@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 +10 -2
- package/dist/cli.js +1 -1
- package/dist/{index-yskzf7vh.js → index-6yz7bra8.js} +17 -4
- package/dist/index.js +4 -7
- package/dist/lib/config.d.ts +1 -1
- package/dist/lib/removed-names.d.ts +1 -0
- package/package.json +1 -1
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
|
|
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
|
|
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
|
@@ -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
|
-
|
|
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
|
|
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-
|
|
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
|
|
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:
|
|
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
|
package/dist/lib/config.d.ts
CHANGED
|
@@ -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
|
|
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): {
|