@fro.bot/systematic 2.14.2 → 2.14.3

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/index.js CHANGED
@@ -767,9 +767,13 @@ async function getAvailableModels(client, options = {}) {
767
767
  if (response.error !== undefined || response.data === undefined) {
768
768
  return readFallbackCache();
769
769
  }
770
+ const models = buildSetFromProviders(response.data.providers);
771
+ if (models.size === 0) {
772
+ return emptyAvailability();
773
+ }
770
774
  return {
771
775
  status: "api",
772
- models: buildSetFromProviders(response.data.providers)
776
+ models
773
777
  };
774
778
  }
775
779
 
@@ -1088,6 +1092,8 @@ function createConfigHandler(deps) {
1088
1092
  const bundledSkills = collectSkillsAsCommands(bundledSkillsDir, systematicConfig.disabled_skills);
1089
1093
  const enabledSkillNames = collectEnabledSkillNames(bundledSkillsDir, systematicConfig.disabled_skills);
1090
1094
  const inventory = buildBundledAgentInventory(bundledAgentsDir2, systematicConfig.disabled_agents);
1095
+ const availability = deps.client ? await getAvailableModels(deps.client) : undefined;
1096
+ const availabilitySet = availability && availability.status !== "unknown" ? availability.models : undefined;
1091
1097
  assertSourceCategoryModelCoverage(inventory.categories);
1092
1098
  const validatedOverlays = validateAgentOverlays({
1093
1099
  inventory,
@@ -1096,8 +1102,6 @@ function createConfigHandler(deps) {
1096
1102
  enabledSkills: enabledSkillNames
1097
1103
  });
1098
1104
  const resolvedOverlays = resolveAgentOverlaySet(validatedOverlays);
1099
- const availability = deps.client ? await getAvailableModels(deps.client) : undefined;
1100
- const availabilitySet = availability && availability.status !== "unknown" ? availability.models : undefined;
1101
1105
  const bundledAgents = collectAgents(bundledAgentsDir2, systematicConfig.disabled_agents, nativeAgents, resolvedOverlays, availabilitySet);
1102
1106
  const bundledCommands = collectCommands(bundledCommandsDir, systematicConfig.disabled_commands);
1103
1107
  const bundledAgentKeys = new Set(Object.keys(bundledAgents));
@@ -22,16 +22,22 @@ export interface OpencodeClientLike {
22
22
  * Outcome of model availability discovery.
23
23
  *
24
24
  * - `api`: The OpenCode server's `/config/providers` endpoint responded with
25
- * a connected-providers payload. `models` may be empty if no providers
26
- * are authenticated; that is authoritative.
25
+ * a connected-providers payload AND `models` is non-empty. An authoritatively
26
+ * empty response (`data.providers = []`, or providers present with zero
27
+ * models) collapses to `'unknown'` instead — see below — because the
28
+ * operational consequence is identical and downstream consumers should treat
29
+ * both cases the same way.
27
30
  * - `cache`: The API call failed (error envelope, thrown, or timed out) and
28
31
  * the local `models.json` cache was readable. `models` reflects whatever
29
- * OpenCode last wrote to disk.
30
- * - `unknown`: Both the API call and the cache fallback failed (cache
31
- * missing, unreadable, corrupt, or schema-mismatched). Resolution should
32
- * degrade gracefully callers should treat `unknown` as a signal to
33
- * skip source-default model pinning so users do not get agents pinned
34
- * to inaccessible models. `models` is the empty set.
32
+ * OpenCode last wrote to disk. The cache may itself be empty; callers that
33
+ * need to distinguish "cached empty" from "cached with content" should
34
+ * inspect `models.size`.
35
+ * - `unknown`: Either both the API call and the cache fallback failed (cache
36
+ * missing, unreadable, corrupt, or schema-mismatched), OR the API call
37
+ * succeeded with zero usable models. Resolution should degrade gracefully
38
+ * callers should treat `unknown` as a signal to skip source-default model
39
+ * pinning so users do not get agents pinned to inaccessible models.
40
+ * `models` is the empty set.
35
41
  */
36
42
  export type DiscoveryStatus = 'api' | 'cache' | 'unknown';
37
43
  export interface ModelAvailability {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fro.bot/systematic",
3
- "version": "2.14.2",
3
+ "version": "2.14.3",
4
4
  "description": "Structured engineering workflows for OpenCode",
5
5
  "type": "module",
6
6
  "homepage": "https://fro.bot/systematic",
@@ -68,7 +68,7 @@
68
68
  "@opencode-ai/sdk": "1.14.48",
69
69
  "@types/bun": "latest",
70
70
  "@types/js-yaml": "4.0.9",
71
- "@types/node": "24.12.3",
71
+ "@types/node": "24.12.4",
72
72
  "ajv": "8.20.0",
73
73
  "ajv-formats": "3.0.1",
74
74
  "conventional-changelog-conventionalcommits": "9.3.1",