@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.
- package/CHANGELOG.md +83 -0
- package/README.md +92 -123
- package/config/routing.example.json +129 -0
- package/config/routing.schema.json +58 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +1 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -1
- package/dist/config.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +1 -1
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +6 -6
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/config-selector.js +1 -1
- package/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +2 -2
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +9 -8
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/utils/pi-user-agent.d.ts.map +1 -1
- package/dist/utils/pi-user-agent.js +4 -1
- package/dist/utils/pi-user-agent.js.map +1 -1
- package/docs/compaction.md +11 -11
- package/docs/custom-provider.md +4 -4
- package/docs/development.md +2 -2
- package/docs/extensions.md +47 -47
- package/docs/fork-policy.md +81 -0
- package/docs/index.md +7 -7
- package/docs/json.md +3 -3
- package/docs/keybindings.md +5 -5
- package/docs/models.md +6 -6
- package/docs/packages.md +37 -37
- package/docs/prompt-templates.md +4 -4
- package/docs/providers.md +9 -9
- package/docs/quickstart.md +25 -25
- package/docs/rpc.md +3 -3
- package/docs/sdk.md +34 -34
- package/docs/session-format.md +4 -4
- package/docs/sessions.md +11 -11
- package/docs/settings.md +9 -9
- package/docs/shell-aliases.md +2 -2
- package/docs/skills.md +9 -9
- package/docs/terminal-setup.md +7 -7
- package/docs/termux.md +6 -6
- package/docs/themes.md +9 -9
- package/docs/tmux.md +3 -3
- package/docs/tui.md +8 -8
- package/docs/usage.md +39 -39
- package/docs/windows.md +2 -2
- package/extensions/phi/agents.ts +12 -117
- package/extensions/phi/benchmark.ts +129 -49
- package/extensions/phi/browser.ts +10 -37
- package/extensions/phi/btw/btw.ts +1 -7
- package/extensions/phi/chrome/index.ts +1283 -741
- package/extensions/phi/commit.ts +9 -14
- package/extensions/phi/goal/index.ts +10 -33
- package/extensions/phi/init.ts +37 -47
- package/extensions/phi/keys.ts +2 -7
- package/extensions/phi/mcp/callback-server.ts +162 -165
- package/extensions/phi/mcp/config.ts +122 -136
- package/extensions/phi/mcp/errors.ts +18 -23
- package/extensions/phi/mcp/index.ts +322 -355
- package/extensions/phi/mcp/oauth-provider.ts +289 -289
- package/extensions/phi/mcp/server-manager.ts +390 -413
- package/extensions/phi/mcp/tool-bridge.ts +381 -415
- package/extensions/phi/memory.ts +2 -2
- package/extensions/phi/models.ts +27 -26
- package/extensions/phi/orchestrator.ts +343 -266
- package/extensions/phi/productivity.ts +4 -2
- package/extensions/phi/providers/agent-def.ts +128 -0
- package/extensions/phi/providers/alibaba.ts +56 -7
- package/extensions/phi/providers/context-window.ts +4 -1
- package/extensions/phi/providers/live-models.ts +5 -20
- package/extensions/phi/providers/orchestrator-helpers.ts +19 -5
- package/extensions/phi/providers/phase-machine.ts +220 -0
- package/extensions/phi/setup.ts +196 -169
- package/extensions/phi/skill-loader.ts +18 -21
- package/extensions/phi/smart-router.ts +6 -6
- package/extensions/phi/web-search.ts +90 -50
- package/package.json +2 -1
|
@@ -18,104 +18,104 @@ import { McpError } from "./errors.js";
|
|
|
18
18
|
// ─── Zod Schemas ──────────────────────────────────────────────────────────────
|
|
19
19
|
|
|
20
20
|
const AuthConfigSchema = z.object({
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
21
|
+
/** Auth type. Currently only "oauth" is supported. Default: "oauth". */
|
|
22
|
+
type: z.enum(["oauth"]).default("oauth"),
|
|
23
|
+
/**
|
|
24
|
+
* Callback URL for the OAuth redirect.
|
|
25
|
+
* Default: auto-detected local callback server.
|
|
26
|
+
*/
|
|
27
|
+
redirectUrl: z.string().optional(),
|
|
28
|
+
/**
|
|
29
|
+
* Optional scope to request during authorization.
|
|
30
|
+
*/
|
|
31
|
+
scope: z.string().optional(),
|
|
32
|
+
/**
|
|
33
|
+
* Pre-registered client_id (skip dynamic client registration).
|
|
34
|
+
*/
|
|
35
|
+
clientId: z.string().optional(),
|
|
36
|
+
/**
|
|
37
|
+
* Pre-registered client_secret.
|
|
38
|
+
*/
|
|
39
|
+
clientSecret: z.string().optional(),
|
|
40
40
|
});
|
|
41
41
|
|
|
42
42
|
const ServerConfigSchema = z
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
43
|
+
.object({
|
|
44
|
+
/** Executable to spawn (e.g. "npx", "node", "uvx"). Required for stdio. */
|
|
45
|
+
command: z.string().optional(),
|
|
46
|
+
/** Arguments passed to command. */
|
|
47
|
+
args: z.array(z.string()).default([]),
|
|
48
|
+
/**
|
|
49
|
+
* Extra environment variables passed to the child process as literals.
|
|
50
|
+
* These merge with process.env; project env overrides parent env.
|
|
51
|
+
* No ${VAR} interpolation — set vars in your shell environment instead.
|
|
52
|
+
*/
|
|
53
|
+
env: z.record(z.string()).optional(),
|
|
54
|
+
/** Transport protocol. Default: "stdio". */
|
|
55
|
+
transport: z.enum(["stdio", "streamable-http", "sse"]).default("stdio"),
|
|
56
|
+
/**
|
|
57
|
+
* URL for streamable-http or sse transports.
|
|
58
|
+
* Must be a valid URL (e.g. "https://my-mcp-server.example.com/mcp").
|
|
59
|
+
*/
|
|
60
|
+
url: z.string().url().optional(),
|
|
61
|
+
/**
|
|
62
|
+
* Static HTTP headers to include with every request (streamable-http / sse only).
|
|
63
|
+
* Useful for API-key-based auth (e.g. { "Authorization": "Bearer <key>" }).
|
|
64
|
+
* For OAuth2, use the "auth" field instead.
|
|
65
|
+
*/
|
|
66
|
+
headers: z.record(z.string()).optional(),
|
|
67
|
+
/**
|
|
68
|
+
* OAuth2 configuration for servers that require authorization.
|
|
69
|
+
* When set, the transport will use the SDK's OAuth flow (discovery,
|
|
70
|
+
* dynamic client registration, PKCE, token refresh).
|
|
71
|
+
* Only applies to streamable-http and sse transports.
|
|
72
|
+
*/
|
|
73
|
+
auth: AuthConfigSchema.optional(),
|
|
74
|
+
/**
|
|
75
|
+
* "eager" — start at session_start.
|
|
76
|
+
* "lazy" — start manually via /mcp:start command.
|
|
77
|
+
*/
|
|
78
|
+
lifecycle: z.enum(["eager", "lazy"]).default("lazy"),
|
|
79
|
+
/** Per-request timeout in ms. Overrides global setting. Default: 30000. */
|
|
80
|
+
requestTimeoutMs: z.number().positive().optional(),
|
|
81
|
+
/**
|
|
82
|
+
* Opt-in heartbeat interval (ping) in ms.
|
|
83
|
+
* Only useful for long-lived connections where you want proactive liveness checks.
|
|
84
|
+
* Default: disabled.
|
|
85
|
+
*/
|
|
86
|
+
healthCheckIntervalMs: z.number().positive().optional(),
|
|
87
|
+
})
|
|
88
|
+
.refine(
|
|
89
|
+
(cfg) => {
|
|
90
|
+
if (cfg.transport === "stdio") return cfg.command !== undefined;
|
|
91
|
+
return cfg.url !== undefined;
|
|
92
|
+
},
|
|
93
|
+
(cfg) => ({
|
|
94
|
+
message:
|
|
95
|
+
cfg.transport === "stdio"
|
|
96
|
+
? `"command" is required for stdio transport`
|
|
97
|
+
: `"url" is required for ${cfg.transport} transport`,
|
|
98
|
+
}),
|
|
99
|
+
);
|
|
100
100
|
|
|
101
101
|
const SettingsSchema = z.object({
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
102
|
+
/**
|
|
103
|
+
* Prefix used in Pi tool names: <prefix>_<server>_<tool>.
|
|
104
|
+
* Must match [a-zA-Z0-9_]. Default: "mcp".
|
|
105
|
+
*/
|
|
106
|
+
toolPrefix: z
|
|
107
|
+
.string()
|
|
108
|
+
.regex(/^[a-zA-Z0-9_]+$/, "toolPrefix must match [a-zA-Z0-9_]")
|
|
109
|
+
.default("mcp"),
|
|
110
|
+
/** Default per-request timeout in ms for all servers. Default: 30000. */
|
|
111
|
+
requestTimeoutMs: z.number().positive().default(30000),
|
|
112
|
+
/** Maximum retry attempts when a server fails to connect. Default: 5. */
|
|
113
|
+
maxRetries: z.number().int().min(0).max(10).default(5),
|
|
114
114
|
});
|
|
115
115
|
|
|
116
116
|
const McpConfigSchema = z.object({
|
|
117
|
-
|
|
118
|
-
|
|
117
|
+
settings: SettingsSchema.default({}),
|
|
118
|
+
mcpServers: z.record(ServerConfigSchema).default({}),
|
|
119
119
|
});
|
|
120
120
|
|
|
121
121
|
// ─── Public Types ─────────────────────────────────────────────────────────────
|
|
@@ -128,41 +128,32 @@ export type McpConfig = z.output<typeof McpConfigSchema>;
|
|
|
128
128
|
// ─── Loader ───────────────────────────────────────────────────────────────────
|
|
129
129
|
|
|
130
130
|
async function readJsonFile(path: string): Promise<unknown | null> {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
131
|
+
try {
|
|
132
|
+
const text = await readFile(path, "utf8");
|
|
133
|
+
return JSON.parse(text) as unknown;
|
|
134
|
+
} catch (err) {
|
|
135
|
+
// ENOENT → file doesn't exist, silently skip
|
|
136
|
+
if ((err as NodeJS.ErrnoException).code === "ENOENT") return null;
|
|
137
|
+
throw err;
|
|
138
|
+
}
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
function parseConfig(raw: unknown, sourcePath: string): McpConfig {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
`Invalid mcp.json at ${sourcePath}:\n${issues}`,
|
|
149
|
-
"<config>",
|
|
150
|
-
"config",
|
|
151
|
-
);
|
|
152
|
-
}
|
|
153
|
-
return result.data;
|
|
142
|
+
const result = McpConfigSchema.safeParse(raw);
|
|
143
|
+
if (!result.success) {
|
|
144
|
+
const issues = result.error.issues.map((i) => ` ${i.path.join(".")}: ${i.message}`).join("\n");
|
|
145
|
+
throw new McpError(`Invalid mcp.json at ${sourcePath}:\n${issues}`, "<config>", "config");
|
|
146
|
+
}
|
|
147
|
+
return result.data;
|
|
154
148
|
}
|
|
155
149
|
|
|
156
|
-
function mergeConfigs(
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
// Per-server override: project server entry completely replaces global entry with same name
|
|
164
|
-
mcpServers: { ...globalCfg.mcpServers, ...projectCfg.mcpServers },
|
|
165
|
-
};
|
|
150
|
+
function mergeConfigs(globalCfg: McpConfig, projectCfg: McpConfig): McpConfig {
|
|
151
|
+
return {
|
|
152
|
+
// Shallow spread: project settings override global settings per key
|
|
153
|
+
settings: { ...globalCfg.settings, ...projectCfg.settings },
|
|
154
|
+
// Per-server override: project server entry completely replaces global entry with same name
|
|
155
|
+
mcpServers: { ...globalCfg.mcpServers, ...projectCfg.mcpServers },
|
|
156
|
+
};
|
|
166
157
|
}
|
|
167
158
|
|
|
168
159
|
/**
|
|
@@ -171,25 +162,20 @@ function mergeConfigs(
|
|
|
171
162
|
* Returns a fully validated, merged config.
|
|
172
163
|
*/
|
|
173
164
|
export async function loadConfig(cwd: string): Promise<McpConfig> {
|
|
174
|
-
|
|
175
|
-
|
|
165
|
+
const globalPath = join(getAgentDir(), "mcp.json");
|
|
166
|
+
const projectPath = join(cwd, ".phi", "mcp.json");
|
|
176
167
|
|
|
177
|
-
|
|
178
|
-
readJsonFile(globalPath),
|
|
179
|
-
readJsonFile(projectPath),
|
|
180
|
-
]);
|
|
168
|
+
const [globalRaw, projectRaw] = await Promise.all([readJsonFile(globalPath), readJsonFile(projectPath)]);
|
|
181
169
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
170
|
+
// If neither file exists, return an empty valid config
|
|
171
|
+
if (globalRaw === null && projectRaw === null) {
|
|
172
|
+
return McpConfigSchema.parse({});
|
|
173
|
+
}
|
|
186
174
|
|
|
187
|
-
|
|
188
|
-
? parseConfig(globalRaw, globalPath)
|
|
189
|
-
: McpConfigSchema.parse({});
|
|
175
|
+
const globalCfg = globalRaw !== null ? parseConfig(globalRaw, globalPath) : McpConfigSchema.parse({});
|
|
190
176
|
|
|
191
|
-
|
|
177
|
+
if (projectRaw === null) return globalCfg;
|
|
192
178
|
|
|
193
|
-
|
|
194
|
-
|
|
179
|
+
const projectCfg = parseConfig(projectRaw, projectPath);
|
|
180
|
+
return mergeConfigs(globalCfg, projectCfg);
|
|
195
181
|
}
|
|
@@ -5,31 +5,26 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
export type McpErrorCode =
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
| "config" // Configuration loading or validation failed
|
|
9
|
+
| "connection" // Transport/connection failed
|
|
10
|
+
| "protocol" // JSON-RPC protocol violation (server error response, timeout, etc.)
|
|
11
|
+
| "tool"; // Tool execution error (isError: true from server)
|
|
12
12
|
|
|
13
13
|
export class McpError extends Error {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
public readonly server: string;
|
|
15
|
+
public readonly code: McpErrorCode;
|
|
16
|
+
public readonly cause: unknown;
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
this.name = "McpError";
|
|
26
|
-
this.server = server;
|
|
27
|
-
this.code = code;
|
|
28
|
-
this.cause = cause;
|
|
29
|
-
}
|
|
18
|
+
constructor(message: string, server: string, code: McpErrorCode, cause?: unknown) {
|
|
19
|
+
super(message);
|
|
20
|
+
this.name = "McpError";
|
|
21
|
+
this.server = server;
|
|
22
|
+
this.code = code;
|
|
23
|
+
this.cause = cause;
|
|
24
|
+
}
|
|
30
25
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
26
|
+
/** Short user-facing message suitable for ctx.ui.notify() */
|
|
27
|
+
get userMessage(): string {
|
|
28
|
+
return `[${this.server}] ${this.message}`;
|
|
29
|
+
}
|
|
35
30
|
}
|