Documentation
¶
Overview ¶
Package diff serves the review session's plain-JSON routes under /api/v1/diff.
Separate from handler/status, which maps one thing - the live status report - onto StatusService's two RPCs. These routes ride no proto service at all, and every constructor here was named NewDiff* while living there, which is the package boundary announcing itself.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type BranchesHandler ¶
BranchesHandler serves GET /api/v1/diff/branches: the other branches changing the files this changeset changes, so a reader learns about a collision before the merge does.
Its own route rather than a field on the changeset, for the reason the review lookup has one: it costs a fork per branch, and the patch has to paint before anything that forks is allowed to hold it up. This ARRIVES, like the conversation does.
It reads what has already been fetched and never fetches. The answer is therefore as fresh as the reader's last fetch and no fresher, which the surface says out loud rather than implying it is live.
func NewBranchesHandler ¶
func NewBranchesHandler(workspace branchSource, log *slog.Logger) *BranchesHandler
NewBranchesHandler returns the branch-overlap handler. A nil workspace reports none, which is what a daemon with no workspace has.
type ContextHandler ¶
ContextHandler serves bounded, snapshot-paired file context.
func NewContextHandler ¶
func NewContextHandler(root string, src patchSource, log *slog.Logger) *ContextHandler
NewContextHandler returns the bounded loopback context handler.
type Handler ¶
Handler serves GET /api/v1/diff: the changed files annotated with what the workspace knows - role (generated or not), owning project, changed-symbol reach, observed coverage - in the order magus recommends reading them.
It is the differentiated half of the review surface and a SECOND round trip on purpose. /api/v1/diff/patch returns the patch in milliseconds; this one loads the symbol shards and walks a reverse closure. Folding them together would hold the whole diff behind the slowest overlay for no reading benefit.
The caller passes the paths it is actually reviewing, repeated as `path`. That is not an optimization: re-deriving the changed set here would race an edit made since the patch was read and annotate a file the reader cannot see.
func NewHandler ¶
NewHandler returns the GET /api/v1/diff handler reading from src. sessions and root may be nil/empty, which serves a session-less review - the shape is identical, so a client needs no branch for a daemon that is not pairing.
type PatchHandler ¶
PatchHandler serves GET /api/v1/diff/patch: the working tree's uncommitted changes as one unified patch, for the console's review surface.
The changeset ships PARSED, and the raw patch travels beside it for a caller that wants the interchange format itself. Parsing here rather than in the browser is what keeps one reader in the product - see internal/diff/parse.go for why a second one must not be written.
Optional `path` query parameters scope the diff, repeated once per path. Absent, the whole repository is diffed. A service with no workspace yields 503, not 500 - the same posture the insight route takes, because "no workspace yet" is a state the console renders rather than an error it reports.
func NewPatchHandler ¶
func NewPatchHandler(src patchSource, log *slog.Logger) *PatchHandler
NewPatchHandler returns the GET /api/v1/diff/patch handler reading from src.
type ReviewHandler ¶
type ReviewHandler struct {
handler.Base
// Sessions and Root are OPTIONAL, set by the daemon wiring after construction: with them the
// handler can say which threads the reader has not seen before, and without them it serves
// the conversation unmarked. A caller that has no session store is not a caller with an
// empty one, so the marking is skipped rather than every thread being called new.
Sessions *changeset.Store
Root string
// contains filtered or unexported fields
}
ReviewHandler serves GET /api/v1/diff/review: which review is open for this tree, and the comment threads already on it.
Beside the session handler because they are two halves of one conversation, but a SEPARATE route because they cost different amounts: the session is local state and returns in microseconds, while this one crosses the network to a forge and can hang for as long as that forge feels like taking. Serving them together would hold the diff behind somebody else's outage.
It never fails. No provider wired, no pull request, an unreachable host: all of them are a closed target with a reason, because the reader's options are identical in every case and a surface that rendered them as errors would be accusing them of something they did not do.
func NewReviewHandler ¶
func NewReviewHandler(workspace reviewSource, log *slog.Logger) *ReviewHandler
NewReviewHandler returns the review-lookup handler. A nil workspace reports no review, which is what a daemon with no workspace has.
type RunHandler ¶
RunHandler serves /api/v1/diff/run: the reader asks a question about the change in front of them - does this still pass? - and gets the answer from the machine the code is on.
This is the one review capability that cannot have a provider gap. It asks the local workspace rather than a forge, so it works identically on GitHub, GitLab, a fork, or no forge at all, and on git or hg alike. Nothing below touches either boundary.
A run is named by a TARGET and a PROJECT, never by an argv. The daemon's job dispatch admits the resulting `run <target> <project>` only when the magusfile declares that target for that project, so the console can ask for work the workspace already defines and cannot ask for anything else. That is strictly less than a terminal's `magus run`, which is the bar a browser- reachable surface has to clear.
func NewRunHandler ¶
func NewRunHandler(workspace runSource, cacheDir, version string, log *slog.Logger) *RunHandler
NewRunHandler returns the inline-run handler. A nil workspace declares no targets, so every request is refused as undeclared - which is what a daemon with no workspace can honestly say.
type SessionHandler ¶
type SessionHandler struct {
handler.Base
SessionOptions
}
SessionHandler serves the live paired-review session.
Every write here is stamped DiffAuthorHuman, because this route is only reachable from the console and the CLI. The agent's half lives on the MCP surface and is stamped DiffAuthorAgent there. Authorship is decided by WHICH ROUTE the write arrived on and never by the payload, which is what makes it unforgeable: an agent cannot reach this handler, so it cannot post as the person.
It is one route with an `op` rather than five, because these are all small mutations of one object and a client applies them from one place - a keypress handler. Five routes would be five fetch wrappers for no gain in clarity.
func NewSessionHandler ¶
func NewSessionHandler(opts SessionOptions, log *slog.Logger) *SessionHandler
NewSessionHandler returns the paired-review handler.
type SessionOptions ¶
type SessionOptions struct {
Sessions *changeset.Store
// Workspace answers where this tree's changes are discussed and reads the working patch.
// Nil serves everything except the review.
Workspace reviewSource
Root string
// CacheDir is where read receipts live. Empty records none.
CacheDir string
// Telemetry records the review families; nil records none.
Telemetry observability.Provider
}
SessionOptions is what both review routes need from the daemon.
A struct because the alternative was five positional arguments with Root and CacheDir adjacent and both string.