Add native /graphify slash command for OpenCode - #2727
Conversation
OpenCode skills are loaded on-demand by the agent via description matching; they are not slash commands. Only a markdown file under .opencode/commands/ becomes a /-menu entry, so installing just the skill and reminder plugin left /graphify absent from the TUI command menu even though the skill loaded correctly and the docs told users to type it. Ship a command-opencode.md template (mirroring the existing Kilo command file) that loads the skill and forwards $ARGUMENTS, and wire it into opencode install/uninstall alongside the existing plugin. Also drops the .opencode/opencode.json "plugin" array registration: OpenCode already auto-loads every file under .opencode/plugins/, so the registration was redundant, and for a global install it wrote a project-relative path into a project-relative config file that a global setup never reads, leaving a dead entry behind. Fixes Graphify-Labs#2709.
There was a problem hiding this comment.
Graphify reviewed this change.
Looks safe to merge — no coupling regressions and no blocking issues, checked against the code graph (not a self-assessment).
Formal verification. 2 change(s) tested, no difference found (not proven).
Graphify review — findings
This PR changes the OpenCode integration in graphify/install.py. It removes the logic that registered/deregistered the plugin in .opencode/opencode.json (so install/uninstall no longer touch that config file) and adds installation of a new native /graphify slash command via a new command-opencode.md file copied into .opencode/commands/. Supporting changes include the new command markdown file, a pyproject.toml package-data entry for it, an import rename in __main__.py, and updated/rewritten tests in test_install.py reflecting the config and command behavior.
No blocking issues surfaced. 3 lower-confidence candidates did not survive cross-model review.
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 479 functions depend on the 293 functions this change touches.
Health — this change adds coupling hotspots:
- worse:
install()— 5 callers, 12 callees - worse:
_agents_install()— 6 callers, 7 callees - worse:
_agents_uninstall()— 7 callers, 5 callees - worse:
uninstall_all()— 2 callers, 14 callees
Verification — 479 functions in the blast radius were not formally verified this run (proofs are advisory here).
Gate & verification
graphify gate
PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.
Advisory (not blocking):
- verification_scope: 479 function(s) in the blast radius were not formally verified this run
Formal verification
Could not verify: Could not verify \_agents\_install.
The verifier did not have enough to check \_agents\_install, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: not verifiable: all 200 sampled inputs raised on both versions — the function never executed, so 'no divergence' would be vacuous (mostly TypeError — names the real obstacle, not a sampling gap)
No difference found (not proven): No behavior difference found in \_agents\_uninstall (not a proof).
The verifier ran both versions of \_agents\_uninstall on many inputs and saw identical behavior every time. Strong evidence the change is safe, but evidence, not a proof.
Guarantee: Empirical: differential testing (both versions run on many generated inputs). A divergence on an untested input remains possible, so this is 'no counterexample found', not 'proven equivalent'.
Note: An input the sampler did not try could still differ.
Could not verify: Could not verify install.
The verifier did not have enough to check install, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: not verifiable: all 23 sampled inputs raised on both versions — the function never executed, so 'no divergence' would be vacuous (mostly SystemExit — names the real obstacle, not a sampling gap)
Could not verify: Could not verify \_install\_opencode\_plugin.
The verifier did not have enough to check \_install\_opencode\_plugin, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: parameter `project_dir` is annotated `Path` — outside the synthesizable primitive/collection set
No difference found (not proven): No behavior difference found in uninstall\_all (not a proof).
The verifier ran both versions of uninstall\_all on many inputs and saw identical behavior every time. Strong evidence the change is safe, but evidence, not a proof.
Guarantee: Empirical: differential testing (both versions run on many generated inputs). A divergence on an untested input remains possible, so this is 'no counterexample found', not 'proven equivalent'.
Note: An input the sampler did not try could still differ.
Could not verify: Could not verify \_uninstall\_opencode\_plugin.
The verifier did not have enough to check \_uninstall\_opencode\_plugin, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: parameter `project_dir` is annotated `Path` — outside the synthesizable primitive/collection set
· 4 more finding(s) on lines outside this diff (see the check run).
|
@safishamsi this PR's CI run is waiting on approval (first-time contributor gate) — could you approve the workflow run when you get a chance? Happy to address any review feedback in the meantime. |
OpenCode skills are loaded on-demand by the agent via description matching; they are not slash commands. Only a markdown file under .opencode/commands/ becomes a /-menu entry, so installing just the skill and reminder plugin left /graphify absent from the TUI command menu even though the skill loaded correctly and the docs told users to type it.
Ship a command-opencode.md template (mirroring the existing Kilo command file) that loads the skill and forwards $ARGUMENTS, and wire it into opencode install/uninstall alongside the existing plugin.
Also drops the .opencode/opencode.json "plugin" array registration: OpenCode already auto-loads every file under .opencode/plugins/, so the registration was redundant, and for a global install it wrote a project-relative path into a project-relative config file that a global setup never reads, leaving a dead entry behind.
Fixes #2709.