New POST /api/messages — injects a synthetic inbound (rx) message into the bot's inbox, as if received on the mesh. For external systems to trigger communication later (issue #12). NOT transmitted over RF.
{"text":"hello bot","from":2594370888}
text required non-empty; from optional node number (integer 1..0xffffffff) — omitted → record has no from
Record lands in the same history buffer as real traffic: {id, dir:"rx", from?, text, channel:0, at} and appears in GET /api/messages newest-first like any rx message
Returns { id }; invalid input → 400 with the same messages on REST and MCP
Details
New MeshService.injectMessage(text, from?) — pushes via the existing HISTORY_LIMIT push+shift cap; shared buffer with captured packets (verified by test)
Shared randomPacketId() extracted in codec.ts (was inline in buildTextToRadio) — tx sends and injections use the same id generation
9th MCP tool inject_message({text, from?}) — JSON-in-text-block pattern; test asserts nothing reaches the bridge socket (no ToRadio packet on the wire)
Verification
npm run build ✓
npm test — 42/42 passed (was 37, +5: newest-first rx records, from omitted when absent, empty/invalid rejection, cap at 100, shared buffer with captured packets)
## What
New `POST /api/messages` — injects a **synthetic inbound (rx) message** into the bot's inbox, as if received on the mesh. For external systems to trigger communication later (issue #12). NOT transmitted over RF.
```json
{ "text": "hello bot", "from": 2594370888 }
```
- `text` required non-empty; `from` optional node number (integer 1..0xffffffff) — omitted → record has no `from`
- Record lands in the same history buffer as real traffic: `{id, dir:"rx", from?, text, channel:0, at}` and appears in `GET /api/messages` newest-first like any rx message
- Returns `{ id }`; invalid input → 400 with the same messages on REST and MCP
## Details
- New `MeshService.injectMessage(text, from?)` — pushes via the existing HISTORY_LIMIT push+shift cap; shared buffer with captured packets (verified by test)
- Shared `randomPacketId()` extracted in codec.ts (was inline in buildTextToRadio) — tx sends and injections use the same id generation
- 9th MCP tool `inject_message({text, from?})` — JSON-in-text-block pattern; test asserts nothing reaches the bridge socket (no ToRadio packet on the wire)
## Verification
- `npm run build` ✓
- `npm test` — 42/42 passed (was 37, +5: newest-first rx records, from omitted when absent, empty/invalid rejection, cap at 100, shared buffer with captured packets)
- v0.9.0, CHANGELOG entry added
Closes #12
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
What
New
POST /api/messages— injects a synthetic inbound (rx) message into the bot's inbox, as if received on the mesh. For external systems to trigger communication later (issue #12). NOT transmitted over RF.textrequired non-empty;fromoptional node number (integer 1..0xffffffff) — omitted → record has nofrom{id, dir:"rx", from?, text, channel:0, at}and appears inGET /api/messagesnewest-first like any rx message{ id }; invalid input → 400 with the same messages on REST and MCPDetails
MeshService.injectMessage(text, from?)— pushes via the existing HISTORY_LIMIT push+shift cap; shared buffer with captured packets (verified by test)randomPacketId()extracted in codec.ts (was inline in buildTextToRadio) — tx sends and injections use the same id generationinject_message({text, from?})— JSON-in-text-block pattern; test asserts nothing reaches the bridge socket (no ToRadio packet on the wire)Verification
npm run build✓npm test— 42/42 passed (was 37, +5: newest-first rx records, from omitted when absent, empty/invalid rejection, cap at 100, shared buffer with captured packets)Closes #12