-
Notifications
You must be signed in to change notification settings - Fork 1
chore: add claude code workflow & rules #231
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
e06e1ec
feat: claude PR assistant workflow
ovitrif 1c4f658
feat: claude code review workflow
ovitrif b6cd260
chore: add ai rules to git
ovitrif fae6f15
Merge branch 'master' into add-claude-github-actions-1763458753833
ovitrif 9ef6293
Merge branch 'master' into add-claude-github-actions-1763458753833
ovitrif d852e4c
Merge branch 'master' into add-claude-github-actions-1763458753833
ovitrif 81fe9d3
Merge branch 'master' into add-claude-github-actions-1763458753833
ovitrif d228d87
Merge branch 'master' into add-claude-github-actions-1763458753833
ovitrif 667f9de
chore: update .gitignore
ovitrif File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| 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 | ||
ovitrif marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| 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: | ||
| claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} | ||
| 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. | ||
ovitrif marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| 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:*)"' | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| 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 | ||
ovitrif marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| id-token: write | ||
ovitrif marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| 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: | ||
| claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} | ||
|
|
||
| # 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:*)' | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,5 +17,3 @@ buildServer.json | |
| # VSCode | ||
| .vscode/ | ||
|
|
||
| #AI | ||
| CLAUDE.md | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,267 @@ | ||
| # AGENTS.md | ||
|
|
||
| This file provides guidance to AI agents like Claude Code (claude.ai/code) when working with code in this repository. | ||
|
|
||
| This file is symlinked for cross-agents compatibility to the following paths: | ||
| - `CLAUDE.md` | ||
|
|
||
| ## Project Overview | ||
|
|
||
| Bitkit iOS is a native Swift implementation of a Bitcoin and Lightning Network wallet. This is a work-in-progress repository that is **NOT** the live production app. The production app uses React Native and is at github.com/synonymdev/bitkit. | ||
|
|
||
| This app integrates with: | ||
| - **LDK Node** (Lightning Development Kit) for Lightning Network functionality | ||
| - **BitkitCore** (Rust-based core library) for Bitcoin operations | ||
| - **Electrum/Esplora** for blockchain data | ||
| - **Blocktank** for Lightning channel services | ||
|
|
||
| ## Build & Development Commands | ||
|
|
||
| ### Building | ||
| ```bash | ||
| # Standard build - Open Bitkit.xcodeproj in Xcode and build | ||
|
|
||
| # E2E test build (uses local Electrum backend) | ||
| xcodebuild -workspace Bitkit.xcodeproj/project.xcworkspace \ | ||
| -scheme Bitkit \ | ||
| -configuration Debug \ | ||
| SWIFT_ACTIVE_COMPILATION_CONDITIONS='$(inherited) E2E_BUILD' \ | ||
| build | ||
| ``` | ||
|
|
||
| ### Code Formatting | ||
| ```bash | ||
| # Install SwiftFormat | ||
| brew install swiftformat | ||
|
|
||
| # Format all Swift code | ||
| swiftformat . | ||
|
|
||
| # Setup git hooks for automatic formatting on commits | ||
| npm install -g git-format-staged | ||
| ./scripts/setup-hooks.sh | ||
| ``` | ||
|
|
||
| ### Localization | ||
| ```bash | ||
| # Validate translations (checks for missing translations and validates translation keys) | ||
| node scripts/validate-translations.js | ||
| ``` | ||
|
|
||
| **Note:** Localization files are synced from Transifex using [bitkit-transifex-sync](https://github.com/synonymdev/bitkit-transifex-sync). | ||
|
|
||
| ### Testing | ||
| ```bash | ||
| # Run tests via Xcode Test Navigator or: | ||
| # Cmd+U in Xcode | ||
| ``` | ||
|
|
||
| ## Architecture | ||
|
|
||
| ### SwiftUI Patterns (CRITICAL) | ||
|
|
||
| This project follows **modern SwiftUI patterns** and explicitly **AVOIDS traditional MVVM with ViewModels**. The architecture uses: | ||
|
|
||
| 1. **@Observable Objects for Business Logic** | ||
| - Use `@Observable class` for shared business logic instead of ViewModels | ||
| - Inject via `.environment(businessLogic)` | ||
| - Retrieve with `@Environment(BusinessLogic.self)` | ||
| - Example: `@Observable class UserManager { var users: [User] = []; func loadUsers() async { } }` | ||
|
|
||
| 2. **Native SwiftUI Data Flow** | ||
| - `@State` for local view state only | ||
| - `@Binding` for two-way data flow between parent/child views | ||
| - `@Observable` for shared business logic objects | ||
| - All state mutations must happen on `@MainActor` | ||
|
|
||
| 3. **Lifecycle Management** | ||
| - Use `.task` modifier for async operations (NOT `.onAppear`) | ||
| - `.task` automatically cancels when view disappears | ||
| - Async operations should delegate to `@Observable` business logic objects | ||
|
|
||
| 4. **Component Design** | ||
| - Decompose views into small, focused, single-purpose components | ||
| - Use descriptive names (e.g., `UserProfileCard` not `Card`) | ||
| - Prefer composition over deep view hierarchies | ||
| - Components should be independent and reusable with generic data types | ||
|
|
||
| ### Core Architecture Layers | ||
|
|
||
| ``` | ||
| ┌─────────────────────────────────────────────────┐ | ||
| │ Views (SwiftUI) │ | ||
| │ - MainNavView, Activity, Wallet, Settings │ | ||
| │ - Small, focused components │ | ||
| └─────────────────┬───────────────────────────────┘ | ||
| │ | ||
| ┌─────────────────▼───────────────────────────────┐ | ||
| │ @Observable Business Logic │ | ||
| │ - AppViewModel, WalletViewModel, etc. │ | ||
| │ - Injected via .environment() │ | ||
| └─────────────────┬───────────────────────────────┘ | ||
| │ | ||
| ┌─────────────────▼───────────────────────────────┐ | ||
| │ Services │ | ||
| │ - CoreService (BitkitCore bridge) │ | ||
| │ - LightningService (LDK Node) │ | ||
| │ - TransferService, CurrencyService │ | ||
| └─────────────────┬───────────────────────────────┘ | ||
| │ | ||
| ┌─────────────────▼───────────────────────────────┐ | ||
| │ External Dependencies │ | ||
| │ - BitkitCore (Rust): Bitcoin operations │ | ||
| │ - LDKNode: Lightning Network operations │ | ||
| │ - Electrum/Esplora: Blockchain data │ | ||
| └─────────────────────────────────────────────────┘ | ||
| ``` | ||
|
|
||
| ### Key Components | ||
|
|
||
| **App Entry Point:** | ||
| - `BitkitApp.swift`: Main app entry, handles AppDelegate setup, push notifications, quick actions | ||
| - `AppScene.swift`: Root scene coordinator, manages app-wide ViewModels and lifecycle | ||
| - `ContentView.swift`: Root content view | ||
|
|
||
| **Services Layer:** | ||
| - `CoreService`: Bridge to BitkitCore (Rust), handles Bitcoin operations and activity storage | ||
| - `LightningService`: Manages LDK Node lifecycle, Lightning operations, channel management | ||
| - `TransferService`: Orchestrates Bitcoin/Lightning transfers (send/receive) | ||
| - `TransferStorage`: Persists pending transfer state | ||
| - `CurrencyService`: Currency conversion and exchange rates | ||
| - `ElectrumConfigService`, `RgsConfigService`: Backend configuration | ||
| - `ServiceQueue`: Queue system for background operations (`.core`, `.ldk` queues) | ||
|
|
||
| **Managers:** | ||
| - `SessionManager`: User session state | ||
| - `PushNotificationManager`: Push notification handling for incoming payments | ||
| - `ScannerManager`: QR code scanning for payments | ||
| - `ToastWindowManager`: App-wide toast notifications | ||
| - `TransferTrackingManager`: Tracks pending transfers (new feature) | ||
| - `TimedSheets/`: Timed sheet management (backup reminders, high balance warnings) | ||
| - `SuggestionsManager`, `TagManager`, `LanguageManager`, `NetworkMonitor` | ||
|
|
||
| **ViewModels (Legacy):** | ||
| While the project is transitioning away from traditional ViewModels, these still exist but should follow `@Observable` patterns: | ||
| - `AppViewModel`: App-wide state (toasts, errors) | ||
| - `WalletViewModel`: Wallet state, balance, node lifecycle | ||
| - `ActivityListViewModel`: Transaction/payment history | ||
| - `TransferViewModel`: Transfer flows (send/receive) | ||
| - `NavigationViewModel`, `SheetViewModel`: UI navigation state | ||
| - `BlocktankViewModel`: Lightning channel ordering via Blocktank | ||
|
|
||
| **Key Directories:** | ||
| - `Components/`: Reusable UI components (buttons, sliders, widgets) | ||
| - `Views/`: Feature-specific views (Onboarding, Backup, Security, Wallets, Settings, Transfer) | ||
| - `Extensions/`: Swift extensions for utilities and mock data | ||
| - `Utilities/`: Helper utilities (Logger, Keychain, Crypto, Haptics, StateLocker) | ||
| - `Models/`: Data models (Toast, ElectrumServer, NodeLifecycleState, etc.) | ||
| - `Styles/`: Fonts and sheet styles | ||
|
|
||
| ### Service Queue Pattern | ||
|
|
||
| Operations that interact with `CoreService` or `LightningService` must use `ServiceQueue`: | ||
|
|
||
| ```swift | ||
| // For BitkitCore operations | ||
| try await ServiceQueue.background(.core) { | ||
| // Core operations here | ||
| } | ||
|
|
||
| // For LDK Node operations | ||
| try await ServiceQueue.background(.ldk) { | ||
| // Lightning operations here | ||
| } | ||
| ``` | ||
|
|
||
| ### State Management Patterns | ||
|
|
||
| **Node Lifecycle:** | ||
| The Lightning node has distinct lifecycle states tracked via `NodeLifecycleState`: | ||
| - `.notStarted` → `.initializing` → `.running` → `.stopped` | ||
| - Error states: `.errorStarting(String)` | ||
|
|
||
| **Transfer Tracking:** | ||
| New feature (`TransferTrackingManager`) tracks pending transfers to handle edge cases where transfers are initiated but not completed. | ||
|
|
||
| ## Important Development Notes | ||
|
|
||
| ### Security & Bitcoin/Lightning | ||
|
|
||
| - Use proper Bitcoin/Lightning terminology in code and naming | ||
| - All Bitcoin/Lightning operations belong in the service layer, never in views | ||
| - The app uses `StateLocker` to prevent concurrent Lightning operations (`.lightning` lock) | ||
| - Keychain is used for sensitive data (mnemonics, passphrases) | ||
|
|
||
| ### Network Configuration | ||
|
|
||
| - The app currently runs on **regtest only** (see `LightningService.swift:92` guard) | ||
| - VSS (Versioned Storage Service) authentication is not yet implemented | ||
| - Electrum/Esplora server URLs are configurable via `Env` | ||
| - E2E builds use local Electrum backend via `E2E_BUILD` compilation flag | ||
|
|
||
| ### Error Handling | ||
|
|
||
| - Use `do-catch` blocks for async operations | ||
| - Provide user feedback via toasts: `app.toast(type: .error, title: "...", description: "...")` | ||
| - Handle loading, error, and empty states comprehensively | ||
| - Consider using `enum LoadingState<T> { case idle, loading, loaded(T), error(Error) }` | ||
|
|
||
| ### iOS Version Compatibility | ||
|
|
||
| - Xcode previews only work with iOS 17 and below (due to Rust dependencies) | ||
| - Use availability checks for iOS 18/26 features: | ||
| ```swift | ||
| if #available(iOS 18.0, *) { | ||
| // Use iOS 18+ features | ||
| } else { | ||
| // Fallback | ||
| } | ||
| ``` | ||
|
|
||
| ### Performance | ||
|
|
||
| - Avoid expensive operations in view body | ||
| - Move heavy computations to `@Observable` objects | ||
| - Use proper state granularity to minimize view updates | ||
| - Use `@ViewBuilder` for repetitive view code | ||
|
|
||
| ### Accessibility | ||
|
|
||
| Ensure accessibility modifiers and labels are added to custom components. | ||
|
|
||
| ## Code Style & Conventions | ||
|
|
||
| - **SwiftFormat** configuration in `.swiftformat` | ||
| - Max line width: 150 characters | ||
| - Swift version: 5.10 | ||
| - Use descriptive names: `isLoadingUsers` not `loading` | ||
| - Follow Apple's SwiftUI best practices | ||
|
|
||
| ## Common Workflows | ||
|
|
||
| ### Adding a New Feature | ||
|
|
||
| 1. Identify if business logic should live in an `@Observable` object or existing ViewModel | ||
| 2. Create UI components in `Components/` or feature-specific views in `Views/` | ||
| 3. Wire up via `.environment()` injection in `AppScene.swift` | ||
| 4. Use `.task` for async initialization | ||
| 5. Add error handling and user feedback (toasts) | ||
|
|
||
| ### Working with Lightning | ||
|
|
||
| 1. All Lightning operations go through `LightningService.shared` | ||
| 2. Lock the Lightning state with `StateLocker.lock(.lightning)` for critical operations | ||
| 3. Listen to LDK events via `wallet.addOnEvent(id:)` pattern | ||
| 4. Sync activity list after Lightning events | ||
|
|
||
| ### Working with Bitcoin | ||
|
|
||
| 1. Use `CoreService` for Bitcoin operations | ||
| 2. Activity tracking handles both on-chain and Lightning payments | ||
| 3. RBF (Replace-By-Fee) is tracked via `ActivityService.replacementTransactions` | ||
|
|
||
| ### Localization Changes | ||
|
|
||
| 1. Update translation keys in code | ||
| 2. Run `node scripts/validate-translations.js` to check for issues | ||
| 3. Sync with Transifex using `bitkit-transifex-sync` tool |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| AGENTS.md |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.