@bexelbie/phone-a-friend 0.1.0 → 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
@@ -28,7 +28,7 @@ GitHub Copilot CLI does not provide a way to retrieve just the agent's final res
28
28
 
29
29
  ## Prerequisites
30
30
 
31
- - **Node.js** >= 20.0.0
31
+ - **Node.js** >= 22.0.0
32
32
  - **GitHub Copilot CLI** — installed, configured, and authenticated. See [About GitHub Copilot in the CLI](https://docs.github.com/en/copilot/github-copilot-in-the-cli/about-github-copilot-in-the-cli) for setup instructions.
33
33
  - **Git** — for worktree management
34
34
  - A **git repository** to work in (the tool operates on git repos)
@@ -39,54 +39,24 @@ Verify Copilot CLI is working:
39
39
  copilot --help
40
40
  ```
41
41
 
42
- ## Installation
42
+ ## Setup
43
43
 
44
- ### From source
44
+ In VS Code, open the Command Palette and run `MCP: Add Server...`, select `npm Package`, and enter `@bexelbie/phone-a-friend`.
45
45
 
46
- ```bash
47
- git clone https://github.com/YOUR_USERNAME/phone-a-friend.git
48
- cd phone-a-friend
49
- npm install
50
- npm run build
51
- ```
52
-
53
- ### As an npm package
54
-
55
- ```bash
56
- npm install -g @bexelbie/phone-a-friend
57
- ```
58
-
59
- ## Configuration
60
-
61
- Add to your VS Code MCP configuration (`.vscode/mcp.json` in your workspace, or user-level via `MCP: Open User Configuration`):
62
-
63
- ```json
64
- {
65
- "servers": {
66
- "phoneAFriend": {
67
- "type": "stdio",
68
- "command": "node",
69
- "args": ["/absolute/path/to/phone-a-friend/dist/index.js"]
70
- }
71
- }
72
- }
73
- ```
74
-
75
- Or if installed globally via npm:
46
+ Or add it manually to `.vscode/mcp.json` (workspace) or via `MCP: Open User Configuration` (global):
76
47
 
77
48
  ```json
78
49
  {
79
50
  "servers": {
80
- "phoneAFriend": {
51
+ "phone-a-friend": {
81
52
  "type": "stdio",
82
- "command": "phone-a-friend"
53
+ "command": "npx",
54
+ "args": ["@bexelbie/phone-a-friend"]
83
55
  }
84
56
  }
85
57
  }
86
58
  ```
87
59
 
88
- See [Use MCP servers in VS Code](https://code.visualstudio.com/docs/copilot/customization/mcp-servers) for details on MCP server configuration.
89
-
90
60
  ## Usage
91
61
 
92
62
  Once configured, the `phone_a_friend` tool is available in GitHub Copilot Chat. You tell the agent what you want, and the agent decides how to use the tool — constructing the prompt, choosing the model, including context, and applying the returned diff.
@@ -150,11 +120,13 @@ You can direct the model to pass any model name directly — GitHub Copilot CLI
150
120
  | `prompt` | Yes | The task or question for the other model. Include relevant context. |
151
121
  | `model` | Yes | Which AI model to use (see list above). |
152
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"`. |
153
124
 
154
125
  ## Safety
155
126
 
156
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.
157
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.
158
130
  - **Automatic cleanup**: Worktrees are removed after each invocation, even on errors.
159
131
  - **No secrets exposure**: The subagent has the same access as `copilot` CLI running locally — no additional permissions are granted.
160
132
 
@@ -168,12 +140,59 @@ You can direct the model to pass any model name directly — GitHub Copilot CLI
168
140
  ## Development
169
141
 
170
142
  ```bash
143
+ git clone https://github.com/bexelbie/phone-a-friend.git
144
+ cd phone-a-friend
171
145
  npm install
172
146
  npm run build # Compile TypeScript
173
147
  npm test # Run tests
174
148
  npm run dev # Watch mode for development
175
149
  ```
176
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
+
177
196
  ## License
178
197
 
179
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,7 +1,11 @@
1
1
  {
2
2
  "name": "@bexelbie/phone-a-friend",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "MCP server that lets VS Code Copilot Chat invoke Copilot CLI with a different model",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/bexelbie/phone-a-friend"
8
+ },
5
9
  "type": "module",
6
10
  "main": "dist/index.js",
7
11
  "bin": {
@@ -27,10 +31,11 @@
27
31
  ],
28
32
  "license": "MIT",
29
33
  "engines": {
30
- "node": ">=20.0.0"
34
+ "node": ">=22.0.0"
31
35
  },
32
36
  "dependencies": {
33
- "@modelcontextprotocol/sdk": "^1.26.0"
37
+ "@modelcontextprotocol/sdk": "^1.26.0",
38
+ "zod": "^4.3.6"
34
39
  },
35
40
  "devDependencies": {
36
41
  "@types/node": "^22.0.0",