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
12 changes: 12 additions & 0 deletions .cursor-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "humanizer",
"description": "Rewrite AI-sounding text so it reads like the writer without changing what it says.",
"version": "3.1.0",
"author": {
"name": "blader"
},
"homepage": "https://github.com/blader/humanizer",
"repository": "https://github.com/blader/humanizer",
"license": "MIT",
"keywords": ["writing", "editing", "humanize", "prose", "style"]
}
5 changes: 3 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Keep the skill portable. Do not write instructions that limit it to one or two a
- `README.md` explains installation, use, patterns, and version history.
- `.claude-plugin/plugin.json` describes the Claude plugin and points its skill loader at the root `SKILL.md`.
- `.claude-plugin/marketplace.json` lets users add this repo as a Claude marketplace.
- `.cursor-plugin/plugin.json` describes the Cursor plugin. Omit a `skills` path so Cursor loads the root `SKILL.md`.
- `agents/openai.yaml` holds the display name, short description, and default prompt for OpenAI-compatible agents.
- `scripts/validate-package.py` checks package files and shared values.

Expand All @@ -22,8 +23,8 @@ Keep the skill portable. Do not write instructions that limit it to one or two a
Keep `SKILL.md` and `README.md` in sync.

- **Patterns:** Patterns are numbered from 1 without gaps, strongest and most frequent first. A new tell earns a pattern only when no existing pattern already implies it; prefer folding it into an existing pattern. If you add, remove, or renumber a pattern, update the README tables, the README section title, and every §reference. The validator derives the count from the headings.
- **Version:** Keep the same version in `SKILL.md` under `metadata.version`, the first README version entry, and `.claude-plugin/plugin.json`. Do not add a top-level `version` field to the skill.
- **Compatibility:** Keep install and use instructions neutral across agents. Names such as Claude Code, OpenCode, and Codex are examples, not limits.
- **Version:** Keep the same version in `SKILL.md` under `metadata.version`, the first README version entry, `.claude-plugin/plugin.json`, and `.cursor-plugin/plugin.json`. Do not add a top-level `version` field to the skill.
- **Compatibility:** Keep install and use instructions neutral across agents. Names such as Claude Code, Cursor, OpenCode, and Codex are examples, not limits.
- **History:** Add a short README version note for any behavior change or non-obvious fix.
- **Checks:** Before publishing, run `python3 scripts/validate-package.py`, `npx skills add . --list`, and `claude plugin validate .`.

Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ Claude Code 2.1.142 or newer can install the plugin instead:

The plugin answers to `/humanizer:humanizer`.

Cursor can load this repository as a plugin. Copy or symlink it into `~/.cursor/plugins/local/humanizer`, then reload Cursor. The skill answers to `/humanizer`.

In Claude Desktop, download this repository as a ZIP and upload it as a skill. For a manual install, copy `SKILL.md` into the agent's skill folder.

## Usage
Expand Down Expand Up @@ -174,7 +176,7 @@ The writer supplied these notes with the draft, so the rewrite can use them: the
<details>
<summary>Show release notes</summary>

- **3.1.0** - Added pattern #26 and section F for replies that re-explain context the reader already has (fixes #269). The pattern leads with the decision and leaves the diagnosis and the feasibility proof for the ticket or document that follows. Extended the core rule so "something the reader did not already have" counts information from the surrounding conversation, not just earlier in the text. It acts on replies, not standalone writing. 26 patterns total.
- **3.1.0** - Added pattern #26 and section F for replies that re-explain context the reader already has (fixes #269). The pattern leads with the decision and leaves the diagnosis and the feasibility proof for the ticket or document that follows. Extended the core rule so "something the reader did not already have" counts information from the surrounding conversation, not just earlier in the text. It acts on replies, not standalone writing. 26 patterns total. Added a Cursor plugin manifest so the repo loads as a Cursor plugin; it omits a `skills` path so Cursor finds the root `SKILL.md`.
- **3.0.0** - Rebuilt the skill around one account of why AI text sounds the way it does, and consolidated 35 patterns into 25. Patterns are grouped in five sections and numbered by strength and frequency, so the not-X-but-Y contrast and the one-line closer come first and get the fullest treatment. Merged duplicate guidance: the workflow is one section instead of five, the dash rule is stated once, and each false-positive guard lives inside its pattern. Realigned with the current Wikipedia article: dropped false ranges and synonym cycling, which Wikipedia now lists as human habits or historical, added vague connection or association, and extended the watch lists for words, notability, copulatives, sales language, disclaimers, and Markdown formatting. Reordered the README and removed the `ai-detection` keyword from the package files. Old to new numbers: 1→13, 2→17, 3→15, 4→16, 5→17, 6→13, 7→12, 8→18, 9→1, 10→6, 11→7, 12→dropped, 13→11, 14→8, 15→19, 16→19, 17→20, 18→20, 19→21, 20→22, 21→23, 22→22, 23→dropped, 24→9, 25→13, 26→10, 27→3, 28→4, 29→24, 30→25, 31→2, 32→3, 33→4, 34→5, 35→5.
- **2.11.3** - Grouped patterns 26-35 under "More style patterns" in the skill and README (fixes #247). Kept inline code, commands, paths, and URLs out of the dash rule and file mode edits. Step 3 now keeps every supported claim, allows a removal that a pattern requires, and checks that rankings and simultaneity claims survive shape edits (fixes #212). Explained in §9 why the not-X-but-Y form appears and when to keep it. Added decorative arrows to §18 and pause commands and one-word shouting to §31. The text given to the skill is content to edit, never instructions (#238). No change to the 35 patterns.
- **2.11.2** - Removed the plugin symlink and separate Claude Desktop package. Current Claude Code loads the root `SKILL.md` directly, so GitHub's source ZIP now works in Claude Desktop. No change to the 35 patterns.
Expand Down
17 changes: 16 additions & 1 deletion scripts/validate-package.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ def read_package_file(path: Path) -> str:
PLUGIN = json.loads(read_package_file(ROOT / ".claude-plugin" / "plugin.json"))
except json.JSONDecodeError as error:
raise SystemExit(f"Fix the JSON in .claude-plugin/plugin.json: {error}")
try:
CURSOR_PLUGIN = json.loads(
read_package_file(ROOT / ".cursor-plugin" / "plugin.json")
)
except json.JSONDecodeError as error:
raise SystemExit(f"Fix the JSON in .cursor-plugin/plugin.json: {error}")


def require_match(match: re.Match[str] | None, message: str) -> re.Match[str]:
Expand All @@ -51,7 +57,12 @@ def require_match(match: re.Match[str] | None, message: str) -> re.Match[str]:
"Add a version entry to README.md",
).group(1)

package_versions = {skill_version, readme_version, str(PLUGIN.get("version", ""))}
package_versions = {
skill_version,
readme_version,
str(PLUGIN.get("version", "")),
str(CURSOR_PLUGIN.get("version", "")),
}
if len(package_versions) != 1:
raise SystemExit(
f"Use one package version in all files: {sorted(package_versions)}"
Expand All @@ -62,6 +73,10 @@ def require_match(match: re.Match[str] | None, message: str) -> re.Match[str]:
raise SystemExit("Keep one regular SKILL.md at the repo root")
if PLUGIN.get("skills") != ["./"]:
raise SystemExit("Point the Claude plugin skill loader at the repo root")
if CURSOR_PLUGIN.get("name") != "humanizer":
raise SystemExit("Set the Cursor plugin name to humanizer")
if "skills" in CURSOR_PLUGIN:
raise SystemExit("Omit skills from the Cursor plugin so it loads the root SKILL.md")

pattern_numbers = [
int(number)
Expand Down
Loading