Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
6a19526
Bump workflow MacOS
theacrat Jun 17, 2026
2c3e870
Add bypassing age verification
theacrat Jun 17, 2026
4fe32ef
Fix crash on toggling Tweet settings
theacrat Jun 17, 2026
92ba777
Try to make sensitive content warning disable always work
theacrat Jun 17, 2026
ff245bd
Remove legacy messages settings
theacrat Jun 17, 2026
e1a95e7
Try to fix chat
theacrat Jun 17, 2026
aa69735
Bump actions versions
theacrat Jun 17, 2026
c86f726
Remove redundant keychainfix
theacrat Jun 17, 2026
6df7c94
Fix downloads
theacrat Jun 18, 2026
b2a56f9
Stop relying on share button
theacrat Jun 18, 2026
3058148
Add using webview to reply
theacrat Jun 19, 2026
32070e9
Custom timeline settings
theacrat Jun 19, 2026
4aac5dc
Fix tab bar items not hiding
theacrat Jun 19, 2026
77aa357
Fix webview reply default not being set
theacrat Jun 19, 2026
d166fca
Custom timeline fixes
theacrat Jun 23, 2026
9e1a197
Fix hiding Grok analyze button
theacrat Jun 23, 2026
c4bc670
Hide trending content
theacrat Jun 23, 2026
ad61dae
Comment changes for clarity
theacrat Jun 23, 2026
9281a11
Add VS code config for Obj-C/Logos
theacrat Jun 23, 2026
77062c6
Fix hiding trending hiding unrelated views
theacrat Jun 23, 2026
2d2c419
Add note about Linux builds
theacrat Jun 24, 2026
b951ccb
Reimplement 9.67-like xauth login flow
theacrat Jul 2, 2026
07444b6
Fix GHA breaking with newest theos
theacrat Jul 2, 2026
51c1439
Make the attestation setting more clear
theacrat Jul 2, 2026
2ec7a14
Fix Grok buttons still working while hidden
theacrat Jul 2, 2026
ab22dd7
Fix sensitive content warnings still showing when age bypass is on
theacrat Jul 2, 2026
00a9c93
Remove old settings page
theacrat Jul 2, 2026
2b2bab6
Update libflex
theacrat Jul 2, 2026
6d31339
Fix login for 12.3
theacrat Jul 2, 2026
a1c3aa6
Make webview reply pop up on post your reply box as well
theacrat Jul 3, 2026
b9f0212
Bump to version 5.2.6
theacrat Jul 3, 2026
389a116
Add a popup to view tweet after posting through webview
theacrat Jul 3, 2026
ce83452
Fix Grok tab bar not properly being hidden by default
theacrat Jul 3, 2026
ea78c40
Export tweets as PNG instead of JPEG
theacrat Jul 3, 2026
da1ed36
Move the download button to the overflow menu and fix font changes fo…
theacrat Jul 3, 2026
543e9b5
Try to fix age verification bypass occasionally not working
theacrat Jul 3, 2026
59aa381
Bump to version 5.2.7
theacrat Jul 3, 2026
d6cc4a6
Make Grok hiding more robust
theacrat Jul 7, 2026
866f8b0
Bump to version 5.2.8
theacrat Jul 7, 2026
231adfe
Use web auth for posting
theacrat Jul 8, 2026
db1f47e
Bump to version 5.2.9
theacrat Jul 8, 2026
e609828
Add text branding replacement
theacrat Jul 8, 2026
5b28ffb
Implement reverting branding in build
theacrat Jul 8, 2026
be73dfc
Set restoring Twitter names to be default
theacrat Jul 8, 2026
1ec347f
Enable iOS Password AutoFill on the legacy login form (#6)
gingerbeardman Jul 8, 2026
1f467a8
Fix Post button vanishing with hide_grok_analyze, plus broken toggles…
gingerbeardman Jul 8, 2026
d27a57a
Add "Hide downvotes" toggle to remove the reply dislike button (#5)
gingerbeardman Jul 8, 2026
5e53883
Bump to version 5.3.0
theacrat Jul 8, 2026
e340e9a
Update asset pack
theacrat Jul 8, 2026
f477f52
Remove mask from startup
theacrat Jul 8, 2026
4139b16
Rename image-pack to resource-pack
theacrat Jul 8, 2026
d2cfc84
Rename package based on branding
theacrat Jul 8, 2026
0b76376
Branding localisation improvements
theacrat Jul 8, 2026
cb8a8d9
Create separate workflow for releasing
theacrat Jul 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 32 additions & 12 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Build and Release NeoFreeBird
name: Build NeoFreeBird

on:
workflow_dispatch:
Expand All @@ -19,27 +19,37 @@ on:
type: string
deploy_format:
description: "Deployment format"
default: rootfull
default: sideloaded
required: true
type: choice
options:
- rootfull
- sideloaded
- trollstore
- rootless
twitter_branding:
description: "Set app name to Twitter (IPA builds only)"
default: true
required: false
type: boolean
resource_pack_url:
description: "Override app icons (.ZIP) (IPA builds only)"
default: "https://files.catbox.moe/dq8zon.zip"
required: false
type: string
commit_id:
description: "(Optional) Commit ID to build at"
default: ""
required: false
type: string
upload_artifact:
description: "Upload iPA as artifact (Public)"
default: false
default: true
required: false
type: boolean
create_release:
description: "Create a draft release (Private)"
default: true
default: false
required: false
type: boolean

Expand All @@ -50,13 +60,13 @@ concurrency:
jobs:
build:
name: Build BHTwitter
runs-on: macos-14
runs-on: macos-latest
permissions:
contents: write

steps:
- name: Checkout Main
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
path: main
ref: ${{ github.event.inputs.commit_id || github.ref }}
Expand All @@ -70,7 +80,7 @@ jobs:
echo "$(brew --prefix make)/libexec/gnubin" >> "$GITHUB_PATH"

- name: Download Theos
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
repository: theos/theos
ref: master
Expand All @@ -83,7 +93,7 @@ jobs:

- name: iOS SDK Caching
id: SDK
uses: actions/cache@v4
uses: actions/cache@v5
env:
cache-name: iOS-${{ inputs.sdk_version }}-SDK
with:
Expand Down Expand Up @@ -122,21 +132,31 @@ jobs:
env:
IPA_URL: ${{ inputs.decrypted_ipa_url }}

- name: Prepare Image Pack
if: inputs.resource_pack_url != '' && (inputs.deploy_format == 'sideloaded' || inputs.deploy_format == 'trollstore')
run: |
wget "$IMAGE_URL" --no-verbose -O main/resource-pack.zip
env:
IMAGE_URL: ${{ inputs.resource_pack_url }}

- name: Build Package
run: |
cd ${{ github.workspace }}/main
sed -i '' "s/^TARGET.*$/TARGET := iphone:clang:${{ inputs.sdk_version }}:${{ inputs.target_version }}/" Makefile
./build.sh --${{ inputs.deploy_format }}
IMAGE_FLAG=""
if [ -f resource-pack.zip ]; then IMAGE_FLAG="--resource-pack resource-pack.zip"; fi
./build.sh --${{ inputs.deploy_format }}${{ inputs.twitter_branding && ' --twitter-branding' || '' }} $IMAGE_FLAG
env:
THEOS: ${{ github.workspace }}/theos

- name: Rename IPA to include IPA version
if: inputs.deploy_format == 'sideloaded' || inputs.deploy_format == 'trollstore'
run: |
mv "main/packages/$(ls -t main/packages | head -n1)" \
"main/packages/NeoFreeBird-${{ inputs.deploy_format }}_${{ env.BHTWITTER_VERSION }}_${{ env.X_VERSION }}.${IPA_EXT}"
"main/packages/NeoFreeBird-${BRANDING}-${{ inputs.deploy_format }}_${{ env.BHTWITTER_VERSION }}_${{ env.X_VERSION }}.${IPA_EXT}"
env:
IPA_EXT: ${{ inputs.deploy_format == 'trollstore' && 'tipa' || 'ipa' }}
BRANDING: ${{ inputs.twitter_branding && 'Twitter' || 'X' }}

- name: Pass package name
id: package_name
Expand All @@ -145,7 +165,7 @@ jobs:

- name: Upload Artifact
if: ${{ inputs.upload_artifact }}
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v6
with:
name: BHTwitter_${{ env.BHTWITTER_VERSION }}
path: ${{ github.workspace }}/main/packages/${{ steps.package_name.outputs.package }}
Expand All @@ -154,7 +174,7 @@ jobs:
- name: Create Draft Release
if: ${{ inputs.create_release }}
id: create_release
uses: softprops/action-gh-release@v1
uses: softprops/action-gh-release@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
Expand Down
180 changes: 180 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
name: Release

on:
workflow_dispatch:
inputs:
sdk_version:
description: "iOS SDK Version"
default: "16.5"
required: true
type: string
target_version:
description: "Target iOS Version"
default: "14.0"
required: true
type: string
decrypted_ipa_url:
description: "Direct URL of the decrypted X ipa (required for sideloaded/trollstore)"
default: ""
required: true
type: string
resource_pack_url:
description: "Custom app icon pack (.ZIP) used for the branded IPA builds"
default: "https://files.catbox.moe/dq8zon.zip"
required: false
type: string
commit_id:
description: "(Optional) Commit ID to build at"
default: ""
required: false
type: string
create_release:
description: "Collect every build into a single draft release"
default: true
required: false
type: boolean

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
name: Build ${{ matrix.deploy_format }}${{ matrix.branded && ' (Twitter)' || matrix.ipa && ' (X)' || '' }}
runs-on: macos-latest
permissions:
contents: write
strategy:
fail-fast: false
matrix:
include:
# Non-IPA formats: branding does not apply, so a single build each.
- deploy_format: rootfull
ipa: false
branded: false
- deploy_format: rootless
ipa: false
branded: false
# IPA formats: built both with and without custom branding.
- deploy_format: sideloaded
ipa: true
branded: false
- deploy_format: sideloaded
ipa: true
branded: true
- deploy_format: trollstore
ipa: true
branded: false
- deploy_format: trollstore
ipa: true
branded: true

steps:
- name: Checkout Main
uses: actions/checkout@v6
with:
path: main
ref: ${{ github.event.inputs.commit_id || github.ref }}
submodules: recursive

- name: Install Dependencies
run: brew install make dpkg ldid

- name: Add GNU Make to PATH
run: |
echo "$(brew --prefix make)/libexec/gnubin" >> "$GITHUB_PATH"

- name: Download Theos
uses: actions/checkout@v6
with:
repository: theos/theos
ref: master
path: theos
submodules: recursive

- name: Install cyan
if: matrix.ipa
run: pip install https://github.com/asdfzxcvbn/pyzule-rw/archive/main.zip

- name: iOS SDK Caching
id: SDK
uses: actions/cache@v5
env:
cache-name: iOS-${{ inputs.sdk_version }}-SDK
with:
path: theos/sdks/
key: ${{ env.cache-name }}
restore-keys: ${{ env.cache-name }}

- name: Download iOS SDK
if: steps.SDK.outputs.cache-hit != 'true'
run: |
# Only download the specific SDK version
git clone -n --depth=1 --filter=tree:0 https://github.com/theos/sdks/
cd sdks
git sparse-checkout set --no-cone iPhoneOS${{ inputs.sdk_version }}.sdk
git checkout
mv ./*.sdk "${THEOS}/sdks"
env:
THEOS: ${{ github.workspace }}/theos

- name: Get BHTwitter Version
run: |
BHTWITTER_VERSION=$(awk '/Version:/ {print $2}' main/control)
echo "BHTWITTER_VERSION=${BHTWITTER_VERSION}" >> "$GITHUB_ENV"
echo "$BHTWITTER_VERSION"

- name: Prepare X iPA
if: matrix.ipa
run: |
wget "$IPA_URL" --no-verbose -O main/packages/com.atebits.Tweetie2.ipa
unzip -q main/packages/com.atebits.Tweetie2.ipa -d main/tmp
# Get the version number of the X app and store it
X_VERSION=$(grep -A 1 '<key>CFBundleShortVersionString</key>' main/tmp/Payload/Twitter.app/Info.plist |
grep '<string>' | awk -F'[><]' '{print $3}')
echo "X_VERSION=${X_VERSION}" >> "$GITHUB_ENV"
echo "$X_VERSION"
env:
IPA_URL: ${{ inputs.decrypted_ipa_url }}

- name: Prepare Image Pack
if: matrix.branded && inputs.resource_pack_url != ''
run: |
wget "$IMAGE_URL" --no-verbose -O main/resource-pack.zip
env:
IMAGE_URL: ${{ inputs.resource_pack_url }}

- name: Build Package
run: |
cd ${{ github.workspace }}/main
sed -i '' "s/^TARGET.*$/TARGET := iphone:clang:${{ inputs.sdk_version }}:${{ inputs.target_version }}/" Makefile
IMAGE_FLAG=""
if [ -f resource-pack.zip ]; then IMAGE_FLAG="--resource-pack resource-pack.zip"; fi
./build.sh --${{ matrix.deploy_format }}${{ matrix.branded && ' --twitter-branding' || '' }} $IMAGE_FLAG
env:
THEOS: ${{ github.workspace }}/theos

- name: Rename IPA to include IPA version
if: matrix.ipa
run: |
mv "main/packages/$(ls -t main/packages | head -n1)" \
"main/packages/NeoFreeBird-${{ matrix.deploy_format }}${BRAND_SUFFIX}_${{ env.BHTWITTER_VERSION }}_${{ env.X_VERSION }}.${IPA_EXT}"
env:
IPA_EXT: ${{ matrix.deploy_format == 'trollstore' && 'tipa' || 'ipa' }}
BRAND_SUFFIX: ${{ matrix.branded && '-Twitter' || '-X' }}

- name: Pass package name
id: package_name
run: |
echo "package=$(ls -t main/packages | head -n1)" >> "$GITHUB_OUTPUT"

- name: Add to Draft Release
if: ${{ inputs.create_release }}
uses: softprops/action-gh-release@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: v${{ env.BHTWITTER_VERSION }}
name: v${{ env.BHTWITTER_VERSION }} - BHTwitter
files: main/packages/${{ steps.package_name.outputs.package }}
draft: true
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,8 @@
classdump/
autopush.sh
*.ipa
packages/stuff/*
packages/
!packages/PUT_IPA_HERE

*.md
!README.md
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[submodule "libflex/FLEX"]
path = libflex/FLEX
url = https://github.com/FLEXTool/FLEX
[submodule "zxPluginsInject"]
path = zxPluginsInject
url = https://github.com/asdfzxcvbn/zxPluginsInject
6 changes: 6 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"recommendations": [
"ms-vscode.cpptools-extension-pack",
"tale.logos-vscode"
]
}
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"files.associations": {
"*.h": "objective-c"
}
}
Loading