@fro.bot/systematic 3.16.5 → 3.17.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.
package/dist/cli.js CHANGED
@@ -33,7 +33,7 @@ import {
33
33
  findCommandsInDir,
34
34
  findSkillsInDir,
35
35
  discoverSkills
36
- } from "./index-65g87tgr.js";
36
+ } from "./index-y33enbkc.js";
37
37
  var __defProp = Object.defineProperty;
38
38
  var __returnValue = (v) => v;
39
39
  function __exportSetter(name, newValue) {
@@ -197,7 +197,8 @@ function readOpencodeLayerField(agentOverlay, categoryOverlay, layer, field) {
197
197
  }
198
198
  function resolveOpencodeModelAndVariant(agentOverlay, categoryOverlay) {
199
199
  const modelLayerIndex = OPENCODE_MODEL_VARIANT_LAYERS.findIndex((layer) => readOpencodeLayerField(agentOverlay, categoryOverlay, layer, "model") !== undefined);
200
- const rawModel = modelLayerIndex === -1 ? undefined : readOpencodeLayerField(agentOverlay, categoryOverlay, OPENCODE_MODEL_VARIANT_LAYERS[modelLayerIndex], "model");
200
+ const modelLayer = modelLayerIndex === -1 ? undefined : OPENCODE_MODEL_VARIANT_LAYERS[modelLayerIndex];
201
+ const rawModel = modelLayer === undefined ? undefined : readOpencodeLayerField(agentOverlay, categoryOverlay, modelLayer, "model");
201
202
  const model = narrowModelValue(rawModel);
202
203
  const hasModel = model !== undefined;
203
204
  const modelSource = hasModel ? OPENCODE_MODEL_VARIANT_LAYERS[modelLayerIndex] : undefined;
@@ -205,8 +206,7 @@ function resolveOpencodeModelAndVariant(agentOverlay, categoryOverlay) {
205
206
  let qualifierSource;
206
207
  if (model !== null) {
207
208
  const eligibleLayerCount = hasModel ? modelLayerIndex + 1 : OPENCODE_MODEL_VARIANT_LAYERS.length;
208
- for (let i = 0;i < eligibleLayerCount; i++) {
209
- const layer = OPENCODE_MODEL_VARIANT_LAYERS[i];
209
+ for (const layer of OPENCODE_MODEL_VARIANT_LAYERS.slice(0, eligibleLayerCount)) {
210
210
  const narrowed = narrowQualifierValue(readOpencodeLayerField(agentOverlay, categoryOverlay, layer, "variant"));
211
211
  if (narrowed !== undefined) {
212
212
  qualifier = narrowed;
@@ -1761,6 +1761,7 @@ var BUNDLED_SKILL_NAMES = [
1761
1761
  "ce:ideate",
1762
1762
  "ce:plan",
1763
1763
  "ce:review",
1764
+ "ce:review-cleanup",
1764
1765
  "ce:work",
1765
1766
  "compound-docs",
1766
1767
  "deepen-plan",
@@ -8686,8 +8687,7 @@ function parseFrontmatter(content) {
8686
8687
  parseError: false
8687
8688
  };
8688
8689
  }
8689
- const yamlContent = match[1];
8690
- const body = match[2];
8690
+ const [, yamlContent = "", body = ""] = match;
8691
8691
  try {
8692
8692
  const parsed = yaml.load(yamlContent, { schema: yaml.JSON_SCHEMA });
8693
8693
  const data = parsed ?? {};
package/dist/index.js CHANGED
@@ -19,7 +19,7 @@ import {
19
19
  extractCommandFrontmatter,
20
20
  findSkillsInDir,
21
21
  discoverSkills
22
- } from "./index-65g87tgr.js";
22
+ } from "./index-y33enbkc.js";
23
23
 
24
24
  // src/index.ts
25
25
  import { createHash as createHash4 } from "crypto";
@@ -75,14 +75,14 @@ var removeCompleteBootstrapBlocks = (entry) => {
75
75
  return result;
76
76
  };
77
77
  var applyBootstrapContent = (output, content) => {
78
- for (let i2 = 0;i2 < output.system.length; i2++) {
79
- output.system[i2] = removeCompleteBootstrapBlocks(output.system[i2]);
78
+ for (const [i2, entry] of output.system.entries()) {
79
+ output.system[i2] = removeCompleteBootstrapBlocks(entry);
80
80
  }
81
- if (output.system.length === 0) {
81
+ const [first] = output.system;
82
+ if (first === undefined) {
82
83
  output.system.push(content);
83
84
  return;
84
85
  }
85
- const first = output.system[0];
86
86
  output.system[0] = first.length > 0 ? `${first}
87
87
 
88
88
  ${content}` : content;
@@ -265,6 +265,9 @@ function parseOverlayShape(overlay, targetType) {
265
265
  return { skills: result.data.skills };
266
266
  }
267
267
  function throwOverlaySchemaError(overlay, issue) {
268
+ if (!issue) {
269
+ throwConfigError(overlay.sourcePath, overlay.keyPath, "schema validation failed");
270
+ }
268
271
  const zodPath = issue.code === "unrecognized_keys" ? issue.message.match(/"([^"]+)"/)?.[1] ?? issue.path.join(".") : issue.path.join(".");
269
272
  const fullPath = zodPath ? `${overlay.keyPath}.${zodPath}` : overlay.keyPath;
270
273
  throwConfigError(overlay.sourcePath, fullPath, issue.message);
@@ -332,7 +335,8 @@ $ARGUMENTS
332
335
  }
333
336
  function extractSkillBody(wrappedTemplate) {
334
337
  const match = wrappedTemplate.match(/<skill-instruction>([\s\S]*?)<\/skill-instruction>/);
335
- return match ? match[1].trim() : wrappedTemplate;
338
+ const [, body2] = match ?? [];
339
+ return body2 !== undefined ? body2.trim() : wrappedTemplate;
336
340
  }
337
341
  function loadSkill(skillInfo) {
338
342
  try {
@@ -956,7 +960,8 @@ function readGitfileTarget(gitfilePath, realPath = fs6.realpathSync) {
956
960
  const match = /^gitdir:\s*(.+?)\s*$/im.exec(contents);
957
961
  if (!match)
958
962
  return;
959
- const target = path5.isAbsolute(match[1]) ? match[1] : path5.resolve(path5.dirname(gitfilePath), match[1]);
963
+ const [, gitdirTarget = ""] = match;
964
+ const target = path5.isAbsolute(gitdirTarget) ? gitdirTarget : path5.resolve(path5.dirname(gitfilePath), gitdirTarget);
960
965
  return canonicalPath(target, realPath);
961
966
  }
962
967
  function readGitdirBacklink(backlinkPath, realPath) {
@@ -7869,7 +7874,7 @@ function parseCommand(node) {
7869
7874
  const commandName = node.childForFieldName("name");
7870
7875
  if (commandName?.type !== "command_name")
7871
7876
  return;
7872
- const executable = parsePlainToken(commandName.namedChildren[0]);
7877
+ const executable = parsePlainToken(commandName.namedChildren[0] ?? null);
7873
7878
  if (!executable)
7874
7879
  return;
7875
7880
  if (!hasSafeCommandChildren(node))
@@ -7936,13 +7941,14 @@ function containsDynamicSyntax(node) {
7936
7941
  return false;
7937
7942
  }
7938
7943
  function classifyCommands(commands) {
7939
- if (commands.length === 0)
7944
+ const lastCommand = commands.at(-1);
7945
+ if (lastCommand === undefined)
7940
7946
  return;
7941
7947
  for (const prefix of commands.slice(0, -1)) {
7942
7948
  if (!isAllowedPrefix(prefix))
7943
7949
  return;
7944
7950
  }
7945
- return classifyFinalCommand(commands[commands.length - 1]);
7951
+ return classifyFinalCommand(lastCommand);
7946
7952
  }
7947
7953
  function isAllowedPrefix(command) {
7948
7954
  return PREFIX_COMMANDS.has(command.executable) && command.arguments.length === 1 && isSafeRelativeCwd(command.arguments[0] ?? "");
@@ -8015,7 +8021,7 @@ function isDestructivePushArgument(value) {
8015
8021
  function classifyGhCommand(args2) {
8016
8022
  if (args2[0] !== "pr")
8017
8023
  return;
8018
- if (args2.length === 6 && args2[1] === "create" && args2[2] === "--title" && args2[3]?.length > 0 && args2[4] === "--body" && args2[5]?.length > 0 && !isEmptyShellString(args2[3]) && !isEmptyShellString(args2[5])) {
8024
+ if (args2.length === 6 && args2[1] === "create" && args2[2] === "--title" && (args2[3]?.length ?? 0) > 0 && args2[4] === "--body" && (args2[5]?.length ?? 0) > 0 && !isEmptyShellString(args2[3]) && !isEmptyShellString(args2[5])) {
8019
8025
  return "pr-creation";
8020
8026
  }
8021
8027
  if (args2.length === 3 && args2[1] === "checks" && isPullRequestNumber(args2[2]))
@@ -10726,8 +10732,7 @@ function canonicalPatchText(patchText, sessionLocation) {
10726
10732
  if (patchTextFileTargets(patchText) === undefined)
10727
10733
  return;
10728
10734
  const segments = patchText.split(/(\r?\n)/);
10729
- for (let index = 0;index < segments.length; index += 1) {
10730
- const line = segments[index];
10735
+ for (const [index, line] of segments.entries()) {
10731
10736
  if (line === `
10732
10737
  ` || line === `\r
10733
10738
  `)
@@ -1,5 +1,5 @@
1
1
  export declare const BUNDLED_AGENT_NAMES: readonly ['adversarial-document-reviewer', 'adversarial-reviewer', 'agent-native-reviewer', 'api-contract-reviewer', 'architecture-strategist', 'best-practices-researcher', 'bug-reproduction-validator', 'cli-readiness-reviewer', 'code-simplicity-reviewer', 'coherence-reviewer', 'correctness-reviewer', 'data-migrations-reviewer', 'deployment-verification-agent', 'design-iterator', 'design-lens-reviewer', 'feasibility-reviewer', 'framework-docs-researcher', 'git-history-analyzer', 'issue-intelligence-analyst', 'kieran-typescript-reviewer', 'learnings-researcher', 'maintainability-reviewer', 'pattern-recognition-specialist', 'performance-reviewer', 'pr-comment-resolver', 'previous-comments-reviewer', 'product-lens-reviewer', 'project-standards-reviewer', 'reliability-reviewer', 'repo-research-analyst', 'scope-guardian-reviewer', 'security-lens-reviewer', 'security-reviewer', 'slack-researcher', 'spec-flow-analyzer', 'systematic-implementer', 'testing-reviewer'];
2
2
  export declare const BUNDLED_AGENT_QUALIFIED_IDS: readonly ['design/design-iterator', 'document-review/adversarial-document-reviewer', 'document-review/coherence-reviewer', 'document-review/design-lens-reviewer', 'document-review/feasibility-reviewer', 'document-review/product-lens-reviewer', 'document-review/scope-guardian-reviewer', 'document-review/security-lens-reviewer', 'research/best-practices-researcher', 'research/framework-docs-researcher', 'research/git-history-analyzer', 'research/issue-intelligence-analyst', 'research/learnings-researcher', 'research/repo-research-analyst', 'research/slack-researcher', 'review/adversarial-reviewer', 'review/agent-native-reviewer', 'review/api-contract-reviewer', 'review/architecture-strategist', 'review/cli-readiness-reviewer', 'review/code-simplicity-reviewer', 'review/correctness-reviewer', 'review/data-migrations-reviewer', 'review/deployment-verification-agent', 'review/kieran-typescript-reviewer', 'review/maintainability-reviewer', 'review/pattern-recognition-specialist', 'review/performance-reviewer', 'review/previous-comments-reviewer', 'review/project-standards-reviewer', 'review/reliability-reviewer', 'review/security-reviewer', 'review/testing-reviewer', 'workflow/bug-reproduction-validator', 'workflow/pr-comment-resolver', 'workflow/spec-flow-analyzer', 'workflow/systematic-implementer'];
3
- export declare const BUNDLED_SKILL_NAMES: readonly ['agent-browser', 'agent-native-architecture', 'agent-native-audit', 'ce:brainstorm', 'ce:compound', 'ce:compound-refresh', 'ce:ideate', 'ce:plan', 'ce:review', 'ce:work', 'compound-docs', 'deepen-plan', 'deploy-docs', 'document-review', 'frontend-design', 'git-clean-gone-branches', 'git-commit', 'git-commit-push-pr', 'git-worktree', 'lfg', 'onboarding', 'orchestrating-subagents', 'report-bug-ce', 'reproduce-bug', 'resolve-pr-feedback', 'slfg', 'test-browser', 'test-driven-development', 'todos', 'using-systematic', 'writing-skills'];
3
+ export declare const BUNDLED_SKILL_NAMES: readonly ['agent-browser', 'agent-native-architecture', 'agent-native-audit', 'ce:brainstorm', 'ce:compound', 'ce:compound-refresh', 'ce:ideate', 'ce:plan', 'ce:review', 'ce:review-cleanup', 'ce:work', 'compound-docs', 'deepen-plan', 'deploy-docs', 'document-review', 'frontend-design', 'git-clean-gone-branches', 'git-commit', 'git-commit-push-pr', 'git-worktree', 'lfg', 'onboarding', 'orchestrating-subagents', 'report-bug-ce', 'reproduce-bug', 'resolve-pr-feedback', 'slfg', 'test-browser', 'test-driven-development', 'todos', 'using-systematic', 'writing-skills'];
4
4
  export type BundledAgentName = (typeof BUNDLED_AGENT_NAMES)[number];
5
5
  export type BundledSkillName = (typeof BUNDLED_SKILL_NAMES)[number];
@@ -242,11 +242,434 @@ export interface SystematicConfigSchemaOptions {
242
242
  * @returns A Zod object schema parsing the top-level Systematic config,
243
243
  * built from the provided agent and skill name sets.
244
244
  */
245
- export declare function createSystematicConfigSchema(opts: SystematicConfigSchemaOptions): z.ZodObject<z.core.$ZodLooseShape>;
246
- export declare const SystematicConfigSchema: z.ZodObject<z.core.$ZodLooseShape, z.core.$strip>;
245
+ export declare function createSystematicConfigSchema(opts: SystematicConfigSchemaOptions): z.ZodObject<{
246
+ $schema: z.ZodOptional<z.ZodString>;
247
+ agents: z.ZodDefault<z.ZodObject<{
248
+ [x: string]: z.ZodOptional<z.ZodObject<{
249
+ model: z.ZodOptional<z.ZodNullable<z.ZodString>>;
250
+ variant: z.ZodOptional<z.ZodString>;
251
+ temperature: z.ZodOptional<z.ZodNumber>;
252
+ top_p: z.ZodOptional<z.ZodNumber>;
253
+ mode: z.ZodOptional<z.ZodEnum<{
254
+ all: "all";
255
+ primary: "primary";
256
+ subagent: "subagent";
257
+ }>>;
258
+ color: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
259
+ accent: "accent";
260
+ error: "error";
261
+ info: "info";
262
+ primary: "primary";
263
+ secondary: "secondary";
264
+ success: "success";
265
+ warning: "warning";
266
+ }>, z.ZodString]>>;
267
+ steps: z.ZodOptional<z.ZodNumber>;
268
+ hidden: z.ZodOptional<z.ZodBoolean>;
269
+ disable: z.ZodOptional<z.ZodBoolean>;
270
+ skills: z.ZodOptional<z.ZodArray<z.ZodString>>;
271
+ permission: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodEnum<{
272
+ allow: "allow";
273
+ ask: "ask";
274
+ deny: "deny";
275
+ }>, z.ZodRecord<z.ZodString, z.ZodEnum<{
276
+ allow: "allow";
277
+ ask: "ask";
278
+ deny: "deny";
279
+ }>>]>>>;
280
+ opencode: z.ZodOptional<z.ZodObject<{
281
+ model: z.ZodOptional<z.ZodNullable<z.ZodString>>;
282
+ variant: z.ZodOptional<z.ZodString>;
283
+ }, z.core.$strict>>;
284
+ pi: z.ZodOptional<z.ZodObject<{
285
+ model: z.ZodOptional<z.ZodNullable<z.ZodString>>;
286
+ thinking: z.ZodOptional<z.ZodEnum<{
287
+ high: "high";
288
+ low: "low";
289
+ max: "max";
290
+ medium: "medium";
291
+ minimal: "minimal";
292
+ off: "off";
293
+ xhigh: "xhigh";
294
+ }>>;
295
+ }, z.core.$strict>>;
296
+ }, z.core.$strict>>;
297
+ }, z.core.$strict>>;
298
+ categories: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
299
+ model: z.ZodOptional<z.ZodNullable<z.ZodString>>;
300
+ variant: z.ZodOptional<z.ZodString>;
301
+ temperature: z.ZodOptional<z.ZodNumber>;
302
+ top_p: z.ZodOptional<z.ZodNumber>;
303
+ mode: z.ZodOptional<z.ZodEnum<{
304
+ all: "all";
305
+ primary: "primary";
306
+ subagent: "subagent";
307
+ }>>;
308
+ color: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
309
+ accent: "accent";
310
+ error: "error";
311
+ info: "info";
312
+ primary: "primary";
313
+ secondary: "secondary";
314
+ success: "success";
315
+ warning: "warning";
316
+ }>, z.ZodString]>>;
317
+ steps: z.ZodOptional<z.ZodNumber>;
318
+ hidden: z.ZodOptional<z.ZodBoolean>;
319
+ skills: z.ZodOptional<z.ZodArray<z.ZodString>>;
320
+ permission: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodEnum<{
321
+ allow: "allow";
322
+ ask: "ask";
323
+ deny: "deny";
324
+ }>, z.ZodRecord<z.ZodString, z.ZodEnum<{
325
+ allow: "allow";
326
+ ask: "ask";
327
+ deny: "deny";
328
+ }>>]>>>;
329
+ opencode: z.ZodOptional<z.ZodObject<{
330
+ model: z.ZodOptional<z.ZodNullable<z.ZodString>>;
331
+ variant: z.ZodOptional<z.ZodString>;
332
+ }, z.core.$strict>>;
333
+ pi: z.ZodOptional<z.ZodObject<{
334
+ model: z.ZodOptional<z.ZodNullable<z.ZodString>>;
335
+ thinking: z.ZodOptional<z.ZodEnum<{
336
+ high: "high";
337
+ low: "low";
338
+ max: "max";
339
+ medium: "medium";
340
+ minimal: "minimal";
341
+ off: "off";
342
+ xhigh: "xhigh";
343
+ }>>;
344
+ }, z.core.$strict>>;
345
+ }, z.core.$strict>>>;
346
+ profiles: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
347
+ agents: z.ZodOptional<z.ZodObject<{
348
+ [x: string]: z.ZodOptional<z.ZodObject<{
349
+ model: z.ZodOptional<z.ZodNullable<z.ZodString>>;
350
+ variant: z.ZodOptional<z.ZodString>;
351
+ temperature: z.ZodOptional<z.ZodNumber>;
352
+ top_p: z.ZodOptional<z.ZodNumber>;
353
+ opencode: z.ZodOptional<z.ZodObject<{
354
+ model: z.ZodOptional<z.ZodNullable<z.ZodString>>;
355
+ variant: z.ZodOptional<z.ZodString>;
356
+ }, z.core.$strict>>;
357
+ pi: z.ZodOptional<z.ZodObject<{
358
+ model: z.ZodOptional<z.ZodNullable<z.ZodString>>;
359
+ thinking: z.ZodOptional<z.ZodEnum<{
360
+ high: "high";
361
+ low: "low";
362
+ max: "max";
363
+ medium: "medium";
364
+ minimal: "minimal";
365
+ off: "off";
366
+ xhigh: "xhigh";
367
+ }>>;
368
+ }, z.core.$strict>>;
369
+ }, z.core.$strict>>;
370
+ }, z.core.$strict>>;
371
+ categories: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
372
+ model: z.ZodOptional<z.ZodNullable<z.ZodString>>;
373
+ variant: z.ZodOptional<z.ZodString>;
374
+ temperature: z.ZodOptional<z.ZodNumber>;
375
+ top_p: z.ZodOptional<z.ZodNumber>;
376
+ opencode: z.ZodOptional<z.ZodObject<{
377
+ model: z.ZodOptional<z.ZodNullable<z.ZodString>>;
378
+ variant: z.ZodOptional<z.ZodString>;
379
+ }, z.core.$strict>>;
380
+ pi: z.ZodOptional<z.ZodObject<{
381
+ model: z.ZodOptional<z.ZodNullable<z.ZodString>>;
382
+ thinking: z.ZodOptional<z.ZodEnum<{
383
+ high: "high";
384
+ low: "low";
385
+ max: "max";
386
+ medium: "medium";
387
+ minimal: "minimal";
388
+ off: "off";
389
+ xhigh: "xhigh";
390
+ }>>;
391
+ }, z.core.$strict>>;
392
+ }, z.core.$strict>>>;
393
+ }, z.core.$strict>>>;
394
+ profile: z.ZodOptional<z.ZodNullable<z.ZodString>>;
395
+ disabled_skills: z.ZodDefault<z.ZodArray<z.ZodEnum<{
396
+ [x: string]: string;
397
+ }>>>;
398
+ disabled_agents: z.ZodDefault<z.ZodArray<z.ZodEnum<{
399
+ [x: string]: string;
400
+ }>>>;
401
+ disabled_commands: z.ZodDefault<z.ZodArray<z.ZodString>>;
402
+ bootstrap: z.ZodDefault<z.ZodObject<{
403
+ enabled: z.ZodDefault<z.ZodBoolean>;
404
+ file: z.ZodOptional<z.ZodString>;
405
+ }, z.core.$strict>>;
406
+ workflow_guard: z.ZodDefault<z.ZodObject<{
407
+ mode: z.ZodDefault<z.ZodEnum<{
408
+ disabled: "disabled";
409
+ observe: "observe";
410
+ protected: "protected";
411
+ }>>;
412
+ debug: z.ZodDefault<z.ZodBoolean>;
413
+ }, z.core.$strict>>;
414
+ pi_subagents: z.ZodDefault<z.ZodObject<{
415
+ categories: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
416
+ thinking: z.ZodOptional<z.ZodEnum<{
417
+ high: "high";
418
+ low: "low";
419
+ max: "max";
420
+ medium: "medium";
421
+ minimal: "minimal";
422
+ off: "off";
423
+ xhigh: "xhigh";
424
+ }>>;
425
+ max_turns: z.ZodOptional<z.ZodNumber>;
426
+ tools: z.ZodOptional<z.ZodString>;
427
+ skills: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodString]>>;
428
+ }, z.core.$strict>>>;
429
+ agents: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
430
+ thinking: z.ZodOptional<z.ZodEnum<{
431
+ high: "high";
432
+ low: "low";
433
+ max: "max";
434
+ medium: "medium";
435
+ minimal: "minimal";
436
+ off: "off";
437
+ xhigh: "xhigh";
438
+ }>>;
439
+ max_turns: z.ZodOptional<z.ZodNumber>;
440
+ tools: z.ZodOptional<z.ZodString>;
441
+ skills: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodString]>>;
442
+ }, z.core.$strict>>>;
443
+ }, z.core.$strict>>;
444
+ skills_as_commands: z.ZodDefault<z.ZodBoolean>;
445
+ }, z.core.$strict>;
446
+ export declare const SystematicConfigSchema: z.ZodObject<{
447
+ $schema: z.ZodOptional<z.ZodString>;
448
+ agents: z.ZodDefault<z.ZodObject<{
449
+ [x: string]: z.ZodOptional<z.ZodObject<{
450
+ model: z.ZodOptional<z.ZodNullable<z.ZodString>>;
451
+ variant: z.ZodOptional<z.ZodString>;
452
+ temperature: z.ZodOptional<z.ZodNumber>;
453
+ top_p: z.ZodOptional<z.ZodNumber>;
454
+ mode: z.ZodOptional<z.ZodEnum<{
455
+ all: "all";
456
+ primary: "primary";
457
+ subagent: "subagent";
458
+ }>>;
459
+ color: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
460
+ accent: "accent";
461
+ error: "error";
462
+ info: "info";
463
+ primary: "primary";
464
+ secondary: "secondary";
465
+ success: "success";
466
+ warning: "warning";
467
+ }>, z.ZodString]>>;
468
+ steps: z.ZodOptional<z.ZodNumber>;
469
+ hidden: z.ZodOptional<z.ZodBoolean>;
470
+ disable: z.ZodOptional<z.ZodBoolean>;
471
+ skills: z.ZodOptional<z.ZodArray<z.ZodString>>;
472
+ permission: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodEnum<{
473
+ allow: "allow";
474
+ ask: "ask";
475
+ deny: "deny";
476
+ }>, z.ZodRecord<z.ZodString, z.ZodEnum<{
477
+ allow: "allow";
478
+ ask: "ask";
479
+ deny: "deny";
480
+ }>>]>>>;
481
+ opencode: z.ZodOptional<z.ZodObject<{
482
+ model: z.ZodOptional<z.ZodNullable<z.ZodString>>;
483
+ variant: z.ZodOptional<z.ZodString>;
484
+ }, z.core.$strict>>;
485
+ pi: z.ZodOptional<z.ZodObject<{
486
+ model: z.ZodOptional<z.ZodNullable<z.ZodString>>;
487
+ thinking: z.ZodOptional<z.ZodEnum<{
488
+ high: "high";
489
+ low: "low";
490
+ max: "max";
491
+ medium: "medium";
492
+ minimal: "minimal";
493
+ off: "off";
494
+ xhigh: "xhigh";
495
+ }>>;
496
+ }, z.core.$strict>>;
497
+ }, z.core.$strict>>;
498
+ }, z.core.$strict>>;
499
+ categories: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
500
+ model: z.ZodOptional<z.ZodNullable<z.ZodString>>;
501
+ variant: z.ZodOptional<z.ZodString>;
502
+ temperature: z.ZodOptional<z.ZodNumber>;
503
+ top_p: z.ZodOptional<z.ZodNumber>;
504
+ mode: z.ZodOptional<z.ZodEnum<{
505
+ all: "all";
506
+ primary: "primary";
507
+ subagent: "subagent";
508
+ }>>;
509
+ color: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
510
+ accent: "accent";
511
+ error: "error";
512
+ info: "info";
513
+ primary: "primary";
514
+ secondary: "secondary";
515
+ success: "success";
516
+ warning: "warning";
517
+ }>, z.ZodString]>>;
518
+ steps: z.ZodOptional<z.ZodNumber>;
519
+ hidden: z.ZodOptional<z.ZodBoolean>;
520
+ skills: z.ZodOptional<z.ZodArray<z.ZodString>>;
521
+ permission: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodEnum<{
522
+ allow: "allow";
523
+ ask: "ask";
524
+ deny: "deny";
525
+ }>, z.ZodRecord<z.ZodString, z.ZodEnum<{
526
+ allow: "allow";
527
+ ask: "ask";
528
+ deny: "deny";
529
+ }>>]>>>;
530
+ opencode: z.ZodOptional<z.ZodObject<{
531
+ model: z.ZodOptional<z.ZodNullable<z.ZodString>>;
532
+ variant: z.ZodOptional<z.ZodString>;
533
+ }, z.core.$strict>>;
534
+ pi: z.ZodOptional<z.ZodObject<{
535
+ model: z.ZodOptional<z.ZodNullable<z.ZodString>>;
536
+ thinking: z.ZodOptional<z.ZodEnum<{
537
+ high: "high";
538
+ low: "low";
539
+ max: "max";
540
+ medium: "medium";
541
+ minimal: "minimal";
542
+ off: "off";
543
+ xhigh: "xhigh";
544
+ }>>;
545
+ }, z.core.$strict>>;
546
+ }, z.core.$strict>>>;
547
+ profiles: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
548
+ agents: z.ZodOptional<z.ZodObject<{
549
+ [x: string]: z.ZodOptional<z.ZodObject<{
550
+ model: z.ZodOptional<z.ZodNullable<z.ZodString>>;
551
+ variant: z.ZodOptional<z.ZodString>;
552
+ temperature: z.ZodOptional<z.ZodNumber>;
553
+ top_p: z.ZodOptional<z.ZodNumber>;
554
+ opencode: z.ZodOptional<z.ZodObject<{
555
+ model: z.ZodOptional<z.ZodNullable<z.ZodString>>;
556
+ variant: z.ZodOptional<z.ZodString>;
557
+ }, z.core.$strict>>;
558
+ pi: z.ZodOptional<z.ZodObject<{
559
+ model: z.ZodOptional<z.ZodNullable<z.ZodString>>;
560
+ thinking: z.ZodOptional<z.ZodEnum<{
561
+ high: "high";
562
+ low: "low";
563
+ max: "max";
564
+ medium: "medium";
565
+ minimal: "minimal";
566
+ off: "off";
567
+ xhigh: "xhigh";
568
+ }>>;
569
+ }, z.core.$strict>>;
570
+ }, z.core.$strict>>;
571
+ }, z.core.$strict>>;
572
+ categories: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
573
+ model: z.ZodOptional<z.ZodNullable<z.ZodString>>;
574
+ variant: z.ZodOptional<z.ZodString>;
575
+ temperature: z.ZodOptional<z.ZodNumber>;
576
+ top_p: z.ZodOptional<z.ZodNumber>;
577
+ opencode: z.ZodOptional<z.ZodObject<{
578
+ model: z.ZodOptional<z.ZodNullable<z.ZodString>>;
579
+ variant: z.ZodOptional<z.ZodString>;
580
+ }, z.core.$strict>>;
581
+ pi: z.ZodOptional<z.ZodObject<{
582
+ model: z.ZodOptional<z.ZodNullable<z.ZodString>>;
583
+ thinking: z.ZodOptional<z.ZodEnum<{
584
+ high: "high";
585
+ low: "low";
586
+ max: "max";
587
+ medium: "medium";
588
+ minimal: "minimal";
589
+ off: "off";
590
+ xhigh: "xhigh";
591
+ }>>;
592
+ }, z.core.$strict>>;
593
+ }, z.core.$strict>>>;
594
+ }, z.core.$strict>>>;
595
+ profile: z.ZodOptional<z.ZodNullable<z.ZodString>>;
596
+ disabled_skills: z.ZodDefault<z.ZodArray<z.ZodEnum<{
597
+ [x: string]: string;
598
+ }>>>;
599
+ disabled_agents: z.ZodDefault<z.ZodArray<z.ZodEnum<{
600
+ [x: string]: string;
601
+ }>>>;
602
+ disabled_commands: z.ZodDefault<z.ZodArray<z.ZodString>>;
603
+ bootstrap: z.ZodDefault<z.ZodObject<{
604
+ enabled: z.ZodDefault<z.ZodBoolean>;
605
+ file: z.ZodOptional<z.ZodString>;
606
+ }, z.core.$strict>>;
607
+ workflow_guard: z.ZodDefault<z.ZodObject<{
608
+ mode: z.ZodDefault<z.ZodEnum<{
609
+ disabled: "disabled";
610
+ observe: "observe";
611
+ protected: "protected";
612
+ }>>;
613
+ debug: z.ZodDefault<z.ZodBoolean>;
614
+ }, z.core.$strict>>;
615
+ pi_subagents: z.ZodDefault<z.ZodObject<{
616
+ categories: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
617
+ thinking: z.ZodOptional<z.ZodEnum<{
618
+ high: "high";
619
+ low: "low";
620
+ max: "max";
621
+ medium: "medium";
622
+ minimal: "minimal";
623
+ off: "off";
624
+ xhigh: "xhigh";
625
+ }>>;
626
+ max_turns: z.ZodOptional<z.ZodNumber>;
627
+ tools: z.ZodOptional<z.ZodString>;
628
+ skills: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodString]>>;
629
+ }, z.core.$strict>>>;
630
+ agents: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
631
+ thinking: z.ZodOptional<z.ZodEnum<{
632
+ high: "high";
633
+ low: "low";
634
+ max: "max";
635
+ medium: "medium";
636
+ minimal: "minimal";
637
+ off: "off";
638
+ xhigh: "xhigh";
639
+ }>>;
640
+ max_turns: z.ZodOptional<z.ZodNumber>;
641
+ tools: z.ZodOptional<z.ZodString>;
642
+ skills: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodString]>>;
643
+ }, z.core.$strict>>>;
644
+ }, z.core.$strict>>;
645
+ skills_as_commands: z.ZodDefault<z.ZodBoolean>;
646
+ }, z.core.$strict>;
647
+ /**
648
+ * Fully-typed shape of a parsed `SystematicConfigSchema` result, inferred
649
+ * directly from the schema's own field builders rather than hand-mirrored.
650
+ * A field added to `createSystematicConfigSchema`'s object shape is
651
+ * reflected here automatically — there is no separate declaration that can
652
+ * drift out of sync with the schema.
653
+ *
654
+ * That guarantee is strongest for fields that are required in the parsed
655
+ * output (no `.optional()`, or defaulted via `.default()`): a test that
656
+ * asserts a literal object against `z.infer<typeof SystematicConfigSchema>`
657
+ * (e.g. via `bun:test`'s `toEqual`) fails to typecheck if the literal omits
658
+ * one. An added `.optional()` field with no default — like `$schema` —
659
+ * drifts silently, since `undefined` satisfies both the type and an
660
+ * omitted key. Consumers reading nested fields for their own logic should
661
+ * still narrow/validate at the boundary rather than trust exhaustiveness —
662
+ * for the `categories` and `profiles` record fields (each
663
+ * `z.record(z.string(), ...)`), `noUncheckedIndexedAccess` in tsconfig.json
664
+ * now makes this compiler-enforced rather than a style convention: an index
665
+ * access like `parsed.categories[key]` types as `V | undefined`, so an
666
+ * unnarrowed read fails to typecheck instead of type-checking clean and
667
+ * throwing at runtime on a missing key.
668
+ */
669
+ export type SystematicConfigParsed = z.infer<typeof SystematicConfigSchema>;
247
670
  export type ValidationResult = {
248
671
  success: true;
249
- data: z.infer<typeof SystematicConfigSchema>;
672
+ data: SystematicConfigParsed;
250
673
  } | {
251
674
  success: false;
252
675
  errors: readonly z.ZodIssue[];
package/dist/pi.js CHANGED
@@ -3143,8 +3143,7 @@ function parseFrontmatter(content) {
3143
3143
  parseError: false
3144
3144
  };
3145
3145
  }
3146
- const yamlContent = match[1];
3147
- const body = match[2];
3146
+ const [, yamlContent = "", body = ""] = match;
3148
3147
  try {
3149
3148
  const parsed = yaml.load(yamlContent, { schema: yaml.JSON_SCHEMA });
3150
3149
  const data = parsed ?? {};
@@ -3525,6 +3524,7 @@ var BUNDLED_SKILL_NAMES = [
3525
3524
  "ce:ideate",
3526
3525
  "ce:plan",
3527
3526
  "ce:review",
3527
+ "ce:review-cleanup",
3528
3528
  "ce:work",
3529
3529
  "compound-docs",
3530
3530
  "deepen-plan",
@@ -9651,7 +9651,8 @@ function readOpencodeLayerField(agentOverlay, categoryOverlay, layer, field) {
9651
9651
  }
9652
9652
  function resolveOpencodeModelAndVariant(agentOverlay, categoryOverlay) {
9653
9653
  const modelLayerIndex = OPENCODE_MODEL_VARIANT_LAYERS.findIndex((layer) => readOpencodeLayerField(agentOverlay, categoryOverlay, layer, "model") !== undefined);
9654
- const rawModel = modelLayerIndex === -1 ? undefined : readOpencodeLayerField(agentOverlay, categoryOverlay, OPENCODE_MODEL_VARIANT_LAYERS[modelLayerIndex], "model");
9654
+ const modelLayer = modelLayerIndex === -1 ? undefined : OPENCODE_MODEL_VARIANT_LAYERS[modelLayerIndex];
9655
+ const rawModel = modelLayer === undefined ? undefined : readOpencodeLayerField(agentOverlay, categoryOverlay, modelLayer, "model");
9655
9656
  const model = narrowModelValue(rawModel);
9656
9657
  const hasModel = model !== undefined;
9657
9658
  const modelSource = hasModel ? OPENCODE_MODEL_VARIANT_LAYERS[modelLayerIndex] : undefined;
@@ -9659,8 +9660,7 @@ function resolveOpencodeModelAndVariant(agentOverlay, categoryOverlay) {
9659
9660
  let qualifierSource;
9660
9661
  if (model !== null) {
9661
9662
  const eligibleLayerCount = hasModel ? modelLayerIndex + 1 : OPENCODE_MODEL_VARIANT_LAYERS.length;
9662
- for (let i = 0;i < eligibleLayerCount; i++) {
9663
- const layer = OPENCODE_MODEL_VARIANT_LAYERS[i];
9663
+ for (const layer of OPENCODE_MODEL_VARIANT_LAYERS.slice(0, eligibleLayerCount)) {
9664
9664
  const narrowed = narrowQualifierValue(readOpencodeLayerField(agentOverlay, categoryOverlay, layer, "variant"));
9665
9665
  if (narrowed !== undefined) {
9666
9666
  qualifier = narrowed;
@@ -11024,7 +11024,8 @@ $ARGUMENTS
11024
11024
  }
11025
11025
  function extractSkillBody(wrappedTemplate) {
11026
11026
  const match = wrappedTemplate.match(/<skill-instruction>([\s\S]*?)<\/skill-instruction>/);
11027
- return match ? match[1].trim() : wrappedTemplate;
11027
+ const [, body] = match ?? [];
11028
+ return body !== undefined ? body.trim() : wrappedTemplate;
11028
11029
  }
11029
11030
  function loadSkill(skillInfo) {
11030
11031
  try {
@@ -1913,6 +1913,7 @@
1913
1913
  "ce:ideate",
1914
1914
  "ce:plan",
1915
1915
  "ce:review",
1916
+ "ce:review-cleanup",
1916
1917
  "ce:work",
1917
1918
  "compound-docs",
1918
1919
  "deepen-plan",