@paulduvall/claude-dev-toolkit 0.0.1-alpha.1 → 0.0.1-alpha.11
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/README.md +74 -23
- package/bin/claude-commands +263 -64
- package/commands/active/xarchitecture.md +393 -0
- package/commands/active/xconfig.md +127 -0
- package/commands/active/xdebug.md +130 -0
- package/commands/active/xdocs.md +178 -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/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/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 +898 -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/README.md +231 -0
- package/hooks/file-logger.sh +98 -0
- package/hooks/lib/argument-parser.sh +422 -0
- package/hooks/lib/config-constants.sh +230 -0
- package/hooks/lib/context-manager.sh +549 -0
- package/hooks/lib/error-handler.sh +412 -0
- package/hooks/lib/execution-engine.sh +627 -0
- package/hooks/lib/file-utils.sh +375 -0
- package/hooks/lib/subagent-discovery.sh +465 -0
- package/hooks/lib/subagent-validator.sh +597 -0
- package/hooks/on-error-debug.sh +221 -0
- package/hooks/pre-commit-quality.sh +204 -0
- package/hooks/pre-write-security.sh +107 -0
- package/hooks/prevent-credential-exposure.sh +265 -0
- package/hooks/subagent-trigger-simple.sh +193 -0
- package/hooks/subagent-trigger.sh +253 -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 +228 -3
- 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-backup.js +579 -0
- package/lib/installation-instruction-generator.js +213 -495
- package/lib/installer.js +134 -56
- package/lib/oidc-command.js +363 -0
- package/lib/result.js +138 -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 +309 -0
- package/lib/subagent-formatter.js +278 -0
- package/lib/subagents-core.js +237 -0
- package/lib/subagents.js +508 -0
- package/lib/types.d.ts +183 -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 +17 -4
- package/scripts/postinstall.js +28 -10
- package/subagents/api-guardian.md +29 -0
- package/subagents/audit-trail-verifier.md +24 -0
- package/subagents/change-scoper.md +23 -0
- package/subagents/ci-pipeline-curator.md +24 -0
- package/subagents/code-review-assistant.md +258 -0
- package/subagents/continuous-release-orchestrator.md +29 -0
- package/subagents/contract-tester.md +24 -0
- package/subagents/data-steward.md +29 -0
- package/subagents/debug-context.md +197 -0
- package/subagents/debug-specialist.md +138 -0
- package/subagents/dependency-steward.md +24 -0
- package/subagents/deployment-strategist.md +29 -0
- package/subagents/documentation-curator.md +29 -0
- package/subagents/environment-guardian.md +29 -0
- package/subagents/license-compliance-guardian.md +29 -0
- package/subagents/observability-engineer.md +25 -0
- package/subagents/performance-guardian.md +29 -0
- package/subagents/product-owner-proxy.md +28 -0
- package/subagents/requirements-reviewer.md +26 -0
- package/subagents/rollback-first-responder.md +24 -0
- package/subagents/sbom-provenance.md +25 -0
- package/subagents/security-auditor.md +29 -0
- package/subagents/style-enforcer.md +23 -0
- package/subagents/test-writer.md +24 -0
- package/subagents/trunk-guardian.md +29 -0
- package/subagents/workflow-coordinator.md +26 -0
- package/templates/README.md +100 -0
- package/templates/basic-settings.json +30 -0
- package/templates/comprehensive-settings.json +206 -0
- package/templates/hybrid-hook-config.yaml +133 -0
- package/templates/security-focused-settings.json +62 -0
- package/templates/subagent-hooks.yaml +188 -0
- package/tsconfig.json +37 -0
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subagents Core Business Logic
|
|
3
|
+
* Pure business logic without console output side effects
|
|
4
|
+
* Uses Result pattern for error handling
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const os = require('os');
|
|
10
|
+
const { Result } = require('./result');
|
|
11
|
+
|
|
12
|
+
// Business logic constants
|
|
13
|
+
const CORE_CONSTANTS = {
|
|
14
|
+
FILE_EXTENSION: '.md',
|
|
15
|
+
CLAUDE_DIR: '.claude',
|
|
16
|
+
SUBAGENTS_DIR: 'subagents'
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Pure business logic for subagent operations
|
|
21
|
+
* All methods return Result objects instead of boolean/throwing
|
|
22
|
+
*/
|
|
23
|
+
class SubagentsCoreService {
|
|
24
|
+
constructor() {
|
|
25
|
+
this.packageRoot = path.join(__dirname, '..');
|
|
26
|
+
this.subagentsDir = path.join(this.packageRoot, CORE_CONSTANTS.SUBAGENTS_DIR);
|
|
27
|
+
this.claudeDir = path.join(os.homedir(), CORE_CONSTANTS.CLAUDE_DIR);
|
|
28
|
+
this.claudeSubagentsDir = path.join(this.claudeDir, CORE_CONSTANTS.SUBAGENTS_DIR);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Get list of available subagent files
|
|
33
|
+
* @returns {Result<string[]>} Array of subagent filenames or error
|
|
34
|
+
*/
|
|
35
|
+
getAvailableSubagents() {
|
|
36
|
+
return Result.try(() => {
|
|
37
|
+
if (!fs.existsSync(this.subagentsDir)) {
|
|
38
|
+
return [];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return fs.readdirSync(this.subagentsDir)
|
|
42
|
+
.filter(f => f.endsWith(CORE_CONSTANTS.FILE_EXTENSION))
|
|
43
|
+
.sort();
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Get subagent names without file extensions
|
|
49
|
+
* @returns {Result<string[]>} Array of subagent names or error
|
|
50
|
+
*/
|
|
51
|
+
getSubagentNames() {
|
|
52
|
+
return this.getAvailableSubagents()
|
|
53
|
+
.map(files => files.map(f => f.replace(CORE_CONSTANTS.FILE_EXTENSION, '')));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Check if Claude directory structure exists
|
|
58
|
+
* @returns {Result<{claudeDir: boolean, subagentsDir: boolean}>} Directory existence status
|
|
59
|
+
*/
|
|
60
|
+
checkDirectoryStructure() {
|
|
61
|
+
return Result.try(() => ({
|
|
62
|
+
claudeDir: fs.existsSync(this.claudeDir),
|
|
63
|
+
subagentsDir: fs.existsSync(this.claudeSubagentsDir)
|
|
64
|
+
}));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Ensure Claude directory structure exists
|
|
69
|
+
* @returns {Result<{created: boolean, path: string}>} Creation result
|
|
70
|
+
*/
|
|
71
|
+
ensureClaudeDirectory() {
|
|
72
|
+
return Result.try(() => {
|
|
73
|
+
let created = false;
|
|
74
|
+
|
|
75
|
+
if (!fs.existsSync(this.claudeDir)) {
|
|
76
|
+
fs.mkdirSync(this.claudeDir, { recursive: true });
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (!fs.existsSync(this.claudeSubagentsDir)) {
|
|
80
|
+
fs.mkdirSync(this.claudeSubagentsDir, { recursive: true });
|
|
81
|
+
created = true;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
created,
|
|
86
|
+
path: this.claudeSubagentsDir
|
|
87
|
+
};
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Install a single subagent file
|
|
93
|
+
* @param {string} filename - Subagent filename
|
|
94
|
+
* @returns {Result<{filename: string, installed: boolean}>} Installation result
|
|
95
|
+
*/
|
|
96
|
+
installSingleSubagent(filename) {
|
|
97
|
+
return Result.try(() => {
|
|
98
|
+
const sourcePath = path.join(this.subagentsDir, filename);
|
|
99
|
+
const destPath = path.join(this.claudeSubagentsDir, filename);
|
|
100
|
+
|
|
101
|
+
fs.copyFileSync(sourcePath, destPath);
|
|
102
|
+
|
|
103
|
+
return {
|
|
104
|
+
filename,
|
|
105
|
+
installed: true
|
|
106
|
+
};
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Install all available subagents
|
|
112
|
+
* @returns {Result<{installed: string[], failed: Array<{filename: string, error: string}>, summary: Object}>}
|
|
113
|
+
*/
|
|
114
|
+
installAllSubagents() {
|
|
115
|
+
// Get available subagents
|
|
116
|
+
const subagentsResult = this.getAvailableSubagents();
|
|
117
|
+
if (subagentsResult.isError) {
|
|
118
|
+
return subagentsResult;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const subagentFiles = subagentsResult.value;
|
|
122
|
+
if (subagentFiles.length === 0) {
|
|
123
|
+
return Result.err(new Error('No subagent files found to install'));
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Ensure directory exists
|
|
127
|
+
const dirResult = this.ensureClaudeDirectory();
|
|
128
|
+
if (dirResult.isError) {
|
|
129
|
+
return dirResult;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Install each subagent
|
|
133
|
+
const installed = [];
|
|
134
|
+
const failed = [];
|
|
135
|
+
|
|
136
|
+
for (const filename of subagentFiles) {
|
|
137
|
+
const installResult = this.installSingleSubagent(filename);
|
|
138
|
+
|
|
139
|
+
if (installResult.isOk) {
|
|
140
|
+
installed.push(filename);
|
|
141
|
+
} else {
|
|
142
|
+
failed.push({
|
|
143
|
+
filename,
|
|
144
|
+
error: installResult.error.message
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const summary = {
|
|
150
|
+
installed: installed.length,
|
|
151
|
+
failed: failed.length,
|
|
152
|
+
path: this.claudeSubagentsDir,
|
|
153
|
+
directoryCreated: dirResult.value.created
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
return Result.ok({
|
|
157
|
+
installed,
|
|
158
|
+
failed,
|
|
159
|
+
summary
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Validate subagent installation
|
|
165
|
+
* @returns {Result<{valid: boolean, installedCount: number, issues: string[]}>}
|
|
166
|
+
*/
|
|
167
|
+
validateInstallation() {
|
|
168
|
+
return Result.try(() => {
|
|
169
|
+
const issues = [];
|
|
170
|
+
let installedCount = 0;
|
|
171
|
+
|
|
172
|
+
// Check if directory exists
|
|
173
|
+
if (!fs.existsSync(this.claudeSubagentsDir)) {
|
|
174
|
+
issues.push('Subagents directory does not exist');
|
|
175
|
+
return { valid: false, installedCount: 0, issues };
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Count installed files
|
|
179
|
+
const installedFiles = fs.readdirSync(this.claudeSubagentsDir)
|
|
180
|
+
.filter(f => f.endsWith(CORE_CONSTANTS.FILE_EXTENSION));
|
|
181
|
+
|
|
182
|
+
installedCount = installedFiles.length;
|
|
183
|
+
|
|
184
|
+
// Get available files for comparison
|
|
185
|
+
const availableResult = this.getAvailableSubagents();
|
|
186
|
+
if (availableResult.isOk) {
|
|
187
|
+
const availableFiles = availableResult.value;
|
|
188
|
+
const missingFiles = availableFiles.filter(f => !installedFiles.includes(f));
|
|
189
|
+
|
|
190
|
+
if (missingFiles.length > 0) {
|
|
191
|
+
issues.push(`Missing files: ${missingFiles.join(', ')}`);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return {
|
|
196
|
+
valid: issues.length === 0,
|
|
197
|
+
installedCount,
|
|
198
|
+
issues
|
|
199
|
+
};
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Get installation status information
|
|
205
|
+
* @returns {Result<Object>} Status information
|
|
206
|
+
*/
|
|
207
|
+
getInstallationStatus() {
|
|
208
|
+
return Result.try(() => {
|
|
209
|
+
const available = this.getAvailableSubagents().unwrapOr([]);
|
|
210
|
+
const directoryStatus = this.checkDirectoryStructure().unwrapOr({
|
|
211
|
+
claudeDir: false,
|
|
212
|
+
subagentsDir: false
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
let installed = [];
|
|
216
|
+
if (directoryStatus.subagentsDir) {
|
|
217
|
+
installed = fs.readdirSync(this.claudeSubagentsDir)
|
|
218
|
+
.filter(f => f.endsWith(CORE_CONSTANTS.FILE_EXTENSION));
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return {
|
|
222
|
+
available: available.length,
|
|
223
|
+
installed: installed.length,
|
|
224
|
+
directories: directoryStatus,
|
|
225
|
+
paths: {
|
|
226
|
+
packageSubagents: this.subagentsDir,
|
|
227
|
+
claudeSubagents: this.claudeSubagentsDir
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
module.exports = {
|
|
235
|
+
SubagentsCoreService,
|
|
236
|
+
CORE_CONSTANTS
|
|
237
|
+
};
|