adb-ready 0.3.3 → 0.3.5

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/CHANGELOG.md CHANGED
@@ -9,12 +9,56 @@ breaking changes.
9
9
 
10
10
  ## [Unreleased]
11
11
 
12
+ ## [0.3.5] - 2026-09-12
13
+
14
+ ### Changed
15
+
16
+ - Enforce at least 95% coverage of measurable executable lines added or
17
+ replaced by a pull request, in addition to the existing repository-wide
18
+ line and function coverage floors.
19
+ - Keep external source maps available in local builds while excluding their
20
+ unreferenced payload from the published npm package.
21
+ - Make the read-only real-ADB check report logical targets and raw transports
22
+ separately and fail when ADB returns an unrecognized device state.
23
+
24
+ ### Fixed
25
+
26
+ - Preserve complete mDNS transport serials containing Bonjour collision
27
+ suffixes such as ` (2)`, preventing one physical device from appearing as a
28
+ second unknown target.
29
+ - Classify connected `_adb-tls-connect._tcp` service transports as TLS even
30
+ when their mDNS serial contains a Bonjour collision suffix.
31
+
32
+ ## [0.3.4] - 2026-09-12
33
+
34
+ ### Added
35
+
36
+ - Publish the verified LCOV report to Codecov through short-lived GitHub OIDC
37
+ credentials and show the measured `main` coverage in a live README badge.
38
+
39
+ ### Changed
40
+
41
+ - Raise the authoritative LCOV line and function coverage floors from 90% to
42
+ 95% with additional lifecycle, recovery, agent, configuration, persistence,
43
+ platform, terminal, and protocol boundary tests.
44
+
45
+ ### Fixed
46
+
47
+ - Keep a development session running when optional local session history cannot
48
+ be initialized or finalized, while reporting the persistence gap as a warning.
49
+ - Return a structured target-lease availability error when its per-user state
50
+ directory cannot be created instead of leaking an internal filesystem error.
51
+
12
52
  ## [0.3.3] - 2026-09-11
13
53
 
14
54
  ### Changed
15
55
 
16
56
  - Fail closed before npm publishing unless the immutable release tag already
17
57
  has a matching draft GitHub release.
58
+ - Isolate the push-level permission needed to inspect that draft release in a
59
+ preflight job that never checks out or executes repository code.
60
+ - Allow the audited workflow on protected `main` to promote an exact immutable
61
+ release tag, so release-infrastructure fixes never require moving that tag.
18
62
  - Document Deno's 24-hour minimum dependency age and the explicit override
19
63
  reserved for immediate post-publish verification.
20
64
  - Enforce 90% LCOV line and function coverage floors in the authoritative
@@ -218,7 +262,9 @@ breaking changes.
218
262
  explainable configuration precedence.
219
263
  - Human, plain, JSON, and NDJSON output across Node, Bun, and Deno entrypoints.
220
264
 
221
- [Unreleased]: https://github.com/Adam014/adb-ready/compare/v0.3.3...HEAD
265
+ [Unreleased]: https://github.com/Adam014/adb-ready/compare/v0.3.5...HEAD
266
+ [0.3.5]: https://github.com/Adam014/adb-ready/compare/v0.3.4...v0.3.5
267
+ [0.3.4]: https://github.com/Adam014/adb-ready/compare/v0.3.3...v0.3.4
222
268
  [0.3.3]: https://github.com/Adam014/adb-ready/compare/v0.3.2...v0.3.3
223
269
  [0.3.2]: https://github.com/Adam014/adb-ready/compare/v0.3.1...v0.3.2
224
270
  [0.3.1]: https://github.com/Adam014/adb-ready/compare/v0.3.0...v0.3.1
package/README.md CHANGED
@@ -9,7 +9,7 @@ verified evidence—for developers, agents, and CI.
9
9
 
10
10
  [![MCP](https://img.shields.io/badge/MCP-native-7c3aed)](./docs/agent-integration.md)
11
11
  [![CI](https://github.com/Adam014/adb-ready/actions/workflows/ci.yml/badge.svg)](https://github.com/Adam014/adb-ready/actions/workflows/ci.yml)
12
- [![Coverage](https://img.shields.io/badge/LCOV-%E2%89%A590%25-16a34a)](https://github.com/Adam014/adb-ready/actions/workflows/ci.yml)
12
+ [![Coverage](https://codecov.io/gh/Adam014/adb-ready/graph/badge.svg?branch=main)](https://app.codecov.io/gh/Adam014/adb-ready)
13
13
  [![npm](https://img.shields.io/npm/v/adb-ready?label=npm&color=1f9db5)](https://www.npmjs.com/package/adb-ready)
14
14
  [![Node.js](https://img.shields.io/badge/Node.js-%E2%89%A522-339933?logo=nodedotjs&logoColor=white)](https://nodejs.org/)
15
15
  [![Bun](https://img.shields.io/badge/Bun-tested-14151a?logo=bun&logoColor=white)](https://bun.sh/)
package/dist/cli.js CHANGED
@@ -355,7 +355,7 @@ import process13 from "node:process";
355
355
  // package.json
356
356
  var package_default = {
357
357
  name: "adb-ready",
358
- version: "0.3.3",
358
+ version: "0.3.5",
359
359
  description: "Agent-ready Android CLI for reliable ADB sessions, app automation, and verified evidence.",
360
360
  private: false,
361
361
  type: "module",
@@ -366,7 +366,7 @@ var package_default = {
366
366
  files: [
367
367
  "CHANGELOG.md",
368
368
  "COMPATIBILITY.md",
369
- "dist",
369
+ "dist/cli.js",
370
370
  "docs",
371
371
  "examples",
372
372
  "LICENSE",
@@ -389,6 +389,7 @@ var package_default = {
389
389
  "ui:check": "bun run scripts/ui-playground.ts --all --non-interactive",
390
390
  test: "bun test",
391
391
  "test:coverage": "bun test --coverage && bun run scripts/coverage-check.mjs",
392
+ "test:coverage:diff": "bun run scripts/coverage-diff-check.mjs",
392
393
  "test:commands": "bun run build && bun run scripts/command-matrix.mjs",
393
394
  "test:package-managers": "bun run build && bun run scripts/package-manager-smoke.mjs",
394
395
  "test:integration": "bun test tests/integration",
@@ -34740,6 +34741,26 @@ function normalizeState(tokens) {
34740
34741
  }
34741
34742
  return { state: "unknown", consumed: candidate === undefined ? 0 : 1 };
34742
34743
  }
34744
+ function splitDeviceLine(line) {
34745
+ const knownState = line.match(/^(.+?)\s+(no\s+permissions|bootloader|device|offline|recovery|sideload|unauthorized)(?:\s+(.*))?$/u);
34746
+ if (knownState !== null) {
34747
+ const serial2 = knownState[1]?.trim();
34748
+ const state = knownState[2];
34749
+ if (serial2 === undefined || serial2 === "" || state === undefined)
34750
+ return;
34751
+ const details = knownState[3]?.trim();
34752
+ return {
34753
+ serial: serial2,
34754
+ tokens: [
34755
+ ...state.split(/\s+/u),
34756
+ ...details === undefined || details === "" ? [] : details.split(/\s+/u)
34757
+ ]
34758
+ };
34759
+ }
34760
+ const tokens = line.split(/\s+/u);
34761
+ const serial = tokens.shift();
34762
+ return serial === undefined || serial === "" ? undefined : { serial, tokens };
34763
+ }
34743
34764
  function parseAdbDevices(output) {
34744
34765
  const devices = [];
34745
34766
  let sawHeader = false;
@@ -34758,11 +34779,10 @@ function parseAdbDevices(output) {
34758
34779
  if (!sawHeader || line.startsWith("* daemon") || line.startsWith("adb server")) {
34759
34780
  continue;
34760
34781
  }
34761
- const tokens = line.split(/\s+/u);
34762
- const serial = tokens.shift();
34763
- if (serial === undefined || serial === "") {
34782
+ const fields = splitDeviceLine(line);
34783
+ if (fields === undefined)
34764
34784
  continue;
34765
- }
34785
+ const { serial, tokens } = fields;
34766
34786
  const { state, consumed } = normalizeState(tokens);
34767
34787
  const details = tokens.slice(consumed);
34768
34788
  const properties = {};
@@ -37833,6 +37853,10 @@ function transportKind(device, services) {
37833
37853
  return services.some((service) => service.serviceType === "connect" && service.endpoint.serial === endpoint.serial) ? "tls" : "tcp";
37834
37854
  }
37835
37855
  if (isMdnsServiceSerial(device.serial)) {
37856
+ if (/\._adb-tls-connect\._tcp(?:\.|$)/iu.test(device.serial))
37857
+ return "tls";
37858
+ if (/\._adb\._tcp(?:\.|$)/iu.test(device.serial))
37859
+ return "tcp";
37836
37860
  return "unknown";
37837
37861
  }
37838
37862
  if (device.usb !== undefined || device.serial !== "") {
@@ -39234,7 +39258,10 @@ async function runDev(options, config4 = {}, dependencies = {}, signal) {
39234
39258
  projectRoot: options.sessionStore.projectRoot ?? options.cwd
39235
39259
  });
39236
39260
  } catch {
39237
- problems.push(commandProblem(ProblemCode.SessionPersistenceFailed, "session.persistence", "Session history could not be started.", "The development session can continue, but this run will not be available afterward.", context.commandId));
39261
+ problems.push({
39262
+ ...commandProblem(ProblemCode.SessionPersistenceFailed, "session.persistence", "Session history could not be started.", "The development session can continue, but this run will not be available afterward.", context.commandId),
39263
+ severity: "warning"
39264
+ });
39238
39265
  }
39239
39266
  }
39240
39267
  const complete = async (data) => {
@@ -39266,7 +39293,10 @@ async function runDev(options, config4 = {}, dependencies = {}, signal) {
39266
39293
  ...data?.preset === undefined ? {} : { preset: data.preset }
39267
39294
  });
39268
39295
  if (!persisted.ok) {
39269
- execution2.result.problems.push(commandProblem(ProblemCode.SessionPersistenceFailed, "session.persistence", persisted.message, "The development session completed, but its local history is incomplete.", context.commandId));
39296
+ execution2.result.problems.push({
39297
+ ...commandProblem(ProblemCode.SessionPersistenceFailed, "session.persistence", persisted.message, "The development session completed, but its local history is incomplete.", context.commandId),
39298
+ severity: "warning"
39299
+ });
39270
39300
  }
39271
39301
  }
39272
39302
  return execution2;
@@ -43274,7 +43304,15 @@ async function acquireTargetLease(request, options = {}) {
43274
43304
  throw new RangeError("target lease heartbeatIntervalMs must be non-negative and less than ttlMs");
43275
43305
  }
43276
43306
  const root = leaseDirectory(options);
43277
- await mkdir4(root, { recursive: true, mode: 448 });
43307
+ try {
43308
+ await mkdir4(root, { recursive: true, mode: 448 });
43309
+ } catch {
43310
+ return {
43311
+ ok: false,
43312
+ code: "TARGET_LEASE_UNAVAILABLE",
43313
+ message: "ADB Ready could not create the target ownership lease."
43314
+ };
43315
+ }
43278
43316
  const canonicalRoot = await realpath4(path11.resolve(request.projectRoot)).catch(() => path11.resolve(request.projectRoot));
43279
43317
  const targetFingerprint = fingerprint3(request.targetIdentity);
43280
43318
  const projectFingerprint = fingerprint3(`root:${process11.platform === "win32" ? canonicalRoot.toLowerCase() : canonicalRoot}`);
@@ -49034,4 +49072,4 @@ try {
49034
49072
  process14.removeListener("SIGTERM", abort);
49035
49073
  }
49036
49074
 
49037
- //# debugId=EF4B0DF694B2B23564756E2164756E21
49075
+ //# debugId=855CD3B5A014B04364756E2164756E21
package/docs/RELEASING.md CHANGED
@@ -24,7 +24,8 @@ The workflow does not use a long-lived npm write token.
24
24
  Release evidence has three tiers:
25
25
 
26
26
  - **Every release:** the complete fixture, unit, integration, runtime, package,
27
- documentation, privacy, and release-artifact verification gate must pass.
27
+ documentation, privacy, coverage, and release-artifact verification gate must
28
+ pass. Pull requests must also satisfy the 95% changed-line coverage gate.
28
29
  - **Device-behavior changes:** rerun every affected workflow on a real target
29
30
  and record the exact host, target, Android version, and transport. A
30
31
  documentation, metadata, or machine-output-only patch does not manufacture
@@ -79,12 +80,14 @@ Do not create or move the final tag until this rehearsal is green.
79
80
 
80
81
  1. Create a draft GitHub release for the exact `vVERSION` tag on the audited
81
82
  release commit.
82
- 2. Dispatch the workflow itself from that immutable tag. Publish mode rejects a
83
- branch-based workflow run even if its checkout input points to a tag:
83
+ 2. Dispatch the audited workflow from protected `main` while selecting the
84
+ immutable tag as the release target. Publish mode rejects every other branch,
85
+ requires the checkout to resolve to that exact tag commit, and also permits a
86
+ self-contained dispatch from the matching tag:
84
87
 
85
88
  ```bash
86
89
  gh workflow run release.yml \
87
- --ref vVERSION \
90
+ --ref main \
88
91
  -f mode=publish \
89
92
  -f release_tag=vVERSION \
90
93
  -f ref=vVERSION
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adb-ready",
3
- "version": "0.3.3",
3
+ "version": "0.3.5",
4
4
  "description": "Agent-ready Android CLI for reliable ADB sessions, app automation, and verified evidence.",
5
5
  "private": false,
6
6
  "type": "module",
@@ -11,7 +11,7 @@
11
11
  "files": [
12
12
  "CHANGELOG.md",
13
13
  "COMPATIBILITY.md",
14
- "dist",
14
+ "dist/cli.js",
15
15
  "docs",
16
16
  "examples",
17
17
  "LICENSE",
@@ -34,6 +34,7 @@
34
34
  "ui:check": "bun run scripts/ui-playground.ts --all --non-interactive",
35
35
  "test": "bun test",
36
36
  "test:coverage": "bun test --coverage && bun run scripts/coverage-check.mjs",
37
+ "test:coverage:diff": "bun run scripts/coverage-diff-check.mjs",
37
38
  "test:commands": "bun run build && bun run scripts/command-matrix.mjs",
38
39
  "test:package-managers": "bun run build && bun run scripts/package-manager-smoke.mjs",
39
40
  "test:integration": "bun test tests/integration",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "title": "ADB Ready agent tool contract",
3
3
  "schemaVersion": 1,
4
- "packageVersion": "0.3.3",
4
+ "packageVersion": "0.3.5",
5
5
  "protocolVersion": "2025-11-25",
6
6
  "transport": "stdio",
7
7
  "tools": [