@massa-ai/codex-plugin 1.53.0 → 1.54.1
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/.codex-plugin/plugin.json +1 -1
- package/install.sh +32 -4
- package/package.json +1 -1
package/install.sh
CHANGED
|
@@ -184,8 +184,28 @@ if (typeof cfg.hooks !== "object" || cfg.hooks === null) {
|
|
|
184
184
|
cfg.hooks = {};
|
|
185
185
|
}
|
|
186
186
|
|
|
187
|
+
// Ownership test — marker first, command shape as the fallback. The marker is
|
|
188
|
+
// precise but not the only way our entries reach this file: an entry written by
|
|
189
|
+
// a release before the marker existed, or copied by hand from documentation,
|
|
190
|
+
// carries none, and was invisible to BOTH directions here — never deduped on
|
|
191
|
+
// install, never removed on uninstall. Claude's copy of this merge had exactly
|
|
192
|
+
// that gap and it double-fired every lifecycle event (measured live
|
|
193
|
+
// 2026-08-17). Referencing the massa-ai-hook binary is unambiguous; a user hook
|
|
194
|
+
// that merely mentions massa-ai elsewhere does not match.
|
|
195
|
+
//
|
|
196
|
+
// isOwned covers both shapes this file has ever held: the flat pre-fix entry
|
|
197
|
+
// (command at the top level) and the matcher group (commands inside hooks[]).
|
|
198
|
+
const OWNED_COMMAND = /massa-ai-hook/;
|
|
199
|
+
|
|
200
|
+
function commandIsOwned(h) {
|
|
201
|
+
return Boolean(h) && typeof h.command === "string" && OWNED_COMMAND.test(h.command);
|
|
202
|
+
}
|
|
203
|
+
|
|
187
204
|
function isOwned(e) {
|
|
188
|
-
|
|
205
|
+
if (!e || typeof e !== "object") return false;
|
|
206
|
+
if (e._massaAiOwned === true) return true;
|
|
207
|
+
if (commandIsOwned(e)) return true;
|
|
208
|
+
return Array.isArray(e.hooks) && e.hooks.length > 0 && e.hooks.every(commandIsOwned);
|
|
189
209
|
}
|
|
190
210
|
|
|
191
211
|
// A correctly-shaped owned entry is a matcher group: its "hooks" is an array.
|
|
@@ -202,10 +222,18 @@ if (mode === "uninstall") {
|
|
|
202
222
|
// Remove owned entries from nested location + perform flat→nested migration
|
|
203
223
|
const hooks = cfg.hooks;
|
|
204
224
|
|
|
205
|
-
//
|
|
206
|
-
|
|
225
|
+
// Back up before removing: this now deletes unmarked entries it did not
|
|
226
|
+
// necessarily write, so the install path's backup discipline applies here too.
|
|
227
|
+
if (existed) {
|
|
228
|
+
fs.copyFileSync(file, `${file}.massa-ai.bak-${ts}`);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Remove owned entries from the correct nested location. Every event, not
|
|
232
|
+
// just the ones this release writes — the predicate identifies our commands
|
|
233
|
+
// rather than a location.
|
|
234
|
+
for (const evt of Object.keys(hooks)) {
|
|
207
235
|
if (Array.isArray(hooks[evt])) {
|
|
208
|
-
hooks[evt] = hooks[evt].filter((e) => !(e
|
|
236
|
+
hooks[evt] = hooks[evt].filter((e) => !isOwned(e));
|
|
209
237
|
if (hooks[evt].length === 0) delete hooks[evt];
|
|
210
238
|
}
|
|
211
239
|
}
|