memoryrouter-codex 1.8.0 → 1.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/bin/cli.cjs +1 -1
- package/lib/installer.cjs +15 -5
- package/lib/managed.cjs +2 -2
- package/package.json +1 -1
- package/runtime/constants.cjs +1 -1
package/README.md
CHANGED
|
@@ -34,7 +34,7 @@ MemoryRouter is the **cross-machine, cross-tool, team-shareable, and auditable**
|
|
|
34
34
|
- Node.js 18 or newer.
|
|
35
35
|
- **Codex 0.145.0 or newer** for the complete lifecycle-hook integration. Version 0.146.0 was tested directly.
|
|
36
36
|
- Local Codex CLI, ChatGPT desktop app's local Codex host, and Codex IDE extension share `config.toml` MCP configuration.
|
|
37
|
-
- Hooks must be trusted once: Codex app **
|
|
37
|
+
- Hooks must be trusted once: in the Codex app open a **New chat**, click the hooks icon next to **Ask for approval** in the message box, then **Allow all**; in the CLI, `/hooks`. OAuth (`mcp_tool`) hooks need a Codex build with MCP tool hooks (the current app and CLI 0.166 have them).
|
|
38
38
|
- Project `.codex` config is loaded only for trusted projects.
|
|
39
39
|
- ChatGPT web does **not** read a laptop's `~/.codex/config.toml` or local hooks. Use MemoryRouter's hosted plugin/connector surface there.
|
|
40
40
|
- Codex cloud environments do not automatically inherit host-local user config or secrets. A project-scope install can travel with a repository, but the environment still needs Node, project trust, package/network availability for the stdio fallback, and `MEMORYROUTER_API_KEY` for hooks.
|
|
@@ -48,9 +48,9 @@ There is no dependency on the obsolete `experimental_use_rmcp_client` setting in
|
|
|
48
48
|
1. Add the server in the app: **Settings > Plugins > Add > Add MCP server**, Type **Streamable HTTP**, Name `memoryrouter`, URL `https://mcp.memoryrouter.ai/mcp`, **Save**, then **Authenticate** and sign in (or create an account) in the browser tab that opens.
|
|
49
49
|
2. In a Codex chat, paste:
|
|
50
50
|
|
|
51
|
-
> Run `npx -y memoryrouter-codex@latest init` with network access, then tell me to trust the MemoryRouter hooks
|
|
51
|
+
> Run `npx -y memoryrouter-codex@latest init` with network access, then tell me to trust the MemoryRouter hooks.
|
|
52
52
|
|
|
53
|
-
Then
|
|
53
|
+
Approve the internet access Codex asks for. Then open a **New chat**, click the hooks icon next to **Ask for approval** in the message box, and choose **Allow all** for the three MemoryRouter hooks (Recalling MemoryRouter context, Searching MemoryRouter, Saving to MemoryRouter).
|
|
54
54
|
|
|
55
55
|
`init` keeps the server the app added (and its sign-in), adds the three `mcp_tool` hooks to `~/.codex/hooks.json` and the MemoryRouter guidance to `~/.codex/AGENTS.md`. The Codex CLI and IDE extension on the same Mac share all of it.
|
|
56
56
|
|
package/bin/cli.cjs
CHANGED
|
@@ -134,7 +134,7 @@ async function main() {
|
|
|
134
134
|
process.stdout.write('\nAutomatic memory: before every prompt Codex searches your vault and adds what it finds as context; after every turn it saves your message and its final response (never tool calls, tool output or intermediate steps). No API key needed.\n');
|
|
135
135
|
process.stdout.write('\nNext:\n');
|
|
136
136
|
if (!result.adoptedServer) process.stdout.write(' 1. Sign in: Codex app Settings > Plugins > memoryrouter > Authenticate (or run: codex mcp login memoryrouter)\n');
|
|
137
|
-
process.stdout.write(` ${result.adoptedServer ? '1' : '2'}. Trust the MemoryRouter hooks once: Codex app
|
|
137
|
+
process.stdout.write(` ${result.adoptedServer ? '1' : '2'}. Trust the MemoryRouter hooks once: Codex app: open a New chat, click the hooks icon next to "Ask for approval", Allow all (CLI: /hooks)\n`);
|
|
138
138
|
process.stdout.write(` ${result.adoptedServer ? '2' : '3'}. Start a New chat\n`);
|
|
139
139
|
} else if (result.auth === 'oauth') {
|
|
140
140
|
const pick = binding && binding.vault ? ` and select the vault ${vaultLabel(binding)} (the one your hooks use)` : '';
|
package/lib/installer.cjs
CHANGED
|
@@ -117,10 +117,19 @@ function init(options = {}) {
|
|
|
117
117
|
agentsFile: options.agents === false ? null : layout.agentsFile,
|
|
118
118
|
runtimeDir: layout.runtimeDir,
|
|
119
119
|
};
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
120
|
+
// The manifest is bookkeeping only (nothing reads it to run hooks). Inside
|
|
121
|
+
// the Codex app's sandbox, writes outside CODEX_HOME need an extra approval,
|
|
122
|
+
// so a blocked write must never fail an otherwise complete install.
|
|
123
|
+
let manifestWritten = true;
|
|
124
|
+
try {
|
|
125
|
+
const manifestDir = path.join(dataHome(options.env), 'installations');
|
|
126
|
+
fs.mkdirSync(manifestDir, { recursive: true, mode: 0o700 });
|
|
127
|
+
const manifestName = Buffer.from(`${layout.scope}:${layout.root}`).toString('base64url');
|
|
128
|
+
fs.writeFileSync(path.join(manifestDir, `${manifestName}.json`), `${JSON.stringify(manifest, null, 2)}\n`, { mode: 0o600 });
|
|
129
|
+
} catch (error) {
|
|
130
|
+
if (options.apiKey) throw error;
|
|
131
|
+
manifestWritten = false;
|
|
132
|
+
}
|
|
124
133
|
return {
|
|
125
134
|
layout,
|
|
126
135
|
auth,
|
|
@@ -128,6 +137,7 @@ function init(options = {}) {
|
|
|
128
137
|
serverName,
|
|
129
138
|
adoptedServer,
|
|
130
139
|
results,
|
|
140
|
+
manifestWritten,
|
|
131
141
|
automaticMemory: options.hooks !== false && (hookMode === 'mcp' || Boolean(options.apiKey || getApiKey(env, loadConfig(options.env)))),
|
|
132
142
|
keySource: options.apiKey ? 'codex-config' : apiKeySource(env, loadConfig(options.env)),
|
|
133
143
|
};
|
|
@@ -223,7 +233,7 @@ async function doctor(options = {}) {
|
|
|
223
233
|
? Object.values(mcpManagedGroups()).flat().flatMap(group => group.hooks || []).length
|
|
224
234
|
: Object.values(managedGroups(layout.runtimeDir, layout.scope)).flat().flatMap(group => group.hooks || []).length;
|
|
225
235
|
addCheck(checks, 'hooks', owned.length === expectedOwned ? 'pass' : 'error', owned.length
|
|
226
|
-
? `${owned.length} of ${expectedOwned} managed lifecycle hooks found${mcpHooks.length ? ' (over the signed-in MCP connection, no API key needed)' : ''}. Trust them once
|
|
236
|
+
? `${owned.length} of ${expectedOwned} managed lifecycle hooks found${mcpHooks.length ? ' (over the signed-in MCP connection, no API key needed)' : ''}. Trust them once: Codex app New chat > hooks icon by "Ask for approval" > Allow all; CLI: /hooks.`
|
|
227
237
|
: 'Managed lifecycle hooks are missing or hooks.json is invalid.');
|
|
228
238
|
addCheck(checks, 'agents', agentsText.includes(AGENTS_START) ? 'pass' : 'warn', agentsText.includes(AGENTS_START) ? 'Managed AGENTS.md guidance is present.' : 'Managed AGENTS.md guidance is missing.');
|
|
229
239
|
|
package/lib/managed.cjs
CHANGED
|
@@ -151,9 +151,9 @@ function uninstallToml(file) {
|
|
|
151
151
|
|
|
152
152
|
function agentsBlock(options = {}) {
|
|
153
153
|
const automatic = options.hookMode === 'mcp'
|
|
154
|
-
? '- Automatic hooks (over the signed-in MemoryRouter connection) search the vault before each prompt and add what they find as context, then save each completed turn: the user\'s message and your final response only, never tool calls, tool output or intermediate steps.\n'
|
|
154
|
+
? '- Automatic hooks (over the signed-in MemoryRouter connection) search the vault before each prompt and add what they find as context ("MemoryRouter recalled this for the current message"), then save each completed turn: the user\'s message and your final response only, never tool calls, tool output or intermediate steps.\n'
|
|
155
155
|
: '- Automatic hooks search the vault before each prompt and save each completed turn (the user\'s message and your final response only) when a MemoryRouter API key is configured.\n';
|
|
156
|
-
return `## MemoryRouter memory\n\n- MemoryRouter is the durable cross-machine, cross-tool, and team/auditable memory layer. Codex native Memories may remain enabled as the local personal recall layer.\n${automatic}-
|
|
156
|
+
return `## MemoryRouter memory\n\n- MemoryRouter is the durable cross-machine, cross-tool, and team/auditable memory layer. Codex native Memories may remain enabled as the local personal recall layer.\n${automatic}- If the recalled context already answers the question, answer from it directly; do not search again. Call MemoryRouter search only when nothing relevant was recalled or you need more detail about prior decisions, preferences, incidents, or unfinished work. Depending on auth mode, the tool is named \`search_memories\` or \`memory_search\`.\n- Store only concise, durable decisions, preferences, facts, and incident outcomes. Depending on auth mode, use \`store_memory\` or \`memory_store\`. Do not duplicate a completed turn that hooks already captured.\n- Keep and cite returned \`mrh_...\` handles when a specific memory must be referenced later.\n- Project scope is derived from the canonical git remote when available, so worktrees and machines share identity without uploading local paths. It is the same project memory Claude Code uses through memoryrouter-claude, so decisions made in either agent are available in both.\n- If MemoryRouter is offline, continue the task without memory; never block work on recall or capture.`;
|
|
157
157
|
}
|
|
158
158
|
|
|
159
159
|
function installAgents(file, options = {}) {
|
package/package.json
CHANGED
package/runtime/constants.cjs
CHANGED