@mrrlin-dev/mcp 0.2.2 → 0.2.4
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/dist/bin.cjs +360 -273
- package/dist/prompts/report-issue.md +155 -0
- package/package.json +6 -5
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: report-issue
|
|
3
|
+
description: Use when a Mrrlin user hits a problem and wants it reported to support. Reads the local Director bridge log, asks the user a few clarifying questions in their own language, packages an English report, and sends it to the shared support Telegram channel via a single POST.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Report a Mrrlin issue to support
|
|
7
|
+
|
|
8
|
+
You are helping a Mrrlin **user/customer** report a problem. Do all the plumbing
|
|
9
|
+
yourself and keep it invisible to them: read their local logs, ask only what you
|
|
10
|
+
genuinely cannot infer, then send one packaged report to the support Telegram
|
|
11
|
+
channel. The user should never see or touch the token, the log path, or the POST.
|
|
12
|
+
|
|
13
|
+
## How this gets invoked
|
|
14
|
+
|
|
15
|
+
This prompt ships inside `@mrrlin-dev/mcp`. `mrrlin-mcp report-issue` prints this
|
|
16
|
+
file to stdout, so the same text drives all three surfaces:
|
|
17
|
+
|
|
18
|
+
- **Terminal (feed it to Codex):** `codex "$(mrrlin-mcp report-issue)"`
|
|
19
|
+
- **Codex slash command:** `mrrlin-mcp report-issue > ~/.codex/prompts/report-issue.md` once, then run `/report-issue`.
|
|
20
|
+
- **Skill:** it has skill frontmatter (`name` + `description`), so a skill-aware agent can activate it directly.
|
|
21
|
+
|
|
22
|
+
## Service bot it talks to
|
|
23
|
+
|
|
24
|
+
The token below is **intentionally public** — `@mrrlinIssuesBot` is a throwaway
|
|
25
|
+
service bot dedicated to the Mrrlin support group. Anyone reading this file may
|
|
26
|
+
see it; that is by design. The bot can only post to the one chat hardcoded
|
|
27
|
+
below, so leaking the token costs at most some spam in that chat — rotate via
|
|
28
|
+
@BotFather if it ever happens.
|
|
29
|
+
|
|
30
|
+
- Bot: `@mrrlinIssuesBot` (id `8506614214`)
|
|
31
|
+
- Group: "Mrrlin", chat id `-5373779177`
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## What to do
|
|
36
|
+
|
|
37
|
+
### 1. Read the Director bridge log
|
|
38
|
+
|
|
39
|
+
The bridge writes one JSON object per line to a daily file. Find the log dir, in
|
|
40
|
+
this order, and use the first that exists:
|
|
41
|
+
|
|
42
|
+
1. `$CODEX_HOME/mrrlin/director-bridge/logs/` (only if `CODEX_HOME` is set)
|
|
43
|
+
2. `~/.mrrlin/director-bridge/logs/`
|
|
44
|
+
|
|
45
|
+
Pick the **most recent** `bridge-YYYY-MM-DD.jsonl` file (filenames are UTC dates;
|
|
46
|
+
sort descending). Read roughly the **last 200 lines**. Each line looks like:
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{"ts":"...","dir":"in|out","spanId":"...","sessionId":"...","type":"turn|event|error|...","ms":123,"payload":{...}}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Secrets are already redacted by the logger (tokens show as `[REDACTED]`), so the
|
|
53
|
+
log lines are safe to forward as-is.
|
|
54
|
+
|
|
55
|
+
From the tail, extract:
|
|
56
|
+
|
|
57
|
+
- Every line with `type:"error"` (and any `dir:"out"` payload that looks like a failure — non-2xx HTTP, stack traces, "failed", "timeout").
|
|
58
|
+
- The last few `type:"turn"` lines for context on what the user was doing.
|
|
59
|
+
- The latest `sessionId` and the `spanId`s tied to the errors.
|
|
60
|
+
- `ts` of the first and last relevant lines (the time window).
|
|
61
|
+
|
|
62
|
+
If no log dir or file exists, or the tail has no errors, say so plainly and rely
|
|
63
|
+
on what the user tells you in step 2 — still send the report.
|
|
64
|
+
|
|
65
|
+
### 2. Ask the user — in THEIR language
|
|
66
|
+
|
|
67
|
+
Detect the language the user is writing in and ask in that language. Keep it to a
|
|
68
|
+
few short questions, ask them **once**, don't interrogate. Cover:
|
|
69
|
+
|
|
70
|
+
- **What were you doing** when it broke?
|
|
71
|
+
- **What actually happened** (the symptom they saw)?
|
|
72
|
+
- **What did you expect to happen instead?** — ask this **only if the expected
|
|
73
|
+
result is not already obvious** from the log or from what they described. If
|
|
74
|
+
it's obvious, infer it and skip the question.
|
|
75
|
+
|
|
76
|
+
If the user gives short or partial answers, accept them and move on. Never block
|
|
77
|
+
the report on a perfect answer.
|
|
78
|
+
|
|
79
|
+
### 3. Package the report (in ENGLISH)
|
|
80
|
+
|
|
81
|
+
Translate the user's answers to English. Build a plain-text report. Keep the whole
|
|
82
|
+
thing under **4096 characters** (Telegram's per-message limit) — trim the log
|
|
83
|
+
excerpt first if needed, keeping the error lines over the context lines.
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
🛠️ Mrrlin issue report
|
|
87
|
+
When (UTC): <iso timestamp of the report>
|
|
88
|
+
Mrrlin MCP: v<version if known> | OS: <platform> | Node: <version>
|
|
89
|
+
|
|
90
|
+
▶ What the user was doing:
|
|
91
|
+
<their answer, in English>
|
|
92
|
+
|
|
93
|
+
▶ Expected result:
|
|
94
|
+
<their answer, or "(obvious from context: ...)", or "(not provided)">
|
|
95
|
+
|
|
96
|
+
▶ Actual result / symptom:
|
|
97
|
+
<their answer, in English>
|
|
98
|
+
|
|
99
|
+
▶ Errors from bridge log (<filename>):
|
|
100
|
+
<the extracted error lines, verbatim — already redacted>
|
|
101
|
+
|
|
102
|
+
▶ Context:
|
|
103
|
+
session=<sessionId> spanIds=<...> window=<first ts>..<last ts>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### 4. Send it — a single POST to Telegram
|
|
107
|
+
|
|
108
|
+
This is **just one HTTP POST** to the Telegram Bot API `sendMessage` method.
|
|
109
|
+
Endpoint and shape:
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
POST https://api.telegram.org/bot8506614214:AAGyhO1phWb7ah2aN6_gAX2Co7OXNN3zb0A/sendMessage
|
|
113
|
+
Content-Type: application/json
|
|
114
|
+
body: { "chat_id": "-5373779177", "text": "<the report>", "disable_web_page_preview": true }
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Do **not** set `parse_mode` — send the report as plain text so nothing needs
|
|
118
|
+
escaping. Because the report has newlines and quotes, build the JSON safely
|
|
119
|
+
(serialize it; don't hand-concatenate a string), write it to a temp file, and POST
|
|
120
|
+
the file so the shell can't mangle it:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
# Write the JSON payload with a proper serializer, then:
|
|
124
|
+
curl -sS -X POST \
|
|
125
|
+
"https://api.telegram.org/bot8506614214:AAGyhO1phWb7ah2aN6_gAX2Co7OXNN3zb0A/sendMessage" \
|
|
126
|
+
-H "Content-Type: application/json" \
|
|
127
|
+
--data-binary @/tmp/mrrlin-report.json
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Check the response: Telegram returns `{"ok":true,...}` on success. If it returns
|
|
131
|
+
`{"ok":false,"description":"..."}` or curl fails, show the user the error and offer
|
|
132
|
+
to retry once.
|
|
133
|
+
|
|
134
|
+
**Optional — full log as an attachment.** If the trimmed excerpt lost important
|
|
135
|
+
lines, also send the full log file as a document (separate call):
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
curl -sS -X POST \
|
|
139
|
+
"https://api.telegram.org/bot8506614214:AAGyhO1phWb7ah2aN6_gAX2Co7OXNN3zb0A/sendDocument" \
|
|
140
|
+
-F "chat_id=-5373779177" \
|
|
141
|
+
-F "document=@<path-to-bridge-YYYY-MM-DD.jsonl>"
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### 5. Confirm
|
|
145
|
+
|
|
146
|
+
Tell the user, in their language, that the report was sent (or that it failed and
|
|
147
|
+
why). Don't dump the raw report or the token back at them — just confirm.
|
|
148
|
+
|
|
149
|
+
## Rules
|
|
150
|
+
|
|
151
|
+
- Ask the user in their language; write the report in English.
|
|
152
|
+
- Hide the mechanics: never surface the token, the log path, or the curl command to the user.
|
|
153
|
+
- Forward log lines as-is — they're already secret-redacted. Do not paste anything that looks like a live token even if you see one.
|
|
154
|
+
- One report = one `sendMessage` POST. Keep it under 4096 chars; use `sendDocument` only for the optional full log.
|
|
155
|
+
- If anything is missing (no log, vague answers), still send the best report you can rather than giving up.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrrlin-dev/mcp",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"mrrlin-mcp": "dist/bin.cjs"
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
},
|
|
11
11
|
"files": [
|
|
12
12
|
"dist/bin.cjs",
|
|
13
|
-
"dist/consensus/personas"
|
|
13
|
+
"dist/consensus/personas",
|
|
14
|
+
"dist/prompts"
|
|
14
15
|
],
|
|
15
16
|
"devDependencies": {
|
|
16
17
|
"@types/node": "^20.17.50",
|
|
@@ -19,12 +20,12 @@
|
|
|
19
20
|
"@types/ws": "^8.18.1",
|
|
20
21
|
"esbuild": "^0.24.0",
|
|
21
22
|
"tsx": "^4.22.3",
|
|
23
|
+
"@mrrlin/client": "0.0.0",
|
|
22
24
|
"@mrrlin/codex-client": "0.0.0",
|
|
23
25
|
"@mrrlin/director-e2e": "0.0.0",
|
|
24
26
|
"@mrrlin/schemas": "0.0.0",
|
|
25
27
|
"@mrrlin/tsconfig": "0.0.0",
|
|
26
|
-
"@mrrlin/wiki": "0.0.0"
|
|
27
|
-
"@mrrlin/client": "0.0.0"
|
|
28
|
+
"@mrrlin/wiki": "0.0.0"
|
|
28
29
|
},
|
|
29
30
|
"dependencies": {
|
|
30
31
|
"@iarna/toml": "^2.2.5",
|
|
@@ -36,7 +37,7 @@
|
|
|
36
37
|
},
|
|
37
38
|
"scripts": {
|
|
38
39
|
"build": "tsc -p tsconfig.json && pnpm run bundle && chmod +x dist/bin.cjs",
|
|
39
|
-
"bundle": "esbuild src/bin.ts --bundle --platform=node --format=cjs --target=node20 --outfile=dist/bin.cjs --banner:js='#!/usr/bin/env node' && mkdir -p dist/consensus/personas && cp src/consensus/personas/*.md dist/consensus/personas/",
|
|
40
|
+
"bundle": "esbuild src/bin.ts --bundle --platform=node --format=cjs --target=node20 --outfile=dist/bin.cjs --banner:js='#!/usr/bin/env node' && mkdir -p dist/consensus/personas && cp src/consensus/personas/*.md dist/consensus/personas/ && mkdir -p dist/prompts && cp src/prompts/*.md dist/prompts/",
|
|
40
41
|
"dev": "tsx watch src/bin.ts serve",
|
|
41
42
|
"lint": "eslint .",
|
|
42
43
|
"start": "node dist/bin.cjs serve",
|