@fro.bot/systematic 2.33.2 → 3.0.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 (112) hide show
  1. package/ATTRIBUTIONS.md +1 -1
  2. package/agents/design/design-iterator.md +1 -0
  3. package/agents/research/best-practices-researcher.md +6 -8
  4. package/agents/review/pattern-recognition-specialist.md +1 -1
  5. package/agents/workflow/systematic-implementer.md +1 -0
  6. package/dist/cli.js +348 -53
  7. package/dist/{index-vyzhzvap.js → index-yskzf7vh.js} +587 -386
  8. package/dist/index.js +100 -155
  9. package/dist/lib/agent-overlays.d.ts +0 -1
  10. package/dist/lib/agent-resolver.d.ts +28 -0
  11. package/dist/lib/bootstrap.d.ts +8 -1
  12. package/dist/lib/bundled-names.d.ts +3 -3
  13. package/dist/lib/pi-delegate-session.d.ts +31 -0
  14. package/dist/lib/pi-delegate-tool.d.ts +42 -0
  15. package/dist/lib/removed-names.d.ts +3 -3
  16. package/dist/lib/setup.d.ts +36 -0
  17. package/dist/lib/skill-loader.d.ts +1 -2
  18. package/dist/lib/skill-resolver.d.ts +39 -0
  19. package/dist/lib/skill-tool.d.ts +2 -11
  20. package/dist/lib/skills.d.ts +1 -9
  21. package/dist/lib/source-model-defaults.d.ts +1 -1
  22. package/dist/pi.d.ts +7 -0
  23. package/dist/pi.js +3641 -0
  24. package/dist/schemas/systematic-config.schema.json +47 -242
  25. package/package.json +31 -8
  26. package/skills/ce-brainstorm/references/handoff.md +5 -26
  27. package/skills/ce-brainstorm/references/universal-brainstorming.md +0 -1
  28. package/skills/ce-compound/SKILL.md +8 -12
  29. package/skills/ce-ideate/references/post-ideation-workflow.md +21 -85
  30. package/skills/ce-plan/SKILL.md +6 -6
  31. package/skills/ce-plan/references/deepening-workflow.md +6 -7
  32. package/skills/ce-plan/references/plan-handoff.md +1 -17
  33. package/skills/ce-plan/references/universal-planning.md +0 -4
  34. package/skills/ce-review/SKILL.md +10 -19
  35. package/skills/ce-review/references/persona-catalog.md +2 -7
  36. package/skills/ce-review/references/review-output-template.md +0 -1
  37. package/skills/ce-work/SKILL.md +1 -1
  38. package/skills/deepen-plan/SKILL.md +6 -7
  39. package/skills/document-review/SKILL.md +2 -2
  40. package/skills/git-commit-push-pr/SKILL.md +1 -2
  41. package/skills/lfg/SKILL.md +1 -1
  42. package/skills/onboarding/SKILL.md +1 -12
  43. package/skills/orchestrating-subagents/SKILL.md +2 -2
  44. package/skills/slfg/SKILL.md +2 -3
  45. package/skills/test-browser/SKILL.md +2 -2
  46. package/skills/todos/SKILL.md +239 -0
  47. package/skills/writing-skills/SKILL.md +102 -1
  48. package/skills/{writing-systematic-skills → writing-skills}/references/foundation-conventions.md +5 -5
  49. package/agents/design/design-implementation-reviewer.md +0 -95
  50. package/agents/design/figma-design-sync.md +0 -173
  51. package/agents/docs/ankane-readme-writer.md +0 -51
  52. package/agents/review/cli-agent-readiness-reviewer.md +0 -418
  53. package/agents/review/data-integrity-guardian.md +0 -72
  54. package/agents/review/data-migration-expert.md +0 -99
  55. package/agents/review/dhh-rails-reviewer.md +0 -46
  56. package/agents/review/julik-frontend-races-reviewer.md +0 -49
  57. package/agents/review/kieran-python-reviewer.md +0 -47
  58. package/agents/review/kieran-rails-reviewer.md +0 -47
  59. package/agents/review/performance-oracle.md +0 -112
  60. package/agents/review/schema-drift-detector.md +0 -143
  61. package/agents/review/security-sentinel.md +0 -95
  62. package/agents/workflow/lint.md +0 -17
  63. package/dist/lib/converter.d.ts +0 -14
  64. package/skills/andrew-kane-gem-writer/SKILL.md +0 -184
  65. package/skills/andrew-kane-gem-writer/references/database-adapters.md +0 -231
  66. package/skills/andrew-kane-gem-writer/references/module-organization.md +0 -121
  67. package/skills/andrew-kane-gem-writer/references/rails-integration.md +0 -183
  68. package/skills/andrew-kane-gem-writer/references/resources.md +0 -119
  69. package/skills/andrew-kane-gem-writer/references/testing-patterns.md +0 -261
  70. package/skills/changelog/SKILL.md +0 -139
  71. package/skills/claude-permissions-optimizer/SKILL.md +0 -166
  72. package/skills/claude-permissions-optimizer/scripts/extract-commands.mjs +0 -655
  73. package/skills/claude-permissions-optimizer/scripts/normalize.mjs +0 -151
  74. package/skills/dhh-rails-style/SKILL.md +0 -186
  75. package/skills/dhh-rails-style/references/architecture.md +0 -653
  76. package/skills/dhh-rails-style/references/controllers.md +0 -303
  77. package/skills/dhh-rails-style/references/frontend.md +0 -510
  78. package/skills/dhh-rails-style/references/gems.md +0 -266
  79. package/skills/dhh-rails-style/references/models.md +0 -359
  80. package/skills/dhh-rails-style/references/testing.md +0 -338
  81. package/skills/dspy-ruby/SKILL.md +0 -737
  82. package/skills/dspy-ruby/assets/config-template.rb +0 -187
  83. package/skills/dspy-ruby/assets/module-template.rb +0 -300
  84. package/skills/dspy-ruby/assets/signature-template.rb +0 -221
  85. package/skills/dspy-ruby/references/core-concepts.md +0 -674
  86. package/skills/dspy-ruby/references/observability.md +0 -366
  87. package/skills/dspy-ruby/references/optimization.md +0 -603
  88. package/skills/dspy-ruby/references/providers.md +0 -418
  89. package/skills/dspy-ruby/references/toolsets.md +0 -502
  90. package/skills/every-style-editor/SKILL.md +0 -135
  91. package/skills/every-style-editor/references/EVERY_WRITE_STYLE.md +0 -529
  92. package/skills/feature-video/SKILL.md +0 -383
  93. package/skills/gemini-imagegen/SKILL.md +0 -237
  94. package/skills/gemini-imagegen/requirements.txt +0 -2
  95. package/skills/gemini-imagegen/scripts/compose_images.py +0 -157
  96. package/skills/gemini-imagegen/scripts/edit_image.py +0 -144
  97. package/skills/gemini-imagegen/scripts/gemini_images.py +0 -263
  98. package/skills/gemini-imagegen/scripts/generate_image.py +0 -133
  99. package/skills/gemini-imagegen/scripts/multi_turn_chat.py +0 -216
  100. package/skills/generate_command/SKILL.md +0 -164
  101. package/skills/orchestrating-swarms/SKILL.md +0 -1723
  102. package/skills/proof/SKILL.md +0 -291
  103. package/skills/proof/references/hitl-review.md +0 -368
  104. package/skills/rclone/SKILL.md +0 -150
  105. package/skills/rclone/scripts/check_setup.sh +0 -60
  106. package/skills/setup/SKILL.md +0 -22
  107. package/skills/test-xcode/SKILL.md +0 -214
  108. package/skills/todo-create/SKILL.md +0 -109
  109. package/skills/todo-resolve/SKILL.md +0 -68
  110. package/skills/todo-triage/SKILL.md +0 -70
  111. package/skills/writing-systematic-skills/SKILL.md +0 -119
  112. /package/skills/{todo-create → todos}/assets/todo-template.md +0 -0
@@ -14,8 +14,9 @@ var __export = (target, all) => {
14
14
  });
15
15
  };
16
16
 
17
- // src/lib/converter.ts
18
- import fs from "fs";
17
+ // src/lib/skills.ts
18
+ import fs2 from "fs";
19
+ import path2 from "path";
19
20
 
20
21
  // src/lib/frontmatter.ts
21
22
  import yaml from "js-yaml";
@@ -40,19 +41,6 @@ function parseFrontmatter(content) {
40
41
  return { data: {}, body, hadFrontmatter: true, parseError: true };
41
42
  }
42
43
  }
43
- function formatFrontmatter(data) {
44
- if (Object.keys(data).length === 0) {
45
- return ["---", "---"].join(`
46
- `);
47
- }
48
- const yamlContent = yaml.dump(data, {
49
- schema: yaml.JSON_SCHEMA,
50
- lineWidth: -1,
51
- noRefs: true
52
- }).trimEnd();
53
- return ["---", yamlContent, "---"].join(`
54
- `);
55
- }
56
44
 
57
45
  // src/lib/validation.ts
58
46
  function isRecord(value) {
@@ -162,307 +150,18 @@ function extractBoolean(data, key) {
162
150
  return;
163
151
  }
164
152
 
165
- // src/lib/converter.ts
166
- var CONVERTER_VERSION = 2;
167
- var cache = new Map;
168
- var TOOL_MAPPINGS = [
169
- [/\bTask\s+tool\b/gi, "task tool"],
170
- [/\bTask\s+([\w-]+)\s*:/g, "task $1:"],
171
- [/\bTask\s+([\w-]+)\s*\(/g, "task $1("],
172
- [/\bTask\s*\(/g, "task("],
173
- [/\bTask\b(?=\s+to\s+\w)/g, "task"],
174
- [/\bTodoWrite\b/g, "todowrite"],
175
- [/\bAskUserQuestion\b/g, "question"],
176
- [/\bWebSearch\b/g, "google_search"],
177
- [/\bRead\b(?=\s+tool|\s+to\s+|\()/g, "read"],
178
- [/\bWrite\b(?=\s+tool|\s+to\s+|\()/g, "write"],
179
- [/\bEdit\b(?=\s+tool|\s+to\s+|\()/g, "edit"],
180
- [/\bBash\b(?=\s+tool|\s+to\s+|\()/g, "bash"],
181
- [/\bGrep\b(?=\s+tool|\s+to\s+|\()/g, "grep"],
182
- [/\bGlob\b(?=\s+tool|\s+to\s+|\()/g, "glob"],
183
- [/\bWebFetch\b/g, "webfetch"],
184
- [/\bSkill\b(?=\s+tool|\s*\()/g, "skill"]
185
- ];
186
- var PATH_REPLACEMENTS = [
187
- [/\.claude\/skills\//g, ".opencode/skills/"],
188
- [/\.claude\/commands\//g, ".opencode/commands/"],
189
- [/\.claude\/agents\//g, ".opencode/agents/"],
190
- [/~\/\.claude\//g, "~/.config/opencode/"],
191
- [/CLAUDE\.md/g, "AGENTS.md"],
192
- [/\/compound-engineering:/g, "/systematic:"],
193
- [/compound-engineering:/g, "systematic:"]
194
- ];
195
- var TOOL_NAME_MAP = {
196
- task: "task",
197
- todowrite: "todowrite",
198
- askuserquestion: "question",
199
- websearch: "google_search",
200
- webfetch: "webfetch",
201
- skill: "skill",
202
- read: "read",
203
- write: "write",
204
- edit: "edit",
205
- bash: "bash",
206
- grep: "grep",
207
- glob: "glob"
208
- };
209
- var PERMISSION_MODE_MAP = {
210
- full: {
211
- edit: "allow",
212
- bash: "allow",
213
- webfetch: "allow"
214
- },
215
- default: {
216
- edit: "ask",
217
- bash: "ask",
218
- webfetch: "ask"
219
- },
220
- plan: {
221
- edit: "deny",
222
- bash: "deny",
223
- webfetch: "ask"
224
- },
225
- bypassPermissions: {
226
- edit: "allow",
227
- bash: "allow",
228
- webfetch: "allow"
229
- }
230
- };
231
- function inferTemperature(name, description) {
232
- const sample = `${name} ${description ?? ""}`.toLowerCase();
233
- if (/(review|audit|security|sentinel|oracle|lint|verification|guardian)/.test(sample)) {
234
- return 0.1;
235
- }
236
- if (/(plan|planning|architecture|strategist|analysis|research)/.test(sample)) {
237
- return 0.2;
238
- }
239
- if (/(doc|readme|changelog|editor|writer)/.test(sample)) {
240
- return 0.3;
241
- }
242
- if (/(brainstorm|creative|ideate|design|concept)/.test(sample)) {
243
- return 0.6;
244
- }
245
- return 0.3;
246
- }
247
- var CODE_BLOCK_PATTERN = /```[\s\S]*?```|`[^`\n]+`/g;
248
- function transformBody(body) {
249
- const codeBlocks = [];
250
- let placeholderIndex = 0;
251
- const withPlaceholders = body.replace(CODE_BLOCK_PATTERN, (match) => {
252
- codeBlocks.push(match);
253
- return `__CODE_BLOCK_${placeholderIndex++}__`;
254
- });
255
- let result = withPlaceholders;
256
- for (const [pattern, replacement] of TOOL_MAPPINGS) {
257
- result = result.replace(pattern, replacement);
258
- }
259
- for (const [pattern, replacement] of PATH_REPLACEMENTS) {
260
- result = result.replace(pattern, replacement);
261
- }
262
- for (let i = 0;i < codeBlocks.length; i++) {
263
- result = result.replace(`__CODE_BLOCK_${i}__`, codeBlocks[i]);
264
- }
265
- return result;
266
- }
267
- function normalizeModel(model) {
268
- if (model.includes("/"))
269
- return model;
270
- if (model === "inherit")
271
- return model;
272
- if (/^claude-/.test(model))
273
- return `anthropic/${model}`;
274
- if (/^(gpt-|o1-|o3-)/.test(model))
275
- return `openai/${model}`;
276
- if (/^gemini-/.test(model))
277
- return `google/${model}`;
278
- return `anthropic/${model}`;
279
- }
280
- function canonicalizeToolName(name) {
281
- const lower = name.trim().toLowerCase();
282
- return TOOL_NAME_MAP[lower] ?? lower;
283
- }
284
- function isValidSteps(value) {
285
- return typeof value === "number" && Number.isFinite(value) && Number.isInteger(value) && value > 0;
286
- }
287
- function mapStepsField(data) {
288
- if (data.steps !== undefined) {
289
- if (isValidSteps(data.steps)) {
290
- delete data.maxTurns;
291
- delete data.maxSteps;
292
- }
293
- return;
294
- }
295
- const candidates = [];
296
- if (isValidSteps(data.maxTurns))
297
- candidates.push(data.maxTurns);
298
- if (isValidSteps(data.maxSteps))
299
- candidates.push(data.maxSteps);
300
- if (candidates.length > 0) {
301
- data.steps = Math.min(...candidates);
302
- delete data.maxTurns;
303
- delete data.maxSteps;
304
- }
305
- }
306
- function mapToolsField(data) {
307
- if (data.tools !== undefined && !Array.isArray(data.tools)) {
308
- if (isToolsMap(data.tools)) {
309
- mergeDisallowedTools(data);
310
- }
311
- return;
312
- }
313
- if (Array.isArray(data.tools)) {
314
- const toolsMap = {};
315
- for (const tool of data.tools) {
316
- if (typeof tool === "string") {
317
- toolsMap[canonicalizeToolName(tool)] = true;
318
- }
319
- }
320
- if (Object.keys(toolsMap).length > 0) {
321
- data.tools = toolsMap;
322
- } else {
323
- delete data.tools;
324
- }
325
- }
326
- mergeDisallowedTools(data);
327
- }
328
- function mergeDisallowedTools(data) {
329
- if (!Array.isArray(data.disallowedTools))
330
- return;
331
- const existing = isToolsMap(data.tools) ? data.tools : {};
332
- for (const tool of data.disallowedTools) {
333
- if (typeof tool === "string") {
334
- existing[canonicalizeToolName(tool)] = false;
335
- }
336
- }
337
- if (Object.keys(existing).length > 0) {
338
- data.tools = existing;
339
- }
340
- delete data.disallowedTools;
341
- }
342
- function mapPermissionMode(data) {
343
- if (data.permission !== undefined) {
344
- const normalized = normalizePermission(data.permission);
345
- if (normalized) {
346
- data.permission = normalized;
347
- delete data.permissionMode;
348
- return;
349
- }
350
- }
351
- if (typeof data.permissionMode !== "string")
352
- return;
353
- const mapped = PERMISSION_MODE_MAP[data.permissionMode];
354
- data.permission = mapped ?? { edit: "ask", bash: "ask", webfetch: "ask" };
355
- delete data.permissionMode;
356
- }
357
- function mapHiddenField(data) {
358
- if (data["disable-model-invocation"] === true || data.disableModelInvocation === true) {
359
- data.hidden = true;
360
- delete data["disable-model-invocation"];
361
- delete data.disableModelInvocation;
362
- }
363
- }
364
- function normalizeModelField(data) {
365
- if (typeof data.model === "string" && data.model !== "inherit") {
366
- data.model = normalizeModel(data.model);
367
- } else if (data.model === "inherit") {
368
- delete data.model;
369
- }
370
- }
371
- function transformAgentFrontmatter(data, agentMode) {
372
- const result = { ...data };
373
- result.mode = isAgentMode(data.mode) ? data.mode : agentMode;
374
- const name = typeof data.name === "string" ? data.name : "";
375
- const description = typeof data.description === "string" ? data.description : "";
376
- if (description) {
377
- result.description = description;
378
- } else if (name) {
379
- result.description = `${name} agent`;
380
- }
381
- normalizeModelField(result);
382
- result.temperature = typeof data.temperature === "number" ? data.temperature : inferTemperature(name, description);
383
- mapStepsField(result);
384
- mapToolsField(result);
385
- mapPermissionMode(result);
386
- mapHiddenField(result);
387
- return result;
388
- }
389
- function transformSkillFrontmatter(data) {
390
- const result = { ...data };
391
- normalizeModelField(result);
392
- if (result.context === "fork") {
393
- result.subtask = true;
394
- }
395
- return result;
396
- }
397
- function transformCommandFrontmatter(data) {
398
- const result = { ...data };
399
- normalizeModelField(result);
400
- return result;
401
- }
402
- function convertContent(content, type, options = {}) {
403
- if (content === "")
404
- return "";
405
- const { data, body, hadFrontmatter, parseError } = parseFrontmatter(content);
406
- if (!hadFrontmatter) {
407
- return options.skipBodyTransform ? content : transformBody(content);
408
- }
409
- if (parseError) {
410
- return options.skipBodyTransform ? content : transformBody(content);
411
- }
412
- const shouldTransformBody = !options.skipBodyTransform;
413
- const transformedBody = shouldTransformBody ? transformBody(body) : body;
414
- if (type === "agent") {
415
- const agentMode = options.agentMode ?? "subagent";
416
- const transformedData = transformAgentFrontmatter(data, agentMode);
417
- return `${formatFrontmatter(transformedData)}
418
- ${transformedBody}`;
419
- }
420
- if (type === "skill") {
421
- const transformedData = transformSkillFrontmatter(data);
422
- return `${formatFrontmatter(transformedData)}
423
- ${transformedBody}`;
424
- }
425
- if (type === "command") {
426
- const transformedData = transformCommandFrontmatter(data);
427
- return `${formatFrontmatter(transformedData)}
428
- ${transformedBody}`;
429
- }
430
- return content;
431
- }
432
- function convertFileWithCache(filePath, type, options = {}) {
433
- const fd = fs.openSync(filePath, "r");
434
- try {
435
- const stats = fs.fstatSync(fd);
436
- const cacheKey = `${CONVERTER_VERSION}:${filePath}:${type}:${options.source ?? "bundled"}:${options.agentMode ?? "subagent"}:${options.skipBodyTransform ?? false}`;
437
- const cached = cache.get(cacheKey);
438
- if (cached != null && cached.mtimeMs === stats.mtimeMs) {
439
- return cached.converted;
440
- }
441
- const content = fs.readFileSync(fd, "utf8");
442
- const converted = convertContent(content, type, options);
443
- cache.set(cacheKey, { mtimeMs: stats.mtimeMs, converted });
444
- return converted;
445
- } finally {
446
- fs.closeSync(fd);
447
- }
448
- }
449
-
450
- // src/lib/skills.ts
451
- import fs3 from "fs";
452
- import path2 from "path";
453
-
454
153
  // src/lib/walk-dir.ts
455
- import fs2 from "fs";
154
+ import fs from "fs";
456
155
  import path from "path";
457
156
  function walkDir(rootDir, options = {}) {
458
157
  const { maxDepth = 3, filter } = options;
459
158
  const results = [];
460
- if (!fs2.existsSync(rootDir))
159
+ if (!fs.existsSync(rootDir))
461
160
  return results;
462
161
  function recurse(currentDir, depth, category) {
463
162
  if (depth > maxDepth)
464
163
  return;
465
- const entries = fs2.readdirSync(currentDir, { withFileTypes: true });
164
+ const entries = fs.readdirSync(currentDir, { withFileTypes: true });
466
165
  for (const entry of entries) {
467
166
  const fullPath = path.join(currentDir, entry.name);
468
167
  const walkEntry = {
@@ -496,32 +195,12 @@ function parseMetadata(data) {
496
195
  }
497
196
  return Object.fromEntries(entries);
498
197
  }
499
- function parseDeprecated(data) {
500
- const deprecatedRaw = data.deprecated;
501
- if (!isRecord(deprecatedRaw)) {
502
- return;
503
- }
504
- const since = typeof deprecatedRaw.since === "string" && deprecatedRaw.since !== "" ? deprecatedRaw.since : undefined;
505
- const removal = typeof deprecatedRaw.removal === "string" && deprecatedRaw.removal !== "" ? deprecatedRaw.removal : undefined;
506
- if (since === undefined || removal === undefined) {
507
- return;
508
- }
509
- const deprecated = { since, removal };
510
- if (typeof deprecatedRaw.replacement === "string") {
511
- deprecated.replacement = deprecatedRaw.replacement;
512
- }
513
- if (typeof deprecatedRaw.reason === "string") {
514
- deprecated.reason = deprecatedRaw.reason;
515
- }
516
- return deprecated;
517
- }
518
198
  function extractFrontmatterFromContent(content) {
519
199
  const { data, parseError } = parseFrontmatter(content);
520
200
  if (parseError) {
521
201
  return { name: "", description: "" };
522
202
  }
523
203
  const metadata = parseMetadata(data);
524
- const deprecated = parseDeprecated(data);
525
204
  const argumentHintRaw = extractNonEmptyString(data, "argument-hint");
526
205
  const argumentHint = argumentHintRaw?.replace(/^["']|["']$/g, "") || undefined;
527
206
  return {
@@ -530,7 +209,6 @@ function extractFrontmatterFromContent(content) {
530
209
  license: extractNonEmptyString(data, "license"),
531
210
  compatibility: extractNonEmptyString(data, "compatibility"),
532
211
  metadata,
533
- deprecated,
534
212
  disableModelInvocation: extractBoolean(data, "disable-model-invocation"),
535
213
  userInvocable: extractBoolean(data, "user-invocable"),
536
214
  subtask: data.context === "fork" ? true : extractBoolean(data, "subtask") ?? undefined,
@@ -542,7 +220,7 @@ function extractFrontmatterFromContent(content) {
542
220
  }
543
221
  function extractFrontmatter(filePath) {
544
222
  try {
545
- const content = fs3.readFileSync(filePath, "utf8");
223
+ const content = fs2.readFileSync(filePath, "utf8");
546
224
  return extractFrontmatterFromContent(content);
547
225
  } catch {
548
226
  return { name: "", description: "" };
@@ -556,7 +234,7 @@ function findSkillsInDir(dir, maxDepth = 3) {
556
234
  });
557
235
  for (const entry of entries) {
558
236
  const skillFile = path2.join(entry.path, "SKILL.md");
559
- if (fs3.existsSync(skillFile)) {
237
+ if (fs2.existsSync(skillFile)) {
560
238
  const frontmatter = extractFrontmatter(skillFile);
561
239
  skills.push({
562
240
  path: entry.path,
@@ -566,7 +244,6 @@ function findSkillsInDir(dir, maxDepth = 3) {
566
244
  license: frontmatter.license,
567
245
  compatibility: frontmatter.compatibility,
568
246
  metadata: frontmatter.metadata,
569
- deprecated: frontmatter.deprecated,
570
247
  disableModelInvocation: frontmatter.disableModelInvocation,
571
248
  userInvocable: frontmatter.userInvocable,
572
249
  subtask: frontmatter.subtask,
@@ -581,7 +258,7 @@ function findSkillsInDir(dir, maxDepth = 3) {
581
258
  }
582
259
 
583
260
  // src/lib/config.ts
584
- import fs4 from "fs";
261
+ import fs3 from "fs";
585
262
  import os from "os";
586
263
  import path3 from "path";
587
264
 
@@ -1033,6 +710,249 @@ var cachedBreakLinesWithSpaces = {
1033
710
  })
1034
711
  }
1035
712
  };
713
+ var supportedEols = [`
714
+ `, "\r", `\r
715
+ `];
716
+
717
+ // node_modules/.bun/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/impl/format.js
718
+ function format(documentText, range, options) {
719
+ let initialIndentLevel;
720
+ let formatText;
721
+ let formatTextStart;
722
+ let rangeStart;
723
+ let rangeEnd;
724
+ if (range) {
725
+ rangeStart = range.offset;
726
+ rangeEnd = rangeStart + range.length;
727
+ formatTextStart = rangeStart;
728
+ while (formatTextStart > 0 && !isEOL(documentText, formatTextStart - 1)) {
729
+ formatTextStart--;
730
+ }
731
+ let endOffset = rangeEnd;
732
+ while (endOffset < documentText.length && !isEOL(documentText, endOffset)) {
733
+ endOffset++;
734
+ }
735
+ formatText = documentText.substring(formatTextStart, endOffset);
736
+ initialIndentLevel = computeIndentLevel(formatText, options);
737
+ } else {
738
+ formatText = documentText;
739
+ initialIndentLevel = 0;
740
+ formatTextStart = 0;
741
+ rangeStart = 0;
742
+ rangeEnd = documentText.length;
743
+ }
744
+ const eol = getEOL(options, documentText);
745
+ const eolFastPathSupported = supportedEols.includes(eol);
746
+ let numberLineBreaks = 0;
747
+ let indentLevel = 0;
748
+ let indentValue;
749
+ if (options.insertSpaces) {
750
+ indentValue = cachedSpaces[options.tabSize || 4] ?? repeat(cachedSpaces[1], options.tabSize || 4);
751
+ } else {
752
+ indentValue = "\t";
753
+ }
754
+ const indentType = indentValue === "\t" ? "\t" : " ";
755
+ let scanner = createScanner(formatText, false);
756
+ let hasError = false;
757
+ function newLinesAndIndent() {
758
+ if (numberLineBreaks > 1) {
759
+ return repeat(eol, numberLineBreaks) + repeat(indentValue, initialIndentLevel + indentLevel);
760
+ }
761
+ const amountOfSpaces = indentValue.length * (initialIndentLevel + indentLevel);
762
+ if (!eolFastPathSupported || amountOfSpaces > cachedBreakLinesWithSpaces[indentType][eol].length) {
763
+ return eol + repeat(indentValue, initialIndentLevel + indentLevel);
764
+ }
765
+ if (amountOfSpaces <= 0) {
766
+ return eol;
767
+ }
768
+ return cachedBreakLinesWithSpaces[indentType][eol][amountOfSpaces];
769
+ }
770
+ function scanNext() {
771
+ let token = scanner.scan();
772
+ numberLineBreaks = 0;
773
+ while (token === 15 || token === 14) {
774
+ if (token === 14 && options.keepLines) {
775
+ numberLineBreaks += 1;
776
+ } else if (token === 14) {
777
+ numberLineBreaks = 1;
778
+ }
779
+ token = scanner.scan();
780
+ }
781
+ hasError = token === 16 || scanner.getTokenError() !== 0;
782
+ return token;
783
+ }
784
+ const editOperations = [];
785
+ function addEdit(text, startOffset, endOffset) {
786
+ if (!hasError && (!range || startOffset < rangeEnd && endOffset > rangeStart) && documentText.substring(startOffset, endOffset) !== text) {
787
+ editOperations.push({ offset: startOffset, length: endOffset - startOffset, content: text });
788
+ }
789
+ }
790
+ let firstToken = scanNext();
791
+ if (options.keepLines && numberLineBreaks > 0) {
792
+ addEdit(repeat(eol, numberLineBreaks), 0, 0);
793
+ }
794
+ if (firstToken !== 17) {
795
+ let firstTokenStart = scanner.getTokenOffset() + formatTextStart;
796
+ let initialIndent = indentValue.length * initialIndentLevel < 20 && options.insertSpaces ? cachedSpaces[indentValue.length * initialIndentLevel] : repeat(indentValue, initialIndentLevel);
797
+ addEdit(initialIndent, formatTextStart, firstTokenStart);
798
+ }
799
+ while (firstToken !== 17) {
800
+ let firstTokenEnd = scanner.getTokenOffset() + scanner.getTokenLength() + formatTextStart;
801
+ let secondToken = scanNext();
802
+ let replaceContent = "";
803
+ let needsLineBreak = false;
804
+ while (numberLineBreaks === 0 && (secondToken === 12 || secondToken === 13)) {
805
+ let commentTokenStart = scanner.getTokenOffset() + formatTextStart;
806
+ addEdit(cachedSpaces[1], firstTokenEnd, commentTokenStart);
807
+ firstTokenEnd = scanner.getTokenOffset() + scanner.getTokenLength() + formatTextStart;
808
+ needsLineBreak = secondToken === 12;
809
+ replaceContent = needsLineBreak ? newLinesAndIndent() : "";
810
+ secondToken = scanNext();
811
+ }
812
+ if (secondToken === 2) {
813
+ if (firstToken !== 1) {
814
+ indentLevel--;
815
+ }
816
+ if (options.keepLines && numberLineBreaks > 0 || !options.keepLines && firstToken !== 1) {
817
+ replaceContent = newLinesAndIndent();
818
+ } else if (options.keepLines) {
819
+ replaceContent = cachedSpaces[1];
820
+ }
821
+ } else if (secondToken === 4) {
822
+ if (firstToken !== 3) {
823
+ indentLevel--;
824
+ }
825
+ if (options.keepLines && numberLineBreaks > 0 || !options.keepLines && firstToken !== 3) {
826
+ replaceContent = newLinesAndIndent();
827
+ } else if (options.keepLines) {
828
+ replaceContent = cachedSpaces[1];
829
+ }
830
+ } else {
831
+ switch (firstToken) {
832
+ case 3:
833
+ case 1:
834
+ indentLevel++;
835
+ if (options.keepLines && numberLineBreaks > 0 || !options.keepLines) {
836
+ replaceContent = newLinesAndIndent();
837
+ } else {
838
+ replaceContent = cachedSpaces[1];
839
+ }
840
+ break;
841
+ case 5:
842
+ if (options.keepLines && numberLineBreaks > 0 || !options.keepLines) {
843
+ replaceContent = newLinesAndIndent();
844
+ } else {
845
+ replaceContent = cachedSpaces[1];
846
+ }
847
+ break;
848
+ case 12:
849
+ replaceContent = newLinesAndIndent();
850
+ break;
851
+ case 13:
852
+ if (numberLineBreaks > 0) {
853
+ replaceContent = newLinesAndIndent();
854
+ } else if (!needsLineBreak) {
855
+ replaceContent = cachedSpaces[1];
856
+ }
857
+ break;
858
+ case 6:
859
+ if (options.keepLines && numberLineBreaks > 0) {
860
+ replaceContent = newLinesAndIndent();
861
+ } else if (!needsLineBreak) {
862
+ replaceContent = cachedSpaces[1];
863
+ }
864
+ break;
865
+ case 10:
866
+ if (options.keepLines && numberLineBreaks > 0) {
867
+ replaceContent = newLinesAndIndent();
868
+ } else if (secondToken === 6 && !needsLineBreak) {
869
+ replaceContent = "";
870
+ }
871
+ break;
872
+ case 7:
873
+ case 8:
874
+ case 9:
875
+ case 11:
876
+ case 2:
877
+ case 4:
878
+ if (options.keepLines && numberLineBreaks > 0) {
879
+ replaceContent = newLinesAndIndent();
880
+ } else {
881
+ if ((secondToken === 12 || secondToken === 13) && !needsLineBreak) {
882
+ replaceContent = cachedSpaces[1];
883
+ } else if (secondToken !== 5 && secondToken !== 17) {
884
+ hasError = true;
885
+ }
886
+ }
887
+ break;
888
+ case 16:
889
+ hasError = true;
890
+ break;
891
+ }
892
+ if (numberLineBreaks > 0 && (secondToken === 12 || secondToken === 13)) {
893
+ replaceContent = newLinesAndIndent();
894
+ }
895
+ }
896
+ if (secondToken === 17) {
897
+ if (options.keepLines && numberLineBreaks > 0) {
898
+ replaceContent = newLinesAndIndent();
899
+ } else {
900
+ replaceContent = options.insertFinalNewline ? eol : "";
901
+ }
902
+ }
903
+ const secondTokenStart = scanner.getTokenOffset() + formatTextStart;
904
+ addEdit(replaceContent, firstTokenEnd, secondTokenStart);
905
+ firstToken = secondToken;
906
+ }
907
+ return editOperations;
908
+ }
909
+ function repeat(s, count) {
910
+ let result = "";
911
+ for (let i = 0;i < count; i++) {
912
+ result += s;
913
+ }
914
+ return result;
915
+ }
916
+ function computeIndentLevel(content, options) {
917
+ let i = 0;
918
+ let nChars = 0;
919
+ const tabSize = options.tabSize || 4;
920
+ while (i < content.length) {
921
+ let ch = content.charAt(i);
922
+ if (ch === cachedSpaces[1]) {
923
+ nChars++;
924
+ } else if (ch === "\t") {
925
+ nChars += tabSize;
926
+ } else {
927
+ break;
928
+ }
929
+ i++;
930
+ }
931
+ return Math.floor(nChars / tabSize);
932
+ }
933
+ function getEOL(options, text) {
934
+ for (let i = 0;i < text.length; i++) {
935
+ const ch = text.charAt(i);
936
+ if (ch === "\r") {
937
+ if (i + 1 < text.length && text.charAt(i + 1) === `
938
+ `) {
939
+ return `\r
940
+ `;
941
+ }
942
+ return "\r";
943
+ } else if (ch === `
944
+ `) {
945
+ return `
946
+ `;
947
+ }
948
+ }
949
+ return options && options.eol || `
950
+ `;
951
+ }
952
+ function isEOL(text, offset) {
953
+ return `\r
954
+ `.indexOf(text.charAt(offset)) !== -1;
955
+ }
1036
956
 
1037
957
  // node_modules/.bun/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/impl/parser.js
1038
958
  var ParseOptions;
@@ -1084,6 +1004,95 @@ function parse(text, errors = [], options = ParseOptions.DEFAULT) {
1084
1004
  visit(text, visitor, options);
1085
1005
  return currentParent[0];
1086
1006
  }
1007
+ function parseTree(text, errors = [], options = ParseOptions.DEFAULT) {
1008
+ let currentParent = { type: "array", offset: -1, length: -1, children: [], parent: undefined };
1009
+ function ensurePropertyComplete(endOffset) {
1010
+ if (currentParent.type === "property") {
1011
+ currentParent.length = endOffset - currentParent.offset;
1012
+ currentParent = currentParent.parent;
1013
+ }
1014
+ }
1015
+ function onValue(valueNode) {
1016
+ currentParent.children.push(valueNode);
1017
+ return valueNode;
1018
+ }
1019
+ const visitor = {
1020
+ onObjectBegin: (offset) => {
1021
+ currentParent = onValue({ type: "object", offset, length: -1, parent: currentParent, children: [] });
1022
+ },
1023
+ onObjectProperty: (name, offset, length) => {
1024
+ currentParent = onValue({ type: "property", offset, length: -1, parent: currentParent, children: [] });
1025
+ currentParent.children.push({ type: "string", value: name, offset, length, parent: currentParent });
1026
+ },
1027
+ onObjectEnd: (offset, length) => {
1028
+ ensurePropertyComplete(offset + length);
1029
+ currentParent.length = offset + length - currentParent.offset;
1030
+ currentParent = currentParent.parent;
1031
+ ensurePropertyComplete(offset + length);
1032
+ },
1033
+ onArrayBegin: (offset, length) => {
1034
+ currentParent = onValue({ type: "array", offset, length: -1, parent: currentParent, children: [] });
1035
+ },
1036
+ onArrayEnd: (offset, length) => {
1037
+ currentParent.length = offset + length - currentParent.offset;
1038
+ currentParent = currentParent.parent;
1039
+ ensurePropertyComplete(offset + length);
1040
+ },
1041
+ onLiteralValue: (value, offset, length) => {
1042
+ onValue({ type: getNodeType(value), offset, length, parent: currentParent, value });
1043
+ ensurePropertyComplete(offset + length);
1044
+ },
1045
+ onSeparator: (sep, offset, length) => {
1046
+ if (currentParent.type === "property") {
1047
+ if (sep === ":") {
1048
+ currentParent.colonOffset = offset;
1049
+ } else if (sep === ",") {
1050
+ ensurePropertyComplete(offset);
1051
+ }
1052
+ }
1053
+ },
1054
+ onError: (error, offset, length) => {
1055
+ errors.push({ error, offset, length });
1056
+ }
1057
+ };
1058
+ visit(text, visitor, options);
1059
+ const result = currentParent.children[0];
1060
+ if (result) {
1061
+ delete result.parent;
1062
+ }
1063
+ return result;
1064
+ }
1065
+ function findNodeAtLocation(root, path3) {
1066
+ if (!root) {
1067
+ return;
1068
+ }
1069
+ let node = root;
1070
+ for (let segment of path3) {
1071
+ if (typeof segment === "string") {
1072
+ if (node.type !== "object" || !Array.isArray(node.children)) {
1073
+ return;
1074
+ }
1075
+ let found = false;
1076
+ for (const propertyNode of node.children) {
1077
+ if (Array.isArray(propertyNode.children) && propertyNode.children[0].value === segment && propertyNode.children.length === 2) {
1078
+ node = propertyNode.children[1];
1079
+ found = true;
1080
+ break;
1081
+ }
1082
+ }
1083
+ if (!found) {
1084
+ return;
1085
+ }
1086
+ } else {
1087
+ const index = segment;
1088
+ if (node.type !== "array" || index < 0 || !Array.isArray(node.children) || index >= node.children.length) {
1089
+ return;
1090
+ }
1091
+ node = node.children[index];
1092
+ }
1093
+ }
1094
+ return node;
1095
+ }
1087
1096
  function visit(text, visitor, options = ParseOptions.DEFAULT) {
1088
1097
  const _scanner = createScanner(text, false);
1089
1098
  const _jsonPath = [];
@@ -1336,6 +1345,170 @@ function visit(text, visitor, options = ParseOptions.DEFAULT) {
1336
1345
  }
1337
1346
  return true;
1338
1347
  }
1348
+ function getNodeType(value) {
1349
+ switch (typeof value) {
1350
+ case "boolean":
1351
+ return "boolean";
1352
+ case "number":
1353
+ return "number";
1354
+ case "string":
1355
+ return "string";
1356
+ case "object": {
1357
+ if (!value) {
1358
+ return "null";
1359
+ } else if (Array.isArray(value)) {
1360
+ return "array";
1361
+ }
1362
+ return "object";
1363
+ }
1364
+ default:
1365
+ return "null";
1366
+ }
1367
+ }
1368
+
1369
+ // node_modules/.bun/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/impl/edit.js
1370
+ function setProperty(text, originalPath, value, options) {
1371
+ const path3 = originalPath.slice();
1372
+ const errors = [];
1373
+ const root = parseTree(text, errors);
1374
+ let parent = undefined;
1375
+ let lastSegment = undefined;
1376
+ while (path3.length > 0) {
1377
+ lastSegment = path3.pop();
1378
+ parent = findNodeAtLocation(root, path3);
1379
+ if (parent === undefined && value !== undefined) {
1380
+ if (typeof lastSegment === "string") {
1381
+ value = { [lastSegment]: value };
1382
+ } else {
1383
+ value = [value];
1384
+ }
1385
+ } else {
1386
+ break;
1387
+ }
1388
+ }
1389
+ if (!parent) {
1390
+ if (value === undefined) {
1391
+ throw new Error("Can not delete in empty document");
1392
+ }
1393
+ return withFormatting(text, { offset: root ? root.offset : 0, length: root ? root.length : 0, content: JSON.stringify(value) }, options);
1394
+ } else if (parent.type === "object" && typeof lastSegment === "string" && Array.isArray(parent.children)) {
1395
+ const existing = findNodeAtLocation(parent, [lastSegment]);
1396
+ if (existing !== undefined) {
1397
+ if (value === undefined) {
1398
+ if (!existing.parent) {
1399
+ throw new Error("Malformed AST");
1400
+ }
1401
+ const propertyIndex = parent.children.indexOf(existing.parent);
1402
+ let removeBegin;
1403
+ let removeEnd = existing.parent.offset + existing.parent.length;
1404
+ if (propertyIndex > 0) {
1405
+ let previous = parent.children[propertyIndex - 1];
1406
+ removeBegin = previous.offset + previous.length;
1407
+ } else {
1408
+ removeBegin = parent.offset + 1;
1409
+ if (parent.children.length > 1) {
1410
+ let next = parent.children[1];
1411
+ removeEnd = next.offset;
1412
+ }
1413
+ }
1414
+ return withFormatting(text, { offset: removeBegin, length: removeEnd - removeBegin, content: "" }, options);
1415
+ } else {
1416
+ return withFormatting(text, { offset: existing.offset, length: existing.length, content: JSON.stringify(value) }, options);
1417
+ }
1418
+ } else {
1419
+ if (value === undefined) {
1420
+ return [];
1421
+ }
1422
+ const newProperty = `${JSON.stringify(lastSegment)}: ${JSON.stringify(value)}`;
1423
+ const index = options.getInsertionIndex ? options.getInsertionIndex(parent.children.map((p) => p.children[0].value)) : parent.children.length;
1424
+ let edit;
1425
+ if (index > 0) {
1426
+ let previous = parent.children[index - 1];
1427
+ edit = { offset: previous.offset + previous.length, length: 0, content: "," + newProperty };
1428
+ } else if (parent.children.length === 0) {
1429
+ edit = { offset: parent.offset + 1, length: 0, content: newProperty };
1430
+ } else {
1431
+ edit = { offset: parent.offset + 1, length: 0, content: newProperty + "," };
1432
+ }
1433
+ return withFormatting(text, edit, options);
1434
+ }
1435
+ } else if (parent.type === "array" && typeof lastSegment === "number" && Array.isArray(parent.children)) {
1436
+ const insertIndex = lastSegment;
1437
+ if (insertIndex === -1) {
1438
+ const newProperty = `${JSON.stringify(value)}`;
1439
+ let edit;
1440
+ if (parent.children.length === 0) {
1441
+ edit = { offset: parent.offset + 1, length: 0, content: newProperty };
1442
+ } else {
1443
+ const previous = parent.children[parent.children.length - 1];
1444
+ edit = { offset: previous.offset + previous.length, length: 0, content: "," + newProperty };
1445
+ }
1446
+ return withFormatting(text, edit, options);
1447
+ } else if (value === undefined && parent.children.length >= 0) {
1448
+ const removalIndex = lastSegment;
1449
+ const toRemove = parent.children[removalIndex];
1450
+ let edit;
1451
+ if (parent.children.length === 1) {
1452
+ edit = { offset: parent.offset + 1, length: parent.length - 2, content: "" };
1453
+ } else if (parent.children.length - 1 === removalIndex) {
1454
+ let previous = parent.children[removalIndex - 1];
1455
+ let offset = previous.offset + previous.length;
1456
+ let parentEndOffset = parent.offset + parent.length;
1457
+ edit = { offset, length: parentEndOffset - 2 - offset, content: "" };
1458
+ } else {
1459
+ edit = { offset: toRemove.offset, length: parent.children[removalIndex + 1].offset - toRemove.offset, content: "" };
1460
+ }
1461
+ return withFormatting(text, edit, options);
1462
+ } else if (value !== undefined) {
1463
+ let edit;
1464
+ const newProperty = `${JSON.stringify(value)}`;
1465
+ if (!options.isArrayInsertion && parent.children.length > lastSegment) {
1466
+ const toModify = parent.children[lastSegment];
1467
+ edit = { offset: toModify.offset, length: toModify.length, content: newProperty };
1468
+ } else if (parent.children.length === 0 || lastSegment === 0) {
1469
+ edit = { offset: parent.offset + 1, length: 0, content: parent.children.length === 0 ? newProperty : newProperty + "," };
1470
+ } else {
1471
+ const index = lastSegment > parent.children.length ? parent.children.length : lastSegment;
1472
+ const previous = parent.children[index - 1];
1473
+ edit = { offset: previous.offset + previous.length, length: 0, content: "," + newProperty };
1474
+ }
1475
+ return withFormatting(text, edit, options);
1476
+ } else {
1477
+ throw new Error(`Can not ${value === undefined ? "remove" : options.isArrayInsertion ? "insert" : "modify"} Array index ${insertIndex} as length is not sufficient`);
1478
+ }
1479
+ } else {
1480
+ throw new Error(`Can not add ${typeof lastSegment !== "number" ? "index" : "property"} to parent of type ${parent.type}`);
1481
+ }
1482
+ }
1483
+ function withFormatting(text, edit, options) {
1484
+ if (!options.formattingOptions) {
1485
+ return [edit];
1486
+ }
1487
+ let newText = applyEdit(text, edit);
1488
+ let begin = edit.offset;
1489
+ let end = edit.offset + edit.content.length;
1490
+ if (edit.length === 0 || edit.content.length === 0) {
1491
+ while (begin > 0 && !isEOL(newText, begin - 1)) {
1492
+ begin--;
1493
+ }
1494
+ while (end < newText.length && !isEOL(newText, end)) {
1495
+ end++;
1496
+ }
1497
+ }
1498
+ const edits = format(newText, { offset: begin, length: end - begin }, { ...options.formattingOptions, keepLines: false });
1499
+ for (let i = edits.length - 1;i >= 0; i--) {
1500
+ const edit2 = edits[i];
1501
+ newText = applyEdit(newText, edit2);
1502
+ begin = Math.min(begin, edit2.offset);
1503
+ end = Math.max(end, edit2.offset + edit2.length);
1504
+ end += edit2.content.length - edit2.length;
1505
+ }
1506
+ const editLength = text.length - (newText.length - end) - begin;
1507
+ return [{ offset: begin, length: editLength, content: newText.substring(begin, end) }];
1508
+ }
1509
+ function applyEdit(text, edit) {
1510
+ return text.substring(0, edit.offset) + edit.content + text.substring(edit.offset + edit.length);
1511
+ }
1339
1512
 
1340
1513
  // node_modules/.bun/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/main.js
1341
1514
  var ScanError;
@@ -1369,6 +1542,7 @@ var SyntaxKind;
1369
1542
  SyntaxKind2[SyntaxKind2["EOF"] = 17] = "EOF";
1370
1543
  })(SyntaxKind || (SyntaxKind = {}));
1371
1544
  var parse2 = parse;
1545
+ var parseTree2 = parseTree;
1372
1546
  var ParseErrorCode;
1373
1547
  (function(ParseErrorCode2) {
1374
1548
  ParseErrorCode2[ParseErrorCode2["InvalidSymbol"] = 1] = "InvalidSymbol";
@@ -1425,44 +1599,55 @@ function printParseErrorCode(code) {
1425
1599
  }
1426
1600
  return "<unknown ParseErrorCode>";
1427
1601
  }
1602
+ function modify(text, path3, value, options) {
1603
+ return setProperty(text, path3, value, options);
1604
+ }
1605
+ function applyEdits(text, edits) {
1606
+ let sortedEdits = edits.slice(0).sort((a, b) => {
1607
+ const diff = a.offset - b.offset;
1608
+ if (diff === 0) {
1609
+ return a.length - b.length;
1610
+ }
1611
+ return diff;
1612
+ });
1613
+ let lastModifiedOffset = text.length;
1614
+ for (let i = sortedEdits.length - 1;i >= 0; i--) {
1615
+ let e = sortedEdits[i];
1616
+ if (e.offset + e.length <= lastModifiedOffset) {
1617
+ text = applyEdit(text, e);
1618
+ } else {
1619
+ throw new Error("Overlapping edit");
1620
+ }
1621
+ lastModifiedOffset = e.offset;
1622
+ }
1623
+ return text;
1624
+ }
1428
1625
 
1429
1626
  // src/lib/bundled-names.ts
1430
1627
  var BUNDLED_AGENT_NAMES = [
1431
1628
  "adversarial-document-reviewer",
1432
1629
  "adversarial-reviewer",
1433
1630
  "agent-native-reviewer",
1434
- "ankane-readme-writer",
1435
1631
  "api-contract-reviewer",
1436
1632
  "architecture-strategist",
1437
1633
  "best-practices-researcher",
1438
1634
  "bug-reproduction-validator",
1439
- "cli-agent-readiness-reviewer",
1440
1635
  "cli-readiness-reviewer",
1441
1636
  "code-simplicity-reviewer",
1442
1637
  "coherence-reviewer",
1443
1638
  "correctness-reviewer",
1444
- "data-integrity-guardian",
1445
- "data-migration-expert",
1446
1639
  "data-migrations-reviewer",
1447
1640
  "deployment-verification-agent",
1448
- "design-implementation-reviewer",
1449
1641
  "design-iterator",
1450
1642
  "design-lens-reviewer",
1451
- "dhh-rails-reviewer",
1452
1643
  "feasibility-reviewer",
1453
- "figma-design-sync",
1454
1644
  "framework-docs-researcher",
1455
1645
  "git-history-analyzer",
1456
1646
  "issue-intelligence-analyst",
1457
- "julik-frontend-races-reviewer",
1458
- "kieran-python-reviewer",
1459
- "kieran-rails-reviewer",
1460
1647
  "kieran-typescript-reviewer",
1461
1648
  "learnings-researcher",
1462
- "lint",
1463
1649
  "maintainability-reviewer",
1464
1650
  "pattern-recognition-specialist",
1465
- "performance-oracle",
1466
1651
  "performance-reviewer",
1467
1652
  "pr-comment-resolver",
1468
1653
  "previous-comments-reviewer",
@@ -1470,21 +1655,16 @@ var BUNDLED_AGENT_NAMES = [
1470
1655
  "project-standards-reviewer",
1471
1656
  "reliability-reviewer",
1472
1657
  "repo-research-analyst",
1473
- "schema-drift-detector",
1474
1658
  "scope-guardian-reviewer",
1475
1659
  "security-lens-reviewer",
1476
1660
  "security-reviewer",
1477
- "security-sentinel",
1478
1661
  "slack-researcher",
1479
1662
  "spec-flow-analyzer",
1480
1663
  "systematic-implementer",
1481
1664
  "testing-reviewer"
1482
1665
  ];
1483
1666
  var BUNDLED_AGENT_QUALIFIED_IDS = [
1484
- "design/design-implementation-reviewer",
1485
1667
  "design/design-iterator",
1486
- "design/figma-design-sync",
1487
- "docs/ankane-readme-writer",
1488
1668
  "document-review/adversarial-document-reviewer",
1489
1669
  "document-review/coherence-reviewer",
1490
1670
  "document-review/design-lens-reviewer",
@@ -1503,32 +1683,21 @@ var BUNDLED_AGENT_QUALIFIED_IDS = [
1503
1683
  "review/agent-native-reviewer",
1504
1684
  "review/api-contract-reviewer",
1505
1685
  "review/architecture-strategist",
1506
- "review/cli-agent-readiness-reviewer",
1507
1686
  "review/cli-readiness-reviewer",
1508
1687
  "review/code-simplicity-reviewer",
1509
1688
  "review/correctness-reviewer",
1510
- "review/data-integrity-guardian",
1511
- "review/data-migration-expert",
1512
1689
  "review/data-migrations-reviewer",
1513
1690
  "review/deployment-verification-agent",
1514
- "review/dhh-rails-reviewer",
1515
- "review/julik-frontend-races-reviewer",
1516
- "review/kieran-python-reviewer",
1517
- "review/kieran-rails-reviewer",
1518
1691
  "review/kieran-typescript-reviewer",
1519
1692
  "review/maintainability-reviewer",
1520
1693
  "review/pattern-recognition-specialist",
1521
- "review/performance-oracle",
1522
1694
  "review/performance-reviewer",
1523
1695
  "review/previous-comments-reviewer",
1524
1696
  "review/project-standards-reviewer",
1525
1697
  "review/reliability-reviewer",
1526
- "review/schema-drift-detector",
1527
1698
  "review/security-reviewer",
1528
- "review/security-sentinel",
1529
1699
  "review/testing-reviewer",
1530
1700
  "workflow/bug-reproduction-validator",
1531
- "workflow/lint",
1532
1701
  "workflow/pr-comment-resolver",
1533
1702
  "workflow/spec-flow-analyzer",
1534
1703
  "workflow/systematic-implementer"
@@ -1537,7 +1706,6 @@ var BUNDLED_SKILL_NAMES = [
1537
1706
  "agent-browser",
1538
1707
  "agent-native-architecture",
1539
1708
  "agent-native-audit",
1540
- "andrew-kane-gem-writer",
1541
1709
  "ce:brainstorm",
1542
1710
  "ce:compound",
1543
1711
  "ce:compound-refresh",
@@ -1545,19 +1713,11 @@ var BUNDLED_SKILL_NAMES = [
1545
1713
  "ce:plan",
1546
1714
  "ce:review",
1547
1715
  "ce:work",
1548
- "changelog",
1549
- "claude-permissions-optimizer",
1550
1716
  "compound-docs",
1551
1717
  "deepen-plan",
1552
1718
  "deploy-docs",
1553
- "dhh-rails-style",
1554
1719
  "document-review",
1555
- "dspy-ruby",
1556
- "every-style-editor",
1557
- "feature-video",
1558
1720
  "frontend-design",
1559
- "gemini-imagegen",
1560
- "generate_command",
1561
1721
  "git-clean-gone-branches",
1562
1722
  "git-commit",
1563
1723
  "git-commit-push-pr",
@@ -1565,23 +1725,15 @@ var BUNDLED_SKILL_NAMES = [
1565
1725
  "lfg",
1566
1726
  "onboarding",
1567
1727
  "orchestrating-subagents",
1568
- "orchestrating-swarms",
1569
- "proof",
1570
- "rclone",
1571
1728
  "report-bug-ce",
1572
1729
  "reproduce-bug",
1573
1730
  "resolve-pr-feedback",
1574
- "setup",
1575
1731
  "slfg",
1576
1732
  "test-browser",
1577
1733
  "test-driven-development",
1578
- "test-xcode",
1579
- "todo-create",
1580
- "todo-resolve",
1581
- "todo-triage",
1734
+ "todos",
1582
1735
  "using-systematic",
1583
- "writing-skills",
1584
- "writing-systematic-skills"
1736
+ "writing-skills"
1585
1737
  ];
1586
1738
 
1587
1739
  // node_modules/.bun/zod@4.4.3/node_modules/zod/v4/classic/external.js
@@ -15872,8 +16024,56 @@ var OPENCODE_AGENT_COLOR_TOKENS = [
15872
16024
  ];
15873
16025
 
15874
16026
  // src/lib/removed-names.ts
15875
- var REMOVED_BUNDLED_SKILL_NAMES = [];
15876
- var REMOVED_BUNDLED_AGENT_NAMES = [];
16027
+ var REMOVED_BUNDLED_SKILL_NAMES = [
16028
+ "andrew-kane-gem-writer",
16029
+ "changelog",
16030
+ "claude-permissions-optimizer",
16031
+ "dhh-rails-style",
16032
+ "dspy-ruby",
16033
+ "every-style-editor",
16034
+ "feature-video",
16035
+ "gemini-imagegen",
16036
+ "generate_command",
16037
+ "orchestrating-swarms",
16038
+ "proof",
16039
+ "rclone",
16040
+ "setup",
16041
+ "test-xcode",
16042
+ "todo-create",
16043
+ "todo-resolve",
16044
+ "todo-triage",
16045
+ "writing-systematic-skills"
16046
+ ];
16047
+ var REMOVED_BUNDLED_AGENT_NAMES = [
16048
+ "ankane-readme-writer",
16049
+ "cli-agent-readiness-reviewer",
16050
+ "data-integrity-guardian",
16051
+ "data-migration-expert",
16052
+ "design-implementation-reviewer",
16053
+ "design/design-implementation-reviewer",
16054
+ "design/figma-design-sync",
16055
+ "dhh-rails-reviewer",
16056
+ "docs/ankane-readme-writer",
16057
+ "figma-design-sync",
16058
+ "julik-frontend-races-reviewer",
16059
+ "kieran-python-reviewer",
16060
+ "kieran-rails-reviewer",
16061
+ "lint",
16062
+ "performance-oracle",
16063
+ "review/cli-agent-readiness-reviewer",
16064
+ "review/data-integrity-guardian",
16065
+ "review/data-migration-expert",
16066
+ "review/dhh-rails-reviewer",
16067
+ "review/julik-frontend-races-reviewer",
16068
+ "review/kieran-python-reviewer",
16069
+ "review/kieran-rails-reviewer",
16070
+ "review/performance-oracle",
16071
+ "review/schema-drift-detector",
16072
+ "review/security-sentinel",
16073
+ "schema-drift-detector",
16074
+ "security-sentinel",
16075
+ "workflow/lint"
16076
+ ];
15877
16077
 
15878
16078
  // src/lib/config-schema.ts
15879
16079
  var permissionSettingSchema = exports_external.enum(["ask", "allow", "deny"]);
@@ -16009,7 +16209,7 @@ function createSystematicConfigSchema(opts) {
16009
16209
  $schema: exports_external.string().url().optional().meta({
16010
16210
  description: "JSON Schema URL for IDE autocomplete. The value is informational only \u2014 the loader does not fetch or validate against it. Add this to enable IDE schema activation and field-level autocomplete in editors that support JSON Schema (VSCode, Zed, IntelliJ).",
16011
16211
  examples: [
16012
- "https://fro.bot/systematic/schemas/v2/systematic-config.schema.json"
16212
+ "https://fro.bot/systematic/schemas/latest/systematic-config.schema.json"
16013
16213
  ]
16014
16214
  }),
16015
16215
  agents: exports_external.object(Object.fromEntries([...agentNames, ...qualifiedAgentIds].map((name) => [
@@ -16099,17 +16299,18 @@ var CURRENT_AGENT_NAMES_SET = new Set([
16099
16299
  function computeDroppedNames(names, allowedSet) {
16100
16300
  return names.filter((n) => !allowedSet.has(n));
16101
16301
  }
16302
+ var MIGRATION_DOCS_URL = "https://fro.bot/systematic/guides/v3-migration/";
16102
16303
  function warnDroppedNames(dropped, field, warned) {
16103
16304
  for (const name of dropped) {
16104
16305
  if (warned.has(name))
16105
16306
  continue;
16106
16307
  warned.add(name);
16107
- console.warn(`[systematic] "${name}" in \`${field}\` is no longer a bundled name and will be ignored. Remove it from your config to silence this warning.`);
16308
+ console.warn(`[systematic] "${name}" in \`${field}\` is no longer a bundled name and will be ignored. Remove it from your config to silence this warning. See ${MIGRATION_DOCS_URL} for migration guidance.`);
16108
16309
  }
16109
16310
  }
16110
16311
  function resolveConfigPath(dir, basename) {
16111
16312
  const jsoncPath = path3.join(dir, `${basename}.jsonc`);
16112
- if (fs4.existsSync(jsoncPath))
16313
+ if (fs3.existsSync(jsoncPath))
16113
16314
  return jsoncPath;
16114
16315
  return path3.join(dir, `${basename}.json`);
16115
16316
  }
@@ -16119,7 +16320,7 @@ function isErrorWithCode(error51) {
16119
16320
  function loadJsoncFile(filePath) {
16120
16321
  let content;
16121
16322
  try {
16122
- content = fs4.readFileSync(filePath, "utf-8");
16323
+ content = fs3.readFileSync(filePath, "utf-8");
16123
16324
  } catch (error51) {
16124
16325
  if (isErrorWithCode(error51) && error51.code === "ENOENT")
16125
16326
  return null;
@@ -16425,4 +16626,4 @@ function extractCommandFrontmatter(content) {
16425
16626
  };
16426
16627
  }
16427
16628
 
16428
- export { parseFrontmatter, isRecord, convertContent, convertFileWithCache, walkDir, extractFrontmatterFromContent, findSkillsInDir, exports_external, AgentOverlaySchema, CategoryOverlaySchema, loadConfig, loadConfigWithSources, getConfigPaths, findAgentsInDir, extractAgentFrontmatter, findCommandsInDir, extractCommandFrontmatter };
16629
+ export { parseFrontmatter, isRecord, walkDir, extractFrontmatterFromContent, findSkillsInDir, parse2 as parse, parseTree2 as parseTree, modify, applyEdits, exports_external, AgentOverlaySchema, CategoryOverlaySchema, loadConfig, loadConfigWithSources, getConfigPaths, findAgentsInDir, extractAgentFrontmatter, findCommandsInDir, extractCommandFrontmatter };