pi-agent-browser-native 0.9.10 → 0.9.11

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
@@ -2,6 +2,19 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.9.11 - 2026-11-02
6
+
7
+ <!-- npm-release:unreleased:start -->
8
+ <!-- npm-release:unreleased:end -->
9
+
10
+ - perf: parallelize independent hot-path awaits (#348) ([5b72527](https://github.com/fitchmultz/pi-agent-browser-native/commit/5b725271ab889b60ee222f50fcddd463e7391f70))
11
+
12
+ ### What's Changed
13
+
14
+ - perf: parallelize independent hot-path awaits by @fitchmultz in https://github.com/fitchmultz/pi-agent-browser-native/pull/348
15
+
16
+ **Full Changelog**: https://github.com/fitchmultz/pi-agent-browser-native/compare/v0.9.10...v0.9.11
17
+
5
18
  ## 0.9.10 - 2026-11-02
6
19
 
7
20
  <!-- npm-release:unreleased:start -->
@@ -9314,8 +9314,7 @@ function sourceSummary(status, candidateCount, electronWorkspace) {
9314
9314
  }
9315
9315
  }
9316
9316
  async function analyzeSourceLookupResults(data, compiled, cwd, context2) {
9317
- const { distinctSourceCandidates: distinctSourceCandidates2, observeSourceCandidates: observeSourceCandidates2 } = await Promise.resolve().then(() => (init_lookup_source_evidence(), lookup_source_evidence_exports));
9318
- const { scanWorkspaceComponent: scanWorkspaceComponent2 } = await Promise.resolve().then(() => (init_lookup_workspace(), lookup_workspace_exports));
9317
+ const [{ distinctSourceCandidates: distinctSourceCandidates2, observeSourceCandidates: observeSourceCandidates2 }, { scanWorkspaceComponent: scanWorkspaceComponent2 }] = await Promise.all([Promise.resolve().then(() => (init_lookup_source_evidence(), lookup_source_evidence_exports)), Promise.resolve().then(() => (init_lookup_workspace(), lookup_workspace_exports))]);
9319
9318
  const observed = observeSourceCandidates2(data);
9320
9319
  const workspace = await scanWorkspaceComponent2(compiled.query, cwd);
9321
9320
  const candidates = distinctSourceCandidates2([...observed.candidates, ...workspace.candidates]);
@@ -9356,8 +9355,7 @@ function networkSummary(status, failedCount, candidateCount) {
9356
9355
  }
9357
9356
  }
9358
9357
  async function analyzeNetworkSourceLookupResults(data, compiled, cwd) {
9359
- const { distinctNetworkCandidates: distinctNetworkCandidates2, getFailedNetworkRequests: getFailedNetworkRequests2, observeInitiatorCandidates: observeInitiatorCandidates2 } = await Promise.resolve().then(() => (init_lookup_network_evidence(), lookup_network_evidence_exports));
9360
- const { scanWorkspaceRequests: scanWorkspaceRequests2 } = await Promise.resolve().then(() => (init_lookup_workspace(), lookup_workspace_exports));
9358
+ const [{ distinctNetworkCandidates: distinctNetworkCandidates2, getFailedNetworkRequests: getFailedNetworkRequests2, observeInitiatorCandidates: observeInitiatorCandidates2 }, { scanWorkspaceRequests: scanWorkspaceRequests2 }] = await Promise.all([Promise.resolve().then(() => (init_lookup_network_evidence(), lookup_network_evidence_exports)), Promise.resolve().then(() => (init_lookup_workspace(), lookup_workspace_exports))]);
9361
9359
  const queryText = compiled.query.filter ?? compiled.query.url;
9362
9360
  const failedRequests = getFailedNetworkRequests2(data, queryText);
9363
9361
  const observed = observeInitiatorCandidates2(data, failedRequests, queryText);
@@ -10600,8 +10598,11 @@ async function attachVisibleImage(presentation, options) {
10600
10598
  }
10601
10599
  async function attachInlineImage(presentation, imagePath, modelVisible = true) {
10602
10600
  try {
10603
- const fileStats = await stat7(imagePath);
10604
- const header = await readImageHeader(imagePath, 64 * 1024);
10601
+ const [fileStats, header] = await Promise.all([
10602
+ stat7(imagePath),
10603
+ // Pi's dimension API accepts base64. Encode only a bounded header, never the whole code-mode image.
10604
+ readImageHeader(imagePath, 64 * 1024)
10605
+ ]);
10605
10606
  const mimeType = getImageMimeType(header);
10606
10607
  if (mimeType === void 0) {
10607
10608
  return presentation;
@@ -10986,16 +10987,19 @@ async function extractFileArtifacts(options) {
10986
10987
  }
10987
10988
  const recording = options.commandInfo.command === "record" ? getRecordingReceipt(options.data, options.commandInfo.subcommand === "stop" ? options.recordingOutcome : void 0) : void 0;
10988
10989
  const recordingPending = getRecordingPending(options, recording);
10989
- const current = (await Promise.all(extractPathStrings(options.data).map((path) => buildFileArtifactMetadata({ ...options, path, recording, recordingPending })))).filter((artifact) => artifact !== void 0);
10990
- const sheet = await extractContactSheet(options, recordingPending);
10990
+ const [currentArtifacts, sheet, previousSheet, previous] = await Promise.all([
10991
+ Promise.all(extractPathStrings(options.data).map((path) => buildFileArtifactMetadata({ ...options, path, recording, recordingPending }))),
10992
+ extractContactSheet(options, recordingPending),
10993
+ extractPreviousContactSheet(options),
10994
+ buildPreviousRestartRecordingArtifact(options)
10995
+ ]);
10996
+ const current = currentArtifacts.filter((artifact) => artifact !== void 0);
10991
10997
  if (sheet) {
10992
10998
  current.push(sheet);
10993
10999
  }
10994
- const previousSheet = await extractPreviousContactSheet(options);
10995
11000
  if (previousSheet) {
10996
11001
  current.unshift(previousSheet);
10997
11002
  }
10998
- const previous = await buildPreviousRestartRecordingArtifact(options);
10999
11003
  return previous ? [previous, ...current] : current;
11000
11004
  }
11001
11005
  function buildManifestEntriesForFileArtifacts(artifacts, nowMs = Date.now()) {
@@ -15223,15 +15227,19 @@ async function isPortAlive(port, signal) {
15223
15227
  const targets = parseCdpTargets(await fetchCdpJson(`http://127.0.0.1:${port}/json/list`, signal));
15224
15228
  return { targets, version };
15225
15229
  }
15226
- async function inspectElectronLaunchStatus(record, signal) {
15227
- const cdp = await isPortAlive(record.port, signal);
15228
- let userDataDirState;
15230
+ async function inspectUserDataDirState(userDataDir) {
15229
15231
  try {
15230
- await lstat2(record.userDataDir);
15231
- userDataDirState = "present";
15232
+ await lstat2(userDataDir);
15233
+ return "present";
15232
15234
  } catch (error) {
15233
- userDataDirState = isRecord(error) && error.code === "ENOENT" ? "absent" : "unknown";
15235
+ return isRecord(error) && error.code === "ENOENT" ? "absent" : "unknown";
15234
15236
  }
15237
+ }
15238
+ async function inspectElectronLaunchStatus(record, signal) {
15239
+ const [cdp, userDataDirState] = await Promise.all([
15240
+ isPortAlive(record.port, signal),
15241
+ inspectUserDataDirState(record.userDataDir)
15242
+ ]);
15235
15243
  return {
15236
15244
  cleanupState: record.cleanupState,
15237
15245
  launchId: record.launchId,
@@ -21253,8 +21261,10 @@ async function inspectElectronHostLaunches(options, compiledElectron, visibleInp
21253
21261
  });
21254
21262
  }
21255
21263
  const records = selection.records ?? [];
21256
- const statuses = await Promise.all(records.map((record) => inspectElectronLaunchStatus(record)));
21257
- const managedSessions = await collectStatusManagedSessions(options, records, compiledElectron.timeoutMs);
21264
+ const [statuses, managedSessions] = await Promise.all([
21265
+ Promise.all(records.map((record) => inspectElectronLaunchStatus(record))),
21266
+ collectStatusManagedSessions(options, records, compiledElectron.timeoutMs)
21267
+ ]);
21258
21268
  const mismatches = statusMismatches(records, statuses, managedSessions);
21259
21269
  return buildElectronStatusResult({
21260
21270
  compiledElectron: visibleInput,
@@ -21792,9 +21802,11 @@ function resolveProbePolicy(options, identity, timeoutMs) {
21792
21802
  };
21793
21803
  }
21794
21804
  async function inspectProbeIdentity(options, identity, input, visibleInput) {
21795
- const status = identity.record ? await inspectElectronLaunchStatus(identity.record) : void 0;
21796
21805
  const policy = resolveProbePolicy(options, identity, input.timeoutMs);
21797
- const probe = await withOwnedElectronManagedSessionPolicy({ ...policy, args: ["snapshot", "-i"] }, () => collectElectronProbe(policy));
21806
+ const [status, probe] = await Promise.all([
21807
+ identity.record ? inspectElectronLaunchStatus(identity.record) : void 0,
21808
+ withOwnedElectronManagedSessionPolicy({ ...policy, args: ["snapshot", "-i"] }, () => collectElectronProbe(policy))
21809
+ ]);
21798
21810
  const managedSession = {
21799
21811
  sessionName: probe.sessionName,
21800
21812
  title: probe.title ?? probe.activeTab?.title,
@@ -26191,10 +26203,12 @@ var init_outcomes = __esm({
26191
26203
 
26192
26204
  // dist/extensions/agent-browser/lib/results/presentation.js
26193
26205
  async function buildToolPresentation(options) {
26194
- const { buildPresentationSource: buildPresentationSource2, buildSourcePresentation: buildSourcePresentation2, resolvePresentationCommands: resolvePresentationCommands2 } = await Promise.resolve().then(() => (init_source(), source_exports));
26195
- const { buildEarlyPresentation: buildEarlyPresentation2, sanitizeModelFacingPresentation: sanitizeModelFacingPresentation2 } = await Promise.resolve().then(() => (init_early_result(), early_result_exports));
26196
- const { applyPresentationNotices: applyPresentationNotices2 } = await Promise.resolve().then(() => (init_notices(), notices_exports));
26197
- const { applyPresentationOutcome: applyPresentationOutcome2 } = await Promise.resolve().then(() => (init_outcomes(), outcomes_exports));
26206
+ const [{ buildPresentationSource: buildPresentationSource2, buildSourcePresentation: buildSourcePresentation2, resolvePresentationCommands: resolvePresentationCommands2 }, { buildEarlyPresentation: buildEarlyPresentation2, sanitizeModelFacingPresentation: sanitizeModelFacingPresentation2 }, { applyPresentationNotices: applyPresentationNotices2 }, { applyPresentationOutcome: applyPresentationOutcome2 }] = await Promise.all([
26207
+ Promise.resolve().then(() => (init_source(), source_exports)),
26208
+ Promise.resolve().then(() => (init_early_result(), early_result_exports)),
26209
+ Promise.resolve().then(() => (init_notices(), notices_exports)),
26210
+ Promise.resolve().then(() => (init_outcomes(), outcomes_exports))
26211
+ ]);
26198
26212
  const commands = resolvePresentationCommands2(options);
26199
26213
  const early = await buildEarlyPresentation2(options, commands);
26200
26214
  if (early) {
@@ -32730,9 +32744,11 @@ function compactPassedQa(draft) {
32730
32744
  }
32731
32745
  async function analyzeOutputChecks(draft) {
32732
32746
  analyzeQaEvidence(draft);
32733
- await collectQaAttachment(draft);
32734
- await lookupSourceEvidence(draft);
32735
- await lookupNetworkSourceEvidence(draft);
32747
+ await Promise.all([
32748
+ collectQaAttachment(draft),
32749
+ lookupSourceEvidence(draft),
32750
+ lookupNetworkSourceEvidence(draft)
32751
+ ]);
32736
32752
  if (draft.networkSourceLookup) {
32737
32753
  prependLookupSummary(draft, draft.networkSourceLookup.summary);
32738
32754
  }
@@ -33067,8 +33083,10 @@ async function publishOutputEffects(input, native, page, lifecycle) {
33067
33083
  await analyzeOutputChecks(draft);
33068
33084
  renderAttachedQaBanner(draft);
33069
33085
  collectEvalGuidance(draft);
33070
- await collectPublicationWarnings(draft);
33071
- const recovery = await recoverFinalOutput(draft);
33086
+ const [, recovery] = await Promise.all([
33087
+ collectPublicationWarnings(draft),
33088
+ recoverFinalOutput(draft)
33089
+ ]);
33072
33090
  await bindOutputDaemonReceipt(draft);
33073
33091
  publishConfirmedSnapshot(draft);
33074
33092
  return { publication: draft, recovery };
@@ -33331,8 +33349,10 @@ var JsonProjection = class {
33331
33349
  }
33332
33350
  };
33333
33351
  async function projectJson(input, fields, maxBytes = ENVELOPE_MAX_BYTES) {
33334
- const { jsonParser } = await import("stream-json/core/parser.js");
33335
- const chain = await import("stream-chain/defs.js");
33352
+ const [{ jsonParser }, chain] = await Promise.all([
33353
+ import("stream-json/core/parser.js"),
33354
+ import("stream-chain/defs.js")
33355
+ ]);
33336
33356
  const tokenize = jsonParser({ packValues: false, streamValues: true });
33337
33357
  const projection = new JsonProjection(fields, maxBytes);
33338
33358
  const decoder = new TextDecoder("utf-8", { fatal: true });
@@ -34351,8 +34371,7 @@ function replayRelevant(value) {
34351
34371
  return value.type === "custom" && typeof value.customType === "string" && REPLAY_CUSTOM_TYPES.has(value.customType) || isRecord(value.data) && isRecord(value.data.event) || isRecord(value.data) && isRecord(value.data.snapshot) && value.data.snapshot.id !== void 0;
34352
34372
  }
34353
34373
  async function verifyCapturedFile(file, path, captured) {
34354
- const current = await file.stat();
34355
- const currentPath = await stat(path);
34374
+ const [current, currentPath] = await Promise.all([file.stat(), stat(path)]);
34356
34375
  if (current.dev !== captured.dev || current.ino !== captured.ino || current.size < captured.size || currentPath.dev !== captured.dev || currentPath.ino !== captured.ino) {
34357
34376
  throw new Error("Pi journal replaced or truncated during replay.");
34358
34377
  }
@@ -34604,8 +34623,7 @@ async function appendPublishedRecord(manager, path, operation) {
34604
34623
  sessionId: manager.getHeader()?.id ?? manager.getSessionId()
34605
34624
  });
34606
34625
  } finally {
34607
- await file?.close();
34608
- await beforeFile.close();
34626
+ await Promise.all([file?.close(), beforeFile.close()]);
34609
34627
  }
34610
34628
  return operation.branch.isCurrent();
34611
34629
  }
@@ -42115,7 +42133,8 @@ async function pathsReferToSameFile(left, right) {
42115
42133
  return true;
42116
42134
  }
42117
42135
  try {
42118
- if (await realpath3(left) === await realpath3(right)) {
42136
+ const [leftPath, rightPath] = await Promise.all([realpath3(left), realpath3(right)]);
42137
+ if (leftPath === rightPath) {
42119
42138
  return true;
42120
42139
  }
42121
42140
  } catch {
@@ -196,8 +196,10 @@ var JsonProjection = class {
196
196
  }
197
197
  };
198
198
  async function projectJson(input, fields, maxBytes = ENVELOPE_MAX_BYTES) {
199
- const { jsonParser } = await import("stream-json/core/parser.js");
200
- const chain = await import("stream-chain/defs.js");
199
+ const [{ jsonParser }, chain] = await Promise.all([
200
+ import("stream-json/core/parser.js"),
201
+ import("stream-chain/defs.js")
202
+ ]);
201
203
  const tokenize = jsonParser({ packValues: false, streamValues: true });
202
204
  const projection = new JsonProjection(fields, maxBytes);
203
205
  const decoder = new TextDecoder("utf-8", { fatal: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-agent-browser-native",
3
- "version": "0.9.10",
3
+ "version": "0.9.11",
4
4
  "description": "pi extension that exposes agent-browser as a native tool for browser automation",
5
5
  "type": "module",
6
6
  "author": "Mitch Fultz (https://github.com/fitchmultz)",