bridgellm 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/README.md +67 -0
- package/dist/commands/connect.d.ts +1 -0
- package/dist/commands/connect.js +120 -0
- package/dist/commands/connect.js.map +1 -0
- package/dist/commands/login.d.ts +1 -0
- package/dist/commands/login.js +129 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/team.d.ts +2 -0
- package/dist/commands/team.js +48 -0
- package/dist/commands/team.js.map +1 -0
- package/dist/config.d.ts +25 -0
- package/dist/config.js +99 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +113 -0
- package/dist/index.js.map +1 -0
- package/package.json +43 -0
package/README.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# BridgeLLM
|
|
2
|
+
|
|
3
|
+
Let AI coding agents talk to each other across teams.
|
|
4
|
+
|
|
5
|
+
When two engineers work on different services, their AI agents (Claude Code, Cursor, etc.) can share API contracts, ask questions, and get answers — without Slack.
|
|
6
|
+
|
|
7
|
+
## Quick Start
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# Login with GitHub
|
|
11
|
+
npx bridgellm login
|
|
12
|
+
|
|
13
|
+
# In your project directory
|
|
14
|
+
npx bridgellm connect
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
That's it. Restart Claude Code and your agent can now share context with other agents on your team.
|
|
18
|
+
|
|
19
|
+
## What Happens
|
|
20
|
+
|
|
21
|
+
1. **Login** — authenticates via GitHub, sets up your team and role
|
|
22
|
+
2. **Connect** — picks a feature, writes `.mcp.json` so Claude Code connects to BridgeLLM
|
|
23
|
+
|
|
24
|
+
Your agent gets 6 tools:
|
|
25
|
+
|
|
26
|
+
| Tool | What it does |
|
|
27
|
+
|------|-------------|
|
|
28
|
+
| `bridge_read` | Search for contracts, decisions, notes |
|
|
29
|
+
| `bridge_write` | Publish a contract or decision |
|
|
30
|
+
| `bridge_ask` | Post an async question |
|
|
31
|
+
| `bridge_query_agent` | Ask a live agent in real-time |
|
|
32
|
+
| `bridge_respond` | Answer a pending query |
|
|
33
|
+
| `bridge_features` | List available features |
|
|
34
|
+
|
|
35
|
+
## Commands
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
bridgellm login # Authenticate with GitHub
|
|
39
|
+
bridgellm connect # Connect this project
|
|
40
|
+
bridgellm team create <name> # Create a team
|
|
41
|
+
bridgellm team join <code> # Join with invite code
|
|
42
|
+
bridgellm config show # View settings
|
|
43
|
+
bridgellm config set role frontend # Change role
|
|
44
|
+
bridgellm config set team other # Change team
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## How It Works
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
Your Claude ──── bridge_write ────▶ BridgeLLM Server ◀──── bridge_read ──── Their Claude
|
|
51
|
+
│
|
|
52
|
+
PostgreSQL
|
|
53
|
+
(shared context)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
No LLM calls on the server. Zero AI costs. Just a database that your agents read and write to.
|
|
57
|
+
|
|
58
|
+
## Config
|
|
59
|
+
|
|
60
|
+
Global config lives in `~/.bridgellm/`. Per-project config in `.bridgellm.yml`.
|
|
61
|
+
|
|
62
|
+
| Setting | Where | Notes |
|
|
63
|
+
|---------|-------|-------|
|
|
64
|
+
| Token | Global | From login |
|
|
65
|
+
| Role | Global | Your role (backend, frontend, etc.) |
|
|
66
|
+
| Team | Global | Your team |
|
|
67
|
+
| Feature | Local | What you're working on |
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function connect(cwd: string): Promise<void>;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { createInterface } from 'node:readline';
|
|
4
|
+
import { getMergedConfig, getLocalConfig, saveLocalConfig, } from '../config.js';
|
|
5
|
+
const CLAUDE_MD_START = '<!-- bridgellm:start -->';
|
|
6
|
+
const CLAUDE_MD_END = '<!-- bridgellm:end -->';
|
|
7
|
+
async function ask(question) {
|
|
8
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
9
|
+
return new Promise((resolve) => {
|
|
10
|
+
rl.question(question, (answer) => {
|
|
11
|
+
rl.close();
|
|
12
|
+
resolve(answer.trim());
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
async function apiFetch(serverUrl, token, path) {
|
|
17
|
+
const res = await fetch(`${serverUrl}${path}`, {
|
|
18
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
19
|
+
});
|
|
20
|
+
if (!res.ok) {
|
|
21
|
+
const data = await res.json();
|
|
22
|
+
throw new Error(data.error);
|
|
23
|
+
}
|
|
24
|
+
return res.json();
|
|
25
|
+
}
|
|
26
|
+
export async function connect(cwd) {
|
|
27
|
+
const config = await getMergedConfig(cwd);
|
|
28
|
+
if (!config.team) {
|
|
29
|
+
throw new Error('No team configured. Run `bridgellm login` first.');
|
|
30
|
+
}
|
|
31
|
+
if (!config.role) {
|
|
32
|
+
throw new Error('No role configured. Run `bridgellm login` first.');
|
|
33
|
+
}
|
|
34
|
+
console.log(`\n Team: ${config.team} | Role: ${config.role}`);
|
|
35
|
+
// Determine feature
|
|
36
|
+
let feature = config.feature;
|
|
37
|
+
if (!feature) {
|
|
38
|
+
// Fetch available features
|
|
39
|
+
try {
|
|
40
|
+
const { features } = await apiFetch(config.server, config.token, '/api/features');
|
|
41
|
+
if (features.length > 0) {
|
|
42
|
+
console.log('\n Features:');
|
|
43
|
+
features.forEach((f, i) => {
|
|
44
|
+
console.log(` ${i + 1}. ${f.name} (${f.context_count} ctx, ${f.active_sessions} online)`);
|
|
45
|
+
});
|
|
46
|
+
console.log(` ${features.length + 1}. New feature`);
|
|
47
|
+
const choice = await ask('\n Select feature: ');
|
|
48
|
+
const idx = parseInt(choice, 10) - 1;
|
|
49
|
+
if (idx >= 0 && idx < features.length) {
|
|
50
|
+
feature = features[idx].name;
|
|
51
|
+
}
|
|
52
|
+
else if (idx === features.length || isNaN(idx)) {
|
|
53
|
+
feature = isNaN(idx) ? choice : await ask(' Feature name: ');
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
feature = await ask('\n No features yet. Feature name: ');
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
feature = await ask('\n Feature name: ');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (!feature)
|
|
65
|
+
throw new Error('Feature name is required.');
|
|
66
|
+
console.log(` Feature: ${feature}`);
|
|
67
|
+
// Save local config
|
|
68
|
+
const local = await getLocalConfig(cwd);
|
|
69
|
+
await saveLocalConfig(cwd, { ...local, feature });
|
|
70
|
+
// Write .mcp.json
|
|
71
|
+
const mcpConfig = {
|
|
72
|
+
mcpServers: {
|
|
73
|
+
bridgellm: {
|
|
74
|
+
type: 'http',
|
|
75
|
+
url: `${config.server}/mcp`,
|
|
76
|
+
headers: {
|
|
77
|
+
Authorization: `Bearer ${config.token}`,
|
|
78
|
+
'X-BridgeLLM-Feature': feature,
|
|
79
|
+
'X-BridgeLLM-Role': config.role,
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
const mcpPath = join(cwd, '.mcp.json');
|
|
85
|
+
await writeFile(mcpPath, JSON.stringify(mcpConfig, null, 2) + '\n');
|
|
86
|
+
// Write CLAUDE.md
|
|
87
|
+
const claudeBlock = `${CLAUDE_MD_START}
|
|
88
|
+
## BridgeLLM
|
|
89
|
+
|
|
90
|
+
Connected to **${config.team}** | Feature: **${feature}** | Role: **${config.role}**
|
|
91
|
+
|
|
92
|
+
- BEFORE writing cross-service code, call \`bridge_read\` first
|
|
93
|
+
- After creating/modifying interfaces, use \`bridge_write\` to publish
|
|
94
|
+
- Use \`bridge_query_agent\` for live queries, \`bridge_ask\` for async
|
|
95
|
+
- Your feature is "${feature}" and role is "${config.role}"
|
|
96
|
+
${CLAUDE_MD_END}`;
|
|
97
|
+
const claudePath = join(cwd, 'CLAUDE.md');
|
|
98
|
+
let claudeContent = '';
|
|
99
|
+
try {
|
|
100
|
+
claudeContent = await readFile(claudePath, 'utf-8');
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
// doesn't exist
|
|
104
|
+
}
|
|
105
|
+
if (claudeContent.includes(CLAUDE_MD_START)) {
|
|
106
|
+
const regex = new RegExp(`${escapeRegex(CLAUDE_MD_START)}[\\s\\S]*?${escapeRegex(CLAUDE_MD_END)}`);
|
|
107
|
+
claudeContent = claudeContent.replace(regex, claudeBlock);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
claudeContent =
|
|
111
|
+
claudeContent + (claudeContent.endsWith('\n') ? '\n' : '\n\n') + claudeBlock + '\n';
|
|
112
|
+
}
|
|
113
|
+
await writeFile(claudePath, claudeContent);
|
|
114
|
+
console.log(`\n ✓ Wrote .bridgellm.yml, .mcp.json, CLAUDE.md`);
|
|
115
|
+
console.log(` Restart Claude Code to connect.\n`);
|
|
116
|
+
}
|
|
117
|
+
function escapeRegex(s) {
|
|
118
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=connect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connect.js","sourceRoot":"","sources":["../../src/commands/connect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function login(serverUrl: string): Promise<void>;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import http from 'node:http';
|
|
2
|
+
import { saveToken, saveServerUrl, saveGlobalConfig, getGlobalConfig } from '../config.js';
|
|
3
|
+
export async function login(serverUrl) {
|
|
4
|
+
const server = http.createServer();
|
|
5
|
+
const port = await new Promise((resolve, reject) => {
|
|
6
|
+
server.once('error', (err) => {
|
|
7
|
+
if (err.code === 'EADDRINUSE') {
|
|
8
|
+
server.listen(0, '127.0.0.1', () => {
|
|
9
|
+
const addr = server.address();
|
|
10
|
+
resolve(typeof addr === 'object' && addr ? addr.port : 0);
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
reject(err);
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
server.listen(9876, '127.0.0.1', () => {
|
|
18
|
+
resolve(9876);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
const authUrl = `${serverUrl}/auth/github?cli_port=${port}`;
|
|
22
|
+
console.log(`\n Opening browser for GitHub authentication...`);
|
|
23
|
+
console.log(` If it doesn't open, visit:\n ${authUrl}\n`);
|
|
24
|
+
const open = (await import('open')).default;
|
|
25
|
+
await open(authUrl);
|
|
26
|
+
const result = await new Promise((resolve, reject) => {
|
|
27
|
+
const timeout = setTimeout(() => {
|
|
28
|
+
server.close();
|
|
29
|
+
reject(new Error('Login timed out after 5 minutes'));
|
|
30
|
+
}, 5 * 60 * 1000);
|
|
31
|
+
server.on('request', (req, res) => {
|
|
32
|
+
const url = new URL(req.url ?? '/', `http://localhost:${port}`);
|
|
33
|
+
if (url.pathname === '/callback') {
|
|
34
|
+
const token = url.searchParams.get('token');
|
|
35
|
+
const name = url.searchParams.get('name');
|
|
36
|
+
if (token) {
|
|
37
|
+
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
38
|
+
res.end(`
|
|
39
|
+
<html><body style="font-family: system-ui; padding: 2em; text-align: center;">
|
|
40
|
+
<h2>Logged in as ${name ?? 'unknown'}</h2>
|
|
41
|
+
<p>You can close this tab and return to the terminal.</p>
|
|
42
|
+
</body></html>
|
|
43
|
+
`);
|
|
44
|
+
clearTimeout(timeout);
|
|
45
|
+
resolve({ token, name: name ?? 'unknown' });
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
res.writeHead(400, { 'Content-Type': 'text/html' });
|
|
49
|
+
res.end('<html><body><h2>Login failed</h2></body></html>');
|
|
50
|
+
clearTimeout(timeout);
|
|
51
|
+
reject(new Error('No token in callback'));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
res.writeHead(404);
|
|
56
|
+
res.end();
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
server.close();
|
|
61
|
+
await saveToken(result.token);
|
|
62
|
+
await saveServerUrl(serverUrl);
|
|
63
|
+
console.log(` Logged in as ${result.name}`);
|
|
64
|
+
// Check if global config already has team + role
|
|
65
|
+
const existing = await getGlobalConfig();
|
|
66
|
+
if (existing.team && existing.role) {
|
|
67
|
+
console.log(` Team: ${existing.team}, Role: ${existing.role}`);
|
|
68
|
+
console.log(`\n Run \`bridgellm connect\` in your project directory.`);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
// First-time setup: ask for team + role
|
|
72
|
+
console.log(`\n First-time setup — let's configure your defaults.\n`);
|
|
73
|
+
const { createInterface } = await import('node:readline');
|
|
74
|
+
const ask = (q) => {
|
|
75
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
76
|
+
return new Promise((resolve) => {
|
|
77
|
+
rl.question(q, (a) => { rl.close(); resolve(a.trim()); });
|
|
78
|
+
});
|
|
79
|
+
};
|
|
80
|
+
// Team
|
|
81
|
+
let teamName;
|
|
82
|
+
const meRes = await fetch(`${serverUrl}/api/me`, {
|
|
83
|
+
headers: { Authorization: `Bearer ${result.token}` },
|
|
84
|
+
});
|
|
85
|
+
const me = await meRes.json();
|
|
86
|
+
if (me.team) {
|
|
87
|
+
teamName = me.team.name;
|
|
88
|
+
console.log(` Team: ${teamName}`);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
console.log(' No team yet.');
|
|
92
|
+
console.log(' 1. Create a new team');
|
|
93
|
+
console.log(' 2. Join with invite code');
|
|
94
|
+
const choice = await ask(' → ');
|
|
95
|
+
if (choice === '1') {
|
|
96
|
+
const name = await ask(' Team name: ');
|
|
97
|
+
const res = await fetch(`${serverUrl}/api/teams`, {
|
|
98
|
+
method: 'POST',
|
|
99
|
+
headers: { Authorization: `Bearer ${result.token}`, 'Content-Type': 'application/json' },
|
|
100
|
+
body: JSON.stringify({ name }),
|
|
101
|
+
});
|
|
102
|
+
const data = await res.json();
|
|
103
|
+
teamName = data.team.name;
|
|
104
|
+
console.log(` Created "${teamName}" — share invite code: ${data.invite_code}`);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
const code = await ask(' Invite code: ');
|
|
108
|
+
const res = await fetch(`${serverUrl}/api/teams/join`, {
|
|
109
|
+
method: 'POST',
|
|
110
|
+
headers: { Authorization: `Bearer ${result.token}`, 'Content-Type': 'application/json' },
|
|
111
|
+
body: JSON.stringify({ invite_code: code }),
|
|
112
|
+
});
|
|
113
|
+
const data = await res.json();
|
|
114
|
+
teamName = data.team.name;
|
|
115
|
+
console.log(` Joined "${teamName}"`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// Role
|
|
119
|
+
const ROLES = ['backend', 'frontend', 'web', 'mobile', 'ios', 'android', 'infra', 'data', 'qa', 'design'];
|
|
120
|
+
console.log(`\n Your role: ${ROLES.join(', ')}`);
|
|
121
|
+
const role = await ask(' → ');
|
|
122
|
+
if (!ROLES.includes(role)) {
|
|
123
|
+
throw new Error(`Invalid role. Must be one of: ${ROLES.join(', ')}`);
|
|
124
|
+
}
|
|
125
|
+
await saveGlobalConfig({ team: teamName, role });
|
|
126
|
+
console.log(`\n Saved: team=${teamName}, role=${role}`);
|
|
127
|
+
console.log(` Run \`bridgellm connect\` in your project directory.\n`);
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { getToken, getServerUrl, getGlobalConfig, saveGlobalConfig } from '../config.js';
|
|
2
|
+
export async function createTeam(name) {
|
|
3
|
+
const token = await getToken();
|
|
4
|
+
const serverUrl = await getServerUrl();
|
|
5
|
+
const res = await fetch(`${serverUrl}/api/teams`, {
|
|
6
|
+
method: 'POST',
|
|
7
|
+
headers: {
|
|
8
|
+
'Content-Type': 'application/json',
|
|
9
|
+
Authorization: `Bearer ${token}`,
|
|
10
|
+
},
|
|
11
|
+
body: JSON.stringify({ name }),
|
|
12
|
+
});
|
|
13
|
+
const data = await res.json();
|
|
14
|
+
if (!res.ok) {
|
|
15
|
+
console.error(`Error: ${data.error}`);
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
const result = data;
|
|
19
|
+
// Update global config
|
|
20
|
+
const global = await getGlobalConfig();
|
|
21
|
+
await saveGlobalConfig({ ...global, team: result.team.name });
|
|
22
|
+
console.log(`Team "${result.team.name}" created!`);
|
|
23
|
+
console.log(`Invite code: ${result.invite_code}`);
|
|
24
|
+
console.log(`Share this code so others can join: bridgellm team join ${result.invite_code}`);
|
|
25
|
+
}
|
|
26
|
+
export async function joinTeam(inviteCode) {
|
|
27
|
+
const token = await getToken();
|
|
28
|
+
const serverUrl = await getServerUrl();
|
|
29
|
+
const res = await fetch(`${serverUrl}/api/teams/join`, {
|
|
30
|
+
method: 'POST',
|
|
31
|
+
headers: {
|
|
32
|
+
'Content-Type': 'application/json',
|
|
33
|
+
Authorization: `Bearer ${token}`,
|
|
34
|
+
},
|
|
35
|
+
body: JSON.stringify({ invite_code: inviteCode }),
|
|
36
|
+
});
|
|
37
|
+
const data = await res.json();
|
|
38
|
+
if (!res.ok) {
|
|
39
|
+
console.error(`Error: ${data.error}`);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
const result = data;
|
|
43
|
+
// Update global config
|
|
44
|
+
const global = await getGlobalConfig();
|
|
45
|
+
await saveGlobalConfig({ ...global, team: result.team.name });
|
|
46
|
+
console.log(result.message);
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=team.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team.js","sourceRoot":"","sources":["../../src/commands/team.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEzF,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAY;IAC3C,MAAM,KAAK,GAAG,MAAM,QAAQ,EAAE,CAAC;IAC/B,MAAM,SAAS,GAAG,MAAM,YAAY,EAAE,CAAC;IAEvC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,SAAS,YAAY,EAAE;QAChD,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,aAAa,EAAE,UAAU,KAAK,EAAE;SACjC;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,CAAC;KAC/B,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;IAE9B,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CAAC,UAAW,IAA0B,CAAC,KAAK,EAAE,CAAC,CAAC;QAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,IAAuD,CAAC;IAEvE,uBAAuB;IACvB,MAAM,MAAM,GAAG,MAAM,eAAe,EAAE,CAAC;IACvC,MAAM,gBAAgB,CAAC,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IAE9D,OAAO,CAAC,GAAG,CAAC,SAAS,MAAM,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,CAAC;IACnD,OAAO,CAAC,GAAG,CAAC,gBAAgB,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;IAClD,OAAO,CAAC,GAAG,CAAC,2DAA2D,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;AAC/F,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,UAAkB;IAC/C,MAAM,KAAK,GAAG,MAAM,QAAQ,EAAE,CAAC;IAC/B,MAAM,SAAS,GAAG,MAAM,YAAY,EAAE,CAAC;IAEvC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,SAAS,iBAAiB,EAAE;QACrD,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,aAAa,EAAE,UAAU,KAAK,EAAE;SACjC;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;KAClD,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;IAE9B,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CAAC,UAAW,IAA0B,CAAC,KAAK,EAAE,CAAC,CAAC;QAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,IAAmD,CAAC;IAEnE,uBAAuB;IACvB,MAAM,MAAM,GAAG,MAAM,eAAe,EAAE,CAAC;IACvC,MAAM,gBAAgB,CAAC,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IAE9D,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAC9B,CAAC"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export declare const DEFAULT_SERVER = "https://bridgellm-bridge-411567362585.asia-south1.run.app";
|
|
2
|
+
export interface GlobalConfig {
|
|
3
|
+
team?: string;
|
|
4
|
+
role?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface LocalConfig {
|
|
7
|
+
feature?: string;
|
|
8
|
+
team?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface MergedConfig {
|
|
11
|
+
token: string;
|
|
12
|
+
server: string;
|
|
13
|
+
team?: string;
|
|
14
|
+
role?: string;
|
|
15
|
+
feature?: string;
|
|
16
|
+
}
|
|
17
|
+
export declare function saveToken(token: string): Promise<void>;
|
|
18
|
+
export declare function getToken(): Promise<string>;
|
|
19
|
+
export declare function saveServerUrl(url: string): Promise<void>;
|
|
20
|
+
export declare function getServerUrl(): Promise<string>;
|
|
21
|
+
export declare function getGlobalConfig(): Promise<GlobalConfig>;
|
|
22
|
+
export declare function saveGlobalConfig(config: GlobalConfig): Promise<void>;
|
|
23
|
+
export declare function getLocalConfig(cwd: string): Promise<LocalConfig>;
|
|
24
|
+
export declare function saveLocalConfig(cwd: string, config: LocalConfig): Promise<void>;
|
|
25
|
+
export declare function getMergedConfig(cwd: string): Promise<MergedConfig>;
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { readFile, writeFile, mkdir } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
export const DEFAULT_SERVER = 'https://bridgellm-bridge-411567362585.asia-south1.run.app';
|
|
5
|
+
const BRIDGELLM_DIR = join(homedir(), '.bridgellm');
|
|
6
|
+
async function ensureDir() {
|
|
7
|
+
await mkdir(BRIDGELLM_DIR, { recursive: true });
|
|
8
|
+
}
|
|
9
|
+
// ── Token ──
|
|
10
|
+
export async function saveToken(token) {
|
|
11
|
+
await ensureDir();
|
|
12
|
+
await writeFile(join(BRIDGELLM_DIR, 'token'), token, { mode: 0o600 });
|
|
13
|
+
}
|
|
14
|
+
export async function getToken() {
|
|
15
|
+
try {
|
|
16
|
+
return (await readFile(join(BRIDGELLM_DIR, 'token'), 'utf-8')).trim();
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
throw new Error('Not logged in. Run `bridgellm login` first.');
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
// ── Server ──
|
|
23
|
+
export async function saveServerUrl(url) {
|
|
24
|
+
await ensureDir();
|
|
25
|
+
await writeFile(join(BRIDGELLM_DIR, 'server'), url, { mode: 0o600 });
|
|
26
|
+
}
|
|
27
|
+
export async function getServerUrl() {
|
|
28
|
+
try {
|
|
29
|
+
return (await readFile(join(BRIDGELLM_DIR, 'server'), 'utf-8')).trim();
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return DEFAULT_SERVER;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
// ── Global config ──
|
|
36
|
+
export async function getGlobalConfig() {
|
|
37
|
+
try {
|
|
38
|
+
const raw = await readFile(join(BRIDGELLM_DIR, 'config.yml'), 'utf-8');
|
|
39
|
+
return parseSimpleYaml(raw);
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return {};
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export async function saveGlobalConfig(config) {
|
|
46
|
+
await ensureDir();
|
|
47
|
+
const lines = [];
|
|
48
|
+
if (config.team)
|
|
49
|
+
lines.push(`team: ${config.team}`);
|
|
50
|
+
if (config.role)
|
|
51
|
+
lines.push(`role: ${config.role}`);
|
|
52
|
+
await writeFile(join(BRIDGELLM_DIR, 'config.yml'), lines.join('\n') + '\n');
|
|
53
|
+
}
|
|
54
|
+
// ── Local config ──
|
|
55
|
+
export async function getLocalConfig(cwd) {
|
|
56
|
+
try {
|
|
57
|
+
const raw = await readFile(join(cwd, '.bridgellm.yml'), 'utf-8');
|
|
58
|
+
return parseSimpleYaml(raw);
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return {};
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
export async function saveLocalConfig(cwd, config) {
|
|
65
|
+
const lines = [];
|
|
66
|
+
if (config.feature)
|
|
67
|
+
lines.push(`feature: ${config.feature}`);
|
|
68
|
+
if (config.team)
|
|
69
|
+
lines.push(`team: ${config.team}`);
|
|
70
|
+
await writeFile(join(cwd, '.bridgellm.yml'), lines.join('\n') + '\n');
|
|
71
|
+
}
|
|
72
|
+
// ── Merged config ──
|
|
73
|
+
export async function getMergedConfig(cwd) {
|
|
74
|
+
const token = await getToken();
|
|
75
|
+
const server = await getServerUrl();
|
|
76
|
+
const global = await getGlobalConfig();
|
|
77
|
+
const local = await getLocalConfig(cwd);
|
|
78
|
+
return {
|
|
79
|
+
token,
|
|
80
|
+
server,
|
|
81
|
+
team: local.team ?? global.team,
|
|
82
|
+
role: global.role,
|
|
83
|
+
feature: local.feature,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function parseSimpleYaml(raw) {
|
|
87
|
+
const result = {};
|
|
88
|
+
for (const line of raw.split('\n')) {
|
|
89
|
+
const trimmed = line.trim();
|
|
90
|
+
if (!trimmed || trimmed.startsWith('#'))
|
|
91
|
+
continue;
|
|
92
|
+
const match = trimmed.match(/^(\w+):\s*(.+)$/);
|
|
93
|
+
if (match) {
|
|
94
|
+
result[match[1]] = match[2].trim();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return result;
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { login } from './commands/login.js';
|
|
4
|
+
import { connect } from './commands/connect.js';
|
|
5
|
+
import { createTeam, joinTeam } from './commands/team.js';
|
|
6
|
+
import { getGlobalConfig, saveGlobalConfig, getServerUrl, DEFAULT_SERVER } from './config.js';
|
|
7
|
+
const program = new Command();
|
|
8
|
+
program
|
|
9
|
+
.name('bridgellm')
|
|
10
|
+
.description('BridgeLLM — let AI coding agents talk to each other')
|
|
11
|
+
.version('0.1.0');
|
|
12
|
+
program
|
|
13
|
+
.command('login')
|
|
14
|
+
.description('Authenticate with GitHub OAuth')
|
|
15
|
+
.option('-s, --server <url>', 'Server URL', DEFAULT_SERVER)
|
|
16
|
+
.action(async (opts) => {
|
|
17
|
+
try {
|
|
18
|
+
await login(opts.server);
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
console.error(err.message);
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
program
|
|
26
|
+
.command('connect')
|
|
27
|
+
.description('Connect this project to BridgeLLM')
|
|
28
|
+
.action(async () => {
|
|
29
|
+
try {
|
|
30
|
+
await connect(process.cwd());
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
console.error(err.message);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
const team = program
|
|
38
|
+
.command('team')
|
|
39
|
+
.description('Team management');
|
|
40
|
+
team
|
|
41
|
+
.command('create <name>')
|
|
42
|
+
.description('Create a new team')
|
|
43
|
+
.action(async (name) => {
|
|
44
|
+
try {
|
|
45
|
+
await createTeam(name);
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
console.error(err.message);
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
team
|
|
53
|
+
.command('join <invite-code>')
|
|
54
|
+
.description('Join a team via invite code')
|
|
55
|
+
.action(async (inviteCode) => {
|
|
56
|
+
try {
|
|
57
|
+
await joinTeam(inviteCode);
|
|
58
|
+
}
|
|
59
|
+
catch (err) {
|
|
60
|
+
console.error(err.message);
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
const config = program
|
|
65
|
+
.command('config')
|
|
66
|
+
.description('View or update settings');
|
|
67
|
+
config
|
|
68
|
+
.command('show')
|
|
69
|
+
.description('Show current config')
|
|
70
|
+
.action(async () => {
|
|
71
|
+
try {
|
|
72
|
+
const global = await getGlobalConfig();
|
|
73
|
+
const server = await getServerUrl();
|
|
74
|
+
console.log(` Server: ${server}`);
|
|
75
|
+
console.log(` Team: ${global.team ?? '(not set)'}`);
|
|
76
|
+
console.log(` Role: ${global.role ?? '(not set)'}`);
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
console.error(err.message);
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
config
|
|
84
|
+
.command('set <key> <value>')
|
|
85
|
+
.description('Set a config value (team, role)')
|
|
86
|
+
.action(async (key, value) => {
|
|
87
|
+
try {
|
|
88
|
+
const global = await getGlobalConfig();
|
|
89
|
+
if (key === 'team') {
|
|
90
|
+
await saveGlobalConfig({ ...global, team: value });
|
|
91
|
+
console.log(` Team set to: ${value}`);
|
|
92
|
+
}
|
|
93
|
+
else if (key === 'role') {
|
|
94
|
+
const ROLES = ['backend', 'frontend', 'web', 'mobile', 'ios', 'android', 'infra', 'data', 'qa', 'design'];
|
|
95
|
+
if (!ROLES.includes(value)) {
|
|
96
|
+
console.error(` Invalid role. Must be one of: ${ROLES.join(', ')}`);
|
|
97
|
+
process.exit(1);
|
|
98
|
+
}
|
|
99
|
+
await saveGlobalConfig({ ...global, role: value });
|
|
100
|
+
console.log(` Role set to: ${value}`);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
console.error(` Unknown key: ${key}. Use "team" or "role".`);
|
|
104
|
+
process.exit(1);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
console.error(err.message);
|
|
109
|
+
process.exit(1);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
program.parse();
|
|
113
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "bridgellm",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "BridgeLLM CLI — let AI coding agents talk to each other across teams",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"bridgellm": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsc",
|
|
11
|
+
"dev": "tsx src/index.ts",
|
|
12
|
+
"typecheck": "tsc --noEmit",
|
|
13
|
+
"prepublishOnly": "npm run build"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"mcp",
|
|
17
|
+
"claude",
|
|
18
|
+
"ai",
|
|
19
|
+
"bridge",
|
|
20
|
+
"llm",
|
|
21
|
+
"cross-team",
|
|
22
|
+
"context-sharing",
|
|
23
|
+
"claude-code"
|
|
24
|
+
],
|
|
25
|
+
"author": "starvader",
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "https://github.com/starvader13/bridgellm"
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"dist"
|
|
33
|
+
],
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"commander": "^13.0.0",
|
|
36
|
+
"open": "^10.0.0"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@types/node": "^22.0.0",
|
|
40
|
+
"tsx": "^4.19.0",
|
|
41
|
+
"typescript": "^5.7.0"
|
|
42
|
+
}
|
|
43
|
+
}
|