@ytspar/sweetlink 1.23.0 → 1.24.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 (92) hide show
  1. package/dist/auto.d.ts.map +1 -1
  2. package/dist/auto.js +3 -4
  3. package/dist/auto.js.map +1 -1
  4. package/dist/browser/commands/exec.d.ts.map +1 -1
  5. package/dist/browser/commands/exec.js +54 -1
  6. package/dist/browser/commands/exec.js.map +1 -1
  7. package/dist/browser/consoleCapture.d.ts +10 -1
  8. package/dist/browser/consoleCapture.d.ts.map +1 -1
  9. package/dist/browser/consoleCapture.js +44 -13
  10. package/dist/browser/consoleCapture.js.map +1 -1
  11. package/dist/cdp.d.ts +1 -1
  12. package/dist/cdp.d.ts.map +1 -1
  13. package/dist/cdp.js +1 -11
  14. package/dist/cdp.js.map +1 -1
  15. package/dist/cli/sweetlink-dev.js +4 -8
  16. package/dist/cli/sweetlink-dev.js.map +1 -1
  17. package/dist/cli/sweetlink.js +1048 -1020
  18. package/dist/cli/sweetlink.js.map +1 -1
  19. package/dist/daemon/client.d.ts +2 -2
  20. package/dist/daemon/client.d.ts.map +1 -1
  21. package/dist/daemon/client.js.map +1 -1
  22. package/dist/daemon/diff.d.ts.map +1 -1
  23. package/dist/daemon/diff.js +21 -1
  24. package/dist/daemon/diff.js.map +1 -1
  25. package/dist/daemon/index.js +17 -18
  26. package/dist/daemon/index.js.map +1 -1
  27. package/dist/daemon/listeners.d.ts.map +1 -1
  28. package/dist/daemon/listeners.js +12 -7
  29. package/dist/daemon/listeners.js.map +1 -1
  30. package/dist/daemon/recording.d.ts.map +1 -1
  31. package/dist/daemon/recording.js +50 -8
  32. package/dist/daemon/recording.js.map +1 -1
  33. package/dist/daemon/refs.d.ts.map +1 -1
  34. package/dist/daemon/refs.js +6 -2
  35. package/dist/daemon/refs.js.map +1 -1
  36. package/dist/daemon/ringBuffer.d.ts +10 -0
  37. package/dist/daemon/ringBuffer.d.ts.map +1 -1
  38. package/dist/daemon/ringBuffer.js +13 -0
  39. package/dist/daemon/ringBuffer.js.map +1 -1
  40. package/dist/daemon/server.d.ts +12 -0
  41. package/dist/daemon/server.d.ts.map +1 -1
  42. package/dist/daemon/server.js +99 -11
  43. package/dist/daemon/server.js.map +1 -1
  44. package/dist/daemon/stateFile.d.ts +15 -1
  45. package/dist/daemon/stateFile.d.ts.map +1 -1
  46. package/dist/daemon/stateFile.js +96 -33
  47. package/dist/daemon/stateFile.js.map +1 -1
  48. package/dist/daemon/types.d.ts +99 -10
  49. package/dist/daemon/types.d.ts.map +1 -1
  50. package/dist/daemon/types.js.map +1 -1
  51. package/dist/daemon/utils.d.ts +17 -4
  52. package/dist/daemon/utils.d.ts.map +1 -1
  53. package/dist/daemon/utils.js +30 -4
  54. package/dist/daemon/utils.js.map +1 -1
  55. package/dist/daemon/viewer.d.ts.map +1 -1
  56. package/dist/daemon/viewer.js +13 -5
  57. package/dist/daemon/viewer.js.map +1 -1
  58. package/dist/index.d.ts +1 -1
  59. package/dist/index.d.ts.map +1 -1
  60. package/dist/index.js.map +1 -1
  61. package/dist/playwright.d.ts +1 -1
  62. package/dist/playwright.d.ts.map +1 -1
  63. package/dist/playwright.js +3 -22
  64. package/dist/playwright.js.map +1 -1
  65. package/dist/screenshotConstants.d.ts +13 -0
  66. package/dist/screenshotConstants.d.ts.map +1 -0
  67. package/dist/screenshotConstants.js +20 -0
  68. package/dist/screenshotConstants.js.map +1 -0
  69. package/dist/server/index.d.ts.map +1 -1
  70. package/dist/server/index.js +125 -97
  71. package/dist/server/index.js.map +1 -1
  72. package/dist/simulator/android.d.ts.map +1 -1
  73. package/dist/simulator/android.js +2 -22
  74. package/dist/simulator/android.js.map +1 -1
  75. package/dist/simulator/env.d.ts +10 -0
  76. package/dist/simulator/env.d.ts.map +1 -0
  77. package/dist/simulator/env.js +30 -0
  78. package/dist/simulator/env.js.map +1 -0
  79. package/dist/simulator/ios.d.ts.map +1 -1
  80. package/dist/simulator/ios.js +2 -22
  81. package/dist/simulator/ios.js.map +1 -1
  82. package/dist/types.d.ts +100 -70
  83. package/dist/types.d.ts.map +1 -1
  84. package/dist/types.js +2 -0
  85. package/dist/types.js.map +1 -1
  86. package/dist/urlUtils.d.ts.map +1 -1
  87. package/dist/urlUtils.js +13 -2
  88. package/dist/urlUtils.js.map +1 -1
  89. package/dist/viewportUtils.d.ts +10 -1
  90. package/dist/viewportUtils.d.ts.map +1 -1
  91. package/dist/viewportUtils.js.map +1 -1
  92. package/package.json +1 -1
@@ -4,6 +4,7 @@
4
4
  * Handles reading, writing, and cleanup of .sweetlink/daemon.json.
5
5
  * Uses atomic writes (tmp + rename) and lockfiles to prevent race conditions.
6
6
  */
7
+ import * as crypto from 'crypto';
7
8
  import * as fs from 'fs';
8
9
  import * as path from 'path';
9
10
  import { DAEMON_LOCK_FILE, DAEMON_STATE_DIR, DAEMON_STATE_FILE } from './types.js';
@@ -35,7 +36,8 @@ export function getLockFilePath(projectRoot, appPort) {
35
36
  */
36
37
  export function extractPort(url) {
37
38
  try {
38
- return new URL(url).port ? parseInt(new URL(url).port, 10) : undefined;
39
+ const port = new URL(url).port;
40
+ return port ? parseInt(port, 10) : undefined;
39
41
  }
40
42
  catch {
41
43
  return undefined;
@@ -45,6 +47,11 @@ export function extractPort(url) {
45
47
  * Write daemon state to .sweetlink/daemon.json (or daemon-{port}.json) atomically.
46
48
  * Creates the directory if it doesn't exist.
47
49
  * Sets file permissions to 600 (owner read/write only) for security.
50
+ *
51
+ * If the rename fails or the process crashes between the write and the
52
+ * rename, the stale `.tmp` file is left containing the bearer token. We
53
+ * unlink any pre-existing tmp before writing so a previous crash can't
54
+ * leak a token across daemon restarts.
48
55
  */
49
56
  export function writeDaemonState(projectRoot, state, appPort) {
50
57
  const dir = getStateDir(projectRoot);
@@ -53,9 +60,27 @@ export function writeDaemonState(projectRoot, state, appPort) {
53
60
  }
54
61
  const stateFile = getStateFilePath(projectRoot, appPort);
55
62
  const tmpFile = `${stateFile}.tmp`;
63
+ try {
64
+ fs.unlinkSync(tmpFile);
65
+ }
66
+ catch {
67
+ /* tmp does not exist — fine */
68
+ }
56
69
  // Atomic write: write to tmp, then rename
57
70
  fs.writeFileSync(tmpFile, JSON.stringify(state, null, 2), { mode: 0o600 });
58
- fs.renameSync(tmpFile, stateFile);
71
+ try {
72
+ fs.renameSync(tmpFile, stateFile);
73
+ }
74
+ catch (err) {
75
+ // Rename failed — clean up tmp so the token doesn't linger on disk.
76
+ try {
77
+ fs.unlinkSync(tmpFile);
78
+ }
79
+ catch {
80
+ /* best-effort */
81
+ }
82
+ throw err;
83
+ }
59
84
  }
60
85
  /**
61
86
  * Read daemon state from .sweetlink/daemon.json (or daemon-{port}.json).
@@ -81,22 +106,18 @@ export function readDaemonState(projectRoot, appPort) {
81
106
  }
82
107
  }
83
108
  /**
84
- * Remove daemon state file and lock file
109
+ * Remove daemon state file and lock file (and any leftover tmp).
85
110
  */
86
111
  export function removeDaemonState(projectRoot, appPort) {
87
112
  const stateFile = getStateFilePath(projectRoot, appPort);
88
113
  const lockFile = getLockFilePath(projectRoot, appPort);
89
- try {
90
- fs.unlinkSync(stateFile);
91
- }
92
- catch {
93
- // File may not exist
94
- }
95
- try {
96
- fs.unlinkSync(lockFile);
97
- }
98
- catch {
99
- // File may not exist
114
+ for (const f of [stateFile, `${stateFile}.tmp`, lockFile]) {
115
+ try {
116
+ fs.unlinkSync(f);
117
+ }
118
+ catch {
119
+ // File may not exist
120
+ }
100
121
  }
101
122
  }
102
123
  /**
@@ -126,6 +147,15 @@ export async function isDaemonAlive(state) {
126
147
  /**
127
148
  * Acquire a lockfile to prevent concurrent daemon starts.
128
149
  * Returns true if the lock was acquired, false if another process holds it.
150
+ *
151
+ * Lockfile format: `PID:TOKEN` where TOKEN is a 16-byte random hex string
152
+ * generated for this acquisition attempt. The token defends against PID
153
+ * reuse — a reincarnated PID can't impersonate the original lock-holder
154
+ * because it has a different token.
155
+ *
156
+ * Stale-lock recovery is made atomic by writing our token and reading it
157
+ * back: if two processes race on recovery, only the winner's token will
158
+ * be in the file.
129
159
  */
130
160
  export function acquireLock(projectRoot, appPort) {
131
161
  const dir = getStateDir(projectRoot);
@@ -133,33 +163,66 @@ export function acquireLock(projectRoot, appPort) {
133
163
  fs.mkdirSync(dir, { recursive: true });
134
164
  }
135
165
  const lockFile = getLockFilePath(projectRoot, appPort);
166
+ const ourToken = crypto.randomBytes(16).toString('hex');
167
+ const ourContent = `${process.pid}:${ourToken}`;
168
+ // Fast path: no existing lock.
169
+ try {
170
+ fs.writeFileSync(lockFile, ourContent, { flag: 'wx', mode: 0o600 });
171
+ return verifyLockOwnership(lockFile, ourContent);
172
+ }
173
+ catch {
174
+ // Lock exists — see if it's stale.
175
+ }
176
+ // Slow path: existing lock might be stale.
177
+ let existingPid;
136
178
  try {
137
- // 'wx' flag: write exclusive — fails if file exists
138
- fs.writeFileSync(lockFile, String(process.pid), { flag: 'wx', mode: 0o600 });
139
- return true;
179
+ const raw = fs.readFileSync(lockFile, 'utf-8').trim();
180
+ const [pidPart] = raw.split(':');
181
+ const parsed = parseInt(pidPart ?? raw, 10);
182
+ if (!Number.isNaN(parsed))
183
+ existingPid = parsed;
140
184
  }
141
185
  catch {
142
- // Check if the lock is stale (holding process is dead)
186
+ /* lockfile vanished or unreadable fall through */
187
+ }
188
+ if (existingPid !== undefined && existingPid !== process.pid) {
143
189
  try {
144
- const pid = parseInt(fs.readFileSync(lockFile, 'utf-8').trim(), 10);
145
- if (!Number.isNaN(pid)) {
146
- try {
147
- // Signal 0 checks if process exists without killing it
148
- process.kill(pid, 0);
149
- // Process is alive lock is valid
150
- return false;
151
- }
152
- catch {
153
- // Process is dead — stale lock, remove and retry
154
- fs.unlinkSync(lockFile);
155
- fs.writeFileSync(lockFile, String(process.pid), { flag: 'wx', mode: 0o600 });
156
- return true;
157
- }
190
+ process.kill(existingPid, 0);
191
+ // Process exists — but PID could have been recycled. Cross-check with
192
+ // the daemon state file: if the state file's PID matches AND the
193
+ // state was written recently, treat as live. Otherwise treat as stale.
194
+ const state = readDaemonState(projectRoot, appPort);
195
+ if (state && state.pid === existingPid) {
196
+ return false; // genuinely live daemon owns the lock
158
197
  }
198
+ // PID is alive but not our daemon — recycled. Fall through to recovery.
159
199
  }
160
200
  catch {
161
- // Can't read lock file another process may be writing it
201
+ // Process is deadstale lock, recover.
162
202
  }
203
+ }
204
+ // Stale-lock recovery: try to atomically take over. Multiple racing
205
+ // processes all unlink + wx-write here; only one wx-write can succeed.
206
+ // Then verify by reading back our token.
207
+ try {
208
+ try {
209
+ fs.unlinkSync(lockFile);
210
+ }
211
+ catch {
212
+ /* may have been unlinked by a concurrent recoverer */
213
+ }
214
+ fs.writeFileSync(lockFile, ourContent, { flag: 'wx', mode: 0o600 });
215
+ return verifyLockOwnership(lockFile, ourContent);
216
+ }
217
+ catch {
218
+ return false;
219
+ }
220
+ }
221
+ function verifyLockOwnership(lockFile, expected) {
222
+ try {
223
+ return fs.readFileSync(lockFile, 'utf-8').trim() === expected;
224
+ }
225
+ catch {
163
226
  return false;
164
227
  }
165
228
  }
@@ -1 +1 @@
1
- {"version":3,"file":"stateFile.js","sourceRoot":"","sources":["../../src/daemon/stateFile.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"stateFile.js","sourceRoot":"","sources":["../../src/daemon/stateFile.ts"],"names":[],"mappings":"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"}
@@ -20,21 +20,110 @@ export interface DaemonState {
20
20
  * prevents callers from constructing requests the server will reject.
21
21
  */
22
22
  export type DaemonAction = 'ping' | 'shutdown' | 'screenshot' | 'screenshot-responsive' | 'snapshot' | 'inspect' | 'click-ref' | 'click-css' | 'fill-ref' | 'hover-ref' | 'press-key' | 'console-read' | 'network-read' | 'dialog-read' | 'screenshot-devices' | 'visual-diff' | 'record-start' | 'record-stop' | 'record-status' | 'record-pause' | 'record-resume' | 'sessions-list' | 'generate-viewer';
23
- /** Request body for daemon HTTP POST */
24
- export interface DaemonRequest {
25
- action: DaemonAction;
26
- params?: Record<string, unknown>;
23
+ /**
24
+ * Per-action params shape. Adding a new action means extending this map
25
+ * with the action's required params; the discriminated `DaemonRequest`
26
+ * union then forces every caller to supply the right payload at compile
27
+ * time. Actions not listed here implicitly accept no params.
28
+ */
29
+ export interface DaemonActionParams {
30
+ ping: undefined;
31
+ shutdown: undefined;
32
+ screenshot: ScreenshotParams | undefined;
33
+ 'screenshot-responsive': ResponsiveScreenshotParams | undefined;
34
+ snapshot: {
35
+ diff?: boolean;
36
+ } | undefined;
37
+ inspect: {
38
+ selector?: string;
39
+ } | undefined;
40
+ 'click-ref': {
41
+ ref: string;
42
+ };
43
+ 'click-css': {
44
+ selector?: string;
45
+ text?: string;
46
+ index?: number;
47
+ };
48
+ 'fill-ref': {
49
+ ref: string;
50
+ value: string;
51
+ };
52
+ 'hover-ref': {
53
+ ref: string;
54
+ };
55
+ 'press-key': {
56
+ key: string;
57
+ };
58
+ 'console-read': {
59
+ errors?: boolean;
60
+ last?: number;
61
+ } | undefined;
62
+ 'network-read': {
63
+ last?: number;
64
+ status?: number;
65
+ } | undefined;
66
+ 'dialog-read': {
67
+ last?: number;
68
+ } | undefined;
69
+ 'screenshot-devices': Record<string, unknown> | undefined;
70
+ 'visual-diff': {
71
+ baseline: string;
72
+ current: string;
73
+ threshold?: number;
74
+ outputPath?: string;
75
+ };
76
+ 'record-start': {
77
+ url?: string;
78
+ label?: string;
79
+ trace?: boolean;
80
+ } | undefined;
81
+ 'record-stop': undefined;
82
+ 'record-status': undefined;
83
+ 'record-pause': undefined;
84
+ 'record-resume': undefined;
85
+ 'sessions-list': undefined;
86
+ 'generate-viewer': {
87
+ sessionDir: string;
88
+ outputPath?: string;
89
+ };
27
90
  }
28
- /** Response from daemon HTTP server */
29
- export interface DaemonResponse {
30
- ok: boolean;
91
+ /**
92
+ * Request body for daemon HTTP POST. Discriminated on `action` so each
93
+ * variant carries only the params shape that action accepts.
94
+ *
95
+ * The dispatch surface (`DAEMON_HANDLERS` in server.ts) still receives
96
+ * `params: Record<string, unknown>` because the wire format is JSON —
97
+ * but on the producing side, callers that build a typed DaemonRequest
98
+ * get compile-time checking.
99
+ */
100
+ export type DaemonRequest = {
101
+ [A in DaemonAction]: {
102
+ action: A;
103
+ params: DaemonActionParams[A];
104
+ };
105
+ }[DaemonAction];
106
+ /**
107
+ * Response from the daemon HTTP server. Discriminated by `ok`:
108
+ * a successful response is `{ ok: true; data?: ... }` (no `error`),
109
+ * a failure is `{ ok: false; error: string; data?: ... }`. Some failure
110
+ * paths still attach a `data` payload with diagnostic context (e.g. a
111
+ * failure screenshot path) so we keep `data` optional on both branches.
112
+ */
113
+ export type DaemonResponse = {
114
+ ok: true;
31
115
  data?: Record<string, unknown>;
32
- error?: string;
33
- }
116
+ error?: never;
117
+ } | {
118
+ ok: false;
119
+ error: string;
120
+ data?: Record<string, unknown>;
121
+ };
34
122
  export interface ScreenshotParams {
35
123
  selector?: string;
36
124
  fullPage?: boolean;
37
- viewport?: string;
125
+ /** Named preset, `WxH` string, or arbitrary string for back-compat. */
126
+ viewport?: import('../viewportUtils.js').ViewportName | string;
38
127
  output?: string;
39
128
  hideDevbar?: boolean;
40
129
  }
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/daemon/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,+DAA+D;AAC/D,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;CACtB;AAMD;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GACpB,MAAM,GACN,UAAU,GACV,YAAY,GACZ,uBAAuB,GACvB,UAAU,GACV,SAAS,GACT,WAAW,GACX,WAAW,GACX,UAAU,GACV,WAAW,GACX,WAAW,GACX,cAAc,GACd,cAAc,GACd,aAAa,GACb,oBAAoB,GACpB,aAAa,GACb,cAAc,GACd,aAAa,GACb,eAAe,GACf,cAAc,GACd,eAAe,GACf,eAAe,GACf,iBAAiB,CAAC;AAEtB,wCAAwC;AACxC,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,uCAAuC;AACvC,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAMD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,0BAA0B;IACzC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,gCAAgC;IAC/C,WAAW,EAAE,KAAK,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC,CAAC;CACJ;AAMD,0CAA0C;AAC1C,eAAO,MAAM,eAAe,QAAQ,CAAC;AAErC,0CAA0C;AAC1C,eAAO,MAAM,eAAe,QAAQ,CAAC;AAErC,iDAAiD;AACjD,eAAO,MAAM,sBAAsB,QAAiB,CAAC;AAErD,gDAAgD;AAChD,eAAO,MAAM,uBAAuB,QAAS,CAAC;AAE9C,4DAA4D;AAC5D,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAE3C,2BAA2B;AAC3B,eAAO,MAAM,gBAAgB,eAAe,CAAC;AAE7C,sBAAsB;AACtB,eAAO,MAAM,iBAAiB,gBAAgB,CAAC;AAE/C,qBAAqB;AACrB,eAAO,MAAM,gBAAgB,gBAAgB,CAAC;AAE9C,mCAAmC;AACnC,eAAO,MAAM,4BAA4B,UAAmB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/daemon/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/daemon/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAmGH,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAE/E,0CAA0C;AAC1C,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,CAAC;AAErC,0CAA0C;AAC1C,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,CAAC;AAErC,iDAAiD;AACjD,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,aAAa;AAEnE,gDAAgD;AAChD,MAAM,CAAC,MAAM,uBAAuB,GAAG,MAAM,CAAC;AAE9C,4DAA4D;AAC5D,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAG,CAAC;AAE3C,2BAA2B;AAC3B,MAAM,CAAC,MAAM,gBAAgB,GAAG,YAAY,CAAC;AAE7C,sBAAsB;AACtB,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAC;AAE/C,qBAAqB;AACrB,MAAM,CAAC,MAAM,gBAAgB,GAAG,aAAa,CAAC;AAE9C,mCAAmC;AACnC,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/daemon/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAoJH,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAE/E,0CAA0C;AAC1C,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,CAAC;AAErC,0CAA0C;AAC1C,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,CAAC;AAErC,iDAAiD;AACjD,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,aAAa;AAEnE,gDAAgD;AAChD,MAAM,CAAC,MAAM,uBAAuB,GAAG,MAAM,CAAC;AAE9C,4DAA4D;AAC5D,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAG,CAAC;AAE3C,2BAA2B;AAC3B,MAAM,CAAC,MAAM,gBAAgB,GAAG,YAAY,CAAC;AAE7C,sBAAsB;AACtB,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAC;AAE/C,qBAAqB;AACrB,MAAM,CAAC,MAAM,gBAAgB,GAAG,aAAa,CAAC;AAE9C,mCAAmC;AACnC,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC"}
@@ -2,11 +2,24 @@
2
2
  * Small utilities shared across daemon and term modules.
3
3
  */
4
4
  /**
5
- * Read git branch + short SHA. Returns nulls when not in a git repo or git
6
- * is missing never throws. The 3s timeout prevents a stuck git process
7
- * (e.g. an interactive credential prompt) from hanging the caller.
5
+ * Ensure the parent directory of a file path exists. Used by every
6
+ * caller that's about to write to disk and is fine with a no-op if the
7
+ * path is already at the cwd.
8
8
  */
9
- export declare function detectGit(): {
9
+ export declare function ensureDir(filePath: string): void;
10
+ /**
11
+ * Register the same handler for SIGTERM and SIGINT. Both signals route
12
+ * to graceful shutdown across the daemon and CLI entry points; doing it
13
+ * once here keeps the three call sites in lockstep.
14
+ */
15
+ export declare function registerGracefulShutdown(handler: () => void): void;
16
+ /**
17
+ * Read git branch + short SHA from `cwd` (defaults to process.cwd()).
18
+ * Returns nulls when not in a git repo or git is missing — never throws.
19
+ * The 3s timeout prevents a stuck git process (e.g. an interactive
20
+ * credential prompt) from hanging the caller.
21
+ */
22
+ export declare function detectGit(cwd?: string): {
10
23
  branch: string | null;
11
24
  commit: string | null;
12
25
  };
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/daemon/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;;;GAIG;AACH,wBAAgB,SAAS,IAAI;IAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAgB5E;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAO5C;AAED,6DAA6D;AAC7D,eAAO,MAAM,UAAU,mBAAa,CAAC"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/daemon/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAKhD;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI,CAIlE;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAkBxF;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAO5C;AAED,6DAA6D;AAC7D,eAAO,MAAM,UAAU,mBAAa,CAAC"}
@@ -2,19 +2,45 @@
2
2
  * Small utilities shared across daemon and term modules.
3
3
  */
4
4
  import { execFileSync } from 'node:child_process';
5
+ import * as fs from 'node:fs';
6
+ import * as path from 'node:path';
5
7
  /**
6
- * Read git branch + short SHA. Returns nulls when not in a git repo or git
7
- * is missing never throws. The 3s timeout prevents a stuck git process
8
- * (e.g. an interactive credential prompt) from hanging the caller.
8
+ * Ensure the parent directory of a file path exists. Used by every
9
+ * caller that's about to write to disk and is fine with a no-op if the
10
+ * path is already at the cwd.
9
11
  */
10
- export function detectGit() {
12
+ export function ensureDir(filePath) {
13
+ const dir = path.dirname(filePath);
14
+ if (dir && dir !== '.' && !fs.existsSync(dir)) {
15
+ fs.mkdirSync(dir, { recursive: true });
16
+ }
17
+ }
18
+ /**
19
+ * Register the same handler for SIGTERM and SIGINT. Both signals route
20
+ * to graceful shutdown across the daemon and CLI entry points; doing it
21
+ * once here keeps the three call sites in lockstep.
22
+ */
23
+ export function registerGracefulShutdown(handler) {
24
+ for (const sig of ['SIGTERM', 'SIGINT']) {
25
+ process.on(sig, handler);
26
+ }
27
+ }
28
+ /**
29
+ * Read git branch + short SHA from `cwd` (defaults to process.cwd()).
30
+ * Returns nulls when not in a git repo or git is missing — never throws.
31
+ * The 3s timeout prevents a stuck git process (e.g. an interactive
32
+ * credential prompt) from hanging the caller.
33
+ */
34
+ export function detectGit(cwd) {
11
35
  try {
12
36
  const branch = execFileSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {
37
+ cwd,
13
38
  encoding: 'utf-8',
14
39
  timeout: 3000,
15
40
  stdio: ['pipe', 'pipe', 'pipe'],
16
41
  }).trim();
17
42
  const commit = execFileSync('git', ['rev-parse', '--short=7', 'HEAD'], {
43
+ cwd,
18
44
  encoding: 'utf-8',
19
45
  timeout: 3000,
20
46
  stdio: ['pipe', 'pipe', 'pipe'],
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/daemon/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD;;;;GAIG;AACH,MAAM,UAAU,SAAS;IACvB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,cAAc,EAAE,MAAM,CAAC,EAAE;YACxE,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,IAAI;YACb,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;SAChC,CAAC,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,WAAW,EAAE,MAAM,CAAC,EAAE;YACrE,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,IAAI;YACb,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;SAChC,CAAC,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;IAC/D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACxC,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,CAAS;IAClC,OAAO,MAAM,CAAC,CAAC,CAAC;SACb,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAC5B,CAAC;AAED,6DAA6D;AAC7D,MAAM,CAAC,MAAM,UAAU,GAAG,UAAU,CAAC"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/daemon/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,QAAgB;IACxC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnC,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9C,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,wBAAwB,CAAC,OAAmB;IAC1D,KAAK,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAU,EAAE,CAAC;QACjD,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC3B,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,GAAY;IACpC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,cAAc,EAAE,MAAM,CAAC,EAAE;YACxE,GAAG;YACH,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,IAAI;YACb,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;SAChC,CAAC,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,WAAW,EAAE,MAAM,CAAC,EAAE;YACrE,GAAG;YACH,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,IAAI;YACb,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;SAChC,CAAC,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;IAC/D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACxC,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,CAAS;IAClC,OAAO,MAAM,CAAC,CAAC,CAAC;SACb,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAC5B,CAAC;AAED,6DAA6D;AAC7D,MAAM,CAAC,MAAM,UAAU,GAAG,UAAU,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"viewer.d.ts","sourceRoot":"","sources":["../../src/daemon/viewer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAIpD,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,YAAY,EAAE,CAAC;IAChC,cAAc,CAAC,EAAE,YAAY,EAAE,CAAC;IAChC;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAID,wBAAsB,cAAc,CAClC,QAAQ,EAAE,eAAe,EACzB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,CAAC,CAojBjB"}
1
+ {"version":3,"file":"viewer.d.ts","sourceRoot":"","sources":["../../src/daemon/viewer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAIpD,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,YAAY,EAAE,CAAC;IAChC,cAAc,CAAC,EAAE,YAAY,EAAE,CAAC;IAChC;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAaD,wBAAsB,cAAc,CAClC,QAAQ,EAAE,eAAe,EACzB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,CAAC,CAojBjB"}
@@ -17,6 +17,14 @@ import * as path from 'path';
17
17
  import { generateSummary } from './summary.js';
18
18
  import { escapeHtml } from './utils.js';
19
19
  // escapeHtml moved to ./utils.ts
20
+ // Encode a value as JSON safe to embed inside a <script> element.
21
+ // JSON itself never produces "</script>" or "<!--", but a string value
22
+ // might — escape every "<" so the HTML parser cannot terminate the
23
+ // surrounding script element. The browser still parses the JSON literal
24
+ // correctly (< decodes back to "<" at JSON.parse time).
25
+ function jsonForScript(value) {
26
+ return JSON.stringify(value).replace(/</g, '\\u003c');
27
+ }
20
28
  export async function generateViewer(manifest, options) {
21
29
  // The viewer can reference the WebM by relative path (default: keeps
22
30
  // the HTML small; reader needs both files) OR inline as base64 (for
@@ -239,18 +247,18 @@ export async function generateViewer(manifest, options) {
239
247
  </div>
240
248
  </div>
241
249
  <script>
242
- var actions = ${JSON.stringify(manifest.commands.map((c) => ({
250
+ var actions = ${jsonForScript(manifest.commands.map((c) => ({
243
251
  timestamp: c.timestamp,
244
252
  action: c.action,
245
253
  args: c.args,
246
254
  boundingBox: c.boundingBox,
247
255
  })))};
248
- var screenshots = ${JSON.stringify(screenshots.map((s) => s.data))};
256
+ var screenshots = ${jsonForScript(screenshots.map((s) => s.data))};
249
257
  var duration = ${manifest.duration};
250
258
  var hasVideo = ${hasVideo};
251
- var summaryReport = ${JSON.stringify(summaryMd)};
252
- var consoleEntries = ${JSON.stringify(sanitizedConsole)};
253
- var networkEntries = ${JSON.stringify(sanitizedNetwork)};
259
+ var summaryReport = ${jsonForScript(summaryMd)};
260
+ var consoleEntries = ${jsonForScript(sanitizedConsole)};
261
+ var networkEntries = ${jsonForScript(sanitizedNetwork)};
254
262
 
255
263
  var currentAction = -1;
256
264
  var autoStepping = false;
@@ -1 +1 @@
1
- {"version":3,"file":"viewer.js","sourceRoot":"","sources":["../../src/daemon/viewer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAG7B,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAgBxC,iCAAiC;AAEjC,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,QAAyB,EACzB,OAAsB;IAEtB,qEAAqE;IACrE,oEAAoE;IACpE,qCAAqC;IACrC,MAAM,UAAU,GAAG,OAAO,CAAC,WAAW,KAAK,IAAI,CAAC;IAChD,IAAI,WAAW,GAAkB,IAAI,CAAC;IACtC,IAAI,WAAW,GAAG,KAAK,CAAC;IACxB,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QACnB,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;QAChE,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;YAC5C,WAAW,GAAG,IAAI,CAAC;YACnB,IAAI,UAAU;gBAAE,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC1D,CAAC;QAAC,MAAM,CAAC;YACP,8BAA8B;QAChC,CAAC;IACH,CAAC;IAED,6CAA6C;IAC7C,MAAM,WAAW,GAA0C,EAAE,CAAC;IAC9D,KAAK,MAAM,GAAG,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC;QACpC,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;YACnB,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC;gBAChF,WAAW,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,UAAU,EAAE,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YAC9E,CAAC;YAAC,MAAM,CAAC;gBACP,kBAAkB;YACpB,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC;IAC/F,MAAM,gBAAgB,GAAG,CAAC,OAAO,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAClE,SAAS,EAAE,CAAC,CAAC,SAAS;QACtB,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;QACxC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS;KACpE,CAAC,CAAC,CAAC;IACJ,MAAM,gBAAgB,GAAG,CAAC,OAAO,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAClE,SAAS,EAAE,CAAC,CAAC,SAAS;QACtB,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;QAChC,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,QAAQ,EAAE,CAAC,CAAC,QAAQ;KACrB,CAAC,CAAC,CAAC;IAEJ,MAAM,YAAY,GAAG,QAAQ,CAAC,QAAQ;SACnC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;QACd,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACjE,MAAM,EAAE,GAAG,GAAG,CAAC,WAAW,CAAC;QAC3B,MAAM,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACzE,OAAO,wCAAwC,CAAC,gBAAgB,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;gCAC9D,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;iCACvB,MAAM;iCACN,UAAU,CAAC,MAAM,CAAC;WACxC,CAAC;IACR,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,MAAM,QAAQ,GAAG,WAAW,CAAC;IAE7B,+CAA+C;IAC/C,MAAM,SAAS,GAAG,eAAe,CAAC;QAChC,QAAQ;QACR,cAAc,EAAE,OAAO,CAAC,cAAc;QACtC,cAAc,EAAE,OAAO,CAAC,cAAc;KACvC,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG;;;;;4BAKa,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAwFpD,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,6SAA6S,CAAC,CAAC,CAAC,EAAE;;;;MAIrW,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,0BAA0B,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,yDAAyD,CAAC,CAAC,CAAC,EAAE;qEAC/I,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,QAAQ,CAAC,QAAQ,CAAC,MAAM,WAAW,QAAQ,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE;yBAC1J,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,KAAK,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,WAAW,SAAS;;;;;;;;QASjH,QAAQ;QACN,CAAC,CAAC,WAAW;YACX,CAAC,CAAC,kDAAkD,WAAW,2BAA2B;YAC1F,CAAC,CAAC,2BAA2B,UAAU,CAAC,QAAQ,CAAC,KAAM,CAAC,2BAA2B;QACrF,CAAC,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC;YACtB,CAAC,CAAC,uDAAuD,WAAW,CAAC,CAAC,CAAE,CAAC,IAAI,MAAM;YACnF,CAAC,CAAC,kDACR;;;;;;;UAOI,QAAQ,CAAC,QAAQ;SAChB,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;QACd,MAAM,GAAG,GAAG,QAAQ,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAClF,OAAO,yCAAyC,CAAC,gBAAgB,GAAG,CAAC,SAAS,iBAAiB,GAAG,aAAa,UAAU,CAAC,GAAG,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC;IAC7K,CAAC,CAAC;SACD,IAAI,CAAC,EAAE,CAAC;;;UAGT,QAAQ,CAAC,CAAC,CAAC,iDAAiD,CAAC,CAAC,CAAC,EAAE;;;;8DAIb,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;;;;;;;;;;;8DAW5B,QAAQ,CAAC,QAAQ,CAAC,MAAM;;;;;;UAM5E,YAAY,IAAI,8CAA8C;;;;;;;;gBAQxD,IAAI,CAAC,SAAS,CAC1B,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC5B,SAAS,EAAE,CAAC,CAAC,SAAS;QACtB,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,WAAW,EAAE,CAAC,CAAC,WAAW;KAC3B,CAAC,CAAC,CACJ;oBACiB,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;iBACjD,QAAQ,CAAC,QAAQ;iBACjB,QAAQ;sBACH,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC;uBACxB,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC;uBAChC,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA+T/C,CAAC;IAEP,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;IACtF,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IAC9C,OAAO,UAAU,CAAC;AACpB,CAAC"}
1
+ {"version":3,"file":"viewer.js","sourceRoot":"","sources":["../../src/daemon/viewer.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -9,7 +9,7 @@ export { SweetlinkBridge, type SweetlinkBridgeConfig } from './browser/Sweetlink
9
9
  export { canvasToDataUrl, copyCanvasToClipboard, DEFAULT_SCREENSHOT_QUALITY, DEFAULT_SCREENSHOT_SCALE, delay, extractBase64FromDataUrl, getMediaTypeFromDataUrl, hideDevbarForCapture, type PrepareForCaptureOptions, prepareForCapture, type ScaleCanvasOptions, scaleCanvas, type ToDataUrlOptions, } from './browser/screenshotUtils.js';
10
10
  export type { ElementMeasurement, MeasurementOptions, MeasurementResult, RulerOutput, } from './ruler.js';
11
11
  export type { InitSweetlinkOptions } from './server.js';
12
- export type { ApiKeyStatusCommand, BrowserClientReadyCommand, ChannelSubscribeCommand, ChannelSubscription, ChannelUnsubscribeCommand, CheckApiKeyCommand, ConsoleLog, DesignReviewErrorCommand, DesignReviewSavedCommand, DesignReviewScreenshotCommand, ExecJsCommand, GetLogsCommand, GetNetworkCommand, HmrScreenshotCommand, HmrScreenshotData, LoadSettingsCommand, LogEventCommand, LogSubscribeCommand, LogSubscription, LogUnsubscribeCommand, OutlineErrorCommand, OutlineNode, OutlineSavedCommand, PageSchema, QueryDomCommand, RefreshCommand, RequestScreenshotCommand, SaveOutlineCommand, SaveSchemaCommand, SaveScreenshotCommand, SaveSettingsCommand, SchemaErrorCommand, SchemaSavedCommand, ScreenshotCommand, ScreenshotResponseCommand, ScreenshotSavedCommand, ServerInfo, SettingsErrorCommand, SettingsLoadedCommand, SettingsSavedCommand, SweetlinkCommand, SweetlinkResponse, } from './types.js';
12
+ export type { ApiKeyStatusCommand, BrowserClientReadyCommand, ChannelSubscribeCommand, ChannelSubscription, ChannelUnsubscribeCommand, CheckApiKeyCommand, ConsoleLog, DesignReviewErrorCommand, DesignReviewSavedCommand, DesignReviewScreenshotCommand, ExecJsCommand, GetLogsCommand, GetNetworkCommand, HmrScreenshotCommand, HmrScreenshotData, LoadSettingsCommand, LogEventCommand, LogSubscribeCommand, LogSubscription, LogUnsubscribeCommand, MetaImage, MicrodataItem, MissingTag, OutlineCategory, OutlineErrorCommand, OutlineNode, OutlineSavedCommand, PageSchema, QueryDomCommand, RefreshCommand, RequestScreenshotCommand, SaveOutlineCommand, SaveSchemaCommand, SaveScreenshotCommand, SaveSettingsCommand, SchemaErrorCommand, SchemaSavedCommand, ScreenshotCommand, ScreenshotResponseCommand, ScreenshotSavedCommand, ServerInfo, SettingsErrorCommand, SettingsLoadedCommand, SettingsSavedCommand, SweetlinkCommand, SweetlinkResponse, } from './types.js';
13
13
  export { formatTimestampForFilename, generateBaseFilename, generateSlugFromUrl, HMR_SCREENSHOT_DIR, MAX_LOG_MESSAGE_LENGTH, MAX_SLUG_LENGTH, SCREENSHOT_DIR, truncateMessage, } from './urlUtils.js';
14
14
  export { DEFAULT_VIEWPORT, parseViewport, VIEWPORT_PRESETS, type ViewportConfig, } from './viewportUtils.js';
15
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,cAAc,EACd,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,SAAS,EACT,UAAU,EACV,KAAK,iBAAiB,EACtB,gBAAgB,EAChB,KAAK,sBAAsB,GAC5B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,4BAA4B,EAAE,MAAM,kCAAkC,CAAC;AAEhF,OAAO,EAAE,eAAe,EAAE,KAAK,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAC3F,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,0BAA0B,EAC1B,wBAAwB,EACxB,KAAK,EACL,wBAAwB,EACxB,uBAAuB,EACvB,oBAAoB,EACpB,KAAK,wBAAwB,EAC7B,iBAAiB,EACjB,KAAK,kBAAkB,EACvB,WAAW,EACX,KAAK,gBAAgB,GACtB,MAAM,8BAA8B,CAAC;AAEtC,YAAY,EACV,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,WAAW,GACZ,MAAM,YAAY,CAAC;AAEpB,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAExD,YAAY,EACV,mBAAmB,EACnB,yBAAyB,EACzB,uBAAuB,EACvB,mBAAmB,EACnB,yBAAyB,EACzB,kBAAkB,EAClB,UAAU,EACV,wBAAwB,EACxB,wBAAwB,EACxB,6BAA6B,EAC7B,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,EACnB,eAAe,EACf,mBAAmB,EACnB,eAAe,EACf,qBAAqB,EACrB,mBAAmB,EACnB,WAAW,EACX,mBAAmB,EACnB,UAAU,EACV,eAAe,EACf,cAAc,EACd,wBAAwB,EACxB,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,yBAAyB,EACzB,sBAAsB,EACtB,UAAU,EACV,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,0BAA0B,EAC1B,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,EAClB,sBAAsB,EACtB,eAAe,EACf,cAAc,EACd,eAAe,GAChB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,KAAK,cAAc,GACpB,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,cAAc,EACd,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,SAAS,EACT,UAAU,EACV,KAAK,iBAAiB,EACtB,gBAAgB,EAChB,KAAK,sBAAsB,GAC5B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,4BAA4B,EAAE,MAAM,kCAAkC,CAAC;AAEhF,OAAO,EAAE,eAAe,EAAE,KAAK,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAC3F,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,0BAA0B,EAC1B,wBAAwB,EACxB,KAAK,EACL,wBAAwB,EACxB,uBAAuB,EACvB,oBAAoB,EACpB,KAAK,wBAAwB,EAC7B,iBAAiB,EACjB,KAAK,kBAAkB,EACvB,WAAW,EACX,KAAK,gBAAgB,GACtB,MAAM,8BAA8B,CAAC;AAEtC,YAAY,EACV,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,WAAW,GACZ,MAAM,YAAY,CAAC;AAEpB,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAExD,YAAY,EACV,mBAAmB,EACnB,yBAAyB,EACzB,uBAAuB,EACvB,mBAAmB,EACnB,yBAAyB,EACzB,kBAAkB,EAClB,UAAU,EACV,wBAAwB,EACxB,wBAAwB,EACxB,6BAA6B,EAC7B,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,EACnB,eAAe,EACf,mBAAmB,EACnB,eAAe,EACf,qBAAqB,EACrB,SAAS,EACT,aAAa,EACb,UAAU,EACV,eAAe,EACf,mBAAmB,EACnB,WAAW,EACX,mBAAmB,EACnB,UAAU,EACV,eAAe,EACf,cAAc,EACd,wBAAwB,EACxB,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,yBAAyB,EACzB,sBAAsB,EACtB,UAAU,EACV,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,0BAA0B,EAC1B,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,EAClB,sBAAsB,EACtB,eAAe,EACf,cAAc,EACd,eAAe,GAChB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,KAAK,cAAc,GACpB,MAAM,oBAAoB,CAAC"}
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,2DAA2D;AAC3D,OAAO,EACL,cAAc,EAGd,SAAS,EACT,UAAU,EAEV,gBAAgB,GAEjB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,4BAA4B,EAAE,MAAM,kCAAkC,CAAC;AAChF,8DAA8D;AAC9D,OAAO,EAAE,eAAe,EAA8B,MAAM,8BAA8B,CAAC;AAC3F,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,0BAA0B,EAC1B,wBAAwB,EACxB,KAAK,EACL,wBAAwB,EACxB,uBAAuB,EACvB,oBAAoB,EAEpB,iBAAiB,EAEjB,WAAW,GAEZ,MAAM,8BAA8B,CAAC;AAuDtC,gBAAgB;AAChB,OAAO,EACL,0BAA0B,EAC1B,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,EAClB,sBAAsB,EACtB,eAAe,EACf,cAAc,EACd,eAAe,GAChB,MAAM,eAAe,CAAC;AACvB,oDAAoD;AACpD,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,gBAAgB,GAEjB,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,2DAA2D;AAC3D,OAAO,EACL,cAAc,EAGd,SAAS,EACT,UAAU,EAEV,gBAAgB,GAEjB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,4BAA4B,EAAE,MAAM,kCAAkC,CAAC;AAChF,8DAA8D;AAC9D,OAAO,EAAE,eAAe,EAA8B,MAAM,8BAA8B,CAAC;AAC3F,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,0BAA0B,EAC1B,wBAAwB,EACxB,KAAK,EACL,wBAAwB,EACxB,uBAAuB,EACvB,oBAAoB,EAEpB,iBAAiB,EAEjB,WAAW,GAEZ,MAAM,8BAA8B,CAAC;AA2DtC,gBAAgB;AAChB,OAAO,EACL,0BAA0B,EAC1B,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,EAClB,sBAAsB,EACtB,eAAe,EACf,cAAc,EACd,eAAe,GAChB,MAAM,eAAe,CAAC;AACvB,oDAAoD;AACpD,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,gBAAgB,GAEjB,MAAM,oBAAoB,CAAC"}
@@ -39,7 +39,7 @@ export declare function screenshotViaPlaywright(options: {
39
39
  selector?: string;
40
40
  output?: string;
41
41
  fullPage?: boolean;
42
- viewport?: string;
42
+ viewport?: import('./viewportUtils.js').ViewportName | string;
43
43
  hover?: boolean;
44
44
  hideDevbar?: boolean;
45
45
  a11y?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"playwright.d.ts","sourceRoot":"","sources":["../src/playwright.ts"],"names":[],"mappings":"AAqCA,KAAK,OAAO,GAAG,OAAO,YAAY,EAAE,OAAO,CAAC;AAC5C,KAAK,cAAc,GAAG,OAAO,YAAY,EAAE,cAAc,CAAC;AAC1D,KAAK,IAAI,GAAG,OAAO,YAAY,EAAE,IAAI,CAAC;AAoDtC;;;GAGG;AACH,wBAAsB,UAAU,CAC9B,GAAG,CAAC,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAC9B,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC,CAoD3D;AAED,2DAA2D;AAC3D,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,CAmB/E;AAED,yEAAyE;AACzE,wBAAsB,6BAA6B,CAAC,CAAC,EACnD,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACxB,OAAO,CAAC,CAAC,CAAC,CAQZ;AAED;;;;;;GAMG;AACH,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,IAAI,CAkCvE;AAED;;;GAGG;AACH,wBAAgB,0CAA0C,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,IAAI,CAoB9F;AAED;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAAC,OAAO,EAAE;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAiB7D"}
1
+ {"version":3,"file":"playwright.d.ts","sourceRoot":"","sources":["../src/playwright.ts"],"names":[],"mappings":"AA+BA,KAAK,OAAO,GAAG,OAAO,YAAY,EAAE,OAAO,CAAC;AAC5C,KAAK,cAAc,GAAG,OAAO,YAAY,EAAE,cAAc,CAAC;AAC1D,KAAK,IAAI,GAAG,OAAO,YAAY,EAAE,IAAI,CAAC;AA4CtC;;;GAGG;AACH,wBAAsB,UAAU,CAC9B,GAAG,CAAC,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAC9B,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC,CAoD3D;AAED,2DAA2D;AAC3D,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,CAmB/E;AAED,yEAAyE;AACzE,wBAAsB,6BAA6B,CAAC,CAAC,EACnD,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACxB,OAAO,CAAC,CAAC,CAAC,CAQZ;AAED;;;;;;GAMG;AACH,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,IAAI,CAkCvE;AAED;;;GAGG;AACH,wBAAgB,0CAA0C,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,IAAI,CAoB9F;AAED;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAAC,OAAO,EAAE;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,oBAAoB,EAAE,YAAY,GAAG,MAAM,CAAC;IAC9D,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAiB7D"}
@@ -1,5 +1,5 @@
1
- import * as fs from 'fs';
2
- import * as path from 'path';
1
+ import { ensureDir } from './daemon/utils.js';
2
+ import { HIDE_DEVBAR_CSS, HIDE_DEVBAR_STYLE_ID, HOVER_TRANSITION_DELAY_MS, SELECTOR_TIMEOUT_MS, } from './screenshotConstants.js';
3
3
  import { DEFAULT_VIEWPORT, parseViewport } from './viewportUtils.js';
4
4
  // ============================================================================
5
5
  // Constants
@@ -8,18 +8,7 @@ const DEFAULT_DEV_URL = process.env.SWEETLINK_DEV_URL || 'http://localhost:3000'
8
8
  const CDP_URL = process.env.CHROME_CDP_URL || 'http://localhost:9222';
9
9
  const CDP_CONNECTION_TIMEOUT_MS = 2000;
10
10
  const NAVIGATION_TIMEOUT_MS = 30000;
11
- const SELECTOR_TIMEOUT_MS = 5000;
12
- const HOVER_TRANSITION_DELAY_MS = 300;
13
11
  const HIDE_DEVBAR_SETTLE_MS = 50;
14
- const HIDE_DEVBAR_STYLE_ID = 'sweetlink-hide-devbar-for-screenshot';
15
- const HIDE_DEVBAR_CSS = `
16
- [data-devbar],
17
- [data-devbar-overlay],
18
- [data-devbar-tooltip] {
19
- visibility: hidden !important;
20
- pointer-events: none !important;
21
- }
22
- `;
23
12
  /** Hard timeout for the entire screenshot operation (browser launch + navigate + capture).
24
13
  * Prevents orphaned Playwright processes when the dev server dies mid-operation.
25
14
  * Configurable via SWEETLINK_OPERATION_TIMEOUT env var (in ms). */
@@ -55,15 +44,7 @@ async function getPlaywright() {
55
44
  throw error;
56
45
  }
57
46
  }
58
- /**
59
- * Ensure the directory for a file path exists
60
- */
61
- function ensureDir(filePath) {
62
- const dir = path.dirname(filePath);
63
- if (dir && dir !== '.' && !fs.existsSync(dir)) {
64
- fs.mkdirSync(dir, { recursive: true });
65
- }
66
- }
47
+ // ensureDir lives in daemon/utils.ts — single source of truth.
67
48
  /**
68
49
  * Get a Playwright browser instance
69
50
  * Tries to connect to existing CDP first, then falls back to launching a new instance