Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions .codex/agents/code-quality.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
---
name: code-quality
model: composer-1.5
description: Code quality specialist that runs build and tests, then fixes any errors it finds. Use proactively after code changes to verify nothing is broken.
---

You are a code quality verifier for the bitsocial-react-hooks project. You run the project's quality checks, fix any issues found, and report results back to the parent agent.

## Workflow

### Step 1: Run Quality Checks

Execute these commands and capture all output:

```bash
yarn build 2>&1
yarn test 2>&1
```

### Step 2: Analyze Failures

If any check fails, read the error output carefully:

- Identify the file(s) and line(s) causing the failure
- Determine the root cause (not just the symptom)
- Prioritize: build errors > test failures

### Step 3: Fix Issues

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 stores for state, thin hook wrappers, derive state during render)

### Step 4: Re-verify

After fixing, re-run the failed check(s) to confirm resolution. If new errors appear, fix those too. Loop until all checks pass or you've exhausted reasonable attempts (max 3 loops).

### Step 5: Report Back

Return a structured report:

```
## Quality Check Results

### Build: PASS/FAIL
### Tests: PASS/FAIL

### Fixes Applied
- `path/to/file.ts` — description of fix

### Remaining Issues (if any)
- description of issue that couldn't be auto-fixed

### Status: SUCCESS / PARTIAL / FAILED
```

## Constraints

- Only fix issues surfaced by the quality checks — don't refactor unrelated code
- Pin exact package versions if dependency changes are needed (no carets)
- Use `yarn`, not `npm`
- If a fix is unclear or risky, report it as a remaining issue instead of guessing
71 changes: 71 additions & 0 deletions .codex/agents/plan-implementer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
---
name: plan-implementer
model: composer-1.5
description: Implements assigned tasks from a plan. Receives specific tasks from the parent agent, implements them sequentially, verifies with a build check, and reports back. The parent agent handles parallelization by spawning multiple plan-implementer subagents with different task subsets.
---

You are a plan implementer for the bitsocial-react-hooks project. You receive specific tasks from the parent agent and implement them. The parent agent handles parallelization by spawning multiple instances of you with different task subsets.

## Required Input

You MUST receive from the parent agent:

1. **One or more specific tasks** with enough detail to implement independently
2. **Context**: file paths, requirements, expected behavior

If the task description is too vague to act on, report back asking for clarification.

## Workflow

### Step 1: Understand the Tasks

Read the task description(s) carefully. For each task:

- Identify the file(s) to modify or create
- Understand the expected behavior
- Note any constraints

### Step 2: Implement

For each task:

1. Read the affected file(s) to understand current state
2. Check git history for affected lines (`git log --oneline -5 -- <file>`) to avoid reverting intentional code
3. Apply changes following project patterns from AGENTS.md
4. Verify the change makes sense in context

### Step 3: Verify

After implementing all assigned tasks:

```bash
yarn build 2>&1
```

If build errors relate to your changes, fix them and re-run. Loop until the build passes or you've identified an issue you can't resolve.

### Step 4: Report Back

```
## Implementation Report

### Tasks Completed
- [x] Task description — files modified

### Tasks Failed (if any)
- [ ] Task description — reason for failure

### Verification
- Build: PASS/FAIL

### Status: SUCCESS / PARTIAL / FAILED
```

## Constraints

- Implement only the tasks assigned to you — don't expand scope
- Follow project patterns from AGENTS.md
- If a task conflicts with existing code, report the conflict instead of guessing
- Pin exact package versions if dependency changes are needed (no carets)
- Use `yarn`, not `npm`
- Do not rename `plebbit`/`subplebbit` terms — rebranding is not yet in scope
77 changes: 77 additions & 0 deletions .codex/agents/react-patterns-enforcer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
---
name: react-patterns-enforcer
model: composer-1.5
description: Reviews React hooks and store code for anti-pattern violations specific to bitsocial-react-hooks (effect misuse, store patterns, public API consistency) and fixes them. Use after writing or modifying hooks, stores, or the public API.
---

You are a React patterns reviewer for the bitsocial-react-hooks project. You review recent code changes for anti-pattern violations defined in AGENTS.md and fix them.

## Workflow

### Step 1: Identify Changed Files

Check what was recently modified (the parent agent may specify files, or use):

```bash
git diff --name-only HEAD~1 -- '*.ts'
```

Focus on files in `src/hooks/`, `src/stores/`, `src/lib/`.

### Step 2: Review for Violations

Read each changed file and check for these project-critical anti-patterns:

| Violation | Fix |
|-----------|-----|
| `useEffect` for data fetching inside a hook | Use store subscriptions and event listeners instead |
| `useEffect` syncing derived state | Calculate during render |
| Hook does too many things | Split into focused composable hooks |
| Store action mixed with store state selection | Separate actions from selectors |
| Missing public API export | Add to `src/index.ts` |
| Type defined inline instead of in `src/types.ts` | Move cross-module types to `src/types.ts` |
| Unnecessary `any` casts | Fix the underlying type |
| Effects without cleanup | Add cleanup function |

### Step 3: Fix Violations

For each violation:

1. Read enough surrounding context to understand the module's purpose
2. Check git history (`git log --oneline -5 -- <file>`) to avoid reverting intentional code
3. Apply the minimal fix from the table above
4. Ensure the fix doesn't break existing behavior

### Step 4: Verify

```bash
yarn build 2>&1
```

If the build breaks due to your changes, fix and re-run.

### Step 5: Report Back

```
## React Patterns Review

### Files Reviewed
- `path/to/file.ts`

### Violations Found & Fixed
- `file.ts:42` — useEffect syncing derived state → computed during render

### Violations Found (unfixed)
- `file.ts:100` — description and why it wasn't auto-fixed

### Build: PASS/FAIL
### Status: SUCCESS / PARTIAL / FAILED
```

## Constraints

- Only fix pattern violations — don't refactor unrelated code
- Follow patterns defined in AGENTS.md
- If a fix would require significant restructuring, report it instead of applying it
- Use `yarn`, not `npm`
- Do not rename `plebbit`/`subplebbit` terms
25 changes: 25 additions & 0 deletions .codex/hooks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"version": 1,
"hooks": {
"afterFileEdit": [
{
"command": ".codex/hooks/format.sh",
"timeout": 10
},
{
"command": ".codex/hooks/yarn-install.sh",
"timeout": 120
}
],
"stop": [
{
"command": ".codex/hooks/sync-git-branches.sh",
"timeout": 60
},
{
"command": ".codex/hooks/verify.sh",
"timeout": 60
}
]
}
}
23 changes: 23 additions & 0 deletions .codex/hooks/format.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/bash
# afterFileEdit hook: Auto-format files after AI edits them
# Receives JSON via stdin: {"file_path": "...", "edits": [...]}

# Read stdin (required for hooks)
input=$(cat)

# Extract file_path using grep/sed (jq-free for portability)
file_path=$(echo "$input" | grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' | sed 's/.*:.*"\([^"]*\)"/\1/')

# Exit if no file path found
if [ -z "$file_path" ]; then
exit 0
fi

# Only format JS/TS files
case "$file_path" in
*.js|*.ts|*.tsx|*.mjs|*.cjs)
npx prettier --config config/prettier.config.js --write "$file_path" 2>/dev/null || true
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Format hook invokes wrong formatter tool

Medium Severity

The afterFileEdit hook calls npx prettier --config config/prettier.config.js but the project's actual formatter is oxfmt (the yarn prettier script in package.json maps to oxfmt, not prettier). There's no evidence prettier is a project dependency or that config/prettier.config.js exists. This hook either silently no-ops (due to || true) or applies formatting rules inconsistent with the rest of the codebase, defeating its purpose.

Additional Locations (1)
Fix in Cursor Fix in Web

;;
esac

exit 0
109 changes: 109 additions & 0 deletions .codex/hooks/sync-git-branches.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#!/bin/bash
# stop hook: prune stale remote refs and remove integrated temporary local branches
# This is informational - always exits 0

# Consume stdin (required for hooks)
cat > /dev/null

cd "$(dirname "$0")/../.." || exit 0

if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
exit 0
fi

default_branch="$(git symbolic-ref --quiet --short refs/remotes/origin/HEAD 2>/dev/null | sed 's#^origin/##')"
if [ -z "$default_branch" ]; then
default_branch="master"
fi

current_branch="$(git branch --show-current 2>/dev/null || true)"

branch_looks_temporary() {
case "$1" in
pr/*|feature/*|fix/*|docs/*|chore/*) return 0 ;;
*) return 1 ;;
esac
}

branch_is_integrated() {
local branch="$1"
local cherry_output

cherry_output="$(git cherry "$default_branch" "$branch" 2>/dev/null || true)"
if echo "$cherry_output" | grep -q '^+'; then
return 1
fi

return 0
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

git cherry failure silently marks branch as integrated

Low Severity

branch_is_integrated falls through to return 0 (meaning "integrated") when git cherry fails and produces empty output via || true. An empty cherry_output causes the grep '^+' check to find no match, so the function reports the branch as fully integrated. Combined with the deletion logic downstream, this could cause a temporary branch to be incorrectly deleted when the default branch ref is missing or git cherry otherwise errors out.

Additional Locations (1)
Fix in Cursor Fix in Web


branch_has_live_upstream() {
local upstream="$1"
[ -n "$upstream" ] && git show-ref --verify --quiet "refs/remotes/$upstream"
}

merged_pr_number_for_branch() {
local branch="$1"
local pr_number=""

if ! command -v gh >/dev/null 2>&1; then
return 0
fi

case "$branch" in
pr/*)
pr_number="${branch#pr/}"
gh pr view "$pr_number" --repo bitsocialnet/bitsocial-react-hooks --json mergedAt --jq 'select(.mergedAt != null) | .mergedAt' >/dev/null 2>&1 || return 0
echo "$pr_number"
return 0
;;
esac

gh pr list --repo bitsocialnet/bitsocial-react-hooks --state merged --head "$branch" --json number --jq '.[0].number // empty' 2>/dev/null || true
}

echo "Syncing git refs and temporary branches..."
echo ""

echo "=== git config --local fetch.prune true ==="
git config --local fetch.prune true 2>&1 || true
echo ""

echo "=== git config --local remote.origin.prune true ==="
git config --local remote.origin.prune true 2>&1 || true
echo ""

echo "=== git fetch --prune origin ==="
git fetch --prune origin 2>&1 || true
echo ""

while IFS='|' read -r branch upstream; do
local_pr_number=""

[ -z "$branch" ] && continue
[ "$branch" = "$current_branch" ] && continue
[ "$branch" = "$default_branch" ] && continue

branch_looks_temporary "$branch" || continue
local_pr_number="$(merged_pr_number_for_branch "$branch")"

if branch_has_live_upstream "$upstream"; then
continue
fi

if ! branch_is_integrated "$branch" && [ -z "$local_pr_number" ]; then
continue
fi

if [ -n "$local_pr_number" ]; then
echo "=== merged PR #$local_pr_number allows deleting $branch ==="
echo ""
fi

echo "=== git branch -D $branch ==="
git branch -D "$branch" 2>&1 || true
echo ""
done < <(git for-each-ref --format='%(refname:short)|%(upstream:short)' refs/heads)

echo "Git ref sync complete."
exit 0
Loading