- Fixed themes.md: 50 -> 51 color tokens
- Rewrote skills.md to match structure of other docs (TOC, concise sections)
- Removed redundant content from skills.md while keeping all essential info
- Merged theme.md content into themes.md
- Added hot reload documentation
- Updated all references from theme.md to themes.md
- Fixed outdated info (vars not defs, complete example with all 50 tokens)
- Removed dev-focused Implementation section
- Rewrote README intro to emphasize extensibility and pi packages
- Added Pi Packages section to README
- Created docs/packages.md covering install, sources, manifest, filtering
- Created docs/prompt-templates.md covering format and arguments
- Created docs/themes.md with overview linking to theme.md
When Google providers return tool calls without an args field (common for
no-argument tools), the arguments field was undefined. This breaks
subsequent API calls that require tool_use.input to be present.
Now defaults to {} when args is missing.
Related: clawdbot/clawdbot#1509
Adds a new 'pi config' command with a TUI to list and toggle package
resources (extensions, skills, prompts, themes).
- Displays resources grouped by source (packages, user, project)
- Subgroups by resource type (Extensions, Skills, Prompts, Themes)
- Toggle enabled/disabled state with space
- Filter resources by typing
- Supports +pattern for force-include, !pattern for exclude
- Properly reads exclusion patterns from settings.json
fixes#938
Extensions calling setWorkingMessage() in agent_start handlers previously
had no effect because the loading animation didn't exist yet. Now the
message is queued and applied once the loader is created.
Fixes#935
For temporary npm extensions (-e npm:...):
- Unpinned packages: fetch latest version from registry and reinstall if newer
- Pinned packages: reinstall if cached version doesn't match
- anthropic.ts: use model.api instead of hardcoding 'anthropic-messages'
- openai-responses.ts: use model.api instead of hardcoding 'openai-responses'
- gitlab-duo: simplify to use actual model IDs, export MODELS array
- Extensions register providers via pendingProviderRegistrations
- These were only applied in bindCore() during AgentSession creation
- But model resolution in main.ts happens before session creation
- Fix: apply pending registrations immediately after loading extensions
- Also fix gitlab-duo to pass Authorization header instead of apiKey
- Delegates to pi-ai's built-in Anthropic/OpenAI streaming
- OAuth support with GitLab's bundled client ID
- Direct access token caching (25 min TTL)
- Models: duo-chat-opus/sonnet/haiku-4-5, duo-chat-gpt-5-1/mini/codex
- No external dependencies beyond pi-ai
- Move custom-provider.ts to custom-provider/index.ts
- Add package.json with @anthropic-ai/sdk dependency
- Extension now requires npm install before use
- Document stream.push/end pattern instead of yield
- Link to existing provider implementations on GitHub
- Add testing section with list of test files to run
- Include proper content block and tool call examples
- Add resetApiProviders() to clear and re-register built-in providers
- Add createAssistantMessageEventStream() factory for extensions
- Add streamSimple support in ProviderConfig for custom API implementations
- Call resetApiProviders() on /reload to clean up extension providers
- Add custom-provider.md documentation
- Add custom-provider.ts example with full Anthropic implementation
- Update extensions.md with streamSimple config option
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
Themes loaded from packages were not appearing in theme selector because
setRegisteredThemes was never called. Now register themes:
- On startup before initTheme
- After /reload completes
- 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 ParsedSkillBlock interface and parseSkillBlock() function
- Change skill expansion to use XML-style <skill> tags
- Add SkillInvocationMessageComponent for collapsible display
- Collapsed: single line with skill name and expand hint
- User message rendered separately after skill block
Fixes#894
There's only ever one bindings instance per session, so the Set/Array
approach was unnecessary. Changed from Set<ExtensionErrorListener> to
optional single listener.
Header values in models.json now resolve using the same logic as apiKey:
- Environment variable names are resolved to their values
- Shell commands prefixed with ! are executed
- Literal values are used directly
This is a minor breaking change: if a header value accidentally matches
an env var name, it will now resolve to that env var's value.
Fixes#909