coder-config 0.44.39 → 0.44.41

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/lib/constants.js CHANGED
@@ -2,7 +2,7 @@
2
2
  * Constants and tool path configurations
3
3
  */
4
4
 
5
- const VERSION = '0.44.39';
5
+ const VERSION = '0.44.41';
6
6
 
7
7
  // Tool-specific path configurations
8
8
  const TOOL_PATHS = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coder-config",
3
- "version": "0.44.39",
3
+ "version": "0.44.41",
4
4
  "description": "Configuration manager for AI coding tools - Claude Code, Gemini CLI, Codex CLI, Antigravity. Manage MCPs, rules, permissions, memory, and workstreams.",
5
5
  "author": "regression.io",
6
6
  "main": "config-loader.js",
@@ -562,77 +562,96 @@ ${task}
562
562
  * Also fixes hooks.json to use absolute paths instead of ${CLAUDE_PLUGIN_ROOT}
563
563
  */
564
564
  function fixRalphLoopPluginStructure() {
565
- const pluginCacheDir = path.join(os.homedir(), '.claude', 'plugins', 'cache', 'claude-plugins-official', 'ralph-loop');
565
+ // Fix both cache and marketplace directories
566
+ // Claude Code reads hooks from marketplace source, not cache
567
+ const pluginLocations = [
568
+ path.join(os.homedir(), '.claude', 'plugins', 'cache', 'claude-plugins-official', 'ralph-loop'),
569
+ path.join(os.homedir(), '.claude', 'plugins', 'marketplaces', 'claude-plugins-official', 'plugins', 'ralph-loop')
570
+ ];
566
571
 
567
- if (!fs.existsSync(pluginCacheDir)) {
568
- return;
569
- }
572
+ for (const pluginDir of pluginLocations) {
573
+ if (!fs.existsSync(pluginDir)) {
574
+ continue;
575
+ }
570
576
 
571
- // Find all version directories
572
- const versions = fs.readdirSync(pluginCacheDir).filter(f => {
573
- const fullPath = path.join(pluginCacheDir, f);
574
- return fs.statSync(fullPath).isDirectory();
575
- });
577
+ // Check if this is a versioned cache dir or direct marketplace dir
578
+ const hasVersionDirs = fs.readdirSync(pluginDir).some(f => {
579
+ const fullPath = path.join(pluginDir, f);
580
+ return fs.statSync(fullPath).isDirectory() && !['commands', 'skills', 'hooks', 'scripts', '.claude-plugin'].includes(f);
581
+ });
576
582
 
577
- for (const version of versions) {
578
- const versionDir = path.join(pluginCacheDir, version);
579
- const commandsDir = path.join(versionDir, 'commands');
580
- const skillsDir = path.join(versionDir, 'skills');
581
- const hooksDir = path.join(versionDir, 'hooks');
582
-
583
- // Fix hooks.json - replace ${CLAUDE_PLUGIN_ROOT} with actual path
584
- const hooksJsonPath = path.join(hooksDir, 'hooks.json');
585
- if (fs.existsSync(hooksJsonPath)) {
586
- try {
587
- let hooksContent = fs.readFileSync(hooksJsonPath, 'utf8');
588
- if (hooksContent.includes('${CLAUDE_PLUGIN_ROOT}')) {
589
- hooksContent = hooksContent.replace(/\$\{CLAUDE_PLUGIN_ROOT\}/g, versionDir);
590
- fs.writeFileSync(hooksJsonPath, hooksContent, 'utf8');
583
+ const dirsToFix = hasVersionDirs
584
+ ? fs.readdirSync(pluginDir).filter(f => {
585
+ const fullPath = path.join(pluginDir, f);
586
+ return fs.statSync(fullPath).isDirectory();
587
+ }).map(v => path.join(pluginDir, v))
588
+ : [pluginDir];
589
+
590
+ for (const versionDir of dirsToFix) {
591
+ const commandsDir = path.join(versionDir, 'commands');
592
+ const skillsDir = path.join(versionDir, 'skills');
593
+ const hooksDir = path.join(versionDir, 'hooks');
594
+
595
+ // Disable plugin's hooks.json - we use our own env-var-based hooks
596
+ // The plugin's hooks use project-local state files which affect ALL terminals
597
+ // in the same project, causing input freezing in other Claude sessions
598
+ const hooksJsonPath = path.join(hooksDir, 'hooks.json');
599
+ if (fs.existsSync(hooksJsonPath)) {
600
+ try {
601
+ const hooksContent = fs.readFileSync(hooksJsonPath, 'utf8');
602
+ const hooks = JSON.parse(hooksContent);
603
+ // Only disable if it has hooks defined (not already disabled)
604
+ if (hooks.hooks && Object.keys(hooks.hooks).length > 0) {
605
+ hooks._disabled_hooks = hooks.hooks; // Keep for reference
606
+ hooks.hooks = {}; // Disable all hooks
607
+ hooks._disabled_reason = 'Disabled by coder-config - using env-var-based hooks instead';
608
+ fs.writeFileSync(hooksJsonPath, JSON.stringify(hooks, null, 2), 'utf8');
609
+ }
610
+ } catch (e) {
611
+ // Ignore errors fixing hooks
591
612
  }
592
- } catch (e) {
593
- // Ignore errors fixing hooks
594
613
  }
595
- }
596
-
597
- if (!fs.existsSync(commandsDir)) {
598
- continue;
599
- }
600
614
 
601
- // Remove old symlink if it exists
602
- if (fs.existsSync(skillsDir) && fs.lstatSync(skillsDir).isSymbolicLink()) {
603
- fs.unlinkSync(skillsDir);
604
- }
615
+ if (!fs.existsSync(commandsDir)) {
616
+ continue;
617
+ }
605
618
 
606
- // Create skills directory if it doesn't exist
607
- if (!fs.existsSync(skillsDir)) {
608
- fs.mkdirSync(skillsDir, { recursive: true });
609
- }
619
+ // Remove old symlink if it exists
620
+ if (fs.existsSync(skillsDir) && fs.lstatSync(skillsDir).isSymbolicLink()) {
621
+ fs.unlinkSync(skillsDir);
622
+ }
610
623
 
611
- // Convert each command to skill format
612
- // commands/ralph-loop.md -> skills/ralph-loop/SKILL.md
613
- const commands = fs.readdirSync(commandsDir).filter(f => f.endsWith('.md'));
614
- for (const cmdFile of commands) {
615
- const skillName = cmdFile.replace('.md', '');
616
- const skillDir = path.join(skillsDir, skillName);
617
- const skillFile = path.join(skillDir, 'SKILL.md');
618
-
619
- // Create skill directory
620
- if (!fs.existsSync(skillDir)) {
621
- fs.mkdirSync(skillDir, { recursive: true });
624
+ // Create skills directory if it doesn't exist
625
+ if (!fs.existsSync(skillsDir)) {
626
+ fs.mkdirSync(skillsDir, { recursive: true });
622
627
  }
623
628
 
624
- // Read command file content
625
- const cmdPath = path.join(commandsDir, cmdFile);
626
- let content = fs.readFileSync(cmdPath, 'utf8');
629
+ // Convert each command to skill format
630
+ // commands/ralph-loop.md -> skills/ralph-loop/SKILL.md
631
+ const commands = fs.readdirSync(commandsDir).filter(f => f.endsWith('.md'));
632
+ for (const cmdFile of commands) {
633
+ const skillName = cmdFile.replace('.md', '');
634
+ const skillDir = path.join(skillsDir, skillName);
635
+ const skillFile = path.join(skillDir, 'SKILL.md');
636
+
637
+ // Create skill directory
638
+ if (!fs.existsSync(skillDir)) {
639
+ fs.mkdirSync(skillDir, { recursive: true });
640
+ }
627
641
 
628
- // Fix frontmatter: replace hide-from-slash-command-tool with name
629
- content = content.replace(
630
- /hide-from-slash-command-tool:\s*["']true["']/g,
631
- `name: ${skillName}`
632
- );
642
+ // Read command file content
643
+ const cmdPath = path.join(commandsDir, cmdFile);
644
+ let content = fs.readFileSync(cmdPath, 'utf8');
633
645
 
634
- // Write skill file (always overwrite to ensure fix is applied)
635
- fs.writeFileSync(skillFile, content, 'utf8');
646
+ // Fix frontmatter: replace hide-from-slash-command-tool with name
647
+ content = content.replace(
648
+ /hide-from-slash-command-tool:\s*["']true["']/g,
649
+ `name: ${skillName}`
650
+ );
651
+
652
+ // Write skill file (always overwrite to ensure fix is applied)
653
+ fs.writeFileSync(skillFile, content, 'utf8');
654
+ }
636
655
  }
637
656
  }
638
657
  }