davenov-cc 1.0.4 → 1.0.5

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 (3) hide show
  1. package/bin/cli.js +226 -13
  2. package/package.json +2 -3
  3. package/install.js +0 -227
package/bin/cli.js CHANGED
@@ -1,22 +1,235 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const path = require('path');
4
- const { spawn } = require('child_process');
3
+ const fs = require("fs");
4
+ const path = require("path");
5
+ const os = require("os");
6
+ const readline = require("readline");
5
7
 
6
- // Pass through arguments to install.js
8
+ const CLAUDE_DIR = path.join(os.homedir(), ".claude");
9
+ const SOURCE_DIR = path.join(__dirname, "..");
10
+
11
+ // Parse command line arguments
7
12
  const args = process.argv.slice(2);
13
+ const AUTO_OVERRIDE = args.includes("--auto-override");
14
+ const UNINSTALL = args.includes("--uninstall");
8
15
 
9
- // Default to --auto-override for install (unless --uninstall)
10
- const isUninstall = args.includes('--uninstall');
11
- const scriptArgs = isUninstall ? args : ['--auto-override', ...args];
16
+ // Directories to install/uninstall
17
+ const CUSTOMIZATION_DIRS = ["commands", "skills"];
12
18
 
13
- const installScript = path.join(__dirname, '..', 'install.js');
19
+ // Files/folders installed by this package (for uninstall)
20
+ const INSTALLED_ITEMS = {
21
+ commands: ["davenov:cc:interview.md", "davenov:cc:rule.md", "davenov:cc:update.md"],
22
+ skills: [
23
+ "davenov:cc:expert-convex-nextjs",
24
+ "davenov:cc:expert-evolu-nextjs",
25
+ "davenov:cc:expert-nextjs-16",
26
+ "davenov:cc:expert-build-nostr"
27
+ ]
28
+ };
14
29
 
15
- const child = spawn(process.execPath, [installScript, ...scriptArgs], {
16
- stdio: 'inherit',
17
- cwd: path.join(__dirname, '..')
18
- });
30
+ function createReadlineInterface() {
31
+ return readline.createInterface({
32
+ input: process.stdin,
33
+ output: process.stdout,
34
+ });
35
+ }
36
+
37
+ async function prompt(rl, question) {
38
+ return new Promise((resolve) => {
39
+ rl.question(question, resolve);
40
+ });
41
+ }
42
+
43
+ function copyRecursive(src, dest) {
44
+ const stats = fs.statSync(src);
45
+
46
+ if (stats.isDirectory()) {
47
+ if (!fs.existsSync(dest)) {
48
+ fs.mkdirSync(dest, { recursive: true });
49
+ }
50
+
51
+ const entries = fs.readdirSync(src);
52
+ for (const entry of entries) {
53
+ copyRecursive(path.join(src, entry), path.join(dest, entry));
54
+ }
55
+ } else {
56
+ fs.copyFileSync(src, dest);
57
+ }
58
+ }
59
+
60
+ function countFiles(dir) {
61
+ let count = 0;
62
+ if (!fs.existsSync(dir)) return 0;
63
+
64
+ const entries = fs.readdirSync(dir);
65
+ for (const entry of entries) {
66
+ const fullPath = path.join(dir, entry);
67
+ const stats = fs.statSync(fullPath);
68
+ if (stats.isDirectory()) {
69
+ count += countFiles(fullPath);
70
+ } else {
71
+ count++;
72
+ }
73
+ }
74
+ return count;
75
+ }
76
+
77
+ function removeRecursive(target) {
78
+ if (!fs.existsSync(target)) return false;
79
+
80
+ const stats = fs.statSync(target);
81
+ if (stats.isDirectory()) {
82
+ fs.rmSync(target, { recursive: true, force: true });
83
+ } else {
84
+ fs.unlinkSync(target);
85
+ }
86
+ return true;
87
+ }
88
+
89
+ async function uninstall(rl) {
90
+ console.log("\nšŸ—‘ļø Claude Code Customizations Uninstaller\n");
91
+ console.log(`Target: ${CLAUDE_DIR}\n`);
92
+
93
+ // Check what's installed
94
+ const installed = [];
95
+ for (const [dir, items] of Object.entries(INSTALLED_ITEMS)) {
96
+ for (const item of items) {
97
+ const fullPath = path.join(CLAUDE_DIR, dir, item);
98
+ if (fs.existsSync(fullPath)) {
99
+ installed.push({ dir, item, fullPath });
100
+ }
101
+ }
102
+ }
103
+
104
+ if (installed.length === 0) {
105
+ console.log("No davenov-cc customizations found to uninstall.");
106
+ return;
107
+ }
108
+
109
+ console.log("Found installed customizations:");
110
+ for (const { dir, item } of installed) {
111
+ console.log(` - ${dir}/${item}`);
112
+ }
113
+ console.log();
114
+
115
+ if (!AUTO_OVERRIDE) {
116
+ const answer = await prompt(
117
+ rl,
118
+ "Do you want to remove these customizations? (y/N): "
119
+ );
120
+
121
+ if (answer.toLowerCase() !== "y") {
122
+ console.log("\nUninstall cancelled.");
123
+ return;
124
+ }
125
+ } else {
126
+ console.log("Auto-override enabled, proceeding...");
127
+ }
128
+
129
+ console.log("\nRemoving...\n");
130
+
131
+ let removed = 0;
132
+ for (const { dir, item, fullPath } of installed) {
133
+ if (removeRecursive(fullPath)) {
134
+ console.log(` āœ“ ${dir}/${item}`);
135
+ removed++;
136
+ }
137
+ }
138
+
139
+ console.log(`\nāœ… Uninstall complete! Removed ${removed} item(s).\n`);
140
+ }
141
+
142
+ async function install(rl) {
143
+ console.log("\nšŸ“¦ Claude Code Customizations Installer\n");
144
+ console.log(`Source: ${SOURCE_DIR}`);
145
+ console.log(`Target: ${CLAUDE_DIR}\n`);
146
+
147
+ // Check what we have to install
148
+ const available = CUSTOMIZATION_DIRS.filter((dir) =>
149
+ fs.existsSync(path.join(SOURCE_DIR, dir))
150
+ );
151
+
152
+ if (available.length === 0) {
153
+ console.log("No customizations found to install.");
154
+ process.exit(0);
155
+ }
156
+
157
+ console.log("Available customizations:");
158
+ for (const dir of available) {
159
+ const srcPath = path.join(SOURCE_DIR, dir);
160
+ const fileCount = countFiles(srcPath);
161
+ console.log(` - ${dir}/ (${fileCount} files)`);
162
+ }
163
+ console.log();
164
+
165
+ // Check for existing files
166
+ const existing = available.filter((dir) =>
167
+ fs.existsSync(path.join(CLAUDE_DIR, dir))
168
+ );
169
+
170
+ if (existing.length > 0) {
171
+ console.log("āš ļø The following directories already exist:");
172
+ for (const dir of existing) {
173
+ console.log(` - ${path.join(CLAUDE_DIR, dir)}`);
174
+ }
175
+ console.log();
176
+
177
+ if (AUTO_OVERRIDE) {
178
+ console.log("Auto-override enabled, proceeding...");
179
+ } else {
180
+ const answer = await prompt(
181
+ rl,
182
+ "Do you want to overwrite existing files? (y/N): "
183
+ );
184
+
185
+ if (answer.toLowerCase() !== "y") {
186
+ console.log("\nInstallation cancelled.");
187
+ rl.close();
188
+ process.exit(0);
189
+ }
190
+ }
191
+ }
192
+
193
+ // Ensure .claude directory exists
194
+ if (!fs.existsSync(CLAUDE_DIR)) {
195
+ fs.mkdirSync(CLAUDE_DIR, { recursive: true });
196
+ console.log(`Created ${CLAUDE_DIR}`);
197
+ }
198
+
199
+ // Install each directory
200
+ console.log("\nInstalling...\n");
201
+
202
+ for (const dir of available) {
203
+ const srcPath = path.join(SOURCE_DIR, dir);
204
+ const destPath = path.join(CLAUDE_DIR, dir);
205
+
206
+ console.log(` ${dir}/`);
207
+ copyRecursive(srcPath, destPath);
208
+ }
209
+
210
+ console.log("\nāœ… Installation complete!\n");
211
+ console.log("Your customizations are now available in Claude Code.");
212
+ }
213
+
214
+ async function main() {
215
+ const rl = createReadlineInterface();
216
+
217
+ try {
218
+ if (UNINSTALL) {
219
+ await uninstall(rl);
220
+ } else {
221
+ // Default to auto-override when run via npx (no TTY interaction expected)
222
+ if (!process.stdin.isTTY && !AUTO_OVERRIDE) {
223
+ args.push("--auto-override");
224
+ }
225
+ await install(rl);
226
+ }
227
+ } finally {
228
+ rl.close();
229
+ }
230
+ }
19
231
 
20
- child.on('close', (code) => {
21
- process.exit(code);
232
+ main().catch((err) => {
233
+ console.error("Error:", err.message);
234
+ process.exit(1);
22
235
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "davenov-cc",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "description": "Claude Code customizations - skills and slash commands for enhanced AI-assisted development",
5
5
  "bin": {
6
6
  "davenov-cc": "./bin/cli.js"
@@ -29,7 +29,6 @@
29
29
  "files": [
30
30
  "bin/",
31
31
  "commands/",
32
- "skills/",
33
- "install.js"
32
+ "skills/"
34
33
  ]
35
34
  }
package/install.js DELETED
@@ -1,227 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const fs = require("fs");
4
- const path = require("path");
5
- const os = require("os");
6
- const readline = require("readline");
7
-
8
- const CLAUDE_DIR = path.join(os.homedir(), ".claude");
9
- const SOURCE_DIR = __dirname;
10
-
11
- // Parse command line arguments
12
- const args = process.argv.slice(2);
13
- const AUTO_OVERRIDE = args.includes("--auto-override");
14
- const UNINSTALL = args.includes("--uninstall");
15
-
16
- // Directories to install/uninstall
17
- const CUSTOMIZATION_DIRS = ["commands", "skills"];
18
-
19
- // Files/folders installed by this package (for uninstall)
20
- const INSTALLED_ITEMS = {
21
- commands: ["davenov:cc:interview.md", "davenov:cc:rule.md", "davenov:cc:update.md"],
22
- skills: [
23
- "davenov:cc:expert-convex-nextjs",
24
- "davenov:cc:expert-evolu-nextjs",
25
- "davenov:cc:expert-nextjs-16",
26
- "davenov:cc:expert-build-nostr"
27
- ]
28
- };
29
-
30
- function createReadlineInterface() {
31
- return readline.createInterface({
32
- input: process.stdin,
33
- output: process.stdout,
34
- });
35
- }
36
-
37
- async function prompt(rl, question) {
38
- return new Promise((resolve) => {
39
- rl.question(question, resolve);
40
- });
41
- }
42
-
43
- function copyRecursive(src, dest) {
44
- const stats = fs.statSync(src);
45
-
46
- if (stats.isDirectory()) {
47
- if (!fs.existsSync(dest)) {
48
- fs.mkdirSync(dest, { recursive: true });
49
- }
50
-
51
- const entries = fs.readdirSync(src);
52
- for (const entry of entries) {
53
- copyRecursive(path.join(src, entry), path.join(dest, entry));
54
- }
55
- } else {
56
- fs.copyFileSync(src, dest);
57
- }
58
- }
59
-
60
- function countFiles(dir) {
61
- let count = 0;
62
- if (!fs.existsSync(dir)) return 0;
63
-
64
- const entries = fs.readdirSync(dir);
65
- for (const entry of entries) {
66
- const fullPath = path.join(dir, entry);
67
- const stats = fs.statSync(fullPath);
68
- if (stats.isDirectory()) {
69
- count += countFiles(fullPath);
70
- } else {
71
- count++;
72
- }
73
- }
74
- return count;
75
- }
76
-
77
- function removeRecursive(target) {
78
- if (!fs.existsSync(target)) return false;
79
-
80
- const stats = fs.statSync(target);
81
- if (stats.isDirectory()) {
82
- fs.rmSync(target, { recursive: true, force: true });
83
- } else {
84
- fs.unlinkSync(target);
85
- }
86
- return true;
87
- }
88
-
89
- async function uninstall(rl) {
90
- console.log("\nšŸ—‘ļø Claude Code Customizations Uninstaller\n");
91
- console.log(`Target: ${CLAUDE_DIR}\n`);
92
-
93
- // Check what's installed
94
- const installed = [];
95
- for (const [dir, items] of Object.entries(INSTALLED_ITEMS)) {
96
- for (const item of items) {
97
- const fullPath = path.join(CLAUDE_DIR, dir, item);
98
- if (fs.existsSync(fullPath)) {
99
- installed.push({ dir, item, fullPath });
100
- }
101
- }
102
- }
103
-
104
- if (installed.length === 0) {
105
- console.log("No davenov-cc customizations found to uninstall.");
106
- return;
107
- }
108
-
109
- console.log("Found installed customizations:");
110
- for (const { dir, item } of installed) {
111
- console.log(` - ${dir}/${item}`);
112
- }
113
- console.log();
114
-
115
- if (!AUTO_OVERRIDE) {
116
- const answer = await prompt(
117
- rl,
118
- "Do you want to remove these customizations? (y/N): "
119
- );
120
-
121
- if (answer.toLowerCase() !== "y") {
122
- console.log("\nUninstall cancelled.");
123
- return;
124
- }
125
- } else {
126
- console.log("Auto-override enabled, proceeding...");
127
- }
128
-
129
- console.log("\nRemoving...\n");
130
-
131
- let removed = 0;
132
- for (const { dir, item, fullPath } of installed) {
133
- if (removeRecursive(fullPath)) {
134
- console.log(` āœ“ ${dir}/${item}`);
135
- removed++;
136
- }
137
- }
138
-
139
- console.log(`\nāœ… Uninstall complete! Removed ${removed} item(s).\n`);
140
- }
141
-
142
- async function main() {
143
- const rl = createReadlineInterface();
144
-
145
- if (UNINSTALL) {
146
- await uninstall(rl);
147
- rl.close();
148
- return;
149
- }
150
-
151
- console.log("\nšŸ“¦ Claude Code Customizations Installer\n");
152
- console.log(`Source: ${SOURCE_DIR}`);
153
- console.log(`Target: ${CLAUDE_DIR}\n`);
154
-
155
- // Check what we have to install
156
- const available = CUSTOMIZATION_DIRS.filter((dir) =>
157
- fs.existsSync(path.join(SOURCE_DIR, dir))
158
- );
159
-
160
- if (available.length === 0) {
161
- console.log("No customizations found to install.");
162
- process.exit(0);
163
- }
164
-
165
- console.log("Available customizations:");
166
- for (const dir of available) {
167
- const srcPath = path.join(SOURCE_DIR, dir);
168
- const fileCount = countFiles(srcPath);
169
- console.log(` - ${dir}/ (${fileCount} files)`);
170
- }
171
- console.log();
172
-
173
- // Check for existing files
174
- const existing = available.filter((dir) =>
175
- fs.existsSync(path.join(CLAUDE_DIR, dir))
176
- );
177
-
178
- if (existing.length > 0) {
179
- console.log("āš ļø The following directories already exist:");
180
- for (const dir of existing) {
181
- console.log(` - ${path.join(CLAUDE_DIR, dir)}`);
182
- }
183
- console.log();
184
-
185
- if (AUTO_OVERRIDE) {
186
- console.log("Auto-override enabled, proceeding...");
187
- } else {
188
- const answer = await prompt(
189
- rl,
190
- "Do you want to overwrite existing files? (y/N): "
191
- );
192
-
193
- if (answer.toLowerCase() !== "y") {
194
- console.log("\nInstallation cancelled.");
195
- rl.close();
196
- process.exit(0);
197
- }
198
- }
199
- }
200
-
201
- // Ensure .claude directory exists
202
- if (!fs.existsSync(CLAUDE_DIR)) {
203
- fs.mkdirSync(CLAUDE_DIR, { recursive: true });
204
- console.log(`Created ${CLAUDE_DIR}`);
205
- }
206
-
207
- // Install each directory
208
- console.log("\nInstalling...\n");
209
-
210
- for (const dir of available) {
211
- const srcPath = path.join(SOURCE_DIR, dir);
212
- const destPath = path.join(CLAUDE_DIR, dir);
213
-
214
- console.log(` ${dir}/`);
215
- copyRecursive(srcPath, destPath);
216
- }
217
-
218
- console.log("\nāœ… Installation complete!\n");
219
- console.log("Your customizations are now available in Claude Code.");
220
-
221
- rl.close();
222
- }
223
-
224
- main().catch((err) => {
225
- console.error("Error:", err.message);
226
- process.exit(1);
227
- });