@kaeawc/auto-mobile 0.0.88 → 0.0.90

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.
@@ -1,70 +1,71 @@
1
- {
2
- "name": "@borewit/text-codec",
3
- "version": "0.2.2",
4
- "description": "Text Decoder",
5
- "type": "module",
6
- "exports": "./lib/index.js",
7
- "types": "lib/index.d.ts",
8
- "files": [
9
- "lib/index.js",
10
- "lib/index.d.ts"
11
- ],
12
- "scripts": {
13
- "clean": "del-cli lib/**/*.js lib/***.js.map test/**/*.d.ts test/**/*.js test/**/*.js.map",
14
- "build": "npm run compile",
15
- "prepublishOnly": "npm run build",
16
- "compile:src": "tsc --p lib --sourceMap false",
17
- "compile:test": "tsc --p test",
18
- "compile": "npm run compile:src && npm run compile:test",
19
- "lint": "biome check",
20
- "test": "mocha",
21
- "update-biome": "npm install --save-dev --save-exact @biomejs/biome@latest && npx @biomejs/biome migrate --write"
22
- },
23
- "devDependencies": {
24
- "@biomejs/biome": "2.4.6",
25
- "@types/chai": "^5.2.2",
26
- "@types/mocha": "^10.0.10",
27
- "chai": "^6.2.2",
28
- "mocha": "^11.7.5",
29
- "ts-node": "^10.9.2",
30
- "typescript": "^5.9.3"
31
- },
32
- "keywords": [
33
- "TextDecoder",
34
- "TextEncoder",
35
- "decoder",
36
- "decoding",
37
- "encod",
38
- "encoding",
39
- "decode",
40
- "text",
41
- "ascii",
42
- "utf-8",
43
- "utf8",
44
- "utf-16le",
45
- "latin1",
46
- "iso-8859-1",
47
- "windows-1252",
48
- "charset",
49
- "encoding",
50
- "decoding",
51
- "polyfill",
52
- "character-set",
53
- "latin",
54
- "hermes",
55
- "react"
56
- ],
57
- "repository": {
58
- "type": "git",
59
- "url": "git+https://github.com/Borewit/text-codec.git"
60
- },
61
- "author": {
62
- "name": "Borewit",
63
- "url": "https://github.com/Borewit"
64
- },
65
- "funding": {
66
- "type": "github",
67
- "url": "https://github.com/sponsors/Borewit"
68
- },
69
- "license": "MIT"
70
- }
1
+ {
2
+ "name": "@borewit/text-codec",
3
+ "version": "0.2.3",
4
+ "description": "Text Decoder",
5
+ "type": "module",
6
+ "exports": "./lib/index.js",
7
+ "types": "lib/index.d.ts",
8
+ "files": [
9
+ "lib/index.js",
10
+ "lib/index.d.ts"
11
+ ],
12
+ "scripts": {
13
+ "clean": "del-cli lib/**/*.js lib/***.js.map test/**/*.d.ts test/**/*.js test/**/*.js.map",
14
+ "build": "npm run compile",
15
+ "prepublishOnly": "npm run build",
16
+ "compile:src": "tsc --p lib --sourceMap false",
17
+ "compile:test": "tsc --p test",
18
+ "compile": "npm run compile:src && npm run compile:test",
19
+ "lint": "biome check --error-on-warnings",
20
+ "pretest": "npm run build",
21
+ "test": "mocha",
22
+ "update-biome": "npm install --save-dev --save-exact @biomejs/biome@latest && npx @biomejs/biome migrate --write",
23
+ "lint:fix": "biome check --write"
24
+ },
25
+ "devDependencies": {
26
+ "@biomejs/biome": "2.6.3",
27
+ "@types/chai": "^5.2.3",
28
+ "@types/mocha": "^10.0.10",
29
+ "chai": "^6.3.0",
30
+ "mocha": "^11.8.0",
31
+ "typescript": "7.0.2"
32
+ },
33
+ "keywords": [
34
+ "TextDecoder",
35
+ "TextEncoder",
36
+ "decoder",
37
+ "decoding",
38
+ "encod",
39
+ "encoding",
40
+ "decode",
41
+ "text",
42
+ "ascii",
43
+ "utf-8",
44
+ "utf8",
45
+ "utf-16le",
46
+ "latin1",
47
+ "iso-8859-1",
48
+ "windows-1252",
49
+ "charset",
50
+ "encoding",
51
+ "decoding",
52
+ "polyfill",
53
+ "character-set",
54
+ "latin",
55
+ "hermes",
56
+ "react"
57
+ ],
58
+ "repository": {
59
+ "type": "git",
60
+ "url": "git+https://github.com/Borewit/text-codec.git"
61
+ },
62
+ "author": {
63
+ "name": "Borewit",
64
+ "url": "https://github.com/Borewit"
65
+ },
66
+ "funding": {
67
+ "type": "github",
68
+ "url": "https://github.com/sponsors/Borewit"
69
+ },
70
+ "license": "MIT"
71
+ }
@@ -389,6 +389,12 @@ peekBuffer(uint8Array: Uint8Array, options?: IReadChunkOptions): Promise<number>
389
389
 
390
390
  Return value `Promise<number>` Promise with number of bytes read. The number of bytes read may be less if the `mayBeLess` flag was set.
391
391
 
392
+ For streams with a known size, a nonempty peek starting at or beyond that size
393
+ rejects with `EndOfStreamError`, or returns zero with `mayBeLess: true`, before
394
+ allocating lookahead or reading input. This also applies through tokenizer views.
395
+ Peeks starting inside the advertised input retain their partial-read behavior
396
+ when they cross EOF. Zero-length peeks remain no-ops.
397
+
392
398
  #### `readToken` function
393
399
 
394
400
  Read a *token* from the tokenizer-stream.
@@ -461,6 +467,10 @@ ignore(length: number): Promise<number>
461
467
 
462
468
  Returns a promise resolving to the number of bytes ignored.
463
469
  Buffer, blob, and file tokenizers stop at the known file size. Stream tokenizers reject with `EndOfStreamError` if the requested bytes are unavailable.
470
+ When a stream has a known size, skips beyond that size reject before allocating
471
+ a skip buffer or consuming input, including skips through tokenizer views.
472
+ If the size is unknown, or the stream ends before its advertised size, a failed
473
+ skip may consume available bytes before rejecting; `position` reflects those bytes.
464
474
 
465
475
  #### `close` function
466
476
  Clean up resources, such as closing a file pointer if applicable.
@@ -471,6 +481,17 @@ close(): Promise<void>
471
481
 
472
482
  Await this method when finished with a tokenizer. For Node.js streams, it does not destroy the underlying stream; the caller remains responsible for its lifecycle.
473
483
 
484
+ For buffer, blob, and file tokenizers, repeated or concurrent `close()` calls
485
+ share one cleanup operation and invoke `onClose` at most once. If cleanup or the
486
+ callback fails, subsequent calls reject with the same error. Calling `abort()`
487
+ before `close()` does not suppress cleanup or the callback.
488
+
489
+ Closing or aborting a Node.js stream tokenizer removes its reader-retaining
490
+ stream listeners. After the source ends, shared error and close guards may remain
491
+ until the source emits either event, including after tokenizer closure; these
492
+ guards do not retain the tokenizer. The caller remains responsible for handling
493
+ subsequent source errors.
494
+
474
495
  For Web streams, `close()` releases the reader lock. A BYOB reader leaves the source uncancelled, allowing another reader to continue reading it. A default reader cancels the source before releasing the lock, discarding remaining data. Bytes already read into tokenizer buffers, including peeked bytes, are not returned to the source.
475
496
 
476
497
  #### `abort` function
@@ -525,7 +546,10 @@ Available on buffer, blob, and file tokenizers (`IRandomAccessTokenizer`).
525
546
  setPosition(position: number): void
526
547
  ```
527
548
 
528
- Sets the current byte offset without reading data.
549
+ Sets the current byte offset without reading data. The position must be a
550
+ non-negative safe integer; invalid positions throw `RangeError` without changing
551
+ the cursor. Seeking past EOF is allowed. At or past EOF, `ignore()` returns zero
552
+ without moving the cursor backward, subject to safe end-position arithmetic.
529
553
 
530
554
  #### `Tokenizer` attributes
531
555
 
@@ -11,7 +11,7 @@ export class AbstractTokenizer {
11
11
  * @protected
12
12
  */
13
13
  constructor(options) {
14
- this.numBuffer = new Uint8Array(8);
14
+ this.numBuffer = new Uint8Array(10); // Includes the 80-bit floating-point tokens.
15
15
  /**
16
16
  * Tokenizer-stream position
17
17
  */
@@ -106,7 +106,7 @@ export class AbstractTokenizer {
106
106
  this.validateLength(length, 'ignore length');
107
107
  this.validateLength(this.position + length, 'end position');
108
108
  if (this.fileInfo.size !== undefined) {
109
- const bytesLeft = this.fileInfo.size - this.position;
109
+ const bytesLeft = Math.max(0, this.fileInfo.size - this.position);
110
110
  if (length > bytesLeft) {
111
111
  this.position += bytesLeft;
112
112
  return bytesLeft;
@@ -115,8 +115,16 @@ export class AbstractTokenizer {
115
115
  this.position += length;
116
116
  return length;
117
117
  }
118
- async close() {
119
- this.removeAbortListener();
118
+ close() {
119
+ if (!this.closePromise) {
120
+ this.removeAbortListener();
121
+ // Cache completion before invoking cleanup hooks or caller callbacks.
122
+ this.closePromise = Promise.resolve().then(() => this.closeOnce());
123
+ }
124
+ return this.closePromise;
125
+ }
126
+ /** Perform cleanup once, sharing completion and the first error across close calls. */
127
+ async closeOnce() {
120
128
  await this.abort();
121
129
  await this.onClose?.();
122
130
  }
@@ -51,6 +51,7 @@ export class BlobTokenizer extends AbstractTokenizer {
51
51
  return true;
52
52
  }
53
53
  setPosition(position) {
54
+ this.validateLength(position, 'position');
54
55
  this.position = position;
55
56
  }
56
57
  }
@@ -45,6 +45,7 @@ export class BufferTokenizer extends AbstractTokenizer {
45
45
  return true;
46
46
  }
47
47
  setPosition(position) {
48
+ this.validateLength(position, 'position');
48
49
  this.position = position;
49
50
  }
50
51
  }
@@ -69,12 +69,12 @@ export class FileTokenizer extends AbstractTokenizer {
69
69
  }
70
70
  return res.bytesRead;
71
71
  }
72
- async close() {
73
- this.removeAbortListener();
72
+ async closeOnce() {
74
73
  await this.fileHandle.close();
75
- return super.close();
74
+ await super.closeOnce();
76
75
  }
77
76
  setPosition(position) {
77
+ this.validateLength(position, 'position');
78
78
  this.position = position;
79
79
  }
80
80
  supportsRandomAccess() {
@@ -58,6 +58,13 @@ export class ReadStreamTokenizer extends AbstractTokenizer {
58
58
  if (normOptions.length === 0) {
59
59
  return 0;
60
60
  }
61
+ // A known-empty range needs neither lookahead allocation nor source I/O.
62
+ if (this.fileInfo.size !== undefined && normOptions.position >= this.fileInfo.size) {
63
+ if (normOptions.mayBeLess) {
64
+ return 0;
65
+ }
66
+ throw new EndOfStreamError();
67
+ }
61
68
  const lookaheadSize = normOptions.length + normOptions.position - this.position;
62
69
  this.validateBufferSize(lookaheadSize);
63
70
  let bytesRead = 0;
@@ -103,6 +110,9 @@ export class ReadStreamTokenizer extends AbstractTokenizer {
103
110
  }
104
111
  this.validateLength(length, 'ignore length');
105
112
  this.validateLength(this.position + length, 'end position');
113
+ if (length > 0 && this.fileInfo.size !== undefined && length > this.fileInfo.size - this.position) {
114
+ throw new EndOfStreamError();
115
+ }
106
116
  const bufSize = Math.min(ignoreChunkSize, this.maxBufferSize, length);
107
117
  const buf = new Uint8Array(bufSize);
108
118
  let totBytesRead = 0;
@@ -4,6 +4,22 @@ import { FileTokenizer } from './FileTokenizer.js';
4
4
  export * from './core.js';
5
5
  export { FileTokenizer } from './FileTokenizer.js';
6
6
  export { NotRegularFileError } from './NotRegularFileError.js';
7
+ async function waitForPendingOpen(stream) {
8
+ if (stream.pending !== true || stream.destroyed || stream.errored !== null) {
9
+ return;
10
+ }
11
+ await new Promise(resolve => {
12
+ const settle = () => {
13
+ stream.removeListener('open', settle);
14
+ stream.removeListener('error', settle);
15
+ stream.removeListener('close', settle);
16
+ resolve();
17
+ };
18
+ stream.once('open', settle);
19
+ stream.once('error', settle);
20
+ stream.once('close', settle);
21
+ });
22
+ }
7
23
  /**
8
24
  * Construct ReadStreamTokenizer from given Stream.
9
25
  * Will set fileSize, if provided given Stream has set the .path property.
@@ -13,11 +29,18 @@ export { NotRegularFileError } from './NotRegularFileError.js';
13
29
  */
14
30
  export async function fromStream(stream, options) {
15
31
  const rst = coreFromStream(stream, options);
16
- if (stream.path) {
17
- const stat = await fsStat(stream.path);
18
- rst.fileInfo.path = stream.path;
19
- rst.fileInfo.size = stat.size;
32
+ try {
33
+ if (stream.path) {
34
+ const stat = await fsStat(stream.path);
35
+ rst.fileInfo.path = stream.path;
36
+ rst.fileInfo.size = stat.size;
37
+ }
38
+ return rst;
39
+ }
40
+ catch (error) {
41
+ await waitForPendingOpen(stream);
42
+ await rst.close();
43
+ throw error;
20
44
  }
21
- return rst;
22
45
  }
23
46
  export const fromFile = FileTokenizer.fromFile;
@@ -1,6 +1,12 @@
1
1
  import { AbstractStreamReader } from './AbstractStreamReader.js';
2
2
  import { Deferred } from './Deferred.js';
3
3
  import { AbortError } from './Errors.js';
4
+ function handlePostEndError() {
5
+ this.removeListener('close', removePostEndErrorHandler);
6
+ }
7
+ function removePostEndErrorHandler() {
8
+ this.removeListener('error', handlePostEndError);
9
+ }
4
10
  /**
5
11
  * Node.js Readable Stream Reader
6
12
  * Ref: https://nodejs.org/api/stream.html#readable-streams
@@ -13,23 +19,32 @@ export class StreamReader extends AbstractStreamReader {
13
19
  * Pending requests waiting for data, tracked until completion or cancellation
14
20
  */
15
21
  this.pendingRequests = new Set();
16
- if (!s.read || !s.once) {
17
- throw new Error('Expected an instance of stream.Readable');
18
- }
19
- this.s.once('end', () => {
22
+ this.onEnd = () => {
20
23
  this.endOfStream = true;
24
+ this.removeLifecycleListeners();
25
+ // Auto-destruction may emit an error after `end`. These shared handlers do
26
+ // not retain this reader when `emitClose` is disabled.
27
+ this.s.once('error', handlePostEndError);
28
+ this.s.once('close', removePostEndErrorHandler);
21
29
  for (const request of this.pendingRequests) {
22
30
  this.removeRequest(request);
23
31
  request.deferred.resolve(0);
24
32
  }
25
- });
26
- this.s.once('error', err => this.reject(err));
27
- this.s.once('close', () => {
33
+ };
34
+ this.onError = (err) => this.reject(err);
35
+ this.onClose = () => {
36
+ this.removeLifecycleListeners();
28
37
  // Normal EOF may leave peeked bytes that the caller still needs to consume.
29
38
  if (!this.endOfStream) {
30
39
  void this.abort();
31
40
  }
32
- });
41
+ };
42
+ if (!s.read || !s.once) {
43
+ throw new Error('Expected an instance of stream.Readable');
44
+ }
45
+ this.s.once('end', this.onEnd);
46
+ this.s.once('error', this.onError);
47
+ this.s.once('close', this.onClose);
33
48
  }
34
49
  /**
35
50
  * Read chunk from stream
@@ -87,7 +102,13 @@ export class StreamReader extends AbstractStreamReader {
87
102
  this.s.removeListener('readable', request.onReadable);
88
103
  this.pendingRequests.delete(request);
89
104
  }
105
+ removeLifecycleListeners() {
106
+ this.s.removeListener('end', this.onEnd);
107
+ this.s.removeListener('error', this.onError);
108
+ this.s.removeListener('close', this.onClose);
109
+ }
90
110
  reject(err) {
111
+ this.removeLifecycleListeners();
91
112
  this.interrupted = true;
92
113
  this.peekQueue = [];
93
114
  for (const request of this.pendingRequests) {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "strtok3",
3
- "version": "10.6.2",
3
+ "version": "10.6.3",
4
4
  "description": "A promise based streaming tokenizer",
5
5
  "author": {
6
6
  "name": "Borewit",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaeawc/auto-mobile",
3
- "version": "0.0.88",
3
+ "version": "0.0.90",
4
4
  "description": "Mobile device interaction automation via MCP",
5
5
  "keywords": [
6
6
  "adb",
@@ -32,7 +32,8 @@
32
32
  "files": [
33
33
  "dist",
34
34
  "!dist/**/*.map",
35
- "schemas"
35
+ "schemas",
36
+ "mcp-skills"
36
37
  ],
37
38
  "main": "dist/src/index.js",
38
39
  "publishConfig": {
@@ -53,6 +54,7 @@
53
54
  "test:memory-leaks": "bun --expose-gc scripts/detect-memory-leaks.ts",
54
55
  "test:integration:webrtc-mediamtx": "bash scripts/webrtc/run-mediamtx-publisher-integration.sh",
55
56
  "test:integration:webrtc-device": "bash scripts/webrtc/run-mediamtx-device-integration.sh",
57
+ "test:prototype-web-screenshots": "bash scripts/prototype/web-screenshots.sh",
56
58
  "gate:android-video-baseline": "bun scripts/webrtc/android-video-baseline-gate.ts",
57
59
  "lint": "bash scripts/lint.sh",
58
60
  "check:boundaries": "bash scripts/check-boundaries.sh",
@@ -77,6 +79,7 @@
77
79
  "benchmark-context": "bun scripts/benchmark-context-thresholds.ts",
78
80
  "benchmark-tools": "bun scripts/benchmark-mcp-tools.ts",
79
81
  "bench:settled-screenshot": "bun scripts/benchmark-settled-screenshot.ts",
82
+ "bench:agent": "bun run build 1>&2 && bun scripts/agent-benchmark/run.ts",
80
83
  "benchmark-startup": "bash scripts/benchmark-startup.sh",
81
84
  "benchmark-npm-unpacked-size": "bun scripts/benchmark-npm-unpacked-size.ts",
82
85
  "profile:memory": "bun --expose-gc --inspect scripts/detect-memory-leaks.ts --mode=profile",
@@ -124,7 +127,7 @@
124
127
  "loop": "bash scripts/validate-loop.sh"
125
128
  },
126
129
  "dependencies": {
127
- "@borewit/text-codec": "0.2.2",
130
+ "@borewit/text-codec": "0.2.3",
128
131
  "@emnapi/runtime": "1.11.3",
129
132
  "@img/colour": "1.1.0",
130
133
  "@jimp/core": "1.6.1",
@@ -155,6 +158,7 @@
155
158
  "@jimp/plugin-threshold": "1.6.1",
156
159
  "@jimp/types": "1.6.1",
157
160
  "@jimp/utils": "1.6.1",
161
+ "@material-design-icons/svg": "0.14.15",
158
162
  "@tokenizer/inflate": "0.4.1",
159
163
  "@tokenizer/token": "0.3.0",
160
164
  "any-base": "1.1.0",
@@ -180,10 +184,10 @@
180
184
  "semver": "7.8.5",
181
185
  "sharp": "0.35.5",
182
186
  "simple-xml-to-json": "1.2.3",
183
- "strtok3": "10.6.2",
187
+ "strtok3": "10.6.3",
184
188
  "tinycolor2": "1.6.0",
185
189
  "token-types": "6.1.2",
186
- "tslib": "2.8.1",
190
+ "tslib": "2.9.1",
187
191
  "uint8array-extras": "1.6.0",
188
192
  "utif2": "4.1.0",
189
193
  "xml-parse-from-string": "1.0.1",
@@ -191,12 +195,12 @@
191
195
  "zod": "3.25.76"
192
196
  },
193
197
  "devDependencies": {
194
- "@anthropic-ai/sdk": "^0.135.0",
198
+ "@anthropic-ai/sdk": "^1.1.0",
195
199
  "@faker-js/faker": "^10.2.0",
196
- "@modelcontextprotocol/client": "^2.3.1",
200
+ "@modelcontextprotocol/client": "^2.4.0",
197
201
  "@modelcontextprotocol/node": "^2.1.1",
198
- "@modelcontextprotocol/server": "^2.3.1",
199
- "@types/bun": "1.4.3",
202
+ "@modelcontextprotocol/server": "^2.4.0",
203
+ "@types/bun": "1.4.4",
200
204
  "@types/node": "^26.0.0",
201
205
  "@types/pngjs": "^6.0.5",
202
206
  "@types/ws": "^8.18.1",
@@ -211,16 +215,18 @@
211
215
  "js-yaml": "^5.1.0",
212
216
  "knip": "^6.0.0",
213
217
  "kysely": "0.29.7",
214
- "oxc-parser": "0.155.0",
215
- "oxfmt": "0.74.0",
216
- "oxlint": "1.89.0",
217
- "oxlint-tsgolint": "7.0.2004",
218
+ "oxc-parser": "0.156.0",
219
+ "oxfmt": "0.75.0",
220
+ "oxlint": "1.90.0",
221
+ "oxlint-tsgolint": "7.0.2005",
218
222
  "pixelmatch": "^8.0.0",
223
+ "playwright-core": "1.64.1",
219
224
  "pngjs": "^7.0.0",
225
+ "qrcode-generator": "2.0.4",
220
226
  "reflect-metadata": "^0.2.2",
221
227
  "turbo": "^2.8.10",
222
228
  "typescript": "6.0.3",
223
- "werift": "^0.25.0",
229
+ "werift": "^0.26.0",
224
230
  "ws": "^8.19.0",
225
231
  "xml2js": "^0.6.2",
226
232
  "zod-to-json-schema": "^3.25.1"
@@ -1924,6 +1924,8 @@
1924
1924
  "thermal": { "type": "string", "enum": ["throttling", "critical", "unset"] },
1925
1925
  "storage": { "type": "string", "enum": ["low", "full", "unset"] },
1926
1926
  "dontKeepActivities": { "type": "string", "enum": ["on", "unset"] },
1927
+ "memoryPressure": { "type": "string", "enum": ["on", "unset"] },
1928
+ "readOnlyFilesystem": { "type": "string", "enum": ["on", "unset"] },
1927
1929
  "revokePermission": {
1928
1930
  "oneOf": [
1929
1931
  { "type": "string", "const": "unset" },
@@ -2038,6 +2040,24 @@
2038
2040
  "additionalProperties": false
2039
2041
  }
2040
2042
  ]
2043
+ },
2044
+ "clockSkew": {
2045
+ "oneOf": [
2046
+ { "type": "string", "const": "unset" },
2047
+ {
2048
+ "type": "object",
2049
+ "properties": {
2050
+ "offsetSeconds": {
2051
+ "type": "integer",
2052
+ "minimum": -315360000,
2053
+ "maximum": 315360000,
2054
+ "anyOf": [{ "minimum": 3 }, { "maximum": -3 }]
2055
+ }
2056
+ },
2057
+ "required": ["offsetSeconds"],
2058
+ "additionalProperties": false
2059
+ }
2060
+ ]
2041
2061
  }
2042
2062
  },
2043
2063
  "additionalProperties": false