ahhhh! there's a ghost! and it's in my mac mini!!! this ghost helps schedule events via slack bot and google calendar integrations
python3 -m venv venv
source venv/bin/activatepip install -e ".[dev]"The scheduler needs OAuth credentials to access your Google Calendar. All secrets are stored in your system keyring (macOS Keychain) — never as plain-text files or environment variables.
- Go to the Google Cloud Console
- Create a new project (or select an existing one)
- Enable the Google Calendar API (APIs & Services → Library)
- Configure the OAuth consent screen (APIs & Services → OAuth consent screen)
- Set the user type to External
- Add yourself as a test user under Audience
- Create OAuth 2.0 credentials (APIs & Services → Credentials → Create Credentials → OAuth client ID)
- Application type: Desktop app
- Add the scope:
https://www.googleapis.com/auth/calendar
- Download the JSON file, then import it into your system keyring:
python -m ghostinthemini.scheduler --import-credentials path/to/credentials.json- Delete the downloaded JSON file — it's now safely stored in your keyring
On first run, a browser window will open asking you to authorize access. After you approve, the OAuth token is saved to your system keyring and reused automatically.
Migrating from an older version? If you already have
credentials.jsonandtoken.jsonfiles, import them both:python -m ghostinthemini.scheduler --import-credentials credentials.json python -m ghostinthemini.scheduler --import-token token.jsonThen delete both files — they're now in your keyring.
The ghost runs on a local Qwen model via Ollama. Make sure Ollama is running with the model pulled before using the scheduler.
The bot connects via Socket Mode — no public URL or inbound ports on your Mac Mini. Only allowlisted Slack user IDs can trigger scheduling.
- Go to api.slack.com/apps → Create New App → From scratch
- Name it whatever you like and pick your workspace
- In the sidebar, go to Socket Mode and toggle it on
- You'll be prompted to generate an app-level token — give it a name (e.g. "ghostinthemini") and select the
connections:writescope - Copy the generated
xapp-…token
- In the sidebar, go to OAuth & Permissions
- Scroll down to Bot Token Scopes and click Add an OAuth Scope for each of:
chat:writeapp_mentions:readim:historyim:read
- In the sidebar, go to Event Subscriptions and toggle it on
- Under Subscribe to bot events, click Add Bot User Event and add:
message.im— so the bot receives your direct messagesapp_mention— so the bot responds to @-mentions in channels
- Click Save Changes
- In the sidebar, go to App Home
- Scroll to Show Tabs and check Allow users to send Slash commands and messages from the messages tab
- In the sidebar, go to Install App and click Install to Workspace
- Authorize on the consent screen
- Copy the Bot User OAuth Token (
xoxb-…) shown after installation
Note: If you add new scopes or event subscriptions later, Slack will ask you to reinstall the app for them to take effect.
# App-level token (xapp-…) — from step 5
python -m ghostinthemini.slack_bot --store slack_app_token xapp-YOUR-TOKEN
# Bot token (xoxb-…) — from step 15
python -m ghostinthemini.slack_bot --store slack_bot_token xoxb-YOUR-TOKENOnly Slack user IDs on the allowlist can interact with the bot — messages from anyone else are silently dropped.
To find your Slack user ID:
- Open Slack
- Click your profile picture (bottom-left on desktop, top-right on mobile)
- Click Profile
- Click the three dots (...) menu next to "Edit Profile" / "Set Status"
- Click Copy member ID
Your member ID will look something like U07AB12CDEF — it is not your display name or username.
Then store it:
python -m ghostinthemini.slack_bot --allow-users U07AB12CDEFTo allow multiple users, pass a comma-separated list:
python -m ghostinthemini.slack_bot --allow-users U07AB12CDEF,U04XY98GHIJSecurity: All tokens and the allowlist live in your system keyring (macOS Keychain) — never in files or environment variables.
# Pulse check — verify the ghost is awake
python -m ghostinthemini.main
# Schedule a task via the CLI
python -m ghostinthemini.scheduler "2 hour deep work session"
# Start the Slack bot (Socket Mode, runs in foreground)
python -m ghostinthemini.slack_botOnce the Slack bot is running, DM it from your phone or desktop:
"Schedule a 30 minute standup at 10am on Friday"
The ghost will check your calendar, find the best slot, and create the event.
pytest