Skip to content

Commit 0a0f009

Browse files
committed
Merge branch 'fix/fallback-expired-ln-to-onchain' of github.com:synonymdev/bitkit-ios into fix/fallback-expired-ln-to-onchain
2 parents 4a563fc + af4cc26 commit 0a0f009

37 files changed

Lines changed: 1669 additions & 641 deletions

.claude/commands/pr.md

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
---
2+
description: Create a PR on GitHub for the current branch
3+
argument_hint: "[branch] [--dry] [--draft]"
4+
allowed_tools: Bash, Read, Glob, Grep, Write, AskUserQuestion, mcp__github__create_pull_request, mcp__github__list_pull_requests, mcp__github__get_file_contents, mcp__github__issue_read
5+
---
6+
7+
Create a PR on GitHub using the `gh` CLI for the currently checked-out branch.
8+
9+
**Examples:**
10+
- `/pr` - Interactive mode, prompts for PR type
11+
- `/pr master` - Interactive with explicit base branch
12+
- `/pr --dry` - Generate description only, save to `.ai/`
13+
- `/pr --draft` - Create as draft PR
14+
- `/pr develop --draft` - Draft PR against non-default branch
15+
16+
## Steps
17+
18+
### 1. Check for Existing PR
19+
Run `gh pr view --json number,url 2>/dev/null` to check if a PR already exists for this branch.
20+
- If PR exists: Output `PR already exists: [URL]` and stop
21+
- If no PR: Continue
22+
23+
### 2. Parse Arguments
24+
- `--dry`: Skip PR creation, only generate and save description
25+
- `--draft`: Create PR as draft
26+
- First non-flag argument: base branch (default: auto-detected, see Step 2.5)
27+
- **If no flags provided**: Use `AskUserQuestion` to prompt user:
28+
- Open PR (create and publish)
29+
- Draft PR (create as draft)
30+
- Dry run (save locally only)
31+
32+
### 2.5. Determine Base Branch
33+
If no base branch argument provided, detect the repo's default branch:
34+
- Run: `git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@'`
35+
- Use result as default (typically `main` or `master`)
36+
- If command fails, fall back to `master`
37+
38+
### 3. Gather Context
39+
- Get current branch name: `git branch --show-current`
40+
- Extract repo identifier: `git remote get-url origin | sed 's/\.git$//' | sed -E 's#.*[:/]([^/]+/[^/]+)$#\1#'` (e.g., `synonymdev/bitkit-ios`)
41+
- Read PR template from `.github/pull_request_template.md`
42+
- Fetch 10 most recent PRs (open or closed) from the extracted repo for writing style reference
43+
- Run `git log $base..HEAD --oneline` for commit messages
44+
- Run `git diff $base...HEAD --stat` for understanding scope of changes
45+
46+
### 4. Extract Linked Issues
47+
Scan commits for issue references:
48+
- Pattern to match: `#123` (just the issue number reference)
49+
- Extract unique issue numbers: `git log $base..HEAD --oneline | grep -oE "#[0-9]+" | sort -u`
50+
- Fetch each issue title: `gh api "repos/$REPO/issues/NUMBER" --jq '.title'` (using repo from Step 3)
51+
- These will be used to start the PR description with linking keywords (see Step 6)
52+
53+
### 5. Identify Suggested Reviewers
54+
Find potential reviewers based on:
55+
- `.github/CODEOWNERS` file patterns (if exists)
56+
- Recent contributors to changed files: `git log --format='%an' -- $(git diff $base..HEAD --name-only) | sort | uniq -c | sort -rn | head -3`
57+
- Exclude the current user from suggestions
58+
59+
### 6. Generate PR Description
60+
Starting from the template in `.github/pull_request_template.md`:
61+
62+
**Title Rules:**
63+
- Format: `prefix: title` (e.g., `feat: add user settings screen`)
64+
- Keep under 50 characters
65+
- Use branch name as concept inspiration
66+
- Prefixes: `feat`, `fix`, `chore`, `refactor`, `docs`, `test`
67+
68+
**Issue Linking (at the very start):**
69+
If linked issues were found in commit messages, begin the PR description with linking keywords:
70+
- Use `Fixes #123` for bug fixes
71+
- Use `Closes #123` for features/enhancements
72+
- One per line, before the "This PR..." opening separated by one empty line
73+
- Reference: https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/using-keywords-in-issues-and-pull-requests
74+
75+
Example:
76+
```
77+
Fixes #528
78+
Closes #418
79+
80+
This PR adds support for...
81+
```
82+
83+
**Opening Format:**
84+
- Single change: Start with "This PR [verb]s..." as a complete sentence
85+
- Example: `This PR adds a Claude Code /pr command for generating PRs.`
86+
- Multiple changes: Start with "This PR:" followed by a numbered list
87+
- Example:
88+
```
89+
This PR:
90+
1. Adds a Claude Code /pr command for generating PRs
91+
2. Fixes issue preventing Claude Code reviews to be added as PR comments
92+
3. Updates reviews workflow to minimize older review comments
93+
```
94+
- Each list item should start with a verb (Adds, Fixes, Updates, Removes, Refactors, etc.)
95+
96+
**Description Rules:**
97+
- Base content around all commit messages in the branch
98+
- Use branch name as the conceptual anchor
99+
- Match writing style of recent PRs
100+
- Focus on functionality over technical details
101+
- Avoid excessive bold formatting like `**this:** that`
102+
- Minimize code and file references like `TheClassName` or `someFunctionName`, `thisFileName.ext`
103+
- Exception: for refactoring PRs (1:10 ratio of functionality to code changes), more technical detail is ok
104+
105+
**QA Notes / Testing Scenarios:**
106+
- Structure with numbered headings and steps
107+
- Make steps easily referenceable
108+
- Be specific about what to test and expected outcomes
109+
110+
**For library repos (has `bindings/` directory or `Cargo.toml`):**
111+
Structure QA Notes around testing and integration:
112+
113+
Example:
114+
```
115+
### QA Notes
116+
117+
#### Testing
118+
- [ ] `cargo test` passes
119+
- [ ] `cargo clippy` clean
120+
- [ ] Android bindings: `./build_android.sh`
121+
- [ ] iOS bindings: `./build_ios.sh`
122+
123+
#### Integration
124+
- Tested in: [bitkit-android#XXX](link)
125+
- Or N/A if internal refactor with no API changes
126+
```
127+
128+
**Preview Section (conditional):**
129+
Only include if the PR template (`.github/pull_request_template.md`) contains a `### Preview` heading:
130+
- Create placeholders for media: `IMAGE_1`, `VIDEO_2`, etc.
131+
- Add code comment under each placeholder describing what it should show
132+
- Example: `<!-- VIDEO_1: Record the send flow by scanning a LN invoice and setting amount to 5000 sats -->`
133+
134+
### 7. Save PR Description
135+
Before creating the PR:
136+
- Get next PR number: `gh api "repos/$REPO/issues?per_page=1&state=all&sort=created&direction=desc" --jq '.[0].number'` then add 1 (using repo from Step 3)
137+
- Create `.ai/` directory if it doesn't exist
138+
- Save to `.ai/pr_NN.md` where `NN` is the predicted PR number
139+
140+
### 8. Create the PR (unless --dry)
141+
If not dry run:
142+
```bash
143+
gh pr create --base $base --title "..." --body "..." [--draft]
144+
```
145+
- Add `--draft` flag if draft mode selected
146+
- If actual PR number differs from predicted, rename the saved file
147+
148+
### 9. Output Summary
149+
150+
**If PR created:**
151+
```
152+
PR Created: [PR URL]
153+
Saved: .ai/pr_NN.md
154+
155+
Suggested reviewers:
156+
- @username1 (X files modified recently)
157+
- @username2 (CODEOWNER)
158+
```
159+
160+
**If dry run:**
161+
```
162+
Dry run complete
163+
Saved: .ai/pr_NN.md
164+
165+
To create PR: /pr [--draft]
166+
167+
Suggested reviewers:
168+
- @username1 (X files modified recently)
169+
- @username2 (CODEOWNER)
170+
```
171+
172+
**Media TODOs (only if Preview section was included):**
173+
If the PR description includes a Preview section with media placeholders, append:
174+
```
175+
## TODOs
176+
- [ ] IMAGE_1: [description]
177+
- [ ] VIDEO_2: [description]
178+
```
179+
List all media placeholders as TODOs with their descriptions.

.cursor/commands/pr.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../.claude/commands/pr.md

.github/workflows/claude-code-review.yml

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: Claude Code Review
22

33
on:
44
pull_request:
5-
types: [opened, synchronize]
5+
types: [opened, synchronize, ready_for_review, reopened]
66
# Optional: Only run on specific file changes
77
# paths:
88
# - "src/**/*.ts"
@@ -31,27 +31,34 @@ jobs:
3131
with:
3232
fetch-depth: 1
3333

34+
- name: Minimize old Claude comments
35+
env:
36+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
37+
run: |
38+
REPO="${{ github.repository }}"
39+
PR_NUMBER="${{ github.event.pull_request.number }}"
40+
41+
# Minimize issue comments from claude[bot]
42+
gh api "repos/$REPO/issues/$PR_NUMBER/comments" --jq '.[] | select(.user.login == "claude[bot]") | .node_id' | while read -r node_id; do
43+
if [ -n "$node_id" ]; then
44+
echo "Minimizing comment: $node_id"
45+
gh api graphql -f query='
46+
mutation($id: ID!) {
47+
minimizeComment(input: {subjectId: $id, classifier: OUTDATED}) {
48+
minimizedComment { isMinimized }
49+
}
50+
}' -f id="$node_id" || true
51+
fi
52+
done
53+
3454
- name: Run Claude Code Review
3555
id: claude-review
3656
uses: anthropics/claude-code-action@v1
3757
with:
3858
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
39-
use_sticky_comment: true
40-
additional_permissions: |
41-
actions: read
42-
prompt: |
43-
REPO: ${{ github.repository }}
44-
PR NUMBER: ${{ github.event.pull_request.number }}
45-
46-
Please review this pull request and provide feedback on:
47-
- Code quality and best practices
48-
- Potential bugs or issues
49-
- Performance considerations
50-
- Security concerns
51-
- Test coverage
52-
53-
Use the repository's CLAUDE.md for guidance on style and conventions. Be constructive and helpful in your feedback.
54-
59+
plugin_marketplaces: 'https://github.com/anthropics/claude-code.git'
60+
plugins: 'code-review@claude-code-plugins'
61+
prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
5562
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
5663
# or https://code.claude.com/docs/en/cli-reference for available options
57-
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:*)"'
64+

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,7 @@ buildServer.json
2020

2121
# VSCode
2222
.vscode/
23+
24+
# AIs
25+
.ai/
26+
.claude/*.local*

Bitkit.xcodeproj/project.pbxproj

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@
1313
4AFCA3702E05933800205CAE /* Zip in Frameworks */ = {isa = PBXBuildFile; productRef = 4AFCA36F2E05933800205CAE /* Zip */; };
1414
4AFCA3722E0596D900205CAE /* Zip in Frameworks */ = {isa = PBXBuildFile; productRef = 4AFCA3712E0596D900205CAE /* Zip */; };
1515
961058E32C355B5500E1F1D8 /* BitkitNotification.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 961058DC2C355B5500E1F1D8 /* BitkitNotification.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
16-
96204B762DE9A91A007BAA26 /* SQLite in Frameworks */ = {isa = PBXBuildFile; productRef = 96204B752DE9A91A007BAA26 /* SQLite */; };
17-
96204B782DE9AA43007BAA26 /* SQLite in Frameworks */ = {isa = PBXBuildFile; productRef = 96204B772DE9AA43007BAA26 /* SQLite */; };
18-
966DE6702C51210000A7B0EF /* LightningDevKit in Frameworks */ = {isa = PBXBuildFile; productRef = 966DE66F2C51210000A7B0EF /* LightningDevKit */; };
1916
968FDF162DFAFE230053CD7F /* LDKNode in Frameworks */ = {isa = PBXBuildFile; productRef = 9613018B2C5022D700878183 /* LDKNode */; };
2017
968FE1402DFB016B0053CD7F /* LDKNode in Frameworks */ = {isa = PBXBuildFile; productRef = 968FE13F2DFB016B0053CD7F /* LDKNode */; };
2118
96DEA03A2DE8BBA1009932BF /* BitkitCore in Frameworks */ = {isa = PBXBuildFile; productRef = 96DEA0392DE8BBA1009932BF /* BitkitCore */; };
@@ -164,10 +161,8 @@
164161
files = (
165162
4AFCA3702E05933800205CAE /* Zip in Frameworks */,
166163
968FDF162DFAFE230053CD7F /* LDKNode in Frameworks */,
167-
96204B782DE9AA43007BAA26 /* SQLite in Frameworks */,
168164
18D65E002EB964B500252335 /* VssRustClientFfi in Frameworks */,
169165
96E493A42C942FD1000E8BC2 /* secp256k1 in Frameworks */,
170-
966DE6702C51210000A7B0EF /* LightningDevKit in Frameworks */,
171166
96DEA03A2DE8BBA1009932BF /* BitkitCore in Frameworks */,
172167
96E20CD42CB6D91A00C24149 /* CodeScanner in Frameworks */,
173168
4AAB08CA2E1FE77600BA63DF /* Lottie in Frameworks */,
@@ -178,7 +173,6 @@
178173
isa = PBXFrameworksBuildPhase;
179174
buildActionMask = 2147483647;
180175
files = (
181-
96204B762DE9A91A007BAA26 /* SQLite in Frameworks */,
182176
96E493A62C94317D000E8BC2 /* secp256k1 in Frameworks */,
183177
);
184178
runOnlyForDeploymentPostprocessing = 0;
@@ -270,11 +264,9 @@
270264
name = Bitkit;
271265
packageProductDependencies = (
272266
9613018B2C5022D700878183 /* LDKNode */,
273-
966DE66F2C51210000A7B0EF /* LightningDevKit */,
274267
96E493A32C942FD1000E8BC2 /* secp256k1 */,
275268
96E20CD32CB6D91A00C24149 /* CodeScanner */,
276269
96DEA0392DE8BBA1009932BF /* BitkitCore */,
277-
96204B772DE9AA43007BAA26 /* SQLite */,
278270
4AFCA36F2E05933800205CAE /* Zip */,
279271
4AAB08C92E1FE77600BA63DF /* Lottie */,
280272
18D65DFF2EB964B500252335 /* VssRustClientFfi */,
@@ -302,7 +294,6 @@
302294
name = BitkitTests;
303295
packageProductDependencies = (
304296
96E493A52C94317D000E8BC2 /* secp256k1 */,
305-
96204B752DE9A91A007BAA26 /* SQLite */,
306297
);
307298
productName = BitkitTests;
308299
productReference = 96FE1F722C2DE6AC006D0C8B /* BitkitTests.xctest */;
@@ -379,8 +370,6 @@
379370
);
380371
mainGroup = 96FE1F582C2DE6AA006D0C8B;
381372
packageReferences = (
382-
961301892C50215500878183 /* XCRemoteSwiftPackageReference "SQLite.swift" */,
383-
966DE66E2C51210000A7B0EF /* XCRemoteSwiftPackageReference "ldk-swift" */,
384373
96E493A22C942FD1000E8BC2 /* XCRemoteSwiftPackageReference "swift-secp256k1" */,
385374
96E20CD22CB6D91A00C24149 /* XCRemoteSwiftPackageReference "CodeScanner" */,
386375
96DEA0382DE8BBA1009932BF /* XCRemoteSwiftPackageReference "bitkit-core" */,
@@ -902,14 +891,6 @@
902891
minimumVersion = 2.1.2;
903892
};
904893
};
905-
961301892C50215500878183 /* XCRemoteSwiftPackageReference "SQLite.swift" */ = {
906-
isa = XCRemoteSwiftPackageReference;
907-
repositoryURL = "https://github.com/stephencelis/SQLite.swift.git";
908-
requirement = {
909-
kind = upToNextMajorVersion;
910-
minimumVersion = 0.15.3;
911-
};
912-
};
913894
962045C92DE998F1007BAA26 /* XCRemoteSwiftPackageReference "ldk-node" */ = {
914895
isa = XCRemoteSwiftPackageReference;
915896
repositoryURL = "https://github.com/lightningdevkit/ldk-node";
@@ -918,14 +899,6 @@
918899
kind = branch;
919900
};
920901
};
921-
966DE66E2C51210000A7B0EF /* XCRemoteSwiftPackageReference "ldk-swift" */ = {
922-
isa = XCRemoteSwiftPackageReference;
923-
repositoryURL = "https://github.com/lightningdevkit/ldk-swift/";
924-
requirement = {
925-
kind = upToNextMajorVersion;
926-
minimumVersion = 0.0.123;
927-
};
928-
};
929902
968FE13E2DFB016B0053CD7F /* XCRemoteSwiftPackageReference "ldk-node" */ = {
930903
isa = XCRemoteSwiftPackageReference;
931904
repositoryURL = "https://github.com/synonymdev/ldk-node";
@@ -991,21 +964,6 @@
991964
package = 962045C92DE998F1007BAA26 /* XCRemoteSwiftPackageReference "ldk-node" */;
992965
productName = LDKNode;
993966
};
994-
96204B752DE9A91A007BAA26 /* SQLite */ = {
995-
isa = XCSwiftPackageProductDependency;
996-
package = 961301892C50215500878183 /* XCRemoteSwiftPackageReference "SQLite.swift" */;
997-
productName = SQLite;
998-
};
999-
96204B772DE9AA43007BAA26 /* SQLite */ = {
1000-
isa = XCSwiftPackageProductDependency;
1001-
package = 961301892C50215500878183 /* XCRemoteSwiftPackageReference "SQLite.swift" */;
1002-
productName = SQLite;
1003-
};
1004-
966DE66F2C51210000A7B0EF /* LightningDevKit */ = {
1005-
isa = XCSwiftPackageProductDependency;
1006-
package = 966DE66E2C51210000A7B0EF /* XCRemoteSwiftPackageReference "ldk-swift" */;
1007-
productName = LightningDevKit;
1008-
};
1009967
968FE13F2DFB016B0053CD7F /* LDKNode */ = {
1010968
isa = XCSwiftPackageProductDependency;
1011969
package = 968FE13E2DFB016B0053CD7F /* XCRemoteSwiftPackageReference "ldk-node" */;

0 commit comments

Comments
 (0)