# AGENTS.md 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. ## Quickstart Checklist - Confirm Windows-friendly Tcl toolchain (8.6+ required, 9.0 supported). - Run `tclsh make.tcl` once after cloning to populate generated assets. - Keep edits within the scoped instructions of any nested `AGENTS.md`. - Use `tclint` before submitting code to align formatting and structure. - Execute at least one relevant test script (`tclsh scriptlib/tests/.tcl`). - Document changes impacting build, tooling, or developer workflow. ## Build & Bootstrap Commands - **Primary build**: `tclsh make.tcl` (Windows default) or `punk make.tcl` inside Punk shell. - **Alt entry point**: `punk build.tcl` or `tclsh build.tcl` for kettle-style builds. - **Bootstrap shell**: `pmix KettleShell` from inside Punk shell for advanced packaging tasks. - **Clean/resync**: Remove `build/` artifacts then rerun `tclsh make.tcl`; avoid partial cleans that break boot modules. - **Binary images**: Use `punk make.tcl --target ` when producing platform-specific bundles (see script comments for targets). ## Testing Strategy - **Test location**: `scriptlib/tests/` holds all Tcl test scripts; keep new tests there. - **Run entire suite**: Iterate with `for /r scriptlib\tests %f in (*.tcl) do tclsh %f` (Windows) or a similar shell loop on POSIX. - **Run single test**: `tclsh scriptlib/tests/.tcl` (e.g., `tclsh scriptlib/tests/json.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. - **Failure triage**: Capture stderr logs; prefer `try/on error` blocks inside tests for clearer diagnostics. ## Linting & Formatting - **Command**: `tclint` (configured via `tclint.toml` in repo root). - **Files covered**: `.tcl`, `.tm`, `.sdc`; 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. - **Auto-fixes**: Run `tclint --fix` only when you have reviewed the resulting diff. ## Toolchain & Dependencies - Prefer the provided vendor modules under `src/vendor*` before fetching new dependencies. - Use `tcl::tm::path add ` to surface project modules when writing new tooling. - Keep compatibility with Tcl 8.6+; gate 9.0-specific features behind version checks. - When optional compiled extensions (e.g., `twapi`, `tdom`) are necessary, guard `package require` calls with fallback messaging. ## Repository Layout Primer ``` src/ bootsupport/modules/ # Early-load modules with minimal deps modules/ # Main Punk modules (.tm) lib/ # Classic Tcl libraries scriptapps/ # Entry-point scripts for Punk apps vendormodules*/ # Third-party modules bundled with repo scriptlib/ # Shared utilities + tests bin/ # Helper binaries/scripts callbacks/, plugj.tcl, etc # Integration glue for host environments src/vfs/* # Virtual file system images for builds ``` Treat VFS directories as generated artifacts; edit them only when updating runtime payloads. ## Imports & Package Management - Always declare dependencies explicitly using `package require ` near file tops. - Prefer fully-qualified namespaces when referencing external packages (`package require tcl::zlib`, `package require TclOO`). - Organize custom modules as `namespace eval punk::` with filenames like `src/modules/punk/-.tm`. - 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 place braces on new lines for readability. - Align continuations under their opening command; use explicit `\` when mapping to pipeline syntax is unclear. - 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. - **Namespaces**: Mirror directory structure; nested modules should reflect filesystem hierarchy. - **Private helpers**: Prefix with `_` (e.g., `_resolve_stream`); do not export them. - **Constants**: `UPPER_CASE_WITH_UNDERSCORES` declared via `namespace eval { variable CONSTANT value }` when practical. ## Procedure Documentation Template ```tcl # # Args: # arg1 - description # arg2 - description # Returns: # Description of return value proc procedure_name {arg1 arg2} { # 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 - 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 # Module description package require namespace eval { variable version namespace export public_proc1 public_proc2 proc public_proc1 {args} { # Implementation } proc _private_helper {} { # Private implementation } } ``` Ensure module filenames include the version (`punk/console-0.1.1.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 `switch -exact`, `regexp`, or Punk pipeline predicates before mutation. - Use dictionaries for structured data; avoid parallel lists. - When bridging to binary data (e.g., ANSI/xbin parsing), document expected encodings and conversions. ## Versioning & Releases - Stick to semantic versioning (`major.minor.patch`). - 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. - Update `punk::libunknown` registries whenever adding/removing modules to keep discovery accurate. ## Platform & Performance Notes - Primary target: Windows (win32-x86_64). Validate code paths that rely on Windows-only packages. - Secondary targets: Linux/macOS/FreeBSD; guard platform-specific calls with `if {$tcl_platform(os) eq "Windows"} {...}`. - Favor compiled extensions (tcllibc, twapi) when available, but always provide scripted fallbacks. - 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. - Update any relevant docs or usage notes in `scriptapps` 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. - Always re-run `tclint` and the most specific test affected by your changes before committing. - 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. - [ ] `tcllint` (and `tcllint --fix` if needed) executed with clean results. - [ ] Relevant tests (`tclsh scriptlib/tests/.tcl`) executed and passing. - [ ] Build step (`tclsh make.tcl`) verified when touching build-critical code. - [ ] 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!