RuleStack

Configs

Stacks

Compare

Diff

RuleStack

Configs

Stacks

Compare

Diff

Read API

RuleStack

Configs

Stacks

Compare

Diff

Read API

Configs/MohamedAbdallah-14/unslop/diff

Two files, one repository

MohamedAbdallah-14/unslop ships 7 formats across 7 indexed files. The question worth asking is whether the second one says anything the first does not.

CompareAGENTS.md ↔ CLAUDE.mdAGENTS.md ↔ GEMINI.mdAGENTS.md ↔ Cline rulesAGENTS.md ↔ Copilot instructionsAGENTS.md ↔ Cursor rulesAGENTS.md ↔ Windsurf rulesCLAUDE.md ↔ GEMINI.mdCLAUDE.md ↔ Cline rulesCLAUDE.md ↔ Copilot instructionsCLAUDE.md ↔ Cursor rulesCLAUDE.md ↔ Windsurf rulesGEMINI.md ↔ Cline rulesGEMINI.md ↔ Copilot instructionsGEMINI.md ↔ Cursor rulesGEMINI.md ↔ Windsurf rulesCline rules ↔ Copilot instructionsCline rules ↔ Cursor rulesCline rules ↔ Windsurf rulesCopilot instructions ↔ Cursor rulesCopilot instructions ↔ Windsurf rulesCursor rules ↔ Windsurf rules
A · AGENTS.md · 257 wordsB · CLAUDE.md · 1672 words
What each file covers, counted
DimensionSharedOnly in AOnly in BOverlap
Sections07170%
Commands10150%
Section tags13413%

What each file covers

Sections

0 shared · 7 only in A · 17 only in B
  • − Agent Instructions — unslop repo
  • − Workflow
  • − Tone
  • − Commits
  • − Reviews
  • − Tests are the contract
  • − Relationship to CLAUDE.md
  • + Unslop — Maintainer Guide
  • + README is a product artifact
  • + What this repo is
  • + Source of Truth
  • + Mirrored locations (do NOT edit by hand)
  • + Hooks
  • + `hooks/unslop-config.js` — shared module
  • + `hooks/unslop-activate.js` — SessionStart hook
  • + `hooks/unslop-mode-tracker.js` — UserPromptSubmit hook
  • + `hooks/unslop-statusline.sh` — Statusline badge
  • + Hook installation
  • + Skills
  • + unslop Python package
  • + Tests
  • + Adding a sub-skill
  • + Voice
  • + Security

Commands

1 shared · 0 only in A · 1 only in B
  • + pip install torch transformers
  •   python3 -m pytest tests/unslop/

Section tags

1 shared · 3 only in A · 4 only in B
  • − git-pr
  • − api
  • − agent-behaviour
  • + setup
  • + security
  • + do-not
  • + docs
  •   test

Line diff

+188 added−22 removed14 unchanged6.9% identical
MohamedAbdallah-14/unslop · AGENTS.md
@@ −1 @@
1# Agent Instructions — unslop repo
2 
3Drop AI-isms. Keep the technical substance exact. Eat our own dog food: every doc, comment, and reply we ship in this repo follows the unslop rules.
4 
5## Workflow
6 
71. Read [`CLAUDE.md`](./CLAUDE.md) for the full maintainer guide.
82. Edit only the SSOT files. Mirrors are auto-generated by CI.
93. Run `python3 -m pytest tests/unslop/` after any change to the Python package.
104. Run `bash hooks/install.sh` after editing any hook script and verify the `.unslop-active` flag updates correctly with `/unslop full` and `stop unslop`.
11 
12## Tone
13 
14- No "Great question!" openers. No "I'd be happy to help."
15- No "delve", "tapestry", "testament", "leverage" (as filler), "robust" (as filler), "seamless", "holistic", "comprehensive" (as filler).
16- No "It's important to note that". No "Generally speaking". No "In essence".
17- No five-paragraph essay shape in commit messages or PR descriptions.
18- Burstiness: short. Then one longer sentence that develops the point. Short again.
19- Real uncertainty is fine ("I think", "probably") when honest. Performative softening isn't.
 
 
20 
21## Commits
22 
23Use `unslop-commit` style (Conventional Commits, body only when "why" isn't obvious from subject). See `skills/unslop-commit/SKILL.md`.
24 
25## Reviews
26 
27Use `unslop-review` style (file:line, severity prefix, observation, fix). See `skills/unslop-review/SKILL.md`.
28 
29## Tests are the contract
 
 
 
 
30 
31The `TestPreservation` suite enforces that humanization never modifies code, URLs, or headings. Don't disable it. If a test fails, the unslop is wrong, not the test.
32 
33## Relationship to CLAUDE.md
34 
35This file is the short cross-IDE companion to `CLAUDE.md`. Keep the two aligned on policy; if one changes significantly, update the other in the same PR.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36 
MohamedAbdallah-14/unslop · CLAUDE.md
@@ +1 @@
1# Unslop — Maintainer Guide
2 
3This file is for agents and maintainers working on the unslop plugin itself. End-user docs live in [`README.md`](./README.md).
4 
5## README is a product artifact
6 
7The README is the product front door. Non-technical people read it to decide whether unslop is worth installing. Treat it like UI copy, not internal docs.
 
 
 
8 
9**Rules for any README change:**
10 
11- Readable by non-AI-agent users. If you write "SessionStart hook injects system context", that phrase is invisible to most readers — translate it ("loads the unslop rules every time you open Claude Code").
12- Keep the **Before / After** examples first. That is the pitch. Cutting them or burying them under prose breaks the conversion path.
13- Install table must stay accurate. One broken install command costs a real user. Re-test every command in the install table on every PR that touches install scripts, plugin manifests, or hook paths.
14- The "What unslop does" feature list must sync with the actual code. If a rule ships or gets removed in `unslop/scripts/humanize.py`, update the README in the same PR.
15- Preserve voice. The README's terse, no-AI-ism style is intentional — it is unslop eating its own dog food. If you find a stock phrase ("comprehensive solution", "leverages cutting-edge"), a sycophancy opener ("Great question!"), or a hedging stack ("It's important to note that"), fix it in the same commit.
16- Benchmark numbers come from real runs in `benchmarks/` and `evals/`. Never invent or round. Re-run the suite if you doubt a number you're about to print.
17- Adding a new IDE/agent integration to the install table: also add a per-agent detail block in the appropriate `<details>` section so the table itself stays scannable.
18- Readability check before any README commit: would a non-programmer understand the value prop and complete the install within 60 seconds? If not, simplify or move detail into `GETTING_STARTED.md`.
19 
20## What this repo is
21 
22A multi-platform plugin that makes assistant output sound human. Single source of truth (SSOT) files are synced to mirrored locations (Cursor, Windsurf, Codex bundle, etc.) by `scripts/sync-mirrors.sh` on push via `.github/workflows/sync.yml`.
23 
24## Source of Truth
25 
26Three files are authoritative. Every other location with the same name is a mirror, generated by `scripts/sync-mirrors.sh` (run by `.github/workflows/sync.yml`). **Edit the SSOT only.**
27 
28| Concern | SSOT |
29|---------|------|
30| Main unslop skill | `skills/unslop/SKILL.md` |
31| Always-on activation rule | `rules/unslop-activate.md` |
32| File-rewriter skill | `unslop/SKILL.md` |
33 
34Sub-skills (`unslop-commit`, `unslop-review`, `unslop-help`) are also authoritative under `skills/<name>/SKILL.md`.
35 
36## Mirrored locations (do NOT edit by hand)
37 
38- `unslop/SKILL.md` (top-level)
39- `plugins/unslop/skills/unslop/SKILL.md`
40- `.cursor/skills/unslop/SKILL.md`
41- `.windsurf/skills/unslop/SKILL.md`
42- `.cursor/rules/unslop.mdc`
43- `.windsurf/rules/unslop.md`
44- `.clinerules/unslop.md`
45- `.github/copilot-instructions.md`
46- `skills/unslop-file/SKILL.md`
47- `skills/unslop-file/scripts/**`
48- `plugins/unslop/skills/unslop-file/SKILL.md`
49- `plugins/unslop/skills/unslop-file/scripts/**`
50 
51The sync workflow handles all of these. If you edit a mirror, the next sync silently overwrites your change.
52 
53## Hooks
54 
55Four hook files live in `hooks/` plus a `unslop-config.js` shared module and a `package.json` CommonJS marker. Communicate via flag file at `$CLAUDE_CONFIG_DIR/.unslop-active` (falls back to `~/.claude/.unslop-active`).
56 
57```
58SessionStart hook ──writes mode──▶ $CLAUDE_CONFIG_DIR/.unslop-active ◀──writes mode── UserPromptSubmit hook
59 │
60 reads
61 ▼
62 unslop-statusline.sh
63 [unslop] / [unslop:FULL] / ...
64```
65 
66`hooks/package.json` pins the directory to `{"type": "commonjs"}` so the `.js` hooks resolve as CJS even when an ancestor `package.json` (e.g. `~/.claude/package.json` from another plugin) declares `"type": "module"`. Without this, `require()` blows up with `ReferenceError: require is not defined in ES module scope`.
67 
68All hooks honor `CLAUDE_CONFIG_DIR` for non-default Claude Code config locations.
69 
70### `hooks/unslop-config.js` — shared module
71 
72Exports:
73- `getDefaultMode()` — resolves default mode from `UNSLOP_DEFAULT_MODE` env var, then `$XDG_CONFIG_HOME/unslop/config.json` / `~/.config/unslop/config.json` / `%APPDATA%\unslop\config.json`, then `'balanced'`
74- `safeWriteFlag(flagPath, content)` — symlink-safe flag write. Refuses if flag target or its immediate parent is a symlink. Opens with `O_NOFOLLOW` where supported. Atomic temp + rename. Creates with `0600`. Protects against local attackers replacing the predictable flag path with a symlink to clobber files writable by the user. Used by both write hooks. Silent-fails on all filesystem errors.
75- `readFlag(flagPath)` — symlink-safe, size-capped (64 bytes), whitelist-validated flag read. Returns null on any anomaly. Used by mode tracker's per-turn reinforcement to avoid injecting untrusted bytes into model context.
76- `getFlagPath()` — resolves `$CLAUDE_CONFIG_DIR/.unslop-active`.
77 
78### `hooks/unslop-activate.js` — SessionStart hook
79 
80Runs once per Claude Code session start. Three things:
811. Writes the active mode to `$CLAUDE_CONFIG_DIR/.unslop-active` via `safeWriteFlag` (creates if missing)
822. Emits unslop ruleset as hidden stdout — reads `skills/unslop/SKILL.md` at runtime, falls back to `rules/unslop-activate.md`, then to hardcoded rules
833. Checks `settings.json` for statusline config; if missing, appends nudge to offer setup on first interaction
84 
85Silent-fails on all filesystem errors — never blocks session start.
86 
87### `hooks/unslop-mode-tracker.js` — UserPromptSubmit hook
88 
89Reads JSON from stdin. Three responsibilities:
90 
91**1. Slash-command activation.** If prompt starts with `/unslop`, writes mode to flag file via `safeWriteFlag`:
92- `/unslop` → configured default (see `unslop-config.js`, defaults to `balanced`)
93- `/unslop subtle` → `subtle`
94- `/unslop balanced` → `balanced`
95- `/unslop full` → `full`
96- `/unslop voice-match` → `voice-match`
97- `/unslop anti-detector` → `anti-detector`
98- `/unslop-commit` → `commit`
99- `/unslop-review` → `review`
100 
101**2. Natural-language activation/deactivation.** Matches phrases like "activate unslop", "turn on unslop mode", "humanize this", "make this sound human" and writes the configured default mode. Matches "stop unslop", "disable unslop", "normal mode", "robotic mode" and deletes the flag file.
102 
103**3. Per-turn reinforcement.** When flag is set to a non-independent mode (i.e. not `commit`/`review`), emits a small `hookSpecificOutput` JSON reminder so the model keeps unslop style after other plugins inject competing instructions mid-conversation. The full ruleset comes from SessionStart — this is an attention anchor.
104 
105### `hooks/unslop-statusline.sh` — Statusline badge
106 
107Reads flag file at `$CLAUDE_CONFIG_DIR/.unslop-active`. Security hardened: refuses symlinks, caps read at 64 bytes, strips non-alphanumeric characters, whitelists valid modes. Outputs colored badge string for Claude Code statusline:
108- `balanced` or empty → `[unslop]` (green)
109- Anything else → `[unslop:<MODE_UPPERCASED>]` (green)
110 
111PowerShell counterpart at `hooks/unslop-statusline.ps1` for Windows.
112 
113### Hook installation
114 
115**Plugin install** — hooks wired automatically by plugin system.
116 
117**Standalone install** — `hooks/install.sh` (macOS/Linux) or `hooks/install.ps1` (Windows) copies hook files into `$CLAUDE_CONFIG_DIR/hooks/` and patches `settings.json` to register SessionStart and UserPromptSubmit hooks plus statusline. Supports `--force` for reinstall, checks idempotency, backs up settings.json.
118 
119**Uninstall** — `hooks/uninstall.sh` / `hooks/uninstall.ps1` removes hook files and patches settings.json.
120 
121**Hook safety rules:**
122 
123- Hooks must never break the session. Catch all errors; silent-fail on filesystem errors.
124- Hooks must be fast (<200ms). No network calls. No reading large files.
125- Hooks must work on first install with no config. Config is opt-in.
126- Any new flag file write must go through `safeWriteFlag()` in `unslop-config.js`. Direct `fs.writeFileSync` on predictable user-owned paths reopens the symlink-clobber attack surface.
127- Hooks must respect `CLAUDE_CONFIG_DIR` env var, not hardcode `~/.claude`. Same for install/uninstall/statusline scripts.
128 
129## Skills
130 
131Markdown files with YAML frontmatter:
132 
133```yaml
134---
135name: unslop
136description: >
137 ...
138---
139```
140 
141`description` is the activation hint shown to the model. Keep it ≤200 words and include trigger phrases.
142 
143The body is the operational spec. Sections we use consistently:
144 
145- `## Persistence` — when the skill turns on/off
146- `## Rules` — what to drop, what to keep
147- `## Intensity` — modes and their effects
148- `## Auto-Clarity` — when to suspend unslop style
149- `## Boundaries` — hard limits
150 
151## unslop Python package
152 
153Lives in `unslop/scripts/`. The package is split:
154 
155- `cli.py` — argparse-style CLI (no external deps)
156- `detect.py` — file type and sensitivity detection
157- `humanize.py` — core logic (deterministic regex + LLM mode)
158- `validate.py` — preserve check (code/URL/heading) + AI-ism residual check
159- `benchmark.py` — quality benchmark across a directory of samples
160- `reasoning.py` — agent reasoning-trace stripper (`<thinking>`, `## Reasoning`). Opt-in via `--strip-reasoning`
161- `surprisal.py` — optional local-LM DivEye reading. Opt-in via `--surprisal-variance`; requires `pip install torch transformers`
162- `stylometry.py` — deterministic voice-match signal extraction (incl. DivEye proxies)
163- `style_memory.py` — persisted voice profile storage (security-hardened)
164- `structural.py` — Phase 1 structural pass
165- `soul.py` — Phase 5 soul / contraction pass
166- `detector.py` — optional AI-text detector feedback loop
167- `fetch_detectors.py` — one-shot HF weight fetcher for `detector.py`
168 
169**Add a new AI-ism**: edit `STOCK_VOCAB`, `HEDGING_OPENERS`, `SYCOPHANCY`, `PERFORMATIVE`, or `TRANSITION_TICS` in `humanize.py` AND add a corresponding pattern to `AI_ISMS` in `validate.py` so the validator catches additions. Add a test in `tests/unslop/test_humanize.py`.
170 
171**Preservation is non-negotiable.** Every regex must run inside `_protect()` placeholders or be guaranteed to match only natural-language prose. `_protect` currently covers, in order: YAML frontmatter, fenced code, indented code, tables, blockquotes, headings, markdown links, inline code, bare URLs, quoted single-word examples (`"delve"`, use/mention distinction). The `TestPreservation` suite in `test_humanize.py` is the contract; the validator in `validate.py` byte-compares each protected category between input and output and fails the run on any mutation.
172 
173**Per-paragraph em-dash cap has a list carve-out.** `_cap_em_dashes_per_paragraph` splits on blank lines, then for paragraphs that are pure lists (every non-blank line starts with `-`, `*`, `+`, or `N.`) it treats each list item as its own em-dash paragraph. Without this, a 5-bullet list where each bullet used a single em-dash would silently lose the dashes in bullets 3–5.
174 
175## Tests
176 
177```bash
178python3 -m pytest tests/unslop/
179```
180 
181The deterministic suite must pass on every change. LLM tests are opt-in via `UNSLOP_RUN_LLM_TESTS=1` (cost API credits).
182 
183## Adding a sub-skill
184 
1851. Create `skills/<name>/SKILL.md` with frontmatter + body.
1862. Create `commands/<name>.toml` if it gets a slash command.
1873. Add the skill to the host manifest only when that host requires explicit skill or command entries. Claude Code hooks currently discover the repo's `skills/` and `commands/` files without listing them in `.claude-plugin/plugin.json`.
1884. Add sync mappings in `scripts/sync-mirrors.sh`, then add trigger paths in `.github/workflows/sync.yml`.
1895. Document the skill in `skills/unslop-help/SKILL.md` (the reference card).
1906. Add a row to the README sub-skills table.
191 
192## Voice
193 
194The unslop voice we keep in our own docs: direct, specific, kind, no AI-isms. We eat our own dog food. If the README opens with "Great question!", we have failed.
195 
196## Security
197 
198- The Python scripts refuse sensitive paths (`.env*`, `*.pem`, `~/.ssh/`, etc.) before any read or API call.
199- LLM mode optionally subprocesses the `claude` CLI when no `ANTHROPIC_API_KEY` is set. `subprocess.run` is always called with `shell=False` and a fixed argument list.
200- File size cap: 500 KB. See `unslop/scripts/detect.py`.
201- See `unslop/SECURITY.md` for the full Snyk rationale.
202 
@@ −1 +1 @@
1−# Agent Instructions — unslop repo
1+# Unslop — Maintainer Guide
22  
3−Drop AI-isms. Keep the technical substance exact. Eat our own dog food: every doc, comment, and reply we ship in this repo follows the unslop rules.
3+This file is for agents and maintainers working on the unslop plugin itself. End-user docs live in [`README.md`](./README.md).
44  
5−## Workflow
5+## README is a product artifact
66  
7−1. Read [`CLAUDE.md`](./CLAUDE.md) for the full maintainer guide.
8−2. Edit only the SSOT files. Mirrors are auto-generated by CI.
9−3. Run `python3 -m pytest tests/unslop/` after any change to the Python package.
10−4. Run `bash hooks/install.sh` after editing any hook script and verify the `.unslop-active` flag updates correctly with `/unslop full` and `stop unslop`.
7+The README is the product front door. Non-technical people read it to decide whether unslop is worth installing. Treat it like UI copy, not internal docs.
118  
12−## Tone
9+**Rules for any README change:**
1310  
14−- No "Great question!" openers. No "I'd be happy to help."
15−- No "delve", "tapestry", "testament", "leverage" (as filler), "robust" (as filler), "seamless", "holistic", "comprehensive" (as filler).
16−- No "It's important to note that". No "Generally speaking". No "In essence".
17−- No five-paragraph essay shape in commit messages or PR descriptions.
18−- Burstiness: short. Then one longer sentence that develops the point. Short again.
19−- Real uncertainty is fine ("I think", "probably") when honest. Performative softening isn't.
11+- Readable by non-AI-agent users. If you write "SessionStart hook injects system context", that phrase is invisible to most readers — translate it ("loads the unslop rules every time you open Claude Code").
12+- Keep the **Before / After** examples first. That is the pitch. Cutting them or burying them under prose breaks the conversion path.
13+- Install table must stay accurate. One broken install command costs a real user. Re-test every command in the install table on every PR that touches install scripts, plugin manifests, or hook paths.
14+- The "What unslop does" feature list must sync with the actual code. If a rule ships or gets removed in `unslop/scripts/humanize.py`, update the README in the same PR.
15+- Preserve voice. The README's terse, no-AI-ism style is intentional — it is unslop eating its own dog food. If you find a stock phrase ("comprehensive solution", "leverages cutting-edge"), a sycophancy opener ("Great question!"), or a hedging stack ("It's important to note that"), fix it in the same commit.
16+- Benchmark numbers come from real runs in `benchmarks/` and `evals/`. Never invent or round. Re-run the suite if you doubt a number you're about to print.
17+- Adding a new IDE/agent integration to the install table: also add a per-agent detail block in the appropriate `<details>` section so the table itself stays scannable.
18+- Readability check before any README commit: would a non-programmer understand the value prop and complete the install within 60 seconds? If not, simplify or move detail into `GETTING_STARTED.md`.
2019  
21−## Commits
20+## What this repo is
2221  
23−Use `unslop-commit` style (Conventional Commits, body only when "why" isn't obvious from subject). See `skills/unslop-commit/SKILL.md`.
22+A multi-platform plugin that makes assistant output sound human. Single source of truth (SSOT) files are synced to mirrored locations (Cursor, Windsurf, Codex bundle, etc.) by `scripts/sync-mirrors.sh` on push via `.github/workflows/sync.yml`.
2423  
25−## Reviews
24+## Source of Truth
2625  
27−Use `unslop-review` style (file:line, severity prefix, observation, fix). See `skills/unslop-review/SKILL.md`.
26+Three files are authoritative. Every other location with the same name is a mirror, generated by `scripts/sync-mirrors.sh` (run by `.github/workflows/sync.yml`). **Edit the SSOT only.**
2827  
29−## Tests are the contract
28+| Concern | SSOT |
29+|---------|------|
30+| Main unslop skill | `skills/unslop/SKILL.md` |
31+| Always-on activation rule | `rules/unslop-activate.md` |
32+| File-rewriter skill | `unslop/SKILL.md` |
3033  
31−The `TestPreservation` suite enforces that humanization never modifies code, URLs, or headings. Don't disable it. If a test fails, the unslop is wrong, not the test.
34+Sub-skills (`unslop-commit`, `unslop-review`, `unslop-help`) are also authoritative under `skills/<name>/SKILL.md`.
3235  
33−## Relationship to CLAUDE.md
36+## Mirrored locations (do NOT edit by hand)
3437  
35−This file is the short cross-IDE companion to `CLAUDE.md`. Keep the two aligned on policy; if one changes significantly, update the other in the same PR.
38+- `unslop/SKILL.md` (top-level)
39+- `plugins/unslop/skills/unslop/SKILL.md`
40+- `.cursor/skills/unslop/SKILL.md`
41+- `.windsurf/skills/unslop/SKILL.md`
42+- `.cursor/rules/unslop.mdc`
43+- `.windsurf/rules/unslop.md`
44+- `.clinerules/unslop.md`
45+- `.github/copilot-instructions.md`
46+- `skills/unslop-file/SKILL.md`
47+- `skills/unslop-file/scripts/**`
48+- `plugins/unslop/skills/unslop-file/SKILL.md`
49+- `plugins/unslop/skills/unslop-file/scripts/**`
50+ 
51+The sync workflow handles all of these. If you edit a mirror, the next sync silently overwrites your change.
52+ 
53+## Hooks
54+ 
55+Four hook files live in `hooks/` plus a `unslop-config.js` shared module and a `package.json` CommonJS marker. Communicate via flag file at `$CLAUDE_CONFIG_DIR/.unslop-active` (falls back to `~/.claude/.unslop-active`).
56+ 
57+```
58+SessionStart hook ──writes mode──▶ $CLAUDE_CONFIG_DIR/.unslop-active ◀──writes mode── UserPromptSubmit hook
59+ │
60+ reads
61+ ▼
62+ unslop-statusline.sh
63+ [unslop] / [unslop:FULL] / ...
64+```
65+ 
66+`hooks/package.json` pins the directory to `{"type": "commonjs"}` so the `.js` hooks resolve as CJS even when an ancestor `package.json` (e.g. `~/.claude/package.json` from another plugin) declares `"type": "module"`. Without this, `require()` blows up with `ReferenceError: require is not defined in ES module scope`.
67+ 
68+All hooks honor `CLAUDE_CONFIG_DIR` for non-default Claude Code config locations.
69+ 
70+### `hooks/unslop-config.js` — shared module
71+ 
72+Exports:
73+- `getDefaultMode()` — resolves default mode from `UNSLOP_DEFAULT_MODE` env var, then `$XDG_CONFIG_HOME/unslop/config.json` / `~/.config/unslop/config.json` / `%APPDATA%\unslop\config.json`, then `'balanced'`
74+- `safeWriteFlag(flagPath, content)` — symlink-safe flag write. Refuses if flag target or its immediate parent is a symlink. Opens with `O_NOFOLLOW` where supported. Atomic temp + rename. Creates with `0600`. Protects against local attackers replacing the predictable flag path with a symlink to clobber files writable by the user. Used by both write hooks. Silent-fails on all filesystem errors.
75+- `readFlag(flagPath)` — symlink-safe, size-capped (64 bytes), whitelist-validated flag read. Returns null on any anomaly. Used by mode tracker's per-turn reinforcement to avoid injecting untrusted bytes into model context.
76+- `getFlagPath()` — resolves `$CLAUDE_CONFIG_DIR/.unslop-active`.
77+ 
78+### `hooks/unslop-activate.js` — SessionStart hook
79+ 
80+Runs once per Claude Code session start. Three things:
81+1. Writes the active mode to `$CLAUDE_CONFIG_DIR/.unslop-active` via `safeWriteFlag` (creates if missing)
82+2. Emits unslop ruleset as hidden stdout — reads `skills/unslop/SKILL.md` at runtime, falls back to `rules/unslop-activate.md`, then to hardcoded rules
83+3. Checks `settings.json` for statusline config; if missing, appends nudge to offer setup on first interaction
84+ 
85+Silent-fails on all filesystem errors — never blocks session start.
86+ 
87+### `hooks/unslop-mode-tracker.js` — UserPromptSubmit hook
88+ 
89+Reads JSON from stdin. Three responsibilities:
90+ 
91+**1. Slash-command activation.** If prompt starts with `/unslop`, writes mode to flag file via `safeWriteFlag`:
92+- `/unslop` → configured default (see `unslop-config.js`, defaults to `balanced`)
93+- `/unslop subtle` → `subtle`
94+- `/unslop balanced` → `balanced`
95+- `/unslop full` → `full`
96+- `/unslop voice-match` → `voice-match`
97+- `/unslop anti-detector` → `anti-detector`
98+- `/unslop-commit` → `commit`
99+- `/unslop-review` → `review`
100+ 
101+**2. Natural-language activation/deactivation.** Matches phrases like "activate unslop", "turn on unslop mode", "humanize this", "make this sound human" and writes the configured default mode. Matches "stop unslop", "disable unslop", "normal mode", "robotic mode" and deletes the flag file.
102+ 
103+**3. Per-turn reinforcement.** When flag is set to a non-independent mode (i.e. not `commit`/`review`), emits a small `hookSpecificOutput` JSON reminder so the model keeps unslop style after other plugins inject competing instructions mid-conversation. The full ruleset comes from SessionStart — this is an attention anchor.
104+ 
105+### `hooks/unslop-statusline.sh` — Statusline badge
106+ 
107+Reads flag file at `$CLAUDE_CONFIG_DIR/.unslop-active`. Security hardened: refuses symlinks, caps read at 64 bytes, strips non-alphanumeric characters, whitelists valid modes. Outputs colored badge string for Claude Code statusline:
108+- `balanced` or empty → `[unslop]` (green)
109+- Anything else → `[unslop:<MODE_UPPERCASED>]` (green)
110+ 
111+PowerShell counterpart at `hooks/unslop-statusline.ps1` for Windows.
112+ 
113+### Hook installation
114+ 
115+**Plugin install** — hooks wired automatically by plugin system.
116+ 
117+**Standalone install** — `hooks/install.sh` (macOS/Linux) or `hooks/install.ps1` (Windows) copies hook files into `$CLAUDE_CONFIG_DIR/hooks/` and patches `settings.json` to register SessionStart and UserPromptSubmit hooks plus statusline. Supports `--force` for reinstall, checks idempotency, backs up settings.json.
118+ 
119+**Uninstall** — `hooks/uninstall.sh` / `hooks/uninstall.ps1` removes hook files and patches settings.json.
120+ 
121+**Hook safety rules:**
122+ 
123+- Hooks must never break the session. Catch all errors; silent-fail on filesystem errors.
124+- Hooks must be fast (<200ms). No network calls. No reading large files.
125+- Hooks must work on first install with no config. Config is opt-in.
126+- Any new flag file write must go through `safeWriteFlag()` in `unslop-config.js`. Direct `fs.writeFileSync` on predictable user-owned paths reopens the symlink-clobber attack surface.
127+- Hooks must respect `CLAUDE_CONFIG_DIR` env var, not hardcode `~/.claude`. Same for install/uninstall/statusline scripts.
128+ 
129+## Skills
130+ 
131+Markdown files with YAML frontmatter:
132+ 
133+```yaml
134+---
135+name: unslop
136+description: >
137+ ...
138+---
139+```
140+ 
141+`description` is the activation hint shown to the model. Keep it ≤200 words and include trigger phrases.
142+ 
143+The body is the operational spec. Sections we use consistently:
144+ 
145+- `## Persistence` — when the skill turns on/off
146+- `## Rules` — what to drop, what to keep
147+- `## Intensity` — modes and their effects
148+- `## Auto-Clarity` — when to suspend unslop style
149+- `## Boundaries` — hard limits
150+ 
151+## unslop Python package
152+ 
153+Lives in `unslop/scripts/`. The package is split:
154+ 
155+- `cli.py` — argparse-style CLI (no external deps)
156+- `detect.py` — file type and sensitivity detection
157+- `humanize.py` — core logic (deterministic regex + LLM mode)
158+- `validate.py` — preserve check (code/URL/heading) + AI-ism residual check
159+- `benchmark.py` — quality benchmark across a directory of samples
160+- `reasoning.py` — agent reasoning-trace stripper (`<thinking>`, `## Reasoning`). Opt-in via `--strip-reasoning`
161+- `surprisal.py` — optional local-LM DivEye reading. Opt-in via `--surprisal-variance`; requires `pip install torch transformers`
162+- `stylometry.py` — deterministic voice-match signal extraction (incl. DivEye proxies)
163+- `style_memory.py` — persisted voice profile storage (security-hardened)
164+- `structural.py` — Phase 1 structural pass
165+- `soul.py` — Phase 5 soul / contraction pass
166+- `detector.py` — optional AI-text detector feedback loop
167+- `fetch_detectors.py` — one-shot HF weight fetcher for `detector.py`
168+ 
169+**Add a new AI-ism**: edit `STOCK_VOCAB`, `HEDGING_OPENERS`, `SYCOPHANCY`, `PERFORMATIVE`, or `TRANSITION_TICS` in `humanize.py` AND add a corresponding pattern to `AI_ISMS` in `validate.py` so the validator catches additions. Add a test in `tests/unslop/test_humanize.py`.
170+ 
171+**Preservation is non-negotiable.** Every regex must run inside `_protect()` placeholders or be guaranteed to match only natural-language prose. `_protect` currently covers, in order: YAML frontmatter, fenced code, indented code, tables, blockquotes, headings, markdown links, inline code, bare URLs, quoted single-word examples (`"delve"`, use/mention distinction). The `TestPreservation` suite in `test_humanize.py` is the contract; the validator in `validate.py` byte-compares each protected category between input and output and fails the run on any mutation.
172+ 
173+**Per-paragraph em-dash cap has a list carve-out.** `_cap_em_dashes_per_paragraph` splits on blank lines, then for paragraphs that are pure lists (every non-blank line starts with `-`, `*`, `+`, or `N.`) it treats each list item as its own em-dash paragraph. Without this, a 5-bullet list where each bullet used a single em-dash would silently lose the dashes in bullets 3–5.
174+ 
175+## Tests
176+ 
177+```bash
178+python3 -m pytest tests/unslop/
179+```
180+ 
181+The deterministic suite must pass on every change. LLM tests are opt-in via `UNSLOP_RUN_LLM_TESTS=1` (cost API credits).
182+ 
183+## Adding a sub-skill
184+ 
185+1. Create `skills/<name>/SKILL.md` with frontmatter + body.
186+2. Create `commands/<name>.toml` if it gets a slash command.
187+3. Add the skill to the host manifest only when that host requires explicit skill or command entries. Claude Code hooks currently discover the repo's `skills/` and `commands/` files without listing them in `.claude-plugin/plugin.json`.
188+4. Add sync mappings in `scripts/sync-mirrors.sh`, then add trigger paths in `.github/workflows/sync.yml`.
189+5. Document the skill in `skills/unslop-help/SKILL.md` (the reference card).
190+6. Add a row to the README sub-skills table.
191+ 
192+## Voice
193+ 
194+The unslop voice we keep in our own docs: direct, specific, kind, no AI-isms. We eat our own dog food. If the README opens with "Great question!", we have failed.
195+ 
196+## Security
197+ 
198+- The Python scripts refuse sensitive paths (`.env*`, `*.pem`, `~/.ssh/`, etc.) before any read or API call.
199+- LLM mode optionally subprocesses the `claude` CLI when no `ANTHROPIC_API_KEY` is set. `subprocess.run` is always called with `shell=False` and a fixed argument list.
200+- File size cap: 500 KB. See `unslop/scripts/detect.py`.
201+- See `unslop/SECURITY.md` for the full Snyk rationale.
36202  
RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack