npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

copydesk

v0.9.5

Published

A cross-harness prose gate for AI agents

Readme

CopyDesk

npm.

test.

license: MIT.

python: 3.9+.

status: pre-1.0.

A prose gate and style system for AI coding agents.

It prevents violations before generation, and refuses the write when a violation slips through.

Every other prose tool reads your text after it is saved. CopyDesk works in three earlier moments: it compiles instructions into the model context before generation, it intercepts file edits to refuse violations at write time, and a pre-commit hook refuses a commit whose added Markdown breaks the rules.

| When | What happens | Who is there | |---|---|---| | Before generation | Instructions enter the model context, so bad prose is never produced | CopyDesk | | At write time | The write is refused and the model revises | CopyDesk | | Before the commit | The commit is refused when its added Markdown breaks the rules | CopyDesk | | After the file is saved | The file is scored and a fix requested | sloptrim | | In continuous integration | The build reports or fails | Vale |


What it looks like

1. Prevention (before generation)

CopyDesk generates tuned output styles and instruction blocks for your agents. The model knows your style, verbosity, and constraints before writing a single token.

Answer first, then support it.
Give the answer and one line of support.
Cut any sentence that does not change what the reader knows or does.

2. Remediation (at write time)

When an agent ignores instructions during a file write, the gate refuses the operation. The agent revises immediately.

The gate blocks on new findings in the edited region, not on pre-existing errors in the file. It tells the model not to touch surrounding code or text.

You can also run CopyDesk as a standalone CLI linter:

$ copydesk check release-notes.md
release-notes.md:
3:announcing-opener:Great question — let me walk you through it. This release delivers a solid and
3:sentence-length:This release delivers a solid and significant overhaul of the export pipeline…
8:idiom:That said, we should circle back on the remaining items. As noted above, the
8:orphan-pointer:That said, we should circle back on the remaining items. As noted above, the
9:soft-offer:former approach is deprecated. Happy to walk through any of this if you'd like.

Why this exists

AI coding agents produce four channels of prose: terminal chat, Markdown documentation, commit messages, and code review comments.

Most unguided agent writing shares four flaws. Sentences stretch past forty words. Openers announce what is coming instead of answering. Chat repeats answered decisions turn after turn.

Post-hoc linters catch these issues in CI or after saving. That costs a full retry round trip or reviewer attention.

Measured across 1.5 million words of real transcripts, terminal chat shows 9.14 blocking violations per 1,000 words against 5.42 in documents. Chat never becomes a saved file, so a post-hoc file linter cannot inspect it. Prevention through compiled context instructions is the only way to reach chat.

Contents

Install

npm install -g copydesk

Or run directly without global installation:

npx copydesk check README.md

Or clone from source:

git clone https://github.com/carlosboeing/copydesk.git
cd copydesk
./install.sh

CopyDesk requires Python 3.9 or later and has zero third-party dependencies.

Quickstart: Setup Wizard

Run the interactive wizard to configure styles, channels, and hooks:

copydesk setup

The wizard guides you through three choices:

  1. Preset style and verbosity for each channel.
  2. Connected harnesses and tools.
  3. Configuration review and proof run.

You can also run unattended with defaults:

copydesk setup --defaults --yes

To check your installation and effective rules:

copydesk doctor

To remove all CopyDesk hooks and configurations:

copydesk uninstall

Managing the commit-msg hook

copydesk setup installs the commit-msg hook into the repository you run it from. The hook subcommand manages it across every repository:

copydesk hook add                 # install into the current repository
copydesk hook add ~/projects/foo  # or a named one
copydesk hook add --scan ~/src    # offer every repository one level under ~/src
copydesk hook list                # every recorded repository and its state
copydesk hook remove --all        # remove them all

A repository whose commit-msg hook already exists is never overwritten: hook add offers to append CopyDesk's block instead, and verifies by a test run that the block is reached. Every install is recorded in $XDG_STATE_HOME/copydesk/hooks.json, so uninstall can offer to remove the hooks in your other repositories too.

Managing the pre-commit hook

The commit-msg gate checks message prose. The pre-commit gate checks the Markdown a commit adds:

copydesk install --git-hook

The hook runs copydesk check --staged before every commit. It judges the lines the commit adds, compared against HEAD.

Touching a clean paragraph passes no matter what else the file hides. An added banned word refuses the commit, and a deletion blocks only for a rule HEAD did not already break. Staged content is checked, so uncommitted edits in your working tree are not judged.

To commit anyway:

git commit --no-verify

The same instruction lives inside the installed hook, so it is there when you need it. Findings at warn severity print but never block, whatever your configuration says about blocking. A missing copydesk binary or an internal error lets the commit through rather than bricking the repository.

A pre-commit hook CopyDesk did not write is never overwritten: the installer prints the lines to append instead, chaining the check into your own script. Running the command again refreshes a hook CopyDesk wrote. To remove it, delete .git/hooks/pre-commit, or the file under core.hooksPath if you set one.

Channels

CopyDesk divides agent writing into four channels:

| Channel | Medium | Gate mechanism | Default style | |---|---|---|---| | chat | Terminal conversational replies | Stop hook, recording only by default | plain (low verbosity) | | documents | Markdown files on disk | PreToolUse write/edit hook | plain (high verbosity) | | commits | Git commit messages | commit-msg git hook | engineer (low verbosity) | | reviews | PR and code review markdown | Configured match file patterns | plain (medium verbosity) |

The chat gate records what a reply broke and does not refuse the reply. Claude Code appends a replacement message and leaves the refused one on screen, so a refusal shows the reader the same answer twice. To refuse instead, run copydesk set channels.chat.gate=block.

Read more in docs/channels.md.

Styles

CopyDesk ships four base styles:

| Style | Purpose | Best suited for | |---|---|---| | plain | Answer first, concise supporting facts | Day-to-day coding, technical documentation | | engineer | Terse procedures, tables, minimal prose | API references, runbooks, schemas | | editorial | Narrative explanations, flowing paragraphs | Thought leadership, blog posts | | general | Plain terms with every specialized word glossed | Onboarding guides, non-technical docs |

Read more in docs/styles.md.

Usage

Check files or standard input:

copydesk check docs/guide.md CHANGELOG.md
cat draft.md | copydesk check -
copydesk check --commit-msg .git/COMMIT_EDITMSG
copydesk check --staged            # lint what the index adds against HEAD
copydesk install --git-hook        # run that automatically before every commit

Inspect rules and resolution:

copydesk doctor                  # explain active settings and health
copydesk doctor docs/guide.md    # explain rules for a specific file
copydesk doctor --rules          # list all rules and guidance parameters

Change a chat setting quickly:

copydesk set channels.chat.verbosity=medium
copydesk set channels.chat.gate=block      # refuse a reply instead of recording it

View local gate telemetry:

copydesk stats                    # activity summary
copydesk stats --since 30d --json # JSON format
copydesk report --out report.md   # detailed markdown report

Exit codes:

| Code | Meaning | |---|---| | 0 | Clean, or warnings only | | 1 | Blocking prose findings | | 2 | Hook blocked a write | | 64 | Usage error | | 70 | Internal error (fails open for git commits) |

Configuration

Configuration is optional. By default, the plain preset applies.

CopyDesk merges configuration across three locations:

| Layer | Path | Purpose | |---|---|---| | User | ~/.config/copydesk/config.json | Personal defaults | | Project | copydesk.config.json | Repository standards | | Local | copydesk.local.json | Local overrides |

JSON with comments (JSONC) is supported.

{
  "$schema": "https://raw.githubusercontent.com/carlosboeing/copydesk/v0/copydesk.schema.json",
  "version": 1,
  "channels": {
    "chat": { "style": "plain", "verbosity": "low" },
    "documents": { "style": "engineer" }
  },
  "paths": {
    "ignore": [".workbench/**", "drafts/**"],
    "warn": ["CHANGELOG.md"]
  },
  "rules": {
    "sentence-length": { "severity": "warn", "max": 30 },
    "banned-word": { "add": ["synergy"], "remove": ["solid"] },
    "unglossed-term": { "add": ["React", "Postgres"] }
  }
}

Full details are in docs/configuration.md.

Rules

15 rules across three groups:

| Group | Rules | |---|---| | Pattern | banned-word, idiom, soft-offer, announcing-opener, contrast-construction, orphan-pointer, verb-jargon | | Metric | sentence-length, paragraph-length, avg-sentence-length, long-sentence-rate, sentence-variation, list-dominated, unglossed-term | | Structural | nested-table |

Every rule and parameter is documented in docs/rules.md.

Setting up the gate by hand

copydesk setup handles installation automatically. If you prefer manual setup for Claude Code:

  1. Copy hooks and rules:

    mkdir -p ~/.claude/hooks/copydesk/rules ~/.claude/output-styles
    cp hooks/gate.sh hooks/reminder.sh lib/linter.py ~/.claude/hooks/copydesk/
    cp rules/plain.json ~/.claude/hooks/copydesk/rules/
    chmod +x ~/.claude/hooks/copydesk/gate.sh ~/.claude/hooks/copydesk/reminder.sh
  2. Register in ~/.claude/settings.json:

    {
      "hooks": {
        "PreToolUse": [
          {
            "matcher": "Write|Edit",
            "hooks": [{ "type": "command", "command": "~/.claude/hooks/copydesk/gate.sh" }]
          }
        ],
        "UserPromptSubmit": [
          {
            "hooks": [{ "type": "command", "command": "~/.claude/hooks/copydesk/reminder.sh" }]
          }
        ]
      }
    }
  3. Run copydesk doctor to verify registration.

How it compares

| When | What happens | Who is there | |---|---|---| | Before generation | Instructions enter the model context | CopyDesk | | At write time | The write is refused | CopyDesk | | Before the commit | The commit is refused when its added Markdown breaks the rules | CopyDesk | | After the file is saved | The file is scored | sloptrim | | In continuous integration | The build reports or fails | Vale |

Where CopyDesk differs:

| Tool | Differences | |---|---| | Vale | Markup-aware parsing, official style packages, and editor integrations. | | sloptrim | Supports 20+ document formats and calculates holistic scores. | | CopyDesk | Real-time latency with zero runtime dependencies and fail-open guarantees. |

Evidence

  • Observational baseline: Analysis across 1,556,107 words of chat and 626,153 words of Markdown.
  • Prevention baseline: The corpus blocking rate and the per-rule false-positive rates. copydesk report names this page as the source of its Prevention section.
  • Gate baseline: Multi-turn session evaluations from 2026-08-17, tracking rule enforcement and instruction decay over time. The prevention baseline re-measures the same transcripts.

Project status

0.9.5, pre-1.0. The CLI commands, config schema, rule identifiers, and channel definitions are stable.

See docs/ROADMAP.md for future plans and CHANGELOG.md for release history.

Contributing

See CONTRIBUTING.md for test execution and contribution guidelines.

Support

Use SUPPORT.md for usage questions, bug reports, and feature requests. The issue tracker is the public place for questions and reports.

Security

CopyDesk runs locally and makes no outbound network connections. Document contents never leave your machine. See SECURITY.md for private vulnerability reports.

Licence and credits

MIT. See LICENSE. Notices for adapted third-party code are in THIRD_PARTY_NOTICES.md.

lib/linter.py is adapted from AminBlg/SimpleEnglish (MIT).