From aa8ab278874e077595fa2f395892dc740fff0f1c Mon Sep 17 00:00:00 2001 From: Tommaso Casaburi Date: Mon, 27 Apr 2026 13:33:50 +0700 Subject: [PATCH] chore: sync AI tooling and AGENTS.md with 5chan Port release-description skill across .claude / .cursor / .codex. Align playbook content, skills, agents, and hooks with seedit terminology (community, not directory or board). Add AGENTS.md rules picked up from 5chan: vercel-react-best-practices review, ready-for-review PR rule, agent model constraints, playwright session policy, you-might-not-need-an-effect review. --- .claude/agents/browser-check.md | 2 + .claude/agents/code-quality.md | 2 +- .claude/agents/profiler.md | 8 +-- .claude/agents/react-doctor-fixer.md | 2 +- .claude/agents/react-patterns-enforcer.md | 2 +- .claude/hooks.json | 6 ++ .claude/hooks/session-start.sh | 22 ++++++ .claude/skills/deslop/SKILL.md | 8 +-- .claude/skills/implement-plan/SKILL.md | 2 +- .claude/skills/inspect-elements/SKILL.md | 6 +- .claude/skills/make-closed-issue/SKILL.md | 6 +- .claude/skills/playwright-cli/SKILL.md | 28 ++++++++ .claude/skills/profile-browsing/SKILL.md | 11 ++- .claude/skills/refactor-pass/SKILL.md | 2 +- .claude/skills/release-description/SKILL.md | 68 +++++++++++++++++++ .claude/skills/test-apk/SKILL.md | 11 ++- .claude/skills/translate/SKILL.md | 2 +- .../you-might-not-need-an-effect/SKILL.md | 8 +-- .codex/agents/browser-check.toml | 4 +- .codex/skills/deslop/SKILL.md | 8 +-- .codex/skills/inspect-elements/SKILL.md | 6 +- .codex/skills/make-closed-issue/SKILL.md | 6 +- .codex/skills/playwright-cli/SKILL.md | 28 ++++++++ .codex/skills/profile-browsing/SKILL.md | 6 +- .codex/skills/refactor-pass/SKILL.md | 2 +- .codex/skills/release-description/SKILL.md | 6 +- .../you-might-not-need-an-effect/SKILL.md | 8 +-- .cursor/agents/browser-check.md | 2 + .cursor/agents/code-quality.md | 2 +- .cursor/agents/profiler.md | 8 +-- .cursor/agents/react-doctor-fixer.md | 2 +- .cursor/agents/react-patterns-enforcer.md | 2 +- .cursor/skills/deslop/SKILL.md | 8 +-- .cursor/skills/implement-plan/SKILL.md | 2 +- .cursor/skills/inspect-elements/SKILL.md | 6 +- .cursor/skills/make-closed-issue/SKILL.md | 6 +- .cursor/skills/playwright-cli/SKILL.md | 28 ++++++++ .cursor/skills/profile-browsing/SKILL.md | 13 ++-- .cursor/skills/refactor-pass/SKILL.md | 2 +- .cursor/skills/release-description/SKILL.md | 68 +++++++++++++++++++ .cursor/skills/test-apk/SKILL.md | 11 ++- .cursor/skills/translate/SKILL.md | 2 +- .../you-might-not-need-an-effect/SKILL.md | 8 +-- AGENTS.md | 7 +- docs/agent-playbooks/hooks-setup.md | 11 +-- docs/agent-playbooks/known-surprises.md | 10 +-- docs/agent-playbooks/skills-and-tools.md | 11 ++- 47 files changed, 378 insertions(+), 101 deletions(-) create mode 100755 .claude/hooks/session-start.sh create mode 100644 .claude/skills/release-description/SKILL.md create mode 100644 .cursor/skills/release-description/SKILL.md diff --git a/.claude/agents/browser-check.md b/.claude/agents/browser-check.md index 0a28aebb..92afc943 100644 --- a/.claude/agents/browser-check.md +++ b/.claude/agents/browser-check.md @@ -82,3 +82,5 @@ playwright-cli -s=verify-webkit snapshot - If playwright-cli is not installed, report it immediately and stop - If the dev server is unreachable, report the error and stop - Don't modify any code — you are read-only, verification only +- Default to a fresh isolated `playwright-cli` browser session. If the requested verification depends on auth, cookies, extensions, open tabs, or other existing browser state and the parent agent did not specify session mode, stop and ask whether to use a fresh browser or the contributor's current browser session. +- Never attach to a live personal browser session without explicit permission. If current-session reuse is requested, use the supported attach path only when available; otherwise report the limitation instead of silently switching modes. diff --git a/.claude/agents/code-quality.md b/.claude/agents/code-quality.md index 441951df..a7520f82 100644 --- a/.claude/agents/code-quality.md +++ b/.claude/agents/code-quality.md @@ -41,7 +41,7 @@ For each failure: 1. Read the affected file to understand context 2. Check git history for the affected lines (`git log --oneline -5 -- `) to avoid reverting intentional code 3. Apply the minimal fix that resolves the error -4. Follow project patterns from AGENTS.md (Zustand for shared state, plebbit-react-hooks for data, derive state during render) +4. Follow project patterns from AGENTS.md (Zustand for shared state, bitsocial-react-hooks for data, derive state during render) ### Step 4: Re-verify diff --git a/.claude/agents/profiler.md b/.claude/agents/profiler.md index 238b5d0c..81120cb4 100644 --- a/.claude/agents/profiler.md +++ b/.claude/agents/profiler.md @@ -4,7 +4,7 @@ model: haiku description: Performance profiler that browses seedit routes via playwright-cli, collecting Web Vitals and React rerender data via react-scan. Returns a structured issues list for a batch of routes. Use proactively when profiling browsing performance, finding bottlenecks, or diagnosing excessive React rerenders. --- -You are a performance profiling agent for the seedit React app at http://localhost:3000. You use playwright-cli to automate browsing and collect both browser-level (Web Vitals) and React-level (commit counts, per-component render data via react-scan) performance metrics. +You are a performance profiling agent for the seedit React app at http://seedit.localhost:1355. You use playwright-cli to automate browsing and collect both browser-level (Web Vitals) and React-level (commit counts, per-component render data via react-scan) performance metrics. **MUST: Never start a dev server.** The orchestrator guarantees one is already running. If the app is unreachable, report the error and stop — do not run `yarn start` or any other server command. @@ -49,7 +49,7 @@ playwright-cli -s=SESSION run-code "async page => await page.addInitScript(() => `window.__PROFILING__=true` tells react-scan to disable its toolbar and sounds during automated profiling. ```bash -playwright-cli -s=SESSION goto http://localhost:3000 +playwright-cli -s=SESSION goto http://seedit.localhost:1355 playwright-cli -s=SESSION tracing-start ``` @@ -62,7 +62,7 @@ For each route, navigate, interact, and **collect data before moving to the next ```bash # Navigate playwright-cli -s=SESSION eval "performance.mark('pre-ROUTE')" -playwright-cli -s=SESSION goto http://localhost:3000/ROUTE +playwright-cli -s=SESSION goto http://seedit.localhost:1355/ROUTE playwright-cli -s=SESSION snapshot playwright-cli -s=SESSION eval "performance.mark('post-ROUTE');performance.measure('ROUTE','pre-ROUTE','post-ROUTE')" @@ -164,6 +164,6 @@ Routes profiled: /route1, /route2, ... - If `__getReactScanReport` returns null, note "react-scan report unavailable" and rely on commit counts - If a route has no content or fails to load, note it in Info and move on - **Always stop tracing and close the browser when done, even on errors** — wrap your workflow in a try/finally mindset: if any step fails, still run `tracing-stop` and `close` -- Board codes (`biz`, `pol`, `g`, etc.) map to subplebbit addresses via the app's directory +- Board codes (`biz`, `pol`, `g`, etc.) map to community addresses via the app's directory - High commit counts without long tasks = frequent cheap rerenders — still worth fixing for efficiency - React-scan report pinpoints exact components — prioritize these in recommendations diff --git a/.claude/agents/react-doctor-fixer.md b/.claude/agents/react-doctor-fixer.md index cda11e40..6997a092 100644 --- a/.claude/agents/react-doctor-fixer.md +++ b/.claude/agents/react-doctor-fixer.md @@ -30,7 +30,7 @@ Follow the plan provided by the parent agent. Apply changes using project patter | Concern | Avoid | Use Instead | |---------|-------|-------------| | Shared state | `useState` + prop drilling | Zustand store (`src/stores/`) | -| Data fetching | `useEffect` + fetch | plebbit-react-hooks | +| Data fetching | `useEffect` + fetch | bitsocial-react-hooks | | Derived state | `useEffect` to sync | Calculate during render | | Side effects | Effects without cleanup | AbortController or event handlers | | Complex flows | Boolean flags | State machine in Zustand | diff --git a/.claude/agents/react-patterns-enforcer.md b/.claude/agents/react-patterns-enforcer.md index 19f17560..dd8f0683 100644 --- a/.claude/agents/react-patterns-enforcer.md +++ b/.claude/agents/react-patterns-enforcer.md @@ -25,7 +25,7 @@ Read each changed file and check for these project-critical anti-patterns: | Violation | Fix | |-----------|-----| | `useState` for shared/global state | Move to Zustand store in `src/stores/` | -| `useEffect` for data fetching | Replace with plebbit-react-hooks | +| `useEffect` for data fetching | Replace with bitsocial-react-hooks | | `useEffect` syncing derived state | Calculate during render instead | | Boolean flag soup (`isLoading`, `isError`) | Use state machine in Zustand | | Copy-pasted logic across components | Extract to custom hook in `src/hooks/` | diff --git a/.claude/hooks.json b/.claude/hooks.json index 1b96c07d..0f80be43 100644 --- a/.claude/hooks.json +++ b/.claude/hooks.json @@ -1,6 +1,12 @@ { "version": 1, "hooks": { + "sessionStart": [ + { + "command": ".claude/hooks/session-start.sh", + "timeout": 120 + } + ], "afterFileEdit": [ { "command": ".claude/hooks/format.sh", diff --git a/.claude/hooks/session-start.sh b/.claude/hooks/session-start.sh new file mode 100755 index 00000000..51afac2e --- /dev/null +++ b/.claude/hooks/session-start.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +# SessionStart hook: ensure dependencies are installed for the current worktree. +# Runs `corepack yarn install` when node_modules is missing, so new Claude-created +# worktrees are usable immediately without a manual install step. + +set -u + +repo_root="${CLAUDE_PROJECT_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}" +cd "$repo_root" 2>/dev/null || exit 0 + +# No yarn.lock → not a yarn project or fresh clone; nothing to do. +[ -f "yarn.lock" ] || exit 0 + +# node_modules already populated → nothing to do (fast path). +if [ -d "node_modules" ] && [ -n "$(ls -A node_modules 2>/dev/null | head -1)" ]; then + exit 0 +fi + +echo "[claude hook] node_modules missing in $repo_root — running corepack yarn install..." +corepack yarn install +exit 0 diff --git a/.claude/skills/deslop/SKILL.md b/.claude/skills/deslop/SKILL.md index eb4fe8f2..db880243 100644 --- a/.claude/skills/deslop/SKILL.md +++ b/.claude/skills/deslop/SKILL.md @@ -44,7 +44,7 @@ const [count, setCount] = useState(0); // Initialize count state to 0 const user = useComment({ commentCid }); // ✅ Keep — explains non-obvious intent -// plebbit-react-hooks returns undefined while loading, null if not found +// bitsocial-react-hooks returns undefined while loading, null if not found const isLoading = comment === undefined; ``` @@ -53,15 +53,15 @@ const isLoading = comment === undefined; AI adds try/catch blocks and null guards everywhere, even on trusted codepaths. Remove guards that the surrounding code doesn't need. ```typescript -// ❌ Slop — plebbit-react-hooks already handles errors internally +// ❌ Slop — bitsocial-react-hooks already handles errors internally try { - const { feed } = useFeed({ subplebbitAddresses }); + const { feed } = useFeed({ communities }); } catch (error) { console.error('Failed to fetch feed:', error); } // ✅ Clean — just use the hook directly -const { feed } = useFeed({ subplebbitAddresses }); +const { feed } = useFeed({ communities }); ``` ### `as any` casts diff --git a/.claude/skills/implement-plan/SKILL.md b/.claude/skills/implement-plan/SKILL.md index fcf9647b..f34a3f3f 100644 --- a/.claude/skills/implement-plan/SKILL.md +++ b/.claude/skills/implement-plan/SKILL.md @@ -47,7 +47,7 @@ Each subagent prompt must include: - **File paths** and context needed to work independently - **Constraints** or edge cases from the plan -Use `model: "fast"` for straightforward tasks. Omit model for complex ones. +Use the `plan-implementer` agent's configured model unless the harness explicitly requires a supported model override for a straightforward task. Omit overrides for complex or cross-cutting tasks. Wait for all subagents in a batch to complete before starting the next batch. diff --git a/.claude/skills/inspect-elements/SKILL.md b/.claude/skills/inspect-elements/SKILL.md index 27583108..608ba660 100644 --- a/.claude/skills/inspect-elements/SKILL.md +++ b/.claude/skills/inspect-elements/SKILL.md @@ -9,7 +9,7 @@ Use this skill to jump from a concrete DOM node in the running seedit app to the ## Prerequisites -- Dev server running at `http://localhost:3000` +- Dev server running at `http://seedit.localhost:1355` - `playwright-cli` installed - Use the local dev app, not production. The element-source helpers are only exposed in dev mode. @@ -33,8 +33,8 @@ The result includes: ## Session setup ```bash -playwright-cli -s=inspect open http://localhost:3000 -playwright-cli -s=inspect goto http://localhost:3000/all +playwright-cli -s=inspect open http://seedit.localhost:1355 +playwright-cli -s=inspect goto http://seedit.localhost:1355/all playwright-cli -s=inspect eval "window.__ELEMENT_SOURCE__?.ready ?? false" playwright-cli -s=inspect snapshot ``` diff --git a/.claude/skills/make-closed-issue/SKILL.md b/.claude/skills/make-closed-issue/SKILL.md index f027abf3..53000ab0 100644 --- a/.claude/skills/make-closed-issue/SKILL.md +++ b/.claude/skills/make-closed-issue/SKILL.md @@ -16,7 +16,9 @@ Creates a GitHub issue, commits relevant changes on a review branch, pushes the ### 1. Determine label(s) -Ask the user using AskQuestion (multi-select): +The agent should choose the issue label(s) itself from the conversation context and diff. Do **not** ask the user to pick labels unless the work is genuinely ambiguous after reviewing both. + +Default mapping: | Option | When | |--------|------| @@ -25,6 +27,8 @@ Ask the user using AskQuestion (multi-select): | `bug` + `enhancement` | New feature that also fixes a bug | | `documentation` | README, AGENTS.md, docs-only changes | +When the classification is ambiguous, make the best reasonable choice and note the reasoning in the final summary. Only ask the user if the ambiguity would materially affect tracking or triage. + ### 2. Resolve the current GitHub assignee Before creating or editing any issue assignee, determine the current contributor's GitHub username from the authenticated `gh` session. diff --git a/.claude/skills/playwright-cli/SKILL.md b/.claude/skills/playwright-cli/SKILL.md index 17ebd6e6..1f5877ea 100644 --- a/.claude/skills/playwright-cli/SKILL.md +++ b/.claude/skills/playwright-cli/SKILL.md @@ -39,6 +39,34 @@ playwright-cli screenshot playwright-cli close ``` +## Session mode selection + +Default to a fresh isolated browser session for reproducible verification. + +Before browser work where existing state may matter, explicitly confirm the mode if the user has not already said which one they want: + +1. Fresh isolated `playwright-cli` session +2. Current browser session reuse + +Existing state usually matters when the task depends on auth, cookies, extensions, open tabs, or reproducing something already happening in the contributor's browser. + +Do not attach to a live personal browser session without explicit approval. + +If current-session reuse is requested, prefer the supported attach path in the local setup: + +```bash +# Fresh isolated browser (default) +playwright-cli -s=verify open https://example.com + +# Reusable Playwright-managed profile +playwright-cli -s=verify open https://example.com --persistent + +# Attach to an existing browser when the local extension bridge is set up +playwright-cli open --extension +``` + +If the task requires the contributor's current browser session and the attach path is not available in the current setup, stop and ask whether to switch to a fresh session or provide an explicit CDP-based Playwright script. + ## Commands ### Core diff --git a/.claude/skills/profile-browsing/SKILL.md b/.claude/skills/profile-browsing/SKILL.md index a33f5c96..cd4f321a 100644 --- a/.claude/skills/profile-browsing/SKILL.md +++ b/.claude/skills/profile-browsing/SKILL.md @@ -9,7 +9,7 @@ Two-layer profiling: browser-level symptoms (Web Vitals, long tasks, scroll jank ## Prerequisites -- Dev server running at http://localhost:3000 (`yarn start`) +- Dev server running at http://seedit.localhost:1355 (`yarn start` via Portless) - `playwright-cli` installed (`npm install -g @playwright/cli@latest`) **IMPORTANT:** The orchestrator (you) is responsible for ensuring exactly ONE dev server is running. Profiler subagents must NEVER start a dev server themselves. @@ -54,16 +54,15 @@ Keep batches balanced. Add thread views (`/:boardIdentifier/thread/:cid`) as nee ## Step 2: Spawn Profiler Subagents -Read the profiler subagent definition at `.claude/agents/profiler.md`. Then spawn one `shell` Task per batch **in parallel** (single message, multiple Task calls): +Read the profiler subagent definition at `.claude/agents/profiler.md`. Then spawn one `profiler` Task per batch **in parallel** (single message, multiple Task calls): ``` For each batch, create a Task: - subagent_type: "shell" + subagent_type: "profiler" prompt: | - You are a performance profiler. Follow the workflow in .claude/agents/profiler.md. Session name: "prof-N" Routes to profile: /route1, /route2, ... - [Include the full profiler workflow from the agent file] + Any non-default app URL or extra profiling constraints ``` Spawn up to 4 subagents simultaneously. Each opens its own browser session, navigates routes, scrolls, collects both Web Vitals and react-scan data per route, and returns a structured issues list. @@ -160,5 +159,5 @@ playwright-cli -s=prof-3 close 2>/dev/null - **Per-route collection**: Data resets on each `goto` — the profiler collects before navigating away. - **addInitScript persistence**: Instrumentation re-injects automatically in each new document. - **Tracing**: Each subagent produces a `trace.zip` viewable in [Trace Viewer](https://trace.playwright.dev). -- **Board codes**: `biz`, `pol`, `g`, `a`, `v`, etc. map to subplebbit addresses via the directory. +- **Board codes**: `biz`, `pol`, `g`, `a`, `v`, etc. map to community addresses via the app's directory. - **Without react-scan**: If `__getReactScanReport` returns null, the profiler falls back to commit counts + render bursts (still useful, just no component names). diff --git a/.claude/skills/refactor-pass/SKILL.md b/.claude/skills/refactor-pass/SKILL.md index 207203af..70d13aaa 100644 --- a/.claude/skills/refactor-pass/SKILL.md +++ b/.claude/skills/refactor-pass/SKILL.md @@ -33,7 +33,7 @@ When refactoring, watch for these anti-patterns from AGENTS.md: | Anti-pattern | Refactor to | |---|---| | `useState` for shared state | Zustand store in `src/stores/` | -| `useEffect` for data fetching | plebbit-react-hooks (`useComment`, `useFeed`, etc.) | +| `useEffect` for data fetching | bitsocial-react-hooks (`useComment`, `useFeed`, etc.) | | `useEffect` to sync derived state | Calculate during render | | Copy-pasted logic across components | Custom hook in `src/hooks/` | | Boolean flag soup (`isLoading`, `isError`, `isSuccess`) | State machine in Zustand | diff --git a/.claude/skills/release-description/SKILL.md b/.claude/skills/release-description/SKILL.md new file mode 100644 index 00000000..4c6693d2 --- /dev/null +++ b/.claude/skills/release-description/SKILL.md @@ -0,0 +1,68 @@ +--- +name: release-description +description: Update the one-liner release description in scripts/release-body.js by analyzing commit titles since the last git tag. Use when the user asks to update the release description, release notes one-liner, or prepare release body for a new version. +--- + +# Release Description + +Update `oneLinerDescription` in `scripts/release-body.js` before each release. + +## Steps + +### 1. Find the latest release tag + +```bash +git tag --sort=-creatordate | head -1 +``` + +### 2. List commit titles since that tag + +```bash +git log --oneline ..HEAD +``` + +If there are no commits since the tag, stop — nothing to update. + +### 3. Analyze the commits + +Categorize by Conventional Commits prefix: + +| Prefix | Category | +|--------|----------| +| `feat:` | New features | +| `fix:` | Bug fixes | +| `perf:` | Performance improvements | +| `refactor:` | Refactors / internal changes | +| `chore:`, `docs:`, `ci:` | Maintenance (mention only if significant) | +| No prefix | Read the title to infer category | + +### 4. Write the one-liner + +Compose a single sentence that summarizes the release at a high level. Rules: + +- **Start with** "This version..." or "This release..." +- **Be concise** — one sentence, no bullet points +- **Highlight the most impactful changes** — lead with the biggest features or fixes +- **Group similar changes** — e.g. "several bug fixes" instead of listing each one +- **Use plain language** — this is user-facing, not developer-facing +- **Don't mention every commit** — summarize the theme + +Examples of good one-liners: +- "This version adds community filtering, a copy user ID menu item, and several bug fixes." +- "This version introduces feed improvements and performance optimizations." +- "This release adds reply threading enhancements and fixes timezone display issues." + +### 5. Update the constant + +Edit `oneLinerDescription` in `scripts/release-body.js` (around line 104–105): + +```js +const oneLinerDescription = 'Your new one-liner here.'; +``` + +### 6. Verify + +Read the updated line back to confirm it looks right. The string should: +- Be a single sentence +- End with a period +- Not contain backticks or markdown diff --git a/.claude/skills/test-apk/SKILL.md b/.claude/skills/test-apk/SKILL.md index c6328e95..3b9fa515 100644 --- a/.claude/skills/test-apk/SKILL.md +++ b/.claude/skills/test-apk/SKILL.md @@ -7,8 +7,8 @@ description: Test and debug Android APK features using a local Android emulator. ## Overview -Delegates APK testing to a **shell subagent** (`model: fast`) to keep the main context clean. -The subagent manages the emulator, builds/installs the APK, executes tests, and returns structured diagnostics. +Delegates APK testing to the dedicated `test-apk` subagent to keep the main context clean. +That subagent manages the emulator, builds and installs only when needed, executes the requested tests, and returns structured diagnostics. ## Workflow @@ -25,14 +25,13 @@ Ask the user (or infer from context) what to test. Common scenarios: | Manual APK interaction | Build, install, launch, capture logcat | | Contract tests (fixtures) | `yarn contract:postimages` | -### Step 2: Delegate to Shell Subagent +### Step 2: Delegate to the `test-apk` Subagent -Spawn a **shell** subagent with `model: fast`. Use the prompt template below, filling in `{TEST_DESCRIPTION}` with the user's requirements. +Spawn the `test-apk` subagent with the prompt template below, filling in `{TEST_DESCRIPTION}` with the user's requirements and any exact commands or classes you want run. ``` Use the Task tool: - subagent_type: "shell" - model: "fast" + subagent_type: "test-apk" prompt: ``` diff --git a/.claude/skills/translate/SKILL.md b/.claude/skills/translate/SKILL.md index 59baf00e..77b226e3 100644 --- a/.claude/skills/translate/SKILL.md +++ b/.claude/skills/translate/SKILL.md @@ -28,7 +28,7 @@ For each key, check if the English value already exists in `public/translations/ ### Step 3 — Spawn translator subagents -For **each key**, spawn a `translator` subagent (using the Task tool with `subagent_type: "generalPurpose"` and `model: "fast"`). The prompt for each subagent must include: +For **each key**, spawn a `translator` subagent using the Task tool with `subagent_type: "translator"`. The prompt for each subagent must include: - The key name - The English value - An instruction to follow the translator subagent's system prompt diff --git a/.claude/skills/you-might-not-need-an-effect/SKILL.md b/.claude/skills/you-might-not-need-an-effect/SKILL.md index e3d6f830..56b626af 100644 --- a/.claude/skills/you-might-not-need-an-effect/SKILL.md +++ b/.claude/skills/you-might-not-need-an-effect/SKILL.md @@ -72,9 +72,9 @@ useEffect(() => { ``` -### 4. Fetching data (use plebbit-react-hooks, not useEffect) +### 4. Fetching data (use bitsocial-react-hooks, not useEffect) -This project uses `plebbit-react-hooks` for all data fetching. Never use `useEffect` + `fetch`. +This project uses `bitsocial-react-hooks` for all data fetching. Never use `useEffect` + `fetch`. ```typescript // ❌ Anti-pattern @@ -134,10 +134,10 @@ if (typeof window !== 'undefined') { | useEffect pattern | Replace with | |-------------------|-------------| -| Fetch data | `useComment`, `useFeed`, `useSubplebbit`, etc. from plebbit-react-hooks | +| Fetch data | `useComment`, `useFeed`, `useCommunity`, etc. from bitsocial-react-hooks | | Sync shared state | Zustand store in `src/stores/` | | Derive values from state | Calculate during render | -| Boolean loading/error flags | `state` field from plebbit-react-hooks, or state machine in Zustand | +| Boolean loading/error flags | `state` field from bitsocial-react-hooks, or state machine in Zustand | ## When useEffect IS Appropriate diff --git a/.codex/agents/browser-check.toml b/.codex/agents/browser-check.toml index 890939b1..bfcec9c2 100644 --- a/.codex/agents/browser-check.toml +++ b/.codex/agents/browser-check.toml @@ -4,7 +4,9 @@ sandbox_mode = "read-only" developer_instructions = """ Verify only the route, user flow, and acceptance criteria the parent agent gives you. Use playwright-cli against the already-running local app at http://seedit.localhost:1355 unless the parent agent gives a different URL. Never start, restart, or stop the dev server. -Run the requested verification flow in all three main browser engines: chrome/Blink, firefox/Gecko, and webkit/Safari. Use separate named playwright-cli sessions per engine so results stay isolated. +Default to a fresh isolated playwright-cli browser session. If verification depends on auth, cookies, extensions, open tabs, or other existing browser state and the parent agent did not specify session mode, stop and ask whether to use a fresh browser or the contributor's current browser session. +Never attach to a live personal browser session without explicit permission. If current-session reuse is requested, use the supported attach path only when available; otherwise report the limitation instead of silently switching modes. +Run the requested verification flow in all three main browser engines: chrome/Blink, firefox/Gecko, and webkit/Safari. Use separate named playwright-cli sessions per engine unless the parent agent explicitly requires a different attach mode. Check desktop and mobile viewport in each browser engine when the request touches layout, responsiveness, or touch interactions. Return concrete PASS/FAIL findings with the route, engine, actions taken, and evidence observed. Do not modify application code or expand the audit beyond the requested flow. """ diff --git a/.codex/skills/deslop/SKILL.md b/.codex/skills/deslop/SKILL.md index eb4fe8f2..db880243 100644 --- a/.codex/skills/deslop/SKILL.md +++ b/.codex/skills/deslop/SKILL.md @@ -44,7 +44,7 @@ const [count, setCount] = useState(0); // Initialize count state to 0 const user = useComment({ commentCid }); // ✅ Keep — explains non-obvious intent -// plebbit-react-hooks returns undefined while loading, null if not found +// bitsocial-react-hooks returns undefined while loading, null if not found const isLoading = comment === undefined; ``` @@ -53,15 +53,15 @@ const isLoading = comment === undefined; AI adds try/catch blocks and null guards everywhere, even on trusted codepaths. Remove guards that the surrounding code doesn't need. ```typescript -// ❌ Slop — plebbit-react-hooks already handles errors internally +// ❌ Slop — bitsocial-react-hooks already handles errors internally try { - const { feed } = useFeed({ subplebbitAddresses }); + const { feed } = useFeed({ communities }); } catch (error) { console.error('Failed to fetch feed:', error); } // ✅ Clean — just use the hook directly -const { feed } = useFeed({ subplebbitAddresses }); +const { feed } = useFeed({ communities }); ``` ### `as any` casts diff --git a/.codex/skills/inspect-elements/SKILL.md b/.codex/skills/inspect-elements/SKILL.md index 27583108..608ba660 100644 --- a/.codex/skills/inspect-elements/SKILL.md +++ b/.codex/skills/inspect-elements/SKILL.md @@ -9,7 +9,7 @@ Use this skill to jump from a concrete DOM node in the running seedit app to the ## Prerequisites -- Dev server running at `http://localhost:3000` +- Dev server running at `http://seedit.localhost:1355` - `playwright-cli` installed - Use the local dev app, not production. The element-source helpers are only exposed in dev mode. @@ -33,8 +33,8 @@ The result includes: ## Session setup ```bash -playwright-cli -s=inspect open http://localhost:3000 -playwright-cli -s=inspect goto http://localhost:3000/all +playwright-cli -s=inspect open http://seedit.localhost:1355 +playwright-cli -s=inspect goto http://seedit.localhost:1355/all playwright-cli -s=inspect eval "window.__ELEMENT_SOURCE__?.ready ?? false" playwright-cli -s=inspect snapshot ``` diff --git a/.codex/skills/make-closed-issue/SKILL.md b/.codex/skills/make-closed-issue/SKILL.md index f027abf3..53000ab0 100644 --- a/.codex/skills/make-closed-issue/SKILL.md +++ b/.codex/skills/make-closed-issue/SKILL.md @@ -16,7 +16,9 @@ Creates a GitHub issue, commits relevant changes on a review branch, pushes the ### 1. Determine label(s) -Ask the user using AskQuestion (multi-select): +The agent should choose the issue label(s) itself from the conversation context and diff. Do **not** ask the user to pick labels unless the work is genuinely ambiguous after reviewing both. + +Default mapping: | Option | When | |--------|------| @@ -25,6 +27,8 @@ Ask the user using AskQuestion (multi-select): | `bug` + `enhancement` | New feature that also fixes a bug | | `documentation` | README, AGENTS.md, docs-only changes | +When the classification is ambiguous, make the best reasonable choice and note the reasoning in the final summary. Only ask the user if the ambiguity would materially affect tracking or triage. + ### 2. Resolve the current GitHub assignee Before creating or editing any issue assignee, determine the current contributor's GitHub username from the authenticated `gh` session. diff --git a/.codex/skills/playwright-cli/SKILL.md b/.codex/skills/playwright-cli/SKILL.md index 17ebd6e6..1f5877ea 100644 --- a/.codex/skills/playwright-cli/SKILL.md +++ b/.codex/skills/playwright-cli/SKILL.md @@ -39,6 +39,34 @@ playwright-cli screenshot playwright-cli close ``` +## Session mode selection + +Default to a fresh isolated browser session for reproducible verification. + +Before browser work where existing state may matter, explicitly confirm the mode if the user has not already said which one they want: + +1. Fresh isolated `playwright-cli` session +2. Current browser session reuse + +Existing state usually matters when the task depends on auth, cookies, extensions, open tabs, or reproducing something already happening in the contributor's browser. + +Do not attach to a live personal browser session without explicit approval. + +If current-session reuse is requested, prefer the supported attach path in the local setup: + +```bash +# Fresh isolated browser (default) +playwright-cli -s=verify open https://example.com + +# Reusable Playwright-managed profile +playwright-cli -s=verify open https://example.com --persistent + +# Attach to an existing browser when the local extension bridge is set up +playwright-cli open --extension +``` + +If the task requires the contributor's current browser session and the attach path is not available in the current setup, stop and ask whether to switch to a fresh session or provide an explicit CDP-based Playwright script. + ## Commands ### Core diff --git a/.codex/skills/profile-browsing/SKILL.md b/.codex/skills/profile-browsing/SKILL.md index c69f4c93..62e3af64 100644 --- a/.codex/skills/profile-browsing/SKILL.md +++ b/.codex/skills/profile-browsing/SKILL.md @@ -9,7 +9,7 @@ Two-layer profiling: browser-level symptoms (Web Vitals, long tasks, scroll jank ## Prerequisites -- Dev server running at http://localhost:3000 (`yarn start`) +- Dev server running at http://seedit.localhost:1355 (`yarn start`) - `playwright-cli` installed (`npm install -g @playwright/cli@latest`) **IMPORTANT:** The orchestrator (you) is responsible for ensuring exactly ONE dev server is running. Profiler subagents must NEVER start a dev server themselves. @@ -31,7 +31,7 @@ Before spawning any profiler subagents, verify exactly one dev server is availab ```bash # Check if the dev server is reachable -curl -sf http://localhost:3000 -o /dev/null && echo "OK" || echo "NOT RUNNING" +curl -sf http://seedit.localhost:1355 -o /dev/null && echo "OK" || echo "NOT RUNNING" ``` - If **OK**: proceed to Step 1. @@ -158,5 +158,5 @@ playwright-cli -s=prof-3 close 2>/dev/null - **Per-route collection**: Data resets on each `goto` — the profiler collects before navigating away. - **addInitScript persistence**: Instrumentation re-injects automatically in each new document. - **Tracing**: Each subagent produces a `trace.zip` viewable in [Trace Viewer](https://trace.playwright.dev). -- **Board codes**: `biz`, `pol`, `g`, `a`, `v`, etc. map to subplebbit addresses via the directory. +- **Board codes**: `biz`, `pol`, `g`, `a`, `v`, etc. map to community addresses via the app's directory. - **Without react-scan**: If `__getReactScanReport` returns null, the profiler falls back to commit counts + render bursts (still useful, just no component names). diff --git a/.codex/skills/refactor-pass/SKILL.md b/.codex/skills/refactor-pass/SKILL.md index 207203af..70d13aaa 100644 --- a/.codex/skills/refactor-pass/SKILL.md +++ b/.codex/skills/refactor-pass/SKILL.md @@ -33,7 +33,7 @@ When refactoring, watch for these anti-patterns from AGENTS.md: | Anti-pattern | Refactor to | |---|---| | `useState` for shared state | Zustand store in `src/stores/` | -| `useEffect` for data fetching | plebbit-react-hooks (`useComment`, `useFeed`, etc.) | +| `useEffect` for data fetching | bitsocial-react-hooks (`useComment`, `useFeed`, etc.) | | `useEffect` to sync derived state | Calculate during render | | Copy-pasted logic across components | Custom hook in `src/hooks/` | | Boolean flag soup (`isLoading`, `isError`, `isSuccess`) | State machine in Zustand | diff --git a/.codex/skills/release-description/SKILL.md b/.codex/skills/release-description/SKILL.md index 406c57ff..4c6693d2 100644 --- a/.codex/skills/release-description/SKILL.md +++ b/.codex/skills/release-description/SKILL.md @@ -48,9 +48,9 @@ Compose a single sentence that summarizes the release at a high level. Rules: - **Don't mention every commit** — summarize the theme Examples of good one-liners: -- "This version adds backlinks for quoted posts, a copy user ID menu item, and several bug fixes." -- "This version introduces mod queue improvements and performance optimizations." -- "This release adds pseudonymity mode support per-reply and fixes timezone display issues." +- "This version adds community filtering, a copy user ID menu item, and several bug fixes." +- "This version introduces feed improvements and performance optimizations." +- "This release adds reply threading enhancements and fixes timezone display issues." ### 5. Update the constant diff --git a/.codex/skills/you-might-not-need-an-effect/SKILL.md b/.codex/skills/you-might-not-need-an-effect/SKILL.md index e3d6f830..56b626af 100644 --- a/.codex/skills/you-might-not-need-an-effect/SKILL.md +++ b/.codex/skills/you-might-not-need-an-effect/SKILL.md @@ -72,9 +72,9 @@ useEffect(() => { ``` -### 4. Fetching data (use plebbit-react-hooks, not useEffect) +### 4. Fetching data (use bitsocial-react-hooks, not useEffect) -This project uses `plebbit-react-hooks` for all data fetching. Never use `useEffect` + `fetch`. +This project uses `bitsocial-react-hooks` for all data fetching. Never use `useEffect` + `fetch`. ```typescript // ❌ Anti-pattern @@ -134,10 +134,10 @@ if (typeof window !== 'undefined') { | useEffect pattern | Replace with | |-------------------|-------------| -| Fetch data | `useComment`, `useFeed`, `useSubplebbit`, etc. from plebbit-react-hooks | +| Fetch data | `useComment`, `useFeed`, `useCommunity`, etc. from bitsocial-react-hooks | | Sync shared state | Zustand store in `src/stores/` | | Derive values from state | Calculate during render | -| Boolean loading/error flags | `state` field from plebbit-react-hooks, or state machine in Zustand | +| Boolean loading/error flags | `state` field from bitsocial-react-hooks, or state machine in Zustand | ## When useEffect IS Appropriate diff --git a/.cursor/agents/browser-check.md b/.cursor/agents/browser-check.md index d320ab6a..0a3af1d6 100644 --- a/.cursor/agents/browser-check.md +++ b/.cursor/agents/browser-check.md @@ -82,3 +82,5 @@ playwright-cli -s=verify-webkit snapshot - If playwright-cli is not installed, report it immediately and stop - If the dev server is unreachable, report the error and stop - Don't modify any code — you are read-only, verification only +- Default to a fresh isolated `playwright-cli` browser session. If the requested verification depends on auth, cookies, extensions, open tabs, or other existing browser state and the parent agent did not specify session mode, stop and ask whether to use a fresh browser or the contributor's current browser session. +- Never attach to a live personal browser session without explicit permission. If current-session reuse is requested, use the supported attach path only when available; otherwise report the limitation instead of silently switching modes. diff --git a/.cursor/agents/code-quality.md b/.cursor/agents/code-quality.md index f286b8ce..c0ee746a 100644 --- a/.cursor/agents/code-quality.md +++ b/.cursor/agents/code-quality.md @@ -41,7 +41,7 @@ For each failure: 1. Read the affected file to understand context 2. Check git history for the affected lines (`git log --oneline -5 -- `) to avoid reverting intentional code 3. Apply the minimal fix that resolves the error -4. Follow project patterns from AGENTS.md (Zustand for shared state, plebbit-react-hooks for data, derive state during render) +4. Follow project patterns from AGENTS.md (Zustand for shared state, bitsocial-react-hooks for data, derive state during render) ### Step 4: Re-verify diff --git a/.cursor/agents/profiler.md b/.cursor/agents/profiler.md index b77d1c1b..b7501a47 100644 --- a/.cursor/agents/profiler.md +++ b/.cursor/agents/profiler.md @@ -3,7 +3,7 @@ name: profiler description: Performance profiler that browses seedit routes via playwright-cli, collecting Web Vitals and React rerender data via react-scan. Returns a structured issues list for a batch of routes. Use proactively when profiling browsing performance, finding bottlenecks, or diagnosing excessive React rerenders. --- -You are a performance profiling agent for the seedit React app at http://localhost:3000. You use playwright-cli to automate browsing and collect both browser-level (Web Vitals) and React-level (commit counts, per-component render data via react-scan) performance metrics. +You are a performance profiling agent for the seedit React app at http://seedit.localhost:1355. You use playwright-cli to automate browsing and collect both browser-level (Web Vitals) and React-level (commit counts, per-component render data via react-scan) performance metrics. **MUST: Never start a dev server.** The orchestrator guarantees one is already running. If the app is unreachable, report the error and stop — do not run `yarn start` or any other server command. @@ -48,7 +48,7 @@ playwright-cli -s=SESSION run-code "async page => await page.addInitScript(() => `window.__PROFILING__=true` tells react-scan to disable its toolbar and sounds during automated profiling. ```bash -playwright-cli -s=SESSION goto http://localhost:3000 +playwright-cli -s=SESSION goto http://seedit.localhost:1355 playwright-cli -s=SESSION tracing-start ``` @@ -61,7 +61,7 @@ For each route, navigate, interact, and **collect data before moving to the next ```bash # Navigate playwright-cli -s=SESSION eval "performance.mark('pre-ROUTE')" -playwright-cli -s=SESSION goto http://localhost:3000/ROUTE +playwright-cli -s=SESSION goto http://seedit.localhost:1355/ROUTE playwright-cli -s=SESSION snapshot playwright-cli -s=SESSION eval "performance.mark('post-ROUTE');performance.measure('ROUTE','pre-ROUTE','post-ROUTE')" @@ -163,6 +163,6 @@ Routes profiled: /route1, /route2, ... - If `__getReactScanReport` returns null, note "react-scan report unavailable" and rely on commit counts - If a route has no content or fails to load, note it in Info and move on - **Always stop tracing and close the browser when done, even on errors** — wrap your workflow in a try/finally mindset: if any step fails, still run `tracing-stop` and `close` -- Board codes (`biz`, `pol`, `g`, etc.) map to subplebbit addresses via the app's directory +- Board codes (`biz`, `pol`, `g`, etc.) map to community addresses via the app's directory - High commit counts without long tasks = frequent cheap rerenders — still worth fixing for efficiency - React-scan report pinpoints exact components — prioritize these in recommendations diff --git a/.cursor/agents/react-doctor-fixer.md b/.cursor/agents/react-doctor-fixer.md index f4f17171..0c21e370 100644 --- a/.cursor/agents/react-doctor-fixer.md +++ b/.cursor/agents/react-doctor-fixer.md @@ -30,7 +30,7 @@ Follow the plan provided by the parent agent. Apply changes using project patter | Concern | Avoid | Use Instead | |---------|-------|-------------| | Shared state | `useState` + prop drilling | Zustand store (`src/stores/`) | -| Data fetching | `useEffect` + fetch | plebbit-react-hooks | +| Data fetching | `useEffect` + fetch | bitsocial-react-hooks | | Derived state | `useEffect` to sync | Calculate during render | | Side effects | Effects without cleanup | AbortController or event handlers | | Complex flows | Boolean flags | State machine in Zustand | diff --git a/.cursor/agents/react-patterns-enforcer.md b/.cursor/agents/react-patterns-enforcer.md index 9cc9ec54..4589d038 100644 --- a/.cursor/agents/react-patterns-enforcer.md +++ b/.cursor/agents/react-patterns-enforcer.md @@ -25,7 +25,7 @@ Read each changed file and check for these project-critical anti-patterns: | Violation | Fix | |-----------|-----| | `useState` for shared/global state | Move to Zustand store in `src/stores/` | -| `useEffect` for data fetching | Replace with plebbit-react-hooks | +| `useEffect` for data fetching | Replace with bitsocial-react-hooks | | `useEffect` syncing derived state | Calculate during render instead | | Boolean flag soup (`isLoading`, `isError`) | Use state machine in Zustand | | Copy-pasted logic across components | Extract to custom hook in `src/hooks/` | diff --git a/.cursor/skills/deslop/SKILL.md b/.cursor/skills/deslop/SKILL.md index eb4fe8f2..db880243 100644 --- a/.cursor/skills/deslop/SKILL.md +++ b/.cursor/skills/deslop/SKILL.md @@ -44,7 +44,7 @@ const [count, setCount] = useState(0); // Initialize count state to 0 const user = useComment({ commentCid }); // ✅ Keep — explains non-obvious intent -// plebbit-react-hooks returns undefined while loading, null if not found +// bitsocial-react-hooks returns undefined while loading, null if not found const isLoading = comment === undefined; ``` @@ -53,15 +53,15 @@ const isLoading = comment === undefined; AI adds try/catch blocks and null guards everywhere, even on trusted codepaths. Remove guards that the surrounding code doesn't need. ```typescript -// ❌ Slop — plebbit-react-hooks already handles errors internally +// ❌ Slop — bitsocial-react-hooks already handles errors internally try { - const { feed } = useFeed({ subplebbitAddresses }); + const { feed } = useFeed({ communities }); } catch (error) { console.error('Failed to fetch feed:', error); } // ✅ Clean — just use the hook directly -const { feed } = useFeed({ subplebbitAddresses }); +const { feed } = useFeed({ communities }); ``` ### `as any` casts diff --git a/.cursor/skills/implement-plan/SKILL.md b/.cursor/skills/implement-plan/SKILL.md index fcf9647b..f34a3f3f 100644 --- a/.cursor/skills/implement-plan/SKILL.md +++ b/.cursor/skills/implement-plan/SKILL.md @@ -47,7 +47,7 @@ Each subagent prompt must include: - **File paths** and context needed to work independently - **Constraints** or edge cases from the plan -Use `model: "fast"` for straightforward tasks. Omit model for complex ones. +Use the `plan-implementer` agent's configured model unless the harness explicitly requires a supported model override for a straightforward task. Omit overrides for complex or cross-cutting tasks. Wait for all subagents in a batch to complete before starting the next batch. diff --git a/.cursor/skills/inspect-elements/SKILL.md b/.cursor/skills/inspect-elements/SKILL.md index 27583108..608ba660 100644 --- a/.cursor/skills/inspect-elements/SKILL.md +++ b/.cursor/skills/inspect-elements/SKILL.md @@ -9,7 +9,7 @@ Use this skill to jump from a concrete DOM node in the running seedit app to the ## Prerequisites -- Dev server running at `http://localhost:3000` +- Dev server running at `http://seedit.localhost:1355` - `playwright-cli` installed - Use the local dev app, not production. The element-source helpers are only exposed in dev mode. @@ -33,8 +33,8 @@ The result includes: ## Session setup ```bash -playwright-cli -s=inspect open http://localhost:3000 -playwright-cli -s=inspect goto http://localhost:3000/all +playwright-cli -s=inspect open http://seedit.localhost:1355 +playwright-cli -s=inspect goto http://seedit.localhost:1355/all playwright-cli -s=inspect eval "window.__ELEMENT_SOURCE__?.ready ?? false" playwright-cli -s=inspect snapshot ``` diff --git a/.cursor/skills/make-closed-issue/SKILL.md b/.cursor/skills/make-closed-issue/SKILL.md index f027abf3..53000ab0 100644 --- a/.cursor/skills/make-closed-issue/SKILL.md +++ b/.cursor/skills/make-closed-issue/SKILL.md @@ -16,7 +16,9 @@ Creates a GitHub issue, commits relevant changes on a review branch, pushes the ### 1. Determine label(s) -Ask the user using AskQuestion (multi-select): +The agent should choose the issue label(s) itself from the conversation context and diff. Do **not** ask the user to pick labels unless the work is genuinely ambiguous after reviewing both. + +Default mapping: | Option | When | |--------|------| @@ -25,6 +27,8 @@ Ask the user using AskQuestion (multi-select): | `bug` + `enhancement` | New feature that also fixes a bug | | `documentation` | README, AGENTS.md, docs-only changes | +When the classification is ambiguous, make the best reasonable choice and note the reasoning in the final summary. Only ask the user if the ambiguity would materially affect tracking or triage. + ### 2. Resolve the current GitHub assignee Before creating or editing any issue assignee, determine the current contributor's GitHub username from the authenticated `gh` session. diff --git a/.cursor/skills/playwright-cli/SKILL.md b/.cursor/skills/playwright-cli/SKILL.md index 17ebd6e6..1f5877ea 100644 --- a/.cursor/skills/playwright-cli/SKILL.md +++ b/.cursor/skills/playwright-cli/SKILL.md @@ -39,6 +39,34 @@ playwright-cli screenshot playwright-cli close ``` +## Session mode selection + +Default to a fresh isolated browser session for reproducible verification. + +Before browser work where existing state may matter, explicitly confirm the mode if the user has not already said which one they want: + +1. Fresh isolated `playwright-cli` session +2. Current browser session reuse + +Existing state usually matters when the task depends on auth, cookies, extensions, open tabs, or reproducing something already happening in the contributor's browser. + +Do not attach to a live personal browser session without explicit approval. + +If current-session reuse is requested, prefer the supported attach path in the local setup: + +```bash +# Fresh isolated browser (default) +playwright-cli -s=verify open https://example.com + +# Reusable Playwright-managed profile +playwright-cli -s=verify open https://example.com --persistent + +# Attach to an existing browser when the local extension bridge is set up +playwright-cli open --extension +``` + +If the task requires the contributor's current browser session and the attach path is not available in the current setup, stop and ask whether to switch to a fresh session or provide an explicit CDP-based Playwright script. + ## Commands ### Core diff --git a/.cursor/skills/profile-browsing/SKILL.md b/.cursor/skills/profile-browsing/SKILL.md index 978c5623..1d7a236c 100644 --- a/.cursor/skills/profile-browsing/SKILL.md +++ b/.cursor/skills/profile-browsing/SKILL.md @@ -9,7 +9,7 @@ Two-layer profiling: browser-level symptoms (Web Vitals, long tasks, scroll jank ## Prerequisites -- Dev server running at http://localhost:3000 (`yarn start`) +- Dev server running at http://seedit.localhost:1355 (`yarn start`) - `playwright-cli` installed (`npm install -g @playwright/cli@latest`) **IMPORTANT:** The orchestrator (you) is responsible for ensuring exactly ONE dev server is running. Profiler subagents must NEVER start a dev server themselves. @@ -31,7 +31,7 @@ Before spawning any profiler subagents, verify exactly one dev server is availab ```bash # Check if the dev server is reachable -curl -sf http://localhost:3000 -o /dev/null && echo "OK" || echo "NOT RUNNING" +curl -sf http://seedit.localhost:1355 -o /dev/null && echo "OK" || echo "NOT RUNNING" ``` - If **OK**: proceed to Step 1. @@ -54,16 +54,15 @@ Keep batches balanced. Add thread views (`/:boardIdentifier/thread/:cid`) as nee ## Step 2: Spawn Profiler Subagents -Read the profiler subagent definition at `.cursor/agents/profiler.md`. Then spawn one `shell` Task per batch **in parallel** (single message, multiple Task calls): +Read the profiler subagent definition at `.cursor/agents/profiler.md`. Then spawn one `profiler` Task per batch **in parallel** (single message, multiple Task calls): ``` For each batch, create a Task: - subagent_type: "shell" + subagent_type: "profiler" prompt: | - You are a performance profiler. Follow the workflow in .cursor/agents/profiler.md. Session name: "prof-N" Routes to profile: /route1, /route2, ... - [Include the full profiler workflow from the agent file] + Any non-default app URL or extra profiling constraints ``` Spawn up to 4 subagents simultaneously. Each opens its own browser session, navigates routes, scrolls, collects both Web Vitals and react-scan data per route, and returns a structured issues list. @@ -160,5 +159,5 @@ playwright-cli -s=prof-3 close 2>/dev/null - **Per-route collection**: Data resets on each `goto` — the profiler collects before navigating away. - **addInitScript persistence**: Instrumentation re-injects automatically in each new document. - **Tracing**: Each subagent produces a `trace.zip` viewable in [Trace Viewer](https://trace.playwright.dev). -- **Board codes**: `biz`, `pol`, `g`, `a`, `v`, etc. map to subplebbit addresses via the directory. +- **Board codes**: `biz`, `pol`, `g`, `a`, `v`, etc. map to community addresses via the app's directory. - **Without react-scan**: If `__getReactScanReport` returns null, the profiler falls back to commit counts + render bursts (still useful, just no component names). diff --git a/.cursor/skills/refactor-pass/SKILL.md b/.cursor/skills/refactor-pass/SKILL.md index 207203af..70d13aaa 100644 --- a/.cursor/skills/refactor-pass/SKILL.md +++ b/.cursor/skills/refactor-pass/SKILL.md @@ -33,7 +33,7 @@ When refactoring, watch for these anti-patterns from AGENTS.md: | Anti-pattern | Refactor to | |---|---| | `useState` for shared state | Zustand store in `src/stores/` | -| `useEffect` for data fetching | plebbit-react-hooks (`useComment`, `useFeed`, etc.) | +| `useEffect` for data fetching | bitsocial-react-hooks (`useComment`, `useFeed`, etc.) | | `useEffect` to sync derived state | Calculate during render | | Copy-pasted logic across components | Custom hook in `src/hooks/` | | Boolean flag soup (`isLoading`, `isError`, `isSuccess`) | State machine in Zustand | diff --git a/.cursor/skills/release-description/SKILL.md b/.cursor/skills/release-description/SKILL.md new file mode 100644 index 00000000..4c6693d2 --- /dev/null +++ b/.cursor/skills/release-description/SKILL.md @@ -0,0 +1,68 @@ +--- +name: release-description +description: Update the one-liner release description in scripts/release-body.js by analyzing commit titles since the last git tag. Use when the user asks to update the release description, release notes one-liner, or prepare release body for a new version. +--- + +# Release Description + +Update `oneLinerDescription` in `scripts/release-body.js` before each release. + +## Steps + +### 1. Find the latest release tag + +```bash +git tag --sort=-creatordate | head -1 +``` + +### 2. List commit titles since that tag + +```bash +git log --oneline ..HEAD +``` + +If there are no commits since the tag, stop — nothing to update. + +### 3. Analyze the commits + +Categorize by Conventional Commits prefix: + +| Prefix | Category | +|--------|----------| +| `feat:` | New features | +| `fix:` | Bug fixes | +| `perf:` | Performance improvements | +| `refactor:` | Refactors / internal changes | +| `chore:`, `docs:`, `ci:` | Maintenance (mention only if significant) | +| No prefix | Read the title to infer category | + +### 4. Write the one-liner + +Compose a single sentence that summarizes the release at a high level. Rules: + +- **Start with** "This version..." or "This release..." +- **Be concise** — one sentence, no bullet points +- **Highlight the most impactful changes** — lead with the biggest features or fixes +- **Group similar changes** — e.g. "several bug fixes" instead of listing each one +- **Use plain language** — this is user-facing, not developer-facing +- **Don't mention every commit** — summarize the theme + +Examples of good one-liners: +- "This version adds community filtering, a copy user ID menu item, and several bug fixes." +- "This version introduces feed improvements and performance optimizations." +- "This release adds reply threading enhancements and fixes timezone display issues." + +### 5. Update the constant + +Edit `oneLinerDescription` in `scripts/release-body.js` (around line 104–105): + +```js +const oneLinerDescription = 'Your new one-liner here.'; +``` + +### 6. Verify + +Read the updated line back to confirm it looks right. The string should: +- Be a single sentence +- End with a period +- Not contain backticks or markdown diff --git a/.cursor/skills/test-apk/SKILL.md b/.cursor/skills/test-apk/SKILL.md index c6328e95..3b9fa515 100644 --- a/.cursor/skills/test-apk/SKILL.md +++ b/.cursor/skills/test-apk/SKILL.md @@ -7,8 +7,8 @@ description: Test and debug Android APK features using a local Android emulator. ## Overview -Delegates APK testing to a **shell subagent** (`model: fast`) to keep the main context clean. -The subagent manages the emulator, builds/installs the APK, executes tests, and returns structured diagnostics. +Delegates APK testing to the dedicated `test-apk` subagent to keep the main context clean. +That subagent manages the emulator, builds and installs only when needed, executes the requested tests, and returns structured diagnostics. ## Workflow @@ -25,14 +25,13 @@ Ask the user (or infer from context) what to test. Common scenarios: | Manual APK interaction | Build, install, launch, capture logcat | | Contract tests (fixtures) | `yarn contract:postimages` | -### Step 2: Delegate to Shell Subagent +### Step 2: Delegate to the `test-apk` Subagent -Spawn a **shell** subagent with `model: fast`. Use the prompt template below, filling in `{TEST_DESCRIPTION}` with the user's requirements. +Spawn the `test-apk` subagent with the prompt template below, filling in `{TEST_DESCRIPTION}` with the user's requirements and any exact commands or classes you want run. ``` Use the Task tool: - subagent_type: "shell" - model: "fast" + subagent_type: "test-apk" prompt: ``` diff --git a/.cursor/skills/translate/SKILL.md b/.cursor/skills/translate/SKILL.md index 59baf00e..77b226e3 100644 --- a/.cursor/skills/translate/SKILL.md +++ b/.cursor/skills/translate/SKILL.md @@ -28,7 +28,7 @@ For each key, check if the English value already exists in `public/translations/ ### Step 3 — Spawn translator subagents -For **each key**, spawn a `translator` subagent (using the Task tool with `subagent_type: "generalPurpose"` and `model: "fast"`). The prompt for each subagent must include: +For **each key**, spawn a `translator` subagent using the Task tool with `subagent_type: "translator"`. The prompt for each subagent must include: - The key name - The English value - An instruction to follow the translator subagent's system prompt diff --git a/.cursor/skills/you-might-not-need-an-effect/SKILL.md b/.cursor/skills/you-might-not-need-an-effect/SKILL.md index e3d6f830..56b626af 100644 --- a/.cursor/skills/you-might-not-need-an-effect/SKILL.md +++ b/.cursor/skills/you-might-not-need-an-effect/SKILL.md @@ -72,9 +72,9 @@ useEffect(() => { ``` -### 4. Fetching data (use plebbit-react-hooks, not useEffect) +### 4. Fetching data (use bitsocial-react-hooks, not useEffect) -This project uses `plebbit-react-hooks` for all data fetching. Never use `useEffect` + `fetch`. +This project uses `bitsocial-react-hooks` for all data fetching. Never use `useEffect` + `fetch`. ```typescript // ❌ Anti-pattern @@ -134,10 +134,10 @@ if (typeof window !== 'undefined') { | useEffect pattern | Replace with | |-------------------|-------------| -| Fetch data | `useComment`, `useFeed`, `useSubplebbit`, etc. from plebbit-react-hooks | +| Fetch data | `useComment`, `useFeed`, `useCommunity`, etc. from bitsocial-react-hooks | | Sync shared state | Zustand store in `src/stores/` | | Derive values from state | Calculate during render | -| Boolean loading/error flags | `state` field from plebbit-react-hooks, or state machine in Zustand | +| Boolean loading/error flags | `state` field from bitsocial-react-hooks, or state machine in Zustand | ## When useEffect IS Appropriate diff --git a/AGENTS.md b/AGENTS.md index e8f6fefb..1c515bc8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -26,7 +26,7 @@ seedit is a serverless, adminless, decentralized Reddit-style client built on th | Situation | Required action | |---|---| -| React UI logic changed (`src/components`, `src/views`, `src/hooks`, UI stores) | Follow React architecture rules below; run `yarn build`, `yarn lint`, and `yarn type-check` | +| React UI logic changed (`src/components`, `src/views`, `src/hooks`, UI stores) | Follow React architecture rules below; review the changed diff with `vercel-react-best-practices` and `vercel:react-best-practices` when available; run `yarn build`, `yarn lint`, and `yarn type-check` | | Visible UI or interaction changed | Verify in browser with `playwright-cli` across Chrome/Blink, Firefox/Gecko, and WebKit/Safari; test desktop and mobile viewport | | `package.json` changed | Run `corepack yarn install` to keep `yarn.lock` in sync | | Translation key/value changed | Use `docs/agent-playbooks/translations.md` | @@ -102,6 +102,7 @@ src/ - Treat branch and worktree as different things: the branch is the change set; the worktree is the checkout where that branch is worked on. - For parallel unrelated tasks, give each task its own branch from `master`, its own worktree, and its own PR into `master`. - After a reviewed branch is merged, prefer deleting it to keep branch drift and merge conflicts low. +- Open PRs as ready for review, not draft. Draft PRs prevent CodeRabbit, Cursor Bugbot, and similar review bots from running. ### Bug Investigation Rules @@ -136,6 +137,10 @@ src/ - If `AGENTS.md` references a skill, agent, or hook, prefer a tracked file under `.codex/`, `.cursor/`, or `.claude/` rather than an untracked local-only instruction. - Review `.codex/config.toml`, `.cursor/hooks.json`, and `.claude/hooks.json` before changing agent orchestration or hook behavior, because they are the entry points contributors will actually load. - When a diff adds new `useEffect`, `useLayoutEffect`, `useInsertionEffect`, `useMemo`, `useCallback`, or `memo(...)` usage under `src/`, treat the repo hook reminder as mandatory and reconsider the change with `you-might-not-need-an-effect` and `vercel-react-best-practices` before finishing. +- Before finishing any React UI logic change under `src/components`, `src/views`, `src/hooks`, or UI stores, review the changed diff with `vercel-react-best-practices` and, in Codex/Vercel-plugin sessions, `vercel:react-best-practices`. Fix valid findings before final verification. +- Do not configure `.claude` agents to use `composer-2`; that model is Cursor-only in this repo. Keep `.claude` agent models on Claude-supported options. +- Do not configure `.codex/agents/*.toml` with `gpt-5.3-codex` or `gpt-5.3-codex-spark`; standardize Codex agents on `gpt-5.4` unless the user explicitly requests a different model. +- For browser automation, default to a fresh isolated `playwright-cli` session for reproducible verification. If the task depends on existing auth, cookies, extensions, open tabs, or another live browser state, explicitly confirm whether to use a fresh isolated session or the contributor's current browser session. Do not assume permission to drive the contributor's active personal browser session. - Directory-specific auto-loaded rules live under `src/AGENTS.md` and `scripts/AGENTS.md`; read them before editing files in those trees. - For work expected to span multiple sessions, keep explicit task state in a `feature-list.json` plus `progress.md` pair using `docs/agent-playbooks/long-running-agent-workflow.md`. - If more than one human or toolchain needs the same task state, keep it in a tracked location such as `docs/agent-runs//` instead of burying it in a tool-specific hidden directory. diff --git a/docs/agent-playbooks/hooks-setup.md b/docs/agent-playbooks/hooks-setup.md index 1b4e8760..7713f9fe 100644 --- a/docs/agent-playbooks/hooks-setup.md +++ b/docs/agent-playbooks/hooks-setup.md @@ -8,19 +8,20 @@ If your AI coding assistant supports lifecycle hooks, configure these for this r |---|---|---| | `afterFileEdit` | `scripts/agent-hooks/format.sh` | Auto-format files after AI edits | | `afterFileEdit` | `scripts/agent-hooks/yarn-install.sh` | Run `corepack yarn install` when `package.json` changes | -| `afterFileEdit` | `scripts/agent-hooks/react-pattern-review.sh` | When a diff adds `useEffect`/memo primitives in `src/`, remind the agent to reconsider with the React review skills | +| `afterFileEdit` | `scripts/agent-hooks/react-pattern-review.sh` | When React UI source changes, remind the agent to run the React best-practice review skills; also flag new `useEffect`/memo primitives | | `stop` | `scripts/agent-hooks/sync-git-branches.sh` | Prune stale refs and delete integrated temporary task branches | -| `stop` | `scripts/agent-hooks/react-pattern-review.sh` | Re-scan the current diff for new React effects/memos before the final verify gate | +| `stop` | `scripts/agent-hooks/react-pattern-review.sh` | Re-scan the current diff for React UI source changes and new React effects/memos before the final verify gate | | `stop` | `scripts/agent-hooks/verify.sh` | Hard-gate build, lint, and type-check; keep `yarn audit` informational | ## Why - Consistent formatting - Lockfile stays in sync -- New `useEffect`/memo additions get an explicit second look before the agent finishes +- React UI source changes get an explicit best-practices review reminder before the agent finishes +- New `useEffect`/memo additions get an additional effect-specific second look before the agent finishes - Build/lint/type issues caught early - Security visibility via `corepack yarn npm audit` -- One shared hook implementation for both Codex and Cursor +- One shared hook implementation for Codex, Cursor, and Claude - Temporary task branches stay aligned with the repo's worktree workflow ## Example Hook Scripts @@ -85,4 +86,4 @@ exit 0 Configure hook wiring according to your agent tool docs (`hooks.json`, equivalent, etc.). -In this repo, `.codex/hooks/*.sh` and `.cursor/hooks/*.sh` should stay as thin wrappers that delegate to the shared implementations under `scripts/agent-hooks/`. +In this repo, `.codex/hooks/*.sh`, `.cursor/hooks/*.sh`, and `.claude/hooks/*.sh` should stay as thin wrappers that delegate to the shared implementations under `scripts/agent-hooks/`. Harness-specific startup hooks such as Claude's `SessionStart` can live alongside those wrappers when the other harnesses do not have an equivalent entry point. diff --git a/docs/agent-playbooks/known-surprises.md b/docs/agent-playbooks/known-surprises.md index 4163f998..1298a9f3 100644 --- a/docs/agent-playbooks/known-surprises.md +++ b/docs/agent-playbooks/known-surprises.md @@ -81,9 +81,9 @@ If uncertain, ask the developer before adding an entry. ### Toolchain model names are not interchangeable - **Date:** 2026-04-08 -- **Observed by:** Codex -- **Context:** Reviewing repo-managed agent configs under `.codex/`, `.claude/`, and `.cursor/`. -- **What was surprising:** `composer-2` is only valid for Cursor agents, while `.codex` agents should use `gpt-5.4` instead of `gpt-5.3-codex` or `gpt-5.3-codex-spark`. -- **Impact:** Agents can silently pick unavailable or poor-performing models when equivalent workflow files are copied across toolchains without adjusting the model field. -- **Mitigation:** When editing shared agent definitions, keep the behavior text aligned across toolchains but set models per platform: Cursor may use `composer-2`, `.claude` must not, and `.codex` should use `gpt-5.4`. +- **Observed by:** contributor + Codex +- **Context:** Reviewing repo-managed agent configs under `.codex/agents`, `.cursor/agents`, and `.claude/agents` +- **What was surprising:** `composer-2` is only available for Cursor in this repo, while Codex agents using `gpt-5.3-codex` or `gpt-5.3-codex-spark` perform poorly enough that they should not be configured by default. +- **Impact:** Agents can silently inherit invalid or weak model settings, leading to broken subagent runs or degraded implementation quality. +- **Mitigation:** Keep `.cursor` agent configs on Cursor-supported models only, never use `composer-2` in `.claude`, and standardize `.codex/agents/*.toml` on `gpt-5.4` unless a contributor explicitly requests an override. - **Status:** confirmed diff --git a/docs/agent-playbooks/skills-and-tools.md b/docs/agent-playbooks/skills-and-tools.md index ad6fab52..e22c9069 100644 --- a/docs/agent-playbooks/skills-and-tools.md +++ b/docs/agent-playbooks/skills-and-tools.md @@ -32,7 +32,14 @@ npx skills add https://github.com/vercel-labs/skills --skill find-skills Use `playwright-cli` for browser automation (navigation, interaction, screenshots, tests, extraction). -When using `playwright-cli` for repo UI verification, do not stop after one engine. Run the relevant flow in all three main browser engines: +Default to a fresh isolated browser session for normal verification. If the task depends on the contributor's existing browser state, ask whether they want: + +- a fresh isolated `playwright-cli` session +- their current browser session reused + +Do not attach to a live personal browser session without explicit confirmation. + +When using `playwright-cli` for repo UI verification, run the relevant flow in all three main browser engines: - `chrome` for Blink - `firefox` for Gecko @@ -47,6 +54,7 @@ playwright-cli install --skills Skill install locations: +- `.codex/skills/playwright-cli/` - `.cursor/skills/playwright-cli/` - `.claude/skills/playwright-cli/` @@ -56,3 +64,4 @@ Avoid GitHub MCP and browser MCP servers for this project because they add signi - GitHub operations: use `gh` CLI. - Browser operations: use `playwright-cli`. +- If current browser reuse is needed, keep using Playwright-based attach paths rather than browser MCP servers.