@sumicom/quicksave 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.
Files changed (58) hide show
  1. package/LICENSE +21 -0
  2. package/dist/ai/commitSummary.d.ts +26 -0
  3. package/dist/ai/commitSummary.d.ts.map +1 -0
  4. package/dist/ai/commitSummary.js +145 -0
  5. package/dist/ai/commitSummary.js.map +1 -0
  6. package/dist/config.d.ts +22 -0
  7. package/dist/config.d.ts.map +1 -0
  8. package/dist/config.js +76 -0
  9. package/dist/config.js.map +1 -0
  10. package/dist/connection/connection.d.ts +54 -0
  11. package/dist/connection/connection.d.ts.map +1 -0
  12. package/dist/connection/connection.js +171 -0
  13. package/dist/connection/connection.js.map +1 -0
  14. package/dist/connection/signaling.d.ts +31 -0
  15. package/dist/connection/signaling.d.ts.map +1 -0
  16. package/dist/connection/signaling.js +144 -0
  17. package/dist/connection/signaling.js.map +1 -0
  18. package/dist/git/operations.d.ts +104 -0
  19. package/dist/git/operations.d.ts.map +1 -0
  20. package/dist/git/operations.js +383 -0
  21. package/dist/git/operations.js.map +1 -0
  22. package/dist/git/operations.test.d.ts +2 -0
  23. package/dist/git/operations.test.d.ts.map +1 -0
  24. package/dist/git/operations.test.js +232 -0
  25. package/dist/git/operations.test.js.map +1 -0
  26. package/dist/handlers/messageHandler.d.ts +33 -0
  27. package/dist/handlers/messageHandler.d.ts.map +1 -0
  28. package/dist/handlers/messageHandler.js +463 -0
  29. package/dist/handlers/messageHandler.js.map +1 -0
  30. package/dist/handlers/messageHandler.test.d.ts +2 -0
  31. package/dist/handlers/messageHandler.test.d.ts.map +1 -0
  32. package/dist/handlers/messageHandler.test.js +233 -0
  33. package/dist/handlers/messageHandler.test.js.map +1 -0
  34. package/dist/index.d.ts +3 -0
  35. package/dist/index.d.ts.map +1 -0
  36. package/dist/index.js +127 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/webrtc/connection.d.ts +52 -0
  39. package/dist/webrtc/connection.d.ts.map +1 -0
  40. package/dist/webrtc/connection.js +255 -0
  41. package/dist/webrtc/connection.js.map +1 -0
  42. package/dist/webrtc/signaling.d.ts +41 -0
  43. package/dist/webrtc/signaling.d.ts.map +1 -0
  44. package/dist/webrtc/signaling.js +152 -0
  45. package/dist/webrtc/signaling.js.map +1 -0
  46. package/package.json +36 -0
  47. package/src/ai/commitSummary.ts +199 -0
  48. package/src/config.ts +97 -0
  49. package/src/connection/connection.ts +223 -0
  50. package/src/connection/signaling.ts +172 -0
  51. package/src/git/operations.test.ts +305 -0
  52. package/src/git/operations.ts +443 -0
  53. package/src/handlers/messageHandler.test.ts +294 -0
  54. package/src/handlers/messageHandler.ts +550 -0
  55. package/src/index.ts +151 -0
  56. package/src/types/webrtc.d.ts +38 -0
  57. package/tsconfig.json +13 -0
  58. package/vitest.config.ts +9 -0
@@ -0,0 +1,255 @@
1
+ import { EventEmitter } from 'events';
2
+ import { RTCPeerConnection } from 'werift';
3
+ import { gzip, gunzip } from 'zlib';
4
+ import { promisify } from 'util';
5
+ import { generateKeyPair, encodeKeyPair, decodeKeyPair, deriveSharedSecret, encryptWithSharedSecret, decryptWithSharedSecret, encodeBase64, decodeBase64, parseMessage, serializeMessage, } from '@quicksave/shared';
6
+ import { SignalingClient } from './signaling.js';
7
+ const gzipAsync = promisify(gzip);
8
+ const gunzipAsync = promisify(gunzip);
9
+ export class WebRTCConnection extends EventEmitter {
10
+ config;
11
+ signaling;
12
+ peerConnection = null;
13
+ dataChannel = null;
14
+ keyPair;
15
+ peerPublicKey = null;
16
+ sharedSecret = null;
17
+ isConnected = false;
18
+ relayMode = false;
19
+ constructor(config) {
20
+ super();
21
+ this.config = config;
22
+ this.keyPair = decodeKeyPair(config.keyPair);
23
+ this.signaling = new SignalingClient(config.signalingServer, config.agentId);
24
+ this.setupSignalingHandlers();
25
+ }
26
+ setupSignalingHandlers() {
27
+ this.signaling.on('peer-connected', () => {
28
+ console.log('PWA peer connected, waiting for offer...');
29
+ });
30
+ this.signaling.on('offer', async (sdp) => {
31
+ await this.handleOffer(sdp);
32
+ });
33
+ this.signaling.on('ice-candidate', async (candidate) => {
34
+ await this.handleIceCandidate(candidate);
35
+ });
36
+ this.signaling.on('peer-disconnected', () => {
37
+ this.handlePeerDisconnected();
38
+ });
39
+ this.signaling.on('relay-mode', () => {
40
+ console.log('Switching to WebSocket relay mode');
41
+ this.enableRelayMode();
42
+ });
43
+ this.signaling.on('relay-data', (data) => {
44
+ if (this.relayMode) {
45
+ this.handleDataChannelMessage(data);
46
+ }
47
+ });
48
+ this.signaling.on('error', (error) => {
49
+ this.emit('error', error);
50
+ });
51
+ }
52
+ enableRelayMode() {
53
+ if (this.relayMode)
54
+ return;
55
+ this.relayMode = true;
56
+ // Close P2P connection if it exists
57
+ if (this.dataChannel) {
58
+ this.dataChannel.close();
59
+ this.dataChannel = null;
60
+ }
61
+ if (this.peerConnection) {
62
+ this.peerConnection.close();
63
+ this.peerConnection = null;
64
+ }
65
+ console.log('Relay mode enabled, waiting for key exchange...');
66
+ }
67
+ async start() {
68
+ console.log('Connecting to signaling server...');
69
+ await this.signaling.connect();
70
+ console.log('Connected to signaling server');
71
+ console.log(`Agent ID: ${this.config.agentId}`);
72
+ console.log(`Public Key: ${this.config.keyPair.publicKey}`);
73
+ }
74
+ async handleOffer(sdp) {
75
+ console.log('Received offer from PWA');
76
+ // Create peer connection
77
+ this.peerConnection = new RTCPeerConnection({
78
+ iceServers: this.config.iceServers || [
79
+ { urls: 'stun:stun.l.google.com:19302' },
80
+ { urls: 'stun:stun1.l.google.com:19302' },
81
+ ],
82
+ });
83
+ // Handle ICE candidates
84
+ this.peerConnection.onicecandidate = (event) => {
85
+ if (event.candidate) {
86
+ this.signaling.sendIceCandidate(event.candidate.toJSON());
87
+ }
88
+ };
89
+ // Handle connection state changes
90
+ this.peerConnection.onconnectionstatechange = () => {
91
+ console.log('Connection state:', this.peerConnection?.connectionState);
92
+ if (this.peerConnection?.connectionState === 'connected') {
93
+ this.isConnected = true;
94
+ this.emit('connected');
95
+ }
96
+ else if (this.peerConnection?.connectionState === 'disconnected' ||
97
+ this.peerConnection?.connectionState === 'failed') {
98
+ this.handlePeerDisconnected();
99
+ }
100
+ };
101
+ // Handle data channel
102
+ this.peerConnection.ondatachannel = (event) => {
103
+ console.log('Data channel received');
104
+ this.setupDataChannel(event.channel);
105
+ };
106
+ // Set remote description and create answer
107
+ await this.peerConnection.setRemoteDescription(sdp);
108
+ const answer = await this.peerConnection.createAnswer();
109
+ await this.peerConnection.setLocalDescription(answer);
110
+ // Send answer
111
+ this.signaling.sendAnswer(answer);
112
+ console.log('Sent answer to PWA');
113
+ }
114
+ async handleIceCandidate(candidate) {
115
+ if (this.peerConnection) {
116
+ await this.peerConnection.addIceCandidate(candidate);
117
+ }
118
+ }
119
+ setupDataChannel(channel) {
120
+ this.dataChannel = channel;
121
+ channel.onopen = () => {
122
+ console.log('Data channel open');
123
+ };
124
+ channel.onclose = () => {
125
+ console.log('Data channel closed');
126
+ this.handlePeerDisconnected();
127
+ };
128
+ channel.onmessage = (event) => {
129
+ this.handleDataChannelMessage(event.data);
130
+ };
131
+ }
132
+ async handleDataChannelMessage(data) {
133
+ try {
134
+ // Handle key exchange (uncompressed) vs encrypted messages (compressed)
135
+ if (!this.peerPublicKey) {
136
+ // Key exchange messages are uncompressed strings/buffers
137
+ const strData = Buffer.isBuffer(data) ? data.toString('utf-8') : data;
138
+ const keyExchange = JSON.parse(strData);
139
+ if (keyExchange.type === 'key-exchange') {
140
+ this.peerPublicKey = decodeBase64(keyExchange.publicKey);
141
+ this.sharedSecret = deriveSharedSecret(this.peerPublicKey, this.keyPair.secretKey);
142
+ console.log('Key exchange complete, connection encrypted');
143
+ // Mark as connected in relay mode (P2P sets this in onconnectionstatechange)
144
+ if (this.relayMode && !this.isConnected) {
145
+ this.isConnected = true;
146
+ this.emit('connected');
147
+ }
148
+ // Send our public key back
149
+ this.sendRaw(JSON.stringify({
150
+ type: 'key-exchange',
151
+ publicKey: encodeBase64(this.keyPair.publicKey),
152
+ }));
153
+ return;
154
+ }
155
+ }
156
+ // Post key-exchange: all messages are compressed
157
+ let strData;
158
+ if (Buffer.isBuffer(data)) {
159
+ // Binary data from data channel - decompress
160
+ const decompressed = await gunzipAsync(data);
161
+ strData = decompressed.toString('utf-8');
162
+ }
163
+ else if (this.relayMode) {
164
+ // Base64 string from relay - decode and decompress
165
+ const buffer = Buffer.from(data, 'base64');
166
+ const decompressed = await gunzipAsync(buffer);
167
+ strData = decompressed.toString('utf-8');
168
+ }
169
+ else {
170
+ // P2P mode: werift may deliver binary as a string with binary encoding
171
+ // Convert string to buffer using latin1 (preserves byte values) and decompress
172
+ const buffer = Buffer.from(data, 'latin1');
173
+ const decompressed = await gunzipAsync(buffer);
174
+ strData = decompressed.toString('utf-8');
175
+ }
176
+ // Decrypt and parse message
177
+ if (!this.sharedSecret) {
178
+ console.error('No shared secret, cannot decrypt message');
179
+ return;
180
+ }
181
+ const decrypted = decryptWithSharedSecret(strData, this.sharedSecret);
182
+ const message = parseMessage(decrypted);
183
+ this.emit('message', message);
184
+ }
185
+ catch (error) {
186
+ console.error('Failed to handle message:', error);
187
+ }
188
+ }
189
+ send(message) {
190
+ if (!this.sharedSecret) {
191
+ console.error('No shared secret, cannot encrypt message');
192
+ return;
193
+ }
194
+ const serialized = serializeMessage(message);
195
+ const encrypted = encryptWithSharedSecret(serialized, this.sharedSecret);
196
+ // Compress the encrypted payload before sending
197
+ gzipAsync(Buffer.from(encrypted)).then((compressed) => {
198
+ if (this.relayMode) {
199
+ // Send through WebSocket relay - base64 encode for JSON transport
200
+ this.signaling.sendRelayData(compressed.toString('base64'));
201
+ }
202
+ else {
203
+ // Send through WebRTC data channel as binary
204
+ if (!this.dataChannel || this.dataChannel.readyState !== 'open') {
205
+ console.error('Data channel not open');
206
+ return;
207
+ }
208
+ this.dataChannel.send(compressed);
209
+ }
210
+ });
211
+ }
212
+ sendRaw(data) {
213
+ if (this.relayMode) {
214
+ this.signaling.sendRelayData(data);
215
+ }
216
+ else if (this.dataChannel && this.dataChannel.readyState === 'open') {
217
+ this.dataChannel.send(data);
218
+ }
219
+ }
220
+ handlePeerDisconnected() {
221
+ if (this.isConnected) {
222
+ this.isConnected = false;
223
+ this.emit('disconnected');
224
+ }
225
+ // Clean up
226
+ this.dataChannel = null;
227
+ this.peerPublicKey = null;
228
+ this.sharedSecret = null;
229
+ this.relayMode = false;
230
+ if (this.peerConnection) {
231
+ this.peerConnection.close();
232
+ this.peerConnection = null;
233
+ }
234
+ console.log('Peer disconnected, waiting for new connection...');
235
+ }
236
+ disconnect() {
237
+ this.signaling.disconnect();
238
+ if (this.peerConnection) {
239
+ this.peerConnection.close();
240
+ }
241
+ }
242
+ getPublicKey() {
243
+ return this.config.keyPair.publicKey;
244
+ }
245
+ getAgentId() {
246
+ return this.config.agentId;
247
+ }
248
+ }
249
+ /**
250
+ * Generate and encode a new key pair for the agent
251
+ */
252
+ export function generateAgentKeyPair() {
253
+ return encodeKeyPair(generateKeyPair());
254
+ }
255
+ //# sourceMappingURL=connection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/webrtc/connection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import { EventEmitter } from 'events';
2
+ type SDPInit = any;
3
+ type ICECandidateInit = any;
4
+ export interface SignalingEvents {
5
+ 'peer-connected': () => void;
6
+ 'peer-disconnected': () => void;
7
+ offer: (sdp: SDPInit) => void;
8
+ answer: (sdp: SDPInit) => void;
9
+ 'ice-candidate': (candidate: ICECandidateInit) => void;
10
+ 'relay-mode': () => void;
11
+ 'relay-data': (data: string) => void;
12
+ connected: () => void;
13
+ disconnected: () => void;
14
+ error: (error: Error) => void;
15
+ }
16
+ export declare class SignalingClient extends EventEmitter {
17
+ private ws;
18
+ private url;
19
+ private agentId;
20
+ private reconnectAttempts;
21
+ private maxReconnectAttempts;
22
+ private reconnectDelay;
23
+ private isConnected;
24
+ constructor(signalingServer: string, agentId: string);
25
+ connect(): Promise<void>;
26
+ private handleMessage;
27
+ sendOffer(sdp: SDPInit): void;
28
+ sendAnswer(sdp: SDPInit): void;
29
+ sendIceCandidate(candidate: ICECandidateInit): void;
30
+ sendBye(): void;
31
+ sendRelayData(data: string): void;
32
+ private compress;
33
+ private decompress;
34
+ private send;
35
+ private attemptReconnect;
36
+ disconnect(): void;
37
+ getAgentId(): string;
38
+ getConnectionUrl(): string;
39
+ }
40
+ export {};
41
+ //# sourceMappingURL=signaling.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signaling.d.ts","sourceRoot":"","sources":["../../src/webrtc/signaling.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAUtC,KAAK,OAAO,GAAG,GAAG,CAAC;AAEnB,KAAK,gBAAgB,GAAG,GAAG,CAAC;AAE5B,MAAM,WAAW,eAAe;IAC9B,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,mBAAmB,EAAE,MAAM,IAAI,CAAC;IAChC,KAAK,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9B,MAAM,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/B,eAAe,EAAE,CAAC,SAAS,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACvD,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,KAAK,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAC/B;AAED,qBAAa,eAAgB,SAAQ,YAAY;IAC/C,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,oBAAoB,CAAK;IACjC,OAAO,CAAC,cAAc,CAAQ;IAC9B,OAAO,CAAC,WAAW,CAAS;gBAEhB,eAAe,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAMpD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA2CxB,OAAO,CAAC,aAAa;IA+BrB,SAAS,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI;IAI7B,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI;IAI9B,gBAAgB,CAAC,SAAS,EAAE,gBAAgB,GAAG,IAAI;IAInD,OAAO,IAAI,IAAI;IAIf,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;YAKnB,QAAQ;YAKR,UAAU;IAMxB,OAAO,CAAC,IAAI;IASZ,OAAO,CAAC,gBAAgB;IAkBxB,UAAU,IAAI,IAAI;IASlB,UAAU,IAAI,MAAM;IAIpB,gBAAgB,IAAI,MAAM;CAG3B"}
@@ -0,0 +1,152 @@
1
+ import WebSocket from 'ws';
2
+ import { EventEmitter } from 'events';
3
+ import { gzip, gunzip } from 'zlib';
4
+ import { promisify } from 'util';
5
+ const gzipAsync = promisify(gzip);
6
+ const gunzipAsync = promisify(gunzip);
7
+ export class SignalingClient extends EventEmitter {
8
+ ws = null;
9
+ url;
10
+ agentId;
11
+ reconnectAttempts = 0;
12
+ maxReconnectAttempts = 5;
13
+ reconnectDelay = 1000;
14
+ isConnected = false;
15
+ constructor(signalingServer, agentId) {
16
+ super();
17
+ this.url = `${signalingServer}/agent/${agentId}`;
18
+ this.agentId = agentId;
19
+ }
20
+ connect() {
21
+ return new Promise((resolve, reject) => {
22
+ try {
23
+ this.ws = new WebSocket(this.url);
24
+ this.ws.on('open', () => {
25
+ this.isConnected = true;
26
+ this.reconnectAttempts = 0;
27
+ this.emit('connected');
28
+ resolve();
29
+ });
30
+ this.ws.on('message', async (data) => {
31
+ try {
32
+ const parsed = JSON.parse(data.toString());
33
+ // Handle compressed messages (z = zipped)
34
+ const message = parsed.z
35
+ ? JSON.parse(await this.decompress(parsed.z))
36
+ : parsed;
37
+ this.handleMessage(message);
38
+ }
39
+ catch (error) {
40
+ console.error('Failed to parse signaling message:', error);
41
+ }
42
+ });
43
+ this.ws.on('close', () => {
44
+ this.isConnected = false;
45
+ this.emit('disconnected');
46
+ this.attemptReconnect();
47
+ });
48
+ this.ws.on('error', (error) => {
49
+ this.emit('error', error);
50
+ if (!this.isConnected) {
51
+ reject(error);
52
+ }
53
+ });
54
+ }
55
+ catch (error) {
56
+ reject(error);
57
+ }
58
+ });
59
+ }
60
+ handleMessage(message) {
61
+ switch (message.type) {
62
+ case 'peer-connected':
63
+ this.emit('peer-connected');
64
+ break;
65
+ case 'peer-offline':
66
+ this.emit('peer-disconnected');
67
+ break;
68
+ case 'offer':
69
+ this.emit('offer', message.payload);
70
+ break;
71
+ case 'answer':
72
+ this.emit('answer', message.payload);
73
+ break;
74
+ case 'ice-candidate':
75
+ this.emit('ice-candidate', message.payload);
76
+ break;
77
+ case 'relay-mode':
78
+ this.emit('relay-mode');
79
+ break;
80
+ case 'relay-data':
81
+ if (typeof message.payload === 'string') {
82
+ this.emit('relay-data', message.payload);
83
+ }
84
+ break;
85
+ case 'bye':
86
+ this.emit('peer-disconnected');
87
+ break;
88
+ }
89
+ }
90
+ sendOffer(sdp) {
91
+ this.send({ type: 'offer', payload: sdp });
92
+ }
93
+ sendAnswer(sdp) {
94
+ this.send({ type: 'answer', payload: sdp });
95
+ }
96
+ sendIceCandidate(candidate) {
97
+ this.send({ type: 'ice-candidate', payload: candidate });
98
+ }
99
+ sendBye() {
100
+ this.send({ type: 'bye' });
101
+ }
102
+ sendRelayData(data) {
103
+ this.send({ type: 'relay-data', payload: data });
104
+ }
105
+ // Gzip compression helpers
106
+ async compress(data) {
107
+ const buffer = await gzipAsync(Buffer.from(data));
108
+ return buffer.toString('base64');
109
+ }
110
+ async decompress(base64) {
111
+ const buffer = Buffer.from(base64, 'base64');
112
+ const decompressed = await gunzipAsync(buffer);
113
+ return decompressed.toString('utf-8');
114
+ }
115
+ send(message) {
116
+ if (this.ws && this.ws.readyState === WebSocket.OPEN) {
117
+ // Send compressed
118
+ this.compress(JSON.stringify(message)).then((compressed) => {
119
+ this.ws?.send(JSON.stringify({ z: compressed }));
120
+ });
121
+ }
122
+ }
123
+ attemptReconnect() {
124
+ if (this.reconnectAttempts >= this.maxReconnectAttempts) {
125
+ console.error('Max reconnect attempts reached');
126
+ return;
127
+ }
128
+ this.reconnectAttempts++;
129
+ const delay = this.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1);
130
+ console.log(`Reconnecting in ${delay}ms (attempt ${this.reconnectAttempts})`);
131
+ setTimeout(() => {
132
+ this.connect().catch((error) => {
133
+ console.error('Reconnect failed:', error);
134
+ });
135
+ }, delay);
136
+ }
137
+ disconnect() {
138
+ this.maxReconnectAttempts = 0; // Prevent reconnection
139
+ if (this.ws) {
140
+ this.sendBye();
141
+ this.ws.close();
142
+ this.ws = null;
143
+ }
144
+ }
145
+ getAgentId() {
146
+ return this.agentId;
147
+ }
148
+ getConnectionUrl() {
149
+ return this.url;
150
+ }
151
+ }
152
+ //# sourceMappingURL=signaling.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signaling.js","sourceRoot":"","sources":["../../src/webrtc/signaling.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@sumicom/quicksave",
3
+ "version": "0.1.0",
4
+ "license": "MIT",
5
+ "type": "module",
6
+ "publishConfig": {
7
+ "branch": "stable"
8
+ },
9
+ "bin": {
10
+ "quicksave": "./dist/index.js"
11
+ },
12
+ "dependencies": {
13
+ "@anthropic-ai/sdk": "^0.71.2",
14
+ "commander": "^12.0.0",
15
+ "qrcode-terminal": "^0.12.0",
16
+ "simple-git": "^3.22.0",
17
+ "ws": "^8.16.0",
18
+ "@sumicom/quicksave-shared": "0.1.0"
19
+ },
20
+ "devDependencies": {
21
+ "@types/node": "^20.11.0",
22
+ "@types/ws": "^8.5.10",
23
+ "tsx": "^4.7.0",
24
+ "typescript": "^5.3.3",
25
+ "vitest": "^1.2.0"
26
+ },
27
+ "scripts": {
28
+ "dev": "tsx watch src/index.ts",
29
+ "build": "tsc",
30
+ "start": "node dist/index.js",
31
+ "typecheck": "tsc --noEmit",
32
+ "test": "vitest run",
33
+ "test:unit": "vitest run",
34
+ "test:watch": "vitest"
35
+ }
36
+ }