@tikoci/centrs 0.1.6 → 0.1.8-next.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/CHANGELOG.md +342 -0
- package/GLOSSARY.txt +32 -0
- package/README.md +10 -6
- package/SECURITY.md +1 -1
- package/commands/AGENTS.md +2 -1
- package/commands/api/AGENTS.md +55 -30
- package/commands/api/README.md +135 -42
- package/commands/api/examples.md +275 -19
- package/commands/devices/README.md +21 -4
- package/commands/devices/examples.md +33 -2
- package/commands/execute/README.md +60 -18
- package/commands/execute/examples.md +224 -0
- package/commands/explain/README.md +42 -5
- package/commands/mcp/README.md +2 -1
- package/commands/retrieve/README.md +348 -4
- package/commands/retrieve/examples.md +442 -5
- package/commands/terminal/README.md +14 -4
- package/commands/terminal/examples.md +22 -3
- package/commands/transfer/README.md +55 -9
- package/commands/transfer/examples.md +106 -7
- package/docs/CLI.md +29 -21
- package/docs/CONSTITUTION.md +41 -16
- package/docs/MATRIX.md +38 -1
- package/docs/errors/README.md +3 -1
- package/docs/errors/cdb/create-failed.md +20 -0
- package/docs/errors/cdb/file-exists.md +23 -0
- package/docs/errors/input/invalid-query.md +36 -0
- package/docs/errors/input/invalid-target.md +25 -3
- package/docs/errors/input/local-destination.md +20 -0
- package/docs/errors/input/unsupported-query.md +19 -0
- package/docs/errors/internal/byte-string.md +13 -0
- package/docs/errors/routeros/invalid-value.md +3 -2
- package/docs/errors/settings/invalid-timeout.md +6 -0
- package/docs/errors/transport/cancel-unacknowledged.md +24 -0
- package/docs/errors/transport/stream-overflow.md +21 -0
- package/docs/errors/usage/removed-flag.md +20 -0
- package/docs/errors/validation/menu-unavailable.md +22 -0
- package/docs/errors/validation/not-followable.md +23 -0
- package/docs/errors/validation/package-missing.md +29 -0
- package/docs/errors/validation/unknown-path.md +16 -4
- package/docs/errors/wait/deadline-exceeded.md +14 -0
- package/docs/errors/wait/interrupted.md +10 -0
- package/package.json +14 -11
- package/src/absent-menu.ts +280 -0
- package/src/api-fanout.ts +22 -12
- package/src/api.ts +603 -194
- package/src/btest.ts +19 -17
- package/src/cli/api.ts +126 -34
- package/src/cli/devices.ts +16 -3
- package/src/cli/execute.ts +18 -5
- package/src/cli/retrieve.ts +216 -22
- package/src/cli/terminal.ts +10 -5
- package/src/cli/transfer.ts +23 -8
- package/src/core/envelope.ts +14 -0
- package/src/core/error-catalog.ts +70 -1
- package/src/core/execute-command.ts +313 -6
- package/src/core/inspect.ts +65 -27
- package/src/core/query.ts +508 -0
- package/src/core/routeros-errors.ts +67 -1
- package/src/data/winbox-cdb-write.ts +22 -8
- package/src/devices.ts +148 -37
- package/src/discover.ts +7 -8
- package/src/errors.ts +116 -7
- package/src/execute-fanout.ts +14 -9
- package/src/execute.ts +128 -116
- package/src/explain/catalog.ts +64 -16
- package/src/explain/menus.ts +27 -6
- package/src/explain.ts +6 -6
- package/src/index.ts +31 -1
- package/src/mcp/tools.ts +10 -15
- package/src/protocols/adapter.ts +235 -118
- package/src/protocols/btest-session.ts +3 -2
- package/src/protocols/endpoint.ts +10 -0
- package/src/protocols/mac-telnet-console.ts +12 -7
- package/src/protocols/native-api.ts +252 -73
- package/src/protocols/sftp.ts +44 -14
- package/src/protocols/ssh.ts +42 -14
- package/src/resolver/cdb.ts +28 -7
- package/src/resolver/index.ts +1 -0
- package/src/resolver/target.ts +84 -18
- package/src/retrieve-fanout.ts +51 -12
- package/src/retrieve-follow.ts +862 -0
- package/src/retrieve-sample.ts +244 -0
- package/src/retrieve-stream.ts +115 -0
- package/src/retrieve-wait.ts +286 -0
- package/src/retrieve.ts +741 -109
- package/src/settings.ts +15 -15
- package/src/transfer-fanout.ts +40 -15
- package/src/transfer.ts +234 -32
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# `cdb/create-failed`
|
|
2
|
+
|
|
3
|
+
A new CDB file could not be created at the resolved location.
|
|
4
|
+
|
|
5
|
+
`centrs devices init` creates an empty CDB at the path from `--cdb-file`,
|
|
6
|
+
`CENTRS_CDB_FILE`, or the default `~/.config/tikoci/winbox.cdb`, making any
|
|
7
|
+
missing parent directories. This error means the filesystem refused: typically
|
|
8
|
+
a directory on the path is not writable by the current user, or a path
|
|
9
|
+
component is a file rather than a directory. The underlying filesystem error
|
|
10
|
+
(for example `EACCES`) is preserved as the error's `cause`; run
|
|
11
|
+
with `--json` to see it.
|
|
12
|
+
|
|
13
|
+
Nothing is written when this fails.
|
|
14
|
+
|
|
15
|
+
## Fix
|
|
16
|
+
|
|
17
|
+
- Check the permissions of the directories on the path shown in the error.
|
|
18
|
+
- Or choose a writable location:
|
|
19
|
+
`centrs devices init --cdb-file PATH`, then pass the same `--cdb-file PATH`
|
|
20
|
+
(or set `CENTRS_CDB_FILE`) on later commands.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# `cdb/file-exists`
|
|
2
|
+
|
|
3
|
+
`devices init` found a CDB already at the resolved location and wrote nothing.
|
|
4
|
+
|
|
5
|
+
This is a warning on a successful result, not an error. Like `git init`,
|
|
6
|
+
`centrs devices init` never overwrites an existing CDB. When the file there
|
|
7
|
+
already loads as a CDB, `init` succeeds with `data.created: false` and
|
|
8
|
+
`data.recordCount` set to the number of records it holds, and leaves the file
|
|
9
|
+
byte-for-byte untouched. A bootstrap script can therefore run `init`
|
|
10
|
+
unconditionally.
|
|
11
|
+
|
|
12
|
+
A file at that path that does not load as a CDB is not reported here. `init`
|
|
13
|
+
fails with the load error instead (`cdb/parse-failed`, or
|
|
14
|
+
`cdb/password-required` for an encrypted CDB without `--cdb-password`), and
|
|
15
|
+
still leaves the file alone.
|
|
16
|
+
|
|
17
|
+
## Fix
|
|
18
|
+
|
|
19
|
+
Usually nothing: the CDB you asked for exists.
|
|
20
|
+
|
|
21
|
+
- To see what it holds: `centrs devices list --cdb-file PATH`.
|
|
22
|
+
- To start fresh, pick a different path (`centrs devices init --cdb-file
|
|
23
|
+
NEW_PATH`), or move the existing file aside yourself; centrs never deletes it.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# `input/invalid-query`
|
|
2
|
+
|
|
3
|
+
A `--query` expression does not parse as a `print where` condition.
|
|
4
|
+
|
|
5
|
+
## When it happens
|
|
6
|
+
|
|
7
|
+
`retrieve --query` and `api --query` take what you would write after
|
|
8
|
+
`print where`: `name=ether1`, `mtu>=1500 and !dynamic`,
|
|
9
|
+
`(type=ether or type=vlan)`. centrs parses it before anything is sent, then
|
|
10
|
+
runs it on the router as an API query. The error's `context.offset` points at
|
|
11
|
+
the problem in `context.query`.
|
|
12
|
+
|
|
13
|
+
centrs also refuses spellings that RouterOS reads differently from how they
|
|
14
|
+
look, or does not accept:
|
|
15
|
+
|
|
16
|
+
- `!name=value` is `(!name)=value` to RouterOS, which matches by accident.
|
|
17
|
+
Write `!(name=value)` or `name!=value`.
|
|
18
|
+
- `not` is not a RouterOS operator. Use `!`.
|
|
19
|
+
- Conditions separated only by a space. Join them with `and` or `or`.
|
|
20
|
+
- An unquoted `=` inside a value. RouterOS reads `comment=x=yes` as
|
|
21
|
+
`(comment=x)=yes`, and `comment=x!=y` matches nothing. Quote it:
|
|
22
|
+
`comment="x=yes"`.
|
|
23
|
+
- A space after the operator (`comment= x`), which RouterOS rejects too.
|
|
24
|
+
- A string escape RouterOS does not have, such as lowercase hex `\0a` (hex is
|
|
25
|
+
two uppercase digits; `\ff` is `\f` then `f`), or a hex byte above `\7F`,
|
|
26
|
+
which a UTF-8 query value cannot carry.
|
|
27
|
+
|
|
28
|
+
A bare name (`disabled`, `comment`) means what it means after `where`: `yes`
|
|
29
|
+
for a boolean and "is set" for anything else. Only the router knows which a
|
|
30
|
+
property is, so with `--validate=false` a bare name fails here too.
|
|
31
|
+
|
|
32
|
+
## Fix
|
|
33
|
+
|
|
34
|
+
- Quote values that contain spaces: `comment="uplink a"`.
|
|
35
|
+
- Close every `(` and `"`.
|
|
36
|
+
- Write a boolean out as `disabled=yes` if validation is off.
|
|
@@ -2,8 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
The target string is invalid for the requested operation.
|
|
4
4
|
|
|
5
|
+
A command's `<router>` is looked up in the CDB first: its `target`, or an
|
|
6
|
+
`identity=` / `mac=` / `ip=` comment lookup key. When nothing matches, centrs
|
|
7
|
+
treats the string as a host. This error means it is not a valid host either,
|
|
8
|
+
or it is a URL that carries a path. Common causes:
|
|
9
|
+
|
|
10
|
+
- **`quickchr:NAME`**: there is no `quickchr:` target prefix. A quickchr VM is
|
|
11
|
+
selected with a flag: `--quickchr NAME`.
|
|
12
|
+
- **A typo or stray characters**, such as spaces or an extra `:` (`a b`,
|
|
13
|
+
`bad:host:name`).
|
|
14
|
+
- **A base URL with a path**, such as `http://192.0.2.1/rest`. The RouterOS
|
|
15
|
+
menu path is a separate argument.
|
|
16
|
+
|
|
17
|
+
The rejected string is in the error's `context.target`.
|
|
18
|
+
|
|
5
19
|
## Fix
|
|
6
20
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
21
|
+
Pass one of the accepted target forms:
|
|
22
|
+
|
|
23
|
+
| Form | Example |
|
|
24
|
+
| ---- | ------- |
|
|
25
|
+
| CDB target or lookup key | `edge1` (see `centrs devices list`) |
|
|
26
|
+
| IP address or hostname, optional `:port` | `192.0.2.1`, `router.example:8080` |
|
|
27
|
+
| Base URL without a path | `https://192.0.2.1:8443` |
|
|
28
|
+
| quickchr VM | `--quickchr NAME` (a flag, not a prefix) |
|
|
29
|
+
|
|
30
|
+
With an explicit `--cdb-file` and no `__default__` fallback record, a string
|
|
31
|
+
that matches no record stops earlier with `cdb/not-found-target`.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# `input/local-destination`
|
|
2
|
+
|
|
3
|
+
A local download destination cannot be written (missing parent directory, a directory, or no permission).
|
|
4
|
+
|
|
5
|
+
`transfer download` checks the local destination before it reads anything
|
|
6
|
+
from the device. The parent directory must already exist, because centrs does
|
|
7
|
+
not create directories, and the destination itself must not be a directory.
|
|
8
|
+
A path that cannot be checked at all (no permission on a directory along the
|
|
9
|
+
way, a file used as a directory, a symlink loop) fails the same way. A write
|
|
10
|
+
that still fails afterwards (no permission, the directory removed
|
|
11
|
+
mid-transfer) reports this code too, with the operating-system error as the
|
|
12
|
+
cause.
|
|
13
|
+
|
|
14
|
+
## Fix
|
|
15
|
+
|
|
16
|
+
- Create the parent directory first: `mkdir -p DIR`, then retry the download.
|
|
17
|
+
- Name a file, not a directory: `download fw.rsc ./backups/fw.rsc`, not
|
|
18
|
+
`download fw.rsc ./backups/`.
|
|
19
|
+
- Pass `-` as the local path to write the bytes to stdout instead.
|
|
20
|
+
- For a fan-out download, `--out-dir` must be an existing directory.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# `input/unsupported-query`
|
|
2
|
+
|
|
3
|
+
A `--query` uses something the RouterOS API query cannot run.
|
|
4
|
+
|
|
5
|
+
## When it happens
|
|
6
|
+
|
|
7
|
+
`--query` runs on the router as an API query (native `?` words, REST
|
|
8
|
+
`.query`), and that query language has no regex (`~`), no prefix membership
|
|
9
|
+
(`in`), and no script evaluation. A value starting with `$`, `[` or `{`, or a
|
|
10
|
+
`$` inside a quoted value, would need RouterOS's script evaluator. centrs
|
|
11
|
+
refuses these rather than filtering some other way and calling it a router
|
|
12
|
+
filter.
|
|
13
|
+
|
|
14
|
+
## Fix
|
|
15
|
+
|
|
16
|
+
- Read the rows without that condition and filter them yourself.
|
|
17
|
+
- Or run the console form, which returns console text rather than rows:
|
|
18
|
+
`centrs execute <router> '/ip/address/print where interface~"^ether"'`.
|
|
19
|
+
- For a literal `$` in a quoted value, escape it as `\$`.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# `internal/byte-string`
|
|
2
|
+
|
|
3
|
+
A binary RouterOS word held a character that is not a byte.
|
|
4
|
+
|
|
5
|
+
## Fix
|
|
6
|
+
|
|
7
|
+
This is a centrs bug; report it with the command that triggered it.
|
|
8
|
+
|
|
9
|
+
`transfer` moves `/file` contents over REST and native-api as byte strings,
|
|
10
|
+
one string code unit per byte (#404). A code unit above U+00FF has no single
|
|
11
|
+
byte, so centrs refuses the request before it reaches the router rather than
|
|
12
|
+
silently keeping the low byte. See
|
|
13
|
+
[`docs/CONSTITUTION.md`](../../CONSTITUTION.md) for the centrs error contract.
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
# `routeros/invalid-value`
|
|
2
2
|
|
|
3
|
-
RouterOS rejected
|
|
4
|
-
|
|
3
|
+
RouterOS rejected a supplied value. When RouterOS names the offending argument,
|
|
4
|
+
it is captured in `context.argument`.
|
|
5
5
|
|
|
6
6
|
## Typical RouterOS strings
|
|
7
7
|
|
|
8
8
|
- `invalid value for argument <name>`
|
|
9
9
|
- `invalid value of <name>`
|
|
10
|
+
- `input does not match ...`
|
|
10
11
|
|
|
11
12
|
## Fix
|
|
12
13
|
|
|
@@ -18,6 +18,12 @@ Like the other typed-value codes here, this isn't `settings`-exclusive:
|
|
|
18
18
|
flag, so the same failure shape shows up anywhere a duration string is
|
|
19
19
|
resolved, not just through `settings set`.
|
|
20
20
|
|
|
21
|
+
`retrieve --sample <interval>` and `retrieve --follow --sweep <period>` are
|
|
22
|
+
stricter: the value needs a unit (`5s`, `500ms`, `1m`). `--sample` must be
|
|
23
|
+
above zero; `--sweep 0` is allowed and turns the sweep off. A bare `--sample 5` fails here
|
|
24
|
+
because RouterOS reads `interval=5` as five seconds while centrs reads a bare
|
|
25
|
+
number as milliseconds; pass the unit you mean.
|
|
26
|
+
|
|
21
27
|
One write detail worth knowing: `settings set timeout` writes the
|
|
22
28
|
**canonical parsed milliseconds**, not the raw suffixed string you typed —
|
|
23
29
|
`centrs settings set timeout 5s` writes `CENTRS_TIMEOUT=5000` to
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# `transport/cancel-unacknowledged`
|
|
2
|
+
|
|
3
|
+
RouterOS did not acknowledge a stream's /cancel within the timeout; centrs ended
|
|
4
|
+
the stream and closed the session locally.
|
|
5
|
+
|
|
6
|
+
## When it happens
|
|
7
|
+
|
|
8
|
+
This is a **warning** on the summary envelope of `centrs api … --stream`, not a
|
|
9
|
+
failure. The stream stopped for its normal reason (`--duration` elapsed, or
|
|
10
|
+
Ctrl-C), and centrs sent RouterOS `/cancel` for the `/listen`. A cooperating
|
|
11
|
+
router answers with an `interrupted` trap and `!done` within milliseconds. This
|
|
12
|
+
one did not answer within `--timeout`, so centrs stopped waiting, closed the
|
|
13
|
+
native API session and finished.
|
|
14
|
+
|
|
15
|
+
The summary's `stopReason` is still the reason the stream stopped. The warning
|
|
16
|
+
records that the router never confirmed the cancel, so the stop was local.
|
|
17
|
+
|
|
18
|
+
## Fix
|
|
19
|
+
|
|
20
|
+
- Usually nothing: the stream ended when you asked, and the session is closed.
|
|
21
|
+
- If it repeats against one router, the API connection is likely stalled (a
|
|
22
|
+
router under load, or a firewall or NAT device holding the TCP session).
|
|
23
|
+
Check the router's CPU and the path to it before relying on long-lived
|
|
24
|
+
streams there.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# `transport/stream-overflow`
|
|
2
|
+
|
|
3
|
+
More stream replies were waiting unread than the buffer allows, so centrs ended
|
|
4
|
+
the stream rather than drop any.
|
|
5
|
+
|
|
6
|
+
## When it happens
|
|
7
|
+
|
|
8
|
+
`centrs retrieve <router> <menu> --follow` buffers changes between RouterOS and
|
|
9
|
+
the reader, up to 50,000. The buffer fills when the reader stops reading (a
|
|
10
|
+
stalled pipe), or when a burst arrives while a long snapshot is still loading.
|
|
11
|
+
centrs never drops a change silently, because the state you hold would then
|
|
12
|
+
look current while being wrong. It ends the follow with this error instead, as
|
|
13
|
+
the failed summary (`stopReason: "transport-error"`).
|
|
14
|
+
|
|
15
|
+
## Fix
|
|
16
|
+
|
|
17
|
+
- The state you built from the lines is stale. Follow again: the new follow
|
|
18
|
+
starts with a fresh snapshot.
|
|
19
|
+
- Read lines as they arrive. Don't buffer the whole output before processing.
|
|
20
|
+
- For a very busy menu, follow a narrower menu (for example `/interface/vlan`
|
|
21
|
+
instead of `/interface`).
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# `usage/removed-flag`
|
|
2
|
+
|
|
3
|
+
A flag or request field was removed; the error names its replacement.
|
|
4
|
+
|
|
5
|
+
## Fix
|
|
6
|
+
|
|
7
|
+
Run the replacement printed in the error's remediation.
|
|
8
|
+
|
|
9
|
+
`api --listen` (and the library's `ApiRequest.listen`) is the current case
|
|
10
|
+
(#402). It meant "stream the replies" and also turned a GET of a menu into a
|
|
11
|
+
change subscription. `api` now sends the command as typed:
|
|
12
|
+
|
|
13
|
+
- To follow changes, request the menu's `listen`:
|
|
14
|
+
`centrs api <router> ip/address/listen`. A `/listen` endpoint implies
|
|
15
|
+
`--stream` and native-api.
|
|
16
|
+
- To stream any other command's replies, use `--stream`
|
|
17
|
+
(`ApiRequest.stream` / `apiStream()` in the library).
|
|
18
|
+
|
|
19
|
+
See [`docs/CONSTITUTION.md`](../../CONSTITUTION.md) for the centrs error
|
|
20
|
+
contract.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# `validation/menu-unavailable`
|
|
2
|
+
|
|
3
|
+
RouterOS 7 publishes this menu or command, but this device does not have it —
|
|
4
|
+
usually hardware, build or version.
|
|
5
|
+
|
|
6
|
+
Same detection as
|
|
7
|
+
[`validation/package-missing`](package-missing.md): RouterOS rejected a path
|
|
8
|
+
segment, and centrs's path catalog knows the path. This code is used when the
|
|
9
|
+
published gates are not a package alone — a hardware capability
|
|
10
|
+
(`/interface/w60g` needs `60ghz`), a build condition, or no gate at all, which
|
|
11
|
+
usually means the device's RouterOS version predates or dropped the menu.
|
|
12
|
+
The path can end in a command rather than a menu: `/system/license/output` is
|
|
13
|
+
published `nochr`, so a CHR rejects it here, and the summary calls it a command.
|
|
14
|
+
|
|
15
|
+
`error.context` carries `path`, `segment`, `gates` (root-first, each with the
|
|
16
|
+
`package`, `syscap` and `conditions` MikroTik published) and `detail`.
|
|
17
|
+
|
|
18
|
+
## Fix
|
|
19
|
+
|
|
20
|
+
The command is not the problem. Compare the gates with the device: installed
|
|
21
|
+
packages (`/system/package/print`), model, and RouterOS version
|
|
22
|
+
(`/system/resource/print`). Run the command only on devices that have the menu.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# `validation/not-followable`
|
|
2
|
+
|
|
3
|
+
The RouterOS menu cannot be followed: it is a single record, or its print has
|
|
4
|
+
no follow-only.
|
|
5
|
+
|
|
6
|
+
## When it happens
|
|
7
|
+
|
|
8
|
+
`centrs retrieve <router> <menu> --follow` checks the menu live through
|
|
9
|
+
`/console/inspect` before following it. RouterOS can follow a menu only when
|
|
10
|
+
its `print` takes `follow-only`, which is the same thing native-API `listen`
|
|
11
|
+
needs. Single-record menus such as `/system/resource`, `/system/identity` and
|
|
12
|
+
`/ip/dns` never take it, and neither do some list menus.
|
|
13
|
+
|
|
14
|
+
Nothing was followed. The error's `context.singleton` says which case it was.
|
|
15
|
+
|
|
16
|
+
## Fix
|
|
17
|
+
|
|
18
|
+
- Read the menu once: `centrs retrieve <router> <menu>`.
|
|
19
|
+
- To see a value change over time, sample it:
|
|
20
|
+
`centrs retrieve <router> <menu> --sample 5s` (one line per complete read,
|
|
21
|
+
until `--count`, `--duration` or Ctrl-C).
|
|
22
|
+
- If you expected the menu to be followable, check the path with
|
|
23
|
+
`centrs retrieve <router> <menu> --list-attributes`.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# `validation/package-missing`
|
|
2
|
+
|
|
3
|
+
This device has no such menu or command; MikroTik publishes it in a package
|
|
4
|
+
that is likely not installed.
|
|
5
|
+
|
|
6
|
+
RouterOS's `:parse` reports a menu it does not have as `syntax error` (slash
|
|
7
|
+
spelling, `/zerotier/print`) or `bad command name` (space spelling,
|
|
8
|
+
`/zerotier print`). Both point at the segment it could not resolve. centrs
|
|
9
|
+
looks that path up in its path catalog — every RouterOS 7.10–7.25 build, all
|
|
10
|
+
extra packages — and when MikroTik publishes it behind a package and nothing
|
|
11
|
+
else, reports this code instead of `validation/syntax`.
|
|
12
|
+
|
|
13
|
+
`error.context` carries:
|
|
14
|
+
|
|
15
|
+
- `path` — the absent menu or command, from the root (`/zerotier`). The summary
|
|
16
|
+
says which, from the path catalog's kind. An abbreviated segment
|
|
17
|
+
is expanded when the catalog has one unique completion.
|
|
18
|
+
- `segment` — the segment as written.
|
|
19
|
+
- `packages` — the published package names. These are MikroTik's build names
|
|
20
|
+
and can differ from the installable package (`wireless-rep` ships in
|
|
21
|
+
`wireless`, `userman-5` in `user-manager`).
|
|
22
|
+
- `gates` — every published gate on the path, root-first.
|
|
23
|
+
- `detail` — RouterOS's own words; `error.position` is its byte column.
|
|
24
|
+
|
|
25
|
+
## Fix
|
|
26
|
+
|
|
27
|
+
The command is not the problem. Check the installed packages with
|
|
28
|
+
`/system/package/print`, install the package and reboot, or run the command only
|
|
29
|
+
on devices that have it.
|
|
@@ -1,9 +1,21 @@
|
|
|
1
1
|
# `validation/unknown-path`
|
|
2
2
|
|
|
3
|
-
The RouterOS path does not expose the requested command.
|
|
3
|
+
The RouterOS path does not exist, or does not expose the requested command.
|
|
4
|
+
|
|
5
|
+
Two sources raise it:
|
|
6
|
+
|
|
7
|
+
- **`execute` / `validate`** — RouterOS's `:parse` rejected a path segment, and
|
|
8
|
+
the path is in no published RouterOS 7 build centrs knows of (its path
|
|
9
|
+
catalog covers 7.10–7.25, all extra packages). Usually a typo.
|
|
10
|
+
`error.context.path` is the path through the rejected segment,
|
|
11
|
+
`error.context.segment` the segment as written, and `error.position`
|
|
12
|
+
RouterOS's byte column. A path the catalog does know is reported as
|
|
13
|
+
[`validation/package-missing`](package-missing.md) or
|
|
14
|
+
[`validation/menu-unavailable`](menu-unavailable.md) instead.
|
|
15
|
+
- **`retrieve` / `api`** — `/console/inspect` shows the path has no command of
|
|
16
|
+
the kind requested (no `print` or `get` to read with).
|
|
4
17
|
|
|
5
18
|
## Fix
|
|
6
19
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
for `validation/unknown-path`.
|
|
20
|
+
Check the spelling of the segment in `error.context.segment`. `centrs explain
|
|
21
|
+
'<command>'` shows how the rest of the command reads offline.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# `wait/deadline-exceeded`
|
|
2
|
+
|
|
3
|
+
The wait deadline passed before readiness or its condition was established.
|
|
4
|
+
|
|
5
|
+
## Fix
|
|
6
|
+
|
|
7
|
+
Check the predicate and the router's current state, then choose a longer
|
|
8
|
+
`--wait` if the operation legitimately needs more time. `--timeout` bounds
|
|
9
|
+
individual requests and does not extend the overall deadline.
|
|
10
|
+
|
|
11
|
+
`meta.operation.wait` reports `deadline-elapsed`, elapsed milliseconds,
|
|
12
|
+
attempts and completed observations. A failed or unfinished read never proves
|
|
13
|
+
an empty result. If the last attempt failed with a transient transport error,
|
|
14
|
+
that error is preserved instead of this code.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# `wait/interrupted`
|
|
2
|
+
|
|
3
|
+
The wait was cancelled before readiness or its condition was established.
|
|
4
|
+
|
|
5
|
+
## Fix
|
|
6
|
+
|
|
7
|
+
Run the wait again when you want to continue. Ctrl-C or an aborted library
|
|
8
|
+
signal is a failure to establish the condition, even if some reads completed.
|
|
9
|
+
The final envelope reports `meta.operation.wait.stopReason: "interrupted"`
|
|
10
|
+
and the partial attempts and observations.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tikoci/centrs",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8-next.0",
|
|
4
4
|
"main": "src/index.ts",
|
|
5
5
|
"module": "src/index.ts",
|
|
6
6
|
"repository": {
|
|
@@ -12,18 +12,18 @@
|
|
|
12
12
|
"packageManager": "bun@1.3.14",
|
|
13
13
|
"license": "MIT",
|
|
14
14
|
"devDependencies": {
|
|
15
|
-
"@biomejs/biome": "2.5.
|
|
16
|
-
"@secretlint/secretlint-rule-preset-recommend": "^13.0.
|
|
17
|
-
"@types/bun": "
|
|
15
|
+
"@biomejs/biome": "2.5.15",
|
|
16
|
+
"@secretlint/secretlint-rule-preset-recommend": "^13.0.7",
|
|
17
|
+
"@types/bun": "1.3.14",
|
|
18
18
|
"cloc": "^2.6.0-cloc",
|
|
19
|
-
"cspell": "^10.
|
|
19
|
+
"cspell": "^10.3.6",
|
|
20
20
|
"has-flag": "4.0.0",
|
|
21
|
-
"markdownlint-cli2": "^0.23.
|
|
22
|
-
"secretlint": "^13.0.
|
|
23
|
-
"typedoc": "^0.28.
|
|
21
|
+
"markdownlint-cli2": "^0.23.3",
|
|
22
|
+
"secretlint": "^13.0.7",
|
|
23
|
+
"typedoc": "^0.28.20"
|
|
24
24
|
},
|
|
25
25
|
"optionalDependencies": {
|
|
26
|
-
"@tikoci/quickchr": "^0.4.
|
|
26
|
+
"@tikoci/quickchr": "^0.4.8"
|
|
27
27
|
},
|
|
28
28
|
"peerDependencies": {
|
|
29
29
|
"typescript": "^6.0.3"
|
|
@@ -133,10 +133,13 @@
|
|
|
133
133
|
"explain:token-census:readme:check": "bun run scripts/explain-token-census.ts --readme --check",
|
|
134
134
|
"security": "bun run lint:secretlint && bun run lint:markdownlint"
|
|
135
135
|
},
|
|
136
|
+
"overrides": {
|
|
137
|
+
"smol-toml": "^1.9.1"
|
|
138
|
+
},
|
|
136
139
|
"type": "module",
|
|
137
140
|
"types": "src/index.ts",
|
|
138
141
|
"dependencies": {
|
|
139
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
140
|
-
"zod": "^4.
|
|
142
|
+
"@modelcontextprotocol/sdk": "^1.32.1",
|
|
143
|
+
"zod": "^4.6.7"
|
|
141
144
|
}
|
|
142
145
|
}
|