@gobing-ai/superskill 0.2.4 → 0.2.6
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/README.md +41 -244
- package/dist/index.js +1235 -279
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2226,13 +2226,20 @@ import { rmSync } from "fs";
|
|
|
2226
2226
|
async function backupFile(filePath) {
|
|
2227
2227
|
let backupPath = `${filePath}.bak`;
|
|
2228
2228
|
if (await Bun.file(backupPath).exists()) {
|
|
2229
|
-
const ts = new Date().toISOString().replace(/[:.]/g, "").slice(0,
|
|
2229
|
+
const ts = new Date().toISOString().replace(/[:.]/g, "").slice(0, 18);
|
|
2230
2230
|
backupPath = `${filePath}.bak.${ts}`;
|
|
2231
|
+
let counter = 1;
|
|
2232
|
+
while (await Bun.file(backupPath).exists()) {
|
|
2233
|
+
backupPath = `${filePath}.bak.${ts}.${counter++}`;
|
|
2234
|
+
}
|
|
2231
2235
|
}
|
|
2232
2236
|
await Bun.write(backupPath, Bun.file(filePath));
|
|
2233
2237
|
return backupPath;
|
|
2234
2238
|
}
|
|
2235
2239
|
async function restoreFromBackup(backupPath, originalPath) {
|
|
2240
|
+
if (!await Bun.file(backupPath).exists()) {
|
|
2241
|
+
throw new Error(`Backup file not found: ${backupPath} \u2014 cannot restore ${originalPath}`);
|
|
2242
|
+
}
|
|
2236
2243
|
await Bun.write(originalPath, Bun.file(backupPath));
|
|
2237
2244
|
rmSync(backupPath, { force: true });
|
|
2238
2245
|
}
|
|
@@ -9230,11 +9237,10 @@ var init_dist2 = __esm(() => {
|
|
|
9230
9237
|
|
|
9231
9238
|
// ../../packages/core/src/content/frontmatter.ts
|
|
9232
9239
|
function parseFrontmatter(content) {
|
|
9233
|
-
if (
|
|
9234
|
-
`)) {
|
|
9240
|
+
if (!/^---\r?\n/.test(content)) {
|
|
9235
9241
|
throw new FrontmatterError("Missing frontmatter: content must start with ---");
|
|
9236
9242
|
}
|
|
9237
|
-
const closerMatch = content.slice(4).match(/\n---(?=\n|$)/);
|
|
9243
|
+
const closerMatch = content.slice(4).match(/\r?\n---(?=\r?\n|$)/);
|
|
9238
9244
|
if (closerMatch?.index === undefined) {
|
|
9239
9245
|
throw new FrontmatterError("Missing frontmatter closing delimiter (---)");
|
|
9240
9246
|
}
|
|
@@ -9445,7 +9451,7 @@ function walkFrontmatter(content, opts) {
|
|
|
9445
9451
|
}
|
|
9446
9452
|
out.push(line);
|
|
9447
9453
|
}
|
|
9448
|
-
if (!injectedName) {
|
|
9454
|
+
if (!injectedName || inFrontmatter) {
|
|
9449
9455
|
return `${opts.fallbackBlock}
|
|
9450
9456
|
|
|
9451
9457
|
${content}`;
|
|
@@ -9469,6 +9475,12 @@ var init_rewrite_references = __esm(() => {
|
|
|
9469
9475
|
SLASH_COMMAND_LINE_RE = /^\s*\/[a-zA-Z0-9._-]+:[a-zA-Z0-9._-]+(\s|$)/;
|
|
9470
9476
|
});
|
|
9471
9477
|
|
|
9478
|
+
// ../../packages/core/src/pipeline/yaml-utils.ts
|
|
9479
|
+
function quoteYaml(value) {
|
|
9480
|
+
const escaped = value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"");
|
|
9481
|
+
return `"${escaped}"`;
|
|
9482
|
+
}
|
|
9483
|
+
|
|
9472
9484
|
// ../../packages/core/src/pipeline/adapt-command.ts
|
|
9473
9485
|
function adaptCommandToSkill(source, expectedName, pluginPrefix) {
|
|
9474
9486
|
let result;
|
|
@@ -9480,7 +9492,7 @@ function adaptCommandToSkill(source, expectedName, pluginPrefix) {
|
|
|
9480
9492
|
const description = firstLine?.trim() || `${expectedName} command`;
|
|
9481
9493
|
result = `---
|
|
9482
9494
|
name: ${expectedName}
|
|
9483
|
-
description:
|
|
9495
|
+
description: ${quoteYaml(description)}
|
|
9484
9496
|
disable-model-invocation: true
|
|
9485
9497
|
---
|
|
9486
9498
|
|
|
@@ -9502,7 +9514,8 @@ function normalizeCommandFrontmatter(content, expectedName) {
|
|
|
9502
9514
|
const value = line.slice(line.indexOf(":") + 1).trim();
|
|
9503
9515
|
if (value.startsWith("["))
|
|
9504
9516
|
return line;
|
|
9505
|
-
const
|
|
9517
|
+
const unquoted = value.replace(/^["']|["']$/g, "");
|
|
9518
|
+
const parts = unquoted.split(/,\s*/).map((p) => p.trim()).filter(Boolean);
|
|
9506
9519
|
return `allowed-tools: [${parts.join(", ")}]`;
|
|
9507
9520
|
}
|
|
9508
9521
|
}
|
|
@@ -9517,10 +9530,6 @@ disable-model-invocation: true
|
|
|
9517
9530
|
---`
|
|
9518
9531
|
});
|
|
9519
9532
|
}
|
|
9520
|
-
function quoteYaml(value) {
|
|
9521
|
-
const escaped = value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"");
|
|
9522
|
-
return `"${escaped}"`;
|
|
9523
|
-
}
|
|
9524
9533
|
var init_adapt_command = __esm(() => {
|
|
9525
9534
|
init_rewrite_references();
|
|
9526
9535
|
});
|
|
@@ -9603,7 +9612,7 @@ function adaptSubagentToSkill(source, expectedName, pluginPrefix) {
|
|
|
9603
9612
|
const description = firstLine?.trim() || `${expectedName} subagent`;
|
|
9604
9613
|
result = `---
|
|
9605
9614
|
name: ${expectedName}
|
|
9606
|
-
description:
|
|
9615
|
+
description: ${quoteYaml(description)}
|
|
9607
9616
|
---
|
|
9608
9617
|
|
|
9609
9618
|
${source}`;
|
|
@@ -9637,17 +9646,17 @@ ${source}`;
|
|
|
9637
9646
|
const piTools = normalizePiToolList(rawToolsStr);
|
|
9638
9647
|
const description = asString(data.description) || `${expectedName} subagent`;
|
|
9639
9648
|
let model = asString(data.model);
|
|
9640
|
-
if (model === "inherit")
|
|
9649
|
+
if (model.toLowerCase() === "inherit")
|
|
9641
9650
|
model = "";
|
|
9642
9651
|
const skillsList = resolvePiSkills(data, body, pluginPrefix, skillExists);
|
|
9643
9652
|
const skillsCsv = skillsList.join(", ");
|
|
9644
9653
|
const fields = [`name: ${expectedName}`];
|
|
9645
9654
|
if (description)
|
|
9646
|
-
fields.push(`description: ${description}`);
|
|
9655
|
+
fields.push(`description: ${quoteYaml(description)}`);
|
|
9647
9656
|
if (piTools)
|
|
9648
9657
|
fields.push(`tools: ${piTools}`);
|
|
9649
9658
|
if (model)
|
|
9650
|
-
fields.push(`model: ${model}`);
|
|
9659
|
+
fields.push(`model: ${quoteYaml(model)}`);
|
|
9651
9660
|
if (skillsCsv)
|
|
9652
9661
|
fields.push(`skill: ${skillsCsv}`);
|
|
9653
9662
|
const runtimeNotes = buildPiRuntimeNotes(parseToolsList(rawToolsStr), skillsCsv);
|
|
@@ -9731,8 +9740,9 @@ var init_adapt_subagent = __esm(() => {
|
|
|
9731
9740
|
});
|
|
9732
9741
|
|
|
9733
9742
|
// ../../packages/core/src/mapper.ts
|
|
9734
|
-
import { existsSync as existsSync3, mkdirSync, readdirSync, readFileSync as readFileSync2, rmSync as rmSync2,
|
|
9735
|
-
import {
|
|
9743
|
+
import { existsSync as existsSync3, lstatSync, mkdirSync, readdirSync, readFileSync as readFileSync2, rmSync as rmSync2, writeFileSync } from "fs";
|
|
9744
|
+
import { homedir as homedir2 } from "os";
|
|
9745
|
+
import { join as join3, resolve } from "path";
|
|
9736
9746
|
function convertClaudeHooksToCanonical(claudeJson) {
|
|
9737
9747
|
const claudeHooks = claudeJson.hooks;
|
|
9738
9748
|
if (!claudeHooks || typeof claudeHooks !== "object")
|
|
@@ -9771,10 +9781,15 @@ function convertClaudeHooksToCanonical(claudeJson) {
|
|
|
9771
9781
|
return { hooks: canonical };
|
|
9772
9782
|
}
|
|
9773
9783
|
function setSkillName(content, newName) {
|
|
9774
|
-
|
|
9784
|
+
if (/^name:\s*.+$/m.test(content)) {
|
|
9785
|
+
return content.replace(/^name:\s*.+$/m, `name: ${newName}`);
|
|
9786
|
+
}
|
|
9787
|
+
return content.replace(/^---\s*$/m, `---
|
|
9788
|
+
name: ${newName}`);
|
|
9775
9789
|
}
|
|
9776
9790
|
function mapPluginToRulesync(pluginPath, pluginName, outputDir) {
|
|
9777
9791
|
assertSafePathSegment(pluginName, "plugin name");
|
|
9792
|
+
assertSafeOutputDir(outputDir);
|
|
9778
9793
|
if (existsSync3(outputDir)) {
|
|
9779
9794
|
rmSync2(outputDir, { recursive: true, force: true });
|
|
9780
9795
|
}
|
|
@@ -9875,7 +9890,12 @@ function deepMergeJsonFile(sourcePath, targetPath) {
|
|
|
9875
9890
|
`);
|
|
9876
9891
|
}
|
|
9877
9892
|
function readJsonObject(path) {
|
|
9878
|
-
|
|
9893
|
+
let value;
|
|
9894
|
+
try {
|
|
9895
|
+
value = JSON.parse(readFileSync2(path, "utf-8"));
|
|
9896
|
+
} catch (e) {
|
|
9897
|
+
throw new Error(`Failed to parse JSON in ${path}: ${e instanceof Error ? e.message : String(e)}`);
|
|
9898
|
+
}
|
|
9879
9899
|
if (!isJsonObject(value)) {
|
|
9880
9900
|
throw new Error(`Expected JSON object in ${path}`);
|
|
9881
9901
|
}
|
|
@@ -9892,20 +9912,44 @@ function deepMerge2(target, source) {
|
|
|
9892
9912
|
function isJsonObject(value) {
|
|
9893
9913
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
9894
9914
|
}
|
|
9915
|
+
function assertSafeOutputDir(outputDir) {
|
|
9916
|
+
const resolved = resolve(outputDir);
|
|
9917
|
+
const home = homedir2();
|
|
9918
|
+
const dangerous = [home, process.cwd(), "/", "/home", "/Users"];
|
|
9919
|
+
for (const danger of dangerous) {
|
|
9920
|
+
if (resolved === resolve(danger)) {
|
|
9921
|
+
throw new Error(`Refusing to delete output directory '${resolved}': resolves to a protected path ` + `(home, cwd, or filesystem root). Use a subdirectory.`);
|
|
9922
|
+
}
|
|
9923
|
+
}
|
|
9924
|
+
}
|
|
9895
9925
|
function copyAndRewriteDirectory(source, destination, pluginName) {
|
|
9896
9926
|
mkdirSync(destination, { recursive: true });
|
|
9897
9927
|
for (const entry of readdirSync(source)) {
|
|
9898
9928
|
const srcPath = join3(source, entry);
|
|
9899
9929
|
const destPath = join3(destination, entry);
|
|
9900
|
-
|
|
9930
|
+
const stat = lstatSync(srcPath);
|
|
9931
|
+
if (stat.isSymbolicLink())
|
|
9932
|
+
continue;
|
|
9933
|
+
if (stat.isDirectory()) {
|
|
9901
9934
|
copyAndRewriteDirectory(srcPath, destPath, pluginName);
|
|
9902
9935
|
} else {
|
|
9903
|
-
const
|
|
9904
|
-
|
|
9936
|
+
const bytes = readFileSync2(srcPath);
|
|
9937
|
+
if (isTextFile(entry, bytes)) {
|
|
9938
|
+
const content = bytes.toString("utf-8");
|
|
9939
|
+
writeFileSync(destPath, rewriteSkillReferences(content, pluginName));
|
|
9940
|
+
} else {
|
|
9941
|
+
writeFileSync(destPath, bytes);
|
|
9942
|
+
}
|
|
9905
9943
|
}
|
|
9906
9944
|
}
|
|
9907
9945
|
}
|
|
9908
|
-
|
|
9946
|
+
function isTextFile(filename, bytes) {
|
|
9947
|
+
const ext = filename.slice(filename.lastIndexOf("."));
|
|
9948
|
+
if (TEXT_EXTENSIONS.has(ext))
|
|
9949
|
+
return true;
|
|
9950
|
+
return !bytes.subarray(0, 8192).includes(0);
|
|
9951
|
+
}
|
|
9952
|
+
var CLAUDE_TO_CANONICAL_EVENT, TEXT_EXTENSIONS;
|
|
9909
9953
|
var init_mapper = __esm(() => {
|
|
9910
9954
|
init_identity();
|
|
9911
9955
|
init_adapt_command();
|
|
@@ -9927,6 +9971,34 @@ var init_mapper = __esm(() => {
|
|
|
9927
9971
|
WorktreeRemove: "worktreeRemove",
|
|
9928
9972
|
MessageDisplay: "messageDisplay"
|
|
9929
9973
|
};
|
|
9974
|
+
TEXT_EXTENSIONS = new Set([
|
|
9975
|
+
".md",
|
|
9976
|
+
".ts",
|
|
9977
|
+
".js",
|
|
9978
|
+
".json",
|
|
9979
|
+
".yaml",
|
|
9980
|
+
".yml",
|
|
9981
|
+
".txt",
|
|
9982
|
+
".sh",
|
|
9983
|
+
".bash",
|
|
9984
|
+
".py",
|
|
9985
|
+
".rb",
|
|
9986
|
+
".go",
|
|
9987
|
+
".rs",
|
|
9988
|
+
".java",
|
|
9989
|
+
".c",
|
|
9990
|
+
".cpp",
|
|
9991
|
+
".h",
|
|
9992
|
+
".css",
|
|
9993
|
+
".html",
|
|
9994
|
+
".xml",
|
|
9995
|
+
".toml",
|
|
9996
|
+
".ini",
|
|
9997
|
+
".cfg",
|
|
9998
|
+
".env",
|
|
9999
|
+
".gitignore",
|
|
10000
|
+
".dockerfile"
|
|
10001
|
+
]);
|
|
9930
10002
|
});
|
|
9931
10003
|
|
|
9932
10004
|
// ../../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/helpers/util.js
|
|
@@ -13897,20 +13969,20 @@ var init_zod = __esm(() => {
|
|
|
13897
13969
|
|
|
13898
13970
|
// ../../packages/core/src/marketplace.ts
|
|
13899
13971
|
import { existsSync as existsSync4, readdirSync as readdirSync2, readFileSync as readFileSync3 } from "fs";
|
|
13900
|
-
import { join as join4, resolve } from "path";
|
|
13972
|
+
import { join as join4, resolve as resolve2 } from "path";
|
|
13901
13973
|
function resolvePlugin(marketplacePath, pluginName) {
|
|
13902
13974
|
let manifestPath = null;
|
|
13903
13975
|
if (marketplacePath) {
|
|
13904
13976
|
if (marketplacePath.endsWith("marketplace.json")) {
|
|
13905
|
-
manifestPath =
|
|
13977
|
+
manifestPath = resolve2(marketplacePath);
|
|
13906
13978
|
} else {
|
|
13907
|
-
manifestPath =
|
|
13979
|
+
manifestPath = resolve2(join4(marketplacePath, "marketplace.json"));
|
|
13908
13980
|
}
|
|
13909
13981
|
if (!existsSync4(manifestPath)) {
|
|
13910
13982
|
throw new Error(`Marketplace manifest not found at: ${manifestPath}`);
|
|
13911
13983
|
}
|
|
13912
13984
|
} else {
|
|
13913
|
-
const cwdManifest =
|
|
13985
|
+
const cwdManifest = resolve2(".claude-plugin", "marketplace.json");
|
|
13914
13986
|
if (existsSync4(cwdManifest)) {
|
|
13915
13987
|
manifestPath = cwdManifest;
|
|
13916
13988
|
}
|
|
@@ -13937,12 +14009,15 @@ function resolvePlugin(marketplacePath, pluginName) {
|
|
|
13937
14009
|
if (!source.startsWith("./")) {
|
|
13938
14010
|
throw new Error(`Remote sources not yet supported for plugin '${pluginName}'. Phase 1 only supports relative-path sources (starting with './').`);
|
|
13939
14011
|
}
|
|
13940
|
-
if (/(
|
|
14012
|
+
if (/(?:^|[\\/])\.\.(?:[\\/]|$)/.test(source)) {
|
|
13941
14013
|
throw new Error(`Plugin source for '${pluginName}' escapes the marketplace root: '${source}'.`);
|
|
13942
14014
|
}
|
|
13943
|
-
const marketplaceRoot = resolve(manifestPath, "..", "..");
|
|
13944
14015
|
const pluginRootBase = manifest.metadata?.pluginRoot ?? "";
|
|
13945
|
-
|
|
14016
|
+
if (pluginRootBase && /(?:^|[\\/])\.\.(?:[\\/]|$)/.test(pluginRootBase)) {
|
|
14017
|
+
throw new Error(`Plugin root for '${pluginName}' escapes the marketplace root: '${pluginRootBase}'.`);
|
|
14018
|
+
}
|
|
14019
|
+
const marketplaceRoot = resolve2(manifestPath, "..", "..");
|
|
14020
|
+
const pluginRoot = resolve2(marketplaceRoot, pluginRootBase, source);
|
|
13946
14021
|
let dirents;
|
|
13947
14022
|
try {
|
|
13948
14023
|
dirents = readdirSync2(pluginRoot);
|
|
@@ -13962,11 +14037,11 @@ function resolvePlugin(marketplacePath, pluginName) {
|
|
|
13962
14037
|
function listResolvablePlugins(marketplacePath) {
|
|
13963
14038
|
let manifestPath = null;
|
|
13964
14039
|
if (marketplacePath) {
|
|
13965
|
-
manifestPath = marketplacePath.endsWith("marketplace.json") ?
|
|
14040
|
+
manifestPath = marketplacePath.endsWith("marketplace.json") ? resolve2(marketplacePath) : resolve2(join4(marketplacePath, "marketplace.json"));
|
|
13966
14041
|
if (!existsSync4(manifestPath))
|
|
13967
14042
|
return [];
|
|
13968
14043
|
} else {
|
|
13969
|
-
const cwdManifest =
|
|
14044
|
+
const cwdManifest = resolve2(".claude-plugin", "marketplace.json");
|
|
13970
14045
|
if (existsSync4(cwdManifest))
|
|
13971
14046
|
manifestPath = cwdManifest;
|
|
13972
14047
|
}
|
|
@@ -14106,7 +14181,7 @@ var init_migrate = __esm(() => {
|
|
|
14106
14181
|
});
|
|
14107
14182
|
|
|
14108
14183
|
// ../../packages/core/src/operations/package.ts
|
|
14109
|
-
import { cpSync, existsSync as existsSync6, mkdirSync as mkdirSync3, statSync as
|
|
14184
|
+
import { cpSync, existsSync as existsSync6, mkdirSync as mkdirSync3, rmSync as rmSync3, statSync as statSync2 } from "fs";
|
|
14110
14185
|
import { basename as basename2, dirname as dirname3, join as join5 } from "path";
|
|
14111
14186
|
import { cwd as cwd3 } from "process";
|
|
14112
14187
|
function resolveSkillDir(name) {
|
|
@@ -14114,7 +14189,7 @@ function resolveSkillDir(name) {
|
|
|
14114
14189
|
if (!skillPath) {
|
|
14115
14190
|
throw Object.assign(new Error(`Skill not found: ${name}`), { code: "ENOENT" });
|
|
14116
14191
|
}
|
|
14117
|
-
const dir =
|
|
14192
|
+
const dir = statSync2(skillPath).isDirectory() ? skillPath : dirname3(skillPath);
|
|
14118
14193
|
return { dir, name: basename2(dir) };
|
|
14119
14194
|
}
|
|
14120
14195
|
function copyDirIfExists(src, dest) {
|
|
@@ -14130,6 +14205,9 @@ function copyFileIfExists(src, dest) {
|
|
|
14130
14205
|
async function packageSkill(name, opts = {}) {
|
|
14131
14206
|
const { dir: skillDir, name: skillName } = resolveSkillDir(name);
|
|
14132
14207
|
const outputDir = join5(opts.output ?? cwd3(), skillName);
|
|
14208
|
+
if (existsSync6(outputDir)) {
|
|
14209
|
+
rmSync3(outputDir, { recursive: true, force: true });
|
|
14210
|
+
}
|
|
14133
14211
|
mkdirSync3(outputDir, { recursive: true });
|
|
14134
14212
|
copyFileIfExists(join5(skillDir, "SKILL.md"), join5(outputDir, "SKILL.md"));
|
|
14135
14213
|
copyDirIfExists(join5(skillDir, "references"), join5(outputDir, "references"));
|
|
@@ -14152,7 +14230,7 @@ var init_package = __esm(() => {
|
|
|
14152
14230
|
|
|
14153
14231
|
// ../../packages/core/src/operations/scaffold.ts
|
|
14154
14232
|
import { existsSync as existsSync7, mkdirSync as mkdirSync4, readFileSync as readFileSync5, writeFileSync as writeFileSync3 } from "fs";
|
|
14155
|
-
import { homedir as
|
|
14233
|
+
import { homedir as homedir3 } from "os";
|
|
14156
14234
|
import { join as join6 } from "path";
|
|
14157
14235
|
import { cwd as cwd4 } from "process";
|
|
14158
14236
|
function parseList(value) {
|
|
@@ -14192,8 +14270,10 @@ function mergeFrontmatterList(content, key, items) {
|
|
|
14192
14270
|
return content.slice(0, fmStart) + newFmBody + content.slice(closePos);
|
|
14193
14271
|
}
|
|
14194
14272
|
function resolveTemplate(type, tier) {
|
|
14195
|
-
const homeDir = process.env.HOME ??
|
|
14273
|
+
const homeDir = process.env.HOME ?? homedir3();
|
|
14196
14274
|
const tierName = tier?.trim();
|
|
14275
|
+
if (tierName)
|
|
14276
|
+
assertSafePathSegment(tierName, "template tier");
|
|
14197
14277
|
if (tierName && tierName !== "default") {
|
|
14198
14278
|
const userTierPath = join6(homeDir, ".superskill", "templates", type, `${tierName}.md`);
|
|
14199
14279
|
if (existsSync7(userTierPath)) {
|
|
@@ -14296,10 +14376,7 @@ function scoreClarityFromDensities(body) {
|
|
|
14296
14376
|
function parseFrontmatterSafe(content) {
|
|
14297
14377
|
try {
|
|
14298
14378
|
return parseFrontmatter(content).data;
|
|
14299
|
-
} catch
|
|
14300
|
-
if (e instanceof FrontmatterError) {
|
|
14301
|
-
return null;
|
|
14302
|
-
}
|
|
14379
|
+
} catch {
|
|
14303
14380
|
return null;
|
|
14304
14381
|
}
|
|
14305
14382
|
}
|
|
@@ -14413,7 +14490,7 @@ function parseHookEntries(raw) {
|
|
|
14413
14490
|
function scoreCorrectness(entries) {
|
|
14414
14491
|
let valid = 0;
|
|
14415
14492
|
for (const e of entries) {
|
|
14416
|
-
if (e.type === "command" && e.command.length > 0 && e.matcher.length > 0)
|
|
14493
|
+
if ((e.type === "command" || e.type === "prompt") && e.command.length > 0 && e.matcher.length > 0)
|
|
14417
14494
|
valid++;
|
|
14418
14495
|
}
|
|
14419
14496
|
const score = entries.length > 0 ? clamp(valid / entries.length) : 0;
|
|
@@ -14423,7 +14500,7 @@ function scoreCorrectness(entries) {
|
|
|
14423
14500
|
function scoreEventCoverage(entries) {
|
|
14424
14501
|
const events = new Set(entries.map((e) => e.event));
|
|
14425
14502
|
const covered = KNOWN_HOOK_EVENTS.filter((e) => events.has(e)).length;
|
|
14426
|
-
const score = clamp(Math.min(
|
|
14503
|
+
const score = clamp(Math.min(covered / 3, 1));
|
|
14427
14504
|
const note = `${covered} of ${KNOWN_HOOK_EVENTS.length} known events covered (${events.size} total)`;
|
|
14428
14505
|
return { score, note };
|
|
14429
14506
|
}
|
|
@@ -14578,7 +14655,7 @@ var init_hook = __esm(() => {
|
|
|
14578
14655
|
});
|
|
14579
14656
|
|
|
14580
14657
|
// ../../packages/core/src/operations/validate.ts
|
|
14581
|
-
import { existsSync as existsSync8, statSync as
|
|
14658
|
+
import { existsSync as existsSync8, statSync as statSync3 } from "fs";
|
|
14582
14659
|
import { dirname as dirname4, join as join7 } from "path";
|
|
14583
14660
|
function checkBodyLinks(body, baseDir) {
|
|
14584
14661
|
const findings = [];
|
|
@@ -14616,7 +14693,7 @@ async function validate(type, nameOrPath, opts) {
|
|
|
14616
14693
|
}
|
|
14617
14694
|
let stat;
|
|
14618
14695
|
try {
|
|
14619
|
-
stat =
|
|
14696
|
+
stat = statSync3(resolvedPath);
|
|
14620
14697
|
} catch {
|
|
14621
14698
|
return sentinelResult(`File not found: ${resolvedPath}`);
|
|
14622
14699
|
}
|
|
@@ -14638,13 +14715,14 @@ async function validate(type, nameOrPath, opts) {
|
|
|
14638
14715
|
const baseDir = dirname4(resolvedPath);
|
|
14639
14716
|
const result = _validateContent(type, content, {
|
|
14640
14717
|
...opts,
|
|
14641
|
-
referenceChecker: (refType, refName) => resolveContentPath(refType, refName, { baseDir }) !== null
|
|
14718
|
+
referenceChecker: opts?.referenceChecker ?? ((refType, refName) => resolveContentPath(refType, refName, { baseDir }) !== null)
|
|
14642
14719
|
});
|
|
14643
|
-
|
|
14644
|
-
|
|
14645
|
-
|
|
14646
|
-
|
|
14647
|
-
|
|
14720
|
+
let bodyForLinks = content;
|
|
14721
|
+
try {
|
|
14722
|
+
const { body } = parseFrontmatter(content);
|
|
14723
|
+
bodyForLinks = body;
|
|
14724
|
+
} catch {}
|
|
14725
|
+
const linkFindings = checkBodyLinks(bodyForLinks, baseDir);
|
|
14648
14726
|
result.findings.push(...linkFindings);
|
|
14649
14727
|
return result;
|
|
14650
14728
|
}
|
|
@@ -14652,7 +14730,9 @@ function _validateContent(type, content, opts) {
|
|
|
14652
14730
|
const findings = [];
|
|
14653
14731
|
let data;
|
|
14654
14732
|
let body;
|
|
14655
|
-
const frontmatterPresent =
|
|
14733
|
+
const frontmatterPresent = content.startsWith(`---
|
|
14734
|
+
`) || content.startsWith(`---\r
|
|
14735
|
+
`);
|
|
14656
14736
|
try {
|
|
14657
14737
|
if (frontmatterPresent) {
|
|
14658
14738
|
const parsed = parseFrontmatter(content);
|
|
@@ -14832,7 +14912,12 @@ function strictChecks(type, data, body) {
|
|
|
14832
14912
|
message: `Body content is too short (${trimmedBody.length} chars). Recommended minimum is 20 characters.`
|
|
14833
14913
|
});
|
|
14834
14914
|
}
|
|
14835
|
-
|
|
14915
|
+
const recognized = new Set([
|
|
14916
|
+
...Object.keys(FIELD_TYPES[type] ?? {}),
|
|
14917
|
+
...REQUIRED_FIELDS[type],
|
|
14918
|
+
...KNOWN_OPTIONAL[type] ?? []
|
|
14919
|
+
]);
|
|
14920
|
+
for (const [key, value] of Object.entries(data)) {
|
|
14836
14921
|
const replacement = DEPRECATED_FIELDS[key];
|
|
14837
14922
|
if (replacement) {
|
|
14838
14923
|
findings.push({
|
|
@@ -14841,31 +14926,20 @@ function strictChecks(type, data, body) {
|
|
|
14841
14926
|
message: `'${key}' is deprecated. ${replacement}`
|
|
14842
14927
|
});
|
|
14843
14928
|
}
|
|
14844
|
-
}
|
|
14845
|
-
for (const [field, value] of Object.entries(data)) {
|
|
14846
14929
|
if (typeof value === "string" && value !== value.trimEnd()) {
|
|
14847
14930
|
findings.push({
|
|
14848
14931
|
severity: "warning",
|
|
14849
|
-
field,
|
|
14850
|
-
message: `'${
|
|
14932
|
+
field: key,
|
|
14933
|
+
message: `'${key}' has trailing whitespace`
|
|
14934
|
+
});
|
|
14935
|
+
}
|
|
14936
|
+
if (!recognized.has(key) && DEPRECATED_FIELDS[key] === undefined) {
|
|
14937
|
+
findings.push({
|
|
14938
|
+
severity: "warning",
|
|
14939
|
+
field: key,
|
|
14940
|
+
message: `Unknown frontmatter key '${key}'`
|
|
14851
14941
|
});
|
|
14852
14942
|
}
|
|
14853
|
-
}
|
|
14854
|
-
const recognized = new Set([
|
|
14855
|
-
...Object.keys(FIELD_TYPES[type] ?? {}),
|
|
14856
|
-
...REQUIRED_FIELDS[type],
|
|
14857
|
-
...KNOWN_OPTIONAL[type] ?? []
|
|
14858
|
-
]);
|
|
14859
|
-
for (const key of Object.keys(data)) {
|
|
14860
|
-
if (recognized.has(key))
|
|
14861
|
-
continue;
|
|
14862
|
-
if (DEPRECATED_FIELDS[key] !== undefined)
|
|
14863
|
-
continue;
|
|
14864
|
-
findings.push({
|
|
14865
|
-
severity: "warning",
|
|
14866
|
-
field: key,
|
|
14867
|
-
message: `Unknown frontmatter key '${key}'`
|
|
14868
|
-
});
|
|
14869
14943
|
}
|
|
14870
14944
|
return findings;
|
|
14871
14945
|
}
|
|
@@ -17290,8 +17364,12 @@ function getTelemetryConfig(configPartial = {}) {
|
|
|
17290
17364
|
function getResolvedConfig() {
|
|
17291
17365
|
return resolvedConfig;
|
|
17292
17366
|
}
|
|
17293
|
-
|
|
17367
|
+
function getTracer() {
|
|
17368
|
+
return import_api.trace.getTracer(TRACER_NAME, TRACER_VERSION);
|
|
17369
|
+
}
|
|
17370
|
+
var import_api, CONFIG_DEFAULTS, TRACER_NAME = "@gobing-ai/ts-infra", TRACER_VERSION = "0.1.0", resolvedConfig;
|
|
17294
17371
|
var init_sdk = __esm(() => {
|
|
17372
|
+
import_api = __toESM(require_src(), 1);
|
|
17295
17373
|
CONFIG_DEFAULTS = {
|
|
17296
17374
|
enabled: true,
|
|
17297
17375
|
serviceName: "ts-libs",
|
|
@@ -17300,13 +17378,41 @@ var init_sdk = __esm(() => {
|
|
|
17300
17378
|
resolvedConfig = getTelemetryConfig();
|
|
17301
17379
|
});
|
|
17302
17380
|
|
|
17381
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.3.21+3246782889eb34e0/node_modules/@gobing-ai/ts-infra/dist/telemetry/tracing.js
|
|
17382
|
+
function isSuppressed(tracer) {
|
|
17383
|
+
return tracer === undefined && !getResolvedConfig().enabled;
|
|
17384
|
+
}
|
|
17385
|
+
function nonRecordingSpan() {
|
|
17386
|
+
return import_api2.trace.wrapSpanContext(import_api2.INVALID_SPAN_CONTEXT);
|
|
17387
|
+
}
|
|
17388
|
+
async function traceAsync(name, fn, options2, tracer) {
|
|
17389
|
+
if (isSuppressed(tracer))
|
|
17390
|
+
return fn(nonRecordingSpan());
|
|
17391
|
+
const resolvedTracer = tracer ?? getTracer();
|
|
17392
|
+
return resolvedTracer.startActiveSpan(name, options2 ?? {}, async (span) => {
|
|
17393
|
+
try {
|
|
17394
|
+
return await fn(span);
|
|
17395
|
+
} catch (err) {
|
|
17396
|
+
span.setStatus({ code: 2, message: err instanceof Error ? err.message : String(err) });
|
|
17397
|
+
throw err;
|
|
17398
|
+
} finally {
|
|
17399
|
+
span.end();
|
|
17400
|
+
}
|
|
17401
|
+
});
|
|
17402
|
+
}
|
|
17403
|
+
var import_api2;
|
|
17404
|
+
var init_tracing = __esm(() => {
|
|
17405
|
+
init_sdk();
|
|
17406
|
+
import_api2 = __toESM(require_src(), 1);
|
|
17407
|
+
});
|
|
17408
|
+
|
|
17303
17409
|
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.3.21+3246782889eb34e0/node_modules/@gobing-ai/ts-infra/dist/telemetry/metrics.js
|
|
17304
17410
|
function getMeter() {
|
|
17305
|
-
return
|
|
17411
|
+
return import_api3.metrics.getMeter(METER_NAME, METER_VERSION);
|
|
17306
17412
|
}
|
|
17307
17413
|
function noopCounter() {
|
|
17308
17414
|
if (!_noopCounter)
|
|
17309
|
-
_noopCounter =
|
|
17415
|
+
_noopCounter = import_api3.createNoopMeter().createCounter("noop");
|
|
17310
17416
|
return _noopCounter;
|
|
17311
17417
|
}
|
|
17312
17418
|
function getOrCreateCounter(key, name, description, unit = "{operation}") {
|
|
@@ -17323,10 +17429,10 @@ function getEventbusEmitsTotal() {
|
|
|
17323
17429
|
function getEventbusErrorsTotal() {
|
|
17324
17430
|
return getOrCreateCounter("ebErr", "eventbus.errors.total", "Event bus errors", "{error}");
|
|
17325
17431
|
}
|
|
17326
|
-
var
|
|
17432
|
+
var import_api3, METER_NAME = "@gobing-ai/ts-infra", METER_VERSION = "0.1.0", instruments, _noopCounter;
|
|
17327
17433
|
var init_metrics = __esm(() => {
|
|
17328
17434
|
init_sdk();
|
|
17329
|
-
|
|
17435
|
+
import_api3 = __toESM(require_src(), 1);
|
|
17330
17436
|
instruments = {};
|
|
17331
17437
|
});
|
|
17332
17438
|
|
|
@@ -17580,10 +17686,16 @@ var init_event_bus2 = __esm(() => {
|
|
|
17580
17686
|
init_event_bus();
|
|
17581
17687
|
});
|
|
17582
17688
|
|
|
17689
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.3.21+3246782889eb34e0/node_modules/@gobing-ai/ts-infra/dist/telemetry/index.js
|
|
17690
|
+
var init_telemetry = __esm(() => {
|
|
17691
|
+
init_tracing();
|
|
17692
|
+
});
|
|
17693
|
+
|
|
17583
17694
|
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.3.21+3246782889eb34e0/node_modules/@gobing-ai/ts-infra/dist/index.js
|
|
17584
17695
|
var init_dist3 = __esm(() => {
|
|
17585
17696
|
init_event_bus2();
|
|
17586
17697
|
init_logger2();
|
|
17698
|
+
init_telemetry();
|
|
17587
17699
|
});
|
|
17588
17700
|
|
|
17589
17701
|
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.3.21+5a4f8cc6c6b198a4/node_modules/@gobing-ai/ts-ai-runner/dist/agents/shims.js
|
|
@@ -32516,7 +32628,7 @@ var init_config = __esm(() => {
|
|
|
32516
32628
|
});
|
|
32517
32629
|
|
|
32518
32630
|
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.3.21/node_modules/@gobing-ai/ts-runtime/dist/file-system-node.js
|
|
32519
|
-
import { appendFileSync, cpSync as cpSync2, createWriteStream, existsSync as existsSync9, mkdirSync as mkdirSync5, readdirSync as readdirSync3, readFileSync as readFileSync6, renameSync, rmSync as
|
|
32631
|
+
import { appendFileSync, cpSync as cpSync2, createWriteStream, existsSync as existsSync9, mkdirSync as mkdirSync5, readdirSync as readdirSync3, readFileSync as readFileSync6, renameSync, rmSync as rmSync4, statSync as statSync4, writeFileSync as writeFileSync4 } from "fs";
|
|
32520
32632
|
import { dirname as dirname5, resolve as resolvePath } from "path";
|
|
32521
32633
|
function createNodeFileSystem(root) {
|
|
32522
32634
|
const projectRoot = root ?? findProjectRoot(process.cwd());
|
|
@@ -32538,7 +32650,7 @@ function createNodeFileSystem(root) {
|
|
|
32538
32650
|
},
|
|
32539
32651
|
readDir: (path) => readdirSync3(path),
|
|
32540
32652
|
deleteFile: (path) => {
|
|
32541
|
-
|
|
32653
|
+
rmSync4(path, { recursive: true, force: true });
|
|
32542
32654
|
},
|
|
32543
32655
|
rename: (src, dest) => {
|
|
32544
32656
|
renameSync(src, dest);
|
|
@@ -32552,7 +32664,7 @@ function createNodeFileSystem(root) {
|
|
|
32552
32664
|
},
|
|
32553
32665
|
stat: (path) => {
|
|
32554
32666
|
try {
|
|
32555
|
-
const s =
|
|
32667
|
+
const s = statSync4(path);
|
|
32556
32668
|
return {
|
|
32557
32669
|
isFile: () => s.isFile(),
|
|
32558
32670
|
isDirectory: () => s.isDirectory(),
|
|
@@ -33518,12 +33630,12 @@ var require_isexe = __commonJS((exports, module) => {
|
|
|
33518
33630
|
if (typeof Promise !== "function") {
|
|
33519
33631
|
throw new TypeError("callback not provided");
|
|
33520
33632
|
}
|
|
33521
|
-
return new Promise(function(
|
|
33633
|
+
return new Promise(function(resolve3, reject) {
|
|
33522
33634
|
isexe(path, options2 || {}, function(er, is) {
|
|
33523
33635
|
if (er) {
|
|
33524
33636
|
reject(er);
|
|
33525
33637
|
} else {
|
|
33526
|
-
|
|
33638
|
+
resolve3(is);
|
|
33527
33639
|
}
|
|
33528
33640
|
});
|
|
33529
33641
|
});
|
|
@@ -33585,27 +33697,27 @@ var require_which = __commonJS((exports, module) => {
|
|
|
33585
33697
|
opt = {};
|
|
33586
33698
|
const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
|
|
33587
33699
|
const found = [];
|
|
33588
|
-
const step = (i) => new Promise((
|
|
33700
|
+
const step = (i) => new Promise((resolve3, reject) => {
|
|
33589
33701
|
if (i === pathEnv.length)
|
|
33590
|
-
return opt.all && found.length ?
|
|
33702
|
+
return opt.all && found.length ? resolve3(found) : reject(getNotFoundError(cmd));
|
|
33591
33703
|
const ppRaw = pathEnv[i];
|
|
33592
33704
|
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
33593
33705
|
const pCmd = path.join(pathPart, cmd);
|
|
33594
33706
|
const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
33595
|
-
|
|
33707
|
+
resolve3(subStep(p, i, 0));
|
|
33596
33708
|
});
|
|
33597
|
-
const subStep = (p, i, ii) => new Promise((
|
|
33709
|
+
const subStep = (p, i, ii) => new Promise((resolve3, reject) => {
|
|
33598
33710
|
if (ii === pathExt.length)
|
|
33599
|
-
return
|
|
33711
|
+
return resolve3(step(i + 1));
|
|
33600
33712
|
const ext = pathExt[ii];
|
|
33601
33713
|
isexe(p + ext, { pathExt: pathExtExe }, (er, is) => {
|
|
33602
33714
|
if (!er && is) {
|
|
33603
33715
|
if (opt.all)
|
|
33604
33716
|
found.push(p + ext);
|
|
33605
33717
|
else
|
|
33606
|
-
return
|
|
33718
|
+
return resolve3(p + ext);
|
|
33607
33719
|
}
|
|
33608
|
-
return
|
|
33720
|
+
return resolve3(subStep(p, i, ii + 1));
|
|
33609
33721
|
});
|
|
33610
33722
|
});
|
|
33611
33723
|
return cb ? step(0).then((res) => cb(null, res), cb) : step(0);
|
|
@@ -34411,7 +34523,7 @@ var normalizeForceKillAfterDelay = (forceKillAfterDelay) => {
|
|
|
34411
34523
|
throw new TypeError(`Expected the \`forceKillAfterDelay\` option to be a non-negative integer, got \`${forceKillAfterDelay}\` (${typeof forceKillAfterDelay})`);
|
|
34412
34524
|
}
|
|
34413
34525
|
return forceKillAfterDelay;
|
|
34414
|
-
}, DEFAULT_FORCE_KILL_TIMEOUT, subprocessKill = ({ kill, options: { forceKillAfterDelay, killSignal }, onInternalError, context, controller }, signalOrError, errorArgument) => {
|
|
34526
|
+
}, DEFAULT_FORCE_KILL_TIMEOUT, subprocessKill = ({ kill, options: { forceKillAfterDelay, killSignal }, onInternalError, context: context2, controller }, signalOrError, errorArgument) => {
|
|
34415
34527
|
const { signal, error: error51 } = parseKillArguments(signalOrError, errorArgument, killSignal);
|
|
34416
34528
|
emitKillError(error51, onInternalError);
|
|
34417
34529
|
const killResult = kill(signal);
|
|
@@ -34421,7 +34533,7 @@ var normalizeForceKillAfterDelay = (forceKillAfterDelay) => {
|
|
|
34421
34533
|
forceKillAfterDelay,
|
|
34422
34534
|
killSignal,
|
|
34423
34535
|
killResult,
|
|
34424
|
-
context,
|
|
34536
|
+
context: context2,
|
|
34425
34537
|
controller
|
|
34426
34538
|
});
|
|
34427
34539
|
return killResult;
|
|
@@ -34438,23 +34550,23 @@ var normalizeForceKillAfterDelay = (forceKillAfterDelay) => {
|
|
|
34438
34550
|
if (error51 !== undefined) {
|
|
34439
34551
|
onInternalError.reject(error51);
|
|
34440
34552
|
}
|
|
34441
|
-
}, setKillTimeout = async ({ kill, signal, forceKillAfterDelay, killSignal, killResult, context, controller }) => {
|
|
34553
|
+
}, setKillTimeout = async ({ kill, signal, forceKillAfterDelay, killSignal, killResult, context: context2, controller }) => {
|
|
34442
34554
|
if (signal === killSignal && killResult) {
|
|
34443
34555
|
killOnTimeout({
|
|
34444
34556
|
kill,
|
|
34445
34557
|
forceKillAfterDelay,
|
|
34446
|
-
context,
|
|
34558
|
+
context: context2,
|
|
34447
34559
|
controllerSignal: controller.signal
|
|
34448
34560
|
});
|
|
34449
34561
|
}
|
|
34450
|
-
}, killOnTimeout = async ({ kill, forceKillAfterDelay, context, controllerSignal }) => {
|
|
34562
|
+
}, killOnTimeout = async ({ kill, forceKillAfterDelay, context: context2, controllerSignal }) => {
|
|
34451
34563
|
if (forceKillAfterDelay === false) {
|
|
34452
34564
|
return;
|
|
34453
34565
|
}
|
|
34454
34566
|
try {
|
|
34455
34567
|
await setTimeout2(forceKillAfterDelay, undefined, { signal: controllerSignal });
|
|
34456
34568
|
if (kill("SIGKILL")) {
|
|
34457
|
-
|
|
34569
|
+
context2.isForcefullyTerminated ??= true;
|
|
34458
34570
|
}
|
|
34459
34571
|
} catch {}
|
|
34460
34572
|
};
|
|
@@ -34478,9 +34590,9 @@ var validateCancelSignal = ({ cancelSignal }) => {
|
|
|
34478
34590
|
if (cancelSignal !== undefined && Object.prototype.toString.call(cancelSignal) !== "[object AbortSignal]") {
|
|
34479
34591
|
throw new Error(`The \`cancelSignal\` option must be an AbortSignal: ${String(cancelSignal)}`);
|
|
34480
34592
|
}
|
|
34481
|
-
}, throwOnCancel = ({ subprocess, cancelSignal, gracefulCancel, context, controller }) => cancelSignal === undefined || gracefulCancel ? [] : [terminateOnCancel(subprocess, cancelSignal,
|
|
34593
|
+
}, throwOnCancel = ({ subprocess, cancelSignal, gracefulCancel, context: context2, controller }) => cancelSignal === undefined || gracefulCancel ? [] : [terminateOnCancel(subprocess, cancelSignal, context2, controller)], terminateOnCancel = async (subprocess, cancelSignal, context2, { signal }) => {
|
|
34482
34594
|
await onAbortedSignal(cancelSignal, signal);
|
|
34483
|
-
|
|
34595
|
+
context2.terminationReason ??= "cancel";
|
|
34484
34596
|
subprocess.kill();
|
|
34485
34597
|
throw cancelSignal.reason;
|
|
34486
34598
|
};
|
|
@@ -34544,8 +34656,8 @@ var init_validation = __esm(() => {
|
|
|
34544
34656
|
// ../../node_modules/.bun/execa@9.6.1/node_modules/execa/lib/utils/deferred.js
|
|
34545
34657
|
var createDeferred = () => {
|
|
34546
34658
|
const methods = {};
|
|
34547
|
-
const promise2 = new Promise((
|
|
34548
|
-
Object.assign(methods, { resolve:
|
|
34659
|
+
const promise2 = new Promise((resolve3, reject) => {
|
|
34660
|
+
Object.assign(methods, { resolve: resolve3, reject });
|
|
34549
34661
|
});
|
|
34550
34662
|
return Object.assign(promise2, methods);
|
|
34551
34663
|
};
|
|
@@ -35005,25 +35117,25 @@ var validateGracefulCancel = ({ gracefulCancel, cancelSignal, ipc, serialization
|
|
|
35005
35117
|
cancelSignal,
|
|
35006
35118
|
gracefulCancel,
|
|
35007
35119
|
forceKillAfterDelay,
|
|
35008
|
-
context,
|
|
35120
|
+
context: context2,
|
|
35009
35121
|
controller
|
|
35010
35122
|
}) => gracefulCancel ? [sendOnAbort({
|
|
35011
35123
|
subprocess,
|
|
35012
35124
|
cancelSignal,
|
|
35013
35125
|
forceKillAfterDelay,
|
|
35014
|
-
context,
|
|
35126
|
+
context: context2,
|
|
35015
35127
|
controller
|
|
35016
|
-
})] : [], sendOnAbort = async ({ subprocess, cancelSignal, forceKillAfterDelay, context, controller: { signal } }) => {
|
|
35128
|
+
})] : [], sendOnAbort = async ({ subprocess, cancelSignal, forceKillAfterDelay, context: context2, controller: { signal } }) => {
|
|
35017
35129
|
await onAbortedSignal(cancelSignal, signal);
|
|
35018
35130
|
const reason = getReason(cancelSignal);
|
|
35019
35131
|
await sendAbort(subprocess, reason);
|
|
35020
35132
|
killOnTimeout({
|
|
35021
35133
|
kill: subprocess.kill,
|
|
35022
35134
|
forceKillAfterDelay,
|
|
35023
|
-
context,
|
|
35135
|
+
context: context2,
|
|
35024
35136
|
controllerSignal: signal
|
|
35025
35137
|
});
|
|
35026
|
-
|
|
35138
|
+
context2.terminationReason ??= "gracefulCancel";
|
|
35027
35139
|
throw cancelSignal.reason;
|
|
35028
35140
|
}, getReason = ({ reason }) => {
|
|
35029
35141
|
if (!(reason instanceof DOMException)) {
|
|
@@ -35050,9 +35162,9 @@ var validateTimeout = ({ timeout }) => {
|
|
|
35050
35162
|
if (timeout !== undefined && (!Number.isFinite(timeout) || timeout < 0)) {
|
|
35051
35163
|
throw new TypeError(`Expected the \`timeout\` option to be a non-negative integer, got \`${timeout}\` (${typeof timeout})`);
|
|
35052
35164
|
}
|
|
35053
|
-
}, throwOnTimeout = (subprocess, timeout,
|
|
35165
|
+
}, throwOnTimeout = (subprocess, timeout, context2, controller) => timeout === 0 || timeout === undefined ? [] : [killAfterTimeout(subprocess, timeout, context2, controller)], killAfterTimeout = async (subprocess, timeout, context2, { signal }) => {
|
|
35054
35166
|
await setTimeout3(timeout, undefined, { signal });
|
|
35055
|
-
|
|
35167
|
+
context2.terminationReason ??= "timeout";
|
|
35056
35168
|
subprocess.kill();
|
|
35057
35169
|
throw new DiscardedError;
|
|
35058
35170
|
};
|
|
@@ -35180,7 +35292,7 @@ var init_encoding_option = __esm(() => {
|
|
|
35180
35292
|
});
|
|
35181
35293
|
|
|
35182
35294
|
// ../../node_modules/.bun/execa@9.6.1/node_modules/execa/lib/arguments/cwd.js
|
|
35183
|
-
import { statSync as
|
|
35295
|
+
import { statSync as statSync5 } from "fs";
|
|
35184
35296
|
import path4 from "path";
|
|
35185
35297
|
import process6 from "process";
|
|
35186
35298
|
var normalizeCwd = (cwd5 = getDefaultCwd()) => {
|
|
@@ -35200,7 +35312,7 @@ ${error51.message}`;
|
|
|
35200
35312
|
}
|
|
35201
35313
|
let cwdStat;
|
|
35202
35314
|
try {
|
|
35203
|
-
cwdStat =
|
|
35315
|
+
cwdStat = statSync5(cwd5);
|
|
35204
35316
|
} catch (error51) {
|
|
35205
35317
|
return `The "cwd" option is invalid: ${cwd5}.
|
|
35206
35318
|
${error51.message}
|
|
@@ -37409,9 +37521,9 @@ var init_all_sync = __esm(() => {
|
|
|
37409
37521
|
|
|
37410
37522
|
// ../../node_modules/.bun/execa@9.6.1/node_modules/execa/lib/resolve/exit-async.js
|
|
37411
37523
|
import { once as once4 } from "events";
|
|
37412
|
-
var waitForExit = async (subprocess,
|
|
37524
|
+
var waitForExit = async (subprocess, context2) => {
|
|
37413
37525
|
const [exitCode, signal] = await waitForExitOrError(subprocess);
|
|
37414
|
-
|
|
37526
|
+
context2.isForcefullyTerminated ??= false;
|
|
37415
37527
|
return [exitCode, signal];
|
|
37416
37528
|
}, waitForExitOrError = async (subprocess) => {
|
|
37417
37529
|
const [spawnPayload, exitPayload] = await Promise.allSettled([
|
|
@@ -39020,14 +39132,14 @@ var waitForSubprocessResult = async ({
|
|
|
39020
39132
|
ipc,
|
|
39021
39133
|
ipcInput
|
|
39022
39134
|
},
|
|
39023
|
-
context,
|
|
39135
|
+
context: context2,
|
|
39024
39136
|
verboseInfo,
|
|
39025
39137
|
fileDescriptors,
|
|
39026
39138
|
originalStreams,
|
|
39027
39139
|
onInternalError,
|
|
39028
39140
|
controller
|
|
39029
39141
|
}) => {
|
|
39030
|
-
const exitPromise = waitForExit(subprocess,
|
|
39142
|
+
const exitPromise = waitForExit(subprocess, context2);
|
|
39031
39143
|
const streamInfo = {
|
|
39032
39144
|
originalStreams,
|
|
39033
39145
|
fileDescriptors,
|
|
@@ -39080,12 +39192,12 @@ var waitForSubprocessResult = async ({
|
|
|
39080
39192
|
]),
|
|
39081
39193
|
onInternalError,
|
|
39082
39194
|
throwOnSubprocessError(subprocess, controller),
|
|
39083
|
-
...throwOnTimeout(subprocess, timeout,
|
|
39195
|
+
...throwOnTimeout(subprocess, timeout, context2, controller),
|
|
39084
39196
|
...throwOnCancel({
|
|
39085
39197
|
subprocess,
|
|
39086
39198
|
cancelSignal,
|
|
39087
39199
|
gracefulCancel,
|
|
39088
|
-
context,
|
|
39200
|
+
context: context2,
|
|
39089
39201
|
controller
|
|
39090
39202
|
}),
|
|
39091
39203
|
...throwOnGracefulCancel({
|
|
@@ -39093,12 +39205,12 @@ var waitForSubprocessResult = async ({
|
|
|
39093
39205
|
cancelSignal,
|
|
39094
39206
|
gracefulCancel,
|
|
39095
39207
|
forceKillAfterDelay,
|
|
39096
|
-
context,
|
|
39208
|
+
context: context2,
|
|
39097
39209
|
controller
|
|
39098
39210
|
})
|
|
39099
39211
|
]);
|
|
39100
39212
|
} catch (error51) {
|
|
39101
|
-
|
|
39213
|
+
context2.terminationReason ??= "other";
|
|
39102
39214
|
return Promise.all([
|
|
39103
39215
|
{ error: error51 },
|
|
39104
39216
|
exitPromise,
|
|
@@ -39144,10 +39256,10 @@ var initializeConcurrentStreams = () => ({
|
|
|
39144
39256
|
const promises = weakMap.get(stream);
|
|
39145
39257
|
const promise2 = createDeferred();
|
|
39146
39258
|
promises.push(promise2);
|
|
39147
|
-
const
|
|
39148
|
-
return { resolve:
|
|
39149
|
-
}, waitForConcurrentStreams = async ({ resolve:
|
|
39150
|
-
|
|
39259
|
+
const resolve3 = promise2.resolve.bind(promise2);
|
|
39260
|
+
return { resolve: resolve3, promises };
|
|
39261
|
+
}, waitForConcurrentStreams = async ({ resolve: resolve3, promises }, subprocess) => {
|
|
39262
|
+
resolve3();
|
|
39151
39263
|
const [isSubprocessExit] = await Promise.race([
|
|
39152
39264
|
Promise.allSettled([true, subprocess]),
|
|
39153
39265
|
Promise.all([false, ...promises])
|
|
@@ -39529,13 +39641,13 @@ var execaCoreAsync = (rawFile, rawArguments, rawOptions, createNested) => {
|
|
|
39529
39641
|
const originalStreams = [...subprocess.stdio];
|
|
39530
39642
|
pipeOutputAsync(subprocess, fileDescriptors, controller);
|
|
39531
39643
|
cleanupOnExit(subprocess, options2, controller);
|
|
39532
|
-
const
|
|
39644
|
+
const context2 = {};
|
|
39533
39645
|
const onInternalError = createDeferred();
|
|
39534
39646
|
subprocess.kill = subprocessKill.bind(undefined, {
|
|
39535
39647
|
kill: subprocess.kill.bind(subprocess),
|
|
39536
39648
|
options: options2,
|
|
39537
39649
|
onInternalError,
|
|
39538
|
-
context,
|
|
39650
|
+
context: context2,
|
|
39539
39651
|
controller
|
|
39540
39652
|
});
|
|
39541
39653
|
subprocess.all = makeAllStream(subprocess, options2);
|
|
@@ -39550,12 +39662,12 @@ var execaCoreAsync = (rawFile, rawArguments, rawOptions, createNested) => {
|
|
|
39550
39662
|
originalStreams,
|
|
39551
39663
|
command,
|
|
39552
39664
|
escapedCommand,
|
|
39553
|
-
context,
|
|
39665
|
+
context: context2,
|
|
39554
39666
|
onInternalError,
|
|
39555
39667
|
controller
|
|
39556
39668
|
});
|
|
39557
39669
|
return { subprocess, promise: promise2 };
|
|
39558
|
-
}, handlePromise = async ({ subprocess, options: options2, startTime, verboseInfo, fileDescriptors, originalStreams, command, escapedCommand, context, onInternalError, controller }) => {
|
|
39670
|
+
}, handlePromise = async ({ subprocess, options: options2, startTime, verboseInfo, fileDescriptors, originalStreams, command, escapedCommand, context: context2, onInternalError, controller }) => {
|
|
39559
39671
|
const [
|
|
39560
39672
|
errorInfo,
|
|
39561
39673
|
[exitCode, signal],
|
|
@@ -39565,7 +39677,7 @@ var execaCoreAsync = (rawFile, rawArguments, rawOptions, createNested) => {
|
|
|
39565
39677
|
] = await waitForSubprocessResult({
|
|
39566
39678
|
subprocess,
|
|
39567
39679
|
options: options2,
|
|
39568
|
-
context,
|
|
39680
|
+
context: context2,
|
|
39569
39681
|
verboseInfo,
|
|
39570
39682
|
fileDescriptors,
|
|
39571
39683
|
originalStreams,
|
|
@@ -39583,22 +39695,22 @@ var execaCoreAsync = (rawFile, rawArguments, rawOptions, createNested) => {
|
|
|
39583
39695
|
stdio,
|
|
39584
39696
|
all,
|
|
39585
39697
|
ipcOutput,
|
|
39586
|
-
context,
|
|
39698
|
+
context: context2,
|
|
39587
39699
|
options: options2,
|
|
39588
39700
|
command,
|
|
39589
39701
|
escapedCommand,
|
|
39590
39702
|
startTime
|
|
39591
39703
|
});
|
|
39592
39704
|
return handleResult2(result, verboseInfo, options2);
|
|
39593
|
-
}, getAsyncResult = ({ errorInfo, exitCode, signal, stdio, all, ipcOutput, context, options: options2, command, escapedCommand, startTime }) => ("error" in errorInfo) ? makeError({
|
|
39705
|
+
}, getAsyncResult = ({ errorInfo, exitCode, signal, stdio, all, ipcOutput, context: context2, options: options2, command, escapedCommand, startTime }) => ("error" in errorInfo) ? makeError({
|
|
39594
39706
|
error: errorInfo.error,
|
|
39595
39707
|
command,
|
|
39596
39708
|
escapedCommand,
|
|
39597
|
-
timedOut:
|
|
39598
|
-
isCanceled:
|
|
39599
|
-
isGracefullyCanceled:
|
|
39709
|
+
timedOut: context2.terminationReason === "timeout",
|
|
39710
|
+
isCanceled: context2.terminationReason === "cancel" || context2.terminationReason === "gracefulCancel",
|
|
39711
|
+
isGracefullyCanceled: context2.terminationReason === "gracefulCancel",
|
|
39600
39712
|
isMaxBuffer: errorInfo.error instanceof MaxBufferError,
|
|
39601
|
-
isForcefullyTerminated:
|
|
39713
|
+
isForcefullyTerminated: context2.isForcefullyTerminated,
|
|
39602
39714
|
exitCode,
|
|
39603
39715
|
signal,
|
|
39604
39716
|
stdio,
|
|
@@ -39903,18 +40015,18 @@ class ObservedPipeProcess {
|
|
|
39903
40015
|
inner;
|
|
39904
40016
|
killedWith;
|
|
39905
40017
|
exited;
|
|
39906
|
-
constructor(inner, events,
|
|
40018
|
+
constructor(inner, events, context2) {
|
|
39907
40019
|
this.inner = inner;
|
|
39908
40020
|
this.exited = inner.exited.then((exitCode) => {
|
|
39909
40021
|
events?.emit("process.exited", {
|
|
39910
|
-
command:
|
|
39911
|
-
args:
|
|
40022
|
+
command: context2.command,
|
|
40023
|
+
args: context2.args,
|
|
39912
40024
|
exitCode,
|
|
39913
40025
|
...this.killedWith !== undefined ? { signal: String(this.killedWith) } : {},
|
|
39914
|
-
durationMs: Date.now() -
|
|
40026
|
+
durationMs: Date.now() - context2.startedAt,
|
|
39915
40027
|
reason: this.killedWith !== undefined ? "signal" : "exit",
|
|
39916
40028
|
timestamp: new Date().toISOString(),
|
|
39917
|
-
...
|
|
40029
|
+
...context2.label !== undefined ? { label: context2.label } : {}
|
|
39918
40030
|
});
|
|
39919
40031
|
return exitCode;
|
|
39920
40032
|
});
|
|
@@ -40001,8 +40113,11 @@ function isTimedOut(error51) {
|
|
|
40001
40113
|
function errorMessage(error51) {
|
|
40002
40114
|
return error51 instanceof Error ? error51.message : String(error51);
|
|
40003
40115
|
}
|
|
40116
|
+
var NodeProcessExecutor;
|
|
40004
40117
|
var init_process_executor = __esm(() => {
|
|
40005
40118
|
init_execa();
|
|
40119
|
+
NodeProcessExecutor = class NodeProcessExecutor extends ProcessExecutor {
|
|
40120
|
+
};
|
|
40006
40121
|
});
|
|
40007
40122
|
|
|
40008
40123
|
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.3.21/node_modules/@gobing-ai/ts-runtime/dist/context.js
|
|
@@ -40159,6 +40274,7 @@ var init_types3 = () => {};
|
|
|
40159
40274
|
var init_dist4 = __esm(() => {
|
|
40160
40275
|
init_file_system_node();
|
|
40161
40276
|
init_process_executor();
|
|
40277
|
+
init_process_executor();
|
|
40162
40278
|
init_config();
|
|
40163
40279
|
init_context2();
|
|
40164
40280
|
init_path();
|
|
@@ -40234,19 +40350,101 @@ var init_slash_command = __esm(() => {
|
|
|
40234
40350
|
});
|
|
40235
40351
|
|
|
40236
40352
|
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.3.21+5a4f8cc6c6b198a4/node_modules/@gobing-ai/ts-ai-runner/dist/ai-runner.js
|
|
40353
|
+
class AiRunner {
|
|
40354
|
+
processExecutor;
|
|
40355
|
+
defaultCwd;
|
|
40356
|
+
defaultTimeout;
|
|
40357
|
+
logger;
|
|
40358
|
+
events;
|
|
40359
|
+
constructor(options2 = {}) {
|
|
40360
|
+
this.processExecutor = options2.processExecutor ?? new NodeProcessExecutor({
|
|
40361
|
+
...options2.processEvents !== undefined ? {
|
|
40362
|
+
events: {
|
|
40363
|
+
emit: (event, detail) => {
|
|
40364
|
+
options2.processEvents?.emit(event, detail);
|
|
40365
|
+
}
|
|
40366
|
+
}
|
|
40367
|
+
} : {},
|
|
40368
|
+
tracer: options2.tracer ?? {
|
|
40369
|
+
traceAsync: async (name, fn) => await traceAsync(name, (span) => fn(span))
|
|
40370
|
+
}
|
|
40371
|
+
});
|
|
40372
|
+
this.defaultCwd = options2.defaultCwd;
|
|
40373
|
+
this.defaultTimeout = options2.defaultTimeout;
|
|
40374
|
+
this.logger = options2.logger ?? getLogger2("ai-runner");
|
|
40375
|
+
this.events = options2.events;
|
|
40376
|
+
}
|
|
40377
|
+
runHelpCommand(agent, options2 = {}) {
|
|
40378
|
+
return this.invoke(agent, "help", getAgentShim(agent).getHelpCommand(), options2, true);
|
|
40379
|
+
}
|
|
40380
|
+
runVersionCommand(agent, options2 = {}) {
|
|
40381
|
+
return this.invoke(agent, "version", getAgentShim(agent).getVersionCommand(), options2, true);
|
|
40382
|
+
}
|
|
40383
|
+
runPromptCommand(agent, promptOptions, options2 = {}) {
|
|
40384
|
+
return this.invoke(agent, "prompt", this.buildPromptCommand(agent, promptOptions, options2), options2, false);
|
|
40385
|
+
}
|
|
40386
|
+
runSlashCommand(agent, input, promptOptions, options2 = {}) {
|
|
40387
|
+
return this.runPromptCommand(agent, { ...promptOptions, input: translateSlashCommand(agent, input) }, options2);
|
|
40388
|
+
}
|
|
40389
|
+
buildPromptCommand(agent, promptOptions, options2 = {}) {
|
|
40390
|
+
return buildAgentCommand(agent, promptOptions, {
|
|
40391
|
+
workspace: options2.cwd ?? this.defaultCwd ?? getProcessCwd()
|
|
40392
|
+
});
|
|
40393
|
+
}
|
|
40394
|
+
runAuthCommand(agent, options2 = {}) {
|
|
40395
|
+
const command = getAgentShim(agent).getAuthCommand();
|
|
40396
|
+
return command === null ? null : this.invoke(agent, "auth", command, options2, true);
|
|
40397
|
+
}
|
|
40398
|
+
async invoke(agent, operation, command, options2, forceBuffered) {
|
|
40399
|
+
const label = `ai-runner.${agent}.${operation}`;
|
|
40400
|
+
this.logger.debug("invoke", { label, command: command.command, args: command.args.join(" ") });
|
|
40401
|
+
this.events?.emit("agent.invoke.start", { agent, operation, label });
|
|
40402
|
+
const result = await this.processExecutor.run({
|
|
40403
|
+
command: command.command,
|
|
40404
|
+
args: command.args,
|
|
40405
|
+
label,
|
|
40406
|
+
rejectOnError: false,
|
|
40407
|
+
forceBuffered,
|
|
40408
|
+
cwd: options2.cwd ?? this.defaultCwd,
|
|
40409
|
+
timeout: options2.timeout ?? this.defaultTimeout
|
|
40410
|
+
});
|
|
40411
|
+
if (result.exitCode !== 0) {
|
|
40412
|
+
this.logger.error("invoke exited non-zero", {
|
|
40413
|
+
label,
|
|
40414
|
+
exitCode: result.exitCode,
|
|
40415
|
+
signal: result.signal
|
|
40416
|
+
});
|
|
40417
|
+
}
|
|
40418
|
+
this.events?.emit("agent.invoke.exit", {
|
|
40419
|
+
agent,
|
|
40420
|
+
operation,
|
|
40421
|
+
label,
|
|
40422
|
+
exitCode: result.exitCode,
|
|
40423
|
+
...result.signal !== undefined ? { signal: result.signal } : {},
|
|
40424
|
+
durationMs: result.durationMs
|
|
40425
|
+
});
|
|
40426
|
+
return {
|
|
40427
|
+
exitCode: result.exitCode,
|
|
40428
|
+
stdout: result.stdout,
|
|
40429
|
+
stderr: result.stderr,
|
|
40430
|
+
...result.signal !== undefined ? { signal: result.signal } : {},
|
|
40431
|
+
durationMs: result.durationMs
|
|
40432
|
+
};
|
|
40433
|
+
}
|
|
40434
|
+
}
|
|
40237
40435
|
function hasIdentityOptions(options2) {
|
|
40238
40436
|
return options2.purpose !== undefined || options2.systemPrompt !== undefined || options2.taskId !== undefined || options2.peers !== undefined && options2.peers.length > 0;
|
|
40239
40437
|
}
|
|
40240
|
-
function buildAgentCommand(agent, promptOptions,
|
|
40241
|
-
return getAgentShim(agent).getPromptCommand(applyIdentityPreamble(agent, promptOptions,
|
|
40438
|
+
function buildAgentCommand(agent, promptOptions, context3) {
|
|
40439
|
+
return getAgentShim(agent).getPromptCommand(applyIdentityPreamble(agent, promptOptions, context3));
|
|
40242
40440
|
}
|
|
40243
|
-
function applyIdentityPreamble(agent, promptOptions,
|
|
40441
|
+
function applyIdentityPreamble(agent, promptOptions, context3) {
|
|
40244
40442
|
if (!hasIdentityOptions(promptOptions))
|
|
40245
40443
|
return promptOptions;
|
|
40246
40444
|
const preamble = buildIdentityPreamble({
|
|
40247
40445
|
agentId: agent,
|
|
40248
40446
|
agentType: agent,
|
|
40249
|
-
workspace:
|
|
40447
|
+
workspace: context3.workspace,
|
|
40250
40448
|
purpose: promptOptions.purpose,
|
|
40251
40449
|
systemPrompt: promptOptions.systemPrompt,
|
|
40252
40450
|
taskId: promptOptions.taskId,
|
|
@@ -40257,8 +40455,11 @@ ${promptOptions.input}`;
|
|
|
40257
40455
|
return { ...promptOptions, input };
|
|
40258
40456
|
}
|
|
40259
40457
|
var init_ai_runner = __esm(() => {
|
|
40458
|
+
init_dist3();
|
|
40459
|
+
init_dist4();
|
|
40260
40460
|
init_shims();
|
|
40261
40461
|
init_identity2();
|
|
40462
|
+
init_slash_command();
|
|
40262
40463
|
});
|
|
40263
40464
|
|
|
40264
40465
|
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.3.21+5a4f8cc6c6b198a4/node_modules/@gobing-ai/ts-ai-runner/dist/agent-detector.js
|
|
@@ -40409,8 +40610,8 @@ class TeamAgentProcess {
|
|
|
40409
40610
|
this.warn("stdin close failed", "stop.endStdin", error51);
|
|
40410
40611
|
}
|
|
40411
40612
|
process11.kill("SIGTERM");
|
|
40412
|
-
const timeout = new Promise((
|
|
40413
|
-
setTimeout(() =>
|
|
40613
|
+
const timeout = new Promise((resolve3) => {
|
|
40614
|
+
setTimeout(() => resolve3("timeout"), 5000);
|
|
40414
40615
|
});
|
|
40415
40616
|
const result = await Promise.race([process11.exited, timeout]);
|
|
40416
40617
|
if (result === "timeout") {
|
|
@@ -40628,7 +40829,7 @@ var init_dist5 = __esm(() => {
|
|
|
40628
40829
|
});
|
|
40629
40830
|
|
|
40630
40831
|
// ../../packages/core/src/targets.ts
|
|
40631
|
-
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;
|
|
40632
40833
|
var init_targets = __esm(() => {
|
|
40633
40834
|
TARGETS = [
|
|
40634
40835
|
"claude",
|
|
@@ -40647,6 +40848,12 @@ var init_targets = __esm(() => {
|
|
|
40647
40848
|
"antigravity-cli": "codexcli",
|
|
40648
40849
|
"antigravity-ide": "codexcli"
|
|
40649
40850
|
};
|
|
40851
|
+
TARGET_TO_RULESYNC_HOOKS = {
|
|
40852
|
+
codex: "codexcli",
|
|
40853
|
+
opencode: "opencode",
|
|
40854
|
+
"antigravity-cli": "antigravity-cli",
|
|
40855
|
+
"antigravity-ide": "antigravity-ide"
|
|
40856
|
+
};
|
|
40650
40857
|
TARGET_SKILLS_RELDIR = {
|
|
40651
40858
|
codex: ".agents/skills",
|
|
40652
40859
|
pi: ".agents/skills",
|
|
@@ -40766,7 +40973,7 @@ function scoreSkillLinkage(body) {
|
|
|
40766
40973
|
function scoreModelFit(data) {
|
|
40767
40974
|
const model = data.model;
|
|
40768
40975
|
const recognizedAliases = { inherit: true, sonnet: true, opus: true, haiku: true };
|
|
40769
|
-
const wellFormedPattern = /^claude-(sonnet|opus|haiku)-/i;
|
|
40976
|
+
const wellFormedPattern = /^claude-(\d+-\d+-)?(sonnet|opus|haiku)-/i;
|
|
40770
40977
|
let score;
|
|
40771
40978
|
let note;
|
|
40772
40979
|
if (typeof model === "string") {
|
|
@@ -40957,6 +41164,127 @@ var init_command3 = __esm(() => {
|
|
|
40957
41164
|
init_types2();
|
|
40958
41165
|
});
|
|
40959
41166
|
|
|
41167
|
+
// ../../packages/core/src/quality/eval-cases.ts
|
|
41168
|
+
import { existsSync as existsSync10, readFileSync as readFileSync9 } from "fs";
|
|
41169
|
+
import { join as join8 } from "path";
|
|
41170
|
+
function isRuleJudge(value) {
|
|
41171
|
+
return typeof value === "object" && value !== null && "checks" in value && Array.isArray(value.checks);
|
|
41172
|
+
}
|
|
41173
|
+
function isRubricRef(value) {
|
|
41174
|
+
return typeof value === "object" && value !== null && "criterion" in value && typeof value.criterion === "string" && !("checks" in value);
|
|
41175
|
+
}
|
|
41176
|
+
function resolveEvalCasesPath(name, opts) {
|
|
41177
|
+
if (opts?.path) {
|
|
41178
|
+
if (!existsSync10(opts.path))
|
|
41179
|
+
return null;
|
|
41180
|
+
return opts.path;
|
|
41181
|
+
}
|
|
41182
|
+
assertSafePathSegment(name, "eval cases skill name");
|
|
41183
|
+
const coLocated = join8(process.cwd(), "skills", name, "eval", "cases.yaml");
|
|
41184
|
+
if (existsSync10(coLocated))
|
|
41185
|
+
return coLocated;
|
|
41186
|
+
return null;
|
|
41187
|
+
}
|
|
41188
|
+
function loadEvalCases(name, opts) {
|
|
41189
|
+
const resolvedPath = resolveEvalCasesPath(name, opts);
|
|
41190
|
+
if (!resolvedPath)
|
|
41191
|
+
return null;
|
|
41192
|
+
const raw = readFileSync9(resolvedPath, "utf-8");
|
|
41193
|
+
let parsed;
|
|
41194
|
+
try {
|
|
41195
|
+
parsed = $parse(raw);
|
|
41196
|
+
} catch (e) {
|
|
41197
|
+
throw new EvalCaseError(resolvedPath, null, `Failed to parse YAML: ${e instanceof Error ? e.message : String(e)}`);
|
|
41198
|
+
}
|
|
41199
|
+
const result = EvalCaseSetSchema.safeParse(parsed);
|
|
41200
|
+
if (!result.success) {
|
|
41201
|
+
const issue2 = result.error.issues[0];
|
|
41202
|
+
if (!issue2) {
|
|
41203
|
+
throw new EvalCaseError(resolvedPath, null, "Schema validation failed with no issue reported.");
|
|
41204
|
+
}
|
|
41205
|
+
const caseId = extractCaseIdFromPath(issue2.path, parsed);
|
|
41206
|
+
const field = issue2.path.length > 0 ? issue2.path.join(".") : "root";
|
|
41207
|
+
throw new EvalCaseError(resolvedPath, caseId, `Schema validation failed at "${field}": ${issue2.message}`);
|
|
41208
|
+
}
|
|
41209
|
+
const caseSet = result.data;
|
|
41210
|
+
const seen = new Set;
|
|
41211
|
+
for (const c3 of caseSet.cases) {
|
|
41212
|
+
if (seen.has(c3.id)) {
|
|
41213
|
+
throw new EvalCaseError(resolvedPath, c3.id, `Duplicate case id "${c3.id}"`);
|
|
41214
|
+
}
|
|
41215
|
+
seen.add(c3.id);
|
|
41216
|
+
}
|
|
41217
|
+
return caseSet;
|
|
41218
|
+
}
|
|
41219
|
+
function extractCaseIdFromPath(path7, parsed) {
|
|
41220
|
+
const casesIdx = path7.indexOf("cases");
|
|
41221
|
+
if (casesIdx >= 0 && path7.length > casesIdx + 1 && typeof path7[casesIdx + 1] === "number") {
|
|
41222
|
+
const caseIndex = path7[casesIdx + 1];
|
|
41223
|
+
if (typeof parsed === "object" && parsed !== null && "cases" in parsed && Array.isArray(parsed.cases)) {
|
|
41224
|
+
const candidate = parsed.cases[caseIndex];
|
|
41225
|
+
if (typeof candidate === "object" && candidate !== null && "id" in candidate && typeof candidate.id === "string") {
|
|
41226
|
+
return candidate.id;
|
|
41227
|
+
}
|
|
41228
|
+
}
|
|
41229
|
+
return `cases[${caseIndex}]`;
|
|
41230
|
+
}
|
|
41231
|
+
return null;
|
|
41232
|
+
}
|
|
41233
|
+
var RuleCheckSchema, RubricRefSchema, RuleJudgeSchema, EvalCaseSchema, EvalCaseSetSchema, EvalCaseError;
|
|
41234
|
+
var init_eval_cases = __esm(() => {
|
|
41235
|
+
init_dist2();
|
|
41236
|
+
init_zod();
|
|
41237
|
+
init_identity();
|
|
41238
|
+
RuleCheckSchema = exports_external.object({
|
|
41239
|
+
op: exports_external.enum(["contains", "regex", "equals", "not_contains", "tool_called"]),
|
|
41240
|
+
arg: exports_external.string().min(1)
|
|
41241
|
+
});
|
|
41242
|
+
RubricRefSchema = exports_external.object({
|
|
41243
|
+
criterion: exports_external.string().min(1),
|
|
41244
|
+
excellent: exports_external.string().optional(),
|
|
41245
|
+
poor: exports_external.string().optional()
|
|
41246
|
+
});
|
|
41247
|
+
RuleJudgeSchema = exports_external.object({
|
|
41248
|
+
checks: exports_external.array(RuleCheckSchema).min(1)
|
|
41249
|
+
});
|
|
41250
|
+
EvalCaseSchema = exports_external.object({
|
|
41251
|
+
id: exports_external.string().min(1),
|
|
41252
|
+
split: exports_external.enum(["train", "holdout"]),
|
|
41253
|
+
prompt: exports_external.string().min(1),
|
|
41254
|
+
reference_kind: exports_external.enum(["exact", "rule", "rubric"]),
|
|
41255
|
+
reference: exports_external.union([exports_external.string().min(1), RuleJudgeSchema, RubricRefSchema]),
|
|
41256
|
+
tags: exports_external.array(exports_external.string().min(1)).optional()
|
|
41257
|
+
}).refine((c3) => {
|
|
41258
|
+
if (c3.reference_kind === "exact" && typeof c3.reference !== "string") {
|
|
41259
|
+
return false;
|
|
41260
|
+
}
|
|
41261
|
+
if (c3.reference_kind === "rule" && !isRuleJudge(c3.reference)) {
|
|
41262
|
+
return false;
|
|
41263
|
+
}
|
|
41264
|
+
if (c3.reference_kind === "rubric" && !isRubricRef(c3.reference)) {
|
|
41265
|
+
return false;
|
|
41266
|
+
}
|
|
41267
|
+
return true;
|
|
41268
|
+
}, {
|
|
41269
|
+
message: 'reference must match reference_kind: string for "exact", RuleJudge for "rule", RubricRef for "rubric"'
|
|
41270
|
+
});
|
|
41271
|
+
EvalCaseSetSchema = exports_external.object({
|
|
41272
|
+
version: exports_external.literal(1),
|
|
41273
|
+
cases: exports_external.array(EvalCaseSchema).min(1)
|
|
41274
|
+
});
|
|
41275
|
+
EvalCaseError = class EvalCaseError extends Error {
|
|
41276
|
+
file;
|
|
41277
|
+
caseId;
|
|
41278
|
+
constructor(file2, caseId, message) {
|
|
41279
|
+
const prefix = caseId ? `${file2}: case "${caseId}" \u2014 ` : `${file2}: `;
|
|
41280
|
+
super(`${prefix}${message}`);
|
|
41281
|
+
this.file = file2;
|
|
41282
|
+
this.caseId = caseId;
|
|
41283
|
+
this.name = "EvalCaseError";
|
|
41284
|
+
}
|
|
41285
|
+
};
|
|
41286
|
+
});
|
|
41287
|
+
|
|
40960
41288
|
// ../../packages/core/src/quality/magent.ts
|
|
40961
41289
|
function scoreCompleteness3(body) {
|
|
40962
41290
|
let found = 0;
|
|
@@ -40993,7 +41321,7 @@ function scorePlatformCoverage(data, body) {
|
|
|
40993
41321
|
[/opencode/i, "opencode"],
|
|
40994
41322
|
[/openclaw/i, "openclaw"],
|
|
40995
41323
|
[/antigravity/i, "antigravity"],
|
|
40996
|
-
[
|
|
41324
|
+
[/\bpi\b/i, "pi"]
|
|
40997
41325
|
];
|
|
40998
41326
|
for (const [re, name] of platformPatterns) {
|
|
40999
41327
|
if (re.test(body))
|
|
@@ -41038,7 +41366,9 @@ function scoreSafety2(body) {
|
|
|
41038
41366
|
}
|
|
41039
41367
|
function evaluateMagent(content, target) {
|
|
41040
41368
|
const body = extractBody(content);
|
|
41041
|
-
const hasFrontmatter =
|
|
41369
|
+
const hasFrontmatter = content.startsWith(`---
|
|
41370
|
+
`) || content.startsWith(`---\r
|
|
41371
|
+
`);
|
|
41042
41372
|
const fmResult = hasFrontmatter ? parseFrontmatterSafe(content) : undefined;
|
|
41043
41373
|
const data = fmResult ?? {};
|
|
41044
41374
|
const fmNote = hasFrontmatter && fmResult === null ? parseErrorNote(content, "Frontmatter parse error") : null;
|
|
@@ -41180,7 +41510,7 @@ function countTriggerPhrases(body) {
|
|
|
41180
41510
|
if (headingMatch) {
|
|
41181
41511
|
const depth = headingMatch[1]?.length ?? 0;
|
|
41182
41512
|
const title = (headingMatch[2] ?? "").toLowerCase();
|
|
41183
|
-
if (/\
|
|
41513
|
+
if (/\b(?:trigger|when to use)/i.test(title)) {
|
|
41184
41514
|
inTriggerSection = true;
|
|
41185
41515
|
sectionDepth = depth;
|
|
41186
41516
|
} else if (inTriggerSection && depth <= sectionDepth) {
|
|
@@ -41196,7 +41526,7 @@ function countTriggerPhrases(body) {
|
|
|
41196
41526
|
}
|
|
41197
41527
|
if (count2 === 0) {
|
|
41198
41528
|
for (const line of lines) {
|
|
41199
|
-
if (/^\s*[-*+]\s/.test(line)) {
|
|
41529
|
+
if (/^\s*[-*+]\s/.test(line) || /^\s*\d+[.)]\s/.test(line)) {
|
|
41200
41530
|
count2++;
|
|
41201
41531
|
}
|
|
41202
41532
|
}
|
|
@@ -41228,29 +41558,77 @@ var init_evaluate = __esm(() => {
|
|
|
41228
41558
|
};
|
|
41229
41559
|
});
|
|
41230
41560
|
|
|
41561
|
+
// ../../packages/core/src/quality/replay.ts
|
|
41562
|
+
function scoreExact(output2, reference) {
|
|
41563
|
+
const normOut = normalize(output2);
|
|
41564
|
+
const normRef = normalize(reference);
|
|
41565
|
+
if (normOut === normRef)
|
|
41566
|
+
return 1;
|
|
41567
|
+
if (normOut.includes(normRef))
|
|
41568
|
+
return 1;
|
|
41569
|
+
return 0;
|
|
41570
|
+
}
|
|
41571
|
+
function scoreRule(output2, judge, toolsCalled) {
|
|
41572
|
+
for (const check2 of judge.checks) {
|
|
41573
|
+
if (!evaluateCheck(output2, check2.op, check2.arg, toolsCalled))
|
|
41574
|
+
return 0;
|
|
41575
|
+
}
|
|
41576
|
+
return 1;
|
|
41577
|
+
}
|
|
41578
|
+
function aggregateHard(scores) {
|
|
41579
|
+
if (scores.length === 0)
|
|
41580
|
+
return 0;
|
|
41581
|
+
const sum = scores.reduce((acc, s) => acc + s, 0);
|
|
41582
|
+
return sum / scores.length;
|
|
41583
|
+
}
|
|
41584
|
+
function normalize(text) {
|
|
41585
|
+
return text.trim().toLowerCase().replace(/\s+/g, " ");
|
|
41586
|
+
}
|
|
41587
|
+
function evaluateCheck(output2, op, arg, toolsCalled) {
|
|
41588
|
+
switch (op) {
|
|
41589
|
+
case "contains":
|
|
41590
|
+
return output2.toLowerCase().includes(arg.toLowerCase());
|
|
41591
|
+
case "regex": {
|
|
41592
|
+
try {
|
|
41593
|
+
return new RegExp(arg).test(output2);
|
|
41594
|
+
} catch {
|
|
41595
|
+
return false;
|
|
41596
|
+
}
|
|
41597
|
+
}
|
|
41598
|
+
case "equals":
|
|
41599
|
+
return normalize(output2) === normalize(arg);
|
|
41600
|
+
case "not_contains":
|
|
41601
|
+
return !output2.toLowerCase().includes(arg.toLowerCase());
|
|
41602
|
+
case "tool_called":
|
|
41603
|
+
return (toolsCalled ?? []).includes(arg);
|
|
41604
|
+
default:
|
|
41605
|
+
return false;
|
|
41606
|
+
}
|
|
41607
|
+
}
|
|
41608
|
+
|
|
41231
41609
|
// ../../packages/core/src/quality/rubric.ts
|
|
41232
|
-
import { existsSync as
|
|
41233
|
-
import { homedir as
|
|
41234
|
-
import { join as
|
|
41610
|
+
import { existsSync as existsSync11, readFileSync as readFileSync10 } from "fs";
|
|
41611
|
+
import { homedir as homedir4 } from "os";
|
|
41612
|
+
import { join as join9 } from "path";
|
|
41235
41613
|
function resolveRubricContent(type, opts) {
|
|
41236
41614
|
if (opts?.path) {
|
|
41237
|
-
if (!
|
|
41615
|
+
if (!existsSync11(opts.path)) {
|
|
41238
41616
|
throw new RubricError("path", `Rubric file not found: ${opts.path}`, opts.path);
|
|
41239
41617
|
}
|
|
41240
|
-
return
|
|
41618
|
+
return readFileSync10(opts.path, "utf-8");
|
|
41241
41619
|
}
|
|
41242
|
-
const homeDir = process.env.HOME
|
|
41243
|
-
const userPath =
|
|
41244
|
-
if (
|
|
41245
|
-
return
|
|
41620
|
+
const homeDir = process.env.HOME || homedir4();
|
|
41621
|
+
const userPath = join9(homeDir, ".superskill", "rubrics", `${type}.yaml`);
|
|
41622
|
+
if (existsSync11(userPath)) {
|
|
41623
|
+
return readFileSync10(userPath, "utf-8");
|
|
41246
41624
|
}
|
|
41247
|
-
const devPath =
|
|
41248
|
-
if (
|
|
41249
|
-
return
|
|
41625
|
+
const devPath = join9(import.meta.dir, "..", "rubrics", `${type}.yaml`);
|
|
41626
|
+
if (existsSync11(devPath)) {
|
|
41627
|
+
return readFileSync10(devPath, "utf-8");
|
|
41250
41628
|
}
|
|
41251
|
-
const prodPath =
|
|
41252
|
-
if (
|
|
41253
|
-
return
|
|
41629
|
+
const prodPath = join9(import.meta.dir, "..", "..", "rubrics", `${type}.yaml`);
|
|
41630
|
+
if (existsSync11(prodPath)) {
|
|
41631
|
+
return readFileSync10(prodPath, "utf-8");
|
|
41254
41632
|
}
|
|
41255
41633
|
throw new RubricError("path", `No rubric found for type "${type}". Searched: ${opts?.path ?? "(no explicit path)"}, ${userPath}, ${devPath}, ${prodPath}`, type);
|
|
41256
41634
|
}
|
|
@@ -47079,11 +47457,11 @@ var require_out = __commonJS((exports) => {
|
|
|
47079
47457
|
async.read(path7, getSettings(optionsOrSettingsOrCallback), callback);
|
|
47080
47458
|
}
|
|
47081
47459
|
exports.stat = stat;
|
|
47082
|
-
function
|
|
47460
|
+
function statSync6(path7, optionsOrSettings) {
|
|
47083
47461
|
const settings = getSettings(optionsOrSettings);
|
|
47084
47462
|
return sync.read(path7, settings);
|
|
47085
47463
|
}
|
|
47086
|
-
exports.statSync =
|
|
47464
|
+
exports.statSync = statSync6;
|
|
47087
47465
|
function getSettings(settingsOrOptions = {}) {
|
|
47088
47466
|
if (settingsOrOptions instanceof settings_1.default) {
|
|
47089
47467
|
return settingsOrOptions;
|
|
@@ -47487,11 +47865,11 @@ var require_reusify = __commonJS((exports, module) => {
|
|
|
47487
47865
|
// ../../node_modules/.bun/fastq@1.20.1/node_modules/fastq/queue.js
|
|
47488
47866
|
var require_queue = __commonJS((exports, module) => {
|
|
47489
47867
|
var reusify = require_reusify();
|
|
47490
|
-
function fastqueue(
|
|
47491
|
-
if (typeof
|
|
47868
|
+
function fastqueue(context3, worker, _concurrency) {
|
|
47869
|
+
if (typeof context3 === "function") {
|
|
47492
47870
|
_concurrency = worker;
|
|
47493
|
-
worker =
|
|
47494
|
-
|
|
47871
|
+
worker = context3;
|
|
47872
|
+
context3 = null;
|
|
47495
47873
|
}
|
|
47496
47874
|
if (!(_concurrency >= 1)) {
|
|
47497
47875
|
throw new Error("fastqueue concurrency must be equal to or greater than 1");
|
|
@@ -47578,7 +47956,7 @@ var require_queue = __commonJS((exports, module) => {
|
|
|
47578
47956
|
}
|
|
47579
47957
|
function push(value, done) {
|
|
47580
47958
|
var current = cache.get();
|
|
47581
|
-
current.context =
|
|
47959
|
+
current.context = context3;
|
|
47582
47960
|
current.release = release;
|
|
47583
47961
|
current.value = value;
|
|
47584
47962
|
current.callback = done || noop4;
|
|
@@ -47594,12 +47972,12 @@ var require_queue = __commonJS((exports, module) => {
|
|
|
47594
47972
|
}
|
|
47595
47973
|
} else {
|
|
47596
47974
|
_running++;
|
|
47597
|
-
worker.call(
|
|
47975
|
+
worker.call(context3, current.value, current.worked);
|
|
47598
47976
|
}
|
|
47599
47977
|
}
|
|
47600
47978
|
function unshift(value, done) {
|
|
47601
47979
|
var current = cache.get();
|
|
47602
|
-
current.context =
|
|
47980
|
+
current.context = context3;
|
|
47603
47981
|
current.release = release;
|
|
47604
47982
|
current.value = value;
|
|
47605
47983
|
current.callback = done || noop4;
|
|
@@ -47615,7 +47993,7 @@ var require_queue = __commonJS((exports, module) => {
|
|
|
47615
47993
|
}
|
|
47616
47994
|
} else {
|
|
47617
47995
|
_running++;
|
|
47618
|
-
worker.call(
|
|
47996
|
+
worker.call(context3, current.value, current.worked);
|
|
47619
47997
|
}
|
|
47620
47998
|
}
|
|
47621
47999
|
function release(holder) {
|
|
@@ -47630,7 +48008,7 @@ var require_queue = __commonJS((exports, module) => {
|
|
|
47630
48008
|
}
|
|
47631
48009
|
queueHead = next.next;
|
|
47632
48010
|
next.next = null;
|
|
47633
|
-
worker.call(
|
|
48011
|
+
worker.call(context3, next.value, next.worked);
|
|
47634
48012
|
if (queueTail === null) {
|
|
47635
48013
|
self2.empty();
|
|
47636
48014
|
}
|
|
@@ -47661,14 +48039,14 @@ var require_queue = __commonJS((exports, module) => {
|
|
|
47661
48039
|
var callback = current.callback;
|
|
47662
48040
|
var errorHandler2 = current.errorHandler;
|
|
47663
48041
|
var val = current.value;
|
|
47664
|
-
var
|
|
48042
|
+
var context4 = current.context;
|
|
47665
48043
|
current.value = null;
|
|
47666
48044
|
current.callback = noop4;
|
|
47667
48045
|
current.errorHandler = null;
|
|
47668
48046
|
if (errorHandler2) {
|
|
47669
48047
|
errorHandler2(new Error("abort"), val);
|
|
47670
48048
|
}
|
|
47671
|
-
callback.call(
|
|
48049
|
+
callback.call(context4, new Error("abort"));
|
|
47672
48050
|
current.release(current);
|
|
47673
48051
|
current = next;
|
|
47674
48052
|
}
|
|
@@ -47700,18 +48078,18 @@ var require_queue = __commonJS((exports, module) => {
|
|
|
47700
48078
|
self2.release(self2);
|
|
47701
48079
|
};
|
|
47702
48080
|
}
|
|
47703
|
-
function queueAsPromised(
|
|
47704
|
-
if (typeof
|
|
48081
|
+
function queueAsPromised(context3, worker, _concurrency) {
|
|
48082
|
+
if (typeof context3 === "function") {
|
|
47705
48083
|
_concurrency = worker;
|
|
47706
|
-
worker =
|
|
47707
|
-
|
|
48084
|
+
worker = context3;
|
|
48085
|
+
context3 = null;
|
|
47708
48086
|
}
|
|
47709
48087
|
function asyncWrapper(arg, cb) {
|
|
47710
48088
|
worker.call(this, arg).then(function(res) {
|
|
47711
48089
|
cb(null, res);
|
|
47712
48090
|
}, cb);
|
|
47713
48091
|
}
|
|
47714
|
-
var queue = fastqueue(
|
|
48092
|
+
var queue = fastqueue(context3, asyncWrapper, _concurrency);
|
|
47715
48093
|
var pushCb = queue.push;
|
|
47716
48094
|
var unshiftCb = queue.unshift;
|
|
47717
48095
|
queue.push = push;
|
|
@@ -47719,42 +48097,42 @@ var require_queue = __commonJS((exports, module) => {
|
|
|
47719
48097
|
queue.drained = drained;
|
|
47720
48098
|
return queue;
|
|
47721
48099
|
function push(value) {
|
|
47722
|
-
var p = new Promise(function(
|
|
48100
|
+
var p = new Promise(function(resolve3, reject) {
|
|
47723
48101
|
pushCb(value, function(err, result) {
|
|
47724
48102
|
if (err) {
|
|
47725
48103
|
reject(err);
|
|
47726
48104
|
return;
|
|
47727
48105
|
}
|
|
47728
|
-
|
|
48106
|
+
resolve3(result);
|
|
47729
48107
|
});
|
|
47730
48108
|
});
|
|
47731
48109
|
p.catch(noop4);
|
|
47732
48110
|
return p;
|
|
47733
48111
|
}
|
|
47734
48112
|
function unshift(value) {
|
|
47735
|
-
var p = new Promise(function(
|
|
48113
|
+
var p = new Promise(function(resolve3, reject) {
|
|
47736
48114
|
unshiftCb(value, function(err, result) {
|
|
47737
48115
|
if (err) {
|
|
47738
48116
|
reject(err);
|
|
47739
48117
|
return;
|
|
47740
48118
|
}
|
|
47741
|
-
|
|
48119
|
+
resolve3(result);
|
|
47742
48120
|
});
|
|
47743
48121
|
});
|
|
47744
48122
|
p.catch(noop4);
|
|
47745
48123
|
return p;
|
|
47746
48124
|
}
|
|
47747
48125
|
function drained() {
|
|
47748
|
-
var p = new Promise(function(
|
|
48126
|
+
var p = new Promise(function(resolve3) {
|
|
47749
48127
|
process.nextTick(function() {
|
|
47750
48128
|
if (queue.idle()) {
|
|
47751
|
-
|
|
48129
|
+
resolve3();
|
|
47752
48130
|
} else {
|
|
47753
48131
|
var previousDrain = queue.drain;
|
|
47754
48132
|
queue.drain = function() {
|
|
47755
48133
|
if (typeof previousDrain === "function")
|
|
47756
48134
|
previousDrain();
|
|
47757
|
-
|
|
48135
|
+
resolve3();
|
|
47758
48136
|
queue.drain = previousDrain;
|
|
47759
48137
|
};
|
|
47760
48138
|
}
|
|
@@ -48215,9 +48593,9 @@ var require_stream3 = __commonJS((exports) => {
|
|
|
48215
48593
|
});
|
|
48216
48594
|
}
|
|
48217
48595
|
_getStat(filepath) {
|
|
48218
|
-
return new Promise((
|
|
48596
|
+
return new Promise((resolve3, reject) => {
|
|
48219
48597
|
this._stat(filepath, this._fsStatSettings, (error51, stats) => {
|
|
48220
|
-
return error51 === null ?
|
|
48598
|
+
return error51 === null ? resolve3(stats) : reject(error51);
|
|
48221
48599
|
});
|
|
48222
48600
|
});
|
|
48223
48601
|
}
|
|
@@ -48239,10 +48617,10 @@ var require_async5 = __commonJS((exports) => {
|
|
|
48239
48617
|
this._readerStream = new stream_1.default(this._settings);
|
|
48240
48618
|
}
|
|
48241
48619
|
dynamic(root, options2) {
|
|
48242
|
-
return new Promise((
|
|
48620
|
+
return new Promise((resolve3, reject) => {
|
|
48243
48621
|
this._walkAsync(root, options2, (error51, entries) => {
|
|
48244
48622
|
if (error51 === null) {
|
|
48245
|
-
|
|
48623
|
+
resolve3(entries);
|
|
48246
48624
|
} else {
|
|
48247
48625
|
reject(error51);
|
|
48248
48626
|
}
|
|
@@ -48252,10 +48630,10 @@ var require_async5 = __commonJS((exports) => {
|
|
|
48252
48630
|
async static(patterns, options2) {
|
|
48253
48631
|
const entries = [];
|
|
48254
48632
|
const stream = this._readerStream.static(patterns, options2);
|
|
48255
|
-
return new Promise((
|
|
48633
|
+
return new Promise((resolve3, reject) => {
|
|
48256
48634
|
stream.once("error", reject);
|
|
48257
48635
|
stream.on("data", (entry) => entries.push(entry));
|
|
48258
|
-
stream.once("end", () =>
|
|
48636
|
+
stream.once("end", () => resolve3(entries));
|
|
48259
48637
|
});
|
|
48260
48638
|
}
|
|
48261
48639
|
}
|
|
@@ -49783,7 +50161,7 @@ var import_fast_glob2, import_ignore, defaultIgnoredDirectories, ignoreFilesGlob
|
|
|
49783
50161
|
}
|
|
49784
50162
|
throw createGitConfigReadError(normalizedPath, error51);
|
|
49785
50163
|
}
|
|
49786
|
-
}, getExcludesFileFromGitConfigSync = (filePath,
|
|
50164
|
+
}, getExcludesFileFromGitConfigSync = (filePath, readFileSync11, gitDirectory, options2 = {}) => {
|
|
49787
50165
|
const { suppressErrors, includeStack = new Set, depth = 0 } = options2;
|
|
49788
50166
|
const normalizedPath = path9.resolve(filePath);
|
|
49789
50167
|
if (includeStack.has(normalizedPath)) {
|
|
@@ -49793,14 +50171,14 @@ var import_fast_glob2, import_ignore, defaultIgnoredDirectories, ignoreFilesGlob
|
|
|
49793
50171
|
return;
|
|
49794
50172
|
}
|
|
49795
50173
|
includeStack.add(normalizedPath);
|
|
49796
|
-
const content = readGitConfigFile(normalizedPath,
|
|
50174
|
+
const content = readGitConfigFile(normalizedPath, readFileSync11, suppressErrors);
|
|
49797
50175
|
if (content === undefined) {
|
|
49798
50176
|
includeStack.delete(normalizedPath);
|
|
49799
50177
|
return;
|
|
49800
50178
|
}
|
|
49801
50179
|
let { excludesFile, includePaths } = parseGitConfigForExcludesFile(content, normalizedPath, gitDirectory);
|
|
49802
50180
|
for (const includePath of includePaths) {
|
|
49803
|
-
const includedExcludesFile = getExcludesFileFromGitConfigSync(includePath,
|
|
50181
|
+
const includedExcludesFile = getExcludesFileFromGitConfigSync(includePath, readFileSync11, gitDirectory, { suppressErrors, includeStack, depth: depth + 1 });
|
|
49804
50182
|
if (includedExcludesFile !== undefined) {
|
|
49805
50183
|
excludesFile = includedExcludesFile;
|
|
49806
50184
|
}
|
|
@@ -49842,13 +50220,13 @@ var import_fast_glob2, import_ignore, defaultIgnoredDirectories, ignoreFilesGlob
|
|
|
49842
50220
|
return gitFilePath;
|
|
49843
50221
|
}
|
|
49844
50222
|
return path9.resolve(path9.dirname(gitFilePath), match[1]);
|
|
49845
|
-
}, getGitDirectorySync = (gitRoot,
|
|
50223
|
+
}, getGitDirectorySync = (gitRoot, readFileSync11) => {
|
|
49846
50224
|
if (!gitRoot) {
|
|
49847
50225
|
return;
|
|
49848
50226
|
}
|
|
49849
50227
|
const gitFilePath = path9.join(gitRoot, ".git");
|
|
49850
50228
|
try {
|
|
49851
|
-
return resolveGitDirectoryFromFile(gitFilePath,
|
|
50229
|
+
return resolveGitDirectoryFromFile(gitFilePath, readFileSync11(gitFilePath, "utf8"));
|
|
49852
50230
|
} catch {
|
|
49853
50231
|
return gitFilePath;
|
|
49854
50232
|
}
|
|
@@ -49891,18 +50269,18 @@ var import_fast_glob2, import_ignore, defaultIgnoredDirectories, ignoreFilesGlob
|
|
|
49891
50269
|
}
|
|
49892
50270
|
}, getGlobalGitignoreFile = (options2 = {}) => {
|
|
49893
50271
|
const cwd5 = toPath2(options2.cwd) ?? process11.cwd();
|
|
49894
|
-
const
|
|
50272
|
+
const readFileSync11 = getReadFileSyncMethod(options2.fs);
|
|
49895
50273
|
const gitRoot = findGitRootSync(cwd5, options2.fs);
|
|
49896
|
-
const gitDirectory = getGitDirectorySync(gitRoot,
|
|
50274
|
+
const gitDirectory = getGitDirectorySync(gitRoot, readFileSync11);
|
|
49897
50275
|
let excludesFileConfig;
|
|
49898
50276
|
for (const gitConfigPath of getGitConfigPaths()) {
|
|
49899
|
-
const value = getExcludesFileFromGitConfigSync(gitConfigPath,
|
|
50277
|
+
const value = getExcludesFileFromGitConfigSync(gitConfigPath, readFileSync11, gitDirectory, { suppressErrors: options2.suppressErrors });
|
|
49900
50278
|
if (value !== undefined) {
|
|
49901
50279
|
excludesFileConfig = value;
|
|
49902
50280
|
}
|
|
49903
50281
|
}
|
|
49904
50282
|
const filePath = resolveExcludesFilePath(excludesFileConfig);
|
|
49905
|
-
return filePath === undefined ? undefined : readGlobalGitignoreContent(filePath,
|
|
50283
|
+
return filePath === undefined ? undefined : readGlobalGitignoreContent(filePath, readFileSync11, options2.suppressErrors);
|
|
49906
50284
|
}, getGlobalGitignoreFileAsync = async (options2 = {}) => {
|
|
49907
50285
|
const cwd5 = toPath2(options2.cwd) ?? process11.cwd();
|
|
49908
50286
|
const readFile = getReadFileMethod(options2.fs);
|
|
@@ -58242,7 +58620,7 @@ import {
|
|
|
58242
58620
|
writeFile
|
|
58243
58621
|
} from "fs/promises";
|
|
58244
58622
|
import os2 from "os";
|
|
58245
|
-
import { dirname as dirname6, isAbsolute, join as join22, relative, resolve as
|
|
58623
|
+
import { dirname as dirname6, isAbsolute, join as join22, relative, resolve as resolve4 } from "path";
|
|
58246
58624
|
import { isAbsolute as isAbsolute2, resolve as resolve22 } from "path";
|
|
58247
58625
|
import { basename as basename3, join as join44, relative as relative3 } from "path";
|
|
58248
58626
|
import { extname as extname2 } from "path";
|
|
@@ -58250,8 +58628,8 @@ import { isDeepStrictEqual } from "util";
|
|
|
58250
58628
|
import { join as join62 } from "path";
|
|
58251
58629
|
import { join as join42 } from "path";
|
|
58252
58630
|
import { join as join52 } from "path";
|
|
58253
|
-
import path10, { relative as relative2, resolve as
|
|
58254
|
-
import { basename as basename4, join as
|
|
58631
|
+
import path10, { relative as relative2, resolve as resolve42 } from "path";
|
|
58632
|
+
import { basename as basename4, join as join92 } from "path";
|
|
58255
58633
|
import { join as join72 } from "path";
|
|
58256
58634
|
import { join as join82 } from "path";
|
|
58257
58635
|
import { join as join10 } from "path";
|
|
@@ -58335,7 +58713,7 @@ import { join as join88 } from "path";
|
|
|
58335
58713
|
import { join as join89 } from "path";
|
|
58336
58714
|
import { join as join90 } from "path";
|
|
58337
58715
|
import { join as join91 } from "path";
|
|
58338
|
-
import { join as
|
|
58716
|
+
import { join as join922 } from "path";
|
|
58339
58717
|
import { join as join93 } from "path";
|
|
58340
58718
|
import { join as join94 } from "path";
|
|
58341
58719
|
import { join as join95 } from "path";
|
|
@@ -58510,9 +58888,9 @@ function checkPathTraversal({
|
|
|
58510
58888
|
if (segments.includes("..")) {
|
|
58511
58889
|
throw new Error(`Path traversal detected: ${relativePath}`);
|
|
58512
58890
|
}
|
|
58513
|
-
const resolved =
|
|
58891
|
+
const resolved = resolve4(intendedRootDir, relativePath);
|
|
58514
58892
|
const rel = relative(intendedRootDir, resolved);
|
|
58515
|
-
if (rel.startsWith("..") ||
|
|
58893
|
+
if (rel.startsWith("..") || resolve4(resolved) !== resolved) {
|
|
58516
58894
|
throw new Error(`Path traversal detected: ${relativePath}`);
|
|
58517
58895
|
}
|
|
58518
58896
|
}
|
|
@@ -58520,7 +58898,7 @@ function resolvePath3(relativePath, outputRoot) {
|
|
|
58520
58898
|
if (!outputRoot)
|
|
58521
58899
|
return relativePath;
|
|
58522
58900
|
checkPathTraversal({ relativePath, intendedRootDir: outputRoot });
|
|
58523
|
-
return
|
|
58901
|
+
return resolve4(outputRoot, relativePath);
|
|
58524
58902
|
}
|
|
58525
58903
|
async function directoryExists(dirPath) {
|
|
58526
58904
|
try {
|
|
@@ -58633,7 +59011,7 @@ function validateOutputRoot(outputRoot) {
|
|
|
58633
59011
|
if (segments.includes("..")) {
|
|
58634
59012
|
throw new Error(`Path traversal detected: ${outputRoot}`);
|
|
58635
59013
|
}
|
|
58636
|
-
const normalized =
|
|
59014
|
+
const normalized = resolve4(outputRoot);
|
|
58637
59015
|
if (normalized !== outputRoot) {
|
|
58638
59016
|
throw new Error(`outputRoot must be a normalized absolute path: ${outputRoot} (normalized: ${normalized})`);
|
|
58639
59017
|
}
|
|
@@ -63025,8 +63403,8 @@ var import_gray_matter, BaseLogger = class {
|
|
|
63025
63403
|
}
|
|
63026
63404
|
getFilePath() {
|
|
63027
63405
|
const fullPath = path10.join(this.outputRoot, this.relativeDirPath, this.relativeFilePath);
|
|
63028
|
-
const resolvedFull =
|
|
63029
|
-
const resolvedBase =
|
|
63406
|
+
const resolvedFull = resolve42(fullPath);
|
|
63407
|
+
const resolvedBase = resolve42(this.outputRoot);
|
|
63030
63408
|
const rel = relative2(resolvedBase, resolvedFull);
|
|
63031
63409
|
if (rel.startsWith("..") || path10.isAbsolute(rel)) {
|
|
63032
63410
|
throw new Error(`Path traversal detected: Final path escapes outputRoot. outputRoot="${this.outputRoot}", relativeDirPath="${this.relativeDirPath}", relativeFilePath="${this.relativeFilePath}"`);
|
|
@@ -63958,7 +64336,7 @@ var init_chunk_QKQNZ6C3 = __esm(() => {
|
|
|
63958
64336
|
if (rest2.validate) {
|
|
63959
64337
|
const result = AntigravityCommandFrontmatterSchema.safeParse(frontmatter);
|
|
63960
64338
|
if (!result.success) {
|
|
63961
|
-
throw new Error(`Invalid frontmatter in ${
|
|
64339
|
+
throw new Error(`Invalid frontmatter in ${join92(rest2.relativeDirPath, rest2.relativeFilePath)}: ${formatError2(result.error)}`);
|
|
63962
64340
|
}
|
|
63963
64341
|
}
|
|
63964
64342
|
super({
|
|
@@ -64054,7 +64432,7 @@ ${body}${turboDirective}`;
|
|
|
64054
64432
|
} else {
|
|
64055
64433
|
return {
|
|
64056
64434
|
success: false,
|
|
64057
|
-
error: new Error(`Invalid frontmatter in ${
|
|
64435
|
+
error: new Error(`Invalid frontmatter in ${join92(this.relativeDirPath, this.relativeFilePath)}: ${formatError2(result.error)}`)
|
|
64058
64436
|
};
|
|
64059
64437
|
}
|
|
64060
64438
|
}
|
|
@@ -64069,7 +64447,7 @@ ${body}${turboDirective}`;
|
|
|
64069
64447
|
relativeFilePath,
|
|
64070
64448
|
validate: validate2 = true
|
|
64071
64449
|
}) {
|
|
64072
|
-
const filePath =
|
|
64450
|
+
const filePath = join92(outputRoot, _AntigravityCommand.getSettablePaths().relativeDirPath, relativeFilePath);
|
|
64073
64451
|
const fileContent = await readFileContent(filePath);
|
|
64074
64452
|
const { frontmatter, body: content } = parseFrontmatter2(fileContent, filePath);
|
|
64075
64453
|
const result = AntigravityCommandFrontmatterSchema.safeParse(frontmatter);
|
|
@@ -71258,7 +71636,7 @@ prompt = ""`;
|
|
|
71258
71636
|
try {
|
|
71259
71637
|
this.json = JSON.parse(this.fileContent);
|
|
71260
71638
|
} catch (error51) {
|
|
71261
|
-
throw new Error(`Failed to parse Cursor MCP config at ${
|
|
71639
|
+
throw new Error(`Failed to parse Cursor MCP config at ${join922(this.relativeDirPath, this.relativeFilePath)}: ${formatError2(error51)}`, { cause: error51 });
|
|
71262
71640
|
}
|
|
71263
71641
|
} else {
|
|
71264
71642
|
this.json = {};
|
|
@@ -71282,13 +71660,13 @@ prompt = ""`;
|
|
|
71282
71660
|
global: global3 = false
|
|
71283
71661
|
}) {
|
|
71284
71662
|
const paths = this.getSettablePaths({ global: global3 });
|
|
71285
|
-
const filePath =
|
|
71663
|
+
const filePath = join922(outputRoot, paths.relativeDirPath, paths.relativeFilePath);
|
|
71286
71664
|
const fileContent = await readFileContentOrNull(filePath) ?? '{"mcpServers":{}}';
|
|
71287
71665
|
let json3;
|
|
71288
71666
|
try {
|
|
71289
71667
|
json3 = JSON.parse(fileContent);
|
|
71290
71668
|
} catch (error51) {
|
|
71291
|
-
throw new Error(`Failed to parse Cursor MCP config at ${
|
|
71669
|
+
throw new Error(`Failed to parse Cursor MCP config at ${join922(paths.relativeDirPath, paths.relativeFilePath)}: ${formatError2(error51)}`, { cause: error51 });
|
|
71292
71670
|
}
|
|
71293
71671
|
const newJson = { ...json3, mcpServers: json3.mcpServers ?? {} };
|
|
71294
71672
|
return new _CursorMcp({
|
|
@@ -71307,12 +71685,12 @@ prompt = ""`;
|
|
|
71307
71685
|
global: global3 = false
|
|
71308
71686
|
}) {
|
|
71309
71687
|
const paths = this.getSettablePaths({ global: global3 });
|
|
71310
|
-
const fileContent = await readOrInitializeFileContent(
|
|
71688
|
+
const fileContent = await readOrInitializeFileContent(join922(outputRoot, paths.relativeDirPath, paths.relativeFilePath), JSON.stringify({ mcpServers: {} }, null, 2));
|
|
71311
71689
|
let json3;
|
|
71312
71690
|
try {
|
|
71313
71691
|
json3 = JSON.parse(fileContent);
|
|
71314
71692
|
} catch (error51) {
|
|
71315
|
-
throw new Error(`Failed to parse Cursor MCP config at ${
|
|
71693
|
+
throw new Error(`Failed to parse Cursor MCP config at ${join922(paths.relativeDirPath, paths.relativeFilePath)}: ${formatError2(error51)}`, { cause: error51 });
|
|
71316
71694
|
}
|
|
71317
71695
|
const mcpServers = rulesyncMcp.getMcpServers();
|
|
71318
71696
|
const transformedServers = convertEnvVarRefsToToolFormat({
|
|
@@ -89292,11 +89670,12 @@ var init_dist9 = __esm(() => {
|
|
|
89292
89670
|
});
|
|
89293
89671
|
|
|
89294
89672
|
// ../../packages/core/src/rulesync.ts
|
|
89295
|
-
import { homedir as
|
|
89673
|
+
import { homedir as homedir5 } from "os";
|
|
89296
89674
|
async function runRulesync(targets, features, inputRoot, options2) {
|
|
89675
|
+
const targetMap = options2.targetMap ?? TARGET_TO_RULESYNC;
|
|
89297
89676
|
const mappedTargets = [];
|
|
89298
89677
|
for (const target of targets) {
|
|
89299
|
-
const rt =
|
|
89678
|
+
const rt = targetMap[target];
|
|
89300
89679
|
if (rt)
|
|
89301
89680
|
mappedTargets.push(rt);
|
|
89302
89681
|
}
|
|
@@ -89322,7 +89701,7 @@ async function runRulesync(targets, features, inputRoot, options2) {
|
|
|
89322
89701
|
hasDiff: false
|
|
89323
89702
|
};
|
|
89324
89703
|
}
|
|
89325
|
-
const root = options2.outputRoot ?? (options2.global ?
|
|
89704
|
+
const root = options2.outputRoot ?? (options2.global ? homedir5() : process.cwd());
|
|
89326
89705
|
const rulesyncGlobal = options2.outputRoot ? false : options2.global;
|
|
89327
89706
|
return generate2({
|
|
89328
89707
|
targets: mappedTargets,
|
|
@@ -89361,6 +89740,7 @@ var init_src = __esm(() => {
|
|
|
89361
89740
|
init_slash_command2();
|
|
89362
89741
|
init_agent();
|
|
89363
89742
|
init_command3();
|
|
89743
|
+
init_eval_cases();
|
|
89364
89744
|
init_evaluate();
|
|
89365
89745
|
init_heuristics();
|
|
89366
89746
|
init_hook();
|
|
@@ -89740,7 +90120,7 @@ var init_version = () => {};
|
|
|
89740
90120
|
|
|
89741
90121
|
// ../../node_modules/.bun/drizzle-orm@0.44.7+a0473b45aab9bf33/node_modules/drizzle-orm/tracing.js
|
|
89742
90122
|
var otel, rawTracer, tracer;
|
|
89743
|
-
var
|
|
90123
|
+
var init_tracing2 = __esm(() => {
|
|
89744
90124
|
init_tracing_utils();
|
|
89745
90125
|
init_version();
|
|
89746
90126
|
tracer = {
|
|
@@ -89830,7 +90210,7 @@ var init_sql = __esm(() => {
|
|
|
89830
90210
|
init_entity();
|
|
89831
90211
|
init_enum();
|
|
89832
90212
|
init_subquery();
|
|
89833
|
-
|
|
90213
|
+
init_tracing2();
|
|
89834
90214
|
init_view_common();
|
|
89835
90215
|
init_column();
|
|
89836
90216
|
init_table();
|
|
@@ -94967,13 +95347,13 @@ __export(exports_db, {
|
|
|
94967
95347
|
openStore: () => openStore,
|
|
94968
95348
|
getDBPath: () => getDBPath
|
|
94969
95349
|
});
|
|
94970
|
-
import { existsSync as
|
|
95350
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync6 } from "fs";
|
|
94971
95351
|
import { dirname as dirname7 } from "path";
|
|
94972
95352
|
async function openStore(opts) {
|
|
94973
95353
|
const url3 = getDBPath(opts);
|
|
94974
95354
|
if (url3 !== ":memory:") {
|
|
94975
95355
|
const dir = dirname7(url3);
|
|
94976
|
-
if (!
|
|
95356
|
+
if (!existsSync12(dir)) {
|
|
94977
95357
|
mkdirSync6(dir, { recursive: true });
|
|
94978
95358
|
}
|
|
94979
95359
|
}
|
|
@@ -95000,7 +95380,7 @@ var init_db2 = __esm(() => {
|
|
|
95000
95380
|
});
|
|
95001
95381
|
|
|
95002
95382
|
// src/cli.ts
|
|
95003
|
-
import { readFileSync as
|
|
95383
|
+
import { readFileSync as readFileSync16 } from "fs";
|
|
95004
95384
|
import { join as join226 } from "path";
|
|
95005
95385
|
|
|
95006
95386
|
// ../../node_modules/.bun/commander@14.0.3/node_modules/commander/esm.mjs
|
|
@@ -95026,7 +95406,7 @@ init_dist();
|
|
|
95026
95406
|
init_src();
|
|
95027
95407
|
init_dist();
|
|
95028
95408
|
init_db2();
|
|
95029
|
-
import { readFileSync as
|
|
95409
|
+
import { readFileSync as readFileSync11 } from "fs";
|
|
95030
95410
|
|
|
95031
95411
|
// src/store/evaluations.ts
|
|
95032
95412
|
init_dist10();
|
|
@@ -95222,7 +95602,7 @@ async function ingestScores(type, resolvedPath, resolvedTarget, opts) {
|
|
|
95222
95602
|
}
|
|
95223
95603
|
let raw;
|
|
95224
95604
|
try {
|
|
95225
|
-
raw =
|
|
95605
|
+
raw = readFileSync11(ingestPath, "utf-8");
|
|
95226
95606
|
} catch {
|
|
95227
95607
|
throw Object.assign(new Error(`Cannot read scores file: ${ingestPath}`), { code: 2 });
|
|
95228
95608
|
}
|
|
@@ -95342,7 +95722,7 @@ function formatEvaluationReport(report, json3) {
|
|
|
95342
95722
|
// src/operations/evolve.ts
|
|
95343
95723
|
init_src();
|
|
95344
95724
|
init_dist();
|
|
95345
|
-
import { existsSync as
|
|
95725
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync7, readFileSync as readFileSync12, rmSync as rmSync5, writeFileSync as writeFileSync6 } from "fs";
|
|
95346
95726
|
import { join as join220 } from "path";
|
|
95347
95727
|
import { createInterface } from "readline";
|
|
95348
95728
|
|
|
@@ -95410,6 +95790,149 @@ function deserializeProposal(row) {
|
|
|
95410
95790
|
};
|
|
95411
95791
|
}
|
|
95412
95792
|
|
|
95793
|
+
// src/operations/pairwise-judge.ts
|
|
95794
|
+
init_src();
|
|
95795
|
+
init_dist5();
|
|
95796
|
+
class TsAiRunnerJudgeBackend {
|
|
95797
|
+
runner;
|
|
95798
|
+
agent;
|
|
95799
|
+
constructor(agent2 = "claude", runner) {
|
|
95800
|
+
this.runner = runner ?? new AiRunner;
|
|
95801
|
+
this.agent = agent2;
|
|
95802
|
+
}
|
|
95803
|
+
async judge(rubric2, prompt, candOutput, baseOutput, options2) {
|
|
95804
|
+
const candidateFirst = options2?.order !== "baseline-first";
|
|
95805
|
+
const outputA = candidateFirst ? candOutput : baseOutput;
|
|
95806
|
+
const outputB = candidateFirst ? baseOutput : candOutput;
|
|
95807
|
+
const systemPrompt = [
|
|
95808
|
+
"You are a strict pairwise behavior judge.",
|
|
95809
|
+
"Compare two outputs for the same task against the rubric criterion.",
|
|
95810
|
+
'Return only JSON: {"winner":"A"|"B"|"tie","margin":number}.',
|
|
95811
|
+
"The margin must be a number from 0 to 1."
|
|
95812
|
+
].join(`
|
|
95813
|
+
`);
|
|
95814
|
+
const input = [
|
|
95815
|
+
`Criterion: ${rubric2.criterion}`,
|
|
95816
|
+
rubric2.excellent ? `Excellent anchor: ${rubric2.excellent}` : "",
|
|
95817
|
+
rubric2.poor ? `Poor anchor: ${rubric2.poor}` : "",
|
|
95818
|
+
`Task prompt:
|
|
95819
|
+
${prompt}`,
|
|
95820
|
+
`Output A:
|
|
95821
|
+
${outputA}`,
|
|
95822
|
+
`Output B:
|
|
95823
|
+
${outputB}`
|
|
95824
|
+
].filter(Boolean).join(`
|
|
95825
|
+
|
|
95826
|
+
`);
|
|
95827
|
+
const result = await this.runner.runPromptCommand(this.agent, {
|
|
95828
|
+
input,
|
|
95829
|
+
systemPrompt,
|
|
95830
|
+
...options2?.seed !== undefined ? { seed: options2.seed } : {},
|
|
95831
|
+
...options2?.temperature !== undefined ? { temperature: options2.temperature } : {}
|
|
95832
|
+
});
|
|
95833
|
+
return parseJudgeResponse(result.stdout, candidateFirst);
|
|
95834
|
+
}
|
|
95835
|
+
}
|
|
95836
|
+
function createJudgeBackend(target, injected) {
|
|
95837
|
+
return injected ?? new TsAiRunnerJudgeBackend(TARGET_TO_AGENT_NAME[target]);
|
|
95838
|
+
}
|
|
95839
|
+
async function pairwiseJudge(backend, rubric2, casePrompt, candOutput, baseOutput, options2 = {}) {
|
|
95840
|
+
const order = options2.order ?? (options2.seed !== undefined && options2.seed % 2 === 1 ? "baseline-first" : "candidate-first");
|
|
95841
|
+
return backend.judge(rubric2, casePrompt, candOutput, baseOutput, { ...options2, order });
|
|
95842
|
+
}
|
|
95843
|
+
function signedMargin(verdict) {
|
|
95844
|
+
if (verdict.winner === "candidate")
|
|
95845
|
+
return verdict.margin;
|
|
95846
|
+
if (verdict.winner === "baseline")
|
|
95847
|
+
return -verdict.margin;
|
|
95848
|
+
return 0;
|
|
95849
|
+
}
|
|
95850
|
+
function parseJudgeResponse(stdout, candidateFirst) {
|
|
95851
|
+
let parsed;
|
|
95852
|
+
try {
|
|
95853
|
+
parsed = JSON.parse(stdout.trim());
|
|
95854
|
+
} catch {
|
|
95855
|
+
throw new Error(`Pairwise judge returned invalid JSON: ${stdout.slice(0, 200)}`);
|
|
95856
|
+
}
|
|
95857
|
+
if (typeof parsed !== "object" || parsed === null) {
|
|
95858
|
+
throw new Error("Pairwise judge returned a non-object JSON payload.");
|
|
95859
|
+
}
|
|
95860
|
+
const value = parsed;
|
|
95861
|
+
if (value.winner !== "A" && value.winner !== "B" && value.winner !== "tie") {
|
|
95862
|
+
throw new Error('Pairwise judge JSON must include winner "A", "B", or "tie".');
|
|
95863
|
+
}
|
|
95864
|
+
if (typeof value.margin !== "number" || value.margin < 0 || value.margin > 1) {
|
|
95865
|
+
throw new Error("Pairwise judge JSON must include margin in [0,1].");
|
|
95866
|
+
}
|
|
95867
|
+
if (value.winner === "tie")
|
|
95868
|
+
return { winner: "tie", margin: 0 };
|
|
95869
|
+
if (value.winner === "A") {
|
|
95870
|
+
return { winner: candidateFirst ? "candidate" : "baseline", margin: value.margin };
|
|
95871
|
+
}
|
|
95872
|
+
return { winner: candidateFirst ? "baseline" : "candidate", margin: value.margin };
|
|
95873
|
+
}
|
|
95874
|
+
|
|
95875
|
+
// src/operations/noise-floor.ts
|
|
95876
|
+
async function estimateNoiseFloor(judge, rubric2, casePrompt, candOutput, baseOutput, n2 = 5) {
|
|
95877
|
+
const margins = [];
|
|
95878
|
+
for (let i2 = 0;i2 < n2; i2++) {
|
|
95879
|
+
const verdict = await pairwiseJudge(judge, rubric2, casePrompt, candOutput, baseOutput, {
|
|
95880
|
+
seed: i2 + 1,
|
|
95881
|
+
temperature: 0
|
|
95882
|
+
});
|
|
95883
|
+
margins.push(signedMargin(verdict));
|
|
95884
|
+
}
|
|
95885
|
+
if (margins.length < 2)
|
|
95886
|
+
return 0;
|
|
95887
|
+
const mean2 = margins.reduce((a2, b) => a2 + b, 0) / margins.length;
|
|
95888
|
+
const variance = margins.reduce((sum2, m) => sum2 + (m - mean2) ** 2, 0) / margins.length;
|
|
95889
|
+
return Math.sqrt(variance);
|
|
95890
|
+
}
|
|
95891
|
+
function rejectsWithinNoise(measuredDelta, noiseFloor) {
|
|
95892
|
+
return Math.abs(measuredDelta) < noiseFloor;
|
|
95893
|
+
}
|
|
95894
|
+
|
|
95895
|
+
// src/operations/replay-runner.ts
|
|
95896
|
+
init_src();
|
|
95897
|
+
init_dist5();
|
|
95898
|
+
class TsAiRunnerBackend {
|
|
95899
|
+
runner;
|
|
95900
|
+
agent;
|
|
95901
|
+
constructor(agent2 = "claude", runner) {
|
|
95902
|
+
this.runner = runner ?? new AiRunner;
|
|
95903
|
+
this.agent = agent2;
|
|
95904
|
+
}
|
|
95905
|
+
async run(systemPrompt, userPrompt) {
|
|
95906
|
+
const result = await this.runner.runPromptCommand(this.agent, {
|
|
95907
|
+
input: userPrompt,
|
|
95908
|
+
systemPrompt
|
|
95909
|
+
});
|
|
95910
|
+
return result.stdout;
|
|
95911
|
+
}
|
|
95912
|
+
}
|
|
95913
|
+
function createReplayBackend(target, injected) {
|
|
95914
|
+
return injected ?? new TsAiRunnerBackend(TARGET_TO_AGENT_NAME[target]);
|
|
95915
|
+
}
|
|
95916
|
+
async function replayCase(backend, skill2, ev, toolsCalled) {
|
|
95917
|
+
const prompt = `[case:${ev.id}] ${ev.prompt}`;
|
|
95918
|
+
const output2 = await backend.run(skill2, prompt);
|
|
95919
|
+
let hard;
|
|
95920
|
+
if (ev.reference_kind === "exact") {
|
|
95921
|
+
hard = scoreExact(output2, ev.reference);
|
|
95922
|
+
} else {
|
|
95923
|
+
hard = scoreRule(output2, ev.reference, toolsCalled);
|
|
95924
|
+
}
|
|
95925
|
+
return { hard, output: output2 };
|
|
95926
|
+
}
|
|
95927
|
+
async function replaySplit(backend, skill2, cases, split, toolsCalled) {
|
|
95928
|
+
const splitCases = cases.filter((c3) => c3.split === split);
|
|
95929
|
+
if (splitCases.length === 0)
|
|
95930
|
+
return { hard: 0, n: 0 };
|
|
95931
|
+
const results = await Promise.all(splitCases.map((c3) => replayCase(backend, skill2, c3, toolsCalled)));
|
|
95932
|
+
const scores = results.map((r) => r.hard);
|
|
95933
|
+
return { hard: aggregateHard(scores), n: splitCases.length };
|
|
95934
|
+
}
|
|
95935
|
+
|
|
95413
95936
|
// src/operations/validate.ts
|
|
95414
95937
|
init_src();
|
|
95415
95938
|
|
|
@@ -95591,6 +96114,106 @@ async function runGate(input) {
|
|
|
95591
96114
|
reason: `\u0394-margin gate failed: \u0394${delta >= 0 ? "+" : ""}${delta.toFixed(2)} < required margin ${input.margin.toFixed(2)}.`
|
|
95592
96115
|
};
|
|
95593
96116
|
}
|
|
96117
|
+
let empiricalScores;
|
|
96118
|
+
if (input.evalGate) {
|
|
96119
|
+
const cases = loadEvalCases(input.evalGate.name);
|
|
96120
|
+
if (cases) {
|
|
96121
|
+
const holdout = cases.cases.filter((c3) => c3.split === "holdout");
|
|
96122
|
+
const rubricCases = holdout.filter((c3) => c3.reference_kind === "rubric");
|
|
96123
|
+
const detCases = holdout.filter((c3) => c3.reference_kind !== "rubric");
|
|
96124
|
+
const maxModelCalls = input.evalGate.judgeBudget?.maxModelCalls ?? Number.POSITIVE_INFINITY;
|
|
96125
|
+
let modelCalls = 0;
|
|
96126
|
+
const consumeModelCalls = (count3, reason) => {
|
|
96127
|
+
modelCalls += count3;
|
|
96128
|
+
if (modelCalls > maxModelCalls) {
|
|
96129
|
+
return {
|
|
96130
|
+
ok: false,
|
|
96131
|
+
failedGate: "empirical",
|
|
96132
|
+
reason: `Empirical gate budget cap hit: ${modelCalls} model call(s) for ${reason} exceeds max ${maxModelCalls}.`
|
|
96133
|
+
};
|
|
96134
|
+
}
|
|
96135
|
+
return null;
|
|
96136
|
+
};
|
|
96137
|
+
const replayBackend = createReplayBackend(input.evalGate.target, input.evalGate.replayBackend);
|
|
96138
|
+
let detBaseScore = 0;
|
|
96139
|
+
let detCandScore = 0;
|
|
96140
|
+
let detN = 0;
|
|
96141
|
+
if (detCases.length > 0) {
|
|
96142
|
+
const budgetResult = consumeModelCalls(detCases.length * 2, "deterministic replay");
|
|
96143
|
+
if (budgetResult)
|
|
96144
|
+
return budgetResult;
|
|
96145
|
+
const baseDet = await replaySplit(replayBackend, input.evalGate.baselineSkillText, detCases, "holdout");
|
|
96146
|
+
const candDet = await replaySplit(replayBackend, input.evalGate.candidateSkillText, detCases, "holdout");
|
|
96147
|
+
detBaseScore = baseDet.hard;
|
|
96148
|
+
detCandScore = candDet.hard;
|
|
96149
|
+
detN = detCases.length;
|
|
96150
|
+
}
|
|
96151
|
+
let rubricBaseScore = 0;
|
|
96152
|
+
let rubricCandScore = 0;
|
|
96153
|
+
let maxNoiseFloor = 0;
|
|
96154
|
+
let signedDeltaTotal = 0;
|
|
96155
|
+
let rubricN = 0;
|
|
96156
|
+
if (rubricCases.length > 0) {
|
|
96157
|
+
const judge = createJudgeBackend(input.evalGate.target, input.evalGate.judgeBackend);
|
|
96158
|
+
const judgeReplays = input.evalGate.judgeReplays ?? 3;
|
|
96159
|
+
for (const rc of rubricCases) {
|
|
96160
|
+
const replayBudget = consumeModelCalls(2, `rubric replay for ${rc.id}`);
|
|
96161
|
+
if (replayBudget)
|
|
96162
|
+
return replayBudget;
|
|
96163
|
+
const prompt = `[case:${rc.id}] ${rc.prompt}`;
|
|
96164
|
+
const [candOutput, baseOutput] = await Promise.all([
|
|
96165
|
+
replayBackend.run(input.evalGate.candidateSkillText, prompt),
|
|
96166
|
+
replayBackend.run(input.evalGate.baselineSkillText, prompt)
|
|
96167
|
+
]);
|
|
96168
|
+
const rubricRef = rc.reference;
|
|
96169
|
+
const judgeBudget = consumeModelCalls(1, `pairwise rubric judge for ${rc.id}`);
|
|
96170
|
+
if (judgeBudget)
|
|
96171
|
+
return judgeBudget;
|
|
96172
|
+
const verdict = await pairwiseJudge(judge, rubricRef, prompt, candOutput, baseOutput, {
|
|
96173
|
+
seed: 0,
|
|
96174
|
+
temperature: 0
|
|
96175
|
+
});
|
|
96176
|
+
const noiseBudget = consumeModelCalls(judgeReplays, `noise-floor replay for ${rc.id}`);
|
|
96177
|
+
if (noiseBudget)
|
|
96178
|
+
return noiseBudget;
|
|
96179
|
+
const noiseFloor = await estimateNoiseFloor(judge, rubricRef, prompt, candOutput, baseOutput, judgeReplays);
|
|
96180
|
+
const delta2 = signedMargin(verdict);
|
|
96181
|
+
maxNoiseFloor = Math.max(maxNoiseFloor, noiseFloor);
|
|
96182
|
+
signedDeltaTotal += delta2;
|
|
96183
|
+
if (rejectsWithinNoise(delta2, noiseFloor)) {
|
|
96184
|
+
rubricCandScore += 0.5;
|
|
96185
|
+
rubricBaseScore += 0.5;
|
|
96186
|
+
} else if (verdict.winner === "candidate") {
|
|
96187
|
+
rubricCandScore += 1;
|
|
96188
|
+
} else if (verdict.winner === "baseline") {
|
|
96189
|
+
rubricBaseScore += 1;
|
|
96190
|
+
} else {
|
|
96191
|
+
rubricCandScore += 0.5;
|
|
96192
|
+
rubricBaseScore += 0.5;
|
|
96193
|
+
}
|
|
96194
|
+
rubricN++;
|
|
96195
|
+
}
|
|
96196
|
+
}
|
|
96197
|
+
const totalN = detN + rubricN;
|
|
96198
|
+
const baseHard = totalN > 0 ? (detBaseScore * detN + rubricBaseScore / Math.max(rubricN, 1) * rubricN) / totalN : 0;
|
|
96199
|
+
const candHard = totalN > 0 ? (detCandScore * detN + rubricCandScore / Math.max(rubricN, 1) * rubricN) / totalN : 0;
|
|
96200
|
+
const rubricDelta = rubricN > 0 ? signedDeltaTotal / rubricN : undefined;
|
|
96201
|
+
if (!(candHard > baseHard && candHard - baseHard >= input.evalGate.margin)) {
|
|
96202
|
+
return {
|
|
96203
|
+
ok: false,
|
|
96204
|
+
failedGate: "empirical",
|
|
96205
|
+
reason: `Empirical gate failed: candidate behavior ${candHard.toFixed(2)} \u2264 baseline ${baseHard.toFixed(2)} (margin ${input.evalGate.margin.toFixed(2)}${rubricDelta !== undefined ? `, rubric_delta=${rubricDelta.toFixed(2)}, noise_floor=${maxNoiseFloor.toFixed(2)}` : ""}).`
|
|
96206
|
+
};
|
|
96207
|
+
}
|
|
96208
|
+
const trainCases = cases.cases.filter((c3) => c3.split === "train");
|
|
96209
|
+
empiricalScores = {
|
|
96210
|
+
hard: candHard,
|
|
96211
|
+
holdout_n: totalN,
|
|
96212
|
+
train_n: trainCases.length,
|
|
96213
|
+
...rubricN > 0 ? { noise_floor: maxNoiseFloor, rubric_delta: rubricDelta ?? 0 } : {}
|
|
96214
|
+
};
|
|
96215
|
+
}
|
|
96216
|
+
}
|
|
95594
96217
|
if (input.ingestedAnchorHash !== undefined && input.baselineAnchorHash !== undefined) {
|
|
95595
96218
|
if (input.ingestedAnchorHash !== input.baselineAnchorHash) {
|
|
95596
96219
|
return {
|
|
@@ -95608,7 +96231,7 @@ async function runGate(input) {
|
|
|
95608
96231
|
reason: `Skeptic gate failed: the Skeptic reported an anchor/invariant violation.${violations}`
|
|
95609
96232
|
};
|
|
95610
96233
|
}
|
|
95611
|
-
return { ok: true };
|
|
96234
|
+
return { ok: true, ...empiricalScores ? { empirical: empiricalScores } : {} };
|
|
95612
96235
|
}
|
|
95613
96236
|
function emitGenerationEnvelope(type, resolvedPath, content, baseline, trends) {
|
|
95614
96237
|
const rubric2 = loadRubric(type);
|
|
@@ -95666,7 +96289,7 @@ function emitGenerationEnvelope(type, resolvedPath, content, baseline, trends) {
|
|
|
95666
96289
|
async function ingestProposal(db2, type, name, resolvedPath, ingestPath, opts, baselineScore) {
|
|
95667
96290
|
let raw;
|
|
95668
96291
|
try {
|
|
95669
|
-
raw =
|
|
96292
|
+
raw = readFileSync12(ingestPath, "utf-8");
|
|
95670
96293
|
} catch {
|
|
95671
96294
|
throw Object.assign(new Error(`Cannot read proposal file: ${ingestPath}`), { code: 2 });
|
|
95672
96295
|
}
|
|
@@ -95708,10 +96331,22 @@ async function ingestProposal(db2, type, name, resolvedPath, ingestPath, opts, b
|
|
|
95708
96331
|
if (opts?.acceptId) {
|
|
95709
96332
|
const backupPath = await backupFile(resolvedPath);
|
|
95710
96333
|
const appliedCount = await stepApply(parsed.changes, resolvedPath, proposalRecord.id, db2);
|
|
96334
|
+
const evalGate = opts?.evalGate ? {
|
|
96335
|
+
name,
|
|
96336
|
+
candidateSkillText: await Bun.file(resolvedPath).text(),
|
|
96337
|
+
baselineSkillText: readFileSync12(backupPath, "utf-8"),
|
|
96338
|
+
margin: opts?.margin ?? 0.05,
|
|
96339
|
+
target: opts?.target ?? "claude",
|
|
96340
|
+
replayBackend: opts?.replayBackend,
|
|
96341
|
+
judgeBackend: opts?.judgeBackend,
|
|
96342
|
+
judgeReplays: opts?.judgeReplays,
|
|
96343
|
+
judgeBudget: opts?.judgeBudget
|
|
96344
|
+
} : undefined;
|
|
95711
96345
|
const verdict = await stepVerify(type, name, resolvedPath, baselineScore, proposalRecord.id, opts, db2, {
|
|
95712
96346
|
backupPath,
|
|
95713
96347
|
ingestedAnchorHash: parsed.anchor_hash,
|
|
95714
|
-
skeptic: parsed.skeptic
|
|
96348
|
+
skeptic: parsed.skeptic,
|
|
96349
|
+
evalGate
|
|
95715
96350
|
});
|
|
95716
96351
|
if (!verdict.rejected && verdict.backupPath) {
|
|
95717
96352
|
await persistVersionSnapshot(verdict.backupPath, resolvedPath, proposalId);
|
|
@@ -95928,7 +96563,7 @@ async function stepVerify(type, name, filePath, baselineScore, proposalDbId, opt
|
|
|
95928
96563
|
const delta = postScore - baselineScore;
|
|
95929
96564
|
if (gate) {
|
|
95930
96565
|
const margin = opts?.margin ?? 0.05;
|
|
95931
|
-
const baselineAnchorHash = gate.ingestedAnchorHash !== undefined ? computeBaselineAnchorHash(
|
|
96566
|
+
const baselineAnchorHash = gate.ingestedAnchorHash !== undefined ? computeBaselineAnchorHash(readFileSync12(gate.backupPath, "utf-8")) : undefined;
|
|
95932
96567
|
const gateResult = await runGate({
|
|
95933
96568
|
type,
|
|
95934
96569
|
resolvedPath: filePath,
|
|
@@ -95937,7 +96572,8 @@ async function stepVerify(type, name, filePath, baselineScore, proposalDbId, opt
|
|
|
95937
96572
|
margin,
|
|
95938
96573
|
ingestedAnchorHash: gate.ingestedAnchorHash,
|
|
95939
96574
|
baselineAnchorHash,
|
|
95940
|
-
skeptic: gate.skeptic
|
|
96575
|
+
skeptic: gate.skeptic,
|
|
96576
|
+
evalGate: gate.evalGate
|
|
95941
96577
|
});
|
|
95942
96578
|
if (!gateResult.ok) {
|
|
95943
96579
|
await restoreFromBackup(gate.backupPath, filePath);
|
|
@@ -95945,6 +96581,31 @@ async function stepVerify(type, name, filePath, baselineScore, proposalDbId, opt
|
|
|
95945
96581
|
echoError(`Gate rejected proposal \u2014 ${gateResult.reason} File restored; proposal stays draft.`);
|
|
95946
96582
|
return { postScore: baselineScore, delta: 0, rejected: true, reason: gateResult.reason };
|
|
95947
96583
|
}
|
|
96584
|
+
if (gateResult.empirical) {
|
|
96585
|
+
try {
|
|
96586
|
+
await new EvaluationDao(db2).insertEvaluation({
|
|
96587
|
+
content_type: type,
|
|
96588
|
+
content_name: name,
|
|
96589
|
+
target_agent: opts?.target ?? "claude",
|
|
96590
|
+
operation: "evolve",
|
|
96591
|
+
aggregate: gateResult.empirical.hard,
|
|
96592
|
+
dimensions: {
|
|
96593
|
+
empirical: {
|
|
96594
|
+
score: gateResult.empirical.hard,
|
|
96595
|
+
hard: gateResult.empirical.hard,
|
|
96596
|
+
holdout_n: gateResult.empirical.holdout_n,
|
|
96597
|
+
train_n: gateResult.empirical.train_n,
|
|
96598
|
+
...gateResult.empirical.noise_floor !== undefined ? { noise_floor: gateResult.empirical.noise_floor } : {},
|
|
96599
|
+
...gateResult.empirical.rubric_delta !== undefined ? { rubric_delta: gateResult.empirical.rubric_delta } : {},
|
|
96600
|
+
note: `Behavior gate: holdout_n=${gateResult.empirical.holdout_n}, train_n=${gateResult.empirical.train_n}${gateResult.empirical.noise_floor !== undefined ? `, noise_floor=${gateResult.empirical.noise_floor.toFixed(2)}` : ""}${gateResult.empirical.rubric_delta !== undefined ? `, rubric_delta=${gateResult.empirical.rubric_delta.toFixed(2)}` : ""}`
|
|
96601
|
+
}
|
|
96602
|
+
}
|
|
96603
|
+
});
|
|
96604
|
+
echo(`Empirical behavior: holdout ${gateResult.empirical.hard.toFixed(2)} (holdout_n=${gateResult.empirical.holdout_n}, train_n=${gateResult.empirical.train_n}${gateResult.empirical.noise_floor !== undefined ? `, noise_floor=${gateResult.empirical.noise_floor.toFixed(2)}` : ""})`);
|
|
96605
|
+
} catch {
|
|
96606
|
+
echoError("Cannot persist empirical behavior score.");
|
|
96607
|
+
}
|
|
96608
|
+
}
|
|
95948
96609
|
}
|
|
95949
96610
|
try {
|
|
95950
96611
|
const verifyEval = await new EvaluationDao(db2).getLatestEvaluation(type, name);
|
|
@@ -95974,7 +96635,7 @@ function formatAnalyze(name, analysis) {
|
|
|
95974
96635
|
const { trends, baselineScore, baselineDate, evaluations: evaluations2 } = analysis;
|
|
95975
96636
|
const grade = scoreToGrade(baselineScore);
|
|
95976
96637
|
const verdict = baselineScore >= 0.7 ? "PASS" : "FAIL";
|
|
95977
|
-
const gitAvailable =
|
|
96638
|
+
const gitAvailable = existsSync13(join220(process.cwd(), ".git"));
|
|
95978
96639
|
const lines = [];
|
|
95979
96640
|
lines.push("=== Evolution Analysis ===");
|
|
95980
96641
|
lines.push(`Target: ${name} Score: ${(baselineScore * 100).toFixed(0)}% (${grade}) Status: ${verdict}`);
|
|
@@ -96004,12 +96665,12 @@ function formatAnalyze(name, analysis) {
|
|
|
96004
96665
|
async function persistVersionSnapshot(backupPath, resolvedPath, proposalId) {
|
|
96005
96666
|
const versionPath = `${resolvedPath}.version-${proposalId}`;
|
|
96006
96667
|
await Bun.write(versionPath, Bun.file(backupPath));
|
|
96007
|
-
|
|
96668
|
+
rmSync5(backupPath, { force: true });
|
|
96008
96669
|
return versionPath;
|
|
96009
96670
|
}
|
|
96010
96671
|
async function evolve(type, name, opts) {
|
|
96011
96672
|
const resolvedPath = resolveContentPath(type, name);
|
|
96012
|
-
if (!resolvedPath || !
|
|
96673
|
+
if (!resolvedPath || !existsSync13(resolvedPath)) {
|
|
96013
96674
|
echoError(`File not found: ${name}`);
|
|
96014
96675
|
return { baselineScore: 0, postScore: 0, delta: 0, changesApplied: 0, proposalPath: "" };
|
|
96015
96676
|
}
|
|
@@ -96044,7 +96705,7 @@ async function evolve(type, name, opts) {
|
|
|
96044
96705
|
const versionId = proposalId2 ?? `#${p.id}`;
|
|
96045
96706
|
const appliedAt = p.applied_at ?? "unknown";
|
|
96046
96707
|
const versionPath = `${resolvedPath}.version-${versionId}`;
|
|
96047
|
-
const hasSnapshot =
|
|
96708
|
+
const hasSnapshot = existsSync13(versionPath) ? "\u2713" : "\u2717";
|
|
96048
96709
|
lines.push(`| ${versionId} | ${appliedAt} | ${hasSnapshot} |`);
|
|
96049
96710
|
}
|
|
96050
96711
|
echo(lines.join(`
|
|
@@ -96057,7 +96718,7 @@ async function evolve(type, name, opts) {
|
|
|
96057
96718
|
return { baselineScore: 0, postScore: 0, delta: 0, changesApplied: 0, proposalPath: "" };
|
|
96058
96719
|
}
|
|
96059
96720
|
const versionPath = `${resolvedPath}.version-${opts.rollback}`;
|
|
96060
|
-
if (!
|
|
96721
|
+
if (!existsSync13(versionPath)) {
|
|
96061
96722
|
echoError(`Version snapshot not found: ${opts.rollback}`);
|
|
96062
96723
|
return { baselineScore: 0, postScore: 0, delta: 0, changesApplied: 0, proposalPath: "" };
|
|
96063
96724
|
}
|
|
@@ -96137,10 +96798,22 @@ async function evolve(type, name, opts) {
|
|
|
96137
96798
|
}
|
|
96138
96799
|
const backupPath2 = await backupFile(resolvedPath);
|
|
96139
96800
|
const appliedCount = await stepApply(acceptedFromStore, resolvedPath, target.id, db2);
|
|
96801
|
+
const evalGateCtx2 = opts?.evalGate ? {
|
|
96802
|
+
name: contentName,
|
|
96803
|
+
candidateSkillText: await Bun.file(resolvedPath).text(),
|
|
96804
|
+
baselineSkillText: readFileSync12(backupPath2, "utf-8"),
|
|
96805
|
+
margin: opts?.margin ?? 0.05,
|
|
96806
|
+
target: opts?.target ?? "claude",
|
|
96807
|
+
replayBackend: opts?.replayBackend,
|
|
96808
|
+
judgeBackend: opts?.judgeBackend,
|
|
96809
|
+
judgeReplays: opts?.judgeReplays,
|
|
96810
|
+
judgeBudget: opts?.judgeBudget
|
|
96811
|
+
} : undefined;
|
|
96140
96812
|
const verdict = await stepVerify(type, contentName, resolvedPath, baselineScore, target.id, opts, db2, {
|
|
96141
96813
|
backupPath: backupPath2,
|
|
96142
96814
|
ingestedAnchorHash: storedAnchorHash,
|
|
96143
|
-
skeptic: storedSkeptic
|
|
96815
|
+
skeptic: storedSkeptic,
|
|
96816
|
+
evalGate: evalGateCtx2
|
|
96144
96817
|
});
|
|
96145
96818
|
if (!verdict.rejected && verdict.backupPath) {
|
|
96146
96819
|
await persistVersionSnapshot(verdict.backupPath, resolvedPath, opts.acceptId);
|
|
@@ -96163,7 +96836,18 @@ async function evolve(type, name, opts) {
|
|
|
96163
96836
|
const { accepted: acceptedChanges } = await interactiveReview(changes, trends);
|
|
96164
96837
|
const backupPath = await backupFile(resolvedPath);
|
|
96165
96838
|
const changesApplied = await stepApply(acceptedChanges, resolvedPath, proposalDbId, db2);
|
|
96166
|
-
const
|
|
96839
|
+
const evalGateCtx = opts?.evalGate ? {
|
|
96840
|
+
name: contentName,
|
|
96841
|
+
candidateSkillText: await Bun.file(resolvedPath).text(),
|
|
96842
|
+
baselineSkillText: readFileSync12(backupPath, "utf-8"),
|
|
96843
|
+
margin: opts?.margin ?? 0.05,
|
|
96844
|
+
target: opts?.target ?? "claude",
|
|
96845
|
+
replayBackend: opts?.replayBackend,
|
|
96846
|
+
judgeBackend: opts?.judgeBackend,
|
|
96847
|
+
judgeReplays: opts?.judgeReplays,
|
|
96848
|
+
judgeBudget: opts?.judgeBudget
|
|
96849
|
+
} : undefined;
|
|
96850
|
+
const { postScore, delta } = await stepVerify(type, contentName, resolvedPath, baselineScore, proposalDbId, opts, db2, evalGateCtx ? { backupPath, evalGate: evalGateCtx } : undefined);
|
|
96167
96851
|
await persistVersionSnapshot(backupPath, resolvedPath, proposalId);
|
|
96168
96852
|
return { baselineScore, postScore, delta, changesApplied, proposalPath };
|
|
96169
96853
|
}
|
|
@@ -96580,7 +97264,7 @@ function addScaffoldOptions(cmd) {
|
|
|
96580
97264
|
return cmd.option("-d, --description <text>", "Content description").option("-t, --target <agent>", "Target agent platform", "claude").option("-o, --output <dir>", "Output directory (default: cwd)").option("--template <tier>", "Template tier (e.g. minimal / standard / specialist)").option("--tools <list>", "Comma-separated tool names to pre-populate frontmatter").option("--force", "Overwrite existing file if present");
|
|
96581
97265
|
}
|
|
96582
97266
|
function addEvolveOptions(cmd) {
|
|
96583
|
-
return cmd.option("-t, --target <agent>", "Target agent platform", "claude").option("--from <date>", "Analyze evaluations since date (ISO 8601)").option("--propose-only", "Generate proposal without applying").option("--accept <id>", "Accept a specific proposal by ID").option("--reject <id>", "Reject a specific proposal").option("--json", "Output machine-readable JSON (envelope-out with --propose-only)").option("--ingest <file>", "Agent-authored proposal JSON (ingest-in mode)").option("--margin <n>", "\u0394-margin gate threshold for accept (default 0.05)", Number.parseFloat, 0.05).option("--analyze", "Print analysis summary (trends, score, data sources) without writing a proposal").option("--history", "List applied proposal versions from the store").option("--rollback <id>", "Rollback to a prior version by proposal_id (requires --confirm)").option("--confirm", "Confirm a destructive operation (required for --rollback)");
|
|
97267
|
+
return cmd.option("-t, --target <agent>", "Target agent platform", "claude").option("--from <date>", "Analyze evaluations since date (ISO 8601)").option("--propose-only", "Generate proposal without applying").option("--accept <id>", "Accept a specific proposal by ID").option("--reject <id>", "Reject a specific proposal").option("--json", "Output machine-readable JSON (envelope-out with --propose-only)").option("--ingest <file>", "Agent-authored proposal JSON (ingest-in mode)").option("--margin <n>", "\u0394-margin gate threshold for accept (default 0.05)", Number.parseFloat, 0.05).option("--eval-gate", "Enable empirical behavior gate (requires skills/<name>/eval/cases.yaml)").option("--analyze", "Print analysis summary (trends, score, data sources) without writing a proposal").option("--history", "List applied proposal versions from the store").option("--rollback <id>", "Rollback to a prior version by proposal_id (requires --confirm)").option("--confirm", "Confirm a destructive operation (required for --rollback)");
|
|
96584
97268
|
}
|
|
96585
97269
|
function addHookEvolveOptions(cmd) {
|
|
96586
97270
|
return cmd.option("-t, --target <agent>", "Target agent platform", "claude").option("--from <date>", "Analyze evaluations since date (ISO 8601)").option("--analyze", "Print analysis summary (trends, score, data sources) \u2014 analyze-only, no apply").option("--json", "Output machine-readable JSON");
|
|
@@ -96689,7 +97373,8 @@ async function agentEvolve(opts) {
|
|
|
96689
97373
|
analyze: opts.analyze,
|
|
96690
97374
|
history: opts.history,
|
|
96691
97375
|
rollback: opts.rollback,
|
|
96692
|
-
confirm: opts.confirm
|
|
97376
|
+
confirm: opts.confirm,
|
|
97377
|
+
evalGate: opts.evalGate
|
|
96693
97378
|
});
|
|
96694
97379
|
return;
|
|
96695
97380
|
}
|
|
@@ -96785,7 +97470,8 @@ async function commandEvolve(opts) {
|
|
|
96785
97470
|
analyze: opts.analyze,
|
|
96786
97471
|
history: opts.history,
|
|
96787
97472
|
rollback: opts.rollback,
|
|
96788
|
-
confirm: opts.confirm
|
|
97473
|
+
confirm: opts.confirm,
|
|
97474
|
+
evalGate: opts.evalGate
|
|
96789
97475
|
});
|
|
96790
97476
|
return;
|
|
96791
97477
|
}
|
|
@@ -96826,27 +97512,280 @@ function registerCommand(program2) {
|
|
|
96826
97512
|
// src/commands/hook.ts
|
|
96827
97513
|
init_src();
|
|
96828
97514
|
init_dist();
|
|
96829
|
-
import { homedir as
|
|
97515
|
+
import { homedir as homedir7 } from "os";
|
|
96830
97516
|
import { join as join225 } from "path";
|
|
96831
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 extractLastAssistantMessage(context3) {
|
|
97552
|
+
const messages2 = context3.messages ?? [];
|
|
97553
|
+
for (let i2 = messages2.length - 1;i2 >= 0; i2--) {
|
|
97554
|
+
const message = messages2[i2];
|
|
97555
|
+
if (message?.role === "assistant") {
|
|
97556
|
+
const content = message.content;
|
|
97557
|
+
if (Array.isArray(content)) {
|
|
97558
|
+
const textParts = [];
|
|
97559
|
+
for (const part of content) {
|
|
97560
|
+
if (part.type === "text" && part.text) {
|
|
97561
|
+
textParts.push(part.text);
|
|
97562
|
+
}
|
|
97563
|
+
}
|
|
97564
|
+
return textParts.join(`
|
|
97565
|
+
`);
|
|
97566
|
+
}
|
|
97567
|
+
return String(content);
|
|
97568
|
+
}
|
|
97569
|
+
}
|
|
97570
|
+
const lastMsg = context3.last_message;
|
|
97571
|
+
if (lastMsg) {
|
|
97572
|
+
return String(lastMsg);
|
|
97573
|
+
}
|
|
97574
|
+
return;
|
|
97575
|
+
}
|
|
97576
|
+
function hasSourceCitations(text3) {
|
|
97577
|
+
if (!text3)
|
|
97578
|
+
return false;
|
|
97579
|
+
for (const pattern of SOURCE_PATTERNS) {
|
|
97580
|
+
if (pattern.test(text3)) {
|
|
97581
|
+
return true;
|
|
97582
|
+
}
|
|
97583
|
+
}
|
|
97584
|
+
return false;
|
|
97585
|
+
}
|
|
97586
|
+
function hasConfidenceLevel(text3) {
|
|
97587
|
+
if (!text3)
|
|
97588
|
+
return false;
|
|
97589
|
+
for (const pattern of CONFIDENCE_PATTERNS) {
|
|
97590
|
+
if (pattern.test(text3)) {
|
|
97591
|
+
return true;
|
|
97592
|
+
}
|
|
97593
|
+
}
|
|
97594
|
+
return false;
|
|
97595
|
+
}
|
|
97596
|
+
function hasToolUsageEvidence(text3) {
|
|
97597
|
+
if (!text3)
|
|
97598
|
+
return false;
|
|
97599
|
+
for (const pattern of TOOL_PATTERNS) {
|
|
97600
|
+
if (pattern.test(text3)) {
|
|
97601
|
+
return true;
|
|
97602
|
+
}
|
|
97603
|
+
}
|
|
97604
|
+
return false;
|
|
97605
|
+
}
|
|
97606
|
+
function hasRedFlags(text3) {
|
|
97607
|
+
if (!text3)
|
|
97608
|
+
return [];
|
|
97609
|
+
const foundFlags = [];
|
|
97610
|
+
for (const pattern of RED_FLAG_PATTERNS) {
|
|
97611
|
+
const matches = text3.match(pattern);
|
|
97612
|
+
if (matches) {
|
|
97613
|
+
foundFlags.push(...matches);
|
|
97614
|
+
}
|
|
97615
|
+
}
|
|
97616
|
+
return foundFlags;
|
|
97617
|
+
}
|
|
97618
|
+
function requiresExternalVerification(text3) {
|
|
97619
|
+
if (!text3)
|
|
97620
|
+
return false;
|
|
97621
|
+
const verificationKeywords = [
|
|
97622
|
+
"api",
|
|
97623
|
+
"library",
|
|
97624
|
+
"framework",
|
|
97625
|
+
"method",
|
|
97626
|
+
"function",
|
|
97627
|
+
"version",
|
|
97628
|
+
"documentation",
|
|
97629
|
+
"official",
|
|
97630
|
+
/recent\s+(?:change|update|release)/i,
|
|
97631
|
+
/\d+\.\d+(?:\.\d+)?/,
|
|
97632
|
+
/https?:\/\//
|
|
97633
|
+
];
|
|
97634
|
+
const textLower = text3.toLowerCase();
|
|
97635
|
+
for (const keyword of verificationKeywords) {
|
|
97636
|
+
if (typeof keyword === "string") {
|
|
97637
|
+
if (textLower.includes(keyword)) {
|
|
97638
|
+
return true;
|
|
97639
|
+
}
|
|
97640
|
+
} else if (keyword.test(textLower)) {
|
|
97641
|
+
return true;
|
|
97642
|
+
}
|
|
97643
|
+
}
|
|
97644
|
+
return false;
|
|
97645
|
+
}
|
|
97646
|
+
function verifyAntiHallucinationProtocol(text3) {
|
|
97647
|
+
if (!text3 || text3.trim().length < 50) {
|
|
97648
|
+
return { ok: true, reason: "Task is complete" };
|
|
97649
|
+
}
|
|
97650
|
+
const needsVerification = requiresExternalVerification(text3);
|
|
97651
|
+
if (!needsVerification) {
|
|
97652
|
+
return { ok: true, reason: "Task is complete (internal discussion)" };
|
|
97653
|
+
}
|
|
97654
|
+
const hasSources = hasSourceCitations(text3);
|
|
97655
|
+
const hasConfidence = hasConfidenceLevel(text3);
|
|
97656
|
+
const hasTools = hasToolUsageEvidence(text3);
|
|
97657
|
+
const redFlags = hasRedFlags(text3);
|
|
97658
|
+
const issues = [];
|
|
97659
|
+
if (!hasSources) {
|
|
97660
|
+
issues.push("source citations for API/library claims");
|
|
97661
|
+
}
|
|
97662
|
+
if (!hasConfidence) {
|
|
97663
|
+
issues.push("confidence level (HIGH/MEDIUM/LOW)");
|
|
97664
|
+
}
|
|
97665
|
+
if (redFlags.length > 0 && !hasTools) {
|
|
97666
|
+
const uniqueFlags = Array.from(new Set(redFlags)).slice(0, 3);
|
|
97667
|
+
issues.push(`uncertainty phrases detected: ${uniqueFlags.join(", ")}`);
|
|
97668
|
+
}
|
|
97669
|
+
if (issues.length > 0) {
|
|
97670
|
+
const reason = `Add verification for: ${issues.join(", ")}`;
|
|
97671
|
+
return { ok: false, reason, issues };
|
|
97672
|
+
}
|
|
97673
|
+
return { ok: true, reason: "Task is complete" };
|
|
97674
|
+
}
|
|
97675
|
+
if (false) {}
|
|
97676
|
+
|
|
97677
|
+
// src/commands/hook-run.ts
|
|
97678
|
+
function preToolUseDecision(decision, reason) {
|
|
97679
|
+
const out = {
|
|
97680
|
+
hookSpecificOutput: { hookEventName: "PreToolUse", permissionDecision: decision }
|
|
97681
|
+
};
|
|
97682
|
+
if (reason !== undefined)
|
|
97683
|
+
out.systemMessage = reason;
|
|
97684
|
+
return { output: JSON.stringify(out), exitCode: 0 };
|
|
97685
|
+
}
|
|
97686
|
+
function resolveSpurTaskOwnership(filePath, cwd5) {
|
|
97687
|
+
const res = spawnSync2("spur", ["task", "resolve", filePath, "--strict", "--json"], {
|
|
97688
|
+
cwd: cwd5,
|
|
97689
|
+
encoding: "utf-8",
|
|
97690
|
+
timeout: 8000
|
|
97691
|
+
});
|
|
97692
|
+
if (res.error || typeof res.status !== "number")
|
|
97693
|
+
return "unknown";
|
|
97694
|
+
return res.status === 0 ? "owned" : "unowned";
|
|
97695
|
+
}
|
|
97696
|
+
function runSpTaskWriteGuard(env, stdinText, resolveTaskOwnership = resolveSpurTaskOwnership) {
|
|
97697
|
+
if (env.SPUR_WRITE_GUARD === "off")
|
|
97698
|
+
return preToolUseDecision("allow");
|
|
97699
|
+
let payload;
|
|
97700
|
+
try {
|
|
97701
|
+
payload = JSON.parse(stdinText);
|
|
97702
|
+
} catch {
|
|
97703
|
+
return preToolUseDecision("allow");
|
|
97704
|
+
}
|
|
97705
|
+
const toolName = payload.tool_name ?? "";
|
|
97706
|
+
if (toolName !== "Write" && toolName !== "Edit")
|
|
97707
|
+
return preToolUseDecision("allow");
|
|
97708
|
+
const filePath = payload.tool_input?.file_path ?? "";
|
|
97709
|
+
if (filePath === "")
|
|
97710
|
+
return preToolUseDecision("allow");
|
|
97711
|
+
const ownership = resolveTaskOwnership(filePath, env.CLAUDE_PROJECT_DIR ?? process.cwd());
|
|
97712
|
+
if (ownership === "owned") {
|
|
97713
|
+
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.");
|
|
97714
|
+
}
|
|
97715
|
+
return preToolUseDecision("allow");
|
|
97716
|
+
}
|
|
97717
|
+
var spTaskWriteGuard = {
|
|
97718
|
+
run: runSpTaskWriteGuard
|
|
97719
|
+
};
|
|
97720
|
+
var ccAntiHallucination = {
|
|
97721
|
+
run(env) {
|
|
97722
|
+
const argumentsJson = env.ARGUMENTS ?? "{}";
|
|
97723
|
+
const allowStop = (feedback, ok) => ({
|
|
97724
|
+
output: JSON.stringify({ hookSpecificOutput: { allowStop: ok, feedback } }),
|
|
97725
|
+
exitCode: ok ? 0 : 1
|
|
97726
|
+
});
|
|
97727
|
+
let context3;
|
|
97728
|
+
try {
|
|
97729
|
+
context3 = JSON.parse(argumentsJson);
|
|
97730
|
+
} catch {
|
|
97731
|
+
return allowStop("Task is complete (invalid context ignored)", true);
|
|
97732
|
+
}
|
|
97733
|
+
const content = extractLastAssistantMessage(context3);
|
|
97734
|
+
if (content === undefined)
|
|
97735
|
+
return allowStop("No content to verify", true);
|
|
97736
|
+
const result = verifyAntiHallucinationProtocol(content);
|
|
97737
|
+
return allowStop(result.reason, result.ok);
|
|
97738
|
+
}
|
|
97739
|
+
};
|
|
97740
|
+
var HOOK_RUNNERS = {
|
|
97741
|
+
"sp/task-write-guard": spTaskWriteGuard,
|
|
97742
|
+
"cc/anti-hallucination": ccAntiHallucination
|
|
97743
|
+
};
|
|
97744
|
+
function hookRun(plugin, hookId, env, stdinText) {
|
|
97745
|
+
const runner = HOOK_RUNNERS[`${plugin}/${hookId}`];
|
|
97746
|
+
if (!runner) {
|
|
97747
|
+
echoError(`Error: unknown hook '${plugin} ${hookId}'. Known hooks: ${Object.keys(HOOK_RUNNERS).join(", ")}`);
|
|
97748
|
+
return 2;
|
|
97749
|
+
}
|
|
97750
|
+
const result = runner.run(env, stdinText);
|
|
97751
|
+
echo(result.output);
|
|
97752
|
+
return result.exitCode;
|
|
97753
|
+
}
|
|
97754
|
+
function registerHookRun(cmd, readInput) {
|
|
97755
|
+
cmd.command("run <plugin> <hook-id>").description("Run a registered plugin hook runner (the runtime command installed hook configs call)").action((plugin, hookId) => {
|
|
97756
|
+
let stdinText = "";
|
|
97757
|
+
if (readInput) {
|
|
97758
|
+
stdinText = readInput();
|
|
97759
|
+
} else {
|
|
97760
|
+
try {
|
|
97761
|
+
stdinText = __require("fs").readFileSync(0, "utf-8");
|
|
97762
|
+
} catch {
|
|
97763
|
+
stdinText = "";
|
|
97764
|
+
}
|
|
97765
|
+
}
|
|
97766
|
+
const code = hookRun(plugin, hookId, process.env, stdinText);
|
|
97767
|
+
process.exit(code);
|
|
97768
|
+
});
|
|
97769
|
+
}
|
|
97770
|
+
|
|
96832
97771
|
// src/commands/install.ts
|
|
96833
97772
|
init_src();
|
|
96834
97773
|
init_dist();
|
|
96835
97774
|
import {
|
|
96836
97775
|
copyFileSync as copyFileSync2,
|
|
96837
|
-
existsSync as
|
|
97776
|
+
existsSync as existsSync15,
|
|
96838
97777
|
mkdirSync as mkdirSync9,
|
|
96839
97778
|
readdirSync as readdirSync4,
|
|
96840
|
-
readFileSync as
|
|
96841
|
-
rmSync as
|
|
96842
|
-
statSync as
|
|
97779
|
+
readFileSync as readFileSync14,
|
|
97780
|
+
rmSync as rmSync6,
|
|
97781
|
+
statSync as statSync6,
|
|
96843
97782
|
writeFileSync as writeFileSync8
|
|
96844
97783
|
} from "fs";
|
|
96845
|
-
import { homedir as
|
|
97784
|
+
import { homedir as homedir6 } from "os";
|
|
96846
97785
|
import { join as join223 } from "path";
|
|
96847
97786
|
|
|
96848
97787
|
// src/hooks.ts
|
|
96849
|
-
import { copyFileSync, existsSync as
|
|
97788
|
+
import { copyFileSync, existsSync as existsSync14, mkdirSync as mkdirSync8, readFileSync as readFileSync13, writeFileSync as writeFileSync7 } from "fs";
|
|
96850
97789
|
import { join as join221 } from "path";
|
|
96851
97790
|
var CANONICAL_TO_PI_EVENT = {
|
|
96852
97791
|
sessionStart: "session_start",
|
|
@@ -96890,10 +97829,10 @@ function convertCanonicalToPiHooks(config3) {
|
|
|
96890
97829
|
}
|
|
96891
97830
|
function readCanonicalHooks(rulesyncDir) {
|
|
96892
97831
|
const hooksPath = join221(rulesyncDir, "hooks.json");
|
|
96893
|
-
if (!
|
|
97832
|
+
if (!existsSync14(hooksPath))
|
|
96894
97833
|
return null;
|
|
96895
97834
|
try {
|
|
96896
|
-
return JSON.parse(
|
|
97835
|
+
return JSON.parse(readFileSync13(hooksPath, "utf-8"));
|
|
96897
97836
|
} catch {
|
|
96898
97837
|
return null;
|
|
96899
97838
|
}
|
|
@@ -97008,7 +97947,7 @@ async function executeInstall(plugin, targets2, options2, dependencies = {}) {
|
|
|
97008
97947
|
const targetInputRoot = prepareTargetRulesyncInput(outputDir, target, plugin);
|
|
97009
97948
|
targetInputRoots.set(target, targetInputRoot);
|
|
97010
97949
|
}
|
|
97011
|
-
const rulesyncFeatures = ["skills",
|
|
97950
|
+
const rulesyncFeatures = ["skills", ...mapResult.mcp ? ["mcp"] : []];
|
|
97012
97951
|
const rulesyncTargets = targets2.filter((t) => t !== "claude" && t !== "hermes" && t !== "omp");
|
|
97013
97952
|
if (targets2.includes("omp") && !targets2.includes("pi")) {
|
|
97014
97953
|
if (!targetInputRoots.has("pi")) {
|
|
@@ -97047,11 +97986,25 @@ async function executeInstall(plugin, targets2, options2, dependencies = {}) {
|
|
|
97047
97986
|
resultCounts.subagentsCount += result.subagentsCount;
|
|
97048
97987
|
resultCounts.hooksCount += result.hooksCount;
|
|
97049
97988
|
}
|
|
97989
|
+
if (mapResult.hooks) {
|
|
97990
|
+
for (const target of rulesyncTargets) {
|
|
97991
|
+
if (!TARGET_TO_RULESYNC_HOOKS[target])
|
|
97992
|
+
continue;
|
|
97993
|
+
const hookResult = await runRulesyncImpl([target], ["hooks"], targetInputRoots.get(target) ?? outputDir, {
|
|
97994
|
+
global: options2.global,
|
|
97995
|
+
dryRun: options2.dryRun,
|
|
97996
|
+
verbose: options2.verbose,
|
|
97997
|
+
outputRoot: options2.outputRoot,
|
|
97998
|
+
targetMap: TARGET_TO_RULESYNC_HOOKS
|
|
97999
|
+
});
|
|
98000
|
+
resultCounts.hooksCount += hookResult.hooksCount;
|
|
98001
|
+
}
|
|
98002
|
+
}
|
|
97050
98003
|
if (options2.verbose) {
|
|
97051
98004
|
echo(` Skills written: ${resultCounts.skillsCount}, Commands: ${resultCounts.commandsCount}, Subagents: ${resultCounts.subagentsCount}, Hooks: ${resultCounts.hooksCount}`);
|
|
97052
98005
|
}
|
|
97053
98006
|
}
|
|
97054
|
-
const outputRoot = options2.outputRoot ?? (options2.global ?
|
|
98007
|
+
const outputRoot = options2.outputRoot ?? (options2.global ? homedir6() : process.cwd());
|
|
97055
98008
|
const hookEmitResults = [];
|
|
97056
98009
|
for (const target of targets2) {
|
|
97057
98010
|
if (target === "claude") {
|
|
@@ -97060,9 +98013,9 @@ async function executeInstall(plugin, targets2, options2, dependencies = {}) {
|
|
|
97060
98013
|
if (!options2.dryRun) {
|
|
97061
98014
|
const marketplaceName = resolution.marketplaceName ?? "superskill";
|
|
97062
98015
|
const marketplaceRoot = resolution.marketplaceRoot ?? process.cwd();
|
|
97063
|
-
const cacheDir = join223(
|
|
97064
|
-
if (
|
|
97065
|
-
|
|
98016
|
+
const cacheDir = join223(homedir6(), ".claude", "plugins", "cache", marketplaceName);
|
|
98017
|
+
if (existsSync15(cacheDir))
|
|
98018
|
+
rmSync6(cacheDir, { recursive: true, force: true });
|
|
97066
98019
|
await runClaudeInstallImpl(marketplaceRoot, marketplaceName, plugin);
|
|
97067
98020
|
}
|
|
97068
98021
|
}
|
|
@@ -97090,7 +98043,7 @@ async function executeInstall(plugin, targets2, options2, dependencies = {}) {
|
|
|
97090
98043
|
if (options2.verbose)
|
|
97091
98044
|
echo(` ${hookResult.message}`);
|
|
97092
98045
|
const agentsDir = join223(pluginRoot, "agents");
|
|
97093
|
-
if (
|
|
98046
|
+
if (existsSync15(agentsDir) && !options2.dryRun) {
|
|
97094
98047
|
const piAgentsDir = join223(outputRoot, ".pi", "agent", "agents");
|
|
97095
98048
|
mkdirSync9(piAgentsDir, { recursive: true });
|
|
97096
98049
|
for (const entry of readdirSync4(agentsDir)) {
|
|
@@ -97098,8 +98051,8 @@ async function executeInstall(plugin, targets2, options2, dependencies = {}) {
|
|
|
97098
98051
|
continue;
|
|
97099
98052
|
const agentName = entry.replace(/\.md$/, "");
|
|
97100
98053
|
const expectedName = `${plugin}-${agentName}`;
|
|
97101
|
-
const source =
|
|
97102
|
-
const skillExists = (bare) =>
|
|
98054
|
+
const source = readFileSync14(join223(agentsDir, entry), "utf-8");
|
|
98055
|
+
const skillExists = (bare) => existsSync15(join223(pluginRoot, "skills", bare));
|
|
97103
98056
|
const adapted = adaptSubagentToPi(source, expectedName, plugin, skillExists);
|
|
97104
98057
|
writeFileSync8(join223(piAgentsDir, `${expectedName}.md`), adapted);
|
|
97105
98058
|
}
|
|
@@ -97148,9 +98101,9 @@ function resolvePluginRoot(plugin, marketplacePath) {
|
|
|
97148
98101
|
const manifestRoot = resolved.marketplaceRoot;
|
|
97149
98102
|
const manifestPath = join223(manifestRoot, ".claude-plugin", "marketplace.json");
|
|
97150
98103
|
let marketplaceName;
|
|
97151
|
-
if (
|
|
98104
|
+
if (existsSync15(manifestPath)) {
|
|
97152
98105
|
try {
|
|
97153
|
-
const raw =
|
|
98106
|
+
const raw = readFileSync14(manifestPath, "utf-8");
|
|
97154
98107
|
const parsed = JSON.parse(raw);
|
|
97155
98108
|
marketplaceName = parsed.name;
|
|
97156
98109
|
} catch {}
|
|
@@ -97158,7 +98111,7 @@ function resolvePluginRoot(plugin, marketplacePath) {
|
|
|
97158
98111
|
return { pluginRoot: resolved.pluginRoot, marketplaceRoot: manifestRoot, marketplaceName };
|
|
97159
98112
|
}
|
|
97160
98113
|
const fallback = join223("plugins", plugin);
|
|
97161
|
-
if (
|
|
98114
|
+
if (existsSync15(fallback) && readdirSync4(fallback).some((d) => ["skills", "commands", "agents", "hooks", "hooks.json"].includes(d)))
|
|
97162
98115
|
return { pluginRoot: fallback };
|
|
97163
98116
|
const available = listResolvablePlugins(marketplacePath);
|
|
97164
98117
|
const msg = available.length > 0 ? `Available: ${available.join(", ")}` : "No marketplace manifest found and no plugins/<name>/ directory.";
|
|
@@ -97167,7 +98120,7 @@ function resolvePluginRoot(plugin, marketplacePath) {
|
|
|
97167
98120
|
function prepareTargetRulesyncInput(sourceRoot, target, pluginName) {
|
|
97168
98121
|
const targetRoot = join223(sourceRoot, ".targets", target);
|
|
97169
98122
|
const targetRulesyncRoot = join223(targetRoot, ".rulesync");
|
|
97170
|
-
|
|
98123
|
+
rmSync6(targetRoot, { recursive: true, force: true });
|
|
97171
98124
|
copyDirectory(sourceRoot, targetRulesyncRoot, { skipDirectoryNames: new Set([".targets"]) });
|
|
97172
98125
|
transformRulesyncMarkdown(targetRulesyncRoot, target, pluginName);
|
|
97173
98126
|
return targetRoot;
|
|
@@ -97193,25 +98146,25 @@ function transformRulesyncMarkdown(root, target, pluginName) {
|
|
|
97193
98146
|
transformMarkdownDirectory(join223(root, "skills"), target, pluginName);
|
|
97194
98147
|
}
|
|
97195
98148
|
function transformMarkdownDirectory(dir, target, pluginName) {
|
|
97196
|
-
if (!
|
|
98149
|
+
if (!existsSync15(dir))
|
|
97197
98150
|
return;
|
|
97198
98151
|
for (const entry of readdirSync4(dir)) {
|
|
97199
98152
|
const path11 = join223(dir, entry);
|
|
97200
|
-
const stats =
|
|
98153
|
+
const stats = statSync6(path11);
|
|
97201
98154
|
if (stats.isDirectory()) {
|
|
97202
98155
|
transformMarkdownDirectory(path11, target, pluginName);
|
|
97203
98156
|
continue;
|
|
97204
98157
|
}
|
|
97205
98158
|
if (!entry.endsWith(".md"))
|
|
97206
98159
|
continue;
|
|
97207
|
-
const content =
|
|
98160
|
+
const content = readFileSync14(path11, "utf-8");
|
|
97208
98161
|
const slashTranslated = translateSlashCommands(content, target);
|
|
97209
98162
|
const transformed = rewriteSkillReferences(slashTranslated, pluginName);
|
|
97210
98163
|
writeFileSync8(path11, transformed);
|
|
97211
98164
|
}
|
|
97212
98165
|
}
|
|
97213
98166
|
function copyDirectory(source, destination, options2 = {}) {
|
|
97214
|
-
if (!
|
|
98167
|
+
if (!existsSync15(source))
|
|
97215
98168
|
return;
|
|
97216
98169
|
mkdirSync9(destination, { recursive: true });
|
|
97217
98170
|
for (const entry of readdirSync4(source)) {
|
|
@@ -97219,7 +98172,7 @@ function copyDirectory(source, destination, options2 = {}) {
|
|
|
97219
98172
|
continue;
|
|
97220
98173
|
const sourcePath = join223(source, entry);
|
|
97221
98174
|
const destinationPath = join223(destination, entry);
|
|
97222
|
-
if (
|
|
98175
|
+
if (statSync6(sourcePath).isDirectory()) {
|
|
97223
98176
|
copyDirectory(sourcePath, destinationPath, options2);
|
|
97224
98177
|
} else {
|
|
97225
98178
|
copyFileSync2(sourcePath, destinationPath);
|
|
@@ -97258,7 +98211,7 @@ async function emitHook(name, opts) {
|
|
|
97258
98211
|
const target = resolveTarget(opts);
|
|
97259
98212
|
const global3 = opts.global !== false;
|
|
97260
98213
|
const dryRun = opts.dryRun === true;
|
|
97261
|
-
const outputRoot = global3 ?
|
|
98214
|
+
const outputRoot = global3 ? homedir7() : process.cwd();
|
|
97262
98215
|
const pluginRoot = resolvePluginRoot(name).pluginRoot;
|
|
97263
98216
|
const outputDir = ".rulesync";
|
|
97264
98217
|
mapPluginToRulesync(pluginRoot, name, outputDir);
|
|
@@ -97326,6 +98279,7 @@ function registerHook(program2) {
|
|
|
97326
98279
|
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) => {
|
|
97327
98280
|
await runOperation(() => hookEmit({ name, ...opts }));
|
|
97328
98281
|
});
|
|
98282
|
+
registerHookRun(cmd);
|
|
97329
98283
|
}
|
|
97330
98284
|
|
|
97331
98285
|
// src/commands/magent.ts
|
|
@@ -97386,7 +98340,8 @@ async function magentEvolve(opts) {
|
|
|
97386
98340
|
analyze: opts.analyze,
|
|
97387
98341
|
history: opts.history,
|
|
97388
98342
|
rollback: opts.rollback,
|
|
97389
|
-
confirm: opts.confirm
|
|
98343
|
+
confirm: opts.confirm,
|
|
98344
|
+
evalGate: opts.evalGate
|
|
97390
98345
|
});
|
|
97391
98346
|
return;
|
|
97392
98347
|
}
|
|
@@ -97430,9 +98385,9 @@ init_dist();
|
|
|
97430
98385
|
// src/operations/migrate.ts
|
|
97431
98386
|
init_src();
|
|
97432
98387
|
init_dist();
|
|
97433
|
-
import { readFileSync as
|
|
98388
|
+
import { readFileSync as readFileSync15 } from "fs";
|
|
97434
98389
|
function readProposalId(proposalPath) {
|
|
97435
|
-
const raw =
|
|
98390
|
+
const raw = readFileSync15(proposalPath, "utf-8");
|
|
97436
98391
|
const parsed = JSON.parse(raw);
|
|
97437
98392
|
if (parsed !== null && typeof parsed === "object" && "proposal_id" in parsed) {
|
|
97438
98393
|
const id = parsed.proposal_id;
|
|
@@ -97537,7 +98492,8 @@ async function skillEvolve(opts) {
|
|
|
97537
98492
|
analyze: opts.analyze,
|
|
97538
98493
|
history: opts.history,
|
|
97539
98494
|
rollback: opts.rollback,
|
|
97540
|
-
confirm: opts.confirm
|
|
98495
|
+
confirm: opts.confirm,
|
|
98496
|
+
evalGate: opts.evalGate
|
|
97541
98497
|
});
|
|
97542
98498
|
return;
|
|
97543
98499
|
}
|
|
@@ -97601,7 +98557,7 @@ function getPackageVersion() {
|
|
|
97601
98557
|
if (packageVersion)
|
|
97602
98558
|
return packageVersion;
|
|
97603
98559
|
const packageJsonPath = join226(import.meta.dir, "..", "package.json");
|
|
97604
|
-
const packageJson = JSON.parse(
|
|
98560
|
+
const packageJson = JSON.parse(readFileSync16(packageJsonPath, "utf-8"));
|
|
97605
98561
|
if (typeof packageJson.version !== "string" || packageJson.version.length === 0) {
|
|
97606
98562
|
throw new Error(`Invalid package version in ${packageJsonPath}`);
|
|
97607
98563
|
}
|