@splicr/mcp-server 0.9.2 → 0.9.4
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/dist/auth.d.ts +13 -3
- package/dist/auth.js +115 -49
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +203 -22
- package/dist/config.d.ts +0 -1
- package/dist/config.js +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/lib/api-client.d.ts +0 -1
- package/dist/lib/api-client.js +0 -1
- package/dist/lib/feedback-tracker.d.ts +0 -1
- package/dist/lib/feedback-tracker.js +0 -1
- package/dist/lib/hint-engine.d.ts +0 -1
- package/dist/lib/hint-engine.js +0 -1
- package/dist/lib/profile-gatherer.d.ts +0 -1
- package/dist/lib/profile-gatherer.js +0 -1
- package/dist/lib/project-detector.d.ts +0 -1
- package/dist/lib/project-detector.js +0 -1
- package/dist/lib/session-state.d.ts +0 -1
- package/dist/lib/session-state.js +0 -1
- package/dist/lib/signal-fusion.d.ts +0 -1
- package/dist/lib/signal-fusion.js +0 -1
- package/dist/lib/signal-gatherer.d.ts +0 -1
- package/dist/lib/signal-gatherer.js +0 -1
- package/dist/login-cli.d.ts +0 -1
- package/dist/login-cli.js +0 -1
- package/dist/tools/browse-project.d.ts +0 -1
- package/dist/tools/browse-project.js +0 -1
- package/dist/tools/get-compiled-page.d.ts +0 -1
- package/dist/tools/get-compiled-page.js +0 -1
- package/dist/tools/get-full-content.d.ts +0 -1
- package/dist/tools/get-full-content.js +0 -1
- package/dist/tools/get-project-context.d.ts +0 -1
- package/dist/tools/get-project-context.js +0 -1
- package/dist/tools/get-recent-insights.d.ts +0 -1
- package/dist/tools/get-recent-insights.js +0 -1
- package/dist/tools/get-relevant-context.d.ts +0 -1
- package/dist/tools/get-relevant-context.js +0 -1
- package/dist/tools/retry-failed.d.ts +0 -1
- package/dist/tools/retry-failed.js +0 -1
- package/dist/tools/save-from-agent.d.ts +0 -1
- package/dist/tools/save-from-agent.js +0 -1
- package/dist/tools/search-knowledge.d.ts +0 -1
- package/dist/tools/search-knowledge.js +0 -1
- package/package.json +3 -2
- package/dist/auth.d.ts.map +0 -1
- package/dist/auth.js.map +0 -1
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/lib/api-client.d.ts.map +0 -1
- package/dist/lib/api-client.js.map +0 -1
- package/dist/lib/auto-register.d.ts.map +0 -1
- package/dist/lib/auto-register.js.map +0 -1
- package/dist/lib/embedding.d.ts.map +0 -1
- package/dist/lib/embedding.js.map +0 -1
- package/dist/lib/feedback-tracker.d.ts.map +0 -1
- package/dist/lib/feedback-tracker.js.map +0 -1
- package/dist/lib/hint-engine.d.ts.map +0 -1
- package/dist/lib/hint-engine.js.map +0 -1
- package/dist/lib/profile-gatherer.d.ts.map +0 -1
- package/dist/lib/profile-gatherer.js.map +0 -1
- package/dist/lib/project-detector.d.ts.map +0 -1
- package/dist/lib/project-detector.js.map +0 -1
- package/dist/lib/session-state.d.ts.map +0 -1
- package/dist/lib/session-state.js.map +0 -1
- package/dist/lib/signal-fusion.d.ts.map +0 -1
- package/dist/lib/signal-fusion.js.map +0 -1
- package/dist/lib/signal-gatherer.d.ts.map +0 -1
- package/dist/lib/signal-gatherer.js.map +0 -1
- package/dist/lib/supabase.d.ts.map +0 -1
- package/dist/lib/supabase.js.map +0 -1
- package/dist/login-cli.d.ts.map +0 -1
- package/dist/login-cli.js.map +0 -1
- package/dist/tools/browse-project.d.ts.map +0 -1
- package/dist/tools/browse-project.js.map +0 -1
- package/dist/tools/get-compiled-page.d.ts.map +0 -1
- package/dist/tools/get-compiled-page.js.map +0 -1
- package/dist/tools/get-full-content.d.ts.map +0 -1
- package/dist/tools/get-full-content.js.map +0 -1
- package/dist/tools/get-project-context.d.ts.map +0 -1
- package/dist/tools/get-project-context.js.map +0 -1
- package/dist/tools/get-recent-insights.d.ts.map +0 -1
- package/dist/tools/get-recent-insights.js.map +0 -1
- package/dist/tools/get-relevant-context.d.ts.map +0 -1
- package/dist/tools/get-relevant-context.js.map +0 -1
- package/dist/tools/retry-failed.d.ts.map +0 -1
- package/dist/tools/retry-failed.js.map +0 -1
- package/dist/tools/save-from-agent.d.ts.map +0 -1
- package/dist/tools/save-from-agent.js.map +0 -1
- package/dist/tools/search-knowledge.d.ts.map +0 -1
- package/dist/tools/search-knowledge.js.map +0 -1
package/dist/auth.d.ts
CHANGED
|
@@ -7,11 +7,21 @@ export declare function loadAuth(): Promise<{
|
|
|
7
7
|
userId: string;
|
|
8
8
|
}>;
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
10
|
+
* Terminal-first login — email + OTP, never leaves the terminal.
|
|
11
|
+
* Works for both new signups and existing users.
|
|
11
12
|
*/
|
|
12
|
-
export declare function login(): Promise<
|
|
13
|
+
export declare function login(): Promise<{
|
|
14
|
+
userId: string;
|
|
15
|
+
email: string;
|
|
16
|
+
}>;
|
|
17
|
+
/**
|
|
18
|
+
* Terminal-first login with invite code — for team join flows.
|
|
19
|
+
*/
|
|
20
|
+
export declare function loginWithInvite(inviteCode: string): Promise<{
|
|
21
|
+
userId: string;
|
|
22
|
+
email: string;
|
|
23
|
+
}>;
|
|
13
24
|
/**
|
|
14
25
|
* Check if auth.json exists (user has logged in before).
|
|
15
26
|
*/
|
|
16
27
|
export declare function hasAuth(): boolean;
|
|
17
|
-
//# sourceMappingURL=auth.d.ts.map
|
package/dist/auth.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
|
|
1
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync, chmodSync } from 'fs';
|
|
2
2
|
import { execSync } from 'child_process';
|
|
3
3
|
import { homedir } from 'os';
|
|
4
4
|
import { join } from 'path';
|
|
@@ -27,8 +27,13 @@ function readAuthFile() {
|
|
|
27
27
|
function writeAuthFile(auth) {
|
|
28
28
|
const dir = join(homedir(), '.splicr');
|
|
29
29
|
if (!existsSync(dir))
|
|
30
|
-
mkdirSync(dir, { recursive: true });
|
|
31
|
-
writeFileSync(AUTH_FILE, JSON.stringify(auth, null, 2));
|
|
30
|
+
mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
31
|
+
writeFileSync(AUTH_FILE, JSON.stringify(auth, null, 2), { mode: 0o600 });
|
|
32
|
+
// Ensure permissions even if file already existed
|
|
33
|
+
try {
|
|
34
|
+
chmodSync(AUTH_FILE, 0o600);
|
|
35
|
+
}
|
|
36
|
+
catch { /* Windows doesn't support chmod */ }
|
|
32
37
|
}
|
|
33
38
|
/**
|
|
34
39
|
* Load auth token. No refresh needed — token is permanent.
|
|
@@ -53,57 +58,119 @@ function openBrowser(url) {
|
|
|
53
58
|
}
|
|
54
59
|
}
|
|
55
60
|
/**
|
|
56
|
-
*
|
|
61
|
+
* Terminal-first login — email + OTP, never leaves the terminal.
|
|
62
|
+
* Works for both new signups and existing users.
|
|
57
63
|
*/
|
|
58
64
|
export async function login() {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
65
|
+
const rl = await createReadlineInterface();
|
|
66
|
+
try {
|
|
67
|
+
// Step 1: Get email
|
|
68
|
+
const email = await prompt(rl, ' Enter your email: ');
|
|
69
|
+
if (!email || !email.includes('@')) {
|
|
70
|
+
console.error(' Invalid email address.');
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
// Step 2: Send OTP
|
|
74
|
+
process.stderr.write(' Sending verification code...');
|
|
75
|
+
const sendRes = await fetch(`${API_URL}/auth/otp/send`, {
|
|
76
|
+
method: 'POST',
|
|
77
|
+
headers: { 'Content-Type': 'application/json', 'X-Splicr-Client': 'cli' },
|
|
78
|
+
body: JSON.stringify({ email }),
|
|
79
|
+
});
|
|
80
|
+
if (!sendRes.ok) {
|
|
81
|
+
const err = await sendRes.json().catch(() => ({}));
|
|
82
|
+
console.error(`\n ${err.error || 'Failed to send code. Check your email and try again.'}`);
|
|
83
|
+
process.exit(1);
|
|
84
|
+
}
|
|
85
|
+
console.error(' sent!');
|
|
86
|
+
// Step 3: Get OTP code
|
|
87
|
+
const code = await prompt(rl, ' Enter 6-digit code from your email: ');
|
|
88
|
+
if (!code || code.length !== 6) {
|
|
89
|
+
console.error(' Invalid code. Must be 6 digits.');
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
// Step 4: Verify OTP
|
|
93
|
+
process.stderr.write(' Verifying...');
|
|
94
|
+
const verifyRes = await fetch(`${API_URL}/auth/otp/verify`, {
|
|
95
|
+
method: 'POST',
|
|
96
|
+
headers: { 'Content-Type': 'application/json', 'X-Splicr-Client': 'cli' },
|
|
97
|
+
body: JSON.stringify({ email, code }),
|
|
98
|
+
});
|
|
99
|
+
if (!verifyRes.ok) {
|
|
100
|
+
const err = await verifyRes.json().catch(() => ({}));
|
|
101
|
+
console.error(`\n ${err.error || 'Verification failed.'}`);
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
const { data } = await verifyRes.json();
|
|
105
|
+
// Step 5: Save credentials
|
|
106
|
+
writeAuthFile({ token: data.token, user_id: data.user.id });
|
|
107
|
+
console.error(` authenticated as ${data.user.email}`);
|
|
108
|
+
return { userId: data.user.id, email: data.user.email };
|
|
68
109
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
110
|
+
finally {
|
|
111
|
+
rl.close();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Terminal-first login with invite code — for team join flows.
|
|
116
|
+
*/
|
|
117
|
+
export async function loginWithInvite(inviteCode) {
|
|
118
|
+
const rl = await createReadlineInterface();
|
|
119
|
+
try {
|
|
120
|
+
const email = await prompt(rl, ' Enter your email: ');
|
|
121
|
+
if (!email || !email.includes('@')) {
|
|
122
|
+
console.error(' Invalid email address.');
|
|
123
|
+
process.exit(1);
|
|
124
|
+
}
|
|
125
|
+
process.stderr.write(' Sending verification code...');
|
|
126
|
+
const sendRes = await fetch(`${API_URL}/auth/otp/send`, {
|
|
127
|
+
method: 'POST',
|
|
128
|
+
headers: { 'Content-Type': 'application/json', 'X-Splicr-Client': 'cli' },
|
|
129
|
+
body: JSON.stringify({ email, invite_code: inviteCode }),
|
|
130
|
+
});
|
|
131
|
+
if (!sendRes.ok) {
|
|
132
|
+
const err = await sendRes.json().catch(() => ({}));
|
|
133
|
+
console.error(`\n ${err.error || 'Failed to send code.'}`);
|
|
134
|
+
process.exit(1);
|
|
135
|
+
}
|
|
136
|
+
console.error(' sent!');
|
|
137
|
+
const code = await prompt(rl, ' Enter 6-digit code from your email: ');
|
|
138
|
+
if (!code || code.length !== 6) {
|
|
139
|
+
console.error(' Invalid code. Must be 6 digits.');
|
|
140
|
+
process.exit(1);
|
|
100
141
|
}
|
|
101
|
-
|
|
102
|
-
|
|
142
|
+
process.stderr.write(' Verifying...');
|
|
143
|
+
const verifyRes = await fetch(`${API_URL}/auth/otp/verify`, {
|
|
144
|
+
method: 'POST',
|
|
145
|
+
headers: { 'Content-Type': 'application/json', 'X-Splicr-Client': 'cli' },
|
|
146
|
+
body: JSON.stringify({ email, code }),
|
|
147
|
+
});
|
|
148
|
+
if (!verifyRes.ok) {
|
|
149
|
+
const err = await verifyRes.json().catch(() => ({}));
|
|
150
|
+
console.error(`\n ${err.error || 'Verification failed.'}`);
|
|
151
|
+
process.exit(1);
|
|
103
152
|
}
|
|
153
|
+
const { data } = await verifyRes.json();
|
|
154
|
+
writeAuthFile({ token: data.token, user_id: data.user.id });
|
|
155
|
+
console.error(` authenticated as ${data.user.email}`);
|
|
156
|
+
return { userId: data.user.id, email: data.user.email };
|
|
104
157
|
}
|
|
105
|
-
|
|
106
|
-
|
|
158
|
+
finally {
|
|
159
|
+
rl.close();
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// ===== readline helpers =====
|
|
163
|
+
import { createInterface } from 'readline';
|
|
164
|
+
function createReadlineInterface() {
|
|
165
|
+
return createInterface({
|
|
166
|
+
input: process.stdin,
|
|
167
|
+
output: process.stderr,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
function prompt(rl, question) {
|
|
171
|
+
return new Promise((resolve) => {
|
|
172
|
+
rl.question(question, (answer) => resolve(answer.trim()));
|
|
173
|
+
});
|
|
107
174
|
}
|
|
108
175
|
/**
|
|
109
176
|
* Check if auth.json exists (user has logged in before).
|
|
@@ -111,4 +178,3 @@ export async function login() {
|
|
|
111
178
|
export function hasAuth() {
|
|
112
179
|
return readAuthFile() !== null;
|
|
113
180
|
}
|
|
114
|
-
//# sourceMappingURL=auth.js.map
|
package/dist/cli.d.ts
CHANGED
package/dist/cli.js
CHANGED
|
@@ -12,6 +12,10 @@ import { execSync } from 'child_process';
|
|
|
12
12
|
import { homedir } from 'os';
|
|
13
13
|
import { join } from 'path';
|
|
14
14
|
const command = process.argv[2];
|
|
15
|
+
const subCommand = process.argv[3];
|
|
16
|
+
// Parse --join flag from any position
|
|
17
|
+
const joinIndex = process.argv.indexOf('--join');
|
|
18
|
+
const joinCode = joinIndex !== -1 ? process.argv[joinIndex + 1] : undefined;
|
|
15
19
|
// Hook constants
|
|
16
20
|
const SPLICR_HOOK_MARKER = '@splicr/mcp-server hook';
|
|
17
21
|
const SPLICR_HOOK_CONFIG = {
|
|
@@ -172,6 +176,9 @@ async function main() {
|
|
|
172
176
|
await login();
|
|
173
177
|
break;
|
|
174
178
|
}
|
|
179
|
+
case 'team':
|
|
180
|
+
await teamCommand();
|
|
181
|
+
break;
|
|
175
182
|
case 'uninstall':
|
|
176
183
|
case 'remove':
|
|
177
184
|
await uninstall();
|
|
@@ -188,6 +195,20 @@ async function main() {
|
|
|
188
195
|
case 'stop':
|
|
189
196
|
await runStop();
|
|
190
197
|
break;
|
|
198
|
+
case 'dashboard':
|
|
199
|
+
case 'open': {
|
|
200
|
+
const url = 'https://splicr.dev/dashboard';
|
|
201
|
+
console.log(`Opening ${url} ...`);
|
|
202
|
+
const { platform } = await import('os');
|
|
203
|
+
const openCmd = platform() === 'win32' ? 'start' : platform() === 'darwin' ? 'open' : 'xdg-open';
|
|
204
|
+
try {
|
|
205
|
+
execSync(`${openCmd} ${url}`, { stdio: 'ignore' });
|
|
206
|
+
}
|
|
207
|
+
catch {
|
|
208
|
+
console.log(`Open ${url} in your browser.`);
|
|
209
|
+
}
|
|
210
|
+
break;
|
|
211
|
+
}
|
|
191
212
|
case 'help':
|
|
192
213
|
case '--help':
|
|
193
214
|
case '-h':
|
|
@@ -203,13 +224,33 @@ async function main() {
|
|
|
203
224
|
}
|
|
204
225
|
}
|
|
205
226
|
async function setup() {
|
|
206
|
-
const
|
|
227
|
+
const hasJoin = !!joinCode;
|
|
228
|
+
const totalSteps = hasJoin ? 3 : 2;
|
|
207
229
|
console.error('\n Splicr — route what you read to what you\'re building\n');
|
|
208
|
-
// Step 1:
|
|
209
|
-
console.error(
|
|
210
|
-
await
|
|
211
|
-
|
|
212
|
-
|
|
230
|
+
// Step 1: Authenticate in terminal (email + OTP)
|
|
231
|
+
console.error(` Step 1/${totalSteps}: Authenticate\n`);
|
|
232
|
+
const { hasAuth, login, loginWithInvite } = await import('./auth.js');
|
|
233
|
+
let authInfo;
|
|
234
|
+
if (hasAuth()) {
|
|
235
|
+
const { loadAuth } = await import('./auth.js');
|
|
236
|
+
const existing = await loadAuth();
|
|
237
|
+
console.error(` Already authenticated (${existing.userId.substring(0, 8)}...)`);
|
|
238
|
+
authInfo = { userId: existing.userId, email: '' };
|
|
239
|
+
}
|
|
240
|
+
else if (hasJoin) {
|
|
241
|
+
authInfo = await loginWithInvite(joinCode);
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
authInfo = await login();
|
|
245
|
+
}
|
|
246
|
+
// Step 2 (optional): Join team
|
|
247
|
+
if (hasJoin) {
|
|
248
|
+
console.error(`\n Step 2/${totalSteps}: Join team\n`);
|
|
249
|
+
await joinTeam(joinCode);
|
|
250
|
+
}
|
|
251
|
+
// Step N: Detect and configure coding agents
|
|
252
|
+
const agentStep = hasJoin ? 3 : 2;
|
|
253
|
+
console.error(`\n Step ${agentStep}/${totalSteps}: Configure coding agents\n`);
|
|
213
254
|
const detected = detectInstalledAgents();
|
|
214
255
|
if (detected.length === 0) {
|
|
215
256
|
console.error(' No coding agents detected. Add Splicr manually to your agent\'s MCP config:\n');
|
|
@@ -228,16 +269,13 @@ async function setup() {
|
|
|
228
269
|
console.error('✗ failed (configure manually)');
|
|
229
270
|
}
|
|
230
271
|
}
|
|
231
|
-
//
|
|
272
|
+
// Inject instruction files + hooks
|
|
232
273
|
injectClaudeMd();
|
|
233
|
-
// Step 4: Inject Claude Code hook for 100% context injection
|
|
234
274
|
injectClaudeHook();
|
|
235
275
|
if (configured > 0) {
|
|
236
276
|
console.error(`\n Done! Splicr is connected to ${configured} agent(s).`);
|
|
237
277
|
console.error(' Start a new session in any agent to use it.');
|
|
238
278
|
console.error(' Save articles from your phone or browser — they\'ll show up when you code.\n');
|
|
239
|
-
console.error(' For manual setup or other agents:\n');
|
|
240
|
-
printManualConfig();
|
|
241
279
|
}
|
|
242
280
|
else {
|
|
243
281
|
console.error('\n Could not auto-configure any agents. Add manually:\n');
|
|
@@ -887,6 +925,144 @@ function injectClaudeHook() {
|
|
|
887
925
|
console.error(' • Claude Code hook... ✗ could not write settings.json');
|
|
888
926
|
}
|
|
889
927
|
}
|
|
928
|
+
// ===== Team commands =====
|
|
929
|
+
const API_URL = process.env.SPLICR_API_URL || 'https://api-production-d889.up.railway.app';
|
|
930
|
+
async function getAuthHeaders() {
|
|
931
|
+
const { loadAuth } = await import('./auth.js');
|
|
932
|
+
const auth = await loadAuth();
|
|
933
|
+
return {
|
|
934
|
+
'Authorization': `Bearer ${auth.accessToken}`,
|
|
935
|
+
'Content-Type': 'application/json',
|
|
936
|
+
};
|
|
937
|
+
}
|
|
938
|
+
async function joinTeam(inviteCode) {
|
|
939
|
+
const headers = await getAuthHeaders();
|
|
940
|
+
// Preview the team first
|
|
941
|
+
const previewRes = await fetch(`${API_URL}/teams/preview/${inviteCode}`);
|
|
942
|
+
if (!previewRes.ok) {
|
|
943
|
+
console.error(' Invalid invite code.');
|
|
944
|
+
process.exit(1);
|
|
945
|
+
}
|
|
946
|
+
const { data: preview } = await previewRes.json();
|
|
947
|
+
process.stderr.write(` Joining "${preview.name}" (${preview.member_count} members)...`);
|
|
948
|
+
const joinRes = await fetch(`${API_URL}/teams/join/${inviteCode}`, {
|
|
949
|
+
method: 'POST',
|
|
950
|
+
headers,
|
|
951
|
+
});
|
|
952
|
+
if (!joinRes.ok) {
|
|
953
|
+
const err = await joinRes.json().catch(() => ({}));
|
|
954
|
+
console.error(`\n ${err.error || 'Failed to join team.'}`);
|
|
955
|
+
process.exit(1);
|
|
956
|
+
}
|
|
957
|
+
const { data } = await joinRes.json();
|
|
958
|
+
console.error(` joined "${data.name}"!`);
|
|
959
|
+
}
|
|
960
|
+
async function teamCommand() {
|
|
961
|
+
const { hasAuth } = await import('./auth.js');
|
|
962
|
+
if (!hasAuth()) {
|
|
963
|
+
console.error('\n Not authenticated. Run `npx @splicr/mcp-server setup` first.\n');
|
|
964
|
+
process.exit(1);
|
|
965
|
+
}
|
|
966
|
+
switch (subCommand) {
|
|
967
|
+
case 'create': {
|
|
968
|
+
const name = process.argv.slice(4).join(' ');
|
|
969
|
+
if (!name) {
|
|
970
|
+
console.error('\n Usage: npx @splicr/mcp-server team create "My Team"\n');
|
|
971
|
+
process.exit(1);
|
|
972
|
+
}
|
|
973
|
+
const headers = await getAuthHeaders();
|
|
974
|
+
process.stderr.write(`\n Creating team "${name}"...`);
|
|
975
|
+
const res = await fetch(`${API_URL}/teams`, {
|
|
976
|
+
method: 'POST',
|
|
977
|
+
headers,
|
|
978
|
+
body: JSON.stringify({ name }),
|
|
979
|
+
});
|
|
980
|
+
if (!res.ok) {
|
|
981
|
+
const err = await res.json().catch(() => ({}));
|
|
982
|
+
console.error(`\n ${err.error || 'Failed to create team.'}`);
|
|
983
|
+
process.exit(1);
|
|
984
|
+
}
|
|
985
|
+
const { data } = await res.json();
|
|
986
|
+
console.error(' done!\n');
|
|
987
|
+
console.error(` Team: ${data.name}`);
|
|
988
|
+
console.error(` Invite code: ${data.invite_code}`);
|
|
989
|
+
console.error(` Invite link: https://splicr.dev/join/${data.invite_code}`);
|
|
990
|
+
console.error(`\n Share the link with teammates. They can join with:`);
|
|
991
|
+
console.error(` npx @splicr/mcp-server setup --join ${data.invite_code}\n`);
|
|
992
|
+
break;
|
|
993
|
+
}
|
|
994
|
+
case 'list': {
|
|
995
|
+
const headers = await getAuthHeaders();
|
|
996
|
+
const res = await fetch(`${API_URL}/teams`, { headers });
|
|
997
|
+
if (!res.ok) {
|
|
998
|
+
console.error('\n Failed to load teams.\n');
|
|
999
|
+
process.exit(1);
|
|
1000
|
+
}
|
|
1001
|
+
const { data: teams } = await res.json();
|
|
1002
|
+
if (!teams || teams.length === 0) {
|
|
1003
|
+
console.error('\n You\'re not on any teams yet.');
|
|
1004
|
+
console.error(' Create one: npx @splicr/mcp-server team create "My Team"\n');
|
|
1005
|
+
return;
|
|
1006
|
+
}
|
|
1007
|
+
console.error('\n Your teams:\n');
|
|
1008
|
+
for (const team of teams) {
|
|
1009
|
+
console.error(` • ${team.name} (${team.role})`);
|
|
1010
|
+
console.error(` Invite code: ${team.invite_code}`);
|
|
1011
|
+
console.error(` Invite link: https://splicr.dev/join/${team.invite_code}`);
|
|
1012
|
+
}
|
|
1013
|
+
console.error('');
|
|
1014
|
+
break;
|
|
1015
|
+
}
|
|
1016
|
+
case 'invite': {
|
|
1017
|
+
const headers = await getAuthHeaders();
|
|
1018
|
+
const res = await fetch(`${API_URL}/teams`, { headers });
|
|
1019
|
+
if (!res.ok) {
|
|
1020
|
+
console.error('\n Failed to load teams.\n');
|
|
1021
|
+
process.exit(1);
|
|
1022
|
+
}
|
|
1023
|
+
const { data: teams } = await res.json();
|
|
1024
|
+
if (!teams || teams.length === 0) {
|
|
1025
|
+
console.error('\n You\'re not on any teams. Create one first:');
|
|
1026
|
+
console.error(' npx @splicr/mcp-server team create "My Team"\n');
|
|
1027
|
+
return;
|
|
1028
|
+
}
|
|
1029
|
+
// Use the first team (most users will have one)
|
|
1030
|
+
const team = teams[0];
|
|
1031
|
+
const link = `https://splicr.dev/join/${team.invite_code}`;
|
|
1032
|
+
const setupCmd = `npx @splicr/mcp-server setup --join ${team.invite_code}`;
|
|
1033
|
+
console.error(`\n Team: ${team.name}\n`);
|
|
1034
|
+
console.error(` Invite link: ${link}`);
|
|
1035
|
+
console.error(` Terminal setup: ${setupCmd}`);
|
|
1036
|
+
console.error(`\n Share either with your teammates.\n`);
|
|
1037
|
+
break;
|
|
1038
|
+
}
|
|
1039
|
+
case 'join': {
|
|
1040
|
+
const code = process.argv[4];
|
|
1041
|
+
if (!code) {
|
|
1042
|
+
console.error('\n Usage: npx @splicr/mcp-server team join <invite-code>\n');
|
|
1043
|
+
process.exit(1);
|
|
1044
|
+
}
|
|
1045
|
+
console.error('');
|
|
1046
|
+
await joinTeam(code);
|
|
1047
|
+
console.error('');
|
|
1048
|
+
break;
|
|
1049
|
+
}
|
|
1050
|
+
default:
|
|
1051
|
+
console.error(`
|
|
1052
|
+
Splicr Teams
|
|
1053
|
+
|
|
1054
|
+
Commands:
|
|
1055
|
+
team create "Name" Create a new team
|
|
1056
|
+
team list List your teams
|
|
1057
|
+
team invite Show invite link for your team
|
|
1058
|
+
team join <code> Join a team by invite code
|
|
1059
|
+
|
|
1060
|
+
Or use setup --join:
|
|
1061
|
+
setup --join <code> Sign up + join team + configure agents (one command)
|
|
1062
|
+
`);
|
|
1063
|
+
break;
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
890
1066
|
function printManualConfig() {
|
|
891
1067
|
console.error(' Add this to your agent\'s MCP settings:\n');
|
|
892
1068
|
console.error(' {');
|
|
@@ -900,27 +1076,32 @@ function printManualConfig() {
|
|
|
900
1076
|
}
|
|
901
1077
|
function printHelp() {
|
|
902
1078
|
console.error(`
|
|
903
|
-
Splicr
|
|
1079
|
+
Splicr — route what you read to what you're building
|
|
1080
|
+
|
|
1081
|
+
Getting started:
|
|
1082
|
+
npx @splicr/mcp-server setup Sign up + configure all agents (one command)
|
|
1083
|
+
npx @splicr/mcp-server setup --join <code> Sign up + join team + configure agents
|
|
904
1084
|
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
1085
|
+
Commands:
|
|
1086
|
+
setup One-time setup: authenticate + configure agents + hooks
|
|
1087
|
+
login Re-authenticate
|
|
1088
|
+
team create "Name" Create a new team
|
|
1089
|
+
team list List your teams
|
|
1090
|
+
team invite Show invite link for your team
|
|
1091
|
+
team join <code> Join a team by invite code
|
|
1092
|
+
dashboard Open knowledge dashboard in browser
|
|
1093
|
+
uninstall Remove Splicr from all coding agents
|
|
911
1094
|
|
|
912
1095
|
Supported agents (auto-detected):
|
|
913
1096
|
Claude Code, Codex, Cursor, Cline, Antigravity
|
|
914
1097
|
|
|
915
1098
|
Quick start:
|
|
916
|
-
1.
|
|
917
|
-
2.
|
|
918
|
-
3.
|
|
919
|
-
4. Open any coding agent — your saves show up when relevant
|
|
1099
|
+
1. Run: npx @splicr/mcp-server setup
|
|
1100
|
+
2. Start saving articles from your phone or browser
|
|
1101
|
+
3. Open any coding agent — your saves show up when relevant
|
|
920
1102
|
`);
|
|
921
1103
|
}
|
|
922
1104
|
main().catch(err => {
|
|
923
1105
|
console.error(`Error: ${err.message}`);
|
|
924
1106
|
process.exit(1);
|
|
925
1107
|
});
|
|
926
|
-
//# sourceMappingURL=cli.js.map
|
package/dist/config.d.ts
CHANGED
package/dist/config.js
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/dist/lib/api-client.d.ts
CHANGED
package/dist/lib/api-client.js
CHANGED
package/dist/lib/hint-engine.js
CHANGED
|
@@ -9,4 +9,3 @@ export declare function detectProject(cwd: string): Promise<DetectedProject | nu
|
|
|
9
9
|
export declare function getGitRemoteUrl(cwd: string): string | null;
|
|
10
10
|
export declare function normalizeGitUrl(url: string): string;
|
|
11
11
|
export {};
|
|
12
|
-
//# sourceMappingURL=project-detector.d.ts.map
|
|
@@ -31,4 +31,3 @@ export declare function parseBranchName(name: string): string | null;
|
|
|
31
31
|
* ["src/routes/auth.ts", "src/middleware/rate-limit.ts"] → "auth routes rate-limit middleware"
|
|
32
32
|
*/
|
|
33
33
|
export declare function extractConceptsFromPaths(files: string[]): string | null;
|
|
34
|
-
//# sourceMappingURL=signal-fusion.d.ts.map
|
package/dist/login-cli.d.ts
CHANGED
package/dist/login-cli.js
CHANGED