genbox-agent 1.0.39 → 1.0.41

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 (67) hide show
  1. package/dist/hook.d.ts +6 -5
  2. package/dist/hook.d.ts.map +1 -1
  3. package/dist/hook.js +200 -81
  4. package/dist/hook.js.map +1 -1
  5. package/dist/hooks/daemon-client.d.ts +39 -0
  6. package/dist/hooks/daemon-client.d.ts.map +1 -0
  7. package/dist/hooks/daemon-client.js +238 -0
  8. package/dist/hooks/daemon-client.js.map +1 -0
  9. package/dist/hooks/index.d.ts +7 -0
  10. package/dist/hooks/index.d.ts.map +1 -0
  11. package/dist/hooks/index.js +23 -0
  12. package/dist/hooks/index.js.map +1 -0
  13. package/dist/server/auth.d.ts +51 -0
  14. package/dist/server/auth.d.ts.map +1 -0
  15. package/dist/server/auth.js +154 -0
  16. package/dist/server/auth.js.map +1 -0
  17. package/dist/server/index.d.ts +156 -0
  18. package/dist/server/index.d.ts.map +1 -0
  19. package/dist/server/index.js +595 -0
  20. package/dist/server/index.js.map +1 -0
  21. package/dist/server/port-finder.d.ts +45 -0
  22. package/dist/server/port-finder.d.ts.map +1 -0
  23. package/dist/server/port-finder.js +267 -0
  24. package/dist/server/port-finder.js.map +1 -0
  25. package/dist/storage/index.d.ts +82 -0
  26. package/dist/storage/index.d.ts.map +1 -0
  27. package/dist/storage/index.js +209 -0
  28. package/dist/storage/index.js.map +1 -0
  29. package/dist/storage/manager.d.ts +112 -0
  30. package/dist/storage/manager.d.ts.map +1 -0
  31. package/dist/storage/manager.js +200 -0
  32. package/dist/storage/manager.js.map +1 -0
  33. package/dist/storage/repositories/events.d.ts +101 -0
  34. package/dist/storage/repositories/events.d.ts.map +1 -0
  35. package/dist/storage/repositories/events.js +258 -0
  36. package/dist/storage/repositories/events.js.map +1 -0
  37. package/dist/storage/repositories/index.d.ts +9 -0
  38. package/dist/storage/repositories/index.d.ts.map +1 -0
  39. package/dist/storage/repositories/index.js +25 -0
  40. package/dist/storage/repositories/index.js.map +1 -0
  41. package/dist/storage/repositories/messages.d.ts +123 -0
  42. package/dist/storage/repositories/messages.d.ts.map +1 -0
  43. package/dist/storage/repositories/messages.js +209 -0
  44. package/dist/storage/repositories/messages.js.map +1 -0
  45. package/dist/storage/repositories/sessions.d.ts +158 -0
  46. package/dist/storage/repositories/sessions.d.ts.map +1 -0
  47. package/dist/storage/repositories/sessions.js +342 -0
  48. package/dist/storage/repositories/sessions.js.map +1 -0
  49. package/dist/storage/schema.d.ts +42 -0
  50. package/dist/storage/schema.d.ts.map +1 -0
  51. package/dist/storage/schema.js +278 -0
  52. package/dist/storage/schema.js.map +1 -0
  53. package/dist/sync/background-sync.d.ts +83 -0
  54. package/dist/sync/background-sync.d.ts.map +1 -0
  55. package/dist/sync/background-sync.js +367 -0
  56. package/dist/sync/background-sync.js.map +1 -0
  57. package/dist/sync/index.d.ts +7 -0
  58. package/dist/sync/index.d.ts.map +1 -0
  59. package/dist/sync/index.js +23 -0
  60. package/dist/sync/index.js.map +1 -0
  61. package/dist/unified-daemon.js +219 -0
  62. package/dist/unified-daemon.js.map +1 -1
  63. package/dist/unified-hook.d.ts +4 -3
  64. package/dist/unified-hook.d.ts.map +1 -1
  65. package/dist/unified-hook.js +155 -31
  66. package/dist/unified-hook.js.map +1 -1
  67. package/package.json +4 -1
@@ -0,0 +1,267 @@
1
+ "use strict";
2
+ /**
3
+ * Port Finder Utility
4
+ *
5
+ * Finds an available port for the genbox-agent server.
6
+ * Uses base port 47191 with automatic fallback to 47192, 47193, etc.
7
+ *
8
+ * Why 47191?
9
+ * - Not in common port lists (IANA, Docker, dev tools)
10
+ * - High enough to avoid privileged range
11
+ * - Memorable pattern: 47-1-91
12
+ * - Unlikely to conflict with other services
13
+ */
14
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ var desc = Object.getOwnPropertyDescriptor(m, k);
17
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
18
+ desc = { enumerable: true, get: function() { return m[k]; } };
19
+ }
20
+ Object.defineProperty(o, k2, desc);
21
+ }) : (function(o, m, k, k2) {
22
+ if (k2 === undefined) k2 = k;
23
+ o[k2] = m[k];
24
+ }));
25
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
26
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
27
+ }) : function(o, v) {
28
+ o["default"] = v;
29
+ });
30
+ var __importStar = (this && this.__importStar) || (function () {
31
+ var ownKeys = function(o) {
32
+ ownKeys = Object.getOwnPropertyNames || function (o) {
33
+ var ar = [];
34
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
35
+ return ar;
36
+ };
37
+ return ownKeys(o);
38
+ };
39
+ return function (mod) {
40
+ if (mod && mod.__esModule) return mod;
41
+ var result = {};
42
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
43
+ __setModuleDefault(result, mod);
44
+ return result;
45
+ };
46
+ })();
47
+ Object.defineProperty(exports, "__esModule", { value: true });
48
+ exports.BASE_PORT = void 0;
49
+ exports.isPortAvailable = isPortAvailable;
50
+ exports.findAvailablePort = findAvailablePort;
51
+ exports.createPortLock = createPortLock;
52
+ exports.removePortLock = removePortLock;
53
+ exports.getLockedPort = getLockedPort;
54
+ exports.findAndLockPort = findAndLockPort;
55
+ exports.cleanupStaleLocks = cleanupStaleLocks;
56
+ const net = __importStar(require("net"));
57
+ const fs = __importStar(require("fs"));
58
+ const path = __importStar(require("path"));
59
+ const os = __importStar(require("os"));
60
+ // Base port for genbox-agent server
61
+ exports.BASE_PORT = 47191;
62
+ // Maximum number of ports to try before giving up
63
+ const MAX_ATTEMPTS = 10;
64
+ // Port lock file directory
65
+ const LOCK_DIR = path.join(os.homedir(), '.genbox', 'locks');
66
+ /**
67
+ * Check if a port is available for binding
68
+ */
69
+ async function isPortAvailable(port, host = '0.0.0.0') {
70
+ return new Promise((resolve) => {
71
+ const server = net.createServer();
72
+ server.once('error', (err) => {
73
+ if (err.code === 'EADDRINUSE' || err.code === 'EACCES') {
74
+ resolve(false);
75
+ }
76
+ else {
77
+ // Other errors - assume port is not usable
78
+ resolve(false);
79
+ }
80
+ });
81
+ server.once('listening', () => {
82
+ server.close(() => {
83
+ resolve(true);
84
+ });
85
+ });
86
+ server.listen(port, host);
87
+ });
88
+ }
89
+ /**
90
+ * Find an available port starting from basePort
91
+ * Returns the first available port, or 0 if none found (let OS assign)
92
+ */
93
+ async function findAvailablePort(basePort = exports.BASE_PORT) {
94
+ for (let offset = 0; offset < MAX_ATTEMPTS; offset++) {
95
+ const port = basePort + offset;
96
+ // Check if port is available
97
+ if (await isPortAvailable(port)) {
98
+ return port;
99
+ }
100
+ console.log(`[port-finder] Port ${port} is in use, trying next...`);
101
+ }
102
+ console.log(`[port-finder] No ports available in range ${basePort}-${basePort + MAX_ATTEMPTS - 1}, using OS-assigned port`);
103
+ return 0; // Let OS assign a random port
104
+ }
105
+ /**
106
+ * Ensure lock directory exists
107
+ */
108
+ function ensureLockDir() {
109
+ if (!fs.existsSync(LOCK_DIR)) {
110
+ fs.mkdirSync(LOCK_DIR, { recursive: true });
111
+ }
112
+ }
113
+ /**
114
+ * Create a lock file for a port (prevents race conditions with other daemon instances)
115
+ */
116
+ function createPortLock(port) {
117
+ ensureLockDir();
118
+ const lockFile = path.join(LOCK_DIR, `port-${port}.lock`);
119
+ try {
120
+ // Check if lock exists and is valid (process still running)
121
+ if (fs.existsSync(lockFile)) {
122
+ const content = fs.readFileSync(lockFile, 'utf8');
123
+ const [pidStr, timestampStr] = content.split(':');
124
+ const pid = parseInt(pidStr, 10);
125
+ // Check if process is still running
126
+ try {
127
+ process.kill(pid, 0); // Signal 0 = check if process exists
128
+ // Process still running, lock is valid
129
+ return false;
130
+ }
131
+ catch {
132
+ // Process not running, lock is stale - remove it
133
+ fs.unlinkSync(lockFile);
134
+ }
135
+ }
136
+ // Create new lock file
137
+ fs.writeFileSync(lockFile, `${process.pid}:${Date.now()}`, { flag: 'wx' });
138
+ return true;
139
+ }
140
+ catch (err) {
141
+ if (err.code === 'EEXIST') {
142
+ // Another process created the lock between our check and write
143
+ return false;
144
+ }
145
+ // Other errors - log and proceed
146
+ console.error(`[port-finder] Failed to create lock file: ${err.message}`);
147
+ return true; // Proceed anyway
148
+ }
149
+ }
150
+ /**
151
+ * Remove port lock file
152
+ */
153
+ function removePortLock(port) {
154
+ const lockFile = path.join(LOCK_DIR, `port-${port}.lock`);
155
+ try {
156
+ if (fs.existsSync(lockFile)) {
157
+ fs.unlinkSync(lockFile);
158
+ }
159
+ }
160
+ catch (err) {
161
+ console.error(`[port-finder] Failed to remove lock file: ${err.message}`);
162
+ }
163
+ }
164
+ /**
165
+ * Get currently locked port by this process (if any)
166
+ * Useful for finding which port the daemon is using
167
+ */
168
+ function getLockedPort() {
169
+ ensureLockDir();
170
+ try {
171
+ const files = fs.readdirSync(LOCK_DIR);
172
+ for (const file of files) {
173
+ if (file.startsWith('port-') && file.endsWith('.lock')) {
174
+ const content = fs.readFileSync(path.join(LOCK_DIR, file), 'utf8');
175
+ const [pidStr] = content.split(':');
176
+ const pid = parseInt(pidStr, 10);
177
+ if (pid === process.pid) {
178
+ const portStr = file.replace('port-', '').replace('.lock', '');
179
+ return parseInt(portStr, 10);
180
+ }
181
+ }
182
+ }
183
+ }
184
+ catch {
185
+ // Ignore errors
186
+ }
187
+ return null;
188
+ }
189
+ /**
190
+ * Find and lock an available port
191
+ * Combines findAvailablePort with createPortLock for atomic operation
192
+ */
193
+ async function findAndLockPort(basePort = exports.BASE_PORT) {
194
+ for (let offset = 0; offset < MAX_ATTEMPTS; offset++) {
195
+ const port = basePort + offset;
196
+ // Try to create lock first (fast path)
197
+ if (!createPortLock(port)) {
198
+ console.log(`[port-finder] Port ${port} is locked by another process, trying next...`);
199
+ continue;
200
+ }
201
+ // Check if port is actually available
202
+ if (await isPortAvailable(port)) {
203
+ console.log(`[port-finder] Successfully locked port ${port}`);
204
+ return port;
205
+ }
206
+ // Port not available, remove our lock and try next
207
+ removePortLock(port);
208
+ console.log(`[port-finder] Port ${port} is in use (no lock), trying next...`);
209
+ }
210
+ // Fallback: let OS assign a port
211
+ console.log(`[port-finder] No ports available in range, requesting OS-assigned port`);
212
+ const osPort = await getOSAssignedPort();
213
+ if (osPort > 0) {
214
+ createPortLock(osPort);
215
+ }
216
+ return osPort;
217
+ }
218
+ /**
219
+ * Get an OS-assigned random available port
220
+ */
221
+ async function getOSAssignedPort() {
222
+ return new Promise((resolve, reject) => {
223
+ const server = net.createServer();
224
+ server.once('error', reject);
225
+ server.once('listening', () => {
226
+ const address = server.address();
227
+ const port = typeof address === 'object' && address ? address.port : 0;
228
+ server.close(() => {
229
+ resolve(port);
230
+ });
231
+ });
232
+ server.listen(0, '0.0.0.0');
233
+ });
234
+ }
235
+ /**
236
+ * Cleanup stale lock files (for maintenance)
237
+ */
238
+ function cleanupStaleLocks() {
239
+ ensureLockDir();
240
+ let cleaned = 0;
241
+ try {
242
+ const files = fs.readdirSync(LOCK_DIR);
243
+ for (const file of files) {
244
+ if (file.startsWith('port-') && file.endsWith('.lock')) {
245
+ const filePath = path.join(LOCK_DIR, file);
246
+ const content = fs.readFileSync(filePath, 'utf8');
247
+ const [pidStr] = content.split(':');
248
+ const pid = parseInt(pidStr, 10);
249
+ // Check if process is still running
250
+ try {
251
+ process.kill(pid, 0);
252
+ // Process still running, leave lock
253
+ }
254
+ catch {
255
+ // Process not running, remove stale lock
256
+ fs.unlinkSync(filePath);
257
+ cleaned++;
258
+ }
259
+ }
260
+ }
261
+ }
262
+ catch (err) {
263
+ console.error(`[port-finder] Error cleaning up stale locks: ${err.message}`);
264
+ }
265
+ return cleaned;
266
+ }
267
+ //# sourceMappingURL=port-finder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"port-finder.js","sourceRoot":"","sources":["../../src/server/port-finder.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmBH,0CAqBC;AAMD,8CAcC;AAcD,wCAmCC;AAKD,wCAUC;AAMD,sCAuBC;AAMD,0CA8BC;AA0BD,8CA+BC;AApPD,yCAA2B;AAC3B,uCAAyB;AACzB,2CAA6B;AAC7B,uCAAyB;AAEzB,oCAAoC;AACvB,QAAA,SAAS,GAAG,KAAK,CAAC;AAE/B,kDAAkD;AAClD,MAAM,YAAY,GAAG,EAAE,CAAC;AAExB,2BAA2B;AAC3B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;AAE7D;;GAEG;AACI,KAAK,UAAU,eAAe,CAAC,IAAY,EAAE,IAAI,GAAG,SAAS;IAClE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,MAAM,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC;QAElC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,GAA0B,EAAE,EAAE;YAClD,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACvD,OAAO,CAAC,KAAK,CAAC,CAAC;YACjB,CAAC;iBAAM,CAAC;gBACN,2CAA2C;gBAC3C,OAAO,CAAC,KAAK,CAAC,CAAC;YACjB,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE;YAC5B,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE;gBAChB,OAAO,CAAC,IAAI,CAAC,CAAC;YAChB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,iBAAiB,CAAC,QAAQ,GAAG,iBAAS;IAC1D,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,YAAY,EAAE,MAAM,EAAE,EAAE,CAAC;QACrD,MAAM,IAAI,GAAG,QAAQ,GAAG,MAAM,CAAC;QAE/B,6BAA6B;QAC7B,IAAI,MAAM,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;YAChC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,4BAA4B,CAAC,CAAC;IACtE,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,6CAA6C,QAAQ,IAAI,QAAQ,GAAG,YAAY,GAAG,CAAC,0BAA0B,CAAC,CAAC;IAC5H,OAAO,CAAC,CAAC,CAAC,8BAA8B;AAC1C,CAAC;AAED;;GAEG;AACH,SAAS,aAAa;IACpB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAgB,cAAc,CAAC,IAAY;IACzC,aAAa,EAAE,CAAC;IAEhB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,IAAI,OAAO,CAAC,CAAC;IAE1D,IAAI,CAAC;QACH,4DAA4D;QAC5D,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAClD,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAClD,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YAEjC,oCAAoC;YACpC,IAAI,CAAC;gBACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,qCAAqC;gBAC3D,uCAAuC;gBACvC,OAAO,KAAK,CAAC;YACf,CAAC;YAAC,MAAM,CAAC;gBACP,iDAAiD;gBACjD,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC;QAED,uBAAuB;QACvB,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3E,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC1B,+DAA+D;YAC/D,OAAO,KAAK,CAAC;QACf,CAAC;QACD,iCAAiC;QACjC,OAAO,CAAC,KAAK,CAAC,6CAA6C,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAC1E,OAAO,IAAI,CAAC,CAAC,iBAAiB;IAChC,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAgB,cAAc,CAAC,IAAY;IACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,IAAI,OAAO,CAAC,CAAC;IAE1D,IAAI,CAAC;QACH,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,6CAA6C,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IAC5E,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAgB,aAAa;IAC3B,aAAa,EAAE,CAAC;IAEhB,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QAEvC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;gBACvD,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;gBACnE,MAAM,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACpC,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;gBAEjC,IAAI,GAAG,KAAK,OAAO,CAAC,GAAG,EAAE,CAAC;oBACxB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;oBAC/D,OAAO,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;gBAC/B,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,gBAAgB;IAClB,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,eAAe,CAAC,QAAQ,GAAG,iBAAS;IACxD,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,YAAY,EAAE,MAAM,EAAE,EAAE,CAAC;QACrD,MAAM,IAAI,GAAG,QAAQ,GAAG,MAAM,CAAC;QAE/B,uCAAuC;QACvC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,+CAA+C,CAAC,CAAC;YACvF,SAAS;QACX,CAAC;QAED,sCAAsC;QACtC,IAAI,MAAM,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,0CAA0C,IAAI,EAAE,CAAC,CAAC;YAC9D,OAAO,IAAI,CAAC;QACd,CAAC;QAED,mDAAmD;QACnD,cAAc,CAAC,IAAI,CAAC,CAAC;QACrB,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,sCAAsC,CAAC,CAAC;IAChF,CAAC;IAED,iCAAiC;IACjC,OAAO,CAAC,GAAG,CAAC,wEAAwE,CAAC,CAAC;IACtF,MAAM,MAAM,GAAG,MAAM,iBAAiB,EAAE,CAAC;IAEzC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QACf,cAAc,CAAC,MAAM,CAAC,CAAC;IACzB,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,iBAAiB;IAC9B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,MAAM,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC;QAElC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAE7B,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE;YAC5B,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;YACjC,MAAM,IAAI,GAAG,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YACvE,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE;gBAChB,OAAO,CAAC,IAAI,CAAC,CAAC;YAChB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,SAAgB,iBAAiB;IAC/B,aAAa,EAAE,CAAC;IAEhB,IAAI,OAAO,GAAG,CAAC,CAAC;IAEhB,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QAEvC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;gBACvD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;gBAC3C,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;gBAClD,MAAM,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACpC,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;gBAEjC,oCAAoC;gBACpC,IAAI,CAAC;oBACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;oBACrB,oCAAoC;gBACtC,CAAC;gBAAC,MAAM,CAAC;oBACP,yCAAyC;oBACzC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;oBACxB,OAAO,EAAE,CAAC;gBACZ,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,gDAAgD,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IAC/E,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Local SQLite Storage
3
+ *
4
+ * Provides persistent storage for sessions, messages, events, and output.
5
+ * Compatible with Session V2 API for seamless cloud sync.
6
+ *
7
+ * Database location: ~/.genbox/data/agent.db
8
+ */
9
+ import Database from 'better-sqlite3';
10
+ export * from './schema';
11
+ /**
12
+ * Storage configuration
13
+ */
14
+ export interface StorageConfig {
15
+ dbPath?: string;
16
+ inMemory?: boolean;
17
+ verbose?: boolean;
18
+ }
19
+ /**
20
+ * Local Storage Manager
21
+ */
22
+ export declare class LocalStorage {
23
+ private db;
24
+ private config;
25
+ constructor(config?: StorageConfig);
26
+ /**
27
+ * Initialize database schema
28
+ */
29
+ private initSchema;
30
+ /**
31
+ * Run migrations
32
+ */
33
+ private migrate;
34
+ /**
35
+ * Get the underlying database instance
36
+ */
37
+ getDb(): Database.Database;
38
+ /**
39
+ * Close the database connection
40
+ */
41
+ close(): void;
42
+ /**
43
+ * Run a transaction
44
+ */
45
+ transaction<T>(fn: () => T): T;
46
+ /**
47
+ * Get database file path
48
+ */
49
+ getPath(): string;
50
+ /**
51
+ * Get database stats
52
+ */
53
+ getStats(): {
54
+ sessions: number;
55
+ messages: number;
56
+ toolUses: number;
57
+ events: number;
58
+ sizeBytes: number;
59
+ };
60
+ /**
61
+ * Get pending sync counts
62
+ */
63
+ getPendingSyncCounts(): {
64
+ sessions: number;
65
+ messages: number;
66
+ toolUses: number;
67
+ events: number;
68
+ };
69
+ /**
70
+ * Vacuum database to reclaim space
71
+ */
72
+ vacuum(): void;
73
+ }
74
+ /**
75
+ * Get or create the storage instance
76
+ */
77
+ export declare function getStorage(config?: StorageConfig): LocalStorage;
78
+ /**
79
+ * Close the storage instance
80
+ */
81
+ export declare function closeStorage(): void;
82
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAOtC,cAAc,UAAU,CAAC;AAMzB;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,EAAE,CAAoB;IAC9B,OAAO,CAAC,MAAM,CAAgB;gBAElB,MAAM,GAAE,aAAkB;IA8BtC;;OAEG;IACH,OAAO,CAAC,UAAU;IAuBlB;;OAEG;IACH,OAAO,CAAC,OAAO;IAQf;;OAEG;IACH,KAAK,IAAI,QAAQ,CAAC,QAAQ;IAI1B;;OAEG;IACH,KAAK,IAAI,IAAI;IAKb;;OAEG;IACH,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC;IAI9B;;OAEG;IACH,OAAO,IAAI,MAAM;IAIjB;;OAEG;IACH,QAAQ,IAAI;QACV,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;KACnB;IAmBD;;OAEG;IACH,oBAAoB,IAAI;QACtB,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;KAChB;IASD;;OAEG;IACH,MAAM,IAAI,IAAI;CAIf;AAKD;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,CAAC,EAAE,aAAa,GAAG,YAAY,CAK/D;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,IAAI,CAKnC"}
@@ -0,0 +1,209 @@
1
+ "use strict";
2
+ /**
3
+ * Local SQLite Storage
4
+ *
5
+ * Provides persistent storage for sessions, messages, events, and output.
6
+ * Compatible with Session V2 API for seamless cloud sync.
7
+ *
8
+ * Database location: ~/.genbox/data/agent.db
9
+ */
10
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ var desc = Object.getOwnPropertyDescriptor(m, k);
13
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
+ desc = { enumerable: true, get: function() { return m[k]; } };
15
+ }
16
+ Object.defineProperty(o, k2, desc);
17
+ }) : (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ o[k2] = m[k];
20
+ }));
21
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
22
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
23
+ }) : function(o, v) {
24
+ o["default"] = v;
25
+ });
26
+ var __importStar = (this && this.__importStar) || (function () {
27
+ var ownKeys = function(o) {
28
+ ownKeys = Object.getOwnPropertyNames || function (o) {
29
+ var ar = [];
30
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
31
+ return ar;
32
+ };
33
+ return ownKeys(o);
34
+ };
35
+ return function (mod) {
36
+ if (mod && mod.__esModule) return mod;
37
+ var result = {};
38
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
39
+ __setModuleDefault(result, mod);
40
+ return result;
41
+ };
42
+ })();
43
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
44
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
45
+ };
46
+ var __importDefault = (this && this.__importDefault) || function (mod) {
47
+ return (mod && mod.__esModule) ? mod : { "default": mod };
48
+ };
49
+ Object.defineProperty(exports, "__esModule", { value: true });
50
+ exports.LocalStorage = void 0;
51
+ exports.getStorage = getStorage;
52
+ exports.closeStorage = closeStorage;
53
+ const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
54
+ const fs = __importStar(require("fs"));
55
+ const path = __importStar(require("path"));
56
+ const os = __importStar(require("os"));
57
+ const schema_1 = require("./schema");
58
+ // Re-export types
59
+ __exportStar(require("./schema"), exports);
60
+ // Default database path
61
+ const DEFAULT_DB_DIR = path.join(os.homedir(), '.genbox', 'data');
62
+ const DEFAULT_DB_PATH = path.join(DEFAULT_DB_DIR, 'agent.db');
63
+ /**
64
+ * Local Storage Manager
65
+ */
66
+ class LocalStorage {
67
+ db;
68
+ config;
69
+ constructor(config = {}) {
70
+ this.config = config;
71
+ // Ensure directory exists
72
+ if (!config.inMemory) {
73
+ const dbPath = config.dbPath || DEFAULT_DB_PATH;
74
+ const dbDir = path.dirname(dbPath);
75
+ if (!fs.existsSync(dbDir)) {
76
+ fs.mkdirSync(dbDir, { recursive: true });
77
+ }
78
+ }
79
+ // Open database
80
+ const dbPath = config.inMemory ? ':memory:' : (config.dbPath || DEFAULT_DB_PATH);
81
+ this.db = new better_sqlite3_1.default(dbPath, {
82
+ verbose: config.verbose ? console.log : undefined,
83
+ });
84
+ // Enable WAL mode for better concurrency
85
+ this.db.pragma('journal_mode = WAL');
86
+ // Enable foreign keys
87
+ this.db.pragma('foreign_keys = ON');
88
+ // Initialize schema
89
+ this.initSchema();
90
+ console.log(`[storage] Database initialized at ${dbPath}`);
91
+ }
92
+ /**
93
+ * Initialize database schema
94
+ */
95
+ initSchema() {
96
+ // Check current schema version
97
+ const hasVersionTable = this.db.prepare(`
98
+ SELECT name FROM sqlite_master
99
+ WHERE type='table' AND name='schema_version'
100
+ `).get();
101
+ if (!hasVersionTable) {
102
+ // Fresh database - create all tables
103
+ this.db.exec(schema_1.SCHEMA_SQL);
104
+ this.db.prepare('INSERT INTO schema_version (version) VALUES (?)').run(schema_1.SCHEMA_VERSION);
105
+ console.log(`[storage] Schema created (version ${schema_1.SCHEMA_VERSION})`);
106
+ }
107
+ else {
108
+ // Check if migration needed
109
+ const row = this.db.prepare('SELECT MAX(version) as version FROM schema_version').get();
110
+ const currentVersion = row?.version || 0;
111
+ if (currentVersion < schema_1.SCHEMA_VERSION) {
112
+ this.migrate(currentVersion, schema_1.SCHEMA_VERSION);
113
+ }
114
+ }
115
+ }
116
+ /**
117
+ * Run migrations
118
+ */
119
+ migrate(fromVersion, toVersion) {
120
+ console.log(`[storage] Migrating from version ${fromVersion} to ${toVersion}`);
121
+ // Add migration logic here as schema evolves
122
+ // For now, just update version
123
+ this.db.prepare('INSERT INTO schema_version (version) VALUES (?)').run(toVersion);
124
+ }
125
+ /**
126
+ * Get the underlying database instance
127
+ */
128
+ getDb() {
129
+ return this.db;
130
+ }
131
+ /**
132
+ * Close the database connection
133
+ */
134
+ close() {
135
+ this.db.close();
136
+ console.log('[storage] Database closed');
137
+ }
138
+ /**
139
+ * Run a transaction
140
+ */
141
+ transaction(fn) {
142
+ return this.db.transaction(fn)();
143
+ }
144
+ /**
145
+ * Get database file path
146
+ */
147
+ getPath() {
148
+ return this.config.dbPath || DEFAULT_DB_PATH;
149
+ }
150
+ /**
151
+ * Get database stats
152
+ */
153
+ getStats() {
154
+ const sessions = this.db.prepare('SELECT COUNT(*) as count FROM sessions').get().count;
155
+ const messages = this.db.prepare('SELECT COUNT(*) as count FROM messages').get().count;
156
+ const toolUses = this.db.prepare('SELECT COUNT(*) as count FROM tool_uses').get().count;
157
+ const events = this.db.prepare('SELECT COUNT(*) as count FROM events').get().count;
158
+ let sizeBytes = 0;
159
+ if (!this.config.inMemory) {
160
+ try {
161
+ const stat = fs.statSync(this.getPath());
162
+ sizeBytes = stat.size;
163
+ }
164
+ catch {
165
+ // Ignore
166
+ }
167
+ }
168
+ return { sessions, messages, toolUses, events, sizeBytes };
169
+ }
170
+ /**
171
+ * Get pending sync counts
172
+ */
173
+ getPendingSyncCounts() {
174
+ const sessions = this.db.prepare('SELECT COUNT(*) as count FROM sessions WHERE sync_pending = 1').get().count;
175
+ const messages = this.db.prepare('SELECT COUNT(*) as count FROM messages WHERE sync_pending = 1').get().count;
176
+ const toolUses = this.db.prepare('SELECT COUNT(*) as count FROM tool_uses WHERE sync_pending = 1').get().count;
177
+ const events = this.db.prepare('SELECT COUNT(*) as count FROM events WHERE sync_pending = 1').get().count;
178
+ return { sessions, messages, toolUses, events };
179
+ }
180
+ /**
181
+ * Vacuum database to reclaim space
182
+ */
183
+ vacuum() {
184
+ this.db.exec('VACUUM');
185
+ console.log('[storage] Database vacuumed');
186
+ }
187
+ }
188
+ exports.LocalStorage = LocalStorage;
189
+ // Singleton instance
190
+ let storageInstance = null;
191
+ /**
192
+ * Get or create the storage instance
193
+ */
194
+ function getStorage(config) {
195
+ if (!storageInstance) {
196
+ storageInstance = new LocalStorage(config);
197
+ }
198
+ return storageInstance;
199
+ }
200
+ /**
201
+ * Close the storage instance
202
+ */
203
+ function closeStorage() {
204
+ if (storageInstance) {
205
+ storageInstance.close();
206
+ storageInstance = null;
207
+ }
208
+ }
209
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"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"}