punk 0.2.0: help system restructured onto ::punk::helptopic topic registry
- each topic (topics|help, tcl, env|environment, console|term|terminal) is a
handler proc returning {channel text} chunks, with its own punk::args
definition (id ::punk::helptopic::<topic>) so 'i help <topic>' renders
documented usage
- registering a topic (re)generates the ::punk::help / ::punk::help_chunks
definitions, so 'i help' shows a documented topic table that always matches
the registry (previously an autogenerated stub); the registry is the seam
for future subshell-declared topics
- 'help topics' derived from the registry (all aliases listed, fits 80 cols)
- no-arg overview and command-fallthrough output byte-identical to before;
80-column layout preserved; verified on tcl 9 and 8.6 kits via the script
and shell subcommands
- 'help env' degrades to a one-line notice when punk::config is not
initialised (e.g. script contexts) instead of an error stack + exit 1
- shared table_block helper destroys table objects after print (previously
leaked several per help invocation)
- project 0.4.4 (CHANGELOG entry)
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
@ -5,6 +5,10 @@ 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.4.4] - 2026-07-08
- 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<N> platform libraries into kit vfs lib_tcl<N> trees — gap recorded as goal G-037.
lappend cmdinfo [list help "?${I}topic${NI}?" "This help.\nTo see available subitems type:\nhelp topics\n\nFor an unrecognised ${I}topic${NI}\nhelp will look for basic\ninfo for it as a command.\n"]
set t [textblock::class::table new -minwidth 51 -show_seps 0]
#standard command-info table as used by the help overview blocks
proc table_block {frametype title rows {minwidth 80}} {
set t [textblock::class::table new -minwidth $minwidth -show_seps 0]
dict set choicelabels $name [dict get $tinfo summary]
}
}
set basehelp {Help system for the punk shell.
With no arguments - an overview of some key shell commands is displayed.
When the first argument is a recognised topic - help for that topic is displayed.
('help topics' lists the available topics)
Anything else is treated as a command name - basic command info (type and
synopsis) is shown for a resolvable command, or the resolved path for an
external executable.}
set topichelp {Help topic, or command words for basic command info. (topics must match exactly - no prefix matching)}
set specs [list]
lappend specs ::punk::help help "Punk shell help system." ""
lappend specs ::punk::help_chunks punk::help_chunks "Punk shell help system - content as {channel text} chunks." "\n\nhelp_chunks returns the help content as a list of {channel text} chunks rather than emitting it."
@cmd -name "help topics" -summary "List help topics." -help "Show the table of topics known to the help system, including registered aliases for each topic."
@values -min 0 -max 0
}
proc topics {context args} {
variable topics
set frametype [dict get $context frametype]
set t [textblock::class::table new -show_seps 0]
$t configure -frametype $frametype
$t add_column -headers [list "Topic"]
$t add_column
dict for {topic tinfo} $topics {
$t add_row [list [join [list $topic {*}[dict get $tinfo aliases]] |] [dict get $tinfo summary]]
}
$t add_row [list "*" "Look up as a command or external executable"]
@cmd -name "help tcl" -summary "Tcl version warnings." -help "Show the running Tcl patchlevel and build-info, with warnings for known Tcl bugs affecting this interpreter (as detected by the punk::lib::check::has_tclbug_* checks)."
@values -min 0 -max 0
}
tcl {
proc tcl {context args} {
set chunks [list]
set warningblock ""
set text "Tcl Patchlevel: [info patchlevel]"
catch {
append text \n "Tcl build-info: [::tcl::build-info]"
@ -8641,8 +8616,26 @@ namespace eval punk {
append warningblock [a]
}
lappend chunks [list stdout $text]
lappend chunks [list stderr $warningblock]
return $chunks
}
punk::args::define {
@id -id ::punk::helptopic::env
@cmd -name "help env" -summary "punkshell environment vars." -help "Show punk-related and other relevant environment variables with their current values."
@values -min 0 -max 0
}
env - environment {
proc env {context args} {
if {[catch {package require punk::config} errM]} {
return [list [list stderr "help env: punk::config package not available - no environment variable info ($errM)\n"]]
}
if {![info exists ::punk::config::punk_env_vars_config] || ![info exists ::punk::config::other_env_vars_config]} {
#punk::config::init has side effects (config dir/file creation) - don't trigger it just for help
return [list [list stderr "help env: punk::config not initialised - no environment variable info\n"]]
@cmd -name "help console" -summary "Console behaviour tests and warnings." -help "Run some console/terminal behaviour tests (control string hiding, grapheme cluster support, cursor position query timing) and report warnings. Requires a responsive interactive console."
@values -min 0 -max 0
}
console - term - terminal {
proc console {context args} {
set chunks [list]
set warningblock ""
set term_env_vars {TERM TERM_PROGRAM TERM_PROGRAM_VERSION COLORTERM}
set term_dict [dict create]
foreach e $term_env_vars {
@ -8889,31 +8891,85 @@ namespace eval punk {
puts stdout [punk::ansi::move_back 200] ;#hack for some horizontal position bugs where the above tests can leave the cursor in the wrong place for the next output.
#200 is arbitrary large number to move back enough to get to start of line.
}
lappend chunks [list stderr $warningblock]
return $chunks
}
topics - help {
set text ""
set topics [dict create {*}{
"topics|help" "List help topics"
"tcl" "Tcl version warnings"
"env|environment" "punkshell environment vars"
"console|terminal" "Some console behaviour tests and warnings"
"*" "Try to find help on the topic as a command or external executable"
lappend cmdinfo [list help "?${I}topic${NI}?" "This help.\nTo see available subitems type:\nhelp topics\n\nFor an unrecognised ${I}topic${NI}\nhelp will look for basic\ninfo for it as a command.\n"]
set text [helptopic::table_block $frametype $title $cmdinfo 51]
set introblock [textblock::join -- $logoblock $text]
#0.2.0 - help system restructured onto a topic registry (::punk::helptopic: register/resolve, per-topic handler procs each with a punk::args definition); ::punk::help and ::punk::help_chunks punk::args definitions (re)generated from the registry so 'i help' / 'i help <topic>' render documented usage; 'help topics' derived from the registry; command-fallthrough and no-arg overview output unchanged; 'help env' degrades cleanly when punk::config is not initialised; help table objects destroyed after printing (leak fix)