humanish 0.15.3 → 0.16.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/dist/run.d.ts CHANGED
@@ -217,6 +217,37 @@ export interface RunSimulation {
217
217
  startedAt: string;
218
218
  updatedAt: string;
219
219
  }
220
+ export interface RunDesktopGeometry {
221
+ /** E2B/X display geometry. Requested config and verified runtime evidence stay distinct. */
222
+ screen: {
223
+ requested: {
224
+ width: number;
225
+ height: number;
226
+ };
227
+ verified?: {
228
+ width: number;
229
+ height: number;
230
+ source: "xdpyinfo";
231
+ };
232
+ };
233
+ /** Browser outer-window bounds measured after the fill attempt. */
234
+ browserWindow?: {
235
+ x: number;
236
+ y: number;
237
+ width: number;
238
+ height: number;
239
+ source: "cdp" | "xdotool";
240
+ };
241
+ /** Browser CSS layout viewport measured from the running page, never copied from config. */
242
+ viewport?: {
243
+ width: number;
244
+ height: number;
245
+ deviceScaleFactor: number;
246
+ source: "cdp";
247
+ };
248
+ /** Public-safe geometry measurement/fill warnings retained with the stream evidence. */
249
+ warnings?: string[];
250
+ }
220
251
  export interface RunStream {
221
252
  id: string;
222
253
  simId: string;
@@ -239,12 +270,19 @@ export interface RunStream {
239
270
  url?: string;
240
271
  title?: string;
241
272
  };
273
+ /**
274
+ * Browser CSS layout viewport. Deterministic browser adapters may declare and render this
275
+ * exactly; hosted-desktop CUA producers set it only from a runtime measurement. Historical
276
+ * hosted CUA bundles may contain the requested screen size here instead.
277
+ */
242
278
  viewport?: {
243
279
  width: number;
244
280
  height: number;
245
281
  deviceScaleFactor?: number;
246
282
  isMobile?: boolean;
247
283
  };
284
+ /** Truthful screen/window/viewport evidence for hosted desktop browser lanes. */
285
+ desktopGeometry?: RunDesktopGeometry;
248
286
  terminal?: {
249
287
  title: string;
250
288
  format: "ansi" | "plain";
package/dist/run.js CHANGED
@@ -2462,7 +2462,7 @@ async function verifyPreparedRun(cwd, runInput, runPaths) {
2462
2462
  });
2463
2463
  const ok = checks.every((check) => check.ok);
2464
2464
  const warnings = isRunBundle(bundle)
2465
- ? [...rawScreenshotPostureWarnings(bundle), ...undeclaredSubjectStateWarnings(bundle)]
2465
+ ? [...rawScreenshotPostureWarnings(bundle), ...undeclaredSubjectStateWarnings(bundle), ...desktopGeometryWarnings(bundle)]
2466
2466
  : [];
2467
2467
  const shareSafety = isRunBundle(bundle)
2468
2468
  ? buildShareSafety({ ok, bundle, publicSafetyFindings })
@@ -3644,6 +3644,10 @@ function rawScreenshotStreamIds(bundle) {
3644
3644
  }
3645
3645
  return rawStreamIds;
3646
3646
  }
3647
+ /** Non-fatal hosted-desktop geometry disclosures, deduplicated across shared-screen streams. */
3648
+ function desktopGeometryWarnings(bundle) {
3649
+ return [...new Set(bundle.streams.flatMap((stream) => stream.desktopGeometry?.warnings ?? []))];
3650
+ }
3647
3651
  function buildShareSafety(args) {
3648
3652
  const reasons = [];
3649
3653
  if (!args.ok) {
@@ -4629,9 +4633,75 @@ function isRunStream(value) {
4629
4633
  && isRunSimulationStatus(value.status)
4630
4634
  && (value.transport === "snapshot" || value.transport === "polling" || value.transport === "sse" || value.transport === "pty" || value.transport === "app-server")
4631
4635
  && typeof value.updatedAt === "string"
4636
+ && (value.viewport === undefined || isRunViewport(value.viewport))
4637
+ && (value.desktopGeometry === undefined || isRunDesktopGeometry(value.desktopGeometry))
4638
+ && hasConsistentStreamGeometry(value)
4632
4639
  && Array.isArray(value.artifacts)
4633
4640
  && value.artifacts.every(isRunStreamArtifact);
4634
4641
  }
4642
+ function isRunViewport(value) {
4643
+ return isRecord(value)
4644
+ && isPositiveFiniteNumber(value.width)
4645
+ && isPositiveFiniteNumber(value.height)
4646
+ && (value.deviceScaleFactor === undefined || isPositiveFiniteNumber(value.deviceScaleFactor))
4647
+ && (value.isMobile === undefined || typeof value.isMobile === "boolean");
4648
+ }
4649
+ function isRunDesktopGeometry(value) {
4650
+ if (!isRecord(value) || !isRecord(value.screen) || !isMeasuredSize(value.screen.requested)) {
4651
+ return false;
4652
+ }
4653
+ const verified = value.screen.verified;
4654
+ if (verified !== undefined) {
4655
+ if (!isRecord(verified))
4656
+ return false;
4657
+ const source = verified.source;
4658
+ if (!isMeasuredSize(verified) || source !== "xdpyinfo")
4659
+ return false;
4660
+ }
4661
+ const browserWindow = value.browserWindow;
4662
+ if (browserWindow !== undefined && (!isRecord(browserWindow)
4663
+ || !isFiniteNumber(browserWindow.x)
4664
+ || !isFiniteNumber(browserWindow.y)
4665
+ || !isPositiveFiniteNumber(browserWindow.width)
4666
+ || !isPositiveFiniteNumber(browserWindow.height)
4667
+ || (browserWindow.source !== "cdp" && browserWindow.source !== "xdotool"))) {
4668
+ return false;
4669
+ }
4670
+ const viewport = value.viewport;
4671
+ if (!(viewport === undefined || (isRecord(viewport)
4672
+ && isPositiveFiniteNumber(viewport.width)
4673
+ && isPositiveFiniteNumber(viewport.height)
4674
+ && isPositiveFiniteNumber(viewport.deviceScaleFactor)
4675
+ && viewport.source === "cdp")))
4676
+ return false;
4677
+ return value.warnings === undefined || (Array.isArray(value.warnings)
4678
+ && value.warnings.every((warning) => typeof warning === "string" && warning.length > 0));
4679
+ }
4680
+ function hasConsistentStreamGeometry(value) {
4681
+ if (value.desktopGeometry === undefined)
4682
+ return true;
4683
+ if (!isRunDesktopGeometry(value.desktopGeometry))
4684
+ return false;
4685
+ const measured = value.desktopGeometry.viewport;
4686
+ if (measured === undefined)
4687
+ return value.viewport === undefined;
4688
+ if (!isRunViewport(value.viewport))
4689
+ return false;
4690
+ return value.viewport.width === measured.width
4691
+ && value.viewport.height === measured.height
4692
+ && value.viewport.deviceScaleFactor === measured.deviceScaleFactor;
4693
+ }
4694
+ function isMeasuredSize(value) {
4695
+ return isRecord(value)
4696
+ && isPositiveFiniteNumber(value.width)
4697
+ && isPositiveFiniteNumber(value.height);
4698
+ }
4699
+ function isPositiveFiniteNumber(value) {
4700
+ return isFiniteNumber(value) && value > 0;
4701
+ }
4702
+ function isFiniteNumber(value) {
4703
+ return typeof value === "number" && Number.isFinite(value);
4704
+ }
4635
4705
  function isRunStreamArtifact(value) {
4636
4706
  return isRecord(value)
4637
4707
  && typeof value.label === "string"