Replaces the painful "register your own OAuth app, paste client_id +
client_secret" flow with click-Authorize-and-done. Two completion
paths:
PKCE (no broker, no secrets)
- Used for providers that support OAuth 2.1 PKCE: Linear today;
Atlassian / Microsoft / Google / Twitter / Discord drop in once each
is registered.
- Local hub generates code_verifier, sends sha256 challenge to the
provider, exchanges code + verifier on the callback. No secret in
the binary.
Broker-mediated (autoMate Cloud or self-hosted)
- For providers that still require a confidential client at the token
endpoint: GitHub, Notion, Slack, 飞书, 钉钉.
- Hosted broker (cloud/oauth_broker/) holds client_secret per
provider; local hub never sees it. Flow:
local → broker /start → provider → broker /callback (exchanges
code for token, stashes by flow_id) → user-browser bounce back to
local with flow_id → local fetches token via broker /result
(single-use, deleted on read).
- Default broker URL is https://broker.automate.cloud; override with
AUTOMATE_OAUTH_BROKER_URL for self-hosted.
- Tokens live in the broker's memory only during the ~30s in-flight
window; flow_id is the only secret in transit (HTTPS).
Tools tab UI
- Each card has ONE "Connect" button.
- OAuth modal: a single big "Authorize with X" button. Click opens a
popup at the provider's consent page; on success the callback page
posts a message to the opener and self-closes; the modal updates to
✓ Connected without a refresh.
- API-key path: a single big deep-link button to the EXACT token
page (with scopes pre-selected for GitHub etc.) + one paste field.
- Removed: client_id + client_secret inputs, "Use OAuth instead
(advanced)" toggle, the /api/integrations/<id>/oauth-app endpoint.
Standalone broker (cloud/oauth_broker/)
- Tiny FastAPI app, deployable as a Docker image (Dockerfile +
requirements.txt included) or `pip install -r requirements.txt &
uvicorn main:app`.
- Reads OAUTH_<PROVIDER>_CLIENT_ID/SECRET from env, plus
PUBLIC_BASE_URL.
- Exposes /oauth/<p>/start, /oauth/<p>/callback, /oauth/result, /health.
- Per-provider OAuth scopes are hardcoded in main.py:SPECS.
Docs
- docs/oauth-broker.md walks maintainers/self-hosters through the
deployment + per-provider OAuth app registration.
When the broker is unreachable the OAuth modal degrades gracefully:
clear error message + "Or paste an API key instead" expandable that
deep-links to the provider's PAT page. OAuth and API-key flows produce
identical end-state in the connections table.
https://claude.ai/code/session_019uRjfdjRsVwG9iNbc5gJmN
The Connect AI tab was a dead-end for non-MCP clients (the user tried
several platforms and none of them worked end-to-end without a manual
relay). Removing it entirely:
- Delete the Connect AI section, the per-client picker, and the
/api/connect snippet endpoint
- Drop aiClient / aiClients / pickAiClient / aiClientMode / aiClientWhere
state, plus copySnippet / copiedKey / loadConnectInfo / connectInfo
- Strip the `connect` tab from desktop tabs and mobile More menu
- Reroute every "Get the snippet" / "Use from a different AI" entry
point to the Bots tab
Bots tab is now a step-by-step OpenClaw-WeChat setup guide:
1. Install OpenClaw + the @canghe/openclaw-wechat plugin
2. Drop autoMate's bundle-mcp config block (URL + bearer token
pre-filled) into ~/.openclaw/openclaw.json5
3. Configure channels.wechat.* (apiKey / proxyUrl / webhookHost)
4. `openclaw gateway start`, scan the QR with WeChat
The same path covers Telegram / Slack / Discord etc. — only step 3
changes per channel. Existing direct-webhook bots (telegram /
wechat_oa / wecom) are kept under "Direct platform webhooks
(advanced / legacy)" for users who can't run OpenClaw.
Renames installInfo state's connectCopied → installCopied and
copyConnectInstructions → copyInstallText to match the new naming.
References https://github.com/freestylefly/openclaw-wechat for the
upstream WeChat plugin setup.
https://claude.ai/code/session_019uRjfdjRsVwG9iNbc5gJmN
Home tab: remove the four-channel grid (Telegram / 微信公众号 / WeCom /
个人微信) — Bots tab is still in the bottom nav. The home page now only
shows three primary entry points: chat, Connect AI, quick actions.
Connect AI tab: surface the "Copy install text (all clients)" button as
the primary CTA at the top of the tab — this is the per-client markdown
guide users can hand to any AI to set itself up. The per-client picker
moves below as a secondary path.
Per-client picker: split "Kimi K2 / Kimi Code" into two distinct cards
since Kimi Code (the CLI) doesn't load MCP servers. Add Cline as its
own card. Each card now declares its actual transport and a "where to
paste" hint pointing at the specific config file or UI surface.
Drop the Android APK build entirely: PWA covers Android the same way it
covers iOS. Removes the android/ directory, the android job in
.github/workflows/build.yml, isAndroid/downloadApk frontend code, and
the platform pattern in system.py update detection. Updates README,
README_CN, docs/mobile.md, docs/sync.md.
Bug fix: loadBridge() and loadConnectInfo() were both writing to a
single connectInfo Alpine property — they have different shapes
(markdown/url/token vs base_url/modes) and clobbered each other under
Promise.all. Renames the bridge-loaded one to installInfo.
https://claude.ai/code/session_019uRjfdjRsVwG9iNbc5gJmN
Both READMEs were stuck at v4.2 status — pre-Coze-retrieval, pre-audio,
pre-channels, pre-MCP-HTTP. Reframes the pitch around the v4.5.7
positioning:
- autoMate is a tool source other AI clients (OpenClaw / Claude Desktop /
Cursor / Cline) call into via MCP-over-HTTP
- standalone web chat is the secondary mode, not the primary
- Settings has a one-click "Copy install text" that's both human-
readable and AI-pasteable
- IM channels are OpenClaw's job (it has the official Tencent WeChat
plugin); autoMate plugs in as its tool source
- new feature surface: search.find (FTS5), audio.transcribe (Pro),
configurable storage path, in-app auto-update
Diagram updated to show OpenClaw at the top of the client list and
search.find in the data column. Status section now reads v4.5.7.
Removed the four-modes table (MCP / HTTP / Bridge / OpenAPI) since
MCP-over-HTTP supersedes the bridge/HTTP modes for any modern client.
The legacy /api/channels/inbox is mentioned in docs/channels.md for
n8n / custom scripts but no longer highlighted as a top-level path.
automate/bots/ deprecation noted in both languages.
Architectural pivot, prompted by user feedback. Previous design (v4.5.6)
treated autoMate as an interceptor: external gateways forwarded all IM
messages to autoMate's inbox, autoMate ran the agent, autoMate replied.
That conflated channel handling with reasoning, and pitted autoMate
against agents that were already doing reasoning (OpenClaw, Claude
Desktop, Cursor, ...).
The right model is: those clients are agents; autoMate is a tool
*they* call when they need the user's notes / files / memory /
schedule. Each agent stays the brain on its own platform; autoMate
is the personal-data spine they all share.
Backend:
- automate/server/mcp_bridge.py: split into _build_mcp() core +
serve_stdio() (legacy, for Claude Desktop's stdio path) and
build_http_app() returning the streamable_http_app + session
manager. streamable_http_path="/" so mounting at /mcp gives the
user-facing path /mcp/ instead of /mcp/mcp.
- automate/server/app.py: mount the MCP app at /mcp with a Bearer
auth wrapper (_BearerProtect) that reuses the channels bridge
token. Bare /mcp (no slash) returns a 307 to /mcp/. Lifespan
context manager runs the MCP session_manager. mcp[cli] promoted
from optional to required dep so this works out of the box.
- automate/server/api/channels.py: new GET /api/channels/connect-
instructions endpoint. Generates a 4-5KB markdown blob with the
hub's URL and token already substituted in, with sections for
OpenClaw / Claude Desktop / Cursor / Cline / generic MCP /
non-MCP gateways / security. Designed so the user can ALSO paste
the entire blob into another AI ("Cursor, set up autoMate for
me") — leading paragraph addresses an AI reader directly.
Frontend:
- Settings → "Connect to AI clients": single big "Copy install text"
button. <details> below shows MCP URL + token + regenerate.
- The legacy /api/channels/inbox URL section moved into a
collapsible <details> further down (kept for non-MCP gateways).
- copyConnectInstructions() prefetches the markdown at refresh
time so the click is instant. Falls back to a notice modal if
clipboard access is blocked.
Verified end-to-end in a smoke test:
- Mount auth: 401 without Bearer / 401 with bad token.
- Initialize: returns serverInfo {name: "autoMate"}.
- tools/list returns 42 tools (automate + search.find +
notes.* + files.* + reminders.* + memory.* + audio.transcribe +
shell + browser + ...).
Docs:
- docs/channels.md rewritten. Documents the two modes (autoMate as
tool inside other clients vs. autoMate's own web chat). Marks
v4.5.6 inbox endpoint as kept-for-non-MCP-gateways but no longer
the highlighted path. /api/channels/inbox itself unchanged.
Bumps to 4.5.7; Android versionCode 17.
Pivot from "build our own IM bots" to "expose a tiny inbox HTTP
endpoint and let an external gateway (OpenClaw) handle the platform
protocols". Architectural decision recorded in docs/channels.md.
Why: reimplementing WeChat/WhatsApp/Telegram is a full-time team's
job. OpenClaw already does it well, and its WeChat plugin is
maintained by Tencent against 微信个人助手 (the official WeChat AI
assistant channel) — no account-takeover, no ban risk. autoMate's
job is files/notes/agent reasoning; let OpenClaw handle the wire.
Backend:
- automate/channels.py:
- get_or_create_token / regenerate_token / verify_token — Bearer
auth, stored in the existing settings KV table, secrets.token_urlsafe.
- InboundMessage / Reply dataclasses.
- process_inbound() — frames the message with a "[from <user> on
<channel>]" context line so the LLM knows it's on chat (terse,
non-Markdown-heavy) and which user it's talking to (memory key).
Calls AgentLoop.run() with source="channel:<chan>:<user>" so
runs are searchable by who said what on which platform.
- automate/server/api/channels.py:
- POST /api/channels/inbox — Bearer-auth'd, runs agent, returns
{text, run_id, ms}. 401 missing/invalid token, 400 empty text,
503 with friendly message on agent failure (instead of 500 — so
the gateway can render something useful).
- GET /api/channels/bridge — returns the inbox URL path + token
so the SPA can show them for copy-paste.
- POST /api/channels/bridge/regenerate — rotate token (with
explicit confirm dialog in UI; existing gateways will break).
Frontend:
- Settings → new "Channels" section above Storage. Shows the full
inbox URL (anchored to hubBase || location.origin), masked token
with Show/Hide, Copy buttons for both, regenerate button with
red warning.
- Loaded as part of refreshAll(); silently noops in local-only mode
(no hub = no token to display).
Docs:
- docs/channels.md — architecture diagram, full bridge protocol
spec (POST shape + status codes), step-by-step OpenClaw setup
including the official Tencent CLI command, examples for n8n /
custom scripts / iOS Shortcuts. Marks automate/bots/ as frozen
(no removal in v4.5.x — old installs keep working).
Smoke test passed: 401 without token / 401 with bad token / 400
on empty text / 503 (not 500) when no LLM provider.
NOT in this release (v4.5.7 candidates):
- Outbound attachments (text-only for now)
- Async 202-then-callback mode for long agent runs
- "Channels wizard" that runs npx OpenClaw install commands for
the user
Bumps to 4.5.6; Android versionCode 16.
User feedback on v4.5.4:
- "App version" line in Settings stayed blank (...) on local-mode
installs because it read status?.version, which only loads when a
hub is reachable. They couldn't tell which version they had.
- Clicking "Download & install APK" bounced them to the system browser
instead of installing in-app — the user said it "feels weird" to
download in browser then have to manually run the installer.
Two fixes:
1. Bundle version with the SPA
- New automate/frontend/version.js sets window.AUTOMATE_VERSION =
"4.5.5". Loaded before app.js so it's always available.
- app.js currentVersion() prefers status?.version (definitive),
falls back to window.AUTOMATE_VERSION, then "?".
- Settings App-version block now shows "Current: v4.5.5" always.
- Update result UI clearer:
- Same version -> green box "✓ You're already on the latest
version (v4.5.5)."
- Newer available -> amber box "v4.5.6 is available (you have
v4.5.5)." with the install button.
2. Don't bounce .apk to the system browser
- v4.5.1's shouldOverrideUrlLoading caught all http/https links
and routed them to ACTION_VIEW (system browser). The "Download
& install APK" button hit this too, so the in-app
DownloadListener that was supposed to grab the APK never fired.
- MainActivity.kt: shouldOverrideUrlLoading now returns false
early when target path ends with .apk (case-insensitive). That
lets WebView begin the navigation, which lets DownloadListener
fire, which calls downloadAndInstall() -> DownloadManager ->
FileProvider -> system installer.
- Net effect: tap button -> "Downloading update…" toast ->
download notification in shade -> system installer pops
automatically. No browser detour.
- Button copy updated to "Download & install in app" to match.
Bumps to 4.5.5; Android versionCode 15.
User feedback: "auto-update doesn't work, asks for hub. file upload
doesn't work, asks for hub. just delete this hub thing, why doesn't
anything work, just store everything locally."
The frustration is justified. Several features were accidentally
gated behind a hub even though they don't structurally need one. This
fixes the worst offenders so the phone-only experience is honest:
some things work, some need a hub, and the difference is clear.
Update check (no hub):
- checkForUpdates() now hits api.github.com/repos/.../releases/latest
directly from the SPA. The hub fallback is kept for users with a
custom AUTOMATE_UPDATE_URL mirror that requires server-side proxy.
- Same response shape — UI didn't have to change.
- Mirror parameter still works client-side (rewrites GitHub URLs).
Files (no hub):
- local-store.js gains files_meta + files_blob object stores
(IndexedDB schema bumped to v2; migration is "create the new stores").
- createFile/listFiles/getFileBlob/deleteFile/filesUsage methods.
- app.js loadFiles/uploadFiles/deleteFile fork on storageMode and
call localStore in local mode, hub in connected mode.
- Files tab UI: drops the "Files need a hub" empty state. Shows
"Stored on this device (IndexedDB)" when local, with a hint about
connecting a hub for unlimited storage.
- Download button: hub mode → /api/files/{id}/raw URL; local mode →
one-shot blob URL via downloadLocalFile().
- Record button hidden in local mode (transcription is Pro-only and
requires the hub anyway).
Home banner copy:
- Old: "Notes & memory live on this device. Files, reminders and tools
work once you connect to a hub."
- New: "Notes, files, memory, and update checks all work locally — no
hub needed. For AI chat, automation tools, integrations, and bots,
run a copy of autoMate on a computer/server (the 'hub') and paste
its URL in Settings."
Links to openSettingsToHub() so the user lands on the right field.
Also bundles v4.5.3 (in-app notice modal replacing native alert) which
was committed but not yet released. The two ship together.
Bumps to 4.5.4; Android versionCode 14.
User screenshots showed the v4.5.1 "Provider configuration lives on
the hub" alert rendered as Android WebView's native dialog, with the
ugly "网址为'file://'的网页显示" header that looks like a browser
warning. Worse, dismissing it dropped them into Settings at whatever
scroll position the sheet was last at — so they never saw the Hub URL
field they were supposed to fill in.
Two fixes:
1. Replace ALL 8 native alert() calls with a proper in-app modal
(rendered as a centered card with icon, title, body, and CTAs).
Same UX everywhere; nothing branded "file://" anymore.
- Provider wizard pre-flight (the one in the screenshot)
- Audio recording Pro gate
- Microphone denied
- Sync hub-empty / success / failure
- Push permission / setup / test
2. New openSettingsToHub() helper: opens the Settings sheet, scrolls
the Hub URL section into view via scrollIntoView, and flashes an
amber ring around it for 2.4s so the user knows where to look.
The provider wizard's "Open Settings" CTA uses this.
Better copy too — instead of "Provider configuration lives on the
hub", we now explain what a hub IS in plain language: "AI providers
(Kimi, Claude, etc.) run on a 'hub' — a copy of autoMate running on
your computer or server. Your phone talks to it over Wi-Fi."
Bumps to 4.5.3; Android versionCode 13.
Default stays at ~/.automate/files (no migration needed for existing
installs). Users can repoint to an external SSD or shared drive via
Settings → Storage location.
Schema:
- files_meta gains a nullable storage_root column. ALTER runs once on
start for existing dbs (pre-v4.5.2 rows keep storage_root=NULL and
resolve to PATHS.files; new rows record their root explicitly).
Backend:
- automate/files.py: storage_dir(db) reads files.storage_dir from the
KV settings, mkdirs + falls back to PATHS.files on error so a broken
config never bricks uploads. set_storage_dir validates: non-empty,
creatable, is-a-directory, write-probe. store_blob writes to the
current dir + persists storage_root per row. open_blob resolves via
per-row storage_root with PATHS.files fallback for legacy rows.
delete_file's GC uses open_blob() so it cleans up wherever the blob
actually lives.
- automate/server/api/system.py:
- GET /api/system/storage → {current, default, is_default, used_bytes}
- PUT /api/system/storage {path} → validates and persists; 400 with a
real message on a bad path (not 500).
Frontend:
- Settings ⚙ gets a "Storage location" section above "Check for updates".
Shows current path + (default) badge if unconfigured + total used
bytes. Path input pre-fills with the current value so it's edit-not-
retype. Save button POSTs and shows ok/error inline.
- loadStorage() runs in refreshAll() and silently no-ops in local-only
mode.
Bumps to 4.5.2; Android versionCode 12.
User reported: on Android, configuring Kimi (and presumably any other
provider) ends in a cryptic "Failed to fetch", and the "Open the
API-keys page" link doesn't actually go anywhere — it looks like the
app jumps back to the home screen.
Root cause #1 (Failed to fetch): the SPA loaded from
file:///android_asset/index.html. With no hub URL in localStorage,
hubBase() returned "" and fetch("" + "/api/...") resolved to
file:///api/... which throws TypeError "Failed to fetch". All provider
paths go through api() so every LLM config hit the same wall.
Fix:
- frontend/app.js api(): pre-flight when location.protocol === "file:"
and no hub configured, throw a real error pointing at Settings.
Also wrap fetch() in try/catch and turn raw TypeError into a
network-diagnostic message.
- frontend/app.js openWizard(): hard-gate when storageMode === "local"
— pop Settings instead of letting the user paste an API key into
a dialog that physically cannot save it.
Root cause #2 (link doesn't navigate): target="_blank" links inside a
file:// page have two failure modes in WebView. (a) Without
setSupportMultipleWindows, the browser silently drops the click. (b)
With it but no onCreateWindow handler, the click also drops. (c)
Without shouldOverrideUrlLoading, regular links (without _blank) try
to load https://platform.moonshot.cn inside the WebView, which most
sites' CSP rejects, leaving a blank page that looks like "the app
went back to the home screen".
Fix in MainActivity.kt:
- WebSettings.setSupportMultipleWindows(true) +
javaScriptCanOpenWindowsAutomatically = true so target="_blank"
fires onCreateWindow.
- WebChromeClient.onCreateWindow: extract the href from
hitTestResult.extra and launch Intent.ACTION_VIEW (system browser).
- WebViewClient.shouldOverrideUrlLoading: catch http/https/mailto/tel
schemes and route them to the system browser. Stay in-WebView only
for URLs whose host matches the saved hub URL.
Bumps to 4.5.1; Android versionCode 11.
Bundles audio into the same release stream — no separate sprint.
- automate/audio.py: provider abstraction with two adapters
- tencent_asr: best Chinese accuracy, hot-words go in HotwordList
with weight 5; auto-selected when the tencent_asr connection has
secret_id/key set.
- openai_whisper: universal fluency; hot-words injected via the
`prompt` arg which biases Whisper's decoder.
- Custom vocabulary is mined locally via TF-IDF over the user's
notes + recent run results — proper-noun coverage without
sending the corpus to the cloud server. We send only the top-N
terms per call.
- automate/tools/audio.py: `audio.transcribe` tool, `tier="pro"`.
First tool to actually exercise the v4.4 tier gate. Unauthenticated
agents see {"error": "needs_pro_subscription", "message": "..."}
and tell the user to sign in.
- automate/server/api/audio.py:
- POST /api/audio/record: multipart upload, stores blob via the
existing files store, transcribes synchronously, optionally
saves a note. Returns 402 (with a clean detail) if no Pro
session — short-circuits before doing the work.
- GET /api/audio/providers: tells the SPA whether a provider is
actually configured on this device.
- frontend Files tab: red Record / ⏹ Stop button next to + Upload,
with an mm:ss timer. While transcribing we show "Transcribing via
<provider>…"; when done we show the text, latency, hot-words, and
a link to the saved note. Pre-flight check: if not signed in,
pop the Settings sheet immediately rather than letting the user
record 10 minutes and then telling them.
- Android:
- AndroidManifest: RECORD_AUDIO + MODIFY_AUDIO_SETTINGS
- MainActivity: WebChromeClient.onPermissionRequest forwards
RESOURCE_AUDIO_CAPTURE to ActivityCompat.requestPermissions.
onRequestPermissionsResult resolves the deferred PermissionRequest.
Bumps to 4.5.0; Android versionCode 10.
Three additions, each independently testable, all wired through the
existing agent / settings / Android shell.
1. Coze-style hybrid retrieval (SQLite FTS5)
The user's complaint: pure-vector RAG products ("Plot Ode") miss obvious
results; Coze nails the right note. Coze runs BM25 + vector + RRF; the
BM25 half is what catches proper nouns and IDs. SQLite FTS5 ships BM25
for free, no extra deps.
- automate/store/db.py: add notes_fts and files_fts virtual tables with
content-link triggers (INSERT/UPDATE/DELETE keep them in sync).
One-shot _backfill_fts() populates them from existing rows on first
upgrade. FTS5 module is optional in the SQLite build, so failures fall
back to LIKE quietly.
- automate/notes.py + automate/files.py: list_* uses FTS5 when query is
set, prefix-matching each whitespace-separated token. UI search inputs
benefit immediately.
- automate/tools/search.py: new search.find unified tool with structured
filters (kinds, tags, date_after, date_before). BM25-ranked results
across notes and files in one call.
- automate/agent/prompts.py: explicit guidance — when the user asks
"find / search / where is / show me X", call search.find with parsed
criteria; don't list everything and grep manually.
2. Auto-update (Android auto-install, desktop opens browser)
GET /api/system/update_check returns the latest GitHub Release plus
indexed download URLs per platform. Soft-fails (HTTP 200 with
{current, error}) on network errors so the UI never shows a 500.
6-hour cache. AUTOMATE_UPDATE_URL env override; ?mirror= query param
rewrites GitHub URLs through a CN-friendly proxy.
Frontend Settings ⚙ sheet gets a "Check for updates" section. UA-based:
- Android (TWA APK / Chrome): big "Download & install APK" button.
Tapping it navigates to the APK URL → MainActivity's DownloadListener
catches it → DownloadManager fetches to cacheDir/updates/ → on
completion, BroadcastReceiver fires Intent.ACTION_VIEW with
application/vnd.android.package-archive via FileProvider → system
installer pops.
- Desktop / iOS / web: "Open release page" link.
A collapsed "CN-friendly mirror" sub-control lets the user paste a
ghproxy.com-style host that rewrites the asset URLs without changing
the metadata source.
Android changes:
- AndroidManifest.xml: add REQUEST_INSTALL_PACKAGES + a FileProvider
with authority "${applicationId}.fileprovider"
- res/xml/provider_paths.xml: cache-path "updates"
- MainActivity.kt: setDownloadListener, downloadAndInstall(),
registered BroadcastReceiver, FileProvider.getUriForFile
3. Login hook + paid-tier decoration (no server enforcement yet)
Modeled on SiYuan: open client, closed cloud server. The server itself
is a separate (closed-source) project that doesn't exist yet. This PR
ships the client side so v4.5+ paid features can plug in without
re-architecting later.
- automate/auth.py: get_session/login/logout/me. Session token stored
in the existing connections table under id="automate_cloud", Fernet-
encrypted via Vault. Cloud base URL comes from AUTOMATE_CLOUD_URL.
When unset, all paths return cleanly: "Cloud sync coming soon", no
network call attempted.
- automate/server/api/auth.py: /api/auth/{me,login,logout} proxying
to the configured cloud server.
- automate/tools/registry.py: Tool.tier field ("free" | "pro").
Default "free"; no current tools are flagged "pro" — the field is
reserved for v4.5 (audio transcription).
- automate/agent/loop.py: before dispatch, if a tool's tier is "pro"
and there's no session, return a clean
{"error": "needs_pro_subscription", "message": "..."} for the LLM
to relay. No exception, no scary 500.
- frontend Settings: an "autoMate Cloud" section. Configurable state:
cloud_configured + logged_in. Coming-soon copy when unset; email/
password form when configured but not logged in; sign-out when logged
in. Tier badge shown next to email.
4. docs/cloud.md
Spells out the SiYuan-style moat strategy: brand + ops + free quota +
genuinely-cloud-only paid features (transcription, public-content
extraction). Documents the cloud server contract so anyone can fork
the client + run their own backend if they want.
Bumps version to 4.4.0; Android versionCode 9.
Audio recording + transcription deferred to v4.5 — see plan.
Strategic pivot: autoMate's built-in agent IS the primary chat experience.
Messaging bots become entry points into that same agent. Power-user
"plug autoMate into your other AI" flow stays available via the existing
Connect AI tab — just demoted, not deleted.
Backend: bot framework
- automate/bots/{base,manager,telegram,wechat_oa,wecom,wechat_personal}.py
- Telegram: long-poll worker (no public URL needed, works behind NAT)
- 微信公众号: webhook handler with SHA-1 signature verification, 5-second
passive-reply XML, soft truncation for long agent responses
- 企业微信: webhook + active push via 主动消息 API (no 5s limit), with
cached access_token
- 个人微信: stub + risk warning (Tencent doesn't sanction this; pluggable
for wechaty/itchat backends later)
- Bot configs persist to a new 'bots' SQLite table, encrypted via Vault
- Manager auto-restarts enabled bots on server startup
Backend: API
- GET /api/bots/catalog static metadata
- GET /api/bots per-instance state + last_error
- PUT /api/bots/{id}/config save (encrypted) — empty fields don't
overwrite, so password fields can be
re-saved without re-typing
- POST /api/bots/{id}/start starts background worker / readies webhook
- POST /api/bots/{id}/stop idempotent stop
- GET /api/bots/wechat_oa/webhook handshake (echostr)
- POST /api/bots/wechat_oa/webhook inbound XML, returns reply XML
- GET /api/bots/wecom/webhook handshake
- POST /api/bots/wecom/webhook inbound, replies via active push
Frontend
- Top nav adds Chat + Bots; mobile bottom nav now Home/Chat/Bots/Notes/More
- Home tab hero is now a big "💬 Chat with autoMate" CTA. Below, "Or chat
from these channels" surfaces the 4 bot kinds with live status.
External-AI snippets demoted to a small "Power user" disclosure.
- New Bots tab: card per kind with status badge (running / ready / error /
stopped), risk note for 个人微信, "Set up" → modal with the kind's
config fields, Start/Stop buttons, last_error inline.
- Webhook URL for 公众号 / 企业微信 shown in the modal, prefilled with
the connect.base_url so the user can copy it into the platform's
backend.
Bumps version to 4.3.0.
Three concrete fixes for "looks like a notes app, not what I expected":
1. NEW Home tab — the default landing on every fresh install.
- Big black hero card: "📦 autoMate · A NAS for any AI"
- "Plug your AI in" — 4 quick-pick cards (Claude Code, Kimi, ChatGPT,
Ollama) that jump to the Connect tab pre-filtered
- Quick actions: New note · Upload file · Set reminder · Get AI snippet
- "Your warehouse" stats: live counts of notes / files / pending
reminders, plus the last-edited note's title and time
- Local-mode hint is small and contextual, with a link into Settings.
2. Top bar simplified — drops the confusing hub-URL input that used to
live in a yellow banner, replaces it with a clear identity line:
"autoMate · A NAS for any AI". A ⚙ icon (top right) opens a Settings
bottom-sheet where the hub URL config now lives. Most users on the
APK never need to touch it; advanced users find it in one obvious
place.
3. Bottom nav reordered — Home / Notes / Files / Reminders + More.
Connect AI moves into the More sheet (the Home tab's hero already
surfaces it on the landing page, so the dedicated tab is for the
detailed snippet view).
Plus: Kimi Code provider added.
- New ProviderSpec id="kimi_code" with adapter=anthropic and base
"https://api.moonshot.cn/anthropic" — Moonshot's Anthropic-
compatible endpoint that Kimi for Coding / Kimi Code CLI uses.
Same Moonshot API key works; the only difference is the endpoint
and Anthropic message format.
- Wizard pick list now shows "Moonshot Kimi (web API)" alongside
"Kimi Code (Anthropic API)" so users know which one to choose.
Plus: mobile typography polish.
- styles.css: -webkit-text-size-adjust: 100% (no iOS auto-zoom)
- inputs/textareas at min 16px (no iOS focus-zoom)
- tap-highlight-color: transparent (cleaner taps on Android)
Bumps version to 4.2.6.
The v4.2.4 APK loaded the SPA correctly but rendered the desktop layout
on a 360px phone, with the 6-tab top nav cropped off-screen and content
crammed into a corner. This commit makes the SPA actually behave like
a phone app on small screens.
Top bar
- Logo + active-tab title (instead of static "autoMate") + truncated
status badges on the right
- Tab nav hidden on mobile (`hidden md:flex`) — replaced by the bottom
nav described below
- Smaller padding (`px-3 sm:px-6`)
Bottom nav (mobile only, `md:hidden`)
- Sticky bottom strip with 4 icon+label tabs (Notes / Reminders / Files /
Connect) plus a "More" entry that opens a bottom-sheet listing the
secondary tabs (Tools / Models / Help)
- Honours iOS safe-area-inset-bottom
Banner
- Local-mode banner stacks vertically on small screens, the URL input
goes flex-1 to fill, the "Sync" button shrinks to one word
Modals
- Welcome modal becomes full-screen on mobile (no extra padding wasted)
- Wizard step badges shorten ("1·Pick", "2·Key", "3·Done")
- Provider + integration modals full-bleed on mobile, max-h-screen with
scroll, larger tap targets
Notes tab
- Mobile: list view when no note is open, editor when one is. A "← Back
to list" link returns. Desktop unchanged (3-col split).
- "+ New note" stays accessible from the header on both layouts
Bumps version to 4.2.5.
The APK loads the SPA from file:///android_asset/index.html. The HTML
referenced resources via absolute paths (/styles.css, /local-store.js,
/app.js, /icon-*.png) which the WebView resolves to file:///styles.css
etc. — outside the assets folder, so all 404. Without app.js the Alpine
data binding was never registered, so:
- tabs (Notes/Files/etc) didn't render — `tabs` was undefined
- the active section stayed hidden — `active === 'notes'` couldn't
evaluate
- only the hardcoded header text + Tailwind/Alpine CDN scripts
survived, hence the blank screenshot below the header
Fix: switch every internal resource link to a relative path. They still
work fine when the SPA is served over HTTP (relative to /), and they
now also resolve correctly inside the APK (relative to
file:///android_asset/).
Also gate service-worker registration on `location.protocol` starting
with "http" so the registration call doesn't throw a NotSupportedError
on file:// origins.
Bumps version to 4.2.4.
In v4.2.2 the APK build succeeded but the release was published before
the android job finished — release.needs only listed [resolve, build,
extension, wheel] so it ran in parallel with android instead of waiting
for it.
Adding android to release.needs makes the release wait. The existing
\`if: always() && needs.resolve.result == 'success' && needs.build.result
== 'success'\` keeps the release tolerant of an APK build failure (we
publish the rest), so this only adds latency when android succeeds —
which is what we want.
Bumps version to 4.2.3.
The pages job was originally needed to host the PWA so the Bubblewrap
TWA APK could wrap a public HTTPS URL. v4.1.1 replaced that with a
native Android project that bundles the SPA into the APK assets
directly, so Pages stopped doing any useful work — but it kept failing
on every run because the default GITHUB_TOKEN lacks permission to
enable Pages on repos that haven't been configured for it.
Just remove the job. The APK ships fine without it; users access the
SPA via their hub URL (laptop LAN IP, ngrok tunnel, or future relay).
Bumps version to 4.2.2.
AGP 7+ refuses to build without `android.useAndroidX=true` in
gradle.properties — that file didn't exist in v4.2.0, which is why the
gradle build exited with code 1.
Adds android/gradle.properties with the AndroidX flag plus standard
performance/caching settings. Also pins gradle-version: "8.7" on the
setup-gradle action so the runner doesn't try to use a missing wrapper,
and adds --stacktrace + a "show versions" step so the next failure (if
there is one) is diagnosable from the log alone.
Bumps version to 4.2.1.
Repositioning: autoMate is "a smart NAS for AI", not "a chat hub". The
phone APK and PWA now work without a hub at all (local mode, notes +
memory in IndexedDB). Connecting to a hub is a one-step "Sync &
connect" action that pushes local data up, pulls hub data down, and
flips the SPA into connected mode for the next reload.
Local mode (phone-first)
- New automate/frontend/local-store.js: IndexedDB store for notes +
memory with full CRUD, search, tags, pin, and an export/import that
supports last-write-wins merge.
- app.js: detects connectivity at boot via /api/health, sets
storageMode = 'local' | 'connected', dispatches notes ops to the
right backend.
- A persistent yellow banner across the top of the SPA in local mode,
with an inline "hub URL → Sync & connect" control.
- Files / Reminders / Models / Tools / Connect AI tabs each render an
honest "needs hub" placeholder when in local mode — no fake-working
UI, clear next step.
APK (Android)
- MainActivity drops the forced hub-URL prompt. Loads the SPA, lets it
detect mode. Saved hub URL (from previous sessions) still gets
injected so connected mode persists.
- versionCode 2 / versionName 4.2.0.
Repositioning everywhere
- Welcome modal headline: "A smart NAS for AI."
- Top-level page title, FastAPI app title/description, CLI description,
pyproject description, package docstring all rewritten around
"warehouse / storage / tool library, plug any LLM in".
- README + README_CN rewritten: smart-NAS framing, two-level deployment
(local-only vs hub), four-mode connect snippets, mobile install paths.
- New docs/sync.md: deployment shapes, free vs (planned) paid tiers,
conflict-resolution roadmap, privacy notes.
Bumps version to 4.2.0.
Replaces the Bubblewrap/TWA approach (which needed a public PWA URL
and was the reason no APK landed in v4.1.0) with a from-scratch native
Android project under android/.
What's in the APK
- Kotlin AppCompat activity (MainActivity.kt) hosting a single WebView
- The full automate/frontend/ SPA bundled into app/src/main/assets/ at
build time — no GitHub Pages, no external manifest, the APK is
self-contained
- First-launch dialog asks for the hub URL (laptop LAN IP or relay),
saves it in SharedPreferences, injects it into the SPA's localStorage
so all the existing remote-hub plumbing just works
- Menu: Change hub URL · Reload
- Launcher icons in all 5 standard densities, generated from the PWA
icon
CI changes
- android job no longer needs the pages job at all
- Uses temurin JDK 17 + setup-android@v3 + setup-gradle@v3
- Stamps the version tag into app/build.gradle's versionName, then
`gradle assembleDebug` and uploads the resulting APK
- Signed with the standard Android debug keystore so users can sideload
the APK from the GitHub Release without us shipping private keys
iOS reality
- New docs/mobile.md spells out: iOS = PWA only (Apple Developer fee,
Xcode-on-macOS, App Store review = not happening for a free OSS tool).
Safari "Add to Home Screen" is the iOS install path; documented step
by step.
Bumps version to 4.1.1.
The previous run failed at actions/configure-pages because the repo
didn't have Pages enabled, which then took down the whole release job
(it depended on `pages` and `android`).
Two-part fix:
- Pass `enablement: true` to actions/configure-pages so it auto-enables
Pages on first run with the existing pages: write permission.
- Mark the `pages` job continue-on-error: true at the job level. Drop
`pages` and `android` from `release.needs`. The release now hard-depends
only on resolve + the binary build matrix; Pages/APK are best-effort
and the release simply omits any artifact that didn't materialise
(`fail_on_unmatched_files: false`).
Also: this iteration is additive, not a breaking change. Roll back the
version from 5.0.0 to 4.1.0 — semver minor bump for the personal-infra
features (notes / files / reminders / memory / Web Push / PWA assets).
Major repositioning from "another chat hub" to "the brain behind any AI
you already use". Don't switch chat apps; switch what's behind them.
New core capabilities (each is both a UI tab and a tool category)
- notes/ Markdown documents, tags, search, pin. notes.{create, search,
read, update, delete} as tools.
- files/ Content-addressed local vault, dedup by SHA-256, multipart
upload, streaming download. files.{put, list, read, delete}.
- reminders/ Background scheduler thread polls every 30s; due reminders
fan out as Web Push to subscribed PWAs. Recurring (hourly/
daily/weekly) supported. reminders.{create, list, snooze,
dismiss}.
- memory/ Long-term key-value facts. memory.{set, get, list, delete}.
Web Push (VAPID)
- VAPID keypair auto-generated on first run, stashed in DB.
- /api/push/{config,subscribe,test} for the PWA to subscribe.
- service-worker.js handles 'push' and 'notificationclick' events.
- pywebpush dep added (graceful fallback if not installed).
UI restructure
- Top nav: Notes | Files | Reminders | Connect AI | Tools | Models | Help.
- Chat tab gone from main nav (still exists for debug; agent loop unchanged).
- Welcome modal copy: "Your AI's brain. Don't switch chat apps."
- Empty states + 'Enable notifications' card in Reminders.
Mobile / multi-platform packaging
- New `pages` job in build.yml: deploys frontend/ to GitHub Pages so the
PWA has a public HTTPS origin.
- `android` job updated: Bubblewrap reads the manifest from the GH Pages
URL and builds a TWA APK. Best-effort (continue-on-error) — a missing
APK doesn't block the release.
- Web Push subscription survives the PWA being installed to home screen,
so reminders fire even when the app is closed.
Backend wiring
- 6 new SQLite tables, indexed for the queries each module uses.
- 5 new API routers mounted under /api.
- 4 new tool categories registered first in the catalog (these are
autoMate's identity now).
- Background scheduler started from server state; stops cleanly.
- python-multipart + pywebpush added as core deps.
README, frontend headline, welcome wizard all rewritten around the new
"personal infra, bring any AI" positioning.
Bumps version to 5.0.0.
Ships the infrastructure for the "any AI, anywhere" story without yet
adding a chat UI on the phone (the phone is a controller, not a host).
PWA
- manifest.webmanifest, service-worker.js, and 32/192/512 icons added
to automate/frontend/. The SW caches the SPA shell offline-first;
/api and /oauth always go to the network.
- index.html links the manifest, registers the SW, sets theme-color
and apple-mobile-web-app-capable so iOS Safari treats it as a real
app when added to the home screen.
- Help tab gets a "Use it on your phone" section walking the user
through `automate serve --host 0.0.0.0` → find LAN IP → open in
mobile Chrome → Add to Home Screen.
Remote hub
- app.js now reads localStorage `automate-hub-base` and prefixes every
fetch + WebSocket URL with it. Default empty = use the current origin.
- New "Connect this UI to a different hub" panel in Help lets the user
point the (PWA) UI at any reachable hub URL — useful when a phone's
installed PWA needs to reach the laptop on a different IP, or via the
relay.
Relay client
- New `automate.relay` module: persistent WS to a relay endpoint,
forwards inbound HTTP frames into the local FastAPI app.
- New CLI subcommand `automate relay <url> --token …`.
- `relay` extra in pyproject (websockets + httpx).
- docs/relay.md fully specifies the wire protocol, threat model, and a
~150-line FastAPI sample relay implementation, plus the roadmap
(E2E encryption, WS tunnelling, hosted relay).
Android
- New `android` job in build.yml uses Bubblewrap to attempt a TWA APK.
Marked continue-on-error: a missing APK doesn't block the release.
Recommended path remains "install the PWA from the hub URL".
Bumps version to 4.0.5.
Two big additions, both pointing at the same insight: autoMate isn't only
for the chat in its own window — it's a hub that any AI should be able to
plug into.
Setup wizard
- Replaces the cold "fill out this modal" flow with a 3-step page wizard:
pick a provider (7 popular ones surfaced as cards) → guided "get your
key" with deep-link → paste + auto-test + auto-activate → 🎉 done page
with three follow-up suggestions (open chat / connect more AIs / wire
in tools).
- Triggered from the welcome modal, the Chat empty state, and any time
the user has no model configured. Reuses the saveAndUse() machinery
underneath, so no double implementation.
Connect AI tab (new top-level tab)
- New /api/connect endpoint emits four ready-to-paste snippets, each
parameterised with the user's local base URL:
mcp — full MCP config JSON for Claude Code / Cursor / Cline /
Kimi K2 / etc.
http — system-prompt fragment for any LLM that can call URLs
("POST /api/agent/run with this body, use it whenever
the user asks for something concrete")
bridge — shell wrapper + system prompt for tool-less LLMs (basic
Ollama, web chat) that can only emit text
discover — OpenAPI URL for agents that can read schemas
- Each snippet has a one-click Copy button + clear "use this when…" line.
- Security note explains the 127.0.0.1 binding and how to opt into LAN
exposure.
Polish
- Welcome modal subtitle now leads with "one hub, any AI" instead of
just "chat in this window".
- Help tab opens with a blue banner pointing at Connect AI.
- Chat empty state has a third link: "Use from a different AI".
README rewritten — leads with "one hub, any AI", followed by the four
connection modes table, before the install instructions.
Bumps version to 4.0.4.
Configuring a model used to be: paste key → click Save → close modal →
find card again → click "Use this". Way too many steps. Plus the default
model for some providers required tier upgrades the user didn't have
(e.g. Kimi defaulted to kimi-k2-0711-preview).
Models tab
- ONE button: "Save and use this provider" — saves credentials, runs
a 1-token test call, sets as active, closes the modal on success.
- API key is the only field shown by default. Base URL + model name
collapsed into "Advanced".
- Defaults changed to the most-universal models per provider:
Anthropic claude-opus-4-7 → claude-sonnet-4-6
Kimi kimi-k2-0711-preview → moonshot-v1-8k
GLM glm-4.6 → glm-4-flash (free)
Doubao doubao-seed-1-6 → (none — clarified that Ark uses
endpoint IDs, not model names)
- Test failures get a diagnostic hint (401/404/403/timeout patterns).
Tools tab
- Per-integration "How to get this" block in the modal — each of the 31
integrations now has a label, the right deep-link to the page where
you create the token, and a one-line guide.
- Single password field + ONE button: "Save and connect".
- OAuth flow tucked under "Use OAuth instead (advanced)" — keeps the
page clean for the 90% case where pasting a token is fine.
- Search box at the top to filter the 31 cards.
- Inline success/error feedback, modal auto-closes on success.
Bumps version to 4.0.3.
The previous build dropped a brand-new user into a chat box with no
guidance. Now:
- Welcome modal auto-opens on first visit when no provider is configured.
Three numbered steps + a "Configure my first model →" button that
jumps to the Models tab. Persists dismissal in localStorage.
- New Help tab — quickstart, runnable examples (with "Try it" buttons),
browser-extension instructions, MCP setup snippet for Claude Code /
Cursor / Cline / Kimi, full tool catalog by category, privacy notes.
- Chat tab: when no model is active, shows an empty-state CTA pointing
to Models instead of letting the user send a doomed message.
- Quick prompts in the Help tab are categorised by which subsystem they
exercise, so users learn the model by trying.
Bumps version to 4.0.2.
Double-clicking automate.exe used to print argparse help and exit, which
looked like a crash to anyone expecting a GUI to pop up. Treat empty
argv as `serve` so the BS hub boots and the browser auto-opens. CLI
users still get help via `automate -h`.
Also makes the startup banner more legible so the URL is obvious in the
console window that appears on Windows double-click.
Bumps version to 4.0.1.
Allows kicking off a release in environments that can push branches but
not tags (e.g. some hosted git proxies). The resolve job derives the tag
from the branch name (release-vX.Y.Z → vX.Y.Z), creates the tag, and the
final release step deletes the trigger branch on success.
Tag push, branch push, and workflow_dispatch all converge on the same
build matrix.
build.yml
- now triggers on push tag v* AND workflow_dispatch
- replaces the tag-creating job with a small resolver that uses
GITHUB_REF_NAME on push, or creates the tag on workflow_dispatch
- adds a wheel job so the GitHub Release also carries the .whl + .tar.gz
- release notes match the new install matrix (binary/pip/docker/extension)
publish.yml
- restricted to workflow_dispatch only — PyPI trusted publisher needs a
one-time setup; auto-publish would fail noisily until that's in place
PyInstaller treats the entry script as a top-level module, so
automate/__main__.py's relative import (`from .cli import main`) blew up
at runtime. Add packaging/launcher.py as a thin absolute-import wrapper
and point the spec at it.
Spec file now resolves all paths via SPEC location so the build runs
correctly from the project root (which is what the GitHub Actions
workflow does).
Verified locally: 37MB Linux x64 binary, doctor + serve work, /api/status
and /openapi.json return 200.
https://claude.ai/code/session_01KLygewzdXxieWmndwGVBEf
Browser extension (extension/)
- Manifest V3 service worker holds a WebSocket to the local hub and
dispatches commands against the user's real browser — their tabs,
cookies, logged-in sessions
- Popup shows pairing status; auto-reconnect with exponential backoff and
a chrome.alarms keepalive ping so the worker isn't suspended mid-call
- Content script handles DOM operations (CSS or text= selectors)
- Tools exposed: bx.{tabs,open,activate,close,navigate,screenshot,click,
type,extract,scroll,eval}
Bridge
- automate/extension_bus.py bridges sync tool handlers ↔ async WS via a
threading.Event + asyncio.Queue, single-extension semantics
- automate/server/api/extension.py mounts /api/extension/{ws,status}
- /api/status now reports extension_connected; UI shows a live dot
Packaging
- packaging/automate.spec — PyInstaller spec wired to automate/__main__,
bundles the static SPA, excludes heavy ML deps
- .github/workflows/build.yml — manually-triggered Windows / macOS-arm64 /
Linux build matrix that also packs the extension and publishes a
Release with all four artifacts
- Dockerfile + .dockerignore — python:3.12-slim base with Playwright
Chromium preinstalled; binds 0.0.0.0:8765, mounts /data
- Wheel + sdist build verified locally (102KB wheel installs into a
clean venv, `automate doctor` reports 22 tools / 25 providers; bound
server returns 200 on / and correct status JSON)
Restructure
- integrations/ → automate/integrations/ for one-package cohesion;
adapter import path updated; setuptools find scope tightened
- README + README_CN: new install matrix (pip / binary / Docker /
extension), project-layout map, updated tool inventory
https://claude.ai/code/session_01KLygewzdXxieWmndwGVBEf
Rebuild the project around a single thesis: any LLM can plan, but it can't
reach into your local shell, your browser session, or your SaaS accounts.
autoMate is the executor that fills that gap.
What's new
- automate/ package with FastAPI server, SQLite + Fernet credential vault
- 25-provider LLM catalog (OpenAI / Anthropic / Gemini / Kimi / Qwen /
DeepSeek / Doubao / GLM / Yi / MiniMax / Hunyuan / Baichuan / StepFun /
Mistral / Grok / OpenRouter / Groq / Together / Fireworks / DeepInfra /
Cohere / Ollama / LM Studio / vLLM)
- Tool registry feeds three doorways from one source of truth: REST,
WebSocket, and stdio MCP
- Three local executors with proper isolation: shell.exec, script.run
(Python/Bash/Node), browser.* (Playwright), desktop.* (pyautogui)
- 31 SaaS integrations adapted into the registry via a shim — drop-in
reuse of the existing integrations/ tree
- OAuth click-through for GitHub / Notion / Slack / Linear / 飞书 / 钉钉
with state token + encrypted client_secret storage
- Static SPA (Tailwind + Alpine, no build step) for onboarding, model
config, tool marketplace, live chat, run history
- automate {serve,mcp,doctor} CLI
Removed
- Old top-level entry points (cli.py, mcp_server.py, install.py, main.spec)
- auto_control/, core/, util/ legacy modules superseded by automate/
- cloud_vision.py (HF Inference Endpoints flow can return as an optional
tool later)
- task_demonstration.json (10MB demo data not needed in the package)
- .github/workflows/build.yml (PyInstaller path; pip install + automate
serve is the new install story)
Smoke tested: 19 REST endpoints + 1 WebSocket + OAuth callback all live,
frontend served, 25 providers + 31 integrations + 11 local tools registered.
https://claude.ai/code/session_01KLygewzdXxieWmndwGVBEf
Merged from claude/optimize-multi-platform-uz5mK:
- 5 new integrations: Stripe, Shopify, Confluence, Asana, Monday.com
- All 3 READMEs updated with competitive comparison vs Composio/Zapier
- New "local-first, zero cloud dependency" positioning angle
- pyproject.toml bumped to v0.8.0
https://claude.ai/code/session_01DMcu2ZyvS47ZgEg64QN1iF
Merge claude/optimize-multi-platform-uz5mK
autoMate now operates as both an API Tool Center (26 platforms, activated
by env vars) and a desktop GUI automation tool. Integrations auto-register
when their env vars are present; unused ones are silently skipped.
Chinese platforms (8): 飞书, 钉钉, 企业微信, 微信公众号, 微博, Gitee, 语雀, 高德地图
Messaging (6): Slack, Telegram, Discord, Microsoft Teams, Zoom, Twitter/X
DevOps (3): GitHub, GitLab, Sentry
Project mgmt (6): Notion, Airtable, Linear, Jira, Trello, HubSpot
Email/marketing (3): SendGrid, Twilio, Mailchimp
https://claude.ai/code/session_01DMcu2ZyvS47ZgEg64QN1iF
Add 12 more integrations across Chinese platforms, DevOps, project
management, and email/marketing categories:
Chinese: Gitee (码云), 语雀 (Yuque), 高德地图 (Amap)
Messaging: Microsoft Teams (webhook), Zoom (OAuth2 meetings)
DevOps: GitLab (issues, MRs, pipelines), Sentry (error tracking)
Project mgmt: Trello (boards/cards), HubSpot (contacts/deals)
Email/marketing: SendGrid, Twilio (SMS), Mailchimp
Also add PUT method to BaseIntegration for PATCH-style upserts.
Update FastMCP instructions and all three READMEs for 26 platforms.
https://claude.ai/code/session_01DMcu2ZyvS47ZgEg64QN1iF
Add cloud_vision.py contributed by @kvk-code:
- OmniParser V2 screen parsing via HuggingFace endpoints (no local GPU)
- UI-TARS / Qwen-VL action reasoning via cloud VLM
- smart_act: full autonomous parse → reason → execute loop
- New MCP tools: cloud_vision_config, warm_endpoints, parse_screen,
reason_action, smart_act
- Logging to ~/.automate/logs/
Update all READMEs with two-mode architecture (basic / cloud vision)
and @latest tag in all config examples.
https://claude.ai/code/session_01DMcu2ZyvS47ZgEg64QN1iF