@searls/turbocommit 0.11.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/redact.js ADDED
@@ -0,0 +1,156 @@
1
+ const SAFE_NAMES = new Set([
2
+ // Shell / OS
3
+ 'HOME', 'USER', 'SHELL', 'PATH', 'PWD', 'OLDPWD', 'LANG', 'TERM',
4
+ 'EDITOR', 'VISUAL', 'PAGER', 'HOSTNAME', 'LOGNAME', 'DISPLAY', 'TZ',
5
+ 'TMPDIR', 'SHLVL', '_', 'BROWSER', 'COMMAND_MODE', 'COLUMNS', 'LINES',
6
+ 'MANPATH', 'INFOPATH',
7
+
8
+ // Terminal
9
+ 'COLORTERM', 'TERM_PROGRAM', 'TERM_PROGRAM_VERSION', 'TERM_SESSION_ID',
10
+ 'ITERM_SESSION_ID', 'ITERM_PROFILE', 'APPLE_TERMINAL_ID',
11
+
12
+ // Locale
13
+ 'LC_ALL', 'LC_COLLATE', 'LC_CTYPE', 'LC_MESSAGES', 'LC_MONETARY',
14
+ 'LC_NUMERIC', 'LC_TIME',
15
+
16
+ // XDG
17
+ 'XDG_DATA_HOME', 'XDG_CONFIG_HOME', 'XDG_STATE_HOME', 'XDG_CACHE_HOME',
18
+ 'XDG_RUNTIME_DIR', 'XDG_DATA_DIRS', 'XDG_CONFIG_DIRS', 'XDG_SESSION_TYPE',
19
+ 'XDG_CURRENT_DESKTOP', 'XDG_SESSION_CLASS', 'XDG_SESSION_ID', 'XDG_SEAT',
20
+ 'XDG_VTNR', 'XDG_MENU_PREFIX',
21
+
22
+ // Dev environment
23
+ 'NODE_ENV', 'RAILS_ENV', 'RACK_ENV', 'GO_ENV', 'MIX_ENV', 'FLASK_ENV',
24
+ 'DEBUG', 'VERBOSE', 'LOG_LEVEL', 'PORT', 'HOST', 'CI',
25
+ 'NVM_DIR', 'NVM_BIN', 'NVM_INC', 'NVM_CD_FLAGS',
26
+ 'VOLTA_HOME', 'HOMEBREW_PREFIX', 'HOMEBREW_CELLAR', 'HOMEBREW_REPOSITORY',
27
+ 'HOMEBREW_SHELLENV_PREFIX',
28
+
29
+ // SSH / GPG (socket paths, not keys)
30
+ 'SSH_AUTH_SOCK', 'SSH_AGENT_PID', 'GPG_AGENT_INFO', 'GPG_TTY',
31
+
32
+ // Git
33
+ 'GIT_EDITOR', 'GIT_PAGER', 'GIT_TERMINAL_PROMPT'
34
+ ])
35
+
36
+ // Values that are common English words, config toggles, or well-known
37
+ // non-secret defaults. Checked case-insensitively.
38
+ const SAFE_VALUES = new Set([
39
+ // Boolean-like
40
+ 'true', 'false', 'yes', 'no', 'on', 'off',
41
+
42
+ // Environment modes
43
+ 'development', 'production', 'staging', 'test', 'testing',
44
+ 'dev', 'prod', 'local', 'ci', 'qa', 'sandbox', 'preview',
45
+ 'canary', 'demo', 'benchmark', 'profile', 'uat', 'integration',
46
+ 'preprod', 'pre-production', 'stage', 'deployment',
47
+
48
+ // Log levels
49
+ 'trace', 'debug', 'info', 'warn', 'warning', 'error', 'fatal',
50
+ 'critical', 'notice', 'verbose', 'silent', 'quiet', 'off',
51
+
52
+ // Common toggles/modes
53
+ 'enabled', 'disabled', 'always', 'never', 'auto', 'default',
54
+ 'manual', 'none', 'null', 'undefined', 'inherit', 'unset',
55
+ 'strict', 'lax', 'permissive', 'enforcing', 'noninteractive',
56
+
57
+ // Editors, pagers, browsers (bare names)
58
+ 'vim', 'vi', 'nano', 'emacs', 'nvim', 'code', 'subl', 'mate',
59
+ 'micro', 'ed', 'pico', 'gedit', 'kate', 'hx', 'kak', 'kakoune',
60
+ 'joe', 'emacsclient', 'less', 'more', 'most', 'cat',
61
+ 'open', 'firefox', 'chromium', 'links', 'lynx', 'w3m', 'safari', 'opera',
62
+
63
+ // Common English words that appear as env values
64
+ 'allow', 'deny', 'block', 'drop', 'accept', 'reject',
65
+ 'public', 'private', 'master', 'main', 'release',
66
+ 'read', 'write', 'root', 'latest', 'stable', 'edge',
67
+ 'screen', 'random', 'node', 'ruby', 'python', 'go', 'java',
68
+ 'rust', 'php', 'slim', 'alpine',
69
+ 'localhost',
70
+
71
+ // Platform/architecture identifiers
72
+ 'linux', 'darwin', 'win32', 'windows', 'freebsd', 'openbsd',
73
+ 'netbsd', 'sunos', 'aix', 'android', 'cygwin', 'msys',
74
+ 'x86_64', 'amd64', 'x64', 'arm64', 'aarch64', 'i386', 'i686',
75
+ 'ia32', 'armv7l', 'arm', 'ppc64le', 's390x', 'riscv64',
76
+
77
+ // TERM values
78
+ 'xterm', 'xterm-256color', 'xterm-color', 'xterm-16color',
79
+ 'screen', 'screen-256color', 'tmux', 'tmux-256color',
80
+ 'linux', 'vt100', 'vt220', 'dumb', 'ansi', 'rxvt',
81
+ 'rxvt-unicode', 'rxvt-unicode-256color', 'alacritty', 'kitty',
82
+ 'wezterm', 'eterm-color', 'foot', 'foot-extra',
83
+ 'gnome-256color', 'konsole-256color', 'st-256color',
84
+ 'putty', 'putty-256color',
85
+
86
+ // COLORTERM
87
+ 'truecolor', '24bit',
88
+
89
+ // TERM_PROGRAM
90
+ 'apple_terminal', 'iterm.app', 'vscode', 'hyper',
91
+
92
+ // Docker/CI identifiers
93
+ 'bullseye', 'bookworm', 'jammy', 'lts',
94
+ 'travis-ci', 'circleci', 'codeship', 'github-actions',
95
+ 'gitlab-ci', 'jenkins', 'buildkite',
96
+
97
+ // System users
98
+ 'nobody', 'www-data', 'daemon', 'nonroot', 'appuser',
99
+ 'nginx', 'postgres', 'mysql', 'redis',
100
+
101
+ // XDG session types
102
+ 'x11', 'wayland', 'tty',
103
+
104
+ // Metasyntactic / genuinely-never-a-credential values
105
+ 'todo', 'fixme', 'tbd', 'n/a',
106
+ 'xxx', 'yyy', 'zzz', 'foo', 'bar', 'baz',
107
+ 'lorem', 'temp', 'tmp', 'blah'
108
+ ])
109
+
110
+ // Pattern-based rules for values that match known non-secret formats
111
+ const SAFE_VALUE_PATTERNS = [
112
+ /^\d+$/, // pure numeric
113
+ /^(.)\1+$/, // repeated single char (xxxx, ****, ....)
114
+ /^\d+\.\d+\.\d+(-[\w.]+)?$/, // semver (18.17.1, 1.0.0-beta.1)
115
+ /^[a-z]{2}_[A-Z]{2}([.\w-]*)?$/, // locale (en_US.UTF-8)
116
+ /^(C|POSIX)(\.UTF-8)?$/, // C/POSIX locale
117
+ /^[A-Z][a-z]+\/[A-Za-z_]+$/, // timezone (America/New_York)
118
+ /^(UTC|Etc\/UTC|US\/\w+)$/, // timezone shorthand
119
+ /^\/[a-z][\w/.-]*$/, // unix path (/usr/local/bin)
120
+ /^(https?|redis|mongodb|postgres(ql)?|mysql|amqp|smtp|memcached|elasticsearch):\/\/(localhost|127\.0\.0\.1|0\.0\.0\.0|::1)/, // localhost URLs
121
+ /^(xterm|screen|tmux|linux|vt\d+|dumb|ansi|rxvt|alacritty|kitty|wezterm|foot)(-[\w]+)*$/, // TERM identifiers
122
+ /^(localhost)?:\d+(\.\d+)?$/, // X11 DISPLAY (:0, :0.0)
123
+ /^wayland-\d+$/, // Wayland display
124
+ /^sqlite:(\/\/\/)?(:\w+:|[\w./]+)$/ // sqlite URLs
125
+ ]
126
+
127
+ function isSafeValue (value) {
128
+ if (!value || value.length <= 3) return true
129
+ if (SAFE_VALUES.has(value.toLowerCase())) return true
130
+ for (const pattern of SAFE_VALUE_PATTERNS) {
131
+ if (pattern.test(value)) return true
132
+ }
133
+ return false
134
+ }
135
+
136
+ function buildRedactions (env) {
137
+ env = env || process.env
138
+ const entries = []
139
+ for (const [name, value] of Object.entries(env)) {
140
+ if (SAFE_NAMES.has(name)) continue
141
+ if (isSafeValue(value)) continue
142
+ entries.push({ name, value })
143
+ }
144
+ entries.sort((a, b) => b.value.length - a.value.length)
145
+ return entries
146
+ }
147
+
148
+ function redact (text, redactions) {
149
+ if (!text) return text
150
+ for (const { name, value } of redactions) {
151
+ text = text.replaceAll(value, '[REDACTED:' + name + ']')
152
+ }
153
+ return text
154
+ }
155
+
156
+ module.exports = { buildRedactions, redact }
package/lib/run.js CHANGED
@@ -8,6 +8,7 @@ const { gitRoot, hasChanges, addAndCommit, hasCommits, currentBranch, pushClean
8
8
  const { logEvent } = require('./log')
9
9
  const { wrapText } = require('./wrap')
10
10
  const { hasTrackedModifications, cleanupTracking } = require('./track')
11
+ const { redact, buildRedactions } = require('./redact')
11
12
  const { getAncestors, savePending, collectPending, cleanupConsumed, cleanupStale, readWatermark, saveWatermark, resolveParentCommit } = require('./session')
12
13
 
13
14
  /**
@@ -187,9 +188,12 @@ function run (input) {
187
188
  const coauthor = resolveCoauthor(config, hookInput.transcript_path, root)
188
189
  const tag = coauthor ? '\n\n' + coauthor : ''
189
190
 
190
- const sha = addAndCommit(root, headline, wrappedBody + tag)
191
+ const redactions = buildRedactions()
192
+ const safeHeadline = redact(headline, redactions)
193
+ const safeBody = redact(wrappedBody + tag, redactions)
194
+ const sha = addAndCommit(root, safeHeadline, safeBody)
191
195
 
192
- logEvent('success', { project, branch, context, title: headline })
196
+ logEvent('success', { project, branch, context, title: safeHeadline })
193
197
 
194
198
  if (config.push === true) {
195
199
  if (pushClean(root)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@searls/turbocommit",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "description": "Auto-commit after every Claude Code turn",
5
5
  "bin": {
6
6
  "turbocommit": "./cli.js"