Skip to content

fix: align OpenCode and OpenClaw TypeScript plugins with Pi contract - #2426

Closed
Andrei-hub11 wants to merge 1 commit into
rtk-ai:developfrom
Andrei-hub11:fix/hooks-ts-rewrite-contract-parity
Closed

Andrei-hub11 wants to merge 1 commit into
rtk-ai:developfrom
Andrei-hub11:fix/hooks-ts-rewrite-contract-parity

Conversation

@Andrei-hub11

Copy link
Copy Markdown

Summary

Align the OpenCode and OpenClaw TypeScript plugins with the Pi rewrite contract.

Changes

  • replace which rtk with rtk --version
  • enforce minimum supported version (>= 0.23.0)
  • respect RTK_DISABLED=1
  • skip commands already starting with rtk
  • only accept rewrites on exit code 0 or 3
  • switch OpenClaw from execFileSync to spawnSync so exit code 3 is handled correctly
  • improve OpenClaw probe warnings for unexpected failures

Why

which rtk is a weaker probe here:

  • it depends on the runtime environment exposing which
  • it does not verify that the resolved rtk supports rtk rewrite
  • it does not let us enforce the minimum supported version

rtk --version checks the actual binary we want to use and lets us validate compatibility in the same step.

Test plan

I wrote and verified some unit tests locally, but left them out to keep things in line with the other TypeScript hooks. Can add them too if that makes sense.

  • cargo fmt --all && cargo clippy --all-targets && cargo test
  • Manual testing: rtk <command> output inspected

Important: All PRs must target the develop branch (not master).
See CONTRIBUTING.md for details.

@CLAassistant

CLAassistant commented Jun 13, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@rtk-release-bot

Copy link
Copy Markdown
Contributor

This pull request has been automatically marked as stale due to 90 days of inactivity. If this pull request is still relevant, please leave any comment (for example, "bump"), and we'll keep it open. Your contribution is very much appreciated — we're sorry we haven't been able to review it yet.

@Andrei-hub11

Copy link
Copy Markdown
Author

bump

@rtk-release-bot rtk-release-bot Bot removed the stale label Sep 21, 2026
@KuSh

KuSh commented Oct 3, 2026

Copy link
Copy Markdown
Collaborator

Thank you for the careful write-up. Closing as outdated because of OpenCode v2, which the plugin code this PR edits no longer fits. The findings here are still useful for the OpenCode plugin work in #4187: probing with rtk --version instead of which rtk, a minimum version check, skipping commands that already start with rtk , honouring RTK_DISABLED, and accepting a rewrite only on exit code 0 or 3. If I missed something this PR still covers, please comment and it can be reopened.

@KuSh KuSh closed this Oct 3, 2026
amnesiaof added a commit to amnesiaof/rtk that referenced this pull request Oct 5, 2026
…51.1

KuSh's review of rtk-ai#2426 named two gaps that also apply here: the plugin
decided usability from the file's existence, and set no minimum version.

existsSync only proves a file is there. A wrong-arch binary, a broken
install, or a stale RTK_BIN all pass that check and then fail on every
single tool call. Spawning `rtk --version` once per session is the check
that actually means something, and the answer is cached per binary.

The floor is 0.51.1, not 0.51.0: `rtk hook opencode` was added in rtk-ai#4349
and exists in no released version -- v0.51.0's src/main.rs has no
HookCommands::Opencode variant. Without the gate a 0.51.0 user gets a
plugin that registers hooks, delegates to a missing subcommand, and
silently passes every command through.

A develop build reports 0.49.0 because release-please only bumps
Cargo.toml on master, and the warning it gets is accurate: such a build
has no release version. An unparseable banner is not evidence of an old
rtk, so it passes and the delegation call still fails open.
amnesiaof added a commit to amnesiaof/rtk that referenced this pull request Oct 5, 2026
KuSh, on rtk-ai#2426: "skipping commands that already start with `rtk `".

`rtk git status` reaching the hook means the agent already used rtk --
either carried over from an earlier rewrite or typed by the user. Handing
it back to `rtk hook opencode` cannot improve it, and it costs a process
spawn on every such call.

hooks/pi/rtk.ts already does this with a bare `startsWith("rtk ")`. The
regex here additionally tolerates leading whitespace, since the shell
ignores it and the command may arrive that way.
amnesiaof added a commit to amnesiaof/rtk that referenced this pull request Oct 5, 2026
KuSh, on rtk-ai#2426: "honouring RTK_DISABLED".

`RTK_DISABLED=1` is the escape hatch hooks/README.md documents for users
who want a run without rtk, and hooks/pi/rtk.ts already checks it. Without
it the OpenCode plugin was the one TS hook that could not be turned off
short of editing the file.

Checked per call rather than at setup, for the same reason pi does: the
variable is inherited from whatever launched OpenCode, so a user can
start a session with it set and get a clean baseline. Only the exact
string "1" disables rewriting -- "0" and "true" are not the documented
form and must not silently turn the plugin off.
amnesiaof added a commit to amnesiaof/rtk that referenced this pull request Oct 5, 2026
…51.1

KuSh's review of rtk-ai#2426 named two gaps that also apply here: the plugin
decided usability from the file's existence, and set no minimum version.

existsSync only proves a file is there. A wrong-arch binary, a broken
install, or a stale RTK_BIN all pass that check and then fail on every
single tool call. Spawning `rtk --version` once per session is the check
that actually means something, and the answer is cached per binary.

The floor is 0.51.1, not 0.51.0: `rtk hook opencode` was added in rtk-ai#4349
and exists in no released version -- v0.51.0's src/main.rs has no
HookCommands::Opencode variant. Without the gate a 0.51.0 user gets a
plugin that registers hooks, delegates to a missing subcommand, and
silently passes every command through.

A develop build reports 0.49.0 because release-please only bumps
Cargo.toml on master, and the warning it gets is accurate: such a build
has no release version. An unparseable banner is not evidence of an old
rtk, so it passes and the delegation call still fails open.
amnesiaof added a commit to amnesiaof/rtk that referenced this pull request Oct 5, 2026
KuSh, on rtk-ai#2426: "skipping commands that already start with `rtk `".

`rtk git status` reaching the hook means the agent already used rtk --
either carried over from an earlier rewrite or typed by the user. Handing
it back to `rtk hook opencode` cannot improve it, and it costs a process
spawn on every such call.

hooks/pi/rtk.ts already does this with a bare `startsWith("rtk ")`. The
regex here additionally tolerates leading whitespace, since the shell
ignores it and the command may arrive that way.
amnesiaof added a commit to amnesiaof/rtk that referenced this pull request Oct 5, 2026
KuSh, on rtk-ai#2426: "honouring RTK_DISABLED".

`RTK_DISABLED=1` is the escape hatch hooks/README.md documents for users
who want a run without rtk, and hooks/pi/rtk.ts already checks it. Without
it the OpenCode plugin was the one TS hook that could not be turned off
short of editing the file.

Checked per call rather than at setup, for the same reason pi does: the
variable is inherited from whatever launched OpenCode, so a user can
start a session with it set and get a clean baseline. Only the exact
string "1" disables rewriting -- "0" and "true" are not the documented
form and must not silently turn the plugin off.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants