CipherTalk Documentation

repository·main·Indexed 21 days ago

https://github.com/ilovebinglu/ciphertalk

A modern tool for viewing and analyzing WeChat chat records, designed for preserving digital assets and extracting evidence. The documentation covers the ciphertalk-cli (miyu command) for interactive and script-based data access, encryption key management, retrieval evaluation (L1) for semantic vector search, and the ciphertalk-plugin-sdk for developing plugins with data APIs and UI components.

Tokens
37.9K
Snippets
46
Records
224
Agent score
78%

What's inside CipherTalk

  1. Use ct-mcp-copilot as an AI Copilot

    main

    The ct-mcp-copilot skill enables an AI agent to act as a patient investigator using CipherTalk MCP tools. Instead of treating the MCP as a rigid database, the copilot should handle fuzzy, incomplete, or mistaken user clues by starting broad and narrowing down results. It is designed to proactively dig for local data rather than stopping after a single failed query.

    Core Investigation Principles:

    • Start Broad, then Narrow: Use list_contacts and list_sessions as fuzzy entry points.
    • Handle Ambiguity: If multiple candidates exist, compare them using resolve_session.candidates[*].evidence and keep shrinking the set.
    • Don't Give Up: If one query misses, reformulate the clue and try another route (e.g., search globally).
    • Prioritize Structured Data: Always answer from fields like items[].text, hits[].message.text, or items[].contentDesc before mentioning that the host only provided a summary.
  2. Use CSS variables for theming and dark mode

    main

    The host injects theme CSS variables that update in real-time when the user switches themes. All ct-* components automatically adapt to these variables. When writing custom styles, use these variables to maintain consistency:

    • Backgrounds: --bg-primary, --bg-secondary, --bg-tertiary, --bg-hover
    • Text: --text-primary, --text-secondary, --text-tertiary
    • Borders/Accents: --border-color, --accent (HeroUI tokens are also available).

    To support dark mode specifically, the host adds a .dark class to the <html> element. You can target it using .dark .your-class { ... }.

    .my-box {
      background: var(--bg-secondary);
      color: var(--text-primary);
      border: 1px solid var(--border-color);
    }
    .my-accent { color: var(--accent); }
  3. Implement the Settings Store Architecture

    main

    The settings management is refactored from local useState hooks to a centralized settingsStore using zustand.

    Key Rules for Consumers/Developers:

    • Leaf Selectors Only: When subscribing to the store in tab components, always use leaf selectors (e.g., s => s.config.xxx) instead of subscribing to the entire config object (s => s.config). This prevents unnecessary re-renders across the entire settings page when a single field changes.
    • Zustand Pattern: Use the create<T>()(...) syntax for defining stores, following the pattern established in src/stores/themeStore.ts.
    • Persistence: The saveConfig logic should retrieve values from useSettingsStore.getState().config and call commit() to persist changes.
  4. Understand the CipherTalk Plugin Architecture

    main

    CipherTalk uses a browser extension model for its plugin system. Plugins are composed of a manifest.json and pure frontend resources (HTML/JS/CSS) that run inside a sandboxed iframe.

    Key Architectural Principles:

    • Security: Plugins have no Node.js permissions. They are isolated via iframe sandboxing, unique origins (ct-plugin://<plugin-id>/), and CSP. They cannot access fs, child_process, or require.
    • Performance: Plugin JavaScript runs in its own context. A heavy plugin will not freeze the main application or the host's core rendering process.
    • Communication: Plugins interact with the host via a typed RPC mechanism using postMessage through the ciphertalk-plugin-sdk.
    • Lazy Activation: UI elements (menus, tabs, buttons) are rendered declaratively from the manifest.json without executing plugin code. The iframe is only created when the user actually opens the plugin view.
  5. How theme consistency works in HeroUI plugins

    main

    Plugins run in an isolated iframe and cannot share the host's React component instances. Therefore, the HeroUI starter plugin bundles its own copy of HeroUI.

    Theme consistency (including dark mode) is achieved through a handshake process:

    1. Handshake: During connect() (in src/main.tsx), the host injects its calculated CSS variables onto the plugin's documentElement. The host also applies the .dark class and re-injects variables when the theme changes.
    2. Mapping: The plugin's src/styles.css maps HeroUI's semantic colors (e.g., --color-*) to these host-injected variables and binds the dark variant to the .dark class.

    This allows HeroUI components to automatically match the host's theme without the plugin needing explicit theme-switching logic.

  6. When to use get_moments_timeline

    main

    Use the get_moments_timeline tool when a user's request pertains to social feed content, specifically regarding:

    • Moments (朋友圈)
    • Dynamic updates (动态)
    • Likes (点赞)
    • Comments (评论)
    • Share cards (分享卡片)
    • Recent activity from a specific person
    • Activity within a specific time period

    Avoid defaulting to standard chat tools when the intent is clearly focused on Moments content.

  7. How to prevent re-render lag in Settings tabs

    main

    To avoid the performance bottleneck where typing in one setting field causes the entire SettingsPage to re-render, follow these architectural rules:

    1. Avoid subscribing to the whole config object: Never use const config = useSettingsStore(s => s.config). This makes the component re-render on any change to any field.
    2. Use Leaf Selectors: Always subscribe to specific fields: const field = useSettingsStore(s => s.config.fieldName).
    3. Decouple Tabs: Each tab (e.g., AppearanceTab, AISummarySettings) should be a standalone component that pulls its own data from the store via leaf selectors rather than receiving everything via props from a parent SettingsPage.
  8. How DbKey is retrieved on macOS

    main

    On macOS, the 64-bit DbKey is not obtained directly via GetDbKey(). Instead, the process follows this workflow:

    1. The Electron main process calls wxKeyServiceMac.autoGetDbKey().
    2. The system checks for SIP (System Integrity Protection) status.
    3. The process uses AppleScript with administrator privileges to launch the xkey_helper binary.
    4. The xkey_helper is executed with the command: xkey_helper <pid> <timeout_ms> to attach to the WeChat process and wait for database access.
    5. The helper returns the final 64-bit DbKey as a JSON object via stdout, which the main process then parses.
    xkey_helper <pid> [timeout_ms]
  9. Understand the CipherTalk Plugin API surface and permissions

    main

    The SDK provides access to several capability groups. Note: Every capability group requires a corresponding permission declaration in your manifest.json. Permissions must be confirmed by the user when enabled.

    Available Capability Groups:

    • data: Sessions, contacts, and messages.
    • media: Media decryption.
    • stt: Speech-to-text.
    • search: Full-text search.
    • stats: Statistics.
    • export: Data export.
    • sns: Moments/Social features.
    • ai: AI capabilities.
    • ui: UI-related host methods (e.g., api.ui.toast()).
    • storage: Local storage.
    • clipboard: Clipboard access.
    • notify: Notifications.
    • window: Window management.
    • events: Event handling.
    • api.capabilities(): A runtime method to detect which methods the host currently supports for graceful degradation.
  10. Required fields for CipherTalk chat export

    main

    Before initiating an export via the MCP tools, you must ensure the following parameters are defined. Do not attempt to export until all required fields are known:

    • target session
    • time range
    • export format
    • media selections

    Note: The outputDir (output directory) may be omitted only if a configured default export directory is available and writable.

  11. Retrieval Evaluation Metrics

    main

    The evaluation produces the following metrics to assess retrieval quality:

    • recall@k: The proportion of expected evidence fragments covered by the top-$k$ retrieved fragments.
    • MRR (Mean Reciprocal Rank): The average of the reciprocal ranks of the first successful hit (higher values indicate relevant fragments appear earlier in the results).
    • fullyCovered: The count of test cases where recall = 1 (complete coverage of all expected evidence).
  12. Understand plugin rate limits and security model

    main

    Plugins run in a sandboxed iframe with a unique origin. They have no access to Node.js or the file system. All capabilities are provided via host RPC and are subject to the following limits:

    LimitValueDescription
    RPC Frequency50 calls/sec/pluginExceeding this causes an error
    Concurrent Calls2 calls/pluginExceeding this causes an error
    Call TimeoutDefault 10sMedia: 30s, Search: 60s, AI/Export: 120s, Transcription: 180s
    Message Page Size$\le$ 2000 linesForced cursor pagination
    AI Budget20 calls/min/pluginUses user's API quota
    Storage256KB per value / 5MB totalCleared upon uninstallation
    Media URL5-minute expirationBound to plugin issuance; do not persist

    Security Boundaries:

    • CSP prevents all external connections if network permission is not granted.
    • Decryption keys, account credentials, and AI API keys are never exposed to the plugin.
    • Plugin crashes or infinite loops only affect the plugin's own iframe.