@phi-code-admin/phi-code 0.84.2 → 0.86.0

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.
Files changed (75) hide show
  1. package/CHANGELOG.md +100 -0
  2. package/README.md +95 -126
  3. package/agents/code.md +1 -0
  4. package/agents/explore.md +11 -5
  5. package/agents/plan.md +18 -3
  6. package/agents/review.md +18 -7
  7. package/agents/test.md +1 -0
  8. package/config/routing.example.json +129 -0
  9. package/config/routing.schema.json +58 -0
  10. package/dist/cli/args.d.ts.map +1 -1
  11. package/dist/cli/args.js +1 -1
  12. package/dist/cli/args.js.map +1 -1
  13. package/dist/config.d.ts.map +1 -1
  14. package/dist/config.js +1 -1
  15. package/dist/config.js.map +1 -1
  16. package/dist/core/sdk.d.ts.map +1 -1
  17. package/dist/core/sdk.js +3 -3
  18. package/dist/core/sdk.js.map +1 -1
  19. package/dist/core/system-prompt.d.ts.map +1 -1
  20. package/dist/core/system-prompt.js +6 -6
  21. package/dist/core/system-prompt.js.map +1 -1
  22. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  23. package/dist/modes/interactive/components/config-selector.js +1 -1
  24. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  25. package/dist/modes/interactive/interactive-mode.d.ts +2 -2
  26. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  27. package/dist/modes/interactive/interactive-mode.js +32 -30
  28. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  29. package/dist/package-manager-cli.d.ts.map +1 -1
  30. package/dist/package-manager-cli.js +9 -8
  31. package/dist/package-manager-cli.js.map +1 -1
  32. package/dist/utils/pi-user-agent.d.ts.map +1 -1
  33. package/dist/utils/pi-user-agent.js +4 -1
  34. package/dist/utils/pi-user-agent.js.map +1 -1
  35. package/dist/utils/version-check.d.ts +5 -5
  36. package/dist/utils/version-check.d.ts.map +1 -1
  37. package/dist/utils/version-check.js +13 -8
  38. package/dist/utils/version-check.js.map +1 -1
  39. package/docs/compaction.md +11 -11
  40. package/docs/custom-provider.md +4 -4
  41. package/docs/development.md +2 -2
  42. package/docs/extensions.md +47 -47
  43. package/docs/fork-policy.md +63 -0
  44. package/docs/index.md +7 -7
  45. package/docs/json.md +3 -3
  46. package/docs/keybindings.md +5 -5
  47. package/docs/models.md +6 -6
  48. package/docs/packages.md +37 -37
  49. package/docs/prompt-templates.md +4 -4
  50. package/docs/providers.md +9 -9
  51. package/docs/quickstart.md +25 -25
  52. package/docs/rpc.md +3 -3
  53. package/docs/sdk.md +34 -34
  54. package/docs/session-format.md +4 -4
  55. package/docs/sessions.md +11 -11
  56. package/docs/settings.md +11 -11
  57. package/docs/shell-aliases.md +2 -2
  58. package/docs/skills.md +9 -9
  59. package/docs/terminal-setup.md +7 -7
  60. package/docs/termux.md +6 -6
  61. package/docs/themes.md +9 -9
  62. package/docs/tmux.md +3 -3
  63. package/docs/tui.md +8 -8
  64. package/docs/usage.md +40 -40
  65. package/docs/windows.md +2 -2
  66. package/examples/sdk/12-full-control.ts +1 -1
  67. package/extensions/phi/agents.ts +5 -113
  68. package/extensions/phi/models.ts +170 -49
  69. package/extensions/phi/orchestrator.ts +44 -37
  70. package/extensions/phi/providers/agent-def.ts +128 -0
  71. package/extensions/phi/providers/live-models.ts +31 -1
  72. package/extensions/phi/providers/opencode-go.ts +7 -3
  73. package/extensions/phi/setup.ts +9 -0
  74. package/extensions/phi/skill-loader.ts +46 -25
  75. package/package.json +2 -1
@@ -1,10 +1,10 @@
1
- > pi can create extensions. Ask it to build one for your use case.
1
+ > phi can create extensions. Ask it to build one for your use case.
2
2
 
3
3
  # Extensions
4
4
 
5
- Extensions are TypeScript modules that extend pi's behavior. They can subscribe to lifecycle events, register custom tools callable by the LLM, add commands, and more.
5
+ Extensions are TypeScript modules that extend phi's behavior. They can subscribe to lifecycle events, register custom tools callable by the LLM, add commands, and more.
6
6
 
7
- > **Placement for /reload:** Put extensions in `~/.pi/agent/extensions/` (global) or `.pi/extensions/` (project-local) for auto-discovery. Use `pi -e ./path.ts` only for quick tests. Extensions in auto-discovered locations can be hot-reloaded with `/reload`.
7
+ > **Placement for /reload:** Put extensions in `~/.phi/agent/extensions/` (global) or `.phi/extensions/` (project-local) for auto-discovery. Use `phi -e ./path.ts` only for quick tests. Extensions in auto-discovered locations can be hot-reloaded with `/reload`.
8
8
 
9
9
  **Key capabilities:**
10
10
  - **Custom tools** - Register tools the LLM can call via `pi.registerTool()`
@@ -54,10 +54,10 @@ See [examples/extensions/](../examples/extensions/) for working implementations.
54
54
 
55
55
  ## Quick Start
56
56
 
57
- Create `~/.pi/agent/extensions/my-extension.ts`:
57
+ Create `~/.phi/agent/extensions/my-extension.ts`:
58
58
 
59
59
  ```typescript
60
- import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
60
+ import type { ExtensionAPI } from "@phi-code-admin/phi-code";
61
61
  import { Type } from "typebox";
62
62
 
63
63
  export default function (pi: ExtensionAPI) {
@@ -102,7 +102,7 @@ export default function (pi: ExtensionAPI) {
102
102
  Test with `--extension` (or `-e`) flag:
103
103
 
104
104
  ```bash
105
- pi -e ./my-extension.ts
105
+ phi -e ./my-extension.ts
106
106
  ```
107
107
 
108
108
  ## Extension Locations
@@ -113,10 +113,10 @@ Extensions are auto-discovered from:
113
113
 
114
114
  | Location | Scope |
115
115
  |----------|-------|
116
- | `~/.pi/agent/extensions/*.ts` | Global (all projects) |
117
- | `~/.pi/agent/extensions/*/index.ts` | Global (subdirectory) |
118
- | `.pi/extensions/*.ts` | Project-local |
119
- | `.pi/extensions/*/index.ts` | Project-local (subdirectory) |
116
+ | `~/.phi/agent/extensions/*.ts` | Global (all projects) |
117
+ | `~/.phi/agent/extensions/*/index.ts` | Global (subdirectory) |
118
+ | `.phi/extensions/*.ts` | Project-local |
119
+ | `.phi/extensions/*/index.ts` | Project-local (subdirectory) |
120
120
 
121
121
  Additional paths via `settings.json`:
122
122
 
@@ -133,20 +133,20 @@ Additional paths via `settings.json`:
133
133
  }
134
134
  ```
135
135
 
136
- To share extensions via npm or git as pi packages, see [packages.md](packages.md).
136
+ To share extensions via npm or git as phi packages, see [packages.md](packages.md).
137
137
 
138
138
  ## Available Imports
139
139
 
140
140
  | Package | Purpose |
141
141
  |---------|---------|
142
- | `@earendil-works/pi-coding-agent` | Extension types (`ExtensionAPI`, `ExtensionContext`, events) |
142
+ | `@phi-code-admin/phi-code` | Extension types (`ExtensionAPI`, `ExtensionContext`, events) |
143
143
  | `typebox` | Schema definitions for tool parameters |
144
144
  | `@earendil-works/pi-ai` | AI utilities (`StringEnum` for Google-compatible enums) |
145
145
  | `@earendil-works/pi-tui` | TUI components for custom rendering |
146
146
 
147
147
  npm dependencies work too. Add a `package.json` next to your extension (or in a parent directory), run `npm install`, and imports from `node_modules/` are resolved automatically.
148
148
 
149
- For distributed pi packages installed with `pi install` (npm or git), runtime deps must be in `dependencies`. Package installation uses production installs (`npm install --omit=dev`) by default, so `devDependencies` are not available at runtime; when `npmCommand` is configured, git packages use plain `install` for compatibility with wrappers.
149
+ For distributed phi packages installed with `phi install` (npm or git), runtime deps must be in `dependencies`. Package installation uses production installs (`npm install --omit=dev`) by default, so `devDependencies` are not available at runtime; when `npmCommand` is configured, git packages use plain `install` for compatibility with wrappers.
150
150
 
151
151
  Node.js built-ins (`node:fs`, `node:path`, etc.) are also available.
152
152
 
@@ -155,7 +155,7 @@ Node.js built-ins (`node:fs`, `node:path`, etc.) are also available.
155
155
  An extension exports a default factory function that receives `ExtensionAPI`. The factory can be synchronous or asynchronous:
156
156
 
157
157
  ```typescript
158
- import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
158
+ import type { ExtensionAPI } from "@phi-code-admin/phi-code";
159
159
 
160
160
  export default function (pi: ExtensionAPI) {
161
161
  // Subscribe to events
@@ -177,14 +177,14 @@ export default function (pi: ExtensionAPI) {
177
177
 
178
178
  Extensions are loaded via [jiti](https://github.com/unjs/jiti), so TypeScript works without compilation.
179
179
 
180
- If the factory returns a `Promise`, pi awaits it before continuing startup. That means async initialization completes before `session_start`, before `resources_discover`, and before provider registrations queued via `pi.registerProvider()` are flushed.
180
+ If the factory returns a `Promise`, phi awaits it before continuing startup. That means async initialization completes before `session_start`, before `resources_discover`, and before provider registrations queued via `pi.registerProvider()` are flushed.
181
181
 
182
182
  ### Async factory functions
183
183
 
184
184
  Use an async factory for one-time startup work such as fetching remote configuration or dynamically discovering available models.
185
185
 
186
186
  ```typescript
187
- import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
187
+ import type { ExtensionAPI } from "@phi-code-admin/phi-code";
188
188
 
189
189
  export default async function (pi: ExtensionAPI) {
190
190
  const response = await fetch("http://localhost:1234/v1/models");
@@ -214,21 +214,21 @@ export default async function (pi: ExtensionAPI) {
214
214
  }
215
215
  ```
216
216
 
217
- This pattern makes the fetched models available during normal startup and to `pi --list-models`.
217
+ This pattern makes the fetched models available during normal startup and to `phi --list-models`.
218
218
 
219
219
  ### Extension Styles
220
220
 
221
221
  **Single file** - simplest, for small extensions:
222
222
 
223
223
  ```
224
- ~/.pi/agent/extensions/
224
+ ~/.phi/agent/extensions/
225
225
  └── my-extension.ts
226
226
  ```
227
227
 
228
228
  **Directory with index.ts** - for multi-file extensions:
229
229
 
230
230
  ```
231
- ~/.pi/agent/extensions/
231
+ ~/.phi/agent/extensions/
232
232
  └── my-extension/
233
233
  ├── index.ts # Entry point (exports default function)
234
234
  ├── tools.ts # Helper module
@@ -238,7 +238,7 @@ This pattern makes the fetched models available during normal startup and to `pi
238
238
  **Package with dependencies** - for extensions that need npm packages:
239
239
 
240
240
  ```
241
- ~/.pi/agent/extensions/
241
+ ~/.phi/agent/extensions/
242
242
  └── my-extension/
243
243
  ├── package.json # Declares dependencies and entry points
244
244
  ├── package-lock.json
@@ -268,7 +268,7 @@ Run `npm install` in the extension directory, then imports from `node_modules/`
268
268
  ### Lifecycle Overview
269
269
 
270
270
  ```
271
- pi starts
271
+ phi starts
272
272
 
273
273
  ├─► session_start { reason: "startup" }
274
274
  └─► resources_discover { reason: "startup" }
@@ -385,7 +385,7 @@ pi.on("session_before_switch", async (event, ctx) => {
385
385
  });
386
386
  ```
387
387
 
388
- After a successful switch or new-session action, pi emits `session_shutdown` for the old extension instance, reloads and rebinds extensions for the new session, then emits `session_start` with `reason: "new" | "resume"` and `previousSessionFile`.
388
+ After a successful switch or new-session action, phi emits `session_shutdown` for the old extension instance, reloads and rebinds extensions for the new session, then emits `session_start` with `reason: "new" | "resume"` and `previousSessionFile`.
389
389
  Do cleanup work in `session_shutdown`, then reestablish any in-memory state in `session_start`.
390
390
 
391
391
  #### session_before_fork
@@ -402,7 +402,7 @@ pi.on("session_before_fork", async (event, ctx) => {
402
402
  });
403
403
  ```
404
404
 
405
- After a successful fork or clone, pi emits `session_shutdown` for the old extension instance, reloads and rebinds extensions for the new session, then emits `session_start` with `reason: "fork"` and `previousSessionFile`.
405
+ After a successful fork or clone, phi emits `session_shutdown` for the old extension instance, reloads and rebinds extensions for the new session, then emits `session_start` with `reason: "fork"` and `previousSessionFile`.
406
406
  Do cleanup work in `session_shutdown`, then reestablish any in-memory state in `session_start`.
407
407
 
408
408
  #### session_before_compact / session_compact
@@ -496,7 +496,7 @@ pi.on("before_agent_start", async (event, ctx) => {
496
496
  });
497
497
  ```
498
498
 
499
- The `systemPromptOptions` field gives extensions access to the same structured data Pi uses to build the system prompt. This lets you inspect what Pi has loaded — custom prompts, guidelines, tool snippets, context files, skills — without re-discovering resources or re-parsing flags. Use it when your extension needs to make deep, informed changes to the system prompt while respecting user-provided configuration.
499
+ The `systemPromptOptions` field gives extensions access to the same structured data phi uses to build the system prompt. This lets you inspect what phi has loaded — custom prompts, guidelines, tool snippets, context files, skills — without re-discovering resources or re-parsing flags. Use it when your extension needs to make deep, informed changes to the system prompt while respecting user-provided configuration.
500
500
 
501
501
  Inside `before_agent_start`, `event.systemPrompt` and `ctx.getSystemPrompt()` both reflect the chained system prompt as of the current handler. Later `before_agent_start` handlers can still modify it again.
502
502
 
@@ -602,7 +602,7 @@ pi.on("context", async (event, ctx) => {
602
602
 
603
603
  Fired after the provider-specific payload is built, right before the request is sent. Handlers run in extension load order. Returning `undefined` keeps the payload unchanged. Returning any other value replaces the payload for later handlers and for the actual request.
604
604
 
605
- This hook can rewrite provider-level system instructions or remove them entirely. Those payload-level changes are not reflected by `ctx.getSystemPrompt()`, which reports Pi's system prompt string rather than the final serialized provider payload.
605
+ This hook can rewrite provider-level system instructions or remove them entirely. Those payload-level changes are not reflected by `ctx.getSystemPrompt()`, which reports phi's system prompt string rather than the final serialized provider payload.
606
606
 
607
607
  ```typescript
608
608
  pi.on("before_provider_request", (event, ctx) => {
@@ -675,7 +675,7 @@ Use this to update extension UI when `pi.setThinkingLevel()`, model changes, or
675
675
 
676
676
  Fired after `tool_execution_start`, before the tool executes. **Can block.** Use `isToolCallEventType` to narrow and get typed inputs.
677
677
 
678
- Before `tool_call` runs, pi waits for previously emitted Agent events to finish draining through `AgentSession`. This means `ctx.sessionManager` is up to date through the current assistant tool-calling message.
678
+ Before `tool_call` runs, phi waits for previously emitted Agent events to finish draining through `AgentSession`. This means `ctx.sessionManager` is up to date through the current assistant tool-calling message.
679
679
 
680
680
  In the default parallel tool execution mode, sibling tool calls from the same assistant message are preflighted sequentially, then executed concurrently. `tool_call` is not guaranteed to see sibling tool results from that same assistant message in `ctx.sessionManager`.
681
681
 
@@ -688,7 +688,7 @@ Behavior guarantees:
688
688
  - Return values from `tool_call` only control blocking via `{ block: true, reason?: string }`
689
689
 
690
690
  ```typescript
691
- import { isToolCallEventType } from "@earendil-works/pi-coding-agent";
691
+ import { isToolCallEventType } from "@phi-code-admin/phi-code";
692
692
 
693
693
  pi.on("tool_call", async (event, ctx) => {
694
694
  // event.toolName - "bash", "read", "write", "edit", etc.
@@ -724,7 +724,7 @@ export type MyToolInput = Static<typeof myToolSchema>;
724
724
  Use `isToolCallEventType` with explicit type parameters:
725
725
 
726
726
  ```typescript
727
- import { isToolCallEventType } from "@earendil-works/pi-coding-agent";
727
+ import { isToolCallEventType } from "@phi-code-admin/phi-code";
728
728
  import type { MyToolInput } from "my-extension";
729
729
 
730
730
  pi.on("tool_call", (event) => {
@@ -748,7 +748,7 @@ In parallel tool mode, `tool_result` and `tool_execution_end` may interleave in
748
748
  Use `ctx.signal` for nested async work inside the handler. This lets Esc cancel model calls, `fetch()`, and other abort-aware operations started by the extension.
749
749
 
750
750
  ```typescript
751
- import { isBashToolResult } from "@earendil-works/pi-coding-agent";
751
+ import { isBashToolResult } from "@phi-code-admin/phi-code";
752
752
 
753
753
  pi.on("tool_result", async (event, ctx) => {
754
754
  // event.toolName, event.toolCallId, event.input
@@ -776,7 +776,7 @@ pi.on("tool_result", async (event, ctx) => {
776
776
  Fired when user executes `!` or `!!` commands. **Can intercept.**
777
777
 
778
778
  ```typescript
779
- import { createLocalBashOperations } from "@earendil-works/pi-coding-agent";
779
+ import { createLocalBashOperations } from "@phi-code-admin/phi-code";
780
780
 
781
781
  pi.on("user_bash", (event, ctx) => {
782
782
  // event.command - the bash command
@@ -891,7 +891,7 @@ Use this for abort-aware nested work started by extension handlers, for example:
891
891
  - file or process helpers that accept `AbortSignal`
892
892
 
893
893
  `ctx.signal` is typically defined during active turn events such as `tool_call`, `tool_result`, `message_update`, and `turn_end`.
894
- It is usually `undefined` in idle or non-turn contexts such as session events, extension commands, and shortcuts fired while pi is idle.
894
+ It is usually `undefined` in idle or non-turn contexts such as session events, extension commands, and shortcuts fired while phi is idle.
895
895
 
896
896
  ```typescript
897
897
  pi.on("tool_result", async (event, ctx) => {
@@ -957,7 +957,7 @@ ctx.compact({
957
957
 
958
958
  ### ctx.getSystemPrompt()
959
959
 
960
- Returns Pi's current system prompt string.
960
+ Returns phi's current system prompt string.
961
961
 
962
962
  - During `before_agent_start`, this reflects chained system-prompt changes made so far for the current turn.
963
963
  - It does not include later `context` message mutations.
@@ -1087,7 +1087,7 @@ Options:
1087
1087
  To discover available sessions, use the static `SessionManager.list()` or `SessionManager.listAll()` methods:
1088
1088
 
1089
1089
  ```typescript
1090
- import { SessionManager } from "@earendil-works/pi-coding-agent";
1090
+ import { SessionManager } from "@phi-code-admin/phi-code";
1091
1091
 
1092
1092
  pi.registerCommand("switch", {
1093
1093
  description: "Switch to another session",
@@ -1181,7 +1181,7 @@ Tools run with `ExtensionContext`, so they cannot call `ctx.reload()` directly.
1181
1181
  Example tool the LLM can call to trigger reload:
1182
1182
 
1183
1183
  ```typescript
1184
- import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
1184
+ import type { ExtensionAPI } from "@phi-code-admin/phi-code";
1185
1185
  import { Type } from "typebox";
1186
1186
 
1187
1187
  export default function (pi: ExtensionAPI) {
@@ -1373,7 +1373,7 @@ Labels persist in the session and survive restarts. Use them to mark important p
1373
1373
 
1374
1374
  Register a command.
1375
1375
 
1376
- If multiple extensions register the same command name, pi keeps them all and assigns numeric invocation suffixes in load order, for example `/review:1` and `/review:2`.
1376
+ If multiple extensions register the same command name, phi keeps them all and assigns numeric invocation suffixes in load order, for example `/review:1` and `/review:2`.
1377
1377
 
1378
1378
  ```typescript
1379
1379
  pi.registerCommand("stats", {
@@ -1544,7 +1544,7 @@ Register or override a model provider dynamically. Useful for proxies, custom en
1544
1544
 
1545
1545
  Calls made during the extension factory function are queued and applied once the runner initialises. Calls made after that — for example from a command handler following a user setup flow — take effect immediately without requiring a `/reload`.
1546
1546
 
1547
- If you need to discover models from a remote endpoint, prefer an async extension factory over deferring the fetch to `session_start`. pi waits for the factory before startup continues, so the registered models are available immediately, including to `pi --list-models`.
1547
+ If you need to discover models from a remote endpoint, prefer an async extension factory over deferring the fetch to `session_start`. phi waits for the factory before startup continues, so the registered models are available immediately, including to `phi --list-models`.
1548
1548
 
1549
1549
  ```typescript
1550
1550
  // Register a new provider with custom models
@@ -1678,7 +1678,7 @@ Pass the real target file path to `withFileMutationQueue()`, not the raw user ar
1678
1678
  Queue the entire mutation window on that target path. That includes read-modify-write logic, not just the final write.
1679
1679
 
1680
1680
  ```typescript
1681
- import { withFileMutationQueue } from "@earendil-works/pi-coding-agent";
1681
+ import { withFileMutationQueue } from "@phi-code-admin/phi-code";
1682
1682
  import { mkdir, readFile, writeFile } from "node:fs/promises";
1683
1683
  import { dirname, resolve } from "node:path";
1684
1684
 
@@ -1774,7 +1774,7 @@ async execute(toolCallId, params) {
1774
1774
 
1775
1775
  **Important:** Use `StringEnum` from `@earendil-works/pi-ai` for string enums. `Type.Union`/`Type.Literal` doesn't work with Google's API.
1776
1776
 
1777
- **Argument preparation:** `prepareArguments(args)` is optional. If defined, it runs before schema validation and before `execute()`. Use it to mimic an older accepted input shape when pi resumes an older session whose stored tool call arguments no longer match the current schema. Return the object you want validated against `parameters`. Keep the public schema strict. Do not add deprecated compatibility fields to `parameters` just to keep old resumed sessions working.
1777
+ **Argument preparation:** `prepareArguments(args)` is optional. If defined, it runs before schema validation and before `execute()`. Use it to mimic an older accepted input shape when phi resumes an older session whose stored tool call arguments no longer match the current schema. Return the object you want validated against `parameters`. Keep the public schema strict. Do not add deprecated compatibility fields to `parameters` just to keep old resumed sessions working.
1778
1778
 
1779
1779
  Example: an older session may contain an `edit` tool call with top-level `oldText` and `newText`, while the current schema only accepts `edits: [{ oldText, newText }]`.
1780
1780
 
@@ -1827,13 +1827,13 @@ Extensions can override built-in tools (`read`, `bash`, `edit`, `write`, `grep`,
1827
1827
 
1828
1828
  ```bash
1829
1829
  # Extension's read tool replaces built-in read
1830
- pi -e ./tool-override.ts
1830
+ phi -e ./tool-override.ts
1831
1831
  ```
1832
1832
 
1833
1833
  Alternatively, use `--no-builtin-tools` to start without any built-in tools while keeping extension tools enabled:
1834
1834
  ```bash
1835
1835
  # No built-in tools, only extension tools
1836
- pi --no-builtin-tools -e ./my-extension.ts
1836
+ phi --no-builtin-tools -e ./my-extension.ts
1837
1837
  ```
1838
1838
 
1839
1839
  See [examples/extensions/tool-override.ts](../examples/extensions/tool-override.ts) for a complete example that overrides `read` with logging and access control.
@@ -1858,7 +1858,7 @@ Built-in tool implementations:
1858
1858
  Built-in tools support pluggable operations for delegating to remote systems (SSH, containers, etc.):
1859
1859
 
1860
1860
  ```typescript
1861
- import { createReadTool, createBashTool, type ReadOperations } from "@earendil-works/pi-coding-agent";
1861
+ import { createReadTool, createBashTool, type ReadOperations } from "@phi-code-admin/phi-code";
1862
1862
 
1863
1863
  // Create tool with custom operations
1864
1864
  const remoteRead = createReadTool(cwd, {
@@ -1884,12 +1884,12 @@ pi.registerTool({
1884
1884
 
1885
1885
  **Operations interfaces:** `ReadOperations`, `WriteOperations`, `EditOperations`, `BashOperations`, `LsOperations`, `GrepOperations`, `FindOperations`
1886
1886
 
1887
- For `user_bash`, extensions can reuse pi's local shell backend via `createLocalBashOperations()` instead of reimplementing local process spawning, shell resolution, and process-tree termination.
1887
+ For `user_bash`, extensions can reuse phi's local shell backend via `createLocalBashOperations()` instead of reimplementing local process spawning, shell resolution, and process-tree termination.
1888
1888
 
1889
1889
  The bash tool also supports a spawn hook to adjust the command, cwd, or env before execution:
1890
1890
 
1891
1891
  ```typescript
1892
- import { createBashTool } from "@earendil-works/pi-coding-agent";
1892
+ import { createBashTool } from "@phi-code-admin/phi-code";
1893
1893
 
1894
1894
  const bashTool = createBashTool(cwd, {
1895
1895
  spawnHook: ({ command, cwd, env }) => ({
@@ -1919,7 +1919,7 @@ import {
1919
1919
  formatSize, // Human-readable size (e.g., "50KB", "1.5MB")
1920
1920
  DEFAULT_MAX_BYTES, // 50KB
1921
1921
  DEFAULT_MAX_LINES, // 2000
1922
- } from "@earendil-works/pi-coding-agent";
1922
+ } from "@phi-code-admin/phi-code";
1923
1923
 
1924
1924
  async execute(toolCallId, params, signal, onUpdate, ctx) {
1925
1925
  const output = await runCommand();
@@ -2055,7 +2055,7 @@ If a slot intentionally has no visible content, return an empty `Component` such
2055
2055
  Use `keyHint()` to display keybinding hints that respect the active keybinding configuration:
2056
2056
 
2057
2057
  ```typescript
2058
- import { keyHint } from "@earendil-works/pi-coding-agent";
2058
+ import { keyHint } from "@phi-code-admin/phi-code";
2059
2059
 
2060
2060
  renderResult(result, { expanded }, theme, context) {
2061
2061
  let text = theme.fg("success", "✓ Done");
@@ -2387,7 +2387,7 @@ See [tui.md](tui.md) for the full `OverlayOptions` API and [overlay-qa-tests.ts]
2387
2387
  Replace the main input editor with a custom implementation (vim mode, emacs mode, etc.):
2388
2388
 
2389
2389
  ```typescript
2390
- import { CustomEditor, type ExtensionAPI } from "@earendil-works/pi-coding-agent";
2390
+ import { CustomEditor, type ExtensionAPI } from "@phi-code-admin/phi-code";
2391
2391
  import { matchesKey } from "@earendil-works/pi-tui";
2392
2392
 
2393
2393
  class VimEditor extends CustomEditor {
@@ -2487,7 +2487,7 @@ theme.strikethrough(text)
2487
2487
  For syntax highlighting in custom tool renderers:
2488
2488
 
2489
2489
  ```typescript
2490
- import { highlightCode, getLanguageFromPath } from "@earendil-works/pi-coding-agent";
2490
+ import { highlightCode, getLanguageFromPath } from "@phi-code-admin/phi-code";
2491
2491
 
2492
2492
  // Highlight code with explicit language
2493
2493
  const highlighted = highlightCode("const x = 1;", "typescript", theme);
@@ -0,0 +1,63 @@
1
+ # Fork policy — staying mergeable with upstream Pi
2
+
3
+ phi-code is a fork of [pi-mono](https://github.com/earendil-works/pi-mono)
4
+ (`packages/coding-agent` = upstream's coding agent). This document defines
5
+ exactly **what is rebranded and what deliberately stays "pi"**, so upstream
6
+ updates can be merged with minimal conflicts and nobody "finishes" a rename
7
+ that would make every future merge painful.
8
+
9
+ ## The one rule
10
+
11
+ > Rebrand **outputs** (what users see), keep **identifiers** (what code sees).
12
+
13
+ All branding flows from `packages/coding-agent/src/config.ts`, driven by
14
+ `package.json`'s `piConfig` block:
15
+
16
+ ```json
17
+ "piConfig": { "name": "phi", "configDir": ".phi" }
18
+ ```
19
+
20
+ which resolves to `APP_NAME = "phi"`, `APP_TITLE`, `CONFIG_DIR_NAME = ".phi"`,
21
+ `PACKAGE_NAME = "@phi-code-admin/phi-code"`. **New user-facing strings must
22
+ use these constants, never a hardcoded "pi" or "phi".**
23
+
24
+ ## Rebranded (must say phi)
25
+
26
+ | Surface | Where |
27
+ |---|---|
28
+ | Binary, config dir | `phi`, `~/.phi/` (via `piConfig`) |
29
+ | Update check + `phi update` | npm registry `@phi-code-admin/phi-code` (`src/utils/version-check.ts`, `src/package-manager-cli.ts`) |
30
+ | Update notifications, changelog link | `uglyswap/phi-code` changelog (`interactive-mode.ts`) |
31
+ | HTTP User-Agent | `phi/<version>` — `APP_NAME`-driven (`src/utils/pi-user-agent.ts`) |
32
+ | OpenRouter attribution headers | `phi-code` (`src/core/sdk.ts`) |
33
+ | Telemetry | **removed** — phi-code sends no install pings |
34
+ | TUI messages, `--help`, docs examples | `phi` commands, `~/.phi/` paths |
35
+ | npm README / CHANGELOG | phi-code |
36
+
37
+ ## Deliberately kept as-is (do NOT rename)
38
+
39
+ | Item | Why |
40
+ |---|---|
41
+ | `PI_*` env vars (`PI_OFFLINE`, `PI_SKIP_VERSION_CHECK`, `PI_TELEMETRY`, …) | Backwards compat + documented everywhere; renaming breaks users and every upstream merge. `PHI_*` additions are fine as aliases. |
42
+ | Internal identifiers (`getPiUserAgent`, `piConfig`, `pi-user-agent.ts`, type names, comments) | Pure code-level names; renaming guarantees merge conflicts for zero user value. |
43
+ | `pi.dev/session/` share viewer (`DEFAULT_SHARE_VIEWER_URL`) | `/share` uploads a gist; the upstream viewer renders any pi-format session. Overridable via `PI_SHARE_VIEWER_URL`. |
44
+ | pi-mono links in `src/migrations.ts` | Historical migration guides that only exist upstream. |
45
+ | `examples/` referencing pi | Upstream examples; kept verbatim to merge cleanly. |
46
+ | `@mariozechner/*` deps (web-ui, jiti) | Upstream packages consumed as-is. |
47
+
48
+ ## Merging upstream
49
+
50
+ 1. `git remote add upstream https://github.com/earendil-works/pi-mono.git && git fetch upstream`
51
+ 2. Merge/cherry-pick into a branch. Conflicts should concentrate in the few
52
+ rebranded files listed above — everything else is untouched by design.
53
+ 3. After merging, run the guard-rails: `npm run check && npm test`. The test
54
+ suite pins the phi behaviors (registry-based update check, `phi/` UA,
55
+ phi-code attribution headers, routing example sync), so an upstream change
56
+ that silently reverts a rebrand point fails CI instead of shipping.
57
+
58
+ ## Fork-owned additions (no upstream counterpart)
59
+
60
+ `extensions/phi/**` (orchestrator, models refresh, setup, memory, skills…),
61
+ `agents/`, `skills/`, `config/`, the `sigma-*` packages, and the browser and
62
+ camoufox packages are phi-code territory: normal engineering rules apply,
63
+ no merge constraints.
package/docs/index.md CHANGED
@@ -1,10 +1,10 @@
1
- # Pi Documentation
1
+ # phi Documentation
2
2
 
3
- Pi is a minimal terminal coding harness. It is designed to stay small at the core while being extended through TypeScript extensions, skills, prompt templates, themes, and pi packages.
3
+ phi is a minimal terminal coding harness. It is designed to stay small at the core while being extended through TypeScript extensions, skills, prompt templates, themes, and phi packages.
4
4
 
5
5
  ## Quick start
6
6
 
7
- On linux or mac you can install Pi with curl:
7
+ On linux or mac you can install phi with curl:
8
8
 
9
9
  ```bash
10
10
  curl -fsSL https://pi.dev/install.sh | sh
@@ -13,7 +13,7 @@ curl -fsSL https://pi.dev/install.sh | sh
13
13
  Or alternatively with npm:
14
14
 
15
15
  ```bash
16
- npm install -g @earendil-works/pi-coding-agent
16
+ npm install -g @phi-code-admin/phi-code
17
17
  ```
18
18
 
19
19
  Then run it in a project directory:
@@ -29,7 +29,7 @@ For the full first-run flow, see [Quickstart](quickstart.md).
29
29
  ## Start here
30
30
 
31
31
  - [Quickstart](quickstart.md) - install, authenticate, and run a first session.
32
- - [Using Pi](usage.md) - interactive mode, slash commands, context files, and CLI reference.
32
+ - [Using phi](usage.md) - interactive mode, slash commands, context files, and CLI reference.
33
33
  - [Providers](providers.md) - subscription and API-key setup for built-in providers.
34
34
  - [Settings](settings.md) - global and project settings.
35
35
  - [Keybindings](keybindings.md) - default shortcuts and custom keybindings.
@@ -42,13 +42,13 @@ For the full first-run flow, see [Quickstart](quickstart.md).
42
42
  - [Skills](skills.md) - Agent Skills for reusable on-demand capabilities.
43
43
  - [Prompt templates](prompt-templates.md) - reusable prompts that expand from slash commands.
44
44
  - [Themes](themes.md) - built-in and custom terminal themes.
45
- - [Pi packages](packages.md) - bundle and share extensions, skills, prompts, and themes.
45
+ - [phi packages](packages.md) - bundle and share extensions, skills, prompts, and themes.
46
46
  - [Custom models](models.md) - add model entries for supported provider APIs.
47
47
  - [Custom providers](custom-provider.md) - implement custom APIs and OAuth flows.
48
48
 
49
49
  ## Programmatic usage
50
50
 
51
- - [SDK](sdk.md) - embed pi in Node.js applications.
51
+ - [SDK](sdk.md) - embed phi in Node.js applications.
52
52
  - [RPC mode](rpc.md) - integrate over stdin/stdout JSONL.
53
53
  - [JSON event stream mode](json.md) - print mode with structured events.
54
54
  - [TUI components](tui.md) - build custom terminal UI for extensions.
package/docs/json.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # JSON Event Stream Mode
2
2
 
3
3
  ```bash
4
- pi --mode json "Your prompt"
4
+ phi --mode json "Your prompt"
5
5
  ```
6
6
 
7
- Outputs all session events as JSON lines to stdout. Useful for integrating pi into other tools or custom UIs.
7
+ Outputs all session events as JSON lines to stdout. Useful for integrating phi into other tools or custom UIs.
8
8
 
9
9
  ## Event Types
10
10
 
@@ -78,5 +78,5 @@ Followed by events as they occur:
78
78
  ## Example
79
79
 
80
80
  ```bash
81
- pi --mode json "List files" 2>/dev/null | jq -c 'select(.type == "message_end")'
81
+ phi --mode json "List files" 2>/dev/null | jq -c 'select(.type == "message_end")'
82
82
  ```
@@ -1,12 +1,12 @@
1
1
  # Keybindings
2
2
 
3
- All keyboard shortcuts can be customized via `~/.pi/agent/keybindings.json`. Each action can be bound to one or more keys.
3
+ All keyboard shortcuts can be customized via `~/.phi/agent/keybindings.json`. Each action can be bound to one or more keys.
4
4
 
5
- The config file uses the same namespaced keybinding ids that pi uses internally and that extension authors use in `keyHint()` and injected `keybindings` managers.
5
+ The config file uses the same namespaced keybinding ids that phi uses internally and that extension authors use in `keyHint()` and injected `keybindings` managers.
6
6
 
7
7
  Older configs using pre-namespaced ids such as `cursorUp` or `expandTools` are migrated automatically to the namespaced ids on startup.
8
8
 
9
- After editing `keybindings.json`, run `/reload` in pi to apply the changes without restarting the session.
9
+ After editing `keybindings.json`, run `/reload` in phi to apply the changes without restarting the session.
10
10
 
11
11
  ## Key Format
12
12
 
@@ -153,7 +153,7 @@ Used inside the scoped models selector (opened via `/scoped-models`).
153
153
 
154
154
  ## Custom Configuration
155
155
 
156
- Create `~/.pi/agent/keybindings.json`:
156
+ Create `~/.phi/agent/keybindings.json`:
157
157
 
158
158
  ```json
159
159
  {
@@ -165,7 +165,7 @@ Create `~/.pi/agent/keybindings.json`:
165
165
 
166
166
  Each action can have a single key or an array of keys. User config overrides defaults.
167
167
 
168
- On native Windows, `app.suspend` has no default binding because Windows terminals do not support Unix job control. If you bind it manually, pi shows a status message instead of suspending. In WSL, the normal Linux `ctrl+z`/`fg` behavior still applies.
168
+ On native Windows, `app.suspend` has no default binding because Windows terminals do not support Unix job control. If you bind it manually, phi shows a status message instead of suspending. In WSL, the normal Linux `ctrl+z`/`fg` behavior still applies.
169
169
 
170
170
  ### Emacs Example
171
171
 
package/docs/models.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Custom Models
2
2
 
3
- Add custom providers and models (Ollama, vLLM, LM Studio, proxies) via `~/.pi/agent/models.json`.
3
+ Add custom providers and models (Ollama, vLLM, LM Studio, proxies) via `~/.phi/agent/models.json`.
4
4
 
5
5
  ## Table of Contents
6
6
 
@@ -36,7 +36,7 @@ For local models (Ollama, LM Studio, vLLM), only `id` is required per model:
36
36
 
37
37
  The `apiKey` is required but Ollama ignores it, so any value works.
38
38
 
39
- Some OpenAI-compatible servers do not understand the `developer` role used for reasoning-capable models. For those providers, set `compat.supportsDeveloperRole` to `false` so pi sends the system prompt as a `system` message instead. If the server also does not support `reasoning_effort`, set `compat.supportsReasoningEffort` to `false` too.
39
+ Some OpenAI-compatible servers do not understand the `developer` role used for reasoning-capable models. For those providers, set `compat.supportsDeveloperRole` to `false` so phi sends the system prompt as a `system` message instead. If the server also does not support `reasoning_effort`, set `compat.supportsReasoningEffort` to `false` too.
40
40
 
41
41
  You can set `compat` at the provider level to apply to all models, or at the model level to override a specific model. This commonly applies to Ollama, vLLM, SGLang, and similar OpenAI-compatible servers.
42
42
 
@@ -159,7 +159,7 @@ The `apiKey` and `headers` fields support three formats:
159
159
  "apiKey": "sk-..."
160
160
  ```
161
161
 
162
- For `models.json`, shell commands are resolved at request time. pi intentionally does not apply built-in TTL, stale reuse, or recovery logic for arbitrary commands. Different commands need different caching and failure strategies, and pi cannot infer the right one.
162
+ For `models.json`, shell commands are resolved at request time. phi intentionally does not apply built-in TTL, stale reuse, or recovery logic for arbitrary commands. Different commands need different caching and failure strategies, and phi cannot infer the right one.
163
163
 
164
164
  If your command is slow, expensive, rate-limited, or should keep using a previous value on transient failures, wrap it in your own script or command that implements the caching or TTL behavior you want.
165
165
 
@@ -192,7 +192,7 @@ If your command is slow, expensive, rate-limited, or should keep using a previou
192
192
  | `name` | No | `id` | Human-readable model label. Used for matching (`--model` patterns) and shown in model details/status text. |
193
193
  | `api` | No | provider's `api` | Override provider's API for this model |
194
194
  | `reasoning` | No | `false` | Supports extended thinking |
195
- | `thinkingLevelMap` | No | omitted | Maps pi thinking levels to provider values and marks unsupported levels (see below) |
195
+ | `thinkingLevelMap` | No | omitted | Maps phi thinking levels to provider values and marks unsupported levels (see below) |
196
196
  | `input` | No | `["text"]` | Input types: `["text"]` or `["text", "image"]` |
197
197
  | `contextWindow` | No | `128000` | Context window size in tokens |
198
198
  | `maxTokens` | No | `16384` | Maximum output tokens |
@@ -205,7 +205,7 @@ Current behavior:
205
205
 
206
206
  ### Thinking Level Map
207
207
 
208
- Use `thinkingLevelMap` on a model to describe model-specific thinking controls. Keys are pi thinking levels: `off`, `minimal`, `low`, `medium`, `high`, `xhigh`.
208
+ Use `thinkingLevelMap` on a model to describe model-specific thinking controls. Keys are phi thinking levels: `off`, `minimal`, `low`, `medium`, `high`, `xhigh`.
209
209
 
210
210
  Values are tristate:
211
211
 
@@ -317,7 +317,7 @@ Behavior notes:
317
317
 
318
318
  For providers or proxies using `api: "anthropic-messages"`, use `compat.supportsEagerToolInputStreaming` to control Anthropic fine-grained tool streaming compatibility.
319
319
 
320
- By default pi sends per-tool `eager_input_streaming: true`. If a proxy or Anthropic-compatible backend rejects that field, set `supportsEagerToolInputStreaming` to `false`. Pi will omit `tools[].eager_input_streaming` and send the legacy `fine-grained-tool-streaming-2025-05-14` beta header for tool-enabled requests instead.
320
+ By default phi sends per-tool `eager_input_streaming: true`. If a proxy or Anthropic-compatible backend rejects that field, set `supportsEagerToolInputStreaming` to `false`. phi will omit `tools[].eager_input_streaming` and send the legacy `fine-grained-tool-streaming-2025-05-14` beta header for tool-enabled requests instead.
321
321
 
322
322
  ```json
323
323
  {