opencode-command-hooks 0.1.7 → 0.1.8

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.
Files changed (2) hide show
  1. package/README.md +31 -26
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # 🪝 OpenCode Command Hooks
1
+ # 🪝 OpenCode Command Hooks 🪝
2
2
 
3
3
  Use simple configs to declaratively define shell command hooks on tool/subagent invocations. With a single line of configuration, you can inject a hook's output directly into context for your agent to read.
4
4
 
@@ -6,7 +6,7 @@ Use simple configs to declaratively define shell command hooks on tool/subagent
6
6
 
7
7
  Define hooks in just a couple lines of markdown frontmatter. Putting them here is also really nice because you can see your entire agent's config in one place.
8
8
 
9
- ````yaml
9
+ ```yaml
10
10
  ---
11
11
  description: Analyzes the codebase and implements code changes.
12
12
  mode: subagent
@@ -15,7 +15,8 @@ hooks:
15
15
  - run: "npm run test"
16
16
  inject: "Test Output:\n{stdout}\n{stderr}"
17
17
  ---
18
- ````
18
+ ```
19
+ **This plugin was not built by the OpenCode team nor is it affiliated with them.**
19
20
 
20
21
  ## Table of Contents
21
22
 
@@ -34,11 +35,11 @@ hooks:
34
35
 
35
36
  ## Why?
36
37
 
37
- When working with a fleet of subagents, automatic validation of the state of your codebase is really useful. By setting up quality gates (lint/typecheck/test/etc.) or other automation, you can catch and prevent errors quickly and reliably.
38
+ When working with a fleet of subagents, automatic validation of the state of your codebase is really useful. By setting up quality gates (lint/typecheck/test/etc.) or other automation, you can catch and prevent errors quickly and reliably.
38
39
 
39
- Doing this by asking your orchestrator agent to use the bash tool (or call a validator subagent) is non-deterministic and can cost a lot of tokens over time. You could always write your own custom plugin to achieve this automatic validation behavior, but I found myself writing the same boilerplate, error handling, output capture, and session injection logic over and over again.
40
+ Doing this by asking your orchestrator agent to use the bash tool (or call a validator subagent) is non-deterministic and can cost a lot of tokens over time. You could always write your own custom plugin to achieve this automatic validation behavior, but I found myself writing the same boilerplate, error handling, output capture, and session injection logic over and over again.
40
41
 
41
- Though this plugin is mostly a wrapper around accessing hooks that Opencode already exposes, it provides basic plumbing that reduces overhead, giving you a simple, opinionated system for integrating command hooks into your Opencode workflow. I also just like having hooks/config for my agents all colocated in one place (markdown files) and thought that maybe somebody else would like this too.
42
+ Though this plugin is mostly a wrapper around accessing hooks that OpenCode already exposes, it provides basic plumbing that reduces overhead, giving you a simple, opinionated system for integrating command hooks into your OpenCode workflow. I also just like having hooks/config for my agents all colocated in one place (markdown files) and thought that maybe somebody else would like this too.
42
43
 
43
44
  ---
44
45
 
@@ -136,14 +137,12 @@ You can set up tool hooks to only trigger on specific arguments via `when.toolAr
136
137
  "when": {
137
138
  "phase": "after",
138
139
  "tool": "playwright_browser_navigate",
139
- "toolArgs": { "url": "http://localhost:3000]" }
140
+ "toolArgs": { "url": "http://localhost:3000]" },
140
141
  },
141
- "run": [
142
- "osascript -e 'display notification \"Agent triggered playwright\"'"
143
- ],
142
+ "run": ["osascript -e 'display notification \"Agent triggered playwright\"'"],
144
143
  "toast": {
145
- "message": "Agent used the playwright {tool} tool"
146
- }
144
+ "message": "Agent used the playwright {tool} tool",
145
+ },
147
146
  }
148
147
  ```
149
148
 
@@ -166,7 +165,7 @@ Add to your `opencode.json`:
166
165
 
167
166
  ```jsonc
168
167
  {
169
- "plugin": ["opencode-command-hooks"]
168
+ "plugin": ["opencode-command-hooks"],
170
169
  }
171
170
  ```
172
171
 
@@ -192,11 +191,11 @@ Create `.opencode/command-hooks.jsonc` in your project (the plugin searches upwa
192
191
 
193
192
  #### JSON Config Options
194
193
 
195
- | Option | Type | Description |
196
- | ------ | ---- | ----------- |
197
- | `truncationLimit` | `number` | Maximum characters to capture from command output. Defaults to 30,000 (matching OpenCode's bash tool). Must be a positive integer. |
198
- | `tool` | `ToolHook[]` | Array of tool execution hooks |
199
- | `session` | `SessionHook[]`| Array of session lifecycle hooks |
194
+ | Option | Type | Description |
195
+ | ----------------- | --------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
196
+ | `truncationLimit` | `number` | Maximum characters to capture from command output. Defaults to 30,000 (matching OpenCode's bash tool). Must be a positive integer. |
197
+ | `tool` | `ToolHook[]` | Array of tool execution hooks |
198
+ | `session` | `SessionHook[]` | Array of session lifecycle hooks |
200
199
 
201
200
  ### Markdown Frontmatter
202
201
 
@@ -349,8 +348,10 @@ All inject/toast string templates support these placeholders:
349
348
  ---
350
349
 
351
350
  ## Why Use This Plugin?
351
+
352
352
  **It lets you easily set up bash hooks with ~3-5 lines of YAML which are cleanly colocated with your subagent configuration.**
353
353
  Conversely, rolling your own looks something like this (for each project and set of hooks you want to set up):
354
+
354
355
  ```ts
355
356
  import type { Plugin } from "@opencode-ai/plugin";
356
357
 
@@ -377,22 +378,26 @@ export const MyHooks: Plugin = async ({ $, client }) => {
377
378
  try {
378
379
  // Run commands sequentially, even if they fail
379
380
  let lastResult = { exitCode: 0, stdout: "", stderr: "" };
380
-
381
+
381
382
  for (const cmd of ["npm run typecheck", "npm run lint"]) {
382
383
  try {
383
384
  const result = await $`sh -c ${cmd}`.nothrow().quiet();
384
385
  const stdout = result.stdout?.toString() || "";
385
386
  const stderr = result.stderr?.toString() || "";
386
-
387
+
387
388
  // Truncate to 30k chars to match OpenCode's bash tool
388
389
  lastResult = {
389
390
  exitCode: result.exitCode ?? 0,
390
- stdout: stdout.length > 30000
391
- ? stdout.slice(0, 30000) + "\n[Output truncated: exceeded 30000 character limit]"
392
- : stdout,
393
- stderr: stderr.length > 30000
394
- ? stderr.slice(0, 30000) + "\n[Output truncated: exceeded 30000 character limit]"
395
- : stderr,
391
+ stdout:
392
+ stdout.length > 30000
393
+ ? stdout.slice(0, 30000) +
394
+ "\n[Output truncated: exceeded 30000 character limit]"
395
+ : stdout,
396
+ stderr:
397
+ stderr.length > 30000
398
+ ? stderr.slice(0, 30000) +
399
+ "\n[Output truncated: exceeded 30000 character limit]"
400
+ : stderr,
396
401
  };
397
402
  } catch (err) {
398
403
  lastResult = { exitCode: 1, stdout: "", stderr: String(err) };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-command-hooks",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "OpenCode plugin for declaratively attaching shell commands to agent/tool/slash-command lifecycle events",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",