Files
ECC/scripts/lib/claude-commit-attribution.js
T
haelyraandGitHub 569b1d5b32 fix: disable Claude co-author attribution by default (#2758)
* fix: disable Claude co-author attribution by default

* fix: harden default co-author opt-out and correct the docs

Follow-up on the co-author default in this PR.

- Remove the existsSync/writeFileSync race in the installer settings write
  (CodeQL js/file-system-race, high). A single guarded read now covers the
  fresh-install case, and unreadable or non-object settings are left untouched.
- Respect `attribution` as an explicit user choice. It supersedes
  `includeCoAuthoredBy` in Claude Code 2.1.x, so a user who configured it would
  otherwise have had a dead key written into their settings.
- Share one opt-out rule via scripts/lib/claude-commit-attribution.js instead of
  duplicating it across the installer and plugin setup.
- Update the git-workflow rule and its nine mirrors and translations, which
  still told users ECC does not ship this setting.

We keep writing the deprecated `includeCoAuthoredBy` key rather than
`attribution`: unknown keys fail Claude Code settings validation, so writing
`attribution` would break users on older versions.
2026-08-12 00:43:58 -04:00

44 lines
1.4 KiB
JavaScript

'use strict';
// Claude Code appends a `Co-Authored-By` trailer to commits and PRs unless the
// user opts out, so ECC-managed installs default that off.
//
// Two settings control the trailer. `attribution: { commit, pr }` is the current
// one and wins when set; `includeCoAuthoredBy` is deprecated as of Claude Code
// 2.1.x but still honored, and is the only one older versions understand. We
// write the deprecated key because unknown keys fail settings validation, so
// writing `attribution` would break users on older Claude Code. Either key being
// present counts as a deliberate user choice that ECC must not overwrite.
const COAUTHOR_SETTING_KEY = 'includeCoAuthoredBy';
function hasExplicitCommitAttributionPreference(settings) {
if (!settings || typeof settings !== 'object') {
return false;
}
if (typeof settings[COAUTHOR_SETTING_KEY] === 'boolean') {
return true;
}
const attribution = settings.attribution;
return Boolean(attribution)
&& typeof attribution === 'object'
&& !Array.isArray(attribution)
&& (attribution.commit !== undefined || attribution.pr !== undefined);
}
function withCommitAttributionDisabled(settings) {
if (hasExplicitCommitAttributionPreference(settings)) {
return settings;
}
return {
...settings,
[COAUTHOR_SETTING_KEY]: false,
};
}
module.exports = {
COAUTHOR_SETTING_KEY,
hasExplicitCommitAttributionPreference,
withCommitAttributionDisabled,
};