@gobing-ai/superskill 0.2.4 → 0.2.5

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.
Files changed (3) hide show
  1. package/README.md +41 -244
  2. package/dist/index.js +957 -276
  3. 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, 15);
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 (!content.startsWith(`---
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: "${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 parts = value.split(/,\s*/).map((p) => p.trim()).filter(Boolean);
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: "${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, statSync as statSync2, writeFileSync } from "fs";
9735
- import { join as join3 } from "path";
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
- return content.replace(/^name:\s*.+$/m, `name: ${newName}`);
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
- const value = JSON.parse(readFileSync2(path, "utf-8"));
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
- if (statSync2(srcPath).isDirectory()) {
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 content = readFileSync2(srcPath, "utf-8");
9904
- writeFileSync(destPath, rewriteSkillReferences(content, pluginName));
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
- var CLAUDE_TO_CANONICAL_EVENT;
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 = resolve(marketplacePath);
13977
+ manifestPath = resolve2(marketplacePath);
13906
13978
  } else {
13907
- manifestPath = resolve(join4(marketplacePath, "marketplace.json"));
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 = resolve(".claude-plugin", "marketplace.json");
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 (/(?:^|\/)\.\.(?:\/|$)/.test(source)) {
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
- const pluginRoot = resolve(marketplaceRoot, pluginRootBase, source);
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") ? resolve(marketplacePath) : resolve(join4(marketplacePath, "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 = resolve(".claude-plugin", "marketplace.json");
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 statSync3 } from "fs";
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 = statSync3(skillPath).isDirectory() ? skillPath : dirname3(skillPath);
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 homedir2 } from "os";
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 ?? homedir2();
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 (e) {
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(events.size / 3, 1));
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 statSync4 } from "fs";
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 = statSync4(resolvedPath);
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
- const bodyStart = content.indexOf(`
14644
- ---
14645
- `);
14646
- const body = bodyStart >= 0 ? content.slice(bodyStart + 5) : content;
14647
- const linkFindings = checkBodyLinks(body, baseDir);
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 = /^---\s*$/m.test(content);
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
- for (const key of Object.keys(data)) {
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: `'${field}' has trailing whitespace`
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
- var CONFIG_DEFAULTS, resolvedConfig;
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 import_api.metrics.getMeter(METER_NAME, METER_VERSION);
17411
+ return import_api3.metrics.getMeter(METER_NAME, METER_VERSION);
17306
17412
  }
17307
17413
  function noopCounter() {
17308
17414
  if (!_noopCounter)
17309
- _noopCounter = import_api.createNoopMeter().createCounter("noop");
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 import_api, METER_NAME = "@gobing-ai/ts-infra", METER_VERSION = "0.1.0", instruments, _noopCounter;
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
- import_api = __toESM(require_src(), 1);
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 rmSync3, statSync as statSync5, writeFileSync as writeFileSync4 } from "fs";
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
- rmSync3(path, { recursive: true, force: true });
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 = statSync5(path);
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(resolve2, reject) {
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
- resolve2(is);
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((resolve2, reject) => {
33700
+ const step = (i) => new Promise((resolve3, reject) => {
33589
33701
  if (i === pathEnv.length)
33590
- return opt.all && found.length ? resolve2(found) : reject(getNotFoundError(cmd));
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
- resolve2(subStep(p, i, 0));
33707
+ resolve3(subStep(p, i, 0));
33596
33708
  });
33597
- const subStep = (p, i, ii) => new Promise((resolve2, reject) => {
33709
+ const subStep = (p, i, ii) => new Promise((resolve3, reject) => {
33598
33710
  if (ii === pathExt.length)
33599
- return resolve2(step(i + 1));
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 resolve2(p + ext);
33718
+ return resolve3(p + ext);
33607
33719
  }
33608
- return resolve2(subStep(p, i, ii + 1));
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
- context.isForcefullyTerminated ??= true;
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, context, controller)], terminateOnCancel = async (subprocess, cancelSignal, context, { signal }) => {
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
- context.terminationReason ??= "cancel";
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((resolve2, reject) => {
34548
- Object.assign(methods, { resolve: resolve2, reject });
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
- context.terminationReason ??= "gracefulCancel";
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, context, controller) => timeout === 0 || timeout === undefined ? [] : [killAfterTimeout(subprocess, timeout, context, controller)], killAfterTimeout = async (subprocess, timeout, context, { signal }) => {
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
- context.terminationReason ??= "timeout";
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 statSync6 } from "fs";
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 = statSync6(cwd5);
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, context) => {
37524
+ var waitForExit = async (subprocess, context2) => {
37413
37525
  const [exitCode, signal] = await waitForExitOrError(subprocess);
37414
- context.isForcefullyTerminated ??= false;
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, context);
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, context, controller),
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
- context.terminationReason ??= "other";
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 resolve2 = promise2.resolve.bind(promise2);
39148
- return { resolve: resolve2, promises };
39149
- }, waitForConcurrentStreams = async ({ resolve: resolve2, promises }, subprocess) => {
39150
- resolve2();
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 context = {};
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: context.terminationReason === "timeout",
39598
- isCanceled: context.terminationReason === "cancel" || context.terminationReason === "gracefulCancel",
39599
- isGracefullyCanceled: context.terminationReason === "gracefulCancel",
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: context.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, context) {
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: context.command,
39911
- args: context.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() - context.startedAt,
40026
+ durationMs: Date.now() - context2.startedAt,
39915
40027
  reason: this.killedWith !== undefined ? "signal" : "exit",
39916
40028
  timestamp: new Date().toISOString(),
39917
- ...context.label !== undefined ? { label: context.label } : {}
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, context2) {
40241
- return getAgentShim(agent).getPromptCommand(applyIdentityPreamble(agent, promptOptions, context2));
40438
+ function buildAgentCommand(agent, promptOptions, context3) {
40439
+ return getAgentShim(agent).getPromptCommand(applyIdentityPreamble(agent, promptOptions, context3));
40242
40440
  }
40243
- function applyIdentityPreamble(agent, promptOptions, context2) {
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: context2.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((resolve2) => {
40413
- setTimeout(() => resolve2("timeout"), 5000);
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") {
@@ -40766,7 +40967,7 @@ function scoreSkillLinkage(body) {
40766
40967
  function scoreModelFit(data) {
40767
40968
  const model = data.model;
40768
40969
  const recognizedAliases = { inherit: true, sonnet: true, opus: true, haiku: true };
40769
- const wellFormedPattern = /^claude-(sonnet|opus|haiku)-/i;
40970
+ const wellFormedPattern = /^claude-(\d+-\d+-)?(sonnet|opus|haiku)-/i;
40770
40971
  let score;
40771
40972
  let note;
40772
40973
  if (typeof model === "string") {
@@ -40957,6 +41158,127 @@ var init_command3 = __esm(() => {
40957
41158
  init_types2();
40958
41159
  });
40959
41160
 
41161
+ // ../../packages/core/src/quality/eval-cases.ts
41162
+ import { existsSync as existsSync10, readFileSync as readFileSync9 } from "fs";
41163
+ import { join as join8 } from "path";
41164
+ function isRuleJudge(value) {
41165
+ return typeof value === "object" && value !== null && "checks" in value && Array.isArray(value.checks);
41166
+ }
41167
+ function isRubricRef(value) {
41168
+ return typeof value === "object" && value !== null && "criterion" in value && typeof value.criterion === "string" && !("checks" in value);
41169
+ }
41170
+ function resolveEvalCasesPath(name, opts) {
41171
+ if (opts?.path) {
41172
+ if (!existsSync10(opts.path))
41173
+ return null;
41174
+ return opts.path;
41175
+ }
41176
+ assertSafePathSegment(name, "eval cases skill name");
41177
+ const coLocated = join8(process.cwd(), "skills", name, "eval", "cases.yaml");
41178
+ if (existsSync10(coLocated))
41179
+ return coLocated;
41180
+ return null;
41181
+ }
41182
+ function loadEvalCases(name, opts) {
41183
+ const resolvedPath = resolveEvalCasesPath(name, opts);
41184
+ if (!resolvedPath)
41185
+ return null;
41186
+ const raw = readFileSync9(resolvedPath, "utf-8");
41187
+ let parsed;
41188
+ try {
41189
+ parsed = $parse(raw);
41190
+ } catch (e) {
41191
+ throw new EvalCaseError(resolvedPath, null, `Failed to parse YAML: ${e instanceof Error ? e.message : String(e)}`);
41192
+ }
41193
+ const result = EvalCaseSetSchema.safeParse(parsed);
41194
+ if (!result.success) {
41195
+ const issue2 = result.error.issues[0];
41196
+ if (!issue2) {
41197
+ throw new EvalCaseError(resolvedPath, null, "Schema validation failed with no issue reported.");
41198
+ }
41199
+ const caseId = extractCaseIdFromPath(issue2.path, parsed);
41200
+ const field = issue2.path.length > 0 ? issue2.path.join(".") : "root";
41201
+ throw new EvalCaseError(resolvedPath, caseId, `Schema validation failed at "${field}": ${issue2.message}`);
41202
+ }
41203
+ const caseSet = result.data;
41204
+ const seen = new Set;
41205
+ for (const c3 of caseSet.cases) {
41206
+ if (seen.has(c3.id)) {
41207
+ throw new EvalCaseError(resolvedPath, c3.id, `Duplicate case id "${c3.id}"`);
41208
+ }
41209
+ seen.add(c3.id);
41210
+ }
41211
+ return caseSet;
41212
+ }
41213
+ function extractCaseIdFromPath(path7, parsed) {
41214
+ const casesIdx = path7.indexOf("cases");
41215
+ if (casesIdx >= 0 && path7.length > casesIdx + 1 && typeof path7[casesIdx + 1] === "number") {
41216
+ const caseIndex = path7[casesIdx + 1];
41217
+ if (typeof parsed === "object" && parsed !== null && "cases" in parsed && Array.isArray(parsed.cases)) {
41218
+ const candidate = parsed.cases[caseIndex];
41219
+ if (typeof candidate === "object" && candidate !== null && "id" in candidate && typeof candidate.id === "string") {
41220
+ return candidate.id;
41221
+ }
41222
+ }
41223
+ return `cases[${caseIndex}]`;
41224
+ }
41225
+ return null;
41226
+ }
41227
+ var RuleCheckSchema, RubricRefSchema, RuleJudgeSchema, EvalCaseSchema, EvalCaseSetSchema, EvalCaseError;
41228
+ var init_eval_cases = __esm(() => {
41229
+ init_dist2();
41230
+ init_zod();
41231
+ init_identity();
41232
+ RuleCheckSchema = exports_external.object({
41233
+ op: exports_external.enum(["contains", "regex", "equals", "not_contains", "tool_called"]),
41234
+ arg: exports_external.string().min(1)
41235
+ });
41236
+ RubricRefSchema = exports_external.object({
41237
+ criterion: exports_external.string().min(1),
41238
+ excellent: exports_external.string().optional(),
41239
+ poor: exports_external.string().optional()
41240
+ });
41241
+ RuleJudgeSchema = exports_external.object({
41242
+ checks: exports_external.array(RuleCheckSchema).min(1)
41243
+ });
41244
+ EvalCaseSchema = exports_external.object({
41245
+ id: exports_external.string().min(1),
41246
+ split: exports_external.enum(["train", "holdout"]),
41247
+ prompt: exports_external.string().min(1),
41248
+ reference_kind: exports_external.enum(["exact", "rule", "rubric"]),
41249
+ reference: exports_external.union([exports_external.string().min(1), RuleJudgeSchema, RubricRefSchema]),
41250
+ tags: exports_external.array(exports_external.string().min(1)).optional()
41251
+ }).refine((c3) => {
41252
+ if (c3.reference_kind === "exact" && typeof c3.reference !== "string") {
41253
+ return false;
41254
+ }
41255
+ if (c3.reference_kind === "rule" && !isRuleJudge(c3.reference)) {
41256
+ return false;
41257
+ }
41258
+ if (c3.reference_kind === "rubric" && !isRubricRef(c3.reference)) {
41259
+ return false;
41260
+ }
41261
+ return true;
41262
+ }, {
41263
+ message: 'reference must match reference_kind: string for "exact", RuleJudge for "rule", RubricRef for "rubric"'
41264
+ });
41265
+ EvalCaseSetSchema = exports_external.object({
41266
+ version: exports_external.literal(1),
41267
+ cases: exports_external.array(EvalCaseSchema).min(1)
41268
+ });
41269
+ EvalCaseError = class EvalCaseError extends Error {
41270
+ file;
41271
+ caseId;
41272
+ constructor(file2, caseId, message) {
41273
+ const prefix = caseId ? `${file2}: case "${caseId}" \u2014 ` : `${file2}: `;
41274
+ super(`${prefix}${message}`);
41275
+ this.file = file2;
41276
+ this.caseId = caseId;
41277
+ this.name = "EvalCaseError";
41278
+ }
41279
+ };
41280
+ });
41281
+
40960
41282
  // ../../packages/core/src/quality/magent.ts
40961
41283
  function scoreCompleteness3(body) {
40962
41284
  let found = 0;
@@ -40993,7 +41315,7 @@ function scorePlatformCoverage(data, body) {
40993
41315
  [/opencode/i, "opencode"],
40994
41316
  [/openclaw/i, "openclaw"],
40995
41317
  [/antigravity/i, "antigravity"],
40996
- [/pi\b/i, "pi"]
41318
+ [/\bpi\b/i, "pi"]
40997
41319
  ];
40998
41320
  for (const [re, name] of platformPatterns) {
40999
41321
  if (re.test(body))
@@ -41038,7 +41360,9 @@ function scoreSafety2(body) {
41038
41360
  }
41039
41361
  function evaluateMagent(content, target) {
41040
41362
  const body = extractBody(content);
41041
- const hasFrontmatter = /^---\s*$/m.test(content);
41363
+ const hasFrontmatter = content.startsWith(`---
41364
+ `) || content.startsWith(`---\r
41365
+ `);
41042
41366
  const fmResult = hasFrontmatter ? parseFrontmatterSafe(content) : undefined;
41043
41367
  const data = fmResult ?? {};
41044
41368
  const fmNote = hasFrontmatter && fmResult === null ? parseErrorNote(content, "Frontmatter parse error") : null;
@@ -41180,7 +41504,7 @@ function countTriggerPhrases(body) {
41180
41504
  if (headingMatch) {
41181
41505
  const depth = headingMatch[1]?.length ?? 0;
41182
41506
  const title = (headingMatch[2] ?? "").toLowerCase();
41183
- if (/\btrigger|when to use/i.test(title)) {
41507
+ if (/\b(?:trigger|when to use)/i.test(title)) {
41184
41508
  inTriggerSection = true;
41185
41509
  sectionDepth = depth;
41186
41510
  } else if (inTriggerSection && depth <= sectionDepth) {
@@ -41196,7 +41520,7 @@ function countTriggerPhrases(body) {
41196
41520
  }
41197
41521
  if (count2 === 0) {
41198
41522
  for (const line of lines) {
41199
- if (/^\s*[-*+]\s/.test(line)) {
41523
+ if (/^\s*[-*+]\s/.test(line) || /^\s*\d+[.)]\s/.test(line)) {
41200
41524
  count2++;
41201
41525
  }
41202
41526
  }
@@ -41228,29 +41552,77 @@ var init_evaluate = __esm(() => {
41228
41552
  };
41229
41553
  });
41230
41554
 
41555
+ // ../../packages/core/src/quality/replay.ts
41556
+ function scoreExact(output2, reference) {
41557
+ const normOut = normalize(output2);
41558
+ const normRef = normalize(reference);
41559
+ if (normOut === normRef)
41560
+ return 1;
41561
+ if (normOut.includes(normRef))
41562
+ return 1;
41563
+ return 0;
41564
+ }
41565
+ function scoreRule(output2, judge, toolsCalled) {
41566
+ for (const check2 of judge.checks) {
41567
+ if (!evaluateCheck(output2, check2.op, check2.arg, toolsCalled))
41568
+ return 0;
41569
+ }
41570
+ return 1;
41571
+ }
41572
+ function aggregateHard(scores) {
41573
+ if (scores.length === 0)
41574
+ return 0;
41575
+ const sum = scores.reduce((acc, s) => acc + s, 0);
41576
+ return sum / scores.length;
41577
+ }
41578
+ function normalize(text) {
41579
+ return text.trim().toLowerCase().replace(/\s+/g, " ");
41580
+ }
41581
+ function evaluateCheck(output2, op, arg, toolsCalled) {
41582
+ switch (op) {
41583
+ case "contains":
41584
+ return output2.toLowerCase().includes(arg.toLowerCase());
41585
+ case "regex": {
41586
+ try {
41587
+ return new RegExp(arg).test(output2);
41588
+ } catch {
41589
+ return false;
41590
+ }
41591
+ }
41592
+ case "equals":
41593
+ return normalize(output2) === normalize(arg);
41594
+ case "not_contains":
41595
+ return !output2.toLowerCase().includes(arg.toLowerCase());
41596
+ case "tool_called":
41597
+ return (toolsCalled ?? []).includes(arg);
41598
+ default:
41599
+ return false;
41600
+ }
41601
+ }
41602
+
41231
41603
  // ../../packages/core/src/quality/rubric.ts
41232
- import { existsSync as existsSync10, readFileSync as readFileSync9 } from "fs";
41233
- import { homedir as homedir3 } from "os";
41234
- import { join as join8 } from "path";
41604
+ import { existsSync as existsSync11, readFileSync as readFileSync10 } from "fs";
41605
+ import { homedir as homedir4 } from "os";
41606
+ import { join as join9 } from "path";
41235
41607
  function resolveRubricContent(type, opts) {
41236
41608
  if (opts?.path) {
41237
- if (!existsSync10(opts.path)) {
41609
+ if (!existsSync11(opts.path)) {
41238
41610
  throw new RubricError("path", `Rubric file not found: ${opts.path}`, opts.path);
41239
41611
  }
41240
- return readFileSync9(opts.path, "utf-8");
41612
+ return readFileSync10(opts.path, "utf-8");
41241
41613
  }
41242
- const homeDir = process.env.HOME ?? homedir3();
41243
- const userPath = join8(homeDir, ".superskill", "rubrics", `${type}.yaml`);
41244
- if (existsSync10(userPath)) {
41245
- return readFileSync9(userPath, "utf-8");
41614
+ const homeDir = process.env.HOME || homedir4();
41615
+ const userPath = join9(homeDir, ".superskill", "rubrics", `${type}.yaml`);
41616
+ if (existsSync11(userPath)) {
41617
+ return readFileSync10(userPath, "utf-8");
41246
41618
  }
41247
- const devPath = join8(import.meta.dir, "..", "rubrics", `${type}.yaml`);
41248
- if (existsSync10(devPath)) {
41249
- return readFileSync9(devPath, "utf-8");
41619
+ const devPath = join9(import.meta.dir, "..", "rubrics", `${type}.yaml`);
41620
+ if (existsSync11(devPath)) {
41621
+ return readFileSync10(devPath, "utf-8");
41250
41622
  }
41251
- const prodPath = join8(import.meta.dir, "..", "..", "rubrics", `${type}.yaml`);
41252
- if (existsSync10(prodPath)) {
41253
- return readFileSync9(prodPath, "utf-8");
41623
+ const prodPath = join9(import.meta.dir, "..", "..", "rubrics", `${type}.yaml`);
41624
+ if (existsSync11(prodPath)) {
41625
+ return readFileSync10(prodPath, "utf-8");
41254
41626
  }
41255
41627
  throw new RubricError("path", `No rubric found for type "${type}". Searched: ${opts?.path ?? "(no explicit path)"}, ${userPath}, ${devPath}, ${prodPath}`, type);
41256
41628
  }
@@ -47079,11 +47451,11 @@ var require_out = __commonJS((exports) => {
47079
47451
  async.read(path7, getSettings(optionsOrSettingsOrCallback), callback);
47080
47452
  }
47081
47453
  exports.stat = stat;
47082
- function statSync7(path7, optionsOrSettings) {
47454
+ function statSync6(path7, optionsOrSettings) {
47083
47455
  const settings = getSettings(optionsOrSettings);
47084
47456
  return sync.read(path7, settings);
47085
47457
  }
47086
- exports.statSync = statSync7;
47458
+ exports.statSync = statSync6;
47087
47459
  function getSettings(settingsOrOptions = {}) {
47088
47460
  if (settingsOrOptions instanceof settings_1.default) {
47089
47461
  return settingsOrOptions;
@@ -47487,11 +47859,11 @@ var require_reusify = __commonJS((exports, module) => {
47487
47859
  // ../../node_modules/.bun/fastq@1.20.1/node_modules/fastq/queue.js
47488
47860
  var require_queue = __commonJS((exports, module) => {
47489
47861
  var reusify = require_reusify();
47490
- function fastqueue(context2, worker, _concurrency) {
47491
- if (typeof context2 === "function") {
47862
+ function fastqueue(context3, worker, _concurrency) {
47863
+ if (typeof context3 === "function") {
47492
47864
  _concurrency = worker;
47493
- worker = context2;
47494
- context2 = null;
47865
+ worker = context3;
47866
+ context3 = null;
47495
47867
  }
47496
47868
  if (!(_concurrency >= 1)) {
47497
47869
  throw new Error("fastqueue concurrency must be equal to or greater than 1");
@@ -47578,7 +47950,7 @@ var require_queue = __commonJS((exports, module) => {
47578
47950
  }
47579
47951
  function push(value, done) {
47580
47952
  var current = cache.get();
47581
- current.context = context2;
47953
+ current.context = context3;
47582
47954
  current.release = release;
47583
47955
  current.value = value;
47584
47956
  current.callback = done || noop4;
@@ -47594,12 +47966,12 @@ var require_queue = __commonJS((exports, module) => {
47594
47966
  }
47595
47967
  } else {
47596
47968
  _running++;
47597
- worker.call(context2, current.value, current.worked);
47969
+ worker.call(context3, current.value, current.worked);
47598
47970
  }
47599
47971
  }
47600
47972
  function unshift(value, done) {
47601
47973
  var current = cache.get();
47602
- current.context = context2;
47974
+ current.context = context3;
47603
47975
  current.release = release;
47604
47976
  current.value = value;
47605
47977
  current.callback = done || noop4;
@@ -47615,7 +47987,7 @@ var require_queue = __commonJS((exports, module) => {
47615
47987
  }
47616
47988
  } else {
47617
47989
  _running++;
47618
- worker.call(context2, current.value, current.worked);
47990
+ worker.call(context3, current.value, current.worked);
47619
47991
  }
47620
47992
  }
47621
47993
  function release(holder) {
@@ -47630,7 +48002,7 @@ var require_queue = __commonJS((exports, module) => {
47630
48002
  }
47631
48003
  queueHead = next.next;
47632
48004
  next.next = null;
47633
- worker.call(context2, next.value, next.worked);
48005
+ worker.call(context3, next.value, next.worked);
47634
48006
  if (queueTail === null) {
47635
48007
  self2.empty();
47636
48008
  }
@@ -47661,14 +48033,14 @@ var require_queue = __commonJS((exports, module) => {
47661
48033
  var callback = current.callback;
47662
48034
  var errorHandler2 = current.errorHandler;
47663
48035
  var val = current.value;
47664
- var context3 = current.context;
48036
+ var context4 = current.context;
47665
48037
  current.value = null;
47666
48038
  current.callback = noop4;
47667
48039
  current.errorHandler = null;
47668
48040
  if (errorHandler2) {
47669
48041
  errorHandler2(new Error("abort"), val);
47670
48042
  }
47671
- callback.call(context3, new Error("abort"));
48043
+ callback.call(context4, new Error("abort"));
47672
48044
  current.release(current);
47673
48045
  current = next;
47674
48046
  }
@@ -47700,18 +48072,18 @@ var require_queue = __commonJS((exports, module) => {
47700
48072
  self2.release(self2);
47701
48073
  };
47702
48074
  }
47703
- function queueAsPromised(context2, worker, _concurrency) {
47704
- if (typeof context2 === "function") {
48075
+ function queueAsPromised(context3, worker, _concurrency) {
48076
+ if (typeof context3 === "function") {
47705
48077
  _concurrency = worker;
47706
- worker = context2;
47707
- context2 = null;
48078
+ worker = context3;
48079
+ context3 = null;
47708
48080
  }
47709
48081
  function asyncWrapper(arg, cb) {
47710
48082
  worker.call(this, arg).then(function(res) {
47711
48083
  cb(null, res);
47712
48084
  }, cb);
47713
48085
  }
47714
- var queue = fastqueue(context2, asyncWrapper, _concurrency);
48086
+ var queue = fastqueue(context3, asyncWrapper, _concurrency);
47715
48087
  var pushCb = queue.push;
47716
48088
  var unshiftCb = queue.unshift;
47717
48089
  queue.push = push;
@@ -47719,42 +48091,42 @@ var require_queue = __commonJS((exports, module) => {
47719
48091
  queue.drained = drained;
47720
48092
  return queue;
47721
48093
  function push(value) {
47722
- var p = new Promise(function(resolve2, reject) {
48094
+ var p = new Promise(function(resolve3, reject) {
47723
48095
  pushCb(value, function(err, result) {
47724
48096
  if (err) {
47725
48097
  reject(err);
47726
48098
  return;
47727
48099
  }
47728
- resolve2(result);
48100
+ resolve3(result);
47729
48101
  });
47730
48102
  });
47731
48103
  p.catch(noop4);
47732
48104
  return p;
47733
48105
  }
47734
48106
  function unshift(value) {
47735
- var p = new Promise(function(resolve2, reject) {
48107
+ var p = new Promise(function(resolve3, reject) {
47736
48108
  unshiftCb(value, function(err, result) {
47737
48109
  if (err) {
47738
48110
  reject(err);
47739
48111
  return;
47740
48112
  }
47741
- resolve2(result);
48113
+ resolve3(result);
47742
48114
  });
47743
48115
  });
47744
48116
  p.catch(noop4);
47745
48117
  return p;
47746
48118
  }
47747
48119
  function drained() {
47748
- var p = new Promise(function(resolve2) {
48120
+ var p = new Promise(function(resolve3) {
47749
48121
  process.nextTick(function() {
47750
48122
  if (queue.idle()) {
47751
- resolve2();
48123
+ resolve3();
47752
48124
  } else {
47753
48125
  var previousDrain = queue.drain;
47754
48126
  queue.drain = function() {
47755
48127
  if (typeof previousDrain === "function")
47756
48128
  previousDrain();
47757
- resolve2();
48129
+ resolve3();
47758
48130
  queue.drain = previousDrain;
47759
48131
  };
47760
48132
  }
@@ -48215,9 +48587,9 @@ var require_stream3 = __commonJS((exports) => {
48215
48587
  });
48216
48588
  }
48217
48589
  _getStat(filepath) {
48218
- return new Promise((resolve2, reject) => {
48590
+ return new Promise((resolve3, reject) => {
48219
48591
  this._stat(filepath, this._fsStatSettings, (error51, stats) => {
48220
- return error51 === null ? resolve2(stats) : reject(error51);
48592
+ return error51 === null ? resolve3(stats) : reject(error51);
48221
48593
  });
48222
48594
  });
48223
48595
  }
@@ -48239,10 +48611,10 @@ var require_async5 = __commonJS((exports) => {
48239
48611
  this._readerStream = new stream_1.default(this._settings);
48240
48612
  }
48241
48613
  dynamic(root, options2) {
48242
- return new Promise((resolve2, reject) => {
48614
+ return new Promise((resolve3, reject) => {
48243
48615
  this._walkAsync(root, options2, (error51, entries) => {
48244
48616
  if (error51 === null) {
48245
- resolve2(entries);
48617
+ resolve3(entries);
48246
48618
  } else {
48247
48619
  reject(error51);
48248
48620
  }
@@ -48252,10 +48624,10 @@ var require_async5 = __commonJS((exports) => {
48252
48624
  async static(patterns, options2) {
48253
48625
  const entries = [];
48254
48626
  const stream = this._readerStream.static(patterns, options2);
48255
- return new Promise((resolve2, reject) => {
48627
+ return new Promise((resolve3, reject) => {
48256
48628
  stream.once("error", reject);
48257
48629
  stream.on("data", (entry) => entries.push(entry));
48258
- stream.once("end", () => resolve2(entries));
48630
+ stream.once("end", () => resolve3(entries));
48259
48631
  });
48260
48632
  }
48261
48633
  }
@@ -49783,7 +50155,7 @@ var import_fast_glob2, import_ignore, defaultIgnoredDirectories, ignoreFilesGlob
49783
50155
  }
49784
50156
  throw createGitConfigReadError(normalizedPath, error51);
49785
50157
  }
49786
- }, getExcludesFileFromGitConfigSync = (filePath, readFileSync10, gitDirectory, options2 = {}) => {
50158
+ }, getExcludesFileFromGitConfigSync = (filePath, readFileSync11, gitDirectory, options2 = {}) => {
49787
50159
  const { suppressErrors, includeStack = new Set, depth = 0 } = options2;
49788
50160
  const normalizedPath = path9.resolve(filePath);
49789
50161
  if (includeStack.has(normalizedPath)) {
@@ -49793,14 +50165,14 @@ var import_fast_glob2, import_ignore, defaultIgnoredDirectories, ignoreFilesGlob
49793
50165
  return;
49794
50166
  }
49795
50167
  includeStack.add(normalizedPath);
49796
- const content = readGitConfigFile(normalizedPath, readFileSync10, suppressErrors);
50168
+ const content = readGitConfigFile(normalizedPath, readFileSync11, suppressErrors);
49797
50169
  if (content === undefined) {
49798
50170
  includeStack.delete(normalizedPath);
49799
50171
  return;
49800
50172
  }
49801
50173
  let { excludesFile, includePaths } = parseGitConfigForExcludesFile(content, normalizedPath, gitDirectory);
49802
50174
  for (const includePath of includePaths) {
49803
- const includedExcludesFile = getExcludesFileFromGitConfigSync(includePath, readFileSync10, gitDirectory, { suppressErrors, includeStack, depth: depth + 1 });
50175
+ const includedExcludesFile = getExcludesFileFromGitConfigSync(includePath, readFileSync11, gitDirectory, { suppressErrors, includeStack, depth: depth + 1 });
49804
50176
  if (includedExcludesFile !== undefined) {
49805
50177
  excludesFile = includedExcludesFile;
49806
50178
  }
@@ -49842,13 +50214,13 @@ var import_fast_glob2, import_ignore, defaultIgnoredDirectories, ignoreFilesGlob
49842
50214
  return gitFilePath;
49843
50215
  }
49844
50216
  return path9.resolve(path9.dirname(gitFilePath), match[1]);
49845
- }, getGitDirectorySync = (gitRoot, readFileSync10) => {
50217
+ }, getGitDirectorySync = (gitRoot, readFileSync11) => {
49846
50218
  if (!gitRoot) {
49847
50219
  return;
49848
50220
  }
49849
50221
  const gitFilePath = path9.join(gitRoot, ".git");
49850
50222
  try {
49851
- return resolveGitDirectoryFromFile(gitFilePath, readFileSync10(gitFilePath, "utf8"));
50223
+ return resolveGitDirectoryFromFile(gitFilePath, readFileSync11(gitFilePath, "utf8"));
49852
50224
  } catch {
49853
50225
  return gitFilePath;
49854
50226
  }
@@ -49891,18 +50263,18 @@ var import_fast_glob2, import_ignore, defaultIgnoredDirectories, ignoreFilesGlob
49891
50263
  }
49892
50264
  }, getGlobalGitignoreFile = (options2 = {}) => {
49893
50265
  const cwd5 = toPath2(options2.cwd) ?? process11.cwd();
49894
- const readFileSync10 = getReadFileSyncMethod(options2.fs);
50266
+ const readFileSync11 = getReadFileSyncMethod(options2.fs);
49895
50267
  const gitRoot = findGitRootSync(cwd5, options2.fs);
49896
- const gitDirectory = getGitDirectorySync(gitRoot, readFileSync10);
50268
+ const gitDirectory = getGitDirectorySync(gitRoot, readFileSync11);
49897
50269
  let excludesFileConfig;
49898
50270
  for (const gitConfigPath of getGitConfigPaths()) {
49899
- const value = getExcludesFileFromGitConfigSync(gitConfigPath, readFileSync10, gitDirectory, { suppressErrors: options2.suppressErrors });
50271
+ const value = getExcludesFileFromGitConfigSync(gitConfigPath, readFileSync11, gitDirectory, { suppressErrors: options2.suppressErrors });
49900
50272
  if (value !== undefined) {
49901
50273
  excludesFileConfig = value;
49902
50274
  }
49903
50275
  }
49904
50276
  const filePath = resolveExcludesFilePath(excludesFileConfig);
49905
- return filePath === undefined ? undefined : readGlobalGitignoreContent(filePath, readFileSync10, options2.suppressErrors);
50277
+ return filePath === undefined ? undefined : readGlobalGitignoreContent(filePath, readFileSync11, options2.suppressErrors);
49906
50278
  }, getGlobalGitignoreFileAsync = async (options2 = {}) => {
49907
50279
  const cwd5 = toPath2(options2.cwd) ?? process11.cwd();
49908
50280
  const readFile = getReadFileMethod(options2.fs);
@@ -58242,7 +58614,7 @@ import {
58242
58614
  writeFile
58243
58615
  } from "fs/promises";
58244
58616
  import os2 from "os";
58245
- import { dirname as dirname6, isAbsolute, join as join22, relative, resolve as resolve2 } from "path";
58617
+ import { dirname as dirname6, isAbsolute, join as join22, relative, resolve as resolve4 } from "path";
58246
58618
  import { isAbsolute as isAbsolute2, resolve as resolve22 } from "path";
58247
58619
  import { basename as basename3, join as join44, relative as relative3 } from "path";
58248
58620
  import { extname as extname2 } from "path";
@@ -58250,8 +58622,8 @@ import { isDeepStrictEqual } from "util";
58250
58622
  import { join as join62 } from "path";
58251
58623
  import { join as join42 } from "path";
58252
58624
  import { join as join52 } from "path";
58253
- import path10, { relative as relative2, resolve as resolve4 } from "path";
58254
- import { basename as basename4, join as join9 } from "path";
58625
+ import path10, { relative as relative2, resolve as resolve42 } from "path";
58626
+ import { basename as basename4, join as join92 } from "path";
58255
58627
  import { join as join72 } from "path";
58256
58628
  import { join as join82 } from "path";
58257
58629
  import { join as join10 } from "path";
@@ -58335,7 +58707,7 @@ import { join as join88 } from "path";
58335
58707
  import { join as join89 } from "path";
58336
58708
  import { join as join90 } from "path";
58337
58709
  import { join as join91 } from "path";
58338
- import { join as join92 } from "path";
58710
+ import { join as join922 } from "path";
58339
58711
  import { join as join93 } from "path";
58340
58712
  import { join as join94 } from "path";
58341
58713
  import { join as join95 } from "path";
@@ -58510,9 +58882,9 @@ function checkPathTraversal({
58510
58882
  if (segments.includes("..")) {
58511
58883
  throw new Error(`Path traversal detected: ${relativePath}`);
58512
58884
  }
58513
- const resolved = resolve2(intendedRootDir, relativePath);
58885
+ const resolved = resolve4(intendedRootDir, relativePath);
58514
58886
  const rel = relative(intendedRootDir, resolved);
58515
- if (rel.startsWith("..") || resolve2(resolved) !== resolved) {
58887
+ if (rel.startsWith("..") || resolve4(resolved) !== resolved) {
58516
58888
  throw new Error(`Path traversal detected: ${relativePath}`);
58517
58889
  }
58518
58890
  }
@@ -58520,7 +58892,7 @@ function resolvePath3(relativePath, outputRoot) {
58520
58892
  if (!outputRoot)
58521
58893
  return relativePath;
58522
58894
  checkPathTraversal({ relativePath, intendedRootDir: outputRoot });
58523
- return resolve2(outputRoot, relativePath);
58895
+ return resolve4(outputRoot, relativePath);
58524
58896
  }
58525
58897
  async function directoryExists(dirPath) {
58526
58898
  try {
@@ -58633,7 +59005,7 @@ function validateOutputRoot(outputRoot) {
58633
59005
  if (segments.includes("..")) {
58634
59006
  throw new Error(`Path traversal detected: ${outputRoot}`);
58635
59007
  }
58636
- const normalized = resolve2(outputRoot);
59008
+ const normalized = resolve4(outputRoot);
58637
59009
  if (normalized !== outputRoot) {
58638
59010
  throw new Error(`outputRoot must be a normalized absolute path: ${outputRoot} (normalized: ${normalized})`);
58639
59011
  }
@@ -63025,8 +63397,8 @@ var import_gray_matter, BaseLogger = class {
63025
63397
  }
63026
63398
  getFilePath() {
63027
63399
  const fullPath = path10.join(this.outputRoot, this.relativeDirPath, this.relativeFilePath);
63028
- const resolvedFull = resolve4(fullPath);
63029
- const resolvedBase = resolve4(this.outputRoot);
63400
+ const resolvedFull = resolve42(fullPath);
63401
+ const resolvedBase = resolve42(this.outputRoot);
63030
63402
  const rel = relative2(resolvedBase, resolvedFull);
63031
63403
  if (rel.startsWith("..") || path10.isAbsolute(rel)) {
63032
63404
  throw new Error(`Path traversal detected: Final path escapes outputRoot. outputRoot="${this.outputRoot}", relativeDirPath="${this.relativeDirPath}", relativeFilePath="${this.relativeFilePath}"`);
@@ -63958,7 +64330,7 @@ var init_chunk_QKQNZ6C3 = __esm(() => {
63958
64330
  if (rest2.validate) {
63959
64331
  const result = AntigravityCommandFrontmatterSchema.safeParse(frontmatter);
63960
64332
  if (!result.success) {
63961
- throw new Error(`Invalid frontmatter in ${join9(rest2.relativeDirPath, rest2.relativeFilePath)}: ${formatError2(result.error)}`);
64333
+ throw new Error(`Invalid frontmatter in ${join92(rest2.relativeDirPath, rest2.relativeFilePath)}: ${formatError2(result.error)}`);
63962
64334
  }
63963
64335
  }
63964
64336
  super({
@@ -64054,7 +64426,7 @@ ${body}${turboDirective}`;
64054
64426
  } else {
64055
64427
  return {
64056
64428
  success: false,
64057
- error: new Error(`Invalid frontmatter in ${join9(this.relativeDirPath, this.relativeFilePath)}: ${formatError2(result.error)}`)
64429
+ error: new Error(`Invalid frontmatter in ${join92(this.relativeDirPath, this.relativeFilePath)}: ${formatError2(result.error)}`)
64058
64430
  };
64059
64431
  }
64060
64432
  }
@@ -64069,7 +64441,7 @@ ${body}${turboDirective}`;
64069
64441
  relativeFilePath,
64070
64442
  validate: validate2 = true
64071
64443
  }) {
64072
- const filePath = join9(outputRoot, _AntigravityCommand.getSettablePaths().relativeDirPath, relativeFilePath);
64444
+ const filePath = join92(outputRoot, _AntigravityCommand.getSettablePaths().relativeDirPath, relativeFilePath);
64073
64445
  const fileContent = await readFileContent(filePath);
64074
64446
  const { frontmatter, body: content } = parseFrontmatter2(fileContent, filePath);
64075
64447
  const result = AntigravityCommandFrontmatterSchema.safeParse(frontmatter);
@@ -71258,7 +71630,7 @@ prompt = ""`;
71258
71630
  try {
71259
71631
  this.json = JSON.parse(this.fileContent);
71260
71632
  } catch (error51) {
71261
- throw new Error(`Failed to parse Cursor MCP config at ${join92(this.relativeDirPath, this.relativeFilePath)}: ${formatError2(error51)}`, { cause: error51 });
71633
+ throw new Error(`Failed to parse Cursor MCP config at ${join922(this.relativeDirPath, this.relativeFilePath)}: ${formatError2(error51)}`, { cause: error51 });
71262
71634
  }
71263
71635
  } else {
71264
71636
  this.json = {};
@@ -71282,13 +71654,13 @@ prompt = ""`;
71282
71654
  global: global3 = false
71283
71655
  }) {
71284
71656
  const paths = this.getSettablePaths({ global: global3 });
71285
- const filePath = join92(outputRoot, paths.relativeDirPath, paths.relativeFilePath);
71657
+ const filePath = join922(outputRoot, paths.relativeDirPath, paths.relativeFilePath);
71286
71658
  const fileContent = await readFileContentOrNull(filePath) ?? '{"mcpServers":{}}';
71287
71659
  let json3;
71288
71660
  try {
71289
71661
  json3 = JSON.parse(fileContent);
71290
71662
  } catch (error51) {
71291
- throw new Error(`Failed to parse Cursor MCP config at ${join92(paths.relativeDirPath, paths.relativeFilePath)}: ${formatError2(error51)}`, { cause: error51 });
71663
+ throw new Error(`Failed to parse Cursor MCP config at ${join922(paths.relativeDirPath, paths.relativeFilePath)}: ${formatError2(error51)}`, { cause: error51 });
71292
71664
  }
71293
71665
  const newJson = { ...json3, mcpServers: json3.mcpServers ?? {} };
71294
71666
  return new _CursorMcp({
@@ -71307,12 +71679,12 @@ prompt = ""`;
71307
71679
  global: global3 = false
71308
71680
  }) {
71309
71681
  const paths = this.getSettablePaths({ global: global3 });
71310
- const fileContent = await readOrInitializeFileContent(join92(outputRoot, paths.relativeDirPath, paths.relativeFilePath), JSON.stringify({ mcpServers: {} }, null, 2));
71682
+ const fileContent = await readOrInitializeFileContent(join922(outputRoot, paths.relativeDirPath, paths.relativeFilePath), JSON.stringify({ mcpServers: {} }, null, 2));
71311
71683
  let json3;
71312
71684
  try {
71313
71685
  json3 = JSON.parse(fileContent);
71314
71686
  } catch (error51) {
71315
- throw new Error(`Failed to parse Cursor MCP config at ${join92(paths.relativeDirPath, paths.relativeFilePath)}: ${formatError2(error51)}`, { cause: error51 });
71687
+ throw new Error(`Failed to parse Cursor MCP config at ${join922(paths.relativeDirPath, paths.relativeFilePath)}: ${formatError2(error51)}`, { cause: error51 });
71316
71688
  }
71317
71689
  const mcpServers = rulesyncMcp.getMcpServers();
71318
71690
  const transformedServers = convertEnvVarRefsToToolFormat({
@@ -89292,7 +89664,7 @@ var init_dist9 = __esm(() => {
89292
89664
  });
89293
89665
 
89294
89666
  // ../../packages/core/src/rulesync.ts
89295
- import { homedir as homedir4 } from "os";
89667
+ import { homedir as homedir5 } from "os";
89296
89668
  async function runRulesync(targets, features, inputRoot, options2) {
89297
89669
  const mappedTargets = [];
89298
89670
  for (const target of targets) {
@@ -89322,7 +89694,7 @@ async function runRulesync(targets, features, inputRoot, options2) {
89322
89694
  hasDiff: false
89323
89695
  };
89324
89696
  }
89325
- const root = options2.outputRoot ?? (options2.global ? homedir4() : process.cwd());
89697
+ const root = options2.outputRoot ?? (options2.global ? homedir5() : process.cwd());
89326
89698
  const rulesyncGlobal = options2.outputRoot ? false : options2.global;
89327
89699
  return generate2({
89328
89700
  targets: mappedTargets,
@@ -89361,6 +89733,7 @@ var init_src = __esm(() => {
89361
89733
  init_slash_command2();
89362
89734
  init_agent();
89363
89735
  init_command3();
89736
+ init_eval_cases();
89364
89737
  init_evaluate();
89365
89738
  init_heuristics();
89366
89739
  init_hook();
@@ -89740,7 +90113,7 @@ var init_version = () => {};
89740
90113
 
89741
90114
  // ../../node_modules/.bun/drizzle-orm@0.44.7+a0473b45aab9bf33/node_modules/drizzle-orm/tracing.js
89742
90115
  var otel, rawTracer, tracer;
89743
- var init_tracing = __esm(() => {
90116
+ var init_tracing2 = __esm(() => {
89744
90117
  init_tracing_utils();
89745
90118
  init_version();
89746
90119
  tracer = {
@@ -89830,7 +90203,7 @@ var init_sql = __esm(() => {
89830
90203
  init_entity();
89831
90204
  init_enum();
89832
90205
  init_subquery();
89833
- init_tracing();
90206
+ init_tracing2();
89834
90207
  init_view_common();
89835
90208
  init_column();
89836
90209
  init_table();
@@ -94967,13 +95340,13 @@ __export(exports_db, {
94967
95340
  openStore: () => openStore,
94968
95341
  getDBPath: () => getDBPath
94969
95342
  });
94970
- import { existsSync as existsSync11, mkdirSync as mkdirSync6 } from "fs";
95343
+ import { existsSync as existsSync12, mkdirSync as mkdirSync6 } from "fs";
94971
95344
  import { dirname as dirname7 } from "path";
94972
95345
  async function openStore(opts) {
94973
95346
  const url3 = getDBPath(opts);
94974
95347
  if (url3 !== ":memory:") {
94975
95348
  const dir = dirname7(url3);
94976
- if (!existsSync11(dir)) {
95349
+ if (!existsSync12(dir)) {
94977
95350
  mkdirSync6(dir, { recursive: true });
94978
95351
  }
94979
95352
  }
@@ -95000,7 +95373,7 @@ var init_db2 = __esm(() => {
95000
95373
  });
95001
95374
 
95002
95375
  // src/cli.ts
95003
- import { readFileSync as readFileSync15 } from "fs";
95376
+ import { readFileSync as readFileSync16 } from "fs";
95004
95377
  import { join as join226 } from "path";
95005
95378
 
95006
95379
  // ../../node_modules/.bun/commander@14.0.3/node_modules/commander/esm.mjs
@@ -95026,7 +95399,7 @@ init_dist();
95026
95399
  init_src();
95027
95400
  init_dist();
95028
95401
  init_db2();
95029
- import { readFileSync as readFileSync10 } from "fs";
95402
+ import { readFileSync as readFileSync11 } from "fs";
95030
95403
 
95031
95404
  // src/store/evaluations.ts
95032
95405
  init_dist10();
@@ -95222,7 +95595,7 @@ async function ingestScores(type, resolvedPath, resolvedTarget, opts) {
95222
95595
  }
95223
95596
  let raw;
95224
95597
  try {
95225
- raw = readFileSync10(ingestPath, "utf-8");
95598
+ raw = readFileSync11(ingestPath, "utf-8");
95226
95599
  } catch {
95227
95600
  throw Object.assign(new Error(`Cannot read scores file: ${ingestPath}`), { code: 2 });
95228
95601
  }
@@ -95342,7 +95715,7 @@ function formatEvaluationReport(report, json3) {
95342
95715
  // src/operations/evolve.ts
95343
95716
  init_src();
95344
95717
  init_dist();
95345
- import { existsSync as existsSync12, mkdirSync as mkdirSync7, readFileSync as readFileSync11, rmSync as rmSync4, writeFileSync as writeFileSync6 } from "fs";
95718
+ import { existsSync as existsSync13, mkdirSync as mkdirSync7, readFileSync as readFileSync12, rmSync as rmSync5, writeFileSync as writeFileSync6 } from "fs";
95346
95719
  import { join as join220 } from "path";
95347
95720
  import { createInterface } from "readline";
95348
95721
 
@@ -95410,6 +95783,149 @@ function deserializeProposal(row) {
95410
95783
  };
95411
95784
  }
95412
95785
 
95786
+ // src/operations/pairwise-judge.ts
95787
+ init_src();
95788
+ init_dist5();
95789
+ class TsAiRunnerJudgeBackend {
95790
+ runner;
95791
+ agent;
95792
+ constructor(agent2 = "claude", runner) {
95793
+ this.runner = runner ?? new AiRunner;
95794
+ this.agent = agent2;
95795
+ }
95796
+ async judge(rubric2, prompt, candOutput, baseOutput, options2) {
95797
+ const candidateFirst = options2?.order !== "baseline-first";
95798
+ const outputA = candidateFirst ? candOutput : baseOutput;
95799
+ const outputB = candidateFirst ? baseOutput : candOutput;
95800
+ const systemPrompt = [
95801
+ "You are a strict pairwise behavior judge.",
95802
+ "Compare two outputs for the same task against the rubric criterion.",
95803
+ 'Return only JSON: {"winner":"A"|"B"|"tie","margin":number}.',
95804
+ "The margin must be a number from 0 to 1."
95805
+ ].join(`
95806
+ `);
95807
+ const input = [
95808
+ `Criterion: ${rubric2.criterion}`,
95809
+ rubric2.excellent ? `Excellent anchor: ${rubric2.excellent}` : "",
95810
+ rubric2.poor ? `Poor anchor: ${rubric2.poor}` : "",
95811
+ `Task prompt:
95812
+ ${prompt}`,
95813
+ `Output A:
95814
+ ${outputA}`,
95815
+ `Output B:
95816
+ ${outputB}`
95817
+ ].filter(Boolean).join(`
95818
+
95819
+ `);
95820
+ const result = await this.runner.runPromptCommand(this.agent, {
95821
+ input,
95822
+ systemPrompt,
95823
+ ...options2?.seed !== undefined ? { seed: options2.seed } : {},
95824
+ ...options2?.temperature !== undefined ? { temperature: options2.temperature } : {}
95825
+ });
95826
+ return parseJudgeResponse(result.stdout, candidateFirst);
95827
+ }
95828
+ }
95829
+ function createJudgeBackend(target, injected) {
95830
+ return injected ?? new TsAiRunnerJudgeBackend(TARGET_TO_AGENT_NAME[target]);
95831
+ }
95832
+ async function pairwiseJudge(backend, rubric2, casePrompt, candOutput, baseOutput, options2 = {}) {
95833
+ const order = options2.order ?? (options2.seed !== undefined && options2.seed % 2 === 1 ? "baseline-first" : "candidate-first");
95834
+ return backend.judge(rubric2, casePrompt, candOutput, baseOutput, { ...options2, order });
95835
+ }
95836
+ function signedMargin(verdict) {
95837
+ if (verdict.winner === "candidate")
95838
+ return verdict.margin;
95839
+ if (verdict.winner === "baseline")
95840
+ return -verdict.margin;
95841
+ return 0;
95842
+ }
95843
+ function parseJudgeResponse(stdout, candidateFirst) {
95844
+ let parsed;
95845
+ try {
95846
+ parsed = JSON.parse(stdout.trim());
95847
+ } catch {
95848
+ throw new Error(`Pairwise judge returned invalid JSON: ${stdout.slice(0, 200)}`);
95849
+ }
95850
+ if (typeof parsed !== "object" || parsed === null) {
95851
+ throw new Error("Pairwise judge returned a non-object JSON payload.");
95852
+ }
95853
+ const value = parsed;
95854
+ if (value.winner !== "A" && value.winner !== "B" && value.winner !== "tie") {
95855
+ throw new Error('Pairwise judge JSON must include winner "A", "B", or "tie".');
95856
+ }
95857
+ if (typeof value.margin !== "number" || value.margin < 0 || value.margin > 1) {
95858
+ throw new Error("Pairwise judge JSON must include margin in [0,1].");
95859
+ }
95860
+ if (value.winner === "tie")
95861
+ return { winner: "tie", margin: 0 };
95862
+ if (value.winner === "A") {
95863
+ return { winner: candidateFirst ? "candidate" : "baseline", margin: value.margin };
95864
+ }
95865
+ return { winner: candidateFirst ? "baseline" : "candidate", margin: value.margin };
95866
+ }
95867
+
95868
+ // src/operations/noise-floor.ts
95869
+ async function estimateNoiseFloor(judge, rubric2, casePrompt, candOutput, baseOutput, n2 = 5) {
95870
+ const margins = [];
95871
+ for (let i2 = 0;i2 < n2; i2++) {
95872
+ const verdict = await pairwiseJudge(judge, rubric2, casePrompt, candOutput, baseOutput, {
95873
+ seed: i2 + 1,
95874
+ temperature: 0
95875
+ });
95876
+ margins.push(signedMargin(verdict));
95877
+ }
95878
+ if (margins.length < 2)
95879
+ return 0;
95880
+ const mean2 = margins.reduce((a2, b) => a2 + b, 0) / margins.length;
95881
+ const variance = margins.reduce((sum2, m) => sum2 + (m - mean2) ** 2, 0) / margins.length;
95882
+ return Math.sqrt(variance);
95883
+ }
95884
+ function rejectsWithinNoise(measuredDelta, noiseFloor) {
95885
+ return Math.abs(measuredDelta) < noiseFloor;
95886
+ }
95887
+
95888
+ // src/operations/replay-runner.ts
95889
+ init_src();
95890
+ init_dist5();
95891
+ class TsAiRunnerBackend {
95892
+ runner;
95893
+ agent;
95894
+ constructor(agent2 = "claude", runner) {
95895
+ this.runner = runner ?? new AiRunner;
95896
+ this.agent = agent2;
95897
+ }
95898
+ async run(systemPrompt, userPrompt) {
95899
+ const result = await this.runner.runPromptCommand(this.agent, {
95900
+ input: userPrompt,
95901
+ systemPrompt
95902
+ });
95903
+ return result.stdout;
95904
+ }
95905
+ }
95906
+ function createReplayBackend(target, injected) {
95907
+ return injected ?? new TsAiRunnerBackend(TARGET_TO_AGENT_NAME[target]);
95908
+ }
95909
+ async function replayCase(backend, skill2, ev, toolsCalled) {
95910
+ const prompt = `[case:${ev.id}] ${ev.prompt}`;
95911
+ const output2 = await backend.run(skill2, prompt);
95912
+ let hard;
95913
+ if (ev.reference_kind === "exact") {
95914
+ hard = scoreExact(output2, ev.reference);
95915
+ } else {
95916
+ hard = scoreRule(output2, ev.reference, toolsCalled);
95917
+ }
95918
+ return { hard, output: output2 };
95919
+ }
95920
+ async function replaySplit(backend, skill2, cases, split, toolsCalled) {
95921
+ const splitCases = cases.filter((c3) => c3.split === split);
95922
+ if (splitCases.length === 0)
95923
+ return { hard: 0, n: 0 };
95924
+ const results = await Promise.all(splitCases.map((c3) => replayCase(backend, skill2, c3, toolsCalled)));
95925
+ const scores = results.map((r) => r.hard);
95926
+ return { hard: aggregateHard(scores), n: splitCases.length };
95927
+ }
95928
+
95413
95929
  // src/operations/validate.ts
95414
95930
  init_src();
95415
95931
 
@@ -95591,6 +96107,106 @@ async function runGate(input) {
95591
96107
  reason: `\u0394-margin gate failed: \u0394${delta >= 0 ? "+" : ""}${delta.toFixed(2)} < required margin ${input.margin.toFixed(2)}.`
95592
96108
  };
95593
96109
  }
96110
+ let empiricalScores;
96111
+ if (input.evalGate) {
96112
+ const cases = loadEvalCases(input.evalGate.name);
96113
+ if (cases) {
96114
+ const holdout = cases.cases.filter((c3) => c3.split === "holdout");
96115
+ const rubricCases = holdout.filter((c3) => c3.reference_kind === "rubric");
96116
+ const detCases = holdout.filter((c3) => c3.reference_kind !== "rubric");
96117
+ const maxModelCalls = input.evalGate.judgeBudget?.maxModelCalls ?? Number.POSITIVE_INFINITY;
96118
+ let modelCalls = 0;
96119
+ const consumeModelCalls = (count3, reason) => {
96120
+ modelCalls += count3;
96121
+ if (modelCalls > maxModelCalls) {
96122
+ return {
96123
+ ok: false,
96124
+ failedGate: "empirical",
96125
+ reason: `Empirical gate budget cap hit: ${modelCalls} model call(s) for ${reason} exceeds max ${maxModelCalls}.`
96126
+ };
96127
+ }
96128
+ return null;
96129
+ };
96130
+ const replayBackend = createReplayBackend(input.evalGate.target, input.evalGate.replayBackend);
96131
+ let detBaseScore = 0;
96132
+ let detCandScore = 0;
96133
+ let detN = 0;
96134
+ if (detCases.length > 0) {
96135
+ const budgetResult = consumeModelCalls(detCases.length * 2, "deterministic replay");
96136
+ if (budgetResult)
96137
+ return budgetResult;
96138
+ const baseDet = await replaySplit(replayBackend, input.evalGate.baselineSkillText, detCases, "holdout");
96139
+ const candDet = await replaySplit(replayBackend, input.evalGate.candidateSkillText, detCases, "holdout");
96140
+ detBaseScore = baseDet.hard;
96141
+ detCandScore = candDet.hard;
96142
+ detN = detCases.length;
96143
+ }
96144
+ let rubricBaseScore = 0;
96145
+ let rubricCandScore = 0;
96146
+ let maxNoiseFloor = 0;
96147
+ let signedDeltaTotal = 0;
96148
+ let rubricN = 0;
96149
+ if (rubricCases.length > 0) {
96150
+ const judge = createJudgeBackend(input.evalGate.target, input.evalGate.judgeBackend);
96151
+ const judgeReplays = input.evalGate.judgeReplays ?? 3;
96152
+ for (const rc of rubricCases) {
96153
+ const replayBudget = consumeModelCalls(2, `rubric replay for ${rc.id}`);
96154
+ if (replayBudget)
96155
+ return replayBudget;
96156
+ const prompt = `[case:${rc.id}] ${rc.prompt}`;
96157
+ const [candOutput, baseOutput] = await Promise.all([
96158
+ replayBackend.run(input.evalGate.candidateSkillText, prompt),
96159
+ replayBackend.run(input.evalGate.baselineSkillText, prompt)
96160
+ ]);
96161
+ const rubricRef = rc.reference;
96162
+ const judgeBudget = consumeModelCalls(1, `pairwise rubric judge for ${rc.id}`);
96163
+ if (judgeBudget)
96164
+ return judgeBudget;
96165
+ const verdict = await pairwiseJudge(judge, rubricRef, prompt, candOutput, baseOutput, {
96166
+ seed: 0,
96167
+ temperature: 0
96168
+ });
96169
+ const noiseBudget = consumeModelCalls(judgeReplays, `noise-floor replay for ${rc.id}`);
96170
+ if (noiseBudget)
96171
+ return noiseBudget;
96172
+ const noiseFloor = await estimateNoiseFloor(judge, rubricRef, prompt, candOutput, baseOutput, judgeReplays);
96173
+ const delta2 = signedMargin(verdict);
96174
+ maxNoiseFloor = Math.max(maxNoiseFloor, noiseFloor);
96175
+ signedDeltaTotal += delta2;
96176
+ if (rejectsWithinNoise(delta2, noiseFloor)) {
96177
+ rubricCandScore += 0.5;
96178
+ rubricBaseScore += 0.5;
96179
+ } else if (verdict.winner === "candidate") {
96180
+ rubricCandScore += 1;
96181
+ } else if (verdict.winner === "baseline") {
96182
+ rubricBaseScore += 1;
96183
+ } else {
96184
+ rubricCandScore += 0.5;
96185
+ rubricBaseScore += 0.5;
96186
+ }
96187
+ rubricN++;
96188
+ }
96189
+ }
96190
+ const totalN = detN + rubricN;
96191
+ const baseHard = totalN > 0 ? (detBaseScore * detN + rubricBaseScore / Math.max(rubricN, 1) * rubricN) / totalN : 0;
96192
+ const candHard = totalN > 0 ? (detCandScore * detN + rubricCandScore / Math.max(rubricN, 1) * rubricN) / totalN : 0;
96193
+ const rubricDelta = rubricN > 0 ? signedDeltaTotal / rubricN : undefined;
96194
+ if (!(candHard > baseHard && candHard - baseHard >= input.evalGate.margin)) {
96195
+ return {
96196
+ ok: false,
96197
+ failedGate: "empirical",
96198
+ 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)}` : ""}).`
96199
+ };
96200
+ }
96201
+ const trainCases = cases.cases.filter((c3) => c3.split === "train");
96202
+ empiricalScores = {
96203
+ hard: candHard,
96204
+ holdout_n: totalN,
96205
+ train_n: trainCases.length,
96206
+ ...rubricN > 0 ? { noise_floor: maxNoiseFloor, rubric_delta: rubricDelta ?? 0 } : {}
96207
+ };
96208
+ }
96209
+ }
95594
96210
  if (input.ingestedAnchorHash !== undefined && input.baselineAnchorHash !== undefined) {
95595
96211
  if (input.ingestedAnchorHash !== input.baselineAnchorHash) {
95596
96212
  return {
@@ -95608,7 +96224,7 @@ async function runGate(input) {
95608
96224
  reason: `Skeptic gate failed: the Skeptic reported an anchor/invariant violation.${violations}`
95609
96225
  };
95610
96226
  }
95611
- return { ok: true };
96227
+ return { ok: true, ...empiricalScores ? { empirical: empiricalScores } : {} };
95612
96228
  }
95613
96229
  function emitGenerationEnvelope(type, resolvedPath, content, baseline, trends) {
95614
96230
  const rubric2 = loadRubric(type);
@@ -95666,7 +96282,7 @@ function emitGenerationEnvelope(type, resolvedPath, content, baseline, trends) {
95666
96282
  async function ingestProposal(db2, type, name, resolvedPath, ingestPath, opts, baselineScore) {
95667
96283
  let raw;
95668
96284
  try {
95669
- raw = readFileSync11(ingestPath, "utf-8");
96285
+ raw = readFileSync12(ingestPath, "utf-8");
95670
96286
  } catch {
95671
96287
  throw Object.assign(new Error(`Cannot read proposal file: ${ingestPath}`), { code: 2 });
95672
96288
  }
@@ -95708,10 +96324,22 @@ async function ingestProposal(db2, type, name, resolvedPath, ingestPath, opts, b
95708
96324
  if (opts?.acceptId) {
95709
96325
  const backupPath = await backupFile(resolvedPath);
95710
96326
  const appliedCount = await stepApply(parsed.changes, resolvedPath, proposalRecord.id, db2);
96327
+ const evalGate = opts?.evalGate ? {
96328
+ name,
96329
+ candidateSkillText: await Bun.file(resolvedPath).text(),
96330
+ baselineSkillText: readFileSync12(backupPath, "utf-8"),
96331
+ margin: opts?.margin ?? 0.05,
96332
+ target: opts?.target ?? "claude",
96333
+ replayBackend: opts?.replayBackend,
96334
+ judgeBackend: opts?.judgeBackend,
96335
+ judgeReplays: opts?.judgeReplays,
96336
+ judgeBudget: opts?.judgeBudget
96337
+ } : undefined;
95711
96338
  const verdict = await stepVerify(type, name, resolvedPath, baselineScore, proposalRecord.id, opts, db2, {
95712
96339
  backupPath,
95713
96340
  ingestedAnchorHash: parsed.anchor_hash,
95714
- skeptic: parsed.skeptic
96341
+ skeptic: parsed.skeptic,
96342
+ evalGate
95715
96343
  });
95716
96344
  if (!verdict.rejected && verdict.backupPath) {
95717
96345
  await persistVersionSnapshot(verdict.backupPath, resolvedPath, proposalId);
@@ -95928,7 +96556,7 @@ async function stepVerify(type, name, filePath, baselineScore, proposalDbId, opt
95928
96556
  const delta = postScore - baselineScore;
95929
96557
  if (gate) {
95930
96558
  const margin = opts?.margin ?? 0.05;
95931
- const baselineAnchorHash = gate.ingestedAnchorHash !== undefined ? computeBaselineAnchorHash(readFileSync11(gate.backupPath, "utf-8")) : undefined;
96559
+ const baselineAnchorHash = gate.ingestedAnchorHash !== undefined ? computeBaselineAnchorHash(readFileSync12(gate.backupPath, "utf-8")) : undefined;
95932
96560
  const gateResult = await runGate({
95933
96561
  type,
95934
96562
  resolvedPath: filePath,
@@ -95937,7 +96565,8 @@ async function stepVerify(type, name, filePath, baselineScore, proposalDbId, opt
95937
96565
  margin,
95938
96566
  ingestedAnchorHash: gate.ingestedAnchorHash,
95939
96567
  baselineAnchorHash,
95940
- skeptic: gate.skeptic
96568
+ skeptic: gate.skeptic,
96569
+ evalGate: gate.evalGate
95941
96570
  });
95942
96571
  if (!gateResult.ok) {
95943
96572
  await restoreFromBackup(gate.backupPath, filePath);
@@ -95945,6 +96574,31 @@ async function stepVerify(type, name, filePath, baselineScore, proposalDbId, opt
95945
96574
  echoError(`Gate rejected proposal \u2014 ${gateResult.reason} File restored; proposal stays draft.`);
95946
96575
  return { postScore: baselineScore, delta: 0, rejected: true, reason: gateResult.reason };
95947
96576
  }
96577
+ if (gateResult.empirical) {
96578
+ try {
96579
+ await new EvaluationDao(db2).insertEvaluation({
96580
+ content_type: type,
96581
+ content_name: name,
96582
+ target_agent: opts?.target ?? "claude",
96583
+ operation: "evolve",
96584
+ aggregate: gateResult.empirical.hard,
96585
+ dimensions: {
96586
+ empirical: {
96587
+ score: gateResult.empirical.hard,
96588
+ hard: gateResult.empirical.hard,
96589
+ holdout_n: gateResult.empirical.holdout_n,
96590
+ train_n: gateResult.empirical.train_n,
96591
+ ...gateResult.empirical.noise_floor !== undefined ? { noise_floor: gateResult.empirical.noise_floor } : {},
96592
+ ...gateResult.empirical.rubric_delta !== undefined ? { rubric_delta: gateResult.empirical.rubric_delta } : {},
96593
+ 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)}` : ""}`
96594
+ }
96595
+ }
96596
+ });
96597
+ 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)}` : ""})`);
96598
+ } catch {
96599
+ echoError("Cannot persist empirical behavior score.");
96600
+ }
96601
+ }
95948
96602
  }
95949
96603
  try {
95950
96604
  const verifyEval = await new EvaluationDao(db2).getLatestEvaluation(type, name);
@@ -95974,7 +96628,7 @@ function formatAnalyze(name, analysis) {
95974
96628
  const { trends, baselineScore, baselineDate, evaluations: evaluations2 } = analysis;
95975
96629
  const grade = scoreToGrade(baselineScore);
95976
96630
  const verdict = baselineScore >= 0.7 ? "PASS" : "FAIL";
95977
- const gitAvailable = existsSync12(join220(process.cwd(), ".git"));
96631
+ const gitAvailable = existsSync13(join220(process.cwd(), ".git"));
95978
96632
  const lines = [];
95979
96633
  lines.push("=== Evolution Analysis ===");
95980
96634
  lines.push(`Target: ${name} Score: ${(baselineScore * 100).toFixed(0)}% (${grade}) Status: ${verdict}`);
@@ -96004,12 +96658,12 @@ function formatAnalyze(name, analysis) {
96004
96658
  async function persistVersionSnapshot(backupPath, resolvedPath, proposalId) {
96005
96659
  const versionPath = `${resolvedPath}.version-${proposalId}`;
96006
96660
  await Bun.write(versionPath, Bun.file(backupPath));
96007
- rmSync4(backupPath, { force: true });
96661
+ rmSync5(backupPath, { force: true });
96008
96662
  return versionPath;
96009
96663
  }
96010
96664
  async function evolve(type, name, opts) {
96011
96665
  const resolvedPath = resolveContentPath(type, name);
96012
- if (!resolvedPath || !existsSync12(resolvedPath)) {
96666
+ if (!resolvedPath || !existsSync13(resolvedPath)) {
96013
96667
  echoError(`File not found: ${name}`);
96014
96668
  return { baselineScore: 0, postScore: 0, delta: 0, changesApplied: 0, proposalPath: "" };
96015
96669
  }
@@ -96044,7 +96698,7 @@ async function evolve(type, name, opts) {
96044
96698
  const versionId = proposalId2 ?? `#${p.id}`;
96045
96699
  const appliedAt = p.applied_at ?? "unknown";
96046
96700
  const versionPath = `${resolvedPath}.version-${versionId}`;
96047
- const hasSnapshot = existsSync12(versionPath) ? "\u2713" : "\u2717";
96701
+ const hasSnapshot = existsSync13(versionPath) ? "\u2713" : "\u2717";
96048
96702
  lines.push(`| ${versionId} | ${appliedAt} | ${hasSnapshot} |`);
96049
96703
  }
96050
96704
  echo(lines.join(`
@@ -96057,7 +96711,7 @@ async function evolve(type, name, opts) {
96057
96711
  return { baselineScore: 0, postScore: 0, delta: 0, changesApplied: 0, proposalPath: "" };
96058
96712
  }
96059
96713
  const versionPath = `${resolvedPath}.version-${opts.rollback}`;
96060
- if (!existsSync12(versionPath)) {
96714
+ if (!existsSync13(versionPath)) {
96061
96715
  echoError(`Version snapshot not found: ${opts.rollback}`);
96062
96716
  return { baselineScore: 0, postScore: 0, delta: 0, changesApplied: 0, proposalPath: "" };
96063
96717
  }
@@ -96137,10 +96791,22 @@ async function evolve(type, name, opts) {
96137
96791
  }
96138
96792
  const backupPath2 = await backupFile(resolvedPath);
96139
96793
  const appliedCount = await stepApply(acceptedFromStore, resolvedPath, target.id, db2);
96794
+ const evalGateCtx2 = opts?.evalGate ? {
96795
+ name: contentName,
96796
+ candidateSkillText: await Bun.file(resolvedPath).text(),
96797
+ baselineSkillText: readFileSync12(backupPath2, "utf-8"),
96798
+ margin: opts?.margin ?? 0.05,
96799
+ target: opts?.target ?? "claude",
96800
+ replayBackend: opts?.replayBackend,
96801
+ judgeBackend: opts?.judgeBackend,
96802
+ judgeReplays: opts?.judgeReplays,
96803
+ judgeBudget: opts?.judgeBudget
96804
+ } : undefined;
96140
96805
  const verdict = await stepVerify(type, contentName, resolvedPath, baselineScore, target.id, opts, db2, {
96141
96806
  backupPath: backupPath2,
96142
96807
  ingestedAnchorHash: storedAnchorHash,
96143
- skeptic: storedSkeptic
96808
+ skeptic: storedSkeptic,
96809
+ evalGate: evalGateCtx2
96144
96810
  });
96145
96811
  if (!verdict.rejected && verdict.backupPath) {
96146
96812
  await persistVersionSnapshot(verdict.backupPath, resolvedPath, opts.acceptId);
@@ -96163,7 +96829,18 @@ async function evolve(type, name, opts) {
96163
96829
  const { accepted: acceptedChanges } = await interactiveReview(changes, trends);
96164
96830
  const backupPath = await backupFile(resolvedPath);
96165
96831
  const changesApplied = await stepApply(acceptedChanges, resolvedPath, proposalDbId, db2);
96166
- const { postScore, delta } = await stepVerify(type, contentName, resolvedPath, baselineScore, proposalDbId, opts, db2);
96832
+ const evalGateCtx = opts?.evalGate ? {
96833
+ name: contentName,
96834
+ candidateSkillText: await Bun.file(resolvedPath).text(),
96835
+ baselineSkillText: readFileSync12(backupPath, "utf-8"),
96836
+ margin: opts?.margin ?? 0.05,
96837
+ target: opts?.target ?? "claude",
96838
+ replayBackend: opts?.replayBackend,
96839
+ judgeBackend: opts?.judgeBackend,
96840
+ judgeReplays: opts?.judgeReplays,
96841
+ judgeBudget: opts?.judgeBudget
96842
+ } : undefined;
96843
+ const { postScore, delta } = await stepVerify(type, contentName, resolvedPath, baselineScore, proposalDbId, opts, db2, evalGateCtx ? { backupPath, evalGate: evalGateCtx } : undefined);
96167
96844
  await persistVersionSnapshot(backupPath, resolvedPath, proposalId);
96168
96845
  return { baselineScore, postScore, delta, changesApplied, proposalPath };
96169
96846
  }
@@ -96580,7 +97257,7 @@ function addScaffoldOptions(cmd) {
96580
97257
  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
97258
  }
96582
97259
  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)");
97260
+ 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
97261
  }
96585
97262
  function addHookEvolveOptions(cmd) {
96586
97263
  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 +97366,8 @@ async function agentEvolve(opts) {
96689
97366
  analyze: opts.analyze,
96690
97367
  history: opts.history,
96691
97368
  rollback: opts.rollback,
96692
- confirm: opts.confirm
97369
+ confirm: opts.confirm,
97370
+ evalGate: opts.evalGate
96693
97371
  });
96694
97372
  return;
96695
97373
  }
@@ -96785,7 +97463,8 @@ async function commandEvolve(opts) {
96785
97463
  analyze: opts.analyze,
96786
97464
  history: opts.history,
96787
97465
  rollback: opts.rollback,
96788
- confirm: opts.confirm
97466
+ confirm: opts.confirm,
97467
+ evalGate: opts.evalGate
96789
97468
  });
96790
97469
  return;
96791
97470
  }
@@ -96826,7 +97505,7 @@ function registerCommand(program2) {
96826
97505
  // src/commands/hook.ts
96827
97506
  init_src();
96828
97507
  init_dist();
96829
- import { homedir as homedir6 } from "os";
97508
+ import { homedir as homedir7 } from "os";
96830
97509
  import { join as join225 } from "path";
96831
97510
 
96832
97511
  // src/commands/install.ts
@@ -96834,19 +97513,19 @@ init_src();
96834
97513
  init_dist();
96835
97514
  import {
96836
97515
  copyFileSync as copyFileSync2,
96837
- existsSync as existsSync14,
97516
+ existsSync as existsSync15,
96838
97517
  mkdirSync as mkdirSync9,
96839
97518
  readdirSync as readdirSync4,
96840
- readFileSync as readFileSync13,
96841
- rmSync as rmSync5,
96842
- statSync as statSync7,
97519
+ readFileSync as readFileSync14,
97520
+ rmSync as rmSync6,
97521
+ statSync as statSync6,
96843
97522
  writeFileSync as writeFileSync8
96844
97523
  } from "fs";
96845
- import { homedir as homedir5 } from "os";
97524
+ import { homedir as homedir6 } from "os";
96846
97525
  import { join as join223 } from "path";
96847
97526
 
96848
97527
  // src/hooks.ts
96849
- import { copyFileSync, existsSync as existsSync13, mkdirSync as mkdirSync8, readFileSync as readFileSync12, writeFileSync as writeFileSync7 } from "fs";
97528
+ import { copyFileSync, existsSync as existsSync14, mkdirSync as mkdirSync8, readFileSync as readFileSync13, writeFileSync as writeFileSync7 } from "fs";
96850
97529
  import { join as join221 } from "path";
96851
97530
  var CANONICAL_TO_PI_EVENT = {
96852
97531
  sessionStart: "session_start",
@@ -96890,10 +97569,10 @@ function convertCanonicalToPiHooks(config3) {
96890
97569
  }
96891
97570
  function readCanonicalHooks(rulesyncDir) {
96892
97571
  const hooksPath = join221(rulesyncDir, "hooks.json");
96893
- if (!existsSync13(hooksPath))
97572
+ if (!existsSync14(hooksPath))
96894
97573
  return null;
96895
97574
  try {
96896
- return JSON.parse(readFileSync12(hooksPath, "utf-8"));
97575
+ return JSON.parse(readFileSync13(hooksPath, "utf-8"));
96897
97576
  } catch {
96898
97577
  return null;
96899
97578
  }
@@ -97051,7 +97730,7 @@ async function executeInstall(plugin, targets2, options2, dependencies = {}) {
97051
97730
  echo(` Skills written: ${resultCounts.skillsCount}, Commands: ${resultCounts.commandsCount}, Subagents: ${resultCounts.subagentsCount}, Hooks: ${resultCounts.hooksCount}`);
97052
97731
  }
97053
97732
  }
97054
- const outputRoot = options2.outputRoot ?? (options2.global ? homedir5() : process.cwd());
97733
+ const outputRoot = options2.outputRoot ?? (options2.global ? homedir6() : process.cwd());
97055
97734
  const hookEmitResults = [];
97056
97735
  for (const target of targets2) {
97057
97736
  if (target === "claude") {
@@ -97060,9 +97739,9 @@ async function executeInstall(plugin, targets2, options2, dependencies = {}) {
97060
97739
  if (!options2.dryRun) {
97061
97740
  const marketplaceName = resolution.marketplaceName ?? "superskill";
97062
97741
  const marketplaceRoot = resolution.marketplaceRoot ?? process.cwd();
97063
- const cacheDir = join223(homedir5(), ".claude", "plugins", "cache", marketplaceName);
97064
- if (existsSync14(cacheDir))
97065
- rmSync5(cacheDir, { recursive: true, force: true });
97742
+ const cacheDir = join223(homedir6(), ".claude", "plugins", "cache", marketplaceName);
97743
+ if (existsSync15(cacheDir))
97744
+ rmSync6(cacheDir, { recursive: true, force: true });
97066
97745
  await runClaudeInstallImpl(marketplaceRoot, marketplaceName, plugin);
97067
97746
  }
97068
97747
  }
@@ -97090,7 +97769,7 @@ async function executeInstall(plugin, targets2, options2, dependencies = {}) {
97090
97769
  if (options2.verbose)
97091
97770
  echo(` ${hookResult.message}`);
97092
97771
  const agentsDir = join223(pluginRoot, "agents");
97093
- if (existsSync14(agentsDir) && !options2.dryRun) {
97772
+ if (existsSync15(agentsDir) && !options2.dryRun) {
97094
97773
  const piAgentsDir = join223(outputRoot, ".pi", "agent", "agents");
97095
97774
  mkdirSync9(piAgentsDir, { recursive: true });
97096
97775
  for (const entry of readdirSync4(agentsDir)) {
@@ -97098,8 +97777,8 @@ async function executeInstall(plugin, targets2, options2, dependencies = {}) {
97098
97777
  continue;
97099
97778
  const agentName = entry.replace(/\.md$/, "");
97100
97779
  const expectedName = `${plugin}-${agentName}`;
97101
- const source = readFileSync13(join223(agentsDir, entry), "utf-8");
97102
- const skillExists = (bare) => existsSync14(join223(pluginRoot, "skills", bare));
97780
+ const source = readFileSync14(join223(agentsDir, entry), "utf-8");
97781
+ const skillExists = (bare) => existsSync15(join223(pluginRoot, "skills", bare));
97103
97782
  const adapted = adaptSubagentToPi(source, expectedName, plugin, skillExists);
97104
97783
  writeFileSync8(join223(piAgentsDir, `${expectedName}.md`), adapted);
97105
97784
  }
@@ -97148,9 +97827,9 @@ function resolvePluginRoot(plugin, marketplacePath) {
97148
97827
  const manifestRoot = resolved.marketplaceRoot;
97149
97828
  const manifestPath = join223(manifestRoot, ".claude-plugin", "marketplace.json");
97150
97829
  let marketplaceName;
97151
- if (existsSync14(manifestPath)) {
97830
+ if (existsSync15(manifestPath)) {
97152
97831
  try {
97153
- const raw = readFileSync13(manifestPath, "utf-8");
97832
+ const raw = readFileSync14(manifestPath, "utf-8");
97154
97833
  const parsed = JSON.parse(raw);
97155
97834
  marketplaceName = parsed.name;
97156
97835
  } catch {}
@@ -97158,7 +97837,7 @@ function resolvePluginRoot(plugin, marketplacePath) {
97158
97837
  return { pluginRoot: resolved.pluginRoot, marketplaceRoot: manifestRoot, marketplaceName };
97159
97838
  }
97160
97839
  const fallback = join223("plugins", plugin);
97161
- if (existsSync14(fallback) && readdirSync4(fallback).some((d) => ["skills", "commands", "agents", "hooks", "hooks.json"].includes(d)))
97840
+ if (existsSync15(fallback) && readdirSync4(fallback).some((d) => ["skills", "commands", "agents", "hooks", "hooks.json"].includes(d)))
97162
97841
  return { pluginRoot: fallback };
97163
97842
  const available = listResolvablePlugins(marketplacePath);
97164
97843
  const msg = available.length > 0 ? `Available: ${available.join(", ")}` : "No marketplace manifest found and no plugins/<name>/ directory.";
@@ -97167,7 +97846,7 @@ function resolvePluginRoot(plugin, marketplacePath) {
97167
97846
  function prepareTargetRulesyncInput(sourceRoot, target, pluginName) {
97168
97847
  const targetRoot = join223(sourceRoot, ".targets", target);
97169
97848
  const targetRulesyncRoot = join223(targetRoot, ".rulesync");
97170
- rmSync5(targetRoot, { recursive: true, force: true });
97849
+ rmSync6(targetRoot, { recursive: true, force: true });
97171
97850
  copyDirectory(sourceRoot, targetRulesyncRoot, { skipDirectoryNames: new Set([".targets"]) });
97172
97851
  transformRulesyncMarkdown(targetRulesyncRoot, target, pluginName);
97173
97852
  return targetRoot;
@@ -97193,25 +97872,25 @@ function transformRulesyncMarkdown(root, target, pluginName) {
97193
97872
  transformMarkdownDirectory(join223(root, "skills"), target, pluginName);
97194
97873
  }
97195
97874
  function transformMarkdownDirectory(dir, target, pluginName) {
97196
- if (!existsSync14(dir))
97875
+ if (!existsSync15(dir))
97197
97876
  return;
97198
97877
  for (const entry of readdirSync4(dir)) {
97199
97878
  const path11 = join223(dir, entry);
97200
- const stats = statSync7(path11);
97879
+ const stats = statSync6(path11);
97201
97880
  if (stats.isDirectory()) {
97202
97881
  transformMarkdownDirectory(path11, target, pluginName);
97203
97882
  continue;
97204
97883
  }
97205
97884
  if (!entry.endsWith(".md"))
97206
97885
  continue;
97207
- const content = readFileSync13(path11, "utf-8");
97886
+ const content = readFileSync14(path11, "utf-8");
97208
97887
  const slashTranslated = translateSlashCommands(content, target);
97209
97888
  const transformed = rewriteSkillReferences(slashTranslated, pluginName);
97210
97889
  writeFileSync8(path11, transformed);
97211
97890
  }
97212
97891
  }
97213
97892
  function copyDirectory(source, destination, options2 = {}) {
97214
- if (!existsSync14(source))
97893
+ if (!existsSync15(source))
97215
97894
  return;
97216
97895
  mkdirSync9(destination, { recursive: true });
97217
97896
  for (const entry of readdirSync4(source)) {
@@ -97219,7 +97898,7 @@ function copyDirectory(source, destination, options2 = {}) {
97219
97898
  continue;
97220
97899
  const sourcePath = join223(source, entry);
97221
97900
  const destinationPath = join223(destination, entry);
97222
- if (statSync7(sourcePath).isDirectory()) {
97901
+ if (statSync6(sourcePath).isDirectory()) {
97223
97902
  copyDirectory(sourcePath, destinationPath, options2);
97224
97903
  } else {
97225
97904
  copyFileSync2(sourcePath, destinationPath);
@@ -97258,7 +97937,7 @@ async function emitHook(name, opts) {
97258
97937
  const target = resolveTarget(opts);
97259
97938
  const global3 = opts.global !== false;
97260
97939
  const dryRun = opts.dryRun === true;
97261
- const outputRoot = global3 ? homedir6() : process.cwd();
97940
+ const outputRoot = global3 ? homedir7() : process.cwd();
97262
97941
  const pluginRoot = resolvePluginRoot(name).pluginRoot;
97263
97942
  const outputDir = ".rulesync";
97264
97943
  mapPluginToRulesync(pluginRoot, name, outputDir);
@@ -97386,7 +98065,8 @@ async function magentEvolve(opts) {
97386
98065
  analyze: opts.analyze,
97387
98066
  history: opts.history,
97388
98067
  rollback: opts.rollback,
97389
- confirm: opts.confirm
98068
+ confirm: opts.confirm,
98069
+ evalGate: opts.evalGate
97390
98070
  });
97391
98071
  return;
97392
98072
  }
@@ -97430,9 +98110,9 @@ init_dist();
97430
98110
  // src/operations/migrate.ts
97431
98111
  init_src();
97432
98112
  init_dist();
97433
- import { readFileSync as readFileSync14 } from "fs";
98113
+ import { readFileSync as readFileSync15 } from "fs";
97434
98114
  function readProposalId(proposalPath) {
97435
- const raw = readFileSync14(proposalPath, "utf-8");
98115
+ const raw = readFileSync15(proposalPath, "utf-8");
97436
98116
  const parsed = JSON.parse(raw);
97437
98117
  if (parsed !== null && typeof parsed === "object" && "proposal_id" in parsed) {
97438
98118
  const id = parsed.proposal_id;
@@ -97537,7 +98217,8 @@ async function skillEvolve(opts) {
97537
98217
  analyze: opts.analyze,
97538
98218
  history: opts.history,
97539
98219
  rollback: opts.rollback,
97540
- confirm: opts.confirm
98220
+ confirm: opts.confirm,
98221
+ evalGate: opts.evalGate
97541
98222
  });
97542
98223
  return;
97543
98224
  }
@@ -97601,7 +98282,7 @@ function getPackageVersion() {
97601
98282
  if (packageVersion)
97602
98283
  return packageVersion;
97603
98284
  const packageJsonPath = join226(import.meta.dir, "..", "package.json");
97604
- const packageJson = JSON.parse(readFileSync15(packageJsonPath, "utf-8"));
98285
+ const packageJson = JSON.parse(readFileSync16(packageJsonPath, "utf-8"));
97605
98286
  if (typeof packageJson.version !== "string" || packageJson.version.length === 0) {
97606
98287
  throw new Error(`Invalid package version in ${packageJsonPath}`);
97607
98288
  }