Skip to content

scripts: make the LINE extension capture work on macOS, Linux and Windows - #278

Open
clins1994 wants to merge 2 commits into
beeper:mainfrom
clins1994:tooling/line-capture-cross-platform
Open

clins1994 wants to merge 2 commits into
beeper:mainfrom
clins1994:tooling/line-capture-cross-platform

Conversation

@clins1994

Copy link
Copy Markdown
Contributor

The capture tooling no longer assumes macOS, and the recorder now saves binary request bodies and the real request headers. Windows (Git Bash) is untested, so please try a capture there.

Les outils de capture de l'extension LINE ne supposent plus macOS, et l'enregistreur sauvegarde désormais les corps de requête binaires et les vrais en-têtes. Windows (Git Bash) n'est pas testé : merci d'y essayer une capture.


🇬🇧 More details

Summary

  • New scripts/line-capture-preflight.sh finds Chrome or Chromium and Python 3.8+ with websocket-client. It reports OK or MISSING and gives no install commands, so the agent picks the install method for the OS and asks the user first.
  • scripts/line-chrome-capture.sh uses the preflight for CHROME and PYTHON, finds the normal Chrome profile per OS, and starts on about:blank.
  • scripts/line-cdp-capture.py saves request bodies and the headers Chrome really sent.
  • scripts/redact-line-capture.py also redacts MIDs, picturePath and the raw body bytes.
  • The agent docs in .agents/ have a preflight step and a warning not to open DevTools on the extension.

Why

A real capture of a group rename and avatar change showed these problems:

  • The launcher only worked on macOS.
  • find on Chrome's Extensions folder failed with "Operation not permitted" and stopped the launcher.
  • Opening index.html as a tab behaved differently from the real popup.
  • The obs/uploadProfile image uploads had no saved body, and only three request headers showed.
  • The extension's per-group popup.html windows stayed blank, and LINE showed "Debugger paused in another tab".

Changes

  • Preflight: detects macOS, Linux, WSL and Windows. It looks for python3, python and py -3. --print-env prints CHROME= and PYTHON=.
  • Launcher:
    • The normal Chrome profile is ~/Library/Application Support/Google/Chrome on macOS, ~/.config/google-chrome or ~/.config/chromium on Linux, and %LOCALAPPDATA%/Google/Chrome/User Data on Windows.
    • Unreadable extension folders are skipped with a warning.
    • The start URL is about:blank. LINE_CAPTURE_START_URL still overrides it.
    • Paths passed to Chrome go through cygpath -w when it exists.
    • The user text says "quit Chrome completely".
  • Recorder:
    • It sends Runtime.runIfWaitingForDebugger to targets that wait for the debugger. This fixes the blank popup.html windows.
    • It calls Network.getRequestPostData for every LINE request with a body. It stores size and sha256, and the bytes in base64 in the raw capture only.
    • It records Network.requestWillBeSentExtraInfo headers as request_extra_headers.
  • scripts/parse-line-traffic.py merges the extra headers and prints body size and sha256 instead of the bytes.
  • scripts/redact-line-capture.py redacts the keys mid, chatMid, contactMid, picturePath, pictureStatus, oid and base64. MIDs after an underscore are now caught too.
  • Docs: the line-capture and line-implement commands and the line-implement skill have the preflight step and the DevTools note. DevTools on the extension hits LINE's debugger; traps, and the recorder does not need it.

How it was tested

  • bash -n on both shell scripts and py_compile on the recorder.
  • Preflight on macOS, and on Ubuntu with Chrome through ssh worth-while 'bash -s' < scripts/line-capture-preflight.sh. Both exit 0.
  • Launcher dry run on macOS with CHROME=/usr/bin/true and a scratch profile. It reaches the Chrome launch step. The "Operation not permitted" folders now print a warning and the run goes on.
  • Recorder logic with fake CDP messages: the body request is sent, and the base64 body and extra headers are stored.
  • A fake capture through the parser and the redactor: tokens, cookies, MIDs, picturePath and body bytes are redacted.

Not tested

  • Windows (Git Bash) was not run at all. The Chrome paths, cygpath conversion and py -3 are untested.
  • No live Chrome capture was run, and nobody logged in to LINE. The recorder against real traffic, and the getRequestPostData result for real binary uploads, still need a check.
  • The launcher was not run on Linux.
🇫🇷 Plus de détails

Summary

  • Le nouveau scripts/line-capture-preflight.sh trouve Chrome ou Chromium, et Python 3.8+ avec websocket-client. Il affiche OK ou MISSING et ne donne aucune commande d'installation : l'agent choisit la méthode adaptée à l'OS et demande d'abord à l'utilisateur.
  • scripts/line-chrome-capture.sh prend CHROME et PYTHON dans le preflight, trouve le profil Chrome habituel selon l'OS et démarre sur about:blank.
  • scripts/line-cdp-capture.py sauvegarde les corps de requête et les en-têtes réellement envoyés par Chrome.
  • scripts/redact-line-capture.py masque aussi les MID, picturePath et les octets bruts des corps.
  • La documentation de .agents/ a une étape de preflight et un avertissement : ne pas ouvrir DevTools sur l'extension.

Why

Une vraie capture d'un changement de nom et d'avatar de groupe a montré ces problèmes :

  • Le lanceur ne fonctionnait que sur macOS.
  • find sur le dossier Extensions de Chrome échouait avec « Operation not permitted » et arrêtait le lanceur.
  • Ouvrir index.html dans un onglet se comportait autrement que le vrai popup.
  • Les envois d'images obs/uploadProfile n'avaient aucun corps sauvegardé, et seulement trois en-têtes de requête apparaissaient.
  • Les fenêtres popup.html de l'extension, une par groupe, restaient vides, et LINE affichait « Debugger paused in another tab ».

Changes

  • Preflight : détecte macOS, Linux, WSL et Windows. Il cherche python3, python et py -3. --print-env affiche CHROME= et PYTHON=.
  • Lanceur :
    • Le profil Chrome habituel est ~/Library/Application Support/Google/Chrome sur macOS, ~/.config/google-chrome ou ~/.config/chromium sur Linux, et %LOCALAPPDATA%/Google/Chrome/User Data sur Windows.
    • Les dossiers d'extension illisibles sont ignorés avec un avertissement.
    • L'URL de départ est about:blank. LINE_CAPTURE_START_URL la remplace toujours.
    • Les chemins passés à Chrome passent par cygpath -w quand il existe.
    • Le texte pour l'utilisateur dit « quitter complètement Chrome ».
  • Enregistreur :
    • Il envoie Runtime.runIfWaitingForDebugger aux cibles qui attendent le débogueur. Cela corrige les fenêtres popup.html vides.
    • Il appelle Network.getRequestPostData pour chaque requête LINE avec un corps. Il stocke la taille et le sha256, et les octets en base64 dans la capture brute seulement.
    • Il enregistre les en-têtes de Network.requestWillBeSentExtraInfo dans request_extra_headers.
  • scripts/parse-line-traffic.py fusionne les en-têtes supplémentaires et affiche la taille et le sha256 du corps au lieu des octets.
  • scripts/redact-line-capture.py masque les clés mid, chatMid, contactMid, picturePath, pictureStatus, oid et base64. Les MID après un tiret bas sont maintenant détectés aussi.
  • Documentation : les commandes line-capture et line-implement et le skill line-implement ont l'étape de preflight et la note sur DevTools. DevTools sur l'extension déclenche les pièges debugger; de LINE, et l'enregistreur n'en a pas besoin.

How it was tested

  • bash -n sur les deux scripts shell et py_compile sur l'enregistreur.
  • Le preflight sur macOS, et sur Ubuntu avec Chrome via ssh worth-while 'bash -s' < scripts/line-capture-preflight.sh. Les deux se terminent avec le code 0.
  • Un essai à blanc du lanceur sur macOS avec CHROME=/usr/bin/true et un profil temporaire. Il atteint l'étape de lancement de Chrome. Les dossiers « Operation not permitted » affichent maintenant un avertissement et l'exécution continue.
  • La logique de l'enregistreur avec de faux messages CDP : la demande de corps est envoyée, et le corps en base64 et les en-têtes supplémentaires sont stockés.
  • Une fausse capture passée dans l'analyseur et l'outil de masquage : jetons, cookies, MID, picturePath et octets du corps sont masqués.

Not tested

  • Windows (Git Bash) n'a pas été exécuté du tout. Les chemins de Chrome, la conversion cygpath et py -3 ne sont pas testés.
  • Aucune vraie capture Chrome n'a été faite, et personne ne s'est connecté à LINE. L'enregistreur sur du vrai trafic, et le résultat de getRequestPostData pour de vrais envois binaires, restent à vérifier.
  • Le lanceur n'a pas été exécuté sur Linux.

🤖 Generated with Claude Code using clins:create-pr

- Add line-capture-preflight.sh (OS, Chrome/Chromium, Python 3.8+,
  websocket-client) and have the launcher use its CHROME/PYTHON.
- Find the normal Chrome profile per OS; skip unreadable extension
  folders with a warning instead of aborting.
- Start on about:blank; open LINE from the toolbar icon.
- Recorder: resume targets held by the debugger, save request bodies
  (binary included) via Network.getRequestPostData and the on-the-wire
  headers from requestWillBeSentExtraInfo.
- Redact MIDs, picturePath and raw body bytes; parser reads the new fields.
- Agent docs: preflight step, no DevTools on the extension during capture.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
- Keep PYTHON as an array so a path with spaces survives.
- Take only the first usable extension dir when Chrome and Chromium both have it.
- Reject Windows chrome.exe under WSL instead of passing it WSL paths.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@clins1994
clins1994 marked this pull request as ready for review October 24, 2026 19:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant