@moikapy/lich 0.8.0 → 0.9.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.
Files changed (35) hide show
  1. package/CHANGELOG.md +49 -1
  2. package/README.md +38 -19
  3. package/dist/{chunk-QOTECFCN.js → chunk-4N3S6ACI.js} +2 -2
  4. package/dist/{chunk-EDRUZF22.js → chunk-KOEZQUIX.js} +1207 -512
  5. package/dist/chunk-KOEZQUIX.js.map +1 -0
  6. package/dist/{chunk-W6JXZBUE.js → chunk-P2YEHNM4.js} +2 -2
  7. package/dist/chunk-P2YEHNM4.js.map +1 -0
  8. package/dist/{chunk-VKEOHUCB.js → chunk-TYRKVBWQ.js} +26 -8
  9. package/dist/chunk-TYRKVBWQ.js.map +1 -0
  10. package/dist/cli.js +82 -44
  11. package/dist/cli.js.map +1 -1
  12. package/dist/{gateway-WU5G4ODO.js → gateway-OSB7254F.js} +209 -47
  13. package/dist/gateway-OSB7254F.js.map +1 -0
  14. package/dist/index.d.ts +105 -60
  15. package/dist/index.js +12 -5
  16. package/dist/{store-COOLBAHB.js → store-YYLEB7JG.js} +2 -2
  17. package/dist/{tui-4BP3TI7J.js → tui-XXIU4W7K.js} +17 -5
  18. package/dist/tui-XXIU4W7K.js.map +1 -0
  19. package/docs/architecture/overview.md +2 -2
  20. package/docs/architecture/tools.md +3 -1
  21. package/docs/getting-started.md +6 -6
  22. package/docs/index.md +1 -1
  23. package/docs/user-guide/cli.md +9 -7
  24. package/docs/user-guide/games.md +2 -1
  25. package/docs/user-guide/library.md +1 -1
  26. package/docs/user-guide/redot.md +2 -2
  27. package/docs/user-guide/tui.md +2 -2
  28. package/package.json +1 -1
  29. package/dist/chunk-EDRUZF22.js.map +0 -1
  30. package/dist/chunk-VKEOHUCB.js.map +0 -1
  31. package/dist/chunk-W6JXZBUE.js.map +0 -1
  32. package/dist/gateway-WU5G4ODO.js.map +0 -1
  33. package/dist/tui-4BP3TI7J.js.map +0 -1
  34. /package/dist/{chunk-QOTECFCN.js.map → chunk-4N3S6ACI.js.map} +0 -0
  35. /package/dist/{store-COOLBAHB.js.map → store-YYLEB7JG.js.map} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,6 +1,54 @@
1
1
  # Changelog
2
2
 
3
- ## 0.8.0 (unreleased)
3
+ ## 0.9.0
4
+
5
+ - close agent should-fixes (A-7/A-8/A-10–A-13): a truncated summarizer no longer
6
+ drops recent older turns, ineffective compress attempts back off for three
7
+ turns and their usage lands on `compress_end` so transcripts stay clean,
8
+ `turn_end` usage balances, duplicate provider names are rejected at config
9
+ load with plugins and `tools_enabled` frozen, session ids use crypto-grade
10
+ entropy, and `run_conversation`, `open_session`, `read_session_messages` are
11
+ exported. session files are now created lazily, so an empty TUI launch
12
+ leaves no file.
13
+ - close provider should-fixes (P-2..P-8): truncated or unparseable tool calls
14
+ are omitted with a note instead of running half-parsed arguments, the
15
+ Anthropic `max_tokens` default rises to 16384, failover preserves the root
16
+ cause and honors server `Retry-After` capped at 30s (longer values fail over
17
+ instead of sleeping), context-overflow detection matches the real
18
+ Anthropic/Ollama error text, and temperature is omitted for reasoning models.
19
+ - harden the gateway reconnect path (G-4/G-6/G-8/G-9): Discord and Twitch
20
+ reconnects sleep on an escalating backoff that resets once a session proves
21
+ itself, fatal closes (bad auth, missing intents) stop retrying, bus eviction
22
+ no longer drops live conversation chains, webhook bodies are capped at 1 MB,
23
+ and Discord heartbeats/intents/`allowed_mentions` and the twitch outbound
24
+ IRC write path are tightened.
25
+ - close MCP should-fixes (M-2..M-9): stdio RPC ids are mapped so responses
26
+ cannot cross wires and a dead pipe rejects pending calls fail-closed, MCP
27
+ attach times out (15s) and honors the run AbortSignal, the refuse list grows
28
+ eval flags, `bun x` / package dlx, and env-var chains, redot pins by command
29
+ basename, gatekeeper dirty-tracking is per-run (AsyncLocalStorage) and fails
30
+ closed, and MCP tool metadata is bounded.
31
+ - close tools should-fixes (S-6..S-9): `terminal` and `run_tests` kill the
32
+ whole process group on timeout or abort so spawned children do not survive
33
+ the run, `grep_files` matches long lines ReDoS-safely (literal `includes`
34
+ for literal patterns, short-prefix probing for complex regexes) without
35
+ losing hit coverage, and `fetch_url`/`http_request` stream response bodies
36
+ under a hard byte ceiling instead of buffering an oversized payload.
37
+ - close CLI should-fixes (C-4/C-5/C-6): switching `--provider-kind` without
38
+ explicit overrides clears stale `base_url`/`api_key_env` while same-kind
39
+ URLs are kept, chat keeps multi-turn memory, skips blank lines, and reads
40
+ piped stdin, and `lich update` only runs `npm install -g` for real npm
41
+ global installs so project-local and bun installs are treated as local.
42
+ - harden the persona_orchestrator example (E-1): the server refuses to start
43
+ with auth off, requires a loopback Host and JSON content-type, caps the
44
+ request body, evicts idle chat chains, and trims capped history to a user
45
+ turn so tool results are not orphaned.
46
+ - sync user docs with the 0.8.0 tree — trust-model table, `LICH_DOCS_DIR`,
47
+ real model ids (#68) — and close test gaps T-3/T-4 with coverage for
48
+ abort/chained runs, compression pairing, provider finish reasons, and
49
+ gateway conversation bounds (#71).
50
+
51
+ ## 0.8.0
4
52
 
5
53
  - TUI session resume (Phase 1): `lich --resume <id|latest>` loads an existing
6
54
  JSONL transcript into the TUI history and shows a `resumed <id> (n messages)`
package/README.md CHANGED
@@ -15,7 +15,7 @@ mythology lives in display strings only.
15
15
  | --- | --- | --- |
16
16
  | **phylacteries** | JSONL session files in `.lich/sessions/` — conversations survive process death | This glossary; TUI `/sessions` listing label |
17
17
  | **vessel-hopping** | Provider failover: 429/5xx retried with backoff, then the next provider takes over | This glossary |
18
- | **the lair / wards** | `work_dir` confinement + `path_escape` guardrails for file tools. Wards do **not** apply to `terminal` or `run_tests` (shell still runs in `work_dir`; secret env names are scrubbed on spawn). | This glossary |
18
+ | **the lair / wards** | `work_dir` confinement for file tools (`resolve_safe_path` / realpath). Lexical+realpath only — not a sandbox. Wards do **not** apply to `terminal` or `run_tests` (shell still runs in `work_dir`; secret env names are scrubbed on spawn). | This glossary |
19
19
  | **lair actions** | Plugin hooks that observe or veto tool calls | This glossary |
20
20
  | **familiars** | Gateway adapters (webhook/telegram/discord/twitch) routing into one shared agent | This glossary |
21
21
  | **spells** | Builtin tools in the registry | This glossary |
@@ -47,11 +47,11 @@ npm install -g @moikapy/lich
47
47
  ```
48
48
 
49
49
  ```sh
50
- # one-shot task
51
- LICH_MODEL=gpt-4.1-mini LICH_PROVIDER_KIND=openai_compat lich "summarize this repo"
50
+ # one-shot task (use a model id your provider accepts)
51
+ LICH_MODEL=gpt-4o-mini LICH_PROVIDER_KIND=openai_compat lich "summarize this repo"
52
52
 
53
53
  # interactive chat (commands: /exit, /quit)
54
- LICH_MODEL=claude-sonnet-4 LICH_PROVIDER_KIND=anthropic lich chat
54
+ LICH_MODEL=claude-sonnet-4-20250514 LICH_PROVIDER_KIND=anthropic lich chat
55
55
 
56
56
  # local ollama (no api key needed)
57
57
  ollama pull llama3.2
@@ -132,13 +132,29 @@ the next self-commit. One gated `git_commit` per run requires
132
132
 
133
133
  | Variable | Purpose |
134
134
  | --- | --- |
135
- | `LICH_MODEL` | model name (e.g. `gpt-4.1-mini`, `claude-sonnet-4`, `llama3.2`) |
135
+ | `LICH_MODEL` | model id your provider accepts (e.g. `gpt-4o-mini`, `claude-sonnet-4-20250514`, `llama3.2`) |
136
136
  | `LICH_PROVIDER_KIND` | `openai_compat` \| `anthropic` \| `ollama` (default `openai_compat`) |
137
137
  | `LICH_BASE_URL` | provider base url (ollama default: `http://localhost:11434`) |
138
138
  | `LICH_API_KEY_ENV` | env var holding the api key (unused by ollama) |
139
139
  | `LICH_ALLOW_SELF_COMMIT` | set to `1` to allow one gated `git_commit` per run; unset is fail-closed |
140
140
  | `LICH_ALLOW_PRIVATE_URLS` | set to exactly `1` to let `fetch_url` / `http_request` reach private or loopback URLs; unset or any other value is fail-closed (blocked) |
141
141
  | `LICH_TEST_COMMAND` | command `run_tests` runs (default: `node node_modules/vitest/vitest.mjs run`) |
142
+ | `LICH_DOCS_DIR` | optional docs root for `docs_read` / `docs_search` (directory with `index.md`, or a parent containing `docs/`); else `<work_dir>/docs` or the package docs |
143
+ | `LICH_TERMINAL_TIMEOUT_MS` | injected into tool context from config `terminal_timeout_ms`; the `terminal` tool does **not** read it yet — use the tool's `timeout_ms` arg (default 60000) |
144
+
145
+ Gateway-only vars are listed under [Gateway](#gateway).
146
+
147
+ ## Trust model
148
+
149
+ Short map of who can do what:
150
+
151
+ | Surface | Trust assumption |
152
+ | --- | --- |
153
+ | **File tools** | Confined to `work_dir` via realpath checks. Not a VM/sandbox; symlinks that stay inside the tree are allowed. |
154
+ | **`terminal` / `run_tests`** | Full shell in `work_dir`. Outside the file wards. Secret-ish env names are scrubbed on spawn; still treat as high privilege. |
155
+ | **Plugins** | Load at startup from paths you list in config. In-process, same privileges as the agent. Only load code you wrote or audited. |
156
+ | **MCP servers** | Enabled servers are trusted local processes (or loopback HTTP). Basename refuse lists block common downloaders as a footgun guard, not a hard boundary — wrappers can bypass them. |
157
+ | **Gateway users** | Public platforms default-deny until allowlisted. Webhook binds loopback by default; non-loopback requires `LICH_GATEWAY_TOKEN`. Gateway tools default to a read-only subset unless you override `gateway.tools_enabled`. |
142
158
 
143
159
  ## Ollama
144
160
 
@@ -175,8 +191,9 @@ Environment variables:
175
191
 
176
192
  | Variable | Purpose |
177
193
  | --- | --- |
194
+ | `LICH_GATEWAY_HOST` | webhook bind address (default `127.0.0.1`; non-loopback requires `LICH_GATEWAY_TOKEN`) |
178
195
  | `LICH_GATEWAY_PORT` | webhook port (default `8089`) |
179
- | `LICH_GATEWAY_TOKEN` | webhook auth: requests must send header `x-lich-token` |
196
+ | `LICH_GATEWAY_TOKEN` | webhook auth: requests must send header `x-lich-token`; required for non-loopback binds |
180
197
  | `LICH_TELEGRAM_BOT_TOKEN` | telegram bot token (adapter idles without it) |
181
198
  | `LICH_DISCORD_BOT_TOKEN` | discord bot token (adapter idles without it) |
182
199
  | `LICH_DISCORD_BOT_ID` | discord bot id; mentions of `<@id>` are stripped |
@@ -210,7 +227,7 @@ lich tui
210
227
  ```
211
228
 
212
229
  Slash commands: `/help`, `/model`, `/usage`, `/clear`, `/sessions`,
213
- `/exit` (also `/quit`, `/q`). The transcript shows the newest 50 blocks.
230
+ `/resume`, `/exit` (also `/quit`, `/q`). The transcript shows the newest 50 blocks.
214
231
 
215
232
  ## Themes
216
233
 
@@ -253,18 +270,20 @@ substitutes `{chars}`; `notices.sessions` substitutes `{count}`.
253
270
  Two directions. lich connects **to** an editor MCP server (stdio local
254
271
  command, or loopback HTTP). The game connects **to** lich through the webhook
255
272
  and [`examples/game_bridge`](examples/game_bridge/README.md). Default is off.
256
- `mcp_servers` is a closed record. Names are `mcp_<server>_<tool>`. `npx`,
257
- `npm`, `bunx`, `uvx`, `curl`, `wget`, remote URLs, and shell metacharacters
258
- are refused. On Bun, stdio children are not `unref`'d, so a one-shot or
259
- other short-lived run waits for the MCP answer instead of exiting while
260
- the child is still working; `agent.close()` (which every CLI mode calls)
261
- kills the child.
262
-
263
- This source has `lich mcp list|add|enable|disable|remove` (changelog 0.7.0).
264
- From a clone: `bun src/cli.ts mcp list`. Redot is a catalog
265
- entry (`redot --headless --mcp-server`), not a fork inside lich. Godot has
266
- no official MCP server; lich does not download a community addon. See
267
- [docs/user-guide/redot.md](docs/user-guide/redot.md).
273
+ `mcp_servers` is a closed record. Names are `mcp_<server>_<tool>`. Config
274
+ validation refuses common downloader basenames (`npx`, `npm`, `bunx`,
275
+ `uvx`, `curl`, `wget`), remote URLs, and shell metacharacters in the
276
+ command a footgun guard, not a sandbox (wrappers like `bash -c` or
277
+ `env npx` are not covered). Treat enabled MCP as trusted code. On Bun,
278
+ stdio children are not `unref`'d, so a one-shot or other short-lived run
279
+ waits for the MCP answer instead of exiting while the child is still
280
+ working; `agent.close()` (which every CLI mode calls) kills the child.
281
+
282
+ `lich mcp list|add|enable|disable|remove` ships in this package (since
283
+ 0.7.0; current release **0.8.0**). From a clone: `bun src/cli.ts mcp list`.
284
+ Redot is a catalog entry (`redot --headless --mcp-server`), not a fork
285
+ inside lich. Godot has no official MCP server; lich does not download a
286
+ community addon. See [docs/user-guide/redot.md](docs/user-guide/redot.md).
268
287
 
269
288
  ## Development
270
289
 
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  logger
3
- } from "./chunk-EDRUZF22.js";
3
+ } from "./chunk-KOEZQUIX.js";
4
4
 
5
5
  // src/util/theme.ts
6
6
  import { readFileSync } from "fs";
@@ -89,4 +89,4 @@ export {
89
89
  notice_flavor,
90
90
  load_theme
91
91
  };
92
- //# sourceMappingURL=chunk-QOTECFCN.js.map
92
+ //# sourceMappingURL=chunk-4N3S6ACI.js.map