36 Commits
Author SHA1 Message Date
Brandon ThomasandClaude Opus 5.5 cbae640688 Add FigCraft; release 0.4.1 (#313)
* Add FigCraft to the launcher

FigCraft (storytold/figcraft): interface design and prototyping, the
thirteenth Craft App and the sixth in the New group.

- Catalog row (brand colour #02da96 from FigCraft's icon README), details
  page (no pictures yet), Linux desktop categories, icon tables, tagline
  in every catalog, xtask local mirror list.
- Icon copied unmodified from FigCraft's repo; ATTRIBUTION.md row.
- The Windows installer art fits five rows of icons.
- Test that a companion figcraft-server tarball is never picked as the app.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Release 0.4.1

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 12:28:29 -04:00
Brandon ThomasandClaude Opus 5.5 d6fdab6596 Release 0.4.0 (#291)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 06:29:23 -04:00
Brandon ThomasandClaude Opus 5.5 1aaf7b27be AGENTS.md: agents never land or approve third-party apps (#213)
A catalog row, download source or install path for an app outside storytold/, or a rule change
that would allow one, is for a maintainer to decide. Agents flag it and stop.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 05:41:18 -04:00
Brandon ThomasandClaude Opus 5.5 2b86d4ca52 Point the details pictures at storytold/craft-launcher-assets (#221)
The pictures repo was renamed from artcraft-launcher-assets to match craft-launcher. GitHub
redirects the old name for now, but the launcher should not depend on that.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 05:02:23 -04:00
Brandon ThomasandClaude Opus 5.5 a464e432b3 i18n(es): translate "Installed · latest {latest}" (#211)
#195 added the string and #196 marked Spanish complete; they landed together, so the
completeness test failed on main.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 02:02:14 -04:00
Brandon ThomasandClaude Opus 5.5 6e7a122866 Release 0.3.2: sign Windows builds again (#174)
Since the release workflow moved to craft-common-actions (#129), the caller
passed only the Apple and WINDOWS_CERTIFICATE secrets, not the AZURE_* ones that
Trusted Signing uses, so the 0.3.1 MSIs and portable exes came out unsigned.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 17:03:52 -04:00
Brandon ThomasandClaude Opus 5.5 b66486df82 Release 0.3.1: Linux riscv64 packages again under the shared release workflow (#170)
craft-common-actions calls `package.sh --formats deb,rpm,tar`, but package.sh
split formats on spaces only, so the riscv64 job built the binary, matched no
format, wrote nothing to dist/release and failed the 0.3.0 release at upload.
package.sh now accepts commas or spaces and rejects unknown format names.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 16:28:01 -04:00
Brandon ThomasandClaude Opus 5.5 41369d3416 Release 0.3.0; rustfmt platform.rs and install.rs (#160)
Bumps the workspace version to 0.3.0 for the new features since 0.2.1, and
applies cargo fmt to the two files from #149 that failed CI's format check.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 15:49:47 -04:00
Brandon ThomasandClaude Opus 5.5 c5b073f5f7 UI tests: the title-bar test needs no GPU unless it saves a snapshot
It asked for a wgpu device up front, which panics where there is none: the
FreeBSD VM job has failed on it since it landed. Like the other tests, let
the default renderer create a device only when a snapshot is rendered.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 05:06:52 -04:00
Brandon ThomasandClaude Opus 5.5 8d76d193db macOS: attach disk images one at a time, and retry when the helper is busy
diskimages-helper turns an attach away ('Resource temporarily unavailable')
while it is busy with another image. The DMG tests added in #51 run in
parallel and made this a flaky failure (about 1 run in 5 locally); the
launcher hits the same thing when several apps update at once. Attaches now
take a process-wide lock (which the tests' hdiutil create shares) and back
off and retry (1, 2, 4, 8 s) when something outside the launcher holds it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 05:05:38 -04:00
Brandon ThomasandClaude Opus 5.5 633f09c7cc Linux: report undetected-package fallback as a system binary (#99 follow-up)
When dpkg/rpm don't list the app, the launcher can't know which package
manager installed it, so label it a system binary (open it, leave update
and removal to whatever installed it) instead of Deb/Rpm with a guessed
package name. Require the binary itself; fix clippy and rustfmt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 02:11:39 -04:00
Brandon ThomasandClaude Opus 5.5 bd1182e75c Release 0.2.0
A minor release, not 0.1.4 (the previous commit's number, never built or
tagged): it adds features. Since 0.1.3, from community contributions: an
interface in Russian and Simplified Chinese (Chinese drawn with the
system's own font); several apps can install at once with one password
prompt on Linux; a verified download is kept for a retry when its install
step fails; the window closes to the tray on Wayland; HTTPS certificates
are verified by the OS; Direct3D 12 by default on Windows (fixes a startup
crash on hybrid AMD laptops); app names centred on their icons.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 14:21:43 -04:00
Brandon ThomasandClaude Opus 5.5 a0b301b8df Release 0.1.4
Since 0.1.3, from community contributions: an interface in Russian and
Simplified Chinese (Chinese drawn with the system's own font); several
apps can install at once with one password prompt on Linux; a verified
download is kept for a retry when its install step fails; the window
closes to the tray on Wayland; HTTPS certificates are verified by the OS;
Direct3D 12 by default on Windows (fixes a startup crash on hybrid AMD
laptops); app names centred on their icons.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 14:21:09 -04:00
Brandon ThomasandClaude Opus 5.5 3a1140e949 Release 0.1.3
Since 0.1.2: release information comes from ArtCraft's API, with GitHub
as the fallback; calls to the API are rate-limited and back off hard on
HTTP 429; the footer names the services in use; ArtCraft announcements
and alerts are shown.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 11:17:58 -04:00
Brandon ThomasandClaude Opus 5.5 9a961dc4de Restyle the release feed's notices and alerts for the new theme
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 11:17:22 -04:00
Brandon ThomasandClaude Opus 5.5 182530fbc8 Rate-limit calls to the ArtCraft API; back off hard on HTTP 429
Every launcher polls the same server, so a FeedThrottle now gates each request:
- at most one a minute once the first load is over;
- up to ten a minute during the first load, front-loaded, with the gaps doubling after each
  failure (the first load ends at the first answer or after ten requests);
- failures back off 2, 4, 8 … minutes (at most an hour), with jitter;
- HTTP 429 waits at least 15 minutes, doubling per 429 in a row up to six hours, never sooner
  than Retry-After, plus up to 50% jitter so a herd of clients doesn't return in step. The
  backoff is saved to cache/feed-throttle.json, so relaunching doesn't skip it.

A check that would have to wait more than ten seconds goes without the feed this time, and the
saved answer stands in.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 11:17:22 -04:00
Brandon ThomasandClaude Opus 5.5 b42d1f49ec Footer names the services in use; retry the ArtCraft API before GitHub
Footer: "Checked just now · using ArtCraft API", "· using GitHub" or
"· using ArtCraft API and GitHub", from where each release on screen came
from (Latest events now carry their origin), so it follows what's shown.

Retries and fallback:
- The very first poll (nothing ever loaded or saved) tries the ArtCraft
  API once, then GitHub at once, so the window fills
- Every other poll tries the API up to three times (1 s, then 3 s apart)
- Until every app has loaded once, a failing API lets GitHub be asked
  fairly freely (every 5 minutes per app)
- After that, GitHub is asked only for apps the API doesn't list or
  hasn't refreshed in a day, or once the API has seriously failed (three
  checks in a row and an hour without an answer); then hourly per app.
  Until then the API's last answer keeps being shown

Tests: the fallback policy for each stage, and the footer wording.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 11:17:22 -04:00
Brandon ThomasandClaude Opus 5.5 4a86071159 Use ArtCraft's release feed; GitHub only as the fallback
The launcher now asks storyteller-web
(GET https://api.storyteller.ai/v1/craft_apps/release_info), which polls
GitHub for every Craft App on a schedule, instead of polling GitHub itself.

- At launch and every five minutes: one request (10 s timeout) for every
  app's latest release, plus renames and notices
- Per app, GitHub is asked only when the feed can't vouch for it: the app
  isn't listed, its entry is more than 24 hours old, or the feed didn't
  answer. Even then, at most once an hour per app (Refresh asks at once).
  With pre-releases on, GitHub decides (the feed serves stable releases)
- Read leniently (crates/core/src/feed.rs): every field optional, unknown
  fields ignored, wrong types read as missing, one bad entry never spoils
  the rest. Download links must still point at the app's own GitHub
  releases; a moved repo counts only when the feed's repo_renames says so
- The last good answer is saved for an instant first paint and stands in
  (while still fresh) when the feed can't be reached
- Announcements show inline until dismissed; alerts pop up until the user
  presses OK (with "Open link" for web links); app renames show as
  announcements; dismissals persist
- "Check for updates": Automatically (every five minutes) or Only when I
  ask; older saved choices load as Automatically
- ARTCRAFT_LAUNCHER_FEED_URL points at a staging server or a local copy

Tests: the feed parser against hostile input, renames and notices; a
contract test against a response produced by storyteller-web's own code;
the feed-first rule with a counting fake GitHub; the notices UI.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 11:17:22 -04:00
Brandon ThomasandClaude Opus 5.5 6802bc6b89 Add LinkedIn to the social links
- LinkedIn icon linking to https://www.linkedin.com/company/artcraft-ai,
  in the footer and Settings › Community
- Social icons now read X, Instagram, LinkedIn, YouTube, TikTok
- The icon is from Font Awesome Free 6.7.2 (CC BY 4.0), since Simple
  Icons no longer carries LinkedIn's logo; white fill and a square view
  box, artwork unchanged. Credited in assets/social/README.md,
  ATTRIBUTION.md and NOTICE

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 03:09:54 -04:00
Brandon ThomasandClaude Opus 5.5 8766e29547 macOS: show the window on the current desktop
Opening the launcher from the menu bar used to switch to the desktop
(Space) its window was last on, which is jarring when you're working on
another one. A new setting, "Show the window on the current desktop"
(on by default), sets AppKit's "move to active space" behavior on the
window whenever it's shown, so it comes to the desktop you're on instead.
Turning it off restores macOS's default of switching to the window.

macOS only: the code and its dependencies compile only for macOS, and
the setting appears only where the host has desktops. objc2,
objc2-foundation and objc2-app-kit are already in Cargo.lock through
winit and tray-icon; they're pinned to those versions, and only safe
AppKit calls are used.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 03:03:12 -04:00
Brandon ThomasandClaude Opus 5.5 e8c4b3d355 Release 0.1.1
Self-update fixes since 0.1.0 (f4f1d77): the restart helper no longer
passes a pretend version on, a just-installed release isn't offered
again, and macOS DMG installs pass strict signature checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 01:05:11 -04:00
Brandon ThomasandClaude Opus 5.5 f4f1d7767e Self-update: stop restart loops and unsigned-looking macOS copies
Fixes found trying "Update and restart" on a real install:

- The restart helper no longer passes ARTCRAFT_LAUNCHER_PRETEND_VERSION
  on to the new launcher. It inherited the old launcher's environment,
  so the restarted copy still believed it was old and offered the same
  update again, forever. A pretend version now lasts one run.
- Loop guard: before restarting, the launcher records the release it
  updated to (self-update.txt in its data folder) and, for a day, won't
  offer that release again. Protects against a release whose binary
  reports a different version from its tag.
- macOS installs from a DMG (the launcher's own update and every Craft
  App) copy with `ditto --norsrc --noextattr --noacl`. The disk image
  adds Finder metadata to its files; copying it made
  `codesign --verify --strict` reject the bundle as carrying detritus,
  although Gatekeeper still accepted it. Signatures live in the bundle's
  files, not in extended attributes.

Tests: the helper command removes the pretend variable; a just-installed
release isn't offered again until the guard lapses.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 01:01:17 -04:00
Brandon ThomasandClaude Opus 5.5 b642df291d ArtCraft Launcher updates itself and restarts
When a newer launcher is released, the banner offers "Update and
restart": the new build is downloaded and verified like any Craft App,
put in place the way this copy was installed, and started by a small
helper once this process has exited (it holds the single-instance lock,
and Windows locks a running exe).

- macOS .app: new bundle copied from the DMG over this one, reopened
- Windows MSI (per-user): helper runs the new MSI after exit
- Windows portable: helper unzips over the folder after exit; settings stay
- Linux AppImage: new AppImage renamed over this one
- Linux .deb / .rpm: system package manager, then restart
- Flatpak, FreeBSD and dev builds keep the download link

ARTCRAFT_LAUNCHER_PRETEND_VERSION makes an installed copy act old, to try
the update against the current release. Tested: the helper waits for the
old process to exit; a real DMG replaces a bundle in place.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 23:49:38 -04:00
Brandon ThomasandClaude Opus 5.5 8143a26014 Detect AUR installs, read distro versions, rescan installs
Ideas from the ArtCraft Suite Updater:

- Arch / AUR: detect each app through pacman under all three AUR names
  (<app>, <app>-bin, <app>-git; PdfCraft also as printcraft*). Updates
  and removals of AUR installs show the paru / yay / pacman command
  instead of installing a second copy
- Read package-manager versions the package-manager way: drop the
  revision (0.5.0-1), epoch (1:) and VCS suffix (0.3.0.r47.g…), and map
  Debian's ~. Fixes .deb installs of the latest release showing an
  update forever
- Flatpak installs that list no version are read with `flatpak info`
- Look again at what's installed every 5 minutes, and when the window
  regains focus (at most every 30 s), so apps installed or removed
  outside the launcher show up; one detection pass at a time
- Package-list parsing lives in crates/native/src/packages.rs, tested on
  every platform

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 23:16:14 -04:00
Brandon Thomas 52be9b1452 better description 2026-10-09 22:59:16 -04:00
Brandon Thomas 0b590ad2c5 Awesome launcher! 2026-10-09 22:58:01 -04:00
Brandon ThomasandClaude Opus 5.5 ad97df25d1 README: show the table screenshot at the same size as the grid one
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 22:48:59 -04:00
Brandon ThomasandClaude Opus 5.5 d175e19b54 README grid + table screenshots; no macOS in CI
- README: the grid view (dark theme) is the main screenshot, with a
  smaller table view (light theme) below it
- CI tests on Linux and Windows only: per craftrules, the org's macOS
  runners are kept for release builds, and release.yml builds and checks
  macOS

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 22:48:21 -04:00
Brandon ThomasandClaude Opus 5.5 24b78f279f README: add a screenshot of the launcher
- docs/screenshots/artcraft-launcher.png: the table view on macOS with
  live release data, shown below the README's navigation links
- Credit the screenshot in ATTRIBUTION.md
- Trim the closing line of the Thanks section

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 22:40:45 -04:00
Brandon ThomasandClaude Opus 5.5 7ddda925c1 App icon is the ArtCraft "A"; thank the community launchers
- The app icon (Dock, taskbar, Start menu, Linux menus, installers) is
  now the black ArtCraft "A" mark, rendered unmodified from
  docs/brand/artcraft-mark-black.svg by packaging/icons.sh; the old
  tile icon is gone
- The app icon is an ArtCraft trademark, not MIT/Apache: say so in
  assets/app-icon/, ATTRIBUTION, NOTICE, README and AGENTS.md
- Settings shows the blue mark in dark theme so it stays visible
- README: a Thanks section crediting the eleven community launchers
  whose ideas shaped this one

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 22:38:23 -04:00
Brandon ThomasandClaude Opus 5.5 4aa07a56f8 Social links: X, YouTube, TikTok and Instagram icons
- Small monochrome service icons (Simple Icons 16.34.0, CC0) linking to
  ArtCraft's accounts, after Website · GitHub · Discord in the footer and
  in Settings › Community; quieter than Discord, brighter on hover
- Settings: the community description gets its own line, so the
  Website and GitHub buttons no longer overlap it
- Credit the icons in assets/social/README.md, ATTRIBUTION.md and NOTICE

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 22:23:59 -04:00
Brandon ThomasandClaude Opus 5.5 d4f5a33ea4 Brand header, sortable table, links to ArtCraft and each app
- Header: the ArtCraft wordmark (white on dark, ink on light), "Launcher ·
  Craft App Suite" and the tagline "Open Source Tools for Creatives,
  Makers, and Builders"
- Tray / menu-bar icon is now the ArtCraft "A" mark, rendered unmodified
  from docs/brand; the old self-drawn tray icons are gone
- Repo docs (NOTICE, ATTRIBUTION, README, asset licenses, AGENTS.md)
  call out that the ArtCraft name, logo and mark are not MIT/Apache
- Table: "Inspired by" column; every column sorts both ways, empty cells
  last; the grid's sort menu has the same options
- Adobe / Microsoft / Autodesk / Avid trademark notice under both views;
  inspirations shown with ®
- Links: Discord button in the header; Website · GitHub · Discord in the
  footer, tray menu and Settings; each card links to its app's website
  (classic apps) and GitHub repo, and the … menu has both
- Fix links never opening: enable eframe's "links" feature
- Clear stale partial downloads at startup

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 22:17:41 -04:00
Brandon ThomasandClaude Opus 5.5 83bdf67d50 Packaging lint: match the LSUIElement key, not the comment explaining it
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 21:46:31 -04:00
Brandon ThomasandClaude Opus 5.5 4dc0602a19 Robust downloads: pause, resume, reconnect; fix every download failing
Every download failed at its last read: ureq's body limit errors once
the limit is reached, and it was set to the exact file size. Sizes and
checksums are now checked by the launcher, with headroom on the limit.

- Pause keeps the partial file; Resume continues from the same byte
  (HTTP range requests). Cancel discards it.
- Dropped or stalled connections retry with backoff from where they
  stopped, shown as "Reconnecting…"; if the connection stays down the
  download pauses itself instead of failing
- Partial downloads survive quitting and show as paused next launch
- Ask for identity encoding so bytes arrive exactly as published
- SHA-256 from GitHub's digest or SHA256SUMS.txt; a mismatch refetches
  once from scratch. Releases with no checksum install with a size
  check and say so; a checksum list that can't be fetched is an error
- Tests against a scripted local server for each failure mode

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 21:46:15 -04:00
Brandon ThomasandClaude Opus 5.5 ec69f0be2c ArtCraft Launcher: install and update the Craft App Suite
A native Rust/egui launcher for the 12 Craft Apps (7 classic + 5 new).

- Grid (icon cards) or sortable table view, filters and search
- Status per app: available, installed and up to date, or update
  available with version and release date
- Installs where each OS keeps apps, from the official release packages:
  /Applications (DMG), Program Files (MSI), deb/rpm via the system
  package manager (Flatpak/AppImage fallback), /usr/local on FreeBSD
- Detects apps installed by hand; updates keep the installed format
- Every download verified against its published SHA-256; running apps
  are never replaced
- Tray/menu-bar mode, start at login, one notification per new version
- GitHub API with ETag cache, falling back to release pages when
  rate-limited; release source is pluggable for a future catalog API
- Web build lists latest releases with per-platform downloads
- Packaging and release workflows for macOS, Windows (x64/x86/arm64),
  Linux (x86_64/aarch64), FreeBSD and web

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 21:08:24 -04:00
Brandon Thomas a147fa2039 initial version 2026-10-09 19:25:58 -04:00