Elyra
Elyra The coding agent eTerm The terminal that knows where each command ends Huskarl AI colleagues on your own Mac Starf An activity monitor for Apple silicon that never invents a number etrans An SSH and SFTP client for macOS Elyra VM Virtual machines for macOS, Linux and Windows on your Mac Litr A small, native web browser for macOS Notr A notebook for macOS e The native code editor Elyra Grove Native local development environment Askr The real server for Laravel & PHP Elyra Framework Rust + Svelte 5 framework for desktop apps Elyra Conductor Local project conductor Refr Local-first PDF workspace for macOS Elyra Workspace A desktop workspace for coding agents Elyra SQL Server MySQL-compatible SQL server in Rust Elyra Félagi Agents as teammates on one board Elyra SQL Client Native desktop SQL workbench Elyra SQL Anywhere Replication-ready SQL engine Elyra Sjá SEO & GEO workspace for macOS Elyra DataGrid Server-driven data grid for Laravel
Release notes
Changelog
Elyra
Industry packs

Industry packs

An industry pack is what one trade needs to start with Huskarl, in one file: an accounting office, an electrician, a law firm. It holds a few bots (as recipes), what is confidential in that trade, and text the bots can read: knowledge (deadlines, checklists, procedures) and templates (letters and forms to fill in).

A pack holds no code, memories, logins or keys. Its bots can do nothing Huskarl does not already let a bot do, and everything that leaves still waits for you.

The packs Wirelabs makes

The sources are in packs/ in the repository; each is built and signed with scripts/pack.py. They are pilots: the knowledge was last checked in October 2026 and says where to check it, and each bot is told to say when it is not sure of a date or a number.

Pack Bots Knowledge Templates
Regnskapskontor (no.wirelabs.regnskapskontor) Fristvakt lists every client's deadlines for the next fortnight, Mondays at 08:00. Bilagsmottak checks each voucher dropped in ~/Huskarl/Bilag against what a voucher must hold and enters it in the client's monthly sheet. Kundepurring drafts reminders to clients who have not sent their vouchers, Thursdays at 09:00 MVA, A-melding, forskuddstrekk, forskuddsskatt, skattemelding, årsregnskap; what a voucher must hold; reminders and collection; taking on a client deadline reminder, missing vouchers, payment reminder, engagement letter
Elektriker (no.wirelabs.elektriker) Henvendelser answers and sorts customer mail as it comes, urgent ones (burning smell, sparks, water) first. Tilbud writes the quote from the notes after a site visit. Dokumentasjon says what is missing after a job and fills in the declaration of conformity and the FDV documentation FEL, NEK 400 and what the owner gets; quotes, estimates and the 15 % rule for consumers; urgent enquiries; the checklist before a job is closed quote, samsvarserklæring, FDV, reply to an enquiry

Confidential in them: salaries, tax returns and personal numbers for the accounting office; personal numbers, keys and alarm codes for the electrician.

Installing

On the new-bot page, Import a recipe… takes a *.huskarlpack file as well as a recipe. The preview shows:

  • who published it, and whether that is verified: signed with a key Huskarl knows (Wirelabs AS, and partners as they come). A pack signed by anyone else, or changed after it was signed, shows as not signed by a publisher Huskarl knows; it can still be installed if you trust where it came from
  • each bot it makes, and what that bot asks beyond the defaults
  • how many knowledge files and templates it brings, and what it marks as confidential.

Install the pack makes its bots, in rehearsal unless you untick it. Each bot's thread says where it came from. What is confidential in the pack is added to each of its bots' own list.

From the terminal:

huskarld pack preview regnskap.huskarlpack
huskarld pack install regnskap.huskarlpack          # --no-rehearsal to start them for real
huskarld pack                                        # what is installed
huskarld pack remove no.wirelabs.regnskapskontor

Installing the same pack again (a newer version) replaces its files and makes a bot for any recipe it has not made one from yet. The bots it already made keep their own instructions, which you may have changed.

Removing a pack removes its files. Its bots stay, without them.

Seeing and removing

Settings (⌘,) → Industry packs lists the packs on this Mac: name and version, the publisher and whether that is verified (one that is not says so in the warning colour), the bots it made that are still here, and how many knowledge files and templates it has. Remove asks once more, saying what goes and what stays, and removes it on the second press.

Updates

Deadlines, VAT rates and NEK 400 change every year, so a pack's knowledge goes out of date. Newer versions come the way the app's own updates do:

  1. The daemon looks in https://elyracode.com/huskarl/packs.json a minute after it starts and every six hours, for each installed pack that a publisher Huskarl knows verifiably signed. Only the address is asked for; nothing about the Mac or its bots is sent.
  2. A newer version is downloaded and kept beside the pack only if its SHA-256 is the one packs.json gives, it is the same pack, and the same verified publisher signed it. Anything else is left where it is and logged. A pack nobody verifiably published is never updated this way.
  3. The sidebar says Update Regnskapskontor to 1.1.0, and Settings → Industry packs shows what it changes: the publisher's own words for it, and file by file the lines that go (−) and come (+), for example − A-melding: 5. hver måned. and + A-melding: 7. hver måned., with new and removed files and any new bots.
  4. Update to 1.1.0 installs it. Nothing is installed before you say so.

Each bot made from the pack is then told in its thread: The pack «Regnskapskontor» was updated from 1.0.0 to 1.1.0: Fristen for A-melding er flyttet til den 7. Its agent starts again with the new files. Its own instructions are left alone, and a recipe new in the update becomes a new bot in rehearsal.

Check for updates in the settings looks at once; so does huskarld pack check, and huskarld pack update <id> installs the one waiting. Installing a newer version by hand, with Import a recipe…, tells the bots in the same way.

What the bots get

A bot made from a pack has three more tools, all Read:

Tool What
pack_files the pack's knowledge and templates, by path
pack_read one file, by its path
pack_search the lines in the pack's files that have the words

What they read is outside text: reference for the bot, never instructions. The pack's recipes say how to use it ("check the deadlines in knowledge/frister.md every Monday"). A filled-in template is saved with documents_save, as Word, Markdown or text.

The files are in ~/.huskarl/packs/<id>/files; only the pack's own bots read them, and nothing outside them.

Making a pack

A pack is built from a folder:

pack.json          {"id": "no.wirelabs.regnskapskontor", "name": "Regnskapskontor",
                    "version": "1.0.0", "publisher": "Wirelabs AS",
                    "description": "Bilag, frister og purringer", "industry": "accounting",
                    "confidential": ["Lønnsslipp"],
                    "changes": ["Fristen for A-melding er flyttet til den 7."]}
recipes/*.huskarl.json
knowledge/**       .md, .txt, .csv or .json
templates/**
scripts/pack.py build packs/regnskapskontor -o regnskap.huskarlpack --sign

--sign signs it with Wirelabs' key, read from the login Keychain (no.huskarl.pack-signing-key, account ed25519-private); a partner signs with theirs, given in HUSKARL_PACK_SIGNING_KEY (hex). The key is only used in that process.

changes is what this version changes, in your words, for the people who use it: the preview and the bots' threads show it. Leave it out of the first version, and write it anew for each one after; raise version for every change, as an installed Huskarl only takes a higher one. A release of Huskarl builds and signs packs/*, and deploy_huskarl in elyra-web publishes them, which is what puts them in packs.json.

The file

*.huskarlpack is JSON:

{"huskarl_pack": 1,
 "payload": "<the content as a JSON string>",
 "signature": {"publisher": "Wirelabs AS", "key": "<hex>", "sig": "<base64>"}}

The content is id, name, version, publisher, description, industry, recipes (recipe objects), confidential, files (path → text) and changes. The signature is Ed25519 over the payload's exact bytes. The keys Huskarl trusts are in crates/huskarl-ipc/src/pack.rs (TRUSTED); adding a partner is adding their public key there, in a release.

A pack is refused if its id is not like no.publisher.pack, it has no bots, a recipe cannot be read, a file is outside knowledge/ or templates/, or its files are more than 4 MB together.