Freebuff Focus for Desktop  (v1.8.3)
=================================================

Blocks the ads Freebuff Desktop renders from the orchestrator it ships inside
its own app bundle.

WHAT IS IN THIS FOLDER
----------------------

  Freebuff Focus.command   Double-click this. It opens Terminal and patches
                             the app.

  freebuff-focus.sh        The tool itself, if you would rather run it by hand:

                               sh freebuff-focus.sh install

USING IT
--------

1. Freebuff Desktop must be installed (usually /Applications/Freebuff.app).

2. Double-click "Freebuff Focus.command", or run:

     sh freebuff-focus.sh install

3. The tool patches, then quits and reopens Freebuff for you, and waits for the
   new process to prove it read the patched file. The orchestrator is read once
   at launch, so a running app has to be restarted - focusing the window is not
   enough. If Freebuff was closed, open it when the tool says so. Ctrl-C stops
   the wait at any time, and --no-restart leaves the quitting to you.

macOS may ask you for permission the first time, because this writes inside an
app bundle. If you see "Operation not permitted", open:

  System Settings -> Privacy & Security -> App Management

switch on Terminal (or whichever app you ran this from), quit and reopen that
app, and run the tool again. It never asks for a password and never uses sudo.

INSTALL IT AS A COMMAND
-----------------------

Run this once and you stop naming a file:

  sh freebuff-focus.sh setup

It copies the tool to ~/.local/share/freebuff-focus, writes
`freebuff-focusmode` into ~/.local/bin, and prints the one line to add that
folder to your PATH if it is not there already. `setup --add-path` edits your
shell rc instead of telling you to. After that:

  freebuff-focusmode status     report what is applied - changes nothing
  freebuff-focusmode focus      keep the ads off until you end it
  freebuff-focusmode focus 25m  keep them off until the deadline
  freebuff-focusmode focus session  keep them off until Freebuff quits
  freebuff-focusmode unfocus    end it now, and bring the ads back
  freebuff-focusmode update     fetch a newer tool, replace this copy, patch again
  freebuff-focusmode uninstall  remove the command; the patch stays

The one-liner on the install page does this for you, which is why the piped form
is the shorter path rather than the longer one.


OTHER COMMANDS
--------------

  sh freebuff-focus.sh status    report what is applied - changes nothing
  sh freebuff-focus.sh verify    wait for the relaunch, then check what it loaded
  sh freebuff-focus.sh scan      show every anchor this build has - changes nothing
  sh freebuff-focus.sh revert    restore the untouched original
  sh freebuff-focus.sh doctor    environment report, for a bug report


FOCUS
-----

Three ways to ask, and only what ends them differs:

  sh freebuff-focus.sh focus          quiet until you run unfocus
  sh freebuff-focus.sh focus 25m      quiet until the deadline
  sh freebuff-focus.sh focus session  quiet until Freebuff quits

All three patch the app first, so a failed install is a failed focus and nothing
is recorded.

A plain `focus` writes no deadline. Closing Freebuff and opening it again keeps
the ads off, because the patched file is still on disk; only `unfocus` restores
it.

`focus 25m` - or 90m, 2h, 45, 45s - starts one small watcher, a detached `sh`,
that restores the original file when the deadline passes. The next start of
Freebuff reads ads-on code again, with nothing to type. A window that is open at
the deadline keeps the code it started with, so it stays quiet until it
restarts; nothing here restarts it for you.

`focus session` starts the same watcher, waiting on Freebuff itself: when the
orchestrator process exits, the original file goes back, so the next launch has
ads. That is the one for "quiet while I work, ads back next time".

The watcher is the only thing this tool leaves running. It writes nothing at all
if the file changed since the patch - a Freebuff update or a fresh install makes
it stand down rather than overwrite. `unfocus` stops it, and so does a second
`focus`. `status` says which mode is on and what will end it.

AFTER A FREEBUFF UPDATE
-----------------------

Every update replaces the app's Resources folder, so the patch goes away. Run
install again after an update. For a newer version of this tool itself, run
`freebuff-focusmode update` once it is installed (or `sh freebuff-focus.sh
update`, which replaces that copy in place and then patches again).

An update can also change the code the tool looks for. Each anchor has a
literal form and a relaxed one; the relaxed form is only used when it appears
the expected number of times AND ad code sits beside it, and the write is
undone if the check afterwards disagrees. When an anchor does not fit, install
refuses and prints the counts it saw - "render ambiguous, literal: 2 match(es)"
- so you can see whether the shape changed or only the number of times it
appears. To get the full report:

  sh freebuff-focus.sh scan                     (a local copy of the tool)

  curl -fsSL https://freebuff-focusmode.vercel.app/downloads/freebuff-focus-desktop.sh | sh -s scan

Both list every candidate site the build has, write a copy to your backup
folder, and touch nothing inside the app. The piped one is for when you ran the
one-liner above and have no local copy to point at.

IS IT ACTUALLY OFF?
--------------------

A patch on disk is not a patch in effect. The orchestrator is read once, when
Freebuff starts, so patching a running app changes nothing until it is
relaunched. That is what `verify` is for:

  sh freebuff-focus.sh verify

It waits for Freebuff to be quit and reopened, then compares two times - when the
patch was written, and when the process running now started. Started later means
the app you are looking at is the one that read the patched file. It also lists
the ad code still in the build, so you can see the patch is aimed at something
real rather than at code that has moved. `install` runs the same check for you
whenever Freebuff is open, which is why it sits and waits after patching.

  sh freebuff-focus.sh verify --no-wait       report now, do not wait
  sh freebuff-focus.sh verify --timeout 60    wait at most a minute

The one thing none of this can see is whether an ad break still appears - that is
the app's behaviour, and only you can watch it. On the free tier, run a turn and
watch the thread: an ad card is the one carrying an "AD" chip or a /track/click
link. If one appears with both markers applied and the process started after the
patch, that is worth reporting - it means Freebuff has a second ad path, and the
scan report above is what a re-anchor needs.

WHAT IT DOES
------------

It only touches the ad code in
Contents/Resources/orchestrator/orchestrator.js. It forces the gate the ad
auction consults to return "no ads to show", and makes the ad client's own
request helper fail before it sends, so none of the /api/v1/ads/* calls can be
reached. Nothing else changes - in particular the log shipper that posts to
/api/logs is left alone.

It refuses to run unless every anchor it expects is found the exact number of
times it expects, so a Freebuff version that renames something fails safe and
changes nothing rather than half-patching a 9 MB file. A relaxed match is
accepted only when ad code sits beside it, so a similarly shaped gate elsewhere
in the bundle is never mistaken for the ad render path. The untouched original
is backed up before the first write, and `revert` puts it back.

Upstream source and licence (MIT):
  https://freebuff-focusmode.vercel.app

Patching a third-party application's bundled code may conflict with that
application's terms of service. Use it on your own machine, at your own
discretion.
