New Features
- Session runtime API:
createAgentSessionRuntime()andAgentSessionRuntimeprovide a closure-based runtime that recreates cwd-bound services and session config on every session switch. Startup,/new,/resume,/fork, and import all use the same creation path. See docs/sdk.md and examples/sdk/13-session-runtime.ts. - Label timestamps in
/tree: Toggle timestamps on tree entries withShift+T, with smart date formatting and timestamp preservation through branching (#2691 by @w-winter) defineTool()helper: Create standalone custom tool definitions with full TypeScript parameter type inference, no manual casts needed (#2746). See docs/extensions.md.- Unified diagnostics: Arg parsing, service creation, session option resolution, and resource loading all return structured diagnostics (
info/warning/error) instead of logging or exiting. The app layer decides presentation and exit behavior.
Breaking Changes
- Removed extension post-transition events
session_switchandsession_fork. Usesession_startwithevent.reason("startup" | "reload" | "new" | "resume" | "fork"). For"new","resume", and"fork",session_startincludespreviousSessionFile. - Removed session-replacement methods from
AgentSession. UseAgentSessionRuntimefornewSession(),switchSession(),fork(), andimportFromJsonl(). Cross-cwd session replacement rebuilds all cwd-bound runtime state and replaces the liveAgentSessioninstance. - Removed
session_directoryfrom extension and settings APIs. - Unknown single-dash CLI flags (e.g.
-s) now produce an error instead of being silently ignored.
Migration: Extensions
Before:
pi.on("session_switch", async (event, ctx) => { ... });
pi.on("session_fork", async (_event, ctx) => { ... });After:
pi.on("session_start", async (event, ctx) => {
// event.reason: "startup" | "reload" | "new" | "resume" | "fork"
// event.previousSessionFile: set for "new", "resume", "fork"
});Migration: SDK session replacement
Before:
await session.newSession();
await session.switchSession("/path/to/session.jsonl");After:
import {
type CreateAgentSessionRuntimeFactory,
createAgentSessionFromServices,
createAgentSessionRuntime,
createAgentSessionServices,
getAgentDir,
SessionManager,
} from "@mariozechner/pi-coding-agent";
const createRuntime: CreateAgentSessionRuntimeFactory = async ({ cwd, sessionManager, sessionStartEvent }) => {
const services = await createAgentSessionServices({ cwd });
return {
...(await createAgentSessionFromServices({ services, sessionManager, sessionStartEvent })),
services,
diagnostics: services.diagnostics,
};
};
const runtime = await createAgentSessionRuntime(createRuntime, {
cwd: process.cwd(),
agentDir: getAgentDir(),
sessionManager: SessionManager.create(process.cwd()),
});
await runtime.newSession();
await runtime.switchSession("/path/to/session.jsonl");
await runtime.fork("entry-id");
// After replacement, runtime.session is the new live session.
// Rebind any session-local subscriptions or extension bindings.Added
-
Added
createAgentSessionRuntime()andAgentSessionRuntimefor runtime-backed session replacement. The runtime takes aCreateAgentSessionRuntimeFactoryclosure that closes over process-global fixed inputs and recreates cwd-bound services and session config for each effective cwd. Startup and later/new,/resume,/fork, import all use the same factory. -
Added unified diagnostics model (
info/warning/error) for arg parsing, service creation, session option resolution, and resource loading. Creation logic no longer logs or exits. The app layer decides presentation and exit behavior. -
Added error diagnostics for missing explicit CLI resource paths (
-e,--skill,--prompt-template,--theme) -
Added
defineTool()so standalone and array-based custom tool definitions keep inferred parameter types without manual casts (#2746) -
Added label timestamps to the session tree with a
Shift+Ttoggle in/tree, smart date formatting, and timestamp preservation through branching (#2691 by @w-winter)
Fixed
- Fixed startup resource loading to reuse the initial
ResourceLoaderfor the first runtime, so extensions are not loaded twice before session startup andsession_starthandlers still fire for singleton-style extensions (#2766) - Fixed retry settlement so retried agent runs wait for the full retry cycle to complete before declaring idle, preventing stale state after transient errors
- Fixed theme
exportcolors to resolve theme variables the same way ascolors, so/exportHTML backgrounds now honor entries likepageBg: "base"instead of requiring inline hex values (#2707) - Fixed Bedrock throttling errors being misidentified as context overflow, causing unnecessary compaction instead of retry (#2699 by @xu0o0)
- Added tool streaming support for newer Z.ai models (#2732 by @kaofelix)