Bastion 1.14.0
Version 1.14.0 ·
Added
A profile's tools, prompts and resources, in one place. Every profile row has a
Tools…button besideTest, and it opens the listing the app could not previously show: all three surfaces, read from the running server through that profile's own write gate, with a count on each tab, a filter, a per-tool token cost and the input schema behind a disclosure. Nothing in Bastion had ever asked a server forprompts/listorresources/list. The check sheet reads one page of tools and reports the five heaviest, on purpose; the Chat pane's picker is a budget control that drops everything the write gate touches. Neither answers "what is in here", and a static table inservers.jsoncannot: a Bastion listing is per profile and per client, which is the same reasonDialect.listCacheScopeisprivate.It says which of the possible listings it is showing, because a number here can honestly disagree with one elsewhere in the app. Whether the gate was on or off; which tools Bastion removed, named and struck through, for a remote server whose catalog entry marks them as writes — a child server switches its own off at startup and cannot be asked what they were; and whether loading on demand means a client is sent three declarations in place of this list. Walking every page also hands
ToolCostStorea better measurement than the check's, which stops at page one.Bastion --capabilities=<profile>/<server>prints the same three lists from a Debug build.What changed, readable after you have already updated. Release notes existed in exactly one place a user could reach: the sheet Sparkle puts up while it asks permission to install. That sheet is gone the moment you press Install, which left the one person most likely to want them — somebody who has just updated — with nowhere to look but
CHANGELOG.mdon GitHub. Settings has a What's New pane now, between About and Updates, because the three answer three parts of one question in that order: which build is this, what did it change, is there a newer one.It is generated, not bundled.
make changelogcompiles the last five releases ofCHANGELOG.mdintoChangelog.swiftthe same waymake serverscompilesservers.jsonintoServerCatalog.swift, andchangelog-checkfails CI if the two drift — so the notes in the app are the notes in the repository, or the build goes red.### Internalsections are dropped at generation time rather than hidden at render time, so repo-facing prose about CI never reaches the binary at all.[Unreleased]is emitted separately and shown only in a Debug build, where it is true of what is running.The parse behind it is now shared with
changelog-notes.mjs, which renders the appcast Sparkle reads, so the two cannot disagree about what a bullet is. Extracting it turned up a latent bug in the renderer's own placeholder scheme, and the tests inscripts/lib/changelog.test.mjsare written against the awkward shapes this file actually contains rather than tidy examples: a bullet with no bold headline, a headline with a code span inside it, and prose sitting between a###heading and its first bullet.Anything that shipped since the version you last read is marked, and says so from the menu bar panel and the main window's footer as well as in Settings — once, until you look. A fresh install is treated as caught up rather than greeted with five unread releases.
Fixed
A server that shells out to
npmcould not find it. Children are spawned with a deliberately minimalPATH, which was/usr/bin:/bin— somcp-npm's publish tool, whosenpm packruns the package's own prepare script, died several layers down withsh: npm: command not found. NeitherResourcesnorResources/npm/binfixes it: the first holds annpmthat is a directory, and the shims in the second locate npm relative to node's prefix (<prefix>/bin/nodeplus<prefix>/lib/node_modules/npm), which the flat bundle layout is not, so they fail with "Could not determine Node.js install directory".make nodenow stages aResources/binof symlinks to the-cli.jsentrypoints, which skips prefix detection entirely, and every child gets that directory in front of/usr/bin:/bin. What is added is exactly node, npm and npx from this bundle — never the developer's shell PATH, and nothing a profile can point elsewhere.scripts/verify-servers.shnow asserts it before signing, withenv -iso an inherited PATH cannot pass the check on the developer's own npm. Every existing step ran the two binaries by absolute path, which is how a bundle that no child could shell out from passed all of them.
Changed
The npm catalog entry documents the variables it always read.
NPM_BIN,NPM_TOTP_LABEL,NPM_TOTP_SECRETandNPM_TOTP_KEYCHAIN_SERVICEare now in the profile editor, andNPM_OTP_MODEliststotp— the only mode that answers npm's second factor without a human, and therefore the only one an unattended publish or trusted-publisher batch can use. It was missing from the description, which made the mode undiscoverable from Bastion.