Browse Source

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
master
Julian Noble 5 days ago
parent
commit
f5e3ed1ce0
  1. 14
      CHANGELOG.md
  2. 2
      punkproject.toml
  3. 2
      src/AGENTS.md
  4. 28
      src/make.tcl

14
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

2
punkproject.toml

@ -1,4 +1,4 @@
[project]
name = "punkshell"
version = "0.23.2"
version = "0.23.3"
license = "BSD-2-Clause"

2
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 `<builtexe> src` / `<builtexe> 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.

28
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)]} {

Loading…
Cancel
Save