@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.
Files changed (143) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +88 -37
  3. package/bin/claude-commands +307 -65
  4. package/commands/active/xarchitecture.md +393 -0
  5. package/commands/active/xconfig.md +127 -0
  6. package/commands/active/xcontinue.md +92 -0
  7. package/commands/active/xdebug.md +130 -0
  8. package/commands/active/xdocs.md +178 -0
  9. package/commands/active/xexplore.md +94 -0
  10. package/commands/active/xgit.md +149 -0
  11. package/commands/active/xpipeline.md +152 -0
  12. package/commands/active/xquality.md +96 -0
  13. package/commands/active/xrefactor.md +198 -0
  14. package/commands/active/xrelease.md +142 -0
  15. package/commands/active/xsecurity.md +92 -0
  16. package/commands/active/xspec.md +174 -0
  17. package/commands/active/xtdd.md +151 -0
  18. package/commands/active/xtest.md +89 -0
  19. package/commands/active/xverify.md +80 -0
  20. package/commands/experiments/xact.md +742 -0
  21. package/commands/experiments/xanalytics.md +113 -0
  22. package/commands/experiments/xanalyze.md +70 -0
  23. package/commands/experiments/xapi.md +161 -0
  24. package/commands/experiments/xatomic.md +112 -0
  25. package/commands/experiments/xaws.md +85 -0
  26. package/commands/experiments/xcicd.md +337 -0
  27. package/commands/experiments/xcommit.md +122 -0
  28. package/commands/experiments/xcompliance.md +182 -0
  29. package/commands/experiments/xconstraints.md +89 -0
  30. package/commands/experiments/xcoverage.md +90 -0
  31. package/commands/experiments/xdb.md +102 -0
  32. package/commands/experiments/xdesign.md +121 -0
  33. package/commands/experiments/xdevcontainer.md +238 -0
  34. package/commands/experiments/xevaluate.md +111 -0
  35. package/commands/experiments/xfootnote.md +12 -0
  36. package/commands/experiments/xgenerate.md +117 -0
  37. package/commands/experiments/xgovernance.md +149 -0
  38. package/commands/experiments/xgreen.md +66 -0
  39. package/commands/experiments/xiac.md +118 -0
  40. package/commands/experiments/xincident.md +137 -0
  41. package/commands/experiments/xinfra.md +115 -0
  42. package/commands/experiments/xknowledge.md +115 -0
  43. package/commands/experiments/xmaturity.md +120 -0
  44. package/commands/experiments/xmetrics.md +118 -0
  45. package/commands/experiments/xmonitoring.md +128 -0
  46. package/commands/experiments/xnew.md +903 -0
  47. package/commands/experiments/xobservable.md +114 -0
  48. package/commands/experiments/xoidc.md +165 -0
  49. package/commands/experiments/xoptimize.md +115 -0
  50. package/commands/experiments/xperformance.md +112 -0
  51. package/commands/experiments/xplanning.md +131 -0
  52. package/commands/experiments/xpolicy.md +115 -0
  53. package/commands/experiments/xproduct.md +98 -0
  54. package/commands/experiments/xreadiness.md +75 -0
  55. package/commands/experiments/xred.md +55 -0
  56. package/commands/experiments/xrisk.md +128 -0
  57. package/commands/experiments/xrules.md +124 -0
  58. package/commands/experiments/xsandbox.md +120 -0
  59. package/commands/experiments/xscan.md +102 -0
  60. package/commands/experiments/xsetup.md +123 -0
  61. package/commands/experiments/xtemplate.md +116 -0
  62. package/commands/experiments/xtrace.md +212 -0
  63. package/commands/experiments/xux.md +171 -0
  64. package/commands/experiments/xvalidate.md +104 -0
  65. package/commands/experiments/xworkflow.md +113 -0
  66. package/hooks/.smellrc.example.json +19 -0
  67. package/hooks/README.md +263 -0
  68. package/hooks/check-commit-signing.py +127 -0
  69. package/hooks/check-complexity.py +38 -0
  70. package/hooks/check-security.py +37 -0
  71. package/hooks/claude-wrapper.sh +29 -0
  72. package/hooks/config.py +110 -0
  73. package/hooks/file-logger.sh +100 -0
  74. package/hooks/lib/argument-parser.sh +427 -0
  75. package/hooks/lib/config-constants.sh +230 -0
  76. package/hooks/lib/context-manager.sh +560 -0
  77. package/hooks/lib/error-handler.sh +423 -0
  78. package/hooks/lib/execution-engine.sh +444 -0
  79. package/hooks/lib/execution-results.sh +113 -0
  80. package/hooks/lib/execution-simulation.sh +114 -0
  81. package/hooks/lib/field-validators.sh +104 -0
  82. package/hooks/lib/file-utils.sh +398 -0
  83. package/hooks/lib/subagent-discovery.sh +468 -0
  84. package/hooks/lib/subagent-validator.sh +407 -0
  85. package/hooks/lib/validation-reporter.sh +134 -0
  86. package/hooks/on-error-debug.sh +226 -0
  87. package/hooks/pre-commit-quality.sh +204 -0
  88. package/hooks/pre-commit-test-runner.sh +132 -0
  89. package/hooks/pre-write-security.sh +115 -0
  90. package/hooks/prevent-credential-exposure.sh +279 -0
  91. package/hooks/security_bandit.py +177 -0
  92. package/hooks/security_checks.py +97 -0
  93. package/hooks/security_secrets.py +81 -0
  94. package/hooks/security_trojan.py +61 -0
  95. package/hooks/settings.example.json +52 -0
  96. package/hooks/smell_checks.py +238 -0
  97. package/hooks/smell_javascript.py +231 -0
  98. package/hooks/smell_python.py +110 -0
  99. package/hooks/smell_ruff.py +70 -0
  100. package/hooks/smell_types.py +72 -0
  101. package/hooks/subagent-trigger-simple.sh +202 -0
  102. package/hooks/subagent-trigger.sh +253 -0
  103. package/hooks/suppression.py +82 -0
  104. package/hooks/tab-color.sh +70 -0
  105. package/hooks/verify-before-edit.sh +135 -0
  106. package/lib/backup-restore-command.js +140 -0
  107. package/lib/base/base-command.js +252 -0
  108. package/lib/base/command-result.js +184 -0
  109. package/lib/config/constants.js +255 -0
  110. package/lib/config.js +48 -6
  111. package/lib/configure-command.js +428 -0
  112. package/lib/dependency-validator.js +64 -5
  113. package/lib/hook-installer-core.js +2 -2
  114. package/lib/installation-instruction-generator.js +213 -495
  115. package/lib/installer.js +134 -56
  116. package/lib/oidc-command.js +740 -0
  117. package/lib/services/backup-list-service.js +226 -0
  118. package/lib/services/backup-service.js +230 -0
  119. package/lib/services/command-installer-service.js +217 -0
  120. package/lib/services/logger-service.js +201 -0
  121. package/lib/services/package-manager-service.js +319 -0
  122. package/lib/services/platform-instruction-service.js +294 -0
  123. package/lib/services/recovery-instruction-service.js +348 -0
  124. package/lib/services/restore-service.js +221 -0
  125. package/lib/setup-command.js +359 -0
  126. package/lib/setup-wizard.js +155 -262
  127. package/lib/uninstall-command.js +100 -0
  128. package/lib/utils/claude-path-config.js +184 -0
  129. package/lib/utils/file-system-utils.js +152 -0
  130. package/lib/utils.js +8 -4
  131. package/lib/verify-command.js +430 -0
  132. package/package.json +7 -3
  133. package/scripts/postinstall.js +172 -157
  134. package/subagents/debug-specialist.md +7 -0
  135. package/templates/README.md +115 -0
  136. package/templates/basic-settings.json +30 -0
  137. package/templates/comprehensive-settings.json +57 -0
  138. package/templates/global-claude.md +344 -0
  139. package/templates/hybrid-hook-config.yaml +132 -0
  140. package/templates/security-focused-settings.json +62 -0
  141. package/templates/subagent-hooks.yaml +188 -0
  142. package/lib/package-manager-service.js +0 -270
  143. package/subagents/debug-context.md +0 -197
@@ -0,0 +1,201 @@
1
+ /**
2
+ * Centralized Logger Service
3
+ * Provides consistent logging across the entire application with context support
4
+ */
5
+
6
+ class LoggerService {
7
+ constructor(options = {}) {
8
+ this.options = {
9
+ timestamp: options.timestamp ?? true,
10
+ context: options.context ?? true,
11
+ colors: options.colors ?? true,
12
+ level: options.level ?? 'info' // debug, info, warn, error
13
+ };
14
+ this.contextData = {};
15
+ }
16
+
17
+ /**
18
+ * Set persistent context data for all log messages
19
+ */
20
+ setContext(context) {
21
+ this.contextData = { ...this.contextData, ...context };
22
+ }
23
+
24
+ /**
25
+ * Clear all context data
26
+ */
27
+ clearContext() {
28
+ this.contextData = {};
29
+ }
30
+
31
+ /**
32
+ * Success message logging
33
+ */
34
+ success(message, context = {}) {
35
+ this._log('success', '✅', message, context);
36
+ }
37
+
38
+ /**
39
+ * Information message logging
40
+ */
41
+ info(message, context = {}) {
42
+ this._log('info', 'ℹ️', message, context);
43
+ }
44
+
45
+ /**
46
+ * Warning message logging
47
+ */
48
+ warn(message, context = {}) {
49
+ this._log('warn', '⚠️', message, context);
50
+ }
51
+
52
+ /**
53
+ * Error message logging
54
+ */
55
+ error(message, error = null, context = {}) {
56
+ const errorContext = error ? { error: this._serializeError(error), ...context } : context;
57
+ this._log('error', '❌', message, errorContext);
58
+ }
59
+
60
+ /**
61
+ * Debug message logging
62
+ */
63
+ debug(message, context = {}) {
64
+ if (this.options.level === 'debug') {
65
+ this._log('debug', '🔍', message, context);
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Step progress logging
71
+ */
72
+ step(message, context = {}) {
73
+ this._log('step', '🔄', message, context);
74
+ }
75
+
76
+ /**
77
+ * Completion logging
78
+ */
79
+ complete(message, context = {}) {
80
+ this._log('complete', '🎉', message, context);
81
+ }
82
+
83
+ /**
84
+ * Progress logging with metrics
85
+ */
86
+ progress(message, current, total, context = {}) {
87
+ const progressContext = { current, total, percentage: Math.round((current / total) * 100), ...context };
88
+ this._log('progress', '📊', message, progressContext);
89
+ }
90
+
91
+ /**
92
+ * Internal logging method
93
+ */
94
+ _log(level, icon, message, context = {}) {
95
+ const timestamp = this.options.timestamp ? `[${new Date().toISOString()}]` : '';
96
+ const fullContext = { ...this.contextData, ...context };
97
+
98
+ let logMessage = `${timestamp} ${icon} ${message}`;
99
+
100
+ // Add context if enabled and present
101
+ if (this.options.context && Object.keys(fullContext).length > 0) {
102
+ const contextStr = this._formatContext(fullContext);
103
+ if (contextStr) {
104
+ logMessage += ` ${contextStr}`;
105
+ }
106
+ }
107
+
108
+ // Route to appropriate console method
109
+ switch (level) {
110
+ case 'error':
111
+ console.error(logMessage);
112
+ break;
113
+ case 'warn':
114
+ console.warn(logMessage);
115
+ break;
116
+ case 'debug':
117
+ console.debug(logMessage);
118
+ break;
119
+ default:
120
+ console.log(logMessage);
121
+ }
122
+ }
123
+
124
+ /**
125
+ * Format context data for display
126
+ */
127
+ _formatContext(context) {
128
+ try {
129
+ // Filter out complex objects and functions
130
+ const filteredContext = {};
131
+ for (const [key, value] of Object.entries(context)) {
132
+ if (value !== null && value !== undefined) {
133
+ if (typeof value === 'object' && !Array.isArray(value)) {
134
+ // Include only simple object properties
135
+ if (Object.keys(value).length < 5) {
136
+ filteredContext[key] = value;
137
+ } else {
138
+ filteredContext[key] = `[Object with ${Object.keys(value).length} keys]`;
139
+ }
140
+ } else if (typeof value !== 'function') {
141
+ filteredContext[key] = value;
142
+ }
143
+ }
144
+ }
145
+
146
+ if (Object.keys(filteredContext).length === 0) {
147
+ return '';
148
+ }
149
+
150
+ return JSON.stringify(filteredContext);
151
+ } catch (error) {
152
+ return `[Context formatting error: ${error.message}]`;
153
+ }
154
+ }
155
+
156
+ /**
157
+ * Serialize error objects for logging
158
+ */
159
+ _serializeError(error) {
160
+ if (!error) return null;
161
+
162
+ return {
163
+ name: error.name,
164
+ message: error.message,
165
+ code: error.code,
166
+ stack: error.stack?.split('\n').slice(0, 3).join('\n') // First 3 lines of stack
167
+ };
168
+ }
169
+
170
+ /**
171
+ * Create a scoped logger with persistent context
172
+ */
173
+ scope(scopeName, context = {}) {
174
+ const scopedLogger = new LoggerService(this.options);
175
+ scopedLogger.setContext({ scope: scopeName, ...this.contextData, ...context });
176
+ return scopedLogger;
177
+ }
178
+
179
+ /**
180
+ * Performance timing utilities
181
+ */
182
+ time(label) {
183
+ console.time(`⏱️ ${label}`);
184
+ }
185
+
186
+ timeEnd(label) {
187
+ console.timeEnd(`⏱️ ${label}`);
188
+ }
189
+
190
+ /**
191
+ * Table logging for structured data
192
+ */
193
+ table(data, message = '') {
194
+ if (message) {
195
+ this.info(message);
196
+ }
197
+ console.table(data);
198
+ }
199
+ }
200
+
201
+ module.exports = LoggerService;
@@ -0,0 +1,319 @@
1
+ /**
2
+ * Package Manager Service
3
+ * Handles package manager detection, validation, and instruction generation
4
+ */
5
+
6
+ const { execSync } = require('child_process');
7
+ const { PACKAGE_MANAGERS } = require('../config/constants');
8
+
9
+ class PackageManagerService {
10
+ constructor() {
11
+ this.packageManagers = PACKAGE_MANAGERS;
12
+ this.detectedManagers = null;
13
+ }
14
+
15
+ /**
16
+ * Detect available package managers on the system
17
+ * @returns {Array} Available package managers
18
+ */
19
+ detectAvailablePackageManagers() {
20
+ if (this.detectedManagers) {
21
+ return this.detectedManagers;
22
+ }
23
+
24
+ const available = [];
25
+
26
+ Object.keys(this.packageManagers).forEach(manager => {
27
+ if (this.isPackageManagerAvailable(manager)) {
28
+ const managerInfo = this.packageManagers[manager];
29
+ available.push({
30
+ name: manager,
31
+ displayName: managerInfo.name,
32
+ version: this.getPackageManagerVersion(manager),
33
+ installCommand: managerInfo.install,
34
+ globalInstallCommand: managerInfo.globalInstall,
35
+ updateCommand: managerInfo.update
36
+ });
37
+ }
38
+ });
39
+
40
+ this.detectedManagers = available;
41
+ return available;
42
+ }
43
+
44
+ /**
45
+ * Check if a package manager is available on the system
46
+ * @param {string} manager - Package manager name
47
+ * @returns {boolean} Is available
48
+ */
49
+ isPackageManagerAvailable(manager) {
50
+ const managerInfo = this.packageManagers[manager];
51
+ if (!managerInfo || !managerInfo.checkCommand) {
52
+ return false;
53
+ }
54
+
55
+ // Check platform compatibility
56
+ if (managerInfo.platforms && !managerInfo.platforms.includes(process.platform)) {
57
+ return false;
58
+ }
59
+
60
+ try {
61
+ execSync(managerInfo.checkCommand, {
62
+ stdio: 'pipe',
63
+ timeout: 5000,
64
+ encoding: 'utf8'
65
+ });
66
+ return true;
67
+ } catch (error) {
68
+ return false;
69
+ }
70
+ }
71
+
72
+ /**
73
+ * Get version of a package manager
74
+ * @param {string} manager - Package manager name
75
+ * @returns {string|null} Version string or null if not available
76
+ */
77
+ getPackageManagerVersion(manager) {
78
+ const managerInfo = this.packageManagers[manager];
79
+ if (!managerInfo || !managerInfo.checkCommand) {
80
+ return null;
81
+ }
82
+
83
+ try {
84
+ const output = execSync(managerInfo.checkCommand, {
85
+ stdio: 'pipe',
86
+ timeout: 5000,
87
+ encoding: 'utf8'
88
+ });
89
+ return output.trim();
90
+ } catch (error) {
91
+ return null;
92
+ }
93
+ }
94
+
95
+ /**
96
+ * Get recommended package manager for platform
97
+ * @param {string} platform - Target platform
98
+ * @returns {string} Recommended package manager name
99
+ */
100
+ getRecommendedPackageManager(platform = process.platform) {
101
+ const platformRecommendations = {
102
+ linux: 'apt',
103
+ darwin: 'brew',
104
+ win32: 'npm'
105
+ };
106
+
107
+ const recommended = platformRecommendations[platform] || 'npm';
108
+
109
+ // Check if recommended manager is available
110
+ if (this.isPackageManagerAvailable(recommended)) {
111
+ return recommended;
112
+ }
113
+
114
+ // Fall back to any available manager
115
+ const available = this.detectAvailablePackageManagers();
116
+ return available.length > 0 ? available[0].name : 'npm';
117
+ }
118
+
119
+ /**
120
+ * Generate installation instructions for multiple package managers
121
+ * @param {string} packageName - Package to install
122
+ * @param {Object} options - Installation options
123
+ * @returns {Array} Installation instructions for different package managers
124
+ */
125
+ generateInstallationInstructions(packageName, options = {}) {
126
+ const instructions = [];
127
+ const availableManagers = this.detectAvailablePackageManagers();
128
+
129
+ if (availableManagers.length === 0) {
130
+ return [{
131
+ manager: 'none',
132
+ error: 'No package managers detected on this system',
133
+ installUrl: this.packageManagers.npm.installUrl
134
+ }];
135
+ }
136
+
137
+ availableManagers.forEach(manager => {
138
+ const instruction = this._generateManagerInstruction(manager, packageName, options);
139
+ if (instruction) {
140
+ instructions.push(instruction);
141
+ }
142
+ });
143
+
144
+ // Sort by recommendation (recommended first)
145
+ const recommended = this.getRecommendedPackageManager();
146
+ instructions.sort((a, b) => {
147
+ if (a.manager === recommended) return -1;
148
+ if (b.manager === recommended) return 1;
149
+ return 0;
150
+ });
151
+
152
+ return instructions;
153
+ }
154
+
155
+ /**
156
+ * Generate instruction for specific package manager
157
+ * @param {Object} manager - Manager information
158
+ * @param {string} packageName - Package to install
159
+ * @param {Object} options - Installation options
160
+ * @returns {Object} Installation instruction
161
+ * @private
162
+ */
163
+ _generateManagerInstruction(manager, packageName, options) {
164
+ const command = options.global ?
165
+ manager.globalInstallCommand || manager.installCommand :
166
+ manager.installCommand;
167
+
168
+ const version = options.version ? `@${options.version}` : '';
169
+ const fullPackageName = `${packageName}${version}`;
170
+
171
+ return {
172
+ manager: manager.name,
173
+ displayName: manager.displayName,
174
+ command: `${command} ${fullPackageName}`,
175
+ version: manager.version,
176
+ global: options.global || false,
177
+ recommended: manager.name === this.getRecommendedPackageManager(),
178
+ notes: this._getManagerSpecificNotes(manager.name, options)
179
+ };
180
+ }
181
+
182
+ /**
183
+ * Get manager-specific installation notes
184
+ * @param {string} managerName - Package manager name
185
+ * @param {Object} options - Installation options
186
+ * @returns {Array} Installation notes
187
+ * @private
188
+ */
189
+ _getManagerSpecificNotes(managerName, options) {
190
+ const notes = [];
191
+
192
+ switch (managerName) {
193
+ case 'npm':
194
+ if (options.global) {
195
+ notes.push('Global installation may require administrator privileges');
196
+ }
197
+ notes.push('Use "npm list" to verify installation');
198
+ break;
199
+
200
+ case 'yarn':
201
+ if (options.global) {
202
+ notes.push('Yarn global installation location may not be in PATH');
203
+ }
204
+ notes.push('Yarn provides faster and more reliable dependency resolution');
205
+ break;
206
+
207
+ case 'pnpm':
208
+ notes.push('pnpm saves disk space by using a content-addressable store');
209
+ if (options.global) {
210
+ notes.push('pnpm global packages are stored in a separate location');
211
+ }
212
+ break;
213
+
214
+ case 'brew':
215
+ notes.push('Homebrew automatically handles dependencies');
216
+ notes.push('Update Homebrew regularly: brew update && brew upgrade');
217
+ break;
218
+
219
+ case 'apt':
220
+ notes.push('May require "sudo" for system-wide installation');
221
+ notes.push('Update package lists first: sudo apt update');
222
+ break;
223
+
224
+ case 'chocolatey':
225
+ notes.push('Run PowerShell as Administrator');
226
+ notes.push('Chocolatey packages are community maintained');
227
+ break;
228
+
229
+ case 'winget':
230
+ notes.push('winget is the official Windows package manager');
231
+ notes.push('Available on Windows 10 1709+ and Windows 11');
232
+ break;
233
+ }
234
+
235
+ return notes;
236
+ }
237
+
238
+ /**
239
+ * Validate package manager installation
240
+ * @param {string} manager - Package manager name
241
+ * @returns {Object} Validation result
242
+ */
243
+ validatePackageManager(manager) {
244
+ const managerInfo = this.packageManagers[manager];
245
+
246
+ if (!managerInfo) {
247
+ return {
248
+ valid: false,
249
+ error: `Unknown package manager: ${manager}`,
250
+ suggestions: ['Use npm, yarn, or pnpm for Node.js packages']
251
+ };
252
+ }
253
+
254
+ // Check platform compatibility
255
+ if (managerInfo.platforms && !managerInfo.platforms.includes(process.platform)) {
256
+ return {
257
+ valid: false,
258
+ error: `${managerInfo.name} is not available on ${process.platform}`,
259
+ suggestions: [
260
+ `Try ${this.getRecommendedPackageManager()} instead`,
261
+ `Install ${managerInfo.name} from ${managerInfo.installUrl || 'official website'}`
262
+ ]
263
+ };
264
+ }
265
+
266
+ // Check if manager is available
267
+ if (!this.isPackageManagerAvailable(manager)) {
268
+ return {
269
+ valid: false,
270
+ error: `${managerInfo.name} is not installed or not in PATH`,
271
+ installUrl: managerInfo.installUrl,
272
+ suggestions: [
273
+ `Install ${managerInfo.name} from ${managerInfo.installUrl || 'official website'}`,
274
+ `Add ${managerInfo.name} to your system PATH`,
275
+ `Use alternative package manager: ${this.getRecommendedPackageManager()}`
276
+ ]
277
+ };
278
+ }
279
+
280
+ return {
281
+ valid: true,
282
+ manager: managerInfo.name,
283
+ version: this.getPackageManagerVersion(manager),
284
+ commands: {
285
+ install: managerInfo.install,
286
+ globalInstall: managerInfo.globalInstall,
287
+ update: managerInfo.update
288
+ }
289
+ };
290
+ }
291
+
292
+ /**
293
+ * Get installation command for specific package and manager
294
+ * @param {string} manager - Package manager name
295
+ * @param {string} packageName - Package to install
296
+ * @param {Object} options - Installation options
297
+ * @returns {string|null} Installation command
298
+ */
299
+ getInstallCommand(manager, packageName, options = {}) {
300
+ const managerInfo = this.packageManagers[manager];
301
+ if (!managerInfo) return null;
302
+
303
+ const baseCommand = options.global ?
304
+ managerInfo.globalInstall || managerInfo.install :
305
+ managerInfo.install;
306
+
307
+ const version = options.version ? `@${options.version}` : '';
308
+ return `${baseCommand} ${packageName}${version}`;
309
+ }
310
+
311
+ /**
312
+ * Clear detected managers cache
313
+ */
314
+ clearCache() {
315
+ this.detectedManagers = null;
316
+ }
317
+ }
318
+
319
+ module.exports = PackageManagerService;