Add an extension that scans .claude/rules/ folder for project-specific
rules and lists them in the system prompt. The agent can then load
relevant rules using the read tool when needed.
SettingsManager was created after extension loading, so extensions
defined in settings.json were never loaded. Move SettingsManager.create
before discoverAndLoadExtensions and merge settings extensions with
CLI --extension args.
Previously the system prompt was converted to an input message in convertMessages,
then stripped out by filterPiSystemPrompts. Now the system prompt is passed directly
to transformRequestBody and appended after CODEX_PI_BRIDGE in the bridge message.
- Accept ExtensionFactory[] for inline extensions (merged with discovery)
- Mark preloadedExtensions as @internal (CLI implementation detail)
- Update sdk.md with inline extension example
- Update CHANGELOG
- Auto-migrate commands/ to prompts/ on startup
- Warn if hooks/ or tools/ directories contain custom extensions
- Show deprecation warnings in interactive mode with keypress to continue
- Update CHANGELOG and docs with full migration guide
Breaking changes:
- Settings: 'hooks' and 'customTools' arrays replaced with 'extensions'
- CLI: '--hook' and '--tool' flags replaced with '--extension' / '-e'
- API: HookMessage renamed to CustomMessage, role 'hookMessage' to 'custom'
- API: FileSlashCommand renamed to PromptTemplate
- API: discoverSlashCommands() renamed to discoverPromptTemplates()
- Directories: commands/ renamed to prompts/ for prompt templates
Migration:
- Session version bumped to 3 (auto-migrates v2 sessions)
- Old 'hookMessage' role entries converted to 'custom'
Structural changes:
- src/core/hooks/ and src/core/custom-tools/ merged into src/core/extensions/
- src/core/slash-commands.ts renamed to src/core/prompt-templates.ts
- examples/hooks/ and examples/custom-tools/ merged into examples/extensions/
- docs/hooks.md and docs/custom-tools.md merged into docs/extensions.md
New test coverage:
- test/extensions-runner.test.ts (10 tests)
- test/extensions-discovery.test.ts (26 tests)
- test/prompt-templates.test.ts
Discovery rules:
1. extensions/*.ts or *.js - direct files
2. extensions/*/index.ts or index.js - subdirectory with index
3. extensions/*/package.json with pi field - load declared paths
No recursion beyond one level. Complex packages use package.json manifest.
Added PiManifest type for future theme/skill bundling support.
17 tests covering all discovery scenarios.
refs #454
New src/core/extensions/ directory with:
- types.ts: merged types from hooks and custom-tools
- loader.ts: single loader for extensions
- runner.ts: ExtensionRunner for event emission
- wrapper.ts: tool wrapping utilities
- index.ts: exports
Key changes from old system:
- Single ExtensionAPI with registerTool() for LLM-callable tools
- Tools use ExtensionContext (has UI access)
- No onSession callback on tools (use pi.on events instead)
refs #454
- event-bus.ts: await async handlers to catch errors properly
- agent-session.ts: clear _pendingNextTurnMessages on newSession/switchSession/branch
- sdk.ts: make eventBus first (required) param for discoverHooks/discoverCustomTools
- docs/sdk.md: document eventBus sharing pattern for hook/tool communication
* feat(coding-agent): add event bus for tool/hook communication
Adds pi.events API enabling custom tools and hooks to communicate via
pub/sub. Tools can emit events, hooks can listen. Shared EventBus instance
created per session in createAgentSession().
- EventBus interface with emit() and on() methods
- on() returns unsubscribe function
- Threaded through hook and tool loaders
- Documented in hooks.md and custom-tools.md
* fix(coding-agent): wrap event handlers to catch errors
* docs: note async handler error handling for event bus
* feat(coding-agent): add sendMessage to tools, nextTurn delivery mode
- Custom tools now have pi.sendMessage() for direct agent notifications
- New deliverAs: 'nextTurn' queues messages for next user prompt
- Fix: hooks and tools now share the same eventBus (was isolated before)
* fix(coding-agent): nextTurn delivery should always queue, even when streaming
The Hook API features (registerFlag, registerShortcut, setWidget, getActiveTools,
plan-mode.ts) were incorrectly listed under 0.32.2 but actually shipped in 0.34.0.
- Added SymbolKey type with 32 symbol keys
- Added symbol key constants to Key helper (Key.backtick, Key.comma, Key.period, etc.)
- Updated matchesKey() and parseKey() to handle symbol key input
- Added documentation in coding-agent README with examples