MarkStale persists the git ref for a chat (or all chats on a workspace when no ChatID is provided), setting stale_at to the past so the next tick picks them up. Publishes a diff status event for each affected chat. Called from workspaceagents handlers. No goroutines spawned.
(ctx context.Context, p MarkStaleParams)
| 290 | // event for each affected chat. |
| 291 | // Called from workspaceagents handlers. No goroutines spawned. |
| 292 | func (w *Worker) MarkStale(ctx context.Context, p MarkStaleParams) { |
| 293 | if p.Branch == "" || p.Origin == "" { |
| 294 | return |
| 295 | } |
| 296 | |
| 297 | // When a specific chat is identified, target it directly |
| 298 | // instead of broadcasting to every chat on the workspace. |
| 299 | // Note: this path does not verify that the chat belongs to |
| 300 | // WorkspaceID. This is safe because ChatID originates from |
| 301 | // chatd via the agent (trusted data flow), but differs from |
| 302 | // the broadcast path which filters by workspace. |
| 303 | if p.ChatID != uuid.Nil { |
| 304 | w.markStaleSingle(ctx, p.ChatID, p.Branch, p.Origin) |
| 305 | return |
| 306 | } |
| 307 | |
| 308 | // Broadcast path: scope by workspace. GetChatsByWorkspaceIDs |
| 309 | // filters archived=false, which is intentional: archived |
| 310 | // chats aren't in the active sidebar and don't need refreshed |
| 311 | // git refs. |
| 312 | chats, err := w.store.GetChatsByWorkspaceIDs(ctx, []uuid.UUID{p.WorkspaceID}) |
| 313 | if err != nil { |
| 314 | w.logger.Warn(ctx, "list chats for git ref storage", |
| 315 | slog.F("workspace_id", p.WorkspaceID), |
| 316 | slog.Error(err)) |
| 317 | return |
| 318 | } |
| 319 | |
| 320 | for _, chat := range chats { |
| 321 | w.markStaleSingle(ctx, chat.ID, p.Branch, p.Origin) |
| 322 | } |
| 323 | } |
| 324 | |
| 325 | // markStaleSingle upserts the git ref for a single chat and |
| 326 | // publishes a diff-status change event. |