mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
chore(ai-workflow): tighten agent workflow and worktree tooling (#1107)
* chore(ai-workflow): tighten agent workflow and worktree tooling * fix(ai-workflow): address review feedback * fix(ai-workflow): make format hook portable
This commit is contained in:
+2
-25
@@ -1,27 +1,4 @@
|
||||
#!/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)
|
||||
# Match the other hooks by resolving relative paths from the repo root.
|
||||
cd "$(dirname "$0")/../.." || exit 0
|
||||
|
||||
# Run oxfmt on the file (silent on success)
|
||||
npx oxfmt "$file_path" 2>/dev/null || true
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
repo_root="$(cd "$(dirname "$0")/../.." && pwd)"
|
||||
exec "$repo_root/scripts/agent-hooks/format.sh" "$@"
|
||||
|
||||
@@ -1,110 +1,4 @@
|
||||
#!/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
|
||||
|
||||
# Change to project directory
|
||||
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
|
||||
}
|
||||
|
||||
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/5chan --json mergedAt --jq 'select(.mergedAt != null) | .mergedAt' >/dev/null 2>&1 || return 0
|
||||
echo "$pr_number"
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
|
||||
gh pr list --repo bitsocialnet/5chan --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
|
||||
repo_root="$(cd "$(dirname "$0")/../.." && pwd)"
|
||||
exec "$repo_root/scripts/agent-hooks/sync-git-branches.sh" "$@"
|
||||
|
||||
+2
-61
@@ -1,63 +1,4 @@
|
||||
#!/bin/bash
|
||||
# stop hook: Run build, lint, type-check, and security audit when agent finishes
|
||||
# This is informational - always exits 0
|
||||
|
||||
# Consume stdin (required for hooks)
|
||||
cat > /dev/null
|
||||
|
||||
# Change to project directory
|
||||
cd "$(dirname "$0")/../.." || exit 0
|
||||
|
||||
cleanup_generated_dir() {
|
||||
local path="$1"
|
||||
|
||||
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
||||
return
|
||||
fi
|
||||
|
||||
if git ls-files --error-unmatch "$path" >/dev/null 2>&1; then
|
||||
if git diff --quiet -- "$path"; then
|
||||
return
|
||||
fi
|
||||
|
||||
echo "=== git restore --worktree $path ==="
|
||||
git restore --worktree -- "$path" 2>&1 || true
|
||||
echo ""
|
||||
return
|
||||
fi
|
||||
|
||||
if [ -e "$path" ]; then
|
||||
echo "=== rm -rf $path ==="
|
||||
rm -rf "$path" 2>&1 || true
|
||||
echo ""
|
||||
fi
|
||||
}
|
||||
|
||||
echo "Running build, lint, type-check, and security audit..."
|
||||
echo ""
|
||||
|
||||
# Run build (catches compilation errors)
|
||||
echo "=== yarn build ==="
|
||||
yarn build 2>&1 || true
|
||||
echo ""
|
||||
|
||||
# Run lint
|
||||
echo "=== yarn lint ==="
|
||||
yarn lint 2>&1 || true
|
||||
echo ""
|
||||
|
||||
# Run type-check
|
||||
echo "=== yarn type-check ==="
|
||||
yarn type-check 2>&1 || true
|
||||
echo ""
|
||||
|
||||
# Run security audit
|
||||
echo "=== yarn audit ==="
|
||||
yarn audit 2>&1 || true
|
||||
echo ""
|
||||
|
||||
cleanup_generated_dir build
|
||||
cleanup_generated_dir dist
|
||||
|
||||
echo "Verification complete."
|
||||
exit 0
|
||||
repo_root="$(cd "$(dirname "$0")/../.." && pwd)"
|
||||
exec "$repo_root/scripts/agent-hooks/verify.sh" "$@"
|
||||
|
||||
@@ -1,25 +1,4 @@
|
||||
#!/bin/bash
|
||||
# afterFileEdit hook: Run yarn install when package.json is changed
|
||||
# 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 run yarn install if package.json was changed
|
||||
if [ "$file_path" = "package.json" ]; then
|
||||
# Change to project directory
|
||||
cd "$(dirname "$0")/../.." || exit 0
|
||||
|
||||
echo "package.json changed - running yarn install to update yarn.lock..."
|
||||
yarn install
|
||||
fi
|
||||
|
||||
exit 0
|
||||
repo_root="$(cd "$(dirname "$0")/../.." && pwd)"
|
||||
exec "$repo_root/scripts/agent-hooks/yarn-install.sh" "$@"
|
||||
|
||||
@@ -41,21 +41,21 @@ fi
|
||||
|
||||
### 3. Ensure branch workflow is reviewable
|
||||
|
||||
- If already on a short-lived task branch such as `feature/*`, `fix/*`, `docs/*`, or `chore/*`, stay on it.
|
||||
- If already on a short-lived task branch such as `codex/feature/*`, `codex/fix/*`, `codex/docs/*`, or `codex/chore/*`, stay on it.
|
||||
- If on `master`, create a task branch before staging or committing.
|
||||
- Do **not** commit the work directly on `master` when PR review bots are expected.
|
||||
|
||||
Suggested naming:
|
||||
|
||||
- `feature/short-slug`
|
||||
- `fix/short-slug`
|
||||
- `docs/short-slug`
|
||||
- `chore/short-slug`
|
||||
- `codex/feature/short-slug`
|
||||
- `codex/fix/short-slug`
|
||||
- `codex/docs/short-slug`
|
||||
- `codex/chore/short-slug`
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
git switch -c fix/reply-editor-stuck
|
||||
git switch -c codex/fix/reply-editor-stuck
|
||||
```
|
||||
|
||||
### 4. Review diffs for relevance
|
||||
|
||||
Reference in New Issue
Block a user