Skip to content

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

omp-commitwright

An opinionated commit and pull request linter for omp. Commit messages and PR bodies must pass ASD-STE100 Simplified Technical English, the Google developer documentation style guide, and the seven rules of a great commit message. Humans get a git hook, agents get a blocked tool call.

The opinions are not configurable by accident. Conventional commit prefixes are required, passive voice is an error, and 12 vocabulary rules reject words like leverage, seamless, and simply. If you disagree with a call, edit vale/.vale.ini and set that check to warning or NO.

Install

Needs Bun and Vale. brew install vale on macOS.

omp plugin marketplace add pjsny/omp-commitwright
omp plugin install commitwright@commitwright
cd ~/.omp/plugins/node_modules/omp-commitwright && bun scripts/setup.ts --styles

Restart your session. The gate is live.

The third line runs vale sync, which downloads the Google style package. The repo does not ship it and plugin install runs no scripts, so prose checks stay off until you sync. Structure checks work either way, and the report prints the exact sync command when the package is missing.

Add --git-hooks to that same command to install the commit-msg hook in the current repo, or --git-hooks --global for every repo. That covers your own commits, not just the agent's.

From a session, /marketplace add pjsny/omp-commitwright and /marketplace install commitwright@commitwright do the same work, then /reload-plugins picks up the slash command.

Development install

git clone https://github.com/pjsny/omp-commitwright && cd omp-commitwright
bun run setup

bun run setup syncs vale styles and runs omp plugin link on the directory. Linking is what makes rules/commit-pr-ste.md visible to rule discovery, which a marketplace install does not get. An extensions: entry in config.yml loads the gate but never the rule.

Flag Effect
--styles Sync vale styles only, skip the link
--project Link into the project scope, not the user scope
--git-hooks Point core.hooksPath at this package for the current repo
--git-hooks --global The same, globally

Every step is idempotent. --git-hooks refuses when core.hooksPath already points somewhere else, because taking it over would silently kill those hooks.

Check the wiring:

omp ttsr list | grep commit-pr-ste
omp ttsr test --source tool --tool bash 'git commit -m "Added stuff"'

What you get

Three places to fail, so no path escapes.

The rule. rules/commit-pr-ste.md fires on tool:bash when the agent writes git commit, jj describe, gh pr create, or gh pr edit, and injects the convention at the moment of writing rather than burning context every turn. Rule discovery covers linked and extensions: roots, not marketplace roots, so a marketplace install ships the same text through the gate on the first block of a session.

The gate. extensions/commitwright.ts handles tool_call, pulls the message out of the command line, and blocks with the diagnostics as the reason. The agent reads which rules it broke and rewrites. It joins repeated -m the way git does, handles --flag=value, -F, --file, --body-file, and checks --title separately. A heredoc counts as the message only when -F - or --body "$(cat <<EOF ...)" routes it there, so a script written next to the commit is left alone.

The git hook. git-hooks/commit-msg catches what no agent gate can see, git commit with no -m, where the message exists only in the editor buffer. The linter applies git's cleanup first. It cuts the --verbose scissors section, drops comment lines, and stays quiet on an empty message, since git aborts that commit on its own.

The rules

Layer Source Checked by
Structure cbeams, tpope bin/lint-commit-message.ts
Language ASD-STE100 Simplified Technical English Vale, vale/styles/STE/
Style Google developer documentation style guide Vale, Google package

The seven rules:

  1. Blank line between subject and body.
  2. Subject under 50 characters, 72 is the hard limit.
  3. Capitalize the subject. Conventional commits invert this, so the prefix leads and the summary stays lowercase.
  4. No period at the end of the subject.
  5. Imperative mood. The subject completes "If applied, this commit will ___".
  6. Wrap the body at 72 characters. Commit messages only, since GitHub ignores hard wraps in a PR body.
  7. The body explains what and why, never how.

Twelve STE rules cover the constraints that survive translation to a linter. Sentence and paragraph length, active voice, banned vocabulary, one word with one meaning, noun clusters, contractions, -ing main verbs. The Google package handles word list, tone, and formatting, with duplicated Google checks disabled so each fault produces one alert instead of two.

Use the linter directly

bun bin/lint-commit-message.ts --kind commit .git/COMMIT_EDITMSG
git log -1 --format=%B | bun bin/lint-commit-message.ts --kind commit -
printf '%s\n' "$BODY" | bun bin/lint-commit-message.ts --kind pr

--kind commit applies all seven rules plus prose. --kind pr is a body with no subject and no wrap limit. --kind pr-title is a title with the subject rules and no prose rules.

Exit codes are 0 for clean or warnings only, 1 for errors, 2 for a bad invocation. Warnings never block.

In a session, /commit-style lints a message, a file, or HEAD when you pass nothing. A clone with bun link also puts the linter on PATH as commitwright. A marketplace install does not, so call the script by path.

Configure

Change a level in vale/.vale.ini. Every check takes NO, suggestion, warning, or error.

Add project vocabulary to vale/styles/config/vocabularies/Commit/accept.txt.

Point at your own styles with COMMITWRIGHT_VALE_CONFIG=/path/to/.vale.ini.

Drop the conventional commit requirement by deleting the Subject.Conventional block in bin/lint-commit-message.ts. The capitalization branch already handles a bare subject.

Skip one commit with git commit --no-verify, which bypasses the git hook. The omp gate has no bypass. Fix the message.

When things are missing

No vale on PATH, or styles not synced, and structure checks still run while prose is skipped. The report names the sync command to run. A crash inside the gate is logged and the command proceeds, because a broken gate must not wedge every commit.

Layout

bin/lint-commit-message.ts   structure checks + vale driver
extensions/commitwright.ts   omp tool_call gate + /commit-style
git-hooks/commit-msg         git hook for editor commits
rules/commit-pr-ste.md       TTSR rule with the full convention
.omp-plugin/marketplace.json marketplace catalog for this repo
vale/.vale.ini               style selection and levels
vale/styles/STE/             12 ASD-STE100 rules
scripts/setup.ts             idempotent installer
test/                        32 tests: parsing, kind routing, exit codes

Prior art

License

MIT

About

An opinionated commit and pull request linter for omp.

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages