claude-code-watchos 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/README.md +47 -0
- package/dist/src/cli/serve.d.ts +6 -0
- package/dist/src/cli/serve.d.ts.map +1 -0
- package/dist/src/cli/serve.js +9 -0
- package/dist/src/cli/serve.js.map +1 -0
- package/dist/src/cli/setup.d.ts +5 -0
- package/dist/src/cli/setup.d.ts.map +1 -0
- package/dist/src/cli/setup.js +215 -0
- package/dist/src/cli/setup.js.map +1 -0
- package/dist/src/cli/status.d.ts +5 -0
- package/dist/src/cli/status.d.ts.map +1 -0
- package/dist/src/cli/status.js +73 -0
- package/dist/src/cli/status.js.map +1 -0
- package/dist/src/cli/unpair.d.ts +5 -0
- package/dist/src/cli/unpair.d.ts.map +1 -0
- package/dist/src/cli/unpair.js +65 -0
- package/dist/src/cli/unpair.js.map +1 -0
- package/dist/src/cloud/client.d.ts +58 -0
- package/dist/src/cloud/client.d.ts.map +1 -0
- package/dist/src/cloud/client.js +166 -0
- package/dist/src/cloud/client.js.map +1 -0
- package/dist/src/cloud/pairing.d.ts +51 -0
- package/dist/src/cloud/pairing.d.ts.map +1 -0
- package/dist/src/cloud/pairing.js +131 -0
- package/dist/src/cloud/pairing.js.map +1 -0
- package/dist/src/config/mcp-config.d.ts +26 -0
- package/dist/src/config/mcp-config.d.ts.map +1 -0
- package/dist/src/config/mcp-config.js +76 -0
- package/dist/src/config/mcp-config.js.map +1 -0
- package/dist/src/config/pairing-store.d.ts +38 -0
- package/dist/src/config/pairing-store.d.ts.map +1 -0
- package/dist/src/config/pairing-store.js +91 -0
- package/dist/src/config/pairing-store.js.map +1 -0
- package/dist/src/index.d.ts +8 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +68 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/server/index.d.ts +12 -0
- package/dist/src/server/index.d.ts.map +1 -0
- package/dist/src/server/index.js +74 -0
- package/dist/src/server/index.js.map +1 -0
- package/dist/src/server/state.d.ts +64 -0
- package/dist/src/server/state.d.ts.map +1 -0
- package/dist/src/server/state.js +194 -0
- package/dist/src/server/state.js.map +1 -0
- package/dist/src/server/tools.d.ts +258 -0
- package/dist/src/server/tools.d.ts.map +1 -0
- package/dist/src/server/tools.js +177 -0
- package/dist/src/server/tools.js.map +1 -0
- package/dist/src/types/index.d.ts +212 -0
- package/dist/src/types/index.d.ts.map +1 -0
- package/dist/src/types/index.js +90 -0
- package/dist/src/types/index.js.map +1 -0
- package/package.json +52 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { getCloudUrl, getPairingId } from "../config/pairing-store.js";
|
|
2
|
+
/**
|
|
3
|
+
* Cloud Relay Client
|
|
4
|
+
*
|
|
5
|
+
* Communicates with the cloud relay server to bridge messages
|
|
6
|
+
* between the MCP server and the Apple Watch.
|
|
7
|
+
*/
|
|
8
|
+
export class CloudClient {
|
|
9
|
+
cloudUrl;
|
|
10
|
+
pairingId;
|
|
11
|
+
pollInterval = 1000; // 1 second
|
|
12
|
+
isPolling = false;
|
|
13
|
+
messageHandler = null;
|
|
14
|
+
constructor(cloudUrl, pairingId) {
|
|
15
|
+
this.cloudUrl = cloudUrl || getCloudUrl();
|
|
16
|
+
this.pairingId = pairingId || getPairingId();
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Check if the client is configured
|
|
20
|
+
*/
|
|
21
|
+
isConfigured() {
|
|
22
|
+
return !!this.pairingId;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Send a message to the watch via cloud relay
|
|
26
|
+
*/
|
|
27
|
+
async sendMessage(message) {
|
|
28
|
+
if (!this.pairingId) {
|
|
29
|
+
console.error("No pairing ID configured");
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
const response = await fetch(`${this.cloudUrl}/api/message`, {
|
|
34
|
+
method: "POST",
|
|
35
|
+
headers: {
|
|
36
|
+
"Content-Type": "application/json",
|
|
37
|
+
},
|
|
38
|
+
body: JSON.stringify({
|
|
39
|
+
pairingId: this.pairingId,
|
|
40
|
+
type: "to_watch",
|
|
41
|
+
payload: message,
|
|
42
|
+
timestamp: new Date().toISOString(),
|
|
43
|
+
}),
|
|
44
|
+
});
|
|
45
|
+
return response.ok;
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
console.error("Failed to send message to cloud:", error);
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Poll for messages from the watch
|
|
54
|
+
*/
|
|
55
|
+
async pollMessages() {
|
|
56
|
+
if (!this.pairingId) {
|
|
57
|
+
return [];
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
const response = await fetch(`${this.cloudUrl}/api/messages?pairingId=${this.pairingId}&direction=to_server`);
|
|
61
|
+
if (!response.ok) {
|
|
62
|
+
return [];
|
|
63
|
+
}
|
|
64
|
+
const data = (await response.json());
|
|
65
|
+
return data.messages || [];
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
console.error("Failed to poll messages:", error);
|
|
69
|
+
return [];
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Broadcast state sync to watch
|
|
74
|
+
*/
|
|
75
|
+
async syncState(state) {
|
|
76
|
+
return this.sendMessage({
|
|
77
|
+
type: "state_sync",
|
|
78
|
+
state,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Start polling for messages
|
|
83
|
+
*/
|
|
84
|
+
startPolling(handler) {
|
|
85
|
+
if (this.isPolling)
|
|
86
|
+
return;
|
|
87
|
+
this.isPolling = true;
|
|
88
|
+
this.messageHandler = handler;
|
|
89
|
+
const poll = async () => {
|
|
90
|
+
if (!this.isPolling)
|
|
91
|
+
return;
|
|
92
|
+
const messages = await this.pollMessages();
|
|
93
|
+
for (const msg of messages) {
|
|
94
|
+
if (this.messageHandler && msg.payload) {
|
|
95
|
+
this.messageHandler(msg.payload);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
setTimeout(poll, this.pollInterval);
|
|
99
|
+
};
|
|
100
|
+
poll();
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Stop polling for messages
|
|
104
|
+
*/
|
|
105
|
+
stopPolling() {
|
|
106
|
+
this.isPolling = false;
|
|
107
|
+
this.messageHandler = null;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Check cloud connectivity
|
|
111
|
+
*/
|
|
112
|
+
async checkConnectivity() {
|
|
113
|
+
const start = Date.now();
|
|
114
|
+
try {
|
|
115
|
+
const response = await fetch(`${this.cloudUrl}/health`, {
|
|
116
|
+
method: "GET",
|
|
117
|
+
signal: AbortSignal.timeout(5000),
|
|
118
|
+
});
|
|
119
|
+
const latency = Date.now() - start;
|
|
120
|
+
if (response.ok) {
|
|
121
|
+
return { connected: true, latency };
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
return {
|
|
125
|
+
connected: false,
|
|
126
|
+
error: `HTTP ${response.status}`,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
return {
|
|
132
|
+
connected: false,
|
|
133
|
+
error: error instanceof Error ? error.message : "Unknown error",
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Get the cloud URL
|
|
139
|
+
*/
|
|
140
|
+
getCloudUrl() {
|
|
141
|
+
return this.cloudUrl;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Get the pairing ID
|
|
145
|
+
*/
|
|
146
|
+
getPairingId() {
|
|
147
|
+
return this.pairingId;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Create a singleton cloud client
|
|
152
|
+
*/
|
|
153
|
+
let clientInstance = null;
|
|
154
|
+
export function getCloudClient() {
|
|
155
|
+
if (!clientInstance) {
|
|
156
|
+
clientInstance = new CloudClient();
|
|
157
|
+
}
|
|
158
|
+
return clientInstance;
|
|
159
|
+
}
|
|
160
|
+
export function resetCloudClient() {
|
|
161
|
+
if (clientInstance) {
|
|
162
|
+
clientInstance.stopPolling();
|
|
163
|
+
clientInstance = null;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/cloud/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate a 6-digit pairing code
|
|
3
|
+
*/
|
|
4
|
+
export declare function generatePairingCode(): string;
|
|
5
|
+
/**
|
|
6
|
+
* Format pairing code for display (e.g., "4 7 2 9 1 3")
|
|
7
|
+
*/
|
|
8
|
+
export declare function formatPairingCode(code: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Pairing session that waits for watch to pair
|
|
11
|
+
*/
|
|
12
|
+
export declare class PairingSession {
|
|
13
|
+
private code;
|
|
14
|
+
private cloudUrl;
|
|
15
|
+
private sessionId;
|
|
16
|
+
private pollInterval;
|
|
17
|
+
private maxAttempts;
|
|
18
|
+
private isActive;
|
|
19
|
+
constructor(cloudUrl?: string);
|
|
20
|
+
/**
|
|
21
|
+
* Get the pairing code
|
|
22
|
+
*/
|
|
23
|
+
getCode(): string;
|
|
24
|
+
/**
|
|
25
|
+
* Get the formatted pairing code for display
|
|
26
|
+
*/
|
|
27
|
+
getFormattedCode(): string;
|
|
28
|
+
/**
|
|
29
|
+
* Register the pairing code with the cloud
|
|
30
|
+
*/
|
|
31
|
+
register(): Promise<boolean>;
|
|
32
|
+
/**
|
|
33
|
+
* Wait for the watch to pair using the code
|
|
34
|
+
* Returns the pairing ID when successful, or null on timeout/cancel
|
|
35
|
+
*/
|
|
36
|
+
waitForPairing(onProgress?: (attempt: number, maxAttempts: number) => void): Promise<string | null>;
|
|
37
|
+
/**
|
|
38
|
+
* Cancel the pairing session
|
|
39
|
+
*/
|
|
40
|
+
cancel(): void;
|
|
41
|
+
/**
|
|
42
|
+
* Cleanup the pairing session on the server
|
|
43
|
+
*/
|
|
44
|
+
cleanup(): Promise<void>;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Simulate local-only pairing (for testing or local mode)
|
|
48
|
+
* In this mode, we generate a pairing ID immediately
|
|
49
|
+
*/
|
|
50
|
+
export declare function createLocalPairing(): string;
|
|
51
|
+
//# sourceMappingURL=pairing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pairing.d.ts","sourceRoot":"","sources":["../../../src/cloud/pairing.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAM5C;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,YAAY,CAAgB;IACpC,OAAO,CAAC,WAAW,CAAe;IAClC,OAAO,CAAC,QAAQ,CAAkB;gBAEtB,QAAQ,CAAC,EAAE,MAAM;IAM7B;;OAEG;IACH,OAAO,IAAI,MAAM;IAIjB;;OAEG;IACH,gBAAgB,IAAI,MAAM;IAI1B;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC;IAqBlC;;;OAGG;IACG,cAAc,CAClB,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,GAC1D,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAiCzB;;OAEG;IACH,MAAM,IAAI,IAAI;IAId;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAe/B;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { getCloudUrl } from "../config/pairing-store.js";
|
|
2
|
+
/**
|
|
3
|
+
* Generate a 6-digit pairing code
|
|
4
|
+
*/
|
|
5
|
+
export function generatePairingCode() {
|
|
6
|
+
const digits = [];
|
|
7
|
+
for (let i = 0; i < 6; i++) {
|
|
8
|
+
digits.push(Math.floor(Math.random() * 10));
|
|
9
|
+
}
|
|
10
|
+
return digits.join("");
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Format pairing code for display (e.g., "4 7 2 9 1 3")
|
|
14
|
+
*/
|
|
15
|
+
export function formatPairingCode(code) {
|
|
16
|
+
return code.split("").join(" ");
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Pairing session that waits for watch to pair
|
|
20
|
+
*/
|
|
21
|
+
export class PairingSession {
|
|
22
|
+
code;
|
|
23
|
+
cloudUrl;
|
|
24
|
+
sessionId;
|
|
25
|
+
pollInterval = 1000;
|
|
26
|
+
maxAttempts = 300; // 5 minutes at 1 second interval
|
|
27
|
+
isActive = false;
|
|
28
|
+
constructor(cloudUrl) {
|
|
29
|
+
this.code = generatePairingCode();
|
|
30
|
+
this.cloudUrl = cloudUrl || getCloudUrl();
|
|
31
|
+
this.sessionId = crypto.randomUUID();
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Get the pairing code
|
|
35
|
+
*/
|
|
36
|
+
getCode() {
|
|
37
|
+
return this.code;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Get the formatted pairing code for display
|
|
41
|
+
*/
|
|
42
|
+
getFormattedCode() {
|
|
43
|
+
return formatPairingCode(this.code);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Register the pairing code with the cloud
|
|
47
|
+
*/
|
|
48
|
+
async register() {
|
|
49
|
+
try {
|
|
50
|
+
const response = await fetch(`${this.cloudUrl}/api/pairing/register`, {
|
|
51
|
+
method: "POST",
|
|
52
|
+
headers: {
|
|
53
|
+
"Content-Type": "application/json",
|
|
54
|
+
},
|
|
55
|
+
body: JSON.stringify({
|
|
56
|
+
code: this.code,
|
|
57
|
+
sessionId: this.sessionId,
|
|
58
|
+
timestamp: new Date().toISOString(),
|
|
59
|
+
}),
|
|
60
|
+
});
|
|
61
|
+
return response.ok;
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
console.error("Failed to register pairing code:", error);
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Wait for the watch to pair using the code
|
|
70
|
+
* Returns the pairing ID when successful, or null on timeout/cancel
|
|
71
|
+
*/
|
|
72
|
+
async waitForPairing(onProgress) {
|
|
73
|
+
this.isActive = true;
|
|
74
|
+
let attempts = 0;
|
|
75
|
+
while (this.isActive && attempts < this.maxAttempts) {
|
|
76
|
+
attempts++;
|
|
77
|
+
if (onProgress) {
|
|
78
|
+
onProgress(attempts, this.maxAttempts);
|
|
79
|
+
}
|
|
80
|
+
try {
|
|
81
|
+
const response = await fetch(`${this.cloudUrl}/api/pairing/check?sessionId=${this.sessionId}`);
|
|
82
|
+
if (response.ok) {
|
|
83
|
+
const data = (await response.json());
|
|
84
|
+
if (data.paired && data.pairingId) {
|
|
85
|
+
this.isActive = false;
|
|
86
|
+
return data.pairingId;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
// Ignore polling errors and continue
|
|
92
|
+
}
|
|
93
|
+
await new Promise((resolve) => setTimeout(resolve, this.pollInterval));
|
|
94
|
+
}
|
|
95
|
+
this.isActive = false;
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Cancel the pairing session
|
|
100
|
+
*/
|
|
101
|
+
cancel() {
|
|
102
|
+
this.isActive = false;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Cleanup the pairing session on the server
|
|
106
|
+
*/
|
|
107
|
+
async cleanup() {
|
|
108
|
+
try {
|
|
109
|
+
await fetch(`${this.cloudUrl}/api/pairing/cleanup`, {
|
|
110
|
+
method: "POST",
|
|
111
|
+
headers: {
|
|
112
|
+
"Content-Type": "application/json",
|
|
113
|
+
},
|
|
114
|
+
body: JSON.stringify({
|
|
115
|
+
sessionId: this.sessionId,
|
|
116
|
+
}),
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
// Ignore cleanup errors
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Simulate local-only pairing (for testing or local mode)
|
|
126
|
+
* In this mode, we generate a pairing ID immediately
|
|
127
|
+
*/
|
|
128
|
+
export function createLocalPairing() {
|
|
129
|
+
return crypto.randomUUID();
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=pairing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pairing.js","sourceRoot":"","sources":["../../../src/cloud/pairing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAEzD;;GAEG;AACH,MAAM,UAAU,mBAAmB;IACjC,MAAM,MAAM,GAAG,EAAE,CAAC;IAClB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACzB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,MAAM,OAAO,cAAc;IACjB,IAAI,CAAS;IACb,QAAQ,CAAS;IACjB,SAAS,CAAS;IAClB,YAAY,GAAW,IAAI,CAAC;IAC5B,WAAW,GAAW,GAAG,CAAC,CAAC,iCAAiC;IAC5D,QAAQ,GAAY,KAAK,CAAC;IAElC,YAAY,QAAiB;QAC3B,IAAI,CAAC,IAAI,GAAG,mBAAmB,EAAE,CAAC;QAClC,IAAI,CAAC,QAAQ,GAAG,QAAQ,IAAI,WAAW,EAAE,CAAC;QAC1C,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;IACvC,CAAC;IAED;;OAEG;IACH,OAAO;QACL,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAED;;OAEG;IACH,gBAAgB;QACd,OAAO,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ;QACZ,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,QAAQ,uBAAuB,EAAE;gBACpE,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;iBACnC;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;oBACnB,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,SAAS,EAAE,IAAI,CAAC,SAAS;oBACzB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;iBACpC,CAAC;aACH,CAAC,CAAC;YAEH,OAAO,QAAQ,CAAC,EAAE,CAAC;QACrB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,kCAAkC,EAAE,KAAK,CAAC,CAAC;YACzD,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,cAAc,CAClB,UAA2D;QAE3D,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,QAAQ,GAAG,CAAC,CAAC;QAEjB,OAAO,IAAI,CAAC,QAAQ,IAAI,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;YACpD,QAAQ,EAAE,CAAC;YACX,IAAI,UAAU,EAAE,CAAC;gBACf,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;YACzC,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAC1B,GAAG,IAAI,CAAC,QAAQ,gCAAgC,IAAI,CAAC,SAAS,EAAE,CACjE,CAAC;gBAEF,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;oBAChB,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAA4C,CAAC;oBAChF,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;wBAClC,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;wBACtB,OAAO,IAAI,CAAC,SAAS,CAAC;oBACxB,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,qCAAqC;YACvC,CAAC;YAED,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;QACzE,CAAC;QAED,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,MAAM;QACJ,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;IACxB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO;QACX,IAAI,CAAC;YACH,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,QAAQ,sBAAsB,EAAE;gBAClD,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;iBACnC;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;oBACnB,SAAS,EAAE,IAAI,CAAC,SAAS;iBAC1B,CAAC;aACH,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,wBAAwB;QAC1B,CAAC;IACH,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO,MAAM,CAAC,UAAU,EAAE,CAAC;AAC7B,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { MCPConfig } from "../types/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Read the current MCP config file
|
|
4
|
+
*/
|
|
5
|
+
export declare function readMCPConfig(): MCPConfig;
|
|
6
|
+
/**
|
|
7
|
+
* Write the MCP config file
|
|
8
|
+
*/
|
|
9
|
+
export declare function writeMCPConfig(config: MCPConfig): void;
|
|
10
|
+
/**
|
|
11
|
+
* Add claude-watch server to MCP config
|
|
12
|
+
*/
|
|
13
|
+
export declare function addClaudeWatchServer(): void;
|
|
14
|
+
/**
|
|
15
|
+
* Remove claude-watch server from MCP config
|
|
16
|
+
*/
|
|
17
|
+
export declare function removeClaudeWatchServer(): void;
|
|
18
|
+
/**
|
|
19
|
+
* Check if claude-watch server is configured
|
|
20
|
+
*/
|
|
21
|
+
export declare function isClaudeWatchConfigured(): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Get the MCP config file path
|
|
24
|
+
*/
|
|
25
|
+
export declare function getMCPConfigPath(): string;
|
|
26
|
+
//# sourceMappingURL=mcp-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-config.d.ts","sourceRoot":"","sources":["../../../src/config/mcp-config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,mBAAmB,CAAC;AAcpE;;GAEG;AACH,wBAAgB,aAAa,IAAI,SAAS,CAiBzC;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAGtD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAY3C;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,IAAI,CAI9C;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,OAAO,CAGjD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
2
|
+
import { homedir } from "os";
|
|
3
|
+
import { join } from "path";
|
|
4
|
+
const CLAUDE_DIR = join(homedir(), ".claude");
|
|
5
|
+
const MCP_CONFIG_PATH = join(CLAUDE_DIR, ".mcp.json");
|
|
6
|
+
/**
|
|
7
|
+
* Ensure the ~/.claude directory exists
|
|
8
|
+
*/
|
|
9
|
+
function ensureClaudeDir() {
|
|
10
|
+
if (!existsSync(CLAUDE_DIR)) {
|
|
11
|
+
mkdirSync(CLAUDE_DIR, { recursive: true });
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Read the current MCP config file
|
|
16
|
+
*/
|
|
17
|
+
export function readMCPConfig() {
|
|
18
|
+
ensureClaudeDir();
|
|
19
|
+
if (!existsSync(MCP_CONFIG_PATH)) {
|
|
20
|
+
return { mcpServers: {} };
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
const content = readFileSync(MCP_CONFIG_PATH, "utf-8");
|
|
24
|
+
const config = JSON.parse(content);
|
|
25
|
+
return {
|
|
26
|
+
mcpServers: config.mcpServers || {},
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
// If file is corrupted, start fresh
|
|
31
|
+
return { mcpServers: {} };
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Write the MCP config file
|
|
36
|
+
*/
|
|
37
|
+
export function writeMCPConfig(config) {
|
|
38
|
+
ensureClaudeDir();
|
|
39
|
+
writeFileSync(MCP_CONFIG_PATH, JSON.stringify(config, null, 2) + "\n");
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Add claude-watch server to MCP config
|
|
43
|
+
*/
|
|
44
|
+
export function addClaudeWatchServer() {
|
|
45
|
+
const config = readMCPConfig();
|
|
46
|
+
// Use npx to run the package
|
|
47
|
+
// This works whether installed globally or via npx
|
|
48
|
+
const serverConfig = {
|
|
49
|
+
command: "npx",
|
|
50
|
+
args: ["claude-watch", "serve"],
|
|
51
|
+
};
|
|
52
|
+
config.mcpServers["claude-watch"] = serverConfig;
|
|
53
|
+
writeMCPConfig(config);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Remove claude-watch server from MCP config
|
|
57
|
+
*/
|
|
58
|
+
export function removeClaudeWatchServer() {
|
|
59
|
+
const config = readMCPConfig();
|
|
60
|
+
delete config.mcpServers["claude-watch"];
|
|
61
|
+
writeMCPConfig(config);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Check if claude-watch server is configured
|
|
65
|
+
*/
|
|
66
|
+
export function isClaudeWatchConfigured() {
|
|
67
|
+
const config = readMCPConfig();
|
|
68
|
+
return "claude-watch" in config.mcpServers;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Get the MCP config file path
|
|
72
|
+
*/
|
|
73
|
+
export function getMCPConfigPath() {
|
|
74
|
+
return MCP_CONFIG_PATH;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=mcp-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-config.js","sourceRoot":"","sources":["../../../src/config/mcp-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AACxE,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAG5B,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;AAC9C,MAAM,eAAe,GAAG,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;AAEtD;;GAEG;AACH,SAAS,eAAe;IACtB,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,eAAe,EAAE,CAAC;IAElB,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QACjC,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;IAC5B,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;QACvD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACnC,OAAO;YACL,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,EAAE;SACpC,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,oCAAoC;QACpC,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;IAC5B,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,MAAiB;IAC9C,eAAe,EAAE,CAAC;IAClB,aAAa,CAAC,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AACzE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB;IAClC,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAE/B,6BAA6B;IAC7B,mDAAmD;IACnD,MAAM,YAAY,GAAoB;QACpC,OAAO,EAAE,KAAK;QACd,IAAI,EAAE,CAAC,cAAc,EAAE,OAAO,CAAC;KAChC,CAAC;IAEF,MAAM,CAAC,UAAU,CAAC,cAAc,CAAC,GAAG,YAAY,CAAC;IACjD,cAAc,CAAC,MAAM,CAAC,CAAC;AACzB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB;IACrC,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAC/B,OAAO,MAAM,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;IACzC,cAAc,CAAC,MAAM,CAAC,CAAC;AACzB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB;IACrC,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAC/B,OAAO,cAAc,IAAI,MAAM,CAAC,UAAU,CAAC;AAC7C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB;IAC9B,OAAO,eAAe,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { PairingConfig } from "../types/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Read the pairing configuration
|
|
4
|
+
*/
|
|
5
|
+
export declare function readPairingConfig(): PairingConfig | null;
|
|
6
|
+
/**
|
|
7
|
+
* Save the pairing configuration
|
|
8
|
+
*/
|
|
9
|
+
export declare function savePairingConfig(config: PairingConfig): void;
|
|
10
|
+
/**
|
|
11
|
+
* Delete the pairing configuration
|
|
12
|
+
*/
|
|
13
|
+
export declare function deletePairingConfig(): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Check if we have a valid pairing
|
|
16
|
+
*/
|
|
17
|
+
export declare function isPaired(): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Get the cloud URL from config or default
|
|
20
|
+
*/
|
|
21
|
+
export declare function getCloudUrl(): string;
|
|
22
|
+
/**
|
|
23
|
+
* Get the pairing ID
|
|
24
|
+
*/
|
|
25
|
+
export declare function getPairingId(): string | null;
|
|
26
|
+
/**
|
|
27
|
+
* Get the config directory path
|
|
28
|
+
*/
|
|
29
|
+
export declare function getConfigDir(): string;
|
|
30
|
+
/**
|
|
31
|
+
* Get the config file path
|
|
32
|
+
*/
|
|
33
|
+
export declare function getConfigPath(): string;
|
|
34
|
+
/**
|
|
35
|
+
* Create a new pairing config with generated ID
|
|
36
|
+
*/
|
|
37
|
+
export declare function createPairingConfig(cloudUrl?: string): PairingConfig;
|
|
38
|
+
//# sourceMappingURL=pairing-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pairing-store.d.ts","sourceRoot":"","sources":["../../../src/config/pairing-store.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAiBvD;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,aAAa,GAAG,IAAI,CAWxD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAG7D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAM7C;AAED;;GAEG;AACH,wBAAgB,QAAQ,IAAI,OAAO,CAGlC;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAGpC;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CAG5C;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,aAAa,CAMpE"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync } from "fs";
|
|
2
|
+
import { homedir } from "os";
|
|
3
|
+
import { join } from "path";
|
|
4
|
+
const CONFIG_DIR = join(homedir(), ".claude-watch");
|
|
5
|
+
const CONFIG_PATH = join(CONFIG_DIR, "config.json");
|
|
6
|
+
// Default cloud URL - Cloudflare Worker
|
|
7
|
+
const DEFAULT_CLOUD_URL = "https://claude-watch.fotescodev.workers.dev";
|
|
8
|
+
/**
|
|
9
|
+
* Ensure the ~/.claude-watch directory exists
|
|
10
|
+
*/
|
|
11
|
+
function ensureConfigDir() {
|
|
12
|
+
if (!existsSync(CONFIG_DIR)) {
|
|
13
|
+
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Read the pairing configuration
|
|
18
|
+
*/
|
|
19
|
+
export function readPairingConfig() {
|
|
20
|
+
if (!existsSync(CONFIG_PATH)) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
const content = readFileSync(CONFIG_PATH, "utf-8");
|
|
25
|
+
return JSON.parse(content);
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Save the pairing configuration
|
|
33
|
+
*/
|
|
34
|
+
export function savePairingConfig(config) {
|
|
35
|
+
ensureConfigDir();
|
|
36
|
+
writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2) + "\n");
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Delete the pairing configuration
|
|
40
|
+
*/
|
|
41
|
+
export function deletePairingConfig() {
|
|
42
|
+
if (existsSync(CONFIG_PATH)) {
|
|
43
|
+
unlinkSync(CONFIG_PATH);
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Check if we have a valid pairing
|
|
50
|
+
*/
|
|
51
|
+
export function isPaired() {
|
|
52
|
+
const config = readPairingConfig();
|
|
53
|
+
return config !== null && !!config.pairingId;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Get the cloud URL from config or default
|
|
57
|
+
*/
|
|
58
|
+
export function getCloudUrl() {
|
|
59
|
+
const config = readPairingConfig();
|
|
60
|
+
return config?.cloudUrl || DEFAULT_CLOUD_URL;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Get the pairing ID
|
|
64
|
+
*/
|
|
65
|
+
export function getPairingId() {
|
|
66
|
+
const config = readPairingConfig();
|
|
67
|
+
return config?.pairingId || null;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Get the config directory path
|
|
71
|
+
*/
|
|
72
|
+
export function getConfigDir() {
|
|
73
|
+
return CONFIG_DIR;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Get the config file path
|
|
77
|
+
*/
|
|
78
|
+
export function getConfigPath() {
|
|
79
|
+
return CONFIG_PATH;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Create a new pairing config with generated ID
|
|
83
|
+
*/
|
|
84
|
+
export function createPairingConfig(cloudUrl) {
|
|
85
|
+
return {
|
|
86
|
+
pairingId: crypto.randomUUID(),
|
|
87
|
+
cloudUrl: cloudUrl || DEFAULT_CLOUD_URL,
|
|
88
|
+
createdAt: new Date().toISOString(),
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=pairing-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pairing-store.js","sourceRoot":"","sources":["../../../src/config/pairing-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AACpF,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAG5B,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,eAAe,CAAC,CAAC;AACpD,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAEpD,wCAAwC;AACxC,MAAM,iBAAiB,GAAG,6CAA6C,CAAC;AAExE;;GAEG;AACH,SAAS,eAAe;IACtB,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACnD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAqB;IACrD,eAAe,EAAE,CAAC;IAClB,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AACrE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB;IACjC,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC5B,UAAU,CAAC,WAAW,CAAC,CAAC;QACxB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,QAAQ;IACtB,MAAM,MAAM,GAAG,iBAAiB,EAAE,CAAC;IACnC,OAAO,MAAM,KAAK,IAAI,IAAI,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC;AAC/C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW;IACzB,MAAM,MAAM,GAAG,iBAAiB,EAAE,CAAC;IACnC,OAAO,MAAM,EAAE,QAAQ,IAAI,iBAAiB,CAAC;AAC/C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY;IAC1B,MAAM,MAAM,GAAG,iBAAiB,EAAE,CAAC;IACnC,OAAO,MAAM,EAAE,SAAS,IAAI,IAAI,CAAC;AACnC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY;IAC1B,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,QAAiB;IACnD,OAAO;QACL,SAAS,EAAE,MAAM,CAAC,UAAU,EAAE;QAC9B,QAAQ,EAAE,QAAQ,IAAI,iBAAiB;QACvC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
export { runSetup } from "./cli/setup.js";
|
|
3
|
+
export { runStatus } from "./cli/status.js";
|
|
4
|
+
export { runUnpair } from "./cli/unpair.js";
|
|
5
|
+
export { runServe } from "./cli/serve.js";
|
|
6
|
+
export { runMCPServer, createMCPServer } from "./server/index.js";
|
|
7
|
+
export * from "./types/index.js";
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAwEA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAClE,cAAc,kBAAkB,CAAC"}
|