# Oh-My-Codex State Management: Architecture of the .omx Directory

> Explore the oh-my-codex state management architecture within the .omx directory. Learn how it hierarchically organizes global data, session snapshots, and team artifacts.

- Repository: [Bellman/oh-my-codex](https://github.com/Yeachan-Heo/oh-my-codex)
- Tags: architecture
- Published: 2026-04-03

---

**Oh-my-codex persists all runtime state in a hidden `.omx` directory using a hierarchical layout that isolates global mode data, per-session snapshots, and team orchestration artifacts while centralizing path resolution through utility functions.**

The `oh-my-codex` repository implements a hierarchical **oh-my-codex state management** system that stores all runtime data in a hidden `.omx` directory at the project root. This architecture isolates global mode state, session-specific snapshots, and team coordination artifacts while providing deterministic path resolution through centralized utility functions.

## The Hierarchical .omx Directory Layout

The `.omx` folder is created lazily upon the first state-writing operation. Its structure isolates distinct runtime concerns into specific subdirectories and files:

- **`.omx/state/`** – Stores core **mode state** JSON files (e.g., [`autopilot-state.json`](https://github.com/Yeachan-Heo/oh-my-codex/blob/main/autopilot-state.json), [`team-state.json`](https://github.com/Yeachan-Heo/oh-my-codex/blob/main/team-state.json), [`ralph-state.json`](https://github.com/Yeachan-Heo/oh-my-codex/blob/main/ralph-state.json)) directly under this directory.
- **`.omx/state/sessions/<session-id>/`** – Contains **session-scoped state** copies used by the MCP state-server to isolate interactive sessions.
- **`.omx/state/team/<team-name>/`** – Houses all **team orchestration artifacts** including configuration, worker directories, tasks, mailboxes, and dispatch queues.
- **[`.omx/notepad.md`](https://github.com/Yeachan-Heo/oh-my-codex/blob/main/.omx/notepad.md)** – Free-form **session notes** written by leaders or sub-agents.
- **[`.omx/project-memory.json`](https://github.com/Yeachan-Heo/oh-my-codex/blob/main/.omx/project-memory.json)** – Cross-session **project-wide memory** acting as a persistent key-value store.
- **`.omx/plans/`** – Persisted product-requirement documents (`prd-*.md`) and test specifications.
- **`.omx/logs/`** – Operational logs for diagnostics such as MCP request logs and notification cooldowns.

## Core State Resolution and Path Utilities

All paths are generated by centralized utilities to prevent hard-coded strings. The **`omxStateDir`** function in [`src/utils/paths.ts`](https://github.com/Yeachan-Heo/oh-my-codex/blob/main/src/utils/paths.ts) establishes the root state directory:

```typescript
import { join } from "path";

/** oh-my-codex state directory (.omx/state/) */
export function omxStateDir(projectRoot?: string): string {
  return join(projectRoot || process.cwd(), ".omx", "state");
}

```

The **MCP state server** constructs concrete file names using **`getStatePath`** from [`src/mcp/state-paths.ts`](https://github.com/Yeachan-Heo/oh-my-codex/blob/main/src/mcp/state-paths.ts), which accepts a mode name, optional working directory, and optional session ID:

```typescript
export function getStatePath(
  mode: string,
  workingDirectory?: string,
  sessionId?: string,
): string {
  return join(getStateDir(workingDirectory, sessionId), getStateFilename(mode));
}

```

This function returns a path such as [`.omx/state/team-state.json`](https://github.com/Yeachan-Heo/oh-my-codex/blob/main/.omx/state/team-state.json) for global state or [`.omx/state/sessions/abc123/team-state.json`](https://github.com/Yeachan-Heo/oh-my-codex/blob/main/.omx/state/sessions/abc123/team-state.json) for session-scoped data.

## Session Scoping and Fallback Logic

The architecture supports **read-scoped lookup** that prefers session data but falls back to the root directory when a session file does not exist. This guarantees backward compatibility with scripts expecting only global state files.

The resolution logic in [`src/mcp/state-paths.ts`](https://github.com/Yeachan-Heo/oh-my-codex/blob/main/src/mcp/state-paths.ts) implements a precedence system:

```typescript
// Resolve reading precedence – root first, then session overrides.
for (const dir of [...readDirs].reverse()) {
  const scope: StateFileScope = dir === rootDir ? 'root' : 'session';
  // ... read operation
}

```

The **`listModeStateFilesWithScopePreference`** function leverages this loop to return active state files with their appropriate scope metadata, ensuring deterministic state retrieval across concurrent sessions.

## Team Orchestration State Structure

When a `$team` workflow initiates, the system creates a dedicated subtree under `.omx/state/team/<team-name>/`. The layout mirrors the logical entities of the team runtime:

```

.omx/state/team/<team-name>/
 ├─ config.json                # team configuration

 ├─ manifest.v2.json          # static worker manifest

 ├─ workers/
 │   └─ worker-1/
 │       ├─ inbox.md          # inbound messages

 │       └─ status.json       # worker status

 ├─ tasks/
 │   └─ task-42.json          # task definitions

 ├─ mailbox/
 │   └─ leader-fixed.json     # leadership coordination

 ├─ dispatch/
 │   └─ requests.json         # dispatch queue

 ├─ events/
 │   └─ events.ndjson         # event stream

 └─ snapshots/
     ├─ monitor-snapshot.json
     └─ team-phase.json

```

All team state operations are handled by the **team state module** in [`src/team/state.ts`](https://github.com/Yeachan-Heo/oh-my-codex/blob/main/src/team/state.ts), which imports `omxStateDir` to locate the root and constructs paths via `join(omxStateDir(), 'team', teamName, ...)`.

## Auxiliary Runtime Files

Beyond mode and team state, the `.omx` directory contains several auxiliary files for operational continuity:

- **[`idle-notif-cooldown.json`](https://github.com/Yeachan-Heo/oh-my-codex/blob/main/idle-notif-cooldown.json)** – Throttling data for idle notifications.
- **[`dispatch-cooldown.json`](https://github.com/Yeachan-Heo/oh-my-codex/blob/main/dispatch-cooldown.json)** – Throttling for dispatch-based messages.
- **[`subagent-tracking.json`](https://github.com/Yeachan-Heo/oh-my-codex/blob/main/subagent-tracking.json)** – Ledger of native sub-agent activity used by `omx ralph`.

These files are accessed directly via MCP tools (**`state_read`**, **`state_write`**, **`state_clear`**) defined in [`src/mcp/state-server.ts`](https://github.com/Yeachan-Heo/oh-my-codex/blob/main/src/mcp/state-server.ts) and documented in the project's **AGENTS.md** contract.

## Practical Code Examples

### Retrieve the Global State Directory

```typescript
import { omxStateDir } from "./utils/paths.js";

const stateRoot = omxStateDir();               // → "/my/project/.omx/state"
console.log(stateRoot);

```

### Write Custom Mode State

When using the MCP client, `state_write` automatically resolves the path via `getStatePath`:

```typescript
import { state_write } from "@modelcontextprotocol/sdk/client";

await state_write({
  mode: "my-mode",
  active: true,
  iteration: 1,
  started_at: new Date().toISOString(),
});

```

This creates or updates [`.omx/state/my-mode-state.json`](https://github.com/Yeachan-Heo/oh-my-codex/blob/main/.omx/state/my-mode-state.json).

### Create a Team Worker Inbox

```typescript
import { join } from "path";
import { writeFile } from "fs/promises";
import { omxStateDir } from "./utils/paths.js";

const teamRoot = join(omxStateDir(), "team", "alpha");
const inboxPath = join(teamRoot, "workers", "worker-1", "inbox.md");

await writeFile(inboxPath, "Welcome worker-1!\n");

```

### List Active Mode States with Scope Preference

```typescript
import { listModeStateFilesWithScopePreference } from "./mcp/state-paths.js";

const activeFiles = await listModeStateFilesWithScopePreference();
console.log(activeFiles.map(f => `${f.mode}: ${f.path}`));
// Output: my-mode: /project/.omx/state/sessions/abc/my-mode-state.json

```

## Summary

- **Oh-my-codex** centralizes all runtime state in a hidden **`.omx`** directory at the project root.
- The **`.omx/state/`** directory holds global mode JSON files, while **`.omx/state/sessions/<id>/`** isolates session-specific data.
- **Team orchestration** stores artifacts under **`.omx/state/team/<team-name>/`**, managed by [`src/team/state.ts`](https://github.com/Yeachan-Heo/oh-my-codex/blob/main/src/team/state.ts).
- Path resolution is deterministic via **`omxStateDir()`** in [`src/utils/paths.ts`](https://github.com/Yeachan-Heo/oh-my-codex/blob/main/src/utils/paths.ts) and **`getStatePath()`** in [`src/mcp/state-paths.ts`](https://github.com/Yeachan-Heo/oh-my-codex/blob/main/src/mcp/state-paths.ts).
- The MCP state server supports **read-scoped lookup** with fallback to root state for backward compatibility.
- Auxiliary files like **[`project-memory.json`](https://github.com/Yeachan-Heo/oh-my-codex/blob/main/project-memory.json)** and **[`notepad.md`](https://github.com/Yeachan-Heo/oh-my-codex/blob/main/notepad.md)** persist data across sessions and agent restarts.

## Frequently Asked Questions

### What is the purpose of the .omx directory in oh-my-codex?

The **.omx** directory serves as the centralized state store for oh-my-codex, housing all transient runtime information including mode configurations, session snapshots, team coordination data, and operational logs. It is created lazily upon the first state write and uses a hierarchical structure to isolate concerns while remaining discoverable via utility functions like `omxStateDir()`.

### How does oh-my-codex handle concurrent session states?

The **MCP state server** creates isolated subdirectories under `.omx/state/sessions/<session-id>/` for each interactive session. When reading state, the server implements a **fallback mechanism** that checks session-scoped files first, then falls back to the global `.omx/state/` directory if the file does not exist, ensuring both isolation and backward compatibility.

### Where are team orchestration files stored?

Team-related state resides under `.omx/state/team/<team-name>/`, containing [`config.json`](https://github.com/Yeachan-Heo/oh-my-codex/blob/main/config.json), [`manifest.v2.json`](https://github.com/Yeachan-Heo/oh-my-codex/blob/main/manifest.v2.json), worker inboxes in `workers/<name>/inbox.md`, task definitions, and dispatch queues. The **team state module** ([`src/team/state.ts`](https://github.com/Yeachan-Heo/oh-my-codex/blob/main/src/team/state.ts)) manages these paths by joining `omxStateDir()` with the team-specific subdirectory structure.

### How are state file paths generated to ensure consistency?

All paths are constructed through centralized utilities to eliminate hard-coded strings. The **`omxStateDir()`** function in [`src/utils/paths.ts`](https://github.com/Yeachan-Heo/oh-my-codex/blob/main/src/utils/paths.ts) returns the root state directory, while **`getStatePath(mode, cwd, sessionId)`** in [`src/mcp/state-paths.ts`](https://github.com/Yeachan-Heo/oh-my-codex/blob/main/src/mcp/state-paths.ts) builds complete file paths following the convention `<mode>-state.json`. This ensures deterministic resolution regardless of the execution context.