nightona 0.191.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +22 -0
- data/.ruby-version +1 -0
- data/CODE_OF_CONDUCT.md +132 -0
- data/LICENSE +190 -0
- data/README.md +184 -0
- data/Rakefile +12 -0
- data/lib/nightona/code_interpreter.rb +359 -0
- data/lib/nightona/common/charts.rb +124 -0
- data/lib/nightona/common/code_interpreter.rb +56 -0
- data/lib/nightona/common/code_language.rb +14 -0
- data/lib/nightona/common/file_system.rb +26 -0
- data/lib/nightona/common/git.rb +19 -0
- data/lib/nightona/common/image.rb +500 -0
- data/lib/nightona/common/nightona.rb +230 -0
- data/lib/nightona/common/process.rb +149 -0
- data/lib/nightona/common/pty.rb +309 -0
- data/lib/nightona/common/resources.rb +39 -0
- data/lib/nightona/common/response.rb +83 -0
- data/lib/nightona/common/snapshot.rb +124 -0
- data/lib/nightona/computer_use.rb +919 -0
- data/lib/nightona/config.rb +116 -0
- data/lib/nightona/file_system.rb +451 -0
- data/lib/nightona/file_transfer.rb +383 -0
- data/lib/nightona/git.rb +334 -0
- data/lib/nightona/lsp_server.rb +139 -0
- data/lib/nightona/nightona.rb +336 -0
- data/lib/nightona/object_storage.rb +172 -0
- data/lib/nightona/otel.rb +183 -0
- data/lib/nightona/process.rb +550 -0
- data/lib/nightona/sandbox.rb +751 -0
- data/lib/nightona/sdk/version.rb +10 -0
- data/lib/nightona/sdk.rb +56 -0
- data/lib/nightona/snapshot_service.rb +238 -0
- data/lib/nightona/util.rb +80 -0
- data/lib/nightona/volume.rb +46 -0
- data/lib/nightona/volume_service.rb +61 -0
- data/lib/nightona.rb +10 -0
- data/project.json +100 -0
- data/scripts/generate-docs.rb +402 -0
- data/sig/nightona/sdk.rbs +6 -0
- metadata +242 -0
data/lib/nightona/git.rb
ADDED
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
# Copyright Daytona Platforms Inc.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
# frozen_string_literal: true
|
|
5
|
+
|
|
6
|
+
module Nightona
|
|
7
|
+
class Git
|
|
8
|
+
include Instrumentation
|
|
9
|
+
|
|
10
|
+
# @return [String] The Sandbox ID
|
|
11
|
+
attr_reader :sandbox_id
|
|
12
|
+
|
|
13
|
+
# @return [NightonaToolboxApiClient::GitApi] API client for Sandbox operations
|
|
14
|
+
attr_reader :toolbox_api
|
|
15
|
+
|
|
16
|
+
# Initializes a new Git handler instance.
|
|
17
|
+
#
|
|
18
|
+
# @param sandbox_id [String] The Sandbox ID.
|
|
19
|
+
# @param toolbox_api [NightonaToolboxApiClient::GitApi] API client for Sandbox operations.
|
|
20
|
+
# @param otel_state [Nightona::OtelState, nil]
|
|
21
|
+
def initialize(sandbox_id:, toolbox_api:, otel_state: nil)
|
|
22
|
+
@sandbox_id = sandbox_id
|
|
23
|
+
@toolbox_api = toolbox_api
|
|
24
|
+
@otel_state = otel_state
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Stages the specified files for the next commit, similar to
|
|
28
|
+
# running 'git add' on the command line.
|
|
29
|
+
#
|
|
30
|
+
# @param path [String] Path to the Git repository root. Relative paths are resolved based on
|
|
31
|
+
# the sandbox working directory.
|
|
32
|
+
# @param files [Array<String>] List of file paths or directories to stage, relative to the repository root.
|
|
33
|
+
# @return [void]
|
|
34
|
+
# @raise [Nightona::Sdk::Error] if adding files fails
|
|
35
|
+
#
|
|
36
|
+
# @example
|
|
37
|
+
# # Stage a single file
|
|
38
|
+
# sandbox.git.add("workspace/repo", ["file.txt"])
|
|
39
|
+
#
|
|
40
|
+
# # Stage multiple files
|
|
41
|
+
# sandbox.git.add("workspace/repo", [
|
|
42
|
+
# "src/main.rb",
|
|
43
|
+
# "spec/main_spec.rb",
|
|
44
|
+
# "README.md"
|
|
45
|
+
# ])
|
|
46
|
+
def add(path, files)
|
|
47
|
+
toolbox_api.add_files(NightonaToolboxApiClient::GitAddRequest.new(path:, files:))
|
|
48
|
+
rescue NightonaToolboxApiClient::ApiError => e
|
|
49
|
+
raise map_api_error(e, 'Failed to add files')
|
|
50
|
+
rescue StandardError => e
|
|
51
|
+
raise Sdk::Error, "Failed to add files: #{e.message}"
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Lists branches in the repository.
|
|
55
|
+
#
|
|
56
|
+
# @param path [String] Path to the Git repository root. Relative paths are resolved based on
|
|
57
|
+
# the sandbox working directory.
|
|
58
|
+
# @return [NightonaApiClient::ListBranchResponse] List of branches in the repository.
|
|
59
|
+
# @raise [Nightona::Sdk::Error] if listing branches fails
|
|
60
|
+
#
|
|
61
|
+
# @example
|
|
62
|
+
# response = sandbox.git.branches("workspace/repo")
|
|
63
|
+
# puts "Branches: #{response.branches}"
|
|
64
|
+
def branches(path)
|
|
65
|
+
toolbox_api.list_branches(path)
|
|
66
|
+
rescue NightonaToolboxApiClient::ApiError => e
|
|
67
|
+
raise map_api_error(e, 'Failed to list branches')
|
|
68
|
+
rescue StandardError => e
|
|
69
|
+
raise Sdk::Error, "Failed to list branches: #{e.message}"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Clones a Git repository into the specified path. It supports
|
|
73
|
+
# cloning specific branches or commits, and can authenticate with the remote
|
|
74
|
+
# repository if credentials are provided.
|
|
75
|
+
#
|
|
76
|
+
# @param url [String] Repository URL to clone from.
|
|
77
|
+
# @param path [String] Path where the repository should be cloned. Relative paths are resolved
|
|
78
|
+
# based on the sandbox working directory.
|
|
79
|
+
# @param branch [String, nil] Specific branch to clone. If not specified,
|
|
80
|
+
# clones the default branch.
|
|
81
|
+
# @param commit_id [String, nil] Specific commit to clone. If specified,
|
|
82
|
+
# the repository will be left in a detached HEAD state at this commit.
|
|
83
|
+
# @param username [String, nil] Git username for authentication.
|
|
84
|
+
# @param password [String, nil] Git password or token for authentication.
|
|
85
|
+
# @param insecure_skip_tls [Boolean, nil] Skip TLS certificate verification (insecure).
|
|
86
|
+
# Use only for trusted internal Git servers with self-signed or private-CA certs;
|
|
87
|
+
# credentials, if supplied, are transmitted over an unverified TLS connection.
|
|
88
|
+
# @return [void]
|
|
89
|
+
# @raise [Nightona::Sdk::Error] if cloning repository fails
|
|
90
|
+
#
|
|
91
|
+
# @example
|
|
92
|
+
# # Clone the default branch
|
|
93
|
+
# sandbox.git.clone(
|
|
94
|
+
# url: "https://github.com/user/repo.git",
|
|
95
|
+
# path: "workspace/repo"
|
|
96
|
+
# )
|
|
97
|
+
#
|
|
98
|
+
# # Clone a specific branch with authentication
|
|
99
|
+
# sandbox.git.clone(
|
|
100
|
+
# url: "https://github.com/user/private-repo.git",
|
|
101
|
+
# path: "workspace/private",
|
|
102
|
+
# branch: "develop",
|
|
103
|
+
# username: "user",
|
|
104
|
+
# password: "token"
|
|
105
|
+
# )
|
|
106
|
+
#
|
|
107
|
+
# # Clone a specific commit
|
|
108
|
+
# sandbox.git.clone(
|
|
109
|
+
# url: "https://github.com/user/repo.git",
|
|
110
|
+
# path: "workspace/repo-old",
|
|
111
|
+
# commit_id: "abc123"
|
|
112
|
+
# )
|
|
113
|
+
def clone(url:, path:, branch: nil, commit_id: nil, username: nil, password: nil, insecure_skip_tls: nil) # rubocop:disable Metrics/MethodLength, Metrics/ParameterLists
|
|
114
|
+
toolbox_api.clone_repository(
|
|
115
|
+
NightonaToolboxApiClient::GitCloneRequest.new(
|
|
116
|
+
url: url,
|
|
117
|
+
branch: branch,
|
|
118
|
+
path: path,
|
|
119
|
+
username: username,
|
|
120
|
+
password: password,
|
|
121
|
+
commit_id: commit_id,
|
|
122
|
+
insecure_skip_tls: insecure_skip_tls
|
|
123
|
+
)
|
|
124
|
+
)
|
|
125
|
+
rescue NightonaToolboxApiClient::ApiError => e
|
|
126
|
+
raise map_api_error(e, 'Failed to clone repository')
|
|
127
|
+
rescue StandardError => e
|
|
128
|
+
raise Sdk::Error, "Failed to clone repository: #{e.message}"
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Creates a new commit with the staged changes. Make sure to stage
|
|
132
|
+
# changes using the add() method before committing.
|
|
133
|
+
#
|
|
134
|
+
# @param path [String] Path to the Git repository root. Relative paths are resolved based on
|
|
135
|
+
# the sandbox working directory.
|
|
136
|
+
# @param message [String] Commit message describing the changes.
|
|
137
|
+
# @param author [String] Name of the commit author.
|
|
138
|
+
# @param email [String] Email address of the commit author.
|
|
139
|
+
# @param allow_empty [Boolean] Allow creating an empty commit when no changes are staged. Defaults to false.
|
|
140
|
+
# @return [GitCommitResponse] Response containing the commit SHA.
|
|
141
|
+
# @raise [Nightona::Sdk::Error] if committing changes fails
|
|
142
|
+
#
|
|
143
|
+
# @example
|
|
144
|
+
# # Stage and commit changes
|
|
145
|
+
# sandbox.git.add("workspace/repo", ["README.md"])
|
|
146
|
+
# commit_response = sandbox.git.commit(
|
|
147
|
+
# path: "workspace/repo",
|
|
148
|
+
# message: "Update documentation",
|
|
149
|
+
# author: "John Doe",
|
|
150
|
+
# email: "john@example.com",
|
|
151
|
+
# allow_empty: true
|
|
152
|
+
# )
|
|
153
|
+
# puts "Commit SHA: #{commit_response.sha}"
|
|
154
|
+
def commit(path:, message:, author:, email:, allow_empty: false)
|
|
155
|
+
response = toolbox_api.commit_changes(
|
|
156
|
+
NightonaToolboxApiClient::GitCommitRequest.new(path:, message:, author:, email:, allow_empty:)
|
|
157
|
+
)
|
|
158
|
+
GitCommitResponse.new(sha: response._hash)
|
|
159
|
+
rescue NightonaToolboxApiClient::ApiError => e
|
|
160
|
+
raise map_api_error(e, 'Failed to commit changes')
|
|
161
|
+
rescue StandardError => e
|
|
162
|
+
raise Sdk::Error, "Failed to commit changes: #{e.message}"
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# Pushes all local commits on the current branch to the remote
|
|
166
|
+
# repository. If the remote repository requires authentication, provide
|
|
167
|
+
# username and password/token.
|
|
168
|
+
#
|
|
169
|
+
# @param path [String] Path to the Git repository root. Relative paths are resolved based on
|
|
170
|
+
# the sandbox working directory.
|
|
171
|
+
# @param username [String, nil] Git username for authentication.
|
|
172
|
+
# @param password [String, nil] Git password or token for authentication.
|
|
173
|
+
# @return [void]
|
|
174
|
+
# @raise [Nightona::Sdk::Error] if pushing changes fails
|
|
175
|
+
#
|
|
176
|
+
# @example
|
|
177
|
+
# # Push without authentication (for public repos or SSH)
|
|
178
|
+
# sandbox.git.push("workspace/repo")
|
|
179
|
+
#
|
|
180
|
+
# # Push with authentication
|
|
181
|
+
# sandbox.git.push(
|
|
182
|
+
# path: "workspace/repo",
|
|
183
|
+
# username: "user",
|
|
184
|
+
# password: "github_token"
|
|
185
|
+
# )
|
|
186
|
+
def push(path:, username: nil, password: nil)
|
|
187
|
+
toolbox_api.push_changes(
|
|
188
|
+
NightonaToolboxApiClient::GitRepoRequest.new(path:, username:, password:)
|
|
189
|
+
)
|
|
190
|
+
rescue NightonaToolboxApiClient::ApiError => e
|
|
191
|
+
raise map_api_error(e, 'Failed to push changes')
|
|
192
|
+
rescue StandardError => e
|
|
193
|
+
raise Sdk::Error, "Failed to push changes: #{e.message}"
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# Pulls changes from the remote repository. If the remote repository requires authentication,
|
|
197
|
+
# provide username and password/token.
|
|
198
|
+
#
|
|
199
|
+
# @param path [String] Path to the Git repository root. Relative paths are resolved based on
|
|
200
|
+
# the sandbox working directory.
|
|
201
|
+
# @param username [String, nil] Git username for authentication.
|
|
202
|
+
# @param password [String, nil] Git password or token for authentication.
|
|
203
|
+
# @return [void]
|
|
204
|
+
# @raise [Nightona::Sdk::Error] if pulling changes fails
|
|
205
|
+
#
|
|
206
|
+
# @example
|
|
207
|
+
# # Pull without authentication
|
|
208
|
+
# sandbox.git.pull("workspace/repo")
|
|
209
|
+
#
|
|
210
|
+
# # Pull with authentication
|
|
211
|
+
# sandbox.git.pull(
|
|
212
|
+
# path: "workspace/repo",
|
|
213
|
+
# username: "user",
|
|
214
|
+
# password: "github_token"
|
|
215
|
+
# )
|
|
216
|
+
#
|
|
217
|
+
def pull(path:, username: nil, password: nil)
|
|
218
|
+
toolbox_api.pull_changes(
|
|
219
|
+
NightonaToolboxApiClient::GitRepoRequest.new(path:, username:, password:)
|
|
220
|
+
)
|
|
221
|
+
rescue NightonaToolboxApiClient::ApiError => e
|
|
222
|
+
raise map_api_error(e, 'Failed to pull changes')
|
|
223
|
+
rescue StandardError => e
|
|
224
|
+
raise Sdk::Error, "Failed to pull changes: #{e.message}"
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
# Gets the current Git repository status.
|
|
228
|
+
#
|
|
229
|
+
# @param path [String] Path to the Git repository root. Relative paths are resolved based on
|
|
230
|
+
# the sandbox working directory.
|
|
231
|
+
# @return [NightonaToolboxApiClient::GitStatus] Repository status information including:
|
|
232
|
+
# @raise [Nightona::Sdk::Error] if getting status fails
|
|
233
|
+
#
|
|
234
|
+
# @example
|
|
235
|
+
# status = sandbox.git.status("workspace/repo")
|
|
236
|
+
# puts "On branch: #{status.current_branch}"
|
|
237
|
+
# puts "Commits ahead: #{status.ahead}"
|
|
238
|
+
# puts "Commits behind: #{status.behind}"
|
|
239
|
+
def status(path)
|
|
240
|
+
toolbox_api.get_status(path)
|
|
241
|
+
rescue NightonaToolboxApiClient::ApiError => e
|
|
242
|
+
raise map_api_error(e, 'Failed to get status')
|
|
243
|
+
rescue StandardError => e
|
|
244
|
+
raise Sdk::Error, "Failed to get status: #{e.message}"
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
# Checkout branch in the repository.
|
|
248
|
+
#
|
|
249
|
+
# @param path [String] Path to the Git repository root. Relative paths are resolved based on
|
|
250
|
+
# the sandbox working directory.
|
|
251
|
+
# @param branch [String] Name of the branch to checkout
|
|
252
|
+
# @return [void]
|
|
253
|
+
# @raise [Nightona::Sdk::Error] if checking out branch fails
|
|
254
|
+
#
|
|
255
|
+
# @example
|
|
256
|
+
# # Checkout a branch
|
|
257
|
+
# sandbox.git.checkout_branch("workspace/repo", "feature-branch")
|
|
258
|
+
def checkout_branch(path, branch)
|
|
259
|
+
toolbox_api.checkout_branch(
|
|
260
|
+
NightonaToolboxApiClient::GitCheckoutRequest.new(path:, branch:)
|
|
261
|
+
)
|
|
262
|
+
rescue NightonaToolboxApiClient::ApiError => e
|
|
263
|
+
raise map_api_error(e, 'Failed to checkout branch')
|
|
264
|
+
rescue StandardError => e
|
|
265
|
+
raise Sdk::Error, "Failed to checkout branch: #{e.message}"
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
# Create branch in the repository.
|
|
269
|
+
#
|
|
270
|
+
# @param path [String] Path to the Git repository root. Relative paths are resolved based on
|
|
271
|
+
# the sandbox working directory.
|
|
272
|
+
# @param name [String] Name of the new branch to create
|
|
273
|
+
# @return [void]
|
|
274
|
+
# @raise [Nightona::Sdk::Error] if creating branch fails
|
|
275
|
+
#
|
|
276
|
+
# @example
|
|
277
|
+
# # Create a new branch
|
|
278
|
+
# sandbox.git.create_branch("workspace/repo", "new-feature")
|
|
279
|
+
#
|
|
280
|
+
def create_branch(path, name)
|
|
281
|
+
toolbox_api.create_branch(
|
|
282
|
+
NightonaToolboxApiClient::GitBranchRequest.new(path:, name:)
|
|
283
|
+
)
|
|
284
|
+
rescue NightonaToolboxApiClient::ApiError => e
|
|
285
|
+
raise map_api_error(e, 'Failed to create branch')
|
|
286
|
+
rescue StandardError => e
|
|
287
|
+
raise Sdk::Error, "Failed to create branch: #{e.message}"
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
# Delete branch in the repository.
|
|
291
|
+
#
|
|
292
|
+
# @param path [String] Path to the Git repository root. Relative paths are resolved based on
|
|
293
|
+
# the sandbox working directory.
|
|
294
|
+
# @param name [String] Name of the branch to delete
|
|
295
|
+
# @return [void]
|
|
296
|
+
# @raise [Nightona::Sdk::Error] if deleting branch fails
|
|
297
|
+
#
|
|
298
|
+
# @example
|
|
299
|
+
# # Delete a branch
|
|
300
|
+
# sandbox.git.delete_branch("workspace/repo", "old-feature")
|
|
301
|
+
def delete_branch(path, name)
|
|
302
|
+
toolbox_api.delete_branch(
|
|
303
|
+
NightonaToolboxApiClient::GitDeleteBranchRequest.new(path:, name:)
|
|
304
|
+
)
|
|
305
|
+
rescue NightonaToolboxApiClient::ApiError => e
|
|
306
|
+
raise map_api_error(e, 'Failed to delete branch')
|
|
307
|
+
rescue StandardError => e
|
|
308
|
+
raise Sdk::Error, "Failed to delete branch: #{e.message}"
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
instrument :add, :branches, :clone, :commit, :push, :pull, :status,
|
|
312
|
+
:checkout_branch, :create_branch, :delete_branch,
|
|
313
|
+
component: 'Git'
|
|
314
|
+
|
|
315
|
+
private
|
|
316
|
+
|
|
317
|
+
# @return [Nightona::OtelState, nil]
|
|
318
|
+
attr_reader :otel_state
|
|
319
|
+
|
|
320
|
+
def map_api_error(api_error, prefix)
|
|
321
|
+
msg = "#{prefix}: #{api_error.message}"
|
|
322
|
+
case api_error.code
|
|
323
|
+
when 400 then Sdk::ValidationError.new(msg)
|
|
324
|
+
when 401 then Sdk::AuthenticationError.new(msg)
|
|
325
|
+
when 403 then Sdk::ForbiddenError.new(msg)
|
|
326
|
+
when 404 then Sdk::NotFoundError.new(msg)
|
|
327
|
+
when 409 then Sdk::ConflictError.new(msg)
|
|
328
|
+
when 429 then Sdk::RateLimitError.new(msg)
|
|
329
|
+
when 500..599 then Sdk::ServerError.new(msg)
|
|
330
|
+
else Sdk::Error.new(msg)
|
|
331
|
+
end
|
|
332
|
+
end
|
|
333
|
+
end
|
|
334
|
+
end
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# Copyright Daytona Platforms Inc.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
# frozen_string_literal: true
|
|
5
|
+
|
|
6
|
+
module Nightona
|
|
7
|
+
class LspServer
|
|
8
|
+
include Instrumentation
|
|
9
|
+
|
|
10
|
+
module Language
|
|
11
|
+
ALL = [
|
|
12
|
+
JAVASCRIPT = :javascript,
|
|
13
|
+
PYTHON = :python,
|
|
14
|
+
TYPESCRIPT = :typescript
|
|
15
|
+
|
|
16
|
+
].freeze
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Represents a zero-based position in a text document,
|
|
20
|
+
# specified by line number and character offset.
|
|
21
|
+
Position = Data.define(:line, :character)
|
|
22
|
+
|
|
23
|
+
# @return [Symbol]
|
|
24
|
+
attr_reader :language_id
|
|
25
|
+
|
|
26
|
+
# @return [String]
|
|
27
|
+
attr_reader :path_to_project
|
|
28
|
+
|
|
29
|
+
# @return [NightonaToolboxApiClient::LspApi]
|
|
30
|
+
attr_reader :toolbox_api
|
|
31
|
+
|
|
32
|
+
# @return [String]
|
|
33
|
+
attr_reader :sandbox_id
|
|
34
|
+
|
|
35
|
+
# @param language_id [Symbol]
|
|
36
|
+
# @param path_to_project [String]
|
|
37
|
+
# @param toolbox_api [NightonaToolboxApiClient::LspApi]
|
|
38
|
+
# @param sandbox_id [String]
|
|
39
|
+
# @param otel_state [Nightona::OtelState, nil]
|
|
40
|
+
def initialize(language_id:, path_to_project:, toolbox_api:, sandbox_id:, otel_state: nil)
|
|
41
|
+
@language_id = language_id
|
|
42
|
+
@path_to_project = path_to_project
|
|
43
|
+
@toolbox_api = toolbox_api
|
|
44
|
+
@sandbox_id = sandbox_id
|
|
45
|
+
@otel_state = otel_state
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Gets completion suggestions at a position in a file
|
|
49
|
+
#
|
|
50
|
+
# @param path [String]
|
|
51
|
+
# @param position [Nightona::LspServer::Position]
|
|
52
|
+
# @return [NightonaApiClient::CompletionList]
|
|
53
|
+
def completions(path:, position:)
|
|
54
|
+
toolbox_api.completions(
|
|
55
|
+
NightonaToolboxApiClient::LspCompletionParams.new(
|
|
56
|
+
language_id:,
|
|
57
|
+
path_to_project:,
|
|
58
|
+
uri: uri(path),
|
|
59
|
+
position: NightonaApiClient::Position.new(line: position.line, character: position.character)
|
|
60
|
+
)
|
|
61
|
+
)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Notify the language server that a file has been closed.
|
|
65
|
+
# This method should be called when a file is closed in the editor to allow
|
|
66
|
+
# the language server to clean up any resources associated with that file.
|
|
67
|
+
#
|
|
68
|
+
# @param path [String]
|
|
69
|
+
# @return [void]
|
|
70
|
+
def did_close(path)
|
|
71
|
+
toolbox_api.did_close(
|
|
72
|
+
NightonaToolboxApiClient::LspDocumentRequest.new(language_id:, path_to_project:, uri: uri(path))
|
|
73
|
+
)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Notifies the language server that a file has been opened.
|
|
77
|
+
# This method should be called when a file is opened in the editor to enable
|
|
78
|
+
# language features like diagnostics and completions for that file. The server
|
|
79
|
+
# will begin tracking the file's contents and providing language features.
|
|
80
|
+
#
|
|
81
|
+
# @param path [String]
|
|
82
|
+
# @return [void]
|
|
83
|
+
def did_open(path)
|
|
84
|
+
toolbox_api.did_open(
|
|
85
|
+
NightonaToolboxApiClient::LspDocumentRequest.new(language_id:, path_to_project:, uri: uri(path))
|
|
86
|
+
)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Gets symbol information (functions, classes, variables, etc.) from a document.
|
|
90
|
+
#
|
|
91
|
+
# @param path [String]
|
|
92
|
+
# @return [Array<NightonaToolboxApiClient::LspSymbol]
|
|
93
|
+
def document_symbols(path) = toolbox_api.document_symbols(language_id, path_to_project, uri(path))
|
|
94
|
+
|
|
95
|
+
# Searches for symbols matching the query string across all files
|
|
96
|
+
# in the Sandbox.
|
|
97
|
+
#
|
|
98
|
+
# @param query [String]
|
|
99
|
+
# @return [Array<NightonaToolboxApiClient::LspSymbol]
|
|
100
|
+
def sandbox_symbols(query) = toolbox_api.workspace_symbols(query, language_id, path_to_project)
|
|
101
|
+
|
|
102
|
+
# Starts the language server.
|
|
103
|
+
# This method must be called before using any other LSP functionality.
|
|
104
|
+
# It initializes the language server for the specified language and project.
|
|
105
|
+
#
|
|
106
|
+
# @return [void]
|
|
107
|
+
def start
|
|
108
|
+
toolbox_api.start(
|
|
109
|
+
NightonaToolboxApiClient::LspServerRequest.new(language_id:, path_to_project:)
|
|
110
|
+
)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# Stops the language server.
|
|
114
|
+
# This method should be called when the LSP server is no longer needed to
|
|
115
|
+
# free up system resources.
|
|
116
|
+
#
|
|
117
|
+
# @return [void]
|
|
118
|
+
def stop
|
|
119
|
+
toolbox_api.stop(
|
|
120
|
+
NightonaToolboxApiClient::LspServerRequest.new(language_id:, path_to_project:)
|
|
121
|
+
)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
instrument :completions, :did_close, :did_open, :document_symbols, :sandbox_symbols,
|
|
125
|
+
:start, :stop,
|
|
126
|
+
component: 'LspServer'
|
|
127
|
+
|
|
128
|
+
private
|
|
129
|
+
|
|
130
|
+
# @return [Nightona::OtelState, nil]
|
|
131
|
+
attr_reader :otel_state
|
|
132
|
+
|
|
133
|
+
# Convert path to file uri.
|
|
134
|
+
#
|
|
135
|
+
# @param path [String]
|
|
136
|
+
# @return [String]
|
|
137
|
+
def uri(path) = "file://#{path}"
|
|
138
|
+
end
|
|
139
|
+
end
|