Skip to content

Phase 5: documentation site (stint.reyem.tech)#20

Merged
mariomeyer merged 13 commits into
mainfrom
phase-5-docs-site
May 23, 2026
Merged

Phase 5: documentation site (stint.reyem.tech)#20
mariomeyer merged 13 commits into
mainfrom
phase-5-docs-site

Conversation

@mariomeyer
Copy link
Copy Markdown
Member

Summary

Ships a Starlight-based documentation site at `stint.reyem.tech`. The existing `/install.sh` installer is preserved at the same domain.

Three commits:

  1. `docs(plan): phase 5 — documentation site` — full plan doc
  2. `docs(site): scaffold Astro + Starlight with custom landing page` — Astro 5 + Starlight 0.34 under `site/`, custom Raycast/Linear-style landing page (gradient mark, terminal mock, install grid, anti-marketing list), 11 content pages, build-time GitHub API fetch for live version + DMG links, Reyem Tech logo pulled from `www.reyem.tech` and bundled
  3. `ci(docs): deploy workflow + publish-docs.sh` — `.github/workflows/deploy-docs.yml` triggers on `site/**` changes (push to main) + `workflow_dispatch`. `publish-docs.sh` syncs `site/dist/` to `docs-pages` branch while preserving `install.sh`, `install.sh.sha256`, and `CNAME`

Why no version bump

All commits are `docs(…):` or `ci(…):` — Conventional Commits' default ruleset treats both as no-version-bump. Site ships without triggering a release; version bumps stay tied to product changes.

Test plan

  • `pnpm --filter stint-docs build` produces 11-page Starlight site
  • Build-time GitHub API fetch resolves to current `v0.2.0` (terminal demo + DMG button + DMG install card)
  • `shellcheck scripts/release/publish-docs.sh` clean
  • `deploy-docs.yml` parses as valid YAML
  • Local dev preview confirmed: hero, all sections, sidebar, light/dark toggle, sub-pages
  • CI green on this branch
  • On merge: `deploy-docs.yml` builds + publishes; `deploy-pages.yml` (existing) auto-deploys; `stint.reyem.tech` serves the new landing
  • `curl https://stint.reyem.tech/install.sh | head -3` still returns the installer
  • Pagefind search works
  • DMG download button on the live site goes to v0.2.0's actual asset URL

Coexistence with install.sh

Two deploy scripts now target the `docs-pages` branch:

  • `publish-install-script.sh` (existing) touches only `install.sh` + `install.sh.sha256`
  • `publish-docs.sh` (new) touches everything else, explicitly preserving `install.sh`, `install.sh.sha256`, `CNAME`

Race window is tiny (each script clones-touches-pushes in ~5s) and disjoint file sets mean retry-on-conflict resolves cleanly — `publish-docs.sh` retries once after a 5s sleep.

Merge via "Create a merge commit" per standard.

Plan for shipping a Starlight-based docs site at stint.reyem.tech.

Key decisions inline:
- Astro 5 + Starlight 0.34 (same JS toolchain as ui/; no new ecosystem)
- Welcome-first deep-grouped sidebar with Getting Started / Reference / Help
- Per-page Starlight default OG cards (defer custom images)
- \`docs:\` commit prefix throughout — Conventional Commits treats as
  no-version-bump, so docs ship without triggering releases
- site/ in main + CI sync to docs-pages branch, preserving install.sh
- Coexistence with publish-install-script.sh: disjoint file sets on the
  same branch with retry-on-conflict

Tasks 1-2 (scaffold + content) execute in this PR. Tasks 3-4 (deploy
script + workflow) follow in subsequent commits on this branch.
New Starlight docs site under site/, served at stint.reyem.tech once
deployed (publish script + CI workflow in a follow-up commit).

Custom landing page (src/content/docs/index.mdx, splash template):
- Bold gradient-accented tagline
- Starlight's auto-injected [data-page-title] decorated with the same
  gradient brand mark used in the in-app About page
- Live-fetched DMG download button + version label (build-time GitHub
  API call, cached at module scope, falls back to releases/latest URL
  if fetch fails)
- Terminal-mock hero showing real \`brew install\` → \`stint start\` →
  \`stint today\` sequence with realistic dim/ok/mid coloring; DMG
  filename pulled from the same release-info module
- "Two surfaces, one truth" split: CLI snippet vs ASCII popover mock
- "Built around how you already work" feature grid
- "What stint doesn't do" anti-marketing list (no account / no telemetry
  / no paywall / no browser tab)
- Install grid with all four channels, DMG card uses the same live
  download button
- Footer with the Reyem Tech logo (pulled from www.reyem.tech and
  bundled at site/public/reyemtech-logo.webp)

Inner docs pages (install, getting-started/*, reference/*, help/*):
- Quickstart (5-min CLI + GUI walkthrough)
- Solidtime setup (PAT + OAuth, Keychain locations, switching modes)
- Calendar setup (Google only; MS Graph + CalDAV noted as future work)
- CLI reference (every subcommand with flags + examples)
- Keyboard shortcuts (main window, popover, menu bar, tray)
- Troubleshooting (updater silent-restart fix, sync errors, OAuth not
  configured, Spotlight not finding stint, dev keychain prompts)
- FAQ (macOS only, offline, no Solidtime, storage paths, telemetry)
- License & credits (MIT, dependency table, Reyem Tech card with logo)

Workspace integration: site/ added to pnpm-workspace.yaml; site/dist
and site/.astro gitignored.
Wires up automatic deploy of the Starlight site to stint.reyem.tech.

scripts/release/publish-docs.sh:
- Clones docs-pages branch via GITHUB_TOKEN
- Stashes the files owned by other deploy paths (install.sh,
  install.sh.sha256, CNAME), wipes everything else, copies the fresh
  site/dist/ contents, restores the stash, commits + pushes
- Retries once on non-fast-forward push (handles the rare race with
  publish-install-script.sh — they write disjoint file sets, so a fresh
  clone + retry succeeds cleanly)

.github/workflows/deploy-docs.yml:
- Triggers on push to main when site/**, deploy-docs.yml, or
  publish-docs.sh changes (plus workflow_dispatch for manual rebuilds)
- Ubuntu runner (Starlight builds are platform-agnostic — no need for
  macos-14)
- pnpm install with --filter stint-docs... scope, then build, then publish
- Concurrency group "docs-pages" with cancel-in-progress: a newer
  rebuild supersedes any in-flight one without blocking on it
- Independent of release.yml's "release-\${ref}" group; docs deploys
  never wait on releases

After merge, stint.reyem.tech will serve the Starlight site at /, with
install.sh continuing to live at /install.sh.
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: aaf953fd47

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread site/src/content/docs/reference/cli.md Outdated
Comment on lines +18 to +19
stint start "client call" --billable
stint start "started at lunch" --start-at "2026-05-23T12:30:00-04:00"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Document supported stint start flags

The stint start examples/flags here include --billable and --start-at, but the actual CLI parser only accepts --project, --task, and --at (crates/stint-cli/src/cmd/start.rs). Users who copy these documented commands will get unknown-argument errors, which breaks the primary timer-start workflow on the new docs site.

Useful? React with 👍 / 👎.

Comment thread site/src/content/docs/reference/cli.md Outdated

Shows today's entries, durations, and sync state.

### `stint list --from <date> --to <date>`
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Use positional args for stint list in docs

This documents stint list --from <date> --to <date>, but stint list is implemented with two required positional arguments (from, to) and no --from/--to flags (crates/stint-cli/src/cmd/list.rs). Following the docs causes argument parsing failure for a core listing command.

Useful? React with 👍 / 👎.

Comment thread site/src/content/docs/reference/cli.md Outdated
Comment on lines +121 to +125
### `stint calendar list-calendars [--account <id>]`

Lists calendars under each account.

### `stint calendar set-included <calendar-id> --included true|false`
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Replace nonexistent calendar subcommands in CLI reference

The calendar reference advertises subcommands like list-calendars and set-included, but the CLI exposes stint calendar calendars <account_id> with option flags instead (crates/stint-cli/src/cmd/calendar.rs). As written, these docs send users to commands that do not exist, so calendar account/calendar management instructions fail when executed.

Useful? React with 👍 / 👎.

mariomeyer added 10 commits May 23, 2026 01:34
The dark variant of the Reyem Tech logo (white-on-transparent) was
invisible on the site's light theme. Adds the light variant from
www.reyem.tech/images/logo-light-tagline.webp and CSS-swaps based on
\`[data-theme]\` so the correct variant is always visible.

- Renamed reyemtech-logo.webp → reyemtech-logo-dark.webp for clarity
- Added reyemtech-logo-light.webp (7.3K, same source domain)
- Both <img> elements emitted; .rt-themed-{dark,light} classes
  hide/show the wrong one per active theme
- Applied to both landing footer and license-page card
One-liner at the top of the README pointing to the new Starlight docs
site shipped in Phase 5. Surfaces install / quickstart / setup / CLI
reference / troubleshooting to anyone landing on the GitHub repo.
Adds a "Docs" button to the About page's identity-card action row,
between "Open Solidtime" and "GitHub". Lands users on
stint.reyem.tech in their default browser via openUrl.

Same pattern as the existing GitHub / Report-an-issue buttons; no
state, no IPC, just an external link.
New /help/privacy/ page formalizing the substantive "no telemetry"
claim made on the landing page. Honest content: nothing is collected,
explicit inventory of the three outbound request categories (Solidtime,
Google Calendar, GitHub release manifest), full list of local storage
locations including the wipe commands, third-party clarification, link
to the file's git history as the canonical change log.

License page renamed to "License & terms" and grows a short Terms
section: no-warranty disclaimer (echoes MIT), auto-update policy with
the disable instructions, third-party services boundary, pointer to the
Privacy page for the substantive data claim. Avoids a separate Terms
page because the MIT license already does most of the legal work.

Sidebar Help section grows from 3 to 4 entries: Troubleshooting / FAQ /
Privacy / License & terms.

Landing footer's meta column now shows "Privacy · License & terms" on
the first line and the existing GitHub/Issues/Docs links below.
Adds a "Privacy" button to the About page action row, between "Docs"
and "GitHub". Opens stint.reyem.tech/help/privacy/ in the default
browser via openUrl.

Same pattern as the existing external-link buttons; no state, no IPC.
Starlight renders the logo via <img>, which doesn't inherit
\`currentColor\` from CSS — so the previous single SVG with
\`fill="currentColor"\` was rendering black on both themes (invisible on
dark mode).

Fix uses Starlight's first-class logo.light / logo.dark config with two
SVGs:
- stint-icon-light.svg — dark fill (#1f1f33) for the light theme
- stint-icon-dark.svg  — light fill (#e4e4ff) for the dark theme

Starlight swaps between them based on the active theme. The old single
stint-icon.svg is no longer referenced; removed.
The install page has 4 install-method headings plus uninstall —
useful to deep-link to from the sidebar so users skip the parts that
don't apply to their setup. Restructures the Install sidebar entry
from a flat link into a Starlight group:

  Install (section, expanded by default)
    · Overview        → /install/
    · Homebrew        → /install/#homebrew-recommended
    · Direct DMG      → /install/#direct-dmg-download
    · curl | sh (CLI)         → /install/#curl--sh--cli-only
    · curl | sh (CLI + GUI)   → /install/#curl--sh--cli--gui
    · Uninstall       → /install/#uninstall

Trade-off: Starlight groups don't render their label as a link, so
"Install" as a header is no longer clickable. Users get to the top of
the page via the "Overview" sub-item instead.
Drop "Overview" (clicking the section header navigates to the page
top anyway), drop "Uninstall" (low-frequency, users find it on the
page if they need it), and collapse the two curl|sh variants into one
entry (they're consecutive sections on the page — users scroll past
the first to see the second).

Final shape:
  Install
    · Homebrew
    · DMG
    · curl | sh
Adds three hand-rolled CSS approximations of the in-app Settings
panels, embedded inline where users encounter them in the setup flow.
No image assets — each mock is a small Astro component composing
divs + CSS classes that mirror the actual UI's Tailwind treatment
(rounded card, subtle border, slate/zinc palette, indigo accent).

Components:
- SolidtimePanelMock — URL field, PAT/OAuth toggle, org dropdown,
  connection status pill, Test/Sign out actions
- CalendarPanelMock — account row with toggleable calendars and
  per-calendar default-project labels
- UpdatesPanelMock — three sub-states via prop ("available",
  "installed", "current") showing the v0.2.0 split Install / Restart
  Stint button flow

Wired into the relevant docs:
- getting-started/solidtime.mdx — SolidtimePanelMock
- getting-started/calendar.mdx — CalendarPanelMock
- help/troubleshooting.mdx — UpdatesPanelMock (both available + installed
  states, illustrating the fix for the silent-no-restart bug)

Three docs pages renamed .md → .mdx to support component imports.
Shared CSS lives under the "Inline panel mocks" section of
custom.css, keyed by .panel-mock + .pm-* classes.

Trade-off vs real screenshots: mocks stay accurate to the latest UI
because the markup lives in this repo (no separate asset cadence to
keep in sync), but the visual fidelity is "representative" rather
than "this is exactly what you'll see." Acceptable for inline docs;
real screenshots can replace these later if needed.
Codex caught three P1 inaccuracies in the CLI docs that would break the
documented workflows when users copy-pasted commands. I had written the
reference from memory rather than from \`crates/stint-cli/src/cmd/\`.

Verified against source and fixed:

1. \`stint start\` — documented \`--billable\` and \`--start-at\`, neither
   of which exist. Real flags are \`--project\`, \`--task\`, \`--at\`.
   Billable always inherits from the project's default (not a CLI flag).
   \`--at\` accepts relative ("1h ago"), bare HH:MM, or RFC 3339.

2. \`stint list\` — documented \`--from <date> --to <date>\` flags;
   actual signature is two required positionals \`<from> <to>\`.

3. \`stint calendar\` — documented \`list-calendars\` and \`set-included\`
   subcommands that don't exist. Real shape is
   \`stint calendar calendars <account-id> [--include | --exclude |
   --set-default-project CAL_ID PROJ_ID | --clear-default-project ID]\`.
   Also fixed \`stint calendar refresh\` (requires positional
   \`<account-id>\`) and \`stint calendar add <provider>\` (positional
   provider arg, only "google" accepted today).

While verifying these, also corrected several other commands against
source so the page is now fully accurate end to end:
- \`stint restart\` takes positional \`<local-uuid>\`, not \`<entry-id>\`
- \`stint edit\` \`--start\`/\`--end\` are HH:MM local time (not arbitrary)
- \`stint sync\` has full subcommand inventory: drain (default),
  retry-abandoned, force-adopt, active, diagnose
- \`stint pull\` exposes conflict-resolution flags --dismiss /
  --stop-remote / --switch
- \`stint config\` subcommands: set / show / test / login / logout
- \`stint projects\` subcommands: list / refresh / raw
- \`stint update\` flags: --check / --force

calendar.mdx had the same calendar-subcommand bug; fixed in parallel
to keep the setup docs consistent with the reference.

Quickstart and Solidtime setup pages cross-checked — clean.
@mariomeyer mariomeyer merged commit 6cab938 into main May 23, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant