scriptlib_resolve now lets an extensionless (or unknown-extension) lib:<name>
call match a file named exactly <name> when its first lines identify it as
tcl: a leading '# tcl' comment (prefix, case-insensitive), a shebang naming
tclsh/tclkit/wish, or the portable sh-trampoline ('#!/bin/sh' with a
commented 'exec tclsh' continuation - detected within the first 4 lines).
New internal punk::path::system::scriptfile_is_tcl does the bounded sniff
(512 bytes, UTF-8 BOM and CRLF tolerated, directories/unreadable files
rejected). When both <name> and <name>.tcl exist, the spelling matching the
call wins, checked per scriptlib location so kit-internal directory
precedence is never crossed by a spelling preference.
.kit joins the known extensions: lib:<name>.kit previously had .tcl appended
(searched <name>.kit.tcl), which made the shell subcommand's do_tclkit
dispatch arms unreachable - lib: kit dispatch is now restored. Result dict
reworked: scripttype (tcl/kit/py/pl/ps1/sh or empty) + notes keys added,
scriptname is now the matched relative name, and matches require file isfile.
app-punkshell and app_shellrun lib: handling refactored onto the shared
resolver (previously independent inline copies of the policy), fixing two
silent-failure bugs in that copy: no message at all when a scriptlib dir
existed but lacked the script, and the error listing showing
<kit>/scriptlib rather than the <kit>/app/scriptlib actually checked.
app-punkscript's post-resolve gate now uses scripttype and its not-found
report includes the identification skip notes. The unused has_globchars
vestige is dropped.
Fixtures scriptlib/_punktest/{extless,dual,dual.tcl,shebang_sh,notatcl} and
5 new scriptexec.test cases (extensionless resolve, both precedence
directions, trampoline shebang + argv, non-tcl skip note on not-found);
suite passes 17/17 against a freshly built punk902z kit. Sniff helper unit
checks pass under tclsh 9.0.3 and 8.6. punkshell project 0.13.0 -> 0.14.0.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
These scripts are fixtures owned by the punk test suite
(src/tests/shell/testsuites/punkexe/scriptexec.test), not user sample
scripts. They exist so tests can exercise the lib: scriptlib-resolution
mechanism and the script subcommand's Tk main-loop behaviour against
stable, committed scripts rather than user-editable samples.
Do not hand-edit these files: the tests assert on their exact behaviour and
output markers. Changing them will break the suite.
The rest of scriptlib/ is user-only territory; this _punktest/ subfolder
is the exception, owned and maintained by the test suite.
They resolve via <punkexe> script lib:_punktest/<name> (subpath resolution
through punk::path::scriptlib_resolve).
Fixtures:
echo.tcl — emits a marker plus its ::argv0/::argv; used for lib:
resolution, subpath resolution, and file-form argument passing.
extless — extensionless, first line # tcl; proves extensionless-tcl
matching (punk::path 0.3.0 first-line identification).
dual / dual.tcl — precedence pair with distinct markers; the spelling
matching the call must win (lib:_punktest/dual runs dual,
lib:_punktest/dual.tcl runs dual.tcl).
shebang_sh — extensionless, portable sh-trampoline shebang (#!/bin/sh
with commented exec tclsh continuation); proves the identification check
accepts the classic cross-platform idiom.
notatcl — extensionless with a python shebang and no .tcl sibling; must
NOT resolve, and the not-found output must note the identification skip.
tk_countdown.tcl <ms> — Tk window that exits 0 from an after callback;
proves the script subcommand services a registered Tk main loop (the
callback runs only if the event loop is serviced).
tk_noexit.tcl — Tk window with no explicit exit; used to prove a GUI
script stays alive (blocks) under script, as it does under tclsh/wish.
tk_error.tcl — Tk window then an uncaught error; proves an errored GUI
script exits promptly (no hanging window).