mira-harness 0.1.0
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/LICENSE +21 -0
- package/README.md +201 -0
- package/dist/chunk-NSGRB4ZK.js +636 -0
- package/dist/chunk-PPYKMDQ4.js +17 -0
- package/dist/cli.js +441 -0
- package/dist/index.d.ts +169 -0
- package/dist/index.js +38 -0
- package/dist/mcp.js +228 -0
- package/examples/catalog.sample.json +22 -0
- package/package.json +67 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Masashi Ono
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# mira-harness
|
|
2
|
+
|
|
3
|
+
**Automated probe harness for the [@mira](https://t.me/mira) Telegram bot.**
|
|
4
|
+
|
|
5
|
+
Drive @mira from a Telegram *userbot* (GramJS), capture the **full** reply — buttons,
|
|
6
|
+
deep-link / `startapp` targets, source links, media, edits, latency — and run a
|
|
7
|
+
self-driving experiment catalog. No screenshots, no copy-paste.
|
|
8
|
+
|
|
9
|
+
> Built to let an AI agent (Claude) experiment on another AI (@mira) hands-free, and
|
|
10
|
+
> to keep a structured, reproducible record of how @mira actually behaves.
|
|
11
|
+
|
|
12
|
+
## Why a userbot (not a bot)
|
|
13
|
+
|
|
14
|
+
@mira has **no public API**, and Telegram has a hard rule: **a bot cannot read
|
|
15
|
+
another bot's messages**. So a bot token can't talk to @mira. The only working path
|
|
16
|
+
is a **userbot** — driving a real Telegram *user account* via MTProto (GramJS).
|
|
17
|
+
|
|
18
|
+
## Install
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
git clone https://github.com/Masashi-Ono0611/mira-harness.git
|
|
22
|
+
cd mira-harness
|
|
23
|
+
npm install
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Configuration
|
|
27
|
+
|
|
28
|
+
Copy `.env.example` to `.env` and fill in your Telegram `api_id` / `api_hash` (it's gitignored):
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
cp .env.example .env
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Mint the session once (interactive — enter the code Telegram sends you):
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npm run login # prints TG_SESSION=... -> paste it into .env
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
(Optional) Mira Pro credits: DM `/promo MIRAFAM26` to @mira.
|
|
41
|
+
|
|
42
|
+
## Usage
|
|
43
|
+
|
|
44
|
+
Via `npm run dev -- <args>`, or build once (`npm run build`) and use the `mira-harness` bin / `npx`.
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# one probe — prints the full settled reply as JSON
|
|
48
|
+
npm run dev -- send "STON_USDT_10"
|
|
49
|
+
|
|
50
|
+
# self-driving catalog (paced 15s, STOP_MIRA kill switch, observe-only)
|
|
51
|
+
npm run dev -- loop --category core
|
|
52
|
+
npm run dev -- loop --category skills --max 4
|
|
53
|
+
|
|
54
|
+
# also press a safe ✅ Confirm on generation probes (spends Pro credits)
|
|
55
|
+
npm run dev -- loop --category generation --confirm
|
|
56
|
+
|
|
57
|
+
# run in a group instead of the DM (needs TG_EXPERIMENT_CHAT)
|
|
58
|
+
npm run dev -- loop --peer experiment
|
|
59
|
+
|
|
60
|
+
# distill the run log into Markdown
|
|
61
|
+
npm run dev -- report
|
|
62
|
+
npm run dev -- report --out report.md
|
|
63
|
+
|
|
64
|
+
# preflight checks (env / session / connectivity) and list the catalog
|
|
65
|
+
npm run dev -- doctor
|
|
66
|
+
npm run dev -- catalog
|
|
67
|
+
npm run dev -- loop --list
|
|
68
|
+
|
|
69
|
+
# message via stdin; tune timing; quiet (no spinner); skip the run log
|
|
70
|
+
echo "STON_USDT_10" | npm run dev -- send
|
|
71
|
+
npm run dev -- send "ping" --settle 3000 --timeout 30000 --quiet --no-log
|
|
72
|
+
|
|
73
|
+
# live-tail @mira while you poke at it by hand; custom catalog; filtered report
|
|
74
|
+
npm run dev -- watch
|
|
75
|
+
npm run dev -- loop --catalog ./examples/catalog.sample.json
|
|
76
|
+
npm run dev -- report --category core
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
After `npm run build` (or once published):
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
npx mira-harness doctor
|
|
83
|
+
npx mira-harness send "STON_USDT_10"
|
|
84
|
+
npx mira-harness loop --category core
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Capture fidelity (the point)
|
|
88
|
+
|
|
89
|
+
@mira's interesting behavior lives **outside the plain text**. `send`/`loop` wait a
|
|
90
|
+
**settle window** (quiet period after the last activity, bounded by a hard cap, with
|
|
91
|
+
a "typing…" fallback for a slow bot — replies run 5–62s) and capture, per message:
|
|
92
|
+
|
|
93
|
+
- **multi-message** replies and **streamed edits** (final text + an `editCount`),
|
|
94
|
+
- **buttons** — inline `url` and **`web_app` / startapp** targets (Mini App "Launch" cards),
|
|
95
|
+
- **links** — `text_url` entities (deep-research source links),
|
|
96
|
+
- **media** — photo / video / audio / document / webpage (metadata; not downloaded).
|
|
97
|
+
|
|
98
|
+
`report` turns the JSONL run log into a per-probe Markdown table (gist / signals / latency).
|
|
99
|
+
|
|
100
|
+
## Commands
|
|
101
|
+
|
|
102
|
+
| Command | What |
|
|
103
|
+
|---|---|
|
|
104
|
+
| `login` | One-time interactive login → prints `TG_SESSION` |
|
|
105
|
+
| `doctor` | Check `.env` / session / connectivity / @mira resolution (read-only) |
|
|
106
|
+
| `send [message...]` | One probe → full reply as JSON (message via arg or stdin). `--quiet --settle --timeout --no-log` |
|
|
107
|
+
| `loop` | Run the catalog paced. `--category --max --confirm --peer --gap --settle --timeout --list --catalog --quiet` |
|
|
108
|
+
| `catalog` | List the catalog (no sends). `--category --catalog --json` |
|
|
109
|
+
| `watch` | Live-tail @mira's messages (observe-only). `--peer` |
|
|
110
|
+
| `report` | Distill the run log into Markdown. `--in --out --category` |
|
|
111
|
+
|
|
112
|
+
Run `mira-harness --help` (or `<command> --help`) for full options.
|
|
113
|
+
|
|
114
|
+
### Custom catalog
|
|
115
|
+
|
|
116
|
+
The built-in catalog (30 probes: `core` / `skills` / `generation` / `wallet`) is just a
|
|
117
|
+
default. Point `--catalog <file.json>` (CLI) or `catalogFile` (MCP) at your own probe set
|
|
118
|
+
to probe any bot — each entry needs `id` + `send` (`category` / `hypothesis` / `slow` /
|
|
119
|
+
`confirm` / `note` optional). See [`examples/catalog.sample.json`](examples/catalog.sample.json):
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
mira-harness loop --catalog ./examples/catalog.sample.json
|
|
123
|
+
mira-harness catalog --catalog ./examples/catalog.sample.json --json
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Use as a library
|
|
127
|
+
|
|
128
|
+
The CLI is a thin frontend over an exported core:
|
|
129
|
+
|
|
130
|
+
```ts
|
|
131
|
+
import { connect, sendAndCollect } from "mira-harness";
|
|
132
|
+
|
|
133
|
+
const client = await connect(process.env.TG_SESSION!);
|
|
134
|
+
const result = await sendAndCollect(client, "mira", "STON_USDT_10");
|
|
135
|
+
console.log(result.messages[0]?.buttons); // captured buttons (incl. web_app/startapp)
|
|
136
|
+
await client.disconnect();
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Exposed: `connect` · `sendAndCollect` · `clickAndCollect` · `extractMessage` · `CATALOG` /
|
|
140
|
+
`probesFor` · `appendRun` · `renderReport` · `tgEnv` (and their types).
|
|
141
|
+
|
|
142
|
+
## MCP server
|
|
143
|
+
|
|
144
|
+
A third frontend over the same core: an MCP **stdio** server (`mira-harness-mcp`) so a
|
|
145
|
+
Claude/agent can probe @mira directly via tools.
|
|
146
|
+
|
|
147
|
+
| Tool | Args | What |
|
|
148
|
+
|---|---|---|
|
|
149
|
+
| `mira_send` | `message`, `settleMs?`, `timeoutMs?` | one probe → full reply (JSON) |
|
|
150
|
+
| `mira_loop` | `category?`, `max?`, `peer?`, `gapMs?`, `settleMs?`, `timeoutMs?`, `catalogFile?` | run the catalog, **observe-only** (never clicks / spends credits) |
|
|
151
|
+
| `mira_catalog` | `category?`, `catalogFile?` | list the catalog (no network) |
|
|
152
|
+
| `mira_report` | `inFile?`, `category?` | run log → Markdown |
|
|
153
|
+
| `mira_doctor` | — | env / session / connectivity check |
|
|
154
|
+
|
|
155
|
+
Register it (local build — run `npm run build` first):
|
|
156
|
+
|
|
157
|
+
```json
|
|
158
|
+
{
|
|
159
|
+
"mcpServers": {
|
|
160
|
+
"mira-harness": {
|
|
161
|
+
"command": "node",
|
|
162
|
+
"args": ["/abs/path/to/mira-harness/dist/mcp.js"],
|
|
163
|
+
"env": {
|
|
164
|
+
"TG_API_ID": "...",
|
|
165
|
+
"TG_API_HASH": "...",
|
|
166
|
+
"TG_SESSION": "...",
|
|
167
|
+
"MIRA_PEER": "mira"
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Credentials come from the `env` block above or a `.env` in the server's working
|
|
175
|
+
directory. Once published (the bin ships in the `mira-harness` package):
|
|
176
|
+
`{ "command": "npx", "args": ["-y", "--package", "mira-harness", "mira-harness-mcp"] }`.
|
|
177
|
+
|
|
178
|
+
## Safety
|
|
179
|
+
|
|
180
|
+
- **Allowlist** — sends only to `MIRA_PEER` (+ optional `TG_EXPERIMENT_CHAT`); anything else throws.
|
|
181
|
+
- **Kill switch** — `touch STOP_MIRA` blocks all sends (re-checked before a credit-gated confirm too).
|
|
182
|
+
- **Observe-only by default** — never clicks. `--confirm` presses only a one-shot **✅ Confirm**
|
|
183
|
+
on `confirm: true` (generation) probes; wallet / OAuth / transfer / "Always yes" are never pressed.
|
|
184
|
+
- **Rate** — human-like gap between probes (own-account ban risk).
|
|
185
|
+
- **Secrets** — `TG_SESSION` = full account access. `.env` only, never commit.
|
|
186
|
+
|
|
187
|
+
> Automating a personal account is a Telegram ToS gray area; a ban hits your real
|
|
188
|
+
> account. Low frequency + allowlist + kill switch mitigate it. To fully isolate, log
|
|
189
|
+
> in with a dedicated test account — no code changes needed.
|
|
190
|
+
|
|
191
|
+
## Develop
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
npm run typecheck # tsc --noEmit
|
|
195
|
+
npm test # unit tests for the pure extractors (no network)
|
|
196
|
+
npm run build # tsup -> dist/cli.js
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## License
|
|
200
|
+
|
|
201
|
+
MIT
|