feat: install and update msd from git release tags, not npm

MSD is not published to npm, so /msd-update and the SessionStart update
check could never find a release. Releases are now vX.Y.Z git tags plus a
stable branch:

- check-latest-version reads release tags via git ls-remote against the
  baked repository URL (latest = highest stable tag, next = incl. -rc)
- /msd-update reruns the bootstrap installer pinned to the checked tag and
  reads the changelog from that tag
- bootstrap.sh defaults to the stable branch and supports --local/--global
- package identity: changelog URL on stable, manual install via
  msd.golem15.com
- README quickstart and update how-to describe the one-line installer
- track the repo-root CLAUDE.md

Emitted-Drift-Ack-Growth: update.md — the update flow now explains the git-tag release lookup and pins the bootstrap installer to the checked tag, replacing the npm/npx wording
This commit is contained in:
Jakub Zych
2026-10-09 02:47:50 +02:00
parent bb581803ad
commit 6524974d93
18 changed files with 349 additions and 202 deletions

View File

@@ -31,13 +31,14 @@ function parseRepoSlug(repository) {
}
/**
* Raw-file URL for CHANGELOG.md on the repo's default branch. GitHub serves raw
* files from a separate host; the golem15 Gitea forge serves them in-place.
* Raw-file URL for CHANGELOG.md on the release branch. GitHub serves raw files
* from a separate host; the golem15 Gitea forge serves them in-place from the
* `stable` branch, which always points at the latest tagged release.
*/
function changelogRawUrlFor(host, slug) {
if (!slug) return '';
if (host === 'github.com') return `https://raw.githubusercontent.com/${slug}/main/CHANGELOG.md`;
return `https://${host}/${slug}/raw/branch/next/CHANGELOG.md`;
return `https://${host}/${slug}/raw/branch/stable/CHANGELOG.md`;
}
/**
@@ -70,16 +71,18 @@ function deriveIdentity(pkg = {}) {
}
/**
* Pure: format the `npx` fallback install command. Shape matches the literal
* the update workflow embeds: `npx -y --package=<pkg>@latest -- <bin>
* Pure: format the manual install command. MSD is not published to npm; it is
* installed by the bootstrap script served at msd.golem15.com
* (scripts/bootstrap.sh on the `stable` branch). Shape matches the literal the
* update workflow embeds: `curl -fsSL https://msd.golem15.com | bash -s --
* [--<runtime>] --<scope>`. The runtime flag is omitted when not supplied.
*
* This function is the canonical source — `render()` serializes it verbatim
* into the generated module, so the runtime copy can never drift from it.
*/
function formatManualInstall({ packageName, binName, scope, runtime } = {}) {
function formatManualInstall({ scope, runtime } = {}) {
const runtimeFlag = runtime ? ` --${runtime}` : '';
return `npx -y --package=${packageName}@latest -- ${binName}${runtimeFlag} --${scope}`;
return `curl -fsSL https://msd.golem15.com | bash -s --${runtimeFlag} --${scope}`;
}
const GENERATED_HEADER =
@@ -107,7 +110,7 @@ function render(identity) {
`const updateCacheFileName = ${j(updateCacheFileName)};\n\n` +
`${formatManualInstall.toString()}\n\n` +
'function manualInstallCommand(opts = {}) {\n' +
' return formatManualInstall({ packageName, binName, scope: opts.scope, runtime: opts.runtime });\n' +
' return formatManualInstall({ scope: opts.scope, runtime: opts.runtime });\n' +
'}\n\n' +
'module.exports = Object.freeze({\n' +
' packageName,\n' +