🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

codex-supermemory

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

codex-supermemory - npm Package Compare versions

Comparing version
1.0.3
to
1.0.5
dist/cli.js

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

+3
{
"type": "commonjs"
}

Sorry, the diff of this file is too big to display

#!/usr/bin/env node
"use strict";
// src/skills/login.ts
var import_node_fs3 = require("node:fs");
var import_node_path3 = require("node:path");
var import_node_os3 = require("node:os");
// src/config.ts
var import_node_fs2 = require("node:fs");
var import_node_path2 = require("node:path");
var import_node_os2 = require("node:os");
// src/services/auth.ts
var import_node_http = require("node:http");
var import_node_fs = require("node:fs");
var import_node_path = require("node:path");
var import_node_os = require("node:os");
var import_node_child_process = require("node:child_process");
var import_node_crypto = require("node:crypto");
var SUPERMEMORY_DIR = (0, import_node_path.join)((0, import_node_os.homedir)(), ".codex", "supermemory");
var CREDENTIALS_FILE = (0, import_node_path.join)(SUPERMEMORY_DIR, "credentials.json");
var AUTH_BASE_URL = process.env.SUPERMEMORY_AUTH_URL || "https://console.supermemory.ai/auth/agent-connect";
var AUTH_TIMEOUT = Number(process.env.SUPERMEMORY_AUTH_TIMEOUT) || 6e4;
var AUTH_SUCCESS_HTML = `<!DOCTYPE html>
<html><head><title>Connected - Supermemory</title><style>
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;display:flex;flex-direction:column;justify-content:center;align-items:center;min-height:100vh;background:#faf9f6}
.dot{width:10px;height:10px;background:#22c55e;border-radius:50%;display:inline-block;margin-right:8px}
h1{font-size:32px;font-weight:500;color:#1a1a1a;margin:16px 0}
p{color:#666;font-size:16px}
</style></head><body>
<div><span class="dot"></span><span style="color:#22c55e;font-size:14px">Connected</span></div>
<h1>Supermemory is ready</h1>
<p>You can close this tab and return to Codex.</p>
</body></html>`;
var AUTH_ERROR_HTML = `<!DOCTYPE html>
<html><head><title>Error - Supermemory</title><style>
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;display:flex;flex-direction:column;justify-content:center;align-items:center;min-height:100vh;background:#faf9f6}
.dot{width:10px;height:10px;background:#ef4444;border-radius:50%;display:inline-block;margin-right:8px}
h1{font-size:32px;font-weight:500;color:#1a1a1a;margin:16px 0}
p{color:#666;font-size:16px}
</style></head><body>
<div><span class="dot"></span><span style="color:#ef4444;font-size:14px">Error</span></div>
<h1>Connection Failed</h1>
<p>Invalid API key received. Please try again.</p>
</body></html>`;
function loadCredentials() {
try {
if ((0, import_node_fs.existsSync)(CREDENTIALS_FILE)) {
const data = JSON.parse((0, import_node_fs.readFileSync)(CREDENTIALS_FILE, "utf-8"));
if (data.apiKey) return data.apiKey;
}
} catch {
}
return void 0;
}
function saveCredentials(apiKey) {
(0, import_node_fs.mkdirSync)(SUPERMEMORY_DIR, { recursive: true, mode: 448 });
(0, import_node_fs.writeFileSync)(
CREDENTIALS_FILE,
JSON.stringify({ apiKey, savedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2),
{ mode: 384 }
);
}
function openBrowser(url) {
const onError = () => {
};
if (process.platform === "win32") {
(0, import_node_child_process.execFile)("explorer.exe", [url], onError);
} else if (process.platform === "darwin") {
(0, import_node_child_process.execFile)("open", [url], onError);
} else {
(0, import_node_child_process.execFile)("xdg-open", [url], onError);
}
}
function startAuthFlow() {
return new Promise((resolve, reject) => {
let resolved = false;
const stateToken = (0, import_node_crypto.randomBytes)(16).toString("hex");
const server = (0, import_node_http.createServer)((req, res) => {
const url = new URL(req.url || "/", "http://localhost");
if (url.pathname === "/callback") {
const callbackState = url.searchParams.get("state");
if (callbackState !== stateToken) {
res.writeHead(403, { "Content-Type": "text/html" });
res.end(AUTH_ERROR_HTML);
return;
}
const apiKey = url.searchParams.get("apikey") || url.searchParams.get("api_key");
if (apiKey?.startsWith("sm_")) {
saveCredentials(apiKey);
res.writeHead(200, { "Content-Type": "text/html" });
res.end(AUTH_SUCCESS_HTML);
resolved = true;
clearTimeout(timer);
server.close();
resolve(apiKey);
} else {
res.writeHead(400, { "Content-Type": "text/html" });
res.end(AUTH_ERROR_HTML);
}
} else {
res.writeHead(404);
res.end("Not found");
}
});
server.listen(0, "127.0.0.1", () => {
const { port } = server.address();
const callbackUrl = `http://localhost:${port}/callback?state=${stateToken}`;
const params = new URLSearchParams({
callback: callbackUrl,
client: "codex",
hostname: `codex - ${(0, import_node_os.hostname)()}`,
os: `${(0, import_node_os.platform)()}-${(0, import_node_os.arch)()}`,
cwd: process.cwd(),
cli_version: "1.0.0"
});
const authUrl = `${AUTH_BASE_URL}?${params.toString()}`;
openBrowser(authUrl);
});
server.on("error", (err) => {
if (!resolved) {
clearTimeout(timer);
reject(new Error(`Failed to start auth server: ${err.message}`));
}
});
const timer = setTimeout(() => {
if (!resolved) {
server.close();
reject(new Error("AUTH_TIMEOUT"));
}
}, AUTH_TIMEOUT);
});
}
// src/config.ts
var CONFIG_FILE = (0, import_node_path2.join)((0, import_node_os2.homedir)(), ".codex", "supermemory.json");
var DEFAULT_SIGNAL_KEYWORDS = [
// Preferences (single words to match "i really like", "i always prefer", etc.)
"prefer",
"like",
"love",
"use",
"hate",
"dislike",
"avoid",
// Memory commands
"remember",
"forget",
"note",
// Decisions & Architecture
"decision",
"decided",
"chose",
"choose",
"picked",
"switched",
"moved",
"migrated",
"architecture",
"pattern",
"approach",
"design",
"tradeoff",
// Technical
"implementation",
"refactor",
"upgrade",
"deprecate",
// Problem solving
"bug",
"fix",
"fixed",
"solved",
"solution",
"important",
// Stack/tools
"stack",
"framework",
"library",
"tool",
"database"
];
var DEFAULTS = {
similarityThreshold: 0.6,
maxMemories: 5,
maxProfileItems: 5,
injectProfile: true,
containerTagPrefix: "codex",
filterPrompt: "You are a stateful coding agent. Remember all the information, including but not limited to user's coding preferences, tech stack, behaviours, workflows, and any other relevant details.",
debug: false,
// Signal extraction - disabled by default, captures everything
signalExtraction: false,
signalKeywords: DEFAULT_SIGNAL_KEYWORDS,
signalTurnsBefore: 3,
// Auto-save interval
autoSaveEveryTurns: 3
};
function loadConfig() {
if ((0, import_node_fs2.existsSync)(CONFIG_FILE)) {
try {
const content = (0, import_node_fs2.readFileSync)(CONFIG_FILE, "utf-8");
return JSON.parse(content);
} catch {
}
}
return {};
}
var fileConfig = loadConfig();
function getApiKey() {
if (process.env.SUPERMEMORY_CODEX_API_KEY) return process.env.SUPERMEMORY_CODEX_API_KEY;
if (fileConfig.apiKey) return fileConfig.apiKey;
return loadCredentials();
}
var SUPERMEMORY_API_KEY = getApiKey();
var CONFIG = {
similarityThreshold: fileConfig.similarityThreshold ?? DEFAULTS.similarityThreshold,
maxMemories: fileConfig.maxMemories ?? DEFAULTS.maxMemories,
maxProfileItems: fileConfig.maxProfileItems ?? DEFAULTS.maxProfileItems,
injectProfile: fileConfig.injectProfile ?? DEFAULTS.injectProfile,
containerTagPrefix: fileConfig.containerTagPrefix ?? DEFAULTS.containerTagPrefix,
userContainerTag: fileConfig.userContainerTag,
projectContainerTag: fileConfig.projectContainerTag,
filterPrompt: fileConfig.filterPrompt ?? DEFAULTS.filterPrompt,
debug: fileConfig.debug ?? DEFAULTS.debug,
// Signal extraction
signalExtraction: fileConfig.signalExtraction ?? DEFAULTS.signalExtraction,
signalKeywords: fileConfig.signalKeywords ?? DEFAULTS.signalKeywords,
signalTurnsBefore: fileConfig.signalTurnsBefore ?? DEFAULTS.signalTurnsBefore,
// Auto-save interval
autoSaveEveryTurns: fileConfig.autoSaveEveryTurns ?? DEFAULTS.autoSaveEveryTurns
};
function isConfigured() {
return !!SUPERMEMORY_API_KEY;
}
// src/skills/login.ts
var AUTH_ATTEMPTED_FILE = (0, import_node_path3.join)((0, import_node_os3.homedir)(), ".codex", "supermemory", ".auth-attempted");
async function main() {
try {
if ((0, import_node_fs3.existsSync)(AUTH_ATTEMPTED_FILE)) (0, import_node_fs3.unlinkSync)(AUTH_ATTEMPTED_FILE);
} catch {
}
if (isConfigured()) {
console.log("Already authenticated with Supermemory. Memory is active.");
console.log(`To re-authenticate, remove ${CREDENTIALS_FILE} and run this again.`);
return;
}
console.log("Opening browser to authenticate with Supermemory...");
console.log(`If the browser does not open, visit: ${AUTH_BASE_URL}`);
try {
await startAuthFlow();
try {
if ((0, import_node_fs3.existsSync)(AUTH_ATTEMPTED_FILE)) (0, import_node_fs3.unlinkSync)(AUTH_ATTEMPTED_FILE);
} catch {
}
console.log("\nAuthenticated successfully! Supermemory is now active.");
} catch (err) {
const isTimeout = err instanceof Error && err.message === "AUTH_TIMEOUT";
if (isTimeout) {
console.error("\nAuthentication timed out. Please try again.");
} else {
console.error("\nAuthentication failed:", err instanceof Error ? err.message : err);
}
console.error(`
Alternatively, set the API key manually:`);
console.error(` export SUPERMEMORY_CODEX_API_KEY="sm_..."`);
console.error(` Get your key at: https://console.supermemory.ai/keys`);
process.exit(1);
}
}
main().catch((err) => {
console.error("Fatal:", err instanceof Error ? err.message : err);
process.exit(1);
});

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

---
name: supermemory-forget
description: Remove outdated or incorrect information from memory. Use when user says something is no longer true, wants to delete a memory, or information has changed.
allowed-tools: Bash(node:*)
---
# Forget
Remove outdated or incorrect information from Supermemory.
## When to Use
- User says something is no longer true or has changed
- User explicitly asks to forget or delete a memory
- Information has become outdated or incorrect
## How to Forget
Describe the content to forget — the system will find and remove matching memories:
```bash
node ~/.codex/supermemory/forget-memory.js "DESCRIPTION_OF_WHAT_TO_FORGET"
```
## Examples
- User says "I no longer use React, I switched to Vue":
```bash
node ~/.codex/supermemory/forget-memory.js "user prefers React for frontend development"
```
- User says "forget that API endpoint, it changed":
```bash
node ~/.codex/supermemory/forget-memory.js "API endpoint for user authentication"
```
## After Forgetting
Confirm to the user that the memory has been removed. If they mentioned new information to replace it, use the supermemory-save skill to save the updated information.
---
name: supermemory-login
description: Log in to Supermemory. Use when the user needs to authenticate, set up their API key, or when memory features report a missing key.
allowed-tools: Bash(node:*)
---
# Supermemory Login
Authenticate with Supermemory to enable persistent memory across Codex sessions.
## Usage
```bash
node ~/.codex/supermemory/login.js
```
This opens a browser window for authentication. Once complete, the API key is saved automatically and memory features activate immediately.
If the browser does not open, the script prints a URL to visit manually.
---
name: supermemory-save
description: Save important project knowledge to memory. Use when user wants to preserve architectural decisions, significant bug fixes, design patterns, or important implementation details for future reference.
allowed-tools: Bash(node:*)
---
# Super Save
Save important project knowledge based on what the user wants to preserve.
## Step 1: Understand User Request
Analyze what the user is asking to save from the conversation.
## Step 2: Format Content
Format the content to capture the key context:
```
[SAVE:<date>]
<User> wanted to <goal/problem>.
The approach taken was <approach/solution>.
Decision: <decision made>.
<key details, files if relevant>
[/SAVE]
```
Example:
```
[SAVE:2025-06-15]
User wanted to create a skill for saving project knowledge.
The approach taken was using a separate container tag for shared team knowledge.
Decision: Keep it simple - no transcript fetching, just save what user asks for.
Files: src/save-memory.ts, src/skills/super-save/SKILL.md
[/SAVE]
```
Keep it natural. Capture the conversation flow.
## Step 3: Save
```bash
node ~/.codex/supermemory/save-memory.js "FORMATTED_CONTENT"
```
---
name: supermemory-search
description: Search your coding memory. Use when user asks about past work, previous sessions, how something was implemented, what they worked on before, or wants to recall information from earlier sessions.
allowed-tools: Bash(node:*)
---
# Super Search
Search Supermemory for past coding sessions, decisions, and saved information.
## How to Search
Run the search script with the user's query and optional scope flag:
```bash
node ~/.codex/supermemory/search-memory.js [--user|--project|--both] "USER_QUERY_HERE"
```
### Scope Flags
- `--both` (default): Search both personal and project memories in parallel
- `--user`: Search personal/user memories across sessions
- `--project`: Search project-specific memories
### Options
- `--no-profile`: Skip fetching the user profile summary (included by default)
## Examples
- User asks "what did I work on yesterday":
```bash
node ~/.codex/supermemory/search-memory.js "work yesterday recent activity"
```
- User asks "how did we implement auth" (project-specific):
```bash
node ~/.codex/supermemory/search-memory.js --project "authentication implementation"
```
- User asks "what are my coding preferences":
```bash
node ~/.codex/supermemory/search-memory.js --user "coding preferences style"
```
## Present Results
The script outputs formatted memory results with relevance information. Present them clearly to the user and offer to search again with different terms if needed.
+1
-1
{
"name": "codex-supermemory",
"version": "1.0.3",
"version": "1.0.5",
"description": "Persistent memory for OpenAI Codex CLI — powered by Supermemory",

@@ -5,0 +5,0 @@ "type": "module",

@@ -46,3 +46,3 @@ # codex-supermemory

Codex CLI supports a hooks system that lets external scripts run at specific
lifecycle events. `codex-supermemory` registers one hook:
lifecycle events. `codex-supermemory` registers two hooks:

@@ -52,6 +52,8 @@ | Hook | Event | What it does |

| `recall` | `UserPromptSubmit` | Captures new turns (every N prompts), then searches Supermemory for relevant memories and your profile, injecting them into the prompt as `additionalContext`. |
| `flush` | `Stop` | Captures any remaining turns at session end so the final conversation turns are never lost. |
**Incremental capture**: Memories are saved every N turns (default: 3) during the session.
This means memories from earlier in your session are immediately available for recall
in the same session.
in the same session. The flush hook ensures any trailing turns are captured when the
session ends.

@@ -61,3 +63,3 @@ The installer:

- Enables the `codex_hooks` feature flag in `~/.codex/config.toml`
- Registers the hook in `~/.codex/hooks.json`
- Registers the hooks in `~/.codex/hooks.json`
- Copies pre-bundled hook scripts to `~/.codex/supermemory/`

@@ -64,0 +66,0 @@ - Installs skills to `~/.codex/skills/`