@askmesh/mcp 0.7.0 → 0.7.2

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,4 +1,5 @@
1
1
  import { readLocalContext } from './context_reader.js';
2
+ import { sendDesktopNotification } from './notifier.js';
2
3
  const SYSTEM_PROMPT = `You are an AI coding agent responding on behalf of a developer through AskMesh.
3
4
  You have access to the developer's project context below.
4
5
  Use this context to answer accurately and concisely.
@@ -17,6 +18,8 @@ export class AutoResponder {
17
18
  }
18
19
  async handleRequest(request) {
19
20
  console.error(`[AskMesh] Question from @${request.fromUsername}: "${request.question}"`);
21
+ // Desktop notification
22
+ sendDesktopNotification(`AskMesh — @${request.fromUsername}`, request.question);
20
23
  // Mark thread as in_progress before processing
21
24
  try {
22
25
  await this.client.updateThreadStatus(request.id, 'in_progress');
@@ -62,11 +65,11 @@ export class AutoResponder {
62
65
  return;
63
66
  }
64
67
  }
65
- catch {
66
- console.error('[AskMesh] MCP sampling not available');
68
+ catch (err) {
69
+ console.error('[AskMesh] MCP sampling failed:', err instanceof Error ? err.message : err);
67
70
  }
68
71
  }
69
- // Strategy 2: Anthropic API fallback (optional — for standalone/server mode)
72
+ // Strategy 2: Anthropic API fallback (optional)
70
73
  const apiKey = process.env.ANTHROPIC_API_KEY;
71
74
  if (apiKey) {
72
75
  try {
@@ -82,8 +85,23 @@ export class AutoResponder {
82
85
  console.error('[AskMesh] Anthropic API failed:', err);
83
86
  }
84
87
  }
85
- // Strategy 3: Manual question stays pending
86
- console.error(`[AskMesh] Question #${request.id} queued use askmesh(action:"pending") to respond`);
88
+ // Strategy 3: Notify Claude Code and revert to pending
89
+ // Revert status so the message can be answered manually
90
+ try {
91
+ await this.client.updateThreadStatus(request.id, 'pending');
92
+ }
93
+ catch { }
94
+ // Send logging notification to Claude Code
95
+ if (this.mcpServer) {
96
+ try {
97
+ await this.mcpServer.sendLoggingMessage({
98
+ level: 'warning',
99
+ data: `📩 AskMesh — @${request.fromUsername} asks: "${request.question.slice(0, 200)}" → Use askmesh(action:"pending") to see and reply.`,
100
+ });
101
+ }
102
+ catch { }
103
+ }
104
+ console.error(`[AskMesh] Question #${request.id} from @${request.fromUsername} — auto-response failed, use askmesh(action:"pending") to respond`);
87
105
  }
88
106
  async callAnthropicAPI(apiKey, request, context) {
89
107
  const model = process.env.ANTHROPIC_MODEL || 'claude-sonnet-4-20250514';
@@ -0,0 +1 @@
1
+ export declare function sendDesktopNotification(title: string, message: string): void;
@@ -0,0 +1,26 @@
1
+ import { exec } from 'node:child_process';
2
+ const NOTIFY_DISABLED = process.env.ASKMESH_NOTIFY === 'false';
3
+ export function sendDesktopNotification(title, message) {
4
+ if (NOTIFY_DISABLED)
5
+ return;
6
+ const escaped = message.replace(/"/g, '\\"').replace(/'/g, "'").slice(0, 200);
7
+ const escapedTitle = title.replace(/"/g, '\\"');
8
+ let cmd = null;
9
+ switch (process.platform) {
10
+ case 'darwin':
11
+ cmd = `osascript -e 'display notification "${escaped}" with title "${escapedTitle}"'`;
12
+ break;
13
+ case 'linux':
14
+ cmd = `notify-send "${escapedTitle}" "${escaped}"`;
15
+ break;
16
+ case 'win32':
17
+ cmd = `powershell -Command "Add-Type -AssemblyName System.Windows.Forms; [System.Windows.Forms.MessageBox]::Show('${escaped}', '${escapedTitle}', 'OK', 'Information')"`;
18
+ break;
19
+ }
20
+ if (cmd) {
21
+ exec(cmd, (err) => {
22
+ if (err)
23
+ console.error('[AskMesh] Desktop notification failed:', err.message);
24
+ });
25
+ }
26
+ }
@@ -84,7 +84,7 @@ export declare class AskMeshClient {
84
84
  createdAt: string;
85
85
  }>;
86
86
  }>;
87
- updateThreadStatus(requestId: number, status: 'in_progress' | 'delegated'): Promise<{
87
+ updateThreadStatus(requestId: number, status: 'pending' | 'in_progress' | 'delegated'): Promise<{
88
88
  id: number;
89
89
  status: string;
90
90
  }>;
package/dist/index.js CHANGED
@@ -15,7 +15,7 @@ const client = new AskMeshClient(URL, TOKEN);
15
15
  const autoResponder = new AutoResponder(client);
16
16
  const server = new McpServer({
17
17
  name: 'askmesh',
18
- version: '0.3.0',
18
+ version: '0.7.0',
19
19
  });
20
20
  // Single unified tool
21
21
  registerAskMesh(server, client);
@@ -1,4 +1,5 @@
1
1
  import EventSource from 'eventsource';
2
+ import { sendDesktopNotification } from '../agent/notifier.js';
2
3
  export class SseListener {
3
4
  es = null;
4
5
  reconnectTimer = null;
@@ -50,6 +51,7 @@ export class SseListener {
50
51
  const payload = JSON.parse(e.data);
51
52
  this.onReply?.(payload);
52
53
  console.error(`[AskMesh] Reply added to thread #${payload.requestId} by @${payload.reply.agentUsername}`);
54
+ sendDesktopNotification(`AskMesh — @${payload.reply.agentUsername}`, `Reply on #${payload.requestId}: ${payload.reply.message}`);
53
55
  }
54
56
  catch { }
55
57
  }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@askmesh/mcp",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "description": "AskMesh MCP server — connect your AI coding agent to your team's mesh network",
5
5
  "type": "module",
6
6
  "bin": {