diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..e6a8fe2 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,27 @@ +# Line-ending rules. +# +# Scoped deliberately to the file types this change introduces, rather than a +# blanket `* text=auto eol=lf`. Nine of the 33 tracked files (LICENSE, several +# .go files, both existing workflows) currently carry CRLF; a blanket rule would +# renormalise all of them the next time anyone touched them, producing a +# whole-file diff at a moment unrelated to whatever they were actually changing. +# That mixed state is worth cleaning up, but as its own commit, not as a side +# effect of this one. + +# Shell scripts must be LF. CRLF gives `bad interpreter: /usr/bin/env bash^M`, +# which is a genuinely confusing way to fail. +*.sh text eol=lf + +# Generated compliance artifacts are written with LF. Without this, a +# contributor with core.autocrlf=true checks them out as CRLF and the freshness +# check reports them stale with a diff that looks empty. +NOTICE text eol=lf +THIRD-PARTY-*.md text eol=lf +*.css text eol=lf + +# Vendored assets — never normalise. These are embedded into the binary +# verbatim and any rewriting corrupts them. +*.woff2 binary +*.woff binary +*.png binary +ai-studio-cli/internal/benchui/ui/vendor/js/*.js -text diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index b5e8cfd..715df0e 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -29,7 +29,18 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 with: - fetch-depth: 1 + # Full history, not a shallow clone. + # + # With fetch-depth: 1 the runner has only the PR head commit and no + # base branch, so the action's own `git fetch origin master --depth=1` + # had nothing to graft onto and failed with + # "Command failed: git fetch origin master --depth=1" + # before the review ever started. A review action has to diff against + # the base branch, which means the base branch has to be present. + # + # 0 = full history. On a repo this size the extra clone cost is + # negligible compared to a job that cannot run at all. + fetch-depth: 0 - name: Run Claude Code Review id: claude-review diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index 6b15fac..508f6b0 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -28,7 +28,18 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 with: - fetch-depth: 1 + # Full history, not a shallow clone. + # + # With fetch-depth: 1 the runner has only the PR head commit and no + # base branch, so the action's own `git fetch origin master --depth=1` + # had nothing to graft onto and failed with + # "Command failed: git fetch origin master --depth=1" + # before the review ever started. A review action has to diff against + # the base branch, which means the base branch has to be present. + # + # 0 = full history. On a repo this size the extra clone cost is + # negligible compared to a job that cannot run at all. + fetch-depth: 0 - name: Run Claude Code id: claude diff --git a/.github/workflows/compliance.yml b/.github/workflows/compliance.yml new file mode 100644 index 0000000..21cfc83 --- /dev/null +++ b/.github/workflows/compliance.yml @@ -0,0 +1,166 @@ +name: Licence compliance + +# Makes the licence position self-enforcing. +# +# The distribution model here is the strictest of the three AI Studio repos. +# aistudio-server conveys container images; aistudio-app serves a JS bundle; +# this ships a compiled Go binary that STATICALLY LINKS every dependency. There +# is no node_modules or site-packages beside the artifact for notices to live +# in — the binary is the whole distribution, so the notices have to be inside +# it. These checks confirm they are. + +on: + push: + branches: [master, main] + pull_request: + schedule: + # Weekly. Upstream modules change licences occasionally and silently. + - cron: "0 6 * * 1" + workflow_dispatch: + +permissions: + contents: read + +env: + GO_VERSION: "1.25" + +jobs: + files: + name: Licence files and bench UI assets + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Static compliance checks + # Same target as `make compliance` locally, so the feedback loop does + # not require a push. Covers LICENSE completeness and filled-in + # copyright, required files, no CDN references in the bench UI, and that + # the vendored fonts and Chart.js are present with their licences. + # + # Needs no Go toolchain and no network, deliberately — these are the + # checks anyone should be able to run on any checkout. The placeholder + # state is reported here, not failed on; that is the `build` job's job. + run: make compliance + + - name: Vendored UI assets match their declared versions + run: | + # These binaries are committed (go:embed needs them at compile time + # and `go build` cannot run npm), so nothing stops someone editing + # them by hand. Regenerate into a scratch dir and compare. + VENDOR_DEST=/tmp/vendor-check ./scripts/vendor-ui-assets.sh + if ! diff -r /tmp/vendor-check ai-studio-cli/internal/benchui/ui/vendor; then + echo "::error::vendored UI assets differ from a clean regeneration." + echo "Run ./scripts/vendor-ui-assets.sh and commit the result." + exit 1 + fi + echo "Vendored assets reproduce exactly." + + - name: Every font referenced by fonts.css exists + run: | + # Guards against a weight being added to the script's list and + # shipping as a CSS rule with no file behind it — which go:embed + # would happily compile into the binary. + cd ai-studio-cli/internal/benchui/ui/vendor + missing=0 + for url in $(grep -oE 'url\("\./[^"]+"\)' fonts.css | sed -E 's|url\("\./||; s|"\)||'); do + [ -f "$url" ] || { echo "::error::fonts.css references missing $url"; missing=1; } + done + exit $missing + + build: + name: Build with generated notices and verify the binary carries them + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-go@v5 + with: + go-version: ${{ env.GO_VERSION }} + cache-dependency-path: ai-studio-cli/go.sum + + - name: Generate notices and build + # Generation happens HERE rather than being compared against a committed + # copy. An earlier version of this workflow diffed the generated output + # against a file in the repo, which meant a reviewable branch could not + # exist without a Go toolchain and network access, and every dependency + # bump carried a regenerate-and-commit step whose only failure mode was + # a red build with a misleading message. + # + # `go list -deps` answers the only question that matters: which modules + # are actually linked into this binary — not everything in go.sum, which + # also lists test and tooling modules that never reach a user. + run: make build-release + + - name: "`licenses` prints real notices" + # The check that actually matters. Everything else verifies files exist + # in a repository; this verifies the notices are inside the artifact a + # user receives, which is what the obligation is. + run: | + out=$(./bin/ai-studio-cli licenses 2>&1) || { + echo "::error::\`bin/ai-studio-cli licenses\` failed:" + echo "$out" + exit 1 + } + + if grep -q "NOTICES-NOT-GENERATED" <<<"$out"; then + echo "::error::the binary embeds the placeholder — make build-release did not generate them." + exit 1 + fi + + copyrights=$(grep -ci "copyright" <<<"$out" || true) + if [ "$copyrights" -lt 10 ]; then + echo "::error::only $copyrights copyright notices in the binary output — expected 10+." + exit 1 + fi + echo "$copyrights copyright notices embedded." + + # The go:embed'd UI assets are not Go modules, so the module walk + # cannot see them. generate-notices.sh appends them; confirm it did. + grep -qi "SIL Open Font License" <<<"$out" || { + echo "::error::OFL-1.1 text missing, but Inter is embedded (OFL s2)." + exit 1 + } + grep -qi "chart.js" <<<"$out" || { + echo "::error::Chart.js attribution missing, but it is embedded (MIT)." + exit 1 + } + echo "Embedded UI asset notices present." + + - name: Bench UI serves no external assets + run: | + # Belt and braces against the Makefile check: assert the reference is + # absent from the compiled binary, not just from the source tree. + # + # Matches a LOADING position (`="https://host`), not any mention of a + # hostname. index.html carries a comment explaining why the Google + # Fonts links were removed, and that comment names the hostname — it is + # embedded verbatim by go:embed, so a bare hostname grep matches our own + # documentation and fails the build. It did exactly that on the first + # run of this check. + # + # The `="` prefix is what separates markup from prose: a real + # regression looks like `/dev/null || echo missing) + if [ "$type" != "tag" ]; then + echo "::error::'$TAG' is a lightweight tag (type=$type)." + echo "Lightweight tags carry no author, date or signature, and can be" + echo "silently repointed. Re-cut it with: git tag -a -s $TAG -m ..." + exit 1 + fi + echo "$TAG is annotated." + + - name: Compliance gate + run: make compliance + + - name: Build with generated notices + # This is where the placeholder is a hard stop rather than a note. + # `build-release` generates the notices, builds, and fails if the + # resulting binary cannot print them. A released binary must never ship + # without its attribution. + run: make build-release + + - name: Verify the binary carries its notices + run: | + out=$(./bin/${BINARY} licenses) + # if/then, not `grep -q ... && { exit 1; }`. The AND-list returns + # grep's status, so in the good case (marker absent) it evaluates to 1 + # — and if it were ever the last command in the step, `bash -e` would + # fail the step precisely when nothing was wrong. + if grep -q "NOTICES-NOT-GENERATED" <<<"$out"; then + echo "::error::refusing to release a binary embedding the placeholder." + exit 1 + fi + echo "Notices embedded: $(grep -ci copyright <<<"$out") copyright lines." + + - name: Package + run: | + TAG="${{ github.event.inputs.tag }}" + TAG="${TAG:-$GITHUB_REF_NAME}" + mkdir -p dist + # The tarball carries the notices and licence beside the binary, so + # they are present even for someone who never runs `licenses`. + cp LICENSE NOTICE ai-studio-cli/internal/notices/THIRD-PARTY-NOTICES.txt dist/ + cp "bin/${BINARY}" dist/ + tar -czf "${TAG}.tar.gz" -C dist . + cp ai-studio-cli/internal/notices/THIRD-PARTY-NOTICES.txt . + + - name: Checksums + run: | + TAG="${{ github.event.inputs.tag }}" + TAG="${TAG:-$GITHUB_REF_NAME}" + sha256sum "${TAG}.tar.gz" THIRD-PARTY-NOTICES.txt > SHA256SUMS + cat SHA256SUMS + + - name: Publish + env: + GH_TOKEN: ${{ github.token }} + run: | + TAG="${{ github.event.inputs.tag }}" + TAG="${TAG:-$GITHUB_REF_NAME}" + gh release create "$TAG" \ + --title "ai-studio-cli $TAG" \ + --generate-notes \ + --verify-tag \ + "${TAG}.tar.gz" \ + THIRD-PARTY-NOTICES.txt \ + SHA256SUMS \ + || gh release upload "$TAG" \ + "${TAG}.tar.gz" THIRD-PARTY-NOTICES.txt SHA256SUMS --clobber diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3ebffc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ + +# Build output — the binary is written to bin/, deliberately not the repo +# root, where its name would collide with the ai-studio-cli/ module directory. +bin/ diff --git a/LICENSE b/LICENSE index 261eeb9..d242001 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright 2026 CoreSpan AI Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5e21046 --- /dev/null +++ b/Makefile @@ -0,0 +1,145 @@ +MODULE_DIR := ai-studio-cli +BINARY := ai-studio-cli + +# Build into bin/, NOT the repo root. +# +# The module lives in a directory with the same name as the binary, so +# `go build -o ../ai-studio-cli` from inside it resolves to the module directory +# itself. `-o` pointing at an existing directory makes Go write the executable +# *inside* it — so the binary landed at ai-studio-cli/ai-studio-cli, and +# `./ai-studio-cli` at the repo root was still the directory. Running it gave +# "Is a directory", exit 126, which make reports as exit 2. That was the real +# cause of the CI build job failing, not the licence notices. +BIN_DIR := bin +BINARY_PATH := $(BIN_DIR)/$(BINARY) + +.PHONY: build build-release run test fmt vet notices vendor-ui compliance clean + +# ── Build ──────────────────────────────────────────────────────────────────── + +build: + @mkdir -p $(BIN_DIR) + cd $(MODULE_DIR) && go build -o ../$(BINARY_PATH) . + @echo "Built ./$(BINARY_PATH)" + @test -f $(BINARY_PATH) || (echo "FAIL: $(BINARY_PATH) is not a regular file" && exit 1) + +run: + cd $(MODULE_DIR) && go run . + +test: + cd $(MODULE_DIR) && go test ./... + +fmt: + cd $(MODULE_DIR) && gofmt -w . + +vet: + cd $(MODULE_DIR) && go vet ./... + +# ── Licence compliance ─────────────────────────────────────────────────────── +# +# A Go binary statically links its dependencies, so shipping a release binary +# means distributing their code. The notices have to travel inside the binary — +# there is nothing else alongside it. See scripts/generate-notices.sh. +# +# THE NOTICES ARE GENERATED, NOT COMMITTED. +# +# The first version of this treated the generated inventory as a committed +# artifact with a CI drift check. That was wrong twice over: it needed network +# access and a Go toolchain just to produce a reviewable branch, and it put a +# regenerate-and-commit step on the critical path of every dependency bump — +# a step whose only failure mode is a red build with a misleading message. +# +# What actually has to be true is narrower: no RELEASED binary may ship without +# its notices. So generation happens in CI and in the release flow, where the +# network is, and `make build-release` is the gate. A locally built binary may +# carry the placeholder; `ai-studio-cli licenses` says so plainly rather than +# printing an empty page. + +notices: + ./scripts/generate-notices.sh + +# Build with real notices embedded. What CI and the release workflow run. +# +# The steps are sequenced inside the recipe rather than declared as +# prerequisites (`build-release: notices build`). Prerequisites may run in +# parallel under `make -j`, which would race the build against the generator and +# could embed the placeholder in a binary that then passes the check by luck. +# Order matters here, so it is made explicit. +build-release: + $(MAKE) notices + $(MAKE) build + @echo + @./$(BINARY_PATH) licenses > /dev/null 2>&1 \ + || (echo "FAIL: the built binary cannot print its notices." \ + && echo " Expected 'make notices' to have replaced the placeholder." \ + && exit 1) + @echo "Built ./$(BINARY_PATH) with $$(./$(BINARY_PATH) licenses | grep -ci copyright) embedded copyright notices." + +vendor-ui: + @# Fonts and Chart.js for the embedded bench UI. Committed, not fetched at + @# build time: `go build` cannot run npm, and go:embed needs the files + @# present in the source tree. + ./scripts/vendor-ui-assets.sh + +compliance: + @echo "── LICENSE ─────────────────────────────────────────────────────────" + @test $$(wc -c < LICENSE) -ge 10000 \ + || (echo " FAIL: LICENSE is only $$(wc -c < LICENSE) bytes — not the full Apache-2.0 text" && exit 1) + @grep -aq "3. Grant of Patent License" LICENSE || (echo " FAIL: LICENSE missing section 3" && exit 1) + @# `grep && (echo; exit 1) || true` swallows the failure — the || catches the + @# subshell's own exit. Use if/then/fi so the recipe actually fails. + @if grep -aq "name of copyright owner" LICENSE; then \ + echo " FAIL — LICENSE still has the placeholder copyright line"; exit 1; \ + fi + @echo " ok — $$(wc -c < LICENSE) bytes, sections present, copyright filled in" + @echo "── Required files ──────────────────────────────────────────────────" + @for f in NOTICE $(MODULE_DIR)/internal/benchui/ui/vendor/NOTICE \ + $(MODULE_DIR)/internal/notices/THIRD-PARTY-NOTICES.txt; do \ + test -f $$f && echo " ok — $$f" || (echo " FAIL — missing $$f" && exit 1); \ + done + @echo "── Embedded notices ────────────────────────────────────────────────" + @# Informational here, fatal in `make build-release`. A checkout carrying + @# the placeholder is the normal state — generating requires network and a + @# Go toolchain, and demanding that of everyone who wants to run the static + @# checks buys nothing. What must never happen is a RELEASE shipping it, and + @# that is enforced where releases are built. + @if grep -q "NOTICES-NOT-GENERATED" $(MODULE_DIR)/internal/notices/THIRD-PARTY-NOTICES.txt; then \ + echo " placeholder present — normal for a fresh checkout."; \ + echo " Real notices are generated by 'make notices', which CI and the"; \ + echo " release workflow run. 'make build-release' fails without them."; \ + else \ + echo " ok — generated notices are present ($$(grep -ci copyright $(MODULE_DIR)/internal/notices/THIRD-PARTY-NOTICES.txt) copyright lines)"; \ + fi + @echo "── Bench UI makes no third-party requests ──────────────────────────" + @# CDN assets break on air-gapped GPU nodes — the target deployment — and + @# Google Fonts discloses the operator's IP. + @# + @# Matches only real loading positions (src=/href= followed by an absolute + @# URL), not any mention of a hostname. A bare hostname grep flags the + @# comment in index.html that explains why the CDN links were removed, which + @# is a good way to get the check deleted. + @if grep -rnE '(src|href)[[:space:]]*=[[:space:]]*["'"'"']https?://' \ + $(MODULE_DIR)/internal/benchui/ui/index.html \ + $(MODULE_DIR)/internal/benchui/ui/index.css \ + $(MODULE_DIR)/internal/benchui/ui/app.js 2>/dev/null; then \ + echo " FAIL — bench UI loads an asset from an absolute URL (see above)"; exit 1; \ + fi + @# CSS url() and @import, which have no src=/href= prefix. + @if grep -rnE '(url\(|@import)[[:space:]]*["'"'"']?https?://' \ + $(MODULE_DIR)/internal/benchui/ui/index.css 2>/dev/null; then \ + echo " FAIL — bench UI CSS loads from an absolute URL (see above)"; exit 1; \ + fi + @echo " ok — no third-party asset references" + @echo "── Vendored UI assets present ──────────────────────────────────────" + @test $$(ls $(MODULE_DIR)/internal/benchui/ui/vendor/fonts/*.woff2 2>/dev/null | wc -l) -eq 6 \ + || (echo " FAIL — expected 6 vendored fonts; run 'make vendor-ui'" && exit 1) + @test -f $(MODULE_DIR)/internal/benchui/ui/vendor/js/chart.umd.js \ + || (echo " FAIL — Chart.js missing; run 'make vendor-ui'" && exit 1) + @echo " ok — fonts and Chart.js vendored with their licences" + @echo "" + @echo "Compliance checks passed." + @echo "Release gate (needs network + Go): 'make build-release'." + +clean: + rm -rf $(BIN_DIR) + cd $(MODULE_DIR) && go clean diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..2d45142 --- /dev/null +++ b/NOTICE @@ -0,0 +1,63 @@ +AI Studio CLI (ai-studio-cli) +Copyright 2026 CoreSpan AI + +This product includes software developed at CoreSpan AI. + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License in the LICENSE file distributed with this work, or at: + + http://www.apache.org/licenses/LICENSE-2.0 + +-------------------------------------------------------------------------------- +THIRD-PARTY SOFTWARE +-------------------------------------------------------------------------------- + +ai-studio-cli is distributed as a compiled Go binary. Go statically links its +dependencies, so a released binary contains compiled copies of every module in +its build graph — cobra, viper, pflag, fsnotify and the rest — together with +the web UI assets embedded via go:embed. + +Distributing the binary distributes all of that. Unlike an interpreted project, +there is no node_modules or site-packages beside the artifact for third-party +notices to live in: the binary is the whole distribution, so the notices are +compiled into it. + +Print them from any build: + + ai-studio-cli licenses + +The same text is published as an asset on every GitHub release, so it can be +read without running the binary. + +Sources of the embedded notices: + + * Go modules — generated by `make notices` (go-licenses over the real build + graph) into ai-studio-cli/internal/notices/THIRD-PARTY-NOTICES.txt + + * Web UI assets — ai-studio-cli/internal/benchui/ui/vendor/NOTICE + Inter and JetBrains Mono, SIL OFL-1.1 + Chart.js 4.4.7, MIT + +-------------------------------------------------------------------------------- +EXTERNAL SOFTWARE THIS TOOL INSTALLS OR RUNS +-------------------------------------------------------------------------------- + +Separately from what is compiled in, ai-studio-cli provisions and runs software +on GPU nodes: NVIDIA drivers and the CUDA userspace, Docker or Podman, vLLM, +nvbandwidth, and container images pulled at run time. + +CoreSpan does not distribute those. They are downloaded by the operator, from +their publishers, onto the operator's own machines, under those publishers' +terms — the NVIDIA driver and CUDA EULAs in particular. Nothing in this +repository's Apache-2.0 grant extends to them, and accepting their terms is +between the operator and the publisher. + +-------------------------------------------------------------------------------- +TRADEMARKS +-------------------------------------------------------------------------------- + +Apache License 2.0 Section 6 grants no trademark rights. "CoreSpan" and the +CoreSpan logo are trademarks of CoreSpan AI. All other product names, logos and +brands referenced in this repository are the property of their respective +owners and are used for identification purposes only. diff --git a/README.md b/README.md index 613c588..165678b 100644 --- a/README.md +++ b/README.md @@ -295,3 +295,59 @@ The dashboard provides: - **Sudo Password**: The tool will securely prompt for your sudo password interactively during setup. --- + +--- + +## Licensing + +CoreSpan AI's source in this repository is licensed **Apache-2.0** — see +[`LICENSE`](LICENSE) and [`NOTICE`](NOTICE). + +Apache-2.0 Section 6 grants no trademark rights. "CoreSpan" and the CoreSpan +logo are trademarks of CoreSpan AI. + +### Third-party attribution + +Go statically links its dependencies, so a released `ai-studio-cli` binary +contains compiled copies of every module it builds against, plus the web UI +assets embedded via `go:embed`. Distributing the binary distributes all of it, +and MIT, BSD-3 and Apache-2.0 all require the copyright notice to travel with a +distributed copy. + +Unlike an interpreted project there is no `node_modules` or `site-packages` +beside the artifact for those notices to live in — the binary is the whole +distribution — so they are compiled into it: + +```bash +ai-studio-cli licenses # everything embedded in this binary +ai-studio-cli licenses cobra # filter to one dependency +``` + +The same text is published as a release asset, so it can be read without +running the binary. + +### What this tool installs but does not distribute + +`ai-studio-cli` provisions NVIDIA drivers, the CUDA userspace, Docker or Podman, +vLLM and container images onto GPU nodes. CoreSpan does not distribute those — +they are downloaded by you, from their publishers, onto your machines, under +their terms. The NVIDIA driver and CUDA EULAs in particular are between you and +NVIDIA. Nothing in our Apache-2.0 grant extends to them. + +### Verifying it yourself + +```bash +make compliance # licence files, no CDN refs in the UI (no network needed) +make notices # generate the third-party notices (needs Go + network) +make build-release # generate notices, build, and verify the binary carries them +make vendor-ui # re-vendor the bench UI fonts and Chart.js +``` + +The notices are **generated, not committed**. A fresh checkout embeds a +placeholder, and `ai-studio-cli licenses` says so rather than printing an empty +page. CI and the release workflow run `make build-release`, which generates them +and fails if the resulting binary cannot print them — so no released binary can +ship without its attribution, and nobody has to remember a regenerate-and-commit +step on every dependency bump. + +See [`.github/workflows/compliance.yml`](.github/workflows/compliance.yml). diff --git a/ai-studio-cli/cmd/licenses.go b/ai-studio-cli/cmd/licenses.go new file mode 100644 index 0000000..ebce59f --- /dev/null +++ b/ai-studio-cli/cmd/licenses.go @@ -0,0 +1,90 @@ +package cmd + +import ( + "fmt" + "os" + "strings" + + "github.com/corespan/ai-studio-cli/internal/notices" + "github.com/spf13/cobra" +) + +// A Go binary statically links every dependency. When we publish a release +// binary we are distributing compiled copies of cobra, viper, pflag and the +// rest — and MIT, BSD-3 and Apache-2.0 all condition redistribution on carrying +// the copyright notice. Unlike a Python or Node project, there is no +// site-packages or node_modules alongside the artifact for those notices to +// live in: the binary is the entire distribution. +// +// So the notices are compiled in too, and this command prints them. It is the +// same approach kubectl, docker and gh take, and it is the only one that +// survives someone copying the binary onto a machine with no network and no +// repository checkout. +var licensesCmd = &cobra.Command{ + Use: "licenses", + Short: "Print third-party licence notices for the software in this binary", + Long: `Print the licences of the open-source software compiled into this binary. + +A Go binary statically links its dependencies, so distributing ai-studio-cli +means distributing copies of that code. The notices below accompany it, as +those licences require. + +The embedded web UI's fonts and Chart.js are covered too — they are compiled in +via go:embed. + +CoreSpan AI's own source is Apache-2.0 and is not covered by these notices. +See https://github.com/corespan/aistudio-cli for the LICENSE and NOTICE files.`, + Args: cobra.MaximumNArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + text := notices.Text() + + if strings.TrimSpace(text) == "" || notices.IsPlaceholder() { + // Better to say so than to print an empty page and let the reader + // conclude this software has no third-party dependencies. + // + // Two different situations produce this, and the message has to + // serve both: a developer's own `make build` (expected, harmless) + // and a released binary (a packaging fault that must not happen, + // and which the release workflow is set up to prevent). + fmt.Fprintln(os.Stderr, + "This binary was built without its third-party licence notices.") + fmt.Fprintln(os.Stderr) + fmt.Fprintln(os.Stderr, + "If you built it yourself, that is expected — the notices are") + fmt.Fprintln(os.Stderr, + "generated rather than committed. Build with them included:") + fmt.Fprintln(os.Stderr) + fmt.Fprintln(os.Stderr, " make build-release") + fmt.Fprintln(os.Stderr) + fmt.Fprintln(os.Stderr, + "If this is a released binary, it is a packaging fault. Please report it:") + fmt.Fprintln(os.Stderr, + "https://github.com/corespan/aistudio-cli/issues") + return fmt.Errorf("licence notices not embedded in this build") + } + + // `licenses ` filters to one dependency. Handy when someone + // only needs to check a single package's terms. + if len(args) == 1 { + needle := strings.ToLower(args[0]) + var matched []string + for _, block := range strings.Split(text, "\n"+strings.Repeat("-", 72)+"\n") { + if strings.Contains(strings.ToLower(block), needle) { + matched = append(matched, strings.TrimSpace(block)) + } + } + if len(matched) == 0 { + return fmt.Errorf("no dependency matching %q is compiled into this binary", args[0]) + } + fmt.Println(strings.Join(matched, "\n\n"+strings.Repeat("-", 72)+"\n\n")) + return nil + } + + fmt.Println(text) + return nil + }, +} + +func init() { + rootCmd.AddCommand(licensesCmd) +} diff --git a/ai-studio-cli/internal/benchui/ui/index.html b/ai-studio-cli/internal/benchui/ui/index.html index 4e81280..9ed100f 100644 --- a/ai-studio-cli/internal/benchui/ui/index.html +++ b/ai-studio-cli/internal/benchui/ui/index.html @@ -6,12 +6,24 @@ Benchmarks — AI Studio - - - - + + + diff --git a/ai-studio-cli/internal/benchui/ui/vendor/NOTICE b/ai-studio-cli/internal/benchui/ui/vendor/NOTICE new file mode 100644 index 0000000..f2f104a --- /dev/null +++ b/ai-studio-cli/internal/benchui/ui/vendor/NOTICE @@ -0,0 +1,31 @@ +Third-party assets embedded in the ai-studio-cli bench UI +========================================================= + +These files are compiled into the ai-studio-cli binary via //go:embed, so +their licence terms travel with every copy of the binary that is distributed. + +Regenerate with: ./scripts/vendor-ui-assets.sh + +Inter + Copyright 2016 The Inter Project Authors (https://github.com/rsms/inter) + SIL Open Font License 1.1 — fonts/LICENSE-Inter-OFL.txt + Packaged via @fontsource/inter@5.3.0 + +JetBrains Mono + Copyright 2020 The JetBrains Mono Project Authors + (https://github.com/JetBrains/JetBrainsMono) + SIL Open Font License 1.1 — fonts/LICENSE-JetBrainsMono-OFL.txt + Packaged via @fontsource/jetbrains-mono@5.3.0 + +Chart.js 4.4.7 + Copyright (c) 2014-2024 Chart.js Contributors + MIT — js/LICENSE-chartjs.md + +OFL-1.1 note: these fonts are redistributed unmodified, under their original +names, and are not sold on their own, which is what OFL section 2 requires. +If a font file is ever subsetted or renamed, re-read sections 3 and 4. + +MIT note: Chart.js previously lived here as a jsdelivr-fetched copy carrying +only a banner comment. A banner names the licence; it is not the licence. MIT +requires "the above copyright notice and this permission notice" to be included, +so the full text is now shipped in js/LICENSE-chartjs.md. diff --git a/ai-studio-cli/internal/benchui/ui/vendor/fonts.css b/ai-studio-cli/internal/benchui/ui/vendor/fonts.css new file mode 100644 index 0000000..85f693a --- /dev/null +++ b/ai-studio-cli/internal/benchui/ui/vendor/fonts.css @@ -0,0 +1,9 @@ +/* Self-hosted web fonts. Generated by scripts/vendor-ui-assets.sh — do not edit. */ +/* Inter — SIL OFL-1.1 — see fonts/LICENSE-Inter-OFL.txt */ +@font-face{font-family:"Inter";font-style:normal;font-display:swap;font-weight:400;src:url("./fonts/inter-latin-400-normal.woff2") format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;} +@font-face{font-family:"Inter";font-style:normal;font-display:swap;font-weight:500;src:url("./fonts/inter-latin-500-normal.woff2") format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;} +@font-face{font-family:"Inter";font-style:normal;font-display:swap;font-weight:600;src:url("./fonts/inter-latin-600-normal.woff2") format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;} +@font-face{font-family:"Inter";font-style:normal;font-display:swap;font-weight:700;src:url("./fonts/inter-latin-700-normal.woff2") format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;} +/* JetBrains Mono — SIL OFL-1.1 — see fonts/LICENSE-JetBrainsMono-OFL.txt */ +@font-face{font-family:"JetBrains Mono";font-style:normal;font-display:swap;font-weight:400;src:url("./fonts/jetbrains-mono-latin-400-normal.woff2") format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;} +@font-face{font-family:"JetBrains Mono";font-style:normal;font-display:swap;font-weight:500;src:url("./fonts/jetbrains-mono-latin-500-normal.woff2") format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;} diff --git a/ai-studio-cli/internal/benchui/ui/vendor/fonts/LICENSE-Inter-OFL.txt b/ai-studio-cli/internal/benchui/ui/vendor/fonts/LICENSE-Inter-OFL.txt new file mode 100644 index 0000000..40589da --- /dev/null +++ b/ai-studio-cli/internal/benchui/ui/vendor/fonts/LICENSE-Inter-OFL.txt @@ -0,0 +1,93 @@ +Copyright 2016 The Inter Project Authors (https://github.com/rsms/inter) Inter-Italic[opsz,wght].ttf: Copyright 2016 The Inter Project Authors (https://github.com/rsms/inter) + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/ai-studio-cli/internal/benchui/ui/vendor/fonts/LICENSE-JetBrainsMono-OFL.txt b/ai-studio-cli/internal/benchui/ui/vendor/fonts/LICENSE-JetBrainsMono-OFL.txt new file mode 100644 index 0000000..8f7ed67 --- /dev/null +++ b/ai-studio-cli/internal/benchui/ui/vendor/fonts/LICENSE-JetBrainsMono-OFL.txt @@ -0,0 +1,93 @@ +Copyright 2020 The JetBrains Mono Project Authors (https://github.com/JetBrains/JetBrainsMono) JetBrainsMono-Italic[wght].ttf: Copyright 2020 The JetBrains Mono Project Authors (https://github.com/JetBrains/JetBrainsMono) + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/ai-studio-cli/internal/benchui/ui/vendor/fonts/inter-latin-400-normal.woff2 b/ai-studio-cli/internal/benchui/ui/vendor/fonts/inter-latin-400-normal.woff2 new file mode 100644 index 0000000..f15b025 Binary files /dev/null and b/ai-studio-cli/internal/benchui/ui/vendor/fonts/inter-latin-400-normal.woff2 differ diff --git a/ai-studio-cli/internal/benchui/ui/vendor/fonts/inter-latin-500-normal.woff2 b/ai-studio-cli/internal/benchui/ui/vendor/fonts/inter-latin-500-normal.woff2 new file mode 100644 index 0000000..54f0a59 Binary files /dev/null and b/ai-studio-cli/internal/benchui/ui/vendor/fonts/inter-latin-500-normal.woff2 differ diff --git a/ai-studio-cli/internal/benchui/ui/vendor/fonts/inter-latin-600-normal.woff2 b/ai-studio-cli/internal/benchui/ui/vendor/fonts/inter-latin-600-normal.woff2 new file mode 100644 index 0000000..d189794 Binary files /dev/null and b/ai-studio-cli/internal/benchui/ui/vendor/fonts/inter-latin-600-normal.woff2 differ diff --git a/ai-studio-cli/internal/benchui/ui/vendor/fonts/inter-latin-700-normal.woff2 b/ai-studio-cli/internal/benchui/ui/vendor/fonts/inter-latin-700-normal.woff2 new file mode 100644 index 0000000..a68fb10 Binary files /dev/null and b/ai-studio-cli/internal/benchui/ui/vendor/fonts/inter-latin-700-normal.woff2 differ diff --git a/ai-studio-cli/internal/benchui/ui/vendor/fonts/jetbrains-mono-latin-400-normal.woff2 b/ai-studio-cli/internal/benchui/ui/vendor/fonts/jetbrains-mono-latin-400-normal.woff2 new file mode 100644 index 0000000..5858873 Binary files /dev/null and b/ai-studio-cli/internal/benchui/ui/vendor/fonts/jetbrains-mono-latin-400-normal.woff2 differ diff --git a/ai-studio-cli/internal/benchui/ui/vendor/fonts/jetbrains-mono-latin-500-normal.woff2 b/ai-studio-cli/internal/benchui/ui/vendor/fonts/jetbrains-mono-latin-500-normal.woff2 new file mode 100644 index 0000000..be878e6 Binary files /dev/null and b/ai-studio-cli/internal/benchui/ui/vendor/fonts/jetbrains-mono-latin-500-normal.woff2 differ diff --git a/ai-studio-cli/internal/benchui/ui/vendor/js/LICENSE-chartjs.md b/ai-studio-cli/internal/benchui/ui/vendor/js/LICENSE-chartjs.md new file mode 100644 index 0000000..f216610 --- /dev/null +++ b/ai-studio-cli/internal/benchui/ui/vendor/js/LICENSE-chartjs.md @@ -0,0 +1,9 @@ +The MIT License (MIT) + +Copyright (c) 2014-2024 Chart.js Contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/ai-studio-cli/internal/benchui/ui/chart.umd.min.js b/ai-studio-cli/internal/benchui/ui/vendor/js/chart.umd.js similarity index 99% rename from ai-studio-cli/internal/benchui/ui/chart.umd.min.js rename to ai-studio-cli/internal/benchui/ui/vendor/js/chart.umd.js index 0bae5b8..d9fd6ec 100644 --- a/ai-studio-cli/internal/benchui/ui/chart.umd.min.js +++ b/ai-studio-cli/internal/benchui/ui/vendor/js/chart.umd.js @@ -1,9 +1,3 @@ -/** - * Skipped minification because the original files appears to be already minified. - * Original file: /npm/chart.js@4.4.7/dist/chart.umd.js - * - * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files - */ /*! * Chart.js v4.4.7 * https://www.chartjs.org diff --git a/ai-studio-cli/internal/notices/THIRD-PARTY-NOTICES.txt b/ai-studio-cli/internal/notices/THIRD-PARTY-NOTICES.txt new file mode 100644 index 0000000..5ff936b --- /dev/null +++ b/ai-studio-cli/internal/notices/THIRD-PARTY-NOTICES.txt @@ -0,0 +1,1395 @@ +ai-studio-cli — third-party licence notices +======================================================================== + +This binary statically links the Go modules listed below, and embeds the +web UI assets noted at the end. Distributing the binary distributes copies +of all of it, so their licences are reproduced here in full. + +CoreSpan AI's own source is Apache-2.0 and is NOT covered by these notices. +See LICENSE and NOTICE at https://github.com/corespan/aistudio-cli + +Generated: 2026-08-03 by scripts/generate-notices.sh +Go: go1.26.3 + +------------------------------------------------------------------------ + +MODULES (17) + + github.com/fsnotify/fsnotify v1.9.0 + github.com/go-viper/mapstructure/v2 v2.4.0 + github.com/inconshreveable/mousetrap v1.1.0 + github.com/pelletier/go-toml/v2 v2.2.4 + github.com/sagikazarmark/locafero v0.11.0 + github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 + github.com/spf13/afero v1.15.0 + github.com/spf13/cast v1.10.0 + github.com/spf13/cobra v1.10.2 + github.com/spf13/pflag v1.0.10 + github.com/spf13/viper v1.21.0 + github.com/subosito/gotenv v1.6.0 + go.yaml.in/yaml/v3 v3.0.4 + golang.org/x/sys v0.35.0 + golang.org/x/term v0.34.0 + golang.org/x/text v0.28.0 + gopkg.in/yaml.v3 v3.0.1 + +------------------------------------------------------------------------ + +github.com/fsnotify/fsnotify@v1.9.0 + + [LICENSE] + + Copyright © 2012 The Go Authors. All rights reserved. + Copyright © fsnotify Authors. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + * Neither the name of Google Inc. nor the names of its contributors may be used + to endorse or promote products derived from this software without specific + prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +------------------------------------------------------------------------ + +github.com/go-viper/mapstructure/v2@v2.4.0 + + [LICENSE] + + The MIT License (MIT) + + Copyright (c) 2013 Mitchell Hashimoto + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + +------------------------------------------------------------------------ + +github.com/inconshreveable/mousetrap@v1.1.0 + + [LICENSE] + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2022 Alan Shreve (@inconshreveable) + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +------------------------------------------------------------------------ + +github.com/pelletier/go-toml/v2@v2.2.4 + + [LICENSE] + + The MIT License (MIT) + + go-toml v2 + Copyright (c) 2021 - 2023 Thomas Pelletier + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +------------------------------------------------------------------------ + +github.com/sagikazarmark/locafero@v0.11.0 + + [LICENSE] + + Copyright (c) 2023 Márk Sági-Kazár + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is furnished + to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + +------------------------------------------------------------------------ + +github.com/sourcegraph/conc@v0.3.1-0.20240121214520-5f936abd7ae8 + + [LICENSE] + + MIT License + + Copyright (c) 2023 Sourcegraph + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +------------------------------------------------------------------------ + +github.com/spf13/afero@v1.15.0 + + [LICENSE.txt] + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +------------------------------------------------------------------------ + +github.com/spf13/cast@v1.10.0 + + [LICENSE] + + The MIT License (MIT) + + Copyright (c) 2014 Steve Francia + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +------------------------------------------------------------------------ + +github.com/spf13/cobra@v1.10.2 + + [LICENSE.txt] + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +------------------------------------------------------------------------ + +github.com/spf13/pflag@v1.0.10 + + [LICENSE] + + Copyright (c) 2012 Alex Ogier. All rights reserved. + Copyright (c) 2012 The Go Authors. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +------------------------------------------------------------------------ + +github.com/spf13/viper@v1.21.0 + + [LICENSE] + + The MIT License (MIT) + + Copyright (c) 2014 Steve Francia + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +------------------------------------------------------------------------ + +github.com/subosito/gotenv@v1.6.0 + + [LICENSE] + + The MIT License (MIT) + + Copyright (c) 2013 Alif Rachmawadi + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + +------------------------------------------------------------------------ + +go.yaml.in/yaml/v3@v3.0.4 + + [LICENSE] + + + This project is covered by two different licenses: MIT and Apache. + + #### MIT License #### + + The following files were ported to Go from C files of libyaml, and thus + are still covered by their original MIT license, with the additional + copyright staring in 2011 when the project was ported over: + + apic.go emitterc.go parserc.go readerc.go scannerc.go + writerc.go yamlh.go yamlprivateh.go + + Copyright (c) 2006-2010 Kirill Simonov + Copyright (c) 2006-2011 Kirill Simonov + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do + so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + ### Apache License ### + + All the remaining project files are covered by the Apache license: + + Copyright (c) 2011-2019 Canonical Ltd + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + [NOTICE] + + Copyright 2011-2016 Canonical Ltd. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +------------------------------------------------------------------------ + +golang.org/x/sys@v0.35.0 + + [LICENSE] + + Copyright 2009 The Go Authors. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + * Neither the name of Google LLC nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +------------------------------------------------------------------------ + +golang.org/x/term@v0.34.0 + + [LICENSE] + + Copyright 2009 The Go Authors. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + * Neither the name of Google LLC nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +------------------------------------------------------------------------ + +golang.org/x/text@v0.28.0 + + [LICENSE] + + Copyright 2009 The Go Authors. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + * Neither the name of Google LLC nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +------------------------------------------------------------------------ + +gopkg.in/yaml.v3@v3.0.1 + + [LICENSE] + + + This project is covered by two different licenses: MIT and Apache. + + #### MIT License #### + + The following files were ported to Go from C files of libyaml, and thus + are still covered by their original MIT license, with the additional + copyright staring in 2011 when the project was ported over: + + apic.go emitterc.go parserc.go readerc.go scannerc.go + writerc.go yamlh.go yamlprivateh.go + + Copyright (c) 2006-2010 Kirill Simonov + Copyright (c) 2006-2011 Kirill Simonov + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do + so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + ### Apache License ### + + All the remaining project files are covered by the Apache license: + + Copyright (c) 2011-2019 Canonical Ltd + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + [NOTICE] + + Copyright 2011-2016 Canonical Ltd. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +------------------------------------------------------------------------ + +The Go standard library + + [LICENSE] + + Copyright 2009 The Go Authors. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + * Neither the name of Google LLC nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +------------------------------------------------------------------------ + +EMBEDDED WEB UI ASSETS + + Third-party assets embedded in the ai-studio-cli bench UI + ========================================================= + + These files are compiled into the ai-studio-cli binary via //go:embed, so + their licence terms travel with every copy of the binary that is distributed. + + Regenerate with: ./scripts/vendor-ui-assets.sh + + Inter + Copyright 2016 The Inter Project Authors (https://github.com/rsms/inter) + SIL Open Font License 1.1 — fonts/LICENSE-Inter-OFL.txt + Packaged via @fontsource/inter@5.3.0 + + JetBrains Mono + Copyright 2020 The JetBrains Mono Project Authors + (https://github.com/JetBrains/JetBrainsMono) + SIL Open Font License 1.1 — fonts/LICENSE-JetBrainsMono-OFL.txt + Packaged via @fontsource/jetbrains-mono@5.3.0 + + Chart.js 4.4.7 + Copyright (c) 2014-2024 Chart.js Contributors + MIT — js/LICENSE-chartjs.md + + OFL-1.1 note: these fonts are redistributed unmodified, under their original + names, and are not sold on their own, which is what OFL section 2 requires. + If a font file is ever subsetted or renamed, re-read sections 3 and 4. + + MIT note: Chart.js previously lived here as a jsdelivr-fetched copy carrying + only a banner comment. A banner names the licence; it is not the licence. MIT + requires "the above copyright notice and this permission notice" to be included, + so the full text is now shipped in js/LICENSE-chartjs.md. + +------------------------------------------------------------------------ + +LICENSE-Inter-OFL.txt + + Copyright 2016 The Inter Project Authors (https://github.com/rsms/inter) Inter-Italic[opsz,wght].ttf: Copyright 2016 The Inter Project Authors (https://github.com/rsms/inter) + + This Font Software is licensed under the SIL Open Font License, Version 1.1. + This license is copied below, and is also available with a FAQ at: + http://scripts.sil.org/OFL + + + ----------------------------------------------------------- + SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 + ----------------------------------------------------------- + + PREAMBLE + The goals of the Open Font License (OFL) are to stimulate worldwide + development of collaborative font projects, to support the font creation + efforts of academic and linguistic communities, and to provide a free and + open framework in which fonts may be shared and improved in partnership + with others. + + The OFL allows the licensed fonts to be used, studied, modified and + redistributed freely as long as they are not sold by themselves. The + fonts, including any derivative works, can be bundled, embedded, + redistributed and/or sold with any software provided that any reserved + names are not used by derivative works. The fonts and derivatives, + however, cannot be released under any other type of license. The + requirement for fonts to remain under this license does not apply + to any document created using the fonts or their derivatives. + + DEFINITIONS + "Font Software" refers to the set of files released by the Copyright + Holder(s) under this license and clearly marked as such. This may + include source files, build scripts and documentation. + + "Reserved Font Name" refers to any names specified as such after the + copyright statement(s). + + "Original Version" refers to the collection of Font Software components as + distributed by the Copyright Holder(s). + + "Modified Version" refers to any derivative made by adding to, deleting, + or substituting -- in part or in whole -- any of the components of the + Original Version, by changing formats or by porting the Font Software to a + new environment. + + "Author" refers to any designer, engineer, programmer, technical + writer or other person who contributed to the Font Software. + + PERMISSION & CONDITIONS + Permission is hereby granted, free of charge, to any person obtaining + a copy of the Font Software, to use, study, copy, merge, embed, modify, + redistribute, and sell modified and unmodified copies of the Font + Software, subject to the following conditions: + + 1) Neither the Font Software nor any of its individual components, + in Original or Modified Versions, may be sold by itself. + + 2) Original or Modified Versions of the Font Software may be bundled, + redistributed and/or sold with any software, provided that each copy + contains the above copyright notice and this license. These can be + included either as stand-alone text files, human-readable headers or + in the appropriate machine-readable metadata fields within text or + binary files as long as those fields can be easily viewed by the user. + + 3) No Modified Version of the Font Software may use the Reserved Font + Name(s) unless explicit written permission is granted by the corresponding + Copyright Holder. This restriction only applies to the primary font name as + presented to the users. + + 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font + Software shall not be used to promote, endorse or advertise any + Modified Version, except to acknowledge the contribution(s) of the + Copyright Holder(s) and the Author(s) or with their explicit written + permission. + + 5) The Font Software, modified or unmodified, in part or in whole, + must be distributed entirely under this license, and must not be + distributed under any other license. The requirement for fonts to + remain under this license does not apply to any document created + using the Font Software. + + TERMINATION + This license becomes null and void if any of the above conditions are + not met. + + DISCLAIMER + THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT + OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE + COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL + DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM + OTHER DEALINGS IN THE FONT SOFTWARE. + +------------------------------------------------------------------------ + +LICENSE-JetBrainsMono-OFL.txt + + Copyright 2020 The JetBrains Mono Project Authors (https://github.com/JetBrains/JetBrainsMono) JetBrainsMono-Italic[wght].ttf: Copyright 2020 The JetBrains Mono Project Authors (https://github.com/JetBrains/JetBrainsMono) + + This Font Software is licensed under the SIL Open Font License, Version 1.1. + This license is copied below, and is also available with a FAQ at: + http://scripts.sil.org/OFL + + + ----------------------------------------------------------- + SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 + ----------------------------------------------------------- + + PREAMBLE + The goals of the Open Font License (OFL) are to stimulate worldwide + development of collaborative font projects, to support the font creation + efforts of academic and linguistic communities, and to provide a free and + open framework in which fonts may be shared and improved in partnership + with others. + + The OFL allows the licensed fonts to be used, studied, modified and + redistributed freely as long as they are not sold by themselves. The + fonts, including any derivative works, can be bundled, embedded, + redistributed and/or sold with any software provided that any reserved + names are not used by derivative works. The fonts and derivatives, + however, cannot be released under any other type of license. The + requirement for fonts to remain under this license does not apply + to any document created using the fonts or their derivatives. + + DEFINITIONS + "Font Software" refers to the set of files released by the Copyright + Holder(s) under this license and clearly marked as such. This may + include source files, build scripts and documentation. + + "Reserved Font Name" refers to any names specified as such after the + copyright statement(s). + + "Original Version" refers to the collection of Font Software components as + distributed by the Copyright Holder(s). + + "Modified Version" refers to any derivative made by adding to, deleting, + or substituting -- in part or in whole -- any of the components of the + Original Version, by changing formats or by porting the Font Software to a + new environment. + + "Author" refers to any designer, engineer, programmer, technical + writer or other person who contributed to the Font Software. + + PERMISSION & CONDITIONS + Permission is hereby granted, free of charge, to any person obtaining + a copy of the Font Software, to use, study, copy, merge, embed, modify, + redistribute, and sell modified and unmodified copies of the Font + Software, subject to the following conditions: + + 1) Neither the Font Software nor any of its individual components, + in Original or Modified Versions, may be sold by itself. + + 2) Original or Modified Versions of the Font Software may be bundled, + redistributed and/or sold with any software, provided that each copy + contains the above copyright notice and this license. These can be + included either as stand-alone text files, human-readable headers or + in the appropriate machine-readable metadata fields within text or + binary files as long as those fields can be easily viewed by the user. + + 3) No Modified Version of the Font Software may use the Reserved Font + Name(s) unless explicit written permission is granted by the corresponding + Copyright Holder. This restriction only applies to the primary font name as + presented to the users. + + 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font + Software shall not be used to promote, endorse or advertise any + Modified Version, except to acknowledge the contribution(s) of the + Copyright Holder(s) and the Author(s) or with their explicit written + permission. + + 5) The Font Software, modified or unmodified, in part or in whole, + must be distributed entirely under this license, and must not be + distributed under any other license. The requirement for fonts to + remain under this license does not apply to any document created + using the Font Software. + + TERMINATION + This license becomes null and void if any of the above conditions are + not met. + + DISCLAIMER + THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT + OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE + COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL + DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM + OTHER DEALINGS IN THE FONT SOFTWARE. + +------------------------------------------------------------------------ + +LICENSE-chartjs.md + + The MIT License (MIT) + + Copyright (c) 2014-2024 Chart.js Contributors + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +------------------------------------------------------------------------ + diff --git a/ai-studio-cli/internal/notices/notices.go b/ai-studio-cli/internal/notices/notices.go new file mode 100644 index 0000000..1ad64cc --- /dev/null +++ b/ai-studio-cli/internal/notices/notices.go @@ -0,0 +1,38 @@ +// Package notices carries the third-party licence text compiled into the +// binary. +// +// The content of THIRD-PARTY-NOTICES.txt is generated by `make notices`, which +// runs go-licenses over the real module graph. It is committed rather than +// produced at build time because `go build` and `go install` must work from a +// plain checkout with no extra tooling — and because go:embed requires the file +// to exist in the source tree at compile time. +// +// Keeping it in its own package rather than in cmd/ means `go build` fails +// loudly if the file is ever deleted, instead of silently producing a binary +// that ships no attribution. +package notices + +import ( + _ "embed" + "strings" +) + +//go:embed THIRD-PARTY-NOTICES.txt +var embedded string + +// placeholderMarker appears in the committed stub and is removed by the +// generator. Its presence means a real inventory was never generated for this +// build, which the `licenses` command reports rather than printing an empty +// document that reads like "no dependencies". +const placeholderMarker = "NOTICES-NOT-GENERATED" + +// Text returns the embedded third-party licence notices. +func Text() string { + return embedded +} + +// IsPlaceholder reports whether this binary was built without a generated +// inventory. Release builds must never return true; CI enforces that. +func IsPlaceholder() bool { + return strings.Contains(embedded, placeholderMarker) +} diff --git a/docs/LICENCE-REVIEW-RESPONSE.md b/docs/LICENCE-REVIEW-RESPONSE.md new file mode 100644 index 0000000..ef60dfc --- /dev/null +++ b/docs/LICENCE-REVIEW-RESPONSE.md @@ -0,0 +1,397 @@ +# Licence review — corespan/aistudio-cli + +**Repo:** `corespan/aistudio-cli` +**Reviewed:** 2 August 2026 +**Author:** ManojDev +**Context:** third in the series, after the 31 July review of `aistudio-server` +and the 2 August audit of `aistudio-app`. + +--- + +## Summary + +Seven findings. Two blockers, two high, two medium, one low. + +**This is the strictest distribution model of the three.** `aistudio-server` +conveys container images and the review had to argue about whether we ship +prebuilt artifacts. `aistudio-app` serves a JS bundle. This ships a **compiled +Go binary that statically links every dependency**. + +That distinction is the whole story. There is no `node_modules`, no +`site-packages`, no image layer beside the artifact for third-party notices to +live in. The binary *is* the distribution. If the notices are not inside it, +they are not accompanying anything — and they were not. + +| | Count | Findings | +| --- | --- | --- | +| ✅ Fixed | 6 | C1, C2, C3, C4, C5, C6 | +| 🔵 Open — product decision | 1 | C7 | + +### A correction to the first version of this fix + +The first attempt treated the generated licence inventory as a **committed** +artifact, with a CI job diffing the committed copy against a fresh +`go-licenses` run. Three CI jobs went red, and the diagnosis was more +interesting than "unfinished work": the design was wrong. + +- The environment this work was done in cannot reach `proxy.golang.org`, + `go.dev` or GitHub — only the npm registry. So the inventory could not be + generated, and a *reviewable branch could not exist* without a Go toolchain + and network access. That is a bad property for a compliance artifact. +- Worse, it put a regenerate-and-commit step on the critical path of **every + dependency bump**, whose only failure mode is a red build with a message that + reads like a mistake rather than a routine step. + +The obligation is narrower than the design assumed. Nothing requires the +inventory to live in git. What must be true is that **no released binary ships +without its notices**. So generation now happens where the network is — in CI +and in the release flow — and `make build-release` is the gate: it generates, +builds, and fails if the resulting binary cannot print them. + +A fresh checkout embeds a placeholder, and `ai-studio-cli licenses` says so +plainly instead of printing an empty page that reads like "no dependencies". +`make compliance` reports it as the normal state rather than an error, so the +static checks run anywhere with no toolchain. + +I deliberately did not hand-write the inventory to paper over the gap. I know +roughly what cobra and viper are licensed under, but writing licence facts I +could not verify into a compliance document is precisely what makes such +documents worthless. + +--- + +## C1. A statically linked binary that carries no attribution + +**Blocker · Licence · largest exposure** + +**Technical.** `go build` links every module in the build graph into a single +executable. Releases publish that executable. The graph includes cobra +(Apache-2.0), viper, pflag, fsnotify, afero, cast, mapstructure, go-toml, +locafero, conc, gotenv, mousetrap, `golang.org/x/{term,sys,text}` and +`yaml.v3` — a mix of MIT, BSD-3 and Apache-2.0, all of which condition +redistribution on carrying the copyright notice. Apache-2.0 §4(d) additionally +requires reproducing any NOTICE file. + +There was no inventory, no notices, and no way for a recipient of the binary to +discover what was in it. + +**Plain.** When you hand someone the `ai-studio-cli` binary you are handing +them a dozen other projects' code, welded into one file. Their licences all say +the same easy thing: keep our name on it. Nothing did. + +**Fix.** The idiomatic Go answer, and the one kubectl, docker and gh all use — +compile the notices in and add a subcommand: + +``` +ai-studio-cli licenses # everything embedded in this binary +ai-studio-cli licenses cobra # filter to one dependency +``` + +- `internal/notices` holds the text, embedded with `go:embed`. Its own package, + so `go build` fails loudly if the file is deleted rather than silently + producing an unattributed binary. +- `scripts/generate-notices.sh` runs `go-licenses` over the **real build + graph** — only what is actually linked, not everything in `go.sum`, which + also lists test and tooling modules that never reach a user. +- The script appends the embedded web UI's notices too. Those are not Go + modules, so `go-licenses` cannot see them, but they are equally compiled in. +- The release workflow publishes the same text as a release asset, so it can be + read without running the binary, and puts `LICENSE`, `NOTICE` and the notices + inside the tarball alongside the executable. + +This survives the case that matters: someone copies the binary onto an isolated +GPU node with no network and no checkout. The notices go with it. + +**Generated, not committed.** See the correction in the summary. `make notices` +runs in CI and in the release flow, where the network is; `make build-release` +generates, builds and fails if the binary cannot print its notices. A fresh +checkout carries a placeholder, which `ai-studio-cli licenses` reports rather +than printing an empty page. + +Nothing needs to be remembered on a dependency bump: the next CI run regenerates +against the new module graph automatically. The guard that matters — a release +never shipping without attribution — sits in the release workflow, which is the +only place it can actually be enforced. + +--- + +## C2. Bench UI loads fonts from Google + +**High · Privacy + Function** + +**Technical.** `internal/benchui/ui/index.html` loaded Inter and JetBrains Mono +from `fonts.googleapis.com`. Same finding as `aistudio-server` #9, but the +consequence is worse here and the irony is sharper: this UI is compiled into the +binary with `go:embed` specifically so it needs no external files — and then +phoned out for fonts on every page load. + +`ai-studio-cli bench-ui` runs **on GPU nodes**, which are routinely air-gapped, +and serves the dashboard on localhost. The CDN reference does not degrade there, +it simply fails. + +The privacy half also applies: LG München I, 3 O 17493/20 (20 Jan 2022) held +that disclosing a visitor's IP to Google via a font request is a GDPR breach +absent consent. Here the disclosed IP is the operator's own machine. + +**Plain.** You embedded the dashboard into the binary so it would work +anywhere, then had it download fonts from Google — which fails on exactly the +isolated machines this tool is built for. + +**Fix.** `scripts/vendor-ui-assets.sh` fetches Inter and JetBrains Mono from +npm, copies their OFL-1.1 licence texts alongside, generates the `@font-face` +CSS, and writes `vendor/NOTICE`. Latin subset, only the four Inter and two +JetBrains weights `index.css` actually references. + +Unlike `aistudio-app`, these binaries **are committed**. `go build` cannot run +npm and `go:embed` needs the files present at compile time — making a working +build depend on a prior npm run would break `go install` for everyone. + +CI regenerates into a scratch directory and diffs, so a hand-edited asset is +caught, and asserts the compiled binary contains no `fonts.googleapis.com` +string. + +--- + +## C3. Vendored Chart.js with a banner instead of a licence + +**High · Licence** + +**Technical.** `internal/benchui/ui/chart.umd.min.js` was a 205 KB copy fetched +from jsdelivr, carrying only: + +``` +/*! + * Chart.js v4.4.7 ... (c) 2024 Chart.js Contributors + * Released under the MIT License + */ +``` + +A banner naming a licence is not the licence. MIT requires *"the above +copyright notice **and this permission notice**"* to be included; the +permission notice — the paragraph granting the rights — was absent. There was +no `LICENSE` file anywhere near it. + +Provenance was also a CDN rather than a package registry, with jsdelivr's own +"Do NOT use SRI with dynamically generated files" warning still embedded in the +header. + +**Plain.** The copy of Chart.js in your repo says "MIT" at the top but doesn't +include the actual licence, which is what MIT asks you to include. + +**Fix.** Replaced with the npm `chart.js@4.4.7` artifact — verified +byte-identical to the vendored copy apart from the jsdelivr banner, so this is +provably the same code from a canonical source — with `LICENSE-chartjs.md` +beside it and an entry in `vendor/NOTICE`. + +--- + +## C4. install.sh: unpinned, unverified, `sudo mv` + +**Blocker · Supply chain** + +**Technical.** The installer resolved `releases/latest` at run time, downloaded +a tarball over curl, and `sudo mv`d the contents into `/usr/local/bin`. No +checksum, no signature, no version pinning, no verification that the tarball +even contained the expected binary. It extracted into `/tmp` under fixed names, +so concurrent runs clobbered each other and failures left files behind. + +This is `aistudio-server` finding 2, but sharper on two counts. That installer +at least pinned a tag; this one installed *whatever is newest at this instant*, +so it could not be used in a reproducible provisioning flow — which is what +this tool is for. And the payload here goes into `/usr/local/bin` with sudo, +rather than into a docker-compose directory. + +**Plain.** `curl | sudo` with nothing checked. Anything that could interfere +with the download — a compromised release asset, a proxy, a bad redirect — +resulted in an unverified binary being installed with root privileges. And two +people running the same command a week apart got different software with no way +to tell. + +**Fix.** + +- Accepts a version: `./install.sh v1.2.3`. Defaults to latest, but resolves it + once, prints it, and tells you how to pin it. +- Downloads and verifies `SHA256SUMS`; a mismatch aborts with a report link. + Checks a detached GPG signature when present. +- Private `mktemp -d` with a cleanup trap. +- Confirms the tarball actually contains the binary before installing. +- Skips sudo entirely when `$INSTALL_DIR` is writable, and says so when it does + need it. +- `set -euo pipefail` instead of bare `set -e`. + +The missing-checksum path is a warning rather than a hard failure only because +existing releases predate `SHA256SUMS`. Once every supported release publishes +one, make it fatal — there is a comment in the script marking the spot. + +`.github/workflows/release.yml` now produces what the installer expects: +refuses to build from a lightweight tag, gates on compliance, verifies the +built binary prints real notices before publishing, and attaches +`SHA256SUMS` plus the notices as assets. + +--- + +## C5. LICENSE copyright placeholder never filled in + +**Medium · Licence** + +**Technical.** `LICENSE` is the complete Apache-2.0 text (11,558 bytes), so +detection and scanning work — unlike `aistudio-server` finding 1. But the +appendix still read `Copyright [yyyy] [name of copyright owner]`, the template +text meant to be replaced. Identical to `aistudio-app` finding A2. + +The file is CRLF-encoded, which is why the obvious `sed` fixes elsewhere in this +series did not apply; the replacement preserves the existing line endings rather +than reformatting the licence text and burying the one-line change in a +whole-file diff. + +**Fix.** `Copyright 2026 CoreSpan AI`. `NOTICE` added, covering the copyright, +the embedded third-party software, the trademark statement, and — specific to +this repo — a section distinguishing what the CLI *distributes* from what it +merely *installs on your behalf*. See C6. + +`make compliance` fails if the placeholder returns. + +--- + +## C6. No statement distinguishing distributed from installed software + +**Medium · Licence · specific to this repo** + +**Technical.** `ai-studio-cli` provisions NVIDIA drivers and the CUDA userspace, +Docker or Podman, vLLM, and pulls container images at run time +(`internal/provision/assets/driversInstallation.sh`, +`installVllmDeps.sh`, `cmd/vllm.go`). Nothing said whose terms govern that. + +The distinction matters and cuts in our favour, which is exactly why it should +be written down. CoreSpan does not convey any of it: the operator downloads it, +from the publisher, onto their own machine. The NVIDIA CUDA EULA question that +is the largest open item for `aistudio-server` — where we *do* build and +distribute images containing CUDA — **does not arise here**, because this tool +only automates the operator fetching it themselves. + +Absent a statement, a reader could reasonably assume our Apache-2.0 grant +extends to the drivers the tool installs. It does not, and neither does any +warranty. + +**Fix.** A dedicated section in `NOTICE` and in the README's Licensing section, +stating plainly what is distributed, what is merely installed, and that +accepting the NVIDIA terms is between the operator and NVIDIA. + +--- + +## C7. "AI Studio" name collision + +**Low · Branding — unchanged across all three repos** + +Same as `aistudio-server` #10 and `aistudio-app` A6. Apache-2.0 §6 grants no +trademark rights; "AI Studio" collides with Google AI Studio and Azure AI +Studio. + +One consideration this repo adds: the binary name `ai-studio-cli` is what +appears in `/usr/local/bin`, in shell history, in provisioning scripts and in +customer runbooks. Of the three surfaces, this is the one with the most +inertia — renaming a deployed CLI means every operator's muscle memory and +every automation script that references it. If a rename is coming, it is +cheapest here first, not last. + +Trademark statement added to `NOTICE`. Clearance search still the suggested +next step. + +--- + +## What did not apply + +| Server finding | Status here | +| --- | --- | +| 1 — LICENSE not the Apache text | Not applicable; text is complete (C5 is the placeholder only). | +| 3 — "open source" vs private gate | Not applicable. No gated registry; the CLI pulls public images and public drivers. | +| 5 — model licences | Not applicable directly. The CLI runs vLLM against models the operator supplies; C6 covers the general statement. | +| 6 — container image inventory | **Does not arise.** We build no images here. The CUDA EULA question that blocks aistudio-server has no counterpart. | +| 7 — unpinned dependencies | **Already satisfied.** `go.sum` pins every module by cryptographic hash — a stronger guarantee than either of the other two repos had. `go.mod` also pins the toolchain at 1.25.0. Nothing to fix. | +| 8 — repo dependency inventory | Superseded by C1, which is the same obligation but harder, because the artifact is a linked binary rather than a source tree the user builds. | + +--- + +## What CI now enforces + +| Check | Catches | +| --- | --- | +| LICENSE complete, no placeholder copyright | C5 recurring | +| NOTICE, vendor NOTICE, embedded notices present | C1, C2, C3 | +| Embedded notices are not the placeholder | C1 — a binary shipping no attribution | +| `make build-release` — generates notices, builds, fails if the binary cannot print them | C1: a release shipping no attribution | +| **Built binary**: `licenses` prints 10+ notices, incl. OFL and Chart.js | C1, C2, C3 — the check that actually matters | +| **Compiled binary** contains no `fonts.googleapis.com` string | C2, asserted against the artifact not the source | +| No `src=`/`href=`/`url()` absolute URLs in the bench UI | C2 creeping back | +| Vendored assets reproduce from a clean run | Hand-edited binaries | +| Every font `fonts.css` references exists | A weight shipping as a rule with no file | +| Release: tag must be annotated; compliance gate before publish | C4 | + +The two build-output checks are the substantive ones. Everything else confirms +files exist in a repository; only those confirm the notices are inside the +artifact a user receives. + +--- + +## Open items + +| # | Item | Owner | +| --- | --- | --- | +| C4 | Cut a release through the new workflow so `SHA256SUMS` exists; then make the missing-checksum branch fatal in install.sh | Engineering | +| C4 | Generate a CoreSpan signing key and sign `SHA256SUMS` | Engineering | +| C7 | Trademark clearance on "AI Studio" — cheapest to rename here first | Product + Counsel | +| — | Mixed line endings: 9 of 33 tracked files are CRLF, including `.go` files, which `gofmt` will fight. Worth one normalisation commit of its own. | Engineering | + +--- + +## Files added or changed + +**Added** + +``` +NOTICE Copyright, embedded software, installed-vs-distributed, trademarks +.gitattributes Scoped LF rules; binary assets protected +Makefile build/test/vet plus notices, vendor-ui, compliance +docs/LICENCE-REVIEW-RESPONSE.md This document +.github/workflows/compliance.yml CI enforcement +.github/workflows/release.yml Signed, checksummed, notice-gated releases +scripts/generate-notices.sh go-licenses over the real build graph +scripts/vendor-ui-assets.sh Fonts + Chart.js with licences +ai-studio-cli/cmd/licenses.go `ai-studio-cli licenses` +ai-studio-cli/internal/notices/notices.go go:embed carrier +ai-studio-cli/internal/notices/THIRD-PARTY-NOTICES.txt Placeholder — run `make notices` +ai-studio-cli/internal/benchui/ui/vendor/ Fonts, Chart.js, licences, NOTICE +``` + +**Changed** + +``` +LICENSE Copyright placeholder → CoreSpan AI (CRLF preserved) +README.md Licensing section +install.sh Version pinning, checksum + signature, private tmp, no blind sudo +ai-studio-cli/internal/benchui/ui/index.html Google Fonts + local chart.umd.min.js → vendor/ +``` + +**Removed** + +``` +ai-studio-cli/internal/benchui/ui/chart.umd.min.js jsdelivr copy, replaced by vendor/js/chart.umd.js + licence +``` + +--- + +## Across the three repos + +Same underlying obligation, three different answers, because the artifact +differs each time: + +| | Artifact | Where notices must live | +| --- | --- | --- | +| `aistudio-server` | Container images + source | SBOM per image; `THIRD-PARTY-NOTICES.md` in repo | +| `aistudio-app` | JS bundle served to browsers | `third-party-licences.txt` served with the app, linked from the footer | +| `aistudio-cli` | Statically linked binary | Compiled into the binary; `ai-studio-cli licenses` | + +The recurring lesson is that "we have a LICENSE file" answers a different +question from "does the attribution reach the person receiving the software". +In all three cases the second answer was no, and in all three the fix was to +put the notices where the artifact goes rather than where the source lives. diff --git a/install.sh b/install.sh old mode 100644 new mode 100755 index 07cf2b9..aac2cfa --- a/install.sh +++ b/install.sh @@ -1,23 +1,112 @@ #!/bin/bash -set -e +# ============================================================================= +# ai-studio-cli installer +# ============================================================================= +# +# Usage: +# ./install.sh # install the latest release +# ./install.sh v1.2.3 # install a specific version +# VERSION=v1.2.3 ./install.sh # same, via environment +# +# What changed and why +# -------------------- +# The previous version resolved "latest" at run time, downloaded a tarball over +# plain curl, and `sudo mv`d the contents into /usr/local/bin with no +# verification of any kind. Three separate problems: +# +# Unpinned Two people running the same command a week apart got different +# binaries, and neither could say which. A script that installs +# "whatever is newest" cannot be used in a reproducible +# provisioning flow, which is what this tool is for. +# +# Unverified No checksum, no signature. Anything that could tamper with the +# download — a compromised release asset, a proxy, a redirect — +# ended up as an unverified binary in /usr/local/bin, with sudo. +# +# Untidy Extracted into /tmp with fixed names, so two concurrent runs +# clobbered each other, and a failure left files behind. +# +# It now pins a version (defaulting to latest, resolved once and reported), +# verifies a published SHA256SUMS, uses a private temp directory, and says what +# it is installing before asking for privilege. +# ============================================================================= + +set -euo pipefail REPO="corespan/aistudio-cli" BINARY_NAME="ai-studio-cli" +INSTALL_DIR="${INSTALL_DIR:-/usr/local/bin}" +VERSION="${1:-${VERSION:-}}" + +die() { echo "ERROR: $*" >&2; exit 1; } + +for cmd in curl tar sha256sum; do + command -v "$cmd" >/dev/null 2>&1 || die "'$cmd' is required but not installed." +done + +# ── Resolve the version ─────────────────────────────────────────────────────── +if [ -z "$VERSION" ]; then + echo "Resolving latest release..." + VERSION=$(curl -fsSL "https://api.github.com/repos/${REPO}/releases/latest" \ + | grep '"tag_name"' | head -1 | sed -E 's/.*"([^"]+)".*/\1/') + [ -n "$VERSION" ] || die "could not resolve the latest release tag." + echo "Latest release is ${VERSION}." + echo "For a reproducible install, pin it: ./install.sh ${VERSION}" + echo +fi + +BASE="https://github.com/${REPO}/releases/download/${VERSION}" +TARBALL="${VERSION}.tar.gz" +TMP="$(mktemp -d)" +trap 'rm -rf "$TMP"' EXIT + +echo "Downloading ${TARBALL} ..." +curl -fsSL "${BASE}/${TARBALL}" -o "${TMP}/${TARBALL}" \ + || die "download failed. Does release ${VERSION} exist?" + +# ── Verify ──────────────────────────────────────────────────────────────────── +# The missing-checksum branch is a warning only while older releases predate +# SHA256SUMS. Once every supported release publishes one, make it a hard +# failure — an unverifiable binary going into /usr/local/bin under sudo +# deserves to stop the install. +echo "Verifying checksum ..." +if curl -fsSL "${BASE}/SHA256SUMS" -o "${TMP}/SHA256SUMS" 2>/dev/null; then + ( cd "$TMP" && grep " ${TARBALL}\$" SHA256SUMS | sha256sum -c - ) \ + || die "CHECKSUM MISMATCH for ${TARBALL}. + +The download does not match the published checksum. Do not install it. +Report this at https://github.com/${REPO}/issues" + echo " Checksum OK." -# 1. Get the latest release tag -TAG=$(curl -fsSL "https://api.github.com/repos/${REPO}/releases/latest" | grep '"tag_name"' | head -1 | sed -E 's/.*"([^"]+)".*/\1/') -echo "Latest release: ${TAG}" + if curl -fsSL "${BASE}/SHA256SUMS.asc" -o "${TMP}/SHA256SUMS.asc" 2>/dev/null; then + if command -v gpg >/dev/null 2>&1 \ + && gpg --verify "${TMP}/SHA256SUMS.asc" "${TMP}/SHA256SUMS" 2>/dev/null; then + echo " Signature OK." + else + echo " NOTE: signature present but not verified (signing key not in your keyring)." + fi + fi +else + echo " WARNING: no SHA256SUMS published for ${VERSION} — cannot verify this download." + echo " Continuing; this release predates checksum publishing." +fi -# 2. Download the tarball -TARBALL="${TAG}.tar.gz" -echo "Downloading ${TARBALL}..." -curl -fsSL "https://github.com/${REPO}/releases/download/${TAG}/${TARBALL}" -o "/tmp/${TARBALL}" +# ── Extract ─────────────────────────────────────────────────────────────────── +tar -xzf "${TMP}/${TARBALL}" -C "$TMP" +[ -f "${TMP}/${BINARY_NAME}" ] || die "the tarball does not contain ${BINARY_NAME}." +chmod +x "${TMP}/${BINARY_NAME}" -# 3. Extract and install -tar -xzf "/tmp/${TARBALL}" -C /tmp -chmod +x "/tmp/${BINARY_NAME}" -echo "Installing to /usr/local/bin/..." -sudo mv "/tmp/${BINARY_NAME}" "/usr/local/bin/${BINARY_NAME}" -rm -f "/tmp/${TARBALL}" +# ── Install ─────────────────────────────────────────────────────────────────── +echo +echo "Installing ${BINARY_NAME} ${VERSION} to ${INSTALL_DIR}/" +if [ -w "$INSTALL_DIR" ]; then + mv "${TMP}/${BINARY_NAME}" "${INSTALL_DIR}/${BINARY_NAME}" +else + echo " ${INSTALL_DIR} is not writable — using sudo." + sudo mv "${TMP}/${BINARY_NAME}" "${INSTALL_DIR}/${BINARY_NAME}" +fi -echo "Done. Run: ${BINARY_NAME} --help" +echo +echo "Done. Installed ${BINARY_NAME} ${VERSION}." +echo " Run: ${BINARY_NAME} --help" +echo " Licence notices: ${BINARY_NAME} licenses" diff --git a/scripts/generate-notices.sh b/scripts/generate-notices.sh new file mode 100755 index 0000000..89bab55 --- /dev/null +++ b/scripts/generate-notices.sh @@ -0,0 +1,226 @@ +#!/usr/bin/env bash +# ============================================================================= +# Generate the third-party licence notices compiled into the binary +# ============================================================================= +# +# WHY +# +# A Go binary statically links every dependency. Publishing a release binary +# distributes compiled copies of cobra, viper, pflag, fsnotify and the rest. +# MIT, BSD-3 and Apache-2.0 all condition redistribution on carrying the +# copyright notice, and there is no node_modules or site-packages beside the +# artifact for those notices to live in — the binary IS the distribution. +# +# So the notices go inside it, via go:embed, and `ai-studio-cli licenses` +# prints them. Same approach as kubectl, docker and gh, and the only one that +# survives someone copying the binary to a machine with no network. +# +# HOW — deliberately without go-licenses +# +# The first version of this script shelled out to `go-licenses save`. That added +# a `go install ...@latest` to every CI run (unpinned, and a network dependency +# beyond the module proxy) and go-licenses is known to fail hard on modules +# whose licence it cannot classify — which turns a licence-notice job into a +# licence-classifier argument. +# +# `go list -deps` already answers the only question that matters: which modules +# are actually linked into this binary. The module cache already contains their +# licence files. Reading them directly needs no extra tooling, cannot fail on an +# unrecognised licence, and is a shorter path to the thing the obligation +# actually requires — the verbatim text. +# +# We do not assert SPDX identifiers we cannot derive. The heading for each +# module names the licence FILE as shipped; the text below it governs. +# +# Output: ai-studio-cli/internal/notices/THIRD-PARTY-NOTICES.txt +# +# Usage: ./scripts/generate-notices.sh +# Requires: Go toolchain, and network access on first run to populate the +# module cache (`go mod download`). +# ============================================================================= + +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +MODULE_DIR="$ROOT/ai-studio-cli" +OUT="$MODULE_DIR/internal/notices/THIRD-PARTY-NOTICES.txt" +UI_NOTICE="$MODULE_DIR/internal/benchui/ui/vendor/NOTICE" + +command -v go >/dev/null 2>&1 || { echo "ERROR: Go toolchain not found." >&2; exit 1; } + +WORK="$(mktemp -d)" +trap 'rm -rf "$WORK"' EXIT + +cd "$MODULE_DIR" + +echo "Resolving the linked module graph ..." +# NOT preceded by `go mod download`. +# +# `go mod download` with no arguments resolves the whole build list, which can +# include modules that go.sum has no entry for because they are not needed to +# compile anything. It then fails with "missing go.sum entry" — a job that +# passes `go build` and `go vet` and fails here, which is exactly what happened +# on the first run of this workflow. +# +# `go list -deps` downloads precisely what it needs to resolve the imports of +# the main package, which is the set we want anyway. +# +# -deps walks everything the main package transitively imports — i.e. what ends +# up in the binary. Modules only; the standard library has no .Module and is +# covered by the Go LICENSE, handled separately below. +# +# Run into a file with an explicit status check rather than as the head of a +# pipeline: `set -o pipefail` would surface a go failure as an opaque exit, and +# `sed`/`sort` would happily produce an empty file from an error. +if ! go list -deps \ + -f '{{if .Module}}{{.Module.Path}}|{{.Module.Version}}|{{.Module.Dir}}{{end}}' . \ + > "$WORK/raw.txt" 2> "$WORK/list.err"; then + echo "ERROR: 'go list -deps' failed:" >&2 + cat "$WORK/list.err" >&2 + exit 1 +fi + +# `sed '/^$/d'` rather than `grep -v '^$'`: grep exits 1 when it filters +# everything out, which under pipefail would fail the pipeline. +sed '/^$/d' "$WORK/raw.txt" | sort -u > "$WORK/modules.txt" + +# Drop our own module — its licence is LICENSE/NOTICE in the repo root. +SELF="$(go list -m)" +grep -v "^${SELF}|" "$WORK/modules.txt" > "$WORK/deps.txt" || true + +COUNT=$(wc -l < "$WORK/deps.txt") +[ "$COUNT" -gt 0 ] || { echo "ERROR: resolved no dependencies — refusing to write empty notices." >&2; exit 1; } +echo " $COUNT modules linked into the binary." + +# A module resolved but not present on disk yields an empty .Module.Dir, and +# every licence file for it would then be silently absent. Fail loudly instead: +# quietly attributing nothing is the failure this whole script exists to prevent. +NODIR=$(awk -F'|' '$3 == "" { print " " $1 "@" $2 }' "$WORK/deps.txt") +if [ -n "$NODIR" ]; then + echo "ERROR: these modules resolved with no on-disk directory:" >&2 + echo "$NODIR" >&2 + echo "Their licence files cannot be read. Try 'go mod download '." >&2 + exit 1 +fi + +# Licence filenames as they appear in the wild. +find_licence_files() { + local dir="$1" + [ -d "$dir" ] || return 0 + find "$dir" -maxdepth 1 -type f \ + \( -iname 'LICENSE*' -o -iname 'LICENCE*' -o -iname 'COPYING*' -o -iname 'NOTICE*' \) \ + 2>/dev/null | sort +} + +{ + echo "ai-studio-cli — third-party licence notices" + printf '=%.0s' {1..72}; echo + echo + echo "This binary statically links the Go modules listed below, and embeds the" + echo "web UI assets noted at the end. Distributing the binary distributes copies" + echo "of all of it, so their licences are reproduced here in full." + echo + echo "CoreSpan AI's own source is Apache-2.0 and is NOT covered by these notices." + echo "See LICENSE and NOTICE at https://github.com/corespan/aistudio-cli" + echo + echo "Generated: $(date -u +%Y-%m-%d) by scripts/generate-notices.sh" + echo "Go: $(go version | awk '{print $3}')" + echo + printf -- '-%.0s' {1..72}; echo + echo + echo "MODULES ($COUNT)" + echo + while IFS='|' read -r path version dir; do + [ -n "$path" ] || continue + printf ' %-56s %s\n' "$path" "$version" + done < "$WORK/deps.txt" + echo + printf -- '-%.0s' {1..72}; echo + echo + + MISSING="" + while IFS='|' read -r path version dir; do + [ -n "$path" ] || continue + echo "$path@$version" + echo + + files=$(find_licence_files "$dir") + if [ -z "$files" ]; then + # Recorded rather than skipped. A module with no licence file in its + # distribution is something to notice, not to quietly omit. + echo " No licence file was shipped in this module's distribution." + echo " See https://$path for its terms." + MISSING="$MISSING $path" + else + while read -r f; do + [ -n "$f" ] || continue + echo " [$(basename "$f")]" + echo + sed 's/^/ /' "$f" + echo + done <<< "$files" + fi + printf -- '-%.0s' {1..72}; echo + echo + done < "$WORK/deps.txt" + + # The Go standard library is linked into every Go binary and carries its own + # BSD-3 licence. go list reports no .Module for it, so it needs naming here. + GOROOT_LIC="$(go env GOROOT)/LICENSE" + if [ -f "$GOROOT_LIC" ]; then + echo "The Go standard library" + echo + echo " [LICENSE]" + echo + sed 's/^/ /' "$GOROOT_LIC" + echo + printf -- '-%.0s' {1..72}; echo + echo + fi + + # The go:embed'd UI assets are not Go modules, so nothing above sees them. + if [ -f "$UI_NOTICE" ]; then + echo "EMBEDDED WEB UI ASSETS" + echo + sed 's/^/ /' "$UI_NOTICE" + echo + printf -- '-%.0s' {1..72}; echo + echo + for lf in "$MODULE_DIR"/internal/benchui/ui/vendor/fonts/LICENSE-*.txt \ + "$MODULE_DIR"/internal/benchui/ui/vendor/js/LICENSE-*.md; do + [ -f "$lf" ] || continue + echo "$(basename "$lf")" + echo + sed 's/^/ /' "$lf" + echo + printf -- '-%.0s' {1..72}; echo + echo + done + else + echo "WARNING: $UI_NOTICE not found — run ./scripts/vendor-ui-assets.sh" >&2 + fi + + # if/then, not `[ -n ... ] && echo`. This is the last command in the block, + # and with `set -o pipefail` a false test here makes the whole pipeline fail — + # so the script would abort precisely when nothing was wrong. + if [ -n "$MISSING" ]; then + echo "Modules shipping no licence file:$MISSING" >&2 + fi +} | sed 's/[[:space:]]*$//' > "$WORK/notices.txt" + +# Never overwrite good notices with something degenerate. +if grep -q "NOTICES-NOT-GENERATED" "$WORK/notices.txt"; then + echo "ERROR: generated output still contains the placeholder marker." >&2 + exit 1 +fi +LINES=$(wc -l < "$WORK/notices.txt") +if [ "$LINES" -lt 50 ]; then + echo "ERROR: generated output is only $LINES lines — refusing to write it." >&2 + exit 1 +fi + +cp "$WORK/notices.txt" "$OUT" +echo +echo "Wrote $OUT" +echo " $(wc -c < "$OUT") bytes, $LINES lines, $(grep -ci copyright "$OUT") copyright lines" +echo "Verify with: cd $MODULE_DIR && go run . licenses | head -40" diff --git a/scripts/vendor-ui-assets.sh b/scripts/vendor-ui-assets.sh new file mode 100755 index 0000000..9a7bbae --- /dev/null +++ b/scripts/vendor-ui-assets.sh @@ -0,0 +1,165 @@ +#!/usr/bin/env bash +# ============================================================================= +# Vendor the bench UI's frontend assets into internal/benchui/ui/vendor/ +# ============================================================================= +# +# The bench UI is compiled into the binary by `//go:embed ui/*`. It must make +# zero network requests at page load. Two independent reasons: +# +# Air-gap This is the point. `ai-studio-cli bench-ui` runs on GPU nodes, +# which are routinely isolated, and serves the dashboard on +# localhost. A Google Fonts there is not a slow load — it is +# a dashboard that renders in fallback fonts on the exact machines +# this tool exists to benchmark. Embedding the UI in the binary and +# then having it phone out for fonts defeats the embedding. +# +# Privacy Requesting fonts from fonts.googleapis.com discloses the +# operator's IP to a third party. LG München I, 3 O 17493/20 +# (20 Jan 2022) held that to be a GDPR breach absent consent. +# +# Self-hosting the fonts creates an SIL OFL-1.1 obligation to ship the copyright +# and licence with them. Handled here: the LICENSE files are copied alongside +# the .woff2 files and summarised in vendor/NOTICE. +# +# WHY THESE BINARIES ARE COMMITTED +# +# Unlike aistudio-app, where the vendored assets are gitignored and fetched at +# setup time, these are committed. `go build` does not run npm, and `go:embed` +# requires the files to exist in the source tree at compile time. Anyone with a +# Go toolchain and a checkout must be able to produce a working binary. Making +# that depend on a prior npm run would break `go install`. +# +# Usage: +# ./scripts/vendor-ui-assets.sh # re-fetch and regenerate +# VENDOR_DEST=/tmp/check ./scripts/... # CI: regenerate elsewhere and diff +# +# Requires: npm +# ============================================================================= + +set -euo pipefail + +# Exact versions. A floating major would ship different .woff2 bytes and fail +# CI's reproducibility diff on an unrelated PR. +INTER_VERSION="5.3.0" +JETBRAINS_VERSION="5.3.0" + +# Must match the version the UI was written against. The previously vendored +# copy came from jsdelivr and was byte-identical to npm's dist/chart.umd.js for +# this version, plus a CDN banner. +CHARTJS_VERSION="4.4.7" + +# Weights actually referenced by index.css (--font-sans, --font-mono). +# Every extra weight is ~25 KB compiled into the binary for nothing. +INTER_WEIGHTS=(400 500 600 700) +JETBRAINS_WEIGHTS=(400 500) + +SUBSET="latin" + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +UI="$ROOT/ai-studio-cli/internal/benchui/ui" +DEST="${VENDOR_DEST:-$UI/vendor}" + +if ! command -v npm >/dev/null 2>&1; then + echo "ERROR: npm is required to vendor UI assets." >&2 + echo " These files are committed, so this is only needed when updating them." >&2 + exit 1 +fi + +WORK="$(mktemp -d)" +BUILD="$WORK/stage" +trap 'rm -rf "$WORK"' EXIT + +echo "Fetching packages ..." +cd "$WORK" +npm init -y >/dev/null 2>&1 +npm install --no-audit --no-fund --silent \ + "@fontsource/inter@${INTER_VERSION}" \ + "@fontsource/jetbrains-mono@${JETBRAINS_VERSION}" \ + "chart.js@${CHARTJS_VERSION}" + +MODULES="$WORK/node_modules" + +# Stage then swap, so a failure partway through cannot leave the embedded UI +# half-populated — `go:embed` would then compile a broken dashboard into the +# binary with no error. +mkdir -p "$BUILD/fonts" "$BUILD/js" + +echo "Copying fonts ..." +for w in "${INTER_WEIGHTS[@]}"; do + cp "$MODULES/@fontsource/inter/files/inter-${SUBSET}-${w}-normal.woff2" "$BUILD/fonts/" +done +for w in "${JETBRAINS_WEIGHTS[@]}"; do + cp "$MODULES/@fontsource/jetbrains-mono/files/jetbrains-mono-${SUBSET}-${w}-normal.woff2" "$BUILD/fonts/" +done + +echo "Copying licences ..." +cp "$MODULES/@fontsource/inter/LICENSE" "$BUILD/fonts/LICENSE-Inter-OFL.txt" +cp "$MODULES/@fontsource/jetbrains-mono/LICENSE" "$BUILD/fonts/LICENSE-JetBrainsMono-OFL.txt" +cp "$MODULES/chart.js/LICENSE.md" "$BUILD/js/LICENSE-chartjs.md" + +echo "Copying Chart.js ..." +# dist/chart.umd.js is already minified upstream; this is the same artifact the +# previous jsdelivr copy carried, minus the CDN banner. +cp "$MODULES/chart.js/dist/chart.umd.js" "$BUILD/js/chart.umd.js" + +RANGE='U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD' + +echo "Generating fonts.css ..." +{ + echo "/* Self-hosted web fonts. Generated by scripts/vendor-ui-assets.sh — do not edit. */" + echo "/* Inter — SIL OFL-1.1 — see fonts/LICENSE-Inter-OFL.txt */" + for w in "${INTER_WEIGHTS[@]}"; do + printf '@font-face{font-family:"Inter";font-style:normal;font-display:swap;font-weight:%s;src:url("./fonts/inter-%s-%s-normal.woff2") format("woff2");unicode-range:%s;}\n' \ + "$w" "$SUBSET" "$w" "$RANGE" + done + echo "/* JetBrains Mono — SIL OFL-1.1 — see fonts/LICENSE-JetBrainsMono-OFL.txt */" + for w in "${JETBRAINS_WEIGHTS[@]}"; do + printf '@font-face{font-family:"JetBrains Mono";font-style:normal;font-display:swap;font-weight:%s;src:url("./fonts/jetbrains-mono-%s-%s-normal.woff2") format("woff2");unicode-range:%s;}\n' \ + "$w" "$SUBSET" "$w" "$RANGE" + done +} > "$BUILD/fonts.css" + +echo "Writing NOTICE ..." +cat > "$BUILD/NOTICE" <