sibling-repo 0.1.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/.env.example +17 -0
- package/LICENSE +21 -0
- package/README.md +183 -0
- package/dist/agent.d.ts +2 -0
- package/dist/agent.js +77 -0
- package/dist/agent.js.map +1 -0
- package/dist/config.d.ts +2 -0
- package/dist/config.js +70 -0
- package/dist/config.js.map +1 -0
- package/dist/prompts.d.ts +3 -0
- package/dist/prompts.js +61 -0
- package/dist/prompts.js.map +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.js +96 -0
- package/dist/server.js.map +1 -0
- package/dist/types.d.ts +23 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +48 -0
package/.env.example
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# .env.example — copy to ~/.sibling-repo/.env and fill in
|
|
2
|
+
|
|
3
|
+
# Sibling repositories: JSON map of short names to absolute paths
|
|
4
|
+
# Example: {"api":"/home/you/repos/api","web":"/home/you/repos/web-app"}
|
|
5
|
+
SIBLING_REPOS=
|
|
6
|
+
|
|
7
|
+
# Claude subscription OAuth token (run: claude setup-token)
|
|
8
|
+
CLAUDE_CODE_OAUTH_TOKEN=
|
|
9
|
+
|
|
10
|
+
# Default models per agent mode
|
|
11
|
+
# Options: haiku, sonnet, opus
|
|
12
|
+
SIBLING_MODEL_EXPLORE=sonnet
|
|
13
|
+
SIBLING_MODEL_PLAN=opus
|
|
14
|
+
SIBLING_MODEL_EXECUTE=opus
|
|
15
|
+
|
|
16
|
+
# Max agent turns before termination
|
|
17
|
+
SIBLING_MAX_TURNS=50
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Delirio
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# sibling-repo
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/sibling-repo)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
|
|
6
|
+
An MCP server that gives Claude Code agents the ability to spawn fully contextualized Claude Code sessions in sibling repositories. Ask questions about a backend API from your frontend repo, plan cross-repo implementations, or trigger changes in another codebase — all through a single tool call.
|
|
7
|
+
|
|
8
|
+
## Quick Start
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
# 1. Generate an OAuth token from your Claude subscription
|
|
12
|
+
claude setup-token
|
|
13
|
+
# Copy the output token
|
|
14
|
+
|
|
15
|
+
# 2. Create config directory and .env file
|
|
16
|
+
mkdir -p ~/.sibling-repo
|
|
17
|
+
cat > ~/.sibling-repo/.env << 'EOF'
|
|
18
|
+
CLAUDE_CODE_OAUTH_TOKEN=<paste-your-token-here>
|
|
19
|
+
SIBLING_REPOS={"backend":"/path/to/backend","frontend":"/path/to/frontend"}
|
|
20
|
+
EOF
|
|
21
|
+
|
|
22
|
+
# 3. Register with Claude Code (npx — no install needed)
|
|
23
|
+
claude mcp add --scope user sibling-repo -- npx -y sibling-repo
|
|
24
|
+
|
|
25
|
+
# 4. Launch Claude Code and try it
|
|
26
|
+
claude
|
|
27
|
+
> Use sibling-repo to explore the backend and find the check-in endpoint contract
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## How It Works
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
┌─────────────────────────────────────────────┐
|
|
34
|
+
│ Claude Code session (e.g., in frontend repo)│
|
|
35
|
+
│ │
|
|
36
|
+
│ Agent calls: ask_repo("backend", prompt) │
|
|
37
|
+
│ │ │
|
|
38
|
+
│ ▼ │
|
|
39
|
+
│ ┌─────────────────────────┐ │
|
|
40
|
+
│ │ sibling-repo MCP server│ (stdio) │
|
|
41
|
+
│ │ (Node.js process) │ │
|
|
42
|
+
│ └──────────┬──────────────┘ │
|
|
43
|
+
│ │ │
|
|
44
|
+
└─────────────┼───────────────────────────────┘
|
|
45
|
+
│ Spawns via Claude Agent SDK
|
|
46
|
+
▼
|
|
47
|
+
┌─────────────────────────────────────────────┐
|
|
48
|
+
│ Ephemeral Claude Code session │
|
|
49
|
+
│ cwd: ~/repos/backend │
|
|
50
|
+
│ Loads backend's CLAUDE.md automatically │
|
|
51
|
+
│ Tools scoped by mode (explore/plan/execute)│
|
|
52
|
+
│ Returns result to MCP server │
|
|
53
|
+
└─────────────────────────────────────────────┘
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
When you call `ask_repo`, sibling-repo spawns a real Claude Code session in the target repository using the [Claude Agent SDK](https://platform.claude.com/docs/en/agent-sdk/overview). The spawned agent loads the target repo's `CLAUDE.md`, has tools scoped to that directory, and operates in a configurable mode. From the calling agent's perspective, it's a single tool call that returns the sibling agent's answer.
|
|
57
|
+
|
|
58
|
+
## Tools
|
|
59
|
+
|
|
60
|
+
### `ask_repo`
|
|
61
|
+
|
|
62
|
+
Spawn a Claude Code agent in a sibling repository.
|
|
63
|
+
|
|
64
|
+
| Parameter | Type | Default | Description |
|
|
65
|
+
|-----------|------|---------|-------------|
|
|
66
|
+
| `repo` | string | required | Repository short name from `SIBLING_REPOS` |
|
|
67
|
+
| `prompt` | string | required | The task or question for the sibling agent |
|
|
68
|
+
| `mode` | `"explore"` \| `"plan"` \| `"execute"` | `"explore"` | Agent mode |
|
|
69
|
+
| `model` | string | per-mode default | Model override: `"haiku"`, `"sonnet"`, `"opus"` |
|
|
70
|
+
|
|
71
|
+
### `list_repos`
|
|
72
|
+
|
|
73
|
+
Returns the configured repositories and their paths. No parameters.
|
|
74
|
+
|
|
75
|
+
## Agent Modes
|
|
76
|
+
|
|
77
|
+
| Mode | Default Model | Tools | Purpose |
|
|
78
|
+
|------|--------------|-------|---------|
|
|
79
|
+
| **explore** | sonnet | Read, Grep, Glob, Bash (read-only) | Codebase investigation — find endpoints, schemas, architecture |
|
|
80
|
+
| **plan** | opus | Read, Grep, Glob, Bash (read-only) | Design implementation plans without making changes |
|
|
81
|
+
| **execute** | opus | Read, Grep, Glob, Bash, Write, Edit, MultiEdit | Make changes in the sibling repo |
|
|
82
|
+
|
|
83
|
+
## Configuration
|
|
84
|
+
|
|
85
|
+
sibling-repo reads from a `.env` file, searched in order:
|
|
86
|
+
|
|
87
|
+
1. `SIBLING_ENV_PATH` environment variable (explicit override)
|
|
88
|
+
2. `~/.sibling-repo/.env` (user-level default)
|
|
89
|
+
3. `./.env` (current directory)
|
|
90
|
+
|
|
91
|
+
### Environment Variables
|
|
92
|
+
|
|
93
|
+
| Variable | Required | Default | Description |
|
|
94
|
+
|----------|----------|---------|-------------|
|
|
95
|
+
| `SIBLING_REPOS` | Yes | — | JSON map of repo names to absolute paths |
|
|
96
|
+
| `CLAUDE_CODE_OAUTH_TOKEN` | Yes | — | OAuth token from `claude setup-token` |
|
|
97
|
+
| `SIBLING_MODEL_EXPLORE` | No | `sonnet` | Default model for explore mode |
|
|
98
|
+
| `SIBLING_MODEL_PLAN` | No | `opus` | Default model for plan mode |
|
|
99
|
+
| `SIBLING_MODEL_EXECUTE` | No | `opus` | Default model for execute mode |
|
|
100
|
+
| `SIBLING_MAX_TURNS` | No | `50` | Max agent turns before termination |
|
|
101
|
+
|
|
102
|
+
### `SIBLING_REPOS` format
|
|
103
|
+
|
|
104
|
+
A JSON object mapping short names (used in tool calls) to absolute paths:
|
|
105
|
+
|
|
106
|
+
```json
|
|
107
|
+
{
|
|
108
|
+
"backend": "/Users/you/repos/api-server",
|
|
109
|
+
"frontend": "/Users/you/repos/web-app",
|
|
110
|
+
"shared": "/Users/you/repos/shared-lib"
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Paths support `~` and `$HOME` expansion. Missing paths produce a startup warning but don't prevent the server from running.
|
|
115
|
+
|
|
116
|
+
## Usage Examples
|
|
117
|
+
|
|
118
|
+
**Explore a backend API from the frontend:**
|
|
119
|
+
```
|
|
120
|
+
ask_repo("backend", "What is the HTTP method, path, request body, and response shape for the user check-in endpoint?")
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
**Plan a cross-repo feature:**
|
|
124
|
+
```
|
|
125
|
+
ask_repo("backend", "Design a new GET endpoint at /api/v1/workouts/history that returns the user's last 30 workout sessions. Follow existing route patterns.", "plan")
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
**Execute changes in a sibling repo:**
|
|
129
|
+
```
|
|
130
|
+
ask_repo("backend", "Create a new GET endpoint at /api/v1/workouts/history that returns the user's last 30 sessions from Firestore.", "execute")
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Development
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
# Clone and build
|
|
137
|
+
git clone https://github.com/AmirAlsad/sibling-repo.git
|
|
138
|
+
cd sibling-repo
|
|
139
|
+
npm install
|
|
140
|
+
npm run build
|
|
141
|
+
|
|
142
|
+
# Run tests
|
|
143
|
+
npm test
|
|
144
|
+
|
|
145
|
+
# Register local build with Claude Code
|
|
146
|
+
claude mcp add --scope user sibling-repo -- node ./dist/server.js
|
|
147
|
+
|
|
148
|
+
# Development with auto-reload
|
|
149
|
+
npm run dev
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Project Structure
|
|
153
|
+
|
|
154
|
+
```
|
|
155
|
+
src/
|
|
156
|
+
server.ts MCP server entry point, tool registration
|
|
157
|
+
agent.ts Claude Agent SDK wrapper, mode configurations
|
|
158
|
+
prompts.ts System prompt constants (explore/plan/execute)
|
|
159
|
+
config.ts .env loading, SIBLING_REPOS parsing, path validation
|
|
160
|
+
types.ts Shared TypeScript types
|
|
161
|
+
tests/
|
|
162
|
+
config.test.ts Config parsing, path resolution, defaults
|
|
163
|
+
agent.test.ts Mode configs, result extraction, error handling
|
|
164
|
+
server.test.ts MCP integration tests via stdio client transport
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Troubleshooting
|
|
168
|
+
|
|
169
|
+
**"SIBLING_REPOS is not set"**
|
|
170
|
+
Create `~/.sibling-repo/.env` with your repo configuration. See [Configuration](#configuration).
|
|
171
|
+
|
|
172
|
+
**"Authentication failed"**
|
|
173
|
+
Run `claude setup-token` to generate a fresh OAuth token and update your `.env` file. Ensure `ANTHROPIC_API_KEY` is not set in your shell (it takes precedence over OAuth).
|
|
174
|
+
|
|
175
|
+
**"Repo path does not exist"**
|
|
176
|
+
Check the path in your `SIBLING_REPOS` configuration. Paths must be absolute. `~` and `$HOME` are expanded automatically.
|
|
177
|
+
|
|
178
|
+
**Agent returns no result**
|
|
179
|
+
The spawned agent may have hit `SIBLING_MAX_TURNS`. Increase the limit in your `.env` or write a more specific prompt.
|
|
180
|
+
|
|
181
|
+
## License
|
|
182
|
+
|
|
183
|
+
[MIT](LICENSE)
|
package/dist/agent.d.ts
ADDED
package/dist/agent.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
2
|
+
import { EXPLORE_PROMPT, PLAN_PROMPT, EXECUTE_PROMPT } from "./prompts.js";
|
|
3
|
+
const MODE_CONFIGS = {
|
|
4
|
+
explore: {
|
|
5
|
+
allowedTools: ["Read", "Grep", "Glob", "Bash"],
|
|
6
|
+
disallowedTools: ["Write", "Edit", "MultiEdit"],
|
|
7
|
+
permissionMode: "bypassPermissions",
|
|
8
|
+
allowDangerouslySkipPermissions: true,
|
|
9
|
+
defaultModel: "sonnet",
|
|
10
|
+
systemPromptAppend: EXPLORE_PROMPT,
|
|
11
|
+
},
|
|
12
|
+
plan: {
|
|
13
|
+
allowedTools: ["Read", "Grep", "Glob", "Bash"],
|
|
14
|
+
disallowedTools: ["Write", "Edit", "MultiEdit"],
|
|
15
|
+
permissionMode: "plan",
|
|
16
|
+
allowDangerouslySkipPermissions: false,
|
|
17
|
+
defaultModel: "opus",
|
|
18
|
+
systemPromptAppend: PLAN_PROMPT,
|
|
19
|
+
},
|
|
20
|
+
execute: {
|
|
21
|
+
allowedTools: ["Read", "Grep", "Glob", "Bash", "Write", "Edit", "MultiEdit"],
|
|
22
|
+
disallowedTools: [],
|
|
23
|
+
permissionMode: "acceptEdits",
|
|
24
|
+
allowDangerouslySkipPermissions: false,
|
|
25
|
+
defaultModel: "opus",
|
|
26
|
+
systemPromptAppend: EXECUTE_PROMPT,
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
export async function runAgent(repoPath, prompt, mode, model, maxTurns) {
|
|
30
|
+
const config = MODE_CONFIGS[mode];
|
|
31
|
+
const options = {
|
|
32
|
+
cwd: repoPath,
|
|
33
|
+
systemPrompt: {
|
|
34
|
+
type: "preset",
|
|
35
|
+
preset: "claude_code",
|
|
36
|
+
append: config.systemPromptAppend,
|
|
37
|
+
},
|
|
38
|
+
allowedTools: config.allowedTools,
|
|
39
|
+
disallowedTools: config.disallowedTools,
|
|
40
|
+
permissionMode: config.permissionMode,
|
|
41
|
+
model,
|
|
42
|
+
maxTurns,
|
|
43
|
+
};
|
|
44
|
+
if (config.allowDangerouslySkipPermissions) {
|
|
45
|
+
options.allowDangerouslySkipPermissions = true;
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
let result = "";
|
|
49
|
+
for await (const message of query({ prompt, options })) {
|
|
50
|
+
if (message.type === "result") {
|
|
51
|
+
if ("result" in message) {
|
|
52
|
+
result = message.result;
|
|
53
|
+
}
|
|
54
|
+
else if ("errors" in message) {
|
|
55
|
+
const errors = message.errors.join("; ");
|
|
56
|
+
throw new Error(`Agent error (${message.subtype}): ${errors}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (!result) {
|
|
61
|
+
throw new Error("Agent returned no result");
|
|
62
|
+
}
|
|
63
|
+
return result;
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
67
|
+
if (msg.includes("auth") ||
|
|
68
|
+
msg.includes("token") ||
|
|
69
|
+
msg.includes("unauthorized") ||
|
|
70
|
+
msg.includes("401")) {
|
|
71
|
+
throw new Error(`Authentication failed. Run \`claude setup-token\` to generate a new OAuth token ` +
|
|
72
|
+
`and add it to your .env file as CLAUDE_CODE_OAUTH_TOKEN. Original error: ${msg}`);
|
|
73
|
+
}
|
|
74
|
+
throw err;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
package/dist/config.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { config as dotenvConfig } from "dotenv";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { homedir } from "node:os";
|
|
5
|
+
function resolvePath(rawPath) {
|
|
6
|
+
const home = homedir();
|
|
7
|
+
if (rawPath.startsWith("~/")) {
|
|
8
|
+
return join(home, rawPath.slice(2));
|
|
9
|
+
}
|
|
10
|
+
return rawPath.replace(/\$HOME/g, home);
|
|
11
|
+
}
|
|
12
|
+
function findEnvFile() {
|
|
13
|
+
const candidates = [
|
|
14
|
+
process.env.SIBLING_ENV_PATH,
|
|
15
|
+
join(homedir(), ".sibling-repo", ".env"),
|
|
16
|
+
join(process.cwd(), ".env"),
|
|
17
|
+
];
|
|
18
|
+
for (const candidate of candidates) {
|
|
19
|
+
if (candidate && existsSync(candidate)) {
|
|
20
|
+
return candidate;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
export function loadConfig() {
|
|
26
|
+
const envPath = findEnvFile();
|
|
27
|
+
if (envPath) {
|
|
28
|
+
dotenvConfig({ path: envPath });
|
|
29
|
+
console.error(`[sibling-repo] Loaded config from ${envPath}`);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
console.error("[sibling-repo] No .env file found. Checking environment variables...");
|
|
33
|
+
}
|
|
34
|
+
const rawRepos = process.env.SIBLING_REPOS;
|
|
35
|
+
if (!rawRepos) {
|
|
36
|
+
throw new Error('SIBLING_REPOS is not set. Create ~/.sibling-repo/.env with:\n' +
|
|
37
|
+
'SIBLING_REPOS={"backend":"/path/to/backend","frontend":"/path/to/frontend"}\n' +
|
|
38
|
+
"See README.md for setup instructions.");
|
|
39
|
+
}
|
|
40
|
+
let parsed;
|
|
41
|
+
try {
|
|
42
|
+
parsed = JSON.parse(rawRepos);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
throw new Error(`SIBLING_REPOS is not valid JSON: ${rawRepos}\n` +
|
|
46
|
+
'Expected format: {"name":"/absolute/path"}');
|
|
47
|
+
}
|
|
48
|
+
const repos = new Map();
|
|
49
|
+
for (const [name, rawPath] of Object.entries(parsed)) {
|
|
50
|
+
const resolvedPath = resolvePath(rawPath);
|
|
51
|
+
const pathExists = existsSync(resolvedPath);
|
|
52
|
+
const hasCLAUDEmd = pathExists && existsSync(join(resolvedPath, "CLAUDE.md"));
|
|
53
|
+
if (!pathExists) {
|
|
54
|
+
console.error(`[sibling-repo] Warning: repo "${name}" path does not exist: ${resolvedPath}`);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
console.error(`[sibling-repo] Registered repo "${name}" → ${resolvedPath}${hasCLAUDEmd ? " (has CLAUDE.md)" : ""}`);
|
|
58
|
+
}
|
|
59
|
+
repos.set(name, { name, path: resolvedPath, hasCLAUDEmd });
|
|
60
|
+
}
|
|
61
|
+
const models = {
|
|
62
|
+
explore: process.env.SIBLING_MODEL_EXPLORE ?? "sonnet",
|
|
63
|
+
plan: process.env.SIBLING_MODEL_PLAN ?? "opus",
|
|
64
|
+
execute: process.env.SIBLING_MODEL_EXECUTE ?? "opus",
|
|
65
|
+
};
|
|
66
|
+
const maxTurns = parseInt(process.env.SIBLING_MAX_TURNS ?? "50", 10);
|
|
67
|
+
console.error(`[sibling-repo] ${repos.size} repo(s) configured, maxTurns=${maxTurns}`);
|
|
68
|
+
return { repos, models, maxTurns };
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare const EXPLORE_PROMPT = "You are a file search specialist. You excel at thoroughly navigating and exploring codebases.\n\n=== CRITICAL: READ-ONLY MODE - NO FILE MODIFICATIONS ===\nThis is a READ-ONLY exploration task. You are STRICTLY PROHIBITED from:\n- Creating new files (no Write, touch, or file creation of any kind)\n- Modifying existing files (no Edit operations)\n- Deleting files (no rm or deletion)\n- Moving or copying files (no mv or cp)\n- Creating temporary files anywhere, including /tmp\n- Using redirect operators (>, >>, |) or heredocs to write to files\n- Running ANY commands that change system state\n\nYour role is EXCLUSIVELY to search and analyze existing code. You do NOT have access to file editing tools \u2014 attempting to edit files will fail.\n\nYour strengths:\n- Rapidly finding files using glob patterns\n- Searching code and text with powerful regex patterns\n- Reading and analyzing file contents\n\nUse Bash ONLY for read-only operations (ls, git status, git log, git diff, find, cat, head, tail).\nNEVER use Bash for: mkdir, touch, rm, cp, mv, git add, git commit, npm install, pip install, or any file creation/modification.\n\nWhen reporting API endpoints, include: HTTP method, path, request body shape, response shape. When reporting data models, include: collection/table name, field names and types, relationships.\n\nComplete the search request efficiently and report your findings clearly and concisely.";
|
|
2
|
+
export declare const PLAN_PROMPT = "You are a software architect and planning specialist. Your role is to explore the codebase and design implementation plans.\n\n=== CRITICAL: READ-ONLY MODE - NO FILE MODIFICATIONS ===\nThis is a READ-ONLY planning task. You are STRICTLY PROHIBITED from:\n- Creating new files (no Write, touch, or file creation of any kind)\n- Modifying existing files (no Edit operations)\n- Deleting files (no rm or deletion)\n- Moving or copying files (no mv or cp)\n- Creating temporary files anywhere, including /tmp\n- Using redirect operators (>, >>, |) or heredocs to write to files\n- Running ANY commands that change system state\n\nYour role is EXCLUSIVELY to explore the codebase and design implementation plans. You do NOT have access to file editing tools \u2014 attempting to edit files will fail.\n\nProcess:\n1. Understand Requirements: Focus on the requirements provided and apply your analysis throughout the design process.\n2. Find existing patterns and conventions using Glob, Grep, and Read tools.\n3. Design a plan that follows the project's established conventions (informed by CLAUDE.md if present).\n\nYour plan should include:\n- Files to create or modify (with paths)\n- The changes needed in each file (described precisely, with code snippets)\n- Any new dependencies required\n- Testing considerations\n- Order of operations (what to do first)\n\nFormat the plan as a markdown document that another developer or agent could follow step-by-step.";
|
|
3
|
+
export declare const EXECUTE_PROMPT = "You are a code implementation specialist. You have full read-write access to this repository.\n\nMake the requested changes following the project's existing conventions (see CLAUDE.md if present). Write clean, idiomatic code that matches the patterns already established in the codebase.\n\nAfter making changes:\n1. Verify your changes compile/parse correctly if applicable\n2. Summarize exactly what you changed (files modified, created, deleted)\n3. Note any follow-up actions needed in other repos";
|
package/dist/prompts.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
export const EXPLORE_PROMPT = `You are a file search specialist. You excel at thoroughly navigating and exploring codebases.
|
|
2
|
+
|
|
3
|
+
=== CRITICAL: READ-ONLY MODE - NO FILE MODIFICATIONS ===
|
|
4
|
+
This is a READ-ONLY exploration task. You are STRICTLY PROHIBITED from:
|
|
5
|
+
- Creating new files (no Write, touch, or file creation of any kind)
|
|
6
|
+
- Modifying existing files (no Edit operations)
|
|
7
|
+
- Deleting files (no rm or deletion)
|
|
8
|
+
- Moving or copying files (no mv or cp)
|
|
9
|
+
- Creating temporary files anywhere, including /tmp
|
|
10
|
+
- Using redirect operators (>, >>, |) or heredocs to write to files
|
|
11
|
+
- Running ANY commands that change system state
|
|
12
|
+
|
|
13
|
+
Your role is EXCLUSIVELY to search and analyze existing code. You do NOT have access to file editing tools — attempting to edit files will fail.
|
|
14
|
+
|
|
15
|
+
Your strengths:
|
|
16
|
+
- Rapidly finding files using glob patterns
|
|
17
|
+
- Searching code and text with powerful regex patterns
|
|
18
|
+
- Reading and analyzing file contents
|
|
19
|
+
|
|
20
|
+
Use Bash ONLY for read-only operations (ls, git status, git log, git diff, find, cat, head, tail).
|
|
21
|
+
NEVER use Bash for: mkdir, touch, rm, cp, mv, git add, git commit, npm install, pip install, or any file creation/modification.
|
|
22
|
+
|
|
23
|
+
When reporting API endpoints, include: HTTP method, path, request body shape, response shape. When reporting data models, include: collection/table name, field names and types, relationships.
|
|
24
|
+
|
|
25
|
+
Complete the search request efficiently and report your findings clearly and concisely.`;
|
|
26
|
+
export const PLAN_PROMPT = `You are a software architect and planning specialist. Your role is to explore the codebase and design implementation plans.
|
|
27
|
+
|
|
28
|
+
=== CRITICAL: READ-ONLY MODE - NO FILE MODIFICATIONS ===
|
|
29
|
+
This is a READ-ONLY planning task. You are STRICTLY PROHIBITED from:
|
|
30
|
+
- Creating new files (no Write, touch, or file creation of any kind)
|
|
31
|
+
- Modifying existing files (no Edit operations)
|
|
32
|
+
- Deleting files (no rm or deletion)
|
|
33
|
+
- Moving or copying files (no mv or cp)
|
|
34
|
+
- Creating temporary files anywhere, including /tmp
|
|
35
|
+
- Using redirect operators (>, >>, |) or heredocs to write to files
|
|
36
|
+
- Running ANY commands that change system state
|
|
37
|
+
|
|
38
|
+
Your role is EXCLUSIVELY to explore the codebase and design implementation plans. You do NOT have access to file editing tools — attempting to edit files will fail.
|
|
39
|
+
|
|
40
|
+
Process:
|
|
41
|
+
1. Understand Requirements: Focus on the requirements provided and apply your analysis throughout the design process.
|
|
42
|
+
2. Find existing patterns and conventions using Glob, Grep, and Read tools.
|
|
43
|
+
3. Design a plan that follows the project's established conventions (informed by CLAUDE.md if present).
|
|
44
|
+
|
|
45
|
+
Your plan should include:
|
|
46
|
+
- Files to create or modify (with paths)
|
|
47
|
+
- The changes needed in each file (described precisely, with code snippets)
|
|
48
|
+
- Any new dependencies required
|
|
49
|
+
- Testing considerations
|
|
50
|
+
- Order of operations (what to do first)
|
|
51
|
+
|
|
52
|
+
Format the plan as a markdown document that another developer or agent could follow step-by-step.`;
|
|
53
|
+
export const EXECUTE_PROMPT = `You are a code implementation specialist. You have full read-write access to this repository.
|
|
54
|
+
|
|
55
|
+
Make the requested changes following the project's existing conventions (see CLAUDE.md if present). Write clean, idiomatic code that matches the patterns already established in the codebase.
|
|
56
|
+
|
|
57
|
+
After making changes:
|
|
58
|
+
1. Verify your changes compile/parse correctly if applicable
|
|
59
|
+
2. Summarize exactly what you changed (files modified, created, deleted)
|
|
60
|
+
3. Note any follow-up actions needed in other repos`;
|
|
61
|
+
//# sourceMappingURL=prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;;wFAwB0D,CAAC;AAEzF,MAAM,CAAC,MAAM,WAAW,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;kGA0BuE,CAAC;AAEnG,MAAM,CAAC,MAAM,cAAc,GAAG;;;;;;;oDAOsB,CAAC"}
|
package/dist/server.d.ts
ADDED
package/dist/server.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { existsSync } from "node:fs";
|
|
6
|
+
import { loadConfig } from "./config.js";
|
|
7
|
+
import { runAgent } from "./agent.js";
|
|
8
|
+
async function main() {
|
|
9
|
+
const config = loadConfig();
|
|
10
|
+
const repoNames = Array.from(config.repos.keys());
|
|
11
|
+
const repoListStr = repoNames.join(", ");
|
|
12
|
+
const server = new McpServer({
|
|
13
|
+
name: "sibling-repo",
|
|
14
|
+
version: "0.1.0",
|
|
15
|
+
});
|
|
16
|
+
server.tool("ask_repo", `Spawn a Claude Code agent in a sibling repository to explore code, plan implementations, or execute changes. Use this when you need to understand APIs, schemas, architecture, or conventions from another repo in this project.
|
|
17
|
+
|
|
18
|
+
Available repos: ${repoListStr}
|
|
19
|
+
|
|
20
|
+
Modes:
|
|
21
|
+
- explore: Read-only investigation. Use for questions about endpoints, schemas, architecture, conventions, or "how does X work" queries.
|
|
22
|
+
- plan: Generate an implementation plan without writing code. Use when you need a step-by-step plan for changes in the sibling repo.
|
|
23
|
+
- execute: Read-write. Actually make changes in the sibling repo. Use when you need the sibling repo to implement something.`, {
|
|
24
|
+
repo: z.string().describe("Repository short name from SIBLING_REPOS"),
|
|
25
|
+
prompt: z.string().describe("The task or question for the sibling agent"),
|
|
26
|
+
mode: z
|
|
27
|
+
.enum(["explore", "plan", "execute"])
|
|
28
|
+
.default("explore")
|
|
29
|
+
.describe("Agent mode: explore (read-only), plan (design), execute (read-write)"),
|
|
30
|
+
model: z
|
|
31
|
+
.string()
|
|
32
|
+
.optional()
|
|
33
|
+
.describe('Model override: "haiku", "sonnet", "opus"'),
|
|
34
|
+
}, async ({ repo, prompt, mode, model }) => {
|
|
35
|
+
const entry = config.repos.get(repo);
|
|
36
|
+
if (!entry) {
|
|
37
|
+
return {
|
|
38
|
+
content: [
|
|
39
|
+
{
|
|
40
|
+
type: "text",
|
|
41
|
+
text: `Unknown repo "${repo}". Available repos: ${repoListStr}`,
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
isError: true,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
if (!existsSync(entry.path)) {
|
|
48
|
+
return {
|
|
49
|
+
content: [
|
|
50
|
+
{
|
|
51
|
+
type: "text",
|
|
52
|
+
text: `Repo path does not exist: ${entry.path}`,
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
isError: true,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
const resolvedModel = model ?? config.models[mode];
|
|
59
|
+
if (mode === "execute") {
|
|
60
|
+
console.error(`[sibling-repo] EXECUTE mode invoked on "${repo}" at ${entry.path}`);
|
|
61
|
+
}
|
|
62
|
+
try {
|
|
63
|
+
const result = await runAgent(entry.path, prompt, mode, resolvedModel, config.maxTurns);
|
|
64
|
+
return {
|
|
65
|
+
content: [{ type: "text", text: result }],
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
70
|
+
return {
|
|
71
|
+
content: [{ type: "text", text: `Agent error: ${errorMessage}` }],
|
|
72
|
+
isError: true,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
server.tool("list_repos", "List all configured sibling repositories and their paths.", {}, async () => {
|
|
77
|
+
const repos = Array.from(config.repos.values()).map((r) => ({
|
|
78
|
+
name: r.name,
|
|
79
|
+
path: r.path,
|
|
80
|
+
has_claude_md: r.hasCLAUDEmd,
|
|
81
|
+
}));
|
|
82
|
+
return {
|
|
83
|
+
content: [
|
|
84
|
+
{ type: "text", text: JSON.stringify(repos, null, 2) },
|
|
85
|
+
],
|
|
86
|
+
};
|
|
87
|
+
});
|
|
88
|
+
const transport = new StdioServerTransport();
|
|
89
|
+
await server.connect(transport);
|
|
90
|
+
console.error("[sibling-repo] MCP server running on stdio");
|
|
91
|
+
}
|
|
92
|
+
main().catch((err) => {
|
|
93
|
+
console.error("[sibling-repo] Fatal:", err);
|
|
94
|
+
process.exit(1);
|
|
95
|
+
});
|
|
96
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type AgentMode = "explore" | "plan" | "execute";
|
|
2
|
+
export interface RepoEntry {
|
|
3
|
+
name: string;
|
|
4
|
+
path: string;
|
|
5
|
+
hasCLAUDEmd: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface ModeConfig {
|
|
8
|
+
allowedTools: string[];
|
|
9
|
+
disallowedTools: string[];
|
|
10
|
+
permissionMode: string;
|
|
11
|
+
allowDangerouslySkipPermissions: boolean;
|
|
12
|
+
defaultModel: string;
|
|
13
|
+
systemPromptAppend: string;
|
|
14
|
+
}
|
|
15
|
+
export interface SiblingConfig {
|
|
16
|
+
repos: Map<string, RepoEntry>;
|
|
17
|
+
models: {
|
|
18
|
+
explore: string;
|
|
19
|
+
plan: string;
|
|
20
|
+
execute: string;
|
|
21
|
+
};
|
|
22
|
+
maxTurns: number;
|
|
23
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "sibling-repo",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "MCP server that spawns Claude Code agents in sibling repositories",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "dist/server.js",
|
|
8
|
+
"bin": {
|
|
9
|
+
"sibling-repo": "./dist/server.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist/",
|
|
13
|
+
"README.md",
|
|
14
|
+
"LICENSE",
|
|
15
|
+
".env.example"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc && chmod +x dist/server.js",
|
|
19
|
+
"dev": "tsx --watch src/server.ts",
|
|
20
|
+
"start": "node dist/server.js",
|
|
21
|
+
"typecheck": "tsc --noEmit",
|
|
22
|
+
"test": "vitest run",
|
|
23
|
+
"test:watch": "vitest"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"mcp",
|
|
27
|
+
"claude-code",
|
|
28
|
+
"multi-repo",
|
|
29
|
+
"agent-sdk",
|
|
30
|
+
"cross-repository"
|
|
31
|
+
],
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "https://github.com/AmirAlsad/sibling-repo"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@anthropic-ai/claude-agent-sdk": "^0.2.0",
|
|
38
|
+
"@modelcontextprotocol/sdk": "^1.27.0",
|
|
39
|
+
"dotenv": "^16.4.0",
|
|
40
|
+
"zod": "^4.0.0"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@types/node": "^22.0.0",
|
|
44
|
+
"tsx": "^4.0.0",
|
|
45
|
+
"typescript": "^5.7.0",
|
|
46
|
+
"vitest": "^4.1.2"
|
|
47
|
+
}
|
|
48
|
+
}
|