master-skill 0.12.12 → 0.12.13
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.
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
{
|
|
10
10
|
"name": "master-skill",
|
|
11
11
|
"description": "FoJin-powered Buddhist AI persona framework — source-grounded, boundary-aware, fidelity-tested, runtime-ready. 15 prebuilt masters across 印度/汉传/藏传/南传 plus compare, debate, and curriculum meta-skills.",
|
|
12
|
-
"version": "0.12.
|
|
12
|
+
"version": "0.12.13",
|
|
13
13
|
"source": "./",
|
|
14
14
|
"author": {
|
|
15
15
|
"name": "xr843",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "master-skill",
|
|
3
3
|
"description": "FoJin-powered Buddhist AI persona framework — source-grounded, boundary-aware, fidelity-tested, runtime-ready. 15 prebuilt masters across 印度/汉传/藏传/南传 plus compare, debate, and curriculum meta-skills.",
|
|
4
|
-
"version": "0.12.
|
|
4
|
+
"version": "0.12.13",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "xr843",
|
|
7
7
|
"email": "xr843@users.noreply.github.com"
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "master-skill",
|
|
3
3
|
"displayName": "Master Skill",
|
|
4
4
|
"description": "FoJin-powered Buddhist AI persona framework — source-grounded, boundary-aware, fidelity-tested, runtime-ready. 15 prebuilt masters across 印度/汉传/藏传/南传.",
|
|
5
|
-
"version": "0.12.
|
|
5
|
+
"version": "0.12.13",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "xr843",
|
|
8
8
|
"email": "xr843@users.noreply.github.com"
|
package/bin/cli.mjs
CHANGED
|
@@ -405,7 +405,40 @@ function cmdInstallAll(label = "Installing") {
|
|
|
405
405
|
return cmdInstall(all);
|
|
406
406
|
}
|
|
407
407
|
|
|
408
|
-
|
|
408
|
+
// Directories under create-master/masters/ — personas the user generated. `update`
|
|
409
|
+
// carries them across (replaceGeneratorInstall); `uninstall` must not quietly
|
|
410
|
+
// delete them either.
|
|
411
|
+
function generatedPersonas(generatorDir) {
|
|
412
|
+
const mastersDir = path.join(generatorDir, "masters");
|
|
413
|
+
if (!fs.existsSync(mastersDir)) return [];
|
|
414
|
+
return fs
|
|
415
|
+
.readdirSync(mastersDir, { withFileTypes: true })
|
|
416
|
+
.filter((entry) => entry.isDirectory())
|
|
417
|
+
.map((entry) => entry.name)
|
|
418
|
+
.sort();
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// Links in the skills directory that `master_builder.py --register` made into
|
|
422
|
+
// this generator's masters/. Resolved with realpath so a Windows junction is
|
|
423
|
+
// recognised as well as a symlink.
|
|
424
|
+
function registrationsInto(generatorDir) {
|
|
425
|
+
const mastersDir = path.join(generatorDir, "masters");
|
|
426
|
+
if (!fs.existsSync(mastersDir) || !fs.existsSync(SKILLS_DIR)) return [];
|
|
427
|
+
const realMasters = fs.realpathSync(mastersDir);
|
|
428
|
+
return fs
|
|
429
|
+
.readdirSync(SKILLS_DIR, { withFileTypes: true })
|
|
430
|
+
.filter((entry) => entry.isSymbolicLink())
|
|
431
|
+
.map((entry) => path.join(SKILLS_DIR, entry.name))
|
|
432
|
+
.filter((link) => {
|
|
433
|
+
try {
|
|
434
|
+
return fs.realpathSync(link).startsWith(realMasters + path.sep);
|
|
435
|
+
} catch {
|
|
436
|
+
return false;
|
|
437
|
+
}
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
function cmdUninstall(names, { force = false } = {}) {
|
|
409
442
|
let failed = 0;
|
|
410
443
|
for (const name of names) {
|
|
411
444
|
if (!isSafeName(name)) {
|
|
@@ -429,6 +462,26 @@ function cmdUninstall(names) {
|
|
|
429
462
|
failed++;
|
|
430
463
|
continue;
|
|
431
464
|
}
|
|
465
|
+
if (skill.kind === "generator") {
|
|
466
|
+
// Until 2026-09-17 this removed the whole directory, masters/ included:
|
|
467
|
+
// every persona the user had generated was deleted with "✓ removed" and
|
|
468
|
+
// exit 0, and the links registered for them were left pointing at nothing.
|
|
469
|
+
const generated = generatedPersonas(dest);
|
|
470
|
+
if (generated.length && !force) {
|
|
471
|
+
console.log(
|
|
472
|
+
` ✗ ${name} — holds ${generated.length} persona(s) you generated: ${generated.join(", ")}`
|
|
473
|
+
);
|
|
474
|
+
console.log(
|
|
475
|
+
` Uninstalling deletes ${path.join(dest, "masters")}. Move it somewhere safe first, or rerun with --force.`
|
|
476
|
+
);
|
|
477
|
+
failed++;
|
|
478
|
+
continue;
|
|
479
|
+
}
|
|
480
|
+
for (const link of registrationsInto(dest)) {
|
|
481
|
+
fs.unlinkSync(link);
|
|
482
|
+
console.log(` ✓ ${path.basename(link)} link removed (${link})`);
|
|
483
|
+
}
|
|
484
|
+
}
|
|
432
485
|
fs.rmSync(dest, { recursive: true, force: true });
|
|
433
486
|
console.log(` ✓ ${name} removed (${dest})`);
|
|
434
487
|
}
|
|
@@ -513,7 +566,9 @@ function installedProblems() {
|
|
|
513
566
|
}
|
|
514
567
|
|
|
515
568
|
// Personas registered by create-master are links into create-master/masters/;
|
|
516
|
-
//
|
|
569
|
+
// deleting or moving a generated persona by hand leaves its link pointing at
|
|
570
|
+
// nothing. (`uninstall create-master` refuses while personas exist, and with
|
|
571
|
+
// --force removes their links itself.)
|
|
517
572
|
if (fs.existsSync(SKILLS_DIR)) {
|
|
518
573
|
for (const entry of fs.readdirSync(SKILLS_DIR, { withFileTypes: true })) {
|
|
519
574
|
if (!entry.isSymbolicLink()) continue;
|
|
@@ -909,6 +964,8 @@ Usage:
|
|
|
909
964
|
master-skill doctor Check local install and runtime paths
|
|
910
965
|
master-skill doctor --json Print diagnostics as JSON
|
|
911
966
|
master-skill uninstall <name...> Remove installed skills
|
|
967
|
+
master-skill uninstall create-master --force
|
|
968
|
+
Also delete the personas you generated (refused otherwise)
|
|
912
969
|
master-skill --version Print version
|
|
913
970
|
master-skill --help Show this help
|
|
914
971
|
|
|
@@ -936,7 +993,8 @@ Examples:
|
|
|
936
993
|
if (CATALOG) {
|
|
937
994
|
const args = process.argv.slice(2);
|
|
938
995
|
const json = args.includes("--json");
|
|
939
|
-
const
|
|
996
|
+
const force = args.includes("--force");
|
|
997
|
+
const positionalArgs = args.filter((arg) => arg !== "--json" && arg !== "--force");
|
|
940
998
|
const cmd = positionalArgs[0];
|
|
941
999
|
|
|
942
1000
|
if (!cmd || cmd === "--help" || cmd === "-h") {
|
|
@@ -977,7 +1035,7 @@ if (CATALOG) {
|
|
|
977
1035
|
console.log("Usage: master-skill uninstall <name...>");
|
|
978
1036
|
process.exitCode = 1;
|
|
979
1037
|
} else {
|
|
980
|
-
if (cmdUninstall(rest) > 0) process.exitCode = 1;
|
|
1038
|
+
if (cmdUninstall(rest, { force }) > 0) process.exitCode = 1;
|
|
981
1039
|
}
|
|
982
1040
|
} else {
|
|
983
1041
|
console.log(`Unknown command: ${cmd}\nRun master-skill --help for usage.`);
|
package/gemini-extension.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "master-skill",
|
|
3
3
|
"description": "FoJin-powered Buddhist AI persona framework — source-grounded, boundary-aware, fidelity-tested, runtime-ready. 15 prebuilt masters across 印度/汉传/藏传/南传.",
|
|
4
|
-
"version": "0.12.
|
|
4
|
+
"version": "0.12.13",
|
|
5
5
|
"contextFileName": "GEMINI.md"
|
|
6
6
|
}
|
package/hooks/session-start
CHANGED
|
@@ -61,7 +61,8 @@ emit_modes_only() {
|
|
|
61
61
|
if [ -n "${CURSOR_PLUGIN_ROOT:-}" ]; then
|
|
62
62
|
printf '{"additional_context": %s}\n' "$MODES_JSON"
|
|
63
63
|
elif [ -n "${CLAUDE_PLUGIN_ROOT:-}" ] && [ -z "${COPILOT_CLI:-}" ]; then
|
|
64
|
-
|
|
64
|
+
# hookEventName is required; without it Claude Code rejects the payload.
|
|
65
|
+
printf '{"hookSpecificOutput": {"hookEventName": "SessionStart", "additionalContext": %s}}\n' "$MODES_JSON"
|
|
65
66
|
else
|
|
66
67
|
printf '{"additionalContext": %s}\n' "$MODES_JSON"
|
|
67
68
|
fi
|
package/hooks/session_start.py
CHANGED
|
@@ -136,7 +136,17 @@ def wrap_for_host(context: str, env: dict) -> dict:
|
|
|
136
136
|
if env.get("CURSOR_PLUGIN_ROOT"):
|
|
137
137
|
return {"additional_context": context}
|
|
138
138
|
if env.get("CLAUDE_PLUGIN_ROOT") and not env.get("COPILOT_CLI"):
|
|
139
|
-
|
|
139
|
+
# `hookEventName` is required. Without it Claude Code 2.1.273 rejects the
|
|
140
|
+
# whole payload — "Hook JSON output validation failed — hookSpecificOutput
|
|
141
|
+
# is missing required field hookEventName" — shows that error at every
|
|
142
|
+
# session start, and injects nothing. Measured 2026-09-17 in an isolated
|
|
143
|
+
# plugin install; the transcript recorded `hook_non_blocking_error`.
|
|
144
|
+
return {
|
|
145
|
+
"hookSpecificOutput": {
|
|
146
|
+
"hookEventName": "SessionStart",
|
|
147
|
+
"additionalContext": context,
|
|
148
|
+
}
|
|
149
|
+
}
|
|
140
150
|
return {"additionalContext": context}
|
|
141
151
|
|
|
142
152
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "master-skill",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.13",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "FoJin-powered Buddhist AI persona framework — source-grounded, boundary-aware, fidelity-tested, runtime-ready. 15 pre-built masters across 印度 / 汉传 / 藏传 / 南传, plus /compare-masters, /master-debate, and /master-curriculum.",
|
|
6
6
|
"bin": {
|