@fro.bot/systematic 2.12.1 → 2.12.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/README.md CHANGED
@@ -338,7 +338,7 @@ Systematic separates config-source precedence from overlay precedence. Config fi
338
338
 
339
339
  Source category model defaults are primary model choices only — they are not fallback chains. Systematic does not support `fallback_models`, inherited retry semantics, runtime fallback behavior, or fallback to the parent model when a source model is unavailable. Explicit and source model IDs are structurally validated and may still fail at OpenCode runtime if the provider or model is unavailable.
340
340
 
341
- Source category model defaults are now ordered preference arrays per category rather than single strings. At plugin load, Systematic reads OpenCode's authentication state from `auth.json` and selects the first array entry whose provider is authenticated. For example, the `review` category defaults to `['anthropic/claude-opus-4.7', 'openai/gpt-5.5']` — a user authenticated only to OpenAI receives `openai/gpt-5.5` (first match), while a user authenticated to Anthropic (or both) receives the more preferred `anthropic/claude-opus-4.7`. If no array entry's provider is authenticated, the first entry is used as the default. The arrays are an ordered preference list, not a runtime fallback chain — `fallback_models` is still not supported.
341
+ Source category model defaults are now ordered preference arrays per category rather than single strings. At plugin load, Systematic reads OpenCode's authentication state from `auth.json` and selects the first array entry whose provider is authenticated. For example, the `review` category defaults to `['anthropic/claude-sonnet-4-6', 'openai/gpt-5.3-codex']` — a user authenticated only to OpenAI receives `openai/gpt-5.5` (first match), while a user authenticated to Anthropic (or both) receives the more preferred `anthropic/claude-sonnet-4-6`. If no array entry's provider is authenticated, the first entry is used as the default. The arrays are an ordered preference list, not a runtime fallback chain — `fallback_models` is still not supported.
342
342
 
343
343
  If you want to restore OpenCode parent-model inheritance for a bundled agent or category (opting out of the source default), set `"model": null` in high-trust user or `$OPENCODE_CONFIG_DIR/systematic.json` config. Project config cannot use `model: null` — project config cannot set, erase, or shadow `model` at any value.
344
344
 
@@ -346,11 +346,11 @@ The source defaults are:
346
346
 
347
347
  | Category | Default `model` | Rationale |
348
348
  |----------|-----------------|-----------|
349
- | `design` | `openai/gpt-5.5` | High-judgment UX/product/design work benefits from a strong general reasoning model. |
350
- | `docs` | `openai/gpt-5.4-mini` | Documentation and summarization should start cheaper/faster. |
351
- | `document-review` | `anthropic/claude-opus-4.7` | Requirements and plan critique benefit from strongest nuanced reasoning. |
352
- | `research` | `openai/gpt-5.5` | Tool-heavy synthesis and source evaluation benefit from a strong general reasoning model. |
353
- | `review` | `anthropic/claude-opus-4.7` | Code/security/adversarial review benefits from strongest reasoning. |
349
+ | `design` | `github-copilot/gemini-3.1-pro-preview` | High-judgment UX/product/design work benefits from a strong general reasoning model. |
350
+ | `docs` | `github-copilot/gemini-3.1-pro-preview` | Documentation and summarization should start cheaper/faster. |
351
+ | `document-review` | `anthropic/claude-opus-4-7` | Requirements and plan critique benefit from strongest nuanced reasoning. |
352
+ | `research` | `openai/gpt-5.4-mini` | Tool-heavy synthesis and source evaluation benefit from a strong general reasoning model. |
353
+ | `review` | `anthropic/claude-sonnet-4-6` | Code/security/adversarial review benefits from strongest reasoning. |
354
354
  | `workflow` | `openai/gpt-5.4-mini` | Orchestration and bounded implementation should default cheaper/faster. |
355
355
 
356
356
  These defaults are owned by Systematic code and emitted for bundled agents in each category when no stronger high-trust exact or category `model` override exists. Uncategorized bundled agents receive no source default and continue inheriting the parent OpenCode model. Native OpenCode agents with the same emitted key are full replacements and receive no Systematic source model default.
package/dist/cli.js CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  findCommandsInDir,
7
7
  findSkillsInDir,
8
8
  getConfigPaths
9
- } from "./index-b4ht76qd.js";
9
+ } from "./index-gb1v2n3m.js";
10
10
 
11
11
  // src/cli.ts
12
12
  import fs from "fs";
@@ -15224,7 +15224,7 @@ var AgentOverlaySchema = exports_external.object({
15224
15224
  description: "Per-agent configuration overlay",
15225
15225
  examples: [
15226
15226
  {
15227
- model: "anthropic/claude-opus-4.7",
15227
+ model: "anthropic/claude-opus-4-7",
15228
15228
  temperature: 0.1,
15229
15229
  mode: "subagent"
15230
15230
  }
@@ -15243,7 +15243,7 @@ var CategoryOverlaySchema = exports_external.object({
15243
15243
  permission: trustProtected(permissionSchema).optional()
15244
15244
  }).strict().meta({
15245
15245
  description: "Per-category configuration overlay (same fields as agent minus disable)",
15246
- examples: [{ model: "anthropic/claude-opus-4.7", temperature: 0.1 }]
15246
+ examples: [{ model: "anthropic/claude-opus-4-7", temperature: 0.1 }]
15247
15247
  });
15248
15248
  var BootstrapSchema = exports_external.object({
15249
15249
  enabled: exports_external.boolean().default(true).meta({
@@ -15271,7 +15271,7 @@ var SystematicConfigSchema = exports_external.object({
15271
15271
  }),
15272
15272
  categories: exports_external.record(exports_external.string(), CategoryOverlaySchema).default({}).meta({
15273
15273
  description: "Per-category configuration overlays keyed by category name",
15274
- examples: [{ review: { model: "anthropic/claude-opus-4.7" } }, {}]
15274
+ examples: [{ review: { model: "anthropic/claude-opus-4-7" } }, {}]
15275
15275
  }),
15276
15276
  disabled_skills: exports_external.array(exports_external.string()).default([]).meta({
15277
15277
  description: "Array of skill names to disable globally",
@@ -15298,7 +15298,7 @@ var SystematicConfigSchema = exports_external.object({
15298
15298
  });
15299
15299
  var SourceCategoryModelDefaultsSchema = exports_external.record(exports_external.string(), exports_external.array(exports_external.string().min(1).regex(MODEL_FORMAT_REGEX, MODEL_FORMAT_MESSAGE)).min(1)).meta({
15300
15300
  description: "Validates source category model defaults shape",
15301
- examples: [{ design: ["openai/gpt-5.5", "anthropic/claude-opus-4.7"] }]
15301
+ examples: [{ design: ["openai/gpt-5.5", "anthropic/claude-opus-4-7"] }]
15302
15302
  });
15303
15303
  function assertSourceCategoryModelDefaults(defaults) {
15304
15304
  SourceCategoryModelDefaultsSchema.parse(defaults);
package/dist/index.d.ts CHANGED
@@ -1,6 +1,3 @@
1
1
  import type { Plugin } from '@opencode-ai/plugin';
2
- export declare const applyBootstrapContent: (output: {
3
- system: string[];
4
- }, content: string) => void;
5
2
  declare const SystematicPlugin: Plugin;
6
3
  export default SystematicPlugin;
package/dist/index.js CHANGED
@@ -13,7 +13,7 @@ import {
13
13
  loadConfig,
14
14
  loadConfigWithSources,
15
15
  parseFrontmatter
16
- } from "./index-b4ht76qd.js";
16
+ } from "./index-gb1v2n3m.js";
17
17
 
18
18
  // src/index.ts
19
19
  import fs4 from "fs";
@@ -29,6 +29,34 @@ var INTERNAL_AGENT_SIGNATURES = [
29
29
  "You are a helpful AI assistant tasked with summarizing conversations",
30
30
  "Summarize what was done in this conversation"
31
31
  ];
32
+ var BOOTSTRAP_MARKER_OPEN = "<SYSTEMATIC_WORKFLOWS>";
33
+ var BOOTSTRAP_MARKER_CLOSE = "</SYSTEMATIC_WORKFLOWS>";
34
+ var findBootstrapMarkerBlock = (entry) => {
35
+ const start = entry.indexOf(BOOTSTRAP_MARKER_OPEN);
36
+ if (start === -1)
37
+ return null;
38
+ const closeStart = entry.indexOf(BOOTSTRAP_MARKER_CLOSE, start + BOOTSTRAP_MARKER_OPEN.length);
39
+ if (closeStart === -1)
40
+ return null;
41
+ return { start, end: closeStart + BOOTSTRAP_MARKER_CLOSE.length };
42
+ };
43
+ var applyBootstrapContent = (output, content) => {
44
+ for (let i = 0;i < output.system.length; i++) {
45
+ const entry = output.system[i];
46
+ const block = findBootstrapMarkerBlock(entry);
47
+ if (block !== null) {
48
+ output.system[i] = entry.slice(0, block.start) + content + entry.slice(block.end);
49
+ return;
50
+ }
51
+ }
52
+ if (output.system.length > 0) {
53
+ output.system[output.system.length - 1] += `
54
+
55
+ ${content}`;
56
+ } else {
57
+ output.system.push(content);
58
+ }
59
+ };
32
60
  function getToolMappingTemplate() {
33
61
  return `**Tool Mapping for OpenCode:**
34
62
  When skills reference tools you don't have, substitute OpenCode equivalents:
@@ -82,12 +110,20 @@ import fs2 from "fs";
82
110
  import os2 from "os";
83
111
  import path2 from "path";
84
112
  var SOURCE_CATEGORY_MODEL_DEFAULTS = {
85
- design: ["openai/gpt-5.5", "anthropic/claude-opus-4.7"],
86
- docs: ["openai/gpt-5.4-mini", "anthropic/claude-haiku-4-5"],
87
- "document-review": ["anthropic/claude-opus-4.7", "openai/gpt-5.5"],
88
- research: ["openai/gpt-5.5", "anthropic/claude-opus-4.7"],
89
- review: ["anthropic/claude-opus-4.7", "openai/gpt-5.5"],
90
- workflow: ["openai/gpt-5.4-mini", "anthropic/claude-haiku-4-5"]
113
+ design: [
114
+ "github-copilot/gemini-3.1-pro-preview",
115
+ "openai/gpt-5.5",
116
+ "anthropic/claude-opus-4-7"
117
+ ],
118
+ docs: [
119
+ "github-copilot/gemini-3.1-pro-preview",
120
+ "openai/gpt-5.4-mini",
121
+ "anthropic/claude-haiku-4-5"
122
+ ],
123
+ "document-review": ["anthropic/claude-sonnet-4-6", "openai/gpt-5.4-mini"],
124
+ research: ["openai/gpt-5.4-mini", "anthropic/claude-sonnet-4-6"],
125
+ review: ["anthropic/claude-sonnet-4-6", "openai/gpt-5.3-codex"],
126
+ workflow: ["openai/gpt-5.4-mini", "anthropic/claude-sonnet-4-6"]
91
127
  };
92
128
  function buildBundledAgentInventory(agentsDir, disabledAgents) {
93
129
  const categories = readCategoryDirs(agentsDir);
@@ -848,34 +884,6 @@ var bundledSkillsDir = path5.join(packageRoot, "skills");
848
884
  var bundledAgentsDir = path5.join(packageRoot, "agents");
849
885
  var bundledCommandsDir = path5.join(packageRoot, "commands");
850
886
  var packageJsonPath = path5.join(packageRoot, "package.json");
851
- var BOOTSTRAP_MARKER_OPEN = "<SYSTEMATIC_WORKFLOWS>";
852
- var BOOTSTRAP_MARKER_CLOSE = "</SYSTEMATIC_WORKFLOWS>";
853
- var findBootstrapMarkerBlock = (entry) => {
854
- const start = entry.indexOf(BOOTSTRAP_MARKER_OPEN);
855
- if (start === -1)
856
- return null;
857
- const closeStart = entry.indexOf(BOOTSTRAP_MARKER_CLOSE, start + BOOTSTRAP_MARKER_OPEN.length);
858
- if (closeStart === -1)
859
- return null;
860
- return { start, end: closeStart + BOOTSTRAP_MARKER_CLOSE.length };
861
- };
862
- var applyBootstrapContent = (output, content) => {
863
- for (let i = 0;i < output.system.length; i++) {
864
- const entry = output.system[i];
865
- const block = findBootstrapMarkerBlock(entry);
866
- if (block !== null) {
867
- output.system[i] = entry.slice(0, block.start) + content + entry.slice(block.end);
868
- return;
869
- }
870
- }
871
- if (output.system.length > 0) {
872
- output.system[output.system.length - 1] += `
873
-
874
- ${content}`;
875
- } else {
876
- output.system.push(content);
877
- }
878
- };
879
887
  var getPackageVersion = () => {
880
888
  try {
881
889
  if (!fs4.existsSync(packageJsonPath))
@@ -951,6 +959,5 @@ var SystematicPlugin = async (input) => {
951
959
  };
952
960
  var src_default = SystematicPlugin;
953
961
  export {
954
- src_default as default,
955
- applyBootstrapContent
962
+ src_default as default
956
963
  };
@@ -1,5 +1,18 @@
1
1
  import type { SystematicConfig } from './config.js';
2
2
  export declare const INTERNAL_AGENT_SIGNATURES: string[];
3
+ /**
4
+ * Inject bootstrap content into the system prompt array, replacing any
5
+ * existing `<SYSTEMATIC_WORKFLOWS>` block. Multi-load idempotency is via
6
+ * the marker — most-recently-registered plugin wins under FIFO hook order.
7
+ *
8
+ * Exported for test access — must NOT be re-exported from the plugin entry
9
+ * point (src/index.ts) because OpenCode's plugin loader expects a single
10
+ * function export; additional named exports break loading. See
11
+ * `docs/solutions/integration-issues/` for the v2.5.0 and v2.12.1 incidents.
12
+ */
13
+ export declare const applyBootstrapContent: (output: {
14
+ system: string[];
15
+ }, content: string) => void;
3
16
  export interface BootstrapDeps {
4
17
  bundledSkillsDir: string;
5
18
  }
@@ -161,7 +161,7 @@
161
161
  "description": "Per-agent configuration overlay",
162
162
  "examples": [
163
163
  {
164
- "model": "anthropic/claude-opus-4.7",
164
+ "model": "anthropic/claude-opus-4-7",
165
165
  "temperature": 0.1,
166
166
  "mode": "subagent"
167
167
  }
@@ -174,7 +174,7 @@
174
174
  "examples": [
175
175
  {
176
176
  "review": {
177
- "model": "anthropic/claude-opus-4.7"
177
+ "model": "anthropic/claude-opus-4-7"
178
178
  }
179
179
  },
180
180
  {}
@@ -314,7 +314,7 @@
314
314
  "description": "Per-category configuration overlay (same fields as agent minus disable)",
315
315
  "examples": [
316
316
  {
317
- "model": "anthropic/claude-opus-4.7",
317
+ "model": "anthropic/claude-opus-4-7",
318
318
  "temperature": 0.1
319
319
  }
320
320
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fro.bot/systematic",
3
- "version": "2.12.1",
3
+ "version": "2.12.3",
4
4
  "description": "Structured engineering workflows for OpenCode",
5
5
  "type": "module",
6
6
  "homepage": "https://fro.bot/systematic",
@@ -69,8 +69,8 @@
69
69
  "@types/bun": "latest",
70
70
  "@types/js-yaml": "4.0.9",
71
71
  "@types/node": "24.12.3",
72
- "ajv": "^8.20.0",
73
- "ajv-formats": "^3.0.1",
72
+ "ajv": "8.20.0",
73
+ "ajv-formats": "3.0.1",
74
74
  "conventional-changelog-conventionalcommits": "9.3.1",
75
75
  "markdownlint-cli": "0.48.0",
76
76
  "rimraf": "6.1.3",