Build script now copies src/viewer/index.html to dist/viewer/.
Also added more candidate paths for index.html resolution so
the viewer works from dist/ (npx), src/ (tsx dev), and repo root.
Replace numbered steps with a single copy-pasteable instruction block
for Claude Code. The agent reads it and handles: engine startup, plugin
install, hook registration, and verification.
Other agents consolidated into a clean table (Cursor, Gemini CLI,
OpenCode, Claude Desktop, SkillKit, REST API) with inline config.
- README: add `text` language tag to fenced code blocks (MD040)
- cli.ts: sessions endpoint returns {sessions: [...]}, not a raw array
- viewer: token budget from URL param instead of hardcoded 2000
- viewer: applyTheme takes persist param, auto-detection doesn't save to
localStorage (prevents OS preference from being overridden on first load)
Address CodeRabbit nitpick on #105: split the result-building loop into
two phases. First filter sequentially (benefits from the per-call
session cache), then batch the kv.get(observations) calls through
Promise.all instead of awaiting them one at a time.
Address CodeRabbit review on #105:
- mem::search now validates query (non-empty string), limit
(positive integer, capped at MAX_LIMIT=100), project and cwd
(must be strings if provided). Throws on invalid input instead
of silently coercing.
- Renamed local 'limit' to 'effectiveLimit' to avoid shadowing.
- ctx.logger no longer emits raw cwd/project (host paths) — logs
only hasProjectFilter/hasCwdFilter booleans.
- api::search whitelists request body fields, returns 400 on
malformed input, and constructs an explicit payload for
sdk.trigger instead of forwarding req.body.
Closes#104
The /agentmemory/search HTTP endpoint and the underlying mem::search
function previously accepted only { query, limit }, returning hits
across all projects on the host. Sessions are already created with
{ project, cwd } via session::start, so this just exposes that scope
on search.
- mem::search now accepts optional project and cwd. When set, results
are filtered by looking up each hit's owning Session.
- To keep the post-filter from starving the result set, the index
fetch is over-fetched (max(limit*10, 100)) when filtering, then
trimmed to limit after filter.
- Session lookups are cached per call.
- api::search forwards the new params; fully backward compatible.
- Add `MinimaxProvider` (`src/providers/minimax.ts`) that calls MiniMax's
Anthropic-compatible API via raw `fetch` instead of the Anthropic SDK.
The SDK auto-injects `x-stainless-*` headers that MiniMax rejects with 403;
using `fetch` directly avoids this entirely.
- Fix `AnthropicProvider` constructor to accept an optional `baseURL` and
forward it to `new Anthropic({ apiKey, baseURL })`. Previously the provider
always connected to `api.anthropic.com` even when `ANTHROPIC_BASE_URL` was
set in `.env`, because `getMergedEnv()` returns a plain JS object that the
Anthropic SDK never sees.
- `detectProvider()` in `config.ts`:
- Checks `MINIMAX_API_KEY` first and returns `provider: "minimax"`.
- Propagates `ANTHROPIC_BASE_URL` as `baseURL` in the Anthropic config.
- Update `ProviderConfig` in `types.ts` to include optional `baseURL` field.
- Update `ProviderType` union to include `"minimax"`.
- Update `VALID_PROVIDERS` set in `config.ts` to include `"minimax"`.
- logo.svg: full logo mark with memory tiers + retrieval spark
- icon.svg: compact 64x64 app icon variant
- banner.svg: README banner with tagline, stats, supported agents
- README: switch from banner.png to banner.svg
Design: 4 memory tiers (cold→hot) with orange accent (#FF6B35),
retrieval lines converging to a spark node, fading dots for decay.
Rewrite README opening to focus on what the user gets ("your agent
remembers everything, no more re-explaining") instead of internal
architecture ("triple-stream retrieval, 4-tier consolidation").
Run agentmemory on LongMemEval-S (ICLR 2025, 500 questions) using the
same dataset and metric (recall_any@5) as MemPalace for direct comparison.
Results:
- BM25+Vector hybrid: 95.2% R@5, 98.6% R@10, 87.9% NDCG@10
- BM25-only: 86.2% R@5, 94.6% R@10, 73.0% NDCG@10
- MemPalace raw vector: 96.6% R@5 (1.4pp gap, same embedding model)
Clearly labels these as retrieval recall, not end-to-end QA accuracy.
- author: change from string to object {name, url}
- hooks: remove field (auto-loaded by convention from hooks/hooks.json)
- skills: change from directory string to explicit file path array
- Update zod from ^3.23.0 to ^4.0.0 (claude-agent-sdk peer dep conflict)
- Mount iii-config.yaml in docker-compose.yml (missing /app/config.yaml)
- Change host binding from 127.0.0.1 to 0.0.0.0 for Docker compatibility
- Switch npm start from index.mjs to cli.mjs (auto-starts iii-engine)
- Fix CLI health check to detect engine via any HTTP response, not just worker route
- Handle EADDRINUSE on viewer port gracefully instead of crashing
- Fix README step numbering and version in health example
Actions tab:
- List view with status badges, priority, tags
- Status filter dropdown (pending/active/done/blocked/cancelled)
- Search across title, description, tags
- Frontier actions highlighted with lightning bolt
- Parallel fetch of actions + frontier data
Crystals tab:
- Card layout with narrative, key outcomes, lessons
- Files affected and source action IDs
- Reuses dashboard crystals data to avoid duplicate fetch
- Search across narrative, outcomes, lessons
Review fixes applied:
- Declared frontier: [] in state init
- Sort on copy (items.slice().sort) not in-place
- Escaped tags with .map(esc)
- Guarded c.keyOutcomes/c.lessons/c.narrative with || [] in search
- Reuse dashboard crystals to avoid duplicate API call
614 tests passing