mirror of
https://github.com/coder/coder.git
synced 2026-06-03 13:08:25 +00:00
48ab492f49
Adds real-time git status watching for workspace agents, so the frontend
can subscribe over WebSocket and show
git file changes in near real-time.
1. Subscription is scoped to a **chat** via `GET
/api/experimental/chats/{chat}/git/watch`.
2. The workspace agent automatically determines which paths to watch
based on tool calls made by the chat (and its ancestor chats).
3. Workspace agent polls subscribed repo working trees on a 30s
interval, on tools calls, and on explicit `refresh` from the client.
4. Scans are rate-limited to at most once per second.
5. Edited paths are tracked **in-memory** inside the workspace agent.
There is no database persistence — state is lost on agent restart. This
will be addresses in a future PR.
6. Messages sent over WebSocket include a full-repo snapshot (unified
diff, branch, origin). A new message is emitted only when the snapshot
changes.
This PR was implemented with AI with me closely controlling what it's
doing. The code follows a plan file that was updated continuously during
implementation. Here's the file if you'd like to see it:
[project.md](https://gist.github.com/hugodutka/8722cf80c92f8a56555f7bc595b770e2).
It reflects the current state of the PR.
41 lines
883 B
Go
41 lines
883 B
Go
package agentfiles
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/go-chi/chi/v5"
|
|
"github.com/spf13/afero"
|
|
|
|
"cdr.dev/slog/v3"
|
|
"github.com/coder/coder/v2/agent/agentgit"
|
|
)
|
|
|
|
// API exposes file-related operations performed through the agent.
|
|
type API struct {
|
|
logger slog.Logger
|
|
filesystem afero.Fs
|
|
pathStore *agentgit.PathStore
|
|
}
|
|
|
|
func NewAPI(logger slog.Logger, filesystem afero.Fs, pathStore *agentgit.PathStore) *API {
|
|
api := &API{
|
|
logger: logger,
|
|
filesystem: filesystem,
|
|
pathStore: pathStore,
|
|
}
|
|
return api
|
|
}
|
|
|
|
// Routes returns the HTTP handler for file-related routes.
|
|
func (api *API) Routes() http.Handler {
|
|
r := chi.NewRouter()
|
|
|
|
r.Post("/list-directory", api.HandleLS)
|
|
r.Get("/read-file", api.HandleReadFile)
|
|
r.Get("/read-file-lines", api.HandleReadFileLines)
|
|
r.Post("/write-file", api.HandleWriteFile)
|
|
r.Post("/edit-files", api.HandleEditFiles)
|
|
|
|
return r
|
|
}
|