collectAutoExtensionEntries now checks if the directory itself has a
package.json with pi.extensions (or index.ts) before scanning children.
This fixes duplicate extension loading when a manifest-aware directory
is specified directly in settings.json extensions array.
Fixes#1274
Use hosted-git-info library for robust parsing of SSH URLs (git@host:path
and ssh://) in addition to HTTPS. SSH and HTTPS URLs for the same repo
are now properly deduplicated.
API keys in auth.json now support the same resolution as models.json:
- Shell command: "\!command" executes and uses stdout (cached)
- Environment variable: uses the value of the named variable
- Literal value: used directly
Extracted shared resolveConfigValue() to new resolve-config-value.ts module.
- Store previousSessionFile before creating branched session
- Update sessionFile after writing new branch file
- Pass parentSession when forking from first message
- Add --local to git config in tests to prevent repo escape
Tests used setExtensionPaths but update() iterates packages, not
extensions. All 5 non-pinned tests were silently passing as no-ops.
Also add regression test for scope-aware update behavior.
Adds Ctrl+N toggle to filter sessions by named-only vs all in the /resume picker.
- Add NameFilter type and filtering logic to session-selector-search.ts
- Add toggleSessionNamedFilter app keybinding (default: ctrl+n)
- Show Name: All/Named state in header
- Empty state mentions toggle keybinding as escape hatch
- Export hasSessionName() to avoid duplication
Co-authored-by: warren <warren.winter@gmail.com>
* fix(coding-agent): tree selector focuses nearest visible ancestor
When the selected entry is not visible (filtered out by mode change or a
metadata entry like model_change), walk up the parent chain to find the
nearest visible ancestor instead of jumping to the last item.
Fixes selection behavior for:
- Initial selection when currentLeafId is a metadata entry
- Filter switching, e.g. Ctrl+U for user-only mode
* fix(coding-agent): tree selector preserves selection through empty filters
When switching to a filter with no results, e.g. labeled-only with no
labels and back, the cursor would reset to the first message instead of
the original selection.
Track lastSelectedId as a class member and only update it when
filteredNodes is non-empty, preserving the selection across empty filter
results.
* test(coding-agent): add tree selector filter and selection tests
- Test metadata entry handling (model_change, thinking_level_change)
- Test filter switching with parent traversal (default ↔ user-only)
- Test empty filter preservation (labeled-only with no labels)
WSL2/WSLg often provides clipboard images as image/bmp only.
Previously this resulted in invalid PNG files being written.
Now readClipboardImage() converts unsupported formats to PNG
via Photon before returning.
Closes#1109
Based on #1112 by @lightningRalf
Package resolution now uses the same discovery logic as local extensions:
only index.ts (or manifest-declared entries) are loaded from subdirectories,
not helper modules.
fixes#1102
- Add set_session_name command with empty name validation
- Expose sessionName in get_state response
- Add setSessionName() to AgentSession and RpcClient
- Document in docs/rpc.md
Fixes#1078
- Add tryNFDVariant() to normalize paths to NFD form
- Add tryCurlyQuoteVariant() to convert straight quotes to curly quotes
- Try combined NFD + curly quote variant for French macOS screenshots
- Add comprehensive tests for path-utils
- Add `-path` force-exclude pattern (exact path match, highest precedence)
- Change `+path` force-include to exact path match (no glob)
- Manifest-excluded resources are now hidden from config (not toggleable)
- Config toggle uses `+` to enable and `-` to disable
- Settings paths resolve relative to settings.json location:
- Global: relative to ~/.pi/agent
- Project: relative to .pi
- Add baseDir to PathMetadata for proper relative path computation
- Update tests for new base directory and pattern behavior
fixes#951
* Add session renaming in interactive mode resume picker
Session list now displays last message timestamp as modified time
instead of file mtime. Ctrl+N enters rename mode in the interactive
resume picker, allowing quick session renaming without leaving the
selector. Rename hint is shown only in interactive mode, not in the
CLI --resume picker./
* Add docs entry for renaming in picker
* Update shortcut to ctrl+r for session renaming
When set to true, the skill is hidden from the system prompt, preventing
agentic invocation. Users can still invoke explicitly via /skill:name.
Also fixes pre-existing test bug where source expectation was wrong.
Fixes#927
- Create shared diagnostics.ts with ResourceCollision and ResourceDiagnostic types
- Update loadSkills() to return diagnostics instead of warnings
- Remove SkillWarning type and skillWarningsToDiagnostics() conversion
- Update skills.test.ts to use diagnostics
- Package deduplication: same package in global+project, project wins
- Collision detection for skills, prompts, and themes with ResourceCollision type
- PathMetadata tracking with parent directory lookup for file paths
- Display improvements: section headers, sorted groups, accent colors for packages
- pi list shows full paths below package names
- Extension loader discovers files in directories without index.ts
- In-memory SettingsManager properly tracks project settings
fixes#645
Previously, user filters completely replaced manifest filtering. Now:
1. Manifest patterns are applied first (defines what package provides)
2. User patterns are applied on top (narrows down further)
This means if a manifest excludes 10 extensions and user adds one more
exclusion, all 11 are excluded (not just the user's one).
- Manifest extensions/skills/prompts/themes arrays now support glob patterns
- Use !pattern for exclusions (e.g., '!**/deprecated/*')
- Enables packages to bundle dependencies and selectively include resources
- Support glob patterns and ! exclusions in package filter arrays
- Support glob patterns and ! exclusions in top-level settings arrays
- Add helper functions: isPattern, hasPatterns, collectFiles, collectSkillEntries, applyPatterns
- Add resolveLocalEntries for pattern-aware resolution of top-level arrays
- Add applyPackageFilter and collectAllPackageFiles for package filter patterns
- Add comprehensive tests for both top-level and package filter patterns
- Add PackageSource type for npm/git sources with optional filtering
- Migrate npm:/git: sources from extensions to packages array
- Add getPackages(), setPackages(), setProjectPackages() methods
- Update package-manager to resolve from packages array
- Support selective loading: extensions, skills, prompts, themes per package
- Update pi list to show packages
- Add migration tests for settings
closes#645
- Add progress callbacks to PackageManager for TUI status during install/remove/update
- Add extension conflict detection (tools, commands, flags with same names)
- Accept raw GitHub/GitLab URLs without git: prefix
- Add tests for package-manager.ts and resource-loader.ts
- Add empty fixture directories for skills tests