@paulduvall/claude-dev-toolkit 0.0.1-alpha.2 → 0.0.1-alpha.21
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 +88 -37
- package/bin/claude-commands +307 -65
- package/commands/active/xarchitecture.md +393 -0
- package/commands/active/xconfig.md +127 -0
- package/commands/active/xcontinue.md +92 -0
- package/commands/active/xdebug.md +130 -0
- package/commands/active/xdocs.md +178 -0
- package/commands/active/xexplore.md +94 -0
- package/commands/active/xgit.md +149 -0
- package/commands/active/xpipeline.md +152 -0
- package/commands/active/xquality.md +96 -0
- package/commands/active/xrefactor.md +198 -0
- package/commands/active/xrelease.md +142 -0
- package/commands/active/xsecurity.md +92 -0
- package/commands/active/xspec.md +174 -0
- package/commands/active/xtdd.md +151 -0
- package/commands/active/xtest.md +89 -0
- package/commands/active/xverify.md +80 -0
- package/commands/experiments/xact.md +742 -0
- package/commands/experiments/xanalytics.md +113 -0
- package/commands/experiments/xanalyze.md +70 -0
- package/commands/experiments/xapi.md +161 -0
- package/commands/experiments/xatomic.md +112 -0
- package/commands/experiments/xaws.md +85 -0
- package/commands/experiments/xcicd.md +337 -0
- package/commands/experiments/xcommit.md +122 -0
- package/commands/experiments/xcompliance.md +182 -0
- package/commands/experiments/xconstraints.md +89 -0
- package/commands/experiments/xcoverage.md +90 -0
- package/commands/experiments/xdb.md +102 -0
- package/commands/experiments/xdesign.md +121 -0
- package/commands/experiments/xdevcontainer.md +238 -0
- package/commands/experiments/xevaluate.md +111 -0
- package/commands/experiments/xfootnote.md +12 -0
- package/commands/experiments/xgenerate.md +117 -0
- package/commands/experiments/xgovernance.md +149 -0
- package/commands/experiments/xgreen.md +66 -0
- package/commands/experiments/xiac.md +118 -0
- package/commands/experiments/xincident.md +137 -0
- package/commands/experiments/xinfra.md +115 -0
- package/commands/experiments/xknowledge.md +115 -0
- package/commands/experiments/xmaturity.md +120 -0
- package/commands/experiments/xmetrics.md +118 -0
- package/commands/experiments/xmonitoring.md +128 -0
- package/commands/experiments/xnew.md +903 -0
- package/commands/experiments/xobservable.md +114 -0
- package/commands/experiments/xoidc.md +165 -0
- package/commands/experiments/xoptimize.md +115 -0
- package/commands/experiments/xperformance.md +112 -0
- package/commands/experiments/xplanning.md +131 -0
- package/commands/experiments/xpolicy.md +115 -0
- package/commands/experiments/xproduct.md +98 -0
- package/commands/experiments/xreadiness.md +75 -0
- package/commands/experiments/xred.md +55 -0
- package/commands/experiments/xrisk.md +128 -0
- package/commands/experiments/xrules.md +124 -0
- package/commands/experiments/xsandbox.md +120 -0
- package/commands/experiments/xscan.md +102 -0
- package/commands/experiments/xsetup.md +123 -0
- package/commands/experiments/xtemplate.md +116 -0
- package/commands/experiments/xtrace.md +212 -0
- package/commands/experiments/xux.md +171 -0
- package/commands/experiments/xvalidate.md +104 -0
- package/commands/experiments/xworkflow.md +113 -0
- package/hooks/.smellrc.example.json +19 -0
- package/hooks/README.md +263 -0
- package/hooks/check-commit-signing.py +127 -0
- package/hooks/check-complexity.py +38 -0
- package/hooks/check-security.py +37 -0
- package/hooks/claude-wrapper.sh +29 -0
- package/hooks/config.py +110 -0
- package/hooks/file-logger.sh +100 -0
- package/hooks/lib/argument-parser.sh +427 -0
- package/hooks/lib/config-constants.sh +230 -0
- package/hooks/lib/context-manager.sh +560 -0
- package/hooks/lib/error-handler.sh +423 -0
- package/hooks/lib/execution-engine.sh +444 -0
- 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 +398 -0
- package/hooks/lib/subagent-discovery.sh +468 -0
- package/hooks/lib/subagent-validator.sh +407 -0
- package/hooks/lib/validation-reporter.sh +134 -0
- package/hooks/on-error-debug.sh +226 -0
- package/hooks/pre-commit-quality.sh +204 -0
- package/hooks/pre-commit-test-runner.sh +132 -0
- package/hooks/pre-write-security.sh +115 -0
- package/hooks/prevent-credential-exposure.sh +279 -0
- package/hooks/security_bandit.py +177 -0
- package/hooks/security_checks.py +97 -0
- package/hooks/security_secrets.py +81 -0
- package/hooks/security_trojan.py +61 -0
- package/hooks/settings.example.json +52 -0
- package/hooks/smell_checks.py +238 -0
- package/hooks/smell_javascript.py +231 -0
- package/hooks/smell_python.py +110 -0
- package/hooks/smell_ruff.py +70 -0
- package/hooks/smell_types.py +72 -0
- package/hooks/subagent-trigger-simple.sh +202 -0
- package/hooks/subagent-trigger.sh +253 -0
- package/hooks/suppression.py +82 -0
- package/hooks/tab-color.sh +70 -0
- package/hooks/verify-before-edit.sh +135 -0
- package/lib/backup-restore-command.js +140 -0
- package/lib/base/base-command.js +252 -0
- package/lib/base/command-result.js +184 -0
- package/lib/config/constants.js +255 -0
- package/lib/config.js +48 -6
- package/lib/configure-command.js +428 -0
- package/lib/dependency-validator.js +64 -5
- package/lib/hook-installer-core.js +2 -2
- package/lib/installation-instruction-generator.js +213 -495
- package/lib/installer.js +134 -56
- package/lib/oidc-command.js +740 -0
- package/lib/services/backup-list-service.js +226 -0
- package/lib/services/backup-service.js +230 -0
- package/lib/services/command-installer-service.js +217 -0
- package/lib/services/logger-service.js +201 -0
- package/lib/services/package-manager-service.js +319 -0
- package/lib/services/platform-instruction-service.js +294 -0
- package/lib/services/recovery-instruction-service.js +348 -0
- package/lib/services/restore-service.js +221 -0
- package/lib/setup-command.js +359 -0
- package/lib/setup-wizard.js +155 -262
- package/lib/uninstall-command.js +100 -0
- package/lib/utils/claude-path-config.js +184 -0
- package/lib/utils/file-system-utils.js +152 -0
- package/lib/utils.js +8 -4
- package/lib/verify-command.js +430 -0
- package/package.json +7 -3
- package/scripts/postinstall.js +172 -157
- package/subagents/debug-specialist.md +7 -0
- package/templates/README.md +115 -0
- package/templates/basic-settings.json +30 -0
- package/templates/comprehensive-settings.json +57 -0
- package/templates/global-claude.md +344 -0
- package/templates/hybrid-hook-config.yaml +132 -0
- package/templates/security-focused-settings.json +62 -0
- package/templates/subagent-hooks.yaml +188 -0
- package/lib/package-manager-service.js +0 -270
- package/subagents/debug-context.md +0 -197
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Path Configuration
|
|
3
|
+
* Centralized path management for Claude Code directories
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const os = require('os');
|
|
8
|
+
|
|
9
|
+
class ClaudePathConfig {
|
|
10
|
+
constructor(homeDir = os.homedir()) {
|
|
11
|
+
this.homeDir = homeDir;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Main Claude directory
|
|
16
|
+
*/
|
|
17
|
+
get claudeDir() {
|
|
18
|
+
return path.join(this.homeDir, '.claude');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Commands directory
|
|
23
|
+
*/
|
|
24
|
+
get commandsDir() {
|
|
25
|
+
return path.join(this.claudeDir, 'commands');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Settings file path
|
|
30
|
+
*/
|
|
31
|
+
get settingsPath() {
|
|
32
|
+
return path.join(this.claudeDir, 'settings.json');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Backups directory
|
|
37
|
+
*/
|
|
38
|
+
get backupsDir() {
|
|
39
|
+
return path.join(this.claudeDir, 'backups');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Settings backups directory
|
|
44
|
+
*/
|
|
45
|
+
get settingsBackupsDir() {
|
|
46
|
+
return path.join(this.backupsDir, 'settings');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Commands backups directory
|
|
51
|
+
*/
|
|
52
|
+
get commandsBackupsDir() {
|
|
53
|
+
return path.join(this.backupsDir, 'commands');
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Hooks directory
|
|
58
|
+
*/
|
|
59
|
+
get hooksDir() {
|
|
60
|
+
return path.join(this.claudeDir, 'hooks');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Subagents directory
|
|
65
|
+
*/
|
|
66
|
+
get subagentsDir() {
|
|
67
|
+
return path.join(this.claudeDir, 'subagents');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Templates directory (in package)
|
|
72
|
+
*/
|
|
73
|
+
get templatesDir() {
|
|
74
|
+
return path.join(__dirname, '..', '..', 'templates');
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Package commands directory (active)
|
|
79
|
+
*/
|
|
80
|
+
get packageActiveCommandsDir() {
|
|
81
|
+
return path.join(__dirname, '..', '..', 'commands', 'active');
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Package commands directory (experiments)
|
|
86
|
+
*/
|
|
87
|
+
get packageExperimentalCommandsDir() {
|
|
88
|
+
return path.join(__dirname, '..', '..', 'commands', 'experiments');
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Package hooks directory
|
|
93
|
+
*/
|
|
94
|
+
get packageHooksDir() {
|
|
95
|
+
return path.join(__dirname, '..', '..', 'hooks');
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Package subagents directory
|
|
100
|
+
*/
|
|
101
|
+
get packageSubagentsDir() {
|
|
102
|
+
return path.join(__dirname, '..', '..', 'subagents');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Get all user directories that might need creation
|
|
107
|
+
*/
|
|
108
|
+
getUserDirectories() {
|
|
109
|
+
return [
|
|
110
|
+
this.claudeDir,
|
|
111
|
+
this.commandsDir,
|
|
112
|
+
this.backupsDir,
|
|
113
|
+
this.settingsBackupsDir,
|
|
114
|
+
this.commandsBackupsDir,
|
|
115
|
+
this.hooksDir,
|
|
116
|
+
this.subagentsDir
|
|
117
|
+
];
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Get all package directories for validation
|
|
122
|
+
*/
|
|
123
|
+
getPackageDirectories() {
|
|
124
|
+
return [
|
|
125
|
+
this.templatesDir,
|
|
126
|
+
this.packageActiveCommandsDir,
|
|
127
|
+
this.packageExperimentalCommandsDir,
|
|
128
|
+
this.packageHooksDir,
|
|
129
|
+
this.packageSubagentsDir
|
|
130
|
+
];
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Create a backup path with timestamp
|
|
135
|
+
*/
|
|
136
|
+
createBackupPath(name, type = 'general') {
|
|
137
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').split('.')[0];
|
|
138
|
+
const backupName = name || `backup-${timestamp}`;
|
|
139
|
+
|
|
140
|
+
switch (type) {
|
|
141
|
+
case 'settings':
|
|
142
|
+
return path.join(this.settingsBackupsDir, `${backupName}.json`);
|
|
143
|
+
case 'commands':
|
|
144
|
+
return path.join(this.commandsBackupsDir, backupName);
|
|
145
|
+
default:
|
|
146
|
+
return path.join(this.backupsDir, backupName);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Resolve template path from name
|
|
152
|
+
*/
|
|
153
|
+
resolveTemplatePath(templateName) {
|
|
154
|
+
const variations = [
|
|
155
|
+
templateName,
|
|
156
|
+
`${templateName}.json`,
|
|
157
|
+
`${templateName}-settings.json`
|
|
158
|
+
];
|
|
159
|
+
|
|
160
|
+
// Common aliases
|
|
161
|
+
const aliases = {
|
|
162
|
+
'basic': 'basic-settings.json',
|
|
163
|
+
'comprehensive': 'comprehensive-settings.json',
|
|
164
|
+
'security': 'security-focused-settings.json',
|
|
165
|
+
'security-focused': 'security-focused-settings.json'
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
if (aliases[templateName]) {
|
|
169
|
+
variations.unshift(aliases[templateName]);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
for (const variant of variations) {
|
|
173
|
+
const fullPath = path.join(this.templatesDir, variant);
|
|
174
|
+
const fs = require('fs');
|
|
175
|
+
if (fs.existsSync(fullPath)) {
|
|
176
|
+
return fullPath;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return null;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
module.exports = ClaudePathConfig;
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File System Utilities
|
|
3
|
+
* Extracted common file system operations used across commands
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
const os = require('os');
|
|
9
|
+
|
|
10
|
+
class FileSystemUtils {
|
|
11
|
+
/**
|
|
12
|
+
* Format file size for human-readable display
|
|
13
|
+
*/
|
|
14
|
+
static formatSize(bytes) {
|
|
15
|
+
const units = ['B', 'KB', 'MB', 'GB'];
|
|
16
|
+
let size = bytes;
|
|
17
|
+
let unitIndex = 0;
|
|
18
|
+
|
|
19
|
+
while (size >= 1024 && unitIndex < units.length - 1) {
|
|
20
|
+
size /= 1024;
|
|
21
|
+
unitIndex++;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return `${size.toFixed(2)} ${units[unitIndex]}`;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Calculate directory size recursively
|
|
29
|
+
*/
|
|
30
|
+
static getDirectorySize(dirPath) {
|
|
31
|
+
let size = 0;
|
|
32
|
+
|
|
33
|
+
try {
|
|
34
|
+
const entries = fs.readdirSync(dirPath);
|
|
35
|
+
entries.forEach(entry => {
|
|
36
|
+
const fullPath = path.join(dirPath, entry);
|
|
37
|
+
const stats = fs.statSync(fullPath);
|
|
38
|
+
|
|
39
|
+
if (stats.isDirectory()) {
|
|
40
|
+
size += this.getDirectorySize(fullPath);
|
|
41
|
+
} else {
|
|
42
|
+
size += stats.size;
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
} catch (error) {
|
|
46
|
+
// Ignore errors and return partial size
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return size;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Ensure directory exists with proper permissions
|
|
54
|
+
*/
|
|
55
|
+
static ensureDirectory(dirPath, mode = 0o755) {
|
|
56
|
+
if (!fs.existsSync(dirPath)) {
|
|
57
|
+
fs.mkdirSync(dirPath, { recursive: true, mode });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Copy file with error handling
|
|
63
|
+
*/
|
|
64
|
+
static copyFile(source, destination, mode = 0o644) {
|
|
65
|
+
try {
|
|
66
|
+
fs.copyFileSync(source, destination);
|
|
67
|
+
fs.chmodSync(destination, mode);
|
|
68
|
+
return true;
|
|
69
|
+
} catch (error) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Check if path exists and is readable
|
|
76
|
+
*/
|
|
77
|
+
static isReadable(filePath) {
|
|
78
|
+
try {
|
|
79
|
+
fs.accessSync(filePath, fs.constants.R_OK);
|
|
80
|
+
return true;
|
|
81
|
+
} catch (error) {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Check if path exists and is writable
|
|
88
|
+
*/
|
|
89
|
+
static isWritable(filePath) {
|
|
90
|
+
try {
|
|
91
|
+
fs.accessSync(filePath, fs.constants.W_OK);
|
|
92
|
+
return true;
|
|
93
|
+
} catch (error) {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Get file stats safely
|
|
100
|
+
*/
|
|
101
|
+
static getStats(filePath) {
|
|
102
|
+
try {
|
|
103
|
+
return fs.statSync(filePath);
|
|
104
|
+
} catch (error) {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Read file safely with encoding
|
|
111
|
+
*/
|
|
112
|
+
static readFile(filePath, encoding = 'utf8') {
|
|
113
|
+
try {
|
|
114
|
+
return fs.readFileSync(filePath, encoding);
|
|
115
|
+
} catch (error) {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Write file safely with mode
|
|
122
|
+
*/
|
|
123
|
+
static writeFile(filePath, content, mode = 0o644) {
|
|
124
|
+
try {
|
|
125
|
+
fs.writeFileSync(filePath, content, { mode });
|
|
126
|
+
return true;
|
|
127
|
+
} catch (error) {
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Remove file or directory safely
|
|
134
|
+
*/
|
|
135
|
+
static remove(targetPath) {
|
|
136
|
+
try {
|
|
137
|
+
if (fs.existsSync(targetPath)) {
|
|
138
|
+
const stats = fs.statSync(targetPath);
|
|
139
|
+
if (stats.isDirectory()) {
|
|
140
|
+
fs.rmSync(targetPath, { recursive: true, force: true });
|
|
141
|
+
} else {
|
|
142
|
+
fs.unlinkSync(targetPath);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return true;
|
|
146
|
+
} catch (error) {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
module.exports = FileSystemUtils;
|
package/lib/utils.js
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
// Utility functions for Claude Dev Toolkit
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const fs = require('fs');
|
|
4
|
+
const FileSystemUtils = require('./utils/file-system-utils');
|
|
4
5
|
|
|
5
6
|
module.exports = {
|
|
7
|
+
// Keep backward compatibility
|
|
6
8
|
ensureDirectory: (dirPath) => {
|
|
7
|
-
|
|
8
|
-
fs.mkdirSync(dirPath, { recursive: true });
|
|
9
|
-
}
|
|
9
|
+
FileSystemUtils.ensureDirectory(dirPath);
|
|
10
10
|
},
|
|
11
11
|
|
|
12
12
|
isValidCommand: (commandName) => {
|
|
13
13
|
return /^[a-z][a-z0-9-]*$/.test(commandName);
|
|
14
|
-
}
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
// Export new utilities for migration
|
|
17
|
+
FileSystemUtils,
|
|
18
|
+
ClaudePathConfig: require('./utils/claude-path-config')
|
|
15
19
|
};
|