claude-code-autoconfig 1.0.87 → 1.0.89

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 (2) hide show
  1. package/bin/cli.js +74 -20
  2. package/package.json +1 -1
package/bin/cli.js CHANGED
@@ -152,6 +152,8 @@ if (process.argv.includes('--pull-updates')) {
152
152
  process.exit(0);
153
153
  }
154
154
 
155
+ const forceMode = process.argv.includes('--force');
156
+
155
157
  console.log('\x1b[36m%s\x1b[0m', '🚀 Claude Code Autoconfig');
156
158
  console.log();
157
159
 
@@ -317,6 +319,21 @@ function copyDir(src, dest) {
317
319
  }
318
320
  }
319
321
 
322
+ function copyDirIfMissing(src, dest) {
323
+ fs.mkdirSync(dest, { recursive: true });
324
+ const entries = fs.readdirSync(src, { withFileTypes: true });
325
+ for (const entry of entries) {
326
+ if (isReservedName(entry.name)) continue;
327
+ const srcPath = path.join(src, entry.name);
328
+ const destPath = path.join(dest, entry.name);
329
+ if (entry.isDirectory()) {
330
+ copyDirIfMissing(srcPath, destPath);
331
+ } else if (!fs.existsSync(destPath)) {
332
+ fs.copyFileSync(srcPath, destPath);
333
+ }
334
+ }
335
+ }
336
+
320
337
  // Copy commands (required for /autoconfig to work)
321
338
  if (fs.existsSync(commandsSrc)) {
322
339
  copyDir(commandsSrc, path.join(claudeDest, 'commands'));
@@ -335,38 +352,75 @@ if (fs.existsSync(agentsSrc)) {
335
352
  copyDir(agentsSrc, path.join(claudeDest, 'agents'));
336
353
  }
337
354
 
338
- // Copy feedback template
355
+ // Copy feedback template (preserve user customizations unless --force)
339
356
  if (fs.existsSync(feedbackSrc)) {
340
- copyDir(feedbackSrc, path.join(claudeDest, 'feedback'));
357
+ const copyFn = forceMode ? copyDir : copyDirIfMissing;
358
+ copyFn(feedbackSrc, path.join(claudeDest, 'feedback'));
341
359
  }
342
360
 
343
- // Copy hooks directory (scaffolding for custom hooks)
361
+ // Copy hooks directory (preserve user customizations unless --force)
344
362
  if (fs.existsSync(hooksSrc)) {
345
- copyDir(hooksSrc, path.join(claudeDest, 'hooks'));
363
+ const copyFn = forceMode ? copyDir : copyDirIfMissing;
364
+ copyFn(hooksSrc, path.join(claudeDest, 'hooks'));
365
+ }
366
+
367
+ // Copy updates directory (new update files only, never overwrite existing)
368
+ const updatesSrc = path.join(packageDir, '.claude', 'updates');
369
+ if (fs.existsSync(updatesSrc)) {
370
+ copyDirIfMissing(updatesSrc, path.join(claudeDest, 'updates'));
346
371
  }
347
372
 
348
373
  // Copy settings.json (only if user doesn't have one - preserves existing config)
349
374
  const settingsSrc = path.join(packageDir, '.claude', 'settings.json');
350
375
  const settingsDest = path.join(claudeDest, 'settings.json');
351
- if (fs.existsSync(settingsSrc) && !fs.existsSync(settingsDest)) {
376
+ if (fs.existsSync(settingsSrc) && (forceMode || !fs.existsSync(settingsDest))) {
352
377
  fs.copyFileSync(settingsSrc, settingsDest);
353
378
  }
354
379
 
355
380
  console.log('\x1b[32m%s\x1b[0m', '✅ Prepared /autoconfig command');
356
381
 
357
- // Step 4: Show "READY TO CONFIGURE" message
358
- console.log();
359
- console.log('\x1b[33m╔════════════════════════════════════════════╗\x1b[0m');
360
- console.log('\x1b[33m║ ║\x1b[0m');
361
- console.log('\x1b[33m║\x1b[0m \x1b[33;1mREADY TO CONFIGURE\x1b[0m \x1b[33m║\x1b[0m');
362
- console.log('\x1b[33m║ ║\x1b[0m');
363
- console.log('\x1b[33m║\x1b[0m \x1b[36mPress ENTER to launch Claude and\x1b[0m \x1b[33m║\x1b[0m');
364
- console.log('\x1b[33m║\x1b[0m \x1b[36mauto-run /autoconfig\x1b[0m \x1b[33m║\x1b[0m');
365
- console.log('\x1b[33m║ ║\x1b[0m');
366
- console.log('\x1b[33m╚════════════════════════════════════════════╝\x1b[0m');
382
+ // Detect upgrade vs fresh install
383
+ const isUpgrade = (() => {
384
+ // Indicator 1: CLAUDE.md has autoconfig marker
385
+ const claudeMdPath = path.join(cwd, 'CLAUDE.md');
386
+ if (fs.existsSync(claudeMdPath)) {
387
+ const content = fs.readFileSync(claudeMdPath, 'utf8');
388
+ if (content.includes('AUTO-GENERATED BY /autoconfig')) return true;
389
+ }
390
+ // Indicator 2: docs HTML exists (unique autoconfig artifact)
391
+ const docsPath = path.join(claudeDest, 'docs', 'autoconfig.docs.html');
392
+ if (fs.existsSync(docsPath)) return true;
393
+ return false;
394
+ })();
395
+
396
+ const launchCommand = isUpgrade ? '/autoconfig-update' : '/autoconfig';
397
+
398
+ // Step 4: Show "READY" message
367
399
  console.log();
368
- console.log('\x1b[90m%s\x1b[0m', "You'll need to approve a few file prompts to complete the installation.");
400
+ if (isUpgrade) {
401
+ console.log('\x1b[33m╔════════════════════════════════════════════╗\x1b[0m');
402
+ console.log('\x1b[33m║ ║\x1b[0m');
403
+ console.log('\x1b[33m║\x1b[0m \x1b[33;1mREADY TO UPDATE\x1b[0m \x1b[33m║\x1b[0m');
404
+ console.log('\x1b[33m║ ║\x1b[0m');
405
+ console.log('\x1b[33m║\x1b[0m \x1b[36mPress ENTER to launch Claude and\x1b[0m \x1b[33m║\x1b[0m');
406
+ console.log('\x1b[33m║\x1b[0m \x1b[36mauto-run /autoconfig-update\x1b[0m \x1b[33m║\x1b[0m');
407
+ console.log('\x1b[33m║ ║\x1b[0m');
408
+ console.log('\x1b[33m╚════════════════════════════════════════════╝\x1b[0m');
409
+ } else {
410
+ console.log('\x1b[33m╔════════════════════════════════════════════╗\x1b[0m');
411
+ console.log('\x1b[33m║ ║\x1b[0m');
412
+ console.log('\x1b[33m║\x1b[0m \x1b[33;1mREADY TO CONFIGURE\x1b[0m \x1b[33m║\x1b[0m');
413
+ console.log('\x1b[33m║ ║\x1b[0m');
414
+ console.log('\x1b[33m║\x1b[0m \x1b[36mPress ENTER to launch Claude and\x1b[0m \x1b[33m║\x1b[0m');
415
+ console.log('\x1b[33m║\x1b[0m \x1b[36mauto-run /autoconfig\x1b[0m \x1b[33m║\x1b[0m');
416
+ console.log('\x1b[33m║ ║\x1b[0m');
417
+ console.log('\x1b[33m╚════════════════════════════════════════════╝\x1b[0m');
418
+ }
369
419
  console.log();
420
+ if (!isUpgrade) {
421
+ console.log('\x1b[90m%s\x1b[0m', "You'll need to approve a few file prompts to complete the installation.");
422
+ console.log();
423
+ }
370
424
 
371
425
  // Step 5: Wait for Enter, then launch Claude Code
372
426
  const rl = readline.createInterface({
@@ -378,14 +432,14 @@ rl.question('\x1b[90mPress ENTER to continue...\x1b[0m', () => {
378
432
  rl.close();
379
433
 
380
434
  console.log();
381
- console.log('\x1b[36m%s\x1b[0m', '🚀 Launching Claude Code with /autoconfig...');
435
+ console.log('\x1b[36m%s\x1b[0m', `🚀 Launching Claude Code with ${launchCommand}...`);
382
436
  console.log();
383
437
  console.log('\x1b[90m%s\x1b[0m', ' Heads up: Claude Code can take 30+ seconds to initialize.');
384
438
  console.log('\x1b[90m%s\x1b[0m', ' Please be patient while it loads.');
385
439
  console.log();
386
440
 
387
- // Spawn claude with /autoconfig - settings.json has pre-approved permissions
388
- const claude = spawn('claude', ['/autoconfig'], {
441
+ // Spawn claude with the appropriate command
442
+ const claude = spawn('claude', [launchCommand], {
389
443
  cwd: cwd,
390
444
  stdio: 'inherit',
391
445
  shell: true
@@ -393,7 +447,7 @@ rl.question('\x1b[90mPress ENTER to continue...\x1b[0m', () => {
393
447
 
394
448
  claude.on('error', (err) => {
395
449
  console.log('\x1b[31m%s\x1b[0m', '❌ Failed to launch Claude Code');
396
- console.log(' Run "claude" manually, then run /autoconfig');
450
+ console.log(` Run "claude" manually, then run ${launchCommand}`);
397
451
  });
398
452
 
399
453
  // Cleanup when Claude exits
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-code-autoconfig",
3
- "version": "1.0.87",
3
+ "version": "1.0.89",
4
4
  "description": "Intelligent, self-configuring setup for Claude Code. One command analyzes your project, configures Claude, and shows you what it did.",
5
5
  "author": "ADAC 1001 <info@adac1001.com>",
6
6
  "license": "MIT",