|
@@ -11,6 +11,63 @@
|
|
|
- Server can also push commands back to routers (uci_set, shell, reboot, wifi_restart, status).
|
|
- Server can also push commands back to routers (uci_set, shell, reboot, wifi_restart, status).
|
|
|
- Dashboard (new in 2.1) provides Apple-style web UI for monitoring and control.
|
|
- Dashboard (new in 2.1) provides Apple-style web UI for monitoring and control.
|
|
|
|
|
|
|
|
|
|
+## Conventions
|
|
|
|
|
+
|
|
|
|
|
+### ⛔ All Lua code targets Lua 5.1 (OpenWrt default)
|
|
|
|
|
+
|
|
|
|
|
+OpenWrt ships **Lua 5.1** (with `compat-5.3` in some builds, but not all
|
|
|
|
|
+packages). Every `.lua` file under `package/` must parse and run cleanly
|
|
|
|
|
+on plain Lua 5.1. **Never use 5.2+/5.3+/5.4/LuaJIT-only features.**
|
|
|
|
|
+
|
|
|
|
|
+**Forbidden (will silently break on the router):**
|
|
|
|
|
+- `goto` / `::label::` statements (5.2+)
|
|
|
|
|
+- `continue` statement (5.2+)
|
|
|
|
|
+- `<close>` attribute on to-be-closed locals (5.4)
|
|
|
|
|
+- `integer` type, hex floats (`0x1.8p3`), `\xNN` escapes (5.3+)
|
|
|
|
|
+- `//` floor division, `&` `|` `~` `<<` `>>` bitwise operators (5.3+, LuaJIT)
|
|
|
|
|
+- `utf8.*` standard library (5.3+)
|
|
|
|
|
+- `table.move` / `table.pack` (5.2+/5.3); use `table.insert` + `table.remove`
|
|
|
|
|
+- `string.pack` / `string.unpack` / `string.dump` (3rd-arg signature 5.3+)
|
|
|
|
|
+- `<toclose>` metamethod pattern
|
|
|
|
|
+
|
|
|
|
|
+**Avoid (work in 5.1 but trap you later):**
|
|
|
|
|
+- Global `unpack` (use `table.unpack` if you must, or just `for i,v in ipairs`)
|
|
|
|
|
+- `setfenv` / `getfenv` (removed in 5.2)
|
|
|
|
|
+- `module(...)` (5.2 deprecates the implicit module function)
|
|
|
|
|
+
|
|
|
|
|
+**Safe to use (all in 5.1):**
|
|
|
|
|
+- `string.byte(s, i, j)` multi-return, `string.char(...)` with numeric args
|
|
|
|
|
+- `string.find` with 4th-arg `init`, `string.match`, `string.gmatch`,
|
|
|
|
|
+ `string.gsub` (string or function replacement)
|
|
|
|
|
+- `io.popen(cmd)` — always guard the result with `if f then`
|
|
|
|
|
+- `coroutine.create / resume / yield / status / wrap`
|
|
|
|
|
+- `pcall` / `xpcall` (single-arg or with custom message handler)
|
|
|
|
|
+- `math.floor / random / randomseed / min / max / huge` etc.
|
|
|
|
|
+- `pairs` / `ipairs` / `next`
|
|
|
|
|
+- Pattern escapes: `%a %A %d %D %s %S %w %W %l %u %c %C %p %P %x %X`
|
|
|
|
|
+- `table.insert(t, [pos,] v)`, `table.remove(t, [pos])`, `table.concat(t, sep)`
|
|
|
|
|
+- `debug` library (5.1+) — avoid in production; only for diagnostics
|
|
|
|
|
+
|
|
|
|
|
+**Validation gate (run before every commit that touches `.lua` files):**
|
|
|
|
|
+```bash
|
|
|
|
|
+luac5.1 -p package/src/client2server-unified.lua # must exit 0
|
|
|
|
|
+```
|
|
|
|
|
+If `luac5.1` is unavailable locally, do a manual review against the
|
|
|
|
|
+forbidden-list above. CI on the router will surface real syntax errors
|
|
|
|
|
+at agent startup, but those are silent and look like a dead daemon.
|
|
|
|
|
+
|
|
|
|
|
+**Real-world example of a bug this rule would have caught:**
|
|
|
|
|
+Commit `466fddc` ("Print at start", 5 Jun 2026) introduced a literal
|
|
|
|
|
+newline inside a Lua string literal:
|
|
|
|
|
+```lua
|
|
|
|
|
+print("START
|
|
|
|
|
+")--[[
|
|
|
|
|
+```
|
|
|
|
|
+That `LF` should have been the two-character escape `\n`. The result
|
|
|
|
|
+was an unparseable file — the Lua agent was dead on every router for
|
|
|
|
|
+~5 days before commit `ff7bf22` fixed it. **Do not let this happen
|
|
|
|
|
+again.** A single `luac5.1 -p` before commit would have caught it.
|
|
|
|
|
+
|
|
|
## Stack
|
|
## Stack
|
|
|
| Layer | Tech |
|
|
| Layer | Tech |
|
|
|
|-------|------|
|
|
|-------|------|
|