├── .github
└── workflows
│ ├── deploy.yml
│ └── test.yml
├── .gitignore
├── ARCHITECTURE.md
├── LICENSE
├── README.md
├── biome.json
├── buf.gen.yaml
├── buf.lock
├── buf.yaml
├── demo
├── demo.css
├── index.html
└── index.ts
├── exa
├── codeium_common_pb
│ └── codeium_common.proto
└── language_server_pb
│ └── language_server.proto
├── package-lock.json
├── package.json
├── src
├── annotations.ts
├── api
│ └── proto
│ │ └── exa
│ │ ├── codeium_common_pb
│ │ └── codeium_common_pb.ts
│ │ └── language_server_pb
│ │ ├── language_server_connect.ts
│ │ └── language_server_pb.ts
├── codeium.ts
├── commands.ts
├── completionDecoration.ts
├── completionRequester.ts
├── config.ts
├── defaultCycleWidget.ts
├── effects.ts
├── plugin.ts
├── requestCompletion.ts
└── types.ts
├── tsconfig.json
└── vite.config.js
/.github/workflows/deploy.yml:
--------------------------------------------------------------------------------
1 | name: Deploy
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 |
8 | permissions:
9 | contents: read
10 | pages: write
11 | id-token: write
12 |
13 | jobs:
14 | build:
15 | name: Build
16 | runs-on: ubuntu-latest
17 |
18 | steps:
19 | - name: Checkout repo
20 | uses: actions/checkout@v3
21 |
22 | - name: Setup Node
23 | uses: actions/setup-node@v3
24 |
25 | - name: Install dependencies
26 | uses: bahmutov/npm-install@v1
27 |
28 | - name: Build project
29 | run: npm run pages
30 | - name: Setup Pages
31 | uses: actions/configure-pages@v3
32 | - name: Upload artifact
33 | uses: actions/upload-pages-artifact@v2
34 | with:
35 | path: "./demo/dist"
36 | - name: Deploy to GitHub Pages
37 | id: deployment
38 | uses: actions/deploy-pages@v2
39 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Test
2 |
3 | on: push
4 |
5 | jobs:
6 | build:
7 | name: Test
8 | runs-on: ubuntu-latest
9 |
10 | steps:
11 | - name: Checkout repo
12 | uses: actions/checkout@v4
13 |
14 | - name: Setup Node
15 | uses: actions/setup-node@v4
16 | with:
17 | node-version: 20
18 |
19 | - name: Install dependencies
20 | uses: bahmutov/npm-install@v1
21 |
22 | - run: npm run tsc
23 | - run: npm run test
24 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 | .DS_Store
4 | .tshy-build
5 |
--------------------------------------------------------------------------------
/ARCHITECTURE.md:
--------------------------------------------------------------------------------
1 | # Architecture
2 |
3 | This module requests autocompletions of code from [Codeium](https://codeium.com/),
4 | shows "ghost text" for them, and allows users to accept them by clicking
5 | or hitting Tab.
6 |
7 | ## Ghost text
8 |
9 | The way that this shows ghost text is quite different from how [codemirror-copilot](https://github.com/asadm/codemirror-copilot) does it, and is derived from the code
10 | in [modeling-app](https://github.com/KittyCAD/modeling-app), which is then derived
11 | from the code in [Cursor](https://cursor.sh/).
12 |
13 | In codemirror-copilot, ghost text is [based on widgets](https://github.com/asadm/codemirror-copilot/blob/09e737a3da8449d5d7f0b5cd8266688afaf3baa5/packages/codemirror-copilot/src/inline-suggestion.ts#L60-L75) -
14 | displaying a [CodeMirror widget](https://codemirror.net/docs/ref/#view.Decoration^widget)
15 | inline with text. This is simple, but has the drawbacks of the ghost
16 | text being non-highlighted, and ghost text does not create additional
17 | line numbers in the line gutter, if there is one.
18 |
19 | In this module, ghost text is added to the real text in the editor, but
20 | we use an [addToHistory](https://codemirror.net/docs/ref/#state.Transaction^addToHistory)
21 | annotation to ensure that it is not added to history. This produces ghost
22 | text that looks more cohesive with the rest of the design of the editor,
23 | but it has the drawback of producing events that upstream consumers
24 | might confuse with user edits. We provide the `copilotIgnore` annotation
25 | and the `shouldTakeUpdate` method to help with this potential confusion.
26 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | ISC License
2 |
3 | Copyright (c) 2024, Val Town
4 |
5 | Permission to use, copy, modify, and/or distribute this software for any
6 | purpose with or without fee is hereby granted, provided that the above
7 | copyright notice and this permission notice appear in all copies.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 |
17 | Contains parts of modeling-app, licensed under the MIT License,
18 | Copyright (c) 2023 The Zoo Authors
19 |
20 | Contains parts of Cursor, licensed under the MIT License,
21 | Copyright (c) 2023 Cursor AI, Inc.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # codemirror-codeium
2 |
3 | [](https://www.npmjs.com/package/@valtown/codemirror-codeium)
4 |
5 | ```mermaid
6 | flowchart TD
7 | Keystroke --> SetTimeout
8 | Keystroke -->|ignoreUpdate| Cancelled
9 | SetTimeout -->|edits| Cancelled
10 | SetTimeout --> GetCompletions
11 | GetCompletions -->|edits| Cancelled
12 | X[ ] -->|focusChanged| Cancelled
13 | GetCompletions --> DispatchEdits
14 | DispatchEdits -->|mousedown| Cancelled
15 | DispatchEdits --> SameKeyCommand
16 | SameKeyCommand -->|tab| AcceptSuggestionCommand
17 | ```
18 |
19 | _Very experimental and unofficial_
20 |
21 | Copilot-like ghost text code from [modeling-app](https://github.com/KittyCAD/modeling-app)
22 | by [Jess Frazelle](https://github.com/jessfraz) and based on [Cursor](https://cursor.sh/).
23 |
24 | ## Documentation
25 |
26 | See the [demo source code](https://github.com/val-town/codemirror-codeium/tree/main/demo) for
27 | a reference to how it's used.
28 |
29 | ```ts
30 | import { copilotPlugin } from "@valtown/codemirror-codeium";
31 |
32 | // This is a CodeMirror extension
33 | copilotPlugin();
34 | ```
35 |
36 | ### CSS
37 |
38 | This adds a `.ghostText` class to CodeMirror decorations for the AI-written
39 | text. You can add your own style for this class. The demo uses this style:
40 |
41 | ```css
42 | .cm-ghostText,
43 | .cm-ghostText * {
44 | opacity: 0.6;
45 | filter: grayscale(20%);
46 | cursor: pointer;
47 | }
48 |
49 | .cm-ghostText:hover {
50 | background: #eee;
51 | }
52 | ```
53 |
54 | ### Architecture
55 |
56 | This makes requests against the [Codeium](https://codeium.com/) hosted product,
57 | using their Protocol Buffer-based interface. That's what the `buf` and `connectrpc`
58 | modules are doing - generating and using bindings to their service.
59 |
60 | The extension is a composite of facets, decorations, state fields, and more
61 | that are encapsulated.
62 |
--------------------------------------------------------------------------------
/biome.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://biomejs.dev/schemas/1.8.1/schema.json",
3 | "organizeImports": {
4 | "enabled": true
5 | },
6 | "formatter": {
7 | "indentStyle": "space"
8 | },
9 | "files": {
10 | "ignore": ["dist/*"]
11 | },
12 | "linter": {
13 | "enabled": true,
14 | "rules": {
15 | "recommended": true,
16 | "style": {
17 | "noNonNullAssertion": "info"
18 | },
19 | "suspicious": {
20 | "noExplicitAny": "info"
21 | }
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/buf.gen.yaml:
--------------------------------------------------------------------------------
1 | # buf.gen.yaml defines a local generation template.
2 | # For details, see https://docs.buf.build/configuration/v1/buf-gen-yaml
3 | version: v1
4 | plugins:
5 | - plugin: buf.build/bufbuild/es:v1.4.2
6 | out: src/api/proto
7 | opt:
8 | - target=ts
9 | - plugin: buf.build/connectrpc/es:v1.1.3
10 | out: src/api/proto
11 | opt:
12 | - target=ts
13 |
--------------------------------------------------------------------------------
/buf.lock:
--------------------------------------------------------------------------------
1 | # Generated by buf. DO NOT EDIT.
2 | version: v1
3 | deps:
4 | - remote: buf.build
5 | owner: envoyproxy
6 | repository: protoc-gen-validate
7 | commit: 71881f09a0c5420a9545a07987a86728
8 | digest: shake256:d320bbf06653b1b2b45a1f95bfa82bf7b998221a777a042708c50d6f86a30d1a85b50c5704c597142d9b308280efe1295d39d76d1abea5f7046d3df4c8cc3cef
9 |
--------------------------------------------------------------------------------
/buf.yaml:
--------------------------------------------------------------------------------
1 | version: v1
2 | deps:
3 | - buf.build/envoyproxy/protoc-gen-validate
4 | build:
5 | excludes:
6 | - node_modules
7 | lint:
8 | use:
9 | - DEFAULT
10 | except:
11 | - PACKAGE_VERSION_SUFFIX
12 | allow_comment_ignores: true
13 | breaking:
14 | except:
15 | - FILE_NO_DELETE
16 |
--------------------------------------------------------------------------------
/demo/demo.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: sans-serif;
4 | background: #eee;
5 | color: #333;
6 | }
7 |
8 | * {
9 | box-sizing: border-box;
10 | }
11 |
12 | h1 {
13 | margin: 0;
14 | }
15 |
16 | h2 {
17 | font-weight: normal;
18 | font-size: 18px;
19 | }
20 |
21 | p {
22 | line-height: 1.5;
23 | }
24 |
25 | a {
26 | color: blue;
27 | }
28 |
29 | a:hover {
30 | color: green;
31 | }
32 |
33 | .cm-editor {
34 | border: 1px solid #000;
35 | }
36 |
37 | main {
38 | max-width: 640px;
39 | min-height: 100vh;
40 | margin: 0 auto;
41 | background: #fff;
42 | padding: 20px;
43 | border-left: 1px solid #aaa;
44 | border-right: 1px solid #aaa;
45 | }
46 |
47 | .cm-ghostText,
48 | .cm-ghostText * {
49 | opacity: 0.6;
50 | filter: grayscale(20%);
51 | cursor: pointer;
52 | }
53 |
54 | .cm-ghostText:hover {
55 | background: #eee;
56 | }
57 |
58 | .cm-codeium-cycle {
59 | font-size: 9px;
60 | background-color: #eee;
61 | padding: 2px;
62 | border-radius: 2px;
63 | display: inline-block;
64 | }
65 |
66 | .cm-codeium-cycle-key {
67 | font-size: 9px;
68 | font-family: monospace;
69 | display: inline-block;
70 | padding: 2px;
71 | border-radius: 2px;
72 | border: none;
73 | background-color: lightblue;
74 | margin-left: 5px;
75 | }
76 |
77 | .cm-codeium-cycle-key:hover {
78 | background-color: deepskyblue;
79 | }
80 |
81 | .cm-codeium-cycle-explanation {
82 | font-family: monospace;
83 | display: inline-block;
84 | padding: 2px;
85 | }
86 |
--------------------------------------------------------------------------------
/demo/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | codemirror-codeium demo
7 |
8 |
9 |
10 |
11 |
16 | by val.town
17 |
18 | ⚠️ Hella experimental, very unofficial. Type in the box and it'll give
19 | you AI autocompletions powered by Codeium.
20 |
21 |
22 | TypeScript AI autocompletion
23 |
24 |
25 | Python AI autocompletion
26 |
27 |
28 | TypeScript AI autocompletion (cmd+k to trigger completion)
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/demo/index.ts:
--------------------------------------------------------------------------------
1 | import { EditorView, basicSetup } from "codemirror";
2 | import { javascript } from "@codemirror/lang-javascript";
3 | import {
4 | codeiumOtherDocumentsConfig,
5 | startCompletion,
6 | Language,
7 | copilotPlugin,
8 | } from "../src/plugin.js";
9 | import { python } from "@codemirror/lang-python";
10 | import { keymap } from "@codemirror/view";
11 |
12 | new EditorView({
13 | doc: "// Factorial function",
14 | extensions: [
15 | basicSetup,
16 | javascript({
17 | typescript: true,
18 | jsx: true,
19 | }),
20 | codeiumOtherDocumentsConfig.of({
21 | override: () => [
22 | {
23 | absolutePath: "https://esm.town/v/foo.ts",
24 | text: `export const foo = 10;
25 |
26 | const hiddenValue = "https://macwright.com/"`,
27 | language: Language.TYPESCRIPT,
28 | editorLanguage: "typescript",
29 | },
30 | ],
31 | }),
32 | copilotPlugin({
33 | apiKey: "d49954eb-cfba-4992-980f-d8fb37f0e942",
34 | shouldComplete(context) {
35 | if (context.tokenBefore(["String"])) {
36 | return true;
37 | }
38 | const match = context.matchBefore(/(@(?:\w*))(?:[./](\w*))?/);
39 | return !match;
40 | },
41 | }),
42 | ],
43 | parent: document.querySelector("#editor")!,
44 | });
45 |
46 | new EditorView({
47 | doc: "// Factorial function (explicit trigger)",
48 | extensions: [
49 | basicSetup,
50 | javascript({
51 | typescript: true,
52 | jsx: true,
53 | }),
54 | codeiumOtherDocumentsConfig.of({
55 | override: () => [
56 | {
57 | absolutePath: "https://esm.town/v/foo.ts",
58 | text: `export const foo = 10;
59 |
60 | const hiddenValue = "https://macwright.com/"`,
61 | language: Language.TYPESCRIPT,
62 | editorLanguage: "typescript",
63 | },
64 | ],
65 | }),
66 | copilotPlugin({
67 | apiKey: "d49954eb-cfba-4992-980f-d8fb37f0e942",
68 | shouldComplete(context) {
69 | if (context.tokenBefore(["String"])) {
70 | return true;
71 | }
72 | const match = context.matchBefore(/(@(?:\w*))(?:[./](\w*))?/);
73 | return !match;
74 | },
75 | alwaysOn: false,
76 | }),
77 | keymap.of([
78 | {
79 | key: "Cmd-k",
80 | run: startCompletion,
81 | },
82 | ]),
83 | ],
84 | parent: document.querySelector("#editor-explicit")!,
85 | });
86 |
87 | new EditorView({
88 | doc: "def hi_python():",
89 | extensions: [
90 | basicSetup,
91 | python(),
92 | copilotPlugin({
93 | apiKey: "d49954eb-cfba-4992-980f-d8fb37f0e942",
94 | language: Language.PYTHON,
95 | }),
96 | ],
97 | parent: document.querySelector("#editor-python")!,
98 | });
99 |
--------------------------------------------------------------------------------
/exa/codeium_common_pb/codeium_common.proto:
--------------------------------------------------------------------------------
1 | // Copyright Exafunction, Inc.
2 |
3 | syntax = "proto3";
4 |
5 | package exa.codeium_common_pb;
6 |
7 | import "google/protobuf/duration.proto";
8 | import "google/protobuf/timestamp.proto";
9 | import "validate/validate.proto";
10 |
11 | option go_package = "github.com/Exafunction/Exafunction/exa/codeium_common_pb";
12 |
13 | enum ExperimentKey {
14 | UNSPECIFIED = 0;
15 | JUPYTER_FORMAT = 77;
16 | }
17 |
18 | // Next ID: 12, Previous field: entropy.
19 | message Completion {
20 | string completion_id = 1;
21 | string text = 2;
22 | string prefix = 3;
23 | string stop = 4;
24 | double score = 5;
25 | repeated uint64 tokens = 6;
26 | repeated string decoded_tokens = 7;
27 | repeated double probabilities = 8;
28 | repeated double adjusted_probabilities = 9;
29 | uint64 generated_length = 10;
30 | }
31 |
32 | // Authentication source for users on the cloud service.
33 | enum AuthSource {
34 | AUTH_SOURCE_CODEIUM = 0;
35 | }
36 |
37 | // Next ID: 15, Previous field: url.
38 | message Metadata {
39 | string ide_name = 1 [(validate.rules).string.min_len = 1];
40 | string ide_version = 7 [(validate.rules).string.min_len = 1];
41 | string extension_name = 12;
42 | string extension_version = 2 [(validate.rules).string.min_len = 1];
43 | string api_key = 3 [(validate.rules).string.uuid = true];
44 | // Regex derived from https://stackoverflow.com/a/48300605.
45 | // TODO(prem): Should this be mandatory?
46 | string locale = 4 [(validate.rules).string = {
47 | ignore_empty: true,
48 | pattern: "^[A-Za-z]{2,4}([_-][A-Za-z]{4})?([_-]([A-Za-z]{2}|[0-9]{3}))?$"
49 | }];
50 | // UID identifying a single session for the given user.
51 | string session_id = 10;
52 |
53 | // Used purely in language server to cancel in flight requests.
54 | // If request_id is 0, then the request is not cancelable.
55 | // This should be a strictly monotonically increasing number
56 | // for the duration of a session.
57 | uint64 request_id = 9;
58 |
59 | // Browser-specific information.
60 | string user_agent = 13;
61 | string url = 14 [(validate.rules).string = {
62 | ignore_empty: true,
63 | uri: true
64 | }];
65 |
66 | // Authentication source information.
67 | AuthSource auth_source = 15;
68 | }
69 |
70 | // Next ID: 3, Previous field: insert_spaces.
71 | message EditorOptions {
72 | uint64 tab_size = 1 [(validate.rules).uint64.gt = 0];
73 | bool insert_spaces = 2;
74 | }
75 |
76 | message Event {
77 | EventType event_type = 1;
78 | string event_json = 2;
79 | int64 timestamp_unix_ms = 3;
80 | }
81 |
82 | enum EventType {
83 | EVENT_TYPE_UNSPECIFIED = 0;
84 | EVENT_TYPE_ENABLE_CODEIUM = 1;
85 | EVENT_TYPE_DISABLE_CODEIUM = 2;
86 | EVENT_TYPE_SHOW_PREVIOUS_COMPLETION = 3;
87 | EVENT_TYPE_SHOW_NEXT_COMPLETION = 4;
88 | }
89 |
90 | enum CompletionSource {
91 | COMPLETION_SOURCE_UNSPECIFIED = 0;
92 | COMPLETION_SOURCE_TYPING_AS_SUGGESTED = 1;
93 | COMPLETION_SOURCE_CACHE = 2;
94 | COMPLETION_SOURCE_NETWORK = 3;
95 | }
96 |
97 | // Every time this list is updated, we should be redeploying the API server
98 | // since it uses the string representation for BQ.
99 | enum Language {
100 | LANGUAGE_UNSPECIFIED = 0;
101 | LANGUAGE_C = 1;
102 | LANGUAGE_CLOJURE = 2;
103 | LANGUAGE_COFFEESCRIPT = 3;
104 | LANGUAGE_CPP = 4;
105 | LANGUAGE_CSHARP = 5;
106 | LANGUAGE_CSS = 6;
107 | LANGUAGE_CUDACPP = 7;
108 | LANGUAGE_DOCKERFILE = 8;
109 | LANGUAGE_GO = 9;
110 | LANGUAGE_GROOVY = 10;
111 | LANGUAGE_HANDLEBARS = 11;
112 | LANGUAGE_HASKELL = 12;
113 | LANGUAGE_HCL = 13;
114 | LANGUAGE_HTML = 14;
115 | LANGUAGE_INI = 15;
116 | LANGUAGE_JAVA = 16;
117 | LANGUAGE_JAVASCRIPT = 17;
118 | LANGUAGE_JSON = 18;
119 | LANGUAGE_JULIA = 19;
120 | LANGUAGE_KOTLIN = 20;
121 | LANGUAGE_LATEX = 21;
122 | LANGUAGE_LESS = 22;
123 | LANGUAGE_LUA = 23;
124 | LANGUAGE_MAKEFILE = 24;
125 | LANGUAGE_MARKDOWN = 25;
126 | LANGUAGE_OBJECTIVEC = 26;
127 | LANGUAGE_OBJECTIVECPP = 27;
128 | LANGUAGE_PERL = 28;
129 | LANGUAGE_PHP = 29;
130 | LANGUAGE_PLAINTEXT = 30;
131 | LANGUAGE_PROTOBUF = 31;
132 | LANGUAGE_PBTXT = 32;
133 | LANGUAGE_PYTHON = 33;
134 | LANGUAGE_R = 34;
135 | LANGUAGE_RUBY = 35;
136 | LANGUAGE_RUST = 36;
137 | LANGUAGE_SASS = 37;
138 | LANGUAGE_SCALA = 38;
139 | LANGUAGE_SCSS = 39;
140 | LANGUAGE_SHELL = 40;
141 | LANGUAGE_SQL = 41;
142 | LANGUAGE_STARLARK = 42;
143 | LANGUAGE_SWIFT = 43;
144 | LANGUAGE_TSX = 44;
145 | LANGUAGE_TYPESCRIPT = 45;
146 | LANGUAGE_VISUALBASIC = 46;
147 | LANGUAGE_VUE = 47;
148 | LANGUAGE_XML = 48;
149 | LANGUAGE_XSL = 49;
150 | LANGUAGE_YAML = 50;
151 | LANGUAGE_SVELTE = 51;
152 | LANGUAGE_TOML = 52;
153 | LANGUAGE_DART = 53;
154 | LANGUAGE_RST = 54;
155 | LANGUAGE_OCAML = 55;
156 | LANGUAGE_CMAKE = 56;
157 | LANGUAGE_PASCAL = 57;
158 | LANGUAGE_ELIXIR = 58;
159 | LANGUAGE_FSHARP = 59;
160 | LANGUAGE_LISP = 60;
161 | LANGUAGE_MATLAB = 61;
162 | LANGUAGE_POWERSHELL = 62;
163 | LANGUAGE_SOLIDITY = 63;
164 | LANGUAGE_ADA = 64;
165 | LANGUAGE_OCAML_INTERFACE = 65;
166 | }
167 |
--------------------------------------------------------------------------------
/exa/language_server_pb/language_server.proto:
--------------------------------------------------------------------------------
1 | // Copyright Exafunction, Inc.
2 |
3 | syntax = "proto3";
4 |
5 | package exa.language_server_pb;
6 |
7 | import "exa/codeium_common_pb/codeium_common.proto";
8 | import "validate/validate.proto";
9 |
10 | option go_package = "github.com/Exafunction/Exafunction/exa/language_server_pb";
11 |
12 | service LanguageServerService {
13 | rpc GetCompletions(GetCompletionsRequest) returns (GetCompletionsResponse) {}
14 | rpc AcceptCompletion(AcceptCompletionRequest) returns (AcceptCompletionResponse) {}
15 | rpc GetAuthToken(GetAuthTokenRequest) returns (GetAuthTokenResponse) {}
16 | }
17 |
18 | message MultilineConfig {
19 | // Multiline model threshold. 0-1, higher = more single line, lower = more multiline,
20 | // 0.0 = only_multiline, default is 0.5
21 | float threshold = 1;
22 | }
23 |
24 | // Next ID: 9, Previous field: disable_cache.
25 | message GetCompletionsRequest {
26 | codeium_common_pb.Metadata metadata = 1 [(validate.rules).message.required = true];
27 | Document document = 2 [(validate.rules).message.required = true];
28 | codeium_common_pb.EditorOptions editor_options = 3 [(validate.rules).message.required = true];
29 | repeated Document other_documents = 5;
30 | ExperimentConfig experiment_config = 7;
31 |
32 | string model_name = 10;
33 | MultilineConfig multiline_config = 13;
34 | }
35 |
36 | // Next ID: 5, Previous field: latency_info.
37 | message GetCompletionsResponse {
38 | State state = 1;
39 | repeated CompletionItem completion_items = 2;
40 | }
41 |
42 | // Next ID: 3, Previous field: completion_id.
43 | message AcceptCompletionRequest {
44 | codeium_common_pb.Metadata metadata = 1 [(validate.rules).message.required = true];
45 | string completion_id = 2;
46 | }
47 |
48 | // Next ID: 1, Previous field: N/A.
49 | message AcceptCompletionResponse {}
50 |
51 | // Next ID: 1, Previous field: N/A.
52 | message GetAuthTokenRequest {}
53 |
54 | // Next ID: 3, Previous field: uuid.
55 | message GetAuthTokenResponse {
56 | string auth_token = 1;
57 | string uuid = 2;
58 | }
59 |
60 | /*****************************************************************************/
61 | /* Helper Messages */
62 | /*****************************************************************************/
63 |
64 | message DocumentPosition {
65 | // 0-indexed. Measured in UTF-8 bytes.
66 | uint64 row = 1;
67 | // 0-indexed. Measured in UTF-8 bytes.
68 | uint64 col = 2;
69 | }
70 |
71 | // Next ID: 9, Previous field: cursor_position.
72 | message Document {
73 | string absolute_path = 1;
74 | // Path relative to the root of the workspace.
75 | string relative_path = 2;
76 | string text = 3;
77 | // Language ID provided by the editor.
78 | string editor_language = 4 [(validate.rules).string.min_len = 1];
79 | // Language enum standardized across editors.
80 | codeium_common_pb.Language language = 5;
81 | // Measured in number of UTF-8 bytes.
82 | uint64 cursor_offset = 6;
83 | // May be present instead of cursor_offset.
84 | DocumentPosition cursor_position = 8;
85 | // \n or \r\n, if known.
86 | string line_ending = 7 [(validate.rules).string = {
87 | in: [
88 | "",
89 | "\n",
90 | "\r\n"
91 | ]
92 | }];
93 | }
94 |
95 | message ExperimentConfig {
96 | repeated codeium_common_pb.ExperimentKey force_enable_experiments = 1 [(validate.rules).repeated.unique = true];
97 | }
98 |
99 | enum CodeiumState {
100 | CODEIUM_STATE_UNSPECIFIED = 0;
101 | CODEIUM_STATE_INACTIVE = 1;
102 | CODEIUM_STATE_PROCESSING = 2;
103 | CODEIUM_STATE_SUCCESS = 3;
104 | CODEIUM_STATE_WARNING = 4;
105 | CODEIUM_STATE_ERROR = 5;
106 | }
107 |
108 | // Next ID: 3, Previous field: message.
109 | message State {
110 | CodeiumState state = 1;
111 | string message = 2;
112 | }
113 |
114 | enum LineType {
115 | LINE_TYPE_UNSPECIFIED = 0;
116 | LINE_TYPE_SINGLE = 1;
117 | LINE_TYPE_MULTI = 2;
118 | }
119 |
120 | // Next ID: 5, Previous field: end_position.
121 | message Range {
122 | uint64 start_offset = 1;
123 | uint64 end_offset = 2;
124 | DocumentPosition start_position = 3;
125 | DocumentPosition end_position = 4;
126 | }
127 |
128 | message Suffix {
129 | // Text to insert after the cursor when accepting the completion.
130 | string text = 1;
131 | // Cursor position delta (as signed offset) from the end of the inserted
132 | // completion (including the suffix).
133 | int64 delta_cursor_offset = 2;
134 | }
135 |
136 | enum CompletionPartType {
137 | COMPLETION_PART_TYPE_UNSPECIFIED = 0;
138 | // Single-line completion parts that appear within an existing line of text.
139 | COMPLETION_PART_TYPE_INLINE = 1;
140 | // Possibly multi-line completion parts that appear below an existing line of text.
141 | COMPLETION_PART_TYPE_BLOCK = 2;
142 | // Like COMPLETION_PART_TYPE_INLINE, but overwrites the existing text.
143 | COMPLETION_PART_TYPE_INLINE_MASK = 3;
144 | }
145 |
146 | // Represents a contiguous part of the completion text that is not
147 | // already in the document.
148 | // Next ID: 4, Previous field: prefix.
149 | message CompletionPart {
150 | string text = 1;
151 | // Offset in the original document where the part starts. For block
152 | // parts, this is always the end of the line before the block.
153 | uint64 offset = 2;
154 | CompletionPartType type = 3;
155 | // The section of the original line that came before this part. Only valid for
156 | // COMPLETION_PART_TYPE_INLINE.
157 | string prefix = 4;
158 | // In the case of COMPLETION_PART_TYPE_BLOCK, represents the line it is below.
159 | uint64 line = 5;
160 | }
161 |
162 | // Next ID: 9, Previous field: completion_parts.
163 | message CompletionItem {
164 | codeium_common_pb.Completion completion = 1;
165 | Suffix suffix = 5;
166 | Range range = 2;
167 | codeium_common_pb.CompletionSource source = 3;
168 | repeated CompletionPart completion_parts = 8;
169 | }
170 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@valtown/codemirror-codeium",
3 | "version": "1.1.1",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "@valtown/codemirror-codeium",
9 | "version": "1.1.1",
10 | "license": "ISC",
11 | "dependencies": {
12 | "@bufbuild/protobuf": "^1.10.0",
13 | "@connectrpc/connect": "^1.4.0",
14 | "@connectrpc/connect-web": "^1.4.0"
15 | },
16 | "devDependencies": {
17 | "@biomejs/biome": "^1.8.1",
18 | "@bufbuild/buf": "^1.36.0",
19 | "@codemirror/lang-javascript": "^6.2.2",
20 | "@codemirror/lang-python": "^6.1.5",
21 | "codemirror": "^6",
22 | "typescript": "^5.4.3",
23 | "vite": "^5.2.7"
24 | },
25 | "engines": {
26 | "node": "*"
27 | },
28 | "peerDependencies": {
29 | "@codemirror/autocomplete": "^6",
30 | "@codemirror/state": "^6",
31 | "@codemirror/view": "^6"
32 | }
33 | },
34 | "node_modules/@biomejs/biome": {
35 | "version": "1.8.3",
36 | "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-1.8.3.tgz",
37 | "integrity": "sha512-/uUV3MV+vyAczO+vKrPdOW0Iaet7UnJMU4bNMinggGJTAnBPjCoLEYcyYtYHNnUNYlv4xZMH6hVIQCAozq8d5w==",
38 | "dev": true,
39 | "hasInstallScript": true,
40 | "bin": {
41 | "biome": "bin/biome"
42 | },
43 | "engines": {
44 | "node": ">=14.21.3"
45 | },
46 | "funding": {
47 | "type": "opencollective",
48 | "url": "https://opencollective.com/biome"
49 | },
50 | "optionalDependencies": {
51 | "@biomejs/cli-darwin-arm64": "1.8.3",
52 | "@biomejs/cli-darwin-x64": "1.8.3",
53 | "@biomejs/cli-linux-arm64": "1.8.3",
54 | "@biomejs/cli-linux-arm64-musl": "1.8.3",
55 | "@biomejs/cli-linux-x64": "1.8.3",
56 | "@biomejs/cli-linux-x64-musl": "1.8.3",
57 | "@biomejs/cli-win32-arm64": "1.8.3",
58 | "@biomejs/cli-win32-x64": "1.8.3"
59 | }
60 | },
61 | "node_modules/@biomejs/cli-darwin-arm64": {
62 | "version": "1.8.3",
63 | "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.8.3.tgz",
64 | "integrity": "sha512-9DYOjclFpKrH/m1Oz75SSExR8VKvNSSsLnVIqdnKexj6NwmiMlKk94Wa1kZEdv6MCOHGHgyyoV57Cw8WzL5n3A==",
65 | "cpu": [
66 | "arm64"
67 | ],
68 | "dev": true,
69 | "optional": true,
70 | "os": [
71 | "darwin"
72 | ],
73 | "engines": {
74 | "node": ">=14.21.3"
75 | }
76 | },
77 | "node_modules/@biomejs/cli-darwin-x64": {
78 | "version": "1.8.3",
79 | "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.8.3.tgz",
80 | "integrity": "sha512-UeW44L/AtbmOF7KXLCoM+9PSgPo0IDcyEUfIoOXYeANaNXXf9mLUwV1GeF2OWjyic5zj6CnAJ9uzk2LT3v/wAw==",
81 | "cpu": [
82 | "x64"
83 | ],
84 | "dev": true,
85 | "optional": true,
86 | "os": [
87 | "darwin"
88 | ],
89 | "engines": {
90 | "node": ">=14.21.3"
91 | }
92 | },
93 | "node_modules/@biomejs/cli-linux-arm64": {
94 | "version": "1.8.3",
95 | "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.8.3.tgz",
96 | "integrity": "sha512-fed2ji8s+I/m8upWpTJGanqiJ0rnlHOK3DdxsyVLZQ8ClY6qLuPc9uehCREBifRJLl/iJyQpHIRufLDeotsPtw==",
97 | "cpu": [
98 | "arm64"
99 | ],
100 | "dev": true,
101 | "optional": true,
102 | "os": [
103 | "linux"
104 | ],
105 | "engines": {
106 | "node": ">=14.21.3"
107 | }
108 | },
109 | "node_modules/@biomejs/cli-linux-arm64-musl": {
110 | "version": "1.8.3",
111 | "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.8.3.tgz",
112 | "integrity": "sha512-9yjUfOFN7wrYsXt/T/gEWfvVxKlnh3yBpnScw98IF+oOeCYb5/b/+K7YNqKROV2i1DlMjg9g/EcN9wvj+NkMuQ==",
113 | "cpu": [
114 | "arm64"
115 | ],
116 | "dev": true,
117 | "optional": true,
118 | "os": [
119 | "linux"
120 | ],
121 | "engines": {
122 | "node": ">=14.21.3"
123 | }
124 | },
125 | "node_modules/@biomejs/cli-linux-x64": {
126 | "version": "1.8.3",
127 | "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-1.8.3.tgz",
128 | "integrity": "sha512-I8G2QmuE1teISyT8ie1HXsjFRz9L1m5n83U1O6m30Kw+kPMPSKjag6QGUn+sXT8V+XWIZxFFBoTDEDZW2KPDDw==",
129 | "cpu": [
130 | "x64"
131 | ],
132 | "dev": true,
133 | "optional": true,
134 | "os": [
135 | "linux"
136 | ],
137 | "engines": {
138 | "node": ">=14.21.3"
139 | }
140 | },
141 | "node_modules/@biomejs/cli-linux-x64-musl": {
142 | "version": "1.8.3",
143 | "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-1.8.3.tgz",
144 | "integrity": "sha512-UHrGJX7PrKMKzPGoEsooKC9jXJMa28TUSMjcIlbDnIO4EAavCoVmNQaIuUSH0Ls2mpGMwUIf+aZJv657zfWWjA==",
145 | "cpu": [
146 | "x64"
147 | ],
148 | "dev": true,
149 | "optional": true,
150 | "os": [
151 | "linux"
152 | ],
153 | "engines": {
154 | "node": ">=14.21.3"
155 | }
156 | },
157 | "node_modules/@biomejs/cli-win32-arm64": {
158 | "version": "1.8.3",
159 | "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.8.3.tgz",
160 | "integrity": "sha512-J+Hu9WvrBevfy06eU1Na0lpc7uR9tibm9maHynLIoAjLZpQU3IW+OKHUtyL8p6/3pT2Ju5t5emReeIS2SAxhkQ==",
161 | "cpu": [
162 | "arm64"
163 | ],
164 | "dev": true,
165 | "optional": true,
166 | "os": [
167 | "win32"
168 | ],
169 | "engines": {
170 | "node": ">=14.21.3"
171 | }
172 | },
173 | "node_modules/@biomejs/cli-win32-x64": {
174 | "version": "1.8.3",
175 | "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-1.8.3.tgz",
176 | "integrity": "sha512-/PJ59vA1pnQeKahemaQf4Nyj7IKUvGQSc3Ze1uIGi+Wvr1xF7rGobSrAAG01T/gUDG21vkDsZYM03NAmPiVkqg==",
177 | "cpu": [
178 | "x64"
179 | ],
180 | "dev": true,
181 | "optional": true,
182 | "os": [
183 | "win32"
184 | ],
185 | "engines": {
186 | "node": ">=14.21.3"
187 | }
188 | },
189 | "node_modules/@bufbuild/buf": {
190 | "version": "1.36.0",
191 | "resolved": "https://registry.npmjs.org/@bufbuild/buf/-/buf-1.36.0.tgz",
192 | "integrity": "sha512-IhUx4aSlCGGD9wJQMsccs+jYsLowdbVPLtJnjJJvLWjxvatKV224iuKn6jP930k0rvejt/c6n/0sSWVu12zksQ==",
193 | "dev": true,
194 | "hasInstallScript": true,
195 | "bin": {
196 | "buf": "bin/buf",
197 | "protoc-gen-buf-breaking": "bin/protoc-gen-buf-breaking",
198 | "protoc-gen-buf-lint": "bin/protoc-gen-buf-lint"
199 | },
200 | "engines": {
201 | "node": ">=12"
202 | },
203 | "optionalDependencies": {
204 | "@bufbuild/buf-darwin-arm64": "1.36.0",
205 | "@bufbuild/buf-darwin-x64": "1.36.0",
206 | "@bufbuild/buf-linux-aarch64": "1.36.0",
207 | "@bufbuild/buf-linux-x64": "1.36.0",
208 | "@bufbuild/buf-win32-arm64": "1.36.0",
209 | "@bufbuild/buf-win32-x64": "1.36.0"
210 | }
211 | },
212 | "node_modules/@bufbuild/buf-darwin-arm64": {
213 | "version": "1.36.0",
214 | "resolved": "https://registry.npmjs.org/@bufbuild/buf-darwin-arm64/-/buf-darwin-arm64-1.36.0.tgz",
215 | "integrity": "sha512-0sXbTAedj9KY7NSHbf4536SLQKjV4yhlREw44f9mV9kGFI3Jr2Dj1z8UDzB80Ti3YFgpVu2BbcOMXIDzQ6dleA==",
216 | "cpu": [
217 | "arm64"
218 | ],
219 | "dev": true,
220 | "optional": true,
221 | "os": [
222 | "darwin"
223 | ],
224 | "engines": {
225 | "node": ">=12"
226 | }
227 | },
228 | "node_modules/@bufbuild/buf-darwin-x64": {
229 | "version": "1.36.0",
230 | "resolved": "https://registry.npmjs.org/@bufbuild/buf-darwin-x64/-/buf-darwin-x64-1.36.0.tgz",
231 | "integrity": "sha512-zKuE+awq1Bslv7WcJ5Rq2npCxAGeEFnQJ4tAMD0RjY8MZ9SjJRETmngU0xGeFdh/FM91+A8f8JehXtUX4D5/3g==",
232 | "cpu": [
233 | "x64"
234 | ],
235 | "dev": true,
236 | "optional": true,
237 | "os": [
238 | "darwin"
239 | ],
240 | "engines": {
241 | "node": ">=12"
242 | }
243 | },
244 | "node_modules/@bufbuild/buf-linux-aarch64": {
245 | "version": "1.36.0",
246 | "resolved": "https://registry.npmjs.org/@bufbuild/buf-linux-aarch64/-/buf-linux-aarch64-1.36.0.tgz",
247 | "integrity": "sha512-GaDGNezX2i2P2bpCwMwjhhoJcu0CKnFzK3c3loS7ErP9e+y3D+AubHkB+Y5MVnmzlV65GD7HcwWnygeUI1rBSg==",
248 | "cpu": [
249 | "arm64"
250 | ],
251 | "dev": true,
252 | "optional": true,
253 | "os": [
254 | "linux"
255 | ],
256 | "engines": {
257 | "node": ">=12"
258 | }
259 | },
260 | "node_modules/@bufbuild/buf-linux-x64": {
261 | "version": "1.36.0",
262 | "resolved": "https://registry.npmjs.org/@bufbuild/buf-linux-x64/-/buf-linux-x64-1.36.0.tgz",
263 | "integrity": "sha512-gF2itk9vZrEYvHX1TobPdwDxh16DGTbfN4W5X66BUDKTZmdgctWBDRrj15UfAZO9oSjEc3oMQM+HkoWkOtsCxw==",
264 | "cpu": [
265 | "x64"
266 | ],
267 | "dev": true,
268 | "optional": true,
269 | "os": [
270 | "linux"
271 | ],
272 | "engines": {
273 | "node": ">=12"
274 | }
275 | },
276 | "node_modules/@bufbuild/buf-win32-arm64": {
277 | "version": "1.36.0",
278 | "resolved": "https://registry.npmjs.org/@bufbuild/buf-win32-arm64/-/buf-win32-arm64-1.36.0.tgz",
279 | "integrity": "sha512-YQDM6hnk4gj4KNrC/rJGLeplD9Lntf2J6b9E1xIlJ7YfMLkXKt72iXT351lLUygN4MNjVhdWTP+GU+tdqMrfPQ==",
280 | "cpu": [
281 | "arm64"
282 | ],
283 | "dev": true,
284 | "optional": true,
285 | "os": [
286 | "win32"
287 | ],
288 | "engines": {
289 | "node": ">=12"
290 | }
291 | },
292 | "node_modules/@bufbuild/buf-win32-x64": {
293 | "version": "1.36.0",
294 | "resolved": "https://registry.npmjs.org/@bufbuild/buf-win32-x64/-/buf-win32-x64-1.36.0.tgz",
295 | "integrity": "sha512-qp+TuO7mHDBpJf/CtMZmIM77txcoUhGJpbjSkW+4WGpcPtwmNtQqciTYqLHXwlBVDSq9GhxpNTyx/W+kXCJS/g==",
296 | "cpu": [
297 | "x64"
298 | ],
299 | "dev": true,
300 | "optional": true,
301 | "os": [
302 | "win32"
303 | ],
304 | "engines": {
305 | "node": ">=12"
306 | }
307 | },
308 | "node_modules/@bufbuild/protobuf": {
309 | "version": "1.10.0",
310 | "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-1.10.0.tgz",
311 | "integrity": "sha512-QDdVFLoN93Zjg36NoQPZfsVH9tZew7wKDKyV5qRdj8ntT4wQCOradQjRaTdwMhWUYsgKsvCINKKm87FdEk96Ag=="
312 | },
313 | "node_modules/@codemirror/autocomplete": {
314 | "version": "6.18.0",
315 | "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.18.0.tgz",
316 | "integrity": "sha512-5DbOvBbY4qW5l57cjDsmmpDh3/TeK1vXfTHa+BUMrRzdWdcxKZ4U4V7vQaTtOpApNU4kLS4FQ6cINtLg245LXA==",
317 | "dependencies": {
318 | "@codemirror/language": "^6.0.0",
319 | "@codemirror/state": "^6.0.0",
320 | "@codemirror/view": "^6.17.0",
321 | "@lezer/common": "^1.0.0"
322 | },
323 | "peerDependencies": {
324 | "@codemirror/language": "^6.0.0",
325 | "@codemirror/state": "^6.0.0",
326 | "@codemirror/view": "^6.0.0",
327 | "@lezer/common": "^1.0.0"
328 | }
329 | },
330 | "node_modules/@codemirror/commands": {
331 | "version": "6.6.0",
332 | "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.6.0.tgz",
333 | "integrity": "sha512-qnY+b7j1UNcTS31Eenuc/5YJB6gQOzkUoNmJQc0rznwqSRpeaWWpjkWy2C/MPTcePpsKJEM26hXrOXl1+nceXg==",
334 | "dev": true,
335 | "dependencies": {
336 | "@codemirror/language": "^6.0.0",
337 | "@codemirror/state": "^6.4.0",
338 | "@codemirror/view": "^6.27.0",
339 | "@lezer/common": "^1.1.0"
340 | }
341 | },
342 | "node_modules/@codemirror/lang-javascript": {
343 | "version": "6.2.2",
344 | "resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.2.2.tgz",
345 | "integrity": "sha512-VGQfY+FCc285AhWuwjYxQyUQcYurWlxdKYT4bqwr3Twnd5wP5WSeu52t4tvvuWmljT4EmgEgZCqSieokhtY8hg==",
346 | "dev": true,
347 | "dependencies": {
348 | "@codemirror/autocomplete": "^6.0.0",
349 | "@codemirror/language": "^6.6.0",
350 | "@codemirror/lint": "^6.0.0",
351 | "@codemirror/state": "^6.0.0",
352 | "@codemirror/view": "^6.17.0",
353 | "@lezer/common": "^1.0.0",
354 | "@lezer/javascript": "^1.0.0"
355 | }
356 | },
357 | "node_modules/@codemirror/lang-python": {
358 | "version": "6.1.6",
359 | "resolved": "https://registry.npmjs.org/@codemirror/lang-python/-/lang-python-6.1.6.tgz",
360 | "integrity": "sha512-ai+01WfZhWqM92UqjnvorkxosZ2aq2u28kHvr+N3gu012XqY2CThD67JPMHnGceRfXPDBmn1HnyqowdpF57bNg==",
361 | "dev": true,
362 | "dependencies": {
363 | "@codemirror/autocomplete": "^6.3.2",
364 | "@codemirror/language": "^6.8.0",
365 | "@codemirror/state": "^6.0.0",
366 | "@lezer/common": "^1.2.1",
367 | "@lezer/python": "^1.1.4"
368 | }
369 | },
370 | "node_modules/@codemirror/language": {
371 | "version": "6.10.2",
372 | "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.10.2.tgz",
373 | "integrity": "sha512-kgbTYTo0Au6dCSc/TFy7fK3fpJmgHDv1sG1KNQKJXVi+xBTEeBPY/M30YXiU6mMXeH+YIDLsbrT4ZwNRdtF+SA==",
374 | "dependencies": {
375 | "@codemirror/state": "^6.0.0",
376 | "@codemirror/view": "^6.23.0",
377 | "@lezer/common": "^1.1.0",
378 | "@lezer/highlight": "^1.0.0",
379 | "@lezer/lr": "^1.0.0",
380 | "style-mod": "^4.0.0"
381 | }
382 | },
383 | "node_modules/@codemirror/lint": {
384 | "version": "6.8.1",
385 | "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.8.1.tgz",
386 | "integrity": "sha512-IZ0Y7S4/bpaunwggW2jYqwLuHj0QtESf5xcROewY6+lDNwZ/NzvR4t+vpYgg9m7V8UXLPYqG+lu3DF470E5Oxg==",
387 | "dev": true,
388 | "dependencies": {
389 | "@codemirror/state": "^6.0.0",
390 | "@codemirror/view": "^6.0.0",
391 | "crelt": "^1.0.5"
392 | }
393 | },
394 | "node_modules/@codemirror/search": {
395 | "version": "6.5.6",
396 | "resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.5.6.tgz",
397 | "integrity": "sha512-rpMgcsh7o0GuCDUXKPvww+muLA1pDJaFrpq/CCHtpQJYz8xopu4D1hPcKRoDD0YlF8gZaqTNIRa4VRBWyhyy7Q==",
398 | "dev": true,
399 | "dependencies": {
400 | "@codemirror/state": "^6.0.0",
401 | "@codemirror/view": "^6.0.0",
402 | "crelt": "^1.0.5"
403 | }
404 | },
405 | "node_modules/@codemirror/state": {
406 | "version": "6.4.1",
407 | "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.4.1.tgz",
408 | "integrity": "sha512-QkEyUiLhsJoZkbumGZlswmAhA7CBU02Wrz7zvH4SrcifbsqwlXShVXg65f3v/ts57W3dqyamEriMhij1Z3Zz4A=="
409 | },
410 | "node_modules/@codemirror/view": {
411 | "version": "6.30.0",
412 | "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.30.0.tgz",
413 | "integrity": "sha512-96Nmn8OeLh6aONQprIeYk8hGVnEuYpWuxKSkdsODOx9hWPxyuyZGvmvxV/JmLsp+CubMO1PsLaN5TNNgrl0UrQ==",
414 | "dependencies": {
415 | "@codemirror/state": "^6.4.0",
416 | "style-mod": "^4.1.0",
417 | "w3c-keyname": "^2.2.4"
418 | }
419 | },
420 | "node_modules/@connectrpc/connect": {
421 | "version": "1.4.0",
422 | "resolved": "https://registry.npmjs.org/@connectrpc/connect/-/connect-1.4.0.tgz",
423 | "integrity": "sha512-vZeOkKaAjyV4+RH3+rJZIfDFJAfr+7fyYr6sLDKbYX3uuTVszhFe9/YKf5DNqrDb5cKdKVlYkGn6DTDqMitAnA==",
424 | "peerDependencies": {
425 | "@bufbuild/protobuf": "^1.4.2"
426 | }
427 | },
428 | "node_modules/@connectrpc/connect-web": {
429 | "version": "1.4.0",
430 | "resolved": "https://registry.npmjs.org/@connectrpc/connect-web/-/connect-web-1.4.0.tgz",
431 | "integrity": "sha512-13aO4psFbbm7rdOFGV0De2Za64DY/acMspgloDlcOKzLPPs0yZkhp1OOzAQeiAIr7BM/VOHIA3p8mF0inxCYTA==",
432 | "peerDependencies": {
433 | "@bufbuild/protobuf": "^1.4.2",
434 | "@connectrpc/connect": "1.4.0"
435 | }
436 | },
437 | "node_modules/@esbuild/aix-ppc64": {
438 | "version": "0.21.5",
439 | "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
440 | "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
441 | "cpu": [
442 | "ppc64"
443 | ],
444 | "dev": true,
445 | "optional": true,
446 | "os": [
447 | "aix"
448 | ],
449 | "engines": {
450 | "node": ">=12"
451 | }
452 | },
453 | "node_modules/@esbuild/android-arm": {
454 | "version": "0.21.5",
455 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
456 | "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
457 | "cpu": [
458 | "arm"
459 | ],
460 | "dev": true,
461 | "optional": true,
462 | "os": [
463 | "android"
464 | ],
465 | "engines": {
466 | "node": ">=12"
467 | }
468 | },
469 | "node_modules/@esbuild/android-arm64": {
470 | "version": "0.21.5",
471 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
472 | "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
473 | "cpu": [
474 | "arm64"
475 | ],
476 | "dev": true,
477 | "optional": true,
478 | "os": [
479 | "android"
480 | ],
481 | "engines": {
482 | "node": ">=12"
483 | }
484 | },
485 | "node_modules/@esbuild/android-x64": {
486 | "version": "0.21.5",
487 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
488 | "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
489 | "cpu": [
490 | "x64"
491 | ],
492 | "dev": true,
493 | "optional": true,
494 | "os": [
495 | "android"
496 | ],
497 | "engines": {
498 | "node": ">=12"
499 | }
500 | },
501 | "node_modules/@esbuild/darwin-arm64": {
502 | "version": "0.21.5",
503 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
504 | "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
505 | "cpu": [
506 | "arm64"
507 | ],
508 | "dev": true,
509 | "optional": true,
510 | "os": [
511 | "darwin"
512 | ],
513 | "engines": {
514 | "node": ">=12"
515 | }
516 | },
517 | "node_modules/@esbuild/darwin-x64": {
518 | "version": "0.21.5",
519 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
520 | "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
521 | "cpu": [
522 | "x64"
523 | ],
524 | "dev": true,
525 | "optional": true,
526 | "os": [
527 | "darwin"
528 | ],
529 | "engines": {
530 | "node": ">=12"
531 | }
532 | },
533 | "node_modules/@esbuild/freebsd-arm64": {
534 | "version": "0.21.5",
535 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
536 | "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
537 | "cpu": [
538 | "arm64"
539 | ],
540 | "dev": true,
541 | "optional": true,
542 | "os": [
543 | "freebsd"
544 | ],
545 | "engines": {
546 | "node": ">=12"
547 | }
548 | },
549 | "node_modules/@esbuild/freebsd-x64": {
550 | "version": "0.21.5",
551 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
552 | "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
553 | "cpu": [
554 | "x64"
555 | ],
556 | "dev": true,
557 | "optional": true,
558 | "os": [
559 | "freebsd"
560 | ],
561 | "engines": {
562 | "node": ">=12"
563 | }
564 | },
565 | "node_modules/@esbuild/linux-arm": {
566 | "version": "0.21.5",
567 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
568 | "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
569 | "cpu": [
570 | "arm"
571 | ],
572 | "dev": true,
573 | "optional": true,
574 | "os": [
575 | "linux"
576 | ],
577 | "engines": {
578 | "node": ">=12"
579 | }
580 | },
581 | "node_modules/@esbuild/linux-arm64": {
582 | "version": "0.21.5",
583 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
584 | "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
585 | "cpu": [
586 | "arm64"
587 | ],
588 | "dev": true,
589 | "optional": true,
590 | "os": [
591 | "linux"
592 | ],
593 | "engines": {
594 | "node": ">=12"
595 | }
596 | },
597 | "node_modules/@esbuild/linux-ia32": {
598 | "version": "0.21.5",
599 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
600 | "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
601 | "cpu": [
602 | "ia32"
603 | ],
604 | "dev": true,
605 | "optional": true,
606 | "os": [
607 | "linux"
608 | ],
609 | "engines": {
610 | "node": ">=12"
611 | }
612 | },
613 | "node_modules/@esbuild/linux-loong64": {
614 | "version": "0.21.5",
615 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
616 | "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
617 | "cpu": [
618 | "loong64"
619 | ],
620 | "dev": true,
621 | "optional": true,
622 | "os": [
623 | "linux"
624 | ],
625 | "engines": {
626 | "node": ">=12"
627 | }
628 | },
629 | "node_modules/@esbuild/linux-mips64el": {
630 | "version": "0.21.5",
631 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
632 | "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
633 | "cpu": [
634 | "mips64el"
635 | ],
636 | "dev": true,
637 | "optional": true,
638 | "os": [
639 | "linux"
640 | ],
641 | "engines": {
642 | "node": ">=12"
643 | }
644 | },
645 | "node_modules/@esbuild/linux-ppc64": {
646 | "version": "0.21.5",
647 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
648 | "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
649 | "cpu": [
650 | "ppc64"
651 | ],
652 | "dev": true,
653 | "optional": true,
654 | "os": [
655 | "linux"
656 | ],
657 | "engines": {
658 | "node": ">=12"
659 | }
660 | },
661 | "node_modules/@esbuild/linux-riscv64": {
662 | "version": "0.21.5",
663 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
664 | "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
665 | "cpu": [
666 | "riscv64"
667 | ],
668 | "dev": true,
669 | "optional": true,
670 | "os": [
671 | "linux"
672 | ],
673 | "engines": {
674 | "node": ">=12"
675 | }
676 | },
677 | "node_modules/@esbuild/linux-s390x": {
678 | "version": "0.21.5",
679 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
680 | "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
681 | "cpu": [
682 | "s390x"
683 | ],
684 | "dev": true,
685 | "optional": true,
686 | "os": [
687 | "linux"
688 | ],
689 | "engines": {
690 | "node": ">=12"
691 | }
692 | },
693 | "node_modules/@esbuild/linux-x64": {
694 | "version": "0.21.5",
695 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
696 | "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
697 | "cpu": [
698 | "x64"
699 | ],
700 | "dev": true,
701 | "optional": true,
702 | "os": [
703 | "linux"
704 | ],
705 | "engines": {
706 | "node": ">=12"
707 | }
708 | },
709 | "node_modules/@esbuild/netbsd-x64": {
710 | "version": "0.21.5",
711 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
712 | "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
713 | "cpu": [
714 | "x64"
715 | ],
716 | "dev": true,
717 | "optional": true,
718 | "os": [
719 | "netbsd"
720 | ],
721 | "engines": {
722 | "node": ">=12"
723 | }
724 | },
725 | "node_modules/@esbuild/openbsd-x64": {
726 | "version": "0.21.5",
727 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
728 | "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
729 | "cpu": [
730 | "x64"
731 | ],
732 | "dev": true,
733 | "optional": true,
734 | "os": [
735 | "openbsd"
736 | ],
737 | "engines": {
738 | "node": ">=12"
739 | }
740 | },
741 | "node_modules/@esbuild/sunos-x64": {
742 | "version": "0.21.5",
743 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
744 | "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
745 | "cpu": [
746 | "x64"
747 | ],
748 | "dev": true,
749 | "optional": true,
750 | "os": [
751 | "sunos"
752 | ],
753 | "engines": {
754 | "node": ">=12"
755 | }
756 | },
757 | "node_modules/@esbuild/win32-arm64": {
758 | "version": "0.21.5",
759 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
760 | "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
761 | "cpu": [
762 | "arm64"
763 | ],
764 | "dev": true,
765 | "optional": true,
766 | "os": [
767 | "win32"
768 | ],
769 | "engines": {
770 | "node": ">=12"
771 | }
772 | },
773 | "node_modules/@esbuild/win32-ia32": {
774 | "version": "0.21.5",
775 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
776 | "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
777 | "cpu": [
778 | "ia32"
779 | ],
780 | "dev": true,
781 | "optional": true,
782 | "os": [
783 | "win32"
784 | ],
785 | "engines": {
786 | "node": ">=12"
787 | }
788 | },
789 | "node_modules/@esbuild/win32-x64": {
790 | "version": "0.21.5",
791 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
792 | "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
793 | "cpu": [
794 | "x64"
795 | ],
796 | "dev": true,
797 | "optional": true,
798 | "os": [
799 | "win32"
800 | ],
801 | "engines": {
802 | "node": ">=12"
803 | }
804 | },
805 | "node_modules/@lezer/common": {
806 | "version": "1.2.1",
807 | "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.1.tgz",
808 | "integrity": "sha512-yemX0ZD2xS/73llMZIK6KplkjIjf2EvAHcinDi/TfJ9hS25G0388+ClHt6/3but0oOxinTcQHJLDXh6w1crzFQ=="
809 | },
810 | "node_modules/@lezer/highlight": {
811 | "version": "1.2.0",
812 | "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.0.tgz",
813 | "integrity": "sha512-WrS5Mw51sGrpqjlh3d4/fOwpEV2Hd3YOkp9DBt4k8XZQcoTHZFB7sx030A6OcahF4J1nDQAa3jXlTVVYH50IFA==",
814 | "dependencies": {
815 | "@lezer/common": "^1.0.0"
816 | }
817 | },
818 | "node_modules/@lezer/javascript": {
819 | "version": "1.4.17",
820 | "resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.4.17.tgz",
821 | "integrity": "sha512-bYW4ctpyGK+JMumDApeUzuIezX01H76R1foD6LcRX224FWfyYit/HYxiPGDjXXe/wQWASjCvVGoukTH68+0HIA==",
822 | "dev": true,
823 | "dependencies": {
824 | "@lezer/common": "^1.2.0",
825 | "@lezer/highlight": "^1.1.3",
826 | "@lezer/lr": "^1.3.0"
827 | }
828 | },
829 | "node_modules/@lezer/lr": {
830 | "version": "1.4.2",
831 | "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.2.tgz",
832 | "integrity": "sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==",
833 | "dependencies": {
834 | "@lezer/common": "^1.0.0"
835 | }
836 | },
837 | "node_modules/@lezer/python": {
838 | "version": "1.1.14",
839 | "resolved": "https://registry.npmjs.org/@lezer/python/-/python-1.1.14.tgz",
840 | "integrity": "sha512-ykDOb2Ti24n76PJsSa4ZoDF0zH12BSw1LGfQXCYJhJyOGiFTfGaX0Du66Ze72R+u/P35U+O6I9m8TFXov1JzsA==",
841 | "dev": true,
842 | "dependencies": {
843 | "@lezer/common": "^1.2.0",
844 | "@lezer/highlight": "^1.0.0",
845 | "@lezer/lr": "^1.0.0"
846 | }
847 | },
848 | "node_modules/@rollup/rollup-android-arm-eabi": {
849 | "version": "4.20.0",
850 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.20.0.tgz",
851 | "integrity": "sha512-TSpWzflCc4VGAUJZlPpgAJE1+V60MePDQnBd7PPkpuEmOy8i87aL6tinFGKBFKuEDikYpig72QzdT3QPYIi+oA==",
852 | "cpu": [
853 | "arm"
854 | ],
855 | "dev": true,
856 | "optional": true,
857 | "os": [
858 | "android"
859 | ]
860 | },
861 | "node_modules/@rollup/rollup-android-arm64": {
862 | "version": "4.20.0",
863 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.20.0.tgz",
864 | "integrity": "sha512-u00Ro/nok7oGzVuh/FMYfNoGqxU5CPWz1mxV85S2w9LxHR8OoMQBuSk+3BKVIDYgkpeOET5yXkx90OYFc+ytpQ==",
865 | "cpu": [
866 | "arm64"
867 | ],
868 | "dev": true,
869 | "optional": true,
870 | "os": [
871 | "android"
872 | ]
873 | },
874 | "node_modules/@rollup/rollup-darwin-arm64": {
875 | "version": "4.20.0",
876 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.20.0.tgz",
877 | "integrity": "sha512-uFVfvzvsdGtlSLuL0ZlvPJvl6ZmrH4CBwLGEFPe7hUmf7htGAN+aXo43R/V6LATyxlKVC/m6UsLb7jbG+LG39Q==",
878 | "cpu": [
879 | "arm64"
880 | ],
881 | "dev": true,
882 | "optional": true,
883 | "os": [
884 | "darwin"
885 | ]
886 | },
887 | "node_modules/@rollup/rollup-darwin-x64": {
888 | "version": "4.20.0",
889 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.20.0.tgz",
890 | "integrity": "sha512-xbrMDdlev53vNXexEa6l0LffojxhqDTBeL+VUxuuIXys4x6xyvbKq5XqTXBCEUA8ty8iEJblHvFaWRJTk/icAQ==",
891 | "cpu": [
892 | "x64"
893 | ],
894 | "dev": true,
895 | "optional": true,
896 | "os": [
897 | "darwin"
898 | ]
899 | },
900 | "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
901 | "version": "4.20.0",
902 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.20.0.tgz",
903 | "integrity": "sha512-jMYvxZwGmoHFBTbr12Xc6wOdc2xA5tF5F2q6t7Rcfab68TT0n+r7dgawD4qhPEvasDsVpQi+MgDzj2faOLsZjA==",
904 | "cpu": [
905 | "arm"
906 | ],
907 | "dev": true,
908 | "optional": true,
909 | "os": [
910 | "linux"
911 | ]
912 | },
913 | "node_modules/@rollup/rollup-linux-arm-musleabihf": {
914 | "version": "4.20.0",
915 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.20.0.tgz",
916 | "integrity": "sha512-1asSTl4HKuIHIB1GcdFHNNZhxAYEdqML/MW4QmPS4G0ivbEcBr1JKlFLKsIRqjSwOBkdItn3/ZDlyvZ/N6KPlw==",
917 | "cpu": [
918 | "arm"
919 | ],
920 | "dev": true,
921 | "optional": true,
922 | "os": [
923 | "linux"
924 | ]
925 | },
926 | "node_modules/@rollup/rollup-linux-arm64-gnu": {
927 | "version": "4.20.0",
928 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.20.0.tgz",
929 | "integrity": "sha512-COBb8Bkx56KldOYJfMf6wKeYJrtJ9vEgBRAOkfw6Ens0tnmzPqvlpjZiLgkhg6cA3DGzCmLmmd319pmHvKWWlQ==",
930 | "cpu": [
931 | "arm64"
932 | ],
933 | "dev": true,
934 | "optional": true,
935 | "os": [
936 | "linux"
937 | ]
938 | },
939 | "node_modules/@rollup/rollup-linux-arm64-musl": {
940 | "version": "4.20.0",
941 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.20.0.tgz",
942 | "integrity": "sha512-+it+mBSyMslVQa8wSPvBx53fYuZK/oLTu5RJoXogjk6x7Q7sz1GNRsXWjn6SwyJm8E/oMjNVwPhmNdIjwP135Q==",
943 | "cpu": [
944 | "arm64"
945 | ],
946 | "dev": true,
947 | "optional": true,
948 | "os": [
949 | "linux"
950 | ]
951 | },
952 | "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
953 | "version": "4.20.0",
954 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.20.0.tgz",
955 | "integrity": "sha512-yAMvqhPfGKsAxHN8I4+jE0CpLWD8cv4z7CK7BMmhjDuz606Q2tFKkWRY8bHR9JQXYcoLfopo5TTqzxgPUjUMfw==",
956 | "cpu": [
957 | "ppc64"
958 | ],
959 | "dev": true,
960 | "optional": true,
961 | "os": [
962 | "linux"
963 | ]
964 | },
965 | "node_modules/@rollup/rollup-linux-riscv64-gnu": {
966 | "version": "4.20.0",
967 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.20.0.tgz",
968 | "integrity": "sha512-qmuxFpfmi/2SUkAw95TtNq/w/I7Gpjurx609OOOV7U4vhvUhBcftcmXwl3rqAek+ADBwSjIC4IVNLiszoj3dPA==",
969 | "cpu": [
970 | "riscv64"
971 | ],
972 | "dev": true,
973 | "optional": true,
974 | "os": [
975 | "linux"
976 | ]
977 | },
978 | "node_modules/@rollup/rollup-linux-s390x-gnu": {
979 | "version": "4.20.0",
980 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.20.0.tgz",
981 | "integrity": "sha512-I0BtGXddHSHjV1mqTNkgUZLnS3WtsqebAXv11D5BZE/gfw5KoyXSAXVqyJximQXNvNzUo4GKlCK/dIwXlz+jlg==",
982 | "cpu": [
983 | "s390x"
984 | ],
985 | "dev": true,
986 | "optional": true,
987 | "os": [
988 | "linux"
989 | ]
990 | },
991 | "node_modules/@rollup/rollup-linux-x64-gnu": {
992 | "version": "4.20.0",
993 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.20.0.tgz",
994 | "integrity": "sha512-y+eoL2I3iphUg9tN9GB6ku1FA8kOfmF4oUEWhztDJ4KXJy1agk/9+pejOuZkNFhRwHAOxMsBPLbXPd6mJiCwew==",
995 | "cpu": [
996 | "x64"
997 | ],
998 | "dev": true,
999 | "optional": true,
1000 | "os": [
1001 | "linux"
1002 | ]
1003 | },
1004 | "node_modules/@rollup/rollup-linux-x64-musl": {
1005 | "version": "4.20.0",
1006 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.20.0.tgz",
1007 | "integrity": "sha512-hM3nhW40kBNYUkZb/r9k2FKK+/MnKglX7UYd4ZUy5DJs8/sMsIbqWK2piZtVGE3kcXVNj3B2IrUYROJMMCikNg==",
1008 | "cpu": [
1009 | "x64"
1010 | ],
1011 | "dev": true,
1012 | "optional": true,
1013 | "os": [
1014 | "linux"
1015 | ]
1016 | },
1017 | "node_modules/@rollup/rollup-win32-arm64-msvc": {
1018 | "version": "4.20.0",
1019 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.20.0.tgz",
1020 | "integrity": "sha512-psegMvP+Ik/Bg7QRJbv8w8PAytPA7Uo8fpFjXyCRHWm6Nt42L+JtoqH8eDQ5hRP7/XW2UiIriy1Z46jf0Oa1kA==",
1021 | "cpu": [
1022 | "arm64"
1023 | ],
1024 | "dev": true,
1025 | "optional": true,
1026 | "os": [
1027 | "win32"
1028 | ]
1029 | },
1030 | "node_modules/@rollup/rollup-win32-ia32-msvc": {
1031 | "version": "4.20.0",
1032 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.20.0.tgz",
1033 | "integrity": "sha512-GabekH3w4lgAJpVxkk7hUzUf2hICSQO0a/BLFA11/RMxQT92MabKAqyubzDZmMOC/hcJNlc+rrypzNzYl4Dx7A==",
1034 | "cpu": [
1035 | "ia32"
1036 | ],
1037 | "dev": true,
1038 | "optional": true,
1039 | "os": [
1040 | "win32"
1041 | ]
1042 | },
1043 | "node_modules/@rollup/rollup-win32-x64-msvc": {
1044 | "version": "4.20.0",
1045 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.20.0.tgz",
1046 | "integrity": "sha512-aJ1EJSuTdGnM6qbVC4B5DSmozPTqIag9fSzXRNNo+humQLG89XpPgdt16Ia56ORD7s+H8Pmyx44uczDQ0yDzpg==",
1047 | "cpu": [
1048 | "x64"
1049 | ],
1050 | "dev": true,
1051 | "optional": true,
1052 | "os": [
1053 | "win32"
1054 | ]
1055 | },
1056 | "node_modules/@types/estree": {
1057 | "version": "1.0.5",
1058 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
1059 | "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
1060 | "dev": true
1061 | },
1062 | "node_modules/codemirror": {
1063 | "version": "6.0.1",
1064 | "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.1.tgz",
1065 | "integrity": "sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==",
1066 | "dev": true,
1067 | "dependencies": {
1068 | "@codemirror/autocomplete": "^6.0.0",
1069 | "@codemirror/commands": "^6.0.0",
1070 | "@codemirror/language": "^6.0.0",
1071 | "@codemirror/lint": "^6.0.0",
1072 | "@codemirror/search": "^6.0.0",
1073 | "@codemirror/state": "^6.0.0",
1074 | "@codemirror/view": "^6.0.0"
1075 | }
1076 | },
1077 | "node_modules/crelt": {
1078 | "version": "1.0.6",
1079 | "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz",
1080 | "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==",
1081 | "dev": true
1082 | },
1083 | "node_modules/esbuild": {
1084 | "version": "0.21.5",
1085 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
1086 | "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
1087 | "dev": true,
1088 | "hasInstallScript": true,
1089 | "bin": {
1090 | "esbuild": "bin/esbuild"
1091 | },
1092 | "engines": {
1093 | "node": ">=12"
1094 | },
1095 | "optionalDependencies": {
1096 | "@esbuild/aix-ppc64": "0.21.5",
1097 | "@esbuild/android-arm": "0.21.5",
1098 | "@esbuild/android-arm64": "0.21.5",
1099 | "@esbuild/android-x64": "0.21.5",
1100 | "@esbuild/darwin-arm64": "0.21.5",
1101 | "@esbuild/darwin-x64": "0.21.5",
1102 | "@esbuild/freebsd-arm64": "0.21.5",
1103 | "@esbuild/freebsd-x64": "0.21.5",
1104 | "@esbuild/linux-arm": "0.21.5",
1105 | "@esbuild/linux-arm64": "0.21.5",
1106 | "@esbuild/linux-ia32": "0.21.5",
1107 | "@esbuild/linux-loong64": "0.21.5",
1108 | "@esbuild/linux-mips64el": "0.21.5",
1109 | "@esbuild/linux-ppc64": "0.21.5",
1110 | "@esbuild/linux-riscv64": "0.21.5",
1111 | "@esbuild/linux-s390x": "0.21.5",
1112 | "@esbuild/linux-x64": "0.21.5",
1113 | "@esbuild/netbsd-x64": "0.21.5",
1114 | "@esbuild/openbsd-x64": "0.21.5",
1115 | "@esbuild/sunos-x64": "0.21.5",
1116 | "@esbuild/win32-arm64": "0.21.5",
1117 | "@esbuild/win32-ia32": "0.21.5",
1118 | "@esbuild/win32-x64": "0.21.5"
1119 | }
1120 | },
1121 | "node_modules/fsevents": {
1122 | "version": "2.3.3",
1123 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
1124 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
1125 | "dev": true,
1126 | "hasInstallScript": true,
1127 | "optional": true,
1128 | "os": [
1129 | "darwin"
1130 | ],
1131 | "engines": {
1132 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
1133 | }
1134 | },
1135 | "node_modules/nanoid": {
1136 | "version": "3.3.7",
1137 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
1138 | "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
1139 | "dev": true,
1140 | "funding": [
1141 | {
1142 | "type": "github",
1143 | "url": "https://github.com/sponsors/ai"
1144 | }
1145 | ],
1146 | "bin": {
1147 | "nanoid": "bin/nanoid.cjs"
1148 | },
1149 | "engines": {
1150 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
1151 | }
1152 | },
1153 | "node_modules/picocolors": {
1154 | "version": "1.0.1",
1155 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
1156 | "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==",
1157 | "dev": true
1158 | },
1159 | "node_modules/postcss": {
1160 | "version": "8.4.41",
1161 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz",
1162 | "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==",
1163 | "dev": true,
1164 | "funding": [
1165 | {
1166 | "type": "opencollective",
1167 | "url": "https://opencollective.com/postcss/"
1168 | },
1169 | {
1170 | "type": "tidelift",
1171 | "url": "https://tidelift.com/funding/github/npm/postcss"
1172 | },
1173 | {
1174 | "type": "github",
1175 | "url": "https://github.com/sponsors/ai"
1176 | }
1177 | ],
1178 | "dependencies": {
1179 | "nanoid": "^3.3.7",
1180 | "picocolors": "^1.0.1",
1181 | "source-map-js": "^1.2.0"
1182 | },
1183 | "engines": {
1184 | "node": "^10 || ^12 || >=14"
1185 | }
1186 | },
1187 | "node_modules/rollup": {
1188 | "version": "4.20.0",
1189 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.20.0.tgz",
1190 | "integrity": "sha512-6rbWBChcnSGzIlXeIdNIZTopKYad8ZG8ajhl78lGRLsI2rX8IkaotQhVas2Ma+GPxJav19wrSzvRvuiv0YKzWw==",
1191 | "dev": true,
1192 | "dependencies": {
1193 | "@types/estree": "1.0.5"
1194 | },
1195 | "bin": {
1196 | "rollup": "dist/bin/rollup"
1197 | },
1198 | "engines": {
1199 | "node": ">=18.0.0",
1200 | "npm": ">=8.0.0"
1201 | },
1202 | "optionalDependencies": {
1203 | "@rollup/rollup-android-arm-eabi": "4.20.0",
1204 | "@rollup/rollup-android-arm64": "4.20.0",
1205 | "@rollup/rollup-darwin-arm64": "4.20.0",
1206 | "@rollup/rollup-darwin-x64": "4.20.0",
1207 | "@rollup/rollup-linux-arm-gnueabihf": "4.20.0",
1208 | "@rollup/rollup-linux-arm-musleabihf": "4.20.0",
1209 | "@rollup/rollup-linux-arm64-gnu": "4.20.0",
1210 | "@rollup/rollup-linux-arm64-musl": "4.20.0",
1211 | "@rollup/rollup-linux-powerpc64le-gnu": "4.20.0",
1212 | "@rollup/rollup-linux-riscv64-gnu": "4.20.0",
1213 | "@rollup/rollup-linux-s390x-gnu": "4.20.0",
1214 | "@rollup/rollup-linux-x64-gnu": "4.20.0",
1215 | "@rollup/rollup-linux-x64-musl": "4.20.0",
1216 | "@rollup/rollup-win32-arm64-msvc": "4.20.0",
1217 | "@rollup/rollup-win32-ia32-msvc": "4.20.0",
1218 | "@rollup/rollup-win32-x64-msvc": "4.20.0",
1219 | "fsevents": "~2.3.2"
1220 | }
1221 | },
1222 | "node_modules/source-map-js": {
1223 | "version": "1.2.0",
1224 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
1225 | "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
1226 | "dev": true,
1227 | "engines": {
1228 | "node": ">=0.10.0"
1229 | }
1230 | },
1231 | "node_modules/style-mod": {
1232 | "version": "4.1.2",
1233 | "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz",
1234 | "integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw=="
1235 | },
1236 | "node_modules/typescript": {
1237 | "version": "5.5.4",
1238 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz",
1239 | "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==",
1240 | "dev": true,
1241 | "bin": {
1242 | "tsc": "bin/tsc",
1243 | "tsserver": "bin/tsserver"
1244 | },
1245 | "engines": {
1246 | "node": ">=14.17"
1247 | }
1248 | },
1249 | "node_modules/vite": {
1250 | "version": "5.3.5",
1251 | "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.5.tgz",
1252 | "integrity": "sha512-MdjglKR6AQXQb9JGiS7Rc2wC6uMjcm7Go/NHNO63EwiJXfuk9PgqiP/n5IDJCziMkfw9n4Ubp7lttNwz+8ZVKA==",
1253 | "dev": true,
1254 | "dependencies": {
1255 | "esbuild": "^0.21.3",
1256 | "postcss": "^8.4.39",
1257 | "rollup": "^4.13.0"
1258 | },
1259 | "bin": {
1260 | "vite": "bin/vite.js"
1261 | },
1262 | "engines": {
1263 | "node": "^18.0.0 || >=20.0.0"
1264 | },
1265 | "funding": {
1266 | "url": "https://github.com/vitejs/vite?sponsor=1"
1267 | },
1268 | "optionalDependencies": {
1269 | "fsevents": "~2.3.3"
1270 | },
1271 | "peerDependencies": {
1272 | "@types/node": "^18.0.0 || >=20.0.0",
1273 | "less": "*",
1274 | "lightningcss": "^1.21.0",
1275 | "sass": "*",
1276 | "stylus": "*",
1277 | "sugarss": "*",
1278 | "terser": "^5.4.0"
1279 | },
1280 | "peerDependenciesMeta": {
1281 | "@types/node": {
1282 | "optional": true
1283 | },
1284 | "less": {
1285 | "optional": true
1286 | },
1287 | "lightningcss": {
1288 | "optional": true
1289 | },
1290 | "sass": {
1291 | "optional": true
1292 | },
1293 | "stylus": {
1294 | "optional": true
1295 | },
1296 | "sugarss": {
1297 | "optional": true
1298 | },
1299 | "terser": {
1300 | "optional": true
1301 | }
1302 | }
1303 | },
1304 | "node_modules/w3c-keyname": {
1305 | "version": "2.2.8",
1306 | "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
1307 | "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ=="
1308 | }
1309 | }
1310 | }
1311 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@valtown/codemirror-codeium",
3 | "version": "1.1.1",
4 | "description": "codemirror integration for codeium",
5 | "scripts": {
6 | "dev": "vite",
7 | "generate": "buf generate",
8 | "tsc": "tsc --noEmit",
9 | "test": "biome lint",
10 | "test:watch": "vitest",
11 | "pages": "vite build",
12 | "build": "tsc --build",
13 | "prepare": "npm run build"
14 | },
15 | "main": "./dist/plugin.js",
16 | "types": "./dist/plugin.d.ts",
17 | "keywords": [
18 | "codemirror",
19 | "typescript",
20 | "ts"
21 | ],
22 | "author": "Val Town",
23 | "license": "ISC",
24 | "peerDependencies": {
25 | "@codemirror/autocomplete": "^6",
26 | "@codemirror/state": "^6",
27 | "@codemirror/view": "^6"
28 | },
29 | "devDependencies": {
30 | "@biomejs/biome": "^1.8.1",
31 | "@bufbuild/buf": "^1.36.0",
32 | "@codemirror/lang-javascript": "^6.2.2",
33 | "@codemirror/lang-python": "^6.1.5",
34 | "codemirror": "^6",
35 | "typescript": "^5.4.3",
36 | "vite": "^5.2.7"
37 | },
38 | "files": [
39 | "dist"
40 | ],
41 | "type": "module",
42 | "engines": {
43 | "node": "*"
44 | },
45 | "dependencies": {
46 | "@bufbuild/protobuf": "^1.10.0",
47 | "@connectrpc/connect": "^1.4.0",
48 | "@connectrpc/connect-web": "^1.4.0"
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/annotations.ts:
--------------------------------------------------------------------------------
1 | import { Annotation } from "@codemirror/state";
2 |
3 | export const copilotEvent = Annotation.define();
4 |
5 | /**
6 | * Annotation that signals to upstream integrations
7 | * that this transaction should not be included
8 | * in history or treated otherwise as a user edit.
9 | */
10 | export const copilotIgnore = Annotation.define();
11 |
--------------------------------------------------------------------------------
/src/api/proto/exa/codeium_common_pb/codeium_common_pb.ts:
--------------------------------------------------------------------------------
1 | // Copyright Exafunction, Inc.
2 |
3 | // @generated by protoc-gen-es v1.4.2 with parameter "target=ts"
4 | // @generated from file exa/codeium_common_pb/codeium_common.proto (package exa.codeium_common_pb, syntax proto3)
5 | /* eslint-disable */
6 | // @ts-nocheck
7 |
8 | import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf";
9 | import { Message, proto3, protoInt64 } from "@bufbuild/protobuf";
10 |
11 | /**
12 | * @generated from enum exa.codeium_common_pb.ExperimentKey
13 | */
14 | export enum ExperimentKey {
15 | /**
16 | * @generated from enum value: UNSPECIFIED = 0;
17 | */
18 | UNSPECIFIED = 0,
19 |
20 | /**
21 | * @generated from enum value: JUPYTER_FORMAT = 77;
22 | */
23 | JUPYTER_FORMAT = 77,
24 | }
25 | // Retrieve enum metadata with: proto3.getEnumType(ExperimentKey)
26 | proto3.util.setEnumType(ExperimentKey, "exa.codeium_common_pb.ExperimentKey", [
27 | { no: 0, name: "UNSPECIFIED" },
28 | { no: 77, name: "JUPYTER_FORMAT" },
29 | ]);
30 |
31 | /**
32 | * Authentication source for users on the cloud service.
33 | *
34 | * @generated from enum exa.codeium_common_pb.AuthSource
35 | */
36 | export enum AuthSource {
37 | /**
38 | * @generated from enum value: AUTH_SOURCE_CODEIUM = 0;
39 | */
40 | CODEIUM = 0,
41 | }
42 | // Retrieve enum metadata with: proto3.getEnumType(AuthSource)
43 | proto3.util.setEnumType(AuthSource, "exa.codeium_common_pb.AuthSource", [
44 | { no: 0, name: "AUTH_SOURCE_CODEIUM" },
45 | ]);
46 |
47 | /**
48 | * @generated from enum exa.codeium_common_pb.EventType
49 | */
50 | export enum EventType {
51 | /**
52 | * @generated from enum value: EVENT_TYPE_UNSPECIFIED = 0;
53 | */
54 | UNSPECIFIED = 0,
55 |
56 | /**
57 | * @generated from enum value: EVENT_TYPE_ENABLE_CODEIUM = 1;
58 | */
59 | ENABLE_CODEIUM = 1,
60 |
61 | /**
62 | * @generated from enum value: EVENT_TYPE_DISABLE_CODEIUM = 2;
63 | */
64 | DISABLE_CODEIUM = 2,
65 |
66 | /**
67 | * @generated from enum value: EVENT_TYPE_SHOW_PREVIOUS_COMPLETION = 3;
68 | */
69 | SHOW_PREVIOUS_COMPLETION = 3,
70 |
71 | /**
72 | * @generated from enum value: EVENT_TYPE_SHOW_NEXT_COMPLETION = 4;
73 | */
74 | SHOW_NEXT_COMPLETION = 4,
75 | }
76 | // Retrieve enum metadata with: proto3.getEnumType(EventType)
77 | proto3.util.setEnumType(EventType, "exa.codeium_common_pb.EventType", [
78 | { no: 0, name: "EVENT_TYPE_UNSPECIFIED" },
79 | { no: 1, name: "EVENT_TYPE_ENABLE_CODEIUM" },
80 | { no: 2, name: "EVENT_TYPE_DISABLE_CODEIUM" },
81 | { no: 3, name: "EVENT_TYPE_SHOW_PREVIOUS_COMPLETION" },
82 | { no: 4, name: "EVENT_TYPE_SHOW_NEXT_COMPLETION" },
83 | ]);
84 |
85 | /**
86 | * @generated from enum exa.codeium_common_pb.CompletionSource
87 | */
88 | export enum CompletionSource {
89 | /**
90 | * @generated from enum value: COMPLETION_SOURCE_UNSPECIFIED = 0;
91 | */
92 | UNSPECIFIED = 0,
93 |
94 | /**
95 | * @generated from enum value: COMPLETION_SOURCE_TYPING_AS_SUGGESTED = 1;
96 | */
97 | TYPING_AS_SUGGESTED = 1,
98 |
99 | /**
100 | * @generated from enum value: COMPLETION_SOURCE_CACHE = 2;
101 | */
102 | CACHE = 2,
103 |
104 | /**
105 | * @generated from enum value: COMPLETION_SOURCE_NETWORK = 3;
106 | */
107 | NETWORK = 3,
108 | }
109 | // Retrieve enum metadata with: proto3.getEnumType(CompletionSource)
110 | proto3.util.setEnumType(CompletionSource, "exa.codeium_common_pb.CompletionSource", [
111 | { no: 0, name: "COMPLETION_SOURCE_UNSPECIFIED" },
112 | { no: 1, name: "COMPLETION_SOURCE_TYPING_AS_SUGGESTED" },
113 | { no: 2, name: "COMPLETION_SOURCE_CACHE" },
114 | { no: 3, name: "COMPLETION_SOURCE_NETWORK" },
115 | ]);
116 |
117 | /**
118 | * Every time this list is updated, we should be redeploying the API server
119 | * since it uses the string representation for BQ.
120 | *
121 | * @generated from enum exa.codeium_common_pb.Language
122 | */
123 | export enum Language {
124 | /**
125 | * @generated from enum value: LANGUAGE_UNSPECIFIED = 0;
126 | */
127 | UNSPECIFIED = 0,
128 |
129 | /**
130 | * @generated from enum value: LANGUAGE_C = 1;
131 | */
132 | C = 1,
133 |
134 | /**
135 | * @generated from enum value: LANGUAGE_CLOJURE = 2;
136 | */
137 | CLOJURE = 2,
138 |
139 | /**
140 | * @generated from enum value: LANGUAGE_COFFEESCRIPT = 3;
141 | */
142 | COFFEESCRIPT = 3,
143 |
144 | /**
145 | * @generated from enum value: LANGUAGE_CPP = 4;
146 | */
147 | CPP = 4,
148 |
149 | /**
150 | * @generated from enum value: LANGUAGE_CSHARP = 5;
151 | */
152 | CSHARP = 5,
153 |
154 | /**
155 | * @generated from enum value: LANGUAGE_CSS = 6;
156 | */
157 | CSS = 6,
158 |
159 | /**
160 | * @generated from enum value: LANGUAGE_CUDACPP = 7;
161 | */
162 | CUDACPP = 7,
163 |
164 | /**
165 | * @generated from enum value: LANGUAGE_DOCKERFILE = 8;
166 | */
167 | DOCKERFILE = 8,
168 |
169 | /**
170 | * @generated from enum value: LANGUAGE_GO = 9;
171 | */
172 | GO = 9,
173 |
174 | /**
175 | * @generated from enum value: LANGUAGE_GROOVY = 10;
176 | */
177 | GROOVY = 10,
178 |
179 | /**
180 | * @generated from enum value: LANGUAGE_HANDLEBARS = 11;
181 | */
182 | HANDLEBARS = 11,
183 |
184 | /**
185 | * @generated from enum value: LANGUAGE_HASKELL = 12;
186 | */
187 | HASKELL = 12,
188 |
189 | /**
190 | * @generated from enum value: LANGUAGE_HCL = 13;
191 | */
192 | HCL = 13,
193 |
194 | /**
195 | * @generated from enum value: LANGUAGE_HTML = 14;
196 | */
197 | HTML = 14,
198 |
199 | /**
200 | * @generated from enum value: LANGUAGE_INI = 15;
201 | */
202 | INI = 15,
203 |
204 | /**
205 | * @generated from enum value: LANGUAGE_JAVA = 16;
206 | */
207 | JAVA = 16,
208 |
209 | /**
210 | * @generated from enum value: LANGUAGE_JAVASCRIPT = 17;
211 | */
212 | JAVASCRIPT = 17,
213 |
214 | /**
215 | * @generated from enum value: LANGUAGE_JSON = 18;
216 | */
217 | JSON = 18,
218 |
219 | /**
220 | * @generated from enum value: LANGUAGE_JULIA = 19;
221 | */
222 | JULIA = 19,
223 |
224 | /**
225 | * @generated from enum value: LANGUAGE_KOTLIN = 20;
226 | */
227 | KOTLIN = 20,
228 |
229 | /**
230 | * @generated from enum value: LANGUAGE_LATEX = 21;
231 | */
232 | LATEX = 21,
233 |
234 | /**
235 | * @generated from enum value: LANGUAGE_LESS = 22;
236 | */
237 | LESS = 22,
238 |
239 | /**
240 | * @generated from enum value: LANGUAGE_LUA = 23;
241 | */
242 | LUA = 23,
243 |
244 | /**
245 | * @generated from enum value: LANGUAGE_MAKEFILE = 24;
246 | */
247 | MAKEFILE = 24,
248 |
249 | /**
250 | * @generated from enum value: LANGUAGE_MARKDOWN = 25;
251 | */
252 | MARKDOWN = 25,
253 |
254 | /**
255 | * @generated from enum value: LANGUAGE_OBJECTIVEC = 26;
256 | */
257 | OBJECTIVEC = 26,
258 |
259 | /**
260 | * @generated from enum value: LANGUAGE_OBJECTIVECPP = 27;
261 | */
262 | OBJECTIVECPP = 27,
263 |
264 | /**
265 | * @generated from enum value: LANGUAGE_PERL = 28;
266 | */
267 | PERL = 28,
268 |
269 | /**
270 | * @generated from enum value: LANGUAGE_PHP = 29;
271 | */
272 | PHP = 29,
273 |
274 | /**
275 | * @generated from enum value: LANGUAGE_PLAINTEXT = 30;
276 | */
277 | PLAINTEXT = 30,
278 |
279 | /**
280 | * @generated from enum value: LANGUAGE_PROTOBUF = 31;
281 | */
282 | PROTOBUF = 31,
283 |
284 | /**
285 | * @generated from enum value: LANGUAGE_PBTXT = 32;
286 | */
287 | PBTXT = 32,
288 |
289 | /**
290 | * @generated from enum value: LANGUAGE_PYTHON = 33;
291 | */
292 | PYTHON = 33,
293 |
294 | /**
295 | * @generated from enum value: LANGUAGE_R = 34;
296 | */
297 | R = 34,
298 |
299 | /**
300 | * @generated from enum value: LANGUAGE_RUBY = 35;
301 | */
302 | RUBY = 35,
303 |
304 | /**
305 | * @generated from enum value: LANGUAGE_RUST = 36;
306 | */
307 | RUST = 36,
308 |
309 | /**
310 | * @generated from enum value: LANGUAGE_SASS = 37;
311 | */
312 | SASS = 37,
313 |
314 | /**
315 | * @generated from enum value: LANGUAGE_SCALA = 38;
316 | */
317 | SCALA = 38,
318 |
319 | /**
320 | * @generated from enum value: LANGUAGE_SCSS = 39;
321 | */
322 | SCSS = 39,
323 |
324 | /**
325 | * @generated from enum value: LANGUAGE_SHELL = 40;
326 | */
327 | SHELL = 40,
328 |
329 | /**
330 | * @generated from enum value: LANGUAGE_SQL = 41;
331 | */
332 | SQL = 41,
333 |
334 | /**
335 | * @generated from enum value: LANGUAGE_STARLARK = 42;
336 | */
337 | STARLARK = 42,
338 |
339 | /**
340 | * @generated from enum value: LANGUAGE_SWIFT = 43;
341 | */
342 | SWIFT = 43,
343 |
344 | /**
345 | * @generated from enum value: LANGUAGE_TSX = 44;
346 | */
347 | TSX = 44,
348 |
349 | /**
350 | * @generated from enum value: LANGUAGE_TYPESCRIPT = 45;
351 | */
352 | TYPESCRIPT = 45,
353 |
354 | /**
355 | * @generated from enum value: LANGUAGE_VISUALBASIC = 46;
356 | */
357 | VISUALBASIC = 46,
358 |
359 | /**
360 | * @generated from enum value: LANGUAGE_VUE = 47;
361 | */
362 | VUE = 47,
363 |
364 | /**
365 | * @generated from enum value: LANGUAGE_XML = 48;
366 | */
367 | XML = 48,
368 |
369 | /**
370 | * @generated from enum value: LANGUAGE_XSL = 49;
371 | */
372 | XSL = 49,
373 |
374 | /**
375 | * @generated from enum value: LANGUAGE_YAML = 50;
376 | */
377 | YAML = 50,
378 |
379 | /**
380 | * @generated from enum value: LANGUAGE_SVELTE = 51;
381 | */
382 | SVELTE = 51,
383 |
384 | /**
385 | * @generated from enum value: LANGUAGE_TOML = 52;
386 | */
387 | TOML = 52,
388 |
389 | /**
390 | * @generated from enum value: LANGUAGE_DART = 53;
391 | */
392 | DART = 53,
393 |
394 | /**
395 | * @generated from enum value: LANGUAGE_RST = 54;
396 | */
397 | RST = 54,
398 |
399 | /**
400 | * @generated from enum value: LANGUAGE_OCAML = 55;
401 | */
402 | OCAML = 55,
403 |
404 | /**
405 | * @generated from enum value: LANGUAGE_CMAKE = 56;
406 | */
407 | CMAKE = 56,
408 |
409 | /**
410 | * @generated from enum value: LANGUAGE_PASCAL = 57;
411 | */
412 | PASCAL = 57,
413 |
414 | /**
415 | * @generated from enum value: LANGUAGE_ELIXIR = 58;
416 | */
417 | ELIXIR = 58,
418 |
419 | /**
420 | * @generated from enum value: LANGUAGE_FSHARP = 59;
421 | */
422 | FSHARP = 59,
423 |
424 | /**
425 | * @generated from enum value: LANGUAGE_LISP = 60;
426 | */
427 | LISP = 60,
428 |
429 | /**
430 | * @generated from enum value: LANGUAGE_MATLAB = 61;
431 | */
432 | MATLAB = 61,
433 |
434 | /**
435 | * @generated from enum value: LANGUAGE_POWERSHELL = 62;
436 | */
437 | POWERSHELL = 62,
438 |
439 | /**
440 | * @generated from enum value: LANGUAGE_SOLIDITY = 63;
441 | */
442 | SOLIDITY = 63,
443 |
444 | /**
445 | * @generated from enum value: LANGUAGE_ADA = 64;
446 | */
447 | ADA = 64,
448 |
449 | /**
450 | * @generated from enum value: LANGUAGE_OCAML_INTERFACE = 65;
451 | */
452 | OCAML_INTERFACE = 65,
453 | }
454 | // Retrieve enum metadata with: proto3.getEnumType(Language)
455 | proto3.util.setEnumType(Language, "exa.codeium_common_pb.Language", [
456 | { no: 0, name: "LANGUAGE_UNSPECIFIED" },
457 | { no: 1, name: "LANGUAGE_C" },
458 | { no: 2, name: "LANGUAGE_CLOJURE" },
459 | { no: 3, name: "LANGUAGE_COFFEESCRIPT" },
460 | { no: 4, name: "LANGUAGE_CPP" },
461 | { no: 5, name: "LANGUAGE_CSHARP" },
462 | { no: 6, name: "LANGUAGE_CSS" },
463 | { no: 7, name: "LANGUAGE_CUDACPP" },
464 | { no: 8, name: "LANGUAGE_DOCKERFILE" },
465 | { no: 9, name: "LANGUAGE_GO" },
466 | { no: 10, name: "LANGUAGE_GROOVY" },
467 | { no: 11, name: "LANGUAGE_HANDLEBARS" },
468 | { no: 12, name: "LANGUAGE_HASKELL" },
469 | { no: 13, name: "LANGUAGE_HCL" },
470 | { no: 14, name: "LANGUAGE_HTML" },
471 | { no: 15, name: "LANGUAGE_INI" },
472 | { no: 16, name: "LANGUAGE_JAVA" },
473 | { no: 17, name: "LANGUAGE_JAVASCRIPT" },
474 | { no: 18, name: "LANGUAGE_JSON" },
475 | { no: 19, name: "LANGUAGE_JULIA" },
476 | { no: 20, name: "LANGUAGE_KOTLIN" },
477 | { no: 21, name: "LANGUAGE_LATEX" },
478 | { no: 22, name: "LANGUAGE_LESS" },
479 | { no: 23, name: "LANGUAGE_LUA" },
480 | { no: 24, name: "LANGUAGE_MAKEFILE" },
481 | { no: 25, name: "LANGUAGE_MARKDOWN" },
482 | { no: 26, name: "LANGUAGE_OBJECTIVEC" },
483 | { no: 27, name: "LANGUAGE_OBJECTIVECPP" },
484 | { no: 28, name: "LANGUAGE_PERL" },
485 | { no: 29, name: "LANGUAGE_PHP" },
486 | { no: 30, name: "LANGUAGE_PLAINTEXT" },
487 | { no: 31, name: "LANGUAGE_PROTOBUF" },
488 | { no: 32, name: "LANGUAGE_PBTXT" },
489 | { no: 33, name: "LANGUAGE_PYTHON" },
490 | { no: 34, name: "LANGUAGE_R" },
491 | { no: 35, name: "LANGUAGE_RUBY" },
492 | { no: 36, name: "LANGUAGE_RUST" },
493 | { no: 37, name: "LANGUAGE_SASS" },
494 | { no: 38, name: "LANGUAGE_SCALA" },
495 | { no: 39, name: "LANGUAGE_SCSS" },
496 | { no: 40, name: "LANGUAGE_SHELL" },
497 | { no: 41, name: "LANGUAGE_SQL" },
498 | { no: 42, name: "LANGUAGE_STARLARK" },
499 | { no: 43, name: "LANGUAGE_SWIFT" },
500 | { no: 44, name: "LANGUAGE_TSX" },
501 | { no: 45, name: "LANGUAGE_TYPESCRIPT" },
502 | { no: 46, name: "LANGUAGE_VISUALBASIC" },
503 | { no: 47, name: "LANGUAGE_VUE" },
504 | { no: 48, name: "LANGUAGE_XML" },
505 | { no: 49, name: "LANGUAGE_XSL" },
506 | { no: 50, name: "LANGUAGE_YAML" },
507 | { no: 51, name: "LANGUAGE_SVELTE" },
508 | { no: 52, name: "LANGUAGE_TOML" },
509 | { no: 53, name: "LANGUAGE_DART" },
510 | { no: 54, name: "LANGUAGE_RST" },
511 | { no: 55, name: "LANGUAGE_OCAML" },
512 | { no: 56, name: "LANGUAGE_CMAKE" },
513 | { no: 57, name: "LANGUAGE_PASCAL" },
514 | { no: 58, name: "LANGUAGE_ELIXIR" },
515 | { no: 59, name: "LANGUAGE_FSHARP" },
516 | { no: 60, name: "LANGUAGE_LISP" },
517 | { no: 61, name: "LANGUAGE_MATLAB" },
518 | { no: 62, name: "LANGUAGE_POWERSHELL" },
519 | { no: 63, name: "LANGUAGE_SOLIDITY" },
520 | { no: 64, name: "LANGUAGE_ADA" },
521 | { no: 65, name: "LANGUAGE_OCAML_INTERFACE" },
522 | ]);
523 |
524 | /**
525 | * Next ID: 12, Previous field: entropy.
526 | *
527 | * @generated from message exa.codeium_common_pb.Completion
528 | */
529 | export class Completion extends Message {
530 | /**
531 | * @generated from field: string completion_id = 1;
532 | */
533 | completionId = "";
534 |
535 | /**
536 | * @generated from field: string text = 2;
537 | */
538 | text = "";
539 |
540 | /**
541 | * @generated from field: string prefix = 3;
542 | */
543 | prefix = "";
544 |
545 | /**
546 | * @generated from field: string stop = 4;
547 | */
548 | stop = "";
549 |
550 | /**
551 | * @generated from field: double score = 5;
552 | */
553 | score = 0;
554 |
555 | /**
556 | * @generated from field: repeated uint64 tokens = 6;
557 | */
558 | tokens: bigint[] = [];
559 |
560 | /**
561 | * @generated from field: repeated string decoded_tokens = 7;
562 | */
563 | decodedTokens: string[] = [];
564 |
565 | /**
566 | * @generated from field: repeated double probabilities = 8;
567 | */
568 | probabilities: number[] = [];
569 |
570 | /**
571 | * @generated from field: repeated double adjusted_probabilities = 9;
572 | */
573 | adjustedProbabilities: number[] = [];
574 |
575 | /**
576 | * @generated from field: uint64 generated_length = 10;
577 | */
578 | generatedLength = protoInt64.zero;
579 |
580 | constructor(data?: PartialMessage) {
581 | super();
582 | proto3.util.initPartial(data, this);
583 | }
584 |
585 | static readonly runtime: typeof proto3 = proto3;
586 | static readonly typeName = "exa.codeium_common_pb.Completion";
587 | static readonly fields: FieldList = proto3.util.newFieldList(() => [
588 | { no: 1, name: "completion_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
589 | { no: 2, name: "text", kind: "scalar", T: 9 /* ScalarType.STRING */ },
590 | { no: 3, name: "prefix", kind: "scalar", T: 9 /* ScalarType.STRING */ },
591 | { no: 4, name: "stop", kind: "scalar", T: 9 /* ScalarType.STRING */ },
592 | { no: 5, name: "score", kind: "scalar", T: 1 /* ScalarType.DOUBLE */ },
593 | { no: 6, name: "tokens", kind: "scalar", T: 4 /* ScalarType.UINT64 */, repeated: true },
594 | { no: 7, name: "decoded_tokens", kind: "scalar", T: 9 /* ScalarType.STRING */, repeated: true },
595 | { no: 8, name: "probabilities", kind: "scalar", T: 1 /* ScalarType.DOUBLE */, repeated: true },
596 | { no: 9, name: "adjusted_probabilities", kind: "scalar", T: 1 /* ScalarType.DOUBLE */, repeated: true },
597 | { no: 10, name: "generated_length", kind: "scalar", T: 4 /* ScalarType.UINT64 */ },
598 | ]);
599 |
600 | static fromBinary(bytes: Uint8Array, options?: Partial): Completion {
601 | return new Completion().fromBinary(bytes, options);
602 | }
603 |
604 | static fromJson(jsonValue: JsonValue, options?: Partial): Completion {
605 | return new Completion().fromJson(jsonValue, options);
606 | }
607 |
608 | static fromJsonString(jsonString: string, options?: Partial): Completion {
609 | return new Completion().fromJsonString(jsonString, options);
610 | }
611 |
612 | static equals(a: Completion | PlainMessage | undefined, b: Completion | PlainMessage | undefined): boolean {
613 | return proto3.util.equals(Completion, a, b);
614 | }
615 | }
616 |
617 | /**
618 | * Next ID: 15, Previous field: url.
619 | *
620 | * @generated from message exa.codeium_common_pb.Metadata
621 | */
622 | export class Metadata extends Message {
623 | /**
624 | * @generated from field: string ide_name = 1;
625 | */
626 | ideName = "";
627 |
628 | /**
629 | * @generated from field: string ide_version = 7;
630 | */
631 | ideVersion = "";
632 |
633 | /**
634 | * @generated from field: string extension_name = 12;
635 | */
636 | extensionName = "";
637 |
638 | /**
639 | * @generated from field: string extension_version = 2;
640 | */
641 | extensionVersion = "";
642 |
643 | /**
644 | * @generated from field: string api_key = 3;
645 | */
646 | apiKey = "";
647 |
648 | /**
649 | * Regex derived from https://stackoverflow.com/a/48300605.
650 | * TODO(prem): Should this be mandatory?
651 | *
652 | * @generated from field: string locale = 4;
653 | */
654 | locale = "";
655 |
656 | /**
657 | * UID identifying a single session for the given user.
658 | *
659 | * @generated from field: string session_id = 10;
660 | */
661 | sessionId = "";
662 |
663 | /**
664 | * Used purely in language server to cancel in flight requests.
665 | * If request_id is 0, then the request is not cancelable.
666 | * This should be a strictly monotonically increasing number
667 | * for the duration of a session.
668 | *
669 | * @generated from field: uint64 request_id = 9;
670 | */
671 | requestId = protoInt64.zero;
672 |
673 | /**
674 | * Browser-specific information.
675 | *
676 | * @generated from field: string user_agent = 13;
677 | */
678 | userAgent = "";
679 |
680 | /**
681 | * @generated from field: string url = 14;
682 | */
683 | url = "";
684 |
685 | /**
686 | * Authentication source information.
687 | *
688 | * @generated from field: exa.codeium_common_pb.AuthSource auth_source = 15;
689 | */
690 | authSource = AuthSource.CODEIUM;
691 |
692 | constructor(data?: PartialMessage) {
693 | super();
694 | proto3.util.initPartial(data, this);
695 | }
696 |
697 | static readonly runtime: typeof proto3 = proto3;
698 | static readonly typeName = "exa.codeium_common_pb.Metadata";
699 | static readonly fields: FieldList = proto3.util.newFieldList(() => [
700 | { no: 1, name: "ide_name", kind: "scalar", T: 9 /* ScalarType.STRING */ },
701 | { no: 7, name: "ide_version", kind: "scalar", T: 9 /* ScalarType.STRING */ },
702 | { no: 12, name: "extension_name", kind: "scalar", T: 9 /* ScalarType.STRING */ },
703 | { no: 2, name: "extension_version", kind: "scalar", T: 9 /* ScalarType.STRING */ },
704 | { no: 3, name: "api_key", kind: "scalar", T: 9 /* ScalarType.STRING */ },
705 | { no: 4, name: "locale", kind: "scalar", T: 9 /* ScalarType.STRING */ },
706 | { no: 10, name: "session_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
707 | { no: 9, name: "request_id", kind: "scalar", T: 4 /* ScalarType.UINT64 */ },
708 | { no: 13, name: "user_agent", kind: "scalar", T: 9 /* ScalarType.STRING */ },
709 | { no: 14, name: "url", kind: "scalar", T: 9 /* ScalarType.STRING */ },
710 | { no: 15, name: "auth_source", kind: "enum", T: proto3.getEnumType(AuthSource) },
711 | ]);
712 |
713 | static fromBinary(bytes: Uint8Array, options?: Partial): Metadata {
714 | return new Metadata().fromBinary(bytes, options);
715 | }
716 |
717 | static fromJson(jsonValue: JsonValue, options?: Partial): Metadata {
718 | return new Metadata().fromJson(jsonValue, options);
719 | }
720 |
721 | static fromJsonString(jsonString: string, options?: Partial): Metadata {
722 | return new Metadata().fromJsonString(jsonString, options);
723 | }
724 |
725 | static equals(a: Metadata | PlainMessage | undefined, b: Metadata | PlainMessage | undefined): boolean {
726 | return proto3.util.equals(Metadata, a, b);
727 | }
728 | }
729 |
730 | /**
731 | * Next ID: 3, Previous field: insert_spaces.
732 | *
733 | * @generated from message exa.codeium_common_pb.EditorOptions
734 | */
735 | export class EditorOptions extends Message {
736 | /**
737 | * @generated from field: uint64 tab_size = 1;
738 | */
739 | tabSize = protoInt64.zero;
740 |
741 | /**
742 | * @generated from field: bool insert_spaces = 2;
743 | */
744 | insertSpaces = false;
745 |
746 | constructor(data?: PartialMessage) {
747 | super();
748 | proto3.util.initPartial(data, this);
749 | }
750 |
751 | static readonly runtime: typeof proto3 = proto3;
752 | static readonly typeName = "exa.codeium_common_pb.EditorOptions";
753 | static readonly fields: FieldList = proto3.util.newFieldList(() => [
754 | { no: 1, name: "tab_size", kind: "scalar", T: 4 /* ScalarType.UINT64 */ },
755 | { no: 2, name: "insert_spaces", kind: "scalar", T: 8 /* ScalarType.BOOL */ },
756 | ]);
757 |
758 | static fromBinary(bytes: Uint8Array, options?: Partial): EditorOptions {
759 | return new EditorOptions().fromBinary(bytes, options);
760 | }
761 |
762 | static fromJson(jsonValue: JsonValue, options?: Partial): EditorOptions {
763 | return new EditorOptions().fromJson(jsonValue, options);
764 | }
765 |
766 | static fromJsonString(jsonString: string, options?: Partial): EditorOptions {
767 | return new EditorOptions().fromJsonString(jsonString, options);
768 | }
769 |
770 | static equals(a: EditorOptions | PlainMessage | undefined, b: EditorOptions | PlainMessage | undefined): boolean {
771 | return proto3.util.equals(EditorOptions, a, b);
772 | }
773 | }
774 |
775 | /**
776 | * @generated from message exa.codeium_common_pb.Event
777 | */
778 | export class Event extends Message {
779 | /**
780 | * @generated from field: exa.codeium_common_pb.EventType event_type = 1;
781 | */
782 | eventType = EventType.UNSPECIFIED;
783 |
784 | /**
785 | * @generated from field: string event_json = 2;
786 | */
787 | eventJson = "";
788 |
789 | /**
790 | * @generated from field: int64 timestamp_unix_ms = 3;
791 | */
792 | timestampUnixMs = protoInt64.zero;
793 |
794 | constructor(data?: PartialMessage) {
795 | super();
796 | proto3.util.initPartial(data, this);
797 | }
798 |
799 | static readonly runtime: typeof proto3 = proto3;
800 | static readonly typeName = "exa.codeium_common_pb.Event";
801 | static readonly fields: FieldList = proto3.util.newFieldList(() => [
802 | { no: 1, name: "event_type", kind: "enum", T: proto3.getEnumType(EventType) },
803 | { no: 2, name: "event_json", kind: "scalar", T: 9 /* ScalarType.STRING */ },
804 | { no: 3, name: "timestamp_unix_ms", kind: "scalar", T: 3 /* ScalarType.INT64 */ },
805 | ]);
806 |
807 | static fromBinary(bytes: Uint8Array, options?: Partial): Event {
808 | return new Event().fromBinary(bytes, options);
809 | }
810 |
811 | static fromJson(jsonValue: JsonValue, options?: Partial): Event {
812 | return new Event().fromJson(jsonValue, options);
813 | }
814 |
815 | static fromJsonString(jsonString: string, options?: Partial): Event {
816 | return new Event().fromJsonString(jsonString, options);
817 | }
818 |
819 | static equals(a: Event | PlainMessage | undefined, b: Event | PlainMessage | undefined): boolean {
820 | return proto3.util.equals(Event, a, b);
821 | }
822 | }
823 |
824 |
--------------------------------------------------------------------------------
/src/api/proto/exa/language_server_pb/language_server_connect.ts:
--------------------------------------------------------------------------------
1 | // Copyright Exafunction, Inc.
2 |
3 | // @generated by protoc-gen-connect-es v1.1.3 with parameter "target=ts"
4 | // @generated from file exa/language_server_pb/language_server.proto (package exa.language_server_pb, syntax proto3)
5 | /* eslint-disable */
6 | // @ts-nocheck
7 |
8 | import { AcceptCompletionRequest, AcceptCompletionResponse, GetAuthTokenRequest, GetAuthTokenResponse, GetCompletionsRequest, GetCompletionsResponse } from "./language_server_pb.js";
9 | import { MethodKind } from "@bufbuild/protobuf";
10 |
11 | /**
12 | * @generated from service exa.language_server_pb.LanguageServerService
13 | */
14 | export const LanguageServerService = {
15 | typeName: "exa.language_server_pb.LanguageServerService",
16 | methods: {
17 | /**
18 | * @generated from rpc exa.language_server_pb.LanguageServerService.GetCompletions
19 | */
20 | getCompletions: {
21 | name: "GetCompletions",
22 | I: GetCompletionsRequest,
23 | O: GetCompletionsResponse,
24 | kind: MethodKind.Unary,
25 | },
26 | /**
27 | * @generated from rpc exa.language_server_pb.LanguageServerService.AcceptCompletion
28 | */
29 | acceptCompletion: {
30 | name: "AcceptCompletion",
31 | I: AcceptCompletionRequest,
32 | O: AcceptCompletionResponse,
33 | kind: MethodKind.Unary,
34 | },
35 | /**
36 | * @generated from rpc exa.language_server_pb.LanguageServerService.GetAuthToken
37 | */
38 | getAuthToken: {
39 | name: "GetAuthToken",
40 | I: GetAuthTokenRequest,
41 | O: GetAuthTokenResponse,
42 | kind: MethodKind.Unary,
43 | },
44 | }
45 | } as const;
46 |
47 |
--------------------------------------------------------------------------------
/src/api/proto/exa/language_server_pb/language_server_pb.ts:
--------------------------------------------------------------------------------
1 | // Copyright Exafunction, Inc.
2 |
3 | // @generated by protoc-gen-es v1.4.2 with parameter "target=ts"
4 | // @generated from file exa/language_server_pb/language_server.proto (package exa.language_server_pb, syntax proto3)
5 | /* eslint-disable */
6 | // @ts-nocheck
7 |
8 | import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf";
9 | import { Message, proto3, protoInt64 } from "@bufbuild/protobuf";
10 | import { Completion, CompletionSource, EditorOptions, ExperimentKey, Language, Metadata } from "../codeium_common_pb/codeium_common_pb.js";
11 |
12 | /**
13 | * @generated from enum exa.language_server_pb.CodeiumState
14 | */
15 | export enum CodeiumState {
16 | /**
17 | * @generated from enum value: CODEIUM_STATE_UNSPECIFIED = 0;
18 | */
19 | UNSPECIFIED = 0,
20 |
21 | /**
22 | * @generated from enum value: CODEIUM_STATE_INACTIVE = 1;
23 | */
24 | INACTIVE = 1,
25 |
26 | /**
27 | * @generated from enum value: CODEIUM_STATE_PROCESSING = 2;
28 | */
29 | PROCESSING = 2,
30 |
31 | /**
32 | * @generated from enum value: CODEIUM_STATE_SUCCESS = 3;
33 | */
34 | SUCCESS = 3,
35 |
36 | /**
37 | * @generated from enum value: CODEIUM_STATE_WARNING = 4;
38 | */
39 | WARNING = 4,
40 |
41 | /**
42 | * @generated from enum value: CODEIUM_STATE_ERROR = 5;
43 | */
44 | ERROR = 5,
45 | }
46 | // Retrieve enum metadata with: proto3.getEnumType(CodeiumState)
47 | proto3.util.setEnumType(CodeiumState, "exa.language_server_pb.CodeiumState", [
48 | { no: 0, name: "CODEIUM_STATE_UNSPECIFIED" },
49 | { no: 1, name: "CODEIUM_STATE_INACTIVE" },
50 | { no: 2, name: "CODEIUM_STATE_PROCESSING" },
51 | { no: 3, name: "CODEIUM_STATE_SUCCESS" },
52 | { no: 4, name: "CODEIUM_STATE_WARNING" },
53 | { no: 5, name: "CODEIUM_STATE_ERROR" },
54 | ]);
55 |
56 | /**
57 | * @generated from enum exa.language_server_pb.LineType
58 | */
59 | export enum LineType {
60 | /**
61 | * @generated from enum value: LINE_TYPE_UNSPECIFIED = 0;
62 | */
63 | UNSPECIFIED = 0,
64 |
65 | /**
66 | * @generated from enum value: LINE_TYPE_SINGLE = 1;
67 | */
68 | SINGLE = 1,
69 |
70 | /**
71 | * @generated from enum value: LINE_TYPE_MULTI = 2;
72 | */
73 | MULTI = 2,
74 | }
75 | // Retrieve enum metadata with: proto3.getEnumType(LineType)
76 | proto3.util.setEnumType(LineType, "exa.language_server_pb.LineType", [
77 | { no: 0, name: "LINE_TYPE_UNSPECIFIED" },
78 | { no: 1, name: "LINE_TYPE_SINGLE" },
79 | { no: 2, name: "LINE_TYPE_MULTI" },
80 | ]);
81 |
82 | /**
83 | * @generated from enum exa.language_server_pb.CompletionPartType
84 | */
85 | export enum CompletionPartType {
86 | /**
87 | * @generated from enum value: COMPLETION_PART_TYPE_UNSPECIFIED = 0;
88 | */
89 | UNSPECIFIED = 0,
90 |
91 | /**
92 | * Single-line completion parts that appear within an existing line of text.
93 | *
94 | * @generated from enum value: COMPLETION_PART_TYPE_INLINE = 1;
95 | */
96 | INLINE = 1,
97 |
98 | /**
99 | * Possibly multi-line completion parts that appear below an existing line of text.
100 | *
101 | * @generated from enum value: COMPLETION_PART_TYPE_BLOCK = 2;
102 | */
103 | BLOCK = 2,
104 |
105 | /**
106 | * Like COMPLETION_PART_TYPE_INLINE, but overwrites the existing text.
107 | *
108 | * @generated from enum value: COMPLETION_PART_TYPE_INLINE_MASK = 3;
109 | */
110 | INLINE_MASK = 3,
111 | }
112 | // Retrieve enum metadata with: proto3.getEnumType(CompletionPartType)
113 | proto3.util.setEnumType(CompletionPartType, "exa.language_server_pb.CompletionPartType", [
114 | { no: 0, name: "COMPLETION_PART_TYPE_UNSPECIFIED" },
115 | { no: 1, name: "COMPLETION_PART_TYPE_INLINE" },
116 | { no: 2, name: "COMPLETION_PART_TYPE_BLOCK" },
117 | { no: 3, name: "COMPLETION_PART_TYPE_INLINE_MASK" },
118 | ]);
119 |
120 | /**
121 | * @generated from message exa.language_server_pb.MultilineConfig
122 | */
123 | export class MultilineConfig extends Message {
124 | /**
125 | * Multiline model threshold. 0-1, higher = more single line, lower = more multiline,
126 | * 0.0 = only_multiline, default is 0.5
127 | *
128 | * @generated from field: float threshold = 1;
129 | */
130 | threshold = 0;
131 |
132 | constructor(data?: PartialMessage) {
133 | super();
134 | proto3.util.initPartial(data, this);
135 | }
136 |
137 | static readonly runtime: typeof proto3 = proto3;
138 | static readonly typeName = "exa.language_server_pb.MultilineConfig";
139 | static readonly fields: FieldList = proto3.util.newFieldList(() => [
140 | { no: 1, name: "threshold", kind: "scalar", T: 2 /* ScalarType.FLOAT */ },
141 | ]);
142 |
143 | static fromBinary(bytes: Uint8Array, options?: Partial): MultilineConfig {
144 | return new MultilineConfig().fromBinary(bytes, options);
145 | }
146 |
147 | static fromJson(jsonValue: JsonValue, options?: Partial): MultilineConfig {
148 | return new MultilineConfig().fromJson(jsonValue, options);
149 | }
150 |
151 | static fromJsonString(jsonString: string, options?: Partial): MultilineConfig {
152 | return new MultilineConfig().fromJsonString(jsonString, options);
153 | }
154 |
155 | static equals(a: MultilineConfig | PlainMessage | undefined, b: MultilineConfig | PlainMessage | undefined): boolean {
156 | return proto3.util.equals(MultilineConfig, a, b);
157 | }
158 | }
159 |
160 | /**
161 | * Next ID: 9, Previous field: disable_cache.
162 | *
163 | * @generated from message exa.language_server_pb.GetCompletionsRequest
164 | */
165 | export class GetCompletionsRequest extends Message {
166 | /**
167 | * @generated from field: exa.codeium_common_pb.Metadata metadata = 1;
168 | */
169 | metadata?: Metadata;
170 |
171 | /**
172 | * @generated from field: exa.language_server_pb.Document document = 2;
173 | */
174 | document?: Document;
175 |
176 | /**
177 | * @generated from field: exa.codeium_common_pb.EditorOptions editor_options = 3;
178 | */
179 | editorOptions?: EditorOptions;
180 |
181 | /**
182 | * @generated from field: repeated exa.language_server_pb.Document other_documents = 5;
183 | */
184 | otherDocuments: Document[] = [];
185 |
186 | /**
187 | * @generated from field: exa.language_server_pb.ExperimentConfig experiment_config = 7;
188 | */
189 | experimentConfig?: ExperimentConfig;
190 |
191 | /**
192 | * @generated from field: string model_name = 10;
193 | */
194 | modelName = "";
195 |
196 | /**
197 | * @generated from field: exa.language_server_pb.MultilineConfig multiline_config = 13;
198 | */
199 | multilineConfig?: MultilineConfig;
200 |
201 | constructor(data?: PartialMessage) {
202 | super();
203 | proto3.util.initPartial(data, this);
204 | }
205 |
206 | static readonly runtime: typeof proto3 = proto3;
207 | static readonly typeName = "exa.language_server_pb.GetCompletionsRequest";
208 | static readonly fields: FieldList = proto3.util.newFieldList(() => [
209 | { no: 1, name: "metadata", kind: "message", T: Metadata },
210 | { no: 2, name: "document", kind: "message", T: Document },
211 | { no: 3, name: "editor_options", kind: "message", T: EditorOptions },
212 | { no: 5, name: "other_documents", kind: "message", T: Document, repeated: true },
213 | { no: 7, name: "experiment_config", kind: "message", T: ExperimentConfig },
214 | { no: 10, name: "model_name", kind: "scalar", T: 9 /* ScalarType.STRING */ },
215 | { no: 13, name: "multiline_config", kind: "message", T: MultilineConfig },
216 | ]);
217 |
218 | static fromBinary(bytes: Uint8Array, options?: Partial): GetCompletionsRequest {
219 | return new GetCompletionsRequest().fromBinary(bytes, options);
220 | }
221 |
222 | static fromJson(jsonValue: JsonValue, options?: Partial): GetCompletionsRequest {
223 | return new GetCompletionsRequest().fromJson(jsonValue, options);
224 | }
225 |
226 | static fromJsonString(jsonString: string, options?: Partial): GetCompletionsRequest {
227 | return new GetCompletionsRequest().fromJsonString(jsonString, options);
228 | }
229 |
230 | static equals(a: GetCompletionsRequest | PlainMessage | undefined, b: GetCompletionsRequest | PlainMessage | undefined): boolean {
231 | return proto3.util.equals(GetCompletionsRequest, a, b);
232 | }
233 | }
234 |
235 | /**
236 | * Next ID: 5, Previous field: latency_info.
237 | *
238 | * @generated from message exa.language_server_pb.GetCompletionsResponse
239 | */
240 | export class GetCompletionsResponse extends Message {
241 | /**
242 | * @generated from field: exa.language_server_pb.State state = 1;
243 | */
244 | state?: State;
245 |
246 | /**
247 | * @generated from field: repeated exa.language_server_pb.CompletionItem completion_items = 2;
248 | */
249 | completionItems: CompletionItem[] = [];
250 |
251 | constructor(data?: PartialMessage) {
252 | super();
253 | proto3.util.initPartial(data, this);
254 | }
255 |
256 | static readonly runtime: typeof proto3 = proto3;
257 | static readonly typeName = "exa.language_server_pb.GetCompletionsResponse";
258 | static readonly fields: FieldList = proto3.util.newFieldList(() => [
259 | { no: 1, name: "state", kind: "message", T: State },
260 | { no: 2, name: "completion_items", kind: "message", T: CompletionItem, repeated: true },
261 | ]);
262 |
263 | static fromBinary(bytes: Uint8Array, options?: Partial): GetCompletionsResponse {
264 | return new GetCompletionsResponse().fromBinary(bytes, options);
265 | }
266 |
267 | static fromJson(jsonValue: JsonValue, options?: Partial): GetCompletionsResponse {
268 | return new GetCompletionsResponse().fromJson(jsonValue, options);
269 | }
270 |
271 | static fromJsonString(jsonString: string, options?: Partial): GetCompletionsResponse {
272 | return new GetCompletionsResponse().fromJsonString(jsonString, options);
273 | }
274 |
275 | static equals(a: GetCompletionsResponse | PlainMessage | undefined, b: GetCompletionsResponse | PlainMessage | undefined): boolean {
276 | return proto3.util.equals(GetCompletionsResponse, a, b);
277 | }
278 | }
279 |
280 | /**
281 | * Next ID: 3, Previous field: completion_id.
282 | *
283 | * @generated from message exa.language_server_pb.AcceptCompletionRequest
284 | */
285 | export class AcceptCompletionRequest extends Message {
286 | /**
287 | * @generated from field: exa.codeium_common_pb.Metadata metadata = 1;
288 | */
289 | metadata?: Metadata;
290 |
291 | /**
292 | * @generated from field: string completion_id = 2;
293 | */
294 | completionId = "";
295 |
296 | constructor(data?: PartialMessage) {
297 | super();
298 | proto3.util.initPartial(data, this);
299 | }
300 |
301 | static readonly runtime: typeof proto3 = proto3;
302 | static readonly typeName = "exa.language_server_pb.AcceptCompletionRequest";
303 | static readonly fields: FieldList = proto3.util.newFieldList(() => [
304 | { no: 1, name: "metadata", kind: "message", T: Metadata },
305 | { no: 2, name: "completion_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
306 | ]);
307 |
308 | static fromBinary(bytes: Uint8Array, options?: Partial): AcceptCompletionRequest {
309 | return new AcceptCompletionRequest().fromBinary(bytes, options);
310 | }
311 |
312 | static fromJson(jsonValue: JsonValue, options?: Partial): AcceptCompletionRequest {
313 | return new AcceptCompletionRequest().fromJson(jsonValue, options);
314 | }
315 |
316 | static fromJsonString(jsonString: string, options?: Partial): AcceptCompletionRequest {
317 | return new AcceptCompletionRequest().fromJsonString(jsonString, options);
318 | }
319 |
320 | static equals(a: AcceptCompletionRequest | PlainMessage | undefined, b: AcceptCompletionRequest | PlainMessage | undefined): boolean {
321 | return proto3.util.equals(AcceptCompletionRequest, a, b);
322 | }
323 | }
324 |
325 | /**
326 | * Next ID: 1, Previous field: N/A.
327 | *
328 | * @generated from message exa.language_server_pb.AcceptCompletionResponse
329 | */
330 | export class AcceptCompletionResponse extends Message {
331 | constructor(data?: PartialMessage) {
332 | super();
333 | proto3.util.initPartial(data, this);
334 | }
335 |
336 | static readonly runtime: typeof proto3 = proto3;
337 | static readonly typeName = "exa.language_server_pb.AcceptCompletionResponse";
338 | static readonly fields: FieldList = proto3.util.newFieldList(() => [
339 | ]);
340 |
341 | static fromBinary(bytes: Uint8Array, options?: Partial): AcceptCompletionResponse {
342 | return new AcceptCompletionResponse().fromBinary(bytes, options);
343 | }
344 |
345 | static fromJson(jsonValue: JsonValue, options?: Partial): AcceptCompletionResponse {
346 | return new AcceptCompletionResponse().fromJson(jsonValue, options);
347 | }
348 |
349 | static fromJsonString(jsonString: string, options?: Partial): AcceptCompletionResponse {
350 | return new AcceptCompletionResponse().fromJsonString(jsonString, options);
351 | }
352 |
353 | static equals(a: AcceptCompletionResponse | PlainMessage | undefined, b: AcceptCompletionResponse | PlainMessage | undefined): boolean {
354 | return proto3.util.equals(AcceptCompletionResponse, a, b);
355 | }
356 | }
357 |
358 | /**
359 | * Next ID: 1, Previous field: N/A.
360 | *
361 | * @generated from message exa.language_server_pb.GetAuthTokenRequest
362 | */
363 | export class GetAuthTokenRequest extends Message {
364 | constructor(data?: PartialMessage) {
365 | super();
366 | proto3.util.initPartial(data, this);
367 | }
368 |
369 | static readonly runtime: typeof proto3 = proto3;
370 | static readonly typeName = "exa.language_server_pb.GetAuthTokenRequest";
371 | static readonly fields: FieldList = proto3.util.newFieldList(() => [
372 | ]);
373 |
374 | static fromBinary(bytes: Uint8Array, options?: Partial): GetAuthTokenRequest {
375 | return new GetAuthTokenRequest().fromBinary(bytes, options);
376 | }
377 |
378 | static fromJson(jsonValue: JsonValue, options?: Partial): GetAuthTokenRequest {
379 | return new GetAuthTokenRequest().fromJson(jsonValue, options);
380 | }
381 |
382 | static fromJsonString(jsonString: string, options?: Partial): GetAuthTokenRequest {
383 | return new GetAuthTokenRequest().fromJsonString(jsonString, options);
384 | }
385 |
386 | static equals(a: GetAuthTokenRequest | PlainMessage | undefined, b: GetAuthTokenRequest | PlainMessage | undefined): boolean {
387 | return proto3.util.equals(GetAuthTokenRequest, a, b);
388 | }
389 | }
390 |
391 | /**
392 | * Next ID: 3, Previous field: uuid.
393 | *
394 | * @generated from message exa.language_server_pb.GetAuthTokenResponse
395 | */
396 | export class GetAuthTokenResponse extends Message {
397 | /**
398 | * @generated from field: string auth_token = 1;
399 | */
400 | authToken = "";
401 |
402 | /**
403 | * @generated from field: string uuid = 2;
404 | */
405 | uuid = "";
406 |
407 | constructor(data?: PartialMessage) {
408 | super();
409 | proto3.util.initPartial(data, this);
410 | }
411 |
412 | static readonly runtime: typeof proto3 = proto3;
413 | static readonly typeName = "exa.language_server_pb.GetAuthTokenResponse";
414 | static readonly fields: FieldList = proto3.util.newFieldList(() => [
415 | { no: 1, name: "auth_token", kind: "scalar", T: 9 /* ScalarType.STRING */ },
416 | { no: 2, name: "uuid", kind: "scalar", T: 9 /* ScalarType.STRING */ },
417 | ]);
418 |
419 | static fromBinary(bytes: Uint8Array, options?: Partial): GetAuthTokenResponse {
420 | return new GetAuthTokenResponse().fromBinary(bytes, options);
421 | }
422 |
423 | static fromJson(jsonValue: JsonValue, options?: Partial): GetAuthTokenResponse {
424 | return new GetAuthTokenResponse().fromJson(jsonValue, options);
425 | }
426 |
427 | static fromJsonString(jsonString: string, options?: Partial): GetAuthTokenResponse {
428 | return new GetAuthTokenResponse().fromJsonString(jsonString, options);
429 | }
430 |
431 | static equals(a: GetAuthTokenResponse | PlainMessage | undefined, b: GetAuthTokenResponse | PlainMessage | undefined): boolean {
432 | return proto3.util.equals(GetAuthTokenResponse, a, b);
433 | }
434 | }
435 |
436 | /**
437 | * @generated from message exa.language_server_pb.DocumentPosition
438 | */
439 | export class DocumentPosition extends Message {
440 | /**
441 | * 0-indexed. Measured in UTF-8 bytes.
442 | *
443 | * @generated from field: uint64 row = 1;
444 | */
445 | row = protoInt64.zero;
446 |
447 | /**
448 | * 0-indexed. Measured in UTF-8 bytes.
449 | *
450 | * @generated from field: uint64 col = 2;
451 | */
452 | col = protoInt64.zero;
453 |
454 | constructor(data?: PartialMessage) {
455 | super();
456 | proto3.util.initPartial(data, this);
457 | }
458 |
459 | static readonly runtime: typeof proto3 = proto3;
460 | static readonly typeName = "exa.language_server_pb.DocumentPosition";
461 | static readonly fields: FieldList = proto3.util.newFieldList(() => [
462 | { no: 1, name: "row", kind: "scalar", T: 4 /* ScalarType.UINT64 */ },
463 | { no: 2, name: "col", kind: "scalar", T: 4 /* ScalarType.UINT64 */ },
464 | ]);
465 |
466 | static fromBinary(bytes: Uint8Array, options?: Partial): DocumentPosition {
467 | return new DocumentPosition().fromBinary(bytes, options);
468 | }
469 |
470 | static fromJson(jsonValue: JsonValue, options?: Partial): DocumentPosition {
471 | return new DocumentPosition().fromJson(jsonValue, options);
472 | }
473 |
474 | static fromJsonString(jsonString: string, options?: Partial): DocumentPosition {
475 | return new DocumentPosition().fromJsonString(jsonString, options);
476 | }
477 |
478 | static equals(a: DocumentPosition | PlainMessage | undefined, b: DocumentPosition | PlainMessage | undefined): boolean {
479 | return proto3.util.equals(DocumentPosition, a, b);
480 | }
481 | }
482 |
483 | /**
484 | * Next ID: 9, Previous field: cursor_position.
485 | *
486 | * @generated from message exa.language_server_pb.Document
487 | */
488 | export class Document extends Message {
489 | /**
490 | * @generated from field: string absolute_path = 1;
491 | */
492 | absolutePath = "";
493 |
494 | /**
495 | * Path relative to the root of the workspace.
496 | *
497 | * @generated from field: string relative_path = 2;
498 | */
499 | relativePath = "";
500 |
501 | /**
502 | * @generated from field: string text = 3;
503 | */
504 | text = "";
505 |
506 | /**
507 | * Language ID provided by the editor.
508 | *
509 | * @generated from field: string editor_language = 4;
510 | */
511 | editorLanguage = "";
512 |
513 | /**
514 | * Language enum standardized across editors.
515 | *
516 | * @generated from field: exa.codeium_common_pb.Language language = 5;
517 | */
518 | language = Language.UNSPECIFIED;
519 |
520 | /**
521 | * Measured in number of UTF-8 bytes.
522 | *
523 | * @generated from field: uint64 cursor_offset = 6;
524 | */
525 | cursorOffset = protoInt64.zero;
526 |
527 | /**
528 | * May be present instead of cursor_offset.
529 | *
530 | * @generated from field: exa.language_server_pb.DocumentPosition cursor_position = 8;
531 | */
532 | cursorPosition?: DocumentPosition;
533 |
534 | /**
535 | * \n or \r\n, if known.
536 | *
537 | * @generated from field: string line_ending = 7;
538 | */
539 | lineEnding = "";
540 |
541 | constructor(data?: PartialMessage) {
542 | super();
543 | proto3.util.initPartial(data, this);
544 | }
545 |
546 | static readonly runtime: typeof proto3 = proto3;
547 | static readonly typeName = "exa.language_server_pb.Document";
548 | static readonly fields: FieldList = proto3.util.newFieldList(() => [
549 | { no: 1, name: "absolute_path", kind: "scalar", T: 9 /* ScalarType.STRING */ },
550 | { no: 2, name: "relative_path", kind: "scalar", T: 9 /* ScalarType.STRING */ },
551 | { no: 3, name: "text", kind: "scalar", T: 9 /* ScalarType.STRING */ },
552 | { no: 4, name: "editor_language", kind: "scalar", T: 9 /* ScalarType.STRING */ },
553 | { no: 5, name: "language", kind: "enum", T: proto3.getEnumType(Language) },
554 | { no: 6, name: "cursor_offset", kind: "scalar", T: 4 /* ScalarType.UINT64 */ },
555 | { no: 8, name: "cursor_position", kind: "message", T: DocumentPosition },
556 | { no: 7, name: "line_ending", kind: "scalar", T: 9 /* ScalarType.STRING */ },
557 | ]);
558 |
559 | static fromBinary(bytes: Uint8Array, options?: Partial): Document {
560 | return new Document().fromBinary(bytes, options);
561 | }
562 |
563 | static fromJson(jsonValue: JsonValue, options?: Partial): Document {
564 | return new Document().fromJson(jsonValue, options);
565 | }
566 |
567 | static fromJsonString(jsonString: string, options?: Partial): Document {
568 | return new Document().fromJsonString(jsonString, options);
569 | }
570 |
571 | static equals(a: Document | PlainMessage | undefined, b: Document | PlainMessage | undefined): boolean {
572 | return proto3.util.equals(Document, a, b);
573 | }
574 | }
575 |
576 | /**
577 | * @generated from message exa.language_server_pb.ExperimentConfig
578 | */
579 | export class ExperimentConfig extends Message {
580 | /**
581 | * @generated from field: repeated exa.codeium_common_pb.ExperimentKey force_enable_experiments = 1;
582 | */
583 | forceEnableExperiments: ExperimentKey[] = [];
584 |
585 | constructor(data?: PartialMessage) {
586 | super();
587 | proto3.util.initPartial(data, this);
588 | }
589 |
590 | static readonly runtime: typeof proto3 = proto3;
591 | static readonly typeName = "exa.language_server_pb.ExperimentConfig";
592 | static readonly fields: FieldList = proto3.util.newFieldList(() => [
593 | { no: 1, name: "force_enable_experiments", kind: "enum", T: proto3.getEnumType(ExperimentKey), repeated: true },
594 | ]);
595 |
596 | static fromBinary(bytes: Uint8Array, options?: Partial): ExperimentConfig {
597 | return new ExperimentConfig().fromBinary(bytes, options);
598 | }
599 |
600 | static fromJson(jsonValue: JsonValue, options?: Partial): ExperimentConfig {
601 | return new ExperimentConfig().fromJson(jsonValue, options);
602 | }
603 |
604 | static fromJsonString(jsonString: string, options?: Partial): ExperimentConfig {
605 | return new ExperimentConfig().fromJsonString(jsonString, options);
606 | }
607 |
608 | static equals(a: ExperimentConfig | PlainMessage | undefined, b: ExperimentConfig | PlainMessage | undefined): boolean {
609 | return proto3.util.equals(ExperimentConfig, a, b);
610 | }
611 | }
612 |
613 | /**
614 | * Next ID: 3, Previous field: message.
615 | *
616 | * @generated from message exa.language_server_pb.State
617 | */
618 | export class State extends Message {
619 | /**
620 | * @generated from field: exa.language_server_pb.CodeiumState state = 1;
621 | */
622 | state = CodeiumState.UNSPECIFIED;
623 |
624 | /**
625 | * @generated from field: string message = 2;
626 | */
627 | message = "";
628 |
629 | constructor(data?: PartialMessage) {
630 | super();
631 | proto3.util.initPartial(data, this);
632 | }
633 |
634 | static readonly runtime: typeof proto3 = proto3;
635 | static readonly typeName = "exa.language_server_pb.State";
636 | static readonly fields: FieldList = proto3.util.newFieldList(() => [
637 | { no: 1, name: "state", kind: "enum", T: proto3.getEnumType(CodeiumState) },
638 | { no: 2, name: "message", kind: "scalar", T: 9 /* ScalarType.STRING */ },
639 | ]);
640 |
641 | static fromBinary(bytes: Uint8Array, options?: Partial): State {
642 | return new State().fromBinary(bytes, options);
643 | }
644 |
645 | static fromJson(jsonValue: JsonValue, options?: Partial): State {
646 | return new State().fromJson(jsonValue, options);
647 | }
648 |
649 | static fromJsonString(jsonString: string, options?: Partial): State {
650 | return new State().fromJsonString(jsonString, options);
651 | }
652 |
653 | static equals(a: State | PlainMessage | undefined, b: State | PlainMessage | undefined): boolean {
654 | return proto3.util.equals(State, a, b);
655 | }
656 | }
657 |
658 | /**
659 | * Next ID: 5, Previous field: end_position.
660 | *
661 | * @generated from message exa.language_server_pb.Range
662 | */
663 | export class Range extends Message {
664 | /**
665 | * @generated from field: uint64 start_offset = 1;
666 | */
667 | startOffset = protoInt64.zero;
668 |
669 | /**
670 | * @generated from field: uint64 end_offset = 2;
671 | */
672 | endOffset = protoInt64.zero;
673 |
674 | /**
675 | * @generated from field: exa.language_server_pb.DocumentPosition start_position = 3;
676 | */
677 | startPosition?: DocumentPosition;
678 |
679 | /**
680 | * @generated from field: exa.language_server_pb.DocumentPosition end_position = 4;
681 | */
682 | endPosition?: DocumentPosition;
683 |
684 | constructor(data?: PartialMessage) {
685 | super();
686 | proto3.util.initPartial(data, this);
687 | }
688 |
689 | static readonly runtime: typeof proto3 = proto3;
690 | static readonly typeName = "exa.language_server_pb.Range";
691 | static readonly fields: FieldList = proto3.util.newFieldList(() => [
692 | { no: 1, name: "start_offset", kind: "scalar", T: 4 /* ScalarType.UINT64 */ },
693 | { no: 2, name: "end_offset", kind: "scalar", T: 4 /* ScalarType.UINT64 */ },
694 | { no: 3, name: "start_position", kind: "message", T: DocumentPosition },
695 | { no: 4, name: "end_position", kind: "message", T: DocumentPosition },
696 | ]);
697 |
698 | static fromBinary(bytes: Uint8Array, options?: Partial): Range {
699 | return new Range().fromBinary(bytes, options);
700 | }
701 |
702 | static fromJson(jsonValue: JsonValue, options?: Partial): Range {
703 | return new Range().fromJson(jsonValue, options);
704 | }
705 |
706 | static fromJsonString(jsonString: string, options?: Partial): Range {
707 | return new Range().fromJsonString(jsonString, options);
708 | }
709 |
710 | static equals(a: Range | PlainMessage | undefined, b: Range | PlainMessage | undefined): boolean {
711 | return proto3.util.equals(Range, a, b);
712 | }
713 | }
714 |
715 | /**
716 | * @generated from message exa.language_server_pb.Suffix
717 | */
718 | export class Suffix extends Message {
719 | /**
720 | * Text to insert after the cursor when accepting the completion.
721 | *
722 | * @generated from field: string text = 1;
723 | */
724 | text = "";
725 |
726 | /**
727 | * Cursor position delta (as signed offset) from the end of the inserted
728 | * completion (including the suffix).
729 | *
730 | * @generated from field: int64 delta_cursor_offset = 2;
731 | */
732 | deltaCursorOffset = protoInt64.zero;
733 |
734 | constructor(data?: PartialMessage) {
735 | super();
736 | proto3.util.initPartial(data, this);
737 | }
738 |
739 | static readonly runtime: typeof proto3 = proto3;
740 | static readonly typeName = "exa.language_server_pb.Suffix";
741 | static readonly fields: FieldList = proto3.util.newFieldList(() => [
742 | { no: 1, name: "text", kind: "scalar", T: 9 /* ScalarType.STRING */ },
743 | { no: 2, name: "delta_cursor_offset", kind: "scalar", T: 3 /* ScalarType.INT64 */ },
744 | ]);
745 |
746 | static fromBinary(bytes: Uint8Array, options?: Partial): Suffix {
747 | return new Suffix().fromBinary(bytes, options);
748 | }
749 |
750 | static fromJson(jsonValue: JsonValue, options?: Partial): Suffix {
751 | return new Suffix().fromJson(jsonValue, options);
752 | }
753 |
754 | static fromJsonString(jsonString: string, options?: Partial): Suffix {
755 | return new Suffix().fromJsonString(jsonString, options);
756 | }
757 |
758 | static equals(a: Suffix | PlainMessage | undefined, b: Suffix | PlainMessage | undefined): boolean {
759 | return proto3.util.equals(Suffix, a, b);
760 | }
761 | }
762 |
763 | /**
764 | * Represents a contiguous part of the completion text that is not
765 | * already in the document.
766 | * Next ID: 4, Previous field: prefix.
767 | *
768 | * @generated from message exa.language_server_pb.CompletionPart
769 | */
770 | export class CompletionPart extends Message {
771 | /**
772 | * @generated from field: string text = 1;
773 | */
774 | text = "";
775 |
776 | /**
777 | * Offset in the original document where the part starts. For block
778 | * parts, this is always the end of the line before the block.
779 | *
780 | * @generated from field: uint64 offset = 2;
781 | */
782 | offset = protoInt64.zero;
783 |
784 | /**
785 | * @generated from field: exa.language_server_pb.CompletionPartType type = 3;
786 | */
787 | type = CompletionPartType.UNSPECIFIED;
788 |
789 | /**
790 | * The section of the original line that came before this part. Only valid for
791 | * COMPLETION_PART_TYPE_INLINE.
792 | *
793 | * @generated from field: string prefix = 4;
794 | */
795 | prefix = "";
796 |
797 | /**
798 | * In the case of COMPLETION_PART_TYPE_BLOCK, represents the line it is below.
799 | *
800 | * @generated from field: uint64 line = 5;
801 | */
802 | line = protoInt64.zero;
803 |
804 | constructor(data?: PartialMessage) {
805 | super();
806 | proto3.util.initPartial(data, this);
807 | }
808 |
809 | static readonly runtime: typeof proto3 = proto3;
810 | static readonly typeName = "exa.language_server_pb.CompletionPart";
811 | static readonly fields: FieldList = proto3.util.newFieldList(() => [
812 | { no: 1, name: "text", kind: "scalar", T: 9 /* ScalarType.STRING */ },
813 | { no: 2, name: "offset", kind: "scalar", T: 4 /* ScalarType.UINT64 */ },
814 | { no: 3, name: "type", kind: "enum", T: proto3.getEnumType(CompletionPartType) },
815 | { no: 4, name: "prefix", kind: "scalar", T: 9 /* ScalarType.STRING */ },
816 | { no: 5, name: "line", kind: "scalar", T: 4 /* ScalarType.UINT64 */ },
817 | ]);
818 |
819 | static fromBinary(bytes: Uint8Array, options?: Partial): CompletionPart {
820 | return new CompletionPart().fromBinary(bytes, options);
821 | }
822 |
823 | static fromJson(jsonValue: JsonValue, options?: Partial): CompletionPart {
824 | return new CompletionPart().fromJson(jsonValue, options);
825 | }
826 |
827 | static fromJsonString(jsonString: string, options?: Partial): CompletionPart {
828 | return new CompletionPart().fromJsonString(jsonString, options);
829 | }
830 |
831 | static equals(a: CompletionPart | PlainMessage | undefined, b: CompletionPart | PlainMessage | undefined): boolean {
832 | return proto3.util.equals(CompletionPart, a, b);
833 | }
834 | }
835 |
836 | /**
837 | * Next ID: 9, Previous field: completion_parts.
838 | *
839 | * @generated from message exa.language_server_pb.CompletionItem
840 | */
841 | export class CompletionItem extends Message {
842 | /**
843 | * @generated from field: exa.codeium_common_pb.Completion completion = 1;
844 | */
845 | completion?: Completion;
846 |
847 | /**
848 | * @generated from field: exa.language_server_pb.Suffix suffix = 5;
849 | */
850 | suffix?: Suffix;
851 |
852 | /**
853 | * @generated from field: exa.language_server_pb.Range range = 2;
854 | */
855 | range?: Range;
856 |
857 | /**
858 | * @generated from field: exa.codeium_common_pb.CompletionSource source = 3;
859 | */
860 | source = CompletionSource.UNSPECIFIED;
861 |
862 | /**
863 | * @generated from field: repeated exa.language_server_pb.CompletionPart completion_parts = 8;
864 | */
865 | completionParts: CompletionPart[] = [];
866 |
867 | constructor(data?: PartialMessage) {
868 | super();
869 | proto3.util.initPartial(data, this);
870 | }
871 |
872 | static readonly runtime: typeof proto3 = proto3;
873 | static readonly typeName = "exa.language_server_pb.CompletionItem";
874 | static readonly fields: FieldList = proto3.util.newFieldList(() => [
875 | { no: 1, name: "completion", kind: "message", T: Completion },
876 | { no: 5, name: "suffix", kind: "message", T: Suffix },
877 | { no: 2, name: "range", kind: "message", T: Range },
878 | { no: 3, name: "source", kind: "enum", T: proto3.getEnumType(CompletionSource) },
879 | { no: 8, name: "completion_parts", kind: "message", T: CompletionPart, repeated: true },
880 | ]);
881 |
882 | static fromBinary(bytes: Uint8Array, options?: Partial): CompletionItem {
883 | return new CompletionItem().fromBinary(bytes, options);
884 | }
885 |
886 | static fromJson(jsonValue: JsonValue, options?: Partial): CompletionItem {
887 | return new CompletionItem().fromJson(jsonValue, options);
888 | }
889 |
890 | static fromJsonString(jsonString: string, options?: Partial): CompletionItem {
891 | return new CompletionItem().fromJsonString(jsonString, options);
892 | }
893 |
894 | static equals(a: CompletionItem | PlainMessage | undefined, b: CompletionItem | PlainMessage | undefined): boolean {
895 | return proto3.util.equals(CompletionItem, a, b);
896 | }
897 | }
898 |
899 |
--------------------------------------------------------------------------------
/src/codeium.ts:
--------------------------------------------------------------------------------
1 | import { createPromiseClient } from "@connectrpc/connect";
2 | import { LanguageServerService } from "./api/proto/exa/language_server_pb/language_server_connect.js";
3 | import { createConnectTransport } from "@connectrpc/connect-web";
4 | import type {
5 | Document,
6 | GetCompletionsResponse,
7 | } from "./api/proto/exa/language_server_pb/language_server_pb.js";
8 | import type { CodeiumConfig } from "./config.js";
9 | import type { PartialMessage } from "@bufbuild/protobuf";
10 | import type { SimpleChangeSpec } from "./types.js";
11 |
12 | // This is the same as the monaco editor example
13 | const transport = createConnectTransport({
14 | baseUrl: "https://web-backend.codeium.com",
15 | useBinaryFormat: true,
16 | });
17 |
18 | const client = createPromiseClient(LanguageServerService, transport);
19 |
20 | let sessionId: string;
21 | try {
22 | /**
23 | * Note that this won't be available in 'insecure contexts',
24 | * websites served under HTTP not HTTPS, but those are rare.
25 | * And it'll work in localhost for development.
26 | */
27 | sessionId = crypto.randomUUID();
28 | } catch {
29 | // When not in a secure context
30 | // https://stackoverflow.com/questions/105034/how-do-i-create-a-guid-uuid
31 | function uuidv4() {
32 | return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, c =>
33 | (+c ^ (crypto.getRandomValues(new Uint8Array(1))[0] ?? 0) & 15 >> +c / 4).toString(16)
34 | );
35 | }
36 | sessionId = uuidv4();
37 | }
38 |
39 | export async function getCodeiumCompletions({
40 | text,
41 | cursorOffset,
42 | config,
43 | otherDocuments,
44 | }: {
45 | text: string;
46 | cursorOffset: number;
47 | config: CodeiumConfig;
48 | otherDocuments: PartialMessage[];
49 | }) {
50 | return (await client.getCompletions(
51 | {
52 | metadata: {
53 | ideName: "web",
54 | ideVersion: "0.0.5",
55 | extensionName: "@valtown/codemirror-codeium",
56 | extensionVersion: "1.0.0",
57 | apiKey: config.apiKey,
58 | sessionId: sessionId,
59 | authSource: config.authSource,
60 | },
61 | document: {
62 | text: text,
63 | cursorOffset: BigInt(cursorOffset),
64 | language: config.language,
65 | // TODO: not sure why we have both language and
66 | // editorlanguage
67 | // The types don't like this here, but it works.
68 | editorLanguage: "typescript",
69 | lineEnding: "\n",
70 | },
71 | editorOptions: {
72 | tabSize: 2n,
73 | insertSpaces: true,
74 | },
75 | otherDocuments: otherDocuments,
76 | multilineConfig: undefined,
77 | },
78 | {
79 | // signal,
80 | headers: {
81 | Authorization: `Basic ${config.apiKey}-${sessionId}`,
82 | },
83 | },
84 | // TODO: why doesn't this work by default?
85 | )) as GetCompletionsResponse;
86 | }
87 |
88 | /**
89 | * Make the body of the response a bit easier to work with:
90 | * turn a BigInt into an int in the response so that it can
91 | * be used with CodeMirror directly, and avoid using some
92 | * complex kinds of completions.
93 | */
94 | export function completionsToChangeSpec(
95 | completions: GetCompletionsResponse,
96 | ): SimpleChangeSpec[][] {
97 | return completions.completionItems.map((item) => {
98 | /**
99 | * Add absolute offsets for the suggestion text insertions
100 | * so that we can add matching decorations.
101 | */
102 | let combinedOffset = 0;
103 | return item.completionParts
104 | .filter((part) => {
105 | // Type 3 overwrites existing text. Maybe we need this eventually,
106 | // but not right now and it usually is duplicative.
107 | return part.type !== 3;
108 | })
109 | .map((part): SimpleChangeSpec => {
110 | const offset = Number(part.offset);
111 | const text = part.type === 2 ? `\n${part.text}` : part.text;
112 | const res: SimpleChangeSpec = {
113 | absoluteStartPos: combinedOffset + offset,
114 | absoluteEndPos: combinedOffset + offset + text.length,
115 | from: offset,
116 | to: offset,
117 | insert: text,
118 | };
119 | combinedOffset += text.length;
120 | return res;
121 | });
122 | });
123 | }
124 |
--------------------------------------------------------------------------------
/src/commands.ts:
--------------------------------------------------------------------------------
1 | import { Transaction, EditorSelection, ChangeSet } from "@codemirror/state";
2 | import type { Command, EditorView } from "@codemirror/view";
3 | import { copilotEvent, copilotIgnore } from "./annotations.js";
4 | import { completionDecoration } from "./completionDecoration.js";
5 | import {
6 | acceptSuggestion,
7 | addSuggestions,
8 | clearSuggestion,
9 | } from "./effects.js";
10 | import { requestCompletion } from "./requestCompletion.js";
11 |
12 | /**
13 | * Accepting a suggestion: we remove the ghost text, which
14 | * was not part of CodeMirror history, and then re-add it,
15 | * making sure that it _is_ added to history, and we remove
16 | * the Decoration that was making that ghost text look ghostly.
17 | */
18 | export function acceptSuggestionCommand(view: EditorView) {
19 | // We delete the ghost text and insert the suggestion.
20 | // We also set the cursor to the end of the suggestion.
21 | const stateField = view.state.field(completionDecoration);
22 |
23 | if (!stateField) {
24 | return false;
25 | }
26 |
27 | const reverseReverseChangeSet = stateField.reverseChangeSet?.invert(
28 | view.state.doc,
29 | );
30 |
31 | // This is removing the previous ghost text.
32 | view.dispatch({
33 | changes: stateField.reverseChangeSet,
34 | effects: acceptSuggestion.of(null),
35 | annotations: [
36 | // Tell upstream integrations to ignore this
37 | // change.
38 | copilotIgnore.of(null),
39 | // Tell ourselves not to request a completion
40 | // because of this change.
41 | copilotEvent.of(null),
42 | // Don't add this to history.
43 | Transaction.addToHistory.of(false),
44 | ],
45 | });
46 |
47 | let lastIndex = 0;
48 | reverseReverseChangeSet?.iterChangedRanges((_fromA, _toA, _fromB, toB) => {
49 | lastIndex = toB;
50 | });
51 |
52 | view.dispatch({
53 | changes: reverseReverseChangeSet,
54 | selection: EditorSelection.cursor(lastIndex),
55 | annotations: [copilotEvent.of(null), Transaction.addToHistory.of(true)],
56 | });
57 |
58 | return true;
59 | }
60 |
61 | /**
62 | * Cycle through suggested AI completed code.
63 | */
64 | export const nextSuggestionCommand: Command = (view: EditorView) => {
65 | const { state } = view;
66 | // We delete the suggestion, then carry through with the original keypress
67 | const stateField = state.field(completionDecoration);
68 |
69 | if (!stateField) {
70 | return false;
71 | }
72 |
73 | const { changeSpecs } = stateField;
74 |
75 | if (changeSpecs.length < 2) {
76 | return false;
77 | }
78 |
79 | // Loop through next suggestion.
80 | const index = (stateField.index + 1) % changeSpecs.length;
81 | const nextSpec = changeSpecs.at(index);
82 | if (!nextSpec) {
83 | return false;
84 | }
85 |
86 | /**
87 | * First, get the original document, by applying the stored
88 | * reverse changeset against the currently-displayed document.
89 | */
90 | const originalDocument = stateField.reverseChangeSet.apply(state.doc);
91 |
92 | /**
93 | * Get the changeset that we will apply that will
94 | *
95 | * 1. Reverse the currently-displayed suggestion, to get us back to
96 | * the original document
97 | * 2. Apply the next suggestion.
98 | *
99 | * It does both in the same changeset, so there is no flickering.
100 | */
101 | const reverseCurrentSuggestionAndApplyNext = ChangeSet.of(
102 | stateField.reverseChangeSet,
103 | state.doc.length,
104 | ).compose(ChangeSet.of(nextSpec, originalDocument.length));
105 |
106 | /**
107 | * Generate the next changeset
108 | */
109 | const nextSet = ChangeSet.of(nextSpec, originalDocument.length);
110 | const reverseChangeSet = nextSet.invert(originalDocument);
111 |
112 | view.dispatch({
113 | changes: reverseCurrentSuggestionAndApplyNext,
114 | effects: addSuggestions.of({
115 | index,
116 | reverseChangeSet,
117 | changeSpecs,
118 | }),
119 | annotations: [
120 | // Tell upstream integrations to ignore this
121 | // change.
122 | copilotIgnore.of(null),
123 | // Tell ourselves not to request a completion
124 | // because of this change.
125 | copilotEvent.of(null),
126 | // Don't add this to history.
127 | Transaction.addToHistory.of(false),
128 | ],
129 | });
130 |
131 | return true;
132 | };
133 |
134 | /**
135 | * Rejecting a suggestion: this looks at the currently-shown suggestion
136 | * and reverses it, clears the suggestion, and makes sure
137 | * that we don't add that clearing transaction to history and we don't
138 | * trigger a new suggestion because of it.
139 | */
140 | export function rejectSuggestionCommand(view: EditorView) {
141 | // We delete the suggestion, then carry through with the original keypress
142 | const stateField = view.state.field(completionDecoration);
143 |
144 | if (!stateField) {
145 | return false;
146 | }
147 |
148 | view.dispatch({
149 | changes: stateField.reverseChangeSet,
150 | effects: clearSuggestion.of(null),
151 | annotations: [
152 | // Tell upstream integrations to ignore this
153 | // change. This was never really in the document
154 | // in the first place - we were just showing ghost text.
155 | copilotIgnore.of(null),
156 | copilotEvent.of(null),
157 | Transaction.addToHistory.of(false),
158 | ],
159 | });
160 |
161 | return false;
162 | }
163 |
164 | // TODO: this isn't full reimplemented yet.
165 | export function sameKeyCommand(view: EditorView, key: string) {
166 | // When we type a key that is the same as the first letter of the suggestion, we delete the first letter of the suggestion and carry through with the original keypress
167 | const stateField = view.state.field(completionDecoration);
168 |
169 | if (!stateField) {
170 | return false;
171 | }
172 |
173 | if (key === "Tab") {
174 | return acceptSuggestionCommand(view);
175 | }
176 | return rejectSuggestionCommand(view);
177 | }
178 |
179 | export const startCompletion: Command = (view: EditorView) => {
180 | requestCompletion(view);
181 | return true;
182 | };
183 |
--------------------------------------------------------------------------------
/src/completionDecoration.ts:
--------------------------------------------------------------------------------
1 | import {
2 | StateField,
3 | type EditorState,
4 | type Transaction,
5 | } from "@codemirror/state";
6 | import { Decoration, EditorView } from "@codemirror/view";
7 | import {
8 | addSuggestions,
9 | acceptSuggestion,
10 | clearSuggestion,
11 | } from "./effects.js";
12 | import type { CompletionState } from "./types.js";
13 | import { codeiumConfig } from "./config.js";
14 |
15 | const ghostMark = Decoration.mark({ class: "cm-ghostText" });
16 |
17 | /**
18 | * Note that the completion _text_ is not actually a decoration!
19 | * The text is very real, and actually inserted into the editor.
20 | * The completion decoration is just a decoration that matches
21 | * the same range as the completion text, and changes how it looks.
22 | */
23 | export const completionDecoration = StateField.define({
24 | create(_state: EditorState) {
25 | return null;
26 | },
27 | update(state: CompletionState, transaction: Transaction) {
28 | const config = transaction.state.facet(codeiumConfig);
29 | for (const effect of transaction.effects) {
30 | if (effect.is(addSuggestions)) {
31 | const { changeSpecs, index } = effect.value;
32 |
33 | // NOTE: here we're adjusting the decoration range
34 | // to refer to locations in the document _after_ we've
35 | // inserted the text.
36 | const ranges = changeSpecs[index]!.map((suggestionRange) => {
37 | const range = ghostMark.range(
38 | suggestionRange.absoluteStartPos,
39 | suggestionRange.absoluteEndPos,
40 | );
41 | return range;
42 | });
43 | const widgetPos = ranges.at(-1)?.to;
44 |
45 | const decorations = Decoration.set([
46 | ...ranges,
47 | ...(widgetPos !== undefined &&
48 | changeSpecs.length > 1 &&
49 | config.widgetClass
50 | ? [
51 | Decoration.widget({
52 | widget: new config.widgetClass(index, changeSpecs.length),
53 | side: 1,
54 | }).range(widgetPos),
55 | ]
56 | : []),
57 | ]);
58 |
59 | return {
60 | index,
61 | decorations,
62 | changeSpecs,
63 | reverseChangeSet: effect.value.reverseChangeSet,
64 | };
65 | }
66 | if (effect.is(acceptSuggestion)) {
67 | return null;
68 | }
69 | if (effect.is(clearSuggestion)) {
70 | return null;
71 | }
72 | }
73 |
74 | if (state) {
75 | // If we ever have a state that is being updated,
76 | // map it through the new changes to avoid the potential
77 | // of a mismatch between it and the new document and new
78 | // document length
79 | return {
80 | ...state,
81 | decorations: state.decorations.map(transaction.changes),
82 | reverseChangeSet: state.reverseChangeSet.map(transaction.changes),
83 | };
84 | }
85 |
86 | return state;
87 | },
88 | provide: (field) =>
89 | EditorView.decorations.from(field, (value) => {
90 | return value?.decorations || Decoration.none;
91 | }),
92 | });
93 |
--------------------------------------------------------------------------------
/src/completionRequester.ts:
--------------------------------------------------------------------------------
1 | import { CompletionContext, completionStatus } from "@codemirror/autocomplete";
2 | import { EditorView, type ViewUpdate } from "@codemirror/view";
3 | import { acceptSuggestion, clearSuggestion } from "./effects.js";
4 | import { completionDecoration } from "./completionDecoration.js";
5 | import { copilotEvent } from "./annotations.js";
6 | import { codeiumConfig } from "./config.js";
7 | import { requestCompletion } from "./requestCompletion.js";
8 |
9 | /**
10 | * To request a completion, the document needs to have been
11 | * updated and the update should not have been because
12 | * of accepting or clearing a suggestion.
13 | */
14 | function shouldRequestCompletion(update: ViewUpdate) {
15 | return (
16 | update.docChanged &&
17 | !update.transactions.some((tr) =>
18 | tr.effects.some((e) => e.is(acceptSuggestion) || e.is(clearSuggestion)),
19 | )
20 | );
21 | }
22 |
23 | /**
24 | * Don't request a completion if we've already
25 | * done so, or it's a copilot event we're responding
26 | * to, or if the view is not focused.
27 | */
28 | function shouldIgnoreUpdate(update: ViewUpdate) {
29 | // not focused
30 | if (!update.view.hasFocus) return true;
31 |
32 | // contains ghost text
33 | if (update.state.field(completionDecoration)) return true;
34 |
35 | // is autocompleting
36 | if (completionStatus(update.state) === "active") return true;
37 |
38 | // bad update
39 | for (const tr of update.transactions) {
40 | if (tr.annotation(copilotEvent) !== undefined) {
41 | return true;
42 | }
43 | }
44 | }
45 |
46 | /**
47 | * A view plugin that requests completions from the server after a delay
48 | */
49 | export function completionRequester() {
50 | let timeout: number | null = null;
51 | let lastPos = 0;
52 |
53 | return EditorView.updateListener.of((update: ViewUpdate) => {
54 | const config = update.view.state.facet(codeiumConfig);
55 | if (!config.alwaysOn) return;
56 |
57 | if (!shouldRequestCompletion(update)) return;
58 |
59 | // Cancel the previous timeout
60 | if (timeout) {
61 | clearTimeout(timeout);
62 | }
63 |
64 | if (shouldIgnoreUpdate(update)) {
65 | return;
66 | }
67 |
68 | // Get the current position and source
69 | const state = update.state;
70 | const pos = state.selection.main.head;
71 |
72 | // If we've configured a custom rule for when to show completions
73 | // and that rule says no, don't offer completions.
74 | if (
75 | config.shouldComplete &&
76 | !config.shouldComplete(
77 | new CompletionContext(update.view.state, pos, false),
78 | )
79 | ) {
80 | return;
81 | }
82 |
83 | // Set a new timeout to request completion
84 | timeout = setTimeout(async () => {
85 | // Check if the position has changed
86 | if (pos !== lastPos) return;
87 |
88 | await requestCompletion(update.view, lastPos);
89 | }, config.timeout);
90 |
91 | // Update the last position
92 | lastPos = pos;
93 | });
94 | }
95 |
--------------------------------------------------------------------------------
/src/config.ts:
--------------------------------------------------------------------------------
1 | import { Facet, combineConfig } from "@codemirror/state";
2 | import { Language } from "./api/proto/exa/codeium_common_pb/codeium_common_pb.js";
3 | import type { Document } from "./api/proto/exa/language_server_pb/language_server_pb.js";
4 | import type { PartialMessage } from "@bufbuild/protobuf";
5 | import type { CompletionContext } from "@codemirror/autocomplete";
6 | import { DefaultCycleWidget } from "./defaultCycleWidget.js";
7 |
8 | export interface CodeiumConfig {
9 | /**
10 | * Codeium API key
11 | */
12 | apiKey: string;
13 |
14 | /**
15 | * The programming language of the given document.
16 | */
17 | language?: Language;
18 | /**
19 | * Time in millseconds after typing to fetch
20 | * completions from codeium
21 | */
22 | timeout?: number;
23 |
24 | authSource?: number;
25 |
26 | /**
27 | * An optional method that lets you decide whether Codeium
28 | * should be triggered at a particular place in a document.
29 | *
30 | * Might be useful for if you're fighting with overlapping
31 | * autocomplete sources.
32 | */
33 | shouldComplete?: (context: CompletionContext) => boolean;
34 |
35 | /**
36 | * The class for the widget that is shown at the end a suggestion
37 | * when there are multiple suggestions to cycle through.
38 | */
39 | widgetClass?: typeof DefaultCycleWidget | null;
40 |
41 | /**
42 | * Always request completions after a delay
43 | */
44 | alwaysOn?: boolean;
45 | }
46 |
47 | export const codeiumConfig = Facet.define<
48 | CodeiumConfig,
49 | Required
50 | >({
51 | combine(configs) {
52 | return combineConfig>(
53 | configs,
54 | {
55 | language: Language.TYPESCRIPT,
56 | timeout: 150,
57 | widgetClass: DefaultCycleWidget,
58 | alwaysOn: true,
59 | },
60 | {},
61 | );
62 | },
63 | });
64 |
65 | type OtherDocuments = PartialMessage[];
66 |
67 | export interface CodeiumOtherDocumentsConfig {
68 | override?: () => Promise | OtherDocuments;
69 | }
70 |
71 | /**
72 | * Configuration for other documents included with the completion
73 | * request. Adding other documents helps you get more accurate
74 | * suggestions by adding context.
75 | */
76 | export const codeiumOtherDocumentsConfig = Facet.define<
77 | CodeiumOtherDocumentsConfig,
78 | Required
79 | >({
80 | combine(configs) {
81 | return combineConfig>(
82 | configs,
83 | {
84 | override: () => [],
85 | },
86 | {},
87 | );
88 | },
89 | });
90 |
--------------------------------------------------------------------------------
/src/defaultCycleWidget.ts:
--------------------------------------------------------------------------------
1 | import { WidgetType } from "@codemirror/view";
2 |
3 | /**
4 | * Shown at the end of a suggestion if there are multiple
5 | * suggestions to cycle through.
6 | */
7 | export class DefaultCycleWidget extends WidgetType {
8 | index: number;
9 | total: number;
10 |
11 | constructor(index: number, total: number) {
12 | super();
13 | this.index = index;
14 | this.total = total;
15 | }
16 |
17 | toDOM() {
18 | const wrap = document.createElement("span");
19 | wrap.setAttribute("aria-hidden", "true");
20 | wrap.className = "cm-codeium-cycle";
21 | const words = wrap.appendChild(document.createElement("span"));
22 | words.className = "cm-codeium-cycle-explanation";
23 | words.innerText = `${this.index + 1}/${this.total}`;
24 | const key = wrap.appendChild(document.createElement("button"));
25 | key.className = "cm-codeium-cycle-key";
26 | key.innerText = "→ (Ctrl ])";
27 | key.dataset.action = "codeium-cycle";
28 | return wrap;
29 | }
30 |
31 | ignoreEvent() {
32 | return false;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/effects.ts:
--------------------------------------------------------------------------------
1 | import { StateEffect } from "@codemirror/state";
2 | import type { AddSuggestionsState } from "./types.js";
3 |
4 | // Effects to tell StateEffect what to do with GhostText
5 | export const addSuggestions = StateEffect.define();
6 | export const acceptSuggestion = StateEffect.define();
7 | export const clearSuggestion = StateEffect.define();
8 |
--------------------------------------------------------------------------------
/src/plugin.ts:
--------------------------------------------------------------------------------
1 | import { EditorView, keymap, type ViewUpdate } from "@codemirror/view";
2 | import { type Extension, Prec } from "@codemirror/state";
3 | import { completionDecoration } from "./completionDecoration.js";
4 | import { completionRequester } from "./completionRequester.js";
5 | import {
6 | sameKeyCommand,
7 | rejectSuggestionCommand,
8 | acceptSuggestionCommand,
9 | nextSuggestionCommand,
10 | startCompletion,
11 | } from "./commands.js";
12 | import {
13 | type CodeiumConfig,
14 | type CodeiumOtherDocumentsConfig,
15 | codeiumConfig,
16 | codeiumOtherDocumentsConfig,
17 | } from "./config.js";
18 | import { Language } from "./api/proto/exa/codeium_common_pb/codeium_common_pb.js";
19 | import { copilotIgnore } from "./annotations.js";
20 |
21 | /**
22 | * Clicking a completion accepts it. This figures out
23 | * whether a given click event is within the completion's area.
24 | */
25 | function isDecorationClicked(view: EditorView): boolean {
26 | let inRange = false;
27 | const head = view.state.selection.asSingle().ranges.at(0)?.head;
28 | const stateField = view.state.field(completionDecoration);
29 | if (head !== undefined && stateField) {
30 | stateField.decorations?.between(head, head, () => {
31 | inRange = true;
32 | });
33 | return inRange;
34 | }
35 | return false;
36 | }
37 |
38 | /**
39 | * Handles the behavior in which if you have a completion like
40 | *
41 | * foo|bar
42 | *
43 | * (the cursor is at |) and you type an x, it rejects
44 | * the completion because that isn't part of the suggested
45 | * code.
46 | */
47 | function completionPlugin() {
48 | return EditorView.domEventHandlers({
49 | keydown(event, view) {
50 | // Ideally, we handle infighting between
51 | // the nextSuggestionCommand and this handler
52 | // by using precedence, but I can't get that to work
53 | // yet.
54 | if (event.key === "]" && event.ctrlKey) {
55 | return false;
56 | }
57 | if (
58 | event.key !== "Shift" &&
59 | event.key !== "Control" &&
60 | event.key !== "Alt" &&
61 | event.key !== "Meta"
62 | ) {
63 | return sameKeyCommand(view, event.key);
64 | }
65 | return false;
66 | },
67 | mouseup(event, view) {
68 | const target = event.target as HTMLElement;
69 | if (
70 | target.nodeName === "BUTTON" &&
71 | target.dataset.action === "codeium-cycle"
72 | ) {
73 | nextSuggestionCommand(view);
74 | event.stopPropagation();
75 | event.preventDefault();
76 | return true;
77 | }
78 | if (isDecorationClicked(view)) {
79 | return acceptSuggestionCommand(view);
80 | }
81 | return rejectSuggestionCommand(view);
82 | },
83 | });
84 | }
85 |
86 | /**
87 | * Next completion map
88 | */
89 | function nextCompletionPlugin() {
90 | return keymap.of([
91 | {
92 | key: "Ctrl-]",
93 | run: nextSuggestionCommand,
94 | },
95 | ]);
96 | }
97 |
98 | /**
99 | * Changing the editor's focus - blurring it by clicking outside -
100 | * rejects the suggestion
101 | */
102 | function viewCompletionPlugin() {
103 | return EditorView.updateListener.of((update) => {
104 | if (update.focusChanged) {
105 | rejectSuggestionCommand(update.view);
106 | }
107 | });
108 | }
109 |
110 | export {
111 | Language,
112 | copilotIgnore,
113 | codeiumConfig,
114 | codeiumOtherDocumentsConfig,
115 | nextSuggestionCommand,
116 | startCompletion,
117 | type CodeiumOtherDocumentsConfig,
118 | type CodeiumConfig,
119 | };
120 |
121 | /**
122 | * A combination of configuration, the keymap, the
123 | * requester - as a composite extension for simplicity.
124 | */
125 | export function copilotPlugin(config: CodeiumConfig): Extension {
126 | return [
127 | codeiumConfig.of(config),
128 | completionDecoration,
129 | Prec.highest(nextCompletionPlugin()),
130 | Prec.highest(viewCompletionPlugin()),
131 | Prec.high(completionPlugin()),
132 | completionRequester(),
133 | ];
134 | }
135 |
136 | /**
137 | * Returns false if this ViewUpdate is just the plugin
138 | * adding or removing ghost text, and it should not be
139 | * considered when saving this CodeMirror state into other
140 | * systems, like draft recovery.
141 | */
142 | export function shouldTakeUpdate(update: ViewUpdate) {
143 | for (const tr of update.transactions) {
144 | if (tr.annotation(copilotIgnore) !== undefined) {
145 | return false;
146 | }
147 | }
148 | return true;
149 | }
150 |
--------------------------------------------------------------------------------
/src/requestCompletion.ts:
--------------------------------------------------------------------------------
1 | import { completionStatus } from "@codemirror/autocomplete";
2 | import { ChangeSet, Transaction } from "@codemirror/state";
3 | import type { EditorView } from "@codemirror/view";
4 | import { completionsToChangeSpec, getCodeiumCompletions } from "./codeium.js";
5 | import { addSuggestions } from "./effects.js";
6 | import { copilotEvent, copilotIgnore } from "./annotations.js";
7 | import { codeiumConfig, codeiumOtherDocumentsConfig } from "./config.js";
8 |
9 | /**
10 | * Inner 'requestCompletion' API, which can optionally
11 | * be run all the time if you set `alwaysOn`
12 | */
13 | export async function requestCompletion(view: EditorView, lastPos?: number) {
14 | const config = view.state.facet(codeiumConfig);
15 | const { override } = view.state.facet(codeiumOtherDocumentsConfig);
16 |
17 | const otherDocuments = await override();
18 |
19 | // Get the current position and source
20 | const state = view.state;
21 | const pos = state.selection.main.head;
22 | const source = state.doc.toString();
23 |
24 | // Request completion from the server
25 | try {
26 | const completionResult = await getCodeiumCompletions({
27 | text: source,
28 | cursorOffset: pos,
29 | config,
30 | otherDocuments,
31 | });
32 |
33 | if (!completionResult || completionResult.completionItems.length === 0) {
34 | return;
35 | }
36 |
37 | // Check if the position is still the same. If
38 | // it has changed, ignore the code that we just
39 | // got from the API and don't show anything.
40 | if (
41 | !(
42 | (lastPos === undefined || pos === lastPos) &&
43 | completionStatus(view.state) !== "active" &&
44 | view.hasFocus
45 | )
46 | ) {
47 | return;
48 | }
49 |
50 | // Dispatch an effect to add the suggestion
51 | // If the completion starts before the end of the line,
52 | // check the end of the line with the end of the completion
53 | const changeSpecs = completionsToChangeSpec(completionResult);
54 |
55 | const index = 0;
56 | const firstSpec = changeSpecs.at(index);
57 | if (!firstSpec) return;
58 | const insertChangeSet = ChangeSet.of(firstSpec, state.doc.length);
59 | const reverseChangeSet = insertChangeSet.invert(state.doc);
60 |
61 | view.dispatch({
62 | changes: insertChangeSet,
63 | effects: addSuggestions.of({
64 | index,
65 | reverseChangeSet,
66 | changeSpecs,
67 | }),
68 | annotations: [
69 | copilotIgnore.of(null),
70 | copilotEvent.of(null),
71 | Transaction.addToHistory.of(false),
72 | ],
73 | });
74 | } catch (error) {
75 | console.warn("copilot completion failed", error);
76 | // Javascript wait for 300ms for some reason is necessary here.
77 | // TODO - FIGURE OUT WHY THIS RESOLVES THE BUG
78 |
79 | await new Promise((resolve) => setTimeout(resolve, 300));
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/types.ts:
--------------------------------------------------------------------------------
1 | import type { Range, ChangeSet } from "@codemirror/state";
2 | import type { Decoration, DecorationSet } from "@codemirror/view";
3 |
4 | /**
5 | * We dispatch an effect that updates the CompletionState.
6 | * CompletionState is null if no completions are displayed.
7 | */
8 | export type CompletionState = null | {
9 | index: number;
10 | reverseChangeSet: ChangeSet;
11 | changeSpecs: SimpleChangeSpec[][];
12 | decorations: DecorationSet;
13 | };
14 |
15 | export type AddSuggestionsState = {
16 | reverseChangeSet: ChangeSet;
17 | changeSpecs: SimpleChangeSpec[][];
18 | index: number;
19 | };
20 |
21 | export interface GhostText {
22 | text: string;
23 | displayPos: number;
24 | startPos: number;
25 | endGhostText: number;
26 | endPos: number;
27 | decorations: DecorationSet;
28 | }
29 |
30 | /**
31 | * This is one of the variants of a ChangeSpec,
32 | * plus the absoluteStartPos and absoluteEndPos
33 | * properties.
34 | */
35 | export type SimpleChangeSpec = {
36 | absoluteStartPos: number;
37 | absoluteEndPos: number;
38 | from: number;
39 | to: number;
40 | insert: string;
41 | };
42 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "declaration": true,
4 | "declarationMap": true,
5 | "esModuleInterop": true,
6 | "forceConsistentCasingInFileNames": true,
7 | "inlineSources": true,
8 | "jsx": "react",
9 | "module": "nodenext",
10 | "moduleResolution": "nodenext",
11 | "noUncheckedIndexedAccess": true,
12 | "resolveJsonModule": true,
13 | "skipLibCheck": true,
14 | "sourceMap": true,
15 | "strict": true,
16 | "target": "es2022",
17 | "rootDir": "./src",
18 | "outDir": "./dist"
19 | },
20 | "exclude": ["./demo", "./dist"]
21 | }
22 |
--------------------------------------------------------------------------------
/vite.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('vite').UserConfig} */
2 | export default {
3 | root: process.env.VITEST ? "." : "demo",
4 | outDir: "build",
5 | base: "/codemirror-codeium/",
6 | };
7 |
--------------------------------------------------------------------------------