|
|
9 hours ago | |
|---|---|---|
| .claude | 2 days ago | |
| .fossil-custom | 3 years ago | |
| .fossil-settings | 2 days ago | |
| bin | 1 day ago | |
| callbacks | 2 weeks ago | |
| goals | 9 hours ago | |
| scriptlib | 15 hours ago | |
| src | 9 hours ago | |
| .gitignore | 2 days ago | |
| AGENTS.md | 2 days ago | |
| CHANGELOG.md | 9 hours ago | |
| CLAUDE.md | 1 week ago | |
| GOALS-archive.md | 17 hours ago | |
| GOALS.md | 9 hours ago | |
| LICENSE.txt | 3 days ago | |
| README.md | 3 days ago | |
| compositing_ansi.png | 2 years ago | |
| getpunk.cmd | 10 months ago | |
| getpunk.cmd.lastrun | 10 months ago | |
| getpunk.ps1 | 10 months ago | |
| hype_roysac.png | 2 years ago | |
| punk1.ico | 3 years ago | |
| punk1.png | 3 years ago | |
| punk1_transparent.png | 3 years ago | |
| punkproject.toml | 9 hours ago | |
| tclint.toml | 9 months ago | |
README.md
punkshell - an alternative Tcl Shell
BSD-2-Clause license (see LICENSE.txt)
Version 0.11.0 (2026-07) — this is alpha level software and still highly experimental. See CHANGELOG.md for recent changes.
Supported Platforms
- Tcl 8.6+ required; Tcl 9.0 and 9.1 supported.
- Primary target: Windows (win32-x86_64). Linux, macOS, and FreeBSD are secondary targets.
Getting Started
The project uses a Tcl-based build system (src/make.tcl). From the project root:
# Fetch a suitable Tcl runtime (cross-platform polyglot wrapper — runs from bash, powershell, or cmd.exe)
./bin/runtime.cmd fetch
# Build modules and libraries into the project root
tclsh src/make.tcl packages
# Full build (modules + libraries + VFS + binaries)
tclsh src/make.tcl project
See src/README.md for detailed build instructions and bin/AGENTS.md for the runtime manager.
For evaluating uncommitted source without a full build, a built executable can run directly against the source tree:
<punkexe> src shell
Features
- default ansi color output - toggle with 'colour on' and 'colour off' (or set NO_COLOR environment variable)
- convenient and comprehensive in-terminal display of tk, web and terminal ANSI colour names and codes.
- rendering of old-school Ansi art (cp437) in the terminal

- Relatively easy compositing of text blocks containing Ansi colour codes - (or rendered versions of ansi containing movement and other controls)
proc welcome_test {} {
package require textblock
package require punk::ansi
package require overtype
set ansi [textblock::join -- " " [punk::ansi::ansicat src/testansi/publicdomain/roysac/roy-welc.ans 80x8]]
# Ansi art courtesy of Carsten Cumbrowski aka Roy/SAC - roysac.com
set table [[textblock::spantest] print]
set punks [a+ web-lawngreen][>punk . lhs][a]\n\n[a+ rgb#FFFF00][>punk . rhs][a]
set ipunks [overtype::renderspace -width [textblock::width $punks] [punk::ansi::enable_inverse]$punks]
set testblock [textblock::testblock -size 15 rainbow]
set contents $ansi\n[textblock::join -- " " $table " " $punks " " $testblock " " $ipunks " " $punks]
set framed [textblock::frame -type arc -title [a+ cyan]Compositing[a] -subtitle [a+ red]ANSI[a] -ansiborder [a+ web-orange] $contents]
}
-
experimental functional/pattern-matching language features. (will not be performant until more work is done on script compilation)
e.g.1 basic pipeline with 2 segments
var_pipe_output.= var_list.= list a b c |> string toupper
e.g.2 basic pattern-match multi-assignment to variables x y & z
x@0,y@1,z@2.= list a b cequivalently:x@,y@,z@.= list a b cor evenx@,y@,z@= {a b c}
x/0,y/1,z/2,zz/3.= list a b cis similar - but the use of forward-slash instead of @ will not produce a mismatch if an index is out of range.
where .= indicates following arguments form a command, and a plain = accepts only a single argument as a value
The diminutive case of this isx= "something"as equivalent toset x "something"
Assignment operations and pattern-matches are slightly optimised to bytecompile, but are unlikely to compete with raw Tcl commands performance-wise.
e.g.3 destructuring pattern-match. Get value of key 'k1' from last item in a list of dicts.
x@end/@@k1.= list {k1 aaa} {k1 bb}returns bbbThere are many more pattern-matching features yet to be documented.
-
easy execution of externals commands with return of stdout, stderr and the exitcode of the process
The run... commands use a very basic repl-telemetry system to output more information to the console than just the return value,
but in a way which makes the return value clear. The telemetry only outputs if the command is the first word on the commandline.run <comand> ...
(return exitcode of process - and allows process writes to stderr/stdout to appear in console as they occur)runout [-n] <command> ...
(return stdout of process - no output until completion)runerr [-n] <command> ...
(return stderr of process - no output until completion)runx [-n] <command> ...(return a dict of stdout stderr exitcode - no output until completion)
The run... commands attempt to make it clear if a called process outputs a trailing newline by displaying a trailing blank line.
The optional-nargument can be used to suppress a trailing newline.runout -n pwdis thus similar to Tcl'sexec pwd
For simple casesexec <command>is fine - but the equivalentrunout -n <command>when used in the shell will display exitcode and stderr separately (whilst returning only stdout) exec will return stdout and stderr together.
If you are on a unix-like platform, or a windows platform which has something like msys2 to provide commands like 'which' and 'grep' in the path:
Tryrunx -n which grep nonexistantvsexec which grep nonexistantto see the difference in terms of easy access to what was written to stderr vs stdout.
The run... commands are intended as a supplement for rather than a replacement for Tcl's exec/open. -
namespace browser (contextual - allowing running of commands within the active namespace - analogous to 'cd' for directories)
n/- display child namespaces of current namespace (alias:/)
alson/ <globpattern>to restrict outputn/ <childns>- if the argument doesn't contain glob chars '*' or '?' - attempt to switch to a child namespace of that name. Analogous tocd <dir>
list any sub namespaces of the namespace we just switched to.n//- display child namespaces and commands (alias://)
with colourised indication of type such as proc,alias,ensemble,oo object,oo class,imported,exported where possible.
(renamed aliases and builtins and commands loaded from binaries will appear unmarked)nn/- move up one namespace towards root namespace '::' analogous tocd ..(alias::/)newns <somename>- create a child namespace called 'somename' and switch to it in one operation. (alias:/new)
-
cross-platform alternative to cd & ls/dir without invoking child processes. Display colourised listing of dirs and folders - with vfs indication.
d/- list current directory (alias./)
alsod/ <globpattern>to restrict outputd/ <subdir>- switch to subdir and list contents in one operationdd/- move up one directory and output listing. Roughly equivalent tocd ..followed by dir or ls (alias../)newdir <folder>- create a child directory and switch to it in one operation.
-
<punkexe> scriptsubcommand for reliable non-interactive script execution:punkexe script <file.tcl> ?args?— runs a script file with conventional::argv0/::argvcommands | punkexe script— runs piped stdin commands and exits at EOF (no trailingexitneeded)- Honest exit codes (0 success, 1 error with errorInfo on stderr); no shellfilter transforms or logging side effects.
lib:<name>resolution for scriptlib scripts:punkexe script lib:helloor barepunkexe lib:hello
-
pluggable console backends: the REPL can run against non-detectable terminal-like devices via
::opunk::Consolesubclasses (ssh-channel, tk-widget, test-double), with size, eof, and capability answered by subclass overrides. -
cross-platform runtime manager (
bin/runtime.cmd): fetch, list, use, and run Tcl runtimes — works from bash, powershell, or cmd.exe.list -remotecompares local vs server runtimes with sha1 verification. -
Ability to create zipfs wrapped applications with all required libraries built in.
-
Additional libraries
- improved fork of tcllib's imap4 (punk::imap4)
- netbox client library (punk::netbox)
- telnet client with support for cp437 e.g can render mapscii.me with mouse support, and can view the ANSI max-headroom movie at 1984.ws
- A feature-rich argument processor (punk::args) that can be used purely to generate function documentation, or
also to process and validate flags and values (punk::args)
The argument processor/documentor can display command synopses, grids of applicable argument choices,
and indications of when short-forms (prefixes for flags/arguments/values) are applicable.
Commands documented with punk::args carry inline usage tables accessible via
i <command>at the repl. - In-shell help system:
i <command>shows documented usage tables;i helplists registered help topics (tcl, env, console, etc.) with per-topic documented usage.
missing
- raw mode REPL (read-eval-print-loop) to allow commandline completion etc (undergoing development).
- documentation is incomplete, though the punk::args (PUNKARGS) system now provides inline usage tables and command documentation for many commands via
i <command>at the repl. - tests coverage is growing but not yet comprehensive — characterization suites exist for punk::args, punk::ns, punk::lib, punk::libunknown, punk::mix, shellthread, shellfilter, and console, among others.
- signal handling on unix-like platforms (ctrl-c implemented on windows only).
very unripe parts:
- shellfilter - api is clumsy
- scriptlib - will likely be reorganised/pruned significantly
- theming
Documentation
src/README.md— detailed build instructionsCHANGELOG.md— version history and recent changesAGENTS.md(root) + child AGENTS.md files — contributor guidance and project structure (DOX hierarchy)GOALS.md— technical goal index with per-goal detail files undergoals/
