Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
Parse and analyze a LINE Chrome Extension network capture.

## Arguments
## Input

$ARGUMENTS is the path to a net-log JSON file (default: `/tmp/line-capture/line-net-log.json`).
Use the provided path to a net-log JSON file. If no path is provided, default to
`/tmp/line-chrome-extension-capture/line-net-log.json`.

## What to do

Expand Down Expand Up @@ -35,7 +36,7 @@ $ARGUMENTS is the path to a net-log JSON file (default: `/tmp/line-capture/line-

5. Highlight any **unimplemented** endpoints or behaviors that differ from what the bridge currently does. Cross-reference with `pkg/line/methods.go` and `pkg/connector/`.

6. After presenting the analysis, ask the user if they want to clean up the capture files (`/tmp/line-capture/`). Warn that the raw net-log and parsed output contain sensitive data (auth tokens in `X-Line-Access` headers, message IDs, etc.) and should not be left on disk or committed to the repository. If the user agrees, delete the entire capture directory.
6. After presenting the analysis, ask the user if they want to clean up the capture files (`/tmp/line-chrome-extension-capture/`). Warn that the raw net-log and parsed output contain sensitive data (auth tokens in `X-Line-Access` headers, message IDs, etc.) and should not be left on disk or committed to the repository. If the user agrees, delete the entire capture directory.

## LINE protocol context

Expand Down
38 changes: 38 additions & 0 deletions .agents/commands/line-capture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
Launch Chrome with network capture enabled for LINE Chrome Extension analysis.

## What to do

1. **Close any running Chrome instances first** (Chrome only supports one instance per profile with remote debugging). Warn the user if Chrome is running.

2. Run the capture script:
```
bash scripts/line-chrome-capture.sh /tmp/line-chrome-extension-capture
```
This launches Chrome with:
- Remote debugging on port 9222
- Full network logging to `/tmp/line-chrome-extension-capture/line-net-log.json`
- A persistent capture-only Chrome profile at
`~/.cache/line-chrome-extension-capture/chrome-debug-profile`
- Auto-loaded LINE and Codex extensions staged from the user's normal Chrome
profile into `~/.cache/line-chrome-extension-capture/extensions`
- A LINE extension version preflight:
- repo version from `pkg/line/client.go` `ExtensionVersion`
- installed/staged Chrome extension version from `manifest.json`
- a warning if those versions differ
- First-run Chrome prompts pre-skipped:
- "Make Google Chrome the default browser" stays unchecked
- "Automatically send usage statistics and crash reports" stays unchecked
- Chrome/Sync sign-in is skipped; use "Stay Signed Out" if it appears
- If the LINE extension is missing and the user asked for setup, relaunch with
`LINE_CAPTURE_AUTO_LOAD_EXTENSIONS=0`, open the official Web Store listing
for `ophjlpahpchlmihnnnihgmmeilfjmjjc`, verify LINE / LY Corporation, click
Add to Chrome, and accept the standard "Add extension" confirmation

3. Tell the user:
- Open the LINE Chrome Extension (browser toolbar icon)
- Log in manually if the capture profile is not already logged in
- Perform whatever flow they want to analyze
- When done, quit Chrome completely (Cmd+Q)

4. Once Chrome is closed, the net-log file is ready. Continue with the
line-analyze workflow.
93 changes: 93 additions & 0 deletions .agents/commands/line-implement.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
Implement a matrix-line feature by capturing and mimicking LINE Chrome Extension behavior.

## Input

Use the provided feature goal, for example:

```
Support Matrix group avatar changes by matching LINE Chrome Extension traffic.
```

## What to do

1. **Understand the goal and the current bridge first.**
- Read `AGENTS.md`/`CLAUDE.md`, `docs/protocol/README.md`, relevant endpoint docs, and `docs/protocol/gap-analysis.md`.
- Inspect the likely implementation surface in `pkg/line/`, `pkg/connector/`, and existing tests.
- If existing protocol docs already answer the feature, implement from docs and code without a new capture.

2. **Write a capture contract before launching Chrome.**
Capture only the missing evidence:
- exact user-visible LINE action to perform
- expected Talk/Auth/OBS/SSE endpoints and method names
- request argument shape and ordering
- response wrapper shape, headers, and error behavior
- resulting SSE/operation events, revisions, message metadata, and local state changes
- what values the bridge must persist or expose afterward

3. **Check LINE Chrome Extension version drift.**
- Compare the installed/staged extension `manifest.json` version against
`pkg/line/client.go` `ExtensionVersion`.
- Also check literal `x-line-application` versions in `pkg/line/client.go`
and the default `clientVersion` in `pkg/runner.go`.
- The capture launcher prints the repo and Chrome extension versions and
warns on mismatch. Do not silently mix capture evidence from a different
LINE Chrome Extension version.

4. **Security preflight.**
- Treat raw captures as secrets: they can contain access tokens, cookies, MIDs, message contents, contact data, and E2EE metadata.
- Use a fresh `/tmp/line-chrome-extension-capture/<timestamp>-<slug>` directory with `umask 077`.
- Do not commit raw capture files, Chrome profiles, screenshots, QR codes, or parsed JSON.
- Do not request, store, or automate the LINE password.
- The user performs LINE login manually, including email/password, QR, PIN, 2FA, and mobile approval.
- Do not run the bridge and LINE Chrome Extension simultaneously unless the user explicitly accepts session invalidation.
- Prefer the persistent capture Chrome profile from `scripts/line-chrome-capture.sh`. Use the user's normal Chrome profile only after explicit approval.

5. **Run the capture.**
- Check for running Chrome and `matrix-line` processes; warn before closing or stopping anything.
- Start capture:
```
umask 077
CAPTURE_DIR="/tmp/line-chrome-extension-capture/$(date +%Y%m%d-%H%M%S)-<slug>"
bash scripts/line-chrome-capture.sh "$CAPTURE_DIR"
```
- Use Codex Chrome automation when available to drive the already-logged-in extension UI. If it cannot access the capture profile or extension UI, use Computer Use.
- The launcher stages clean unpacked LINE and Codex extension copies from the user's normal Chrome profile and auto-loads them when possible.
- The launcher pre-skips Chrome's first-run prompts: default browser is off,
usage/crash reporting is off, and Chrome/Sync sign-in should be skipped.
If the sign-in screen still appears, choose "Stay Signed Out".
- If Chrome blocks unpacked loading or LINE is missing from the capture
profile, relaunch setup with `LINE_CAPTURE_AUTO_LOAD_EXTENSIONS=0`, open
the official Web Store listing
`https://chromewebstore.google.com/detail/line/ophjlpahpchlmihnnnihgmmeilfjmjjc`,
verify LINE / LY Corporation, click Add to Chrome, and accept the standard
"Add extension" confirmation when the user has requested setup.
- If Chrome is not logged in, pause and ask the user to complete LINE login manually in the capture browser.
- Perform the smallest LINE UI flow that satisfies the capture contract, then quit Chrome completely.

6. **Parse, redact, and analyze.**
- Prefer CDP output because it includes SSE messages:
```
python3 scripts/parse-line-traffic.py "$CAPTURE_DIR/line-cdp-capture.json" "$CAPTURE_DIR/line-cdp-capture-parsed.json"
python3 scripts/redact-line-capture.py "$CAPTURE_DIR/line-cdp-capture-parsed.json"
```
- Read raw files only locally and only when redacted output loses information needed for implementation.
- Quote or document only redacted snippets.
- Compare against `pkg/line/methods.go`, `pkg/line/client.go`, `pkg/line/sse.go`, and the relevant `pkg/connector/` flow.
- Produce an evidence table: Chrome behavior, bridge behavior, implementation delta, files to change.

7. **Implement religiously.**
- Match the Chrome Extension's endpoint path, service/method name, argument order, headers, request body shape, response handling, and fallback behavior.
- Preserve existing bridge architecture: Thrift/API code in `pkg/line`, Matrix-facing behavior in `pkg/connector`, E2EE behavior in `pkg/e2ee`/`pkg/ltsm`.
- Update protocol docs only with redacted request/response/event evidence.
- Add or update focused tests for parsing, request construction, event handling, persistence, and fallback/error behavior.

8. **Verify and clean up.**
- Run:
```
go fmt ./...
goimports -local "github.com/highesttt/matrix-line-messenger" -w .
go test ./...
go vet $(go list ./... | grep -v /ltsm)
```
- If available, run `staticcheck $(go list ./... | grep -v /ltsm)`.
- Before finishing, report where raw captures live and ask whether to delete them. Prefer keeping only redacted notes/docs.
170 changes: 170 additions & 0 deletions .agents/skills/line-implement/REFERENCE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
# Line Implement Reference

## Repo Orientation

Start with:

- `AGENTS.md` / `CLAUDE.md`
- `.agents/commands/line-capture.md`
- `.agents/commands/line-analyze.md`
- `.agents/commands/line-implement.md`
- `docs/protocol/README.md`
- `docs/protocol/endpoints/README.md`
- `docs/protocol/gap-analysis.md`
- `pkg/line/methods.go`, `pkg/line/client.go`, `pkg/line/sse.go`
- likely `pkg/connector/*` files for the Matrix-facing feature

Do not capture if the current protocol docs already provide enough evidence.
Use `.agents` as the repo-local source of truth. `.claude/commands` is a
compatibility symlink for Claude-style command discovery when present.

## Capture Contract

Before launching Chrome, write down:

- the exact LINE UI action to perform
- fixture requirements such as DM/group, `c...`/`r...` chat MID type, media type,
old/new state, or Letter Sealing state
- expected endpoint families: TalkService, AuthService, LoginQrCode, OBS, SSE,
CDN, or secondary APIs
- unknowns needed for implementation: method name, URL, argument order, request
body shape, response wrapper, headers, operation events, revision changes,
persisted IDs, and fallback/error behavior

Keep the UI flow narrow. Avoid broad exploratory captures unless the protocol
surface is genuinely unknown.

## Version Preflight

Before trusting capture evidence, compare the repo's LINE Chrome Extension
version with the installed extension:

```bash
rg -n 'ExtensionVersion|x-line-application|clientVersion' pkg/line/client.go pkg/runner.go
find "$HOME/.cache/line-chrome-extension-capture/chrome-debug-profile/Default/Extensions/ophjlpahpchlmihnnnihgmmeilfjmjjc" \
-maxdepth 2 -type f -name manifest.json -print
```

The canonical repo version is `pkg/line/client.go` `ExtensionVersion`. Also
check hardcoded `x-line-application` header strings in `pkg/line/client.go` and
the default `clientVersion` in `pkg/runner.go`; those must not drift from the
extension manifest version. The capture launcher prints repo and Chrome LINE
versions at startup and warns on mismatch. If versions differ, do not silently
mix evidence: warn the user and either update the repo version constants/headers
or record that the capture was taken from a different LINE Chrome Extension
version.

## Security Rules

Raw LINE captures are secrets. They may include access tokens, cookies, session
IDs, MIDs, contacts, message bodies, media object IDs, QR/login artifacts, and
E2EE metadata.

- Use `/tmp/line-chrome-extension-capture/<timestamp>-<slug>` with `umask 077`.
- Prefer the persistent dedicated Chrome profile created by `scripts/line-chrome-capture.sh`
at `~/.cache/line-chrome-extension-capture/chrome-debug-profile`.
- Ask before using the user's normal Chrome profile.
- Ask before stopping a running bridge or invalidating an active LINE session.
- Keep remote debugging local and close Chrome after capture.
- If the user asks to set up the capture browser, installing the official LINE
Chrome Extension is in scope. Verify extension ID
`ophjlpahpchlmihnnnihgmmeilfjmjjc`, listing name LINE, and publisher/offered
by LY Corporation before clicking Add to Chrome and accepting the standard
"Add extension" confirmation.
- Do not request, store, or automate LINE credentials.
- Never ask the user to paste their LINE password into chat, command arguments,
files, or terminal output.
- If the capture browser is not logged in, pause and ask the user to complete
LINE login manually in Chrome, including email/password, QR, PIN, 2FA, and
mobile approval.
- Never commit raw captures, Chrome profiles, screenshots, QR codes, parsed JSON,
or redacted files unless the user explicitly asks for sanitized docs.
- Quote/document only redacted snippets.

## Capture Commands

Use CDP capture first because it includes SSE event bodies:

```bash
umask 077
CAPTURE_DIR="/tmp/line-chrome-extension-capture/$(date +%Y%m%d-%H%M%S)-feature-slug"
bash scripts/line-chrome-capture.sh "$CAPTURE_DIR"
```

The launcher stages clean unpacked copies of the LINE and Codex Chrome extension
directories from the user's normal Chrome profile when they are installed there,
then auto-loads those staged copies. When LINE is already installed in the
persistent capture profile, the launcher uses that installed copy and only
auto-loads other staged extensions; in that mode it must not pass
`--disable-extensions-except` for only the staged helpers, because that disables
the installed LINE extension. Override detection with
`LINE_CHROME_EXTENSION_DIR` or `CODEX_CHROME_EXTENSION_DIR` when needed.
If unpacked loading is blocked by Chrome, use the persistent capture profile to
open the official LINE Chrome Web Store listing and install it there; start this
setup run with `LINE_CAPTURE_AUTO_LOAD_EXTENSIONS=0` so Chrome is not also
loading a staged unpacked extension with the same ID. Accept the expected
extension confirmation only after the user has requested setup.
It also pre-seeds the dedicated capture profile so Chrome first-run/sign-in
prompts do not interrupt capture: default-browser opt-in is off, usage/crash
reporting is off, and Chrome/Sync stays signed out. If Chrome still shows the
sign-in screen, choose "Stay Signed Out" and continue to LINE login only.

When Chrome closes:

```bash
python3 scripts/parse-line-traffic.py "$CAPTURE_DIR/line-cdp-capture.json" "$CAPTURE_DIR/line-cdp-capture-parsed.json"
python3 scripts/redact-line-capture.py "$CAPTURE_DIR/line-cdp-capture-parsed.json"
```

Use the net-log only as a backup:

```bash
python3 scripts/parse-line-traffic.py "$CAPTURE_DIR/line-net-log.json" "$CAPTURE_DIR/line-net-log-parsed.json"
python3 scripts/redact-line-capture.py "$CAPTURE_DIR/line-net-log-parsed.json"
```

## Analysis Checklist

Build an evidence table with:

- ordered requests and timestamps
- endpoint URL and service/method
- meaningful headers such as `x-lhm`, `x-lpv`, `x-lsr`, OBS headers, and content type
- request argument shape and exact order
- response status, wrapper code/message/data, and important headers
- SSE/operation event type, params, revisions, message metadata, LOC_KEYs, and
localRev/chat revision changes
- Chrome behavior vs bridge behavior
- implementation delta and files to change

For Thrift payloads, prefer structured decoded data when available. If only
opaque binary/base64 is available, use the URL, service/method, headers, and
observable response/event behavior, then map to existing Go request builders.

## Implementation Rules

- Put LINE API/client behavior in `pkg/line`.
- Put Matrix bridge behavior and portal/message handling in `pkg/connector`.
- Keep E2EE behavior in `pkg/e2ee` and avoid editing generated `pkg/ltsm/wbc_generated.go`.
- Match Chrome's method names, endpoint paths, arg order, header semantics,
body shape, retry/fallback behavior, and event interpretation.
- Prefer existing request helpers and local patterns over new abstractions.
- Add protocol docs for new endpoint behavior using only redacted evidence.
- Add focused tests for request construction, response parsing, event handling,
persistence, and user-visible bridge behavior.

## Verification

Run the relevant subset, then the broader checks when practical:

```bash
go fmt ./...
goimports -local "github.com/highesttt/matrix-line-messenger" -w .
go test ./...
go vet $(go list ./... | grep -v /ltsm)
staticcheck $(go list ./... | grep -v /ltsm)
```

If a command is unavailable or too slow, report that clearly.

At the end, state where raw captures remain and ask whether to delete them.
Loading
Loading