stitchflow-local-agent
Local daemons that automate SaaS admin tasks for a Stitchflow workspace:
- Action agent — executes user removals and role changes in ChatGPT and Calendly.
- Data sync — exports user CSVs from ChatGPT and Calendly, then uploads them to Stitchflow.
Both run headlessly via agent-browser (Playwright) using a shared persistent browser profile for session management.
Install
pip install "git+https://github.com/Stitchflow-website-webapps/stitchflow-local-agent.git"
Two CLI commands become available:
| CLI | Purpose |
|---|---|
stitchflow-agent |
Action execution — user removal, role changes |
stitchflow-sync |
Daily data sync — app CSV export and Stitchflow upload |
Quick start
# 1. First-time setup — installs agent-browser, opens browsers for login
stitchflow-agent setup
stitchflow-sync setup
# 2. Single run
stitchflow-agent run
stitchflow-sync run
# 3. Foreground daemon commands (for local testing)
stitchflow-agent daemon
stitchflow-sync daemon
# 4. Check health
stitchflow-agent status
stitchflow-sync status
Package structure
stitchflow_local_agent/
common/ shared config, browser helpers, daemon, logging, installer
actions/
api_client.py Stitchflow task API client
dispatcher.py task routing by (integration, action)
chatgpt/ ChatGPT: remove_user
calendly/ Calendly: remove_user, change_role
sync/
stitchflow_upload.py generic CSV → Stitchflow UI upload
calendly/ Calendly user export (UI-based)
chatgpt/ ChatGPT user export (API via browser session)
agent_cli.py stitchflow-agent entrypoint
sync_cli.py stitchflow-sync entrypoint
Action agent (stitchflow-agent)
Polls the Stitchflow API for pending tasks, claims them, and executes each one through browser automation.
stitchflow-agent setup # auto-install agent-browser + Chromium, configure env, open login
stitchflow-agent login # re-authenticate (auto-installs if missing)
stitchflow-agent run # process all pending tasks once
stitchflow-agent daemon # poll continuously (foreground; launchd/task manages background)
stitchflow-agent status # show config, daemon PID, last task results
Supported actions
| Integration | Action | Description |
|---|---|---|
| ChatGPT | remove_user |
Remove a team member by email from the ChatGPT admin panel |
| Calendly | remove_user |
Remove a user from the Calendly organization |
| Calendly | change_role |
Change a user's role (Admin ↔ User) |
Extending
Register a new handler in actions/dispatcher.py:
HANDLERS[("app_name", "action_name")] = handler_function
Data sync (stitchflow-sync)
Exports user CSVs from connected apps and uploads each to the matching Stitchflow connection. All configured apps are synced in a single cycle.
stitchflow-sync setup # open Calendly, ChatGPT, and Stitchflow for login
stitchflow-sync run # run one full sync cycle
stitchflow-sync daemon # local foreground loop (use launchd/task scheduler for production background runs)
stitchflow-sync status # show config, logs, daemon status, recent CSVs
Supported sync sources
| App | Export method | Notes |
|---|---|---|
| Calendly | UI automation — click Export → Active → download ZIP | CSV extracted from ZIP automatically |
| ChatGPT | API via browser session — JS fetches /api/auth/session, paginates the users API |
Account ID auto-discovered from session |
Sync cycle
Each cycle runs sequentially: Calendly export → upload → ChatGPT export → upload → close browser.
Calendly
- Opens Calendly admin → clicks Export → Active → downloads ZIP → extracts CSV.
- Opens Stitchflow → Connections → searches "Calendly" → uploads CSV → polls until "Connected".
ChatGPT
- Opens ChatGPT → executes JS that fetches the auth token, auto-discovers the workspace account ID from the session, and paginates the users API.
- Converts the returned JSON to CSV in Python, saves to
~/.stitchflow/data-sync/chatgpt/. - Opens Stitchflow → Connections → searches "ChatGPT" → uploads CSV → polls until "Connected".
Audit logs
JSONL logs under ~/.stitchflow/logs/:
| File | Records |
|---|---|
calendly-export.jsonl |
Each Calendly export — timestamp, CSV path, file size (success) or error (failure) |
chatgpt-export.jsonl |
Each ChatGPT export — timestamp, CSV path, file size, user count (success) or error (failure) |
data-sync-audit.jsonl |
Each Stitchflow upload per app — timestamp, CSV path (success) or error (failure) |
data-sync.log |
Full sync cycle run log |
Extending
Add a new sync source in three steps:
- Create
sync/<app>/export.pywith anasync def export_<app>_users() -> str | Nonefunction. - The upload side (
sync/stitchflow_upload.py) is already generic — pass anyapp_name. - Wire the export into
sync_cli.py'srun_sync()via_sync_app().
Environment variables
| Variable | Required | Default | Description |
|---|---|---|---|
STITCHFLOW_API_URL |
Yes | http://localhost:3030 |
Stitchflow API base URL |
STITCHFLOW_WORKSPACE_ID |
Yes | — | Stitchflow workspace ID |
STITCHFLOW_API_KEY |
No | — | API key (prefer keyring storage) |
AGENT_BROWSER_PROFILE |
No | ~/.agent-browser-profile |
Persistent Chromium profile path |
CHATGPT_ACCOUNT_ID |
No | auto-discovered | Override for ChatGPT workspace ID (normally detected from session) |
STITCHFLOW_AGENT_POLL_INTERVAL_SECONDS |
No | 60 |
Action daemon poll interval |
STITCHFLOW_AGENT_POLL_MAX_IDLE_SECONDS |
No | 900 |
Action daemon max idle backoff |
STITCHFLOW_AGENT_POLL_MAX_ERROR_SECONDS |
No | 300 |
Action daemon max error backoff |
STITCHFLOW_SYNC_INTERVAL_SECONDS |
No | 86400 |
Sync daemon interval (24 h) |
All config is persisted to ~/.stitchflow/agent.env during setup.
Daemon scheduling (recommended for production)
See DAEMON_SETUP.md for macOS launchd and Windows Task Scheduler installation guides covering both daemons.
Security
- API keys — stored in the OS credential manager (macOS Keychain / Windows DPAPI) via
keyring. Falls back to~/.stitchflow/agent.envifkeyringis unavailable. - Browser sessions — maintained in a persistent profile at
~/.agent-browser-profile. No credentials are stored in code or config files. - Action proof artifacts —
before.png,after.png, andaudit.jsonper task under~/.stitchflow/artifacts/. - Audit trail — rolling log at
~/.stitchflow/logs/audit.log.
Dependencies
| Package | Purpose |
|---|---|
| Python 3.11 - 3.13 | Runtime |
httpx |
Async HTTP client for the Stitchflow API |
keyring |
OS credential manager integration |
agent-browser |
Playwright-based browser automation CLI (installed via npm) |
stitchflow-agent setup / stitchflow-sync setup auto-installs agent-browser via npm install -g agent-browser (or brew install agent-browser on macOS), then runs agent-browser install to download Chromium.
Building and releasing
All Python source files are compiled to native extensions via Cython before distribution. Published wheels contain only compiled binaries — no .py or .c source files.
Release workflow
- Bump the version in
pyproject.toml. - Commit the version bump, then create the matching tag from that same commit:
git commit -am "Release v<version>" && git tag v<version> && git push && git push --tags. - GitHub Actions builds compiled wheels for macOS (ARM + Intel), Linux, and Windows across Python 3.11–3.13.
- A verification step checks that no source files leaked into any wheel.
- The workflow validates that
GITHUB_REFmatches[project].versionbefore publishing. - Wheels are published to PyPI automatically.
Local testing
# Install build deps
pip install "cython>=3.0" setuptools wheel
# Compile extensions in-place (for development testing)
python setup.py build_ext --inplace
# Build a wheel for your current platform
pip wheel . --no-deps -w dist/
# Verify no source files in the wheel
unzip -l dist/*.whl | grep -E '\.(py|c)$'
# (should return no results)
CI configuration
The build pipeline is defined in .github/workflows/build-wheels.yml. It requires a PYPI_API_TOKEN secret configured in the GitHub repository settings under an environment named pypi.
Further reading
ARCHITECTURE.md— internals: dispatcher, browser layer, sync pipeline, error handling, file layout.DAEMON_SETUP.md— launchd / Task Scheduler install guides.
Metadata
Release files for stitchflow-local-agent 0.3.18
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
Total release size: 90.4 MB
Release files / stitchflow_local_agent-0.3.18-cp313-cp313-win_amd64.whl
| Download URL | stitchflow_local_agent-0.3.18-cp313-cp313-win_amd64.whl |
|---|---|
| Size | 1.7 MB |
| Tags | CPython 3.13 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
4b587255aa3140049731ce8929f823f95fd9d8f4c7da872578ad8bd02e6cf114
|
|
BLAKE2b-256 checksum How to use checksums |
bf9d31bb452f94189a6088cff72f5b202188ef9ae9e87b45ed417fa911e4f1de
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / stitchflow_local_agent-0.3.18-cp313-cp313-win32.whl
| Download URL | stitchflow_local_agent-0.3.18-cp313-cp313-win32.whl |
|---|---|
| Size | 1.5 MB |
| Tags | CPython 3.13 Windows x86-32 |
|
SHA-256 checksum How to use checksums |
91546b5eccbbdc92d1148cd237b25692f3d07d8ad51c48fb484064da38182d94
|
|
BLAKE2b-256 checksum How to use checksums |
387b72be006d5274ba2a8726ef4b3000d18e881a0ce4aaf5a7bcaf6ad23fb2c9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / stitchflow_local_agent-0.3.18-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | stitchflow_local_agent-0.3.18-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 11.7 MB |
| Tags | CPython 3.13 Linux glibc 2.17+ x86-64 |
|
SHA-256 checksum How to use checksums |
083b27ac0b07718f6485c87123f509c81368bdd897974e9a6307b64ebfd52335
|
|
BLAKE2b-256 checksum How to use checksums |
b10a832c3569102467de2d5ffbf50c3afb9d4fa03784411c847bd809c8f4dede
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / stitchflow_local_agent-0.3.18-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
| Download URL | stitchflow_local_agent-0.3.18-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl |
|---|---|
| Size | 11.1 MB |
| Tags | CPython 3.13 Linux glibc 2.17+ x86-32 Linux glibc 2.5+ x86-32 |
|
SHA-256 checksum How to use checksums |
db1a2de6b6a9db8b30ecb87e230f46f5666fb675d0149ece50b5098f6e87b506
|
|
BLAKE2b-256 checksum How to use checksums |
89f1f06b7c8427e0b276064b8d84d78057e66f0716b9253f9fc8ca1f2e9507a7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / stitchflow_local_agent-0.3.18-cp313-cp313-macosx_11_0_arm64.whl
| Download URL | stitchflow_local_agent-0.3.18-cp313-cp313-macosx_11_0_arm64.whl |
|---|---|
| Size | 1.8 MB |
| Tags | CPython 3.13 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
8b5726da663272e221768efeaf4b76ce5c01efac415d14099b49ead207b2fdcc
|
|
BLAKE2b-256 checksum How to use checksums |
0c32675794234366e37ca102c218565b1e1e82cd0d5ffd48e6ecf34a4e46d9f0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / stitchflow_local_agent-0.3.18-cp313-cp313-macosx_10_13_x86_64.whl
| Download URL | stitchflow_local_agent-0.3.18-cp313-cp313-macosx_10_13_x86_64.whl |
|---|---|
| Size | 1.8 MB |
| Tags | CPython 3.13 macOS 10.13+ x86-64 |
|
SHA-256 checksum How to use checksums |
3018e901f3599f8dce1d60319a3846b1ca9ea58ceecf0d3c9f57dce58657e918
|
|
BLAKE2b-256 checksum How to use checksums |
7b2eb0b74c5ec001e4639d884d266e6349079575345d398b45b8c8ff97fe0d59
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / stitchflow_local_agent-0.3.18-cp312-cp312-win_amd64.whl
| Download URL | stitchflow_local_agent-0.3.18-cp312-cp312-win_amd64.whl |
|---|---|
| Size | 1.7 MB |
| Tags | CPython 3.12 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
d7281b0115e0a113a98e7f82bb9ae4363dd761f6ebbe48bcb6801dd007100ff3
|
|
BLAKE2b-256 checksum How to use checksums |
00f70cd4bd19057859cf3cad1be2f98d7c083aca2f743aaeb29429036f587852
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / stitchflow_local_agent-0.3.18-cp312-cp312-win32.whl
| Download URL | stitchflow_local_agent-0.3.18-cp312-cp312-win32.whl |
|---|---|
| Size | 1.5 MB |
| Tags | CPython 3.12 Windows x86-32 |
|
SHA-256 checksum How to use checksums |
f69edbf59a8e5f93daead47368dfdd47e27ef37c69f14fa8f9e91b78254890f0
|
|
BLAKE2b-256 checksum How to use checksums |
2ff40c527925bc84212542c9e6429ac1636768201396750894ec49e696d4d28e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / stitchflow_local_agent-0.3.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | stitchflow_local_agent-0.3.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 11.9 MB |
| Tags | CPython 3.12 Linux glibc 2.17+ x86-64 |
|
SHA-256 checksum How to use checksums |
bd787fdd0e22c594e1e42dacffe260bea15a0e0bda0af8caac05d0b7f2dec24a
|
|
BLAKE2b-256 checksum How to use checksums |
aebbc513e4dc8b85df7e0d6ae0319ccb426460cbb2c22a5d77952deca1554cf9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / stitchflow_local_agent-0.3.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
| Download URL | stitchflow_local_agent-0.3.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl |
|---|---|
| Size | 11.3 MB |
| Tags | CPython 3.12 Linux glibc 2.17+ x86-32 Linux glibc 2.5+ x86-32 |
|
SHA-256 checksum How to use checksums |
2c52227cdf4971d4b0b9073d7fd07077e2261235f6cf0a293ae140a6673949b4
|
|
BLAKE2b-256 checksum How to use checksums |
0e59e724cf4c7888f014f225d39ac27b7559b9fa5c3031adea08367d969d59a1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / stitchflow_local_agent-0.3.18-cp312-cp312-macosx_11_0_arm64.whl
| Download URL | stitchflow_local_agent-0.3.18-cp312-cp312-macosx_11_0_arm64.whl |
|---|---|
| Size | 1.8 MB |
| Tags | CPython 3.12 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
2ffda2ec2dab87bed066fca2733835693d3ec3a45964b3c1b852756c8b871d15
|
|
BLAKE2b-256 checksum How to use checksums |
d944950be12725ee294b181bf03a17c8945351657d6fd8a8e1c93c80082c509c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / stitchflow_local_agent-0.3.18-cp312-cp312-macosx_10_13_x86_64.whl
| Download URL | stitchflow_local_agent-0.3.18-cp312-cp312-macosx_10_13_x86_64.whl |
|---|---|
| Size | 1.8 MB |
| Tags | CPython 3.12 macOS 10.13+ x86-64 |
|
SHA-256 checksum How to use checksums |
91d24c9bfeda286b606963575925a5c831caf16e032943c071f4a12f56ba7b9a
|
|
BLAKE2b-256 checksum How to use checksums |
b8cbccfe3a4de15812b59c01742c5a9cccec80d4700d4a996e25cd61758a5952
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / stitchflow_local_agent-0.3.18-cp311-cp311-win_amd64.whl
| Download URL | stitchflow_local_agent-0.3.18-cp311-cp311-win_amd64.whl |
|---|---|
| Size | 1.8 MB |
| Tags | CPython 3.11 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
b7185a694b05eedb0198488a7e4bbba0bbec85311d0a3f661ab32388f04a8aa3
|
|
BLAKE2b-256 checksum How to use checksums |
9509976b8b55e9687e5341241bb4ddc167fcddd2d6e0dd374c65da520e46d56f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / stitchflow_local_agent-0.3.18-cp311-cp311-win32.whl
| Download URL | stitchflow_local_agent-0.3.18-cp311-cp311-win32.whl |
|---|---|
| Size | 1.5 MB |
| Tags | CPython 3.11 Windows x86-32 |
|
SHA-256 checksum How to use checksums |
2820fa8719af193b50050f997f74bdafdd51079cb4e930c41ffb2ab246bccf41
|
|
BLAKE2b-256 checksum How to use checksums |
0946a959bf66ed79a8ad1711eb2688d6b81c5edb02ed0b615e093e7f50ba5c3a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / stitchflow_local_agent-0.3.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | stitchflow_local_agent-0.3.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 12.0 MB |
| Tags | CPython 3.11 Linux glibc 2.17+ x86-64 |
|
SHA-256 checksum How to use checksums |
5a77bb02b0de1ec9f7cf9d5c093d1b5d741917019696ed060ba49d3573ae8196
|
|
BLAKE2b-256 checksum How to use checksums |
85d62cae44848b6d1d5a1d75be0dc507f66d5a1f5f1db01455a8943f412c38a4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / stitchflow_local_agent-0.3.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
| Download URL | stitchflow_local_agent-0.3.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl |
|---|---|
| Size | 11.7 MB |
| Tags | CPython 3.11 Linux glibc 2.17+ x86-32 Linux glibc 2.5+ x86-32 |
|
SHA-256 checksum How to use checksums |
94f159eab46e88cc5bc2f65fd52b1549875360dd1f66dd9b5cf729244d8ab021
|
|
BLAKE2b-256 checksum How to use checksums |
bd59ed412710d2d36145b1ea24354d6fd3d64ddafc288986965e0ec6e3f73a08
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / stitchflow_local_agent-0.3.18-cp311-cp311-macosx_11_0_arm64.whl
| Download URL | stitchflow_local_agent-0.3.18-cp311-cp311-macosx_11_0_arm64.whl |
|---|---|
| Size | 1.8 MB |
| Tags | CPython 3.11 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
09b434830fc50ad49639cf6bfa0c117a34bf4a25c34892da19567b48651a0bad
|
|
BLAKE2b-256 checksum How to use checksums |
27694b35fc85fae5a0c79e445a60d5a431c1811c95e32c50a08b1208147d2405
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / stitchflow_local_agent-0.3.18-cp311-cp311-macosx_10_9_x86_64.whl
| Download URL | stitchflow_local_agent-0.3.18-cp311-cp311-macosx_10_9_x86_64.whl |
|---|---|
| Size | 1.9 MB |
| Tags | CPython 3.11 macOS 10.9+ x86-64 |
|
SHA-256 checksum How to use checksums |
312850abfb808b8561a0b31984bae6dfcb801c204d9f463f303f45fdcf839951
|
|
BLAKE2b-256 checksum How to use checksums |
4d8cbc331c07e95a8b94deed800665b11fb47e1ad47eee100f7b67d025f3d04e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|