Repository navigation
Releases: luanAfons0/FirstMate
Release list
FirstMate 2.0.0-beta.3
What's Changed
- Word the Stopped Notice, name the App's folder FirstMate, and keep each PR's installer by @luanAfons0 in #155
- Make the command line short to read and pleasant to use by @luanAfons0 in #165
- Raise the version to 2.0.0-beta.3, for the third beta by @luanAfons0 in #166
Full Changelog: v2.0.0-beta.2...v2.0.0-beta.3
FirstMate 2.0.0-beta.2
What's Changed
- Install the App when Windows still holds the installer, and soften the Smart App Control note by @luanAfons0 in #152
- Show start at logon as it is, and the App's mark on its taskbar button by @luanAfons0 in #153
- Raise the version to 2.0.0-beta.2, for the second beta by @luanAfons0 in #154
Full Changelog: v2.0.0-beta.1...v2.0.0-beta.2
FirstMate 2.0.0-beta.1
What's Changed
- Give the command line help, status, exit codes, reload and restart by @luanAfons0 in #149
- Raise the version to 1.4.0, for the check to publish by @luanAfons0 in #150
- Start Plugin Servers on native Windows by @luanAfons0 in #151
Full Changelog: v1.3.0...v2.0.0-beta.1
v1.3.0
You now choose the order of your Plugins, and the window can switch Plugin and show its own settings. Under the hood, the repository is a pnpm workspace, and the package is one bundle.
New
- The Plugin Order.
firstmate ordersays every Plugin with its position, andfirstmate order <name> <position>moves one. The Index Page,/plugins.json, the window's switcher and the Tray menu all follow it. A new order shows within a few seconds, with no restart. - The switcher. In the window, the last part of the breadcrumb (FirstMate › worklog) opens a list of every Plugin over the page, in the Plugin Order and with its state. Click one, or use the arrow keys and Enter. Esc closes it.
- The Settings View. The gear at the right of the strip opens it in place of the page, and the page is still there when you close it. Drag a Plugin, or use its arrows, to move it in the Plugin Order. It also turns start at logon on and off, restarts the Host, and shows the Shelf, the Shortcuts and the Grants with the command that changes each. Moving a Plugin needs the service (
firstmate service on).
Changed
- The package is one bundle built with
tsdown, in 5 files instead of one file per source file. Nothing you type changes. - The repository is a pnpm workspace:
packages/core,packages/hostandapps/cli, which is the npm package (ADR-0017). From a clone, the commands are nownode apps/cli/src/cli.ts …andnode packages/host/src/main.ts, andpnpm checkruns every check.
Update
npm install -g @luan-afonso/firstmate
systemctl --user restart firstmateIf you run FirstMate from a clone with the service, run node apps/cli/src/cli.ts service on again after you pull. The old unit names src/main.ts, which is gone.
Still not done
- The Tray and the window are Windows only. Native Linux and macOS have no Tray.
- Native Windows cannot run a Plugin Server. WSL Debian is the one proved platform. The native Windows App is the work toward 2.0.
v1.1.0
FirstMate now sets itself up from one command, and has a window of its own on Windows.
New
firstmate setupasks a few questions and does what you answer: the Shelf, the Official Plugins, their Grants, the Shortcuts, and the service.firstmate install <dir|git URL|official-name>fetches a Plugin into the Shelf and registers it.firstmate shelf [dir]says where the Shelf is, or moves it.- Official Plugins:
worklog,schedulerandnexusinstall by name. firstmate desktopopens the FirstMate window on Windows, with an icon in the notification area, the Plugin list, start at logon, restart and quit.- Shortcuts:
firstmate bind <keys> <plugin> [path]andunbind. The Tray holds them in all of Windows and opens the address in a Popup. - Notices: a Plugin Server can send one, and the Host sends one when a Plugin goes Stopped. The Tray shows them as Windows pop-ups; a click opens the address.
firstmate service on|offinstalls or removes the systemd user service, and prints the command for the Windows logon task.- A Tool Bus call can carry
timeoutMs, up toFIRSTMATE_MAX_CALL_MS. - New variables:
FIRSTMATE_MAX_CALL_MS,FIRSTMATE_NOTICE_MS,FIRSTMATE_SHELF. - New addresses:
/shortcuts.jsonand/notices.json.
Removed
- The PowerShell Tray and its scripts (
windows/install-tray.ps1,uninstall-tray.ps1,firstmate-tray.ps1,firstmate-runtime.ps1,firstmate-open.ps1).firstmate desktopreplaces them. scripts/install-service.sh,scripts/uninstall-service.shandsystemd/firstmate.service.firstmate service on|offreplaces them.
Update
npm install -g @luan-afonso/firstmateIf you ran the old PowerShell Tray, remove it first with the uninstall-tray.ps1 from 1.0.1.
Still not done
- The Tray and the window are Windows only. Native Linux and macOS have no Tray.
- Native Windows cannot run a Plugin Server. WSL Debian is the one proved platform.
v1.0.1
Published by the check, not by hand.
No source file changed since v1.0.0. What changed is how this version was built, and what it can now prove about itself.
npx @luan-afonso/firstmate startProvenance
v1.0.1 carries a SLSA v1 provenance attestation. It says which repository, which tag and which workflow produced the tarball:
repository : https://github.com/luanAfons0/FirstMate
ref : refs/tags/v1.0.1
workflow : .github/workflows/release.yml
subject : pkg:npm/@luan-afonso/firstmate@1.0.1
Check it yourself:
npm install @luan-afonso/firstmate
npm audit signaturesv1.0.0 was published from a laptop and carries none, which is the whole reason this version exists.
No secret to keep
npm accepts GitHub Actions as a trusted publisher over OpenID Connect, so the release job asks for an identity token minted for that one run and expiring in minutes. There is no NPM_TOKEN in this repository, and none to leak or rotate.
The job refuses a tag that disagrees with package.json, checks the types and runs the whole suite before it publishes, so a broken release cannot leave the machine.
How a release is cut is written down in CONTRIBUTING.md, so it is not one person's knowledge.
Node 24 or newer. MIT. The command is still firstmate.
v1.0.0
FirstMate is a local plugin host. It runs a person's own tools on their own machine and gives each one a process, a page and an address, so that no tool has to build a runtime of its own.
npx @luan-afonso/firstmate startWhat a Plugin is
A directory, named in the Registry. There is no manifest and no schema.
- Put a
web/directory in it and the Host serves it at/p/<name>/, byte for byte. - Put an executable named
mcpin it and the Host runs it and speaks MCP to it over stdin and stdout. The shebang decides the language, so a Plugin Server can be written in anything. - A directory with neither is still a Plugin. It just has nothing to show.
Adding a Plugin neither copies nor symlinks its directory. The Registry holds the path, so a Plugin stays in its own repository wherever it already lives.
What the Host does
Four things, and nothing else: it supervises processes, it serves HTTP on loopback, it serves a Plugin's static files, and it is a JSON-RPC client.
- Starts every Plugin Server at boot, and holds the truth about each. A Plugin is
Running,Stopped, or has no Plugin Server, and the Index Page says which. - Serves the Index Page, every Plugin Page, and
POST /p/<name>/rpc, which carries a Plugin Page's tool call to its own Plugin Server. - Carries a call from one Plugin Server to another over the stdio pipe it already owns, and only where the Registry records a Grant for that pair, in that direction. The calling Plugin Name comes from the pipe, so it cannot be forged.
- Mints a token at every start and refuses every request that does not carry it. It checks
HostandOriginon each one, and binds127.0.0.1and no other address.
What v1 does not do
The absences are deliberate. Each one is written down.
- No scheduler. The Host runs nothing on a timer. Use
cron, or systemd, or the Plugin's own loop (ADR-0004). - No sandbox. A Plugin is a directory its owner registered, run with the owner's own privileges. The Host supervises processes; it does not contain them. Registering a hostile Plugin is the same act as running a hostile program.
- No data of yours. The Host keeps no run history, no logs and no settings for a Plugin. A Plugin owns its own data (ADR-0005).
- No reach between Plugin Pages. A Plugin Page reaches its own Plugin and no other. The Tool Bus is on the pipe, and a browser holds no end of it (ADR-0009).
- No restart of a Stopped Plugin. A broken Plugin stays visible rather than spinning in a restart loop. It still serves its Plugin Page.
- No framework, no bundler, no build step in a clone. Node 24 runs the TypeScript directly. Only the published package is compiled (ADR-0010).
- No runtime dependencies. The Host speaks MCP over about 140 lines of its own JSON-RPC.
Where it runs
Evidence, not a promise. WSL Debian is proved throughout. macOS and native Linux should work and are untried. Native Windows will not run a Plugin Server: the Supervisor tests the executable bit and runs the mcp file directly, and Windows reads no shebang. Plugin Pages are unaffected.
The README's platform table is where this is kept honest. If you run FirstMate somewhere untried, #46 is the smallest way to help.
Getting started
- README — install it, add a Plugin, run the Host.
docs/plugin-guide.md— the whole Plugin contract: what the Host enforces, and what it only advises.CONTEXT.md— every word this project uses.docs/adr/— the decisions that are expensive to reverse.
On the name
The package is @luan-afonso/firstmate. npm refuses the plain firstmate, and an org named firstmate, as too similar to first-mate — an unrelated TextMate package. The command is still firstmate:
npm install -g @luan-afonso/firstmate
firstmate add notes ~/plugins/notes
firstmate startNode 24 or newer. MIT.