@cardinal4/opencode-fold-diffs 0.3.1 → 0.3.3
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/README.md +12 -4
- package/package.json +2 -2
- package/tui.js +14 -6
package/README.md
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
# opencode-fold-diffs
|
|
2
2
|
|
|
3
|
+
> [!IMPORTANT]
|
|
4
|
+
> **This is a fork, and it exists for one reason: OpenCode V2 support.**
|
|
5
|
+
>
|
|
6
|
+
> The original plugin is **[Tanner Bruhn](https://github.com/tannerbruhn)**'s [`tannerbruhn/opencode-fold-diffs`](https://github.com/tannerbruhn/opencode-fold-diffs) (npm: `opencode-fold-diffs`) — the **OpenCode V1** plugin, whose V1 implementation does not run in V2. This fork — [`cardin/opencode-fold-diffs`](https://github.com/cardin/opencode-fold-diffs), published as [`@cardinal4/opencode-fold-diffs`](https://www.npmjs.com/package/@cardinal4/opencode-fold-diffs) — ports it to **OpenCode V2** (the `@opencode/cli` 2.x line, `opencode v2.0.x`). Install this fork if you are on V2; install upstream if you are on V1.
|
|
7
|
+
>
|
|
8
|
+
> **All credit for the original plugin goes to [Tanner Bruhn](https://github.com/tannerbruhn).** This fork is unofficial and independent: Tanner has not reviewed it, does not maintain it, and does not endorse it. Report bugs in this fork here, not upstream.
|
|
9
|
+
|
|
3
10
|
**Every `write` and `edit` dumps the whole file or the whole diff into your transcript, and stays there.** This plugin folds those blocks down to their header line — `# Wrote 40 lines · click to expand src/app.ts` — and opens them again on click, or with a fold/unfold-all key if you configure one.
|
|
4
11
|
|
|
5
|
-
|
|
12
|
+
The V2 port is not a re-host: it follows V2's new plugin API and render tree, so the V1 code cannot be reused. See [Migrating from V1](#migrating-from-v1) for what changed.
|
|
6
13
|
|
|
7
14
|
## What V2 already folds
|
|
8
15
|
|
|
@@ -117,14 +124,15 @@ The V2 TUI plugin API (`@opencode/plugin/tui`) has no slot for message parts, so
|
|
|
117
124
|
|
|
118
125
|
Renderable classes are matched by duck-typing (`typeof node.diff === "string"`, `content` + `filetype` for code) rather than `instanceof`, because the opentui classes are minified in the shipped binary and their names are not stable.
|
|
119
126
|
|
|
120
|
-
Blocks are re-scanned on `message.
|
|
127
|
+
Blocks are re-scanned on V2's `session.message.content.updated`, `session.tool.success` and `session.tool.failed`, plus `session.step.ended` and `session.execution.succeeded` (`session.shell.ended` joins them when `bash` folding is on). A 2 s sweep catches a session opened from history, whose parts land before any event this plugin sees.
|
|
121
128
|
|
|
122
129
|
## Migrating from V1
|
|
123
130
|
|
|
124
|
-
V1 plugin implementations do not run in V2.
|
|
131
|
+
V1 plugin implementations do not run in V2. The V2 port made these changes:
|
|
125
132
|
|
|
126
133
|
- Entrypoint is a `{ id, setup(context) }` definition (`Plugin.define()` is an identity helper, so the shape is the same). `setup` returns the cleanup function instead of `api.lifecycle.onDispose`.
|
|
127
134
|
- `api.renderer` → `context.renderer`; `api.route.current.name` → `context.ui.router.current().type`; `api.event.on` → `context.data.on`; `api.ui.toast` → `context.ui.toast.show`; `api.keymap.registerLayer` → `context.keymap.layer`.
|
|
135
|
+
- Event names are V2's: `message.updated` / `message.part.updated` are legacy schemas in V2 and are never emitted. The plugin listens to `session.message.content.updated`, `session.tool.success` / `session.tool.failed`, `session.step.ended` and `session.execution.succeeded` (plus `session.shell.ended` when bash folding is on). These names exist from 2.0.10 on, so older V2 installs get the same fix without upgrading.
|
|
128
136
|
- Tool headers are no longer one string. V1 rendered `"← Edit src/app.ts"`; V2 renders a label node plus a path node, so detection and the stats suffix target the label.
|
|
129
137
|
- `bash` defaults to `false`, because V2 now trims long commands to two lines itself.
|
|
130
138
|
- Config moves from `tui.json` to `cli.json` (or `opencode.json(c)`).
|
|
@@ -146,7 +154,7 @@ V1 plugin implementations do not run in V2. This branch made these changes:
|
|
|
146
154
|
|
|
147
155
|
## Status
|
|
148
156
|
|
|
149
|
-
Written against **opencode v2.0.
|
|
157
|
+
Written against **opencode v2.0.24**, and compatible across the V2 line: the `session.*` events this version listens to exist from v2.0.10 on, so an older V2 install gets the fix without upgrading. The tree-walking, block matching, fold/unfold and toggle logic run green against a mock renderer tree shaped like V2's (`node --test`), and the fold was checked against a real transcript: `visible = false` (Yoga `display: none`) is what actually hides a body, not `maxHeight`.
|
|
150
158
|
|
|
151
159
|
Edits with fewer than `min_lines` changed lines (default 6) are left expanded on purpose — a one-line change is already its own summary. Set `min_lines: 0` to fold every file block.
|
|
152
160
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cardinal4/opencode-fold-diffs",
|
|
3
|
-
"version": "0.3.
|
|
4
|
-
"description": "OpenCode V2
|
|
3
|
+
"version": "0.3.3",
|
|
4
|
+
"description": "Unofficial OpenCode V2 fork of opencode-fold-diffs: write, edit and apply_patch blocks render folded to their header line, click to expand.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"keywords": [
|
package/tui.js
CHANGED
|
@@ -10,15 +10,15 @@
|
|
|
10
10
|
// closed without one, so this does it from a plugin.
|
|
11
11
|
//
|
|
12
12
|
// A folded block renders as its header line -- "# Wrote 40 lines · click to
|
|
13
|
-
// expand src/app.ts" -- and opens on click, or with
|
|
14
|
-
// once.
|
|
13
|
+
// expand src/app.ts" -- and opens on click, or with the optional `key`
|
|
14
|
+
// binding for every block at once.
|
|
15
15
|
//
|
|
16
16
|
// Options (cli.json -> ["opencode-fold-diffs", { ... }] or opencode.json(c)):
|
|
17
17
|
// lines lines of the body left visible when folded (default 0, title only)
|
|
18
18
|
// min_lines leave blocks with fewer content lines alone (default 6)
|
|
19
19
|
// stats append "40 lines · click to expand" to the header (default true)
|
|
20
20
|
// folded new blocks start folded (default true)
|
|
21
|
-
// key binding that folds/unfolds every block (default "
|
|
21
|
+
// key binding that folds/unfolds every block (default "", none)
|
|
22
22
|
// bash fold long bash commands too (default false on V2)
|
|
23
23
|
// bash_lines rows of the command left visible when folded (default 1)
|
|
24
24
|
//
|
|
@@ -420,10 +420,18 @@ export default {
|
|
|
420
420
|
}, 120);
|
|
421
421
|
}
|
|
422
422
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
423
|
+
// V1's message.part.updated / message.updated are legacy schemas in V2 --
|
|
424
|
+
// the client emits the session.* events instead, so the V1 names were a
|
|
425
|
+
// silent no-op and a new block only folded on the sweeping timer.
|
|
426
|
+
const events = [
|
|
427
|
+
"session.message.content.updated", // a part was appended or replaced
|
|
428
|
+
"session.tool.success", // a tool body (diff or file) appeared
|
|
429
|
+
"session.tool.failed", // a failed tool still renders its block
|
|
430
|
+
"session.step.ended", // the step's final content has arrived
|
|
431
|
+
"session.execution.succeeded", // the turn settled; take a final look
|
|
426
432
|
];
|
|
433
|
+
if (shell) events.push("session.shell.ended"); // the command now carries its "$ " prefix
|
|
434
|
+
const offs = events.map((name) => context.data.on(name, schedule));
|
|
427
435
|
const timer = setInterval(sweep, SWEEP_MS);
|
|
428
436
|
schedule();
|
|
429
437
|
|