@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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Eric Hansen
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,55 @@
1
+ /**
2
+ * WingmanClient — Core wrapper around the GitHub Copilot SDK's CopilotClient.
3
+ *
4
+ * Manages the CopilotClient singleton lifecycle, creates and resumes sessions,
5
+ * and orchestrates MCP discovery, tools, and event routing.
6
+ */
7
+ import type { WingmanConfig, AgentMode } from './types.js';
8
+ import { type EventCallbacks } from './events.js';
9
+ export interface SendMessageOptions extends Partial<EventCallbacks> {
10
+ /** Timeout in milliseconds for sendAndWait. Default: 300_000 (5 min). */
11
+ timeout?: number;
12
+ }
13
+ export interface WingmanClientOptions {
14
+ config?: WingmanConfig;
15
+ }
16
+ export declare class WingmanClient {
17
+ private client;
18
+ private config;
19
+ private telemetry;
20
+ constructor(options?: WingmanClientOptions);
21
+ /** Lazily initialize the CopilotClient singleton. */
22
+ private getClient;
23
+ /**
24
+ * Create or resume a session. If a sessionId is provided and a cached
25
+ * session exists, reuses it to prevent listener duplication.
26
+ */
27
+ getSession(sessionId?: string): Promise<import("@github/copilot-sdk").CopilotSession>;
28
+ /**
29
+ * Send a message and stream events to the provided callbacks.
30
+ * Handles the full lifecycle: listener setup, sendAndWait, cleanup.
31
+ */
32
+ sendMessage(sessionId: string | undefined, message: string, callbacks?: SendMessageOptions): Promise<string>;
33
+ /** Extract session ID from a session object. */
34
+ private getSessionId;
35
+ /** Build MCP server configs from discovery + user config. */
36
+ private buildMCPServers;
37
+ /** Gracefully shut down the client. */
38
+ stop(): Promise<void>;
39
+ /** Get the resolved configuration. */
40
+ getConfig(): Required<WingmanConfig>;
41
+ /** List available models from the SDK. */
42
+ listModels(): Promise<Array<{
43
+ id: string;
44
+ name: string;
45
+ }>>;
46
+ /** Switch the model for an active session. */
47
+ switchModel(sessionId: string, modelId: string): Promise<void>;
48
+ /** Get the current agent mode for a session. */
49
+ getMode(sessionId: string): Promise<string>;
50
+ /** Set the agent mode for a session. */
51
+ setMode(sessionId: string, mode: AgentMode): Promise<void>;
52
+ /** Get account quota information. */
53
+ getQuota(): Promise<Record<string, unknown> | null>;
54
+ }
55
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAG3D,OAAO,EAAe,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAmB/D,MAAM,WAAW,kBAAmB,SAAQ,OAAO,CAAC,cAAc,CAAC;IACjE,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAA8B;IAC5C,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,SAAS,CAAkC;gBAEvC,OAAO,GAAE,oBAAyB;IAK9C,qDAAqD;IACrD,OAAO,CAAC,SAAS;IAOjB;;;OAGG;IACG,UAAU,CAAC,SAAS,CAAC,EAAE,MAAM;IAwCnC;;;OAGG;IACG,WAAW,CACf,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,kBAAuB;IA+CpC,gDAAgD;IAEhD,OAAO,CAAC,YAAY;IAIpB,6DAA6D;YAC/C,eAAe;IAI7B,uCAAuC;IACjC,IAAI;IAQV,sCAAsC;IACtC,SAAS,IAAI,QAAQ,CAAC,aAAa,CAAC;IAQpC,0CAA0C;IACpC,UAAU,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAShE,8CAA8C;IACxC,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKpE,gDAAgD;IAC1C,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAMjD,wCAAwC;IAClC,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAKhE,qCAAqC;IAC/B,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAM1D"}
package/dist/client.js ADDED
@@ -0,0 +1,227 @@
1
+ /**
2
+ * WingmanClient — Core wrapper around the GitHub Copilot SDK's CopilotClient.
3
+ *
4
+ * Manages the CopilotClient singleton lifecycle, creates and resumes sessions,
5
+ * and orchestrates MCP discovery, tools, and event routing.
6
+ */
7
+ import { CopilotClient, approveAll } from '@github/copilot-sdk';
8
+ import { resolveConfig } from './config.js';
9
+ import { discoverMCPServers } from './mcp.js';
10
+ import { EventRouter } from './events.js';
11
+ import { createTracer } from './telemetry.js';
12
+ // ---------------------------------------------------------------------------
13
+ // Session cache — prevents duplicate events on resume
14
+ // ---------------------------------------------------------------------------
15
+ /**
16
+ * The SDK's `resumeSession()` creates a new CopilotSession object that shares
17
+ * the same backend session. Both objects receive events from the same JSON-RPC
18
+ * connection, so listeners accumulate and events fire twice.
19
+ *
20
+ * Workaround: cache the original session object by ID and reuse it.
21
+ */
22
+ const sessionCache = new Map();
23
+ export class WingmanClient {
24
+ client = null;
25
+ config;
26
+ telemetry;
27
+ constructor(options = {}) {
28
+ this.config = resolveConfig(options.config ?? {});
29
+ this.telemetry = createTracer(this.config.telemetry);
30
+ }
31
+ /** Lazily initialize the CopilotClient singleton. */
32
+ getClient() {
33
+ if (!this.client) {
34
+ this.client = new CopilotClient();
35
+ }
36
+ return this.client;
37
+ }
38
+ /**
39
+ * Create or resume a session. If a sessionId is provided and a cached
40
+ * session exists, reuses it to prevent listener duplication.
41
+ */
42
+ async getSession(sessionId) {
43
+ const client = this.getClient();
44
+ // Resume from cache if possible
45
+ if (sessionId && sessionCache.has(sessionId)) {
46
+ const cached = sessionCache.get(sessionId);
47
+ // Clean up previous listener before attaching a new one
48
+ if (cached.unsubscribe) {
49
+ cached.unsubscribe();
50
+ cached.unsubscribe = null;
51
+ }
52
+ return cached.session;
53
+ }
54
+ // Build MCP server configurations
55
+ const mcpServers = await this.buildMCPServers();
56
+ const sessionConfig = {
57
+ model: this.config.model,
58
+ streaming: true,
59
+ systemMessage: { content: this.config.systemPrompt },
60
+ mcpServers,
61
+ skillDirectories: this.config.skillDirectories,
62
+ onPermissionRequest: approveAll,
63
+ };
64
+ let session;
65
+ if (sessionId) {
66
+ session = await client.resumeSession(sessionId, sessionConfig);
67
+ }
68
+ else {
69
+ session = await client.createSession(sessionConfig);
70
+ }
71
+ // Cache the session
72
+ const sid = this.getSessionId(session);
73
+ sessionCache.set(sid, { session, unsubscribe: null });
74
+ return session;
75
+ }
76
+ /**
77
+ * Send a message and stream events to the provided callbacks.
78
+ * Handles the full lifecycle: listener setup, sendAndWait, cleanup.
79
+ */
80
+ async sendMessage(sessionId, message, callbacks = {}) {
81
+ const session = await this.getSession(sessionId);
82
+ const sid = this.getSessionId(session);
83
+ const cached = sessionCache.get(sid);
84
+ // Clean up any previous listener
85
+ if (cached?.unsubscribe) {
86
+ cached.unsubscribe();
87
+ cached.unsubscribe = null;
88
+ }
89
+ // Create telemetry callbacks for this turn
90
+ const telemetryCallbacks = this.telemetry.createCallbacks(sid, this.config.model);
91
+ // Compose user callbacks with telemetry callbacks
92
+ const composedCallbacks = composeCallbacks(callbacks, telemetryCallbacks);
93
+ // Wire up event router with composed callbacks
94
+ const router = new EventRouter(composedCallbacks);
95
+ const unsubscribe = session.on((event) => {
96
+ router.route(event);
97
+ });
98
+ // Track this specific unsubscribe by reference so the finally block
99
+ // only cleans up its own listener, not a concurrent turn's listener.
100
+ const myUnsubscribe = unsubscribe;
101
+ if (cached) {
102
+ cached.unsubscribe = unsubscribe;
103
+ }
104
+ const timeout = callbacks.timeout ?? 300_000;
105
+ try {
106
+ await session.sendAndWait({ prompt: message }, timeout);
107
+ }
108
+ finally {
109
+ // Only unsubscribe our own listener — if a concurrent turn replaced
110
+ // cached.unsubscribe, we must not null it out.
111
+ myUnsubscribe();
112
+ if (cached && cached.unsubscribe === myUnsubscribe) {
113
+ cached.unsubscribe = null;
114
+ }
115
+ }
116
+ return sid;
117
+ }
118
+ /** Extract session ID from a session object. */
119
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
120
+ getSessionId(session) {
121
+ return session.sessionId ?? session.id ?? 'unknown';
122
+ }
123
+ /** Build MCP server configs from discovery + user config. */
124
+ async buildMCPServers() {
125
+ return discoverMCPServers(this.config.mcpServers);
126
+ }
127
+ /** Gracefully shut down the client. */
128
+ async stop() {
129
+ if (this.client) {
130
+ await this.client.stop();
131
+ this.client = null;
132
+ }
133
+ sessionCache.clear();
134
+ }
135
+ /** Get the resolved configuration. */
136
+ getConfig() {
137
+ return this.config;
138
+ }
139
+ // -------------------------------------------------------------------------
140
+ // RPC methods — expose SDK RPC surface for UI controls
141
+ // -------------------------------------------------------------------------
142
+ /** List available models from the SDK. */
143
+ async listModels() {
144
+ const client = this.getClient();
145
+ const result = await client.rpc.models.list();
146
+ return result.models.map((m) => ({
147
+ id: m.id,
148
+ name: m.id,
149
+ }));
150
+ }
151
+ /** Switch the model for an active session. */
152
+ async switchModel(sessionId, modelId) {
153
+ const session = await this.getSession(sessionId);
154
+ await session.rpc.model.switchTo({ modelId });
155
+ }
156
+ /** Get the current agent mode for a session. */
157
+ async getMode(sessionId) {
158
+ const session = await this.getSession(sessionId);
159
+ const result = await session.rpc.mode.get();
160
+ return result.mode;
161
+ }
162
+ /** Set the agent mode for a session. */
163
+ async setMode(sessionId, mode) {
164
+ const session = await this.getSession(sessionId);
165
+ await session.rpc.mode.set({ mode });
166
+ }
167
+ /** Get account quota information. */
168
+ async getQuota() {
169
+ const client = this.getClient();
170
+ const result = await client.rpc.account.getQuota();
171
+ const quotaSnapshots = result?.quotaSnapshots;
172
+ return quotaSnapshots != null ? quotaSnapshots : null;
173
+ }
174
+ }
175
+ // ---------------------------------------------------------------------------
176
+ // Callback composition — merges user + telemetry callbacks
177
+ // ---------------------------------------------------------------------------
178
+ /**
179
+ * Compose two sets of EventCallbacks so both fire for each event.
180
+ * Primary (user) callbacks fire first, then secondary (telemetry).
181
+ * Telemetry callbacks are wrapped in try/catch — they must never
182
+ * break user-facing streaming.
183
+ */
184
+ function composeCallbacks(primary, secondary) {
185
+ const composed = {};
186
+ const allKeys = new Set([
187
+ ...Object.keys(primary),
188
+ ...Object.keys(secondary),
189
+ ]);
190
+ for (const key of allKeys) {
191
+ const primaryValue = primary[key];
192
+ const secondaryValue = secondary[key];
193
+ const pFn = typeof primaryValue === 'function'
194
+ ? primaryValue
195
+ : undefined;
196
+ const sFn = typeof secondaryValue === 'function'
197
+ ? secondaryValue
198
+ : undefined;
199
+ if (pFn && sFn) {
200
+ composed[key] = (...args) => {
201
+ pFn(...args);
202
+ try {
203
+ sFn(...args);
204
+ }
205
+ catch (err) {
206
+ console.debug('Telemetry callback error:', key, err);
207
+ }
208
+ };
209
+ }
210
+ else if (pFn) {
211
+ composed[key] = pFn;
212
+ }
213
+ else if (sFn) {
214
+ const wrappedSFn = sFn;
215
+ composed[key] = (...args) => {
216
+ try {
217
+ wrappedSFn(...args);
218
+ }
219
+ catch (err) {
220
+ console.debug('Telemetry callback error:', key, err);
221
+ }
222
+ };
223
+ }
224
+ }
225
+ return composed;
226
+ }
227
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,aAAa,EAAE,UAAU,EAAiE,MAAM,qBAAqB,CAAC;AAE/H,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAuB,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,8EAA8E;AAC9E,sDAAsD;AACtD,8EAA8E;AAE9E;;;;;;GAMG;AACH,MAAM,YAAY,GAAG,IAAI,GAAG,EAGxB,CAAC;AAWL,MAAM,OAAO,aAAa;IAChB,MAAM,GAAyB,IAAI,CAAC;IACpC,MAAM,CAA0B;IAChC,SAAS,CAAkC;IAEnD,YAAY,UAAgC,EAAE;QAC5C,IAAI,CAAC,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;QAClD,IAAI,CAAC,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACvD,CAAC;IAED,qDAAqD;IAC7C,SAAS;QACf,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,IAAI,CAAC,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;QACpC,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,UAAU,CAAC,SAAkB;QACjC,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QAEhC,gCAAgC;QAChC,IAAI,SAAS,IAAI,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7C,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,SAAS,CAAE,CAAC;YAC5C,wDAAwD;YACxD,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;gBACvB,MAAM,CAAC,WAAW,EAAE,CAAC;gBACrB,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC;YAC5B,CAAC;YACD,OAAO,MAAM,CAAC,OAAO,CAAC;QACxB,CAAC;QAED,kCAAkC;QAClC,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,eAAe,EAAmD,CAAC;QAEjG,MAAM,aAAa,GAAG;YACpB,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK;YACxB,SAAS,EAAE,IAAI;YACf,aAAa,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE;YACpD,UAAU;YACV,gBAAgB,EAAE,IAAI,CAAC,MAAM,CAAC,gBAAgB;YAC9C,mBAAmB,EAAE,UAAU;SAChC,CAAC;QAEF,IAAI,OAAO,CAAC;QACZ,IAAI,SAAS,EAAE,CAAC;YACd,OAAO,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;QACjE,CAAC;aAAM,CAAC;YACN,OAAO,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;QACtD,CAAC;QAED,oBAAoB;QACpB,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QACvC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;QAEtD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,WAAW,CACf,SAA6B,EAC7B,OAAe,EACf,YAAgC,EAAE;QAElC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QACjD,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QACvC,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAErC,iCAAiC;QACjC,IAAI,MAAM,EAAE,WAAW,EAAE,CAAC;YACxB,MAAM,CAAC,WAAW,EAAE,CAAC;YACrB,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC;QAC5B,CAAC;QAED,2CAA2C;QAC3C,MAAM,kBAAkB,GAAG,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAElF,kDAAkD;QAClD,MAAM,iBAAiB,GAAG,gBAAgB,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC;QAE1E,+CAA+C;QAC/C,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,iBAAiB,CAAC,CAAC;QAClD,MAAM,WAAW,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC,KAAmB,EAAE,EAAE;YACrD,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC,CAAC,CAAC;QAEH,oEAAoE;QACpE,qEAAqE;QACrE,MAAM,aAAa,GAAG,WAAW,CAAC;QAClC,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,CAAC,WAAW,GAAG,WAAW,CAAC;QACnC,CAAC;QAED,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,IAAI,OAAO,CAAC;QAE7C,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC;QAC1D,CAAC;gBAAS,CAAC;YACT,oEAAoE;YACpE,+CAA+C;YAC/C,aAAa,EAAE,CAAC;YAChB,IAAI,MAAM,IAAI,MAAM,CAAC,WAAW,KAAK,aAAa,EAAE,CAAC;gBACnD,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC;YAC5B,CAAC;QACH,CAAC;QAED,OAAO,GAAG,CAAC;IACb,CAAC;IAED,gDAAgD;IAChD,8DAA8D;IACtD,YAAY,CAAC,OAAY;QAC/B,OAAO,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,EAAE,IAAI,SAAS,CAAC;IACtD,CAAC;IAED,6DAA6D;IACrD,KAAK,CAAC,eAAe;QAC3B,OAAO,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IACpD,CAAC;IAED,uCAAuC;IACvC,KAAK,CAAC,IAAI;QACR,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACrB,CAAC;QACD,YAAY,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IAED,sCAAsC;IACtC,SAAS;QACP,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,4EAA4E;IAC5E,uDAAuD;IACvD,4EAA4E;IAE5E,0CAA0C;IAC1C,KAAK,CAAC,UAAU;QACd,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QAC9C,OAAO,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC/B,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,IAAI,EAAE,CAAC,CAAC,EAAE;SACX,CAAC,CAAC,CAAC;IACN,CAAC;IAED,8CAA8C;IAC9C,KAAK,CAAC,WAAW,CAAC,SAAiB,EAAE,OAAe;QAClD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QACjD,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;IAChD,CAAC;IAED,gDAAgD;IAChD,KAAK,CAAC,OAAO,CAAC,SAAiB;QAC7B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QAC5C,OAAO,MAAM,CAAC,IAAI,CAAC;IACrB,CAAC;IAED,wCAAwC;IACxC,KAAK,CAAC,OAAO,CAAC,SAAiB,EAAE,IAAe;QAC9C,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QACjD,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;IACvC,CAAC;IAED,qCAAqC;IACrC,KAAK,CAAC,QAAQ;QACZ,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;QACnD,MAAM,cAAc,GAAG,MAAM,EAAE,cAAc,CAAC;QAC9C,OAAO,cAAc,IAAI,IAAI,CAAC,CAAC,CAAE,cAAqD,CAAC,CAAC,CAAC,IAAI,CAAC;IAChG,CAAC;CACF;AAED,8EAA8E;AAC9E,2DAA2D;AAC3D,8EAA8E;AAE9E;;;;;GAKG;AACH,SAAS,gBAAgB,CACvB,OAAgC,EAChC,SAAkC;IAElC,MAAM,QAAQ,GAAiD,EAAE,CAAC;IAElE,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC;QACtB,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;QACvB,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC;KAC1B,CAAC,CAAC;IAEH,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,MAAM,YAAY,GAAI,OAAmC,CAAC,GAAG,CAAC,CAAC;QAC/D,MAAM,cAAc,GAAI,SAAqC,CAAC,GAAG,CAAC,CAAC;QAEnE,MAAM,GAAG,GAAG,OAAO,YAAY,KAAK,UAAU;YAC5C,CAAC,CAAE,YAA6C;YAChD,CAAC,CAAC,SAAS,CAAC;QACd,MAAM,GAAG,GAAG,OAAO,cAAc,KAAK,UAAU;YAC9C,CAAC,CAAE,cAA+C;YAClD,CAAC,CAAC,SAAS,CAAC;QAEd,IAAI,GAAG,IAAI,GAAG,EAAE,CAAC;YACf,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAe,EAAE,EAAE;gBACrC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;gBACb,IAAI,CAAC;oBACH,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;gBACf,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;gBACvD,CAAC;YACH,CAAC,CAAC;QACJ,CAAC;aAAM,IAAI,GAAG,EAAE,CAAC;YACf,QAAQ,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;QACtB,CAAC;aAAM,IAAI,GAAG,EAAE,CAAC;YACf,MAAM,UAAU,GAAG,GAAG,CAAC;YACvB,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAe,EAAE,EAAE;gBACrC,IAAI,CAAC;oBACH,UAAU,CAAC,GAAG,IAAI,CAAC,CAAC;gBACtB,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;gBACvD,CAAC;YACH,CAAC,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,QAAqC,CAAC;AAC/C,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Wingman configuration loader.
3
+ *
4
+ * Provides `defineConfig()` for type-safe configuration and `resolveConfig()`
5
+ * to deep-merge user config with defaults.
6
+ */
7
+ import type { WingmanConfig } from './types.js';
8
+ /** Type-safe config helper — provides autocomplete and validation. */
9
+ export declare function defineConfig(config: WingmanConfig): WingmanConfig;
10
+ /** Default configuration values. */
11
+ export declare const DEFAULT_CONFIG: Required<WingmanConfig>;
12
+ /** Deep-merge user config with defaults. */
13
+ export declare function resolveConfig(userConfig: WingmanConfig): Required<WingmanConfig>;
14
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,sEAAsE;AACtE,wBAAgB,YAAY,CAAC,MAAM,EAAE,aAAa,GAAG,aAAa,CAEjE;AAED,oCAAoC;AACpC,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,aAAa,CAgClD,CAAC;AAEF,4CAA4C;AAC5C,wBAAgB,aAAa,CAAC,UAAU,EAAE,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC,CAQhF"}
package/dist/config.js ADDED
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Wingman configuration loader.
3
+ *
4
+ * Provides `defineConfig()` for type-safe configuration and `resolveConfig()`
5
+ * to deep-merge user config with defaults.
6
+ */
7
+ /** Type-safe config helper — provides autocomplete and validation. */
8
+ export function defineConfig(config) {
9
+ return config;
10
+ }
11
+ /** Default configuration values. */
12
+ export const DEFAULT_CONFIG = {
13
+ systemPrompt: 'You are a helpful assistant.',
14
+ model: 'claude-sonnet-4',
15
+ reasoningEffort: 'medium',
16
+ mcpServers: {},
17
+ skillDirectories: [],
18
+ customAgents: [],
19
+ tools: [],
20
+ ui: {
21
+ title: 'Wingman',
22
+ theme: 'system',
23
+ logo: undefined,
24
+ welcomeMessage: 'How can I help?',
25
+ suggestions: [],
26
+ colors: {},
27
+ showTokenUsage: true,
28
+ showModelPicker: true,
29
+ showModeSwitcher: true,
30
+ showDebugPanel: false,
31
+ },
32
+ server: {
33
+ port: 3000,
34
+ cors: true,
35
+ transport: 'sse',
36
+ },
37
+ telemetry: {
38
+ enabled: false,
39
+ exporter: 'console',
40
+ endpoint: undefined,
41
+ serviceName: 'wingman',
42
+ captureContent: false,
43
+ },
44
+ };
45
+ /** Deep-merge user config with defaults. */
46
+ export function resolveConfig(userConfig) {
47
+ return {
48
+ ...DEFAULT_CONFIG,
49
+ ...userConfig,
50
+ ui: { ...DEFAULT_CONFIG.ui, ...userConfig.ui },
51
+ server: { ...DEFAULT_CONFIG.server, ...userConfig.server },
52
+ telemetry: { ...DEFAULT_CONFIG.telemetry, ...userConfig.telemetry },
53
+ };
54
+ }
55
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,sEAAsE;AACtE,MAAM,UAAU,YAAY,CAAC,MAAqB;IAChD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,oCAAoC;AACpC,MAAM,CAAC,MAAM,cAAc,GAA4B;IACrD,YAAY,EAAE,8BAA8B;IAC5C,KAAK,EAAE,iBAAiB;IACxB,eAAe,EAAE,QAAQ;IACzB,UAAU,EAAE,EAAE;IACd,gBAAgB,EAAE,EAAE;IACpB,YAAY,EAAE,EAAE;IAChB,KAAK,EAAE,EAAE;IACT,EAAE,EAAE;QACF,KAAK,EAAE,SAAS;QAChB,KAAK,EAAE,QAAQ;QACf,IAAI,EAAE,SAAS;QACf,cAAc,EAAE,iBAAiB;QACjC,WAAW,EAAE,EAAE;QACf,MAAM,EAAE,EAAE;QACV,cAAc,EAAE,IAAI;QACpB,eAAe,EAAE,IAAI;QACrB,gBAAgB,EAAE,IAAI;QACtB,cAAc,EAAE,KAAK;KACtB;IACD,MAAM,EAAE;QACN,IAAI,EAAE,IAAI;QACV,IAAI,EAAE,IAAI;QACV,SAAS,EAAE,KAAK;KACjB;IACD,SAAS,EAAE;QACT,OAAO,EAAE,KAAK;QACd,QAAQ,EAAE,SAAS;QACnB,QAAQ,EAAE,SAAS;QACnB,WAAW,EAAE,SAAS;QACtB,cAAc,EAAE,KAAK;KACtB;CACF,CAAC;AAEF,4CAA4C;AAC5C,MAAM,UAAU,aAAa,CAAC,UAAyB;IACrD,OAAO;QACL,GAAG,cAAc;QACjB,GAAG,UAAU;QACb,EAAE,EAAE,EAAE,GAAG,cAAc,CAAC,EAAE,EAAE,GAAG,UAAU,CAAC,EAAE,EAAE;QAC9C,MAAM,EAAE,EAAE,GAAG,cAAc,CAAC,MAAM,EAAE,GAAG,UAAU,CAAC,MAAM,EAAE;QAC1D,SAAS,EAAE,EAAE,GAAG,cAAc,CAAC,SAAS,EAAE,GAAG,UAAU,CAAC,SAAS,EAAE;KACpE,CAAC;AACJ,CAAC"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * EventRouter — Routes all 51 SDK event types to typed callbacks.
3
+ *
4
+ * Clean-room implementation that exhaustively handles every event type
5
+ * the Copilot SDK emits. No event is silently dropped.
6
+ */
7
+ import type { UsageData, ToolExecution } from './types.js';
8
+ export interface EventCallbacks {
9
+ onDelta?: (content: string) => void;
10
+ onReasoningDelta?: (content: string, reasoningId?: string) => void;
11
+ onReasoning?: (content: string, reasoningId?: string) => void;
12
+ onUsage?: (usage: UsageData) => void;
13
+ onTurnStart?: (turnId: string) => void;
14
+ onTurnEnd?: (turnId: string) => void;
15
+ onIntent?: (intent: string) => void;
16
+ onToolStart?: (tool: Pick<ToolExecution, 'toolCallId' | 'toolName' | 'arguments'> & {
17
+ mcpServerName?: string;
18
+ mcpToolName?: string;
19
+ }) => void;
20
+ onToolComplete?: (toolCallId: string, toolName: string, result: string) => void;
21
+ onToolProgress?: (toolCallId: string, message: string) => void;
22
+ onToolPartialResult?: (toolCallId: string, result: string) => void;
23
+ onToolUserRequested?: (toolCallId: string, toolName: string) => void;
24
+ onSkillInvoked?: (name: string, pluginName?: string, path?: string) => void;
25
+ onSubagentStarted?: (toolCallId: string, name: string, displayName?: string, description?: string) => void;
26
+ onSubagentCompleted?: (toolCallId: string, name: string, displayName?: string) => void;
27
+ onSubagentFailed?: (toolCallId: string, name: string, error?: string) => void;
28
+ onSubagentSelected?: (name: string) => void;
29
+ onSubagentDeselected?: (name: string) => void;
30
+ onSessionStart?: (sessionId: string) => void;
31
+ onSessionResume?: (sessionId: string) => void;
32
+ onSessionShutdown?: () => void;
33
+ onSessionIdle?: () => void;
34
+ onError?: (message: string) => void;
35
+ onInfo?: (infoType: string, message: string) => void;
36
+ onWarning?: (warningType: string, message: string) => void;
37
+ onModelChange?: (model: string) => void;
38
+ onTruncation?: (data: Record<string, unknown>) => void;
39
+ onCompactionStart?: () => void;
40
+ onCompactionComplete?: () => void;
41
+ onContextChanged?: (data: Record<string, unknown>) => void;
42
+ onModeChanged?: (mode: string) => void;
43
+ onPlanChanged?: (plan: unknown) => void;
44
+ onTitleChanged?: (title: string) => void;
45
+ onPermissionRequested?: (data: Record<string, unknown>) => void;
46
+ onPermissionCompleted?: (data: Record<string, unknown>) => void;
47
+ onElicitationRequested?: (data: Record<string, unknown>) => void;
48
+ onElicitationCompleted?: (data: Record<string, unknown>) => void;
49
+ onUserInputRequested?: (data: Record<string, unknown>) => void;
50
+ onUserInputCompleted?: (data: Record<string, unknown>) => void;
51
+ onUserMessage?: (content: string) => void;
52
+ onSystemMessage?: (content: string) => void;
53
+ onAssistantMessage?: (content: string) => void;
54
+ onPendingMessagesModified?: (data: Record<string, unknown>) => void;
55
+ onWorkspaceFileChanged?: (path: string) => void;
56
+ onSnapshotRewind?: (data: Record<string, unknown>) => void;
57
+ onHookStart?: (name: string) => void;
58
+ onHookEnd?: (name: string) => void;
59
+ onTaskComplete?: (data: Record<string, unknown>) => void;
60
+ onHandoff?: (data: Record<string, unknown>) => void;
61
+ onUsageInfo?: (data: Record<string, unknown>) => void;
62
+ onUnhandledEvent?: (type: string, data: Record<string, unknown>) => void;
63
+ }
64
+ export declare class EventRouter {
65
+ private callbacks;
66
+ private debug;
67
+ constructor(callbacks: EventCallbacks, debug?: boolean);
68
+ /**
69
+ * Route a SessionEvent to the appropriate callback.
70
+ * Every event type is explicitly handled — nothing is silently dropped.
71
+ */
72
+ route(event: {
73
+ type: string;
74
+ data?: any;
75
+ }): void;
76
+ }
77
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"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"}