{"id":46727938,"url":"https://github.com/nickustinov/itsyconnect-macos","last_synced_at":"2026-04-01T19:40:31.053Z","repository":{"id":341605399,"uuid":"1167525671","full_name":"nickustinov/itsyconnect-macos","owner":"nickustinov","description":"Better App Store Connect","archived":false,"fork":false,"pushed_at":"2026-03-26T22:09:31.000Z","size":11187,"stargazers_count":83,"open_issues_count":4,"forks_count":3,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-27T10:15:42.608Z","etag":null,"topics":["appstoreconnect","asc-api","docker-container","electron","ios","iosdevelopment","macos","mcp-server","testflight"],"latest_commit_sha":null,"homepage":"https://itsyconnect.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nickustinov.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-26T11:44:40.000Z","updated_at":"2026-03-26T22:09:35.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/nickustinov/itsyconnect-macos","commit_stats":null,"previous_names":["nickustinov/itsyconnect-macos"],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/nickustinov/itsyconnect-macos","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickustinov%2Fitsyconnect-macos","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickustinov%2Fitsyconnect-macos/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickustinov%2Fitsyconnect-macos/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickustinov%2Fitsyconnect-macos/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nickustinov","download_url":"https://codeload.github.com/nickustinov/itsyconnect-macos/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickustinov%2Fitsyconnect-macos/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31291178,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T13:12:26.723Z","status":"ssl_error","status_checked_at":"2026-04-01T13:12:25.102Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["appstoreconnect","asc-api","docker-container","electron","ios","iosdevelopment","macos","mcp-server","testflight"],"created_at":"2026-03-09T14:07:56.137Z","updated_at":"2026-04-01T19:40:31.034Z","avatar_url":"https://github.com/nickustinov.png","language":"TypeScript","funding_links":[],"categories":["개발 도구"],"sub_categories":["개발자 유틸리티"],"readme":"\u003ch1\u003eItsyconnect\u003c/h1\u003e\n\n\u003cp\u003e\n  Better App Store Connect.\n\u003c/p\u003e\n\n\u003cp\u003e\n  \u003ca href=\"https://github.com/nickustinov/itsyconnect-macos/blob/main/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/license-AGPL--v3-blue.svg\" alt=\"License\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/nickustinov/itsyconnect-macos/actions\"\u003e\u003cimg src=\"https://img.shields.io/github/actions/workflow/status/nickustinov/itsyconnect-macos/ci.yml?branch=main\" alt=\"CI\" /\u003e\u003c/a\u003e\n  \u003cimg src=\"https://img.shields.io/badge/electron-40-9feaf9\" alt=\"Electron\" /\u003e\n  \u003cimg src=\"https://img.shields.io/badge/next.js-16-black\" alt=\"Next.js 16\" /\u003e\n  \u003cimg src=\"https://img.shields.io/badge/sqlite-WAL-green\" alt=\"SQLite\" /\u003e\n  \u003cimg src=\"https://img.shields.io/badge/macOS-11%2B-999\" alt=\"macOS 11+\" /\u003e\n  \u003ca href=\"https://github.com/nickustinov/itsyconnect-macos/releases\"\u003e\u003cimg src=\"https://img.shields.io/github/downloads/nickustinov/itsyconnect-macos/total\" alt=\"Downloads\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\nA desktop app and self-hosted web dashboard that replaces Apple's App Store Connect. Edit metadata across all locales at once, manage TestFlight builds and testers, review analytics, respond to customer reviews, and submit nominations – all from a single desktop window. AI translates your descriptions, keywords, review replies, and even screenshots into every language with one click.\n\nEverything runs locally. One SQLite database, no cloud, no accounts, no telemetry. Credentials are encrypted with AES-256-GCM and the master key lives in the macOS Keychain.\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ca href=\"docs/screenshots/1.webp\"\u003e\u003cimg src=\"docs/screenshots/1.webp\" alt=\"App overview\" /\u003e\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003ca href=\"docs/screenshots/2.webp\"\u003e\u003cimg src=\"docs/screenshots/2.webp\" alt=\"Store listing\" /\u003e\u003c/a\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ca href=\"docs/screenshots/3.webp\"\u003e\u003cimg src=\"docs/screenshots/3.webp\" alt=\"Screenshots\" /\u003e\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003ca href=\"docs/screenshots/4.webp\"\u003e\u003cimg src=\"docs/screenshots/4.webp\" alt=\"TestFlight builds\" /\u003e\u003c/a\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ca href=\"docs/screenshots/5.webp\"\u003e\u003cimg src=\"docs/screenshots/5.webp\" alt=\"Analytics\" /\u003e\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003ca href=\"docs/screenshots/6.webp\"\u003e\u003cimg src=\"docs/screenshots/6.webp\" alt=\"Customer reviews\" /\u003e\u003c/a\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n## Features\n\n**Release management** – edit descriptions, keywords, what's new, promotional text, names, and subtitles for every locale. Pick builds, choose release method (manual, automatic, or scheduled), toggle phased rollout. Save everything in one click.\n\n**AI-powered localisation** – translate any field or all fields to one locale or every locale simultaneously. Generate optimised keywords. Draft professional review replies. Translate foreign reviews. Generate appeal text for unfair ratings. Bring your own API key from Anthropic, OpenAI, Google, xAI, Mistral, or DeepSeek.\n\n**TestFlight** – manage builds, beta groups, and testers in one interface. Add or remove builds from groups in bulk. Track installs, sessions, and crashes per build. Review tester feedback with device details and screenshots. Mark feedback as done.\n\n**Analytics** – impressions, downloads, proceeds, first-time downloads, sessions, crashes, and conversion funnel. Compare periods, break down by territory, track version adoption. Acquisition sources, usage patterns, and crash reports across separate tabs.\n\n**Keyword optimisation** – track keyword character budgets per locale and storefront. Detect duplicates between name, subtitle, and keyword fields within a locale and across locales. One-click fix suggestions help maximise coverage and ranking across every market.\n\n**Customer reviews** – filter by rating, territory, or response status. Translate foreign-language reviews with one click. Draft replies with AI, automatically matching the reviewer's language. Edit and delete existing responses.\n\n**Screenshots** – upload, reorder with drag-and-drop, preview in lightbox, and delete screenshots across all device categories (iPhone, iPad, Mac, Apple TV, Apple Watch, Apple Vision) and locales. Translate screenshots to any locale using Gemini 3 Pro Image – the AI translates marketing text while preserving fonts and layout. Copy base locale screenshots to other locales without translation. Locale picker shows which locales have screenshots at a glance.\n\n**Nominations** – browse, edit, and submit App Store nominations. AI-powered fill generates nomination answers from your app metadata with one click.\n\n**Dark mode** – full light and dark theme support, follows your system appearance or can be set manually.\n\n**Self-hosted Docker** – run Itsyconnect as a web app on your local network or server. One command to start, auto-generated encryption key, persistent SQLite volume. See [self-hosting with Docker](#self-hosting-with-docker).\n\n**Diff mode** – opt-in setting that accumulates store listing, app details, app review, and keyword changes locally instead of saving to App Store Connect immediately. Review a full before/after diff across all sections and locales, discard individual fields, then push everything in one go.\n\n**MCP server** – optional [Model Context Protocol](https://modelcontextprotocol.io) server lets AI coding tools (Claude Code, Codex, Cursor, OpenCode) manage your app listings directly. Update release notes, translate fields, add locales – all from your terminal. Respects diff mode when enabled. See [docs/MCP.md](docs/MCP.md).\n\n**Privacy and security** – local-first architecture. All data stays on your Mac in a single SQLite file. Credentials encrypted with AES-256-GCM envelope encryption, master key stored in the macOS Keychain. No cloud, no accounts, no telemetry.\n\n## Free vs Pro\n\nItsyconnect is free to use with one app and one developer account. A one-time Pro upgrade removes all limits – unlimited apps and accounts.\n\n| | Free | Pro |\n|---|---|---|\n| Apps | 1 | Unlimited |\n| Developer accounts | 1 | Unlimited |\n| All features | Yes | Yes |\n| Price | Free | One-time purchase |\n\n**Direct distribution** – licences are handled via [LemonSqueezy](https://store.itsyapps.com) (key-based activation).\n\n**Mac App Store** – Pro is available as a StoreKit in-app purchase (non-consumable, one-time).\n\n## Quick start\n\n```bash\ngit clone https://github.com/nickustinov/itsyconnect-macos.git\ncd itsyconnect-macos\nnpm install\nnpm run electron:dev\n```\n\nThe setup wizard will guide you through connecting your App Store Connect credentials.\n\n## Self-hosting with Docker\n\nRun Itsyconnect as a web app on your local network or server.\n\n```bash\ndocker run -d -p 3000:3000 -v itsyconnect-data:/app/data ghcr.io/nickustinov/itsyconnect:latest\n```\n\nOr with docker compose:\n\n```bash\ndocker compose up -d\n```\n\nThe app will be available at `http://localhost:3000`. A master encryption key is auto-generated and saved to the data volume on first run.\n### Reverse proxy with authentication\n\nThe Docker container has no built-in authentication. If you expose it beyond your local machine, put it behind a reverse proxy with basic auth.\n\n**Caddy** (recommended – automatic HTTPS):\n\n```\nitsyconnect.example.com {\n    basicauth {\n        admin $2a$14$... # caddy hash-password\n    }\n    reverse_proxy localhost:3000\n}\n```\n\nGenerate a password hash with `caddy hash-password`, then paste it into the Caddyfile.\n\n**Nginx:**\n\n```nginx\nserver {\n    listen 443 ssl;\n    server_name itsyconnect.example.com;\n\n    auth_basic \"Itsyconnect\";\n    auth_basic_user_file /etc/nginx/.htpasswd;\n\n    location / {\n        proxy_pass http://localhost:3000;\n        proxy_set_header Host $host;\n        proxy_set_header X-Real-IP $remote_addr;\n    }\n}\n```\n\nGenerate credentials with `htpasswd -c /etc/nginx/.htpasswd admin`.\n\n**Tailscale** – if you just want access from your own devices without exposing anything to the public internet, put the machine on your tailnet and access it via the Tailscale IP. No auth config needed.\n\n### Data persistence\n\nAll data (SQLite database, master key) is stored in the `/app/data` volume. Back up this directory to preserve your configuration and cached analytics.\n\n## Development\n\n```bash\nnpm run electron:dev          # Launch Electron with hot reload\nnpm run electron:make:dmg     # Build signed DMG (direct distribution)\nnpm run electron:make:mas     # Build for Mac App Store (MAS=1)\nnpm run test                  # Run tests\nnpm run test:watch            # Watch mode\nnpm run test:coverage         # Coverage report\nnpm run db:generate           # Generate Drizzle migration\nnpm run db:studio             # Drizzle Studio\nnpm run lint                  # ESLint\n```\n\n### MAS builds\n\nThe `MAS=1` environment variable switches the app from LemonSqueezy to StoreKit for the Pro upgrade. It is set automatically by the `electron:make:mas` script.\n\nTo test MAS mode during development:\n\n```bash\nMAS=1 npm run electron:dev\n```\n\nThis shows the StoreKit UI (buy/restore buttons) on the licence page instead of the LemonSqueezy key input. The auto-updater is disabled in MAS mode.\n\n### Build flags\n\n| Flag | Purpose |\n|---|---|\n| `MAS=1` | Switch to StoreKit IAP, disable auto-updater, use MAS entitlements. Set automatically by `electron:make:mas`. |\n| `MAS_DEV=1` | Sign with Apple Development cert + dev provisioning profile (for local testing). Without this, the build uses the 3rd Party Mac Developer Application cert + distribution profile (for App Store submission). |\n\n### Provisioning profiles\n\nTwo provisioning profiles are needed in the project root (both gitignored):\n\n| File | Type | When to use |\n|---|---|---|\n| `provisioning.dev.provisionprofile` | macOS App Development | Local testing (`MAS_DEV=1`) |\n| `provisioning.dist.provisionprofile` | Mac App Distribution | App Store submission |\n\nCreate both in the [Apple Developer portal](https://developer.apple.com/account/resources/profiles/) under Provisioning Profiles, selecting the `com.itsyconnect.app` App ID and the matching certificate.\n\n### Building and testing MAS locally\n\n```bash\n# Build with dev signing (runs locally)\nMAS_DEV=1 npm run electron:make:mas\n\n# Open the built app\nopen out/Itsyconnect-darwin-arm64/Itsyconnect.app\n```\n\n### Building for App Store submission\n\n```bash\n# Build with distribution signing\nnpm run electron:make:mas\n\n# Submit via Transporter or altool\nxcrun altool --upload-app -f out/make/*.pkg -u you@example.com\n```\n\n### Testing the StoreKit API locally\n\nWhile running `MAS=1 npm run electron:dev`, you can simulate StoreKit activations via curl:\n\n```bash\n# Activate (simulates a successful purchase)\ncurl -X POST http://127.0.0.1:3000/api/license/storekit \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"transactionId\": \"test-txn-123\"}'\n\n# Check licence status\ncurl http://127.0.0.1:3000/api/license\n\n# Deactivate\ncurl -X DELETE http://127.0.0.1:3000/api/license/storekit\n```\n\n### Testing real StoreKit purchases\n\nReal purchases require a signed MAS build and an Apple sandbox tester:\n\n1. Register the product `com.itsyconnect.app.pro` (non-consumable) in App Store Connect\n2. Create a sandbox tester under Users and Access → Sandbox\n3. Build with `MAS_DEV=1 npm run electron:make:mas`\n4. Run the signed build, sign into the sandbox account when prompted, then purchase\n\n## Architecture\n\n```\nElectron app\n├── electron/main.ts      → main process (Keychain, server, window)\n├── electron/preload.ts   → minimal context bridge (no FS access)\n├── src/proxy.ts          → request interception (replaces middleware.ts)\n├── src/app/api/*         → REST API routes (Next.js 16)\n├── src/lib/asc/*         → App Store Connect API client\n├── src/lib/ai/*          → AI prompt templates and streaming\n├── src/db/*              → Drizzle ORM + SQLite (WAL mode)\n└── ~/Library/Application Support/Itsyconnect/\n    ├── itsyconnect.db    → SQLite database\n    └── master-key.enc    → Keychain-encrypted master key\n```\n\n**Stack:** Electron 40 · Next.js 16 · React 19 · TypeScript · Tailwind v4 · shadcn/ui · Phosphor Icons · Geist font · SQLite via better-sqlite3 · Drizzle ORM · Recharts · dnd-kit · Zod · Vercel AI SDK · AES-256-GCM envelope encryption · macOS Keychain\n\n## Releasing a new version\n\n### Direct distribution\n\nThe app auto-updates via [update.electronjs.org](https://update.electronjs.org), which reads from public GitHub Releases.\n\n1. Bump `APP_VERSION` and `BUILD_NUMBER` in `src/lib/version.ts`, and `\"version\"` in `package.json`\n2. Commit and push\n3. Run the release script (builds, signs, notarizes, creates a draft GitHub release):\n   ```bash\n   APPLE_ID=you@example.com APPLE_ID_PASSWORD=xxxx-xxxx-xxxx-xxxx APPLE_TEAM_ID=XXXXXXXXXX \\\n     ./scripts/build-release.sh\n   ```\n4. Review the draft release on GitHub, edit release notes, then click **Publish**\n5. `update.electronjs.org` picks up the new release – existing users are prompted to restart and update\n\nUsers can also check manually via **Itsyconnect \u003e Check for updates…** in the menu bar.\n\n### Mac App Store\n\nMAS builds use Apple's distribution signing and skip notarization (Apple reviews MAS apps separately). The auto-updater is disabled – updates go through the App Store.\n\n```bash\nnpm run electron:make:mas\n```\n\nSubmit the resulting package via Transporter or `xcrun altool`.\n\n## License\n\n[AGPL-3.0](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnickustinov%2Fitsyconnect-macos","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnickustinov%2Fitsyconnect-macos","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnickustinov%2Fitsyconnect-macos/lists"}