@fro.bot/systematic 2.15.0 → 2.16.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
@@ -6,7 +6,7 @@ import {
6
6
  findCommandsInDir,
7
7
  findSkillsInDir,
8
8
  getConfigPaths
9
- } from "./index-6xnehr4s.js";
9
+ } from "./index-s0d2z9ph.js";
10
10
 
11
11
  // src/cli.ts
12
12
  import fs from "fs";
@@ -16064,21 +16064,55 @@ var TYPED_KEY_FIELDS = new Set([
16064
16064
  "disabled_agents",
16065
16065
  "disabled_skills"
16066
16066
  ]);
16067
- function enrichUnrecognizedKeyIssues(issues) {
16067
+ function formatUnrecognizedKeysHint(badKeys, topField) {
16068
+ if (badKeys.length === 0) {
16069
+ throw new Error("formatUnrecognizedKeysHint requires non-empty keys");
16070
+ }
16071
+ if (badKeys.length === 1) {
16072
+ return `Unrecognized key '${badKeys[0]}' in \`${topField}\`. This must be a bundled name. See ${TYPED_VALIDATION_DOCS_URL} for the full list of valid names.`;
16073
+ }
16074
+ const joined = badKeys.map((k) => `'${k}'`).join(", ");
16075
+ return `Unrecognized keys ${joined} in \`${topField}\`. These must be bundled names. See ${TYPED_VALIDATION_DOCS_URL} for the full list of valid names.`;
16076
+ }
16077
+ function enrichUnrecognizedKeyIssues(issues, rawInput) {
16068
16078
  return issues.map((issue2) => {
16069
- if (issue2.code !== "unrecognized_keys")
16070
- return issue2;
16071
16079
  const topField = issue2.path[0];
16072
16080
  if (typeof topField !== "string" || !TYPED_KEY_FIELDS.has(topField)) {
16073
16081
  return issue2;
16074
16082
  }
16075
- const badKey = issue2.message.match(/"([^"]+)"/)?.[1] ?? "";
16076
- const hint = badKey ? `Unrecognized key '${badKey}' in \`${topField}\`. This must be a bundled name. See ${TYPED_VALIDATION_DOCS_URL} for the full list of valid names.` : `${issue2.message} See ${TYPED_VALIDATION_DOCS_URL} for the full list of valid names.`;
16077
- return { ...issue2, message: hint };
16083
+ if (issue2.code === "unrecognized_keys") {
16084
+ const hint = formatUnrecognizedKeysHint(issue2.keys, topField);
16085
+ return { ...issue2, message: hint };
16086
+ }
16087
+ if (issue2.code === "invalid_value" && (topField === "disabled_agents" || topField === "disabled_skills")) {
16088
+ const badValue = resolveValueAtPath(rawInput, issue2.path);
16089
+ const kind = topField === "disabled_agents" ? "agent" : "skill";
16090
+ const hint = typeof badValue === "string" ? `Unrecognized ${kind} name '${badValue}' in \`${topField}\`. This must be a bundled name. See ${TYPED_VALIDATION_DOCS_URL} for the full list of valid names.` : `Invalid value in \`${topField}\`. See ${TYPED_VALIDATION_DOCS_URL} for the full list of valid names.`;
16091
+ return { ...issue2, message: hint };
16092
+ }
16093
+ return issue2;
16078
16094
  });
16079
16095
  }
16080
- function throwTopLevelConfigSchemaError(filePath, trust, rawIssues) {
16081
- const issues = enrichUnrecognizedKeyIssues(rawIssues);
16096
+ function resolveValueAtPath(root, path4) {
16097
+ let current = root;
16098
+ for (const segment of path4) {
16099
+ if (typeof segment === "symbol") {
16100
+ return;
16101
+ }
16102
+ if (typeof segment === "number") {
16103
+ if (!Array.isArray(current))
16104
+ return;
16105
+ current = current[segment];
16106
+ } else {
16107
+ if (!isRecord2(current))
16108
+ return;
16109
+ current = current[segment];
16110
+ }
16111
+ }
16112
+ return current;
16113
+ }
16114
+ function throwTopLevelConfigSchemaError(filePath, trust, rawIssues, rawInput) {
16115
+ const issues = enrichUnrecognizedKeyIssues(rawIssues, rawInput);
16082
16116
  const issue2 = issues[0];
16083
16117
  if (!issue2) {
16084
16118
  throw Object.assign(new Error(`Invalid Systematic config in ${filePath}: schema validation failed`), { _tag: "ConfigSchemaError", filePath, trust, issues });
@@ -16098,7 +16132,7 @@ function loadConfigSource(filePath, trust) {
16098
16132
  return null;
16099
16133
  const result = SystematicConfigSchema.safeParse(rawConfig);
16100
16134
  if (!result.success) {
16101
- throwTopLevelConfigSchemaError(filePath, trust, result.error.issues);
16135
+ throwTopLevelConfigSchemaError(filePath, trust, result.error.issues, rawConfig);
16102
16136
  }
16103
16137
  return { path: filePath, config: rawConfig, trust };
16104
16138
  }
package/dist/index.js CHANGED
@@ -13,7 +13,7 @@ import {
13
13
  loadConfig,
14
14
  loadConfigWithSources,
15
15
  parseFrontmatter
16
- } from "./index-6xnehr4s.js";
16
+ } from "./index-s0d2z9ph.js";
17
17
 
18
18
  // src/index.ts
19
19
  import fs5 from "fs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fro.bot/systematic",
3
- "version": "2.15.0",
3
+ "version": "2.16.0",
4
4
  "description": "Structured engineering workflows for OpenCode",
5
5
  "type": "module",
6
6
  "homepage": "https://fro.bot/systematic",
@@ -64,8 +64,8 @@
64
64
  },
65
65
  "devDependencies": {
66
66
  "@biomejs/biome": "2.4.15",
67
- "@opencode-ai/plugin": "1.14.48",
68
- "@opencode-ai/sdk": "1.14.48",
67
+ "@opencode-ai/plugin": "1.14.49",
68
+ "@opencode-ai/sdk": "1.14.49",
69
69
  "@types/bun": "latest",
70
70
  "@types/js-yaml": "4.0.9",
71
71
  "@types/node": "24.12.4",