@phi-code-admin/phi-code 0.85.0 → 0.87.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 (86) hide show
  1. package/CHANGELOG.md +83 -0
  2. package/README.md +92 -123
  3. package/config/routing.example.json +129 -0
  4. package/config/routing.schema.json +58 -0
  5. package/dist/cli/args.d.ts.map +1 -1
  6. package/dist/cli/args.js +1 -1
  7. package/dist/cli/args.js.map +1 -1
  8. package/dist/config.d.ts.map +1 -1
  9. package/dist/config.js +1 -1
  10. package/dist/config.js.map +1 -1
  11. package/dist/core/sdk.d.ts.map +1 -1
  12. package/dist/core/sdk.js +1 -1
  13. package/dist/core/sdk.js.map +1 -1
  14. package/dist/core/system-prompt.d.ts.map +1 -1
  15. package/dist/core/system-prompt.js +6 -6
  16. package/dist/core/system-prompt.js.map +1 -1
  17. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  18. package/dist/modes/interactive/components/config-selector.js +1 -1
  19. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  20. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  21. package/dist/modes/interactive/interactive-mode.js +2 -2
  22. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  23. package/dist/package-manager-cli.d.ts.map +1 -1
  24. package/dist/package-manager-cli.js +9 -8
  25. package/dist/package-manager-cli.js.map +1 -1
  26. package/dist/utils/pi-user-agent.d.ts.map +1 -1
  27. package/dist/utils/pi-user-agent.js +4 -1
  28. package/dist/utils/pi-user-agent.js.map +1 -1
  29. package/docs/compaction.md +11 -11
  30. package/docs/custom-provider.md +4 -4
  31. package/docs/development.md +2 -2
  32. package/docs/extensions.md +47 -47
  33. package/docs/fork-policy.md +81 -0
  34. package/docs/index.md +7 -7
  35. package/docs/json.md +3 -3
  36. package/docs/keybindings.md +5 -5
  37. package/docs/models.md +6 -6
  38. package/docs/packages.md +37 -37
  39. package/docs/prompt-templates.md +4 -4
  40. package/docs/providers.md +9 -9
  41. package/docs/quickstart.md +25 -25
  42. package/docs/rpc.md +3 -3
  43. package/docs/sdk.md +34 -34
  44. package/docs/session-format.md +4 -4
  45. package/docs/sessions.md +11 -11
  46. package/docs/settings.md +9 -9
  47. package/docs/shell-aliases.md +2 -2
  48. package/docs/skills.md +9 -9
  49. package/docs/terminal-setup.md +7 -7
  50. package/docs/termux.md +6 -6
  51. package/docs/themes.md +9 -9
  52. package/docs/tmux.md +3 -3
  53. package/docs/tui.md +8 -8
  54. package/docs/usage.md +39 -39
  55. package/docs/windows.md +2 -2
  56. package/extensions/phi/agents.ts +12 -117
  57. package/extensions/phi/benchmark.ts +129 -49
  58. package/extensions/phi/browser.ts +10 -37
  59. package/extensions/phi/btw/btw.ts +1 -7
  60. package/extensions/phi/chrome/index.ts +1283 -741
  61. package/extensions/phi/commit.ts +9 -14
  62. package/extensions/phi/goal/index.ts +10 -33
  63. package/extensions/phi/init.ts +37 -47
  64. package/extensions/phi/keys.ts +2 -7
  65. package/extensions/phi/mcp/callback-server.ts +162 -165
  66. package/extensions/phi/mcp/config.ts +122 -136
  67. package/extensions/phi/mcp/errors.ts +18 -23
  68. package/extensions/phi/mcp/index.ts +322 -355
  69. package/extensions/phi/mcp/oauth-provider.ts +289 -289
  70. package/extensions/phi/mcp/server-manager.ts +390 -413
  71. package/extensions/phi/mcp/tool-bridge.ts +381 -415
  72. package/extensions/phi/memory.ts +2 -2
  73. package/extensions/phi/models.ts +27 -26
  74. package/extensions/phi/orchestrator.ts +343 -266
  75. package/extensions/phi/productivity.ts +4 -2
  76. package/extensions/phi/providers/agent-def.ts +128 -0
  77. package/extensions/phi/providers/alibaba.ts +56 -7
  78. package/extensions/phi/providers/context-window.ts +4 -1
  79. package/extensions/phi/providers/live-models.ts +5 -20
  80. package/extensions/phi/providers/orchestrator-helpers.ts +19 -5
  81. package/extensions/phi/providers/phase-machine.ts +220 -0
  82. package/extensions/phi/setup.ts +196 -169
  83. package/extensions/phi/skill-loader.ts +18 -21
  84. package/extensions/phi/smart-router.ts +6 -6
  85. package/extensions/phi/web-search.ts +90 -50
  86. package/package.json +2 -1
package/docs/tui.md CHANGED
@@ -1,4 +1,4 @@
1
- > pi can create TUI components. Ask it to build one for your use case.
1
+ > phi can create TUI components. Ask it to build one for your use case.
2
2
 
3
3
  # TUI Components
4
4
 
@@ -425,7 +425,7 @@ renderResult(result, options, theme, context) {
425
425
  **For Markdown**, use `getMarkdownTheme()`:
426
426
 
427
427
  ```typescript
428
- import { getMarkdownTheme } from "@earendil-works/pi-coding-agent";
428
+ import { getMarkdownTheme } from "@phi-code-admin/phi-code";
429
429
  import { Markdown } from "@earendil-works/pi-tui";
430
430
 
431
431
  renderResult(result, options, theme, context) {
@@ -590,8 +590,8 @@ These patterns cover the most common UI needs in extensions. **Copy these patter
590
590
  For letting users pick from a list of options. Use `SelectList` from `@earendil-works/pi-tui` with `DynamicBorder` for framing.
591
591
 
592
592
  ```typescript
593
- import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
594
- import { DynamicBorder } from "@earendil-works/pi-coding-agent";
593
+ import type { ExtensionAPI } from "@phi-code-admin/phi-code";
594
+ import { DynamicBorder } from "@phi-code-admin/phi-code";
595
595
  import { Container, type SelectItem, SelectList, Text } from "@earendil-works/pi-tui";
596
596
 
597
597
  pi.registerCommand("pick", {
@@ -650,7 +650,7 @@ pi.registerCommand("pick", {
650
650
  For operations that take time and should be cancellable. `BorderedLoader` shows a spinner and handles escape to cancel.
651
651
 
652
652
  ```typescript
653
- import { BorderedLoader } from "@earendil-works/pi-coding-agent";
653
+ import { BorderedLoader } from "@phi-code-admin/phi-code";
654
654
 
655
655
  pi.registerCommand("fetch", {
656
656
  handler: async (_args, ctx) => {
@@ -682,7 +682,7 @@ pi.registerCommand("fetch", {
682
682
  For toggling multiple settings. Use `SettingsList` from `@earendil-works/pi-tui` with `getSettingsListTheme()`.
683
683
 
684
684
  ```typescript
685
- import { getSettingsListTheme } from "@earendil-works/pi-coding-agent";
685
+ import { getSettingsListTheme } from "@phi-code-admin/phi-code";
686
686
  import { Container, type SettingItem, SettingsList, Text } from "@earendil-works/pi-tui";
687
687
 
688
688
  pi.registerCommand("settings", {
@@ -737,7 +737,7 @@ ctx.ui.setStatus("my-ext", undefined);
737
737
 
738
738
  ### Pattern 4b: Working Indicator Customization
739
739
 
740
- Customize the inline working indicator shown while pi is streaming a response.
740
+ Customize the inline working indicator shown while phi is streaming a response.
741
741
 
742
742
  ```typescript
743
743
  // Static indicator
@@ -822,7 +822,7 @@ Token stats available via `ctx.sessionManager.getBranch()` and `ctx.model`.
822
822
  Replace the main input editor with a custom implementation. Useful for modal editing (vim), different keybindings (emacs), or specialized input handling.
823
823
 
824
824
  ```typescript
825
- import { CustomEditor, type ExtensionAPI } from "@earendil-works/pi-coding-agent";
825
+ import { CustomEditor, type ExtensionAPI } from "@phi-code-admin/phi-code";
826
826
  import { matchesKey, truncateToWidth } from "@earendil-works/pi-tui";
827
827
 
828
828
  type Mode = "normal" | "insert";
package/docs/usage.md CHANGED
@@ -1,4 +1,4 @@
1
- # Using Pi
1
+ # Using phi
2
2
 
3
3
  This page collects day-to-day usage details that do not fit on the quickstart page.
4
4
 
@@ -53,7 +53,7 @@ Type `/` in the editor to open command completion. Extensions can register custo
53
53
  | `/reload` | Reload keybindings, extensions, skills, prompts, and context files |
54
54
  | `/hotkeys` | Show all keyboard shortcuts |
55
55
  | `/changelog` | Display version history |
56
- | `/quit` | Quit pi |
56
+ | `/quit` | Quit phi |
57
57
 
58
58
  ## Message Queue
59
59
 
@@ -64,20 +64,20 @@ You can submit messages while the agent is still working:
64
64
  - **Escape** aborts and restores queued messages to the editor.
65
65
  - **Alt+Up** retrieves queued messages back to the editor.
66
66
 
67
- On Windows Terminal, Alt+Enter is fullscreen by default. Remap it as described in [Terminal setup](terminal-setup.md) if you want pi to receive the shortcut.
67
+ On Windows Terminal, Alt+Enter is fullscreen by default. Remap it as described in [Terminal setup](terminal-setup.md) if you want phi to receive the shortcut.
68
68
 
69
69
  Configure delivery in [Settings](settings.md) with `steeringMode` and `followUpMode`.
70
70
 
71
71
  ## Sessions
72
72
 
73
- Sessions are saved automatically to `~/.pi/agent/sessions/`, organized by working directory.
73
+ Sessions are saved automatically to `~/.phi/agent/sessions/`, organized by working directory.
74
74
 
75
75
  ```bash
76
- pi -c # Continue most recent session
77
- pi -r # Browse and select a session
78
- pi --no-session # Ephemeral mode; do not save
79
- pi --session <path|id> # Use a specific session file or session ID
80
- pi --fork <path|id> # Fork a session into a new session file
76
+ phi -c # Continue most recent session
77
+ phi -r # Browse and select a session
78
+ phi --no-session # Ephemeral mode; do not save
79
+ phi --session <path|id> # Use a specific session file or session ID
80
+ phi --fork <path|id> # Fork a session into a new session file
81
81
  ```
82
82
 
83
83
  Useful session commands:
@@ -92,9 +92,9 @@ See [Sessions](sessions.md) and [Compaction](compaction.md) for details.
92
92
 
93
93
  ## Context Files
94
94
 
95
- Pi loads `AGENTS.md` or `CLAUDE.md` at startup from:
95
+ phi loads `AGENTS.md` or `CLAUDE.md` at startup from:
96
96
 
97
- - `~/.pi/agent/AGENTS.md` for global instructions
97
+ - `~/.phi/agent/AGENTS.md` for global instructions
98
98
  - parent directories, walking up from the current working directory
99
99
  - the current directory
100
100
 
@@ -104,8 +104,8 @@ Use context files for project conventions, commands, safety rules, and preferenc
104
104
 
105
105
  Replace the default system prompt with:
106
106
 
107
- - `.pi/SYSTEM.md` for a project
108
- - `~/.pi/agent/SYSTEM.md` globally
107
+ - `.phi/SYSTEM.md` for a project
108
+ - `~/.phi/agent/SYSTEM.md` globally
109
109
 
110
110
  Append to the default prompt without replacing it with `APPEND_SYSTEM.md` in either location.
111
111
 
@@ -120,24 +120,24 @@ If you use pi for open source work and want to publish sessions for model, promp
120
120
  ## CLI Reference
121
121
 
122
122
  ```bash
123
- pi [options] [@files...] [messages...]
123
+ phi [options] [@files...] [messages...]
124
124
  ```
125
125
 
126
126
  ### Package Commands
127
127
 
128
128
  ```bash
129
- pi install <source> [-l] # Install package, -l for project-local
130
- pi remove <source> [-l] # Remove package
131
- pi uninstall <source> [-l] # Alias for remove
132
- pi update [source|self|pi] # Update pi and packages; skips pinned packages
133
- pi update --extensions # Update packages only
134
- pi update --self # Update pi only
135
- pi update --extension <src> # Update one package
136
- pi list # List installed packages
137
- pi config # Enable/disable package resources
129
+ phi install <source> [-l] # Install package, -l for project-local
130
+ phi remove <source> [-l] # Remove package
131
+ phi uninstall <source> [-l] # Alias for remove
132
+ phi update [source|self] # Update phi and packages; skips pinned packages
133
+ phi update --extensions # Update packages only
134
+ phi update --self # Update phi only
135
+ phi update --extension <src> # Update one package
136
+ phi list # List installed packages
137
+ phi config # Enable/disable package resources
138
138
  ```
139
139
 
140
- See [Pi Packages](packages.md) for package sources and security notes.
140
+ See [Phi Packages](packages.md) for package sources and security notes.
141
141
 
142
142
  ### Modes
143
143
 
@@ -149,10 +149,10 @@ See [Pi Packages](packages.md) for package sources and security notes.
149
149
  | `--mode rpc` | RPC mode over stdin/stdout; see [RPC mode](rpc.md) |
150
150
  | `--export <in> [out]` | Export a session to HTML |
151
151
 
152
- In print mode, pi also reads piped stdin and merges it into the initial prompt:
152
+ In print mode, phi also reads piped stdin and merges it into the initial prompt:
153
153
 
154
154
  ```bash
155
- cat README.md | pi -p "Summarize this text"
155
+ cat README.md | phi -p "Summarize this text"
156
156
  ```
157
157
 
158
158
  ### Model Options
@@ -204,7 +204,7 @@ Built-in tools: `read`, `bash`, `edit`, `write`, `grep`, `find`, `ls`.
204
204
  Combine `--no-*` with explicit flags to load exactly what you need, ignoring settings. Example:
205
205
 
206
206
  ```bash
207
- pi --no-extensions -e ./my-extension.ts
207
+ phi --no-extensions -e ./my-extension.ts
208
208
  ```
209
209
 
210
210
  ### Other Options
@@ -223,7 +223,7 @@ Prefix files with `@` to include them in the message:
223
223
 
224
224
  ```bash
225
225
  pi @prompt.md "Answer this"
226
- pi -p @screenshot.png "What's in this image?"
226
+ phi -p @screenshot.png "What's in this image?"
227
227
  pi @code.ts @test.ts "Review these files"
228
228
  ```
229
229
 
@@ -231,36 +231,36 @@ pi @code.ts @test.ts "Review these files"
231
231
 
232
232
  ```bash
233
233
  # Interactive with initial prompt
234
- pi "List all .ts files in src/"
234
+ phi "List all .ts files in src/"
235
235
 
236
236
  # Non-interactive
237
- pi -p "Summarize this codebase"
237
+ phi -p "Summarize this codebase"
238
238
 
239
239
  # Non-interactive with piped stdin
240
- cat README.md | pi -p "Summarize this text"
240
+ cat README.md | phi -p "Summarize this text"
241
241
 
242
242
  # Different model
243
- pi --provider openai --model gpt-4o "Help me refactor"
243
+ phi --provider openai --model gpt-4o "Help me refactor"
244
244
 
245
245
  # Model with provider prefix
246
- pi --model openai/gpt-4o "Help me refactor"
246
+ phi --model openai/gpt-4o "Help me refactor"
247
247
 
248
248
  # Model with thinking level shorthand
249
- pi --model sonnet:high "Solve this complex problem"
249
+ phi --model sonnet:high "Solve this complex problem"
250
250
 
251
251
  # Limit model cycling
252
- pi --models "claude-*,gpt-4o"
252
+ phi --models "claude-*,gpt-4o"
253
253
 
254
254
  # Read-only mode
255
- pi --tools read,grep,find,ls -p "Review the code"
255
+ phi --tools read,grep,find,ls -p "Review the code"
256
256
  ```
257
257
 
258
258
  ### Environment Variables
259
259
 
260
260
  | Variable | Description |
261
261
  |----------|-------------|
262
- | `PI_CODING_AGENT_DIR` | Override config directory; default is `~/.pi/agent` |
263
- | `PI_CODING_AGENT_SESSION_DIR` | Override session storage directory; overridden by `--session-dir` |
262
+ | `PHI_CODING_AGENT_DIR` | Override config directory; default is `~/.phi/agent` |
263
+ | `PHI_CODING_AGENT_SESSION_DIR` | Override session storage directory; overridden by `--session-dir` |
264
264
  | `PI_PACKAGE_DIR` | Override package directory, useful for Nix/Guix store paths |
265
265
  | `PI_OFFLINE` | Disable startup network operations, including update checks, package update checks, and install/update telemetry |
266
266
  | `PI_SKIP_VERSION_CHECK` | Skip the phi-code version update check at startup. This prevents the npm registry latest-version request |
@@ -270,7 +270,7 @@ pi --tools read,grep,find,ls -p "Review the code"
270
270
 
271
271
  ## Design Principles
272
272
 
273
- Pi keeps the core small and pushes workflow-specific behavior into extensions, skills, prompt templates, and packages.
273
+ phi keeps the core small and pushes workflow-specific behavior into extensions, skills, prompt templates, and packages.
274
274
 
275
275
  It bundles MCP support (see the MCP extension) and sub-agents. It does not include permission popups, to-dos, or background bash by default: you can build or install those workflows as extensions or packages, or use external tools such as containers and tmux.
276
276
 
package/docs/windows.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # Windows Setup
2
2
 
3
- Pi requires a bash shell on Windows. Checked locations (in order):
3
+ phi requires a bash shell on Windows. Checked locations (in order):
4
4
 
5
- 1. Custom path from `~/.pi/agent/settings.json`
5
+ 1. Custom path from `~/.phi/agent/settings.json`
6
6
  2. Git Bash (`C:\Program Files\Git\bin\bash.exe`)
7
7
  3. `bash.exe` on PATH (Cygwin, MSYS2, WSL)
8
8
 
@@ -4,123 +4,15 @@
4
4
  * Provides:
5
5
  * - /agents command to list all configured sub-agents
6
6
  * - /agents <name> to show detailed agent info
7
- * - Agent definitions loaded from ~/.phi/agent/agents/ and .phi/agents/
8
- * - Model assignment visibility
7
+ * - Agent definitions loaded from .phi/agents/, ~/.phi/agent/agents/ and the
8
+ * bundled agents/ directory via the shared providers/agent-def module
9
+ * (same parser and search order as the /plan orchestrator).
9
10
  */
10
11
 
11
12
  import type { ExtensionAPI } from "phi-code";
12
- import { readFileSync, readdirSync, existsSync, statSync } from "node:fs";
13
- import { join, basename } from "node:path";
14
- import { homedir } from "node:os";
15
-
16
- interface AgentDefinition {
17
- name: string;
18
- description: string;
19
- tools: string[];
20
- model: string;
21
- source: string; // "global", "project", "bundled"
22
- filePath: string;
23
- systemPrompt: string;
24
- }
25
-
26
- /**
27
- * Parse YAML frontmatter from agent .md file
28
- */
29
- function parseAgentFile(filePath: string): AgentDefinition | null {
30
- try {
31
- const content = readFileSync(filePath, "utf-8");
32
- const fmMatch = content.match(/^---\s*\n([\s\S]*?)\n---\s*\n([\s\S]*)$/);
33
-
34
- if (!fmMatch) return null;
35
-
36
- const frontmatter = fmMatch[1];
37
- const body = fmMatch[2].trim();
38
-
39
- // Simple YAML parser for our frontmatter
40
- const fields: Record<string, string> = {};
41
- for (const line of frontmatter.split("\n")) {
42
- const match = line.match(/^(\w+):\s*(.*)$/);
43
- if (match) {
44
- fields[match[1]] = match[2].trim();
45
- }
46
- }
47
-
48
- if (!fields.name) return null;
49
-
50
- return {
51
- name: fields.name,
52
- description: fields.description || "No description",
53
- tools: (fields.tools || "").split(",").map(t => t.trim()).filter(Boolean),
54
- model: fields.model || "default",
55
- source: "unknown",
56
- filePath,
57
- systemPrompt: body,
58
- };
59
- } catch {
60
- return null;
61
- }
62
- }
63
-
64
- /**
65
- * Scan a directory for agent .md files
66
- */
67
- function scanAgentDir(dir: string, source: string): AgentDefinition[] {
68
- const agents: AgentDefinition[] = [];
69
-
70
- if (!existsSync(dir)) return agents;
71
-
72
- try {
73
- const entries = readdirSync(dir);
74
- for (const entry of entries) {
75
- if (!entry.endsWith(".md")) continue;
76
- const fullPath = join(dir, entry);
77
- if (!statSync(fullPath).isFile()) continue;
78
-
79
- const agent = parseAgentFile(fullPath);
80
- if (agent) {
81
- agent.source = source;
82
- agents.push(agent);
83
- }
84
- }
85
- } catch {
86
- // Directory not readable
87
- }
88
-
89
- return agents;
90
- }
13
+ import { type AgentDef, discoverAgents } from "./providers/agent-def.js";
91
14
 
92
15
  export default function agentsExtension(pi: ExtensionAPI) {
93
- /**
94
- * Discover all agent definitions from all sources
95
- */
96
- function discoverAgents(): AgentDefinition[] {
97
- const seen = new Set<string>();
98
- const allAgents: AgentDefinition[] = [];
99
-
100
- const addAgents = (agents: AgentDefinition[]) => {
101
- for (const agent of agents) {
102
- if (!seen.has(agent.name)) {
103
- seen.add(agent.name);
104
- allAgents.push(agent);
105
- }
106
- }
107
- };
108
-
109
- // 1. Project-local agents
110
- addAgents(scanAgentDir(join(process.cwd(), ".phi", "agents"), "project"));
111
-
112
- // 2. Global agents
113
- addAgents(scanAgentDir(join(homedir(), ".phi", "agent", "agents"), "global"));
114
-
115
- // 3. Bundled agents (shipped with package)
116
- const bundledDir = join(__dirname, "..", "..", "..", "agents");
117
- if (existsSync(bundledDir)) {
118
- addAgents(scanAgentDir(bundledDir, "bundled"));
119
- }
120
-
121
- return allAgents;
122
- }
123
-
124
16
  /**
125
17
  * /agents command
126
18
  */
@@ -131,15 +23,18 @@ export default function agentsExtension(pi: ExtensionAPI) {
131
23
  const arg = args.trim().toLowerCase();
132
24
 
133
25
  if (agents.length === 0) {
134
- ctx.ui.notify("No agent definitions found.\n\nCreate agent files in:\n- `.phi/agents/` (project)\n- `~/.phi/agent/agents/` (global)\n\nFormat: Markdown with YAML frontmatter (name, description, tools, model).", "info");
26
+ ctx.ui.notify(
27
+ "No agent definitions found.\n\nCreate agent files in:\n- `.phi/agents/` (project)\n- `~/.phi/agent/agents/` (global)\n\nFormat: Markdown with YAML frontmatter (name, description, tools, model).",
28
+ "info",
29
+ );
135
30
  return;
136
31
  }
137
32
 
138
33
  // Show specific agent details
139
34
  if (arg && arg !== "list") {
140
- const agent = agents.find(a => a.name.toLowerCase() === arg);
35
+ const agent = agents.find((a) => a.name.toLowerCase() === arg);
141
36
  if (!agent) {
142
- ctx.ui.notify(`Agent "${arg}" not found. Available: ${agents.map(a => a.name).join(", ")}`, "warning");
37
+ ctx.ui.notify(`Agent "${arg}" not found. Available: ${agents.map((a) => a.name).join(", ")}`, "warning");
143
38
  return;
144
39
  }
145
40
 
@@ -147,7 +42,7 @@ export default function agentsExtension(pi: ExtensionAPI) {
147
42
 
148
43
  📝 ${agent.description}
149
44
  🤖 Model: \`${agent.model}\`
150
- 🔧 Tools: ${agent.tools.map(t => `\`${t}\``).join(", ")}
45
+ 🔧 Tools: ${agent.tools.map((t) => `\`${t}\``).join(", ")}
151
46
  📁 Source: ${agent.source} (\`${agent.filePath}\`)
152
47
 
153
48
  **System Prompt:**
@@ -163,7 +58,7 @@ ${agent.systemPrompt.substring(0, 800)}${agent.systemPrompt.length > 800 ? "\n..
163
58
  let output = `**🤖 Sub-Agents (${agents.length})**\n\n`;
164
59
 
165
60
  // Group by source
166
- const bySource: Record<string, AgentDefinition[]> = {};
61
+ const bySource: Record<string, AgentDef[]> = {};
167
62
  for (const agent of agents) {
168
63
  const key = agent.source;
169
64
  if (!bySource[key]) bySource[key] = [];