mirror of
https://github.com/browseros-ai/BrowserOS.git
synced 2026-05-13 15:46:22 +00:00
feat: add PostHog to CLI (#603)
* feat: add PostHog usage analytics to CLI Add anonymous command-level analytics to browseros-cli using the PostHog Go SDK. Tracks which commands are executed, their success/failure status, and duration — no PII or person profiles. - New analytics package with Init/Track/Close singleton - Distinct ID resolves from server's browseros_id (server.json), falls back to CLI-generated UUID (~/.config/browseros-cli/install_id) - API key injected at build time via ldflags (dev builds = silent no-op) - Server now writes browseros_id into server.json for cross-surface identity correlation * fix: address PR review feedback for #603 - Return "unknown" for unrecognized args in commandName to avoid sending arbitrary user input to PostHog - Revert goreleaser to {{ .Env.POSTHOG_API_KEY }} (intentional hard fail — release builds must have the key set) - go mod tidy to fix posthog-go direct/indirect marker - Add POSTHOG_API_KEY to .env.production.example
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
# Production upload env for CLI installer scripts
|
||||
# Production build env for CLI
|
||||
|
||||
POSTHOG_API_KEY=
|
||||
|
||||
# Upload env for CLI installer scripts
|
||||
R2_ACCOUNT_ID=
|
||||
R2_ACCESS_KEY_ID=
|
||||
R2_SECRET_ACCESS_KEY=
|
||||
|
||||
@@ -13,7 +13,7 @@ builds:
|
||||
flags:
|
||||
- -trimpath
|
||||
ldflags:
|
||||
- -s -w -X main.version={{ .Version }}
|
||||
- -s -w -X main.version={{ .Version }} -X browseros-cli/analytics.posthogAPIKey={{ .Env.POSTHOG_API_KEY }}
|
||||
targets:
|
||||
- darwin_amd64
|
||||
- darwin_arm64
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
BINARY := browseros-cli
|
||||
SOURCES := $(shell find . -name '*.go')
|
||||
VERSION ?= dev
|
||||
POSTHOG_API_KEY ?=
|
||||
LDFLAGS := -X main.version=$(VERSION) -X browseros-cli/analytics.posthogAPIKey=$(POSTHOG_API_KEY)
|
||||
|
||||
$(BINARY): $(SOURCES)
|
||||
go build -ldflags "-X main.version=$(VERSION)" -o $(BINARY) .
|
||||
go build -ldflags "$(LDFLAGS)" -o $(BINARY) .
|
||||
|
||||
.PHONY: install clean vet test
|
||||
|
||||
install:
|
||||
go install -ldflags "-X main.version=$(VERSION)" .
|
||||
go install -ldflags "$(LDFLAGS)" .
|
||||
|
||||
clean:
|
||||
rm -f $(BINARY)
|
||||
|
||||
129
packages/browseros-agent/apps/cli/analytics/analytics.go
Normal file
129
packages/browseros-agent/apps/cli/analytics/analytics.go
Normal file
@@ -0,0 +1,129 @@
|
||||
package analytics
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"browseros-cli/config"
|
||||
|
||||
"github.com/posthog/posthog-go"
|
||||
)
|
||||
|
||||
var (
|
||||
posthogAPIKey string // set via ldflags
|
||||
posthogHost = "https://us.i.posthog.com"
|
||||
)
|
||||
|
||||
const eventPrefix = "browseros.cli."
|
||||
|
||||
var svc *service
|
||||
|
||||
type service struct {
|
||||
client posthog.Client
|
||||
distinctID string
|
||||
}
|
||||
|
||||
func Init(version string) {
|
||||
if posthogAPIKey == "" {
|
||||
return
|
||||
}
|
||||
|
||||
distinctID := resolveDistinctID()
|
||||
if distinctID == "" {
|
||||
return
|
||||
}
|
||||
|
||||
client, err := posthog.NewWithConfig(posthogAPIKey, posthog.Config{
|
||||
Endpoint: posthogHost,
|
||||
BatchSize: 10,
|
||||
ShutdownTimeout: 3 * time.Second,
|
||||
DefaultEventProperties: posthog.NewProperties().
|
||||
Set("cli_version", version).
|
||||
Set("os", runtime.GOOS).
|
||||
Set("arch", runtime.GOARCH),
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
svc = &service{client: client, distinctID: distinctID}
|
||||
}
|
||||
|
||||
func Track(command string, success bool, duration time.Duration) {
|
||||
if svc == nil {
|
||||
return
|
||||
}
|
||||
svc.client.Enqueue(posthog.Capture{
|
||||
DistinctId: svc.distinctID,
|
||||
Event: eventPrefix + "command_executed",
|
||||
Properties: posthog.NewProperties().
|
||||
Set("command", command).
|
||||
Set("success", success).
|
||||
Set("duration_ms", duration.Milliseconds()).
|
||||
Set("$process_person_profile", false),
|
||||
})
|
||||
}
|
||||
|
||||
func Close() {
|
||||
if svc == nil {
|
||||
return
|
||||
}
|
||||
svc.client.Close()
|
||||
svc = nil
|
||||
}
|
||||
|
||||
func resolveDistinctID() string {
|
||||
if id := loadBrowserosID(); id != "" {
|
||||
return id
|
||||
}
|
||||
return loadOrCreateInstallID()
|
||||
}
|
||||
|
||||
func loadBrowserosID() string {
|
||||
home, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
data, err := os.ReadFile(filepath.Join(home, ".browseros", "server.json"))
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
var sc struct {
|
||||
BrowserosID string `json:"browseros_id"`
|
||||
}
|
||||
if json.Unmarshal(data, &sc) != nil {
|
||||
return ""
|
||||
}
|
||||
return sc.BrowserosID
|
||||
}
|
||||
|
||||
func loadOrCreateInstallID() string {
|
||||
dir := config.Dir()
|
||||
idPath := filepath.Join(dir, "install_id")
|
||||
|
||||
data, err := os.ReadFile(idPath)
|
||||
if err == nil {
|
||||
if id := strings.TrimSpace(string(data)); id != "" {
|
||||
return id
|
||||
}
|
||||
}
|
||||
|
||||
id := generateUUID()
|
||||
os.MkdirAll(dir, 0755)
|
||||
os.WriteFile(idPath, []byte(id), 0644)
|
||||
return id
|
||||
}
|
||||
|
||||
func generateUUID() string {
|
||||
var b [16]byte
|
||||
rand.Read(b[:])
|
||||
b[6] = (b[6] & 0x0f) | 0x40 // version 4
|
||||
b[8] = (b[8] & 0x3f) | 0x80 // variant 2
|
||||
return fmt.Sprintf("%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:])
|
||||
}
|
||||
132
packages/browseros-agent/apps/cli/analytics/analytics_test.go
Normal file
132
packages/browseros-agent/apps/cli/analytics/analytics_test.go
Normal file
@@ -0,0 +1,132 @@
|
||||
package analytics
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestGenerateUUID(t *testing.T) {
|
||||
id := generateUUID()
|
||||
uuidRe := regexp.MustCompile(`^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$`)
|
||||
if !uuidRe.MatchString(id) {
|
||||
t.Errorf("generateUUID() = %q, does not match UUID v4 pattern", id)
|
||||
}
|
||||
|
||||
id2 := generateUUID()
|
||||
if id == id2 {
|
||||
t.Error("generateUUID() returned the same value twice")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadBrowserosID(t *testing.T) {
|
||||
tmp := t.TempDir()
|
||||
t.Setenv("HOME", tmp)
|
||||
|
||||
// No server.json → empty
|
||||
if got := loadBrowserosID(); got != "" {
|
||||
t.Errorf("loadBrowserosID() = %q, want empty", got)
|
||||
}
|
||||
|
||||
// server.json without browseros_id → empty
|
||||
dir := filepath.Join(tmp, ".browseros")
|
||||
os.MkdirAll(dir, 0755)
|
||||
data, _ := json.Marshal(map[string]any{"server_port": 9100, "url": "http://127.0.0.1:9100"})
|
||||
os.WriteFile(filepath.Join(dir, "server.json"), data, 0644)
|
||||
|
||||
if got := loadBrowserosID(); got != "" {
|
||||
t.Errorf("loadBrowserosID() = %q, want empty (no browseros_id field)", got)
|
||||
}
|
||||
|
||||
// server.json with browseros_id → returns it
|
||||
data, _ = json.Marshal(map[string]any{
|
||||
"server_port": 9100,
|
||||
"url": "http://127.0.0.1:9100",
|
||||
"browseros_id": "test-uuid-1234",
|
||||
})
|
||||
os.WriteFile(filepath.Join(dir, "server.json"), data, 0644)
|
||||
|
||||
if got := loadBrowserosID(); got != "test-uuid-1234" {
|
||||
t.Errorf("loadBrowserosID() = %q, want %q", got, "test-uuid-1234")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadOrCreateInstallID(t *testing.T) {
|
||||
tmp := t.TempDir()
|
||||
configDir := filepath.Join(tmp, "browseros-cli")
|
||||
t.Setenv("XDG_CONFIG_HOME", tmp)
|
||||
|
||||
// First call creates the file
|
||||
id := loadOrCreateInstallID()
|
||||
if id == "" {
|
||||
t.Fatal("loadOrCreateInstallID() returned empty string")
|
||||
}
|
||||
|
||||
// File was persisted
|
||||
data, err := os.ReadFile(filepath.Join(configDir, "install_id"))
|
||||
if err != nil {
|
||||
t.Fatalf("install_id file not created: %v", err)
|
||||
}
|
||||
if string(data) != id {
|
||||
t.Errorf("persisted id = %q, want %q", string(data), id)
|
||||
}
|
||||
|
||||
// Second call returns the same ID
|
||||
id2 := loadOrCreateInstallID()
|
||||
if id2 != id {
|
||||
t.Errorf("loadOrCreateInstallID() = %q, want stable %q", id2, id)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolveDistinctID_PrefersBrowserosID(t *testing.T) {
|
||||
tmp := t.TempDir()
|
||||
t.Setenv("HOME", tmp)
|
||||
t.Setenv("XDG_CONFIG_HOME", tmp)
|
||||
|
||||
// Write server.json with browseros_id
|
||||
dir := filepath.Join(tmp, ".browseros")
|
||||
os.MkdirAll(dir, 0755)
|
||||
data, _ := json.Marshal(map[string]any{"browseros_id": "server-uuid"})
|
||||
os.WriteFile(filepath.Join(dir, "server.json"), data, 0644)
|
||||
|
||||
got := resolveDistinctID()
|
||||
if got != "server-uuid" {
|
||||
t.Errorf("resolveDistinctID() = %q, want %q", got, "server-uuid")
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolveDistinctID_FallsBackToInstallID(t *testing.T) {
|
||||
tmp := t.TempDir()
|
||||
t.Setenv("HOME", tmp)
|
||||
t.Setenv("XDG_CONFIG_HOME", tmp)
|
||||
|
||||
// No server.json → should generate install_id
|
||||
got := resolveDistinctID()
|
||||
if got == "" {
|
||||
t.Error("resolveDistinctID() returned empty string")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInitNoopsWithoutAPIKey(t *testing.T) {
|
||||
old := posthogAPIKey
|
||||
posthogAPIKey = ""
|
||||
defer func() { posthogAPIKey = old }()
|
||||
|
||||
Init("1.0.0")
|
||||
if svc != nil {
|
||||
t.Error("Init() created service without API key")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTrackAndCloseNoopWithoutInit(t *testing.T) {
|
||||
old := svc
|
||||
svc = nil
|
||||
defer func() { svc = old }()
|
||||
|
||||
// Should not panic
|
||||
Track("test", true, time.Second)
|
||||
Close()
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"browseros-cli/analytics"
|
||||
"browseros-cli/config"
|
||||
"browseros-cli/mcp"
|
||||
"browseros-cli/output"
|
||||
@@ -113,11 +114,27 @@ var rootCmd = &cobra.Command{
|
||||
}
|
||||
|
||||
func Execute() {
|
||||
if err := rootCmd.Execute(); err != nil {
|
||||
analytics.Init(version)
|
||||
start := time.Now()
|
||||
|
||||
err := rootCmd.Execute()
|
||||
|
||||
analytics.Track(commandName(os.Args[1:]), err == nil, time.Since(start))
|
||||
analytics.Close()
|
||||
|
||||
if err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func commandName(args []string) string {
|
||||
cmd, _, err := rootCmd.Find(args)
|
||||
if err != nil || cmd == rootCmd {
|
||||
return "unknown"
|
||||
}
|
||||
return cmd.CommandPath()
|
||||
}
|
||||
|
||||
func init() {
|
||||
cobra.AddTemplateFunc("helpHeader", helpHeader)
|
||||
cobra.AddTemplateFunc("helpCmdCol", helpCmdCol)
|
||||
|
||||
25
packages/browseros-agent/apps/cli/cmd/root_test.go
Normal file
25
packages/browseros-agent/apps/cli/cmd/root_test.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package cmd
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestCommandName(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
args []string
|
||||
want string
|
||||
}{
|
||||
{"empty args", nil, "unknown"},
|
||||
{"known command", []string{"health"}, "browseros-cli health"},
|
||||
{"unknown command", []string{"nonexistent"}, "unknown"},
|
||||
{"subcommand", []string{"bookmark", "search"}, "browseros-cli bookmark search"},
|
||||
{"known with extra args", []string{"snap", "--enhanced"}, "browseros-cli snap"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := commandName(tt.args)
|
||||
if got != tt.want {
|
||||
t.Errorf("commandName(%v) = %q, want %q", tt.args, got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -4,20 +4,24 @@ go 1.25.7
|
||||
|
||||
require (
|
||||
github.com/fatih/color v1.18.0
|
||||
github.com/modelcontextprotocol/go-sdk v1.4.0
|
||||
github.com/posthog/posthog-go v1.11.2
|
||||
github.com/spf13/cobra v1.10.2
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/goccy/go-json v0.10.5 // indirect
|
||||
github.com/google/jsonschema-go v0.4.2 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/modelcontextprotocol/go-sdk v1.4.0 // indirect
|
||||
github.com/segmentio/asm v1.1.3 // indirect
|
||||
github.com/segmentio/encoding v0.5.3 // indirect
|
||||
github.com/spf13/pflag v1.0.9 // indirect
|
||||
github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
|
||||
golang.org/x/oauth2 v0.34.0 // indirect
|
||||
golang.org/x/sys v0.40.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
@@ -1,8 +1,20 @@
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
|
||||
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
|
||||
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
|
||||
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
|
||||
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8=
|
||||
github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
|
||||
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/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
@@ -12,6 +24,10 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/modelcontextprotocol/go-sdk v1.4.0 h1:u0kr8lbJc1oBcawK7Df+/ajNMpIDFE41OEPxdeTLOn8=
|
||||
github.com/modelcontextprotocol/go-sdk v1.4.0/go.mod h1:Nxc2n+n/GdCebUaqCOhTetptS17SXXNu9IfNTaLDi1E=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/posthog/posthog-go v1.11.2 h1:ApKTtOhIeWhUBc4ByO+mlbg2o0iZaEGJnJHX2QDnn5Q=
|
||||
github.com/posthog/posthog-go v1.11.2/go.mod h1:xsVOW9YImilUcazwPNEq4PJDqEZf2KeCS758zXjwkPg=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/segmentio/asm v1.1.3 h1:WM03sfUOENvvKexOLp+pCqgb/WDjsi7EK8gIsICtzhc=
|
||||
github.com/segmentio/asm v1.1.3/go.mod h1:Ld3L4ZXGNcSLRg4JBsZ3//1+f/TjYl0Mzen/DQy1EJg=
|
||||
@@ -21,6 +37,8 @@ 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/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4=
|
||||
github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4=
|
||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||
@@ -28,10 +46,11 @@ golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
|
||||
golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
||||
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.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
||||
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
|
||||
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc=
|
||||
golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
@@ -116,6 +116,7 @@ export class Application {
|
||||
server_version: VERSION,
|
||||
browseros_version: this.config.instanceBrowserosVersion,
|
||||
chromium_version: this.config.instanceChromiumVersion,
|
||||
browseros_id: identity.getBrowserOSId(),
|
||||
})
|
||||
} catch (error) {
|
||||
logger.warn('Failed to write server config for auto-discovery', {
|
||||
|
||||
@@ -13,4 +13,5 @@ export interface ServerDiscoveryConfig {
|
||||
server_version: string
|
||||
browseros_version?: string
|
||||
chromium_version?: string
|
||||
browseros_id?: string
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user