Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ sweeper.md
.claude/
*.jsonl
coverage.out
api-key-*.txt

# Sweeper ephemeral VM jcards (contain secrets)
.sweeper/vm/
Expand Down
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,31 @@ Every sub-agent session is recorded in [tapes](https://github.com/papercomputeco

Run `sweeper observe` after each sweep to see insights and tune your next run.

## Confluent Cloud Telemetry

Sweeper can stream telemetry events to Confluent Cloud alongside local JSONL files. Enable it in `.sweeper/config.toml`:

```toml
[telemetry]
backend = "confluent"
dir = ".sweeper/telemetry"

[telemetry.confluent]
brokers = ["pkc-xxxxx.region.provider.confluent.cloud:9092"]
topic = "sweeper.telemetry"
client_id = "sweeper"
api_key_env = "SWEEPER_CONFLUENT_API_KEY"
api_secret_env = "SWEEPER_CONFLUENT_API_SECRET"
```

Set `SWEEPER_CONFLUENT_API_KEY` and `SWEEPER_CONFLUENT_API_SECRET` in your environment. The config references env var names, not raw credentials.

For cluster and topic setup, install the [confluent-cloud-setup](https://github.com/papercomputeco/skills/tree/main/skills/confluent-cloud-setup) skill:

```bash
npx skills add papercomputeco/skills
```

## VM Isolation

Sub-agents can run inside ephemeral [stereOS](https://stereos.ai) virtual machines, managed by the `mb` (Masterblaster) CLI. This is what makes high concurrency safe.
Expand Down
9 changes: 8 additions & 1 deletion cmd/observe.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cmd
import (
"fmt"

"github.com/papercomputeco/sweeper/pkg/config"
"github.com/papercomputeco/sweeper/pkg/observer"
"github.com/papercomputeco/sweeper/pkg/tapes"
"github.com/spf13/cobra"
Expand All @@ -13,6 +14,12 @@ func newObserveCmd() *cobra.Command {
Use: "observe",
Short: "Analyze past runs and show learned patterns",
RunE: func(cmd *cobra.Command, args []string) error {
tc, err := config.LoadTOML(".", configPath)
if err != nil {
tc = config.NewDefaultTOMLConfig()
}
telDir := tc.Telemetry.Dir

var opts []observer.ObserverOption

if !noTapes {
Expand All @@ -26,7 +33,7 @@ func newObserveCmd() *cobra.Command {
}
}

obs := observer.New(".sweeper/telemetry", opts...)
obs := observer.New(telDir, opts...)
insights, err := obs.Analyze()
if err != nil {
return err
Expand Down
2 changes: 2 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ var (
concurrency int
rateLimit time.Duration
noTapes bool
configPath string
)

func NewRootCmd() *cobra.Command {
Expand All @@ -23,6 +24,7 @@ func NewRootCmd() *cobra.Command {
root.PersistentFlags().IntVarP(&concurrency, "concurrency", "c", 2, "max parallel sub-agents")
root.PersistentFlags().DurationVar(&rateLimit, "rate-limit", 2*time.Second, "minimum delay between agent dispatches (e.g. 2s, 500ms)")
root.PersistentFlags().BoolVar(&noTapes, "no-tapes", false, "disable tapes integration")
root.PersistentFlags().StringVar(&configPath, "config", "", "path to config.toml (default: .sweeper/config.toml)")
root.AddCommand(newVersionCmd())
root.AddCommand(newRunCmd())
root.AddCommand(newObserveCmd())
Expand Down
96 changes: 81 additions & 15 deletions cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
"github.com/papercomputeco/sweeper/pkg/config"
"github.com/papercomputeco/sweeper/pkg/linter"
"github.com/papercomputeco/sweeper/pkg/provider"
"github.com/papercomputeco/sweeper/pkg/telemetry"
"github.com/papercomputeco/sweeper/pkg/telemetry/confluent"
"github.com/papercomputeco/sweeper/pkg/vm"
"github.com/papercomputeco/sweeper/pkg/worker"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -42,24 +44,58 @@ Examples:
ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
defer cancel()

clamped := config.ClampConcurrency(concurrency)
if clamped != concurrency {
fmt.Printf("Concurrency clamped to %d (max %d)\n", clamped, config.MaxConcurrency)
// Load TOML config (defaults -> home -> project -> env).
tc, err := config.LoadTOML(targetDir, configPath)
if err != nil {
fmt.Printf("Warning: loading config: %v\n", err)
tc = config.NewDefaultTOMLConfig()
}

// CLI flags override TOML config.
rootPF := cmd.Root().PersistentFlags()
if rootPF.Changed("concurrency") {
tc.Run.Concurrency = concurrency
}
if rootPF.Changed("rate-limit") {
tc.Run.RateLimit = rateLimit.String()
}
if rootPF.Changed("no-tapes") {
tc.Run.NoTapes = noTapes
}
if cmd.Flags().Changed("max-rounds") {
tc.Run.MaxRounds = maxRounds
}
if cmd.Flags().Changed("stale-threshold") {
tc.Run.StaleThreshold = staleThreshold
}
cfg := config.Config{
TargetDir: targetDir,
Concurrency: clamped,
RateLimit: rateLimit,
TelemetryDir: ".sweeper/telemetry",
DryRun: dryRun,
NoTapes: noTapes,
MaxRounds: maxRounds,
StaleThreshold: staleThreshold,
Provider: providerName,
ProviderModel: providerModel,
ProviderAPI: providerAPI,
if cmd.Flags().Changed("dry-run") {
tc.Run.DryRun = dryRun
}
if cmd.Flags().Changed("provider") {
tc.Provider.Name = providerName
}
if cmd.Flags().Changed("model") {
tc.Provider.Model = providerModel
}
if cmd.Flags().Changed("api-base") {
tc.Provider.APIBase = providerAPI
}

// Build runtime config from TOML.
cfg := config.FromTOML(tc)
cfg.TargetDir = targetDir

clamped := config.ClampConcurrency(cfg.Concurrency)
if clamped != cfg.Concurrency {
fmt.Printf("Concurrency clamped to %d (max %d)\n", clamped, config.MaxConcurrency)
cfg.Concurrency = clamped
}



// Build telemetry publisher from config.
pub := buildPublisher(tc)

// Validate provider exists before proceeding.
if _, err := provider.Get(cfg.Provider); err != nil {
return err
Expand Down Expand Up @@ -137,6 +173,8 @@ Examples:
}
}

opts = append(opts, agent.WithPublisher(pub))

a := agent.New(cfg, opts...)
summary, err := a.Run(ctx)
if err != nil {
Expand Down Expand Up @@ -177,3 +215,31 @@ func argsAfterDash(cmd *cobra.Command, args []string) []string {
}
return args[idx:]
}

func buildPublisher(tc config.TOMLConfig) telemetry.Publisher {
jsonl := telemetry.NewJSONLPublisher(tc.Telemetry.Dir)

if tc.Telemetry.Backend != "confluent" {
return jsonl
}

cc := tc.Telemetry.Confluent
if len(cc.Brokers) == 0 || cc.Topic == "" {
fmt.Println("Warning: confluent backend selected but brokers/topic not configured, using JSONL only")
return jsonl
}

cp, err := confluent.NewPublisher(confluent.Config{
Brokers: cc.Brokers,
Topic: cc.Topic,
ClientID: cc.ClientID,
APIKeyEnv: cc.APIKeyEnv,
APISecretEnv: cc.APISecretEnv,
})
if err != nil {
fmt.Printf("Warning: confluent publisher: %v, using JSONL only\n", err)
return jsonl
}

return telemetry.NewMultiPublisher(jsonl, cp)
}
43 changes: 43 additions & 0 deletions example.config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# .sweeper/config.toml — sweeper project configuration
# Copy to .sweeper/config.toml or ~/.sweeper/config.toml
#
# Precedence (highest to lowest):
# 1. CLI flags (--concurrency, --provider, etc.)
# 2. SWEEPER_* environment variables
# 3. .sweeper/config.toml (project)
# 4. ~/.sweeper/config.toml (user)
# 5. Built-in defaults

version = 1

[run]
concurrency = 2
rate_limit = "2s"
max_rounds = 1
stale_threshold = 2
# dry_run = false
# no_tapes = false

[provider]
name = "claude"
# model = ""
# api_base = ""
# allowed_tools = ["Read", "Write", "Edit", "Glob", "Grep"]

[telemetry]
# backend: "jsonl" (default, always active) or "confluent" (adds Kafka fan-out)
backend = "jsonl"
dir = ".sweeper/telemetry"

# [telemetry.confluent]
# brokers = ["pkc-xxxxx.us-west-2.aws.confluent.cloud:9092"]
# topic = "sweeper.telemetry"
# client_id = "sweeper"
# api_key_env = "CONFLUENT_API_KEY"
# api_secret_env = "CONFLUENT_API_SECRET"
# publish_timeout = "5s"

# [vm]
# enabled = false
# name = ""
# jcard = ""
16 changes: 16 additions & 0 deletions extensions/sweeper/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,22 @@ function todayFileName(): string {

function telemetryDir(targetDir: string): string {
const path = require("path");
const fs = require("fs");

// Check config.toml for custom telemetry dir
const configPath = path.join(targetDir, ".sweeper", "config.toml");
if (fs.existsSync(configPath)) {
try {
const content = fs.readFileSync(configPath, "utf-8").replace(/\r\n/g, "\n");
// Simple TOML extraction for telemetry.dir (handles comments between section and key)
const match = content.match(/^\[telemetry\]\s*\n(?:(?:#[^\n]*|[^\[]*?)\n)*?dir\s*=\s*"([^"]+)"/m);
if (match) {
return path.isAbsolute(match[1]) ? match[1] : path.join(targetDir, match[1]);
}
} catch {
// Fall through to default
}
}
return path.join(targetDir, ".sweeper", "telemetry");
}

Expand Down
4 changes: 4 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@ require (
)

require (
github.com/BurntSushi/toml v1.6.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/klauspost/compress v1.15.9 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/ncruces/go-strftime v1.0.0 // indirect
github.com/pierrec/lz4/v4 v4.1.15 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/segmentio/kafka-go v0.4.47 // indirect
github.com/spf13/pflag v1.0.9 // indirect
golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 // indirect
golang.org/x/sys v0.37.0 // indirect
Expand Down
60 changes: 60 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk=
github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs=
Expand All @@ -9,30 +13,86 @@ github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY=
github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w=
github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/pierrec/lz4/v4 v4.1.15 h1:MO0/ucJhngq7299dKLwIMtgTfbkoSPF6AoMYDd8Q4q0=
github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/segmentio/kafka-go v0.4.47 h1:IqziR4pA3vrZq7YdRxaT3w1/5fvIH5qpCwstUanQQB0=
github.com/segmentio/kafka-go v0.4.47/go.mod h1:HjF6XbOKh0Pjlkr5GVZxt6CsjjwnmhVOfURM5KMd8qg=
github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=
github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY=
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 h1:mgKeJMpvi0yx/sU5GsxQ7p6s2wtOnGAHZWCHUM4KGzY=
golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546/go.mod h1:j/pmGrbnkbPtQfxEe5D0VQhZC6qKbfKifgD0oM7sR70=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=
golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
modernc.org/cc/v4 v4.27.1 h1:9W30zRlYrefrDV2JE2O8VDtJ1yPGownxciz5rrbQZis=
modernc.org/cc/v4 v4.27.1/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
modernc.org/ccgo/v4 v4.30.1 h1:4r4U1J6Fhj98NKfSjnPUN7Ze2c6MnAdL0hWw6+LrJpc=
Expand Down
Loading
Loading