@massa-ai/claude-plugin 1.10.0 → 1.12.0
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/.claude-plugin/plugin.json +1 -1
- package/install.sh +81 -12
- package/package.json +1 -1
package/install.sh
CHANGED
|
@@ -291,7 +291,13 @@ if (typeof data.platforms !== "object" || data.platforms === null || Array.isArr
|
|
|
291
291
|
data.platforms = {};
|
|
292
292
|
}
|
|
293
293
|
data.version = 2;
|
|
294
|
+
const prev = data.platforms[host];
|
|
294
295
|
data.platforms[host] = { root, skillsOwner: "plugin", skills: ["massa-ai", "persona-router"] };
|
|
296
|
+
// The whole-record replace must not drop the plugin version record a previous
|
|
297
|
+
// successful install wrote (R2) — re-attach it.
|
|
298
|
+
if (prev && typeof prev === "object" && !Array.isArray(prev) && prev.plugin && typeof prev.plugin === "object") {
|
|
299
|
+
data.platforms[host].plugin = prev.plugin;
|
|
300
|
+
}
|
|
295
301
|
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
296
302
|
fs.writeFileSync(file, JSON.stringify(data, null, 2) + "\n");
|
|
297
303
|
NODE
|
|
@@ -319,28 +325,87 @@ try {
|
|
|
319
325
|
}
|
|
320
326
|
NODE
|
|
321
327
|
)"
|
|
322
|
-
[[ "$raw_owner" == "plugin" ]]
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
328
|
+
[[ "$raw_owner" == "plugin" ]] && {
|
|
329
|
+
local name
|
|
330
|
+
for name in massa-ai persona-router; do
|
|
331
|
+
rm -rf "$HARNESS_SKILLS_DIR/$name"
|
|
332
|
+
done
|
|
333
|
+
rmdir "$HARNESS_SKILLS_DIR" 2>/dev/null || true
|
|
334
|
+
echo " - removed plugin-owned harness skills from $HARNESS_SKILLS_DIR"
|
|
335
|
+
}
|
|
330
336
|
|
|
337
|
+
# AC-15: a plugin-owned platform keeps the whole-record delete (clean-slate
|
|
338
|
+
# semantics unchanged); any other platform loses only its plugin version
|
|
339
|
+
# record while root/skills/skillsOwner survive (Plan Challenge C-4).
|
|
331
340
|
"$runner" - "$HARNESS_STATE_FILE" "$HARNESS_HOST" <<'NODE'
|
|
332
341
|
const fs = require("fs");
|
|
333
342
|
const [, , file, host] = process.argv;
|
|
334
343
|
try {
|
|
335
344
|
const data = JSON.parse(fs.readFileSync(file, "utf8"));
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
345
|
+
const rec = data && data.platforms && data.platforms[host];
|
|
346
|
+
if (rec && typeof rec === "object") {
|
|
347
|
+
if (rec.skillsOwner === "plugin") {
|
|
348
|
+
delete data.platforms[host];
|
|
349
|
+
fs.writeFileSync(file, JSON.stringify(data, null, 2) + "\n");
|
|
350
|
+
} else if (rec.plugin && typeof rec.plugin === "object") {
|
|
351
|
+
delete rec.plugin;
|
|
352
|
+
fs.writeFileSync(file, JSON.stringify(data, null, 2) + "\n");
|
|
353
|
+
}
|
|
339
354
|
}
|
|
340
355
|
} catch { /* nothing to clean up */ }
|
|
341
356
|
NODE
|
|
342
357
|
}
|
|
343
358
|
|
|
359
|
+
# ── Plugin version recording (PAI-03/04/07) ─────────────────────────────────
|
|
360
|
+
# Why: the harness gates re-runs on the recorded bundle version, so a
|
|
361
|
+
# successful install records it — but ONLY as the final step of the
|
|
362
|
+
# install path. A version written before a later step fails would mark a
|
|
363
|
+
# broken install "current" and skip it forever (AC-16, Plan Challenge C-1).
|
|
364
|
+
# Impacts: PAI-03 record, PAI-04 upgrade trigger, PAI-07 uninstall, AC-3/16.
|
|
365
|
+
# Test: bash scripts/tests/test-plugin-auto-install.sh (Section 3 e2e chain)
|
|
366
|
+
record_plugin_version() {
|
|
367
|
+
local runner=""
|
|
368
|
+
if command -v node &>/dev/null; then runner="node"
|
|
369
|
+
elif command -v bun &>/dev/null; then runner="bun"
|
|
370
|
+
else
|
|
371
|
+
echo " ⚠ node or bun required to record the plugin version — next run will reinstall" >&2
|
|
372
|
+
return 0
|
|
373
|
+
fi
|
|
374
|
+
|
|
375
|
+
local version installed_at
|
|
376
|
+
version="$(sed -n 's/.*"version"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' "$SCRIPT_DIR/package.json" | head -n 1)"
|
|
377
|
+
installed_at="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
378
|
+
|
|
379
|
+
# Tolerant of a corrupt/missing state file (rewrites a minimal valid one —
|
|
380
|
+
# AC-8). A record-write failure warns but never fails the install: the next
|
|
381
|
+
# run treats the host as unknown-version and reinstalls.
|
|
382
|
+
"$runner" - "$HARNESS_STATE_FILE" "$HARNESS_HOST" "$TARGET" "$version" "$installed_at" <<'NODE' || \
|
|
383
|
+
echo " ⚠ could not record the plugin version — next run will reinstall (unknown version)" >&2
|
|
384
|
+
const fs = require("fs");
|
|
385
|
+
const path = require("path");
|
|
386
|
+
const [, , file, host, root, version, installedAt] = process.argv;
|
|
387
|
+
let data = { version: 2, platforms: {} };
|
|
388
|
+
try {
|
|
389
|
+
const existing = JSON.parse(fs.readFileSync(file, "utf8"));
|
|
390
|
+
if (existing && typeof existing === "object" && !Array.isArray(existing)) data = existing;
|
|
391
|
+
} catch { /* fresh */ }
|
|
392
|
+
if (typeof data.platforms !== "object" || data.platforms === null || Array.isArray(data.platforms)) {
|
|
393
|
+
data.platforms = {};
|
|
394
|
+
}
|
|
395
|
+
data.version = 2;
|
|
396
|
+
// Preserve every unrelated field; a missing record gets the minimal shape the
|
|
397
|
+
// strict skills reader accepts (non-empty root + a skills list).
|
|
398
|
+
const rec =
|
|
399
|
+
data.platforms[host] && typeof data.platforms[host] === "object" && !Array.isArray(data.platforms[host])
|
|
400
|
+
? data.platforms[host]
|
|
401
|
+
: { root, skillsOwner: "plugin", skills: [] };
|
|
402
|
+
rec.plugin = { version, installedAt };
|
|
403
|
+
data.platforms[host] = rec;
|
|
404
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
405
|
+
fs.writeFileSync(file, JSON.stringify(data, null, 2) + "\n");
|
|
406
|
+
NODE
|
|
407
|
+
}
|
|
408
|
+
|
|
344
409
|
# ── Plugin-registry registration (delegated to the claude CLI) ──────────────
|
|
345
410
|
# The CLI owns the registry format, so it is the only supported way to make the
|
|
346
411
|
# plugin appear in /plugin. Every failure path returns non-zero and the caller
|
|
@@ -546,4 +611,8 @@ vecho " 1. Try: /massa-ai-status"
|
|
|
546
611
|
vecho " 2. Try: /massa-ai-map (on an indexed project)"
|
|
547
612
|
# ~/.claude.json, not ~/.claude/settings.json — Claude Code reads MCP
|
|
548
613
|
# definitions from the former; settings.json only holds approval controls.
|
|
549
|
-
vecho "💡 Hooks are wired by this plugin; MCP is registered in ~/.claude.json by scripts/install-agents.sh (single writer)."
|
|
614
|
+
vecho "💡 Hooks are wired by this plugin; MCP is registered in ~/.claude.json by scripts/install-agents.sh (single writer)."
|
|
615
|
+
|
|
616
|
+
# Final step of the install path: record the bundle version. Reached only when
|
|
617
|
+
# every fallible step succeeded (AC-16) — never on --uninstall (exits above).
|
|
618
|
+
record_plugin_version
|
package/package.json
CHANGED