@tikoci/centrs 0.1.1 → 0.1.2
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/CHANGELOG.md +48 -2
- package/GLOSSARY.txt +16 -0
- package/README.md +1 -1
- package/commands/AGENTS.md +3 -2
- package/commands/api/AGENTS.md +212 -0
- package/commands/api/README.md +159 -0
- package/commands/api/examples.md +325 -0
- package/commands/btest/README.md +56 -31
- package/commands/btest/examples.md +35 -10
- package/commands/execute/README.md +9 -3
- package/commands/retrieve/README.md +1 -1
- package/docs/CONSTITUTION.md +6 -6
- package/docs/MATRIX.md +46 -15
- package/docs/errors/routeros/btest-connection-count-single-stream.md +22 -0
- package/docs/errors/routeros/btest-udp-tx-size-ignored.md +15 -0
- package/docs/errors/usage/invalid-method.md +23 -0
- package/package.json +5 -5
- package/src/api.ts +1555 -0
- package/src/btest.ts +61 -1
- package/src/cli/api.ts +536 -0
- package/src/cli/common.ts +64 -0
- package/src/cli.ts +22 -0
- package/src/core/error-catalog.ts +14 -0
- package/src/core/fanout.ts +160 -0
- package/src/core/inspect.ts +170 -0
- package/src/execute.ts +14 -47
- package/src/index.ts +61 -8
- package/src/protocols/adapter.ts +328 -0
- package/src/protocols/btest-session.ts +279 -46
- package/src/protocols/btest.ts +6 -2
- package/src/protocols/native-api.ts +223 -30
- package/src/retrieve-fanout.ts +13 -141
- package/src/retrieve.ts +30 -87
- package/commands/stream/README.md +0 -70
package/docs/MATRIX.md
CHANGED
|
@@ -24,7 +24,7 @@ A cell advances only with the matching evidence in the same change.
|
|
|
24
24
|
| Command | rest-api | native-api | ssh | mac-telnet | snmp | mndp | romon | winbox-terminal |
|
|
25
25
|
| -------- | ------------- | ------------- | ------------- | ------------- | ------------- | ------------- | ------------- | ---------------- |
|
|
26
26
|
| retrieve | `CHR-passed` | `CHR-passed` | — | — | `not-started` | — | — | — |
|
|
27
|
-
|
|
|
27
|
+
| api | `CHR-passed` | `CHR-passed` | — | — | — | — | — | — |
|
|
28
28
|
| execute | `CHR-passed` | `CHR-passed` | `CHR-passed` | `CHR-passed` | — | — | `not-started` | `not-started` |
|
|
29
29
|
| terminal | — | — | `CHR-passed` | `CHR-passed` | — | — | — | — |
|
|
30
30
|
| transfer | `CHR-passed` | `CHR-passed` | `CHR-passed` | — | — | — | — | — |
|
|
@@ -56,13 +56,26 @@ verbose REST `board-name`), and the L2 validation policy are documented in
|
|
|
56
56
|
`commands/discover/README.md`.
|
|
57
57
|
|
|
58
58
|
There is no `update` command: `execute` is the single read/write surface for
|
|
59
|
-
RouterOS add/set/remove, and `retrieve` stays read-only.
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
59
|
+
RouterOS *CLI-shaped* add/set/remove, and `retrieve` stays read-only. The `api`
|
|
60
|
+
command is the structured one-command-per-operation surface (the verb trichotomy
|
|
61
|
+
in `commands/api/README.md`); it can also write. See `docs/CONSTITUTION.md`
|
|
62
|
+
(protocol selection).
|
|
63
|
+
|
|
64
|
+
`api` is `CHR-passed` for `rest-api` and `native-api` (single-target): endpoint
|
|
65
|
+
normalization, the method→verb map, the `/console/inspect` gate, write
|
|
66
|
+
confirmation, `.query`/`.proplist`, `-f`/`-d`/`--input` bodies, `--raw`,
|
|
67
|
+
`/execute` script-run (`=as-string=` for sync output on both transports), and
|
|
68
|
+
open-ended `--stream` follow (native-api only — `NativeApiSession.listen()` +
|
|
69
|
+
`/cancel`, NDJSON envelope frames with a terminating summary; `--via rest-api
|
|
70
|
+
--stream` errors `transport/capability-unsupported`), green on CHR 7.23.1 via
|
|
71
|
+
`test/integration/api.test.ts` + `api-native.test.ts` + `api-listen.test.ts`.
|
|
72
|
+
Still deferred (own phase): multi-target fan-out (`--stream` is single-session).
|
|
73
|
+
|
|
74
|
+
`api` **absorbs** the former `stream` command (folded — no separate row): the
|
|
75
|
+
read-only follow surface is `api <router> <endpoint> --stream` (alias `--listen`;
|
|
76
|
+
the `/listen` endpoint form infers it), native-api only, since REST's 60s cap
|
|
77
|
+
cannot follow. `centrs stream`/`centrs tail` now error with a pointer to
|
|
78
|
+
`api --stream`.
|
|
66
79
|
|
|
67
80
|
`transfer` is `CHR-passed` for `rest-api`/`native-api` and for **sftp** (the
|
|
68
81
|
`ssh` column's first method): `src/transfer.ts` + `src/cli/transfer.ts`
|
|
@@ -156,7 +169,7 @@ core and carry their own state, tracked here:
|
|
|
156
169
|
|
|
157
170
|
| Surface | State | Spec | Notes |
|
|
158
171
|
| ------- | ----- | ---- | ----- |
|
|
159
|
-
| api
|
|
172
|
+
| ts-api | `CHR-passed` | `src/index.ts` | Root **TypeScript library** surface; everything else adapts it. (Renamed from `api (TS)` to avoid colliding with the `api` **command** row in the grid above — the command is a verb, this is the library.) |
|
|
160
173
|
| cli | `coded` | `src/cli/` | `retrieve`/`execute`/`transfer`/`terminal`/`devices`/`discover`/`btest` wired. |
|
|
161
174
|
| mcp | `CHR-passed` | `commands/mcp/` | Scoped-verb stdio MCP server; CDB-as-allowlist safety model. Phase 1 (explain/validate/retrieve/execute, resources) plus first Phase 2 CDB mutation (`centrs_devices add`) green on CHR 7.23 via `test/integration/mcp.test.ts`, including gated write execution. |
|
|
162
175
|
| tui | `not-started` | `src/tui.ts` | Stub. |
|
|
@@ -186,12 +199,30 @@ The wire codec, the EC-SRP5 session/handshake (shared core byte-identical with
|
|
|
186
199
|
mac-telnet's MTWEI, plus the net-new server role), the TCP/UDP data engines, the
|
|
187
200
|
orchestrator + CLI, and the honest grounding caveat (the server gets direct CHR
|
|
188
201
|
evidence over the QEMU SLIRP gateway `10.0.2.2`; the client gets direct CHR
|
|
189
|
-
evidence over a host→guest `tcp:2000` forward
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
`
|
|
202
|
+
evidence over a host→guest `tcp:2000` forward (the forward carries TCP; UDP rides
|
|
203
|
+
the guest→host gateway instead, below); UDP-receive was
|
|
204
|
+
previously a soft smoke test because the SLIRP reverse path was believed to block
|
|
205
|
+
real validation and a `connect()` socket filter was silently dropping all received
|
|
206
|
+
datagrams — RouterOS sends UDP data **from a different source port** than the
|
|
207
|
+
negotiated `serverUdpPort`, so the BSD receive filter rejected every packet;
|
|
208
|
+
fixed by removing `connect()` and addressing sends explicitly, validated against
|
|
209
|
+
a real RouterOS device at 163–203 Mbps receive and 104 Mbps bidirectional, and
|
|
210
|
+
**CI now gates UDP client receive/both** — the server→client return rides the
|
|
211
|
+
guest→host SLIRP gateway (`10.0.2.2:clientUdpPort`), needing no UDP forward and no
|
|
212
|
+
quickchr change (#88 closed; the `connect()` filter fix in #86 is what enabled it);
|
|
213
|
+
TCP
|
|
214
|
+
`connection-count` reaches the server's command packet (#84) and centrs opens the
|
|
215
|
+
negotiated extra TCP data connections — multi-connection **fan-out** (#87),
|
|
216
|
+
grounded byte-for-byte against RouterOS 7.23.1 (secondary join
|
|
217
|
+
`[token:u16 BE][0x02][0 …]`) and CHR-gated for the realized fan-out
|
|
218
|
+
(`activeConnections == count`; no throughput-rise assertion — the SLIRP loopback is
|
|
219
|
+
bandwidth-bound); authenticated sessions stay single-stream (warned); TCP
|
|
220
|
+
`direction=both` demuxes the server's
|
|
221
|
+
interleaved status frames so the client paces its TX from feedback and does not
|
|
222
|
+
starve server→client RX (#85 fixed); the Windows unit tier skips UDP-loopback
|
|
223
|
+
tests (#69); NDJSON is not adopted) are
|
|
224
|
+
documented in `commands/btest/README.md` and the `src/protocols/btest.ts`,
|
|
225
|
+
`src/protocols/btest-session.ts`, and `src/protocols/ec-srp5.ts` module headers.
|
|
195
226
|
|
|
196
227
|
## Priority order
|
|
197
228
|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# `routeros/btest-connection-count-single-stream`
|
|
2
|
+
|
|
3
|
+
A **warning** (not a failure): `centrs btest client --protocol tcp
|
|
4
|
+
--connection-count <n>` opened **fewer** TCP data connections than `n`. centrs
|
|
5
|
+
does implement the multi-connection fan-out — it opens the extra connections that
|
|
6
|
+
join the test with the server-negotiated session token — but it falls back to a
|
|
7
|
+
single stream when the server negotiates **no** token. The common case is an
|
|
8
|
+
**authenticated (EC-SRP5)** session: centrs does not yet capture the post-auth
|
|
9
|
+
session token, so authenticated tests stay single-stream. A secondary connection
|
|
10
|
+
that fails mid-handshake also reduces the realized count.
|
|
11
|
+
|
|
12
|
+
The warning reports both the requested and the actually-active connection count.
|
|
13
|
+
|
|
14
|
+
## Workaround
|
|
15
|
+
|
|
16
|
+
- For full multi-stream throughput, run the test **unauthenticated**
|
|
17
|
+
(`/tool/bandwidth-server` with `authenticate=no`), where centrs negotiates the
|
|
18
|
+
token and opens all `n` connections.
|
|
19
|
+
- Or run several `centrs btest client` processes in parallel and sum their
|
|
20
|
+
throughput.
|
|
21
|
+
|
|
22
|
+
See `docs/CONSTITUTION.md` for the centrs error/warning contract.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# `routeros/btest-udp-tx-size-ignored`
|
|
2
|
+
|
|
3
|
+
A non-fatal warning. For UDP `--direction both`, the btest wire protocol carries
|
|
4
|
+
a **single** `tx-size` field, so the client and the server transmit with the
|
|
5
|
+
same packet size. centrs maps `--local-udp-tx-size` to that field and discards
|
|
6
|
+
`--remote-udp-tx-size`. This warning fires only when both flags are set to
|
|
7
|
+
different values, so you know which size the session actually used.
|
|
8
|
+
|
|
9
|
+
## Fix
|
|
10
|
+
|
|
11
|
+
Drop `--remote-udp-tx-size` for `--direction both`, or set both flags to the
|
|
12
|
+
same value. To size each direction independently, run two sessions:
|
|
13
|
+
`--direction transmit` (uses `--local-udp-tx-size`) and `--direction receive`
|
|
14
|
+
(uses `--remote-udp-tx-size`). See `commands/btest/README.md` and
|
|
15
|
+
[`docs/CONSTITUTION.md`](../../CONSTITUTION.md).
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# `usage/invalid-method`
|
|
2
|
+
|
|
3
|
+
The -X/--method value is not a supported HTTP method.
|
|
4
|
+
|
|
5
|
+
## Fix
|
|
6
|
+
|
|
7
|
+
`centrs api` honors the HTTP method (`-X` / `--method`) literally against
|
|
8
|
+
RouterOS's REST verb map. The accepted methods are `GET`, `PUT`, `PATCH`,
|
|
9
|
+
`DELETE`, and `POST` (case-insensitive):
|
|
10
|
+
|
|
11
|
+
| Method | RouterOS verb |
|
|
12
|
+
| ------ | -------------------- |
|
|
13
|
+
| `GET` | print / get |
|
|
14
|
+
| `PUT` | add (RouterOS create) |
|
|
15
|
+
| `PATCH`| set |
|
|
16
|
+
| `DELETE`| remove |
|
|
17
|
+
| `POST` | run a command |
|
|
18
|
+
|
|
19
|
+
Pass one of those with `-X`, or omit the flag to use the default `GET`. Note the
|
|
20
|
+
trap: **`PUT` is RouterOS's create**, not `POST`.
|
|
21
|
+
|
|
22
|
+
See [`docs/CONSTITUTION.md`](../../CONSTITUTION.md) for the centrs error
|
|
23
|
+
contract.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tikoci/centrs",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"main": "src/index.ts",
|
|
5
5
|
"module": "src/index.ts",
|
|
6
6
|
"repository": {
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"packageManager": "bun@1.3.13",
|
|
13
13
|
"devDependencies": {
|
|
14
14
|
"@agent-lint/cli": "^0.8.1",
|
|
15
|
-
"@biomejs/biome": "2.5.
|
|
15
|
+
"@biomejs/biome": "2.5.1",
|
|
16
16
|
"@secretlint/secretlint-rule-preset-recommend": "^13.0.2",
|
|
17
17
|
"@tikoci/quickchr": "^0.4.2",
|
|
18
18
|
"@types/bun": "^1.3.13",
|
|
@@ -57,11 +57,11 @@
|
|
|
57
57
|
"scripts": {
|
|
58
58
|
"ci": "bun run lint && bun run test && bun run build",
|
|
59
59
|
"git:pre-commit": "bun run lint",
|
|
60
|
-
"git:pre-push": "bun run
|
|
60
|
+
"git:pre-push": "bun run lint:git:push",
|
|
61
61
|
"lint": "bun run lint:biome && bun run lint:typecheck",
|
|
62
62
|
"lint:git:commit": "bun run lint",
|
|
63
|
-
"lint:git:push": "bun run ci",
|
|
64
|
-
"lint:ci": "bun run lint && bun run lint:markdownlint && bun run lint:cspell && bun run lint:secretlint
|
|
63
|
+
"lint:git:push": "bun run lint:ci && bun run test && bun run build",
|
|
64
|
+
"lint:ci": "bun run lint && bun run lint:markdownlint && bun run lint:cspell && bun run lint:secretlint",
|
|
65
65
|
"lint:cspell": "cspell lint . --gitignore",
|
|
66
66
|
"lint:cspell:all": "cspell lint . --no-gitignore",
|
|
67
67
|
"lint:markdownlint": "markdownlint-cli2 \"**/*.md\" \"!.scratch/**\"",
|