Merge pull request #814 from bitsocialnet/codex/chore/ai-tooling-sync

chore: sync AI tooling and AGENTS.md with 5chan
This commit is contained in:
Tommaso Casaburi
2026-04-27 19:28:00 +07:00
committed by GitHub
47 changed files with 378 additions and 101 deletions

View File

@@ -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.

View File

@@ -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 -- <file>`) 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

View File

@@ -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

View File

@@ -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 |

View File

@@ -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/` |

View File

@@ -1,6 +1,12 @@
{
"version": 1,
"hooks": {
"sessionStart": [
{
"command": ".claude/hooks/session-start.sh",
"timeout": 120
}
],
"afterFileEdit": [
{
"command": ".claude/hooks/format.sh",

22
.claude/hooks/session-start.sh Executable file
View File

@@ -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

View File

@@ -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

View File

@@ -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.

View File

@@ -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
```

View File

@@ -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.

View File

@@ -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

View File

@@ -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).

View File

@@ -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 |

View File

@@ -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 <tag>..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 104105):
```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

View File

@@ -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: <see Prompt Template below>
```

View File

@@ -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

View File

@@ -72,9 +72,9 @@ useEffect(() => {
<CommentForm key={postCid} />
```
### 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

View File

@@ -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.
"""

View File

@@ -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

View File

@@ -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
```

View File

@@ -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.

View File

@@ -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

View File

@@ -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).

View File

@@ -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 |

View File

@@ -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

View File

@@ -72,9 +72,9 @@ useEffect(() => {
<CommentForm key={postCid} />
```
### 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

View File

@@ -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.

View File

@@ -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 -- <file>`) 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

View File

@@ -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

View File

@@ -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 |

View File

@@ -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/` |

View File

@@ -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

View File

@@ -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.

View File

@@ -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
```

View File

@@ -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.

View File

@@ -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

View File

@@ -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).

View File

@@ -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 |

View File

@@ -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 <tag>..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 104105):
```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

View File

@@ -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: <see Prompt Template below>
```

View File

@@ -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

View File

@@ -72,9 +72,9 @@ useEffect(() => {
<CommentForm key={postCid} />
```
### 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

View File

@@ -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/<slug>/` instead of burying it in a tool-specific hidden directory.

View File

@@ -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.

View File

@@ -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

View File

@@ -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.