* [AI] Fix git-guard false positives on heredoc and multi -m commits
The [AI]-prefix check extracted the commit message with a greedy
".*-m" sed pattern, which broke in two real-world cases:
- "git commit -m \"$(cat <<'EOF' ...)\"" — the pattern matched the
command-substitution text on the first line and reported the message
as "$(cat <<", blocking a correctly prefixed commit.
- Multiple -m flags — the greedy match grabbed the LAST -m (typically
a Co-Authored-By trailer), so valid commits were blocked and a
missing prefix on the subject could slip through if the last
paragraph happened to start with [AI].
Replace the extraction: find the FIRST -m/--message via
shortest-prefix stripping (git takes the first -m as the subject),
detect the heredoc-in-command-substitution form and read the subject
from the heredoc body's first line, and otherwise check the inline
string as before. Editor/amend/file-based commits remain untouched,
as do the push, hook-skip, git-config and yarn-workspace guards.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Add release notes
* [AI] Fail closed when heredoc detector matches without a body line
The heredoc pattern also matches single-line command substitutions
containing a here-string (e.g. <<< on one line), where reading the
"second line" produced an empty message that the final check treated
as "no inline message" and allowed — letting unprefixed subjects
through. Take the first non-blank heredoc body line instead (matching
git's leading-blank-line cleanup), and when no body line exists fall
back to inline parsing so a statically unknowable message is blocked
rather than waved through.
Found by CodeRabbit review on #8192.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* [AI] Replace mechanical agent rules with shared agent hooks + nano-staged
Move the mechanical "remember to run X" rules out of AGENTS.md and the
agent guidance docs into deterministic, cross-agent hooks, and migrate
the pre-commit runner from lint-staged to nano-staged.
- Add shared hook scripts in scripts/agent-hooks/ (git-guard,
format-edited-file, no-strict-ignore-new-file, prefer-one-component,
check-on-stop, common helpers) wired for Claude (.claude/settings.json),
Codex (.codex/config.toml), and Cursor (.cursor/hooks.json + adapters).
- Enforce "avoid enum" via a new actual/no-enum lint rule, grandfathering
the two existing declarations in .oxlintrc.json overrides.
- Migrate lint-staged -> nano-staged (.nano-staged.json, .husky/pre-commit,
package.json).
- Trim AGENTS.md, .github/agents/pr-and-commit-rules.md, the Cursor rule,
and the committing skill down to the rules that aren't auto-enforced.
- Add release note 8089.md.
* [AI] Align PR-title wording in AGENTS.md with canonical rules
* [AI] Fix check-on-stop hook on bash 3.2 and TSV column collapse
The Stop hook silently no-op'd in two ways:
- `declare -A` isn't supported on stock macOS bash 3.2, and the
slash/hyphen path subscript aborted under `set -u`. Dedupe via a
space-padded string match instead.
- jq emitted an empty middle TSV field for a package with test but no
typecheck; tab is IFS-whitespace so `read` collapsed it and shifted the
columns (eslint-plugin-actual then ran neither). Emit non-empty
sentinels (-, yes/no) so no field can collapse.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>