@wingmanjs/core 0.1.0

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/mcp.js ADDED
@@ -0,0 +1,241 @@
1
+ /**
2
+ * MCP Discovery — Auto-discovers MCP servers from multiple sources.
3
+ *
4
+ * Discovery chain (later overrides earlier):
5
+ * 1. Built-in defaults (Power BI remote)
6
+ * 2. User global config (~/.copilot/mcp-config.json)
7
+ * 3. Installed Copilot CLI plugins (~/.copilot/installed-plugins/)
8
+ * 4. Project-level overrides (./mcp.json)
9
+ * 5. User overrides from wingman.config.ts (highest priority)
10
+ */
11
+ import { readFile, readdir, stat } from 'node:fs/promises';
12
+ import { join } from 'node:path';
13
+ import { homedir } from 'node:os';
14
+ import { trace, SpanStatusCode, context } from '@opentelemetry/api';
15
+ const MCP_TRACER = 'wingman';
16
+ // ---------------------------------------------------------------------------
17
+ // Safe filesystem helpers
18
+ // ---------------------------------------------------------------------------
19
+ async function exists(path) {
20
+ try {
21
+ await stat(path);
22
+ return true;
23
+ }
24
+ catch {
25
+ return false;
26
+ }
27
+ }
28
+ async function readJson(path) {
29
+ try {
30
+ const content = await readFile(path, 'utf-8');
31
+ return JSON.parse(content);
32
+ }
33
+ catch {
34
+ return null;
35
+ }
36
+ }
37
+ // ---------------------------------------------------------------------------
38
+ // Discovery pipeline
39
+ // ---------------------------------------------------------------------------
40
+ /** Built-in default MCP servers. */
41
+ function getBuiltinDefaults() {
42
+ return {
43
+ 'powerbi-remote': {
44
+ type: 'http',
45
+ url: 'https://api.fabric.microsoft.com/v1/mcp/powerbi',
46
+ tools: ['*'],
47
+ },
48
+ };
49
+ }
50
+ /** Load servers from ~/.copilot/mcp-config.json */
51
+ async function loadGlobalConfig() {
52
+ const configPath = join(homedir(), '.copilot', 'mcp-config.json');
53
+ const config = await readJson(configPath);
54
+ return config?.mcpServers ?? {};
55
+ }
56
+ /** Scan installed plugins for MCP server configs. */
57
+ async function loadPluginServers() {
58
+ const servers = {};
59
+ const skills = [];
60
+ const diagnostics = [];
61
+ const pluginsBase = join(homedir(), '.copilot', 'installed-plugins');
62
+ if (!(await exists(pluginsBase))) {
63
+ return { servers, skills, diagnostics };
64
+ }
65
+ // Scan catalog directories (_direct, copilot-plugins, awesome-copilot)
66
+ const catalogs = await readdir(pluginsBase).catch(() => []);
67
+ for (const catalog of catalogs) {
68
+ const catalogPath = join(pluginsBase, catalog);
69
+ const catalogStat = await stat(catalogPath).catch(() => null);
70
+ if (!catalogStat?.isDirectory())
71
+ continue;
72
+ const plugins = await readdir(catalogPath).catch(() => []);
73
+ for (const plugin of plugins) {
74
+ try {
75
+ const pluginPath = join(catalogPath, plugin);
76
+ const pluginJsonPath = join(pluginPath, 'plugin.json');
77
+ const pluginJson = await readJson(pluginJsonPath);
78
+ if (!pluginJson)
79
+ continue;
80
+ // MCP servers — can be inline object or path to external JSON
81
+ if (pluginJson.mcpServers) {
82
+ let pluginServers = {};
83
+ if (typeof pluginJson.mcpServers === 'string') {
84
+ // External file reference
85
+ const externalPath = join(pluginPath, pluginJson.mcpServers);
86
+ const external = await readJson(externalPath);
87
+ if (external)
88
+ pluginServers = external;
89
+ }
90
+ else if (typeof pluginJson.mcpServers === 'object' && pluginJson.mcpServers !== null) {
91
+ pluginServers = pluginJson.mcpServers;
92
+ }
93
+ for (const [name, config] of Object.entries(pluginServers)) {
94
+ servers[name] = config;
95
+ diagnostics.push(` āœ… ${name} ← plugin (${catalog}/${plugin})`);
96
+ }
97
+ }
98
+ // Skills directory
99
+ if (pluginJson.skills) {
100
+ const skillsDir = join(pluginPath, pluginJson.skills);
101
+ if (await exists(skillsDir)) {
102
+ skills.push(skillsDir);
103
+ }
104
+ }
105
+ }
106
+ catch (err) {
107
+ diagnostics.push(` āš ļø ${catalog}/${plugin} — failed to load: ${err instanceof Error ? err.message : String(err)}`);
108
+ }
109
+ }
110
+ }
111
+ return { servers, skills, diagnostics };
112
+ }
113
+ /** Load project-level MCP config from ./mcp.json */
114
+ async function loadProjectConfig(projectRoot) {
115
+ const root = projectRoot ?? process.cwd();
116
+ const mcpJsonPath = join(root, 'mcp.json');
117
+ const config = await readJson(mcpJsonPath);
118
+ return config?.mcpServers ?? {};
119
+ }
120
+ async function runDiscoveryStage(tracer, parentCtx, spanName, fn) {
121
+ const span = tracer.startSpan(spanName, {}, parentCtx);
122
+ try {
123
+ await fn(span);
124
+ span.setStatus({ code: SpanStatusCode.OK });
125
+ }
126
+ catch (error) {
127
+ span.recordException(error);
128
+ span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });
129
+ throw error;
130
+ }
131
+ finally {
132
+ span.end();
133
+ }
134
+ }
135
+ // ---------------------------------------------------------------------------
136
+ // Public API
137
+ // ---------------------------------------------------------------------------
138
+ /**
139
+ * Discover all MCP servers from the 5-stage pipeline.
140
+ * User-provided overrides (from wingman.config.ts) are merged last.
141
+ */
142
+ export async function discoverMCPServers(userOverrides) {
143
+ const result = {};
144
+ // Stage 1: Built-in defaults
145
+ Object.assign(result, getBuiltinDefaults());
146
+ // Stage 2: Global config
147
+ Object.assign(result, await loadGlobalConfig());
148
+ // Stage 3: Plugins
149
+ const plugins = await loadPluginServers();
150
+ Object.assign(result, plugins.servers);
151
+ // Stage 4: Project config
152
+ Object.assign(result, await loadProjectConfig());
153
+ // Stage 5: User overrides from wingman.config.ts
154
+ if (userOverrides) {
155
+ Object.assign(result, userOverrides);
156
+ }
157
+ return result;
158
+ }
159
+ /**
160
+ * Discover servers with full diagnostics — returns source tracking
161
+ * and skill directories for logging and UI display.
162
+ */
163
+ export async function discoverWithDiagnostics(userOverrides, projectRoot) {
164
+ const tracer = trace.getTracer(MCP_TRACER);
165
+ const discoverySpan = tracer.startSpan('mcp.discovery', {
166
+ attributes: {
167
+ 'mcp.discovery.has_overrides': userOverrides != null && Object.keys(userOverrides).length > 0,
168
+ },
169
+ });
170
+ const ctx = trace.setSpan(context.active(), discoverySpan);
171
+ const servers = {};
172
+ const sources = new Map();
173
+ const diagnostics = ['šŸ”Œ MCP Servers Discovered:'];
174
+ const skillDirectories = [];
175
+ try {
176
+ // Stage 1: Built-in defaults
177
+ await runDiscoveryStage(tracer, ctx, 'mcp.discovery.stage1_builtins', async (stageSpan) => {
178
+ const builtins = getBuiltinDefaults();
179
+ for (const [name, config] of Object.entries(builtins)) {
180
+ servers[name] = config;
181
+ sources.set(name, 'built-in');
182
+ diagnostics.push(` āœ… ${name} ← built-in default`);
183
+ }
184
+ stageSpan.setAttribute('mcp.discovery.stage1.count', Object.keys(builtins).length);
185
+ });
186
+ // Stage 2: Global config
187
+ await runDiscoveryStage(tracer, ctx, 'mcp.discovery.stage2_global', async (stageSpan) => {
188
+ const globals = await loadGlobalConfig();
189
+ for (const [name, config] of Object.entries(globals)) {
190
+ servers[name] = config;
191
+ sources.set(name, 'global config');
192
+ diagnostics.push(` āœ… ${name} ← global config`);
193
+ }
194
+ stageSpan.setAttribute('mcp.discovery.stage2.count', Object.keys(globals).length);
195
+ });
196
+ // Stage 3: Plugins
197
+ await runDiscoveryStage(tracer, ctx, 'mcp.discovery.stage3_plugins', async (stageSpan) => {
198
+ const plugins = await loadPluginServers();
199
+ for (const [name, config] of Object.entries(plugins.servers)) {
200
+ servers[name] = config;
201
+ sources.set(name, 'plugin');
202
+ }
203
+ diagnostics.push(...plugins.diagnostics);
204
+ skillDirectories.push(...plugins.skills);
205
+ stageSpan.setAttribute('mcp.discovery.stage3.count', Object.keys(plugins.servers).length);
206
+ });
207
+ // Stage 4: Project config
208
+ await runDiscoveryStage(tracer, ctx, 'mcp.discovery.stage4_project', async (stageSpan) => {
209
+ const project = await loadProjectConfig(projectRoot);
210
+ for (const [name, config] of Object.entries(project)) {
211
+ servers[name] = config;
212
+ sources.set(name, 'project mcp.json');
213
+ diagnostics.push(` āœ… ${name} ← project mcp.json`);
214
+ }
215
+ stageSpan.setAttribute('mcp.discovery.stage4.count', Object.keys(project).length);
216
+ });
217
+ // Stage 5: User overrides
218
+ if (userOverrides && Object.keys(userOverrides).length > 0) {
219
+ await runDiscoveryStage(tracer, ctx, 'mcp.discovery.stage5_overrides', async (stageSpan) => {
220
+ for (const [name, config] of Object.entries(userOverrides)) {
221
+ servers[name] = config;
222
+ sources.set(name, 'wingman.config.ts');
223
+ diagnostics.push(` āœ… ${name} ← wingman.config.ts`);
224
+ }
225
+ stageSpan.setAttribute('mcp.discovery.stage5.count', Object.keys(userOverrides).length);
226
+ });
227
+ }
228
+ discoverySpan.setAttribute('mcp.discovery.total_servers', Object.keys(servers).length);
229
+ discoverySpan.setStatus({ code: SpanStatusCode.OK });
230
+ }
231
+ catch (error) {
232
+ discoverySpan.recordException(error);
233
+ discoverySpan.setStatus({ code: SpanStatusCode.ERROR, message: error.message });
234
+ throw error;
235
+ }
236
+ finally {
237
+ discoverySpan.end();
238
+ }
239
+ return { servers, sources, skillDirectories, diagnostics };
240
+ }
241
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Wingman Express Server — SSE streaming endpoint for the chat UI.
3
+ *
4
+ * Provides:
5
+ * - POST /api/chat — SSE streaming chat endpoint
6
+ * - GET /api/health — Health check
7
+ * - Static file serving for the React frontend
8
+ *
9
+ * SSE is the Phase 0 transport. Socket.IO upgrade happens in Phase 2.
10
+ */
11
+ import { WingmanClient } from './client.js';
12
+ import type { WingmanConfig } from './types.js';
13
+ import type { Application } from 'express';
14
+ import type { Server } from 'node:http';
15
+ export interface CreateServerOptions {
16
+ config?: WingmanConfig;
17
+ /** Absolute path to the built React frontend (dist/client). */
18
+ staticDir?: string;
19
+ }
20
+ export interface ServerInstance {
21
+ app: Application;
22
+ client: WingmanClient;
23
+ config: Required<WingmanConfig>;
24
+ }
25
+ export interface RunningServerInstance extends ServerInstance {
26
+ server: Server;
27
+ }
28
+ export declare function createServer(options?: CreateServerOptions): ServerInstance;
29
+ /** Start the server and listen on the configured port. */
30
+ export declare function startServer(options?: CreateServerOptions): Promise<RunningServerInstance>;
31
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAKhD,OAAO,KAAK,EAAE,WAAW,EAAqB,MAAM,SAAS,CAAC;AAC9D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAmBxC,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,+DAA+D;IAC/D,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,WAAW,CAAC;IACjB,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,EAAE,QAAQ,CAAC,aAAa,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,qBAAsB,SAAQ,cAAc;IAC3D,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,YAAY,CAAC,OAAO,GAAE,mBAAwB,GAAG,cAAc,CAyS9E;AAED,0DAA0D;AAC1D,wBAAsB,WAAW,CAAC,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAgCnG"}
package/dist/server.js ADDED
@@ -0,0 +1,317 @@
1
+ /**
2
+ * Wingman Express Server — SSE streaming endpoint for the chat UI.
3
+ *
4
+ * Provides:
5
+ * - POST /api/chat — SSE streaming chat endpoint
6
+ * - GET /api/health — Health check
7
+ * - Static file serving for the React frontend
8
+ *
9
+ * SSE is the Phase 0 transport. Socket.IO upgrade happens in Phase 2.
10
+ */
11
+ import express from 'express';
12
+ import { resolve } from 'node:path';
13
+ import { WingmanClient } from './client.js';
14
+ import { resolveConfig } from './config.js';
15
+ import { discoverWithDiagnostics } from './mcp.js';
16
+ import { initTelemetry, shutdownTelemetry } from './instrumentation.js';
17
+ // ---------------------------------------------------------------------------
18
+ // Validation helpers
19
+ // ---------------------------------------------------------------------------
20
+ const SESSION_ID_PATTERN = /^[a-zA-Z0-9_-]{1,128}$/;
21
+ function validateSessionId(req, res) {
22
+ const { sessionId } = req.params;
23
+ if (!SESSION_ID_PATTERN.test(sessionId)) {
24
+ res.status(400).json({ error: 'Invalid session ID format' });
25
+ return null;
26
+ }
27
+ return sessionId;
28
+ }
29
+ const MAX_MESSAGE_LENGTH = 100_000;
30
+ export function createServer(options = {}) {
31
+ const config = resolveConfig(options.config ?? {});
32
+ const client = new WingmanClient({ config });
33
+ const app = express();
34
+ app.use(express.json({ limit: '1mb' }));
35
+ // CORS
36
+ const corsOption = config.server.cors;
37
+ const corsEnabled = corsOption === true
38
+ || (typeof corsOption === 'string' && corsOption.length > 0)
39
+ || (Array.isArray(corsOption) && corsOption.length > 0);
40
+ if (corsEnabled) {
41
+ // Warn when wildcard CORS is used in production
42
+ if (corsOption === true && process.env.NODE_ENV === 'production') {
43
+ console.warn('[wingman] āš ļø CORS is set to allow all origins (*). ' +
44
+ 'This is unsafe in production. Set server.cors to a specific ' +
45
+ 'origin or list of origins, e.g. cors: "https://myapp.com"');
46
+ }
47
+ const allowedOrigins = typeof corsOption === 'string' ? new Set([corsOption])
48
+ : Array.isArray(corsOption) ? new Set(corsOption)
49
+ : null; // null ⇒ wildcard
50
+ app.use((req, res, next) => {
51
+ const origin = req.headers.origin;
52
+ if (allowedOrigins) {
53
+ if (origin && allowedOrigins.has(origin)) {
54
+ res.setHeader('Access-Control-Allow-Origin', origin);
55
+ res.vary('Origin');
56
+ }
57
+ }
58
+ else {
59
+ res.setHeader('Access-Control-Allow-Origin', '*');
60
+ }
61
+ res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
62
+ res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
63
+ if (req.method === 'OPTIONS') {
64
+ res.sendStatus(204);
65
+ return;
66
+ }
67
+ next();
68
+ });
69
+ }
70
+ // Health check
71
+ app.get('/api/health', (_req, res) => {
72
+ res.json({ status: 'ok', version: '0.1.0' });
73
+ });
74
+ // MCP discovery info
75
+ app.get('/api/mcp', async (_req, res) => {
76
+ try {
77
+ const discovery = await discoverWithDiagnostics(config.mcpServers);
78
+ res.json({
79
+ servers: Object.keys(discovery.servers),
80
+ sources: Object.fromEntries(discovery.sources),
81
+ diagnostics: discovery.diagnostics,
82
+ });
83
+ }
84
+ catch (err) {
85
+ res.status(500).json({ error: String(err) });
86
+ }
87
+ });
88
+ // UI config (for React frontend)
89
+ app.get('/api/config', (_req, res) => {
90
+ res.json(config.ui);
91
+ });
92
+ // -------------------------------------------------------------------------
93
+ // RPC routes — expose SDK controls for the UI
94
+ // -------------------------------------------------------------------------
95
+ // List available models
96
+ app.get('/api/models', async (_req, res) => {
97
+ try {
98
+ const models = await client.listModels();
99
+ res.json({ models });
100
+ }
101
+ catch (err) {
102
+ res.status(500).json({ error: String(err) });
103
+ }
104
+ });
105
+ // Switch model for a session
106
+ app.post('/api/session/:sessionId/model', async (req, res) => {
107
+ const sessionId = validateSessionId(req, res);
108
+ if (!sessionId)
109
+ return;
110
+ const { model } = req.body;
111
+ if (!model || typeof model !== 'string') {
112
+ res.status(400).json({ error: 'model is required' });
113
+ return;
114
+ }
115
+ try {
116
+ await client.switchModel(sessionId, model);
117
+ res.json({ ok: true, model });
118
+ }
119
+ catch (err) {
120
+ const msg = err instanceof Error ? err.message : String(err);
121
+ const status = msg.includes('No session found') ? 404 : 500;
122
+ res.status(status).json({ error: msg });
123
+ }
124
+ });
125
+ // Get current mode for a session
126
+ app.get('/api/session/:sessionId/mode', async (req, res) => {
127
+ const sessionId = validateSessionId(req, res);
128
+ if (!sessionId)
129
+ return;
130
+ try {
131
+ const mode = await client.getMode(sessionId);
132
+ res.json({ mode });
133
+ }
134
+ catch (err) {
135
+ const msg = err instanceof Error ? err.message : String(err);
136
+ const status = msg.includes('No session found') ? 404 : 500;
137
+ res.status(status).json({ error: msg });
138
+ }
139
+ });
140
+ // Set mode for a session
141
+ app.post('/api/session/:sessionId/mode', async (req, res) => {
142
+ const sessionId = validateSessionId(req, res);
143
+ if (!sessionId)
144
+ return;
145
+ const { mode } = req.body;
146
+ if (!mode || typeof mode !== 'string') {
147
+ res.status(400).json({ error: 'mode is required' });
148
+ return;
149
+ }
150
+ const allowedModes = ['interactive', 'plan', 'autopilot'];
151
+ if (!allowedModes.includes(mode)) {
152
+ res.status(400).json({ error: 'invalid mode', allowedModes });
153
+ return;
154
+ }
155
+ try {
156
+ await client.setMode(sessionId, mode);
157
+ res.json({ ok: true, mode });
158
+ }
159
+ catch (err) {
160
+ const msg = err instanceof Error ? err.message : String(err);
161
+ const status = msg.includes('No session found') ? 404 : 500;
162
+ res.status(status).json({ error: msg });
163
+ }
164
+ });
165
+ // Get account quota
166
+ app.get('/api/quota', async (_req, res) => {
167
+ try {
168
+ const quota = await client.getQuota();
169
+ res.json(quota ?? {});
170
+ }
171
+ catch (err) {
172
+ res.status(500).json({ error: String(err) });
173
+ }
174
+ });
175
+ // Chat SSE endpoint
176
+ app.post('/api/chat', async (req, res) => {
177
+ const { message, sessionId } = req.body;
178
+ // Input validation
179
+ if (!message || typeof message !== 'string' || message.trim().length === 0) {
180
+ res.status(400).json({ error: 'message is required' });
181
+ return;
182
+ }
183
+ if (message.length > MAX_MESSAGE_LENGTH) {
184
+ res.status(400).json({ error: `Message too long (max ${MAX_MESSAGE_LENGTH} characters)` });
185
+ return;
186
+ }
187
+ if (sessionId !== undefined && typeof sessionId !== 'string') {
188
+ res.status(400).json({ error: 'sessionId must be a string' });
189
+ return;
190
+ }
191
+ if (sessionId !== undefined && !SESSION_ID_PATTERN.test(sessionId)) {
192
+ res.status(400).json({ error: 'Invalid session ID format' });
193
+ return;
194
+ }
195
+ // SSE headers
196
+ res.setHeader('Content-Type', 'text/event-stream');
197
+ res.setHeader('Cache-Control', 'no-cache');
198
+ res.setHeader('Connection', 'keep-alive');
199
+ res.setHeader('X-Accel-Buffering', 'no');
200
+ res.flushHeaders();
201
+ // Disable Nagle's algorithm for immediate delivery
202
+ if (res.socket) {
203
+ res.socket.setNoDelay(true);
204
+ }
205
+ // SSE send helper
206
+ const send = (event, data) => {
207
+ if (closed)
208
+ return;
209
+ res.write(`event: ${event}\ndata: ${JSON.stringify(data)}\n\n`);
210
+ };
211
+ // Request timeout: must exceed SDK's 300s so SDK error fires first
212
+ const DEFAULT_TIMEOUT = 330_000;
213
+ const parsed = parseInt(process.env.REQUEST_TIMEOUT ?? '', 10);
214
+ const REQUEST_TIMEOUT = Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_TIMEOUT;
215
+ const timeout = setTimeout(() => {
216
+ if (!closed) {
217
+ send('error', { message: 'Request timeout exceeded' });
218
+ res.end();
219
+ }
220
+ }, REQUEST_TIMEOUT);
221
+ // Keepalive pings to prevent browser/proxy timeout
222
+ const keepalive = setInterval(() => {
223
+ if (!closed) {
224
+ res.write(`: keepalive\n\n`);
225
+ }
226
+ }, 5000);
227
+ // Track client disconnection — registered after timers to avoid TDZ
228
+ let closed = false;
229
+ res.on('close', () => {
230
+ closed = true;
231
+ clearInterval(keepalive);
232
+ clearTimeout(timeout);
233
+ });
234
+ // Send initial heartbeat
235
+ send('heartbeat', { status: 'connected' });
236
+ try {
237
+ const resultSessionId = await client.sendMessage(sessionId, message.trim(), {
238
+ onDelta: (content) => send('delta', { content }),
239
+ onReasoningDelta: (content, reasoningId) => send('reasoning_delta', { content, reasoningId }),
240
+ onReasoning: (content, reasoningId) => send('reasoning', { content, reasoningId }),
241
+ onUsage: (usage) => send('usage', usage),
242
+ onTurnStart: (turnId) => send('turn_start', { turnId }),
243
+ onTurnEnd: (turnId) => send('turn_end', { turnId }),
244
+ onIntent: (intent) => send('intent', { intent }),
245
+ onToolStart: (tool) => send('tool_start', tool),
246
+ onToolComplete: (toolCallId, toolName, result) => send('tool_complete', { toolCallId, toolName, result }),
247
+ onToolProgress: (toolCallId, message) => send('tool_progress', { toolCallId, message }),
248
+ onSkillInvoked: (name, pluginName) => send('skill_invoked', { name, pluginName }),
249
+ onSubagentStarted: (toolCallId, name, displayName) => send('subagent_started', { toolCallId, name, displayName }),
250
+ onSubagentCompleted: (toolCallId, name) => send('subagent_completed', { toolCallId, name }),
251
+ onSubagentFailed: (toolCallId, name, error) => send('subagent_failed', { toolCallId, name, error }),
252
+ onError: (message) => send('error', { message }),
253
+ onInfo: (infoType, message) => send('info', { infoType, message }),
254
+ onWarning: (warningType, message) => send('warning', { warningType, message }),
255
+ onModelChange: (model) => send('model_change', { model }),
256
+ onTitleChanged: (title) => send('title_changed', { title }),
257
+ onModeChanged: (mode) => send('mode_changed', { mode }),
258
+ onTruncation: (data) => send('truncation', data),
259
+ onCompactionStart: () => send('compaction_start', {}),
260
+ onCompactionComplete: () => send('compaction_complete', {}),
261
+ });
262
+ if (!closed) {
263
+ send('done', { sessionId: resultSessionId });
264
+ res.end();
265
+ }
266
+ }
267
+ catch (err) {
268
+ const errMsg = err instanceof Error ? err.message : String(err);
269
+ if (!closed) {
270
+ send('error', { message: errMsg });
271
+ res.end();
272
+ }
273
+ }
274
+ finally {
275
+ clearInterval(keepalive);
276
+ clearTimeout(timeout);
277
+ }
278
+ });
279
+ // Serve static React frontend if staticDir provided
280
+ if (options.staticDir) {
281
+ app.use(express.static(resolve(options.staticDir)));
282
+ // SPA fallback — serve index.html for all non-API routes
283
+ app.get('*', (_req, res) => {
284
+ res.sendFile(resolve(options.staticDir, 'index.html'));
285
+ });
286
+ }
287
+ return { app, client, config };
288
+ }
289
+ /** Start the server and listen on the configured port. */
290
+ export async function startServer(options = {}) {
291
+ // Initialize OTel before constructing app/client so the tracer provider
292
+ // is registered before any trace.getTracer() calls
293
+ const preConfig = resolveConfig(options.config ?? {});
294
+ await initTelemetry(preConfig.telemetry);
295
+ const { app, client, config } = createServer(options);
296
+ const port = config.server.port;
297
+ // Log MCP discovery
298
+ const discovery = await discoverWithDiagnostics(config.mcpServers);
299
+ for (const line of discovery.diagnostics) {
300
+ console.log(line);
301
+ }
302
+ const server = app.listen(port, () => {
303
+ console.log(`\n🦜 Wingman running at http://localhost:${port}\n`);
304
+ });
305
+ // Graceful shutdown
306
+ const shutdown = async () => {
307
+ console.log('\nShutting down...');
308
+ server.close();
309
+ await client.stop();
310
+ await shutdownTelemetry();
311
+ process.exit(0);
312
+ };
313
+ process.on('SIGINT', shutdown);
314
+ process.on('SIGTERM', shutdown);
315
+ return { server, app, client, config };
316
+ }
317
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}