Atlas / Skills / marcus / Drag Pane

Drag PaneSAFE

skills/marcus/drag-pane

Use sidecar next to CLI agents for diffs, file trees, conversation history, and task management with td

Verdict
SAFE
Grade
B
Trust score
89 /100
Version
—
Hosts
—
License
MIT
Stars
1,086
01

Overview

Use sidecar next to CLI agents for diffs, file trees, conversation history, and task management with td

Read from source at commit a69114b893d1OBSERVED · 2026-10-10
02

What it tells the agent

The instruction file, verbatim from the audited commit — this is the text the model reads, and the surface the audit's instruction layer examines. Quoted here so you can judge it without cloning anything.

---
name: drag-pane
description: >
  Drag-and-drop pane resizing implementation for two-pane plugin layouts.
  Covers mouse event handling via the internal/mouse package, hit region
  registration, drag delta calculation, width clamping, state persistence,
  and pane layout management. Use when working on pane resizing, drag
  interactions, layout management, or adding drag-to-resize to a new plugin.
---

# Drag-to-Resize Pane Implementation

## Overview

Add drag-to-resize support for two-pane plugin layouts (sidebar + main content). Users click and drag the divider between panes to resize them.

## Prerequisites

- Plugin already has a two-pane layout (sidebar + main content)
- State persistence functions exist in `internal/state/state.go` (each plugin has its own getter/setter)
- Familiarity with `internal/mouse` package

## Existing Implementations

| Plugin | State Functions | Mouse File |
|--------|----------------|------------|
| FileBrowser | `GetFileBrowserTreeWidth()` / `SetFileBrowserTreeWidth()` | `internal/plugins/filebrowser/mouse.go` |
| GitStatus | `GetGitStatusSidebarWidth()` / `SetGitStatusSidebarWidth()` | `internal/plugins/gitstatus/mouse.go` |
| Conversations | `GetConversationsSideWidth()` / `SetConversationsSideWidth()` | `internal/plugins/conversations/mouse.go` |
| Workspace (project) | `GetWorkspaceSidebarWidth()` / `SetWorkspaceSidebarWidth()` | `internal/plugins/workspace/view_list.go` |
| Sessions (global workspace) | `GetWorkspaceSidebarWidth()` / `SetWorkspaceSidebarWidth()` | `internal/overview/workspaces.go` |

## Windowing parity: project and global workspaces are one feature

The project workspace (`internal/plugins/workspace`) and the global Workspaces
browser shown as **Sessions** in the navbar (`internal/overview`) are two
projections of the same windowing model. They are not independent surfaces that
happen to look similar.

**If a change affects panes, splits, drag handles, pane borders, focus chrome,
or pane hit regions in one of them, it affects the other.** The rule is
structural, not a habit to remember:

- `internal/panelayout` owns pane-tree structure and geometry.
- `internal/paneframe` owns presentation: chrome geometry (`Inset`, `Geometry`),
  the leaf border states (`Chrome`, `WrapLeaf`), the drag handle
  (`RenderDividerHandle`, `DividerHitBox`, `HandleStateFor`), the compositor
  (`Compose`, `ComposeLeaf`, `RenderContent`), the chrome-aware floors
  (`ChromeFloors`), and the one order hit regions are registered in
  (`RegisterRegions`), and click-to-focus (`LeafAt`, `FocusLeafAt`).
- Each surface implements `paneframe.Host` and `paneframe.RegionSink` in exactly
  one file: `internal/plugins/workspace/pane_host.go` and
  `internal/overview/pane_host.go`.

**Focus is one value, answered from geometry.** `Host.Focus()` draws the ring and
`Host.SetFocus()` moves it; there is no third place a surface may record who is
being typed into, so a surface whose live terminal holds the keyboard separately
gives it up inside its own focus setter (`workspace.setFocusTarget`,
`overview.focusPreviewLeaf`). A pointer moves focus through
`paneframe.FocusLeafAt`, which resolves the leaf from its OUTER **box**, not from
the hit region the press landed on — a terminal leaf owns no click-to-focus
region, because its presses belong to the live pane and are forwarded to tmux.
`FocusLeafAt` moves focus and nothing else, so the press still reaches whichever
region claimed it, and it declines the divider's widened target so a press one
cell off a handle resizes without also re-focusing. Hanging focus off the region
handlers instead is td-43db92: one focus call per leaf kind, and the ring drawn
on a neighbour for the kind nobody remembered.

`Host.Layout()` must answer the tree the surface last **drew**, not one it could
place. A view that replaces the preview — the kanban board, a modal — draws no
tree, and geometry that outlives the frame lets a click on whatever is drawn
there move pane focus instead. The project plugin records the layout beside the
hit regions it earned (`paneFrame`/`paneFrameDrawn`, cleared with the hit map at
the top of `View`); the global browser's `previewPeerBox()` already refuses when
the preview is not drawn.

**Do not add a second compositor, a second border rule, or a second divider
renderer.** If a behaviour belongs to windowing, it goes in `paneframe`; if it
belongs to one surface's content, it goes in that surface's host file. Both
surfaces then get it at once.

Tests that hold this: `internal/paneframe/paneframe_test.go`,
`internal/plugins/workspace/pane_peer_chrome_test.go`, and
`internal/overview/pane_peer_chrome_test.go`.

### The header's layout button is part of the same model

A pane can be **moved**, not only resized, and that entry point lives in the same
chrome the drag handle does. `internal/panereposition` owns the shared
interaction policy — the modal controller, the header adapter, the structural
fingerprint, and the graft helpers — while `panelayout.PlanMove`/`ApplyMove` own
the structure. There are three hosts, and all three get it: project Workspaces,
global Sessions, and the app content decks.

- **Reserve.** `panereposition.ReserveMovableHeader(width, movable, hasClose)`
  wraps `ui.ReserveHeaderControls` and returns the tab strip's width plus each
  control's column. Each host binds it once per frame in its own
  `reserveHeader`/`composeHeader` pair, and every header renderer, tab strip and
  region on that surface goes through those — a strip laid out for one reserve
  while the header composes another is how a tab click lands on the wrong tab.
  The **drop order as the row narrows is layout first, close `×` last**,
  all-or-nothing per control: a clipped button is a target whose meaning cannot
  be recovered.
- **`movable` comes from the tree** (`panereposition.Movable`): false with no
  tree, and false for a tree of one leaf, because `PlanMove` refuses every
  destination on a single leaf. A header with no lea
03

Trust audit

SAFEgrade B · trust 89/100 Nothing in the source contradicts what it says it does. Grade A is reserved for packages that have also passed the behavioural sandbox.

LayerWhat it checksResult
L0Provenance & inventoryWARN
L1Static analysis of the codeNA
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfacePASS
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
none-observed
Network
none-observed
Shell
none-observed
Dependencies
pinned
Secrets in source
none-found

Findings (2)

MEDIUMInventory / provenance · inv.symlink · CWE-1104
.codex/skills
.codex/skills
Why it matters. link not followed
LOWInventory / provenance · inv.symlink · CWE-1104
GEMINI.md
GEMINI.md
Why it matters. link not followed

Gates applied: no_behavioural_pass.

Audited 2026-10-10 · audit v0.4.1 · source sha a69114b893d1full audit observations/trust-audit/skill/marcus__drag-pane.json · Report an issue / request a re-scan
04

Audit history

Every audit this skill has had.

DateSourceVerdictGradeScoreChange
2026-10-10a69114b893d1SAFEB89first audit
05

Questions

What does the Drag Pane skill do?

Use sidecar next to CLI agents for diffs, file trees, conversation history, and task management with td

Is Drag Pane safe to install?

The audit found nothing in the source that contradicts what it says it does, and graded it B (89/100). Grade A is held back for packages that have also passed a sandboxed behavioural run, which is why a clean skill reads B.

What can Drag Pane access on my machine?

The audit observed no filesystem, network or shell use at all in its source.

How current is this page?

The grade is for one exact copy of the source (a69114b893d1), read on 2026-10-10. The repository is watched, and a new audit runs when it changes — this is the first audit.

Advertisement