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
9 changes: 9 additions & 0 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env sh

branch="$(git symbolic-ref --quiet --short HEAD 2>/dev/null || true)"

if [ "$branch" = "main" ]; then
echo "Direct commits to main are disabled in this repository."
echo "Create a feature branch first, then commit there."
exit 1
fi
10 changes: 10 additions & 0 deletions .githooks/pre-push
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env sh

while read -r local_ref local_oid remote_ref remote_oid
do
if [ "$remote_ref" = "refs/heads/main" ]; then
echo "Direct pushes to main are disabled in this repository."
echo "Push a feature branch and open a pull request instead."
exit 1
fi
done
6 changes: 6 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@ the implementation, and where should a change land first.
`skills/browser-cli-delivery/SKILL.md`
- Tests for behavior and contracts:
`tests/unit/*`, `tests/integration/*`
- Repo-local git branch protection hooks:
`.githooks/pre-commit`, `.githooks/pre-push`

## Common Navigation Paths

Expand Down Expand Up @@ -215,6 +217,8 @@ the implementation, and where should a change land first.
-> inspect `src/browser_cli/extension/session.py` and `tests/unit/test_extension_transport.py`.
- If a change touches architecture or public product contracts:
inspect `scripts/guards/architecture.py`, `scripts/guards/product_contracts.py`, and `scripts/guards/docs_sync.py` before making the change final.
- If repo-local branch protection appears inactive in a clone:
inspect `.githooks/pre-commit`, `.githooks/pre-push`, and `git config --local core.hooksPath`; the hooks are repo-owned but activation is clone-local.

## Architectural Boundaries

Expand Down Expand Up @@ -242,6 +246,8 @@ public interactive commands.

- Top-level parser registration lives in `src/browser_cli/cli/main.py`. `read`, `doctor`, `paths`, `task`, `automation`, `status`, and lifecycle `reload` are hand-wired there; the rest come from `get_action_specs()`.
- `browser-cli install-skills` installs the packaged Browser CLI skills into `~/.agents/skills` by default and `--target` overrides the destination root.
- Repo-local contributor branch protection lives under `.githooks/`; activate it
per clone with `git config core.hooksPath .githooks`.
- Public daemon-backed actions should be added through `ActionSpec`, not by manually bolting ad hoc parsers into `main.py`.
- The lifecycle command `browser-cli reload` and the page action `browser-cli page-reload` are intentionally different surfaces. Do not collapse them.
- Public daemon commands return JSON payloads. Preserve `ok/data/meta` shape and machine-readable error codes.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Main Branch Local Protection Design

## Goal

Prevent accidental direct `git commit` and `git push` operations on `main` in a
way that is lightweight, repository-owned, and easy to understand.

## Chosen Approach

Use repo-local git hooks under `.githooks/` and activate them in each clone with
`git config core.hooksPath .githooks`.

This keeps the policy versioned with the repository without introducing new
runtime dependencies or changing the Python product surface.

## Behavior

- `.githooks/pre-commit` rejects commits when the current branch is `main`.
- `.githooks/pre-push` rejects any push whose destination ref is
`refs/heads/main`.
- Detached HEAD states are not blocked by the commit hook.
- The hooks are advisory local protection and can still be bypassed with normal
git escape hatches such as `--no-verify`; remote branch protection remains the
authoritative enforcement layer.

## Documentation Impact

Record the hook location and activation requirement in `AGENTS.md` so future
agents know where the local policy lives and why it may appear inactive in a new
clone.

## Validation

- Mark both hook files executable.
- Set `core.hooksPath` to `.githooks` in the current clone.
- Run repository lint, tests, and guards after the change.
Loading