From 62c596cec7e535348ac7cfa51880fe576b3fa1a3 Mon Sep 17 00:00:00 2001 From: Julian Noble Date: Wed, 5 Aug 2026 01:36:28 +1000 Subject: [PATCH] Single-help-mechanism outputs: core 0.5.0 delivered (vfscommon), moduledoc 0.6.0/0.3.0, pending module promotions swept make.tcl modules + vfscommonupdate + bake ripple (native Tcl903 driver) from the single-mechanism change-set ac19df2a: _vfscommon punkboot/core.tcl regenerated from the 0.5.0 master; moduledoc::punkexe 0.5.0 -> 0.6.0 and moduledoc::punkboot 0.2.0 -> 0.3.0 version renames; punk::mix templates modpod repacked carrying the layout _config sweep (modpod-template copies + layout make.tcl copies via the established sync channels). The same vfscommonupdate swept in promotions pending from committed src work of the last sessions: commandstack 0.7.1, punk::args 0.15.1, punk::auto_exec 0.1.1, punk::ns 0.9.2, punk::tcltestrun 0.4.2, punk::zip 0.4.0. Claude-Session: https://claude.ai/code/session_01Y1diJnhjUxKgEG6EwYAzxj Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com --- .../vendor/punk/project-0.1/src/make.tcl | 100 +++++---- .../src/vfs/_config/project_main.tcl | 16 +- .../src/vfs/_config/punkboot_core.tcl | 200 +++++++++++------- .../src/vfs/_vfscommon.vfs/punkboot/core.tcl | 200 +++++++++++------- .../vendor/punk/basic/src/make.tcl | 100 +++++---- .../vendor/punk/project-0.1/src/make.tcl | 100 +++++---- ...ndstack-0.7.0.tm => commandstack-0.7.1.tm} | 43 +++- .../punk/{args-0.14.0.tm => args-0.15.1.tm} | 124 ++++++++++- .../{punkboot-0.2.0.tm => punkboot-0.3.0.tm} | 25 ++- .../{punkexe-0.5.0.tm => punkexe-0.6.0.tm} | 125 +++++------ ...{auto_exec-0.1.0.tm => auto_exec-0.1.1.tm} | 28 ++- .../modules/punk/mix/templates-0.2.0.tm | Bin 375432 -> 378252 bytes .../modules/punk/{ns-0.9.1.tm => ns-0.9.2.tm} | 12 +- ...cltestrun-0.4.1.tm => tcltestrun-0.4.2.tm} | 14 +- .../punk/{zip-0.3.0.tm => zip-0.4.0.tm} | 158 ++++++++++---- src/vfs/_vfscommon.vfs/punkboot/core.tcl | 166 ++++++++------- 16 files changed, 887 insertions(+), 524 deletions(-) rename src/vfs/_vfscommon.vfs/modules/{commandstack-0.7.0.tm => commandstack-0.7.1.tm} (97%) rename src/vfs/_vfscommon.vfs/modules/punk/{args-0.14.0.tm => args-0.15.1.tm} (99%) rename src/vfs/_vfscommon.vfs/modules/punk/args/moduledoc/{punkboot-0.2.0.tm => punkboot-0.3.0.tm} (93%) rename src/vfs/_vfscommon.vfs/modules/punk/args/moduledoc/{punkexe-0.5.0.tm => punkexe-0.6.0.tm} (86%) rename src/vfs/_vfscommon.vfs/modules/punk/{auto_exec-0.1.0.tm => auto_exec-0.1.1.tm} (98%) rename src/vfs/_vfscommon.vfs/modules/punk/{ns-0.9.1.tm => ns-0.9.2.tm} (99%) rename src/vfs/_vfscommon.vfs/modules/punk/{tcltestrun-0.4.1.tm => tcltestrun-0.4.2.tm} (97%) rename src/vfs/_vfscommon.vfs/modules/punk/{zip-0.3.0.tm => zip-0.4.0.tm} (92%) diff --git a/src/modules/punk/mix/#modpod-templates-999999.0a1.0/templates/project_layouts/vendor/punk/project-0.1/src/make.tcl b/src/modules/punk/mix/#modpod-templates-999999.0a1.0/templates/project_layouts/vendor/punk/project-0.1/src/make.tcl index 606a356e..5c350a1e 100644 --- a/src/modules/punk/mix/#modpod-templates-999999.0a1.0/templates/project_layouts/vendor/punk/project-0.1/src/make.tcl +++ b/src/modules/punk/mix/#modpod-templates-999999.0a1.0/templates/project_layouts/vendor/punk/project-0.1/src/make.tcl @@ -198,7 +198,6 @@ namespace eval ::punkboot { variable scriptfolder [file normalize [file dirname [info script]]] variable foldername [file tail $scriptfolder] variable pkg_requirements [list]; variable pkg_missing [list];variable pkg_loaded [list] - variable help_flags [list -help --help /? -h] variable known_commands [list bakehouse packages modules libs bake bakelist vfslibs bin info check shell vendorupdate libfetch bootsupport vfscommonupdate projectversion workflow buildsuite tool] } @@ -2588,17 +2587,18 @@ proc ::punkboot::punkboot_gethelp {args} { set scriptname [file tail [info script]] append h "Usage:" \n append h "" \n - append h " $scriptname -help or $scriptname --help or $scriptname /? or just $scriptname" \n + append h " $scriptname help or just $scriptname" \n append h " - This help." \n \n append h " $scriptname bakehouse ?-k? ?-dirty-abort 1|0?" \n append h " - consumer run from a clean checkout: mints the packages (modules + libs) then bakes kit/zipkit executables to /bin" \n append h " - refuses uncommitted src by default (-dirty-abort defaults ON: the bakehouse bakes from the committed recipe; pass -dirty-abort 0 to override)" \n append h " - the optional -k flag will terminate running processes matching the executable being baked (if applicable)" \n append h " - does NOT run the promotion gates (bootsupport, vfscommonupdate) - on a clean checkout they are already satisfied by the committed tree" \n \n - append h " $scriptname bake ?-k? ?kitname ...?" \n + append h " $scriptname bake ?-k? ?-force? ?kitname ...?" \n append h " - assemble kit/zipkit executables from the promoted payload (src/vfs) and src/runtime runtimes into /bin" \n append h " - includes the vfslibs phase; does not re-mint modules/libs and does not run the promotion gates" \n - append h " - with kitname arguments, bakes and deploys only the named configured kits (unknown names error before any bake)" \n \n + append h " - with kitname arguments, bakes and deploys only the named configured kits (unknown names error before any bake)" \n + append h " - -force re-assembles kits whose inputs are unchanged (bypasses the 'no change detected' skip)" \n \n append h " $scriptname bakelist ?kitname ...?" \n append h " - list the kit outputs configured in src/runtime/mapvfs.toml: name, kit type, runtime (with presence)," \n append h " vfs folder and deployed state (bin copy absent/current/stale/nobake vs the src/_bake product)" \n @@ -2655,7 +2655,7 @@ proc ::punkboot::punkboot_gethelp {args} { append h " - zig is OPTIONAL: packages/bake never require this step; without a suitable toolchain the state is" \n append h " reported and build/test exit nonzero with fetch guidance (bin/punk-getzig.cmd)" \n \n append h " $scriptname help ?subcommand? ?arg ...?" \n - append h " - show usage for $scriptname or one of its subcommands (equivalent: $scriptname -help);" \n + append h " - show usage for $scriptname or one of its subcommands (the single help mechanism);" \n append h " extra words are the subcommand's own command line, dry-run through its declaration - an accepted" \n append h " line shows the matched action's usage (tool, buildsuite), a rejected line that subcommand's own" \n append h " usage error (tabled help only)" \n \n @@ -3078,7 +3078,9 @@ set scriptargs $::argv # G-030: make.tcl dogfoods punk::args. # Subcommands and their options are declared as punk::args definitions ((script)::punkboot and # (script)::punkboot::) and parsed with punk::args::parse - 'make.tcl', -# 'make.tcl help ?subcommand?' and 'make.tcl -help' render tabled usage, and invalid +# 'make.tcl help ?subcommand? ?arg ...?' renders tabled usage (the single help mechanism - +# help FLAGS like -help/--help are ordinary arguments since 2026-08-05: they fail whatever +# gate they meet, the usage error itself being documentation), and invalid # arguments produce punk::args usage errors. # Degrade rule (hard requirement - see goals/archive/G-030-maketcl-punkargs.md): punk::args is # guarded. When it (or a definition feature it needs) is unavailable from bootsupport, dispatch @@ -3308,14 +3310,18 @@ if {[info exists ::env(PUNKBOOT_PLAIN)] && [string is true -strict $::env(PUNKBO update contract for keeping it in step with make.tcl behaviour." help " - Show tabled usage for make.tcl as a whole, or for a single subcommand. - After the subject, accepts that subcommand's own command line and - dry-runs it through the subcommand's declaration: a line the - subcommand would accept shows the matched action's usage - 'make.tcl - help tool build -test 0 punkzip' shows the tool build form, as does - appending -help to the command line itself ('make.tcl tool build - -test 0 punkzip -help') - while a line it would reject shows the - same usage error the subcommand itself would produce (the error + Show tabled usage for make.tcl as a whole, or for a single + subcommand. This leading 'help' word is the SINGLE help + mechanism: there is no -help flag handling anywhere (a + -help/--help in a command line is an ordinary argument that + fails whatever gate it meets, and that usage error is itself + the documentation). + After the subject, accepts that subcommand's own command line + and dry-runs it through the subcommand's declaration: a line + the subcommand would accept shows the matched action's usage - + 'make.tcl help tool build -test 0 punkzip' shows the tool + build form - while a line it would reject shows the same + usage error the subcommand itself would produce (the error table carries the forms' synopsis, argument rows and per-form reasons; exit 1). An accepted line is confirmed with a one-line report of where each word landed ('kitname = punk91 -confirm 0' @@ -3424,6 +3430,14 @@ if {[info exists ::env(PUNKBOOT_PLAIN)] && [string is true -strict $::env(PUNKBO "Terminate running processes matching the executable being built (if applicable) so the bake can install over it." } + variable OPT_FORCE { + -force -type none -default 0 -help\ + "Re-assemble kits even when no input change is detected. + By default a kit whose vfs/runtime inputs are unchanged since its + last bake is skipped ('no change detected'); -force bypasses that + skip for the selected kits - e.g to compare assembly behaviour + across driving interpreters without touching inputs." + } #bakehouse defaults the dirty gate ON: #the bakehouse bakes from the committed recipe (G-112 two-persona model). variable OPT_DIRTYABORT_ON { @@ -3503,6 +3517,7 @@ if {[info exists ::env(PUNKBOOT_PLAIN)] && [string is true -strict $::env(PUNKBO {${[dict get $HELPTEXTS bakehouse]}} @opts ${$OPT_FORCEKILL} + ${$OPT_FORCE} ${$OPT_DIRTYABORT_ON} ${$OPT_CONFIRM} @values -min 0 -max 0 @@ -3548,6 +3563,7 @@ if {[info exists ::env(PUNKBOOT_PLAIN)] && [string is true -strict $::env(PUNKBO {${[dict get $HELPTEXTS bake]}} @opts ${$OPT_FORCEKILL} + ${$OPT_FORCE} ${$OPT_DIRTYABORT} ${$OPT_CONFIRM} @values -min 0 -max -1 @@ -3792,11 +3808,12 @@ if {[info exists ::env(PUNKBOOT_PLAIN)] && [string is true -strict $::env(PUNKBO 'bin' and 'modules' folders at the same level as 'src'. General usage: make.tcl ?flags? - 'make.tcl help ?arg ...?' or 'make.tcl - ?arg ...? -help' shows a subcommand's own usage - the words are - dry-run through the subcommand's declaration, so an accepted - command line shows the matched action's usage (tool, buildsuite) - and a rejected one shows that subcommand's own usage error. + 'make.tcl help ?arg ...?' shows a subcommand's own + usage (the single help mechanism - there is no -help flag) - + the words after the subject are dry-run through the + subcommand's declaration, so an accepted command line shows + the matched action's usage (tool, buildsuite) and a rejected + one shows that subcommand's own usage error. Interactive y/n confirmations can be driven non-interactively with the -confirm flag declared on the relevant subcommands.} punk::args::define { @@ -3901,21 +3918,22 @@ set ::punkboot::opt_kitnames [list] ;#G-121: requested kit names for bake/bak if {$::punkboot::punkargs_ok} { set first [lindex $scriptargs 0] - if {![llength $scriptargs] || $first in $::punkboot::help_flags} { + if {![llength $scriptargs]} { set do_help 1 } else { #validate/resolve the subcommand word via the top-level definition - #(allows unambiguous prefixes; unknown subcommands get a punk::args usage error) + #(allows unambiguous prefixes; unknown subcommands get a punk::args + #usage error - INCLUDING help flags like -help/--help since the + #2026-08-05 single-mechanism revision: the leading 'help' word and + #the bare invocation are the help surface, and a '-help' anywhere + #else is an ordinary argument that fails whatever gate it meets, + #with the usage error itself carrying the documentation) if {[catch {punk::args::parse [list $first] -errorstyle $::punkboot::errstyle withid (script)::punkboot} argd]} { puts stderr $argd exit 1 } set subcommand [dict get $argd leaders subcommand] set subargs [lrange $scriptargs 1 end] - set wants_help 0 - foreach h $::punkboot::help_flags { - if {$h in $subargs} {set wants_help 1 ; break} - } if {$subcommand eq "help"} { set do_help 1 if {[llength $subargs]} { @@ -3932,17 +3950,6 @@ if {$::punkboot::punkargs_ok} { set help_subject [dict get $argd values subject] set help_words [lrange $subargs 1 end] } - } elseif {$wants_help} { - set do_help 1 - set help_subject $subcommand - #' ?arg ...? -help' - the same contract as - #'make.tcl help ?arg ...?': the remaining words are the - #subcommand's command line, with the help flag itself removed - #(wherever it appeared). - set help_words [list] - foreach w $subargs { - if {$w ni $::punkboot::help_flags} {lappend help_words $w} - } } elseif {$subcommand eq "shell"} { #declared passthrough: everything after 'shell' goes to the repl unparsed set ::punkboot::command shell @@ -4035,13 +4042,12 @@ if {$::punkboot::punkargs_ok} { set ::punkboot::opt_confirm [expr {bool($v)}] } default { - if {$a in $::punkboot::help_flags} { - set do_help 1 - } else { - puts stderr "Unknown flag: $a\n" - set do_help 1 - set help_exitcode 1 - } + #help flags are not special (2026-08-05 single-mechanism + #revision): they land here as unknown flags, and the + #resulting help display carries exit 1 + puts stderr "Unknown flag: $a\n" + set do_help 1 + set help_exitcode 1 } } } else { @@ -8645,7 +8651,8 @@ foreach vfstail $vfs_tails { set changed_unchanged [$vfs_event targetset_source_changes] - set vfs_or_runtime_changed [expr {[llength [dict get $changed_unchanged changed]] || [llength [$vfs_event get_targets_exist]] < [llength [$vfs_event get_targets]]}] + #bake -force bypasses the no-change skip (always re-assemble the selected kits) + set vfs_or_runtime_changed [expr {$::punkboot::opt_force || [llength [dict get $changed_unchanged changed]] || [llength [$vfs_event get_targets_exist]] < [llength [$vfs_event get_targets]]}] if {$vfs_or_runtime_changed} { #source .vfs folder has changes @@ -9111,7 +9118,12 @@ foreach vfstail $vfs_tails { #stamps (and kits) differ run to run. Same principle as the G-117 #embedded records, which keep sha1/size/built in the SIDECAR only - #time facts belong to punkcheck records and sidecars, not payloads. + #LF translation pinned for the same reason (G-165): the default + #text translation follows the driving interpreter (crlf on windows + #drivers, lf on unix-family ones), which made the stamp's BYTES + #driver-dependent - caught by the G-165 four-driver parity run. set fd [open [file join $targetvfs punkkit-stamp.toml] w] + chan configure $fd -translation lf puts -nonewline $fd "[join $lines \n]\n" close $fd puts stdout " kit stamp (G-025): punkkit-stamp.toml (project_version=$stamp_project_version vfs=$vfstail runtime=$runtime_fullname boot_core=$core_ver)" diff --git a/src/modules/punk/mix/#modpod-templates-999999.0a1.0/templates/project_layouts/vendor/punk/project-0.1/src/vfs/_config/project_main.tcl b/src/modules/punk/mix/#modpod-templates-999999.0a1.0/templates/project_layouts/vendor/punk/project-0.1/src/vfs/_config/project_main.tcl index eb437b45..6696ceb4 100644 --- a/src/modules/punk/mix/#modpod-templates-999999.0a1.0/templates/project_layouts/vendor/punk/project-0.1/src/vfs/_config/project_main.tcl +++ b/src/modules/punk/mix/#modpod-templates-999999.0a1.0/templates/project_layouts/vendor/punk/project-0.1/src/vfs/_config/project_main.tcl @@ -16,8 +16,9 @@ # punk::args::moduledoc::punkexe package for the documented launch surface), # module and library path setup, punk::libunknown, and the default dispatch # (tclsh/shellspy/punk/shell/script/buildinfo/help) with its G-032 help -# surface (' help', '-help', ' -help' - tabled usage -# listing your registered subcommands, degrading to a plain list). +# surface (' help ?subcommand? ?arg ...?' - the single help mechanism: +# tabled usage listing your registered subcommands, degrading to a plain +# list; help FLAGS are never intercepted). # #WHAT TO EDIT # Only the ==CUSTOMIZE== blocks below. Everything else is contract plumbing. @@ -58,11 +59,12 @@ apply { args { namespace eval ::punkboot {variable project_subcommands [dict create]} #Optional per-name help/parse metadata (G-032): with this declared, your - #subcommands appear in ' help' with summaries, 'help ' / - #' -help' render your punk::args definition, and parse 1 validates - #arguments through it before your handler runs (usage errors tabled, - #exit 1). All keys optional; a name without an entry keeps full - #passthrough semantics. Contract detail: punk::args::moduledoc::punkboot + #subcommands appear in ' help' with summaries, 'help ' renders + #your punk::args definition, and parse 1 validates arguments through it + #before your handler runs (usage errors tabled, exit 1). All keys + #optional; a name without an entry keeps full passthrough semantics (the + #launcher never touches a subcommand's own arguments - help flags + #included). Contract detail: punk::args::moduledoc::punkboot #registration definition. # namespace eval ::punkboot {variable project_subcommand_info [dict create \ # mytool {summary "Frob the widgets in a directory." \ diff --git a/src/modules/punk/mix/#modpod-templates-999999.0a1.0/templates/project_layouts/vendor/punk/project-0.1/src/vfs/_config/punkboot_core.tcl b/src/modules/punk/mix/#modpod-templates-999999.0a1.0/templates/project_layouts/vendor/punk/project-0.1/src/vfs/_config/punkboot_core.tcl index eb9d4d87..98ddd3fa 100644 --- a/src/modules/punk/mix/#modpod-templates-999999.0a1.0/templates/project_layouts/vendor/punk/project-0.1/src/vfs/_config/punkboot_core.tcl +++ b/src/modules/punk/mix/#modpod-templates-999999.0a1.0/templates/project_layouts/vendor/punk/project-0.1/src/vfs/_config/punkboot_core.tcl @@ -11,13 +11,17 @@ #package_mode parsing (minted|os|internal|src with the proj: scope prefix, #G-033), module-path and auto_path assembly, punk::libunknown, src-mode ##modpod registration, then the default subcommand dispatch -#(tclsh/shellspy/punk/shell/script/buildinfo/help) extended by the thin +#(tclsh/shellspy/punk/shell/script/buildinfo/help plus the G-077 top-level +#'-e' one-liner reclassification to 'script -e') extended by the thin #main's declared project subcommands (G-031 registration model - see the #dispatch section near the end of this file). The launch surface documents -#itself via punk::args (G-032): ' help ?subcommand?', '-help' and -#' -help' render tabled usage from the moduledoc::punkexe -#definitions plus the live registrations, degrading to a plain subcommand -#list when that stack is unavailable. +#itself via punk::args (G-032; -help flag forms withdrawn 2026-08-05): +#' help ?subcommand? ?arg ...?' - the single help mechanism - +#renders tabled usage from the moduledoc::punkexe definitions plus the live +#registrations, degrading to a plain subcommand list when that stack is +#unavailable. Help flags (-help etc) are never intercepted: a leading one +#falls under the unknown-first-argument refusal (which shows usage on +#stderr), and after a subcommand they are the subcommand's own arguments. # #The package_mode surface (documented in full by punk::args::moduledoc::punkexe): #an optional FIRST launch argument of the form minted|os|internal|src or any @@ -51,7 +55,7 @@ namespace eval ::punkboot { #boot-core identity (G-031; stamped into kits + reported by the G-025 #buildinfo surfaces) - variable core_version 0.3.0 + variable core_version 0.5.0 } if {![info exists ::punkboot::launch_args]} { namespace eval ::punkboot [list variable launch_args $::argv] @@ -1522,23 +1526,25 @@ if {![info exists ::punkboot::launch_defaults]} { namespace eval ::punkboot [list variable boot_state $boot_state_dict] #--------------------------------------------------------------- - #Launcher help + declared-parse machinery (G-032) + #Launcher help + declared-parse machinery (G-032; -help flag forms + #withdrawn 2026-08-05 by user direction - single mechanism) #The launch surface documents itself through punk::args (definition ids - #from the punk::args::moduledoc::punkexe family): - # help ?subcommand? tabled usage; the top-level table lists - # built-ins AND project-registered - # subcommands with summaries - # -help same as bare 'help' - only on kits whose - # unknownfirst default is 'script' (a - # tool-style kit routes flags to its own - # processor; its surface stays reachable - # via the 'help' word) - # -help the subcommand's tabled usage when -help - # is its FIRST argument (tclsh: only when - # -help is the SOLE argument - stock - # parity keeps every other dash form in - # ::argv; project subcommands: only when - # the registration declares an argsid) + #from the punk::args::moduledoc::punkexe family) via ONE mechanism, the + #leading 'help' word (the punkshell 'i ...' idiom): + # help tabled top-level usage; the table + # lists built-ins AND project-registered + # subcommands with summaries + # help ?arg ...? + # the subcommand's tabled usage; words + # after the subject are accepted and + # ignored, so 'help' can be prepended + # to any existing command line + #There is deliberately NO -help/--help flag handling anywhere in the + #dispatch: a leading help-flag word falls under the unknown-first-argument + #rule (whose refusal shows this usage anyway, stderr exit 1), and + #' -help' belongs to the subcommand's own arguments (full + #passthrough - e.g app-shellspy handles -help/--help/help itself; a + #parse-declared subcommand rejects it like any undeclared flag). #Everything is guarded and lazy (the G-030 degradation doctrine): nothing #here loads punk::args on a normal boot/dispatch path. When punk::args or #the moduledoc definitions are unavailable (or PUNKBOOT_PLAIN=1 - same @@ -1553,7 +1559,6 @@ if {![info exists ::punkboot::launch_defaults]} { #(script)::punkexe::help for subject validation. #--------------------------------------------------------------- namespace eval ::punkboot { - variable help_flags [list -help --help -h /?] variable launch_builtin_subcommands [list] variable launch_subcommands [list] variable launcher_punkargs_state "" ;#"" unprobed | ok | plain @@ -1679,8 +1684,8 @@ if {![info exists ::punkboot::launch_defaults]} { proc launcher_helpdef_id {} { #define (script)::punkexe.launcherhelp: the moduledoc #(script)::punkexe::help definition with the subject choices - #replaced by the live subcommand set, so 'help ' validates - #(and prefix-resolves) against what this kit actually offers. + #replaced by the live subcommand set - the DISPLAY clone rendered + #by 'help help'. set id (script)::punkexe.launcherhelp set existing "" catch {set existing [punk::args::raw_def $id]} @@ -1698,11 +1703,37 @@ if {![info exists ::punkboot::launch_defaults]} { } return $id } + proc launcher_helpsubjectdef_id {} { + #define (script)::punkexe.launcherhelpsubject: the VALIDATION + #clone the help arm parses the subject word against - subject + #REQUIRED with the live choices, and the display definition's + #ignored trailing-arg row suppressed (-antiglobs). Without this + #the display shape lets punk::args SKIP a mistyped optional + #subject into the unconstrained arg row, silently rendering the + #top-level table where a tabled choice error is wanted. + set id (script)::punkexe.launcherhelpsubject + set existing "" + catch {set existing [punk::args::raw_def $id]} + if {$existing ne ""} { + return $id + } + if {[catch { + set ov [dict create \ + @id [list -id $id] \ + subject [list -optional 0 -choices [launcher_live_choices]] \ + ] + punk::args::define [punk::args::resolved_def -antiglobs {arg} -override $ov (script)::punkexe::help] + }]} { + return "" + } + return $id + } proc launcher_plain_help {} { #degraded help: plain subcommand list built without punk::args set exebase [file rootname [file tail [info nameofexecutable]]] set lines [list] lappend lines "Usage: $exebase ?packagemode? ?subcommand? ?arg ...?" + lappend lines " $exebase ?packagemode? -e