When envelope.Data is a map containing a list of objects (e.g. tag +list
returns {tags: [...], total_count}), printTable previously fell back to
JSON because the map had complex values. Now it scans the map for the
largest []interface{} of map[string]interface{} and renders that list
via printSliceTable, so users see a table again.
- Add findLargestSlice helper to pick the largest table-renderable slice
- Add hasOnlyNestedMaps to distinguish scalar-only maps from nested-map maps
- Keep JSON fallback for genuinely nested (non-list) structures
- Add formatter_test.go covering all 5 branches of printTable
Selecting a command showed no output because Execute built the
RuntimeContext as a bare struct literal (&RuntimeContext{Args: args}),
leaving Client == nil. Any command calling ctx.CallAPI then panicked with
a nil pointer dereference inside the executor goroutine; the panic aborted
the goroutine before w.Close()/stdout restore, so the execResultMsg never
fired and the REPL hung silently.
Fix: use common.NewRuntimeContext(args) (initializes Client/Format/Owner/Repo,
matching runner.go), and wrap s.Run in safeRun() so a panic converts to an
error and stdout is always restored.
Adds regression tests: nil-Client assertion, panic-safe stdout restore, and
an end-to-end test that runs the real repo +list shortcut and asserts
Execute never returns (empty output, nil error).
Previously the palette only opened after pressing Enter because the trigger
logic lived in the KeyEnter branch. The spec requires '/' to open the palette
immediately. Now KeyRunes with '/' as the first character of an empty input
switches to statePalette right away, carrying any trailing characters (e.g.
'/iss') as the initial search query.
Adds regression tests covering: immediate '/', '/' with query, and ordinary
text staying in input state.
hook-runner +list - List webhook delivery tasks
hook-runner +view - View specific delivery task details
hook-runner +failed - List only failed deliveries
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
When a wiki page is deleted, also remove _Sidebar.md so that GitLink
regenerates it from the current file list on next web visit. This
prevents orphaned page references from accumulating in the sidebar.
Use git add -A to safely stage all changes (deleted page + sidebar)
without failing when _Sidebar.md doesn't exist.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Modifying _Sidebar.md causes wiki page rendering to break on the
web UI. Delete now only removes the .md file and leaves sidebar
management to GitLink's web interface.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add safe sidebar cleanup using a separate helper file (sidebar.go)
to avoid encoding issues. Only removes the page reference, never
adds or modifies other content.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Rewrite tests to use local Git repositories for list/view (Git-based)
and HTTP test servers for create/delete (API-based). Add
repoGitURLOverride variable for test isolation.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Snippet list and view now clone the repo (read-only) instead of
using broken API endpoints. Delete auto-fetches file SHA via
git hash-object for proper API verification.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Automatic sidebar updates caused wiki rendering issues on the web UI.
The sidebar is best left managed by GitLink's web interface directly.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
When creating a wiki page, add [[PageName]] to _Sidebar.md.
When deleting a wiki page, remove [[PageName]] from _Sidebar.md.
This ensures the web UI properly reflects page changes.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Store snippets as files in the snippets/ directory of the repository
using the repo file API. Supports language tagging in content format
and branch selection for commits.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>