Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
189110f
feat: Created transport module with object-safe Listener/Connector trai…
taweili May 13, 2026
1f7b843
feat: Wired transport module into daemon server, added TCP listening al…
taweili May 13, 2026
2d11f69
feat: Added global --tcp CLI flag and wired TCP transport with 15s conn…
taweili May 13, 2026
7681e69
feat: Wired --tcp into daemon stop command with manual-stop warning; st…
taweili May 13, 2026
57ad8f1
test: All changes compile on native and Windows targets; 32 unit tests…
taweili May 13, 2026
ee54abd
test: Added 3 integration tests (round-trip, connection refused, livene…
taweili May 13, 2026
7b50d6a
test: Added real TCP daemon integration tests that spawn the actual wx…
taweili May 13, 2026
a8ac864
test: Added TCP vs local transport data comparison test that queries se…
taweili May 13, 2026
e145090
chore: auto-commit after complete-milestone
taweili May 13, 2026
59b2ebb
chore: auto-commit after complete-milestone
taweili May 13, 2026
5a4de7f
chore: auto-commit after worktree-switch
taweili May 13, 2026
3d0dd9b
feat: migrate from eprintln! to tracing for structured logging
taweili May 13, 2026
7ab918a
Merge milestone/M001: migrate to tracing for structured logging
taweili May 13, 2026
11e7372
fix: change default tracing log level from warn to info
taweili May 13, 2026
7d2a54c
chore: untrack .gsd/ runtime files from git index
taweili May 13, 2026
107af74
chore: auto-commit after quick-task
taweili May 13, 2026
521c629
fix: unterminated char literal and missing cli_dir in start_daemon
taweili May 13, 2026
1106b4f
feat(daemon): log every received request at info level
taweili May 13, 2026
cba33e4
fix(cli): require '=' for --tcp flag to prevent subcommand collision
taweili May 13, 2026
1be706d
fix(daemon): pass global --tcp to daemon start
taweili May 13, 2026
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
1 change: 1 addition & 0 deletions .bg-shell/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
27 changes: 27 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,30 @@ __pycache__/
Thumbs.db
find_all_keys_macos
.claude/worktrees/

# ── GSD baseline (auto-generated) ──
.gsd
.gsd-id
.mcp.json
.bg-shell/
*.swp
*.swo
*~
.idea/
.vscode/
*.code-workspace
.env
.env.*
!.env.example
node_modules/
.next/
dist/
build/
*.pyc
.venv/
venv/
vendor/
*.log
coverage/
.cache/
tmp/
86 changes: 86 additions & 0 deletions .gsd.migrating/CODEBASE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Codebase Map

Generated: 2026-05-13T05:22:55Z | Files: 52 | Described: 0/52
<!-- gsd:codebase-meta {"generatedAt":"2026-05-13T05:22:55Z","fingerprint":"3306bb8206b573a313a49bde0ead8c4bf8f719b8","fileCount":52,"truncated":false} -->

### (root)/
- `.gitignore`
- `AGENTS.md`
- `Cargo.toml`
- `CLAUDE.md`
- `config.example.json`
- `install.ps1`
- `install.sh`
- `LICENSE`
- `README.md`
- `SKILL.md`

### .github/workflows/
- `.github/workflows/release.yml`

### docs/
- `docs/macos-3x-vs-4x-decryption-guide.md`
- `docs/macos-permission-guide.md`

### npm/platforms/darwin-arm64/
- `npm/platforms/darwin-arm64/package.json`

### npm/platforms/darwin-x64/
- `npm/platforms/darwin-x64/package.json`

### npm/platforms/linux-arm64/
- `npm/platforms/linux-arm64/package.json`

### npm/platforms/linux-x64/
- `npm/platforms/linux-x64/package.json`

### npm/platforms/win32-x64/
- `npm/platforms/win32-x64/package.json`

### npm/wx-cli/
- `npm/wx-cli/install.js`
- `npm/wx-cli/package.json`

### npm/wx-cli/bin/
- `npm/wx-cli/bin/wx.js`

### src/
- `src/config.rs`
- `src/ipc.rs`
- `src/main.rs`

### src/cli/
- `src/cli/contacts.rs`
- `src/cli/daemon_cmd.rs`
- `src/cli/export.rs`
- `src/cli/favorites.rs`
- `src/cli/history.rs`
- `src/cli/init.rs`
- `src/cli/members.rs`
- `src/cli/mod.rs`
- `src/cli/new_messages.rs`
- `src/cli/output.rs`
- `src/cli/search.rs`
- `src/cli/sessions.rs`
- `src/cli/sns_feed.rs`
- `src/cli/sns_notifications.rs`
- `src/cli/sns_search.rs`
- `src/cli/stats.rs`
- `src/cli/transport.rs`
- `src/cli/unread.rs`

### src/crypto/
- `src/crypto/mod.rs`
- `src/crypto/wal.rs`

### src/daemon/
- `src/daemon/cache.rs`
- `src/daemon/mod.rs`
- `src/daemon/query.rs`
- `src/daemon/server.rs`

### src/scanner/
- `src/scanner/linux.rs`
- `src/scanner/macos.rs`
- `src/scanner/mod.rs`
- `src/scanner/windows.rs`
16 changes: 16 additions & 0 deletions .gsd.migrating/CONTEXT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Project Context

Auto-detected by GSD init wizard. Edit or expand as needed.

## Language / Stack

Primary: rust

## Project Files

- Cargo.toml
- .github/workflows

## CI/CD

CI configuration detected.
12 changes: 12 additions & 0 deletions .gsd.migrating/DECISIONS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Decisions Register

<!-- Append-only. Never edit or remove existing rows.
To reverse a decision, add a new row that supersedes it.
Read this file at the start of any planning or research phase. -->

| # | When | Scope | Decision | Choice | Rationale | Revisable? | Made By |
|---|------|-------|----------|--------|-----------|------------|---------|
| D001 | | architecture | Transport abstraction via traits | Listener and Connector traits with shared protocol.rs, implementations for Unix/Windows/TCP | Eliminates ~50 lines of duplicated JSON-line protocol handling, provides clear extension point for future transports | Yes | collaborative |
| D002 | | architecture | Global --tcp CLI flag for transport selection | Global clap flag on root Cli struct, inherited by all subcommands | Discoverable, consistent UX. User specifies once, affects all commands | Yes | human |
| D003 | | architecture | No built-in TCP security | No TLS, no auth tokens, no IP whitelist in this milestone. Bind exactly as user specifies. | User handles firewall/ACL at OS level. TLS adds cert management and dependency complexity. Can be added later non-breaking. | Yes | collaborative |
| D004 | | architecture | One request per connection protocol model | One JSON-line request per connection, no keepalive or pooling | Matches existing behavior, minimal complexity, sufficient for CLI usage patterns | Yes | agent |
16 changes: 16 additions & 0 deletions .gsd.migrating/PREFERENCES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
version: 1
mode: solo
git:
isolation: worktree
main_branch: main
auto_push: true
verification_commands:
- cargo test
- cargo clippy
---
# GSD Project Preferences

Generated by `/gsd init`. Edit directly or use `/gsd prefs project` to modify.

See `~/.gsd/agent/extensions/gsd/docs/preferences-reference.md` for full field documentation.
35 changes: 35 additions & 0 deletions .gsd.migrating/PROJECT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# wx-cli

## What This Is

A cross-platform Rust CLI tool for extracting and querying local WeChat 4.x data. Decrypts SQLCipher-encrypted databases, caches decrypted copies with mtime-aware invalidation, and provides a daemon-based IPC architecture for fast repeated queries. Currently uses Unix sockets (macOS/Linux) and Windows named pipes for local-only communication.

## Core Value

Query your local WeChat chat history, contacts, and moments from the command line with millisecond response times — data never leaves your machine.

## Project Shape

- **Complexity:** simple
- **Why:** Well-defined scope, existing codebase with clear module boundaries, single transport addition with refactoring

## Current State

Version 0.1.10. Fully functional CLI with 17 subcommands. Daemon auto-starts on first query. Cross-platform (macOS, Linux, Windows). No integration tests. Local IPC only.

## Architecture / Key Patterns

- Single binary: client and daemon (`WX_DAEMON_MODE` env var)
- Daemon uses tokio async runtime, Unix socket / Windows named pipe IPC
- JSON-line protocol: one request per connection
- mtime-aware decryption cache in `~/.wx-cli/cache/`
- Platform-specific memory scanners for SQLCipher key extraction
- All queries executed via rusqlite on decrypted DBs

## Capability Contract

See `.gsd/REQUIREMENTS.md` for the explicit capability contract.

## Milestone Sequence

- [ ] M001: TCP Transport — Add `--tcp host:port` global flag and TCP transport support to daemon and client
163 changes: 163 additions & 0 deletions .gsd.migrating/REQUIREMENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
# Requirements

## Active

### R001 — TCP transport on server
- Class: core-capability
- Status: active
- Description: Daemon listens on TCP when `--tcp host:port` is specified, in addition to local transport
- Why it matters: Enables remote clients to query WeChat data over network
- Source: user
- Primary owning slice: M001/S01
- Supporting slices: M001/S02
- Validation: unmapped
- Notes: Bind exactly as user specifies, no TLS, no IP whitelist

### R002 — TCP transport on client
- Class: core-capability
- Status: active
- Description: Client connects via TCP when `--tcp host:port` is specified, with no local fallback
- Why it matters: Users explicitly choosing TCP must connect to that address
- Source: user
- Primary owning slice: M001/S02
- Supporting slices: none
- Validation: unmapped
- Notes: Hard error if connection fails, no silent fallback

### R003 — Transport abstraction layer
- Class: quality-attribute
- Status: active
- Description: Transport layer uses trait-based abstraction (Listener/Connector) to eliminate platform duplication
- Why it matters: Makes adding new transports (TCP, future TLS) easy without duplicating protocol logic
- Source: inferred
- Primary owning slice: M001/S01
- Supporting slices: M001/S02, M001/S03
- Validation: unmapped
- Notes: Must support Unix socket, Windows named pipe, and TCP

### R004 — Global `--tcp` CLI flag
- Class: primary-user-loop
- Status: active
- Description: `--tcp host:port` is a global CLI flag, affecting all commands including `daemon status`, `daemon logs`, and all query commands
- Why it matters: Discoverable, consistent interface for TCP across all commands
- Source: user
- Primary owning slice: M001/S02
- Supporting slices: none
- Validation: unmapped
- Notes: Replaces env var approach, cleaner UX

### R005 — Daemon start command
- Class: primary-user-loop
- Status: active
- Description: New `wx daemon start` subcommand to explicitly start the daemon with configurable options
- Why it matters: Currently daemon auto-starts on first query; explicit start gives user control over transport config
- Source: user
- Primary owning slice: M001/S01
- Supporting slices: none
- Validation: unmapped
- Notes: Should support `--tcp` flag

### R006 — Cross-platform compilation
- Class: constraint
- Status: active
- Description: Code compiles on macOS, Linux, and Windows (`cargo check` on all targets)
- Why it matters: Project is cross-platform by design, TCP must work on all three
- Source: inferred
- Primary owning slice: M001/S01
- Supporting slices: M001/S02, M001/S03
- Validation: unmapped
- Notes: TcpListener/TcpStream are std library, should be trivial

### R007 — Error handling for TCP failures
- Class: failure-visibility
- Status: active
- Description: TCP bind/connect failures produce clear error messages with no silent fallback
- Why it matters: Users need to know when transport configuration fails
- Source: inferred
- Primary owning slice: M001/S02
- Supporting slices: none
- Validation: unmapped
- Notes: 15s connect timeout, 120s read/write timeout

### R008 — Integration: CLI ↔ daemon over TCP
- Class: integration
- Status: active
- Description: End-to-end verification: CLI and daemon communicate successfully over TCP on localhost
- Why it matters: Proves the transport actually works, not just compiles
- Source: inferred
- Primary owning slice: M001/S04
- Supporting slices: none
- Validation: unmapped
- Notes: Manual smoke test sufficient, no automated integration tests

## Deferred

### R020 — TLS encryption for TCP transport
- Class: compliance/security
- Status: deferred
- Description: Optional TLS encryption on TCP transport for secure remote access
- Why it matters: Plaintext TCP exposes chat data to network sniffing
- Source: inferred
- Primary owning slice: none
- Supporting slices: none
- Validation: unmapped
- Notes: Deferred — adds tokio-rustls dependency and cert management complexity

### R021 — Authentication tokens for TCP
- Class: compliance/security
- Status: deferred
- Description: Token-based authentication for TCP connections
- Why it matters: Prevents unauthorized access to WeChat data over network
- Source: inferred
- Primary owning slice: none
- Supporting slices: none
- Validation: unmapped
- Notes: Deferred — requires protocol change (Auth request type)

### R022 — TCP connection keepalive
- Class: quality-attribute
- Status: deferred
- Description: Persistent TCP connections with keepalive for reduced latency
- Why it matters: Current one-request-per-connection model has connection overhead
- Source: inferred
- Primary owning slice: none
- Supporting slices: none
- Validation: unmapped
- Notes: Deferred — requires protocol and connection management changes

## Out of Scope

### R030 — Network-level access control
- Class: constraint
- Status: out-of-scope
- Description: IP whitelisting, firewall rules, or network ACLs within the application
- Why it matters: Prevents scope creep into network security management
- Source: user
- Primary owning slice: none
- Supporting slices: none
- Validation: n/a
- Notes: User handles firewall/ACL at OS level

## Traceability

| ID | Class | Status | Primary owner | Supporting | Proof |
|---|---|---|---|---|---|
| R001 | core-capability | active | M001/S01 | M001/S02 | unmapped |
| R002 | core-capability | active | M001/S02 | none | unmapped |
| R003 | quality-attribute | active | M001/S01 | M001/S02, M001/S03 | unmapped |
| R004 | primary-user-loop | active | M001/S02 | none | unmapped |
| R005 | primary-user-loop | active | M001/S01 | none | unmapped |
| R006 | constraint | active | M001/S01 | M001/S02, M001/S03 | unmapped |
| R007 | failure-visibility | active | M001/S02 | none | unmapped |
| R008 | integration | active | M001/S04 | none | unmapped |
| R020 | compliance/security | deferred | none | none | unmapped |
| R021 | compliance/security | deferred | none | none | unmapped |
| R022 | quality-attribute | deferred | none | none | unmapped |
| R030 | constraint | out-of-scope | none | none | n/a |

## Coverage Summary

- Active requirements: 8
- Mapped to slices: 8
- Validated: 0
- Unmapped active requirements: 0
18 changes: 18 additions & 0 deletions .gsd.migrating/STATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# GSD State

**Active Milestone:** M001: TCP Transport
**Active Slice:** S01: Transport abstraction layer
**Phase:** planning
**Requirements Status:** 0 active · 0 validated · 0 deferred · 0 out of scope

## Milestone Registry
- 🔄 **M001:** TCP Transport

## Recent Decisions
- None recorded

## Blockers
- None

## Next Action
Slice S01 has no DB tasks. Plan slice tasks before execution.
Loading