diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f0a609c5..2109ba79 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -24,16 +24,18 @@ post it on the board first, where others can vote on it. ## 1. Prerequisites -Follow the [Serverpod installation guide](https://docs.serverpod.dev/installation) to install +Install Flutter, Serverpod, and a frontier coding agent such as Codex, Claude Code, Antigravity, +or Cursor. The [Serverpod installation guide](https://docs.serverpod.dev/installation) covers Flutter, Dart and what Serverpod needs on your machine. You also need: - **Flutter** 3.47.5 (stable) or newer. The version CI uses is pinned in `.github/workflows/tests.yml`. -- **An AI coding agent.** [Claude Code](https://claude.com/claude-code) is recommended; any agent - that reads `AGENTS.md` and can use MCP servers works. +- **A frontier coding agent** that reads `AGENTS.md` and can use MCP servers. - Git and a GitHub account. -## 2. Install the Serverpod CLI +## 2. Get the right version of Serverpod + +Use Dart's install command to make sure that you are using the right version of Serverpod: ```bash dart install serverpod_cli 4.1.0-rc.1 @@ -50,7 +52,8 @@ page). The fork is your own copy: you push your changes to it and open the pull ## 4. Clone the repository -Clone your fork (replace `` with your GitHub username) and get the packages: +Clone your fork to your local machine (replace `` with your GitHub username) and get the +code: ```bash git clone https://github.com//wonky.git @@ -69,38 +72,32 @@ Its values are development defaults that work as they are (they are not secrets; elsewhere). AI keys are optional: without them, the in-app assistant asks each user for their own key, and the board skips its AI checks. -## 6. Run Wonky Work - -```bash -serverpod start -``` - -Run it in `wonky_server`. It starts the development database, the server, applies migrations, watches for changes and hot -reloads. The apps are started on demand from its UI, or by your agent through the `serverpod` MCP -server. The repository configures it, together with the `dart` MCP server and the Flutter and -Serverpod skills, for Claude Code (`.mcp.json`, `.claude/`), Codex (`.codex/`, `.agents/`), Cursor -(`.cursor/`) and Antigravity (`.agents/`). -The apps run at http://localhost:8082/drive/ (and `/write/`, `/sheets/`, `/slides/`) once built, -or on their own dev ports when started from `serverpod start`. - -Sign up with any email: in development the verification code is printed in the server log. +## 6. Pick a task -## 7. Build the task - -1. On the task page, press **Claim this task**. Note your claim code (for example `7Q4F-K2M9`). -2. Create a branch in your fork. +1. Claim a task under [Up for grabs](https://wonky.work/improvements/tasks): on the task page, + press **Claim this task**. Note your claim code (for example `7Q4F-K2M9`). +2. Start your agent with the `wonky` folder (the repository root) as its working directory. 3. Copy the task's prompt (**Copy prompt**) and give it to your agent. The prompt points the agent - at `AGENTS.md` and the specs, which are the source of truth. + at `AGENTS.md` and the specs, which are the source of truth. Let the agent do its job. 4. Review what the agent did, run the app, and check the acceptance criteria yourself. -5. Run the checklist from `AGENTS.md`: `dart analyze`, `dart format`, and the tests of the - packages you changed. + +You don't need to start the server yourself: the agent starts it, together with the development +database, through the `serverpod` MCP server, and starts the apps the same way. The repository +configures it, together with the `dart` MCP server and the Flutter and Serverpod skills, for +Claude Code (`.mcp.json`, `.claude/`), Codex (`.codex/`, `.agents/`), Cursor (`.cursor/`) and +Antigravity (`.agents/`). To watch it or start an app by hand, run `serverpod start` in +`wonky_server`; it attaches to the running server. Sign up with any email: in development the +verification code is printed in the server log. You can **release** a claim at any time if you can't finish. Two active claims per person at a time. -## 8. Open the pull request +## 7. Open a pull request -Open it against `main`. The description must contain exactly one of each line: +Your agent will help you open a pull request towards +[serverpod/wonky](https://github.com/serverpod/wonky/pulls), from a branch in your fork against +`main`. Before it does, it runs the checklist from `AGENTS.md`: `dart analyze`, `dart format`, and +the tests of the packages you changed. The description must contain exactly one of each line: ``` Wonky-Task: T-12 @@ -116,7 +113,7 @@ Add a short summary of how each acceptance criterion is met (the PR template has advisory; maintainers make the call. - The normal CI (analyze, format, tests) must pass. -## 9. Sign the CLA and follow up +## 8. Sign the CLA and follow up If you haven't signed the Serverpod Contributor License Agreement (CLA) yet, sign it on GitHub: the CLA Assistant bot comments on your pull request, and you reply with the line from diff --git a/packages/wonky_app/lib/l10n/wonky_app_en.arb b/packages/wonky_app/lib/l10n/wonky_app_en.arb index 581ba667..0ddda7d8 100644 --- a/packages/wonky_app/lib/l10n/wonky_app_en.arb +++ b/packages/wonky_app/lib/l10n/wonky_app_en.arb @@ -2805,19 +2805,30 @@ "boardAddPosts": "Add issues…", "boardFieldPostNumbers": "Issue numbers", "boardHowToBuild": "How to build it", - "boardStepSetupNumber": "1.", - "@boardStepSetupNumber": { - "description": "The number of the first step of How to build it, before the link boardStepSetupLink." + "boardStepSetup": "1. Read the {guide} and set up your development environment", + "@boardStepSetup": { + "description": "Step 1 of How to build it. {guide} is the link boardStepSetupLink to the How to contribute page.", + "placeholders": { + "guide": { + "type": "String" + } + } }, - "boardStepSetupLink": "Set up your development environment", + "boardStepSetupLink": "contribution guide", "@boardStepSetupLink": { - "description": "Step 1 of How to build it: a link to the How to contribute page." + "description": "The link in boardStepSetup: opens the How to contribute page." }, - "boardInstallTools": "Install Flutter, Dart and the Serverpod CLI:", "boardInstallGuide": "Serverpod installation guide", "boardStepPrompt": "2. Give your coding agent the prompt", "boardStepPr": "3. Open a pull request", - "boardStepPromptLocked": "2. Give your coding agent the prompt (claim the task to get the prompt).", + "boardStepClaim": "2. Claim the task to get a prompt", + "@boardStepClaim": { + "description": "Step 2 of How to build it for everyone but the claimant and admins, while the task is up for grabs." + }, + "boardStepPaste": "3. Paste the prompt into your AI agent using a frontier model", + "@boardStepPaste": { + "description": "Step 3 of How to build it for everyone but the claimant and admins, while the task is up for grabs." + }, "boardPrRules": "One task per pull request, against main. Put these two lines in its description:", "boardPullRequest": "Pull request", "boardPrNumber": "Pull request #{number}", @@ -2846,24 +2857,23 @@ "boardContributeTitle": "How to contribute", "boardContributeIntro": "Anyone can build a task that is up for grabs. Claim it, let a coding agent do the work with the task's prompt, and open a pull request.", "boardContribStep1Title": "Get the tools", - "boardContribStep1": "Install Flutter, Dart and the Serverpod CLI, and an AI coding agent that reads AGENTS.md, such as Claude Code.", - "boardContribStep2Title": "Install or update the Serverpod CLI", - "boardContribStep2": "It runs the server and the apps. The same command updates an installed CLI to this version. Add Dart's install directory to your PATH if serverpod is not found.", + "boardContribStep1": "Install Flutter, Serverpod, and a frontier coding agent such as Codex, Claude Code, Antigravity, or Cursor.", + "boardContribStep2Title": "Get the right version of Serverpod", + "boardContribStep2": "Use Dart's install command to make sure that we are using the right version of Serverpod.", "boardContribStep3Title": "Fork the repository", "boardContribStep3": "Create your own copy of the repository on GitHub. You push your changes to your fork and open the pull request from there.", "boardContribForkLink": "Fork on GitHub", "boardContribStep4Title": "Clone the repository", - "boardContribStep4": "Clone your fork to your machine (replace with your GitHub username) and get the packages.", + "boardContribStep4": "Clone your fork to your local machine (replace with your GitHub username) and get the code.", "boardContribStep5Title": "Configure the server", "boardContribStep5": "Create your passwords file in wonky_server. Its development values work as they are; AI keys are optional.", - "boardContribStep6Title": "Start the server", - "boardContribStep6": "Run it in wonky_server: it starts the development database, applies the migrations and hot reloads. Start an app from its UI or let your agent do it through the serverpod MCP server (.mcp.json is in the repository). Sign up with any email; in development the code is in the server log.", - "boardContribStep7Title": "Pick a task", - "boardContribStep7": "Claim a task under Up for grabs, paste its prompt into your agent and review the result.", - "boardContribStep8Title": "Open a pull request", - "boardContribStep8": "One task per pull request. The description contains the Wonky-Task and Wonky-Claim lines from the task page. Pull requests without a valid task are closed after 7 days.", - "boardContribStep9Title": "Sign the CLA and follow up", - "boardContribStep9": "If you haven't signed the Serverpod contributor license agreement (CLA) yet, sign it on GitHub: the CLA Assistant bot asks for it on your pull request, and you reply with the line below. You sign it once. Then check back once your pull request has been reviewed, and fix any issues the review points out.", + "boardContribStep6Title": "Pick a task", + "boardContribStep6": "Claim a task under Up for grabs, make sure you have wonky as the agent's working directory, let the agent do its job and review the result.", + "boardContribStep7Title": "Open a pull request", + "boardContribStep7": "Your agent will help you open a pull request towards Wonky's repository.", + "boardContribPullRequests": "View pull requests", + "boardContribStep8Title": "Sign the CLA and follow up", + "boardContribStep8": "If you haven't signed the Serverpod contributor license agreement (CLA) yet, sign it on GitHub: the CLA Assistant bot asks for it on your pull request, and you reply with the line below. You sign it once. Then check back once your pull request has been reviewed, and fix any issues the review points out.", "boardContribLicense": "Contributions are accepted under the repository's BSD-3-Clause license.", "boardContribSecurity": "Found a security issue? Email {email}. Never post it on the board or in a pull request.", "@boardContribSecurity": { diff --git a/packages/wonky_app/lib/l10n/wonky_app_en_XA.arb b/packages/wonky_app/lib/l10n/wonky_app_en_XA.arb index 73f5335b..ba3cdf22 100644 --- a/packages/wonky_app/lib/l10n/wonky_app_en_XA.arb +++ b/packages/wonky_app/lib/l10n/wonky_app_en_XA.arb @@ -1184,13 +1184,13 @@ "boardAddPosts": "[Åðð îššûéš… one]", "boardFieldPostNumbers": "[Κšûé ñûɱƀéŕš one t]", "boardHowToBuild": "[Ĥöŵ ţö ƀûîļð îţ one t]", - "boardStepSetupNumber": "[1. o]", - "boardStepSetupLink": "[Šéţ ûþ ýöûŕ ðéṽéļöþɱéñţ éñṽîŕöñɱéñţ one two thr]", - "boardInstallTools": "[Îñšţåļļ Ƒļûţţéŕ, Ðåŕţ åñð ţĥé Šéŕṽéŕþöð ÇĻÎ: one two three]", + "boardStepSetup": "[1. Ŕéåð ţĥé {guide} åñð šéţ ûþ ýöûŕ ðéṽéļöþɱéñţ éñṽîŕöñɱéñţ one two three fo]", + "boardStepSetupLink": "[çöñţŕîƀûţîöñ ĝûîðé one tw]", "boardInstallGuide": "[Šéŕṽéŕþöð îñšţåļļåţîöñ ĝûîðé one two th]", "boardStepPrompt": "[2. Ĝîṽé ýöûŕ çöðîñĝ åĝéñţ ţĥé þŕöɱþţ one two thr]", "boardStepPr": "[3. Öþéñ å þûļļ ŕéǫûéšţ one two]", - "boardStepPromptLocked": "[2. Ĝîṽé ýöûŕ çöðîñĝ åĝéñţ ţĥé þŕöɱþţ (çļåîɱ ţĥé ţåšķ ţö ĝéţ ţĥé þŕöɱþţ). one two three four fi]", + "boardStepClaim": "[2. Çļåîɱ ţĥé ţåšķ ţö ĝéţ å þŕöɱþţ one two th]", + "boardStepPaste": "[3. Þåšţé ţĥé þŕöɱþţ îñţö ýöûŕ ÅÎ åĝéñţ ûšîñĝ å ƒŕöñţîéŕ ɱöðéļ one two three four]", "boardPrRules": "[Öñé ţåšķ þéŕ þûļļ ŕéǫûéšţ, åĝåîñšţ ɱåîñ. Þûţ ţĥéšé ţŵö ļîñéš îñ îţš ðéšçŕîþţîöñ: one two three four five]", "boardPullRequest": "[Þûļļ ŕéǫûéšţ one]", "boardPrNumber": "[Þûļļ ŕéǫûéšţ #{number} one t]", @@ -1202,24 +1202,23 @@ "boardContributeTitle": "[Ĥöŵ ţö çöñţŕîƀûţé one tw]", "boardContributeIntro": "[Åñýöñé çåñ ƀûîļð å ţåšķ ţĥåţ îš ûþ ƒöŕ ĝŕåƀš. Çļåîɱ îţ, ļéţ å çöðîñĝ åĝéñţ ðö ţĥé ŵöŕķ ŵîţĥ ţĥé ţåšķ'š þŕöɱþţ, åñð öþéñ å þûļļ ŕéǫûéšţ. one two three four five six seven eigh]", "boardContribStep1Title": "[Ĝéţ ţĥé ţööļš one]", - "boardContribStep1": "[Îñšţåļļ Ƒļûţţéŕ, Ðåŕţ åñð ţĥé Šéŕṽéŕþöð ÇĻÎ, åñð åñ ÅÎ çöðîñĝ åĝéñţ ţĥåţ ŕéåðš ÅĜÉÑŢŠ.ɱð, šûçĥ åš Çļåûðé Çöðé. one two three four five six seven]", - "boardContribStep2Title": "[Îñšţåļļ öŕ ûþðåţé ţĥé Šéŕṽéŕþöð ÇĻÎ one two thr]", - "boardContribStep2": "[Îţ ŕûñš ţĥé šéŕṽéŕ åñð ţĥé åþþš. Ţĥé šåɱé çöɱɱåñð ûþðåţéš åñ îñšţåļļéð ÇĻÎ ţö ţĥîš ṽéŕšîöñ. Åðð Ðåŕţ'š îñšţåļļ ðîŕéçţöŕý ţö ýöûŕ ÞÅŢĤ îƒ šéŕṽéŕþöð îš ñöţ ƒöûñð. one two three four five six seven eight nine te]", + "boardContribStep1": "[Îñšţåļļ Ƒļûţţéŕ, Šéŕṽéŕþöð, åñð å ƒŕöñţîéŕ çöðîñĝ åĝéñţ šûçĥ åš Çöðéẋ, Çļåûðé Çöðé, Åñţîĝŕåṽîţý, öŕ Çûŕšöŕ. one two three four five six seven]", + "boardContribStep2Title": "[Ĝéţ ţĥé ŕîĝĥţ ṽéŕšîöñ öƒ Šéŕṽéŕþöð one two thr]", + "boardContribStep2": "[Ûšé Ðåŕţ'š îñšţåļļ çöɱɱåñð ţö ɱåķé šûŕé ţĥåţ ŵé åŕé ûšîñĝ ţĥé ŕîĝĥţ ṽéŕšîöñ öƒ Šéŕṽéŕþöð. one two three four five si]", "boardContribStep3Title": "[Ƒöŕķ ţĥé ŕéþöšîţöŕý one tw]", "boardContribStep3": "[Çŕéåţé ýöûŕ öŵñ çöþý öƒ ţĥé ŕéþöšîţöŕý öñ ĜîţĤûƀ. Ýöû þûšĥ ýöûŕ çĥåñĝéš ţö ýöûŕ ƒöŕķ åñð öþéñ ţĥé þûļļ ŕéǫûéšţ ƒŕöɱ ţĥéŕé. one two three four five six seven e]", "boardContribForkLink": "[Ƒöŕķ öñ ĜîţĤûƀ one t]", "boardContribStep4Title": "[Çļöñé ţĥé ŕéþöšîţöŕý one two]", - "boardContribStep4": "[Çļöñé ýöûŕ ƒöŕķ ţö ýöûŕ ɱåçĥîñé (ŕéþļåçé <ýöû> ŵîţĥ ýöûŕ ĜîţĤûƀ ûšéŕñåɱé) åñð ĝéţ ţĥé þåçķåĝéš. one two three four five six]", + "boardContribStep4": "[Çļöñé ýöûŕ ƒöŕķ ţö ýöûŕ ļöçåļ ɱåçĥîñé (ŕéþļåçé <ýöû> ŵîţĥ ýöûŕ ĜîţĤûƀ ûšéŕñåɱé) åñð ĝéţ ţĥé çöðé. one two three four five six s]", "boardContribStep5Title": "[Çöñƒîĝûŕé ţĥé šéŕṽéŕ one two]", "boardContribStep5": "[Çŕéåţé ýöûŕ þåššŵöŕðš ƒîļé îñ ŵöñķý_šéŕṽéŕ. Îţš ðéṽéļöþɱéñţ ṽåļûéš ŵöŕķ åš ţĥéý åŕé; ÅÎ ķéýš åŕé öþţîöñåļ. one two three four five six seve]", - "boardContribStep6Title": "[Šţåŕţ ţĥé šéŕṽéŕ one t]", - "boardContribStep6": "[Ŕûñ îţ îñ ŵöñķý_šéŕṽéŕ: îţ šţåŕţš ţĥé ðéṽéļöþɱéñţ ðåţåƀåšé, åþþļîéš ţĥé ɱîĝŕåţîöñš åñð ĥöţ ŕéļöåðš. Šţåŕţ åñ åþþ ƒŕöɱ îţš ÛÎ öŕ ļéţ ýöûŕ åĝéñţ ðö îţ ţĥŕöûĝĥ ţĥé šéŕṽéŕþöð ṀÇÞ šéŕṽéŕ (.ɱçþ.ĵšöñ îš îñ ţĥé ŕéþöšîţöŕý). Šîĝñ ûþ ŵîţĥ åñý éɱåîļ; îñ ðéṽéļöþɱéñţ ţĥé çöðé îš îñ ţĥé šéŕṽéŕ ļöĝ. one two three four five six seven eight nine ten one two three four five six seven]", - "boardContribStep7Title": "[Þîçķ å ţåšķ one]", - "boardContribStep7": "[Çļåîɱ å ţåšķ ûñðéŕ Ûþ ƒöŕ ĝŕåƀš, þåšţé îţš þŕöɱþţ îñţö ýöûŕ åĝéñţ åñð ŕéṽîéŵ ţĥé ŕéšûļţ. one two three four five si]", - "boardContribStep8Title": "[Öþéñ å þûļļ ŕéǫûéšţ one tw]", - "boardContribStep8": "[Öñé ţåšķ þéŕ þûļļ ŕéǫûéšţ. Ţĥé ðéšçŕîþţîöñ çöñţåîñš ţĥé Ŵöñķý-Ţåšķ åñð Ŵöñķý-Çļåîɱ ļîñéš ƒŕöɱ ţĥé ţåšķ þåĝé. Þûļļ ŕéǫûéšţš ŵîţĥöûţ å ṽåļîð ţåšķ åŕé çļöšéð åƒţéŕ 7 ðåýš. one two three four five six seven eight nine ten o]", - "boardContribStep9Title": "[Šîĝñ ţĥé ÇĻÅ åñð ƒöļļöŵ ûþ one two]", - "boardContribStep9": "[΃ ýöû ĥåṽéñ'ţ šîĝñéð ţĥé Šéŕṽéŕþöð çöñţŕîƀûţöŕ ļîçéñšé åĝŕééɱéñţ (ÇĻÅ) ýéţ, šîĝñ îţ öñ ĜîţĤûƀ: ţĥé ÇĻÅ Åššîšţåñţ ƀöţ åšķš ƒöŕ îţ öñ ýöûŕ þûļļ ŕéǫûéšţ, åñð ýöû ŕéþļý ŵîţĥ ţĥé ļîñé ƀéļöŵ. Ýöû šîĝñ îţ öñçé. Ţĥéñ çĥéçķ ƀåçķ öñçé ýöûŕ þûļļ ŕéǫûéšţ ĥåš ƀééñ ŕéṽîéŵéð, åñð ƒîẋ åñý îššûéš ţĥé ŕéṽîéŵ þöîñţš öûţ. one two three four five six seven eight nine ten one two three four five six seven eight]", + "boardContribStep6Title": "[Þîçķ å ţåšķ one]", + "boardContribStep6": "[Çļåîɱ å ţåšķ ûñðéŕ Ûþ ƒöŕ ĝŕåƀš, ɱåķé šûŕé ýöû ĥåṽé ŵöñķý åš ţĥé åĝéñţ'š ŵöŕķîñĝ ðîŕéçţöŕý, ļéţ ţĥé åĝéñţ ðö îţš ĵöƀ åñð ŕéṽîéŵ ţĥé ŕéšûļţ. one two three four five six seven eight]", + "boardContribStep7Title": "[Öþéñ å þûļļ ŕéǫûéšţ one tw]", + "boardContribStep7": "[Ýöûŕ åĝéñţ ŵîļļ ĥéļþ ýöû öþéñ å þûļļ ŕéǫûéšţ ţöŵåŕðš Ŵöñķý'š ŕéþöšîţöŕý. one two three four fiv]", + "boardContribPullRequests": "[Ṽîéŵ þûļļ ŕéǫûéšţš one tw]", + "boardContribStep8Title": "[Šîĝñ ţĥé ÇĻÅ åñð ƒöļļöŵ ûþ one two]", + "boardContribStep8": "[΃ ýöû ĥåṽéñ'ţ šîĝñéð ţĥé Šéŕṽéŕþöð çöñţŕîƀûţöŕ ļîçéñšé åĝŕééɱéñţ (ÇĻÅ) ýéţ, šîĝñ îţ öñ ĜîţĤûƀ: ţĥé ÇĻÅ Åššîšţåñţ ƀöţ åšķš ƒöŕ îţ öñ ýöûŕ þûļļ ŕéǫûéšţ, åñð ýöû ŕéþļý ŵîţĥ ţĥé ļîñé ƀéļöŵ. Ýöû šîĝñ îţ öñçé. Ţĥéñ çĥéçķ ƀåçķ öñçé ýöûŕ þûļļ ŕéǫûéšţ ĥåš ƀééñ ŕéṽîéŵéð, åñð ƒîẋ åñý îššûéš ţĥé ŕéṽîéŵ þöîñţš öûţ. one two three four five six seven eight nine ten one two three four five six seven eight]", "boardContribLicense": "[Çöñţŕîƀûţîöñš åŕé åççéþţéð ûñðéŕ ţĥé ŕéþöšîţöŕý'š ƁŠÐ-3-Çļåûšé ļîçéñšé. one two three four five]", "boardContribSecurity": "[Ƒöûñð å šéçûŕîţý îššûé? Éɱåîļ {email}. Ñéṽéŕ þöšţ îţ öñ ţĥé ƀöåŕð öŕ îñ å þûļļ ŕéǫûéšţ. one two three four five]", "boardContributeGuide": "[Ƒûļļ ĝûîðé öñ ĜîţĤûƀ one tw]", diff --git a/packages/wonky_app/lib/src/board/pages/board_chrome.dart b/packages/wonky_app/lib/src/board/pages/board_chrome.dart index a4c29b09..3488adac 100644 --- a/packages/wonky_app/lib/src/board/pages/board_chrome.dart +++ b/packages/wonky_app/lib/src/board/pages/board_chrome.dart @@ -457,7 +457,7 @@ class BoardTopActions extends StatelessWidget { if (showContribute) ( 'board.howToContribute', - LucideIcons.gitPullRequest, + LucideIcons.wrench, l.boardContributeLink, () => boardOpenContribute(s), ), diff --git a/packages/wonky_app/lib/src/board/pages/contribute_page.dart b/packages/wonky_app/lib/src/board/pages/contribute_page.dart index 75e0317f..b9478249 100644 --- a/packages/wonky_app/lib/src/board/pages/contribute_page.dart +++ b/packages/wonky_app/lib/src/board/pages/contribute_page.dart @@ -31,8 +31,9 @@ const boardClaSignLine = /// The setup commands of `CONTRIBUTING.md` after the tools are installed /// (specs/16 §10.3), one per copy button: install (or update) the CLI, /// clone your fork of [repository] and get the packages, configure the -/// server, run it. Forking has no command: it is done on GitHub. Serverpod starts the development database itself, so -/// there is no Docker step. +/// server. Forking has no command: it is done on GitHub. The agent starts +/// the server (and with it the development database) through the +/// `serverpod` MCP server, so there is no run or Docker step. List boardSetupCommands(String repository) { final name = repository.split('/').last; return [ @@ -41,50 +42,11 @@ List boardSetupCommands(String repository) { 'cd $name && flutter pub get', 'cd wonky_server', 'cp config/passwords.example.yaml config/passwords.yaml', - 'serverpod start', ]; } -/// *Install Flutter, Dart and the Serverpod CLI: Serverpod installation -/// guide* — the first setup step, a link to [boardServerpodInstallUrl] -/// through the external-link confirmation. -class BoardInstallGuideLink extends StatelessWidget { - const BoardInstallGuideLink({ - super.key, - required this.services, - required this.linkKey, - }); - - final ShellServices services; - final String linkKey; - - @override - Widget build(BuildContext context) { - final l = WonkyAppLocalizations.of(context); - final theme = ShadTheme.of(context); - return Wrap( - crossAxisAlignment: WrapCrossAlignment.center, - spacing: 4, - runSpacing: 2, - children: [ - Text(l.boardInstallTools, style: theme.textTheme.small), - BoardTextLink( - key: ValueKey(linkKey), - label: l.boardInstallGuide, - external: true, - onTap: () => confirmExternalLink( - context, - services, - url: boardServerpodInstallUrl, - ), - ), - ], - ); - } -} - /// `/improvements/contribute` (specs/16 §10.3): the short version of -/// `CONTRIBUTING.md` (steps 1–9) as app strings, so it works without +/// `CONTRIBUTING.md` (steps 1–8) as app strings, so it works without /// GitHub, with copy buttons and a link to the full guide. class BoardContributePage extends StatefulWidget { const BoardContributePage({super.key, required this.services}); @@ -123,6 +85,20 @@ class _BoardContributePageState extends State { final cmds = boardSetupCommands(repo); final security = BoardHub.of(s).me.value?.securityContact ?? 'security@serverpod.dev'; + // The buttons under a step's text (Serverpod installation guide, Fork + // on GitHub, Up for grabs, View pull requests). + Widget button(String key, String label, VoidCallback onPressed) => Align( + alignment: AlignmentDirectional.centerStart, + child: ShadButton.outline( + key: ValueKey(key), + size: ShadButtonSize.sm, + onPressed: onPressed, + // Ellipsized on a narrow window rather than overflowing. + child: Flexible( + child: Text(label, maxLines: 1, overflow: TextOverflow.ellipsis), + ), + ), + ); Widget step( int n, String title, @@ -175,26 +151,27 @@ class _BoardContributePageState extends State { Text(l.boardContributeIntro, style: theme.textTheme.p), const SizedBox(height: 20), step(1, l.boardContribStep1Title, l.boardContribStep1, [ - BoardInstallGuideLink( - services: s, - linkKey: 'board.contribute.installGuide', + button( + 'board.contribute.installGuide', + l.boardInstallGuide, + () => confirmExternalLink( + context, + s, + url: boardServerpodInstallUrl, + ), ), ]), step(2, l.boardContribStep2Title, l.boardContribStep2, [ BoardCopyLine(text: cmds[0], copyKey: 'board.contribute.copy.0'), ]), step(3, l.boardContribStep3Title, l.boardContribStep3, [ - Align( - alignment: AlignmentDirectional.centerStart, - child: BoardTextLink( - key: const ValueKey('board.contribute.fork'), - label: l.boardContribForkLink, - external: true, - onTap: () => confirmExternalLink( - context, - s, - url: 'https://github.com/$repo/fork', - ), + button( + 'board.contribute.fork', + l.boardContribForkLink, + () => confirmExternalLink( + context, + s, + url: 'https://github.com/$repo/fork', ), ), ]), @@ -207,26 +184,24 @@ class _BoardContributePageState extends State { BoardCopyLine(text: cmds[i], copyKey: 'board.contribute.copy.$i'), ]), step(6, l.boardContribStep6Title, l.boardContribStep6, [ - BoardCopyLine(text: cmds[5], copyKey: 'board.contribute.copy.5'), + button( + 'board.contribute.tasks', + l.boardTabTasks, + () => boardOpenList(s, BoardTab.tasks), + ), ]), step(7, l.boardContribStep7Title, l.boardContribStep7, [ - Align( - alignment: AlignmentDirectional.centerStart, - child: ShadButton.outline( - key: const ValueKey('board.contribute.tasks'), - size: ShadButtonSize.sm, - onPressed: () => boardOpenList(s, BoardTab.tasks), - child: Text(l.boardTabTasks), + button( + 'board.contribute.pulls', + l.boardContribPullRequests, + () => confirmExternalLink( + context, + s, + url: 'https://github.com/$repo/pulls', ), ), ]), step(8, l.boardContribStep8Title, l.boardContribStep8, [ - const BoardCopyLine( - text: 'Wonky-Task: T-12\nWonky-Claim: XXXX-XXXX', - copyKey: 'board.contribute.copy.prLines', - ), - ]), - step(9, l.boardContribStep9Title, l.boardContribStep9, [ const BoardCopyLine( text: boardClaSignLine, copyKey: 'board.contribute.copy.cla', diff --git a/packages/wonky_app/lib/src/board/pages/task_page.dart b/packages/wonky_app/lib/src/board/pages/task_page.dart index a6550d8d..bc1604fb 100644 --- a/packages/wonky_app/lib/src/board/pages/task_page.dart +++ b/packages/wonky_app/lib/src/board/pages/task_page.dart @@ -384,6 +384,9 @@ class _BoardTaskPageState extends State { if (!full && t.status != BoardTaskStatus.published) { return const SizedBox.shrink(); } + // Step 1's sentence around its link (the {guide} placeholder). + const marker = '\u0000'; + final setup = l.boardStepSetup(marker).split(marker); return Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ @@ -404,29 +407,33 @@ class _BoardTaskPageState extends State { children: [ // Step 1: the setup is on How to contribute (same tab, under // the board's breadcrumb). - Row( - crossAxisAlignment: CrossAxisAlignment.start, - spacing: 4, - children: [ - Text(l.boardStepSetupNumber, style: theme.textTheme.small), - Flexible( - child: BoardTextLink( - key: const ValueKey('board.task.setup'), - label: l.boardStepSetupLink, - onTap: () => boardOpenContribute(s), + Text.rich( + TextSpan( + children: [ + TextSpan(text: setup.first), + WidgetSpan( + alignment: PlaceholderAlignment.baseline, + baseline: TextBaseline.alphabetic, + child: BoardTextLink( + key: const ValueKey('board.task.setup'), + label: l.boardStepSetupLink, + onTap: () => boardOpenContribute(s), + ), ), - ), - ], + if (setup.length > 1) TextSpan(text: setup.last), + ], + ), + style: theme.textTheme.small, ), if (!full) ...[ // Not claimed by the viewer: the outline only (the Claim button // is in the header). Text( - l.boardStepPromptLocked, + l.boardStepClaim, key: const ValueKey('board.task.promptLocked'), style: theme.textTheme.small, ), - Text(l.boardStepPr, style: theme.textTheme.small), + Text(l.boardStepPaste, style: theme.textTheme.small), ] else ...[ Row( children: [ diff --git a/packages/wonky_app/lib/src/l10n/wonky_app_localizations.dart b/packages/wonky_app/lib/src/l10n/wonky_app_localizations.dart index bd7ceeeb..926ce2b9 100644 --- a/packages/wonky_app/lib/src/l10n/wonky_app_localizations.dart +++ b/packages/wonky_app/lib/src/l10n/wonky_app_localizations.dart @@ -7198,24 +7198,18 @@ abstract class WonkyAppLocalizations { /// **'How to build it'** String get boardHowToBuild; - /// The number of the first step of How to build it, before the link boardStepSetupLink. + /// Step 1 of How to build it. {guide} is the link boardStepSetupLink to the How to contribute page. /// /// In en, this message translates to: - /// **'1.'** - String get boardStepSetupNumber; + /// **'1. Read the {guide} and set up your development environment'** + String boardStepSetup(String guide); - /// Step 1 of How to build it: a link to the How to contribute page. + /// The link in boardStepSetup: opens the How to contribute page. /// /// In en, this message translates to: - /// **'Set up your development environment'** + /// **'contribution guide'** String get boardStepSetupLink; - /// No description provided for @boardInstallTools. - /// - /// In en, this message translates to: - /// **'Install Flutter, Dart and the Serverpod CLI:'** - String get boardInstallTools; - /// No description provided for @boardInstallGuide. /// /// In en, this message translates to: @@ -7234,11 +7228,17 @@ abstract class WonkyAppLocalizations { /// **'3. Open a pull request'** String get boardStepPr; - /// No description provided for @boardStepPromptLocked. + /// Step 2 of How to build it for everyone but the claimant and admins, while the task is up for grabs. + /// + /// In en, this message translates to: + /// **'2. Claim the task to get a prompt'** + String get boardStepClaim; + + /// Step 3 of How to build it for everyone but the claimant and admins, while the task is up for grabs. /// /// In en, this message translates to: - /// **'2. Give your coding agent the prompt (claim the task to get the prompt).'** - String get boardStepPromptLocked; + /// **'3. Paste the prompt into your AI agent using a frontier model'** + String get boardStepPaste; /// No description provided for @boardPrRules. /// @@ -7309,19 +7309,19 @@ abstract class WonkyAppLocalizations { /// No description provided for @boardContribStep1. /// /// In en, this message translates to: - /// **'Install Flutter, Dart and the Serverpod CLI, and an AI coding agent that reads AGENTS.md, such as Claude Code.'** + /// **'Install Flutter, Serverpod, and a frontier coding agent such as Codex, Claude Code, Antigravity, or Cursor.'** String get boardContribStep1; /// No description provided for @boardContribStep2Title. /// /// In en, this message translates to: - /// **'Install or update the Serverpod CLI'** + /// **'Get the right version of Serverpod'** String get boardContribStep2Title; /// No description provided for @boardContribStep2. /// /// In en, this message translates to: - /// **'It runs the server and the apps. The same command updates an installed CLI to this version. Add Dart\'s install directory to your PATH if serverpod is not found.'** + /// **'Use Dart\'s install command to make sure that we are using the right version of Serverpod.'** String get boardContribStep2; /// No description provided for @boardContribStep3Title. @@ -7351,7 +7351,7 @@ abstract class WonkyAppLocalizations { /// No description provided for @boardContribStep4. /// /// In en, this message translates to: - /// **'Clone your fork to your machine (replace with your GitHub username) and get the packages.'** + /// **'Clone your fork to your local machine (replace with your GitHub username) and get the code.'** String get boardContribStep4; /// No description provided for @boardContribStep5Title. @@ -7369,50 +7369,44 @@ abstract class WonkyAppLocalizations { /// No description provided for @boardContribStep6Title. /// /// In en, this message translates to: - /// **'Start the server'** + /// **'Pick a task'** String get boardContribStep6Title; /// No description provided for @boardContribStep6. /// /// In en, this message translates to: - /// **'Run it in wonky_server: it starts the development database, applies the migrations and hot reloads. Start an app from its UI or let your agent do it through the serverpod MCP server (.mcp.json is in the repository). Sign up with any email; in development the code is in the server log.'** + /// **'Claim a task under Up for grabs, make sure you have wonky as the agent\'s working directory, let the agent do its job and review the result.'** String get boardContribStep6; /// No description provided for @boardContribStep7Title. /// /// In en, this message translates to: - /// **'Pick a task'** + /// **'Open a pull request'** String get boardContribStep7Title; /// No description provided for @boardContribStep7. /// /// In en, this message translates to: - /// **'Claim a task under Up for grabs, paste its prompt into your agent and review the result.'** + /// **'Your agent will help you open a pull request towards Wonky\'s repository.'** String get boardContribStep7; - /// No description provided for @boardContribStep8Title. + /// No description provided for @boardContribPullRequests. /// /// In en, this message translates to: - /// **'Open a pull request'** - String get boardContribStep8Title; - - /// No description provided for @boardContribStep8. - /// - /// In en, this message translates to: - /// **'One task per pull request. The description contains the Wonky-Task and Wonky-Claim lines from the task page. Pull requests without a valid task are closed after 7 days.'** - String get boardContribStep8; + /// **'View pull requests'** + String get boardContribPullRequests; - /// No description provided for @boardContribStep9Title. + /// No description provided for @boardContribStep8Title. /// /// In en, this message translates to: /// **'Sign the CLA and follow up'** - String get boardContribStep9Title; + String get boardContribStep8Title; - /// No description provided for @boardContribStep9. + /// No description provided for @boardContribStep8. /// /// In en, this message translates to: /// **'If you haven\'t signed the Serverpod contributor license agreement (CLA) yet, sign it on GitHub: the CLA Assistant bot asks for it on your pull request, and you reply with the line below. You sign it once. Then check back once your pull request has been reviewed, and fix any issues the review points out.'** - String get boardContribStep9; + String get boardContribStep8; /// No description provided for @boardContribLicense. /// diff --git a/packages/wonky_app/lib/src/l10n/wonky_app_localizations_en.dart b/packages/wonky_app/lib/src/l10n/wonky_app_localizations_en.dart index 924ec14f..a2eafaf3 100644 --- a/packages/wonky_app/lib/src/l10n/wonky_app_localizations_en.dart +++ b/packages/wonky_app/lib/src/l10n/wonky_app_localizations_en.dart @@ -4157,14 +4157,12 @@ class WonkyAppLocalizationsEn extends WonkyAppLocalizations { String get boardHowToBuild => 'How to build it'; @override - String get boardStepSetupNumber => '1.'; - - @override - String get boardStepSetupLink => 'Set up your development environment'; + String boardStepSetup(String guide) { + return '1. Read the $guide and set up your development environment'; + } @override - String get boardInstallTools => - 'Install Flutter, Dart and the Serverpod CLI:'; + String get boardStepSetupLink => 'contribution guide'; @override String get boardInstallGuide => 'Serverpod installation guide'; @@ -4176,8 +4174,11 @@ class WonkyAppLocalizationsEn extends WonkyAppLocalizations { String get boardStepPr => '3. Open a pull request'; @override - String get boardStepPromptLocked => - '2. Give your coding agent the prompt (claim the task to get the prompt).'; + String get boardStepClaim => '2. Claim the task to get a prompt'; + + @override + String get boardStepPaste => + '3. Paste the prompt into your AI agent using a frontier model'; @override String get boardPrRules => @@ -4220,14 +4221,14 @@ class WonkyAppLocalizationsEn extends WonkyAppLocalizations { @override String get boardContribStep1 => - 'Install Flutter, Dart and the Serverpod CLI, and an AI coding agent that reads AGENTS.md, such as Claude Code.'; + 'Install Flutter, Serverpod, and a frontier coding agent such as Codex, Claude Code, Antigravity, or Cursor.'; @override - String get boardContribStep2Title => 'Install or update the Serverpod CLI'; + String get boardContribStep2Title => 'Get the right version of Serverpod'; @override String get boardContribStep2 => - 'It runs the server and the apps. The same command updates an installed CLI to this version. Add Dart\'s install directory to your PATH if serverpod is not found.'; + 'Use Dart\'s install command to make sure that we are using the right version of Serverpod.'; @override String get boardContribStep3Title => 'Fork the repository'; @@ -4244,7 +4245,7 @@ class WonkyAppLocalizationsEn extends WonkyAppLocalizations { @override String get boardContribStep4 => - 'Clone your fork to your machine (replace with your GitHub username) and get the packages.'; + 'Clone your fork to your local machine (replace with your GitHub username) and get the code.'; @override String get boardContribStep5Title => 'Configure the server'; @@ -4254,31 +4255,27 @@ class WonkyAppLocalizationsEn extends WonkyAppLocalizations { 'Create your passwords file in wonky_server. Its development values work as they are; AI keys are optional.'; @override - String get boardContribStep6Title => 'Start the server'; + String get boardContribStep6Title => 'Pick a task'; @override String get boardContribStep6 => - 'Run it in wonky_server: it starts the development database, applies the migrations and hot reloads. Start an app from its UI or let your agent do it through the serverpod MCP server (.mcp.json is in the repository). Sign up with any email; in development the code is in the server log.'; + 'Claim a task under Up for grabs, make sure you have wonky as the agent\'s working directory, let the agent do its job and review the result.'; @override - String get boardContribStep7Title => 'Pick a task'; + String get boardContribStep7Title => 'Open a pull request'; @override String get boardContribStep7 => - 'Claim a task under Up for grabs, paste its prompt into your agent and review the result.'; + 'Your agent will help you open a pull request towards Wonky\'s repository.'; @override - String get boardContribStep8Title => 'Open a pull request'; + String get boardContribPullRequests => 'View pull requests'; @override - String get boardContribStep8 => - 'One task per pull request. The description contains the Wonky-Task and Wonky-Claim lines from the task page. Pull requests without a valid task are closed after 7 days.'; - - @override - String get boardContribStep9Title => 'Sign the CLA and follow up'; + String get boardContribStep8Title => 'Sign the CLA and follow up'; @override - String get boardContribStep9 => + String get boardContribStep8 => 'If you haven\'t signed the Serverpod contributor license agreement (CLA) yet, sign it on GitHub: the CLA Assistant bot asks for it on your pull request, and you reply with the line below. You sign it once. Then check back once your pull request has been reviewed, and fix any issues the review points out.'; @override @@ -9246,15 +9243,12 @@ class WonkyAppLocalizationsEnXa extends WonkyAppLocalizationsEn { String get boardHowToBuild => '[Ĥöŵ ţö ƀûîļð îţ one t]'; @override - String get boardStepSetupNumber => '[1. o]'; - - @override - String get boardStepSetupLink => - '[Šéţ ûþ ýöûŕ ðéṽéļöþɱéñţ éñṽîŕöñɱéñţ one two thr]'; + String boardStepSetup(String guide) { + return '[1. Ŕéåð ţĥé $guide åñð šéţ ûþ ýöûŕ ðéṽéļöþɱéñţ éñṽîŕöñɱéñţ one two three fo]'; + } @override - String get boardInstallTools => - '[Îñšţåļļ Ƒļûţţéŕ, Ðåŕţ åñð ţĥé Šéŕṽéŕþöð ÇĻÎ: one two three]'; + String get boardStepSetupLink => '[çöñţŕîƀûţîöñ ĝûîðé one tw]'; @override String get boardInstallGuide => '[Šéŕṽéŕþöð îñšţåļļåţîöñ ĝûîðé one two th]'; @@ -9267,8 +9261,11 @@ class WonkyAppLocalizationsEnXa extends WonkyAppLocalizationsEn { String get boardStepPr => '[3. Öþéñ å þûļļ ŕéǫûéšţ one two]'; @override - String get boardStepPromptLocked => - '[2. Ĝîṽé ýöûŕ çöðîñĝ åĝéñţ ţĥé þŕöɱþţ (çļåîɱ ţĥé ţåšķ ţö ĝéţ ţĥé þŕöɱþţ). one two three four fi]'; + String get boardStepClaim => '[2. Çļåîɱ ţĥé ţåšķ ţö ĝéţ å þŕöɱþţ one two th]'; + + @override + String get boardStepPaste => + '[3. Þåšţé ţĥé þŕöɱþţ îñţö ýöûŕ ÅÎ åĝéñţ ûšîñĝ å ƒŕöñţîéŕ ɱöðéļ one two three four]'; @override String get boardPrRules => @@ -9312,15 +9309,15 @@ class WonkyAppLocalizationsEnXa extends WonkyAppLocalizationsEn { @override String get boardContribStep1 => - '[Îñšţåļļ Ƒļûţţéŕ, Ðåŕţ åñð ţĥé Šéŕṽéŕþöð ÇĻÎ, åñð åñ ÅÎ çöðîñĝ åĝéñţ ţĥåţ ŕéåðš ÅĜÉÑŢŠ.ɱð, šûçĥ åš Çļåûðé Çöðé. one two three four five six seven]'; + '[Îñšţåļļ Ƒļûţţéŕ, Šéŕṽéŕþöð, åñð å ƒŕöñţîéŕ çöðîñĝ åĝéñţ šûçĥ åš Çöðéẋ, Çļåûðé Çöðé, Åñţîĝŕåṽîţý, öŕ Çûŕšöŕ. one two three four five six seven]'; @override String get boardContribStep2Title => - '[Îñšţåļļ öŕ ûþðåţé ţĥé Šéŕṽéŕþöð ÇĻÎ one two thr]'; + '[Ĝéţ ţĥé ŕîĝĥţ ṽéŕšîöñ öƒ Šéŕṽéŕþöð one two thr]'; @override String get boardContribStep2 => - '[Îţ ŕûñš ţĥé šéŕṽéŕ åñð ţĥé åþþš. Ţĥé šåɱé çöɱɱåñð ûþðåţéš åñ îñšţåļļéð ÇĻÎ ţö ţĥîš ṽéŕšîöñ. Åðð Ðåŕţ\'š îñšţåļļ ðîŕéçţöŕý ţö ýöûŕ ÞÅŢĤ îƒ šéŕṽéŕþöð îš ñöţ ƒöûñð. one two three four five six seven eight nine te]'; + '[Ûšé Ðåŕţ\'š îñšţåļļ çöɱɱåñð ţö ɱåķé šûŕé ţĥåţ ŵé åŕé ûšîñĝ ţĥé ŕîĝĥţ ṽéŕšîöñ öƒ Šéŕṽéŕþöð. one two three four five si]'; @override String get boardContribStep3Title => '[Ƒöŕķ ţĥé ŕéþöšîţöŕý one tw]'; @@ -9337,7 +9334,7 @@ class WonkyAppLocalizationsEnXa extends WonkyAppLocalizationsEn { @override String get boardContribStep4 => - '[Çļöñé ýöûŕ ƒöŕķ ţö ýöûŕ ɱåçĥîñé (ŕéþļåçé <ýöû> ŵîţĥ ýöûŕ ĜîţĤûƀ ûšéŕñåɱé) åñð ĝéţ ţĥé þåçķåĝéš. one two three four five six]'; + '[Çļöñé ýöûŕ ƒöŕķ ţö ýöûŕ ļöçåļ ɱåçĥîñé (ŕéþļåçé <ýöû> ŵîţĥ ýöûŕ ĜîţĤûƀ ûšéŕñåɱé) åñð ĝéţ ţĥé çöðé. one two three four five six s]'; @override String get boardContribStep5Title => '[Çöñƒîĝûŕé ţĥé šéŕṽéŕ one two]'; @@ -9347,31 +9344,27 @@ class WonkyAppLocalizationsEnXa extends WonkyAppLocalizationsEn { '[Çŕéåţé ýöûŕ þåššŵöŕðš ƒîļé îñ ŵöñķý_šéŕṽéŕ. Îţš ðéṽéļöþɱéñţ ṽåļûéš ŵöŕķ åš ţĥéý åŕé; ÅÎ ķéýš åŕé öþţîöñåļ. one two three four five six seve]'; @override - String get boardContribStep6Title => '[Šţåŕţ ţĥé šéŕṽéŕ one t]'; + String get boardContribStep6Title => '[Þîçķ å ţåšķ one]'; @override String get boardContribStep6 => - '[Ŕûñ îţ îñ ŵöñķý_šéŕṽéŕ: îţ šţåŕţš ţĥé ðéṽéļöþɱéñţ ðåţåƀåšé, åþþļîéš ţĥé ɱîĝŕåţîöñš åñð ĥöţ ŕéļöåðš. Šţåŕţ åñ åþþ ƒŕöɱ îţš ÛÎ öŕ ļéţ ýöûŕ åĝéñţ ðö îţ ţĥŕöûĝĥ ţĥé šéŕṽéŕþöð ṀÇÞ šéŕṽéŕ (.ɱçþ.ĵšöñ îš îñ ţĥé ŕéþöšîţöŕý). Šîĝñ ûþ ŵîţĥ åñý éɱåîļ; îñ ðéṽéļöþɱéñţ ţĥé çöðé îš îñ ţĥé šéŕṽéŕ ļöĝ. one two three four five six seven eight nine ten one two three four five six seven]'; + '[Çļåîɱ å ţåšķ ûñðéŕ Ûþ ƒöŕ ĝŕåƀš, ɱåķé šûŕé ýöû ĥåṽé ŵöñķý åš ţĥé åĝéñţ\'š ŵöŕķîñĝ ðîŕéçţöŕý, ļéţ ţĥé åĝéñţ ðö îţš ĵöƀ åñð ŕéṽîéŵ ţĥé ŕéšûļţ. one two three four five six seven eight]'; @override - String get boardContribStep7Title => '[Þîçķ å ţåšķ one]'; + String get boardContribStep7Title => '[Öþéñ å þûļļ ŕéǫûéšţ one tw]'; @override String get boardContribStep7 => - '[Çļåîɱ å ţåšķ ûñðéŕ Ûþ ƒöŕ ĝŕåƀš, þåšţé îţš þŕöɱþţ îñţö ýöûŕ åĝéñţ åñð ŕéṽîéŵ ţĥé ŕéšûļţ. one two three four five si]'; + '[Ýöûŕ åĝéñţ ŵîļļ ĥéļþ ýöû öþéñ å þûļļ ŕéǫûéšţ ţöŵåŕðš Ŵöñķý\'š ŕéþöšîţöŕý. one two three four fiv]'; @override - String get boardContribStep8Title => '[Öþéñ å þûļļ ŕéǫûéšţ one tw]'; + String get boardContribPullRequests => '[Ṽîéŵ þûļļ ŕéǫûéšţš one tw]'; @override - String get boardContribStep8 => - '[Öñé ţåšķ þéŕ þûļļ ŕéǫûéšţ. Ţĥé ðéšçŕîþţîöñ çöñţåîñš ţĥé Ŵöñķý-Ţåšķ åñð Ŵöñķý-Çļåîɱ ļîñéš ƒŕöɱ ţĥé ţåšķ þåĝé. Þûļļ ŕéǫûéšţš ŵîţĥöûţ å ṽåļîð ţåšķ åŕé çļöšéð åƒţéŕ 7 ðåýš. one two three four five six seven eight nine ten o]'; - - @override - String get boardContribStep9Title => '[Šîĝñ ţĥé ÇĻÅ åñð ƒöļļöŵ ûþ one two]'; + String get boardContribStep8Title => '[Šîĝñ ţĥé ÇĻÅ åñð ƒöļļöŵ ûþ one two]'; @override - String get boardContribStep9 => + String get boardContribStep8 => '[΃ ýöû ĥåṽéñ\'ţ šîĝñéð ţĥé Šéŕṽéŕþöð çöñţŕîƀûţöŕ ļîçéñšé åĝŕééɱéñţ (ÇĻÅ) ýéţ, šîĝñ îţ öñ ĜîţĤûƀ: ţĥé ÇĻÅ Åššîšţåñţ ƀöţ åšķš ƒöŕ îţ öñ ýöûŕ þûļļ ŕéǫûéšţ, åñð ýöû ŕéþļý ŵîţĥ ţĥé ļîñé ƀéļöŵ. Ýöû šîĝñ îţ öñçé. Ţĥéñ çĥéçķ ƀåçķ öñçé ýöûŕ þûļļ ŕéǫûéšţ ĥåš ƀééñ ŕéṽîéŵéð, åñð ƒîẋ åñý îššûéš ţĥé ŕéṽîéŵ þöîñţš öûţ. one two three four five six seven eight nine ten one two three four five six seven eight]'; @override diff --git a/packages/wonky_app/test/board/pages/task_page_test.dart b/packages/wonky_app/test/board/pages/task_page_test.dart index a7fe8b9d..468ea20c 100644 --- a/packages/wonky_app/test/board/pages/task_page_test.dart +++ b/packages/wonky_app/test/board/pages/task_page_test.dart @@ -54,17 +54,24 @@ void main() { findsOneWidget, ); expect(byKey('board.task.claimCode'), findsNothing); - // Before claiming, How to build it is the outline: the setup link, a - // one-line prompt step, and the PR step without its instructions. + // Before claiming, How to build it is the outline: the setup link, + // claiming for the prompt and pasting it into the agent, without the PR + // step. expect(byKey('board.task.setup'), findsOneWidget); + expect( + find.textContaining( + '1. Read the \uFFFC and set up your development environment', + ), + findsOneWidget, + ); + expect(find.text('2. Claim the task to get a prompt'), findsOneWidget); expect( find.text( - '2. Give your coding agent the prompt (claim the task to get the ' - 'prompt).', + '3. Paste the prompt into your AI agent using a frontier model', ), findsOneWidget, ); - expect(find.text('3. Open a pull request'), findsOneWidget); + expect(find.text('3. Open a pull request'), findsNothing); expect(byKey('board.task.prLines'), findsNothing); expect(find.textContaining('Wonky-Task: T-1'), findsNothing); expect(byKey('board.task.prompt'), findsNothing); @@ -194,10 +201,10 @@ void main() { size: const Size(2400, 1000), ); - expect(find.text('Set up your development environment'), findsOneWidget); + expect(find.text('contribution guide'), findsOneWidget); for (final line in const [ 'dart install serverpod_cli 4.1.0-rc.1', - 'serverpod start', + 'cp config/passwords.example.yaml config/passwords.yaml', ]) { expect( find.text(line), @@ -246,10 +253,15 @@ void main() { } expect(find.text('Fork and clone the repository'), findsNothing); expect(byKey('board.contribute.fork'), findsOneWidget); - expect(find.text('9'), findsOneWidget); + expect(find.text('8'), findsOneWidget); + expect(find.text('9'), findsNothing); + // Starting the server is the agent's job: there is no step for it. + expect(find.text('Start the server'), findsNothing); + expect(find.text('serverpod start'), findsNothing); expect(tester.getTopLeft(fork).dy, lessThan(tester.getTopLeft(clone).dy)); + expect(byKey('board.contribute.copy.prLines'), findsNothing); expect( - tester.getTopLeft(byKey('board.contribute.copy.prLines')).dy, + tester.getTopLeft(byKey('board.contribute.pulls')).dy, lessThan(tester.getTopLeft(cla).dy), ); expect(find.text(boardClaSignLine), findsOneWidget); diff --git a/specs/16-bugs-and-improvements.md b/specs/16-bugs-and-improvements.md index 7e941f09..4f586708 100644 --- a/specs/16-bugs-and-improvements.md +++ b/specs/16-bugs-and-improvements.md @@ -354,7 +354,7 @@ The board routes are added to every app by `buildShellRouter`, next to `settings scrollbar stays at the window edge. - **Top bar actions (`BoardTopActions`):** *Report a bug* (Lucide `bug`), *Suggest an improvement* (`leaf`, the improvement icon everywhere; both `shell.board.report` with their kind) and *How to contribute* - (`git-pull-request`; not on the contribute page itself), all `ShadButton.outline` size `sm` + (`wrench`, like the home menu's *Contribute & build*; not on the contribute page itself), all `ShadButton.outline` size `sm` with their icons, after the breadcrumb (keys `board.reportBug`, `board.suggest`, `board.howToContribute`). The breadcrumb has priority: the buttons keep their labels only while the whole trail fits beside them, else they are outline icon buttons with tooltips; below a @@ -516,10 +516,11 @@ task. claims expired without a pull request or an unclaim.*); - for the claimant: the **claim code** (`7Q4F-K2M9`) with *Copy*, and the time left. - **Linked issues**: one row per issue with its score and its screenshots. -- **How to build it** (always shown, not collapsible; the claimant and admins see every step, others see an outline while the task is up for grabs — the setup link, "Give your coding agent the prompt (claim the task to get the prompt)." and "Open a pull request" without instructions — and nothing once someone else claimed it): - 1. A single link, *Set up your development environment* (`board.task.setup`), that opens - *How to contribute* (`/improvements/contribute`, §10.3) in the same tab, under the board's - breadcrumb (Back returns to the task). The setup commands are only there. +- **How to build it** (always shown, not collapsible; the claimant and admins see every step, others see an outline while the task is up for grabs — "1. Read the contribution guide and set up your development environment", "2. Claim the task to get a prompt" (`board.task.promptLocked`) and "3. Paste the prompt into your AI agent using a frontier model" — and nothing once someone else claimed it): + 1. *Read the contribution guide and set up your development environment*, where *contribution + guide* (`board.task.setup`) is a link that opens *How to contribute* + (`/improvements/contribute`, §10.3) in the same tab, under the board's breadcrumb (Back + returns to the task). The setup commands are only there. 2. **The prompt** — for the claimant and admins only: the prompt in a monospaced card with *Copy prompt*. Everyone else sees *Claim this task to get the prompt.* (`board.task.promptLocked`) with *Claim this task* while the task is up for grabs (*Sign in @@ -1434,33 +1435,36 @@ is opened for a change nobody has seen working. The frame is added when the task - **`CONTRIBUTING.md`** (new, repository root, linked from the task page and `/improvements/contribute`) covers: - 1. Prerequisites: the [Serverpod installation guide](https://docs.serverpod.dev/installation) - (Flutter, Dart and what Serverpod needs), Flutter at least the CI version, and an AI coding - agent (Claude Code recommended, any agent that reads `AGENTS.md` works). - 2. Install or update the Serverpod CLI to the version Wonky Work uses: - `dart install serverpod_cli ` (the version of the CI workflow). + 1. Get the tools: Flutter, Serverpod and a frontier coding agent (Codex, Claude Code, + Antigravity, Cursor; any agent that reads `AGENTS.md` and uses MCP servers), with the + [Serverpod installation guide](https://docs.serverpod.dev/installation) and Flutter at least + the CI version. + 2. Get the right version of Serverpod: `dart install serverpod_cli ` (the version of + the CI workflow). 3. Fork the repository on GitHub (the in-app step links to `https://github.com//fork`). 4. Clone the fork and run `flutter pub get`. 5. In `wonky_server`, create `config/passwords.yaml` from `passwords.example.yaml` (development defaults only; AI keys are optional). - 6. Run `serverpod start` in `wonky_server` (it also starts the development database) and start - an app from its UI. Point the agent at the - `serverpod` MCP server (`.mcp.json` is already in the repo). - 7. Pick a task, paste its prompt into the agent, and review the result. - 8. PR rules (§13.1): one task per PR, the `Wonky-Task:` and `Wonky-Claim:` lines, the - checks *Wonky task* and *Wonky task review*, and auto-close after 7 days without a valid - task. - 9. Sign the CLA and follow up (B13): the Serverpod CLA is signed once, on GitHub, on the first + 6. Pick a task: claim it, start the agent with the repository root as its working directory, + give it the prompt and review the result. There is no step to start the server: since + Serverpod 4.1.0-rc.1 the agent starts it (and the development database and the apps) + through the `serverpod` MCP server (`.mcp.json` and the other agents' configs are in the + repo); `serverpod start` in `wonky_server` attaches to it. + 7. Open a pull request (the agent helps): PR rules (§13.1), one task per PR, the + `Wonky-Task:` and `Wonky-Claim:` lines, the checks *Wonky task* and *Wonky task review*, and + auto-close after 7 days without a valid task. + 8. Sign the CLA and follow up (B13): the Serverpod CLA is signed once, on GitHub, on the first pull request, by replying to the CLA Assistant bot; then check back once the pull request is reviewed and fix what the review points out. - 10. License (BSD-3-Clause) and security issues: email `security@serverpod.dev`, never an issue - or PR (`SECURITY.md`). -- **In-app page** `/improvements/contribute`: a short version of steps 1–9 with copy buttons and - a link to the full file on GitHub. Step 1 (and the task page's *Set up Wonky Work locally*) - starts with *Install Flutter, Dart and the Serverpod CLI: Serverpod installation guide*, a link - through the external-link confirmation; the commands are `boardSetupCommands` (no Docker step); - step 9 has the CLA reply line (`boardClaSignLine`) to copy; under the steps, the license and - security lines. The text is part of the app's strings, not fetched, because the board must work + 9. License (BSD-3-Clause) and security issues: email `security@serverpod.dev`, never an issue + or PR (`SECURITY.md`). +- **In-app page** `/improvements/contribute`: a short version of steps 1–8 with copy buttons and + a link to the full file on GitHub. Links are small outline buttons under a step's text, through + the external-link confirmation where they leave the app: step 1 *Serverpod installation guide*, + step 3 *Fork on GitHub*, step 6 *Up for grabs* (the board's tab), step 7 *View pull requests* + (`https://github.com//pulls`; the step has no PR lines to copy, the agent writes them from + the prompt). The commands are `boardSetupCommands` (no run or Docker step); step 8 has the CLA + reply line (`boardClaSignLine`) to copy; under the steps, the license and security lines. The text is part of the app's strings, not fetched, because the board must work offline from GitHub. - **`.github/ISSUE_TEMPLATE/config.yml`** adds a contact link *Report bugs and suggest improvements in Wonky Work* (`https://wonky.work/improvements`) and sets