Repository navigation
Releases
Scriptoscope 0.9.0
Scriptoscope 0.9.0 is a minor release on 0.8.0. It adds scheme authoring and moves window input closer to the classic Window Manager. It continues 0.y.z pre-launch development (#168). GitHub release only; no npm publication.
Behaviour change: clicks pass through transparent frame pixels (#597)
- Managed windows now default to
regionhit mode, as in Kaleidoscope 2.3.1. A press between a scheme's merlons, ornaments or studs reaches the page behind, with its default actions. - A press on page content deactivates the active window, as a click on the desktop did on the classic Mac.
- To keep the old behaviour, set
data-scriptoscope-hit="box"on a window,{ hit: 'box' }onWindowManager.add, ornew WindowManager({ hit: 'box' })for the whole page. Windows insideopenModalkeep the box automatically. parseWindowAttrsno longer defaultsstateto'active'whendata-scriptoscope-stateisn't declared (#614).
New: scheme authoring (#540)
tools/theme-author/writes new Kaleidoscope schemes from code as real resource forks that load in Scriptoscope and in the original Kaleidoscope 2.3.1.- Workflow tools:
npm run author,paint-over,sim8andcapture:authoring, plus a dev-only preview page. - The Scriptoscope Reference Native Theme in
authoring/schemes/, and guides starting atdocs/authoring-a-scheme.md.
Changed: window input
- A first press on an inactive window's title widget or grow box only activates it (#614).
- Region windows use native hit targets, so wheel and pointer input reach native content, nested scrollers and the page (#631, #635).
- New
WindowManager.dispose()(#621) andhit/hitEffectivereporting onWindowManager.describe. - Window and control rendering allocates less (#643).
Fixed
- Collapsed windows draw only their title-axis sides, as Kaleidoscope does (#617).
- Window titles fit their slot using the complete title's ink, so substitute-font descenders and cedillas aren't clipped (#637, #624).
- Utility windows use their alternate pressed-widget art, and popup windows ignore collapse (#624, #625).
- A single scroll bar reaches the content edge when the scheme has no grow-box art (#640).
- Movable-modal, movable-alert, popup and collapsed titled-utility windows show their title text again (#540).
- Focus, Tab order, Shift+wheel and gesture fixes (#619, #621, #628).
Known limitation
- On Linux WebKit (WebKitGTK), title fitting and title painting can differ by one colour step or a faint edge pixel, because WebKitGTK picks its canvas backend by canvas size. This isn't visible. The affected checks are expected failures on Linux WebKit only; the fix is tracked in #646.
Contributor workflow
npm run check:schemesis part ofnpm run gates, andnpm run bench:rendermeasures render allocations.- The release gate caught three regressions that had landed without running the WebKit and Firefox jobs. They were fixed before tagging (#645, #647).
The final release gate passed on the exact tagged commit, and the tag check confirmed it.
Runtime size versus 0.8.0 (npm run loc:src -- HEAD --base v0.8.0):
| non-test source | 0.8.0 | 0.9.0 | delta |
|---|---|---|---|
| logic | 16654 | 17661 | +1007 |
| cited engine tables | 2380 | 2380 | 0 |
| total | 19034 | 20041 | +1007 |
Full details are in the CHANGELOG.
Scriptoscope 0.8.0
Scriptoscope 0.8.0 is a minor release on 0.7.0, and the first cut from main since the v2 integration branch was retired. It's 0.8.0 rather than a patch because of one breaking sizing change; everything else is fixes. It continues 0.y.z pre-launch development (#168).
Breaking: auto-sized windows now fit their chrome inside the element's box (#526, #541)
- A window with no declared size used to take the element's measured size as its content size and draw the frame outside it.
- The measured size,
data-scriptoscope-extra-width/-heightand pxmax-width/max-heightcaps now bound the whole window. Thick-framed schemes therefore get a smaller content area: on dolphin-som, the measured width less 116 px. - To keep a fixed content area, declare
data-scriptoscope-width/-height. These are still content sizes, as areWindowManager.addwidth/heightandsetContentSize. - New:
outerSizeonWindowManager.add,WindowManager.setOuterSizeandWindowManager.chromeExtent, for sizing by the outer box.
Fixed: windows and controls behave like the classic Window and Control Managers
- Scroll bars act on the part under the pointer, with auto-repeat (#567). Inactive windows draw inactive scroll bars, and a first press on one only activates the window (#594). Scroll arrows sit clear of the grow box (#524).
- Title-bar and grow-box presses that don't move are no longer drags or resizes (#552, #561), and cancelled drags revert (#563). Outer bounds hold through collapse, zoom and restore.
- Keyboard focus entering a window activates and raises it (#550). Focus and control identity survive re-renders (#525, #533), and title widgets follow the visual tab order (#537).
Fixed: rendering
- Dialog and alert bodies use the scheme's dialog colour, from Kaleidoscope's PACH 130 patch (#540).
- Disclosure triangles draw the scheme's own art for each direction and state (#595).
- Themed sliders let a patterned window body show through (#596).
composeButtonreportsunavailableinstead of returning a blank button on the five built-in-frame schemes (#608).- Disposed themes are rejected in every browser (#589).
Fixed: demo
- Showcase text, links and picker tiles reach WCAG AA contrast on every scheme.
- Ready timing and persisted layouts are fixed.
Documentation
- New
docs/interaction.md, a consumer reference for every interactive behaviour. llms.txtand the integration docs no longer describe removed APIs.- New decode specs: slider host background (#606), window structure regions and hit-testing (#610), and corrected kDEF dispatch labels (#615).
Contributor workflow
- All work lands on
main;v2is archived as tagarchive/v2. - CI is tiered (#598). PRs run Chromium rendering shards and exact Linux goldens. A release-tier gate runs Firefox/WebKit interaction contracts, the extended matrix and the scene fixtures, which are now required (#607).
Final release gate passed on the exact tagged commit, and the tag check confirmed it.
Runtime size versus 0.7.0:
| non-test source | 0.7.0 | 0.8.0 | delta |
|---|---|---|---|
| logic | 16081 | 16654 | +573 |
| cited engine tables | 2329 | 2380 | +51 |
| total | 18410 | 19034 | +624 |
See the CHANGELOG for details. No npm publication accompanies this GitHub release.
v0.7.0
Scriptoscope 0.7.0 hands window and control lifetime to the application. Explicit promotion primitives now cover what the old declarative mount did, and two more families move onto decoded engine drivers. It continues 0.y.z pre-launch development from 0.6.0 (#168). v2 is an internal branch label, not a 2.0 release or the 1.0 threshold.
Breaking changes and migration:
mountDeclarative,mountOwnedDeclarativeand their mount-specific types are removed (#491). Applications own source selection, attachment, theme replacement and teardown through the public promotion and restoration primitives. You can also adapt the separatemountExplicitPageexample helper. See explicit host migration.interactiveCheckbox,radioGroupand their option types are retired in favour of native inputs, labels andchangelisteners (#484).interactiveButtonstays, and now returns a nativetype="button"element.- Custom push allocators must not rely on dimension getter reads that were removed (#497).
- Minifier-generated function and constructor name strings may vary, under the narrow generated-name policy (#507).
Added:
- Owned decoded-raster loading:
loadOwnedThemeandloadOwnedKaleidoscopeScheme, with asynchronous image export and explicit disposal (#480). The eagerLoadedThemeloaders remain supported. - An optional
scriptoscope/rendererentry for consumers that already have a theme (#489). - An integrated capability collection in the demo.
Engine:
- Whole-header and list-column composition, and segmented tabs, now use typed engine drivers. The replaced header painters, the three-slice tab fallback and the tab-body helper are removed.
- Unsupported tab metadata now returns null with a distinct diagnostic instead of drawing the legacy body.
Fixed:
- Windows inside
transform: scale(), rotated or skewed ancestors follow the pointer when dragged and resized (#518, #521). - In those same ancestors, promoted windows take their layout size, and slider and scrollbar pointers follow the control's own axis (#522).
- Dragging on a scrolled page, secondary clicks on themed buttons, tab-panel semantics and title-widget reachability (#381) are also fixed.
Not delivered: Studio, the bevel experiment and the header/allocator prototype (#475, #483, #500) closed unmerged. The Windows 95 titlebar reference adds zero exact browser-pixel oracles. Native typography, device rendering and whole-control fidelity remain unknown.
Final release CI passed on the exact release tree.
Runtime size versus 0.6.0:
| non-test source | 0.6.0 | 0.7.0 | delta |
|---|---|---|---|
| logic | 17094 | 16081 | −1013 |
| cited engine tables | 2237 | 2329 | +92 |
| total | 19331 | 18410 | −921 |
The runtime shrinks overall. The removed declarative scanner, persistence and cascade, the retired checkable wrappers and the replaced painters outweigh the new drivers and QuickDraw primitives.
See the CHANGELOG and the migration guide for details. No npm publication accompanies this GitHub release.
v0.6.0
Scriptoscope 0.6.0 moves push buttons, default rings, checkboxes and radios onto the decoded engine, completing the remaining families in #459.
Resource selection preserves signed IDs, selected owners and source occurrences, and distinguishes absent resources from malformed or unknown dependencies. Sampled preparation respects clipping, cancellation and captured ownership. Visible labelled native/CSS replacements preserve focus, disabled behavior, form activation and No Theme restoration when themed painting is unavailable. The installed public VERSION now agrees with the package version.
Migration notes:
- Checkables allocate a nominal 20px single-line extent and preserve full source bounds. Consumers should accommodate that allocation; affected native fallback layouts gain 2px of ordinary flow.
- Public mode 5 transfer requires aligned 1:1 source/destination geometry.
- Canonical signed art replaces retired named aliases and cross-state substitutions. Malformed selected dependencies reject explicitly.
These layout and fallback rules are modern compatibility policies. Native typography, provider/cache/device/transfer behavior and unsampled outcomes remain unknown. The 39 unknown window rows and six unsupported slider cases remain unchanged; this is an incremental release, not the all-family 1.0 milestone.
Fidelity accounting withdraws 15 current verification claims for normal, pressed and inactive empty push-button outputs in System7 Nostalgia Silver, Apple Platinum 2, Black Platinum, Platinum 8 and Slimes. Those paths have unresolved no-cinf preparation dependencies and remain unknown. Historical captures, prior matching executions and all 1,832 declared obligations remain preserved. Nine other exact outputs retain their comparisons under narrower execution registrations.
Four named screenshot sheets retain their canonical comparisons and also recognize one independently reviewed complete alternative image each for a disabled CSS button edge. The strict alternatives preserve every other pixel; the browser raster trigger remains unknown. This regression policy makes no new native fidelity claim.
Final release CI passed all 530 browser contracts, 36 Linux screenshot sheets covering 1,260 cases, the installed-package consumer contract and full requirement-execution checks. All 36 sheets used their canonical comparison; their observations identify a clean CI merge with the exact reviewed 0.6.0 release tree. Independent review also verified the alternative-image acceptance and rejection of changed glyph, artwork, edge and outside pixels.
Runtime size versus 0.5.0:
| non-test source | 0.5.0 | 0.6.0 | delta |
|---|---|---|---|
| logic | 16150 | 17094 | +944 |
| cited engine tables | 2147 | 2237 | +90 |
| total | 18297 | 19331 | +1034 |
The growth covers drivers/facades and explicit resource, preparation, diagnostics and lifetime handling. The replaced controls.ts drawers lose 239 net lines; the overall runtime grows.
See the CHANGELOG for migration and validation details. No npm publication accompanies this GitHub release.
Scriptoscope 0.5.0
Fourth incremental release from the v2 integration branch (#459,
#460–#466): follow-ups to the existing window, progress and slider paths,
process boundaries, diagnostic links and contributor documentation. v2
remains the integration branch between releases (DECISIONS #8). Push buttons and
checkables remain future engine migration work; their specs do not ship those
migrations in this release.
-
Clean-room process boundaries (#462): isolate independent oracles and verifier material from runtime implementer reading; retain separate spec, implementation and verification ownership.
-
Contributor orientation (#459, #466): distinguish the current incremental v2 engine from historical renderer resets, route runtime implementers through the safe brief before any source-reference catalogue, and preserve role-specific evidence boundaries.
-
Declared slider resource chain (#427, #459): the opt-in ordered
cinftier now supplies gate, corner and groove metadata together. Every declared provider must be complete before admission; missing declared metadata cannot borrow archive metadata. Ordinary resource resolution remains unchanged. -
Slider pointer geometry (#427): imperative sliders use the engine's committed thumb travel, direction, exact-value grab and track-click centering for both ordinary and declared layouts.
-
Breaking slider metadata cleanup (#427): remove
ChromeElement.sliderLayoutCinf,SliderLayout.endpointPolicy, the decoded slider summary fields and retired slider admission helper exports. Keep the preparation/binding option and generic IDs/data/body views;sliderLayoutEnvironmentis now only the opaque frozen{ environmentId, bindingId }marker. Use engine traces for selected provider provenance. -
Window titles (#459): load raw title color samples and draw TX7's shadow before the foreground, preserving the declared substitute-font sizing, clip and alpha-over policies. When no glyph plus ellipsis fits, retain the ellipsis alone. The corpus-wide
window.title-fitassertion checks that fitting titles stay whole; it does not claim original-font pixel equivalence. -
Collapsed utility windows (#423, #459): route the exact collapsed no-title utility type through the built-in frame engine on all five built-in schemes. Collapsing hides caller content and makes it inert and unfocusable while preserving its body slot, identity and value; expanding restores content and focus behavior.
-
Progress follow-ups (#459): preserve the
progressSetDataflag byte, validateProgressIdlephase inputs and enforce the public draw-path invariant. Correct the FB9 corpus count to 36. -
Breaking title metadata cleanup (#459): remove
ComposedChrome.titleFillSrcXandtitleFillRgb. Regenerate custom sliced-window manifests to supplyWindowType.titleSamples; without exact samples, source-backed title colors remain unspecified and the title is suppressed. Built-in procedural titles retain their existing presentation. -
Breaking inspector cleanup (#436, #459): remove the deprecated
ThemeProgressModeltype,ThemeInspector.resourceRoles.progressandprogressSummary. Progress rendering remains selected by the engine'scinfgate; inspector artwork roles no longer predict the drawing path. Consumers must stop reading the removed metadata. -
Diagnostic theme links (#459): honor valid URL hash themes and playground settings on initial load, hash changes and Back/Forward traversal, including rapid switching. The manual visual-baseline command includes independent diagnostic hash checks.
-
Window ledger housekeeping (#459): the 39 retained-unknown flag, mask and remaining-fill obligations now cite their completed independent review. No status, evidence claim or case closure changes. The routine map points to the current window engine and drawing facade, replacing references to deleted compositor functions.
Migration and limits (0.4.0 → 0.5.0)
- Stop importing
ThemeProgressModeland reading
ThemeInspector.resourceRoles.progressorprogressSummary; these deprecated
inspector fields are removed, with no replacement model predicting draw paths.
Progress selection remains with the engine'scinfgate. - Stop reading
ComposedChrome.titleFillSrcXandtitleFillRgb. Regenerate custom
sliced-window manifests with exactWindowType.titleSamplesfrom the original
resources. Without those samples, source-backed title colors are unspecified and
the title is suppressed; built-in procedural titles keep their presentation.
Do not infer samples from composed browser output. The shadow draws before the
foreground, retaining the substitute-font geometry (DECISIONS #13) and browser
alpha-over policy. These accepted feature cases do not establish original-font,
native text-transfer or device equivalence; remaining native conditions stay unknown. - Remove uses of
ChromeElement.sliderLayoutCinf, decoded slider summary fields,
SliderLayout.endpointPolicyand the retired slider admission helper exports.
Keep the opt-in preparation/binding option and generic IDs/data/body views.
sliderLayoutEnvironmentis only the opaque frozen{ environmentId, bindingId }
marker; use engine traces for selected provider provenance. A declared provider
must supply gate, corner and groove metadata completely, without borrowing missing
declared metadata from the archive tier. - Ordinary imperative sliders now use committed thumb travel and direction, retain
the exact value when grabbed, and center the thumb on track clicks, matching the
declared path. This is a pointer geometry correction, not a new slider family. - Preserve existing golden capture provenance and independent approval: reviewed
browser goldens establish regression stability only. This release neither
recaptures goldens nor promotes ledger status, original-reference eligibility or
all-family fidelity. The 39 window obligations retain their unknown status.
Runtime size (npm run loc:src -- HEAD --base v0.4.0)
| src/ lines (non-test .ts) | v0.4.0 | 0.5.0 | delta |
|---|---|---|---|
| logic (all src except engine tables) | 16112 | 16150 | +38 |
| engine tables (cited data) | 2145 | 2147 | +2 |
| total | 18257 | 18297 | +40 |
Measured with the repository tool against v0.4.0. The net logic growth includes
an 86-line typed declared-slider provider adapter accepted in independent #465
review: it routes complete declared metadata through the engine resource chain.
Legacy slider metadata/admission branches and title sampling branches are deleted;
the title, pointer and progress follow-ups account for the remaining changes.
The release metadata update preserves the accepted runtime behavior.
Release implementation and review: #459, #460–#467. No npm publication is part of this release.
Scriptoscope 0.4.0
Third incremental release from the v2 engine branch (#378). Three more families move onto the decoded Kaleidoscope 2.3.1 engine: the window recipe for the 13 schemes with a wnd# recipe, the slider and the progress bar.
- Window recipe on the v2 engine (#432, #444). Layout, title, widget remap, draw and hit test follow the decoded kDEF window widgets (
docs/spec/engine/window-widgets.md), fixing runtime divergences F1–F10. Mostwnd#windows change slightly; see the migration notes.- Accessibility divergence (DECISIONS #12): title-bar widgets on inactive windows stay focusable and keyboard-operable, although the original makes them inert.
- Font substitution (DECISIONS #13, #453): the runtime can't draw the original's condensed title face, so titles are sized and truncated to the plate for the font we draw. They also move down when our taller font would clip their tops.
- Slider on the v2 engine (CDEF 3; #419, fixes #407). It adds
pressedPart,variant,tickMarks,thicknessandbackground. Vertical sliders now put 0 at the bottom. - Progress bar on the v2 engine (CDEF 5; #440, #446). It adds integer
rangeandindeterminate/phase(DECISIONS #10, #11). The 8 schemes without progress art now draw the original's own procedural bar, andcomposeProgressnever returnsnull. - Loader: the public
loadKaleidoscopeScheme(npm export and the Pagestheme-loader/module) passes the engine'scinfand icon-blit ids by default (#428, #434, #439; fixes #431). Dropped archives get the same output as bundled themes. - Fidelity ledger: 340 verified, 0 mismatched, 6 unsupported and 1,486 unknown of 1,832 obligations. In 0.3.0 it was 257 verified and 33 mismatched.
Also in this release
- Specs:
- Tooling:
lane:readynow rejects silent reverts of base commits, and CI builds the demo (#447).
- Known gaps:
Changes
- v2 engine:
wnd#windows now lay out and hit-test through the decoded 2.3.1 window recipe (engine familywindow,docs/spec/engine/window-widgets.md). A new driver (src/engine/families/window.ts, tables insrc/engine/tables/window.ts) follows the spec rows: part-code verdicts (PV), layout sums and placed ends (LS), the too-short step (TS), the allocation path (AP), per-cell widths with the unclamped budget (AW), the titled side (TT), cell rects (CR), the widget remap (RM), the pressed-widget draw (WD9) and the widget hit (HT).composeChrome.tsis now a facade over it; the legacy classifier, too-short negotiation, half split and placement-based widget remap are deleted. It fixes the window-widgets §7.2 findings F1–F10: a collapse box inside a dropped code-10 cell is now empty (not drawn, not hit, RM6); below the minimum the budget goes negative instead of clamping (AW8); the title plate is placed on the content centre withW = SW + marginsand drops at ≤ 2 px of room (TT2–TT9); close, zoom and collapse are separate flags (F7); the collapse gate is re-read on every layout (F5, LC3); widget hits need the pressed-strip cicn and its mask (HT3–HT7, F8; inactive windows keep keyboard-reachable buttons, a runtime policy where HT2 would make them inert); the cell bands use the template cicn bounds (CR2/CR4, F6).
Migration notes (window recipe)
-
Pixels change on most
wnd#windows (engine diff: 1530 of 1656 existing window cells, plus 156 new popup-family cells, each blessed intests/engine-diff/expected/window.jsonwith its spec row). Each side now ends at its placed endP[N] = S[N] + content delta(LS7, after the AW7 walk), so growers no longer absorb template slack past the last border. Untitled windows no longer draw the code-6 title bezels or plate (TT4, AW5); titled windows get a plate exactlySW + marginswide on the content centre instead of the measured width plus 18 px of padding, and at the template size a too-narrow side drops its title (TT3) rather than overflowing the frame. -
composeWindowChromeoptions:titleWidthPxis nowSW, the bare title width (renderWindow no longer adds padding). New optionaltitleWidthCondensedPx(TT2; default the TT2a declared valueSW − titleLength),titleLength(default 1 whenSW > 0),active(drawActive, default true; renderWindow leaves it set),widgetCicn(the WD11 pressed strip,cicn −14330) andpressedWidget. -
ComposedChromegainswidgets(the reachable widget hit areas),hitWidget(x, y)(the HT rows, mask included) andlayout(the engine layout).shadeClearedis removed.titleRegionis now the code-5 plate, not the run of 5/6 cells. NewtitleRect: the remapped title rectt4p(TX3). -
resolveTitleWidgetRects(wt, composed)returnscomposed.widgetsforwnd#windows; it no longer remaps fromplacement. Behaviour change: a cleared or emptied collapse box has none, and a press inside a widget rect but outside the strip's mask falls through to the window (HT7). renderWindow loads the pressed strip through the engine resource chain; without it no widget is hit or drawn pressed. -
The title text follows the decode (TX2–TX5, TX8): left-aligned in the remapped title rect, baseline 4 px above its bottom, clipped to that rect + 2 px, truncated only when it does not fit; it is centred on the content (the layout centres the rect, TT6/TT7), no longer on the plate. Untitled windows and an empty title rect draw no text. The runtime has no condensed face, so TX5 only truncates, and TX7's shadow string and sampled colours are not drawn (runtime colour rule kept).
-
popup-windowtitled sides now follow the decoded popup placement (AP1, PP1–PP7) with the creation values of the popup data (pdMode 0,pdLen 33): a 13 px plate 10 px in from the content's left edge, whatever the title; the titled-side rows do not run there. This default visibly truncates every popup title to the 13 px title rect (PP6/PP7 declare the creation values; who changes the popup data later is not decoded). Popup windows also draw the WD6 raw template blits: the type-5 and type-6 rect-list art at the content's top-left and top-right corners and the 15×15 corner ending at the body's bottom-right at the content's bottom-right (under the DOM content). -
Sides now draw in the decoded order (top, bottom, left, right) with CopyMask (WD4, qd-primitives Q5), so transparent template pixels no longer overwrite earlier sides.
-
The leading region
[0, S[0])and the trailing region past a side's end are left unpainted, as in the original (no full-draw routine paints them, window-widgets §6 Q3): the content behind the window shows through there. The placement map no longer reports them (no segment 0 or −1 slices). -
Inactive windows keep focusable, operable widget buttons, although the decode makes them inert (HT2), so keyboard and assistive-technology users can act on background windows; widget art still follows the decode (DECISIONS #12).
-
Pressed
wnd#widgets draw the scheme's pressed-strip cicn (WD9) instead of darkening the template; a scheme without it draws nothing. -
The L4 parity lock
src/engine/windowChromeParity.*is removed. The engine diff covers its archives, window types, states and titles at native, 97×53 and 320×160, but not its 240×120 size.tests/engine-diff/cases.mjsacceptswindow-widgets.mdrow ids for the window family. -
Window titles fit our title font (DECISIONS #13). Two runtime limits of #432's decoded title draw are fixed. The runtime has no condensed face and draws titles at full width, so
composeWindowChromenow defaultsSWctoSW(TT2 no longer narrows the plate below the drawn text). Our title font is taller than the original's, so when its ascent would start above the remapped title rect, the baseline moves down by exactly that overflow, and no glyph is cut at the top. The decoded clip and baseline are kept otherwise.
Migration notes (window title fit)
-
composeWindowChrome({ titleWidthCondensedPx })now defaults totitleWidthPx(SW). It used to default to the TT2a valueSW − titleLength. Pass a measured condensed width to get TT2's narrowing. -
Titled-utility titles on 1984, 1990, floppies, windows-31 and windows-95 now draw 1 px lower, inside the title rect: their letter tops were cut before. No title's descent leaves the rect (checked on every wnd# scheme with a descender title). Document-window titles are unchanged.
-
Titles truncate to the plate: the truncation room is the title rect + 2 px (TX5) but never past the plate's right edge, so on dolphin-som and evolution, whose title rect ends flush with the plate, a truncated title no longer draws 1 px past it. The clip stays the decoded title rect + 2 px. The room never drops below the title rect's own width, so templates whose plate is narrower than the title rect (floppies, 1138) keep titles that fit whole.
-
Unchanged by design: titles are left-aligned in a plate exactly
SW + marginswide, so on schemes whose title rect fills the code-5 cell (evolution, dolphin-som) the text starts at the plate's first column. BeOS tabs follow the TT rows (no extra plate padding). -
v2 engine: the progress bar now draws through the decoded 2.3.1 progress CDEF 5. A new driver (
src/engine/families/progress.ts, tables insrc/engine/tables/progress.ts) followsdocs/spec/engine/progress.md. It forces the control rect to 14 rows (RECT1). The path is chosen by thecinfgate: inactive (hilite 254 or 255) needscinf −10077, and without it the whole bar draws with the active ids (GATE1/GATE1a). Nocinf −10080or a missing frame cicn...
Scriptoscope 0.3.0
Second incremental release from the v2 engine branch (#378). The five schemes with no wnd# recipe (apple-platinum-2, black-platinum, platinum-8, slimes, system7-nostalgia-silver) now draw Kaleidoscope's own decoded built-in window frame instead of the old corner-sprite approximation.
- Built-in window frame on the v2 engine (fixes #387, #414). Document, dialog, alert, movable-modal and utility windows, including their collapsed forms, draw through the decoded kDEF built-in window definition. The window footprint changes; see the migration notes below. The old
composeCornerSpriteChromeexport is removed. - Known gap: collapsed no-title utility windows still render expanded on these schemes (#423).
- Slider: the engine slider (#416/#419, issue #407) is held for 0.4.0.
- Fidelity ledger: 257 verified obligations, up from 229 on v2 at 0.2.0 (window families 1.2.0–1.4.0; #409, #418, #424). The ledger also records 33 known
composeSlidermismatches (#407, slider ledger 1.1.0, #408), which the 0.4.0 engine slider resolves.
Also in this release
- Decisions (#405): DECISIONS #7 (masked fallback) approved, and #9 (slider
pressedPart) added. - Slider rule rows (#408): CDEF 3 rule rows, with the current slider's disagreements pinned against #407. Tests and ledger only; no engine code.
- Icon companions: a mismatched opaque icon-blit companion now falls back to the masked asset and is traced (DECISIONS #7, #413). No pixel changes on the corpus.
- Dead-code cleanup (#410): unused internal exports are dropped, the resource-role rubric is de-duplicated, and the manual visual-baseline browser suites get an
npm run test:visual-baselinesscript. - Engine-diff gate hardening (#411):
- it runs the base copy of the harness in its own process;
- it accepts ledger evidence ids;
- it compares against the merge-base for PRs into main.
Release PRs must declare every changed family (tests/engine-diff/README.md).
- Specs:
Changes
-
Add
npm run loc:src(scripts/src-loc.mjs). It reports non-testsrc/line counts, split into engine tables and logic, with an optional--base <ref>delta measured from the merge-base. CONTRIBUTING now asks every PR that changessrc/to paste this table, every family migration to delete the legacy path it replaces, and every release to report the trend against the previous tag. -
v2 engine: utility windows of the five built-in-frame schemes now draw Kaleidoscope's decoded utility frame (procedural-frame §9, revision 3; fixes #414). This covers titled, side-floating, no-title and the collapsed variants. Before this change these windows had no frame. Horizontal bars draw UFH1–UFH12 and vertical (side) bars UFS1–UFS12. Collapsed windows draw a 2-px box (UFC1–UFC6). Every frame shape gets the drop shadow (UFT3). The art is cicn -14316 / -14320 for horizontal bars and -14315 / -14319 for side bars. Line colours are sampled from that cicn: fill P(4, 3), text P(5, 3), shadow P(7, 3), with transposed points on side bars. Stripes are cicn -14314 (side: -14318 first), tiled 1:1 in a 9-row band between the title limits. The title is erased into the band, then drawn with a shadow pass that is skipped when the shadow colour equals the fill. Too-long titles are condensed and truncated. Widgets are 10 × 10 boxes that plot 16 × 16 glyphs (-14320 / -14318 / -14319). The interior fill is painted last, around the stripes, the title and the widget boxes. Widget presence and the bar height are now derived from the window record: H is 15 with a title and 13 without, or on a side bar, and narrow windows drop widgets against a 7-px outset (UP1–UP4). The declared per-slug
utilityWidgets/utilityTitleddefaults are removed. The normal 16 × 16 grow box (-14313 / -14317) is drawn by message 6. The small one (variation bit 4) is part of the frame and crops the cicn's top-left 11/15, unscaled (UGB2). Utility hit testing is UH1–UH8: widget hits are the box inset by 1. Corrections to #412's document family: grow boxes are copied through their mask (GB1/GB3). A draw with a part below 4 clears the shared toggle bit; part 258 flips it in the document family only (TG1–TG4, UM2). The narrow-window drops follow WP1–WP4: without a close box the zoom box is never dropped. Colour-table "entry n" is found by value (CT1–CT4). Message 6 draws its two scroll-bar lines (M6L1–M6L6). Hit rows are cited HT1–HT9. Engine-diff: all 1,005 cells seeded by #412 change, and 90 new collapsed no-title cells bring the family to 1,095. The 450 utility cells draw the frame. The 555 document cells change in the trace only: every corpus grow cicn is fully opaque under its mask, so the masked copy changes no pixel. Thewindowandscrollbarcells are unchanged. Not implemented: the procedural kind-5 grow box (GB4–GB6 / GL1–GL4, reached only with thin + grow, which no slug sets) and utility messages 7 and 8 (§9.10). No native capture backs this (§10 item 9).
Migration (utility windows, built-in frame schemes)
-
Utility windows of apple-platinum-2, black-platinum, platinum-8, slimes and system7-nostalgia-silver now have a frame. They are 4 px on the sides and bottom, with a 16-px bar (titled) or 14-px bar (untitled or side) and a 1-px shadow.
ComposedChrome.framereports the new insets. -
The side-floating utility window now shows its collapse box (the Kaleidoscope collapse option is on and there is no close box to collide with). It previously showed no widgets.
-
PfWindowSlugRow.utilityWidgets/utilityTitledandProceduralFrameInput.utilityWidgets/utilityTitledare removed. Widget presence and the bar height are derived. New optional inputs:titleWidthCondensed, andfontfor the utility title metrics. -
Collapsed utility windows of these schemes no longer draw a full document window. The facade resolves the window-type key through its canonical, legacy and raw-id equivalents (
equivalentWindowTypeKeys). renderWindow and the WindowManager collapse path pass canonical slugs such ascollapsed-titled-utility-window, and the record table had only the legacy names, so the lookup fell back to the document window. An unknown key still falls back to the document window, but now warns once and traces it (proceduralFrameRecordFor(key).fallback). A record is added forcollapsed-no-title-utility. -
On these schemes the collapsed titled utility window keeps its title, so its bar stays 16 px like the expanded window's (UI10). wnd# schemes keep the old title gate.
-
collapsed-no-title-utility-windowstill renders as the expanded no-title window on these schemes. The loader's built-in-frame window table has no such type, so the newcollapsed-no-title-utilityrecord is not reachable from the public path yet (#423). -
PfTextPassgains optionalcondensed/truncateTo(UT3).TitleRastergainsfontAscent/fontDescent.rasterizeTitletakes an optional{ exactPx }. -
v2 engine: windows of the five schemes without a
wnd#recipe now draw through Kaleidoscope's decoded built-in window frame (engine familyproceduralFrame,docs/spec/engine/procedural-frame.md; fixes #387). Affects apple-platinum-2, black-platinum, platinum-8, slimes and system7-nostalgia-silver. The frame is 6 px on the sides and bottom with a 1-px drop shadow. Its corners are copied from the scheme's own frame cicn (-14332 active, -14336 inactive) and every line colour is a pixel sampled from that cicn: the bar fill is P(6, 3), the title text P(7, 3) and the title shadow P(9, 3). The title bar is 22 px for the system font. Dialogs and alerts draw the 3-px ring, the content gap and the shadow from the dialog cicns (-14326/-14328, or -14322/-14324 for alert colouring). Movable modals draw a boxed title bar above the ring. Stripes fill the close-box rows: the scheme'sppatfirst, then its own cicn three-slice-stretched over it, with a 3-px gap around the title. Widgets are the scheme'sics#/ics8icons in fixed 16 × 16 slots. Zoom is -14334 (pressed -14331) and collapse is -14335 (pressed -14332); they were swapped before. Stripes and widgets are drawn only on the active window. The 17 × 17 grow box (-14330 active, -14334 inactive) sits at (C.r − 15, C.b − 15). The legacy compositor (composeCornerSprite.ts,cornerSpriteGeometry.ts) is deleted with its heuristics:dominantColor, the lighten/darken bevels,headerColorsring and panel colours, the 19-px title, the 7 × 7 procedural widgets, the stripe paddings and ink-bounds glyph trimming. The engine also answers hit testing (message 1), features (7) and regions (8). Utility windows (titled, side-floating, no-title and their collapsed variants) draw only their decoded parts, the widgets and grow box. The utility frame, stripes and title are not decoded yet (§9) and are tracedunimplemented, so these windows had no frame at this point (superseded by the utility-frame entry above, #421, in this release). The slug → variation mapping and other environment inputs are declared defaults insrc/engine/tables/proceduralFrame.ts, not decoded values; the spec questions are in the lane notes. One consequence of the literal §3.5 comparison: slimes' alert colour table has a white entry 0, equal to the declared default content colour, so slimes dialogs and movable modals use the alert art. The loader gains an additiveinspector.colorTables(actb/clutentries; the raw-mode result gainscolorTablesandiconMaskPlanes), and the icon-blit loader set now includes the frame and grow cicns.theme.jsonand lint fingerprints are unchanged. A new engine-diff familyproceduralFrame(1,005 cells) is seeded; the `window...
Scriptoscope 0.2.0
First release from the v2 engine-model branch (#378). This is an incremental cutover: further control families ship in later minor releases, and "every family on the engine" is the 1.0 milestone. The previous version label was 0.0.1; there was no 0.1.x release.
- v2 engine core. QuickDraw-style primitives, a ResourceChain, state normalisation and a per-call trace in
src/engine/. Window chrome now draws through it with no pixel change. - Scroll bar on the decoded 2.3.1 CDEF (fixes #374). Adds the
pressedPartoption.proportionalandthumbExtentare now ignored; see the migration notes below. - Window too-short step and widget hit-rect remap, carried over from main (#377).
- Fidelity tooling:
- the
lane:readypre-review gate and a docs CI job; - a per-family requirement ledger with a history guard;
- the engine trace-diff gate;
- a clean-room linter and implementer brief;
- a frozen routine denominator of 552 in-scope ranges.
- the
- Decoded specs (docs only, no runtime change yet): the procedural window frame, the slider (CDEF 3) and answers to the QuickDraw primitive questions.
Migration notes (0.0.1 → 0.2.0): scroll bar
composeScrollbargains an optionalpressedPart: 'up' | 'down' | 'pageUp' | 'pageDown' | 'thumb'.state: 'pressed'with no part meansthumb.interactiveScrollbarsets the part from the hit.proportionalandthumbExtentare still accepted but now ignored: the thumb is always its cicn's length, as in the original under the declared defaults.- Scroll-bar thickness is fixed at 16 px and
value0..1 maps onto 0..32767. Both are documented modern policy rows in the engine tables. - New opt-in loader option
iconBlitCicnIds, and a new additiveinspector.iconMaskPlanesfield on every load. Default loads and decoded fingerprints are unchanged.