diff --git a/.env.example b/.env.example index 6293848c..010e0883 100644 --- a/.env.example +++ b/.env.example @@ -28,7 +28,7 @@ VITE_POSTHOG_HOST=https://us.i.posthog.com # Set this in hosted builds to use a private feedback channel # VITE_FEEDBACK_URL=https://discord.gg/your-private-invite -# API URL (optional - defaults to https://21st.dev) +# API URL (optional - defaults to https://getcrunch.dev) # Only change this if you're running the web app locally # MAIN_VITE_API_URL=http://localhost:3000 diff --git a/.gitignore b/.gitignore index 54d8ce1a..240e2029 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,9 @@ electron.vite.config.*.mjs # Claude binary (downloaded at build time) resources/bin/ + +# Test data (local testing only) +test-data/ + +# Claude Code local config +.claude/ diff --git a/CLAUDE.md b/CLAUDE.md index d41a54ea..3451e8fd 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -23,7 +23,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## What is this? -**21st Agents** - A local-first Electron desktop app for AI-powered code assistance. Users create chat sessions linked to local project folders, interact with Claude in Plan or Agent mode, and see real-time tool execution (bash, file edits, web search, etc.). +**Crunch** - A local-first Electron desktop app for AI-powered code assistance. Users create chat sessions linked to local project folders, interact with Claude in Plan or Agent mode, and see real-time tool execution (bash, file edits, web search, etc.). ## Commands @@ -165,8 +165,8 @@ rm -rf ~/Library/Application\ Support/Agents\ Dev/ /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -kill -r -domain local -domain system -domain user # 3. Clear app preferences -defaults delete dev.21st.agents.dev # Dev mode -defaults delete dev.21st.agents # Production +defaults delete dev.getcrunch.app.dev # Dev mode +defaults delete dev.getcrunch.app # Production # 4. Run in dev mode with clean state cd apps/desktop @@ -178,7 +178,7 @@ bun run dev - **Folder dialog not appearing**: Window focus timing issues on first launch. Fixed by ensuring window focus before showing `dialog.showOpenDialog()`. **Dev vs Production App:** -- Dev mode uses `twentyfirst-agents-dev://` protocol +- Dev mode uses `crunch-dev://` protocol - Dev mode uses separate userData path (`~/Library/Application Support/Agents Dev/`) - This prevents conflicts between dev and production installs @@ -186,8 +186,8 @@ bun run dev ### Prerequisites for Notarization -- Keychain profile: `21st-notarize` -- Create with: `xcrun notarytool store-credentials "21st-notarize" --apple-id YOUR_APPLE_ID --team-id YOUR_TEAM_ID` +- Keychain profile: `crunch-notarize` +- Create with: `xcrun notarytool store-credentials "crunch-notarize" --apple-id YOUR_APPLE_ID --team-id YOUR_TEAM_ID` ### Release Commands @@ -210,7 +210,7 @@ npm version patch --no-git-tag-version # 0.0.27 → 0.0.28 ### After Release Script Completes -1. Wait for notarization (2-5 min): `xcrun notarytool history --keychain-profile "21st-notarize"` +1. Wait for notarization (2-5 min): `xcrun notarytool history --keychain-profile "crunch-notarize"` 2. Staple DMGs: `cd release && xcrun stapler staple *.dmg` 3. Re-upload stapled DMGs to R2 and GitHub (see RELEASE.md for commands) 4. Update changelog: `gh release edit v0.0.X --notes "..."` @@ -223,14 +223,14 @@ npm version patch --no-git-tag-version # 0.0.27 → 0.0.28 |------|---------| | `latest-mac.yml` | Manifest for arm64 auto-updates | | `latest-mac-x64.yml` | Manifest for Intel auto-updates | -| `1Code-{version}-arm64-mac.zip` | Auto-update payload (arm64) | -| `1Code-{version}-mac.zip` | Auto-update payload (Intel) | -| `1Code-{version}-arm64.dmg` | Manual download (arm64) | -| `1Code-{version}.dmg` | Manual download (Intel) | +| `Crunch-{version}-arm64-mac.zip` | Auto-update payload (arm64) | +| `Crunch-{version}-mac.zip` | Auto-update payload (Intel) | +| `Crunch-{version}-arm64.dmg` | Manual download (arm64) | +| `Crunch-{version}.dmg` | Manual download (Intel) | ### Auto-Update Flow -1. App checks `https://cdn.21st.dev/releases/desktop/latest-mac.yml` on startup and when window regains focus (with 1 min cooldown) +1. App checks `https://cdn.getcrunch.dev/releases/desktop/latest-mac.yml` on startup and when window regains focus (with 1 min cooldown) 2. If version in manifest > current version, shows "Update Available" banner 3. User clicks Download → downloads ZIP in background 4. User clicks "Restart Now" → installs update and restarts diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0ca96280..45ff78d5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ -# Contributing to 1Code +# Contributing to Crunch ## Building from Source @@ -13,9 +13,9 @@ bun run package:mac # Create distributable ## Open Source vs Hosted Version -This is the open-source version of 1Code. Some features require the hosted backend at 1code.dev: +This is the open-source version of Crunch. Some features require the hosted backend at getcrunch.dev: -| Feature | Open Source | Hosted (1code.dev) | +| Feature | Open Source | Hosted (getcrunch.dev) | |---------|-------------|-------------------| | Local AI chat | Yes | Yes | | Claude Code integration | Yes | Yes | diff --git a/README.md b/README.md index 0a25e820..8050c43a 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,16 @@ -# 1Code +# Crunch -[1Code.dev](https://1code.dev) +[getcrunch.dev](https://getcrunch.dev) Best UI for Claude Code with local and remote agent execution. -By [21st.dev](https://21st.dev) team +By [getcrunch.dev](https://getcrunch.dev) team > **Platforms:** macOS, Linux, and Windows. Windows support improved thanks to community contributions from [@jesus-mgtc](https://github.com/jesus-mgtc) and [@evgyur](https://github.com/evgyur). -## 1Code vs Claude Code +## Crunch vs Claude Code -| Feature | 1Code | Claude Code | +| Feature | Crunch | Claude Code | |---------|-------|-------------| | **Visual UI** | ✅ Cursor-like desktop app | ✅ | | **Git Worktree Isolation** | ✅ Each chat runs in isolated worktree | ✅ | @@ -90,11 +90,11 @@ bun run package:mac # or package:win, package:linux > **Important:** The `claude:download` step downloads the Claude CLI binary which is required for the agent chat to work. If you skip this step, the app will build but agent functionality won't work. -### Option 2: Subscribe to 1code.dev (recommended) +### Option 2: Subscribe to getcrunch.dev (recommended) -Get pre-built releases + background agents support by subscribing at [1code.dev](https://1code.dev). +Get pre-built releases + background agents support by subscribing at [getcrunch.dev](https://getcrunch.dev). -Your subscription helps us maintain and improve 1Code. +Your subscription helps us maintain and improve Crunch. ## Development diff --git a/bun.lockb b/bun.lockb index b29263e1..45a6475b 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index 277f33b9..0bbf3781 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,11 @@ { - "name": "21st-desktop", + "name": "crunch-desktop", "version": "0.0.46", "private": true, - "description": "1Code - UI for parallel work with AI agents", + "description": "Crunch - UI for parallel work with AI agents", "author": { - "name": "21st.dev", - "email": "support@21st.dev" + "name": "getcrunch.dev", + "email": "support@getcrunch.dev" }, "main": "out/main/index.js", "scripts": { @@ -36,7 +36,9 @@ "@anthropic-ai/claude-agent-sdk": "^0.2.12", "@git-diff-view/react": "^0.0.35", "@git-diff-view/shiki": "^0.0.36", + "@glideapps/glide-data-grid": "^6.0.3", "@modelcontextprotocol/sdk": "^1.25.3", + "@monaco-editor/react": "^4.7.0", "@radix-ui/react-accordion": "^1.2.12", "@radix-ui/react-alert-dialog": "^1.1.15", "@radix-ui/react-checkbox": "^1.3.3", @@ -61,6 +63,7 @@ "@trpc/client": "^11.7.1", "@trpc/react-query": "^11.7.1", "@trpc/server": "^11.7.1", + "@types/lodash-es": "^4.17.12", "@xterm/addon-canvas": "^0.7.0", "@xterm/addon-fit": "^0.11.0", "@xterm/addon-search": "^0.16.0", @@ -74,15 +77,21 @@ "clsx": "^2.1.1", "date-fns": "^3.6.0", "drizzle-orm": "^0.45.1", + "duckdb": "^1.4.3", "electron-log": "^5.4.3", "electron-updater": "^6.7.3", "gray-matter": "^4.0.3", "jotai": "^2.11.1", + "jotai-family": "^1.0.1", + "lodash-es": "^4.17.22", "lucide-react": "^0.468.0", "mermaid": "^11.12.2", + "monaco-editor": "^0.55.1", "motion": "^11.15.0", "next-themes": "^0.4.4", "node-pty": "^1.1.0", + "papaparse": "^5.5.3", + "parquetjs-lite": "^0.8.7", "pidtree": "^0.6.0", "posthog-js": "^1.239.1", "posthog-node": "^5.20.0", @@ -103,6 +112,7 @@ "tailwindcss-animate": "^1.0.7", "trpc-electron": "^0.1.2", "unique-names-generator": "^4.7.1", + "xlsx": "^0.18.5", "xterm": "^5.3.0", "zod": "^3.24.1", "zustand": "^5.0.3" @@ -112,6 +122,7 @@ "@electron-toolkit/utils": "^4.0.0", "@types/better-sqlite3": "^7.6.13", "@types/node": "^20.17.50", + "@types/papaparse": "^5.5.2", "@types/react": "^19.0.7", "@types/react-dom": "^19.0.3", "@types/react-syntax-highlighter": "^15.5.13", @@ -129,14 +140,14 @@ "vite": "^6.3.4" }, "build": { - "appId": "dev.21st.agents", - "productName": "1Code", + "appId": "dev.getcrunch.app", + "productName": "Crunch", "npmRebuild": true, "protocols": [ { - "name": "1Code", + "name": "Crunch", "schemes": [ - "twentyfirst-agents" + "crunch" ] } ], @@ -194,7 +205,7 @@ "entitlements": "build/entitlements.mac.plist", "entitlementsInherit": "build/entitlements.mac.plist", "extendInfo": { - "NSMicrophoneUsageDescription": "1Code needs microphone access for voice dictation" + "NSMicrophoneUsageDescription": "Crunch needs microphone access for voice dictation" } }, "dmg": { @@ -240,7 +251,7 @@ }, "publish": { "provider": "generic", - "url": "https://cdn.21st.dev/releases/desktop" + "url": "https://cdn.getcrunch.dev/releases/desktop" } } } diff --git a/src/main/auth-manager.ts b/src/main/auth-manager.ts index e31b7bc1..2f13a641 100644 --- a/src/main/auth-manager.ts +++ b/src/main/auth-manager.ts @@ -5,9 +5,9 @@ import { AUTH_SERVER_PORT } from "./constants" // Get API URL - in packaged app always use production, in dev allow override function getApiBaseUrl(): string { if (app.isPackaged) { - return "https://21st.dev" + return "https://www.getcrunch.dev" } - return import.meta.env.MAIN_VITE_API_URL || "https://21st.dev" + return import.meta.env.MAIN_VITE_API_URL || "https://www.getcrunch.dev" } export class AuthManager { @@ -79,7 +79,7 @@ export class AuthManager { const platform = process.platform const arch = process.arch const version = app.getVersion() - return `21st Desktop ${version} (${platform} ${arch})` + return `Crunch Desktop ${version} (${platform} ${arch})` } /** @@ -216,7 +216,7 @@ export class AuthManager { if (this.isDev) { authUrl += `&callback=${encodeURIComponent(`http://localhost:${AUTH_SERVER_PORT}/auth/callback`)}` // Pass dev protocol so production web can use correct deep link if callback fails - authUrl += `&protocol=twentyfirst-agents-dev` + authUrl += `&protocol=crunch-dev` } shell.openExternal(authUrl) diff --git a/src/main/index.ts b/src/main/index.ts index 9c0bb912..969d389e 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -40,7 +40,7 @@ import { IS_DEV, AUTH_SERVER_PORT } from "./constants" // Deep link protocol (must match package.json build.protocols.schemes) // Use different protocol in dev to avoid conflicts with production app -const PROTOCOL = IS_DEV ? "twentyfirst-agents-dev" : "twentyfirst-agents" +const PROTOCOL = IS_DEV ? "crunch-dev" : "crunch" // Set dev mode userData path BEFORE requestSingleInstanceLock() // This ensures dev and prod have separate instance locks @@ -75,13 +75,13 @@ if (app.isPackaged && !IS_DEV) { // In dev mode, allow override via MAIN_VITE_API_URL env variable export function getBaseUrl(): string { if (app.isPackaged) { - return "https://21st.dev" + return "https://getcrunch.dev" } - return import.meta.env.MAIN_VITE_API_URL || "https://21st.dev" + return import.meta.env.MAIN_VITE_API_URL || "https://getcrunch.dev" } export function getAppUrl(): string { - return process.env.ELECTRON_RENDERER_URL || "https://21st.dev/agents" + return process.env.ELECTRON_RENDERER_URL || "https://getcrunch.dev/agents" } // Auth manager singleton (use the one from auth-manager module) @@ -185,7 +185,7 @@ function handleDeepLink(url: string): void { try { const parsed = new URL(url) - // Handle auth callback: twentyfirst-agents://auth?code=xxx + // Handle auth callback: crunch://auth?code=xxx if (parsed.pathname === "/auth" || parsed.host === "auth") { const code = parsed.searchParams.get("code") if (code) { @@ -194,7 +194,7 @@ function handleDeepLink(url: string): void { } } - // Handle MCP OAuth callback: twentyfirst-agents://mcp-oauth?code=xxx&state=yyy + // Handle MCP OAuth callback: crunch://mcp-oauth?code=xxx&state=yyy if (parsed.pathname === "/mcp-oauth" || parsed.host === "mcp-oauth") { const code = parsed.searchParams.get("code") const state = parsed.searchParams.get("state") @@ -310,7 +310,7 @@ const server = createServer((req, res) => {
-