Skip to content

feat(#45): hooks resolve ops root from any workspace directory#46

Merged
atlas-apex merged 2 commits into
mainfrom
feature/#45-hooks-multi-repo-support
Apr 12, 2026
Merged

feat(#45): hooks resolve ops root from any workspace directory#46
atlas-apex merged 2 commits into
mainfrom
feature/#45-hooks-multi-repo-support

Conversation

@atlas-apex

Copy link
Copy Markdown
Collaborator

Summary

  • All 14 hook commands in settings.json now use an inline resolver that walks up from $PWD to find onboarding.yaml (the ops root marker), then exec the hook from the resolved absolute path
  • 4 cross-repo hooks now parse --repo from the command and pass it to gh API calls
  • Fixes "No such file or directory" errors when working inside workspace/<project>/

Changes

File What changed
.claude/settings.json All 14 command entries use inline ops-root resolver
validate-pr-create.sh Parse --repo for cross-repo issue validation
block-merge-on-red-ci.sh Parse --repo, pass to gh pr checks/view
block-unreviewed-merge.sh Parse --repo, pass to gh pr view fallback
require-design-review-for-ui.sh Parse --repo, pass to gh pr view/diff

Test plan

  • Resolver finds ops root from workspace/curios-dog/backend/
  • Resolver works from ops repo root (no regression)
  • Hooks block correctly when invoked via resolver (block-main-push, block-git-add-all tested)
  • End-to-end: work on a ticket in a workspace project, hooks enforce SDLC

Closes #45


Glossary

Term Definition
Ops root The ApexStack fork directory containing onboarding.yaml, .claude/, and workspace/
Inline resolver A bash -c one-liner that walks up from $PWD looking for onboarding.yaml to find the ops root
Cross-repo hook A hook that validates against a different repo than origin (via --repo flag)

Generated with Claude Code

- settings.json: all 14 hook commands use inline resolver that walks up
  from $PWD to find onboarding.yaml (the ops root marker), then exec
  the hook from the resolved absolute path
- validate-pr-create.sh: parse --repo flag for cross-repo PR creation
- block-merge-on-red-ci.sh: pass --repo to gh pr checks/view
- block-unreviewed-merge.sh: pass --repo to gh pr view fallback
- require-design-review-for-ui.sh: pass --repo to gh pr view/diff

Previously all hooks failed with "No such file or directory" when cwd
was inside workspace/<project>/ because the relative .claude/hooks/
path only resolved from the ops repo root.

Closes #45

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

@atlas-apex atlas-apex left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Code Review: PR #46

Commit: 3586278e302d351a26f34ab275237f960cbff0f0

Summary

This PR makes all 14 ApexStack hooks work when cwd is inside a workspace project directory (e.g., workspace/curios-dog/backend/) instead of requiring the ops repo root. It does this via (a) an inline bash -c resolver in settings.json that walks up from $PWD to find onboarding.yaml, and (b) --repo flag parsing in 4 cross-repo hooks so gh API calls target the correct repository.

Checklist Results

  • Architecture & Design: Pass -- the resolver pattern is simple, consistent across all 14 hooks, and the --repo parsing in shell hooks is a reasonable approach for cross-repo support.
  • Code Quality: Pass with one issue (see below) -- the hook changes are clean and follow existing patterns.
  • Testing: N/A -- shell hook infrastructure; the PR description documents manual test coverage.
  • Security: Pass -- no secrets, no injection vectors. The $REPO_FLAG is derived from command parsing and passed to gh which validates it.
  • Performance: Pass -- the resolver is a simple directory walk, not on a hot path.
  • PR Description & Glossary: Pass -- clear summary, change table, test plan, and glossary present.
  • Technical Decisions (AgDR): N/A -- this is a bug fix / infrastructure improvement, not a new technology choice or architecture decision. The resolver pattern is a minimal shell idiom, not an architectural decision requiring an AgDR.

Issues Found

1. $schema URL changed to a broken URL (non-blocking but should fix)

In .claude/settings.json line 2, the $schema was changed from:

"$schema": "https://json.schemastore.org/claude-code-settings.json"

to:

"$schema": "https://json-schema.org/claude-code-settings.json"

The old URL (json.schemastore.org) redirects to a valid schema (HTTP 200). The new URL (json-schema.org) returns HTTP 404. This appears to be an accidental edit -- it is unrelated to the hook resolver feature. Should be reverted to the original URL.

Suggestions (non-blocking)

1. --repo=value syntax not parsed

The sed pattern 's/.*--repo[[:space:]]+([^[:space:]]+).*/\1/p' only handles --repo value (space-separated). The gh CLI also accepts --repo=value (equals-sign). If someone uses the equals form, CMD_REPO will be empty and the hook falls back to local repo context -- safe degradation, not a crash, but worth noting. A future enhancement could handle both:

sed -nE 's/.*--repo[=[:space:]]+([^[:space:]]+).*/\1/p'

2. Resolver failure mode when onboarding.yaml is missing entirely

If the walker reaches / without finding onboarding.yaml, r becomes empty string, and exec "/.claude/hooks/..." will fail with "No such file or directory". This is acceptable behavior (the hook effectively becomes a no-op with a non-zero exit), but a future improvement could add a guard: [ -z "$r" ] || [ "$r" = "/" ] && exit 0.

Verdict

COMMENT -- The code logic is correct and well-structured. The only concrete issue is the broken $schema URL which should be reverted before merge. The --repo= and resolver-failure-mode points are non-blocking suggestions for future hardening.


Reviewed by Rex (Code Reviewer Agent)
Reviewed commit: 3586278e302d351a26f34ab275237f960cbff0f0

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@atlas-apex atlas-apex merged commit fcdfa58 into main Apr 12, 2026
2 checks passed
Dr-kersho added a commit to Dr-kersho/apexyard that referenced this pull request Jun 3, 2026
- Add physical-card printing feasibility (DEFER, gates G1–G5)
- Mark Phase 1 complete; me2resh#36/me2resh#45/me2resh#46 done; link me2resh#47 to feasibility doc

Co-authored-by: Cursor <cursoragent@cursor.com>
Dr-kersho added a commit to Dr-kersho/apexyard that referenced this pull request Jun 3, 2026
* docs(koraid): me2resh#47 feasibility and roadmap sync

- Add physical-card printing feasibility (DEFER, gates G1–G5)
- Mark Phase 1 complete; me2resh#36/me2resh#45/me2resh#46 done; link me2resh#47 to feasibility doc

Co-authored-by: Cursor <cursoragent@cursor.com>

* docs(koraid): note ops PR scope in README

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
osama-abu-baker pushed a commit to osama-abu-baker/apexyard that referenced this pull request Jun 3, 2026
…ulti-repo-support

feat(me2resh#45): hooks resolve ops root from any workspace directory
@me2resh me2resh deleted the feature/#45-hooks-multi-repo-support branch June 5, 2026 16:52
mosta7il pushed a commit to mosta7il/apexyard that referenced this pull request Jun 8, 2026
…ulti-repo-support

feat(me2resh#45): hooks resolve ops root from any workspace directory
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: hooks must work from workspace project directories (multi-repo support)

2 participants