@@ -16,14 +16,36 @@ type controllerV1 struct {
1616 server *Server
1717}
1818
19+// handleGetHealth checks server health.
20+//
21+// @Summary Health check
22+// @Tags system
23+// @Success 200
24+// @Router /health [get]
1925func (c *controllerV1) handleGetHealth(w http.ResponseWriter, _ *http.Request) {
2026 w.WriteHeader(http.StatusOK)
2127}
2228
29+// handleGetVersion returns server version information.
30+//
31+// @Summary Get server version
32+// @Tags system
33+// @Produce json
34+// @Success 200 {object} proto.VersionInfo
35+// @Router /version [get]
2336func (c *controllerV1) handleGetVersion(w http.ResponseWriter, _ *http.Request) {
2437 jsonEncode(w, c.backend.VersionInfo())
2538}
2639
40+// handlePostControl sends a control command to the server.
41+//
42+// @Summary Send server control command
43+// @Tags system
44+// @Accept json
45+// @Param request body proto.ServerControl true "Control command (e.g. shutdown)"
46+// @Success 200
47+// @Failure 400 {object} proto.Error
48+// @Router /control [post]
2749func (c *controllerV1) handlePostControl(w http.ResponseWriter, r *http.Request) {
2850 var req proto.ServerControl
2951 if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
@@ -42,14 +64,38 @@ func (c *controllerV1) handlePostControl(w http.ResponseWriter, r *http.Request)
4264 }
4365}
4466
67+// handleGetConfig returns global server configuration.
68+//
69+// @Summary Get server config
70+// @Tags system
71+// @Produce json
72+// @Success 200 {object} object
73+// @Router /config [get]
4574func (c *controllerV1) handleGetConfig(w http.ResponseWriter, _ *http.Request) {
4675 jsonEncode(w, c.backend.Config())
4776}
4877
78+// handleGetWorkspaces lists all workspaces.
79+//
80+// @Summary List workspaces
81+// @Tags workspaces
82+// @Produce json
83+// @Success 200 {array} proto.Workspace
84+// @Router /workspaces [get]
4985func (c *controllerV1) handleGetWorkspaces(w http.ResponseWriter, _ *http.Request) {
5086 jsonEncode(w, c.backend.ListWorkspaces())
5187}
5288
89+// handleGetWorkspace returns a single workspace by ID.
90+//
91+// @Summary Get workspace
92+// @Tags workspaces
93+// @Produce json
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]
5399func (c *controllerV1) handleGetWorkspace(w http.ResponseWriter, r *http.Request) {
54100 id := r.PathValue("id")
55101 ws, err := c.backend.GetWorkspaceProto(id)
@@ -60,6 +106,17 @@ func (c *controllerV1) handleGetWorkspace(w http.ResponseWriter, r *http.Request
60106 jsonEncode(w, ws)
61107}
62108
109+// handlePostWorkspaces creates a new workspace.
110+//
111+// @Summary Create workspace
112+// @Tags workspaces
113+// @Accept json
114+// @Produce json
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]
63120func (c *controllerV1) handlePostWorkspaces(w http.ResponseWriter, r *http.Request) {
64121 var args proto.Workspace
65122 if err := json.NewDecoder(r.Body).Decode(&args); err != nil {
@@ -76,11 +133,29 @@ func (c *controllerV1) handlePostWorkspaces(w http.ResponseWriter, r *http.Reque
76133 jsonEncode(w, result)
77134}
78135
136+// handleDeleteWorkspaces deletes a workspace.
137+//
138+// @Summary Delete workspace
139+// @Tags workspaces
140+// @Param id path string true "Workspace ID"
141+// @Success 200
142+// @Failure 404 {object} proto.Error
143+// @Router /workspaces/{id} [delete]
79144func (c *controllerV1) handleDeleteWorkspaces(w http.ResponseWriter, r *http.Request) {
80145 id := r.PathValue("id")
81146 c.backend.DeleteWorkspace(id)
82147}
83148
149+// handleGetWorkspaceConfig returns workspace configuration.
150+//
151+// @Summary Get workspace config
152+// @Tags workspaces
153+// @Produce json
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]
84159func (c *controllerV1) handleGetWorkspaceConfig(w http.ResponseWriter, r *http.Request) {
85160 id := r.PathValue("id")
86161 cfg, err := c.backend.GetWorkspaceConfig(id)
@@ -91,6 +166,16 @@ func (c *controllerV1) handleGetWorkspaceConfig(w http.ResponseWriter, r *http.R
91166 jsonEncode(w, cfg)
92167}
93168
169+// handleGetWorkspaceProviders lists available providers for a workspace.
170+//
171+// @Summary Get workspace providers
172+// @Tags workspaces
173+// @Produce json
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]
94179func (c *controllerV1) handleGetWorkspaceProviders(w http.ResponseWriter, r *http.Request) {
95180 id := r.PathValue("id")
96181 providers, err := c.backend.GetWorkspaceProviders(id)
@@ -101,6 +186,16 @@ func (c *controllerV1) handleGetWorkspaceProviders(w http.ResponseWriter, r *htt
101186 jsonEncode(w, providers)
102187}
103188
189+// handleGetWorkspaceEvents streams workspace events as Server-Sent Events.
190+//
191+// @Summary Stream workspace events (SSE)
192+// @Tags workspaces
193+// @Produce text/event-stream
194+// @Param id path string true "Workspace ID"
195+// @Success 200
196+// @Failure 404 {object} proto.Error
197+// @Failure 500 {object} proto.Error
198+// @Router /workspaces/{id}/events [get]
104199func (c *controllerV1) handleGetWorkspaceEvents(w http.ResponseWriter, r *http.Request) {
105200 flusher := http.NewResponseController(w)
106201 id := r.PathValue("id")
@@ -140,6 +235,16 @@ func (c *controllerV1) handleGetWorkspaceEvents(w http.ResponseWriter, r *http.R
140235 }
141236}
142237
238+// handleGetWorkspaceLSPs lists LSP clients for a workspace.
239+//
240+// @Summary List LSP clients
241+// @Tags lsp
242+// @Produce json
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]
143248func (c *controllerV1) handleGetWorkspaceLSPs(w http.ResponseWriter, r *http.Request) {
144249 id := r.PathValue("id")
145250 states, err := c.backend.GetLSPStates(id)
@@ -160,6 +265,17 @@ func (c *controllerV1) handleGetWorkspaceLSPs(w http.ResponseWriter, r *http.Req
160265 jsonEncode(w, result)
161266}
162267
268+// handleGetWorkspaceLSPDiagnostics returns diagnostics for an LSP client.
269+//
270+// @Summary Get LSP diagnostics
271+// @Tags lsp
272+// @Produce json
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]
163279func (c *controllerV1) handleGetWorkspaceLSPDiagnostics(w http.ResponseWriter, r *http.Request) {
164280 id := r.PathValue("id")
165281 lspName := r.PathValue("lsp")
@@ -171,6 +287,16 @@ func (c *controllerV1) handleGetWorkspaceLSPDiagnostics(w http.ResponseWriter, r
171287 jsonEncode(w, diagnostics)
172288}
173289
290+// handleGetWorkspaceSessions lists sessions for a workspace.
291+//
292+// @Summary List sessions
293+// @Tags sessions
294+// @Produce json
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]
174300func (c *controllerV1) handleGetWorkspaceSessions(w http.ResponseWriter, r *http.Request) {
175301 id := r.PathValue("id")
176302 sessions, err := c.backend.ListSessions(r.Context(), id)
@@ -181,6 +307,19 @@ func (c *controllerV1) handleGetWorkspaceSessions(w http.ResponseWriter, r *http
181307 jsonEncode(w, sessions)
182308}
183309
310+// handlePostWorkspaceSessions creates a new session in a workspace.
311+//
312+// @Summary Create session
313+// @Tags sessions
314+// @Accept json
315+// @Produce json
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]
184323func (c *controllerV1) handlePostWorkspaceSessions(w http.ResponseWriter, r *http.Request) {
185324 id := r.PathValue("id")
186325
@@ -199,6 +338,17 @@ func (c *controllerV1) handlePostWorkspaceSessions(w http.ResponseWriter, r *htt
199338 jsonEncode(w, sess)
200339}
201340
341+// handleGetWorkspaceSession returns a single session.
342+//
343+// @Summary Get session
344+// @Tags sessions
345+// @Produce json
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]
202352func (c *controllerV1) handleGetWorkspaceSession(w http.ResponseWriter, r *http.Request) {
203353 id := r.PathValue("id")
204354 sid := r.PathValue("sid")
@@ -210,6 +360,17 @@ func (c *controllerV1) handleGetWorkspaceSession(w http.ResponseWriter, r *http.
210360 jsonEncode(w, sess)
211361}
212362
363+// handleGetWorkspaceSessionHistory returns the history for a session.
364+//
365+// @Summary Get session history
366+// @Tags sessions
367+// @Produce json
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]
213374func (c *controllerV1) handleGetWorkspaceSessionHistory(w http.ResponseWriter, r *http.Request) {
214375 id := r.PathValue("id")
215376 sid := r.PathValue("sid")
@@ -221,6 +382,17 @@ func (c *controllerV1) handleGetWorkspaceSessionHistory(w http.ResponseWriter, r
221382 jsonEncode(w, history)
222383}
223384
385+// handleGetWorkspaceSessionMessages returns all messages for a session.
386+//
387+// @Summary Get session messages
388+// @Tags sessions
389+// @Produce json
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]
224396func (c *controllerV1) handleGetWorkspaceSessionMessages(w http.ResponseWriter, r *http.Request) {
225397 id := r.PathValue("id")
226398 sid := r.PathValue("sid")
@@ -232,6 +404,20 @@ func (c *controllerV1) handleGetWorkspaceSessionMessages(w http.ResponseWriter,
232404 jsonEncode(w, messagesToProto(messages))
233405}
234406
407+// handlePutWorkspaceSession updates a session.
408+//
409+// @Summary Update session
410+// @Tags sessions
411+// @Accept json
412+// @Produce json
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]
235421func (c *controllerV1) handlePutWorkspaceSession(w http.ResponseWriter, r *http.Request) {
236422 id := r.PathValue("id")
237423
@@ -250,6 +436,16 @@ func (c *controllerV1) handlePutWorkspaceSession(w http.ResponseWriter, r *http.
250436 jsonEncode(w, saved)
251437}
252438
439+// handleDeleteWorkspaceSession deletes a session.
440+//
441+// @Summary Delete session
442+// @Tags sessions
443+// @Param id path string true "Workspace ID"
444+// @Param sid path string true "Session ID"
445+// @Success 200
446+// @Failure 404 {object} proto.Error
447+// @Failure 500 {object} proto.Error
448+// @Router /workspaces/{id}/sessions/{sid} [delete]
253449func (c *controllerV1) handleDeleteWorkspaceSession(w http.ResponseWriter, r *http.Request) {
254450 id := r.PathValue("id")
255451 sid := r.PathValue("sid")
@@ -260,6 +456,17 @@ func (c *controllerV1) handleDeleteWorkspaceSession(w http.ResponseWriter, r *ht
260456 w.WriteHeader(http.StatusOK)
261457}
262458
459+// handleGetWorkspaceSessionUserMessages returns user messages for a session.
460+//
461+// @Summary Get user messages for session
462+// @Tags sessions
463+// @Produce json
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]
263470func (c *controllerV1) handleGetWorkspaceSessionUserMessages(w http.ResponseWriter, r *http.Request) {
264471 id := r.PathValue("id")
265472 sid := r.PathValue("sid")
@@ -271,6 +478,16 @@ func (c *controllerV1) handleGetWorkspaceSessionUserMessages(w http.ResponseWrit
271478 jsonEncode(w, messagesToProto(messages))
272479}
273480
481+// handleGetWorkspaceAllUserMessages returns all user messages across sessions.
482+//
483+// @Summary Get all user messages for workspace
484+// @Tags workspaces
485+// @Produce json
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]
274491func (c *controllerV1) handleGetWorkspaceAllUserMessages(w http.ResponseWriter, r *http.Request) {
275492 id := r.PathValue("id")
276493 messages, err := c.backend.ListAllUserMessages(r.Context(), id)
@@ -281,6 +498,17 @@ func (c *controllerV1) handleGetWorkspaceAllUserMessages(w http.ResponseWriter,
281498 jsonEncode(w, messagesToProto(messages))
282499}
283500
501+// handleGetWorkspaceSessionFileTrackerFiles lists files read in a session.
502+//
503+// @Summary List tracked files for session
504+// @Tags filetracker
505+// @Produce json
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]
284512func (c *controllerV1) handleGetWorkspaceSessionFileTrackerFiles(w http.ResponseWriter, r *http.Request) {
285513 id := r.PathValue("id")
286514 sid := r.PathValue("sid")
@@ -292,13 +520,22 @@ func (c *controllerV1) handleGetWorkspaceSessionFileTrackerFiles(w http.Response
292520 jsonEncode(w, files)
293521}
294522
523+// handlePostWorkspaceFileTrackerRead records a file read event.
524+//
525+// @Summary Record file read
526+// @Tags filetracker
527+// @Accept json
528+// @Param id path string true "Workspace ID"
529+// @Param request body proto.FileTrackerReadRequest true "File tracker read request"
530+// @Success 200
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]
295535func (c *controllerV1) handlePostWorkspaceFileTrackerRead(w http.ResponseWriter, r *http.Request) {
296536 id := r.PathValue("id")
297537
298− var req struct {
299− SessionID string `json:"session_id"`
300− Path string `json:"path"`
301− }
538+ var req proto.FileTrackerReadRequest
302539 if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
303540 c.server.logError(r, "Failed to decode request", "error", err)
304541 jsonError(w, http.StatusBadRequest, "failed to decode request")
@@ -312,6 +549,18 @@ func (c *controllerV1) handlePostWorkspaceFileTrackerRead(w http.ResponseWriter,
312549 w.WriteHeader(http.StatusOK)
313550}
314551
552+// handleGetWorkspaceFileTrackerLastRead returns the last read time for a file.
553+//
554+// @Summary Get last read time for file
555+// @Tags filetracker
556+// @Produce json
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]
315564func (c *controllerV1) handleGetWorkspaceFileTrackerLastRead(w http.ResponseWriter, r *http.Request) {
316565 id := r.PathValue("id")
317566 sid := r.URL.Query().Get("session_id")
@@ -325,12 +574,22 @@ func (c *controllerV1) handleGetWorkspaceFileTrackerLastRead(w http.ResponseWrit
325574 jsonEncode(w, t)
326575}
327576
577+// handlePostWorkspaceLSPStart starts an LSP server for a path.
578+//
579+// @Summary Start LSP server
580+// @Tags lsp
581+// @Accept json
582+// @Param id path string true "Workspace ID"
583+// @Param request body proto.LSPStartRequest true "LSP start request"
584+// @Success 200
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]
328589func (c *controllerV1) handlePostWorkspaceLSPStart(w http.ResponseWriter, r *http.Request) {
329590 id := r.PathValue("id")
330591
331− var req struct {
332− Path string `json:"path"`
333− }
592+ var req proto.LSPStartRequest
334593 if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
335594 c.server.logError(r, "Failed to decode request", "error", err)
336595 jsonError(w, http.StatusBadRequest, "failed to decode request")
@@ -344,6 +603,15 @@ func (c *controllerV1) handlePostWorkspaceLSPStart(w http.ResponseWriter, r *htt
344603 w.WriteHeader(http.StatusOK)
345604}
346605
606+// handlePostWorkspaceLSPStopAll stops all LSP servers.
607+//
608+// @Summary Stop all LSP servers
609+// @Tags lsp
610+// @Param id path string true "Workspace ID"
611+// @Success 200
612+// @Failure 404 {object} proto.Error
613+// @Failure 500 {object} proto.Error
614+// @Router /workspaces/{id}/lsps/stop [post]
347615func (c *controllerV1) handlePostWorkspaceLSPStopAll(w http.ResponseWriter, r *http.Request) {
348616 id := r.PathValue("id")
349617 if err := c.backend.LSPStopAll(r.Context(), id); err != nil {
@@ -353,6 +621,16 @@ func (c *controllerV1) handlePostWorkspaceLSPStopAll(w http.ResponseWriter, r *h
353621 w.WriteHeader(http.StatusOK)
354622}
355623
624+// handleGetWorkspaceAgent returns agent info for a workspace.
625+//
626+// @Summary Get agent info
627+// @Tags agent
628+// @Produce json
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]
356634func (c *controllerV1) handleGetWorkspaceAgent(w http.ResponseWriter, r *http.Request) {
357635 id := r.PathValue("id")
358636 info, err := c.backend.GetAgentInfo(id)
@@ -363,6 +641,18 @@ func (c *controllerV1) handleGetWorkspaceAgent(w http.ResponseWriter, r *http.Re
363641 jsonEncode(w, info)
364642}
365643
644+// handlePostWorkspaceAgent sends a message to the agent.
645+//
646+// @Summary Send message to agent
647+// @Tags agent
648+// @Accept json
649+// @Param id path string true "Workspace ID"
650+// @Param request body proto.AgentMessage true "Agent message"
651+// @Success 200
652+// @Failure 400 {object} proto.Error
653+// @Failure 404 {object} proto.Error
654+// @Failure 500 {object} proto.Error
655+// @Router /workspaces/{id}/agent [post]
366656func (c *controllerV1) handlePostWorkspaceAgent(w http.ResponseWriter, r *http.Request) {
367657 id := r.PathValue("id")
368658
@@ -380,6 +670,15 @@ func (c *controllerV1) handlePostWorkspaceAgent(w http.ResponseWriter, r *http.R
380670 w.WriteHeader(http.StatusOK)
381671}
382672
673+// handlePostWorkspaceAgentInit initializes the agent for a workspace.
674+//
675+// @Summary Initialize agent
676+// @Tags agent
677+// @Param id path string true "Workspace ID"
678+// @Success 200
679+// @Failure 404 {object} proto.Error
680+// @Failure 500 {object} proto.Error
681+// @Router /workspaces/{id}/agent/init [post]
383682func (c *controllerV1) handlePostWorkspaceAgentInit(w http.ResponseWriter, r *http.Request) {
384683 id := r.PathValue("id")
385684 if err := c.backend.InitAgent(r.Context(), id); err != nil {
@@ -389,6 +688,15 @@ func (c *controllerV1) handlePostWorkspaceAgentInit(w http.ResponseWriter, r *ht
389688 w.WriteHeader(http.StatusOK)
390689}
391690
691+// handlePostWorkspaceAgentUpdate updates the agent for a workspace.
692+//
693+// @Summary Update agent
694+// @Tags agent
695+// @Param id path string true "Workspace ID"
696+// @Success 200
697+// @Failure 404 {object} proto.Error
698+// @Failure 500 {object} proto.Error
699+// @Router /workspaces/{id}/agent/update [post]
392700func (c *controllerV1) handlePostWorkspaceAgentUpdate(w http.ResponseWriter, r *http.Request) {
393701 id := r.PathValue("id")
394702 if err := c.backend.UpdateAgent(r.Context(), id); err != nil {
@@ -398,6 +706,17 @@ func (c *controllerV1) handlePostWorkspaceAgentUpdate(w http.ResponseWriter, r *
398706 w.WriteHeader(http.StatusOK)
399707}
400708
709+// handleGetWorkspaceAgentSession returns a specific agent session.
710+//
711+// @Summary Get agent session
712+// @Tags agent
713+// @Produce json
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]
401720func (c *controllerV1) handleGetWorkspaceAgentSession(w http.ResponseWriter, r *http.Request) {
402721 id := r.PathValue("id")
403722 sid := r.PathValue("sid")
@@ -409,6 +728,16 @@ func (c *controllerV1) handleGetWorkspaceAgentSession(w http.ResponseWriter, r *
409728 jsonEncode(w, agentSession)
410729}
411730
731+// handlePostWorkspaceAgentSessionCancel cancels a running agent session.
732+//
733+// @Summary Cancel agent session
734+// @Tags agent
735+// @Param id path string true "Workspace ID"
736+// @Param sid path string true "Session ID"
737+// @Success 200
738+// @Failure 404 {object} proto.Error
739+// @Failure 500 {object} proto.Error
740+// @Router /workspaces/{id}/agent/sessions/{sid}/cancel [post]
412741func (c *controllerV1) handlePostWorkspaceAgentSessionCancel(w http.ResponseWriter, r *http.Request) {
413742 id := r.PathValue("id")
414743 sid := r.PathValue("sid")
@@ -419,6 +748,17 @@ func (c *controllerV1) handlePostWorkspaceAgentSessionCancel(w http.ResponseWrit
419748 w.WriteHeader(http.StatusOK)
420749}
421750
751+// handleGetWorkspaceAgentSessionPromptQueued returns whether a queued prompt exists.
752+//
753+// @Summary Get queued prompt status
754+// @Tags agent
755+// @Produce json
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]
422762func (c *controllerV1) handleGetWorkspaceAgentSessionPromptQueued(w http.ResponseWriter, r *http.Request) {
423763 id := r.PathValue("id")
424764 sid := r.PathValue("sid")
@@ -430,6 +770,16 @@ func (c *controllerV1) handleGetWorkspaceAgentSessionPromptQueued(w http.Respons
430770 jsonEncode(w, queued)
431771}
432772
773+// handlePostWorkspaceAgentSessionPromptClear clears the prompt queue for a session.
774+//
775+// @Summary Clear prompt queue
776+// @Tags agent
777+// @Param id path string true "Workspace ID"
778+// @Param sid path string true "Session ID"
779+// @Success 200
780+// @Failure 404 {object} proto.Error
781+// @Failure 500 {object} proto.Error
782+// @Router /workspaces/{id}/agent/sessions/{sid}/prompts/clear [post]
433783func (c *controllerV1) handlePostWorkspaceAgentSessionPromptClear(w http.ResponseWriter, r *http.Request) {
434784 id := r.PathValue("id")
435785 sid := r.PathValue("sid")
@@ -440,6 +790,16 @@ func (c *controllerV1) handlePostWorkspaceAgentSessionPromptClear(w http.Respons
440790 w.WriteHeader(http.StatusOK)
441791}
442792
793+// handlePostWorkspaceAgentSessionSummarize summarizes a session.
794+//
795+// @Summary Summarize session
796+// @Tags agent
797+// @Param id path string true "Workspace ID"
798+// @Param sid path string true "Session ID"
799+// @Success 200
800+// @Failure 404 {object} proto.Error
801+// @Failure 500 {object} proto.Error
802+// @Router /workspaces/{id}/agent/sessions/{sid}/summarize [post]
443803func (c *controllerV1) handlePostWorkspaceAgentSessionSummarize(w http.ResponseWriter, r *http.Request) {
444804 id := r.PathValue("id")
445805 sid := r.PathValue("sid")
@@ -450,6 +810,17 @@ func (c *controllerV1) handlePostWorkspaceAgentSessionSummarize(w http.ResponseW
450810 w.WriteHeader(http.StatusOK)
451811}
452812
813+// handleGetWorkspaceAgentSessionPromptList returns the list of queued prompts.
814+//
815+// @Summary List queued prompts
816+// @Tags agent
817+// @Produce json
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]
453824func (c *controllerV1) handleGetWorkspaceAgentSessionPromptList(w http.ResponseWriter, r *http.Request) {
454825 id := r.PathValue("id")
455826 sid := r.PathValue("sid")
@@ -461,6 +832,17 @@ func (c *controllerV1) handleGetWorkspaceAgentSessionPromptList(w http.ResponseW
461832 jsonEncode(w, prompts)
462833}
463834
835+// handleGetWorkspaceAgentDefaultSmallModel returns the default small model for a provider.
836+//
837+// @Summary Get default small model
838+// @Tags agent
839+// @Produce json
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]
464846func (c *controllerV1) handleGetWorkspaceAgentDefaultSmallModel(w http.ResponseWriter, r *http.Request) {
465847 id := r.PathValue("id")
466848 providerID := r.URL.Query().Get("provider_id")
@@ -472,6 +854,18 @@ func (c *controllerV1) handleGetWorkspaceAgentDefaultSmallModel(w http.ResponseW
472854 jsonEncode(w, model)
473855}
474856
857+// handlePostWorkspacePermissionsGrant grants a permission request.
858+//
859+// @Summary Grant permission
860+// @Tags permissions
861+// @Accept json
862+// @Param id path string true "Workspace ID"
863+// @Param request body proto.PermissionGrant true "Permission grant"
864+// @Success 200
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]
475869func (c *controllerV1) handlePostWorkspacePermissionsGrant(w http.ResponseWriter, r *http.Request) {
476870 id := r.PathValue("id")
477871
@@ -489,6 +883,18 @@ func (c *controllerV1) handlePostWorkspacePermissionsGrant(w http.ResponseWriter
489883 w.WriteHeader(http.StatusOK)
490884}
491885
886+// handlePostWorkspacePermissionsSkip sets whether to skip permission prompts.
887+//
888+// @Summary Set skip permissions
889+// @Tags permissions
890+// @Accept json
891+// @Param id path string true "Workspace ID"
892+// @Param request body proto.PermissionSkipRequest true "Permission skip request"
893+// @Success 200
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]
492898func (c *controllerV1) handlePostWorkspacePermissionsSkip(w http.ResponseWriter, r *http.Request) {
493899 id := r.PathValue("id")
494900
@@ -505,6 +911,16 @@ func (c *controllerV1) handlePostWorkspacePermissionsSkip(w http.ResponseWriter,
505911 }
506912}
507913
914+// handleGetWorkspacePermissionsSkip returns whether permission prompts are skipped.
915+//
916+// @Summary Get skip permissions status
917+// @Tags permissions
918+// @Produce json
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]
508924func (c *controllerV1) handleGetWorkspacePermissionsSkip(w http.ResponseWriter, r *http.Request) {
509925 id := r.PathValue("id")
510926 skip, err := c.backend.GetPermissionsSkip(id)