10x-chat 0.8.3 → 0.9.1

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 (42) hide show
  1. package/dist/browser/daemon.d.ts +22 -29
  2. package/dist/browser/daemon.d.ts.map +1 -1
  3. package/dist/browser/daemon.js +500 -61
  4. package/dist/browser/daemon.js.map +1 -1
  5. package/dist/browser/manager.d.ts.map +1 -1
  6. package/dist/browser/manager.js +8 -53
  7. package/dist/browser/manager.js.map +1 -1
  8. package/dist/browser/page-utils.d.ts +4 -0
  9. package/dist/browser/page-utils.d.ts.map +1 -0
  10. package/dist/browser/page-utils.js +37 -0
  11. package/dist/browser/page-utils.js.map +1 -0
  12. package/dist/browser/server.d.ts +2 -0
  13. package/dist/browser/server.d.ts.map +1 -0
  14. package/dist/browser/server.js +510 -0
  15. package/dist/browser/server.js.map +1 -0
  16. package/dist/browser/tabs.d.ts +2 -16
  17. package/dist/browser/tabs.d.ts.map +1 -1
  18. package/dist/browser/tabs.js +6 -80
  19. package/dist/browser/tabs.js.map +1 -1
  20. package/dist/core/research-orchestrator.d.ts.map +1 -1
  21. package/dist/core/research-orchestrator.js +2 -3
  22. package/dist/core/research-orchestrator.js.map +1 -1
  23. package/dist/notebooklm/rpc/decoder.d.ts +1 -1
  24. package/dist/notebooklm/rpc/decoder.d.ts.map +1 -1
  25. package/dist/notebooklm/rpc/decoder.js +1 -1
  26. package/dist/notebooklm/rpc/decoder.js.map +1 -1
  27. package/dist/notebooklm/types.d.ts +1 -2
  28. package/dist/notebooklm/types.d.ts.map +1 -1
  29. package/dist/notebooklm/types.js +1 -2
  30. package/dist/notebooklm/types.js.map +1 -1
  31. package/dist/providers/claude.d.ts +1 -0
  32. package/dist/providers/claude.d.ts.map +1 -1
  33. package/dist/providers/claude.js +60 -1
  34. package/dist/providers/claude.js.map +1 -1
  35. package/dist/providers/grok.d.ts.map +1 -1
  36. package/dist/providers/grok.js +2 -3
  37. package/dist/providers/grok.js.map +1 -1
  38. package/dist/providers/perplexity.d.ts.map +1 -1
  39. package/dist/providers/perplexity.js +2 -5
  40. package/dist/providers/perplexity.js.map +1 -1
  41. package/package.json +1 -1
  42. package/skills/10x-chat/SKILL.md +98 -55
@@ -0,0 +1,510 @@
1
+ // HTTP daemon architecture inspired by gstack (github.com/garrytan/gstack)
2
+ import { randomUUID } from 'node:crypto';
3
+ import { chmod, mkdir, rename, rm, writeFile } from 'node:fs/promises';
4
+ import { createServer } from 'node:http';
5
+ import path from 'node:path';
6
+ import { chromium, } from 'playwright';
7
+ import { getAppDir } from '../paths.js';
8
+ import { CHROMIUM_ARGS } from './process.js';
9
+ const STATE_PATH = process.env.TEN_X_CHAT_BROWSER_STATE_FILE ?? path.join(getAppDir(), 'browser-daemon.json');
10
+ const AUTH_TOKEN = randomUUID();
11
+ const HEADLESS = process.env.TEN_X_CHAT_BROWSER_HEADLESS !== '0';
12
+ const IDLE_TIMEOUT_MS = 30 * 60 * 1000;
13
+ const MIN_PORT = 10_000;
14
+ const MAX_PORT = 60_000;
15
+ let browser = null;
16
+ let lastActivity = Date.now();
17
+ let activePageCount = 0;
18
+ let shuttingDown = false;
19
+ const contexts = new Map();
20
+ const pages = new Map();
21
+ const manualTabs = new Set();
22
+ const fileChoosers = new Map();
23
+ const downloads = new Map();
24
+ function touchActivity() {
25
+ lastActivity = Date.now();
26
+ }
27
+ function serializeValue(value) {
28
+ if (value === undefined)
29
+ return null;
30
+ return value;
31
+ }
32
+ function deserializeValue(value) {
33
+ if (value && typeof value === 'object') {
34
+ if ('__type' in value && value.__type === 'regexp') {
35
+ return new RegExp(String(value.source), String(value.flags));
36
+ }
37
+ if ('__type' in value && value.__type === 'function') {
38
+ return new Function(`return (${value.source});`)();
39
+ }
40
+ if (Array.isArray(value)) {
41
+ return value.map((entry) => deserializeValue(entry));
42
+ }
43
+ return Object.fromEntries(Object.entries(value).map(([key, entry]) => [
44
+ key,
45
+ deserializeValue(entry),
46
+ ]));
47
+ }
48
+ return value;
49
+ }
50
+ function toContextHandle(contextId) {
51
+ return {
52
+ __handle: true,
53
+ handleType: 'context',
54
+ id: contextId,
55
+ };
56
+ }
57
+ function toPageHandle(pageId, contextId, page) {
58
+ return {
59
+ __handle: true,
60
+ handleType: 'page',
61
+ id: pageId,
62
+ contextId,
63
+ pageId,
64
+ url: page.url(),
65
+ };
66
+ }
67
+ function toFileChooserHandle(eventId) {
68
+ return {
69
+ __handle: true,
70
+ handleType: 'filechooser',
71
+ id: eventId,
72
+ };
73
+ }
74
+ function toDownloadHandle(eventId, download) {
75
+ return {
76
+ __handle: true,
77
+ handleType: 'download',
78
+ id: eventId,
79
+ suggestedFilename: download.suggestedFilename(),
80
+ };
81
+ }
82
+ async function writeStateFile(port) {
83
+ const state = {
84
+ pid: process.pid,
85
+ port,
86
+ token: AUTH_TOKEN,
87
+ headless: HEADLESS,
88
+ createdAt: new Date().toISOString(),
89
+ };
90
+ await mkdir(path.dirname(STATE_PATH), { recursive: true });
91
+ const tmpPath = `${STATE_PATH}.${process.pid}.tmp`;
92
+ await writeFile(tmpPath, JSON.stringify(state, null, 2), { mode: 0o600 });
93
+ await rename(tmpPath, STATE_PATH);
94
+ await chmod(STATE_PATH, 0o600).catch(() => {
95
+ // ignore chmod failures
96
+ });
97
+ }
98
+ async function clearStateFile() {
99
+ await rm(STATE_PATH, { force: true }).catch(() => {
100
+ // ignore
101
+ });
102
+ }
103
+ async function findPort() {
104
+ for (let attempt = 0; attempt < 20; attempt++) {
105
+ const port = MIN_PORT + Math.floor(Math.random() * (MAX_PORT - MIN_PORT + 1));
106
+ const available = await new Promise((resolve) => {
107
+ const tester = createServer();
108
+ tester.once('error', () => resolve(false));
109
+ tester.once('listening', () => {
110
+ tester.close(() => resolve(true));
111
+ });
112
+ tester.listen(port, '127.0.0.1');
113
+ });
114
+ if (available)
115
+ return port;
116
+ }
117
+ throw new Error(`Unable to find an available port in range ${MIN_PORT}-${MAX_PORT}`);
118
+ }
119
+ function getContext(contextId) {
120
+ if (!contextId) {
121
+ throw new Error('Missing contextId');
122
+ }
123
+ const context = contexts.get(contextId);
124
+ if (!context) {
125
+ throw new Error(`Context not found: ${contextId}`);
126
+ }
127
+ return context;
128
+ }
129
+ function getPage(pageId) {
130
+ if (!pageId) {
131
+ throw new Error('Missing pageId');
132
+ }
133
+ const page = pages.get(pageId);
134
+ if (!page) {
135
+ throw new Error(`Page not found: ${pageId}`);
136
+ }
137
+ return page;
138
+ }
139
+ function resolveLocator(page, steps) {
140
+ if (!steps || steps.length === 0) {
141
+ throw new Error('Missing locator steps');
142
+ }
143
+ let current = page;
144
+ for (const step of steps) {
145
+ switch (step.type) {
146
+ case 'locator':
147
+ current = current.locator(step.selector);
148
+ break;
149
+ case 'getByRole':
150
+ current = current.getByRole(step.role, deserializeValue(step.options ?? {}));
151
+ break;
152
+ case 'first':
153
+ current = current.first();
154
+ break;
155
+ case 'last':
156
+ current = current.last();
157
+ break;
158
+ case 'nth':
159
+ current = current.nth(step.index);
160
+ break;
161
+ }
162
+ }
163
+ return current;
164
+ }
165
+ function buildPageState(pageId) {
166
+ const entry = pages.get(pageId);
167
+ return {
168
+ pageId,
169
+ url: entry?.page.url() ?? 'about:blank',
170
+ };
171
+ }
172
+ function attachPage(page, contextId) {
173
+ const pageId = randomUUID();
174
+ pages.set(pageId, { page, contextId });
175
+ activePageCount++;
176
+ page.on('close', () => {
177
+ if (pages.delete(pageId)) {
178
+ activePageCount = Math.max(0, activePageCount - 1);
179
+ }
180
+ });
181
+ return pageId;
182
+ }
183
+ async function handleRpc(body) {
184
+ const args = (body.args ?? []).map((arg) => deserializeValue(arg));
185
+ switch (body.kind) {
186
+ case 'browser': {
187
+ if (!browser)
188
+ throw new Error('Browser is not available');
189
+ if (body.method !== 'newContext') {
190
+ throw new Error(`Unsupported browser method: ${body.method}`);
191
+ }
192
+ const context = await browser.newContext(args[0] ?? {});
193
+ const contextId = randomUUID();
194
+ contexts.set(contextId, context);
195
+ return { ok: true, result: toContextHandle(contextId) };
196
+ }
197
+ case 'context': {
198
+ const context = getContext(body.target?.contextId);
199
+ if (body.method === 'newPage') {
200
+ const page = await context.newPage();
201
+ const pageId = attachPage(page, body.target?.contextId ?? '');
202
+ return {
203
+ ok: true,
204
+ result: toPageHandle(pageId, body.target?.contextId ?? '', page),
205
+ pageState: buildPageState(pageId),
206
+ };
207
+ }
208
+ if (body.method === 'close') {
209
+ await context.close();
210
+ contexts.delete(body.target?.contextId ?? '');
211
+ return { ok: true, result: null };
212
+ }
213
+ if (body.method === 'storageState') {
214
+ const options = args[0] ?? {};
215
+ const result = await context.storageState(options);
216
+ return { ok: true, result: serializeValue(result) };
217
+ }
218
+ if (body.method === 'cookies') {
219
+ const result = await context.cookies(args[0] ?? []);
220
+ return { ok: true, result: serializeValue(result) };
221
+ }
222
+ throw new Error(`Unsupported context method: ${body.method}`);
223
+ }
224
+ case 'page': {
225
+ const { page } = getPage(body.target?.pageId);
226
+ const pageId = body.target?.pageId ?? '';
227
+ switch (body.method) {
228
+ case 'goto':
229
+ await page.goto(args[0], args[1] ?? {});
230
+ return { ok: true, result: null, pageState: buildPageState(pageId) };
231
+ case 'waitForTimeout':
232
+ await page.waitForTimeout(Number(args[0] ?? 0));
233
+ return { ok: true, result: null, pageState: buildPageState(pageId) };
234
+ case 'waitForLoadState':
235
+ await page.waitForLoadState(args[0] ?? 'load');
236
+ return { ok: true, result: null, pageState: buildPageState(pageId) };
237
+ case 'waitForURL': {
238
+ const matcher = args[0];
239
+ const options = args[1] ?? {};
240
+ if (typeof matcher === 'string' || matcher instanceof RegExp) {
241
+ await page.waitForURL(matcher, options);
242
+ }
243
+ else if (matcher && typeof matcher === 'object') {
244
+ const predicate = matcher;
245
+ if (predicate.mode === 'changes') {
246
+ await page.waitForURL((url) => url.toString() !== predicate.value, options);
247
+ }
248
+ else if (predicate.mode === 'startsWith') {
249
+ await page.waitForURL((url) => url.pathname.startsWith(predicate.value ?? ''), options);
250
+ }
251
+ else {
252
+ throw new Error('Unsupported waitForURL predicate');
253
+ }
254
+ }
255
+ else {
256
+ throw new Error('Unsupported waitForURL matcher');
257
+ }
258
+ return { ok: true, result: null, pageState: buildPageState(pageId) };
259
+ }
260
+ case 'waitForEvent': {
261
+ const eventName = String(args[0] ?? '');
262
+ const options = args[1] ?? {};
263
+ if (eventName === 'filechooser') {
264
+ const fileChooser = await page.waitForEvent('filechooser', options);
265
+ const eventId = randomUUID();
266
+ fileChoosers.set(eventId, fileChooser);
267
+ return {
268
+ ok: true,
269
+ result: toFileChooserHandle(eventId),
270
+ pageState: buildPageState(pageId),
271
+ };
272
+ }
273
+ if (eventName === 'download') {
274
+ const download = await page.waitForEvent('download', options);
275
+ const eventId = randomUUID();
276
+ downloads.set(eventId, download);
277
+ return {
278
+ ok: true,
279
+ result: toDownloadHandle(eventId, download),
280
+ pageState: buildPageState(pageId),
281
+ };
282
+ }
283
+ throw new Error(`Unsupported page event: ${eventName}`);
284
+ }
285
+ case 'evaluate': {
286
+ const pageFunction = args[0];
287
+ const arg = args[1];
288
+ let result;
289
+ if (typeof pageFunction === 'string') {
290
+ result = await page.evaluate(pageFunction);
291
+ }
292
+ else if (typeof pageFunction === 'function') {
293
+ result = await page.evaluate(pageFunction, arg);
294
+ }
295
+ else {
296
+ throw new Error('Unsupported evaluate payload');
297
+ }
298
+ return { ok: true, result: serializeValue(result), pageState: buildPageState(pageId) };
299
+ }
300
+ case 'close':
301
+ await page.close();
302
+ return { ok: true, result: null, pageState: { pageId, url: 'about:blank' } };
303
+ case 'title': {
304
+ const result = await page.title();
305
+ return { ok: true, result, pageState: buildPageState(pageId) };
306
+ }
307
+ default:
308
+ throw new Error(`Unsupported page method: ${body.method}`);
309
+ }
310
+ }
311
+ case 'keyboard': {
312
+ const { page } = getPage(body.target?.pageId);
313
+ const pageId = body.target?.pageId ?? '';
314
+ if (body.method === 'press') {
315
+ await page.keyboard.press(args[0], args[1] ?? {});
316
+ return { ok: true, result: null, pageState: buildPageState(pageId) };
317
+ }
318
+ if (body.method === 'type') {
319
+ await page.keyboard.type(args[0], args[1] ?? {});
320
+ return { ok: true, result: null, pageState: buildPageState(pageId) };
321
+ }
322
+ throw new Error(`Unsupported keyboard method: ${body.method}`);
323
+ }
324
+ case 'locator': {
325
+ const { page } = getPage(body.target?.pageId);
326
+ const pageId = body.target?.pageId ?? '';
327
+ const locator = resolveLocator(page, body.target?.steps);
328
+ switch (body.method) {
329
+ case 'waitFor':
330
+ await locator.waitFor((args[0] ?? {}));
331
+ return { ok: true, result: null, pageState: buildPageState(pageId) };
332
+ case 'isVisible': {
333
+ const result = await locator.isVisible((args[0] ?? {}));
334
+ return { ok: true, result, pageState: buildPageState(pageId) };
335
+ }
336
+ case 'click':
337
+ await locator.click((args[0] ?? {}));
338
+ return { ok: true, result: null, pageState: buildPageState(pageId) };
339
+ case 'fill':
340
+ await locator.fill(String(args[0] ?? ''));
341
+ return { ok: true, result: null, pageState: buildPageState(pageId) };
342
+ case 'count': {
343
+ const result = await locator.count();
344
+ return { ok: true, result, pageState: buildPageState(pageId) };
345
+ }
346
+ case 'textContent': {
347
+ const result = await locator.textContent((args[0] ?? {}));
348
+ return { ok: true, result: serializeValue(result), pageState: buildPageState(pageId) };
349
+ }
350
+ case 'innerHTML': {
351
+ const result = await locator.innerHTML((args[0] ?? {}));
352
+ return { ok: true, result, pageState: buildPageState(pageId) };
353
+ }
354
+ case 'setInputFiles':
355
+ await locator.setInputFiles(args[0] ?? []);
356
+ return { ok: true, result: null, pageState: buildPageState(pageId) };
357
+ default:
358
+ throw new Error(`Unsupported locator method: ${body.method}`);
359
+ }
360
+ }
361
+ case 'tabs': {
362
+ if (body.method === 'register') {
363
+ const tabKey = String(args[0] ?? randomUUID());
364
+ manualTabs.add(tabKey);
365
+ return { ok: true, result: tabKey };
366
+ }
367
+ if (body.method === 'unregister') {
368
+ manualTabs.delete(String(args[0] ?? ''));
369
+ return { ok: true, result: Math.max(manualTabs.size, activePageCount) };
370
+ }
371
+ throw new Error(`Unsupported tabs method: ${body.method}`);
372
+ }
373
+ case 'event': {
374
+ if (body.method === 'setFiles') {
375
+ const chooser = fileChoosers.get(body.target?.eventId ?? '');
376
+ if (!chooser)
377
+ throw new Error('File chooser not found');
378
+ await chooser.setFiles(args[0] ?? []);
379
+ fileChoosers.delete(body.target?.eventId ?? '');
380
+ return { ok: true, result: null };
381
+ }
382
+ if (body.method === 'saveAs') {
383
+ const download = downloads.get(body.target?.eventId ?? '');
384
+ if (!download)
385
+ throw new Error('Download not found');
386
+ await download.saveAs(String(args[0] ?? ''));
387
+ downloads.delete(body.target?.eventId ?? '');
388
+ return { ok: true, result: null };
389
+ }
390
+ throw new Error(`Unsupported event method: ${body.method}`);
391
+ }
392
+ }
393
+ }
394
+ async function shutdown(server) {
395
+ if (shuttingDown)
396
+ return;
397
+ shuttingDown = true;
398
+ await clearStateFile();
399
+ // Close browser first — this aborts any pending Playwright actions, which
400
+ // unblocks any active long-poll HTTP connections to the server.
401
+ // Add a hard 3s timeout: browser.close() can hang if Playwright's IPC
402
+ // channel is already broken (e.g. Chrome crashed or was kill -9'd).
403
+ if (browser) {
404
+ browser.removeAllListeners('disconnected');
405
+ await Promise.race([
406
+ browser.close().catch(() => { }),
407
+ new Promise((resolve) => setTimeout(resolve, 3000)),
408
+ ]);
409
+ }
410
+ // Stop accepting new connections. Active connections will have been aborted
411
+ // by browser.close() above, so this resolves quickly. We add a 2s hard
412
+ // timeout so a stuck connection never prevents the process from exiting.
413
+ if (server) {
414
+ await Promise.race([
415
+ new Promise((resolve) => {
416
+ server.close(() => resolve());
417
+ }),
418
+ new Promise((resolve) => setTimeout(resolve, 2000)),
419
+ ]).catch(() => {
420
+ // ignore
421
+ });
422
+ }
423
+ process.exit(0);
424
+ }
425
+ async function readJsonBody(req) {
426
+ const chunks = [];
427
+ for await (const chunk of req) {
428
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
429
+ }
430
+ if (chunks.length === 0)
431
+ return {};
432
+ return JSON.parse(Buffer.concat(chunks).toString('utf-8'));
433
+ }
434
+ async function main() {
435
+ browser = await chromium.launch({
436
+ headless: HEADLESS,
437
+ args: CHROMIUM_ARGS,
438
+ });
439
+ browser.on('disconnected', () => {
440
+ void clearStateFile().finally(() => process.exit(1));
441
+ });
442
+ const idleInterval = setInterval(() => {
443
+ if (Date.now() - lastActivity > IDLE_TIMEOUT_MS) {
444
+ void shutdown(server);
445
+ }
446
+ }, 60_000);
447
+ idleInterval.unref();
448
+ const port = await findPort();
449
+ const server = createServer(async (req, res) => {
450
+ const authHeader = req.headers.authorization;
451
+ if (authHeader !== `Bearer ${AUTH_TOKEN}`) {
452
+ res.writeHead(401, { 'Content-Type': 'application/json' });
453
+ res.end(JSON.stringify({ ok: false, error: 'Unauthorized' }));
454
+ return;
455
+ }
456
+ if (req.method === 'GET' && req.url === '/health') {
457
+ res.writeHead(200, { 'Content-Type': 'application/json' });
458
+ res.end(JSON.stringify({
459
+ ok: true,
460
+ activeTabs: Math.max(manualTabs.size, activePageCount),
461
+ headless: HEADLESS,
462
+ pid: process.pid,
463
+ }));
464
+ return;
465
+ }
466
+ if (req.method === 'POST' && req.url === '/stop') {
467
+ res.writeHead(200, { 'Content-Type': 'application/json' });
468
+ res.end(JSON.stringify({ ok: true }));
469
+ setTimeout(() => {
470
+ void shutdown(server);
471
+ }, 0);
472
+ return;
473
+ }
474
+ if (req.method !== 'POST' || req.url !== '/rpc') {
475
+ res.writeHead(404, { 'Content-Type': 'application/json' });
476
+ res.end(JSON.stringify({ ok: false, error: 'Not found' }));
477
+ return;
478
+ }
479
+ touchActivity();
480
+ try {
481
+ const body = (await readJsonBody(req));
482
+ const response = await handleRpc(body);
483
+ res.writeHead(200, { 'Content-Type': 'application/json' });
484
+ res.end(JSON.stringify(response));
485
+ }
486
+ catch (error) {
487
+ res.writeHead(500, { 'Content-Type': 'application/json' });
488
+ res.end(JSON.stringify({
489
+ ok: false,
490
+ error: error instanceof Error ? error.message : String(error),
491
+ }));
492
+ }
493
+ });
494
+ await new Promise((resolve, reject) => {
495
+ server.once('error', reject);
496
+ server.listen(port, '127.0.0.1', () => resolve());
497
+ });
498
+ await writeStateFile(port);
499
+ const cleanup = () => {
500
+ void shutdown(server);
501
+ };
502
+ process.on('SIGINT', cleanup);
503
+ process.on('SIGTERM', cleanup);
504
+ }
505
+ void main().catch(async (error) => {
506
+ console.error(error instanceof Error ? error.message : String(error));
507
+ await clearStateFile();
508
+ process.exit(1);
509
+ });
510
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/browser/server.ts"],"names":[],"mappings":"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"}
@@ -1,22 +1,8 @@
1
1
  /**
2
- * Browser tab ref-counting via filesystem.
3
- *
4
- * Each active CLI session writes a file to ~/.10x-chat/browser-tabs/.
5
- * Filename: <pid>-<uuid>.tab
6
- *
7
- * On open: registerTab() → writes file, returns tabKey
8
- * On close: unregisterTab() → deletes file, returns remaining live count
9
- *
10
- * Stale tab files from crashed processes are cleaned up automatically
11
- * by checking PID liveness during unregister.
2
+ * Shared browser tab ref-counting is handled by the HTTP daemon.
3
+ * These wrappers keep the public API stable.
12
4
  */
13
- /** Register a new tab. Returns a tabKey to pass to unregisterTab(). */
14
5
  export declare function registerTab(): Promise<string>;
15
- /**
16
- * Unregister a tab and return the remaining live tab count.
17
- * Stale files from dead processes are cleaned up during this call.
18
- */
19
6
  export declare function unregisterTab(tabKey: string): Promise<number>;
20
- /** Get current live tab count without modifying anything. */
21
7
  export declare function getLiveTabCount(): Promise<number>;
22
8
  //# sourceMappingURL=tabs.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tabs.d.ts","sourceRoot":"","sources":["../../src/browser/tabs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAcH,uEAAuE;AACvE,wBAAsB,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CAanD;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAiCnE;AAED,6DAA6D;AAC7D,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,CAcvD"}
1
+ {"version":3,"file":"tabs.d.ts","sourceRoot":"","sources":["../../src/browser/tabs.ts"],"names":[],"mappings":"AAEA;;;GAGG;AAEH,wBAAsB,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CAEnD;AAED,wBAAsB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAEnE;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,CAEvD"}
@@ -1,89 +1,15 @@
1
+ import { readLiveTabCount, registerDaemonTab, unregisterDaemonTab } from './daemon.js';
1
2
  /**
2
- * Browser tab ref-counting via filesystem.
3
- *
4
- * Each active CLI session writes a file to ~/.10x-chat/browser-tabs/.
5
- * Filename: <pid>-<uuid>.tab
6
- *
7
- * On open: registerTab() → writes file, returns tabKey
8
- * On close: unregisterTab() → deletes file, returns remaining live count
9
- *
10
- * Stale tab files from crashed processes are cleaned up automatically
11
- * by checking PID liveness during unregister.
3
+ * Shared browser tab ref-counting is handled by the HTTP daemon.
4
+ * These wrappers keep the public API stable.
12
5
  */
13
- import { randomUUID } from 'node:crypto';
14
- import { mkdir, readdir, rm, writeFile } from 'node:fs/promises';
15
- import path from 'node:path';
16
- import { getAppDir } from '../paths.js';
17
- import { isProcessAlive } from './process.js';
18
- const TABS_DIR = 'browser-tabs';
19
- function getTabsDir() {
20
- return path.join(getAppDir(), TABS_DIR);
21
- }
22
- /** Register a new tab. Returns a tabKey to pass to unregisterTab(). */
23
6
  export async function registerTab() {
24
- const dir = getTabsDir();
25
- await mkdir(dir, { recursive: true });
26
- const tabId = randomUUID();
27
- const tabKey = `${process.pid}-${tabId}`;
28
- const filePath = path.join(dir, `${tabKey}.tab`);
29
- await writeFile(filePath, JSON.stringify({ pid: process.pid, tabId, createdAt: new Date().toISOString() }));
30
- return tabKey;
7
+ return registerDaemonTab();
31
8
  }
32
- /**
33
- * Unregister a tab and return the remaining live tab count.
34
- * Stale files from dead processes are cleaned up during this call.
35
- */
36
9
  export async function unregisterTab(tabKey) {
37
- const dir = getTabsDir();
38
- // Remove this tab's file
39
- try {
40
- await rm(path.join(dir, `${tabKey}.tab`), { force: true });
41
- }
42
- catch {
43
- // already gone
44
- }
45
- // Count remaining live tabs, cleaning up stale ones
46
- try {
47
- const files = await readdir(dir);
48
- const tabFiles = files.filter((f) => f.endsWith('.tab'));
49
- let liveCount = 0;
50
- for (const f of tabFiles) {
51
- const pid = Number.parseInt(f.split('-')[0], 10);
52
- if (Number.isNaN(pid) || !isProcessAlive(pid)) {
53
- // Stale — clean up
54
- try {
55
- await rm(path.join(dir, f), { force: true });
56
- }
57
- catch {
58
- // ignore
59
- }
60
- }
61
- else {
62
- liveCount++;
63
- }
64
- }
65
- return liveCount;
66
- }
67
- catch {
68
- return 0;
69
- }
10
+ return unregisterDaemonTab(tabKey);
70
11
  }
71
- /** Get current live tab count without modifying anything. */
72
12
  export async function getLiveTabCount() {
73
- const dir = getTabsDir();
74
- try {
75
- const files = await readdir(dir);
76
- const tabFiles = files.filter((f) => f.endsWith('.tab'));
77
- let count = 0;
78
- for (const f of tabFiles) {
79
- const pid = Number.parseInt(f.split('-')[0], 10);
80
- if (!Number.isNaN(pid) && isProcessAlive(pid))
81
- count++;
82
- }
83
- return count;
84
- }
85
- catch {
86
- return 0;
87
- }
13
+ return readLiveTabCount();
88
14
  }
89
15
  //# sourceMappingURL=tabs.js.map