{
  "title": "Files tree width",
  "beforeRevision": "084a4106040a0d64a02ac04eecf88ea8a8a8f31b",
  "afterRevision": "ab650488ed6a9db47bdc14b9682458a2fdc1683f",
  "builds": {
    "before": "bd00d766c4f403c3",
    "after": "bf128a3fcf7cd316"
  },
  "versions": {
    "before": {
      "pins": {
        "agentServer": "1.58.1",
        "agentCanvas": "1.33.0",
        "automation": "1.25.1"
      },
      "reportedRuntime": {
        "agentServer": "1.58.1",
        "sdk": "1.58.1"
      },
      "node": "v24.22.1",
      "npm": "11.12.1",
      "browserUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.0.0 Safari/537.36",
      "automation": "Committed launcher pin 1.25.1; /api/automation/health reports status only, no independent version field."
    },
    "after": {
      "pins": {
        "agentServer": "1.58.1",
        "agentCanvas": "1.33.0",
        "automation": "1.25.1"
      },
      "reportedRuntime": {
        "agentServer": "1.58.1",
        "sdk": "1.58.1"
      },
      "node": "v24.22.1",
      "npm": "11.12.1",
      "browserUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/156.0.0.0 Safari/537.36",
      "automation": "Committed launcher pin 1.25.1; /api/automation/health reports status only, no independent version field."
    }
  },
  "implementation": {
    "before": "The persisted, clamped file-tree width is applied as an inline width declaration.",
    "after": "The same persisted width is forwarded through --files-tab-tree-width and consumed by the Tailwind width utility. Existing state clamping, persistence and shrink-0 behavior remain in place.",
    "owner": "src/routes/files-tab.tsx; generated Tailwind CSS width utility"
  },
  "scope": {
    "desktop": {
      "theme": "OpenHands-Neutral",
      "viewport": [
        1440,
        1000
      ],
      "sidebar": "expanded",
      "gettingStarted": "collapsed, 1 complete",
      "conversation": "Files width check; genuine idle; no messages",
      "fixtureBasename": "qa-width-workspace",
      "selected": "src/calc.py",
      "content": "def add(a, b):\n    return a + b\n",
      "drawerWidth": 569,
      "drawerStoredPercent": "50"
    },
    "phone": {
      "theme": "Light+",
      "viewport": [
        390,
        844
      ]
    },
    "phoneSidebar": "Files panel route, full phone viewport",
    "phoneExercise": "224→160→reload160→224",
    "comparison": "Actual separator drags, desktop min/max clamp, persisted reload width, collapse/restore, selected highlighted calc.py preview, and representative theme stills."
  },
  "comparisonSummary": "13 named direct DOM samples paired; maximum observed settled geometry difference 0 px, 0 comparable stable-field differences. Exact scope and sampled fields are in the comparison JSON.",
  "limits": [
    "This evidence compares the specified genuine Before and After revisions; it is not a claim of pixel identity, exhaustive UI coverage, or a speed/performance improvement.",
    "The central film is curated from labelled source intervals at 25 fps without editorial speed changes. Complete original PNGs and MP4s are in the ZIP.",
    "The source recorder caps an unchanged initial lead-in at one second and holds the final frame at least one second. Per-source capture-clock and encoded durations are retained; these can differ without changing action intervals.",
    "No credentials, provider connection, login submission, or model invocation was used. The genuine unconfigured-model banner remains visible.",
    "The After phone source reports one screenshot capture miss and includes a 2.624-second static screenshot delay around the reloaded 160px state. The raw receipt and recording are retained; no guarantee is made that every motion frame was captured.",
    "The 160–480 px range is shown in the desktop drag/clamp exercise. The phone film exercises 224→160→reload160→224; it does not claim that all supported tree widths fit a phone viewport.",
    "At the desktop 480 px limit, the remaining preview space is narrow in both revisions. Existing narrow-layout behavior is retained.",
    "The selected file remains calc.py after reload while its src folder naturally collapses; the actual highlighted code readout is recorded.",
    "The central desktop footage uses a labelled actual top-right source crop after a clean full-viewport lead. The full unmodified recordings remain in the ZIP.",
    "One initial Files recipe click timeout occurred before recording, when an already active Files control closed the drawer. It was retained in the receipt, followed by a healthy doctor check, reload and successful retry."
  ],
  "captureProvenance": "files-tree-width-capture-provenance.json",
  "captureProvenanceSha256": "d4dbe207759c985a3f0e64ea0e11d0bd453899e17c58daf5be5d1ac152a41c42",
  "evidenceDownload": "files-tree-width-evidence.zip",
  "evidenceDownloadSha256": "110318b3b8bbec8b9ec08e0c3ff6e76f533e14a7e6899029f290a659f723a670",
  "pullRequest": "https://github.com/OpenHands/OpenHands/pull/18903",
  "film": {
    "dimensions": [
      1440,
      1120
    ],
    "fps": 25,
    "durationSeconds": 59.92,
    "scenes": [
      {
        "phase": "before",
        "sourceRevision": "084a4106040a0d64a02ac04eecf88ea8a8a8f31b",
        "kind": "screenshot",
        "publicSourcePath": "files-tree-width-evidence/before/neutral-desktop-restored-224.png",
        "label": "Before · Inline width",
        "subtitle": "Desktop · Full context",
        "caption": "Before: genuine clean full desktop viewport at restored 224px. This contextual still is held for 1.6 seconds; the next scene shows the original desktop recording from its beginning.",
        "view": "Desktop",
        "cropDisclosure": "Full original 1440×1000 viewport below a separate editorial header.",
        "sourceSha256": "d5ba801be0eba2c46ecbe2327286afe7d19d7dde6b2d95862768e285fb210da9",
        "sourceBytes": 61182,
        "sourceDurationSeconds": null,
        "sourceFps": null,
        "timelineSeconds": [
          0,
          1.6
        ],
        "presentationDurationSeconds": 1.6,
        "editorialSpeedChange": false,
        "sourceStartSeconds": 0,
        "sourceSelectedRangeSeconds": [
          0,
          1.6
        ],
        "fullOriginalSelected": false,
        "sourcePlaybackNote": "Selected MP4 interval presented at its existing frame cadence. Recorder caps an initial static lead-in at 1 second and holds the final frame at least 1 second; action intervals retain capture timing. Presentation repeats frames only for output cadence; no motion interpolation.",
        "fullOriginalTimelineSelected": false,
        "fullOriginalViewportSelected": true
      },
      {
        "phase": "before",
        "sourceRevision": "084a4106040a0d64a02ac04eecf88ea8a8a8f31b",
        "kind": "recording",
        "publicSourcePath": "files-tree-width-evidence/before/neutral-desktop-resize.mp4",
        "label": "Before · Inline width",
        "subtitle": "Detail · Same 160–480px range",
        "caption": "Before: complete genuine desktop drag, clamp, reload and restore recording at its existing 25 fps cadence. Labelled actual source crop x870/y0/570×500px enlarges the Files controls and selected highlighted calc.py preview. Full viewport original remains in the ZIP.",
        "view": "Desktop detail",
        "crop": [
          870,
          0,
          570,
          500
        ],
        "cropDisclosure": "Actual top-right 570×500px source crop at x870/y0, fitted below a separate editorial header. No UI pixels are fabricated.",
        "sourceSha256": "5875c032b756e5788e442a358efe569dc3f1837da22144a969a22fcdd4e68fec",
        "sourceBytes": 155758,
        "sourceDurationSeconds": 17.88,
        "sourceFps": 25.0,
        "timelineSeconds": [
          1.6,
          19.48
        ],
        "presentationDurationSeconds": 17.88,
        "editorialSpeedChange": false,
        "sourceStartSeconds": 0,
        "sourceSelectedRangeSeconds": [
          0,
          17.88
        ],
        "fullOriginalSelected": false,
        "sourcePlaybackNote": "Selected MP4 interval presented at its existing frame cadence. Recorder caps an initial static lead-in at 1 second and holds the final frame at least 1 second; action intervals retain capture timing. Presentation repeats frames only for output cadence; no motion interpolation.",
        "fullOriginalTimelineSelected": true,
        "fullOriginalViewportSelected": false
      },
      {
        "phase": "after",
        "sourceRevision": "ab650488ed6a9db47bdc14b9682458a2fdc1683f",
        "kind": "screenshot",
        "publicSourcePath": "files-tree-width-evidence/after/neutral-desktop-restored-224.png",
        "label": "After · CSS width",
        "subtitle": "Desktop · Full context",
        "caption": "After: genuine clean full desktop viewport at restored 224px. This contextual still is held for 1.6 seconds; the next scene shows the original desktop recording from its beginning.",
        "view": "Desktop",
        "cropDisclosure": "Full original 1440×1000 viewport below a separate editorial header.",
        "sourceSha256": "165bb961045ffbc27dd05d92fdbd9cc7125371051888bb82b8f8a10c5a20f62a",
        "sourceBytes": 61210,
        "sourceDurationSeconds": null,
        "sourceFps": null,
        "timelineSeconds": [
          19.48,
          21.08
        ],
        "presentationDurationSeconds": 1.6,
        "editorialSpeedChange": false,
        "sourceStartSeconds": 0,
        "sourceSelectedRangeSeconds": [
          0,
          1.6
        ],
        "fullOriginalSelected": false,
        "sourcePlaybackNote": "Selected MP4 interval presented at its existing frame cadence. Recorder caps an initial static lead-in at 1 second and holds the final frame at least 1 second; action intervals retain capture timing. Presentation repeats frames only for output cadence; no motion interpolation.",
        "fullOriginalTimelineSelected": false,
        "fullOriginalViewportSelected": true
      },
      {
        "phase": "after",
        "sourceRevision": "ab650488ed6a9db47bdc14b9682458a2fdc1683f",
        "kind": "recording",
        "publicSourcePath": "files-tree-width-evidence/after/neutral-desktop-resize.mp4",
        "label": "After · CSS width",
        "subtitle": "Detail · Same 160–480px range",
        "caption": "After: complete genuine desktop drag, clamp, reload and restore recording at its existing 25 fps cadence. Labelled actual source crop x870/y0/570×500px enlarges the Files controls and selected highlighted calc.py preview. Full viewport original remains in the ZIP.",
        "view": "Desktop detail",
        "crop": [
          870,
          0,
          570,
          500
        ],
        "cropDisclosure": "Actual top-right 570×500px source crop at x870/y0, fitted below a separate editorial header. No UI pixels are fabricated.",
        "sourceSha256": "eaa3645455284fd5988f8664cc5c84803671f346598a86196c1b268bc9f5a7ad",
        "sourceBytes": 165071,
        "sourceDurationSeconds": 18.16,
        "sourceFps": 25.0,
        "timelineSeconds": [
          21.08,
          39.24
        ],
        "presentationDurationSeconds": 18.16,
        "editorialSpeedChange": false,
        "sourceStartSeconds": 0,
        "sourceSelectedRangeSeconds": [
          0,
          18.16
        ],
        "fullOriginalSelected": false,
        "sourcePlaybackNote": "Selected MP4 interval presented at its existing frame cadence. Recorder caps an initial static lead-in at 1 second and holds the final frame at least 1 second; action intervals retain capture timing. Presentation repeats frames only for output cadence; no motion interpolation.",
        "fullOriginalTimelineSelected": true,
        "fullOriginalViewportSelected": false
      },
      {
        "phase": "before",
        "sourceRevision": "084a4106040a0d64a02ac04eecf88ea8a8a8f31b",
        "kind": "recording",
        "publicSourcePath": "files-tree-width-evidence/before/light-plus-phone-resize.mp4",
        "sourceStart": 0,
        "label": "Before · Inline width",
        "subtitle": "Phone · 224↔160px",
        "caption": "Before: genuine Light+ phone drag, reload and restore, source interval 0.00–9.48s at its existing 25 fps cadence. The full phone viewport is retained. This exercises 224px and 160px; it does not claim every supported width fits a phone.",
        "view": "Phone",
        "cropDisclosure": "Full original 390×844 viewport below a separate editorial header.",
        "sourceSha256": "582c3fd3724d6602a2b4cbce338edc7798564d84c4592b1cacd37fff48ae1116",
        "sourceBytes": 63992,
        "sourceDurationSeconds": 10.96,
        "sourceFps": 25.0,
        "timelineSeconds": [
          39.24,
          48.72
        ],
        "presentationDurationSeconds": 9.48,
        "editorialSpeedChange": false,
        "sourceStartSeconds": 0,
        "sourceSelectedRangeSeconds": [
          0,
          9.48
        ],
        "fullOriginalSelected": false,
        "sourcePlaybackNote": "Selected MP4 interval presented at its existing frame cadence. Recorder caps an initial static lead-in at 1 second and holds the final frame at least 1 second; action intervals retain capture timing. Presentation repeats frames only for output cadence; no motion interpolation.",
        "fullOriginalTimelineSelected": false,
        "fullOriginalViewportSelected": true
      },
      {
        "phase": "after",
        "sourceRevision": "ab650488ed6a9db47bdc14b9682458a2fdc1683f",
        "kind": "recording",
        "publicSourcePath": "files-tree-width-evidence/after/light-plus-phone-resize.mp4",
        "sourceStart": 0,
        "label": "After · CSS width",
        "subtitle": "Phone · 224↔160px",
        "caption": "After: genuine Light+ phone drag, reload and restore, source interval 0.00–11.20s at its existing 25 fps cadence. The full phone viewport is retained. This exercises 224px and 160px; it does not claim every supported width fits a phone.",
        "view": "Phone",
        "cropDisclosure": "Full original 390×844 viewport below a separate editorial header.",
        "sourceSha256": "e2ceeca0b2c19c188b2c2bb77973cbacdd12670b109230a37dca427c25e25589",
        "sourceBytes": 68587,
        "sourceDurationSeconds": 13.36,
        "sourceFps": 25.0,
        "timelineSeconds": [
          48.72,
          59.92
        ],
        "presentationDurationSeconds": 11.2,
        "editorialSpeedChange": false,
        "sourceStartSeconds": 0,
        "sourceSelectedRangeSeconds": [
          0,
          11.2
        ],
        "fullOriginalSelected": false,
        "sourcePlaybackNote": "Selected MP4 interval presented at its existing frame cadence. Recorder caps an initial static lead-in at 1 second and holds the final frame at least 1 second; action intervals retain capture timing. Presentation repeats frames only for output cadence; no motion interpolation.",
        "fullOriginalTimelineSelected": false,
        "fullOriginalViewportSelected": true
      }
    ],
    "ambience": {
      "origin": "Original synthesized ambient pad; no external samples or provider.",
      "frequenciesHz": [
        174.61,
        220,
        261.63
      ],
      "amplitude": 0.004,
      "normalizationGain": 1.232111,
      "fadeInSeconds": 1.5,
      "fadeOutSeconds": 2,
      "meanDbfs": -52.5,
      "peakDbfs": -42.6,
      "applicationAudio": false
    },
    "recipeSha256": "85a8c65655e92c521f844590e66a2214add3bd4a5c49b4fc8782e85aa1b93792",
    "rangeMetadataRepair": {
      "method": "H.264 video_full_range_flag=0 and MP4 color_range tv, stream-copy remux; no reencoding.",
      "decodedFramesCompared": 1498,
      "everyDecodedYuvFrameIdentical": true,
      "aacElementaryBytesIdentical": true,
      "previousPrivateMp4Sha256": "e3608aee5893f6d6a3658df7eb6e59690e4dcc5dc91c94d853aedf942ff6f505"
    }
  },
  "preview": {
    "file": "files-tree-width-poster.jpg",
    "dimensions": [
      1440,
      1120
    ],
    "type": "poster",
    "audio": false,
    "limitation": "Still poster. Download or play the MP4 for actual drag, reload and restore behavior."
  },
  "files": {
    "files-tree-width-evidence.zip": {
      "sha256": "110318b3b8bbec8b9ec08e0c3ff6e76f533e14a7e6899029f290a659f723a670",
      "bytes": 1681470
    },
    "files-tree-width-before-after.mp4": {
      "sha256": "cd2bfa2274fe2eea7229b5eb3823900c4498b1b3b46db9345507dc357280dc97",
      "bytes": 1989706
    },
    "files-tree-width-captions.vtt": {
      "sha256": "11ba31274328af46c084352ee4f3f12b8ea92b318aedc7968adb6b1e8484e376",
      "bytes": 1579
    },
    "files-tree-width-comparison.json": {
      "sha256": "13503daacd23593d0f1bbb347057f116aa3f33259cde9facdc6465f11a215360",
      "bytes": 16379
    },
    "files-tree-width-poster.jpg": {
      "sha256": "febc5d8f3f25281e603e606f6129e5d006d9cb5217841c9f98f3859a8294b826",
      "bytes": 71068
    },
    "files-tree-width-capture-provenance.json": {
      "sha256": "d4dbe207759c985a3f0e64ea0e11d0bd453899e17c58daf5be5d1ac152a41c42",
      "bytes": 32494
    }
  }
}
