build(examples/gastro): gitignore tailwind output, generate on demand
Removes examples/gastro/static/styles.css from version control and
treats it like every other generated artifact in the project (the
.gastro/ tree, example binaries, etc.).
Why
---
Committing the Tailwind output forced a minify-on-commit /
unminify-during-dev workflow with a CI drift gate (`go generate
./... && git diff --exit-code`). Every contributor and agent
edit cycle had to remember to regenerate the minified form before
staging, or CI would fail. The committed 50KB blob also obscured
source review every time a new utility class landed.
Tailwind output is generator-produced and noise-prone to commit.
It's consistent with how the project treats .gastro/ (gitignored,
regenerated by `gastro generate`).
What changed
------------
.gitignore
- New entry: examples/gastro/static/styles.css. Adjacent comment
explains the bootstrap requirement.
- Removed the stale "committed examples/gastro/static/styles.css
is what ships" sentence from the node_modules comment.
git rm --cached examples/gastro/static/styles.css
- Untracks the file; subsequent generators write to a gitignored
path.
scripts/dev/example-website
- New `if [ ! -f static/styles.css ]; then tailwindcss ...; fi`
bootstrap line before `exec gastro watch`. Without it the dev
watcher's first Generate would copy an empty static/ into
.gastro/static/ before --asset has a chance to fire, and the
first page load would 404 on /static/styles.css. The check is
a no-op on subsequent runs.
examples/gastro/Dockerfile
- Install the standalone tailwindcss binary (v4.3.0-linux-x64-musl
to match mise.toml and alpine's libc). wget added to apk install
list.
- Replace `RUN gastro generate` with `RUN go generate ./...` so
both //go:generate directives run in order (tailwindcss first,
then `gastro generate`). Keeps host and Docker bootstrap
commands identical.
.github/workflows/ci.yml
- Drop the `git diff --exit-code` drift check. The file is now
gitignored so no tracked file can drift. Keep the
`go generate ./...` step as a smoke test that the generators
still run cleanly against the gitignored fresh state.
cmd/gastro/watch.go
- New `suspectedAssetOutputCollision` companion to the existing
`suspectedBuildOutputCollision`. The asset variant permits
writes into static/ (the canonical Tailwind / esbuild / image-opt
destination) and only flags writes into pages/ or components/
where they'd feed back into Generate and loop. Without this
every legitimate --asset Tailwind setup printed a noisy false-
positive warning at startup.
- Extract shared `-o <path>` parsing into a `parseOutputPath`
helper consumed by both collision checkers.
- Updated startup call site for --asset to use the new function
and a more accurate warning message ("under a watched source
path", since static/ is no longer in the flagged set).
examples/gastro/AGENTS.md
- Replace the "must be minified, CI drift gate" warning with
bootstrap docs: gitignored, regenerated by `go generate ./...`
or the mise dev task, with notes on the dev / production
minification asymmetry and the Tailwind version pin alignment
requirement.
cmd/gastro/watch_test.go
- New `TestSuspectedAssetOutputCollision` covering the canonical
cases: Tailwind into static/ (allowed), esbuild into static/
(allowed), tmp/ (allowed), pages/ and components/ (flagged),
no -o (allowed).
Trade-offs
----------
- Fresh clone needs `go generate ./...` before `go build` produces
a website with CSS. Documented in AGENTS.md; the mise dev task
handles it automatically.
- Production builds need tailwindcss available. Dockerfile installs
it explicitly with a pinned version; the mise.toml-managed local
binary handles dev and CI.
- One more "tool must be on PATH" requirement to keep in sync with
mise.toml. AGENTS.md calls this out.
build(examples/gastro): gitignore tailwind output, generate on demand
Removes examples/gastro/static/styles.css from version control and
treats it like every other generated artifact in the project (the
.gastro/ tree, example binaries, etc.).
Why
---
Committing the Tailwind output forced a minify-on-commit /
unminify-during-dev workflow with a CI drift gate (`go generate
./... && git diff --exit-code`). Every contributor and agent
edit cycle had to remember to regenerate the minified form before
staging, or CI would fail. The committed 50KB blob also obscured
source review every time a new utility class landed.
Tailwind output is generator-produced and noise-prone to commit.
It's consistent with how the project treats .gastro/ (gitignored,
regenerated by `gastro generate`).
What changed
------------
.gitignore
- New entry: examples/gastro/static/styles.css. Adjacent comment
explains the bootstrap requirement.
- Removed the stale "committed examples/gastro/static/styles.css
is what ships" sentence from the node_modules comment.
git rm --cached examples/gastro/static/styles.css
- Untracks the file; subsequent generators write to a gitignored
path.
scripts/dev/example-website
- New `if [ ! -f static/styles.css ]; then tailwindcss ...; fi`
bootstrap line before `exec gastro watch`. Without it the dev
watcher's first Generate would copy an empty static/ into
.gastro/static/ before --asset has a chance to fire, and the
first page load would 404 on /static/styles.css. The check is
a no-op on subsequent runs.
examples/gastro/Dockerfile
- Install the standalone tailwindcss binary (v4.3.0-linux-x64-musl
to match mise.toml and alpine's libc). wget added to apk install
list.
- Replace `RUN gastro generate` with `RUN go generate ./...` so
both //go:generate directives run in order (tailwindcss first,
then `gastro generate`). Keeps host and Docker bootstrap
commands identical.
.github/workflows/ci.yml
- Drop the `git diff --exit-code` drift check. The file is now
gitignored so no tracked file can drift. Keep the
`go generate ./...` step as a smoke test that the generators
still run cleanly against the gitignored fresh state.
cmd/gastro/watch.go
- New `suspectedAssetOutputCollision` companion to the existing
`suspectedBuildOutputCollision`. The asset variant permits
writes into static/ (the canonical Tailwind / esbuild / image-opt
destination) and only flags writes into pages/ or components/
where they'd feed back into Generate and loop. Without this
every legitimate --asset Tailwind setup printed a noisy false-
positive warning at startup.
- Extract shared `-o <path>` parsing into a `parseOutputPath`
helper consumed by both collision checkers.
- Updated startup call site for --asset to use the new function
and a more accurate warning message ("under a watched source
path", since static/ is no longer in the flagged set).
examples/gastro/AGENTS.md
- Replace the "must be minified, CI drift gate" warning with
bootstrap docs: gitignored, regenerated by `go generate ./...`
or the mise dev task, with notes on the dev / production
minification asymmetry and the Tailwind version pin alignment
requirement.
cmd/gastro/watch_test.go
- New `TestSuspectedAssetOutputCollision` covering the canonical
cases: Tailwind into static/ (allowed), esbuild into static/
(allowed), tmp/ (allowed), pages/ and components/ (flagged),
no -o (allowed).
Trade-offs
----------
- Fresh clone needs `go generate ./...` before `go build` produces
a website with CSS. Documented in AGENTS.md; the mise dev task
handles it automatically.
- Production builds need tailwindcss available. Dockerfile installs
it explicitly with a pinned version; the mise.toml-managed local
binary handles dev and CI.
- One more "tool must be on PATH" requirement to keep in sync with
mise.toml. AGENTS.md calls this out.
Add Zed extension, CI/CD, and fix developer experience issues
Zed extension (editors/zed/) with Rust WASM shim that auto-downloads
gastro-lsp from GitHub releases. Cross-platform release build script
and GitHub Actions workflows for CI (test, lint, Zed WASM check) and
release (matrix build for 6 platforms, GitHub release creation).
DX fixes: dedicated build:gastro-lsp task, VS Code npm deps automated,
Neovim LSP auto-starts without requiring setup(), link:neovim task,
lint task (go vet), clean task, consistent build output. Docs updated
with correct Go version (1.26+) and Zed editor instructions.
Add Zed extension, CI/CD, and fix developer experience issues
Zed extension (editors/zed/) with Rust WASM shim that auto-downloads
gastro-lsp from GitHub releases. Cross-platform release build script
and GitHub Actions workflows for CI (test, lint, Zed WASM check) and
release (matrix build for 6 platforms, GitHub release creation).
DX fixes: dedicated build:gastro-lsp task, VS Code npm deps automated,
Neovim LSP auto-starts without requiring setup(), link:neovim task,
lint task (go vet), clean task, consistent build output. Docs updated
with correct Go version (1.26+) and Zed editor instructions.
feat(cli): adopt `go tool gastro` as a first-class install method
Adds the Go 1.24+ `tool` directive (project is on 1.26.1) as a third
install path alongside `mise` and `go install`, presented as equal-tier
peers. Decision recorded in DECISIONS.md (entry dated 2026-05-03).
Surfaces touched:
* All four examples (`blog`, `dashboard`, `gastro`, `sse`) gained
`tool github.com/andrioid/gastro/cmd/gastro` via `go get -tool`,
with the require version manually reverted to v0.0.0 so the existing
`replace … => ../..` convention continues to fail loudly if the
replace is dropped.
* `internal/scaffold/template/go.mod.tmpl` adds the same `tool`
directive (both dev and release paths). `main.go.tmpl` gains
`//go:generate go tool gastro generate`.
* VSCode extension (`editors/vscode/`): three-step launch resolver —
explicit `gastro.lspPath` setting wins, else walk up looking for a
`go.mod` containing the tool directive and launch
`go tool gastro lsp` with cwd at that go.mod, else fall back to
`gastro lsp` from PATH. Auto-detect chosen over an explicit
`gastro.useGoTool` setting because the directive in go.mod is
already the source of truth — duplicating it as a VSCode setting
would invite drift. Launch source logged to the LSP output channel
at startup. Version-mismatch warning text branches on launch source.
Bumped version 0.1.17 → 0.1.18. New devDependency `@types/node`
approved for the `fs`/`path` reads in the resolver.
* Neovim docs-only (`editors/neovim/gastro.lua`): install header
lists `go tool` as a third option with copy-paste
`setup({ cmd = { "go", "tool", "gastro", "lsp" } })` snippet.
* Zed no-op: the extension downloads its own LSP from GitHub releases
and never consults PATH; new `editors/zed/README.md` documents
this so users don't waste time wondering why their tool directive
isn't picked up.
* LSP version-on-startup logging (`internal/lsp/server/server.go`):
the existing `gastro lsp: starting` log line now includes the
version. Visible in VSCode output channel, Neovim `:LspLog`, and
Zed language server log.
* `scripts/verify-bootstrap` extended to exercise both
`go tool gastro list` (proves the directive resolves and the
binary builds) and `go generate ./...` (proves the directive
triggers regeneration) on the freshly-scaffolded test project.
* `internal/scaffold/scaffold_test.go` gained three assertions: the
tool directive in both release and dev go.mod shapes, and the
`//go:generate` directive in main.go.
No `cmd/gastro` runtime code changes were needed — `gastro dev`'s
child-process spawning model uses no `os.Executable()` self-reference,
so the binary works identically whether launched globally or via
`go tool`.
Approved one new VSCode devDependency (`@types/node`); no new Go
runtime/CLI dependencies.