{"_id":"@aggc/no-coauthor","_rev":"14-218883178dedf8202f5567db20f663ce","name":"@aggc/no-coauthor","dist-tags":{"latest":"2.5.0"},"versions":{"1.1.0":{"name":"@aggc/no-coauthor","version":"1.1.0","keywords":["git","hooks","commit-msg","commit","co-author","co-authored-by","ai","claude","claude-code","copilot","codex","gpt","chatgpt","gemini","cursor","devin"],"author":{"name":"0xdsgnrd"},"license":"MIT","_id":"@aggc/no-coauthor@1.1.0","maintainers":[{"name":"aggc","email":"dev@aggc.dev"}],"contributors":[{"name":"jmtrs"}],"homepage":"https://github.com/jmtrs/no-coAuthor#readme","bugs":{"url":"https://github.com/jmtrs/no-coAuthor/issues"},"bin":{"no-coauthor":"bin/no-coauthor.js"},"dist":{"shasum":"0fc0e8018ea8b0f5c2e5bddd0aea55933ab963c6","tarball":"https://registry.npmjs.org/@aggc/no-coauthor/-/no-coauthor-1.1.0.tgz","fileCount":11,"integrity":"sha512-JPIMItPAOrVcrSzTJG6WKOfTq+/KtDtvg71MiU4/fC+K8IDTI73dF+08p+7Mro41pZZNiEbW6ihQWjEeNLh8KQ==","signatures":[{"sig":"MEQCIDf5KogJU9hduFIudDCa9j/XBEN6dCM5TdEsWCADpoYvAiA/ibW8pzccpYI6rjSUTZUiTPq0hDR8cehvGvdegSmPMw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":43319},"engines":{"node":">=18"},"gitHead":"6b8eb124c7bb35a386eea4d5652818ae997754b7","scripts":{"test":"node --test test/*.test.js","release":"changeset publish","changeset":"changeset","version-packages":"changeset version"},"_npmUser":{"name":"aggc","email":"dev@aggc.dev"},"repository":{"url":"git+https://github.com/jmtrs/no-coAuthor.git","type":"git"},"_npmVersion":"11.12.1","description":"Git hook that strips AI co-author trailers (Claude, Copilot, Codex, Cursor, Oz/Warp, GPT, Gemini, Devin, etc.) from commit messages while preserving human co-authors","directories":{},"_nodeVersion":"26.0.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@changesets/cli":"^2.31.0","@changesets/changelog-github":"^0.7.0"},"_npmOperationalInternal":{"tmp":"tmp/no-coauthor_1.1.0_1783933924846_0.12011029565626563","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@aggc/no-coauthor","version":"1.2.0","keywords":["git","hooks","commit-msg","commit","co-author","co-authored-by","ai","claude","claude-code","copilot","codex","gpt","chatgpt","gemini","cursor","devin"],"author":{"name":"0xdsgnrd"},"license":"MIT","_id":"@aggc/no-coauthor@1.2.0","maintainers":[{"name":"aggc","email":"dev@aggc.dev"}],"contributors":[{"name":"jmtrs"}],"homepage":"https://github.com/jmtrs/no-coAuthor#readme","bugs":{"url":"https://github.com/jmtrs/no-coAuthor/issues"},"bin":{"no-coauthor":"bin/no-coauthor.js"},"dist":{"shasum":"a7edeae260be877dfffdd329b25ddf7417539ed5","tarball":"https://registry.npmjs.org/@aggc/no-coauthor/-/no-coauthor-1.2.0.tgz","fileCount":11,"integrity":"sha512-kJmKKP1vLftiRl5mRpqdreaLFWsgsN1i7go+0sdF4WGcx8y1q68+kd2Ux/KDKus1Pm9/K/yTEdTtWGNveR3Rug==","signatures":[{"sig":"MEUCIQD6DxkMUtLsWK1omC9zwDQsqWjnBo6uAr5vUxGUqZIZDwIgbqwP2BtRRK31s9ZjwVVtYdDc+H0rTCHVcpLdL/0fqWg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aggc%2fno-coauthor@1.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":43304},"engines":{"node":">=18"},"gitHead":"eb1057dccbcd2a99b87d58cabbe450c6776956c2","scripts":{"test":"node --test","release":"changeset publish","changeset":"changeset","version-packages":"changeset version"},"_npmUser":{"name":"aggc","email":"dev@aggc.dev"},"repository":{"url":"git+https://github.com/jmtrs/no-coAuthor.git","type":"git"},"_npmVersion":"10.8.2","description":"Git hook that strips AI co-author trailers (Claude, Copilot, Codex, Cursor, Oz/Warp, GPT, Gemini, Devin, etc.) from commit messages while preserving human co-authors","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@changesets/cli":"^2.31.0","@changesets/changelog-github":"^0.7.0"},"_npmOperationalInternal":{"tmp":"tmp/no-coauthor_1.2.0_1783934695896_0.7826777460190457","host":"s3://npm-registry-packages-npm-production"}},"1.2.1":{"name":"@aggc/no-coauthor","version":"1.2.1","keywords":["git","hooks","commit-msg","commit","co-author","co-authored-by","ai","claude","claude-code","copilot","codex","gpt","chatgpt","gemini","cursor","devin"],"author":{"name":"0xdsgnrd"},"license":"MIT","_id":"@aggc/no-coauthor@1.2.1","maintainers":[{"name":"aggc","email":"dev@aggc.dev"}],"contributors":[{"name":"jmtrs"}],"homepage":"https://github.com/jmtrs/no-coAuthor#readme","bugs":{"url":"https://github.com/jmtrs/no-coAuthor/issues"},"bin":{"no-coauthor":"bin/no-coauthor.js"},"dist":{"shasum":"b30a63c17bd9f32d62df5ba3732852546c2ce16b","tarball":"https://registry.npmjs.org/@aggc/no-coauthor/-/no-coauthor-1.2.1.tgz","fileCount":12,"integrity":"sha512-Fiu1rIp2IC/2L2Ma/M9xPk/6tGIJgGWjvBnE6PeBwY4Pp2H//GfEziGuz++oxNuQl8KpMcCyGFWcvXfCwcLIHw==","signatures":[{"sig":"MEUCIHKCGaNKMEOQhPHLvrxaycOsyFJi8h83pXGl1Mc8FkXUAiEAtBg5/vs2RhY33H/Q66+d8Hyi067sTgYxcomp67Ocggs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aggc%2fno-coauthor@1.2.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":44388},"engines":{"node":">=18"},"gitHead":"c7fd20f07b9a5324582a4df09c87bf2d6e90232a","scripts":{"test":"node --test","release":"changeset publish","changeset":"changeset","prepublishOnly":"npm test","version-packages":"changeset version"},"_npmUser":{"name":"aggc","email":"dev@aggc.dev"},"repository":{"url":"git+https://github.com/jmtrs/no-coAuthor.git","type":"git"},"_npmVersion":"10.8.2","description":"Git hook that strips AI co-author trailers (Claude, Copilot, Codex, Cursor, Oz/Warp, GPT, Gemini, Devin, etc.) from commit messages while preserving human co-authors","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@changesets/cli":"^2.31.0","@changesets/changelog-github":"^0.7.0"},"_npmOperationalInternal":{"tmp":"tmp/no-coauthor_1.2.1_1783935251263_0.13526936002842982","host":"s3://npm-registry-packages-npm-production"}},"1.3.0":{"name":"@aggc/no-coauthor","version":"1.3.0","keywords":["git","hooks","commit-msg","commit","co-author","co-authored-by","ai","claude","claude-code","copilot","codex","gpt","chatgpt","gemini","cursor","devin"],"author":{"name":"0xdsgnrd"},"license":"MIT","_id":"@aggc/no-coauthor@1.3.0","maintainers":[{"name":"aggc","email":"dev@aggc.dev"}],"contributors":[{"name":"jmtrs"}],"homepage":"https://github.com/jmtrs/no-coAuthor#readme","bugs":{"url":"https://github.com/jmtrs/no-coAuthor/issues"},"bin":{"no-coauthor":"bin/no-coauthor.js"},"dist":{"shasum":"c5bad8e849639c4681b5584b11fd8533b2f3b26c","tarball":"https://registry.npmjs.org/@aggc/no-coauthor/-/no-coauthor-1.3.0.tgz","fileCount":13,"integrity":"sha512-lq2adXFvI8gy0FHTn1gXFJYsT1+ikKExy3skEpvRc3WAsrQHHxZZM6CxbsOSZ7DXCuSlPqBSTgWSUd8xh4CC4Q==","signatures":[{"sig":"MEYCIQD7wBLtPztyGsb94q0kbN8vwb6vvVMIUhEQu3NUz3OBVAIhAK4X0NrFY0lNCbfB/U+LmJGMNUAUJDFtthH9KYqv8WVD","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aggc%2fno-coauthor@1.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":55689},"engines":{"node":">=18"},"gitHead":"512ab54562a7be0a1b92247662613f5fb18f6c25","scripts":{"test":"node --test","release":"changeset publish","changeset":"changeset","prepublishOnly":"npm test","sync-install-sh":"node scripts/sync-install-sh.js","version-packages":"changeset version"},"_npmUser":{"name":"aggc","email":"dev@aggc.dev"},"repository":{"url":"git+https://github.com/jmtrs/no-coAuthor.git","type":"git"},"_npmVersion":"10.8.2","description":"Git hook that strips AI co-author trailers (Claude, Copilot, Codex, Cursor, Oz/Warp, GPT, Gemini, Devin, etc.) from commit messages while preserving human co-authors","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@changesets/cli":"^2.31.0","@changesets/changelog-github":"^0.7.0"},"_npmOperationalInternal":{"tmp":"tmp/no-coauthor_1.3.0_1783938220909_0.5849428770016654","host":"s3://npm-registry-packages-npm-production"}},"1.3.1":{"name":"@aggc/no-coauthor","version":"1.3.1","keywords":["git","hooks","commit-msg","commit","co-author","co-authored-by","ai","claude","claude-code","copilot","codex","gpt","chatgpt","gemini","cursor","devin"],"author":{"name":"0xdsgnrd"},"license":"MIT","_id":"@aggc/no-coauthor@1.3.1","maintainers":[{"name":"aggc","email":"dev@aggc.dev"}],"contributors":[{"name":"jmtrs"}],"homepage":"https://github.com/jmtrs/no-coAuthor#readme","bugs":{"url":"https://github.com/jmtrs/no-coAuthor/issues"},"bin":{"no-coauthor":"bin/no-coauthor.js"},"dist":{"shasum":"1cf00bec0ac3ffc98edae33606537bb3169fbe4b","tarball":"https://registry.npmjs.org/@aggc/no-coauthor/-/no-coauthor-1.3.1.tgz","fileCount":13,"integrity":"sha512-8jdlskCon2+TI2xi2jJ4JIOxsqpSuyP2Yse0jIFOloCVCTPUA6tjmHcMhdfFH3SE3nvwqAw3fC/LzE+XhfiwRw==","signatures":[{"sig":"MEQCIDhGOKesqQK7jl7BDSS8BrqsUqoKa8jMPXt8H4NAJ007AiA8w0t9gBdCbOu4txhmVxlZbzsOaZq9pJNBRRAcTTuIjw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aggc%2fno-coauthor@1.3.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":57183},"engines":{"node":">=18"},"gitHead":"bb7dfb873f3919282b6ef22db7f96132757280e7","scripts":{"test":"node --test","release":"changeset publish","changeset":"changeset","prepublishOnly":"npm test","sync-install-sh":"node scripts/sync-install-sh.js","version-packages":"changeset version"},"_npmUser":{"name":"aggc","email":"dev@aggc.dev"},"repository":{"url":"git+https://github.com/jmtrs/no-coAuthor.git","type":"git"},"_npmVersion":"10.8.2","description":"Git hook that strips AI co-author trailers (Claude, Copilot, Codex, Cursor, Oz/Warp, GPT, Gemini, Devin, etc.) from commit messages while preserving human co-authors","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@changesets/cli":"^2.31.0","@changesets/changelog-github":"^0.7.0"},"_npmOperationalInternal":{"tmp":"tmp/no-coauthor_1.3.1_1783938666216_0.5136899914161783","host":"s3://npm-registry-packages-npm-production"}},"1.4.0":{"name":"@aggc/no-coauthor","version":"1.4.0","keywords":["git","hooks","commit-msg","commit","co-author","co-authored-by","ai","claude","claude-code","copilot","codex","gpt","chatgpt","gemini","cursor","devin"],"author":{"name":"0xdsgnrd"},"license":"MIT","_id":"@aggc/no-coauthor@1.4.0","maintainers":[{"name":"aggc","email":"dev@aggc.dev"}],"contributors":[{"name":"jmtrs"}],"homepage":"https://github.com/jmtrs/no-coAuthor#readme","bugs":{"url":"https://github.com/jmtrs/no-coAuthor/issues"},"bin":{"no-coauthor":"bin/no-coauthor.js"},"dist":{"shasum":"817b1a865e9a09c8b2511b7bbc956180cbd1402d","tarball":"https://registry.npmjs.org/@aggc/no-coauthor/-/no-coauthor-1.4.0.tgz","fileCount":13,"integrity":"sha512-K5HfZjo9Rv92DNk4R4cOi22Xlex9cwNhYHAX0Q9kOk1FT5Z94UxICheLz+NWZ2+OqsfEnIcaUmz1pmlSu6Gzhw==","signatures":[{"sig":"MEQCIAyg0z13eB5TOH4Xpcw2asnWBi8Oy5RBkZK9c39ShgCXAiB/GgRBYbncrSkI8cRhg699o+rFASuhWhXhtbefSH2KMg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aggc%2fno-coauthor@1.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":59467},"engines":{"node":">=18"},"gitHead":"e085ace9fd13ac37f5238649783f1365988696df","scripts":{"test":"node --test","release":"changeset publish","changeset":"changeset","prepublishOnly":"npm test","sync-install-sh":"node scripts/sync-install-sh.js","version-packages":"changeset version"},"_npmUser":{"name":"aggc","email":"dev@aggc.dev"},"repository":{"url":"git+https://github.com/jmtrs/no-coAuthor.git","type":"git"},"_npmVersion":"10.8.2","description":"Git hook that strips AI co-author trailers (Claude, Copilot, Codex, Cursor, Oz/Warp, GPT, Gemini, Devin, etc.) from commit messages while preserving human co-authors","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@changesets/cli":"^2.31.0","@changesets/changelog-github":"^0.7.0"},"_npmOperationalInternal":{"tmp":"tmp/no-coauthor_1.4.0_1783939844411_0.23132079341511247","host":"s3://npm-registry-packages-npm-production"}},"1.5.0":{"name":"@aggc/no-coauthor","version":"1.5.0","keywords":["git","hooks","commit-msg","commit","co-author","co-authored-by","ai","claude","claude-code","copilot","codex","gpt","chatgpt","gemini","cursor","devin"],"author":{"name":"0xdsgnrd"},"license":"MIT","_id":"@aggc/no-coauthor@1.5.0","maintainers":[{"name":"aggc","email":"dev@aggc.dev"}],"contributors":[{"name":"jmtrs"}],"homepage":"https://github.com/jmtrs/no-coAuthor#readme","bugs":{"url":"https://github.com/jmtrs/no-coAuthor/issues"},"bin":{"no-coauthor":"bin/no-coauthor.js"},"dist":{"shasum":"b676f1b9bfc983899593dd478321af015c715b8f","tarball":"https://registry.npmjs.org/@aggc/no-coauthor/-/no-coauthor-1.5.0.tgz","fileCount":15,"integrity":"sha512-OB09ax8ESHX3gtkQV8LKHrDSkgHCBEu//m5Aq83h24jVU3T8sD9tfh4+1gl34t3gdE2KL093hNyFUsAacC8ugw==","signatures":[{"sig":"MEYCIQCJwaQrR/iFHddiLP2m+jBRWHv0+bO7Ozx9bP+hyJOFKQIhALhNoa1XgIG54Nb9etIE8+K6mfu9WR7jjdiaSY39FXCC","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aggc%2fno-coauthor@1.5.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":69847},"engines":{"node":">=18"},"gitHead":"f9886c318cb5c4d6e74068de66eddfd6bc001458","scripts":{"test":"node --test","release":"changeset publish","changeset":"changeset","prepublishOnly":"npm test","sync-install-sh":"node scripts/sync-install-sh.js","version-packages":"changeset version"},"_npmUser":{"name":"aggc","email":"dev@aggc.dev"},"repository":{"url":"git+https://github.com/jmtrs/no-coAuthor.git","type":"git"},"_npmVersion":"10.8.2","description":"Git hook that strips AI co-author trailers (Claude, Copilot, Codex, Cursor, Oz/Warp, GPT, Gemini, Devin, etc.) from commit messages while preserving human co-authors","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@changesets/cli":"^2.31.0","@changesets/changelog-github":"^0.7.0"},"_npmOperationalInternal":{"tmp":"tmp/no-coauthor_1.5.0_1783940901634_0.05552487165597375","host":"s3://npm-registry-packages-npm-production"}},"1.5.1":{"name":"@aggc/no-coauthor","version":"1.5.1","keywords":["git","hooks","commit-msg","commit","co-author","co-authored-by","ai","claude","claude-code","copilot","codex","gpt","chatgpt","gemini","cursor","devin"],"author":{"name":"0xdsgnrd"},"license":"MIT","_id":"@aggc/no-coauthor@1.5.1","maintainers":[{"name":"aggc","email":"dev@aggc.dev"}],"contributors":[{"name":"jmtrs"}],"homepage":"https://github.com/jmtrs/no-coAuthor#readme","bugs":{"url":"https://github.com/jmtrs/no-coAuthor/issues"},"bin":{"no-coauthor":"bin/no-coauthor.js"},"dist":{"shasum":"36bb36a1bc5b7491eb4182649825dd9cec800cd4","tarball":"https://registry.npmjs.org/@aggc/no-coauthor/-/no-coauthor-1.5.1.tgz","fileCount":16,"integrity":"sha512-Pu38LojB7OLjdPIuZlAGZSwmrrmFHQtawFxidXw+OVhr91SPCCMQpM30RGQes8/f6LfeWC4clsCgMANXDoUCSQ==","signatures":[{"sig":"MEQCIDJKY61k5pFnHyFMFkTnHVCEn1JZFnX+B9tylwa2Gi97AiA4jmxGXzOHDrS/NlP8eLrP0KaWge/BEna46BhfwEJexw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aggc%2fno-coauthor@1.5.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":73039},"engines":{"node":">=18"},"gitHead":"5d6ede579a5fed9d83f9a7ec867405d75319065a","scripts":{"test":"node --test","release":"changeset publish","changeset":"changeset","prepublishOnly":"npm test","sync-install-sh":"node scripts/sync-install-sh.js","version-packages":"changeset version"},"_npmUser":{"name":"aggc","email":"dev@aggc.dev"},"repository":{"url":"git+https://github.com/jmtrs/no-coAuthor.git","type":"git"},"_npmVersion":"10.8.2","description":"Git hook that strips AI co-author trailers (Claude, Copilot, Codex, Cursor, Oz/Warp, GPT, Gemini, Devin, etc.) from commit messages while preserving human co-authors","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@changesets/cli":"^2.31.0","@changesets/changelog-github":"^0.7.0"},"_npmOperationalInternal":{"tmp":"tmp/no-coauthor_1.5.1_1783943860939_0.9789466978317478","host":"s3://npm-registry-packages-npm-production"}},"2.0.0":{"name":"@aggc/no-coauthor","version":"2.0.0","keywords":["git","hooks","commit-msg","commit","co-author","co-authored-by","ai","claude","claude-code","copilot","codex","gpt","chatgpt","gemini","cursor","devin"],"author":{"name":"0xdsgnrd"},"license":"MIT","_id":"@aggc/no-coauthor@2.0.0","maintainers":[{"name":"aggc","email":"dev@aggc.dev"}],"contributors":[{"name":"jmtrs"}],"homepage":"https://github.com/jmtrs/no-coAuthor#readme","bugs":{"url":"https://github.com/jmtrs/no-coAuthor/issues"},"bin":{"no-coauthor":"bin/no-coauthor.js"},"dist":{"shasum":"74c2b3ebe8224ee52a5d4193631bae70cb5f0dcf","tarball":"https://registry.npmjs.org/@aggc/no-coauthor/-/no-coauthor-2.0.0.tgz","fileCount":16,"integrity":"sha512-PHFSXT8JGDcV5nyUvHKx3H9ykQhh8ALX53fUj0hbOQzHsZHKynIzIxP630XsrnC9nieB/2iHkN/kzKqSOhz9Kg==","signatures":[{"sig":"MEUCIQCYRuzGYai2gOKMGKTCatvIb3eqNywPKWFnYcl4atKH8QIgIOboH+DQas6kRYepAXe/JFcb+33IO5HeN3egpobZCWQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aggc%2fno-coauthor@2.0.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":81043},"engines":{"node":">=18"},"gitHead":"c77581cf3aa1adb33bd49e8c6ace05499e446bf8","scripts":{"test":"node --test","release":"changeset publish","changeset":"changeset","prepublishOnly":"npm test","sync-install-sh":"node scripts/sync-install-sh.js","version-packages":"changeset version"},"_npmUser":{"name":"aggc","email":"dev@aggc.dev"},"repository":{"url":"git+https://github.com/jmtrs/no-coAuthor.git","type":"git"},"_npmVersion":"10.8.2","description":"Git hook that strips AI co-author trailers (Claude, Copilot, Codex, Cursor, Oz/Warp, GPT, Gemini, Devin, etc.) from commit messages while preserving human co-authors","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@changesets/cli":"^2.31.0","@changesets/changelog-github":"^0.7.0"},"_npmOperationalInternal":{"tmp":"tmp/no-coauthor_2.0.0_1783958238374_0.23921526141305138","host":"s3://npm-registry-packages-npm-production"}},"2.1.0":{"name":"@aggc/no-coauthor","version":"2.1.0","keywords":["git","hooks","commit-msg","commit","co-author","co-authored-by","ai","claude","claude-code","copilot","codex","gpt","chatgpt","gemini","cursor","devin"],"author":{"name":"0xdsgnrd"},"license":"MIT","_id":"@aggc/no-coauthor@2.1.0","maintainers":[{"name":"aggc","email":"dev@aggc.dev"}],"contributors":[{"name":"jmtrs"}],"homepage":"https://github.com/jmtrs/no-coAuthor#readme","bugs":{"url":"https://github.com/jmtrs/no-coAuthor/issues"},"bin":{"no-coauthor":"bin/no-coauthor.js"},"dist":{"shasum":"83598150210319bc30162e5c802e50be38a973f3","tarball":"https://registry.npmjs.org/@aggc/no-coauthor/-/no-coauthor-2.1.0.tgz","fileCount":16,"integrity":"sha512-mCu8l6VbH3tb3YV1Im0vBSH6rkOX5DyXxoDhrZ40d7UpHz36W3U7olapocsSSGc8UA258cf7g4QFYVJGYR8XoA==","signatures":[{"sig":"MEQCIB86gd47vnYxFmHgvhkdnOTuW/Gk4PuYI6jRFizw68A+AiARcWoKYCBHFQCjINrxesKC59vCJTvVCdBf3KcbXkwpuQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aggc%2fno-coauthor@2.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":83258},"engines":{"node":">=18"},"gitHead":"1e3ccb88e7ca1847ca2625b1e58b4589c7347cc4","scripts":{"test":"node --test","release":"changeset publish","changeset":"changeset","prepublishOnly":"npm test","sync-install-sh":"node scripts/sync-install-sh.js","version-packages":"changeset version"},"_npmUser":{"name":"aggc","email":"dev@aggc.dev"},"repository":{"url":"git+https://github.com/jmtrs/no-coAuthor.git","type":"git"},"_npmVersion":"10.8.2","description":"Git hook that strips AI co-author trailers (Claude, Copilot, Codex, Cursor, Oz/Warp, GPT, Gemini, Devin, etc.) from commit messages while preserving human co-authors","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@changesets/cli":"^2.31.0","@changesets/changelog-github":"^0.7.0"},"_npmOperationalInternal":{"tmp":"tmp/no-coauthor_2.1.0_1783960657901_0.33856685470407966","host":"s3://npm-registry-packages-npm-production"}},"2.2.0":{"name":"@aggc/no-coauthor","version":"2.2.0","keywords":["git","hooks","commit-msg","commit","co-author","co-authored-by","ai","claude","claude-code","copilot","codex","gpt","chatgpt","gemini","cursor","devin"],"author":{"name":"0xdsgnrd"},"license":"MIT","_id":"@aggc/no-coauthor@2.2.0","maintainers":[{"name":"aggc","email":"dev@aggc.dev"}],"contributors":[{"name":"jmtrs"}],"homepage":"https://github.com/jmtrs/no-coAuthor#readme","bugs":{"url":"https://github.com/jmtrs/no-coAuthor/issues"},"bin":{"no-coauthor":"bin/no-coauthor.js"},"dist":{"shasum":"1691d8ed9c186bd924e380920ca45d16be7bca77","tarball":"https://registry.npmjs.org/@aggc/no-coauthor/-/no-coauthor-2.2.0.tgz","fileCount":17,"integrity":"sha512-omRfMvQ86YRgt8bgKFBnZVTmLI4hiFSnjeoOW7w21SZgW7z7PxoOSedPactuu+wD9OyYvSee+obx7gRtv7pH7g==","signatures":[{"sig":"MEYCIQCMjKV6fth+dMm9HdiP5Ha65TDay3k/5wiZKxbO7s1O2gIhAOigCfNsST/nNcSQOQu+WUiyFL0qJPotWSP4sPXquPCq","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aggc%2fno-coauthor@2.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":87651},"engines":{"node":">=18"},"gitHead":"4baa72b7e1a4ec9d60cd558ec65bcbafb2e0587e","scripts":{"test":"node --test","release":"changeset publish","changeset":"changeset","prepublishOnly":"npm test","sync-install-sh":"node scripts/sync-install-sh.js","version-packages":"changeset version"},"_npmUser":{"name":"aggc","email":"dev@aggc.dev"},"repository":{"url":"git+https://github.com/jmtrs/no-coAuthor.git","type":"git"},"_npmVersion":"10.8.2","description":"Git hook that strips AI co-author trailers (Claude, Copilot, Codex, Cursor, Oz/Warp, GPT, Gemini, Devin, etc.) from commit messages while preserving human co-authors","directories":{},"_nodeVersion":"20.20.2","dependencies":{"picocolors":"1.1.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@changesets/cli":"^2.31.0","@changesets/changelog-github":"^0.7.0"},"_npmOperationalInternal":{"tmp":"tmp/no-coauthor_2.2.0_1783962860246_0.09517562737446483","host":"s3://npm-registry-packages-npm-production"}},"2.3.0":{"name":"@aggc/no-coauthor","version":"2.3.0","keywords":["git","hooks","commit-msg","commit","co-author","co-authored-by","ai","claude","claude-code","copilot","codex","gpt","chatgpt","gemini","cursor","devin"],"author":{"name":"0xdsgnrd"},"license":"MIT","_id":"@aggc/no-coauthor@2.3.0","maintainers":[{"name":"aggc","email":"dev@aggc.dev"}],"contributors":[{"name":"jmtrs"}],"homepage":"https://github.com/jmtrs/no-coAuthor#readme","bugs":{"url":"https://github.com/jmtrs/no-coAuthor/issues"},"bin":{"no-coauthor":"bin/no-coauthor.js"},"dist":{"shasum":"40f491f5c73bbb8d746cd8938de7408afe784975","tarball":"https://registry.npmjs.org/@aggc/no-coauthor/-/no-coauthor-2.3.0.tgz","fileCount":17,"integrity":"sha512-xtSRamfFTUU61kZpieUY98VJdiaMTeVq9RNpP4DcMzbso9vVRnrRRtlYEvL9881rOel7GTJsJqEfDNgAJ9khIA==","signatures":[{"sig":"MEYCIQCTv3pcfl6Raf5SQuIqH3EWXA5djwLb4R6GXy5SauQgBgIhAJx5Nvn4uLM8ySwQ21Vd51XRFs9QIUXMkLj/JBHea2od","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aggc%2fno-coauthor@2.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":95795},"engines":{"node":">=18"},"gitHead":"1d13d220e8a1176aee642e492000e6a087a79720","scripts":{"test":"node --test","release":"changeset publish","changeset":"changeset","prepublishOnly":"npm test","sync-install-sh":"node scripts/sync-install-sh.js","version-packages":"changeset version"},"_npmUser":{"name":"aggc","email":"dev@aggc.dev"},"repository":{"url":"git+https://github.com/jmtrs/no-coAuthor.git","type":"git"},"_npmVersion":"10.8.2","description":"Git hook that strips AI co-author trailers (Claude, Copilot, Codex, Cursor, Oz/Warp, GPT, Gemini, Devin, etc.) from commit messages while preserving human co-authors","directories":{},"_nodeVersion":"20.20.2","dependencies":{"picocolors":"1.1.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@changesets/cli":"^2.31.0","@changesets/changelog-github":"^0.7.0"},"_npmOperationalInternal":{"tmp":"tmp/no-coauthor_2.3.0_1783972741639_0.1565465729230644","host":"s3://npm-registry-packages-npm-production"}},"2.4.0":{"name":"@aggc/no-coauthor","version":"2.4.0","keywords":["git","hooks","commit-msg","commit","co-author","co-authored-by","ai","claude","claude-code","copilot","codex","gpt","chatgpt","gemini","cursor","devin"],"author":{"name":"0xdsgnrd"},"license":"MIT","_id":"@aggc/no-coauthor@2.4.0","maintainers":[{"name":"aggc","email":"dev@aggc.dev"}],"contributors":[{"name":"jmtrs"}],"homepage":"https://github.com/jmtrs/no-coAuthor#readme","bugs":{"url":"https://github.com/jmtrs/no-coAuthor/issues"},"bin":{"no-coauthor":"bin/no-coauthor.js"},"dist":{"shasum":"8e7c71dcc9229a0d80cfddf578e783e7c18e856b","tarball":"https://registry.npmjs.org/@aggc/no-coauthor/-/no-coauthor-2.4.0.tgz","fileCount":18,"integrity":"sha512-LYbv91mEBri2KxXjAgvyTw/p2oIjreadq1zNJjoETbiVVHE0g1PfmxpjN6EwetGnypoVWr1EeSzqfPnSjMRdRA==","signatures":[{"sig":"MEUCICOUFw4ngYZ35J9vWQ0nV+tSsP82gFH5PQ3Zp7CsAd5bAiEA3bE6LJbSnxpZVxrzQq9FzGRPQLiLTCGCxWk0J7QTlc8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aggc%2fno-coauthor@2.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":100892},"engines":{"node":">=18"},"gitHead":"53ca63eaff19141c915e8cc9686f8a4b8b5e869b","scripts":{"test":"node --test","release":"changeset publish","changeset":"changeset","prepublishOnly":"npm test","sync-install-sh":"node scripts/sync-install-sh.js","version-packages":"changeset version"},"_npmUser":{"name":"aggc","email":"dev@aggc.dev"},"repository":{"url":"git+https://github.com/jmtrs/no-coAuthor.git","type":"git"},"_npmVersion":"10.8.2","description":"Git hook that strips AI co-author trailers (Claude, Copilot, Codex, Cursor, Oz/Warp, GPT, Gemini, Devin, etc.) from commit messages while preserving human co-authors","directories":{},"_nodeVersion":"20.20.2","dependencies":{"picocolors":"1.1.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@changesets/cli":"^2.31.0","@changesets/changelog-github":"^0.7.0"},"_npmOperationalInternal":{"tmp":"tmp/no-coauthor_2.4.0_1783975266377_0.30246289276656046","host":"s3://npm-registry-packages-npm-production"}},"2.5.0":{"name":"@aggc/no-coauthor","version":"2.5.0","description":"Git hook that strips AI co-author trailers (Claude, Copilot, Codex, Cursor, Oz/Warp, GPT, Gemini, Devin, etc.) from commit messages while preserving human co-authors","license":"MIT","author":{"name":"0xdsgnrd"},"contributors":[{"name":"jmtrs"}],"repository":{"type":"git","url":"git+https://github.com/jmtrs/no-coAuthor.git"},"bin":{"no-coauthor":"bin/no-coauthor.js"},"publishConfig":{"access":"public"},"scripts":{"test":"node --test","prepublishOnly":"npm test","sync-install-sh":"node scripts/sync-install-sh.js","changeset":"changeset","version-packages":"changeset version","release":"changeset publish"},"engines":{"node":">=18"},"keywords":["git","hooks","commit-msg","commit","co-author","co-authored-by","ai","claude","claude-code","copilot","codex","gpt","chatgpt","gemini","cursor","devin"],"devDependencies":{"@changesets/changelog-github":"^0.7.0","@changesets/cli":"^2.31.0"},"dependencies":{"picocolors":"1.1.1"},"_id":"@aggc/no-coauthor@2.5.0","gitHead":"a5792115ec0357b0e95b7acbdfc62fa0639c253c","bugs":{"url":"https://github.com/jmtrs/no-coAuthor/issues"},"homepage":"https://github.com/jmtrs/no-coAuthor#readme","_nodeVersion":"20.20.2","_npmVersion":"10.8.2","dist":{"integrity":"sha512-MHMhp8o0v4IT0qGG2SDyzYCGyYqtiZVnWo3riyR5LLchjQUUo+G788O//fepkkQUnViqOkINu+Y5iRwv77XkGg==","shasum":"bff2650927506fa54ea80b6e6c11d0b5af78f3d8","tarball":"https://registry.npmjs.org/@aggc/no-coauthor/-/no-coauthor-2.5.0.tgz","fileCount":18,"unpackedSize":102026,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aggc%2fno-coauthor@2.5.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDnD5I8OZrSEnZ6NnIJoW1xxr95C7UoeAs/wgEDmuvfrgIgYwi1SBevpIvwkbtsTDCIfRT6SEZIvatb8OfJdWeqQow="}]},"_npmUser":{"name":"aggc","email":"dev@aggc.dev"},"directories":{},"maintainers":[{"name":"aggc","email":"dev@aggc.dev"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/no-coauthor_2.5.0_1784032926750_0.30568254565271724"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-13T09:12:04.730Z","modified":"2026-07-14T12:42:07.183Z","1.1.0":"2026-07-13T09:12:05.020Z","1.2.0":"2026-07-13T09:24:56.134Z","1.2.1":"2026-07-13T09:34:11.400Z","1.3.0":"2026-07-13T10:23:41.095Z","1.3.1":"2026-07-13T10:31:06.367Z","1.4.0":"2026-07-13T10:50:44.549Z","1.5.0":"2026-07-13T11:08:21.775Z","1.5.1":"2026-07-13T11:57:41.074Z","2.0.0":"2026-07-13T15:57:18.483Z","2.1.0":"2026-07-13T16:37:38.058Z","2.2.0":"2026-07-13T17:14:20.427Z","2.3.0":"2026-07-13T19:59:01.774Z","2.4.0":"2026-07-13T20:41:06.518Z","2.5.0":"2026-07-14T12:42:06.908Z"},"bugs":{"url":"https://github.com/jmtrs/no-coAuthor/issues"},"author":{"name":"0xdsgnrd"},"license":"MIT","homepage":"https://github.com/jmtrs/no-coAuthor#readme","keywords":["git","hooks","commit-msg","commit","co-author","co-authored-by","ai","claude","claude-code","copilot","codex","gpt","chatgpt","gemini","cursor","devin"],"repository":{"type":"git","url":"git+https://github.com/jmtrs/no-coAuthor.git"},"description":"Git hook that strips AI co-author trailers (Claude, Copilot, Codex, Cursor, Oz/Warp, GPT, Gemini, Devin, etc.) from commit messages while preserving human co-authors","contributors":[{"name":"jmtrs"}],"maintainers":[{"name":"aggc","email":"dev@aggc.dev"}],"readme":"# no-coauthor\n\n[![CI](https://github.com/jmtrs/no-coAuthor/actions/workflows/ci.yml/badge.svg)](https://github.com/jmtrs/no-coAuthor/actions/workflows/ci.yml)\n[![npm](https://img.shields.io/npm/v/%40aggc%2Fno-coauthor.svg)](https://www.npmjs.com/package/@aggc/no-coauthor)\n[![license](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n[![node](https://img.shields.io/node/v/%40aggc%2Fno-coauthor.svg)](package.json)\n\nA `commit-msg` git hook that strips AI `Co-Authored-By:` trailers from commit\nmessages — while **preserving human co-authors** and every other trailer\n(`Signed-off-by`, `Refs`, `Closes`, …).\n\nIt runs inside git, not inside the AI tool, so it catches the trailer\nregardless of which tool added it or whether that tool's own \"disable\nattribution\" setting actually works.\n\n> Fork of [`0xdsgnrd/no-coAuthor`](https://github.com/0xdsgnrd/no-coAuthor) —\n> full credit to the original author for the concept and initial\n> implementation. This fork adds email-based detection (not just names),\n> `core.hooksPath` support, non-destructive install/uninstall, a POSIX shell\n> fallback for machines without Node.js, a user config file, an automated\n> test suite, and cross-platform CI. Published on npm as\n> [`@aggc/no-coauthor`](https://www.npmjs.com/package/@aggc/no-coauthor); the\n> installed hook and CLI command are still called `no-coauthor`.\n\n## Quick start\n\n```bash\nnpx @aggc/no-coauthor install\n```\n\nThat's it — every commit in this repo now has AI `Co-Authored-By:` trailers\nstripped automatically, human co-authors untouched. See\n[Install](#install) for the global, curl, and no-Node.js variants.\n\n## Table of contents\n\n- [Quick start](#quick-start)\n- [Why](#why)\n- [How it decides what to strip](#how-it-decides-what-to-strip)\n- [Covered tools](#covered-tools)\n- [Install](#install)\n- [Uninstall](#uninstall)\n- [How install works (non-destructive)](#how-install-works-non-destructive)\n- [Configuration](#configuration)\n- [Temporarily disabling](#temporarily-disabling)\n- [Server-side enforcement](#server-side-enforcement)\n- [CLI reference](#cli-reference)\n- [Architecture](#architecture)\n- [Cross-platform](#cross-platform)\n- [Limitations](#limitations)\n- [Contributing](#contributing)\n- [Releasing](#releasing)\n- [Credits](#credits)\n- [License](#license)\n\n## Why\n\nAI coding assistants (Claude Code, Copilot, Cursor, Codex, Gemini, Oz/Warp, …)\ninject `Co-Authored-By:` trailers into commits. Some tools expose a setting to\ndisable this, but those settings are unreliable in practice: Claude Code's\n`attribution` setting is intermittently ignored, Cursor has re-enabled it\nacross updates, and tools like Copilot Agent or Gemini Code Assist offer no\nsetting at all.\n\n`no-coauthor` is a git-level safety net that works regardless of the tool,\nits version, or its settings. Use it **together with** your tool's built-in\nsetting when one exists — prevention at the source plus enforcement at the\ncommit boundary. Belt and suspenders.\n\n## How it decides what to strip\n\nA `Co-Authored-By: Name <email>` line is removed when **any** of these rules\nmatch (all matching is case-insensitive and anchored to the trailer line):\n\n| Rule | Condition | Example |\n|---|---|---|\n| **A. Bot address** | The `<email>` matches a known bot address/domain (`copilot@github.com`, `noreply@anthropic.com`, `oz-agent@warp.dev`, `…+copilot@users.noreply.github.com`, …). High confidence — no human co-author uses these. | `Co-Authored-By: Claude <noreply@anthropic.com>` |\n| **B. Name + bot-shaped email** | The name matches a known AI tool name **and** the email is bot-shaped (`noreply`, `users.noreply.github.com`, `[bot]`). | `Co-Authored-By: gemini-code-assist[bot] <176…@users.noreply.github.com>` |\n| **C. Name + tool domain** | The name matches a known AI tool name **and** the email domain is a known AI-tool domain (`anthropic.com`, `cursor.com`, `warp.dev`, …). Catches non-noreply bot addresses. | `Co-Authored-By: Oz <oz-agent@warp.dev>` |\n\nA **name match alone never strips a line**. This is what keeps a human\nliterally named \"Claude\", \"Cody\", or \"Devin\" intact:\n\n```\nCo-Authored-By: Claude <noreply@anthropic.com>       → stripped (A, B)\nCo-Authored-By: Oz <oz-agent@warp.dev>                → stripped (A, C)\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> → stripped (A, B — model-suffixed names too)\nCo-Authored-By: Claude Smith <claude@gmail.com>       → KEPT (human, unrelated email)\nCo-Authored-By: Jane <jane@cursor.com>                → KEPT (same domain, non-AI name)\nCo-Authored-By: Pat <pat@google.com>                  → KEPT (google.com deliberately excluded, see Limitations)\n```\n\nEverything else in the commit message — `Signed-off-by:`, `Refs:`, `Closes:`,\nfree text, other trailers — is left untouched. Removal is line-based and\ncollapses any blank line left behind so the trailer block stays valid for\ngit's trailer parser.\n\nSeparately, a small set of known **AI banner/footer lines** — plain body\nlines some tools insert that aren't trailers at all — are stripped the same\nway. Today this is Claude Code's default commit-body attribution line, which\ncovers the confirmed variants across its CLI versions/docs (emoji prefix\noptional, link optional, markdown or plain-parenthetical link):\n\n```\n🤖 Generated with [Claude Code](https://claude.com/claude-code)\nGenerated with [Claude Code](https://claude.ai/code)\n🤖 Generated with Claude Code\nGenerated with Claude Code (https://claude.com/claude-code)\n```\n\nOf the other major tools surveyed (Copilot, Cursor, Codex CLI, Gemini CLI,\nAider, Devin, Amazon Q Developer, Windsurf), none currently ship a\nstandardized commit-body banner like this — they either only use a\n`Co-Authored-By:` trailer (already covered above) or have no attribution\nconvention at all. Only exact, confirmed formats are matched (see\n`AI_BANNER_LINES` in `lib/patterns.js`), so a commit message that merely\n*mentions* a tool by name in its own body text is left untouched.\n\n## Covered tools\n\n| Tool | Detected via |\n|---|---|\n| Claude / Claude Code (Anthropic) | `noreply@anthropic.com`, name match |\n| GitHub Copilot | `copilot@github.com`, `*copilot*@users.noreply.github.com`, `[bot]` forms |\n| OpenAI Codex | `noreply@openai.com`, `codex@openai.com`, GitHub noreply form |\n| ChatGPT / GPT (OpenAI) | `@chatgpt.com`, name match |\n| Cursor (incl. Cursor Agent / background agents) | `noreply@cursor.com`/`.sh`, `cursoragent@cursor.com` |\n| Gemini / Bard / Gemini Code Assist (Google) | `gemini*@google.com`, `bard*@google.com`, `[bot]` forms |\n| Oz (Warp) | `oz-agent@warp.dev` |\n| Codeium / Windsurf | `noreply@codeium.com`, `noreply@windsurf.com` |\n| Tabnine | `noreply@tabnine.com` |\n| Amazon Q / CodeWhisperer | name match (`amazon-q`, `amazonq`, `CodeWhisperer`) |\n| Aider | `noreply@aider.chat`/`.ai` |\n| Zed AI | `noreply@zed.dev` |\n| Cody (Sourcegraph) | `noreply@sourcegraph.com` |\n| Devin (Cognition) | `noreply@cognition.ai`/`.dev` |\n| Augment Code | `noreply@augmentcode.com` |\n| Replit Agent / Ghostwriter | `noreply@replit.com` |\n| Cline, Continue, Llama, Tabby, Bolt, v0, Lovable, Goose, OpenHands, Plandex, Qoder, Jules | name match |\n\nAlso stripped as a standalone body line (not a trailer): Claude Code's\n`Generated with Claude Code` attribution banner, in its confirmed variants\n(with/without emoji, with/without a link) — see [How it decides what to\nstrip](#how-it-decides-what-to-strip) and `AI_BANNER_LINES` in\n`lib/patterns.js`.\n\nThis list is best-effort and evolves as tools change their default trailers.\nMissing one? Add it locally via [config](#configuration) — no code change\nneeded — or open a PR against `lib/patterns.js`.\n\n## Install\n\n### npm (recommended — Node.js hook with config-file support)\n\n```bash\n# Per-project (inside a git repo)\nnpx @aggc/no-coauthor install\n\n# Every repo on this machine\nnpx @aggc/no-coauthor install --global\n```\n\n`--global` sets git's own `core.hooksPath` globally, so it affects **every\nrepo on the machine that doesn't already set its own local\n`core.hooksPath`** — not just repos you plan to use it with. If you have\nolder per-project hooks (e.g. a husky v4-style setup that writes straight\ninto `.git/hooks` instead of setting `core.hooksPath`), they'll stop running\nsilently. Run `npx @aggc/no-coauthor status` in any repo you're unsure about\nto check.\n\n### curl (no Node.js required — POSIX shell hook)\n\n```bash\n# Per-project\ncurl -fsSL https://raw.githubusercontent.com/jmtrs/no-coAuthor/main/install.sh | sh\n\n# Global\ncurl -fsSL https://raw.githubusercontent.com/jmtrs/no-coAuthor/main/install.sh | sh -s -- --global\n```\n\n### POSIX shell hook via npm\n\n```bash\nnpx @aggc/no-coauthor install --no-node\n```\n\n### Homebrew (no Node.js required)\n\n```bash\nbrew install jmtrs/tap/no-coauthor\nno-coauthor install          # per-project\nno-coauthor install --global # every repo on this machine\n```\n\nSame POSIX shell hook as the curl installer above — [jmtrs/homebrew-tap](https://github.com/jmtrs/homebrew-tap)\njust packages `install.sh` under the `no-coauthor` command name. The formula\nis updated automatically on every release (see `.github/workflows/release.yml`).\n\n### pre-commit framework\n\nAlready using [pre-commit](https://pre-commit.com)? Add this repo to your\n`.pre-commit-config.yaml` instead of running `install` — pre-commit manages\nthe `commit-msg` hook file for you:\n\n```yaml\nrepos:\n  - repo: https://github.com/jmtrs/no-coAuthor\n    rev: v2.4.0 # use the latest tag: https://github.com/jmtrs/no-coAuthor/tags\n    hooks:\n      - id: no-coauthor\n```\n\nThen:\n\n```bash\npre-commit install --hook-type commit-msg\n```\n\nThis runs `no-coauthor commit-msg <file>` under pre-commit's own Node\nenvironment instead of through `no-coauthor install`, so it does **not** get\nthe wrapper/preserve-foreign-hook handling `lib/install.js` does for a direct\ninstall — pre-commit is already managing the hook file and any other\n`commit-msg` hooks you've configured through it. Everything else (which\ntrailers/banners get stripped, `.no-coauthorrc.json`, `NO_COAUTHOR_DISABLE`)\nbehaves the same either way.\n\n## Uninstall\n\n```bash\nnpx @aggc/no-coauthor uninstall          # per-project\nnpx @aggc/no-coauthor uninstall --global # global\n```\n\n## How install works (non-destructive)\n\n- **No existing `commit-msg` hook** → writes ours (standalone).\n- **Existing foreign hook** → preserved as `commit-msg.orig` and replaced with\n  a small shell `commit-msg` wrapper that runs the previous hook **then**\n  no-coauthor. Your existing hook keeps working unmodified.\n- **Already installed** → updated in place (idempotent — safe to re-run).\n- **`core.hooksPath`-aware** — if the repo sets a local `core.hooksPath`\n  (e.g. `.githooks`), the hook is installed **there**, not in `.git/hooks`\n  (which git would otherwise ignore). If a global `core.hooksPath` would\n  shadow a per-project install, you get a warning with the fix.\n- **Worktree- and submodule-safe** — `install`/`uninstall`/`status` resolve\n  the hooks directory through `git rev-parse --git-common-dir` rather than\n  assuming `<repo>/.git` is a directory (it's a text file pointing elsewhere\n  in both). Installing from a linked worktree writes to the main repo's\n  shared hooks dir — the same place git itself reads hooks from for every\n  worktree — so one install covers all of them.\n\nUninstall restores the preserved foreign hook if one exists, otherwise\nremoves the no-coauthor hook cleanly.\n\nRun `npx @aggc/no-coauthor status` any time to confirm the hook is still\nthere and actually stripping trailers — see [CLI reference](#cli-reference).\n\n## Configuration\n\nOptional `.no-coauthorrc.json` adds custom patterns on top of the built-ins.\nEntries are treated as **literal strings** and escaped automatically, so no\nregex knowledge is required:\n\n```json\n{\n  \"names\": [\"MyAgent\"],\n  \"emails\": [\"bot@myteam.ai\"],\n  \"domains\": [\"myteam.ai\"],\n  \"banners\": [\"Generated by MyAgent v2\"]\n}\n```\n\nThe Node.js hook and the `check` command read this at runtime. There are two\nlocations, with **different trust levels**:\n\n- **`~/.no-coauthorrc.json`** — your own machine, always honored.\n- **`./.no-coauthorrc.json`** (repo root) — **ignored by default**. A cloned\n  repo could ship a config that silently strips real human co-author\n  attribution, which is exactly what this tool exists to prevent. To honor a\n  repo-root config you control (e.g. a team-shared one in CI), opt in with:\n\n```bash\nexport NO_COAUTHOR_TRUST_REPO=1\n```\n\nThe POSIX fallback hook does not read either file — it is fully\nself-contained by design, with no filesystem reads beyond the commit message\nitself.\n\n## Temporarily disabling\n\nTwo ways to skip stripping, for different scopes:\n\n```bash\n# Skip every hook for one commit (git's own escape hatch) — also skips any\n# OTHER hook this may be wrapping (see [How install works](#how-install-works-non-destructive)).\ngit commit --no-verify -m \"...\"\n\n# Skip only no-coauthor for one commit — any wrapped hook still runs.\nNO_COAUTHOR_DISABLE=1 git commit -m \"...\"\n\n# Skip only no-coauthor for a whole shell session.\nexport NO_COAUTHOR_DISABLE=1\n```\n\n`NO_COAUTHOR_DISABLE` is checked first thing in both the Node and POSIX\nhooks, before any matching happens. Prefer it over `--no-verify` whenever a\nforeign hook is wrapped and you still want that one to run.\n\n## Server-side enforcement\n\n**The commit-msg hook is a client-side, opt-in safety net, not a security\nboundary.** Anything running on the committer's own machine — including an\nAI agent with shell access — can skip it: `--no-verify`, `NO_COAUTHOR_DISABLE=1`,\nor just never running `install` in the first place. No local git hook can be\nmade bypass-proof against the same machine it runs on; that's true of this\ntool and of every other commit-msg hook (husky, pre-commit, lint-staged, …)\nequally, not a no-coauthor-specific weakness.\n\nIf your threat model includes an agent that might *deliberately* re-add\nattribution rather than just doing it by unreliable default, the hook alone\nisn't enough — you need a check that runs somewhere the committer doesn't\ncontrol: **CI, as a required PR status check.**\n\n```bash\nnpx @aggc/no-coauthor check <range>   # exit 1 if any commit in <range> has an AI trailer\nnpx @aggc/no-coauthor check           # defaults to HEAD~1..HEAD\n```\n\n`check` reuses the exact same detection logic as the hooks (same\n`lib/patterns.js`, same `.no-coauthorrc.json`), so it can never flag\nsomething the hook wouldn't also have stripped, or vice versa. Copy\n[`examples/reject-ai-coauthor.yml`](examples/reject-ai-coauthor.yml) into\nyour repo's `.github/workflows/` — it computes the commit range from the\nPR's base/head SHAs, so it works the same regardless of which branch a PR\ntargets or is opened from, not just `main`.\n\nA failing check does **not** block a merge by itself — add a branch\nprotection rule (or ruleset) on your target branch(es) requiring that job to\npass, and restrict who can bypass required checks. That combination — hook\nfor the common case, required CI check for the case where someone tries to\nroute around it — is what actually can't be defeated from a local shell.\n\n## CLI reference\n\n```\n$ npx @aggc/no-coauthor <command> [options]\n\nCommands\n  install             Install hook in current repo\n  install --global    Install as global git hook\n  install --no-node   Install POSIX shell hook (no Node.js needed)\n  uninstall           Remove hook from current repo\n  uninstall --global  Remove global git hook\n  status              Check the hook is installed and actually stripping trailers\n  status --global     Check the global hook instead of the local one\n  check [range]       Scan already-made commits for AI trailers (default: HEAD~1..HEAD)\n                      For CI use — see [Server-side enforcement](#server-side-enforcement)\n  commit-msg <file>   Strip trailers/banners from a commit message file in place.\n                      Internal: invoked by pre-commit, not meant to be run by hand\n                      — see [pre-commit framework](#install)\n\nOptions\n  --no-node           Use POSIX shell hook instead of Node.js\n  -h, --help          Show help\n  -v, --version       Show version\n```\n\n`status` exists because this tool's whole job is to run invisibly on every\ncommit — if something else later overwrites `.git/hooks/commit-msg` (a hook\nmanager like husky/lefthook reinstalling, a manual edit, a fresh `git init`\ntemplate), no-coauthor silently stops working with **zero visible signal**,\nwhich is exactly the failure mode it exists to prevent. `status` checks the\nhook file is present, is ours, is executable, and then actually **runs it**\nagainst a synthetic AI trailer to confirm it still strips correctly — not\njust that a plausible-looking file exists:\n\n```bash\n$ npx @aggc/no-coauthor status\nno-coauthor: checking local hook at /path/to/repo/.git/hooks\n✔ commit-msg hook is installed and managed by no-coauthor\n✔ /path/to/repo/.git/hooks/commit-msg is executable\n✔ live check: a synthetic AI trailer was stripped and a human trailer was kept\n```\n\n## Architecture\n\n```\nbin/no-coauthor.js       CLI entry point (install / uninstall / --help / --version)\nlib/git-utils.js         Shared git plumbing (gitConfig, gitRoot, gitCommonDir) used\n                         by install/uninstall/status to resolve the hooks dir —\n                         worktree/submodule-safe (see How install works above)\nlib/install.js           Non-destructive install: standalone, wrap, or update-in-place\nlib/uninstall.js         Restores a preserved foreign hook, or removes ours cleanly\nlib/status.js            Checks the hook is installed, managed, executable, and\n                         actually strips a synthetic AI trailer right now\nlib/check.js             Server-side companion: scans a git revision range of\n                         already-made commits for AI trailers (reuses strip.js)\nlib/commit-msg.js        Runtime commit-msg entry point for `no-coauthor commit-msg\n                         <file>` — what .pre-commit-hooks.yaml shells out to\n                         (reuses strip.js, unlike the generated hooks below)\nlib/hook.js              Builds the self-contained Node.js commit-msg hook that gets\n                         written to disk (inlines strip.js + patterns.js — no\n                         runtime dependency on this package once installed)\nlib/hook-posix.js        Builds the POSIX /bin/sh commit-msg hook from the same\n                         patterns.js source (JS regex fragments transliterated\n                         to POSIX ERE character classes)\nlib/patterns.js          Single source of truth for bot emails, tool domains,\n                         and AI tool names — both hooks are generated from this\nlib/strip.js             Core matching/stripping logic (rules A/B/C), shared by\n                         the Node hook builder and the test suite\ninstall.sh               Standalone POSIX installer for the curl one-liner;\n                         embeds a copy of the hook-posix.js output\nscripts/sync-install-sh.js  Regenerates that embedded copy after a\n                         lib/patterns.js change (`npm run sync-install-sh`)\nexamples/reject-ai-coauthor.yml  Copy-paste GitHub Actions workflow wired to\n                         `no-coauthor check` — see Server-side enforcement above\n.pre-commit-hooks.yaml   Exposes this repo as a pre-commit `commit-msg`-stage\n                         hook — see pre-commit framework under Install above\n```\n\nBoth hook implementations are generated from `lib/patterns.js`, so a tool\nadded there is picked up by the Node hook, the POSIX hook, and (after\nregeneration) `install.sh` alike. `test/install.test.js` asserts the\n`install.sh` embedded hook body stays byte-identical to `lib/hook-posix.js`'s\noutput, so the two can't silently drift.\n\n## Cross-platform\n\n- **Node.js hook** (default) — Linux, macOS, and Windows (Git for\n  Windows / Git Bash).\n- **POSIX shell hook** (fallback) — anywhere with `/bin/sh`, `grep -E`, and\n  `awk`; no Node.js required.\n\nCI (`.github/workflows/ci.yml`) runs the full test suite on Ubuntu, macOS,\nand Windows against Node 18 / 20 / 22, plus a dedicated end-to-end job that\ninstalls the POSIX hook with real `sh`/`grep`/`awk` and performs an actual\n`git commit`.\n\n## Limitations\n\n- `status`'s live check only exercises the built-in patterns (a synthetic\n  Claude/Anthropic trailer) — it does not know about your\n  `.no-coauthorrc.json` custom patterns, so a working `status` doesn't\n  guarantee a misconfigured custom pattern is actually matching.\n- Lines longer than 500 chars are never treated as a `Co-Authored-By`\n  trailer and are left untouched (no real one gets remotely close — this\n  bound exists to keep the Node hook's regex matching from doing\n  quadratic-time work on an adversarial or buggy-tool-generated giant line).\n- The POSIX fallback is best-effort: it compiles all patterns into one\n  combined ERE and does not read the config file. Prefer the Node hook when\n  possible; use `--no-node` only when Node.js is unavailable.\n- `google.com` is intentionally **not** listed as an AI-tool domain (rule C)\n  — it's too broad and would risk stripping real Google employees. Gemini/Bard\n  bot accounts are still caught by their specific addresses (rule A).\n- A human co-author who shares a tool-company domain **and** happens to have\n  an AI tool name (e.g. an Anthropic employee literally named \"Claude\") would\n  be stripped by rule C. This is an accepted, rare trade-off — narrow it with\n  [config](#configuration) if it matters to you.\n- Detection is pattern-based against known trailer shapes. A tool that starts\n  emitting a previously-unseen bot address/domain won't be caught until\n  patterns.js is updated (or you add it via config).\n- Banner/footer-line stripping is intentionally narrow: only Claude Code's\n  confirmed default formats are built in today (a survey of Copilot, Cursor,\n  Codex CLI, Gemini CLI, Aider, Devin, Amazon Q Developer, and Windsurf found\n  no other standardized commit-body banner as of this writing — only\n  `Co-Authored-By:` trailers, already covered above, or no attribution\n  convention at all). Claude Code's own `attribution.commit` setting also\n  lets a user/team override this text to anything, which by definition no\n  fixed pattern can catch — add a custom banner via `banners` in\n  [config](#configuration), or open a PR against `AI_BANNER_LINES` if another\n  tool starts shipping its own standardized one.\n\n## Contributing\n\nBug reports and new tool patterns are welcome.\n\n```bash\nnpm test                  # full suite: strip logic, install/uninstall, POSIX hook, sh -n\nnpm run sync-install-sh   # regenerate install.sh after touching lib/patterns.js\nnpx changeset             # record a changelog entry for your change (patch/minor/major + summary)\n```\n\nIf you add or change a pattern in `lib/patterns.js`:\n\n1. Add a `strip.test.js` case for both the strip and the preserve side.\n2. Run `npm run sync-install-sh` so the curl installer matches — CI fails the\n   build otherwise (`test/install.test.js` checks they're byte-identical).\n3. `test/posix-parity.test.js` automatically checks your new pattern strips\n   correctly under the POSIX hook too; no extra test needed for that part.\n4. `npx changeset` before opening the PR — merging to `main` won't publish\n   anything by itself, but a maintainer merging the resulting \"Version\n   Packages\" PR will (see [Releasing](#releasing)).\n\n### Releasing\n\nThis repo publishes via [Changesets](https://github.com/changesets/changesets):\nevery push to `main` with a pending changeset opens/updates a \"Version\nPackages\" PR; merging that PR bumps the version, updates `CHANGELOG.md`, and\npublishes to npm automatically (`.github/workflows/release.yml`).\n\n## Credits\n\nOriginally created by [0xdsgnrd](https://github.com/0xdsgnrd) —\n[`0xdsgnrd/no-coAuthor`](https://github.com/0xdsgnrd/no-coAuthor). This fork\nbuilds on that work; see the [table of contents](#table-of-contents) above\nfor everything added on top.\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n","readmeFilename":"README.md"}