@diegotsi/flint-mcp 1.2.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +94 -24
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,46 +1,50 @@
|
|
|
1
1
|
# @diegotsi/flint-mcp
|
|
2
2
|
|
|
3
|
-
MCP (Model Context Protocol) server for [Flint](https://github.com/diegotsi/flint) —
|
|
3
|
+
MCP (Model Context Protocol) server for [Flint](https://github.com/diegotsi/flint) — triage, analyze, and fix your bug reports straight from Claude Code, Cursor, Claude Desktop, or any MCP client.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Quick start
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
| `get_bug` | Full report detail — AI root cause, console logs, environment |
|
|
11
|
-
| `search_code` | Search the indexed codebase (not yet available via MCP) |
|
|
12
|
-
| `suggest_fix` | AI-generated fix suggestion for a bug |
|
|
13
|
-
| `triage_bug` | Set assignee, severity, area or notes |
|
|
14
|
-
| `resolve_bug` | Mark a bug as resolved |
|
|
15
|
-
| `create_fix_pr` | Open a GitHub PR with an AI-generated fix |
|
|
16
|
-
| `get_analytics` | Project analytics (volume, severity, releases, SLA) |
|
|
17
|
-
| `chat_about_bug` | Ask questions about a bug with full AI context |
|
|
7
|
+
1. **Get a personal access token** — a `flint_pat_…` string (step 1 below).
|
|
8
|
+
2. **Add the MCP** to your client with that token (step 2 below).
|
|
9
|
+
3. **Ask away** — _"list my P1 bugs"_, _"what's the root cause of bug clxx123"_, _"open a PR for the suggested fix"_.
|
|
18
10
|
|
|
19
|
-
|
|
11
|
+
---
|
|
20
12
|
|
|
21
|
-
|
|
22
|
-
|---|---|---|
|
|
23
|
-
| `FLINT_SERVER_URL` | yes | URL of your Flint server, e.g. `https://api.yourflint.com` |
|
|
24
|
-
| `FLINT_ADMIN_KEY` | yes | Admin key (`X-Admin-Key`) — **not** the project key used by the widget SDK |
|
|
25
|
-
| `FLINT_PROJECT_ID` | no | Default project — avoids passing `projectId` on every call |
|
|
13
|
+
## 1. Get a token
|
|
26
14
|
|
|
27
|
-
|
|
15
|
+
The MCP authenticates as **you**, with a personal access token — not the shared admin key. So actions are scoped to your account and role, and show up in the audit log under your name.
|
|
28
16
|
|
|
29
|
-
|
|
17
|
+
1. Open the Flint **admin dashboard** and sign in.
|
|
18
|
+
2. Go to **Settings → Team → Personal Access Tokens**.
|
|
19
|
+
3. Click **New token**, give it a name (e.g. `My laptop MCP`), optionally pick an expiry, and **Create**.
|
|
20
|
+
4. **Copy the token now** (`flint_pat_…`) — it's shown **once** and stored only as a hash. If you lose it, just create another.
|
|
21
|
+
|
|
22
|
+
Tokens are revocable any time from the same screen (they show their last-used time), so create one per machine and revoke it if a laptop is lost.
|
|
23
|
+
|
|
24
|
+
> **Self-hosting without user accounts?** You can fall back to the server's shared `FLINT_ADMIN_KEY` (god-mode across every project). Prefer a per-user token whenever you have one.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 2. Add the MCP
|
|
29
|
+
|
|
30
|
+
You'll also need:
|
|
31
|
+
|
|
32
|
+
- **`FLINT_SERVER_URL`** — your Flint API URL, e.g. `https://api.yourflint.com`.
|
|
33
|
+
- **`FLINT_PROJECT_ID`** _(optional)_ — a default project so you don't pass `projectId` on every call. Find it in the project's URL in the dashboard.
|
|
30
34
|
|
|
31
35
|
### Claude Code
|
|
32
36
|
|
|
33
37
|
```bash
|
|
34
38
|
claude mcp add flint \
|
|
35
39
|
-e FLINT_SERVER_URL=https://api.yourflint.com \
|
|
36
|
-
-e
|
|
40
|
+
-e FLINT_API_TOKEN=flint_pat_your_token \
|
|
37
41
|
-e FLINT_PROJECT_ID=your-project-id \
|
|
38
42
|
-- npx -y @diegotsi/flint-mcp
|
|
39
43
|
```
|
|
40
44
|
|
|
41
45
|
### Cursor / Windsurf / Claude Desktop
|
|
42
46
|
|
|
43
|
-
Add to your MCP config (`.cursor/mcp.json`, `~/.codeium/windsurf/mcp_config.json
|
|
47
|
+
Add to your MCP config (`.cursor/mcp.json`, `~/.codeium/windsurf/mcp_config.json`, or `claude_desktop_config.json`):
|
|
44
48
|
|
|
45
49
|
```json
|
|
46
50
|
{
|
|
@@ -50,7 +54,7 @@ Add to your MCP config (`.cursor/mcp.json`, `~/.codeium/windsurf/mcp_config.json
|
|
|
50
54
|
"args": ["-y", "@diegotsi/flint-mcp"],
|
|
51
55
|
"env": {
|
|
52
56
|
"FLINT_SERVER_URL": "https://api.yourflint.com",
|
|
53
|
-
"
|
|
57
|
+
"FLINT_API_TOKEN": "flint_pat_your_token",
|
|
54
58
|
"FLINT_PROJECT_ID": "your-project-id"
|
|
55
59
|
}
|
|
56
60
|
}
|
|
@@ -58,6 +62,72 @@ Add to your MCP config (`.cursor/mcp.json`, `~/.codeium/windsurf/mcp_config.json
|
|
|
58
62
|
}
|
|
59
63
|
```
|
|
60
64
|
|
|
65
|
+
Restart the client (or reload the MCP servers) and Flint's tools become available.
|
|
66
|
+
|
|
67
|
+
### Verify / alternatives
|
|
68
|
+
|
|
69
|
+
`npx` fetches and runs the published package on demand — there's no separate install step. To confirm it works, run it once with no env; it tells you what's missing and exits, which means it fetched and launched fine:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
npx -y @diegotsi/flint-mcp
|
|
73
|
+
# → [Flint MCP] Set FLINT_API_TOKEN (per-user, recommended) or FLINT_ADMIN_KEY
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Prefer a pinned global binary instead of `npx`? Install once and point `command` at it:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
npm i -g @diegotsi/flint-mcp # then use "flint-mcp" as the MCP command
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## 3. Use it
|
|
85
|
+
|
|
86
|
+
Once connected, ask your assistant things like:
|
|
87
|
+
|
|
88
|
+
- _"List the open P1 bugs in this project."_
|
|
89
|
+
- _"Show me bug `clxx123` — root cause and suggested fix."_
|
|
90
|
+
- _"Triage bug `clxx123`: assign it to me, set severity P2."_
|
|
91
|
+
- _"Open a GitHub PR with the suggested fix for `clxx123`."_
|
|
92
|
+
- _"What's our bug volume and SLA this week?"_
|
|
93
|
+
|
|
94
|
+
### Available tools
|
|
95
|
+
|
|
96
|
+
| Tool | Description |
|
|
97
|
+
|---|---|
|
|
98
|
+
| `list_bugs` | List bug reports with filters (status, severity, release, …) |
|
|
99
|
+
| `get_bug` | Full report detail — AI root cause, console logs, environment |
|
|
100
|
+
| `search_code` | Search the indexed codebase (not yet available via MCP) |
|
|
101
|
+
| `suggest_fix` | AI-generated fix suggestion for a bug |
|
|
102
|
+
| `triage_bug` | Set assignee, severity, area or notes |
|
|
103
|
+
| `resolve_bug` | Mark a bug as resolved |
|
|
104
|
+
| `create_fix_pr` | Open a GitHub PR with an AI-generated fix |
|
|
105
|
+
| `get_analytics` | Project analytics (volume, severity, releases, SLA) |
|
|
106
|
+
| `chat_about_bug` | Ask questions about a bug with full AI context |
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Configuration reference
|
|
111
|
+
|
|
112
|
+
| Env var | Required | Description |
|
|
113
|
+
|---|---|---|
|
|
114
|
+
| `FLINT_SERVER_URL` | yes | URL of your Flint server, e.g. `https://api.yourflint.com` |
|
|
115
|
+
| `FLINT_API_TOKEN` | yes\* | **Recommended.** Per-user personal access token (`flint_pat_…`) from **Settings → Team → Personal Access Tokens**. Scoped to your account, revocable, and audited. |
|
|
116
|
+
| `FLINT_ADMIN_KEY` | yes\* | Shared admin key (`X-Admin-Key`) — god-mode across all projects. Use only when a per-user token isn't available. |
|
|
117
|
+
| `FLINT_PROJECT_ID` | no | Default project — avoids passing `projectId` on every call |
|
|
118
|
+
|
|
119
|
+
> \* Provide **either** `FLINT_API_TOKEN` (preferred) **or** `FLINT_ADMIN_KEY`. The token takes precedence. `FLINT_API_KEY` is still accepted as a fallback for `FLINT_ADMIN_KEY`.
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## Troubleshooting
|
|
124
|
+
|
|
125
|
+
- **401 / Unauthorized** — the token is wrong, expired, or revoked. Create a fresh one under **Settings → Team → Personal Access Tokens**. If you set both vars, `FLINT_API_TOKEN` wins over `FLINT_ADMIN_KEY`.
|
|
126
|
+
- **`projectId is required`** — set `FLINT_PROJECT_ID`, or pass `projectId` in the request.
|
|
127
|
+
- **Nothing happens / tools missing** — confirm `FLINT_SERVER_URL` points at your Flint **API** and that the client was restarted after editing its MCP config.
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
61
131
|
## Development
|
|
62
132
|
|
|
63
133
|
```bash
|
package/dist/index.js
CHANGED
|
@@ -9,6 +9,7 @@ import { z } from "zod";
|
|
|
9
9
|
|
|
10
10
|
// src/client.ts
|
|
11
11
|
var serverUrl = (process.env.FLINT_SERVER_URL ?? "http://localhost:3333").replace(/\/$/, "");
|
|
12
|
+
var apiToken = process.env.FLINT_API_TOKEN ?? "";
|
|
12
13
|
var adminKey = process.env.FLINT_ADMIN_KEY ?? process.env.FLINT_API_KEY ?? "";
|
|
13
14
|
var defaultProjectId = process.env.FLINT_PROJECT_ID ?? "";
|
|
14
15
|
function resolveProjectId(pid) {
|
|
@@ -18,13 +19,13 @@ if (!serverUrl) {
|
|
|
18
19
|
console.error("[Flint MCP] FLINT_SERVER_URL is required");
|
|
19
20
|
process.exit(1);
|
|
20
21
|
}
|
|
21
|
-
if (!adminKey) {
|
|
22
|
-
console.error("[Flint MCP]
|
|
22
|
+
if (!apiToken && !adminKey) {
|
|
23
|
+
console.error("[Flint MCP] Set FLINT_API_TOKEN (per-user, recommended) or FLINT_ADMIN_KEY");
|
|
23
24
|
process.exit(1);
|
|
24
25
|
}
|
|
25
26
|
function headers() {
|
|
26
27
|
return {
|
|
27
|
-
"X-Admin-Key": adminKey,
|
|
28
|
+
...apiToken ? { Authorization: `Bearer ${apiToken}` } : { "X-Admin-Key": adminKey },
|
|
28
29
|
"Content-Type": "application/json"
|
|
29
30
|
};
|
|
30
31
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/tools/chatAboutBug.ts","../src/client.ts","../src/tools/createFixPR.ts","../src/tools/getAnalytics.ts","../src/tools/getBug.ts","../src/shouldShowFix.ts","../src/tools/listBugs.ts","../src/tools/resolveBug.ts","../src/tools/searchCode.ts","../src/tools/suggestFix.ts","../src/tools/triageBug.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport {\n registerChatAboutBug,\n registerCreateFixPR,\n registerGetAnalytics,\n registerGetBug,\n registerListBugs,\n registerResolveBug,\n registerSearchCode,\n registerSuggestFix,\n registerTriageBug,\n} from \"./tools/index.js\";\n\nconst server = new McpServer({\n name: \"flint\",\n version: \"1.0.0\",\n description:\n \"Flint bug tracking & error monitoring — list bugs, search code, suggest fixes, triage issues directly from your editor.\",\n});\n\nregisterListBugs(server);\nregisterGetBug(server);\nregisterSearchCode(server);\nregisterSuggestFix(server);\nregisterTriageBug(server);\nregisterResolveBug(server);\nregisterCreateFixPR(server);\nregisterGetAnalytics(server);\nregisterChatAboutBug(server);\n\nasync function main() {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n console.error(\"Flint MCP Server running on stdio\");\n}\n\nmain().catch((error) => {\n console.error(\"Fatal error in MCP server:\", error);\n process.exit(1);\n});\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { apiPost, resolveProjectId } from \"../client.js\";\n\nexport function registerChatAboutBug(server: McpServer) {\n server.registerTool(\n \"chat_about_bug\",\n {\n description:\n \"Ask a question about a specific bug report. Uses AI with full context (code, similar bugs, fix history) to answer.\",\n inputSchema: {\n projectId: z.string().optional().describe(\"Project ID (uses FLINT_PROJECT_ID env if omitted)\"),\n reportId: z.string().describe(\"The bug report ID\"),\n message: z.string().describe(\"The message/question to ask about this bug\"),\n },\n },\n async ({ projectId: pid, reportId, message }) => {\n const projectId = resolveProjectId(pid);\n if (!projectId)\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Error: projectId is required. Set FLINT_PROJECT_ID env or pass projectId.\",\n },\n ],\n };\n let result: any;\n try {\n result = await apiPost(`/api/v1/admin/projects/${projectId}/reports/${reportId}/chat`, { message });\n } catch (err: any) {\n const errorMsg = err.message ?? \"Unknown error\";\n return {\n content: [\n {\n type: \"text\" as const,\n text: [\n `Failed to chat about bug #${reportId}: ${errorMsg}`,\n \"\",\n \"The AI chat feature may not be enabled for this project, or the bug report may not exist.\",\n \"Check the Flint Admin Dashboard for more details.\",\n ].join(\"\\n\"),\n },\n ],\n };\n }\n\n // The chat endpoint may return the response in different formats:\n // - { response: \"...\" } or { text: \"...\" } or { message: \"...\" }\n // - or the result itself could be a string (if the response was plain text parsed as JSON string)\n let responseText: string;\n if (typeof result === \"string\") {\n responseText = result;\n } else if (result?.response) {\n responseText = result.response;\n } else if (result?.text) {\n responseText = result.text;\n } else if (result?.message) {\n responseText = result.message;\n } else if (result?.content) {\n // Handle case where the API returns an array of content blocks (Anthropic-style)\n if (Array.isArray(result.content)) {\n responseText = result.content\n .filter((block: any) => block.type === \"text\")\n .map((block: any) => block.text)\n .join(\"\\n\");\n } else {\n responseText = String(result.content);\n }\n } else {\n responseText = JSON.stringify(result, null, 2);\n }\n\n if (!responseText || responseText === \"null\" || responseText === \"undefined\") {\n responseText = \"No response was generated. The AI may need more context about this bug.\";\n }\n\n return {\n content: [{ type: \"text\" as const, text: responseText }],\n };\n },\n );\n}\n","/**\n * HTTP client for the Flint Admin API.\n * Used by MCP tools instead of direct Prisma access.\n */\n\nconst serverUrl = (process.env.FLINT_SERVER_URL ?? \"http://localhost:3333\").replace(/\\/$/, \"\");\n// FLINT_API_KEY kept as fallback for setups created before the rename\nconst adminKey = process.env.FLINT_ADMIN_KEY ?? process.env.FLINT_API_KEY ?? \"\";\nexport const defaultProjectId = process.env.FLINT_PROJECT_ID ?? \"\";\n\nexport function resolveProjectId(pid?: string): string | null {\n return pid || defaultProjectId || null;\n}\n\nif (!serverUrl) {\n console.error(\"[Flint MCP] FLINT_SERVER_URL is required\");\n process.exit(1);\n}\nif (!adminKey) {\n console.error(\"[Flint MCP] FLINT_ADMIN_KEY is required\");\n process.exit(1);\n}\n\nfunction headers(): Record<string, string> {\n return {\n \"X-Admin-Key\": adminKey,\n \"Content-Type\": \"application/json\",\n };\n}\n\nexport async function apiGet<T = unknown>(path: string): Promise<T> {\n const res = await fetch(`${serverUrl}${path}`, { headers: headers() });\n if (!res.ok) {\n const body = await res.text().catch(() => \"\");\n throw new Error(`API ${res.status}: ${body.slice(0, 200)}`);\n }\n return res.json() as Promise<T>;\n}\n\nexport async function apiPatch<T = unknown>(path: string, body?: unknown): Promise<T> {\n const res = await fetch(`${serverUrl}${path}`, {\n method: \"PATCH\",\n headers: headers(),\n body: body ? JSON.stringify(body) : undefined,\n });\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n throw new Error(`API ${res.status}: ${text.slice(0, 200)}`);\n }\n return res.json() as Promise<T>;\n}\n\nexport async function apiPost<T = unknown>(path: string, body?: unknown): Promise<T> {\n const res = await fetch(`${serverUrl}${path}`, {\n method: \"POST\",\n headers: headers(),\n body: body ? JSON.stringify(body) : undefined,\n });\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n throw new Error(`API ${res.status}: ${text.slice(0, 200)}`);\n }\n return res.json() as Promise<T>;\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { apiPost, resolveProjectId } from \"../client.js\";\n\nexport function registerCreateFixPR(server: McpServer) {\n server.registerTool(\n \"create_fix_pr\",\n {\n description:\n \"Create a GitHub Pull Request with the AI-suggested fix for a bug report. Requires the bug to have a suggested fix.\",\n inputSchema: {\n projectId: z.string().optional().describe(\"Project ID (uses FLINT_PROJECT_ID env if omitted)\"),\n reportId: z.string().describe(\"The bug report ID\"),\n branch: z.string().optional().describe(\"Branch name (default: fix/<reportId>)\"),\n commitMessage: z.string().optional().describe(\"Custom commit message\"),\n },\n },\n async ({ projectId: pid, reportId, branch, commitMessage }) => {\n const projectId = resolveProjectId(pid);\n if (!projectId)\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Error: projectId is required. Set FLINT_PROJECT_ID env or pass projectId.\",\n },\n ],\n };\n const body: Record<string, string> = {};\n if (branch) body.branch = branch;\n if (commitMessage) body.commitMessage = commitMessage;\n\n let result: any;\n try {\n result = await apiPost(\n `/api/v1/admin/projects/${projectId}/reports/${reportId}/create-fix-pr`,\n Object.keys(body).length > 0 ? body : undefined,\n );\n } catch (err: any) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Failed to create fix PR for bug #${reportId}: ${err.message ?? \"Unknown error\"}`,\n },\n ],\n };\n }\n\n const prUrl = result?.pr_url ?? result?.prUrl ?? result?.url ?? null;\n\n const text = prUrl\n ? [\n `## Pull Request Created for Bug #${reportId}`,\n \"\",\n `**PR URL:** ${prUrl}`,\n \"\",\n \"The PR has been created with the AI-suggested fix. Review and merge when ready.\",\n ].join(\"\\n\")\n : [\n `## Fix PR Request Submitted for Bug #${reportId}`,\n \"\",\n \"The request to create a fix PR was accepted.\",\n result?.message\n ? `Server response: ${result.message}`\n : \"Check the Flint Admin Dashboard or your GitHub repository for the PR.\",\n ].join(\"\\n\");\n\n return {\n content: [{ type: \"text\" as const, text }],\n };\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { apiGet, resolveProjectId } from \"../client.js\";\n\nexport function registerGetAnalytics(server: McpServer) {\n server.registerTool(\n \"get_analytics\",\n {\n description:\n \"Get project analytics: total reports, open/critical counts, resolution time, triage rate, top errors, and trends.\",\n inputSchema: {\n projectId: z.string().optional().describe(\"Project ID (uses FLINT_PROJECT_ID env if omitted)\"),\n period: z.string().optional().describe(\"Time period: 7d, 30d, or 90d (default 30d)\"),\n },\n },\n async ({ projectId: pid, period }) => {\n const projectId = resolveProjectId(pid);\n if (!projectId)\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Error: projectId is required. Set FLINT_PROJECT_ID env or pass projectId.\",\n },\n ],\n };\n const periodStr = period ?? \"30d\";\n\n let data: any;\n try {\n data = await apiGet(`/api/v1/admin/projects/${projectId}/analytics?period=${periodStr}`);\n } catch (err: any) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Failed to fetch analytics for project ${projectId}: ${err.message ?? \"Unknown error\"}`,\n },\n ],\n };\n }\n\n // The analytics endpoint may return data in different shapes.\n // We handle the most common fields gracefully.\n const total = data.total ?? data.totalReports ?? \"—\";\n const open = data.open ?? data.openCount ?? \"—\";\n const inProgress = data.inProgress ?? data.inProgressCount ?? \"—\";\n const resolved = data.resolved ?? data.resolvedCount ?? \"—\";\n const critical = data.critical ?? data.criticalCount ?? \"—\";\n const avgResolution = data.avgResolutionHours ?? data.avgResolution ?? \"—\";\n const triageRate = data.triageRate ?? data.triagedPercent ?? \"—\";\n\n const sections: string[] = [\n `## Analytics (${periodStr})`,\n \"\",\n `**Total:** ${total} reports | **Open:** ${open} | **In Progress:** ${inProgress} | **Critical (P1/P2):** ${critical} | **Resolved:** ${resolved}`,\n `**Avg Resolution:** ${avgResolution}${typeof avgResolution === \"number\" ? \"h\" : \"\"} | **Triage Rate:** ${triageRate}${typeof triageRate === \"number\" ? \"%\" : \"\"}`,\n ];\n\n // Top errors\n const topErrors: any[] = data.topErrors ?? data.errorGroups ?? data.topErrorGroups ?? [];\n if (topErrors.length > 0) {\n sections.push(\"\", \"### Top Errors\");\n topErrors.forEach((e: any, i: number) => {\n const title = e.title ?? e.message ?? \"Unknown error\";\n const events = e.error_count ?? e.errorCount ?? e.count ?? 0;\n const users = e.user_count ?? e.userCount ?? 0;\n sections.push(`${i + 1}. ${title} (${events} events${users ? `, ${users} users` : \"\"})`);\n });\n }\n\n // Trends\n const trends: any[] = data.trends ?? data.dailyCounts ?? [];\n if (trends.length > 0) {\n sections.push(\"\", \"### Trend (daily bug count)\");\n const recent = trends.slice(-7);\n const trendLine = recent\n .map((t: any) => {\n const date = t.date ?? t.day ?? t.label ?? \"?\";\n const count = t.count ?? t.total ?? 0;\n return `${date}: ${count}`;\n })\n .join(\" | \");\n sections.push(trendLine);\n }\n\n return {\n content: [{ type: \"text\" as const, text: sections.join(\"\\n\") }],\n };\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { apiGet, resolveProjectId } from \"../client.js\";\nimport { shouldShowFix } from \"../shouldShowFix.js\";\n\nfunction timeAgo(iso: string): string {\n const diff = Date.now() - new Date(iso).getTime();\n const mins = Math.floor(diff / 60_000);\n if (mins < 1) return \"just now\";\n if (mins < 60) return `${mins}m ago`;\n const hours = Math.floor(mins / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n return `${days}d ago`;\n}\n\nexport function registerGetBug(server: McpServer) {\n server.registerTool(\n \"get_bug\",\n {\n description:\n \"Get full details of a bug report including AI analysis, root cause, suggested fix, console errors, network errors, and environment info.\",\n inputSchema: {\n projectId: z.string().optional().describe(\"Project ID (uses FLINT_PROJECT_ID env if omitted)\"),\n reportId: z.string().describe(\"Bug report ID\"),\n },\n },\n async ({ projectId: pid, reportId }) => {\n const projectId = resolveProjectId(pid);\n if (!projectId)\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Error: projectId is required. Set FLINT_PROJECT_ID env or pass projectId.\",\n },\n ],\n };\n let r: any;\n try {\n r = await apiGet(`/api/v1/admin/projects/${projectId}/reports/${reportId}`);\n } catch {\n return { content: [{ type: \"text\" as const, text: `Bug report \"${reportId}\" not found.` }] };\n }\n\n const meta = r.meta as Record<string, unknown> | null;\n const aiReasoning = r.ai_reasoning as Record<string, unknown> | null;\n const consoleLogs = (meta?.consoleLogs ?? []) as { level: string; args: string }[];\n const networkErrors = (meta?.networkErrors ?? []) as { method: string; url: string; status: number }[];\n const envInfo = meta?.environment as Record<string, unknown> | null;\n const fix = r.fix ?? (r.ai_suggested_fix ? JSON.parse(r.ai_suggested_fix) : null);\n\n const sections: string[] = [];\n\n sections.push(`## Bug #${r.id.slice(-8)} — ${r.ai_title ?? r.title}`);\n sections.push(\n `**Severity:** ${r.severity} | **Status:** ${r.status} | **Assignee:** ${r.assignee ?? \"unassigned\"}`,\n );\n sections.push(\n `**Reporter:** ${r.reporter_name} | **Created:** ${timeAgo(r.created_at)} | **URL:** ${r.url ?? \"N/A\"}`,\n );\n if (r.app_version || r.release) {\n sections.push(`**Version:** ${r.app_version ?? \"N/A\"} | **Release:** ${r.release ?? \"N/A\"}`);\n }\n\n if (r.ai_description) sections.push(`\\n### AI Summary\\n${r.ai_description}`);\n\n if (r.ai_root_cause) {\n const conf = (aiReasoning?.rootCauseConfidence as number) ?? null;\n const confStr = conf !== null ? ` (${conf}% confidence)` : \"\";\n sections.push(`\\n### Root Cause${confStr}\\n${r.ai_root_cause}`);\n }\n\n // Withhold low-signal fixes so they don't mislead the consuming agent.\n if (fix && shouldShowFix(fix)) {\n const filePath = fix.filePath ?? fix.file_path ?? \"unknown\";\n sections.push(\n `\\n### Suggested Fix (${fix.confidence ?? \"unknown\"} confidence)\\n**File:** ${filePath}\\n\\n${fix.explanation ?? \"\"}\\n\\n\\`\\`\\`diff\\n${fix.diff ?? \"\"}\\n\\`\\`\\``,\n );\n }\n\n const errors = consoleLogs.filter((e) => e.level === \"error\").slice(-5);\n if (errors.length > 0) {\n sections.push(`\\n### Console Errors (last ${errors.length})\\n${errors.map((e) => `- ${e.args}`).join(\"\\n\")}`);\n }\n\n if (networkErrors.length > 0) {\n sections.push(\n `\\n### Failed Network Requests\\n${networkErrors.map((e) => `- ${e.method} ${e.url} → ${e.status}`).join(\"\\n\")}`,\n );\n }\n\n if (envInfo) {\n sections.push(\n `\\n### Environment\\n${envInfo.browser} | ${envInfo.os} | ${envInfo.viewport} | ${envInfo.timezone}`,\n );\n }\n\n const steps = r.steps_to_reproduce as { action: string; result: string }[] | null;\n if (steps && steps.length > 0) {\n sections.push(\n `\\n### Steps to Reproduce\\n${steps.map((s, i) => `${i + 1}. ${s.action}${s.result ? ` → ${s.result}` : \"\"}`).join(\"\\n\")}`,\n );\n }\n\n if (r.ai_repro_steps) sections.push(`\\n### AI-Generated Repro Steps\\n${r.ai_repro_steps}`);\n\n // Fix patterns (D9)\n if (r.fixPatterns?.length > 0) {\n sections.push(`\\n### How Similar Bugs Were Fixed`);\n for (const fp of r.fixPatterns) {\n sections.push(\n `- **PR #${fp.pr_number}**${fp.author_name ? ` by ${fp.author_name}` : \"\"} — ${fp.bug_title.slice(0, 50)}\\n ${fp.diff_summary.slice(0, 120)}`,\n );\n }\n }\n\n return { content: [{ type: \"text\" as const, text: sections.join(\"\\n\") }] };\n },\n );\n}\n","// Suppression gate for low-signal AI fixes (M0). Keep in sync with\n// `shouldShowFix` in @flint/types. A suggested fix is only surfaced when the\n// model is reasonably confident — \"low\" and \"speculative\" fixes are withheld so\n// they don't mislead a downstream agent that consumes this MCP.\nexport function shouldShowFix(fix: { confidence?: string | null } | null | undefined): boolean {\n return fix != null && (fix.confidence === \"high\" || fix.confidence === \"medium\");\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { apiGet, resolveProjectId } from \"../client.js\";\n\nfunction timeAgo(iso: string): string {\n const diff = Date.now() - new Date(iso).getTime();\n const mins = Math.floor(diff / 60_000);\n if (mins < 1) return \"just now\";\n if (mins < 60) return `${mins}m ago`;\n const hours = Math.floor(mins / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n return `${days}d ago`;\n}\n\nexport function registerListBugs(server: McpServer) {\n server.registerTool(\n \"list_bugs\",\n {\n description:\n \"List bug reports for a project with optional filters. Returns a summary table with ID, title, severity, status, assignee, and creation time.\",\n inputSchema: {\n projectId: z.string().optional().describe(\"Project ID (uses FLINT_PROJECT_ID env if omitted)\"),\n severity: z.string().optional().describe(\"Filter by severity: P1, P2, P3, P4 (comma-separated)\"),\n status: z\n .string()\n .optional()\n .describe(\"Filter by status: OPEN, IN_PROGRESS, TESTING, RESOLVED (comma-separated). Defaults to OPEN\"),\n assignee: z.string().optional().describe(\"Filter by assignee name\"),\n area: z.string().optional().describe(\"Filter by area: FRONTEND, BACKEND, DESIGN\"),\n q: z.string().optional().describe(\"Search in title, reporter name, URL\"),\n limit: z.number().optional().describe(\"Max results (default 10, max 50)\"),\n },\n },\n async ({ projectId: pid, severity, status, assignee, area, q, limit }) => {\n const projectId = resolveProjectId(pid);\n if (!projectId)\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Error: projectId is required. Set FLINT_PROJECT_ID env or pass projectId.\",\n },\n ],\n };\n const params = new URLSearchParams({ page: \"1\", limit: String(Math.min(limit ?? 10, 50)) });\n if (severity) params.set(\"severity\", severity);\n params.set(\"status\", status ?? \"OPEN\");\n if (assignee) params.set(\"assignee\", assignee);\n if (area) params.set(\"area\", area);\n if (q) params.set(\"q\", q);\n\n const data = await apiGet<{ reports: any[]; total: number }>(\n `/api/v1/admin/projects/${projectId}/reports?${params}`,\n );\n\n if (data.reports.length === 0) {\n return { content: [{ type: \"text\" as const, text: \"No bugs found matching the filters.\" }] };\n }\n\n const lines = data.reports.map((r: any) => {\n const title = (r.ai_title ?? r.title).slice(0, 60);\n const assigneeStr = r.assignee ?? \"unassigned\";\n const quality = r.quality_score ? ` Q:${r.quality_score}%` : \"\";\n return `- **${r.severity}** \\`${r.id}\\` ${title} — ${r.status} — ${assigneeStr} — ${timeAgo(r.created_at)}${quality}`;\n });\n\n const text = `## Bug Reports (${data.total} total, showing ${data.reports.length})\\n\\n${lines.join(\"\\n\")}\\n\\nUse \\`get_bug\\` with a report ID for full details.`;\n return { content: [{ type: \"text\" as const, text }] };\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { apiPatch, resolveProjectId } from \"../client.js\";\n\nexport function registerResolveBug(server: McpServer) {\n server.registerTool(\n \"resolve_bug\",\n {\n description: \"Mark a bug report as resolved.\",\n inputSchema: {\n projectId: z.string().optional().describe(\"Project ID (uses FLINT_PROJECT_ID env if omitted)\"),\n reportId: z.string().describe(\"The bug report ID\"),\n },\n },\n async ({ projectId: pid, reportId }) => {\n const projectId = resolveProjectId(pid);\n if (!projectId)\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Error: projectId is required. Set FLINT_PROJECT_ID env or pass projectId.\",\n },\n ],\n };\n try {\n await apiPatch(`/api/v1/admin/projects/${projectId}/reports/${reportId}/resolve`);\n } catch (err: any) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Failed to resolve bug #${reportId}: ${err.message ?? \"Unknown error\"}`,\n },\n ],\n };\n }\n\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Bug #${reportId} marked as RESOLVED.`,\n },\n ],\n };\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { resolveProjectId } from \"../client.js\";\n\nexport function registerSearchCode(server: McpServer) {\n server.registerTool(\n \"search_code\",\n {\n description:\n \"Search the project's indexed codebase by semantic query. Returns relevant code chunks with file paths and line numbers.\",\n inputSchema: {\n projectId: z.string().optional().describe(\"Project ID (uses FLINT_PROJECT_ID env if omitted)\"),\n query: z.string().describe(\"Semantic search query\"),\n limit: z.number().optional().describe(\"Max results to return (default 5)\"),\n },\n },\n async ({ projectId: pid, query, limit }) => {\n const projectId = resolveProjectId(pid) ?? \"unknown\";\n const text = [\n \"## Code Search — Not Available via MCP\",\n \"\",\n \"Semantic code search requires direct access to the vector embedding pipeline (Voyage AI + pgvector), which is not exposed through the HTTP API.\",\n \"\",\n \"**Alternatives:**\",\n `- Use the **Flint Admin Dashboard** → Project → Code Index to search the indexed codebase for project \\`${projectId}\\`.`,\n `- Use \\`chat_about_bug\\` with a specific bug report ID — the AI chat endpoint includes relevant code context automatically.`,\n \"\",\n `Your query was: \"${query}\" (limit: ${limit ?? 5})`,\n ].join(\"\\n\");\n\n return {\n content: [{ type: \"text\" as const, text }],\n };\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { apiGet, resolveProjectId } from \"../client.js\";\nimport { shouldShowFix } from \"../shouldShowFix.js\";\n\nexport function registerSuggestFix(server: McpServer) {\n server.registerTool(\n \"suggest_fix\",\n {\n description:\n \"Generate an AI-suggested code fix for a bug report. Uses the project's indexed code and AI analysis to produce a diff.\",\n inputSchema: {\n projectId: z.string().optional().describe(\"Project ID (uses FLINT_PROJECT_ID env if omitted)\"),\n reportId: z.string().describe(\"The bug report ID\"),\n },\n },\n async ({ projectId: pid, reportId }) => {\n const projectId = resolveProjectId(pid);\n if (!projectId)\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Error: projectId is required. Set FLINT_PROJECT_ID env or pass projectId.\",\n },\n ],\n };\n let report: any;\n try {\n report = await apiGet(`/api/v1/admin/projects/${projectId}/reports/${reportId}`);\n } catch (err: any) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Bug report ${reportId} not found in project ${projectId}. ${err.message ?? \"\"}`,\n },\n ],\n };\n }\n\n const rawFix = report.ai_suggested_fix;\n\n if (!rawFix) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: [\n `## No Fix Available for Bug #${reportId}`,\n \"\",\n \"An AI-suggested fix has not been generated yet for this bug report.\",\n \"The fix is generated automatically during background processing when the bug is first created.\",\n \"\",\n \"**Possible reasons:**\",\n \"- The bug was recently created and background processing hasn't completed yet.\",\n \"- The project's codebase may not be indexed (Code Index is required for fix generation).\",\n \"- The AI analysis did not produce a fix for this particular bug.\",\n \"\",\n \"Check the Flint Admin Dashboard for the latest status.\",\n ].join(\"\\n\"),\n },\n ],\n };\n }\n\n let fix: any;\n try {\n fix = typeof rawFix === \"string\" ? JSON.parse(rawFix) : rawFix;\n } catch {\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Failed to parse the suggested fix data.\",\n },\n ],\n };\n }\n\n if (!shouldShowFix(fix)) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: [\n `## No High-Confidence Fix for Bug #${reportId}`,\n \"\",\n `The AI fix for this bug is **${fix.confidence ?? \"low\"} confidence** and has been withheld to avoid sending a misleading suggestion to an agent.`,\n \"Investigate manually, or open the bug in the Flint dashboard for full context.\",\n ].join(\"\\n\"),\n },\n ],\n };\n }\n\n const filePath = fix.file_path ?? fix.filePath ?? \"unknown\";\n const explanation = fix.explanation ?? \"No explanation provided.\";\n const diff = fix.diff ?? fix.code ?? \"\";\n const confidence = fix.confidence ?? \"unknown\";\n\n const text = [\n `## Suggested Fix for Bug #${reportId}`,\n \"\",\n `**File:** \\`${filePath}\\``,\n `**Confidence:** ${confidence}`,\n \"\",\n `### Explanation`,\n explanation,\n \"\",\n \"### Diff\",\n \"```diff\",\n diff,\n \"```\",\n ].join(\"\\n\");\n\n return {\n content: [{ type: \"text\" as const, text }],\n };\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { apiPatch, resolveProjectId } from \"../client.js\";\n\nexport function registerTriageBug(server: McpServer) {\n server.registerTool(\n \"triage_bug\",\n {\n description: \"Update triage fields on a bug report: assignee, severity, area, and notes.\",\n inputSchema: {\n projectId: z.string().optional().describe(\"Project ID (uses FLINT_PROJECT_ID env if omitted)\"),\n reportId: z.string().describe(\"The bug report ID\"),\n assignee: z.string().optional().describe(\"Assignee name or identifier\"),\n severity: z.string().optional().describe(\"Severity level: P1, P2, P3, or P4\"),\n area: z.string().optional().describe(\"Affected area: FRONTEND, BACKEND, or DESIGN\"),\n notes: z.string().optional().describe(\"Triage notes\"),\n },\n },\n async ({ projectId: pid, reportId, assignee, severity, area, notes }) => {\n const projectId = resolveProjectId(pid);\n if (!projectId)\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Error: projectId is required. Set FLINT_PROJECT_ID env or pass projectId.\",\n },\n ],\n };\n const data: Record<string, unknown> = {};\n if (assignee !== undefined) data.assignee = assignee;\n if (severity !== undefined) data.severity = severity;\n if (area !== undefined) data.area = area;\n if (notes !== undefined) data.notes = notes;\n\n if (Object.keys(data).length === 0) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"No triage fields provided. Specify at least one of: assignee, severity, area, notes.\",\n },\n ],\n };\n }\n\n try {\n await apiPatch(`/api/v1/admin/projects/${projectId}/reports/${reportId}/triage`, data);\n } catch (err: any) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Failed to triage bug #${reportId}: ${err.message ?? \"Unknown error\"}`,\n },\n ],\n };\n }\n\n const parts: string[] = [];\n if (assignee !== undefined) parts.push(`Assignee: ${assignee}`);\n if (severity !== undefined) parts.push(`Severity: ${severity}`);\n if (area !== undefined) parts.push(`Area: ${area}`);\n if (notes !== undefined) parts.push(`Notes: ${notes}`);\n\n const text = `Bug #${reportId} triaged: ${parts.join(\", \")}`;\n\n return {\n content: [{ type: \"text\" as const, text }],\n };\n },\n );\n}\n"],"mappings":"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","names":["server","z","server","z","z","server","z","z","server","z","z","timeAgo","server","z","z","server","z","z","server","z","z","server","z","z","server","z"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/tools/chatAboutBug.ts","../src/client.ts","../src/tools/createFixPR.ts","../src/tools/getAnalytics.ts","../src/tools/getBug.ts","../src/shouldShowFix.ts","../src/tools/listBugs.ts","../src/tools/resolveBug.ts","../src/tools/searchCode.ts","../src/tools/suggestFix.ts","../src/tools/triageBug.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport {\n registerChatAboutBug,\n registerCreateFixPR,\n registerGetAnalytics,\n registerGetBug,\n registerListBugs,\n registerResolveBug,\n registerSearchCode,\n registerSuggestFix,\n registerTriageBug,\n} from \"./tools/index.js\";\n\nconst server = new McpServer({\n name: \"flint\",\n version: \"1.0.0\",\n description:\n \"Flint bug tracking & error monitoring — list bugs, search code, suggest fixes, triage issues directly from your editor.\",\n});\n\nregisterListBugs(server);\nregisterGetBug(server);\nregisterSearchCode(server);\nregisterSuggestFix(server);\nregisterTriageBug(server);\nregisterResolveBug(server);\nregisterCreateFixPR(server);\nregisterGetAnalytics(server);\nregisterChatAboutBug(server);\n\nasync function main() {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n console.error(\"Flint MCP Server running on stdio\");\n}\n\nmain().catch((error) => {\n console.error(\"Fatal error in MCP server:\", error);\n process.exit(1);\n});\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { apiPost, resolveProjectId } from \"../client.js\";\n\nexport function registerChatAboutBug(server: McpServer) {\n server.registerTool(\n \"chat_about_bug\",\n {\n description:\n \"Ask a question about a specific bug report. Uses AI with full context (code, similar bugs, fix history) to answer.\",\n inputSchema: {\n projectId: z.string().optional().describe(\"Project ID (uses FLINT_PROJECT_ID env if omitted)\"),\n reportId: z.string().describe(\"The bug report ID\"),\n message: z.string().describe(\"The message/question to ask about this bug\"),\n },\n },\n async ({ projectId: pid, reportId, message }) => {\n const projectId = resolveProjectId(pid);\n if (!projectId)\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Error: projectId is required. Set FLINT_PROJECT_ID env or pass projectId.\",\n },\n ],\n };\n let result: any;\n try {\n result = await apiPost(`/api/v1/admin/projects/${projectId}/reports/${reportId}/chat`, { message });\n } catch (err: any) {\n const errorMsg = err.message ?? \"Unknown error\";\n return {\n content: [\n {\n type: \"text\" as const,\n text: [\n `Failed to chat about bug #${reportId}: ${errorMsg}`,\n \"\",\n \"The AI chat feature may not be enabled for this project, or the bug report may not exist.\",\n \"Check the Flint Admin Dashboard for more details.\",\n ].join(\"\\n\"),\n },\n ],\n };\n }\n\n // The chat endpoint may return the response in different formats:\n // - { response: \"...\" } or { text: \"...\" } or { message: \"...\" }\n // - or the result itself could be a string (if the response was plain text parsed as JSON string)\n let responseText: string;\n if (typeof result === \"string\") {\n responseText = result;\n } else if (result?.response) {\n responseText = result.response;\n } else if (result?.text) {\n responseText = result.text;\n } else if (result?.message) {\n responseText = result.message;\n } else if (result?.content) {\n // Handle case where the API returns an array of content blocks (Anthropic-style)\n if (Array.isArray(result.content)) {\n responseText = result.content\n .filter((block: any) => block.type === \"text\")\n .map((block: any) => block.text)\n .join(\"\\n\");\n } else {\n responseText = String(result.content);\n }\n } else {\n responseText = JSON.stringify(result, null, 2);\n }\n\n if (!responseText || responseText === \"null\" || responseText === \"undefined\") {\n responseText = \"No response was generated. The AI may need more context about this bug.\";\n }\n\n return {\n content: [{ type: \"text\" as const, text: responseText }],\n };\n },\n );\n}\n","/**\n * HTTP client for the Flint Admin API.\n * Used by MCP tools instead of direct Prisma access.\n */\n\nconst serverUrl = (process.env.FLINT_SERVER_URL ?? \"http://localhost:3333\").replace(/\\/$/, \"\");\n// Per-user personal access token (recommended). Falls back to the shared admin key.\nconst apiToken = process.env.FLINT_API_TOKEN ?? \"\";\n// FLINT_API_KEY kept as fallback for setups created before the rename\nconst adminKey = process.env.FLINT_ADMIN_KEY ?? process.env.FLINT_API_KEY ?? \"\";\nexport const defaultProjectId = process.env.FLINT_PROJECT_ID ?? \"\";\n\nexport function resolveProjectId(pid?: string): string | null {\n return pid || defaultProjectId || null;\n}\n\nif (!serverUrl) {\n console.error(\"[Flint MCP] FLINT_SERVER_URL is required\");\n process.exit(1);\n}\nif (!apiToken && !adminKey) {\n console.error(\"[Flint MCP] Set FLINT_API_TOKEN (per-user, recommended) or FLINT_ADMIN_KEY\");\n process.exit(1);\n}\n\nfunction headers(): Record<string, string> {\n // Prefer the per-user token; fall back to the shared admin key for legacy setups.\n return {\n ...(apiToken ? { Authorization: `Bearer ${apiToken}` } : { \"X-Admin-Key\": adminKey }),\n \"Content-Type\": \"application/json\",\n };\n}\n\nexport async function apiGet<T = unknown>(path: string): Promise<T> {\n const res = await fetch(`${serverUrl}${path}`, { headers: headers() });\n if (!res.ok) {\n const body = await res.text().catch(() => \"\");\n throw new Error(`API ${res.status}: ${body.slice(0, 200)}`);\n }\n return res.json() as Promise<T>;\n}\n\nexport async function apiPatch<T = unknown>(path: string, body?: unknown): Promise<T> {\n const res = await fetch(`${serverUrl}${path}`, {\n method: \"PATCH\",\n headers: headers(),\n body: body ? JSON.stringify(body) : undefined,\n });\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n throw new Error(`API ${res.status}: ${text.slice(0, 200)}`);\n }\n return res.json() as Promise<T>;\n}\n\nexport async function apiPost<T = unknown>(path: string, body?: unknown): Promise<T> {\n const res = await fetch(`${serverUrl}${path}`, {\n method: \"POST\",\n headers: headers(),\n body: body ? JSON.stringify(body) : undefined,\n });\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n throw new Error(`API ${res.status}: ${text.slice(0, 200)}`);\n }\n return res.json() as Promise<T>;\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { apiPost, resolveProjectId } from \"../client.js\";\n\nexport function registerCreateFixPR(server: McpServer) {\n server.registerTool(\n \"create_fix_pr\",\n {\n description:\n \"Create a GitHub Pull Request with the AI-suggested fix for a bug report. Requires the bug to have a suggested fix.\",\n inputSchema: {\n projectId: z.string().optional().describe(\"Project ID (uses FLINT_PROJECT_ID env if omitted)\"),\n reportId: z.string().describe(\"The bug report ID\"),\n branch: z.string().optional().describe(\"Branch name (default: fix/<reportId>)\"),\n commitMessage: z.string().optional().describe(\"Custom commit message\"),\n },\n },\n async ({ projectId: pid, reportId, branch, commitMessage }) => {\n const projectId = resolveProjectId(pid);\n if (!projectId)\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Error: projectId is required. Set FLINT_PROJECT_ID env or pass projectId.\",\n },\n ],\n };\n const body: Record<string, string> = {};\n if (branch) body.branch = branch;\n if (commitMessage) body.commitMessage = commitMessage;\n\n let result: any;\n try {\n result = await apiPost(\n `/api/v1/admin/projects/${projectId}/reports/${reportId}/create-fix-pr`,\n Object.keys(body).length > 0 ? body : undefined,\n );\n } catch (err: any) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Failed to create fix PR for bug #${reportId}: ${err.message ?? \"Unknown error\"}`,\n },\n ],\n };\n }\n\n const prUrl = result?.pr_url ?? result?.prUrl ?? result?.url ?? null;\n\n const text = prUrl\n ? [\n `## Pull Request Created for Bug #${reportId}`,\n \"\",\n `**PR URL:** ${prUrl}`,\n \"\",\n \"The PR has been created with the AI-suggested fix. Review and merge when ready.\",\n ].join(\"\\n\")\n : [\n `## Fix PR Request Submitted for Bug #${reportId}`,\n \"\",\n \"The request to create a fix PR was accepted.\",\n result?.message\n ? `Server response: ${result.message}`\n : \"Check the Flint Admin Dashboard or your GitHub repository for the PR.\",\n ].join(\"\\n\");\n\n return {\n content: [{ type: \"text\" as const, text }],\n };\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { apiGet, resolveProjectId } from \"../client.js\";\n\nexport function registerGetAnalytics(server: McpServer) {\n server.registerTool(\n \"get_analytics\",\n {\n description:\n \"Get project analytics: total reports, open/critical counts, resolution time, triage rate, top errors, and trends.\",\n inputSchema: {\n projectId: z.string().optional().describe(\"Project ID (uses FLINT_PROJECT_ID env if omitted)\"),\n period: z.string().optional().describe(\"Time period: 7d, 30d, or 90d (default 30d)\"),\n },\n },\n async ({ projectId: pid, period }) => {\n const projectId = resolveProjectId(pid);\n if (!projectId)\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Error: projectId is required. Set FLINT_PROJECT_ID env or pass projectId.\",\n },\n ],\n };\n const periodStr = period ?? \"30d\";\n\n let data: any;\n try {\n data = await apiGet(`/api/v1/admin/projects/${projectId}/analytics?period=${periodStr}`);\n } catch (err: any) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Failed to fetch analytics for project ${projectId}: ${err.message ?? \"Unknown error\"}`,\n },\n ],\n };\n }\n\n // The analytics endpoint may return data in different shapes.\n // We handle the most common fields gracefully.\n const total = data.total ?? data.totalReports ?? \"—\";\n const open = data.open ?? data.openCount ?? \"—\";\n const inProgress = data.inProgress ?? data.inProgressCount ?? \"—\";\n const resolved = data.resolved ?? data.resolvedCount ?? \"—\";\n const critical = data.critical ?? data.criticalCount ?? \"—\";\n const avgResolution = data.avgResolutionHours ?? data.avgResolution ?? \"—\";\n const triageRate = data.triageRate ?? data.triagedPercent ?? \"—\";\n\n const sections: string[] = [\n `## Analytics (${periodStr})`,\n \"\",\n `**Total:** ${total} reports | **Open:** ${open} | **In Progress:** ${inProgress} | **Critical (P1/P2):** ${critical} | **Resolved:** ${resolved}`,\n `**Avg Resolution:** ${avgResolution}${typeof avgResolution === \"number\" ? \"h\" : \"\"} | **Triage Rate:** ${triageRate}${typeof triageRate === \"number\" ? \"%\" : \"\"}`,\n ];\n\n // Top errors\n const topErrors: any[] = data.topErrors ?? data.errorGroups ?? data.topErrorGroups ?? [];\n if (topErrors.length > 0) {\n sections.push(\"\", \"### Top Errors\");\n topErrors.forEach((e: any, i: number) => {\n const title = e.title ?? e.message ?? \"Unknown error\";\n const events = e.error_count ?? e.errorCount ?? e.count ?? 0;\n const users = e.user_count ?? e.userCount ?? 0;\n sections.push(`${i + 1}. ${title} (${events} events${users ? `, ${users} users` : \"\"})`);\n });\n }\n\n // Trends\n const trends: any[] = data.trends ?? data.dailyCounts ?? [];\n if (trends.length > 0) {\n sections.push(\"\", \"### Trend (daily bug count)\");\n const recent = trends.slice(-7);\n const trendLine = recent\n .map((t: any) => {\n const date = t.date ?? t.day ?? t.label ?? \"?\";\n const count = t.count ?? t.total ?? 0;\n return `${date}: ${count}`;\n })\n .join(\" | \");\n sections.push(trendLine);\n }\n\n return {\n content: [{ type: \"text\" as const, text: sections.join(\"\\n\") }],\n };\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { apiGet, resolveProjectId } from \"../client.js\";\nimport { shouldShowFix } from \"../shouldShowFix.js\";\n\nfunction timeAgo(iso: string): string {\n const diff = Date.now() - new Date(iso).getTime();\n const mins = Math.floor(diff / 60_000);\n if (mins < 1) return \"just now\";\n if (mins < 60) return `${mins}m ago`;\n const hours = Math.floor(mins / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n return `${days}d ago`;\n}\n\nexport function registerGetBug(server: McpServer) {\n server.registerTool(\n \"get_bug\",\n {\n description:\n \"Get full details of a bug report including AI analysis, root cause, suggested fix, console errors, network errors, and environment info.\",\n inputSchema: {\n projectId: z.string().optional().describe(\"Project ID (uses FLINT_PROJECT_ID env if omitted)\"),\n reportId: z.string().describe(\"Bug report ID\"),\n },\n },\n async ({ projectId: pid, reportId }) => {\n const projectId = resolveProjectId(pid);\n if (!projectId)\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Error: projectId is required. Set FLINT_PROJECT_ID env or pass projectId.\",\n },\n ],\n };\n let r: any;\n try {\n r = await apiGet(`/api/v1/admin/projects/${projectId}/reports/${reportId}`);\n } catch {\n return { content: [{ type: \"text\" as const, text: `Bug report \"${reportId}\" not found.` }] };\n }\n\n const meta = r.meta as Record<string, unknown> | null;\n const aiReasoning = r.ai_reasoning as Record<string, unknown> | null;\n const consoleLogs = (meta?.consoleLogs ?? []) as { level: string; args: string }[];\n const networkErrors = (meta?.networkErrors ?? []) as { method: string; url: string; status: number }[];\n const envInfo = meta?.environment as Record<string, unknown> | null;\n const fix = r.fix ?? (r.ai_suggested_fix ? JSON.parse(r.ai_suggested_fix) : null);\n\n const sections: string[] = [];\n\n sections.push(`## Bug #${r.id.slice(-8)} — ${r.ai_title ?? r.title}`);\n sections.push(\n `**Severity:** ${r.severity} | **Status:** ${r.status} | **Assignee:** ${r.assignee ?? \"unassigned\"}`,\n );\n sections.push(\n `**Reporter:** ${r.reporter_name} | **Created:** ${timeAgo(r.created_at)} | **URL:** ${r.url ?? \"N/A\"}`,\n );\n if (r.app_version || r.release) {\n sections.push(`**Version:** ${r.app_version ?? \"N/A\"} | **Release:** ${r.release ?? \"N/A\"}`);\n }\n\n if (r.ai_description) sections.push(`\\n### AI Summary\\n${r.ai_description}`);\n\n if (r.ai_root_cause) {\n const conf = (aiReasoning?.rootCauseConfidence as number) ?? null;\n const confStr = conf !== null ? ` (${conf}% confidence)` : \"\";\n sections.push(`\\n### Root Cause${confStr}\\n${r.ai_root_cause}`);\n }\n\n // Withhold low-signal fixes so they don't mislead the consuming agent.\n if (fix && shouldShowFix(fix)) {\n const filePath = fix.filePath ?? fix.file_path ?? \"unknown\";\n sections.push(\n `\\n### Suggested Fix (${fix.confidence ?? \"unknown\"} confidence)\\n**File:** ${filePath}\\n\\n${fix.explanation ?? \"\"}\\n\\n\\`\\`\\`diff\\n${fix.diff ?? \"\"}\\n\\`\\`\\``,\n );\n }\n\n const errors = consoleLogs.filter((e) => e.level === \"error\").slice(-5);\n if (errors.length > 0) {\n sections.push(`\\n### Console Errors (last ${errors.length})\\n${errors.map((e) => `- ${e.args}`).join(\"\\n\")}`);\n }\n\n if (networkErrors.length > 0) {\n sections.push(\n `\\n### Failed Network Requests\\n${networkErrors.map((e) => `- ${e.method} ${e.url} → ${e.status}`).join(\"\\n\")}`,\n );\n }\n\n if (envInfo) {\n sections.push(\n `\\n### Environment\\n${envInfo.browser} | ${envInfo.os} | ${envInfo.viewport} | ${envInfo.timezone}`,\n );\n }\n\n const steps = r.steps_to_reproduce as { action: string; result: string }[] | null;\n if (steps && steps.length > 0) {\n sections.push(\n `\\n### Steps to Reproduce\\n${steps.map((s, i) => `${i + 1}. ${s.action}${s.result ? ` → ${s.result}` : \"\"}`).join(\"\\n\")}`,\n );\n }\n\n if (r.ai_repro_steps) sections.push(`\\n### AI-Generated Repro Steps\\n${r.ai_repro_steps}`);\n\n // Fix patterns (D9)\n if (r.fixPatterns?.length > 0) {\n sections.push(`\\n### How Similar Bugs Were Fixed`);\n for (const fp of r.fixPatterns) {\n sections.push(\n `- **PR #${fp.pr_number}**${fp.author_name ? ` by ${fp.author_name}` : \"\"} — ${fp.bug_title.slice(0, 50)}\\n ${fp.diff_summary.slice(0, 120)}`,\n );\n }\n }\n\n return { content: [{ type: \"text\" as const, text: sections.join(\"\\n\") }] };\n },\n );\n}\n","// Suppression gate for low-signal AI fixes (M0). Keep in sync with\n// `shouldShowFix` in @flint/types. A suggested fix is only surfaced when the\n// model is reasonably confident — \"low\" and \"speculative\" fixes are withheld so\n// they don't mislead a downstream agent that consumes this MCP.\nexport function shouldShowFix(fix: { confidence?: string | null } | null | undefined): boolean {\n return fix != null && (fix.confidence === \"high\" || fix.confidence === \"medium\");\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { apiGet, resolveProjectId } from \"../client.js\";\n\nfunction timeAgo(iso: string): string {\n const diff = Date.now() - new Date(iso).getTime();\n const mins = Math.floor(diff / 60_000);\n if (mins < 1) return \"just now\";\n if (mins < 60) return `${mins}m ago`;\n const hours = Math.floor(mins / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n return `${days}d ago`;\n}\n\nexport function registerListBugs(server: McpServer) {\n server.registerTool(\n \"list_bugs\",\n {\n description:\n \"List bug reports for a project with optional filters. Returns a summary table with ID, title, severity, status, assignee, and creation time.\",\n inputSchema: {\n projectId: z.string().optional().describe(\"Project ID (uses FLINT_PROJECT_ID env if omitted)\"),\n severity: z.string().optional().describe(\"Filter by severity: P1, P2, P3, P4 (comma-separated)\"),\n status: z\n .string()\n .optional()\n .describe(\"Filter by status: OPEN, IN_PROGRESS, TESTING, RESOLVED (comma-separated). Defaults to OPEN\"),\n assignee: z.string().optional().describe(\"Filter by assignee name\"),\n area: z.string().optional().describe(\"Filter by area: FRONTEND, BACKEND, DESIGN\"),\n q: z.string().optional().describe(\"Search in title, reporter name, URL\"),\n limit: z.number().optional().describe(\"Max results (default 10, max 50)\"),\n },\n },\n async ({ projectId: pid, severity, status, assignee, area, q, limit }) => {\n const projectId = resolveProjectId(pid);\n if (!projectId)\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Error: projectId is required. Set FLINT_PROJECT_ID env or pass projectId.\",\n },\n ],\n };\n const params = new URLSearchParams({ page: \"1\", limit: String(Math.min(limit ?? 10, 50)) });\n if (severity) params.set(\"severity\", severity);\n params.set(\"status\", status ?? \"OPEN\");\n if (assignee) params.set(\"assignee\", assignee);\n if (area) params.set(\"area\", area);\n if (q) params.set(\"q\", q);\n\n const data = await apiGet<{ reports: any[]; total: number }>(\n `/api/v1/admin/projects/${projectId}/reports?${params}`,\n );\n\n if (data.reports.length === 0) {\n return { content: [{ type: \"text\" as const, text: \"No bugs found matching the filters.\" }] };\n }\n\n const lines = data.reports.map((r: any) => {\n const title = (r.ai_title ?? r.title).slice(0, 60);\n const assigneeStr = r.assignee ?? \"unassigned\";\n const quality = r.quality_score ? ` Q:${r.quality_score}%` : \"\";\n return `- **${r.severity}** \\`${r.id}\\` ${title} — ${r.status} — ${assigneeStr} — ${timeAgo(r.created_at)}${quality}`;\n });\n\n const text = `## Bug Reports (${data.total} total, showing ${data.reports.length})\\n\\n${lines.join(\"\\n\")}\\n\\nUse \\`get_bug\\` with a report ID for full details.`;\n return { content: [{ type: \"text\" as const, text }] };\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { apiPatch, resolveProjectId } from \"../client.js\";\n\nexport function registerResolveBug(server: McpServer) {\n server.registerTool(\n \"resolve_bug\",\n {\n description: \"Mark a bug report as resolved.\",\n inputSchema: {\n projectId: z.string().optional().describe(\"Project ID (uses FLINT_PROJECT_ID env if omitted)\"),\n reportId: z.string().describe(\"The bug report ID\"),\n },\n },\n async ({ projectId: pid, reportId }) => {\n const projectId = resolveProjectId(pid);\n if (!projectId)\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Error: projectId is required. Set FLINT_PROJECT_ID env or pass projectId.\",\n },\n ],\n };\n try {\n await apiPatch(`/api/v1/admin/projects/${projectId}/reports/${reportId}/resolve`);\n } catch (err: any) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Failed to resolve bug #${reportId}: ${err.message ?? \"Unknown error\"}`,\n },\n ],\n };\n }\n\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Bug #${reportId} marked as RESOLVED.`,\n },\n ],\n };\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { resolveProjectId } from \"../client.js\";\n\nexport function registerSearchCode(server: McpServer) {\n server.registerTool(\n \"search_code\",\n {\n description:\n \"Search the project's indexed codebase by semantic query. Returns relevant code chunks with file paths and line numbers.\",\n inputSchema: {\n projectId: z.string().optional().describe(\"Project ID (uses FLINT_PROJECT_ID env if omitted)\"),\n query: z.string().describe(\"Semantic search query\"),\n limit: z.number().optional().describe(\"Max results to return (default 5)\"),\n },\n },\n async ({ projectId: pid, query, limit }) => {\n const projectId = resolveProjectId(pid) ?? \"unknown\";\n const text = [\n \"## Code Search — Not Available via MCP\",\n \"\",\n \"Semantic code search requires direct access to the vector embedding pipeline (Voyage AI + pgvector), which is not exposed through the HTTP API.\",\n \"\",\n \"**Alternatives:**\",\n `- Use the **Flint Admin Dashboard** → Project → Code Index to search the indexed codebase for project \\`${projectId}\\`.`,\n `- Use \\`chat_about_bug\\` with a specific bug report ID — the AI chat endpoint includes relevant code context automatically.`,\n \"\",\n `Your query was: \"${query}\" (limit: ${limit ?? 5})`,\n ].join(\"\\n\");\n\n return {\n content: [{ type: \"text\" as const, text }],\n };\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { apiGet, resolveProjectId } from \"../client.js\";\nimport { shouldShowFix } from \"../shouldShowFix.js\";\n\nexport function registerSuggestFix(server: McpServer) {\n server.registerTool(\n \"suggest_fix\",\n {\n description:\n \"Generate an AI-suggested code fix for a bug report. Uses the project's indexed code and AI analysis to produce a diff.\",\n inputSchema: {\n projectId: z.string().optional().describe(\"Project ID (uses FLINT_PROJECT_ID env if omitted)\"),\n reportId: z.string().describe(\"The bug report ID\"),\n },\n },\n async ({ projectId: pid, reportId }) => {\n const projectId = resolveProjectId(pid);\n if (!projectId)\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Error: projectId is required. Set FLINT_PROJECT_ID env or pass projectId.\",\n },\n ],\n };\n let report: any;\n try {\n report = await apiGet(`/api/v1/admin/projects/${projectId}/reports/${reportId}`);\n } catch (err: any) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Bug report ${reportId} not found in project ${projectId}. ${err.message ?? \"\"}`,\n },\n ],\n };\n }\n\n const rawFix = report.ai_suggested_fix;\n\n if (!rawFix) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: [\n `## No Fix Available for Bug #${reportId}`,\n \"\",\n \"An AI-suggested fix has not been generated yet for this bug report.\",\n \"The fix is generated automatically during background processing when the bug is first created.\",\n \"\",\n \"**Possible reasons:**\",\n \"- The bug was recently created and background processing hasn't completed yet.\",\n \"- The project's codebase may not be indexed (Code Index is required for fix generation).\",\n \"- The AI analysis did not produce a fix for this particular bug.\",\n \"\",\n \"Check the Flint Admin Dashboard for the latest status.\",\n ].join(\"\\n\"),\n },\n ],\n };\n }\n\n let fix: any;\n try {\n fix = typeof rawFix === \"string\" ? JSON.parse(rawFix) : rawFix;\n } catch {\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Failed to parse the suggested fix data.\",\n },\n ],\n };\n }\n\n if (!shouldShowFix(fix)) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: [\n `## No High-Confidence Fix for Bug #${reportId}`,\n \"\",\n `The AI fix for this bug is **${fix.confidence ?? \"low\"} confidence** and has been withheld to avoid sending a misleading suggestion to an agent.`,\n \"Investigate manually, or open the bug in the Flint dashboard for full context.\",\n ].join(\"\\n\"),\n },\n ],\n };\n }\n\n const filePath = fix.file_path ?? fix.filePath ?? \"unknown\";\n const explanation = fix.explanation ?? \"No explanation provided.\";\n const diff = fix.diff ?? fix.code ?? \"\";\n const confidence = fix.confidence ?? \"unknown\";\n\n const text = [\n `## Suggested Fix for Bug #${reportId}`,\n \"\",\n `**File:** \\`${filePath}\\``,\n `**Confidence:** ${confidence}`,\n \"\",\n `### Explanation`,\n explanation,\n \"\",\n \"### Diff\",\n \"```diff\",\n diff,\n \"```\",\n ].join(\"\\n\");\n\n return {\n content: [{ type: \"text\" as const, text }],\n };\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { apiPatch, resolveProjectId } from \"../client.js\";\n\nexport function registerTriageBug(server: McpServer) {\n server.registerTool(\n \"triage_bug\",\n {\n description: \"Update triage fields on a bug report: assignee, severity, area, and notes.\",\n inputSchema: {\n projectId: z.string().optional().describe(\"Project ID (uses FLINT_PROJECT_ID env if omitted)\"),\n reportId: z.string().describe(\"The bug report ID\"),\n assignee: z.string().optional().describe(\"Assignee name or identifier\"),\n severity: z.string().optional().describe(\"Severity level: P1, P2, P3, or P4\"),\n area: z.string().optional().describe(\"Affected area: FRONTEND, BACKEND, or DESIGN\"),\n notes: z.string().optional().describe(\"Triage notes\"),\n },\n },\n async ({ projectId: pid, reportId, assignee, severity, area, notes }) => {\n const projectId = resolveProjectId(pid);\n if (!projectId)\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"Error: projectId is required. Set FLINT_PROJECT_ID env or pass projectId.\",\n },\n ],\n };\n const data: Record<string, unknown> = {};\n if (assignee !== undefined) data.assignee = assignee;\n if (severity !== undefined) data.severity = severity;\n if (area !== undefined) data.area = area;\n if (notes !== undefined) data.notes = notes;\n\n if (Object.keys(data).length === 0) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: \"No triage fields provided. Specify at least one of: assignee, severity, area, notes.\",\n },\n ],\n };\n }\n\n try {\n await apiPatch(`/api/v1/admin/projects/${projectId}/reports/${reportId}/triage`, data);\n } catch (err: any) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Failed to triage bug #${reportId}: ${err.message ?? \"Unknown error\"}`,\n },\n ],\n };\n }\n\n const parts: string[] = [];\n if (assignee !== undefined) parts.push(`Assignee: ${assignee}`);\n if (severity !== undefined) parts.push(`Severity: ${severity}`);\n if (area !== undefined) parts.push(`Area: ${area}`);\n if (notes !== undefined) parts.push(`Notes: ${notes}`);\n\n const text = `Bug #${reportId} triaged: ${parts.join(\", \")}`;\n\n return {\n content: [{ type: \"text\" as const, text }],\n };\n },\n );\n}\n"],"mappings":";;;AACA,SAAS,iBAAiB;AAC1B,SAAS,4BAA4B;;;ACDrC,SAAS,SAAS;;;ACIlB,IAAM,aAAa,QAAQ,IAAI,oBAAoB,yBAAyB,QAAQ,OAAO,EAAE;AAE7F,IAAM,WAAW,QAAQ,IAAI,mBAAmB;AAEhD,IAAM,WAAW,QAAQ,IAAI,mBAAmB,QAAQ,IAAI,iBAAiB;AACtE,IAAM,mBAAmB,QAAQ,IAAI,oBAAoB;AAEzD,SAAS,iBAAiB,KAA6B;AAC5D,SAAO,OAAO,oBAAoB;AACpC;AAEA,IAAI,CAAC,WAAW;AACd,UAAQ,MAAM,0CAA0C;AACxD,UAAQ,KAAK,CAAC;AAChB;AACA,IAAI,CAAC,YAAY,CAAC,UAAU;AAC1B,UAAQ,MAAM,4EAA4E;AAC1F,UAAQ,KAAK,CAAC;AAChB;AAEA,SAAS,UAAkC;AAEzC,SAAO;AAAA,IACL,GAAI,WAAW,EAAE,eAAe,UAAU,QAAQ,GAAG,IAAI,EAAE,eAAe,SAAS;AAAA,IACnF,gBAAgB;AAAA,EAClB;AACF;AAEA,eAAsB,OAAoB,MAA0B;AAClE,QAAM,MAAM,MAAM,MAAM,GAAG,SAAS,GAAG,IAAI,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;AACrE,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,OAAO,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,EAAE;AAC5C,UAAM,IAAI,MAAM,OAAO,IAAI,MAAM,KAAK,KAAK,MAAM,GAAG,GAAG,CAAC,EAAE;AAAA,EAC5D;AACA,SAAO,IAAI,KAAK;AAClB;AAEA,eAAsB,SAAsB,MAAc,MAA4B;AACpF,QAAM,MAAM,MAAM,MAAM,GAAG,SAAS,GAAG,IAAI,IAAI;AAAA,IAC7C,QAAQ;AAAA,IACR,SAAS,QAAQ;AAAA,IACjB,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,EACtC,CAAC;AACD,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,OAAO,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,EAAE;AAC5C,UAAM,IAAI,MAAM,OAAO,IAAI,MAAM,KAAK,KAAK,MAAM,GAAG,GAAG,CAAC,EAAE;AAAA,EAC5D;AACA,SAAO,IAAI,KAAK;AAClB;AAEA,eAAsB,QAAqB,MAAc,MAA4B;AACnF,QAAM,MAAM,MAAM,MAAM,GAAG,SAAS,GAAG,IAAI,IAAI;AAAA,IAC7C,QAAQ;AAAA,IACR,SAAS,QAAQ;AAAA,IACjB,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,EACtC,CAAC;AACD,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,OAAO,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,EAAE;AAC5C,UAAM,IAAI,MAAM,OAAO,IAAI,MAAM,KAAK,KAAK,MAAM,GAAG,GAAG,CAAC,EAAE;AAAA,EAC5D;AACA,SAAO,IAAI,KAAK;AAClB;;;AD9DO,SAAS,qBAAqBA,SAAmB;AACtD,EAAAA,QAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,aACE;AAAA,MACF,aAAa;AAAA,QACX,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mDAAmD;AAAA,QAC7F,UAAU,EAAE,OAAO,EAAE,SAAS,mBAAmB;AAAA,QACjD,SAAS,EAAE,OAAO,EAAE,SAAS,4CAA4C;AAAA,MAC3E;AAAA,IACF;AAAA,IACA,OAAO,EAAE,WAAW,KAAK,UAAU,QAAQ,MAAM;AAC/C,YAAM,YAAY,iBAAiB,GAAG;AACtC,UAAI,CAAC;AACH,eAAO;AAAA,UACL,SAAS;AAAA,YACP;AAAA,cACE,MAAM;AAAA,cACN,MAAM;AAAA,YACR;AAAA,UACF;AAAA,QACF;AACF,UAAI;AACJ,UAAI;AACF,iBAAS,MAAM,QAAQ,0BAA0B,SAAS,YAAY,QAAQ,SAAS,EAAE,QAAQ,CAAC;AAAA,MACpG,SAAS,KAAU;AACjB,cAAM,WAAW,IAAI,WAAW;AAChC,eAAO;AAAA,UACL,SAAS;AAAA,YACP;AAAA,cACE,MAAM;AAAA,cACN,MAAM;AAAA,gBACJ,6BAA6B,QAAQ,KAAK,QAAQ;AAAA,gBAClD;AAAA,gBACA;AAAA,gBACA;AAAA,cACF,EAAE,KAAK,IAAI;AAAA,YACb;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAKA,UAAI;AACJ,UAAI,OAAO,WAAW,UAAU;AAC9B,uBAAe;AAAA,MACjB,WAAW,QAAQ,UAAU;AAC3B,uBAAe,OAAO;AAAA,MACxB,WAAW,QAAQ,MAAM;AACvB,uBAAe,OAAO;AAAA,MACxB,WAAW,QAAQ,SAAS;AAC1B,uBAAe,OAAO;AAAA,MACxB,WAAW,QAAQ,SAAS;AAE1B,YAAI,MAAM,QAAQ,OAAO,OAAO,GAAG;AACjC,yBAAe,OAAO,QACnB,OAAO,CAAC,UAAe,MAAM,SAAS,MAAM,EAC5C,IAAI,CAAC,UAAe,MAAM,IAAI,EAC9B,KAAK,IAAI;AAAA,QACd,OAAO;AACL,yBAAe,OAAO,OAAO,OAAO;AAAA,QACtC;AAAA,MACF,OAAO;AACL,uBAAe,KAAK,UAAU,QAAQ,MAAM,CAAC;AAAA,MAC/C;AAEA,UAAI,CAAC,gBAAgB,iBAAiB,UAAU,iBAAiB,aAAa;AAC5E,uBAAe;AAAA,MACjB;AAEA,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,aAAa,CAAC;AAAA,MACzD;AAAA,IACF;AAAA,EACF;AACF;;;AEjFA,SAAS,KAAAC,UAAS;AAGX,SAAS,oBAAoBC,SAAmB;AACrD,EAAAA,QAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,aACE;AAAA,MACF,aAAa;AAAA,QACX,WAAWC,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mDAAmD;AAAA,QAC7F,UAAUA,GAAE,OAAO,EAAE,SAAS,mBAAmB;AAAA,QACjD,QAAQA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,uCAAuC;AAAA,QAC9E,eAAeA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,uBAAuB;AAAA,MACvE;AAAA,IACF;AAAA,IACA,OAAO,EAAE,WAAW,KAAK,UAAU,QAAQ,cAAc,MAAM;AAC7D,YAAM,YAAY,iBAAiB,GAAG;AACtC,UAAI,CAAC;AACH,eAAO;AAAA,UACL,SAAS;AAAA,YACP;AAAA,cACE,MAAM;AAAA,cACN,MAAM;AAAA,YACR;AAAA,UACF;AAAA,QACF;AACF,YAAM,OAA+B,CAAC;AACtC,UAAI,OAAQ,MAAK,SAAS;AAC1B,UAAI,cAAe,MAAK,gBAAgB;AAExC,UAAI;AACJ,UAAI;AACF,iBAAS,MAAM;AAAA,UACb,0BAA0B,SAAS,YAAY,QAAQ;AAAA,UACvD,OAAO,KAAK,IAAI,EAAE,SAAS,IAAI,OAAO;AAAA,QACxC;AAAA,MACF,SAAS,KAAU;AACjB,eAAO;AAAA,UACL,SAAS;AAAA,YACP;AAAA,cACE,MAAM;AAAA,cACN,MAAM,oCAAoC,QAAQ,KAAK,IAAI,WAAW,eAAe;AAAA,YACvF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,YAAM,QAAQ,QAAQ,UAAU,QAAQ,SAAS,QAAQ,OAAO;AAEhE,YAAM,OAAO,QACT;AAAA,QACE,oCAAoC,QAAQ;AAAA,QAC5C;AAAA,QACA,eAAe,KAAK;AAAA,QACpB;AAAA,QACA;AAAA,MACF,EAAE,KAAK,IAAI,IACX;AAAA,QACE,wCAAwC,QAAQ;AAAA,QAChD;AAAA,QACA;AAAA,QACA,QAAQ,UACJ,oBAAoB,OAAO,OAAO,KAClC;AAAA,MACN,EAAE,KAAK,IAAI;AAEf,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,KAAK,CAAC;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AACF;;;ACxEA,SAAS,KAAAC,UAAS;AAGX,SAAS,qBAAqBC,SAAmB;AACtD,EAAAA,QAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,aACE;AAAA,MACF,aAAa;AAAA,QACX,WAAWC,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mDAAmD;AAAA,QAC7F,QAAQA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,4CAA4C;AAAA,MACrF;AAAA,IACF;AAAA,IACA,OAAO,EAAE,WAAW,KAAK,OAAO,MAAM;AACpC,YAAM,YAAY,iBAAiB,GAAG;AACtC,UAAI,CAAC;AACH,eAAO;AAAA,UACL,SAAS;AAAA,YACP;AAAA,cACE,MAAM;AAAA,cACN,MAAM;AAAA,YACR;AAAA,UACF;AAAA,QACF;AACF,YAAM,YAAY,UAAU;AAE5B,UAAI;AACJ,UAAI;AACF,eAAO,MAAM,OAAO,0BAA0B,SAAS,qBAAqB,SAAS,EAAE;AAAA,MACzF,SAAS,KAAU;AACjB,eAAO;AAAA,UACL,SAAS;AAAA,YACP;AAAA,cACE,MAAM;AAAA,cACN,MAAM,yCAAyC,SAAS,KAAK,IAAI,WAAW,eAAe;AAAA,YAC7F;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAIA,YAAM,QAAQ,KAAK,SAAS,KAAK,gBAAgB;AACjD,YAAM,OAAO,KAAK,QAAQ,KAAK,aAAa;AAC5C,YAAM,aAAa,KAAK,cAAc,KAAK,mBAAmB;AAC9D,YAAM,WAAW,KAAK,YAAY,KAAK,iBAAiB;AACxD,YAAM,WAAW,KAAK,YAAY,KAAK,iBAAiB;AACxD,YAAM,gBAAgB,KAAK,sBAAsB,KAAK,iBAAiB;AACvE,YAAM,aAAa,KAAK,cAAc,KAAK,kBAAkB;AAE7D,YAAM,WAAqB;AAAA,QACzB,iBAAiB,SAAS;AAAA,QAC1B;AAAA,QACA,cAAc,KAAK,wBAAwB,IAAI,uBAAuB,UAAU,4BAA4B,QAAQ,oBAAoB,QAAQ;AAAA,QAChJ,uBAAuB,aAAa,GAAG,OAAO,kBAAkB,WAAW,MAAM,EAAE,uBAAuB,UAAU,GAAG,OAAO,eAAe,WAAW,MAAM,EAAE;AAAA,MAClK;AAGA,YAAM,YAAmB,KAAK,aAAa,KAAK,eAAe,KAAK,kBAAkB,CAAC;AACvF,UAAI,UAAU,SAAS,GAAG;AACxB,iBAAS,KAAK,IAAI,gBAAgB;AAClC,kBAAU,QAAQ,CAAC,GAAQ,MAAc;AACvC,gBAAM,QAAQ,EAAE,SAAS,EAAE,WAAW;AACtC,gBAAM,SAAS,EAAE,eAAe,EAAE,cAAc,EAAE,SAAS;AAC3D,gBAAM,QAAQ,EAAE,cAAc,EAAE,aAAa;AAC7C,mBAAS,KAAK,GAAG,IAAI,CAAC,KAAK,KAAK,KAAK,MAAM,UAAU,QAAQ,KAAK,KAAK,WAAW,EAAE,GAAG;AAAA,QACzF,CAAC;AAAA,MACH;AAGA,YAAM,SAAgB,KAAK,UAAU,KAAK,eAAe,CAAC;AAC1D,UAAI,OAAO,SAAS,GAAG;AACrB,iBAAS,KAAK,IAAI,6BAA6B;AAC/C,cAAM,SAAS,OAAO,MAAM,EAAE;AAC9B,cAAM,YAAY,OACf,IAAI,CAAC,MAAW;AACf,gBAAM,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS;AAC3C,gBAAM,QAAQ,EAAE,SAAS,EAAE,SAAS;AACpC,iBAAO,GAAG,IAAI,KAAK,KAAK;AAAA,QAC1B,CAAC,EACA,KAAK,KAAK;AACb,iBAAS,KAAK,SAAS;AAAA,MACzB;AAEA,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,SAAS,KAAK,IAAI,EAAE,CAAC;AAAA,MAChE;AAAA,IACF;AAAA,EACF;AACF;;;AC1FA,SAAS,KAAAC,UAAS;;;ACGX,SAAS,cAAc,KAAiE;AAC7F,SAAO,OAAO,SAAS,IAAI,eAAe,UAAU,IAAI,eAAe;AACzE;;;ADDA,SAAS,QAAQ,KAAqB;AACpC,QAAM,OAAO,KAAK,IAAI,IAAI,IAAI,KAAK,GAAG,EAAE,QAAQ;AAChD,QAAM,OAAO,KAAK,MAAM,OAAO,GAAM;AACrC,MAAI,OAAO,EAAG,QAAO;AACrB,MAAI,OAAO,GAAI,QAAO,GAAG,IAAI;AAC7B,QAAM,QAAQ,KAAK,MAAM,OAAO,EAAE;AAClC,MAAI,QAAQ,GAAI,QAAO,GAAG,KAAK;AAC/B,QAAM,OAAO,KAAK,MAAM,QAAQ,EAAE;AAClC,SAAO,GAAG,IAAI;AAChB;AAEO,SAAS,eAAeC,SAAmB;AAChD,EAAAA,QAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,aACE;AAAA,MACF,aAAa;AAAA,QACX,WAAWC,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mDAAmD;AAAA,QAC7F,UAAUA,GAAE,OAAO,EAAE,SAAS,eAAe;AAAA,MAC/C;AAAA,IACF;AAAA,IACA,OAAO,EAAE,WAAW,KAAK,SAAS,MAAM;AACtC,YAAM,YAAY,iBAAiB,GAAG;AACtC,UAAI,CAAC;AACH,eAAO;AAAA,UACL,SAAS;AAAA,YACP;AAAA,cACE,MAAM;AAAA,cACN,MAAM;AAAA,YACR;AAAA,UACF;AAAA,QACF;AACF,UAAI;AACJ,UAAI;AACF,YAAI,MAAM,OAAO,0BAA0B,SAAS,YAAY,QAAQ,EAAE;AAAA,MAC5E,QAAQ;AACN,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,eAAe,QAAQ,eAAe,CAAC,EAAE;AAAA,MAC7F;AAEA,YAAM,OAAO,EAAE;AACf,YAAM,cAAc,EAAE;AACtB,YAAM,cAAe,MAAM,eAAe,CAAC;AAC3C,YAAM,gBAAiB,MAAM,iBAAiB,CAAC;AAC/C,YAAM,UAAU,MAAM;AACtB,YAAM,MAAM,EAAE,QAAQ,EAAE,mBAAmB,KAAK,MAAM,EAAE,gBAAgB,IAAI;AAE5E,YAAM,WAAqB,CAAC;AAE5B,eAAS,KAAK,WAAW,EAAE,GAAG,MAAM,EAAE,CAAC,WAAM,EAAE,YAAY,EAAE,KAAK,EAAE;AACpE,eAAS;AAAA,QACP,iBAAiB,EAAE,QAAQ,kBAAkB,EAAE,MAAM,oBAAoB,EAAE,YAAY,YAAY;AAAA,MACrG;AACA,eAAS;AAAA,QACP,iBAAiB,EAAE,aAAa,mBAAmB,QAAQ,EAAE,UAAU,CAAC,eAAe,EAAE,OAAO,KAAK;AAAA,MACvG;AACA,UAAI,EAAE,eAAe,EAAE,SAAS;AAC9B,iBAAS,KAAK,gBAAgB,EAAE,eAAe,KAAK,mBAAmB,EAAE,WAAW,KAAK,EAAE;AAAA,MAC7F;AAEA,UAAI,EAAE,eAAgB,UAAS,KAAK;AAAA;AAAA,EAAqB,EAAE,cAAc,EAAE;AAE3E,UAAI,EAAE,eAAe;AACnB,cAAM,OAAQ,aAAa,uBAAkC;AAC7D,cAAM,UAAU,SAAS,OAAO,KAAK,IAAI,kBAAkB;AAC3D,iBAAS,KAAK;AAAA,gBAAmB,OAAO;AAAA,EAAK,EAAE,aAAa,EAAE;AAAA,MAChE;AAGA,UAAI,OAAO,cAAc,GAAG,GAAG;AAC7B,cAAM,WAAW,IAAI,YAAY,IAAI,aAAa;AAClD,iBAAS;AAAA,UACP;AAAA,qBAAwB,IAAI,cAAc,SAAS;AAAA,YAA2B,QAAQ;AAAA;AAAA,EAAO,IAAI,eAAe,EAAE;AAAA;AAAA;AAAA,EAAmB,IAAI,QAAQ,EAAE;AAAA;AAAA,QACrJ;AAAA,MACF;AAEA,YAAM,SAAS,YAAY,OAAO,CAAC,MAAM,EAAE,UAAU,OAAO,EAAE,MAAM,EAAE;AACtE,UAAI,OAAO,SAAS,GAAG;AACrB,iBAAS,KAAK;AAAA,2BAA8B,OAAO,MAAM;AAAA,EAAM,OAAO,IAAI,CAAC,MAAM,KAAK,EAAE,IAAI,EAAE,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,MAC9G;AAEA,UAAI,cAAc,SAAS,GAAG;AAC5B,iBAAS;AAAA,UACP;AAAA;AAAA,EAAkC,cAAc,IAAI,CAAC,MAAM,KAAK,EAAE,MAAM,IAAI,EAAE,GAAG,WAAM,EAAE,MAAM,EAAE,EAAE,KAAK,IAAI,CAAC;AAAA,QAC/G;AAAA,MACF;AAEA,UAAI,SAAS;AACX,iBAAS;AAAA,UACP;AAAA;AAAA,EAAsB,QAAQ,OAAO,MAAM,QAAQ,EAAE,MAAM,QAAQ,QAAQ,MAAM,QAAQ,QAAQ;AAAA,QACnG;AAAA,MACF;AAEA,YAAM,QAAQ,EAAE;AAChB,UAAI,SAAS,MAAM,SAAS,GAAG;AAC7B,iBAAS;AAAA,UACP;AAAA;AAAA,EAA6B,MAAM,IAAI,CAAC,GAAG,MAAM,GAAG,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,EAAE,SAAS,WAAM,EAAE,MAAM,KAAK,EAAE,EAAE,EAAE,KAAK,IAAI,CAAC;AAAA,QACzH;AAAA,MACF;AAEA,UAAI,EAAE,eAAgB,UAAS,KAAK;AAAA;AAAA,EAAmC,EAAE,cAAc,EAAE;AAGzF,UAAI,EAAE,aAAa,SAAS,GAAG;AAC7B,iBAAS,KAAK;AAAA,gCAAmC;AACjD,mBAAW,MAAM,EAAE,aAAa;AAC9B,mBAAS;AAAA,YACP,WAAW,GAAG,SAAS,KAAK,GAAG,cAAc,OAAO,GAAG,WAAW,KAAK,EAAE,WAAM,GAAG,UAAU,MAAM,GAAG,EAAE,CAAC;AAAA,IAAO,GAAG,aAAa,MAAM,GAAG,GAAG,CAAC;AAAA,UAC9I;AAAA,QACF;AAAA,MACF;AAEA,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,SAAS,KAAK,IAAI,EAAE,CAAC,EAAE;AAAA,IAC3E;AAAA,EACF;AACF;;;AEvHA,SAAS,KAAAC,UAAS;AAGlB,SAASC,SAAQ,KAAqB;AACpC,QAAM,OAAO,KAAK,IAAI,IAAI,IAAI,KAAK,GAAG,EAAE,QAAQ;AAChD,QAAM,OAAO,KAAK,MAAM,OAAO,GAAM;AACrC,MAAI,OAAO,EAAG,QAAO;AACrB,MAAI,OAAO,GAAI,QAAO,GAAG,IAAI;AAC7B,QAAM,QAAQ,KAAK,MAAM,OAAO,EAAE;AAClC,MAAI,QAAQ,GAAI,QAAO,GAAG,KAAK;AAC/B,QAAM,OAAO,KAAK,MAAM,QAAQ,EAAE;AAClC,SAAO,GAAG,IAAI;AAChB;AAEO,SAAS,iBAAiBC,SAAmB;AAClD,EAAAA,QAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,aACE;AAAA,MACF,aAAa;AAAA,QACX,WAAWC,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mDAAmD;AAAA,QAC7F,UAAUA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,sDAAsD;AAAA,QAC/F,QAAQA,GACL,OAAO,EACP,SAAS,EACT,SAAS,4FAA4F;AAAA,QACxG,UAAUA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,yBAAyB;AAAA,QAClE,MAAMA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,2CAA2C;AAAA,QAChF,GAAGA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,qCAAqC;AAAA,QACvE,OAAOA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kCAAkC;AAAA,MAC1E;AAAA,IACF;AAAA,IACA,OAAO,EAAE,WAAW,KAAK,UAAU,QAAQ,UAAU,MAAM,GAAG,MAAM,MAAM;AACxE,YAAM,YAAY,iBAAiB,GAAG;AACtC,UAAI,CAAC;AACH,eAAO;AAAA,UACL,SAAS;AAAA,YACP;AAAA,cACE,MAAM;AAAA,cACN,MAAM;AAAA,YACR;AAAA,UACF;AAAA,QACF;AACF,YAAM,SAAS,IAAI,gBAAgB,EAAE,MAAM,KAAK,OAAO,OAAO,KAAK,IAAI,SAAS,IAAI,EAAE,CAAC,EAAE,CAAC;AAC1F,UAAI,SAAU,QAAO,IAAI,YAAY,QAAQ;AAC7C,aAAO,IAAI,UAAU,UAAU,MAAM;AACrC,UAAI,SAAU,QAAO,IAAI,YAAY,QAAQ;AAC7C,UAAI,KAAM,QAAO,IAAI,QAAQ,IAAI;AACjC,UAAI,EAAG,QAAO,IAAI,KAAK,CAAC;AAExB,YAAM,OAAO,MAAM;AAAA,QACjB,0BAA0B,SAAS,YAAY,MAAM;AAAA,MACvD;AAEA,UAAI,KAAK,QAAQ,WAAW,GAAG;AAC7B,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,sCAAsC,CAAC,EAAE;AAAA,MAC7F;AAEA,YAAM,QAAQ,KAAK,QAAQ,IAAI,CAAC,MAAW;AACzC,cAAM,SAAS,EAAE,YAAY,EAAE,OAAO,MAAM,GAAG,EAAE;AACjD,cAAM,cAAc,EAAE,YAAY;AAClC,cAAM,UAAU,EAAE,gBAAgB,MAAM,EAAE,aAAa,MAAM;AAC7D,eAAO,OAAO,EAAE,QAAQ,QAAQ,EAAE,EAAE,MAAM,KAAK,WAAM,EAAE,MAAM,WAAM,WAAW,WAAMF,SAAQ,EAAE,UAAU,CAAC,GAAG,OAAO;AAAA,MACrH,CAAC;AAED,YAAM,OAAO,mBAAmB,KAAK,KAAK,mBAAmB,KAAK,QAAQ,MAAM;AAAA;AAAA,EAAQ,MAAM,KAAK,IAAI,CAAC;AAAA;AAAA;AACxG,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,KAAK,CAAC,EAAE;AAAA,IACtD;AAAA,EACF;AACF;;;ACtEA,SAAS,KAAAG,UAAS;AAGX,SAAS,mBAAmBC,SAAmB;AACpD,EAAAA,QAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,aAAa;AAAA,MACb,aAAa;AAAA,QACX,WAAWC,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mDAAmD;AAAA,QAC7F,UAAUA,GAAE,OAAO,EAAE,SAAS,mBAAmB;AAAA,MACnD;AAAA,IACF;AAAA,IACA,OAAO,EAAE,WAAW,KAAK,SAAS,MAAM;AACtC,YAAM,YAAY,iBAAiB,GAAG;AACtC,UAAI,CAAC;AACH,eAAO;AAAA,UACL,SAAS;AAAA,YACP;AAAA,cACE,MAAM;AAAA,cACN,MAAM;AAAA,YACR;AAAA,UACF;AAAA,QACF;AACF,UAAI;AACF,cAAM,SAAS,0BAA0B,SAAS,YAAY,QAAQ,UAAU;AAAA,MAClF,SAAS,KAAU;AACjB,eAAO;AAAA,UACL,SAAS;AAAA,YACP;AAAA,cACE,MAAM;AAAA,cACN,MAAM,0BAA0B,QAAQ,KAAK,IAAI,WAAW,eAAe;AAAA,YAC7E;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,QACL,SAAS;AAAA,UACP;AAAA,YACE,MAAM;AAAA,YACN,MAAM,QAAQ,QAAQ;AAAA,UACxB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AC/CA,SAAS,KAAAC,UAAS;AAGX,SAAS,mBAAmBC,SAAmB;AACpD,EAAAA,QAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,aACE;AAAA,MACF,aAAa;AAAA,QACX,WAAWC,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mDAAmD;AAAA,QAC7F,OAAOA,GAAE,OAAO,EAAE,SAAS,uBAAuB;AAAA,QAClD,OAAOA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mCAAmC;AAAA,MAC3E;AAAA,IACF;AAAA,IACA,OAAO,EAAE,WAAW,KAAK,OAAO,MAAM,MAAM;AAC1C,YAAM,YAAY,iBAAiB,GAAG,KAAK;AAC3C,YAAM,OAAO;AAAA,QACX;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,qHAA2G,SAAS;AAAA,QACpH;AAAA,QACA;AAAA,QACA,oBAAoB,KAAK,aAAa,SAAS,CAAC;AAAA,MAClD,EAAE,KAAK,IAAI;AAEX,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,KAAK,CAAC;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AACF;;;AClCA,SAAS,KAAAC,UAAS;AAIX,SAAS,mBAAmBC,SAAmB;AACpD,EAAAA,QAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,aACE;AAAA,MACF,aAAa;AAAA,QACX,WAAWC,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mDAAmD;AAAA,QAC7F,UAAUA,GAAE,OAAO,EAAE,SAAS,mBAAmB;AAAA,MACnD;AAAA,IACF;AAAA,IACA,OAAO,EAAE,WAAW,KAAK,SAAS,MAAM;AACtC,YAAM,YAAY,iBAAiB,GAAG;AACtC,UAAI,CAAC;AACH,eAAO;AAAA,UACL,SAAS;AAAA,YACP;AAAA,cACE,MAAM;AAAA,cACN,MAAM;AAAA,YACR;AAAA,UACF;AAAA,QACF;AACF,UAAI;AACJ,UAAI;AACF,iBAAS,MAAM,OAAO,0BAA0B,SAAS,YAAY,QAAQ,EAAE;AAAA,MACjF,SAAS,KAAU;AACjB,eAAO;AAAA,UACL,SAAS;AAAA,YACP;AAAA,cACE,MAAM;AAAA,cACN,MAAM,cAAc,QAAQ,yBAAyB,SAAS,KAAK,IAAI,WAAW,EAAE;AAAA,YACtF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,YAAM,SAAS,OAAO;AAEtB,UAAI,CAAC,QAAQ;AACX,eAAO;AAAA,UACL,SAAS;AAAA,YACP;AAAA,cACE,MAAM;AAAA,cACN,MAAM;AAAA,gBACJ,gCAAgC,QAAQ;AAAA,gBACxC;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,cACF,EAAE,KAAK,IAAI;AAAA,YACb;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,UAAI;AACJ,UAAI;AACF,cAAM,OAAO,WAAW,WAAW,KAAK,MAAM,MAAM,IAAI;AAAA,MAC1D,QAAQ;AACN,eAAO;AAAA,UACL,SAAS;AAAA,YACP;AAAA,cACE,MAAM;AAAA,cACN,MAAM;AAAA,YACR;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,UAAI,CAAC,cAAc,GAAG,GAAG;AACvB,eAAO;AAAA,UACL,SAAS;AAAA,YACP;AAAA,cACE,MAAM;AAAA,cACN,MAAM;AAAA,gBACJ,sCAAsC,QAAQ;AAAA,gBAC9C;AAAA,gBACA,gCAAgC,IAAI,cAAc,KAAK;AAAA,gBACvD;AAAA,cACF,EAAE,KAAK,IAAI;AAAA,YACb;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,YAAM,WAAW,IAAI,aAAa,IAAI,YAAY;AAClD,YAAM,cAAc,IAAI,eAAe;AACvC,YAAM,OAAO,IAAI,QAAQ,IAAI,QAAQ;AACrC,YAAM,aAAa,IAAI,cAAc;AAErC,YAAM,OAAO;AAAA,QACX,6BAA6B,QAAQ;AAAA,QACrC;AAAA,QACA,eAAe,QAAQ;AAAA,QACvB,mBAAmB,UAAU;AAAA,QAC7B;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,EAAE,KAAK,IAAI;AAEX,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,KAAK,CAAC;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AACF;;;ACxHA,SAAS,KAAAC,UAAS;AAGX,SAAS,kBAAkBC,SAAmB;AACnD,EAAAA,QAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,aAAa;AAAA,MACb,aAAa;AAAA,QACX,WAAWC,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mDAAmD;AAAA,QAC7F,UAAUA,GAAE,OAAO,EAAE,SAAS,mBAAmB;AAAA,QACjD,UAAUA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,6BAA6B;AAAA,QACtE,UAAUA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mCAAmC;AAAA,QAC5E,MAAMA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,6CAA6C;AAAA,QAClF,OAAOA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,cAAc;AAAA,MACtD;AAAA,IACF;AAAA,IACA,OAAO,EAAE,WAAW,KAAK,UAAU,UAAU,UAAU,MAAM,MAAM,MAAM;AACvE,YAAM,YAAY,iBAAiB,GAAG;AACtC,UAAI,CAAC;AACH,eAAO;AAAA,UACL,SAAS;AAAA,YACP;AAAA,cACE,MAAM;AAAA,cACN,MAAM;AAAA,YACR;AAAA,UACF;AAAA,QACF;AACF,YAAM,OAAgC,CAAC;AACvC,UAAI,aAAa,OAAW,MAAK,WAAW;AAC5C,UAAI,aAAa,OAAW,MAAK,WAAW;AAC5C,UAAI,SAAS,OAAW,MAAK,OAAO;AACpC,UAAI,UAAU,OAAW,MAAK,QAAQ;AAEtC,UAAI,OAAO,KAAK,IAAI,EAAE,WAAW,GAAG;AAClC,eAAO;AAAA,UACL,SAAS;AAAA,YACP;AAAA,cACE,MAAM;AAAA,cACN,MAAM;AAAA,YACR;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,UAAI;AACF,cAAM,SAAS,0BAA0B,SAAS,YAAY,QAAQ,WAAW,IAAI;AAAA,MACvF,SAAS,KAAU;AACjB,eAAO;AAAA,UACL,SAAS;AAAA,YACP;AAAA,cACE,MAAM;AAAA,cACN,MAAM,yBAAyB,QAAQ,KAAK,IAAI,WAAW,eAAe;AAAA,YAC5E;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,YAAM,QAAkB,CAAC;AACzB,UAAI,aAAa,OAAW,OAAM,KAAK,aAAa,QAAQ,EAAE;AAC9D,UAAI,aAAa,OAAW,OAAM,KAAK,aAAa,QAAQ,EAAE;AAC9D,UAAI,SAAS,OAAW,OAAM,KAAK,SAAS,IAAI,EAAE;AAClD,UAAI,UAAU,OAAW,OAAM,KAAK,UAAU,KAAK,EAAE;AAErD,YAAM,OAAO,QAAQ,QAAQ,aAAa,MAAM,KAAK,IAAI,CAAC;AAE1D,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,KAAK,CAAC;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AACF;;;AXzDA,IAAM,SAAS,IAAI,UAAU;AAAA,EAC3B,MAAM;AAAA,EACN,SAAS;AAAA,EACT,aACE;AACJ,CAAC;AAED,iBAAiB,MAAM;AACvB,eAAe,MAAM;AACrB,mBAAmB,MAAM;AACzB,mBAAmB,MAAM;AACzB,kBAAkB,MAAM;AACxB,mBAAmB,MAAM;AACzB,oBAAoB,MAAM;AAC1B,qBAAqB,MAAM;AAC3B,qBAAqB,MAAM;AAE3B,eAAe,OAAO;AACpB,QAAM,YAAY,IAAI,qBAAqB;AAC3C,QAAM,OAAO,QAAQ,SAAS;AAC9B,UAAQ,MAAM,mCAAmC;AACnD;AAEA,KAAK,EAAE,MAAM,CAAC,UAAU;AACtB,UAAQ,MAAM,8BAA8B,KAAK;AACjD,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":["server","z","server","z","z","server","z","z","server","z","z","timeAgo","server","z","z","server","z","z","server","z","z","server","z","z","server","z"]}
|
package/package.json
CHANGED