@ytspar/sweetlink 1.21.0 → 1.23.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.
- package/README.md +77 -0
- package/dist/browser/SweetlinkBridge.d.ts +9 -0
- package/dist/browser/SweetlinkBridge.d.ts.map +1 -1
- package/dist/browser/SweetlinkBridge.js +73 -20
- package/dist/browser/SweetlinkBridge.js.map +1 -1
- package/dist/browser/commands/screenshot.d.ts.map +1 -1
- package/dist/browser/commands/screenshot.js +16 -7
- package/dist/browser/commands/screenshot.js.map +1 -1
- package/dist/browser/consoleCapture.js +1 -1
- package/dist/browser/consoleCapture.js.map +1 -1
- package/dist/browser/earlyConsoleCapture.d.ts +1 -1
- package/dist/browser/earlyConsoleCapture.d.ts.map +1 -1
- package/dist/browser/screenshotUtils.d.ts +13 -3
- package/dist/browser/screenshotUtils.d.ts.map +1 -1
- package/dist/browser/screenshotUtils.js +32 -6
- package/dist/browser/screenshotUtils.js.map +1 -1
- package/dist/cdp.d.ts +1 -0
- package/dist/cdp.d.ts.map +1 -1
- package/dist/cdp.js +34 -3
- package/dist/cdp.js.map +1 -1
- package/dist/cli/outputSchemas.d.ts +1 -0
- package/dist/cli/outputSchemas.d.ts.map +1 -1
- package/dist/cli/outputSchemas.js +1 -0
- package/dist/cli/outputSchemas.js.map +1 -1
- package/dist/cli/sweetlink-dev.d.ts +5 -2
- package/dist/cli/sweetlink-dev.d.ts.map +1 -1
- package/dist/cli/sweetlink-dev.js +12 -4
- package/dist/cli/sweetlink-dev.js.map +1 -1
- package/dist/cli/sweetlink.js +148 -64
- package/dist/cli/sweetlink.js.map +1 -1
- package/dist/daemon/browser.d.ts +3 -0
- package/dist/daemon/browser.d.ts.map +1 -1
- package/dist/daemon/browser.js +38 -5
- package/dist/daemon/browser.js.map +1 -1
- package/dist/daemon/demo.d.ts.map +1 -1
- package/dist/daemon/demo.js +3 -19
- package/dist/daemon/demo.js.map +1 -1
- package/dist/daemon/recording.d.ts +1 -1
- package/dist/daemon/recording.d.ts.map +1 -1
- package/dist/daemon/recording.js +1 -19
- package/dist/daemon/recording.js.map +1 -1
- package/dist/daemon/server.d.ts.map +1 -1
- package/dist/daemon/server.js +7 -9
- package/dist/daemon/server.js.map +1 -1
- package/dist/daemon/session.d.ts +8 -1
- package/dist/daemon/session.d.ts.map +1 -1
- package/dist/daemon/types.d.ts +9 -2
- package/dist/daemon/types.d.ts.map +1 -1
- package/dist/daemon/types.js.map +1 -1
- package/dist/daemon/utils.d.ts +22 -0
- package/dist/daemon/utils.d.ts.map +1 -0
- package/dist/daemon/utils.js +44 -0
- package/dist/daemon/utils.js.map +1 -0
- package/dist/daemon/viewer.d.ts.map +1 -1
- package/dist/daemon/viewer.js +2 -8
- package/dist/daemon/viewer.js.map +1 -1
- package/dist/daemon/visualDiff.d.ts +9 -0
- package/dist/daemon/visualDiff.d.ts.map +1 -1
- package/dist/daemon/visualDiff.js +12 -1
- package/dist/daemon/visualDiff.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/next.d.ts.map +1 -1
- package/dist/next.js +16 -1
- package/dist/next.js.map +1 -1
- package/dist/playwright.d.ts +19 -0
- package/dist/playwright.d.ts.map +1 -1
- package/dist/playwright.js +119 -12
- package/dist/playwright.js.map +1 -1
- package/dist/runs.d.ts +15 -3
- package/dist/runs.d.ts.map +1 -1
- package/dist/runs.js +29 -13
- package/dist/runs.js.map +1 -1
- package/dist/server/index.d.ts +7 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +56 -16
- package/dist/server/index.js.map +1 -1
- package/dist/simulator/android.d.ts +6 -0
- package/dist/simulator/android.d.ts.map +1 -1
- package/dist/simulator/android.js +81 -4
- package/dist/simulator/android.js.map +1 -1
- package/dist/simulator/androidTaps.d.ts +12 -2
- package/dist/simulator/androidTaps.d.ts.map +1 -1
- package/dist/simulator/androidTaps.js +57 -11
- package/dist/simulator/androidTaps.js.map +1 -1
- package/dist/simulator/ios.d.ts +7 -0
- package/dist/simulator/ios.d.ts.map +1 -1
- package/dist/simulator/ios.js +70 -25
- package/dist/simulator/ios.js.map +1 -1
- package/dist/term/cast.d.ts +24 -0
- package/dist/term/cast.d.ts.map +1 -0
- package/dist/term/cast.js +24 -0
- package/dist/term/cast.js.map +1 -0
- package/dist/term/player.d.ts.map +1 -1
- package/dist/term/player.js +36 -14
- package/dist/term/player.js.map +1 -1
- package/dist/term/recorder.d.ts +7 -0
- package/dist/term/recorder.d.ts.map +1 -1
- package/dist/term/recorder.js +35 -1
- package/dist/term/recorder.js.map +1 -1
- package/dist/types.d.ts +37 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +127 -0
- package/dist/types.js.map +1 -1
- package/dist/vite.d.ts +11 -0
- package/dist/vite.d.ts.map +1 -1
- package/dist/vite.js +20 -1
- package/dist/vite.js.map +1 -1
- package/package.json +1 -1
- package/dist/term/ansi.d.ts +0 -37
- package/dist/term/ansi.d.ts.map +0 -1
- package/dist/term/ansi.js +0 -205
- package/dist/term/ansi.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"androidTaps.d.ts","sourceRoot":"","sources":["../../src/simulator/androidTaps.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,KAAK,YAAY,EAAmB,MAAM,eAAe,CAAC;AAEnE,MAAM,WAAW,QAAQ;IACvB,8CAA8C;IAC9C,CAAC,EAAE,MAAM,CAAC;IACV,8CAA8C;IAC9C,CAAC,EAAE,MAAM,CAAC;IACV,qCAAqC;IACrC,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,eAAe;IAC9B,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,WAAW,EAAE,MAAM,CAAC;IACpB,gCAAgC;IAChC,YAAY,EAAE,MAAM,CAAC;CACtB;AAWD;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAMjF;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,GACV,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,OAAO,CAAA;CAAE,CAAC,CAgB3E;AAED;;;GAGG;AACH,wBAAsB,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAqBpF;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AACD,wBAAgB,eAAe,IAAI,UAAU,CAE5C;
|
|
1
|
+
{"version":3,"file":"androidTaps.d.ts","sourceRoot":"","sources":["../../src/simulator/androidTaps.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,KAAK,YAAY,EAAmB,MAAM,eAAe,CAAC;AAEnE,MAAM,WAAW,QAAQ;IACvB,8CAA8C;IAC9C,CAAC,EAAE,MAAM,CAAC;IACV,8CAA8C;IAC9C,CAAC,EAAE,MAAM,CAAC;IACV,qCAAqC;IACrC,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,eAAe;IAC9B,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,WAAW,EAAE,MAAM,CAAC;IACpB,gCAAgC;IAChC,YAAY,EAAE,MAAM,CAAC;CACtB;AAWD;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAMjF;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,GACV,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,OAAO,CAAA;CAAE,CAAC,CAgB3E;AAED;;;GAGG;AACH,wBAAsB,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAqBpF;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AACD,wBAAgB,eAAe,IAAI,UAAU,CAE5C;AAgBD,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,MAAM,CAAC,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GACjF,QAAQ,EAAE,CAkCZ;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,eAAe,EACrB,OAAO,EAAE,MAAM,GACd;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,QAAQ,EAAE,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAiD/D"}
|
|
@@ -99,7 +99,23 @@ export async function findTouchDevice(deviceSerial) {
|
|
|
99
99
|
export function freshParseState() {
|
|
100
100
|
return { curX: null, curY: null, downAtMs: null };
|
|
101
101
|
}
|
|
102
|
-
|
|
102
|
+
/**
|
|
103
|
+
* Parse a hex value from `getevent` output. A hostile / unusual adb daemon
|
|
104
|
+
* (manufacturer firmware, network adb at 5555) can emit non-hex tokens or
|
|
105
|
+
* extra-large values; reject those rather than letting NaN/huge numbers
|
|
106
|
+
* propagate into the overlay filter and silently break ffmpeg.
|
|
107
|
+
*/
|
|
108
|
+
function safeHex(value, max) {
|
|
109
|
+
if (!value)
|
|
110
|
+
return null;
|
|
111
|
+
if (!/^[0-9a-fA-F]+$/.test(value))
|
|
112
|
+
return null;
|
|
113
|
+
const n = parseInt(value, 16);
|
|
114
|
+
if (!Number.isFinite(n) || n < 0 || n > max)
|
|
115
|
+
return null;
|
|
116
|
+
return n;
|
|
117
|
+
}
|
|
118
|
+
export function processGetEventChunk(text, state, scaleX, scaleY, startMs, nowMs, bounds) {
|
|
103
119
|
const out = [];
|
|
104
120
|
for (const line of text.split('\n')) {
|
|
105
121
|
const m = line.match(/^\/dev\/input\/\S+:\s+(EV_\w+)\s+(\w+)\s+(\w+)/);
|
|
@@ -107,10 +123,14 @@ export function processGetEventChunk(text, state, scaleX, scaleY, startMs, nowMs
|
|
|
107
123
|
continue;
|
|
108
124
|
const [, evType, evCode, valueStr] = m;
|
|
109
125
|
if (evType === 'EV_ABS' && evCode === 'ABS_MT_POSITION_X') {
|
|
110
|
-
|
|
126
|
+
const v = safeHex(valueStr, bounds?.maxX ?? Number.MAX_SAFE_INTEGER);
|
|
127
|
+
if (v !== null)
|
|
128
|
+
state.curX = v;
|
|
111
129
|
}
|
|
112
130
|
else if (evType === 'EV_ABS' && evCode === 'ABS_MT_POSITION_Y') {
|
|
113
|
-
|
|
131
|
+
const v = safeHex(valueStr, bounds?.maxY ?? Number.MAX_SAFE_INTEGER);
|
|
132
|
+
if (v !== null)
|
|
133
|
+
state.curY = v;
|
|
114
134
|
}
|
|
115
135
|
else if (evType === 'EV_KEY' && evCode === 'BTN_TOUCH') {
|
|
116
136
|
if (valueStr === 'DOWN') {
|
|
@@ -118,11 +138,15 @@ export function processGetEventChunk(text, state, scaleX, scaleY, startMs, nowMs
|
|
|
118
138
|
}
|
|
119
139
|
else if (valueStr === 'UP') {
|
|
120
140
|
if (state.curX !== null && state.curY !== null && state.downAtMs !== null) {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
141
|
+
const px = Math.round(state.curX * scaleX);
|
|
142
|
+
const py = Math.round(state.curY * scaleY);
|
|
143
|
+
const sw = bounds?.screenWidth;
|
|
144
|
+
const sh = bounds?.screenHeight;
|
|
145
|
+
const x = sw ? Math.max(0, Math.min(sw, px)) : px;
|
|
146
|
+
const y = sh ? Math.max(0, Math.min(sh, py)) : py;
|
|
147
|
+
if (Number.isFinite(x) && Number.isFinite(y)) {
|
|
148
|
+
out.push({ x, y, t: (state.downAtMs - startMs) / 1000 });
|
|
149
|
+
}
|
|
126
150
|
}
|
|
127
151
|
state.curX = null;
|
|
128
152
|
state.curY = null;
|
|
@@ -135,16 +159,27 @@ export function processGetEventChunk(text, state, scaleX, scaleY, startMs, nowMs
|
|
|
135
159
|
/**
|
|
136
160
|
* Spawn a `getevent -l` listener for the given input path. Returns the
|
|
137
161
|
* child process plus a live array of tap events that the caller can read
|
|
138
|
-
* after they
|
|
162
|
+
* after they await `done` (or kill the process and await close).
|
|
163
|
+
*
|
|
164
|
+
* `done` resolves once the proc 'close' event fires AND the trailing
|
|
165
|
+
* buffered partial line has been processed — without it, taps in the final
|
|
166
|
+
* milliseconds before SIGTERM are silently dropped.
|
|
139
167
|
*/
|
|
140
168
|
export function captureTapsLive(deviceSerial, info, startMs) {
|
|
141
169
|
const taps = [];
|
|
142
170
|
const state = freshParseState();
|
|
143
171
|
const scaleX = info.screenWidth / info.maxX;
|
|
144
172
|
const scaleY = info.screenHeight / info.maxY;
|
|
173
|
+
const bounds = {
|
|
174
|
+
maxX: info.maxX,
|
|
175
|
+
maxY: info.maxY,
|
|
176
|
+
screenWidth: info.screenWidth,
|
|
177
|
+
screenHeight: info.screenHeight,
|
|
178
|
+
};
|
|
145
179
|
const proc = spawn('adb', ['-s', deviceSerial, 'shell', 'getevent', '-l', info.path], {
|
|
146
180
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
147
181
|
});
|
|
182
|
+
proc.unref(); // don't keep the parent process alive past its main work
|
|
148
183
|
let buffer = '';
|
|
149
184
|
proc.stdout?.on('data', (chunk) => {
|
|
150
185
|
buffer += chunk.toString();
|
|
@@ -154,9 +189,20 @@ export function captureTapsLive(deviceSerial, info, startMs) {
|
|
|
154
189
|
return;
|
|
155
190
|
const ready = buffer.slice(0, lastNl);
|
|
156
191
|
buffer = buffer.slice(lastNl + 1);
|
|
157
|
-
const newTaps = processGetEventChunk(ready, state, scaleX, scaleY, startMs, Date.now());
|
|
192
|
+
const newTaps = processGetEventChunk(ready, state, scaleX, scaleY, startMs, Date.now(), bounds);
|
|
158
193
|
taps.push(...newTaps);
|
|
159
194
|
});
|
|
160
|
-
|
|
195
|
+
const done = new Promise((resolve) => {
|
|
196
|
+
proc.on('close', () => {
|
|
197
|
+
// Flush trailing buffer — anything that didn't end with \n.
|
|
198
|
+
if (buffer.length > 0) {
|
|
199
|
+
const newTaps = processGetEventChunk(buffer, state, scaleX, scaleY, startMs, Date.now(), bounds);
|
|
200
|
+
taps.push(...newTaps);
|
|
201
|
+
buffer = '';
|
|
202
|
+
}
|
|
203
|
+
resolve();
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
return { proc, taps, done };
|
|
161
207
|
}
|
|
162
208
|
//# sourceMappingURL=androidTaps.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"androidTaps.js","sourceRoot":"","sources":["../../src/simulator/androidTaps.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"androidTaps.js","sourceRoot":"","sources":["../../src/simulator/androidTaps.ts"],"names":[],"mappings":"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"}
|
package/dist/simulator/ios.d.ts
CHANGED
|
@@ -18,6 +18,13 @@ export interface IosRecordOptions {
|
|
|
18
18
|
cwd?: string;
|
|
19
19
|
/** Override shell. */
|
|
20
20
|
shell?: string;
|
|
21
|
+
/**
|
|
22
|
+
* When true, the spawned command sees the full process.env. Default false:
|
|
23
|
+
* only a small allowlist (PATH/HOME/USER/LANG/SHELL/etc.) is forwarded so
|
|
24
|
+
* secrets in env (NPM_TOKEN, GH_TOKEN, ANTHROPIC_API_KEY, ...) cannot leak
|
|
25
|
+
* into the recorded .mp4 via stack traces or test logs.
|
|
26
|
+
*/
|
|
27
|
+
inheritEnv?: boolean;
|
|
21
28
|
}
|
|
22
29
|
export interface IosRecordResult {
|
|
23
30
|
output: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ios.d.ts","sourceRoot":"","sources":["../../src/simulator/ios.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,MAAM,WAAW,gBAAgB;IAC/B,4CAA4C;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,MAAM,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oCAAoC;IACpC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,sBAAsB;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"ios.d.ts","sourceRoot":"","sources":["../../src/simulator/ios.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,MAAM,WAAW,gBAAgB;IAC/B,4CAA4C;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,MAAM,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oCAAoC;IACpC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,sBAAsB;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAyBD,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,4EAA4E;IAC5E,eAAe,EAAE,OAAO,CAAC;CAC1B;AAoBD;;;GAGG;AACH,wBAAsB,aAAa,CACjC,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAqBhD;AAED,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAuG5F"}
|
package/dist/simulator/ios.js
CHANGED
|
@@ -10,6 +10,28 @@
|
|
|
10
10
|
import { execFile, spawn } from 'child_process';
|
|
11
11
|
import { promises as fs } from 'fs';
|
|
12
12
|
import * as path from 'path';
|
|
13
|
+
const MINIMAL_ENV_KEYS = [
|
|
14
|
+
'PATH',
|
|
15
|
+
'HOME',
|
|
16
|
+
'USER',
|
|
17
|
+
'LANG',
|
|
18
|
+
'LC_ALL',
|
|
19
|
+
'LC_CTYPE',
|
|
20
|
+
'TERM',
|
|
21
|
+
'SHELL',
|
|
22
|
+
'TZ',
|
|
23
|
+
'TMPDIR',
|
|
24
|
+
'PWD',
|
|
25
|
+
];
|
|
26
|
+
function pickMinimalEnv() {
|
|
27
|
+
const out = {};
|
|
28
|
+
for (const key of MINIMAL_ENV_KEYS) {
|
|
29
|
+
const v = process.env[key];
|
|
30
|
+
if (typeof v === 'string')
|
|
31
|
+
out[key] = v;
|
|
32
|
+
}
|
|
33
|
+
return out;
|
|
34
|
+
}
|
|
13
35
|
/** Run `xcrun simctl <args>` and return parsed JSON or text output. */
|
|
14
36
|
function simctl(args, json = false) {
|
|
15
37
|
return new Promise((resolve, reject) => {
|
|
@@ -71,47 +93,70 @@ export async function recordIosSimulator(options) {
|
|
|
71
93
|
if (recProc.exitCode !== null) {
|
|
72
94
|
throw new Error(`recordVideo failed to start on ${device.name}: ${recStderr.trim() || 'unknown error'}`);
|
|
73
95
|
}
|
|
74
|
-
// Run the user's command and capture its exit code.
|
|
96
|
+
// Run the user's command and capture its exit code. Add an `error`
|
|
97
|
+
// handler so a missing shell or bad cwd doesn't crash the parent process
|
|
98
|
+
// before we get a chance to clean up the orphaned recordVideo child.
|
|
75
99
|
const startedAt = Date.now();
|
|
76
100
|
const cmdResult = await new Promise((resolve) => {
|
|
77
101
|
const child = spawn(options.shell ?? '/bin/sh', ['-c', options.command], {
|
|
78
102
|
cwd: options.cwd,
|
|
79
103
|
stdio: 'inherit',
|
|
104
|
+
env: options.inheritEnv
|
|
105
|
+
? process.env
|
|
106
|
+
: pickMinimalEnv(),
|
|
107
|
+
});
|
|
108
|
+
child.on('error', (err) => {
|
|
109
|
+
console.error(`[Sweetlink] Failed to spawn user command: ${err.message}`);
|
|
110
|
+
resolve({ exitCode: 127 });
|
|
80
111
|
});
|
|
81
112
|
child.on('close', (code) => resolve({ exitCode: code ?? 0 }));
|
|
82
113
|
});
|
|
83
114
|
const durationSec = (Date.now() - startedAt) / 1000;
|
|
84
115
|
// Stop recording: SIGINT triggers simctl's flush-and-exit path. SIGTERM
|
|
85
|
-
// would also work but truncates the trailing buffer.
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
116
|
+
// would also work but truncates the trailing buffer. Wrapped in
|
|
117
|
+
// try/finally so orphaned recProc gets killed on any later failure.
|
|
118
|
+
let closed = false;
|
|
119
|
+
try {
|
|
120
|
+
closed = await new Promise((resolve) => {
|
|
121
|
+
let resolved = false;
|
|
122
|
+
const timer = setTimeout(() => {
|
|
123
|
+
if (!resolved) {
|
|
124
|
+
resolved = true;
|
|
125
|
+
// Recording didn't shut down within 5s — kill it forcefully.
|
|
126
|
+
try {
|
|
127
|
+
recProc.kill('SIGKILL');
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
/* ignore */
|
|
131
|
+
}
|
|
132
|
+
resolve(false);
|
|
94
133
|
}
|
|
95
|
-
|
|
96
|
-
|
|
134
|
+
}, 5_000);
|
|
135
|
+
recProc.on('close', () => {
|
|
136
|
+
if (!resolved) {
|
|
137
|
+
resolved = true;
|
|
138
|
+
clearTimeout(timer);
|
|
139
|
+
resolve(true);
|
|
97
140
|
}
|
|
98
|
-
|
|
141
|
+
});
|
|
142
|
+
try {
|
|
143
|
+
recProc.kill('SIGINT');
|
|
99
144
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
if (!resolved) {
|
|
103
|
-
resolved = true;
|
|
104
|
-
clearTimeout(timer);
|
|
105
|
-
resolve(true);
|
|
145
|
+
catch {
|
|
146
|
+
/* ignore */
|
|
106
147
|
}
|
|
107
148
|
});
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
149
|
+
}
|
|
150
|
+
finally {
|
|
151
|
+
if (recProc.exitCode === null) {
|
|
152
|
+
try {
|
|
153
|
+
recProc.kill('SIGKILL');
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
/* ignore */
|
|
157
|
+
}
|
|
113
158
|
}
|
|
114
|
-
}
|
|
159
|
+
}
|
|
115
160
|
return {
|
|
116
161
|
output: options.output,
|
|
117
162
|
device: device.name,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ios.js","sourceRoot":"","sources":["../../src/simulator/ios.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAqB,QAAQ,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"ios.js","sourceRoot":"","sources":["../../src/simulator/ios.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for the asciicast v2 format.
|
|
3
|
+
* Recorder and player both import these so the on-disk schema stays in sync.
|
|
4
|
+
*/
|
|
5
|
+
export type CastEventKind = 'o' | 'i';
|
|
6
|
+
export type CastEvent = [time: number, kind: CastEventKind, data: string];
|
|
7
|
+
export interface CastHeader {
|
|
8
|
+
version: 2;
|
|
9
|
+
width: number;
|
|
10
|
+
height: number;
|
|
11
|
+
timestamp?: number;
|
|
12
|
+
duration?: number;
|
|
13
|
+
title?: string;
|
|
14
|
+
env?: Record<string, string>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Escape a JSON string for safe interpolation inside an HTML <script> block.
|
|
18
|
+
* JSON.stringify alone does NOT escape `</script>`, `<!--`, or U+2028/U+2029,
|
|
19
|
+
* so attacker-controlled bytes inside event data could break out of the
|
|
20
|
+
* script element and execute. The .html player is designed for sharing in
|
|
21
|
+
* PR comments, so this matters.
|
|
22
|
+
*/
|
|
23
|
+
export declare function escapeJsonForScript(json: string): string;
|
|
24
|
+
//# sourceMappingURL=cast.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cast.d.ts","sourceRoot":"","sources":["../../src/term/cast.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,aAAa,GAAG,GAAG,GAAG,GAAG,CAAC;AAEtC,MAAM,MAAM,SAAS,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AAE1E,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,CAAC,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAKD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CASxD"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for the asciicast v2 format.
|
|
3
|
+
* Recorder and player both import these so the on-disk schema stays in sync.
|
|
4
|
+
*/
|
|
5
|
+
const LINE_SEP = String.fromCharCode(0x2028);
|
|
6
|
+
const PARA_SEP = String.fromCharCode(0x2029);
|
|
7
|
+
/**
|
|
8
|
+
* Escape a JSON string for safe interpolation inside an HTML <script> block.
|
|
9
|
+
* JSON.stringify alone does NOT escape `</script>`, `<!--`, or U+2028/U+2029,
|
|
10
|
+
* so attacker-controlled bytes inside event data could break out of the
|
|
11
|
+
* script element and execute. The .html player is designed for sharing in
|
|
12
|
+
* PR comments, so this matters.
|
|
13
|
+
*/
|
|
14
|
+
export function escapeJsonForScript(json) {
|
|
15
|
+
return json
|
|
16
|
+
.replace(/</g, '\\u003c')
|
|
17
|
+
.replace(/>/g, '\\u003e')
|
|
18
|
+
.replace(/&/g, '\\u0026')
|
|
19
|
+
.split(LINE_SEP)
|
|
20
|
+
.join('\\u2028')
|
|
21
|
+
.split(PARA_SEP)
|
|
22
|
+
.join('\\u2029');
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=cast.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cast.js","sourceRoot":"","sources":["../../src/term/cast.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAgBH,MAAM,QAAQ,GAAG,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;AAC7C,MAAM,QAAQ,GAAG,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;AAE7C;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,OAAO,IAAI;SACR,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC;SACxB,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC;SACxB,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC;SACxB,KAAK,CAAC,QAAQ,CAAC;SACf,IAAI,CAAC,SAAS,CAAC;SACf,KAAK,CAAC,QAAQ,CAAC;SACf,IAAI,CAAC,SAAS,CAAC,CAAC;AACrB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"player.d.ts","sourceRoot":"","sources":["../../src/term/player.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;
|
|
1
|
+
{"version":3,"file":"player.d.ts","sourceRoot":"","sources":["../../src/term/player.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAOH,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAsB,cAAc,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAiQ5E"}
|
package/dist/term/player.js
CHANGED
|
@@ -16,37 +16,59 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import { promises as fs } from 'fs';
|
|
18
18
|
import * as path from 'path';
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
.replace(/&/g, '&')
|
|
22
|
-
.replace(/</g, '<')
|
|
23
|
-
.replace(/>/g, '>')
|
|
24
|
-
.replace(/"/g, '"');
|
|
25
|
-
}
|
|
19
|
+
import { escapeHtml as escapeAttr } from '../daemon/utils.js';
|
|
20
|
+
import { escapeJsonForScript } from './cast.js';
|
|
26
21
|
export async function generatePlayer(options) {
|
|
27
22
|
const cast = await fs.readFile(options.castPath, 'utf-8');
|
|
28
23
|
const lines = cast.split(/\r?\n/).filter(Boolean);
|
|
29
24
|
if (lines.length === 0)
|
|
30
25
|
throw new Error(`Empty .cast file: ${options.castPath}`);
|
|
31
|
-
|
|
26
|
+
let header;
|
|
27
|
+
try {
|
|
28
|
+
header = JSON.parse(lines[0]);
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
const preview = lines[0].slice(0, 80);
|
|
32
|
+
throw new Error(`Not a valid asciicast v2 file: ${options.castPath} — first line is not JSON: ${preview}`);
|
|
33
|
+
}
|
|
34
|
+
if (header.version !== 2) {
|
|
35
|
+
throw new Error(`Unsupported asciicast version ${header.version} (expected 2): ${options.castPath}`);
|
|
36
|
+
}
|
|
37
|
+
const width = Number.isFinite(header.width) && header.width > 0 ? header.width : 80;
|
|
38
|
+
const height = Number.isFinite(header.height) && header.height > 0 ? header.height : 24;
|
|
32
39
|
const events = [];
|
|
33
40
|
for (let i = 1; i < lines.length; i++) {
|
|
34
41
|
try {
|
|
35
42
|
const e = JSON.parse(lines[i]);
|
|
36
|
-
if (Array.isArray(e) &&
|
|
43
|
+
if (Array.isArray(e) &&
|
|
44
|
+
e.length === 3 &&
|
|
45
|
+
typeof e[0] === 'number' &&
|
|
46
|
+
(e[1] === 'o' || e[1] === 'i') &&
|
|
47
|
+
typeof e[2] === 'string') {
|
|
37
48
|
events.push(e);
|
|
49
|
+
}
|
|
38
50
|
}
|
|
39
51
|
catch {
|
|
40
52
|
/* skip malformed lines */
|
|
41
53
|
}
|
|
42
54
|
}
|
|
43
|
-
|
|
55
|
+
if (events.length === 0) {
|
|
56
|
+
throw new Error(`No events captured in ${options.castPath} — refusing to generate empty player`);
|
|
57
|
+
}
|
|
58
|
+
const lastEventT = events[events.length - 1][0];
|
|
59
|
+
const rawDuration = header.duration ?? lastEventT;
|
|
60
|
+
// Clamp to a sane range so the seek slider is functional.
|
|
61
|
+
const totalDuration = Number.isFinite(rawDuration) && rawDuration > 0
|
|
62
|
+
? Math.max(rawDuration, 1)
|
|
63
|
+
: Math.max(lastEventT, 1);
|
|
44
64
|
const titleText = options.title ?? header.title ?? path.basename(options.castPath);
|
|
45
65
|
const outputPath = options.outputPath ?? `${options.castPath.replace(/\.cast$/i, '')}.html`;
|
|
46
|
-
// Embed the events as an inline JSON string.
|
|
47
|
-
//
|
|
48
|
-
//
|
|
49
|
-
|
|
66
|
+
// Embed the events as an inline JSON string. JSON.stringify alone does NOT
|
|
67
|
+
// escape `</script>`, `<!--`, or U+2028/U+2029, so attacker-controlled
|
|
68
|
+
// bytes inside event data could break out of the script element and run
|
|
69
|
+
// attacker JS in any teammate who opens the shareable .html. Always pipe
|
|
70
|
+
// through escapeJsonForScript before string-interpolating.
|
|
71
|
+
const dataJson = escapeJsonForScript(JSON.stringify({ width, height, events }));
|
|
50
72
|
const html = `<!DOCTYPE html>
|
|
51
73
|
<html lang="en">
|
|
52
74
|
<head>
|
package/dist/term/player.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"player.js","sourceRoot":"","sources":["../../src/term/player.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"player.js","sourceRoot":"","sources":["../../src/term/player.ts"],"names":[],"mappings":"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"}
|
package/dist/term/recorder.d.ts
CHANGED
|
@@ -21,6 +21,13 @@ export interface TerminalCaptureOptions {
|
|
|
21
21
|
env?: Record<string, string>;
|
|
22
22
|
/** Optional human-readable label embedded in the .cast title field. */
|
|
23
23
|
label?: string;
|
|
24
|
+
/**
|
|
25
|
+
* When true, the spawned child sees the full process.env (which may include
|
|
26
|
+
* secrets like AWS_SECRET_ACCESS_KEY, ANTHROPIC_API_KEY, NPM_TOKEN). When
|
|
27
|
+
* false (default), only a minimal allowlist is forwarded. Recorded stdout
|
|
28
|
+
* is shareable, so leaking env values into a .cast on disk is a real risk.
|
|
29
|
+
*/
|
|
30
|
+
inheritEnv?: boolean;
|
|
24
31
|
}
|
|
25
32
|
export interface TerminalCaptureResult {
|
|
26
33
|
durationSec: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../../src/term/recorder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;
|
|
1
|
+
{"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../../src/term/recorder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAmCH,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,uEAAuE;IACvE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,eAAe,CACnC,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,qBAAqB,CAAC,CAuEhC"}
|
package/dist/term/recorder.js
CHANGED
|
@@ -11,6 +11,34 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import { spawn } from 'child_process';
|
|
13
13
|
import { promises as fs } from 'fs';
|
|
14
|
+
/**
|
|
15
|
+
* Allowlist of environment variables forwarded to recorded child processes.
|
|
16
|
+
* Excludes anything matching common secret patterns (AWS_*, GH_TOKEN,
|
|
17
|
+
* NPM_TOKEN, ANTHROPIC_API_KEY, etc.). Callers can opt into the full env
|
|
18
|
+
* via `inheritEnv: true`.
|
|
19
|
+
*/
|
|
20
|
+
const MINIMAL_ENV_KEYS = [
|
|
21
|
+
'PATH',
|
|
22
|
+
'HOME',
|
|
23
|
+
'USER',
|
|
24
|
+
'LANG',
|
|
25
|
+
'LC_ALL',
|
|
26
|
+
'LC_CTYPE',
|
|
27
|
+
'TERM',
|
|
28
|
+
'SHELL',
|
|
29
|
+
'TZ',
|
|
30
|
+
'TMPDIR',
|
|
31
|
+
'PWD',
|
|
32
|
+
];
|
|
33
|
+
function pickMinimalEnv() {
|
|
34
|
+
const out = {};
|
|
35
|
+
for (const key of MINIMAL_ENV_KEYS) {
|
|
36
|
+
const v = process.env[key];
|
|
37
|
+
if (typeof v === 'string')
|
|
38
|
+
out[key] = v;
|
|
39
|
+
}
|
|
40
|
+
return out;
|
|
41
|
+
}
|
|
14
42
|
export async function captureTerminal(options) {
|
|
15
43
|
const startTime = Date.now();
|
|
16
44
|
const events = [];
|
|
@@ -19,8 +47,14 @@ export async function captureTerminal(options) {
|
|
|
19
47
|
// Coax common CLIs into emitting ANSI colour even though stdout isn't
|
|
20
48
|
// a TTY. We don't drop a real PTY in front of them — the trade-off is
|
|
21
49
|
// simpler installation (no native build) at the cost of TUI fidelity.
|
|
50
|
+
// Default to a minimal env to avoid leaking secrets (AWS keys, GH tokens,
|
|
51
|
+
// ANTHROPIC_API_KEY, etc.) into the recorded .cast — programs that print
|
|
52
|
+
// env on error would otherwise embed them in the shareable artifact.
|
|
53
|
+
const baseEnv = options.inheritEnv
|
|
54
|
+
? process.env
|
|
55
|
+
: pickMinimalEnv();
|
|
22
56
|
const env = {
|
|
23
|
-
...
|
|
57
|
+
...baseEnv,
|
|
24
58
|
...options.env,
|
|
25
59
|
FORCE_COLOR: '3',
|
|
26
60
|
CLICOLOR_FORCE: '1',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recorder.js","sourceRoot":"","sources":["../../src/term/recorder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"recorder.js","sourceRoot":"","sources":["../../src/term/recorder.ts"],"names":[],"mappings":"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"}
|