diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 4fc19618..aecda6eb 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -42,12 +42,12 @@ app package from src/lib/ (app-punkshell, app-punkscript, app-repl, app-shellsp ## Boot and launch chain - **Kit anatomy.** Each `src/vfs/*.vfs` folder is a runtime payload; `src/runtime/mapvfs.toml` (G-024, tomlish-parsed; deprecated `mapvfs.config` line format still readable) maps payload folders to platform runtimes under `bin/runtime//` as named kit outputs, with named groups and generative version-named schemes; an optional sibling `src/vfs/.vfs.toml` declares payload packages materialized INTO the folder with drop-in-wins precedence (G-115 - spec: `src/vfs/README.md`); `src/vfs/_vfscommon.vfs/` is a generated merge of common libraries (never hand-edited); `src/vfs/_config/` holds the entry scripts. Sources: `src/vfs/AGENTS.md`, `src/runtime/AGENTS.md`. -- **Entry point.** `src/vfs/_config/punk_main.tcl` (thin main sourcing the shared boot core - G-031). An optional first argument is a dash-delimited package mode composed of tokens from `minted`, `os`, `src`, `internal` (`internal` is always appended when absent; `minted` was named `dev` pre-0.43.0), optionally scoped with the `proj:` prefix (G-033: `minted`/`src` resolve against the project containing the cwd - walk-up to the nearest git/fossil repo root with a punkshell-style src tree - instead of the executable's own project; discovery is always reported, never a silent rebind). The next argument is the subcommand: `shell`, `script`, `punk`, `tclsh`, `shellspy`, `buildinfo`, `help`. A non-subcommand first argument naming an existing file (or `lib:*` reference) is treated as a script invocation; a first argument of exactly `-e` runs the following argument as a Tcl one-liner (G-077, achieved - handled as `script -e`; tool-style kits keep `-e` routed to their own processor); anything else is refused with usage (G-032); no arguments at all means interactive shell. Subcommands map to app packages under `src/lib/` (`app-punkshell`, `app-punkscript`, `app-repl`, `app-shellspy`). The launch surface self-documents through punk::args (G-032, achieved semantics in boot core 0.4.0): `help`/`-help`/` -help` render tabled usage from the moduledoc definitions plus project registrations (`::punkboot::project_subcommand_info` - summaries, definition ids, optional declared parse), degrading to a plain subcommand list when that stack is unavailable. Source: `src/vfs/AGENTS.md`. +- **Entry point.** `src/vfs/_config/punk_main.tcl` (thin main sourcing the shared boot core - G-031). An optional first argument is a dash-delimited package mode composed of tokens from `minted`, `os`, `src`, `internal` (`internal` is always appended when absent; `minted` was named `dev` pre-0.43.0), optionally scoped with the `proj:` prefix (G-033: `minted`/`src` resolve against the project containing the cwd - walk-up to the nearest git/fossil repo root with a punkshell-style src tree - instead of the executable's own project; discovery is always reported, never a silent rebind). The next argument is the subcommand: `shell`, `script`, `punk`, `tclsh`, `shellspy`, `buildinfo`, `help`. A non-subcommand first argument naming an existing file (or `lib:*` reference) is treated as a script invocation; a first argument of exactly `-e` runs the following argument as a Tcl one-liner (G-077, achieved - handled as `script -e`; tool-style kits keep `-e` routed to their own processor); anything else is refused with usage (G-032); no arguments at all means interactive shell. Subcommands map to app packages under `src/lib/` (`app-punkshell`, `app-punkscript`, `app-repl`, `app-shellspy`). The launch surface self-documents through punk::args (G-032; single-mechanism revision 2026-08-05 in boot core 0.5.0): `help ?subcommand? ?arg ...?` - the only help entry, trailing words accepted so `help` can be prepended to a command line - renders tabled usage from the moduledoc definitions plus project registrations (`::punkboot::project_subcommand_info` - summaries, definition ids, optional declared parse), degrading to a plain subcommand list when that stack is unavailable; help FLAGS are never intercepted (a leading `-help` earns the refusal, ` -help` belongs to the subcommand). Source: `src/vfs/AGENTS.md`. - **Package modes pick module provenance.** `internal` uses module snapshots baked into the kit at bake time; `minted` loads the mint output trees at repo-root `modules/` and `lib/`; `src` loads the unbuilt working tree (`src/modules`, `src/lib`, `src/bootsupport`, `src/vendormodules`) with `package prefer latest` so magic-version dev modules (`999999.0a1.0`) beat stamped snapshots. `src` mode is the standard way to verify working-tree changes without a rebuild. Source: `bin/AGENTS.md` "Launch package modes". - **Payload mount derivation (G-129, achieved).** The boot keys zipfs presence on `tcl::zipfs::mount` and derives where the executable's attached archive actually mounted from the mount table itself (the entry whose archive file is the executable; fallback: the mount containing the boot script) instead of assuming `tcl::zipfs::root` + `//zipfs:/app`. Modern runtimes still answer `//zipfs:/app`; the androwish/undroidwish 8.6 backport has no `root` command, mounts at the executable's own path, and boots the same payload through its `app/main.tcl` in-archive hook (`src/vfs/punk8win.vfs` carries fauxlinks for both conventions). A mounted archive the boot cannot attribute is reported on stderr rather than silently yielding no internal paths. The derivation procs stay defined post-boot (`::punkboot::zipfs_kit_mountbase`). Sources: `src/vfs/AGENTS.md`, `bin/AGENTS.md` "Kit-wrappable runtime requirements", `src/tests/shell/testsuites/punkexe/kitmountpoint.test`. - **Static package capture (G-058, achieved).** Boot probe-loads the runtime's statically linked packages in a throwaway interp and records what each provides; every interp the shell fabricates (boot, codethread, shellthread workers) seeds `package ifneeded {load {} }` from that record, and `punk::packagepreference` resolves static-vs-bundled version-aware. Sources: `src/vfs/AGENTS.md`, `goals/archive/G-058-static-runtime-packages.md`. - **`script` subcommand (G-015, achieved).** The lean non-interactive path: default punk shell module/alias environment, no shellfilter stacks/transforms, honest exit codes, launch plumbing emits nothing on stdout/stderr (exec-style callers see only the script's own output). Supports `lib:` scriptlib resolution; a first argument of exactly `-e` runs the second argument as a Tcl one-liner (G-077, achieved - `::argv0` is `-e`, trailing args in `::argv`, a usage error when the script argument is missing, stdin never read by the form itself, non-empty final result echoed), also reachable as top-level ` -e` via a boot-core reclassification ahead of the unknown-first-arg refusal. App package: `src/lib/app-punkscript/`. -- **`tclsh` subcommand (G-118, achieved).** Plain-tclsh emulation with NO punk modules loaded: stock argument-form parity (`-encoding name file`; any other leading `-` argument means no script, everything stays in `::argv`; no `-e` one-liner - deliberate stock parity; the punk-level one-liner lives at the top level and as `script -e` (G-077, achieved 2026-08-04 - goals/archive/G-077-punkexe-dash-e-oneliner.md)), `lib:` refused with a pointer at `script`, missing script file is a clean exit 1. On piperepl-patched runtimes (the punk family runtimes - `src/buildsuites/suite_tcl90/patches/`) the C-level machinery publishes `::tclsh` launch state (`istty`, `dorepl`, `evalinput`, `inputbuffer`, `reopened`) allowing piped input to hand over to a live console repl at eof; runtimes without the machinery evaluate piped stdin whole-buffer with honest exit codes and fail fast on console stdin. The subcommand-family contract (tclsh/script/shell/punk/shellspy/buildinfo/help) is documented as punk::args definitions in `src/modules/punk/args/moduledoc/punkexe-999999.0a1.0.tm` (ids `(script)::punkexe` + per-subcommand; view via `punk::args::usage`), which the G-032 launcher help wiring renders and parses from at dispatch time (a help flag as tclsh's SOLE argument is the one deliberate stock-parity exception). Pipe-testable behaviour pinned by `src/tests/shell/testsuites/punkexe/tclshcmd.test` and `launcherhelp.test`. +- **`tclsh` subcommand (G-118, achieved).** Plain-tclsh emulation with NO punk modules loaded: stock argument-form parity (`-encoding name file`; any other leading `-` argument means no script, everything stays in `::argv`; no `-e` one-liner - deliberate stock parity; the punk-level one-liner lives at the top level and as `script -e` (G-077, achieved 2026-08-04 - goals/archive/G-077-punkexe-dash-e-oneliner.md)), `lib:` refused with a pointer at `script`, missing script file is a clean exit 1. On piperepl-patched runtimes (the punk family runtimes - `src/buildsuites/suite_tcl90/patches/`) the C-level machinery publishes `::tclsh` launch state (`istty`, `dorepl`, `evalinput`, `inputbuffer`, `reopened`) allowing piped input to hand over to a live console repl at eof; runtimes without the machinery evaluate piped stdin whole-buffer with honest exit codes and fail fast on console stdin. The subcommand-family contract (tclsh/script/shell/punk/shellspy/buildinfo/help) is documented as punk::args definitions in `src/modules/punk/args/moduledoc/punkexe-999999.0a1.0.tm` (ids `(script)::punkexe` + per-subcommand; view via `punk::args::usage`), which the G-032 launcher help wiring renders and parses from at dispatch time (`help tclsh` for the usage; stock dash parity is exception-free since the 2026-08-05 single-mechanism revision). Pipe-testable behaviour pinned by `src/tests/shell/testsuites/punkexe/tclshcmd.test` and `launcherhelp.test`. - **`bin/` launch surface.** Built kits plus polyglot `.cmd` utilities (`punk-runtime`, `punk-getzig`, `punk-tclargs`, `dtplite`) generated from `src/scriptapps/` sources by the `punk::mix` scriptwrap machinery - outputs are never hand-edited. `bin/punk-runtime.cmd` fetches/lists/selects plain runtimes under `bin/runtime//` from the punkbin artifact server with sha1 verification. Source: `bin/AGENTS.md`. ## Interp and thread topology diff --git a/CHANGELOG.md b/CHANGELOG.md index 44e0e98f..880e7746 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,26 @@ 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.53.0] - 2026-08-05 + +- Single help mechanism (user direction; boot core 0.5.0, moduledoc::punkexe + 0.6.0, moduledoc::punkboot 0.3.0): all -help/--help flag interception is + withdrawn from the kit launcher and make.tcl - the leading `help` word is + the one help entry (the punkshell `i ...` idiom). ` help + ?arg ...?` now accepts and ignores trailing words, so `help` + can simply be prepended to an existing command line (previously + `help tclsh somefile somearg` confusingly fell back to the top-level + table). Help flags are ordinary arguments everywhere: a leading `-help` + earns the unknown-first-argument refusal (whose stderr usage answers it, + exit 1), `tclsh -help` regains full stock dash parity (the sole-argument + carve-out is gone), `buildinfo -help` is refused like any argument + (exit 2), the experimental shellspy processor's own -help/--help handling + is reachable again, and `make.tcl ... -help` fails whatever + punk::args gate it meets (e.g. `bakelist -help` = the same choice-gate + rejection as `bakelist nonexistant`) with the usage error itself carrying + the documentation. launcherhelp.test and maketclhelp.test re-pinned to + the revised contract. + ## [0.52.0] - 2026-08-04 - G-165 driver-invariant kit assembly: every make.tcl zip-kit bake now emits diff --git a/bin/AGENTS.md b/bin/AGENTS.md index bff6e178..11eed0fc 100644 --- a/bin/AGENTS.md +++ b/bin/AGENTS.md @@ -97,7 +97,7 @@ platform-specific difference left in examples is path separator style ### Launch package modes (built punk shells) -The first argument to a built punk shell may be a dash-delimited package mode composed of tokens from `minted`, `os`, `src`, `internal` (e.g. `punksys src`, `punk902z minted-os`), optionally scoped with the `proj:` prefix (e.g. `punk91 proj:internal-src`). (`minted` was named `dev` before punkshell 0.43.0 - clean rename, no alias: old kits accept only `dev`, current kits only `minted`.) `internal` is the default and is always appended when absent. A first argument that is not a valid mode list is treated as a subcommand instead (a `proj:` prefix on a non-mode string is not consumed either). Implementation: `src/vfs/_config/punk_main.tcl` (search `all_package_modes`). The full packagemode contract (block meanings, ordering, proj: examples) is the punk::args documentation at id `(script)::punkexe` (module `punk::args::moduledoc::punkexe`), and the launch surface is self-documenting in every current kit (G-032): ` help ?subcommand?`, ` -help` or ` -help` render tabled usage (with the packagemode contract as the leader row) - degrading to a plain subcommand list where the punk::args stack is unavailable. An unknown first argument that names no existing file (and no `lib:*` scriptlib reference) is refused with that usage rather than silently attempted as a script. A first argument of exactly `-e` instead runs the following argument as a Tcl one-liner (G-077; equivalently ` script -e