feat(palier-3): recherche globale, mes issues, briefing ntfy, MCP lecture
- client: search_issues (/repos/issues/search, type=issues, assigned_by), delete_label + forget_label_cache; models: kv_store - /search groupe par projet avec colonne Kanban; /my = issues ouvertes assignées à l'utilisateur du jeton (get_user) - briefing: _briefing_data (focus, âgées, milestones <= 7 j, activité journal), page /briefing, /api/briefing, envoi ntfy manuel + planificateur lifespan à KANBANTE_BRIEFING_TIME (kv briefing_last_sent, pas de doublon); app/briefing.py = format texte + envoi ntfy (en-têtes ASCII) - MCP: POST /mcp JSON-RPC (initialize, tools/list, tools/call, ping, notifications 202), 7 outils en lecture seule, GET /mcp de découverte; erreurs -32601/-32700, isError pour les outils - focus refactoré en _collect_focus_groups réutilisé par le briefing et l'outil MCP get_focus
This commit is contained in:
@@ -269,6 +269,37 @@ class GiteaClient:
|
||||
)
|
||||
r.raise_for_status()
|
||||
|
||||
async def delete_label(self, owner: str, repo: str, label_id: int) -> None:
|
||||
"""Delete a label definition from the repo (all issues lose it)."""
|
||||
r = await self.client.delete(f"/repos/{owner}/{repo}/labels/{label_id}")
|
||||
r.raise_for_status()
|
||||
self.forget_label_cache(owner, repo)
|
||||
|
||||
def forget_label_cache(self, owner: str, repo: str) -> None:
|
||||
cache = self.__dict__.get("_label_cache")
|
||||
if cache:
|
||||
cache.pop(f"{owner}/{repo}", None)
|
||||
|
||||
# ── Issue search (global + assigned) ───────────────────
|
||||
|
||||
async def search_issues(
|
||||
self,
|
||||
q: str = "",
|
||||
state: str = "open",
|
||||
assigned_by: str | None = None,
|
||||
) -> list[dict]:
|
||||
"""Search issues across every repo visible to the token.
|
||||
|
||||
Uses Gitea's /repos/issues/search (type=issues excludes PRs).
|
||||
Results carry their repository in issue["repository"].
|
||||
"""
|
||||
params: dict[str, Any] = {"state": state, "type": "issues"}
|
||||
if q:
|
||||
params["q"] = q
|
||||
if assigned_by:
|
||||
params["assigned_by"] = assigned_by
|
||||
return await self._get_all_pages("/repos/issues/search", **params)
|
||||
|
||||
# ── Milestones ─────────────────────────────────────────
|
||||
|
||||
async def get_milestones(
|
||||
|
||||
Reference in New Issue
Block a user