@paulduvall/claude-dev-toolkit 0.0.1-alpha.11 ā 0.0.1-alpha.13
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/LICENSE +21 -0
- package/README.md +7 -7
- package/bin/claude-commands +72 -9
- package/commands/active/xcontinue.md +92 -0
- package/commands/active/xexplore.md +94 -0
- package/commands/active/xverify.md +80 -0
- package/commands/experiments/xdevcontainer.md +238 -0
- package/commands/experiments/xnew.md +5 -0
- package/hooks/README.md +32 -0
- package/hooks/file-logger.sh +4 -2
- package/hooks/lib/argument-parser.sh +7 -2
- package/hooks/lib/config-constants.sh +4 -4
- package/hooks/lib/context-manager.sh +19 -8
- package/hooks/lib/error-handler.sh +21 -10
- package/hooks/lib/execution-engine.sh +11 -194
- package/hooks/lib/execution-results.sh +113 -0
- package/hooks/lib/execution-simulation.sh +114 -0
- package/hooks/lib/field-validators.sh +104 -0
- package/hooks/lib/file-utils.sh +49 -26
- package/hooks/lib/subagent-discovery.sh +9 -6
- package/hooks/lib/subagent-validator.sh +19 -209
- package/hooks/lib/validation-reporter.sh +134 -0
- package/hooks/on-error-debug.sh +16 -11
- package/hooks/pre-commit-test-runner.sh +132 -0
- package/hooks/pre-write-security.sh +14 -6
- package/hooks/prevent-credential-exposure.sh +55 -45
- package/hooks/subagent-trigger-simple.sh +17 -8
- package/hooks/verify-before-edit.sh +135 -0
- package/lib/oidc-command.js +385 -8
- package/lib/setup-wizard.js +155 -262
- package/lib/uninstall-command.js +100 -0
- package/package.json +2 -2
- package/scripts/postinstall.js +168 -171
- package/subagents/debug-specialist.md +6 -0
- package/templates/README.md +15 -0
- package/templates/basic-settings.json +33 -19
- package/templates/comprehensive-settings.json +68 -171
- package/templates/global-claude.md +344 -0
- package/templates/security-focused-settings.json +58 -41
- package/lib/installation-instruction-generator-backup.js +0 -579
- package/lib/package-manager-service.js +0 -270
- package/subagents/debug-context.md +0 -197
package/scripts/postinstall.js
CHANGED
|
@@ -3,198 +3,195 @@
|
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const os = require('os');
|
|
6
|
-
const { execSync } = require('child_process');
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
process.argv.includes('--skip-setup');
|
|
7
|
+
const skipSetup = process.env.CLAUDE_SKIP_SETUP === 'true' ||
|
|
8
|
+
process.argv.includes('--skip-setup');
|
|
11
9
|
|
|
12
|
-
console.log('
|
|
10
|
+
console.log('Setting up Claude Custom Commands...');
|
|
13
11
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
console.log('ā
Created .claude/commands directory');
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
if (!fs.existsSync(hooksDir)) {
|
|
34
|
-
fs.mkdirSync(hooksDir, { recursive: true });
|
|
35
|
-
console.log('ā
Created .claude/hooks directory');
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// Get package installation directory
|
|
39
|
-
const packageDir = __dirname.replace('/scripts', '');
|
|
40
|
-
|
|
41
|
-
// Check if we should run interactive setup
|
|
42
|
-
if (!skipSetup && process.stdin.isTTY) {
|
|
43
|
-
console.log('\nš Starting Interactive Setup Wizard...');
|
|
44
|
-
console.log('(Use --skip-setup or set CLAUDE_SKIP_SETUP=true to skip)\n');
|
|
45
|
-
|
|
46
|
-
const InteractiveSetupWizard = require('../lib/setup-wizard');
|
|
47
|
-
const wizard = new InteractiveSetupWizard(claudeDir);
|
|
48
|
-
|
|
49
|
-
// Validate environment first (REQ-006)
|
|
50
|
-
const envCheck = wizard.validateEnvironment();
|
|
51
|
-
if (!envCheck.valid) {
|
|
52
|
-
console.error('ā Environment validation failed:', envCheck.message);
|
|
53
|
-
process.exit(1);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Run interactive setup (REQ-007)
|
|
57
|
-
const setupResult = await wizard.runInteractiveSetup();
|
|
58
|
-
|
|
59
|
-
if (setupResult.completed) {
|
|
60
|
-
const config = setupResult.configuration;
|
|
61
|
-
|
|
62
|
-
// Install commands based on selection
|
|
63
|
-
const sourceCommandsDir = path.join(packageDir, 'commands');
|
|
64
|
-
if (fs.existsSync(sourceCommandsDir)) {
|
|
65
|
-
copySelectedCommands(sourceCommandsDir, commandsDir, config);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// Install security hooks if selected
|
|
69
|
-
if (config.securityHooks) {
|
|
70
|
-
const sourceHooksDir = path.join(packageDir, 'hooks');
|
|
71
|
-
if (fs.existsSync(sourceHooksDir)) {
|
|
72
|
-
copySelectedHooks(sourceHooksDir, hooksDir, config.selectedHooks || []);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// Apply configuration template
|
|
77
|
-
if (config.template) {
|
|
78
|
-
const templateFile = path.join(packageDir, 'templates', `${config.template}-settings.json`);
|
|
79
|
-
const targetFile = path.join(claudeDir, 'settings.json');
|
|
80
|
-
if (fs.existsSync(templateFile)) {
|
|
81
|
-
fs.copyFileSync(templateFile, targetFile);
|
|
82
|
-
console.log(`ā
Applied ${config.template} configuration template`);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
} else {
|
|
87
|
-
// Non-interactive installation - install all commands by default
|
|
88
|
-
console.log('Running non-interactive installation...');
|
|
89
|
-
|
|
90
|
-
const sourceCommandsDir = path.join(packageDir, 'commands');
|
|
91
|
-
if (fs.existsSync(sourceCommandsDir)) {
|
|
92
|
-
copyCommandsFlat(sourceCommandsDir, commandsDir);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// Count installed commands (now in flat structure)
|
|
97
|
-
if (fs.existsSync(commandsDir)) {
|
|
98
|
-
const installedCommands = fs.readdirSync(commandsDir).filter(f => f.endsWith('.md')).length;
|
|
99
|
-
console.log(`\nš¦ Installed ${installedCommands} commands`);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
console.log('\nš Installation complete!');
|
|
103
|
-
console.log('\nNext steps:');
|
|
104
|
-
console.log('1. Run: claude-commands list');
|
|
105
|
-
console.log('2. Try: claude-commands --help');
|
|
106
|
-
console.log('3. Configure: claude-commands config');
|
|
107
|
-
console.log('4. Explore commands in Claude Code using /xhelp\n');
|
|
108
|
-
|
|
109
|
-
} catch (error) {
|
|
110
|
-
console.error('ā Installation failed:', error.message);
|
|
111
|
-
process.exit(1);
|
|
112
|
-
}
|
|
12
|
+
// --- Directory helpers ---
|
|
13
|
+
|
|
14
|
+
function ensureDir(dirPath, label) {
|
|
15
|
+
if (fs.existsSync(dirPath)) return;
|
|
16
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
17
|
+
console.log(` Created ${label}`);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function getClaudeDirs() {
|
|
21
|
+
const homeDir = os.homedir();
|
|
22
|
+
const claudeDir = path.join(homeDir, '.claude');
|
|
23
|
+
return {
|
|
24
|
+
claudeDir,
|
|
25
|
+
commandsDir: path.join(claudeDir, 'commands'),
|
|
26
|
+
hooksDir: path.join(claudeDir, 'hooks')
|
|
27
|
+
};
|
|
113
28
|
}
|
|
114
29
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
30
|
+
// --- Command copying ---
|
|
31
|
+
|
|
32
|
+
function copyCommandsFlat(sourceDir, targetDir) {
|
|
33
|
+
if (!fs.existsSync(sourceDir)) return;
|
|
34
|
+
for (const item of fs.readdirSync(sourceDir)) {
|
|
35
|
+
const src = path.join(sourceDir, item);
|
|
36
|
+
if (fs.statSync(src).isDirectory()) {
|
|
37
|
+
copyCommandsFlat(src, targetDir);
|
|
123
38
|
} else if (item.endsWith('.md')) {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
fs.copyFileSync(sourcePath, targetPath);
|
|
39
|
+
fs.copyFileSync(src, path.join(targetDir, item));
|
|
40
|
+
console.log(` Installed command: ${item}`);
|
|
127
41
|
}
|
|
128
42
|
}
|
|
129
43
|
}
|
|
130
44
|
|
|
45
|
+
function copyCommandSubdir(sourceDir, subdir, targetDir) {
|
|
46
|
+
const sub = path.join(sourceDir, subdir);
|
|
47
|
+
if (fs.existsSync(sub)) copyCommandsFlat(sub, targetDir);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function shouldCopyActive(type, sets) {
|
|
51
|
+
return type === 'standard' || sets.includes('development');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function shouldCopyExperimental(type, sets) {
|
|
55
|
+
return type === 'full' || sets.includes('experimental');
|
|
56
|
+
}
|
|
57
|
+
|
|
131
58
|
function copySelectedCommands(sourceDir, targetDir, config) {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
if (installationType === 'full' || !config.commandSets) {
|
|
136
|
-
// Copy all commands in flat structure
|
|
59
|
+
const type = config.installationType || 'standard';
|
|
60
|
+
if (type === 'full' || !config.commandSets) {
|
|
137
61
|
copyCommandsFlat(sourceDir, targetDir);
|
|
138
|
-
|
|
139
|
-
// Copy selected command sets
|
|
140
|
-
const commandSets = config.commandSets || [];
|
|
141
|
-
|
|
142
|
-
// Always copy active commands for standard installation (flat structure)
|
|
143
|
-
if (installationType === 'standard' || commandSets.includes('development')) {
|
|
144
|
-
const activeSource = path.join(sourceDir, 'active');
|
|
145
|
-
if (fs.existsSync(activeSource)) {
|
|
146
|
-
copyCommandsFlat(activeSource, targetDir);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// Copy experimental if selected (flat structure to avoid namespace)
|
|
151
|
-
if (commandSets.includes('experimental') || installationType === 'full') {
|
|
152
|
-
const expSource = path.join(sourceDir, 'experiments');
|
|
153
|
-
if (fs.existsSync(expSource)) {
|
|
154
|
-
copyCommandsFlat(expSource, targetDir);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
62
|
+
return;
|
|
157
63
|
}
|
|
64
|
+
const sets = config.commandSets || [];
|
|
65
|
+
if (shouldCopyActive(type, sets)) copyCommandSubdir(sourceDir, 'active', targetDir);
|
|
66
|
+
if (shouldCopyExperimental(type, sets)) copyCommandSubdir(sourceDir, 'experiments', targetDir);
|
|
158
67
|
}
|
|
159
68
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
69
|
+
// --- Hook copying ---
|
|
70
|
+
|
|
71
|
+
function copyHookFile(src, dest, label) {
|
|
72
|
+
fs.copyFileSync(src, dest);
|
|
73
|
+
if (label.endsWith('.sh')) fs.chmodSync(dest, '755');
|
|
74
|
+
console.log(` Installed hook: ${label}`);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function copyHooksLibDir(sourceDir, targetDir) {
|
|
78
|
+
const libSrc = path.join(sourceDir, 'lib');
|
|
79
|
+
if (!fs.existsSync(libSrc)) return;
|
|
80
|
+
const libDest = path.join(targetDir, 'lib');
|
|
81
|
+
ensureDir(libDest, 'hooks/lib');
|
|
82
|
+
for (const f of fs.readdirSync(libSrc)) {
|
|
83
|
+
const src = path.join(libSrc, f);
|
|
84
|
+
if (fs.statSync(src).isFile()) {
|
|
85
|
+
copyHookFile(src, path.join(libDest, f), `lib/${f}`);
|
|
175
86
|
}
|
|
176
87
|
}
|
|
177
88
|
}
|
|
178
89
|
|
|
179
90
|
function copySelectedHooks(sourceDir, targetDir, selectedHooks) {
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
91
|
+
for (const item of fs.readdirSync(sourceDir)) {
|
|
92
|
+
const src = path.join(sourceDir, item);
|
|
93
|
+
if (fs.statSync(src).isDirectory()) continue;
|
|
94
|
+
const match = selectedHooks.length === 0 || selectedHooks.some(h => item.includes(h));
|
|
95
|
+
if (match) copyHookFile(src, path.join(targetDir, item), item);
|
|
96
|
+
}
|
|
97
|
+
copyHooksLibDir(sourceDir, targetDir);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// --- Template application ---
|
|
101
|
+
|
|
102
|
+
function applyTemplate(packageDir, claudeDir, templateName) {
|
|
103
|
+
const src = path.join(packageDir, 'templates', `${templateName}-settings.json`);
|
|
104
|
+
if (!fs.existsSync(src)) return;
|
|
105
|
+
const dest = path.join(claudeDir, 'settings.json');
|
|
106
|
+
fs.copyFileSync(src, dest);
|
|
107
|
+
console.log(` Applied ${templateName} configuration template`);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// --- Interactive setup ---
|
|
111
|
+
|
|
112
|
+
function installFromConfig(packageDir, dirs, config) {
|
|
113
|
+
const cmdSrc = path.join(packageDir, 'commands');
|
|
114
|
+
if (fs.existsSync(cmdSrc)) copySelectedCommands(cmdSrc, dirs.commandsDir, config);
|
|
115
|
+
if (config.securityHooks) {
|
|
116
|
+
const hookSrc = path.join(packageDir, 'hooks');
|
|
117
|
+
if (fs.existsSync(hookSrc)) copySelectedHooks(hookSrc, dirs.hooksDir, config.selectedHooks || []);
|
|
118
|
+
}
|
|
119
|
+
if (config.template) applyTemplate(packageDir, dirs.claudeDir, config.template);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
async function runInteractiveInstall(packageDir, dirs) {
|
|
123
|
+
console.log('\nStarting Interactive Setup Wizard...');
|
|
124
|
+
console.log('(Use --skip-setup or set CLAUDE_SKIP_SETUP=true to skip)\n');
|
|
125
|
+
const Wizard = require('../lib/setup-wizard');
|
|
126
|
+
const wizard = new Wizard(dirs.claudeDir);
|
|
127
|
+
const envCheck = wizard.validateEnvironment();
|
|
128
|
+
if (!envCheck.valid) {
|
|
129
|
+
console.error('Environment validation failed:', envCheck.message);
|
|
130
|
+
console.error('\nTroubleshooting:');
|
|
131
|
+
console.error(' - Ensure Node.js >= 18 is installed');
|
|
132
|
+
console.error(' - Check write permissions on ~/.claude/');
|
|
133
|
+
console.error(' - Try: claude-commands setup --dry-run');
|
|
134
|
+
process.exit(1);
|
|
135
|
+
}
|
|
136
|
+
const result = await wizard.runInteractiveSetup();
|
|
137
|
+
if (!result.completed) return;
|
|
138
|
+
installFromConfig(packageDir, dirs, result.configuration);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// --- Non-interactive setup ---
|
|
142
|
+
|
|
143
|
+
function runNonInteractiveInstall(packageDir, dirs) {
|
|
144
|
+
console.log('Running non-interactive installation...');
|
|
145
|
+
const cmdSrc = path.join(packageDir, 'commands');
|
|
146
|
+
if (fs.existsSync(cmdSrc)) copyCommandsFlat(cmdSrc, dirs.commandsDir);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// --- Main ---
|
|
150
|
+
|
|
151
|
+
function printSummary(commandsDir) {
|
|
152
|
+
if (fs.existsSync(commandsDir)) {
|
|
153
|
+
const count = fs.readdirSync(commandsDir).filter(f => f.endsWith('.md')).length;
|
|
154
|
+
console.log(`\nInstalled ${count} commands`);
|
|
155
|
+
}
|
|
156
|
+
console.log('\nInstallation complete!');
|
|
157
|
+
console.log('\nNext steps:');
|
|
158
|
+
console.log('1. Run: claude-commands list');
|
|
159
|
+
console.log('2. Try: claude-commands --help');
|
|
160
|
+
console.log('3. Configure: claude-commands config');
|
|
161
|
+
console.log('4. Explore commands in Claude Code using /xhelp\n');
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function printInstallError(error) {
|
|
165
|
+
console.error('Installation failed:', error.message);
|
|
166
|
+
console.error('\nTroubleshooting:');
|
|
167
|
+
console.error(' - Check write permissions: ls -la ~/.claude/');
|
|
168
|
+
console.error(' - Try manual install: claude-commands install --all');
|
|
169
|
+
console.error(' - Report issues: https://github.com/PaulDuvall/claude-code/issues');
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function initDirs() {
|
|
173
|
+
const dirs = getClaudeDirs();
|
|
174
|
+
ensureDir(dirs.claudeDir, '.claude');
|
|
175
|
+
ensureDir(dirs.commandsDir, '.claude/commands');
|
|
176
|
+
ensureDir(dirs.hooksDir, '.claude/hooks');
|
|
177
|
+
return dirs;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
async function runSetup() {
|
|
181
|
+
try {
|
|
182
|
+
const dirs = initDirs();
|
|
183
|
+
const packageDir = path.dirname(__dirname);
|
|
184
|
+
|
|
185
|
+
if (!skipSetup && process.stdin.isTTY) {
|
|
186
|
+
await runInteractiveInstall(packageDir, dirs);
|
|
187
|
+
} else {
|
|
188
|
+
runNonInteractiveInstall(packageDir, dirs);
|
|
195
189
|
}
|
|
190
|
+
printSummary(dirs.commandsDir);
|
|
191
|
+
} catch (error) {
|
|
192
|
+
printInstallError(error);
|
|
193
|
+
process.exit(1);
|
|
196
194
|
}
|
|
197
195
|
}
|
|
198
196
|
|
|
199
|
-
|
|
200
|
-
runSetup();
|
|
197
|
+
runSetup();
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Specialized debugging assistant with expertise in root cause analysis, error interpretation, and systematic troubleshooting"
|
|
3
|
+
tags: ["debugging", "error-analysis", "troubleshooting", "performance"]
|
|
4
|
+
tools: ["Read", "Bash", "Grep", "Edit", "Glob"]
|
|
5
|
+
---
|
|
6
|
+
|
|
1
7
|
# Debug Specialist Sub-Agent
|
|
2
8
|
|
|
3
9
|
## Agent Description
|
package/templates/README.md
CHANGED
|
@@ -59,6 +59,21 @@ cp templates/comprehensive-settings.json ~/.claude/settings.json
|
|
|
59
59
|
# Configure webhooks and organizational settings
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
+
### 4. `global-claude.md`
|
|
63
|
+
**Use case**: Universal development standards for all projects
|
|
64
|
+
**Features**:
|
|
65
|
+
- Verification-before-action rules (prevent fabricated references)
|
|
66
|
+
- Zero-error test policy
|
|
67
|
+
- Platform-specific formatting guidelines (LinkedIn, Slack, GitHub, email)
|
|
68
|
+
- Code structure limits (function length, nesting, complexity)
|
|
69
|
+
- Security checklist (no hardcoded secrets, parameterized SQL, input validation)
|
|
70
|
+
- Session management and failure protocols
|
|
71
|
+
|
|
72
|
+
**To use**:
|
|
73
|
+
```bash
|
|
74
|
+
cp templates/global-claude.md ~/.claude/CLAUDE.md
|
|
75
|
+
```
|
|
76
|
+
|
|
62
77
|
## Configuration Notes
|
|
63
78
|
|
|
64
79
|
### Settings Hierarchy
|
|
@@ -1,30 +1,44 @@
|
|
|
1
1
|
{
|
|
2
2
|
"// Basic Claude Code settings.json template": "Copy to ~/.claude/settings.json",
|
|
3
|
-
"//
|
|
3
|
+
"// Based on official Claude Code documentation": "https://docs.anthropic.com/en/docs/claude-code/settings",
|
|
4
4
|
|
|
5
|
-
"allowedTools":
|
|
6
|
-
|
|
7
|
-
"
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
"// Core tool permissions (replaces invalid 'allowedTools')": "",
|
|
6
|
+
"permissions": {
|
|
7
|
+
"allow": [
|
|
8
|
+
"Edit(*)",
|
|
9
|
+
"Bash(*)",
|
|
10
|
+
"Read(*)",
|
|
11
|
+
"Write(*)",
|
|
12
|
+
"MultiEdit(*)",
|
|
13
|
+
"Glob(*)",
|
|
14
|
+
"Grep(*)",
|
|
15
|
+
"LS(*)"
|
|
16
|
+
]
|
|
17
|
+
},
|
|
11
18
|
|
|
12
19
|
"// Basic hooks configuration": "",
|
|
13
20
|
"hooks": {
|
|
14
|
-
"PreToolUse": [
|
|
15
|
-
|
|
21
|
+
"PreToolUse": [
|
|
22
|
+
{
|
|
23
|
+
"matcher": "*",
|
|
24
|
+
"hooks": [
|
|
25
|
+
{
|
|
26
|
+
"type": "command",
|
|
27
|
+
"command": "echo 'Tool execution logged at $(date)' >> ~/.claude/logs/tool-usage.log"
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
}
|
|
31
|
+
]
|
|
16
32
|
},
|
|
17
33
|
|
|
18
|
-
"//
|
|
19
|
-
"
|
|
20
|
-
|
|
34
|
+
"// Standard Claude Code environment variables": "",
|
|
35
|
+
"env": {
|
|
36
|
+
"DISABLE_TELEMETRY": "1"
|
|
37
|
+
},
|
|
21
38
|
|
|
22
|
-
"//
|
|
23
|
-
"
|
|
39
|
+
"// Optional: Include Claude co-authorship in git commits": "",
|
|
40
|
+
"includeCoAuthoredBy": true,
|
|
24
41
|
|
|
25
|
-
"// Optional:
|
|
26
|
-
"
|
|
27
|
-
"CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "true",
|
|
28
|
-
"BASH_DEFAULT_TIMEOUT_MS": "120000"
|
|
29
|
-
}
|
|
42
|
+
"// Optional: Custom retention for chat transcripts (days)": "",
|
|
43
|
+
"cleanupPeriodDays": 30
|
|
30
44
|
}
|