@madsoftwaredev/opencode-sidebar-resize 0.1.0 → 0.1.2

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 (3) hide show
  1. package/README.md +29 -3
  2. package/package.json +7 -5
  3. package/sidebar.ts +10 -10
package/README.md CHANGED
@@ -33,7 +33,7 @@ same `sidebar-resize` plugin ID and storage keys.
33
33
 
34
34
  ## Compatibility and limitations
35
35
 
36
- The supported development baseline is **OpenCode 2.0.27**, **OpenTUI 0.5.17**,
36
+ The supported development baseline is **OpenCode 2.1.0**, **OpenTUI 0.6.6**,
37
37
  and **Solid 1.9.12**. This is not a guarantee that every later OpenCode layout
38
38
  will work. The package exports `./tui` only and runs in the OpenCode terminal,
39
39
  not in the web or desktop UI. Its Node `>=22` engine metadata does not make the
@@ -42,12 +42,16 @@ TypeScript/TSX entrypoint a standalone Node program.
42
42
  OpenCode V2 has no public sidebar-width API. This plugin uses the exposed
43
43
  OpenTUI renderer and Yoga layout tree, not a browser DOM, to locate and resize
44
44
  the original sidebar and its host pane from a `sidebar.footer` slot anchor.
45
- The adapter was originally inspected against OpenCode 2.0.26 and requires the
45
+ The adapter was inspected against OpenCode 2.1.0-era checkout `32b41bab` and requires the
46
46
  same padded, 42-column sidebar shape, heading, scrollbox, and footer branch.
47
47
  Unrecognized layouts are left unchanged with a warning. OpenCode updates or
48
48
  other plugins that replace the footer or alter that tree can prevent attachment.
49
49
  No installed binaries or OpenCode source files are patched.
50
50
 
51
+ OpenTUI 0.6.6 removed `getLayoutNode()`. The adapter uses Renderable's direct
52
+ `getWidth()`, `getPadding()`, and `getPositionType()` style getters instead;
53
+ `getLayout()` returns computed geometry and is not a replacement for these getters.
54
+
51
55
  The drag fallback temporarily wraps the renderer root's `processMouseEvent`
52
56
  to catch drags whose first move jumps past the handle. Cleanup restores that
53
57
  handler if it still owns it, removes the handle, and restores the original
@@ -77,10 +81,32 @@ native OpenTUI test renderer with a representative sidebar tree and a fake
77
81
  plugin context to check whole-sidebar resizing, dragging, persistence success
78
82
  and failure, terminal resizing, and cleanup. A runtime-import check ensures the
79
83
  TypeScript adapter does not import UI packages at runtime. These checks do not
80
- prove the actual layout or plugin loader in a running OpenCode TUI. The build
84
+ by themselves prove the actual layout or plugin loader in a running OpenCode TUI. The build
81
85
  command checks transpilation, not host integration. Development dependencies
82
86
  are not needed to load the plugin in OpenCode.
83
87
 
88
+ ### Actual-host verification
89
+
90
+ On 2026-10-20, the same adapter was checked with the installed **OpenCode 2.1.0**
91
+ binary in an isolated headless PTY at **180 × 50**, using its actual render tree.
92
+ The local copy was auto-discovered through a controlled global `plugins` symlink,
93
+ not an explicit CLI package entry. This verifies the adapter, not npm package loading.
94
+ Disposable HOME/XDG directories, a private `--standalone` server and database, and a
95
+ fake local provider endpoint were used. Sounds and notifications were disabled;
96
+ no prompts or generations were sent and no existing user sessions changed.
97
+
98
+ | Action | Sidebar width | Session pane width | Handle x |
99
+ | --- | ---: | ---: | ---: |
100
+ | Initial layout | 42 | 138 | 138 |
101
+ | Dispatch `sidebar-resize.width` with `60` | 60 | 120 | 120 |
102
+ | SGR mouse press/drag/release through the PTY | 80 | 100 | 100 |
103
+ | Dispatch reset | 42 | 138 | 138 |
104
+
105
+ Resizing the PTY from 180 to 100 columns unmounted the sidebar handle and expanded
106
+ the session pane to 100 columns. Restoring 180 columns remounted the handle at
107
+ x=138, with sidebar width 42 and session pane width 138.
108
+ Physical-terminal behavior and a human-operated drag remain unverified.
109
+
84
110
  ## License
85
111
 
86
112
  MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@madsoftwaredev/opencode-sidebar-resize",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "OpenCode V2 TUI plugin for resizing the existing session sidebar by dragging or command.",
5
5
  "keywords": [
6
6
  "opencode",
@@ -39,15 +39,17 @@
39
39
  "typecheck": "tsc --noEmit"
40
40
  },
41
41
  "dependencies": {
42
- "@opencode/plugin": "^2.0.27"
42
+ "@opencode/plugin": "^2.1.0"
43
43
  },
44
44
  "peerDependencies": {
45
- "@opentui/core": ">=0.5.17",
46
- "@opentui/solid": ">=0.5.17",
45
+ "@opentui/core": ">=0.6.6",
46
+ "@opentui/solid": ">=0.6.6",
47
47
  "solid-js": ">=1.9.12"
48
48
  },
49
49
  "devDependencies": {
50
- "@types/bun": "1.3.9",
50
+ "@opentui/core": "0.8.1",
51
+ "@opentui/solid": "0.8.1",
52
+ "@types/bun": "1.4.0",
51
53
  "typescript": "5.8.2"
52
54
  },
53
55
  "publishConfig": {
package/sidebar.ts CHANGED
@@ -19,23 +19,23 @@ function findSidebar(anchor: Renderable, core: Core): SidebarTarget | undefined
19
19
  let branch = anchor;
20
20
  for (let node = anchor.parent; node; branch = node, node = node.parent) {
21
21
  const children = node.getChildren();
22
- const layout = node.getLayoutNode();
22
+ // OpenTUI 0.6.6 exposes style getters on Renderable itself; getLayout()
23
+ // returns computed geometry, not the removed Yoga node or its style values.
23
24
  if (
24
25
  children.length !== 3 ||
25
26
  !(children[1] instanceof core.ScrollBoxRenderable) ||
26
27
  children[2] !== branch ||
27
- layout.getPadding(Edge.Left).value !== 2 ||
28
- layout.getPadding(Edge.Right).value !== 2 ||
29
- layout.getWidth().unit !== Unit.Point ||
30
- layout.getWidth().value !== DEFAULT_WIDTH
28
+ node.getPadding(Edge.Left).value !== 2 ||
29
+ node.getPadding(Edge.Right).value !== 2 ||
30
+ node.getWidth().unit !== Unit.Point ||
31
+ node.getWidth().value !== DEFAULT_WIDTH
31
32
  )
32
33
  continue;
33
34
 
34
35
  const pane = node.parent;
35
36
  if (!pane) return undefined;
36
- const paneLayout = pane.getLayoutNode();
37
- const width = paneLayout.getWidth();
38
- const overlay = paneLayout.getPositionType() === PositionType.Absolute;
37
+ const width = pane.getWidth();
38
+ const overlay = pane.getPositionType() === PositionType.Absolute;
39
39
  if (overlay && width.unit === Unit.Percent && width.value === 100) {
40
40
  return { sidebar: node, pane, overlay: true };
41
41
  }
@@ -68,8 +68,8 @@ export function attachSidebarResize(options: {
68
68
  const next = clampWidth(width, available(), overlay);
69
69
  // Both widths are fixed by the host. Updating only the inner box would
70
70
  // overlap the transcript rather than give the whole sidebar more room.
71
- if (sidebar.getLayoutNode().getWidth().value !== next) sidebar.width = next;
72
- if (!overlay && pane.getLayoutNode().getWidth().value !== next) pane.width = next;
71
+ if (sidebar.getWidth().value !== next) sidebar.width = next;
72
+ if (!overlay && pane.getWidth().value !== next) pane.width = next;
73
73
  };
74
74
  const refresh = () => apply(drag?.width ?? options.width());
75
75
  const schedule = () => {