diff --git a/README.md b/README.md index 44ef724..3eafac6 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,24 @@ notes and errors go to stderr. vabc --json inventory check 010807 --near 22182 | jq '.store.quantity, .nearbyStores[].quantity' ``` +`vabc` conforms to the [Agent CLI Guidelines](https://aclig.dev/) **v0.4.0** at the **Full** level. +The conformance block is machine-verifiable from the binary itself — `vabc schema --json` emits a +top-level `conformance` key — so an agent can confirm the contract version without trusting this badge: + +```json +{ + "conformance": { + "spec": "agent-cli-guidelines", + "version": "0.4.0", + "level": "Full" + } +} +``` + +```bash +vabc schema --json | jq '.conformance' +``` + ## How it works Everything is a live read against Virginia ABC's public, unauthenticated endpoints — product diff --git a/internal/cli/misc.go b/internal/cli/misc.go index 7045f29..8f213eb 100644 --- a/internal/cli/misc.go +++ b/internal/cli/misc.go @@ -96,8 +96,11 @@ func (c *SchemaCmd) Run(rt *Runtime) error { return errs.New(errs.ExitGeneric, "SCHEMA_ERROR", err.Error(), "") } out := map[string]any{ - "tool": "vabc", - "version": version.String(), + "tool": "vabc", + "version": version.String(), + "conformance": map[string]any{ + "spec": "agent-cli-guidelines", "version": version.Spec, "level": "Full", + }, "commands": nodeToMap(k.Model.Node), "exit_codes": errs.Table(), "safety": map[string]any{ @@ -159,8 +162,30 @@ func (c *AgentCmd) Run(rt *Runtime) error { // --- version ---------------------------------------------------------------- -type VersionCmd struct{} +// VersionCmd prints the version, or with --check asks (pull-based, fail-silent) whether a +// newer release exists. Update awareness, never self-mutation (contract §11). The tool never +// auto-updates; it only reports the upgrade command for the human/package manager. + +type VersionCmd struct { + Check bool `help:"Check for a newer release (network, short timeout, fail-silent)."` +} func (c *VersionCmd) Run(rt *Runtime) error { - return rt.Out.Emit(map[string]any{"version": version.String()}) + cur := version.String() + if !c.Check { + return rt.Out.Emit(map[string]any{"version": cur}) + } + out := map[string]any{ + "current": cur, + "latest": nil, + "updateAvailable": false, + "upgrade": version.UpgradeHint(), + } + if latest, err := version.Latest(rt.Ctx); err == nil && latest != "" { + out["latest"] = latest + out["updateAvailable"] = version.UpdateAvailable(latest, cur) + } else { + out["note"] = "could not check for updates" + } + return rt.Out.Emit(out) } diff --git a/internal/cli/testdata/schema.golden.json b/internal/cli/testdata/schema.golden.json index 0a035f3..824d568 100644 --- a/internal/cli/testdata/schema.golden.json +++ b/internal/cli/testdata/schema.golden.json @@ -215,11 +215,22 @@ "name": "agent" }, { + "flags": [ + { + "help": "Check for a newer release (network, short timeout, fail-silent).", + "name": "check" + } + ], "help": "Print the version.", "name": "version" } ] }, + "conformance": { + "level": "Full", + "spec": "agent-cli-guidelines", + "version": "0.4.0" + }, "exit_codes": { "auth_required": 4, "cancelled": 130, diff --git a/internal/version/version.go b/internal/version/version.go index 1de7c8c..72ef8d4 100644 --- a/internal/version/version.go +++ b/internal/version/version.go @@ -1,6 +1,18 @@ package version -import "runtime/debug" +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "os" + "runtime/debug" + "strings" + "time" +) + +// Spec is the Agent CLI Guidelines version this tool conforms to (declared in `schema`). +const Spec = "0.4.0" // version is a plain literal so -ldflags "-X .../version.version=vX" can override it. // It MUST NOT be initialized from a function call (golang/go#64246). @@ -24,3 +36,76 @@ func String() string { } return version } + +// repoSlug parses "owner/repo" from the module path (github.com/owner/repo), or "" if +// it can't be determined. +func repoSlug() string { + if bi, ok := debug.ReadBuildInfo(); ok { + if rest, found := strings.CutPrefix(bi.Main.Path, "github.com/"); found { + parts := strings.Split(rest, "/") + if len(parts) >= 2 { + return parts[0] + "/" + parts[1] + } + } + } + return "" +} + +// UpgradeHint returns the recommended upgrade command for this tool. The main package lives at +// ./cmd/ (the scaffold layout), so the install path includes /cmd/ — a bare +// module@latest would fail for tools with no root main. +func UpgradeHint() string { + slug := repoSlug() + if slug == "" { + return "" + } + repo := slug[strings.LastIndex(slug, "/")+1:] + return "go install github.com/" + slug + "/cmd/" + repo + "@latest" +} + +// Latest returns the latest released version tag (from GitHub Releases by default). +// Network, short timeout, **fail-silent**: returns ("", err) on any problem so a +// `version --check` never errors or blocks an agent loop. The release source can be +// overridden with VABC_RELEASES_URL (used in tests). +func Latest(ctx context.Context) (string, error) { + url := os.Getenv("VABC_RELEASES_URL") + if url == "" { + slug := repoSlug() + if slug == "" { + return "", fmt.Errorf("unknown repository") + } + url = "https://api.github.com/repos/" + slug + "/releases/latest" + } + ctx, cancel := context.WithTimeout(ctx, 3*time.Second) + defer cancel() + req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) + if err != nil { + return "", err + } + req.Header.Set("Accept", "application/vnd.github+json") + req.Header.Set("User-Agent", "vabc-version-check") // GitHub's REST API rejects requests with no UA + resp, err := http.DefaultClient.Do(req) + if err != nil { + return "", err + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return "", fmt.Errorf("release source: %s", resp.Status) + } + var body struct { + TagName string `json:"tag_name"` + } + if err := json.NewDecoder(resp.Body).Decode(&body); err != nil { + return "", err + } + return body.TagName, nil +} + +// UpdateAvailable reports whether latest is a different release than current. +// Dev/source builds (current == "dev") never report an update — don't nag them. +func UpdateAvailable(latest, current string) bool { + if latest == "" || current == "" || current == "dev" { + return false + } + return strings.TrimPrefix(latest, "v") != strings.TrimPrefix(current, "v") +} diff --git a/site/astro.config.mjs b/site/astro.config.mjs index 5d37088..e47980b 100644 --- a/site/astro.config.mjs +++ b/site/astro.config.mjs @@ -1,6 +1,7 @@ // @ts-check import { defineConfig } from "astro/config"; import starlight from "@astrojs/starlight"; +import starlightLlmsTxt from "starlight-llms-txt"; // Canonical site URL. Currently the live Vercel alias; cut over to https://vabc.sh // once the domain is bought (update here + redeploy + re-alias + regenerate OG cards). @@ -15,6 +16,7 @@ export default defineConfig({ description: "Virginia ABC product search and store inventory from your terminal — agent-friendly, read-only.", tagline: "Find the bottle. Skip the website.", + plugins: [starlightLlmsTxt()], logo: { src: "./src/assets/mark.svg", replacesTitle: false }, customCss: ["./src/styles/tokens.css", "./src/styles/docs.css"], social: { github: "https://github.com/rnwolfe/vabc" }, diff --git a/site/package.json b/site/package.json index 3540b21..dd46727 100644 --- a/site/package.json +++ b/site/package.json @@ -10,7 +10,8 @@ "og": "node scripts/gen-og.mjs" }, "dependencies": { - "@astrojs/starlight": "^0.30.0", + "@astrojs/starlight": "^0.31.0", + "starlight-llms-txt": "^0.4.0", "@fontsource/bricolage-grotesque": "^5.2.10", "@fontsource/ibm-plex-mono": "^5.2.7", "@fontsource/ibm-plex-sans": "^5.2.8", diff --git a/site/pnpm-lock.yaml b/site/pnpm-lock.yaml index efd9afb..d5659e4 100644 --- a/site/pnpm-lock.yaml +++ b/site/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: dependencies: '@astrojs/starlight': - specifier: ^0.30.0 - version: 0.30.6(astro@5.18.2(@types/node@24.13.2)(rollup@4.62.2)(typescript@5.9.3)) + specifier: ^0.31.0 + version: 0.31.1(astro@5.18.2(@types/node@24.13.2)(rollup@4.62.2)(typescript@5.9.3)) '@fontsource/bricolage-grotesque': specifier: ^5.2.10 version: 5.2.10 @@ -26,6 +26,9 @@ importers: sharp: specifier: ^0.33.5 version: 0.33.5 + starlight-llms-txt: + specifier: ^0.4.0 + version: 0.4.1(@astrojs/starlight@0.31.1(astro@5.18.2(@types/node@24.13.2)(rollup@4.62.2)(typescript@5.9.3)))(astro@5.18.2(@types/node@24.13.2)(rollup@4.62.2)(typescript@5.9.3)) packages: @@ -51,10 +54,10 @@ packages: '@astrojs/sitemap@3.7.3': resolution: {integrity: sha512-f8euLVsyeAmAkSm/1M2Kb8sL8byQmfgbvBNaHFItCheTj/IpiJYSEWVcqDHZ/yEHxiS7+w87mQkzwZaPHmk5GA==} - '@astrojs/starlight@0.30.6': - resolution: {integrity: sha512-/AoLXjPPD1MqixkTd2Lp3qahSzfCejePWHZQ3+fDjj1CuXI7Gjrr5bR3zNV0b9tynloPAIBM0HOyBNEGAo9uAQ==} + '@astrojs/starlight@0.31.1': + resolution: {integrity: sha512-VIVkHugwgtEqJPiRH8+ouP0UqUfdmpBO9C64R+6QaQ2qmADNkI/BA3/YAJHTBZYlMQQGEEuLJwD9qpaUovi52Q==} peerDependencies: - astro: ^5.0.0 + astro: ^5.1.5 '@astrojs/telemetry@3.3.0': resolution: {integrity: sha512-UFBgfeldP06qu6khs/yY+q1cDAaArM2/7AEIqQ9Cuvf7B1hNLq0xDrZkct+QoIGyjq56y8IaE2I3CTvG99mlhQ==} @@ -404,17 +407,17 @@ packages: cpu: [x64] os: [win32] - '@expressive-code/core@0.38.3': - resolution: {integrity: sha512-s0/OtdRpBONwcn23O8nVwDNQqpBGKscysejkeBkwlIeHRLZWgiTVrusT5Idrdz1d8cW5wRk9iGsAIQmwDPXgJg==} + '@expressive-code/core@0.40.2': + resolution: {integrity: sha512-gXY3v7jbgz6nWKvRpoDxK4AHUPkZRuJsM79vHX/5uhV9/qX6Qnctp/U/dMHog/LCVXcuOps+5nRmf1uxQVPb3w==} - '@expressive-code/plugin-frames@0.38.3': - resolution: {integrity: sha512-qL2oC6FplmHNQfZ8ZkTR64/wKo9x0c8uP2WDftR/ydwN/yhe1ed7ZWYb8r3dezxsls+tDokCnN4zYR594jbpvg==} + '@expressive-code/plugin-frames@0.40.2': + resolution: {integrity: sha512-aLw5IlDlZWb10Jo/TTDCVsmJhKfZ7FJI83Zo9VDrV0OBlmHAg7klZqw68VDz7FlftIBVAmMby53/MNXPnMjTSQ==} - '@expressive-code/plugin-shiki@0.38.3': - resolution: {integrity: sha512-kqHnglZeesqG3UKrb6e9Fq5W36AZ05Y9tCREmSN2lw8LVTqENIeCIkLDdWtQ5VoHlKqwUEQFTVlRehdwoY7Gmw==} + '@expressive-code/plugin-shiki@0.40.2': + resolution: {integrity: sha512-t2HMR5BO6GdDW1c1ISBTk66xO503e/Z8ecZdNcr6E4NpUfvY+MRje+LtrcvbBqMwWBBO8RpVKcam/Uy+1GxwKQ==} - '@expressive-code/plugin-text-markers@0.38.3': - resolution: {integrity: sha512-dPK3+BVGTbTmGQGU3Fkj3jZ3OltWUAlxetMHI6limUGCWBCucZiwoZeFM/WmqQa71GyKRzhBT+iEov6kkz2xVA==} + '@expressive-code/plugin-text-markers@0.40.2': + resolution: {integrity: sha512-/XoLjD67K9nfM4TgDlXAExzMJp6ewFKxNpfUw4F7q5Ecy+IU3/9zQQG/O70Zy+RxYTwKGw2MA9kd7yelsxnSmw==} '@fontsource/bricolage-grotesque@5.2.10': resolution: {integrity: sha512-V2xS+1P7C8IrSypXLUx/bLtX/LsTlYtV2k2CsU+S/0t8qepZ2hvKSlyJIx7Ub/iY8Bbnj+IjAuUF9nvFz+BbIg==} @@ -887,6 +890,9 @@ packages: '@shikijs/vscode-textmate@10.0.2': resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} + '@types/braces@3.0.5': + resolution: {integrity: sha512-SQFof9H+LXeWNz8wDe7oN5zu7ket0qwMu5vZubW4GCJ8Kkeh6nBWUz87+KTz/G3Kqsrp0j/W253XJb3KMEeg3w==} + '@types/debug@4.1.13': resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} @@ -908,6 +914,9 @@ packages: '@types/mdx@2.0.14': resolution: {integrity: sha512-T48PeuJtvLosNTPVhfnIp3i/n3a4g4Bad7YCq5k64D4u7NwDrAotikQ+5+sjtUvBmxCMlbo3dVL+C2dP0rWHzg==} + '@types/micromatch@4.0.10': + resolution: {integrity: sha512-5jOhFDElqr4DKTrTEbnW8DZ4Hz5LRUEmyrGpCMrD/NphYv3nUnaF08xmSLx1rGGnyEs/kFnhiw6dCgcDqMr5PQ==} + '@types/ms@2.1.0': resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} @@ -975,8 +984,8 @@ packages: resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} hasBin: true - astro-expressive-code@0.38.3: - resolution: {integrity: sha512-Tvdc7RV0G92BbtyEOsfJtXU35w41CkM94fOAzxbQP67Wj5jArfserJ321FO4XA7WG9QMV0GIBmQq77NBIRDzpQ==} + astro-expressive-code@0.40.2: + resolution: {integrity: sha512-yJMQId0yXSAbW9I6yqvJ3FcjKzJ8zRL7elbJbllkv1ZJPlsI0NI83Pxn1YL1IapEM347EvOOkSW2GL+2+NO61w==} peerDependencies: astro: ^4.0.0-beta || ^5.0.0-beta || ^3.3.0 @@ -1008,6 +1017,10 @@ packages: resolution: {integrity: sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw==} engines: {node: '>=18'} + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + camelcase@8.0.0: resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==} engines: {node: '>=16'} @@ -1242,8 +1255,8 @@ packages: eventemitter3@5.0.4: resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} - expressive-code@0.38.3: - resolution: {integrity: sha512-COM04AiUotHCKJgWdn7NtW2lqu8OW8owAidMpkXt1qxrZ9Q2iC7+tok/1qIn2ocGnczvr9paIySgGnEwFeEQ8Q==} + expressive-code@0.40.2: + resolution: {integrity: sha512-1zIda2rB0qiDZACawzw2rbdBQiWHBT56uBctS+ezFe5XMAaFaHLnnSYND/Kd+dVzO9HfCXRDpzH3d+3fvOWRcw==} extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} @@ -1257,6 +1270,10 @@ packages: picomatch: optional: true + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + flattie@1.1.1: resolution: {integrity: sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==} engines: {node: '>=8'} @@ -1328,6 +1345,9 @@ packages: hast-util-to-jsx-runtime@2.3.6: resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} + hast-util-to-mdast@10.1.2: + resolution: {integrity: sha512-FiCRI7NmOvM4y+f5w32jPRzcxDIz+PUqDwEqn1A+1q2cdp3B8Gx7aVrXORdOKjMNDQsD1ogOr896+0jJHW1EFQ==} + hast-util-to-parse5@8.0.1: resolution: {integrity: sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==} @@ -1396,6 +1416,10 @@ packages: engines: {node: '>=14.16'} hasBin: true + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + is-plain-obj@4.1.0: resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} engines: {node: '>=12'} @@ -1600,6 +1624,10 @@ packages: micromark@4.0.2: resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + mrmime@2.0.1: resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} engines: {node: '>=10'} @@ -1750,12 +1778,15 @@ packages: regex@6.1.0: resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==} - rehype-expressive-code@0.38.3: - resolution: {integrity: sha512-RYSSDkMBikoTbycZPkcWp6ELneANT4eTpND1DSRJ6nI2eVFUwTBDCvE2vO6jOOTaavwnPiydi4i/87NRyjpdOA==} + rehype-expressive-code@0.40.2: + resolution: {integrity: sha512-+kn+AMGCrGzvtH8Q5lC6Y5lnmTV/r33fdmi5QU/IH1KPHKobKr5UnLwJuqHv5jBTSN/0v2wLDS7RTM73FVzqmQ==} rehype-format@5.0.1: resolution: {integrity: sha512-zvmVru9uB0josBVpr946OR8ui7nJEdzZobwLOOqHb/OOD88W0Vk2SqLwoVOj0fM6IPCCO6TaV9CvQvJMWwukFQ==} + rehype-minify-whitespace@6.0.2: + resolution: {integrity: sha512-Zk0pyQ06A3Lyxhe9vGtOtzz3Z0+qZ5+7icZ/PL/2x1SHPbKao5oB/g/rlc6BCTajqBb33JcOe71Ye1oFsuYbnw==} + rehype-parse@9.0.1: resolution: {integrity: sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==} @@ -1765,6 +1796,9 @@ packages: rehype-recma@1.0.0: resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==} + rehype-remark@10.0.1: + resolution: {integrity: sha512-EmDndlb5NVwXGfUa4c9GPK+lXeItTilLhE6ADSaQuHr4JUlKw9MidzGzx4HpqZrNCt6vnHmEifXQiiA+CEnjYQ==} + rehype-stringify@10.0.1: resolution: {integrity: sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==} @@ -1859,6 +1893,13 @@ packages: space-separated-tokens@2.0.2: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + starlight-llms-txt@0.4.1: + resolution: {integrity: sha512-lrMvDBOxsZ70je4FIRn77J+aS9J7XVARusxrfjsrWYNoO7sosIyEeEyCK5HEmVBRFdR9uNRXw3uCUuDoz5OabA==} + engines: {node: ^18.17.1 || ^20.3.0 || >=21.0.0} + peerDependencies: + '@astrojs/starlight': '>=0.31' + astro: ^5.1.6 + stream-replace-string@2.0.0: resolution: {integrity: sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w==} @@ -1903,9 +1944,16 @@ packages: resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} engines: {node: '>=12.0.0'} + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + trim-lines@3.0.1: resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + trim-trailing-lines@2.1.0: + resolution: {integrity: sha512-5UR5Biq4VlVOtzqkm2AZlgvSlDJtME46uV0br0gENbwN4l5+mMKT4b9gJKqWtuL2zAIqajGJGuvbCbcAJUZqBg==} + trough@2.2.0: resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} @@ -1968,6 +2016,9 @@ packages: unist-util-remove-position@5.0.0: resolution: {integrity: sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==} + unist-util-remove@4.0.0: + resolution: {integrity: sha512-b4gokeGId57UVRX/eVKej5gXqGlc9+trkORhFJpu9raqZkZhU0zm8Doi05+HaiBsMEIJowL+2WtQ5ItjsngPXg==} + unist-util-stringify-position@4.0.0: resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} @@ -2217,7 +2268,7 @@ snapshots: stream-replace-string: 2.0.0 zod: 4.4.3 - '@astrojs/starlight@0.30.6(astro@5.18.2(@types/node@24.13.2)(rollup@4.62.2)(typescript@5.9.3))': + '@astrojs/starlight@0.31.1(astro@5.18.2(@types/node@24.13.2)(rollup@4.62.2)(typescript@5.9.3))': dependencies: '@astrojs/mdx': 4.3.14(astro@5.18.2(@types/node@24.13.2)(rollup@4.62.2)(typescript@5.9.3)) '@astrojs/sitemap': 3.7.3 @@ -2226,7 +2277,7 @@ snapshots: '@types/js-yaml': 4.0.9 '@types/mdast': 4.0.4 astro: 5.18.2(@types/node@24.13.2)(rollup@4.62.2)(typescript@5.9.3) - astro-expressive-code: 0.38.3(astro@5.18.2(@types/node@24.13.2)(rollup@4.62.2)(typescript@5.9.3)) + astro-expressive-code: 0.40.2(astro@5.18.2(@types/node@24.13.2)(rollup@4.62.2)(typescript@5.9.3)) bcp-47: 2.1.0 hast-util-from-html: 2.0.3 hast-util-select: 6.0.4 @@ -2441,7 +2492,7 @@ snapshots: '@esbuild/win32-x64@0.27.7': optional: true - '@expressive-code/core@0.38.3': + '@expressive-code/core@0.40.2': dependencies: '@ctrl/tinycolor': 4.2.0 hast-util-select: 6.0.4 @@ -2453,18 +2504,18 @@ snapshots: unist-util-visit: 5.1.0 unist-util-visit-parents: 6.0.2 - '@expressive-code/plugin-frames@0.38.3': + '@expressive-code/plugin-frames@0.40.2': dependencies: - '@expressive-code/core': 0.38.3 + '@expressive-code/core': 0.40.2 - '@expressive-code/plugin-shiki@0.38.3': + '@expressive-code/plugin-shiki@0.40.2': dependencies: - '@expressive-code/core': 0.38.3 + '@expressive-code/core': 0.40.2 shiki: 1.29.2 - '@expressive-code/plugin-text-markers@0.38.3': + '@expressive-code/plugin-text-markers@0.40.2': dependencies: - '@expressive-code/core': 0.38.3 + '@expressive-code/core': 0.40.2 '@fontsource/bricolage-grotesque@5.2.10': {} @@ -2850,6 +2901,8 @@ snapshots: '@shikijs/vscode-textmate@10.0.2': {} + '@types/braces@3.0.5': {} + '@types/debug@4.1.13': dependencies: '@types/ms': 2.1.0 @@ -2872,6 +2925,10 @@ snapshots: '@types/mdx@2.0.14': {} + '@types/micromatch@4.0.10': + dependencies: + '@types/braces': 3.0.5 + '@types/ms@2.1.0': {} '@types/nlcst@2.0.3': @@ -2923,10 +2980,10 @@ snapshots: astring@1.9.0: {} - astro-expressive-code@0.38.3(astro@5.18.2(@types/node@24.13.2)(rollup@4.62.2)(typescript@5.9.3)): + astro-expressive-code@0.40.2(astro@5.18.2(@types/node@24.13.2)(rollup@4.62.2)(typescript@5.9.3)): dependencies: astro: 5.18.2(@types/node@24.13.2)(rollup@4.62.2)(typescript@5.9.3) - rehype-expressive-code: 0.38.3 + rehype-expressive-code: 0.40.2 astro@5.18.2(@types/node@24.13.2)(rollup@4.62.2)(typescript@5.9.3): dependencies: @@ -3057,6 +3114,10 @@ snapshots: widest-line: 5.0.0 wrap-ansi: 9.0.2 + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + camelcase@8.0.0: {} ccount@2.0.1: {} @@ -3316,12 +3377,12 @@ snapshots: eventemitter3@5.0.4: {} - expressive-code@0.38.3: + expressive-code@0.40.2: dependencies: - '@expressive-code/core': 0.38.3 - '@expressive-code/plugin-frames': 0.38.3 - '@expressive-code/plugin-shiki': 0.38.3 - '@expressive-code/plugin-text-markers': 0.38.3 + '@expressive-code/core': 0.40.2 + '@expressive-code/plugin-frames': 0.40.2 + '@expressive-code/plugin-shiki': 0.40.2 + '@expressive-code/plugin-text-markers': 0.40.2 extend@3.0.2: {} @@ -3329,6 +3390,10 @@ snapshots: optionalDependencies: picomatch: 4.0.4 + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + flattie@1.1.1: {} fontace@0.4.1: @@ -3514,6 +3579,23 @@ snapshots: transitivePeerDependencies: - supports-color + hast-util-to-mdast@10.1.2: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.3.2 + hast-util-phrasing: 3.0.1 + hast-util-to-html: 9.0.5 + hast-util-to-text: 4.0.2 + hast-util-whitespace: 3.0.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-hast: 13.2.1 + mdast-util-to-string: 4.0.0 + rehype-minify-whitespace: 6.0.2 + trim-trailing-lines: 2.1.0 + unist-util-position: 5.0.0 + unist-util-visit: 5.1.0 + hast-util-to-parse5@8.0.1: dependencies: '@types/hast': 3.0.4 @@ -3586,6 +3668,8 @@ snapshots: dependencies: is-docker: 3.0.0 + is-number@7.0.0: {} + is-plain-obj@4.1.0: {} is-wsl@3.1.1: @@ -4077,6 +4161,11 @@ snapshots: transitivePeerDependencies: - supports-color + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.2 + mrmime@2.0.1: {} ms@2.1.3: {} @@ -4252,15 +4341,20 @@ snapshots: dependencies: regex-utilities: 2.3.0 - rehype-expressive-code@0.38.3: + rehype-expressive-code@0.40.2: dependencies: - expressive-code: 0.38.3 + expressive-code: 0.40.2 rehype-format@5.0.1: dependencies: '@types/hast': 3.0.4 hast-util-format: 1.1.0 + rehype-minify-whitespace@6.0.2: + dependencies: + '@types/hast': 3.0.4 + hast-util-minify-whitespace: 1.0.1 + rehype-parse@9.0.1: dependencies: '@types/hast': 3.0.4 @@ -4281,6 +4375,14 @@ snapshots: transitivePeerDependencies: - supports-color + rehype-remark@10.0.1: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + hast-util-to-mdast: 10.1.2 + unified: 11.0.5 + vfile: 6.0.3 + rehype-stringify@10.0.1: dependencies: '@types/hast': 3.0.4 @@ -4512,6 +4614,25 @@ snapshots: space-separated-tokens@2.0.2: {} + starlight-llms-txt@0.4.1(@astrojs/starlight@0.31.1(astro@5.18.2(@types/node@24.13.2)(rollup@4.62.2)(typescript@5.9.3)))(astro@5.18.2(@types/node@24.13.2)(rollup@4.62.2)(typescript@5.9.3)): + dependencies: + '@astrojs/mdx': 4.3.14(astro@5.18.2(@types/node@24.13.2)(rollup@4.62.2)(typescript@5.9.3)) + '@astrojs/starlight': 0.31.1(astro@5.18.2(@types/node@24.13.2)(rollup@4.62.2)(typescript@5.9.3)) + '@types/hast': 3.0.4 + '@types/micromatch': 4.0.10 + astro: 5.18.2(@types/node@24.13.2)(rollup@4.62.2)(typescript@5.9.3) + github-slugger: 2.0.0 + hast-util-select: 6.0.4 + micromatch: 4.0.8 + rehype-parse: 9.0.1 + rehype-remark: 10.0.1 + remark-gfm: 4.0.1 + remark-stringify: 11.0.0 + unified: 11.0.5 + unist-util-remove: 4.0.0 + transitivePeerDependencies: + - supports-color + stream-replace-string@2.0.0: {} string-width@4.2.3: @@ -4566,8 +4687,14 @@ snapshots: fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + trim-lines@3.0.1: {} + trim-trailing-lines@2.1.0: {} + trough@2.2.0: {} tsconfck@3.1.6(typescript@5.9.3): @@ -4632,6 +4759,12 @@ snapshots: '@types/unist': 3.0.3 unist-util-visit: 5.1.0 + unist-util-remove@4.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + unist-util-stringify-position@4.0.0: dependencies: '@types/unist': 3.0.3