Adding memory to gjc (gajae-code)

it can reopen one session; nothing reads the others back

gajae-code — gjc on the command line — writes a JSONL session log under ~/.gjc/agent/sessions/, honouring $GJC_CODING_AGENT_DIR, and can reopen one. A new session reads none of the others, and nothing in it knows about the Claude Code session in the same repo yesterday. This page is about adding that.

What gjc already has

The session logs, a way back into one, and its own customization surfaces: mcp.json in the agent directory for servers, native skills at skills/<name>/SKILL.md, and slash commands. Claude's and Codex's skill directories are import candidates in gjc rather than directories it loads, so a skill written there would be one no session reads.

Adding recall

deja install gjc-auto

Four files, all reversible with deja uninstall gjc-auto:

  • The MCP server in ~/.gjc/agent/mcp.json — the path out of gjc's own surface table, not assumed from its pi lineage.
  • The skill at ~/.gjc/agent/skills/deja-history/SKILL.md, which is the directory gjc actually loads. Its own gjc customize doctor is where to check that: a skill under ~/.agents/skills is reported as source-ignored, because gjc loads skills from .gjc locations only.
  • The slash command at ~/.gjc/agent/commands/deja.md, so /deja <question> works whether or not the model decides to look.
  • The extension at ~/.gjc/agent/extensions/deja.ts, which is where recall arrives without being asked: gjc's extension loader is pi's, discovering modules in the agent directory's extensions/ and handing them session_start, before_agent_start, context, tool_result and session_compact. deja install gjc without the suffix writes the first three files and leaves this one out.

The directory hooks stay unwired, and the reason is their shape rather than their path. User-scope hooks resolve to <agent dir>/hooks/pre and …/post — settled against resolveScopePaths in the loader, because docs/hooks.md's ~/.gjc/hooks is stale — and a directory hook is a TypeScript module whose only documented return is {block, reason}: allow the call or refuse it, with no channel for adding context. The extension has that channel, so that is where the recall goes.

What arrives

At the front of the session, a short digest of what this machine has done on the project — decisions, the commands that worked, the errors that recurred. On a prompt your own history already answers, that answer. When a command fails, what followed that same error here before. Silence is the common case, and an injection is capped at 1,536 bytes per prompt and about 4 KB per tool call. Beyond that the tool is in front of the model — search past sessions, read one in full, see a file's history — and /deja <question> asks directly. What memory costs has the measured comparison.

The part that is not about gajae-code

The index covers every agent's transcripts on the machine — thirty-four of them, each in its own format — so a fix found in Claude Code answers a question asked in gajae-code, including sessions from before any of this was installed. A transcript a client later deletes stays searchable; only deja forget drops one on purpose. Nothing here writes memories, so there is nothing to hallucinate into your history; indexing and search are local, and credentials are stripped as the index is built (privacy).

Getting started · Switching between agents · The gajae-code session format

Found this useful? Star deja-vu on GitHub.