Repository navigation
perf(memo): memo lists past 500 rows, first page with and without sources - #344
Merged
Merged
Conversation
…rces WireCat Desktop's Memory page could read only the newest 500 memories, facts or actions (NEED-2497). With cli-core's offset (#2811) and memo's --page, this run times the first and a later page on a synthetic store of 2000 rows of each, and what --brief and --json=<fields> save. A later page costs the same as the first; Node start is most of the time. --json=<fields> halves the bytes but saves no time, and actions list --brief already drops the sources, so no new flag. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
leemour
added a commit
to WireCatLabs/cli-memo
that referenced
this pull request
Nov 10, 2026
… codes per request; cli-core 0.627.0 (#788) ## Task WireCat Desktop's Memory page cannot read past 500 memories, facts or actions of a kind. The owner ruled that these lists page like `relationships list`, with `--page` (NEED-2497 A). Also: a command server that answers several requests at once must not give one request's exit code to another (cli-core #2812). ## Why - `memories list`, `facts list`, `actions list` and `agents list` took only `--limit`, up to 500. cli-core 0.627.0 adds an `offset` to their store lists ([cli-core #2811](WireCatLabs/cli-core#2811)). - `sync`, `doctor`, `digest run` and `digest backfill` wrote `process.exitCode` directly. Under `commands --serve`, up to 8 requests run at once, and Node has one `process.exitCode`, so the code went to the request that ended next. ## What - **`--page <n>` on the four lists**, as `relationships list` has it. - The offset is `(page - 1)` times the limit after the 500 clamp. - The answer keeps `page.next_page`, and its `page.next` step repeats `--limit` and the query. - At the 500 cap the list reads one row past the page, so `has_more` is exact. It used to be `true` for any full page of 500. - `actions list` decides `has_more` on the store's rows before the group lock filters them, so a filtered page does not end the paging early. - **No new brief flag.** `actions list --brief` already leaves out the sources with their excerpts. Memories and facts carry only evidence references. `--json=<fields>` trims bytes but not time (timings below). - **Exit codes per request.** `createProgram` takes `startCli`'s `entry.setExitCode`, keeps it on the root command (`src/exit-code.ts`), and the four commands set their code through it. A program built without it, as in tests, still sets `process.exitCode`. - **cli-core 0.625.0 → 0.627.0.** This brings cli-core's shared `models ai` command. Its 7 command-lint findings belong to cli-core: the verbs `off` and `forget`, the resource `ai`, three options with no role in the vocabulary, and an example with three arguments. They go to `lint/baseline` here. - Regenerated `docs/commands.md` and `docs/dev/test-matrix.md`. The changelog fragment is `changes/feat-memory-lists-paging.md`. ## Testing - `free -g` first, then the full suite on one worker: `pnpm exec vitest run --maxWorkers=1` gives 136 files and 1368 tests passed. - New tests: - `src/memories/paging.test.ts`: 520 memories and facts across the 500 boundary, each row once and newest first, and page 2 of actions and agents. - `src/page.test.ts`: an over-large `--limit`, the exact `has_more` at the cap, and a filter that drops rows. - `src/exit-code.test.ts`: the code goes to the run's own setter. - `typecheck`, `generate`, `test:matrix:check`, `docs:check`, `lint` and `lint:commands` pass. - Checked by hand on a throwaway store (`HOME`, XDG folders and `MESSAGING_STORE` in a temp folder, `DBUS_SESSION_BUS_ADDRESS=disabled:`), with the built `dist/bin/memo.js`: - `memo commands --serve` prints `{"ready":true,"protocol":1,"version":"0.131.75","concurrent":8}`. - `memo people list kind:stranger --json` answers a list, empty here, with `page` and a `people.kinds` step. - `memo memories list --limit 2 --page 1000 --json` gives the last two of 2000 memories, with `has_more: false`. First-page timings on 2000 synthetic rows of each kind, as medians of 9 runs. The full page and the scripts are in [cli-testing #344](WireCatLabs/cli-testing#344) (`performance/memo/lists-paging`). | command | time | answer | |---|---|---| | `memories list --limit 1` (start, the floor) | 346 ms | 1 KB | | `memories list --limit 500` | 383 ms | 241 KB | | `memories list --limit 500 --page 4` | 316 ms | 239 KB | | `actions list --limit 500` | 657 ms | 965 KB | | `actions list --limit 500 --brief` | 622 ms | 766 KB | A later page costs the same as the first. ## For WireCat Desktop In `src-tauri/src/memory.rs`, `list()`, per kind: 1. Loop `memo <noun> list --limit 500 --page N --json --no-record`, with `--brief` for actions, while `page.has_more` is true. 2. Remove duplicates by `ref`. 3. Stop after about 40 pages, and set `more` only when that limit stopped the loop. The test fake always answers `has_more: true` for facts. 4. An older memo refuses `--page`: retry without it through `unsupported(&e)`. Keep `agents list --limit 30` as it is. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Task
Publish the timings behind memo's
--pageonmemories,facts,actionsandagents list(NEED-2497) with the scripts that produced them, as the rule for results asks.Why
The numbers were only in the body of cli-core #2811, and the scripts sat in a session folder that is deleted with the session.
What
performance/memo/lists-paging/README.md: why it was run, setup, the command, results, what it showed, what was not measured.seed.mjsfills a throwaway store with 2000 synthetic memories, facts and evidence-findings batches.bench.shtimes each command as a whole process. Both refuse the real store orHOME.performance/memo/README.mdarea, linked fromperformance/README.md.Headline: a later page costs the same as the first, at about 300 to 650 ms, mostly Node start.
--json=<fields>halves the bytes but saves no time.actions list --briefalready drops the sources, so memo needs no new flag.Testing
biome check performance/memo,markdownlint-cli2andcspellon the new pages, andpnpm docs:checkpass. The scripts ran as published, apart from the guards and formatting added here.🤖 Generated with Claude Code