Releases: KenM76/scriptree
v0.8.0a5 — screenshooter forest/menu accept .scriptreeforest
Patch release on top of v0.8.0a4.
What's new
The screenshooter's forest and menu kinds now accept a
full .scriptreeforest file (the workspace container) as input,
not just a single .scriptree / .scriptreetree catalog.
forest kind on a .scriptreeforest
Each item in the forest file becomes a cell at a honeycomb
neighbour slot around the hub (inner ring first, outer ring on
overflow). The composite shows your REAL workspace layout as a
single PNG — same composition the live forest launcher produces
at startup, just rendered off-screen.
menu kind on a .scriptreeforest
Every item gets added to the forest's _members, so the merged
tree-popup populates with all of them. The captured menu matches
what the live ScripTreeForest pops up on a forest double-click
(header + search bar + sub-menu per item, nested ring sub-menus
included).
Usage
python screenshooter.py forest my-workspace.scriptreeforest --out workspace.png --cell-size 96
python screenshooter.py menu my-workspace.scriptreeforest --out workspace-menu.png --cell-size 96
Or via the new run_screenshooter.bat launcher (also v0.8.0a4).
Tests
2 new in tests/test_screenshooter.py write a small on-disk
.scriptreeforest fixture (tmp_path) and assert both kinds
round-trip successfully. Suite: 18/18 screenshooter tests pass.
Install
Download the zip, extract, and double-click run_scriptreeforest.bat
(forest workspace), run_scriptreering.bat (bare ring shell),
run_scriptree.bat (V1 editor), or run_screenshooter.bat
(headless screenshot tool — no args opens a GUI form).
v0.8.0a4 — launcher table fix + run_screenshooter.bat
Patch release on top of v0.8.0a3.
Fixes
-
README launcher table — previously claimed "two launchers" but
the project actually ships three. The primary entry point
(run_scriptreeforest.bat— the forest workspace) was missing.
Now lists all four entries: forest workspace, bare ring shell, V1
editor, and the new screenshooter launcher. -
run_screenshooter.bat(new). Double-click launcher for the
headless screenshot tool. With no arguments, opens
screenshooter.scriptreein the V1 editor so the user gets a
labeled form (dropdown of the 8 kinds — cell / form / tree /
editor / tabs / forest / menu — plus width / height / cell-size
spinners and a file picker). With arguments, CLI passthrough to
screenshooter.py. Same Python search as the other launchers,
so a portable install (withlib/python/vendored) works without
a system Python install. -
Vendored-pypi prelude in
screenshooter.pyso the script
runs on portable installs where PySide6 lives underlib/pypi/
rather than being installed system-wide. -
One stray Unicode arrow in argparse help that broke
cmd.exe's
cp1252 console on--help.
Install
Download the zip, extract, and double-click one of:
run_scriptreeforest.bat— the forest workspace (most users
want this).run_scriptreering.bat— bare cell + ring shell.run_scriptree.bat— V1 editor directly.run_screenshooter.bat— headless screenshot tool (GUI form
with no args; CLI passthrough with args).
v0.8.0a3 — screenshooter editor/tabs/forest/menu
Patch release on top of v0.8.0a2.
Screenshooter — four new kinds
The headless screenshot tool can now capture the views a tool author
actually wants for documentation:
editor— full editorMainWindowwith tree (left) + form
(centre) + extra-args / command-line / output (right & bottom).
When given a.scriptreetreeit auto-selects the first leaf so
every dock populates — no more "tree-only" capture with an empty
right side.tabs—StandaloneWindow.from_treecapture with one tab per
leaf tool. This is what a cell shows when single-clicked on a
.scriptreetree.forest— composite PNG of the workspace forest hub with the
catalog's cell docked beside it. Shows the user "what this looks
like attached to the desktop forest".menu— composite PNG of the forest hub with its merged tree-
popup menu rendered below. Shows the menu the user sees when
they double-click the forest.
Composition uses a new _capture_composite helper that
grab() -s each unshown widget and pastes them onto one canvas —
the underlying "no flash, no focus theft" guarantee is preserved.
Front-end screenshooter.scriptree dropdown updated with the
four new choices and descriptive labels.
Refactor
tree_popup.show_tree_popup_for split into
build_tree_popup_menu (builds + returns the QMenu) +
show_tree_popup_for (calls build then positions / exec()'s).
This is what lets the screenshooter capture the menu without
showing it.
Tests
6 new in tests/test_screenshooter.py covering each new kind +
the auto-leaf-select branch + the tabs-rejects-.scriptree
error path. Full suite: 1816 passed, 5 skipped.
Install
Download the zip, extract, and double-click run_scriptreering.bat
(the cell shell) or run_scriptree.bat (the V1 editor).
Usage
python screenshooter.py editor my-tree.scriptreetree --out editor.png --width 1200 --height 780
python screenshooter.py tabs my-tree.scriptreetree --out tabs.png
python screenshooter.py forest my-tool.scriptree --out forest.png --cell-size 96
python screenshooter.py menu my-tree.scriptreetree --out menu.png --cell-size 96
v0.8.0a2 — hover tooltip stays on-screen
Patch release on top of v0.8.0a1.
Fix
Hover tooltip no longer falls off the right edge of the screen.
Previously the tip was offset down-right of the cell's bottom-centre
with a fixed +12/+18 px offset; for cells parked near the right edge
of the screen most of the tip ended up off-display, and even on the
left side it sat noticeably far below the cell.
v0.8.0a2 centres the tip horizontally on the cell and parks it 6 px
below the cell's bottom edge. Both axes are clamped to the
containing screen's available rect — if the below-cell position
would run off the bottom edge the tip flips above the cell
instead.
Other
- Bundled
combridge.exeruntime is unchanged from v0.8.0a1. - Test suite: 1810 passed, 5 skipped.
Install
Download the zip, extract, and double-click run_scriptreering.bat
(the cell shell) or run_scriptree.bat (the V1 editor).
v0.8.0a1 — link/dock split + bundled combridge
First alpha of the v0.8.0 line. Bundled COM-bridge runtime
(lib/combridge/) plus a major rework of the cell-graph model
that powers the hexagonal-cell shell.
⚠️ Pre-release — tested in single-user desktop usage but the
link/dock split touches a lot of code. Back up your
~/Documents/ScripTree/(or wherever your.scriptreering
files live) before trying it on important layouts.
What's new
Cell graph: link vs dock split
The old _group_master_id field conflated two different
relationships. v0.8.0 splits them:
- LINK — tree-shaped membership (forest → rings → cells). Drives
the merged menu, save / close behaviour, autoload. - DOCK — spatial edge-adjacency. Drives the drag cascade and the
snap-commit dock writes.
Rings stay link-attached to the forest even when dragged out of the
forest cluster; only dock-attached siblings move along during a forest
drag. Cells dragged out of a ring stay put when the ring later
moves (was: they followed the ring around).
Auto-named rings + cleaner merged menu
Freshly spawned rings get a session-unique name (Ring 1,
Ring 2 …) shown in the hover tooltip and merged-menu header. The
forest menu now recurses into nested rings so a brand-new ring shows
up as a sub-menu (empty rings get a (empty) hint instead of
disappearing).
Shake-to-close rings (replaces auto-close on quorum loss)
Rings no longer disappear automatically when their member count drops
below 2. Shake a ring to get a Save / Close / Cancel prompt
instead. Forest is excluded (it never closes by shake).
Bundled combridge runtime
lib/combridge/ ships with the release zip. Includes the
combridge.exe host, the ComBridge.Core engine, and adapter
plugins for SolidWorks, Excel, Word, PowerPoint, and Outlook. Catalogs
that target a vendor app can run straight from the portable copy.
Drag-end behaviour
- Snap-shift on a cell propagates to every cell docked to it.
- When a ring docks to a cluster and some members would overlap other
cells, the master stays at its dock slot and only the overlapping
members get re-slotted individually (no more "ring bounces away
from its dock"). - Snap-preview overlay now shows when dragging a ring (previously only
cells got the dock-slot outline). - Closing the whole forest prompts exactly once per unsaved ring
inside (was: prompted for the forest itself too, producing two
identical-looking dialogs).
Tiling math centralised
New scriptree/shell/tiling.py module owns honeycomb slot-position
and polygon-collision math; layout.py, snap_engine.py,
group_layout.py, and the layout_sim developer tool all
delegate to it.
Test suite
1799 passed, 5 skipped (intentional spec-change skips on the now-
disabled quorum-loss auto-close path).
Install
Download the zip, extract, and double-click run_scriptreering.bat
(the cell shell) or run_scriptree.bat (the V1 editor). The
bundled combridge means catalogs that drive vendor COM apps work
without a separate install.
v0.6.38 — membership self-heal + slot-aware drag cascade
What the v0.6.37 trace exposed
Cells with parent=forest, slot=set, NOT in forest._positioned — they were correctly linked but got "left behind" when you dragged the forest. Also phantom ids in _positioned (leftover from closed pair-masters) and one cell with parent=None, slot=set (orphan).
Root cause: the snap-commit pair-master spawn path mutates membership in multiple steps; failure at any step leaves inconsistent state. Fixing each of the 60+ mutation sites would be a multi-session refactor.
What this release does
_audit_membership() — defensive self-heal on every master drag
On every mousePressEvent for a master, walk _members + _positioned, repair four kinds of corruption in place:
- Phantom ids in
_positioned(no registry entry) → removed - Cells in
_membersbut registry has nothing → removed - Cells linked-with-slot but not in
_positioned→ added - Orphan cells (parent=None, slot set, but in
_members) → reparented
Every fix is logged via the layout_trace AUDIT_* events so the next diagnostic session can see what was healed.
Drag cascade uses link+slot as ground truth
GROUP_MOVE now iterates the union of _positioned AND cells whose parent + slot independently point to this master. A stale _positioned can no longer strand a docked cell.
Tests
1745 passed (4 new audit cases).
v0.6.37 — two bugs nailed by the v0.6.36 trace
Bugs fixed (both diagnosed from the v0.6.36 diagnostic log)
1. Cells stacked at spawn instead of laid out
The trace showed every new cell spawning at the master's left-edge position (e.g. 92,1311) with NO LAYOUT_RUN between cells. Only after some unrelated event triggered the next repack did all the stacked cells snap into honeycomb slots at once — what you saw as "started off spaced out".
Fix: forest_controller._spawn_item now calls the master's layout function after each cell is added, so every new cell lands on its slot as it appears.
2. Master snapping to its own descendants
25+ SNAP_COMMIT events in the trace had the forest snapping to one of its own children. When the forest is dragged, the children move with it (the GROUP_MOVE cascade), and the snap engine saw them as nearby snap targets — offering the forest a slot relative to its own children. That's the "highlighted docking is misaligned with the forest" symptom.
Fix: SnapEngine._tick now excludes the dragged source's descendants (recursive through any nested masters) from candidate snap targets.
3. Icons / overlay oversized — instrumentation added
No root cause from the v0.6.36 trace (SNAPSHOT showed all cells at size_px=56). Extended the SNAPSHOT to log widget_w/h + icon_scale per cell, so the next time it happens the trace will show whether logical size and rendered size diverge.
Tests
1741 passed.
v0.6.36 — diagnostic tracing for layout issues
What's new
Verbose diagnostic tracing of every layout-affecting event. Per user request: "tie up cpu cycles if you have to just to do the tracking and logging. get all the data you think you need."
The log is written to %TEMP%/scriptree-layout-trace-<stamp>-<pid>.log (path printed to stderr on startup). Every event is one grep-friendly line.
Captured events
CREATE— cell constructionMOVE— every moveEvent with from/to/delta/drag-state/slot/parentPRESS/RELEASE— drag boundaries with full world SNAPSHOTsGROUP_MOVE— master drag cascade with delta and member listLAYOUT_RUN— every_compute_layoutcallSLOT_ASSIGN— slot assignments inside_compute_layoutLAYOUT_MOVE— every position write from_compute_layoutAUTO_HIDE/AUTO_SHOW— visibility flipsCOLLAPSE_START/EXPAND_START— animation kickoffs with snapshotsSNAP_ATTACH/SNAP_DETACH/SNAP_COMMIT— snap-engine activitySNAPSHOT— full world dump at key transitions
CPU cost
Tracing is event-driven — no continuous timer. When idle, no events fire, no CPU spent. The idle-CPU contract is preserved. Disable with SCRIPTREE_LAYOUT_TRACE=0.
Other changes
__build_date__is now local time (was UTC). About dialog reflects this immediately.
Tests
1741 passed.
v0.6.35 — slot-based layout algorithm wired into startup
Algorithm-first refactor: startup path
This version ports the proven slot-based layout algorithm (designed + tested in a pure-Python simulator first, see tools/layout_sim.py) into the live cell shell. The startup path now uses it; everything else (drag, snap, collapse) still rides the older code paths until the next session ports them too.
What you should see
- No more startup jumble. When the forest opens, every cell snaps onto a free honeycomb slot around its master via the algorithm — same code the simulator proves correct across 14 scenarios.
- No more "cells at the forest's centre." The algorithm reserves the back-toward-parent slot for any docked master, so a child of a ring can never land on the forest's centre point.
- No more cross-cluster aliasing. The slot allocator runs a global collision check against every other placed cell in the workspace; two cells in different clusters can no longer hash to the same world coordinate.
Algorithm proof
tests/test_layout_algorithm.py runs all 14 simulator scenarios as pytest cases — including the user-reported nightmare cases (forest into corner, 20 random forest positions, nested collapse during outer drag, forest resize, floating cell survives collapse). Any algorithm regression fails CI.
What didn't change yet
- Drag-snap, collapse animation, live-edge-reflow, and master-drag cascade are still on the older code paths. The new model + the older mutations co-exist; the canonical layout function overrides positions during repack. Porting the rest is tracked in
help/LLM/scenegraph_layout_plan.mdand is the next focused session. - No new periodic timers. The idle-CPU contract is preserved.
Tests
Full suite: 1741 passed.
v0.6.34 — revert layout races, instant startup, collapse safety belt
Why this revert ships
The v0.6.32 additions (overlap watchdog, drag cascade, sibling redock) introduced races that caused random cell movement, disappearing cells, and "click forest does nothing" — the layout system has too many independent helpers fighting for the same data. This release rolls those back to a known-working baseline and adds two narrow fixes so the app is usable while the proper scene-graph refactor is planned.
What changed
Reverts (v0.6.32 helpers removed)
- Overlap watchdog (
_resettle_overlapping_neighbours) — was settling cells during collapse animations - Cascade translate (
_cascade_translate_positioned) — replaced with an inline self-contained shift inside the existing drag handler - Sibling redock (
_try_redock_to_sibling) — the re-link path was the cause of cells disappearing when the forest moved to a corner
Targeted fixes
- Instant startup layout —
_repack_members(instant=True)at forest open so members snap onto canonical slots immediately; no 260 ms eased animation from stale-saved positions (which looked like jumble). - Collapse safety watchdog — if a collapse / expand animation's
finishedsignal is lost, a 1 sQTimer.singleShotforce-clears the state so the next click isn't ignored by the animation-in-flight guard.
Looking forward
The underlying problem is the data model: cell positions are stored as absolute screen coordinates and seven independent helpers mutate them. This release stops the bleeding; the real fix is a slot-based scene graph (each cell stores a slot index relative to its parent; one layout tick replaces all the scattered helpers). Full plan in help/LLM/scenegraph_layout_plan.md.
Tests
1724 passed.