Skip to content

Scriptoscope 0.3.0

Choose a tag to compare

@khawkins98 khawkins98 released this 22 Oct 15:15
· 284 commits to main since this release
dd49a88

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 composeCornerSpriteChrome export 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 composeSlider mismatches (#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-baselines script.
  • 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:
    • procedural-frame revision 3 decodes the utility frame (#415);
    • the slider spec answers (#417);
    • the window-widget spec is split into an implementer-safe unit and an evidence file (#420). The split corrects three earlier readings and lists eight runtime divergences for the window-recipe migration.

Changes

  • Add npm run loc:src (scripts/src-loc.mjs). It reports non-test src/ 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 changes src/ 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 / utilityTitled defaults 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. The window and scrollbar cells 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.frame reports 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 / utilityTitled and ProceduralFrameInput.utilityWidgets / utilityTitled are removed. Widget presence and the bar height are derived. New optional inputs: titleWidthCondensed, and font for 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 as collapsed-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 for collapsed-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-window still renders as the expanded no-title window on these schemes. The loader's built-in-frame window table has no such type, so the new collapsed-no-title-utility record is not reachable from the public path yet (#423).

  • PfTextPass gains optional condensed / truncateTo (UT3). TitleRaster gains fontAscent / fontDescent. rasterizeTitle takes 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 family proceduralFrame, 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's ppat first, then its own cicn three-slice-stretched over it, with a 3-px gap around the title. Widgets are the scheme's ics#/ics8 icons 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, headerColors ring 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 traced unimplemented, 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 in src/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 additive inspector.colorTables (actb/clut entries; the raw-mode result gains colorTables and iconMaskPlanes), and the icon-blit loader set now includes the frame and grow cicns. theme.json and lint fingerprints are unchanged. A new engine-diff family proceduralFrame (1,005 cells) is seeded; the window and scrollbar cells are unchanged. No native capture backs this (§10 item 9).

Migration (built-in frame windows)

  • These windows are larger. The title bar is 22 px (was 19), sides and bottom are 6 px plus a 1-px shadow on the right and bottom (were 1–5 px), and dialogs are outset 6. fullWidth = content + 13 and fullHeight = content + 29 for a document window. Code that hard-coded the old insets should read ComposedChrome.frame.
  • Widgets are 16 × 16 icon slots: close at bar left + 4, collapse at bar right − 17, zoom at bar right − 33 (− 17 without a collapse box). They were 7 × 7 boxes or ink-trimmed glyphs. Hit and press areas follow.
  • Inactive windows show no widgets and no stripes.
  • Long titles are clipped to the space between the widgets, as the original does; they are no longer truncated with an ellipsis.
  • The public export composeCornerSpriteChrome (and the CornerSpriteOptions type) is removed. Render these windows with renderWindow. scripts/render-window.mjs now refuses corner-sprite types and points to the engine-diff --dump.
  • WindowType.sprites and WindowType.widgets stay in the schema but the runtime no longer reads them.

Runtime size (npm run loc:src -- HEAD --base v0.2.0)

src/ lines (non-test .ts) v0.2.0 0.3.0 delta
logic (all src except engine tables) 14776 15399 +623
engine tables (cited data) 461 1258 +797
total 15237 16657 +1420

The growth is the decoded frame family and its cited tables. The legacy corner-sprite compositor (about 700 lines) is deleted. The large legacy files (controls.ts, interactive.ts, composeChrome.ts) shrink when their families migrate.