Skip to content

fix(install): install lash, not opencode - #48

Merged
lacymorrow merged 1 commit into
lashfrom
fix/lash-installer
Sep 17, 2026
Merged

lacymorrow merged 1 commit into
lashfrom
fix/lash-installer

Conversation

@lacymorrow

Copy link
Copy Markdown
Owner

curl -fsSL https://lash.lacy.sh/install | bash currently installs opencode. The site's /install route proxies this file straight from the repo, so the wrong product is one command away from any visitor.

What was wrong

The script is upstream's, unmodified:

APP=opencode
INSTALL_DIR=$HOME/.opencode/bin
url="https://github.com/anomalyco/opencode/releases/latest/download/$filename"
mv "$tmp_dir/opencode" "$INSTALL_DIR"

/install/beta and /install/nightly export LASH_CHANNEL and then run this same script, so the channel routes were wrong too.

What this changes

Only the identifiers. The logic is good and stays: rosetta detection, musl detection, AVX2 baseline selection, and the shell-config PATH handling all match our release matrix exactly.

before after
app APP=opencode APP=lash
asset prefix (none) ASSET=lashcode
install dir $HOME/.opencode/bin ${LASH_INSTALL_DIR:-$HOME/.lash/bin}
repo anomalyco/opencode lacymorrow/lash
binary mv "$tmp_dir/opencode" mv "$tmp_dir/$APP"
version probe command -v opencode command -v lash

APP and ASSET are genuinely two values. Release archives publish as lashcode-<target>, the binary inside them is lash. Collapsing them into one name is exactly what makes the filename wrong, which is the bug on main (below).

Evidence

Ran end to end on darwin-arm64 with the existing brew-installed lash hidden from PATH, so the version short-circuit could not skip the download:

Installing lash version: 1.7.13
######################################## 100.0%

█    █▀▀█ █▀▀▀ █  █
█░░░ █▀▀█ ▀▀▀█ █▀▀█
▀▀▀▀ ▀  ▀ ▀▀▀▀ ▀  ▀

$ ls -la $LASH_INSTALL_DIR
-rwxr-xr-x  1  154890400  lash
$ $LASH_INSTALL_DIR/lash --version
1.7.13

Fetches lashcode-darwin-arm64.zip from the v1.7.13 release, extracts, installs, runs. shellcheck -S warning reports only the five style warnings that were already there upstream.

Also here

The README's installation section still told people to run curl -fsSL https://opencode.ai/install | bash and brew install anomalyco/tap/opencode. Rewritten to the real commands, both of which resolve today: brew install lacymorrow/tap/lash and npm i -g lashcode.

One thing to know

main carries a different install script that is lash-branded but broken in other ways: it builds filenames as lash-<target>.tar.gz (wrong prefix, and macOS ships .zip), hardcodes a default version of 0.6.12-fixed which does not exist, and does mkdir -p lashtmp && cd lashtmp in the user's current directory. This supersedes it. Worth deleting that one so it does not get promoted later.

The install script was upstream's, unmodified. Anyone running
`curl -fsSL https://lash.lacy.sh/install | bash` got the opencode binary from
github.com/anomalyco/opencode dropped in ~/.opencode/bin. The site proxies this
file, so the wrong product was one command away from any visitor.

The script itself is good: rosetta detection, musl detection, AVX2 baseline
selection, and PATH handling all match our release matrix exactly. Only the
identifiers were wrong, so this changes those and leaves the logic alone.

  APP=opencode                   -> APP=lash
  (none)                         -> ASSET=lashcode
  $HOME/.opencode/bin            -> ${LASH_INSTALL_DIR:-$HOME/.lash/bin}
  anomalyco/opencode             -> lacymorrow/lash
  mv "$tmp_dir/opencode"         -> mv "$tmp_dir/$APP"
  command -v opencode            -> command -v lash

APP and ASSET are genuinely two values: the release archives are published as
lashcode-<target>, the binary inside them is `lash`. Collapsing them into one
name is what makes the filename wrong.

Verified end to end on darwin-arm64 with the existing lash hidden from PATH:
fetches lashcode-darwin-arm64.zip from v1.7.13, extracts, installs, and the
result reports 1.7.13.

Also replaced the opencode ASCII art and closing text, and rewrote the README
installation section, which still told people to install opencode from
opencode.ai. Lash installs alongside opencode rather than over it: different
binary name, different install directory.

Note for whoever picks this up: main carries a different install script that is
lash-branded but broken in other ways. It builds filenames as lash-<target>.tar.gz
(wrong prefix, and macOS ships .zip), hardcodes a default version of 0.6.12-fixed
that does not exist, and creates its temp directory in the user's cwd. This
supersedes it.
lacymorrow added a commit to lacymorrow/lash-www that referenced this pull request Sep 17, 2026
The route fetched raw.githubusercontent.com/lacymorrow/lash/dev/install. `dev`
is upstream's branch name. `lash` is this repo's default and working branch, and
where lacymorrow/lash#48 fixes the script. The two files happen to be identical
right now, so this changes nothing today and everything once #48 merges.
@lacymorrow

Copy link
Copy Markdown
Owner Author

The two e2e failures here are pre-existing on the branch, not from this change.

They are Playwright tests of the desktop app UI: legacy-new-session.spec.ts and session-timeline-projection.spec.ts (comment strips and diff summary overflow). This PR touches install and README.md, a shell script and a markdown file. Neither is loaded by the app under test.

PR #46, the upstream sync, has the same two failures and touches none of the same files.

Evidence for the change itself is in the description: ran end to end on darwin-arm64 with the brew-installed lash hidden from PATH so the version check could not short-circuit the download. It fetched lashcode-darwin-arm64.zip from v1.7.13, extracted, installed to the target directory, and the binary reports 1.7.13.

@lacymorrow
lacymorrow merged commit 16e3ca3 into lash Sep 17, 2026
8 of 10 checks passed
@lacymorrow
lacymorrow deleted the fix/lash-installer branch September 17, 2026 23:42
lacymorrow added a commit to lacymorrow/lash-www that referenced this pull request Sep 18, 2026
* feat: strip the site to Lash

lash.lacy.sh was a Shipkit install with a Lash landing page bolted on. The
landing page linked to none of the rest of it, so everything behind the nav was
another product's marketing site: a pricing page for a $0 MIT product, a
features page describing Payload CMS and Auth.js, a blog holding two posts about
Shipkit releases, a download page selling "the premium Next.js boilerplate", and
a dashboard, admin area, 14 demo routes and a SaaS API surface with no product
behind any of it.

Deleted. 426 files, 48k lines. What is left is the landing page, the docs, the
changelog, the contact page, and the /install script route.

Removed:

  (kit)          faq, features, pricing, bones/cli
  (dashboard)    dashboard, projects, teams, deployments, api-keys, download, tools
  (admin)        the whole admin area
  (demo)         14 demo and example routes
  (integrations) builder.io, google-docs, polar, stripe
  (cms)          Payload
  blog           two Shipkit posts, plus rss.xml
  settings       account, profile, appearance, polar-products
  api            admin/users, deployments, download, github/*, payments/*,
                 permissions, projects, setup/*, teams
  install        the wizard UI, keeping only route.ts, which is the thing
                 `curl lash.lacy.sh/install` actually hits

Typecheck is clean before and after, which is the tell: none of it was wired to
anything that survived.

Docs. The docs/ directory held Shipkit's documentation, 66 of 78 files
describing a Next.js starter kit. Deleted and replaced with two pages that
document Lash: what the fork adds over OpenCode (the three execution modes and
ctrl+space, how Auto decides between shell and agent, the two prompt bars, cwd
tracking in the footer, Tab for shell completion), and how to install it.
Everything OpenCode already documents links to opencode.ai/docs rather than
being restated here.

With docs/ holding Lash content instead of Shipkit content, it ships again:
docs/** comes back out of .vercelignore.

Sitemap. src/app/sitemap.ts exported generateSitemaps(), which splits output
across /sitemap/0.xml, /sitemap/1.xml and so on. That is a feature for sites
with tens of thousands of URLs, and it is why /sitemap.xml returned 404. Replaced
with a single file listing the landing page, the docs and the changelog. robots.ts
had its sitemap line commented out, so robots.txt named no sitemap either; now it
does, and it disallows /api/ and the auth pages.

Nav is Docs and Changelog. It was Faqs, Features, Pricing on one layout and Blog,
Changelog, Docs on another, pointing at pages that are now gone.

Also removed an em dash from the site description, and the bones/muscles/brains
product tiers from site-config, which are Shipkit's and which nothing read.

Left alone on purpose: the auth routes. The site has no accounts and does not
need sign-in, but removing the auth stack means touching the root layout,
middleware and session providers, which is its own change. robots.txt keeps them
out of the index in the meantime. The contact page and its health check are also
untouched, since another branch is working on them.

* fix(install): proxy the install script from lash, not dev

The route fetched raw.githubusercontent.com/lacymorrow/lash/dev/install. `dev`
is upstream's branch name. `lash` is this repo's default and working branch, and
where lacymorrow/lash#48 fixes the script. The two files happen to be identical
right now, so this changes nothing today and everything once #48 merges.

* fix(types): drop the bones/muscles/brains fields from the branding type

Removing them from the object without removing them from the interface broke
typecheck. They are Shipkit's product tiers, nothing reads them, and the `(kit)`
routes that named them are gone, so the type goes with the values.
lacymorrow added a commit that referenced this pull request Sep 21, 2026
…c-2026-09-14

* origin/lash:
  fix(install): install lash, not opencode (#48)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant