Repository: winfunc/opcode Branch: main Commit: 70c16d8a4910 Files: 179 Total size: 1.8 MB Directory structure: gitextract_3l4qo4o3/ ├── .cargo/ │ └── config.toml ├── .github/ │ └── workflows/ │ ├── build-linux.yml │ ├── build-macos.yml │ ├── build-test.yml │ ├── claude-code-review.yml │ ├── claude.yml │ ├── pr-check.yml │ └── release.yml ├── .gitignore ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── bun.lockb ├── cc_agents/ │ ├── README.md │ ├── git-commit-bot.opcode.json │ ├── security-scanner.opcode.json │ └── unit-tests-bot.opcode.json ├── index.html ├── justfile ├── package.json ├── scripts/ │ └── bump-version.sh ├── shell.nix ├── src/ │ ├── App.tsx │ ├── assets/ │ │ ├── nfo/ │ │ │ └── opcode-nfo.ogg │ │ └── shimmer.css │ ├── components/ │ │ ├── AgentExecution.tsx │ │ ├── AgentExecutionDemo.tsx │ │ ├── AgentRunOutputViewer.tsx │ │ ├── AgentRunView.tsx │ │ ├── AgentRunsList.tsx │ │ ├── Agents.tsx │ │ ├── AgentsModal.tsx │ │ ├── AnalyticsConsent.tsx │ │ ├── AnalyticsErrorBoundary.tsx │ │ ├── App.cleaned.tsx │ │ ├── CCAgents.tsx │ │ ├── CheckpointSettings.tsx │ │ ├── ClaudeBinaryDialog.tsx │ │ ├── ClaudeCodeSession.refactored.tsx │ │ ├── ClaudeCodeSession.tsx │ │ ├── ClaudeFileEditor.tsx │ │ ├── ClaudeMemoriesDropdown.tsx │ │ ├── ClaudeVersionSelector.tsx │ │ ├── CreateAgent.tsx │ │ ├── CustomTitlebar.tsx │ │ ├── ErrorBoundary.tsx │ │ ├── ExecutionControlBar.tsx │ │ ├── FilePicker.optimized.tsx │ │ ├── FilePicker.tsx │ │ ├── FloatingPromptInput.tsx │ │ ├── GitHubAgentBrowser.tsx │ │ ├── HooksEditor.tsx │ │ ├── IconPicker.tsx │ │ ├── ImagePreview.tsx │ │ ├── MCPAddServer.tsx │ │ ├── MCPImportExport.tsx │ │ ├── MCPManager.tsx │ │ ├── MCPServerList.tsx │ │ ├── MarkdownEditor.tsx │ │ ├── NFOCredits.tsx │ │ ├── PreviewPromptDialog.tsx │ │ ├── ProjectList.tsx │ │ ├── ProjectSettings.tsx │ │ ├── ProxySettings.tsx │ │ ├── RunningClaudeSessions.tsx │ │ ├── SessionList.optimized.tsx │ │ ├── SessionList.tsx │ │ ├── SessionOutputViewer.tsx │ │ ├── Settings.tsx │ │ ├── SlashCommandPicker.tsx │ │ ├── SlashCommandsManager.tsx │ │ ├── StartupIntro.tsx │ │ ├── StorageTab.tsx │ │ ├── StreamMessage.tsx │ │ ├── TabContent.tsx │ │ ├── TabManager.tsx │ │ ├── TimelineNavigator.tsx │ │ ├── TokenCounter.tsx │ │ ├── ToolWidgets.new.tsx │ │ ├── ToolWidgets.tsx │ │ ├── Topbar.tsx │ │ ├── UsageDashboard.original.tsx │ │ ├── UsageDashboard.tsx │ │ ├── WebviewPreview.tsx │ │ ├── claude-code-session/ │ │ │ ├── MessageList.tsx │ │ │ ├── PromptQueue.tsx │ │ │ ├── SessionHeader.tsx │ │ │ ├── useCheckpoints.ts │ │ │ └── useClaudeMessages.ts │ │ ├── index.ts │ │ ├── ui/ │ │ │ ├── badge.tsx │ │ │ ├── button.tsx │ │ │ ├── card.tsx │ │ │ ├── dialog.tsx │ │ │ ├── dropdown-menu.tsx │ │ │ ├── input.tsx │ │ │ ├── label.tsx │ │ │ ├── pagination.tsx │ │ │ ├── popover.tsx │ │ │ ├── radio-group.tsx │ │ │ ├── scroll-area.tsx │ │ │ ├── select.tsx │ │ │ ├── split-pane.tsx │ │ │ ├── switch.tsx │ │ │ ├── tabs.tsx │ │ │ ├── textarea.tsx │ │ │ ├── toast.tsx │ │ │ ├── tooltip-modern.tsx │ │ │ └── tooltip.tsx │ │ └── widgets/ │ │ ├── BashWidget.tsx │ │ ├── LSWidget.tsx │ │ ├── TodoWidget.tsx │ │ └── index.ts │ ├── contexts/ │ │ ├── TabContext.tsx │ │ └── ThemeContext.tsx │ ├── hooks/ │ │ ├── index.ts │ │ ├── useAnalytics.ts │ │ ├── useApiCall.ts │ │ ├── useDebounce.ts │ │ ├── useLoadingState.ts │ │ ├── usePagination.ts │ │ ├── usePerformanceMonitor.ts │ │ ├── useTabState.ts │ │ └── useTheme.ts │ ├── lib/ │ │ ├── analytics/ │ │ │ ├── consent.ts │ │ │ ├── events.ts │ │ │ ├── index.ts │ │ │ ├── resourceMonitor.ts │ │ │ └── types.ts │ │ ├── api-tracker.ts │ │ ├── api.ts │ │ ├── apiAdapter.ts │ │ ├── claudeSyntaxTheme.ts │ │ ├── date-utils.ts │ │ ├── hooksManager.ts │ │ ├── linkDetector.tsx │ │ ├── outputCache.tsx │ │ └── utils.ts │ ├── main.tsx │ ├── services/ │ │ ├── sessionPersistence.ts │ │ └── tabPersistence.ts │ ├── stores/ │ │ ├── README.md │ │ ├── agentStore.ts │ │ └── sessionStore.ts │ ├── styles.css │ ├── types/ │ │ └── hooks.ts │ └── vite-env.d.ts ├── src-tauri/ │ ├── .gitignore │ ├── Cargo.toml │ ├── Info.plist │ ├── build.rs │ ├── capabilities/ │ │ └── default.json │ ├── entitlements.plist │ ├── icons/ │ │ └── icon.icns │ ├── src/ │ │ ├── checkpoint/ │ │ │ ├── manager.rs │ │ │ ├── mod.rs │ │ │ ├── state.rs │ │ │ └── storage.rs │ │ ├── claude_binary.rs │ │ ├── commands/ │ │ │ ├── agents.rs │ │ │ ├── claude.rs │ │ │ ├── mcp.rs │ │ │ ├── mod.rs │ │ │ ├── proxy.rs │ │ │ ├── slash_commands.rs │ │ │ ├── storage.rs │ │ │ └── usage.rs │ │ ├── lib.rs │ │ ├── main.rs │ │ ├── process/ │ │ │ ├── mod.rs │ │ │ └── registry.rs │ │ ├── web_main.rs │ │ └── web_server.rs │ ├── tauri.conf.json │ └── tests/ │ └── TESTS_COMPLETE.md ├── tsconfig.json ├── tsconfig.node.json ├── vite.config.ts └── web_server.design.md ================================================ FILE CONTENTS ================================================ ================================================ FILE: .cargo/config.toml ================================================ [target.aarch64-unknown-linux-gnu] linker = "aarch64-linux-gnu-gcc" [env] PKG_CONFIG_ALLOW_CROSS = "1" ================================================ FILE: .github/workflows/build-linux.yml ================================================ name: Build Linux on: workflow_call: workflow_dispatch: push: branches: [main] jobs: build: name: Build Linux x86_64 runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Install system dependencies run: | sudo apt-get update sudo apt-get install -y \ pkg-config \ libwebkit2gtk-4.1-dev \ libgtk-3-dev \ libssl-dev \ libayatana-appindicator3-dev \ librsvg2-dev - name: Setup Rust uses: dtolnay/rust-toolchain@stable with: targets: x86_64-unknown-linux-gnu - name: Setup Rust cache uses: Swatinem/rust-cache@v2 with: workspaces: src-tauri - name: Setup Bun uses: oven-sh/setup-bun@v2 - name: Install dependencies run: bun install - name: Build Tauri app run: bun run tauri build --target x86_64-unknown-linux-gnu - name: Create artifacts directory run: | mkdir -p dist/linux-x86_64 cp src-tauri/target/x86_64-unknown-linux-gnu/release/bundle/deb/*.deb dist/linux-x86_64/ || true cp src-tauri/target/x86_64-unknown-linux-gnu/release/bundle/appimage/*.AppImage dist/linux-x86_64/ || true # Generate checksums cd dist/linux-x86_64 sha256sum * > checksums.txt - name: Upload artifacts uses: actions/upload-artifact@v4 with: name: linux-x86_64 path: dist/linux-x86_64/* ================================================ FILE: .github/workflows/build-macos.yml ================================================ name: Build macOS on: workflow_call: secrets: APPLE_CERTIFICATE: required: true APPLE_CERTIFICATE_PASSWORD: required: true KEYCHAIN_PASSWORD: required: true APPLE_SIGNING_IDENTITY: required: true APPLE_ID: required: true APPLE_TEAM_ID: required: true APPLE_PASSWORD: required: true workflow_dispatch: inputs: skip_build: description: 'Skip build and use artifacts from a previous run' required: false default: false type: boolean run_id: description: 'Run ID to download artifacts from (leave empty for latest)' required: false type: string push: branches: [main] jobs: build: name: Build macOS ${{ matrix.target }} if: ${{ !inputs.skip_build }} runs-on: ${{ matrix.os }} strategy: matrix: include: - os: macos-13 # Intel target: x86_64-apple-darwin arch: x86_64 - os: macos-14 # Apple Silicon target: aarch64-apple-darwin arch: aarch64 steps: - uses: actions/checkout@v4 - name: Setup Rust uses: dtolnay/rust-toolchain@stable - name: Setup Rust cache uses: Swatinem/rust-cache@v2 with: workspaces: src-tauri - name: Setup Bun uses: oven-sh/setup-bun@v2 - name: Install dependencies run: bun install - name: Import Apple certificates env: APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} run: | # Create variables CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12 KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db # Import certificate from secrets echo -n "$APPLE_CERTIFICATE" | base64 --decode -o $CERTIFICATE_PATH # Create temporary keychain security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH security set-keychain-settings -lut 21600 $KEYCHAIN_PATH security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH # Import certificate to keychain security import $CERTIFICATE_PATH -P "$APPLE_CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH security list-keychain -d user -s $KEYCHAIN_PATH - name: Build native env: CI: true run: bun run tauri build - name: Upload architecture-specific artifacts uses: actions/upload-artifact@v4 with: name: macos-${{ matrix.arch }} path: | src-tauri/target/release/bundle/macos/opcode.app src-tauri/target/release/bundle/dmg/*.dmg retention-days: 1 universal: name: Create Universal Binary needs: [build] if: ${{ !cancelled() && (needs.build.result == 'success' || needs.build.result == 'skipped') }} runs-on: macos-latest steps: - uses: actions/checkout@v4 - name: Download artifacts from current workflow if: ${{ !inputs.skip_build }} uses: actions/download-artifact@v4 with: pattern: macos-* path: artifacts - name: Download artifacts from specific run if: ${{ inputs.skip_build && inputs.run_id != '' }} uses: dawidd6/action-download-artifact@v3 with: workflow: build-macos.yml run_id: ${{ inputs.run_id }} name: macos-* path: artifacts - name: Download artifacts from latest run if: ${{ inputs.skip_build && inputs.run_id == '' }} uses: dawidd6/action-download-artifact@v3 with: workflow: build-macos.yml workflow_conclusion: success name: macos-* path: artifacts - name: List downloaded artifacts run: | echo "📁 Artifact structure:" find artifacts -type f -name "*.app" -o -name "*.dmg" | head -20 echo "" echo "📁 Full directory structure:" ls -la artifacts/ ls -la artifacts/macos-aarch64/ || echo "macos-aarch64 directory not found" ls -la artifacts/macos-x86_64/ || echo "macos-x86_64 directory not found" - name: Import Apple certificates env: APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} run: | # Create variables CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12 KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db # Import certificate from secrets echo -n "$APPLE_CERTIFICATE" | base64 --decode -o $CERTIFICATE_PATH # Create temporary keychain security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH security set-keychain-settings -lut 21600 $KEYCHAIN_PATH security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH # Import certificate to keychain security import $CERTIFICATE_PATH -P "$APPLE_CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH security list-keychain -d user -s $KEYCHAIN_PATH - name: Create universal app run: | # Create temp directory mkdir -p dmg_temp # Extract zip files if they exist if [ -f "artifacts/macos-aarch64.zip" ]; then echo "📦 Extracting macos-aarch64.zip..." unzip -q artifacts/macos-aarch64.zip -d artifacts/macos-aarch64/ fi if [ -f "artifacts/macos-x86_64.zip" ]; then echo "📦 Extracting macos-x86_64.zip..." unzip -q artifacts/macos-x86_64.zip -d artifacts/macos-x86_64/ fi # Find the actual app paths AARCH64_APP=$(find artifacts/macos-aarch64 -name "opcode.app" -type d | head -1) X86_64_APP=$(find artifacts/macos-x86_64 -name "opcode.app" -type d | head -1) if [ -z "$AARCH64_APP" ] || [ -z "$X86_64_APP" ]; then echo "❌ Could not find app bundles" echo "AARCH64_APP: $AARCH64_APP" echo "X86_64_APP: $X86_64_APP" exit 1 fi echo "✅ Found app bundles:" echo " ARM64: $AARCH64_APP" echo " x86_64: $X86_64_APP" # Copy ARM64 app as base cp -R "$AARCH64_APP" dmg_temp/ # Create universal binary using lipo lipo -create -output dmg_temp/opcode.app/Contents/MacOS/opcode \ "$AARCH64_APP/Contents/MacOS/opcode" \ "$X86_64_APP/Contents/MacOS/opcode" # Ensure executable permissions are set chmod +x dmg_temp/opcode.app/Contents/MacOS/opcode echo "✅ Universal binary created" lipo -info dmg_temp/opcode.app/Contents/MacOS/opcode - name: Sign app bundle env: APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }} run: | codesign --sign "$APPLE_SIGNING_IDENTITY" \ --timestamp \ --options runtime \ --force \ --deep \ --entitlements src-tauri/entitlements.plist \ dmg_temp/opcode.app - name: Create DMG run: | hdiutil create -volname "opcode Installer" \ -srcfolder dmg_temp \ -ov -format UDZO opcode.dmg - name: Sign DMG env: APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }} run: | codesign --sign "$APPLE_SIGNING_IDENTITY" \ --timestamp \ --force opcode.dmg - name: Notarize DMG env: APPLE_ID: ${{ secrets.APPLE_ID }} APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }} run: | # Store notarization credentials xcrun notarytool store-credentials "notarytool-profile" \ --apple-id "$APPLE_ID" \ --team-id "$APPLE_TEAM_ID" \ --password "$APPLE_PASSWORD" # Submit for notarization xcrun notarytool submit opcode.dmg \ --keychain-profile "notarytool-profile" \ --wait - name: Staple notarization run: xcrun stapler staple opcode.dmg - name: Verify DMG run: | spctl -a -t open -vvv --context context:primary-signature opcode.dmg echo "✅ DMG verification complete" - name: Create artifacts directory run: | mkdir -p dist/macos-universal cp opcode.dmg dist/macos-universal/ # Also save the app bundle using ditto to preserve permissions and signatures ditto -c -k --sequesterRsrc --keepParent \ dmg_temp/opcode.app dist/macos-universal/opcode.app.zip # Generate checksum shasum -a 256 dist/macos-universal/* > dist/macos-universal/checksums.txt - name: Upload artifacts uses: actions/upload-artifact@v4 with: name: macos-universal path: dist/macos-universal/* - name: Cleanup if: always() run: | echo "🧹 Cleaning up temporary directories..." rm -rf dmg_temp temp_x86 artifacts # Clean up keychain if [ -n "$RUNNER_TEMP" ] && [ -f "$RUNNER_TEMP/app-signing.keychain-db" ]; then security delete-keychain "$RUNNER_TEMP/app-signing.keychain-db" || true fi echo "✅ Cleanup complete" ================================================ FILE: .github/workflows/build-test.yml ================================================ name: Build Test # Trigger on every push and pull request on: push: branches: [ main, develop, 'release/**', 'feature/**' ] pull_request: branches: [ main, develop ] types: [opened, synchronize, reopened] # Cancel in-progress workflows when a new commit is pushed concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true env: CARGO_TERM_COLOR: always RUST_BACKTRACE: 1 jobs: build-test: name: Build Test (${{ matrix.platform.name }}) strategy: fail-fast: false matrix: platform: - name: Linux os: ubuntu-latest rust-target: x86_64-unknown-linux-gnu - name: Linux ARM64 os: ubuntu-24.04-arm64 rust-target: aarch64-unknown-linux-gnu - name: Windows os: windows-latest rust-target: x86_64-pc-windows-msvc - name: macOS os: macos-latest rust-target: x86_64-apple-darwin runs-on: ${{ matrix.platform.os }} steps: # Checkout the repository - name: Checkout repository uses: actions/checkout@v4 with: fetch-depth: 0 # Install system dependencies for Linux - name: Install Linux dependencies if: matrix.platform.os == 'ubuntu-latest' run: | sudo apt-get update sudo apt-get install -y \ libwebkit2gtk-4.1-dev \ libgtk-3-dev \ libayatana-appindicator3-dev \ librsvg2-dev \ libssl-dev \ libglib2.0-dev \ libjavascriptcoregtk-4.1-dev \ libsoup-3.0-dev \ libxdo-dev \ libxcb-shape0-dev \ libxcb-xfixes0-dev # Setup Rust with caching - name: Setup Rust uses: dtolnay/rust-toolchain@stable with: targets: ${{ matrix.platform.rust-target }} # Cache Rust dependencies - name: Cache Rust dependencies uses: Swatinem/rust-cache@v2 with: workspaces: './src-tauri -> target' key: ${{ matrix.platform.os }}-rust-${{ hashFiles('**/Cargo.lock') }} # Setup Bun - name: Setup Bun uses: oven-sh/setup-bun@v2 with: bun-version: latest # Cache Bun dependencies - name: Cache Bun dependencies uses: actions/cache@v4 with: path: | ~/.bun node_modules key: ${{ matrix.platform.os }}-bun-${{ hashFiles('bun.lockb', 'package.json') }} restore-keys: | ${{ matrix.platform.os }}-bun- # Install frontend dependencies - name: Install frontend dependencies run: bun install --frozen-lockfile # Build frontend - name: Build frontend run: bun run build # Build Tauri application - name: Build Tauri application run: bun run tauri build --no-bundle -d env: TAURI_SIGNING_PRIVATE_KEY: "" TAURI_SIGNING_PRIVATE_KEY_PASSWORD: "" # Upload build artifacts for debugging (optional) - name: Upload build logs on failure if: failure() uses: actions/upload-artifact@v4 with: name: build-logs-${{ matrix.platform.name }} path: | src-tauri/target/release/build/*/output src-tauri/target/debug/build/*/output retention-days: 3 # Summary job to ensure all builds pass build-test-summary: name: Build Test Summary runs-on: ubuntu-latest needs: [build-test] if: always() steps: - name: Check build results run: | if [[ "${{ needs.build-test.result }}" == "failure" ]]; then echo "❌ One or more build tests failed" exit 1 elif [[ "${{ needs.build-test.result }}" == "cancelled" ]]; then echo "⚠️ Build tests were cancelled" exit 1 else echo "✅ All build tests passed successfully" fi - name: Create status comment (PR only) if: github.event_name == 'pull_request' uses: actions/github-script@v7 with: script: | const result = '${{ needs.build-test.result }}'; const emoji = result === 'success' ? '✅' : '❌'; const status = result === 'success' ? 'All build tests passed!' : 'Build tests failed'; // Create a comment summarizing the build status const comment = `## ${emoji} Build Test Results **Status**: ${status} **Commit**: ${{ github.event.pull_request.head.sha || github.sha }} | Platform | Status | |----------|--------| | Linux | ${{ contains(needs.build-test.result, 'success') && '✅' || '❌' }} | | Windows | ${{ contains(needs.build-test.result, 'success') && '✅' || '❌' }} | | macOS | ${{ contains(needs.build-test.result, 'success') && '✅' || '❌' }} | [View full workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})`; // Only post comment if it's a PR if (context.eventName === 'pull_request') { await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, body: comment }); } ================================================ FILE: .github/workflows/claude-code-review.yml ================================================ name: Claude Code Review on: pull_request: types: [opened, synchronize] # Optional: Only run on specific file changes # paths: # - "src/**/*.ts" # - "src/**/*.tsx" # - "src/**/*.js" # - "src/**/*.jsx" jobs: claude-review: # Optional: Filter by PR author # if: | # github.event.pull_request.user.login == 'external-contributor' || # github.event.pull_request.user.login == 'new-developer' || # github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR' runs-on: ubuntu-latest permissions: contents: read pull-requests: read issues: read id-token: write steps: - name: Checkout repository uses: actions/checkout@v4 with: fetch-depth: 1 - name: Run Claude Code Review id: claude-review uses: anthropics/claude-code-action@v1 with: anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} prompt: | REPO: ${{ github.repository }} PR NUMBER: ${{ github.event.pull_request.number }} Please review this pull request and provide feedback on: - Code quality and best practices - Potential bugs or issues - Performance considerations - Security concerns - Test coverage Use the repository's CLAUDE.md for guidance on style and conventions. Be constructive and helpful in your feedback. Use `gh pr comment` with your Bash tool to leave your review as a comment on the PR. # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md # or https://docs.claude.com/en/docs/claude-code/cli-reference for available options claude_args: '--allowed-tools "Bash(gh issue view:*),Bash(gh search:*),Bash(gh issue list:*),Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr list:*)"' ================================================ FILE: .github/workflows/claude.yml ================================================ name: Claude Code on: issue_comment: types: [created] pull_request_review_comment: types: [created] issues: types: [opened, assigned] pull_request_review: types: [submitted] jobs: claude: if: | (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) || (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) || (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) || (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))) runs-on: ubuntu-latest permissions: contents: read pull-requests: read issues: read id-token: write actions: read # Required for Claude to read CI results on PRs steps: - name: Checkout repository uses: actions/checkout@v4 with: fetch-depth: 1 - name: Run Claude Code id: claude uses: anthropics/claude-code-action@v1 with: anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} # This is an optional setting that allows Claude to read CI results on PRs additional_permissions: | actions: read # Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it. # prompt: 'Update the pull request description to include a summary of changes.' # Optional: Add claude_args to customize behavior and configuration # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md # or https://docs.claude.com/en/docs/claude-code/cli-reference for available options # claude_args: '--allowed-tools Bash(gh pr:*)' ================================================ FILE: .github/workflows/pr-check.yml ================================================ name: PR Checks (bun run check) on: pull_request: types: [opened, synchronize, reopened, ready_for_review] permissions: contents: read pull-requests: read concurrency: group: pr-check-${{ github.workflow }}-${{ github.event.pull_request.head.sha || github.sha }} cancel-in-progress: true jobs: check: name: bun run check runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 - name: Set up Bun uses: oven-sh/setup-bun@v2 with: bun-version: latest - name: Cache Bun dependencies uses: actions/cache@v4 with: path: | ~/.bun/install/cache node_modules key: ${{ runner.os }}-bun-${{ hashFiles('bun.lock') }} restore-keys: | ${{ runner.os }}-bun- - name: Install JS/TS dependencies run: bun install --frozen-lockfile - name: Set up Rust (stable) uses: dtolnay/rust-toolchain@stable - name: Cache Rust dependencies uses: Swatinem/rust-cache@v2 with: workspaces: | src-tauri -> src-tauri/target cache-on-failure: true - name: Run checks run: bun run check ================================================ FILE: .github/workflows/release.yml ================================================ name: Release on: push: tags: - 'v*' workflow_dispatch: inputs: version: description: 'Version to release (e.g., v1.0.0)' required: true type: string permissions: contents: write jobs: # Build jobs for each platform build-linux: uses: ./.github/workflows/build-linux.yml secrets: inherit build-macos: uses: ./.github/workflows/build-macos.yml secrets: inherit # Create release after all builds complete create-release: name: Create Release needs: [build-linux, build-macos] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Determine version id: version run: | if [ "${{ github.event_name }}" = "push" ]; then VERSION="${GITHUB_REF#refs/tags/}" else VERSION="${{ inputs.version }}" fi echo "version=$VERSION" >> $GITHUB_OUTPUT echo "Version: $VERSION" - name: Download all artifacts uses: actions/download-artifact@v4 with: path: artifacts - name: Prepare release assets run: | mkdir -p release-assets # Linux artifacts if [ -d "artifacts/linux-x86_64" ]; then cp artifacts/linux-x86_64/*.deb release-assets/opcode_${{ steps.version.outputs.version }}_linux_x86_64.deb || true cp artifacts/linux-x86_64/*.AppImage release-assets/opcode_${{ steps.version.outputs.version }}_linux_x86_64.AppImage || true fi # macOS artifacts if [ -d "artifacts/macos-universal" ]; then cp artifacts/macos-universal/opcode.dmg release-assets/opcode_${{ steps.version.outputs.version }}_macos_universal.dmg || true cp artifacts/macos-universal/opcode.app.zip release-assets/opcode_${{ steps.version.outputs.version }}_macos_universal.app.tar.gz || true fi # Create source code archives # Clean version without 'v' prefix for archive names CLEAN_VERSION="${{ steps.version.outputs.version }}" CLEAN_VERSION="${CLEAN_VERSION#v}" # Create source code archives (excluding .git and other unnecessary files) echo "Creating source code archives..." # Create a clean export of the repository git archive --format=tar.gz --prefix=opcode-${CLEAN_VERSION}/ -o release-assets/opcode-${CLEAN_VERSION}.tar.gz HEAD git archive --format=zip --prefix=opcode-${CLEAN_VERSION}/ -o release-assets/opcode-${CLEAN_VERSION}.zip HEAD # Generate signatures for all files cd release-assets for file in *; do if [ -f "$file" ]; then sha256sum "$file" > "$file.sha256" fi done cd .. - name: Create Release uses: softprops/action-gh-release@v1 with: tag_name: ${{ steps.version.outputs.version }} name: opcode ${{ steps.version.outputs.version }} draft: true prerelease: false generate_release_notes: true files: release-assets/* body: |
A powerful GUI app and Toolkit for Claude Code
Create custom agents, manage interactive Claude Code sessions, run secure background agents, and more.
Made with ❤️ by the Asterisk
Pre-built AI agents for opcode powered by Claude Code
{isRunning ? 'Running' : messages.length > 0 ? 'Complete' : 'Ready'} • {model === 'opus' ? 'Claude 4 Opus' : 'Claude 4 Sonnet'}
Working in: {projectPath.split('/').pop() || projectPath}
)}Enter a task to run the agent
Enter a task to run the agent
Loading agent run...
{run.task}
No output available yet
{run.task}
{error || "Run not found"}
Execution History
{run.task}
No execution history yet
{run.task}
Manage your Claude Code agents
Are you sure you want to delete "{agentToDelete.name}"? This action cannot be undone.
Create your first agent to get started
No description provided
Run an agent to see it here
{new Date(run.created_at).toLocaleString()}
{run.metrics?.duration_ms ? `${(run.metrics.duration_ms / 1000).toFixed(1)}s` : run.duration_ms ? `${(run.duration_ms / 1000).toFixed(1)}s` : '—'}
{run.metrics?.total_tokens ? run.metrics.total_tokens.toLocaleString() : run.total_tokens ? run.total_tokens.toLocaleString() : '—'}
Help improve opcode
We collect anonymous usage data to improve your experience. No personal data is collected.
{this.state.error.message}
( Component: React.ComponentType
,
fallback?: (error: Error, reset: () => void) => ReactNode
) {
return (props: P) => (
Manage your Claude Code agents
Create your first CC Agent to get started
Created: {new Date(agent.created_at).toLocaleDateString()}
Manage session checkpoints and recovery Experimental Feature
Checkpointing may affect directory structure or cause data loss. Use with caution.
Automatically create checkpoints based on the selected strategy
{checkpointStrategy === "manual" && "Checkpoints will only be created manually"}
{checkpointStrategy === "per_prompt" && "A checkpoint will be created after each user prompt"}
{checkpointStrategy === "per_tool_use" && "A checkpoint will be created after each tool use"}
{checkpointStrategy === "smart" && "Checkpoints will be created after destructive operations"}
Total checkpoints: {totalCheckpoints}
Remove old checkpoints, keeping only the most recent {keepCount}
{error} {queuedPrompt.prompt}
Edit project-specific Claude Code system prompt
{file.relative_path} {error}
Select which version of Claude to use
{isEditMode ? "Update your Claude Code agent configuration" : "Configure a new Claude Code agent"}
This will be used as the default task placeholder when executing the agent
Define the behavior and capabilities of your Claude Code agent
An error occurred while rendering this component.
↑↓ Navigate • Enter Select • → Enter Directory • ← Go Back • Esc Close
{THINKING_MODES.find(m => m.id === selectedThinkingMode)?.name || "Auto"} {THINKING_MODES.find(m => m.id === selectedThinkingMode)?.description} {selectedModelData.name} {selectedModelData.description} Thinking: {THINKING_MODES.find(m => m.id === selectedThinkingMode)?.name || "Auto"} {THINKING_MODES.find(m => m.id === selectedThinkingMode)?.description} Tool name pattern (regex supported). Leave empty to match all tools. No commands added yet {warning} {warning}
Configure shell commands to execute at various points in Claude Code's lifecycle.
{scope === 'local' && ' These settings are not committed to version control.'}
You have unsaved changes. Click Save to persist them.
Validation Errors: • {error} Security Warnings: • {warning}
{EVENT_INFO[event].description}
No hooks configured for this event {template.description}
Matcher: {template.matcher}
No icons found for "{searchQuery}"
Click an icon to select • {allIcons.length} icons available
Configure a new Model Context Protocol server
A unique name to identify this server
The command to execute the server
Space-separated command arguments
A unique name to identify this server
The SSE endpoint URL
• Postgres: /path/to/postgres-mcp-server --connection-string "postgresql://..." • Weather API: /usr/local/bin/weather-cli --api-key ABC123 • SSE Server: https://api.example.com/mcp/stream
Import MCP servers from other sources or export your configuration
Choose where to save imported servers from JSON files
Automatically imports all MCP servers from Claude Desktop. Installs to user scope (available across all projects).
Import server configuration from a JSON file
Export your MCP server configuration
Start Claude Code as an MCP server that other applications can connect to
Single server: Multiple servers (.mcp.json format):
Manage Model Context Protocol servers
{server.command}
{server.url}
Command
{server.command}
Arguments URL
{server.url}
Environment Variables
{servers.length} server{servers.length !== 1 ? "s" : ""} configured
No MCP servers configured
Add a server to get started with Model Context Protocol
Edit your Claude Code system prompt
{isLocalhost ? 'Local Development Server' : 'External URL'}
{url}
Select a project to start working with Claude Code
Open a project to get started with Claude Code
Custom commands that are specific to this project. These commands are stored in
These hooks apply to all users working on this project. They are stored in
These hooks only apply to your machine. They are stored in
Local settings file is not in .gitignore
Configure proxy settings for Claude API requests
Use proxy for all Claude API requests
Comma-separated list of hosts that should bypass the proxy
Proxy URL to use for all protocols if protocol-specific proxies are not set
{sessionId.substring(0, 20)}...
{session.project_path}
{projectPath}
No sessions found for this project
Session on {session.message_timestamp
? new Date(session.message_timestamp).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric'
})
: new Date(session.created_at * 1000).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric'
})
}
{truncateText(getFirstLine(session.first_message), 120)}
No messages yet
{session.id.slice(-8)}
Waiting for output...
Agent is running but no output received yet
No output available Waiting for output...
Agent is running but no output received yet
No output availableCC Agents
No agents yet
{agent.name}
Recent Executions
Checkpoint Settings
Session Timeline
{file.relative_path}
{selectedInstallation.path}
{isEditMode ? "Edit Agent" : "Create New Agent"}
Basic Information
Configuration
System Prompt
Something went wrong
Error details
{this.state.error.message}
Compose your prompt
Hooks Configuration
{template.name}
{category}
handleImageError(index)}
/>
)}
{/* Hover overlay with maximize icon */}
handleImageError(selectedImageIndex)}
/>
{/* Navigation buttons if multiple images */}
{displayImages.length > 1 && (
<>
>
)}
Add MCP Server
Import & Export
Import from Claude Desktop
Import from JSON
Export Configuration
Use Claude Code as MCP Server
{`{
"type": "stdio",
"command": "/path/to/server",
"args": ["--arg1", "value"],
"env": { "KEY": "value" }
}`}
{`{
"mcpServers": {
"server1": {
"command": "/path/to/server1",
"args": [],
"env": {}
},
"server2": {
"command": "/path/to/server2",
"args": ["--port", "8080"],
"env": { "API_KEY": "..." }
}
}
}`}
MCP Servers
{server.name}
{server.status?.running && (
Configured Servers
CLAUDE.md
{item.content}
);
case "spacer":
return ;
default:
return null;
}
})}
Projects
Recent Projects
{!showAll ? (
) : (
)}
No recent projects
Project Settings
Project Slash Commands
.claude/slash-commands/
and can be committed to version control.
Project Hooks
.claude/settings.json
and should be committed to version control.
Local Hooks
.claude/settings.local.json
and should NOT be committed to version control.
Proxy Settings
Active Claude Sessions
{`Session ${session.id.slice(0, 8)}`}
Sessions
{session.agent_name} - Output
{session.status === 'running' && (