Metadata-Version: 2.4
Name: opencode-markdown-memory
Version: 0.1.0
Summary: Install Markdown-backed memory CRUD tools for OpenCode
Project-URL: Homepage, https://pypi.org/project/opencode-markdown-memory/
Author-email: Dark Light <darklight@noreply.com>
License-Expression: Apache-2.0
License-File: LICENSE
Keywords: agent,markdown,memory,opencode
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development :: Build Tools
Requires-Python: <3.15,>=3.11
Requires-Dist: filelock<4,>=3.16
Requires-Dist: platformdirs<5,>=4
Requires-Dist: tomli-w<2,>=1.1
Description-Content-Type: text/markdown

# OpenCode Markdown Memory

`opencode-markdown-memory` installs five persistent memory tools for OpenCode. Memories
are stored as human-readable Markdown in a directory chosen by the user. The package
does not run a daemon, expose an MCP server, call a network service, create embeddings,
or record conversations automatically.

## Requirements

- Python 3.11 through 3.14
- OpenCode with Custom Tools support

OpenCode executes Custom Tool definitions as TypeScript. No separate Bun installation is
required; the generated adapter runs inside OpenCode's own runtime and invokes the
installed Python CLI with `Bun.spawn` and an argument array.

## Install the package

Using `uv`:

```console
uv tool install opencode-markdown-memory
```

Or using `pipx`:

```console
pipx install opencode-markdown-memory
```

## Install the OpenCode tools

Install globally:

```console
opencode-markdown-memory install \
  --scope global \
  --memory-dir /absolute/path/to/memories
```

Install for one project:

```console
opencode-markdown-memory install \
  --scope project \
  --target /absolute/path/to/project \
  --memory-dir /absolute/path/to/memories
```

The command prompts for missing required values when stdin is a TTY. A non-interactive
invocation with missing required values exits with status 2. Use `--yes` to skip the
interactive confirmation, `--dry-run` to show the planned paths without writing, and
`--json` for machine-readable output. `--config-dir` explicitly selects the global
OpenCode configuration directory.

Change the canonical memory base for future calls:

```console
opencode-markdown-memory configure --memory-dir /new/absolute/path
```

`configure` does not move existing memories. Move them deliberately before or after the
configuration change if migration is desired.

## OpenCode tools

The installer adds the permission rule `"markdown_memory_*": "allow"`. More specific
rules are placed after an existing catch-all, and unrelated permissions are preserved.
All five operations therefore run without another OpenCode confirmation.

| Tool | Inputs | Result |
| --- | --- | --- |
| `markdown_memory_create` | `title`, `content`, optional `tags` | Creates an entry with a UUID and UTC timestamps. |
| `markdown_memory_list` | optional `query`, `limit`, `offset` | Returns metadata and previews ordered by `updated_at`. |
| `markdown_memory_read` | `id` | Returns one complete entry. |
| `markdown_memory_update` | `id` and at least one changed field | Atomically replaces selected fields. Empty content and empty tags are valid. |
| `markdown_memory_delete` | `id` | Permanently removes one entry while retaining `MEMORY.md`. |

Tool inputs never accept a filesystem path. The configured profile determines the only
file each installed adapter can access.

## Storage layout

The canonical base directory is stored in the platform-specific user configuration file
for `opencode-markdown-memory`. `OPENCODE_MARKDOWN_MEMORY_DIR` overrides it at runtime.

```text
<base>/global/MEMORY.md
<base>/projects/<project-slug>-<sha256-12>/MEMORY.md
```

Each managed document starts with a format header and contains independently marked
entries:

```markdown
# OpenCode Memories
<!-- opencode-markdown-memory:format=1 -->

<!-- opencode-markdown-memory:550e8400-e29b-41d4-a716-446655440000
{"created_at":"2026-07-16T12:00:00.000000Z","tags":["example"],"updated_at":"2026-07-16T12:00:00.000000Z"}
-->
## Example

Free-form **Markdown** content.
<!-- /opencode-markdown-memory:550e8400-e29b-41d4-a716-446655440000 -->
```

The agent can create, replace, and permanently delete entries inside the selected file.
Deleting the last entry leaves a valid empty managed document.

## Safety properties

- A 10-second file lock serializes writers.
- Writes use a temporary file in the destination directory, `fsync`, and `os.replace`.
- Invalid markers, duplicate IDs, malformed metadata, and unmanaged existing files are
  rejected without changing the store.
- Symlinks in managed profile paths, `MEMORY.md`, lock files, configuration files, tool
  files, and manifests are rejected.
- Existing foreign or locally modified tool files are never overwritten.
- OpenCode JSON is merged conservatively; JSONC and malformed JSON are rejected in 0.1.x.
- Titles are limited to 200 characters, content to 512 KiB UTF-8, tags to 20 unique
  values of 64 characters each, list limits to 100, and each document to 64 MiB.
- The generated adapter uses no shell interpolation and bounds subprocess time and output.

The files are local plaintext Markdown. Protect the configured directory with the
operating system permissions appropriate for the sensitivity of the memories.

## Development and verification

```console
uv sync --group dev
uv run pytest --cov=opencode_markdown_memory --cov-fail-under=80
uv run ruff check .
uv run ruff format --check .
uv run mypy src/opencode_markdown_memory
uv run python -m build
uv run python -m twine check dist/*
```

The release smoke uses OpenCode itself rather than a separately installed Bun CLI:

```console
uv run python scripts/opencode_e2e.py \
  --cli .venv/bin/opencode-markdown-memory \
  --opencode opencode \
  --artifact-dir artifacts/opencode-source
```

It runs CRUD through the installed Python bridge, starts isolated OpenCode servers for
both scopes, and verifies all five IDs and JSON schemas through
`/experimental/tool/ids` and `/experimental/tool` without contacting an LLM.

The source distribution includes `docs/design.md`, `docs/release.md`, and `SECURITY.md`
with the complete design, release, and reporting contracts.

## License

Apache-2.0. Copyright 2026 Dark Light.
