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.
 
 
 
 
 
 

27 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.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 lost package require access to them in every interp/thread punkshell fabricates: the appended vfs replaces the runtime's own //zipfs:/app mount (taking its pkgIndex files with it) and punkshell's boot path replacement discards what remains — the repl code interp failed with can't find package Thread and punk::console couldn't load. Now punk_main.tcl captures the static baseline at boot (probe-loading each empty-filename info loaded prefix in a throwaway interp and recording only packages the load actually provides; configurable denylist for side-effecting/composite inits), and the baseline seeds package ifneeded <name> <ver> {load {} <prefix>} mappings in the boot interp, the repl codethread and code interp (punk::lib 0.4.0 interp_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 loaded entries) 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) and staticruntime.test (kit integration behind the capability-probed statickitavailable constraint). The verification runtime tclsfe-x64.exe is 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: overall ok/status (valid|invalid|incomplete)/scheme/message/errorcode/failureclass/badarg/form/receivednames plus per-argument argstatus entries (class, status ok|bad|unparsed, received count/positions, value-in-effect including -default fill). arg_error accepts the structure via -parsestatus and both its renderers derive goodarg/badarg row marking and choice value-in-effect highlighting from it. Scheme colours now resolve per-render: the documented -scheme value nocolour takes 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/missingrequiredleader failures now carry -badarg, and punk::args::parse gained -caller to 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 -type check now badarg-marks the unfillable argument's row (previously only choice violations marked anything), an explicit -scheme is 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 (-help on @cmd/@examples/argument records, @formdisplay bodies) - expansion is deferred to help-display time with its own cache. First use of heavily documented commands is dramatically faster (punk::ansi::mark_columns first call ~4.3s → ~12ms; tclcore ::lseq resolve ~184ms → ~2ms) and -help content that calls punk::args-parsing commands (including against its own definition id) resolves cleanly instead of stalling or looping. Also fixed: @dynamic multiline -help substitutions 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 string renderer aligns cmd-help continuation lines under the Description: label and its Example: 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.g i 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.g i 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::TEST definition); the interactive Get_caller diagnostics and lib::tstr_test_one renamed with leading __ and unexported; internal parser/renderer helpers moved from the exported punk::args namespace into a new internal punk::args::private namespace (underscore prefixes dropped); every remaining exported command now carries a PUNKARGS definition, so i/punk::args::usage render documentation for the whole punk::args API (including punk::args::lib utilities and the helpers/argdocbase ANSI shorthands).

[0.4.12] - 2026-07-09

  • Tcl 9.1b0 runtime compatibility (first punk91.exe build on tclsfe-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 normalizes int[+-]int offset operands itself, so callers like range 0 [llength $list]-1 keep working (this broke punk::ansi::grepstr and with it example-block highlighting and the punk::args examples.test under 9.1). Also aligned the lseq branch with the tcl8 fallback contract: default by now infers direction (descending range 5 1 previously returned empty under tcl9 — silently breaking documented reverse-range callers) and by 0 returns an empty list (9.1's lseq ... by 0 changed to return one element). Direct lseq expression operands wrapped in expr (lzipn_tcl9b/lzipn_tcl9c/cols/cols2). check::has_tclbug_safeinterp_compile falls back to interp invokehidden tcl:unsupported:disassemble — Tcl 9.1 safe interps hide tcl::unsupported::* instead of exposing it.
    • punk::args 0.3.2: zero_based_posns expr-wraps its count-1 lseq operand (TIP 746).
    • New modules/punk/lib range.test pins the range contract (offset expressions, direction inference, by 0) under both 9.0 and 9.1.

[0.4.11] - 2026-07-09

  • punk::args 0.3.1: fixed helpers::example -title path calling bare [a] (resolvable only where a global a alias 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 ✓; @cmd accepts-but-ignores — GAP pinned), constructed (string-built) definition absolute-indent characterization, multiline ${[cmd]}/${$var}/resolved_def insertions (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 -help insertions lose insertion-column alignment for lines 2+, GAP pinned: the second-round subst lacks paramindent re-alignment).
    • choicegroups.test (5): group/-choices union 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 (\De stores {\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/-tstr toggle (no-dedent direct-call contract pinned), ${[example ...]} insertion into @cmd help aligned with the auto Example: row, @examplespunk::args::eg with #<nodisplay>/@#<nodisplay> stripping (ANSI-tolerant), strip_nodisplay_lines unit, and a live tclcore ::lseq smoke (the heaviest example consumer).
  • Investigated punk::ansi::mark_columns first-call slowness (reproduced: 3.94s first call, 60µs thereafter): the argdoc -help contains ${[...num_columns_example]} which itself calls mark_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 -help processing 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/-nocase setting, 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 from get_dict into the shared resolver punk::args::choiceword_match, now also consumed by punk::ns 0.1.2's cmd_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 help lists 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 reserved c/to/tc all fall through to command lookup. Argless help output 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 argless help overview 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 vfslibs step (also run inside make.tcl project) propagates declared vendored platform-library packages into kit vfs lib_tcl trees — declarations in src/runtime/vendorlib_vfs.toml (tomlish-parsed, per-package per-kit with explicit supersedes removal 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::lib 0.3.0 adds punk::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 alongside has_tclbug_*, supports a full url reference 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 puts removed from the command doc-lookup machinery — "PROC auto def"/"ENSEMBLE auto def" from generate_autodef were emitted on STDOUT and polluted i/s output in script/exec contexts (visible to agents piping i <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 -parameters handling in the doc-lookup flow (the punk::netbox::man pattern — a leading apicontextid before the subcommand): generate_autodef models each parameter as a -ensembleparameter 1 leader 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 debug puts stderr that 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::define documentation for the -choice* fields now spells out the verified interplay semantics — -choicerestricted 0 passthrough of non-matching/ambiguous/denied/reserved words, -choiceprefix normalization of accepted prefixes to the canonical choice in parse results (with minimal-prefix highlighting in usage display), and the -choiceprefixreservelist phantom-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_chunks definitions are (re)generated from the registry — i help now renders a documented usage table with topic choices and summaries, and i help <topic> shows per-topic documented usage (previously an autogenerated stub). help topics is 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 env without 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/project do 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

  • script subcommand now matches tclsh for 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 explicit exit (or one that exits from an after callback, like scriptlib/tktimer.tcl) stays alive and runs — previously it flashed and died, and shell was 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

  • script subcommand supports lib:<name> scriptlib scripts (with or without .tcl extension), matching the shell subcommand's scheme: punkexe script lib:hello, or bare punkexe lib:hello via reclassification. The prefix always wins — a literal path beginning lib: (pathological; illegal on Windows filesystems) is reachable via ./lib:.... Not-found errors list the searched locations. Only .tcl runs via the script subcommand.
  • punk::path 0.2.2: new scriptlib_resolve — the shared lib: resolution policy (kit-internal app/scriptlib first 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

  • script subcommand: core-command documentation parity with the interactive shell — app-punkscript now loads punk::args::moduledoc::tclcore (catch-guarded, ~40ms) so e.g. 'i list' | punkexe script renders 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> script completed (goal G-015 achieved): runs a script file (script <file> ?args?, conventional ::argv0/::argv) or the whole of piped stdin (<commands> | <punkexe> script — no trailing exit needed) in the default punk shell module/alias environment, so one-liners like dev projects.work *name* work with no boilerplate. Honest exit codes (0 success, 1 error with errorInfo on stderr, script's own exit honoured); no shellfilter transforms or logging side effects; never falls into an interactive shell. Implemented as the lean app-punkscript package; 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_main entry point.
  • _vfscommon.vfs kit 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::run now guarantees tee-stack removal (stdout/stderr restoration) via try/finally even when its body errors, and the decorative stack-status table rendering in log::critical blocks is catch-guarded. Previously an error there (observed: a stale same-version textblock snapshot calling the new punk::ansi sgr_merge_singles with 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::add prepends, head of tcl::tm::list wins ties, so the last test_tmlist element wins); testinterp auto_path gains the parent of [info library] so binary packages such as Thread resolve in projects without a root lib_tcl<N>/<arch> payload.

[0.2.5] - 2026-07-06

  • make.tcl vendorupdate now 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 left runx/run/runout/runerr calling punk::args::parse without requiring it, breaking shellrun in bare interps — including the src/tests/runtests.tcl testinterp, which made every source-tree test run fail).

[0.2.3] - 2026-07-06

  • shellrun: removed -tcl from sh_run, sh_runout, sh_runerr, sh_runx (was silently swallowed with no useful effect because sh -c is always an external shell; now rejected with a usage message).
  • shellrun: migrated runx from the legacy get_run_opts parser to punk::args::parse with a full PUNKARGS spec; runx now honours -debug and --timeout= (previously accepted but silently ignored).
  • shellrun: expanded PUNKARGS documentation for run, runconsole, runout, runerr, and runx with @cmd metadata and -help text on all opts/values.
  • shellrun: migrated sh_run, sh_runout, sh_runerr, sh_runx from get_run_opts to punk::args::parse with dedicated PUNKARGS specs.
  • shellrun: removed the internal get_run_opts proc; all callers now use punk::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 verifying CHANGELOG.md matches punkproject.toml and warning if src/ has commits since the last project-version bump.
  • Clarified project versioning policy: the make.tcl command interface is part of the product surface.

[0.2.0] - 2026-07-05

  • Initial tracking of the punkshell project version in punkproject.toml.