Skip to content

docs: fix accuracy bugs from the site quality audit - #30

Merged
wavyx merged 1 commit into
mainfrom
feat-docs-quality
Jul 9, 2026
Merged

docs: fix accuracy bugs from the site quality audit#30
wavyx merged 1 commit into
mainfrom
feat-docs-quality

Conversation

@wavyx

@wavyx wavyx commented Jul 9, 2026

Copy link
Copy Markdown
Owner

A holistic docs quality audit (accurate/engaging/useful) graded the site B+/A-/B+ and surfaced a concentrated set of accuracy bugs — all verified against src/ and fixed here. The build is green and literal --flags in prose are confirmed intact.

Highlights

  • Homebrew/Scoop install channels don't exist yet (release.yml publishes neither) — marked coming-soon and routed to npm/npx/Docker/tarballs. (Actually wiring up brew/scoop publishing is a separate follow-up.)
  • bulk: correct upsert --by searchable types (address/monetary are refused).
  • backup: sync warehouse watermark semantics were backwards (at-least-once, newest update_time, warehouse-manifest.json).
  • api-model: search costs 20 tokens not 40 (matches OpenAPI + cookbook).
  • deal-products: the API does accept per-line billing.
  • config/output/analytics/relations/exit-codes/authentication: path, flag-scope, survivorship, output-shape, and exit-code corrections.
  • Home.astro: terminal mocks now show real command output.
  • gen-commands.mjs: global-flag list derived from source so it can't drift; commands.mdx regenerated.

Engagement/usefulness improvements (task-to-command index, agents-page restructure, jq-troubleshooting entry) are tracked separately.

https://claude.ai/code/session_018dRMUUj9vpKp3tqKQFsvE9

Greptile Summary

This PR is a focused accuracy sweep of the pdcli documentation site, verifying claims against src/ and correcting a concentrated set of bugs found during a quality audit. It also closes a structural drift risk in gen-commands.mjs by deriving the global-flag list from the oclif manifest at generation time.

  • Docs accuracy fixes (14 files): Corrections span install channels (Homebrew/Scoop marked coming-soon), config paths, watermark semantics in sync warehouse, upsert --by type list, search token cost (40 → 20), per-line billing availability, org-relationship table output shape, exit-code shell idiom, --fields and --resolve-fields scope, and --profile default — each verified against source.
  • gen-commands.mjs: Replaces the hand-maintained global-flag string with a globalFlagTokens() function that reads helpGroup:'GLOBAL' entries from the manifest, preventing the kind of omission (missing --resolve-fields) that motivated this PR.
  • astro.config.mjs: Migrates from the deprecated markdown.gfm/smartypants booleans to markdown.processor: unified(…), but the new API requires Astro ≥ 6.4.0 while package.json still declares ^6.3.1, creating a version constraint gap that could silently leave smartypants active and corrupt --flag formatting in the generated docs.

Confidence Score: 4/5

Safe to merge for the documentation content changes; the one item to resolve before merging is the Astro version constraint in website/package.json.

All fourteen documentation corrections are well-reasoned accuracy fixes. The only functional concern is astro.config.mjs: markdown.processor is a 6.4.0 feature but the declared minimum is 6.3.1, and @astrojs/markdown-remark is imported without being a direct dependency. If the lockfile ever resolves to Astro 6.3.x, the processor key is silently ignored and smartypants remains active, which would corrupt --flag literals throughout the generated documentation — the exact problem this config change is meant to prevent.

website/package.json (not in the diff) should be updated alongside astro.config.mjs to raise the lower bound to ^6.4.0 and add @astrojs/markdown-remark as a direct dependency.

Important Files Changed

Filename Overview
website/astro.config.mjs Migrates from deprecated markdown.gfm/smartypants booleans to markdown.processor: unified(…), but the new API requires Astro ≥6.4.0 while package.json only declares ^6.3.1; @astrojs/markdown-remark is also imported as an undeclared transitive dependency.
scripts/gen-commands.mjs Adds globalFlagTokens() to derive the global flag list from the oclif manifest at generation time, preventing the "forgot --resolve-fields" drift problem. Logic is sound; edge case when no command has GLOBAL flags returns empty string but is benign.
website/src/content/docs/start/distribution.mdx Adds prominent :::caution[Coming soon] blocks to Homebrew and Scoop sections that don't exist yet, and updates the comparison table; accurate and well-scoped fix.
website/src/content/docs/guides/backup.mdx Fixes watermark filename (manifest.jsonwarehouse-manifest.json), corrects at-least-once semantics (exact watermark, no +1s), and clarifies the cursor never moves backward; substantive accuracy correction.
website/src/content/docs/guides/bulk.mdx Corrects --by searchable field types (removes address/monetary, adds varchar_auto), explains why those two are refused with exit 64, and documents --match modes and 100-row cap.
website/src/content/docs/concepts/api-model.mdx Fixes search token cost (40 → 20), adds tasks to the v2 topic table, and trims the retry-header description that apparently misrepresented the behavior.
website/src/content/docs/reference/config.mdx Removes non-existent "Global config" precedence layer, corrects Linux config path to pdcli-nodejs, adds PDCLI_CONFIG_DIR, adds --resolve-fields flag row, and fixes --profile default description.
website/src/content/docs/guides/deal-products.mdx Corrects the note about per-line billing: the v2 API does accept it, and provides a pdcli api PATCH workaround until CLI flags are added.
website/src/content/docs/guides/relations.mdx Fixes table output to show org names instead of IDs, explains the rendering behavior, and adds a "See also" section with relevant links.
website/src/content/docs/automation/exit-codes.mdx Fixes the `watch
website/src/content/docs/automation/output.mdx Corrects --fields description to reflect that it also narrows json/yaml records, and broadens --resolve-fields scope from get-only to get and core list commands.
website/src/content/docs/guides/analytics.mdx Corrects deal summary token cost, clarifies dwell p50/p90 sampling bias (open-only vs full history), and notes the --format / --output mutual exclusion.
website/src/content/docs/start/installation.mdx Bumps stale version example from 0.5.0 to 0.22.0 and adds a pointer to Node-free install channels.
website/src/content/docs/guides/authentication.mdx Clarifies --api-token shell history risk, adds env-var alternative, and documents exit code 77 for auth failures.
website/src/components/Home.astro Updates terminal mock outputs (pipeline health table, deal update confirmation, person import) to show command shapes and output that match the real CLI.
website/src/content/docs/reference/commands.mdx Adds --resolve-fields to the global flags list in the auto-generated intro sentence.
docs/commands.md Adds --jq, --fields, and --resolve-fields to the global flags list in the GitHub-facing command reference.
website/src/content/docs/concepts/security.mdx Removes the hardcoded pdcli/0.5.0 version example from the User-Agent description, replacing it with a generic <version> placeholder.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[oclif manifest] -->|read by gen-commands.mjs| B[globalFlagTokens]
    B -->|filter helpGroup GLOBAL| C[Flag list]
    C -->|andList + withOptions| D[docs/commands.md]
    C -->|andList| E[reference/commands.mdx]
    A -->|groupByTopic + renderGithubMarkdown| D
    A -->|groupByTopic + renderWebsiteMdx| E
    A -->|renderStatsJson| F[cli-stats.json]

    G[astro.config.mjs] -->|markdown.processor| H{Astro version?}
    H -->|≥ 6.4.0 installed| I[smartypants OFF ✓]
    H -->|6.3.x pinned| J[processor key ignored — smartypants active ✗]

    K[package.json declares ^6.3.1] -.->|gap| H
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[oclif manifest] -->|read by gen-commands.mjs| B[globalFlagTokens]
    B -->|filter helpGroup GLOBAL| C[Flag list]
    C -->|andList + withOptions| D[docs/commands.md]
    C -->|andList| E[reference/commands.mdx]
    A -->|groupByTopic + renderGithubMarkdown| D
    A -->|groupByTopic + renderWebsiteMdx| E
    A -->|renderStatsJson| F[cli-stats.json]

    G[astro.config.mjs] -->|markdown.processor| H{Astro version?}
    H -->|≥ 6.4.0 installed| I[smartypants OFF ✓]
    H -->|6.3.x pinned| J[processor key ignored — smartypants active ✗]

    K[package.json declares ^6.3.1] -.->|gap| H
Loading

Fix All in Claude Code

Reviews (1): Last reviewed commit: "docs: fix accuracy bugs found in the sit..." | Re-trigger Greptile

Greptile also left 2 inline comments on this PR.

Verified each against src/ before changing. Highlights:

- distribution: Homebrew/Scoop are not published yet (release.yml ships
  neither); marked both "coming soon" and route to npm/npx/Docker/tarballs
  (all verified working). Actually publishing brew/scoop is a follow-up.
- bulk: upsert --by searchable types are varchar/varchar_auto/text/double/
  phone only (address/monetary are refused, exit 64), not what was listed.
- backup: sync warehouse advances the watermark to the newest update_time
  exactly (at-least-once, re-emits the boundary, never regresses) — the doc
  had it backwards; manifest is warehouse-manifest.json.
- api-model: search costs 20 tokens, not 40 (matches the OpenAPI spec and
  the cookbook); added tasks to the v2 row.
- deal-products: the v2 endpoint does accept per-line billing_frequency;
  pdcli just has no flags yet (use the api escape hatch).
- config: Linux path is ~/.config/pdcli-nodejs; added --resolve-fields and
  PDCLI_CONFIG_DIR; dropped the non-existent "global config" layer.
- output: --fields also projects json/yaml; --resolve-fields covers list too.
- analytics: metrics aging baselines OPEN deals only (survivorship note).
- relations: org relationship list renders org names, not ids.
- exit-codes/authentication: 127 wording, watch exit-8 test, auth exit 77,
  env creds bypass auth login.
- Home.astro: the terminal mocks now show real output (no fabricated
  "activity logged", real pipeline-health columns, an actual upsert dry-run).
- gen-commands.mjs: derive the global-flag list from the GLOBAL helpGroup so
  --resolve-fields (and --jq/--fields) can't drift; commands.mdx regenerated.
- astro.config: migrate gfm/smartypants to the processor API (literal --flags
  in prose confirmed intact in the built HTML).
- Stale 0.5.0 version strings bumped / made version-neutral.

Claude-Session: https://claude.ai/code/session_018dRMUUj9vpKp3tqKQFsvE9
@wavyx
wavyx merged commit c27f285 into main Jul 9, 2026
@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Comment thread website/astro.config.mjs
Comment on lines 3 to +26
@@ -9,10 +10,20 @@ export default defineConfig({
site: 'https://wavyx.github.io',
base: '/pdcli',

// GFM tables in .md/.mdx (the MDX pipeline inherits these classic options,
// unlike a custom `processor`); smartypants off so code examples keep
// literal `--flags` and straight quotes.
markdown: { gfm: true, smartypants: false },
// GFM tables in .md/.mdx; smartypants OFF so prose keeps literal `--flags`,
// `--`, and straight quotes (Astro's smart punctuation would turn `--` into
// an en/em dash). Astro 6 deprecated the top-level `markdown.gfm` /
// `markdown.smartypants` booleans — configure them on the unified processor
// instead (removed in a future major otherwise).
//
// NOTE: the build still prints ONE `markdown.gfm`/`smartypants` deprecation
// line during `/llms-*.txt` generation. That is NOT from this config: the
// `starlight-llms-txt` plugin renders via the experimental Astro Container,
// which calls `validateConfig(ASTRO_CONFIG_DEFAULTS, …)` (astro/dist/container/
// index.js), and Astro's own defaults object still carries explicit
// `gfm`/`smartypants` keys — so it trips its own deprecation check. It is
// unfixable from here; it clears when Astro drops those keys from the defaults.
markdown: { processor: unified({ gfm: true, smartypants: 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 markdown.processor requires Astro ≥ 6.4.0, but package.json declares ^6.3.1

markdown.processor and the unified export from @astrojs/markdown-remark were introduced in Astro 6.4.0. The declared peer range "astro": "^6.3.1" permits 6.3.x; if a lockfile (or a fresh npm install that resolves to 6.3.x) is in play, Astro silently ignores the unknown processor key and smartypants remains active — converting -- in prose to an en-dash and breaking all the literal flag examples this PR is trying to protect.

Additionally, @astrojs/markdown-remark is not listed as a direct dependency in package.json (only as a transitive dep of astro), so the import is fragile across package-manager and version changes.

Bump the lower bound in package.json to "astro": "^6.4.0" and add "@astrojs/markdown-remark": "..." as an explicit dependency to make both requirements auditable.

Fix in Claude Code

Comment thread scripts/gen-commands.mjs
Comment on lines +27 to +36
const globalFlagTokens = (manifest, { withOptions = false } = {}) => {
const cmd = Object.values(manifest.commands).find((c) =>
Object.values(c.flags || {}).some((f) => f.helpGroup === 'GLOBAL'),
)
return Object.entries(cmd?.flags || {})
.filter(([, f]) => f.helpGroup === 'GLOBAL')
.map(([name, f]) => {
const opts = withOptions && f.options ? ` ${f.options.join('|')}` : ''
return `\`--${name}${opts}\``
})

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 First-command heuristic may omit flags that don't appear on every command

globalFlagTokens picks the first command object that has any GLOBAL flag, then reads all GLOBAL flags from that one command. If any global flag (e.g. --limit) is conditionally absent from some commands' manifests, the first matching command might return an incomplete set. The approach is sound as long as every command with GLOBAL flags carries the full set (i.e. BaseCommand.baseFlags is inherited uniformly), but a command-specific override that drops a base flag would silently remove it from the generated intro without a warning.

Fix in Claude Code

@wavyx
wavyx deleted the feat-docs-quality branch July 10, 2026 06:42
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.

2 participants