@bexelbie/phone-a-friend 0.1.1 → 0.2.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/README.md CHANGED
@@ -120,11 +120,13 @@ You can direct the model to pass any model name directly — GitHub Copilot CLI
120
120
  | `prompt` | Yes | The task or question for the other model. Include relevant context. |
121
121
  | `model` | Yes | Which AI model to use (see list above). |
122
122
  | `working_directory` | Yes | Git repo directory to work in. Must be inside a git repository. Always pass this explicitly — the server's own working directory is not the user's workspace. |
123
+ | `mode` | No | `"default"` returns the response and a unified diff of file changes. `"query"` discards all file changes and returns only the response — use for reviews, analysis, or questions. Default: `"default"`. |
123
124
 
124
125
  ## Safety
125
126
 
126
127
  - **Push protection**: The CLI is invoked with `--deny-tool 'shell(git push*)'` which blocks all push attempts at the tool level. The prompt also instructs the agent not to push.
127
128
  - **Worktree isolation**: All work happens in a temporary git worktree. Your working tree is never modified directly.
129
+ - **Query mode**: When `mode` is `"query"`, all file changes in the worktree are discarded. The subagent is instructed that the repo is read-only. No git diff is returned.
128
130
  - **Automatic cleanup**: Worktrees are removed after each invocation, even on errors.
129
131
  - **No secrets exposure**: The subagent has the same access as `copilot` CLI running locally — no additional permissions are granted.
130
132
 
@@ -146,6 +148,51 @@ npm test # Run tests
146
148
  npm run dev # Watch mode for development
147
149
  ```
148
150
 
151
+ ### Testing a local build in VS Code
152
+
153
+ If you have phone-a-friend installed globally (via `npx @bexelbie/phone-a-friend`), you need to point VS Code at your local build instead. Update your MCP configuration (`.vscode/mcp.json` or user-level `mcp.json`) to use `node` with the local dist path:
154
+
155
+ ```json
156
+ {
157
+ "servers": {
158
+ "phone-a-friend": {
159
+ "type": "stdio",
160
+ "command": "node",
161
+ "args": [
162
+ "/absolute/path/to/phone-a-friend/dist/index.js"
163
+ ],
164
+ "env": {}
165
+ }
166
+ }
167
+ }
168
+ ```
169
+
170
+ Replace `/absolute/path/to/phone-a-friend` with the actual path to your clone.
171
+
172
+ After changing the config:
173
+
174
+ 1. Build your changes: `npm run build`
175
+ 2. In VS Code, open the Command Palette and run `MCP: List Servers`
176
+ 3. Select `phone-a-friend` and choose `Restart Server` to pick up the new code
177
+ 4. Test in Copilot Chat — the tool will now use your local build
178
+
179
+ When you're done testing, revert the MCP config back to `npx`:
180
+
181
+ ```json
182
+ {
183
+ "servers": {
184
+ "phone-a-friend": {
185
+ "type": "stdio",
186
+ "command": "npx",
187
+ "args": [
188
+ "@bexelbie/phone-a-friend"
189
+ ],
190
+ "env": {}
191
+ }
192
+ }
193
+ }
194
+ ```
195
+
149
196
  ## License
150
197
 
151
198
  MIT
package/dist/git.d.ts CHANGED
@@ -33,7 +33,7 @@ export declare function getHeadSha(dir: string): Promise<string>;
33
33
  * against the given base SHA (the original commit before the agent ran).
34
34
  * This ensures committed changes are also captured.
35
35
  */
36
- export declare function captureChanges(worktreePath: string, baseSha: string): Promise<string>;
36
+ export declare function captureChanges(worktreePath: string, baseSha: string): Promise<string | null>;
37
37
  /**
38
38
  * Reads and removes the message-in-a-bottle response file.
39
39
  */
package/dist/git.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AAWA;;GAEG;AACH,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO7D;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAO7D;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAYf;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CA0Bf;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAwC/C;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAO7D;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,CAAC,CAkBjB;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CASxB"}
1
+ {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AAWA;;GAEG;AACH,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO7D;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAO7D;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAYf;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CA0Bf;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CA4C/C;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAO7D;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAsBxB;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CASxB"}
package/dist/git.js CHANGED
@@ -102,7 +102,10 @@ export async function runCopilotCli(worktreePath, prompt, model) {
102
102
  resolvePromise({ exitCode: code ?? 1, stderr });
103
103
  });
104
104
  child.on("error", (err) => {
105
- resolvePromise({ exitCode: 1, stderr: err.message });
105
+ const message = err.code === "ENOENT"
106
+ ? "Copilot CLI not found. Install it (https://docs.github.com/en/copilot/github-copilot-in-the-cli) and ensure 'copilot' is on your PATH."
107
+ : err.message;
108
+ resolvePromise({ exitCode: 1, stderr: message });
106
109
  });
107
110
  });
108
111
  }
@@ -131,8 +134,9 @@ export async function captureChanges(worktreePath, baseSha) {
131
134
  const { stdout } = await execFileAsync("git", ["diff", "--staged", baseSha], { cwd: worktreePath, maxBuffer: 10 * 1024 * 1024 });
132
135
  return stdout;
133
136
  }
134
- catch {
135
- return "";
137
+ catch (err) {
138
+ console.error(`[phone-a-friend] diff capture failed in ${worktreePath}:`, err instanceof Error ? err.message : err);
139
+ return null;
136
140
  }
137
141
  }
138
142
  /**
package/dist/git.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"git.js","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -2,15 +2,18 @@
2
2
  // ABOUTME: MCP server that invokes Copilot CLI with a different model.
3
3
  // ABOUTME: Enables cross-model subagent calls from VS Code Copilot Chat.
4
4
  import { resolve } from "node:path";
5
+ import { createRequire } from "node:module";
5
6
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
6
7
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
7
8
  import { z } from "zod";
8
- import { RESPONSE_FILENAME, AVAILABLE_MODELS, wrapPrompt, generateWorktreePath, promptSizeWarning, } from "./util.js";
9
+ import { RESPONSE_FILENAME, AVAILABLE_MODELS, TOOL_MODES, wrapPrompt, generateWorktreePath, promptSizeWarning, } from "./util.js";
9
10
  import { isGitRepo, getGitRoot, createWorktree, removeWorktree, runCopilotCli, getHeadSha, captureChanges, readAndRemoveResponse, } from "./git.js";
11
+ const require = createRequire(import.meta.url);
12
+ const { version } = require("../package.json");
10
13
  // --- MCP Server Setup ---
11
14
  const server = new McpServer({
12
15
  name: "phone-a-friend",
13
- version: "0.1.0",
16
+ version,
14
17
  });
15
18
  server.registerTool("phone_a_friend", {
16
19
  title: "Phone a Friend",
@@ -24,6 +27,7 @@ server.registerTool("phone_a_friend", {
24
27
  "- The user wants a specific model for a subtask (e.g., a faster model for simple work, or a different vendor)\n" +
25
28
  "- The user mentions \"phone a friend\", \"subagent\", or \"different model\"\n" +
26
29
  "- The user wants to delegate a focused coding task to another model and get the changes back as a diff\n" +
30
+ "- Use mode \"query\" when you only want the agent's analysis — reviews, explanations, architectural assessments — not file changes\n" +
27
31
  "\n\nWhen NOT to use this tool:\n" +
28
32
  "- The current model can handle the task directly — don't add round-trip overhead for no benefit\n" +
29
33
  "- The task requires seeing uncommitted changes and the user hasn't provided the file contents\n" +
@@ -49,9 +53,17 @@ server.registerTool("phone_a_friend", {
49
53
  "repository. Always pass this explicitly using the workspace " +
50
54
  "path from your conversation context — the server's own working " +
51
55
  "directory is not the user's workspace."),
56
+ mode: z
57
+ .enum(TOOL_MODES)
58
+ .optional()
59
+ .default("default")
60
+ .describe('"default" returns the agent response and a unified diff of file changes. ' +
61
+ '"query" discards all file changes and returns only the agent response — ' +
62
+ "use for reviews, analysis, or questions where you don't need code changes."),
52
63
  }),
53
- }, async ({ prompt, model, working_directory }) => {
64
+ }, async ({ prompt, model, working_directory, mode }) => {
54
65
  const workDir = resolve(working_directory);
66
+ const toolMode = mode ?? "default";
55
67
  // Validate git repo
56
68
  if (!(await isGitRepo(workDir))) {
57
69
  return {
@@ -73,12 +85,10 @@ server.registerTool("phone_a_friend", {
73
85
  // even if the agent commits during its run.
74
86
  const baseSha = await getHeadSha(worktreePath);
75
87
  // Run the CLI agent
76
- const wrappedPrompt = wrapPrompt(prompt);
88
+ const wrappedPrompt = wrapPrompt(prompt, toolMode);
77
89
  const { exitCode, stderr } = await runCopilotCli(worktreePath, wrappedPrompt, model);
78
90
  // Read the response file before diffing
79
91
  const response = await readAndRemoveResponse(worktreePath, RESPONSE_FILENAME);
80
- // Capture all file changes
81
- const diff = await captureChanges(worktreePath, baseSha);
82
92
  // Build result
83
93
  const parts = [];
84
94
  if (response) {
@@ -89,11 +99,21 @@ server.registerTool("phone_a_friend", {
89
99
  "*No response file was created. The agent may have failed " +
90
100
  "to follow the message-in-a-bottle instructions.*");
91
101
  }
92
- if (diff.trim()) {
93
- parts.push("## File Changes (unified diff)\n\n```diff\n" + diff + "\n```");
94
- }
95
- else {
96
- parts.push("## File Changes\n\nNo file changes were made.");
102
+ // Capture and include file changes only in default mode
103
+ if (toolMode === "default") {
104
+ const diff = await captureChanges(worktreePath, baseSha);
105
+ if (diff === null) {
106
+ parts.push("## File Changes\n\n" +
107
+ "**Warning:** Diff capture failed (output may have exceeded the " +
108
+ "10 MB buffer limit). The agent may have made changes that are " +
109
+ "not shown here.");
110
+ }
111
+ else if (diff.trim()) {
112
+ parts.push("## File Changes (unified diff)\n\n```diff\n" + diff + "\n```");
113
+ }
114
+ else {
115
+ parts.push("## File Changes\n\nNo file changes were made.");
116
+ }
97
117
  }
98
118
  if (exitCode !== 0) {
99
119
  parts.push(`## Warnings\n\nCopilot CLI exited with code ${exitCode}.` +
@@ -112,8 +132,8 @@ server.registerTool("phone_a_friend", {
112
132
  try {
113
133
  await removeWorktree(gitRoot, worktreePath);
114
134
  }
115
- catch {
116
- // Best effort cleanup
135
+ catch (err) {
136
+ console.error(`[phone-a-friend] worktree cleanup failed for ${worktreePath}:`, err instanceof Error ? err.message : err);
117
137
  }
118
138
  }
119
139
  });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/util.d.ts CHANGED
@@ -1,10 +1,13 @@
1
+ export declare const TOOL_MODES: readonly ["default", "query"];
2
+ export type ToolMode = (typeof TOOL_MODES)[number];
1
3
  export declare const RESPONSE_FILENAME = ".paf-response.md";
2
4
  export declare const AVAILABLE_MODELS: readonly ["claude-sonnet-4.5", "claude-haiku-4.5", "claude-opus-4.6", "claude-opus-4.6-fast", "claude-opus-4.5", "claude-sonnet-4", "gemini-3-pro-preview", "gpt-5.3-codex", "gpt-5.2-codex", "gpt-5.2", "gpt-5.1-codex-max", "gpt-5.1-codex", "gpt-5.1", "gpt-5", "gpt-5.1-codex-mini", "gpt-5-mini", "gpt-4.1"];
3
5
  /**
4
6
  * Wraps the user's prompt with instructions for the subagent about
5
- * the message-in-a-bottle response file and push restrictions.
7
+ * the message-in-a-bottle response file and operating constraints.
8
+ * In query mode, tells the subagent changes will be discarded.
6
9
  */
7
- export declare function wrapPrompt(userPrompt: string): string;
10
+ export declare function wrapPrompt(userPrompt: string, mode?: ToolMode): string;
8
11
  /**
9
12
  * Generates a unique worktree path based on timestamp and random suffix.
10
13
  */
@@ -1 +1 @@
1
- {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,iBAAiB,qBAAqB,CAAC;AAEpD,eAAO,MAAM,gBAAgB,mTAkBnB,CAAC;AAEX;;;GAGG;AACH,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAgBrD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAI5D;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE7C;AAED,eAAO,MAAM,6BAA6B,QAAY,CAAC;AAIvD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAY/D"}
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,UAAU,+BAAgC,CAAC;AACxD,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnD,eAAO,MAAM,iBAAiB,qBAAqB,CAAC;AAEpD,eAAO,MAAM,gBAAgB,mTAkBnB,CAAC;AAEX;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,GAAE,QAAoB,GAAG,MAAM,CAgCjF;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAI5D;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE7C;AAED,eAAO,MAAM,6BAA6B,QAAY,CAAC;AAIvD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAY/D"}
package/dist/util.js CHANGED
@@ -1,6 +1,7 @@
1
1
  // ABOUTME: Pure utility functions for prompt wrapping and path generation.
2
2
  // ABOUTME: Separated from server startup so tests can import without side effects.
3
3
  import { join } from "node:path";
4
+ export const TOOL_MODES = ["default", "query"];
4
5
  export const RESPONSE_FILENAME = ".paf-response.md";
5
6
  export const AVAILABLE_MODELS = [
6
7
  "claude-sonnet-4.5",
@@ -23,20 +24,36 @@ export const AVAILABLE_MODELS = [
23
24
  ];
24
25
  /**
25
26
  * Wraps the user's prompt with instructions for the subagent about
26
- * the message-in-a-bottle response file and push restrictions.
27
+ * the message-in-a-bottle response file and operating constraints.
28
+ * In query mode, tells the subagent changes will be discarded.
27
29
  */
28
- export function wrapPrompt(userPrompt) {
30
+ export function wrapPrompt(userPrompt, mode = "default") {
31
+ if (mode === "query") {
32
+ return `## CRITICAL INSTRUCTIONS — READ BEFORE DOING ANYTHING
33
+
34
+ You are operating as a subagent inside an isolated git worktree for reference only. Any file changes you make will be discarded. Focus on analysis and your written response.
35
+
36
+ 1. **Do NOT modify files.** Any changes will be thrown away. The repository is available for you to read, not to edit.
37
+ 2. **When you are finished**, write your complete final response to the file \`${RESPONSE_FILENAME}\` in the repository root. This file is your ONLY communication channel back to the calling agent. Include:
38
+ - Your analysis or answer
39
+ - Any important findings or decisions
40
+ - Any warnings or caveats
41
+ 3. You MUST create the \`${RESPONSE_FILENAME}\` file. It is how you report back.
42
+
43
+ ## YOUR TASK
44
+
45
+ ${userPrompt}`;
46
+ }
29
47
  return `## CRITICAL INSTRUCTIONS — READ BEFORE DOING ANYTHING
30
48
 
31
49
  You are operating as a subagent inside an isolated git worktree. Follow these rules:
32
50
 
33
51
  1. **NEVER push to any remote.** Do not run \`git push\` under any circumstances.
34
- 2. **Commits are fine.** You may commit freely within this worktree.
35
- 3. **When you are finished**, write your complete final response to the file \`${RESPONSE_FILENAME}\` in the repository root. This file is your ONLY communication channel back to the calling agent. Include:
52
+ 2. **When you are finished**, write your complete final response to the file \`${RESPONSE_FILENAME}\` in the repository root. This file is your ONLY communication channel back to the calling agent. Include:
36
53
  - A summary of what you did
37
54
  - Any important findings or decisions
38
55
  - Any warnings or caveats
39
- 4. You MUST create the \`${RESPONSE_FILENAME}\` file even if you made no code changes. It is how you report back.
56
+ 3. You MUST create the \`${RESPONSE_FILENAME}\` file even if you made no code changes. It is how you report back.
40
57
 
41
58
  ## YOUR TASK
42
59
 
package/dist/util.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,mFAAmF;AAEnF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,CAAC,MAAM,iBAAiB,GAAG,kBAAkB,CAAC;AAEpD,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,mBAAmB;IACnB,kBAAkB;IAClB,iBAAiB;IACjB,sBAAsB;IACtB,iBAAiB;IACjB,iBAAiB;IACjB,sBAAsB;IACtB,eAAe;IACf,eAAe;IACf,SAAS;IACT,mBAAmB;IACnB,eAAe;IACf,SAAS;IACT,OAAO;IACP,oBAAoB;IACpB,YAAY;IACZ,SAAS;CACD,CAAC;AAEX;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,UAAkB;IAC3C,OAAO;;;;;;iFAMwE,iBAAiB;;;;2BAIvE,iBAAiB;;;;EAI1C,UAAU,EAAE,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAe;IAClD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1D,OAAO,IAAI,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,SAAS,IAAI,MAAM,EAAE,CAAC,CAAC;AACnE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,CAAS;IACnC,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC;AACzC,CAAC;AAED,MAAM,CAAC,MAAM,6BAA6B,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,QAAQ;AAEhE,MAAM,eAAe,GAAG,mDAAmD,CAAC;AAE5E;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAc;IAC9C,IAAI,MAAM,CAAC,MAAM,GAAG,6BAA6B,EAAE,CAAC;QAClD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAChD,OAAO,CACL,kEAAkE,MAAM,MAAM;QAC9E,+EAA+E;QAC/E,6EAA6E;QAC7E,gFAAgF;QAChF,YAAY,eAAe,EAAE,CAC9B,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,mFAAmF;AAEnF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,SAAS,EAAE,OAAO,CAAU,CAAC;AAGxD,MAAM,CAAC,MAAM,iBAAiB,GAAG,kBAAkB,CAAC;AAEpD,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,mBAAmB;IACnB,kBAAkB;IAClB,iBAAiB;IACjB,sBAAsB;IACtB,iBAAiB;IACjB,iBAAiB;IACjB,sBAAsB;IACtB,eAAe;IACf,eAAe;IACf,SAAS;IACT,mBAAmB;IACnB,eAAe;IACf,SAAS;IACT,OAAO;IACP,oBAAoB;IACpB,YAAY;IACZ,SAAS;CACD,CAAC;AAEX;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,UAAkB,EAAE,OAAiB,SAAS;IACvE,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;QACrB,OAAO;;;;;iFAKsE,iBAAiB;;;;2BAIvE,iBAAiB;;;;EAI1C,UAAU,EAAE,CAAC;IACb,CAAC;IAED,OAAO;;;;;iFAKwE,iBAAiB;;;;2BAIvE,iBAAiB;;;;EAI1C,UAAU,EAAE,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAe;IAClD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1D,OAAO,IAAI,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,SAAS,IAAI,MAAM,EAAE,CAAC,CAAC;AACnE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,CAAS;IACnC,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC;AACzC,CAAC;AAED,MAAM,CAAC,MAAM,6BAA6B,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,QAAQ;AAEhE,MAAM,eAAe,GAAG,mDAAmD,CAAC;AAE5E;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAc;IAC9C,IAAI,MAAM,CAAC,MAAM,GAAG,6BAA6B,EAAE,CAAC;QAClD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAChD,OAAO,CACL,kEAAkE,MAAM,MAAM;QAC9E,+EAA+E;QAC/E,6EAA6E;QAC7E,gFAAgF;QAChF,YAAY,eAAe,EAAE,CAC9B,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bexelbie/phone-a-friend",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "MCP server that lets VS Code Copilot Chat invoke Copilot CLI with a different model",
5
5
  "repository": {
6
6
  "type": "git",
@@ -34,7 +34,8 @@
34
34
  "node": ">=22.0.0"
35
35
  },
36
36
  "dependencies": {
37
- "@modelcontextprotocol/sdk": "^1.26.0"
37
+ "@modelcontextprotocol/sdk": "^1.26.0",
38
+ "zod": "^4.3.6"
38
39
  },
39
40
  "devDependencies": {
40
41
  "@types/node": "^22.0.0",