dsh-inner-browser-use 0.35.0 → 0.35.1

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.
Files changed (3) hide show
  1. package/package.json +1 -1
  2. package/sidecar.js +10 -11
  3. package/tools.js +30 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-inner-browser-use",
3
- "version": "0.35.0",
3
+ "version": "0.35.1",
4
4
  "description": "An agent-owned Chromium sidecar mirrored into the DeepSeek Harness right column: the agent drives it, the person watches and can take the mouse, and logins survive restarts.",
5
5
  "type": "module",
6
6
  "main": "index.js",
package/sidecar.js CHANGED
@@ -826,18 +826,17 @@ export class SidecarPage {
826
826
  probe is only for the case where the click never made one, so it gets a
827
827
  single short look instead of the old half-second of polling. */
828
828
  if (target === null) {
829
- /* Look, wait for the announcement, look again: a new tab is announced
830
- before the browser lists it, so one look is not enough. */
831
- const deadline = Date.now() + POPUP_GRACE_MS
832
- while (target === null && Date.now() < deadline) {
833
- const found = await this.findPopup(foreign)
834
- if (found !== null) {
835
- target = found
836
- break
829
+ /* One look at the tab list answers the common case — a click that opened
830
+ nothing. When it says nothing, the announcement is the cheaper door:
831
+ a tab exists a moment before the browser lists it, so the wait ends on
832
+ the event instead of running out the window. */
833
+ target = await this.findPopup(foreign)
834
+ if (target === null) {
835
+ await this.waitPopup(Math.min(8, POPUP_GRACE_MS))
836
+ if (this.opened !== null && this.opened !== undefined && Date.now() - Number(this.opened.at ?? 0) < 2000) {
837
+ target = { targetId: String(this.opened.targetId), url: String(this.opened.url) }
837
838
  }
838
- const left = deadline - Date.now()
839
- if (left <= 0) break
840
- await this.waitPopup(Math.min(8, left))
839
+ this.opened = null
841
840
  }
842
841
  }
843
842
  if (target === null) {
package/tools.js CHANGED
@@ -310,7 +310,17 @@ export async function outcome(page, before) {
310
310
  const [wasTitle, wasUrl, wasText, wasNodes] = before.split('|')
311
311
  const [nowTitle, nowUrl, nowText, nowNodes] = after.split('|')
312
312
  if (after === before) return ' · no visible change'
313
- if (nowUrl !== wasUrl) return ` · navigated to ${String(nowUrl).slice(0, 300)}`
313
+ if (nowUrl !== wasUrl) {
314
+ /* The brief on the same line already names the address this step went to.
315
+ What it cannot say is whether the page moved within itself, so a jump to
316
+ another spot on the same address is said as the spot alone. */
317
+ const was = String(wasUrl ?? '')
318
+ const now = String(nowUrl ?? '')
319
+ const base = (value) => (value.includes('#') ? value.slice(0, value.indexOf('#')) : value)
320
+ const spot = now.includes('#') ? now.slice(now.indexOf('#')) : ''
321
+ if (spot !== '' && base(was) === base(now)) return ` · ${spot.slice(0, 120)}`
322
+ return ' · new page'
323
+ }
314
324
  const words = Math.abs(Number(nowText ?? 0) - Number(wasText ?? 0))
315
325
  const nodes = Math.abs(Number(nowNodes ?? 0) - Number(wasNodes ?? 0))
316
326
  if (nowTitle !== wasTitle) return ' · page moved on'
@@ -352,9 +362,27 @@ export function withoutSeenAddress(page, url, text) {
352
362
  return body.slice(first.length + 1)
353
363
  }
354
364
 
365
+ /** The focus line repeats the control the call named: say the name once. */
366
+ export function dropSameFocus(line, args) {
367
+ const squeezed = (value) => String(value ?? '').toLowerCase().replace(/\s+/g, '')
368
+ const named = squeezed(args?.text ?? args?.name ?? args?.ref ?? '')
369
+ if (named === '') return line
370
+ const at = line.indexOf(' · focus ')
371
+ if (at < 0) return line
372
+ const head = line.slice(0, at)
373
+ const parts = line.slice(at + ' · focus '.length).split(' · ')
374
+ const said = String(parts[0] ?? '')
375
+ /* A field carries a value the words do not: that part is news, so it stays. */
376
+ if (said.includes(' = ')) return line
377
+ const label = squeezed(said)
378
+ if (label !== named && !label.includes(named) && !named.includes(label)) return line
379
+ const rest = parts.slice(1)
380
+ return rest.length === 0 ? head : `${head} · ${rest.join(' · ')}`
381
+ }
382
+
355
383
  async function acted(page, args, look, label) {
356
384
  if (args?.read === true) return await look()
357
- return `ok ${label} · ${oncePerPage(page, await brief(page))}`
385
+ return `ok ${label} · ${dropSameFocus(oncePerPage(page, await brief(page)), args)}`
358
386
  }
359
387
 
360
388
  /**