Skip to main content

Constructor

new Nugget(opts: {
  name: string;
  D?: number;
  banks?: number;
  ensembles?: number;
  autoSave?: boolean;
  saveDir?: string;
  maxFacts?: number;
})
opts.name
string
required
Unique identifier for this nugget. Used as the filename (<name>.nugget.json) and as the nugget name embedded in every graph note.
opts.D
number
default:"16384"
Dimensionality of the FHRR vectors. Higher values increase storage capacity and recall accuracy at the cost of memory. Must be the same value when reloading a saved nugget.
opts.banks
number
default:"4"
Number of memory banks. Facts are distributed across banks in round-robin order. More banks improve retrieval robustness when the fact set is large.
opts.ensembles
number
default:"1"
Number of independent ensemble copies. Each ensemble uses a separate random key matrix. Increasing this value improves recall at the cost of memory.
opts.autoSave
boolean
default:"true"
When true, the nugget writes to disk after every mutating operation (remember, forget, clear, and note mutations). Set to false when batching many writes.
opts.saveDir
string
default:"~/.nuggets"
Directory where <name>.nugget.json is stored. The note graph is always written to <saveDir>/graph/graph.json.
opts.maxFacts
number
default:"0"
Maximum number of facts to retain. When the limit is reached, the oldest facts are evicted in FIFO order and their corresponding graph notes are removed. 0 means unlimited.

Methods

remember

remember(key: string, value: string, noteMeta?: GraphNoteMetaInput): void
Stores or updates a key-value fact. If a fact with the same key (case-insensitive) already exists, its value is overwritten. The fact is mirrored into the note graph as a "fact"-kind note.
key
string
required
Lookup key for this fact. Keys are trimmed and compared case-insensitively. Use a scoped prefix such as user:, self:, shared:, or project: to set the memory scope explicitly.
value
string
required
Value to store. Trimmed before saving.
noteMeta
GraphNoteMetaInput
Optional metadata to attach to the graph note. See GraphNoteMetaInput.
const nugget = new Nugget({ name: "project" });
nugget.remember("user:preferred-language", "TypeScript");
nugget.remember("shared:test-command", "pnpm test", { type: "preference" });

recall

recall(
  query: string,
  sessionId?: string,
): { answer: string | null; confidence: number; margin: number; found: boolean; key: string }
Searches holographic memory for a fact matching the query. The lookup is approximate: the engine first tries an exact key match, then substring containment, then fuzzy sequence-match ratio. If sessionId is provided, the matched fact’s hit counter increments once per session.
query
string
required
The key or partial key to search for.
sessionId
string
default:"\"\""
An opaque string identifying the current session. When non-empty and the session hasn’t seen this fact before, the hit count increments by one.
Returns
answer
string | null
The recalled value, or null if no match was found.
confidence
number
Softmax probability of the top match across all vocabulary entries. Range [0, 1].
margin
number
Difference between the top-1 and top-2 softmax probabilities. A higher margin means a cleaner, less ambiguous recall.
found
boolean
true when a key matched the query and a value was decoded.
key
string
The actual key that matched the query.
const result = nugget.recall("preferred-language", "session-abc");
if (result.found) {
  console.log(result.answer);     // "TypeScript"
  console.log(result.confidence); // e.g. 0.97
  console.log(result.margin);     // e.g. 0.42
}

forget

forget(key: string): boolean
Removes a fact by key (case-insensitive, trimmed) and deletes the associated graph note.
key
string
required
The key to remove.
Returns true if a fact was found and removed, false if no matching key existed.
const removed = nugget.forget("user:preferred-language");
console.log(removed); // true

facts

facts(): Array<{ key: string; value: string; hits: number }>
Returns a snapshot of all stored facts. The array is ordered by insertion time.
for (const fact of nugget.facts()) {
  console.log(`${fact.key} = ${fact.value} (${fact.hits} hits)`);
}

createNote

createNote(
  title: string,
  content: string,
  tags?: string[],
  meta?: GraphNoteMetaInput,
): MemoryNote
Creates a free-form "note"-kind graph note. Notes are richer than facts: they have a title, multi-line content, tags, and can carry outbound links.
title
string
required
Note title. Used as the primary search surface and as the human-readable label in the graph.
content
string
required
Note body. Whitespace is normalised (trailing spaces trimmed, runs of 3+ blank lines collapsed).
tags
string[]
default:"[]"
Optional tag list. Tags are lower-cased and hyphenated.
meta
GraphNoteMetaInput
Optional metadata overrides. See GraphNoteMetaInput.
Returns the newly created MemoryNote.
const note = nugget.createNote(
  "CORS fix",
  "Add the client origin to the allowlist in config.ts line 47.",
  ["bug", "cors"],
  { scope: "project", type: "note" },
);
console.log(note.id); // "note-project-a1b2c3d4"

editNote

editNote(
  noteId: string,
  newContent: string,
  updates?: {
    tags?: string[];
    title?: string;
    hidden?: boolean;
    rewrittenAt?: string;
    noteMeta?: GraphNoteMetaInput;
  },
): MemoryNote | null
Replaces the content of an existing note and optionally updates its title, tags, or visibility. If the note is a "fact"-kind note, the underlying fact entry is also updated to stay in sync.
noteId
string
required
The ID of the note to edit.
newContent
string
required
Replacement content. Whitespace is normalised.
updates.tags
string[]
Replacement tag list.
updates.title
string
New title. For fact-kind notes this also updates the fact key.
updates.hidden
boolean
Set to true to soft-archive the note.
updates.rewrittenAt
string
ISO 8601 timestamp to record as lastRewrittenAt.
updates.noteMeta
GraphNoteMetaInput
Metadata overrides applied during the edit.
Returns the updated MemoryNote, or null if the note was not found.
const updated = nugget.editNote(
  "note-project-a1b2c3d4",
  "Add origin to allowlist in config.ts:47 and restart the server.",
  { tags: ["bug", "cors", "resolved"] },
);

updateNote

updateNote(
  noteId: string,
  updates: Partial<Omit<MemoryNote, "id" | "nuggetName">>,
): MemoryNote | null
Applies a partial patch to any writable fields of a note. Unlike editNote, you can update individual fields (such as hits, lastAccessedAt, or scope) without supplying new content.
noteId
string
required
The ID of the note to update.
updates
Partial<Omit<MemoryNote, 'id' | 'nuggetName'>>
required
An object with any subset of MemoryNote fields. id and nuggetName are immutable and ignored if supplied.
Returns the updated MemoryNote, or null if the note was not found.
nugget.updateNote("note-project-a1b2c3d4", {
  stability: "durable",
  confidence: 0.95,
});

deleteNote

deleteNote(noteId: string, hard?: boolean): boolean
Deletes or archives a note. By default, the note is soft-deleted: hidden is set to true and archivedAt is recorded. Pass hard: true to permanently remove it from the graph file and strip all incoming links.
noteId
string
required
The ID of the note to delete.
hard
boolean
default:"false"
When true, the note is permanently removed. When false, it is hidden but remains in the graph.
Returns true on success, false if the note was not found.
Hard deletion is irreversible. All incoming links to the note are also removed.
// Soft archive (reversible)
nugget.deleteNote("note-project-a1b2c3d4");

// Permanent removal
nugget.deleteNote("note-project-a1b2c3d4", true);

addLink(note1: string, note2: string, reason: string): boolean
Creates a bidirectional link between two notes. You can pass a note ID or a note title as either argument.
note1
string
required
ID or title of the first note.
note2
string
required
ID or title of the second note.
reason
string
required
Human-readable description of why these notes are related. Stored on both link objects.
Returns true if the link was created, false if either note could not be resolved.
nugget.addLink("CORS fix", "note-project-b5c6d7e8", "same module affected");

mergeNotes

mergeNotes(target: string, source: string, reason: string): MemoryNote | null
Merges the source note into the target note. The target’s content gains any unique lines from the source. Tags, links, and hit counts are combined. The source note is soft-archived and a redirect link is added pointing to the target. You can pass a note ID or title for either argument.
target
string
required
ID or title of the note to merge into.
source
string
required
ID or title of the note to merge from. Soft-archived after the merge.
reason
string
required
Reason stored on the redirect link attached to the source.
Returns the updated target MemoryNote, or null if either note could not be resolved.
const merged = nugget.mergeNotes(
  "CORS configuration",
  "CORS fix",
  "duplicate notes about the same CORS issue",
);

searchNotes

searchNotes(
  query: string,
  limit?: number,
  opts?: NoteFilterOptions,
): SearchNotesResult[]
Searches graph notes using a hybrid scoring model that combines FHRR vector similarity (42%), text overlap (48%), and metadata boosts for durable and user-scoped notes.
query
string
required
Free-text search query.
limit
number
default:"5"
Maximum number of results to return.
opts
NoteFilterOptions
Optional filters. See NoteFilterOptions.
Returns an array of SearchNotesResult sorted by score descending.
const results = nugget.searchNotes("CORS", 3);
for (const { note, score } of results) {
  console.log(`${note.title} — score ${score.toFixed(3)}`);
}

listNotes

listNotes(opts?: NoteFilterOptions): MemoryNote[]
Returns all visible notes belonging to this nugget, sorted by updatedAt ascending.
opts
NoteFilterOptions
Optional filters. See NoteFilterOptions.
// All visible notes
const notes = nugget.listNotes();

// Including archived notes
const all = nugget.listNotes({ includeHidden: true });

// Only user-scoped fact notes
const userFacts = nugget.listNotes({ scope: "user", type: "fact" });

getNote

getNote(noteId: string): MemoryNote | null
Retrieves a single note by its ID.
noteId
string
required
The note ID to look up.
Returns the MemoryNote or null if not found.
const note = nugget.getNote("note-project-a1b2c3d4");
if (note) {
  console.log(note.content);
}

clear

clear(): void
Removes all facts and all graph notes belonging to this nugget. Resets the internal FHRR state. If autoSave is enabled, writes the empty nugget to disk.
clear() is not reversible. All facts and notes are permanently deleted.
nugget.clear();
console.log(nugget.facts()); // []

status

status(): {
  name: string;
  fact_count: number;
  dimension: number;
  banks: number;
  ensembles: number;
  capacity_used_pct: number;
  capacity_warning: string;
  max_facts: number;
  note_count: number;
}
Returns a health snapshot of the nugget.
name
string
The nugget’s name.
fact_count
number
Number of facts currently stored.
dimension
number
FHRR vector dimensionality (D).
banks
number
Number of memory banks.
ensembles
number
Number of ensemble copies.
capacity_used_pct
number
Estimated percentage of the theoretical FHRR capacity in use. Calculated as fact_count / (banks × √D) × 100.
capacity_warning
string
Empty string when usage is healthy. "WARNING: approaching capacity" above 80%. "CRITICAL: nearly full" above 90%.
max_facts
number
The configured maxFacts limit. 0 means unlimited.
note_count
number
Total number of graph notes (including hidden) belonging to this nugget.
const s = nugget.status();
console.log(`${s.fact_count} facts, ${s.capacity_used_pct}% capacity used`);
if (s.capacity_warning) console.warn(s.capacity_warning);

save

save(path?: string): string
Persists the nugget to disk. If no path is given, the file is written to <saveDir>/<name>.nugget.json. The write is atomic: data is staged to a .tmp file and then renamed.
path
string
Explicit output path. Defaults to <saveDir>/<name>.nugget.json.
Returns the path the file was written to.
const savedPath = nugget.save();
console.log(`Saved to ${savedPath}`);

// Save to a custom path
nugget.save("/tmp/backup.nugget.json");

Nugget.load

static load(path: string, opts?: { autoSave?: boolean }): Nugget
Loads a nugget from a .nugget.json file. On load, legacy unscoped keys are migrated to scoped form and the FHRR memory is rebuilt from the stored facts.
path
string
required
Absolute or relative path to the .nugget.json file.
opts.autoSave
boolean
default:"true"
Whether the loaded nugget should auto-save on mutations.
Returns a fully initialised Nugget instance ready for use.
const nugget = Nugget.load("~/.nuggets/project.nugget.json");
console.log(nugget.facts());

Build docs developers (and LLMs) love