@@ -16,14 +16,36 @@ type controllerV1 struct {
16 server *Server
16 server *Server
19+// handleGetHealth checks server health.
21+// @Summary Health check
24+// @Router /health [get]
19func (c *controllerV1) handleGetHealth(w http.ResponseWriter, _ *http.Request) {
25func (c *controllerV1) handleGetHealth(w http.ResponseWriter, _ *http.Request) {
20 w.WriteHeader(http.StatusOK)
26 w.WriteHeader(http.StatusOK)
29+// handleGetVersion returns server version information.
31+// @Summary Get server version
34+// @Success 200 {object} proto.VersionInfo
35+// @Router /version [get]
23func (c *controllerV1) handleGetVersion(w http.ResponseWriter, _ *http.Request) {
36func (c *controllerV1) handleGetVersion(w http.ResponseWriter, _ *http.Request) {
24 jsonEncode(w, c.backend.VersionInfo())
37 jsonEncode(w, c.backend.VersionInfo())
40+// handlePostControl sends a control command to the server.
42+// @Summary Send server control command
45+// @Param request body proto.ServerControl true "Control command (e.g. shutdown)"
47+// @Failure 400 {object} proto.Error
48+// @Router /control [post]
27func (c *controllerV1) handlePostControl(w http.ResponseWriter, r *http.Request) {
49func (c *controllerV1) handlePostControl(w http.ResponseWriter, r *http.Request) {
28 var req proto.ServerControl
50 var req proto.ServerControl
29 if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
51 if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
@@ -42,14 +64,38 @@ func (c *controllerV1) handlePostControl(w http.ResponseWriter, r *http.Request)
67+// handleGetConfig returns global server configuration.
69+// @Summary Get server config
72+// @Success 200 {object} object
73+// @Router /config [get]
45func (c *controllerV1) handleGetConfig(w http.ResponseWriter, _ *http.Request) {
74func (c *controllerV1) handleGetConfig(w http.ResponseWriter, _ *http.Request) {
46 jsonEncode(w, c.backend.Config())
75 jsonEncode(w, c.backend.Config())
78+// handleGetWorkspaces lists all workspaces.
80+// @Summary List workspaces
83+// @Success 200 {array} proto.Workspace
84+// @Router /workspaces [get]
49func (c *controllerV1) handleGetWorkspaces(w http.ResponseWriter, _ *http.Request) {
85func (c *controllerV1) handleGetWorkspaces(w http.ResponseWriter, _ *http.Request) {
50 jsonEncode(w, c.backend.ListWorkspaces())
86 jsonEncode(w, c.backend.ListWorkspaces())
89+// handleGetWorkspace returns a single workspace by ID.
91+// @Summary Get workspace
94+// @Param id path string true "Workspace ID"
95+// @Success 200 {object} proto.Workspace
96+// @Failure 404 {object} proto.Error
97+// @Failure 500 {object} proto.Error
98+// @Router /workspaces/{id} [get]
53func (c *controllerV1) handleGetWorkspace(w http.ResponseWriter, r *http.Request) {
99func (c *controllerV1) handleGetWorkspace(w http.ResponseWriter, r *http.Request) {
54 id := r.PathValue("id")
100 id := r.PathValue("id")
55 ws, err := c.backend.GetWorkspaceProto(id)
101 ws, err := c.backend.GetWorkspaceProto(id)
@@ -60,6 +106,17 @@ func (c *controllerV1) handleGetWorkspace(w http.ResponseWriter, r *http.Request
60 jsonEncode(w, ws)
106 jsonEncode(w, ws)
109+// handlePostWorkspaces creates a new workspace.
111+// @Summary Create workspace
115+// @Param request body proto.Workspace true "Workspace creation params"
116+// @Success 200 {object} proto.Workspace
117+// @Failure 400 {object} proto.Error
118+// @Failure 500 {object} proto.Error
119+// @Router /workspaces [post]
63func (c *controllerV1) handlePostWorkspaces(w http.ResponseWriter, r *http.Request) {
120func (c *controllerV1) handlePostWorkspaces(w http.ResponseWriter, r *http.Request) {
64 var args proto.Workspace
121 var args proto.Workspace
65 if err := json.NewDecoder(r.Body).Decode(&args); err != nil {
122 if err := json.NewDecoder(r.Body).Decode(&args); err != nil {
@@ -76,11 +133,29 @@ func (c *controllerV1) handlePostWorkspaces(w http.ResponseWriter, r *http.Reque
76 jsonEncode(w, result)
133 jsonEncode(w, result)
136+// handleDeleteWorkspaces deletes a workspace.
138+// @Summary Delete workspace
140+// @Param id path string true "Workspace ID"
142+// @Failure 404 {object} proto.Error
143+// @Router /workspaces/{id} [delete]
79func (c *controllerV1) handleDeleteWorkspaces(w http.ResponseWriter, r *http.Request) {
144func (c *controllerV1) handleDeleteWorkspaces(w http.ResponseWriter, r *http.Request) {
80 id := r.PathValue("id")
145 id := r.PathValue("id")
81 c.backend.DeleteWorkspace(id)
146 c.backend.DeleteWorkspace(id)
149+// handleGetWorkspaceConfig returns workspace configuration.
151+// @Summary Get workspace config
154+// @Param id path string true "Workspace ID"
155+// @Success 200 {object} object
156+// @Failure 404 {object} proto.Error
157+// @Failure 500 {object} proto.Error
158+// @Router /workspaces/{id}/config [get]
84func (c *controllerV1) handleGetWorkspaceConfig(w http.ResponseWriter, r *http.Request) {
159func (c *controllerV1) handleGetWorkspaceConfig(w http.ResponseWriter, r *http.Request) {
85 id := r.PathValue("id")
160 id := r.PathValue("id")
86 cfg, err := c.backend.GetWorkspaceConfig(id)
161 cfg, err := c.backend.GetWorkspaceConfig(id)
@@ -91,6 +166,16 @@ func (c *controllerV1) handleGetWorkspaceConfig(w http.ResponseWriter, r *http.R
91 jsonEncode(w, cfg)
166 jsonEncode(w, cfg)
169+// handleGetWorkspaceProviders lists available providers for a workspace.
171+// @Summary Get workspace providers
174+// @Param id path string true "Workspace ID"
175+// @Success 200 {object} object
176+// @Failure 404 {object} proto.Error
177+// @Failure 500 {object} proto.Error
178+// @Router /workspaces/{id}/providers [get]
94func (c *controllerV1) handleGetWorkspaceProviders(w http.ResponseWriter, r *http.Request) {
179func (c *controllerV1) handleGetWorkspaceProviders(w http.ResponseWriter, r *http.Request) {
95 id := r.PathValue("id")
180 id := r.PathValue("id")
96 providers, err := c.backend.GetWorkspaceProviders(id)
181 providers, err := c.backend.GetWorkspaceProviders(id)
@@ -101,6 +186,16 @@ func (c *controllerV1) handleGetWorkspaceProviders(w http.ResponseWriter, r *htt
101 jsonEncode(w, providers)
186 jsonEncode(w, providers)
189+// handleGetWorkspaceEvents streams workspace events as Server-Sent Events.
191+// @Summary Stream workspace events (SSE)
193+// @Produce text/event-stream
194+// @Param id path string true "Workspace ID"
196+// @Failure 404 {object} proto.Error
197+// @Failure 500 {object} proto.Error
198+// @Router /workspaces/{id}/events [get]
104func (c *controllerV1) handleGetWorkspaceEvents(w http.ResponseWriter, r *http.Request) {
199func (c *controllerV1) handleGetWorkspaceEvents(w http.ResponseWriter, r *http.Request) {
105 flusher := http.NewResponseController(w)
200 flusher := http.NewResponseController(w)
106 id := r.PathValue("id")
201 id := r.PathValue("id")
@@ -140,6 +235,16 @@ func (c *controllerV1) handleGetWorkspaceEvents(w http.ResponseWriter, r *http.R
238+// handleGetWorkspaceLSPs lists LSP clients for a workspace.
240+// @Summary List LSP clients
243+// @Param id path string true "Workspace ID"
244+// @Success 200 {object} map[string]proto.LSPClientInfo
245+// @Failure 404 {object} proto.Error
246+// @Failure 500 {object} proto.Error
247+// @Router /workspaces/{id}/lsps [get]
143func (c *controllerV1) handleGetWorkspaceLSPs(w http.ResponseWriter, r *http.Request) {
248func (c *controllerV1) handleGetWorkspaceLSPs(w http.ResponseWriter, r *http.Request) {
144 id := r.PathValue("id")
249 id := r.PathValue("id")
145 states, err := c.backend.GetLSPStates(id)
250 states, err := c.backend.GetLSPStates(id)
@@ -160,6 +265,17 @@ func (c *controllerV1) handleGetWorkspaceLSPs(w http.ResponseWriter, r *http.Req
160 jsonEncode(w, result)
265 jsonEncode(w, result)
268+// handleGetWorkspaceLSPDiagnostics returns diagnostics for an LSP client.
270+// @Summary Get LSP diagnostics
273+// @Param id path string true "Workspace ID"
274+// @Param lsp path string true "LSP client name"
275+// @Success 200 {object} object
276+// @Failure 404 {object} proto.Error
277+// @Failure 500 {object} proto.Error
278+// @Router /workspaces/{id}/lsps/{lsp}/diagnostics [get]
163func (c *controllerV1) handleGetWorkspaceLSPDiagnostics(w http.ResponseWriter, r *http.Request) {
279func (c *controllerV1) handleGetWorkspaceLSPDiagnostics(w http.ResponseWriter, r *http.Request) {
164 id := r.PathValue("id")
280 id := r.PathValue("id")
165 lspName := r.PathValue("lsp")
281 lspName := r.PathValue("lsp")
@@ -171,6 +287,16 @@ func (c *controllerV1) handleGetWorkspaceLSPDiagnostics(w http.ResponseWriter, r
171 jsonEncode(w, diagnostics)
287 jsonEncode(w, diagnostics)
290+// handleGetWorkspaceSessions lists sessions for a workspace.
292+// @Summary List sessions
295+// @Param id path string true "Workspace ID"
296+// @Success 200 {array} proto.Session
297+// @Failure 404 {object} proto.Error
298+// @Failure 500 {object} proto.Error
299+// @Router /workspaces/{id}/sessions [get]
174func (c *controllerV1) handleGetWorkspaceSessions(w http.ResponseWriter, r *http.Request) {
300func (c *controllerV1) handleGetWorkspaceSessions(w http.ResponseWriter, r *http.Request) {
175 id := r.PathValue("id")
301 id := r.PathValue("id")
176 sessions, err := c.backend.ListSessions(r.Context(), id)
302 sessions, err := c.backend.ListSessions(r.Context(), id)
@@ -181,6 +307,19 @@ func (c *controllerV1) handleGetWorkspaceSessions(w http.ResponseWriter, r *http
181 jsonEncode(w, sessions)
307 jsonEncode(w, sessions)
310+// handlePostWorkspaceSessions creates a new session in a workspace.
312+// @Summary Create session
316+// @Param id path string true "Workspace ID"
317+// @Param request body proto.Session true "Session creation params (title)"
318+// @Success 200 {object} proto.Session
319+// @Failure 400 {object} proto.Error
320+// @Failure 404 {object} proto.Error
321+// @Failure 500 {object} proto.Error
322+// @Router /workspaces/{id}/sessions [post]
184func (c *controllerV1) handlePostWorkspaceSessions(w http.ResponseWriter, r *http.Request) {
323func (c *controllerV1) handlePostWorkspaceSessions(w http.ResponseWriter, r *http.Request) {
185 id := r.PathValue("id")
324 id := r.PathValue("id")
@@ -199,6 +338,17 @@ func (c *controllerV1) handlePostWorkspaceSessions(w http.ResponseWriter, r *htt
199 jsonEncode(w, sess)
338 jsonEncode(w, sess)
341+// handleGetWorkspaceSession returns a single session.
343+// @Summary Get session
346+// @Param id path string true "Workspace ID"
347+// @Param sid path string true "Session ID"
348+// @Success 200 {object} proto.Session
349+// @Failure 404 {object} proto.Error
350+// @Failure 500 {object} proto.Error
351+// @Router /workspaces/{id}/sessions/{sid} [get]
202func (c *controllerV1) handleGetWorkspaceSession(w http.ResponseWriter, r *http.Request) {
352func (c *controllerV1) handleGetWorkspaceSession(w http.ResponseWriter, r *http.Request) {
203 id := r.PathValue("id")
353 id := r.PathValue("id")
204 sid := r.PathValue("sid")
354 sid := r.PathValue("sid")
@@ -210,6 +360,17 @@ func (c *controllerV1) handleGetWorkspaceSession(w http.ResponseWriter, r *http.
210 jsonEncode(w, sess)
360 jsonEncode(w, sess)
363+// handleGetWorkspaceSessionHistory returns the history for a session.
365+// @Summary Get session history
368+// @Param id path string true "Workspace ID"
369+// @Param sid path string true "Session ID"
370+// @Success 200 {array} proto.File
371+// @Failure 404 {object} proto.Error
372+// @Failure 500 {object} proto.Error
373+// @Router /workspaces/{id}/sessions/{sid}/history [get]
213func (c *controllerV1) handleGetWorkspaceSessionHistory(w http.ResponseWriter, r *http.Request) {
374func (c *controllerV1) handleGetWorkspaceSessionHistory(w http.ResponseWriter, r *http.Request) {
214 id := r.PathValue("id")
375 id := r.PathValue("id")
215 sid := r.PathValue("sid")
376 sid := r.PathValue("sid")
@@ -221,6 +382,17 @@ func (c *controllerV1) handleGetWorkspaceSessionHistory(w http.ResponseWriter, r
221 jsonEncode(w, history)
382 jsonEncode(w, history)
385+// handleGetWorkspaceSessionMessages returns all messages for a session.
387+// @Summary Get session messages
390+// @Param id path string true "Workspace ID"
391+// @Param sid path string true "Session ID"
392+// @Success 200 {array} proto.Message
393+// @Failure 404 {object} proto.Error
394+// @Failure 500 {object} proto.Error
395+// @Router /workspaces/{id}/sessions/{sid}/messages [get]
224func (c *controllerV1) handleGetWorkspaceSessionMessages(w http.ResponseWriter, r *http.Request) {
396func (c *controllerV1) handleGetWorkspaceSessionMessages(w http.ResponseWriter, r *http.Request) {
225 id := r.PathValue("id")
397 id := r.PathValue("id")
226 sid := r.PathValue("sid")
398 sid := r.PathValue("sid")
@@ -232,6 +404,20 @@ func (c *controllerV1) handleGetWorkspaceSessionMessages(w http.ResponseWriter,
232 jsonEncode(w, messagesToProto(messages))
404 jsonEncode(w, messagesToProto(messages))
407+// handlePutWorkspaceSession updates a session.
409+// @Summary Update session
413+// @Param id path string true "Workspace ID"
414+// @Param sid path string true "Session ID"
415+// @Param request body proto.Session true "Updated session"
416+// @Success 200 {object} proto.Session
417+// @Failure 400 {object} proto.Error
418+// @Failure 404 {object} proto.Error
419+// @Failure 500 {object} proto.Error
420+// @Router /workspaces/{id}/sessions/{sid} [put]
235func (c *controllerV1) handlePutWorkspaceSession(w http.ResponseWriter, r *http.Request) {
421func (c *controllerV1) handlePutWorkspaceSession(w http.ResponseWriter, r *http.Request) {
236 id := r.PathValue("id")
422 id := r.PathValue("id")
@@ -250,6 +436,16 @@ func (c *controllerV1) handlePutWorkspaceSession(w http.ResponseWriter, r *http.
250 jsonEncode(w, saved)
436 jsonEncode(w, saved)
439+// handleDeleteWorkspaceSession deletes a session.
441+// @Summary Delete session
443+// @Param id path string true "Workspace ID"
444+// @Param sid path string true "Session ID"
446+// @Failure 404 {object} proto.Error
447+// @Failure 500 {object} proto.Error
448+// @Router /workspaces/{id}/sessions/{sid} [delete]
253func (c *controllerV1) handleDeleteWorkspaceSession(w http.ResponseWriter, r *http.Request) {
449func (c *controllerV1) handleDeleteWorkspaceSession(w http.ResponseWriter, r *http.Request) {
254 id := r.PathValue("id")
450 id := r.PathValue("id")
255 sid := r.PathValue("sid")
451 sid := r.PathValue("sid")
@@ -260,6 +456,17 @@ func (c *controllerV1) handleDeleteWorkspaceSession(w http.ResponseWriter, r *ht
260 w.WriteHeader(http.StatusOK)
456 w.WriteHeader(http.StatusOK)
459+// handleGetWorkspaceSessionUserMessages returns user messages for a session.
461+// @Summary Get user messages for session
464+// @Param id path string true "Workspace ID"
465+// @Param sid path string true "Session ID"
466+// @Success 200 {array} proto.Message
467+// @Failure 404 {object} proto.Error
468+// @Failure 500 {object} proto.Error
469+// @Router /workspaces/{id}/sessions/{sid}/messages/user [get]
263func (c *controllerV1) handleGetWorkspaceSessionUserMessages(w http.ResponseWriter, r *http.Request) {
470func (c *controllerV1) handleGetWorkspaceSessionUserMessages(w http.ResponseWriter, r *http.Request) {
264 id := r.PathValue("id")
471 id := r.PathValue("id")
265 sid := r.PathValue("sid")
472 sid := r.PathValue("sid")
@@ -271,6 +478,16 @@ func (c *controllerV1) handleGetWorkspaceSessionUserMessages(w http.ResponseWrit
271 jsonEncode(w, messagesToProto(messages))
478 jsonEncode(w, messagesToProto(messages))
481+// handleGetWorkspaceAllUserMessages returns all user messages across sessions.
483+// @Summary Get all user messages for workspace
486+// @Param id path string true "Workspace ID"
487+// @Success 200 {array} proto.Message
488+// @Failure 404 {object} proto.Error
489+// @Failure 500 {object} proto.Error
490+// @Router /workspaces/{id}/messages/user [get]
274func (c *controllerV1) handleGetWorkspaceAllUserMessages(w http.ResponseWriter, r *http.Request) {
491func (c *controllerV1) handleGetWorkspaceAllUserMessages(w http.ResponseWriter, r *http.Request) {
275 id := r.PathValue("id")
492 id := r.PathValue("id")
276 messages, err := c.backend.ListAllUserMessages(r.Context(), id)
493 messages, err := c.backend.ListAllUserMessages(r.Context(), id)
@@ -281,6 +498,17 @@ func (c *controllerV1) handleGetWorkspaceAllUserMessages(w http.ResponseWriter,
281 jsonEncode(w, messagesToProto(messages))
498 jsonEncode(w, messagesToProto(messages))
501+// handleGetWorkspaceSessionFileTrackerFiles lists files read in a session.
503+// @Summary List tracked files for session
506+// @Param id path string true "Workspace ID"
507+// @Param sid path string true "Session ID"
508+// @Success 200 {array} string
509+// @Failure 404 {object} proto.Error
510+// @Failure 500 {object} proto.Error
511+// @Router /workspaces/{id}/sessions/{sid}/filetracker/files [get]
284func (c *controllerV1) handleGetWorkspaceSessionFileTrackerFiles(w http.ResponseWriter, r *http.Request) {
512func (c *controllerV1) handleGetWorkspaceSessionFileTrackerFiles(w http.ResponseWriter, r *http.Request) {
285 id := r.PathValue("id")
513 id := r.PathValue("id")
286 sid := r.PathValue("sid")
514 sid := r.PathValue("sid")
@@ -292,13 +520,22 @@ func (c *controllerV1) handleGetWorkspaceSessionFileTrackerFiles(w http.Response
292 jsonEncode(w, files)
520 jsonEncode(w, files)
523+// handlePostWorkspaceFileTrackerRead records a file read event.
525+// @Summary Record file read
528+// @Param id path string true "Workspace ID"
529+// @Param request body proto.FileTrackerReadRequest true "File tracker read request"
531+// @Failure 400 {object} proto.Error
532+// @Failure 404 {object} proto.Error
533+// @Failure 500 {object} proto.Error
534+// @Router /workspaces/{id}/filetracker/read [post]
295func (c *controllerV1) handlePostWorkspaceFileTrackerRead(w http.ResponseWriter, r *http.Request) {
535func (c *controllerV1) handlePostWorkspaceFileTrackerRead(w http.ResponseWriter, r *http.Request) {
296 id := r.PathValue("id")
536 id := r.PathValue("id")
298− var req struct {
538+ var req proto.FileTrackerReadRequest
299− SessionID string `json:"session_id"`
300− Path string `json:"path"`
302 if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
539 if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
303 c.server.logError(r, "Failed to decode request", "error", err)
540 c.server.logError(r, "Failed to decode request", "error", err)
304 jsonError(w, http.StatusBadRequest, "failed to decode request")
541 jsonError(w, http.StatusBadRequest, "failed to decode request")
@@ -312,6 +549,18 @@ func (c *controllerV1) handlePostWorkspaceFileTrackerRead(w http.ResponseWriter,
312 w.WriteHeader(http.StatusOK)
549 w.WriteHeader(http.StatusOK)
552+// handleGetWorkspaceFileTrackerLastRead returns the last read time for a file.
554+// @Summary Get last read time for file
557+// @Param id path string true "Workspace ID"
558+// @Param session_id query string false "Session ID"
559+// @Param path query string true "File path"
560+// @Success 200 {object} object
561+// @Failure 404 {object} proto.Error
562+// @Failure 500 {object} proto.Error
563+// @Router /workspaces/{id}/filetracker/lastread [get]
315func (c *controllerV1) handleGetWorkspaceFileTrackerLastRead(w http.ResponseWriter, r *http.Request) {
564func (c *controllerV1) handleGetWorkspaceFileTrackerLastRead(w http.ResponseWriter, r *http.Request) {
316 id := r.PathValue("id")
565 id := r.PathValue("id")
317 sid := r.URL.Query().Get("session_id")
566 sid := r.URL.Query().Get("session_id")
@@ -325,12 +574,22 @@ func (c *controllerV1) handleGetWorkspaceFileTrackerLastRead(w http.ResponseWrit
325 jsonEncode(w, t)
574 jsonEncode(w, t)
577+// handlePostWorkspaceLSPStart starts an LSP server for a path.
579+// @Summary Start LSP server
582+// @Param id path string true "Workspace ID"
583+// @Param request body proto.LSPStartRequest true "LSP start request"
585+// @Failure 400 {object} proto.Error
586+// @Failure 404 {object} proto.Error
587+// @Failure 500 {object} proto.Error
588+// @Router /workspaces/{id}/lsps/start [post]
328func (c *controllerV1) handlePostWorkspaceLSPStart(w http.ResponseWriter, r *http.Request) {
589func (c *controllerV1) handlePostWorkspaceLSPStart(w http.ResponseWriter, r *http.Request) {
329 id := r.PathValue("id")
590 id := r.PathValue("id")
331− var req struct {
592+ var req proto.LSPStartRequest
332− Path string `json:"path"`
334 if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
593 if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
335 c.server.logError(r, "Failed to decode request", "error", err)
594 c.server.logError(r, "Failed to decode request", "error", err)
336 jsonError(w, http.StatusBadRequest, "failed to decode request")
595 jsonError(w, http.StatusBadRequest, "failed to decode request")
@@ -344,6 +603,15 @@ func (c *controllerV1) handlePostWorkspaceLSPStart(w http.ResponseWriter, r *htt
344 w.WriteHeader(http.StatusOK)
603 w.WriteHeader(http.StatusOK)
606+// handlePostWorkspaceLSPStopAll stops all LSP servers.
608+// @Summary Stop all LSP servers
610+// @Param id path string true "Workspace ID"
612+// @Failure 404 {object} proto.Error
613+// @Failure 500 {object} proto.Error
614+// @Router /workspaces/{id}/lsps/stop [post]
347func (c *controllerV1) handlePostWorkspaceLSPStopAll(w http.ResponseWriter, r *http.Request) {
615func (c *controllerV1) handlePostWorkspaceLSPStopAll(w http.ResponseWriter, r *http.Request) {
348 id := r.PathValue("id")
616 id := r.PathValue("id")
349 if err := c.backend.LSPStopAll(r.Context(), id); err != nil {
617 if err := c.backend.LSPStopAll(r.Context(), id); err != nil {
@@ -353,6 +621,16 @@ func (c *controllerV1) handlePostWorkspaceLSPStopAll(w http.ResponseWriter, r *h
353 w.WriteHeader(http.StatusOK)
621 w.WriteHeader(http.StatusOK)
624+// handleGetWorkspaceAgent returns agent info for a workspace.
626+// @Summary Get agent info
629+// @Param id path string true "Workspace ID"
630+// @Success 200 {object} proto.AgentInfo
631+// @Failure 404 {object} proto.Error
632+// @Failure 500 {object} proto.Error
633+// @Router /workspaces/{id}/agent [get]
356func (c *controllerV1) handleGetWorkspaceAgent(w http.ResponseWriter, r *http.Request) {
634func (c *controllerV1) handleGetWorkspaceAgent(w http.ResponseWriter, r *http.Request) {
357 id := r.PathValue("id")
635 id := r.PathValue("id")
358 info, err := c.backend.GetAgentInfo(id)
636 info, err := c.backend.GetAgentInfo(id)
@@ -363,6 +641,18 @@ func (c *controllerV1) handleGetWorkspaceAgent(w http.ResponseWriter, r *http.Re
363 jsonEncode(w, info)
641 jsonEncode(w, info)
644+// handlePostWorkspaceAgent sends a message to the agent.
646+// @Summary Send message to agent
649+// @Param id path string true "Workspace ID"
650+// @Param request body proto.AgentMessage true "Agent message"
652+// @Failure 400 {object} proto.Error
653+// @Failure 404 {object} proto.Error
654+// @Failure 500 {object} proto.Error
655+// @Router /workspaces/{id}/agent [post]
366func (c *controllerV1) handlePostWorkspaceAgent(w http.ResponseWriter, r *http.Request) {
656func (c *controllerV1) handlePostWorkspaceAgent(w http.ResponseWriter, r *http.Request) {
367 id := r.PathValue("id")
657 id := r.PathValue("id")
@@ -380,6 +670,15 @@ func (c *controllerV1) handlePostWorkspaceAgent(w http.ResponseWriter, r *http.R
380 w.WriteHeader(http.StatusOK)
670 w.WriteHeader(http.StatusOK)
673+// handlePostWorkspaceAgentInit initializes the agent for a workspace.
675+// @Summary Initialize agent
677+// @Param id path string true "Workspace ID"
679+// @Failure 404 {object} proto.Error
680+// @Failure 500 {object} proto.Error
681+// @Router /workspaces/{id}/agent/init [post]
383func (c *controllerV1) handlePostWorkspaceAgentInit(w http.ResponseWriter, r *http.Request) {
682func (c *controllerV1) handlePostWorkspaceAgentInit(w http.ResponseWriter, r *http.Request) {
384 id := r.PathValue("id")
683 id := r.PathValue("id")
385 if err := c.backend.InitAgent(r.Context(), id); err != nil {
684 if err := c.backend.InitAgent(r.Context(), id); err != nil {
@@ -389,6 +688,15 @@ func (c *controllerV1) handlePostWorkspaceAgentInit(w http.ResponseWriter, r *ht
389 w.WriteHeader(http.StatusOK)
688 w.WriteHeader(http.StatusOK)
691+// handlePostWorkspaceAgentUpdate updates the agent for a workspace.
693+// @Summary Update agent
695+// @Param id path string true "Workspace ID"
697+// @Failure 404 {object} proto.Error
698+// @Failure 500 {object} proto.Error
699+// @Router /workspaces/{id}/agent/update [post]
392func (c *controllerV1) handlePostWorkspaceAgentUpdate(w http.ResponseWriter, r *http.Request) {
700func (c *controllerV1) handlePostWorkspaceAgentUpdate(w http.ResponseWriter, r *http.Request) {
393 id := r.PathValue("id")
701 id := r.PathValue("id")
394 if err := c.backend.UpdateAgent(r.Context(), id); err != nil {
702 if err := c.backend.UpdateAgent(r.Context(), id); err != nil {
@@ -398,6 +706,17 @@ func (c *controllerV1) handlePostWorkspaceAgentUpdate(w http.ResponseWriter, r *
398 w.WriteHeader(http.StatusOK)
706 w.WriteHeader(http.StatusOK)
709+// handleGetWorkspaceAgentSession returns a specific agent session.
711+// @Summary Get agent session
714+// @Param id path string true "Workspace ID"
715+// @Param sid path string true "Session ID"
716+// @Success 200 {object} proto.AgentSession
717+// @Failure 404 {object} proto.Error
718+// @Failure 500 {object} proto.Error
719+// @Router /workspaces/{id}/agent/sessions/{sid} [get]
401func (c *controllerV1) handleGetWorkspaceAgentSession(w http.ResponseWriter, r *http.Request) {
720func (c *controllerV1) handleGetWorkspaceAgentSession(w http.ResponseWriter, r *http.Request) {
402 id := r.PathValue("id")
721 id := r.PathValue("id")
403 sid := r.PathValue("sid")
722 sid := r.PathValue("sid")
@@ -409,6 +728,16 @@ func (c *controllerV1) handleGetWorkspaceAgentSession(w http.ResponseWriter, r *
409 jsonEncode(w, agentSession)
728 jsonEncode(w, agentSession)
731+// handlePostWorkspaceAgentSessionCancel cancels a running agent session.
733+// @Summary Cancel agent session
735+// @Param id path string true "Workspace ID"
736+// @Param sid path string true "Session ID"
738+// @Failure 404 {object} proto.Error
739+// @Failure 500 {object} proto.Error
740+// @Router /workspaces/{id}/agent/sessions/{sid}/cancel [post]
412func (c *controllerV1) handlePostWorkspaceAgentSessionCancel(w http.ResponseWriter, r *http.Request) {
741func (c *controllerV1) handlePostWorkspaceAgentSessionCancel(w http.ResponseWriter, r *http.Request) {
413 id := r.PathValue("id")
742 id := r.PathValue("id")
414 sid := r.PathValue("sid")
743 sid := r.PathValue("sid")
@@ -419,6 +748,17 @@ func (c *controllerV1) handlePostWorkspaceAgentSessionCancel(w http.ResponseWrit
419 w.WriteHeader(http.StatusOK)
748 w.WriteHeader(http.StatusOK)
751+// handleGetWorkspaceAgentSessionPromptQueued returns whether a queued prompt exists.
753+// @Summary Get queued prompt status
756+// @Param id path string true "Workspace ID"
757+// @Param sid path string true "Session ID"
758+// @Success 200 {object} object
759+// @Failure 404 {object} proto.Error
760+// @Failure 500 {object} proto.Error
761+// @Router /workspaces/{id}/agent/sessions/{sid}/prompts/queued [get]
422func (c *controllerV1) handleGetWorkspaceAgentSessionPromptQueued(w http.ResponseWriter, r *http.Request) {
762func (c *controllerV1) handleGetWorkspaceAgentSessionPromptQueued(w http.ResponseWriter, r *http.Request) {
423 id := r.PathValue("id")
763 id := r.PathValue("id")
424 sid := r.PathValue("sid")
764 sid := r.PathValue("sid")
@@ -430,6 +770,16 @@ func (c *controllerV1) handleGetWorkspaceAgentSessionPromptQueued(w http.Respons
430 jsonEncode(w, queued)
770 jsonEncode(w, queued)
773+// handlePostWorkspaceAgentSessionPromptClear clears the prompt queue for a session.
775+// @Summary Clear prompt queue
777+// @Param id path string true "Workspace ID"
778+// @Param sid path string true "Session ID"
780+// @Failure 404 {object} proto.Error
781+// @Failure 500 {object} proto.Error
782+// @Router /workspaces/{id}/agent/sessions/{sid}/prompts/clear [post]
433func (c *controllerV1) handlePostWorkspaceAgentSessionPromptClear(w http.ResponseWriter, r *http.Request) {
783func (c *controllerV1) handlePostWorkspaceAgentSessionPromptClear(w http.ResponseWriter, r *http.Request) {
434 id := r.PathValue("id")
784 id := r.PathValue("id")
435 sid := r.PathValue("sid")
785 sid := r.PathValue("sid")
@@ -440,6 +790,16 @@ func (c *controllerV1) handlePostWorkspaceAgentSessionPromptClear(w http.Respons
440 w.WriteHeader(http.StatusOK)
790 w.WriteHeader(http.StatusOK)
793+// handlePostWorkspaceAgentSessionSummarize summarizes a session.
795+// @Summary Summarize session
797+// @Param id path string true "Workspace ID"
798+// @Param sid path string true "Session ID"
800+// @Failure 404 {object} proto.Error
801+// @Failure 500 {object} proto.Error
802+// @Router /workspaces/{id}/agent/sessions/{sid}/summarize [post]
443func (c *controllerV1) handlePostWorkspaceAgentSessionSummarize(w http.ResponseWriter, r *http.Request) {
803func (c *controllerV1) handlePostWorkspaceAgentSessionSummarize(w http.ResponseWriter, r *http.Request) {
444 id := r.PathValue("id")
804 id := r.PathValue("id")
445 sid := r.PathValue("sid")
805 sid := r.PathValue("sid")
@@ -450,6 +810,17 @@ func (c *controllerV1) handlePostWorkspaceAgentSessionSummarize(w http.ResponseW
450 w.WriteHeader(http.StatusOK)
810 w.WriteHeader(http.StatusOK)
813+// handleGetWorkspaceAgentSessionPromptList returns the list of queued prompts.
815+// @Summary List queued prompts
818+// @Param id path string true "Workspace ID"
819+// @Param sid path string true "Session ID"
820+// @Success 200 {array} string
821+// @Failure 404 {object} proto.Error
822+// @Failure 500 {object} proto.Error
823+// @Router /workspaces/{id}/agent/sessions/{sid}/prompts/list [get]
453func (c *controllerV1) handleGetWorkspaceAgentSessionPromptList(w http.ResponseWriter, r *http.Request) {
824func (c *controllerV1) handleGetWorkspaceAgentSessionPromptList(w http.ResponseWriter, r *http.Request) {
454 id := r.PathValue("id")
825 id := r.PathValue("id")
455 sid := r.PathValue("sid")
826 sid := r.PathValue("sid")
@@ -461,6 +832,17 @@ func (c *controllerV1) handleGetWorkspaceAgentSessionPromptList(w http.ResponseW
461 jsonEncode(w, prompts)
832 jsonEncode(w, prompts)
835+// handleGetWorkspaceAgentDefaultSmallModel returns the default small model for a provider.
837+// @Summary Get default small model
840+// @Param id path string true "Workspace ID"
841+// @Param provider_id query string false "Provider ID"
842+// @Success 200 {object} object
843+// @Failure 404 {object} proto.Error
844+// @Failure 500 {object} proto.Error
845+// @Router /workspaces/{id}/agent/default-small-model [get]
464func (c *controllerV1) handleGetWorkspaceAgentDefaultSmallModel(w http.ResponseWriter, r *http.Request) {
846func (c *controllerV1) handleGetWorkspaceAgentDefaultSmallModel(w http.ResponseWriter, r *http.Request) {
465 id := r.PathValue("id")
847 id := r.PathValue("id")
466 providerID := r.URL.Query().Get("provider_id")
848 providerID := r.URL.Query().Get("provider_id")
@@ -472,6 +854,18 @@ func (c *controllerV1) handleGetWorkspaceAgentDefaultSmallModel(w http.ResponseW
472 jsonEncode(w, model)
854 jsonEncode(w, model)
857+// handlePostWorkspacePermissionsGrant grants a permission request.
859+// @Summary Grant permission
862+// @Param id path string true "Workspace ID"
863+// @Param request body proto.PermissionGrant true "Permission grant"
865+// @Failure 400 {object} proto.Error
866+// @Failure 404 {object} proto.Error
867+// @Failure 500 {object} proto.Error
868+// @Router /workspaces/{id}/permissions/grant [post]
475func (c *controllerV1) handlePostWorkspacePermissionsGrant(w http.ResponseWriter, r *http.Request) {
869func (c *controllerV1) handlePostWorkspacePermissionsGrant(w http.ResponseWriter, r *http.Request) {
476 id := r.PathValue("id")
870 id := r.PathValue("id")
@@ -489,6 +883,18 @@ func (c *controllerV1) handlePostWorkspacePermissionsGrant(w http.ResponseWriter
489 w.WriteHeader(http.StatusOK)
883 w.WriteHeader(http.StatusOK)
886+// handlePostWorkspacePermissionsSkip sets whether to skip permission prompts.
888+// @Summary Set skip permissions
891+// @Param id path string true "Workspace ID"
892+// @Param request body proto.PermissionSkipRequest true "Permission skip request"
894+// @Failure 400 {object} proto.Error
895+// @Failure 404 {object} proto.Error
896+// @Failure 500 {object} proto.Error
897+// @Router /workspaces/{id}/permissions/skip [post]
492func (c *controllerV1) handlePostWorkspacePermissionsSkip(w http.ResponseWriter, r *http.Request) {
898func (c *controllerV1) handlePostWorkspacePermissionsSkip(w http.ResponseWriter, r *http.Request) {
493 id := r.PathValue("id")
899 id := r.PathValue("id")
@@ -505,6 +911,16 @@ func (c *controllerV1) handlePostWorkspacePermissionsSkip(w http.ResponseWriter,
914+// handleGetWorkspacePermissionsSkip returns whether permission prompts are skipped.
916+// @Summary Get skip permissions status
919+// @Param id path string true "Workspace ID"
920+// @Success 200 {object} proto.PermissionSkipRequest
921+// @Failure 404 {object} proto.Error
922+// @Failure 500 {object} proto.Error
923+// @Router /workspaces/{id}/permissions/skip [get]
508func (c *controllerV1) handleGetWorkspacePermissionsSkip(w http.ResponseWriter, r *http.Request) {
924func (c *controllerV1) handleGetWorkspacePermissionsSkip(w http.ResponseWriter, r *http.Request) {
509 id := r.PathValue("id")
925 id := r.PathValue("id")
510 skip, err := c.backend.GetPermissionsSkip(id)
926 skip, err := c.backend.GetPermissionsSkip(id)