From f5e3ed1ce03deb4c413ae7b92687b3f82024ac3a Mon Sep 17 00:00:00 2001 From: Julian Noble Date: Sat, 25 Jul 2026 23:59:06 +1000 Subject: [PATCH] colour policy: unix-class 8.6 terminals detected via the tty channel signature (-mode) Second 8.6 tty rung: on unix-class Tcl 8.6 (linux/WSL/mac AND msys2/cygwin- runtime builds, which report tcl_platform unix even on a windows machine - e.g the scoop msys2 usr/bin/tclsh8.6), real ttys are isatty-gated into the tty channel type and expose the serial/tty options (-mode etc) that pipes/ files lack - a zero-exec, dependency-free discriminator exactly parallel to -winsize. Verified: WSL 8.6.14 pty mode=tty colour on ansistrip=0 vs piped tcl86-plain stripped; msys2 8.6.12 piped tcl86-plain (interactive -mode presence per field report); windows batteries + punkexe suites 54/0 unchanged. Together with the 0.23.2 windows console-encoding signature this completes dependency-free 8.6 tty detection - the planned G-122 probe-ladder goal (procfs/test -t/twapi rungs) is superseded before drafting: channel signatures cover every case without exec or optional packages. Also confirmed by byte-diff: 8.6 and 9.x piped help renders are IDENTICAL (modulo native-8.6 zipfs warnings) - no 8.6-specific rendering defect exists; the top-level help's wide Description indent is a cross-version cosmetic of that one constructed definition, present on 9.x too. punkshell 0.23.3 + CHANGELOG; src/AGENTS colour bullet updated. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com --- CHANGELOG.md | 14 ++++++++++++++ punkproject.toml | 2 +- src/AGENTS.md | 2 +- src/make.tcl | 28 ++++++++++++++++++---------- 4 files changed, 34 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d0b319e..7f13e065 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,20 @@ The latest `## [X.Y.Z]` header must match the `version` field in `punkproject.to Entries are newest-first; one bullet per notable change. See the root `AGENTS.md` "Project Versioning" section for the bump policy. +## [0.23.3] - 2026-07-25 + +- make.tcl colour policy: unix-class Tcl 8.6 terminals auto-detected via the tty channel + signature - real ttys (isatty-gated channel type) expose the serial/tty options + (`-mode` etc) that pipes/files lack. Covers linux/WSL and msys2/cygwin-runtime tclsh + builds (which report platform unix even on windows - e.g the scoop-installed msys2 + `usr/bin/tclsh8.6`, previously colourless-with-transform on its pty). Verified: WSL + 8.6.14 pty mode=tty / piped tcl86-plain; msys2 8.6.12 piped tcl86-plain (interactive + carries `-mode` per field report). With the 0.23.2 windows console-encoding signature + this completes dependency-free 8.6 tty detection on all supported hosts; the force + env vars remain for exotic environments. Also confirmed: 8.6 and 9.x piped help + output is byte-identical - no 8.6-specific rendering defect existed; all observed + mangling was the (fixed) utf-16 transform corruption. + ## [0.23.2] - 2026-07-25 - make.tcl colour policy defect fix + 8.6 windows console auto-detection: the G-113 diff --git a/punkproject.toml b/punkproject.toml index c8f60bd1..816fb136 100644 --- a/punkproject.toml +++ b/punkproject.toml @@ -1,4 +1,4 @@ [project] name = "punkshell" -version = "0.23.2" +version = "0.23.3" license = "BSD-2-Clause" diff --git a/src/AGENTS.md b/src/AGENTS.md index 14546ba5..b7f1ea6f 100644 --- a/src/AGENTS.md +++ b/src/AGENTS.md @@ -63,7 +63,7 @@ Recovery after a wrong path guess: - Use `tclsh src/make.tcl modules` to build just the module packages. - Use `tclsh src/make.tcl libs` to build just the library packages. - Use `tclsh src/make.tcl packages` to build both modules and libraries. -- make.tcl colour is terminal-aware (G-113): piped/redirected runs (agent harnesses, CI, log capture) automatically produce fully ESC-free output with no caller action required - an ansistrip channel transform on stdout+stderr guarantees zero ESC bytes for every emitter, including module-side ones (punkcheck summaries, punk::args tables). Interactive terminal runs keep colour (stdout tty probe via the `-winsize` channel option, Tcl 8.7+/9). Precedence: `NO_COLOR` (any value) always suppresses colour; `PUNK_FORCE_COLOR`/`FORCE_COLOR` (value other than 0/false/no/off) re-enables ANSI on piped output; otherwise the probe decides. Tcl 8.6 windows consoles are auto-detected via the console channel's utf-16 encoding signature (`-encoding unicode` - only 8.6 console channels report it), so interactive 8.6 windows runs keep colour; the byte-level strip transform is never pushed onto a utf-16-class channel (it would corrupt the stream - per-channel push, so `> file` from an 8.6 console wraps stdout only). 8.6 on unix/WSL has no probe - colour fails OFF there (use the force vars). stderr follows the stdout decision; `make.tcl shell` pops the transform (repl colour is the shell's own concern). `tclsh src/make.tcl check` reports the active policy (`colour policy (G-113): mode=...` line; modes tty|forced|nocolor|piped-plain|tcl86-plain). Pinned by `src/tests/shell/testsuites/punkexe/maketclcolour.test`. Agents no longer need to set NO_COLOR for captured runs (setting it remains harmless). +- make.tcl colour is terminal-aware (G-113): piped/redirected runs (agent harnesses, CI, log capture) automatically produce fully ESC-free output with no caller action required - an ansistrip channel transform on stdout+stderr guarantees zero ESC bytes for every emitter, including module-side ones (punkcheck summaries, punk::args tables). Interactive terminal runs keep colour (stdout tty probe via the `-winsize` channel option, Tcl 8.7+/9). Precedence: `NO_COLOR` (any value) always suppresses colour; `PUNK_FORCE_COLOR`/`FORCE_COLOR` (value other than 0/false/no/off) re-enables ANSI on piped output; otherwise the probe decides. Tcl 8.6 terminals are auto-detected without dependencies: windows consoles via the console channel's utf-16 encoding signature (`-encoding unicode` - only 8.6 console channels report it; the byte-level strip transform is never pushed onto a utf-16-class channel, which it would corrupt - per-channel push, so `> file` from an 8.6 console wraps stdout only), and unix-class hosts (linux/WSL/mac, plus msys2/cygwin-runtime tclsh builds that report platform unix on windows) via the tty channel signature (real ttys expose `-mode` etc; pipes/files lack them). The force vars remain for exotic environments. stderr follows the stdout decision; `make.tcl shell` pops the transform (repl colour is the shell's own concern). `tclsh src/make.tcl check` reports the active policy (`colour policy (G-113): mode=...` line; modes tty|forced|nocolor|piped-plain|tcl86-plain). Pinned by `src/tests/shell/testsuites/punkexe/maketclcolour.test`. Agents no longer need to set NO_COLOR for captured runs (setting it remains harmless). - Use `tclsh src/make.tcl vendorupdate` to refresh vendormodules from config. It warns (non-fatal) for each source project whose fossil/git checkout is dirty - vendored artifacts built from a dirty tree have no committed provenance; commit in the source project to clear the warning (enforcement policy tracked by goal G-026). - All build/promotion commands (`bakehouse`, `packages`, `modules`, `libs`, `bake`, `vfslibs`, `bin`, `bootsupport`, `vfscommonupdate`) warn similarly when this project's own `src/` has uncommitted fossil/git changes (dirt outside `src/` is ignored). Warn-only by default EXCEPT `bakehouse` (aborts by default; `-dirty-abort 0` overrides); pass `-dirty-abort` elsewhere to make the check aborting. For evaluating uncommitted source without a build, prefer ` src` / ` src shell`. The check is `punkboot::utils::vcs_dirty_warnings` (optional scope argument) loaded guardedly from bootsupport - if the snapshot is stale/missing the check degrades to a skip notice (but `-dirty-abort` then aborts rather than silently losing the requested strictness). - Provenance warnings (dirty-src gate + vendorupdate source-project check) print with a plain column-0 `PROVENANCE-WARNING:` token (grep for it in captured build output) and are recapped at the end of the run via make.tcl's wrapped `::exit`. Interactive terminal runs get a 3-second ctrl-c grace countdown before a dirty build proceeds; piped/agent runs skip it. `tclsh src/make.tcl check` reports the current src provenance status and what the build commands would do. diff --git a/src/make.tcl b/src/make.tcl index 5fed0a2a..d4662a07 100644 --- a/src/make.tcl +++ b/src/make.tcl @@ -96,18 +96,26 @@ apply {{} { } } set stdout_is_tty [expr {![catch {chan configure stdout -winsize}]}] - if {!$stdout_is_tty && $::tcl_platform(platform) eq "windows" - && ![package vsatisfies [package provide Tcl] 8.7-]} { - #Tcl 8.6 windows: no -winsize/-inputmode probe exists, but 8.6's windows - #CONSOLE channels are the only ones that report -encoding unicode (utf-16; - #pipes/files get the system encoding) - a dependency-free console signature. - #This both restores interactive colour on 8.6 consoles and is load-bearing - #for the ansistrip transform below: the byte-level strip must never sit on - #a utf-16 channel (ESC arrives as 1B 00 - sequences pass unstripped and the - #hold-back logic defers/drops real content; field defect 2026-07-25 mangling - #punk86/punksys console help output). + if {!$stdout_is_tty && ![package vsatisfies [package provide Tcl] 8.7-]} { + #Tcl 8.6 tty signatures (no -winsize/-inputmode exists pre-8.7): + # - windows: 8.6's CONSOLE channels are the only ones that report + # -encoding unicode (utf-16; pipes/files get the system encoding). This + # both restores interactive colour on 8.6 consoles and is load-bearing + # for the ansistrip transform below: the byte-level strip must never sit + # on a utf-16 channel (ESC arrives as 1B 00 - sequences pass unstripped + # and the hold-back logic defers/drops real content; field defect + # 2026-07-25 mangling punk86/punksys console help output). + # - unix-class (linux/WSL/mac AND msys2/cygwin-runtime builds, which report + # tcl_platform(platform) unix even on a windows machine): the tty channel + # type is isatty-gated and exposes the serial/tty options (-mode etc) on + # real terminals only - pipes/files lack them. Verified: WSL 8.6.14 pty + # -mode present / piped absent; msys2 8.6.12 interactive present / piped + # absent. (-mode on a windows 8.6 stdout would mean a serial channel - + # terminal-equivalent for colour purposes.) if {[chan configure stdout -encoding] eq "unicode"} { set stdout_is_tty 1 + } elseif {![catch {chan configure stdout -mode}]} { + set stdout_is_tty 1 } } if {[info exists ::env(NO_COLOR)]} {