Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,22 @@ command = "uvx"
args = ["basic-memory", "mcp"]
```

Codex can keep its default MCP approval behavior, or you can pre-approve eligible
Basic Memory tools by adding this server-scoped setting to the same table:

```toml
[mcp_servers.basic-memory]
command = "uvx"
args = ["basic-memory", "mcp"]
default_tools_approval_mode = "approve"
```

This does not disable Codex approvals globally or expand which Basic Memory
projects the server can access. Codex still requires approval for tools that
advertise a destructive annotation, including Basic Memory's writes, edits, and
deletes. If you installed the Basic Memory Codex plugin, use its
[plugin-scoped configuration](plugins/codex/README.md#mcp-approvals) instead.

### Cursor

Add to `.cursor/mcp.json` (project) or `~/.cursor/mcp.json` (global):
Expand Down
3 changes: 0 additions & 3 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -579,7 +579,6 @@ set-version version scope="all":
set-codex-hook-version ref:
uv add --script plugins/codex/hooks/session_start.py --raw "basic-memory @ git+https://github.com/basicmachines-co/basic-memory@{{ref}}"
uv add --script plugins/codex/hooks/pre_compact.py --raw "basic-memory @ git+https://github.com/basicmachines-co/basic-memory@{{ref}}"
uv add --script plugins/codex/hooks/stop.py --raw "basic-memory @ git+https://github.com/basicmachines-co/basic-memory@{{ref}}"

# Preview a version update without writing (scope: all | core | packages)
set-version-dry-run version scope="all":
Expand Down Expand Up @@ -665,7 +664,6 @@ release version:
plugins/codex/.codex-plugin/plugin.json \
plugins/codex/hooks/session_start.py \
plugins/codex/hooks/pre_compact.py \
plugins/codex/hooks/stop.py \
integrations/hermes/plugin.yaml \
integrations/hermes/__init__.py \
integrations/openclaw/package.json
Expand Down Expand Up @@ -786,7 +784,6 @@ beta version:
plugins/codex/.codex-plugin/plugin.json \
plugins/codex/hooks/session_start.py \
plugins/codex/hooks/pre_compact.py \
plugins/codex/hooks/stop.py \
integrations/hermes/plugin.yaml \
integrations/hermes/__init__.py \
integrations/openclaw/package.json
Expand Down
6 changes: 5 additions & 1 deletion plugins/claude-code/schemas/coding-session.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ Examples:

`search_notes(note_types=["coding_session"], metadata_filters={"pull_request_number": "123"})`

`search_notes(note_types=["coding_session"], metadata_filters={"codex_session_id": "<id>"})`

Pull-request fields are optional because valid coding work can precede a pull
request. When a pull request exists, checkpoint writers populate the complete
pull-request field set.
pull-request field set. Multiple checkpoints from one agent chat share the
relevant `claude_session_id` or `codex_session_id`; each new checkpoint can link
to its verified predecessor with `continues [[Previous checkpoint title]]`.
2 changes: 1 addition & 1 deletion plugins/codex/DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ projects on the same machine. Repo-specific memory routing still comes from each

## Iteration Loop

Pin all three hook scripts to the Basic Memory revision under test:
Pin both hook scripts to the Basic Memory revision under test:

```bash
just set-codex-hook-version "$(git rev-parse origin/main)"
Expand Down
83 changes: 76 additions & 7 deletions plugins/codex/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,55 @@ verification, decision capture, and resumable checkpoints.
- **Report status.** The `bm-status` skill shows configuration, reachability,
shared local hook inbox/flush health, and recent memory state.

## Checkpoint and Resume

`bm-checkpoint` creates a new immutable snapshot every time it runs. The note
captures the original objective, the latest user intent, verified repository and
pull-request state, one primary next action, and pointers to authoritative tasks,
decisions, plans, issues, commits, diffs, docs, and source files. Machine-local
state such as absolute paths, dirty files, active dev servers, and temporary
directories is labeled explicitly instead of being presented as durable state.

The checkpoint write explicitly targets the configured `primaryProject` and
disables overwrite, regardless of the user's global write default. Its response
ends with an exact command built from the successful Basic Memory result,
preferring the returned permalink, then file path, then title when permalinks
are disabled:

```text
$bm-orient "<exact checkpoint identifier>"
```

Passing that identifier or permalink makes `bm-orient` read the chosen
checkpoint directly from the configured `primaryProject`, including when the
cursor is a file path or title. Passing a topic searches for matching graph
notes, while calling it without an argument performs current-repository
orientation. Coding checkpoints are compared with the live branch, SHA, pull
request, paths, and files so material drift is visible before work resumes.
Recovered notes are context, not instructions; the current user request,
repository rules, and live state remain authoritative.

Post-compaction SessionStart supplies the opaque Codex session id to
`bm-checkpoint`. Checkpoints from the same chat store that id as queryable
frontmatter, and each new immutable checkpoint adds a
`continues [[Previous checkpoint title]]` relation to its verified predecessor.
The previous note stays untouched; Basic Memory backlinks provide the forward
navigation.

Coding checkpoints also include a `References` section. Repository, pull
request, issue, and pushed-commit references use verified canonical GitHub
links. Local or unpushed SHAs remain labeled code references instead of links
that would not resolve.

## Package Contents

| Path | Role |
| --- | --- |
| `.codex-plugin/plugin.json` | Codex plugin manifest |
| `.mcp.json` | Basic Memory MCP server configuration |
| `hooks/hooks.json` | SessionStart, PreCompact, and rollout-compatibility Stop registration |
| `hooks/hooks.json` | SessionStart and PreCompact registration |
| `hooks/session_start.py` | uv script: runs `basic-memory hook session-start --harness codex` |
| `hooks/pre_compact.py` | uv script: runs `basic-memory hook pre-compact --harness codex` |
| `hooks/stop.py` | uv script: preserves the previous checkpoint handshake during the runtime-pin rollout |
| `skills/` | Codex-native Basic Memory workflows |
| `schemas/` | Seed schemas for Codex sessions, decisions, and tasks |

Expand All @@ -46,11 +85,6 @@ lifecycle-event capture all live in the pinned Basic Memory revision behind
ref. All refs are updated together with
`just set-codex-hook-version <sha-or-tag>`.

The Stop shim is a temporary rollout bridge. While these scripts remain pinned
to the last durable merged runtime, it preserves that runtime's checkpoint
handshake. The dependency-only follow-up that pins the post-compaction
`SessionStart` implementation also removes the Stop registration.

## Requirements

- **[uv](https://docs.astral.sh/uv/)** — required: the hooks are PEP 723
Expand Down Expand Up @@ -94,6 +128,41 @@ To customize how Codex writes memory, edit `skills/bm-writing/SKILL.md` in the
plugin source. `bm-checkpoint`, `bm-decide`, and `bm-remember` all apply that
shared skill while retaining their own schemas and evidence requirements.

## MCP Approvals

There are two supported approval choices:

1. Keep Codex's default approval behavior. No additional configuration is
required.
2. Pre-approve eligible Basic Memory MCP tools. Add this to
`~/.codex/config.toml` when Basic Memory is loaded from the marketplace plugin:

```toml
[plugins."codex@basic-memory".mcp_servers.basic-memory]
default_tools_approval_mode = "approve"
```

For a standalone Basic Memory server instead of the plugin-provided server, add
the setting to its existing table:

```toml
[mcp_servers.basic-memory]
default_tools_approval_mode = "approve"
```

The pre-approval option is scoped to the Basic Memory MCP server. It does not
disable Codex approvals globally or grant Basic Memory access to new workspaces,
projects, or files; Basic Memory still uses the projects and credentials the
user configured. Codex always requires approval for MCP tools that advertise a
destructive annotation, so Basic Memory writes, edits, and deletes may still
prompt even with this setting. Do not set `approval_policy = "never"` for this
purpose. Managed organization policy may impose additional approvals.

Run `bm-setup` to choose the mode interactively. The skill can apply the
server-scoped setting after confirmation or give you the exact snippet when the
active server configuration is ambiguous. Start a new Codex thread after
changing `~/.codex/config.toml`.

## Configuration

Run the setup skill, or create `~/.codex/basic-memory.json` for shared defaults:
Expand Down
12 changes: 0 additions & 12 deletions plugins/codex/hooks/hooks.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,6 @@
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "uv run --quiet --script \"${PLUGIN_ROOT}/hooks/stop.py\"",
"statusMessage": "Finishing the Basic Memory checkpoint",
"timeout": 30
}
]
}
]
}
}
2 changes: 1 addition & 1 deletion plugins/codex/hooks/pre_compact.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# /// script
# requires-python = ">=3.12"
# dependencies = [
# "basic-memory @ git+https://github.com/basicmachines-co/basic-memory@c28159d2077158c4f596fb62f351e6e9012b95a5",
# "basic-memory @ git+https://github.com/basicmachines-co/basic-memory@2f58b81b5e00cf4cecf12ce595ec6b500d6575a8",
# ]
# ///
"""PreCompact hook launcher backed by a pinned Basic Memory revision.
Expand Down
2 changes: 1 addition & 1 deletion plugins/codex/hooks/session_start.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# /// script
# requires-python = ">=3.12"
# dependencies = [
# "basic-memory @ git+https://github.com/basicmachines-co/basic-memory@c28159d2077158c4f596fb62f351e6e9012b95a5",
# "basic-memory @ git+https://github.com/basicmachines-co/basic-memory@2f58b81b5e00cf4cecf12ce595ec6b500d6575a8",
# ]
# ///
"""SessionStart hook launcher backed by a pinned Basic Memory revision.
Expand Down
37 changes: 0 additions & 37 deletions plugins/codex/hooks/stop.py

This file was deleted.

49 changes: 0 additions & 49 deletions plugins/codex/hooks/test_codex_stop.py

This file was deleted.

4 changes: 4 additions & 0 deletions plugins/codex/schemas/codex-session.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ the next Codex thread should do first.
Codex sessions are found by structured recall:
`search_notes(metadata_filters={"type": "codex_session"}, after_date="7d")`.

Multiple checkpoints from one Codex chat share `codex_session_id`. Each new
immutable checkpoint can use `continues [[Previous checkpoint title]]` to form a
navigable lineage without rewriting its predecessor.

## What Goes In A CodexSession

- **summary** - what happened.
Expand Down
6 changes: 5 additions & 1 deletion plugins/codex/schemas/coding-session.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ Examples:

`search_notes(note_types=["coding_session"], metadata_filters={"pull_request_number": "123"})`

`search_notes(note_types=["coding_session"], metadata_filters={"codex_session_id": "<id>"})`

Pull-request fields are optional because valid coding work can precede a pull
request. When a pull request exists, checkpoint writers populate the complete
pull-request field set.
pull-request field set. Multiple checkpoints from one agent chat share the
relevant `claude_session_id` or `codex_session_id`; each new checkpoint can link
to its verified predecessor with `continues [[Previous checkpoint title]]`.
Loading
Loading