@askmesh/mcp 0.11.0 → 0.11.1

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.
@@ -1,3 +1,4 @@
1
+ export declare const DEFAULT_PATTERNS: string[];
1
2
  export interface IgnoreMatcher {
2
3
  patterns: string[];
3
4
  shouldIgnore: (filePath: string) => boolean;
@@ -2,7 +2,7 @@ import { readFileSync, existsSync } from 'node:fs';
2
2
  import { join, basename } from 'node:path';
3
3
  // Default exclusions — applied even when no .askmeshignore file exists.
4
4
  // These are patterns that almost no project should ever share via the mesh.
5
- const DEFAULT_PATTERNS = [
5
+ export const DEFAULT_PATTERNS = [
6
6
  // Environment files
7
7
  '.env',
8
8
  '.env.*',
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.11.0',
14
+ version: '0.11.1',
15
15
  });
16
16
  if (!TOKEN) {
17
17
  // No token — start in setup-only mode
@@ -5,6 +5,7 @@ import { homedir } from 'os';
5
5
  import { createHash } from 'crypto';
6
6
  import { fileURLToPath } from 'url';
7
7
  import * as statusCache from '../statusline/cache.js';
8
+ import { DEFAULT_PATTERNS, loadIgnore } from '../agent/askmeshignore.js';
8
9
  export function registerAskMesh(server, client) {
9
10
  server.tool('askmesh', `AskMesh — ton réseau de communication entre développeurs et agents IA.
10
11
  Utilise cet outil pour envoyer et recevoir des messages, vérifier qui est connecté/online,
@@ -37,8 +38,9 @@ Actions disponibles :
37
38
  - "setup" : installer les slash commands (/ask-inbox, /ask-broadcast, etc.) et la status line dans le projet courant
38
39
  - "update" : vérifier les mises à jour du MCP, mettre à jour les skills et la status line
39
40
  - "loop-start" : marquer le loop comme actif (utilisé par /ask-loop)
40
- - "loop-stop" : arrêter le loop (utilisé par /ask-loop-stop)`, {
41
- action: z.enum(['ask', 'list', 'status', 'pending', 'inbox', 'answer', 'reply', 'thread', 'close', 'my-threads', 'board', 'progress', 'broadcast', 'context', 'setup', 'update', 'loop-start', 'loop-stop']).describe('Action à effectuer'),
41
+ - "loop-stop" : arrêter le loop (utilisé par /ask-loop-stop)
42
+ - "privacy" : afficher la politique .askmeshignore active (defaults + fichier projet)`, {
43
+ action: z.enum(['ask', 'list', 'status', 'pending', 'inbox', 'answer', 'reply', 'thread', 'close', 'my-threads', 'board', 'progress', 'broadcast', 'context', 'setup', 'update', 'loop-start', 'loop-stop', 'privacy']).describe('Action à effectuer'),
42
44
  username: z.string().optional().describe("Username de l'agent cible (pour ask/status)"),
43
45
  question: z.string().optional().describe('Question à poser (pour ask)'),
44
46
  requestId: z.number().optional().describe('ID de la requête (pour answer/reply/thread/close/progress)'),
@@ -246,6 +248,9 @@ Actions disponibles :
246
248
  statusCache.setLoopActive(false);
247
249
  return text('Loop arrêté.');
248
250
  }
251
+ case 'privacy': {
252
+ return showPrivacyPolicy();
253
+ }
249
254
  default:
250
255
  return text('Action inconnue.');
251
256
  }
@@ -277,7 +282,7 @@ Si l'utilisateur n'a pas encore de compte, dirige-le vers https://askmesh.dev po
277
282
  return text('Action inconnue.');
278
283
  });
279
284
  }
280
- const CURRENT_VERSION = '0.11.0';
285
+ const CURRENT_VERSION = '0.11.1';
281
286
  async function checkUpdateAndSetup() {
282
287
  const lines = [];
283
288
  lines.push(`Version actuelle : ${CURRENT_VERSION}`);
@@ -306,6 +311,55 @@ async function checkUpdateAndSetup() {
306
311
  lines.push(setupText);
307
312
  return text(lines.join('\n'));
308
313
  }
314
+ function showPrivacyPolicy() {
315
+ const cwd = process.cwd();
316
+ const filePath = join(cwd, '.askmeshignore');
317
+ const fileExists = existsSync(filePath);
318
+ let userPatterns = [];
319
+ if (fileExists) {
320
+ try {
321
+ const content = readFileSync(filePath, 'utf-8');
322
+ userPatterns = content
323
+ .split('\n')
324
+ .map((l) => l.trim())
325
+ .filter((l) => l && !l.startsWith('#'));
326
+ }
327
+ catch { }
328
+ }
329
+ const matcher = loadIgnore(cwd);
330
+ const lines = [];
331
+ lines.push('🔒 AskMesh Privacy Policy');
332
+ lines.push('');
333
+ lines.push('Your agent will NEVER read or share files matching these patterns.');
334
+ lines.push('');
335
+ lines.push(`📋 Default patterns (${DEFAULT_PATTERNS.length}, baked into the MCP):`);
336
+ for (const p of DEFAULT_PATTERNS) {
337
+ lines.push(` • ${p}`);
338
+ }
339
+ lines.push('');
340
+ if (fileExists) {
341
+ lines.push(`📁 .askmeshignore (${filePath}) — ${userPatterns.length} custom pattern(s):`);
342
+ if (userPatterns.length > 0) {
343
+ for (const p of userPatterns) {
344
+ lines.push(` • ${p}`);
345
+ }
346
+ }
347
+ else {
348
+ lines.push(' (no custom patterns yet — file is empty or only comments)');
349
+ }
350
+ }
351
+ else {
352
+ lines.push(`📁 .askmeshignore — not found in this project`);
353
+ lines.push(` Create it to add custom patterns:`);
354
+ lines.push(` echo "private-docs/" > ${filePath}`);
355
+ }
356
+ lines.push('');
357
+ lines.push(`🛡 Total active patterns: ${matcher.patterns.length}`);
358
+ lines.push('');
359
+ lines.push('🚫 Pre-send redaction filter is also active — replies containing API keys,');
360
+ lines.push(' JWTs, private keys, DB connection strings, etc. will be blocked automatically.');
361
+ return text(lines.join('\n'));
362
+ }
309
363
  function text(t) {
310
364
  return { content: [{ type: 'text', text: t }] };
311
365
  }
@@ -334,6 +388,7 @@ function setupSkillsAndStatusLine(token, pollInterval, url) {
334
388
  '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).`,
335
389
  'ask-loop.md': `Lance une boucle de vérification périodique des messages AskMesh.\n\nÉtapes :\n1. D'abord, utilise l'outil MCP askmesh avec l'action "loop-start" pour vérifier qu'aucun loop n'est déjà actif et marquer le loop comme actif\n2. Si le loop-start réussit, lance : /loop <intervalle ou 2m> /ask-inbox\n\nArguments optionnels : $ARGUMENTS (intervalle, ex: "2m", "5m", "30s")\nPar défaut : 2m\n\nSi un loop est déjà actif, préviens l'utilisateur et propose /ask-loop-stop.`,
336
390
  'ask-loop-stop.md': `Arrête la boucle de vérification périodique des messages AskMesh.\n\nÉtapes :\n1. Utilise l'outil MCP askmesh avec l'action "loop-stop" pour marquer le loop comme inactif\n2. Indique à l'utilisateur que le loop est arrêté\n\nNote : cela met à jour la status line pour retirer l'indicateur "loop".`,
391
+ 'ask-privacy.md': `Utilise l'outil MCP askmesh avec l'action "privacy" pour afficher la politique de confidentialité active du projet.\n\nCela montre :\n- Les patterns par défaut bakés dans le MCP (jamais lus ni partagés via le mesh)\n- Les patterns custom du fichier .askmeshignore du projet (s'il existe)\n- Le nombre total de patterns actifs\n- Un rappel que le filtre de redaction pré-envoi est actif\n\nC'est l'outil pour répondre aux questions du type "qu'est-ce qui peut sortir de mon projet via askmesh ?".`,
337
392
  };
338
393
  // Create commands directory
339
394
  try {
@@ -419,6 +474,32 @@ function setupSkillsAndStatusLine(token, pollInterval, url) {
419
474
  gitignoreStatus = '.gitignore : .env ajouté';
420
475
  }
421
476
  }
477
+ // Create a .askmeshignore template if it doesn't exist
478
+ const askmeshIgnorePath = join(cwd, '.askmeshignore');
479
+ let askmeshIgnoreStatus = '';
480
+ if (!existsSync(askmeshIgnorePath)) {
481
+ const template = `# AskMesh privacy policy
482
+ # Patterns listed here will NEVER be read or shared via the mesh.
483
+ #
484
+ # The MCP also has built-in defaults that are ALWAYS active, even
485
+ # without this file. Run /ask-privacy to see the full active policy.
486
+ #
487
+ # Built-in defaults include: .env, .env.*, secrets/, *.key, *.pem,
488
+ # id_rsa*, .aws/, .ssh/, service-account.json, node_modules/, .git/
489
+ #
490
+ # Use this file to add project-specific exclusions:
491
+
492
+ # private-docs/
493
+ # config/production.yml
494
+ # *.dump
495
+ # customers/
496
+ `;
497
+ writeFileSync(askmeshIgnorePath, template);
498
+ askmeshIgnoreStatus = '.askmeshignore template créé — édite-le pour ajouter tes patterns custom';
499
+ }
500
+ else {
501
+ askmeshIgnoreStatus = '.askmeshignore : présent (run /ask-privacy pour voir la policy active)';
502
+ }
422
503
  // Auto-configure status line — per-project, not global
423
504
  // Copy statusline.sh to ~/.claude/ (stable location), configure per-project with agent hash
424
505
  const mcpDir = dirname(fileURLToPath(import.meta.url));
@@ -486,6 +567,7 @@ function setupSkillsAndStatusLine(token, pollInterval, url) {
486
567
  lines.push(envStatus);
487
568
  if (gitignoreStatus)
488
569
  lines.push(gitignoreStatus);
570
+ lines.push(askmeshIgnoreStatus);
489
571
  lines.push(statusLineStatus);
490
572
  if (token) {
491
573
  lines.push('');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@askmesh/mcp",
3
- "version": "0.11.0",
3
+ "version": "0.11.1",
4
4
  "description": "AskMesh MCP server — connect your AI coding agent to your team's mesh network",
5
5
  "type": "module",
6
6
  "bin": {