Commit Graph

4 Commits

Author SHA1 Message Date
Tom Boucher
e38d246015 fix(#4439): render pending-todo 'created' as date-only, matching [date] (#4494)
* test(#4439): failing-first regression coverage for pending-todo date rendering

renderPendingTodoBullet currently echoes the todo's `created` frontmatter
verbatim into the rendered bullet's [date] bracket, so a full ISO-8601
timestamp (the actual stored shape, per add-todo.md's create_file step)
leaks through instead of the date-only format documented in
docs/reference/state-md.md and docs/COMMANDS.md. This commit adds the
regression coverage only; the renderer fix lands in the next commit.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* fix(#4439): render pending-todo 'created' as date-only, matching [date]

renderPendingTodoBullet echoed the todo's created frontmatter verbatim
into the rendered STATE.md bullet. That value is always a full
ISO-8601 timestamp by design (add-todo.md's create_file step writes
init.todos' timestamp field), but docs/reference/state-md.md and
docs/COMMANDS.md document the bullet as `- [date] ...` — a short
calendar date. Added pendingTodoDateOnly(), a pure display-only
formatter: a value starting with a well-formed YYYY-MM-DD is shortened
to just that; anything else ('unknown', a malformed string) passes
through unchanged. The stored frontmatter and the JSON todos[].created
field are untouched.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* test(#4439): cover a non-4-digit-year near-miss for the date-only formatter

Standards review flagged a gap: the malformed-date coverage exercised
a non-padded month/day but not a non-4-digit year, the other way the
input can look almost-but-not-quite like YYYY-MM-DD. Same pass-through
code path as the existing malformed-date test; no behavior change.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* docs(#4439): changeset for the pending-todo date-only bullet fix

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* docs(#4439): backfill changeset PR number

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

---------

Co-authored-by: sim <sim@local>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-07 13:33:30 -04:00
Tom Boucher
ed133cc116 enhance(#3085): add Grep to allowed-tools for 21 skills (#4397)
* enhance(#3085): add Grep to allowed-tools for 21 skills

29 of 71 skills omit Grep from allowed-tools, forcing Bash grep for
structured search instead of the dedicated tool. Adds Grep to the
21-skill subset confirmed safe in prior review (excludes the 6
gsd-ns-* dispatchers, gsd-help, and gsd-surface, which have no
plausible structured-search need).

Hand-edits commands/gsd/*.md only; skills/*/SKILL.md is regenerated
via `npm run gen:plugin-skills` from that source. Updates the one
hardcoded copilot-install test assertion affected by gsd-health's
new tool order.

* chore(#3085): backfill changeset PR number

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* test(#2618): assert the Needs clause on the structured field, not the path-length-dependent bullet

The bullet embeds the todo file's ABSOLUTE path, so its total length
varies by runner tmpdir: on macOS CI, /private/var/folders/… plus the
test harness's gsd-test-run-* wrapper pushed the full bullet to 244
chars — past renderPendingTodoBullet's intended 240-char cap, whose
documented first degradation step drops the Needs clause. The product
behavior is correct (#2618 design); the assertion was runner-dependent.
The extraction is now pinned on json.todos[0].needs; the rendered-bullet
shape stays covered by the path-independent title assertion and the
renderer's own unit rows.

Found blocking #4186's CI on the macOS shard (test landed 30 minutes
earlier in b7406b293f / PR #4384).

---------

Co-authored-by: sim <sim@local>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-06 13:37:47 -04:00
Tom Boucher
b7917882bb fix(#4398): render the pending-todo bullet link repo-relative (#4416)
* test(#4384): failing-first regression rows for the macOS long-base todo-cap failure

The 240-char pending-todo bullet cap must be deterministic w.r.t. where the
repo is checked out. Deterministic long-base-path fixtures (a single 110-char
segment, no real macOS dependency) reproduce next's own macos shard 3/3
failure (run 34038716700) on every OS: with an absolute link the bullet
exceeds the cap and the documented needs-first truncation drops the
'Needs <solution>' clause. Rows cover the determinism property (byte-identical
bullets under short and long bases), the CLI surface, relative-path stability,
legacy no-projectRoot behavior, drop-order preservation, and adversarial
edges (outside-root, path===root, non-string path).

* fix(#4384): render the pending-todo bullet link repo-relative

renderPendingTodosMarkdown gains an optional projectRoot; when given and the
todo's path is absolute, the bullet's [todo file](…) target becomes
toPosixPath(path.relative(projectRoot, path)) — the idiom already used for
project_exists. cmdInitTodos passes cwd.

The JSON todos[].path field stays absolute (#2376). Only the rendered display
link changes: embedding the machine-variable absolute base let macOS's
/private/var/folders/… temp paths consume the 240-char budget and drop the
'Needs' clause on long-path machines only — next's own macos-latest shard 3/3
went red on exactly this (run 34038716700), Linux's short /tmp passed. The
240-char whole-bullet cap and the needs→title→area drop order are unchanged;
this matches PR #4384's own canonical example, docs, and unit tests, which all
show repo-relative links. Docs updated at all three surfaces that describe the
bullet (COMMANDS.md, templates/state.md, reference/state-md.md — the last was
still pre-#4384 'count and reference' prose).

Fixes the macOS regression introduced by #4384; next is red on its own CI.

* test(#4384): fix substring false positive in the outside-root regression row

The ../-form relative link legitimately contains the absolute path as a
substring, so !line.includes(absolutePath) fired on correct output (caught by
the first remote verify run, linux-node24 44018/44019). Assert the property
itself instead: extract the link target and require it to be non-absolute and
not equal to the absolute path.

* chore(#4398): backfill PR number in changeset

---------

Co-authored-by: sim <sim@local>
2026-09-06 13:23:26 -04:00
Tom Boucher
b7406b293f enhance(#2618): render pending todos as one bounded bullet per todo (#4384) 2026-09-06 08:06:39 -04:00