@vasilvestre/opencode-plain-style 1.0.0 → 1.1.0
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/.opencode/plugins/plain-style.js +46 -0
- package/README.md +22 -10
- package/package.json +4 -4
- package/.opencode/plugins/plain-style.mjs +0 -25
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// plain-style — OpenCode plugin, supports opencode v1.x and v2.x.
|
|
2
|
+
//
|
|
3
|
+
// Injects the plain-language rulebook (plain-style.md, beside this file) into
|
|
4
|
+
// every chat's system prompt on every agent-loop LLM request, primary agent
|
|
5
|
+
// and subagents alike.
|
|
6
|
+
//
|
|
7
|
+
// The default export is one object with both entrypoints (v2 migration guide:
|
|
8
|
+
// https://opencode.ai/v2/docs/build/plugins/migrate-v1):
|
|
9
|
+
// - v2 calls setup() and registers a "context" session hook; system parts are
|
|
10
|
+
// objects ({ type: "text", text }) there.
|
|
11
|
+
// - v1 (object entrypoints need opencode >= 1.18.29) calls server() and gets
|
|
12
|
+
// the experimental.chat.system.transform hook; system entries there are
|
|
13
|
+
// plain strings. The hook must mutate output.system in place (push), because v1
|
|
14
|
+
// ignores a reassignment of output.system.
|
|
15
|
+
//
|
|
16
|
+
// Auto-discovered from .opencode/plugins/ in both versions, so no
|
|
17
|
+
// opencode.json entry is needed. To register it by hand instead:
|
|
18
|
+
// { "plugin": ["./.opencode/plugins/plain-style.js"] } (opencode v1)
|
|
19
|
+
// { "plugins": ["./.opencode/plugins/plain-style.js"] } (opencode v2)
|
|
20
|
+
|
|
21
|
+
import fs from 'fs';
|
|
22
|
+
import path from 'path';
|
|
23
|
+
import { fileURLToPath } from 'url';
|
|
24
|
+
|
|
25
|
+
// Read once at load; a missing file throws here so startup fails loud instead
|
|
26
|
+
// of silently injecting nothing.
|
|
27
|
+
const rulebook = fs.readFileSync(
|
|
28
|
+
path.join(path.dirname(fileURLToPath(import.meta.url)), 'plain-style.md'),
|
|
29
|
+
'utf8',
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
export default {
|
|
33
|
+
id: 'vasilvestre.opencode-plain-style',
|
|
34
|
+
async setup(ctx) {
|
|
35
|
+
await ctx.session.hook('context', (event) => {
|
|
36
|
+
event.system.push({ type: 'text', text: rulebook });
|
|
37
|
+
});
|
|
38
|
+
},
|
|
39
|
+
async server() {
|
|
40
|
+
return {
|
|
41
|
+
'experimental.chat.system.transform': async (_input, output) => {
|
|
42
|
+
output.system.push(rulebook);
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
},
|
|
46
|
+
};
|
package/README.md
CHANGED
|
@@ -90,7 +90,13 @@ Rules state what to do, not what to avoid by name.
|
|
|
90
90
|
### Steps
|
|
91
91
|
|
|
92
92
|
1. Open `~/.config/opencode/opencode.json`.
|
|
93
|
-
2. Add the package name to the
|
|
93
|
+
2. Add the package name to the plugin array. opencode v2 uses the `plugins` key, opencode v1 uses `plugin`:
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"plugins": ["@vasilvestre/opencode-plain-style"]
|
|
98
|
+
}
|
|
99
|
+
```
|
|
94
100
|
|
|
95
101
|
```json
|
|
96
102
|
{
|
|
@@ -119,28 +125,32 @@ Use this to test changes before publishing, or to run a fork.
|
|
|
119
125
|
|
|
120
126
|
```json
|
|
121
127
|
{
|
|
122
|
-
"
|
|
128
|
+
"plugins": ["file:///absolute/path/to/opencode-plain-style/.opencode/plugins/plain-style.js"]
|
|
123
129
|
}
|
|
124
130
|
```
|
|
125
131
|
|
|
126
|
-
The path must be absolute and must point at the `.
|
|
132
|
+
opencode v1 uses the same URL under the `plugin` key. The path must be absolute and must point at the `.js` file, not the directory.
|
|
127
133
|
|
|
128
134
|
3. Restart opencode.
|
|
129
135
|
|
|
130
136
|
### Uninstall
|
|
131
137
|
|
|
132
|
-
1. Remove the entry from the `plugin`
|
|
138
|
+
1. Remove the entry from the plugin array (`plugins` in opencode v2, `plugin` in v1) in `~/.config/opencode/opencode.json`.
|
|
133
139
|
2. Restart opencode.
|
|
134
140
|
|
|
135
141
|
## How it works
|
|
136
142
|
|
|
137
|
-
The plugin
|
|
138
|
-
|
|
143
|
+
The plugin exports one object with two entrypoints; opencode picks the one matching its version:
|
|
144
|
+
|
|
145
|
+
- opencode v1 calls `server()`. It hooks `experimental.chat.system.transform` and pushes the rulebook text (a string) into the system prompt array on each request.
|
|
146
|
+
- opencode v2 calls `setup()`. It registers a `context` session hook and appends a `{ type: "text" }` part to the system prompt.
|
|
147
|
+
|
|
139
148
|
The rulebook is read from disk once at module load, so each request costs one array push and zero I/O.
|
|
140
|
-
|
|
149
|
+
The plugin has no dependencies.
|
|
141
150
|
|
|
142
|
-
|
|
143
|
-
|
|
151
|
+
In opencode v1 the hook must mutate `output.system` in place: a reassignment is silently ignored.
|
|
152
|
+
|
|
153
|
+
Note: v1 support needs opencode 1.18.29 or later (object-style plugin entrypoints).
|
|
144
154
|
|
|
145
155
|
## Example output
|
|
146
156
|
|
|
@@ -205,10 +215,12 @@ Fork the repo, edit the file, and point your config at the local copy:
|
|
|
205
215
|
|
|
206
216
|
```json
|
|
207
217
|
{
|
|
208
|
-
"
|
|
218
|
+
"plugins": ["file:///path/to/your/fork/.opencode/plugins/plain-style.js"]
|
|
209
219
|
}
|
|
210
220
|
```
|
|
211
221
|
|
|
222
|
+
opencode v1 uses the `plugin` key instead.
|
|
223
|
+
|
|
212
224
|
## Development
|
|
213
225
|
|
|
214
226
|
The `bench/` directory holds the full benchmark suite: harness, scorer, aggregator, raw results.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vasilvestre/opencode-plain-style",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Plain-language writing rules for opencode agents, injected into every system prompt. Enforces ISO 24495-1 principles on commits, comments, docs, and chat prose.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"opencode-plugin",
|
|
@@ -23,10 +23,10 @@
|
|
|
23
23
|
"url": "https://github.com/vasilvestre/opencode-plain-style/issues"
|
|
24
24
|
},
|
|
25
25
|
"type": "module",
|
|
26
|
-
"main": "./.opencode/plugins/plain-style.
|
|
26
|
+
"main": "./.opencode/plugins/plain-style.js",
|
|
27
27
|
"exports": {
|
|
28
|
-
".": "./.opencode/plugins/plain-style.
|
|
29
|
-
"./plugin": "./.opencode/plugins/plain-style.
|
|
28
|
+
".": "./.opencode/plugins/plain-style.js",
|
|
29
|
+
"./plugin": "./.opencode/plugins/plain-style.js"
|
|
30
30
|
},
|
|
31
31
|
"scripts": {
|
|
32
32
|
"test": "node scripts/check-plugin.mjs"
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
// plain-style — OpenCode plugin.
|
|
2
|
-
//
|
|
3
|
-
// Injects the plain-language rulebook (plain-style.md, beside this file) into
|
|
4
|
-
// every chat's system prompt on every LLM request — primary agent and
|
|
5
|
-
// subagents alike — so the rules survive context compaction. Pattern cloned
|
|
6
|
-
// from the ponytail plugin (experimental.chat.system.transform).
|
|
7
|
-
//
|
|
8
|
-
// Registered in opencode.jsonc: { "plugin": [..., "./plugins/plain-style.mjs"] }
|
|
9
|
-
|
|
10
|
-
import fs from 'fs';
|
|
11
|
-
import path from 'path';
|
|
12
|
-
import { fileURLToPath } from 'url';
|
|
13
|
-
|
|
14
|
-
// Read once at load; a missing file throws here so startup fails loud instead
|
|
15
|
-
// of silently injecting nothing.
|
|
16
|
-
const rulebook = fs.readFileSync(
|
|
17
|
-
path.join(path.dirname(fileURLToPath(import.meta.url)), 'plain-style.md'),
|
|
18
|
-
'utf8',
|
|
19
|
-
);
|
|
20
|
-
|
|
21
|
-
export default async () => ({
|
|
22
|
-
'experimental.chat.system.transform': async (_input, output) => {
|
|
23
|
-
output.system.push(rulebook);
|
|
24
|
-
},
|
|
25
|
-
});
|