展示 HN:我们用 Fortran 构建了一个仅限终端的 Bluesky / AT Proto 客户端
Show HN: We built a terminal-only Bluesky / AT Proto client written in Fortran

原始链接: https://github.com/FormerLab/fortransky

## Fortransky:一个Fortran Bluesky/AT 协议客户端 Fortransky 是一个基于终端的 Bluesky 社交网络客户端,独特性在于它使用 Fortran 编写。它利用 Rust 静态库来解码 AT 协议的 relay-raw 流,通过 `iso_c_binding` 和 C libcurl 接口将 Fortran 与 Rust 连接起来。 该客户端提供诸如时间线获取、作者订阅源、搜索、个人资料查看、撰写帖子以及基本的帖子互动(点赞、转发、引用帖子)等功能。它支持两种流模式:Jetstream(WebSocket,JSON)和 relay-raw(二进制 CBOR,由 Rust 解码)。会话数据存储在 `~/.fortransky/session.json` 中,需要应用程序密码进行身份验证。 安装过程包括使用 `cargo` 构建 Rust 桥接,然后使用 CMake 将其与 Fortran 代码链接。relay-raw 流路径需要 Python 依赖项 (`cbor2`,`websockets`)。目前,它显示原始 DID,尚未将其解析为句柄。最近的更新 (v1.1) 集成了原生 Rust 解码器,以提高性能和稳定性。

一位开发者,FormerLabFred,使用Fortran构建了一个名为“Fortransky”的基于终端的Bluesky/AT Proto社交网络客户端。这个项目的语言选择引发了好奇,开发者俏皮地暗示了一个伴随项目“Cobolsky”。 使用Fortran的原因在于保持这种“古老语言”的活力,它的直截了当、快速循环以及潜在的长期可用性——今天编写的代码理论上可以在未来几十年内保持不变地运行。他们还预计Fortran在未来版本中对信息流生成算法会有用。 开发者正在为Fortransky构建一个定制终端,但它在Swordfish90等复古终端上也表现良好。该项目旨在证明Fortran在现代软件开发中仍然有一席之地,甚至在社交媒体领域也是如此。
相关文章

原文

Yes, that Fortran.

A terminal-only Bluesky / AT Protocol client written in Fortran, with a Rust native firehose decoder for the relay-raw stream path.

Fortran TUI  (src/)
  └─ C libcurl bridge  (cshim/)
  └─ Fortran iso_c_binding module  (src/atproto/firehose_bridge.f90)
       └─ Rust staticlib  (bridge/firehose-bridge/)
            envelope → CAR → DAG-CBOR → NormalizedEvent → JSONL
            + firehose_bridge_cli binary  (used by relay_raw_tail.py)

Session state is saved in ~/.fortransky/session.json. Use an app password, not your main Bluesky password.


System packages (Ubuntu/Debian)

sudo apt install -y gfortran cmake pkg-config libcurl4-openssl-dev

Requires rustc >= 1.70. Install via rustup if not present:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Python deps (relay-raw stream path only)

The relay_raw_tail.py helper is launched as a subprocess by the TUI. It must be able to import cbor2 and websockets using whichever python3 is on PATH at the time Fortransky runs — not just in an active venv.

Option A — system-wide (simplest):

sudo pip install cbor2 websockets --break-system-packages

Option B — venv, then symlink or alias:

python3 -m venv .venv
source .venv/bin/activate
pip install cbor2 websockets

Then either run Fortransky with the venv active, or set:

export FORTRANSKY_RELAY_PYTHON=$PWD/.venv/bin/python3

(support for this env var is planned)


This builds the Rust bridge first (cargo build --release), then runs CMake. The Rust step is skipped on subsequent builds if nothing changed.


Use an app password created for Fortransky specifically. At the home prompt:

l
Identifier: yourhandle.bsky.social
Password/app password: <app password>

Session is saved to ~/.fortransky/session.json and restored on next launch. To log out: x


Command Action
l login + fetch timeline
x logout + clear saved session
a <handle> author feed
s <query> search posts
p <handle> profile view
n notifications
c compose post
t <uri/url> open thread
j stream tail
m toggle stream mode (jetstream / relay-raw)
q quit
Command Action
j / k move selection
n / p next / previous page
o open selected thread
r reply to selected post
l like selected post
R repost selected post
q quote-post
P open author profile
/query search
b back to home
Command Action
j / k move selection
n / p next / previous page
o open thread
r reply
b back
Command Action
j refresh
b back

jetstream — connects to Bluesky's Jetstream WebSocket service. Lower bandwidth, JSON native, easiest to work with.

relay-raw — connects to the raw AT Protocol relay (com.atproto.sync.subscribeRepos). Frames are binary CBOR over WebSocket. The native Rust decoder (firehose_bridge_cli) handles envelope → CAR → DAG-CBOR → normalized JSON. Python cbor2 fallback remains for fixture mode.

Native decoder detection order

  1. FORTRANSKY_FIREHOSE_DECODER environment variable
  2. bridge/firehose-bridge/target/release/firehose_bridge_cli
  3. bridge/firehose-bridge/target/debug/firehose_bridge_cli
  4. firehose_bridge_cli on PATH

Relay fixture (offline testing)

By default relay-raw uses a bundled synthetic fixture. To use the live relay:

FORTRANSKY_RELAY_FIXTURE=0 ./build/fortransky

Quick offline demo:

printf 'b\nm\nj\nb\nq\n' | ./build/fortransky

  • JSON parser is hand-rolled and lightweight — not a full schema-driven parser
  • relay-raw only surfaces app.bsky.feed.post create ops; other collections are filtered out at the normalize stage
  • Stream view shows raw DIDs; handle resolution (DID → handle lookup) is not yet implemented
  • The TUI is line-based (type command + Enter), not raw keypress
  • m and j for stream control are home view commands — go b back to home first if you are in the post list

v1.1 — Native Rust firehose decoder integrated. relay_raw_tail.py prefers firehose_bridge_cli when found. CMakeLists wires Rust staticlib into the Fortran link. JWT field lengths bumped to 1024 to fit full AT Protocol tokens. JSON key scanner depth-tracking fix (was matching nested keys before top-level feed array).

v1.0 — Like, repost, quote-post actions. URL facet emission.

v0.9 — Typed decode layer (decode.f90). Richer post semantics in TUI.

v0.7 — C libcurl bridge replacing shell curl. Saved session support. Stream mode toggle (jetstream / relay-raw).

联系我们 contact @ memedata.com