@moikapy/lich 0.7.0 → 0.8.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 (40) hide show
  1. package/CHANGELOG.md +75 -5
  2. package/README.md +38 -9
  3. package/dist/{chunk-QVJCIZIF.js → chunk-EDRUZF22.js} +763 -286
  4. package/dist/chunk-EDRUZF22.js.map +1 -0
  5. package/dist/chunk-PL6MKRKE.js +75 -0
  6. package/dist/chunk-PL6MKRKE.js.map +1 -0
  7. package/dist/{chunk-JYURFAGB.js → chunk-QOTECFCN.js} +2 -2
  8. package/dist/chunk-VKEOHUCB.js +86 -0
  9. package/dist/chunk-VKEOHUCB.js.map +1 -0
  10. package/dist/{chunk-SAEB3QL3.js → chunk-W6JXZBUE.js} +2 -2
  11. package/dist/cli.d.ts +19 -1
  12. package/dist/cli.js +53 -11
  13. package/dist/cli.js.map +1 -1
  14. package/dist/{gateway-5BG3YCZF.js → gateway-WU5G4ODO.js} +109 -49
  15. package/dist/gateway-WU5G4ODO.js.map +1 -0
  16. package/dist/index.d.ts +46 -3
  17. package/dist/index.js +3 -2
  18. package/dist/resolve-H22TOVB5.js +7 -0
  19. package/dist/resolve-H22TOVB5.js.map +1 -0
  20. package/dist/store-COOLBAHB.js +9 -0
  21. package/dist/store-COOLBAHB.js.map +1 -0
  22. package/dist/{tui-L6RABP2J.js → tui-4BP3TI7J.js} +224 -30
  23. package/dist/tui-4BP3TI7J.js.map +1 -0
  24. package/docs/architecture/agent-loop.md +28 -9
  25. package/docs/architecture/overview.md +10 -10
  26. package/docs/architecture/tools.md +30 -3
  27. package/docs/getting-started.md +3 -3
  28. package/docs/index.md +1 -1
  29. package/docs/user-guide/cli.md +13 -5
  30. package/docs/user-guide/games.md +3 -3
  31. package/docs/user-guide/gateway.md +70 -16
  32. package/docs/user-guide/library.md +6 -3
  33. package/docs/user-guide/redot.md +2 -2
  34. package/docs/user-guide/tui.md +3 -2
  35. package/package.json +1 -1
  36. package/dist/chunk-QVJCIZIF.js.map +0 -1
  37. package/dist/gateway-5BG3YCZF.js.map +0 -1
  38. package/dist/tui-L6RABP2J.js.map +0 -1
  39. /package/dist/{chunk-JYURFAGB.js.map → chunk-QOTECFCN.js.map} +0 -0
  40. /package/dist/{chunk-SAEB3QL3.js.map → chunk-W6JXZBUE.js.map} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,6 +1,79 @@
1
1
  # Changelog
2
2
 
3
- ## 0.7.0 (unreleased)
3
+ ## 0.8.0 (unreleased)
4
+
5
+ - TUI session resume (Phase 1): `lich --resume <id|latest>` loads an existing
6
+ JSONL transcript into the TUI history and shows a `resumed <id> (n messages)`
7
+ banner. One-shot, chat, and gateway reject `--resume`.
8
+ - Incremental session persistence (Phase 2): Agent appends transcript records
9
+ as the loop emits (`llm_end`, `tool_call_end`, `budget_exhausted`,
10
+ `compress_end`) instead of a post-run bulk write. TUI opens one
11
+ `SessionHandle` per launch and passes it into every `agent.run`; one-shot,
12
+ chat, and gateway keep per-run files. Append failures warn and never fail
13
+ the run.
14
+ - TUI `/resume <id|latest>` (Phase 3): same resolve + load path as `--resume`,
15
+ resets the on-screen transcript with a meta notice, seeds agent history for
16
+ the next turn, and updates the resume banner. Does not change persistence.
17
+
18
+ ## 0.7.1
19
+
20
+ - close agent-core review must-fixes A-1–A-4: multi-turn runs stop
21
+ duplicating history, tool pairs survive compression and gateway history
22
+ caps, and a mid-call abort becomes `stopped_reason: aborted` with the
23
+ abort signal reaching in-flight tools.
24
+ - harden the webhook gateway (G-1/G-2/G-3/G-5): binds to loopback by
25
+ default and requires a token when exposed, defaults public platforms
26
+ (telegram/discord/twitch) to deny with a configurable allowlist plus a
27
+ reduced safe toolset, catches telegram/discord reply send failures
28
+ instead of crashing the run, and forces `platform=webhook` on the HTTP
29
+ adapter.
30
+ - close MCP exit (M-1), empty Anthropic text, and env provider fallback:
31
+ one-shot/chat/TUI/gateway runs call `Agent.close()` so stdio MCP
32
+ sessions release; node children are still `unref`'d so the event loop
33
+ can drain (bun keeps the child attached — see below). an empty
34
+ Anthropic text block no longer 400s the session permanently, and
35
+ mcp-only project configs no longer shadow `LICH_MODEL` / env providers.
36
+ - close tools must-fixes S-1–S-5: file writes/edits resolve realpath so
37
+ symlink escapes are confined, `fetch_url`/`http_request` block private
38
+ and loopback URLs, `.lich/config.json` and `.env` are forbidden write
39
+ targets, terminal child env is scrubbed of provider secrets, and
40
+ dash-leading `run_tests` filters are rejected so they cannot open the
41
+ commit gate. `http_request` also strips IPv6 brackets before SSRF IP
42
+ classification so `[::1]` literals are not skipped, and asserts headers
43
+ through `Headers` after the `safe_fetch` merge.
44
+ - isolate usage per run (A-5) and memoize MCP attach (A-6): concurrent
45
+ `Agent.run` calls no longer mix `usage_total`, and attach races can
46
+ neither skip nor permanently fail.
47
+ - TUI: ignore message submit while a run is in flight (U-1), and walk the
48
+ newest-first recall ring so Up moves to older entries instead of
49
+ clamping on the newest (U-2).
50
+ - pin outbound HTTP: `fetch_url` and `http_request` keep the https
51
+ hostname for TLS/SNI and the `Host` header while `safe_fetch` pins the
52
+ connect to a vetted public IP through a custom DNS `lookup`, and
53
+ re-validates every redirect hop. the operator opt-out is exact:
54
+ `LICH_ALLOW_PRIVATE_URLS=1`; unset or any other value is fail-closed
55
+ (private/loopback URLs blocked).
56
+ - harden `grep_files`: the directory walk skips symbolic links (same
57
+ skip path as `SKIP_DIRS`), and every candidate read runs
58
+ `assert_file_tool_access`, so `.lich/config.json` is denied with
59
+ `forbidden_path: .lich/config.json`.
60
+ - twitch gateway: `PRIVMSG` matching is anchored (`^:... PRIVMSG #...
61
+ :...$` after the optional tags strip), so `USERNOTICE` and
62
+ `WHISPER` lines are not chat and cannot spoof the allowlist.
63
+ - bun stdio MCP children are no longer `unref`'d: one-shot and
64
+ short-lived runs wait for the MCP answer instead of letting the child
65
+ detach and exit early.
66
+ - add CI (tsc + vitest on Node 20/22), sync the 0.7.0 user docs with this
67
+ tree, and make `edit_file` treat `$` sequences literally while allowing
68
+ an empty `new_string` (#57).
69
+ - sync docs/architecture with the outbound-HTTP pin, grep hardening,
70
+ twitch anchor, and bun MCP exit changes (#61).
71
+ - add a manual Release workflow: Actions → Release → Run workflow (from
72
+ `main`) with a `patch|minor|major` bump runs `bun release`, then
73
+ publishes the packed tarball to npm with `NPM_TOKEN`. maintainer
74
+ plumbing, not a runtime change (#62).
75
+
76
+ ## 0.7.0
4
77
 
5
78
  - add a general MCP client. `mcp_servers` is a closed record of named
6
79
  stdio or loopback-http entries, default off. tool names are
@@ -14,10 +87,7 @@
14
87
  add uses the catalog or `--command`/`--url`, stays disabled, and
15
88
  updates `.lich/config.json` through the existing writer without
16
89
  dropping other keys.
17
- - sync user docs with this tree. the published package is 0.6.0
18
- (`lich --version` reads package.json). MCP commands are not in that
19
- package. CLI, config, plugin load, and sidebar links match the code.
20
- 0.7.0 is not released.
90
+ - sync user docs with this tree. MCP is included in the 0.7.0 package.
21
91
 
22
92
  ## 0.6.0
23
93
 
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 | 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 |
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 |
@@ -101,7 +101,7 @@ snake_case args and are registered under the `builtin` toolset.
101
101
  | `edit_file` | Replace a unique string in a file, with an optional replace-all. |
102
102
  | `list_dir` | List a directory tree iteratively (dirs first, file sizes). |
103
103
  | `terminal` | Run a shell command via `bash -lc` and capture output plus exit code. |
104
- | `grep_files` | Regex search across files, skipping node_modules/.git/dist and binaries. |
104
+ | `grep_files` | Regex search across files, skipping node_modules/.git/dist, symlinks, and binaries; `.lich/config.json` is denied. |
105
105
  | `fetch_url` | GET an http(s) URL and return the body text with a status header. |
106
106
  | `web_search` | Web search via DuckDuckGo's HTML endpoint (no api key). |
107
107
  | `http_request` | Generic HTTP calls (method/headers/body) for REST-ish APIs. |
@@ -137,6 +137,7 @@ the next self-commit. One gated `git_commit` per run requires
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
+ | `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) |
140
141
  | `LICH_TEST_COMMAND` | command `run_tests` runs (default: `node node_modules/vitest/vitest.mjs run`) |
141
142
 
142
143
  ## Ollama
@@ -254,12 +255,13 @@ command, or loopback HTTP). The game connects **to** lich through the webhook
254
255
  and [`examples/game_bridge`](examples/game_bridge/README.md). Default is off.
255
256
  `mcp_servers` is a closed record. Names are `mcp_<server>_<tool>`. `npx`,
256
257
  `npm`, `bunx`, `uvx`, `curl`, `wget`, remote URLs, and shell metacharacters
257
- are refused.
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.
258
262
 
259
- This source has `lich mcp list|add|enable|disable|remove` (changelog 0.7.0,
260
- unreleased). The published npm package is 0.6.0 and does not include those
261
- commands; `lich --version` still prints `0.6.0` because it reads
262
- `package.json`. From a clone: `bun src/cli.ts mcp list`. Redot is a catalog
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
263
265
  entry (`redot --headless --mcp-server`), not a fork inside lich. Godot has
264
266
  no official MCP server; lich does not download a community addon. See
265
267
  [docs/user-guide/redot.md](docs/user-guide/redot.md).
@@ -277,15 +279,42 @@ packages in /tmp and break dependency resolution.
277
279
 
278
280
  ## Releasing
279
281
 
282
+ Update `CHANGELOG.md` first so the new version notes match what you ship
283
+ (GitHub release labels / automated notes are a follow-up).
284
+
285
+ ### GitHub Actions (preferred)
286
+
287
+ Requires the `NPM_TOKEN` repository secret (npm **automation** or
288
+ granular token with publish access to `@moikapy/lich` — not a classic
289
+ token that needs interactive OTP, which `npm publish` in CI cannot
290
+ answer). It is typically already configured; if not, add it under
291
+ **Settings → Secrets and variables → Actions → New repository secret**.
292
+ 1. Ensure Actions can push commits/tags to `main` (repo
293
+ **Settings → Actions → General → Workflow permissions**: read and
294
+ write; if branch protection blocks `GITHUB_TOKEN`, allow GitHub Actions
295
+ to bypass or push to `main`).
296
+ 2. Run: **Actions → Release → Run workflow** (from `main` only) → choose
297
+ `bump` (`patch` / `minor` / `major`, default `patch`).
298
+
299
+ The workflow runs `bun release <bump>` (typecheck, test, bump, build,
300
+ pack + audit, commit, tag, push — no force-push), then
301
+ `npm publish test/.tmp/lich-<version>.tgz --access public` with
302
+ `NODE_AUTH_TOKEN` from `NPM_TOKEN`. It refuses to publish if the pack
303
+ file is missing. Permissions include `id-token: write` for a future npm
304
+ OIDC trusted-publishing switch; today the token path is what works.
305
+
306
+ ### Local
307
+
280
308
  ```sh
281
309
  bun release patch # or minor | major
310
+ npm publish test/.tmp/lich-<version>.tgz
282
311
  ```
283
312
 
284
313
  Fails closed on a dirty tree, a non-main branch, a typecheck error, or a
285
314
  test failure; bumps via `npm version`, builds, and packs + audits
286
315
  `test/.tmp/lich-<version>.tgz` (SHA-512 + scope verification) before
287
- committing, tagging `v<version>`, and pushing main. Publishing stays manual
288
- (`npm publish test/.tmp/lich-<version>.tgz`) so npm can prompt for the OTP.
316
+ committing, tagging `v<version>`, and pushing main. Local publish stays
317
+ interactive so npm can prompt for OTP.
289
318
 
290
319
  ## License
291
320