jettypod 4.4.75 → 4.4.77

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/jettypod.js CHANGED
@@ -814,36 +814,64 @@ async function initializeProject() {
814
814
  ensureJettypodGitignores();
815
815
 
816
816
  const claudeSettingsPath = path.join('.claude', 'settings.json');
817
- if (!fs.existsSync(claudeSettingsPath)) {
818
- const claudeSettings = {
819
- hooks: {
820
- PreToolUse: [
821
- {
822
- matcher: 'Edit',
823
- hooks: [
824
- { type: 'command', command: '.jettypod/hooks/global-guardrails.js' },
825
- { type: 'command', command: '.jettypod/hooks/protect-claude-md.js' }
826
- ]
827
- },
828
- {
829
- matcher: 'Write',
830
- hooks: [
831
- { type: 'command', command: '.jettypod/hooks/global-guardrails.js' },
832
- { type: 'command', command: '.jettypod/hooks/protect-claude-md.js' }
833
- ]
834
- },
835
- {
836
- matcher: 'Bash',
837
- hooks: [
838
- { type: 'command', command: '.jettypod/hooks/global-guardrails.js' },
839
- { type: 'command', command: '.jettypod/hooks/enforce-skill-activation.js' }
840
- ]
841
- }
842
- ]
817
+
818
+ // Required hooks configuration - always ensure these are present
819
+ const requiredHooks = {
820
+ Edit: [
821
+ '.jettypod/hooks/global-guardrails.js',
822
+ '.jettypod/hooks/protect-claude-md.js'
823
+ ],
824
+ Write: [
825
+ '.jettypod/hooks/global-guardrails.js',
826
+ '.jettypod/hooks/protect-claude-md.js'
827
+ ],
828
+ Bash: [
829
+ '.jettypod/hooks/global-guardrails.js',
830
+ '.jettypod/hooks/enforce-skill-activation.js'
831
+ ]
832
+ };
833
+
834
+ // Load existing settings or create empty structure
835
+ let claudeSettings = { hooks: { PreToolUse: [] } };
836
+ if (fs.existsSync(claudeSettingsPath)) {
837
+ try {
838
+ claudeSettings = JSON.parse(fs.readFileSync(claudeSettingsPath, 'utf-8'));
839
+ if (!claudeSettings.hooks) claudeSettings.hooks = {};
840
+ if (!claudeSettings.hooks.PreToolUse) claudeSettings.hooks.PreToolUse = [];
841
+ } catch {
842
+ // Invalid JSON, start fresh
843
+ claudeSettings = { hooks: { PreToolUse: [] } };
844
+ }
845
+ }
846
+
847
+ // Ensure required hooks are present for each matcher
848
+ let hooksUpdated = false;
849
+ for (const [matcher, requiredCommands] of Object.entries(requiredHooks)) {
850
+ // Find existing entry for this matcher
851
+ let matcherEntry = claudeSettings.hooks.PreToolUse.find(e => e.matcher === matcher);
852
+
853
+ if (!matcherEntry) {
854
+ // Create new entry for this matcher
855
+ matcherEntry = { matcher, hooks: [] };
856
+ claudeSettings.hooks.PreToolUse.push(matcherEntry);
857
+ hooksUpdated = true;
858
+ }
859
+
860
+ // Ensure each required command is present
861
+ for (const command of requiredCommands) {
862
+ const hasCommand = matcherEntry.hooks.some(h => h.command === command);
863
+ if (!hasCommand) {
864
+ // Add required hook at the beginning (guardrails should run first)
865
+ matcherEntry.hooks.unshift({ type: 'command', command });
866
+ hooksUpdated = true;
843
867
  }
844
- };
845
- fs.writeFileSync(claudeSettingsPath, JSON.stringify(claudeSettings, null, 2));
846
- console.log('⚙️ Claude Code hooks configured');
868
+ }
869
+ }
870
+
871
+ // Write updated settings
872
+ fs.writeFileSync(claudeSettingsPath, JSON.stringify(claudeSettings, null, 2));
873
+ if (hooksUpdated) {
874
+ console.log('⚙️ Claude Code hooks updated');
847
875
  }
848
876
 
849
877
  // Copy skills directory
@@ -1,5 +1,7 @@
1
1
  const { execSync } = require('child_process');
2
2
  const https = require('https');
3
+ const fs = require('fs');
4
+ const path = require('path');
3
5
  const packageJson = require('../../package.json');
4
6
 
5
7
  /**
@@ -83,6 +85,18 @@ function updateJettyPod(version = 'latest') {
83
85
  stdio: 'inherit'
84
86
  });
85
87
 
88
+ // Clear dashboard .next folder to force rebuild with new assets
89
+ try {
90
+ const globalRoot = execSync('npm root -g', { encoding: 'utf-8' }).trim();
91
+ const dashboardNextPath = path.join(globalRoot, 'jettypod', 'apps', 'dashboard', '.next');
92
+ if (fs.existsSync(dashboardNextPath)) {
93
+ fs.rmSync(dashboardNextPath, { recursive: true, force: true });
94
+ console.log('🧹 Cleared dashboard cache');
95
+ }
96
+ } catch {
97
+ // Non-fatal - dashboard will still work, just might use old cache
98
+ }
99
+
86
100
  return true;
87
101
  } catch (err) {
88
102
  console.log('');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jettypod",
3
- "version": "4.4.75",
3
+ "version": "4.4.77",
4
4
  "description": "AI-powered development workflow manager with TDD, BDD, and automatic test generation",
5
5
  "main": "jettypod.js",
6
6
  "bin": {