├── .gitignore ├── Dockerfile ├── LICENSE ├── Makefile ├── README.md ├── hack ├── build.sh └── get_protos.sh └── src ├── cmd ├── flags.go ├── get.go ├── getExtension.go ├── getExtensionIndex.go ├── getLatestRelease.go ├── root.go ├── serve.go └── version.go ├── go.mod ├── go.sum ├── llm ├── openai_compatible.go └── openai_compatible_test.go ├── main.go ├── utils ├── concurrent_counter.go ├── concurrent_map.go ├── concurrent_map_test.go ├── dir.go ├── env.go ├── hash.go └── ifelse.go └── zed ├── api.go ├── api_controller.go ├── client.go ├── client_test.go ├── client_users.go ├── edit_predict.go ├── extension.go ├── pb ├── ai.pb.go ├── ai.proto ├── app.pb.go ├── app.proto ├── binary_input_file ├── buf.yaml ├── buffer.pb.go ├── buffer.proto ├── call.pb.go ├── call.proto ├── channel.pb.go ├── channel.proto ├── core.pb.go ├── core.proto ├── debugger.pb.go ├── debugger.proto ├── git.pb.go ├── git.proto ├── lsp.pb.go ├── lsp.proto ├── notification.pb.go ├── notification.proto ├── task.pb.go ├── task.proto ├── toolchain.pb.go ├── toolchain.proto ├── worktree.pb.go ├── worktree.proto ├── zed.pb.go └── zed.proto ├── release_notes.go ├── rpc.go └── version.go /.gitignore: -------------------------------------------------------------------------------- 1 | .zedex-cache 2 | zedex 3 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.24-alpine AS builder 2 | RUN apk update && apk add make git &&\ 3 | rm -rf /var/cache/apk/* 4 | WORKDIR /app 5 | COPY hack hack 6 | COPY src src 7 | COPY .git .git 8 | COPY Makefile . 9 | RUN make build 10 | 11 | FROM scratch 12 | COPY --from=builder /app/zedex /bin/zedex 13 | ENTRYPOINT [ "/bin/zedex" ] 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Magnus F 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | get-protos: 2 | bash hack/get_protos.sh 3 | 4 | .PHONY=build 5 | build: 6 | sh hack/build.sh 7 | 8 | .PHONY=build-docker 9 | build-docker: 10 | docker build -t zedex:build . 11 | 12 | .PHONY=push-docker 13 | push-docker: build-docker 14 | docker tag zedex:build praktiskt/zedex:latest &&\ 15 | docker push praktiskt/zedex:latest 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # zedex 2 | 3 | Self-hosted Zed server. 4 | 5 | `zedex` can currently; 6 | * Download the extension index 7 | * Download individual extensions 8 | * Download the latest release, and its release notes 9 | * Serve the downloaded extension index and downloaded extensions 10 | * List the latest version of Zed, and store a reference to it (version+url), and its release notes 11 | * Log in anonymously. 12 | * Use any OpenAI-compatible backend for edit prediction 13 | * Note: It works, kind of, but needs more work. 14 | * (Be a transparent Zed proxy, to see what calls Zed makes) 15 | 16 | ## Usage 17 | 18 | ### Offline usage 19 | ```sh 20 | # Download and write the index to .zedex-cache/extensions.json 21 | zedex get extension-index 22 | 23 | # Download all extensions to .zedex-cache/.tar.gz 24 | zedex get extension $(cat .zedex-cache/extensions.json | jq -r '.data[].id' | xargs) 25 | 26 | # Download info about the latest release to .zedex-cache/latest_release.json 27 | zedex get latest-release 28 | 29 | # Serve the downloaded index, its extensions and info about the latest release 30 | zedex serve --port=8080 31 | 32 | # You can run certain features in "passthrough" mode by disabling them in zedex. The 33 | # following command will fetch extensions and releases from zed, but handle the rest 34 | # of the calls itself. 35 | zedex serve --enable-extension-store=false --enable-releases=false 36 | ``` 37 | 38 | Modify the Zed-settings file (`settings.json`) to use the proxy: 39 | ```json 40 | { 41 | "server_url": "http://localhost:8080" 42 | } 43 | ``` 44 | 45 | ## Edit Prediction 46 | In order to use this, you must be logged into Zed (edit prediction is login-gated by the Zed client). `zedex` supports an anonymous login which does the trick. You can also use the real login and just set `ZED_PREDICT_EDITS_URL`. 47 | 48 | ### Zedex configuration 49 | Running `zedex` with `--enable-edit-prediction` (default) allows you to configure an OpenAI compatible backend to manage your requests. Set the following environment variables if you wish; 50 | ```sh 51 | # If you do not want to use edit prediction, you can disable it. 52 | # export OPENAI_COMPATIBLE_DISABLE=true 53 | 54 | # Configure a server 55 | export OPENAI_COMPATIBLE_HOST="https://some.url.here/v1/chat/completions" 56 | export OPENAI_COMPATIBLE_API_KEY="add your key here" 57 | export OPENAI_COMPATIBLE_MODEL="name of the model to use" 58 | 59 | # Optionally, you can modify the system prompt. Note that this needs to keep some special tokens intact that Zed ships in its requests. You'll probably need to dig through the zedex source to find how we do it at the moment. 60 | # export OPENAI_COMPATIBLE_SYSTEM_PROMPT="You are a code autocomplete engine." 61 | ``` 62 | 63 | The default for zedex is to use [Groq](https://groq.com/). 64 | 65 | ### Client configuration 66 | You have two options; 67 | * Logging in to `zedex` (just click login if you've set `server_url`). 68 | 69 | OR 70 | 71 | * Set environment variable `ZED_PREDICT_EDITS_URL=http://localhost:8080/predict_edits/v2` and run Zed. 72 | 73 | ## Building 74 | 75 | ```sh 76 | make build 77 | ``` 78 | -------------------------------------------------------------------------------- /hack/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | set -e 4 | 5 | commit_hash() { 6 | git rev-parse HEAD 7 | } 8 | 9 | now() { 10 | date +%Y-%m-%dT%H:%M:%S%z 11 | } 12 | 13 | main() { 14 | LDFLAGS="-s -w -buildid=" 15 | LDFLAGS="$LDFLAGS -X zedex/cmd.GIT_COMMIT_SHA=$(commit_hash)" 16 | LDFLAGS="$LDFLAGS -X zedex/cmd.BUILD_TIME=$(now)" 17 | set -x 18 | CGO_ENABLED=0 go build -C src -trimpath -ldflags="$LDFLAGS" -o ../zedex 19 | } 20 | 21 | main $@ 22 | -------------------------------------------------------------------------------- /hack/get_protos.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -ex 4 | 5 | OUTDIR="./src/zed/pb" 6 | ZED_TEMP_DIR="/tmp/zed-repo" 7 | 8 | clone_dir() { 9 | cleanup 10 | git clone --sparse https://github.com/zed-industries/zed.git "$ZED_TEMP_DIR" --filter=blob:none 11 | pushd "$ZED_TEMP_DIR" 12 | git sparse-checkout set crates/proto/proto 13 | popd 14 | } 15 | 16 | cleanup() { 17 | rm -rf "$ZED_TEMP_DIR" 18 | } 19 | 20 | main() { 21 | clone_dir 22 | mv $ZED_TEMP_DIR/crates/proto/proto/* "$OUTDIR/" 23 | cleanup 24 | pushd $OUTDIR 25 | PROTOS=$(ls | grep -E '\.proto$') 26 | for FILE in $PROTOS; do 27 | if ! grep -q "option go_package" $FILE; then 28 | sed -i '2i option go_package = "./pb";' $FILE 29 | fi 30 | done 31 | protoc --go_out=. --go_opt=paths=source_relative *.proto 32 | popd 33 | } 34 | 35 | main $@ 36 | -------------------------------------------------------------------------------- /src/cmd/flags.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "github.com/sirupsen/logrus" 5 | ) 6 | 7 | var baseFlags struct { 8 | debug bool 9 | } 10 | 11 | func manageDefaultFlags() { 12 | if baseFlags.debug { 13 | logrus.SetReportCaller(true) 14 | logrus.SetLevel(logrus.DebugLevel) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/cmd/get.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | ) 6 | 7 | var getCmd = &cobra.Command{ 8 | Use: "get", 9 | } 10 | 11 | func init() { 12 | rootCmd.AddCommand(getCmd) 13 | } 14 | -------------------------------------------------------------------------------- /src/cmd/getExtension.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "os" 5 | "path" 6 | 7 | "zedex/utils" 8 | "zedex/zed" 9 | 10 | "github.com/remeh/sizedwaitgroup" 11 | log "github.com/sirupsen/logrus" 12 | "github.com/spf13/cobra" 13 | ) 14 | 15 | var getExtensionCmdConfig = struct { 16 | outputDir string 17 | }{} 18 | 19 | var getExtensionCmd = &cobra.Command{ 20 | Use: "extension", 21 | PreRun: func(cmd *cobra.Command, args []string) { manageDefaultFlags() }, 22 | Run: func(cmd *cobra.Command, args []string) { 23 | zc := zed.NewZedClient(1) 24 | swg := sizedwaitgroup.New(20) 25 | for _, id := range args { 26 | swg.Add() 27 | go func() { 28 | defer swg.Done() 29 | log.Infof("(extension=%v) downloading", id) 30 | bytes, err := zc.DownloadExtensionArchiveDefault(zed.Extension{ID: id}) 31 | if err != nil { 32 | log.Errorf("(extension=%v) %v", err.Error()) 33 | return 34 | } 35 | 36 | utils.CreateDirIfNotExists(getExtensionCmdConfig.outputDir) 37 | err = os.WriteFile(path.Join(getExtensionCmdConfig.outputDir, id+".tar.gz"), bytes, 0o644) 38 | if err != nil { 39 | log.Errorf("(extension=%v) %v", err.Error()) 40 | return 41 | } 42 | log.Infof("(extension=%v) wrote %v bytes", id, len(bytes)) 43 | }() 44 | } 45 | swg.Wait() 46 | }, 47 | } 48 | 49 | func init() { 50 | getCmd.AddCommand(getExtensionCmd) 51 | getExtensionCmd.Flags().StringVar(&getExtensionCmdConfig.outputDir, "output-dir", ".zedex-cache", "output directory") 52 | } 53 | -------------------------------------------------------------------------------- /src/cmd/getExtensionIndex.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "os" 7 | 8 | "zedex/utils" 9 | "zedex/zed" 10 | 11 | log "github.com/sirupsen/logrus" 12 | "github.com/spf13/cobra" 13 | ) 14 | 15 | var getExtensionIndexCmdConfig = struct { 16 | outputDir string 17 | }{} 18 | 19 | var getExtensionIndexCmd = &cobra.Command{ 20 | Use: "extension-index", 21 | PreRun: func(cmd *cobra.Command, args []string) { manageDefaultFlags() }, 22 | Run: func(cmd *cobra.Command, args []string) { 23 | zc := zed.NewZedClient(1) 24 | extensions, err := zc.GetExtensionsIndex() 25 | if err != nil { 26 | log.Panic(err) 27 | } 28 | 29 | wrapped := extensions.AsWrapped() 30 | extensionsJson, err := json.MarshalIndent(wrapped, "", "\t") 31 | if err != nil { 32 | log.Panic(err) 33 | } 34 | if getExtensionIndexCmdConfig.outputDir == "" { 35 | fmt.Println(string(extensionsJson)) 36 | } else { 37 | utils.CreateDirIfNotExists(getExtensionIndexCmdConfig.outputDir) 38 | extensionsFilePath := getExtensionIndexCmdConfig.outputDir + "/extensions.json" 39 | err := os.WriteFile(extensionsFilePath, extensionsJson, 0o644) 40 | if err != nil { 41 | log.Panic(err) 42 | } 43 | } 44 | }, 45 | } 46 | 47 | func init() { 48 | getCmd.AddCommand(getExtensionIndexCmd) 49 | getExtensionIndexCmd.Flags().StringVar(&getExtensionIndexCmdConfig.outputDir, "output-dir", ".zedex-cache", "output directory of the 'extensions.json' file") 50 | } 51 | -------------------------------------------------------------------------------- /src/cmd/getLatestRelease.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "os" 7 | 8 | "zedex/utils" 9 | "zedex/zed" 10 | 11 | log "github.com/sirupsen/logrus" 12 | "github.com/spf13/cobra" 13 | ) 14 | 15 | var getLatestReleaseCmdConfig struct { 16 | outputDir string 17 | } 18 | 19 | var getLatestReleaseCmd = &cobra.Command{ 20 | Use: "latest-release", 21 | Short: "Get the latest release from zed.dev", 22 | PreRun: func(cmd *cobra.Command, args []string) { manageDefaultFlags() }, 23 | Run: func(cmd *cobra.Command, args []string) { 24 | zc := zed.NewZedClient(1) 25 | latestRelease, err := zc.GetLatestZedVersion() 26 | if err != nil { 27 | log.Panic(err) 28 | } 29 | 30 | latestReleaseNotes, err := zc.GetReleaseNotes(latestRelease.Version) 31 | if err != nil { 32 | log.Panic(err) 33 | } 34 | 35 | latestReleaseJson, err := json.MarshalIndent(latestRelease, "", "\t") 36 | if err != nil { 37 | log.Panic(err) 38 | } 39 | 40 | latestReleaseNotesJson, err := json.MarshalIndent(latestReleaseNotes, "", "\t") 41 | if err != nil { 42 | log.Panic(err) 43 | } 44 | 45 | if getLatestReleaseCmdConfig.outputDir == "" { 46 | fmt.Println(string(latestReleaseJson)) 47 | return 48 | } 49 | utils.CreateDirIfNotExists(getLatestReleaseCmdConfig.outputDir) 50 | latestReleasePath := getLatestReleaseCmdConfig.outputDir + "/latest_release.json" 51 | if err := os.WriteFile(latestReleasePath, latestReleaseJson, 0o644); err != nil { 52 | log.Panic(err) 53 | } 54 | 55 | latestReleaseNotePath := getLatestReleaseCmdConfig.outputDir + "/latest_release_notes.json" 56 | if err := os.WriteFile(latestReleaseNotePath, latestReleaseNotesJson, 0o644); err != nil { 57 | log.Panic(err) 58 | } 59 | }, 60 | } 61 | 62 | func init() { 63 | getCmd.AddCommand(getLatestReleaseCmd) 64 | getLatestReleaseCmd.Flags().StringVar(&getLatestReleaseCmdConfig.outputDir, "output-dir", ".zedex-cache", "output directory of the 'latest_release.json' and 'latest_release_notes.json' file") 65 | } 66 | -------------------------------------------------------------------------------- /src/cmd/root.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/spf13/cobra" 7 | ) 8 | 9 | var rootCmd = &cobra.Command{ 10 | Use: "zedex", 11 | PreRun: func(cmd *cobra.Command, args []string) { manageDefaultFlags() }, 12 | Short: "A self hosted Zed server.", 13 | } 14 | 15 | func Execute() { 16 | err := rootCmd.Execute() 17 | if err != nil { 18 | os.Exit(1) 19 | } 20 | } 21 | 22 | func init() { 23 | rootCmd.PersistentFlags().BoolVar(&baseFlags.debug, "debug", false, "activate debug logging") 24 | } 25 | -------------------------------------------------------------------------------- /src/cmd/serve.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "fmt" 5 | 6 | "zedex/zed" 7 | 8 | log "github.com/sirupsen/logrus" 9 | "github.com/spf13/cobra" 10 | ) 11 | 12 | var serveCmdConfig = struct { 13 | outputDir string 14 | port int 15 | enableEditPrediction bool 16 | enableLogin bool 17 | enableExtensionStore bool 18 | enableReleases bool 19 | enableReleaseNotes bool 20 | }{} 21 | 22 | var serveCmd = &cobra.Command{ 23 | Use: "serve", 24 | Args: cobra.ExactArgs(0), 25 | PreRun: func(cmd *cobra.Command, args []string) { manageDefaultFlags() }, 26 | Run: func(cmd *cobra.Command, args []string) { 27 | if !serveCmdConfig.enableLogin { 28 | log.Fatalf("zedex does not support login forwarding yet") 29 | } 30 | if !serveCmdConfig.enableEditPrediction { 31 | log.Fatalf("zedex does not support edit prediction forwarding yet") 32 | } 33 | 34 | zc := zed.NewZedClient(1) 35 | zc.WithExtensionsLocalDir(serveCmdConfig.outputDir) 36 | api := zed.NewAPI( 37 | serveCmdConfig.enableExtensionStore, 38 | serveCmdConfig.enableLogin, 39 | serveCmdConfig.enableEditPrediction, 40 | serveCmdConfig.enableReleases, 41 | serveCmdConfig.enableReleaseNotes, 42 | zc, 43 | serveCmdConfig.port) 44 | 45 | log.Infof("serving on %v", serveCmdConfig.port) 46 | api.Router().Run(fmt.Sprintf(":%v", serveCmdConfig.port)) 47 | }, 48 | } 49 | 50 | func init() { 51 | rootCmd.AddCommand(serveCmd) 52 | serveCmd.Flags().BoolVar(&serveCmdConfig.enableLogin, "enable-login", true, "enable login requests, letting zedex manage them") 53 | serveCmd.Flags().BoolVar(&serveCmdConfig.enableEditPrediction, "enable-edit-prediction", true, "enable edit prediction requests, letting zedex manage them") 54 | serveCmd.Flags().BoolVar(&serveCmdConfig.enableExtensionStore, "enable-extension-store", true, "enable extension store requests, letting zedex manage them") 55 | serveCmd.Flags().BoolVar(&serveCmdConfig.enableReleases, "enable-releases", true, "enable release update requests, letting zedex manage them") 56 | serveCmd.Flags().BoolVar(&serveCmdConfig.enableReleaseNotes, "enable-release-notes", true, "enable release note requests, letting zedex manage them") 57 | serveCmd.Flags().StringVar(&serveCmdConfig.outputDir, "output-dir", ".zedex-cache", "the directory where local artifacts (index and extensions) are located, ignored if local-mode=false") 58 | serveCmd.Flags().IntVar(&serveCmdConfig.port, "port", 8080, "port to serve proxy on") 59 | } 60 | -------------------------------------------------------------------------------- /src/cmd/version.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/spf13/cobra" 7 | ) 8 | 9 | var ( 10 | GIT_COMMIT_SHA = "" 11 | BUILD_TIME = "" 12 | ) 13 | 14 | // versionCmd represents the version command 15 | var versionCmd = &cobra.Command{ 16 | Use: "version", 17 | Short: "Display version details", 18 | Run: func(cmd *cobra.Command, args []string) { 19 | fmt.Println("GIT_COMMIT_SHA:", GIT_COMMIT_SHA) 20 | fmt.Println("BUILD_TIME:", BUILD_TIME) 21 | }, 22 | } 23 | 24 | func init() { 25 | rootCmd.AddCommand(versionCmd) 26 | } 27 | -------------------------------------------------------------------------------- /src/go.mod: -------------------------------------------------------------------------------- 1 | module zedex 2 | 3 | go 1.24.0 4 | 5 | require ( 6 | github.com/0x6flab/namegenerator v1.4.0 7 | github.com/gin-gonic/gin v1.11.0 8 | github.com/google/uuid v1.6.0 9 | github.com/gorilla/websocket v1.5.3 10 | github.com/klauspost/compress v1.18.1 11 | github.com/remeh/sizedwaitgroup v1.0.0 12 | github.com/sirupsen/logrus v1.9.3 13 | github.com/spf13/cobra v1.10.1 14 | github.com/stretchr/testify v1.11.1 15 | golang.org/x/exp v0.0.0-20251113190631-e25ba8c21ef6 16 | google.golang.org/protobuf v1.36.10 17 | ) 18 | 19 | require ( 20 | github.com/bytedance/gopkg v0.1.3 // indirect 21 | github.com/bytedance/sonic v1.14.2 // indirect 22 | github.com/bytedance/sonic/loader v0.4.0 // indirect 23 | github.com/cloudwego/base64x v0.1.6 // indirect 24 | github.com/davecgh/go-spew v1.1.1 // indirect 25 | github.com/gabriel-vasile/mimetype v1.4.11 // indirect 26 | github.com/gin-contrib/sse v1.1.0 // indirect 27 | github.com/go-playground/locales v0.14.1 // indirect 28 | github.com/go-playground/universal-translator v0.18.1 // indirect 29 | github.com/go-playground/validator/v10 v10.28.0 // indirect 30 | github.com/goccy/go-json v0.10.5 // indirect 31 | github.com/goccy/go-yaml v1.18.0 // indirect 32 | github.com/inconshreveable/mousetrap v1.1.0 // indirect 33 | github.com/json-iterator/go v1.1.12 // indirect 34 | github.com/klauspost/cpuid/v2 v2.3.0 // indirect 35 | github.com/leodido/go-urn v1.4.0 // indirect 36 | github.com/mattn/go-isatty v0.0.20 // indirect 37 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 38 | github.com/modern-go/reflect2 v1.0.2 // indirect 39 | github.com/pelletier/go-toml/v2 v2.2.4 // indirect 40 | github.com/pmezard/go-difflib v1.0.0 // indirect 41 | github.com/quic-go/qpack v0.6.0 // indirect 42 | github.com/quic-go/quic-go v0.57.0 // indirect 43 | github.com/spf13/pflag v1.0.10 // indirect 44 | github.com/twitchyliquid64/golang-asm v0.15.1 // indirect 45 | github.com/ugorji/go/codec v1.3.1 // indirect 46 | go.uber.org/mock v0.6.0 // indirect 47 | golang.org/x/arch v0.23.0 // indirect 48 | golang.org/x/crypto v0.45.0 // indirect 49 | golang.org/x/mod v0.30.0 // indirect 50 | golang.org/x/net v0.47.0 // indirect 51 | golang.org/x/sync v0.18.0 // indirect 52 | golang.org/x/sys v0.38.0 // indirect 53 | golang.org/x/text v0.31.0 // indirect 54 | golang.org/x/tools v0.39.0 // indirect 55 | gopkg.in/yaml.v3 v3.0.1 // indirect 56 | ) 57 | -------------------------------------------------------------------------------- /src/go.sum: -------------------------------------------------------------------------------- 1 | github.com/0x6flab/namegenerator v1.4.0 h1:QnkI813SZsI/hYnKD9pg3mkIlcYzCx0N4hnzb0YYME4= 2 | github.com/0x6flab/namegenerator v1.4.0/go.mod h1:2sQzXuS6dX/KEwWtB6GJU729O3m4gBdD5oAU8hd0SyY= 3 | github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M= 4 | github.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM= 5 | github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ= 6 | github.com/bytedance/sonic v1.13.2/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4= 7 | github.com/bytedance/sonic v1.14.2 h1:k1twIoe97C1DtYUo+fZQy865IuHia4PR5RPiuGPPIIE= 8 | github.com/bytedance/sonic v1.14.2/go.mod h1:T80iDELeHiHKSc0C9tubFygiuXoGzrkjKzX2quAx980= 9 | github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= 10 | github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY= 11 | github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= 12 | github.com/bytedance/sonic/loader v0.4.0 h1:olZ7lEqcxtZygCK9EKYKADnpQoYkRQxaeY2NYzevs+o= 13 | github.com/bytedance/sonic/loader v0.4.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo= 14 | github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4= 15 | github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= 16 | github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M= 17 | github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU= 18 | github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= 19 | github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= 20 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 21 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 22 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 23 | github.com/gabriel-vasile/mimetype v1.4.9 h1:5k+WDwEsD9eTLL8Tz3L0VnmVh9QxGjRmjBvAG7U/oYY= 24 | github.com/gabriel-vasile/mimetype v1.4.9/go.mod h1:WnSQhFKJuBlRyLiKohA/2DtIlPFAbguNaG7QCHcyGok= 25 | github.com/gabriel-vasile/mimetype v1.4.11 h1:AQvxbp830wPhHTqc1u7nzoLT+ZFxGY7emj5DR5DYFik= 26 | github.com/gabriel-vasile/mimetype v1.4.11/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s= 27 | github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w= 28 | github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= 29 | github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= 30 | github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= 31 | github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk= 32 | github.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls= 33 | github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= 34 | github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= 35 | github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= 36 | github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= 37 | github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= 38 | github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= 39 | github.com/go-playground/validator/v10 v10.26.0 h1:SP05Nqhjcvz81uJaRfEV0YBSSSGMc/iMaVtFbr3Sw2k= 40 | github.com/go-playground/validator/v10 v10.26.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo= 41 | github.com/go-playground/validator/v10 v10.28.0 h1:Q7ibns33JjyW48gHkuFT91qX48KG0ktULL6FgHdG688= 42 | github.com/go-playground/validator/v10 v10.28.0/go.mod h1:GoI6I1SjPBh9p7ykNE/yj3fFYbyDOpwMn5KXd+m2hUU= 43 | github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= 44 | github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= 45 | github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= 46 | github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= 47 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= 48 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 49 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 50 | github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= 51 | github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 52 | github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= 53 | github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= 54 | github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= 55 | github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= 56 | github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= 57 | github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= 58 | github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= 59 | github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= 60 | github.com/klauspost/compress v1.18.1 h1:bcSGx7UbpBqMChDtsF28Lw6v/G94LPrrbMbdC3JH2co= 61 | github.com/klauspost/compress v1.18.1/go.mod h1:ZQFFVG+MdnR0P+l6wpXgIL4NTtwiKIdBnrBd8Nrxr+0= 62 | github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= 63 | github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= 64 | github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= 65 | github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= 66 | github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= 67 | github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= 68 | github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= 69 | github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= 70 | github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= 71 | github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 72 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 73 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= 74 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 75 | github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= 76 | github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= 77 | github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= 78 | github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= 79 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 80 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 81 | github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8= 82 | github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII= 83 | github.com/quic-go/quic-go v0.57.0 h1:AsSSrrMs4qI/hLrKlTH/TGQeTMY0ib1pAOX7vA3AdqE= 84 | github.com/quic-go/quic-go v0.57.0/go.mod h1:ly4QBAjHA2VhdnxhojRsCUOeJwKYg+taDlos92xb1+s= 85 | github.com/remeh/sizedwaitgroup v1.0.0 h1:VNGGFwNo/R5+MJBf6yrsr110p0m4/OX4S3DCy7Kyl5E= 86 | github.com/remeh/sizedwaitgroup v1.0.0/go.mod h1:3j2R4OIe/SeS6YDhICBy22RWjJC5eNCJ1V+9+NVNYlo= 87 | github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 88 | github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= 89 | github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= 90 | github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= 91 | github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= 92 | github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= 93 | github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= 94 | github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= 95 | github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 96 | github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 97 | github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= 98 | github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 99 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 100 | github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 101 | github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= 102 | github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= 103 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 104 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 105 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 106 | github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 107 | github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= 108 | github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= 109 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 110 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 111 | github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= 112 | github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= 113 | github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= 114 | github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= 115 | github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= 116 | github.com/ugorji/go/codec v1.3.1 h1:waO7eEiFDwidsBN6agj1vJQ4AG7lh2yqXyOXqhgQuyY= 117 | github.com/ugorji/go/codec v1.3.1/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= 118 | go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y= 119 | go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU= 120 | golang.org/x/arch v0.16.0 h1:foMtLTdyOmIniqWCHjY6+JxuC54XP1fDwx4N0ASyW+U= 121 | golang.org/x/arch v0.16.0/go.mod h1:JmwW7aLIoRUKgaTzhkiEFxvcEiQGyOg9BMonBJUS7EE= 122 | golang.org/x/arch v0.23.0 h1:lKF64A2jF6Zd8L0knGltUnegD62JMFBiCPBmQpToHhg= 123 | golang.org/x/arch v0.23.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A= 124 | golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= 125 | golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= 126 | golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= 127 | golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= 128 | golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM= 129 | golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8= 130 | golang.org/x/exp v0.0.0-20251113190631-e25ba8c21ef6 h1:zfMcR1Cs4KNuomFFgGefv5N0czO2XZpUbxGUy8i8ug0= 131 | golang.org/x/exp v0.0.0-20251113190631-e25ba8c21ef6/go.mod h1:46edojNIoXTNOhySWIWdix628clX9ODXwPsQuG6hsK0= 132 | golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk= 133 | golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc= 134 | golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= 135 | golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= 136 | golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= 137 | golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= 138 | golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= 139 | golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= 140 | golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 141 | golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 142 | golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= 143 | golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 144 | golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= 145 | golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= 146 | golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= 147 | golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= 148 | golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= 149 | golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= 150 | golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= 151 | golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= 152 | google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= 153 | google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= 154 | google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= 155 | google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= 156 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 157 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 158 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 159 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 160 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 161 | nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= 162 | -------------------------------------------------------------------------------- /src/llm/openai_compatible.go: -------------------------------------------------------------------------------- 1 | package llm 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "io" 7 | "net/http" 8 | "os" 9 | "strings" 10 | ) 11 | 12 | type OpenAIHost struct { 13 | Host string 14 | EnvName string 15 | SystemPrompt string 16 | Temperature float64 17 | Model string 18 | } 19 | 20 | func NewOpenAIHost(host, envName string) *OpenAIHost { 21 | return &OpenAIHost{ 22 | Host: host, 23 | EnvName: envName, 24 | } 25 | } 26 | 27 | func (c *OpenAIHost) WithSystemPrompt(prompt string) *OpenAIHost { 28 | c.SystemPrompt = prompt 29 | return c 30 | } 31 | 32 | func (c *OpenAIHost) WithTemperature(temperature float64) *OpenAIHost { 33 | c.Temperature = temperature 34 | return c 35 | } 36 | 37 | func (c *OpenAIHost) WithModel(modelName string) *OpenAIHost { 38 | c.Model = modelName 39 | return c 40 | } 41 | 42 | func (c OpenAIHost) GetKey() (string, error) { 43 | key, ok := os.LookupEnv(c.EnvName) 44 | if !ok { 45 | return "", fmt.Errorf("env %v is not set", c.EnvName) 46 | } 47 | if key == "" { 48 | return "", fmt.Errorf("env %v is empty", c.EnvName) 49 | } 50 | 51 | return key, nil 52 | } 53 | 54 | type OpenAIResponse struct { 55 | ID string `json:"id"` 56 | Object string `json:"object"` 57 | Created int `json:"created"` 58 | Model string `json:"model"` 59 | Choices []struct { 60 | Text string `json:"text"` 61 | Message struct { 62 | Content string `json:"content"` 63 | Role string `json:"role"` 64 | } `json:"message"` 65 | } `json:"choices"` 66 | } 67 | 68 | func (o *OpenAIResponse) GetLastResponse() string { 69 | if len(o.Choices) == 0 { 70 | return "" 71 | } 72 | return o.Choices[len(o.Choices)-1].Message.Content 73 | } 74 | 75 | func (c *OpenAIHost) Chat(question string) (*OpenAIResponse, error) { 76 | if v, ok := os.LookupEnv("OPENAI_COMPATIBLE_DISABLE"); ok || v != "" { 77 | return nil, nil 78 | } 79 | 80 | req, err := http.NewRequest("POST", c.Host, nil) 81 | if err != nil { 82 | return nil, err 83 | } 84 | 85 | auth, err := c.GetKey() 86 | if err != nil { 87 | return nil, fmt.Errorf("OPENAI_COMPATIBLE_API_KEY not set") 88 | } 89 | req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", auth)) 90 | req.Header.Set("Accept", "application/json") 91 | req.Header.Set("Content-Type", "application/json") 92 | 93 | postData := map[string]interface{}{ 94 | "messages": []map[string]string{ 95 | { 96 | "role": "system", 97 | "content": c.SystemPrompt, 98 | }, 99 | { 100 | "role": "user", 101 | "content": question, 102 | }, 103 | }, 104 | "model": c.Model, 105 | "temperature": 0.1, 106 | } 107 | jsonPostData, err := json.Marshal(postData) 108 | if err != nil { 109 | return nil, err 110 | } 111 | req.Body = io.NopCloser(strings.NewReader(string(jsonPostData))) 112 | 113 | client := &http.Client{} 114 | resp, err := client.Do(req) 115 | if err != nil { 116 | return nil, err 117 | } 118 | defer resp.Body.Close() 119 | 120 | body, err := io.ReadAll(resp.Body) 121 | if err != nil { 122 | return nil, err 123 | } 124 | 125 | if resp.StatusCode != http.StatusOK { 126 | return nil, fmt.Errorf("server responded with %v: %v", resp.StatusCode, string(body)) 127 | } 128 | 129 | var openAIResponse OpenAIResponse 130 | err = json.Unmarshal(body, &openAIResponse) 131 | if err != nil { 132 | return nil, err 133 | } 134 | 135 | return &openAIResponse, nil 136 | } 137 | -------------------------------------------------------------------------------- /src/llm/openai_compatible_test.go: -------------------------------------------------------------------------------- 1 | package llm 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func TestGroq(t *testing.T) { 10 | groq := NewOpenAIHost( 11 | "https://api.groq.com/openai/v1/chat/completions", 12 | "GROQ_API_KEY", 13 | ). 14 | WithModel("llama-3.3-70b-versatile"). 15 | WithTemperature(0.1). 16 | WithSystemPrompt("You are a helpful assistant") 17 | 18 | response, err := groq.Chat("What is 1+1? Answer only with the result and nothing else.") 19 | if err != nil { 20 | t.Error(err) 21 | return 22 | } 23 | 24 | assert.Equal(t, 1, len(response.Choices)) 25 | assert.Equal(t, "2", response.GetLastResponse()) 26 | } 27 | -------------------------------------------------------------------------------- /src/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2024 NAME HERE 3 | 4 | */ 5 | package main 6 | 7 | import "zedex/cmd" 8 | 9 | func main() { 10 | cmd.Execute() 11 | } 12 | -------------------------------------------------------------------------------- /src/utils/concurrent_counter.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "sync" 5 | 6 | "golang.org/x/exp/constraints" 7 | ) 8 | 9 | type number interface { 10 | constraints.Integer | constraints.Float 11 | } 12 | 13 | type ConcurrentCounter[T number] struct { 14 | count T 15 | mtx sync.Mutex 16 | } 17 | 18 | func NewConcurrentCounter[T number]() ConcurrentCounter[T] { 19 | return ConcurrentCounter[T]{} 20 | } 21 | 22 | func (c *ConcurrentCounter[T]) Add(n T) *ConcurrentCounter[T] { 23 | c.mtx.Lock() 24 | defer c.mtx.Unlock() 25 | c.count += n 26 | return c 27 | } 28 | 29 | func (c *ConcurrentCounter[T]) Increment() *ConcurrentCounter[T] { 30 | c.mtx.Lock() 31 | defer c.mtx.Unlock() 32 | c.count = c.count + 1 33 | return c 34 | } 35 | 36 | func (c *ConcurrentCounter[T]) Decrement() *ConcurrentCounter[T] { 37 | c.mtx.Lock() 38 | defer c.mtx.Unlock() 39 | c.count = c.count - 1 40 | return c 41 | } 42 | 43 | func (c *ConcurrentCounter[T]) Reset() *ConcurrentCounter[T] { 44 | c.mtx.Lock() 45 | defer c.mtx.Unlock() 46 | c.count = 0 47 | return c 48 | } 49 | 50 | func (c *ConcurrentCounter[T]) Value() T { 51 | c.mtx.Lock() 52 | defer c.mtx.Unlock() 53 | v := c.count 54 | return v 55 | } 56 | -------------------------------------------------------------------------------- /src/utils/concurrent_map.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "sync" 5 | 6 | "golang.org/x/exp/maps" 7 | ) 8 | 9 | type ConcurrentMap[A comparable, B any] struct { 10 | m map[A]B 11 | l sync.Mutex 12 | } 13 | 14 | func NewConcurrentMap[A comparable, B any]() ConcurrentMap[A, B] { 15 | return ConcurrentMap[A, B]{ 16 | m: map[A]B{}, 17 | } 18 | } 19 | 20 | func (m *ConcurrentMap[A, B]) Set(k A, v B) { 21 | m.l.Lock() 22 | defer m.l.Unlock() 23 | m.m[k] = v 24 | } 25 | 26 | func (m *ConcurrentMap[A, B]) Get(k A) B { 27 | m.l.Lock() 28 | defer m.l.Unlock() 29 | return m.m[k] 30 | } 31 | 32 | func (m *ConcurrentMap[A, B]) GetUnsafe(k A) B { 33 | return m.m[k] 34 | } 35 | 36 | func (m *ConcurrentMap[A, B]) SetUnsafe(k A, v B) { 37 | m.m[k] = v 38 | } 39 | 40 | func (m *ConcurrentMap[A, B]) Delete(k A) { 41 | m.l.Lock() 42 | defer m.l.Unlock() 43 | delete(m.m, k) 44 | } 45 | 46 | func (m *ConcurrentMap[A, B]) Transaction(f func(m map[A]B) map[A]B) { 47 | m.l.Lock() 48 | defer m.l.Unlock() 49 | m.m = f(m.Map()) 50 | } 51 | 52 | func (m *ConcurrentMap[A, B]) Pop(k A) B { 53 | m.l.Lock() 54 | defer m.l.Unlock() 55 | v := m.m[k] 56 | delete(m.m, k) 57 | return v 58 | } 59 | 60 | func (m *ConcurrentMap[A, B]) Exists(k A) bool { 61 | m.l.Lock() 62 | defer m.l.Unlock() 63 | _, exists := m.m[k] 64 | return exists 65 | } 66 | 67 | func (m *ConcurrentMap[A, B]) ExistsUnsafe(k A) bool { 68 | _, exists := m.m[k] 69 | return exists 70 | } 71 | 72 | func (m *ConcurrentMap[A, B]) Map() map[A]B { 73 | return m.m 74 | } 75 | 76 | func (m *ConcurrentMap[A, B]) Keys() []A { 77 | m.l.Lock() 78 | defer m.l.Unlock() 79 | return maps.Keys(m.m) 80 | } 81 | 82 | func (m *ConcurrentMap[A, B]) Values() []B { 83 | m.l.Lock() 84 | defer m.l.Unlock() 85 | return maps.Values(m.m) 86 | } 87 | 88 | func (m *ConcurrentMap[A, B]) Len() int { 89 | m.l.Lock() 90 | defer m.l.Unlock() 91 | return len(m.Map()) 92 | } 93 | -------------------------------------------------------------------------------- /src/utils/concurrent_map_test.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "sync" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | func TestConcurrentMap(t *testing.T) { 11 | s := NewConcurrentMap[int, int]() 12 | var wg sync.WaitGroup 13 | for i := 0; i < 1000; i++ { 14 | wg.Add(1) 15 | s.Set(1, 1) 16 | go func(i int) { 17 | defer wg.Done() 18 | for j := 0; j < 1000; j++ { 19 | s.Set(1, 2) 20 | s.Get(1) 21 | s.Len() 22 | s.Get(0) 23 | s.Set(2, 1) 24 | s.Get(2) 25 | s.Keys() 26 | s.Map() 27 | s.Values() 28 | s.Exists(1) 29 | s.Delete(1) 30 | s.Set(2, 1) 31 | s.Pop(1) 32 | } 33 | }(i) 34 | } 35 | wg.Wait() 36 | 37 | assert.Equal(t, s.Len(), 1) 38 | } 39 | -------------------------------------------------------------------------------- /src/utils/dir.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import "os" 4 | 5 | func CreateDirIfNotExists(dir string) { 6 | if dir == "" { 7 | return 8 | } 9 | os.MkdirAll(dir, os.ModePerm) 10 | } 11 | -------------------------------------------------------------------------------- /src/utils/env.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import "os" 4 | 5 | func EnvWithFallback(key, fallback string) string { 6 | if value, ok := os.LookupEnv(key); ok { 7 | return value 8 | } 9 | return fallback 10 | } 11 | -------------------------------------------------------------------------------- /src/utils/hash.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "crypto/md5" 5 | "encoding/binary" 6 | ) 7 | 8 | func StringToUInt64Hash(s string) uint64 { 9 | hash := md5.New() 10 | if _, err := hash.Write([]byte(s)); err != nil { 11 | return 0 12 | } 13 | hashSum := hash.Sum(nil) 14 | hashBytes := hashSum[:8] 15 | return binary.BigEndian.Uint64(hashBytes) 16 | } 17 | 18 | func StringToUin32Hash(s string) uint32 { 19 | return binary.BigEndian.Uint32([]byte(s)) 20 | } 21 | -------------------------------------------------------------------------------- /src/utils/ifelse.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | func IfElse[T any](c bool, vT, vF T) T { 4 | if c { 5 | return vT 6 | } 7 | return vF 8 | } 9 | -------------------------------------------------------------------------------- /src/zed/api.go: -------------------------------------------------------------------------------- 1 | package zed 2 | 3 | import ( 4 | "strings" 5 | 6 | "github.com/gin-gonic/gin" 7 | ) 8 | 9 | type API struct { 10 | enableExtensionStore bool 11 | enableLogin bool 12 | enableEditPrediction bool 13 | enableReleases bool 14 | enableReleaseNotes bool 15 | zedClient Client 16 | port int 17 | } 18 | 19 | func NewAPI( 20 | enableExtensionStore bool, 21 | enableLogin bool, 22 | enableEditPrediction bool, 23 | enableReleases bool, 24 | enableReleaseNotes bool, 25 | zedClient Client, 26 | port int, 27 | ) API { 28 | return API{ 29 | zedClient: zedClient, 30 | port: port, 31 | enableExtensionStore: enableExtensionStore, 32 | enableLogin: enableLogin, 33 | enableEditPrediction: enableEditPrediction, 34 | enableReleases: enableReleases, 35 | enableReleaseNotes: enableReleaseNotes, 36 | } 37 | } 38 | 39 | func (api *API) Router() *gin.Engine { 40 | router := gin.Default() 41 | controller := NewController( 42 | api.enableExtensionStore, 43 | api.enableLogin, 44 | api.enableEditPrediction, 45 | api.enableReleases, 46 | api.enableReleaseNotes, 47 | api.zedClient, 48 | api.port, 49 | ) 50 | router.GET("/extensions", controller.Extensions) 51 | router.GET("/extensions/:id/download", controller.DownloadExtension) 52 | router.GET("/extensions/:id/:version/download", controller.DownloadExtension) 53 | 54 | router.GET("/releases/stable/latest/asset", controller.LatestVersion) 55 | 56 | router.GET("/api/*path", func(c *gin.Context) { 57 | if c.Request.URL.Path == "/api/releases/latest" && api.enableReleases { 58 | controller.LatestVersion(c) 59 | return 60 | } 61 | if strings.HasPrefix(c.Request.URL.Path, "/api/release_notes/v2/stable/") && api.enableReleaseNotes { 62 | controller.LatestReleaseNotes(c) 63 | return 64 | } 65 | 66 | // Redirect to zed.host if not /api/releases 67 | c.Redirect(301, controller.zed.host+c.Request.URL.RequestURI()) 68 | }) 69 | router.GET("/native_app_signin", controller.NativeAppSignin) 70 | router.GET("/native_app_signin_succeeded", controller.NativeAppSigninSucceeded) 71 | router.GET("/rpc", controller.HandleRpcRequest) 72 | router.GET("/handle-rpc", controller.HandleWebSocketRequest) 73 | router.GET("/favicon.ico", func(c *gin.Context) { 74 | c.String(200, "plain/text", "") 75 | }) 76 | 77 | router.POST("/predict_edits/v2", controller.HandleEditPredictRequest) 78 | 79 | router.POST("/client/llm_tokens", func(c *gin.Context) { 80 | c.JSON(200, NewLLMToken()) 81 | }) 82 | router.GET("/client/users/me", func(c *gin.Context) { 83 | c.JSON(200, NewGetAuthenticatedUsersResponse()) 84 | }) 85 | 86 | router.GET("/account", controller.Account) 87 | return router 88 | } 89 | -------------------------------------------------------------------------------- /src/zed/api_controller.go: -------------------------------------------------------------------------------- 1 | package zed 2 | 3 | import ( 4 | "crypto/rand" 5 | "crypto/rsa" 6 | "crypto/sha256" 7 | "crypto/x509" 8 | "encoding/base64" 9 | "fmt" 10 | "math" 11 | mrand "math/rand" 12 | "os" 13 | "path" 14 | "strconv" 15 | "strings" 16 | 17 | "zedex/llm" 18 | "zedex/utils" 19 | 20 | "github.com/gin-gonic/gin" 21 | "github.com/sirupsen/logrus" 22 | ) 23 | 24 | type Controller struct { 25 | zed Client 26 | llm *llm.OpenAIHost 27 | port int 28 | enableExtensionStore bool 29 | enableLogin bool 30 | enableEditPrediction bool 31 | enableReleases bool 32 | enableReleaseNotes bool 33 | 34 | editPredictClient EditPredictClient 35 | rpcHandler RpcHandler 36 | } 37 | 38 | func NewController( 39 | enableExtensionStore bool, 40 | enableLogin bool, 41 | enableEditPrediction bool, 42 | enableReleases bool, 43 | enableReleaseNotes bool, 44 | zedClient Client, 45 | port int, 46 | ) Controller { 47 | _, envExists := os.LookupEnv("OPENAI_COMPATIBLE_API_KEY") 48 | oai := llm.NewOpenAIHost( 49 | utils.EnvWithFallback("OPENAI_COMPATIBLE_HOST", "https://api.groq.com/openai/v1/chat/completions"), 50 | utils.IfElse(envExists, "OPENAI_COMPATIBLE_API_KEY", "GROQ_API_KEY"), 51 | ). 52 | WithModel(utils.EnvWithFallback("OPENAI_COMPATIBLE_MODEL", "meta-llama/llama-4-scout-17b-16e-instruct")). 53 | WithTemperature(0.1). // TODO: Use env. 54 | WithSystemPrompt(utils.EnvWithFallback("OPENAI_COMPATIBLE_SYSTEM_PROMPT", `You are a code autocomplete engine. 55 | 56 | RULES: 57 | * Only respond with code (nothing else). 58 | * YOU MUST INCLUDE ALL PLACEHOLDERS "<|editable_region_start|>" AND "<|editable_region_end|>" IN YOUR RESPONSE. 59 | * YOU MAY ALTER ALL CODE CONTAINED WITHIN "<|editable_region_start|>" AND "<|editable_region_end|>". 60 | * ALWAYS AUTO COMPLETE AS LITTLE AS POSSIBLE`)) 61 | return Controller{ 62 | zed: zedClient, 63 | enableExtensionStore: enableExtensionStore, 64 | enableLogin: enableLogin, 65 | enableEditPrediction: enableEditPrediction, 66 | enableReleases: enableReleases, 67 | enableReleaseNotes: enableReleaseNotes, 68 | port: port, 69 | editPredictClient: NewEditPredictClient(*oai), 70 | rpcHandler: NewRpcHandler(), 71 | } 72 | } 73 | 74 | func (co *Controller) Extensions(c *gin.Context) { 75 | var extensions Extensions 76 | var err error 77 | 78 | if co.enableExtensionStore { 79 | extensionsFile := path.Join(co.zed.extensionsLocalDir, "extensions.json") 80 | extensions, err = co.zed.LoadExtensionIndex(extensionsFile) 81 | } else { 82 | extensions, err = co.zed.GetExtensionsIndex() 83 | } 84 | 85 | if err != nil { 86 | logrus.Error(err) 87 | c.JSON(500, gin.H{ 88 | "error": "Internal Server Error", 89 | "message": err.Error(), 90 | }) 91 | return 92 | } 93 | 94 | maxSchemaVersion := c.DefaultQuery("max_schema_version", "100") 95 | maxSchemaVersionInt, err := strconv.Atoi(maxSchemaVersion) 96 | if err != nil { 97 | logrus.Error(err) 98 | c.JSON(400, gin.H{ 99 | "error": "Bad Request", 100 | "message": "max_schema_version must be an integer", 101 | }) 102 | return 103 | } 104 | 105 | extensions = extensions.Filter(func(e Extension) bool { 106 | return e.SchemaVersion <= maxSchemaVersionInt 107 | }) 108 | 109 | if filter := c.DefaultQuery("filter", ""); filter != "" { 110 | extensions = extensions.Filter(func(e Extension) bool { 111 | return strings.Contains(strings.ToLower(e.AsJsonStr()), strings.ToLower(filter)) 112 | }) 113 | } 114 | 115 | if filter := c.DefaultQuery("provides", ""); filter != "" { 116 | extensions = extensions.FilterByProvides(filter) 117 | } 118 | 119 | c.JSON(200, extensions.AsWrapped()) 120 | } 121 | 122 | func (co *Controller) DownloadExtension(c *gin.Context) { 123 | id := c.Param("id") 124 | 125 | // TODO: Do we care about version? 126 | // minSchemaVersion := c.DefaultQuery("min_schema_version", "0") 127 | // minSchemaVersionInt, err := strconv.Atoi(minSchemaVersion) 128 | // if err != nil { 129 | // c.JSON(400, gin.H{ 130 | // "error": "Bad Request", 131 | // "message": "min_schema_version must be an integer", 132 | // }) 133 | // return 134 | // } 135 | // maxSchemaVersion := c.Query("max_schema_version") 136 | // minWasmApiVersion := c.Query("min_wasm_api_version") 137 | // maxWasmApiVersion := c.Query("max_wasm_api_version") 138 | 139 | extension := Extension{ID: id} 140 | var bytes []byte 141 | var err error 142 | 143 | if co.enableExtensionStore { 144 | bytes, err = co.zed.LoadExtensionArchive(extension) 145 | } else { 146 | bytes, err = co.zed.DownloadExtensionArchiveDefault(extension) 147 | } 148 | 149 | if err != nil { 150 | logrus.Error(err) 151 | c.JSON(500, gin.H{ 152 | "error": "Internal Server Error", 153 | "message": err.Error(), 154 | }) 155 | return 156 | } 157 | 158 | c.Data(200, "application/octet-stream", bytes) 159 | } 160 | 161 | func (co *Controller) LatestVersion(c *gin.Context) { 162 | var v Version 163 | var err error 164 | if co.enableReleases { 165 | versionFile := path.Join(co.zed.extensionsLocalDir, "latest_release.json") 166 | v, err = co.zed.LoadLatestZedVersionFromFile(versionFile) 167 | } else { 168 | v, err = co.zed.GetLatestZedVersion() 169 | } 170 | 171 | if err != nil { 172 | logrus.Error(err) 173 | c.JSON(500, gin.H{ 174 | "error": "Internal Server Error", 175 | "message": err.Error(), 176 | }) 177 | return 178 | } 179 | 180 | c.JSON(200, v) 181 | } 182 | 183 | func (co *Controller) LatestReleaseNotes(c *gin.Context) { 184 | var v ReleaseNotes 185 | var err error 186 | if co.enableReleaseNotes { 187 | versionFile := path.Join(co.zed.extensionsLocalDir, "latest_release_notes.json") 188 | v, err = co.zed.LoadReleaseNotes(versionFile) 189 | } else { 190 | v, err = co.zed.GetLatestReleaseNotes() 191 | } 192 | 193 | if err != nil { 194 | logrus.Error(err) 195 | c.JSON(500, gin.H{ 196 | "error": "Internal Server Error", 197 | "message": err.Error(), 198 | }) 199 | return 200 | } 201 | 202 | c.JSON(200, v) 203 | } 204 | 205 | // v1 is a reference to rusts rsa crate 206 | func encryptStringV1(base64PublicKey, plaintext string) (string, error) { 207 | pubKeyBytes, err := base64.URLEncoding.DecodeString(base64PublicKey) 208 | if err != nil { 209 | return "", err 210 | } 211 | 212 | rsaPubKey, err := x509.ParsePKCS1PublicKey(pubKeyBytes) 213 | if err != nil { 214 | return "", err 215 | } 216 | 217 | encryptedBytes, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, rsaPubKey, []byte(plaintext), nil) 218 | if err != nil { 219 | return "", err 220 | } 221 | 222 | encryptedBase64 := base64.URLEncoding.EncodeToString(encryptedBytes) 223 | return encryptedBase64, nil 224 | } 225 | 226 | func randomToken() (string, error) { 227 | tokenBytes := make([]byte, 48) 228 | _, err := rand.Read(tokenBytes) 229 | if err != nil { 230 | return "", err 231 | } 232 | 233 | // Use base64.URLEncoding to get URL-safe encoding 234 | encodedToken := base64.URLEncoding.EncodeToString(tokenBytes) 235 | return encodedToken, nil 236 | } 237 | 238 | func (co *Controller) NativeAppSignin(c *gin.Context) { 239 | portStr := c.Query("native_app_port") 240 | pubKey := c.Query("native_app_public_key") 241 | 242 | enc, err := encryptStringV1(pubKey, "a") 243 | if err != nil { 244 | logrus.Error(err) 245 | c.JSON(500, gin.H{ 246 | "error": "Internal Server Error", 247 | "message": err.Error(), 248 | }) 249 | return 250 | } 251 | 252 | // user_id must be numeric, possibly a reference to github id 253 | // https://api.github.com/users/ 254 | uid := mrand.Intn(math.MaxInt) 255 | host := fmt.Sprintf("http://127.0.0.1:%s/native_app_signin?user_id=%v&access_token=%s", portStr, uid, enc) 256 | c.Redirect(302, host) 257 | } 258 | 259 | func (co *Controller) NativeAppSigninSucceeded(c *gin.Context) { 260 | c.Data(200, 261 | "text/html; charset=utf-8", 262 | []byte(` 263 | 264 |

You should now be signed into Zed. You can close this tab.

265 | 266 | `, 267 | ), 268 | ) 269 | } 270 | 271 | func (co *Controller) Account(c *gin.Context) { 272 | c.Data(200, 273 | "text/html; charset=utf-8", 274 | []byte(` 275 | 276 |

You are logged in anonymously with Zedex.

277 | 278 | `, 279 | ), 280 | ) 281 | } 282 | 283 | func (co *Controller) HandleRpcRequest(c *gin.Context) { 284 | baseURL := utils.EnvWithFallback("BASE_URL", fmt.Sprintf("http://127.0.0.1:%v", co.port)) 285 | location := fmt.Sprintf("%s/handle-rpc", baseURL) 286 | c.Redirect(301, location) 287 | } 288 | 289 | // https://github.com/zed-industries/zed/blob/1e22faebc9f9c8da685a34b15c17f2bc2b418b26/crates/collab/src/rpc.rs#L1092 290 | func (co *Controller) HandleWebSocketRequest(c *gin.Context) { 291 | co.rpcHandler.HandleRequest(c) 292 | } 293 | 294 | func (co *Controller) HandleEditPredictRequest(c *gin.Context) { 295 | epr := EditPredictRequest{} 296 | if err := c.ShouldBindJSON(&epr); err != nil { 297 | logrus.Error(err) 298 | c.JSON(500, gin.H{"error": err.Error()}) 299 | return 300 | } 301 | 302 | resp, err := co.editPredictClient.HandleRequest(epr) 303 | if err != nil { 304 | logrus.Error(err) 305 | c.JSON(500, gin.H{"error": err.Error()}) 306 | return 307 | } 308 | 309 | c.JSON(200, resp) 310 | } 311 | -------------------------------------------------------------------------------- /src/zed/client.go: -------------------------------------------------------------------------------- 1 | package zed 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "io" 7 | "net/http" 8 | "net/url" 9 | "os" 10 | "runtime" 11 | 12 | "zedex/utils" 13 | ) 14 | 15 | type Client struct { 16 | apiHost string 17 | host string 18 | maxSchemaVersion int 19 | extensionsLocalDir string 20 | } 21 | 22 | func NewZedClient(maxSchemaVersion int) Client { 23 | return Client{ 24 | maxSchemaVersion: maxSchemaVersion, 25 | host: utils.EnvWithFallback("ZED_HOST", "https://zed.dev"), 26 | apiHost: utils.EnvWithFallback("ZED_API_HOST", "https://api.zed.dev"), 27 | } 28 | } 29 | 30 | func (c *Client) WithExtensionsLocalDir(extensionsLocalDir string) *Client { 31 | c.extensionsLocalDir = extensionsLocalDir 32 | return c 33 | } 34 | 35 | func (c *Client) ensureExtensionsLocalDir() error { 36 | if c.extensionsLocalDir == "" { 37 | return nil 38 | } 39 | return os.MkdirAll(c.extensionsLocalDir, os.ModePerm) 40 | } 41 | 42 | // LoadExtensionIndex loads the extensions index from a local file. 43 | // 44 | // This function takes a file path as an argument, reads the file, and returns a list of extensions. 45 | // 46 | // Args: 47 | // 48 | // indexFile (string): The path to the file containing the extensions index. 49 | // 50 | // Returns: 51 | // 52 | // Extensions: A list of extensions read from the file. 53 | // error: Any error that occurs during the loading process. 54 | func (c *Client) LoadExtensionIndex(indexFile string) (Extensions, error) { 55 | file, err := os.Open(indexFile) 56 | if err != nil { 57 | return Extensions{}, err 58 | } 59 | defer file.Close() 60 | 61 | var exResp wrappedExtensions 62 | if err := json.NewDecoder(file).Decode(&exResp); err != nil { 63 | return Extensions{}, err 64 | } 65 | 66 | return exResp.Data, nil 67 | } 68 | 69 | // GetExtensionsIndex retrieves the list of available extensions from the Zed API. 70 | // 71 | // This function takes a maximum schema version as an argument and returns a list of 72 | // extensions that are compatible with that version. 73 | // 74 | // Args: 75 | // 76 | // maxSchemaVersion (int): The maximum schema version that the extensions should be compatible with. 77 | // 78 | // Returns: 79 | // 80 | // Extensions: A list of extensions that match the provided schema version. 81 | // error: Any error that occurs during the retrieval process. 82 | func (c *Client) GetExtensionsIndex() (Extensions, error) { 83 | u := fmt.Sprintf("%s/extensions?max_schema_version=%d&include_native=true", c.apiHost, c.maxSchemaVersion) 84 | if _, err := url.Parse(u); err != nil { 85 | return Extensions{}, err 86 | } 87 | 88 | resp, err := http.Get(u) 89 | if err != nil { 90 | return Extensions{}, err 91 | } 92 | defer resp.Body.Close() 93 | 94 | var exResp wrappedExtensions 95 | if err := json.NewDecoder(resp.Body).Decode(&exResp); err != nil { 96 | return Extensions{}, err 97 | } 98 | 99 | return exResp.Data, nil 100 | } 101 | 102 | // DownloadExtensionArchive downloads the bytes of a tarball that contains the extension. 103 | // 104 | // This function takes an extension and version constraints as arguments and returns 105 | // the bytes of the tarball containing the extension. The version constraints are used 106 | // to filter the extensions that match the provided schema and WASM API versions. 107 | // 108 | // Args: 109 | // 110 | // extension (Extension): The extension to download. 111 | // minSchemaVersion (int): The minimum schema version that the extension should be compatible with. 112 | // minWasmAPIVersion (string): The minimum WASM API version that the extension should be compatible with. 113 | // maxWasmAPIVersion (string): The maximum WASM API version that the extension should be compatible with. 114 | // 115 | // Returns: 116 | // 117 | // []byte: The bytes of the tarball containing the extension. 118 | // error: Any error that occurs during the download process. 119 | func (c *Client) DownloadExtensionArchive(extension Extension, minSchemaVersion int, minWasmAPIVersion string, maxWasmAPIVersion string) ([]byte, error) { 120 | u := fmt.Sprintf( 121 | "%s/extensions/%s/download?min_schema_version=%d&max_schema_version=%d&min_wasm_api_version=%s&max_wasm_api_version=%s", 122 | c.apiHost, 123 | extension.ID, 124 | minSchemaVersion, 125 | c.maxSchemaVersion, 126 | minWasmAPIVersion, 127 | maxWasmAPIVersion, 128 | ) 129 | if _, err := url.Parse(u); err != nil { 130 | return []byte{}, err 131 | } 132 | 133 | resp, err := http.Get(u) 134 | if err != nil { 135 | return []byte{}, err 136 | } 137 | defer resp.Body.Close() 138 | if resp.StatusCode != http.StatusOK { 139 | return []byte{}, fmt.Errorf("HTTP request failed with status code %d", resp.StatusCode) 140 | } 141 | 142 | return io.ReadAll(resp.Body) 143 | } 144 | 145 | func (c *Client) DownloadExtensionArchiveDefault(extension Extension) ([]byte, error) { 146 | archiveBytes, err := c.DownloadExtensionArchive(extension, 0, "0.0.0", "100.0.0") // TODO: Fix version "hack" 147 | if err != nil { 148 | return []byte{}, err 149 | } 150 | 151 | if err := c.ensureExtensionsLocalDir(); err != nil { 152 | return []byte{}, err 153 | } 154 | 155 | return archiveBytes, nil 156 | } 157 | 158 | func (c *Client) LoadExtensionArchive(extension Extension) ([]byte, error) { 159 | if err := c.ensureExtensionsLocalDir(); err != nil { 160 | return []byte{}, err 161 | } 162 | 163 | filePath := fmt.Sprintf("%s/%s.tar.gz", c.extensionsLocalDir, extension.ID) 164 | file, err := os.Open(filePath) 165 | if err != nil { 166 | return []byte{}, err 167 | } 168 | defer file.Close() 169 | 170 | return io.ReadAll(file) 171 | } 172 | 173 | func (c *Client) GetLatestZedVersion() (Version, error) { 174 | os := runtime.GOOS 175 | arch := utils.IfElse(runtime.GOARCH == "amd64", "x86_64", runtime.GOARCH) 176 | u := fmt.Sprintf("%s/api/releases/latest?asset=zed&os=%s&arch=%s", c.host, os, arch) 177 | resp, err := http.Get(u) 178 | if err != nil { 179 | return Version{}, err 180 | } 181 | var ver Version 182 | if err := json.NewDecoder(resp.Body).Decode(&ver); err != nil { 183 | return Version{}, err 184 | } 185 | 186 | return ver, nil 187 | } 188 | 189 | func (c *Client) LoadLatestZedVersionFromFile(versionFile string) (Version, error) { 190 | file, err := os.Open(versionFile) 191 | if err != nil { 192 | return Version{}, err 193 | } 194 | defer file.Close() 195 | 196 | var ver Version 197 | if err := json.NewDecoder(file).Decode(&ver); err != nil { 198 | return Version{}, err 199 | } 200 | 201 | return ver, nil 202 | } 203 | 204 | func (c *Client) GetReleaseNotes(version string) (ReleaseNotes, error) { 205 | u := fmt.Sprintf("%s/api/release_notes/v2/stable/%s", c.host, version) 206 | if _, err := url.Parse(u); err != nil { 207 | return ReleaseNotes{}, err 208 | } 209 | 210 | resp, err := http.Get(u) 211 | if err != nil { 212 | return ReleaseNotes{}, err 213 | } 214 | defer resp.Body.Close() 215 | 216 | var releaseNotes ReleaseNotes 217 | if err := json.NewDecoder(resp.Body).Decode(&releaseNotes); err != nil { 218 | return ReleaseNotes{}, err 219 | } 220 | 221 | return releaseNotes, nil 222 | } 223 | 224 | func (c *Client) GetLatestReleaseNotes() (ReleaseNotes, error) { 225 | return c.GetReleaseNotes("") 226 | } 227 | 228 | func (c *Client) LoadReleaseNotes(releaseNotesFile string) (ReleaseNotes, error) { 229 | file, err := os.Open(releaseNotesFile) 230 | if err != nil { 231 | return ReleaseNotes{}, err 232 | } 233 | defer file.Close() 234 | 235 | var releaseNotes ReleaseNotes 236 | if err := json.NewDecoder(file).Decode(&releaseNotes); err != nil { 237 | return ReleaseNotes{}, err 238 | } 239 | 240 | return releaseNotes, nil 241 | } 242 | -------------------------------------------------------------------------------- /src/zed/client_test.go: -------------------------------------------------------------------------------- 1 | package zed 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | var zed = NewZedClient(1) 10 | 11 | func TestGetExtensionsList(t *testing.T) { 12 | extensions, err := zed.GetExtensionsIndex() 13 | assert.Nil(t, err) 14 | assert.Greater(t, extensions.Len(), 400) 15 | 16 | htmlExtension := extensions.GetByID("html") 17 | assert.NotNil(t, htmlExtension) 18 | assert.Equal(t, htmlExtension.ID, "html") 19 | assert.Equal(t, htmlExtension.Name, "HTML") 20 | assert.Greater(t, htmlExtension.DownloadCount, 1000000) 21 | } 22 | 23 | func TestDownloadExtensionArchive(t *testing.T) { 24 | extension := Extension{ 25 | ID: "html", 26 | Name: "HTML", 27 | Version: "0.1.4", 28 | Description: "HTML support.", 29 | Authors: []string{"Isaac Clayton "}, 30 | Repository: "https://github.com/zed-industries/zed", 31 | SchemaVersion: 1, 32 | WasmAPIVersion: "0.1.0", 33 | PublishedAt: "2024-11-15T15:20:59Z", 34 | DownloadCount: 1009996, 35 | } 36 | 37 | b, err := zed.DownloadExtensionArchive(extension, 0, "0.0.1", extension.WasmAPIVersion) 38 | assert.Nil(t, err) 39 | assert.Greater(t, len(b), 0) 40 | } 41 | -------------------------------------------------------------------------------- /src/zed/client_users.go: -------------------------------------------------------------------------------- 1 | package zed 2 | 3 | import ( 4 | "time" 5 | 6 | "google.golang.org/protobuf/proto" 7 | ) 8 | 9 | type GetAuthenticatedUserResponse struct { 10 | User AuthenticatedUser `json:"user"` 11 | FeatureFlags []string `json:"feature_flags"` 12 | Plan PlanInfo `json:"plan"` 13 | } 14 | 15 | type AuthenticatedUser struct { 16 | ID int `json:"id"` 17 | MetricsID string `json:"metrics_id"` 18 | AvatarURL string `json:"avatar_url"` 19 | GithubLogin string `json:"github_login"` 20 | Name *string `json:"name"` 21 | IsStaff bool `json:"is_staff"` 22 | AcceptedTosAt *string `json:"accepted_tos_at"` 23 | } 24 | 25 | type PlanInfo struct { 26 | Plan string `json:"plan"` 27 | SubscriptionPeriod *SubscriptionPeriod `json:"subscription_period"` 28 | Usage CurrentUsage `json:"usage"` 29 | TrialStartedAt *string `json:"trial_started_at"` 30 | IsUsageBasedBillingEnabled bool `json:"is_usage_based_billing_enabled"` 31 | IsAccountTooYoung bool `json:"is_account_too_young"` 32 | HasOverdueInvoices bool `json:"has_overdue_invoices"` 33 | } 34 | 35 | type SubscriptionPeriod struct { 36 | StartedAt string `json:"started_at"` 37 | EndedAt string `json:"ended_at"` 38 | } 39 | 40 | type AcceptTermsOfServiceResponse struct { 41 | User AuthenticatedUser `json:"user"` 42 | } 43 | 44 | type LlmToken struct { 45 | Token string `json:"token"` 46 | SupportsEditPrediction bool `json:"supports_edit_prediction"` 47 | } 48 | 49 | type CreateLlmTokenResponse struct { 50 | Token LlmToken `json:"token"` 51 | } 52 | 53 | type Plan int 54 | 55 | const ( 56 | // ZedFree is the free plan 57 | ZedFree Plan = iota 58 | // ZedPro is the pro plan 59 | ZedPro 60 | // ZedProTrial is the pro trial plan 61 | ZedProTrial 62 | ) 63 | 64 | func (p Plan) String() string { 65 | plans := [...]string{"Free", "ZedPro", "ZedProTrial"} 66 | return plans[p] 67 | } 68 | 69 | type GetSubscriptionResponse struct { 70 | Plan Plan `json:"plan"` 71 | Usage *CurrentUsage `json:"usage"` 72 | } 73 | 74 | type CurrentUsage struct { 75 | ModelRequests UsageData `json:"model_requests"` 76 | EditPredictions UsageData `json:"edit_predictions"` 77 | } 78 | 79 | type UsageData struct { 80 | Used uint32 `json:"used"` 81 | Limit string `json:"limit"` 82 | } 83 | 84 | type UsageLimit struct { 85 | Limited *int32 `json:"limited"` 86 | Unlimited bool `json:"unlimited"` 87 | } 88 | 89 | func NewGetAuthenticatedUsersResponse() GetAuthenticatedUserResponse { 90 | return GetAuthenticatedUserResponse{ 91 | User: AuthenticatedUser{ 92 | ID: 1, 93 | MetricsID: "", 94 | AvatarURL: "", 95 | // TODO: Fix me 96 | GithubLogin: "", 97 | Name: nil, 98 | IsStaff: false, 99 | AcceptedTosAt: proto.String(time.Now().UTC().Format(time.RFC3339)), 100 | }, 101 | FeatureFlags: []string{}, 102 | Plan: PlanInfo{ 103 | Plan: "Free", 104 | SubscriptionPeriod: nil, 105 | Usage: CurrentUsage{ 106 | ModelRequests: UsageData{ 107 | Used: 0, 108 | Limit: "unlimited", 109 | }, 110 | EditPredictions: UsageData{ 111 | Used: 0, 112 | Limit: "unlimited", 113 | }, 114 | }, 115 | TrialStartedAt: proto.String(time.Now().UTC().Format(time.RFC3339)), 116 | IsUsageBasedBillingEnabled: false, 117 | IsAccountTooYoung: false, 118 | HasOverdueInvoices: false, 119 | }, 120 | } 121 | } 122 | 123 | func NewLLMToken() CreateLlmTokenResponse { 124 | return CreateLlmTokenResponse{ 125 | Token: LlmToken{ 126 | Token: "le-token", 127 | SupportsEditPrediction: true, 128 | }, 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /src/zed/edit_predict.go: -------------------------------------------------------------------------------- 1 | package zed 2 | 3 | import ( 4 | "regexp" 5 | "strings" 6 | 7 | "zedex/llm" 8 | "zedex/utils" 9 | 10 | "github.com/google/uuid" 11 | "github.com/sirupsen/logrus" 12 | ) 13 | 14 | const ( 15 | EDIT_REGION_START = "<|editable_region_start|>" 16 | EDIT_REGION_END = "<|editable_region_end|>" 17 | START_OF_FILE = "<|start_of_file|>" 18 | ) 19 | 20 | type EditPredictClient struct { 21 | OpenAIHost llm.OpenAIHost 22 | cache utils.ConcurrentMap[string, string] 23 | concurrentRequests chan struct{} 24 | } 25 | 26 | type EditPredictRequest struct { 27 | Outline string `json:"outline"` 28 | InputEvents string `json:"input_events"` 29 | InputExcerpt string `json:"input_excerpt"` 30 | SpeculatedOutput string `json:"speculated_output"` 31 | } 32 | 33 | type EditPredictResponse struct { 34 | RequestId string `json:"request_id"` 35 | OutputExcerpt string `json:"output_excerpt"` 36 | } 37 | 38 | func NewEditPredictClient(openAIHost llm.OpenAIHost) EditPredictClient { 39 | return EditPredictClient{ 40 | OpenAIHost: openAIHost, 41 | cache: utils.NewConcurrentMap[string, string](), 42 | concurrentRequests: make(chan struct{}, 1), 43 | } 44 | } 45 | 46 | // WithConcurrentLLMRequests controls the number of concurrent in-flight requests made 47 | // towards the backing LLM. Setting it to something low may potentially increase cache 48 | // hit rate. 49 | func (epc *EditPredictClient) WithConcurrentLLMRequests(num int) { 50 | if num < 1 { 51 | logrus.Fatal("must set concurrency capacity to at least 1") 52 | } 53 | epc.concurrentRequests = make(chan struct{}, num) 54 | } 55 | 56 | func (c *EditPredictClient) HandleRequest(req EditPredictRequest) (EditPredictResponse, error) { 57 | // TODO: This is a naive concurrency control. Zed fires 3x completion request, but 58 | // it seems like it would only need one. By controlling concurrency we can more 59 | // efficiently increase cache hit rate. 60 | c.concurrentRequests <- struct{}{} 61 | defer func() { <-c.concurrentRequests }() 62 | 63 | if hit := c.cache.Get(req.InputExcerpt); hit != "" { 64 | logrus.Debugf("cache hit") 65 | epr := EditPredictResponse{ 66 | RequestId: uuid.New().String(), 67 | OutputExcerpt: hit, 68 | } 69 | return epr, nil 70 | } 71 | 72 | txt := extractEditableRegion(req.InputExcerpt) 73 | resp, err := c.OpenAIHost.Chat(txt) 74 | if err != nil || resp == nil { 75 | return EditPredictResponse{}, err 76 | } 77 | 78 | predicted := extractEditableRegion(resp.GetLastResponse()) 79 | response := replaceEditableRegion(req.InputExcerpt, predicted) 80 | response = removeReasoningBlock(response) 81 | response = removeCodeBlock(response) 82 | logrus.Debug(response) 83 | 84 | epr := EditPredictResponse{ 85 | RequestId: uuid.New().String(), 86 | OutputExcerpt: response, 87 | } 88 | c.cache.Set(req.InputExcerpt, epr.OutputExcerpt) 89 | 90 | return epr, nil 91 | } 92 | 93 | func extractEditableRegion(s string) string { 94 | startIndex := strings.Index(s, EDIT_REGION_START) 95 | endIndex := strings.Index(s, EDIT_REGION_END) 96 | if startIndex == -1 || endIndex == -1 { 97 | return "" 98 | } 99 | return s[startIndex : endIndex+len(EDIT_REGION_END)] 100 | } 101 | 102 | func replaceEditableRegion(original, replacement string) string { 103 | startIndex := strings.Index(original, EDIT_REGION_START) 104 | endIndex := strings.Index(original, EDIT_REGION_END) 105 | if startIndex == -1 || endIndex == -1 { 106 | return original 107 | } 108 | return original[:startIndex] + replacement + original[endIndex+len(EDIT_REGION_END):] 109 | } 110 | 111 | func removeReasoningBlock(s string) string { 112 | return regexp.MustCompile(`^.*?\s+?`).ReplaceAllString(s, "") 113 | } 114 | 115 | func removeCodeBlock(s string) string { 116 | firstLine := strings.SplitN(s, "\n", 2) 117 | if len(firstLine) == 2 && strings.HasPrefix(firstLine[0], "```") { 118 | s = firstLine[1] 119 | } 120 | if strings.HasSuffix(s, "```") { 121 | s = s[:len(s)-4] 122 | } 123 | if strings.HasPrefix(s, " ") { 124 | s = s[1:] 125 | } 126 | return s 127 | } 128 | -------------------------------------------------------------------------------- /src/zed/extension.go: -------------------------------------------------------------------------------- 1 | package zed 2 | 3 | import ( 4 | "encoding/json" 5 | "slices" 6 | "sort" 7 | ) 8 | 9 | type Extension struct { 10 | ID string `json:"id"` 11 | Name string `json:"name"` 12 | Version string `json:"version"` 13 | Description string `json:"description"` 14 | Authors []string `json:"authors"` 15 | Repository string `json:"repository"` 16 | Provides []string `json:"provides"` 17 | SchemaVersion int `json:"schema_version"` 18 | WasmAPIVersion string `json:"wasm_api_version"` 19 | PublishedAt string `json:"published_at"` 20 | DownloadCount int `json:"download_count"` 21 | } 22 | 23 | func (e Extension) AsJsonStr() string { 24 | jsonStr, _ := json.Marshal(e) 25 | return string(jsonStr) 26 | } 27 | 28 | type Extensions []Extension 29 | 30 | // wrappedExtension exists only to solve back and forth with the Zed API. 31 | type wrappedExtensions struct { 32 | Data Extensions `json:"data"` 33 | } 34 | 35 | func (ex Extensions) AsWrapped() wrappedExtensions { 36 | return wrappedExtensions{Data: ex} 37 | } 38 | 39 | func (e Extensions) Filter(f func(Extension) bool) Extensions { 40 | var filtered Extensions 41 | for _, ext := range e { 42 | if f(ext) { 43 | filtered = append(filtered, ext) 44 | } 45 | } 46 | return filtered 47 | } 48 | 49 | func (e Extensions) FilterBySchemaVersion(version int) Extensions { 50 | return e.Filter(func(ext Extension) bool { 51 | return ext.SchemaVersion == version 52 | }) 53 | } 54 | 55 | func (e Extensions) FilterByProvides(t string) Extensions { 56 | return e.Filter(func(ext Extension) bool { 57 | return slices.Contains(ext.Provides, t) 58 | }) 59 | } 60 | 61 | func (e Extensions) SortByDownloadCount(ascending bool) { 62 | sort.Slice(e, func(i, j int) bool { 63 | if ascending { 64 | return e[i].DownloadCount < e[j].DownloadCount 65 | } 66 | return e[i].DownloadCount > e[j].DownloadCount 67 | }) 68 | } 69 | 70 | func (e Extensions) Len() int { return len(e) } 71 | func (e Extensions) Swap(i, j int) { e[i], e[j] = e[j], e[i] } 72 | func (e Extensions) Less(i, j int) bool { return e[i].DownloadCount > e[j].DownloadCount } 73 | 74 | func (e Extensions) GetByID(id string) *Extension { 75 | for _, ext := range e { 76 | if ext.ID == id { 77 | return &ext 78 | } 79 | } 80 | return nil 81 | } 82 | -------------------------------------------------------------------------------- /src/zed/pb/ai.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | option go_package = "./pb"; 3 | package zed.messages; 4 | 5 | import "buffer.proto"; 6 | 7 | message Context { 8 | repeated ContextOperation operations = 1; 9 | } 10 | 11 | message ContextMetadata { 12 | string context_id = 1; 13 | optional string summary = 2; 14 | } 15 | 16 | message ContextMessageStatus { 17 | oneof variant { 18 | Done done = 1; 19 | Pending pending = 2; 20 | Error error = 3; 21 | Canceled canceled = 4; 22 | } 23 | 24 | message Done {} 25 | 26 | message Pending {} 27 | 28 | message Error { 29 | string message = 1; 30 | } 31 | 32 | message Canceled {} 33 | } 34 | 35 | message ContextMessage { 36 | LamportTimestamp id = 1; 37 | Anchor start = 2; 38 | LanguageModelRole role = 3; 39 | ContextMessageStatus status = 4; 40 | } 41 | 42 | message SlashCommandOutputSection { 43 | AnchorRange range = 1; 44 | string icon_name = 2; 45 | string label = 3; 46 | optional string metadata = 4; 47 | } 48 | 49 | message ThoughtProcessOutputSection { 50 | AnchorRange range = 1; 51 | } 52 | 53 | message ContextOperation { 54 | oneof variant { 55 | InsertMessage insert_message = 1; 56 | UpdateMessage update_message = 2; 57 | UpdateSummary update_summary = 3; 58 | BufferOperation buffer_operation = 5; 59 | SlashCommandStarted slash_command_started = 6; 60 | SlashCommandOutputSectionAdded slash_command_output_section_added = 7; 61 | SlashCommandCompleted slash_command_completed = 8; 62 | ThoughtProcessOutputSectionAdded thought_process_output_section_added = 9; 63 | } 64 | 65 | reserved 4; 66 | 67 | message InsertMessage { 68 | ContextMessage message = 1; 69 | repeated VectorClockEntry version = 2; 70 | } 71 | 72 | message UpdateMessage { 73 | LamportTimestamp message_id = 1; 74 | LanguageModelRole role = 2; 75 | ContextMessageStatus status = 3; 76 | LamportTimestamp timestamp = 4; 77 | repeated VectorClockEntry version = 5; 78 | } 79 | 80 | message UpdateSummary { 81 | string summary = 1; 82 | bool done = 2; 83 | LamportTimestamp timestamp = 3; 84 | repeated VectorClockEntry version = 4; 85 | } 86 | 87 | message SlashCommandStarted { 88 | LamportTimestamp id = 1; 89 | AnchorRange output_range = 2; 90 | string name = 3; 91 | repeated VectorClockEntry version = 4; 92 | } 93 | 94 | message SlashCommandOutputSectionAdded { 95 | LamportTimestamp timestamp = 1; 96 | SlashCommandOutputSection section = 2; 97 | repeated VectorClockEntry version = 3; 98 | } 99 | 100 | message SlashCommandCompleted { 101 | LamportTimestamp id = 1; 102 | LamportTimestamp timestamp = 3; 103 | optional string error_message = 4; 104 | repeated VectorClockEntry version = 5; 105 | } 106 | 107 | message ThoughtProcessOutputSectionAdded { 108 | LamportTimestamp timestamp = 1; 109 | ThoughtProcessOutputSection section = 2; 110 | repeated VectorClockEntry version = 3; 111 | } 112 | 113 | message BufferOperation { 114 | Operation operation = 1; 115 | } 116 | } 117 | 118 | message AdvertiseContexts { 119 | uint64 project_id = 1; 120 | repeated ContextMetadata contexts = 2; 121 | } 122 | 123 | message OpenContext { 124 | uint64 project_id = 1; 125 | string context_id = 2; 126 | } 127 | 128 | message OpenContextResponse { 129 | Context context = 1; 130 | } 131 | 132 | message CreateContext { 133 | uint64 project_id = 1; 134 | } 135 | 136 | message CreateContextResponse { 137 | string context_id = 1; 138 | Context context = 2; 139 | } 140 | 141 | message UpdateContext { 142 | uint64 project_id = 1; 143 | string context_id = 2; 144 | ContextOperation operation = 3; 145 | } 146 | 147 | message ContextVersion { 148 | string context_id = 1; 149 | repeated VectorClockEntry context_version = 2; 150 | repeated VectorClockEntry buffer_version = 3; 151 | } 152 | 153 | message SynchronizeContexts { 154 | uint64 project_id = 1; 155 | repeated ContextVersion contexts = 2; 156 | } 157 | 158 | message SynchronizeContextsResponse { 159 | repeated ContextVersion contexts = 1; 160 | } 161 | 162 | message GetLlmToken {} 163 | 164 | message GetLlmTokenResponse { 165 | string token = 1; 166 | } 167 | 168 | message RefreshLlmToken {} 169 | 170 | enum LanguageModelRole { 171 | LanguageModelUser = 0; 172 | LanguageModelAssistant = 1; 173 | LanguageModelSystem = 2; 174 | reserved 3; 175 | } 176 | -------------------------------------------------------------------------------- /src/zed/pb/app.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | option go_package = "./pb"; 3 | package zed.messages; 4 | 5 | message UpdateInviteInfo { 6 | string url = 1; 7 | uint32 count = 2; 8 | } 9 | 10 | message GetPrivateUserInfo {} 11 | 12 | message GetPrivateUserInfoResponse { 13 | string metrics_id = 1; 14 | bool staff = 2; 15 | repeated string flags = 3; 16 | optional uint64 accepted_tos_at = 4; 17 | } 18 | 19 | enum Plan { 20 | Free = 0; 21 | ZedPro = 1; 22 | ZedProTrial = 2; 23 | } 24 | 25 | message UpdateUserPlan { 26 | Plan plan = 1; 27 | optional uint64 trial_started_at = 2; 28 | optional bool is_usage_based_billing_enabled = 3; 29 | optional SubscriptionUsage usage = 4; 30 | optional SubscriptionPeriod subscription_period = 5; 31 | optional bool account_too_young = 6; 32 | optional bool has_overdue_invoices = 7; 33 | } 34 | 35 | message SubscriptionPeriod { 36 | uint64 started_at = 1; 37 | uint64 ended_at = 2; 38 | } 39 | 40 | message SubscriptionUsage { 41 | uint32 model_requests_usage_amount = 1; 42 | UsageLimit model_requests_usage_limit = 2; 43 | uint32 edit_predictions_usage_amount = 3; 44 | UsageLimit edit_predictions_usage_limit = 4; 45 | } 46 | 47 | message UsageLimit { 48 | oneof variant { 49 | Limited limited = 1; 50 | Unlimited unlimited = 2; 51 | } 52 | 53 | message Limited { 54 | uint32 limit = 1; 55 | } 56 | 57 | message Unlimited {} 58 | } 59 | 60 | message AcceptTermsOfService {} 61 | 62 | message AcceptTermsOfServiceResponse { 63 | uint64 accepted_tos_at = 1; 64 | } 65 | 66 | message ShutdownRemoteServer {} 67 | 68 | message Toast { 69 | uint64 project_id = 1; 70 | string notification_id = 2; 71 | string message = 3; 72 | } 73 | 74 | message HideToast { 75 | uint64 project_id = 1; 76 | string notification_id = 2; 77 | } 78 | 79 | message OpenServerSettings { 80 | uint64 project_id = 1; 81 | } 82 | 83 | message GetPanicFiles { 84 | } 85 | 86 | message GetPanicFilesResponse { 87 | repeated string file_contents = 2; 88 | } 89 | 90 | message Extension { 91 | string id = 1; 92 | string version = 2; 93 | bool dev = 3; 94 | } 95 | 96 | message SyncExtensions { 97 | repeated Extension extensions = 1; 98 | } 99 | 100 | message SyncExtensionsResponse { 101 | string tmp_dir = 1; 102 | repeated Extension missing_extensions = 2; 103 | } 104 | 105 | message InstallExtension { 106 | Extension extension = 1; 107 | string tmp_dir = 2; 108 | } 109 | 110 | message AskPassRequest { 111 | uint64 project_id = 1; 112 | reserved 2; 113 | uint64 repository_id = 3; 114 | uint64 askpass_id = 4; 115 | string prompt = 5; 116 | } 117 | 118 | message AskPassResponse { 119 | string response = 1; 120 | } 121 | 122 | message GetSupermavenApiKey {} 123 | 124 | message GetSupermavenApiKeyResponse { 125 | string api_key = 1; 126 | } 127 | -------------------------------------------------------------------------------- /src/zed/pb/binary_input_file: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/praktiskt/zedex/1e13384f04a5e95c89e7ad56c94647b212e75f9d/src/zed/pb/binary_input_file -------------------------------------------------------------------------------- /src/zed/pb/buf.yaml: -------------------------------------------------------------------------------- 1 | version: v1 2 | breaking: 3 | use: 4 | - WIRE 5 | -------------------------------------------------------------------------------- /src/zed/pb/buffer.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | option go_package = "./pb"; 3 | package zed.messages; 4 | 5 | import "core.proto"; 6 | import "worktree.proto"; 7 | 8 | message OpenNewBuffer { 9 | uint64 project_id = 1; 10 | } 11 | 12 | message OpenBufferResponse { 13 | uint64 buffer_id = 1; 14 | } 15 | 16 | message CreateBufferForPeer { 17 | uint64 project_id = 1; 18 | PeerId peer_id = 2; 19 | oneof variant { 20 | BufferState state = 3; 21 | BufferChunk chunk = 4; 22 | } 23 | } 24 | 25 | message UpdateBuffer { 26 | uint64 project_id = 1; 27 | uint64 buffer_id = 2; 28 | repeated Operation operations = 3; 29 | } 30 | 31 | message OpenBufferByPath { 32 | uint64 project_id = 1; 33 | uint64 worktree_id = 2; 34 | string path = 3; 35 | } 36 | 37 | message OpenBufferById { 38 | uint64 project_id = 1; 39 | uint64 id = 2; 40 | } 41 | 42 | message UpdateBufferFile { 43 | uint64 project_id = 1; 44 | uint64 buffer_id = 2; 45 | File file = 3; 46 | } 47 | 48 | message SaveBuffer { 49 | uint64 project_id = 1; 50 | uint64 buffer_id = 2; 51 | repeated VectorClockEntry version = 3; 52 | optional ProjectPath new_path = 4; 53 | } 54 | 55 | message CloseBuffer { 56 | uint64 project_id = 1; 57 | uint64 buffer_id = 2; 58 | } 59 | 60 | message BufferSaved { 61 | uint64 project_id = 1; 62 | uint64 buffer_id = 2; 63 | repeated VectorClockEntry version = 3; 64 | Timestamp mtime = 4; 65 | reserved 5; 66 | } 67 | 68 | message BufferReloaded { 69 | uint64 project_id = 1; 70 | uint64 buffer_id = 2; 71 | repeated VectorClockEntry version = 3; 72 | Timestamp mtime = 4; 73 | reserved 5; 74 | LineEnding line_ending = 6; 75 | } 76 | 77 | message ReloadBuffers { 78 | uint64 project_id = 1; 79 | repeated uint64 buffer_ids = 2; 80 | } 81 | 82 | message ReloadBuffersResponse { 83 | ProjectTransaction transaction = 1; 84 | } 85 | 86 | message SynchronizeBuffers { 87 | uint64 project_id = 1; 88 | repeated BufferVersion buffers = 2; 89 | } 90 | 91 | message SynchronizeBuffersResponse { 92 | repeated BufferVersion buffers = 1; 93 | } 94 | 95 | message BufferVersion { 96 | uint64 id = 1; 97 | repeated VectorClockEntry version = 2; 98 | } 99 | 100 | message BufferState { 101 | uint64 id = 1; 102 | optional File file = 2; 103 | string base_text = 3; 104 | LineEnding line_ending = 5; 105 | repeated VectorClockEntry saved_version = 6; 106 | Timestamp saved_mtime = 8; 107 | 108 | reserved 7; 109 | reserved 4; 110 | } 111 | 112 | message BufferChunk { 113 | uint64 buffer_id = 1; 114 | repeated Operation operations = 2; 115 | bool is_last = 3; 116 | } 117 | 118 | enum LineEnding { 119 | Unix = 0; 120 | Windows = 1; 121 | } 122 | 123 | message VectorClockEntry { 124 | uint32 replica_id = 1; 125 | uint32 timestamp = 2; 126 | } 127 | 128 | message UndoMapEntry { 129 | uint32 replica_id = 1; 130 | uint32 local_timestamp = 2; 131 | repeated UndoCount counts = 3; 132 | } 133 | 134 | message UndoCount { 135 | uint32 replica_id = 1; 136 | uint32 lamport_timestamp = 2; 137 | uint32 count = 3; 138 | } 139 | 140 | message Operation { 141 | oneof variant { 142 | Edit edit = 1; 143 | Undo undo = 2; 144 | UpdateSelections update_selections = 3; 145 | UpdateDiagnostics update_diagnostics = 4; 146 | UpdateCompletionTriggers update_completion_triggers = 5; 147 | } 148 | 149 | message Edit { 150 | uint32 replica_id = 1; 151 | uint32 lamport_timestamp = 2; 152 | repeated VectorClockEntry version = 3; 153 | repeated Range ranges = 4; 154 | repeated string new_text = 5; 155 | } 156 | 157 | message Undo { 158 | uint32 replica_id = 1; 159 | uint32 lamport_timestamp = 2; 160 | repeated VectorClockEntry version = 3; 161 | repeated UndoCount counts = 4; 162 | } 163 | 164 | message UpdateSelections { 165 | uint32 replica_id = 1; 166 | uint32 lamport_timestamp = 2; 167 | repeated Selection selections = 3; 168 | bool line_mode = 4; 169 | CursorShape cursor_shape = 5; 170 | } 171 | 172 | message UpdateCompletionTriggers { 173 | uint32 replica_id = 1; 174 | uint32 lamport_timestamp = 2; 175 | repeated string triggers = 3; 176 | uint64 language_server_id = 4; 177 | } 178 | } 179 | 180 | message ProjectTransaction { 181 | repeated uint64 buffer_ids = 1; 182 | repeated Transaction transactions = 2; 183 | } 184 | 185 | message Transaction { 186 | LamportTimestamp id = 1; 187 | repeated LamportTimestamp edit_ids = 2; 188 | repeated VectorClockEntry start = 3; 189 | } 190 | 191 | message LamportTimestamp { 192 | uint32 replica_id = 1; 193 | uint32 value = 2; 194 | } 195 | 196 | message Range { 197 | uint64 start = 1; 198 | uint64 end = 2; 199 | } 200 | 201 | message Selection { 202 | uint64 id = 1; 203 | EditorAnchor start = 2; 204 | EditorAnchor end = 3; 205 | bool reversed = 4; 206 | } 207 | 208 | message EditorAnchor { 209 | uint64 excerpt_id = 1; 210 | Anchor anchor = 2; 211 | } 212 | 213 | enum CursorShape { 214 | CursorBar = 0; 215 | CursorBlock = 1; 216 | CursorUnderscore = 2; 217 | CursorHollow = 3; 218 | } 219 | 220 | message UpdateDiagnostics { 221 | uint32 replica_id = 1; 222 | uint32 lamport_timestamp = 2; 223 | uint64 server_id = 3; 224 | repeated Diagnostic diagnostics = 4; 225 | } 226 | 227 | message Anchor { 228 | uint32 replica_id = 1; 229 | uint32 timestamp = 2; 230 | uint64 offset = 3; 231 | Bias bias = 4; 232 | optional uint64 buffer_id = 5; 233 | } 234 | 235 | message AnchorRange { 236 | Anchor start = 1; 237 | Anchor end = 2; 238 | } 239 | 240 | message Location { 241 | uint64 buffer_id = 1; 242 | Anchor start = 2; 243 | Anchor end = 3; 244 | } 245 | 246 | enum Bias { 247 | Left = 0; 248 | Right = 1; 249 | } 250 | 251 | message Diagnostic { 252 | Anchor start = 1; 253 | Anchor end = 2; 254 | optional string source = 3; 255 | 256 | enum SourceKind { 257 | Pulled = 0; 258 | Pushed = 1; 259 | Other = 2; 260 | } 261 | 262 | SourceKind source_kind = 16; 263 | Severity severity = 4; 264 | string message = 5; 265 | optional string code = 6; 266 | uint64 group_id = 7; 267 | bool is_primary = 8; 268 | 269 | reserved 9; 270 | 271 | bool is_disk_based = 10; 272 | bool is_unnecessary = 11; 273 | bool underline = 15; 274 | 275 | enum Severity { 276 | None = 0; 277 | Error = 1; 278 | Warning = 2; 279 | Information = 3; 280 | Hint = 4; 281 | } 282 | optional string data = 12; 283 | optional string code_description = 13; 284 | optional string markdown = 14; 285 | } 286 | 287 | message SearchQuery { 288 | string query = 2; 289 | bool regex = 3; 290 | bool whole_word = 4; 291 | bool case_sensitive = 5; 292 | string files_to_include = 6; 293 | string files_to_exclude = 7; 294 | bool match_full_paths = 9; 295 | bool include_ignored = 8; 296 | } 297 | 298 | message FindSearchCandidates { 299 | uint64 project_id = 1; 300 | SearchQuery query = 2; 301 | uint64 limit = 3; 302 | } 303 | 304 | message FindSearchCandidatesResponse { 305 | repeated uint64 buffer_ids = 1; 306 | } 307 | -------------------------------------------------------------------------------- /src/zed/pb/call.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | option go_package = "./pb"; 3 | package zed.messages; 4 | 5 | import "core.proto"; 6 | import "worktree.proto"; 7 | import "buffer.proto"; 8 | import "lsp.proto"; 9 | import "channel.proto"; 10 | import "git.proto"; 11 | 12 | message CreateRoom {} 13 | 14 | message CreateRoomResponse { 15 | Room room = 1; 16 | optional LiveKitConnectionInfo live_kit_connection_info = 2; 17 | } 18 | 19 | message JoinRoom { 20 | uint64 id = 1; 21 | } 22 | 23 | message JoinRoomResponse { 24 | Room room = 1; 25 | optional uint64 channel_id = 2; 26 | optional LiveKitConnectionInfo live_kit_connection_info = 3; 27 | } 28 | 29 | message RejoinRoom { 30 | uint64 id = 1; 31 | repeated UpdateProject reshared_projects = 2; 32 | repeated RejoinProject rejoined_projects = 3; 33 | } 34 | 35 | message RejoinRemoteProjects { 36 | repeated RejoinProject rejoined_projects = 1; 37 | } 38 | 39 | message RejoinRemoteProjectsResponse { 40 | repeated RejoinedProject rejoined_projects = 1; 41 | } 42 | 43 | message RejoinProject { 44 | uint64 id = 1; 45 | repeated RejoinWorktree worktrees = 2; 46 | repeated RejoinRepository repositories = 3; 47 | } 48 | 49 | message RejoinWorktree { 50 | uint64 id = 1; 51 | uint64 scan_id = 2; 52 | } 53 | 54 | message RejoinRepository { 55 | uint64 id = 1; 56 | uint64 scan_id = 2; 57 | } 58 | 59 | message RejoinRoomResponse { 60 | Room room = 1; 61 | repeated ResharedProject reshared_projects = 2; 62 | repeated RejoinedProject rejoined_projects = 3; 63 | } 64 | 65 | message ResharedProject { 66 | uint64 id = 1; 67 | repeated Collaborator collaborators = 2; 68 | } 69 | 70 | message RejoinedProject { 71 | uint64 id = 1; 72 | repeated WorktreeMetadata worktrees = 2; 73 | repeated Collaborator collaborators = 3; 74 | repeated LanguageServer language_servers = 4; 75 | } 76 | 77 | message LeaveRoom {} 78 | 79 | message Room { 80 | uint64 id = 1; 81 | repeated Participant participants = 2; 82 | repeated PendingParticipant pending_participants = 3; 83 | repeated Follower followers = 4; 84 | string livekit_room = 5; 85 | } 86 | 87 | message Participant { 88 | uint64 user_id = 1; 89 | PeerId peer_id = 2; 90 | repeated ParticipantProject projects = 3; 91 | ParticipantLocation location = 4; 92 | uint32 participant_index = 5; 93 | ChannelRole role = 6; 94 | reserved 7; 95 | } 96 | 97 | message PendingParticipant { 98 | uint64 user_id = 1; 99 | uint64 calling_user_id = 2; 100 | optional uint64 initial_project_id = 3; 101 | } 102 | 103 | message ParticipantProject { 104 | uint64 id = 1; 105 | repeated string worktree_root_names = 2; 106 | } 107 | 108 | message Follower { 109 | PeerId leader_id = 1; 110 | PeerId follower_id = 2; 111 | uint64 project_id = 3; 112 | } 113 | 114 | message ParticipantLocation { 115 | oneof variant { 116 | SharedProject shared_project = 1; 117 | UnsharedProject unshared_project = 2; 118 | External external = 3; 119 | } 120 | 121 | message SharedProject { 122 | uint64 id = 1; 123 | } 124 | 125 | message UnsharedProject {} 126 | 127 | message External {} 128 | } 129 | 130 | message Call { 131 | uint64 room_id = 1; 132 | uint64 called_user_id = 2; 133 | optional uint64 initial_project_id = 3; 134 | } 135 | 136 | message IncomingCall { 137 | uint64 room_id = 1; 138 | uint64 calling_user_id = 2; 139 | repeated uint64 participant_user_ids = 3; 140 | optional ParticipantProject initial_project = 4; 141 | } 142 | 143 | message CallCanceled { 144 | uint64 room_id = 1; 145 | } 146 | 147 | message CancelCall { 148 | uint64 room_id = 1; 149 | uint64 called_user_id = 2; 150 | } 151 | 152 | message DeclineCall { 153 | uint64 room_id = 1; 154 | } 155 | 156 | message UpdateParticipantLocation { 157 | uint64 room_id = 1; 158 | ParticipantLocation location = 2; 159 | } 160 | 161 | message RoomUpdated { 162 | Room room = 1; 163 | } 164 | 165 | message LiveKitConnectionInfo { 166 | string server_url = 1; 167 | string token = 2; 168 | bool can_publish = 3; 169 | } 170 | 171 | message ShareProject { 172 | uint64 room_id = 1; 173 | repeated WorktreeMetadata worktrees = 2; 174 | reserved 3; 175 | bool is_ssh_project = 4; 176 | } 177 | 178 | message ShareProjectResponse { 179 | uint64 project_id = 1; 180 | } 181 | 182 | message UnshareProject { 183 | uint64 project_id = 1; 184 | } 185 | 186 | message UpdateProject { 187 | uint64 project_id = 1; 188 | repeated WorktreeMetadata worktrees = 2; 189 | } 190 | 191 | message JoinProject { 192 | uint64 project_id = 1; 193 | optional string committer_email = 2; 194 | optional string committer_name = 3; 195 | } 196 | 197 | message JoinProjectResponse { 198 | uint64 project_id = 5; 199 | uint32 replica_id = 1; 200 | repeated WorktreeMetadata worktrees = 2; 201 | repeated Collaborator collaborators = 3; 202 | repeated LanguageServer language_servers = 4; 203 | ChannelRole role = 6; 204 | reserved 7; 205 | } 206 | 207 | message LeaveProject { 208 | uint64 project_id = 1; 209 | } 210 | 211 | message UpdateWorktree { 212 | uint64 project_id = 1; 213 | uint64 worktree_id = 2; 214 | string root_name = 3; 215 | repeated Entry updated_entries = 4; 216 | repeated uint64 removed_entries = 5; 217 | repeated RepositoryEntry updated_repositories = 6; // deprecated 218 | repeated uint64 removed_repositories = 7; // deprecated 219 | uint64 scan_id = 8; 220 | bool is_last_update = 9; 221 | string abs_path = 10; 222 | } 223 | 224 | // deprecated 225 | message RepositoryEntry { 226 | uint64 repository_id = 1; 227 | reserved 2; 228 | repeated StatusEntry updated_statuses = 3; 229 | repeated string removed_statuses = 4; 230 | repeated string current_merge_conflicts = 5; 231 | optional Branch branch_summary = 6; 232 | } 233 | 234 | message AddProjectCollaborator { 235 | uint64 project_id = 1; 236 | Collaborator collaborator = 2; 237 | } 238 | 239 | message UpdateProjectCollaborator { 240 | uint64 project_id = 1; 241 | PeerId old_peer_id = 2; 242 | PeerId new_peer_id = 3; 243 | } 244 | 245 | message RemoveProjectCollaborator { 246 | uint64 project_id = 1; 247 | PeerId peer_id = 2; 248 | } 249 | 250 | message GetUsers { 251 | repeated uint64 user_ids = 1; 252 | } 253 | 254 | message FuzzySearchUsers { 255 | string query = 1; 256 | } 257 | 258 | message UsersResponse { 259 | repeated User users = 1; 260 | } 261 | 262 | message RequestContact { 263 | uint64 responder_id = 1; 264 | } 265 | 266 | message RemoveContact { 267 | uint64 user_id = 1; 268 | } 269 | 270 | message RespondToContactRequest { 271 | uint64 requester_id = 1; 272 | ContactRequestResponse response = 2; 273 | } 274 | 275 | enum ContactRequestResponse { 276 | Accept = 0; 277 | Decline = 1; 278 | Block = 2; 279 | Dismiss = 3; 280 | } 281 | 282 | message UpdateContacts { 283 | repeated Contact contacts = 1; 284 | repeated uint64 remove_contacts = 2; 285 | repeated IncomingContactRequest incoming_requests = 3; 286 | repeated uint64 remove_incoming_requests = 4; 287 | repeated uint64 outgoing_requests = 5; 288 | repeated uint64 remove_outgoing_requests = 6; 289 | } 290 | 291 | message ShowContacts {} 292 | 293 | message IncomingContactRequest { 294 | uint64 requester_id = 1; 295 | } 296 | 297 | message Follow { 298 | uint64 room_id = 1; 299 | optional uint64 project_id = 2; 300 | PeerId leader_id = 3; 301 | } 302 | 303 | message FollowResponse { 304 | View active_view = 3; 305 | // TODO: Remove after version 0.145.x stabilizes. 306 | optional ViewId active_view_id = 1; 307 | repeated View views = 2; 308 | } 309 | 310 | message UpdateFollowers { 311 | uint64 room_id = 1; 312 | optional uint64 project_id = 2; 313 | reserved 3; 314 | oneof variant { 315 | View create_view = 5; 316 | // TODO: Remove after version 0.145.x stabilizes. 317 | UpdateActiveView update_active_view = 4; 318 | UpdateView update_view = 6; 319 | } 320 | } 321 | 322 | message Unfollow { 323 | uint64 room_id = 1; 324 | optional uint64 project_id = 2; 325 | PeerId leader_id = 3; 326 | } 327 | 328 | message ViewId { 329 | PeerId creator = 1; 330 | uint64 id = 2; 331 | } 332 | 333 | message UpdateActiveView { 334 | optional ViewId id = 1; 335 | optional PeerId leader_id = 2; 336 | View view = 3; 337 | } 338 | 339 | enum PanelId { 340 | AssistantPanel = 0; 341 | DebugPanel = 1; 342 | } 343 | 344 | message UpdateView { 345 | ViewId id = 1; 346 | optional PeerId leader_id = 2; 347 | 348 | oneof variant { 349 | Editor editor = 3; 350 | } 351 | 352 | message Editor { 353 | repeated ExcerptInsertion inserted_excerpts = 1; 354 | repeated uint64 deleted_excerpts = 2; 355 | repeated Selection selections = 3; 356 | optional Selection pending_selection = 4; 357 | EditorAnchor scroll_top_anchor = 5; 358 | float scroll_x = 6; 359 | float scroll_y = 7; 360 | } 361 | } 362 | 363 | message View { 364 | ViewId id = 1; 365 | optional PeerId leader_id = 2; 366 | optional PanelId panel_id = 6; 367 | 368 | oneof variant { 369 | Editor editor = 3; 370 | ChannelView channel_view = 4; 371 | ContextEditor context_editor = 5; 372 | } 373 | 374 | message Editor { 375 | bool singleton = 1; 376 | optional string title = 2; 377 | repeated Excerpt excerpts = 3; 378 | repeated Selection selections = 4; 379 | optional Selection pending_selection = 5; 380 | EditorAnchor scroll_top_anchor = 6; 381 | float scroll_x = 7; 382 | float scroll_y = 8; 383 | } 384 | 385 | message ChannelView { 386 | uint64 channel_id = 1; 387 | Editor editor = 2; 388 | } 389 | 390 | message ContextEditor { 391 | string context_id = 1; 392 | Editor editor = 2; 393 | } 394 | } 395 | 396 | message ExcerptInsertion { 397 | Excerpt excerpt = 1; 398 | optional uint64 previous_excerpt_id = 2; 399 | } 400 | 401 | message Excerpt { 402 | uint64 id = 1; 403 | uint64 buffer_id = 2; 404 | Anchor context_start = 3; 405 | Anchor context_end = 4; 406 | Anchor primary_start = 5; 407 | Anchor primary_end = 6; 408 | } 409 | 410 | message Contact { 411 | uint64 user_id = 1; 412 | bool online = 2; 413 | bool busy = 3; 414 | } 415 | 416 | message SetRoomParticipantRole { 417 | uint64 room_id = 1; 418 | uint64 user_id = 2; 419 | ChannelRole role = 3; 420 | } 421 | -------------------------------------------------------------------------------- /src/zed/pb/channel.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | option go_package = "./pb"; 3 | package zed.messages; 4 | 5 | import "core.proto"; 6 | import "buffer.proto"; 7 | 8 | message Channel { 9 | uint64 id = 1; 10 | string name = 2; 11 | ChannelVisibility visibility = 3; 12 | int32 channel_order = 4; 13 | repeated uint64 parent_path = 5; 14 | } 15 | 16 | enum ChannelVisibility { 17 | Public = 0; 18 | Members = 1; 19 | } 20 | 21 | message UpdateChannels { 22 | repeated Channel channels = 1; 23 | repeated uint64 delete_channels = 4; 24 | repeated Channel channel_invitations = 5; 25 | repeated uint64 remove_channel_invitations = 6; 26 | repeated ChannelParticipants channel_participants = 7; 27 | repeated ChannelMessageId latest_channel_message_ids = 8; 28 | repeated ChannelBufferVersion latest_channel_buffer_versions = 9; 29 | 30 | reserved 10 to 15; 31 | } 32 | 33 | message UpdateUserChannels { 34 | repeated ChannelMessageId observed_channel_message_id = 1; 35 | repeated ChannelBufferVersion observed_channel_buffer_version = 2; 36 | repeated ChannelMembership channel_memberships = 3; 37 | } 38 | 39 | message ChannelMembership { 40 | uint64 channel_id = 1; 41 | ChannelRole role = 2; 42 | } 43 | 44 | message ChannelMessageId { 45 | uint64 channel_id = 1; 46 | uint64 message_id = 2; 47 | } 48 | 49 | message ChannelPermission { 50 | uint64 channel_id = 1; 51 | ChannelRole role = 3; 52 | } 53 | 54 | message ChannelParticipants { 55 | uint64 channel_id = 1; 56 | repeated uint64 participant_user_ids = 2; 57 | } 58 | 59 | message JoinChannel { 60 | uint64 channel_id = 1; 61 | } 62 | 63 | message DeleteChannel { 64 | uint64 channel_id = 1; 65 | } 66 | 67 | message GetChannelMembers { 68 | uint64 channel_id = 1; 69 | string query = 2; 70 | uint64 limit = 3; 71 | } 72 | 73 | message GetChannelMembersResponse { 74 | repeated ChannelMember members = 1; 75 | repeated User users = 2; 76 | } 77 | 78 | message ChannelMember { 79 | uint64 user_id = 1; 80 | Kind kind = 3; 81 | ChannelRole role = 4; 82 | 83 | enum Kind { 84 | Member = 0; 85 | Invitee = 1; 86 | } 87 | } 88 | 89 | message SubscribeToChannels {} 90 | 91 | message CreateChannel { 92 | string name = 1; 93 | optional uint64 parent_id = 2; 94 | } 95 | 96 | message CreateChannelResponse { 97 | Channel channel = 1; 98 | optional uint64 parent_id = 2; 99 | } 100 | 101 | message InviteChannelMember { 102 | uint64 channel_id = 1; 103 | uint64 user_id = 2; 104 | ChannelRole role = 4; 105 | } 106 | 107 | message RemoveChannelMember { 108 | uint64 channel_id = 1; 109 | uint64 user_id = 2; 110 | } 111 | 112 | enum ChannelRole { 113 | Admin = 0; 114 | Member = 1; 115 | Guest = 2; 116 | Banned = 3; 117 | Talker = 4; 118 | } 119 | 120 | message SetChannelMemberRole { 121 | uint64 channel_id = 1; 122 | uint64 user_id = 2; 123 | ChannelRole role = 3; 124 | } 125 | 126 | message SetChannelVisibility { 127 | uint64 channel_id = 1; 128 | ChannelVisibility visibility = 2; 129 | } 130 | 131 | message RenameChannel { 132 | uint64 channel_id = 1; 133 | string name = 2; 134 | } 135 | 136 | message RenameChannelResponse { 137 | Channel channel = 1; 138 | } 139 | 140 | message JoinChannelChat { 141 | uint64 channel_id = 1; 142 | } 143 | 144 | message JoinChannelChatResponse { 145 | repeated ChannelMessage messages = 1; 146 | bool done = 2; 147 | } 148 | 149 | message LeaveChannelChat { 150 | uint64 channel_id = 1; 151 | } 152 | 153 | message SendChannelMessage { 154 | uint64 channel_id = 1; 155 | string body = 2; 156 | Nonce nonce = 3; 157 | repeated ChatMention mentions = 4; 158 | optional uint64 reply_to_message_id = 5; 159 | } 160 | 161 | message RemoveChannelMessage { 162 | uint64 channel_id = 1; 163 | uint64 message_id = 2; 164 | } 165 | 166 | message UpdateChannelMessage { 167 | uint64 channel_id = 1; 168 | uint64 message_id = 2; 169 | Nonce nonce = 4; 170 | string body = 5; 171 | repeated ChatMention mentions = 6; 172 | } 173 | 174 | message AckChannelMessage { 175 | uint64 channel_id = 1; 176 | uint64 message_id = 2; 177 | } 178 | 179 | message SendChannelMessageResponse { 180 | ChannelMessage message = 1; 181 | } 182 | 183 | message ChannelMessageSent { 184 | uint64 channel_id = 1; 185 | ChannelMessage message = 2; 186 | } 187 | 188 | message ChannelMessageUpdate { 189 | uint64 channel_id = 1; 190 | ChannelMessage message = 2; 191 | } 192 | 193 | message GetChannelMessages { 194 | uint64 channel_id = 1; 195 | uint64 before_message_id = 2; 196 | } 197 | 198 | message GetChannelMessagesResponse { 199 | repeated ChannelMessage messages = 1; 200 | bool done = 2; 201 | } 202 | 203 | message GetChannelMessagesById { 204 | repeated uint64 message_ids = 1; 205 | } 206 | 207 | message MoveChannel { 208 | uint64 channel_id = 1; 209 | uint64 to = 2; 210 | } 211 | 212 | message ReorderChannel { 213 | uint64 channel_id = 1; 214 | enum Direction { 215 | Up = 0; 216 | Down = 1; 217 | } 218 | Direction direction = 2; 219 | } 220 | 221 | message JoinChannelBuffer { 222 | uint64 channel_id = 1; 223 | } 224 | 225 | message ChannelBufferVersion { 226 | uint64 channel_id = 1; 227 | repeated VectorClockEntry version = 2; 228 | uint64 epoch = 3; 229 | } 230 | 231 | message UpdateChannelBufferCollaborators { 232 | uint64 channel_id = 1; 233 | repeated Collaborator collaborators = 2; 234 | } 235 | 236 | message UpdateChannelBuffer { 237 | uint64 channel_id = 1; 238 | repeated Operation operations = 2; 239 | } 240 | 241 | message ChannelMessage { 242 | uint64 id = 1; 243 | string body = 2; 244 | uint64 timestamp = 3; 245 | uint64 sender_id = 4; 246 | Nonce nonce = 5; 247 | repeated ChatMention mentions = 6; 248 | optional uint64 reply_to_message_id = 7; 249 | optional uint64 edited_at = 8; 250 | } 251 | 252 | message ChatMention { 253 | Range range = 1; 254 | uint64 user_id = 2; 255 | } 256 | 257 | message RejoinChannelBuffers { 258 | repeated ChannelBufferVersion buffers = 1; 259 | } 260 | 261 | message RejoinChannelBuffersResponse { 262 | repeated RejoinedChannelBuffer buffers = 1; 263 | } 264 | 265 | message AckBufferOperation { 266 | uint64 buffer_id = 1; 267 | uint64 epoch = 2; 268 | repeated VectorClockEntry version = 3; 269 | } 270 | 271 | message JoinChannelBufferResponse { 272 | uint64 buffer_id = 1; 273 | uint32 replica_id = 2; 274 | string base_text = 3; 275 | repeated Operation operations = 4; 276 | repeated Collaborator collaborators = 5; 277 | uint64 epoch = 6; 278 | } 279 | 280 | message RejoinedChannelBuffer { 281 | uint64 channel_id = 1; 282 | repeated VectorClockEntry version = 2; 283 | repeated Operation operations = 3; 284 | repeated Collaborator collaborators = 4; 285 | } 286 | 287 | message LeaveChannelBuffer { 288 | uint64 channel_id = 1; 289 | } 290 | 291 | message RespondToChannelInvite { 292 | uint64 channel_id = 1; 293 | bool accept = 2; 294 | } 295 | -------------------------------------------------------------------------------- /src/zed/pb/core.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // versions: 3 | // protoc-gen-go v1.34.1 4 | // protoc v3.21.12 5 | // source: core.proto 6 | 7 | package pb 8 | 9 | import ( 10 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 11 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 12 | reflect "reflect" 13 | sync "sync" 14 | ) 15 | 16 | const ( 17 | // Verify that this generated code is sufficiently up-to-date. 18 | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) 19 | // Verify that runtime/protoimpl is sufficiently up-to-date. 20 | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) 21 | ) 22 | 23 | type PeerId struct { 24 | state protoimpl.MessageState 25 | sizeCache protoimpl.SizeCache 26 | unknownFields protoimpl.UnknownFields 27 | 28 | OwnerId uint32 `protobuf:"varint,1,opt,name=owner_id,json=ownerId,proto3" json:"owner_id,omitempty"` 29 | Id uint32 `protobuf:"varint,2,opt,name=id,proto3" json:"id,omitempty"` 30 | } 31 | 32 | func (x *PeerId) Reset() { 33 | *x = PeerId{} 34 | if protoimpl.UnsafeEnabled { 35 | mi := &file_core_proto_msgTypes[0] 36 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 37 | ms.StoreMessageInfo(mi) 38 | } 39 | } 40 | 41 | func (x *PeerId) String() string { 42 | return protoimpl.X.MessageStringOf(x) 43 | } 44 | 45 | func (*PeerId) ProtoMessage() {} 46 | 47 | func (x *PeerId) ProtoReflect() protoreflect.Message { 48 | mi := &file_core_proto_msgTypes[0] 49 | if protoimpl.UnsafeEnabled && x != nil { 50 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 51 | if ms.LoadMessageInfo() == nil { 52 | ms.StoreMessageInfo(mi) 53 | } 54 | return ms 55 | } 56 | return mi.MessageOf(x) 57 | } 58 | 59 | // Deprecated: Use PeerId.ProtoReflect.Descriptor instead. 60 | func (*PeerId) Descriptor() ([]byte, []int) { 61 | return file_core_proto_rawDescGZIP(), []int{0} 62 | } 63 | 64 | func (x *PeerId) GetOwnerId() uint32 { 65 | if x != nil { 66 | return x.OwnerId 67 | } 68 | return 0 69 | } 70 | 71 | func (x *PeerId) GetId() uint32 { 72 | if x != nil { 73 | return x.Id 74 | } 75 | return 0 76 | } 77 | 78 | type User struct { 79 | state protoimpl.MessageState 80 | sizeCache protoimpl.SizeCache 81 | unknownFields protoimpl.UnknownFields 82 | 83 | Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` 84 | GithubLogin string `protobuf:"bytes,2,opt,name=github_login,json=githubLogin,proto3" json:"github_login,omitempty"` 85 | AvatarUrl string `protobuf:"bytes,3,opt,name=avatar_url,json=avatarUrl,proto3" json:"avatar_url,omitempty"` 86 | Name *string `protobuf:"bytes,5,opt,name=name,proto3,oneof" json:"name,omitempty"` 87 | } 88 | 89 | func (x *User) Reset() { 90 | *x = User{} 91 | if protoimpl.UnsafeEnabled { 92 | mi := &file_core_proto_msgTypes[1] 93 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 94 | ms.StoreMessageInfo(mi) 95 | } 96 | } 97 | 98 | func (x *User) String() string { 99 | return protoimpl.X.MessageStringOf(x) 100 | } 101 | 102 | func (*User) ProtoMessage() {} 103 | 104 | func (x *User) ProtoReflect() protoreflect.Message { 105 | mi := &file_core_proto_msgTypes[1] 106 | if protoimpl.UnsafeEnabled && x != nil { 107 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 108 | if ms.LoadMessageInfo() == nil { 109 | ms.StoreMessageInfo(mi) 110 | } 111 | return ms 112 | } 113 | return mi.MessageOf(x) 114 | } 115 | 116 | // Deprecated: Use User.ProtoReflect.Descriptor instead. 117 | func (*User) Descriptor() ([]byte, []int) { 118 | return file_core_proto_rawDescGZIP(), []int{1} 119 | } 120 | 121 | func (x *User) GetId() uint64 { 122 | if x != nil { 123 | return x.Id 124 | } 125 | return 0 126 | } 127 | 128 | func (x *User) GetGithubLogin() string { 129 | if x != nil { 130 | return x.GithubLogin 131 | } 132 | return "" 133 | } 134 | 135 | func (x *User) GetAvatarUrl() string { 136 | if x != nil { 137 | return x.AvatarUrl 138 | } 139 | return "" 140 | } 141 | 142 | func (x *User) GetName() string { 143 | if x != nil && x.Name != nil { 144 | return *x.Name 145 | } 146 | return "" 147 | } 148 | 149 | type Nonce struct { 150 | state protoimpl.MessageState 151 | sizeCache protoimpl.SizeCache 152 | unknownFields protoimpl.UnknownFields 153 | 154 | UpperHalf uint64 `protobuf:"varint,1,opt,name=upper_half,json=upperHalf,proto3" json:"upper_half,omitempty"` 155 | LowerHalf uint64 `protobuf:"varint,2,opt,name=lower_half,json=lowerHalf,proto3" json:"lower_half,omitempty"` 156 | } 157 | 158 | func (x *Nonce) Reset() { 159 | *x = Nonce{} 160 | if protoimpl.UnsafeEnabled { 161 | mi := &file_core_proto_msgTypes[2] 162 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 163 | ms.StoreMessageInfo(mi) 164 | } 165 | } 166 | 167 | func (x *Nonce) String() string { 168 | return protoimpl.X.MessageStringOf(x) 169 | } 170 | 171 | func (*Nonce) ProtoMessage() {} 172 | 173 | func (x *Nonce) ProtoReflect() protoreflect.Message { 174 | mi := &file_core_proto_msgTypes[2] 175 | if protoimpl.UnsafeEnabled && x != nil { 176 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 177 | if ms.LoadMessageInfo() == nil { 178 | ms.StoreMessageInfo(mi) 179 | } 180 | return ms 181 | } 182 | return mi.MessageOf(x) 183 | } 184 | 185 | // Deprecated: Use Nonce.ProtoReflect.Descriptor instead. 186 | func (*Nonce) Descriptor() ([]byte, []int) { 187 | return file_core_proto_rawDescGZIP(), []int{2} 188 | } 189 | 190 | func (x *Nonce) GetUpperHalf() uint64 { 191 | if x != nil { 192 | return x.UpperHalf 193 | } 194 | return 0 195 | } 196 | 197 | func (x *Nonce) GetLowerHalf() uint64 { 198 | if x != nil { 199 | return x.LowerHalf 200 | } 201 | return 0 202 | } 203 | 204 | type Collaborator struct { 205 | state protoimpl.MessageState 206 | sizeCache protoimpl.SizeCache 207 | unknownFields protoimpl.UnknownFields 208 | 209 | PeerId *PeerId `protobuf:"bytes,1,opt,name=peer_id,json=peerId,proto3" json:"peer_id,omitempty"` 210 | ReplicaId uint32 `protobuf:"varint,2,opt,name=replica_id,json=replicaId,proto3" json:"replica_id,omitempty"` 211 | UserId uint64 `protobuf:"varint,3,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` 212 | IsHost bool `protobuf:"varint,4,opt,name=is_host,json=isHost,proto3" json:"is_host,omitempty"` 213 | CommitterName *string `protobuf:"bytes,5,opt,name=committer_name,json=committerName,proto3,oneof" json:"committer_name,omitempty"` 214 | CommitterEmail *string `protobuf:"bytes,6,opt,name=committer_email,json=committerEmail,proto3,oneof" json:"committer_email,omitempty"` 215 | } 216 | 217 | func (x *Collaborator) Reset() { 218 | *x = Collaborator{} 219 | if protoimpl.UnsafeEnabled { 220 | mi := &file_core_proto_msgTypes[3] 221 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 222 | ms.StoreMessageInfo(mi) 223 | } 224 | } 225 | 226 | func (x *Collaborator) String() string { 227 | return protoimpl.X.MessageStringOf(x) 228 | } 229 | 230 | func (*Collaborator) ProtoMessage() {} 231 | 232 | func (x *Collaborator) ProtoReflect() protoreflect.Message { 233 | mi := &file_core_proto_msgTypes[3] 234 | if protoimpl.UnsafeEnabled && x != nil { 235 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 236 | if ms.LoadMessageInfo() == nil { 237 | ms.StoreMessageInfo(mi) 238 | } 239 | return ms 240 | } 241 | return mi.MessageOf(x) 242 | } 243 | 244 | // Deprecated: Use Collaborator.ProtoReflect.Descriptor instead. 245 | func (*Collaborator) Descriptor() ([]byte, []int) { 246 | return file_core_proto_rawDescGZIP(), []int{3} 247 | } 248 | 249 | func (x *Collaborator) GetPeerId() *PeerId { 250 | if x != nil { 251 | return x.PeerId 252 | } 253 | return nil 254 | } 255 | 256 | func (x *Collaborator) GetReplicaId() uint32 { 257 | if x != nil { 258 | return x.ReplicaId 259 | } 260 | return 0 261 | } 262 | 263 | func (x *Collaborator) GetUserId() uint64 { 264 | if x != nil { 265 | return x.UserId 266 | } 267 | return 0 268 | } 269 | 270 | func (x *Collaborator) GetIsHost() bool { 271 | if x != nil { 272 | return x.IsHost 273 | } 274 | return false 275 | } 276 | 277 | func (x *Collaborator) GetCommitterName() string { 278 | if x != nil && x.CommitterName != nil { 279 | return *x.CommitterName 280 | } 281 | return "" 282 | } 283 | 284 | func (x *Collaborator) GetCommitterEmail() string { 285 | if x != nil && x.CommitterEmail != nil { 286 | return *x.CommitterEmail 287 | } 288 | return "" 289 | } 290 | 291 | var File_core_proto protoreflect.FileDescriptor 292 | 293 | var file_core_proto_rawDesc = []byte{ 294 | 0x0a, 0x0a, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x7a, 0x65, 295 | 0x64, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x22, 0x33, 0x0a, 0x06, 0x50, 0x65, 296 | 0x65, 0x72, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 297 | 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 298 | 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, 0x22, 299 | 0x80, 0x01, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 300 | 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x67, 0x69, 0x74, 0x68, 301 | 0x75, 0x62, 0x5f, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 302 | 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 303 | 0x76, 0x61, 0x74, 0x61, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 304 | 0x09, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x55, 0x72, 0x6c, 0x12, 0x17, 0x0a, 0x04, 0x6e, 0x61, 305 | 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 306 | 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x4a, 0x04, 0x08, 0x04, 307 | 0x10, 0x05, 0x22, 0x45, 0x0a, 0x05, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 308 | 0x70, 0x70, 0x65, 0x72, 0x5f, 0x68, 0x61, 0x6c, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 309 | 0x09, 0x75, 0x70, 0x70, 0x65, 0x72, 0x48, 0x61, 0x6c, 0x66, 0x12, 0x1d, 0x0a, 0x0a, 0x6c, 0x6f, 310 | 0x77, 0x65, 0x72, 0x5f, 0x68, 0x61, 0x6c, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 311 | 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x48, 0x61, 0x6c, 0x66, 0x22, 0x8f, 0x02, 0x0a, 0x0c, 0x43, 0x6f, 312 | 0x6c, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x2d, 0x0a, 0x07, 0x70, 0x65, 313 | 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x7a, 0x65, 314 | 0x64, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x49, 315 | 0x64, 0x52, 0x06, 0x70, 0x65, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x70, 316 | 0x6c, 0x69, 0x63, 0x61, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 317 | 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 318 | 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 319 | 0x64, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x73, 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 320 | 0x28, 0x08, 0x52, 0x06, 0x69, 0x73, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x0e, 0x63, 0x6f, 321 | 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 322 | 0x28, 0x09, 0x48, 0x00, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x4e, 323 | 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x2c, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 324 | 0x74, 0x65, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, 325 | 0x01, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x45, 0x6d, 0x61, 0x69, 326 | 0x6c, 0x88, 0x01, 0x01, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 327 | 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x12, 0x0a, 0x10, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 328 | 0x69, 0x74, 0x74, 0x65, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x42, 0x06, 0x5a, 0x04, 0x2e, 329 | 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 330 | } 331 | 332 | var ( 333 | file_core_proto_rawDescOnce sync.Once 334 | file_core_proto_rawDescData = file_core_proto_rawDesc 335 | ) 336 | 337 | func file_core_proto_rawDescGZIP() []byte { 338 | file_core_proto_rawDescOnce.Do(func() { 339 | file_core_proto_rawDescData = protoimpl.X.CompressGZIP(file_core_proto_rawDescData) 340 | }) 341 | return file_core_proto_rawDescData 342 | } 343 | 344 | var file_core_proto_msgTypes = make([]protoimpl.MessageInfo, 4) 345 | var file_core_proto_goTypes = []interface{}{ 346 | (*PeerId)(nil), // 0: zed.messages.PeerId 347 | (*User)(nil), // 1: zed.messages.User 348 | (*Nonce)(nil), // 2: zed.messages.Nonce 349 | (*Collaborator)(nil), // 3: zed.messages.Collaborator 350 | } 351 | var file_core_proto_depIdxs = []int32{ 352 | 0, // 0: zed.messages.Collaborator.peer_id:type_name -> zed.messages.PeerId 353 | 1, // [1:1] is the sub-list for method output_type 354 | 1, // [1:1] is the sub-list for method input_type 355 | 1, // [1:1] is the sub-list for extension type_name 356 | 1, // [1:1] is the sub-list for extension extendee 357 | 0, // [0:1] is the sub-list for field type_name 358 | } 359 | 360 | func init() { file_core_proto_init() } 361 | func file_core_proto_init() { 362 | if File_core_proto != nil { 363 | return 364 | } 365 | if !protoimpl.UnsafeEnabled { 366 | file_core_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { 367 | switch v := v.(*PeerId); i { 368 | case 0: 369 | return &v.state 370 | case 1: 371 | return &v.sizeCache 372 | case 2: 373 | return &v.unknownFields 374 | default: 375 | return nil 376 | } 377 | } 378 | file_core_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { 379 | switch v := v.(*User); i { 380 | case 0: 381 | return &v.state 382 | case 1: 383 | return &v.sizeCache 384 | case 2: 385 | return &v.unknownFields 386 | default: 387 | return nil 388 | } 389 | } 390 | file_core_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { 391 | switch v := v.(*Nonce); i { 392 | case 0: 393 | return &v.state 394 | case 1: 395 | return &v.sizeCache 396 | case 2: 397 | return &v.unknownFields 398 | default: 399 | return nil 400 | } 401 | } 402 | file_core_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { 403 | switch v := v.(*Collaborator); i { 404 | case 0: 405 | return &v.state 406 | case 1: 407 | return &v.sizeCache 408 | case 2: 409 | return &v.unknownFields 410 | default: 411 | return nil 412 | } 413 | } 414 | } 415 | file_core_proto_msgTypes[1].OneofWrappers = []interface{}{} 416 | file_core_proto_msgTypes[3].OneofWrappers = []interface{}{} 417 | type x struct{} 418 | out := protoimpl.TypeBuilder{ 419 | File: protoimpl.DescBuilder{ 420 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 421 | RawDescriptor: file_core_proto_rawDesc, 422 | NumEnums: 0, 423 | NumMessages: 4, 424 | NumExtensions: 0, 425 | NumServices: 0, 426 | }, 427 | GoTypes: file_core_proto_goTypes, 428 | DependencyIndexes: file_core_proto_depIdxs, 429 | MessageInfos: file_core_proto_msgTypes, 430 | }.Build() 431 | File_core_proto = out.File 432 | file_core_proto_rawDesc = nil 433 | file_core_proto_goTypes = nil 434 | file_core_proto_depIdxs = nil 435 | } 436 | -------------------------------------------------------------------------------- /src/zed/pb/core.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | option go_package = "./pb"; 3 | package zed.messages; 4 | 5 | message PeerId { 6 | uint32 owner_id = 1; 7 | uint32 id = 2; 8 | } 9 | 10 | message User { 11 | reserved 4; 12 | uint64 id = 1; 13 | string github_login = 2; 14 | string avatar_url = 3; 15 | optional string name = 5; 16 | } 17 | 18 | message Nonce { 19 | uint64 upper_half = 1; 20 | uint64 lower_half = 2; 21 | } 22 | 23 | message Collaborator { 24 | PeerId peer_id = 1; 25 | uint32 replica_id = 2; 26 | uint64 user_id = 3; 27 | bool is_host = 4; 28 | optional string committer_name = 5; 29 | optional string committer_email = 6; 30 | } 31 | -------------------------------------------------------------------------------- /src/zed/pb/debugger.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | option go_package = "./pb"; 3 | package zed.messages; 4 | 5 | import "core.proto"; 6 | import "buffer.proto"; 7 | 8 | enum BreakpointState { 9 | Enabled = 0; 10 | Disabled = 1; 11 | } 12 | 13 | message Breakpoint { 14 | Anchor position = 1; 15 | BreakpointState state = 2; 16 | reserved 3; 17 | optional string message = 4; 18 | optional string condition = 5; 19 | optional string hit_condition = 6; 20 | map session_state = 7; 21 | } 22 | 23 | message BreakpointSessionState { 24 | uint64 id = 1; 25 | bool verified = 2; 26 | } 27 | 28 | message BreakpointsForFile { 29 | uint64 project_id = 1; 30 | string path = 2; 31 | repeated Breakpoint breakpoints = 3; 32 | } 33 | 34 | message ToggleBreakpoint { 35 | uint64 project_id = 1; 36 | string path = 2; 37 | Breakpoint breakpoint = 3; 38 | } 39 | 40 | enum DapThreadStatus { 41 | Running = 0; 42 | Stopped = 1; 43 | Exited = 2; 44 | Ended = 3; 45 | } 46 | 47 | enum VariablesArgumentsFilter { 48 | Indexed = 0; 49 | Named = 1; 50 | } 51 | 52 | message ValueFormat { 53 | optional bool hex = 1; 54 | } 55 | 56 | message VariablesRequest { 57 | uint64 project_id = 1; 58 | uint64 client_id = 2; 59 | uint64 variables_reference = 3; 60 | optional VariablesArgumentsFilter filter = 4; 61 | optional uint64 start = 5; 62 | optional uint64 count = 6; 63 | optional ValueFormat format = 7; 64 | } 65 | 66 | enum SteppingGranularity { 67 | Statement = 0; 68 | Line = 1; 69 | Instruction = 2; 70 | } 71 | 72 | message DapLocationsRequest { 73 | uint64 project_id = 1; 74 | uint64 session_id = 2; 75 | uint64 location_reference = 3; 76 | } 77 | 78 | message DapLocationsResponse { 79 | DapSource source = 1; 80 | uint64 line = 2; 81 | optional uint64 column = 3; 82 | optional uint64 end_line = 4; 83 | optional uint64 end_column = 5; 84 | } 85 | 86 | enum DapEvaluateContext { 87 | Repl = 0; 88 | Watch = 1; 89 | Hover = 2; 90 | Clipboard = 3; 91 | EvaluateVariables = 4; 92 | EvaluateUnknown = 5; 93 | } 94 | 95 | message DapEvaluateRequest { 96 | uint64 project_id = 1; 97 | uint64 client_id = 2; 98 | string expression = 3; 99 | optional uint64 frame_id = 4; 100 | optional DapEvaluateContext context = 5; 101 | } 102 | 103 | message DapEvaluateResponse { 104 | string result = 1; 105 | optional string evaluate_type = 2; 106 | uint64 variable_reference = 3; 107 | optional uint64 named_variables = 4; 108 | optional uint64 indexed_variables = 5; 109 | optional string memory_reference = 6; 110 | } 111 | 112 | 113 | message DapCompletionRequest { 114 | uint64 project_id = 1; 115 | uint64 client_id = 2; 116 | string query = 3; 117 | optional uint64 frame_id = 4; 118 | optional uint64 line = 5; 119 | uint64 column = 6; 120 | } 121 | 122 | enum DapCompletionItemType { 123 | Method = 0; 124 | Function = 1; 125 | Constructor = 2; 126 | Field = 3; 127 | Variable = 4; 128 | Class = 5; 129 | Interface = 6; 130 | Module = 7; 131 | Property = 8; 132 | Unit = 9; 133 | Value = 10; 134 | Enum = 11; 135 | Keyword = 12; 136 | Snippet = 13; 137 | Text = 14; 138 | Color = 15; 139 | CompletionItemFile = 16; 140 | Reference = 17; 141 | Customcolor = 19; 142 | } 143 | 144 | message DapCompletionItem { 145 | string label = 1; 146 | optional string text = 2; 147 | optional string sort_text = 3; 148 | optional string detail = 4; 149 | optional DapCompletionItemType typ = 5; 150 | optional uint64 start = 6; 151 | optional uint64 length = 7; 152 | optional uint64 selection_start = 8; 153 | optional uint64 selection_length = 9; 154 | } 155 | 156 | message DapCompletionResponse { 157 | uint64 client_id = 1; 158 | repeated DapCompletionItem completions = 2; 159 | } 160 | 161 | message DapScopesRequest { 162 | uint64 project_id = 1; 163 | uint64 client_id = 2; 164 | uint64 stack_frame_id = 3; 165 | } 166 | 167 | message DapScopesResponse { 168 | repeated DapScope scopes = 1; 169 | } 170 | 171 | message DapSetVariableValueRequest { 172 | uint64 project_id = 1; 173 | uint64 client_id = 2; 174 | string name = 3; 175 | string value = 4; 176 | uint64 variables_reference = 5; 177 | } 178 | 179 | message DapSetVariableValueResponse { 180 | uint64 client_id = 1; 181 | string value = 2; 182 | optional string variable_type = 3; 183 | optional uint64 variables_reference = 4; 184 | optional uint64 named_variables = 5; 185 | optional uint64 indexed_variables = 6; 186 | optional string memory_reference = 7; 187 | } 188 | 189 | message DapPauseRequest { 190 | uint64 project_id = 1; 191 | uint64 client_id = 2; 192 | uint64 thread_id = 3; 193 | } 194 | 195 | message DapDisconnectRequest { 196 | uint64 project_id = 1; 197 | uint64 client_id = 2; 198 | optional bool restart = 3; 199 | optional bool terminate_debuggee = 4; 200 | optional bool suspend_debuggee = 5; 201 | } 202 | 203 | message DapTerminateThreadsRequest { 204 | uint64 project_id = 1; 205 | uint64 client_id = 2; 206 | repeated uint64 thread_ids = 3; 207 | } 208 | 209 | message DapThreadsRequest { 210 | uint64 project_id = 1; 211 | uint64 client_id = 2; 212 | } 213 | 214 | message DapThreadsResponse { 215 | repeated DapThread threads = 1; 216 | } 217 | 218 | message DapTerminateRequest { 219 | uint64 project_id = 1; 220 | uint64 client_id = 2; 221 | optional bool restart = 3; 222 | } 223 | 224 | message DapRestartRequest { 225 | uint64 project_id = 1; 226 | uint64 client_id = 2; 227 | bytes raw_args = 3; 228 | } 229 | 230 | message DapRestartStackFrameRequest { 231 | uint64 project_id = 1; 232 | uint64 client_id = 2; 233 | uint64 stack_frame_id = 3; 234 | } 235 | 236 | message ToggleIgnoreBreakpoints { 237 | uint64 project_id = 1; 238 | uint32 session_id = 2; 239 | } 240 | 241 | message IgnoreBreakpointState { 242 | uint64 project_id = 1; 243 | uint64 session_id = 2; 244 | bool ignore = 3; 245 | } 246 | 247 | message DapNextRequest { 248 | uint64 project_id = 1; 249 | uint64 client_id = 2; 250 | uint64 thread_id = 3; 251 | optional bool single_thread = 4; 252 | optional SteppingGranularity granularity = 5; 253 | } 254 | 255 | message DapStepInRequest { 256 | uint64 project_id = 1; 257 | uint64 client_id = 2; 258 | uint64 thread_id = 3; 259 | optional uint64 target_id = 4; 260 | optional bool single_thread = 5; 261 | optional SteppingGranularity granularity = 6; 262 | } 263 | 264 | message DapStepOutRequest { 265 | uint64 project_id = 1; 266 | uint64 client_id = 2; 267 | uint64 thread_id = 3; 268 | optional bool single_thread = 4; 269 | optional SteppingGranularity granularity = 5; 270 | } 271 | 272 | message DapStepBackRequest { 273 | uint64 project_id = 1; 274 | uint64 client_id = 2; 275 | uint64 thread_id = 3; 276 | optional bool single_thread = 4; 277 | optional SteppingGranularity granularity = 5; 278 | } 279 | 280 | message DapContinueRequest { 281 | uint64 project_id = 1; 282 | uint64 client_id = 2; 283 | uint64 thread_id = 3; 284 | optional bool single_thread = 4; 285 | } 286 | 287 | message DapContinueResponse { 288 | uint64 client_id = 1; 289 | optional bool all_threads_continued = 2; 290 | } 291 | 292 | message DapModulesRequest { 293 | uint64 project_id = 1; 294 | uint64 client_id = 2; 295 | } 296 | 297 | message DapModulesResponse { 298 | uint64 client_id = 1; 299 | repeated DapModule modules = 2; 300 | } 301 | 302 | message DapLoadedSourcesRequest { 303 | uint64 project_id = 1; 304 | uint64 client_id = 2; 305 | } 306 | 307 | message DapLoadedSourcesResponse { 308 | uint64 client_id = 1; 309 | repeated DapSource sources = 2; 310 | } 311 | 312 | message DapStackTraceRequest { 313 | uint64 project_id = 1; 314 | uint64 client_id = 2; 315 | uint64 thread_id = 3; 316 | optional uint64 start_frame = 4; 317 | optional uint64 stack_trace_levels = 5; 318 | } 319 | 320 | message DapStackTraceResponse { 321 | repeated DapStackFrame frames = 1; 322 | } 323 | 324 | message DapStackFrame { 325 | uint64 id = 1; 326 | string name = 2; 327 | optional DapSource source = 3; 328 | uint64 line = 4; 329 | uint64 column = 5; 330 | optional uint64 end_line = 6; 331 | optional uint64 end_column = 7; 332 | optional bool can_restart = 8; 333 | optional string instruction_pointer_reference = 9; 334 | optional DapModuleId module_id = 10; 335 | optional DapStackPresentationHint presentation_hint = 11; 336 | } 337 | 338 | message DebuggerLoadedSourceList { 339 | uint64 client_id = 1; 340 | repeated DapSource sources = 2; 341 | } 342 | 343 | message DapVariables { 344 | uint64 client_id = 1; 345 | repeated DapVariable variables = 2; 346 | } 347 | 348 | // Remote Debugging: Dap Types 349 | message DapVariable { 350 | string name = 1; 351 | string value = 2; 352 | optional string type = 3; 353 | // optional DapVariablePresentationHint presentation_hint = 4; 354 | optional string evaluate_name = 5; 355 | uint64 variables_reference = 6; 356 | optional uint64 named_variables = 7; 357 | optional uint64 indexed_variables = 8; 358 | optional string memory_reference = 9; 359 | } 360 | 361 | message DapThread { 362 | uint64 id = 1; 363 | string name = 2; 364 | } 365 | 366 | message DapScope { 367 | string name = 1; 368 | optional DapScopePresentationHint presentation_hint = 2; 369 | uint64 variables_reference = 3; 370 | optional uint64 named_variables = 4; 371 | optional uint64 indexed_variables = 5; 372 | bool expensive = 6; 373 | optional DapSource source = 7; 374 | optional uint64 line = 8; 375 | optional uint64 column = 9; 376 | optional uint64 end_line = 10; 377 | optional uint64 end_column = 11; 378 | } 379 | 380 | message DapSource { 381 | optional string name = 1; 382 | optional string path = 2; 383 | optional uint64 source_reference = 3; 384 | optional DapSourcePresentationHint presentation_hint = 4; 385 | optional string origin = 5; 386 | repeated DapSource sources = 6; 387 | optional bytes adapter_data = 7; 388 | repeated DapChecksum checksums = 8; 389 | } 390 | 391 | enum DapOutputCategory { 392 | ConsoleOutput = 0; 393 | Important = 1; 394 | Stdout = 2; 395 | Stderr = 3; 396 | Unknown = 4; 397 | } 398 | 399 | enum DapOutputEventGroup { 400 | Start = 0; 401 | StartCollapsed = 1; 402 | End = 2; 403 | } 404 | 405 | message DapOutputEvent { 406 | string output = 1; 407 | optional DapOutputCategory category = 2; 408 | optional uint64 variables_reference = 3; 409 | optional DapOutputEventGroup group = 4; 410 | optional DapSource source = 5; 411 | optional uint32 line = 6; 412 | optional uint32 column = 7; 413 | } 414 | 415 | enum DapChecksumAlgorithm { 416 | CHECKSUM_ALGORITHM_UNSPECIFIED = 0; 417 | MD5 = 1; 418 | SHA1 = 2; 419 | SHA256 = 3; 420 | TIMESTAMP = 4; 421 | } 422 | 423 | message DapChecksum { 424 | DapChecksumAlgorithm algorithm = 1; 425 | string checksum = 2; 426 | } 427 | 428 | enum DapScopePresentationHint { 429 | Arguments = 0; 430 | Locals = 1; 431 | Registers = 2; 432 | ReturnValue = 3; 433 | ScopeUnknown = 4; 434 | } 435 | 436 | enum DapSourcePresentationHint { 437 | SourceNormal = 0; 438 | Emphasize = 1; 439 | Deemphasize = 2; 440 | SourceUnknown = 3; 441 | } 442 | 443 | enum DapStackPresentationHint { 444 | StackNormal = 0; 445 | Label = 1; 446 | Subtle = 2; 447 | StackUnknown = 3; 448 | } 449 | message DapModule { 450 | DapModuleId id = 1; 451 | string name = 2; 452 | optional string path = 3; 453 | optional bool is_optimized = 4; 454 | optional bool is_user_code = 5; 455 | optional string version = 6; 456 | optional string symbol_status = 7; 457 | optional string symbol_file_path = 8; 458 | optional string date_time_stamp = 9; 459 | optional string address_range = 10; 460 | } 461 | 462 | message DebugTaskDefinition { 463 | string adapter = 1; 464 | string label = 2; 465 | string config = 3; 466 | optional TcpHost tcp_connection = 4; 467 | } 468 | 469 | message TcpHost { 470 | optional uint32 port = 1; 471 | optional string host = 2; 472 | optional uint64 timeout = 3; 473 | } 474 | 475 | message DebugLaunchRequest { 476 | string program = 1; 477 | optional string cwd = 2; 478 | repeated string args = 3; 479 | map env = 4; 480 | } 481 | 482 | message DebugAttachRequest { 483 | uint32 process_id = 1; 484 | } 485 | 486 | message DapModuleId { 487 | oneof id { 488 | uint32 number = 1; 489 | string string = 2; 490 | } 491 | } 492 | 493 | message GetDebugAdapterBinary { 494 | uint64 project_id = 1; 495 | uint64 session_id = 3; 496 | DebugTaskDefinition definition = 2; 497 | uint64 worktree_id = 4; 498 | } 499 | 500 | message DebugAdapterBinary { 501 | optional string command = 1; 502 | repeated string arguments = 2; 503 | map envs = 3; 504 | optional string cwd = 4; 505 | optional TcpHost connection = 5; 506 | string configuration = 7; 507 | LaunchType launch_type = 8; 508 | enum LaunchType { 509 | Attach = 0; 510 | Launch = 1; 511 | } 512 | } 513 | 514 | message RunDebugLocators { 515 | uint64 project_id = 1; 516 | SpawnInTerminal build_command = 2; 517 | string locator = 3; 518 | } 519 | 520 | message DebugRequest { 521 | oneof request { 522 | DebugLaunchRequest debug_launch_request = 1; 523 | DebugAttachRequest debug_attach_request = 2; 524 | } 525 | } 526 | 527 | message DebugScenario { 528 | string label = 1; 529 | string adapter = 2; 530 | reserved 3; 531 | DebugRequest request = 4; 532 | optional TcpHost connection = 5; 533 | optional bool stop_on_entry = 6; 534 | optional string configuration = 7; 535 | } 536 | 537 | message SpawnInTerminal { 538 | string label = 1; 539 | optional string command = 2; 540 | repeated string args = 3; 541 | map env = 4; 542 | optional string cwd = 5; 543 | } 544 | 545 | message LogToDebugConsole { 546 | uint64 project_id = 1; 547 | uint64 session_id = 2; 548 | string message = 3; 549 | } 550 | -------------------------------------------------------------------------------- /src/zed/pb/git.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | option go_package = "./pb"; 3 | package zed.messages; 4 | 5 | import "worktree.proto"; 6 | import "buffer.proto"; 7 | 8 | message GitBranchesResponse { 9 | repeated Branch branches = 1; 10 | } 11 | 12 | message UpdateDiffBases { 13 | uint64 project_id = 1; 14 | uint64 buffer_id = 2; 15 | 16 | enum Mode { 17 | // No collaborator is using the unstaged diff. 18 | HEAD_ONLY = 0; 19 | // No collaborator is using the diff from HEAD. 20 | INDEX_ONLY = 1; 21 | // Both the unstaged and uncommitted diffs are demanded, 22 | // and the contents of the index and HEAD are the same for this path. 23 | INDEX_MATCHES_HEAD = 2; 24 | // Both the unstaged and uncommitted diffs are demanded, 25 | // and the contents of the index and HEAD differ for this path, 26 | // where None means the path doesn't exist in that state of the repo. 27 | INDEX_AND_HEAD = 3; 28 | } 29 | 30 | optional string staged_text = 3; 31 | optional string committed_text = 4; 32 | Mode mode = 5; 33 | } 34 | 35 | message OpenUnstagedDiff { 36 | uint64 project_id = 1; 37 | uint64 buffer_id = 2; 38 | } 39 | 40 | message OpenUnstagedDiffResponse { 41 | optional string staged_text = 1; 42 | } 43 | 44 | message OpenUncommittedDiff { 45 | uint64 project_id = 1; 46 | uint64 buffer_id = 2; 47 | } 48 | 49 | message OpenUncommittedDiffResponse { 50 | enum Mode { 51 | INDEX_MATCHES_HEAD = 0; 52 | INDEX_AND_HEAD = 1; 53 | } 54 | optional string staged_text = 1; 55 | optional string committed_text = 2; 56 | Mode mode = 3; 57 | } 58 | 59 | message SetIndexText { 60 | uint64 project_id = 1; 61 | reserved 2; 62 | uint64 repository_id = 3; 63 | string path = 4; 64 | optional string text = 5; 65 | } 66 | 67 | message GetPermalinkToLine { 68 | uint64 project_id = 1; 69 | uint64 buffer_id = 2; 70 | Range selection = 3; 71 | } 72 | 73 | message GetPermalinkToLineResponse { 74 | string permalink = 1; 75 | } 76 | 77 | message Branch { 78 | bool is_head = 1; 79 | string ref_name = 2; 80 | optional uint64 unix_timestamp = 3; 81 | optional GitUpstream upstream = 4; 82 | optional CommitSummary most_recent_commit = 5; 83 | } 84 | 85 | message GitUpstream { 86 | string ref_name = 1; 87 | optional UpstreamTracking tracking = 2; 88 | } 89 | 90 | message UpstreamTracking { 91 | uint64 ahead = 1; 92 | uint64 behind = 2; 93 | } 94 | 95 | message CommitSummary { 96 | string sha = 1; 97 | string subject = 2; 98 | int64 commit_timestamp = 3; 99 | } 100 | 101 | message GitBranches { 102 | uint64 project_id = 1; 103 | ProjectPath repository = 2; 104 | } 105 | 106 | 107 | message UpdateGitBranch { 108 | uint64 project_id = 1; 109 | string branch_name = 2; 110 | ProjectPath repository = 3; 111 | } 112 | 113 | message UpdateRepository { 114 | uint64 project_id = 1; 115 | uint64 id = 2; 116 | string abs_path = 3; 117 | repeated uint64 entry_ids = 4; 118 | optional Branch branch_summary = 5; 119 | repeated StatusEntry updated_statuses = 6; 120 | repeated string removed_statuses = 7; 121 | repeated string current_merge_conflicts = 8; 122 | uint64 scan_id = 9; 123 | bool is_last_update = 10; 124 | optional GitCommitDetails head_commit_details = 11; 125 | } 126 | 127 | message RemoveRepository { 128 | uint64 project_id = 1; 129 | uint64 id = 2; 130 | } 131 | 132 | enum GitStatus { 133 | Added = 0; 134 | Modified = 1; 135 | Conflict = 2; 136 | Deleted = 3; 137 | Updated = 4; 138 | TypeChanged = 5; 139 | Renamed = 6; 140 | Copied = 7; 141 | Unmodified = 8; 142 | } 143 | 144 | message GitFileStatus { 145 | oneof variant { 146 | Untracked untracked = 1; 147 | Ignored ignored = 2; 148 | Unmerged unmerged = 3; 149 | Tracked tracked = 4; 150 | } 151 | 152 | message Untracked {} 153 | message Ignored {} 154 | message Unmerged { 155 | GitStatus first_head = 1; 156 | GitStatus second_head = 2; 157 | } 158 | message Tracked { 159 | GitStatus index_status = 1; 160 | GitStatus worktree_status = 2; 161 | } 162 | } 163 | 164 | message GitGetBranches { 165 | uint64 project_id = 1; 166 | reserved 2; 167 | uint64 repository_id = 3; 168 | } 169 | 170 | message GitCreateBranch { 171 | uint64 project_id = 1; 172 | reserved 2; 173 | uint64 repository_id = 3; 174 | string branch_name = 4; 175 | } 176 | 177 | message GitChangeBranch { 178 | uint64 project_id = 1; 179 | reserved 2; 180 | uint64 repository_id = 3; 181 | string branch_name = 4; 182 | } 183 | 184 | message GitDiff { 185 | uint64 project_id = 1; 186 | reserved 2; 187 | uint64 repository_id = 3; 188 | DiffType diff_type = 4; 189 | 190 | enum DiffType { 191 | HEAD_TO_WORKTREE = 0; 192 | HEAD_TO_INDEX = 1; 193 | } 194 | } 195 | 196 | message GitDiffResponse { 197 | string diff = 1; 198 | } 199 | 200 | message GitInit { 201 | uint64 project_id = 1; 202 | string abs_path = 2; 203 | string fallback_branch_name = 3; 204 | } 205 | 206 | message CheckForPushedCommits { 207 | uint64 project_id = 1; 208 | reserved 2; 209 | uint64 repository_id = 3; 210 | } 211 | 212 | message CheckForPushedCommitsResponse { 213 | repeated string pushed_to = 1; 214 | } 215 | 216 | message GitShow { 217 | uint64 project_id = 1; 218 | reserved 2; 219 | uint64 repository_id = 3; 220 | string commit = 4; 221 | } 222 | 223 | message GitCommitDetails { 224 | string sha = 1; 225 | string message = 2; 226 | int64 commit_timestamp = 3; 227 | string author_email = 4; 228 | string author_name = 5; 229 | } 230 | 231 | message LoadCommitDiff { 232 | uint64 project_id = 1; 233 | reserved 2; 234 | uint64 repository_id = 3; 235 | string commit = 4; 236 | } 237 | 238 | message LoadCommitDiffResponse { 239 | repeated CommitFile files = 1; 240 | } 241 | 242 | message CommitFile { 243 | string path = 1; 244 | optional string old_text = 2; 245 | optional string new_text = 3; 246 | } 247 | 248 | message GitReset { 249 | uint64 project_id = 1; 250 | reserved 2; 251 | uint64 repository_id = 3; 252 | string commit = 4; 253 | ResetMode mode = 5; 254 | enum ResetMode { 255 | SOFT = 0; 256 | MIXED = 1; 257 | } 258 | } 259 | 260 | message GitCheckoutFiles { 261 | uint64 project_id = 1; 262 | reserved 2; 263 | uint64 repository_id = 3; 264 | string commit = 4; 265 | repeated string paths = 5; 266 | } 267 | 268 | // Move to `git.proto` once collab's min version is >=0.171.0. 269 | message StatusEntry { 270 | string repo_path = 1; 271 | // Can be removed once collab's min version is >=0.171.0. 272 | GitStatus simple_status = 2; 273 | GitFileStatus status = 3; 274 | } 275 | 276 | message Stage { 277 | uint64 project_id = 1; 278 | reserved 2; 279 | uint64 repository_id = 3; 280 | repeated string paths = 4; 281 | } 282 | 283 | message Unstage { 284 | uint64 project_id = 1; 285 | reserved 2; 286 | uint64 repository_id = 3; 287 | repeated string paths = 4; 288 | } 289 | 290 | message Commit { 291 | uint64 project_id = 1; 292 | reserved 2; 293 | uint64 repository_id = 3; 294 | optional string name = 4; 295 | optional string email = 5; 296 | string message = 6; 297 | optional CommitOptions options = 7; 298 | reserved 8; 299 | 300 | message CommitOptions { 301 | bool amend = 1; 302 | } 303 | } 304 | 305 | message OpenCommitMessageBuffer { 306 | uint64 project_id = 1; 307 | reserved 2; 308 | uint64 repository_id = 3; 309 | } 310 | 311 | message Push { 312 | uint64 project_id = 1; 313 | reserved 2; 314 | uint64 repository_id = 3; 315 | string remote_name = 4; 316 | string branch_name = 5; 317 | optional PushOptions options = 6; 318 | uint64 askpass_id = 7; 319 | 320 | enum PushOptions { 321 | SET_UPSTREAM = 0; 322 | FORCE = 1; 323 | } 324 | } 325 | 326 | message Fetch { 327 | uint64 project_id = 1; 328 | reserved 2; 329 | uint64 repository_id = 3; 330 | uint64 askpass_id = 4; 331 | optional string remote = 5; 332 | } 333 | 334 | message GetRemotes { 335 | uint64 project_id = 1; 336 | reserved 2; 337 | uint64 repository_id = 3; 338 | optional string branch_name = 4; 339 | } 340 | 341 | message GetRemotesResponse { 342 | repeated Remote remotes = 1; 343 | 344 | message Remote { 345 | string name = 1; 346 | } 347 | } 348 | 349 | message Pull { 350 | uint64 project_id = 1; 351 | reserved 2; 352 | uint64 repository_id = 3; 353 | string remote_name = 4; 354 | string branch_name = 5; 355 | uint64 askpass_id = 6; 356 | } 357 | 358 | message RemoteMessageResponse { 359 | string stdout = 1; 360 | string stderr = 2; 361 | } 362 | 363 | message BlameBuffer { 364 | uint64 project_id = 1; 365 | uint64 buffer_id = 2; 366 | repeated VectorClockEntry version = 3; 367 | } 368 | 369 | message BlameEntry { 370 | bytes sha = 1; 371 | 372 | uint32 start_line = 2; 373 | uint32 end_line = 3; 374 | uint32 original_line_number = 4; 375 | 376 | optional string author = 5; 377 | optional string author_mail = 6; 378 | optional int64 author_time = 7; 379 | optional string author_tz = 8; 380 | 381 | optional string committer = 9; 382 | optional string committer_mail = 10; 383 | optional int64 committer_time = 11; 384 | optional string committer_tz = 12; 385 | 386 | optional string summary = 13; 387 | optional string previous = 14; 388 | 389 | string filename = 15; 390 | } 391 | 392 | message CommitMessage { 393 | bytes oid = 1; 394 | string message = 2; 395 | } 396 | 397 | message CommitPermalink { 398 | bytes oid = 1; 399 | string permalink = 2; 400 | } 401 | 402 | message BlameBufferResponse { 403 | message BlameResponse { 404 | repeated BlameEntry entries = 1; 405 | repeated CommitMessage messages = 2; 406 | optional string remote_url = 4; 407 | reserved 3; 408 | } 409 | 410 | optional BlameResponse blame_response = 5; 411 | 412 | reserved 1 to 4; 413 | } 414 | -------------------------------------------------------------------------------- /src/zed/pb/notification.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // versions: 3 | // protoc-gen-go v1.34.1 4 | // protoc v3.21.12 5 | // source: notification.proto 6 | 7 | package pb 8 | 9 | import ( 10 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 11 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 12 | reflect "reflect" 13 | sync "sync" 14 | ) 15 | 16 | const ( 17 | // Verify that this generated code is sufficiently up-to-date. 18 | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) 19 | // Verify that runtime/protoimpl is sufficiently up-to-date. 20 | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) 21 | ) 22 | 23 | type GetNotifications struct { 24 | state protoimpl.MessageState 25 | sizeCache protoimpl.SizeCache 26 | unknownFields protoimpl.UnknownFields 27 | 28 | BeforeId *uint64 `protobuf:"varint,1,opt,name=before_id,json=beforeId,proto3,oneof" json:"before_id,omitempty"` 29 | } 30 | 31 | func (x *GetNotifications) Reset() { 32 | *x = GetNotifications{} 33 | if protoimpl.UnsafeEnabled { 34 | mi := &file_notification_proto_msgTypes[0] 35 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 36 | ms.StoreMessageInfo(mi) 37 | } 38 | } 39 | 40 | func (x *GetNotifications) String() string { 41 | return protoimpl.X.MessageStringOf(x) 42 | } 43 | 44 | func (*GetNotifications) ProtoMessage() {} 45 | 46 | func (x *GetNotifications) ProtoReflect() protoreflect.Message { 47 | mi := &file_notification_proto_msgTypes[0] 48 | if protoimpl.UnsafeEnabled && x != nil { 49 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 50 | if ms.LoadMessageInfo() == nil { 51 | ms.StoreMessageInfo(mi) 52 | } 53 | return ms 54 | } 55 | return mi.MessageOf(x) 56 | } 57 | 58 | // Deprecated: Use GetNotifications.ProtoReflect.Descriptor instead. 59 | func (*GetNotifications) Descriptor() ([]byte, []int) { 60 | return file_notification_proto_rawDescGZIP(), []int{0} 61 | } 62 | 63 | func (x *GetNotifications) GetBeforeId() uint64 { 64 | if x != nil && x.BeforeId != nil { 65 | return *x.BeforeId 66 | } 67 | return 0 68 | } 69 | 70 | type AddNotification struct { 71 | state protoimpl.MessageState 72 | sizeCache protoimpl.SizeCache 73 | unknownFields protoimpl.UnknownFields 74 | 75 | Notification *Notification `protobuf:"bytes,1,opt,name=notification,proto3" json:"notification,omitempty"` 76 | } 77 | 78 | func (x *AddNotification) Reset() { 79 | *x = AddNotification{} 80 | if protoimpl.UnsafeEnabled { 81 | mi := &file_notification_proto_msgTypes[1] 82 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 83 | ms.StoreMessageInfo(mi) 84 | } 85 | } 86 | 87 | func (x *AddNotification) String() string { 88 | return protoimpl.X.MessageStringOf(x) 89 | } 90 | 91 | func (*AddNotification) ProtoMessage() {} 92 | 93 | func (x *AddNotification) ProtoReflect() protoreflect.Message { 94 | mi := &file_notification_proto_msgTypes[1] 95 | if protoimpl.UnsafeEnabled && x != nil { 96 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 97 | if ms.LoadMessageInfo() == nil { 98 | ms.StoreMessageInfo(mi) 99 | } 100 | return ms 101 | } 102 | return mi.MessageOf(x) 103 | } 104 | 105 | // Deprecated: Use AddNotification.ProtoReflect.Descriptor instead. 106 | func (*AddNotification) Descriptor() ([]byte, []int) { 107 | return file_notification_proto_rawDescGZIP(), []int{1} 108 | } 109 | 110 | func (x *AddNotification) GetNotification() *Notification { 111 | if x != nil { 112 | return x.Notification 113 | } 114 | return nil 115 | } 116 | 117 | type GetNotificationsResponse struct { 118 | state protoimpl.MessageState 119 | sizeCache protoimpl.SizeCache 120 | unknownFields protoimpl.UnknownFields 121 | 122 | Notifications []*Notification `protobuf:"bytes,1,rep,name=notifications,proto3" json:"notifications,omitempty"` 123 | Done bool `protobuf:"varint,2,opt,name=done,proto3" json:"done,omitempty"` 124 | } 125 | 126 | func (x *GetNotificationsResponse) Reset() { 127 | *x = GetNotificationsResponse{} 128 | if protoimpl.UnsafeEnabled { 129 | mi := &file_notification_proto_msgTypes[2] 130 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 131 | ms.StoreMessageInfo(mi) 132 | } 133 | } 134 | 135 | func (x *GetNotificationsResponse) String() string { 136 | return protoimpl.X.MessageStringOf(x) 137 | } 138 | 139 | func (*GetNotificationsResponse) ProtoMessage() {} 140 | 141 | func (x *GetNotificationsResponse) ProtoReflect() protoreflect.Message { 142 | mi := &file_notification_proto_msgTypes[2] 143 | if protoimpl.UnsafeEnabled && x != nil { 144 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 145 | if ms.LoadMessageInfo() == nil { 146 | ms.StoreMessageInfo(mi) 147 | } 148 | return ms 149 | } 150 | return mi.MessageOf(x) 151 | } 152 | 153 | // Deprecated: Use GetNotificationsResponse.ProtoReflect.Descriptor instead. 154 | func (*GetNotificationsResponse) Descriptor() ([]byte, []int) { 155 | return file_notification_proto_rawDescGZIP(), []int{2} 156 | } 157 | 158 | func (x *GetNotificationsResponse) GetNotifications() []*Notification { 159 | if x != nil { 160 | return x.Notifications 161 | } 162 | return nil 163 | } 164 | 165 | func (x *GetNotificationsResponse) GetDone() bool { 166 | if x != nil { 167 | return x.Done 168 | } 169 | return false 170 | } 171 | 172 | type DeleteNotification struct { 173 | state protoimpl.MessageState 174 | sizeCache protoimpl.SizeCache 175 | unknownFields protoimpl.UnknownFields 176 | 177 | NotificationId uint64 `protobuf:"varint,1,opt,name=notification_id,json=notificationId,proto3" json:"notification_id,omitempty"` 178 | } 179 | 180 | func (x *DeleteNotification) Reset() { 181 | *x = DeleteNotification{} 182 | if protoimpl.UnsafeEnabled { 183 | mi := &file_notification_proto_msgTypes[3] 184 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 185 | ms.StoreMessageInfo(mi) 186 | } 187 | } 188 | 189 | func (x *DeleteNotification) String() string { 190 | return protoimpl.X.MessageStringOf(x) 191 | } 192 | 193 | func (*DeleteNotification) ProtoMessage() {} 194 | 195 | func (x *DeleteNotification) ProtoReflect() protoreflect.Message { 196 | mi := &file_notification_proto_msgTypes[3] 197 | if protoimpl.UnsafeEnabled && x != nil { 198 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 199 | if ms.LoadMessageInfo() == nil { 200 | ms.StoreMessageInfo(mi) 201 | } 202 | return ms 203 | } 204 | return mi.MessageOf(x) 205 | } 206 | 207 | // Deprecated: Use DeleteNotification.ProtoReflect.Descriptor instead. 208 | func (*DeleteNotification) Descriptor() ([]byte, []int) { 209 | return file_notification_proto_rawDescGZIP(), []int{3} 210 | } 211 | 212 | func (x *DeleteNotification) GetNotificationId() uint64 { 213 | if x != nil { 214 | return x.NotificationId 215 | } 216 | return 0 217 | } 218 | 219 | type UpdateNotification struct { 220 | state protoimpl.MessageState 221 | sizeCache protoimpl.SizeCache 222 | unknownFields protoimpl.UnknownFields 223 | 224 | Notification *Notification `protobuf:"bytes,1,opt,name=notification,proto3" json:"notification,omitempty"` 225 | } 226 | 227 | func (x *UpdateNotification) Reset() { 228 | *x = UpdateNotification{} 229 | if protoimpl.UnsafeEnabled { 230 | mi := &file_notification_proto_msgTypes[4] 231 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 232 | ms.StoreMessageInfo(mi) 233 | } 234 | } 235 | 236 | func (x *UpdateNotification) String() string { 237 | return protoimpl.X.MessageStringOf(x) 238 | } 239 | 240 | func (*UpdateNotification) ProtoMessage() {} 241 | 242 | func (x *UpdateNotification) ProtoReflect() protoreflect.Message { 243 | mi := &file_notification_proto_msgTypes[4] 244 | if protoimpl.UnsafeEnabled && x != nil { 245 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 246 | if ms.LoadMessageInfo() == nil { 247 | ms.StoreMessageInfo(mi) 248 | } 249 | return ms 250 | } 251 | return mi.MessageOf(x) 252 | } 253 | 254 | // Deprecated: Use UpdateNotification.ProtoReflect.Descriptor instead. 255 | func (*UpdateNotification) Descriptor() ([]byte, []int) { 256 | return file_notification_proto_rawDescGZIP(), []int{4} 257 | } 258 | 259 | func (x *UpdateNotification) GetNotification() *Notification { 260 | if x != nil { 261 | return x.Notification 262 | } 263 | return nil 264 | } 265 | 266 | type MarkNotificationRead struct { 267 | state protoimpl.MessageState 268 | sizeCache protoimpl.SizeCache 269 | unknownFields protoimpl.UnknownFields 270 | 271 | NotificationId uint64 `protobuf:"varint,1,opt,name=notification_id,json=notificationId,proto3" json:"notification_id,omitempty"` 272 | } 273 | 274 | func (x *MarkNotificationRead) Reset() { 275 | *x = MarkNotificationRead{} 276 | if protoimpl.UnsafeEnabled { 277 | mi := &file_notification_proto_msgTypes[5] 278 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 279 | ms.StoreMessageInfo(mi) 280 | } 281 | } 282 | 283 | func (x *MarkNotificationRead) String() string { 284 | return protoimpl.X.MessageStringOf(x) 285 | } 286 | 287 | func (*MarkNotificationRead) ProtoMessage() {} 288 | 289 | func (x *MarkNotificationRead) ProtoReflect() protoreflect.Message { 290 | mi := &file_notification_proto_msgTypes[5] 291 | if protoimpl.UnsafeEnabled && x != nil { 292 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 293 | if ms.LoadMessageInfo() == nil { 294 | ms.StoreMessageInfo(mi) 295 | } 296 | return ms 297 | } 298 | return mi.MessageOf(x) 299 | } 300 | 301 | // Deprecated: Use MarkNotificationRead.ProtoReflect.Descriptor instead. 302 | func (*MarkNotificationRead) Descriptor() ([]byte, []int) { 303 | return file_notification_proto_rawDescGZIP(), []int{5} 304 | } 305 | 306 | func (x *MarkNotificationRead) GetNotificationId() uint64 { 307 | if x != nil { 308 | return x.NotificationId 309 | } 310 | return 0 311 | } 312 | 313 | type Notification struct { 314 | state protoimpl.MessageState 315 | sizeCache protoimpl.SizeCache 316 | unknownFields protoimpl.UnknownFields 317 | 318 | Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` 319 | Timestamp uint64 `protobuf:"varint,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"` 320 | Kind string `protobuf:"bytes,3,opt,name=kind,proto3" json:"kind,omitempty"` 321 | EntityId *uint64 `protobuf:"varint,4,opt,name=entity_id,json=entityId,proto3,oneof" json:"entity_id,omitempty"` 322 | Content string `protobuf:"bytes,5,opt,name=content,proto3" json:"content,omitempty"` 323 | IsRead bool `protobuf:"varint,6,opt,name=is_read,json=isRead,proto3" json:"is_read,omitempty"` 324 | Response *bool `protobuf:"varint,7,opt,name=response,proto3,oneof" json:"response,omitempty"` 325 | } 326 | 327 | func (x *Notification) Reset() { 328 | *x = Notification{} 329 | if protoimpl.UnsafeEnabled { 330 | mi := &file_notification_proto_msgTypes[6] 331 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 332 | ms.StoreMessageInfo(mi) 333 | } 334 | } 335 | 336 | func (x *Notification) String() string { 337 | return protoimpl.X.MessageStringOf(x) 338 | } 339 | 340 | func (*Notification) ProtoMessage() {} 341 | 342 | func (x *Notification) ProtoReflect() protoreflect.Message { 343 | mi := &file_notification_proto_msgTypes[6] 344 | if protoimpl.UnsafeEnabled && x != nil { 345 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 346 | if ms.LoadMessageInfo() == nil { 347 | ms.StoreMessageInfo(mi) 348 | } 349 | return ms 350 | } 351 | return mi.MessageOf(x) 352 | } 353 | 354 | // Deprecated: Use Notification.ProtoReflect.Descriptor instead. 355 | func (*Notification) Descriptor() ([]byte, []int) { 356 | return file_notification_proto_rawDescGZIP(), []int{6} 357 | } 358 | 359 | func (x *Notification) GetId() uint64 { 360 | if x != nil { 361 | return x.Id 362 | } 363 | return 0 364 | } 365 | 366 | func (x *Notification) GetTimestamp() uint64 { 367 | if x != nil { 368 | return x.Timestamp 369 | } 370 | return 0 371 | } 372 | 373 | func (x *Notification) GetKind() string { 374 | if x != nil { 375 | return x.Kind 376 | } 377 | return "" 378 | } 379 | 380 | func (x *Notification) GetEntityId() uint64 { 381 | if x != nil && x.EntityId != nil { 382 | return *x.EntityId 383 | } 384 | return 0 385 | } 386 | 387 | func (x *Notification) GetContent() string { 388 | if x != nil { 389 | return x.Content 390 | } 391 | return "" 392 | } 393 | 394 | func (x *Notification) GetIsRead() bool { 395 | if x != nil { 396 | return x.IsRead 397 | } 398 | return false 399 | } 400 | 401 | func (x *Notification) GetResponse() bool { 402 | if x != nil && x.Response != nil { 403 | return *x.Response 404 | } 405 | return false 406 | } 407 | 408 | var File_notification_proto protoreflect.FileDescriptor 409 | 410 | var file_notification_proto_rawDesc = []byte{ 411 | 0x0a, 0x12, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 412 | 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x7a, 0x65, 0x64, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 413 | 0x65, 0x73, 0x22, 0x42, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 414 | 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x20, 0x0a, 0x09, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 415 | 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x48, 0x00, 0x52, 0x08, 0x62, 0x65, 0x66, 416 | 0x6f, 0x72, 0x65, 0x49, 0x64, 0x88, 0x01, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x62, 0x65, 0x66, 417 | 0x6f, 0x72, 0x65, 0x5f, 0x69, 0x64, 0x22, 0x51, 0x0a, 0x0f, 0x41, 0x64, 0x64, 0x4e, 0x6f, 0x74, 418 | 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3e, 0x0a, 0x0c, 0x6e, 0x6f, 0x74, 419 | 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 420 | 0x1a, 0x2e, 0x7a, 0x65, 0x64, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x4e, 421 | 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x6e, 0x6f, 0x74, 422 | 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x70, 0x0a, 0x18, 0x47, 0x65, 0x74, 423 | 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 424 | 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0d, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 425 | 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x7a, 426 | 0x65, 0x64, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 427 | 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 428 | 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x6f, 0x6e, 0x65, 0x18, 429 | 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x64, 0x6f, 0x6e, 0x65, 0x22, 0x3d, 0x0a, 0x12, 0x44, 430 | 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 431 | 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 432 | 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x6e, 0x6f, 0x74, 0x69, 433 | 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x54, 0x0a, 0x12, 0x55, 0x70, 434 | 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 435 | 0x12, 0x3e, 0x0a, 0x0c, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 436 | 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x7a, 0x65, 0x64, 0x2e, 0x6d, 0x65, 0x73, 437 | 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 438 | 0x6f, 0x6e, 0x52, 0x0c, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 439 | 0x22, 0x3f, 0x0a, 0x14, 0x4d, 0x61, 0x72, 0x6b, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 440 | 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x61, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x6e, 0x6f, 0x74, 0x69, 441 | 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 442 | 0x04, 0x52, 0x0e, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 443 | 0x64, 0x22, 0xe1, 0x01, 0x0a, 0x0c, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 444 | 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 445 | 0x69, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 446 | 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 447 | 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 448 | 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x20, 0x0a, 0x09, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, 449 | 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x48, 0x00, 0x52, 0x08, 0x65, 0x6e, 0x74, 0x69, 0x74, 450 | 0x79, 0x49, 0x64, 0x88, 0x01, 0x01, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 451 | 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 452 | 0x12, 0x17, 0x0a, 0x07, 0x69, 0x73, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 453 | 0x08, 0x52, 0x06, 0x69, 0x73, 0x52, 0x65, 0x61, 0x64, 0x12, 0x1f, 0x0a, 0x08, 0x72, 0x65, 0x73, 454 | 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x48, 0x01, 0x52, 0x08, 0x72, 455 | 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x88, 0x01, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x65, 456 | 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x72, 0x65, 0x73, 457 | 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 458 | 0x72, 0x6f, 0x74, 0x6f, 0x33, 459 | } 460 | 461 | var ( 462 | file_notification_proto_rawDescOnce sync.Once 463 | file_notification_proto_rawDescData = file_notification_proto_rawDesc 464 | ) 465 | 466 | func file_notification_proto_rawDescGZIP() []byte { 467 | file_notification_proto_rawDescOnce.Do(func() { 468 | file_notification_proto_rawDescData = protoimpl.X.CompressGZIP(file_notification_proto_rawDescData) 469 | }) 470 | return file_notification_proto_rawDescData 471 | } 472 | 473 | var file_notification_proto_msgTypes = make([]protoimpl.MessageInfo, 7) 474 | var file_notification_proto_goTypes = []interface{}{ 475 | (*GetNotifications)(nil), // 0: zed.messages.GetNotifications 476 | (*AddNotification)(nil), // 1: zed.messages.AddNotification 477 | (*GetNotificationsResponse)(nil), // 2: zed.messages.GetNotificationsResponse 478 | (*DeleteNotification)(nil), // 3: zed.messages.DeleteNotification 479 | (*UpdateNotification)(nil), // 4: zed.messages.UpdateNotification 480 | (*MarkNotificationRead)(nil), // 5: zed.messages.MarkNotificationRead 481 | (*Notification)(nil), // 6: zed.messages.Notification 482 | } 483 | var file_notification_proto_depIdxs = []int32{ 484 | 6, // 0: zed.messages.AddNotification.notification:type_name -> zed.messages.Notification 485 | 6, // 1: zed.messages.GetNotificationsResponse.notifications:type_name -> zed.messages.Notification 486 | 6, // 2: zed.messages.UpdateNotification.notification:type_name -> zed.messages.Notification 487 | 3, // [3:3] is the sub-list for method output_type 488 | 3, // [3:3] is the sub-list for method input_type 489 | 3, // [3:3] is the sub-list for extension type_name 490 | 3, // [3:3] is the sub-list for extension extendee 491 | 0, // [0:3] is the sub-list for field type_name 492 | } 493 | 494 | func init() { file_notification_proto_init() } 495 | func file_notification_proto_init() { 496 | if File_notification_proto != nil { 497 | return 498 | } 499 | if !protoimpl.UnsafeEnabled { 500 | file_notification_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { 501 | switch v := v.(*GetNotifications); i { 502 | case 0: 503 | return &v.state 504 | case 1: 505 | return &v.sizeCache 506 | case 2: 507 | return &v.unknownFields 508 | default: 509 | return nil 510 | } 511 | } 512 | file_notification_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { 513 | switch v := v.(*AddNotification); i { 514 | case 0: 515 | return &v.state 516 | case 1: 517 | return &v.sizeCache 518 | case 2: 519 | return &v.unknownFields 520 | default: 521 | return nil 522 | } 523 | } 524 | file_notification_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { 525 | switch v := v.(*GetNotificationsResponse); i { 526 | case 0: 527 | return &v.state 528 | case 1: 529 | return &v.sizeCache 530 | case 2: 531 | return &v.unknownFields 532 | default: 533 | return nil 534 | } 535 | } 536 | file_notification_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { 537 | switch v := v.(*DeleteNotification); i { 538 | case 0: 539 | return &v.state 540 | case 1: 541 | return &v.sizeCache 542 | case 2: 543 | return &v.unknownFields 544 | default: 545 | return nil 546 | } 547 | } 548 | file_notification_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { 549 | switch v := v.(*UpdateNotification); i { 550 | case 0: 551 | return &v.state 552 | case 1: 553 | return &v.sizeCache 554 | case 2: 555 | return &v.unknownFields 556 | default: 557 | return nil 558 | } 559 | } 560 | file_notification_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { 561 | switch v := v.(*MarkNotificationRead); i { 562 | case 0: 563 | return &v.state 564 | case 1: 565 | return &v.sizeCache 566 | case 2: 567 | return &v.unknownFields 568 | default: 569 | return nil 570 | } 571 | } 572 | file_notification_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { 573 | switch v := v.(*Notification); i { 574 | case 0: 575 | return &v.state 576 | case 1: 577 | return &v.sizeCache 578 | case 2: 579 | return &v.unknownFields 580 | default: 581 | return nil 582 | } 583 | } 584 | } 585 | file_notification_proto_msgTypes[0].OneofWrappers = []interface{}{} 586 | file_notification_proto_msgTypes[6].OneofWrappers = []interface{}{} 587 | type x struct{} 588 | out := protoimpl.TypeBuilder{ 589 | File: protoimpl.DescBuilder{ 590 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 591 | RawDescriptor: file_notification_proto_rawDesc, 592 | NumEnums: 0, 593 | NumMessages: 7, 594 | NumExtensions: 0, 595 | NumServices: 0, 596 | }, 597 | GoTypes: file_notification_proto_goTypes, 598 | DependencyIndexes: file_notification_proto_depIdxs, 599 | MessageInfos: file_notification_proto_msgTypes, 600 | }.Build() 601 | File_notification_proto = out.File 602 | file_notification_proto_rawDesc = nil 603 | file_notification_proto_goTypes = nil 604 | file_notification_proto_depIdxs = nil 605 | } 606 | -------------------------------------------------------------------------------- /src/zed/pb/notification.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | option go_package = "./pb"; 3 | package zed.messages; 4 | 5 | message GetNotifications { 6 | optional uint64 before_id = 1; 7 | } 8 | 9 | message AddNotification { 10 | Notification notification = 1; 11 | } 12 | 13 | message GetNotificationsResponse { 14 | repeated Notification notifications = 1; 15 | bool done = 2; 16 | } 17 | 18 | message DeleteNotification { 19 | uint64 notification_id = 1; 20 | } 21 | 22 | message UpdateNotification { 23 | Notification notification = 1; 24 | } 25 | 26 | message MarkNotificationRead { 27 | uint64 notification_id = 1; 28 | } 29 | 30 | message Notification { 31 | uint64 id = 1; 32 | uint64 timestamp = 2; 33 | string kind = 3; 34 | optional uint64 entity_id = 4; 35 | string content = 5; 36 | bool is_read = 6; 37 | optional bool response = 7; 38 | } 39 | -------------------------------------------------------------------------------- /src/zed/pb/task.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | option go_package = "./pb"; 3 | package zed.messages; 4 | 5 | import "buffer.proto"; 6 | 7 | message TaskContextForLocation { 8 | uint64 project_id = 1; 9 | Location location = 2; 10 | map task_variables = 3; 11 | } 12 | 13 | message TaskContext { 14 | optional string cwd = 1; 15 | map task_variables = 2; 16 | map project_env = 3; 17 | } 18 | 19 | message Shell { 20 | message WithArguments { 21 | string program = 1; 22 | repeated string args = 2; 23 | } 24 | 25 | oneof shell_type { 26 | System system = 1; 27 | string program = 2; 28 | WithArguments with_arguments = 3; 29 | } 30 | } 31 | 32 | message System {} 33 | 34 | enum RevealStrategy { 35 | RevealAlways = 0; 36 | RevealNever = 1; 37 | } 38 | 39 | enum HideStrategy { 40 | HideAlways = 0; 41 | HideNever = 1; 42 | HideOnSuccess = 2; 43 | } 44 | -------------------------------------------------------------------------------- /src/zed/pb/toolchain.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | option go_package = "./pb"; 3 | package zed.messages; 4 | 5 | message ListToolchains { 6 | uint64 project_id = 1; 7 | uint64 worktree_id = 2; 8 | string language_name = 3; 9 | optional string path = 4; 10 | } 11 | 12 | message Toolchain { 13 | string name = 1; 14 | string path = 2; 15 | string raw_json = 3; 16 | } 17 | 18 | message ToolchainGroup { 19 | uint64 start_index = 1; 20 | string name = 2; 21 | } 22 | 23 | message ListToolchainsResponse { 24 | repeated Toolchain toolchains = 1; 25 | bool has_values = 2; 26 | repeated ToolchainGroup groups = 3; 27 | optional string relative_worktree_path = 4; 28 | } 29 | 30 | message ActivateToolchain { 31 | uint64 project_id = 1; 32 | uint64 worktree_id = 2; 33 | Toolchain toolchain = 3; 34 | string language_name = 4; 35 | optional string path = 5; 36 | } 37 | 38 | message ActiveToolchain { 39 | uint64 project_id = 1; 40 | uint64 worktree_id = 2; 41 | string language_name = 3; 42 | optional string path = 4; 43 | } 44 | 45 | message ActiveToolchainResponse { 46 | optional Toolchain toolchain = 1; 47 | } 48 | -------------------------------------------------------------------------------- /src/zed/pb/worktree.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | option go_package = "./pb"; 3 | package zed.messages; 4 | 5 | message Timestamp { 6 | uint64 seconds = 1; 7 | uint32 nanos = 2; 8 | } 9 | 10 | message File { 11 | uint64 worktree_id = 1; 12 | optional uint64 entry_id = 2; 13 | string path = 3; 14 | Timestamp mtime = 4; 15 | bool is_deleted = 5; 16 | } 17 | 18 | message Entry { 19 | uint64 id = 1; 20 | bool is_dir = 2; 21 | string path = 3; 22 | uint64 inode = 4; 23 | Timestamp mtime = 5; 24 | bool is_ignored = 7; 25 | bool is_external = 8; 26 | reserved 6; 27 | reserved 9; 28 | bool is_fifo = 10; 29 | optional uint64 size = 11; 30 | optional string canonical_path = 12; 31 | } 32 | 33 | message AddWorktree { 34 | string path = 1; 35 | uint64 project_id = 2; 36 | bool visible = 3; 37 | } 38 | 39 | message AddWorktreeResponse { 40 | uint64 worktree_id = 1; 41 | string canonicalized_path = 2; 42 | } 43 | 44 | message RemoveWorktree { 45 | uint64 worktree_id = 1; 46 | } 47 | 48 | message GetPathMetadata { 49 | uint64 project_id = 1; 50 | string path = 2; 51 | } 52 | 53 | message GetPathMetadataResponse { 54 | bool exists = 1; 55 | string path = 2; 56 | bool is_dir = 3; 57 | } 58 | 59 | message WorktreeMetadata { 60 | uint64 id = 1; 61 | string root_name = 2; 62 | bool visible = 3; 63 | string abs_path = 4; 64 | } 65 | 66 | message ProjectPath { 67 | uint64 worktree_id = 1; 68 | string path = 2; 69 | } 70 | 71 | message ListRemoteDirectoryConfig { 72 | bool is_dir = 1; 73 | } 74 | 75 | message ListRemoteDirectory { 76 | uint64 dev_server_id = 1; 77 | string path = 2; 78 | ListRemoteDirectoryConfig config = 3; 79 | } 80 | 81 | message EntryInfo { 82 | bool is_dir = 1; 83 | } 84 | 85 | message ListRemoteDirectoryResponse { 86 | repeated string entries = 1; 87 | repeated EntryInfo entry_info = 2; 88 | } 89 | 90 | message CreateProjectEntry { 91 | uint64 project_id = 1; 92 | uint64 worktree_id = 2; 93 | string path = 3; 94 | bool is_directory = 4; 95 | optional bytes content = 5; 96 | } 97 | 98 | message RenameProjectEntry { 99 | uint64 project_id = 1; 100 | uint64 entry_id = 2; 101 | string new_path = 3; 102 | } 103 | 104 | message CopyProjectEntry { 105 | uint64 project_id = 1; 106 | uint64 entry_id = 2; 107 | string new_path = 3; 108 | optional string relative_worktree_source_path = 4; 109 | } 110 | 111 | message DeleteProjectEntry { 112 | uint64 project_id = 1; 113 | uint64 entry_id = 2; 114 | bool use_trash = 3; 115 | } 116 | 117 | message ExpandProjectEntry { 118 | uint64 project_id = 1; 119 | uint64 entry_id = 2; 120 | } 121 | 122 | message ExpandProjectEntryResponse { 123 | uint64 worktree_scan_id = 1; 124 | } 125 | 126 | message ExpandAllForProjectEntry { 127 | uint64 project_id = 1; 128 | uint64 entry_id = 2; 129 | } 130 | 131 | message ExpandAllForProjectEntryResponse { 132 | uint64 worktree_scan_id = 1; 133 | } 134 | 135 | message ProjectEntryResponse { 136 | optional Entry entry = 1; 137 | uint64 worktree_scan_id = 2; 138 | } 139 | 140 | message UpdateWorktreeSettings { 141 | uint64 project_id = 1; 142 | uint64 worktree_id = 2; 143 | string path = 3; 144 | optional string content = 4; 145 | optional LocalSettingsKind kind = 5; 146 | } 147 | 148 | enum LocalSettingsKind { 149 | Settings = 0; 150 | Tasks = 1; 151 | Editorconfig = 2; 152 | Debug = 3; 153 | } 154 | -------------------------------------------------------------------------------- /src/zed/pb/zed.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | option go_package = "./pb"; 3 | package zed.messages; 4 | 5 | import "ai.proto"; 6 | import "app.proto"; 7 | import "buffer.proto"; 8 | import "call.proto"; 9 | import "channel.proto"; 10 | import "core.proto"; 11 | import "debugger.proto"; 12 | import "git.proto"; 13 | import "lsp.proto"; 14 | import "notification.proto"; 15 | import "task.proto"; 16 | import "toolchain.proto"; 17 | import "worktree.proto"; 18 | 19 | // Looking for a number? Search "// current max" 20 | 21 | message Envelope { 22 | uint32 id = 1; 23 | optional uint32 responding_to = 2; 24 | optional PeerId original_sender_id = 3; 25 | optional uint32 ack_id = 266; 26 | 27 | oneof payload { 28 | Hello hello = 4; 29 | Ack ack = 5; 30 | Error error = 6; 31 | Ping ping = 7; 32 | Test test = 8; 33 | EndStream end_stream = 165; 34 | 35 | CreateRoom create_room = 9; 36 | CreateRoomResponse create_room_response = 10; 37 | JoinRoom join_room = 11; 38 | JoinRoomResponse join_room_response = 12; 39 | RejoinRoom rejoin_room = 13; 40 | RejoinRoomResponse rejoin_room_response = 14; 41 | LeaveRoom leave_room = 15; 42 | Call call = 16; 43 | IncomingCall incoming_call = 17; 44 | CallCanceled call_canceled = 18; 45 | CancelCall cancel_call = 19; 46 | DeclineCall decline_call = 20; 47 | UpdateParticipantLocation update_participant_location = 21; 48 | RoomUpdated room_updated = 22; 49 | 50 | ShareProject share_project = 23; 51 | ShareProjectResponse share_project_response = 24; 52 | UnshareProject unshare_project = 25; 53 | JoinProject join_project = 26; 54 | JoinProjectResponse join_project_response = 27; 55 | LeaveProject leave_project = 28; 56 | AddProjectCollaborator add_project_collaborator = 29; 57 | UpdateProjectCollaborator update_project_collaborator = 30; 58 | RemoveProjectCollaborator remove_project_collaborator = 31; 59 | 60 | GetDefinition get_definition = 32; 61 | GetDefinitionResponse get_definition_response = 33; 62 | GetDeclaration get_declaration = 237; 63 | GetDeclarationResponse get_declaration_response = 238; 64 | GetTypeDefinition get_type_definition = 34; 65 | GetTypeDefinitionResponse get_type_definition_response = 35; 66 | 67 | GetReferences get_references = 36; 68 | GetReferencesResponse get_references_response = 37; 69 | GetDocumentHighlights get_document_highlights = 38; 70 | GetDocumentHighlightsResponse get_document_highlights_response = 39; 71 | GetProjectSymbols get_project_symbols = 40; 72 | GetProjectSymbolsResponse get_project_symbols_response = 41; 73 | OpenBufferForSymbol open_buffer_for_symbol = 42; 74 | OpenBufferForSymbolResponse open_buffer_for_symbol_response = 43; 75 | 76 | UpdateProject update_project = 44; 77 | UpdateWorktree update_worktree = 45; 78 | 79 | CreateProjectEntry create_project_entry = 46; 80 | RenameProjectEntry rename_project_entry = 47; 81 | CopyProjectEntry copy_project_entry = 48; 82 | DeleteProjectEntry delete_project_entry = 49; 83 | ProjectEntryResponse project_entry_response = 50; 84 | ExpandProjectEntry expand_project_entry = 51; 85 | ExpandProjectEntryResponse expand_project_entry_response = 52; 86 | ExpandAllForProjectEntry expand_all_for_project_entry = 291; 87 | ExpandAllForProjectEntryResponse expand_all_for_project_entry_response = 292; 88 | UpdateDiagnosticSummary update_diagnostic_summary = 53; 89 | StartLanguageServer start_language_server = 54; 90 | UpdateLanguageServer update_language_server = 55; 91 | 92 | OpenBufferById open_buffer_by_id = 56; 93 | OpenBufferByPath open_buffer_by_path = 57; 94 | OpenBufferResponse open_buffer_response = 58; 95 | CreateBufferForPeer create_buffer_for_peer = 59; 96 | UpdateBuffer update_buffer = 60; 97 | UpdateBufferFile update_buffer_file = 61; 98 | SaveBuffer save_buffer = 62; 99 | BufferSaved buffer_saved = 63; 100 | BufferReloaded buffer_reloaded = 64; 101 | ReloadBuffers reload_buffers = 65; 102 | ReloadBuffersResponse reload_buffers_response = 66; 103 | SynchronizeBuffers synchronize_buffers = 67; 104 | SynchronizeBuffersResponse synchronize_buffers_response = 68; 105 | FormatBuffers format_buffers = 69; 106 | FormatBuffersResponse format_buffers_response = 70; 107 | GetCompletions get_completions = 71; 108 | GetCompletionsResponse get_completions_response = 72; 109 | ResolveCompletionDocumentation resolve_completion_documentation = 73; 110 | ResolveCompletionDocumentationResponse resolve_completion_documentation_response = 74; 111 | ApplyCompletionAdditionalEdits apply_completion_additional_edits = 75; 112 | ApplyCompletionAdditionalEditsResponse apply_completion_additional_edits_response = 76; 113 | GetCodeActions get_code_actions = 77; 114 | GetCodeActionsResponse get_code_actions_response = 78; 115 | GetHover get_hover = 79; 116 | GetHoverResponse get_hover_response = 80; 117 | ApplyCodeAction apply_code_action = 81; 118 | ApplyCodeActionResponse apply_code_action_response = 82; 119 | PrepareRename prepare_rename = 83; 120 | PrepareRenameResponse prepare_rename_response = 84; 121 | PerformRename perform_rename = 85; 122 | PerformRenameResponse perform_rename_response = 86; 123 | 124 | UpdateContacts update_contacts = 89; 125 | UpdateInviteInfo update_invite_info = 90; 126 | ShowContacts show_contacts = 91; 127 | 128 | GetUsers get_users = 92; 129 | FuzzySearchUsers fuzzy_search_users = 93; 130 | UsersResponse users_response = 94; 131 | RequestContact request_contact = 95; 132 | RespondToContactRequest respond_to_contact_request = 96; 133 | RemoveContact remove_contact = 97; 134 | 135 | Follow follow = 98; 136 | FollowResponse follow_response = 99; 137 | UpdateFollowers update_followers = 100; 138 | Unfollow unfollow = 101; 139 | GetPrivateUserInfo get_private_user_info = 102; 140 | GetPrivateUserInfoResponse get_private_user_info_response = 103; 141 | UpdateUserPlan update_user_plan = 234; 142 | UpdateDiffBases update_diff_bases = 104; 143 | AcceptTermsOfService accept_terms_of_service = 239; 144 | AcceptTermsOfServiceResponse accept_terms_of_service_response = 240; 145 | 146 | OnTypeFormatting on_type_formatting = 105; 147 | OnTypeFormattingResponse on_type_formatting_response = 106; 148 | 149 | UpdateWorktreeSettings update_worktree_settings = 107; 150 | 151 | InlayHints inlay_hints = 108; 152 | InlayHintsResponse inlay_hints_response = 109; 153 | ResolveInlayHint resolve_inlay_hint = 110; 154 | ResolveInlayHintResponse resolve_inlay_hint_response = 111; 155 | RefreshInlayHints refresh_inlay_hints = 112; 156 | 157 | CreateChannel create_channel = 113; 158 | CreateChannelResponse create_channel_response = 114; 159 | InviteChannelMember invite_channel_member = 115; 160 | RemoveChannelMember remove_channel_member = 116; 161 | RespondToChannelInvite respond_to_channel_invite = 117; 162 | UpdateChannels update_channels = 118; 163 | JoinChannel join_channel = 119; 164 | DeleteChannel delete_channel = 120; 165 | GetChannelMembers get_channel_members = 121; 166 | GetChannelMembersResponse get_channel_members_response = 122; 167 | SetChannelMemberRole set_channel_member_role = 123; 168 | RenameChannel rename_channel = 124; 169 | RenameChannelResponse rename_channel_response = 125; 170 | SubscribeToChannels subscribe_to_channels = 207; 171 | 172 | JoinChannelBuffer join_channel_buffer = 126; 173 | JoinChannelBufferResponse join_channel_buffer_response = 127; 174 | UpdateChannelBuffer update_channel_buffer = 128; 175 | LeaveChannelBuffer leave_channel_buffer = 129; 176 | UpdateChannelBufferCollaborators update_channel_buffer_collaborators = 130; 177 | RejoinChannelBuffers rejoin_channel_buffers = 131; 178 | RejoinChannelBuffersResponse rejoin_channel_buffers_response = 132; 179 | AckBufferOperation ack_buffer_operation = 133; 180 | 181 | JoinChannelChat join_channel_chat = 134; 182 | JoinChannelChatResponse join_channel_chat_response = 135; 183 | LeaveChannelChat leave_channel_chat = 136; 184 | SendChannelMessage send_channel_message = 137; 185 | SendChannelMessageResponse send_channel_message_response = 138; 186 | ChannelMessageSent channel_message_sent = 139; 187 | GetChannelMessages get_channel_messages = 140; 188 | GetChannelMessagesResponse get_channel_messages_response = 141; 189 | RemoveChannelMessage remove_channel_message = 142; 190 | AckChannelMessage ack_channel_message = 143; 191 | GetChannelMessagesById get_channel_messages_by_id = 144; 192 | 193 | MoveChannel move_channel = 147; 194 | ReorderChannel reorder_channel = 349; 195 | SetChannelVisibility set_channel_visibility = 148; 196 | 197 | AddNotification add_notification = 149; 198 | GetNotifications get_notifications = 150; 199 | GetNotificationsResponse get_notifications_response = 151; 200 | DeleteNotification delete_notification = 152; 201 | MarkNotificationRead mark_notification_read = 153; 202 | LspExtExpandMacro lsp_ext_expand_macro = 154; 203 | LspExtExpandMacroResponse lsp_ext_expand_macro_response = 155; 204 | SetRoomParticipantRole set_room_participant_role = 156; 205 | 206 | UpdateUserChannels update_user_channels = 157; 207 | 208 | GetImplementation get_implementation = 162; 209 | GetImplementationResponse get_implementation_response = 163; 210 | 211 | UpdateChannelMessage update_channel_message = 170; 212 | ChannelMessageUpdate channel_message_update = 171; 213 | 214 | BlameBuffer blame_buffer = 172; 215 | BlameBufferResponse blame_buffer_response = 173; 216 | 217 | UpdateNotification update_notification = 174; 218 | 219 | MultiLspQuery multi_lsp_query = 175; 220 | MultiLspQueryResponse multi_lsp_query_response = 176; 221 | RestartLanguageServers restart_language_servers = 208; 222 | 223 | RejoinRemoteProjects rejoin_remote_projects = 186; 224 | RejoinRemoteProjectsResponse rejoin_remote_projects_response = 187; 225 | 226 | OpenNewBuffer open_new_buffer = 196; 227 | 228 | GetSupermavenApiKey get_supermaven_api_key = 198; 229 | GetSupermavenApiKeyResponse get_supermaven_api_key_response = 199; 230 | 231 | TaskContextForLocation task_context_for_location = 203; 232 | TaskContext task_context = 204; 233 | 234 | LinkedEditingRange linked_editing_range = 209; 235 | LinkedEditingRangeResponse linked_editing_range_response = 210; 236 | 237 | AdvertiseContexts advertise_contexts = 211; 238 | OpenContext open_context = 212; 239 | OpenContextResponse open_context_response = 213; 240 | CreateContext create_context = 232; 241 | CreateContextResponse create_context_response = 233; 242 | UpdateContext update_context = 214; 243 | SynchronizeContexts synchronize_contexts = 215; 244 | SynchronizeContextsResponse synchronize_contexts_response = 216; 245 | 246 | GetSignatureHelp get_signature_help = 217; 247 | GetSignatureHelpResponse get_signature_help_response = 218; 248 | 249 | ListRemoteDirectory list_remote_directory = 219; 250 | ListRemoteDirectoryResponse list_remote_directory_response = 220; 251 | AddWorktree add_worktree = 222; 252 | AddWorktreeResponse add_worktree_response = 223; 253 | 254 | GetLlmToken get_llm_token = 235; 255 | GetLlmTokenResponse get_llm_token_response = 236; 256 | RefreshLlmToken refresh_llm_token = 259; 257 | 258 | LspExtSwitchSourceHeader lsp_ext_switch_source_header = 241; 259 | LspExtSwitchSourceHeaderResponse lsp_ext_switch_source_header_response = 242; 260 | 261 | FindSearchCandidates find_search_candidates = 243; 262 | FindSearchCandidatesResponse find_search_candidates_response = 244; 263 | 264 | CloseBuffer close_buffer = 245; 265 | 266 | ShutdownRemoteServer shutdown_remote_server = 257; 267 | 268 | RemoveWorktree remove_worktree = 258; 269 | 270 | LanguageServerLog language_server_log = 260; 271 | 272 | Toast toast = 261; 273 | HideToast hide_toast = 262; 274 | 275 | OpenServerSettings open_server_settings = 263; 276 | 277 | GetPermalinkToLine get_permalink_to_line = 264; 278 | GetPermalinkToLineResponse get_permalink_to_line_response = 265; 279 | 280 | FlushBufferedMessages flush_buffered_messages = 267; 281 | 282 | LanguageServerPromptRequest language_server_prompt_request = 268; 283 | LanguageServerPromptResponse language_server_prompt_response = 269; 284 | 285 | GitBranchesResponse git_branches_response = 271; 286 | 287 | UpdateGitBranch update_git_branch = 272; 288 | 289 | ListToolchains list_toolchains = 273; 290 | ListToolchainsResponse list_toolchains_response = 274; 291 | ActivateToolchain activate_toolchain = 275; 292 | ActiveToolchain active_toolchain = 276; 293 | ActiveToolchainResponse active_toolchain_response = 277; 294 | 295 | GetPathMetadata get_path_metadata = 278; 296 | GetPathMetadataResponse get_path_metadata_response = 279; 297 | 298 | GetPanicFiles get_panic_files = 280; 299 | GetPanicFilesResponse get_panic_files_response = 281; 300 | 301 | CancelLanguageServerWork cancel_language_server_work = 282; 302 | 303 | LspExtOpenDocs lsp_ext_open_docs = 283; 304 | LspExtOpenDocsResponse lsp_ext_open_docs_response = 284; 305 | 306 | SyncExtensions sync_extensions = 285; 307 | SyncExtensionsResponse sync_extensions_response = 286; 308 | InstallExtension install_extension = 287; 309 | 310 | OpenUnstagedDiff open_unstaged_diff = 288; 311 | OpenUnstagedDiffResponse open_unstaged_diff_response = 289; 312 | 313 | RegisterBufferWithLanguageServers register_buffer_with_language_servers = 290; 314 | 315 | Stage stage = 293; 316 | Unstage unstage = 294; 317 | Commit commit = 295; 318 | OpenCommitMessageBuffer open_commit_message_buffer = 296; 319 | 320 | OpenUncommittedDiff open_uncommitted_diff = 297; 321 | OpenUncommittedDiffResponse open_uncommitted_diff_response = 298; 322 | 323 | SetIndexText set_index_text = 299; 324 | 325 | GitShow git_show = 300; 326 | GitReset git_reset = 301; 327 | GitCommitDetails git_commit_details = 302; 328 | GitCheckoutFiles git_checkout_files = 303; 329 | 330 | Push push = 304; 331 | Fetch fetch = 305; 332 | GetRemotes get_remotes = 306; 333 | GetRemotesResponse get_remotes_response = 307; 334 | Pull pull = 308; 335 | 336 | ApplyCodeActionKind apply_code_action_kind = 309; 337 | ApplyCodeActionKindResponse apply_code_action_kind_response = 310; 338 | 339 | RemoteMessageResponse remote_message_response = 311; 340 | 341 | GitGetBranches git_get_branches = 312; 342 | GitCreateBranch git_create_branch = 313; 343 | GitChangeBranch git_change_branch = 314; 344 | 345 | CheckForPushedCommits check_for_pushed_commits = 315; 346 | CheckForPushedCommitsResponse check_for_pushed_commits_response = 316; 347 | 348 | AskPassRequest ask_pass_request = 317; 349 | AskPassResponse ask_pass_response = 318; 350 | 351 | GitDiff git_diff = 319; 352 | GitDiffResponse git_diff_response = 320; 353 | GitInit git_init = 321; 354 | 355 | CodeLens code_lens = 322; 356 | GetCodeLens get_code_lens = 323; 357 | GetCodeLensResponse get_code_lens_response = 324; 358 | RefreshCodeLens refresh_code_lens = 325; 359 | 360 | ToggleBreakpoint toggle_breakpoint = 326; 361 | BreakpointsForFile breakpoints_for_file = 327; 362 | 363 | UpdateRepository update_repository = 328; 364 | RemoveRepository remove_repository = 329; 365 | 366 | GetDocumentSymbols get_document_symbols = 330; 367 | GetDocumentSymbolsResponse get_document_symbols_response = 331; 368 | 369 | LanguageServerIdForName language_server_id_for_name = 332; 370 | LanguageServerIdForNameResponse language_server_id_for_name_response = 333; 371 | 372 | LoadCommitDiff load_commit_diff = 334; 373 | LoadCommitDiffResponse load_commit_diff_response = 335; 374 | 375 | StopLanguageServers stop_language_servers = 336; 376 | 377 | LspExtRunnables lsp_ext_runnables = 337; 378 | LspExtRunnablesResponse lsp_ext_runnables_response = 338; 379 | 380 | GetDebugAdapterBinary get_debug_adapter_binary = 339; 381 | DebugAdapterBinary debug_adapter_binary = 340; 382 | RunDebugLocators run_debug_locators = 341; 383 | DebugRequest debug_request = 342; 384 | 385 | LspExtGoToParentModule lsp_ext_go_to_parent_module = 343; 386 | LspExtGoToParentModuleResponse lsp_ext_go_to_parent_module_response = 344; 387 | LspExtCancelFlycheck lsp_ext_cancel_flycheck = 345; 388 | LspExtRunFlycheck lsp_ext_run_flycheck = 346; 389 | LspExtClearFlycheck lsp_ext_clear_flycheck = 347; 390 | 391 | LogToDebugConsole log_to_debug_console = 348; 392 | 393 | GetDocumentDiagnostics get_document_diagnostics = 350; 394 | GetDocumentDiagnosticsResponse get_document_diagnostics_response = 351; 395 | PullWorkspaceDiagnostics pull_workspace_diagnostics = 352; 396 | 397 | GetDocumentColor get_document_color = 353; 398 | GetDocumentColorResponse get_document_color_response = 354; 399 | GetColorPresentation get_color_presentation = 355; 400 | GetColorPresentationResponse get_color_presentation_response = 356; // current max 401 | 402 | } 403 | 404 | reserved 87 to 88; 405 | reserved 158 to 161; 406 | reserved 164; 407 | reserved 166 to 169; 408 | reserved 177 to 185; 409 | reserved 188; 410 | reserved 189 to 192; 411 | reserved 193 to 195; 412 | reserved 197; 413 | reserved 200 to 202; 414 | reserved 205 to 206; 415 | reserved 221; 416 | reserved 224 to 229; 417 | reserved 230 to 231; 418 | reserved 246; 419 | reserved 270; 420 | reserved 247 to 254; 421 | reserved 255 to 256; 422 | } 423 | 424 | message Hello { 425 | PeerId peer_id = 1; 426 | } 427 | 428 | message Ping {} 429 | 430 | message Ack {} 431 | 432 | message Error { 433 | string message = 1; 434 | ErrorCode code = 2; 435 | repeated string tags = 3; 436 | } 437 | 438 | enum ErrorCode { 439 | Internal = 0; 440 | NoSuchChannel = 1; 441 | Disconnected = 2; 442 | SignedOut = 3; 443 | UpgradeRequired = 4; 444 | Forbidden = 5; 445 | NeedsCla = 7; 446 | NotARootChannel = 8; 447 | BadPublicNesting = 9; 448 | CircularNesting = 10; 449 | WrongMoveTarget = 11; 450 | UnsharedItem = 12; 451 | NoSuchProject = 13; 452 | DevServerProjectPathDoesNotExist = 16; 453 | RemoteUpgradeRequired = 17; 454 | RateLimitExceeded = 18; 455 | CommitFailed = 19; 456 | reserved 6; 457 | reserved 14 to 15; 458 | } 459 | 460 | message EndStream {} 461 | 462 | message Test { 463 | uint64 id = 1; 464 | } 465 | 466 | message FlushBufferedMessages {} 467 | 468 | message FlushBufferedMessagesResponse {} 469 | -------------------------------------------------------------------------------- /src/zed/release_notes.go: -------------------------------------------------------------------------------- 1 | package zed 2 | 3 | type ReleaseNotes struct { 4 | Title string `json:"title"` 5 | ReleaseNotes string `json:"release_notes"` 6 | } 7 | -------------------------------------------------------------------------------- /src/zed/rpc.go: -------------------------------------------------------------------------------- 1 | package zed 2 | 3 | import ( 4 | "crypto/rand" 5 | "encoding/base64" 6 | "net/http" 7 | "strconv" 8 | "strings" 9 | "time" 10 | 11 | "zedex/utils" 12 | "zedex/zed/pb" 13 | 14 | "github.com/0x6flab/namegenerator" 15 | "github.com/gin-gonic/gin" 16 | "github.com/gorilla/websocket" 17 | "github.com/klauspost/compress/zstd" 18 | log "github.com/sirupsen/logrus" 19 | "google.golang.org/protobuf/proto" 20 | "google.golang.org/protobuf/reflect/protoreflect" 21 | ) 22 | 23 | const ( 24 | ZSTD_COMPRESSION_LEVEL = 4 25 | WEBSOCKET_READ_LIMIT = 1024 * 1024 26 | ) 27 | 28 | type RpcHandler struct { 29 | sockets utils.ConcurrentMap[int, *websocket.Conn] 30 | users utils.ConcurrentMap[uint64, *pb.User] 31 | channels utils.ConcurrentMap[uint64, *pb.Channel] 32 | channelMembers utils.ConcurrentMap[uint64, []*pb.ChannelMember] 33 | channelMessages utils.ConcurrentMap[uint64, []*pb.ChannelMessage] 34 | id utils.ConcurrentCounter[uint32] 35 | nameGenerator namegenerator.NameGenerator 36 | } 37 | 38 | func NewRpcHandler() RpcHandler { 39 | return RpcHandler{ 40 | sockets: utils.NewConcurrentMap[int, *websocket.Conn](), 41 | users: utils.NewConcurrentMap[uint64, *pb.User](), 42 | channels: utils.NewConcurrentMap[uint64, *pb.Channel](), 43 | channelMembers: utils.NewConcurrentMap[uint64, []*pb.ChannelMember](), 44 | channelMessages: utils.NewConcurrentMap[uint64, []*pb.ChannelMessage](), 45 | id: utils.NewConcurrentCounter[uint32](), 46 | nameGenerator: namegenerator.NewGenerator(), 47 | } 48 | } 49 | 50 | type ProtoDispatcher struct { 51 | rpc *RpcHandler 52 | userId int 53 | peerId *pb.PeerId 54 | } 55 | 56 | func NewProtoDispatcher(rpc *RpcHandler, userId int) *ProtoDispatcher { 57 | return &ProtoDispatcher{ 58 | rpc: rpc, 59 | userId: userId, 60 | } 61 | } 62 | 63 | func (pd *ProtoDispatcher) CompressMsg(b []byte) ([]byte, error) { 64 | encoder, err := zstd.NewWriter(nil, zstd.WithEncoderLevel((ZSTD_COMPRESSION_LEVEL))) 65 | if err != nil { 66 | return []byte{}, err 67 | } 68 | return encoder.EncodeAll(b, make([]byte, 0, len(b))), nil 69 | } 70 | 71 | func (pd *ProtoDispatcher) SendMessage(b []byte) error { 72 | bb, err := pd.CompressMsg(b) 73 | if err != nil { 74 | return err 75 | } 76 | if err := pd.rpc.sockets.Get(pd.userId).WriteMessage(websocket.BinaryMessage, bb); err != nil { 77 | return err 78 | } 79 | return nil 80 | } 81 | 82 | func (pd *ProtoDispatcher) SendProtobuf(protobuf protoreflect.ProtoMessage) error { 83 | log.Infof("[user: %v] sending proto %#v", pd.userId, protobuf) 84 | b, err := proto.Marshal(protobuf) 85 | if err != nil { 86 | return err 87 | } 88 | return pd.SendMessage(b) 89 | } 90 | 91 | func (pd *ProtoDispatcher) SendHello() error { 92 | envelope := pb.Envelope{ 93 | Payload: &pb.Envelope_Hello{ 94 | Hello: &pb.Hello{ 95 | PeerId: &pb.PeerId{Id: uint32(pd.userId)}, 96 | }, 97 | }, 98 | } 99 | 100 | return pd.SendProtobuf(&envelope) 101 | } 102 | 103 | func (rpc *RpcHandler) NextId() uint32 { 104 | return rpc.id.Increment().Value() 105 | } 106 | 107 | func (pd *ProtoDispatcher) NextId() uint32 { 108 | return pd.rpc.NextId() 109 | } 110 | 111 | func (rpc *RpcHandler) handleMessages(pd *ProtoDispatcher) { 112 | for { 113 | _, message, err := rpc.sockets.Get(pd.userId).ReadMessage() 114 | if err != nil { 115 | log.Errorf("failed to receive message: %v", err) 116 | return 117 | } 118 | rpc.handleMessage(pd, message) 119 | } 120 | } 121 | 122 | func (rpc *RpcHandler) handleMessage(pd *ProtoDispatcher, message []byte) error { 123 | var envelope pb.Envelope 124 | err := proto.Unmarshal(message, &envelope) 125 | if err != nil { 126 | log.Errorf("failed to unmarshal message: %v", err) 127 | return err 128 | } 129 | 130 | log.Debugf("[user: %v] incoming %#v", pd.userId, envelope.Payload) 131 | 132 | switch msg := envelope.Payload.(type) { 133 | case *pb.Envelope_Hello: 134 | resp := pb.Envelope{ 135 | Id: pd.NextId(), 136 | RespondingTo: &envelope.Id, 137 | Payload: &pb.Envelope_UpdateChannels{ 138 | UpdateChannels: &pb.UpdateChannels{ 139 | Channels: rpc.channels.Values(), 140 | }, 141 | }, 142 | } 143 | if err := pd.SendProtobuf(&resp); err != nil { 144 | return err 145 | } 146 | 147 | case *pb.Envelope_GetUsers: 148 | gu := envelope.Payload.(*pb.Envelope_GetUsers) 149 | ru := []*pb.User{} 150 | for _, uid := range gu.GetUsers.UserIds { 151 | ru = append(ru, rpc.users.Get(uid)) 152 | } 153 | resp := pb.Envelope{ 154 | Id: pd.NextId(), 155 | RespondingTo: &envelope.Id, 156 | Payload: &pb.Envelope_UsersResponse{ 157 | UsersResponse: &pb.UsersResponse{ 158 | Users: ru, 159 | }, 160 | }, 161 | } 162 | if err := pd.SendProtobuf(&resp); err != nil { 163 | return err 164 | } 165 | 166 | case *pb.Envelope_GetPrivateUserInfo: 167 | resp := pb.Envelope{ 168 | RespondingTo: &envelope.Id, 169 | Payload: &pb.Envelope_GetPrivateUserInfoResponse{ 170 | GetPrivateUserInfoResponse: &pb.GetPrivateUserInfoResponse{ 171 | MetricsId: "123", 172 | Staff: true, 173 | Flags: []string{"zed-pro", "notebooks", "debugger", "llm-closed-beta", "thread-auto-capture"}, 174 | AcceptedTosAt: proto.Uint64(1), 175 | }, 176 | }, 177 | } 178 | if err := pd.SendProtobuf(&resp); err != nil { 179 | return err 180 | } 181 | 182 | case *pb.Envelope_GetChannelMessagesById: 183 | ids := msg.GetChannelMessagesById.MessageIds 184 | msgs := []*pb.ChannelMessage{} 185 | for _, id := range ids { 186 | msgs = append(msgs, rpc.channelMessages.Get(id)...) 187 | } 188 | resp := pb.Envelope{ 189 | Id: pd.NextId(), 190 | RespondingTo: &envelope.Id, 191 | Payload: &pb.Envelope_GetChannelMessagesResponse{ 192 | GetChannelMessagesResponse: &pb.GetChannelMessagesResponse{ 193 | Messages: msgs, 194 | }, 195 | }, 196 | } 197 | if err := pd.SendProtobuf(&resp); err != nil { 198 | return err 199 | } 200 | 201 | case *pb.Envelope_SendChannelMessage: 202 | scm := msg.SendChannelMessage 203 | channelMsg := &pb.ChannelMessage{ 204 | Id: uint64(time.Now().UnixNano()), 205 | Body: scm.Body, 206 | Timestamp: uint64(time.Now().Unix()), 207 | Nonce: scm.Nonce, 208 | Mentions: scm.Mentions, 209 | ReplyToMessageId: scm.ReplyToMessageId, 210 | } 211 | 212 | rpc.channelMessages.Transaction(func(m map[uint64][]*pb.ChannelMessage) map[uint64][]*pb.ChannelMessage { 213 | m[scm.ChannelId] = append(m[scm.ChannelId], channelMsg) 214 | return m 215 | }) 216 | 217 | resp := pb.Envelope{ 218 | Id: pd.NextId(), 219 | RespondingTo: &envelope.Id, 220 | Payload: &pb.Envelope_SendChannelMessageResponse{ 221 | SendChannelMessageResponse: &pb.SendChannelMessageResponse{ 222 | Message: channelMsg, 223 | }, 224 | }, 225 | } 226 | if err := pd.SendProtobuf(&resp); err != nil { 227 | return err 228 | } 229 | 230 | case *pb.Envelope_AckChannelMessage: 231 | log.Debug("Envelope_AckChannelMessage") 232 | 233 | case *pb.Envelope_LeaveChannelChat: 234 | log.Debug("Envelope_LeaveChannelChat") 235 | 236 | case *pb.Envelope_JoinChannelBuffer: 237 | log.Debug("Envelope_JoinChannelBuffer") 238 | resp := pb.Envelope{ 239 | Id: pd.NextId(), 240 | RespondingTo: &envelope.Id, 241 | Payload: &pb.Envelope_JoinChannelBuffer{ 242 | JoinChannelBuffer: &pb.JoinChannelBuffer{ 243 | ChannelId: msg.JoinChannelBuffer.ChannelId, 244 | }, 245 | }, 246 | } 247 | if err := pd.SendProtobuf(&resp); err != nil { 248 | return err 249 | } 250 | 251 | case *pb.Envelope_AcceptTermsOfService: 252 | resp := pb.Envelope{ 253 | Id: pd.NextId(), 254 | RespondingTo: &envelope.Id, 255 | Payload: &pb.Envelope_AcceptTermsOfServiceResponse{ 256 | AcceptTermsOfServiceResponse: &pb.AcceptTermsOfServiceResponse{}, 257 | }, 258 | } 259 | if err := pd.SendProtobuf(&resp); err != nil { 260 | return err 261 | } 262 | 263 | case *pb.Envelope_GetNotifications: 264 | log.Debug("Envelope_GetNotifications") 265 | 266 | case *pb.Envelope_FuzzySearchUsers: 267 | ru := rpc.users.Values() 268 | resp := pb.Envelope{ 269 | Id: pd.NextId(), 270 | RespondingTo: &envelope.Id, 271 | Payload: &pb.Envelope_UsersResponse{ 272 | UsersResponse: &pb.UsersResponse{ 273 | Users: ru, 274 | }, 275 | }, 276 | } 277 | if err := pd.SendProtobuf(&resp); err != nil { 278 | return err 279 | } 280 | 281 | case *pb.Envelope_GetLlmToken: 282 | resp := pb.Envelope{ 283 | Id: pd.NextId(), 284 | RespondingTo: &envelope.Id, 285 | Payload: &pb.Envelope_GetLlmTokenResponse{ 286 | GetLlmTokenResponse: &pb.GetLlmTokenResponse{ 287 | Token: "abc123", 288 | }, 289 | }, 290 | } 291 | if err := pd.SendProtobuf(&resp); err != nil { 292 | return err 293 | } 294 | 295 | case *pb.Envelope_SubscribeToChannels: 296 | log.Debug("Envelope_SubscribeToChannels") 297 | 298 | case *pb.Envelope_CreateChannel: 299 | ccr := msg.CreateChannel 300 | channel := &pb.Channel{ 301 | Id: *proto.Uint64(utils.StringToUInt64Hash(ccr.Name)), 302 | Name: ccr.Name, 303 | Visibility: pb.ChannelVisibility_Public, 304 | } 305 | 306 | rpc.channels.Transaction(func(m map[uint64]*pb.Channel) map[uint64]*pb.Channel { 307 | if _, ok := m[channel.Id]; !ok { 308 | m[channel.Id] = channel 309 | } 310 | return m 311 | }) 312 | 313 | resp := pb.Envelope{ 314 | Id: pd.NextId(), 315 | RespondingTo: &envelope.Id, 316 | Payload: &pb.Envelope_CreateChannelResponse{ 317 | CreateChannelResponse: &pb.CreateChannelResponse{ 318 | Channel: channel, 319 | }, 320 | }, 321 | } 322 | if err := pd.SendProtobuf(&resp); err != nil { 323 | return err 324 | } 325 | 326 | case *pb.Envelope_JoinChannelChat: 327 | jcc := msg.JoinChannelChat 328 | resp := pb.Envelope{ 329 | Id: pd.NextId(), 330 | RespondingTo: &envelope.Id, 331 | Payload: &pb.Envelope_JoinChannelChatResponse{ 332 | JoinChannelChatResponse: &pb.JoinChannelChatResponse{ 333 | Messages: rpc.channelMessages.Get(jcc.ChannelId), 334 | }, 335 | }, 336 | } 337 | if err := pd.SendProtobuf(&resp); err != nil { 338 | return err 339 | } 340 | 341 | case *pb.Envelope_GetChannelMembers: 342 | gcm := msg.GetChannelMembers 343 | resp := pb.Envelope{ 344 | Id: pd.NextId(), 345 | RespondingTo: &envelope.Id, 346 | Payload: &pb.Envelope_GetChannelMembersResponse{ 347 | GetChannelMembersResponse: &pb.GetChannelMembersResponse{ 348 | Members: rpc.channelMembers.Get(gcm.ChannelId), 349 | }, 350 | }, 351 | } 352 | if err := pd.SendProtobuf(&resp); err != nil { 353 | return err 354 | } 355 | 356 | case *pb.Envelope_InviteChannelMember: 357 | req := msg.InviteChannelMember 358 | rpc.channelMembers.Transaction(func(m map[uint64][]*pb.ChannelMember) map[uint64][]*pb.ChannelMember { 359 | m[req.UserId] = append(m[req.UserId], &pb.ChannelMember{UserId: req.UserId, Kind: pb.ChannelMember_Member, Role: pb.ChannelRole_Admin}) 360 | return m 361 | }) 362 | 363 | case *pb.Envelope_JoinChannel: 364 | // jc := envelope.Payload.(*pb.Envelope_JoinChannel).JoinChannel 365 | // resp := pb.Envelope{ 366 | // RespondingTo: &envelope.Id, 367 | // Payload: &pb.Envelope_JoinChannelChatResponse{ 368 | // JoinChannelChatResponse: &pb.JoinChannelChatResponse{}, 369 | // }, 370 | // } 371 | // if err := rpc.SendProtobuf(connId, &resp); err != nil { 372 | // return err 373 | // } 374 | default: 375 | log.Infof("Received unmapped WebSocket message base64: %v", base64.StdEncoding.EncodeToString(message)) 376 | } 377 | return nil 378 | } 379 | 380 | func (rpc *RpcHandler) generateWebSocketKey() string { 381 | key := make([]byte, 16) 382 | if _, err := rand.Read(key); err != nil { 383 | log.Fatal("Failed to generate random key: ", err) 384 | } 385 | return base64.StdEncoding.EncodeToString(key) 386 | } 387 | 388 | func (rpc *RpcHandler) HandleRequest(c *gin.Context) { 389 | upgrader := websocket.Upgrader{} // use default options 390 | c.Request.Header.Add("Upgrade", "websocket") 391 | c.Request.Header.Add("Connection", "upgrade") 392 | c.Request.Header.Add("Sec-WebSocket-Protocol", "chat") 393 | c.Request.Header.Add("Sec-WebSocket-Version", "13") 394 | c.Request.Header.Add("Sec-WebSocket-Key", rpc.generateWebSocketKey()) 395 | 396 | auth := c.Request.Header.Get("Authorization") 397 | if len(strings.Split(auth, " ")) != 2 { 398 | log.Error("failed to get stuff from auth header") 399 | c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to get stuff from auth header"}) 400 | return 401 | } 402 | 403 | // NOTE: The other part of the map ([1]) is the decrypted data from the crypto challenge. 404 | connIdStr := strings.Split(auth, " ")[0] 405 | userId, err := strconv.Atoi(connIdStr) 406 | if err != nil { 407 | log.Error(err) 408 | c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) 409 | return 410 | } 411 | 412 | conn, err := upgrader.Upgrade(c.Writer, c.Request, nil) 413 | if err != nil { 414 | log.Error(err) 415 | c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to upgrade connection"}) 416 | return 417 | } 418 | rpc.sockets.Set(userId, conn) 419 | rpc.sockets.Get(userId).SetReadLimit(WEBSOCKET_READ_LIMIT) 420 | 421 | // TODO: Transaction 422 | if !rpc.users.Exists(uint64(userId)) { 423 | u := &pb.User{ 424 | Id: uint64(userId), 425 | GithubLogin: rpc.nameGenerator.Generate(), 426 | } 427 | rpc.users.Set(uint64(userId), u) 428 | log.Debugf("added a user, current users: %v", len(rpc.users.Map())) 429 | } 430 | pd := NewProtoDispatcher(rpc, userId) 431 | go rpc.handleMessages(pd) 432 | if err := pd.SendHello(); err != nil { 433 | log.Error(err) 434 | c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) 435 | return 436 | } 437 | } 438 | -------------------------------------------------------------------------------- /src/zed/version.go: -------------------------------------------------------------------------------- 1 | package zed 2 | 3 | type Version struct { 4 | Version string `json:"version"` 5 | URL string `json:"url"` 6 | } 7 | 8 | func NewVersion(offline bool) Version { 9 | return Version{} 10 | } 11 | --------------------------------------------------------------------------------