@gobing-ai/superskill 0.2.5 → 0.2.7
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/dist/index.js +290 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -40829,7 +40829,7 @@ var init_dist5 = __esm(() => {
|
|
|
40829
40829
|
});
|
|
40830
40830
|
|
|
40831
40831
|
// ../../packages/core/src/targets.ts
|
|
40832
|
-
var TARGETS, TARGET_TO_RULESYNC, TARGET_SKILLS_RELDIR, TARGET_TO_AGENT_NAME;
|
|
40832
|
+
var TARGETS, TARGET_TO_RULESYNC, TARGET_TO_RULESYNC_HOOKS, TARGET_SKILLS_RELDIR, TARGET_TO_AGENT_NAME;
|
|
40833
40833
|
var init_targets = __esm(() => {
|
|
40834
40834
|
TARGETS = [
|
|
40835
40835
|
"claude",
|
|
@@ -40848,6 +40848,12 @@ var init_targets = __esm(() => {
|
|
|
40848
40848
|
"antigravity-cli": "codexcli",
|
|
40849
40849
|
"antigravity-ide": "codexcli"
|
|
40850
40850
|
};
|
|
40851
|
+
TARGET_TO_RULESYNC_HOOKS = {
|
|
40852
|
+
codex: "codexcli",
|
|
40853
|
+
opencode: "opencode",
|
|
40854
|
+
"antigravity-cli": "antigravity-cli",
|
|
40855
|
+
"antigravity-ide": "antigravity-ide"
|
|
40856
|
+
};
|
|
40851
40857
|
TARGET_SKILLS_RELDIR = {
|
|
40852
40858
|
codex: ".agents/skills",
|
|
40853
40859
|
pi: ".agents/skills",
|
|
@@ -89666,9 +89672,10 @@ var init_dist9 = __esm(() => {
|
|
|
89666
89672
|
// ../../packages/core/src/rulesync.ts
|
|
89667
89673
|
import { homedir as homedir5 } from "os";
|
|
89668
89674
|
async function runRulesync(targets, features, inputRoot, options2) {
|
|
89675
|
+
const targetMap = options2.targetMap ?? TARGET_TO_RULESYNC;
|
|
89669
89676
|
const mappedTargets = [];
|
|
89670
89677
|
for (const target of targets) {
|
|
89671
|
-
const rt =
|
|
89678
|
+
const rt = targetMap[target];
|
|
89672
89679
|
if (rt)
|
|
89673
89680
|
mappedTargets.push(rt);
|
|
89674
89681
|
}
|
|
@@ -97508,6 +97515,271 @@ init_dist();
|
|
|
97508
97515
|
import { homedir as homedir7 } from "os";
|
|
97509
97516
|
import { join as join225 } from "path";
|
|
97510
97517
|
|
|
97518
|
+
// src/commands/hook-run.ts
|
|
97519
|
+
init_dist();
|
|
97520
|
+
import { spawnSync as spawnSync2 } from "child_process";
|
|
97521
|
+
|
|
97522
|
+
// ../../plugins/cc/scripts/anti-hallucination/ah_guard.ts
|
|
97523
|
+
var SOURCE_PATTERNS = [
|
|
97524
|
+
/\[Source:\s*[^\]]+\]/i,
|
|
97525
|
+
/Source:\s*\[?[^\n]+\]?/i,
|
|
97526
|
+
/Sources:\s*\n\s*-\s*\[?[^\n]+\]/i,
|
|
97527
|
+
/https?:\/\/[^\s)]+/i,
|
|
97528
|
+
/\*\*Source\*\*:\s*[^\n]+/i
|
|
97529
|
+
];
|
|
97530
|
+
var CONFIDENCE_PATTERNS = [
|
|
97531
|
+
/Confidence:\s*(HIGH|MEDIUM|LOW)/i,
|
|
97532
|
+
/\*\*Confidence\*\*:\s*(HIGH|MEDIUM|LOW)/i,
|
|
97533
|
+
/### Confidence/i
|
|
97534
|
+
];
|
|
97535
|
+
var TOOL_PATTERNS = [
|
|
97536
|
+
/ref_search_documentation/,
|
|
97537
|
+
/ref_read_url/,
|
|
97538
|
+
/searchCode/,
|
|
97539
|
+
/WebSearch/,
|
|
97540
|
+
/WebFetch/,
|
|
97541
|
+
/mcp__ref__ref_search_documentation/,
|
|
97542
|
+
/mcp__ref__ref_read_url/,
|
|
97543
|
+
/mcp__grep__searchCode/
|
|
97544
|
+
];
|
|
97545
|
+
var RED_FLAG_PATTERNS = [
|
|
97546
|
+
/I (?:think|believe|recall) (?:that|the)?/gi,
|
|
97547
|
+
/(?:It|This) (?:should|might|may|could)/gi,
|
|
97548
|
+
/Probably|Likely|Possibly/gi,
|
|
97549
|
+
/(?:As far as|If I) (?:know|recall)/gi
|
|
97550
|
+
];
|
|
97551
|
+
function buildStopOutput(result) {
|
|
97552
|
+
if (result.ok) {
|
|
97553
|
+
return JSON.stringify({
|
|
97554
|
+
hookSpecificOutput: { hookEventName: "Stop", additionalContext: result.reason }
|
|
97555
|
+
});
|
|
97556
|
+
}
|
|
97557
|
+
return JSON.stringify({
|
|
97558
|
+
decision: "block",
|
|
97559
|
+
reason: result.reason,
|
|
97560
|
+
hookSpecificOutput: { hookEventName: "Stop" }
|
|
97561
|
+
});
|
|
97562
|
+
}
|
|
97563
|
+
function extractLastAssistantMessage(context3) {
|
|
97564
|
+
const messages2 = context3.messages ?? [];
|
|
97565
|
+
for (let i2 = messages2.length - 1;i2 >= 0; i2--) {
|
|
97566
|
+
const message = messages2[i2];
|
|
97567
|
+
if (message?.role === "assistant") {
|
|
97568
|
+
const content = message.content;
|
|
97569
|
+
if (Array.isArray(content)) {
|
|
97570
|
+
const textParts = [];
|
|
97571
|
+
for (const part of content) {
|
|
97572
|
+
if (part.type === "text" && part.text) {
|
|
97573
|
+
textParts.push(part.text);
|
|
97574
|
+
}
|
|
97575
|
+
}
|
|
97576
|
+
return textParts.join(`
|
|
97577
|
+
`);
|
|
97578
|
+
}
|
|
97579
|
+
return String(content);
|
|
97580
|
+
}
|
|
97581
|
+
}
|
|
97582
|
+
const lastMsg = context3.last_message;
|
|
97583
|
+
if (lastMsg) {
|
|
97584
|
+
return String(lastMsg);
|
|
97585
|
+
}
|
|
97586
|
+
return;
|
|
97587
|
+
}
|
|
97588
|
+
function hasSourceCitations(text3) {
|
|
97589
|
+
if (!text3)
|
|
97590
|
+
return false;
|
|
97591
|
+
for (const pattern of SOURCE_PATTERNS) {
|
|
97592
|
+
if (pattern.test(text3)) {
|
|
97593
|
+
return true;
|
|
97594
|
+
}
|
|
97595
|
+
}
|
|
97596
|
+
return false;
|
|
97597
|
+
}
|
|
97598
|
+
function hasConfidenceLevel(text3) {
|
|
97599
|
+
if (!text3)
|
|
97600
|
+
return false;
|
|
97601
|
+
for (const pattern of CONFIDENCE_PATTERNS) {
|
|
97602
|
+
if (pattern.test(text3)) {
|
|
97603
|
+
return true;
|
|
97604
|
+
}
|
|
97605
|
+
}
|
|
97606
|
+
return false;
|
|
97607
|
+
}
|
|
97608
|
+
function hasToolUsageEvidence(text3) {
|
|
97609
|
+
if (!text3)
|
|
97610
|
+
return false;
|
|
97611
|
+
for (const pattern of TOOL_PATTERNS) {
|
|
97612
|
+
if (pattern.test(text3)) {
|
|
97613
|
+
return true;
|
|
97614
|
+
}
|
|
97615
|
+
}
|
|
97616
|
+
return false;
|
|
97617
|
+
}
|
|
97618
|
+
function hasRedFlags(text3) {
|
|
97619
|
+
if (!text3)
|
|
97620
|
+
return [];
|
|
97621
|
+
const foundFlags = [];
|
|
97622
|
+
for (const pattern of RED_FLAG_PATTERNS) {
|
|
97623
|
+
const matches = text3.match(pattern);
|
|
97624
|
+
if (matches) {
|
|
97625
|
+
foundFlags.push(...matches);
|
|
97626
|
+
}
|
|
97627
|
+
}
|
|
97628
|
+
return foundFlags;
|
|
97629
|
+
}
|
|
97630
|
+
function requiresExternalVerification(text3) {
|
|
97631
|
+
if (!text3)
|
|
97632
|
+
return false;
|
|
97633
|
+
const verificationKeywords = [
|
|
97634
|
+
"api",
|
|
97635
|
+
"library",
|
|
97636
|
+
"framework",
|
|
97637
|
+
"method",
|
|
97638
|
+
"function",
|
|
97639
|
+
"version",
|
|
97640
|
+
"documentation",
|
|
97641
|
+
"official",
|
|
97642
|
+
/recent\s+(?:change|update|release)/i,
|
|
97643
|
+
/\d+\.\d+(?:\.\d+)?/,
|
|
97644
|
+
/https?:\/\//
|
|
97645
|
+
];
|
|
97646
|
+
const textLower = text3.toLowerCase();
|
|
97647
|
+
for (const keyword of verificationKeywords) {
|
|
97648
|
+
if (typeof keyword === "string") {
|
|
97649
|
+
if (textLower.includes(keyword)) {
|
|
97650
|
+
return true;
|
|
97651
|
+
}
|
|
97652
|
+
} else if (keyword.test(textLower)) {
|
|
97653
|
+
return true;
|
|
97654
|
+
}
|
|
97655
|
+
}
|
|
97656
|
+
return false;
|
|
97657
|
+
}
|
|
97658
|
+
function verifyAntiHallucinationProtocol(text3) {
|
|
97659
|
+
if (!text3 || text3.trim().length < 50) {
|
|
97660
|
+
return { ok: true, reason: "Task is complete" };
|
|
97661
|
+
}
|
|
97662
|
+
const needsVerification = requiresExternalVerification(text3);
|
|
97663
|
+
if (!needsVerification) {
|
|
97664
|
+
return { ok: true, reason: "Task is complete (internal discussion)" };
|
|
97665
|
+
}
|
|
97666
|
+
const hasSources = hasSourceCitations(text3);
|
|
97667
|
+
const hasConfidence = hasConfidenceLevel(text3);
|
|
97668
|
+
const hasTools = hasToolUsageEvidence(text3);
|
|
97669
|
+
const redFlags = hasRedFlags(text3);
|
|
97670
|
+
const issues = [];
|
|
97671
|
+
if (!hasSources) {
|
|
97672
|
+
issues.push("source citations for API/library claims");
|
|
97673
|
+
}
|
|
97674
|
+
if (!hasConfidence) {
|
|
97675
|
+
issues.push("confidence level (HIGH/MEDIUM/LOW)");
|
|
97676
|
+
}
|
|
97677
|
+
if (redFlags.length > 0 && !hasTools) {
|
|
97678
|
+
const uniqueFlags = Array.from(new Set(redFlags)).slice(0, 3);
|
|
97679
|
+
issues.push(`uncertainty phrases detected: ${uniqueFlags.join(", ")}`);
|
|
97680
|
+
}
|
|
97681
|
+
if (issues.length > 0) {
|
|
97682
|
+
const reason = `Add verification for: ${issues.join(", ")}`;
|
|
97683
|
+
return { ok: false, reason, issues };
|
|
97684
|
+
}
|
|
97685
|
+
return { ok: true, reason: "Task is complete" };
|
|
97686
|
+
}
|
|
97687
|
+
if (false) {}
|
|
97688
|
+
|
|
97689
|
+
// src/commands/hook-run.ts
|
|
97690
|
+
function preToolUseDecision(decision, reason) {
|
|
97691
|
+
const out = {
|
|
97692
|
+
hookSpecificOutput: { hookEventName: "PreToolUse", permissionDecision: decision }
|
|
97693
|
+
};
|
|
97694
|
+
if (reason !== undefined)
|
|
97695
|
+
out.systemMessage = reason;
|
|
97696
|
+
return { output: JSON.stringify(out), exitCode: 0 };
|
|
97697
|
+
}
|
|
97698
|
+
function resolveSpurTaskOwnership(filePath, cwd5) {
|
|
97699
|
+
const res = spawnSync2("spur", ["task", "resolve", filePath, "--strict", "--json"], {
|
|
97700
|
+
cwd: cwd5,
|
|
97701
|
+
encoding: "utf-8",
|
|
97702
|
+
timeout: 8000
|
|
97703
|
+
});
|
|
97704
|
+
if (res.error || typeof res.status !== "number")
|
|
97705
|
+
return "unknown";
|
|
97706
|
+
return res.status === 0 ? "owned" : "unowned";
|
|
97707
|
+
}
|
|
97708
|
+
function runSpTaskWriteGuard(env, stdinText, resolveTaskOwnership = resolveSpurTaskOwnership) {
|
|
97709
|
+
if (env.SPUR_WRITE_GUARD === "off")
|
|
97710
|
+
return preToolUseDecision("allow");
|
|
97711
|
+
let payload;
|
|
97712
|
+
try {
|
|
97713
|
+
payload = JSON.parse(stdinText);
|
|
97714
|
+
} catch {
|
|
97715
|
+
return preToolUseDecision("allow");
|
|
97716
|
+
}
|
|
97717
|
+
const toolName = payload.tool_name ?? "";
|
|
97718
|
+
if (toolName !== "Write" && toolName !== "Edit")
|
|
97719
|
+
return preToolUseDecision("allow");
|
|
97720
|
+
const filePath = payload.tool_input?.file_path ?? "";
|
|
97721
|
+
if (filePath === "")
|
|
97722
|
+
return preToolUseDecision("allow");
|
|
97723
|
+
const ownership = resolveTaskOwnership(filePath, env.CLAUDE_PROJECT_DIR ?? process.cwd());
|
|
97724
|
+
if (ownership === "owned") {
|
|
97725
|
+
return preToolUseDecision("deny", `${filePath} is a task file owned by the spur corpus. Edit it through the spur CLI ` + "(e.g. `spur task update <wbs> --section <name> --from-file <file>`), not a raw " + "Write/Edit. Set SPUR_WRITE_GUARD=off to bypass.");
|
|
97726
|
+
}
|
|
97727
|
+
return preToolUseDecision("allow");
|
|
97728
|
+
}
|
|
97729
|
+
var spTaskWriteGuard = {
|
|
97730
|
+
run: runSpTaskWriteGuard
|
|
97731
|
+
};
|
|
97732
|
+
var ccAntiHallucination = {
|
|
97733
|
+
run(env) {
|
|
97734
|
+
const argumentsJson = env.ARGUMENTS ?? "{}";
|
|
97735
|
+
const allowStop = (feedback, ok) => ({
|
|
97736
|
+
output: buildStopOutput({ ok, reason: feedback }),
|
|
97737
|
+
exitCode: ok ? 0 : 1
|
|
97738
|
+
});
|
|
97739
|
+
let context3;
|
|
97740
|
+
try {
|
|
97741
|
+
context3 = JSON.parse(argumentsJson);
|
|
97742
|
+
} catch {
|
|
97743
|
+
return allowStop("Task is complete (invalid context ignored)", true);
|
|
97744
|
+
}
|
|
97745
|
+
const content = extractLastAssistantMessage(context3);
|
|
97746
|
+
if (content === undefined)
|
|
97747
|
+
return allowStop("No content to verify", true);
|
|
97748
|
+
const result = verifyAntiHallucinationProtocol(content);
|
|
97749
|
+
return allowStop(result.reason, result.ok);
|
|
97750
|
+
}
|
|
97751
|
+
};
|
|
97752
|
+
var HOOK_RUNNERS = {
|
|
97753
|
+
"sp/task-write-guard": spTaskWriteGuard,
|
|
97754
|
+
"cc/anti-hallucination": ccAntiHallucination
|
|
97755
|
+
};
|
|
97756
|
+
function hookRun(plugin, hookId, env, stdinText) {
|
|
97757
|
+
const runner = HOOK_RUNNERS[`${plugin}/${hookId}`];
|
|
97758
|
+
if (!runner) {
|
|
97759
|
+
echoError(`Error: unknown hook '${plugin} ${hookId}'. Known hooks: ${Object.keys(HOOK_RUNNERS).join(", ")}`);
|
|
97760
|
+
return 2;
|
|
97761
|
+
}
|
|
97762
|
+
const result = runner.run(env, stdinText);
|
|
97763
|
+
echo(result.output);
|
|
97764
|
+
return result.exitCode;
|
|
97765
|
+
}
|
|
97766
|
+
function registerHookRun(cmd, readInput) {
|
|
97767
|
+
cmd.command("run <plugin> <hook-id>").description("Run a registered plugin hook runner (the runtime command installed hook configs call)").action((plugin, hookId) => {
|
|
97768
|
+
let stdinText = "";
|
|
97769
|
+
if (readInput) {
|
|
97770
|
+
stdinText = readInput();
|
|
97771
|
+
} else {
|
|
97772
|
+
try {
|
|
97773
|
+
stdinText = __require("fs").readFileSync(0, "utf-8");
|
|
97774
|
+
} catch {
|
|
97775
|
+
stdinText = "";
|
|
97776
|
+
}
|
|
97777
|
+
}
|
|
97778
|
+
const code = hookRun(plugin, hookId, process.env, stdinText);
|
|
97779
|
+
process.exit(code);
|
|
97780
|
+
});
|
|
97781
|
+
}
|
|
97782
|
+
|
|
97511
97783
|
// src/commands/install.ts
|
|
97512
97784
|
init_src();
|
|
97513
97785
|
init_dist();
|
|
@@ -97687,7 +97959,7 @@ async function executeInstall(plugin, targets2, options2, dependencies = {}) {
|
|
|
97687
97959
|
const targetInputRoot = prepareTargetRulesyncInput(outputDir, target, plugin);
|
|
97688
97960
|
targetInputRoots.set(target, targetInputRoot);
|
|
97689
97961
|
}
|
|
97690
|
-
const rulesyncFeatures = ["skills",
|
|
97962
|
+
const rulesyncFeatures = ["skills", ...mapResult.mcp ? ["mcp"] : []];
|
|
97691
97963
|
const rulesyncTargets = targets2.filter((t) => t !== "claude" && t !== "hermes" && t !== "omp");
|
|
97692
97964
|
if (targets2.includes("omp") && !targets2.includes("pi")) {
|
|
97693
97965
|
if (!targetInputRoots.has("pi")) {
|
|
@@ -97726,6 +97998,20 @@ async function executeInstall(plugin, targets2, options2, dependencies = {}) {
|
|
|
97726
97998
|
resultCounts.subagentsCount += result.subagentsCount;
|
|
97727
97999
|
resultCounts.hooksCount += result.hooksCount;
|
|
97728
98000
|
}
|
|
98001
|
+
if (mapResult.hooks) {
|
|
98002
|
+
for (const target of rulesyncTargets) {
|
|
98003
|
+
if (!TARGET_TO_RULESYNC_HOOKS[target])
|
|
98004
|
+
continue;
|
|
98005
|
+
const hookResult = await runRulesyncImpl([target], ["hooks"], targetInputRoots.get(target) ?? outputDir, {
|
|
98006
|
+
global: options2.global,
|
|
98007
|
+
dryRun: options2.dryRun,
|
|
98008
|
+
verbose: options2.verbose,
|
|
98009
|
+
outputRoot: options2.outputRoot,
|
|
98010
|
+
targetMap: TARGET_TO_RULESYNC_HOOKS
|
|
98011
|
+
});
|
|
98012
|
+
resultCounts.hooksCount += hookResult.hooksCount;
|
|
98013
|
+
}
|
|
98014
|
+
}
|
|
97729
98015
|
if (options2.verbose) {
|
|
97730
98016
|
echo(` Skills written: ${resultCounts.skillsCount}, Commands: ${resultCounts.commandsCount}, Subagents: ${resultCounts.subagentsCount}, Hooks: ${resultCounts.hooksCount}`);
|
|
97731
98017
|
}
|
|
@@ -98005,6 +98291,7 @@ function registerHook(program2) {
|
|
|
98005
98291
|
addTargetOption(cmd.command("emit <name>").description("Emit a hook definition to a single target agent (thin wrapper over the install hook path)")).option("--global", "Install to user-level global directory (default)", true).option("--dry-run", "Preview without writing files", false).action(async (name, opts) => {
|
|
98006
98292
|
await runOperation(() => hookEmit({ name, ...opts }));
|
|
98007
98293
|
});
|
|
98294
|
+
registerHookRun(cmd);
|
|
98008
98295
|
}
|
|
98009
98296
|
|
|
98010
98297
|
// src/commands/magent.ts
|