@ytspar/sweetlink 1.13.0 → 1.15.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 (100) hide show
  1. package/README.md +294 -40
  2. package/claude-skills/screenshot/SKILL.md +141 -20
  3. package/dist/cli/outputSchemas.d.ts +16 -0
  4. package/dist/cli/outputSchemas.d.ts.map +1 -1
  5. package/dist/cli/outputSchemas.js +33 -0
  6. package/dist/cli/outputSchemas.js.map +1 -1
  7. package/dist/cli/sweetlink-dev.js +0 -0
  8. package/dist/cli/sweetlink.js +639 -11
  9. package/dist/cli/sweetlink.js.map +1 -1
  10. package/dist/daemon/browser.d.ts +58 -0
  11. package/dist/daemon/browser.d.ts.map +1 -0
  12. package/dist/daemon/browser.js +172 -0
  13. package/dist/daemon/browser.js.map +1 -0
  14. package/dist/daemon/client.d.ts +34 -0
  15. package/dist/daemon/client.d.ts.map +1 -0
  16. package/dist/daemon/client.js +139 -0
  17. package/dist/daemon/client.js.map +1 -0
  18. package/dist/daemon/cursor.d.ts +15 -0
  19. package/dist/daemon/cursor.d.ts.map +1 -0
  20. package/dist/daemon/cursor.js +76 -0
  21. package/dist/daemon/cursor.js.map +1 -0
  22. package/dist/daemon/demo.d.ts +68 -0
  23. package/dist/daemon/demo.d.ts.map +1 -0
  24. package/dist/daemon/demo.js +247 -0
  25. package/dist/daemon/demo.js.map +1 -0
  26. package/dist/daemon/devices.d.ts +39 -0
  27. package/dist/daemon/devices.d.ts.map +1 -0
  28. package/dist/daemon/devices.js +101 -0
  29. package/dist/daemon/devices.js.map +1 -0
  30. package/dist/daemon/diff.d.ts +20 -0
  31. package/dist/daemon/diff.d.ts.map +1 -0
  32. package/dist/daemon/diff.js +181 -0
  33. package/dist/daemon/diff.js.map +1 -0
  34. package/dist/daemon/errorPatterns.d.ts +17 -0
  35. package/dist/daemon/errorPatterns.d.ts.map +1 -0
  36. package/dist/daemon/errorPatterns.js +81 -0
  37. package/dist/daemon/errorPatterns.js.map +1 -0
  38. package/dist/daemon/evidence.d.ts +29 -0
  39. package/dist/daemon/evidence.d.ts.map +1 -0
  40. package/dist/daemon/evidence.js +131 -0
  41. package/dist/daemon/evidence.js.map +1 -0
  42. package/dist/daemon/index.d.ts +10 -0
  43. package/dist/daemon/index.d.ts.map +1 -0
  44. package/dist/daemon/index.js +102 -0
  45. package/dist/daemon/index.js.map +1 -0
  46. package/dist/daemon/listeners.d.ts +55 -0
  47. package/dist/daemon/listeners.d.ts.map +1 -0
  48. package/dist/daemon/listeners.js +129 -0
  49. package/dist/daemon/listeners.js.map +1 -0
  50. package/dist/daemon/recording.d.ts +54 -0
  51. package/dist/daemon/recording.d.ts.map +1 -0
  52. package/dist/daemon/recording.js +216 -0
  53. package/dist/daemon/recording.js.map +1 -0
  54. package/dist/daemon/refs.d.ts +70 -0
  55. package/dist/daemon/refs.d.ts.map +1 -0
  56. package/dist/daemon/refs.js +185 -0
  57. package/dist/daemon/refs.js.map +1 -0
  58. package/dist/daemon/ringBuffer.d.ts +26 -0
  59. package/dist/daemon/ringBuffer.d.ts.map +1 -0
  60. package/dist/daemon/ringBuffer.js +54 -0
  61. package/dist/daemon/ringBuffer.js.map +1 -0
  62. package/dist/daemon/server.d.ts +23 -0
  63. package/dist/daemon/server.d.ts.map +1 -0
  64. package/dist/daemon/server.js +585 -0
  65. package/dist/daemon/server.js.map +1 -0
  66. package/dist/daemon/session.d.ts +47 -0
  67. package/dist/daemon/session.d.ts.map +1 -0
  68. package/dist/daemon/session.js +8 -0
  69. package/dist/daemon/session.js.map +1 -0
  70. package/dist/daemon/stateFile.d.ts +56 -0
  71. package/dist/daemon/stateFile.d.ts.map +1 -0
  72. package/dist/daemon/stateFile.js +178 -0
  73. package/dist/daemon/stateFile.js.map +1 -0
  74. package/dist/daemon/summary.d.ts +28 -0
  75. package/dist/daemon/summary.d.ts.map +1 -0
  76. package/dist/daemon/summary.js +152 -0
  77. package/dist/daemon/summary.js.map +1 -0
  78. package/dist/daemon/types.d.ts +72 -0
  79. package/dist/daemon/types.d.ts.map +1 -0
  80. package/dist/daemon/types.js +28 -0
  81. package/dist/daemon/types.js.map +1 -0
  82. package/dist/daemon/viewer.d.ts +24 -0
  83. package/dist/daemon/viewer.d.ts.map +1 -0
  84. package/dist/daemon/viewer.js +567 -0
  85. package/dist/daemon/viewer.js.map +1 -0
  86. package/dist/daemon/visualDiff.d.ts +34 -0
  87. package/dist/daemon/visualDiff.d.ts.map +1 -0
  88. package/dist/daemon/visualDiff.js +80 -0
  89. package/dist/daemon/visualDiff.js.map +1 -0
  90. package/dist/server/index.d.ts.map +1 -1
  91. package/dist/server/index.js +173 -0
  92. package/dist/server/index.js.map +1 -1
  93. package/dist/types.d.ts +19 -1
  94. package/dist/types.d.ts.map +1 -1
  95. package/dist/types.js.map +1 -1
  96. package/dist/vite.d.ts +12 -0
  97. package/dist/vite.d.ts.map +1 -1
  98. package/dist/vite.js +13 -0
  99. package/dist/vite.js.map +1 -1
  100. package/package.json +20 -12
@@ -0,0 +1,585 @@
1
+ /**
2
+ * Daemon HTTP Server
3
+ *
4
+ * Localhost-only HTTP server with bearer token auth.
5
+ * Routes POST requests to /api/{action} and dispatches to handlers.
6
+ * Manages idle timer for auto-shutdown.
7
+ */
8
+ import { createServer } from 'http';
9
+ import { closeBrowser, getBrowserInstance, getPage, initBrowser, takeResponsiveScreenshots, takeScreenshot } from './browser.js';
10
+ import { annotateScreenshot, diffSnapshots } from './diff.js';
11
+ import { takeDeviceScreenshots } from './devices.js';
12
+ import { consoleBuffer, dialogBuffer, formatConsoleEntries, formatNetworkEntries, getErrorCount, getWarningCount, networkBuffer, } from './listeners.js';
13
+ import { getRecordingPage, getRecordingStatus, isRecording, logAction, startRecording, stopRecording } from './recording.js';
14
+ import { detectServerErrors } from './errorPatterns.js';
15
+ import { generateSummary } from './summary.js';
16
+ import { generateViewer } from './viewer.js';
17
+ import { visualDiff } from './visualDiff.js';
18
+ import { buildRefMap, checkRefStale, formatRefMap, getBaseline, getCurrentRefMap, resolveRef, setBaseline, } from './refs.js';
19
+ import { DAEMON_IDLE_TIMEOUT_MS, DEFAULT_RESPONSIVE_VIEWPORTS } from './types.js';
20
+ // ============================================================================
21
+ // State
22
+ // ============================================================================
23
+ let httpServer = null;
24
+ let idleTimer = null;
25
+ let shutdownCallback = null;
26
+ let daemonPort = null;
27
+ // ============================================================================
28
+ // Idle Timer
29
+ // ============================================================================
30
+ function resetIdleTimer() {
31
+ if (idleTimer)
32
+ clearTimeout(idleTimer);
33
+ idleTimer = setTimeout(() => {
34
+ console.error('[Daemon] Idle timeout reached. Shutting down...');
35
+ shutdown();
36
+ }, DAEMON_IDLE_TIMEOUT_MS);
37
+ }
38
+ // ============================================================================
39
+ // Action Handlers
40
+ // ============================================================================
41
+ async function handlePing() {
42
+ return { ok: true, data: { pong: true, timestamp: Date.now() } };
43
+ }
44
+ async function handleShutdown() {
45
+ // Schedule shutdown after response is sent
46
+ setTimeout(() => shutdown(), 100);
47
+ return { ok: true, data: { message: 'Daemon shutting down' } };
48
+ }
49
+ async function handleScreenshot(params, url) {
50
+ await initBrowser(url);
51
+ const { buffer, width, height } = await takeScreenshot({
52
+ selector: params.selector,
53
+ fullPage: params.fullPage,
54
+ viewport: params.viewport,
55
+ });
56
+ return {
57
+ ok: true,
58
+ data: {
59
+ screenshot: buffer.toString('base64'),
60
+ width,
61
+ height,
62
+ },
63
+ };
64
+ }
65
+ async function handleResponsiveScreenshot(params, url) {
66
+ await initBrowser(url);
67
+ const viewports = params.viewports ?? DEFAULT_RESPONSIVE_VIEWPORTS;
68
+ const results = await takeResponsiveScreenshots({
69
+ viewports,
70
+ fullPage: params.fullPage,
71
+ });
72
+ return {
73
+ ok: true,
74
+ data: {
75
+ screenshots: results.map((r) => ({
76
+ width: r.width,
77
+ height: r.height,
78
+ screenshot: r.buffer.toString('base64'),
79
+ label: r.label,
80
+ })),
81
+ },
82
+ };
83
+ }
84
+ // ============================================================================
85
+ // Ref System Handlers
86
+ // ============================================================================
87
+ async function handleSnapshot(params, url) {
88
+ await initBrowser(url);
89
+ const recPage = getRecordingPage();
90
+ const page = recPage ?? getPage();
91
+ const interactive = params.interactive;
92
+ const diff = params.diff;
93
+ const annotate = params.annotate;
94
+ // If diffing, we need the baseline before taking new snapshot
95
+ const baseline = diff ? getBaseline() : null;
96
+ const resolved = await buildRefMap(page, { interactive: interactive !== false });
97
+ // Handle diff mode
98
+ if (diff) {
99
+ if (!baseline) {
100
+ return {
101
+ ok: false,
102
+ error: 'No baseline snapshot to diff against. Run `snapshot` first, then make changes, then `snapshot -D`.',
103
+ };
104
+ }
105
+ const diffText = diffSnapshots(baseline, resolved);
106
+ setBaseline(); // Update baseline for next diff
107
+ return {
108
+ ok: true,
109
+ data: {
110
+ diff: diffText,
111
+ tree: formatRefMap(resolved),
112
+ refs: resolved.entries,
113
+ count: resolved.entries.length,
114
+ },
115
+ };
116
+ }
117
+ // Handle annotated screenshot mode
118
+ if (annotate) {
119
+ const currentRefs = getCurrentRefMap();
120
+ if (!currentRefs || currentRefs.entries.length === 0) {
121
+ return { ok: false, error: 'No refs to annotate. Run `snapshot -i` first.' };
122
+ }
123
+ const buffer = await annotateScreenshot(page, currentRefs);
124
+ setBaseline();
125
+ return {
126
+ ok: true,
127
+ data: {
128
+ screenshot: buffer.toString('base64'),
129
+ tree: formatRefMap(resolved),
130
+ refs: resolved.entries,
131
+ count: resolved.entries.length,
132
+ },
133
+ };
134
+ }
135
+ // Default: set as baseline for future diffs
136
+ setBaseline();
137
+ return {
138
+ ok: true,
139
+ data: {
140
+ tree: formatRefMap(resolved),
141
+ refs: resolved.entries,
142
+ count: resolved.entries.length,
143
+ rawSnapshot: resolved.rawSnapshot,
144
+ },
145
+ };
146
+ }
147
+ async function handleClickRef(params, url) {
148
+ await initBrowser(url);
149
+ // Use recording page if recording, otherwise main page
150
+ const recPage = getRecordingPage();
151
+ const page = recPage ?? getPage();
152
+ const ref = params.ref;
153
+ if (!ref)
154
+ return { ok: false, error: 'Missing ref parameter' };
155
+ const stale = await checkRefStale(page, ref);
156
+ if (stale) {
157
+ return {
158
+ ok: false,
159
+ error: `Ref ${ref} is stale — element no longer exists. Run \`snapshot\` to get fresh refs.`,
160
+ };
161
+ }
162
+ const locator = resolveRef(page, ref);
163
+ const box = await locator.boundingBox();
164
+ await locator.click();
165
+ // Log action if recording
166
+ if (isRecording()) {
167
+ await logAction('click', [ref], page, box ?? undefined);
168
+ }
169
+ return { ok: true, data: { clicked: ref } };
170
+ }
171
+ async function handleFillRef(params, url) {
172
+ await initBrowser(url);
173
+ const recPage = getRecordingPage();
174
+ const page = recPage ?? getPage();
175
+ const ref = params.ref;
176
+ const value = params.value;
177
+ if (!ref)
178
+ return { ok: false, error: 'Missing ref parameter' };
179
+ if (value === undefined)
180
+ return { ok: false, error: 'Missing value parameter' };
181
+ const stale = await checkRefStale(page, ref);
182
+ if (stale) {
183
+ return {
184
+ ok: false,
185
+ error: `Ref ${ref} is stale — element no longer exists. Run \`snapshot\` to get fresh refs.`,
186
+ };
187
+ }
188
+ const locator = resolveRef(page, ref);
189
+ const box = await locator.boundingBox();
190
+ await locator.fill(value);
191
+ if (isRecording()) {
192
+ await logAction('fill', [ref, value], page, box ?? undefined);
193
+ }
194
+ return { ok: true, data: { filled: ref, value } };
195
+ }
196
+ async function handleHoverRef(params, url) {
197
+ await initBrowser(url);
198
+ const page = getPage();
199
+ const ref = params.ref;
200
+ if (!ref)
201
+ return { ok: false, error: 'Missing ref parameter' };
202
+ const stale = await checkRefStale(page, ref);
203
+ if (stale) {
204
+ return {
205
+ ok: false,
206
+ error: `Ref ${ref} is stale — element no longer exists. Run \`snapshot\` to get fresh refs.`,
207
+ };
208
+ }
209
+ const locator = resolveRef(page, ref);
210
+ await locator.hover();
211
+ return { ok: true, data: { hovered: ref } };
212
+ }
213
+ async function handlePressKey(params, url) {
214
+ await initBrowser(url);
215
+ const page = getPage();
216
+ const key = params.key;
217
+ if (!key)
218
+ return { ok: false, error: 'Missing key parameter' };
219
+ await page.keyboard.press(key);
220
+ return { ok: true, data: { pressed: key } };
221
+ }
222
+ // ============================================================================
223
+ // Ring Buffer Handlers
224
+ // ============================================================================
225
+ async function handleConsoleRead(params) {
226
+ const errorsOnly = params.errors;
227
+ const last = params.last;
228
+ let entries = errorsOnly
229
+ ? consoleBuffer.filter((e) => e.level === 'error')
230
+ : consoleBuffer.toArray();
231
+ if (last) {
232
+ entries = entries.slice(-last);
233
+ }
234
+ return {
235
+ ok: true,
236
+ data: {
237
+ entries,
238
+ formatted: formatConsoleEntries(entries),
239
+ total: consoleBuffer.size,
240
+ errorCount: getErrorCount(),
241
+ warningCount: getWarningCount(),
242
+ },
243
+ };
244
+ }
245
+ async function handleNetworkRead(params) {
246
+ const failedOnly = params.failed;
247
+ const last = params.last;
248
+ let entries = failedOnly
249
+ ? networkBuffer.filter((e) => e.status >= 400 || e.status === 0)
250
+ : networkBuffer.toArray();
251
+ if (last) {
252
+ entries = entries.slice(-last);
253
+ }
254
+ return {
255
+ ok: true,
256
+ data: {
257
+ entries,
258
+ formatted: formatNetworkEntries(entries),
259
+ total: networkBuffer.size,
260
+ failedCount: networkBuffer.filter((e) => e.status >= 400 || e.status === 0).length,
261
+ },
262
+ };
263
+ }
264
+ async function handleDialogRead() {
265
+ const entries = dialogBuffer.toArray();
266
+ return {
267
+ ok: true,
268
+ data: { entries, total: dialogBuffer.size },
269
+ };
270
+ }
271
+ async function handleScreenshotDevices(params, url) {
272
+ await initBrowser(url);
273
+ const page = getPage();
274
+ const devices = params.devices;
275
+ if (!devices || devices.length === 0) {
276
+ return { ok: false, error: 'Missing devices parameter' };
277
+ }
278
+ const results = await takeDeviceScreenshots(page, devices, {
279
+ fullPage: params.fullPage,
280
+ });
281
+ return {
282
+ ok: true,
283
+ data: {
284
+ screenshots: results.map((r) => ({
285
+ device: r.device.name,
286
+ width: r.device.viewport.width,
287
+ height: r.device.viewport.height,
288
+ screenshot: r.buffer.toString('base64'),
289
+ })),
290
+ },
291
+ };
292
+ }
293
+ async function handleRecordStart(url) {
294
+ await initBrowser(url);
295
+ const browser = getBrowserInstance();
296
+ const result = await startRecording(browser, url, '.sweetlink');
297
+ return { ok: true, data: { sessionId: result.sessionId } };
298
+ }
299
+ async function handleRecordStop() {
300
+ const manifest = await stopRecording();
301
+ if (!manifest) {
302
+ return { ok: false, error: 'No recording in progress' };
303
+ }
304
+ // Auto-generate viewer HTML + summary report
305
+ const sessionDir = `.sweetlink/${manifest.sessionId}`;
306
+ let viewerPath;
307
+ let summaryPath;
308
+ try {
309
+ const consoleLogs = consoleBuffer.toArray();
310
+ const networkLogs = networkBuffer.toArray();
311
+ viewerPath = await generateViewer(manifest, {
312
+ sessionDir,
313
+ consoleEntries: consoleLogs,
314
+ networkEntries: networkLogs,
315
+ });
316
+ // Generate SUMMARY.md
317
+ const { promises: fsp } = await import('fs');
318
+ // Detect server errors from console log messages
319
+ const consoleText = consoleLogs.map(e => e.message).join('\n');
320
+ const serverErrors = detectServerErrors(consoleText);
321
+ if (serverErrors.length > 0) {
322
+ manifest.errors.server = serverErrors.length;
323
+ }
324
+ const summaryMd = generateSummary({
325
+ manifest,
326
+ consoleEntries: consoleLogs,
327
+ networkEntries: networkLogs,
328
+ serverErrors: serverErrors.map(e => ({
329
+ source: 'server',
330
+ message: e.line,
331
+ timestamp: Date.now(),
332
+ code: e.language,
333
+ })),
334
+ gitBranch: manifest.gitBranch,
335
+ gitCommit: manifest.gitCommit,
336
+ });
337
+ summaryPath = `${sessionDir}/SUMMARY.md`;
338
+ await fsp.writeFile(summaryPath, summaryMd, 'utf-8');
339
+ console.error(`[Daemon] Summary saved: ${summaryPath}`);
340
+ }
341
+ catch (e) {
342
+ console.error('[Daemon] Report generation error:', e);
343
+ }
344
+ // Include a browser-accessible URL for the viewer
345
+ const viewerUrl = manifest.sessionId && daemonPort ? `http://127.0.0.1:${daemonPort}/viewer/${manifest.sessionId}` : undefined;
346
+ return { ok: true, data: { manifest, viewerPath, viewerUrl, summaryPath } };
347
+ }
348
+ async function handleRecordStatus() {
349
+ const status = getRecordingStatus();
350
+ return { ok: true, data: status };
351
+ }
352
+ async function handleGenerateViewer(params) {
353
+ const sessionDir = params.sessionDir;
354
+ const outputPath = params.outputPath;
355
+ if (!sessionDir)
356
+ return { ok: false, error: 'Missing sessionDir parameter' };
357
+ try {
358
+ const { promises: fsp } = await import('fs');
359
+ const manifestRaw = await fsp.readFile(`${sessionDir}/sweetlink-session.json`, 'utf-8');
360
+ const manifest = JSON.parse(manifestRaw);
361
+ const viewerPath = await generateViewer(manifest, {
362
+ sessionDir,
363
+ outputPath,
364
+ consoleEntries: consoleBuffer.toArray(),
365
+ networkEntries: networkBuffer.toArray(),
366
+ });
367
+ return { ok: true, data: { viewerPath } };
368
+ }
369
+ catch (error) {
370
+ return { ok: false, error: `Failed to generate viewer: ${error instanceof Error ? error.message : error}` };
371
+ }
372
+ }
373
+ async function handleVisualDiff(params) {
374
+ const baseline = params.baseline;
375
+ const current = params.current;
376
+ const threshold = params.threshold;
377
+ if (!baseline || !current) {
378
+ return { ok: false, error: 'Missing baseline or current parameter (base64 encoded PNG)' };
379
+ }
380
+ const baselineBuffer = Buffer.from(baseline, 'base64');
381
+ const currentBuffer = Buffer.from(current, 'base64');
382
+ const result = await visualDiff(baselineBuffer, currentBuffer, { threshold });
383
+ return {
384
+ ok: true,
385
+ data: {
386
+ mismatchPercentage: result.mismatchPercentage,
387
+ mismatchCount: result.mismatchCount,
388
+ totalPixels: result.totalPixels,
389
+ pass: result.pass,
390
+ },
391
+ };
392
+ }
393
+ // ============================================================================
394
+ // Request Handling
395
+ // ============================================================================
396
+ async function handleRequest(action, params, url) {
397
+ switch (action) {
398
+ case 'ping':
399
+ return handlePing();
400
+ case 'shutdown':
401
+ return handleShutdown();
402
+ case 'screenshot':
403
+ return handleScreenshot(params, url);
404
+ case 'screenshot-responsive':
405
+ return handleResponsiveScreenshot(params, url);
406
+ case 'snapshot':
407
+ return handleSnapshot(params, url);
408
+ case 'click-ref':
409
+ return handleClickRef(params, url);
410
+ case 'fill-ref':
411
+ return handleFillRef(params, url);
412
+ case 'hover-ref':
413
+ return handleHoverRef(params, url);
414
+ case 'press-key':
415
+ return handlePressKey(params, url);
416
+ case 'console-read':
417
+ return handleConsoleRead(params);
418
+ case 'network-read':
419
+ return handleNetworkRead(params);
420
+ case 'dialog-read':
421
+ return handleDialogRead();
422
+ case 'screenshot-devices':
423
+ return handleScreenshotDevices(params, url);
424
+ case 'visual-diff':
425
+ return handleVisualDiff(params);
426
+ case 'record-start':
427
+ return handleRecordStart(url);
428
+ case 'record-stop':
429
+ return handleRecordStop();
430
+ case 'record-status':
431
+ return handleRecordStatus();
432
+ case 'generate-viewer':
433
+ return handleGenerateViewer(params);
434
+ default:
435
+ return { ok: false, error: `Unknown action: ${action}` };
436
+ }
437
+ }
438
+ function readBody(req) {
439
+ return new Promise((resolve, reject) => {
440
+ const chunks = [];
441
+ let size = 0;
442
+ const MAX_BODY = 10 * 1024 * 1024; // 10MB max (visual-diff sends two screenshots)
443
+ req.on('data', (chunk) => {
444
+ size += chunk.length;
445
+ if (size > MAX_BODY) {
446
+ req.destroy();
447
+ reject(new Error('Request body too large'));
448
+ return;
449
+ }
450
+ chunks.push(chunk);
451
+ });
452
+ req.on('end', () => resolve(Buffer.concat(chunks).toString()));
453
+ req.on('error', reject);
454
+ });
455
+ }
456
+ function sendJson(res, status, body) {
457
+ res.writeHead(status, { 'Content-Type': 'application/json' });
458
+ res.end(JSON.stringify(body));
459
+ }
460
+ /**
461
+ * Start the daemon HTTP server.
462
+ * Binds to 127.0.0.1 (localhost only) on the specified port.
463
+ */
464
+ export function startServer(options) {
465
+ return new Promise((resolve, reject) => {
466
+ shutdownCallback = options.onShutdown;
467
+ daemonPort = options.port;
468
+ httpServer = createServer(async (req, res) => {
469
+ // CORS preflight
470
+ if (req.method === 'OPTIONS') {
471
+ res.writeHead(204, {
472
+ 'Access-Control-Allow-Origin': '*',
473
+ 'Access-Control-Allow-Methods': 'POST',
474
+ 'Access-Control-Allow-Headers': 'Content-Type, Authorization',
475
+ });
476
+ res.end();
477
+ return;
478
+ }
479
+ // Serve viewer HTML via GET (no auth required — localhost only)
480
+ if (req.method === 'GET') {
481
+ const urlPath = req.url ?? '/';
482
+ const viewerMatch = urlPath.match(/^\/viewer\/([a-z0-9-]+)$/);
483
+ if (viewerMatch) {
484
+ const sid = viewerMatch[1];
485
+ try {
486
+ const { promises: fsp } = await import('fs');
487
+ const viewerHtml = await fsp.readFile(`.sweetlink/${sid}/viewer.html`, 'utf-8');
488
+ res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
489
+ res.end(viewerHtml);
490
+ }
491
+ catch {
492
+ res.writeHead(404, { 'Content-Type': 'text/plain' });
493
+ res.end('Viewer not found');
494
+ }
495
+ return;
496
+ }
497
+ // GET /viewers — list available sessions
498
+ if (urlPath === '/viewers') {
499
+ try {
500
+ const { promises: fsp } = await import('fs');
501
+ const entries = await fsp.readdir('.sweetlink', { withFileTypes: true });
502
+ const sessions = entries
503
+ .filter(e => e.isDirectory() && e.name.startsWith('session-'))
504
+ .map(e => e.name)
505
+ .sort()
506
+ .reverse();
507
+ res.writeHead(200, { 'Content-Type': 'application/json' });
508
+ res.end(JSON.stringify({ sessions, daemonPort: options.port }));
509
+ }
510
+ catch {
511
+ res.writeHead(200, { 'Content-Type': 'application/json' });
512
+ res.end(JSON.stringify({ sessions: [] }));
513
+ }
514
+ return;
515
+ }
516
+ sendJson(res, 404, { ok: false, error: 'Not found' });
517
+ return;
518
+ }
519
+ // Only accept POST for API
520
+ if (req.method !== 'POST') {
521
+ sendJson(res, 405, { ok: false, error: 'Method not allowed' });
522
+ return;
523
+ }
524
+ // Validate bearer token
525
+ const auth = req.headers.authorization;
526
+ if (!auth || auth !== `Bearer ${options.token}`) {
527
+ sendJson(res, 401, { ok: false, error: 'Unauthorized' });
528
+ return;
529
+ }
530
+ // Parse action from URL path: /api/{action}
531
+ const urlPath = req.url ?? '/';
532
+ const match = urlPath.match(/^\/api\/([a-z-]+)$/);
533
+ if (!match) {
534
+ sendJson(res, 404, { ok: false, error: 'Not found' });
535
+ return;
536
+ }
537
+ const action = match[1];
538
+ // Reset idle timer on every valid request
539
+ resetIdleTimer();
540
+ try {
541
+ const body = await readBody(req);
542
+ const parsed = body ? JSON.parse(body) : {};
543
+ const params = parsed.params ?? {};
544
+ const response = await handleRequest(action, params, options.url);
545
+ sendJson(res, response.ok ? 200 : 400, response);
546
+ }
547
+ catch (error) {
548
+ const message = error instanceof Error ? error.message : String(error);
549
+ console.error('[Daemon] Request error:', message);
550
+ sendJson(res, 500, { ok: false, error: message });
551
+ }
552
+ });
553
+ httpServer.on('error', (error) => {
554
+ if (error.code === 'EADDRINUSE') {
555
+ reject(new Error(`Port ${options.port} is in use`));
556
+ }
557
+ else {
558
+ reject(error);
559
+ }
560
+ });
561
+ // Bind to localhost only
562
+ httpServer.listen(options.port, '127.0.0.1', () => {
563
+ console.error(`[Daemon] HTTP server listening on http://127.0.0.1:${options.port}`);
564
+ resetIdleTimer();
565
+ resolve();
566
+ });
567
+ });
568
+ }
569
+ /**
570
+ * Shut down the daemon: close browser, close HTTP server, call shutdown callback.
571
+ */
572
+ export async function shutdown() {
573
+ console.error('[Daemon] Shutting down...');
574
+ if (idleTimer) {
575
+ clearTimeout(idleTimer);
576
+ idleTimer = null;
577
+ }
578
+ await closeBrowser();
579
+ if (httpServer) {
580
+ httpServer.close();
581
+ httpServer = null;
582
+ }
583
+ shutdownCallback?.();
584
+ }
585
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/daemon/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Session Manifest
3
+ *
4
+ * Machine-readable session description for viewer generation,
5
+ * report generation, and PR evidence upload.
6
+ */
7
+ export interface ActionEntry {
8
+ /** Seconds since session start */
9
+ timestamp: number;
10
+ /** Command name (click, fill, snapshot, screenshot, etc.) */
11
+ action: string;
12
+ /** Command arguments */
13
+ args: string[];
14
+ /** Duration of the action in ms */
15
+ duration: number;
16
+ /** Bounding box of the target element (if applicable) */
17
+ boundingBox?: {
18
+ x: number;
19
+ y: number;
20
+ width: number;
21
+ height: number;
22
+ };
23
+ /** Screenshot filename taken at this action */
24
+ screenshot?: string;
25
+ }
26
+ export interface SessionManifest {
27
+ sessionId: string;
28
+ /** Target app URL that was recorded */
29
+ url?: string;
30
+ /** Git branch at time of recording */
31
+ gitBranch?: string;
32
+ /** Git commit SHA at time of recording */
33
+ gitCommit?: string;
34
+ startedAt: string;
35
+ endedAt: string;
36
+ /** Duration in seconds */
37
+ duration: number;
38
+ commands: ActionEntry[];
39
+ screenshots: string[];
40
+ video?: string;
41
+ errors: {
42
+ console: number;
43
+ network: number;
44
+ server: number;
45
+ };
46
+ }
47
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/daemon/session.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,MAAM,WAAW,WAAW;IAC1B,kCAAkC;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC;IACf,wBAAwB;IACxB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,mCAAmC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,yDAAyD;IACzD,WAAW,CAAC,EAAE;QACZ,CAAC,EAAE,MAAM,CAAC;QACV,CAAC,EAAE,MAAM,CAAC;QACV,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,+CAA+C;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,sCAAsC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,0BAA0B;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE;QACN,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Session Manifest
3
+ *
4
+ * Machine-readable session description for viewer generation,
5
+ * report generation, and PR evidence upload.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=session.js.map