diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000000..3e9c82bffe --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,52 @@ +name: "CodeQL Advanced" + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + schedule: + - cron: '20 10 * * 2' + +jobs: + analyze: + name: Analyze (${{ matrix.language }}) + runs-on: ubuntu-latest + permissions: + security-events: write + packages: read + actions: read + contents: read + + strategy: + fail-fast: false + matrix: + include: + # JavaScript/TypeScript explicitly skips compilation + - language: javascript-typescript + build-mode: autobuild + + # C# compiles dynamically via autobuild execution + - language: javascript-typescipt + build-mode: autobuild + + steps: + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + # Initializes the CodeQL tools with optional matrix keys + - name: Initialize CodeQL + uses: github/codeql-action/init@24c54180a607b1449ed407dd24f251e4e9147c8d # v4.38.3 + with: + languages: ${{ matrix.language }} + build-mode: ${{ matrix.build-mode }} + + # Runs compilation rules dynamically ONLY when explicitly set in matrix properties + - name: Autobuild + if: matrix.build-mode == 'autobuild' + uses: github/codeql-action/autobuild@24c54180a607b1449ed407dd24f251e4e9147c8d # v4.38.3 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@24c54180a607b1449ed407dd24f251e4e9147c8d # v4.38.3 + with: + category: "/language:${{ matrix.language }}" diff --git a/.github/workflows/codeqlaxe.yml b/.github/workflows/codeqlaxe.yml new file mode 100644 index 0000000000..d479cd1d03 --- /dev/null +++ b/.github/workflows/codeqlaxe.yml @@ -0,0 +1,51 @@ +name: "CodeQL Advanced" + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + schedule: + - cron: '20 10 * * *' + +jobs: + analyze: + name: Analyze (${{ matrix.language }}) + runs-on: ubuntu-latest + permissions: + security-events: write + packages: read + actions: read + contents: read + + strategy: + fail-fast: false + matrix: + include: + # JavaScript/TypeScript explicitly skips compilation + - language: javascript-typescript + build-mode: none + + # C# compiles dynamically via autobuild execution + - language: csharp + build-mode: manual + + steps: + - name: Checkout repository + uses: actions/checkout # v4.2.2 + + # Initializes the CodeQL tools with optional matrix keys + - name: Initialize CodeQL + uses: github/codeql-action/init # v4.38.3 + with: + languages: ${{ matrix.language }} + + # Runs compilation rules dynamically ONLY when explicitly set in matrix properties + - name: Autobuild + if: matrix.build-mode == 'autobuild' + uses: github/codeql-action/autobuild # v4.38.3 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze # v4.38.3 + with: + category: "/language:${{ matrix.language }}" diff --git a/go.mod b/go.mod index 6e854e8103..16c3f58309 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/github/github-mcp-server/v2 go 1.27.3 require ( - github.com/go-chi/chi/v5 v5.3.2 + github.com/go-chi/chi/v5 v5.4.0 github.com/go-viper/mapstructure/v2 v2.5.0 github.com/google/go-github/v92 v92.0.0 github.com/google/jsonschema-go v0.4.3 diff --git a/go.sum b/go.sum index bfa3c4dbae..7ea89c993b 100644 --- a/go.sum +++ b/go.sum @@ -5,8 +5,8 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= -github.com/go-chi/chi/v5 v5.3.2 h1:5YQkICvTCSZ25hoRsyJazN0scjzKGiu4VAUc7H1o1nY= -github.com/go-chi/chi/v5 v5.3.2/go.mod h1:R+tYY2hNuVUUjxoPtqUdgBqevM9s9njzkTLutVsOCto= +github.com/go-chi/chi/v5 v5.4.0 h1:+ufzvFTGKyin26Or5DLrlIDq4ygIDBVcj7oVNeeaYFE= +github.com/go-chi/chi/v5 v5.4.0/go.mod h1:d1IG7GtKPSjPyBP365PH8sAGVHk3qfB/IhjFNRH1wWM= github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY= diff --git a/pkg/errors/error.go b/pkg/errors/error.go index 7c9fb049e1..0c1bddae19 100644 --- a/pkg/errors/error.go +++ b/pkg/errors/error.go @@ -6,7 +6,9 @@ import ( stderrors "errors" "fmt" "net/http" + "slices" "strings" + "sync" "time" "github.com/github/github-mcp-server/v2/pkg/sanitize" @@ -21,7 +23,7 @@ type GitHubAPIError struct { Err error `json:"-"` } -// NewGitHubAPIError creates a new GitHubAPIError with the provided message, response, and error. +// newGitHubAPIError creates a new GitHubAPIError with the provided message, response, and error. func newGitHubAPIError(message string, resp *github.Response, err error) *GitHubAPIError { return &GitHubAPIError{ Message: message, @@ -31,7 +33,20 @@ func newGitHubAPIError(message string, resp *github.Response, err error) *GitHub } func (e *GitHubAPIError) Error() string { - return fmt.Errorf("%s: %w", e.Message, e.Err).Error() + if e == nil { + return "" + } + if e.Err == nil { + return e.Message + } + return fmt.Sprintf("%s: %v", e.Message, e.Err) +} + +func (e *GitHubAPIError) Unwrap() error { + if e == nil { + return nil + } + return e.Err } type GitHubGraphQLError struct { @@ -47,7 +62,20 @@ func newGitHubGraphQLError(message string, err error) *GitHubGraphQLError { } func (e *GitHubGraphQLError) Error() string { - return fmt.Errorf("%s: %w", e.Message, e.Err).Error() + if e == nil { + return "" + } + if e.Err == nil { + return e.Message + } + return fmt.Sprintf("%s: %v", e.Message, e.Err) +} + +func (e *GitHubGraphQLError) Unwrap() error { + if e == nil { + return nil + } + return e.Err } type GitHubRawAPIError struct { @@ -65,11 +93,26 @@ func newGitHubRawAPIError(message string, resp *http.Response, err error) *GitHu } func (e *GitHubRawAPIError) Error() string { - return fmt.Errorf("%s: %w", e.Message, e.Err).Error() + if e == nil { + return "" + } + if e.Err == nil { + return e.Message + } + return fmt.Sprintf("%s: %v", e.Message, e.Err) +} + +func (e *GitHubRawAPIError) Unwrap() error { + if e == nil { + return nil + } + return e.Err } type GitHubErrorKey struct{} + type GitHubCtxErrors struct { + mu sync.Mutex api []*GitHubAPIError graphQL []*GitHubGraphQLError raw []*GitHubRawAPIError @@ -80,13 +123,13 @@ func ContextWithGitHubErrors(ctx context.Context) context.Context { if ctx == nil { ctx = context.Background() } - if val, ok := ctx.Value(GitHubErrorKey{}).(*GitHubCtxErrors); ok { - // If the context already has GitHubCtxErrors, we just empty the slices to start fresh + if val, ok := ctx.Value(GitHubErrorKey{}).(*GitHubCtxErrors); ok && val != nil { + val.mu.Lock() val.api = []*GitHubAPIError{} val.graphQL = []*GitHubGraphQLError{} val.raw = []*GitHubRawAPIError{} + val.mu.Unlock() } else { - // If not, we create a new GitHubCtxErrors and set it in the context ctx = context.WithValue(ctx, GitHubErrorKey{}, &GitHubCtxErrors{}) } @@ -95,24 +138,39 @@ func ContextWithGitHubErrors(ctx context.Context) context.Context { // GetGitHubAPIErrors retrieves the slice of GitHubAPIErrors from the context. func GetGitHubAPIErrors(ctx context.Context) ([]*GitHubAPIError, error) { - if val, ok := ctx.Value(GitHubErrorKey{}).(*GitHubCtxErrors); ok { - return val.api, nil // return the slice of API errors from the context + if ctx == nil { + return nil, fmt.Errorf("context is nil") + } + if val, ok := ctx.Value(GitHubErrorKey{}).(*GitHubCtxErrors); ok && val != nil { + val.mu.Lock() + defer val.mu.Unlock() + return slices.Clone(val.api), nil } return nil, fmt.Errorf("context does not contain GitHubCtxErrors") } // GetGitHubGraphQLErrors retrieves the slice of GitHubGraphQLErrors from the context. func GetGitHubGraphQLErrors(ctx context.Context) ([]*GitHubGraphQLError, error) { - if val, ok := ctx.Value(GitHubErrorKey{}).(*GitHubCtxErrors); ok { - return val.graphQL, nil // return the slice of GraphQL errors from the context + if ctx == nil { + return nil, fmt.Errorf("context is nil") + } + if val, ok := ctx.Value(GitHubErrorKey{}).(*GitHubCtxErrors); ok && val != nil { + val.mu.Lock() + defer val.mu.Unlock() + return slices.Clone(val.graphQL), nil } return nil, fmt.Errorf("context does not contain GitHubCtxErrors") } // GetGitHubRawAPIErrors retrieves the slice of GitHubRawAPIErrors from the context. func GetGitHubRawAPIErrors(ctx context.Context) ([]*GitHubRawAPIError, error) { - if val, ok := ctx.Value(GitHubErrorKey{}).(*GitHubCtxErrors); ok { - return val.raw, nil // return the slice of raw API errors from the context + if ctx == nil { + return nil, fmt.Errorf("context is nil") + } + if val, ok := ctx.Value(GitHubErrorKey{}).(*GitHubCtxErrors); ok && val != nil { + val.mu.Lock() + defer val.mu.Unlock() + return slices.Clone(val.raw), nil } return nil, fmt.Errorf("context does not contain GitHubCtxErrors") } @@ -134,27 +192,41 @@ func NewGitHubGraphQLErrorToCtx(ctx context.Context, message string, err error) } func addGitHubAPIErrorToContext(ctx context.Context, err *GitHubAPIError) (context.Context, error) { - if val, ok := ctx.Value(GitHubErrorKey{}).(*GitHubCtxErrors); ok { - val.api = append(val.api, err) // append the error to the existing slice in the context + if ctx == nil { + return nil, fmt.Errorf("context is nil") + } + if val, ok := ctx.Value(GitHubErrorKey{}).(*GitHubCtxErrors); ok && val != nil { + val.mu.Lock() + val.api = append(val.api, err) + val.mu.Unlock() return ctx, nil } return nil, fmt.Errorf("context does not contain GitHubCtxErrors") } func addGitHubGraphQLErrorToContext(ctx context.Context, err *GitHubGraphQLError) (context.Context, error) { - if val, ok := ctx.Value(GitHubErrorKey{}).(*GitHubCtxErrors); ok { - val.graphQL = append(val.graphQL, err) // append the error to the existing slice in the context + if ctx == nil { + return nil, fmt.Errorf("context is nil") + } + if val, ok := ctx.Value(GitHubErrorKey{}).(*GitHubCtxErrors); ok && val != nil { + val.mu.Lock() + val.graphQL = append(val.graphQL, err) + val.mu.Unlock() return ctx, nil } return nil, fmt.Errorf("context does not contain GitHubCtxErrors") } func addRawAPIErrorToContext(ctx context.Context, err *GitHubRawAPIError) (context.Context, error) { - if val, ok := ctx.Value(GitHubErrorKey{}).(*GitHubCtxErrors); ok { + if ctx == nil { + return nil, fmt.Errorf("context is nil") + } + if val, ok := ctx.Value(GitHubErrorKey{}).(*GitHubCtxErrors); ok && val != nil { + val.mu.Lock() val.raw = append(val.raw, err) + val.mu.Unlock() return ctx, nil } - return nil, fmt.Errorf("context does not contain GitHubCtxErrors") } @@ -165,7 +237,8 @@ func NewGitHubAPIErrorResponse(ctx context.Context, message string, resp *github _, _ = addGitHubAPIErrorToContext(ctx, apiErr) // Explicitly ignore error for graceful handling } - if rateLimitErr, ok := stderrors.AsType[*github.RateLimitError](err); ok { + var rateLimitErr *github.RateLimitError + if stderrors.As(err, &rateLimitErr) && rateLimitErr != nil { resetTime := rateLimitErr.Rate.Reset.Time if !resetTime.IsZero() { retryIn := time.Until(resetTime).Round(time.Second) @@ -178,7 +251,8 @@ func NewGitHubAPIErrorResponse(ctx context.Context, message string, resp *github "%s: GitHub API rate limit exceeded. Wait before retrying.", message)) } - if abuseErr, ok := stderrors.AsType[*github.AbuseRateLimitError](err); ok { + var abuseErr *github.AbuseRateLimitError + if stderrors.As(err, &abuseErr) && abuseErr != nil { if abuseErr.RetryAfter != nil { retryAfter := abuseErr.RetryAfter.Round(time.Second) if retryAfter > 0 { @@ -198,7 +272,7 @@ func NewGitHubAPIErrorResponse(ctx context.Context, message string, resp *github // including request or response metadata from the underlying HTTP exchange. func formatGitHubValidationError(resp *github.Response, err error) error { var ghErr *github.ErrorResponse - if !stderrors.As(err, &ghErr) { + if !stderrors.As(err, &ghErr) || ghErr == nil { return err } @@ -206,7 +280,7 @@ func formatGitHubValidationError(resp *github.Response, err error) error { if ghErr.Response != nil { statusCode = ghErr.Response.StatusCode } - if statusCode == 0 && resp != nil { + if statusCode == 0 && resp != nil && resp.Response != nil { statusCode = resp.StatusCode } if statusCode != http.StatusUnprocessableEntity { @@ -280,7 +354,12 @@ func NewGitHubRawAPIErrorResponse(ctx context.Context, message string, resp *htt // but returns an unexpected HTTP status code. It creates a synthetic error from the // status code and response body, then records it in context for observability tracking. func NewGitHubAPIStatusErrorResponse(ctx context.Context, message string, resp *github.Response, body []byte) *mcp.CallToolResult { - err := fmt.Errorf("unexpected status %d: %s", resp.StatusCode, string(body)) + var err error + if resp != nil && resp.Response != nil { + err = fmt.Errorf("unexpected status %d: %s", resp.StatusCode, string(body)) + } else { + err = fmt.Errorf("unexpected status: %s", string(body)) + } return NewGitHubAPIErrorResponse(ctx, message, resp, err) } @@ -306,6 +385,9 @@ type StructuredResolutionError struct { // Error implements the error interface; the message is the JSON body so that the // downstream tool result also carries the structured payload as plain text. func (e *StructuredResolutionError) Error() string { + if e == nil { + return `{"error":"unknown"}` + } b, err := json.Marshal(e) if err != nil { return fmt.Sprintf(`{"error":%q,"name":%q}`, e.Kind, e.Name) @@ -326,5 +408,8 @@ func NewStructuredResolutionError(kind, name, hint string, candidates []any) *St // NewStructuredResolutionErrorResponse returns an mcp.CallToolResult whose text body // is the JSON-serialised StructuredResolutionError, suitable for agent self-correction. func NewStructuredResolutionErrorResponse(err *StructuredResolutionError) *mcp.CallToolResult { + if err == nil { + return utils.NewToolResultError(`{"error":"unknown"}`) + } return utils.NewToolResultError(err.Error()) } diff --git a/third-party-licenses.darwin.md b/third-party-licenses.darwin.md index 5868e15ae9..087aadd8d2 100644 --- a/third-party-licenses.darwin.md +++ b/third-party-licenses.darwin.md @@ -15,7 +15,7 @@ The following packages are included for the amd64, arm64 architectures. - [github.com/aymerick/douceur](https://pkg.go.dev/github.com/aymerick/douceur) ([MIT](https://github.com/aymerick/douceur/blob/v0.2.0/LICENSE)) - [github.com/fsnotify/fsnotify](https://pkg.go.dev/github.com/fsnotify/fsnotify) ([BSD-3-Clause](https://github.com/fsnotify/fsnotify/blob/v1.9.0/LICENSE)) - [github.com/github/github-mcp-server/v2](https://pkg.go.dev/github.com/github/github-mcp-server/v2) ([MIT](https://github.com/github/github-mcp-server/blob/HEAD/LICENSE)) - - [github.com/go-chi/chi/v5](https://pkg.go.dev/github.com/go-chi/chi/v5) ([MIT](https://github.com/go-chi/chi/blob/v5.3.2/LICENSE)) + - [github.com/go-chi/chi/v5](https://pkg.go.dev/github.com/go-chi/chi/v5) ([MIT](https://github.com/go-chi/chi/blob/v5.4.0/LICENSE)) - [github.com/go-viper/mapstructure/v2](https://pkg.go.dev/github.com/go-viper/mapstructure/v2) ([MIT](https://github.com/go-viper/mapstructure/blob/v2.5.0/LICENSE)) - [github.com/google/go-github/v92/github](https://pkg.go.dev/github.com/google/go-github/v92/github) ([BSD-3-Clause](https://github.com/google/go-github/blob/v92.0.0/LICENSE)) - [github.com/google/go-querystring/query](https://pkg.go.dev/github.com/google/go-querystring/query) ([BSD-3-Clause](https://github.com/google/go-querystring/blob/v1.2.0/LICENSE)) diff --git a/third-party-licenses.linux.md b/third-party-licenses.linux.md index b305cf81e5..d7823d862b 100644 --- a/third-party-licenses.linux.md +++ b/third-party-licenses.linux.md @@ -15,7 +15,7 @@ The following packages are included for the 386, amd64, arm64 architectures. - [github.com/aymerick/douceur](https://pkg.go.dev/github.com/aymerick/douceur) ([MIT](https://github.com/aymerick/douceur/blob/v0.2.0/LICENSE)) - [github.com/fsnotify/fsnotify](https://pkg.go.dev/github.com/fsnotify/fsnotify) ([BSD-3-Clause](https://github.com/fsnotify/fsnotify/blob/v1.9.0/LICENSE)) - [github.com/github/github-mcp-server/v2](https://pkg.go.dev/github.com/github/github-mcp-server/v2) ([MIT](https://github.com/github/github-mcp-server/blob/HEAD/LICENSE)) - - [github.com/go-chi/chi/v5](https://pkg.go.dev/github.com/go-chi/chi/v5) ([MIT](https://github.com/go-chi/chi/blob/v5.3.2/LICENSE)) + - [github.com/go-chi/chi/v5](https://pkg.go.dev/github.com/go-chi/chi/v5) ([MIT](https://github.com/go-chi/chi/blob/v5.4.0/LICENSE)) - [github.com/go-viper/mapstructure/v2](https://pkg.go.dev/github.com/go-viper/mapstructure/v2) ([MIT](https://github.com/go-viper/mapstructure/blob/v2.5.0/LICENSE)) - [github.com/google/go-github/v92/github](https://pkg.go.dev/github.com/google/go-github/v92/github) ([BSD-3-Clause](https://github.com/google/go-github/blob/v92.0.0/LICENSE)) - [github.com/google/go-querystring/query](https://pkg.go.dev/github.com/google/go-querystring/query) ([BSD-3-Clause](https://github.com/google/go-querystring/blob/v1.2.0/LICENSE)) diff --git a/third-party-licenses.windows.md b/third-party-licenses.windows.md index cd62776f35..0ef1daa3af 100644 --- a/third-party-licenses.windows.md +++ b/third-party-licenses.windows.md @@ -15,7 +15,7 @@ The following packages are included for the 386, amd64, arm64 architectures. - [github.com/aymerick/douceur](https://pkg.go.dev/github.com/aymerick/douceur) ([MIT](https://github.com/aymerick/douceur/blob/v0.2.0/LICENSE)) - [github.com/fsnotify/fsnotify](https://pkg.go.dev/github.com/fsnotify/fsnotify) ([BSD-3-Clause](https://github.com/fsnotify/fsnotify/blob/v1.9.0/LICENSE)) - [github.com/github/github-mcp-server/v2](https://pkg.go.dev/github.com/github/github-mcp-server/v2) ([MIT](https://github.com/github/github-mcp-server/blob/HEAD/LICENSE)) - - [github.com/go-chi/chi/v5](https://pkg.go.dev/github.com/go-chi/chi/v5) ([MIT](https://github.com/go-chi/chi/blob/v5.3.2/LICENSE)) + - [github.com/go-chi/chi/v5](https://pkg.go.dev/github.com/go-chi/chi/v5) ([MIT](https://github.com/go-chi/chi/blob/v5.4.0/LICENSE)) - [github.com/go-viper/mapstructure/v2](https://pkg.go.dev/github.com/go-viper/mapstructure/v2) ([MIT](https://github.com/go-viper/mapstructure/blob/v2.5.0/LICENSE)) - [github.com/google/go-github/v92/github](https://pkg.go.dev/github.com/google/go-github/v92/github) ([BSD-3-Clause](https://github.com/google/go-github/blob/v92.0.0/LICENSE)) - [github.com/google/go-querystring/query](https://pkg.go.dev/github.com/google/go-querystring/query) ([BSD-3-Clause](https://github.com/google/go-querystring/blob/v1.2.0/LICENSE)) diff --git a/ui/package-lock.json b/ui/package-lock.json index bf773f62c6..7633eef3d7 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -18,7 +18,7 @@ "react-dom": "^19.3.0", "react-markdown": "^10.1.0", "remark-gfm": "^4.0.1", - "zod": "^4.2.0" + "zod": "^4.6.7" }, "devDependencies": { "@types/node": "^26.6.5", @@ -26,7 +26,7 @@ "@types/react-dom": "^19.3.0", "@vitejs/plugin-react": "^6.1.2", "typescript": "^7.0.2", - "vite": "^8.3.2", + "vite": "^8.3.5", "vite-plugin-singlefile": "^2.3.3" }, "engines": { @@ -143,9 +143,9 @@ "license": "BSD-3-Clause" }, "node_modules/@oxc-project/types": { - "version": "0.152.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.152.0.tgz", - "integrity": "sha512-oM/5rLBm2tPkg0iBgkH/FOeR3PCDpY19GTgAZjMFM8h9WI9VW7cLgzp6nwtarYKmovavIQZ+Fe/RKX/8C8O/Rw==", + "version": "0.155.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.155.0.tgz", + "integrity": "sha512-SeE8JPwW1xs1tHeNycjUtUBdhorRa8o4jlvjwk49R7/Z291i+4DQa7JJIgOm/TaYQZx+QrPQbVJ/9c8dMIZN8Q==", "dev": true, "license": "MIT", "funding": { @@ -236,9 +236,9 @@ } }, "node_modules/@rolldown/binding-android-arm-eabi": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.12.tgz", - "integrity": "sha512-dB/a1214qKfHMXCpgqR4OZT+jS4kTyEXbQGJPqzobt5EwH5rX080pxE37alt3RzvR1bf1Yz/yGqRfrYAxuPw0A==", + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.15.tgz", + "integrity": "sha512-aLcgK9gIJ3YRvrrtfSBbRa27F5WrpiTaPulnFpsHPxpUHgFlSgnU4854MHwoRGEBhfRJDWCS2WQ7lIjskE9Olw==", "cpu": [ "arm" ], @@ -253,9 +253,9 @@ } }, "node_modules/@rolldown/binding-android-arm64": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.12.tgz", - "integrity": "sha512-7KHFgQ5VJxIHcLlrwrc3Xbds7oTNQT7Pgi9gQCJKrd2VGab/UksIOYp6VD8MzCstGxOKMgNamPwUCfxPdP1OHg==", + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.15.tgz", + "integrity": "sha512-xD7DdZCrbThKuxNg7ooQmvp07ys4J/pnSEMTG3/OdOWl6daC67m/Q4fL78sRHMxTH/N4fGUbYhcPM0MF5WFHkg==", "cpu": [ "arm64" ], @@ -270,9 +270,9 @@ } }, "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.12.tgz", - "integrity": "sha512-3YIhqHD96nA5SaYNRBR16HnGv4oavZvXfD/ayHM+oYZ0WD/8lBAtf6zQua4kEyAvpqrluKXl0lnOBoiNby7x9w==", + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.15.tgz", + "integrity": "sha512-m2WuQ6r0B4OTYxyPpNLtXaMRbRDUbG8YQV2Q3KTdSSK8Th6KHCnC8jVCJt8bvYeSB5WivkkNbc85mKadaSdOxA==", "cpu": [ "arm64" ], @@ -287,9 +287,9 @@ } }, "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.12.tgz", - "integrity": "sha512-UuuJ35MFw4gmFOrE9pEqIV+K3syIKveph+Qc1/ljHZVdoDW4pz/JHR/eMVom+TZGl/5OOvGJOWaOCVt3ZfqhxA==", + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.15.tgz", + "integrity": "sha512-5RtnsHM36nodM9WbMy+zip0LGS/G+y5wro5RHrpOlr4ac24+1zSi9kiV2MP1myZeZ/ifEHfulQcWjnAXzc2C2A==", "cpu": [ "x64" ], @@ -304,9 +304,9 @@ } }, "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.12.tgz", - "integrity": "sha512-uMvssit0a4W+/7D8CbHUvG719mH3R2jwXAlh/XcPvuHTE0g++LymF88DCGNX0HM2rBOn0xrzgXktIB6fLSJBTQ==", + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.15.tgz", + "integrity": "sha512-g3l09pyFqhu+135JKkbkwiKGQmwU5hUMUPJ4VdBADvuqR8d33L6H578rh8m7rtxbdp+VmX/+nzI7nvhSZlzpUQ==", "cpu": [ "x64" ], @@ -321,9 +321,9 @@ } }, "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.12.tgz", - "integrity": "sha512-XcFu0R0xWnwzSf4IQgFH1rJIckPN1pLy2R+4r9IDB7Yfu/ys9cVqfa4pBrMHj7a3gl8mIR4nRNPg0e5IvEVs6g==", + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.15.tgz", + "integrity": "sha512-nIe3VugI97nGQtspPxDqA4sXMUpeiocKIP/CqpY/u/vgbT+alX+cVxu1C/oVBPKg4feNTmYovE91v4DgXvXNwQ==", "cpu": [ "arm" ], @@ -338,13 +338,16 @@ } }, "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.12.tgz", - "integrity": "sha512-260UrKgn8tz39ak+SMDOirKzr7V04M9dWPw5llW00SwBivCZoWcRBKV1d8cXnRkUmSZA3BdiUmBHWk7734Ulpw==", + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.15.tgz", + "integrity": "sha512-iTBjXx+B5QSvgI89lJfmqh4wTh8NabR1YZIIN3hNx4zSG0EVfVqkOvLulNpG4251pbd6/IAmZ/LefVk1Y4rPhw==", "cpu": [ "arm64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -355,13 +358,16 @@ } }, "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.12.tgz", - "integrity": "sha512-5YK1I9SqDkbPgc1IA8BgDl34suqUS2q0KWnBrirm0E51YjOs6eo6dV6jbQfNE/argHRSvd0QUGgtpIoYx+WWpw==", + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.15.tgz", + "integrity": "sha512-uN26XOnVR7rqQupG3V9oAG2EGGatWjcJHOeDOHUFCh4TBWmP2tHTFoVN13aYbwfm0aHqJAEmcwhAu6sooIjfqQ==", "cpu": [ "arm64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -372,13 +378,16 @@ } }, "node_modules/@rolldown/binding-linux-ppc64-gnu": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.12.tgz", - "integrity": "sha512-Rkcrmp7eFRg74yL5fXEU91JEWbdEPLevWwGtXpmhbjlD1StScbWTmO94Bhly+Mo+ketKYkdmM1vNUKeWSlx8cQ==", + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.15.tgz", + "integrity": "sha512-9nWkcdd+H+XhaA3fQIwpHnKIrfx/PQ6rO0pivr78Og07tXlUlctBBJoEYLPfhTmCR/QxEVdn6uPjHV5SymPhdw==", "cpu": [ "ppc64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -389,13 +398,16 @@ } }, "node_modules/@rolldown/binding-linux-s390x-gnu": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.12.tgz", - "integrity": "sha512-qvK4DuAsQc2BSjlx+Xr+IzOIvvxbGZqxFwdWfG6F518Erj0GGISyQbJ6pIappnOxlNPzNHvo/L0BwB30GZ+zVw==", + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.15.tgz", + "integrity": "sha512-Ggh0ciFjLwIusLSLz7LZYEaGdxOAUJXI+Qu5JCbhPJJHEt8vP+IjRATTJheiJsdzzTYgUiHUiw3X1Ea3ZpMBdA==", "cpu": [ "s390x" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -406,13 +418,16 @@ } }, "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.12.tgz", - "integrity": "sha512-Q9uLBO53Xd4QIq1WOycVQyPP1O4HhraEV2qqb3uTrnVw6QZih9duY4vNXOivL1xoUS1/z+W8eF4NMfl2a8Sdjw==", + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.15.tgz", + "integrity": "sha512-FHg60rS6DBePAYZ9X9F67x+JObFdmgn6tupA1C/a3B+CufFmTD4mX+e8M75tCiAO3foR/6xwVBI0KQiI7sn/rw==", "cpu": [ "x64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -423,13 +438,16 @@ } }, "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.12.tgz", - "integrity": "sha512-3IBxWFMjbOZskDPKv8Lf9BCnahlKuHthWkYnyIxOH/QcJrFcS4EmcenthApkwr/5+nEqZlLzeYbxeMaX7A5u4g==", + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.15.tgz", + "integrity": "sha512-/cvV/7v5VGz/moiz0XKRj2dE8DzsKyhIu1KpOvJGPjRywg3yscON889UGvAe8zfiJLHup7VLjBduoGWi3HusWQ==", "cpu": [ "x64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -440,9 +458,9 @@ } }, "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.12.tgz", - "integrity": "sha512-xtX61xg4LKPkPWilZU1ynKClz5Gj4bf74LML4r3eVLWumKnGjoEr1OSHQhMdbBDoYTi+yjrujvpZe2pUnqCrrA==", + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.15.tgz", + "integrity": "sha512-MyzC5Hrv/sm+Z7TSGKP/j8001RO2xQm1zOpCNVL4j0cY/VhBZviludA2YFQ7i4lH6ZAXxQm0lcMdBzM+99mE7w==", "cpu": [ "arm64" ], @@ -457,9 +475,9 @@ } }, "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.12.tgz", - "integrity": "sha512-At7fPB6PCaIjzgIhEZFxuT+BBFqiQibJDT4d3PhiR3f4E7bbMZF4aKblbFfEM3sETRDd1YiQx/+U/g/B/ou5Ew==", + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.15.tgz", + "integrity": "sha512-+PgYiS+AH5omy6L45ZLxybasauJaj3M8buoT83D+nzPmCayXlxUV9hydhciCKVyIg0B/v0BtXPDE1uGqNwCPpg==", "cpu": [ "arm64" ], @@ -474,9 +492,9 @@ } }, "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.12.tgz", - "integrity": "sha512-WIw2haVKwjuYdXkHaoC0mF8Le71TuCBxjrdKqLbJGctbBABj+ClfmNvtbOnzpq3RokNo5+V1qhtSzJyXorsklQ==", + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.15.tgz", + "integrity": "sha512-HFZd2QNQYn1JbIi+Hpd7H+r/lkWxcfIu28nirZ6eCn2LafuvmExMlb/P96Sfx5tf7pPArw39IdhmCF8vmV+NhQ==", "cpu": [ "x64" ], @@ -2614,9 +2632,9 @@ "license": "MIT" }, "node_modules/nanoid": { - "version": "3.3.19", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.19.tgz", - "integrity": "sha512-Y2tUNy4ouw6tq5oDSKeQYGOyhkUBhNOcGV/02KC+6kd9eDGqdZd++mjMiIDilrBYvjEnCYvVtsuHCuP+okSfug==", + "version": "3.3.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.20.tgz", + "integrity": "sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==", "dev": true, "funding": [ { @@ -2696,9 +2714,9 @@ } }, "node_modules/postcss": { - "version": "8.5.28", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.28.tgz", - "integrity": "sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==", + "version": "8.5.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.31.tgz", + "integrity": "sha512-YUbWYCgErwnMAVkjUnYa+KlMBzGpHwiIt/DE7f0G33AuX2LH9UcTk6KgWxd3zRU+pN3u/C+Xl3EnMLM4Hea7Sg==", "dev": true, "funding": [ { @@ -2716,9 +2734,9 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.18", + "nanoid": "^3.3.20", "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" + "source-map-js": "^1.2.2" }, "engines": { "node": "^10 || ^12 || >=14" @@ -2871,13 +2889,13 @@ } }, "node_modules/rolldown": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.12.tgz", - "integrity": "sha512-8wafseiaG80xmXSfqidUNqZcylTlhmPZZt+za2m+js2sFZ8dTNlhIOV2WcbIPx2hgwPBJpEUGFAMZ9bgBBLTSQ==", + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.15.tgz", + "integrity": "sha512-6odND+fel5zVw3I4Yc2e69gvguDnX0CAAGiNDZSq4ik5WUcaLrkD2GLuog0XcODbor31hZ5ayEMgVDno+KPV5g==", "dev": true, "license": "MIT", "dependencies": { - "@oxc-project/types": "=0.152.0", + "@oxc-project/types": "=0.155.0", "@rolldown/pluginutils": "^1.0.0" }, "bin": { @@ -2887,21 +2905,21 @@ "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rolldown/binding-android-arm-eabi": "1.2.12", - "@rolldown/binding-android-arm64": "1.2.12", - "@rolldown/binding-darwin-arm64": "1.2.12", - "@rolldown/binding-darwin-x64": "1.2.12", - "@rolldown/binding-freebsd-x64": "1.2.12", - "@rolldown/binding-linux-arm-gnueabihf": "1.2.12", - "@rolldown/binding-linux-arm64-gnu": "1.2.12", - "@rolldown/binding-linux-arm64-musl": "1.2.12", - "@rolldown/binding-linux-ppc64-gnu": "1.2.12", - "@rolldown/binding-linux-s390x-gnu": "1.2.12", - "@rolldown/binding-linux-x64-gnu": "1.2.12", - "@rolldown/binding-linux-x64-musl": "1.2.12", - "@rolldown/binding-openharmony-arm64": "1.2.12", - "@rolldown/binding-win32-arm64-msvc": "1.2.12", - "@rolldown/binding-win32-x64-msvc": "1.2.12" + "@rolldown/binding-android-arm-eabi": "1.2.15", + "@rolldown/binding-android-arm64": "1.2.15", + "@rolldown/binding-darwin-arm64": "1.2.15", + "@rolldown/binding-darwin-x64": "1.2.15", + "@rolldown/binding-freebsd-x64": "1.2.15", + "@rolldown/binding-linux-arm-gnueabihf": "1.2.15", + "@rolldown/binding-linux-arm64-gnu": "1.2.15", + "@rolldown/binding-linux-arm64-musl": "1.2.15", + "@rolldown/binding-linux-ppc64-gnu": "1.2.15", + "@rolldown/binding-linux-s390x-gnu": "1.2.15", + "@rolldown/binding-linux-x64-gnu": "1.2.15", + "@rolldown/binding-linux-x64-musl": "1.2.15", + "@rolldown/binding-openharmony-arm64": "1.2.15", + "@rolldown/binding-win32-arm64-msvc": "1.2.15", + "@rolldown/binding-win32-x64-msvc": "1.2.15" } }, "node_modules/scheduler": { @@ -3191,16 +3209,16 @@ } }, "node_modules/vite": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-8.3.2.tgz", - "integrity": "sha512-SQr1x6W5vVSbROg7vsyXIaxK9b0G7zsT68acdWWRmnBUsgDieLCRG+Rep9WdZgcposvv/GSnr4GUUBqB3vXq6w==", + "version": "8.3.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.3.5.tgz", + "integrity": "sha512-z1YpjieJ9g0ebTmQpLBv/oq9E3F9EIlOe+7LahW8SrE3LTiG3udBRUXQOlYXP9b+IC2q2phHeVxj9xGlw34OEQ==", "dev": true, "license": "MIT", "dependencies": { "lightningcss": "^1.33.0", "picomatch": "^4.0.7", - "postcss": "^8.5.28", - "rolldown": "~1.2.11", + "postcss": "^8.5.30", + "rolldown": "~1.2.14", "tinyglobby": "^0.2.17" }, "bin": { @@ -3217,7 +3235,7 @@ }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", - "@vitejs/devtools": "^0.7.1", + "@vitejs/devtools": "^0.7.1 || ^0.8.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", @@ -3306,9 +3324,9 @@ } }, "node_modules/zod": { - "version": "4.6.5", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.6.5.tgz", - "integrity": "sha512-v5l/aFXZQeai4awLbOpSoHecE9UiMrnfx75tEXLjNonXVARxQ5mOeipTjROUchszUNCqnE+hqAMujRsRHsut2Q==", + "version": "4.6.7", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.6.7.tgz", + "integrity": "sha512-g8W2D2kU6a8untc053fX1uVBKzM7yqAxW/3zwk83+6RyF2+SKOuV+c0wBDhUwzV1PaGapmZH+rmcUzPf+3CGwg==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" diff --git a/ui/package.json b/ui/package.json index 99a14dcaa9..eaf979eb4b 100644 --- a/ui/package.json +++ b/ui/package.json @@ -25,7 +25,7 @@ "react-dom": "^19.3.0", "react-markdown": "^10.1.0", "remark-gfm": "^4.0.1", - "zod": "^4.2.0" + "zod": "^4.6.7" }, "devDependencies": { "@types/node": "^26.6.5", @@ -33,7 +33,7 @@ "@types/react-dom": "^19.3.0", "@vitejs/plugin-react": "^6.1.2", "typescript": "^7.0.2", - "vite": "^8.3.2", + "vite": "^8.3.5", "vite-plugin-singlefile": "^2.3.3" } }