You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
61 KiB
61 KiB
Changelog
All notable changes to the punkshell project version are documented here.
The latest ## [X.Y.Z] header must match the version field in punkproject.toml.
Entries are newest-first; one bullet per notable change. See the root AGENTS.md
"Project Versioning" section for the bump policy.
[0.12.30] - 2026-07-14
- punk::args 0.12.3: fixed the stringstartswith tail-clause reservation bug flagged in the 0.12.2 comment review - the multi-member tail-clause walk in get_dict_can_assign_value compared the prefix against the type string instead of the candidate value, so an optional trailing clause like {literal(with) stringstartswith(v)} lost its matching words to a preceding -multiple argument, and certain prefix spellings caused spurious "Received more values than can be assigned" errors. Characterized pre-fix, pin flipped (allocation.test), guards added for the literal-only and no-match cases.
[0.12.29] - 2026-07-14
- punk::args 0.12.2 comment/documentation hygiene pass (no behaviour change): ~1100 lines of superseded commented-out code removed (old check_clausecolumn, abandoned _check_clausecolumn2 experiment with its error-collection idea preserved as a note for G-072-era rework, pre-parsekey ordering loop, disabled switch arm, debug remnants); MAINTENANCE loop-parity comments upgraded to a dated refactor assessment (shared-helper extraction deferred to ride G-084 under G-046 hot-path constraints); user-visible doc fixes (get_dict return-shape and directive lists corrected, false solo-flag/last-value-only claims removed, two broken doc examples fixed); goal cross-refs (G-053, G-084) annotated at the relevant code sites; a suspected latent bug in the multi-member clause stringstartswith( arm flagged in a comment (matches the type string instead of the value) without changing behaviour.
[0.12.28] - 2026-07-14
- G-082 (achieved): punk::args 0.12.1 single-form parse error selection - a word rejected by an optional argument's allocation screen (restricted choices, or the basic int/double/bool/number/dict type screen) that then overflows the argument list now reports the specific rejection (choiceviolation naming the word and allowed choices, or typemismatch naming the type, with -badarg/-badval) instead of the generic "Received more values than can be assigned" overflow - restoring the 0.5.0-era pointedness for optional choice-restricted dispatch shapes (shell-visible in usage errors from punk::args-parsed commands). Genuinely-surplus words still report toomanyarguments; multiform selection unchanged. New errorselection.test (pre-fix behaviour characterized first, pins flipped deliberately); the make.tcl
-optional 0authoring workaround is no longer needed on fixed versions (src/modules/AGENTS.md guideline re-documented; make.tcl keeps it while running against the bootsupport 0.12.0 snapshot). - Also: punk::args goals G-083 (argument relations: strict mutual exclusivity, parsekey-group integrity) and G-084 (-parsekey completeness) proposed, with parsekey characterization tests (mash/prefix/shared-default/collision pins + dev known-bug pins) landed alongside.
[0.12.27] - 2026-07-14
- make.tcl shell under a built punk executable: fixed missing prompts and the raw-mode 'invalid command name struct::set' error. Both stemmed from the kit's script-mode boot pre-loading the punk stack: (1) app-punkscript correctly forces ::tcl_interactive 0 for script runs, and since punk::repl was already loaded its load-time interactivity probe never re-ran - the shell branch now recomputes ::tcl_interactive via punk::repl::is_interactive against the real input channel before repl::start; (2) the accelerator-reload block (package forget + command destroy of sha1/md5/struct::*) relied on later package-require chains to restore the packages, which never re-fire when consumers (punk::lib, punk::du, flagfilter etc) were pre-loaded at kit boot - the block now records what was actually loaded and re-requires it immediately (verified: repl-thread interp state now identical under tclsh and punk91). src/AGENTS.md gains a "pre-loaded interp, not a virgin one" note covering the class: interp surgery and load-time-state assumptions in make.tcl must restore deliberately and be tested under both tclsh and a punk exe (includes the kit-vs-bootsupport module provenance-mixing caveat).
[0.12.26] - 2026-07-14
- make.tcl under a built punk executable: kit builds gain a self-build guard - the kit whose deployed executable is running the build is skipped with a clear warning (previously the pre-deploy process sweep would taskkill the build's own process mid-run with -k, since it matched processes by executable name only; without -k the polite kill's failure was the only thing saving the run). The sweep now also excludes the build's own pid unconditionally (covers a same-named copy driving the build from a non-deploy path). Informational/update subcommands were already safe (they exit before the kit machinery); building other kits from a punk exe remains supported. Also quietened the 'punk::libunknown::init already done - unnecessary call?' stderr diagnostic when a punk exe runs make.tcl: make.tcl now leaves an already-active libunknown in place instead of re-sourcing the bootsupport copy over it and tripping init's rename guard. src/AGENTS.md build guidance updated.
[0.12.25] - 2026-07-14
- G-030 follow-up (user review): make.tcl's constructed punk::args definitions adopt the G-045 authoring mechanisms - @cmd -help bodies converted to block-form values with a bare @normalize per definition, fixing the constructed-definition indent leak (first Description line rendered less indented than continuations; the braced option fragments never leaked because literal block-shaped parts get file-style normalization). Added a define-time capability probe (get_spec on representative ids) so a stale punk::args that accepts the text but cannot resolve a mechanism degrades to the plain fallback immediately. AGENTS infrastructure for future documentation work: new "punk::args definition authoring ergonomics" subsection in src/modules/AGENTS.md (constructed-def @normalize + block form, -unindentedfields, -& record continuation, container quoting rules, explicit @form -synopsis for script-level ids, the optional-choice error-quality workaround), cross-referenced from src/AGENTS.md with ::punkboot::argdoc named as the in-tree exemplar. Layout make.tcl copies followed via the punkcheck channel.
[0.12.24] - 2026-07-14
- G-030 (achieved): make.tcl dogfoods punk::args. All 15 subcommands are punk::args-declared ((script)::punkboot definitions with single-source summaries, shared option fragments and explicit @form -synopsis lines): bare
make.tcl/-helprender tabled usage with grouped subcommand summaries,make.tcl help ?subcommand?/<subcommand> -helpshow per-subcommand definitions, invalid flags and unknown subcommands raise punk::args usage errors (exit 1) with unambiguous-prefix resolution. New-confirm 0|1prompt policy on every confirmation point (bootsupport minor-staleness gate, vfscommonupdate REPLACE, kit-type mismatch): default prompts only on an interactive terminal and aborts fast with guidance on non-interactive stdin (the piped-yagent workflow is retired - use-confirm 0; the old vfscommonupdate decline half-abort now exits 1). punk::args joined the bootstrap-tracked staleness set (parsing contract only - the punk::ansi/textblock rendering stack degrades instead: minimal errorstyle/plain help when unhealthy, and full scan-based fallback dispatch when punk::args itself is unavailable; PUNKBOOT_PLAIN=1 forces the degraded mode). Bootsupport snapshot refreshed (args 0.5.0->0.12.0 plus punk/lib/ns/repl/tclcore moduledoc) and layout make.tcl/bootsupport copies followed via the punkcheck channel. Docs: src/AGENTS.md, src/bootsupport/AGENTS.md, src/modules/AGENTS.md, src/tests/shell/AGENTS.md. Dogfooding finding recorded in the goal file: punk::args 0.12.0 reports a generic overflow error where 0.5.0 reported a pointed choiceviolation for optional-choice mismatches (worked around with required leaders; candidate punk::args error-selection improvement). - Also since 0.12.23 (landed before this version's bump, entry added retrospectively 2026-07-14): punk::args -> doctools and punk-native HTML/Markdown converter prototypes under src/scriptapps/tools (punkargs_to_doctools.tcl, punkargs_punknative.tcl); vendored punkdoc-mono web font (OFL subset of Cascadia Mono 2404.23) with reproducible fontprep builds and -assets embed|link|none in the punknative generator; punknative generator refinements (nav index, per-form arg tables, terminal-black backdrop, integer row pitch, settled ansi-art html rendering recipe). Goals G-078..G-081 drafted (punk::ansi->html api, default-colour semantics, cell-grid rendering mode, argdoc build pipeline).
[0.12.23] - 2026-07-13
- Restored
dev doc.validate: tcllib dtplite wrapped as the generated polyglot bin/dtplite.cmd (multishell scriptset: src/scriptapps/dtplite.tcl + dtplite_wrap.toml, LF-only payload; falls back to the project-vendored tcllib under src/vendorlib_tcl9/ when the invoking tclsh lacks the dtplite package). Previously the repl unknown-handler's auto_execok found no dtplite executable ("invalid command name dtplite" - only the legacy misnamed bin/dtplite_run.bat existed). New src/tests/shell/testsuites/binscripts/dtplite.test pins the artifact (LF-only, checkfile-clean, byte-identical round-trip re-wrap) and exercises usage-error/validate/html usecases. Verified: 'dev doc.validate' validates all 64 src/doc .man files clean. The doctools pipeline remains interim - punk::args is intended to become the documentation source of truth. (Entry added retrospectively 2026-07-14; the version bump landed in the original commit without one.)
[0.12.22] - 2026-07-13
- G-074 (achieved): punk::args 0.12.0 adds punk::args::formcheck - on-demand multiform ambiguity analysis. It reports the form pairs of a definition that some argument list could cleanly match simultaneously, confirming every candidate with a real parse of a synthetic witness arglist against both forms - so fully discriminated form pairs can never false-alarm, and each reported witness is a genuine multipleformmatches input. Findings classify as type-weakness (a literal/choice discriminator aligned with a permissive non-validating type such as expr/any/string - the 'lseq 1 count 5' class) vs structural (the forms genuinely share an argument shape - the 'after cancel id|script' class). The new @form -overlapallowed key sanctions a known/documented overlap for formcheck reporting only (parse behaviour untouched; unknown form names rejected at definition resolve); tclcore moduledoc 0.3.4 adopts it for the after cancel pair, leaving ::after with zero unsanctioned findings while ::lseq's expr-typed-end findings stay visible as actionable. New testsuite args/formcheck.test.
[0.12.21] - 2026-07-13
- G-076 (new goal, active): 'help tcl' now warns about the tcl9 dead-console defect (upstream ticket f10d91c2d3, root-caused in G-039: a dead console is never delivered to the script as a fileevent while the core's console reader thread busy-loops) via punk::lib 0.4.3's has_tclbug_console_deadspin — version-based detection through the pure classifier tclbug_console_deadspin_applies, gated by check::tclbug_console_deadspin_fixed_in (empty until a released Tcl contains the upstream fix verified by re-running the G-039 kill procedure). punk::repl 0.5.1 arms the dead-console watchdog only when that same check reports the runtime affected, so recording the fixed release once silences the warning and stops arming the watchdog together. Buginfo dicts gain a mitigated/mitigation axis orthogonal to level (punk 0.2.6 renders it): the deadspin warning keeps severity major but displays "(mitigated)" in subdued grey with the watchdog's scope described when punk::repl >= 0.5.0 is available to the runtime; non-repl console reads remain exposed and unmitigated warnings render unchanged.
[0.12.20] - 2026-07-13
- tclcore moduledoc 0.3.3: removed the unnecessary @dynamic tags from the split, array and join definitions - no bad-@dynamic warnings remain anywhere in the module, and the three definitions now cache their display expansion like the rest instead of re-expanding per render.
[0.12.19] - 2026-07-13
- punk::args 0.11.2: the "bad @dynamic tag" warning now emits once per definition instead of on every resolve ('i join' emitted it 4x, user-reported) - the underlying inefficiency fixed: parse-inert @dynamic definitions now cache their round-1 resolution like legitimately dynamic ones instead of redoing the full text substitution on every resolve. The warning wording now notes @dynamic still forces display-field re-expansion per render for such definitions. tclcore moduledoc 0.3.2: fixed the malformed ::tcl_startOfNextWord definition (unescaped quotes in its embedded man-page example prevented it resolving at all - 'i tcl_startOfNextWord' now works), found by sweeping all 462 registered ids; the sweep identified ::split, ::array and ::join as the parse-inert @dynamic carriers.
[0.12.18] - 2026-07-13
- tclcore moduledoc 0.3.1 (authoring-style only): the after id-shape harvest is consumed via tstr placeholders with the variable in the argdoc namespace (the defspace), replacing the interim string-map token - the module now showcases the neater placeholder style documented in punk::args 0.11.1, with string map reserved for when build-time substitution is genuinely necessary. Behaviour unchanged.
[0.12.17] - 2026-07-13
- punk::args 0.11.1 (documentation-only): the define help now documents the two definition-registration styles (direct define vs lazy PUNKARGS/register::NAMESPACES registration used by module templates and moduledocs) and the tstr interpolation rules - display-field deferral, parse-field expansion at first resolve, the defspace rule (argdoc child namespace wins when present), the silent-literal fallback for unresolvable placeholders, and the safe patterns for load-time-computed values.
[0.12.16] - 2026-07-13
- tclcore moduledoc 0.3.0: 'after cancel ' and 'after info ' now discriminate by the after-id shape, harvested from the running interpreter at load time (user-directed). 'i after cancel someid' resolves cleanly to the cancel-script form exactly as real Tcl treats it (silent script-match no-op), and only genuinely id-shaped words ('after#N') report the cancelid/cancelscript ambiguity - the junction real Tcl itself resolves by id liveness at runtime. Parity pins added (tclcoreparity.test) including the accepted dead-id over-acceptance boundary.
[0.12.15] - 2026-07-13
- G-041 doc surface: the help system presents the command form matching the supplied words - 'i after cancel ' presents the cancel form's argument table (candidates are named when no form or several forms match, e.g 'after cancel someid' reports the genuine cancelid/cancelscript ambiguity of the documented forms), and 's after cancel someid' underlines the matching synopsis line(s) (punk::ns 0.5.0). punk::args 0.11.0: the documented @form -synopsis override now renders in synopsis output, and candidate-form ranking recognises -choices discriminators (the tclcore models' subcommand words) via the shared choice resolver.
[0.12.14] - 2026-07-13
- punk::args 0.10.0 (G-041 increment): multi-form argument definitions now parse by automated form selection - punk::args::parse without -form attempts every form and auto-selects the one that cleanly matches ('lseq'-style multiform commands no longer fail with the first form's error when the arguments fit a later form). No matching form raises an error naming each candidate form's failure (best candidate first); arguments matching several forms raise an error naming them, with -form (which now accepts the documented list of form names/indices) restricting to the intended form. Parse results and parse_status report the selected form and every candidate's status ('form'/'formstatus' keys).
[0.12.13] - 2026-07-13
- G-051 achieved: punk::ns 0.4.0 - the help system's doc walk now accepts the same choice-word abbreviations parsing accepts: 'i string is tr' resolves to the 'string is true' documentation exactly as 'string is tr 1' executes (unique prefixes, aliases, nocase; ambiguous/denied/unknown words stay at the parent exactly when parse rejects them). cmdinfo also reports the truthful cmdtype 'doconly' (was 'notfound') for documentation-only levels such as 'string is ' and documented TclOO method docids. punk::lib 0.4.1 adapts its script analysis to the new value with identical behaviour.
[0.12.12] - 2026-07-12
- punk::ns 0.3.0: 'i ' with no argument words again signals when the command cannot be called bare - e.g 'i if' shows "Bad number of trailing values for if. Got 0 values. Expected at least 2" in the error scheme above the usage table (regression vs older builds, reported by the user). The G-046-era suppression of that render existed because the old message carried internal-looking attribution ("for punk::args::parse ..."); the G-049 -caller attribution fixed the message wording, so the suppression was reversed rather than reworded - the original 'i string is' complaint case now renders an accurate "Bad number of leading values for string is ..." instead of being hidden.
[0.12.11] - 2026-07-12
- G-071 achieved: punk::args 0.9.0 allocation choice screen - optional arguments with restricted choice sets no longer greedily consume non-choice words at allocation time, so noise-word grammars parse correctly with the noise word omitted. 'i lseq 0 10 2' (and the '0 10 by 2' / '1 5 by 0' shapes) now parse and render correctly against the tclcore moduledoc; genuinely invalid arglists report a plain excess-values error instead of blaming an unrelated optional argument. Correction recorded: parse_status already accepted -form before the withid/withdef tail per its documented synopsis - the earlier 'missing -form' finding was an argument-order mistake, now pinned by test.
[0.12.10] - 2026-07-12
- punk::args 0.8.3 (G-071 increment): silenced four more unconditional debug lines that printed to stderr during normal argument parsing whenever an optional element was skipped (visible when using 'i'/help display against commands modelled with noise-word arguments such as if and lseq). New allocation characterization testsuite pins the optional-element mis-allocation ('lseq 0 10 2'-class failures) as GAP tests ahead of the allocator fix.
[0.12.9] - 2026-07-12
- punk::args 0.8.2: fixed stray debug output ("checking tp ... against value ...") printed to the console when parsing multi-element clause arguments (e.g. 'i try ...' style usage against the tclcore moduledoc). Found during G-041 prework probing of if/switch/try/lseq real-vs-model divergence; findings recorded in the G-041 and G-055 goal detail files.
[0.12.8] - 2026-07-12
- G-045 achieved: punk::args 0.8.1 documents the definition container quoting rules in the punk::args::define help (braced values fully literal; double-quoted values with Tcl backslash semantics at record parse while $ and [] stay literal; the backslash-escaped tstr placeholder idiom). This completes the definition authoring ergonomics goal: @cmd -unindentedfields honoured (0.6.1), -& record continuation (0.7.0), @normalize block-form indent normalization with the help-system definitions as consumer proof (0.8.0 / punk 0.2.5), quoting documentation (0.8.1).
[0.12.7] - 2026-07-12
- G-045 (increment): punk::args 0.8.0 adds the bare @normalize directive - opts a definition into indent normalization of block-form multi-line field values (structural leading newline dropped, content re-based to the file-style 4-space continuation convention, relative indents preserved, -unindentedfields exempt, no-op on conforming file-style definitions). Intended for constructed (string-built) definitions. punk 0.2.5: the help-system definitions (::punk::help / help_chunks) convert to indented block authoring under @normalize; 'i help' rendering unchanged.
[0.12.6] - 2026-07-12
- G-045 (increment): punk::args 0.7.0 adds the -& record-continuation token - an unquoted trailing -& on a definition record line continues the record on the next line, assembling byte-identically to the equivalent backslash continuation. Intended for constructed (string-built) definitions, where backslash-newline is consumed by the building code's own quoting. Brace a literal trailing -& value ({-&}); -& elsewhere on a line or inside braced/quoted multi-line values is ordinary data. Backslash-continuation authoring is unchanged.
[0.12.5] - 2026-07-12
- G-045 (increment): 'i help' usage table alignment fixed (punk 0.2.4) - the Description block's continuations no longer render indented +12 relative to the first line, and the topic argument's help first line no longer renders +4 relative to its continuations. ::punk::helptopic::define_docs authors help text at the left margin with -unindentedfields {-help} on the @cmd and topic lines. Help text content unchanged.
[0.12.4] - 2026-07-12
- G-045 (increment): punk::args 0.6.1 - the @cmd directive now honours -unindentedfields for -help, so command help authored at the left margin renders its first line flush with continuations in help/usage displays (previously the option was accepted on @cmd but ignored). No shipped definitions used it yet, so existing help rendering is unchanged; the define documentation states where -unindentedfields is valid.
[0.12.3] - 2026-07-12
- punk::args 0.6.0 synced into the common vfs payload (_vfscommon.vfs): help/usage synopses render small restricted choice sets as literal alternates (module change committed earlier as c309ed47; this ships it in built kits).
[0.12.2] - 2026-07-12
- G-039 fix: an interactive shell orphaned by its hosting console dying (killed conhost/terminal) previously spun ~2 CPU cores forever — the Tcl 9 windows console driver never delivers the dead-console state to the script level as a fileevent (tclWinConsole.c
ConsoleEventProconly notifies on buffered data) while its reader thread busy-loops on the persistent channel error. punk::repl 0.5.0 addsrepl::console_watchdog, a 5s liveness poll (read-only GetConsoleMode viachan configure -inputmode) armed only for a tcl9 console input channel on the process-default console on windows: on a dead console it closes the input channel (stopping the driver's reader thread) and finishes the repl via the normal eof path, so the orphan exits cleanly within seconds. Piped, foreign-console and tcl 8.6 inputs are unaffected.
[0.12.1] - 2026-07-11
- G-062 achieved: canonical project license declared as BSD-2-Clause.
LICENSE.txtadded at the repo root with the standard BSD-2-Clause text (copyright Julian Marcel Noble, 2023-2026);README.mdnames BSD-2-Clause and points atLICENSE.txt; rootAGENTS.mdRepo-wide Notes names the license precisely;punkproject.toml[project]carrieslicense = "BSD-2-Clause". Repo-sweep found no top-level license claims contradicting it (vendored library licenses and module-level generated docs are not project-level claims).
[0.12.0] - 2026-07-11
- punk::args 0.6.0: command synopses (
s <cmd>,i <cmd>, usage headers) now display small restricted choice sets as literal alternates — an argument whose choice pool (-choicesplus-choicegroupsmembers) has 1–3 members and-choicerestrictedtrue renders those words unitalicised joined by|(e.g.after cancelshows literalcancel; a 3-choice option shows(left|centre|right)), matching the existing display style ofliteral()/literalprefix()type-alternates. Larger or unrestricted choice sets keep the italicised argname/type display and an explicit-typesynopsisalways wins, so e.g.textblock::frame -type (choice|<dict>)is unchanged. Synopsis rendering of type-alternates,-typesynopsispassthrough (including documenter ANSI styling), and multi-element clause display gained characterization test coverage (synopsis.test).
[0.11.0] - 2026-07-11
- G-001 achieved: an interactive REPL can be launched against a non-detectable terminal-like device via an
::opunk::Consolesubclass —repl::init -console <spec>selects the console (channel pair, anchored instance name, or object value),repl::start's input channel defaults to it, and the repl's output (prompts, results, and the code interp's stdout/stderr — diverted via shellfilter junction stacks and emitted per run) routes through the selected console's channels, with eof/size/capability answered by the subclass overrides (punk::repl 0.4.0; base::opunk::Consoleandpunk::consoleuntouched). Verified end-to-end by child-process driver tests: an::opunk::SshConsolesocket session whose scripted remote terminal answersCSI 6n(size resolved over the socket) and a::opunk::TkConsoletext widget wired as a live console by newopunk::console::tk::console(reflected output channel rendering into the widget + Return-binding input pipe, opunk::console::tk 0.2.0). Process-console behaviours (tcl_interactive prompt gating, stdin reopen on eof, raw-mode re-enable, the windows line re-decode experiment) now apply only when no foreign console is selected; default stdin/stdout repl behaviour is unchanged.
[0.10.3] - 2026-07-11
- make.tcl build/promotion commands (
project,packages,modules,libs,vfs,vfslibs,bin,bootsupport,vfscommonupdate) now warn whensrc/has uncommitted fossil/git changes — artifacts built from dirty src have no committed provenance (G-026 direction). Warn-only by default; a new-dirty-abortflag makes the check aborting. Dirt outsidesrc/is ignored (punkboot::utils::vcs_dirty_warningsgained an optional scope argument, utils 0.2.0). With<builtexe> src/<builtexe> src shellavailable for evaluating uncommitted source directly, building is the promotion step the warning treats it as. - Provenance warnings (dirty-src gate and vendorupdate's dirty source-project check) are presented with a plain column-0
PROVENANCE-WARNING:token for automated discovery in redirected output plus ANSI colour for humans, and are recapped at the very end of the run (via a wrapped::exit) so they survive scrolling chatty build output. Interactive terminal runs (Tcl 8.7+/9 stdin-inputmodeprobe) additionally get a 3-second ctrl-c grace countdown before a dirty build proceeds; piped/agent/CI runs pay no delay.make.tcl checknow reports src provenance status and what the build/promotion commands would do.
[0.10.2] - 2026-07-11
- punk::libunknown bumped 0.1 → 0.2.0 (file renamed
libunknown-0.2.0.tm), retroactively versioning the register_all_tm and source_pkgindex additions and adopting fullmajor.minor.patchform. Verified nothing requires it by exact version or filename: punk_main.tcl and punk::repl globlibunknown-*.tmpicking the highest by vcompare (the dev copy now also outversions the stale bootsupport/project.vfs0.1copies deterministically), bootsupport's include_modules.config lists it by name only. The module header now carries a version-history block in lieu of a buildversion.txt, andsrc/modules/AGENTS.mddocuments the manual-versioning bump mechanics for agents (same Patch/Minor/Major rules as buildversion-tracked modules).
[0.10.1] - 2026-07-11
- punk::libunknown: pkgIndex.tcl scripts are now executed in an isolated
source_pkgindexframe providing the documented$dirvariable plusauto_path/envglobal links (matching stock tclPkgUnknown's contract), instead of at::scope with aglobal dir. Fixes any user global nameddirbeing silently overwritten whenever apackage requirefell through to the pkg unknown handler, and stops index scripts' helper variables (ver,pkg,script,_CawtSubDirs, ...) leaking into the global namespace. Verified against tcllib 2.0's index behaviours (auto_path extension, apply-scoped subindex sweep, critcl-style loaders); regression tests pin the$dir/auto_path/no-leak contract.
[0.10.0] - 2026-07-11
dev lib.searchnow performs deep module discovery by default: newpunk::libunknown::register_all_tmregisters.tmmodules at every namespace depth across all tm paths (reusing/populating the per-epoch directory index cache, at most one scan perpackage epochper interp), so namespaced modules in never-requested subfolders (e.g.test::*) appear in search results without-refresh(punk::mix::commandset::loadedlib 0.2.0).dev lib.search -refreshrepurposed to mean a genuine filesystem re-scan: it increments the package epoch (invalidating punk::libunknown's scan caches) and re-runs discovery, picking up.tmfiles added/removed on disk and re-sourcingpkgIndex.tclfiles. Without punk::libunknown active,-refreshretains the previous dummy-require deep-walk behaviour.- lib.search dependency fixes: works in bare interps now — highlight ANSI codes computed only when highlighting (fully-qualified
punk::ansiwith inline require; previously errored on the shell-globala+alias even with-highlight 0), inline requires forpunk::path(fallback walk) andtextblock(table output).
[0.9.1] - 2026-07-11
dev lib.search-refreshhelp rewritten to document actual semantics (punk::mix::commandset::loadedlib 0.1.1, doc-only): the flag performs a deep tm discovery pass (registering.tmmodules in never-requested namespace subfolders), it does not re-scan directories already indexed in the currentpackage epoch(runpackage epoch incrfirst for a genuine filesystem re-scan), and tm/auto_path list changes are epoch-invalidated automatically. New characterization test suites pin the underlying punk::libunknown discovery/epoch-cache behaviour (src/tests/modules/punk/libunknown/testsuites/discovery/) and the lib.search match +-refreshcontract (src/tests/modules/punk/mix/testsuites/loadedlib/), including a GAP pin of the pkg-unknown handler clobbering a user globaldirvariable (stock Tcl keeps it proc-local).
[0.9.0] - 2026-07-11
- G-001 (in progress) increment 1: three pluggable
::opunk::Consolebackend modules, with the base class and punk::console untouched —opunk::console::test(::opunk::TestConsole: deterministic channel-pair test double with fixed size and probe-free eof — the console seam the repl/editbuf characterization work needs),opunk::console::ssh(::opunk::SshConsole: socket-carried terminal sessions — construction-time capability, chan-eof without byte-consuming probes, and size resolved by punk::console's ANSI cursor-report provider querying over the connection, proven against a scripted remote terminal answeringCSI 6nover a socket pair), andopunk::console::tk(::opunk::TkConsole: a Tk text widget as terminal — widget char dimensions as size, backend eof marker viaopunk::console::tk::set_eof, verified live under the tk-capable punk91 kit). Subclass values dispatch through existing base-class holders andconsole_spec_resolvevirtually. Remaining for the goal: repl launch-time console selection and output-channel parameterization.
[0.8.2] - 2026-07-11
- G-054 achieved: tclcore moduledoc 0.2.0 — the
string isclass choices shown byi string is(and the per-class docids likei string is digit) are now harvested from the running interpreter at define time instead of a hand-maintained list, so the documented/parsed class set always matches what the interpreter accepts (previously the static Tcl 9.0 list wrongly accepteddictunder 8.6 and rejected 8.7'sunicode). Version notes render on classes that differ across releases; unrecognized future classes get a generic label instead of vanishing. Behavioural parity pinned bytclcoreparity.testwith expectations derived from the live interpreter — green on Tcl 8.6.13, 8.7a6 and 9.0.3.
[0.8.1] - 2026-07-11
runtime.cmdpowershell payload: cachedsha1sums.txtfallback backported from the bash payload -list -remoteagainst an unreachable server now warns and compares using the previously fetched copy instead of dying on an unhandled download error, and thefetchpath's pre-existing silent fall-through to a cached copy now announces itself. Also fixed a latent undefined-variable bug creating the runtime folder in thelist -remotebranch.
[0.8.0] - 2026-07-11
runtime.cmd list -remoteparity for the unix (bash/zsh) payload: local-vs-server comparison table (Same version / UPDATE AVAILABLE / not-listed, plus remote-only entries), falling back to a cachedsha1sums.txtwith a warning when the server is unreachable. Both payloads gain aPUNKBIN_URLenv override of the artifact server base url (mirrors/testing).- The polyglot's 512-byte label guard caught its first real regression during this change: the payload growth pushed the template's
:exit_multishelllabel across a boundary; fixed with a documented byte-alignment spacer comment inruntime.bash(workflow recorded in bin/AGENTS.md). - G-059 achieved: WSL capability probing + native-filesystem staging for driving unix-side tests from Windows (
src/tests/testsupport/wslprobe.tcl,wsllinuxconstraint). The MULTISHELL sh payload and the runtime.cmd unix payload (runtime.bash— never previously executed on real unix) now run green under WSL: active/use/run resolution, env override, stale-active guidance, single-candidate fallback and offlinelist -remote— all staged to the distro's native filesystem, with a guard test asserting the Windows checkout's git state is untouched.
[0.7.0] - 2026-07-11
bin/runtime.cmdgains ausesubcommand and an active-runtime selection: which runtimerunlaunches is now the per-machinebin/runtime/<platform>/active.toml(active = "<name>", shown with a*inlist), resolved asPUNK_ACTIVE_RUNTIMEenv override →active.toml→ sole installed candidate — with multiple runtimes and no selection,runerrors listing candidates instead of silently launching the last name alphabetically. The firstfetchsets the active runtime only when none is recorded; later fetches never steal it.runtime.cmd fetchchecksum parity for the unix (bash/zsh) payload: it now fetchessha1sums.txt, skips when the local file already matches, downloads to.tmpand installs only on sha1 match (tool detection acrosssha1sum/shasum/sha1/openssl; refuses unverified downloads when no tool is present), and accepts an optional runtime name like the powershell payload. Bug fixes: the powershell "stored hash" message printed an empty variable; the bash MSYS branch had an invalidinterp =assignment;.tmpleftovers and non-runtime files no longer appear as run/list/use candidates.- The runtime scriptset sources moved to
src/scriptapps/bin/(alongsidegetzig.*), the proper home for bin-deployed scriptsets;bin/runtime.cmdregenerated via the scriptwrap workflow (round-trip pinned byte-identical by the multishell test suite).
[0.6.0] - 2026-07-10
- G-058: punkshell boot honours statically-linked runtime packages. Kits built on runtimes with static extensions (e.g
tclsfe-x64.exe: Thread/twapi/sqlite3/tdbc — the punk91 kit) previously lostpackage requireaccess to them in every interp/thread punkshell fabricates: the appended vfs replaces the runtime's own//zipfs:/appmount (taking its pkgIndex files with it) and punkshell's boot path replacement discards what remains — the repl code interp failed withcan't find package Threadand punk::console couldn't load. Nowpunk_main.tclcaptures the static baseline at boot (probe-loading each empty-filenameinfo loadedprefix in a throwaway interp and recording only packages the load actually provides; configurable denylist for side-effecting/composite inits), and the baseline seedspackage ifneeded <name> <ver> {load {} <prefix>}mappings in the boot interp, the repl codethread and code interp (punk::lib 0.4.0interp_sync_package_paths/snapshot_package_paths, punk::repl 0.3.0), and shellthread 1.7.0 workers — introspectable at the repl via::punkboot::static_packages. - punk::packagepreference 0.2.0: static-vs-bundled resolution is version-aware — requiring a baseline package triggers the package-index scan before resolution so all candidates register and the highest version wins (a static copy is no longer masked by an older bundled dll, and a genuinely newer bundled copy remains reachable); static registrations (empty-filename
info loadedentries) no longer trip the loaded-shared-object same-version pinning. Composite statics whose script layer lived in the runtime's replaced zipfs (e.g. static twapi) provide nothing under the probe and correctly defer to bundled complete copies. - Tests:
staticseed.test+staticpolicy.test(un-gated, simulated baselines) andstaticruntime.test(kit integration behind the capability-probedstatickitavailableconstraint). The verification runtimetclsfe-x64.exeis pinned in the punkbin artifact repository (win32-x86_64 + sha1sums) so the constraint is satisfiable on other machines.
[0.5.0] - 2026-07-10
- punk::args 0.5.0 (G-049): new
punk::args::parse_status- runs a parse attempt and returns a documented parse-status structure instead of raising on validation failure: overallok/status(valid|invalid|incomplete)/scheme/message/errorcode/failureclass/badarg/form/receivednamesplus per-argumentargstatusentries (class, status ok|bad|unparsed, received count/positions, value-in-effect including-defaultfill).arg_erroraccepts the structure via-parsestatusand both its renderers derive goodarg/badarg row marking and choice value-in-effect highlighting from it. Scheme colours now resolve per-render: the documented-schemevaluenocolourtakes effect (previously it fell through to whatever colours the last scheme render left behind) and scheme renders no longer mutate the shared colour array (the strike-only goodarg style no longer leaks into later renders).missingrequiredvalue/missingrequiredleaderfailures now carry-badarg, andpunk::args::parsegained-callerto control the%caller%attribution in failure messages. - punk::ns 0.2.0 (G-049):
i <cmd> <args...>(cmdhelp) gains-return dict- a machine-parsable dict of resolution info (origin/docid/cmdtype/args_remaining) plus the parse-status structure of the supplied argument words. Display fixes: a value failing its-typecheck now badarg-marks the unfillable argument's row (previously only choice violations marked anything), an explicit-schemeis honoured on the parse-failure path, and parse-failure messages name the queried command instead of leaking cmdhelp's internal parse source line at top call depth.
[0.4.15] - 2026-07-10
- punk::args 0.4.2 (G-046): argument resolution no longer expands display-only
${...}content (-helpon@cmd/@examples/argument records,@formdisplaybodies) - expansion is deferred to help-display time with its own cache. First use of heavily documented commands is dramatically faster (punk::ansi::mark_columnsfirst call ~4.3s → ~12ms; tclcore::lseqresolve ~184ms → ~2ms) and-helpcontent that calls punk::args-parsing commands (including against its own definition id) resolves cleanly instead of stalling or looping. Also fixed:@dynamicmultiline-helpsubstitutions now align at their insertion column; prefix/alias-normalized choice values keep the same plain-string shape as exact input (\Deleted-style values); the-return stringrenderer aligns cmd-help continuation lines under theDescription:label and itsExample:line shows the example reference instead of the doc url. - punk::ns 0.1.4 (G-046):
i <cmd>for a command whose definition requires arguments (e.gi string is,i punk::args::define) shows plain usage instead of an internal-looking "Bad number of leading values for punk::args::parse ..." error prefix - and builds the usage table once, not twice (the discarded advisory-parse error no longer renders its own table; display timing for large argdocs stays at pre-change levels).
[0.4.14] - 2026-07-10
- punk::args 0.4.1: first
i <ensemble>in a fresh shell now shows subcommand-help markers and synopsis choicelabels for documented subcommands whose argdocs are lazily registered (e.gi ansistring); previously the autogenerated ensemble help omitted them until another path loaded the ensemble's registered namespace (punk::args::update_definitions).
[0.4.13] - 2026-07-09
- punk::args 0.4.0 tidy-up (pre G-046): dead developer-test procs removed (
define2,parseXXX, the unused::punk::args::TESTdefinition); the interactiveGet_callerdiagnostics andlib::tstr_test_onerenamed with leading__and unexported; internal parser/renderer helpers moved from the exportedpunk::argsnamespace into a new internalpunk::args::privatenamespace (underscore prefixes dropped); every remaining exported command now carries a PUNKARGS definition, soi/punk::args::usagerender documentation for the whole punk::args API (includingpunk::args::libutilities and thehelpers/argdocbaseANSI shorthands).
[0.4.12] - 2026-07-09
- Tcl 9.1b0 runtime compatibility (first
punk91.exebuild ontclsfe-x64; the developed baseline remains Tcl 9.0.2):- punk::lib 0.3.1: TIP 746 removed
lseq's expr-operand behaviour in Tcl 9.1 —punk::lib::range(lseq branch) now normalizesint[+-]intoffset operands itself, so callers likerange 0 [llength $list]-1keep working (this brokepunk::ansi::grepstrand with it example-block highlighting and the punk::args examples.test under 9.1). Also aligned the lseq branch with the tcl8 fallback contract: defaultbynow infers direction (descendingrange 5 1previously returned empty under tcl9 — silently breaking documented reverse-range callers) andby 0returns an empty list (9.1'slseq ... by 0changed to return one element). Directlseqexpression operands wrapped inexpr(lzipn_tcl9b/lzipn_tcl9c/cols/cols2).check::has_tclbug_safeinterp_compilefalls back tointerp invokehidden tcl:unsupported:disassemble— Tcl 9.1 safe interps hidetcl::unsupported::*instead of exposing it. - punk::args 0.3.2:
zero_based_posnsexpr-wraps itscount-1lseq operand (TIP 746). - New
modules/punk/librange.test pins therangecontract (offset expressions, direction inference,by 0) under both 9.0 and 9.1.
- punk::lib 0.3.1: TIP 746 removed
[0.4.11] - 2026-07-09
- punk::args 0.3.1: fixed
helpers::example-titlepath calling bare[a](resolvable only where a globalaalias exists, e.g. punk shells — errored under plain tclsh); found by the new test coverage. - punk::args test suite grown to 128 tests across 15 files with four new characterization areas, added before any changes to the definition-parsing/indentation machinery (user-directed tests-first):
- rendering.test (15): nesting independence (plain + tstr defs), relative-indent preservation (the 2-space help and 1-space choicelabel conventions, single and multiline),
-unindentedfields(arg ✓;@cmdaccepts-but-ignores — GAP pinned), constructed (string-built) definition absolute-indent characterization, multiline${[cmd]}/${$var}/resolved_definsertions (aligned, nesting-independent), and@dynamic${$DYN_X}double substitution (stable across resolutions, provider refresh honoured in help/choices/parse, textblock::frame-style art choicelabels byte-aligned — but multiline-helpinsertions lose insertion-column alignment for lines 2+, GAP pinned: the second-round subst lacks paramindent re-alignment). - choicegroups.test (5): group/
-choicesunion parsing, cross-group prefixes, duplicate-entry dedup, per-group titled choice tables, and punk::imap4-style{\Deleted}/{$MDNSent}values with labels — plus a GAP pin: prefix-normalization list-quotes special-character choices (\Destores{\Deleted}where exact input stores plain\Deleted). - defquoting.test (3): container quoting rules pinned — braced values fully literal (
$,[], two-char\n, bare backslashes), quoted values get Tcl backslash semantics (\n→ newline,\\→\) with$/[]still literal, and\$\{...\}renders a literal${...}in tstr-processed blocks. - examples.test (6): helpers::example box structure/title/
-tstrtoggle (no-dedent direct-call contract pinned),${[example ...]}insertion into@cmdhelp aligned with the autoExample:row,@examples→punk::args::egwith#<nodisplay>/@#<nodisplay>stripping (ANSI-tolerant), strip_nodisplay_lines unit, and a live tclcore::lseqsmoke (the heaviest example consumer).
- rendering.test (15): nesting independence (plain + tstr defs), relative-indent preservation (the 2-space help and 1-space choicelabel conventions, single and multiline),
- Investigated punk::ansi::mark_columns first-call slowness (reproduced: 3.94s first call, 60µs thereafter): the argdoc
-helpcontains${[...num_columns_example]}which itself callsmark_columns, whose parse resolves the same still-resolving definition — the in-source TODO already documents the recursion hazard and candidate fixes (reentrancy guard, or deferring-helpprocessing out of argument resolution, which would also help general first-parse performance). Recorded for goal consideration rather than patched.
[0.4.10] - 2026-07-08
- G-040 completed (activated and flipped to achieved same day, user-directed): punk::args 0.3.0 adds
-choicealiases {alias canonical ...}— aliases accepted exact under any-choiceprefix/-nocasesetting, participating in prefix calculation when prefixing is on, always normalizing to the canonical choice in parse results; deny semantics apply to the matched name (a denied alias needs the full alias; a canonical reached via its alias is exempt from the canonical's own deny entry); usage display folds aliases into the canonical entry as an(alias: …)label note. The choice-word matching chain was extracted fromget_dictinto the shared resolverpunk::args::choiceword_match, now also consumed by punk::ns 0.1.2'scmd_traverse— closing the doc-lookup parity gap (deny/reserve lists were honoured by parse but ignored by the walk; the pinned GAP tests flipped to agreement) and normalizing aliases before choiceinfo lookup. - punk 0.2.3: punk::help adopts the feature —
i helplists one entry per registered topic (topics+alias help,tcl,env+alias environment,console+aliases term|terminal), and topic words accept aliases and unique prefixes with the user-decided minimum-prefix policy:h/he/hel,e/en,te/ter, and the reservedc/to/tcall fall through to command lookup. Arglesshelpoutput remains byte-identical to the strict-80 baseline. - Suites: punk/args 98 pass + 1 skip (5 new alias tests incl. the punk::help policy matrix), punk/ns 28 pass (parity tests flipped, alias traverse + display-fold assertions), punk/lib 21 pass.
[0.4.9] - 2026-07-08
- punk 0.2.2 (doc-only, from interactive review of the help restructure):
i help/i help <topic>usage tables narrowed to reasonable widths (61-68 columns, previously ~160) by manually folding the helptopic argdoc help texts at ~70 columns and rendering the generated topic-choice grid with-choicecolumns 2. Only the arglesshelpoverview is strictly 80-column (unchanged, byte-identical); usage tables do not yet wrap to terminal width, so punk::args source line lengths directly set table width — automated (potentially language-dependent) wrapping, e.g. via tcllib's text-adjust facilities, is a possible future improvement.
[0.4.8] - 2026-07-08
- G-037 completed (flipped to achieved): new
make.tcl vfslibsstep (also run insidemake.tcl project) propagates declared vendored platform-library packages into kit vfs lib_tcl trees — declarations insrc/runtime/vendorlib_vfs.toml(tomlish-parsed, per-package per-kit with explicitsupersedesremoval so no silent mixed-version provision; punkcheck provenance at src/vfs/.punkcheck, outside kit payloads; malformed entries fail the build naming the entry). G-024's mapvfs toml conversion was not required; the file is recorded as a candidate for absorption into it. Authority is the declaration — undeclared drift (e.g. the vendorlib/kit twapi divergence) is deliberately untouched. - 8.6 kits upgraded to tcludp 1.0.13 via the new step (the G-036 loose-end decision): the 1.0.13 folder is dual-generation (pkgIndex selects tcl9udp1013.dll or udp1013t.dll), so the single vendorlib_tcl9 source serves punk8win.vfs/lib_tcl8, replacing udp 1.0.12. Verified on rebuilt kits: punksys/punkbi (8.6.13) and punk902z (9.0.2) all load udp 1.0.13 from their vfs; no udp1.0.12 remains under src/vfs.
[0.4.7] - 2026-07-08
- G-036 completed (flipped to achieved):
punk::lib0.3.0 addspunk::lib::check::has_libbug_udp_threadexit— version-based detection of the tcludp < 1.0.13 thread-exit bug on Tcl 9 Windows (the per-thread exit handler closes process-global event handles, silently freezing every other udp-using thread's event loop after any udp-loaded thread exits; root-caused and fixed-by-upgrade earlier in 0.4.3).has_libbug_*is the new check family for bundled/vendored library bugs;help tcl(punk 0.2.1) now scans it alongsidehas_tclbug_*, supports a fullurlreference key for non tcl-core trackers, and no longer errors on a triggered check carrying a reference without a description. Detection is loaded-version based, falling back to the best available registered version without loading the binary. New checkbugs.test covers the classifier matrix, the live check's dict shape/consistency, and a contract test over all existing check procs. Open decisions recorded in the G-036 detail: punk8win (8.6) kit's udp 1.0.12 swap; optional upstream tickets for residual tcludp trunk weaknesses.
[0.4.6] - 2026-07-08
- punk::ns 0.1.1: five development trace
putsremoved from the command doc-lookup machinery — "PROC auto def"/"ENSEMBLE auto def" from generate_autodef were emitted on STDOUT and pollutedi/soutput in script/exec contexts (visible to agents pipingi <cmd>per the G-015 pattern); "skipping to documented subcommand", "cmd_traverse ensembleparam" and the "cmd_traverse 10 ... review" fallthrough note were stderr noise on the space-form-id, ensemble-parameter and undocumented-tail traverse paths. No functional change. - punk/ns cmdflow.test: 8 new tests characterizing ensemble
-parametershandling in the doc-lookup flow (the punk::netbox::man pattern — a leading apicontextid before the subcommand): generate_autodef models each parameter as a-ensembleparameter 1leader with @leaders min/max = nparams+1 (single- and two-parameter fixtures), cmd_traverse consumes parameter words and resolves the subcommand's explicit or autodef docid (re-presenting the parameter in args_remaining for the subcommand's own leader parse, matching punk::netbox::man's explicit defs), nested sub-ensembles with their own -parameters re-consume the curried parameter at each level, parse treats -ensembleparameter leaders as ordinary named leaders, and cmdhelp renders a documented subcommand's usage through the parameter.
[0.4.5] - 2026-07-08
- punk::args 0.2.3: fixed
@opts -any 1(arbitrary/adhoc option passthrough) — an option not present in the definition crashed parsing with "can't read argname" instead of passing through with its value (real consumers: vendored tomlish definitions declare-any 1); silenced a debugputs stderrthat fired on every failed clause type assignment (visible on any multiform parse miss). Found while building the punk::args comprehensiveness pass. - punk::args test suite expanded (94 tests, was 71 at start of day): new forms.test characterizes multi-form (@form) parsing and pins the G-041 gaps — parse without -form is effectively form-0-only, -form rejects the documented list-of-forms usage, and the @form -synopsis override is stored but ignored by synopsis rendering; new validation.test covers the -type validation matrix, -range/-minsize/-maxsize, -nocase choice normalization, option -multiple accumulation, required-option enforcement, unknown-vs-adhoc option handling, the -- end-of-options marker, @values -max enforcement, received-key clause ordinals, solos, and default-vs-received distinction.
[0.4.4] - 2026-07-08
- punk::args 0.2.2 (doc-only): the
punk::args::definedocumentation for the -choice* fields now spells out the verified interplay semantics —-choicerestricted 0passthrough of non-matching/ambiguous/denied/reserved words,-choiceprefixnormalization of accepted prefixes to the canonical choice in parse results (with minimal-prefix highlighting in usage display), and the-choiceprefixreservelistphantom-entry idiom for per-choice minimum-prefix control. Characterization tests added (choices.test unrestricted-mode tests; new punk/ns cmdflow.test for the cmdwhich/cmdinfo/cmd_traverse docid flow, pinning the parse-vs-doc-walk deny/reserve divergence as GAP pending G-040). - help system restructured onto a topic registry (punk module 0.2.0,
::punk::helptopic): each topic (topics|help,tcl,env|environment,console|term|terminal) is a handler proc with its own punk::args definition, and the::punk::help/::punk::help_chunksdefinitions are (re)generated from the registry —i helpnow renders a documented usage table with topic choices and summaries, andi help <topic>shows per-topic documented usage (previously an autogenerated stub).help topicsis derived from the registry (lists all aliases, fits 80 columns). No-arg overview and command-fallthrough (help <cmdname>) output byte-identical to before; 80-column layout preserved; verified on both generations, script and shell subcommands.help envwithout an initialised punk::config (e.g. script contexts) degrades to a one-line notice instead of an error stack. The registry is the intended seam for future subshell-declared topics (punk::config-gated — not yet a goal).
[0.4.3] - 2026-07-08
- vendored tcludp upgraded 1.0.12 -> 1.0.13 in the tcl9 kit vfs folders (punk9win.vfs, punk9win_for_tkruntime.vfs) and src/vendorlib_tcl9 — 1.0.12's Windows per-thread exit handler closed the process-global tcludp synchronization events, so the first udp-loaded worker thread to die froze every other udp-loaded thread's event loop (root cause of the G-036 wedge; fixed upstream in 1.0.13). Verified with the G-036 regression harness: run-2 syslog workers alive (baseline on 1.0.12: wedged 4/4). Note: punk8win.vfs still bundles udp 1.0.12 (8.6 appeared immune; pending decision). The manual vfs copy was required because
libs/vfscommonupdate/projectdo not propagate vendorlib_tcl platform libraries into kit vfs lib_tcl trees — gap recorded as goal G-037.
[0.4.2] - 2026-07-08
- piped-stdin exit/quit hang fixed (shellthread 1.6.3, shellfilter 0.2.4): repl/app teardown no longer blocks forever when a shellthread worker's event loop has wedged — unsubscribe's settings-reset send is now async, shutdown_free_threads keeps its timeout armed across all waits, and shellfilter::run honors its -syslog option (default empty -> no runtag log worker thread) instead of a hardcoded 127.0.0.1:514 debug leftover. Syslog remains supported when explicitly configured. Diagnosis and residual root-cause work tracked as goal G-036.
[0.4.1] - 2026-07-07
scriptsubcommand now matchestclshfor GUI scripts: if the script leaves a registered Tk main loop (Tk loaded with a live main window), the event loop is serviced until the last window closes, instead of sourcing-then-exiting immediately. So a Tk script with no explicitexit(or one that exits from anaftercallback, likescriptlib/tktimer.tcl) stays alive and runs — previously it flashed and died, andshellwas needed as a workaround (relevant to G-020 GUI automation). Console scripts are unaffected; a script that errors exits at once (no hanging window). Verified on both generations.
[0.4.0] - 2026-07-07
scriptsubcommand supportslib:<name>scriptlib scripts (with or without.tclextension), matching theshellsubcommand's scheme:punkexe script lib:hello, or barepunkexe lib:hellovia reclassification. The prefix always wins — a literal path beginninglib:(pathological; illegal on Windows filesystems) is reachable via./lib:.... Not-found errors list the searched locations. Only.tclruns via the script subcommand.- punk::path 0.2.2: new
scriptlib_resolve— the sharedlib:resolution policy (kit-internalapp/scriptlibfirst and not externally overridable, then scriptlib dirs relative to the executable), PUNKARGS-documented. app-punkshell still carries its inline copy of the policy (refactor onto the shared proc noted as todo).
[0.3.1] - 2026-07-07
scriptsubcommand: core-command documentation parity with the interactive shell — app-punkscript now loadspunk::args::moduledoc::tclcore(catch-guarded, ~40ms) so e.g.'i list' | punkexe scriptrenders the doc table instead of "Undocumented command". Verified on both generations; kit startup ~0.33s.- punk::packagepreference 0.1.1: the moduledoc auto-load success notice moved from stdout to stderr — stdout must stay clean for script/exec contexts (the failure branch already used stderr).
[0.3.0] - 2026-07-07
<punkexe> scriptcompleted (goal G-015 achieved): runs a script file (script <file> ?args?, conventional ::argv0/::argv) or the whole of piped stdin (<commands> | <punkexe> script— no trailingexitneeded) in the default punk shell module/alias environment, so one-liners likedev projects.work *name*work with no boilerplate. Honest exit codes (0 success, 1 error with errorInfo on stderr, script's ownexithonoured); no shellfilter transforms or logging side effects; never falls into an interactive shell. Implemented as the leanapp-punkscriptpackage; the stdin form echoes the script's final result when non-empty. Verified on both Tcl generations (punk902z, punksys).
[0.2.7] - 2026-07-07
- vendored tomlish 1.1.10: the library API now carries punk::args (PUNKARGS) documentation (from_toml, to_dict, from_dict, to_toml, update_tomlish_from_dict) — the G-014 tomlish precondition is met (documented upstream, re-vendored from a clean checkout); plus the explicit
tomlish::cmdline_mainentry point. _vfscommon.vfskit payload refreshed to the current built modules: shellfilter 0.2.3, shellrun 0.1.4, punkboot::utils 0.1.1, punk::console 0.7.1 content catch-up, tomlish 1.1.10.
[0.2.6] - 2026-07-06
- shellfilter 0.2.3:
shellfilter::runnow guarantees tee-stack removal (stdout/stderr restoration) via try/finally even when its body errors, and the decorative stack-status table rendering inlog::criticalblocks is catch-guarded. Previously an error there (observed: a stale same-version textblock snapshot calling the new punk::ansisgr_merge_singleswith old option syntax) aborted the run between channel diversion and restoration, leaving the process's stdout/stderr broken and all subsequent output silently lost. - runtests.tcl: testinterp tm path order fixed so the bootsupport snapshot wins same-version module ties over vendormodules (verified rule on Tcl 9.0.3, standard and punk::libunknown scanners:
tcl::tm::addprepends, head oftcl::tm::listwins ties, so the lasttest_tmlistelement wins); testinterp auto_path gains the parent of[info library]so binary packages such as Thread resolve in projects without a rootlib_tcl<N>/<arch>payload.
[0.2.5] - 2026-07-06
make.tcl vendorupdatenow checks each vendor source project's fossil/git checkout state and warns (non-fatal, once per VCS root) when pulling from a dirty tree — vendored artifacts built from uncommitted source have no committed provenance. Enforcement policy (abort/override, bootsupport coverage) tracked by goal G-026.- punkboot::utils 0.1.1: the dirty-checkout check lives in the module as
vcs_dirty_warnings(make.tcl calls it via a guarded lazy require and degrades to skipped if the bootsupport snapshot lacks it); bootsupport snapshots refreshed (punkboot::utils 0.1.1, shellrun 0.1.4, punk::console 0.7.1 content catch-up).
[0.2.4] - 2026-07-06
- shellrun 0.1.4: added missing
package require punk::args(the 0.1.3 migration leftrunx/run/runout/runerrcallingpunk::args::parsewithout requiring it, breaking shellrun in bare interps — including thesrc/tests/runtests.tcltestinterp, which made every source-tree test run fail).
[0.2.3] - 2026-07-06
- shellrun: removed
-tclfromsh_run,sh_runout,sh_runerr,sh_runx(was silently swallowed with no useful effect becausesh -cis always an external shell; now rejected with a usage message). - shellrun: migrated
runxfrom the legacyget_run_optsparser topunk::args::parsewith a full PUNKARGS spec;runxnow honours-debugand--timeout=(previously accepted but silently ignored). - shellrun: expanded PUNKARGS documentation for
run,runconsole,runout,runerr, andrunxwith@cmdmetadata and-helptext on all opts/values. - shellrun: migrated
sh_run,sh_runout,sh_runerr,sh_runxfromget_run_optstopunk::args::parsewith dedicated PUNKARGS specs. - shellrun: removed the internal
get_run_optsproc; all callers now usepunk::args.
[0.2.2] - 2026-07-06
- punk::console: terminal queries fired while an 8.6-based shell waits at an idle line-mode prompt now fail fast with a discriminable errorcode (
PUNK CONSOLE QUERY HOSTAGE_COOKED_READ) and emit nothing, instead of timing out (~500ms) and later corrupting input with the swallowed response (idle-reader hostage guard; raw mode and mid-command queries unaffected). Owner-routed queries preserve the owner-side errorcode.
[0.2.1] - 2026-07-06
make.tcl projectversion: new advisory subcommand verifyingCHANGELOG.mdmatchespunkproject.tomland warning ifsrc/has commits since the last project-version bump.- Clarified project versioning policy: the
make.tclcommand interface is part of the product surface.
[0.2.0] - 2026-07-05
- Initial tracking of the punkshell project version in
punkproject.toml.