diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 62254f5..203e474 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,7 +4,7 @@ on: push: branches: ["master"] pull_request: - branches: ["master"] + branches: ["master", "codex/**"] permissions: read-all @@ -15,11 +15,11 @@ jobs: - uses: actions/checkout@v5 - uses: actions/setup-go@v6 with: - go-version: "1.27.1" + go-version: "1.27.4" - name: Verify the pinned interpreter run: test "$(go list -m -f '{{.Version}}' go.starlark.net)" = "v0.0.0-20260324133313-ffb3f39dd27a" - name: Guard the compatible crypto dependency boundary - # v0.55.0 keeps Go 1.25 support. Its SSH/OpenPGP packages must not enter + # The reviewed crypto dependency requires Go 1.26. SSH/OpenPGP must not enter # this application's build or tests; their advisories need a separate # dependency and compatibility review before either package is used. run: | @@ -36,7 +36,7 @@ jobs: - uses: actions/checkout@v5 - uses: actions/setup-go@v6 with: - go-version: "1.27.1" + go-version: "1.27.4" - name: Build the runtime image run: | CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -trimpath -o starcli . @@ -54,11 +54,11 @@ jobs: # Star* module's pipeline. Pinned to a commit SHA for supply-chain safety; # bump the pin when meta's workflow changes (Dependabot github-actions can # automate this). - uses: 1set/meta/.github/workflows/go-ci.yml@23f088bcd6dce16c93e0056d7b70b4f4434208e8 + uses: 1set/meta/.github/workflows/go-ci.yml@6b334e6a2762acaeefcea9fc7d3e86964e9246be with: # Match go.mod's compatibility floor; the shared workflow also tests # the current stable Go release. - go-floor: "1.25" + go-floor: "1.26" # Test-coverage ratchet (covcheck). The CLI-R0 characterization suite # brought total statement coverage to ~69.5% (cli 68.9 / config 94.1 / # util 92.7 / sys 77.8; main.go and web/ are the uncovered remainder). diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c4aea23..904ece0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -7,7 +7,7 @@ on: branches: ["master"] tags: ["v*"] pull_request: - branches: ["master"] + branches: ["master", "codex/**"] permissions: contents: read @@ -25,7 +25,7 @@ jobs: persist-credentials: false - uses: actions/setup-go@v6 with: - go-version: "1.27.1" + go-version: "1.27.4" - name: Check source vulnerabilities run: go run golang.org/x/vuln/cmd/govulncheck@v1.8.0 ./... - name: Select release or snapshot build @@ -79,7 +79,7 @@ jobs: target: linux_arm64.tar.gz - os: macos-15-intel target: macOS_amd64.tar.gz - - os: macos-14 + - os: macos-15 target: macOS_arm64.tar.gz - os: windows-2022 target: windows_amd64.zip @@ -91,7 +91,7 @@ jobs: persist-credentials: false - uses: actions/setup-go@v6 with: - go-version: "1.27.1" + go-version: "1.27.4" - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 with: python-version: "3.13" diff --git a/README.md b/README.md index 00e6eb5..95f3b22 100644 --- a/README.md +++ b/README.md @@ -180,6 +180,14 @@ by a tier, not even `full`. For a one-flag "trust everything" run there is command execution of any command in a single switch. Use it only with fully trusted scripts. +SQLite's `register_function` is disabled unless the operator passes +`--dangerously-allow-all`. The `open`/`full` tiers and `--allow-cmd` do not enable +custom SQL callbacks. Ordinary SQL and built-in functions remain available. +Restricted connections also exclude callbacks registered earlier by a trusted +box in the same process. This intentionally tightens the previous default. +Custom callbacks run outside the Machine's step budget; use the trusted-script +flag only when that limitation is acceptable. + Set a stricter default for a whole deployment with the env var: ```bash @@ -395,7 +403,8 @@ host_name: MyStarCLIServer ### Prerequisites -- Go 1.25.8 or later (prebuilt binaries do not require a Go installation) +- Go 1.26.0 or later for source builds and the kit API; production binaries use + Go 1.27.4 (prebuilt binaries do not require a Go installation). ### Building diff --git a/SECURITY.md b/SECURITY.md index 24f721b..77d3416 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -30,6 +30,12 @@ do not provide process or memory isolation. The default `open` tier permits network and filesystem access. `--allow-cmd` authorizes arbitrary host commands and process environment access, including through `gum` and `runtime`. +SQLite custom functions require `--dangerously-allow-all`. Ordinary module and +command grants do not enable them. Normal connections exclude process-wide +callbacks, including ones registered earlier by a trusted box. Fully trusted +callbacks retain the existing separate-thread behavior and are not bounded by +`--max-steps`; this is not an isolated-worker or complete resource budget. + Use the narrowest capability grants and import directories that your script needs. HTTP execution has request and cooperative execution limits, but these do not preempt arbitrary Go builtins or impose a complete output-byte budget. diff --git a/cli/args.go b/cli/args.go index 5e57b08..7ff67b3 100644 --- a/cli/args.go +++ b/cli/args.go @@ -66,7 +66,7 @@ func ParseArgs() *Args { flag.BoolVar(&args.AllowNet, "allow-net", false, "widen a restrictive tier with network modules (http, net, email, llm)") flag.BoolVar(&args.AllowFS, "allow-fs", false, "widen a restrictive tier with filesystem modules (file, path)") flag.BoolVar(&args.AllowCmd, "allow-cmd", false, "allow ANY host command, gum subprocesses, and runtime environment mutation (trusted scripts only)") - flag.BoolVar(&args.Dangerous, "dangerously-allow-all", false, "DANGER: open everything — network + filesystem + host command execution of ANY command. Use only with fully trusted scripts.") + flag.BoolVar(&args.Dangerous, "dangerously-allow-all", false, "DANGER: open network, filesystem, arbitrary host commands, and SQLite custom functions. Fully trusted scripts only.") flag.BoolVar(&args.Check, "check", false, "syntax/resolve check the script (-c or file) without running it") flag.StringVar(&args.LogFile, "log-file", "", "append the script's log module output to this file") flag.StringVar(&args.LogFormat, "log-format", "console", "log file format: console (human) or json (machine)") diff --git a/cli/capability_test.go b/cli/capability_test.go index 86b51a8..df93747 100644 --- a/cli/capability_test.go +++ b/cli/capability_test.go @@ -12,6 +12,7 @@ package cli // - wired pure domain modules are classified pure and pass the safe gate // - cmd execution gating: off by default, on with --allow-cmd / // --dangerously-allow-all (the execCmd lever + end-to-end run()) +// - SQLite custom functions require the fully trusted-script grant import ( "fmt" @@ -19,6 +20,7 @@ import ( "path/filepath" "strings" "sync" + "sync/atomic" "testing" "github.com/1set/starlet" @@ -441,3 +443,95 @@ func TestProcessCapabilityBoundary(t *testing.T) { } } } + +// SQLite callbacks use their own Starlark threads and process-wide registry. +// Ordinary module/network/filesystem/command grants must not authorize them. +var sqlitePolicyFunctionID uint64 + +func TestSQLiteCustomFunctionPolicy(t *testing.T) { + cases := []struct { + name string + opts BoxOpts + allowed bool + }{ + {"default open", BoxOpts{}, false}, + {"explicit open", BoxOpts{caps: "open"}, false}, + {"full tier", BoxOpts{caps: "full"}, false}, + {"network and filesystem", BoxOpts{caps: "safe", allowNet: true, allowFS: true}, false}, + {"command grant", BoxOpts{allowCmd: true}, false}, + {"fully trusted", BoxOpts{caps: "safe", dangerous: true}, true}, + } + for _, tc := range cases { + for _, eager := range []bool{false, true} { + t.Run(fmt.Sprintf("%s/eager=%t", tc.name, eager), func(t *testing.T) { + opts := tc.opts + checkSQLiteFunctionPolicy(t, &opts, eager, tc.allowed) + }) + } + } +} + +func checkSQLiteFunctionPolicy(t *testing.T, opts *BoxOpts, eager, allowed bool) { + t.Helper() + opts.scenario, opts.printerName = scenarioDirect, "none" + opts.moduleToLoad = []string{"sqlite"} + box, err := BuildBox(opts) + if err != nil { + t.Fatal(err) + } + fn := fmt.Sprintf("starcli_policy_fn_%d", atomic.AddUint64(&sqlitePolicyFunctionID, 1)) + load, prefix := `load("sqlite", "connect", "register_function")`, "" + if eager { + load, prefix = "", "sqlite." + } + code := fmt.Sprintf(` +%s +%sregister_function(%q, lambda: 73, num_args=0) +db = %sconnect(":memory:") +def verify(): + if db.query_one("SELECT %s() AS result")["result"] != 73: + fail("custom function returned an incorrect value") +verify() +db.close() +`, load, prefix, fn, prefix, fn) + _, err = box.Run(code) + if allowed { + if err != nil { + t.Fatal(err) + } + return + } + if err == nil || !strings.Contains(err.Error(), "custom functions are disabled by the host") { + t.Fatalf("registration must be rejected by host policy, got %v", err) + } +} + +func TestSQLiteRestrictedConnectionIgnoresTrustedFunctions(t *testing.T) { + trusted, err := BuildBox(&BoxOpts{scenario: scenarioDirect, printerName: "none", moduleToLoad: []string{"sqlite"}, dangerous: true}) + if err != nil { + t.Fatal(err) + } + fn := fmt.Sprintf("starcli_private_fn_%d", atomic.AddUint64(&sqlitePolicyFunctionID, 1)) + if _, err = trusted.Run(fmt.Sprintf(`load("sqlite", "register_function"); register_function(%q, lambda: 41, num_args=0)`, fn)); err != nil { + t.Fatal(err) + } + restricted, err := BuildBox(&BoxOpts{scenario: scenarioDirect, printerName: "none", moduleToLoad: []string{"sqlite"}, caps: "full"}) + if err != nil { + t.Fatal(err) + } + _, err = restricted.Run(fmt.Sprintf(`load("sqlite", "connect"); db = connect(":memory:"); row = db.query_one("SELECT %s() AS result")`, fn)) + if err == nil || !strings.Contains(err.Error(), "no such function") { + t.Fatalf("restricted connection inherited a process-wide callback: %v", err) + } + if _, err = restricted.Run(` +load("sqlite", "connect") +db = connect(":memory:") +def verify(): + if db.query_one("SELECT abs(-73) AS result")["result"] != 73: + fail("built-in SQLite functions must remain usable") +verify() +db.close() +`); err != nil { + t.Fatalf("ordinary SQL on a restricted connection: %v", err) + } +} diff --git a/cli/mods.go b/cli/mods.go index 8cb638c..2f39a7b 100644 --- a/cli/mods.go +++ b/cli/mods.go @@ -94,7 +94,12 @@ func loadCLIModuleByName(opts *BoxOpts, name string) (starlet.ModuleLoader, erro } return cmd.NewModule().LoadModule(), nil case sqlite.ModuleName: - return sqlite.NewModule().LoadModule(), nil + // SQLite callbacks use separate Starlark threads and a process-wide + // registry. Only the fully trusted-script grant may enable them; ordinary + // SQL and built-in functions remain available under the normal grant. + return sqlite.NewModuleWithHostPolicy(sqlite.HostPolicy{ + DisableCustomFunctions: !opts.dangerous, + }).LoadModule(), nil case web.ModuleName: return web.NewModule().LoadModule(), nil case cache.ModuleName: diff --git a/e2e/e2e_test.go b/e2e/e2e_test.go index f9bb767..48767c9 100644 --- a/e2e/e2e_test.go +++ b/e2e/e2e_test.go @@ -5,7 +5,7 @@ // *work* through the CLI, not merely that they load. // // Sections: local imports, golden scripts, domain modules, stdin, recordings, -// containers. +// containers, SQLite custom-function authorization. package e2e import ( @@ -378,3 +378,37 @@ func TestContainer(t *testing.T) { } }) } + +// TestSQLiteCustomFunctionAuthorization exercises real argument parsing and the +// production module registry, including SQL calls after the explicit opt-in. +func TestSQLiteCustomFunctionAuthorization(t *testing.T) { + const code = ` +load("sqlite", "connect", "register_function") +register_function("starcli_e2e_answer", lambda: 73, num_args=0) +db = connect(":memory:") +print(db.query_one("SELECT starcli_e2e_answer() AS result")["result"]) +db.close() +` + for _, tc := range []struct { + name string + flags []string + allowed bool + }{ + {"default", nil, false}, + {"full tier", []string{"--caps", "full"}, false}, + {"command grant", []string{"--allow-cmd"}, false}, + {"fully trusted", []string{"--dangerously-allow-all"}, true}, + } { + t.Run(tc.name, func(t *testing.T) { + args := append(append([]string{}, tc.flags...), "-o", "stdout", "-c", code) + stdout, stderr, exit := runCLI(t, "", args...) + if tc.allowed { + if exit != 0 || !strings.Contains(stdout, "73") { + t.Fatalf("trusted custom function: exit=%d stdout=%q stderr=%q", exit, stdout, stderr) + } + } else if exit == 0 || !strings.Contains(stderr, "custom functions are disabled by the host") { + t.Fatalf("custom function requires the trusted-script grant: exit=%d stdout=%q stderr=%q", exit, stdout, stderr) + } + }) + } +} diff --git a/examples/go.mod b/examples/go.mod index d37a3f0..a74ca1a 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -5,7 +5,7 @@ // non-gating job. The replace points at the in-repo kit until starcli is tagged. module github.com/1set/starcli/examples -go 1.25.8 +go 1.26.0 require ( github.com/1set/starcli v0.0.0 @@ -29,7 +29,7 @@ require ( go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.9.0 // indirect go.uber.org/zap v1.24.0 // indirect - golang.org/x/sys v0.47.0 // indirect + golang.org/x/sys v0.49.0 // indirect ) replace github.com/1set/starcli => ../ diff --git a/examples/go.sum b/examples/go.sum index 6554772..bfaf235 100644 --- a/examples/go.sum +++ b/examples/go.sum @@ -52,8 +52,8 @@ go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTV go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs= -golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.49.0 h1:XbzkgYJHdqh/8m2Uu0W/dQv8nktxx4BFHp1M0gROTXA= +golang.org/x/sys v0.49.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= diff --git a/go.mod b/go.mod index 6f86fe3..a719755 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/1set/starcli -go 1.25.8 +go 1.26.0 require ( bitbucket.org/ai69/colorlogo v0.1.3 @@ -20,7 +20,7 @@ require ( github.com/starpkg/llm v0.1.0 github.com/starpkg/markdown v0.1.0 github.com/starpkg/qrcode v0.1.0 - github.com/starpkg/sqlite v0.2.1 + github.com/starpkg/sqlite v0.2.2-0.20260923164825-56739df72ba2 github.com/starpkg/toml v0.1.0 github.com/starpkg/totp v0.1.0 github.com/starpkg/web v0.1.0 @@ -28,8 +28,8 @@ require ( go.starlark.net v0.0.0-20260324133313-ffb3f39dd27a go.uber.org/atomic v1.11.0 go.uber.org/zap v1.24.0 - golang.org/x/sys v0.47.0 - golang.org/x/term v0.45.0 + golang.org/x/sys v0.49.0 + golang.org/x/term v0.47.0 ) require ( @@ -119,11 +119,11 @@ require ( github.com/yuin/goldmark-emoji v1.0.6 // indirect go.uber.org/multierr v1.9.0 // indirect golang.org/x/arch v0.3.0 // indirect - golang.org/x/crypto v0.55.0 // indirect + golang.org/x/crypto v0.58.1-0.20261009181718-2f1f834330b2 // indirect golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 // indirect - golang.org/x/net v0.57.0 // indirect - golang.org/x/sync v0.22.0 // indirect - golang.org/x/text v0.41.0 // indirect + golang.org/x/net v0.62.0 // indirect + golang.org/x/sync v0.24.0 // indirect + golang.org/x/text v0.43.0 // indirect google.golang.org/protobuf v1.36.11 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/go.sum b/go.sum index c9d6a52..fa0b953 100644 --- a/go.sum +++ b/go.sum @@ -251,8 +251,8 @@ github.com/starpkg/markdown v0.1.0 h1:buLZwTcZ9SQWrVOUVeTcHqw/DCkxKPE8rdvHpbhjrE github.com/starpkg/markdown v0.1.0/go.mod h1:JsRNXRFjvLPRrkjGrf6jXDTl3Qg9+d2/PByzW7WxYvg= github.com/starpkg/qrcode v0.1.0 h1:VULD2XBVacMq0c2WxJgdG0d3k0Z4EOSaFdYdkOB7bME= github.com/starpkg/qrcode v0.1.0/go.mod h1:itKiBubTuioyMM78bA+RTfwm/hH3EYG+W6NX0cscgh0= -github.com/starpkg/sqlite v0.2.1 h1:oTVkPCTQYhud3qDXztJsb/1cBY4SgXLF2PKonRhJPFI= -github.com/starpkg/sqlite v0.2.1/go.mod h1:Hfs3JZnFbDPefCL9ybSmRJIQ+IBVMYtj5FyZ+7XZpmc= +github.com/starpkg/sqlite v0.2.2-0.20260923164825-56739df72ba2 h1:YS+in+4QZRDTboQWFip0HFcduKdFV3xDIEMKTq/9IDc= +github.com/starpkg/sqlite v0.2.2-0.20260923164825-56739df72ba2/go.mod h1:16YgyyCzRaKMDqWZO6uucWIKyG3wWuIJx/O9MsDKHDs= github.com/starpkg/toml v0.1.0 h1:geXbLw/SW7XcU9Tz/eqjxSNywsMbxqfndXYOlXXkSKE= github.com/starpkg/toml v0.1.0/go.mod h1:8QtTjIjFNuw0WGYzDHFbynhQ21QM6BvdACzapKE1cr8= github.com/starpkg/totp v0.1.0 h1:BQ1J5bbhR8iICQ+iRJ4LZgJNX3RhhOZtY2aoaf38WqY= @@ -301,28 +301,28 @@ go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/crypto v0.55.0 h1:+KWHjbgOaAQ66dh/YlkZKHlz9ZUlq61AFirAR9ntP8M= -golang.org/x/crypto v0.55.0/go.mod h1:uq0V9dE/fzQuJtbnL+2EhWOE63vo164FY8xqEnV9xis= +golang.org/x/crypto v0.58.1-0.20261009181718-2f1f834330b2 h1:zGDaB+/Mus2mScKvZ23k+W9NAUbP56sNM9SptgvWI5A= +golang.org/x/crypto v0.58.1-0.20261009181718-2f1f834330b2/go.mod h1:Xh+kl5A+M0gMiWDytH2Hhr5Z7WbNCpv/eB/EFgfSk+w= golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 h1:aAcj0Da7eBAtrTp03QXWvm88pSyOt+UgdZw2BFZ+lEw= golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8/go.mod h1:CQ1k9gNrJ50XIzaKCRR2hssIjF07kZFEiieALBM/ARQ= -golang.org/x/mod v0.38.0 h1:MECBjubtXD7yj4HrhIUcywNaGeNVUdfVnxmPajOk4yk= -golang.org/x/mod v0.38.0/go.mod h1:V6Xz0pq8TQ3dGqVQ1FVHuelZpAL0uNhSkk9ogYP3c40= -golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE= -golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU= -golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek= -golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/mod v0.41.0 h1:qJmnOUb4YB+FsEuM3HcWucdZASCPGhsX6uljO6pog0c= +golang.org/x/mod v0.41.0/go.mod h1:Ek9pY8RKWXwsWvd3rQiHYtMqkjSUV+s1Rj7j4H5Ur6o= +golang.org/x/net v0.62.0 h1:18ELalfM5+XNRwzM2nYqXsZQ9ByS1uhj2O/U7+5jqRY= +golang.org/x/net v0.62.0/go.mod h1:WgDCOTH8iwtB66T4/GfI94AHo/hhdb7Hah9NDseQfiI= +golang.org/x/sync v0.24.0 h1:iqiDrGoDgyuvAKrhLQthUEzU/R378N78gXbBjxed7oA= +golang.org/x/sync v0.24.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0= golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs= -golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0= -golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w= -golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8= -golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M= -golang.org/x/tools v0.48.0 h1:3+hClM1aLL5mjMKm5ovokw9epgRXPuu2tILgismM6RE= -golang.org/x/tools v0.48.0/go.mod h1:08xX0orndb/F7jJxGDicx061tyd5pcMto75YMAXr6lk= +golang.org/x/sys v0.49.0 h1:XbzkgYJHdqh/8m2Uu0W/dQv8nktxx4BFHp1M0gROTXA= +golang.org/x/sys v0.49.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= +golang.org/x/term v0.47.0 h1:cpyOwQkr2Nzxe2p6KnrTG7Ei2wtzjsuSjhpXXepZ/BM= +golang.org/x/term v0.47.0/go.mod h1:efAfAuG6RKABvg1ArGebRkvX6LXul14SM67o2e4mUCY= +golang.org/x/text v0.43.0 h1:1QivrlhwAsnMOcqgOdl9my7s9OyZl8O5/UGUTJVXoWc= +golang.org/x/text v0.43.0/go.mod h1:hbSIYA/amXcRXTFSZqh8tWHEoqRvvbKPJ2uz/KU+a+s= +golang.org/x/tools v0.51.0 h1:k4Xc/1Om9jwkBJBo4NVLMSARBoWtK10mx+W5BnXCeAI= +golang.org/x/tools v0.51.0/go.mod h1:9eEncMayCV6zRMGhR5eZEC2iBx98qWcF1HZ9Z7wJOoA= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=