bridgellm 0.1.8 → 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 +116 -64
- package/dist/commands/connect.d.ts +1 -1
- package/dist/commands/connect.js +28 -96
- package/dist/commands/connect.js.map +1 -1
- package/dist/commands/login.js +4 -57
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/team.js +7 -10
- package/dist/commands/team.js.map +1 -1
- package/dist/config.d.ts +1 -0
- package/dist/config.js +25 -46
- package/dist/config.js.map +1 -1
- package/dist/index.js +169 -116
- package/dist/index.js.map +1 -1
- package/dist/ui.d.ts +5 -4
- package/dist/ui.js +88 -44
- package/dist/ui.js.map +1 -1
- package/package.json +1 -2
package/README.md
CHANGED
|
@@ -1,115 +1,167 @@
|
|
|
1
1
|
# BridgeLLM
|
|
2
2
|
|
|
3
|
-
**Let your coding agents talk to each other across services.**
|
|
4
|
-
|
|
5
3
|
[](https://www.npmjs.com/package/bridgellm)
|
|
6
4
|
|
|
7
|
-
|
|
5
|
+
Your AI coding agents can't talk to each other. Backend Claude doesn't know what Frontend Claude is building. Someone ends up on Slack copy-pasting API contracts.
|
|
6
|
+
|
|
7
|
+
BridgeLLM is an MCP server that lets agents share context, query each other, and stay in sync — without you being the middleman.
|
|
8
8
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
12
|
npm install -g bridgellm
|
|
13
13
|
|
|
14
|
-
# or run without installing
|
|
15
|
-
npx bridgellm <command>
|
|
16
|
-
|
|
17
14
|
# or via Homebrew
|
|
18
15
|
brew install starvader13/bridgellm/bridgellm
|
|
19
16
|
```
|
|
20
17
|
|
|
21
|
-
|
|
18
|
+
Requires Node.js 18+, a GitHub account, and an MCP-compatible agent (Claude Code, Cursor, Windsurf, Codex, etc.).
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Get Started
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
bridgellm
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The CLI walks you through setup interactively:
|
|
29
|
+
|
|
30
|
+
1. **Login** — opens GitHub OAuth in your browser
|
|
31
|
+
2. **Team** — create a new team or join with an invite code
|
|
32
|
+
3. **Role** — pick yours (backend, frontend, mobile, infra, etc.)
|
|
33
|
+
4. **Feature** — select the feature you're working on
|
|
34
|
+
|
|
35
|
+
Once done, it writes a `.mcp.json` in your project. Restart your IDE and your agent is connected.
|
|
36
|
+
|
|
37
|
+
### Second project, same team
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
cd another-project/
|
|
41
|
+
bridgellm
|
|
42
|
+
# skips login/team/role — just picks feature
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Already set up?
|
|
22
46
|
|
|
23
47
|
```bash
|
|
24
|
-
|
|
25
|
-
|
|
48
|
+
bridgellm
|
|
49
|
+
# shows current config
|
|
50
|
+
```
|
|
26
51
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
bridgellm connect
|
|
30
|
-
# → picks your feature
|
|
31
|
-
# → writes .mcp.json + CLAUDE.md
|
|
52
|
+
```
|
|
53
|
+
✓ Connected
|
|
32
54
|
|
|
33
|
-
|
|
55
|
+
┌─────────────────────────────────┐
|
|
56
|
+
│ Team: payments │
|
|
57
|
+
│ Feature: gift-cards │
|
|
58
|
+
│ Role: backend │
|
|
59
|
+
└─────────────────────────────────┘
|
|
34
60
|
```
|
|
35
61
|
|
|
36
|
-
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Change Settings
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
bridgellm --set role frontend # switch role
|
|
68
|
+
bridgellm --set feature checkout # switch feature
|
|
69
|
+
bridgellm --set team platform # switch team
|
|
70
|
+
```
|
|
37
71
|
|
|
38
|
-
|
|
39
|
-
|------|-------------|
|
|
40
|
-
| `bridge_read` | Search for contracts, decisions, notes |
|
|
41
|
-
| `bridge_write` | Publish a contract, decision, or note |
|
|
42
|
-
| `bridge_ask` | Post an async question (saved for later) |
|
|
43
|
-
| `bridge_query_agent` | Ask a live agent in real-time |
|
|
44
|
-
| `bridge_respond` | Answer or decline a pending query |
|
|
45
|
-
| `bridge_features` | List features and who's online |
|
|
72
|
+
Updates config and rewrites `.mcp.json` automatically.
|
|
46
73
|
|
|
47
|
-
|
|
74
|
+
To re-pick everything interactively:
|
|
48
75
|
|
|
49
76
|
```bash
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
77
|
+
bridgellm --reconfigure
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Cleanup
|
|
53
83
|
|
|
54
|
-
|
|
55
|
-
bridgellm connect # Connect to a feature
|
|
84
|
+
Remove project config (`.mcp.json`, `.bridgellm.yml`) from the current directory:
|
|
56
85
|
|
|
57
|
-
|
|
58
|
-
bridgellm
|
|
59
|
-
|
|
86
|
+
```bash
|
|
87
|
+
bridgellm --disconnect
|
|
88
|
+
```
|
|
60
89
|
|
|
61
|
-
|
|
62
|
-
bridgellm config show # View settings
|
|
63
|
-
bridgellm config set role <role> # backend, frontend, mobile, infra, etc.
|
|
64
|
-
bridgellm config set team <team> # Switch team
|
|
90
|
+
Wipe all local config (`~/.bridgellm/` and project files):
|
|
65
91
|
|
|
66
|
-
|
|
67
|
-
bridgellm
|
|
68
|
-
bridgellm reset # Full reset (server + local)
|
|
92
|
+
```bash
|
|
93
|
+
bridgellm --reset
|
|
69
94
|
```
|
|
70
95
|
|
|
71
|
-
|
|
96
|
+
Offline-safe. Server-side tokens expire automatically (90-day TTL).
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## What Your Agent Gets
|
|
72
101
|
|
|
73
|
-
|
|
102
|
+
Once connected, your agent has 6 MCP tools:
|
|
74
103
|
|
|
75
|
-
|
|
104
|
+
| Tool | Use it to |
|
|
105
|
+
|------|-----------|
|
|
106
|
+
| `bridge_read` | Search for contracts, decisions, notes published by other agents |
|
|
107
|
+
| `bridge_write` | Publish a contract, decision, note, or assumption |
|
|
108
|
+
| `bridge_ask` | Post a question for another agent (async — they'll see it later) |
|
|
109
|
+
| `bridge_query_agent` | Ask a live agent a question in real-time |
|
|
110
|
+
| `bridge_respond` | Answer or decline a pending query from another agent |
|
|
111
|
+
| `bridge_features` | List features and see who's online |
|
|
112
|
+
|
|
113
|
+
---
|
|
76
114
|
|
|
77
115
|
## How It Works
|
|
78
116
|
|
|
79
117
|
```
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
118
|
+
Backend Agent ── bridge_write ──▶ BridgeLLM ◀── bridge_read ── Frontend Agent
|
|
119
|
+
│
|
|
120
|
+
PostgreSQL
|
|
121
|
+
(shared context)
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
No LLM inference on the server. No compute costs. BridgeLLM is a database and message router — your agents do the thinking.
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Reference
|
|
129
|
+
|
|
130
|
+
### CLI
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
bridgellm setup / status
|
|
134
|
+
bridgellm --set <key> <value> change a setting (team, role, feature)
|
|
135
|
+
bridgellm --reconfigure re-run full setup
|
|
136
|
+
bridgellm --disconnect remove project config
|
|
137
|
+
bridgellm --reset wipe all local config
|
|
84
138
|
```
|
|
85
139
|
|
|
86
|
-
|
|
140
|
+
### Files
|
|
87
141
|
|
|
88
|
-
|
|
142
|
+
| File | Scope | Purpose |
|
|
143
|
+
|------|-------|---------|
|
|
144
|
+
| `~/.bridgellm/token` | Global | Auth token |
|
|
145
|
+
| `~/.bridgellm/server` | Global | Server URL |
|
|
146
|
+
| `~/.bridgellm/config.yml` | Global | Team, role |
|
|
147
|
+
| `.bridgellm.yml` | Project | Feature name |
|
|
148
|
+
| `.mcp.json` | Project | MCP server config (contains token) |
|
|
89
149
|
|
|
90
|
-
|
|
91
|
-
|------|----------|---------------|
|
|
92
|
-
| `~/.bridgellm/config.yml` | Home dir | Team, role |
|
|
93
|
-
| `~/.bridgellm/token` | Home dir | Auth token |
|
|
94
|
-
| `~/.bridgellm/server` | Home dir | Server URL |
|
|
95
|
-
| `.bridgellm.yml` | Project root | Feature name |
|
|
96
|
-
| `.mcp.json` | Project root | MCP server config (contains your token) |
|
|
97
|
-
| `CLAUDE.md` | Project root | Agent instructions |
|
|
150
|
+
Add `.bridgellm.yml` and `.mcp.json` to your `.gitignore`.
|
|
98
151
|
|
|
99
|
-
|
|
152
|
+
### Roles
|
|
100
153
|
|
|
101
|
-
|
|
154
|
+
`backend` `frontend` `web` `mobile` `ios` `android` `infra` `data` `qa` `design`
|
|
102
155
|
|
|
103
|
-
|
|
104
|
-
- An MCP-compatible coding agent (Claude Code, Cursor, Windsurf, Codex, etc.)
|
|
105
|
-
- A GitHub account
|
|
156
|
+
---
|
|
106
157
|
|
|
107
158
|
## Links
|
|
108
159
|
|
|
109
|
-
- [
|
|
160
|
+
- [Website](https://www.bridgellm.tech/)
|
|
110
161
|
- [npm](https://www.npmjs.com/package/bridgellm)
|
|
162
|
+
- [GitHub](https://github.com/starvader13/bridgellm)
|
|
111
163
|
- [Homebrew](https://github.com/starvader13/homebrew-bridgellm)
|
|
112
|
-
- [
|
|
164
|
+
- [Issues](https://github.com/starvader13/bridgellm/issues)
|
|
113
165
|
|
|
114
166
|
## License
|
|
115
167
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function
|
|
1
|
+
export declare function selectFeature(serverUrl: string, token: string, defaultFeature?: string): Promise<string>;
|
package/dist/commands/connect.js
CHANGED
|
@@ -1,106 +1,38 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
if (!config.role) {
|
|
23
|
-
throw new Error("No role configured. Run `bridgellm login` first.");
|
|
24
|
-
}
|
|
25
|
-
heading("BridgeLLM Connect");
|
|
26
|
-
info(`Team: ${config.team} • Role: ${config.role}`);
|
|
27
|
-
// Determine feature
|
|
28
|
-
let feature = config.feature;
|
|
29
|
-
if (!feature) {
|
|
30
|
-
try {
|
|
31
|
-
const { features } = (await apiFetch(config.server, config.token, "/api/features"));
|
|
32
|
-
if (features.length > 0) {
|
|
33
|
-
const labels = features.map((f) => `${f.name} (${f.context_count} contexts, ${f.active_sessions} online)`);
|
|
34
|
-
const result = await select("Select feature", labels, {
|
|
35
|
-
newLabel: "Create new feature",
|
|
36
|
-
});
|
|
37
|
-
feature = result.value;
|
|
1
|
+
import { ask, select } from '../ui.js';
|
|
2
|
+
export async function selectFeature(serverUrl, token, defaultFeature) {
|
|
3
|
+
let feature;
|
|
4
|
+
try {
|
|
5
|
+
const res = await fetch(`${serverUrl}/api/features`, {
|
|
6
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
7
|
+
});
|
|
8
|
+
if (!res.ok)
|
|
9
|
+
throw new Error('Failed to fetch features');
|
|
10
|
+
const { features } = (await res.json());
|
|
11
|
+
if (features.length > 0) {
|
|
12
|
+
const labels = features.map((f) => `${f.name} (${f.context_count} contexts, ${f.active_sessions} online)`);
|
|
13
|
+
const defaultIdx = defaultFeature
|
|
14
|
+
? Math.max(0, features.findIndex((f) => f.name === defaultFeature))
|
|
15
|
+
: 0;
|
|
16
|
+
const result = await select('Select feature', labels, {
|
|
17
|
+
newLabel: 'Create new feature',
|
|
18
|
+
defaultIndex: defaultIdx,
|
|
19
|
+
});
|
|
20
|
+
if (result.isNew) {
|
|
21
|
+
feature = await ask('Feature name: ');
|
|
38
22
|
}
|
|
39
23
|
else {
|
|
40
|
-
feature =
|
|
24
|
+
feature = result.value;
|
|
41
25
|
}
|
|
42
26
|
}
|
|
43
|
-
|
|
44
|
-
feature = await ask(
|
|
27
|
+
else {
|
|
28
|
+
feature = await ask('No features yet. Feature name: ');
|
|
45
29
|
}
|
|
46
30
|
}
|
|
47
|
-
if (!feature)
|
|
48
|
-
throw new Error("Feature name is required.");
|
|
49
|
-
// Save local config
|
|
50
|
-
const local = await getLocalConfig(cwd);
|
|
51
|
-
await saveLocalConfig(cwd, { ...local, feature });
|
|
52
|
-
// Write .mcp.json
|
|
53
|
-
const mcpConfig = {
|
|
54
|
-
mcpServers: {
|
|
55
|
-
bridgellm: {
|
|
56
|
-
type: "http",
|
|
57
|
-
url: `${config.server}/mcp`,
|
|
58
|
-
headers: {
|
|
59
|
-
Authorization: `Bearer ${config.token}`,
|
|
60
|
-
"X-BridgeLLM-Feature": feature,
|
|
61
|
-
"X-BridgeLLM-Role": config.role,
|
|
62
|
-
},
|
|
63
|
-
},
|
|
64
|
-
},
|
|
65
|
-
};
|
|
66
|
-
const mcpPath = join(cwd, ".mcp.json");
|
|
67
|
-
await writeFile(mcpPath, JSON.stringify(mcpConfig, null, 2) + "\n");
|
|
68
|
-
// Write CLAUDE.md
|
|
69
|
-
const claudeBlock = `${CLAUDE_MD_START}
|
|
70
|
-
## BridgeLLM
|
|
71
|
-
|
|
72
|
-
Connected to **${config.team}** | Feature: **${feature}** | Role: **${config.role}**
|
|
73
|
-
|
|
74
|
-
- BEFORE writing cross-service code, call \`bridge_read\` first
|
|
75
|
-
- After creating/modifying interfaces, use \`bridge_write\` to publish
|
|
76
|
-
- Use \`bridge_query_agent\` for live queries, \`bridge_ask\` for async
|
|
77
|
-
- Your feature is "${feature}" and role is "${config.role}"
|
|
78
|
-
${CLAUDE_MD_END}`;
|
|
79
|
-
const claudePath = join(cwd, "CLAUDE.md");
|
|
80
|
-
let claudeContent = "";
|
|
81
|
-
try {
|
|
82
|
-
claudeContent = await readFile(claudePath, "utf-8");
|
|
83
|
-
}
|
|
84
31
|
catch {
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
if (claudeContent.includes(CLAUDE_MD_START)) {
|
|
88
|
-
const regex = new RegExp(`${escapeRegex(CLAUDE_MD_START)}[\\s\\S]*?${escapeRegex(CLAUDE_MD_END)}`);
|
|
89
|
-
claudeContent = claudeContent.replace(regex, claudeBlock);
|
|
32
|
+
feature = await ask('Feature name: ');
|
|
90
33
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
(claudeContent.endsWith("\n") ? "\n" : "\n\n") +
|
|
95
|
-
claudeBlock +
|
|
96
|
-
"\n";
|
|
97
|
-
}
|
|
98
|
-
await writeFile(claudePath, claudeContent);
|
|
99
|
-
summary({ Team: config.team, Feature: feature, Role: config.role });
|
|
100
|
-
success("Wrote .bridgellm.yml, .mcp.json, CLAUDE.md");
|
|
101
|
-
info("Restart Claude Code to connect.\n");
|
|
102
|
-
}
|
|
103
|
-
function escapeRegex(s) {
|
|
104
|
-
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
34
|
+
if (!feature)
|
|
35
|
+
throw new Error('Feature name is required.');
|
|
36
|
+
return feature;
|
|
105
37
|
}
|
|
106
38
|
//# sourceMappingURL=connect.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connect.js","sourceRoot":"","sources":["../../src/commands/connect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"connect.js","sourceRoot":"","sources":["../../src/commands/connect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAEvC,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,SAAiB,EACjB,KAAa,EACb,cAAuB;IAEvB,IAAI,OAAe,CAAC;IAEpB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,SAAS,eAAe,EAAE;YACnD,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE;SAC9C,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAEzD,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAMrC,CAAC;QAEF,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CACzB,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,aAAa,cAAc,CAAC,CAAC,eAAe,UAAU,CAC9E,CAAC;YACF,MAAM,UAAU,GAAG,cAAc;gBAC/B,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,cAAc,CAAC,CAAC;gBACnE,CAAC,CAAC,CAAC,CAAC;YAEN,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,gBAAgB,EAAE,MAAM,EAAE;gBACpD,QAAQ,EAAE,oBAAoB;gBAC9B,YAAY,EAAE,UAAU;aACzB,CAAC,CAAC;YAEH,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;gBACjB,OAAO,GAAG,MAAM,GAAG,CAAC,gBAAgB,CAAC,CAAC;YACxC,CAAC;iBAAM,CAAC;gBACN,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC;YACzB,CAAC;QACH,CAAC;aAAM,CAAC;YACN,OAAO,GAAG,MAAM,GAAG,CAAC,iCAAiC,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,MAAM,GAAG,CAAC,gBAAgB,CAAC,CAAC;IACxC,CAAC;IAED,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAE3D,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
package/dist/commands/login.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import http from 'node:http';
|
|
2
|
-
import { saveToken, saveServerUrl
|
|
3
|
-
import { heading, info, success
|
|
2
|
+
import { saveToken, saveServerUrl } from '../config.js';
|
|
3
|
+
import { heading, info, success } from '../ui.js';
|
|
4
4
|
function escapeHtml(s) {
|
|
5
5
|
return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
|
6
6
|
}
|
|
@@ -24,8 +24,7 @@ export async function login(serverUrl) {
|
|
|
24
24
|
});
|
|
25
25
|
const authUrl = `${serverUrl}/auth/github?cli_port=${port}`;
|
|
26
26
|
heading('GitHub Authentication');
|
|
27
|
-
info(
|
|
28
|
-
info(`If it doesn't open, visit:\n ${authUrl}\n`);
|
|
27
|
+
info(`If the browser doesn't open, visit:\n ${authUrl}\n`);
|
|
29
28
|
const open = (await import('open')).default;
|
|
30
29
|
await open(authUrl);
|
|
31
30
|
const result = await new Promise((resolve, reject) => {
|
|
@@ -65,58 +64,6 @@ export async function login(serverUrl) {
|
|
|
65
64
|
server.close();
|
|
66
65
|
await saveToken(result.token);
|
|
67
66
|
await saveServerUrl(serverUrl);
|
|
68
|
-
success(`
|
|
69
|
-
// Check if global config already has team + role
|
|
70
|
-
const existing = await getGlobalConfig();
|
|
71
|
-
if (existing.team && existing.role) {
|
|
72
|
-
summary({ Team: existing.team, Role: existing.role });
|
|
73
|
-
info('Run `bridgellm connect` in your project directory.\n');
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
// First-time setup
|
|
77
|
-
heading('First-time setup');
|
|
78
|
-
console.log('');
|
|
79
|
-
// Team
|
|
80
|
-
let teamName;
|
|
81
|
-
const meRes = await fetch(`${serverUrl}/api/me`, {
|
|
82
|
-
headers: { Authorization: `Bearer ${result.token}` },
|
|
83
|
-
});
|
|
84
|
-
const me = await meRes.json();
|
|
85
|
-
if (me.team) {
|
|
86
|
-
teamName = me.team.name;
|
|
87
|
-
success(`Team: ${teamName}`);
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
const { value, isNew } = await select('No team yet', ['Create a new team', 'Join with invite code']);
|
|
91
|
-
if (value === 'Create a new team') {
|
|
92
|
-
const name = await ask('Team name: ');
|
|
93
|
-
const res = await fetch(`${serverUrl}/api/teams`, {
|
|
94
|
-
method: 'POST',
|
|
95
|
-
headers: { Authorization: `Bearer ${result.token}`, 'Content-Type': 'application/json' },
|
|
96
|
-
body: JSON.stringify({ name }),
|
|
97
|
-
});
|
|
98
|
-
const data = await res.json();
|
|
99
|
-
teamName = data.team.name;
|
|
100
|
-
success(`Created "${teamName}"`);
|
|
101
|
-
info(`Invite code: ${data.invite_code}`);
|
|
102
|
-
info('Share this code so teammates can join.\n');
|
|
103
|
-
}
|
|
104
|
-
else {
|
|
105
|
-
const code = await ask('Invite code: ');
|
|
106
|
-
const res = await fetch(`${serverUrl}/api/teams/join`, {
|
|
107
|
-
method: 'POST',
|
|
108
|
-
headers: { Authorization: `Bearer ${result.token}`, 'Content-Type': 'application/json' },
|
|
109
|
-
body: JSON.stringify({ invite_code: code }),
|
|
110
|
-
});
|
|
111
|
-
const data = await res.json();
|
|
112
|
-
teamName = data.team.name;
|
|
113
|
-
success(`Joined "${teamName}"`);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
// Role
|
|
117
|
-
const role = await selectRole();
|
|
118
|
-
await saveGlobalConfig({ team: teamName, role });
|
|
119
|
-
summary({ Team: teamName, Role: role });
|
|
120
|
-
info('Run `bridgellm connect` in your project directory.\n');
|
|
67
|
+
success(`Authenticated as ${result.name}`);
|
|
121
68
|
}
|
|
122
69
|
//# sourceMappingURL=login.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/team.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getToken, getServerUrl, getGlobalConfig, saveGlobalConfig } from '../config.js';
|
|
2
|
+
import { success, info } from '../ui.js';
|
|
2
3
|
export async function createTeam(name) {
|
|
3
4
|
const token = await getToken();
|
|
4
5
|
const serverUrl = await getServerUrl();
|
|
@@ -12,16 +13,14 @@ export async function createTeam(name) {
|
|
|
12
13
|
});
|
|
13
14
|
const data = await res.json();
|
|
14
15
|
if (!res.ok) {
|
|
15
|
-
|
|
16
|
-
process.exit(1);
|
|
16
|
+
throw new Error(data.error);
|
|
17
17
|
}
|
|
18
18
|
const result = data;
|
|
19
|
-
// Update global config
|
|
20
19
|
const global = await getGlobalConfig();
|
|
21
20
|
await saveGlobalConfig({ ...global, team: result.team.name });
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
success(`Team "${result.team.name}" created`);
|
|
22
|
+
info(`Invite code: ${result.invite_code}`);
|
|
23
|
+
info('Share this code so teammates can join.');
|
|
25
24
|
}
|
|
26
25
|
export async function joinTeam(inviteCode) {
|
|
27
26
|
const token = await getToken();
|
|
@@ -36,13 +35,11 @@ export async function joinTeam(inviteCode) {
|
|
|
36
35
|
});
|
|
37
36
|
const data = await res.json();
|
|
38
37
|
if (!res.ok) {
|
|
39
|
-
|
|
40
|
-
process.exit(1);
|
|
38
|
+
throw new Error(data.error);
|
|
41
39
|
}
|
|
42
40
|
const result = data;
|
|
43
|
-
// Update global config
|
|
44
41
|
const global = await getGlobalConfig();
|
|
45
42
|
await saveGlobalConfig({ ...global, team: result.team.name });
|
|
46
|
-
|
|
43
|
+
success(`Joined "${result.team.name}"`);
|
|
47
44
|
}
|
|
48
45
|
//# sourceMappingURL=team.js.map
|
|
@@ -1 +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;
|
|
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;AACzF,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAEzC,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,MAAM,IAAI,KAAK,CAAE,IAA0B,CAAC,KAAK,CAAC,CAAC;IACrD,CAAC;IAED,MAAM,MAAM,GAAG,IAAuD,CAAC;IAEvE,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,SAAS,MAAM,CAAC,IAAI,CAAC,IAAI,WAAW,CAAC,CAAC;IAC9C,IAAI,CAAC,gBAAgB,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;IAC3C,IAAI,CAAC,wCAAwC,CAAC,CAAC;AACjD,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,MAAM,IAAI,KAAK,CAAE,IAA0B,CAAC,KAAK,CAAC,CAAC;IACrD,CAAC;IAED,MAAM,MAAM,GAAG,IAAmD,CAAC;IAEnE,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,WAAW,MAAM,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;AAC1C,CAAC"}
|
package/dist/config.d.ts
CHANGED
|
@@ -23,5 +23,6 @@ export declare function saveGlobalConfig(config: GlobalConfig): Promise<void>;
|
|
|
23
23
|
export declare function getLocalConfig(cwd: string): Promise<LocalConfig>;
|
|
24
24
|
export declare function saveLocalConfig(cwd: string, config: LocalConfig): Promise<void>;
|
|
25
25
|
export declare function getMergedConfig(cwd: string): Promise<MergedConfig>;
|
|
26
|
+
export declare function writeMcpJson(cwd: string): Promise<void>;
|
|
26
27
|
export declare function clean(cwd: string): Promise<void>;
|
|
27
28
|
export declare function reset(cwd: string): Promise<void>;
|