opencode-codex-memory 0.3.1 → 0.4.1
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 +199 -69
- package/dist/src/codex-interop.d.ts +38 -0
- package/dist/src/codex-interop.js +316 -0
- package/dist/src/db.js +17 -11
- package/dist/src/git-baseline.js +22 -0
- package/dist/src/index.d.ts +6 -0
- package/dist/src/index.js +87 -44
- package/dist/src/llm.js +5 -0
- package/dist/src/options.d.ts +30 -0
- package/dist/src/options.js +31 -0
- package/dist/src/path-guard.d.ts +2 -0
- package/dist/src/path-guard.js +17 -0
- package/dist/src/phase1.js +1 -1
- package/dist/src/phase2.d.ts +4 -1
- package/dist/src/phase2.js +39 -9
- package/dist/src/store.d.ts +2 -2
- package/dist/src/store.js +18 -6
- package/dist/src/workspace.js +25 -20
- package/dist/tools/control.js +51 -1
- package/dist/tools/memory.js +3 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,38 +1,39 @@
|
|
|
1
|
-
#
|
|
1
|
+
# OpenCode Codex Memory
|
|
2
2
|
|
|
3
|
-
Persistent memory for [
|
|
3
|
+
Persistent memory for [OpenCode](https://opencode.ai): your agent remembers what
|
|
4
4
|
it learned in past sessions — your conventions, your projects, the decisions you
|
|
5
5
|
made — and brings that context into new conversations automatically.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
`~/.local/share/opencode/`.
|
|
10
|
-
|
|
11
|
-
Despite the name: **no codex subscription or OpenAI account is needed.** This
|
|
12
|
-
project ports the memory *design* from OpenAI's codex to opencode. It works out
|
|
7
|
+
Despite the name: **no Codex subscription or OpenAI account is needed.** This
|
|
8
|
+
project is a faithful port of the memory system in OpenAI's Codex. It works out
|
|
13
9
|
of the box with zero extra configuration and uses whatever models you already
|
|
14
|
-
have set up in
|
|
10
|
+
have set up in OpenCode.
|
|
11
|
+
|
|
12
|
+
**Local-first by design.** Memory is plain markdown files plus a small SQLite
|
|
13
|
+
database on your own machine — no memory service to sign up for, no MCP server,
|
|
14
|
+
no separate process, no sync. Installing it is one line in your `opencode.json`;
|
|
15
|
+
from there everything lives under `~/.local/share/opencode/`, so you can read it,
|
|
16
|
+
grep it, edit it, or delete it like anything else you own. Nothing leaves your
|
|
17
|
+
machine beyond the model calls OpenCode already makes.
|
|
18
|
+
|
|
19
|
+
If you *do* also use the Codex CLI: the plugin can share memory with Codex in
|
|
20
|
+
both directions — what one assistant learns on your machine, the other picks
|
|
21
|
+
up. Off by default, one config flag per direction; see
|
|
22
|
+
[Sharing memory with the Codex CLI](#sharing-memory-with-the-codex-cli).
|
|
15
23
|
|
|
16
24
|
## Why
|
|
17
25
|
|
|
18
|
-
By default every
|
|
26
|
+
By default every OpenCode session starts from zero. You re-explain your build
|
|
19
27
|
commands, your code style, and the quirks of each repo over and over.
|
|
20
28
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
- **It consolidates.** Periodically it merges those notes into a compact,
|
|
27
|
-
searchable memory, pruning what's stale.
|
|
28
|
-
- **It remembers at the right time.** A short summary is injected into the system
|
|
29
|
-
prompt, and the agent can search the full memory on demand when a task looks
|
|
30
|
-
related to past work.
|
|
31
|
-
- **It self-corrects.** When the agent actually uses a memory it cites the source,
|
|
32
|
-
so useful memories rank higher over time and unused ones fade.
|
|
29
|
+
This plugin closes that loop. It reviews finished sessions in the
|
|
30
|
+
background, keeps what's durable — your preferences, how a repo is built, what
|
|
31
|
+
worked and what didn't — and puts that context back in front of the agent in
|
|
32
|
+
later conversations. You don't manage any of it; OpenCode just gets more useful
|
|
33
|
+
the more you use it.
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
If you want the mental model before the details, jump to
|
|
36
|
+
[How it works](#how-it-works).
|
|
36
37
|
|
|
37
38
|
## Install
|
|
38
39
|
|
|
@@ -40,19 +41,37 @@ anything.
|
|
|
40
41
|
|
|
41
42
|
```json
|
|
42
43
|
{
|
|
43
|
-
"plugin": ["opencode-codex-memory"]
|
|
44
|
+
"plugin": ["opencode-codex-memory@0.4.1"]
|
|
44
45
|
}
|
|
45
46
|
```
|
|
46
47
|
|
|
48
|
+
**Pin the version** (here and for any OpenCode plugin). OpenCode installs a
|
|
49
|
+
plugin spec once into its package cache and never re-resolves it, so a bare
|
|
50
|
+
`"opencode-codex-memory"` is not "always latest" — it freezes at whatever
|
|
51
|
+
was latest the first time OpenCode started. With a version tag you decide
|
|
52
|
+
which release runs, and bumping the tag installs the new one. Check
|
|
53
|
+
[npm](https://www.npmjs.com/package/opencode-codex-memory) for the current
|
|
54
|
+
version.
|
|
55
|
+
|
|
56
|
+
Since updating is then just editing version numbers, it's worth automating
|
|
57
|
+
with a custom command — one that reads your `opencode.json`, compares each
|
|
58
|
+
pin against npm, and rewrites the ones you confirm. If you'd rather not
|
|
59
|
+
write your own, this repo has one you can copy:
|
|
60
|
+
[`docs/commands/update-plugins.md`](./docs/commands/update-plugins.md) →
|
|
61
|
+
`~/.config/opencode/command/update-plugins.md`, then run `/update-plugins`.
|
|
62
|
+
It's documentation, not part of the package: nothing about it is installed
|
|
63
|
+
with the plugin, and it works for every pinned plugin in your config, not
|
|
64
|
+
just this one.
|
|
65
|
+
|
|
47
66
|
(While developing locally, point it at an absolute path to your checkout
|
|
48
67
|
instead of the package name.)
|
|
49
68
|
|
|
50
69
|
2. That's it. The memory workspace is created on first use. Installing the
|
|
51
70
|
plugin is the opt-in: background learning and summary injection are active
|
|
52
|
-
immediately (
|
|
71
|
+
immediately (Codex ships the same system behind a default-off feature flag
|
|
53
72
|
with a consent prompt; a standalone memory plugin *is* the consent).
|
|
54
73
|
|
|
55
|
-
Requires
|
|
74
|
+
Requires OpenCode 1.18 or newer (official release). Git is bundled
|
|
56
75
|
(`isomorphic-git`) — no `git` binary or any other external tool needed.
|
|
57
76
|
|
|
58
77
|
The two restricted sub-agents that do the background learning (`memorize`,
|
|
@@ -66,11 +85,11 @@ override `memorize`, keep an `external_directory` allow for
|
|
|
66
85
|
`~/.local/share/opencode/memories/*` (e.g.
|
|
67
86
|
`"external_directory": { "$HOME/.local/share/opencode/memories/*": "allow" }`
|
|
68
87
|
after the wildcard deny) — the memory folder lives outside your project, and
|
|
69
|
-
without that grant
|
|
88
|
+
without that grant OpenCode blocks the consolidator's file access.
|
|
70
89
|
|
|
71
90
|
## Try it
|
|
72
91
|
|
|
73
|
-
Just use
|
|
92
|
+
Just use OpenCode normally. Sessions that have been idle for a few hours get
|
|
74
93
|
reviewed in the background and memory starts building up — you don't have to do
|
|
75
94
|
anything. Come back the next day and ask something like *"what do you know about how I
|
|
76
95
|
work?"* or *"what was I doing in this repo?"* and the agent draws on what it
|
|
@@ -91,11 +110,59 @@ echo 'I prefer TypeScript strict mode and 2-space indentation.' \
|
|
|
91
110
|
> ~/.local/share/opencode/memories/memory_summary.md
|
|
92
111
|
```
|
|
93
112
|
|
|
113
|
+
## How it works
|
|
114
|
+
|
|
115
|
+
You don't need to know any of this to use the plugin. The design is Codex's,
|
|
116
|
+
ported as-is, and it does what any memory system has to do: decide what's worth
|
|
117
|
+
keeping, write it down so it can be found again, surface the right piece at the
|
|
118
|
+
right moment, and forget what stopped being useful.
|
|
119
|
+
|
|
120
|
+
Think of it as three jobs: two background writers and one reader. **Nothing here
|
|
121
|
+
runs while you're waiting for a reply** — an assistant that stops to take notes
|
|
122
|
+
mid-answer would be slower and more expensive, so the learning happens after the
|
|
123
|
+
fact, on transcripts of conversations that are already over.
|
|
124
|
+
|
|
125
|
+
**Phase 1 — read one finished session, write notes about it.** Once a
|
|
126
|
+
conversation has been idle long enough that it's clearly done (default 6 h), the
|
|
127
|
+
plugin fetches that transcript, strips secrets out of it, and hands it to a
|
|
128
|
+
cheap model with one question: *what from this is worth keeping?* The answer
|
|
129
|
+
comes back as structured data — a detailed note plus a short recap of the
|
|
130
|
+
session — and lands in a local SQLite database. One session in, one record out.
|
|
131
|
+
Sessions are independent, so this part is easy to parallelize and to retry when
|
|
132
|
+
it fails.
|
|
133
|
+
|
|
134
|
+
**Phase 2 — merge all those notes into one memory.** Every few hours at most
|
|
135
|
+
(and only one run at a time across all your OpenCode windows), a second pass
|
|
136
|
+
takes the most relevant per-session notes and rewrites the actual memory files:
|
|
137
|
+
`MEMORY.md` as the full index, `memory_summary.md` as the short version, and
|
|
138
|
+
`skills/` for procedures worth repeating. This is where the interesting work
|
|
139
|
+
happens — ten similar observations collapse into one rule, contradictions get
|
|
140
|
+
resolved, and notes nothing ever used age out. Forgetting is a feature: memory
|
|
141
|
+
that only grows is memory that stops being useful.
|
|
142
|
+
|
|
143
|
+
The split exists because the two halves have opposite needs. Phase 1 is
|
|
144
|
+
per-session and can run many at once; phase 2 touches the single shared memory,
|
|
145
|
+
so it has to be serialized. Keeping them apart means one slow or failing session
|
|
146
|
+
extraction can't corrupt or block the shared store.
|
|
147
|
+
|
|
148
|
+
**The read path — actually remembering.** Every turn, the short summary is
|
|
149
|
+
appended to the system prompt (capped at ~2500 tokens, so the cost is small and
|
|
150
|
+
predictable). That's the always-on layer. When a task looks related to past
|
|
151
|
+
work, the agent goes further and searches the full memory itself with the
|
|
152
|
+
`memory_*` tools — the equivalent of "I've seen this before, let me look it up"
|
|
153
|
+
rather than carrying everything around all the time.
|
|
154
|
+
|
|
155
|
+
**The feedback loop.** When the agent uses a memory, it cites it. The citation
|
|
156
|
+
is recorded and then stripped before it reaches your screen, and those usage
|
|
157
|
+
counts feed back into phase 2's ranking. Memories that keep proving useful get
|
|
158
|
+
kept and sharpened; memories nothing has touched in a month drop out. The system
|
|
159
|
+
finds out which of its own notes were worth writing.
|
|
160
|
+
|
|
94
161
|
## Where your data lives
|
|
95
162
|
|
|
96
163
|
```
|
|
97
164
|
~/.local/share/opencode/
|
|
98
|
-
├── memory.db # the plugin's own database (
|
|
165
|
+
├── memory.db # the plugin's own database (OpenCode's data is only accessed via its API)
|
|
99
166
|
└── memories/
|
|
100
167
|
├── memory_summary.md # compact summary injected into the system prompt
|
|
101
168
|
├── MEMORY.md # searchable index of everything learned
|
|
@@ -104,7 +171,7 @@ echo 'I prefer TypeScript strict mode and 2-space indentation.' \
|
|
|
104
171
|
└── extensions/ad_hoc/notes/ # things you explicitly asked it to remember
|
|
105
172
|
```
|
|
106
173
|
|
|
107
|
-
The location follows
|
|
174
|
+
The location follows OpenCode's own data directory — `$XDG_DATA_HOME/opencode`
|
|
108
175
|
when that's set, otherwise `~/.local/share/opencode` (same resolution on macOS,
|
|
109
176
|
Linux, and Windows).
|
|
110
177
|
|
|
@@ -115,8 +182,12 @@ those too.)
|
|
|
115
182
|
|
|
116
183
|
## Privacy & safety
|
|
117
184
|
|
|
118
|
-
- **Local only.**
|
|
119
|
-
|
|
185
|
+
- **Local only.** There is no remote storage option to enable, by accident or
|
|
186
|
+
otherwise: Codex keeps memory storage behind a backend interface whose only
|
|
187
|
+
implementation today is the local filesystem, and this port implements that
|
|
188
|
+
path and nothing else. Nothing is sent anywhere except through your existing
|
|
189
|
+
OpenCode provider, using your existing credentials; the plugin holds no keys
|
|
190
|
+
of its own.
|
|
120
191
|
- **Secrets are redacted** (API keys, tokens, private keys, passwords) from
|
|
121
192
|
session transcripts and extracted memories before anything is written or sent
|
|
122
193
|
to a model. Notes you explicitly dictate ("remember that ...") are stored as
|
|
@@ -128,14 +199,14 @@ those too.)
|
|
|
128
199
|
- **Reset is safe.** `memory_reset` refuses to run if the memory folder is a
|
|
129
200
|
symlink, so it can't be tricked into deleting something else.
|
|
130
201
|
- **Web/MCP sessions:** by default, sessions that used web search, fetch, or MCP
|
|
131
|
-
tools are still eligible for memory (matching
|
|
202
|
+
tools are still eligible for memory (matching Codex). If you'd rather exclude
|
|
132
203
|
them so scraped or external content can't enter your memory, set
|
|
133
204
|
`disable_on_external_context: true`.
|
|
134
205
|
|
|
135
206
|
## Configuration
|
|
136
207
|
|
|
137
208
|
Optional plugin options (all have sensible defaults). Names and defaults match
|
|
138
|
-
|
|
209
|
+
Codex's `[memories]` config so the two stay easy to compare:
|
|
139
210
|
|
|
140
211
|
| Option | Default | Meaning |
|
|
141
212
|
|---|---|---|
|
|
@@ -143,84 +214,143 @@ codex's `[memories]` config so the two stay easy to compare:
|
|
|
143
214
|
| `use_memories` | `true` | Inject the memory summary into the system prompt |
|
|
144
215
|
| `dedicated_tools` | `true` | Expose the `memory_read`/`memory_search`/`memory_list`/`memory_add_note` tools |
|
|
145
216
|
| `disable_on_external_context` | `false` | Exclude sessions that used web/MCP tools from memory |
|
|
146
|
-
| `extract_model` |
|
|
147
|
-
| `consolidation_model` |
|
|
217
|
+
| `extract_model` | OpenCode `small_model`, else see below | Model used for per-session extraction |
|
|
218
|
+
| `consolidation_model` | OpenCode `model`, else see below | Model used for consolidation |
|
|
148
219
|
| `max_raw_memories_for_consolidation` | `256` | How many raw memories feed each consolidation pass |
|
|
149
220
|
| `max_rollout_age_days` | `10` | Ignore sessions older than this for extraction |
|
|
150
221
|
| `min_rollout_idle_hours` | `6` | How long a session must be idle before it's eligible |
|
|
151
222
|
| `max_rollouts_per_startup` | `2` | Max sessions extracted per pass |
|
|
152
223
|
| `max_unused_days` | `30` | Prune memories unused for this long |
|
|
224
|
+
| `codex_interop` | `{ "import": false, "export": false }` | Two-way memory exchange with a local Codex CLI (see below) |
|
|
153
225
|
|
|
154
226
|
To set options, turn the plugin entry into a `[name, options]` pair:
|
|
155
227
|
|
|
156
228
|
```json
|
|
157
229
|
{
|
|
158
230
|
"plugin": [
|
|
159
|
-
["opencode-codex-memory", { "disable_on_external_context": true, "min_rollout_idle_hours": 2 }]
|
|
231
|
+
["opencode-codex-memory@0.4.1", { "disable_on_external_context": true, "min_rollout_idle_hours": 2 }]
|
|
160
232
|
]
|
|
161
233
|
}
|
|
162
234
|
```
|
|
163
235
|
|
|
164
|
-
See the [
|
|
236
|
+
See the [OpenCode plugin docs](https://opencode.ai/docs/plugins/) for details.
|
|
165
237
|
|
|
166
|
-
Numeric options are clamped to
|
|
238
|
+
Numeric options are clamped to Codex's valid ranges; unknown option keys are
|
|
167
239
|
ignored with a warning. Setting `use_memories: false` also hides the memory
|
|
168
|
-
tools, matching
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
240
|
+
tools, matching Codex's extension gating.
|
|
241
|
+
|
|
242
|
+
**Verifying your configuration:** the plugin never hard-fails on bad options.
|
|
243
|
+
To check what actually took effect, ask the agent to run `memory_inspect` — it
|
|
244
|
+
echoes the effective options (after parsing and clamping), lists warnings for
|
|
245
|
+
unknown or malformed keys (typos included), and shows the resolved Codex
|
|
246
|
+
interop state. A mistyped option shows up there twice: as a warning, and as
|
|
247
|
+
the default value appearing where you expected your setting.
|
|
248
|
+
|
|
249
|
+
Model selection mirrors Codex's cheap-extraction / capable-consolidation
|
|
250
|
+
split using OpenCode's own concepts: when `extract_model` is unset, the
|
|
251
|
+
`small_model` from your `opencode.json` is used (Codex uses `gpt-5.4-mini`);
|
|
252
|
+
when `consolidation_model` is unset, your main `model` is used (Codex uses
|
|
174
253
|
`gpt-5.4`). If neither is configured, the learning sub-agents fall back to
|
|
175
254
|
their own agent-level `model` (if you defined one), else the provider default.
|
|
176
|
-
(
|
|
255
|
+
(OpenCode's *automatic* small-model pick is internal to OpenCode and not
|
|
177
256
|
exposed to plugins — set `small_model` explicitly to get the cheap extraction
|
|
178
257
|
path.)
|
|
179
258
|
|
|
180
259
|
The full precedence per phase: plugin option (`extract_model` /
|
|
181
|
-
`consolidation_model`) →
|
|
260
|
+
`consolidation_model`) → OpenCode config (`small_model` / `model`) → a `model`
|
|
182
261
|
on your own `memorize-extract`/`memorize` agent definition, if you overrode
|
|
183
262
|
one → the provider's default model. Note that the first two pass the model
|
|
184
263
|
explicitly, so they win over an agent-level `model`.
|
|
185
264
|
|
|
186
|
-
> Note: `dedicated_tools` defaults to `true` here (
|
|
265
|
+
> Note: `dedicated_tools` defaults to `true` here (Codex defaults it to `false`).
|
|
187
266
|
> This is the one intentional default difference — the tools are a core part of a
|
|
188
|
-
> standalone memory plugin. Everything else matches
|
|
267
|
+
> standalone memory plugin. Everything else matches Codex's defaults.
|
|
189
268
|
>
|
|
190
269
|
> Turning `dedicated_tools` off keeps background learning, summary injection,
|
|
191
|
-
> and citation tracking working. The injected guidance switches to
|
|
270
|
+
> and citation tracking working. The injected guidance switches to Codex's
|
|
192
271
|
> file-based mode — the agent reads the memory files with its normal file
|
|
193
272
|
> tools and writes "remember this" notes directly into
|
|
194
273
|
> `extensions/ad_hoc/notes/`. Caveat: the memory folder lives outside your
|
|
195
|
-
> project, so
|
|
274
|
+
> project, so OpenCode raises an `external_directory` permission prompt the
|
|
196
275
|
> first time an agent touches it (allow-always covers later access); agents
|
|
197
276
|
> whose permissions deny that ask cannot use file-based mode. The dedicated
|
|
198
277
|
> tools have no such friction — that's why they are the default. The
|
|
199
278
|
> maintenance tools (`memory_reset`, `memory_inspect`, `memory_mode`) stay
|
|
200
279
|
> available either way.
|
|
201
280
|
|
|
202
|
-
|
|
281
|
+
### Sharing memory with the Codex CLI
|
|
203
282
|
|
|
204
|
-
|
|
283
|
+
If you switch between OpenCode and OpenAI's Codex CLI on the same machine, the
|
|
284
|
+
plugin can exchange consolidated memories with Codex — in either or both
|
|
285
|
+
directions:
|
|
205
286
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
like it belongs to that project" hints rather than hard partitions. This port
|
|
214
|
-
mirrors that exactly.
|
|
287
|
+
```json
|
|
288
|
+
{
|
|
289
|
+
"plugin": [
|
|
290
|
+
["opencode-codex-memory@0.4.1", { "codex_interop": { "import": true, "export": true } }]
|
|
291
|
+
]
|
|
292
|
+
}
|
|
293
|
+
```
|
|
215
294
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
295
|
+
- `import` copies Codex's consolidated `MEMORY.md` / `memory_summary.md` into a
|
|
296
|
+
memory extension (`extensions/codex_import/`) before each consolidation pass.
|
|
297
|
+
The consolidator merges what's new, tagging it `[from codex]`.
|
|
298
|
+
- `export` copies this plugin's consolidated memory into Codex's memory
|
|
299
|
+
workspace as an extension (`extensions/opencode_import/`) after each
|
|
300
|
+
successful consolidation, together with instructions for Codex's own
|
|
301
|
+
consolidator. Codex picks it up on its next consolidation — no Codex
|
|
302
|
+
configuration needed. Nothing is exported until Codex's memory feature has
|
|
303
|
+
created `$CODEX_HOME/memories`, and Codex's own files are never modified.
|
|
304
|
+
(After a `memory_reset` here, the last export stays in Codex until your
|
|
305
|
+
next successful consolidation replaces it.)
|
|
306
|
+
- `codex_home` overrides where Codex lives (default: `$CODEX_HOME`, else
|
|
307
|
+
`~/.codex`).
|
|
308
|
+
|
|
309
|
+
Both sides mark imported content with a provenance tag (`[from codex]` /
|
|
310
|
+
`[from opencode]`) and skip content carrying the other side's tag, so memories
|
|
311
|
+
don't ping-pong between the two systems. This follows the same extension
|
|
312
|
+
mechanism Codex itself uses to import Claude memories.
|
|
313
|
+
|
|
314
|
+
## Why one global memory?
|
|
315
|
+
|
|
316
|
+
There's a single store for everything you do, not one per project — and that's
|
|
317
|
+
the design choice most likely to surprise you, so it's worth explaining where it
|
|
318
|
+
came from.
|
|
319
|
+
|
|
320
|
+
Codex *started* with per-project memory: a separate bucket per directory, plus a
|
|
321
|
+
user-level scope on top. It **deliberately removed that** in early 2026 and
|
|
322
|
+
collapsed everything into one global root — one store, one lock, one
|
|
323
|
+
consolidation pass — for simplicity.
|
|
324
|
+
|
|
325
|
+
Simplicity is easy to underrate here — until you try to draw the boundaries
|
|
326
|
+
yourself. Scoping forces a question that often has no good answer: which project does
|
|
327
|
+
"prefers table-driven tests" belong to? Monorepos, worktrees, and sibling repos
|
|
328
|
+
of the same stack all blur the line, and the most valuable lessons — the ones
|
|
329
|
+
about how *you* work — belong to no project at all. Per-scope stores also each
|
|
330
|
+
consolidate over a thinner slice of evidence than the whole.
|
|
331
|
+
|
|
332
|
+
Project awareness didn't disappear; it moved out of storage and into the prompt.
|
|
333
|
+
Memories carry the project they came from, and the consolidator is told to keep
|
|
334
|
+
per-project detail separable — soft "this looks like it belongs to that project"
|
|
335
|
+
hints rather than hard partitions. You get the cross-project transfer (your
|
|
336
|
+
conventions follow you into a new repo on day one) while project-specific facts
|
|
337
|
+
stay recognizable as such.
|
|
338
|
+
|
|
339
|
+
The cost is real: with one store, an unrelated project's details can surface in
|
|
340
|
+
the summary. Codex judged that cheaper than the alternative, and this port
|
|
341
|
+
mirrors that decision rather than layering scoping back on top.
|
|
342
|
+
|
|
343
|
+
## Contributing
|
|
344
|
+
|
|
345
|
+
The port follows Codex closely: same two-phase pipeline, same on-disk artifacts,
|
|
346
|
+
same prompts (adapted only where OpenCode differs). If you want the full design
|
|
347
|
+
and the trade-offs, see [`ARCHITECTURE.md`](./ARCHITECTURE.md); contributor
|
|
348
|
+
guidance lives in [`CONTRIBUTING.md`](./CONTRIBUTING.md) and
|
|
349
|
+
[`AGENTS.md`](./AGENTS.md) — in short: this repo exists to port Codex's memory
|
|
350
|
+
system to OpenCode, and PRs that break that parity will be rejected.
|
|
221
351
|
|
|
222
352
|
## License
|
|
223
353
|
|
|
224
354
|
Apache 2.0 — the same license as [OpenAI Codex](https://github.com/openai/codex),
|
|
225
355
|
whose memory system this project ports. See [`LICENSE`](./LICENSE) and
|
|
226
|
-
[`NOTICE`](./NOTICE). Not affiliated with the
|
|
356
|
+
[`NOTICE`](./NOTICE). Not affiliated with the Codex project.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export declare const IMPORT_EXTENSION = "codex_import";
|
|
2
|
+
export declare const EXPORT_EXTENSION = "opencode_import";
|
|
3
|
+
export interface CodexInteropOptions {
|
|
4
|
+
import: boolean;
|
|
5
|
+
export: boolean;
|
|
6
|
+
codex_home?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface ResolvedCodexInterop {
|
|
9
|
+
codexMemoryRoot: string;
|
|
10
|
+
importEnabled: boolean;
|
|
11
|
+
exportEnabled: boolean;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Resolves the Codex memory root and validates it against the plugin memory
|
|
15
|
+
* root. Precedence for the Codex home: explicit option > CODEX_HOME env >
|
|
16
|
+
* `~/.codex` (codex-rs find_codex_home). Overlapping roots would let one
|
|
17
|
+
* side's sync recurse into the other's workspace, so interop fails closed
|
|
18
|
+
* (returns null) with a warning.
|
|
19
|
+
*/
|
|
20
|
+
export declare function resolveCodexInterop(opts: CodexInteropOptions): ResolvedCodexInterop | null;
|
|
21
|
+
/**
|
|
22
|
+
* Import direction: Codex consolidated memory -> our
|
|
23
|
+
* `extensions/codex_import/`. Call inside the claimed phase-2 job, after the
|
|
24
|
+
* git baseline exists (codex prepare_memory_workspace ordering) and before
|
|
25
|
+
* the workspace diff is captured, so copies are consolidated in the same run.
|
|
26
|
+
* Returns true when the plugin workspace changed.
|
|
27
|
+
*/
|
|
28
|
+
export declare function syncCodexImport(codexMemoryRoot: string): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Export direction: our consolidated memory -> Codex's
|
|
31
|
+
* `extensions/opencode_import/`. Strictly additive: never bootstraps the
|
|
32
|
+
* Codex memory workspace (missing `<codex_home>/memories` means Codex's
|
|
33
|
+
* memory feature is not in use) and never touches Codex's state DB — Codex
|
|
34
|
+
* discovers the files through its own workspace diff on its next
|
|
35
|
+
* consolidation. Only valid consolidated artifacts are exported; the seeded
|
|
36
|
+
* placeholder MEMORY.md / empty summary would just be noise.
|
|
37
|
+
*/
|
|
38
|
+
export declare function exportToCodexMemory(codexMemoryRoot: string): boolean;
|