Skip to content

Tags: profullstack/cli-tools

Tags

v0.51.1

Toggle v0.51.1's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
dev2: deploy-app.sh rolls back on any failure after the swap starts (…

…0.51.1) (#122)

Under set -e, a failed `compose up` or `compose down` exited the script before
its health check and rollback ran, so a deploy that had already removed the old
container could leave the site down. The rollback path also rebuilt the old
revision, which fails the same way when the build is what broke.

Now the images the running containers came from are recorded (and pinned as
<name>:rollback) before anything is touched, and an ERR trap plus the health
check failure both re-tag them and `compose up --no-build`. A failed build exits
before the snapshot with the running stack untouched. The subnet grep no longer
kills the script when a compose file has no subnet.

test/dev2-deploy-app.test.ts drives the script against a fake docker: build
failure, failed up, unhealthy image, healthy deploy.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

v0.51.0

Toggle v0.51.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
alchemy: Alchemy's CLI as a command, installed on first use (0.51.0) (#…

…121)

A launcher for @alchemy/cli in the openmcp shape: everything is passed
through, the first run installs into ~/.local/share/cli-tools/vendor/alchemy,
--self-update and --self-where are ours. A global copy that is not this
wrapper (moshcode install alchemy makes one) is used as it is.

That copy is exec'd by its PATH name, not its realpath: under mise the global
bin is a shim symlinked to the mise binary, and exec'ing the realpath ran
`mise --json ...`. firstOnPath is exported from registry.ts for it.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

v0.49.1

Toggle v0.49.1's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
gh-pulse: a lock that names no pid is stale, not pid 0 (0.49.1) (#114)

An empty run.lock read as Number('') = 0, and kill(0, 0) signals our own
process group, so it always looked alive: every daily run since 2026-09-24
refused with 'another gh-pulse run is in progress (pid 0)'. The holder is
now parsed strictly (positive integer or nothing), isAlive refuses pid <= 0,
and the lock is written to a temp file and renamed so a run killed mid-write
cannot leave an empty one behind.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

v0.48.0

Toggle v0.48.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
mail send --html: a multipart/alternative message from the CLI (0.48.…

…0) (#94)

The library already carried an HTML part through SMTP, Resend and the Forward Email defang; only bin/mail.ts had no way to set it. --html P reads a file into that part and the text from --body, --file or stdin stays the plain part. With --html and no --body or --file, piped stdin is still the text; only when nothing is piped does the text fall back to the HTML with its tags stripped, instead of refusing a terminal. The body logic moves into an exported bodiesFrom with an injectable stdin, which the new tests drive.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

v0.47.0

Toggle v0.47.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Document the tea knobs, release 0.47.0 (#93)

The header's Environment list is the only place a reader looks for these,
and #92 shipped CLI_TOOLS_SKIP_TEA and TEA_CLI_VERSION without adding
them to it. A list that omits two of its own knobs is worse than no list:
it reads as complete.

Bumps to 0.47.0 so the tea install reaches boxes as a release like
everything else here.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

v0.46.0

Toggle v0.46.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Release 0.46.0: jobhunt (#90)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

v0.45.0

Toggle v0.45.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
icon hq: the optional HQ style, full-colour icons at the OpenEmoji ba…

…r (0.45.0) (#84)

* icon hq: the optional HQ style, full-colour icons at the OpenEmoji bar

UI icons are drawn by gpt-image-2 as edits pinned to their own simple line
glyph (first reference: keep silhouette and meaning) and three OpenEmoji
masters (the look), with a colour-by-meaning rule so the set spans the
spectrum. Stops on credit exhaustion, backs off on 429, never redraws a
master. Brands take the owner's colour (Simple Icons hex, or a cited brand
page for the nine Font Awesome logos), never a model. Writes hq/png,
hq/webp/{64,128}, hq/svg for brands, and an hq block per icon plus styles
and hq top-level in openicon.json; icon build preserves it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* icon hq: colour is set per icon, not left to the model; outlines become solid bodies

Left to the model the set drifted to one hue (orange with warm references,
blue with cool ones). Each category now has its own colour and meaning
overrides it (green add/check, coral red delete/error, gold star/key/warning,
steel lock). Outlined shapes are filled as solid glass instead of traced as
hollow tubes. Style references: laptop, gem, light bulb.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* icon hq: describe form-control keys whose names mislead the model (radio-off drew a radio set)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* icon: 0.45.0 for the HQ style

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

v0.44.0

Toggle v0.44.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Emoji command (#83)

* emoji: every standard emoji, drawn by an image model as one set (0.41.0)

`emoji generate` draws all 3,963 fully-qualified sequences in Unicode's
emoji-test.txt with gpt-image-2 under one art direction. Six anchors are
drawn first and every later glyph is an edit that sees them, so the set
does not drift; skin-tone variants are edits of their base that change the
skin only. Resumable: a master that exists is never redrawn.

`emoji build` derives the rest offline: PNGs at 16-512, posterised SVGs
(vtracer), CBDT and sbix colour fonts (nanoemoji, via uv), CSS, a preview
page and an OpenEmoji manifest (logicsrc.com/openemoji).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* emoji: list every emoji in the manifest, CLDR keywords, webp previews, incremental build

The manifest now carries all 3,963 entries; only drawn ones have files, so
a catalog can show the whole set while it is being drawn. Keywords come
from CLDR annotations (base + derived, matched without FE0F). build writes
webp/64 and webp/128 and skips glyphs whose outputs are newer than the
master. prompts.jsonl is appended per glyph so a killed run keeps it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* emoji: art direction forbids look-alikes of film, game and brand characters

The first People & Body run drew a genie, fairy and merperson close to
well-known film designs; the set is CC BY, so every design must be its own.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* emoji export: bundles for 22 networks, verified limits, stickers where emoji are not supported

emoji export writes per-network packs sized, encoded and named to each
network's documented rules (checked against official docs and source,
2026-09-24): Slack, Discord, Stoat, Mastodon (tootctl tarball), Misskey
(meta.json zip), Pleroma/Akkoma (pack.json), Mattermost, Zulip,
Rocket.Chat, Teams, Matrix, Telegram emoji and stickers, Signal and
WhatsApp (.wastickers) sticker packs, Twitch, YouTube, Reddit, Kick, and
X / Bluesky / Threads-Instagram-Facebook-LinkedIn as images to post, with
X opening on flags. platforms.json carries the same table for the catalog.
Manifest entries gain their oe_ shortcode.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* emoji export: palette PNGs (4x smaller), archives as release assets

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

v0.36.1

Toggle v0.36.1's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
gh-pulse: quiet cron, a clamped spinner, a rescan that rescans (0.36.…

…1) (#73)

Follow-ups from a review of the busy indicator. The daily run handed its
per-ten progress counts to the plain logger when stderr was not a terminal,
so every cron.log grew ~70 lines it never had; the counts now ride the
spinner only on a terminal and cron prints exactly what it printed before.
The command-line spinner clamps its row to the terminal width (an overlong
row walked down the screen a row per tick) and stops exactly once (the
range path could stop it twice and print the last line twice). In the TUI,
`r` finally forces a rescan (force was dropped at the ShowOptions boundary
and the hour-fresh cache came back), a "still scanning" notice no longer
outlives the scan, and the loading range button uses the ascii frames on a
terminal without Unicode, like the spinner line does.


Claude-Session: https://claude.ai/code/session_011gfb1vcQH5rf82HfbJvf1Z

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>

v0.36.0

Toggle v0.36.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
gh-pulse: throttle the hour (0.36.0) (#72)

A run died this morning with GitHub 403, rate limit exceeded, ten repos
into the events step, and the spinner kept ticking after the error
because the queue went on draining in the background. Four range scans
and a daily run in one hour had spent the whole 5,000-call budget the
token shares with gh and everything else, and the client's answer to a
403 was to wait at most two minutes, four times, then throw.

The GitHub client is now the only place the hour is spent, and it
behaves. GH_PULSE_RESERVE calls (default 500) are never spent: down to
the reserve, or rate limited anyway, a scan pauses until the hour
resets, on one shared pause for every in-flight request, for as long as
the headers say, and then carries on. Four requests in flight and 100ms
between starts keep it out of the secondary limits; retry-after is
honoured. Every reply is cached by ETag under <data>/cache and offered
back with If-None-Match, and GitHub does not charge for a 304, so an
unchanged page is free; since= is asked from the top of the hour so the
URL repeats and a rescan hits the cache, with the exact cutoff applied
to the items. Once a task has failed nothing queued behind it starts,
and show exits the process when the screen closes, so a crash or a quit
no longer spends the rest of the hour in the background. One daily run
at a time, through <data>/run.lock.

The budget is read off the first real reply's headers, not /rate_limit,
which reported a fresh hour for this token while real replies carried
4,695 left. Each scan logs what it has to spend and closes with what was
charged, what came from cache and what is left.

Measured live on one repo for the last hour: a cold scan charged 20
calls, the warm rescan 0, with 26 answered from cache.


Claude-Session: https://claude.ai/code/session_012nnVu9u7HeHEVRoCwKcQM3

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>