README Refresh Implementation Plan#
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Refresh README.md + 9 translations, add llms.txt, sync GitHub repo description + topics so opendray accurately represents its current 5-CLI capability surface, looks comparable to top OSS repos, and is discoverable via both search engines and LLM answers.
Architecture: One atomic PR on branch docs/readme-refresh. Sequential commits: screenshots first (visual assets are prerequisites for the README changes that reference them), then English canonical README, then llms.txt, then the 9 translations. Then PR + CI + merge. Then GitHub metadata update (after merge, so description on main is consistent with README on main). No version bump (this is a docs change per VERSIONING.md).
Tech Stack: Playwright (headless Chromium) for screenshot capture; Node.js for scripts; gh CLI for GitHub metadata + PR ops; Markdown (GitHub-flavored) for content.
Reference documents:
- Spec:
docs/superpowers/specs/2026-07-02-readme-refresh-design.md(committed on this branch asf5738c1) - Current README:
README.md(474 lines) - Existing translations:
README.zh.md,README.fa.md,README.es.md,README.pt-BR.md,README.ja.md,README.ko.md,README.fr.md,README.de.md,README.ru.md - Provider catalog (source of truth for which CLIs to name):
internal/catalog/builtin/{claude,codex,antigravity,grok,opencode,shell}.json
Global Constraints#
- No em-dashes (
—U+2014,–U+2013) anywhere in the output. Use periods, commas, parens, colons, or semicolons instead. Rule applies to English AND all 9 translation files including RU, FR, DE, FA, ZH, JA, KO, ES, PT-BR. - No Claude attribution in commit messages, PR title, PR body, or issue text. No "Co-Authored-By: Claude", no "Generated with Claude Code" footer.
- No version bump. VERSIONING.md classifies docs as patch or no-bump; this is a docs-only refresh, no CHANGELOG entry required unless the merging maintainer wants one.
- Do not touch translations manually beyond section-parity requirements. Match the existing translation style per language. Do not "improve" pre-existing prose.
- Single atomic PR. All commits land on branch
docs/readme-refreshand merge in one PR. No amending, no force-push, no split PRs. - CI must be green before merge. The
check-i18n-parityjob runs on every PR;check-readme-driftis advisory but should show clean (all 9 translations updated in this PR). - Base branch:
main. Do not target any other branch.
File Structure#
Created:
docs/assets/screenshots/hero-web-admin.png(wide dashboard shot)docs/assets/screenshots/session-live.png(live session view with memory rail)docs/assets/screenshots/mobile-session.png(mobile viewport view)docs/assets/screenshots/channels-telegram.png(channels page)llms.txt(root)scripts/capture-screenshots.mjs(throwaway; deleted at end)
Modified:
README.md(English canonical, full rewrite per spec)README.zh.md,README.fa.md,README.es.md,README.pt-BR.md,README.ja.md,README.ko.md,README.fr.md,README.de.md,README.ru.md(9 files, structural sync + translated new sections)
External state changed:
- GitHub repo description on
Opendray/opendray - GitHub repo topics on
Opendray/opendray
Task 1: Capture product screenshots#
Privacy constraint (operator-set): Screenshots must come from a fresh
seeded gateway, NOT from the production instance on 127.0.0.1:8770. The
production instance carries real user data; the shots go into a public README.
Files:
- Create:
docs/assets/screenshots/hero-web-admin.png - Create:
docs/assets/screenshots/session-live.png - Create:
docs/assets/screenshots/mobile-session.png - Create:
docs/assets/screenshots/channels-telegram.png - Create then delete:
scripts/capture-screenshots.mjs - Create then delete:
/tmp/opendray-shots/config.toml,/tmp/opendray-shots/data/
Interfaces:
Consumes: none (first task)
Produces: four PNG files at the paths above, each ≤500KB, referenced by name in later tasks.
Step 1: Spin up a seeded scratch gateway on
127.0.0.1:8771
Do NOT reuse the production instance on :8770. Create a fresh scratch
instance:
Apply schema, seed fake data (see Step 2), then start:
[object Promise]Expected: HTTP 200.
- Step 1b: Seed fake data
Write /tmp/opendray-shots/seed.sql with fake but plausible fixtures. Use
generic names ("Prompt refactor", "Docs update", "Bug triage") and never
real personal info. Seed:
- Four sessions in Sessions view, showing multi-provider coverage: Claude Code / Codex / Grok Build / shell. Each with a fake project name ("app/web", "internal/session", "docs/", "misc/").
- 8-12 memory entries with generic technical text (no personal data).
- Three channels configured but disabled: Telegram, Slack, Discord (do not
put real webhook URLs or tokens; use
sk_fake_xxxstyle placeholders).
Apply:
[object Promise]If direct SQL is fragile against the migration schema, fall back to using
the REST API against 127.0.0.1:8771 with the admin credentials to POST
the fixtures. Either path lands the same data.
- Step 2: Install Playwright + Chromium
Run:
[object Promise]Expected: no error, chromium browser downloaded to ~/.cache/ms-playwright/.
If apt-get prompts for sudo on --with-deps in a restricted env, retry without it: npx --yes [email protected] install chromium.
- Step 3: Write the capture script
Create scripts/capture-screenshots.mjs:
- Step 4: Run the capture script
Expected output:
[object Promise]If the admin uses cookie auth rather than HTTP basic (check by opening /admin/ in a browser and observing the login form), replace the httpCredentials block in the script with an explicit login flow:
- Step 5: Verify screenshots
Expected: 4 PNG files, each between 30KB and 500KB, each identified as PNG image data, 1440 x 900 (desktop shots) or 390 x 844 (mobile shot). If any file is >500KB, compress with optipng -o5 <file> or reduce viewport.
- Step 6: Tear down the scratch gateway and delete the throwaway script
- Step 7: Commit
Expected: commit succeeds, git log --oneline -1 shows the new commit.
Task 2: Rewrite README.md (English canonical)#
Files:
- Modify:
README.md(full rewrite per spec section 1 + section 2)
Interfaces:
Consumes: PNG file names from Task 1 (
docs/assets/screenshots/{hero-web-admin,session-live,mobile-session,channels-telegram}.png)Produces: canonical structure that all 9 translations in Task 4 will mirror. New section headings (verbatim, English) that translations must match:
## What is opendray?## Screenshots## Features## Architecture at a glance## Comparison## Who is this for?## Install## Quickstart (5-minute dev path)## Production deploy## Web frontend## Mobile app## FAQ## Documentation## Status## Tests## Relationship to v1## License
Step 1: Read the current README and the spec side by side
Read both files fully before writing. The spec covers structural changes; the current README carries prose that mostly stays (install, quickstart, production deploy).
- Step 2: Write the new hero (top of file through the language switcher)
Replace lines 1-34 of README.md with:
- Step 3: Write "What is opendray?" section
Replace the existing "What is opendray?" block (lines around 48-58) with:
[object Promise]- Step 4: Add Screenshots section
Insert after "What is opendray?", before "Architecture at a glance":
[object Promise]- Step 5: Add Features matrix
Insert after Screenshots, before "Architecture at a glance":
[object Promise]- Step 6: Update the Architecture Mermaid diagram to name all 5 CLIs
Replace the subgraph cli block in the existing Mermaid (currently naming cc, co, ag, sh) with:
And add the corresponding edges:
[object Promise]- Step 7: Add Comparison section (two tables)
Insert after "Architecture at a glance", before "Install":
[object Promise]- Step 8: Add "Who is this for?" section
Insert after Comparison, before Install:
[object Promise]- Step 9: Preserve Install, Quickstart, Production deploy sections
These sections (lines ~127-391 in the current file) stay word-for-word. Only touch: any em-dash present. Search:
[object Promise]Replace each hit with a period, comma, colon, or parens as context dictates. Do not add or remove any information; only swap the punctuation.
- Step 10: Preserve Web frontend + Mobile app sections
Keep the existing content. Add one deep-link at the end of the Mobile app section:
[object Promise]- Step 11: Write the FAQ section
Insert after Mobile app, before Documentation:
[object Promise]- Step 12: Move Status/Version section to just before Tests
Delete the current "Status" block near the top of the file (the one that says v2.7.6). Insert a new block just before the "Tests" section:
- Step 13: Preserve Documentation, Tests, Relationship to v1, License
These sections stay word-for-word. Sweep any em-dashes.
- Step 14: Final em-dash sweep
Expected output: (empty). If any hit remains, replace and re-check.
- Step 15: Verify Markdown renders
Expected: missing local links: [].
- Step 16: Commit
Task 3: Add llms.txt at repo root#
Files:
- Create:
llms.txt
Interfaces:
Consumes: nothing (independent from other tasks)
Produces: canonical LLM-facing summary at repo root
Step 1: Write
llms.txt
Create llms.txt at repo root:
curl -fsSL https://raw.githubusercontent.com/Opendray/opendray/main/scripts/install.sh | bash
[object Promise]- Step 2: Em-dash sweep
Expected: clean.
- Step 3: Commit
Task 4a: Translate to CJK (zh, ja, ko)#
Files:
- Modify:
README.zh.md,README.ja.md,README.ko.md
Interfaces:
Consumes: new English README from Task 2 (section headings, prose, tables)
Produces: three translated files with identical structure
Step 1: Read the current translation to learn the file's style
For each file (zh, ja, ko):
[object Promise]Note the tone, honorifics, technical-term handling (English kept vs localized), and header casing conventions per language.
- Step 2: For each of zh, ja, ko: mirror the new English structure
For each language, rewrite the file to match the new English README's section order and content. Keep:
- The existing language-switcher row unchanged (they already list all 10 languages).
- Existing code blocks and command examples verbatim (English).
- Screenshot references and image paths verbatim.
- Feature-matrix category labels in the target language; capability values in the target language.
- Comparison-table column headers in the target language; product names verbatim (Claude Desktop, Cursor, Open WebUI, etc.).
- FAQ questions translated verbatim (they are literal user queries in the target language too).
Style expectations per language:
Chinese (zh): simplified, no honorifics. Match the existing tone.
Japanese (ja): です・ます tone (matches existing file). Technical terms often kept in Katakana or English (session → セッション, memory → メモリ or memory).
Korean (ko): 존댓말, technical terms often in English within parentheses.
Step 3: Em-dash sweep for each file
Expected: all three clean.
- Step 4: Section-parity check
Expected: each translation has the same H2 count as the English canonical.
- Step 5: Commit
Task 4b: Translate to Romance (es, pt-BR, fr)#
Files:
- Modify:
README.es.md,README.pt-BR.md,README.fr.md
Interfaces:
Consumes: new English README from Task 2
Produces: three translated files with identical structure
Step 1: Read the current translation to learn each file's style
Note tone (formal vs informal), diacritic usage, and technical-term policy (usually keep English for CLI names).
- Step 2: For each of es, pt-BR, fr: mirror the new English structure
Follow the same procedure as Task 4a Step 2. Style expectations:
Spanish (es): neutral (no vos/vosotros regional slant), technical terms in English.
Portuguese (pt-BR): Brazilian conventions.
French (fr): vouvoiement, technical terms in English with occasional French gloss.
Step 3: Em-dash sweep
Expected: all three clean. Note that Romance languages sometimes tempt em-dashes in dialogue-style prose. Use commas or parens instead.
- Step 4: Section-parity check
Expected: all three match the English H2 count.
- Step 5: Commit
Task 4c: Translate to remaining (de, ru, fa)#
Files:
- Modify:
README.de.md,README.ru.md,README.fa.md
Interfaces:
Consumes: new English README from Task 2
Produces: three translated files with identical structure
Step 1: Read the current translation to learn each file's style
Note: README.fa.md is right-to-left. Preserve <p align="center"> and <img> wrappers (they align in the Markdown-rendered flow); Farsi body prose reads RTL naturally in GitHub's renderer without extra markup.
- Step 2: For each of de, ru, fa: mirror the new English structure
Follow the same procedure. Style expectations:
German (de): formal Sie-form, compound nouns typical in tech writing. Technical terms usually kept in English (Session, Memory).
Russian (ru): formal вы-form. Technical terms often kept in English with a Russian gloss on first mention.
Farsi (fa): RTL. Technical terms often kept in English. Do not add
<div dir="rtl">wrappers (existing file does not use them and GitHub renders correctly without).Step 3: Em-dash sweep
Expected: all three clean. German prose sometimes tempts em-dashes; use commas or parens instead. Russian and Farsi rarely use em-dashes in this style.
- Step 4: Section-parity check
Expected: all three match.
- Step 5: Commit
Task 6 (reordered from 5): Update GitHub repo description + topics AFTER merge#
Files:
- No local files. External state change on
Opendray/opendrayviagh api.
Interfaces:
Consumes: nothing local
Produces: updated
descriptionandtopicson the GitHub repo, verifiable viagh repo viewStep 1: Update the repo description
Expected: 200 OK, JSON response echoing the new description.
- Step 2: Fetch current topics
Expected: current topic list. Note the presence of gemini-cli.
- Step 3: Compute the new topic list
Expected: same list minus gemini-cli, plus the 8 new topics, no duplicates.
- Step 4: Apply the new topics
If the array form of -f fails, use --input:
Expected: 200 OK, JSON echo of new topics list.
- Step 5: Verify from a fresh fetch
Expected: description matches the new string exactly. Topics list contains grok, opencode, antigravity, pgvector, ai-gateway, agent-runtime, homelab-ai, local-first, and does NOT contain gemini-cli.
- Step 6: Note the change in the plan status
No commit here (no local files touched). The change is auditable via GitHub's activity log.
Task 5 (reordered from 6): Open PR, wait for CI, merge#
Files:
- No local files. PR creation, CI wait, merge on green.
Interfaces:
Consumes: all commits from Tasks 1-4 on branch
docs/readme-refreshProduces: merged commit on
mainStep 1: Push all commits
Expected: no error, branch updated on remote.
- Step 2: Open the PR
Expected: PR URL printed. Note the PR number.
- Step 3: Wait for CI to complete
Set PR=<the number from step 2> then:
Expected: every check has "conclusion":"SUCCESS". If any check is FAILURE or CANCELLED, stop and report.
- Step 4: Merge on green
Expected: ✓ Squashed and merged pull request #<N>. Branch deleted.
If the PR is BEHIND main, update first:
Then re-run Step 3 to wait for CI on the updated branch, then re-run Step 4.
- Step 5: Verify the merge landed
Expected: "state":"MERGED", non-null mergeCommit.oid.
- Step 6: Sanity-check the live README + metadata
Open https://github.com/Opendray/opendray in a browser (or gh browse). Confirm:
- Hero mentions Grok Build and OpenCode.
- Hero screenshot renders.
- Comparison tables render.
- FAQ section renders.
- Repo description at the top of the page matches the new string.
- Topics chips show
grok,opencode,antigravity, and do not showgemini-cli. llms.txtis fetchable athttps://raw.githubusercontent.com/Opendray/opendray/main/llms.txt.
If any check fails, open a follow-up PR to fix. Do NOT amend the merged commit.
Success Criteria#
- README hero names all 5 wrapped CLIs (Claude Code, Codex, Antigravity, Grok Build, OpenCode).
- 4 screenshots render on the GitHub-rendered README.
- Comparison tables + FAQ + personas + feature matrix all render correctly.
- Status/version block no longer contains
v2.7.6. llms.txtpresent at repo root, fetchable via raw.githubusercontent.- All 9 translations updated (check-readme-drift advisory clean, i18n parity green).
- Repo description on GitHub matches the new string exactly.
- Repo topics include
grok,opencode,antigravity,pgvector,ai-gateway,agent-runtime,homelab-ai,local-first; do NOT includegemini-cli. - All CI checks green.
- Zero em-dashes across all changed files.
- PR merged into
main.