@splicr/mcp-server 0.9.3 → 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.
Files changed (95) hide show
  1. package/dist/auth.d.ts +13 -3
  2. package/dist/auth.js +115 -49
  3. package/dist/cli.d.ts +0 -1
  4. package/dist/cli.js +189 -23
  5. package/dist/config.d.ts +0 -1
  6. package/dist/config.js +0 -1
  7. package/dist/index.d.ts +0 -1
  8. package/dist/index.js +0 -1
  9. package/dist/lib/api-client.d.ts +0 -1
  10. package/dist/lib/api-client.js +0 -1
  11. package/dist/lib/feedback-tracker.d.ts +0 -1
  12. package/dist/lib/feedback-tracker.js +0 -1
  13. package/dist/lib/hint-engine.d.ts +0 -1
  14. package/dist/lib/hint-engine.js +0 -1
  15. package/dist/lib/profile-gatherer.d.ts +0 -1
  16. package/dist/lib/profile-gatherer.js +0 -1
  17. package/dist/lib/project-detector.d.ts +0 -1
  18. package/dist/lib/project-detector.js +0 -1
  19. package/dist/lib/session-state.d.ts +0 -1
  20. package/dist/lib/session-state.js +0 -1
  21. package/dist/lib/signal-fusion.d.ts +0 -1
  22. package/dist/lib/signal-fusion.js +0 -1
  23. package/dist/lib/signal-gatherer.d.ts +0 -1
  24. package/dist/lib/signal-gatherer.js +0 -1
  25. package/dist/login-cli.d.ts +0 -1
  26. package/dist/login-cli.js +0 -1
  27. package/dist/tools/browse-project.d.ts +0 -1
  28. package/dist/tools/browse-project.js +0 -1
  29. package/dist/tools/get-compiled-page.d.ts +0 -1
  30. package/dist/tools/get-compiled-page.js +0 -1
  31. package/dist/tools/get-full-content.d.ts +0 -1
  32. package/dist/tools/get-full-content.js +0 -1
  33. package/dist/tools/get-project-context.d.ts +0 -1
  34. package/dist/tools/get-project-context.js +0 -1
  35. package/dist/tools/get-recent-insights.d.ts +0 -1
  36. package/dist/tools/get-recent-insights.js +0 -1
  37. package/dist/tools/get-relevant-context.d.ts +0 -1
  38. package/dist/tools/get-relevant-context.js +0 -1
  39. package/dist/tools/retry-failed.d.ts +0 -1
  40. package/dist/tools/retry-failed.js +0 -1
  41. package/dist/tools/save-from-agent.d.ts +0 -1
  42. package/dist/tools/save-from-agent.js +0 -1
  43. package/dist/tools/search-knowledge.d.ts +0 -1
  44. package/dist/tools/search-knowledge.js +0 -1
  45. package/package.json +3 -2
  46. package/dist/auth.d.ts.map +0 -1
  47. package/dist/auth.js.map +0 -1
  48. package/dist/cli.d.ts.map +0 -1
  49. package/dist/cli.js.map +0 -1
  50. package/dist/config.d.ts.map +0 -1
  51. package/dist/config.js.map +0 -1
  52. package/dist/index.d.ts.map +0 -1
  53. package/dist/index.js.map +0 -1
  54. package/dist/lib/api-client.d.ts.map +0 -1
  55. package/dist/lib/api-client.js.map +0 -1
  56. package/dist/lib/auto-register.d.ts.map +0 -1
  57. package/dist/lib/auto-register.js.map +0 -1
  58. package/dist/lib/embedding.d.ts.map +0 -1
  59. package/dist/lib/embedding.js.map +0 -1
  60. package/dist/lib/feedback-tracker.d.ts.map +0 -1
  61. package/dist/lib/feedback-tracker.js.map +0 -1
  62. package/dist/lib/hint-engine.d.ts.map +0 -1
  63. package/dist/lib/hint-engine.js.map +0 -1
  64. package/dist/lib/profile-gatherer.d.ts.map +0 -1
  65. package/dist/lib/profile-gatherer.js.map +0 -1
  66. package/dist/lib/project-detector.d.ts.map +0 -1
  67. package/dist/lib/project-detector.js.map +0 -1
  68. package/dist/lib/session-state.d.ts.map +0 -1
  69. package/dist/lib/session-state.js.map +0 -1
  70. package/dist/lib/signal-fusion.d.ts.map +0 -1
  71. package/dist/lib/signal-fusion.js.map +0 -1
  72. package/dist/lib/signal-gatherer.d.ts.map +0 -1
  73. package/dist/lib/signal-gatherer.js.map +0 -1
  74. package/dist/lib/supabase.d.ts.map +0 -1
  75. package/dist/lib/supabase.js.map +0 -1
  76. package/dist/login-cli.d.ts.map +0 -1
  77. package/dist/login-cli.js.map +0 -1
  78. package/dist/tools/browse-project.d.ts.map +0 -1
  79. package/dist/tools/browse-project.js.map +0 -1
  80. package/dist/tools/get-compiled-page.d.ts.map +0 -1
  81. package/dist/tools/get-compiled-page.js.map +0 -1
  82. package/dist/tools/get-full-content.d.ts.map +0 -1
  83. package/dist/tools/get-full-content.js.map +0 -1
  84. package/dist/tools/get-project-context.d.ts.map +0 -1
  85. package/dist/tools/get-project-context.js.map +0 -1
  86. package/dist/tools/get-recent-insights.d.ts.map +0 -1
  87. package/dist/tools/get-recent-insights.js.map +0 -1
  88. package/dist/tools/get-relevant-context.d.ts.map +0 -1
  89. package/dist/tools/get-relevant-context.js.map +0 -1
  90. package/dist/tools/retry-failed.d.ts.map +0 -1
  91. package/dist/tools/retry-failed.js.map +0 -1
  92. package/dist/tools/save-from-agent.d.ts.map +0 -1
  93. package/dist/tools/save-from-agent.js.map +0 -1
  94. package/dist/tools/search-knowledge.d.ts.map +0 -1
  95. 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
- * Browser-based login flow opens browser for OTP auth, polls for completion.
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<void>;
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
- * Browser-based login flow opens browser for OTP auth, polls for completion.
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
- // Step 1: Create CLI link code
60
- const linkRes = await fetch(`${API_URL}/auth/cli-link`, {
61
- method: 'POST',
62
- headers: { 'Content-Type': 'application/json' },
63
- body: JSON.stringify({}),
64
- });
65
- if (!linkRes.ok) {
66
- console.error(' Failed to create auth link. Check your internet connection.');
67
- process.exit(1);
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
- const { data: { code } } = await linkRes.json();
70
- const authUrl = `${WEB_URL}/cli-auth?code=${code}`;
71
- // Step 2: Open browser
72
- console.error(` Opening browser to sign in...`);
73
- console.error(` If the browser didn't open, visit:\n ${authUrl}\n`);
74
- openBrowser(authUrl);
75
- // Step 3: Poll for completion (every 2s, up to 5 min)
76
- const maxAttempts = 150;
77
- for (let i = 0; i < maxAttempts; i++) {
78
- await new Promise(r => setTimeout(r, 2000));
79
- try {
80
- const pollRes = await fetch(`${API_URL}/auth/cli-link/${code}`);
81
- if (!pollRes.ok) {
82
- console.error('\n Auth link expired. Run setup again.');
83
- process.exit(1);
84
- }
85
- const pollBody = await pollRes.json();
86
- if (pollBody.data.status === 'complete') {
87
- const auth = {
88
- token: pollBody.data.token,
89
- user_id: pollBody.data.user.id,
90
- };
91
- writeAuthFile(auth);
92
- console.error(` Authenticated as ${pollBody.data.user.email}`);
93
- console.error(` Credentials saved to ${AUTH_FILE}`);
94
- return;
95
- }
96
- // Show dots for progress
97
- if (i > 0 && i % 5 === 0) {
98
- process.stderr.write('.');
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
- catch {
102
- // Network error keep polling
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
- console.error('\n Authentication timed out. Run `npx @splicr/mcp-server login` to try again.');
106
- process.exit(1);
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
@@ -8,4 +8,3 @@
8
8
  * - "help" → print usage
9
9
  */
10
10
  export {};
11
- //# sourceMappingURL=cli.d.ts.map
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();
@@ -217,13 +224,33 @@ async function main() {
217
224
  }
218
225
  }
219
226
  async function setup() {
220
- const { login } = await import('./auth.js');
227
+ const hasJoin = !!joinCode;
228
+ const totalSteps = hasJoin ? 3 : 2;
221
229
  console.error('\n Splicr — route what you read to what you\'re building\n');
222
- // Step 1: Login
223
- console.error(' Step 1/2: Authenticate\n');
224
- await login();
225
- // Step 2: Detect and configure coding agents
226
- console.error('\n Step 2/2: Configure coding agents\n');
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`);
227
254
  const detected = detectInstalledAgents();
228
255
  if (detected.length === 0) {
229
256
  console.error(' No coding agents detected. Add Splicr manually to your agent\'s MCP config:\n');
@@ -242,16 +269,13 @@ async function setup() {
242
269
  console.error('✗ failed (configure manually)');
243
270
  }
244
271
  }
245
- // Step 3: Inject CLAUDE.md instruction for reliable tool usage
272
+ // Inject instruction files + hooks
246
273
  injectClaudeMd();
247
- // Step 4: Inject Claude Code hook for 100% context injection
248
274
  injectClaudeHook();
249
275
  if (configured > 0) {
250
276
  console.error(`\n Done! Splicr is connected to ${configured} agent(s).`);
251
277
  console.error(' Start a new session in any agent to use it.');
252
278
  console.error(' Save articles from your phone or browser — they\'ll show up when you code.\n');
253
- console.error(' For manual setup or other agents:\n');
254
- printManualConfig();
255
279
  }
256
280
  else {
257
281
  console.error('\n Could not auto-configure any agents. Add manually:\n');
@@ -901,6 +925,144 @@ function injectClaudeHook() {
901
925
  console.error(' • Claude Code hook... ✗ could not write settings.json');
902
926
  }
903
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
+ }
904
1066
  function printManualConfig() {
905
1067
  console.error(' Add this to your agent\'s MCP settings:\n');
906
1068
  console.error(' {');
@@ -914,28 +1076,32 @@ function printManualConfig() {
914
1076
  }
915
1077
  function printHelp() {
916
1078
  console.error(`
917
- Splicr MCP Server — route what you read to what you're building
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
918
1084
 
919
- Usage:
920
- npx @splicr/mcp-server setup One-time setup: login + configure agents + hook
921
- npx @splicr/mcp-server login Re-authenticate with your Splicr account
922
- npx @splicr/mcp-server hook Context hook (used by Claude Code automatically)
923
- npx @splicr/mcp-server dashboard Open your knowledge dashboard in the browser
924
- npx @splicr/mcp-server uninstall Remove Splicr from all coding agents
925
- npx @splicr/mcp-server Start MCP server (used by coding agents)
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
926
1094
 
927
1095
  Supported agents (auto-detected):
928
1096
  Claude Code, Codex, Cursor, Cline, Antigravity
929
1097
 
930
1098
  Quick start:
931
- 1. Sign up at splicr.dev
932
- 2. Run: npx @splicr/mcp-server setup
933
- 3. Start saving articles from your phone or browser
934
- 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
935
1102
  `);
936
1103
  }
937
1104
  main().catch(err => {
938
1105
  console.error(`Error: ${err.message}`);
939
1106
  process.exit(1);
940
1107
  });
941
- //# sourceMappingURL=cli.js.map
package/dist/config.d.ts CHANGED
@@ -2,4 +2,3 @@ export interface SplicrConfig {
2
2
  apiServerUrl: string;
3
3
  }
4
4
  export declare function loadConfig(): SplicrConfig;
5
- //# sourceMappingURL=config.d.ts.map
package/dist/config.js CHANGED
@@ -23,4 +23,3 @@ export function loadConfig() {
23
23
  // Default — production API
24
24
  return { apiServerUrl: 'https://api-production-d889.up.railway.app' };
25
25
  }
26
- //# sourceMappingURL=config.js.map
package/dist/index.d.ts CHANGED
@@ -1,3 +1,2 @@
1
1
  #!/usr/bin/env node
2
2
  export {};
3
- //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -98,4 +98,3 @@ server.connect(transport).then(() => {
98
98
  console.error('[Splicr MCP] Failed to start:', err);
99
99
  process.exit(1);
100
100
  });
101
- //# sourceMappingURL=index.js.map
@@ -112,4 +112,3 @@ export declare function getRelevantContext(params: {
112
112
  search_strategy: string;
113
113
  }>;
114
114
  export { API_URL };
115
- //# sourceMappingURL=api-client.d.ts.map
@@ -95,4 +95,3 @@ export async function getRelevantContext(params) {
95
95
  return { results: data.results ?? [], search_strategy: data.search_strategy ?? '' };
96
96
  }
97
97
  export { API_URL };
98
- //# sourceMappingURL=api-client.js.map
@@ -9,4 +9,3 @@ export declare function trackSearchResults(resultIds: string[], query: string, s
9
9
  * Fire-and-forget — never blocks the content fetch.
10
10
  */
11
11
  export declare function checkAndLogFeedback(captureId: string): void;
12
- //# sourceMappingURL=feedback-tracker.d.ts.map
@@ -37,4 +37,3 @@ export function checkAndLogFeedback(captureId) {
37
37
  source_tool: lastSearchTool,
38
38
  }).catch(() => { });
39
39
  }
40
- //# sourceMappingURL=feedback-tracker.js.map
@@ -6,4 +6,3 @@ export interface HintContext {
6
6
  topResultTitle?: string;
7
7
  }
8
8
  export declare function generateHints(ctx: HintContext): string;
9
- //# sourceMappingURL=hint-engine.d.ts.map
@@ -18,4 +18,3 @@ export function generateHints(ctx) {
18
18
  return '';
19
19
  return '\n\n---\n*Hints:*\n' + hints.map(h => `- ${h}`).join('\n');
20
20
  }
21
- //# sourceMappingURL=hint-engine.js.map
@@ -18,4 +18,3 @@ export interface ProjectProfileData {
18
18
  * Every operation is individually try/caught — one failure never blocks the rest.
19
19
  */
20
20
  export declare function gatherProjectProfile(cwd: string): ProjectProfileData;
21
- //# sourceMappingURL=profile-gatherer.d.ts.map
@@ -144,4 +144,3 @@ function detectTechStack(cwd) {
144
144
  techStack.push('rust');
145
145
  return techStack;
146
146
  }
147
- //# sourceMappingURL=profile-gatherer.js.map
@@ -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
@@ -163,4 +163,3 @@ function detectTechStack(cwd) {
163
163
  techStack.push('rust');
164
164
  return techStack;
165
165
  }
166
- //# sourceMappingURL=project-detector.js.map
@@ -13,4 +13,3 @@ export declare function getStats(): {
13
13
  saves: number;
14
14
  contextServed: number;
15
15
  };
16
- //# sourceMappingURL=session-state.d.ts.map
@@ -42,4 +42,3 @@ export function getStats() {
42
42
  contextServed: contextServedIds.size,
43
43
  };
44
44
  }
45
- //# sourceMappingURL=session-state.js.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
@@ -123,4 +123,3 @@ function cleanError(error) {
123
123
  function dedupeStrings(arr) {
124
124
  return [...new Set(arr.map(s => s.trim()).filter(Boolean))];
125
125
  }
126
- //# sourceMappingURL=signal-fusion.js.map
@@ -13,4 +13,3 @@ export interface EnvironmentSignals {
13
13
  * Target: < 1 second total.
14
14
  */
15
15
  export declare function gatherSignals(cwd: string): EnvironmentSignals;
16
- //# sourceMappingURL=signal-gatherer.d.ts.map
@@ -90,4 +90,3 @@ function detectProjectName(cwd) {
90
90
  }
91
91
  return cwd.replace(/\\/g, '/').split('/').pop() || null;
92
92
  }
93
- //# sourceMappingURL=signal-gatherer.js.map
@@ -1,3 +1,2 @@
1
1
  #!/usr/bin/env node
2
2
  export {};
3
- //# sourceMappingURL=login-cli.d.ts.map
package/dist/login-cli.js CHANGED
@@ -4,4 +4,3 @@ login().catch(err => {
4
4
  console.error('Login error:', err.message);
5
5
  process.exit(1);
6
6
  });
7
- //# sourceMappingURL=login-cli.js.map
@@ -28,4 +28,3 @@ export declare const browseProjectSchema: {
28
28
  };
29
29
  };
30
30
  export declare function handleBrowseProject(args: Record<string, unknown>): Promise<string>;
31
- //# sourceMappingURL=browse-project.d.ts.map
@@ -115,4 +115,3 @@ function formatDate(iso) {
115
115
  return `${Math.floor(diffDays / 30)}mo ago`;
116
116
  return `${Math.floor(diffDays / 365)}y ago`;
117
117
  }
118
- //# sourceMappingURL=browse-project.js.map
@@ -13,4 +13,3 @@ export declare const getCompiledPageSchema: {
13
13
  };
14
14
  };
15
15
  export declare function handleGetCompiledPage(args: Record<string, unknown>): Promise<string>;
16
- //# sourceMappingURL=get-compiled-page.d.ts.map
@@ -44,4 +44,3 @@ function formatAge(iso) {
44
44
  return `${Math.floor(diffDays / 7)}w ago`;
45
45
  return `${Math.floor(diffDays / 30)}mo ago`;
46
46
  }
47
- //# sourceMappingURL=get-compiled-page.js.map