bot-process-control

安装量: 48
排名: #15406

安装

npx skills add https://github.com/terrylica/cc-skills --skill bot-process-control

Bot Process Control Manage the Gmail Commander bot daemon and scheduled digest via launchd. Mandatory Preflight Step 1: Check Current Process Status echo "=== Gmail Commander Processes ===" pgrep -fl "gmail-commander" 2

/dev/null || echo "No processes found" echo "" echo "=== launchd Status ===" launchctl list | grep gmail-commander 2

/dev/null || echo "No launchd jobs" echo "" echo "=== PID Files ===" cat /tmp/gmail-commander-bot.pid 2

/dev/null && echo " (bot)" || echo "No bot PID file" cat /tmp/gmail-digest.pid 2

/dev/null && echo " (digest)" || echo "No digest PID file" Two Services Service Type Trigger PID File Bot Daemon KeepAlive Always-on (grammY polling) /tmp/gmail-commander-bot.pid Digest StartInterval Every 6 hours (21600s) /tmp/gmail-digest.pid launchd Plist Templates Bot Daemon — com.terryli.gmail-commander-bot.plist

<! DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"

< plist version = " 1.0 "

< dict

< key

Label </ key

< string

com.terryli.gmail-commander-bot </ string

< key

ProgramArguments </ key

< array

< string

{{HOME}}/own/amonic/bin/gmail-commander-bot </ string

</ array

< key

RunAtLoad </ key

< true /> < key

KeepAlive </ key

< dict

< key

NetworkState </ key

< true /> </ dict

< key

StandardOutPath </ key

< string

{{HOME}}/.local/state/launchd-logs/gmail-commander-bot/stdout.log </ string

< key

StandardErrorPath </ key

< string

{{HOME}}/.local/state/launchd-logs/gmail-commander-bot/stderr.log </ string

< key

EnvironmentVariables </ key

< dict

< key

PATH </ key

< string

{{HOME}}/.local/share/mise/shims:/usr/local/bin:/usr/bin:/bin </ string

</ dict

< key

ThrottleInterval </ key

< integer

10 </ integer

</ dict

</ plist

Scheduled Digest — com.terryli.gmail-commander-digest.plist

<! DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"

< plist version = " 1.0 "

< dict

< key

Label </ key

< string

com.terryli.gmail-commander-digest </ string

< key

ProgramArguments </ key

< array

< string

{{HOME}}/own/amonic/bin/gmail-commander-digest </ string

</ array

< key

StartInterval </ key

< integer

21600 </ integer

< key

StandardOutPath </ key

< string

{{HOME}}/.local/state/launchd-logs/gmail-commander-digest/stdout.log </ string

< key

StandardErrorPath </ key

< string

{{HOME}}/.local/state/launchd-logs/gmail-commander-digest/stderr.log </ string

< key

EnvironmentVariables </ key

< dict

< key

PATH </ key

< string

{{HOME}}/.local/share/mise/shims:/usr/local/bin:/usr/bin:/bin </ string

</ dict

</ dict

</ plist

Quick Operations Start Bot launchctl load ~/Library/LaunchAgents/com.terryli.gmail-commander-bot.plist Stop Bot launchctl unload ~/Library/LaunchAgents/com.terryli.gmail-commander-bot.plist Restart Bot launchctl unload ~/Library/LaunchAgents/com.terryli.gmail-commander-bot.plist launchctl load ~/Library/LaunchAgents/com.terryli.gmail-commander-bot.plist Force Kill (Emergency) pkill -f "gmail-commander.*bot.ts" rm -f /tmp/gmail-commander-bot.pid View Logs

Recent bot output (centralized launchd logs)

tail -50 ~/.local/state/launchd-logs/gmail-commander-bot/stderr.log

Recent digest output

tail -50 ~/.local/state/launchd-logs/gmail-commander-digest/stderr.log

Audit log (NDJSON, app-managed)

cat $PROJECT_DIR /logs/audit/ $( date +%Y-%m-%d ) .ndjson | jq .

OAuth token refresher log

tail
-20
~/.local/state/launchd-logs/gmail-oauth-refresher/stderr.log
System Resources (Expected)
Memory
~20-30 MB RSS (Bun runtime + grammY)
CPU
Negligible (idle polling, wakes on message)
Network
Minimal (single long-poll connection to Telegram API)
Disk
~1 MB/day audit logs (14-day rotation)
Telegram Commands
Command
Description
/inbox
Show recent inbox emails
/search
Search emails (Gmail query syntax)
/read
Read email by ID
/compose
Compose a new email
/reply
Reply to an email
/abort
Cancel current compose/reply action
/drafts
List draft emails
/digest
Run email digest now
/status
Bot status and stats
/help
Show all commands
Note
:
/abort
cancels any in-progress compose or reply session. Works at any step in the flow.
OAuth Token Management
Two-Layer Token Architecture
Browser Auth (one-time, interactive)
→ Google issues: access_token (1h TTL) + refresh_token (7d TTL in Testing mode)
→ Saved to: ~/.claude/tools/gmail-tokens/.json
Silent Refresh (automatic, no browser)
→ Uses refresh_token to get new access_token
→ Fails with invalid_grant when refresh_token itself expires
Hourly Token Refresher (launchd)
A compiled Swift binary runs hourly to proactively refresh the access token:
File
Path
Source
~/.claude/automation/gmail-token-refresher/main.swift
Binary
~/.claude/automation/gmail-token-refresher/gmail-oauth-token-hourly-refresher
Plist
~/Library/LaunchAgents/com.terryli.gmail-oauth-token-hourly-refresher.plist
Log
$PROJECT_DIR/logs/token-refresher.log
Why hourly
Access tokens expire every 1 hour. Refreshing hourly keeps the token perpetually valid. Frequent refresh also increases the chance Google issues a new refresh_token , resetting its 7-day clock. Verify it's running : launchctl list | grep gmail-oauth-token tail -5 $PROJECT_DIR /logs/token-refresher.log Credentials source : GMAIL_OP_UUID item in 1Password Claude Automation vault (fields: client_id , client_secret ). Accessed via service account token — no biometric prompt required. Diagnosing invalid_grant invalid_grant means the refresh token itself expired (not just the access token):

Symptom in audit log:

cat $PROJECT_DIR /logs/audit/ $( date +%Y-%m-%d ) .ndjson | jq 'select(.event == "gmail.error")'

→ "Token expired, refreshing...\nError: invalid_grant\n"

Check token file age:

ls -la ~/.claude/tools/gmail-tokens/ < GMAIL_OP_UUID

.json Fix :

1. Delete expired token

rm ~/.claude/tools/gmail-tokens/ < GMAIL_OP_UUID

.json

2. Trigger browser re-auth (opens Google consent page)

source $PROJECT_DIR /.env.launchd $PLUGIN_DIR /scripts/gmail-cli/gmail list -n 1

3. Restart bot

launchctl unload ~/Library/LaunchAgents/com.terryli.gmail-commander-bot.plist
launchctl load ~/Library/LaunchAgents/com.terryli.gmail-commander-bot.plist
Root cause
Google OAuth apps in Testing mode issue refresh tokens with 7-day TTL. Permanent fix: publish the Google Cloud OAuth app (Google Cloud Console → OAuth consent screen → Publish app). Diagnosing Stale PID Lock If the bot exits uncleanly, the PID file may block restart:

Symptom: launchctl shows bot loaded but PID is dead

kill -0 $( cat /tmp/gmail-commander-bot.pid ) 2

&1

→ "No such process"

Fix: restart via launchctl (acquireLock handles stale PIDs automatically)

launchctl unload ~/Library/LaunchAgents/com.terryli.gmail-commander-bot.plist launchctl load ~/Library/LaunchAgents/com.terryli.gmail-commander-bot.plist Post-Change Checklist YAML frontmatter valid (no colons in description) Trigger keywords current Path patterns use $HOME not hardcoded paths launchd plist templates match actual launcher scripts OAuth token refresher launchd service loaded and running

返回排行榜