od-contribute
One-click contribution flow for OpenDesign (nexu-io/open-design) — even for non-coders. Pick one of four cards (ship a Skill or Design System you made with OD; translate docs; fix a typo / write a blog; report a bug), the agent validates and opens a PR (or issue) for you. Trigger words contribute to
By nexu-io · 1,488 installs
npx skills add nexu-io/open-design --skill od-contribute
Source repository · Upstream listing
od contribute — first contribution flow for OpenDesign
Locked to nexu io/open design . Branches by contribution type , not by issue. Replaces the dev loop with type specific no code validators. Designed so a product user with zero coding background can ship a real PR.
Language
Mirror the user's language in every user facing message — AskUserQuestion labels and descriptions, status updates, error explanations. Detect from their first message; when uncertain, default to English.
Generated artifacts (PR titles, commit messages, PR/issue body files, branch names) MUST be English regardless of the user's chat language. GitHub conventions, maintainer review, and search all assume English. The templates under templates/ are already English — keep them that way when rendering.
Scripts live under scripts/ . Source the shared helpers from any script:
SKILL DIR below = the directory that contains this SKILL.md .
Step 1 — Prereq check (always first)
Exit 0: capture GH USER=<login from stdout. Default TARGET FORK="${GH USER}/open design" .
Exit 2: surface the printed install / auth hint verbatim and stop. Do not attempt token workarounds.
If gh repo view "$TARGET FORK" fails, ask the user (one AskUserQuestion ) whether to fork now via gh repo fork nexu io/open design clone=false . Default to yes.
Step 2 — Pick contribution type
Single AskUserQuestion (header: "Contribution", multiSelect: false), four options. Translate option labels/descriptions into the user's chat language; the branch routing is unchanged.
1. 🎨 Ship something I made with OD — a Skill, Design System, HyperFrame, or template I want to contribute upstream → branch 3a
2. 🌍 Translate OD docs — README / QUICKSTART / CONTRIBUTING into a new language → branch 3b
3. 📝 Fix docs / write a blog / fix a typo — typo fix, dead link, use case writeup → branch 3c
4. 🐛 Report a bug — something broke; I'll help turn it into a high quality issue → branch 3d (issue path, no PR)
Each branch below is self contained. Steps 7–8 (preview + push) are shared across branches 3a / 3b / 3c . Branch 3d skips them entirely.
Step 3a — OD product submission (Skill / Design System)
3a.1 Ask user: "What's the local path to the artifact you want to ship?" (single free text, translated into the user's chat language). Common: a folder path (Skill) or a single DESIGN.md file (Design System).
3a.2 Sniff type:
If ambiguous, ask the user to confirm.
3a.3 Run setup:
<slug is od::slugify of the Skill name frontmatter field or of the brand name. Capture WORKDIR from stdout.
3a.4 Copy artifact into workspace at the right target dir:
Skill → $WORKDIR/skills/<slug /
Design System → $WORKDIR/design systems/<brand slug /DESIGN.md (+ any sibling assets in the same folder)
3a.5 Validate:
If validation fails, surface the FAIL lines verbatim, ask the user to fix, retry. Never push a failing artifact.
3a.6 Ask 3 short questions via AskUserQuestion (translate the labels into the user's chat language):
"What name should we credit you under in the PR?" — free text
"One line pitch for this Skill / Design System?" — free text
"Path to a screenshot (optional)?" — free text
3a.7 Render templates/PR BODY skill.md (or PR BODY design system.md ) with substitutions:
{{SKILL NAME}} , {{SKILL SLUG}} (or {{BRAND NAME}} , {{BRAND SLUG}} )
{{PITCH}} (the one line)
{{MOTIVATION}} (free text — agent can offer to draft this from the skill body, but user confirms)
{{TRY PROMPT}} (a prompt they recommend trying — agent suggests a default, user confirms)
{{SCREENSHOT BLOCK}} (Markdown image block if a screenshot path was given, else empty)
{{DISCORD INVITE}} from $OD DISCORD INVITE
Write to $WORKDIR/.od contrib/PR BODY.md .
→ Jump to Step 7 .
Step 3b — i18n translation
3b.1 Setup workspace (slug = translate <doc <lang if known, else translate ):
3b.2 Discover gaps:
Each line is JSON. Rank by:
status: "missing" first (missing language is highest leverage)
then status: "stale" ordered by english commits since translation desc
README family before QUICKSTART before CONTRIBUTING
3b.3 Take the top 3–4 gaps and present via AskUserQuestion (header: "Translation target"). Each option label like: README → 한국어 (Korean) / QUICKSTART (zh CN) refresh — 12 commits behind . Translate the header text into the user's chat language but keep the option labels descriptive (the language names belong in their native script).
3b.4 Once user picks, rename branch to be specific:
(or pre set the slug in step 3b.1 if the user confirmed earlier.)
3b.5 Translate. Read the English source. Translate structure preserving :
Code blocks: leave untranslated
Brand / product names: leave untranslated
Filenames in inline code: leave untranslated
Image / link targets: leave untranslated; if a localized version of a linked doc exists, swap the link to the localized file
Headings: translate, keep the heading depth identical
Tables: translate cell text only, keep alignment / pipes
Write the result to $WORKDIR/<TRANSLATED PATH (e.g. QUICKSTART.es.md ). Show user a unified diff vs. the English source for visual sanity check (line count delta within ±15% is a healthy signal).
3b.6 Validate the translated file against the English source. The reference flag tells the validator to ignore relative refs that were already broken in the source — OD docs frequently link to website route slugs (e.g. skills/blog post/ ) that aren't files on disk; we don't want a structure preserving translation to fail because of pre existing dead refs.
If FAIL → surface verbatim, fix, retry.
3b.7 Render templates/PR BODY i18n.md with {{DOC NAME}} , {{LANG DISPLAY NAME}} , {{LANG CODE}} , {{TRANSLATED PATH}} , {{ENGLISH PATH}} , {{STATUS}} , {{TRANSLATION NOTES}} (one paragraph from the agent: anything tricky, untranslated terms it kept, etc.), {{DISCORD INVITE}} .
→ Step 7 .
Step 3c — Docs / blog / typo
3c.1 Setup workspace (slug docs ):
3c.2 Ask user (one AskUserQuestion ):
1. Auto discover small fixes (run discover doc gaps, pick something)
2. I have a specific fix in mind (free text)
3. I want to write a blog / case study (free text — what's the use case?)
3c.3 (Auto discover branch) Run:
Group by kind (typo / deadlink / todo). Show the user up to 6 candidates via AskUserQuestion . Once picked, apply the fix in code (typo: replace word; deadlink: ask user for the new URL; todo: that's a proper task, ask user to write the missing prose).
3c.4 (Specific fix branch) Read the file, apply user's described change. Confirm via diff.
3c.5 (Blog branch) First check whether OD has a blog directory:
If a docs/blog/ or similar exists, place the new post there. If not, ask the user where it should live, defaulting to docs/<slug .md . Generate an outline → user fills in user specific bits (their use case, screenshots, the prompt they used, the rendered output) → agent stitches into a final Markdown.
3c.6 Validate every changed/added file. For files that already exist in the repo (typo fix, dead link fix, doc edit), pass reference pointing at HEAD's version so we only fail on relative refs the user introduced , not on pre existing route slugs:
3c.7 Render templates/PR BODY docs.md with {{ONE LINE SUMMARY}} , {{DETAILS}} , {{FILES LIST}} , {{DISCORD INVITE}} .
→ Step 7 .
Step 3d — Bug report (issue path, no PR)
3d.1 Read OD's actual schema at runtime to make sure we mirror it:
If the schema has drifted from the template ( templates/ISSUE BODY bug.md ), regenerate the body to match.
3d.2 Ask the user via AskUserQuestion , one structured prompt per critical field. Use plain language , not the YAML field names:
Bug report field Prompt to user
description "What went wrong? One sentence is fine."
steps "How can I reproduce it? Walk me through step by step."
expected "What did you expect to happen?"
version "Which OD version are you running? (About menu, or od version )"
platform dropdown: macOS (Apple Silicon) / macOS (Intel) / Windows / Linux / Other
logs "Any error logs you can paste? Skip if you don't have them."
screenshots "Path to a screenshot? Skip if you don't have one."
Translate every prompt above into the user's chat language at runtime.
3d.3 Auto collect what we can (these don't need to ask the user):
OS family from uname
Node version from node v if relevant
3d.4 Dedupe: extract 3–5 keywords from the description, run:
If matches exist, present them to the user via AskUserQuestion (translate to user's language): "These existing issues look related. Do you want to: (a) comment on an existing one, (b) open a new issue anyway, (c) cancel?"
3d.5 If proceeding with new issue, render templates/ISSUE BODY bug.md and submit:
3d.6 Print the issue URL on its own line. Do not push branches or open PRs from this branch.
Step 7 — Preview + confirm (shared, PR branches only)
Show the user a clean summary:
Then git C "$WORKDIR" diff stat and a head 40 of the rendered PR body for visual sanity.
Required AskUserQuestion confirmation (translate to user's language): "Push this PR?" with three options:
Ship it — proceed to Step 8
Let me revise — return to the relevant Step 3 sub step
Cancel — leave the workspace on disk, tell the user the path so they can return later, exit
Never push without an explicit "Ship it".
Step 8 — Push & open PR
Print the PR URL on its own line. Done.
Safety rails (mandatory)
Never push to main / master / develop . The push scripts refuse.
Never force push. Just don't.
All workspace activity stays under $OD WORK ROOT (default $HOME/od contrib work ). od::assert in workroot enforces this.
Bug report path always runs the dedupe search before gh issue create .
Honor user memory: skip GitHub user xxiaoxiong from any contributor lookup ([[feedback no outreach xxiaoxiong]]).
When NOT to use this skill
The user wants to fix a daemon / web bug or add a feature with code changes → use auto github contributor instead (it has the TDD loop). This skill deliberately doesn't run lint/typecheck/tests because content paths don't need them.
The user wants to generate a Skill / Design System from scratch → that's OpenDesign itself. Run OD first, get an artifact, then come back here to ship it.