@fro.bot/systematic 3.0.1 → 3.0.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
@@ -29,7 +29,7 @@ You want AI that follows your process, not just your prompts. You want repeatabl
29
29
 
30
30
  ## What You Get
31
31
 
32
- Systematic is an [OpenCode](https://opencode.ai/) plugin that ships 40+ bundled skills covering brainstorming, planning, implementation, review, and knowledge capture. It includes 50+ specialized agents for architecture, security, performance, design, and code review. Installation is zero-configuration — the plugin registers everything via OpenCode's config hooks and works immediately on restart. OCX registry support is available for component-level installs when you only want specific pieces.
32
+ Systematic is an [OpenCode](https://opencode.ai/) plugin — and, from v3, a [Pi coding agent](https://github.com/earendil-works/pi-coding-agent) extension in the same package — that ships 31 bundled skills covering brainstorming, planning, implementation, review, and knowledge capture. It includes 37 specialized agents for architecture, security, performance, design, and code review. Installation is zero-configuration — the plugin registers everything via OpenCode's config hooks and works immediately on restart. OCX registry support is available for component-level installs when you only want specific pieces.
33
33
 
34
34
  ## Quick Install
35
35
 
@@ -41,13 +41,21 @@ Systematic is an [OpenCode](https://opencode.ai/) plugin that ships 40+ bundled
41
41
 
42
42
  Add that to `~/.config/opencode/opencode.json` and restart OpenCode.
43
43
 
44
+ **Pi coding agent** — same package, second harness (bundled skills, `systematic_skill`, persona delegation via `systematic_delegate`):
45
+
46
+ ```bash
47
+ npx @fro.bot/systematic setup --harness pi
48
+ ```
49
+
50
+ See the [Pi harness guide](https://fro.bot/systematic/guides/pi-harness/) for what carries over and where parity honestly ends.
51
+
44
52
  **`npx skills`** — portable skill content for any AI harness (Claude Code, Cursor, Copilot, …):
45
53
 
46
54
  ```bash
47
55
  npx skills add marcusrbrown/systematic
48
56
  ```
49
57
 
50
- Use the plugin if you're on OpenCode and want the complete experience. Use `npx skills` if you want the skill Markdown files dropped into whatever harness you're running.
58
+ Use the plugin if you're on OpenCode and want the complete experience, the Pi setup command if you're on Pi, or `npx skills` if you want the skill Markdown files dropped into whatever harness you're running.
51
59
 
52
60
  ## First Workflow
53
61
 
package/dist/cli.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  modify,
10
10
  parse,
11
11
  parseTree
12
- } from "./index-yskzf7vh.js";
12
+ } from "./index-6yz7bra8.js";
13
13
 
14
14
  // src/cli.ts
15
15
  import fs2 from "fs";
@@ -16074,6 +16074,9 @@ var REMOVED_BUNDLED_AGENT_NAMES = [
16074
16074
  "security-sentinel",
16075
16075
  "workflow/lint"
16076
16076
  ];
16077
+ var REMOVED_BUNDLED_AGENT_CATEGORIES = [
16078
+ "docs"
16079
+ ];
16077
16080
 
16078
16081
  // src/lib/config-schema.ts
16079
16082
  var permissionSettingSchema = exports_external.enum(["ask", "allow", "deny"]);
@@ -16296,16 +16299,19 @@ var CURRENT_AGENT_NAMES_SET = new Set([
16296
16299
  ...BUNDLED_AGENT_NAMES,
16297
16300
  ...BUNDLED_AGENT_QUALIFIED_IDS
16298
16301
  ]);
16302
+ var REMOVED_AGENT_CATEGORIES_SET = new Set(REMOVED_BUNDLED_AGENT_CATEGORIES);
16299
16303
  function computeDroppedNames(names, allowedSet) {
16300
16304
  return names.filter((n) => !allowedSet.has(n));
16301
16305
  }
16302
16306
  var MIGRATION_DOCS_URL = "https://fro.bot/systematic/guides/v3-migration/";
16303
- function warnDroppedNames(dropped, field, warned) {
16307
+ function warnDroppedNames(dropped, field, warned, removalVersion) {
16304
16308
  for (const name of dropped) {
16305
16309
  if (warned.has(name))
16306
16310
  continue;
16307
16311
  warned.add(name);
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.`);
16312
+ const displayName = field === "categories" ? `${field}.${name}` : name;
16313
+ const removalNote = removalVersion ? ` It was removed in ${removalVersion}.` : "";
16314
+ console.warn(`[systematic] "${displayName}" in \`${field}\` is no longer a bundled name and will be ignored.${removalNote} Remove it from your config to silence this warning. See ${MIGRATION_DOCS_URL} for migration guidance.`);
16309
16315
  }
16310
16316
  }
16311
16317
  function resolveConfigPath(dir, basename) {
@@ -16443,7 +16449,15 @@ function loadConfigWithSources(projectDir) {
16443
16449
  const projectSource = loadConfigSource(paths.projectConfig, "project");
16444
16450
  const customSource = paths.customConfig ? loadConfigSource(paths.customConfig, "custom") : null;
16445
16451
  const sources = [userSource, projectSource, customSource].filter((source) => source !== null);
16446
- const overlays = mergeOverlaySources(sources);
16452
+ const mergedOverlays = mergeOverlaySources(sources);
16453
+ const droppedCategories = Object.keys(mergedOverlays.categories).filter((name) => REMOVED_AGENT_CATEGORIES_SET.has(name));
16454
+ const warned = new Set;
16455
+ warnDroppedNames(droppedCategories, "categories", warned, "v3.0.0");
16456
+ const droppedCategorySet = new Set(droppedCategories);
16457
+ const overlays = droppedCategorySet.size === 0 ? mergedOverlays : {
16458
+ ...mergedOverlays,
16459
+ categories: Object.fromEntries(Object.entries(mergedOverlays.categories).filter(([key]) => !droppedCategorySet.has(key)))
16460
+ };
16447
16461
  const userConfig = userSource?.config;
16448
16462
  const projectConfig = projectSource?.config;
16449
16463
  const customConfig = customSource?.config;
@@ -16461,7 +16475,6 @@ function loadConfigWithSources(projectDir) {
16461
16475
  categories: overlayValues(overlays.categories),
16462
16476
  skills_as_commands: customConfig?.skills_as_commands ?? projectConfig?.skills_as_commands ?? userConfig?.skills_as_commands ?? DEFAULT_CONFIG.skills_as_commands
16463
16477
  };
16464
- const warned = new Set;
16465
16478
  const droppedSkills = computeDroppedNames(result.disabled_skills, CURRENT_SKILL_NAMES_SET);
16466
16479
  warnDroppedNames(droppedSkills, "disabled_skills", warned);
16467
16480
  const droppedAgents = computeDroppedNames(result.disabled_agents, CURRENT_AGENT_NAMES_SET);
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ import {
14
14
  loadConfigWithSources,
15
15
  parseFrontmatter,
16
16
  walkDir
17
- } from "./index-yskzf7vh.js";
17
+ } from "./index-6yz7bra8.js";
18
18
 
19
19
  // src/index.ts
20
20
  import fs8 from "fs";
@@ -1283,9 +1283,6 @@ function normalizePath(path8) {
1283
1283
  return path8.replaceAll("\\", "/").replace(/\/+$/u, "");
1284
1284
  }
1285
1285
 
1286
- // src/lib/skill-tool.ts
1287
- import { tool } from "@opencode-ai/plugin/tool";
1288
-
1289
1286
  // src/lib/skill-resolver.ts
1290
1287
  import fs7 from "fs";
1291
1288
  import path8 from "path";
@@ -1384,7 +1381,7 @@ function createSkillTool(options) {
1384
1381
  const buildParameterHint = () => buildSkillToolParameterHint({ bundledSkillsDir, disabledSkills });
1385
1382
  let cachedDescription = null;
1386
1383
  let cachedParameterHint = null;
1387
- return tool({
1384
+ return {
1388
1385
  get description() {
1389
1386
  if (cachedDescription == null) {
1390
1387
  cachedDescription = buildDescription();
@@ -1392,7 +1389,7 @@ function createSkillTool(options) {
1392
1389
  return cachedDescription;
1393
1390
  },
1394
1391
  args: {
1395
- name: tool.schema.string().describe((() => {
1392
+ name: exports_external.string().describe((() => {
1396
1393
  if (cachedParameterHint == null) {
1397
1394
  cachedParameterHint = buildParameterHint();
1398
1395
  }
@@ -1418,7 +1415,7 @@ function createSkillTool(options) {
1418
1415
  });
1419
1416
  return output;
1420
1417
  }
1421
- });
1418
+ };
1422
1419
  }
1423
1420
 
1424
1421
  // src/index.ts
@@ -40,7 +40,7 @@ export declare function computeDroppedNames(names: readonly string[], allowedSet
40
40
  * single load call -- callers must NOT share it across independent loads.
41
41
  * Passing a fresh set per load ensures no cross-load suppression.
42
42
  */
43
- export declare function warnDroppedNames(dropped: string[], field: string, warned: Set<string>): void;
43
+ export declare function warnDroppedNames(dropped: string[], field: string, warned: Set<string>, removalVersion?: string): void;
44
44
  export declare function loadConfig(projectDir: string): SystematicConfig;
45
45
  export declare function loadConfigWithSources(projectDir: string): SourceAwareConfigResult;
46
46
  export declare function getConfigPaths(projectDir: string): {
@@ -13,3 +13,4 @@
13
13
  */
14
14
  export declare const REMOVED_BUNDLED_SKILL_NAMES: readonly string[];
15
15
  export declare const REMOVED_BUNDLED_AGENT_NAMES: readonly string[];
16
+ export declare const REMOVED_BUNDLED_AGENT_CATEGORIES: readonly string[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fro.bot/systematic",
3
- "version": "3.0.1",
3
+ "version": "3.0.3",
4
4
  "description": "Structured engineering workflows for OpenCode",
5
5
  "type": "module",
6
6
  "homepage": "https://fro.bot/systematic",