@torka/claude-workflows 0.1.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/.claude-plugin/plugin.json +51 -0
- package/LICENSE +21 -0
- package/README.md +299 -0
- package/agents/principal-code-reviewer.md +80 -0
- package/agents/story-prep-master.md +53 -0
- package/commands/git-cleanup-and-merge.md +519 -0
- package/commands/implement-epic-with-subagents.md +5 -0
- package/commands/plan-parallelization.md +194 -0
- package/examples/settings.local.example.json +57 -0
- package/hooks/auto_approve_safe.py +261 -0
- package/hooks/auto_approve_safe.rules.json +134 -0
- package/install.js +181 -0
- package/package.json +52 -0
- package/scripts/context-monitor.py +175 -0
- package/skills/agent-creator/COMMUNITY-REPOS.md +212 -0
- package/skills/agent-creator/NON-STORY-AGENT-TEMPLATE.md +90 -0
- package/skills/agent-creator/REGISTRY.yaml +107 -0
- package/skills/agent-creator/SKILL.md +339 -0
- package/skills/agent-creator/STORY-AGENT-TEMPLATE.md +199 -0
- package/uninstall.js +186 -0
package/uninstall.js
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @torka/claude-workflows - Pre-uninstall script
|
|
4
|
+
* Removes workflow files from the .claude directory
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const os = require('os');
|
|
10
|
+
|
|
11
|
+
// ANSI colors for output
|
|
12
|
+
const colors = {
|
|
13
|
+
green: '\x1b[32m',
|
|
14
|
+
yellow: '\x1b[33m',
|
|
15
|
+
blue: '\x1b[34m',
|
|
16
|
+
red: '\x1b[31m',
|
|
17
|
+
reset: '\x1b[0m',
|
|
18
|
+
bold: '\x1b[1m',
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
function log(message, color = 'reset') {
|
|
22
|
+
console.log(`${colors[color]}${message}${colors.reset}`);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function logSuccess(message) {
|
|
26
|
+
log(` ✓ ${message}`, 'green');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function logSkip(message) {
|
|
30
|
+
log(` ○ ${message}`, 'yellow');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Files that were installed by this package
|
|
35
|
+
* Only remove files we installed, not user-modified files
|
|
36
|
+
*/
|
|
37
|
+
const INSTALLED_FILES = {
|
|
38
|
+
commands: [
|
|
39
|
+
'implement-epic-with-subagents.md',
|
|
40
|
+
'plan-parallelization.md',
|
|
41
|
+
'git-cleanup-and-merge.md',
|
|
42
|
+
],
|
|
43
|
+
agents: [
|
|
44
|
+
'principal-code-reviewer.md',
|
|
45
|
+
'story-prep-master.md',
|
|
46
|
+
],
|
|
47
|
+
'skills/agent-creator': [
|
|
48
|
+
'SKILL.md',
|
|
49
|
+
'REGISTRY.yaml',
|
|
50
|
+
'STORY-AGENT-TEMPLATE.md',
|
|
51
|
+
'NON-STORY-AGENT-TEMPLATE.md',
|
|
52
|
+
'COMMUNITY-REPOS.md',
|
|
53
|
+
],
|
|
54
|
+
scripts: [
|
|
55
|
+
'auto_approve_safe.py',
|
|
56
|
+
'auto_approve_safe.rules.json',
|
|
57
|
+
'context-monitor.py',
|
|
58
|
+
],
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Determine the target .claude directory based on installation context
|
|
63
|
+
*/
|
|
64
|
+
function getTargetBase() {
|
|
65
|
+
const isGlobal = process.env.npm_config_global === 'true';
|
|
66
|
+
|
|
67
|
+
if (isGlobal) {
|
|
68
|
+
return path.join(os.homedir(), '.claude');
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
let projectRoot = process.env.INIT_CWD || process.cwd();
|
|
72
|
+
|
|
73
|
+
while (projectRoot !== path.dirname(projectRoot)) {
|
|
74
|
+
const packageJsonPath = path.join(projectRoot, 'package.json');
|
|
75
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
76
|
+
try {
|
|
77
|
+
const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
78
|
+
if (pkg.name !== '@torka/claude-workflows') {
|
|
79
|
+
return path.join(projectRoot, '.claude');
|
|
80
|
+
}
|
|
81
|
+
} catch (e) {
|
|
82
|
+
// Continue walking up
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
projectRoot = path.dirname(projectRoot);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return path.join(process.env.INIT_CWD || process.cwd(), '.claude');
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Remove a file if it exists and matches what we installed
|
|
93
|
+
*/
|
|
94
|
+
function removeFile(filePath, stats) {
|
|
95
|
+
if (fs.existsSync(filePath)) {
|
|
96
|
+
try {
|
|
97
|
+
fs.unlinkSync(filePath);
|
|
98
|
+
stats.removed.push(filePath);
|
|
99
|
+
logSuccess(`Removed: ${path.relative(stats.targetBase, filePath)}`);
|
|
100
|
+
} catch (error) {
|
|
101
|
+
stats.failed.push({ path: filePath, error: error.message });
|
|
102
|
+
log(` ✗ Failed to remove: ${path.relative(stats.targetBase, filePath)}`, 'red');
|
|
103
|
+
}
|
|
104
|
+
} else {
|
|
105
|
+
stats.notFound.push(filePath);
|
|
106
|
+
logSkip(`Not found: ${path.relative(stats.targetBase, filePath)}`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Remove empty directories
|
|
112
|
+
*/
|
|
113
|
+
function removeEmptyDir(dirPath) {
|
|
114
|
+
if (fs.existsSync(dirPath)) {
|
|
115
|
+
const files = fs.readdirSync(dirPath);
|
|
116
|
+
if (files.length === 0) {
|
|
117
|
+
fs.rmdirSync(dirPath);
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Main uninstall function
|
|
126
|
+
*/
|
|
127
|
+
function uninstall() {
|
|
128
|
+
const targetBase = getTargetBase();
|
|
129
|
+
const isGlobal = process.env.npm_config_global === 'true';
|
|
130
|
+
|
|
131
|
+
log('\n' + colors.bold + '📦 @torka/claude-workflows - Uninstalling...' + colors.reset);
|
|
132
|
+
log(` Target: ${targetBase}`, 'blue');
|
|
133
|
+
log(` Mode: ${isGlobal ? 'Global' : 'Project-level'}\n`, 'blue');
|
|
134
|
+
|
|
135
|
+
if (!fs.existsSync(targetBase)) {
|
|
136
|
+
log(' .claude directory not found, nothing to remove.\n', 'yellow');
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const stats = {
|
|
141
|
+
removed: [],
|
|
142
|
+
notFound: [],
|
|
143
|
+
failed: [],
|
|
144
|
+
targetBase,
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
// Remove files by category
|
|
148
|
+
for (const [dir, files] of Object.entries(INSTALLED_FILES)) {
|
|
149
|
+
log(`\n${colors.bold}${dir}/${colors.reset}`);
|
|
150
|
+
for (const file of files) {
|
|
151
|
+
const filePath = path.join(targetBase, dir, file);
|
|
152
|
+
removeFile(filePath, stats);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Try to remove empty directories
|
|
156
|
+
const dirPath = path.join(targetBase, dir);
|
|
157
|
+
if (removeEmptyDir(dirPath)) {
|
|
158
|
+
log(` ○ Removed empty directory: ${dir}/`, 'yellow');
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Try to remove agent-creator skill directory if empty
|
|
163
|
+
const skillDir = path.join(targetBase, 'skills', 'agent-creator');
|
|
164
|
+
if (removeEmptyDir(skillDir)) {
|
|
165
|
+
log(` ○ Removed empty directory: skills/agent-creator/`, 'yellow');
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Summary
|
|
169
|
+
log('\n' + colors.bold + '📊 Uninstall Summary' + colors.reset);
|
|
170
|
+
log(` Files removed: ${stats.removed.length}`, 'green');
|
|
171
|
+
log(` Files not found: ${stats.notFound.length}`, 'yellow');
|
|
172
|
+
if (stats.failed.length > 0) {
|
|
173
|
+
log(` Failed to remove: ${stats.failed.length}`, 'red');
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
log('\n' + colors.yellow + '⚠️ Note: settings.local.json was not modified.' + colors.reset);
|
|
177
|
+
log(' You may want to manually remove hook/statusLine configurations.\n');
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Run uninstall
|
|
181
|
+
try {
|
|
182
|
+
uninstall();
|
|
183
|
+
} catch (error) {
|
|
184
|
+
log(`Uninstall warning: ${error.message}`, 'yellow');
|
|
185
|
+
// Don't exit with error code - allow npm uninstall to complete
|
|
186
|
+
}
|