npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

foxpack-ai

v0.1.0

Published

Bring your AI memory home: import ChatGPT, Claude and Gemini exports into a local store.

Readme

foxpack

npm version Downloads/month License: MIT

Quickstart · API reference · Export coverage · FAQ

foxpack brings your AI memory home: it imports ChatGPT, Claude and Gemini exports into a local store. It finds memory candidates in what you said, and you accept, edit or reject each one. Agents can read the accepted memories through SCENT or MCP; they never see the raw conversations.

Install

npm install foxpack-ai

Node.js 24 or later is required. The library also runs in a browser; the Firefox extension targets Firefox 153 or later. Runtime dependencies: fflate for zip files, and @modelcontextprotocol/sdk with zod for the MCP server. foxmemory is an optional peer dependency.

Keep your first memory

Save this as example.mjs, then run node example.mjs. No API keys, network access or .env file are needed.

import { createPack, inMemoryStore } from "foxpack-ai";

const pack = createPack({ store: inMemoryStore() });
await pack.import("memories", "- Prefers aisle seats.\n- Has a dog named Miso.");
const [first] = await pack.memories({ status: "pending" });
await pack.accept(first.id);
console.log((await pack.memories({ status: "accepted" })).map((m) => `${m.kind}: ${m.text}`));

Success prints [ 'preference: Prefers aisle seats.' ]. From the command line, with a real export:

npx -p foxpack-ai foxpack import chatgpt ~/Downloads/chatgpt-export.zip
npx -p foxpack-ai foxpack memories --pending
npx -p foxpack-ai foxpack accept <id>
npx -p foxpack-ai foxpack export --format markdown > my-memory.md

How it works

export file -> readExport (zip or JSON, size cap) -> parser per source -> conversations
conversations -> extractMemories (sentence patterns, no model) -> candidates
candidates -> you: accept / edit / reject / forget -> accepted memories
accepted memories -> export (foxpack, DTI, Markdown) | SCENT resolver | MCP tools | foxmemory

foxpack makes no network calls. The pack is one JSON object: in ~/.foxpack/pack.json for the CLI, in browser.storage.local for the extension. A decision is kept by candidate id, so a new import never brings back a memory you rejected.

Why it exists

Your AI memory sits in many vendor clouds, and you cannot read it, fix it or move it. ChatGPT, Claude and Gemini each export your chats, but in three formats, and none of them exports your saved memories as data. Claude's memory import takes a pasted summary from another assistant; nothing flows back. foxpack reads all three exports in one place. You choose what is true, and the result stays on your computer.

Compare

Checked on 2026-10-15 against the convoviz README and the Claude memory import page.

| Property | foxpack | convoviz | Claude memory import | |---|---|---|---| | Sources | ChatGPT, Claude, Gemini Takeout, pasted lists | ChatGPT | Text pasted from another assistant | | Output | Local pack, foxpack/DTI/Markdown exports | Markdown files, word clouds and usage graphs | Memory inside Claude | | Memory review | Each candidate: accept, edit, reject | None | Claude picks what to keep | | Agent access | SCENT resolver and read-only MCP tools | None | Claude only |

Coverage

| Export | Status | How it was checked | |---|---|---| | ChatGPT data export, zip or conversations.json, also split conversations-000.json files | ✓ | Fixtures built from field names in open-source parsers of real exports; Firefox E2E | | ChatGPT memory writes (bio tool) and custom instructions | ✓ | Same; the bio content shape is unconfirmed | | Claude data export, zip, conversations.json, memories.json | ✓ | Same | | Google Takeout, My Activity > Gemini Apps, MyActivity.json | ✓ | Same; conversation grouping is unconfirmed, see docs/format.md | | Google Takeout as HTML (the Takeout default) | — | Refused with a message to choose JSON | | A pasted memory list from any assistant | ✓ | Unit tests and E2E | | DTI "AI Conversation History" export | ✓ | Checked against the required fields of the published schema |

No real user export was used in the tests. The fixtures follow the shapes in docs/format.md, which lists what is confirmed and what is not.

Common use cases

  1. A person who used ChatGPT for two years moves to Claude and takes the facts that matter with them.
  2. A Firefox user keeps one local list of their preferences and lets the foxscope extension share parts of it with an agent.
  3. A developer gives a coding agent the user's accepted project notes through foxpack mcp, without the chats.
  4. A foxmate builder sends accepted memories to foxmemory with createPack({ store, memory }).
  5. A person backs up their history from three vendors as one Markdown file they can read.

Features

  • Three vendor exports and plain lists: zip or JSON, found at any depth in the zip; see coverage.
  • Candidates without a model: fixed sentence patterns, a kind and a confidence, the source chat and date.
  • Review that sticks: accept, edit, reject and forget survive re-imports. Forget deletes the memory, and the sentence it came from in your imported chats and their titles. A reply or a chat title in other words stays.
  • Exports: foxpack JSON (reads back in), DTI JSON, Markdown; accepted memories only.
  • Agents see accepted memories only: SCENT and MCP never return a conversation or a pending candidate.

Runtime surfaces

Library (foxpack)

| Export | What it does | |---|---| | parseChatGPT(contents), parseClaude(contents), parseClaudeMemories(contents), parseGemini(contents), parseSavedMemories(text) | Pure parsers, from file text or parsed JSON to { source, conversations, savedMemories, skipped }. Throw FoxpackError bad_export. | | readExport(source, bytes or text, { maxBytes? }) | Detects a zip by its bytes, reads only the needed files, and calls the parser. maxBytes defaults to 256 MiB. | | extractMemories({ conversations, savedMemories?, source? }) | Candidates { id, text, kind, confidence, source, conversationId, date, seenIn }. Kinds: preference, fact, person, project. | | createPack({ store, memory?, read?, now? }) | The pack. store is any { load(), save(data) }; memory is a foxmemory memory. | | memoryResolver(pack) | A SCENT v0.1 resolver for the memory namespace. | | exportPack(data, options), toDti(conversation, at) | The export functions that pack.export uses. | | inMemoryStore(), storageStore(browser.storage.local) | Stores for tests and for an extension. | | scentListener(storage) | The runtime.onMessageExternal listener: answers foxscope@pooriaarab only. Any other sender gets the error of an add-on that is not installed. | | FoxpackError | Every failure. code is bad_input, bad_export, corrupt_zip, too_large, not_found, corrupt_store or locked. |

A pack has these methods. They run one at a time.

| Method | What it does | |---|---| | import(source, contents) | source is chatgpt, claude, gemini or memories. Returns { source, conversations, candidates, added, skipped }. Nothing is written when it fails. | | conversations({ source? }), search(query, { limit? }) | The imported chats, and a plain text search over them. | | memories({ status?, kind?, query? }) | Candidates and memories. The default leaves out forgotten ones. | | accept(id), reject(id), edit(id, text), forget(id) | The review. With a foxmemory sink, accept, edit and forget change foxmemory too. | | export({ format, conversations? }) | foxpack, dti or markdown, with accepted memories only. | | restore(text) | Reads a foxpack export back in. Its memories come back as pending, to review again: a file can say anything, so foxpack does not take its word that they were accepted. A local decision wins. One bad record and nothing is saved. | | stats(), clear(), data() | Counts; delete everything; a copy of the stored pack. |

foxpack/node

fileStore(path?) keeps the pack in $FOXPACK_HOME/pack.json, else ~/.foxpack/pack.json, with a lock file and atomic writes. readExportFile(path) checks the size before it reads. In Node, import("foxpack-ai") resolves to this entry, so memoryResolver() with no argument reads the pack file read-only.

CLI

foxpack import chatgpt|claude|gemini|memories|foxpack <file>
foxpack stats
foxpack memories [--pending|--rejected|--all]
foxpack accept|reject|forget <id> [id...]
foxpack edit <id> <text>
foxpack search <words>
foxpack export --format foxpack|dti|markdown [--no-conversations]
foxpack mcp

Output of stats after one Claude export:

conversations: 3 (chatgpt 0, claude 3, gemini 0, memories 0)
messages: 6
memories: 2 pending, 0 accepted, 0 rejected, 0 forgotten

Results go to stdout and messages to stderr. The exit code is 0 when the command works, 1 when it fails, and 2 for bad arguments.

MCP server

foxpack mcp starts a read-only server on stdio with three tools: memory_list (accepted memories, optional kind), memory_search (text match on accepted memories) and pack_stats (counts only). No tool returns a conversation or a pending candidate, and no tool writes.

{ "mcpServers": { "foxpack": { "command": "npx", "args": ["-p", "foxpack-ai", "foxpack", "mcp"] } } }

SCENT fields

| Field | Sensitivity | Value | |---|---|---| | memory.preferences, memory.facts, memory.people, memory.projects | ask | Accepted memories of that kind. With derive, texts only. | | memory.conversations | private | Never returned. |

Firefox extension

The import page (the add-on's options page) reads an export in the page and lists the candidates for review. The popup counts the pack and lists the last reads by foxscope. The add-on has the storage permission only, and no host permissions.

Delivery and behavior limits

  • Patterns, not understanding. extractMemories matches sentences like "I prefer...", "call me...", "my sister is...". It misses facts said any other way, and it can propose a sentence that is not true of you. You review each one.
  • No real exports in the tests. The fixtures follow the field names that open-source parsers read in real exports. A vendor can change its export at any time.
  • Gemini has no conversation ids. Entries are grouped by a chat link when the export has one, else each prompt is its own conversation.
  • One JSON object. The whole pack is read and written at once, under one storage key in Firefox or in one file in Node. Every review click (accept, reject, edit, forget) reads and rewrites all of it, conversations included, so with a large history each click gets slower. The 256 MiB cap stops larger files.
  • Not encrypted. The pack is plain JSON in your home folder or in Firefox storage.
  • Forget removes your sentences, nothing else. It removes each sentence you wrote that gave the memory, also in a re-import, and its copy in the title of that chat. It never searches for the memory text, so an edit cannot widen it. An assistant reply that repeats the fact stays, and so does a title that names it in other words ("Jane's epilepsy"), as ChatGPT and Claude write titles.
  • ChatGPT memory writes are a history. A memory you deleted in ChatGPT can still show up as a candidate.
  • The extension does not use foxmemory. A separate add-on cannot read foxpack's storage anyway; use the library with your own foxmemory to share memories.

FAQ

Does foxpack upload my export?

No. The library, the CLI and the extension read the file on your computer and make no network calls.

Which export formats are confirmed?

No vendor publishes a schema. docs/format.md lists each field, where it was seen, and what is unconfirmed.

Does foxpack use an AI model to find memories?

No. It uses fixed sentence patterns, so the same file always gives the same candidates.

What is the DTI export?

The Data Transfer Initiative publishes an "AI Conversation History" schema. export --format dti writes one object per conversation in that schema. The schema has no place for memories, so a DTI export holds the conversations only.

Can an agent read my conversations?

No. SCENT and MCP return accepted memories only. memory.conversations is a private field.

Try the extension

pnpm install
pnpm ci:local
pnpm build:ext

Load dist-ext/manifest.json from Firefox about:debugging, then open the add-on's options page. pnpm e2e runs the Firefox E2E and writes artifacts/e2e-<date>.json; set FOXKIT_BROWSER=ichabod to run it on Ichabod.

License

MIT