Browse Source
A new .agents/skills/punkpath/SKILL.md (canonical) with a byte-identical
.claude/skills/punkpath/SKILL.md copy for Claude Code discovery (verified
sync with a plain diff). Models the tcl-whatis/tcl-nslist shape: a single
~0.7s side-effect-free punkshell invocation answering two questions agents
guess wrong:
1. Which PATH executable a bare command name actually runs, and what
shadows it (overshadowed/overshadowed_by entry-idx fields). This is
the diagnostic companion to the tcl-runtests warning that bare tclsh
from a Bash tool often resolves to the MSYS tclsh - the skill gets
the machine-readable verdict on which copy wins instead of guessing.
2. Whether a PATH executable clashes with a Tcl command (tcl_conflicts
command:match=exact|nocase) - the 'invalid command name X' where X is
X.exe on PATH (dir/sort/find/clip).
Documents the -return json/text/dict forms, the -pathglob/-conflicts
filters, and the -context lever (G-173: pass it for a stable conflict
verdict through a wrapper/one-liner; the default-caller namespace is for
interactive use). Scope kept tight to PATH-resolution and Tcl-command
clash; explicitly disclaims being a general 'what is installed' tool.
No root AGENTS.md index change (the .agents/skills/ entry is generic and
does not list individual skills, matching the tcl-whatis/tcl-nslist/
tcl-runtests handling).
Assisted-by: harness=pi; primary-model=huggingface/zai-org/GLM-5.2; api-location=huggingface.co
master
2 changed files with 244 additions and 0 deletions
@ -0,0 +1,122 @@
|
||||
--- |
||||
name: punkpath |
||||
description: "Use to resolve which PATH executable a bare command name actually runs (and what shadows it), and whether a PATH executable clashes with a Tcl command - the two questions agents guess wrong when debugging test failures or 'invalid command name X' errors. Cost: one ~0.7s side-effect-free punkshell invocation. Returns JSON via 'punk91 src script -e {punk::path -return json <name>}' listing PATH entries whose executables match the name, each with overshadowed/overshadowed_by (entry idx) and tcl_conflicts (command:match=exact|nocase) fields. Not a general 'what is installed' tool - PATH shadowing and Tcl-command clash only." |
||||
--- |
||||
|
||||
# punkpath |
||||
|
||||
PATH-executable resolution and Tcl-command clash diagnosis for the punkshell |
||||
repo - the "which tclsh will I actually get, and does X.exe shadow a Tcl |
||||
command?" answer that agents guess wrong. Asks the live interpreter via |
||||
`punk::path -return json`, so the verdict is the OS PATH-resolution truth |
||||
(first non-shadowed entry wins), not a guess from `which`/`where` or a |
||||
single-env-var read. |
||||
|
||||
## When to use |
||||
|
||||
- A test run fails in a way that smells like the wrong interpreter |
||||
(spurious Tcl-version failures, msys path semantics). The tcl-runtests |
||||
skill warns that bare `tclsh` from a Bash tool often resolves to the |
||||
MSYS/Git-for-Windows tclsh; run this to get the machine-readable verdict |
||||
on which `tclsh.exe` wins and what it shadows, instead of guessing. |
||||
- An "invalid command name X" error where X might be an `X.exe` on PATH |
||||
clashing with a Tcl command (`dir`, `sort`, `find`, `clip` are classic). |
||||
The `tcl_conflicts` field reports the resolved Tcl command and the |
||||
exact|nocase match. |
||||
- Before asserting an external tool is available, or which copy of a |
||||
duplicate (e.g. several `tclsh.exe`) the shell will execute. |
||||
|
||||
## Command |
||||
|
||||
Run from the repo root (`punk91` lives in `bin/`, so `bin/punk91` from the |
||||
Bash tool). `punk91` embeds Tcl 9.1; `punk905` (Tcl 9.0) or `punksys` |
||||
(Tcl 8.6) take the same one-liner. Cost: ~0.7s filtered, ~0.7s full PATH, |
||||
no side effects (read-only). |
||||
|
||||
bin/punk91 src script -e 'punk::path -return json ?-pathglob <pat>?... ?-context <ns>? ?-conflicts 0|1? ?<binglob>...?' |
||||
|
||||
- `-return json` - machine-readable; the only form worth parsing. `table` |
||||
(default) is the human ANSI table; `text` is a plain-ASCII fixed-key |
||||
layout; `dict` returns a Tcl dict. All three non-table forms are |
||||
ANSI-free regardless of other options. |
||||
- `<binglob>...` - executable-name glob filter (default `*` = all). Pass |
||||
a bare name (`tclsh`) or glob (`tclsh*`, `dir`) to narrow to the |
||||
executables you care about. ALWAYS filter by name unless you genuinely |
||||
need the whole PATH (the unfiltered scan returns every executable on |
||||
PATH - thousands). |
||||
- `-pathglob <pat>...` - filter PATH entries by directory (case-insensitive |
||||
glob on the directory path). Default `*` = all PATH entries. Use to |
||||
narrow "which scoop shims provide X" etc. |
||||
- `-context <namespace>` - the namespace whose commands are checked for |
||||
conflicts. Default empty = the caller's namespace. PASS THIS when |
||||
invoked through a wrapper/one-liner (`src script -e`) to make the |
||||
conflict verdict stable and meaningful; the default-caller behaviour |
||||
is for interactive use. `::` checks the global namespace. |
||||
- `-conflicts 0|1` - default 1 (compute Tcl conflicts). Set 0 to skip for |
||||
a small perf win when you only care about overshadowing; the conflict |
||||
fields are then empty. |
||||
|
||||
Load noise ("src mode: registered ...") goes to stderr; read stdout only |
||||
(append `2>/dev/null` in bash). Prefer the Bash tool over the PowerShell |
||||
tool (attached consoles flip punkshell's terminal detection). |
||||
|
||||
## Output structure (JSON) |
||||
|
||||
{ |
||||
"summary": { |
||||
"context": "::", "is_windows": 1, "separator": ";", |
||||
"path_entries": 130, # total PATH entries scanned |
||||
"shown_entries": 6, # entries with matching executables |
||||
"executable_total": 6, # matching executables across shown entries |
||||
"overshadowed_total": 5, # how many are shadowed by an earlier entry |
||||
"conflict_total": 0 # how many clash with a Tcl command |
||||
}, |
||||
"entries": [{ |
||||
"idx": 0, # PATH order index (0 = first on PATH) |
||||
"path": "C:\\Program Files\\Git\\mingw64\\bin", |
||||
"normalised": "...", "is_directory": 1, |
||||
"is_duplicate": 0, "duplicate_of": -1, # same dir appearing again on PATH |
||||
"exe_count": 55, "overshadowed_count": 0, |
||||
"executables": [{ |
||||
"name": "tclsh.exe", |
||||
"overshadowed": 0, # 1 = an earlier PATH entry also has this exe |
||||
"overshadowed_by": -1, # entry IDX (into entries[]) that shadows it |
||||
"tcl_conflicts": [] # list of {command, match} |
||||
}] |
||||
}, ...] |
||||
} |
||||
|
||||
## Reading the verdict |
||||
|
||||
- **Which copy wins:** the first entry (lowest `idx`) whose executable has |
||||
`overshadowed: 0` - that is what a bare command name resolves to. All |
||||
later copies of the same name have `overshadowed: 1` and |
||||
`overshadowed_by` = the winning entry's `idx`. |
||||
- **Tcl-command clash:** `tcl_conflicts` lists `{command, match}` pairs |
||||
where `command` is the resolved Tcl command name (namespace origin) and |
||||
`match` is `exact` (case-identical) or `nocase` (case-differing). An empty |
||||
list means the PATH executable does not clash with any resolvable Tcl |
||||
command in `-context`. |
||||
- **`shown_entries` < `path_entries`** means the binglob/pathglob filtered |
||||
some entries out; that is expected when you pass a name. |
||||
- **`overshadowed_by` is an entry idx, not an exe name** - cross-reference |
||||
it against `entries[].idx` to name the shadowing copy. |
||||
|
||||
## Caveats |
||||
|
||||
- This is PATH-resolution and Tcl-command-clash only. It is NOT a general |
||||
"what is installed" / `which` replacement and does not report |
||||
non-PATH tools, shell builtins, or aliases. |
||||
- The conflict verdict depends on `-context` (which namespace's commands |
||||
are resolvable). The default (caller's namespace) is wrong for a |
||||
wrapper/one-liner invocation - pass `-context ::` or the target |
||||
namespace explicitly. |
||||
- `is_duplicate`/`duplicate_of` refers to a PATH DIRECTORY appearing |
||||
more than once (the later copies have no own executable list); it is |
||||
not the same as `overshadowed` (an executable name repeated across |
||||
different directories). |
||||
- Full (unfiltered) output is large - thousands of executables across |
||||
the whole PATH. Filter by name unless you need the whole picture. |
||||
- From Tcl code, `punk::path -return dict` returns the same structure as |
||||
a dict; `punk::path -return json` round-trips to the same data (decode |
||||
via tcllib json and recompare - the G-173 acceptance criterion). |
||||
@ -0,0 +1,122 @@
|
||||
--- |
||||
name: punkpath |
||||
description: "Use to resolve which PATH executable a bare command name actually runs (and what shadows it), and whether a PATH executable clashes with a Tcl command - the two questions agents guess wrong when debugging test failures or 'invalid command name X' errors. Cost: one ~0.7s side-effect-free punkshell invocation. Returns JSON via 'punk91 src script -e {punk::path -return json <name>}' listing PATH entries whose executables match the name, each with overshadowed/overshadowed_by (entry idx) and tcl_conflicts (command:match=exact|nocase) fields. Not a general 'what is installed' tool - PATH shadowing and Tcl-command clash only." |
||||
--- |
||||
|
||||
# punkpath |
||||
|
||||
PATH-executable resolution and Tcl-command clash diagnosis for the punkshell |
||||
repo - the "which tclsh will I actually get, and does X.exe shadow a Tcl |
||||
command?" answer that agents guess wrong. Asks the live interpreter via |
||||
`punk::path -return json`, so the verdict is the OS PATH-resolution truth |
||||
(first non-shadowed entry wins), not a guess from `which`/`where` or a |
||||
single-env-var read. |
||||
|
||||
## When to use |
||||
|
||||
- A test run fails in a way that smells like the wrong interpreter |
||||
(spurious Tcl-version failures, msys path semantics). The tcl-runtests |
||||
skill warns that bare `tclsh` from a Bash tool often resolves to the |
||||
MSYS/Git-for-Windows tclsh; run this to get the machine-readable verdict |
||||
on which `tclsh.exe` wins and what it shadows, instead of guessing. |
||||
- An "invalid command name X" error where X might be an `X.exe` on PATH |
||||
clashing with a Tcl command (`dir`, `sort`, `find`, `clip` are classic). |
||||
The `tcl_conflicts` field reports the resolved Tcl command and the |
||||
exact|nocase match. |
||||
- Before asserting an external tool is available, or which copy of a |
||||
duplicate (e.g. several `tclsh.exe`) the shell will execute. |
||||
|
||||
## Command |
||||
|
||||
Run from the repo root (`punk91` lives in `bin/`, so `bin/punk91` from the |
||||
Bash tool). `punk91` embeds Tcl 9.1; `punk905` (Tcl 9.0) or `punksys` |
||||
(Tcl 8.6) take the same one-liner. Cost: ~0.7s filtered, ~0.7s full PATH, |
||||
no side effects (read-only). |
||||
|
||||
bin/punk91 src script -e 'punk::path -return json ?-pathglob <pat>?... ?-context <ns>? ?-conflicts 0|1? ?<binglob>...?' |
||||
|
||||
- `-return json` - machine-readable; the only form worth parsing. `table` |
||||
(default) is the human ANSI table; `text` is a plain-ASCII fixed-key |
||||
layout; `dict` returns a Tcl dict. All three non-table forms are |
||||
ANSI-free regardless of other options. |
||||
- `<binglob>...` - executable-name glob filter (default `*` = all). Pass |
||||
a bare name (`tclsh`) or glob (`tclsh*`, `dir`) to narrow to the |
||||
executables you care about. ALWAYS filter by name unless you genuinely |
||||
need the whole PATH (the unfiltered scan returns every executable on |
||||
PATH - thousands). |
||||
- `-pathglob <pat>...` - filter PATH entries by directory (case-insensitive |
||||
glob on the directory path). Default `*` = all PATH entries. Use to |
||||
narrow "which scoop shims provide X" etc. |
||||
- `-context <namespace>` - the namespace whose commands are checked for |
||||
conflicts. Default empty = the caller's namespace. PASS THIS when |
||||
invoked through a wrapper/one-liner (`src script -e`) to make the |
||||
conflict verdict stable and meaningful; the default-caller behaviour |
||||
is for interactive use. `::` checks the global namespace. |
||||
- `-conflicts 0|1` - default 1 (compute Tcl conflicts). Set 0 to skip for |
||||
a small perf win when you only care about overshadowing; the conflict |
||||
fields are then empty. |
||||
|
||||
Load noise ("src mode: registered ...") goes to stderr; read stdout only |
||||
(append `2>/dev/null` in bash). Prefer the Bash tool over the PowerShell |
||||
tool (attached consoles flip punkshell's terminal detection). |
||||
|
||||
## Output structure (JSON) |
||||
|
||||
{ |
||||
"summary": { |
||||
"context": "::", "is_windows": 1, "separator": ";", |
||||
"path_entries": 130, # total PATH entries scanned |
||||
"shown_entries": 6, # entries with matching executables |
||||
"executable_total": 6, # matching executables across shown entries |
||||
"overshadowed_total": 5, # how many are shadowed by an earlier entry |
||||
"conflict_total": 0 # how many clash with a Tcl command |
||||
}, |
||||
"entries": [{ |
||||
"idx": 0, # PATH order index (0 = first on PATH) |
||||
"path": "C:\\Program Files\\Git\\mingw64\\bin", |
||||
"normalised": "...", "is_directory": 1, |
||||
"is_duplicate": 0, "duplicate_of": -1, # same dir appearing again on PATH |
||||
"exe_count": 55, "overshadowed_count": 0, |
||||
"executables": [{ |
||||
"name": "tclsh.exe", |
||||
"overshadowed": 0, # 1 = an earlier PATH entry also has this exe |
||||
"overshadowed_by": -1, # entry IDX (into entries[]) that shadows it |
||||
"tcl_conflicts": [] # list of {command, match} |
||||
}] |
||||
}, ...] |
||||
} |
||||
|
||||
## Reading the verdict |
||||
|
||||
- **Which copy wins:** the first entry (lowest `idx`) whose executable has |
||||
`overshadowed: 0` - that is what a bare command name resolves to. All |
||||
later copies of the same name have `overshadowed: 1` and |
||||
`overshadowed_by` = the winning entry's `idx`. |
||||
- **Tcl-command clash:** `tcl_conflicts` lists `{command, match}` pairs |
||||
where `command` is the resolved Tcl command name (namespace origin) and |
||||
`match` is `exact` (case-identical) or `nocase` (case-differing). An empty |
||||
list means the PATH executable does not clash with any resolvable Tcl |
||||
command in `-context`. |
||||
- **`shown_entries` < `path_entries`** means the binglob/pathglob filtered |
||||
some entries out; that is expected when you pass a name. |
||||
- **`overshadowed_by` is an entry idx, not an exe name** - cross-reference |
||||
it against `entries[].idx` to name the shadowing copy. |
||||
|
||||
## Caveats |
||||
|
||||
- This is PATH-resolution and Tcl-command-clash only. It is NOT a general |
||||
"what is installed" / `which` replacement and does not report |
||||
non-PATH tools, shell builtins, or aliases. |
||||
- The conflict verdict depends on `-context` (which namespace's commands |
||||
are resolvable). The default (caller's namespace) is wrong for a |
||||
wrapper/one-liner invocation - pass `-context ::` or the target |
||||
namespace explicitly. |
||||
- `is_duplicate`/`duplicate_of` refers to a PATH DIRECTORY appearing |
||||
more than once (the later copies have no own executable list); it is |
||||
not the same as `overshadowed` (an executable name repeated across |
||||
different directories). |
||||
- Full (unfiltered) output is large - thousands of executables across |
||||
the whole PATH. Filter by name unless you need the whole picture. |
||||
- From Tcl code, `punk::path -return dict` returns the same structure as |
||||
a dict; `punk::path -return json` round-trips to the same data (decode |
||||
via tcllib json and recompare - the G-173 acceptance criterion). |
||||
Loading…
Reference in new issue