@fro.bot/systematic 2.9.1 → 2.9.2

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.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: design-iterator
3
3
  description: "Iteratively refines UI design through N screenshot-analyze-improve cycles. Use PROACTIVELY when design changes aren't coming together after 1-2 attempts, or when user requests iterative refinement."
4
- color: violet
4
+ color: accent
5
5
  ---
6
6
 
7
7
  You are an expert UI/UX design iterator specializing in systematic, progressive refinement of web components. Your methodology combines visual analysis, competitor research, and incremental improvements to transform ordinary interfaces into polished, professional designs.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: figma-design-sync
3
3
  description: "Detects and fixes visual differences between a web implementation and its Figma design. Use iteratively when syncing implementation to match Figma specs."
4
- color: purple
4
+ color: accent
5
5
  ---
6
6
 
7
7
  You are an expert design-to-code synchronization specialist with deep expertise in visual design systems, web development, CSS/Tailwind styling, and automated quality assurance. Your mission is to ensure pixel-perfect alignment between Figma designs and their web implementations through systematic comparison, detailed analysis, and precise code adjustments.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: ankane-readme-writer
3
3
  description: "Creates or updates README files following Ankane-style template for Ruby gems. Use when writing gem documentation with imperative voice, concise prose, and standard section ordering."
4
- color: cyan
4
+ color: info
5
5
  ---
6
6
 
7
7
  You are an expert Ruby gem documentation writer specializing in the Ankane-style README format. You have deep knowledge of Ruby ecosystem conventions and excel at creating clear, concise documentation that follows Andrew Kane's proven template structure.
@@ -2,7 +2,7 @@
2
2
  name: adversarial-reviewer
3
3
  description: Conditional code-review persona, selected when the diff is large (>=50 changed lines) or touches high-risk domains like auth, payments, data mutations, or external APIs. Actively constructs failure scenarios to break the implementation rather than checking against known patterns.
4
4
  tools: Read, Grep, Glob, Bash
5
- color: red
5
+ color: error
6
6
 
7
7
  ---
8
8
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: agent-native-reviewer
3
3
  description: "Reviews code to ensure agent-native parity -- any action a user can take, an agent can also take. Use after adding UI features, agent tools, or system prompts."
4
- color: cyan
4
+ color: info
5
5
  tools: Read, Grep, Glob, Bash
6
6
  ---
7
7
 
@@ -2,7 +2,7 @@
2
2
  name: api-contract-reviewer
3
3
  description: Conditional code-review persona, selected when the diff touches API routes, request/response types, serialization, versioning, or exported type signatures. Reviews code for breaking contract changes.
4
4
  tools: Read, Grep, Glob, Bash
5
- color: blue
5
+ color: info
6
6
  mode: subagent
7
7
  temperature: 0.1
8
8
  ---
@@ -2,7 +2,7 @@
2
2
  name: cli-agent-readiness-reviewer
3
3
  description: "Reviews CLI source code, plans, or specs for AI agent readiness using a severity-based rubric focused on whether a CLI is merely usable by agents or genuinely optimized for them."
4
4
  tools: Read, Grep, Glob, Bash
5
- color: yellow
5
+ color: warning
6
6
  ---
7
7
 
8
8
  # CLI Agent-Readiness Reviewer
@@ -2,7 +2,7 @@
2
2
  name: cli-readiness-reviewer
3
3
  description: "Conditional code-review persona, selected when the diff touches CLI command definitions, argument parsing, or command handler implementations. Reviews CLI code for agent readiness -- how well the CLI serves autonomous agents, not just human users."
4
4
  tools: Read, Grep, Glob, Bash
5
- color: blue
5
+ color: info
6
6
  ---
7
7
 
8
8
  # CLI Agent-Readiness Reviewer
@@ -2,7 +2,7 @@
2
2
  name: correctness-reviewer
3
3
  description: Always-on code-review persona. Reviews code for logic errors, edge cases, state management bugs, error propagation failures, and intent-vs-implementation mismatches.
4
4
  tools: Read, Grep, Glob, Bash
5
- color: blue
5
+ color: info
6
6
  mode: subagent
7
7
  temperature: 0.1
8
8
  ---
@@ -2,7 +2,7 @@
2
2
  name: data-migrations-reviewer
3
3
  description: Conditional code-review persona, selected when the diff touches migration files, schema changes, data transformations, or backfill scripts. Reviews code for data integrity and migration safety.
4
4
  tools: Read, Grep, Glob, Bash
5
- color: blue
5
+ color: info
6
6
  mode: subagent
7
7
  temperature: 0.1
8
8
  ---
@@ -2,7 +2,7 @@
2
2
  name: dhh-rails-reviewer
3
3
  description: Conditional code-review persona, selected when Rails diffs introduce architectural choices, abstractions, or frontend patterns that may fight the framework. Reviews code from an opinionated DHH perspective.
4
4
  tools: Read, Grep, Glob, Bash
5
- color: blue
5
+ color: info
6
6
  mode: subagent
7
7
  temperature: 0.1
8
8
  ---
@@ -2,7 +2,7 @@
2
2
  name: julik-frontend-races-reviewer
3
3
  description: Conditional code-review persona, selected when the diff touches async UI code, Stimulus/Turbo lifecycles, or DOM-timing-sensitive frontend behavior. Reviews code for race conditions and janky UI failure modes.
4
4
  tools: Read, Grep, Glob, Bash
5
- color: blue
5
+ color: info
6
6
  mode: subagent
7
7
  temperature: 0.1
8
8
  ---
@@ -2,7 +2,7 @@
2
2
  name: kieran-python-reviewer
3
3
  description: Conditional code-review persona, selected when the diff touches Python code. Reviews changes with Kieran's strict bar for Pythonic clarity, type hints, and maintainability.
4
4
  tools: Read, Grep, Glob, Bash
5
- color: blue
5
+ color: info
6
6
  mode: subagent
7
7
  temperature: 0.1
8
8
  ---
@@ -2,7 +2,7 @@
2
2
  name: kieran-rails-reviewer
3
3
  description: Conditional code-review persona, selected when the diff touches Rails application code. Reviews Rails changes with Kieran's strict bar for clarity, conventions, and maintainability.
4
4
  tools: Read, Grep, Glob, Bash
5
- color: blue
5
+ color: info
6
6
  mode: subagent
7
7
  temperature: 0.1
8
8
  ---
@@ -2,7 +2,7 @@
2
2
  name: kieran-typescript-reviewer
3
3
  description: Conditional code-review persona, selected when the diff touches TypeScript code. Reviews changes with Kieran's strict bar for type safety, clarity, and maintainability.
4
4
  tools: Read, Grep, Glob, Bash
5
- color: blue
5
+ color: info
6
6
  mode: subagent
7
7
  temperature: 0.1
8
8
  ---
@@ -2,7 +2,7 @@
2
2
  name: maintainability-reviewer
3
3
  description: Always-on code-review persona. Reviews code for premature abstraction, unnecessary indirection, dead code, coupling between unrelated modules, and naming that obscures intent.
4
4
  tools: Read, Grep, Glob, Bash
5
- color: blue
5
+ color: info
6
6
  mode: subagent
7
7
  temperature: 0.1
8
8
  ---
@@ -2,7 +2,7 @@
2
2
  name: performance-reviewer
3
3
  description: Conditional code-review persona, selected when the diff touches database queries, loop-heavy data transforms, caching layers, or I/O-intensive paths. Reviews code for runtime performance and scalability issues.
4
4
  tools: Read, Grep, Glob, Bash
5
- color: blue
5
+ color: info
6
6
  mode: subagent
7
7
  temperature: 0.1
8
8
  ---
@@ -2,7 +2,7 @@
2
2
  name: previous-comments-reviewer
3
3
  description: Conditional code-review persona, selected when reviewing a PR that has existing review comments or review threads. Checks whether prior feedback has been addressed in the current diff.
4
4
  tools: Read, Grep, Glob, Bash
5
- color: yellow
5
+ color: warning
6
6
 
7
7
  ---
8
8
 
@@ -2,7 +2,7 @@
2
2
  name: project-standards-reviewer
3
3
  description: Always-on code-review persona. Audits changes against the project's own AGENTS.md standards -- frontmatter rules, reference inclusion, naming conventions, cross-platform portability, and tool selection policies.
4
4
  tools: Read, Grep, Glob, Bash
5
- color: blue
5
+ color: info
6
6
 
7
7
  ---
8
8
 
@@ -2,7 +2,7 @@
2
2
  name: reliability-reviewer
3
3
  description: Conditional code-review persona, selected when the diff touches error handling, retries, circuit breakers, timeouts, health checks, background jobs, or async handlers. Reviews code for production reliability and failure modes.
4
4
  tools: Read, Grep, Glob, Bash
5
- color: blue
5
+ color: info
6
6
  mode: subagent
7
7
  temperature: 0.1
8
8
  ---
@@ -2,7 +2,7 @@
2
2
  name: security-reviewer
3
3
  description: Conditional code-review persona, selected when the diff touches auth middleware, public endpoints, user input handling, or permission checks. Reviews code for exploitable vulnerabilities.
4
4
  tools: Read, Grep, Glob, Bash
5
- color: blue
5
+ color: info
6
6
  mode: subagent
7
7
  temperature: 0.1
8
8
  ---
@@ -2,7 +2,7 @@
2
2
  name: testing-reviewer
3
3
  description: Always-on code-review persona. Reviews code for test coverage gaps, weak assertions, brittle implementation-coupled tests, and missing edge case coverage.
4
4
  tools: Read, Grep, Glob, Bash
5
- color: blue
5
+ color: info
6
6
 
7
7
  ---
8
8
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: lint
3
3
  description: Use this agent when you need to run linting and code quality checks on Ruby and ERB files. Run before pushing to origin.
4
- color: yellow
4
+ color: warning
5
5
  mode: subagent
6
6
  temperature: 0.1
7
7
  ---
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: pr-comment-resolver
3
3
  description: "Evaluates and resolves one or more related PR review threads -- assesses validity, implements fixes, and returns structured summaries with reply text. Spawned by the resolve-pr-feedback skill."
4
- color: blue
4
+ color: info
5
5
  ---
6
6
 
7
7
  You resolve PR review threads. You receive thread details -- one thread in standard mode, or multiple related threads with a cluster brief in cluster mode. Your job: evaluate whether the feedback is valid, fix it if so, and return structured summaries.
package/dist/index.js CHANGED
@@ -734,28 +734,20 @@ function registerSkillsPaths(config, skillsDir) {
734
734
  var SINGLETON_KEY = Symbol.for("systematic.singleton.v1");
735
735
  async function plugInOnce({
736
736
  doInit,
737
- onDuplicate,
738
737
  pid
739
738
  }) {
740
739
  const currentPid = pid ?? process.pid;
741
740
  const g = globalThis;
742
741
  const existing = g[SINGLETON_KEY];
743
742
  if (existing && existing.pid === currentPid) {
744
- if (!existing.warned) {
745
- existing.warned = true;
746
- try {
747
- onDuplicate?.(currentPid);
748
- } catch {}
749
- }
750
- await existing.hooksPromise;
751
- return { isFirst: false, hooks: {} };
743
+ const hooks2 = await existing.hooksPromise;
744
+ return { isFirst: false, hooks: hooks2 };
752
745
  }
753
746
  const hooksPromise = doInit();
754
747
  g[SINGLETON_KEY] = {
755
748
  pid: currentPid,
756
749
  loadedAt: Date.now(),
757
- hooksPromise,
758
- warned: false
750
+ hooksPromise
759
751
  };
760
752
  const hooks = await hooksPromise;
761
753
  return { isFirst: true, hooks };
@@ -1004,18 +996,7 @@ var initializePlugin = async ({ client, directory }) => {
1004
996
  };
1005
997
  var SystematicPlugin = async (input) => {
1006
998
  const { hooks } = await plugInOnce({
1007
- doInit: () => initializePlugin(input),
1008
- onDuplicate: (pid) => {
1009
- const message = `[systematic] duplicate factory invocation in same process (pid=${pid}); skipping duplicate registration. Multiple opencode.json sources may list this plugin.`;
1010
- console.warn(message);
1011
- input.client.app.log({
1012
- body: {
1013
- service: "systematic",
1014
- level: "warn",
1015
- message
1016
- }
1017
- }).catch(() => {});
1018
- }
999
+ doInit: () => initializePlugin(input)
1019
1000
  });
1020
1001
  return hooks;
1021
1002
  };
@@ -11,25 +11,17 @@
11
11
  *
12
12
  * On the first invocation `doInit` runs and the resulting hooks promise
13
13
  * is cached on `globalThis`; the caller receives `{ isFirst: true, hooks }`.
14
- * On every subsequent invocation in the same PID `doInit` is skipped, the
15
- * cached promise is awaited (so sticky rejections still propagate),
16
- * `onDuplicate` fires exactly once, and the caller receives
17
- * `{ isFirst: false, hooks: {} as T }`. Across PIDs the guard is treated
18
- * as absent and init runs fresh — `globalThis` is per-process, but the
19
- * explicit PID check adds defensive belt-and-suspenders against any
20
- * state-leakage edge case.
14
+ * On every subsequent invocation in the same PID `doInit` is skipped and
15
+ * the cached resolved hooks are returned directly to every caller.
16
+ * Across PIDs the guard is treated as absent and init runs fresh —
17
+ * `globalThis` is per-process, but the explicit PID check adds defensive
18
+ * belt-and-suspenders against any state-leakage edge case.
21
19
  *
22
- * **Why empty hooks on duplicate invocations.** A whole-hooks singleton
23
- * that returns the same hooks reference to both invocations does not
24
- * deduplicate host-side tool registration: OpenCode iterates each plugin
25
- * source's returned hook surface and registers every tool entry it finds,
26
- * even when two sources return the same JS reference. Returning `{}` from
27
- * the duplicate path is the only shape that prevents host-side double
28
- * registration of `systematic_skill`, the `config` hook, and the
29
- * `experimental.chat.system.transform` hook. The Phase 0 follow-up probe
30
- * (see `docs/plans/2026-05-01-001-fix-idempotent-plugin-registration-plan.md`)
31
- * verified the duplicate `systematic_skill` entry in OpenCode's
32
- * `client.tool.list(...)` output, which is the LLM-visible tool catalog.
20
+ * The singleton returns the same hooks reference to every caller within a
21
+ * process first and duplicate alike. OpenCode may register the same hook
22
+ * surface once per configured plugin source; that is preferable to suppressing
23
+ * duplicates with an empty object because every source keeps the full tools,
24
+ * commands, skills, and hooks surface.
33
25
  *
34
26
  * **Known limitation — rejected init is sticky.** If `doInit()` rejects,
35
27
  * the rejected promise is stored on `globalThis` and every subsequent
@@ -40,37 +32,27 @@
40
32
  export interface PlugInOnceOptions<T> {
41
33
  /** Heavy init work that should run at most once per process. */
42
34
  doInit: () => Promise<T>;
43
- /**
44
- * Called exactly once on the first duplicate invocation in the same
45
- * process. Subsequent duplicates are silent. Receives the same `pid`
46
- * value the guard used for its identity check (so test overrides flow
47
- * through faithfully). Implementations must not throw; fire-and-forget
48
- * side effects (logging, metrics) are expected. Synchronous exceptions
49
- * are swallowed defensively.
50
- */
51
- onDuplicate?: (pid: number) => void;
52
35
  /** Test override; defaults to `process.pid`. */
53
36
  pid?: number;
54
37
  }
55
38
  /**
56
39
  * Result envelope for `plugInOnce(...)`.
57
40
  *
58
- * - `isFirst: true` — caller should return `hooks` to OpenCode.
59
- * - `isFirst: false` — caller MUST return `hooks` (which is an empty `{}`)
60
- * so the host loader does not register tools or hooks twice.
41
+ * - `isFirst: true` — caller was the first invocation in this process.
42
+ * - `isFirst: false` — `doInit` was skipped; the cached result is returned.
61
43
  *
62
- * Callers that just `return result.hooks` do the right thing in both
63
- * cases without needing to inspect `isFirst`.
44
+ * In both cases `hooks` is the real resolved value of `doInit()`. Callers
45
+ * return `result.hooks` unconditionally without inspecting `isFirst`.
64
46
  */
65
47
  export interface PlugInOnceResult<T> {
66
48
  isFirst: boolean;
67
49
  hooks: T;
68
50
  }
69
51
  /**
70
- * Run `doInit` at most once per process; on duplicate invocations resolve to
71
- * empty hooks so the OpenCode host does not double-register tools and hooks.
52
+ * Run `doInit` at most once per process; on duplicate invocations return the
53
+ * cached real hook surface so every config source sees the same surface.
72
54
  */
73
- export declare function plugInOnce<T>({ doInit, onDuplicate, pid, }: PlugInOnceOptions<T>): Promise<PlugInOnceResult<T>>;
55
+ export declare function plugInOnce<T>({ doInit, pid, }: PlugInOnceOptions<T>): Promise<PlugInOnceResult<T>>;
74
56
  /**
75
57
  * Test-only: clear the singleton state so the next invocation re-runs
76
58
  * init. Must not be called in production code paths.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fro.bot/systematic",
3
- "version": "2.9.1",
3
+ "version": "2.9.2",
4
4
  "description": "Structured engineering workflows for OpenCode",
5
5
  "type": "module",
6
6
  "homepage": "https://fro.bot/systematic",