Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
cae95c5
docs: add the docs standard and a screenshot capture script
chhoumann Oct 11, 2026
5c50672
docs: group the sidebar by task, theme the site, and render screensho…
chhoumann Oct 11, 2026
3b1f337
docs: add a landing page and rewrite getting started
chhoumann Oct 11, 2026
595e83c
docs: rewrite every page for the task-based structure
chhoumann Oct 11, 2026
767fb1a
docs: apply the first review round's fixes
chhoumann Oct 11, 2026
601d18c
docs: point AGENTS.md and the docs README at the standard and the scr…
chhoumann Oct 11, 2026
4796b79
docs: apply the second review round's fixes and split the queue and p…
chhoumann Oct 11, 2026
31272d4
docs: apply the second visual review: phone crops, readable tables, a…
chhoumann Oct 11, 2026
53f9478
docs: apply the third review round: matching note screenshot, phone h…
chhoumann Oct 11, 2026
7179213
docs: apply the fourth review round: clean phone captures, path break…
chhoumann Oct 12, 2026
e68f084
Merge remote-tracking branch 'origin/master' into docs/overhaul
chhoumann Oct 12, 2026
bd9ad59
docs: apply the fifth review round's minor fixes and name the Obsidia…
chhoumann Oct 12, 2026
f897bfa
fix(docs): pass capture values as CDP arguments and escape stacked ta…
chhoumann Oct 12, 2026
d42c160
Merge remote-tracking branch 'origin/master' into docs/overhaul
chhoumann Oct 12, 2026
e36007c
docs: say Deepgram transcribes only with speaker labels on
chhoumann Oct 12, 2026
ad0f895
docs: apply the sixth review round across every page
chhoumann Oct 12, 2026
0df9248
docs: apply the seventh review round across every page
chhoumann Oct 12, 2026
db4fe4a
docs: apply the eighth review round across every page
chhoumann Oct 12, 2026
a30c6dd
Merge remote-tracking branch 'origin/master' into docs/overhaul
chhoumann Oct 12, 2026
76e4503
docs: apply the ninth review round across every page
chhoumann Oct 12, 2026
e49dfd6
docs: apply the tenth review round's standards and QuickAdd fixes
chhoumann Oct 12, 2026
1e92f3f
docs: finish the tenth review round
chhoumann Oct 12, 2026
1f3e9a3
docs: add the PodNotes mark to the site header and favicons
chhoumann Oct 12, 2026
80bdd1b
docs: bold the QuickAdd choice names you select
chhoumann Oct 12, 2026
909d8be
Merge remote-tracking branch 'origin/master' into docs/overhaul
chhoumann Oct 12, 2026
fc65831
docs: apply the eleventh review round's minor fixes
chhoumann Oct 12, 2026
4be8931
docs: fix the QuickAdd AI recipe's prompt template and save steps
chhoumann Oct 12, 2026
d2fa449
docs: set up QuickAdd's AI Assistant with a listed provider and a model
chhoumann Oct 12, 2026
6575da0
docs: number the steps for adding another QuickAdd provider
chhoumann Oct 12, 2026
8ec9455
docs: keep the When a feed cannot be reached link on the podcasts page
chhoumann Oct 12, 2026
0bc5694
docs: describe a failed feed fetch without promising what a search shows
chhoumann Oct 12, 2026
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
23 changes: 16 additions & 7 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,16 +206,25 @@ terminal session and allow their documented timeout.

## Documentation
Docs are an Astro Starlight site in `docs/`, a standalone npm package with its
own `package-lock.json`. Pages live in `docs/src/content/docs/`, images in
`docs/public/resources/`, and the sidebar in `docs/src/site.mjs`. Every page
sets `slug:` frontmatter to pin its URL, and the build fails without it. Update
docs with user-facing behavior changes, new commands, API changes, template
syntax, transcript behavior, local-file behavior, or import/export changes.
own `package-lock.json`. Pages live in `docs/src/content/docs/` and the sidebar
in `docs/src/site.mjs`. Every page sets `slug:` frontmatter to pin its URL, and
the build fails without it. Update docs with user-facing behavior changes, new
commands, API changes, template syntax, transcript behavior, local-file
behavior, or import/export changes.

Every page follows the standard in `docs/STYLE.md`: pages grouped by what the
reader is doing, one job per page, UI labels spelled as PodNotes shows them,
and facts that describe the latest published release, not unreleased `master`.
Screenshots come only from `node docs/scripts/screenshots.mjs`, which captures
them in light and dark from the seeded vault in `docs/screenshots/`. Rerun it
after a UI change instead of adding images by hand.

Use `npm run docs:build` to validate docs locally. It installs the docs
dependencies and runs `astro build`, which fails on a broken internal link or
anchor. Cloudflare Pages builds from `docs/` and publishes `docs/dist`, configured in
`docs/wrangler.jsonc`. See `docs/README.md` for the docs project layout.
anchor, a page missing from the sidebar, or a published heading id that no
longer resolves. Cloudflare Pages builds from `docs/` and publishes `docs/dist`,
configured in `docs/wrangler.jsonc`. See `docs/README.md` for the docs project
layout.

## Release Workflow
Goal: publish each version from a tested, reviewed, and attested commit. Stop
Expand Down
54 changes: 48 additions & 6 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,65 @@ plugin's dependencies.

## Layout

- `STYLE.md` is the standard every page follows. Read it before you write.
- `src/content/docs/` holds the pages as markdown. Each page sets `slug:`
frontmatter to its URL path. For example, `slug: commands` serves
`/commands/`, and `slug: index` serves `/`. The build fails if a page has no
`slug:`, because Astro would otherwise lowercase the generated slug and
change URLs such as `/QuickAdd/`. If you change a slug, add a 301 in
`public/_redirects`.
- `index.md` is the landing page. It uses Starlight's splash template, and
`src/components/Hero.astro` renders its hero with the hero screenshot.
- `astro.config.mjs` holds the Starlight config. The sidebar lives in
`src/site.mjs`, which the LLM files below also read.
`src/site.mjs`, which the LLM files below also read. `src/styles/custom.css`
holds the theme.
- `src/components/MarkdownContent.astro` post-processes every page:
`src/screenshots.mjs` gives each screenshot its size, its dark twin, and its
phone crop, and `src/tables.mjs` labels table cells so wide tables stack on
phones.
- `scripts/legacy-fragments.mjs` runs after every build and fails it if a
heading fragment from the old MkDocs site (`legacy-fragments.json`) has no
heading fragment the site has published (`legacy-fragments.json`) has no
target. When a heading's new id differs from the old one, start the heading
with an empty `<span id="old-id"></span>`, as `commands.md` does. For an old
page-title id, set `legacyTitleId:` in the frontmatter instead.
- `public/` holds static assets served as-is. Images live in
`public/resources/` and are referenced with site-absolute paths such as
`/resources/podcast_grid.png`. The repo-root `README.md` uses the same
images.
- `public/` holds static assets served as-is. Older images live in
`public/resources/` and stay for existing links.

## Screenshots

Every screenshot in `public/screenshots/` comes from one script. From the repo
root, after `npm run build`:

```sh
node docs/scripts/screenshots.mjs
```

It builds a vault from `screenshots/` (the notes, a Bases file, the PodNotes
settings in `seed.json`, and the Minimal theme), opens it in a private Obsidian
capture instance at 2x, adds the podcast feeds through Settings, plays the
episodes, creates notes and captures timestamps with PodNotes' own commands, and
writes each shot as `<name>.webp` and `<name>-dark.webp`, with a
`<name>-phone.webp` crop where the desktop shot is unreadable on a phone, plus
the README demo
GIFs and the social preview `og.png`. It needs network access for the feeds,
their artwork, and the theme. The episodes in `seed.json` must still be among
each feed's latest episodes. If one has left, pick a newer one and update its
notes in `screenshots/notes/`.

To show a screenshot on a page, write
`![What it shows](/screenshots/<name>.webp)`. The site adds the size, lazy
loading, the dark twin, and the phone crop if there is one.

## Brand

The PodNotes mark is `public/brand/podnotes-mark.svg`, drawn on a 16 px grid so
the smallest favicon stays sharp. The header logo uses it directly. The
favicons and the Apple touch icon are built from it. After you change the mark,
run from the repo root:

```sh
node docs/scripts/brand.mjs
```

## Commands

Expand Down
102 changes: 102 additions & 0 deletions docs/STYLE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# PodNotes docs standard

Every page on https://podnotes.obsidian.guide follows this checklist. Review a
page against it before you merge. The sources are listed at the end.

The reader is an Obsidian user who wants to listen to a podcast and keep notes.
They skim, they often read on a phone, and they arrive from search on a page
other than the home page.

## The site

- [ ] The sidebar groups pages by what the reader is doing, in this order:
**Start here**, **Listen**, **Take notes**, **Your library**, **Automate**,
**Reference**, **Help**. `src/site.mjs` holds the sidebar.
- [ ] Every answer is at most two clicks from the home page: the home page or the
sidebar, then the page.
- [ ] Each page has one job, named by its title. A page that does two jobs
becomes two pages.
- [ ] A procedure lives on one page. Other pages link to it instead of repeating
it. Two exceptions: **Getting started** walks through the first install,
podcast, playback, timestamp, and note in one place, and the landing page
and the FAQ may give a one-line fix that links to the page that owns the
procedure.
- [ ] URLs never break. Every page pins `slug:`. A moved page gets a 301 in
`public/_redirects`. A renamed heading keeps its old id with an empty
`<span id="old-id"></span>` (the build checks `legacy-fragments.json`).
- [ ] Content lives in text, not only in images, so the raw `.md` page and
`llms.txt` carry all of it.

## The page

- [ ] The title says what the reader does or looks up: "Capture timestamps",
"Template tags". Sentence case.
- [ ] `description:` frontmatter is one sentence. Search results and link
previews show it.
- [ ] The first sentence says what the page lets the reader do. No "This page",
no "In this guide", no history.
- [ ] The common case comes first. Limits and edge cases come last, under a
heading that names them.
- [ ] Task headings start with a verb ("Add a podcast"). Concept headings are
noun phrases ("Episode identity"). FAQ entries are the reader's questions.
No heading starts with an -ing word, and no level is skipped.
- [ ] A how-to page covers one feature. Each task on it fits in about one
screen at 1440x900, and the page stays under about four screens before any
reference section. Split a page that grows past that. Lookup tables go at
the end of the page under a heading that says so, or on a reference page.
- [ ] A procedure is a numbered list with one action per step. Each step names
the place before the action: "In **Settings → PodNotes**, select
**Add**."
- [ ] When desktop and mobile differ, the page says so where it matters.

## The sentences

- [ ] Write to "you", in the present tense and the active voice.
- [ ] UI labels are bold and spelled exactly as PodNotes shows them, case
included: **Search Podcasts**, **Capture timestamp format**.
- [ ] Commands use the palette name: **PodNotes: Capture Timestamp**.
- [ ] Settings paths use an arrow: **Settings → Community plugins**.
- [ ] Use "select" for clicks and taps. Shortcuts look like `Ctrl+P`.
- [ ] Use plain words: "use", not "utilize". No "simply", "just", "easy",
"powerful", or "seamless". No emoji.
- [ ] No em dash and no semicolons. End the sentence instead.
- [ ] Examples use real values: a real feed, a real time such as `00:12:41`.
- [ ] Link text names the destination. Never "here". Link with site-absolute
paths such as `/timestamps/#capture-a-range`.

## The facts

- [ ] Describe only the latest published release
(`gh release list --repo chhoumann/PodNotes`). Behavior that exists only
on `master` waits for the release.
- [ ] Check every claim against `src/` at the release tag.
- [ ] State a limit plainly and give the workaround if one exists.

## Screenshots

- [ ] A screenshot shows something words cannot. Never screenshot text.
- [ ] `docs/scripts/screenshots.mjs` captures every screenshot from the seed
vault in `docs/screenshots/`. Never add one by hand. Rerun the script
after a UI change.
- [ ] Each screenshot has a light file and a `-dark` file. The site shows the
one that matches the reader's theme.
- [ ] The crop shows the part that matters and enough context to find it.
- [ ] A shot whose text is unreadable at 390 px wide gets a `-phone` crop
captured in Obsidian's phone layout. The site shows it on narrow screens.
- [ ] Alt text says what the screenshot shows in under 150 characters.

## Before you merge

- [ ] `npm run docs:build` passes. It checks links, legacy fragments, and that
every page is in the sidebar.
- [ ] You read the page at 390 px and 1440 px wide, in light and dark.

## Sources

- Lee Robinson, [Documentation](https://leerob.com/docs) and
[On developer experience](https://leerob.com/dx).
- [Diátaxis](https://diataxis.fr/).
- [Google developer documentation style guide](https://developers.google.com/style).
- [Write the Docs: documentation principles](https://www.writethedocs.org/guide/writing/docs-principles/).
- [Obsidian Help style guide](https://obsidian.md/help/style-guide).
- [Nielsen Norman Group: how users read on the web](https://www.nngroup.com/articles/how-users-read-on-the-web/).
51 changes: 45 additions & 6 deletions docs/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { defineConfig } from "astro/config";
import starlight from "@astrojs/starlight";
import starlightLinksValidator from "starlight-links-validator";
import { description, sidebar, site, title } from "./src/site.mjs";
import { description, repository, sidebar, site, title } from "./src/site.mjs";

// https://astro.build/config
export default defineConfig({
Expand All @@ -11,28 +11,67 @@ export default defineConfig({
starlight({
title,
description,
logo: { src: "./public/brand/podnotes-mark.svg", alt: "" },
plugins: [starlightLinksValidator()],
social: [
{
icon: "github",
label: "GitHub",
href: "https://github.com/chhoumann/PodNotes",
href: repository,
},
],
editLink: {
baseUrl: "https://github.com/chhoumann/PodNotes/edit/master/docs/",
},
customCss: ["./src/styles/custom.css"],
expressiveCode: {
defaultProps: { wrap: true },
styleOverrides: { borderRadius: "0.5rem" },
},
head: [
{
tag: "meta",
tag: "link",
attrs: {
rel: "icon",
type: "image/png",
sizes: "32x32",
href: "/favicon-32.png",
},
},
{
tag: "link",
attrs: {
rel: "icon",
type: "image/png",
sizes: "16x16",
href: "/favicon-16.png",
},
},
{ tag: "link", attrs: { rel: "apple-touch-icon", href: "/apple-touch-icon.png" } },
{
tag: "link",
attrs: {
property: "og:image",
content: `${site}/resources/podcast_grid.png`,
rel: "preload",
href: "/fonts/InterVariable.woff2",
as: "font",
type: "font/woff2",
crossorigin: "",
},
},
{
tag: "meta",
attrs: { property: "og:image", content: `${site}/screenshots/og.png` },
},
{ tag: "meta", attrs: { property: "og:image:width", content: "1200" } },
{ tag: "meta", attrs: { property: "og:image:height", content: "630" } },
{ tag: "meta", attrs: { name: "twitter:card", content: "summary_large_image" } },
],
sidebar,
components: { PageTitle: "./src/components/PageTitle.astro" },
components: {
Hero: "./src/components/Hero.astro",
MarkdownContent: "./src/components/MarkdownContent.astro",
PageTitle: "./src/components/PageTitle.astro",
},
}),
],
});
Loading
Loading