From fsi to fsd: rebuilding formseal-decrypt
A day ago, I wrote about moving formseal to a GitHub organization. That post covered the big-picture migration - renaming repos, setting up org structure, and the PyPI naming situation.
But there was another migration hiding inside that one: renaming the CLI tool from fsi to fsd, and making it modular in the process.
The context
formseal-inbox was named with a vague idea in mind - I imagined it becoming some kind of terminal inbox, messages, viewing, maybe a TUI. That never happened. The tool was always just a decryptor:
ciphertexts.jsonl → decrypted data
At some point "inbox" started feeling wrong. The name implied features that didn't exist and kept me entertaining ideas that had no business being in a decryption tool. So I renamed it:
formseal-inbox → formseal-decrypt
fsi → fsd
But while I was at it, I rebuilt the output system to be modular - so adding new formats down the line would be straightforward instead of a mess of if/else.
What changed
Package renamed
fsi/ → fsd/
fsi/fsi.py → fsd/fsd.py
Every import shifted from from fsi.ui import ... to from fsd.ui import .... Tedious but clean.
Output formats became modular
Originally, decrypt just hardcoded JSONL output:
with open(dest, 'w') as f:
for msg in decrypted:
f.write(json.dumps(msg) + '\n')
Now there's a proper format system with a base class:
# formats/formatter.py
class Formatter(ABC):
name: str = ""
extension: str = ""
@abstractmethod
def write(self, data: list[dict], path: Path):
pass
Each format lives in its own file:
formats/
├── formatter.py # base class
├── jsonl.py
└── json.py
Adding CSV or table output later is just: drop in a new file, register it, done. No touching the core decrypt command.
Connect now asks for format
Source File (ciphertexts): formseal.ct.jsonl
Destination Directory: ./output
Output Format [JSON Lines, JSON]: json
Private Key: <your-key>
Saved in config so you don't have to specify it every time. And the before/after is pretty clean:
# Before
fsi decrypt # jsonl, no choice
# After
fsd decrypt --format json
Issues I hit
Nothing catastrophic, but a few things that were easy to miss:
- GitHub Actions still pointed to
fsi/directories that no longer existed. The inject-version workflow was trying to update a file path that had moved. Quick fix once I caught it. - Empty
__init__.pyfiles were scattered everywhere - unnecessary once you explicitly list packages inpyproject.toml. Deleted most of them, kept the ones with actual imports. - Docs took longer than expected. README, CONTRIBUTING, SECURITY - all had old repo references (
grayguava/formseal-inbox→useFormseal/decrypt) and old command names. Not hard, just slow.
[!NOTE] Core decryption logic stayed completely untouched - NaCl sealed boxes, base64url handling, error flows. Only output handling changed.
Version bump
The old formseal-inbox was at v0.1.0. Given this is a new repo with a meaningful refactor, I bumped to v0.2.0. I'll create a v0.1.0 tag pointing back to the old inbox repo for continuity.
Where this leaves us
| Tool | Status |
|---|---|
| formseal-embed | active |
| formseal-fetch | active |
| formseal-decrypt | active |
| formseal-inbox | archived |
The rename forced me to actually think about what the tool is. The answer was simple: just a decryptor. And that simplicity is worth preserving.