Agent handbook for the ShellSpy (Punk Shell) repository. These guidelines cover builds, linting, testing, code style, and day-to-day conventions for all contributors and agentic assistants. Always check for nested `AGENTS.md` files before editing subdirectories. This root spec applies repo-wide unless overridden deeper in the tree.
- Run `tclsh src/make.tcl packages` once after cloning to populate generated assets.
- Keep edits within the scoped instructions of any nested `AGENTS.md`.
- Review VS Code Tcl lint diagnostics before submitting new agent-produced Tcl code, but do not use lint tooling to reformat existing code.
- Execute at least one relevant test script (`tclsh src/tests/<path>/<file>.tcl`).
- Document changes impacting build, tooling, or developer workflow.
## Build & Bootstrap Commands
- **Primary build**: `tclsh make.tcl project` (Windows default) or `punk902z make.tcl project` inside Punk shell.
- **Clean/resync**: Remove `_build/` artifacts then rerun `tclsh make.tcl project`; avoid partial cleans that break boot modules. Cleaning _build is generally not required.
- **Binary images**: Use `punk make.tcl project` to produce punk binaries. There are no platform-specific flags for cross-platform building - it must currently be done on each specific platform. The Tcl modules and libs are mostly cross-platform by nature, but the built binaries rely on platform specific runtimes and some binary packages from whichever src/vfs/*.vfs folder was used to build.
## Testing Strategy
- **Test location**: `src/tests/` holds all Tcl test scripts; keep new tests there, named with the .test file extension.
- **Run entire suite**: Run base src/tests/runtests.tcl or Iterate with something like `for /r src\tests %f in (*.tcl) do tclsh %f` (Windows) or a similar shell loop on POSIX.
- **Run single test**: `tclsh src/tests/<path>/<script>.tcl` (e.g., `tclsh src/tests/modules/opunk/str/tests/all.tcl`).
- **Focused verification**: Mirror production pipelines inside tests using Punk pipeline syntax for parity.
- **Test dependencies**: Every test must `package require punk`; declare extra packages explicitly to avoid hidden dependencies.
- **Command**: None. Tcl linting is currently only available through the VS Code tclint plugin, configured via `tclint.toml`; do not try to run `tclint` or `tcllint` as shell commands.
- **Files covered**: `.tcl`, `.tm` extend config if new extensions appear.
- **Line length**: Hard cap at 400 characters; wrap pipelines thoughtfully instead of exceeding.
- **Blank lines**: No more than 10 consecutive blanks.
- **Indentation**: 4 spaces; tabs are disallowed in Tcl sources except inside string literals.
## Toolchain & Dependencies
- Prefer the provided vendor modules under `src/vendor*` before fetching new dependencies.
- Use `tcl::tm::path add <dir>` to surface project modules when writing new tooling.
- Keep compatibility with Tcl 8.6+; gate 9.0-specific features behind version checks, or use existing punk::lib::compat functions.
- When optional compiled extensions (e.g., `twapi`, `tdom`) are necessary, guard `package require` calls with fallback messaging.
## Repository Layout Primer
```
modules/ # Target module folder for when `tclsh src/make.tcl modules` is run. Agents should not directly modify.
lib/ # Target library folder for when `tclsh src/make.tcl libs` is run. Agents should not directly modify.
src/
bootsupport/modules/ # Early-load modules with minimal deps. These are analogous to npm devDependencies. Agents should not directly modify.
modules/ # Main Punk modules (.tm) - most development for punkshell is in this section.
modules/test # Hierarchy for unit tests that have been bundled into .tm module-based test packages with module name portion beginning with 'test' namespace/folder matching the namespace/folder of the module to be tested. Agents should generally not update this area aside from updating versions as necessary in <modulename>-buildversion.txt files, as it is generated from src/tests or manually updated by the user. Running these tests, tests the installed module/library state (that acheived after running `tclsh src/make.tcl packages|modules|lib`)
lib_tcl8/ # Tcl8 specific pgkIndex.tcl-based libraries
lib_tcl9/ # Tcl9 specific pgkIndex.tcl-based libraries
runtime/ # Location of mapvfs.config which determines which src/vfs/*.vfs folders are mapped with which runtime executable.
scriptapps/ # Entry-point scripts for Punk apps
testansi/ # sample files for punk::ansi features. Agents should not modify.
vendormodules/ # Third-party modules bundled with repo. .tm files are either manually placed here or refreshed based on include_modules.config using `tclsh src/make.tcl vendorupdate`.
tests/ # Unit tests (using the tcltest package) - these are designed to run against the modules in the src hierarchy. ie prior to installation.
vfs/ # Virtual file system images for builds - *.vfs folders are currently manually updated by the user, not Agent modified.
vfs/_config/ # Entry point .tcl files for executables built from the *.vfs folders.
vfs/_vfscommon.vfs # Common libraries to be integrated into vfs during executable building. These are completley refreshed by running `tclsh src/make.tcl vfscommonupdate` - not modified directly by user or agents.
scriptlib/ # Shared utilities + manual tests. Updated by user only unless explicit request made for agent to modify.
bin/ # Helper binaries/scripts. Target for built punk binaries made from bin/runtime/<platform>/*.exe files and associated src/vfs/*.vfs folders. Agents should not modify.
bin/runtime/* # Immediate subfolders are named for the target platform. These are where specific pre-built runtimes are installed by the bin/runtime.cmd helper script (or manually). Agents should not modify.
callbacks/ # Experimental features for when punkshell is launched with the "shellspy" parameter. Agents should not modify.
```
Treat VFS directories as generated artifacts; edit them only when updating runtime payloads.
## File Resolution Policy
Use the strongest available anchor first and do not broaden scope until that anchor is checked.
### Anchor Order
1. Exact path named by the user.
2. Active editor file, when the environment provides one.
3. Exact proc, symbol, or identifier named by the user.
4. Repository naming and source-precedence rules.
Do not skip a stronger anchor for a weaker one.
### Source Priority
- For editable Punk module source, prefer `src/modules/`.
- Source module filenames use the literal suffix `-999999.0a1.0.tm`.
- Do not shorten or normalize that suffix.
- For editable Tcl library source, prefer `src/lib/`.
- Treat `src/modules_tcl<major>/` and `src/lib_tcl<major>/` as Tcl-major-version-specific source trees.
- Prefer generic source in `src/modules/` or `src/lib/` unless the package, proc, or surrounding package mapping is specific to a Tcl major version or exists only in a version-specific tree.
- Treat `pkgIndex.tcl` as a loader map unless the task is about package loading or registration.
- If the best hit is `pkgIndex.tcl`, resolve the implementation file and continue there.
- Prefer editable source over bootstrap, VFS, built, installed, project layout, or generated copies unless the user explicitly targets one of those.
### Proc Inspection Order
1. Read the exact file named by the user, if provided.
2. Otherwise read the active editor file, if provided and relevant.
3. Otherwise search once for the exact proc name.
4. Prefer editable source under `src/modules/`, `src/modules_tcl<major>/`, `src/lib/`, or `src/lib_tcl<major>/`.
5. If multiple matches exist, prefer the generic source tree unless version-specific behavior is relevant or only a version-specific definition exists.
6. If the best hit is `pkgIndex.tcl`, use it to resolve the implementation file.
7. Once the owning source file is identified, continue locally from that file.
### Recovery After Wrong Path Guess
- Re-check user-provided path.
- Re-check active editor file, if available.
- Re-check repo naming conventions.
- Use one exact symbol search instead of probing more filename variants.
## Imports & Package Management
- Always declare dependencies explicitly using `package require <name>` near file tops.
- Organize custom modules as `namespace eval punk::<modulename>` with filenames like `src/modules/punk/<modulename>-<magicversionnumber>.tm`.
- Custom modules can have deeper hierarchies such as `punk::lib::util::<somename>` with a corresponding directory structure.
- Use semantic versions that `package vcompare` can interpret; strip leading zeros.
- For optional features, probe with `if {[catch {package require foo}]} { ... }` and degrade gracefully.
## Formatting & Layout Rules
- Opening braces stay on the same line for procs; multiline control structures may span lines for readability if Tcl syntax allows without using line-continuation-backslash. e.g braced `expr` contents (or `if` expressions)
- Line continuation backslashes should only be used in documentation blocks for use with punk::args (ie in 'punk::args::define' arguments or in 'lappend PUNKARGS' elements)
- proc contents should not use line continuation backslashes as it can make debug line-number matching harder. use Tcl expand operator with an opening brace instead.
e.g
dict create {*}{
a A
b B
c C
}
This works in a single block for literals, but for values that need substitution, additional expand with brace pairs may be needed.
e.g
dict create {*}{
} a A
b B
c C {*}{
} d $DVAL {*}{
}
- test files may commonly use line continuations - which is ok in this instance outside of proc definitions.
- For test files that include tcl expand syntax based structures - these should not be refactored into line continuations.
- Keep pipelines readable by aligning `% var = ...` and `pipecase` segments vertically when possible.
- Document non-trivial procedures and exports with the standard header template (see below).
## Naming Conventions
- **Procedures**: `lowercase_with_underscores` for internals, `camelCase` allowed for public APIs where existing patterns fit.
- **Variables**: `lowercase_with_underscores`; avoid single-letter names except for loop indices.
#- If performance sensitive or not part of a broad-concept of 'API' for the module and useful utilities,
#- use fast `switch` based code to parse the arguments.
#- procedure functionality implementation
}
```
Update the template with concrete details whenever functions are user-facing or complex.
## Error Handling & Logging
- Prefer `try { ... } on error {result options} { ... }` (Tcl 8.6+) for structured handling.
- Fallback pattern:
```tcl
if {[catch {some_command} result]} {
puts stderr "Error: $result"
return -code error $result
}
```
- For Punk pipelines, wrap risky commands inside `pipecase` blocks and emit descriptive messages via `puts stderr` or Punk logging helpers.
- Never swallow errors silently; propagate with context so shell users see actionable details.
## Pipeline & Functional Style Notes
- Punk Pipeline functionality is somewhat experimental/in-flux and should usually be avoided for AI generated code unless the user specifically requests it.
- Use `% var = ...` bindings to capture intermediate values; keep names meaningful.
- `pipecase` should list specific patterns before catch-alls to avoid hidden matches.
- `fun name pattern { ... }` definitions should remain side-effect light; treat them as pure functions unless otherwise documented.
- Keep pipelines short and composable; extract into helper procs or `fun` definitions when they exceed ~10 logical steps.
## Module Structure Expectations
```tcl
# <Moduledescription>
package require <dependencies>
#- comments such as this with a leading dash are descriptions for the agent of how-to/what-to to implement
#- whereas comments without the dash are either literal comments, or if angle-bracketed, descriptions of what to put in the comment.
namespace eval <module_namespace> {
variable version <semver>
namespace export public_proc1 public_proc2
namespace eval argdoc {
lappend PUNKARGS [list {
@id -id <module_namespace>::public_proc1
... elided ...
#- punk::args textblock similar to example given in Procedure Documentation Template
#- This should exist immediately prior to each proc (or at least very close),
#- even if it is only being used for documentation and not for parsing.
#- If the public_proc1 proc does not use the PUNKARGS definition for parsing; then the parsing within the proc
#- and the punk::args definitions of proc args and behaviour; must be kept synchronized.
}]
}
proc public_proc1 {args} {
#- argument parsing code, using `punk::args::parse` if part of API and not performance critical
#- if argument parsing is done in code here - the behaviour must match the arguments as defined in the PUNKARGS list created above.
package provide <module_namespace> [tcl::namespace::eval <module_namespace> {
variable version
#- this version number, exactly 999999.0a1.0 is a literal that should be used in all src/module folders
#- we refer to this sometimes as the 'magic version number'
set version 999999.0a1.0
}]
return
```
Ensure module filenames include the magic version (`punk/<subpath>/<modulename>-999999.0a1.tm`), and keep `namespace export` lists alphabetized for clarity.
## Type & Data Handling
- Tcl is dynamically typed; emulate structural typing via argument validation at proc boundaries.
- Validate user inputs with punk::args::parse or `switch -exact`, `regexp`, or Punk pipeline predicates before mutation.
- Use dictionaries for structured data, or parallel lists if it is likely to be a performance win.
- Tcl arrays can also be used, but limit to simple flat structures, or cases where it is specifically warranted.
- When bridging to binary data (e.g., ANSI/xbin parsing), document expected encodings and conversions.
## Versioning & Releases
- Stick to semantic versioning (`major.minor.patch`).
- Use the magic version 999999.0a1.0 for src/modules src/modules_tcl9 etc and add/update the actual version number in the associated <modulename>-buildversion.txt file.
- Update the <modulename>-buildversion.txt file when API changes are made
- There may be occasional exceptions such as punk::libunknown-0.1.tm which is deliberately manually versioned, but new modules should use the magic version mechanism.
- vendormodules and modules in .vfs folders or src/bootsupport/modules should not use the magic version mechanism, nor should modules with the magic version number appear in the output paths such as <projectdir>/modules
- When referencing ranges, use bounded specs (e.g., `1.2.3-2.0.0`).
- Convert loose versions to bounded form in module metadata; helper utilities exist in boot modules for this purpose.
- Favor compiled extensions (tcllibc, twapi) when available, but provide scripted fallbacks whenever possible.
- Be mindful of long-running pipelines; chunk work and avoid blocking the Punk shell UI thread.
## Documentation & Comments
- Keep inline comments concise; describe intent, not mechanics.
- Primary documentation for procs should use the punk::args system, preferably within an argdoc sub namespace using: lappend PUNKARGS <listoftextblocks>
- Update any relevant docs or usage notes when behavior changes.
- Mention environment variables or flags required to run new features.
## Agent Workflow Tips
- No `.cursor/rules/`, `.cursorrules`, or `.github/copilot-instructions.md` files exist as of this update. If they appear later, integrate their instructions here.
- Review VS Code Tcl lint diagnostics and run the most specific test affected by your changes before committing.
- When a tool summary reports cleanup issues such as `git diff --check` whitespace errors, verify against the exact command output and exit code before running secondary scans or reporting the issue.
- When touching VFS payloads, describe regeneration steps inside commit messages and this guide if persistent.
- Favor incremental commits tied to logical units of work; avoid monolithic diffs mixing tooling and feature changes.
## Final Submission Checklist
- [ ] Nested `AGENTS.md` files checked for scope-specific rules.
- [ ] VS Code Tcl lint diagnostics reviewed when available; no `tclint`/`tcllint` CLI is expected.
- [ ] Relevant tests (`tclsh src/tests/runtests.tcl`) executed and passing, or more specific `tclsh src/tests/modules/<modulehierarchypath>/tests/all.tcl` passing
- [ ] Documentation/comments updated for new behavior or flags.
- [ ] Diffs reviewed to ensure no stray whitespace or debugging output remains.
Adhering to these conventions keeps the ShellSpy/Punk Shell ecosystem consistent, portable, and friendly for future agentic collaborators. Happy hacking!
- This root file is intentionally limited to DOX governance, global ownership boundaries, and the top-level Child DOX Index.
- Source-tree build, testing, linting, and file-resolution workflow lives in `src/AGENTS.md`.
- Tcl module authoring conventions live in `src/modules/AGENTS.md` and closer module child docs.
- If AGENTS.md conflicts with CLAUDE.md, AGENTS.md wins.
@ -8,27 +8,75 @@ The source tree root contains all editable source code, build scripts, test suit
- The `src/` tree is where agents perform development work.
- Generated/output directories at the project root (`modules/`, `lib/`, `lib_tcl8/`, `lib_tcl9/`, `modules_tcl8/`, `modules_tcl9/`) are build targets — agents must not directly modify them.
- VFS payloads, runtime mappings, vendored dependencies, generated docs, and entry-point scripts have child AGENTS.md files with local ownership rules.
## Local Contracts
- `make.tcl` is the primary build entry point: `tclsh src/make.tcl <command>`.
- Source priority for libraries: `src/lib/` > `src/lib_tcl<major>/` > vendorlib.
- The `_build/` directories are build intermediates; they can be deleted and regenerated.
- Tcl 8.6+ is required and Tcl 9.0 is supported; gate 9.0-specific behavior behind version checks or existing `punk::lib::compat` helpers.
- Primary target is Windows (`win32-x86_64`); Linux, macOS, and FreeBSD are secondary targets.
- Tcl linting is available only through the VS Code Tcl lint plugin configured by `tclint.toml`; do not try to run `tclint` or `tcllint` as shell commands.
- Lint coverage is `.tcl` and `.tm`; extend config if new Tcl-related extensions appear.
- Shared Tcl source formatting defaults are a 400-character line cap, no more than 10 consecutive blank lines, 4-space indentation, and no tabs except inside string literals.
- Source priority for editable modules: `src/modules/` > `src/modules_tcl<major>/` > bootsupport > VFS > built > installed.
- Source priority for editable libraries: `src/lib/` > `src/lib_tcl<major>/` > vendorlib > VFS > built > installed.
- Treat `pkgIndex.tcl` as a loader map unless the task is about package loading or registration.
- Prefer vendored dependencies under `src/vendor*` before fetching new dependencies.
- Guard optional compiled extensions such as `twapi` or `tdom` with fallback behavior or actionable messages.
### File Resolution Policy
Use the strongest available anchor first and do not broaden scope until that anchor is checked.
Anchor order:
1. Exact path named by the user.
2. Active editor file, when the environment provides one.
3. Exact proc, symbol, or identifier named by the user.
4. Repository naming and source-precedence rules.
Proc inspection order:
1. Read the exact file named by the user, if provided.
2. Otherwise read the active editor file, if provided and relevant.
3. Otherwise search once for the exact proc name.
4. Prefer editable source under `src/modules/`, `src/modules_tcl<major>/`, `src/lib/`, or `src/lib_tcl<major>/`.
5. If multiple matches exist, prefer the generic source tree unless version-specific behavior is relevant or only a version-specific definition exists.
6. If the best hit is `pkgIndex.tcl`, use it to resolve the implementation file.
7. Once the owning source file is identified, continue locally from that file.
Recovery after a wrong path guess:
- Re-check the user-provided path.
- Re-check the active editor file, if available.
- Re-check repo naming conventions.
- Use one exact symbol search instead of probing more filename variants.
## Work Guidance
- Run `tclsh src/make.tcl packages` once after cloning to populate generated module and library assets.
- Use `tclsh src/make.tcl project` for full builds.
- Use `tclsh src/make.tcl modules` to build just the module packages.
- Use `tclsh src/make.tcl libs` to build just the library packages.
- Use `tclsh src/make.tcl packages` to build both modules and libraries.
- Use `tclsh src/make.tcl vendorupdate` to refresh vendormodules from config.
- Use `tclsh src/make.tcl vfscommonupdate` to rebuild `_vfscommon.vfs`.
- Use `punk make.tcl project` or `punk902z make.tcl project` inside Punk shell when building binaries through Punk.
- Binary images are platform-specific; build on each target platform rather than expecting a cross-platform flag.
- Remove `_build/` artifacts only when a clean/resync is needed, then rerun the relevant `make.tcl` command. Avoid partial cleans that break boot modules.
- Use `tcl::tm::path add <dir>` to surface project modules when writing focused tooling.
- Review VS Code Tcl lint diagnostics before submitting new agent-produced Tcl code, but do not use lint tooling to reformat existing code.
- When touching VFS payloads, describe regeneration steps in durable docs if the workflow changes.
- When a tool summary reports cleanup issues such as `git diff --check` whitespace errors, verify against exact command output and exit code before running secondary scans or reporting the issue.
## Verification
- `tclsh src/make.tcl project` completes without errors.
- `tclsh src/tests/runtests.tcl` passes.
- VS Code Tcl lint diagnostics are reviewed for modified Tcl files when available.
- Relevant tests pass, either `tclsh src/tests/runtests.tcl` or a specific `tclsh src/tests/modules/<modulehierarchypath>/tests/all.tcl`.
- `tclsh src/make.tcl packages` is verified when touching build-critical code.
- `tclsh src/make.tcl project` completes without errors when changing build, runtime, or VFS behavior.
- Documentation/comments are updated for new behavior, flags, workflow, or ownership rules.
- Diffs are reviewed so no stray whitespace or debugging output remains.
## Child DOX Index
@ -50,4 +98,4 @@ The source tree root contains all editable source code, build scripts, test suit
- `vendorlib_tcl9/` — Tcl 9 specific vendor libraries
- `runtime/` — Build runtimes and VFS config (see runtime/AGENTS.md)
- `doc/` — Generated documentation (see doc/AGENTS.md)
- `testansi/` — Sample ANSI art files (do not modify)
- `testansi/` — Sample ANSI art files (do not modify)
@ -15,6 +15,7 @@ Modules and libraries required during the build/bootstrap/make process before th
- Modules here are loaded by initialisation scripts via `tcl::tm::path`.
- Each `.tm` file must work standalone without requiring Punk's full module loading infrastructure.
- The `include_modules.config` file controls which vendormodules are pulled into bootsupport.
- Bootsupport snapshots do not use the `999999.0a1.0` source-module magic version unless explicitly copied from a source module with the prescribed workflow.
Source of truth for all editable Punk project modules. This is where agents should make module source edits. Each `.tm` file is a Tcl module belonging to a named package.
Source of truth for all editable Punk project modules. This is where agents should make generic module source edits. Each `.tm` file is a Tcl module belonging to a named package.
## Ownership
- Agents should edit files here as the primary development area.
- The top-level modules (non-punk namespace) include shellfilter, shellrun, overtype, textblock, patternpunk, etc.
- Agents should edit files here as the primary development area for generic modules.
- The top-level modules (non-punk namespace) include shellfilter, shellrun, overtype, textblock, patternpunk, and related packages.
- The `punk/` subdirectory holds all `punk::*` namespace modules.
- Tcl-major-specific sibling trees under `src/modules_tcl8/` and `src/modules_tcl9/` mirror these module conventions where applicable, but their local AGENTS.md files control source selection for version-specific behavior.
## Local Contracts
- Module filenames use the literal suffix `-999999.0a1.0.tm`.
- Corresponding `<modulename>-buildversion.txt` files hold the real version number.
- The exception is `punk::libunknown` which uses its own version `0.1`.
- `#modpod-*` directories contain internal files packed into `.tm` archives during build — do not flatten or edit without understanding the modpod format.
- The exception is `punk::libunknown`, which uses its own version `0.1`.
- `#modpod-*` directories contain internal files packed into `.tm` archives during build; do not flatten or edit them without understanding the modpod format.
- `_build/` directory holds build intermediates and should not be manually edited.
- Always declare dependencies explicitly using `package require <name>` near file tops.
- Prefer fully qualified namespaces when referencing external packages, such as `package require tcl::zlib` or `package require TclOO`.
- Organize custom modules as namespaces mirroring directory structure, such as `namespace eval punk::<modulename>` or deeper paths like `punk::lib::util::<somename>`.
- Use semantic versions that `package vcompare` can interpret; strip leading zeros.
- For optional features, probe with `if {[catch {package require foo}]} { ... }` and degrade gracefully.
- Vendormodules, bootsupport snapshots, VFS modules, and built output modules do not use the magic version scheme unless their own local docs explicitly say otherwise.
## Work Guidance
- Treat `src/modules/` as the source of truth for generic editable Punk modules.
- Expect the literal suffix `-999999.0a1.0.tm`.
- Expect the literal suffix `-999999.0a1.0.tm` and do not shorten or normalize it.
- Prefer Unix-style LF line endings for `.tm` source files in this tree.
- If the same proc exists in both `src/modules/` and `src/modules_tcl<major>/`, prefer `src/modules/` unless version-specific behavior is relevant or only the version-specific file is active.
- Use `deck module.new <name>` or `punk::mix::commandset::module::new` to scaffold new modules.
- Run `tclsh src/make.tcl modules` to build modules, or `tclsh src/make.tcl project` for a full build.
### Formatting And Layout
- Opening braces stay on the same line for procs.
- Multiline control structures may span lines for readability if Tcl syntax allows without line-continuation backslashes, such as braced `expr` contents or `if` expressions.
- Line-continuation backslashes should only be used in documentation blocks for `punk::args`, such as `punk::args::define` arguments or `lappend PUNKARGS` elements.
- Proc bodies should not use line-continuation backslashes because they make debug line-number matching harder; use Tcl expand syntax where practical.
- For test-specific continuation rules, use `src/tests/AGENTS.md`.
- Keep pipelines readable by aligning `% var = ...` and `pipecase` segments when practical.
- Keep inline comments concise and describe intent, not mechanics.
- Document non-trivial procedures and exports with the standard `argdoc`/`PUNKARGS` template below.
Example expand-style dictionary literal:
```tcl
dict create {*}{
a A
b B
c C
}
```
Example expand-style dictionary literal with substituted values:
```tcl
dict create {*}{
} a A
b B
c C {*}{
} d $DVAL {*}{
}
```
### Naming Conventions
- Procedures: `lowercase_with_underscores` for internals; `camelCase` is allowed for public APIs where existing patterns fit.
- Variables: `lowercase_with_underscores`; avoid single-letter names except for loop indices.
package provide <module_namespace> [tcl::namespace::eval <module_namespace> {
variable version
#- this version number, exactly 999999.0a1.0, is a literal used in src module folders
#- we refer to this sometimes as the magic version number
set version 999999.0a1.0
}]
return
```
### Type And Data Handling
- Tcl is dynamically typed; emulate structural typing through argument validation at proc boundaries.
- Validate user inputs with `punk::args::parse`, `switch -exact`, `regexp`, or Punk pipeline predicates before mutation.
- Use dictionaries for structured data, or parallel lists if it is likely to be a performance win.
- Tcl arrays can be used, but limit them to simple flat structures or cases where they are specifically warranted.
- When bridging to binary data, such as ANSI/xbin parsing, document expected encodings and conversions.
### Versioning And Releases
- Stick to semantic versioning: `major.minor.patch`.
- Use the magic version `999999.0a1.0` for source modules and add or update the actual version number in the associated `<modulename>-buildversion.txt` file.
- Update the `<modulename>-buildversion.txt` file when API changes are made.
- There may be occasional exceptions such as `punk::libunknown-0.1.tm`, which is deliberately manually versioned; new modules should use the magic version mechanism.
- Modules with the magic version number must not appear in output paths such as `<projectdir>/modules`.
- When referencing ranges, use bounded specs such as `1.2.3-2.0.0`.
- Convert loose versions to bounded form in module metadata; helper utilities exist in boot modules for this purpose.
- Update `punk::libunknown` registries whenever adding or removing modules to keep discovery accurate.
### Documentation And Comments
- Primary documentation for procs should use the `punk::args` system, preferably within an `argdoc` sub-namespace using `lappend PUNKARGS <list of textblocks>`.
- If a public proc parses arguments manually, keep the implementation behavior synchronized with its PUNKARGS definition.
- Update relevant docs or usage notes when behavior changes.
- Mention environment variables or flags required to run new features.
## Verification
- VS Code Tcl lint diagnostics are clean for modified `.tm` files when available.
- `tclsh src/make.tcl modules` completes without errors.
@ -8,6 +8,7 @@ Holds source modules specific to Tcl major version 8. Use only when a package or
- Agents should prefer `src/modules/` over this tree unless the task explicitly involves Tcl 8-specific behaviour.
- Files here follow the same naming and structure conventions as `src/modules/`.
- Follow the module authoring conventions in `src/modules/AGENTS.md` where they apply; this file narrows source selection and Tcl 8 compatibility rules.
@ -8,6 +8,7 @@ Holds source modules specific to Tcl major version 9. Use only when a package or
- Agents should prefer `src/modules/` over this tree unless the task explicitly involves Tcl 9-specific behaviour.
- Files here follow the same naming and structure conventions as `src/modules/`.
- Follow the module authoring conventions in `src/modules/AGENTS.md` where they apply; this file narrows source selection and Tcl 9 compatibility rules.
@ -7,26 +7,32 @@ Unit tests that run against modules in the `src/` source tree, prior to installa
## Ownership
- Owned by the project maintainer; agents should add new tests here when modifying modules but must not delete or silently skip existing failing tests.
- This is the primary test-authoring location for module behavior. Installed-module test packages under `src/modules/test/` are a packaging layer, not the default place to add tests.
## Local Contracts
- Test files use `.tcl` extension and must `package require punk`(plus any extra packages explicitly).
- Test files use `.tcl` extension and must `package require punk` plus any extra packages explicitly.
- The directory hierarchy under `src/tests/modules/` mirrors namespace paths of the modules being tested.
- Tests run against source modules in the `src/` tree, not installed packages.
- Prefer `try { ... } on error {result options} { ... }` for structured error capture in test bodies.
- New test files go in `src/tests/modules/<namespacepath>/tests/` mirroring the module namespace.
- Prefer `try { ... } on error {result options} { ... }` for structured error capture in test bodies.
- Focused verification should mirror production pipelines inside tests using Punk pipeline syntax when that parity matters.
- Test files may commonly use line-continuation backslashes, and existing Tcl expand-syntax structures in tests should not be refactored into line continuations.
## Work Guidance
- Run a single test: `tclsh src/tests/modules/<namespacepath>/tests/all.tcl`
- Run the full suite: `tclsh src/tests/runtests.tcl`
- Run a single test: `tclsh src/tests/modules/<namespacepath>/tests/all.tcl`.
- Run the full suite: `tclsh src/tests/runtests.tcl`.
- On Windows, an alternate full-suite loop is `for /r src\tests %f in (*.tcl) do tclsh %f`.
- When adding a test, mirror the namespace path of the module under test.
- Do not add tests for vendormodules or bootsupport here unless explicitly requested.
- Capture stderr logs for failure triage and include enough context for the failing command or assertion.
## Verification
- `tclsh src/tests/<path>/all.tcl` exits cleanly with pass/fail summary.
- `tclsh src/tests/runtests.tcl` passes when broad test coverage is relevant.
## Child DOX Index
- `modules/` — Per-namespace test directories mirroring `src/modules/` structure
- `modules/` — Per-namespace test directories mirroring `src/modules/` structure