You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

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.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/<file>.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 <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 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 <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, 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 <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 like src/modules/punk/<segment>-<version>.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

# <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 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

# 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::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/<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!