jettypod 4.4.76 → 4.4.78
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 +80 -38
- package/package.json +1 -1
package/jettypod.js
CHANGED
|
@@ -705,6 +705,77 @@ async function generateClaude(options = {}) {
|
|
|
705
705
|
console.log('📝 CLAUDE.md generated');
|
|
706
706
|
}
|
|
707
707
|
|
|
708
|
+
// Ensure Claude Code hooks are up to date (called on every jettypod launch)
|
|
709
|
+
function ensureClaudeHooks() {
|
|
710
|
+
// Create .claude directory if needed
|
|
711
|
+
if (!fs.existsSync('.claude')) {
|
|
712
|
+
fs.mkdirSync('.claude', { recursive: true });
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
const claudeSettingsPath = path.join('.claude', 'settings.json');
|
|
716
|
+
|
|
717
|
+
// Required hooks configuration - always ensure these are present
|
|
718
|
+
const requiredHooks = {
|
|
719
|
+
Edit: [
|
|
720
|
+
'.jettypod/hooks/global-guardrails.js',
|
|
721
|
+
'.jettypod/hooks/protect-claude-md.js'
|
|
722
|
+
],
|
|
723
|
+
Write: [
|
|
724
|
+
'.jettypod/hooks/global-guardrails.js',
|
|
725
|
+
'.jettypod/hooks/protect-claude-md.js'
|
|
726
|
+
],
|
|
727
|
+
Bash: [
|
|
728
|
+
'.jettypod/hooks/global-guardrails.js',
|
|
729
|
+
'.jettypod/hooks/enforce-skill-activation.js'
|
|
730
|
+
]
|
|
731
|
+
};
|
|
732
|
+
|
|
733
|
+
// Load existing settings or create empty structure
|
|
734
|
+
let claudeSettings = { hooks: { PreToolUse: [] } };
|
|
735
|
+
if (fs.existsSync(claudeSettingsPath)) {
|
|
736
|
+
try {
|
|
737
|
+
claudeSettings = JSON.parse(fs.readFileSync(claudeSettingsPath, 'utf-8'));
|
|
738
|
+
if (!claudeSettings.hooks) claudeSettings.hooks = {};
|
|
739
|
+
if (!claudeSettings.hooks.PreToolUse) claudeSettings.hooks.PreToolUse = [];
|
|
740
|
+
} catch {
|
|
741
|
+
// Invalid JSON, start fresh
|
|
742
|
+
claudeSettings = { hooks: { PreToolUse: [] } };
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
// Ensure required hooks are present for each matcher
|
|
747
|
+
let hooksUpdated = false;
|
|
748
|
+
for (const [matcher, requiredCommands] of Object.entries(requiredHooks)) {
|
|
749
|
+
// Find existing entry for this matcher
|
|
750
|
+
let matcherEntry = claudeSettings.hooks.PreToolUse.find(e => e.matcher === matcher);
|
|
751
|
+
|
|
752
|
+
if (!matcherEntry) {
|
|
753
|
+
// Create new entry for this matcher
|
|
754
|
+
matcherEntry = { matcher, hooks: [] };
|
|
755
|
+
claudeSettings.hooks.PreToolUse.push(matcherEntry);
|
|
756
|
+
hooksUpdated = true;
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
// Ensure each required command is present
|
|
760
|
+
for (const command of requiredCommands) {
|
|
761
|
+
const hasCommand = matcherEntry.hooks.some(h => h.command === command);
|
|
762
|
+
if (!hasCommand) {
|
|
763
|
+
// Add required hook at the beginning (guardrails should run first)
|
|
764
|
+
matcherEntry.hooks.unshift({ type: 'command', command });
|
|
765
|
+
hooksUpdated = true;
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
// Write updated settings
|
|
771
|
+
fs.writeFileSync(claudeSettingsPath, JSON.stringify(claudeSettings, null, 2));
|
|
772
|
+
if (hooksUpdated) {
|
|
773
|
+
console.log('⚙️ Claude Code hooks updated');
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
return hooksUpdated;
|
|
777
|
+
}
|
|
778
|
+
|
|
708
779
|
// Initialize project (used by both 'jettypod init' and 'jettypod' with no args)
|
|
709
780
|
async function initializeProject() {
|
|
710
781
|
const { showLogo } = require('./lib/terminal-logo');
|
|
@@ -805,46 +876,11 @@ async function initializeProject() {
|
|
|
805
876
|
fs.chmodSync(guardrailsHookDest, 0o755);
|
|
806
877
|
}
|
|
807
878
|
|
|
808
|
-
// Create Claude Code settings
|
|
809
|
-
if (!fs.existsSync('.claude')) {
|
|
810
|
-
fs.mkdirSync('.claude', { recursive: true });
|
|
811
|
-
}
|
|
812
|
-
|
|
813
879
|
// Ensure .claude/session.md is gitignored and untracked
|
|
814
880
|
ensureJettypodGitignores();
|
|
815
881
|
|
|
816
|
-
|
|
817
|
-
|
|
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
|
-
]
|
|
843
|
-
}
|
|
844
|
-
};
|
|
845
|
-
fs.writeFileSync(claudeSettingsPath, JSON.stringify(claudeSettings, null, 2));
|
|
846
|
-
console.log('⚙️ Claude Code hooks configured');
|
|
847
|
-
}
|
|
882
|
+
// Ensure Claude Code hooks are up to date
|
|
883
|
+
ensureClaudeHooks();
|
|
848
884
|
|
|
849
885
|
// Copy skills directory
|
|
850
886
|
// Allow tests to override skills source directory
|
|
@@ -1135,8 +1171,11 @@ switch (command) {
|
|
|
1135
1171
|
const updateCommand = require('./lib/update-command');
|
|
1136
1172
|
const success = await updateCommand.runUpdate();
|
|
1137
1173
|
|
|
1138
|
-
// Always refresh skills in current project after update attempt
|
|
1174
|
+
// Always refresh skills and hooks in current project after update attempt
|
|
1139
1175
|
if (fs.existsSync('.jettypod')) {
|
|
1176
|
+
// Update Claude Code hooks first
|
|
1177
|
+
ensureClaudeHooks();
|
|
1178
|
+
|
|
1140
1179
|
console.log('');
|
|
1141
1180
|
console.log('🔄 Refreshing skills in current project...');
|
|
1142
1181
|
|
|
@@ -2071,6 +2110,9 @@ switch (command) {
|
|
|
2071
2110
|
const currentConfig = config.read();
|
|
2072
2111
|
await generateClaude();
|
|
2073
2112
|
|
|
2113
|
+
// Ensure Claude Code hooks are up to date on every launch
|
|
2114
|
+
ensureClaudeHooks();
|
|
2115
|
+
|
|
2074
2116
|
// Launch dashboard
|
|
2075
2117
|
const dashboardPath = path.join(__dirname, 'apps', 'dashboard');
|
|
2076
2118
|
const BASE_PORT = 3456;
|