@mariozechner/pi-coding-agent 0.27.1 → 0.27.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -192,7 +192,7 @@ interface ToolSessionEvent {
192
192
 
193
193
  **Reasons:**
194
194
  - `start`: Initial session load on startup
195
- - `switch`: User switched to a different session (`/session`)
195
+ - `switch`: User switched to a different session (`/resume`)
196
196
  - `branch`: User branched from a previous message (`/branch`)
197
197
  - `clear`: User cleared the session (`/clear`)
198
198
 
@@ -400,12 +400,12 @@ const factory: CustomToolFactory = (pi) => {
400
400
 
401
401
  ## Examples
402
402
 
403
- See [`examples/custom-tools/todo.ts`](../examples/custom-tools/todo.ts) for a complete example with:
403
+ See [`examples/custom-tools/todo/index.ts`](../examples/custom-tools/todo/index.ts) for a complete example with:
404
404
  - `onSession` for state reconstruction
405
405
  - Custom `renderCall` and `renderResult`
406
406
  - Proper branching support via details storage
407
407
 
408
408
  Test with:
409
409
  ```bash
410
- pi --tool packages/coding-agent/examples/custom-tools/todo.ts
410
+ pi --tool packages/coding-agent/examples/custom-tools/todo/index.ts
411
411
  ```
package/docs/hooks.md CHANGED
@@ -120,7 +120,7 @@ user branches (/branch)
120
120
  ├─► session (reason: "before_branch", can cancel)
121
121
  └─► session (reason: "branch", AFTER branch)
122
122
 
123
- user switches session (/session)
123
+ user switches session (/resume)
124
124
 
125
125
  ├─► session (reason: "before_switch", can cancel)
126
126
  └─► session (reason: "switch", AFTER switch)
@@ -154,13 +154,18 @@ pi.on("session", async (event, ctx) => {
154
154
  if (event.reason === "before_clear") {
155
155
  return { cancel: true };
156
156
  }
157
- // No return needed if not cancelling
157
+
158
+ // For before_branch only: create branch but skip conversation restore
159
+ // (useful for checkpoint hooks that restore files separately)
160
+ if (event.reason === "before_branch") {
161
+ return { skipConversationRestore: true };
162
+ }
158
163
  });
159
164
  ```
160
165
 
161
166
  **Reasons:**
162
167
  - `start`: Initial session load on startup
163
- - `before_switch` / `switch`: User switched sessions (`/session`)
168
+ - `before_switch` / `switch`: User switched sessions (`/resume`)
164
169
  - `before_clear` / `clear`: User cleared the session (`/clear`)
165
170
  - `before_branch` / `branch`: User branched the session (`/branch`)
166
171
  - `shutdown`: Process is exiting (double Ctrl+C, Ctrl+D, or SIGTERM)
package/docs/sdk.md CHANGED
@@ -258,10 +258,16 @@ If no model is provided:
258
258
 
259
259
  ### API Keys
260
260
 
261
+ API key resolution priority:
262
+ 1. `settings.json` apiKeys (e.g., `{ "apiKeys": { "anthropic": "sk-..." } }`)
263
+ 2. Custom providers from `models.json`
264
+ 3. OAuth credentials from `oauth.json`
265
+ 4. Environment variables (`ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, etc.)
266
+
261
267
  ```typescript
262
268
  import { defaultGetApiKey, configureOAuthStorage } from "@mariozechner/pi-coding-agent";
263
269
 
264
- // Default: checks models.json, OAuth, environment variables
270
+ // Default: checks settings.json, models.json, OAuth, environment variables
265
271
  const { session } = await createAgentSession();
266
272
 
267
273
  // Custom resolver
@@ -271,7 +277,7 @@ const { session } = await createAgentSession({
271
277
  if (model.provider === "anthropic") {
272
278
  return process.env.MY_ANTHROPIC_KEY;
273
279
  }
274
- // Fall back to default
280
+ // Fall back to default (pass settingsManager for settings.json lookup)
275
281
  return defaultGetApiKey()(model);
276
282
  },
277
283
  });
@@ -203,6 +203,7 @@ async function runSingleAgent(
203
203
  agents: AgentConfig[],
204
204
  agentName: string,
205
205
  task: string,
206
+ cwd: string | undefined,
206
207
  step: number | undefined,
207
208
  signal: AbortSignal | undefined,
208
209
  onUpdate: OnUpdateCallback | undefined,
@@ -263,7 +264,7 @@ async function runSingleAgent(
263
264
  let wasAborted = false;
264
265
 
265
266
  const exitCode = await new Promise<number>((resolve) => {
266
- const proc = spawn("pi", args, { cwd: pi.cwd, shell: false, stdio: ["ignore", "pipe", "pipe"] });
267
+ const proc = spawn("pi", args, { cwd: cwd ?? pi.cwd, shell: false, stdio: ["ignore", "pipe", "pipe"] });
267
268
  let buffer = "";
268
269
 
269
270
  const processLine = (line: string) => {
@@ -338,11 +339,13 @@ async function runSingleAgent(
338
339
  const TaskItem = Type.Object({
339
340
  agent: Type.String({ description: "Name of the agent to invoke" }),
340
341
  task: Type.String({ description: "Task to delegate to the agent" }),
342
+ cwd: Type.Optional(Type.String({ description: "Working directory for the agent process" })),
341
343
  });
342
344
 
343
345
  const ChainItem = Type.Object({
344
346
  agent: Type.String({ description: "Name of the agent to invoke" }),
345
347
  task: Type.String({ description: "Task with optional {previous} placeholder for prior output" }),
348
+ cwd: Type.Optional(Type.String({ description: "Working directory for the agent process" })),
346
349
  });
347
350
 
348
351
  const AgentScopeSchema = StringEnum(["user", "project", "both"] as const, {
@@ -357,6 +360,7 @@ const SubagentParams = Type.Object({
357
360
  chain: Type.Optional(Type.Array(ChainItem, { description: "Array of {agent, task} for sequential execution" })),
358
361
  agentScope: Type.Optional(AgentScopeSchema),
359
362
  confirmProjectAgents: Type.Optional(Type.Boolean({ description: "Prompt before running project-local agents. Default: true.", default: true })),
363
+ cwd: Type.Optional(Type.String({ description: "Working directory for the agent process (single mode)" })),
360
364
  });
361
365
 
362
366
  const factory: CustomToolFactory = (pi) => {
@@ -441,7 +445,7 @@ const factory: CustomToolFactory = (pi) => {
441
445
  }
442
446
  } : undefined;
443
447
 
444
- const result = await runSingleAgent(pi, agents, step.agent, taskWithContext, i + 1, signal, chainUpdate, makeDetails("chain"));
448
+ const result = await runSingleAgent(pi, agents, step.agent, taskWithContext, step.cwd, i + 1, signal, chainUpdate, makeDetails("chain"));
445
449
  results.push(result);
446
450
 
447
451
  const isError = result.exitCode !== 0 || result.stopReason === "error" || result.stopReason === "aborted";
@@ -486,7 +490,7 @@ const factory: CustomToolFactory = (pi) => {
486
490
 
487
491
  const results = await mapWithConcurrencyLimit(params.tasks, MAX_CONCURRENCY, async (t, index) => {
488
492
  const result = await runSingleAgent(
489
- pi, agents, t.agent, t.task, undefined, signal,
493
+ pi, agents, t.agent, t.task, t.cwd, undefined, signal,
490
494
  // Per-task update callback
491
495
  (partial) => {
492
496
  if (partial.details?.results[0]) {
@@ -511,7 +515,7 @@ const factory: CustomToolFactory = (pi) => {
511
515
  }
512
516
 
513
517
  if (params.agent && params.task) {
514
- const result = await runSingleAgent(pi, agents, params.agent, params.task, undefined, signal, onUpdate, makeDetails("single"));
518
+ const result = await runSingleAgent(pi, agents, params.agent, params.task, params.cwd, undefined, signal, onUpdate, makeDetails("single"));
515
519
  const isError = result.exitCode !== 0 || result.stopReason === "error" || result.stopReason === "aborted";
516
520
  if (isError) {
517
521
  const errorMsg = result.errorMessage || result.stderr || getFinalOutput(result.messages) || "(no output)";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mariozechner/pi-coding-agent",
3
- "version": "0.27.1",
3
+ "version": "0.27.3",
4
4
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
5
5
  "type": "module",
6
6
  "piConfig": {
@@ -39,9 +39,9 @@
39
39
  "prepublishOnly": "npm run clean && npm run build"
40
40
  },
41
41
  "dependencies": {
42
- "@mariozechner/pi-agent-core": "^0.27.1",
43
- "@mariozechner/pi-ai": "^0.27.1",
44
- "@mariozechner/pi-tui": "^0.27.1",
42
+ "@mariozechner/pi-agent-core": "^0.27.3",
43
+ "@mariozechner/pi-ai": "^0.27.3",
44
+ "@mariozechner/pi-tui": "^0.27.3",
45
45
  "chalk": "^5.5.0",
46
46
  "cli-highlight": "^2.1.11",
47
47
  "diff": "^8.0.2",