@askmesh/mcp 0.10.2 → 0.10.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/README.md CHANGED
@@ -19,7 +19,7 @@ npx -y @askmesh/mcp
19
19
  "mcpServers": {
20
20
  "askmesh": {
21
21
  "command": "npx",
22
- "args": ["-y", "@askmesh/mcp"]
22
+ "args": ["-y", "@askmesh/mcp@latest"]
23
23
  }
24
24
  }
25
25
  }
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@ const TOKEN = process.env.ASKMESH_TOKEN;
11
11
  const URL = process.env.ASKMESH_URL || 'https://api.askmesh.dev';
12
12
  const server = new McpServer({
13
13
  name: 'askmesh',
14
- version: '0.10.2',
14
+ version: '0.10.4',
15
15
  });
16
16
  if (!TOKEN) {
17
17
  // No token — start in setup-only mode
@@ -33,8 +33,9 @@ Actions disponibles :
33
33
  - "progress" : marquer un thread comme "en cours de traitement"
34
34
  - "broadcast" : envoyer un message à toute ton équipe (notification Telegram/Slack, sans créer de thread)
35
35
  - "context" : partager ton contexte projet avec ton équipe
36
- - "setup" : installer les slash commands (/inbox, /broadcast, etc.) et la status line dans le projet courant`, {
37
- action: z.enum(['ask', 'list', 'status', 'pending', 'inbox', 'answer', 'reply', 'thread', 'close', 'my-threads', 'board', 'progress', 'broadcast', 'context', 'setup']).describe('Action à effectuer'),
36
+ - "setup" : installer les slash commands (/ask-inbox, /ask-broadcast, etc.) et la status line dans le projet courant
37
+ - "update" : vérifier les mises à jour du MCP, mettre à jour les skills et la status line`, {
38
+ action: z.enum(['ask', 'list', 'status', 'pending', 'inbox', 'answer', 'reply', 'thread', 'close', 'my-threads', 'board', 'progress', 'broadcast', 'context', 'setup', 'update']).describe('Action à effectuer'),
38
39
  username: z.string().optional().describe("Username de l'agent cible (pour ask/status)"),
39
40
  question: z.string().optional().describe('Question à poser (pour ask)'),
40
41
  requestId: z.number().optional().describe('ID de la requête (pour answer/reply/thread/close/progress)'),
@@ -212,35 +213,73 @@ Actions disponibles :
212
213
  case 'setup': {
213
214
  return setupSkillsAndStatusLine(token);
214
215
  }
216
+ case 'update': {
217
+ return await checkUpdateAndSetup();
218
+ }
215
219
  default:
216
- return text('Action inconnue. Actions disponibles : ask, list, status, pending, answer, context, setup');
220
+ return text('Action inconnue. Actions disponibles : ask, list, status, pending, answer, context, setup, update');
217
221
  }
218
222
  });
219
223
  }
220
224
  export function registerSetupOnly(server) {
221
- server.tool('askmesh', `AskMesh — première configuration requise.
222
- Aucun token trouvé. Utilise cet outil pour configurer AskMesh dans ce projet.
225
+ server.tool('askmesh', `AskMesh — réseau de communication entre développeurs et agents IA.
223
226
 
224
- Actions disponibles :
225
- - "setup" : configurer le projet (crée le .env, installe les slash commands, configure la status line)
227
+ ⚠️ CONFIGURATION REQUISE — Aucun token trouvé dans le .env.
228
+
229
+ IMPORTANT : Demande immédiatement à l'utilisateur son token AskMesh.
230
+ Le token est disponible sur https://askmesh.dev → Settings → copier l'API token.
226
231
 
227
- Pour commencer :
228
- 1. Inscris-toi sur https://askmesh.dev
229
- 2. Copie ton API token depuis Settings
230
- 3. Lance l'action "setup" avec ton token pour tout installer`, {
231
- action: z.enum(['setup']).describe('Action à effectuer'),
232
- token: z.string().optional().describe('Ton API token AskMesh (depuis askmesh.dev > Settings)'),
233
- }, async ({ action, token }) => {
232
+ Une fois le token obtenu, appelle cet outil avec action "setup" et le token en paramètre.
233
+ Cela va configurer automatiquement : le .env, les slash commands, et la status line.
234
+
235
+ Si l'utilisateur n'a pas encore de compte, dirige-le vers https://askmesh.dev pour s'inscrire.`, {
236
+ action: z.enum(['setup']).describe('Action à effectuer — toujours "setup" en mode configuration'),
237
+ token: z.string().optional().describe('API token AskMesh DEMANDER à l\'utilisateur si non fourni'),
238
+ pollInterval: z.number().optional().describe('Intervalle de polling en secondes (optionnel, pour agents serveur)'),
239
+ url: z.string().optional().describe('URL API AskMesh (optionnel, défaut: https://api.askmesh.dev)'),
240
+ }, async ({ action, token, pollInterval, url }) => {
234
241
  if (action === 'setup') {
235
- return setupSkillsAndStatusLine(token);
242
+ if (!token) {
243
+ return text(`Pour configurer AskMesh, j'ai besoin de ton token.\n\n1. Va sur https://askmesh.dev\n2. Connecte-toi ou crée un compte\n3. Va dans Settings → copie ton API token\n4. Donne-le moi et je configure tout automatiquement.\n\nSi tu as déjà un token, relance avec : action "setup", token "<ton_token>"`);
244
+ }
245
+ return setupSkillsAndStatusLine(token, pollInterval, url);
236
246
  }
237
247
  return text('Action inconnue.');
238
248
  });
239
249
  }
250
+ const CURRENT_VERSION = '0.10.4';
251
+ async function checkUpdateAndSetup() {
252
+ const lines = [];
253
+ lines.push(`Version actuelle : ${CURRENT_VERSION}`);
254
+ // Check latest version on npm
255
+ try {
256
+ const res = await fetch('https://registry.npmjs.org/@askmesh/mcp/latest');
257
+ const data = await res.json();
258
+ const latest = data.version;
259
+ lines.push(`Dernière version npm : ${latest}`);
260
+ if (latest !== CURRENT_VERSION) {
261
+ lines.push(`\n⚡ Mise à jour disponible ! ${CURRENT_VERSION} → ${latest}`);
262
+ lines.push(`Pour mettre à jour, relance Claude Code — npx avec @latest récupérera la nouvelle version.`);
263
+ lines.push(`Ou lance : npx clear-npx-cache && npx -y @askmesh/mcp@latest`);
264
+ }
265
+ else {
266
+ lines.push(`\n✓ Tu es à jour.`);
267
+ }
268
+ }
269
+ catch {
270
+ lines.push(`Impossible de vérifier la version npm.`);
271
+ }
272
+ // Re-run setup to update skills and status line
273
+ const setupResult = setupSkillsAndStatusLine();
274
+ const setupText = setupResult.content[0].text;
275
+ lines.push('\n---\n');
276
+ lines.push(setupText);
277
+ return text(lines.join('\n'));
278
+ }
240
279
  function text(t) {
241
280
  return { content: [{ type: 'text', text: t }] };
242
281
  }
243
- function setupSkillsAndStatusLine(token) {
282
+ function setupSkillsAndStatusLine(token, pollInterval, url) {
244
283
  const cwd = process.cwd();
245
284
  const commandsDir = join(cwd, '.claude', 'commands');
246
285
  const installed = [];
@@ -254,6 +293,7 @@ function setupSkillsAndStatusLine(token) {
254
293
  'ask-threads.md': `Utilise l'outil MCP askmesh avec l'action "my-threads" pour afficher toutes mes conversations actives.\n\nPrésente les threads regroupés par statut :\n- En attente (pending)\n- En cours (in_progress)\n- Actifs (active)\n\nIgnore les threads clos. Pour chaque thread, montre : l'ID, qui a posé la question, le sujet, et le nombre de réponses.`,
255
294
  'ask-status.md': `Utilise l'outil MCP askmesh avec l'action "list" pour voir qui est connecté sur le réseau.\n\nAffiche la liste des membres de l'équipe avec leur statut (online/offline) de manière claire et concise.`,
256
295
  'ask-setup.md': `Utilise l'outil MCP askmesh avec l'action "setup" pour installer ou mettre à jour la configuration AskMesh dans ce projet.\n\nCela va :\n- Créer ou vérifier le .env avec le token AskMesh\n- Installer les slash commands (/ask-inbox, /ask-broadcast, etc.)\n- Configurer la status line\n- Ajouter .env au .gitignore\n\nSi l'utilisateur fournit un token dans les arguments ($ARGUMENTS), passe-le en paramètre "token".`,
296
+ 'ask-update.md': `Utilise l'outil MCP askmesh avec l'action "update" pour vérifier les mises à jour et mettre à jour les skills et la status line.\n\nCela va :\n- Vérifier si une nouvelle version du MCP est disponible sur npm\n- Mettre à jour les slash commands\n- Mettre à jour le script de status line\n\nSi une mise à jour est disponible, indique à l'utilisateur comment l'installer (relancer Claude Code ou npx clear-npx-cache).`,
257
297
  };
258
298
  // Create commands directory
259
299
  try {
@@ -285,25 +325,36 @@ function setupSkillsAndStatusLine(token) {
285
325
  catch { }
286
326
  }
287
327
  }
288
- // Handle .env token
328
+ // Handle .env
289
329
  const envPath = join(cwd, '.env');
330
+ const apiUrl = url || 'https://api.askmesh.dev';
290
331
  let envStatus = '';
291
332
  if (token) {
333
+ // Build env content
334
+ const envLines = [];
335
+ envLines.push(`ASKMESH_TOKEN=${token}`);
336
+ envLines.push(`ASKMESH_URL=${apiUrl}`);
337
+ if (pollInterval && pollInterval > 0) {
338
+ envLines.push(`ASKMESH_POLL_INTERVAL=${pollInterval}`);
339
+ }
292
340
  if (existsSync(envPath)) {
293
- const content = readFileSync(envPath, 'utf-8');
294
- if (content.includes('ASKMESH_TOKEN')) {
295
- const updated = content.replace(/ASKMESH_TOKEN=.*/, `ASKMESH_TOKEN=${token}`);
296
- writeFileSync(envPath, updated);
297
- envStatus = '.env : ASKMESH_TOKEN mis à jour';
298
- }
299
- else {
300
- appendFileSync(envPath, `\nASKMESH_TOKEN=${token}\nASKMESH_URL=https://api.askmesh.dev\n`);
301
- envStatus = '.env : ASKMESH_TOKEN ajouté';
341
+ let content = readFileSync(envPath, 'utf-8');
342
+ // Update or append each var
343
+ for (const line of envLines) {
344
+ const key = line.split('=')[0];
345
+ if (content.includes(key + '=')) {
346
+ content = content.replace(new RegExp(`${key}=.*`), line);
347
+ }
348
+ else {
349
+ content = content.trimEnd() + '\n' + line;
350
+ }
302
351
  }
352
+ writeFileSync(envPath, content + '\n');
353
+ envStatus = '.env : configuration mise à jour';
303
354
  }
304
355
  else {
305
- writeFileSync(envPath, `ASKMESH_TOKEN=${token}\nASKMESH_URL=https://api.askmesh.dev\n`);
306
- envStatus = '.env créé avec le token';
356
+ writeFileSync(envPath, envLines.join('\n') + '\n');
357
+ envStatus = '.env créé avec la configuration';
307
358
  }
308
359
  }
309
360
  else if (existsSync(envPath)) {
@@ -312,12 +363,11 @@ function setupSkillsAndStatusLine(token) {
312
363
  envStatus = '.env : ASKMESH_TOKEN présent';
313
364
  }
314
365
  else {
315
- envStatus = '.env : ASKMESH_TOKEN absent — ajoute-le ou relance /ask-setup avec ton token';
366
+ envStatus = '.env : ASKMESH_TOKEN absent — relance /ask-setup avec ton token';
316
367
  }
317
368
  }
318
369
  else {
319
- writeFileSync(envPath, `ASKMESH_TOKEN=your_token_here\nASKMESH_URL=https://api.askmesh.dev\n`);
320
- envStatus = '.env créé — remplace your_token_here par ton token (depuis askmesh.dev > Settings)';
370
+ envStatus = '.env absent — relance /ask-setup avec ton token pour le créer';
321
371
  }
322
372
  // Check .gitignore includes .env
323
373
  const gitignorePath = join(cwd, '.gitignore');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@askmesh/mcp",
3
- "version": "0.10.2",
3
+ "version": "0.10.4",
4
4
  "description": "AskMesh MCP server — connect your AI coding agent to your team's mesh network",
5
5
  "type": "module",
6
6
  "bin": {
package/statusline.sh CHANGED
@@ -24,18 +24,18 @@ done
24
24
  parts=()
25
25
 
26
26
  if [ "$pending" -gt 0 ] 2>/dev/null; then
27
- parts+=("\033[33m${pending}↓\033[0m")
27
+ parts+=("\033[33m${pending} pending\033[0m")
28
28
  fi
29
29
  if [ "$active" -gt 0 ] 2>/dev/null; then
30
- parts+=("\033[32m${active}~\033[0m")
30
+ parts+=("\033[32m${active} active\033[0m")
31
31
  fi
32
32
  if [ "$replies" -gt 0 ] 2>/dev/null; then
33
- parts+=("\033[36m${replies}>\033[0m")
33
+ parts+=("\033[36m${replies} replies\033[0m")
34
34
  fi
35
35
 
36
36
  if [ ${#parts[@]} -gt 0 ]; then
37
- joined=$(IFS=' '; echo "${parts[*]}")
38
- echo -e "mesh $joined"
37
+ joined=$(IFS=' · '; echo "${parts[*]}")
38
+ echo -e "mesh > $joined"
39
39
  else
40
40
  echo "mesh"
41
41
  fi