Read large items in parts with item_get offset and take #305

openReady to startCreated by Claude Code (User hu_yMavF3p1) • Unassigned • Normal priority

Description

See #302. item_get returns whole items today; a page can hold 100,000 characters.

Contract

  • offset and take in characters (not bytes, which split UTF-8 characters), take with a high default such as 20,000 so ordinary items still arrive in one call.
  • Applies to the long text field of the item: page content, memory detail, task description.
  • The server cuts at the last line break before the limit, so table rows and code lines stay whole, and returns contentLength, offset, returned and nextOffset (null when complete). The caller passes nextOffset back and never computes it.
  • A partial response is marked complete: false.
  • Outline: a partial page also returns its headings with their offsets (## Deploy @ 14200), so an agent can jump to the section it needs.
  • Stable revision: follow-up reads pass the revisionId of the first read and receive that revision, so parts of different revisions never mix.

item_history

item_history still returns the full text of every revision of a memory, page or the instructions; #303 left it unchanged because no tool reads a single revision. Once item_get reads a given revisionId, item_history returns revision metadata only (id, base, title, author, time, status) and the text comes from item_get.

Guard against partial read then full write

page_store replaces content completely; an agent that read only the first part and writes the page back deletes the rest.

  • Tool descriptions and system guide: replace content only after reading it completely.
  • page_store refuses new content that is much shorter than the current revision unless replaceAll: true is passed. Define the threshold; apply the same to memory detail in memory_store.

Acceptance

  • Reading a large page in parts and joining them yields exactly the stored content, including multi-byte characters and CRLF.
  • A read with a stale revisionId after an edit returns the requested revision or a clear error, never mixed text.
  • A shortened write without replaceAll is refused with a message naming the guard; with it, it succeeds.
  • item_history entries carry no revision text.
  • The outline and lengths reveal nothing beyond what the caller may read.
Connection interrupted or session ended. Reload

Rejoining the server...

Rejoin failed... trying again in seconds.

Failed to rejoin.
Please retry or reload the page.

The session has been paused by the server.

Failed to resume the session.
Please retry or reload the page.