The Input component had no placeholder text support — when empty, it
showed only "> " with a blinking cursor and no hint of expected input.
The ExtensionInputComponent received a placeholder parameter but
discarded it (_placeholder with underscore = intentionally unused).
Fix: Input now has a public placeholder property. When value is empty,
renders the placeholder in dim text. ExtensionInputComponent passes
the placeholder through to Input.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Split skill diagnostics into [Skill conflicts] (actual collisions) and
[Skill issues] (validation warnings like missing description) so users
aren't misled by the label. Add wizard hint to /gsd prefs output.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When all credentials for a provider are exhausted, the system now
automatically falls back to the next available provider in a
user-configured fallback chain. Higher-priority providers are
restored automatically when their backoff expires.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
On macOS the Alt key is the Option key (⌥), but all UI hints showed
"Alt+". Added formatKeyForDisplay() utility that converts alt+ to ⌥
on darwin, applied it in formatKeys() for dynamic keybinding hints,
and updated hardcoded strings in tree-selector, models-selector,
settings-selector, auto-mode dashboard, and extension shortcut display.
Hashline prefixes (e.g. "1#BQ:") were leaking into the TUI display
for file reads, showing as weird characters to users. Strip them
before rendering since they're only meant for model consumption.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace manual binary header parsing (PNG/JPEG/GIF/WebP) in terminal-image.ts
with the native @gsd/native/image module, and replace photon-node (WASM) with
native N-API calls for image resize and format conversion.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The autocomplete file search no longer spawns the external `fd` binary via
spawnSync. It calls the in-process Rust fuzzyFind() function from @gsd/native,
which handles directory walking, gitignore, hidden files, and fuzzy scoring
in a single native call. The fdPath constructor parameter and ensureTool("fd")
download are removed since the binary is no longer needed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Switch syntax highlighting from the cli-highlight npm package to the
@gsd/native Rust-based highlight module (syntect). The native module
accepts raw ANSI escape sequences via the HighlightColors interface,
eliminating the wrapper-function indirection of the old CliHighlightTheme.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
In RPC mode, `ctx.ui.custom()` returns `undefined as never`, causing
`showInterviewRound` to return undefined and `Object.keys(result.answers)`
to throw TypeError.
When `showInterviewRound` returns undefined (RPC mode), fall back to
sequential `ctx.ui.select()` calls for each question, forwarding the
abort signal (#171) and supporting `allowMultiple` (#165).
- Add `allowMultiple` to `ExtensionUIDialogOptions`
- Widen `select()` return type to `string | string[] | undefined`
- Add `allowMultiple` to RPC select request and `values` array to response
- Update RPC `select()` to forward `allowMultiple` and parse array responses
- Guard existing `ctx.ui.select()` callers against the widened return type
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
After /login, if the current model has no valid API key, auto-switch to
a model from the newly authenticated provider. After /logout, if the
current model belongs to the logged-out provider, auto-switch to a
fallback model from a different provider.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Three locations used lastIndexOf("/") or includes("/") for path
manipulation, which fails on Windows where paths use backslashes.
- auto.ts: writeBlockerPlaceholder directory extraction → dirname()
- interactive-mode.ts: parent directory traversal → path.dirname() loop
- path-utils.ts: non-null assertion on MSYS drive letter access
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Vendor all 4 Pi packages (tui, ai, agent-core, coding-agent) from
pi-mono v0.57.1 as @gsd/* workspace packages under packages/. This
replaces the compiled npm dependency (@mariozechner/pi-coding-agent)
and patch-package workflow, giving direct source access for
modifications.
- Copy Pi source from pi-mono v0.57.1 into packages/
- Create workspace package.json + tsconfig.json for each package
- Rename ~240 imports from @mariozechner/pi-* to @gsd/pi-*
- Apply existing patches as source edits (setModel persist, VT input)
- Remove @mariozechner/pi-coding-agent dep and patch-package
- Update build pipeline to build packages in dependency order
- Add pi-upstream git remote for future selective syncing
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>