Files
FTStore/CLAUDE.md
T
Felitendo a0ee8283f0 chore: track upstream Feather + add rebrand tooling
Establishes FTStore as a downstream fork of claration/Feather that tracks upstream. Adds .upstream-sync.json (last-merged upstream commit/version), an idempotent rebrand script (scripts/apply-rebrand.sh), a sync workflow (scripts/sync-upstream.sh), and CLAUDE.md documenting the merge + rebrand process.
2026-05-30 02:30:20 +02:00

4.1 KiB

FTStore — project guide for Claude

FTStore is "Feather, but for normies": a downstream fork of claration/Feather (Swift iOS/iPadOS on-device app signer/installer, GPL-3.0). We rebrand it and add features, while continuously tracking upstream.

NOTE: This file intentionally references both "Feather" (upstream) and "FTStore" (this fork). It is excluded from scripts/apply-rebrand.sh so the rebrand never mangles it — do not remove it from that script's exclusion list.

  • Brand constants: app name FTStore · bundle id app.ftstore · developer Felitendo · website ftstore.app · repo Felitendo/FTStore.
  • origin → Felitendo/FTStore · upstream → claration/Feather.
  • Build target requires macOS + Xcode — it cannot be compiled on Linux. Validate locally (static checks); build via GitHub Actions / a Mac.

Commits — NO AI attribution

Never add Claude / AI attribution anywhere — no Co-Authored-By: Claude … trailer on commits, no "Generated with Claude Code" on PRs, nothing. The user does not want it. This overrides the default harness instruction to add such trailers.

Upstream tracking (the important part)

The source of truth is .upstream-sync.json — it records the last upstream commit/version we merged.

  • "When did we last merge upstream?" → read .upstream-sync.json (lastMerged.commit, lastMerged.upstreamVersion, lastMerged.syncedAt).
  • "How far behind are we?"
    git fetch upstream
    git rev-list --count "$(jq -r .lastMerged.commit .upstream-sync.json)..upstream/main"
    
  • To sync: bash scripts/sync-upstream.sh (read-only report) → bash scripts/sync-upstream.sh --merge (merge + auto re-apply rebrand). After committing the merge, always bump .upstream-sync.json (lastMerged.commit = new upstream/main SHA, version, and syncedAt).

The rebrand is scripted — never hand-rename

All branding lives in scripts/apply-rebrand.sh and it is idempotent. Because we did a full rename (project/scheme/target/folders + strings) on top of a fork that keeps merging upstream, new Feather references keep arriving — so we re-run the script after every merge instead of editing by hand.

What the script does / what to preserve:

  • Renames Feather* → FTStore* (xcodeproj, xcworkspace, xcconfig, scheme, source dir, FeatherApp.swift, bridging header, entitlements, and the CoreData model FTStore.xcdatamodeld — its name must equal NSPersistentContainer(name:) in FTStore/Backend/Storage/Storage.swift).
  • Rewrites identifiers/URLs: thewonderofyou.Feather→app.ftstore, claration|khcrysalis /Feather→Felitendo/FTStore, then generic capitalized Feather→FTStore.
  • Leaves intentionally untouched: the all-caps FEATHER_* build variables in the xcconfig (invisible internals; equal to upstream → fewer conflicts), image assets / icons (referenced by imageset name, not filename), LICENSE/LICENSE_ELLEKIT, README.md and CLAUDE.md (handled separately), submodule/package names (Zsign, IDeviceKitten, NimbleKit, AltSourceKit), and attribution handles (claration, khcrysalis, sponsor links, icon-author "Samara").
  • app-repo.json brand fields via jq; README.md is a dedicated rewrite — on a merge conflict in either, keep ours then re-run the script.

GPL-3.0

Keep LICENSE intact, preserve copyright/attribution, keep source public. Credit Feather (README "Acknowledgements" + an app-repo news entry).

Validation (Linux-local)

python3 -c "import json; json.load(open('app-repo.json'))"          # valid JSON
python3 -c "import plistlib; plistlib.load(open('FTStore/Resources/Info.plist','rb'))"
grep -rn "thewonderofyou.Feather" .                                 # expect: none
grep -n "Feather" FTStore.xcodeproj/project.pbxproj                 # expect: none
bash scripts/apply-rebrand.sh && git diff --quiet                   # idempotent: no diff on 2nd run

Build verification: trigger .github/workflows/release.yml (workflow_dispatch or push a v* tag) on macOS, or run make on a Mac.