Skip to content

Merge dev → main (automated) - #2012

Merged
SorraTheOrc merged 107 commits into
mainfrom
release/dev-to-main-20260801072334
Aug 1, 2026
Merged

Merge dev → main (automated)#2012
SorraTheOrc merged 107 commits into
mainfrom
release/dev-to-main-20260801072334

Conversation

@SorraTheOrc

Copy link
Copy Markdown
Member

Automated release created by ship skill.\n\nIncludes CHANGELOG.md with work-item summaries from this release.

pi added 30 commits July 26, 2026 19:05
Implements a Herdr plugin (worklog-selection-list) that provides a
keyboard-navigable work item selection list pane for browsing, filtering,
and selecting Worklog work items from within the Herdr environment.

Key files:
- packages/herdr/herdr-plugin.toml - Plugin manifest with actions and pane
- packages/herdr/src/index.ts - Main TUI entry point
- packages/herdr/src/worklist.ts - Core list UI state, rendering, keyboard
- packages/herdr/src/fetcher.ts - wl CLI data fetching with test injection
- packages/herdr/scripts/open.sh - Action: open worklist pane
- packages/herdr/scripts/toggle.sh - Action: toggle worklist pane
- packages/herdr/README.md - Plugin documentation
- tests/herdr/ - 63 tests across 3 test files

Features: work item listing, stage filtering, detail view, keyboard
navigation (arrows/jk, pgup/pgdn, g/G, enter, escape), refresh, quit.
Herdr resolves command paths relative to the plugin directory
(packages/herdr/), not the repo root.
The extractItems function was checking workItems array before results,
but wl next -n returns both an empty workItems array AND a populated
results array — causing items to be silently dropped. Fixed by:
1. Checking results array first (takes priority when both present)
2. Adding length guard to skip empty arrays
3. Adding fallback for empty results/workItems arrays
4. Adding handling for single-item { workItem: {...} } wrapper
   format used by wl next (no -n) and wl show
Port icon system from Pi TUI browse.ts with:
- icons.ts: statusIcon, stageIcon, priorityIcon, auditIcon, epicIcon,
  riskIcon, effortIcon, needsProducerReviewIcon, auditStaleIcon
- isAuditFresh() for 60-second staleness detection
- getIconPrefix() with multi-column layout (status, stage/audit,
  producer review, epic+children)
- applyStageColour() for ANSI stage-based colouring
- stageColor() for ANSI 256-color codes per stage

Updated worklist.ts:
- formatItemLine now uses icon prefix, stage colouring, priority icons
- createListRenderer renders group separators (── Group ──)
- createListRenderer accepts totalCount for 'top N of M' display
- ANSI-aware truncation preserves escape codes

93 tests passing (4 test files).
Port chord shortcut system from Pi TUI with:
- ShortcutRegistry class: lookup, lookupChord, getChordByPrefix,
  getChordByLeader, getChordEntries, getEntriesForStage
- shortcuts.json: non-agent-triggering shortcuts (c, n, p, s single
  keys + f- chords for filter stage switching)
- loadShortcutConfig(): parses shortcuts.json with validation
- Chord state machine in worklist.ts: pendingChordKeys, hints,
  processChordInput, isChordLeader, formatChordHintsForHelp,
  getChordHelpHints
- Dynamic help bar: shows chord-mode hints when in chord input,
  regular hints otherwise
- runWorklistTui: chord-aware key dispatching, accepts
  ShortcutRegistry parameter
- index.ts: loads shortcut config and passes to TUI loop

125 tests passing, TypeScript compiles cleanly.
Add scrollable detail view with:
- formatDetailContent(): returns full content as line array with
  metadata, wrapped description, and footer
- formatDetailView(): scrollable viewport rendering with offset
  and viewport height parameters
- detailScrollOffset on WorkItemListState with detailScrollUp()
  and detailScrollDown() methods
- Keyboard handling: j/k/arrows for line scroll, PgUp/PgDn for
  page scroll, g/G for top/bottom
- Scroll position indicator: 'Lines X-Y of Z (P%)' shown on last
  visible line when content exceeds viewport
- auto-clamping of scroll offset using formatDetailContent length
- Resets scroll offset when entering/exiting detail mode
- createListRenderer accepts detailScrollOffset parameter

154 tests passing, TypeScript compiles cleanly.
Add auto-refresh support with:
- runWorklistTui options parameter: autoRefresh (default: true)
  and refreshIntervalMs (default: 30000)
- Periodic fetch via setInterval every 30s
- Refresh notifications: '[Refreshed: +N new]', '[Refreshed]',
  '[Refresh failed]' with 3s auto-dismiss
- Auto-refresh timer cleanup on exit
- createListRenderer autoRefresh parameter showing indicator
  in header: '[auto-refresh on]'
- index.ts passes auto-refresh options to TUI loop

162 tests passing, TypeScript compiles cleanly.
Add hierarchical display with expand/collapse:
- WorkItem.children and depth fields for child item data
- WorkItemListState.expandedItems set with isExpanded(),
  toggleExpand(), getFlattenedItems()
- Expand/collapse icons: ▶ (collapsed) and ▼ (expanded) for
  items with childCount > 0
- Depth-based indentation for child items
- Enter toggles expand/collapse for parent items, shows
  detail view for leaf items
- createListRenderer accepts expandedItems Set parameter and
  flattens items for display
- runWorklistTui passes expanded items state to renderer
- WorkItem interface extended with children, depth, _expanded

177 tests passing, TypeScript compiles cleanly.
Add final polish features:
- WlError interface and formatWlError() for user-facing error messages
- Empty list edge case handling (no crash on navigation, clamping)
- goToLast safety check for empty lists
- Error handling tests for init/generic/unknown error cases
- Small terminal size handling in both list and detail modes
- Footer key hints verification in render output
- chordState hint display in footer

197 tests passing (9 test files), TypeScript compiles cleanly.
Add settings system with:
- PluginSettings interface: autoRefresh, refreshIntervalMs, showIcons, wlCount
- defaultSettings with sensible defaults (30s auto-refresh, 20 items, icons on)
- loadSettings(): merge file settings with defaults, handles missing/malformed
- saveSettings(): writes JSON with directory creation
- getDefaultSettingsPath(): ~/.config/herdr/worklog-plugin.json
- index.ts integration: loads settings and passes to TUI loop

207 tests passing (10 test files), TypeScript compiles cleanly.
…Count

The hierarchy expand/collapse on enter was triggered by checking
childCount > 0, but the real wl CLI returns childCount on items
without actual children data. Changed condition to check for a
populated children array instead, so enter opens the detail view
for normal items and only toggles expand when children data exists.

Fixes: enter-to-select broken for all worklog items
The select-and-confirm check at the end of handleKeypress was
using state.mode === 'detail' after handleKeypress had already
changed mode to 'detail' via selectItem(). This caused the TUI
to immediately exit on the first enter press.

Fix: save prevMode before the keypress, so we only resolve
when pressing enter while already in detail mode (i.e.,
confirming a selection, not entering detail view for the
first time).

Adds regression test: enters detail mode on enter for items
without children.

208 tests passing (10 files), TypeScript compiles cleanly.
Two related fixes for detail view rendering:

1. getTermSize() now uses process.stdout.columns/rows first
   (reflects actual terminal dimensions), with env var fallback.
   Herdr panes may not have COLUMNS/LINES set, causing content
   wider than the terminal and visual wrapping artifacts.

2. formatDetailContent now truncates every line to fit the terminal
   width (ANSI-aware), preventing overflow/wrapping that caused
   duplicate-looking content when lines wrapped in the terminal.

3. Separator and description wrap width now use contentWidth
   (maxCols - 2) matching the 2-space line indent.

208 tests passing, TypeScript compiles cleanly.
cursorHome (\x1b[H) moves to top-left but does not erase old
content. When detail view (fewer lines than list view) replaces
list view, old lines and wrapped overflow remnants remained
visible, causing visual garbage like duplicate text and mixed
content from different views.

Fix: emit ANSI.clear (\x1b[2J) before cursorHome to wipe the
entire screen before each render.

208 tests passing, TypeScript compiles cleanly.
The chordHelpHints variable was computed in runWorklistTui() but never
passed to the renderer or displayed. This made the chord shortcut system
invisible — no visual indication that chords are available.

- Added chordHelpHints parameter to createListRenderer() signature
- Shows '[f] chords' in the footer when shortcuts are loaded
- Pass chordHelpHints from runWorklistTui to the render function

WL-0MS31Q7FD00710B7
When a chord sequence completed (e.g. f-r for filter review),
the TUI would call cleanup() and resolve(undefined), simply exiting.
The resolved command was ignored entirely.

Added dispatchChordCommand() that maps /wl <stage> commands to the
corresponding stage filter action via state.applyFilter().

Now pressing f-r applies the 'in_review' filter and stays in the TUI,
the same applies to f-i (idea), f-n (intake), f-p (plan).

Also fixed chord help hints not being displayed in the footer
(committed separately in b704809, merged here for atomicity).

WL-0MS31Q7FD00710B7
- Removed '/' case from keyToAction() — no longer opens filter prompt
- Updated footer hint: removed [/] filter, [f] chords remains
- Updated 'No filter' message to reference f-* chords
- Updated test to expect null instead of 'filter' for '/' key
- Added postbuild script to copy shortcuts.json to dist/

WL-0MS31Q7FD00710B7
The footer now dynamically shows only shortcuts applicable to the
currently selected work item's stage, matching the Pi TUI behavior:

- Calls shortcutRegistry.getEntriesForStage(selectedStage) to get
  relevant entries for the selected item's stage
- Filters to list/both views
- Deduplicates chord leaders (only one hint per leader key)
- Excludes commands requiring &lt;id&gt; when the list is empty
- Formats as key:label pairs (e.g., 'c:create new', 'f:filter...')

Hints update on each render as the user navigates between items.

WL-0MS31Q7FD00710B7
Auto-refresh is on by default (30s interval), header shows [auto-refresh on].
Removed nav/enter/refresh/quit hints from the footer — they're redundant:
- 'r' refresh: auto-refresh handles it
- nav/select/quit: basic TUI keys, no need to clutter the footer
- filter: handled by f-* chords

Footer now shows only stage-appropriate shortcut hints (e.g.
'c:create new  s:Search  f:filter...') or is left minimal.

WL-0MS31Q7FD00710B7
Updated stage icon mapping in Herdr plugin to match the main project:
  idea:       🔍 → 💡  (magnifying glass → light bulb)
  intake_cpl: 📋 → 📥  (clipboard → inbox tray)
  plan_cpl:   📝 → 📋  (memo → clipboard)
  in_progress: ◐ → 🛠️ (half circle → hammer wrench)
  in_review:  🔎 → 🔍  (right-facing → left-facing magnifying glass)

Previously Herdr used 🔍 for idea (which is the main project's
in_review icon), causing the reported regression.

WL-0MS31Q7FD00710B7
Add auditedAt to WorkItem interface and normalizeItem() mapping in
fetcher.ts so the data flows through the pipeline. Display three audit
fields in formatDetailContent() metadata section:

- Audit: uses auditIcon() — ✅ ready / ❌ failed / ❓ unknown
- Reviewed: uses needsProducerReviewIcon() — ❌ needs review / ✅ reviewed
- Audited At: ISO timestamp (same pattern as createdAt/updatedAt)

Adds 7 test cases covering all three fields (present, absent, null/undefined
states).

Closes WL-0MS3ALBD40006RGD
…ands

When a chord completes in the Herdr worklist plugin, non-/wl commands
were previously silently dropped. This change adds an onCommand
callback to runWorklistTui that receives resolved commands with <id>
placeholders replaced by the selected item ID.

- Export dispatchChordCommand and add executeResolvedCommand() helper
- Add onCommand option to runWorklistTui parameter
- Update index.ts to pass callback writing CMD:<command> to stdout
- Add 12 tests covering all acceptance criteria
- Update README documentation

Closes WL-0MS4GICML0015GW5
…ommand

Update dispatchChordCommand to recognize and route the following
command families through the stdout output mechanism:
- /skill:implement, /skill:audit (agent skill invocations)
- /intake, /plan (agent workflow commands)
- !!wl reviewed (producer review toggle)
- Compound audit commands (&& wl audit-set)

Add resolveAndRouteCommand helper that resolves <id> placeholders
from the selected item and calls the onCommand callback for routing
to the output mechanism (CMD: prefix + process.exit).

Update executeResolvedCommand to pass onCommand to dispatchChordCommand,
so recognized command families are dispatched (return 'dispatched')
rather than falling through to the generic callback path.

Update shortcuts.json with new single-key and chord shortcuts for
implement, audit, producer review, and audit approve/reject.

Add 53 tests covering all new command families, <id> resolution,
no-op handling, and backward compatibility with existing /wl commands.

Refs: WL-0MS4GIMB80084PC5
Adds tests verifying:
- dispatchChordCommand returns false for !!wl update/close/delete/search
- executeResolvedCommand routes !!wl close/delete through onCommand
- No-op when no item selected and <id> required
- Backward compatible behavior without callback
- Full dispatch chain for all !!wl command families

Child: WL-0MS4GIMBD008GWVM
Epic: WL-0MS4GHV30000HXL0
The chord leader check in onData only ran when action === null, but 'r'
returns 'refresh' from handleKeypress. Changed condition to also check
isChordLeader, so chord leaders start chord mode even when the key has
a direct action binding.

Fixes review chords (r v, r a, r r) being unreachable.

Bug: WL-0MS4LDWHW0062FTA
With the chord leader check fix, 'r' is now handled entirely by the chord
system in list mode (review chords r-v, r-a, r-r). The direct 'refresh'
action mapping was dead code and conflicted with the chord leader.

Detail mode still maps 'r' to refresh since chords don't apply there.

Bug: WL-0MS4LDWHW0062FTA
Replace the dual 'key' (single-press) and 'chord' (multi-press) fields
with a single 'chord' array. A single-key shortcut is now chord: ['i'],
consistent with multi-key chords like chord: ['r', 'v'].

Changes:
- Remove 'key' from ShortcutEntry interface — 'chord' is now required
- Remove lookup() method (replaced by lookupChord with any-length array)
- Remove chordEntries Map indexing (superceded by getChordByPrefix)
- isChordLeader now accepts chords of any length >= 1
- loadShortcutConfig validates chord.length >= 1 instead of key presence
- hints fallback uses chord[0] instead of key
- All entries in shortcuts.json use 'chord' uniformly
- getChordEntries() returns all entries (not filtered to length >= 2)
- getChordByLeader delegates to getChordByPrefix
…h Tab in Herdr TUI

Root cause: createListRenderer had its own flattening logic that
re-flattened items already flattened by state.getFlattenedItems()
upstream, causing each child to appear twice.

Fix: Remove the redundant flattening logic from createListRenderer.
The caller (render callback in runWorklistTui) already passes
flattened items from state.getFlattenedItems(), so re-flattening
inside the renderer adds children a second time.

Tests:
- New tests verify no duplication when expandedItems set is provided
  with already-flattened items
- Updated hierarchy tests to pass flattened items (matching real caller)
- 284/284 Herdr tests pass, all 3626 non-pre-existing tests pass
Adds explicit documentation for the audit metadata fields (Audit,
Reviewed, Audited At) that were added in a36f62d:

- packages/herdr/README.md: Add 'Audit indicators' feature bullet and
  mention audit fields in the 'View details' description
- packages/herdr/src/worklist.ts: Add JSDoc for formatDetailContent()
  listing all metadata fields including audit-related ones

Part of WL-0MS3ALBD40006RGD
…d hierarchy

Changes:
- moveUp() wraps to last item when at index 0 (uses flatCount)
- moveDown() wraps to first item when at last (uses flatCount)
- goToLast() uses flatCount - 1 instead of items.length - 1
- pageDown() uses flatCount bounds instead of items.length
- _clampSelection() uses flatCount to properly clamp when hierarchy expanded
- _adjustScroll() uses flatCount for scroll offset calculation
- Updated tests for wrap-around and expanded hierarchy navigation
- Updated README documentation

Closes WL-0MS4QIJLF0090Q9Y
pi added 29 commits July 31, 2026 16:16
…ed/in_review items in TUI lists

Implements the always-show rule for the default selection lists in both TUIs
(Herdr plugin worklist + Pi TUI Worklog extension), including auto-refresh
and DB-backed paths:

- New per-TUI pure selectWorkItems(items, browseItemCount) helper (duplicated
  per decision Q2c): mandatory = critical ∪ completed/in_review always shown,
  browseItemCount limits only "other" items, slots floored at zero.
- fetchNextItems / createDefaultListWorkItems / createDefaultListWorkItemsDb
  now fetch the mandatory subsets explicitly via parallel wl list queries
  (wl list --priority critical + wl list --status completed --stage in_review)
  because wl next -n N hard-caps at 32 items; merged and deduplicated by ID.
- Pi TUI browse flow: removed redundant .slice(0, itemCount) in runBrowseFlow
  re-fetch and initial paths; "top N of M" heading now reflects the actual
  displayed count.
- Stage-filtered views unchanged (no always-show rule).
- Docs: READMEs updated (Herdr + TUI extensions); CHANGELOG.md untouched.

Tests: smart-selection.test.ts in both packages (20 tests covering reference
examples, edge cases, ordering), browse-total-count.test.ts heading updates,
settings-persistence + runWl-init-detection test adjustments for the
additional mandatory-subset queries.
…lists in both TUIs

Filter stage !== 'done' inside selectWorkItems (Herdr + Pi TUI copies),
the single choke point covering all default-list fetch paths (wl next,
mandatory subsets, DB-backed). Explicit stage-filtered views unchanged.

6 new tests per package (12 total): done excluded as critical, as
completed, not consuming slots, empty-list-when-all-done, interleaved
mandatory preservation, plain exclusion.
…0MS4FHW290053SH4)

- tests/herdr/shortcuts.test.ts: dedicated id-substitution dispatch tests for
  all four u-p-* priority templates, u-s stage/status template, and a-y/a-r
  audit approve/reject templates (previously only covered generically)
- packages/tui/tests/browse-shortcut-help.test.ts: help-line rendering tests
  asserting u/x/f chord families collapse to single leader hints, and that
  a-a/a-y stage-gated audit chords appear only for in_review items
…ILJ0079283)

The live herdr session touches root-level worklog.db-shm/worklog.db-wal,
which kept dirtying the working tree and blocking the implement safety gate.
Audit of WL-0MS4FI763006105Y found the NavigationStack was only exercised
in unit tests — production drill-down paths never called pushNavigationState,
so Escape in the live TUI never returned to the parent list.

- worklist.ts: push navigation state when expanding a parent (Enter and Tab
  paths); clear the entry when collapsing; add NavigationStack.removeForParent
  + WorkItemListState.clearNavigationStateFor
- doRefresh re-fetches children for expanded parents after refresh
- README: document Enter/Tab expand and Escape back-to-parent
- tests: production-path nav-stack tests (hierarchy), nav-stack survival
  across refresh (auto-refresh)
…0079283)

.implement_state.json is per-worktree machine state for the implement
orchestration script. The copy committed to dev was stale (pointing at a
previous work item) and its presence at the repo root made
implement.py finish refuse to discover worktrees.
…WL-0MS7MFILJ0079283)

Adds scripts/run-in-pane.sh which splits the current pane to the right,
runs the given command through a shell in the new pane (so && and quoted
--summary values work), renames it, auto-closes on exit 0 after a 500ms
pause, and stays open on non-zero exit for error inspection.

Routes !/!! prefixed commands in the onCommand callback to this script
(via new routeCommand helper) instead of the dead CMD: stdout path.
Agent commands (/skill:*, /intake, /plan) still go to send-to-pi.sh;
unprefixed commands keep the CMD: fallback. Adds 13 routeCommand tests.
…n a pane (WL-0MS95CEAE0080EB4)

The a-y chord resolved to 'wl reviewed <id> false && wl audit-set <id>
--ready-to-close yes ...' which was routed to the dead CMD: stdout path
(herdr v0.7.5 has no CMD: handling), so nothing happened.

Restore the !! prefix on the 12 shell-executed shortcuts (a-y, a-r, r, s,
u-p-*, u-s, u-t, x-c, x-d), exactly matching the pre-a779d71 state. These
now route via routeCommand to run-in-pane.sh (WL-0MS7MFILJ0079283): the
command runs visibly in a new herdr pane, auto-closes on success, and
stays open on failure. Agent commands and /wl filters are unaffected.

Verified end-to-end: the a-y command through the pane wrapper sets
needsProducerReview=false and audit-set --ready-to-close yes with the
summary. Adds 7 tests (dispatch + shortcuts.json routing).
…09MR66)

Criterion 6 of WL-0MS4FI763006105Y audit required a test asserting the
parent scroll position is restored when navigating back. popNavigationState
restores scrollOffset from the pushed entry; new test verifies a non-zero
scrollOffset captured at push time is restored after pop.
…SIA0057ABR)

- Add wl list --root-only flag (mutually exclusive with --parent)
- Make wl next strictly root-only: orphan promotion removed; children
  under closed/deleted/in-progress parents are hidden entirely
- Critical escalation and Stage 3 blocker surfacing never return child
  items; child blockers resolved to selectable parent or dropped with a
  clear reason
- Pi TUI and Herdr fetch mandatory subsets and stage lists root-only;
  defensive parentId filter in both selectWorkItems copies
- Update docs (CLI.md, README.md, TUI.md, herdr README)
- Tests: list-root-only CLI suite, strict root-only database tests,
  updated next-regression expectations, TUI/Herdr fetch-arg tests
…0MS9DNFNN008R263)

src/index.test.ts imported join twice (line 114 from e1c8a10, line 219 from
1fc0332), causing tsc TS2300 and making 'npm run build' exit 2, which fails
herdr's [[build]] step for the linked plugin. The line-114 import already
covers the whole file; the duplicate at line 219 is removed. Build now exits 0.
… (WL-0MS9EK4ED005CSQH)

Root cause: tests/setup-tests.ts (8889958) installs a global
vi.mock('child_process') for the forks pool, which:
1. Silently bypassed runWl-init-detection.test.ts's vi.mock('node:child_process')
   factory — runWl fell through to the real execFile + tests/cli/mock-bin wl
   mock, resolving instead of rejecting (24/25 tests failing).
2. Broke promisify(child_process.execFile) in mock-timeout.test.ts — a
   vi.fn() wrapper breaks callback-arity detection, returning undefined
   stdout/stderr even with real delegation.

Fixes:
- lib/tools.ts: promisify(execFile) lazily inside runWl so the mock binding
  is observable regardless of module-load order.
- tests/child-process-mocks.ts + setup-tests.ts: add a shared mockExecFile to
  the globalThis store and register BOTH child_process and node:child_process
  to the same instances; execFile delegates to real by default.
- runWl-init-detection.test.ts: use the shared store mock; restore real
  execFile delegation in beforeEach so recycled workers keep real behavior.
- mock-timeout.test.ts: resolve the truly-real child_process via
  createRequire for its promisify (this test drives the mock-bin scripts and
  needs the real 4-arity execFile).

Full suite: 3897 passed, 0 failed (previously 24 runWl + 6 mock-timeout
failures, plus intermittent cli-utils-markdown flakes).
…FI763006105Y)

- packages/herdr/README.md: document the [esc] back / (N levels) footer hint
- packages/tui/extensions/README.md: correct hierarchical navigation docs —
  Tab drills into children (Enter opens the detail view, not children); add
  back-hint note
…and (WL-0MS9HIUE0002JAKQ)

The run-in-pane.sh --exec wrapper previously auto-closed the pane after a
500ms pause on exit 0, which was too fast for the user to read the output.
Now the pane stays open for any exit status; the wrapper reports the exit
status and prints a hint to close the pane manually (herdr prefix+x).

- packages/herdr/scripts/run-in-pane.sh: remove sleep+pane close on success;
  print status line + close hint
- packages/herdr/src/index.ts: update onCommand comment
- packages/herdr/README.md: update routing docs
- tests/herdr/run-in-pane.test.ts: 6 tests for --exec mode with mock herdr
…alive (WL-0MS9HIUE0002JAKQ)

Root cause: herdr tears down a pane when its primary process exits. The
previous fix only removed the explicit 'herdr pane close' call, but the
--exec wrapper still exited after printing the status, so herdr still
terminated the pane ~0.7s after spawn (no pane.close API call observed).

Real fix: the --exec wrapper now keeps the pane's process alive after the
command finishes:
- TTY stdin (interactive pane): waits for Enter, hint mentions prefix+x
- HERDR_PANE_ID set, non-TTY stdin: blocks on read from /dev/zero until
  the user closes the pane with prefix+x
- Otherwise (tests/automation): exits immediately with the command status

- packages/herdr/scripts/run-in-pane.sh: keep-alive logic + comments
- packages/herdr/src/index.ts: updated onCommand comment
- packages/herdr/README.md: updated wording (Enter / prefix+x dismiss)
- tests/herdr/run-in-pane.test.ts: 8 tests incl. PTY-based 'stays alive'
  checks and HERDR_PANE_ID non-TTY keep-alive via timeout (124)
…L-0MS9PL90F002MR8G)

Global ~/.pi/agent/AGENTS.md now uses absolute /home/rgardler/.pi/agent/skills/...
paths; update the doc example to match (was showing a 'skills/' prefix that
did not exist).
…flake (WL-0MS9TGA4X004ZPOD)

Audit fixes:
- browse.ts: auto-refresh now re-fetches the total actionable count so the
  'top N of M' title stays fresh (WL-0MS4FIEN40037GB9); heading N is the
  actual displayed count, not capped to M, when the mandatory set exceeds
  the actionable total (WL-0MS8XOOMN0022LLH)
- worklist.ts: fix stale formatDetailContent JSDoc metadata list (WL-0MS4FIM8T001XAVF)
- herdr index.ts + settings.ts: showHelpText re-read on each TUI invocation
  (no restart needed); centralize browseItemCount clamp in settings.ts
  (WL-0MS4FJ2TX009V7V5)
- CHANGELOG.md: document recently merged features (WL-0MS4FIEN40037GB9)
- tests: auto-refresh total-count test, mandatory-set-exceeds-total heading
  test, browseItemCount clamp tests

Flake fix:
- cli-utils-markdown.test.ts: use a vi.hoisted shared loadConfig mock instead
  of vi.spyOn on the module namespace (which was flaky in full-suite runs);
  reset + default re-apply in beforeEach. This was the last intermittent
  failure blocking the audit gate.

Full suite: 3920 passed, 0 failed (twice).
…or paths (WL-0MS4FIEN40037GB9)

Covers the Herdr-side total-count fetch (previously only render-level
undefined handling was tested): count parse, missing-count undefined,
wl-failure graceful degradation, and the open/in-progress/blocked query.
…0MS4FJ2TX009V7V5, WL-0MS4FIM8T001XAVF)

- herdr index.ts + worklist.ts: showHelpText re-read via getShowHelpText()
  callback on every render, so the setting applies on next refresh without a
  plugin restart (matches browseItemCount behavior)
- herdr README: document browseItemCount/showHelpText/showIcons in the
  settings list; document GitHub Issue number in the detail view features
- tests: herdr suite green (427)
…key (WL-0MS4FIUYS001K08K)

- auto-sync.ts: runSync now returns { success, error } so the UI can surface
  sync status instead of silently discarding failures
- worklist.ts: doSync() renders '[Synced]' / '[Sync failed: ...]' in the
  notification area; wired into the auto-refresh and auto-sync timers; new
  'S' (uppercase) key triggers a manual sync
- tests: runSync success/failure/exit-code tests, manual 'S' key action test

Full suite: 3927 passed, 0 failed.
…initialized-report tests (WL-0MS6LS2TF007AV63, WL-0MS6LSFOH001E2YJ)

- index.ts: route plain (non-!!) shell commands through run-in-pane.sh with
  --cwd targetCwd so they execute from the tab working directory (herdr has
  no CMD: handling, so the stdout CMD: protocol was a dead execution path)
- index.ts: fetcher returns an empty list when no valid .worklog/ exists in
  the tab dir, so the TUI shows the uninitialized/empty state instead of
  resolving the plugin's own CWD worklog
- index.ts: extract uninitializedReport() helper; main() uses it
- index.test.ts: assert the uninitialized stderr messages (Showing empty
  worklist / No valid .worklog)

Full suite: 3928 passed, 0 failed.
- auto-sync.ts: runSync(worklogDir?) accepts the resolved worklog dir and
  passes --worklog-dir to wl sync (avoids circular import with fetcher)
- worklist.ts: doSync() passes getWorklogDir() so background sync targets the
  tab project instead of the plugin pane CWD
- tests: runSync --worklog-dir argument test

Full suite: 3929 passed, 0 failed.
…(WL-0MS9TGA4X004ZPOD)

dev's CHANGELOG was behind main (missing v1.0.4 release notes), causing a
merge conflict in the dev→main release flow. Merge main's version history
into dev's CHANGELOG, keeping the Unreleased section for this release.
…004ZPOD)

Importing index.js in a vitest worker previously triggered main(), which can
call process.exit(1) (e.g. wl not on PATH in CI), crashing the test runner
and failing the cli-tests/install-and-smoke-test CI checks on the release PR.
main() now runs only when index.js is the entry point.
@SorraTheOrc
SorraTheOrc merged commit 858f28b into main Aug 1, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant