Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
9cd5ec0
docs: document reproducible UI stack installs
riyandhiman14 Aug 21, 2026
e78d9c0
fix: honor pinned refs on UI reinstall
riyandhiman14 Aug 21, 2026
b27ef6c
chore: add dependency update automation
riyandhiman14 Aug 21, 2026
392c046
ci: cancel superseded UI checks
riyandhiman14 Aug 21, 2026
84b13fa
ci: build checksummed UI release binaries
riyandhiman14 Aug 21, 2026
7d63929
docs: show UI artifact checksum verification
riyandhiman14 Aug 21, 2026
5993edc
docs: add UI release runbook
riyandhiman14 Aug 21, 2026
f1e8469
docs: recommend pinned UI releases
riyandhiman14 Aug 21, 2026
5df2788
Bound UI CI and release runtimes
riyandhiman14 Aug 21, 2026
39cb702
Pin UI installer fallback releases
riyandhiman14 Aug 21, 2026
b1305b3
Pin UI builds to the declared Go toolchain
riyandhiman14 Aug 21, 2026
f2e1ab9
Make UI release archives reproducible
riyandhiman14 Aug 21, 2026
f5c8716
Make UI release checksums artifact-relative
riyandhiman14 Aug 21, 2026
e91343d
Protect UI installer from untracked checkout state
riyandhiman14 Aug 21, 2026
a2a3ef5
Stamp UI release versions into binaries
riyandhiman14 Aug 21, 2026
375db5d
Document UI binary version verification
riyandhiman14 Aug 21, 2026
56833a5
Require UI release notes for tags
riyandhiman14 Aug 21, 2026
c9abeaf
Validate UI installer Python floor early
riyandhiman14 Aug 21, 2026
916f6c1
Validate UI installer Go floor early
riyandhiman14 Aug 21, 2026
7ade1da
Vendor TypeScript in UI stack installer
riyandhiman14 Aug 21, 2026
e3478e8
Document vendored TypeScript in UI installer
riyandhiman14 Aug 21, 2026
4bc56d8
Add safe UI installer help handling
riyandhiman14 Aug 21, 2026
f954b81
Document macOS release checksum verification
riyandhiman14 Aug 21, 2026
4f75519
Make UI release archives reproducible
riyandhiman14 Aug 21, 2026
8138f86
Honor custom install roots in graph helper
riyandhiman14 Aug 21, 2026
a52ed41
Verify UI archive reproducibility in release CI
riyandhiman14 Aug 21, 2026
9d9f554
Correct UI engine install guidance
riyandhiman14 Aug 21, 2026
e7e40f6
Honor custom Lachesis roots in UI discovery
riyandhiman14 Aug 21, 2026
508dee1
Ignore non-directory graph artifacts in UI
riyandhiman14 Aug 21, 2026
9d9b06f
Reject non-directory graph paths early
riyandhiman14 Aug 21, 2026
bd0bac9
Bound UI engine startup time
riyandhiman14 Aug 21, 2026
d64d463
Document UI runtime safeguards
riyandhiman14 Aug 21, 2026
b26596b
Stamp version into installer-built UI
riyandhiman14 Aug 21, 2026
f22e718
Fail fast when UI build toolchain is missing
riyandhiman14 Aug 21, 2026
2816d53
Serialize UI installer runs
riyandhiman14 Aug 21, 2026
c6b181b
Recover stale UI installer locks safely
riyandhiman14 Aug 21, 2026
400cfdb
Pin UI CI actions to immutable SHAs
riyandhiman14 Aug 21, 2026
4ddc226
Keep generated graph paths inside graph root
riyandhiman14 Aug 21, 2026
d03f50d
Add one-command UI developer gate
riyandhiman14 Aug 21, 2026
f1e1d9d
Document UI developer gate
riyandhiman14 Aug 21, 2026
547d1d1
Surface MCP engine diagnostics in UI
riyandhiman14 Aug 21, 2026
7f25cc8
Clarify missing source errors in graph helper
riyandhiman14 Aug 21, 2026
5937296
Clarify UI engine interpreter setup
riyandhiman14 Aug 21, 2026
c0fe085
Validate UI installer refs early
riyandhiman14 Aug 21, 2026
70540f5
Use selected interpreter in UI recovery hint
riyandhiman14 Aug 21, 2026
4352cc3
Bound UI MCP tool requests
riyandhiman14 Aug 21, 2026
156baa5
Make UI installer Git noninteractive
riyandhiman14 Aug 21, 2026
7d1a1d3
Smoke test native UI release
riyandhiman14 Aug 21, 2026
5adc4c5
Smoke-test extracted UI release archive
riyandhiman14 Aug 21, 2026
dc9cbed
Bound UI installer network waits
riyandhiman14 Aug 21, 2026
9b94943
Document UI installer network bounds
riyandhiman14 Aug 21, 2026
8e70cba
Clarify UI engine install recovery
riyandhiman14 Aug 21, 2026
c3d40bd
Clarify UI binary release install path
riyandhiman14 Aug 21, 2026
a52e1d0
Unify UI version metadata
riyandhiman14 Aug 21, 2026
671d717
Warn on mutable UI stack refs
riyandhiman14 Aug 21, 2026
84044d8
Terminate UI engine process groups on timeout
riyandhiman14 Aug 21, 2026
598e4cc
Test UI process group configuration
riyandhiman14 Aug 21, 2026
d3f6a52
Configure UI graph build timeout
riyandhiman14 Aug 21, 2026
689bb5f
Document UI engine Python support
riyandhiman14 Aug 21, 2026
5111879
Derive UI build version from VERSION
riyandhiman14 Aug 21, 2026
a7767ed
Use version tags in UI workflows
riyandhiman14 Aug 21, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
version: 2
updates:
- package-ecosystem: gomod
directory: "/"
schedule:
interval: weekly
- package-ecosystem: github-actions
directory: "/"
schedule:
interval: weekly
28 changes: 8 additions & 20 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,35 +9,23 @@ on:
permissions:
contents: read

concurrency:
group: ui-ci-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
name: build and check
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Check out
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.24'
check-latest: true

- name: Verify gofmt
run: |
unformatted=$(gofmt -l .)
if [ -n "$unformatted" ]; then
echo "These files are not gofmt-clean:"
echo "$unformatted"
echo "Run 'make fmt' and commit the result."
exit 1
fi

- name: go vet
run: go vet ./...

- name: Build
run: go build ./...
go-version: '1.24.2'

- name: Test
run: go test ./...
- name: Run the local gate
run: make check
93 changes: 93 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
name: release binaries

on:
push:
tags: ["v*"]

permissions:
contents: read

jobs:
build:
name: ${{ matrix.goos }}-${{ matrix.goarch }}
runs-on: ubuntu-latest
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
include:
- goos: linux
goarch: amd64
- goos: linux
goarch: arm64
- goos: darwin
goarch: amd64
- goos: darwin
goarch: arm64
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.24.2"
cache: true
- name: Verify tag has changelog entry
run: |
python3 - <<'PY'
import os
from pathlib import Path

version = os.environ["GITHUB_REF_NAME"].removeprefix("v")
heading = f"## [{version}]"
if heading not in Path("CHANGELOG.md").read_text(encoding="utf-8"):
raise SystemExit(f"CHANGELOG.md has no release heading for {version}")
declared = Path("VERSION").read_text(encoding="utf-8").strip()
if declared != version:
raise SystemExit(f"VERSION declares {declared}, but tag is {version}")
print(f"changelog entry: {heading}")
print(f"UI version: {declared}")
PY
- name: Build and package
env:
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
CGO_ENABLED: "0"
run: |
set -euo pipefail
export SOURCE_DATE_EPOCH="$(git log -1 --format=%ct)"
version="${GITHUB_REF_NAME#v}"
name="lachesis-ui-${GITHUB_REF_NAME}-${GOOS}-${GOARCH}"
mkdir -p dist
go build -trimpath -ldflags="-s -w -X github.com/UnboundCompute/lachesis-ui/internal/mcp.Version=$version" -o "dist/$name/lachesis-ui" .
cp README.md LICENSE "dist/$name/"
# Normalize tar metadata and the gzip header so the same tag rebuilds
# to byte-identical artifacts.
tar -C dist --sort=name --mtime="@${SOURCE_DATE_EPOCH}" \
--owner=0 --group=0 --numeric-owner -cf - "$name" \
| gzip -n > "dist/$name.tar.gz"
sha256sum "dist/$name.tar.gz" > "/tmp/${name}.first.sha256"
tar -C dist --sort=name --mtime="@${SOURCE_DATE_EPOCH}" \
--owner=0 --group=0 --numeric-owner -cf - "$name" \
| gzip -n > "dist/$name.tar.gz"
sha256sum -c "/tmp/${name}.first.sha256"
(cd dist && sha256sum "$name.tar.gz") >> dist/SHA256SUMS
- name: Smoke-test native binary
if: matrix.goos == 'linux' && matrix.goarch == 'amd64'
run: |
set -euo pipefail
version="${GITHUB_REF_NAME#v}"
name="lachesis-ui-${GITHUB_REF_NAME}-${{ matrix.goos }}-${{ matrix.goarch }}"
expected="lachesis-ui ${version}"
verify_dir="$(mktemp -d)"
trap 'rm -rf "$verify_dir"' EXIT
tar -xzf "dist/$name.tar.gz" -C "$verify_dir"
test -f "$verify_dir/$name/lachesis-ui"
actual="$("$verify_dir/$name/lachesis-ui" --version)"
test "$actual" = "$expected" || {
echo "version mismatch: got '$actual', want '$expected'" >&2
exit 1
}
- name: Upload binary artifact
uses: actions/upload-artifact@v4
with:
name: lachesis-ui-${{ github.ref_name }}-${{ matrix.goos }}-${{ matrix.goarch }}
path: dist/
60 changes: 60 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,12 @@ and this project aims to follow [Semantic Versioning](https://semver.org/spec/v2

## [Unreleased]

- Added a machine-readable `VERSION` source used by the installer’s source-build
default; release CI now rejects tags that do not match it.

### Added

- Tagged releases now build checksummed Linux and macOS binaries for amd64 and arm64.
- Nested, collapsible source tree on the Tree screen. Folders expand in place
and load their children lazily, with child-count badges, so a large repo
opens as a handful of top-level folders rather than a flat wall of files.
Expand All @@ -18,9 +22,65 @@ and this project aims to follow [Semantic Versioning](https://semver.org/spec/v2

### Changed

- Release verification now executes the native Linux binary and checks its stamped
version from the extracted archive before uploading cross-platform archives.

- The stack installer now disables Git terminal prompts so unattended setup fails
clearly when a checkout cannot authenticate or reach its repository.

- The stack installer now applies Git low-speed and pip network bounds, so stalled
repository or dependency transfers fail clearly instead of hanging unattended.

- UI MCP tool requests now have a two-minute default bound, configurable with
`LACHESIS_UI_REQUEST_TIMEOUT`, and report recent engine diagnostics when a request
times out instead of leaving the terminal waiting indefinitely.

- The install documentation now uses `python -m pip` so engine dependencies
stay in the interpreter the UI discovers.

- Engine startup recovery now points to the supported source-checkout install and
labels the PyPI command as conditional until a release is published.

- The binary-only install section now distinguishes the working source build from
the `go install` command reserved for a published UI tag.

- The stack installer now warns when engine or catalog refs remain on mutable `main`,
while preserving those defaults for development use.

- UI engine shutdown now uses a dedicated POSIX process group, so startup or request
timeouts terminate compiler/helper children along with the MCP parent.
- The stack installer now exposes the generated graph helper's frontend timeout as
`LACHESIS_BUILD_TIMEOUT` instead of requiring edits to generated shell code.
- Documented the engine's Python 3.10–3.12 release-tested window in the UI setup guide.
- The Makefile now derives its default binary version from `VERSION`, matching the
installer and release workflow while retaining explicit `VERSION=...` overrides.

- UI startup diagnostics now use `python -m pip` in their engine-install hint,
avoiding interpreter mismatches during recovery.

- The installer rejects empty, option-like, or whitespace-containing engine,
catalog, and UI refs before invoking Git.

- MCP startup and request failures now include the bounded recent engine stderr
tail, making wrong-interpreter, missing-graph, and import failures visible in
the UI instead of looking like a silent server exit.

- Added a single `make check` developer/CI gate covering formatting, vet, build,
and tests.

- The generated `build-graph.sh` helper rejects path-like graph names so output
cannot escape the configured graph directory.

- The generated graph helper now reports a clear error for a missing source
directory before attempting to resolve it.

- The Tree keys now match a nested tree: right expands a folder, left collapses
it or jumps to its parent, and enter opens a folder or a symbol's
neighborhood.
- Custom `LACHESIS_HOME` installs now work end-to-end, including UI engine and graph
discovery.
- Engine startup is bounded by a configurable timeout, and invalid graph artifacts
are rejected with actionable diagnostics.

## [0.1.0]

Expand Down
11 changes: 5 additions & 6 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ about how that information is shown or navigated, it belongs here.

## Getting set up

You need Go 1.24+ and, to run the UI against a real graph, the engine.
You need Go 1.24.2+ and, to run the UI against a real graph, the engine.

```sh
git clone https://github.com/UnboundCompute/lachesis-ui
Expand Down Expand Up @@ -64,15 +64,14 @@ in the screen's own file.

## Before you open a pull request

Run the local checks. CI runs the same ones and will block a merge if any fail.
Run the local gate. CI runs the same command and will block a merge if any check fails.

```sh
make fmt # gofmt: formatting must be clean
make vet # go vet: no reported problems
make build # the binary must build
go test ./... # tests must pass
make check # gofmt check, vet, build, and tests
```

Use `make fmt` when the formatting check reports files that need rewriting.

Guidelines:

- Keep formatting gofmt-clean. CI fails on any file gofmt would rewrite.
Expand Down
19 changes: 17 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
BIN ?= lachesis-ui
PREFIX ?= $(HOME)/.lachesis/bin
VERSION ?= $(shell tr -d '[:space:]' < VERSION 2>/dev/null || printf '0.1.0')
LDFLAGS ?= -X github.com/UnboundCompute/lachesis-ui/internal/mcp.Version=$(VERSION)

.PHONY: build install run tidy fmt vet clean stack
.PHONY: build install run tidy fmt vet check clean stack

## build the binary into the working directory
build:
go build -o $(BIN) .
go build -ldflags "$(LDFLAGS)" -o $(BIN) .

## build and drop the binary into ~/.lachesis/bin
install: build
Expand All @@ -29,5 +31,18 @@ fmt:
vet:
go vet ./...

## run the complete local gate used by CI
check:
@unformatted="$$(gofmt -l .)"; \
if [ -n "$$unformatted" ]; then \
echo "These files are not gofmt-clean:"; \
echo "$$unformatted"; \
echo "Run 'make fmt' and commit the result."; \
exit 1; \
fi
go vet ./...
go build ./...
go test ./...

clean:
rm -f $(BIN)
Loading
Loading