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/dist/ui.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createInterface } from 'node:readline';
|
|
1
|
+
import { createInterface, emitKeypressEvents } from 'node:readline';
|
|
2
2
|
const DIM = '\x1b[2m';
|
|
3
3
|
const BOLD = '\x1b[1m';
|
|
4
4
|
const GREEN = '\x1b[32m';
|
|
@@ -6,6 +6,10 @@ const CYAN = '\x1b[36m';
|
|
|
6
6
|
const YELLOW = '\x1b[33m';
|
|
7
7
|
const RED = '\x1b[31m';
|
|
8
8
|
const RESET = '\x1b[0m';
|
|
9
|
+
// Restore cursor on exit (in case of crash during selection)
|
|
10
|
+
process.on('exit', () => {
|
|
11
|
+
process.stdout.write('\x1b[?25h');
|
|
12
|
+
});
|
|
9
13
|
export function heading(text) {
|
|
10
14
|
console.log(`\n ${BOLD}${text}${RESET}`);
|
|
11
15
|
}
|
|
@@ -34,60 +38,100 @@ export async function ask(question) {
|
|
|
34
38
|
});
|
|
35
39
|
}
|
|
36
40
|
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
41
|
+
* Arrow-key navigable select list.
|
|
42
|
+
* Use ↑/↓ to move, Enter to confirm.
|
|
39
43
|
*/
|
|
40
44
|
export async function select(label, options, extra) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
+
const items = [...options];
|
|
46
|
+
const newIdx = extra?.newLabel ? items.length : -1;
|
|
47
|
+
if (extra?.newLabel)
|
|
48
|
+
items.push(`+ ${extra.newLabel}`);
|
|
49
|
+
let selected = extra?.defaultIndex ?? 0;
|
|
50
|
+
if (selected < 0 || selected >= items.length)
|
|
51
|
+
selected = 0;
|
|
52
|
+
const totalLines = items.length;
|
|
53
|
+
// Print label
|
|
54
|
+
if (label) {
|
|
55
|
+
heading(label);
|
|
56
|
+
console.log('');
|
|
57
|
+
}
|
|
58
|
+
// Initial render
|
|
59
|
+
renderItems(items, selected, newIdx);
|
|
60
|
+
// Hide cursor during selection
|
|
61
|
+
process.stdout.write('\x1b[?25l');
|
|
62
|
+
return new Promise((resolve) => {
|
|
63
|
+
emitKeypressEvents(process.stdin);
|
|
64
|
+
if (process.stdin.isTTY)
|
|
65
|
+
process.stdin.setRawMode(true);
|
|
66
|
+
process.stdin.resume();
|
|
67
|
+
const onKeypress = (_str, key) => {
|
|
68
|
+
if (!key)
|
|
69
|
+
return;
|
|
70
|
+
if (key.ctrl && key.name === 'c') {
|
|
71
|
+
cleanup();
|
|
72
|
+
process.exit(0);
|
|
73
|
+
}
|
|
74
|
+
if (key.name === 'up' && selected > 0) {
|
|
75
|
+
selected--;
|
|
76
|
+
rerender(items, selected, totalLines, newIdx);
|
|
77
|
+
}
|
|
78
|
+
else if (key.name === 'down' && selected < items.length - 1) {
|
|
79
|
+
selected++;
|
|
80
|
+
rerender(items, selected, totalLines, newIdx);
|
|
81
|
+
}
|
|
82
|
+
else if (key.name === 'return') {
|
|
83
|
+
cleanup();
|
|
84
|
+
console.log('');
|
|
85
|
+
if (selected === newIdx) {
|
|
86
|
+
resolve({ value: '', isNew: true });
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
const clean = options[selected].replace(/\s*\(.*\)$/, '');
|
|
90
|
+
resolve({ value: clean, isNew: false });
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
const cleanup = () => {
|
|
95
|
+
process.stdout.write('\x1b[?25h'); // show cursor
|
|
96
|
+
process.stdin.removeListener('keypress', onKeypress);
|
|
97
|
+
if (process.stdin.isTTY)
|
|
98
|
+
process.stdin.setRawMode(false);
|
|
99
|
+
process.stdin.pause();
|
|
100
|
+
};
|
|
101
|
+
process.stdin.on('keypress', onKeypress);
|
|
45
102
|
});
|
|
46
|
-
|
|
47
|
-
|
|
103
|
+
}
|
|
104
|
+
function formatItem(item, index, selected, newIdx) {
|
|
105
|
+
const arrow = index === selected ? `${GREEN}❯${RESET}` : ' ';
|
|
106
|
+
let text;
|
|
107
|
+
if (index === selected) {
|
|
108
|
+
text = index === newIdx ? `${CYAN}${item}${RESET}` : `${CYAN}${BOLD}${item}${RESET}`;
|
|
48
109
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
const idx = parseInt(input, 10) - 1;
|
|
52
|
-
if (idx >= 0 && idx < options.length) {
|
|
53
|
-
// Extract clean name (strip any metadata in parens)
|
|
54
|
-
const clean = options[idx].replace(/\s*\(.*\)$/, '');
|
|
55
|
-
return { value: clean, isNew: false };
|
|
110
|
+
else {
|
|
111
|
+
text = `${DIM}${item}${RESET}`;
|
|
56
112
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
113
|
+
return ` ${arrow} ${text}`;
|
|
114
|
+
}
|
|
115
|
+
function renderItems(items, selected, newIdx) {
|
|
116
|
+
for (let i = 0; i < items.length; i++) {
|
|
117
|
+
console.log(formatItem(items[i], i, selected, newIdx));
|
|
60
118
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
119
|
+
}
|
|
120
|
+
function rerender(items, selected, totalLines, newIdx) {
|
|
121
|
+
process.stdout.write(`\x1b[${totalLines}A`);
|
|
122
|
+
for (let i = 0; i < items.length; i++) {
|
|
123
|
+
process.stdout.write('\x1b[2K');
|
|
124
|
+
console.log(formatItem(items[i], i, selected, newIdx));
|
|
64
125
|
}
|
|
65
|
-
throw new Error('Invalid selection');
|
|
66
126
|
}
|
|
67
127
|
/**
|
|
68
|
-
*
|
|
128
|
+
* Arrow-key navigable role picker.
|
|
69
129
|
*/
|
|
70
|
-
export async function selectRole() {
|
|
130
|
+
export async function selectRole(defaultRole) {
|
|
71
131
|
const ROLES = ['backend', 'frontend', 'web', 'mobile', 'ios', 'android', 'infra', 'data', 'qa', 'design'];
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
for (let i = 0; i < ROLES.length; i += 2) {
|
|
76
|
-
const left = `${DIM}${i + 1}.${RESET} ${ROLES[i]}`;
|
|
77
|
-
const right = i + 1 < ROLES.length ? `${DIM}${i + 2}.${RESET} ${ROLES[i + 1]}` : '';
|
|
78
|
-
console.log(` ${left.padEnd(28)}${right}`);
|
|
79
|
-
}
|
|
80
|
-
console.log('');
|
|
81
|
-
const input = await ask(`${DIM}Enter number or name:${RESET} `);
|
|
82
|
-
const idx = parseInt(input, 10) - 1;
|
|
83
|
-
if (idx >= 0 && idx < ROLES.length) {
|
|
84
|
-
return ROLES[idx];
|
|
85
|
-
}
|
|
86
|
-
const normalized = input.toLowerCase().trim();
|
|
87
|
-
const match = ROLES.find(r => r === normalized);
|
|
88
|
-
if (match)
|
|
89
|
-
return match;
|
|
90
|
-
throw new Error(`Invalid role "${input}". Must be one of: ${ROLES.join(', ')}`);
|
|
132
|
+
const defaultIdx = defaultRole ? Math.max(0, ROLES.indexOf(defaultRole)) : 0;
|
|
133
|
+
const { value } = await select('Select your role', ROLES, { defaultIndex: defaultIdx });
|
|
134
|
+
return value;
|
|
91
135
|
}
|
|
92
136
|
/**
|
|
93
137
|
* Show a summary box.
|
package/dist/ui.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui.js","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"ui.js","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bridgellm",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Let your AI coding agents talk to each other across services",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -48,7 +48,6 @@
|
|
|
48
48
|
"README.md"
|
|
49
49
|
],
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"commander": "^13.0.0",
|
|
52
51
|
"open": "^10.0.0"
|
|
53
52
|
},
|
|
54
53
|
"devDependencies": {
|