@jaggerxtrm/specialists 3.12.0 → 3.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/config/hooks/specialists-session-start.mjs +1 -1
  2. package/config/mandatory-rules/bead-id-verbatim.md +14 -0
  3. package/config/mandatory-rules/per-turn-handoff-schema.md +16 -0
  4. package/config/skills/specialists-creator/SKILL.md +16 -0
  5. package/config/skills/update-specialists/SKILL.md +183 -350
  6. package/config/skills/using-kpi/SKILL.md +86 -0
  7. package/config/skills/using-script-specialists/SKILL.md +7 -5
  8. package/config/skills/using-specialists-v2/SKILL.md +1 -1
  9. package/config/skills/using-specialists-v3/SKILL.md +530 -112
  10. package/config/specialists/changelog-keeper.specialist.json +2 -1
  11. package/config/specialists/code-sanity.specialist.json +3 -1
  12. package/config/specialists/debugger.specialist.json +3 -1
  13. package/config/specialists/executor.specialist.json +3 -1
  14. package/config/specialists/explorer.specialist.json +2 -1
  15. package/config/specialists/overthinker.specialist.json +2 -1
  16. package/config/specialists/planner.specialist.json +3 -1
  17. package/config/specialists/researcher.specialist.json +2 -1
  18. package/config/specialists/reviewer.specialist.json +3 -1
  19. package/config/specialists/security-auditor.specialist.json +53 -10
  20. package/config/specialists/specialists-creator.specialist.json +2 -2
  21. package/config/specialists/sync-docs.specialist.json +3 -1
  22. package/config/specialists/test-runner.specialist.json +2 -1
  23. package/dist/index.js +634 -498
  24. package/dist/lib.js +183 -62
  25. package/dist/types/cli/help.d.ts.map +1 -1
  26. package/dist/types/cli/run.d.ts.map +1 -1
  27. package/dist/types/cli/script.d.ts.map +1 -1
  28. package/dist/types/cli/serve.d.ts +11 -2
  29. package/dist/types/cli/serve.d.ts.map +1 -1
  30. package/dist/types/cli/version-check.d.ts +3 -0
  31. package/dist/types/cli/version-check.d.ts.map +1 -1
  32. package/dist/types/index.d.ts +1 -1
  33. package/dist/types/specialist/mandatory-rules.d.ts +5 -0
  34. package/dist/types/specialist/mandatory-rules.d.ts.map +1 -1
  35. package/dist/types/specialist/observability-sqlite.d.ts +1 -0
  36. package/dist/types/specialist/observability-sqlite.d.ts.map +1 -1
  37. package/dist/types/specialist/schema.d.ts +27 -0
  38. package/dist/types/specialist/schema.d.ts.map +1 -1
  39. package/dist/types/specialist/script-runner.d.ts +5 -1
  40. package/dist/types/specialist/script-runner.d.ts.map +1 -1
  41. package/package.json +4 -4
  42. package/config/specialists/.serena/project.yml +0 -151
package/dist/lib.js CHANGED
@@ -555,6 +555,8 @@ var require_Alias = __commonJS((exports) => {
555
555
  });
556
556
  }
557
557
  resolve(doc, ctx) {
558
+ if (ctx?.maxAliasCount === 0)
559
+ throw new ReferenceError("Alias resolution is disabled");
558
560
  let nodes;
559
561
  if (ctx?.aliasResolveCache) {
560
562
  nodes = ctx.aliasResolveCache;
@@ -1334,6 +1336,7 @@ var require_stringify = __commonJS((exports) => {
1334
1336
  nullStr: "null",
1335
1337
  simpleKeys: false,
1336
1338
  singleQuote: null,
1339
+ trailingComma: false,
1337
1340
  trueStr: "true",
1338
1341
  verifyAliasOrder: true
1339
1342
  }, doc.schema.toStringOptions, options);
@@ -1603,18 +1606,18 @@ var require_merge = __commonJS((exports) => {
1603
1606
  };
1604
1607
  var isMergeKey = (ctx, key) => (merge.identify(key) || identity.isScalar(key) && (!key.type || key.type === Scalar.Scalar.PLAIN) && merge.identify(key.value)) && ctx?.doc.schema.tags.some((tag) => tag.tag === merge.tag && tag.default);
1605
1608
  function addMergeToJSMap(ctx, map, value) {
1606
- value = ctx && identity.isAlias(value) ? value.resolve(ctx.doc) : value;
1607
- if (identity.isSeq(value))
1608
- for (const it of value.items)
1609
+ const source = resolveAliasValue(ctx, value);
1610
+ if (identity.isSeq(source))
1611
+ for (const it of source.items)
1609
1612
  mergeValue(ctx, map, it);
1610
- else if (Array.isArray(value))
1611
- for (const it of value)
1613
+ else if (Array.isArray(source))
1614
+ for (const it of source)
1612
1615
  mergeValue(ctx, map, it);
1613
1616
  else
1614
- mergeValue(ctx, map, value);
1617
+ mergeValue(ctx, map, source);
1615
1618
  }
1616
1619
  function mergeValue(ctx, map, value) {
1617
- const source = ctx && identity.isAlias(value) ? value.resolve(ctx.doc) : value;
1620
+ const source = resolveAliasValue(ctx, value);
1618
1621
  if (!identity.isMap(source))
1619
1622
  throw new Error("Merge sources must be maps or map aliases");
1620
1623
  const srcMap = source.toJSON(null, ctx, Map);
@@ -1635,6 +1638,9 @@ var require_merge = __commonJS((exports) => {
1635
1638
  }
1636
1639
  return map;
1637
1640
  }
1641
+ function resolveAliasValue(ctx, value) {
1642
+ return ctx && identity.isAlias(value) ? value.resolve(ctx.doc, ctx) : value;
1643
+ }
1638
1644
  exports.addMergeToJSMap = addMergeToJSMap;
1639
1645
  exports.isMergeKey = isMergeKey;
1640
1646
  exports.merge = merge;
@@ -1842,13 +1848,20 @@ ${indent}${line}` : `
1842
1848
  if (comment)
1843
1849
  reqNewline = true;
1844
1850
  let str = stringify.stringify(item, itemCtx, () => comment = null);
1845
- if (i < items.length - 1)
1851
+ reqNewline || (reqNewline = lines.length > linesAtValue || str.includes(`
1852
+ `));
1853
+ if (i < items.length - 1) {
1846
1854
  str += ",";
1855
+ } else if (ctx.options.trailingComma) {
1856
+ if (ctx.options.lineWidth > 0) {
1857
+ reqNewline || (reqNewline = lines.reduce((sum, line) => sum + line.length + 2, 2) + (str.length + 2) > ctx.options.lineWidth);
1858
+ }
1859
+ if (reqNewline) {
1860
+ str += ",";
1861
+ }
1862
+ }
1847
1863
  if (comment)
1848
1864
  str += stringifyComment.lineComment(str, itemIndent, commentString(comment));
1849
- if (!reqNewline && (lines.length > linesAtValue || str.includes(`
1850
- `)))
1851
- reqNewline = true;
1852
1865
  lines.push(str);
1853
1866
  linesAtValue = lines.length;
1854
1867
  }
@@ -2203,7 +2216,7 @@ var require_stringifyNumber = __commonJS((exports) => {
2203
2216
  if (!isFinite(num))
2204
2217
  return isNaN(num) ? ".nan" : num < 0 ? "-.inf" : ".inf";
2205
2218
  let n = Object.is(value, -0) ? "-0" : JSON.stringify(value);
2206
- if (!format && minFractionDigits && (!tag || tag === "tag:yaml.org,2002:float") && /^\d/.test(n)) {
2219
+ if (!format && minFractionDigits && (!tag || tag === "tag:yaml.org,2002:float") && /^-?\d/.test(n) && !n.includes("e")) {
2207
2220
  let i = n.indexOf(".");
2208
2221
  if (i < 0) {
2209
2222
  i = n.length;
@@ -4428,7 +4441,7 @@ var require_resolve_flow_scalar = __commonJS((exports) => {
4428
4441
  while (next === " " || next === "\t")
4429
4442
  next = source[++i + 1];
4430
4443
  } else if (next === "x" || next === "u" || next === "U") {
4431
- const length = { x: 2, u: 4, U: 8 }[next];
4444
+ const length = next === "x" ? 2 : next === "u" ? 4 : 8;
4432
4445
  res += parseCharCode(source, i + 1, length, onError);
4433
4446
  i += length;
4434
4447
  } else {
@@ -4497,12 +4510,13 @@ var require_resolve_flow_scalar = __commonJS((exports) => {
4497
4510
  const cc = source.substr(offset, length);
4498
4511
  const ok = cc.length === length && /^[0-9a-fA-F]+$/.test(cc);
4499
4512
  const code = ok ? parseInt(cc, 16) : NaN;
4500
- if (isNaN(code)) {
4513
+ try {
4514
+ return String.fromCodePoint(code);
4515
+ } catch {
4501
4516
  const raw = source.substr(offset - 2, length + 2);
4502
4517
  onError(offset - 2, "BAD_DQ_ESCAPE", `Invalid escape sequence ${raw}`);
4503
4518
  return raw;
4504
4519
  }
4505
- return String.fromCodePoint(code);
4506
4520
  }
4507
4521
  exports.resolveFlowScalar = resolveFlowScalar;
4508
4522
  });
@@ -4643,17 +4657,22 @@ var require_compose_node = __commonJS((exports) => {
4643
4657
  case "block-map":
4644
4658
  case "block-seq":
4645
4659
  case "flow-collection":
4646
- node = composeCollection.composeCollection(CN, ctx, token, props, onError);
4647
- if (anchor)
4648
- node.anchor = anchor.source.substring(1);
4660
+ try {
4661
+ node = composeCollection.composeCollection(CN, ctx, token, props, onError);
4662
+ if (anchor)
4663
+ node.anchor = anchor.source.substring(1);
4664
+ } catch (error) {
4665
+ const message = error instanceof Error ? error.message : String(error);
4666
+ onError(token, "RESOURCE_EXHAUSTION", message);
4667
+ }
4649
4668
  break;
4650
4669
  default: {
4651
4670
  const message = token.type === "error" ? token.message : `Unsupported token (type: ${token.type})`;
4652
4671
  onError(token, "UNEXPECTED_TOKEN", message);
4653
- node = composeEmptyNode(ctx, token.offset, undefined, null, props, onError);
4654
4672
  isSrcToken = false;
4655
4673
  }
4656
4674
  }
4675
+ node ?? (node = composeEmptyNode(ctx, token.offset, undefined, null, props, onError));
4657
4676
  if (anchor && node.anchor === "")
4658
4677
  onError(anchor, "BAD_ALIAS", "Anchor cannot be an empty string");
4659
4678
  if (atKey && ctx.options.stringKeys && (!identity.isScalar(node) || typeof node.value !== "string" || node.tag && node.tag !== "tag:yaml.org,2002:str")) {
@@ -6908,6 +6927,7 @@ var require_public_api = __commonJS((exports) => {
6908
6927
  import { spawn } from "node:child_process";
6909
6928
  import { createHash, randomUUID } from "node:crypto";
6910
6929
  import { readFileSync as readFileSync2 } from "node:fs";
6930
+ import { isAbsolute, relative, resolve } from "node:path";
6911
6931
 
6912
6932
  // src/specialist/templateEngine.ts
6913
6933
  function renderTemplate(template, variables) {
@@ -6917,7 +6937,8 @@ function renderTemplate(template, variables) {
6917
6937
  }
6918
6938
 
6919
6939
  // src/specialist/observability-sqlite.ts
6920
- import { existsSync, readFileSync, statSync } from "node:fs";
6940
+ import { existsSync, mkdirSync, readFileSync, statSync } from "node:fs";
6941
+ import { dirname, join as join2 } from "node:path";
6921
6942
 
6922
6943
  // src/specialist/observability-db.ts
6923
6944
  import { spawnSync } from "node:child_process";
@@ -9013,23 +9034,30 @@ class SqliteClient {
9013
9034
  this.db.close();
9014
9035
  }
9015
9036
  }
9016
- function createObservabilitySqliteClient(cwd = process.cwd()) {
9037
+ function openObservabilitySqliteClient(dbPath) {
9017
9038
  if (!loadBunDatabase())
9018
9039
  return null;
9019
- const location = resolveObservabilityDbLocation(cwd);
9020
- if (!existsSync(location.dbPath))
9021
- return null;
9022
9040
  try {
9023
9041
  const Ctor = loadBunDatabase();
9024
- const initDb = new Ctor(location.dbPath);
9042
+ const initDb = new Ctor(dbPath);
9025
9043
  initDb.run(`PRAGMA busy_timeout=${BUSY_TIMEOUT_MS}`);
9026
9044
  initSchema(initDb);
9027
9045
  initDb.close();
9028
- return new SqliteClient(location.dbPath);
9046
+ return new SqliteClient(dbPath);
9029
9047
  } catch {
9030
9048
  return null;
9031
9049
  }
9032
9050
  }
9051
+ function createObservabilitySqliteClient(cwd = process.cwd()) {
9052
+ const location = resolveObservabilityDbLocation(cwd);
9053
+ if (!existsSync(location.dbPath))
9054
+ return null;
9055
+ return openObservabilitySqliteClient(location.dbPath);
9056
+ }
9057
+ function createObservabilitySqliteClientAtPath(dbPath) {
9058
+ mkdirSync(dirname(dbPath), { recursive: true });
9059
+ return openObservabilitySqliteClient(dbPath);
9060
+ }
9033
9061
 
9034
9062
  // src/specialist/script-runner.ts
9035
9063
  class CompatGuardError extends Error {
@@ -9040,6 +9068,18 @@ class CompatGuardError extends Error {
9040
9068
  this.name = "CompatGuardError";
9041
9069
  }
9042
9070
  }
9071
+ function isPathWithinRoot(candidatePath, rootPath) {
9072
+ const candidate = resolve(candidatePath);
9073
+ const root = resolve(rootPath);
9074
+ const rel = relative(root, candidate);
9075
+ return rel === "" || rel.length > 0 && !rel.startsWith("..") && !isAbsolute(rel);
9076
+ }
9077
+ function assertSkillPathWithinRoots(field, path, roots) {
9078
+ const allowed = roots.some((root) => isPathWithinRoot(path, root));
9079
+ if (!allowed) {
9080
+ throw new CompatGuardError(field, `skill path '${path}' not under any --allow-skills-roots entry`);
9081
+ }
9082
+ }
9043
9083
  function hasUnsubstitutedVariables(template, variables) {
9044
9084
  const matches = template.match(/\$([a-zA-Z_][a-zA-Z0-9_]*)/g) ?? [];
9045
9085
  for (const match of matches) {
@@ -9058,8 +9098,8 @@ function compatGuard(spec, trust) {
9058
9098
  if (execution.permission_required !== "READ_ONLY")
9059
9099
  throw new CompatGuardError("execution.permission_required", "permission_required must be READ_ONLY");
9060
9100
  const hasScripts = (spec.specialist.skills?.scripts?.length ?? 0) > 0;
9061
- if (hasScripts && !trust?.allowLocalScripts) {
9062
- throw new CompatGuardError("skills.scripts", "scripts not allowed (enable with --allow-local-scripts)");
9101
+ if (hasScripts) {
9102
+ throw new CompatGuardError("skills.scripts", "local scripts are not supported in script-class specialists");
9063
9103
  }
9064
9104
  const hasPaths = (spec.specialist.skills?.paths?.length ?? 0) > 0;
9065
9105
  const hasSkillInherit = Boolean(spec.specialist.prompt.skill_inherit);
@@ -9069,26 +9109,34 @@ function compatGuard(spec, trust) {
9069
9109
  if (hasSkillInherit && !trust?.allowSkills) {
9070
9110
  throw new CompatGuardError("prompt.skill_inherit", "skills not allowed (enable with --allow-skills)");
9071
9111
  }
9072
- if (hasPaths && trust?.allowSkills && trust.allowSkillsRoots && trust.allowSkillsRoots.length > 0) {
9112
+ if (trust?.allowSkills && trust.allowSkillsRoots && trust.allowSkillsRoots.length > 0) {
9073
9113
  const paths = spec.specialist.skills?.paths ?? [];
9074
- for (const path of paths) {
9075
- const allowed = trust.allowSkillsRoots.some((root) => path.startsWith(root));
9076
- if (!allowed) {
9077
- throw new CompatGuardError("skills.paths", `skill path '${path}' not under any --allow-skills-roots entry`);
9078
- }
9114
+ for (const path of paths)
9115
+ assertSkillPathWithinRoots("skills.paths", path, trust.allowSkillsRoots);
9116
+ if (typeof spec.specialist.prompt.skill_inherit === "string") {
9117
+ assertSkillPathWithinRoots("prompt.skill_inherit", spec.specialist.prompt.skill_inherit, trust.allowSkillsRoots);
9079
9118
  }
9080
9119
  }
9081
9120
  }
9121
+ function collectSkillPathEntries(spec) {
9122
+ return [
9123
+ ...(spec.specialist.skills?.paths ?? []).map((path) => ({ path, source: "skills.paths" })),
9124
+ ...typeof spec.specialist.prompt.skill_inherit === "string" ? [{ path: spec.specialist.prompt.skill_inherit, source: "prompt.skill_inherit" }] : []
9125
+ ];
9126
+ }
9127
+ function collectSkillPaths(spec) {
9128
+ return collectSkillPathEntries(spec).map((entry) => entry.path);
9129
+ }
9082
9130
  function computeSkillSources(spec) {
9083
- const paths = spec.specialist.skills?.paths ?? [];
9131
+ const entries = collectSkillPathEntries(spec);
9084
9132
  const sources = [];
9085
- for (const path of paths) {
9133
+ for (const { path, source } of entries) {
9086
9134
  try {
9087
9135
  const content = readFileSync2(path);
9088
9136
  const sha256 = createHash("sha256").update(content).digest("hex");
9089
- sources.push({ path, sha256 });
9137
+ sources.push({ path, sha256, source });
9090
9138
  } catch {
9091
- sources.push({ path, sha256: "unreadable" });
9139
+ sources.push({ path, sha256: "unreadable", source });
9092
9140
  }
9093
9141
  }
9094
9142
  return sources;
@@ -9099,6 +9147,34 @@ function renderTaskTemplate(template, variables) {
9099
9147
  throw new Error(`Missing template variable: ${missing}`);
9100
9148
  return renderTemplate(template, variables);
9101
9149
  }
9150
+ function truncateForPrompt(value, limitBytes) {
9151
+ if (Buffer.byteLength(value, "utf8") <= limitBytes)
9152
+ return value;
9153
+ return `${value.slice(0, limitBytes)}
9154
+ ... truncated ...`;
9155
+ }
9156
+ function buildJsonOutputContract(spec) {
9157
+ if (spec.specialist.execution.response_format !== "json")
9158
+ return;
9159
+ const schema = spec.specialist.prompt.output_schema;
9160
+ const required = Array.isArray(schema?.required) ? schema.required.filter((value) => typeof value === "string") : [];
9161
+ const lines = [
9162
+ "Output contract:",
9163
+ "- Return only valid JSON. Do not include Markdown fences, prose, or commentary."
9164
+ ];
9165
+ if (required.length > 0)
9166
+ lines.push(`- Include these required top-level keys: ${required.join(", ")}.`);
9167
+ if (schema)
9168
+ lines.push(`- JSON schema: ${truncateForPrompt(JSON.stringify(schema), 4096)}`);
9169
+ return lines.join(`
9170
+ `);
9171
+ }
9172
+ function applyOutputContract(prompt, spec) {
9173
+ const contract = buildJsonOutputContract(spec);
9174
+ return contract ? `${prompt}
9175
+
9176
+ ${contract}` : prompt;
9177
+ }
9102
9178
  function mapErrorType(message) {
9103
9179
  if (message.includes("Specialist not found"))
9104
9180
  return "specialist_not_found";
@@ -9106,6 +9182,8 @@ function mapErrorType(message) {
9106
9182
  return "specialist_load_error";
9107
9183
  if (message.includes("Missing template variable"))
9108
9184
  return "template_variable_missing";
9185
+ if (message.includes("prompt too large"))
9186
+ return "prompt_too_large";
9109
9187
  if (message.includes("output too large"))
9110
9188
  return "output_too_large";
9111
9189
  if (message.includes("auth") || message.includes("403") || message.includes("401"))
@@ -9176,6 +9254,19 @@ function writeTraceRow(client, specialist, model, traceId, output, durationMs, s
9176
9254
  var DEFAULT_PENDING_LINE_LIMIT_BYTES = 16 * 1024 * 1024;
9177
9255
  var DEFAULT_ASSISTANT_TEXT_LIMIT_BYTES = 4 * 1024 * 1024;
9178
9256
  var DEFAULT_STDERR_LIMIT_BYTES = 1 * 1024 * 1024;
9257
+ var DEFAULT_PROMPT_LIMIT_BYTES = 4 * 1024 * 1024;
9258
+ function resolvePromptLimitBytes(spec) {
9259
+ return spec.specialist.execution.prompt_limit_bytes ?? resolveEnvPromptLimitBytes() ?? DEFAULT_PROMPT_LIMIT_BYTES;
9260
+ }
9261
+ function resolveEnvPromptLimitBytes() {
9262
+ const raw = process.env.SPECIALISTS_SCRIPT_PROMPT_LIMIT_BYTES;
9263
+ if (raw === undefined)
9264
+ return;
9265
+ const envLimit = Number(raw);
9266
+ if (!Number.isFinite(envLimit) || envLimit <= 0)
9267
+ return;
9268
+ return Math.floor(envLimit);
9269
+ }
9179
9270
  function resolveAssistantTextLimitBytes(spec) {
9180
9271
  return spec.specialist.execution.stdout_limit_bytes ?? resolveEnvAssistantTextLimitBytes() ?? DEFAULT_ASSISTANT_TEXT_LIMIT_BYTES;
9181
9272
  }
@@ -9191,8 +9282,9 @@ function resolveEnvAssistantTextLimitBytes() {
9191
9282
  return Math.floor(envLimit);
9192
9283
  }
9193
9284
  function openObservabilityClient(options) {
9194
- const dbPath = options.observabilityDbPath ?? options.projectDir;
9195
- return createObservabilitySqliteClient(dbPath);
9285
+ if (options.observabilityDbPath)
9286
+ return createObservabilitySqliteClientAtPath(options.observabilityDbPath);
9287
+ return createObservabilitySqliteClient(options.projectDir);
9196
9288
  }
9197
9289
  function resolveScriptSpecialistName(name) {
9198
9290
  if (name === "changelog-keeper")
@@ -9206,9 +9298,28 @@ async function runScriptSpecialist(input, options) {
9206
9298
  const resolvedSpecialist = resolveScriptSpecialistName(input.specialist);
9207
9299
  const spec = await options.loader.get(resolvedSpecialist);
9208
9300
  compatGuard(spec, options.trust);
9301
+ const skillPaths = options.trust?.allowSkills ? collectSkillPaths(spec) : [];
9209
9302
  const skillSources = options.trust?.allowSkills ? computeSkillSources(spec) : undefined;
9210
9303
  const template = input.template ?? spec.specialist.prompt.task_template;
9211
- const prompt = renderTaskTemplate(template, input.variables ?? {});
9304
+ const prompt = applyOutputContract(renderTaskTemplate(template, input.variables ?? {}), spec);
9305
+ const modelCandidates = collectModelCandidates(input, spec, options);
9306
+ const promptLimitBytes = resolvePromptLimitBytes(spec);
9307
+ const promptBytes = Buffer.byteLength(prompt, "utf8");
9308
+ if (promptBytes > promptLimitBytes) {
9309
+ return {
9310
+ success: false,
9311
+ error: `prompt too large: ${promptBytes} bytes exceeds limit ${promptLimitBytes} bytes`,
9312
+ error_type: "prompt_too_large",
9313
+ meta: {
9314
+ specialist: resolvedSpecialist,
9315
+ requested_specialist: input.requested_specialist ?? input.specialist,
9316
+ resolved_specialist: resolvedSpecialist,
9317
+ model: modelCandidates[0],
9318
+ duration_ms: Date.now() - startedAt,
9319
+ trace_id: traceId
9320
+ }
9321
+ };
9322
+ }
9212
9323
  if (process.env.SPECIALISTS_SCRIPT_STUB_OUTPUT) {
9213
9324
  return {
9214
9325
  success: true,
@@ -9224,11 +9335,11 @@ async function runScriptSpecialist(input, options) {
9224
9335
  };
9225
9336
  }
9226
9337
  const timeoutMs = input.timeout_ms ?? spec.specialist.execution.timeout_ms ?? 120000;
9227
- const modelCandidates = collectModelCandidates(input, spec, options);
9228
9338
  const assistantTextLimitBytes = resolveAssistantTextLimitBytes(spec);
9229
9339
  const attempts = [];
9230
9340
  for (const model of modelCandidates) {
9231
- const attempt = await runSingleAttempt(prompt, model, input.thinking_level ?? spec.specialist.execution.thinking_level, timeoutMs, assistantTextLimitBytes, options);
9341
+ const systemPrompt = spec.specialist.prompt.system || undefined;
9342
+ const attempt = await runSingleAttempt(prompt, model, input.thinking_level ?? spec.specialist.execution.thinking_level, timeoutMs, assistantTextLimitBytes, options, systemPrompt, skillPaths);
9232
9343
  attempts.push(attempt);
9233
9344
  const parsed = classifyAttempt(attempt);
9234
9345
  if (parsed.retryable)
@@ -9271,14 +9382,23 @@ function collectModelCandidates(input, spec, options) {
9271
9382
  const candidates = [input.model_override, spec.specialist.execution.model, spec.specialist.execution.fallback_model, options.fallbackModel].filter((value) => typeof value === "string" && value.length > 0);
9272
9383
  return [...new Set(candidates)];
9273
9384
  }
9274
- function runSingleAttempt(prompt, model, thinkingLevel, timeoutMs, assistantTextLimitBytes, options) {
9275
- return new Promise((resolve, reject) => {
9276
- const args = ["--mode", "json", "--no-session", "--no-extensions", "--no-tools", "--model", model];
9385
+ function runSingleAttempt(prompt, model, thinkingLevel, timeoutMs, assistantTextLimitBytes, options, systemPrompt, skillPaths = []) {
9386
+ return new Promise((resolve2, reject) => {
9387
+ const args = ["--mode", "json", "--no-session", "--no-extensions", "--no-tools", "--offline", "--no-context-files", "--no-prompt-templates", "--no-themes"];
9388
+ if (skillPaths.length === 0)
9389
+ args.push("--no-skills");
9390
+ for (const skillPath of skillPaths)
9391
+ args.push("--skill", skillPath);
9392
+ args.push("--model", model);
9277
9393
  if (thinkingLevel)
9278
9394
  args.push("--thinking", thinkingLevel);
9279
- args.push(prompt);
9280
- const pi = spawn("pi", args, { stdio: ["ignore", "pipe", "pipe"] });
9395
+ if (systemPrompt)
9396
+ args.push("--system-prompt", systemPrompt);
9397
+ const pi = spawn("pi", args, { stdio: ["pipe", "pipe", "pipe"], cwd: options.projectDir ?? process.cwd() });
9281
9398
  options.onChild?.(pi);
9399
+ pi.stdin?.on("error", () => {});
9400
+ pi.stdin?.write(prompt);
9401
+ pi.stdin?.end();
9282
9402
  let stderr = "";
9283
9403
  let timedOut = false;
9284
9404
  let outputTooLarge = false;
@@ -9347,7 +9467,7 @@ function runSingleAttempt(prompt, model, thinkingLevel, timeoutMs, assistantText
9347
9467
  pi.on("error", reject);
9348
9468
  pi.on("close", (code) => {
9349
9469
  clearTimeout(timer);
9350
- resolve({
9470
+ resolve2({
9351
9471
  model,
9352
9472
  text: assistantText,
9353
9473
  stderr,
@@ -9386,7 +9506,7 @@ function isRetryableModelFailure(stderr, text) {
9386
9506
  }
9387
9507
  // src/specialist/loader.ts
9388
9508
  import { readdir, readFile, stat } from "node:fs/promises";
9389
- import { basename, join as join2 } from "node:path";
9509
+ import { basename, join as join3 } from "node:path";
9390
9510
  import { existsSync as existsSync3 } from "node:fs";
9391
9511
 
9392
9512
  // node_modules/yaml/dist/index.js
@@ -13266,6 +13386,7 @@ var ExecutionSchema = objectType({
13266
13386
  max_retries: numberType().int().min(0).default(0),
13267
13387
  interactive: booleanType().default(false),
13268
13388
  stdout_limit_bytes: numberType().int().positive().optional(),
13389
+ prompt_limit_bytes: numberType().int().positive().optional(),
13269
13390
  response_format: enumType(["text", "json", "markdown"]).default("text"),
13270
13391
  output_type: enumType(["codegen", "analysis", "review", "synthesis", "orchestration", "workflow", "research", "custom"]).default("custom"),
13271
13392
  permission_required: enumType(["READ_ONLY", "LOW", "MEDIUM", "HIGH"]).default("READ_ONLY"),
@@ -13439,15 +13560,15 @@ class SpecialistLoader {
13439
13560
  }
13440
13561
  getScanDirs() {
13441
13562
  const dirs = [
13442
- { path: join2(this.projectDir, ".specialists", "user"), scope: "user", source: "user" },
13443
- { path: join2(this.projectDir, ".specialists", "user", "specialists"), scope: "user", source: "legacy" },
13444
- { path: join2(this.projectDir, ".specialists", "default"), scope: "default", source: "default-mirror" },
13445
- { path: join2(this.projectDir, ".specialists", "default", "specialists"), scope: "default", source: "legacy" },
13446
- { path: join2(this.projectDir, "config", "specialists"), scope: "package", source: "package-fallback" },
13563
+ { path: join3(this.projectDir, ".specialists", "user"), scope: "user", source: "user" },
13564
+ { path: join3(this.projectDir, ".specialists", "user", "specialists"), scope: "user", source: "legacy" },
13565
+ { path: join3(this.projectDir, ".specialists", "default"), scope: "default", source: "default-mirror" },
13566
+ { path: join3(this.projectDir, ".specialists", "default", "specialists"), scope: "default", source: "legacy" },
13567
+ { path: join3(this.projectDir, "config", "specialists"), scope: "package", source: "package-fallback" },
13447
13568
  { path: resolveCanonicalAssetDir("specialists") ?? "", scope: "package", source: "package-live" },
13448
- { path: join2(this.projectDir, "specialists"), scope: "default", source: "legacy" },
13449
- { path: join2(this.projectDir, ".claude", "specialists"), scope: "default", source: "legacy" },
13450
- { path: join2(this.projectDir, ".agent-forge", "specialists"), scope: "default", source: "legacy" }
13569
+ { path: join3(this.projectDir, "specialists"), scope: "default", source: "legacy" },
13570
+ { path: join3(this.projectDir, ".claude", "specialists"), scope: "default", source: "legacy" },
13571
+ { path: join3(this.projectDir, ".agent-forge", "specialists"), scope: "default", source: "legacy" }
13451
13572
  ];
13452
13573
  return dirs.filter((d) => d.path && existsSync3(d.path));
13453
13574
  }
@@ -13457,11 +13578,11 @@ class SpecialistLoader {
13457
13578
  return JSON.stringify($parse(content));
13458
13579
  }
13459
13580
  resolveSpecialistPath(dirPath, specialistName) {
13460
- const jsonPath = join2(dirPath, `${specialistName}.specialist.json`);
13581
+ const jsonPath = join3(dirPath, `${specialistName}.specialist.json`);
13461
13582
  if (existsSync3(jsonPath)) {
13462
13583
  return { filePath: jsonPath, deprecatedYaml: false };
13463
13584
  }
13464
- const yamlPath = join2(dirPath, `${specialistName}.specialist.yaml`);
13585
+ const yamlPath = join3(dirPath, `${specialistName}.specialist.yaml`);
13465
13586
  if (existsSync3(yamlPath)) {
13466
13587
  return { filePath: yamlPath, deprecatedYaml: true };
13467
13588
  }
@@ -13539,9 +13660,9 @@ class SpecialistLoader {
13539
13660
  const fileDir = dir.path;
13540
13661
  const resolved = rawPaths.map((p) => {
13541
13662
  if (p.startsWith("~/"))
13542
- return join2(process.env.HOME || "", p.slice(2));
13663
+ return join3(process.env.HOME || "", p.slice(2));
13543
13664
  if (p.startsWith("./"))
13544
- return join2(fileDir, p.slice(2));
13665
+ return join3(fileDir, p.slice(2));
13545
13666
  return p;
13546
13667
  });
13547
13668
  spec.specialist.skills.paths = resolved;
@@ -1 +1 @@
1
- {"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../../src/cli/help.ts"],"names":[],"mappings":"AAqEA,wBAAsB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAiGzC"}
1
+ {"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../../src/cli/help.ts"],"names":[],"mappings":"AAoEA,wBAAsB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAgGzC"}
@@ -1 +1 @@
1
- {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/cli/run.ts"],"names":[],"mappings":"AAkjBA,wBAAsB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAgSzC"}
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/cli/run.ts"],"names":[],"mappings":"AAkjBA,wBAAsB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAiSzC"}
@@ -1 +1 @@
1
- {"version":3,"file":"script.d.ts","sourceRoot":"","sources":["../../../src/cli/script.ts"],"names":[],"mappings":"AAEA,OAAO,EAAmD,KAAK,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAE5H,UAAU,UAAU;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,OAAO,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,OAAO,CAAC;CAChB;AAQD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CAsCpD;AAeD,wBAAgB,WAAW,CAAC,MAAM,EAAE,oBAAoB,GAAG,MAAM,CAchE;AAwBD,wBAAsB,GAAG,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CAU/E;AAED,eAAO,MAAM,SAAS;;;CAA6B,CAAC"}
1
+ {"version":3,"file":"script.d.ts","sourceRoot":"","sources":["../../../src/cli/script.ts"],"names":[],"mappings":"AAEA,OAAO,EAAmD,KAAK,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAE5H,UAAU,UAAU;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,OAAO,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,OAAO,CAAC;CAChB;AAQD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CAsCpD;AAeD,wBAAgB,WAAW,CAAC,MAAM,EAAE,oBAAoB,GAAG,MAAM,CAchE;AAwBD,wBAAsB,GAAG,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CAc/E;AAED,eAAO,MAAM,SAAS;;;CAA6B,CAAC"}
@@ -5,14 +5,19 @@ interface ServeArgs {
5
5
  queueTimeoutMs: number;
6
6
  shutdownGraceMs: number;
7
7
  projectDir: string;
8
+ dbPath?: string;
8
9
  fallbackModel?: string;
9
10
  auditFailureThreshold: number;
10
11
  allowSkills: boolean;
11
12
  allowSkillsRoots: string[];
12
- allowLocalScripts: boolean;
13
13
  reloadPollMs: number;
14
+ readinessCanaryMode: 'off' | 'warn' | 'require';
15
+ readinessRequiredPiFlags: string[];
16
+ readinessCanarySpecialist?: string;
17
+ readinessCanaryTimeoutMs: number;
18
+ logLevel: 'off' | 'info' | 'debug';
14
19
  }
15
- export type ReadinessReason = 'draining' | 'degraded:audit' | 'pi_config_unreadable' | 'db_not_writable' | 'empty_user_dir' | 'invalid_spec_in_user_dir';
20
+ export type ReadinessReason = 'draining' | 'degraded:audit' | 'pi_config_unreadable' | 'db_not_writable' | 'pi_binary_missing' | 'pi_flag_missing' | 'pi_smoke_failed' | 'empty_user_dir' | 'invalid_spec_in_user_dir';
16
21
  export interface ReadinessState {
17
22
  shuttingDown: boolean;
18
23
  auditFailures: number[];
@@ -27,13 +32,17 @@ export interface ReadinessCheckOptions {
27
32
  piConfigPath?: string;
28
33
  auditFailureThreshold: number;
29
34
  now?: number;
35
+ piCanaryMode?: 'off' | 'warn' | 'require';
36
+ piCanaryCheck?: () => Promise<ReadinessReason | undefined> | ReadinessReason | undefined;
30
37
  }
31
38
  export declare function evaluateReadiness(opts: ReadinessCheckOptions): Promise<{
32
39
  ready: true;
40
+ warning?: ReadinessReason;
33
41
  } | {
34
42
  ready: false;
35
43
  reason: ReadinessReason;
36
44
  }>;
45
+ export declare function checkPiHelpForFlags(flags?: string[]): ReadinessReason | undefined;
37
46
  export declare function startServe(argv?: string[]): Promise<{
38
47
  server: import("http").Server<typeof IncomingMessage, typeof ServerResponse>;
39
48
  args: ServeArgs;
@@ -1 +1 @@
1
- {"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../../src/cli/serve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AAcpF,UAAU,SAAS;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,WAAW,EAAE,OAAO,CAAC;IACrB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;CACtB;AAID,MAAM,MAAM,eAAe,GACvB,UAAU,GACV,gBAAgB,GAChB,sBAAsB,GACtB,iBAAiB,GACjB,gBAAgB,GAChB,0BAA0B,CAAC;AAE/B,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,wBAAgB,oBAAoB,IAAI,cAAc,CAErD;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,GAAE,MAAmB,GAAG,IAAI,CAIxF;AA8BD,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,cAAc,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC;IAAE,KAAK,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,eAAe,CAAA;CAAE,CAAC,CA4BzI;AAyDD,wBAAsB,UAAU,CAAC,IAAI,GAAE,MAAM,EAA0B;;;;;GAmFtE;AAED,wBAAsB,GAAG,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/E"}
1
+ {"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../../src/cli/serve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AAepF,UAAU,SAAS;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,WAAW,EAAE,OAAO,CAAC;IACrB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,KAAK,GAAG,MAAM,GAAG,SAAS,CAAC;IAChD,wBAAwB,EAAE,MAAM,EAAE,CAAC;IACnC,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,wBAAwB,EAAE,MAAM,CAAC;IACjC,QAAQ,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC;CACpC;AAKD,MAAM,MAAM,eAAe,GACvB,UAAU,GACV,gBAAgB,GAChB,sBAAsB,GACtB,iBAAiB,GACjB,mBAAmB,GACnB,iBAAiB,GACjB,iBAAiB,GACjB,gBAAgB,GAChB,0BAA0B,CAAC;AAE/B,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,wBAAgB,oBAAoB,IAAI,cAAc,CAErD;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,GAAE,MAAmB,GAAG,IAAI,CAIxF;AA8BD,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,cAAc,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,SAAS,CAAC;IAC1C,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC,GAAG,eAAe,GAAG,SAAS,CAAC;CAC1F;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,OAAO,CAAC,EAAE,eAAe,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,eAAe,CAAA;CAAE,CAAC,CAsCpK;AAmDD,wBAAgB,mBAAmB,CAAC,KAAK,GAAE,MAAM,EAA8B,GAAG,eAAe,GAAG,SAAS,CAM5G;AAiDD,wBAAsB,UAAU,CAAC,IAAI,GAAE,MAAM,EAA0B;;;;;GA0KtE;AAED,wBAAsB,GAAG,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/E"}
@@ -1,3 +1,5 @@
1
+ type PackageRequire = (specifier: string) => unknown;
2
+ export declare function readBundledPackageVersion(requireFn?: PackageRequire): string;
1
3
  export declare const localVersion: string;
2
4
  export interface VersionCheckCache {
3
5
  checked_at_ms: number;
@@ -14,4 +16,5 @@ export declare function readCachedVersionCheck(): VersionCheckCache | null;
14
16
  export declare function getVersionCheckResult(): VersionCheckResult | null;
15
17
  export declare function formatVersionCheckNudge(result: VersionCheckResult): string | null;
16
18
  export declare function markVersionCheckNotified(result: VersionCheckResult): void;
19
+ export {};
17
20
  //# sourceMappingURL=version-check.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"version-check.d.ts","sourceRoot":"","sources":["../../../src/cli/version-check.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,YAAY,QAAiB,CAAC;AAM3C,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,iBAAiB,CAAC;CAC1B;AAED,wBAAgB,qBAAqB,IAAI,OAAO,CAK/C;AAWD,wBAAgB,sBAAsB,IAAI,iBAAiB,GAAG,IAAI,CAEjE;AAkDD,wBAAgB,qBAAqB,IAAI,kBAAkB,GAAG,IAAI,CA2BjE;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM,GAAG,IAAI,CAIjF;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAMzE"}
1
+ {"version":3,"file":"version-check.d.ts","sourceRoot":"","sources":["../../../src/cli/version-check.ts"],"names":[],"mappings":"AAOA,KAAK,cAAc,GAAG,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;AAErD,wBAAgB,yBAAyB,CAAC,SAAS,GAAE,cAAwB,GAAG,MAAM,CAYrF;AAID,eAAO,MAAM,YAAY,QAAiB,CAAC;AAM3C,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,iBAAiB,CAAC;CAC1B;AAED,wBAAgB,qBAAqB,IAAI,OAAO,CAK/C;AAWD,wBAAgB,sBAAsB,IAAI,iBAAiB,GAAG,IAAI,CAEjE;AAkDD,wBAAgB,qBAAqB,IAAI,kBAAkB,GAAG,IAAI,CA2BjE;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM,GAAG,IAAI,CAIjF;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAMzE"}
@@ -2,7 +2,7 @@
2
2
  /**
3
3
  * Specialists MCP Server — entry point
4
4
  * Subcommands: install, version, list, view, models, init, db, validate, edit, config, run,
5
- * status, ps, result, feed, poll, clean, merge, epic, end, stop, attach, quickstart, serve, script, release, help
5
+ * status, ps, result, feed, clean, merge, epic, end, stop, attach, quickstart, serve, script, release, help
6
6
  */
7
7
  export {};
8
8
  //# sourceMappingURL=index.d.ts.map
@@ -17,8 +17,13 @@ interface MandatoryRulesIndex {
17
17
  required_template_sets?: string[];
18
18
  default_template_sets?: string[];
19
19
  }
20
+ export interface MandatoryRulesSection {
21
+ setId: string;
22
+ block: string;
23
+ }
20
24
  export interface MandatoryRulesInjection {
21
25
  block: string;
26
+ sections: MandatoryRulesSection[];
22
27
  setsLoaded: string[];
23
28
  ruleCount: number;
24
29
  inlineRulesCount: number;
@@ -1 +1 @@
1
- {"version":3,"file":"mandatory-rules.d.ts","sourceRoot":"","sources":["../../../src/specialist/mandatory-rules.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,aAAa,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,8BAA8B;IAC7C,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,YAAY,CAAC,EAAE,aAAa,EAAE,CAAC;CAChC;AAED,UAAU,mBAAmB;IAC3B,sBAAsB,CAAC,EAAE,MAAM,EAAE,CAAC;IAClC,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,OAAO,CAAC;CAC1B;AAsBD,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI,CAwB/E;AAiKD,wBAAgB,4BAA4B,CAC1C,gBAAgB,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,8BAA8B,CAAA;KAAE,CAAA;CAAE,GACpG,uBAAuB,CA4BzB;AAED,wBAAgB,wBAAwB,CAAC,gBAAgB,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,8BAA8B,CAAA;KAAE,CAAA;CAAE,GAAG,MAAM,CAEtJ"}
1
+ {"version":3,"file":"mandatory-rules.d.ts","sourceRoot":"","sources":["../../../src/specialist/mandatory-rules.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,aAAa,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,8BAA8B;IAC7C,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,YAAY,CAAC,EAAE,aAAa,EAAE,CAAC;CAChC;AAED,UAAU,mBAAmB;IAC3B,sBAAsB,CAAC,EAAE,MAAM,EAAE,CAAC;IAClC,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,qBAAqB,EAAE,CAAC;IAClC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,OAAO,CAAC;CAC1B;AAsBD,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI,CAwB/E;AAoKD,wBAAgB,4BAA4B,CAC1C,gBAAgB,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,8BAA8B,CAAA;KAAE,CAAA;CAAE,GACpG,uBAAuB,CA6BzB;AAED,wBAAgB,wBAAwB,CAAC,gBAAgB,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,8BAA8B,CAAA;KAAE,CAAA;CAAE,GAAG,MAAM,CAEtJ"}
@@ -257,5 +257,6 @@ export interface ObservabilitySqliteClient {
257
257
  }
258
258
  export declare function hasRunCompleteEvent(jobId: string, cwd?: string): boolean;
259
259
  export declare function createObservabilitySqliteClient(cwd?: string): ObservabilitySqliteClient | null;
260
+ export declare function createObservabilitySqliteClientAtPath(dbPath: string): ObservabilitySqliteClient | null;
260
261
  export {};
261
262
  //# sourceMappingURL=observability-sqlite.d.ts.map