# Augment Features

Augment is a local RAG memory system for coding agents.

## Memory Folder

- The memory folder is a normal directory.
- Only one memory root is configured per local system.
- Memory file paths are relative to this root.

## Memories

- Memories are text files in the memory folder.
- Files are markdown with YAML frontmatter.
- Canonical organization:

```txt
org/repo/kind/name.md
.generic/kind/name.md
```

- Supported kinds:
  - `ISSUE`
  - `ARCH`
  - `TODO`
  - `SPEC`
  - `WORK`

Memory files are the canonical source of truth. Numeric memory IDs are local
database IDs only and are not written to memory files. Relative paths are the
durable cross-system identity.

Example:

```md
---
kind: ARCH
project: fingerskier/augment
name: search-contract
tags: [mcp, search, ranking]
links:
  - to: fingerskier/augment/SPEC/local-daemon.md
    type: RELATED
created_at: 2026-06-29T00:00:00Z
updated_at: 2026-06-29T00:00:00Z
---

Body text.
```

Generic memories are ordinary memory files of any supported kind under the
reserved `.generic/` directory; glean output is restricted to durable SPEC or
ARCH records. The path is authoritative: `.generic/SPEC/retries.md` is generic
even if externally edited frontmatter says otherwise. Normal CRUD and an
explicit `project_name: ".generic"` work, but project inference never selects the
reserved pseudo-project and routine current-project search does not boost it as
an exact project match. Generic memories still participate in normal global
search alongside current- and foreign-project memories.

**User-authored generic store** (skill `augment-generic`, Pi `/augment-generic`)
imports portable knowledge (knowledgebases, domain notes) into `.generic/` via
ordinary `upsert` — SPEC/ARCH only, dedup + batch approval for large imports.
That path is separate from **decoction** (cross-project recurrence with
`derived_from` spanning ≥4 projects).

## Database

- A shared local daemon watches memory files and maintains a rebuildable libsql
  index.
- The database includes metadata, body text, embeddings, gzip density score, and
  derived link rows.
- `Xenova/bge-small-en-v1.5` via `@huggingface/transformers` provides 384D
  embeddings. The model revision is recorded as a tripwire constant
  (`PINNED_MODEL_REVISION`) for reproducibility.
- Indexing is incremental: an external edit reindexes only the changed file, a
  full rebuild skips unchanged files by mtime, and the daemon's own writes are
  indexed inline (no watcher round-trip).
- The database file is rebuildable and should not be synced as canonical state.

Tables:

- `projects` — `id`, `name`, `org`, `repo`, `source`, `created_at`, `updated_at`.
- `memories` — `id`, `project_id`, `kind`, `name`, `relative_path`,
  `content_hash`, `frontmatter_hash`, `size`, `density`, `mtime`, `tags_json`,
  `links_json`, `body`, `created_at`, `updated_at`.
- `memory_embeddings` — `memory_id`, `model_id`, `model_version`, `dimensions`,
  `vector_json`, `embedded_hash`, `embedded_at`.
- `links` — `id`, `from_memory_id`, `to_memory_id`, `type`, `created_at`
  (unique on `from` + `to` + `type`).

Links are written to the source memory's frontmatter using target relative paths.
The daemon rebuilds local `links` rows from those declarations. A mutation
(`upsert`/`link`/`unlink`) repairs only the touched memory's link subgraph, so
link IDs survive *unrelated* mutations within a daemon run — but the touched
memory's own outbound link IDs are reassigned each time, and all IDs churn on a
full index rebuild. Relative paths remain the durable identity.

## Daemon

- `augment-daemon` is shared by all local MCP servers for one memory root.
- The daemon owns file watching, embedding, and database writes.
- It exposes a localhost HTTP control endpoint.
- It binds to `127.0.0.1`, uses a dynamic port by default, writes a discovery
  file, and serves all routes without auth (loopback-only; no token required).
- It starts serving immediately and builds the initial index in the background
  (a cold corpus no longer blocks hooks or clients on the port);
  `GET /index/status` reports `{ ok, ready, error? }`.
- Besides memory/link CRUD it serves `/health`, `/index/rebuild`, and the
  dashboard UI.
- Memories can be deleted via the dashboard or `DELETE /memories/:id` (the file
  and DB row are removed and inbound frontmatter links in other memories are
  scrubbed). Ordinary delete is deliberately **not** exposed as an MCP tool;
  `decoction_cleanup` is the narrowly scoped, explicitly approved exception.

## Git auto-commit

When the memory root is itself a git repository, the daemon auto-commits
augment's own writes so the corpus carries its own version history — no manual
snapshotting required.

- **Enabled by default**; disable with `AUGMENT_GIT_AUTOCOMMIT=0` (also `false`,
  `no`, `off`).
- **Daemon-side and debounced.** Only augment's own mutations (upsert, delete,
  link, unlink) schedule a commit; a burst of writes coalesces into one snapshot
  commit. External/editor/Dropbox edits are *not* committed.
- **Markdown only.** It stages `*.md` (`git add -A -- '*.md'`), so a nested state
  dir or unrelated files are never swept in, and every memory mutation — including
  deletes and link scrubs — is captured.
- **Root-repo only.** It engages only when the memory root is the git worktree
  root, never when it merely sits inside a larger project repo.
- **Never pushes, always fails open.** Commits stay local; any git failure is
  logged once and swallowed so a snapshot can never break a write. A fresh
  `git init` with no configured identity still commits (a fallback
  `Augment <augment@localhost>` identity is used only when none is set).
- The check runs **once at daemon startup**, so enabling the flag or `git init`-ing
  the memory root takes effect on the next daemon restart.

## Dashboard

A daemon-served single-page web UI for browsing and editing memories as a graph:

- Project graph drills into a per-project memory subgraph (nodes colored by
  kind, edges labeled by link type).
- Projects view uses global semantic search; an open project uses debounced,
  project-local fuzzy search over memory names, tags, and paths with graph
  spotlighting for matches and their immediate neighbors.
- Memory and link create/edit/delete reconcile in place while preserving graph
  positions, viewport, and selection where possible.
- Fit, Relayout, and manual Refresh controls; no polling or push subscription.
- Launched via `augment dashboard [--no-open]`; loopback-only; honors
  `AUGMENT_DAEMON_PORT`.
- Fully self-contained assets (Cytoscape bundled from `node_modules`; no CDN).

## CLI

Run without a clone via `npx -y @fingerskier/augment <command>`:

- `status` — print the resolved config (default command; `config` is an alias).
- `install <codex|claude|all>` — wire agent integrations (see
  [Agent Integration Installer](#agent-integration-installer)).
- `dashboard [--no-open]` — start the daemon and open the web UI.
- `recall "<query>" [--project <org/repo>] [--cwd <dir>] [--limit N]
  [--max-chars N] [--min-score X]` — print the same context-injection text the
  hooks use. No match prints the explicit abstention message ("No memory met
  the relevance threshold …"); output is empty only on failure (daemon down,
  blank query).
- `hook <session-start|user-prompt-submit|pre-tool-use|stop>` — run a lifecycle
  hook over stdin JSON. Host-wired by `install`; rarely called directly.
- `help` — full usage.

## Pi Package

The npm package is also a first-class Pi package (`keywords: ["pi-package"]` and
a `pi` manifest in `package.json`). `pi install npm:@fingerskier/augment` loads:

- `dist/pi/extension.js` — a Pi extension that registers namespaced
  `augment_*` tools and slash commands.
- `integrations/pi/skills/augment-context/SKILL.md`,
  `integrations/pi/skills/augment-decoction/SKILL.md`,
  `integrations/pi/skills/augment-dream/SKILL.md`, and
  `integrations/pi/skills/augment-generic/SKILL.md` — Pi-specific workflow
  guidance using the `augment_*` tool names. Generic store is intentional
  user/agent knowledge into `.generic/` via ordinary upsert (not decoction).

The Pi extension does not replace built-ins such as `read`; MCP `read` is exposed
as `augment_read_memory`. It lazily connects to the shared daemon from tools and
session events (no background resources start in the extension factory), warms
`init_project` on `session_start`, injects recalled task context on
`before_agent_start`, and reminds or follows up after non-trivial turns to
persist durable work.

Pi tools:

- `augment_init_project`, `augment_list_projects`
- `augment_search`, `augment_project_context`, `augment_read_memory`
- `augment_upsert`, `augment_link`, `augment_list_links`, `augment_unlink`
- `augment_decoction_glean`, `augment_decoction_cleanup`
- `augment_sleep_candidates`, `augment_sleep_propose`, `augment_sleep_proposals`,
  `augment_sleep_apply`, `augment_sleep_reject`
- `augment_dream_propose`, `augment_dream_proposals`, `augment_dream_apply`,
  `augment_dream_reject`
- `augment_memory_insights`, `augment_memory_graph`

Pi commands:

- `/augment-context [query]`
- `/augment-persist [summary]`
- `/augment-dashboard [--no-open]`
- `/augment-sleep`
- `/augment-dream`
- `/augment-generic [from: path|notes]`

Pi-specific environment variables:

- `AUGMENT_PI_AUTO_CONTEXT=inject|reminder|off` (default `inject`).
- `AUGMENT_PI_AUTO_PERSIST=reminder|followup|off` (default `reminder`).
- `AUGMENT_PI_CONTEXT_LIMIT` (default `5`).
- `AUGMENT_PI_CONTEXT_MAX_CHARS` (default `12000`).

Pi and MCP expose the same sleep, decoction, and dream lifecycle operations;
Claude/Codex/Grok skills supply the agent-side synthesis and approval guidance,
including the intentional generic-store skill (`augment-generic`) that writes
ordinary `.generic/` memories via upsert (not `decoction_glean`). The CLI and
lifecycle-hook behavior is unchanged.

## Lifecycle Hooks

Both installed integrations wire the same `hooks/hooks.json` (Claude Code and
Codex share the event names and stdin-JSON contract). Every handler **fails
open** — any error yields empty output and exit 0, so a broken hook can never
break the host agent.

- `SessionStart` — warms the daemon and registers the project.
- `UserPromptSubmit` — recalls memory for the prompt and injects it as
  `additionalContext` before the model sees the prompt.
- `PreToolUse` (matcher `Edit|Write|Bash`) — recalls additional memory keyed to
  the tool action (the edited file / the Bash command). Uses a raised relevance
  floor (0.45, calibrated on the real model — tool queries are command/path
  shaped, not prose) and injects each distinct query at most once per session.
  Injection-only: never blocks, gates, or rewrites a tool call.
- `Stop` — blocks the turn once with a directive to upsert a memory, then allows
  the stop (loop-guarded per turn).

Installed hook commands invoke the install-time-provisioned runtime directly
(`node <prefix>/node_modules/@fingerskier/augment/dist/bin/augment.js hook
<event>`) — no npm bootstrap on the hot path.

The verification process for the whole flow is
[docs/verify-memory-flow.md](verify-memory-flow.md).

## Recall Log

Every `/memories/search` appends one JSON line to `<stateDir>/recall/events.jsonl`
recording what recall actually returned: `ts`, `surface`, `project`, `query`,
`abstained`, `result_count`, `top_score`, and `paths`. It is the passive
instrument that caught the 2026-07-10 memoryRoot split-brain (six days of
empty-corpus recalls that abstained silently).

- **Passive and human-rating-free.** Search records events without asking users
  to rate individual results.
- **Best-effort by design.** A failed append never fails the search that
  triggered it.
- **Single-slot rotation.** When the file exceeds `RECALL_LOG_MAX_BYTES` (5 MB)
  it is rotated to `events.jsonl.1` before the next append — the log is
  diagnostic, not a record of account.

## MCP Tools

### `init_project`

Infers or accepts a project name and upserts a project record.

Inputs:

```ts
{ project_name?: string }
```

### `list_projects`

Lists known project records.

Inputs:

```ts
{ name?: string }
```

### `search`

Recalls memories semantically and lexically similar to a query.

Inputs:

```ts
{
  project_name?: string;
  query: string;
  limit?: number;      // default 5, max 20
  max_chars?: number;  // default 12000, max 50000
  kinds?: Array<"ISSUE" | "ARCH" | "TODO" | "SPEC" | "WORK">;
  include_linked?: boolean;
  min_score?: number;  // 0..1 relevance floor; default 0.4, 0 disables
}
```

Behavior:

- Returns plain text suitable for direct context injection.
- Includes local memory IDs, project names, paths, kinds, scores, and link
  annotations.
- May use the CWD project as a modest metadata boost, but cross-project results
  are allowed based on score.
- Labels the provenance of each result relative to the querying project: a memory
  from another repo in the same org is marked `provenance:foreign-cross-repo`, and
  one from another org `provenance:foreign-cross-org`. The shared memory store is
  multi-author, so cross-project recall is also cross-author — the marker lets the
  consuming agent discount memory it did not author (a relevance floor alone can't
  stop a genuinely-relevant foreign memory).
- Prioritizes linked memories without requiring them.
- **Down-weights archived memories** (a WORK source consolidated by a `sleep`
  pass) rather than hiding them: their blended score is multiplied by
  `ARCHIVED_SEARCH_WEIGHT` (0.5, after the blend and before the floor), so the
  consolidated record outranks its sources while the sources stay auditable.
  `read` still returns an archived memory's body verbatim.
- Applies a minimum relevance threshold (`min_score`, default
  `DEFAULT_SEARCH_MIN_SCORE` = 0.4) and **abstains** when nothing clears it —
  returning no results and a "nothing injected" message rather than surfacing an
  unrelated memory. The floor is calibrated against the real embedding model:
  after the empirically-anchored cosine rescale (`SEMANTIC_COSINE_BASELINE`
  0.33), an unrelated memory blends to ~0.12 while an on-topic one lands ~0.60,
  so 0.4 separates abstention from recall with margin. Pass `min_score: 0` to
  disable the floor (never abstain), or raise it to demand a stronger match.
- Packs results under a fair-share character budget: each result may use an even
  split of the remaining `max_chars`, with unused share rolling forward; an
  oversized body is head-truncated with a visible `[truncated]` marker rather
  than omitted, and a result is skipped only when fewer than 80 usable characters
  remain. Bodies are whole-file prefixes — never summarized.

### `upsert`

Stores text in a memory file.

Inputs:

```ts
{
  project_id: number;
  memory_id?: number;
  kind?: "ISSUE" | "ARCH" | "TODO" | "SPEC" | "WORK";
  name: string;
  content: string;
  tags?: string[];
}
```

If `memory_id` is absent, Augment may automatically update a highly similar
memory in the same project and kind — but only when the new content subsumes the
existing one (every distinct term of the prior body survives in the new content),
so the in-place update is a lossless refresh. If the new content instead
contradicts or omits something the prior memory held, Augment preserves the prior
memory intact and stores the new content as its own memory rather than silently
overwriting history.

Content is capped at 12,000 characters; an oversized upsert is rejected — split
the note instead.

### `read`

Reads one memory by local numeric ID.

Inputs:

```ts
{ id: number }
```

### `link`

Creates a directional link between memories and persists it as a relative-path
link in the source memory frontmatter.

Inputs:

```ts
{
  from_memory_id: number | string;
  to_memory_id: number | string;
  type?: "DEPENDS_ON" | "BLOCKS" | "IMPLEMENTS" | "PARENT" | "RELATED";
}
```

Each reference may be a local numeric ID **or** a relative path
(`org/repo/KIND/name.md`). Paths are the durable handle — they survive index
rebuilds, while numeric IDs churn. An all-digit string is interpreted as a
numeric ID.

### `list_links`

Lists inbound and outbound links involving a memory.

Inputs:

```ts
{ memory_id: number }
```

### `unlink`

Removes a link by local link ID.

Inputs:

```ts
{ id: number }
```

### `decoction_glean`

Discovers recurring cross-project evidence or writes an agent-authored generic
memory. It is separate from sleep and performs no LLM synthesis itself.

Inputs:

```ts
{ action: "discover"; min_cosine?: number; limit?: number }

// or
{
  action: "write";
  kind: "SPEC" | "ARCH";
  name: string;
  content: string;
  tags?: string[];
  derived_from: string[];
  suggested_removals?: Array<{ path: string; reason: string }>;
  expected_content_hash?: string;
  expected_frontmatter_hash?: string;
}
```

Discovery uses the existing memory embeddings and complete-link clustering:
every pair in a cluster must meet `min_cosine` (default `0.75`), and a result
must span at least four distinct projects. Multiple memories from one project
count once; `local/*` projects count normally. Existing generics, archived
memories, and sources tagged `private` or `no-generalize` are excluded; there is
no age gate. Eligible evidence kinds are WORK, ISSUE, SPEC, and ARCH.

Write stores a normal `.generic/<KIND>/<name>.md` memory with `derived_from`
provenance. Those unique sources must satisfy the same eligibility rules and
span at least four projects. Removal suggestions and credential-shaped-content
warnings are returned to the agent but are not persisted as lifecycle metadata.
Warnings do not block the write. Creating a generic omits expected hashes;
updating one requires both current hashes so a stale glean cannot overwrite a
newer edit.

### `decoction_cleanup`

Hard-deletes an explicitly approved set of originals after retargeting their
typed inbound links to one generic memory.

Inputs:

```ts
{ generic_path: string; source_paths: string[] }
```

The whole request is prevalidated before deletion: the target must be generic,
every source must exist, and no source may itself be generic. Cleanup then
returns one result per source. There is no journal or rollback; a runtime failure
does not undo sources already processed. The generic keeps its `derived_from`
paths as historical provenance.

### `sleep_candidates`

READ-ONLY preview of sleep consolidation. Clusters settled WORK memories
(default: older than 3 days by `updated_at`) within each project into candidate
groups a `sleep` pass distills into SPEC/ARCH records via `sleep_propose` →
user approval → `sleep_apply`.

- Edges: existing links of any type, or raw cosine >= `min_cosine`
  (default 0.75 — semantic-only, deliberately above the blended recall floor;
  see `SLEEP_MIN_COSINE` in `src/constants.ts`).
- Clusters never span projects; archived memories are excluded from candidacy.
  Output reports durable `relative_path`s.
- Input: optional `project_name` (inferred from cwd otherwise), `min_cosine`,
  `min_age_days`, `limit` (default 20, `SLEEP_MAX_CLUSTERS`).
- Mutates nothing.

### `sleep_propose`

Draft a sleep consolidation: fold ≥2 settled WORK memories into one new SPEC or
ARCH record. Writes **only** a proposal file outside the corpus (under
`<stateDir>/sleeps/`), for user review — the corpus is untouched until the user
approves and `sleep_apply` runs.

Inputs:

```ts
{
  project_name?: string;  // inferred from cwd otherwise
  kind: "SPEC" | "ARCH";
  name: string;
  content: string;
  derived_from: string[]; // >=2 WORK relative paths, all in project_name
  rationale?: string;
}
```

Validation (shared by propose, re-checked at apply since drafts sit while the
corpus moves): every `derived_from` path resolves in the corpus, all are kind
`WORK`, all belong to `project_name` (single-project constraint), none archived,
`derived_from.length >= 2`, and the target path
`<project>/<kind>/<name>.md` must not already exist. The proposal body is
user-editable on disk before approval.

### `sleep_proposals`

Lists sleep proposals drafted by `sleep_propose`, optionally filtered by status.

Inputs:

```ts
{ status?: "proposed" | "applied" | "rejected" }
```

### `sleep_apply`

Applies a sleep proposal by filename. Requires explicit user approval of the
named proposal and is the **only** corpus write in the sleep flow: it re-reads
the proposal fresh from disk, re-validates, upserts the consolidated SPEC/ARCH
(with `derived_from` provenance), archives each WORK source in place
(`archived: true` + `consolidated_into:`, body byte-untouched), and marks the
proposal `applied`. The daemon route lands the whole pass as one revertible
`sleep:` git commit on the memory root.

Inputs:

```ts
{ filename: string }
```

### `sleep_reject`

Rejects a pending sleep proposal by filename. Mutates only the proposal file
(outside the corpus); the corpus is untouched.

Inputs:

```ts
{ filename: string }
```

### `dream_propose`

Writes a user-reviewable speculative memory or link proposal under
`<stateDir>/dreams/`; it does not mutate the corpus. Agents gather inspiration
through normal global search, which prioritizes the current project while still
returning generic and foreign-project memories.

Inputs:

```ts
{
  project_name?: string; // defaults to cwd inference; must be a real project
  kind: "ISSUE" | "ARCH" | "TODO" | "SPEC" | "WORK";
  name: string;
  content: string;
  derived_from: string[]; // >=1 current, generic, or foreign memory
  rationale?: string;
}

// or
{
  project_name?: string; // defaults to cwd inference; must be a real project
  link: {
    from: string;
    to: string;
    type: "DEPENDS_ON" | "BLOCKS" | "IMPLEMENTS" | "PARENT" | "RELATED";
  };
  rationale?: string;
}
```

A dream memory is created in the inferred or explicit current real project and
may be inspired entirely by generic or foreign memories. `.generic` cannot be
the active dream project. A dream link's source must belong to the current
project; its target may belong to any project. The draft remains editable until
apply.

### `dream_proposals`

Lists both dream-memory and dream-link proposals, optionally filtered by status.

Inputs:

```ts
{ status?: "proposed" | "applied" | "rejected" }
```

### `dream_apply`

Re-reads and revalidates one explicitly approved proposal. A dream-memory apply
creates the reviewed record with the `dream` tag and `derived_from` provenance;
a dream-link apply creates exactly the reviewed link. The daemon records the
corpus mutation as a `dream:` git commit when git auto-commit is available.

Inputs:

```ts
{ filename: string }
```

### `dream_reject`

Rejects a pending dream proposal without changing the corpus.

Inputs:

```ts
{ filename: string }
```

### `memory_insights`

Aggregates a project's memory graph into dashboard insights.

Inputs:

```ts
{ project_name?: string }
```

Behavior:

- Resolves the project strictly (exact name, or a single unambiguous substring
  match) — unlike `init_project` it never creates anything.
- Returns a text summary (always) plus `structuredContent` with: totals
  (memories/links/distinct tags/chars), counts by kind, links by type, top tags,
  12 weekly activity buckets (created vs updated), most-connected memories,
  orphan count, and freshest memory.
- In MCP Apps hosts (see below) the result renders as an interactive dashboard
  snippet.

### `memory_graph`

Returns a project's memory graph for visualization.

Inputs:

```ts
{ project_name?: string }
```

Behavior:

- Text summary (node/link counts, top hubs) is always returned and points at
  `augment dashboard` for the full experience.
- The compact node/edge payload (capped at the 300 most recently updated
  memories) is attached as `structuredContent` **only** when the client
  negotiated the MCP Apps extension or `AUGMENT_MCP_UI_EMBED=1` is set — in a
  text-only host it would only burn model context.

## MCP Apps Dashboard Snippets (SEP-1865)

The MCP server implements the [MCP Apps extension](https://github.com/modelcontextprotocol/ext-apps)
(`io.modelcontextprotocol/ui`, spec version 2026-01-26):

- Two UI templates are predeclared as resources with mime type
  `text/html;profile=mcp-app`: `ui://augment/insights.html` and
  `ui://augment/graph.html`. Both are fully self-contained HTML documents
  (inline CSS/JS, Cytoscape inlined from `node_modules` at read time) so they
  work offline under the extension's default CSP.
- `memory_insights` / `memory_graph` reference their template via
  `_meta.ui.resourceUri`; UI-capable hosts render the tool result in a sandboxed
  iframe and stream data in over the spec's postMessage JSON-RPC
  (`ui/initialize` → `ui/notifications/initialized` →
  `ui/notifications/tool-result`). The snippets adapt to the host theme
  (`hostContext.theme` + host CSS variables), auto-resize via
  `ui/notifications/size-changed`, and the insights snippet can refresh itself
  through the host-proxied `tools/call`.
- Hosts without the extension ignore the metadata entirely and get the text
  fallback — the tools stay useful in text-only hosts like CLIs.
- Classic MCP-UI hosts (embedded-block renderers that never negotiate the
  extension): set `AUGMENT_MCP_UI_EMBED=1` to append a self-contained
  `type: "resource"` HTML block (data inlined, `mimeType: text/html`) to tool
  results when — and only when — the client did not negotiate the extension.

## Configuration

Resolution order:

1. Environment variables.
2. `~/.augment/config.json`.
3. Defaults.

Environment variables:

- `AUGMENT_MEMORY_ROOT`
- `AUGMENT_STATE_DIR`
- `AUGMENT_DAEMON_PORT`
- `AUGMENT_GIT_AUTOCOMMIT` — default on; set `0`/`false`/`no`/`off` to disable the
  daemon's [git auto-commit](#git-auto-commit) of memory writes.
- `AUGMENT_MCP_UI_EMBED` — set `1` to embed classic MCP-UI HTML blocks in
  `memory_insights`/`memory_graph` results for hosts that render embedded
  `ui://` resources but do not negotiate the MCP Apps extension.

Defaults:

- Memory root: `~/.augment/memories`
- State directory: `~/.augment/state`
- Database: `~/.augment/state/index.db`
- Daemon discovery file: `~/.augment/state/daemon.json`

## Agent Integration Installer

The `augment` CLI can install dogfooding integrations:

```powershell
npm exec --yes --package @fingerskier/augment -- augment install codex --scope user --memory-root "C:\Users\you\Dropbox\augment-memories"
npm exec --yes --package @fingerskier/augment -- augment install codex --scope repo
npm exec --yes --package @fingerskier/augment -- augment install claude --scope repo
npm exec --yes --package @fingerskier/augment -- augment install grok --scope user
npm exec --yes --package @fingerskier/augment -- augment install all --scope user --dry-run
```

Codex install creates or updates:

- A local plugin folder named `augment`.
- `.codex-plugin/plugin.json`.
- `.mcp.json` pointing to the published `@fingerskier/augment` package through
  an isolated npm `--prefix` directory.
- `skills/augment-context/SKILL.md`, including the context, decoction, dream,
  and generic-store workflows exposed through Codex's single packaged skill.
- `hooks/hooks.json` wiring SessionStart / UserPromptSubmit /
  PreToolUse (`Edit|Write|Bash`) / Stop.
- A personal or repo marketplace entry.

Claude install creates or updates:

- A real Claude Code plugin folder named `augment` with
  `.claude-plugin/plugin.json`, auto-discovered `augment-context`,
  `augment-sleep`, `augment-decoction`, `augment-dream`, and `augment-generic`
  skills, a bundled `.mcp.json` (same cwd-safe MCP command shape as Codex), and
  `hooks/hooks.json` (auto-discovered lifecycle hooks).
- A `.claude-plugin/marketplace.json` entry so the plugin is installable via
  `/plugin marketplace add` + `/plugin install augment@<marketplace>`.
- A direct MCP registration so the server is active immediately: repo scope writes
  `<repo>/.mcp.json`; user scope merges `mcpServers.augment` into `~/.claude.json`,
  preserving all other keys.
- A best-effort plugin registration through Claude's own CLI — it shells out to
  `claude plugin marketplace add <root>` and `claude plugin install augment@<marketplace>`
  (mapping `--scope repo` to Claude's `project` scope). This uses Claude's official
  install path (cache + catalog) rather than hand-writing Claude's internal plugin
  state. It is skipped when `claude` is not on PATH, on `--dry-run`, or with
  `--no-plugin`, falling back to printing the manual `/plugin` commands.
- A marked Augment block in `CLAUDE.md` carrying the always-on memory workflow.

Grok Build install creates or updates:

- `[mcp_servers.augment]` in `~/.grok/config.toml` (user) or
  `<repo>/.grok/config.toml` (repo) via an idempotent TOML merge that preserves
  unrelated sections; sets `startup_timeout_sec = 60` and optional
  `[mcp_servers.augment.env]` when `--memory-root` is given.
- Skills under `.grok/skills/` (context, sleep, decoction, dream, generic).
- Lifecycle hooks at `.grok/hooks/augment.json` (SessionStart / UserPromptSubmit /
  PreToolUse with `Edit|Write|Bash` matcher — Grok aliases those to its own tool
  names — / Stop).
- A marked Augment block in `~/.grok/AGENTS.md` (user) or repo `AGENTS.md` (repo).

All installers also provision the shared hook runtime once via
`npm install --prefix ~/.augment/npm-exec @fingerskier/augment`, so hook commands
run through a direct `node <entry>` invocation (tens of milliseconds) instead of
an npm bootstrap on every event. If npm is unavailable at install time the
installer prints the manual command; hooks fail open (silent no-ops) until it is
run. This installer path is independent of the [Pi Package](#pi-package) manifest
and remains the supported setup for Claude Code, Codex, and Grok Build.
`install all` runs codex + claude + grok.

## Deferred

- `sleep`/`dream` **automation** (scheduled passes, auto-approve, batch dreams)
  — deferred until supervised proposals are consistently high-quality.
- Memory `move`.

Not planned:

- Remote sync — file sync (e.g. Dropbox) is the supported multi-machine story.
