Memory plugin (memory)
A local second brain gives one place to ask "what do we know about X?" with citations back to the source.
Command: /memory
Code discovery
See Markdown and shared discovery below for project-wide parsing/search.
Index one committed TypeScript project, then search symbol names, signatures,
documentation, and structural relationships. No model, remote API, or database
server is required. The project must contain committed package.json and
tsconfig.json; inherited configuration and aliases are resolved by TypeScript.
Project paths are relative to AppWeaver core's active workspace.
bun src/cli.ts memory code.parse '{"project":"plugins/nr"}'
bun src/cli.ts memory code.parse '{"project":"plugins/nr","fresh":true}'
bun src/cli.ts memory code.search '{"project":"plugins/nr","query":"NostrResolutionService"}'
bun src/cli.ts memory code.search '{"project":"plugins/nr","query":"NostrResolutionService","format":"json"}'
bun src/cli.ts memory code.inspect '{"project":"plugins/nr","id":"<returned-node-id>"}'
bun src/cli.ts memory code.expand '{"project":"plugins/nr","id":"<returned-node-id>","depth":2}'
Equivalent app commands use flags:
/memory code.parse --project plugins/nr
/memory code.search --project plugins/nr --query NostrResolutionService
/memory code.search --project plugins/nr --query NostrResolutionService --format json
/memory code.inspect --project plugins/nr --id <returned-node-id>
/memory code.expand --project plugins/nr --id <returned-node-id> --depth 2
All four code tools default to compact text. Use "format":"json" in
tool arguments or --format json in app commands for the full typed result.
Search text lists names, kinds, full callable IDs, locations and matching fields;
use inspection for signatures/comments. Inspection and expansion use numbered
node tables and --relation--> edges. Row numbers and F follow-up labels are
local display references, not IDs. External navigation commands are shell-quoted
and deduplicated. Truncation, pagination, revision drift, and indexing suggestions
(which write the DB) remain visible. JSON includes all stored locations/evidence.
code.parseanalyzes TS/TSX, including tests, and saves immediately without a draft. Uncommitted source/config inputs and compiler errors block publication. Failed runs preserve the previous index.freshforces a whole-project rebuild; otherwise unchanged input manifests skip analysis.- Git owns file eligibility and repository boundaries. Tracked files remain eligible even when an ignore rule matches. Imported local files within the project join the index closure; outside dependencies are minimal references.
code.searchacceptskind, exactfile,tests(include/exclude/only),limit(1–100), andoffset. Exact symbol names rank first.code.inspectreturns compact metadata and direct edges withlimit(1–200) andoffset; full bodies are never returned.code.expandacceptsdirection,relations(JSON tool),depth(1–3),maxNodes(1–200), andmaxEdges(1–500). Cycles are deduplicated and truncated results are labeled. Edge evidence is capped at 20 locations with its full count and an explicit truncation marker.- External symbols carry target project/file/revision and typed
followUparguments for a separate query or suggested parse. They do not enable automatic cross-project traversal. Reading the reported source is always an alternative. - Results describe the last indexed snapshot. Project HEAD/dirty-input drift is
reported; dependency freshness remains
unknownuntil inputs are revalidated by parsing. Unsupported dynamic call targets are reported as limitations. - Direct inline invocations (including parenthesized/type-asserted IIFEs and named
function expressions) have function nodes and invocation/body edges. Anonymous
IDs use structural positions rather than line numbers. Injected callbacks and
functions returned by other calls are reported separately as
callback-invocationandreturned-function-call; no runtime target is guessed. Analyzer version 4 triggers a rebuild on the next successful parse.
Indexed projects widget
Open /memory projects to view indexed projects within the active workspace as
a regular timeline card, without adding a header/docked widget.
Each expandable row shows files/nodes, short indexed and HEAD hashes, indexing
timestamp, generation, edge/external-reference counts, hook state, last automatic
run, and stored diagnostics. Current means hashes match; Outdated means
they differ; Unknown means HEAD could not be read. Uncommitted code/config
changes are shown separately. Dependency freshness remains unknown.
Index diagnostics are collapsed and grouped by code, with readable source locations
and messages on expansion. Old unresolved-call records remain readable until
reindexing; raw stored diagnostics remain available in JSON output.
The latest indexing attempt is tracked separately from the successful snapshot
and automatic-hook log. A failed manual or automatic parse shows its reason,
browser-local failure time, recovery advice, and expandable failure details even
while the project row is collapsed. Refresh preserves this feedback. Successful
or unchanged attempts clear the prior failure; unfinished attempts are identified
as having no completed result. Compiler/cleanliness errors are separate from
non-blocking graph coverage limitations. JSON includes lastAttempt.
Displayed hashes use eight characters, with full values on hover and in JSON.
Indexed-at and last-run timestamps use the browser's local date/time and timezone;
JSON retains epoch milliseconds. CLI text uses its process-local timezone.
Refresh only reloads status. Reindex explicitly forces a rebuild (fresh: true)
and refreshes the originating widget. Preview hook opens a modal with the exact
command and proposed changes; its explicitly labeled Enable/Disable button calls
the existing hook operation. Opening either view never changes Git settings or
indexes a project. Missing project directories remain visible with disabled
actions; paths outside the workspace (including symlink escapes) are excluded.
Unindexed-project discovery is deferred.
bun src/cli.ts memory projects '{}'
bun src/cli.ts memory projects '{"format":"json"}'
Storage and implementation
db.sqlite lives beside the plugin. Versioned memory_code_* tables contain
project snapshots, nodes, edges/evidence, compact metadata, and FTS5 search data.
The input manifest records Git revisions, read hashes, and negative resolution
lookups. Installed packages and ignored generated dependencies are explicitly
hashed local environment inputs, not falsely labeled as Git-committed content.
The additive memory_code_attempts table retains one latest attempt per project,
with a monotonic ID, start/completion timestamps, outcome, and structured errors.
Older concurrent completions cannot overwrite a newer attempt's outcome.
Index replacement is transactional and project-scoped. Generation checks reject stale concurrent publishers. The full AST and implementation bodies are not persisted. Root filesystem paths currently identify projects; moving a project requires a new index. Multiple referenced tsconfig projects are not yet supported.
Scaffold CRUD commands operate directly against SQLite without draft review. Draft commands and draft table creation have been removed. Indexed-project status and hook controls are available in the projects widget; broader settings and unindexed-project discovery remain later work. See the Memory design for the durable design/progress record.
Tool schemas and agent instructions are exported through aiDefinition in ai.ts.
Regenerate tooling with bun run plugin:generate after changing that interface.
Opt-in post-commit indexing
Indexing never installs a Git hook. Each repository requires a separate explicit install action by the user or an agent acting on that specific user request:
bun src/cli.ts memory code.hook '{"project":"plugins/journal","operation":"preview"}'
bun src/cli.ts memory code.hook '{"project":"plugins/journal","operation":"install"}'
bun src/cli.ts memory code.hook '{"project":"plugins/journal","operation":"status"}'
bun src/cli.ts memory code.hook '{"project":"plugins/journal","operation":"remove"}'
Equivalent app commands use --project and --operation; all operations support
format: "json". Preview shows the generated wrapper, exact executable command,
managed directory, and delegated original hook directory. Install is idempotent
when the existing installation is intact. Natural-language /memory ai cannot
install/remove hooks; use the explicit command.
The installer sets repository-local core.hooksPath to a managed directory
inside Git metadata. Other standard hooks delegate through symlinks; post-commit
runs the original executable first, then the plugin-owned indexing runner. It
never edits shared release scripts or global Git settings. Nested release-hook
amendments run existing hooks but skip duplicate indexing, so the outer run sees
the final revision. Original hook failure skips indexing and preserves its exit
code. Indexing failure is logged and preserves the Git commit and previous index.
Code-query text headers show AUTO-INDEX; JSON metadata contains automation.
Status distinguishes off, enabled, missing, changed, and unavailable,
and includes the last attempted revision/result. Automatic runs synchronously use
the same clean-input/diagnostic/manifest guards as manual parse, without AI
or network calls. Busy runs are skipped with a catch-up message; stale dead-process
locks are reclaimed. Manual parsing or the next commit can catch up after a missed
run. Dirty source or consumed dependency inputs may still block automatic indexing.
Remove restores the previous local hooksPath value (or removes the override) and only deletes validated managed files. Edited wrappers/delegation/config and active runs require reconciliation rather than overwriting user changes. Project roots must be repository roots, with Git metadata inside the workspace; worktree-scoped hooksPath overrides and multiple local hooksPath values are not supported in v1. The managed record/last-run state is local to Git metadata, not committed source.
Markdown and shared discovery
parse attempts code and Markdown independently for a selected project; a failed
index retains its previous snapshot without rolling back a successful sibling.
search combines their ranked results with separate revisions/status and typed
inspection actions. It uses reciprocal rank scores, not incomparable raw FTS scores.
Continue shared search with its returned nextCursor (per-index offsets).
bun src/cli.ts memory parse '{"project":"plugins/journal"}'
bun src/cli.ts memory search '{"project":"plugins/journal","query":"publication"}'
bun src/cli.ts memory markdown.parse '{"project":"plugins/journal"}'
bun src/cli.ts memory markdown.parse '{"project":"plugins/journal","exclude":["archive/**"]}'
bun src/cli.ts memory markdown.search '{"project":"plugins/journal","query":"relay","format":"json"}'
bun src/cli.ts memory markdown.inspect '{"project":"plugins/journal","id":"<section-id>"}'
bun src/cli.ts memory markdown.expand '{"project":"plugins/journal","id":"<section-id>","relations":["links-to"]}'
App commands use equivalent --project, --query, --id, --format flags.
Repeat --exclude/--relations for arrays; shared --cursor accepts a quoted JSON
object. Null/omitted exclusions preserve saved patterns; an empty JSON array clears
them. Shared parsing and commit hooks preserve those settings.
Markdown requires Git, but not package.json/tsconfig.json. Folder arguments resolve to the nearest committed TypeScript project, independent Git root, or active workspace fallback. More-specific configured/indexed projects own their files; independent repositories are not traversed. Code is not applicable without its committed config pair, unless an existing code index needs explicit failure/status rather than removal.
Index committed .md/.markdown anywhere, including feature READMEs, with tracked
Git semantics and saved project-relative exclusion globs. Dirty Markdown or ownership
configuration rejects publication, including staged deletions, renames and eligible
untracked additions. Unrelated dirty TypeScript does not block Markdown. Git revision
is rechecked before publishing. Parsing never commits files or enables hooks.
CommonMark/GFM AST positions supply heading hierarchy, reference links, tables,
lists and fenced examples; headings/links inside examples are not relationships.
Every heading owns its direct body, with a separate introduction. Long sections use
block-oriented chunks; oversized single blocks split into 6,000-character ranges.
Inspection defaults to 12,000 characters with pagination (maxChars: 6,000–50,000).
Files above 2,000,000 characters are rejected with exclusion/splitting advice.
FTS5 weights titles/headings/tags above body, returning the best chunk per section, exact locations and callable IDs. YAML title falls back to first heading/filename; tags must be a string array. Other fields/raw frontmatter are inspectable. Malformed or cyclic metadata warns without hiding the body; unterminated frontmatter remains ordinary Markdown with a warning.
Inline/reference/same-document links use GitHub slugs and duplicate-heading suffixes.
URI paths/fragments are decoded; leading / paths are project-root relative.
Cross-project links/backlinks expose source/target projects, revisions and locations,
with separate source/target inspection actions. Missing files/headings, unindexed
projects, external URLs, unsupported targets and workspace escapes remain explicit.
Queries never fetch URLs or automatically inspect another project's content. Code-file
links are preserved; their resolution is deferred. Link resolution uses latest indexed
targets in one SQLite read snapshot, so target updates immediately refresh resolution
and backlinks without reparsing referring documents.
memory_markdown_* tables retain one latest successful snapshot, parsed documents,
FTS chunks and monotonic attempts. Unchanged blob hashes/parser versions reuse parsing;
deletions/exclusions/rebuilds replace facts atomically with generation guards. Section
IDs use project/path/slug, not lines; rename/reheading/duplicate reorder can change IDs.
Chunk IDs are snapshot-local offsets. History search, vectors, wikilinks and AI-extracted
knowledge are deferred.
The projects card has separate code/Markdown status and errors in one project row, shared Reindex and individual expanded actions. The existing opt-in runner now calls shared parsing; managed wrapper/consent remain unchanged. Restart the host for app use.
Architecture
See local architecture and source map.