9.4 KiB
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.tclonce after cloning to populate generated assets. - Keep edits within the scoped instructions of any nested
AGENTS.md. - Use
tclintbefore submitting code to align formatting and structure. - Execute at least one relevant test script (
tclsh scriptlib/tests/<file>.tcl). - Document changes impacting build, tooling, or developer workflow.
Build & Bootstrap Commands
- Primary build:
tclsh make.tcl(Windows default) orpunk make.tclinside Punk shell. - Alt entry point:
punk build.tclortclsh build.tclfor kettle-style builds. - Bootstrap shell:
pmix KettleShellfrom inside Punk shell for advanced packaging tasks. - Clean/resync: Remove
build/artifacts then reruntclsh make.tcl; avoid partial cleans that break boot modules. - Binary images: Use
punk make.tcl --target <name>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/<test_name>.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 errorblocks inside tests for clearer diagnostics.
Linting & Formatting
- Command:
tclint(configured viatclint.tomlin 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 --fixonly 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 <dir>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, guardpackage requirecalls 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 <name>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::<segment>with filenames likesrc/modules/punk/<segment>-<version>.tm. - Use semantic versions that
package vcomparecan 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 = ...andpipecasesegments vertically when possible. - Document non-trivial procedures and exports with the standard header template (see below).
Naming Conventions
- Procedures:
lowercase_with_underscoresfor internals,camelCaseallowed 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_UNDERSCORESdeclared vianamespace eval { variable CONSTANT value }when practical.
Procedure Documentation Template
# <Procedure summary>
# 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:
if {[catch {some_command} result]} { puts stderr "Error: $result" return -code error $result } - For Punk pipelines, wrap risky commands inside
pipecaseblocks and emit descriptive messages viaputs stderror 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. pipecaseshould 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
fundefinitions when they exceed ~10 logical steps.
Module Structure Expectations
# Module description
package require <dependencies>
namespace eval <module_namespace> {
variable version <semver>
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::libunknownregistries 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
scriptappswhen behavior changes. - Mention environment variables or flags required to run new features.
Agent Workflow Tips
- No
.cursor/rules/,.cursorrules, or.github/copilot-instructions.mdfiles exist as of this update. If they appear later, integrate their instructions here. - Always re-run
tclintand 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.mdfiles checked for scope-specific rules. tcllint(andtcllint --fixif needed) executed with clean results.- Relevant tests (
tclsh scriptlib/tests/<file>.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!