You are browsing as a guest. Sign up (or log in) to start making projects!

Hackfetch

  • 16 Devlogs
  • 99 Total hours

custom fetch tool built for hack clubbers. live hackatime stats, 7 hack-club logos, and a leaderboard so you can see who's crushing it today.

Open comments for this post

9h 26m 5s logged

big thank you for everyone’s feedback! :dance_catgirl:

fresh out of the oven: hackfetch v2.1.1 (aka the reviewer bug fix pass)

what got fixed: :miku-spin:

  • shell detection used to just read $SHELL which is your login shell. if you log in as bash but run fish, hackfetch was calling you a bash user. it now checks $FISH_VERSION / $ZSH_VERSION / $BASH_VERSION and falls back to asking the OS who your parent process actually is

  • editor detection was two bugs in a trench coat. it wasnt stripping args so zeditor --wait showed up as “zeditor –wait” instead of “Zed”, and if you had no $EDITOR set it defaulted to nano even if you had literally never opened nano. now it strips flags, maps launcher names to human ones (zeditor -> Zed, code -> VS Code, cursor -> Cursor, hx -> Helix etc), and says “-” instead of nano if nothing is set.

  • top project label was ambiguous. it was pulling weekly stats but the row just said “top project” so people thought it meant all time. now weekly rows read top proj 7d, top lang 7d, top ed 7d, top cat 7d.

  • setup dialog was scaring people. it always printed “file exists but has no api_key” whenever it reached the setup flow, even if the api_key line was actually there but just failing to parse. loadConfig is now more forgiving (inline comments, quoted values, case insensitive keys) and setup tells you WHY its stuck instead of gaslighting you about your own config. also short circuits if you run hackfetch -setup when youre already set up.

  • people said they wanted a gay flag color was already there under the name pride but that wasnt obvious. gay is now an alias so both work.

grab it: :dance:

brew upgrade hackfetch

or

yay -S hackfetch-bin

or curl / powershell installer if you don’t have it yet

curl -fsSL https://raw.githubusercontent.com/xerneas3318/hackfetch/main/install.sh | sh

again thank you to everyone who took the time to actually run it and tell me what was broken! :dance-dance:

0
0
10
Open comments for this post

10h 34m 34s logged

hackfetch COLLAB?? :yay:

so my last two devlogs teased two features. shipping both today.

-leaderboard

last devlog i said “compete with your friends on hackatime hours is coming soon.” i thought i was gonna have to build a whole nest server for it. turns out /api/v1/leaderboard/daily and /api/v1/leaderboard/weekly already exist and are public on hackatime. just a single call!! :dance_catgirl:

so hackfetch -leaderboard daily (or weekly) now shows the top 10:

✦ daily leaderboard Last 24 hours

🥇  1. soaphia14                11h 12m
🥈  2. AnastKara               10h 32m
🥉  3. RoSerMar                10h 6m
      4. euledone                 10h
      5. TheShovel               10h
      6. Dylhouse                 9h 1m
      7. Dexrn                         8h 59m
      8. HexFud                     8h 31m
      9. zeddash                   8h 29m
     10. Trtotomotoro        8h 26m

every username is an OSC 8 clickable link to that person’s hackatime profile. modern terminals (iterm2, kitty, wezterm, alacritty, gnome-terminal) render it as an actual hyperlink you can click. terminals without OSC 8 just show the plain text so it doesnt look broken.

if you’re on the board it highlights your row in orange and adds (you) next to your name.

json addon

the other thing. someone else competing in stardance messaged me the other day about integrating hackatime into their own project and needed help figuring out the api (YAY). helping them made me realize hackfetch is doing a bunch of work (auth, caching, streak reconstruction, per-day bucketing) that other tools would love to piggyback on. so now:

$ hackfetch -json
{
  "version": "2",
  "fetched_at": "2026-07-25T17:00: 20.900829+05:30",
  "system": {
    "user": "xerneas",
    "host": "Macbook-Pro",
    "os": "macOS 26.5.2",
    ...
  },
  "hackatime": {
    "slack": "@U0B8FHHRQPJ",
    "streak": 12,
    "today_seconds": 15820,
    "week_seconds": 237501,
    "top_project": { "name": "hackfetch", "
    "top_language": { "name": "Go", "seconds": 97418 },
    "week_chart": [36967, 31651, 33841, 284
    "machines": 3
  }
}

week_chart is 7 numbers = daily seconds oldest to newest same as the sparkline. top_language skips the unknown/other buckets. everything lines up with what the normal fetch would show, just parseable. :miku-spin:

ship

landed in v2.1.0.

brew update && brew upgrade hackfetch

or arch:

yay -Syu hackfetch-bin

then try:

hackfetch -leaderboard weekly
hackfetch -json | jq

For a general install use:
curl -fsSL https://raw.githubusercontent.com/xerneas3318/hackfetch/main/install.sh | sh

3
0
35
Ship #2 ✨ Blessed

HACKFETCH V2.0

it’s been a few weeks since ship #1 and hackfetch is a completely different tool now. faster, smaller, quieter, actually correct, and now lives in places besides your terminal window. v2.0.0 is out.

what changed:

  • fits in your tmux status bar with one line of config. same story for lualine. hackfetch -status prints a compact one-liner meant to be shelled out to every minute.
  • fits everywhere else too. now on the AUR (yay -S hackfetch-bin) alongside the existing brew tap, curl installer, powershell installer, and go install. seven install channels total.
  • runs in ~20ms on repeat calls thanks to an on-disk cache. tmux polling every minute is basically free now. was ~700ms cold before.
  • runs in ~0.7s cold thanks to a parallel API fetch. was ~1.7s before.
  • shows a smooth truecolor gradient on any modern terminal. auto-detects $COLORTERM. falls back to 256-color on older ones.
  • -doctor walks a colored checklist of your setup and tells you exactly what’s broken. green if fine, orange if not, non-zero exit if you wanna script it.
  • new pizza logo because hack club runs on pizza. seven logos total.
  • streak is finally correct after silently saying “1 day” for a month. /summaries is gone from hackatime so hackfetch now reconstructs streak from every coding session in your history via /heartbeats/spans. real streak: 9 days for me right now.
  • 7-day sparkline baked into the fetch (with -v) and available as -status –sparkline for the tmux bar.
  • default fetch got leaner. slack handle, machines count, and the sparkline moved behind -v so the normal fetch stays focused on hours + project + language.
  • loading spinner on the api fetch so you know something is happening. and then the cache made it show up almost never.

one install:

Linux / Mac:
curl -fsSL https://raw.githubusercontent.com/xerneas3318/hackfetch/main/install.sh | sh

Windows:
irm https://raw.githubusercontent.com/xerneas3318/hackfetch/main/install.ps1 | iex

Arch family:
yay -S hackfetch-bin

macOS / Linuxbrew:
brew install xerneas3318/tap/hackfetch

For more install methods check out the github page:
https://github.com/xerneas3318/hackfetch

teasing the next big thing: hackfetch -leaderboard is coming next, using the public leaderboard endpoints i found in hackatime’s routes file. compete with friends on daily and weekly hours right from your terminal. private friend groups on a hackclub nest box after that.

if you try it, thanks. send me some feedback

  • 7 devlogs
  • 61h
  • 19.60x multiplier
  • 1381 Stardust
Try project → See source code →
Open comments for this post

8h 38m 34s logged

my streak was lying to me for a month :dance_catgirl:

went to add a simple 7-day sparkline. by the end of the night i had rewritten how hackfetch talks to hackatime and my streak field is finally accurate for the first time in weeks.

the plan was get the status from the last 7 days. draw ▁▂▃▄▅▆▇█ bars :miku-spin:

except the endpoint i needed straight up 404s. /users/current/summaries doesnt exist on the current hackatime deployment.

Which means every single time i ran hackfetch it was quietly making a 30-day range call that always failed, then falling back to a placeholder that said “if today has activity, streak = 1”. thats it. no matter how long ive actually been on a streak, the fetch would just show 1 day. 🤦

my streak has said 1 day for the last 2 weeks even though ive been coding literally every day. never noticed because 1 day looks kinda plausible (i added 1 day as a fallback so that it didn’t show an error a couple weeks ago and forgot :shrug-1-67: )

the fix:

went digging in hackatimes rails routes on github. turns out theres a whole /api/v1/ namespace i was never using. and one of the endpoints is /api/v1/users/:id/heartbeats/spans. one call, ~150kb of json, every coding session ive ever logged with start_time, end_time, duration. 2000+ spans.

which is exactly what i need for both features. bucket the timestamps by local calendar day, count unique days for streak, sum durations per day for the sparkline. one request covers both. and while i was already in the api layer i noticed fetchUser was making a whole separate call for my slack handle, which is silly because that data is already in the weekly stats response we cache. so i piggybacked it. weve gone from 4 api calls per fetch to 3.

the sparkline:

7-day chart ▄▄▇▅▄▅▃ 65h 28m

oldest on the left, newest on the right. that tall bar in the middle is a big lock-in session from earlier in the week. the two shorter ones on the right are today (still coding) and yesterday (took a break).

opt in for -status --sparkline if you want it in your tmux bar too:

2h 9m today · streak 9 · ▄▄▇▅▄▅▃ 65h 28m

teasing a backend:

I’m planning on building a whole leaderboard server on a free hack club nest box so people can compete on their hackatime hours. while i was poking around the routes file for the streak fix i noticed something.

/api/v1/leaderboard/daily and /api/v1/leaderboard/weekly already exist. public. no auth needed. no server needed. no cron sync. hackatime literally already has it directly.

so hackfetch -leaderboard is coming soon (private friend groups and personal competitions can come later)

last devlog before my next ship

after the ship the devlogs are going to be huge.

stay tuned :P

0
0
41
Open comments for this post

9h 46m logged

caching or i owe hackclub money :dance_catgirl:

so heres what my day looked like: nvim was calling hackfetch -status on every redraw for my lualine. tmux was calling it every 60 seconds for the status bar. i had 3 tmux sessions open. and every time i actually opened a new terminal, hackfetch fired again on shell start.

quick napkin math: nvim redraws are basically continuous when im typing, tmux was hitting the api 3x/minute across sessions, plus every terminal open = another fetch. we’re talking hundreds of calls to hackatime in a normal work session. from ONE user.
me :menhera-point:

hackatime is a free hack club service and i was starting to feel bad lol. :mikustare:

the fix: cache the response
~/.cache/hackfetch/last.json stores the last snapshot with a timestamp. every fetch checks that file first. if its fresh enough, skip the network entirely and just render from disk.

TTL is different depending on the caller:
hackfetch (one-shot): 30 seconds. long enough that a normal re-run inside a devlog attempt is instant, short enough that you dont get badly stale numbers.
hackfetch -status: 60 seconds
tmux polls roughly this often anyway so its basically free now.

hackfetch -watch: ignores the cache, always fresh (thats the whole point of watch mode).

opt out with -no-cache or HACKFETCH_CACHE_TTL=0 if you want. also HACKFETCH_CACHE_TTL=300 to be even more polite.

So yea tmux is now basically free. :agadance:

but the real win writing this made me realize the cache does more than save milliseconds:

  • every fetch was a full TLS handshake, wifi radio spin up, etc. now most fetches touch the disk once and nothing else. macbook fan appreciates it.

  • offline. if your wifi drops mid coding session you keep working from the cache instead of showing a spinner forever. tmux bar just keeps saying what it said 40 seconds ago.

  • battery again but for the hackatime server. hackfetch stops asking the api 5-10x more than they need to. multiply by everyone who has it in their tmux config and thats a real thing.

  • atomic write via .tmp + rename so nothing ever reads a half-written file. cache is user-only (0600), because it does contain your top project name.

bonus: -doctor :agasp:

while i was fixing the polite-to-the-api stuff i added -doctor, which walks a checklist and tells you whats broken:

hackfetch doctor
✓ wakatime config exists       /Users/xerneas/.wakatime.cfg
✓ api_key present              loaded from config
✓ wakatime-cli found           /Users/xerneas/.wakatime/wakatime-cli
✓ hackatime api reachable      today: 28m
✓ terminal supports truecolor  $COLORTERM=truecolor
✓ browser opener available     /usr/bin/open

green if its working, orange if its not, and non-zero exit if anything failed so you can script it. this was going to be a small self-diagnosis feature and it caught a real bug in the api client on the very first run i did while writing it lol (a string field where hackatime returns an int, so one of the fields was silently missing from every fetch since v1.0). fixed that too.

ship :miku-spin:

both landed in v1.10.0. update as usual:

brew update
brew upgrade hackfetch

or arch:

yay -Syu hackfetch-bin

then run hackfetch -doctor first, and if anything is broken it’ll tell you exactly what.

2
0
88
Open comments for this post

8h 25m 29s logged

hackfetch is now TMUX + NVIM COMPATIBLE :party-11ty:

new thing today: hackfetch will just show up wherever you already look. tmux status bar. nvim statusline. any tool that can shell out to a command and put text on a screen.

The addition was simple:

hackfetch -status
prints one line:

2h 11m today · hackfetch (45m) · streak 12

just the numbers, for tools that already have their own rendering. hackfetch is a data source now, not just a display.

in tmux

two lines in ~/.tmux.conf:

set -g status-interval 60

thats it. every tmux session, every window, refreshing once a minute. i dropped it in a pink Catppuccin capsule to the left of my existing date capsule and now i cant stop glancing at it lol.

in neovim (lualine)

same story, five lines of lua:

  sections = {
    lualine_z = {
      function()
        return vim.fn.system("hackfetch -status"):gsub("\n", "")
      end
    }
  }
}

shells out on every redraw. works with airline too, or any custom statusline that lets you plug in a function.

the fun part

making hackfetch call safe for “something tmux runs every 60s forever” meant fixing three assumptions the normal fetch was making. this was way harder than it should have been ngl.

setup cant block. if you dont have ~/.wakatime.cfg, normal hackfetch throws you into an interactive setup wizard (ask me how i know). in status mode that would freeze your tmux bar until you notice and Ctrl+C it. so status mode is fully non interactive now.

no config → print nothing → tmux shows nothing → no deadlock 🙏

api errors cant leak into your bar. hackatime offline? old behavior would dump HTTP 500 timeout into your status area which looks INSANE. now status mode exits silently instead so your bar stays clean

every call has to be cheap. hackfetch’s parallel fetch alr seconds, and the shared HTTP client keeps connections alive across the 4 API calls it fires, so tmux polling every 60s is easy on the API. a proper local file cache is on the list for later but honestly not
needed for now (i’m lazy)

ship

landed in v1.9.0. if you already have it:

brew update
brew upgrade hackfetch

or arch family:

yay -Syu hackfetch-bin

(for more installs for ur specific os check out the github pls)

then drop the tmux or lualine snippet above into your dotfiles and its just there in every terminal. no plugin. no config. no daemon. just a flag.

0
0
44
Open comments for this post

8h 43m 39s logged

Hackfetch Gets Real Colors

New thing today: hackfetch now emits 24-bit color when your terminal supports it, and spreads gradients smoothly across each row instead of cycling through the palette one character at a time.

Before and after

Old behavior: for a per-char scheme like rainbow, each character got exactly one palette entry, wrapping around every N characters. On a 30-column row with a 3-color palette, that looked like ten cycles of red, green, blue, red, green, blue… basically RGB static.

New behavior: the palette spreads across the row once, and characters between palette entries get interpolated in-between colors. Same 3-color palette on a 30-column row now shows red, olive, green, teal, blue, magenta, back to red.

Why the rebuild

Terminals speak two color modes:

  • 256-color (\x1b[38;5;Nm): pick from a fixed palette of 256 preset RGB values.
  • 24-bit / truecolor (\x1b[38;2;R;G;Bm): specify any of ~16 million RGB values directly.

The old code always used 256-color. That meant every character had to snap to one of the palette entries. No in-betweens possible.

The new code checks $COLORTERM (set to truecolor by iTerm2, kitty, WezTerm, Alacritty, GNOME Terminal, and most modern terminals) and emits 24-bit escapes when supported. When it’s not, it falls back to the old cycled-palette behavior automatically.

You can force it either way with HACKFETCH_TRUECOLOR=1 or =0.

Where you’ll notice it

The built-in rainbow scheme has 23 palette stops, so the difference on that one is small. You just see a smoother color distribution and less banding.

The change is dramatic on:

  • custom themes with few stops (try 3 colors in your ~/.config/hackfetch/colors.json for the wildest gradient)
  • the stardance palette (11 stops, per-char), where sparkles now flow through the spectrum in order instead of landing on random-looking colors
  • any per-line scheme (pride, trans, bi, pan, sunset, ocean, forest) since they now emit exact RGB values instead of nearest-256-color

Bonus: the SVG, PNG, and JPG export paths use the smooth interpolation too, so exported cards look better regardless of your terminal.

Ship

Landed in v1.8.0.

brew update
brew upgrade hackfetch

Or on the Arch family:
yay -Syu hackfetch-bin
 
Try hackfetch rocket forest and just watch.

1
1
818
Open comments for this post

9h 58m 35s logged

One More Way to Install (and Pizza)

Two small things today: hackfetch is now on the AUR, and there’s a new logo.

hackfetch on the AUR

A reviewer on my last ship said they had a hard time getting hackfetch running on CachyOS (an Arch-based Linux distro). Instead of trying to reproduce their exact issue, I figured the cleanest fix was to publish hackfetch through the package manager Arch users already trust.
 
So hackfetch is now up as hackfetch-bin on the AUR: aur.archlinux.org/packages/hackfetch-bin
 
If you’re on Arch, CachyOS, Manjaro, EndeavourOS, Garuda, or any other Arch-based distro:

yay -S hackfetch-bin

Or with paru:
paru -S hackfetch-bin

The package pulls the pre-built binary straight from the GitHub release, so there’s no waiting on a source build. Works on both x86_64 and aarch64.
 
Add it up and hackfetch is now installable one command from:

  • brew (macOS and Linuxbrew)
  • apt / dnf / yum / pacman / zypper / apk (all through the curl installer)
  • the AUR (Arch family)
  • go install (any platform with Go)
  • the PowerShell installer (Windows)

This thing is getting kind of hard to NOT install.

Pizza logo

Hack Club runs on pizza. Now hackfetch does too.
 
hackfetch pizza
 
It’s a triangular slice viewed from the tip, HACK CLUB baked into the middle, and a rolled crust at the wide edge.
 
The tricky part was the crust. I went through three drafts trying to make it curve at the bottom without breaking the connection to the slice’s diagonal sides (turns out you can’t cleanly connect diagonal characters to horizontal ones in a monospace grid). Landed on a two-row rolled crust where the diagonals keep going and the interior fills with a double horizontal band.
 
Pairs surprisingly well with sunset:
 
hackfetch pizza sunset
 
Turns your terminal into a golden-hour pizza box.

Ship

Both landed in v1.7.3. If you’re on Arch-family:
 
yay -S hackfetch-bin
 
Elsewhere:
 
brew update
brew upgrade hackfetch
 
Now try hackfetch pizza and tell me if the crust looks right.

0
0
24
Open comments for this post

3h 11m 20s logged

Hackfetch Is Now Actually Fast

Last log I added a loading spinner so you’d have something to look at while hackfetch was hitting the Hackatime API. This week I made it so you barely have time to see the spinner at all (undoing all my work lol)

The problem

hackfetch was making four separate calls to Hackatime for every fetch:

/users/current/heartbeats/most_recent (for your slack handle)
/users/current/summaries (for your streak)
/users/current/statusbar/today (for today's coding time)
/users/current/stats/last_7_days (for weekly stats)

Doing them one after another meant the total wait was the sum of all four. Turns out that’s about 1.7 seconds on a normal connection. Not the end of the world, but very noticeable when you just want to open a terminal.

The fix: run them all at the same time

Now hackfetch fires all four calls in parallel using goroutines, waits for the slowest one to come back, and then builds the fetch from the responses. Total wait drops from “sum of all four” to “just the slowest one.”

  • Before: ~1.7 seconds
  • After: ~0.7 seconds

60% faster. Every single fetch. Every single time.

One tiny bonus optimization

While I was in there, I also switched to a single shared HTTP client with a bigger connection pool. The default Go setup caps you at 2 open connections per host, which is fine when you’re calling one endpoint at a time but hurts when you’re firing four at once. Now the parallel calls can share connections instead of stacking up on each other.

Nothing about the fetch itself changed. Same info, same layout, same colors. Just faster.

Ship

Shipped in v1.7.2. If you have hackfetch installed:

brew update
brew upgrade hackfetch
time hackfetch

Watch the spinner barely have time to appear.

0
0
19
Open comments for this post

12h 34m 59s logged

Loading Spinner and Splitting Up main.go

Thanks so much to everyone who took the time to comment, rate, and drop feedback on my latest ship. All of it was genuinely so helpful and I’ve been spending the last couple days fixing things up a bit. I totally forgot to devlog so I’m actually losing a couple hours since it’s been over ten hours since my last one :sob

A loading spinner while Hackatime fetches

One reviewer pointed out that hackfetch takes a couple of seconds when it’s pulling your Hackatime stats for the first time, and there was no signal that anything was happening. Now there is.

⠋ fetching Hackatime...

The spinner cycles through 10 braille frames and the whole line clears out the instant the fetch finishes. Same fetch, way less awkward pause.
Two small details that make it feel right:

  • It only shows when stderr is actually a terminal, so it doesn’t spam control codes into your log files if you redirect output.
  • It prints one frame immediately, so fast fetches still flash something instead of nothing.

hackfetch runs it around the API calls automatically. No config, no opt-in. It’s just there.

Splitting up main.go

Another reviewer said the 1.5k-line file was too much. They were completely right. hackfetch had grown into one giant main.go that held the logos, the color schemes, the Hackatime API client, the terminal render, the SVG exporter, the PNG rasterizer, everything.

Refactored today into files that each do one thing:

  • logos.go: the ASCII logos
  • colors.go: color schemes and the ANSI → hex table
  • config.go: reads ~/.wakatime.cfg
  • hackatime.go: the API client, caching, and language inference
  • sysinfo.go: OS, shell, editor, terminal
  • setup.go: the -setup flow
  • render.go: terminal render, watch loop, and layout
  • export.go: SVG, PNG, and JPG exporters
  • main.go: just flag parsing and the entry point (~100 lines instead of 1,600)

Same binary, same behavior, zero user-visible change. But next time I want to add a new logo or a new color scheme, I know exactly which file to open. Also way friendlier for anyone who wants to hack on it.

Ship

Both landed in v1.7.1. If you already have it:

brew update
brew upgrade hackfetch

Or the curl installer will pull v1.7.1 the next time you run it.

Try it.

0
0
25
Ship #1 ✨ Blessed

Every fetch tool tells you your OS. Mine tells you your streak.

hackfetch is a Hack Club themed terminal fetch tool. Inspired by neofetch (originally bash, now archived) and fastfetch (its C successor), written in pure Go. Instead of just showing your kernel and CPU, it pulls live stats from your Hackatime account: today’s hours, weekly total, current streak, top project, top language. Right in your terminal.

Six Hack Club themed ASCII logos (including my GOAT orpheus). Fourteen color schemes (pride, trans, bi, pan included). Live watch mode that refreshes while you code. And as of today, you can export the whole thing as a PNG, JPG, or SVG card and post it anywhere.

One line to install:

Linux / Mac:
curl -fsSL https://raw.githubusercontent.com/xerneas3318/hackfetch/main/install.sh | sh

Windows:
irm https://raw.githubusercontent.com/xerneas3318/hackfetch/main/install.ps1 | iex

Tell me how it was! Follow and like for updates.

  • 7 devlogs
  • 17h
  • 17.78x multiplier
  • 370 Stardust
Try project → See source code →
Open comments for this post

4h 15m 40s logged

New feature today: hackfetch can turn itself into a shareable image.

The goal was simple: your terminal fetch should be more than a terminal thing. If it looks cool on your screen, you should be able to post it in a Slack channel or drop it in a devlog without ever having to take a screenshot.

hackfetch -export card.svg

Run that and instead of printing to your terminal, hackfetch writes an SVG file that looks exactly like the fetch on your screen: logo on the left, stats on the right, rounded corners, monospace font, every color preserved.

Getting the general SVG output was the easy part. Draw a rectangle, put text inside it, done.

The hard part was preserving the colors.

Terminals speak ANSI 256-color codes. SVGs speak hex color strings. They don’t line up one-to-one, so a naive export just drops every color and produces a black-and-white version of the fetch. Not very shareable.

The fix: a lookup table from ANSI 256-color codes to hex values, plus a rendering path that emits every styled character as its own SVG element with the correct fill color.

That’s actually a lot of tspans. Schemes like per-char, where every single glyph has its own gradient stop, can produce hundreds of colored elements per fetch. But it works. The SVG renders smoothly in any browser and looks identical to what shows up in your terminal.

Use It Anywhere

Some things you can do with the exported card:

  • open it in a browser to see it
  • drop it into a Slack channel or a devlog
  • convert it to PNG with rsvg-convert if you need a raster image

hackfetch -export card.svg trans

Open it.

Post it.

Ship it.

0
0
18
Open comments for this post

2h 1m 10s logged

Live Hackfetch

New milestone today: hackfetch can now stay open and update itself while you code.

The goal was simple: run hackfetch once, leave it in the corner of your terminal, and watch the numbers move in real time as you work.

hackfetch -watch

Your today-hours tick up. Your top project changes when you switch repos. Your streak rolls over at midnight. All without running the command a second time.

The static render was already in place from the regular one-shot fetch. The new part was redrawing without scrolling.

That sounds simple. It is not.

In a terminal, every time you print something, it appends to the bottom of the screen. By default, refreshing the fetch would just print a second copy of itself underneath the first, then a third, then a fourth. Within a minute you’d have a wall of identical fetches scrolling away into the past.

The trick is ANSI escape codes. There’s a sequence that means “move the cursor up N lines” and one that means “clear the rest of the screen from here down.” Together they let you erase the previous fetch and redraw a new one in the same spot. Same screen, fresh data, no scroll.

Why every 30 seconds? Two reasons:

Hackatime aggregates heartbeats in 1-minute buckets internally, so polling faster than that doesn’t tell you anything new 30 seconds is fast enough to feel “live” without hammering the API for no reason

Ctrl+C to quit. Resizing the terminal doesn’t break it. Pair it with a gradient color scheme and the whole thing turns into a tiny dashboard for your coding session:

hackfetch -watch sunset

1
0
30
Open comments for this post

23m 30s logged

Hackfetch Installs Itself Anywhere

Hackfetch crossed another milestone today: you no longer need Go installed to use it. Or Homebrew. Or anything, really.

The goal was simple: one command, any Linux, any Mac, no prerequisites.

curl -fsSL https://raw.githubusercontent.com/xerneas3318/hackfetch/main/install.sh | sh

Run that on Ubuntu, Fedora, Alpine, Arch, openSUSE, whatever you have, and a few seconds later hackfetch is on your PATH.

Getting the basic installer working was the easy part. Detect your OS, detect your CPU architecture, grab the matching binary from GitHub Releases, drop it in /usr/local/bin. Standard installer stuff.

The harder problem was the script itself failing on some Linuxes.

I’d written the first version in Bash, with set -euo pipefail at the top and $'\033[1m' style escape sequences sprinkled through. Worked great on my Mac. Worked great on Ubuntu. Then I checked which shell Alpine Linux ships by default. Not Bash. The whole script would die on line one for anyone on a minimal container.

So I rewrote it in POSIX sh, which is the one shell every Unix system actually has. No Bash-isms, no fancy quoting, no pipefail. Smaller, dumber, way more portable.

Speaking Seven Package Managers

The next problem: the script needs curl and tar to do its job. If you don’t have them, normally you’d just be stuck.

Instead, the installer now detects your system’s package manager and installs the missing prereqs for you:

  • apt (Debian, Ubuntu)
  • dnf (Fedora, RHEL)
  • yum (CentOS, older RHEL)
  • pacman (Arch)
  • zypper (openSUSE)
  • apk (Alpine)
  • brew (macOS)

They all do the same thing. They all use different words for it. The installer knows all seven.

One line. Any Linux. No prereqs.

0
0
15
Open comments for this post

19m 10s logged

Hackfetch Meets Orpheus!

If you’ve been around Hack Club for more than five minutes, you know Orpheus. The little dinosaur shows up everywhere: stickers,
websites, T-shirts, hackathon merch.

Until today, he wasn’t in hackfetch. That’s been bugging me since v1.0.

The goal was simple: give Orpheus a spot in the logo lineup, the same way flag, bot, and rocket already have one.

hackfetch orpheus

Drawing him was the harder part.

Every logo in hackfetch has to fit inside a fixed width of 33 characters, otherwise the system info column next to it gets pushed off the screen. 33 characters is not a lot of room to draw a recognizable dinosaur, especially one with personality.

I tried him head-on first. It didn’t work. Round dinosaur faces in ASCII end up looking like blobs because you don’t have curves, only corners.

So I redrew him in profile. The result:

  • a snout sticking out to one side
  • one big eye (◉) that catches the light
  • a HACK CLUB body underneath
  • two tiny stubby legs at the bottom

Nine lines tall. No wasted rows.

He plays especially well with the gradient color schemes:

hackfetch orpheus -color forest
hackfetch orpheus -color sunset

Forest makes him look like he’s wandering through tall grass. Sunset gives him a “main character in the closing shot” vibe.

The mascot finally has a seat at the terminal.

Long overdue!

Also if any better artists want to have a crack at it, I’m super open to that, and I can credit you in my repo as a collaborator! THNX!

1
0
23
Open comments for this post

4h 44m 56s logged

Hackfetch Can Finally Fetch

Hackfetch crossed a pretty big milestone today: it actually fetches things.

The goal is simple: build a Neofetch-style dashboard for Hack Club.

Run a single command and get a snapshot of your machine alongside your Hack Club activity.

hackfetch

and instantly see information like:

  • OS
  • Hostname
  • Username
  • Shell
  • Terminal
  • Editor
  • Hackatime
  • stats

Getting the system information was the easy part. Go makes it straightforward to grab things like the current user, hostname, operating system, and environment variables.

The harder problem was rendering everything cleanly beside an ASCII logo.

Each logo has different dimensions and line lengths, so I ended up building a small layout engine that calculates the width of every logo row and pads it dynamically before printing the corresponding information. Without that, the text column slowly drifts into the logo and the entire fetch screen looks broken.

Hooking into Hackatime

The more interesting work was integrating with the Hackatime API.Hackfetch reads your API key from:

~/.wakatime.cfg

authenticates with Hackatime, and pulls fresh coding statistics every time you run the command.Right now it can display:

Today’s coding time
Weekly coding time
Current streak
Top project
Most-used language

No browser.

No dashboard.

Just a terminal command.

1
0
35
Open comments for this post

27m 3s logged

In honor of pride month, I have added a pride color scheme to my custom hackfetch. It is currently installable via brew. On macs, simply run:

brew install xerneas3318/tap/hackfetch

Currently working on better support for more operating systems. Follow and like to stay updated!

2
0
236
Open comments for this post

5h 6m 35s logged

Introducing hackfetch a tiny terminal fetch tool for hackatime. Run hackfetch and get your hours today, weekly total, streak, top project, and top language right in your terminal.

5 logos. 8 color schemes. mix and match:
hackfetch stardance rainbow

How it works: hackfetch reads your hackatime key from ~/.wakatime.cfg, fetches your Hackatime summaries and heartbeats, then renders your stats directly in the terminal.

0
0
52

Delete project?

Are you sure you want to permanently delete this project? This action cannot be undone.

All devlogs, followers, and associated data will be removed.

Followers

Loading…