Tree:
43f009ed80
master
v0.1a
${ noResults }
124 Commits (43f009ed809aba6c2c8ea6246609116bf9b3662e)
| Author | SHA1 | Message | Date |
|---|---|---|---|
|
|
43f009ed80 |
G-083 increment 2: punk::args optionconflict parse-time enforcement (0.20.0)
The -conflicts and -parsekeymode error vocabulary declared at define time
(0.19.0) is now enforced at parse. A new optionconflict failure class joins the
PUNKARGS VALIDATION errorcode vocabulary, mirroring optionmissing's shape:
{optionconflict <arg_a> <arg_b> received <receivednames>} - it names both
offending received arguments, for both per-arg -conflicts violations (any
pair, cross-group) and -parsekeymode error group co-occurrence (distinct
members of a shared-parsekey group).
The check runs in a single post-resolution site in get_dict_form (after the
optionmissing/valuemissing block), so the ordinary option path and the mash
(short-flag bundling) path share it - both raise identically. Checked against
RECEIVED arguments only (defaults never conflict), after prefix/abbreviation
resolution, on optset identity (a new optsets_received tracker for options,
since flagsreceived collapses shared-parsekey members onto one api_opt). Runs
unconditionally - a received conflict is a hard contradiction in any mode, not
end-of-input exhaustion, so parse_status_classify maps optionconflict to invalid
(not incomplete) and the candidacy/viability probe reports it.
Define-time check added: a group marked -parsekeymode error must also declare a
non-empty -parsekey (the strict mode only applies to a shared-parsekey group).
relations.test extended with 7 enforcement pins (raise cases for -conflicts
and -parsekeymode error, defaults-never-conflict, cross-group conflicts,
one-received-ok, override-legacy last-wins, parse_status invalid). buildversion
0.19.0 -> 0.20.0.
Bug found and fixed during the increment: the group-co-occurrence dedup check
initially used `ni` (not-in) where `in` was meant - `ni` returns true on an
empty list, so it skipped every member and the check never fired. Corrected
to `in`.
Legacy untouched by default: -parsekeymode override is the default and absent
-conflicts means no check runs, so the full existing suite (including the
pinned parsekey_repeat_ordering last-wins / prepend-defaults idiom) passes
unchanged.
Verification: full punk/args suite via canonical tclsh90s - 363 total / 360
passed / 3 skipped (punkargsKnownBug) / 0 failed; punk/ns suite 125/125 clean.
goals_lint clean. No punkproject.toml bump (module API addition, not shell-
level user-visible behaviour yet - the lsearch moduledoc adoption that ships
user-visible behaviour lands in increment 3).
Assisted-by: harness=pi; primary-model=huggingface/zai-org/GLM-5.2; api-location=huggingface.co
|
3 days ago |
|
|
055f4bbf2f |
G-083 increment 1: punk::args argument-relations define-time vocabulary (0.19.0)
Spec compiler (resolve) accepts and stores the new relation keys: - per-argument -conflicts <list>: parsekeys or flag names that must not be RECEIVED together with this argument; checked against received args only at parse time (defaults never conflict) - parse-time optionconflict enforcement lands in a later G-083 increment. - @opts-level -parsekeymode override|error: per named OPT_GROUPS group; error = distinct-member co-occurrence within a shared-parsekey group raises optionconflict at parse; override = legacy last-wins, the default. Both keys are cross-validated at resolve: -conflicts targets must name a defined argname or declared -parsekey; -parsekeymode requires -group and a value of override|error. Define-time integrity hole closed: a -parsekey colliding with a distinct defined argument's name (one not sharing that -parsekey) is now a resolve error instead of silently forming an implicit shared-key group (parsekey_collides_with_defined_optname_GAP flipped in parsekey.test to a define-time error pin, plus redundant-self-name and deliberate-shared-group guards). Design settled (recorded in the goal detail): -parsekeymode is per named group (OPT_GROUPS entry, keyed by the @opts line's -group), not form-wide. Rationale: lsearch uses per-arg -conflicts only (partial conflicts, groups stay default override); clock clicks uses -parsekeymode error on its single named group (full pairwise exclusivity). Unnamed shared-parsekey groups default override. Legacy untouched by default: -parsekeymode override is the default and absent -conflicts means no check runs; the pinned parsekey_repeat_ordering last-wins / prepend-defaults idiom and the full existing suite pass unchanged. New testsuite relations.test pins the define-time vocabulary (7 tests, matching the longopts.test/mashopts.test error-pin style). buildversion 0.18.0 -> 0.19.0. Verification: full punk/args suite via canonical tclsh90s - 356 total / 353 passed / 3 skipped (punkargsKnownBug) / 0 failed. goals_lint clean. No punkproject.toml bump (define-time only; no shell-level user-visible behaviour yet - the module change, not the shell product). Assisted-by: harness=pi; primary-model=huggingface/zai-org/GLM-5.2; api-location=huggingface.co |
3 days ago |
|
|
b0c92567a3 |
G-151 achieved: punk::args::parse_report landing report + ansistring TRUNCATE (args 0.18.0, ansi 0.2.0)
User-directed activation and implementation in one arc (proposed -> active at
the user's word with the activation-freshness overlap survey recorded, ->
achieved + archived on acceptance).
punk::args 0.18.0 - new parse_report: the annotated SUCCESS render (the
arg_error usage table's success-side sibling). One row per value-holding
argument (received, or -default in effect) in declaration-section order
(leaders, opts, values), columns Argument | Source | Value; Source carries
received / received xN / default (the plain-mode twin of the colour marking:
CLR(check)/CLR(parsekey_hint)); absent optionals get no row. Entry forms per
acceptance: a punk::args::parse result dict, or '<arglist> withid <id>' (the
parse is performed first - a rejected line raises the same validation error
parse would; errorcode parity pinned). Returns: table (bordered textblock
block, default), tableobject, string (plain lines; also the degraded
no-textblock path), dict (machine form - never elided). The canonical
demonstration pinned: {build punk95 -confirm 0} lands
'args (received x2) = -confirm 0' - a flag-like word consumed as a VALUE
visibly attributed to its consuming argument (the make.tcl dry-run
'kitname = punk91 -confirm 0' class from the G-143 sessions).
Display elision is type-aware, deterministic, always marked: strings
single-line-ized (ansistring VIEW -lf 1 -vt 1 -sp 0 - controls and embedded
ANSI render visibly so a value cannot disturb the table, real spaces stay
real) then grapheme-capped with '...' + ' (len N)'; -multiple/-type list
values element-capped '(+N more)'; -type dict values pair-capped
'(+N pairs)'. Width cascade per the G-149 plumbing precedent: caller
-valuewidth > new @cmd directive key -reportvaluewidth (documented in
define -help) > built-in 48; 0 = no cap; never console-derived (the G-007
emit-then-query lesson). Row data rides the G-049
private::parse_status_build structure - no second status assembler;
display-level bridging recovers the value-in-effect across the parse
result's storage-key folds (-parsekey renames, aliased optionsets'
last-|-member finalopts fold) so received aliased args keep their row -
engine-level rationalization recorded as a G-084 follow-on disposition.
The registered two-form definition (parsed/withid) follows parse_status's
structure - per-form @leaders first, then the shared @opts via a re-widened
@form selection (the resolver rejects leaders declared after a form's
options).
punk::ansi 0.2.0 - new ansistring TRUNCATE ?-ellipsis marker? string
maxgraphemes (design lean 4: the ANSI/grapheme-safe truncate primitive
homes in ansistring beside RANGE/VIEW): fits => byte-identical passthrough
(trailing and non-SGR codes included); truncation => RANGE-extracted prefix
(merged SGR re-application per the contract documented at 0.1.4) + marker
totalling exactly maxgraphemes, with an SGR reset appended before the
marker when the prefix carries codes; the marker is charged against the
budget and itself truncated when it alone meets/exceeds it; maxgraphemes 0
=> empty string. Grapheme-count based (column-aware variant a recorded
follow-on). Strict option handling (deliberately unlike VIEW's pinned
silent tolerance). Ensemble export + PUNKARGS argdoc + doctools comment.
Tests: new args/parsereport.test (13 - canonical attribution, entry
parity, dict shape/row order/row policy, solo+multi xN multiplicity,
per-type elision markers, dict-never-elided, width cascade,
single-line-ization, alias bridging, bordered/tableobject renders, failure
parity, bad calls, own-definition render); ansi/ansistring.test +2
TRUNCATE pins (budget/passthrough/errors; ANSI-reset + CJK +
combining-cluster safety). Full punk/args subtree 331 passed / 3
pre-existing skips / 0 failed and punk/ansi subtree 73/73 - each on native
tclsh90 (9.0.3) AND tclsh87; failure-side rendering unchanged per
acceptance. Minted modules/punk/args-0.18.0.tm + ansi-0.2.0.tm via
make.tcl modules; bootsupport/vfscommon promotion left to the next cycle -
make.tcl keeps its interim one-line report (and its 4-copy 'no annotated
success render yet' comment) until the promotion-gated follow-on lands.
Goals: G-151 entry moved to GOALS-archive.md, detail file to goals/archive/
with verification evidence and 5 Follow-on lines (make.tcl interim-report
retirement open; arg_error value-truncation via the same helpers open;
storage-key rationalization => goal G-084; column-aware TRUNCATE open;
word-oriented inverse view open). Activation-survey Related: lines recorded
(G-166, G-084, G-167 back-pointer); reference sweep updated G-170
(sequencing lean honoured - its dry-run arm consumes this render), G-167
archive marker, G-084 back-pointer note. src/tests/modules AGENTS.md
punk/args + punk/ansi bullets extended. goals_lint clean (83 active / 87
archived).
Claude-Session: https://claude.ai/code/session_0156PuejSCGjgeGb7jiABrDU
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
5 days ago |
|
|
7cdf5b2323 |
G-149 achieved: punk::args configurable multi-form synopsis hint labels (punk::args 0.17.0)
The per-form hint labels rendered beside a multi-form definition's synopsis lines in the usage/arg_error table (hard-coded ' i -form N ...' previously) are now a template substituted per form: %formindex% is replaced with the form's 0-based ordinal, %formname% with its name, and an empty template suppresses the labels entirely (the cell keeps just the Synopsis: label, as single-form renders always have). Both acceptance arms landed. Definition side: new '@cmd -formhint <template>' key - rides the existing arbitrary-key cmd_info merge (no resolver change), round-trips through resolved_def, not display -deferred; documented in the define -help directive-options. Caller side: new -formhint option on arg_error (manual parser + PUNKARGS block) pulled into usage via its existing resolved_def opts pull; supplied-empty (suppress) is distinct from not-supplied (the option declares no -default, so an unsupplied usage call passes nothing through). Precedence: caller > definition > built-in default, whose template substitutes to the exact prior bytes. Motivation (G-143 origin): script-level (script) ids - make.tcl's - are unreachable from any repl, so the repl-oriented 'i' hint was not actionable there. Scope decisions pinned: single-form renders never carry hint labels; the -return string renderer has no hint column and is unchanged. Byte-identity for unconfigured definitions proven by pre/post capture diff of 'punk::args::usage ::punk::args::parse' (identical bytes, through the usage pass-through path). Tests: new formhint.test (9 tests - default labels, directive/caller/suppression matrix, parse -error path, single-form + string-renderer scope); full punk/args subtree 302/0-fail on BOTH tclsh90 9.0.3 and the punk86 kit (8.6); punk/ns subtree 115/115 (cmdhelp consumer). make.tcl help untouched until promotion (maketclhelp.test still pins the bootsupport hint). Goals: G-149 activated at user direction then flipped achieved 2026-08-05 + archived (index record newest-first, detail file to goals/archive with Progress evidence and 1 follow-on: make.tcl adoption after a bootsupport promotion => open). Activation-freshness survey recorded the G-167 relationship (same renderer surface - composition note both sides); reference sweep updated G-151/G-167 mentions; goals_lint clean, no orphaned xref pairs. punkshell 0.55.0 + CHANGELOG. Bootsupport/vfscommon snapshots unchanged until promotion + bake. Claude-Session: https://claude.ai/code/session_01QgaxV27VZkmEec7oNbEVFc Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
6 days ago |
|
|
69927531a4 |
G-073 achieved: punk::args unavailable choices (-choiceunavailable) + G-166 drafted (punk::args 0.16.0, tclcore moduledoc 0.4.0, punk::ns 0.9.3)
New per-argument key -choiceunavailable <list>: names recognised but not
available in the current runtime/context. Entries display among the
choices under a dedicated "Unavailable (recognised, not selectable
here)" group (one rendering-side injection - both renderers,
choicelabels notes, choiceinfo markers, trie prefix marking and
value-in-effect exclusion all inherited) and join the prefix pools;
synopsis literals and goodchoice marking never include them. Resolve
-time validation: no collision with choices/alias names/reservelist,
-default may not be unavailable, requires -choices/-choicegroups.
choiceword_match gains an optional 8th argument and an 'unavailable'
result key (matched stays 0 - matched-only consumers unaffected):
exact, nocase and unique-prefix landings carry the name as canonical; a
prefix shared with an available choice stays plain-ambiguous.
Validation rejects a landing with the tailored PUNKARGS VALIDATION
{choiceunavailable <name> choices <list>} error (-badarg/-badval;
private::unavailable_choice_msg names the supplied word, the resolved
entry, its choicelabel note and the available values; shared by final
validation and both G-082 overflow raise sites via rejection kind
'unavailable' from the allocation screen). Ambiguity messages annotate
unavailable longer matches '(recognised but unavailable)';
-choicerestricted 0 keeps full passthrough.
tclcore 'string is' adoption: curated forward list {dict} ('unicode'
deliberately excluded) diffed against the define-time harvest; labels
and per-class virtual ids extend to unavailable classes. On Tcl 8.6:
dict displays with its "(class not present in Tcl 8.6)" note,
'string is dict' rejects informatively, 'string is di' is ambiguous
(deliberately stricter than real 8.6 - recorded as a user-sanctioned
parity exemption; full words parity-true), and 'i string is dict'
documents via the virtual id. punk::ns cmd_traverse passes the key at
both resolver sites (doc-walk parity; the choice-traverse comment now
documents the choice-resolution vs doc-addressing axes split). tclcore
moduledoc requires punk::args 0.16.0-.
Tests: new choiceunavailable.test (10 tests); usagemarking.test gains
the goodchoice-exclusion pin; tclcoreparity.test gains forward-class
adoption invariants and the sanctioned 'di' strictness exemption, with
the version_notes pin deliberately flipped (dict's label now renders on
every runtime). Green: the three suites 37/37 on native Tcl 8.6.10
(luck runtime), 8.7a6 and 9.0.3; punk/args subtree 293/290/3 skips/0
fail on 9.0.3 AND 8.7; modules/punk sweep green except the three
documented pre-existing box-baseline failures (grepstr x2, nslist x1);
ns cmdhelp/corp 58/58 after the comment clarification.
Goals: G-073 flipped achieved 2026-08-05 + archived (index record
moved, detail file to goals/archive with Progress/verification and 3
follow-ons). G-166 drafted [proposed] at user direction (approved
wording): cmdinfo availability key + cmdhelp marking + tclcore leading
note + prefix-landing decision; the enacted G-073 follow-on flipped
=> goal G-166, the G-055 pattern follow-on => goal G-055 with a Notes
pointer added there. goals_lint clean. punkshell 0.54.0 + CHANGELOG.
Bootsupport/vfscommon snapshots unchanged until promotion + bake.
Claude-Session: https://claude.ai/code/session_01QgaxV27VZkmEec7oNbEVFc
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
6 days ago |
|
|
d2094364a3 |
G-082 follow-on landed: required typed value/leader misreport -> pointed typemismatch (punk::args 0.15.2)
A REQUIRED typed value or leader whose present word fails the basic-type allocation screen (int/double/bool/number/dict) now reports the pointed typemismatch naming the word and argument (-badarg/-badval, same shape as the G-082 overflow-site selection) instead of the generic missingrequiredvalue/missingrequiredleader shortfall. The in-loop required-arg raise sites consult the rejection record returned by get_dict_can_assign_value; the leaders-loop edit mirrors the values loop per the MAINTENANCE contract. Unchanged by design: end-of-input shortages (valuemissing/count classes), literal-typed members, multi-member clause partials (no rejection record - conservatism preserved), and required-arg choice words (never screened - G-071 asymmetry, choiceviolation already pointed). parse_status: the shape now classifies invalid/typemismatch (the formstatus viability verdict was already invalid; one probe re-parse saved); argdoc status-key note updated. Pins deliberately flipped: parsestatus.test (renamed parsestatus_typed_value_screen_typemismatch), formviability.test (single-form top-status/formstatus split demo re-anchored on a required-option shape), punk/ns cmdhelp.test message match. New errorselection.test coverage: required value + leader typemismatch pins plus unchanged-shape guards. Verified tcl 9.0.3: punk/args subtree 280 total / 277 passed / 3 intended skips / 0 failed; punk/ns only the pre-existing nslist(1) box-baseline failure (stash-verified unrelated). tcl 8.7: touched args suites 38/38, cmdhelp 45/45. Follow-on disposition flipped => landed in goals/archive/G-082-punkargs-error-selection.md (goals_lint clean; ledger 23 open / 20 goal / 15 landed / 2 declined). punkshell 0.53.1 + CHANGELOG entry. Bootsupport/vfscommon args copies stay 0.15.1 until the next promotion + bake. Claude-Session: https://claude.ai/code/session_01QgaxV27VZkmEec7oNbEVFc Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
6 days ago |
|
|
1605b97b37 |
G-164 achieved 2026-08-04: punk::args 0.15.1 viability probe alternative-allocation re-probe (punkshell 0.51.1)
Assisted-by: harness=opencode; primary-model=openrouter/moonshotai/kimi-k3; api-location=openrouter.ai |
6 days ago |
|
|
7ad110dde6 |
punk::args 0.15.0: @values -flagvalues - unmatched dash-led words seat as trailing values (G-150 follow-on)
- a @values section may declare -flagvalues 1: an unmatched dash-led word in option position is consumed as a trailing value instead of raising invalidoption (declared options still match first; the '--' end-of-options marker is unaffected; off by default) - VAL_FLAGVALUES on the form dict (template default false; @values compiler key, boolean-validated at resolve time) short-circuits the unmatched-dash-word fallback in the parse engine - motivation: '--help'-style forms robustly swallowing ignored trailing words of any shape - previously such a word seated as a value only positionally (at end-of-input via the valmin reservation, or within a bounded valmax) and errored 'Unexpected option' otherwise ('{--help -t foo}' on the unconstrained shape) - in-tree consumer: punk::auto_exec::hash's help form (next commit); documented in the module header notes - tests: new flagvalues.test (9 tests - seating matrix, declared-option precedence, off-by-default contrast, optionmissing after value seating, key validation); args subtree 271/271 green Assisted-by: harness=opencode; primary-model=openrouter/moonshotai/kimi-k3; api-location=openrouter.ai |
6 days ago |
|
|
f4e23418d5 |
G-152 punk::args 0.14.0: sound suffix-viability verdicts (achieved + archived)
Multiform per-form failure statuses (formstatus records, noformmatch errorcode
classes + -formerrors) are now sound suffix-viability verdicts: 'incomplete'
(viable) iff every supplied word was validly consumed as a prefix of the form
and the failure is pure exhaustion at end-of-input; anything already supplied
contradicting the form reports 'invalid'. Mechanism: viability-probe mode on
private::get_dict_form suppressing only the position-guarded pure-exhaustion
raises (count min-shortfalls, missing-required checks, adhoc option value at
end) while final validation of the consumed words stands as the soundness
backstop; multiform candidacy and parse_status's single-form formstatus record
confirm each classify-'incomplete' failure with one probe re-parse. Rendered
noformmatch form lines marked '(viable - needs more arguments)'/'(not viable)'
after the stable "form '<fid>':" anchor. Consumer contract documented in the
parse ('Multiform failure contract') and parse_status argdocs. Documented
conservatism: input ending inside a multi-member type clause reports invalid.
New testsuite formviability.test (acceptance scenarios, option position
guards, single-form record soundness, clause conservatism, message marking);
forms.test verdict pins deliberately updated (ms/idle incomplete->invalid for
type-screen rejections). punkshell 0.41.3 (patch: refined multiform error
classification/reporting at the shell surface).
Goal G-152 activated (user-directed) and flipped achieved 2026-08-02 with
acceptance verified via runtests (args subtree green; full-suite parity with
stashed baseline); entry archived to GOALS-archive.md, detail file to
goals/archive/ with verification evidence; consumer pointers pushed to
G-044/G-150 notes.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
1 week ago |
|
|
543dd1df40 |
G-144 achieved: punk::args auto-synopsis @cmd -name fallback for (script) ids
Auto-generated synopses for (script)-prefixed constructed definition ids now lead with the declared @cmd -name (the invocation name - e.g 'make.tcl modules' for (script)::punkboot::modules) instead of the raw id, across punk::args::synopsis full/summary renders and the usage/arg_error synopsis sections that funnel through them (punk::args 0.12.7 -> 0.13.0). The fallback is gated on the (script) prefix only (user-confirmed narrowing): (autodef) ids are excluded - their id-minus-tag IS the invocation (arg_error's existing tag strip surfaces it) while their @cmd -name is a display label ('destroy', 'Object: ::x'); (shared)/(package)/(default)/(widgetcommand) doc ids declare no invocation-style -name today and render the id as before. Real command ids render byte-identical (full args testsuite passes with no pin updates). Six new synopsis.test pins: (script) full/summary/multiform/ surfaces, no-name constructed id, autodef unchanged, real-id byte-identical. Goal tiers: index entry archived to GOALS-archive.md, detail file moved to goals/archive/ (G-143's pending-tense Related line rewritten to reflect achievement + follow-through pointer: make.tcl's @form -synopsis overrides are now optional, retirement under G-143 or a follow-on edit). Docs: @form -synopsis directive known-case text, synopsis -help, src/modules/AGENTS.md ergonomics bullet. Project 0.39.5 -> 0.39.6 (patch: latent capability, no shipped definition renders differently today). Bootsupport refresh (make.tcl modules + bootsupport): snapshot gains args-0.13.0.tm and picks up two lagging source syncs - mix/commandset::layout 0.2.0 -> 0.3.0, mix/commandset::project 0.4.0 -> 0.4.1, and the shellfilter 0.2.4 G-145 comment; superseded copies pruned. Assisted-by: harness=opencode; primary-model=openrouter/moonshotai/kimi-k3; api-location=openrouter.ai |
1 week ago |
|
|
f5deb4d1b8 |
G-118 item 10: launch subcommand family docs as punk::args definitions (moduledoc punkexe)
New punk::args::moduledoc::punkexe 0.1.0: (script)::punkexe dispatch definition (package modes, subcommand enumeration, default reclassification) + (script)::punkexe::tclsh full contract (stock arg-form parity incl the deliberate no -e boundary (G-077), lib: refusal, piperepl ::tclsh state array + env gates, intended divergences recorded per item decisions 2/6/8) + summary definitions for script/shell/punk/shellspy. G-032-compatible: the launcher help/parse wiring renders from these ids later. punk::args 0.12.7: update_definitions handles tag-prefixed id namespaces first-class - namespace_docpackages consulted with the tagged key (usage/ real_id on registered-but-unloaded (script)::* ids no longer no-such-id), generic tag strip for the real-namespace probes, unqualified-ns warning no longer fires for tag ids. args/ns/repl suites 352 pass 0 fail. punk::repl 0.5.3: code-interp setup catch-requires the punkexe moduledoc beside tclcore (both sites) so the docs are queryable in any punk shell. ARCHITECTURE.md: tclsh subcommand bullet in the boot/launch chain (architecture_lint clean). punkproject 0.20.1 + CHANGELOG. Verified: fresh-interp usage-first render (real_id path); rebuilt punk902z kit self-carries 0.1.0 (5298-char tclsh render); piped punk session renders (script)::punkexe with no manual require. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
2 weeks ago |
|
|
75cffe21f3 |
punk::args 0.12.6 + punk::ns 0.9.0: LLM-oriented usage output; tcl-whatis agent skill
punk::ns 0.9.0: cmdhelp (i) gains -return text - plain-text argument
documentation for machine/LLM consumption: no ANSI, no table layout, the
argument section of every command form rendered in one output under a common
header ('i -return text after' shows all six forms), G-041 form selection
still honoured when argument words are supplied, no advisory-parse error
preamble (-return dict remains the parse-status surface). Implementation
delegates resolution to the -return dict recursion and renders per-form via
the string renderer.
punk::args 0.12.6 (user direction; string-form layout explicitly not frozen -
no external consumers yet):
- arg_error renders the error message + per-form match detail exactly once,
BELOW the usage display (was above and below); bottom append suppressed for
empty messages.
- string renderer argument rows are single-line
'name TYPE:type(constraints) ?DEFAULT:'val'? ?MULTI:yes?' - type
constraints parenthesize onto the base type instead of line-breaking
mid-row; empty DEFAULT/MULTI labels and whitespace-only help blocks omitted.
- choices render as markdown-subset bullets '- `choice` - label' with label
continuations at a fixed deeper indent - choice names are now
machine-distinguishable from label text without ANSI. Structural contract:
column-0 lines bearing TYPE: are argument rows, indented lines are
documentation, backticked bullets are choices. Table cells unchanged.
New scriptlib/developer/whatis.tcl (runtime command introspection for
agents): resolved name, subcommand-chain resolution via punk::ns::cmdinfo
('whatis string is'), kind, providing package + loaded version, origin file,
proc definition file:line, punk::args synopsis; -body appends the runtime
body with file-relative line numbers, -doc the full plain-text argdoc via
cmdhelp -return text (with fallback for older punk::ns). Backing the
cross-framework tcl-whatis agent skill: canonical .agents/skills/tcl-whatis/
(Agent Skills standard - pi/OpenCode/Codex) with byte-identical copy in
.claude/skills/ for Claude Code; .gitignore gains !.claude/skills/ with the
fossil ignore-glob comment + exception-set docs updated per the dual-VCS
contract (fossil adds staged). Root AGENTS.md: .agents/skills index entry,
whatis pointer in Repo-wide Notes, scriptlib/developer example.
Tests: new pins cmdhelp_return_text_all_forms/_argword_form_selection/
_single_form_plain_marker (cmdhelp.test), rendering_stringmode_singleline_argrows
+ rendering_stringmode_choice_bullets (rendering.test); deliberate-change pin
updates: errorselection.test message matches gained leading * and cmdhelp.test
message pins sample the last line (message placement). Full source-tree suite
963/979 pass, sole failure the pre-existing exec-14.3 baseline; make.tcl
modules clean.
Project version 0.12.42 -> 0.13.0 with CHANGELOG.md entry.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
3 weeks ago |
|
|
c2574a7050 |
punk::args 0.12.5 + punk::ns 0.8.1: parse -cache overhaul, synopsis notation, eg resolution
parse -cache overhaul:
- VALIDATION trap's parse_cache write now explicitly gated on -cache (formerly
unconditional but landing in a discarded proc-local for -cache 0 by scoping
accident - 'variable parse_cache' only ran on the -cache 1 branch)
- cached validation errors stored as per {errorstyle callertext} render
variants under a {arglist definition form} main key (-caller dropped from the
main key - results don't depend on it); a missing variant falls through to a
fresh render. Previously the first caller's errorstyle and %caller%
attribution were baked in and replayed verbatim to later callers.
- @dynamic definitions (and legacy leading '-dynamic 1') are never cached so
re-evaluated substitutions always take effect; dev/dynamic-cache.test
known-bug pin flipped
- new punk::args::parse_cache view/clear proc (sgr_cache style); guarded
variable init; -errorstyle definition default corrected to the operative
'standard'. New parsecache.test (7 tests).
synopsis notation + internal @form -synopsis retirement:
- ::punk::args::parse/::parse_status dropped their stale @form -synopsis
overrides (omitted -cache/-caller) for auto-generated lines shaped with
-typesynopsis {<int|formname>...} on -form; drift pin
synopsis_parse_generated added
- punk::ns::synopsis no longer errors on custom @form -synopsis lines that are
not valid Tcl lists (e.g Tcl manpage style '?-form {int|<formname>...}?' -
's parse' raised 'list element in braces followed by ...'): non-list lines
take a textual command-head replacement fallback
- @form -synopsis directive help rewritten (display-only, any style, prefer
auto-generation, known warranted case: script-level/constructed ids);
::punk::args::synopsis -help gains a notation legend and a new @examples
block comparing Tcl man-page ?...? style with the bracket style (punk::args::eg)
eg usability + examples indication:
- punk::args::eg resolves relative/unqualified command names (punk::ns::cmdinfo
from calling context when loaded, else global qualification) - in namespaces
where it shadows the global 'eg' alias (e.g ::punk::args) 'eg list' returned
empty while 'i list' worked; unknown ids now return a message naming the id;
punk::ns::eg hands the typed name through on unresolved docids
- usage-table 'Example: eg <id>' header row now uses scheme colour CLR(check)
(interim display until G-088 footer/subtitle support)
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
3 weeks ago |
|
|
c55225a392 |
punk::args 0.12.4: collision-aware resolve miss path (undefined-id warning retired)
resolve's first-sighting path for a rawdef whose @id is already registered with different content now purges the id's existing cache entries (quiet undefine) before registering, mirroring define's re-creation behaviour. Previously it repointed id_cache_rawdef while stale rawdef_cache_about / rawdef_cache_argdata entries lingered - two rawdefs claimed the same id and a subsequent define with the original text was a silent no-op (stale cache-about hit), leaving withid lookups stuck on the inline definition. The disabled blanket "called with undefined id" stderr warning is removed - it flagged supported inline usage (parse ... withdef, direct resolve calls). Guard checks id_cache_rawdef directly (id_exists also matches aliases, where the rawdef lookup would error). Known residual: the miss path still records no -defspace for @dynamic definitions first seen via resolve. New define.test pin define_resolve_id_shadow (characterized pre-fix: the re-define no-op reproduced with the purge disabled). punk::args suite green under Tcl 9.0.3 (228 passed, 0 failed). punkshell 0.12.41. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
3 weeks ago |
|
|
d50d1dd6c5 |
punk::args 0.12.3: fix stringstartswith tail-clause reservation ($tp -> $rv); flip pin
The stringstartswith(*) arm of get_dict_can_assign_value''s multi-member tail-clause reservation walk compared the prefix against $tp (the type string) instead of $rv (the candidate value). Consequences (pinned pre-fix in the previous commit): - a later optional clause mixing literal(...) and stringstartswith(...) members never had genuinely matching trailing words reserved - a greedy -multiple argument swallowed them and the tail clause was silently lost - a prefix text that happened to prefix the literal type string (e.g str vs stringstartswith(str)) wrongly reserved NON-matching words, raising a spurious toomanyarguments overflow One-token fix; allocation_tailclause_ssw_reservation_GAP flipped to the correct expectations (matching words reserved; non-matching words left to the -multiple argument with no error); literal-only and no-match guards unchanged. Known remaining approximation (pre-existing, noted in the buildversion changelog): the walk still requires a literal* member in the tail clause''s typelist to run at all - a stringstartswith-only tail clause is not reserved. Verified: full punk/args suite 231 total / 227 passed / 0 failed (4 intended skips), punk/ns 57/57 under Tcl 9.0.3; allocation.test 10/10 under Tcl 8.7. punk::args buildversion 0.12.2 -> 0.12.3; project 0.12.30 + CHANGELOG. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
4 weeks ago |
|
|
54d6396237 |
punk::args 0.12.2: comment/doc hygiene pass - dead code removed, MAINTENANCE notes upgraded to refactor assessments, stale docs corrected
No behaviour change (full args suite 224/0-failed, ns 57/57, 8.7 spot check).
Removed (~1100 lines of commented-out code, recoverable via git history):
- old-signature private::check_clausecolumn ("old version")
- _check_clausecolumn2 "interim version" experiment (its collect-all-clause-
failures idea preserved as an in-place note for G-072-era rework)
- pre-parsekey opts ordering loop, pasted opts-logic reference copy in the
values loop, disabled XXXliteral* switch arm, misc debug remnants
MAINTENANCE comments: the leaders/values loop-parity notes expanded into a
dated refactor assessment - shared clause-assignment helper extraction is
indicated (drift is real: G-082 duplicated its selection block, parsekey
idents exist only values-side) but deferred to ride the G-084 parity work
under the G-046 hot-path constraints; mirror-or-justify rule stated at both
loops. The old "synchronize with values loop" todo folded into it.
Documentation accuracy:
- get_dict PUNKARGS + doctools: real result keys (leaders opts values
received solos multis id form, + formstatus when candidacy ran); directive
lists corrected beyond @cmd/@leaders/@opts/@values; false primordial claims
removed ("only supports -flag val pairs, not solo options" / "only the
last value is used")
- parse -help example fixed (dict exists bracketing was broken) and header
dofilestuff example fixed (stray trailing 1 after -type existingfile);
punk::parse -> punk::args::parse; typos
- goal cross-refs annotated at code sites (G-053 -multiple ranges, G-084
values/leaders parsekey incompleteness); wrong test-name comments corrected
to parsekey_repeat_ordering
Flagged, deliberately unfixed (comment only, no pins exist): suspected bug in
the multi-member clause "stringstartswith(*" arm of get_dict_can_assign_value
- it matches against $tp (the type string) instead of $rv (the value), so it
always succeeds.
All inserted/updated comments carry 2026-07-14 Agent-Generated/Agent-Updated
marks. punk::args buildversion 0.12.1 -> 0.12.2; project 0.12.29 + CHANGELOG.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
4 weeks ago |
|
|
d2e96dbe30 |
G-082 achieved: punk::args 0.12.1 single-form error selection - specific rejection preferred over generic overflow
A word rejected by an OPTIONAL argument's allocation screen (G-071 restricted-choice screen, or the basic int/double/bool/number/dict type screen) that subsequently overflows the argument list now reports the specific rejection instead of "Received more values than can be assigned": - choiceviolation naming the word and allowed choices, with -badarg/-badval and the final-validation message template (Leading/Trailing argument attribution), for choice-screen rejections - typemismatch naming the declared (normalized) type, with -badarg/-badval, for basic-type screen rejections Mechanism: private::get_dict_can_assign_value returns a 'rejection' record (single-member clauses only; literal-category mismatches deliberately not recorded); get_dict_form collects first-rejection-per-word from the three allocation call sites (leader/value split trial, leaders loop, values loop) into a per-form store; the two toomanyarguments raise sites prefer a recorded rejection for the unassignable word. Genuinely-surplus words still report toomanyarguments; words consumed by later slots parse unchanged; multiform selection (rank_form_failures) untouched. errorselection.test _GAP pins flipped to the pointed expectations (pre-fix behaviour pinned in the previous commit). punk::args buildversion 0.12.0 -> 0.12.1. Closeout: G-082 flipped achieved + archived (index -> GOALS-archive.md, detail -> goals/archive/ with mechanism/verification/residue recorded); G-073 note updated to point at the new rejection-record seam; src/modules/AGENTS.md authoring-ergonomics bullet re-documented (-optional 0 workaround no longer needed on >= 0.12.1; make.tcl keeps it - it runs against the bootsupport 0.12.0 snapshot). Project version 0.12.28 + CHANGELOG. Verified: full punk/args suite 228/224/0-failed (4 intended skips) and punk/ns 57/57 under Tcl 9.0.3; errorselection.test 7/7 under Tcl 8.7; make.tcl frobnicate still pointed; goals_lint clean. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
4 weeks ago |
|
|
6af0fd541e |
punk::args 0.12.0: formcheck on-demand multiform ambiguity analysis + @form -overlapallowed sanction (G-074 achieved)
New punk::args::formcheck <id> ?-return dict|summary?: reports the form pairs of a multiform definition that some argument list could cleanly match simultaneously (the multipleformmatches inputs). Static pairwise pass over the resolved FORMS enumerates each form's positional word-slot chains (leaders then values; -optional and ?-wrapped clause-member branching; -multiple capped; options excluded - order-free), screens aligned equal-length chains per position (discriminator words via choiceword_match, type witnesses from a small table), and CONFIRMS every candidate witness arglist with a real single-form parse against both forms (parse_status - no raise, no user-supplied words, no define/resolve cost). Findings are therefore witnessed - discriminated form pairs cannot false-alarm; misses (exotic types, option-requiring forms, enumeration caps) are the documented conservative direction. Classes: type_weakness (discriminator aligned with a permissive non-validating type - any/none/string/ansistring/globstring/expr/script) vs structural (forms genuinely share an argument shape). New @form key -overlapallowed <formname-list> sanctions a KNOWN overlap on either pair member: the finding reports with sanctioned 1 and leaves the result's unsanctioned list (the actionable/gate subset). Parse behaviour is never affected; unknown form names are rejected at definition resolve (end-of-forms cycle). @form directive doc updated. tclcore moduledoc 0.3.4: the documented after cancelid/cancelscript overlap (runtime-liveness ambiguity, 0.3.0 record) sanctioned on the cancelid form - ::after now reports zero unsanctioned findings while 'after cancel <id-shaped>' still raises multipleformmatches. ::lseq deliberately unsanctioned: formcheck reports range/start_count (witness {1 count 1}) AND range/count (witness {1 by 1}) - both real, both rooted in the expr-typed end slot, kept visible pending an expr syntax-validating type (G-069/G-070). Tests: new args/formcheck.test (7) - no-finding cases (parse withid/withdef pair, afterish/sharedform fixtures), class+sanction fixture, unknown-form rejection, -return summary, ::lseq/::after pins with witnesses re-verified, sanction parse-neutrality. punk::args suite 210/210, punk::ns 57/57. G-074 achieved and archived (acceptance review in the detail file); G-055 verification gate gains the formcheck step (unsanctioned must be empty for regenerated multiform commands). Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
4 weeks ago |
|
|
b35ea12896 |
punk::args 0.11.2: bad-@dynamic warn-once + round-1 caching; tclcore 0.3.2: fix malformed tcl_startOfNextWord (project 0.12.19)
User-reported: 'i join' emitted the bad-@dynamic warning 4 times ('i
join test' 6). Root cause was a real inefficiency, not just noisy
logging: a @dynamic definition whose round-1 tstr output has no
round-2 parameters bypassed argdefcache_unresolved entirely, so every
resolve in the 'i' flow (doc walk, advisory parse, get_spec for the
render, synopsis) redid display masking plus the full round-1 tstr and
re-warned. Such definitions now cache as a zero-param unresolved entry
- consistent with the round-1 freezing legitimately dynamic
definitions already get - so later resolves take the cheap cached
branch and the warning emits once per definition per interp.
Warning wording corrected: @dynamic is not a complete no-op for a
parse-inert definition - deferred display fields still re-expand per
render instead of caching - so the message says removal is appropriate
only if that display behaviour is unintended. Sweep of all 462
registered ids: ::split, ::array, ::join carry the parse-inert tag
(left in place pending the display-refresh decision).
Incidental finds from the sweep: the malformed ::tcl_startOfNextWord
tclcore definition (double-quoted -help with unescaped quotes in the
embedded man-page example) failed to resolve at all - now braced per
the define quoting rules, 'i tcl_startOfNextWord' works; and resolve's
malformed-record error path printed dev diagnostics (full records dump
+ ::testrecord global) - commented per the stray-debug convention.
Tests: new args/dynamic.test (warn-once + cached parse, legit-dynamic
round-2 freshness; stderr captured via channel transform). punk::args
203/204 (1 pre-existing skip), punk::ns 57/57. Live-verified: 'i join'
and 'i join test' each emit the warning exactly once (punk902z src).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
4 weeks ago |
|
|
f1c0ea10a0 |
punk::args 0.11.1: define doc - registration styles and tstr/defspace interpolation rules (project 0.12.17)
Documentation-only. The define -help gains two sections: 'Registration styles' (direct define vs deferred lappend-PUNKARGS registration - the lazy scan/on-demand definition mechanics, why moduledocs and the module template use it, PUNKARGS_aliases, punk::args::status timings) and 'Interpolation (tstr placeholders) and the defspace' (display-field deferral vs parse-field expansion vs @dynamic; the defspace rule with the argdoc-child subtlety; the silent-literal fallback; safe patterns for load-time-computed values). Motivated by the ::after id-shape harvest misattribution - corrected record in goals/G-055. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
4 weeks ago |
|
|
4707af6fc2 |
G-041 increment 2: doc surface presents the matching form (punk::ns 0.5.0, punk::args 0.11.0, project 0.12.15)
cmdhelp ('i'): the -form option defaults to * (was 0) with parse's
list semantics, and both render sites present the form the advisory
parse selected - 'i after cancel <id>' presents the cancel form's
argument table with its synopsis line underlined; 'i lseq 0 10 2'
presents the range form info-scheme. When no form matches, the ranked
candidates are passed to arg_error (best candidate's table, all
candidates marked, message naming each form's failure); when several
forms match, all matching forms are marked under the ambiguity message.
punk::ns::synopsis ('s'): trailing argument words after a multiform
command path underline the form(s) they match - matching forms from the
advisory parse's formstatus, or the best candidate when none fully
matches ('s after cancel someid' marks both cancel forms; 's lseq
0 10 2' marks the range form). Ordinal line position maps lines to
declaration-order forms in both full and summary renders; marking is
skipped under alias-currying excess or an explicit -form.
punk::args 0.11.0: the documented @form -synopsis override now renders
in punk::args::synopsis full and summary output (arg_error honoured it
already) - the adjacent forms.test GAP flipped
(forms_form_synopsis_override_rendered). Candidate ranking extended:
form_literal_affinity treats required RESTRICTED-choice arguments as
discriminators via choiceword_match (the tclcore models express
subcommand words as -choices), so 'after cancel' ranks the cancel
forms first instead of falling back to declaration order.
Real-model findings recorded in the goal detail: 'after cancel someid'
is genuinely ambiguous in the doc-faithful model (cancelid vs
cancelscript - real Tcl disambiguates semantically); 'lseq 1 count 5'
ambiguity traces to the expr-typed operands (noted in G-055 as a
model-tightening candidate alongside TIP 746).
Tests: cmdhelp.test gains the multiform doc-surface pins (autoselected
form presented, noformmatch best-candidate table + candidate naming,
synopsis marking present/absent). punk::ns 57/57, punk::args 198/199
(1 pre-existing skip); full source-tree suite in the detail record.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
4 weeks ago |
|
|
d85608d685 |
G-041 increment 1: multi-form candidacy engine (punk::args 0.10.0, project 0.12.14)
punk::args::parse/get_dict with the default -form * (or any multi-form selection) now attempts every permitted form instead of effectively parsing form 0 only. Exactly one clean match auto-selects (result gains a 'form' key; 'formstatus' reports every candidate when candidacy ran). No match raises a 'noformmatch' validation error naming each candidate form's first-line failure, ranked best-candidate first (leading-literal affinity with the supplied words, then incomplete before invalid, then declaration order). Several clean matches raise 'multipleformmatches' naming the forms - deliberately no silent preference (recorded in the goal detail); callers pass -form to disambiguate. -form now accepts the documented list of form names/indices across get_dict, parse, parse_status and arg_error via a shared resolver (private::form_selection). arg_error renders the argument table for the first listed form and marks all listed forms' synopsis entries; parse's error render passes the ranked candidate list so the closest form's argument table shows under the no-match message. parse_status: 'form' is now the matched (or best-candidate) form - the per-argument statuses and badarg marking are built for it - and the new documented 'formstatus' key carries per-form status/failureclass/badarg/ message (caller-attributed), the per-form compatibility surface the G-044 completion/hinting consumer needs on partial argument lists. Engine restructure: the single-form parse body of get_dict extracted verbatim to private::get_dict_form (argspecs resolved in the caller's context before selection; no caller-frame use inside - verified). Single-form definitions take the direct path unchanged. Tests: forms.test GAP pins flipped (forms_parse_autoselect, forms_parse_formlist_restriction) plus new coverage: shared-prologue arity discrimination, noformmatch ranking + errorcode payload, multipleformmatches + explicit -form disambiguation, formstatus in results and parse_status. punk::args 198 pass / 1 pre-existing skip, punk::ns 53/53, punk::lib 35/35. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
4 weeks ago |
|
|
d4519f41d3 |
G-071 achieved: punk::args 0.9.0 allocation choice screen - lseq-class optional-element arglists parse in-form (project 0.12.11)
Root cause: get_dict_can_assign_value blanket-satisfied the member check
for any argument carrying choices, so an optional restricted-choice value
(the lseq '..'/'to' noise word) consumed any word whenever arity
permitted, starving later elements/clauses and failing validation with a
confusing trailing-choices error ('lseq 0 10 2' shape).
Fix: an allocation choice screen using choiceword_match (the shared G-040
implementation - exact/alias/prefix/nocase semantics; -choicemultiple
words screened per list member within min/max), applied only where
allocation has an alternative: -optional arguments and further
occurrences of -multiple arguments. Required arguments are deliberately
not screened - the word must fill them and validation's choiceviolation
reporting stays informative (the existing parsestatus/cmdhelp/choices
pins forced and now document both refinements). -choicerestricted 0
behaviour unchanged.
Results: the allocation.test GAPs flipped ('1 2 3' and '1 2 by 3' parse
with correct clause shapes {{} 3}/{by 3}; '1 2 3 4' gets the plain
excess-values rejection instead of blaming the unrelated optional);
prefix normalization survives the screen; all noise-word variants and
if-shape guards unchanged. lseq moduledoc matrix parses per lseq.n under
-form range, and 'i lseq 0 10 2' works end-to-end. Remaining lseq
divergences trace to G-041 form selection or the -type expr laxity
recorded in G-055 - not allocation.
Also corrected an increment-1 mis-premise: parse_status ALREADY accepts
-form before the withid/withdef tail per its documented synopsis - the
probe had passed it trailing. GAP replaced by
parsestatus_form_option_order (correct-order acceptance incl. the form
key, trailing rejection). No code change was needed for that acceptance
clause.
Verification: punk::args suite 193 pass / 1 pre-existing skip / 0 fail;
punk::ns 53/53; full source-tree suite 813 pass / 13 skip / 1 fail =
exec-14.3 only (known baseline) - zero regressions (tclsh 9.0.3; lseq
verification in punk902z src, Tcl 9.0.2).
Flip edits: G-071 index entry moved to GOALS-archive.md (achieved
2026-07-12), detail Status flipped with the acceptance review and
before/after record; reference sweep updates G-041 (prerequisite fixed,
parse_status correction) and G-072 Notes. The detail-file move to
goals/archive/ follows as a pure rename; goals_lint transiently unclean
between the two commits.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
4 weeks ago |
|
|
17b8a6dbbd |
G-071 increment 1: allocation characterization suite + retreat-path debug silencing (punk::args 0.8.3, project 0.12.10)
G-071 flipped proposed -> active (user direction 2026-07-12).
New allocation.test (7 tests) with reduced fixtures isolating the failing
shape from the tclcore moduledoc: the lseq-range shape (start ?sep? end
?by-step clause?) reproduces the moduledoc failures exactly. Current
mis-allocation pinned as GAP tests ("1 2 3" -> invalid blaming sep,
"1 2 by 3" -> incomplete blaming end, "1 2 3 4" correctly invalid but
misblaming sep), noise-word variants and the if-shape noise-word clauses
pinned as regression guards, parse_status -form absence pinned as GAP.
Also silenced four more unconditional debug puts on get_dict allocation
retreat paths ((111)/(222)/(333)/(444)) - these printed to stderr during
NORMAL successful parses at every optional-skip retreat, polluting
interactive help/parse output for noise-word-modelled commands. Behaviour
unchanged; the retreat logic they marked is exactly this goal fix target.
Full punk::args suite 193 pass / 1 pre-existing skip / 0 fail (tclsh
9.0.3).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
4 weeks ago |
|
|
58da288d45 |
G-041 prework: if/switch/try/lseq real-vs-model probe findings recorded; punk::args 0.8.2 debug-leak fix (project 0.12.9)
Probing (punk902z kit, Tcl 9.0.2) of the tclcore moduledoc models against the real builtins, driven by user concerns about variable-length clauses with optional elements before G-041 activation. Findings recorded in the G-041 detail file (auto-selection evidence on real commands, the allocator prerequisite, parse_status -form gap) and the G-055 detail file (modelability over-acceptance list: try compound handler types, reserved-word clause allocation, "-" fallthrough constraints, switch two-argument option suppression, unvalidated -type expr, TIP 746 version-conditionality for lseq operands; plus the user doc-direction guidance that definitions split into @form entries where source docs simplify). Key result: the per-form models are doc-faithful (lseq.n synopsis maps 1:1; switch separate/block parse correctly under explicit -form; try mixed on/trap interleaving and finally positioning all agree with the real command) - but the value allocator mishandles an optional single-word choice value followed by a required value plus trailing optional-member clause, so lseq range arglists without the ../to noise word ("0 10 2", "0 10 by 2") fail in-form. No lseq form accepts them, so G-041 form selection alone cannot fix "i lseq 0 10 2" - allocator fix flagged as a candidate prerequisite goal. Fix included (punk::args 0.8.2): unconditional debug puts on the clause type-check path (get_dict_can_assign_value) commented, companion to the 0.2.3 find. Full punk::args suite 186 pass / 1 pre-existing skip / 0 fail. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
4 weeks ago |
|
|
66df76c82e |
G-045 achieved: punk::args 0.8.1 define quoting documentation; flip + archival edits (project 0.12.8)
Increment 5 (final): the container quoting rules pinned by defquoting.test now appear in the punk::args::define -help documentation - braced values fully literal (backslash sequences survive as typed); double-quoted values get Tcl backslash semantics at record parse while $ and [] stay literal with no substitution outside tstr placeholders; the backslash-escaped placeholder idiom renders a literal placeholder. Rendered section verified in punk902z src (meta-escapes display correctly). punk::args suite 186 pass / 1 pre-existing skip / 0 fail. Acceptance review recorded in the detail file: all criteria satisfied across increments 1-5 (@cmd -unindentedfields 0.6.1, i help alignment punk 0.2.4, -& record continuation 0.7.0, @normalize + define_docs consumer proof 0.8.0/punk 0.2.5, quoting documentation 0.8.1; suite grown 128 -> 187 tests, GAPs flipped, none weakened, full source-tree suite zero regressions). Flip edits: G-045 index entry moved to GOALS-archive.md (achieved 2026-07-12), detail file Status flipped with evidence in Progress, reference sweep updates G-053 notes. The detail file move to goals/archive/ follows in the next commit as a pure rename (per the goals/AGENTS.md archive rules) - goals_lint is transiently unclean between the two. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
4 weeks ago |
|
|
22606faebe |
G-045 increment 4: punk::args 0.8.0 @normalize directive; define_docs converts as consumer proof (project 0.12.7)
New bare @normalize directive: opts a definition into indent normalization of BLOCK-FORM multi-line field values (first line whitespace-only, as authored by opening a braced literal with a newline). The structural first newline and a whitespace-only trailing line are dropped, the content lines' common leading whitespace is the block's base indent, the first content line is unindented fully and subsequent lines are re-based to the standard 4-space continuation convention (deeper relative indents preserved; whitespace-only inner lines become empty). Fields in a record's -unindentedfields are exempt. Implemented as a resolve pre-pass over the split records (private::normalize_records / rebase_multiline_value); @normalize with options is an error. Head-form values are never altered - their base indent is unknowable (continuations uniformly at 6 may be base-4 with the deliberate +2 relative convention, or base-6 flush; re-basing would flatten the former). The idempotence test caught exactly that on a file-style definition during implementation, narrowing the user-confirmed re-base semantics to block form only - which also makes @normalize a proven no-op on conforming file-style definitions. Consumer proof (punk 0.2.5, per the recorded user decision): ::punk::helptopic::define_docs converts from interim left-margin authoring to indented block-form values under @normalize, dropping its -unindentedfields declarations; 'i help' and 'i help_chunks' verified aligned in punk902z src, including the blank-line separator in the combined basehelp+extra block. Tests: new normalize.test (5 tests: block re-base, block left-margin, head-form boundary, exemption byte-exactness, file-style idempotence); rendering.test P4 characterization stays pinned as the deliberate unopted default with its text updated to reference @normalize. punk::args suite 186 pass / 1 pre-existing skip / 0 fail; punk::ns 53/53; full source-tree suite 806 pass / 13 skip / 1 fail = exec-14.3 only (known baseline) - zero regressions (tclsh 9.0.3). define doc documents the directive. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
4 weeks ago |
|
|
52ad1211a2 |
G-045 increment 3: punk::args 0.7.0 - record-continuation token -& (project 0.12.6)
An unquoted trailing -& element on a definition record line continues the
record on the next line. Implemented in
private::split_definition_records: the token is dropped and the next line
joins after a single space with its leading whitespace collapsed - exactly
how the Tcl parser joins backslash-newline continuations before a braced
definition ever reaches the splitter - so a -& record assembles
byte-identical to its backslash-continued equivalent. Motivation:
constructed (string-built) definitions cannot author backslash-newline
ergonomically (the building code's own quoting consumes it); -& is plain
text and survives any construction.
Collision rules (analysis and decision recorded in the goal detail file):
bare word preceded by whitespace (or whole line), trailing whitespace
tolerated; braced/quoted -& is data ({-&} escapes a literal trailing
value); mid-line -&, word-suffix abc-&, and -& inside still-open
braced/quoted values are data. Element-count disambiguation rejected
(action-at-a-distance; positional rule is locally decidable). Backslash
authoring unchanged - continuation is additive.
Tests: new recordcontinuation.test (6 tests) incl. backslash-twin
parse+render byte-equality and the constructed-def chaining case. Full
punk::args suite 181 pass / 1 pre-existing skip / 0 fail; full source-tree
suite 801 pass / 13 skip / 1 fail = exec-14.3 only (known baseline) - zero
regressions (tclsh 9.0.3). define doc documents -& alongside backslash
continuation.
Also recorded: tclparser considered and rejected for the splitter (ANSI
unbalanced-bracket data, dialect semantics outside Tcl grammar, binary
dependency vs G-004); dev-time parse cross-check lint flagged as candidate.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
4 weeks ago |
|
|
bb9ff66f51 |
G-045 increment 1: punk::args 0.6.1 - @cmd honours -unindentedfields for -help (project 0.12.4)
arg_error's cmd-help display transform (undent " "+help, max 4 - the '#unindentedfields ?' todo site) is now gated by "-help" membership in the @cmd line's -unindentedfields list, mirroring the existing per-argument gate. The single transform site feeds both the table and string renderers, so left-margin-authored @cmd help renders its first line flush with continuations in both. @cmd -summary carries no indent transform in any renderer, so -unindentedfields for -summary is vacuously honoured. No in-tree definitions set -unindentedfields on @cmd - existing rendering is unchanged. define doc for -unindentedfields now states where the option is valid. Tests: rendering_unindentedfields_cmd_help_GAP flipped to rendering_unindentedfields_cmd_help (aligned expectation, both renderers measured). Full punk::args suite 175 pass / 1 pre-existing skip / 0 fail; punk::ns suite 53/53 (arg_error consumer); make.tcl modules builds clean (tclsh 9.0.3). Also: G-045 flipped proposed -> active (user direction 2026-07-12); progress and remaining-work recorded in the detail file. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
4 weeks ago |
|
|
c309ed4782 |
punk::args 0.6.0: small restricted choice sets display as literal alternates in synopses
An argument whose choice pool (-choices plus -choicegroups members, deduplicated) has 1-3 members and -choicerestricted true (the default) now renders those words unitalicised joined by | in synopses - e.g 'after cancel' shows literal cancel, a 3-choice option shows (left|centre|right) - matching the display style of literal()/literalprefix() type-alternates. Larger or unrestricted choice sets keep the italicised argname/<type> display, and an explicit -typesynopsis always takes precedence (textblock::frame -type unchanged). New shared helper punk::args::private::synopsis_choice_literals feeds both synopsis render paths (leaders/values via synopsis_form_arg_display, options inline in synopsis); applies only to single-element -type lists. Superseded commented-out single-choice sketches removed; define doc for -choices documents the rule. tests: synopsis.test 4 -> 13 - characterization coverage for literal/literalprefix/stringstartswith/stringendswith type-alternates, option alternate parenthesization, multi-element clause display (?type? members, argname tail-word hints), -typesynopsis value-element lists and option passthrough incl documenter ANSI, plus the new choice-literal rule (leader/option/value positions, choicegroups counting, >3 and unrestricted fallbacks, -typesynopsis precedence). rendering.test choicelabel fixtures padded to 4 choices so markercol keeps matching the choices cell rather than the now-literal synopsis line. Known residue (deliberate): option-path -typesynopsis ?-trim edge cases remain (todo comments at the render site) - resolve-time rejection deferred; any future normalization surgery belongs to punk::ansi::ansistring/opunk::Str. project 0.12.0 Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
1 month ago |
|
|
ce2ba184cb |
punk::args 0.5.0 + punk::ns 0.2.0: G-049 parse-status data model + machine-parsable cmdhelp returns
- new punk::args::parse_status: documented status structure from a parse attempt (overall ok / status valid|invalid|incomplete / scheme / message / errorcode minus -argspecs / failureclass / badarg / form / receivednames + per-argument argstatus with class, status ok|bad|unparsed, received count/positions, value-in-effect incl -default fill); validation failures reported in the structure, not raised
- arg_error -parsestatus: both renderers derive goodarg/badarg row marking and choice value-in-effect highlighting from the structure (transient goodargs/badarg locals replaced; built internally from -badarg/-parsedargs when not supplied)
- per-render scheme colour resolution: documented -scheme choice value 'nocolour' now takes effect and scheme renders no longer mutate the shared arg_error_CLR array (strike-only goodarg leak fixed)
- parse: new -caller option overriding the %caller% frame-walk substitution (included in parse cache key); get_dict missingrequiredvalue/missingrequiredleader now carry -badarg (type/allocation failures get badarg marking, not just choice violations)
- punk::ns::cmdhelp: -return dict {origin docid cmdtype args_remaining parsestatus}; advisory parse via parse_status on both alias and main paths; explicit -scheme honoured on the parse-failure render; failure messages name the queried command instead of leaking the internal parse source line at top call depth
- tests: parsestatus.test new (12); usagemarking.test G-049 GAP pins flipped + -parsestatus parity/badarg render tests (17); cmdhelp.test G-049 GAP pins flipped + cmdhelp_return_dict_* (25); punk/args + punk/ns trees green on Tcl 9.0.3 and 8.7; full source-tree suite baseline unchanged (exec-14.3 only)
- punkshell 0.5.0: CHANGELOG entry; src/tests/modules/AGENTS.md test-index blurbs updated
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
1 month ago |
|
|
02da46eb74 |
punk::args 0.4.2 + punk::ns 0.1.4: G-046 achieved - deferred display-field expansion, rendering/value-shape fixes
Argument resolution no longer tstr-expands display-only content (-help on @cmd/@examples/argument records, @formdisplay bodies): ${...} there is masked with inert tokens (spec key DISPLAY_DEFERRED) and expanded at display time via private::expand_display_fields (hooks in arg_error/eg/resolved_def/@default copyfrom; separate display cache for non-dynamic defs; @dynamic re-expands per render preserving provider refresh; reentrancy guard substitutes raw sources when expansion of the same id re-enters). First parse of heavily documented commands drops accordingly (punk::ansi::mark_columns first call ~4.3s -> ~12ms; tclcore ::lseq resolve ~184ms -> ~2ms) and -help content that calls punk::args-parsing commands - including against its own definition id - resolves cleanly instead of stalling or looping. -choicelabels stays eager (punk::ns reads it from parse specs in the subcommand walk). Record splitter factored to private::split_definition_records. Also per G-046 acceptance: - @dynamic multiline -help substitutions align at the insertion column (rendering_atdynamic_multiline_help_insertion GAP flipped) - prefix/alias choice normalization keeps single-element-clause values plain-string ({\Deleted} list-wrap shape bug; choicegroups_imap_prefix_shape GAP flipped) - -return string renderer aligns cmd-help continuations under the Description: label (characterization updated) and its Example: line shows the example, not the doc url - punk::ns cmdhelp shows plain info-scheme usage when no argument words are supplied for a leader/value-requiring definition ('i string is', 'i punk::args::define') - advisory parse runs -errorstyle minimal so the discarded error no longer renders a second usage table (timing parity with pre-change: ~5.3s/4.1s on punk91 src) Tests: deferredhelp.test (new); suites green on tcl903 + tcl87; full source-tree run baseline-clean (exec-14.3 only). GOALS.md: G-046 -> achieved 2026-07-10 (activated this session at user direction); design + verification evidence in the detail file. Project 0.4.15. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
1 month ago |
|
|
383e4e5057 |
punk::args 0.4.1: ensemble autodef loads lazily-registered subcommand argdocs before id_exists checks
First 'i <ensemble>' in a fresh shell (e.g 'i ansistring') rendered the autogenerated ensemble help without subcommand-help markers/choicelabels: ensemble_subcommands_definition tested punk::args::id_exists against argdocs whose registered namespace (::punk::args::register::NAMESPACES) had not yet been lazily loaded - the punk::ns doc-lookup entry path only loads the ensemble command's parent namespace. The generator now runs update_definitions for the namespaces its id checks could resolve in. Self-healed on later calls (autodef regenerates per 'i' invocation), which is why the defect went unnoticed; no prior test pinned the load ordering. Tests: punk/args ensembledef.test (new), punk/ns cmdhelp.test cmdhelp_ensemble_lazy_registered_argdocs. Project 0.4.14. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
1 month ago |
|
|
52dab2457d |
punk::args 0.4.0: internals to private ns, dev-test procs culled, full PUNKARGS coverage; project 0.4.13
Pre-G-046 tidy-up of punk::args:
- deleted dead developer procs define2, parseXXX and the unused ::punk::args::TEST definition
- Get_caller diagnostics renamed __test_get_dict/__test_get_by_id/__test_callers (+ __test1 id)
and lib tstr demo renamed __tstr_test_one - unexported (punk::args::lib now exports {[a-z]*})
- new internal namespace punk::args::private (namespace path punk::args + lib + system):
_get_dict_can_assign_value, _split_type_expression, _check_clausecolumn,
_synopsis_form_arg_display, _argerror_load_colours and lib::_parse_tstr_parts moved there
with underscore prefixes dropped; argerror_load_colours reaches arg_error_CLR* state via upvar
- PUNKARGS definitions added for every remaining exported command (main ns incl. get_dict and
choiceword_match; lib utilities; helpers and argdocbase B/N/I/NI); resolve's empty -help filled;
punk::args::argdocbase added to registered definition namespaces
- tests: punk/args suite 127 pass + 1 known skip, punk/ns suite 28/28 (tcl87)
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
1 month ago |
|
|
87eafd63b0 |
Tcl 9.1 compat: punk::lib 0.3.1, punk::args 0.3.2 - lseq TIP 746, safe-interp disassemble; project 0.4.12
TIP 746 (Tcl 9.1) removed lseq's expr-operand behaviour. punk::lib::range (lseq branch) now normalizes int[+-]int offsets via offset_expr so callers like `range 0 [llength $list]-1` keep working (punk::ansi::grepstr broke under 9.1b0, taking example-block highlighting and the punk::args examples.test with it). The lseq branch is also aligned with the tcl8 fallback contract: default 'by' now infers direction (descending ranges previously returned empty under tcl9) and 'by 0' returns empty (Tcl 9.1 lseq changed by-0 to return one element). Direct lseq expression operands expr-wrapped: punk::lib lzipn_tcl9b/c, cols, cols2; punk::args zero_based_posns. check::has_tclbug_safeinterp_compile falls back to interp invokehidden tcl:unsupported:disassemble - Tcl 9.1 safe interps hide tcl::unsupported::*. New modules/punk/lib range.test pins the range contract on 9.0 and 9.1; core tests AGENTS.md documents native-tclsh vs punk-exe exec.test baselines. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
1 month ago |
|
|
4541944928 |
punk::args rendering/quoting/choicegroups/examples characterization suite; helpers::example [a] fix
Tests-first coverage pass (user-directed) before any changes to the definition-parsing/indentation machinery. punk/args suite: 128 tests, 15 files. - rendering.test (15): nesting independence (plain + tstr definitions render identically regardless of source-block indentation), relative-indent preservation (2-space help and 1-space choicelabel conventions, single and multiline - preservation, not enforcement), -unindentedfields (arg -help works left-margin; @cmd accepts-but-ignores it - GAP pinned), constructed (string-built) definition absolute-indent characterization ('constructed' to avoid confusion with the @dynamic directive), multiline ${[cmd]}/${$var}/ resolved_def insertions (aligned at insertion column, nesting-independent), and @dynamic ${$DYN_X} double substitution: stable across repeated resolutions, provider refresh honoured in help text, choice display and parse acceptance, textblock::frame-style art choicelabels byte-aligned - but multiline -help insertions land lines 2+ at insertion-4 (GAP pinned: the second-round subst path lacks paramindent re-alignment) - choicegroups.test (5): group/-choices union parsing, cross-group prefixes, duplicate-entry dedup, per-group titled choice tables (the punk::imap4 multi-table display), imap4-style {\Deleted}/{$MDNSent} values with labels incl. through tstr-bearing blocks; GAP pinned: prefix-normalization list-quotes special-character choices (exact '\Deleted' stores the plain string, prefix '\De' stores a one-element list) - value shape depends on input style - defquoting.test (3): container quoting rules pinned - braced values fully literal ($, [], two-char \n, bare backslashes), quoted values get Tcl backslash semantics (\n -> newline, \ -> \) with $/[] still literal, and \$\{...\} renders a literal ${...} in tstr-processed blocks - examples.test (6): helpers::example box/title/-tstr toggle (no-dedent direct-call contract pinned), ${[example ...]} insertion into @cmd help (bars at insertion column, content +2, automatic 'Example: eg <id>' row), @examples -> punk::args::eg with #<nodisplay>/@#<nodisplay> stripping (ANSI-tolerant), strip_nodisplay_lines unit, live tclcore ::lseq smoke - punk::args 0.3.1: helpers::example -title path called bare [a] (resolvable only where a punk shell's global alias exists - errored under plain tclsh); now punk::ansi::a. Found by examples.test in the runtests environment. - investigated punk::ansi::mark_columns first-call slowness (3.94s first, 60us after): argdoc -help calls a proc that calls mark_columns, whose parse resolves the same still-resolving definition - hazard already documented in-source with candidate fixes; recorded in CHANGELOG for goal consideration, deliberately not patched - project 0.4.11 (CHANGELOG entry) Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
1 month ago |
|
|
850b7f23cc |
G-040 achieved: punk::args -choicealiases with shared choiceword_match resolver; doc-lookup parity; punk::help topic collapse
Activated and completed under user direction (2026-07-08). Aliases for choice
values are now first-class: accepted at parse, normalized to their canonical
choice in results, folded into the canonical entry in usage display, and
resolved identically by the punk::ns doc-lookup walk.
- punk::args 0.3.0:
* -choicealiases {alias canonical ...} on argument lines; dict shape
validated in the option switch, alias->existing-choice and no-collision
cross-validated after spec merge (surfaces at resolve time - define is
lazy)
* the choice-word matching chain extracted from get_dict into the shared
resolver punk::args::choiceword_match {word nocase allchoices
choicealiases choiceprefix denylist reservelist} -> {matched exact
canonical}; get_dict delegates to it (writeback/lset logic stays at the
call site) - one implementation for parser and doc walk
* exact aliases match under any -choiceprefix/-nocase setting; alias names
join the prefix-calculation pool when -choiceprefix is true; deny applies
to the matched NAME (denied alias requires the full alias; a canonical
reached via its alias is exempt from the canonical's own deny entry)
* display: aliases fold into the canonical entry as an '(alias: x)' /
'(aliases: x|y)' label note (single convergence point covers all render
paths); alias names join the display prefix calculation so highlighted
minimal prefixes stay truthful
* define doc gains the -choicealiases section
- punk::ns 0.1.2: cmd_traverse resolves subcommand words via choiceword_match
- -choiceprefixdenylist/-choiceprefixreservelist now honoured in doc lookup
(the two pinned parity GAP tests flipped to agreement), aliases normalize
before choiceinfo lookup, -nocase honoured in the walk
- punk 0.2.3: punk::help adopts the feature - 'i help' lists one entry per
registered topic (topics+help, tcl, env+environment, console+term|terminal);
topic words accept aliases and unique prefixes with the user-decided
minimum-prefix policy recorded in ::punk::helptopic: denylist {help}
(h/he/hel stay command words), reservelist {c to tc} (fall through to
command lookup; e/en and te/ter fall through naturally as ambiguous).
Argless 'help' output byte-identical to the strict-80 baseline.
- tests: choices.test +5 (alias exact/prefix normalization, noprefix exact-
only, nocase, the punk::help policy matrix, resolve-time validation);
cmdflow.test parity tests flipped from GAP to agreement + alias-traverse and
display-fold assertions (+flowaliased fixture)
- suites: punk/args 98 pass + 1 skip, punk/ns 28 pass, punk/lib 21 pass
- G-040 flipped active -> achieved 2026-07-08; detail file records
implementation and verification
- project 0.4.10 (CHANGELOG entry)
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
1 month ago |
|
|
e624bdc057 |
punk::args 0.2.3: fix @opts -any adhoc option crash; forms + validation test coverage
- fixed "@opts -any 1" (arbitrary/adhoc option passthrough): an option not in
the definition crashed get_dict with "can't read argname" at the name-mapping
stage - adhoc opts now fall back to their raw supplied name, under which
argstate/arg_checks were already populated at scan time (real consumers:
vendored tomlish definitions declare -any 1)
- commented out a debug puts stderr (">>>_get_dict_can_assign_value NOT
alloc_ok...") that fired on every failed clause type assignment (visible on
any multiform parse miss; its happy-path twin was already commented)
- new forms.test (8 tests): @form spec structure (form_names, shared
{a b}-prologue blocks), explicit -form by name/index with cross-form
rejection, multiform synopsis rendering, and GAP pins for G-041 - default
parse is effectively form-0-only, -form rejects the documented list-of-forms
usage, and @form -synopsis overrides are stored in the spec but ignored by
synopsis rendering
- new validation.test (11 tests): -type validation matrix, -range/-minsize/
-maxsize, -nocase choice normalization, option -multiple accumulation,
required-option enforcement, unknown-option rejection vs -any adhoc
passthrough (the bugfix's regression test), -- end-of-options marker,
@values -max enforcement, received-key clause ordinals, solos list, and
default-vs-received distinction
- src/tests/AGENTS.md: note that tcltest compares the -body return value -
bodies ending in a loop must end with an explicit 'set result'
- suites: punk/args 93 pass + 1 skip (was 70+1), punk/ns 18 pass; full
source-tree run 569/581 with only the known exec-14.3 baseline failure
- project 0.4.5 (CHANGELOG entry)
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
1 month ago |
|
|
e45fea9b16 |
G-040 proposed (punk::args -choicealiases); choice-flow characterization tests; -choice* doc clarifications
- GOALS.md: G-040 punk::args choice aliasing with parse normalization, display folding, and doc-lookup parity (user-approved); detail file records the prefix/deny/reserve collapse analysis from the punk::help work, the cmd_traverse divergence, the c/to/tc minimum-prefix policy question, and the test-first sequencing - new punk/ns cmdflow.test (10 tests): cmdwhich/cmdinfo/cmd_traverse docid flow - direct, via-alias and subhelp-choiceinfo resolution (exact + unique prefix), unknown-word fallback to parent docid, -choiceprefix 0 exact-only, space-delimited ids, cmdhelp -return string smoke; the parse-vs-doc-walk divergence (deny/reserve lists honoured by punk::args::parse, ignored by the cmd_traverse walk) pinned as GAP tests pending G-040 - choices.test: 4 new unrestricted-mode (-choicerestricted 0) tests - prefix normalization to the canonical choice, unknown/ambiguous passthrough, denylist and reservelist passthrough, and the punk::help collapse recipe (prefix+deny+reserve on a -multiple leader) - punk::args 0.2.2 (doc-only): define doc -choice* fields now state the -choicerestricted 0 passthrough semantics, -choiceprefix result normalization + minimal-prefix display highlighting, denylist behaviour for shorter prefixes in both restricted modes, and the reservelist phantom-entry idiom for per-choice minimum-prefix control - suites: punk/args 74 pass + 1 skip (was 70+1), punk/ns 18 pass (was 8) Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
1 month ago |
|
|
0455efd614 |
startup behaviour,punk::path fixes, AGENTS guidance
|
1 month ago |
|
|
d7f47f04bd |
punk::args -parsekey fixes for opts
|
1 month ago |
|
|
d264c284e4 |
fcat improvements, test framework work
|
2 months ago |
|
|
b69d0e50f3 |
punk::path and punk::lib fixes
|
2 months ago |
|
|
61aa54c738 |
punk::ns::corp and ansi fixes, punkcheck file save debug output
|
3 months ago |
|
|
36cb87b0dd |
punk::lib - tclscript_info tclscript_showparse, remove line continuations for better cmdtrace support
|
3 months ago |
|
|
b8f57878f2 |
overtype and ansi changes, untabify, opunk, experimental punk::lib::tclscript_info static analysis beginnings
|
3 months ago |
|
|
4c6a3058c3 |
punk::ansi and overtype fixes and tests, grepstr fixes, punk::args synopsis improvements, voo module
|
4 months ago |
|
|
8dfae55673 |
add 'mash options' aka 'option clustering' aka 'short flag stacking'
|
4 months ago |
|
|
d6d6ea8de5 |
overtype,punk::winlnk,punk::args,punk::console etc fixes.
|
4 months ago |
|
|
eab7d854ef |
punk::args::helpers::example fix eat your own dogfood documentation
|
4 months ago |