coder-config 0.42.39 → 0.42.40

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.42.39';
5
+ const VERSION = '0.42.40';
6
6
 
7
7
  // Tool-specific path configurations
8
8
  const TOOL_PATHS = {
package/lib/sessions.js CHANGED
@@ -118,7 +118,7 @@ function installHooks() {
118
118
  // Continue even if chmod fails
119
119
  }
120
120
 
121
- // Add SessionStart hook (new format with matcher/hooks)
121
+ // Clean up and migrate SessionStart hooks to new format
122
122
  if (!settings.hooks.SessionStart) {
123
123
  settings.hooks.SessionStart = [];
124
124
  }
@@ -126,22 +126,75 @@ function installHooks() {
126
126
  settings.hooks.SessionStart = [settings.hooks.SessionStart];
127
127
  }
128
128
 
129
- // Check for hook in both old and new formats
130
- const hasStartHook = settings.hooks.SessionStart.some(h => {
129
+ // Filter out old format hooks and invalid entries, collect commands to migrate
130
+ const commandsToKeep = new Set();
131
+ settings.hooks.SessionStart = settings.hooks.SessionStart.filter(h => {
131
132
  if (typeof h !== 'object') return false;
132
- // Old format: { type, command }
133
- if (h.command === sessionStartHook) return true;
134
- // New format: { matcher, hooks: [{ type, command }] }
133
+ // Old format: { type, command } - remove but track command
134
+ if (h.command && !h.hooks) {
135
+ commandsToKeep.add(h.command);
136
+ return false;
137
+ }
138
+ // Invalid format: { matcher: {} } object - remove matcher
139
+ if (h.matcher && typeof h.matcher === 'object') {
140
+ delete h.matcher;
141
+ }
142
+ // New format with hooks array - keep
135
143
  if (Array.isArray(h.hooks)) {
136
- return h.hooks.some(hh => hh.command === sessionStartHook);
144
+ h.hooks.forEach(hh => {
145
+ if (hh.command) commandsToKeep.add(hh.command);
146
+ });
147
+ return true;
137
148
  }
138
149
  return false;
139
150
  });
140
- if (!hasStartHook) {
141
- // Use new hook format (no matcher for SessionStart)
151
+
152
+ // Add our hook command if not already present
153
+ commandsToKeep.add(sessionStartHook);
154
+
155
+ // Consolidate all commands into a single entry
156
+ if (settings.hooks.SessionStart.length === 0) {
142
157
  settings.hooks.SessionStart.push({
143
- hooks: [{ type: 'command', command: sessionStartHook }]
158
+ hooks: Array.from(commandsToKeep).map(cmd => ({ type: 'command', command: cmd }))
144
159
  });
160
+ } else {
161
+ // Add missing commands to existing entry
162
+ const existingCommands = new Set(
163
+ settings.hooks.SessionStart[0].hooks.map(h => h.command)
164
+ );
165
+ for (const cmd of commandsToKeep) {
166
+ if (!existingCommands.has(cmd)) {
167
+ settings.hooks.SessionStart[0].hooks.push({ type: 'command', command: cmd });
168
+ }
169
+ }
170
+ }
171
+
172
+ // Clean up SessionEnd hooks (same migration as SessionStart)
173
+ if (settings.hooks.SessionEnd && Array.isArray(settings.hooks.SessionEnd)) {
174
+ const endCommandsToKeep = new Set();
175
+ settings.hooks.SessionEnd = settings.hooks.SessionEnd.filter(h => {
176
+ if (typeof h !== 'object') return false;
177
+ if (h.command && !h.hooks) {
178
+ endCommandsToKeep.add(h.command);
179
+ return false;
180
+ }
181
+ if (h.matcher && typeof h.matcher === 'object') {
182
+ delete h.matcher;
183
+ }
184
+ if (Array.isArray(h.hooks)) {
185
+ h.hooks.forEach(hh => {
186
+ if (hh.command) endCommandsToKeep.add(hh.command);
187
+ });
188
+ return true;
189
+ }
190
+ return false;
191
+ });
192
+ // Consolidate remaining commands
193
+ if (endCommandsToKeep.size > 0 && settings.hooks.SessionEnd.length === 0) {
194
+ settings.hooks.SessionEnd.push({
195
+ hooks: Array.from(endCommandsToKeep).map(cmd => ({ type: 'command', command: cmd }))
196
+ });
197
+ }
145
198
  }
146
199
 
147
200
  // Add permission to write session context file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coder-config",
3
- "version": "0.42.39",
3
+ "version": "0.42.40",
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",
@@ -131,6 +131,7 @@ function installHooks() {
131
131
  // Continue
132
132
  }
133
133
 
134
+ // Clean up and migrate SessionStart hooks to new format
134
135
  if (!settings.hooks.SessionStart) {
135
136
  settings.hooks.SessionStart = [];
136
137
  }
@@ -138,22 +139,75 @@ function installHooks() {
138
139
  settings.hooks.SessionStart = [settings.hooks.SessionStart];
139
140
  }
140
141
 
141
- // Check for hook in both old and new formats
142
- const hasStartHook = settings.hooks.SessionStart.some(h => {
142
+ // Filter out old format hooks and invalid entries, collect commands to migrate
143
+ const commandsToKeep = new Set();
144
+ settings.hooks.SessionStart = settings.hooks.SessionStart.filter(h => {
143
145
  if (typeof h !== 'object') return false;
144
- // Old format: { type, command }
145
- if (h.command === sessionStartHook) return true;
146
- // New format: { matcher, hooks: [{ type, command }] }
146
+ // Old format: { type, command } - remove but track command
147
+ if (h.command && !h.hooks) {
148
+ commandsToKeep.add(h.command);
149
+ return false;
150
+ }
151
+ // Invalid format: { matcher: {} } object - remove matcher
152
+ if (h.matcher && typeof h.matcher === 'object') {
153
+ delete h.matcher;
154
+ }
155
+ // New format with hooks array - keep
147
156
  if (Array.isArray(h.hooks)) {
148
- return h.hooks.some(hh => hh.command === sessionStartHook);
157
+ h.hooks.forEach(hh => {
158
+ if (hh.command) commandsToKeep.add(hh.command);
159
+ });
160
+ return true;
149
161
  }
150
162
  return false;
151
163
  });
152
- if (!hasStartHook) {
153
- // Use new hook format (no matcher for SessionStart)
164
+
165
+ // Add our hook command if not already present
166
+ commandsToKeep.add(sessionStartHook);
167
+
168
+ // Consolidate all commands into a single entry
169
+ if (settings.hooks.SessionStart.length === 0) {
154
170
  settings.hooks.SessionStart.push({
155
- hooks: [{ type: 'command', command: sessionStartHook }]
171
+ hooks: Array.from(commandsToKeep).map(cmd => ({ type: 'command', command: cmd }))
172
+ });
173
+ } else {
174
+ // Add missing commands to existing entry
175
+ const existingCommands = new Set(
176
+ settings.hooks.SessionStart[0].hooks.map(h => h.command)
177
+ );
178
+ for (const cmd of commandsToKeep) {
179
+ if (!existingCommands.has(cmd)) {
180
+ settings.hooks.SessionStart[0].hooks.push({ type: 'command', command: cmd });
181
+ }
182
+ }
183
+ }
184
+
185
+ // Clean up SessionEnd hooks (same migration as SessionStart)
186
+ if (settings.hooks.SessionEnd && Array.isArray(settings.hooks.SessionEnd)) {
187
+ const endCommandsToKeep = new Set();
188
+ settings.hooks.SessionEnd = settings.hooks.SessionEnd.filter(h => {
189
+ if (typeof h !== 'object') return false;
190
+ if (h.command && !h.hooks) {
191
+ endCommandsToKeep.add(h.command);
192
+ return false;
193
+ }
194
+ if (h.matcher && typeof h.matcher === 'object') {
195
+ delete h.matcher;
196
+ }
197
+ if (Array.isArray(h.hooks)) {
198
+ h.hooks.forEach(hh => {
199
+ if (hh.command) endCommandsToKeep.add(hh.command);
200
+ });
201
+ return true;
202
+ }
203
+ return false;
156
204
  });
205
+ // Consolidate remaining commands
206
+ if (endCommandsToKeep.size > 0 && settings.hooks.SessionEnd.length === 0) {
207
+ settings.hooks.SessionEnd.push({
208
+ hooks: Array.from(endCommandsToKeep).map(cmd => ({ type: 'command', command: cmd }))
209
+ });
210
+ }
157
211
  }
158
212
 
159
213
  // Add permission to write session context file