diff --git a/src/vfs/_vfscommon.vfs/modules/punk/args/moduledoc/punkexe-0.2.0.tm b/src/vfs/_vfscommon.vfs/modules/punk/args/moduledoc/punkexe-0.2.0.tm new file mode 100644 index 00000000..f050dbfd --- /dev/null +++ b/src/vfs/_vfscommon.vfs/modules/punk/args/moduledoc/punkexe-0.2.0.tm @@ -0,0 +1,373 @@ +# -*- tcl -*- +# Maintenance Instruction: leave the 999999.xxx.x as is and use punkshell 'dev make' or bin/punkmake to update from -buildversion.txt +# module template: punkshell/src/decktemplates/vendor/punk/modules/template_module-0.0.3.tm +# +# Please consider using a BSD or MIT style license for greatest compatibility with the Tcl ecosystem. +# Code using preferred Tcl licenses can be eligible for inclusion in Tcllib, Tklib and the punk package repository. +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +# (C) 2026 +# +# @@ Meta Begin +# Application punk::args::moduledoc::punkexe 0.2.0 +# Meta platform tcl +# Meta license BSD +# @@ Meta End + + +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +# doctools header +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +#*** !doctools +#[manpage_begin punkshell_module_punk::args::moduledoc::punkexe 0 0.2.0] +#[copyright "2026"] +#[titledesc {punk executable launch documentation}] [comment {-- Name section and table of contents description --}] +#[moddesc {-}] [comment {-- Description at end of page heading --}] +#[require punk::args::moduledoc::punkexe] +#[keywords module launch subcommand tclsh] +#[description] +#[para] punk::args definitions documenting the punk executable launch dispatch +#[para] (the subcommand family implemented in the kit boot script src/vfs/_config/punk_main.tcl) + +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ + +#*** !doctools +#[section Overview] +#[para] These definitions are the documentation home for the launch subcommand +#[para] family of the punk executables: tclsh, script, shell, punk, shellspy +#[para] (G-118 item 10). They are authored to be consumable by the future +#[para] launcher help/parse wiring (goal G-032) - rendering, option parsing and +#[para] degradation wiring stay with that goal. Id convention follows the +#[para] make.tcl precedent for script-level surfaces: (script)::punkexe and +#[para] (script)::punkexe::, with explicit @form -synopsis overrides +#[para] since a constructed id is not an invocable command name. + +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +## Requirements +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ + +#*** !doctools +#[subsection dependencies] +#[para] packages used by punk::args::moduledoc::punkexe +#[list_begin itemized] + +package require Tcl 8.6- +#*** !doctools +#[item] [package {Tcl 8.6}] + +#*** !doctools +#[list_end] + +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ + +#*** !doctools +#[section API] + + +tcl::namespace::eval punk::args::moduledoc::punkexe { + # ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ + # Base namespace + # ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ + #*** !doctools + #[subsection {Namespace punk::args::moduledoc::punkexe}] + #[para] punk::args definitions for the punk executable launch dispatch + #[list_begin definitions] + + variable PUNKARGS + + namespace eval argdoc { + #Top-level launch dispatch (kit boot script punk_main.tcl, mirrored in + #project_main.tcl for generated projects). Display-first definitions: + #the dispatch itself does not parse via punk::args yet (goal G-032). + # -- --- --- --- --- --- --- --- --- --- --- --- --- --- + lappend PUNKARGS [list { + @id -id (script)::punkexe + @cmd -name punkexe\ + -summary\ + "punk executable launch: package modes and subcommand dispatch."\ + -help\ + "Launch surface of the punk shell executables ('' below + stands for any punk kit executable, e.g punk905, or a generated + project's kit). + + An optional FIRST argument selects package modes: one or more of + the tokens minted, os, src, internal joined with '-' when combined + (e.g 'minted', 'src', 'minted-src'), optionally scoped with the + 'proj:' prefix (e.g 'proj:internal-src') so minted/src resolve + against the project containing the current directory instead of + the executable's own (G-033 visitor mode). Modes decide which + module sources the shell trusts and their precedence; 'internal' + (kit-bundled modules) is always appended when absent. Full + contract: the packagemode leader below and bin/AGENTS.md + 'launch package modes' in the punkshell source tree. + + The next argument selects a subcommand from the choices below. + When the first non-mode argument is not a known subcommand: + with no arguments at all the interactive punk shell is launched + ('shell'); any other first argument is treated as a script + invocation (handled as for the 'script' subcommand)." + @form -synopsis " ?packagemode? ?subcommand? ?arg ...?" + @leaders -min 0 -max 2 + packagemode -type string -optional 1 -default internal -help\ + "Package-source mode: an ordered dash-separated list of path + blocks, optionally scoped with the 'proj:' prefix. + Blocks (each adds a group of module/library paths): + internal - paths inside the executable's kit (always included; + appended last unless listed explicitly) + minted - the project's minted output trees (/modules ...) + src - the project's unbuilt source (src/modules, + src/bootsupport/modules, src/vendormodules, src/lib) + os - ad-hoc .tm paths from the current directory/environment + Without 'proj:', minted/src resolve against the executable's own + project (executable in /bin). With 'proj:', they + resolve against the nearest project root at or above the current + directory (a git or fossil repository root) - for an installed + punkshell binary visiting a project that builds no shell of its + own. + ORDER MATTERS: earlier blocks win when the same version of a + module exists in more than one location. + Examples: + src work on the executable's own project source + proj:internal-src explore the cwd project; the executable's own + copies win version ties (robust visitor default) + proj:src explore the cwd project; ITS copies win version + ties (faithful to the project's snapshot vintage) + The launch reports the detected project root and effective + precedence." + subcommand -type string -optional 1 -choicerestricted 0 -choices {tclsh script shell punk shellspy} -choicelabels { + tclsh + " Run as a (near) stock tclsh - no punk modules loaded." + script + " Run a script non-interactively in the punk script environment; honest exit codes." + shell + " Interactive punk shell (repl); can run a script first and stay interactive." + punk + " punk shell launch; piped-stdin friendly (echo cmds | punk)." + shellspy + " Experimental shellspy command-line processor." + } -help\ + "Subcommand to run. Each subcommand's own contract is documented + under its definition id (script)::punkexe::." + @values -min 0 -max -1 + arg -type any -optional 1 -multiple 1 -help\ + "Arguments for the selected subcommand." + }] + # -- --- --- --- --- --- --- --- --- --- --- --- --- --- + + #tclsh subcommand: full contract (G-118). The documented-as-intended + #divergences below record G-118 item decisions: item 2 (tcl_interactive + #early link), item 6 (piped whole-buffer eval + honest exit codes), + #item 8 (istty read-only by convention). The 'no -e one-liner' note is + #the G-077 boundary: stock parity INSIDE this subcommand is deliberate; + #one-liner affordances belong to the top-level/'script' surfaces (G-077). + # -- --- --- --- --- --- --- --- --- --- --- --- --- --- + lappend PUNKARGS [list { + @id -id (script)::punkexe::tclsh + @cmd -name "punkexe tclsh"\ + -summary\ + "Run the punk executable as a (near) stock tclsh - no punk modules."\ + -help\ + "Run the executable as a plain tclsh: no punk modules are loaded + and behaviour matches stock 'tclsh' as closely as the kit boot + allows. The subcommand is an EXTENSION of standard tclsh + behaviour, not an exact emulator - the divergences are listed + below and are intended. + + Stock argument-form parity (tclMain.c): the only recognised + leading option is '-encoding name scriptfile', and only when + scriptfile does not itself begin with '-'. Any other leading '-' + argument means NO script file: all arguments stay in ::argv and + input comes from stdin. In particular there is no -e/-c + one-liner flag - ' tclsh -e (script)' puts '-e' and the + script text into ::argv and reads stdin, exactly like stock + tclsh. That parity is deliberate; one-liner affordances belong + to the punk-level launch surfaces, not this subcommand. + + A scriptfile of the form 'lib:name' is refused with a pointer to + the 'script' subcommand: scriptlib resolution is a punk + facility and the tclsh subcommand keeps plain-tclsh semantics. + A missing scriptfile is a clean error (exit 1); errors raised by + an existing script keep their full trace. + + Piperepl runtimes: kits on a 'punk' family runtime carry the + TCLSH_PIPEREPL patch (disable with env TCLSH_PIPEREPL=0; a kit + on an unpatched runtime notes the missing patch on stderr for + the forms that would use it). With the gate open the runtime + publishes launch state in the ::tclsh array before any script + runs: + istty launch-time fact: was stdin a tty? Never updated + afterwards (still 0 after a console reopen). + Read-only by convention - no readonly trace is + installed; a script write corrupts the + Tcl-visible value without affecting behaviour. + Its existence is also the patch-presence probe. + dorepl linked control: a script (or piped input) sets + this to 1 to enter the interactive repl after + the script/stdin completes - on piped launches + stdin is reopened from the console (CONIN$ on + windows, /dev/tty elsewhere). + evalinput linked control: piped input a script-arg run + did not consume is BUFFERED, not evaluated, + unless the script sets evalinput to 1. + inputbuffer set at console reopen: holds the unconsumed + piped input. + reopened 0 at gate-open startup; republished as 1 after + a successful console reopen. + Env TCLSH_PIPEREPL_DEBUG=1 enables patch diagnostics on stderr + (e.g the console-reopen notice, silent by default). + + Intended divergences from stock tclsh: + - tcl_interactive: with the piperepl gate open it is linked + to the tty flag BEFORE the startup script runs; a + script-arg launch from a console therefore reads 1 where + stock reads 0 (piped launches read 0 either way). The + early link is load-bearing: a piped script that sets + dorepl writes ::tcl_interactive to opt into prompts/echo + in the reopened repl. + - piped no-arg evaluation WITHOUT the machinery (unpatched + runtime, or TCLSH_PIPEREPL=0): stdin is read to eof and + evaluated as one script - output appears at eof on slow + pipes, a mid-script error aborts the remainder, and the + exit code is honest (nonzero on error) where stock tclsh + streams per command, continues after errors and exits 0. + (With the machinery present, evaluation is the stock + per-command repl loop.) On machinery-less runtimes the + interactive form (console stdin, no script) fails fast + with a usage error instead of blocking in a console read." + + @form -form {scriptfile} -synopsis " tclsh ?-encoding name? scriptfile ?arg ...?" + @leaders -min 0 -max 0 + @opts + -encoding -type string -optional 1 -typesynopsis name -help\ + "Encoding used to read scriptfile (as for 'source -encoding'). + Recognised only immediately after 'tclsh' and only when the + following argument does not begin with '-'; an incomplete + -encoding form falls through to the no-script form (stock + behaviour)." + @values -min 1 -max -1 + scriptfile -type string -optional 0 -help\ + "Script file to source and exit. ::argv0 and 'info script' are + the (normalized) script path; remaining args are ::argv. The + script may set ::tclsh(dorepl) 1 (piperepl runtimes) to enter + the interactive repl after it completes." + arg -type any -optional 1 -multiple 1 -help\ + "Arguments passed to the script in ::argv." + + @form -form {stdin} -synopsis " tclsh ?arg ...?" + @values -min 0 -max -1 + arg -type any -optional 1 -multiple 1 -help\ + "With no script file all arguments (including any leading '-' + arguments) stay in ::argv; ::argv0 is the executable path. + Input comes from stdin: the interactive repl on a console + (piperepl runtimes), evaluation of piped input otherwise." + }] + # -- --- --- --- --- --- --- --- --- --- --- --- --- --- + + #Sibling subcommands: summary-level contracts. Deep punk::args parse + #definitions for these surfaces are G-032's lane ('script' is its + #natural first parsed subcommand). + # -- --- --- --- --- --- --- --- --- --- --- --- --- --- + lappend PUNKARGS [list { + @id -id (script)::punkexe::script + @cmd -name "punkexe script"\ + -summary\ + "Run a script non-interactively in the punk script environment."\ + -help\ + "Run a Tcl script and exit with an honest exit code + (app-punkscript): script errors exit nonzero and the launch + plumbing emits nothing of its own on stdout/stderr, so + exec-style callers see only the script's output. The default + punk module/alias environment is loaded (unlike 'tclsh'). + + The script comes from the file argument, from piped stdin when + no argument is given (terminal stdin without a script argument + is a usage error - no interactive fallback), or via scriptlib + resolution when the argument has the form 'lib:name' (resolved + from the scriptlib locations associated with the executable, + including extensionless and shebang'd scripts)." + @form -synopsis " script ?scriptfile|lib:name? ?arg ...?" + @values -min 0 -max -1 + scriptfile -type string -optional 1 -help\ + "Script file path, or lib:name for scriptlib resolution. + Omitted: the script is read from piped stdin." + arg -type any -optional 1 -multiple 1 -help\ + "Arguments passed to the script in ::argv." + }] + # -- --- --- --- --- --- --- --- --- --- --- --- --- --- + lappend PUNKARGS [list { + @id -id (script)::punkexe::shell + @cmd -name "punkexe shell"\ + -summary\ + "Interactive punk shell (repl)."\ + -help\ + "Launch the interactive punk shell (app-punkshell). With + arguments, a script can be run first with the interactive + shell maintained afterwards. This is also the default when the + executable is launched with no arguments at all." + @form -synopsis " shell ?arg ...?" + @values -min 0 -max -1 + arg -type any -optional 1 -multiple 1 -help\ + "Arguments passed through to the shell launch." + }] + # -- --- --- --- --- --- --- --- --- --- --- --- --- --- + lappend PUNKARGS [list { + @id -id (script)::punkexe::punk + @cmd -name "punkexe punk"\ + -summary\ + "punk shell launch; piped-stdin friendly."\ + -help\ + "Launch the punk shell. With arguments the app-punkshell launch + path is used (as for 'shell'); without arguments the + interactive shell is launched directly. Commands piped into + stdin are supported (e.g: echo 'puts hello' | punk) + and stderr is kept clean of launch chatter so exec-style + callers do not misreport failure." + @form -synopsis " punk ?arg ...?" + @values -min 0 -max -1 + arg -type any -optional 1 -multiple 1 -help\ + "Arguments passed through to the shell launch." + }] + # -- --- --- --- --- --- --- --- --- --- --- --- --- --- + lappend PUNKARGS [list { + @id -id (script)::punkexe::shellspy + @cmd -name "punkexe shellspy"\ + -summary\ + "Experimental shellspy command-line processor."\ + -help\ + "Pass all arguments to the experimental shellspy command-line + processor (app-shellspy). Note: 'shellspy' is only this launch + subcommand - it is not the project name (the project is + punkshell)." + @form -synopsis " shellspy ?arg ...?" + @values -min 0 -max -1 + arg -type any -optional 1 -multiple 1 -help\ + "Arguments for the shellspy processor." + }] + # -- --- --- --- --- --- --- --- --- --- --- --- --- --- + } + + #*** !doctools + #[list_end] [comment {--- end definitions namespace punk::args::moduledoc::punkexe ---}] +} + +# ----------------------------------------------------------------------------- +# register namespace(s) to have PUNKARGS,PUNKARGS_aliases variables checked +# ----------------------------------------------------------------------------- +# variable PUNKARGS +# variable PUNKARGS_aliases +namespace eval ::punk::args::register { + #use fully qualified so 8.6 doesn't find existing var in global namespace + lappend ::punk::args::register::NAMESPACES ::punk::args::moduledoc::punkexe ::punk::args::moduledoc::punkexe::argdoc +} +# ----------------------------------------------------------------------------- + +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +## Ready +package provide punk::args::moduledoc::punkexe [tcl::namespace::eval punk::args::moduledoc::punkexe { + variable pkg punk::args::moduledoc::punkexe + variable version + set version 0.2.0 +}] +return + +#*** !doctools +#[manpage_end]