@wrongstack/core 0.277.2 → 0.280.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 (83) hide show
  1. package/dist/{agent-bridge-BFJ2ODzI.d.ts → agent-bridge-DXC6QDJ4.d.ts} +1 -1
  2. package/dist/{agent-subagent-runner-BimKihiC.d.ts → agent-subagent-runner-PoqNKiR4.d.ts} +563 -471
  3. package/dist/{compactor-D3BGw26y.d.ts → compactor-U3agvUIG.d.ts} +1 -1
  4. package/dist/{config-DAOjriz9.d.ts → config-Cr3312zc.d.ts} +102 -4
  5. package/dist/coordination/index.d.ts +1087 -998
  6. package/dist/coordination/index.js +12235 -12052
  7. package/dist/coordination/index.js.map +1 -1
  8. package/dist/defaults/index.d.ts +31 -30
  9. package/dist/defaults/index.js +403 -189
  10. package/dist/defaults/index.js.map +1 -1
  11. package/dist/{brain-CCfuEOdp.d.ts → events-Bs2fmldo.d.ts} +117 -112
  12. package/dist/execution/index.d.ts +27 -19
  13. package/dist/execution/index.js +216 -63
  14. package/dist/execution/index.js.map +1 -1
  15. package/dist/execution/prompt-enhancer.d.ts +1 -1
  16. package/dist/execution/prompt-enhancer.js.map +1 -1
  17. package/dist/extension/index.d.ts +8 -7
  18. package/dist/{global-mailbox-Dr4cTKqL.d.ts → global-mailbox-Ct7IorLJ.d.ts} +84 -6
  19. package/dist/{goal-store-C1uH4srH.d.ts → goal-store-C4F6DjC0.d.ts} +1 -1
  20. package/dist/hq/index.d.ts +504 -7
  21. package/dist/hq/index.js +1069 -20
  22. package/dist/hq/index.js.map +1 -1
  23. package/dist/{index-DJXj-dcr.d.ts → index-kidebiDh.d.ts} +8 -5
  24. package/dist/{index-cMEmzCVN.d.ts → index-nP09-oP2.d.ts} +2 -2
  25. package/dist/index.d.ts +153 -76
  26. package/dist/index.js +5791 -3163
  27. package/dist/index.js.map +1 -1
  28. package/dist/infrastructure/index.d.ts +7 -6
  29. package/dist/kernel/index.d.ts +14 -13
  30. package/dist/kernel/index.js +31 -15
  31. package/dist/kernel/index.js.map +1 -1
  32. package/dist/{mailbox-types-DTl7bRH3.d.ts → mailbox-types-BGZWrYTJ.d.ts} +38 -0
  33. package/dist/{mcp-servers-CFb60-pH.d.ts → mcp-servers-D910X5_r.d.ts} +3 -3
  34. package/dist/models/index.d.ts +5 -5
  35. package/dist/models/index.js.map +1 -1
  36. package/dist/{models-registry-5Ufn7f2m.d.ts → models-registry-CLkoOcHk.d.ts} +1 -1
  37. package/dist/{multi-agent-coordinator-CcrcncvG.d.ts → multi-agent-coordinator-CieyUoEL.d.ts} +1 -1
  38. package/dist/{null-fleet-bus-C9KsYyrI.d.ts → null-fleet-bus-DkdmZJ_W.d.ts} +464 -464
  39. package/dist/observability/index.d.ts +3 -2
  40. package/dist/{path-resolver-CEeX9I7O.d.ts → path-resolver-XfZ9eLxG.d.ts} +3 -3
  41. package/dist/{permission-DbsGOA1C.d.ts → permission-Dx6dIqS2.d.ts} +2 -7
  42. package/dist/{permission-policy-BpEea3r7.d.ts → permission-policy-C8vJcnX5.d.ts} +2 -2
  43. package/dist/{pipeline-CEjBjzVA.d.ts → pipeline-BwAP21_4.d.ts} +9 -4
  44. package/dist/{provider-model-resolve-BpfXp3Jj.d.ts → provider-model-resolve-CwQNZWt_.d.ts} +3 -3
  45. package/dist/{provider-runner-CnOSr5BN.d.ts → provider-runner-CYHFImzV.d.ts} +3 -3
  46. package/dist/{retry-policy-Git9WF6d.d.ts → retry-policy-D4feSLk3.d.ts} +1 -1
  47. package/dist/sdd/index.d.ts +11 -10
  48. package/dist/sdd/index.js +2 -2
  49. package/dist/sdd/index.js.map +1 -1
  50. package/dist/secret-scrubber-3MHDDAtm.d.ts +6 -0
  51. package/dist/{secret-vault-DDSMHqIm.d.ts → secret-vault-CImt2XrR.d.ts} +1 -1
  52. package/dist/security/index.d.ts +6 -5
  53. package/dist/security/index.js.map +1 -1
  54. package/dist/{selector-Cq72C0Oy.d.ts → selector-Dy-MzKp1.d.ts} +1 -1
  55. package/dist/{session-event-bridge-DG94B3Bk.d.ts → session-event-bridge-CqdiGnfU.d.ts} +1 -1
  56. package/dist/{session-reader-BzT-iMQT.d.ts → session-reader-Hk0WbNm9.d.ts} +1 -1
  57. package/dist/{skill-DGIXCtdv.d.ts → skill-DHniprNl.d.ts} +15 -1
  58. package/dist/skills/index.d.ts +472 -26
  59. package/dist/skills/index.js +872 -129
  60. package/dist/skills/index.js.map +1 -1
  61. package/dist/storage/index.d.ts +27 -14
  62. package/dist/storage/index.js +264 -85
  63. package/dist/storage/index.js.map +1 -1
  64. package/dist/{strategy-compactor-Bt_ZH6R0.d.ts → strategy-compactor-CQwhbErd.d.ts} +32 -17
  65. package/dist/{todos-checkpoint-CH1pcua9.d.ts → todos-checkpoint-Bk2uP7Ex.d.ts} +6 -6
  66. package/dist/{context-DPlA6kid.d.ts → tool-BkOgs_KL.d.ts} +306 -286
  67. package/dist/{tool-executor-SVFq7IOR.d.ts → tool-executor-SiE1wlZo.d.ts} +9 -9
  68. package/dist/tools/index.d.ts +2 -2
  69. package/dist/tools/index.js.map +1 -1
  70. package/dist/types/index.d.ts +22 -21
  71. package/dist/types/index.js +7 -9
  72. package/dist/types/index.js.map +1 -1
  73. package/dist/utils/index.d.ts +30 -4
  74. package/dist/utils/index.js +50 -1
  75. package/dist/utils/index.js.map +1 -1
  76. package/dist/{worktree-manager-C4YIf1Fa.d.ts → worktree-manager-BjOFF6bt.d.ts} +1 -1
  77. package/dist/{wstack-paths-_NrRovdr.d.ts → wstack-paths-CMl_cYgq.d.ts} +8 -0
  78. package/package.json +1 -1
  79. package/skills/mailbox-bridge/SKILL.md +1 -0
  80. package/skills/plugin-author/SKILL.md +350 -0
  81. package/skills/sdd/SKILL.md +134 -134
  82. package/skills/skill-creator/SKILL.md +45 -7
  83. package/skills/wrongstack-mailbox/SKILL.md +40 -21
@@ -70,8 +70,8 @@ async function atomicWrite(targetPath, content, opts = {}) {
70
70
  }
71
71
  let mode;
72
72
  try {
73
- const stat10 = await fsp7.stat(targetPath);
74
- mode = stat10.mode & 511;
73
+ const stat11 = await fsp7.stat(targetPath);
74
+ mode = stat11.mode & 511;
75
75
  } catch {
76
76
  mode = opts.mode;
77
77
  }
@@ -117,8 +117,8 @@ async function withFileLock(targetPath, fn, opts = {}) {
117
117
  }
118
118
  if (code !== "EEXIST") throw err;
119
119
  try {
120
- const stat10 = await fsp7.stat(lockPath);
121
- if (Date.now() - stat10.mtimeMs > staleMs) {
120
+ const stat11 = await fsp7.stat(lockPath);
121
+ if (Date.now() - stat11.mtimeMs > staleMs) {
122
122
  await fsp7.unlink(lockPath);
123
123
  continue;
124
124
  }
@@ -380,6 +380,7 @@ function createContextEvidenceState() {
380
380
  toolCalls: [],
381
381
  fileGraph: {},
382
382
  repeatedReads: [],
383
+ completedWork: [],
383
384
  updatedAt: Date.now()
384
385
  };
385
386
  }
@@ -442,6 +443,7 @@ function ensureEvidence(ctx) {
442
443
  if (!ctx.contextEvidence) {
443
444
  ctx.contextEvidence = createContextEvidenceState();
444
445
  }
446
+ ctx.contextEvidence.completedWork ??= [];
445
447
  return ctx.contextEvidence;
446
448
  }
447
449
  var MAX_DIGEST_CHARS;
@@ -627,8 +629,8 @@ async function expandGlob(pattern) {
627
629
  for (const e of entries) {
628
630
  const full = `${dir}${SEP}${e}`;
629
631
  try {
630
- const stat10 = await fsp7.stat(full);
631
- if (stat10.isDirectory()) await walk3(full, rest);
632
+ const stat11 = await fsp7.stat(full);
633
+ if (stat11.isDirectory()) await walk3(full, rest);
632
634
  } catch {
633
635
  }
634
636
  }
@@ -645,8 +647,8 @@ async function expandGlob(pattern) {
645
647
  if (entries.includes(seg)) {
646
648
  const full = `${dir}${SEP}${seg}`;
647
649
  try {
648
- const stat10 = await fsp7.stat(full);
649
- if (stat10.isDirectory()) await walk3(full, rest);
650
+ const stat11 = await fsp7.stat(full);
651
+ if (stat11.isDirectory()) await walk3(full, rest);
650
652
  } catch {
651
653
  }
652
654
  }
@@ -2277,16 +2279,20 @@ function wstackGlobalRoot() {
2277
2279
  }
2278
2280
  function resolveWstackPaths(opts) {
2279
2281
  const globalRoot = opts.globalRoot ?? (opts.userHome ? path4.join(opts.userHome, ".wrongstack") : wstackGlobalRoot());
2282
+ const homeDir = opts.userHome ?? os.homedir();
2280
2283
  const hash = projectHash(opts.projectRoot);
2281
2284
  const slug = projectSlug(opts.projectRoot);
2282
2285
  const projectDir = path4.join(globalRoot, "projects", slug);
2283
2286
  return {
2284
2287
  globalRoot,
2288
+ projectRoot: opts.projectRoot,
2289
+ homeDir,
2285
2290
  configDir: globalRoot,
2286
2291
  globalConfig: path4.join(globalRoot, "config.json"),
2287
2292
  secretsKey: path4.join(globalRoot, ".key"),
2288
2293
  globalMemory: path4.join(globalRoot, "memory.md"),
2289
2294
  globalSkills: path4.join(globalRoot, "skills"),
2295
+ globalClaudeSkills: path4.join(homeDir, ".claude", "skills"),
2290
2296
  globalDesignKits: path4.join(globalRoot, "design-kits"),
2291
2297
  globalPrompts: path4.join(globalRoot, "prompts"),
2292
2298
  globalInstructions: path4.join(globalRoot, "instructions"),
@@ -2306,6 +2312,7 @@ function resolveWstackPaths(opts) {
2306
2312
  inProjectConfig: path4.join(opts.projectRoot, ".wrongstack", "config.json"),
2307
2313
  inProjectAgentsFile: path4.join(opts.projectRoot, ".wrongstack", "AGENTS.md"),
2308
2314
  inProjectSkills: path4.join(opts.projectRoot, ".wrongstack", "skills"),
2315
+ inProjectClaudeSkills: path4.join(opts.projectRoot, ".claude", "skills"),
2309
2316
  inProjectPrompts: path4.join(opts.projectRoot, ".wrongstack", "prompts"),
2310
2317
  inProjectInstructions: path4.join(opts.projectRoot, ".wrongstack", "instructions"),
2311
2318
  inProjectDesignKits: path4.join(opts.projectRoot, ".wrongstack", "design-kits"),
@@ -5821,7 +5828,7 @@ var CollabSession = class extends EventEmitter {
5821
5828
  }
5822
5829
  for (const filePath of allFiles) {
5823
5830
  try {
5824
- const [content, stat10] = await Promise.all([
5831
+ const [content, stat11] = await Promise.all([
5825
5832
  fsp7.readFile(filePath, "utf8"),
5826
5833
  fsp7.stat(filePath)
5827
5834
  ]);
@@ -5831,8 +5838,8 @@ var CollabSession = class extends EventEmitter {
5831
5838
  path: filePath,
5832
5839
  content,
5833
5840
  language,
5834
- snapshotMtimeMs: stat10.mtimeMs,
5835
- snapshotSizeBytes: stat10.size
5841
+ snapshotMtimeMs: stat11.mtimeMs,
5842
+ snapshotSizeBytes: stat11.size
5836
5843
  });
5837
5844
  } catch {
5838
5845
  this.snapshot.files.push({ path: filePath, content: "", language: void 0 });
@@ -6245,9 +6252,9 @@ Emit each evaluation immediately. Do not wait until you have read all reports.`;
6245
6252
  for (const file of this.snapshot.files) {
6246
6253
  if (file.snapshotMtimeMs === void 0 && file.snapshotSizeBytes === void 0) continue;
6247
6254
  try {
6248
- const stat10 = await fsp7.stat(file.path);
6249
- const mtimeChanged = file.snapshotMtimeMs !== void 0 && stat10.mtimeMs > file.snapshotMtimeMs + 1;
6250
- const sizeChanged = file.snapshotSizeBytes !== void 0 && stat10.size !== file.snapshotSizeBytes;
6255
+ const stat11 = await fsp7.stat(file.path);
6256
+ const mtimeChanged = file.snapshotMtimeMs !== void 0 && stat11.mtimeMs > file.snapshotMtimeMs + 1;
6257
+ const sizeChanged = file.snapshotSizeBytes !== void 0 && stat11.size !== file.snapshotSizeBytes;
6251
6258
  if (mtimeChanged || sizeChanged) {
6252
6259
  warnings.push(`${file.path} changed after the collab snapshot was captured.`);
6253
6260
  }
@@ -6333,7 +6340,7 @@ function readBundledInstructionText(relativePath) {
6333
6340
  function renderInstructionTemplate(template, values) {
6334
6341
  return template.replace(
6335
6342
  /\{\{\s*([a-zA-Z0-9_.-]+)\s*\}\}/g,
6336
- (match, key) => Object.prototype.hasOwnProperty.call(values, key) ? values[key] ?? "" : match
6343
+ (match, key) => Object.hasOwn(values, key) ? values[key] ?? "" : match
6337
6344
  );
6338
6345
  }
6339
6346
  function instructionRootCandidates() {
@@ -9026,6 +9033,7 @@ var Director = class _Director {
9026
9033
  if (entry?.model) {
9027
9034
  config.model = entry.model;
9028
9035
  if (entry.provider) config.provider = entry.provider;
9036
+ if (entry.modelRuntime) config.modelRuntime = entry.modelRuntime;
9029
9037
  }
9030
9038
  }
9031
9039
  if (this.fleetManager) {
@@ -10547,9 +10555,9 @@ var DefaultSessionStore = class _DefaultSessionStore {
10547
10555
  let cacheHit = false;
10548
10556
  try {
10549
10557
  const s = await fsp7.stat(file);
10550
- const stat10 = { mtimeMs: s.mtimeMs, size: s.size };
10558
+ const stat11 = { mtimeMs: s.mtimeMs, size: s.size };
10551
10559
  const cached = this._loadCache.get(id);
10552
- if (cached && cached.mtimeMs === stat10.mtimeMs && cached.size === stat10.size) {
10560
+ if (cached && cached.mtimeMs === stat11.mtimeMs && cached.size === stat11.size) {
10553
10561
  cacheHit = true;
10554
10562
  this._loadCache.delete(id);
10555
10563
  this._loadCache.set(id, cached);
@@ -10672,7 +10680,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
10672
10680
  this._loadCache.delete(oldest);
10673
10681
  }
10674
10682
  }
10675
- this._loadCache.set(id, { mtimeMs: stat10.mtimeMs, size: stat10.size, data });
10683
+ this._loadCache.set(id, { mtimeMs: stat11.mtimeMs, size: stat11.size, data });
10676
10684
  }
10677
10685
  return data;
10678
10686
  } catch (err) {
@@ -10714,14 +10722,14 @@ var DefaultSessionStore = class _DefaultSessionStore {
10714
10722
  const limit = opts?.limit;
10715
10723
  const signal = opts?.signal;
10716
10724
  const out = [];
10717
- let stat10;
10725
+ let stat11;
10718
10726
  try {
10719
- stat10 = await fsp7.stat(file);
10727
+ stat11 = await fsp7.stat(file);
10720
10728
  } catch (err) {
10721
10729
  if (err.code === "ENOENT") return [];
10722
10730
  throw err;
10723
10731
  }
10724
- if (stat10.size === 0) return [];
10732
+ if (stat11.size === 0) return [];
10725
10733
  let fh;
10726
10734
  try {
10727
10735
  fh = await fsp7.open(file, "r");
@@ -10904,15 +10912,15 @@ var DefaultSessionStore = class _DefaultSessionStore {
10904
10912
  * Returns empty array when the index doesn't exist or is corrupt.
10905
10913
  */
10906
10914
  async readIndex() {
10907
- let stat10;
10915
+ let stat11;
10908
10916
  try {
10909
10917
  const s = await fsp7.stat(this.indexFile);
10910
- stat10 = { mtimeMs: s.mtimeMs, size: s.size };
10918
+ stat11 = { mtimeMs: s.mtimeMs, size: s.size };
10911
10919
  } catch {
10912
10920
  this._indexCache = null;
10913
10921
  return [];
10914
10922
  }
10915
- if (this._indexCache !== null && this._indexCache.mtimeMs === stat10.mtimeMs && this._indexCache.size === stat10.size) {
10923
+ if (this._indexCache !== null && this._indexCache.mtimeMs === stat11.mtimeMs && this._indexCache.size === stat11.size) {
10916
10924
  return [...this._indexCache.summaries];
10917
10925
  }
10918
10926
  let raw;
@@ -10945,7 +10953,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
10945
10953
  if (a.startedAt > b.startedAt) return -1;
10946
10954
  return a.id.localeCompare(b.id);
10947
10955
  });
10948
- this._indexCache = { ...stat10, summaries };
10956
+ this._indexCache = { ...stat11, summaries };
10949
10957
  return [...summaries];
10950
10958
  }
10951
10959
  /**
@@ -11112,8 +11120,8 @@ var DefaultSessionStore = class _DefaultSessionStore {
11112
11120
  if (fromManifest) return fromManifest;
11113
11121
  try {
11114
11122
  const full = this.sessionPath(id, ".jsonl");
11115
- const stat10 = await fsp7.stat(full);
11116
- const summary = await this.summarize(id, stat10.mtime.toISOString());
11123
+ const stat11 = await fsp7.stat(full);
11124
+ const summary = await this.summarize(id, stat11.mtime.toISOString());
11117
11125
  await atomicWrite(manifest, JSON.stringify(summary), { mode: 384 }).catch((err) => {
11118
11126
  const msg = toErrorMessage(err);
11119
11127
  this.emitError(id, manifest, "summary_fallback", msg, true);
@@ -11156,18 +11164,18 @@ var DefaultSessionStore = class _DefaultSessionStore {
11156
11164
  async summaryHeaderFor(ref) {
11157
11165
  let mtime = (/* @__PURE__ */ new Date(0)).toISOString();
11158
11166
  try {
11159
- const stat10 = await fsp7.stat(ref.filePath);
11160
- if (!stat10.isFile()) {
11167
+ const stat11 = await fsp7.stat(ref.filePath);
11168
+ if (!stat11.isFile()) {
11161
11169
  return {
11162
11170
  id: ref.id,
11163
11171
  title: "(damaged)",
11164
- startedAt: stat10.mtime.toISOString(),
11172
+ startedAt: stat11.mtime.toISOString(),
11165
11173
  model: "unknown",
11166
11174
  provider: "unknown",
11167
11175
  tokenTotal: 0
11168
11176
  };
11169
11177
  }
11170
- mtime = stat10.mtime.toISOString();
11178
+ mtime = stat11.mtime.toISOString();
11171
11179
  } catch {
11172
11180
  return null;
11173
11181
  }
@@ -11268,8 +11276,8 @@ var DefaultSessionStore = class _DefaultSessionStore {
11268
11276
  const pruneFile = async (dir, name, prefix) => {
11269
11277
  const jsonlPath = path4.join(dir, name);
11270
11278
  try {
11271
- const stat10 = await fsp7.stat(jsonlPath);
11272
- if (stat10.mtimeMs >= cutoff) return;
11279
+ const stat11 = await fsp7.stat(jsonlPath);
11280
+ if (stat11.mtimeMs >= cutoff) return;
11273
11281
  } catch {
11274
11282
  return;
11275
11283
  }
@@ -13110,7 +13118,7 @@ async function recordOverrides(projectRoot, patch, isoTime) {
13110
13118
  if (!active) return void 0;
13111
13119
  const merged = { ...active.overrides ?? {} };
13112
13120
  for (const [k, v] of Object.entries(patch)) {
13113
- if (v && v.trim()) merged[k] = v.trim();
13121
+ if (v?.trim()) merged[k] = v.trim();
13114
13122
  else delete merged[k];
13115
13123
  }
13116
13124
  try {
@@ -15925,6 +15933,134 @@ Summarize the following message range:`;
15925
15933
  return estimateMessages(messages);
15926
15934
  }
15927
15935
  };
15936
+
15937
+ // src/skills/foreign-sources.ts
15938
+ var FOREIGN_SKILL_TOOLS = [
15939
+ { id: "agents", subdir: "skills" },
15940
+ // shared store (asm / agentskills.io ecosystem)
15941
+ { id: "codex", subdir: "skills" },
15942
+ // OpenAI Codex CLI
15943
+ { id: "gemini", subdir: "skills" },
15944
+ // Gemini CLI
15945
+ { id: "cursor", subdir: "skills" },
15946
+ // Cursor (standard subdir, aligned with skills.sh ecosystem)
15947
+ { id: "qwen", subdir: "skills" },
15948
+ // Qwen Code
15949
+ { id: "trae", subdir: "skills" },
15950
+ // Trae
15951
+ { id: "windsurf", subdir: "skills" }
15952
+ // Windsurf
15953
+ ];
15954
+ var KNOWN_FOREIGN_IDS = new Set(FOREIGN_SKILL_TOOLS.map((t) => t.id));
15955
+ function resolveForeignToolIds(opt) {
15956
+ return resolveForeignToolIdsWithWarnings(opt).ids;
15957
+ }
15958
+ function resolveForeignToolIdsWithWarnings(opt) {
15959
+ if (opt === false) return { ids: [], unknownIds: [] };
15960
+ if (Array.isArray(opt)) {
15961
+ const ids = [];
15962
+ const unknownIds = [];
15963
+ for (const id of opt) {
15964
+ if (KNOWN_FOREIGN_IDS.has(id)) ids.push(id);
15965
+ else unknownIds.push(id);
15966
+ }
15967
+ return { ids, unknownIds };
15968
+ }
15969
+ return { ids: FOREIGN_SKILL_TOOLS.map((t) => t.id), unknownIds: [] };
15970
+ }
15971
+
15972
+ // src/skills/frontmatter.ts
15973
+ var SCALAR_KEYS = /* @__PURE__ */ new Set(["name", "description", "version", "license", "compatibility"]);
15974
+ function parseSkillFrontmatter(raw) {
15975
+ const text = normalizeLineEndings(raw);
15976
+ if (!text.startsWith("---")) return {};
15977
+ const end = text.indexOf("\n---", 4);
15978
+ if (end === -1) return {};
15979
+ return parseFrontmatterBlock(text.slice(4, end));
15980
+ }
15981
+ function normalizeLineEndings(s) {
15982
+ return s.replace(/\r\n?/g, "\n");
15983
+ }
15984
+ function parseFrontmatterBlock(block) {
15985
+ const out = {};
15986
+ const lines = block.split("\n");
15987
+ let i = 0;
15988
+ while (i < lines.length) {
15989
+ const line = lines[i] ?? "";
15990
+ const m = /^([a-zA-Z][a-zA-Z0-9_-]*):\s*(.*)$/.exec(line);
15991
+ if (!m) {
15992
+ i++;
15993
+ continue;
15994
+ }
15995
+ const key = m[1] ?? "";
15996
+ const rest = (m[2] ?? "").trim();
15997
+ if (key === "metadata") {
15998
+ const map = {};
15999
+ i++;
16000
+ while (i < lines.length) {
16001
+ const sub = lines[i] ?? "";
16002
+ const sm = /^\s+([a-zA-Z0-9_.-]+):\s*(.*)$/.exec(sub);
16003
+ if (!sm) break;
16004
+ map[sm[1] ?? ""] = unquote((sm[2] ?? "").trim());
16005
+ i++;
16006
+ }
16007
+ if (Object.keys(map).length > 0) out.metadata = map;
16008
+ continue;
16009
+ }
16010
+ if (rest === "|" || rest === ">") {
16011
+ const collected = [];
16012
+ i++;
16013
+ while (i < lines.length) {
16014
+ const sub = lines[i] ?? "";
16015
+ if (sub === "" || sub.startsWith(" ") || sub.startsWith(" ")) {
16016
+ collected.push(sub.replace(/^\s+/, ""));
16017
+ i++;
16018
+ } else break;
16019
+ }
16020
+ out[normalizeKey(key)] = collected.join("\n").trim();
16021
+ continue;
16022
+ }
16023
+ if (key === "allowed-tools" || key === "allowedTools") {
16024
+ out.allowedTools = rest.split(/[\s,]+/).filter(Boolean);
16025
+ i++;
16026
+ continue;
16027
+ }
16028
+ if (SCALAR_KEYS.has(key)) {
16029
+ out[key] = unquote(rest);
16030
+ i++;
16031
+ continue;
16032
+ }
16033
+ i++;
16034
+ }
16035
+ return out;
16036
+ }
16037
+ function normalizeKey(key) {
16038
+ return key === "allowed-tools" ? "allowedTools" : key;
16039
+ }
16040
+ function unquote(s) {
16041
+ if (s.length >= 2 && (s.startsWith('"') && s.endsWith('"') || s.startsWith("'") && s.endsWith("'"))) {
16042
+ return s.slice(1, -1);
16043
+ }
16044
+ return s;
16045
+ }
16046
+ function isValidSkillNameFormat(name) {
16047
+ return name.length >= 1 && name.length <= 64 && /^[a-z0-9]+(-[a-z0-9]+)*$/.test(name);
16048
+ }
16049
+
16050
+ // src/skills/limits.ts
16051
+ var SKILL_LIMITS = {
16052
+ /**
16053
+ * Auto-compact body limits (the token-saving fallback used when a skill has
16054
+ * no hand-crafted `SKILL.save.md`). The Overview and Rules sections are
16055
+ * extracted and trimmed to these char budgets, then the total is capped.
16056
+ *
16057
+ * Consumer: `DefaultSkillLoader.compactSkillBody`.
16058
+ */
16059
+ COMPACT_OVERVIEW_MAX: 200,
16060
+ COMPACT_RULES_MAX: 350,
16061
+ COMPACT_TOTAL_MAX: 450};
16062
+
16063
+ // src/execution/skill-loader.ts
15928
16064
  function stripFrontmatter2(raw) {
15929
16065
  if (!raw.startsWith("---")) return raw;
15930
16066
  const end = raw.indexOf("\n---", 4);
@@ -15938,21 +16074,33 @@ function compactSkillBody(body) {
15938
16074
  const overviewMatch = body.match(/##\s*Overview\s*\n([\s\S]*?)(?=\n##|\n$|$)/i);
15939
16075
  const overview = overviewMatch?.[1];
15940
16076
  if (overview?.trim()) {
15941
- sections.push(overview.trim().slice(0, 200));
16077
+ sections.push(overview.trim().slice(0, SKILL_LIMITS.COMPACT_OVERVIEW_MAX));
15942
16078
  }
15943
16079
  const rulesMatch = body.match(/##\s*Rules\s*\n([\s\S]*?)(?=\n##|\n$|$)/i);
15944
16080
  const rules = rulesMatch?.[1];
15945
16081
  if (rules?.trim()) {
15946
- const trimmed = rules.trim().slice(0, 350);
16082
+ const trimmed = rules.trim().slice(0, SKILL_LIMITS.COMPACT_RULES_MAX);
15947
16083
  const ruleLines = trimmed.split("\n").filter((l) => /^\s*[-*]\s/.test(l) || /^\s*\d+[.)]\s/.test(l)).slice(0, 6).join("\n");
15948
16084
  if (ruleLines) sections.push(ruleLines);
15949
16085
  }
15950
16086
  if (sections.length === 0) {
15951
- const first = body.trim().slice(0, 200);
16087
+ const first = body.trim().slice(0, SKILL_LIMITS.COMPACT_OVERVIEW_MAX);
15952
16088
  if (first) sections.push(first);
15953
16089
  }
15954
16090
  const result = sections.join("\n\n");
15955
- return result.length > 450 ? result.slice(0, 447) + "\u2026" : result;
16091
+ const total = SKILL_LIMITS.COMPACT_TOTAL_MAX;
16092
+ return result.length > total ? result.slice(0, total - 3) + "\u2026" : result;
16093
+ }
16094
+ async function entryIsDirectory(dir, entry) {
16095
+ if (entry.isDirectory()) return true;
16096
+ if (entry.isSymbolicLink()) {
16097
+ try {
16098
+ return (await fsp7.stat(path4.join(dir, entry.name))).isDirectory();
16099
+ } catch {
16100
+ return false;
16101
+ }
16102
+ }
16103
+ return false;
15956
16104
  }
15957
16105
  var DefaultSkillLoader = class {
15958
16106
  dirs;
@@ -15960,36 +16108,58 @@ var DefaultSkillLoader = class {
15960
16108
  entriesCache;
15961
16109
  bodyCache = /* @__PURE__ */ new Map();
15962
16110
  constructor(opts) {
15963
- this.dirs = [
15964
- { dir: opts.paths.inProjectSkills, source: "project" },
15965
- { dir: opts.paths.globalSkills, source: "user" }
15966
- ];
15967
- if (opts.bundledDir) {
15968
- this.dirs.push({ dir: opts.bundledDir, source: "bundled" });
15969
- }
16111
+ const readClaude = opts.readClaudeSkills !== false;
16112
+ const foreignIds = resolveForeignToolIds(opts.foreignSources);
16113
+ const dirs = [];
16114
+ const pushForeign = (root) => {
16115
+ if (!root) return;
16116
+ for (const tool of FOREIGN_SKILL_TOOLS) {
16117
+ if (!foreignIds.includes(tool.id)) continue;
16118
+ dirs.push({
16119
+ dir: path4.join(root, "." + tool.id, tool.subdir),
16120
+ source: "foreign",
16121
+ originTool: tool.id
16122
+ });
16123
+ }
16124
+ };
16125
+ dirs.push({ dir: opts.paths.inProjectSkills, source: "project" });
16126
+ if (readClaude) dirs.push({ dir: opts.paths.inProjectClaudeSkills, source: "claude-project" });
16127
+ pushForeign(opts.paths.projectRoot);
16128
+ dirs.push({ dir: opts.paths.globalSkills, source: "user" });
16129
+ if (readClaude) dirs.push({ dir: opts.paths.globalClaudeSkills, source: "claude-user" });
16130
+ pushForeign(opts.paths.homeDir);
16131
+ for (const d of opts.extraDirs ?? []) dirs.push({ dir: d, source: "extra" });
16132
+ if (opts.bundledDir) dirs.push({ dir: opts.bundledDir, source: "bundled" });
16133
+ this.dirs = dirs;
15970
16134
  }
15971
16135
  async list() {
15972
16136
  if (this.cache) return this.cache;
15973
16137
  const found = [];
15974
16138
  const seen = /* @__PURE__ */ new Set();
15975
- for (const { dir, source } of this.dirs) {
16139
+ for (const { dir, source, originTool } of this.dirs) {
15976
16140
  try {
15977
16141
  const entries = await fsp7.readdir(dir, { withFileTypes: true });
15978
16142
  for (const e of entries) {
15979
- if (!e.isDirectory()) continue;
16143
+ if (!await entryIsDirectory(dir, e)) continue;
15980
16144
  const skillFile = path4.join(dir, e.name, "SKILL.md");
15981
16145
  try {
15982
16146
  const raw = await fsp7.readFile(skillFile, "utf8");
15983
- const meta = parseFrontmatter(raw);
15984
- if (!meta.name || !meta.description) continue;
15985
- if (seen.has(meta.name)) continue;
15986
- seen.add(meta.name);
16147
+ const fm = parseSkillFrontmatter(raw);
16148
+ if (!fm.name || !fm.description) continue;
16149
+ if (!isValidSkillNameFormat(fm.name)) continue;
16150
+ if (seen.has(fm.name)) continue;
16151
+ seen.add(fm.name);
15987
16152
  found.push({
15988
- name: meta.name,
15989
- description: meta.description,
15990
- version: meta.version,
16153
+ name: fm.name,
16154
+ description: fm.description,
16155
+ version: fm.version,
16156
+ license: fm.license,
16157
+ compatibility: fm.compatibility,
16158
+ metadata: fm.metadata,
16159
+ allowedTools: fm.allowedTools,
15991
16160
  path: skillFile,
15992
- source
16161
+ source,
16162
+ originTool
15993
16163
  });
15994
16164
  } catch {
15995
16165
  }
@@ -16022,7 +16192,14 @@ var DefaultSkillLoader = class {
16022
16192
  const entries = [];
16023
16193
  for (const s of skills) {
16024
16194
  const { trigger, scope } = parseDescriptionFromText(s.description ?? "");
16025
- entries.push({ name: s.name, trigger, scope, source: s.source, path: s.path });
16195
+ entries.push({
16196
+ name: s.name,
16197
+ trigger,
16198
+ scope,
16199
+ source: s.source,
16200
+ originTool: s.originTool,
16201
+ path: s.path
16202
+ });
16026
16203
  }
16027
16204
  this.entriesCache = entries;
16028
16205
  return entries;
@@ -16068,42 +16245,6 @@ ${compact}`;
16068
16245
  return result;
16069
16246
  }
16070
16247
  };
16071
- function parseFrontmatter(raw) {
16072
- if (!raw.startsWith("---")) return {};
16073
- const end = raw.indexOf("\n---", 4);
16074
- if (end === -1) return {};
16075
- const block = raw.slice(4, end);
16076
- const out = {};
16077
- let key = null;
16078
- let value = [];
16079
- const flush = () => {
16080
- if (key) {
16081
- out[key] = value.join("\n").trim();
16082
- }
16083
- key = null;
16084
- value = [];
16085
- };
16086
- for (const line of block.split("\n")) {
16087
- const m = /^([a-zA-Z_]+):\s*(\|?)\s*(.*)$/.exec(line);
16088
- if (m) {
16089
- flush();
16090
- key = m[1] ?? "";
16091
- const pipe = m[2];
16092
- const rest = m[3] ?? "";
16093
- if (pipe === "|") {
16094
- value = [];
16095
- } else if (rest) {
16096
- value = [rest];
16097
- } else {
16098
- value = [];
16099
- }
16100
- } else if (key) {
16101
- value.push(line.replace(/^\s+/, ""));
16102
- }
16103
- }
16104
- flush();
16105
- return out;
16106
- }
16107
16248
  function parseDescriptionFromText(desc) {
16108
16249
  const firstSentenceEnd = desc.indexOf(". ");
16109
16250
  const trigger = firstSentenceEnd !== -1 ? desc.slice(0, firstSentenceEnd + 1).trim() : desc.trim().split("\n")[0] ?? "";
@@ -16812,7 +16953,9 @@ ${errorDetails}`,
16812
16953
  toolUseId: use.id,
16813
16954
  toolName: tool.name,
16814
16955
  input: use.input,
16815
- suggestedPattern
16956
+ suggestedPattern,
16957
+ decisionSource: decision.source,
16958
+ riskTier: decision.riskTier ?? tool.riskTier
16816
16959
  };
16817
16960
  return { result: pending, tool, durationMs: Date.now() - start };
16818
16961
  }
@@ -18114,8 +18257,8 @@ async function loadProjectModes(modesDir) {
18114
18257
  for (const entry of entries) {
18115
18258
  if (!entry.endsWith(".md") && !entry.endsWith(".txt")) continue;
18116
18259
  const filePath = path4.join(modesDir, entry);
18117
- const stat10 = await fsp7.stat(filePath);
18118
- if (!stat10.isFile()) continue;
18260
+ const stat11 = await fsp7.stat(filePath);
18261
+ if (!stat11.isFile()) continue;
18119
18262
  const content = await fsp7.readFile(filePath, "utf8");
18120
18263
  const id = path4.basename(entry, path4.extname(entry));
18121
18264
  modes.push({
@@ -23101,7 +23244,7 @@ var SddParallelRun = class {
23101
23244
  disabledTools: ["delegate"],
23102
23245
  ...model ? { model } : {},
23103
23246
  ...provider ? { provider } : {},
23104
- ...fallbackModels && fallbackModels.length ? { fallbackModels } : {}
23247
+ ...fallbackModels?.length ? { fallbackModels } : {}
23105
23248
  });
23106
23249
  if (!spawnResult.subagentId) {
23107
23250
  throw new SddError({
@@ -25525,8 +25668,8 @@ function unwrapDataKey(buf, keyFile) {
25525
25668
  function checkKeyFilePermissions(keyFile) {
25526
25669
  if (process.platform === "win32") return;
25527
25670
  try {
25528
- const stat10 = fs12.statSync(keyFile);
25529
- const actualMode = stat10.mode & 511;
25671
+ const stat11 = fs12.statSync(keyFile);
25672
+ const actualMode = stat11.mode & 511;
25530
25673
  if (actualMode !== KEY_FILE_MODE) {
25531
25674
  console.warn(JSON.stringify({
25532
25675
  level: "warn",
@@ -26017,8 +26160,9 @@ function mergeAdjacentText(blocks) {
26017
26160
  }
26018
26161
  return out;
26019
26162
  }
26020
- init_atomic_write();
26021
- init_error();
26163
+
26164
+ // src/types/config.ts
26165
+ var DEFAULT_TUI_THINKING_WORD = "thinking";
26022
26166
 
26023
26167
  // src/types/context-window.ts
26024
26168
  var DEFAULT_CONTEXT_WINDOW_MODE_ID = "balanced";
@@ -26071,13 +26215,12 @@ function isContextWindowModeId(id) {
26071
26215
  return CONTEXT_WINDOW_MODES.some((m) => m.id === id);
26072
26216
  }
26073
26217
 
26074
- // src/types/config.ts
26075
- var DEFAULT_TUI_THINKING_WORD = "thinking";
26076
-
26077
26218
  // src/storage/config-loader.ts
26078
26219
  init_errors();
26079
- init_safe_json();
26220
+ init_atomic_write();
26080
26221
  init_deep_merge();
26222
+ init_error();
26223
+ init_safe_json();
26081
26224
  function storageErrorString(err) {
26082
26225
  if (err instanceof Error) {
26083
26226
  const code = err.code;
@@ -26119,10 +26262,16 @@ var BEHAVIOR_DEFAULTS = {
26119
26262
  tokenSavingMode: "off",
26120
26263
  allowOutsideProjectRoot: true
26121
26264
  },
26265
+ skills: { readClaudeSkills: true },
26122
26266
  mcpServers: {},
26123
26267
  fallbackAuto: true,
26124
26268
  maxConcurrent: 4,
26125
- yolo: false,
26269
+ // YOLO on by default: auto-approve normal project work without a per-call
26270
+ // prompt. Destructive operations still gate through a confirmation. Users
26271
+ // who want the per-call prompts set `yolo: false`. Existing installs whose
26272
+ // config lacks this key pick it up via fillMissingDefaults; an explicit
26273
+ // `false` is preserved by the deep-merge (opt-out respected).
26274
+ yolo: true,
26126
26275
  nextPrediction: false,
26127
26276
  hints: true,
26128
26277
  debugStream: false,
@@ -26135,12 +26284,19 @@ var BEHAVIOR_DEFAULTS = {
26135
26284
  },
26136
26285
  session: { ...DEFAULT_SESSION_LOGGING_CONFIG },
26137
26286
  autonomy: {
26138
- defaultMode: "off",
26287
+ // 'auto' by default: the agent self-drives (picks the top next-step after
26288
+ // each turn). This is a startup default, not a runtime flip — the
26289
+ // autoProceedMaxIterations cap + autoProceedDelayMs cooldown + destructive
26290
+ // gate + Ctrl+C / [GOAL_COMPLETE] stops remain in force. Explicit 'off'
26291
+ // in a config file is preserved (opt-out respected).
26292
+ defaultMode: "auto",
26139
26293
  autoProceedDelayMs: DEFAULT_AUTONOMY_CONFIG.autoProceedDelayMs,
26140
26294
  autoProceedMaxIterations: 50,
26141
26295
  autonomyNextPrompt: "auto {{suggestion}}",
26142
26296
  terminalTitleAnimation: true,
26143
- yolo: false,
26297
+ // Mirrored from the top-level yolo default so the autonomy subsystem
26298
+ // (which reads autonomy.yolo) stays consistent with config.yolo.
26299
+ yolo: true,
26144
26300
  streamFleet: true,
26145
26301
  chime: false,
26146
26302
  confirmExit: true,
@@ -26176,7 +26332,7 @@ function fillMissingDefaults(target, defaults) {
26176
26332
  function fillMissingDefaultsInPlace(target, defaults) {
26177
26333
  let changed = false;
26178
26334
  for (const [key, defaultValue] of Object.entries(defaults)) {
26179
- if (!Object.prototype.hasOwnProperty.call(target, key)) {
26335
+ if (!Object.hasOwn(target, key)) {
26180
26336
  target[key] = cloneJsonValue(defaultValue);
26181
26337
  changed = true;
26182
26338
  continue;
@@ -26246,6 +26402,7 @@ var IN_PROJECT_ALLOWED_KEYS = /* @__PURE__ */ new Set([
26246
26402
  "context",
26247
26403
  "tools",
26248
26404
  "features",
26405
+ "skills",
26249
26406
  "autonomy",
26250
26407
  "indexing",
26251
26408
  "session",
@@ -26256,6 +26413,7 @@ var IN_PROJECT_ALLOWED_KEYS = /* @__PURE__ */ new Set([
26256
26413
  "debugStream",
26257
26414
  "configScope",
26258
26415
  "maxConcurrent",
26416
+ "uiLocale",
26259
26417
  "fallbackModels",
26260
26418
  "fallbackProfiles",
26261
26419
  "favoriteModels",
@@ -26288,6 +26446,7 @@ var KNOWN_CONFIG_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set([
26288
26446
  "apiKey",
26289
26447
  "baseUrl",
26290
26448
  "maxConcurrent",
26449
+ "uiLocale",
26291
26450
  "providers",
26292
26451
  "models",
26293
26452
  "modelMatrix",
@@ -26303,6 +26462,7 @@ var KNOWN_CONFIG_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set([
26303
26462
  "plugins",
26304
26463
  "log",
26305
26464
  "features",
26465
+ "skills",
26306
26466
  "yolo",
26307
26467
  "nextPrediction",
26308
26468
  "cwd",
@@ -26328,8 +26488,12 @@ function assertInProjectAllowListComplete() {
26328
26488
  const denied = KNOWN_DENIED_IN_PROJECT.find((d) => d.key === key);
26329
26489
  if (!denied) missingFromBoth.push(key);
26330
26490
  }
26331
- const staleDenials = KNOWN_DENIED_IN_PROJECT.filter((d) => !KNOWN_CONFIG_TOP_LEVEL_KEYS.has(d.key)).map((d) => d.key);
26332
- const duplicate = KNOWN_DENIED_IN_PROJECT.filter((d) => IN_PROJECT_ALLOWED_KEYS.has(d.key)).map((d) => d.key);
26491
+ const staleDenials = KNOWN_DENIED_IN_PROJECT.filter(
26492
+ (d) => !KNOWN_CONFIG_TOP_LEVEL_KEYS.has(d.key)
26493
+ ).map((d) => d.key);
26494
+ const duplicate = KNOWN_DENIED_IN_PROJECT.filter((d) => IN_PROJECT_ALLOWED_KEYS.has(d.key)).map(
26495
+ (d) => d.key
26496
+ );
26333
26497
  const problems = [];
26334
26498
  if (missingFromBoth.length > 0) {
26335
26499
  problems.push(
@@ -26371,14 +26535,41 @@ function stripUnsafeInProjectFields(inProject, sourcePath, warn = (msg) => conso
26371
26535
  const outTools = out["tools"];
26372
26536
  if (outTools && typeof outTools === "object") {
26373
26537
  const execCfg = outTools["exec"];
26374
- if (execCfg && typeof execCfg === "object" && "allow" in execCfg) {
26375
- const clonedExec = { ...execCfg };
26376
- delete clonedExec["allow"];
26377
- out["tools"] = {
26378
- ...outTools,
26379
- exec: clonedExec
26380
- };
26381
- stripped.push("tools.exec.allow");
26538
+ if (execCfg && typeof execCfg === "object") {
26539
+ const hasAllow = "allow" in execCfg;
26540
+ const hasDanger = "danger" in execCfg;
26541
+ if (hasAllow || hasDanger) {
26542
+ const clonedExec = { ...execCfg };
26543
+ if (hasAllow) {
26544
+ delete clonedExec["allow"];
26545
+ stripped.push("tools.exec.allow");
26546
+ }
26547
+ if (hasDanger) {
26548
+ delete clonedExec["danger"];
26549
+ stripped.push("tools.exec.danger");
26550
+ }
26551
+ out["tools"] = {
26552
+ ...outTools,
26553
+ exec: clonedExec
26554
+ };
26555
+ }
26556
+ }
26557
+ }
26558
+ const outSkills = out["skills"];
26559
+ if (outSkills && typeof outSkills === "object") {
26560
+ const skillsRec = outSkills;
26561
+ const needsClone = "extraDirs" in skillsRec || "registryUrl" in skillsRec;
26562
+ if (needsClone) {
26563
+ const clonedSkills = { ...skillsRec };
26564
+ if ("extraDirs" in clonedSkills) {
26565
+ delete clonedSkills["extraDirs"];
26566
+ stripped.push("skills.extraDirs");
26567
+ }
26568
+ if ("registryUrl" in clonedSkills) {
26569
+ delete clonedSkills["registryUrl"];
26570
+ stripped.push("skills.registryUrl");
26571
+ }
26572
+ out["skills"] = clonedSkills;
26382
26573
  }
26383
26574
  }
26384
26575
  if (stripped.length > 0) {
@@ -26413,7 +26604,11 @@ function deepMerge2(base, patch) {
26413
26604
  );
26414
26605
  };
26415
26606
  }
26416
- return deepMerge(base, patch, opts);
26607
+ return deepMerge(
26608
+ base,
26609
+ patch,
26610
+ opts
26611
+ );
26417
26612
  }
26418
26613
  var DefaultConfigLoader = class {
26419
26614
  paths;
@@ -26459,13 +26654,15 @@ var DefaultConfigLoader = class {
26459
26654
  cfg = deepMerge2(cfg, patch);
26460
26655
  }
26461
26656
  } catch (err) {
26462
- console.warn(JSON.stringify({
26463
- level: "warn",
26464
- event: "config.source_load_failed",
26465
- source: src.name,
26466
- message: toErrorMessage(err),
26467
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
26468
- }));
26657
+ console.warn(
26658
+ JSON.stringify({
26659
+ level: "warn",
26660
+ event: "config.source_load_failed",
26661
+ source: src.name,
26662
+ message: toErrorMessage(err),
26663
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
26664
+ })
26665
+ );
26469
26666
  }
26470
26667
  }
26471
26668
  if (opts.cliFlags) {
@@ -26524,13 +26721,15 @@ var DefaultConfigLoader = class {
26524
26721
  durationMs: Date.now() - t0,
26525
26722
  ...this.traceId !== void 0 ? { traceId: this.traceId } : {}
26526
26723
  });
26527
- console.warn(JSON.stringify({
26528
- level: "warn",
26529
- event: "config.defaults_read_failed",
26530
- path: fp,
26531
- message: toErrorMessage(err),
26532
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
26533
- }));
26724
+ console.warn(
26725
+ JSON.stringify({
26726
+ level: "warn",
26727
+ event: "config.defaults_read_failed",
26728
+ path: fp,
26729
+ message: toErrorMessage(err),
26730
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
26731
+ })
26732
+ );
26534
26733
  return;
26535
26734
  }
26536
26735
  parsed = {};
@@ -26563,13 +26762,15 @@ var DefaultConfigLoader = class {
26563
26762
  durationMs: Date.now() - t0,
26564
26763
  ...this.traceId !== void 0 ? { traceId: this.traceId } : {}
26565
26764
  });
26566
- console.warn(JSON.stringify({
26567
- level: "warn",
26568
- event: "config.defaults_write_failed",
26569
- path: fp,
26570
- message: toErrorMessage(err),
26571
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
26572
- }));
26765
+ console.warn(
26766
+ JSON.stringify({
26767
+ level: "warn",
26768
+ event: "config.defaults_write_failed",
26769
+ path: fp,
26770
+ message: toErrorMessage(err),
26771
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
26772
+ })
26773
+ );
26573
26774
  }
26574
26775
  }
26575
26776
  /**
@@ -26671,12 +26872,14 @@ var DefaultConfigLoader = class {
26671
26872
  error: storageErrorString(err),
26672
26873
  ...this.traceId !== void 0 ? { traceId: this.traceId } : {}
26673
26874
  });
26674
- console.warn(JSON.stringify({
26675
- level: "warn",
26676
- event: "config.sync_load_failed",
26677
- message: toErrorMessage(err),
26678
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
26679
- }));
26875
+ console.warn(
26876
+ JSON.stringify({
26877
+ level: "warn",
26878
+ event: "config.sync_load_failed",
26879
+ message: toErrorMessage(err),
26880
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
26881
+ })
26882
+ );
26680
26883
  return null;
26681
26884
  }
26682
26885
  }
@@ -26684,8 +26887,8 @@ var DefaultConfigLoader = class {
26684
26887
  const t0 = Date.now();
26685
26888
  let mtimeMs = null;
26686
26889
  try {
26687
- const stat10 = await fsp7.stat(file);
26688
- mtimeMs = stat10.mtimeMs;
26890
+ const stat11 = await fsp7.stat(file);
26891
+ mtimeMs = stat11.mtimeMs;
26689
26892
  const cached = this.jsonCache.get(file);
26690
26893
  if (cached && cached.mtimeMs === mtimeMs) {
26691
26894
  return structuredClone(cached.value);
@@ -26705,13 +26908,15 @@ var DefaultConfigLoader = class {
26705
26908
  error: storageErrorString(err),
26706
26909
  ...this.traceId !== void 0 ? { traceId: this.traceId } : {}
26707
26910
  });
26708
- console.warn(JSON.stringify({
26709
- level: "warn",
26710
- event: "config.read_failed",
26711
- path: file,
26712
- message: toErrorMessage(err),
26713
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
26714
- }));
26911
+ console.warn(
26912
+ JSON.stringify({
26913
+ level: "warn",
26914
+ event: "config.read_failed",
26915
+ path: file,
26916
+ message: toErrorMessage(err),
26917
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
26918
+ })
26919
+ );
26715
26920
  return {};
26716
26921
  }
26717
26922
  let raw;
@@ -26729,13 +26934,15 @@ var DefaultConfigLoader = class {
26729
26934
  error: storageErrorString(err),
26730
26935
  ...this.traceId !== void 0 ? { traceId: this.traceId } : {}
26731
26936
  });
26732
- console.warn(JSON.stringify({
26733
- level: "warn",
26734
- event: "config.read_failed",
26735
- path: file,
26736
- message: toErrorMessage(err),
26737
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
26738
- }));
26937
+ console.warn(
26938
+ JSON.stringify({
26939
+ level: "warn",
26940
+ event: "config.read_failed",
26941
+ path: file,
26942
+ message: toErrorMessage(err),
26943
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
26944
+ })
26945
+ );
26739
26946
  }
26740
26947
  this.jsonCache.set(file, { mtimeMs: null, value: {} });
26741
26948
  return {};
@@ -26752,35 +26959,40 @@ var DefaultConfigLoader = class {
26752
26959
  error: "parse error or empty file",
26753
26960
  ...this.traceId !== void 0 ? { traceId: this.traceId } : {}
26754
26961
  });
26755
- console.warn(JSON.stringify({
26756
- level: "warn",
26757
- event: "config.parse_failed",
26758
- path: file,
26759
- message: "invalid JSON \u2014 falling back to defaults for this layer",
26760
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
26761
- }));
26962
+ console.warn(
26963
+ JSON.stringify({
26964
+ level: "warn",
26965
+ event: "config.parse_failed",
26966
+ path: file,
26967
+ message: "invalid JSON \u2014 falling back to defaults for this layer",
26968
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
26969
+ })
26970
+ );
26762
26971
  return {};
26763
26972
  }
26764
26973
  this.jsonCache.set(file, { mtimeMs, value: structuredClone(parsed.value) });
26765
26974
  return parsed.value;
26766
26975
  }
26767
26976
  validateBehavior(cfg) {
26768
- if (cfg.version === void 0) throw new ConfigError({
26769
- message: "Config: missing version field",
26770
- code: ERROR_CODES.CONFIG_INVALID,
26771
- context: { field: "version" }
26772
- });
26773
- if (cfg.version !== 1) throw new ConfigError({
26774
- message: `Config: unsupported version ${cfg.version}`,
26775
- code: ERROR_CODES.CONFIG_INVALID,
26776
- context: { field: "version", actual: cfg.version }
26777
- });
26977
+ if (cfg.version === void 0)
26978
+ throw new ConfigError({
26979
+ message: "Config: missing version field",
26980
+ code: ERROR_CODES.CONFIG_INVALID,
26981
+ context: { field: "version" }
26982
+ });
26983
+ if (cfg.version !== 1)
26984
+ throw new ConfigError({
26985
+ message: `Config: unsupported version ${cfg.version}`,
26986
+ code: ERROR_CODES.CONFIG_INVALID,
26987
+ context: { field: "version", actual: cfg.version }
26988
+ });
26778
26989
  const c = cfg.context;
26779
- if (!c) throw new ConfigError({
26780
- message: "Config: missing context section",
26781
- code: ERROR_CODES.CONFIG_INVALID,
26782
- context: { field: "context" }
26783
- });
26990
+ if (!c)
26991
+ throw new ConfigError({
26992
+ message: "Config: missing context section",
26993
+ code: ERROR_CODES.CONFIG_INVALID,
26994
+ context: { field: "context" }
26995
+ });
26784
26996
  const fields = ["warnThreshold", "softThreshold", "hardThreshold"];
26785
26997
  for (const f of fields) {
26786
26998
  const v = c[f];
@@ -27119,8 +27331,8 @@ var FileMemoryBackend = class {
27119
27331
  }
27120
27332
  async getMtime(file) {
27121
27333
  try {
27122
- const stat10 = await fsp7.stat(file);
27123
- return stat10.mtimeMs;
27334
+ const stat11 = await fsp7.stat(file);
27335
+ return stat11.mtimeMs;
27124
27336
  } catch {
27125
27337
  return 0;
27126
27338
  }
@@ -28608,7 +28820,9 @@ var STANDARD_AUDIT_EVENTS = /* @__PURE__ */ new Set([
28608
28820
  "error",
28609
28821
  "message_truncated",
28610
28822
  "provider_retry",
28611
- "provider_error"
28823
+ "provider_error",
28824
+ "skill_activated",
28825
+ "skill_deactivated"
28612
28826
  ]);
28613
28827
  var FULL_ONLY_EVENTS = /* @__PURE__ */ new Set([
28614
28828
  "tool_progress"
@@ -28720,8 +28934,8 @@ var DefaultSessionReader = class _DefaultSessionReader {
28720
28934
  const sessionPath = sessionScopedPath(rootDir, sessionId, ".jsonl");
28721
28935
  let mtimeMs = null;
28722
28936
  try {
28723
- const stat10 = await fsp7.stat(sessionPath);
28724
- mtimeMs = stat10.mtimeMs;
28937
+ const stat11 = await fsp7.stat(sessionPath);
28938
+ mtimeMs = stat11.mtimeMs;
28725
28939
  } catch {
28726
28940
  this.eventCache.delete(sessionId);
28727
28941
  this.eventCacheMtimes.delete(sessionId);