# fyaic/wecom-auth-keeper architecture

> Architecture diagram of the GitHub repository fyaic/wecom-auth-keeper, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-29). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/fyaic/wecom-auth-keeper
- Repository: https://github.com/fyaic/wecom-auth-keeper

## Overview

wecom-auth-keeper is a macOS operations tool for detecting expired WeCom document permissions and restoring them through the signed-in desktop app. Its main cycle probes document read/write access, invokes renewal when probes report expiry (or recovery is pending), probes again, then records and optionally notifies the outcome. A separate renewal command supports inspection, expired-permission recovery, and experimental pre-renewal; the README also documents configurable capability-row selection and optional authorization-link delivery and monitor coordination. Source excerpts are partial, so unshown renewal internals are represented only where documented or evidenced.

Main entry points: [`keepalive.py`](https://github.com/fyaic/wecom-auth-keeper/blob/main/keepalive.py) (Keepalive cycle), [`renew.py`](https://github.com/fyaic/wecom-auth-keeper/blob/main/renew.py) (Renewal command), [`probe.py`](https://github.com/fyaic/wecom-auth-keeper/blob/main/probe.py) (Probe command), [`keeper_ax.py`](https://github.com/fyaic/wecom-auth-keeper/blob/main/keeper_ax.py) (Native AX adapter)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_probe["Capability probes"]
  node_probe_cli["Probe command<br/>[probe.py]"]
  node_read_probe["Read probe<br/>[probe.py]"]
  node_write_probe["Write probe<br/>[probe.py]"]
end

subgraph group_cycle["Keepalive and state"]
  node_keepalive["Keepalive cycle<br/>[keepalive.py]"]
  node_shared_runtime["Config and locks<br/>[keeper_common.py]"]
  node_state_store[("Local state and logs<br/>[keeper_common.py]")]
  node_notice_receipt[("Notice receipt<br/>[keepalive.py]")]
end

subgraph group_renew["Permission recovery"]
  node_renew_cli["Renewal command<br/>[renew.py]"]
  node_permission_page["Permission page<br/>[renew.py]"]
  node_identity_check["Bot identity check<br/>[renew.py]"]
  node_permission_status["Permission status<br/>[renew.py]"]
  node_permission_actions["Renew / pre-renew<br/>[renew.py]"]
  node_ax_adapter["Native AX adapter<br/>[keeper_ax.py]"]
  node_recovery_journal[("Recovery journal<br/>[renew.py]")]
end

subgraph group_integrations["External systems"]
  node_wecom_cli["wecom-cli"]
  node_wecom_api{{"WeCom APIs"}}
  node_wecom_desktop["WeCom desktop"]
  node_bridge{{"Optional bridge"}}
end

node_operator(("Operator"))
node_scheduler(("launchd scheduler"))

node_operator -->|"runs cycle"| node_keepalive
node_scheduler -.->|"runs hourly"| node_keepalive
node_operator -->|"runs probe"| node_probe_cli
node_operator -->|"runs recovery"| node_renew_cli
node_keepalive -->|"loads config"| node_shared_runtime
node_keepalive -->|"locks and logs"| node_state_store
node_keepalive -->|"calls probes"| node_probe_cli
node_probe_cli -->|"runs read"| node_read_probe
node_probe_cli -->|"runs write"| node_write_probe
node_read_probe -->|"invokes"| node_wecom_cli
node_write_probe -->|"invokes"| node_wecom_cli
node_wecom_cli -->|"calls"| node_wecom_api
node_keepalive -->|"runs on expiry"| node_renew_cli
node_renew_cli -->|"loads config and locks"| node_shared_runtime
node_renew_cli -->|"opens or reuses"| node_permission_page
node_permission_page -->|"inspected through"| node_ax_adapter
node_ax_adapter -->|"controls and reads"| node_wecom_desktop
node_renew_cli -->|"validates target"| node_identity_check
node_renew_cli -->|"reads rows"| node_permission_status
node_renew_cli -->|"dispatches actions"| node_permission_actions
node_renew_cli -->|"recovers pending action"| node_recovery_journal
node_permission_actions -->|"persists before revoke"| node_recovery_journal
node_keepalive -->|"checks pending state"| node_state_store
node_keepalive -.->|"sends optional notice"| node_bridge
node_keepalive -->|"deduplicates notices"| node_notice_receipt
node_renew_cli -.->|"optional link and monitor"| node_bridge

click node_keepalive "https://github.com/fyaic/wecom-auth-keeper/blob/main/keepalive.py"
click node_probe_cli "https://github.com/fyaic/wecom-auth-keeper/blob/main/probe.py"
click node_read_probe "https://github.com/fyaic/wecom-auth-keeper/blob/main/probe.py"
click node_write_probe "https://github.com/fyaic/wecom-auth-keeper/blob/main/probe.py"
click node_renew_cli "https://github.com/fyaic/wecom-auth-keeper/blob/main/renew.py"
click node_permission_page "https://github.com/fyaic/wecom-auth-keeper/blob/main/renew.py"
click node_identity_check "https://github.com/fyaic/wecom-auth-keeper/blob/main/renew.py"
click node_permission_status "https://github.com/fyaic/wecom-auth-keeper/blob/main/renew.py"
click node_permission_actions "https://github.com/fyaic/wecom-auth-keeper/blob/main/renew.py"
click node_ax_adapter "https://github.com/fyaic/wecom-auth-keeper/blob/main/keeper_ax.py"
click node_shared_runtime "https://github.com/fyaic/wecom-auth-keeper/blob/main/keeper_common.py"
click node_state_store "https://github.com/fyaic/wecom-auth-keeper/blob/main/keeper_common.py"
click node_recovery_journal "https://github.com/fyaic/wecom-auth-keeper/blob/main/renew.py"
click node_notice_receipt "https://github.com/fyaic/wecom-auth-keeper/blob/main/keepalive.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_probe_cli,node_read_probe,node_write_probe toneBlue
class node_keepalive,node_shared_runtime,node_state_store,node_notice_receipt toneAmber
class node_renew_cli,node_permission_page,node_identity_check,node_permission_status,node_permission_actions,node_ax_adapter,node_recovery_journal toneMint
class node_wecom_cli,node_wecom_api,node_wecom_desktop,node_bridge,node_scheduler toneRose
class node_operator toneIndigo
```

## Components

### Capability probes

- [Probe command](https://github.com/fyaic/wecom-auth-keeper/blob/main/probe.py): `probe.py`
- [Read probe](https://github.com/fyaic/wecom-auth-keeper/blob/main/probe.py): `probe.py`
- [Write probe](https://github.com/fyaic/wecom-auth-keeper/blob/main/probe.py): `probe.py`

### Keepalive and state

- [Keepalive cycle](https://github.com/fyaic/wecom-auth-keeper/blob/main/keepalive.py): `keepalive.py`
- [Config and locks](https://github.com/fyaic/wecom-auth-keeper/blob/main/keeper_common.py): `keeper_common.py`
- [Local state and logs](https://github.com/fyaic/wecom-auth-keeper/blob/main/keeper_common.py): `keeper_common.py`
- [Notice receipt](https://github.com/fyaic/wecom-auth-keeper/blob/main/keepalive.py): `keepalive.py`

### Permission recovery

- [Renewal command](https://github.com/fyaic/wecom-auth-keeper/blob/main/renew.py): `renew.py`
- [Permission page](https://github.com/fyaic/wecom-auth-keeper/blob/main/renew.py): `renew.py`
- [Bot identity check](https://github.com/fyaic/wecom-auth-keeper/blob/main/renew.py): `renew.py`
- [Permission status](https://github.com/fyaic/wecom-auth-keeper/blob/main/renew.py): `renew.py`
- [Renew / pre-renew](https://github.com/fyaic/wecom-auth-keeper/blob/main/renew.py): `renew.py`
- [Native AX adapter](https://github.com/fyaic/wecom-auth-keeper/blob/main/keeper_ax.py): `keeper_ax.py`
- [Recovery journal](https://github.com/fyaic/wecom-auth-keeper/blob/main/renew.py): `renew.py`

### External systems

- **wecom-cli**
- **WeCom APIs**
- **WeCom desktop**
- **Optional bridge**

### Other components

- **Operator**
- **launchd scheduler**

## Connections

- Operator → Keepalive cycle: runs cycle
- launchd scheduler → Keepalive cycle: runs hourly
- Operator → Probe command: runs probe
- Operator → Renewal command: runs recovery
- Keepalive cycle → Config and locks: loads config
- Keepalive cycle → Local state and logs: locks and logs
- Keepalive cycle → Probe command: calls probes
- Probe command → Read probe: runs read
- Probe command → Write probe: runs write
- Read probe → wecom-cli: invokes
- Write probe → wecom-cli: invokes
- wecom-cli → WeCom APIs: calls
- Keepalive cycle → Renewal command: runs on expiry
- Renewal command → Config and locks: loads config and locks
- Renewal command → Permission page: opens or reuses
- Permission page → Native AX adapter: inspected through
- Native AX adapter → WeCom desktop: controls and reads
- Renewal command → Bot identity check: validates target
- Renewal command → Permission status: reads rows
- Renewal command → Renew / pre-renew: dispatches actions
- Renewal command → Recovery journal: recovers pending action
- Renew / pre-renew → Recovery journal: persists before revoke
- Keepalive cycle → Local state and logs: checks pending state
- Keepalive cycle → Optional bridge: sends optional notice
- Keepalive cycle → Notice receipt: deduplicates notices
- Renewal command → Optional bridge: optional link and monitor
