暂存
This commit is contained in:
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
*.log
|
||||||
28
AGENTS.md
Normal file
28
AGENTS.md
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# Repository Guidelines
|
||||||
|
|
||||||
|
## Project Structure & Module Organization
|
||||||
|
This workspace contains two related repositories. `Xime/` is the Android input method built with Kotlin, Jetpack Compose, Gradle, CMake, and JNI. Its main app code lives in `Xime/app/src/main/java`, Android resources in `Xime/app/src/main/res`, bundled Rime/config assets in `Xime/app/src/main/assets`, JVM tests in `Xime/app/src/test`, and instrumented tests in `Xime/app/src/androidTest`. Shared plugin APIs are in `Xime/plugin-core`, sample plugins in `Xime/plugins`, and docs/screenshots in `Xime/docs`.
|
||||||
|
|
||||||
|
`winxime/` is the Windows/Rust TSF implementation. Rust crates live under `winxime/crates`, installer WiX files under `winxime/crates/winxime-server/wix`, runtime resources under `winxime/resources`, and vendored/native dependencies under `winxime/librime` and `winxime/rime-wubi`.
|
||||||
|
|
||||||
|
## Build, Test, and Development Commands
|
||||||
|
Run commands from the relevant subproject directory.
|
||||||
|
|
||||||
|
- Android build: `cd Xime; .\gradlew.bat assembleDebug --quiet` builds debug APKs.
|
||||||
|
- Android unit tests: `cd Xime; .\gradlew.bat :app:testDebugUnitTest` runs JVM tests.
|
||||||
|
- Android instrumented tests: `cd Xime; .\gradlew.bat :app:connectedDebugAndroidTest` requires a device or emulator.
|
||||||
|
- Docs: `cd Xime; pnpm docs:dev` serves VitePress docs locally.
|
||||||
|
- Windows build: `cd winxime; cargo build --quiet` validates the Rust workspace.
|
||||||
|
- Windows package: `cd winxime; .\msi-build.ps1` creates an MSI. `.\rebuild.ps1` rebuilds/registers locally; automated agents should not run it unless explicitly asked.
|
||||||
|
|
||||||
|
## Coding Style & Naming Conventions
|
||||||
|
Use Kotlin/JVM 17 and Rust 2021. Follow existing package namespaces such as `com.kingzcheung.xime.*` and Compose naming conventions: composables and screens use `PascalCase`, helpers/managers use descriptive `PascalCase` class names, and tests end in `Test`. Keep Gradle Kotlin DSL files as `*.gradle.kts`. In Rust, keep crate names kebab-case and modules snake_case. For `winxime`, do not introduce `unwrap()` or `expect()`.
|
||||||
|
|
||||||
|
## Testing Guidelines
|
||||||
|
Add or update tests when changing input logic, settings parsers, plugins, speech, association, or IPC behavior. Android unit tests use JUnit, Mockito, coroutines-test, and Compose test utilities; instrumented tests live in `androidTest`. Rust changes should at minimum pass `cargo build --quiet`; add crate-level tests where behavior is pure and deterministic.
|
||||||
|
|
||||||
|
## Commit & Pull Request Guidelines
|
||||||
|
Recent history uses Conventional Commit-style subjects such as `feat(settings): ...`, `docs(readme): ...`, and `chore(config): ...`; keep scopes specific. PRs should describe the user-visible change, list commands run, link related issues, and include screenshots or screen recordings for keyboard/settings UI changes.
|
||||||
|
|
||||||
|
## Security & Configuration Tips
|
||||||
|
Do not commit local signing material such as `Xime/app/keystore.properties`; use `keystore.properties.example` as the template. Treat `winxime/librime` as read-only unless the task explicitly targets native dependency updates. Automated agents should not commit changes unless requested.
|
||||||
166
CLIPBOARD_SYNC_PLAN.md
Normal file
166
CLIPBOARD_SYNC_PLAN.md
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
# Clipboard Sync Implementation Plan
|
||||||
|
|
||||||
|
## 1. Goal and Scope
|
||||||
|
|
||||||
|
Build clipboard synchronization between the Android input method in `Xime/` and the Windows input method in `winxime/`, using a Docker-deployable HTTPS relay server.
|
||||||
|
|
||||||
|
MVP scope:
|
||||||
|
|
||||||
|
- Sync text clipboard content only.
|
||||||
|
- Devices join the same sync chain by entering a sync code.
|
||||||
|
- Remote content is written to the local system clipboard, equivalent to a user copy action.
|
||||||
|
- Android additionally exposes received synced text in the IME candidate bar so users can commit it directly.
|
||||||
|
- Users can enable/disable sync in settings and must configure an HTTPS relay server URL.
|
||||||
|
|
||||||
|
Out of MVP scope:
|
||||||
|
|
||||||
|
- Image/file/rich-text clipboard sync.
|
||||||
|
- Automatic paste into the currently focused field.
|
||||||
|
- Multi-user administration UI.
|
||||||
|
- Cloud-hosted default relay.
|
||||||
|
|
||||||
|
## 2. Repository Layout Proposal
|
||||||
|
|
||||||
|
Add a new backend service at workspace root:
|
||||||
|
|
||||||
|
```text
|
||||||
|
sync-server/
|
||||||
|
Dockerfile
|
||||||
|
docker-compose.yml
|
||||||
|
src/
|
||||||
|
README.md
|
||||||
|
```
|
||||||
|
|
||||||
|
Client integrations:
|
||||||
|
|
||||||
|
- Android: `Xime/app/src/main/java/com/kingzcheung/xime/settings`, `service`, `clipboard`, and `ui`.
|
||||||
|
- Windows: `winxime/crates/winxime-server` for clipboard watching, WebSocket sync, and local clipboard writes.
|
||||||
|
- Shared protocol docs: `CLIPBOARD_SYNC_PROTOCOL.md` or `sync-server/docs/protocol.md`.
|
||||||
|
|
||||||
|
## 3. Core Product Rules
|
||||||
|
|
||||||
|
- A sync chain is a group of devices allowed to exchange clipboard events.
|
||||||
|
- A sync code authorizes a device to join a chain. It must be random, revocable, and regeneratable.
|
||||||
|
- The server must reject non-HTTPS client relay URLs. For local development, allow explicit debug-only overrides such as `http://localhost`.
|
||||||
|
- Every synced item must be inserted into the local clipboard and local clipboard history where the platform/app supports it.
|
||||||
|
- Android must show the latest remote synced text in the candidate bar. Tapping it should commit the text through the IME.
|
||||||
|
- Sync must be opt-in and pauseable per device.
|
||||||
|
|
||||||
|
## 4. Architecture
|
||||||
|
|
||||||
|
Use HTTPS REST for setup and WSS for live sync:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Android Xime <--- HTTPS/WSS ---> Sync Relay Server <--- HTTPS/WSS ---> WinXime
|
||||||
|
```
|
||||||
|
|
||||||
|
The server is a relay, not an editor. It authenticates devices, tracks sync chains, forwards clipboard events, and keeps short-lived replay data for reconnects.
|
||||||
|
|
||||||
|
Recommended backend stack:
|
||||||
|
|
||||||
|
- Rust with `tokio`, `axum`, `tower`, `serde`, and `sqlx`/SQLite for a small self-hosted binary.
|
||||||
|
- Docker image exposing one port, with TLS handled either by the service or by a reverse proxy such as Caddy/Nginx.
|
||||||
|
- WebSocket heartbeat, reconnect support, and event replay by last acknowledged sequence.
|
||||||
|
|
||||||
|
## 5. Protocol and Data Model
|
||||||
|
|
||||||
|
REST endpoints:
|
||||||
|
|
||||||
|
```text
|
||||||
|
GET /healthz
|
||||||
|
POST /v1/chains
|
||||||
|
POST /v1/chains/join
|
||||||
|
POST /v1/chains/{chainId}/sync-code/rotate
|
||||||
|
GET /v1/ws
|
||||||
|
```
|
||||||
|
|
||||||
|
Minimum tables/entities:
|
||||||
|
|
||||||
|
```text
|
||||||
|
chains(id, code_hash, code_expires_at, created_at)
|
||||||
|
devices(id, chain_id, name, platform, token_hash, last_seen_at)
|
||||||
|
clipboard_events(id, chain_id, source_device_id, seq, content_type, content_hash, encrypted_payload, created_at, expires_at)
|
||||||
|
```
|
||||||
|
|
||||||
|
WebSocket event shape:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"type": "clipboard.publish",
|
||||||
|
"eventId": "uuid",
|
||||||
|
"chainId": "uuid",
|
||||||
|
"sourceDeviceId": "uuid",
|
||||||
|
"sequence": 42,
|
||||||
|
"contentType": "text/plain",
|
||||||
|
"contentHash": "sha256:...",
|
||||||
|
"payload": "base64 encrypted or encoded text",
|
||||||
|
"createdAt": "2026-06-09T00:00:00Z",
|
||||||
|
"ttlSeconds": 86400
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Client requirements:
|
||||||
|
|
||||||
|
- Ignore events from the same `deviceId`.
|
||||||
|
- Cache recent `eventId` and `contentHash` values to prevent duplicate imports.
|
||||||
|
- Suppress the next local clipboard-change callback after writing a remote event to avoid echo loops.
|
||||||
|
- Limit payload size, for example 64 KiB for MVP.
|
||||||
|
|
||||||
|
## 6. Security Requirements
|
||||||
|
|
||||||
|
- Relay URL validation must require `https://`; WebSocket connections must use `wss://`.
|
||||||
|
- Store only token hashes and sync code hashes on the server.
|
||||||
|
- Use TLS in all production deployments.
|
||||||
|
- Prefer end-to-end encryption for clipboard payloads. At minimum, server-side event storage must be short-lived with a configurable TTL.
|
||||||
|
- Sync codes should expire by default, for example after 10 minutes or after first successful join. Provide a manual rotate/revoke action.
|
||||||
|
- Never log raw clipboard content on clients or server.
|
||||||
|
|
||||||
|
## 7. Android Implementation Plan
|
||||||
|
|
||||||
|
1. Add settings fields: enable sync, relay server URL, sync code, device name, connection status, pause/resume, and disconnect.
|
||||||
|
2. Persist config in `SettingsPreferences.kt` or a dedicated sync preferences class.
|
||||||
|
3. Add a `ClipboardSyncClient` responsible for HTTPS join, WSS connection, heartbeats, reconnects, and event acknowledgements.
|
||||||
|
4. Add a clipboard bridge that publishes local text copies and writes remote text via Android `ClipboardManager`.
|
||||||
|
5. Add a local synced-item state source consumed by `CandidateBar.kt` or the relevant keyboard UI layer.
|
||||||
|
6. When remote text arrives, update system clipboard and display it as a candidate. Tapping the candidate commits the text.
|
||||||
|
7. Add unit tests for URL validation, dedupe, echo-loop suppression, and event parsing.
|
||||||
|
|
||||||
|
## 8. Windows Implementation Plan
|
||||||
|
|
||||||
|
1. Add sync configuration to the existing Windows settings/config layer.
|
||||||
|
2. Implement a WebSocket sync client inside `winxime-server`.
|
||||||
|
3. Watch local clipboard changes from the server process and publish text changes.
|
||||||
|
4. Write remote text into the Windows clipboard using the existing server/background process.
|
||||||
|
5. Prevent loops by tagging remote writes and suppressing the resulting local notification.
|
||||||
|
6. Surface connection status in tray/setup UI if practical.
|
||||||
|
7. Validate with `cargo build --quiet`; do not use `unwrap()` or `expect()`.
|
||||||
|
|
||||||
|
## 9. Backend Implementation Plan
|
||||||
|
|
||||||
|
1. Scaffold `sync-server` with health check, config loading, structured logging, and Dockerfile.
|
||||||
|
2. Implement chain creation, sync-code join, device token issuance, and code rotation.
|
||||||
|
3. Implement authenticated WebSocket sessions with heartbeat and reconnect.
|
||||||
|
4. Implement event fan-out to online devices in the same chain.
|
||||||
|
5. Persist recent events for replay after reconnect, bounded by TTL and size limits.
|
||||||
|
6. Add Docker Compose example with a reverse proxy HTTPS configuration.
|
||||||
|
7. Add integration tests for join, auth failure, event fan-out, replay, TTL expiry, and duplicate suppression expectations.
|
||||||
|
|
||||||
|
## 10. Acceptance Criteria
|
||||||
|
|
||||||
|
- A user can deploy the relay with Docker and access it over HTTPS.
|
||||||
|
- Android and Windows settings reject plain `http://` relay URLs outside debug/local mode.
|
||||||
|
- Device A can create or rotate a sync code; Device B can join using that code.
|
||||||
|
- Copying text on Windows updates Android clipboard and shows the text in the Android candidate bar.
|
||||||
|
- Copying text on Android updates the Windows clipboard.
|
||||||
|
- The same event is not re-broadcast indefinitely.
|
||||||
|
- Reconnect after network loss resumes sync without requiring a new sync code.
|
||||||
|
- Raw clipboard content does not appear in logs.
|
||||||
|
|
||||||
|
## 11. Implementation Order for Agents
|
||||||
|
|
||||||
|
1. Protocol agent: finalize event schema, sync-code lifecycle, error codes, and protocol doc.
|
||||||
|
2. Backend agent: implement relay, Docker image, tests, and deployment README.
|
||||||
|
3. Windows agent: implement local clipboard watcher/writer and WSS client.
|
||||||
|
4. Android agent: implement settings, WSS client, clipboard bridge, and candidate bar display.
|
||||||
|
5. Integration agent: run end-to-end tests across one Android device/emulator, one Windows client, and the Docker relay.
|
||||||
|
|
||||||
Reference in New Issue
Block a user