# CLAUDE.md ## Project Summary This project is porting the NATS server from Go to .NET 10 C#. The Go source (~130K LOC across 109 non-test files, 85 test files) is at `golang/nats-server/`. The porting process is tracked via an SQLite database (`porting.db`) and managed by two tools: a Go AST analyzer and a .NET PortTracker CLI. ## Folder Layout ``` natsnet/ ├── golang/nats-server/ # Go source (reference) ├── dotnet/ # .NET ported version │ ├── src/ │ │ ├── ZB.MOM.NatsNet.Server/ # Main server library │ │ └── ZB.MOM.NatsNet.Server.Host/ # Host/entry point │ └── tests/ │ ├── ZB.MOM.NatsNet.Server.Tests/ # Unit tests │ └── ZB.MOM.NatsNet.Server.IntegrationTests/ # Integration tests ├── tools/ │ ├── go-analyzer/ # Go AST analyzer (Phases 1-2) │ └── NatsNet.PortTracker/ # .NET CLI tool (all phases) ├── docs/plans/phases/ # Phase instruction guides ├── reports/ # Generated porting reports ├── porting.db # SQLite tracking database ├── porting-schema.sql # Database schema └── documentation_rules.md # Documentation conventions ``` ## Tools ### Go AST Analyzer ```bash CGO_ENABLED=1 go build -o go-analyzer . && ./go-analyzer --source golang/nats-server --db porting.db --schema porting-schema.sql ``` ### .NET PortTracker CLI ```bash dotnet run --project tools/NatsNet.PortTracker -- --db porting.db ``` ## Phase Instructions - **Phase 1: Go Codebase Decomposition** - `docs/plans/phases/phase-1-decomposition.md` - **Phase 2: Verification of Captured Items** - `docs/plans/phases/phase-2-verification.md` - **Phase 3: Library Mapping** - `docs/plans/phases/phase-3-library-mapping.md` - **Phase 4: .NET Solution Design** - `docs/plans/phases/phase-4-dotnet-design.md` - **Phase 5: Mapping Verification** - `docs/plans/phases/phase-5-mapping-verification.md` - **Phase 6: Initial Porting** - `docs/plans/phases/phase-6-porting.md` - **Phase 7: Porting Verification** - `docs/plans/phases/phase-7-porting-verification.md` ## .NET Standards All .NET code must follow the rules in [`docs/standards/dotnet-standards.md`](docs/standards/dotnet-standards.md). Key points: - .NET 10, C# latest - **Testing**: xUnit 3, Shouldly, NSubstitute — do NOT use FluentAssertions or Moq - **Logging**: `Microsoft.Extensions.Logging` with Serilog provider; use `LogContext.PushProperty` for contextual enrichment - **Naming**: PascalCase for all public members; `ZB.MOM.NatsNet.Server.[Module]` namespace hierarchy ## Using Codex via tmux-cli Use `tmux-cli` to launch and interact with OpenAI Codex (`ccc` alias) in a separate tmux pane. This lets you delegate tasks to Codex without blocking your current session. **Do NOT use the Codex MCP server (`mcp__codex__codex`) for long-running commands.** Use `tmux-cli` + `ccc` instead — it runs in a separate pane, won't time out, and lets you capture output when ready. ### The `ccc` alias `ccc` runs `codex --dangerously-bypass-approvals-and-sandbox` (with Node/nvm auto-setup). Use it for tasks you want Codex to handle autonomously. ### Workflow **Always launch a shell pane first** — if a command errors without a shell, the pane closes and output is lost: ```bash # 1. Launch a shell (returns pane ID, e.g. "2") tmux-cli launch "zsh" # 2. Send a codex command to that pane tmux-cli send 'ccc "your prompt here"' --pane=2 # 3. Wait for codex to finish (no output for N seconds = idle) tmux-cli wait_idle --pane=2 --idle-time=10.0 # 4. Capture the output tmux-cli capture --pane=2 # 5. Clean up when done tmux-cli kill --pane=2 ``` ### Key tmux-cli commands | Command | Purpose | |---------|---------| | `tmux-cli launch "zsh"` | Start a shell pane (do this FIRST) | | `tmux-cli send "cmd" --pane=N` | Send text + Enter to pane N | | `tmux-cli send "text" --pane=N --enter=False` | Send text without pressing Enter | | `tmux-cli send "text" --pane=N --delay-enter=0.5` | Custom delay before Enter (default 1.5s) | | `tmux-cli wait_idle --pane=N --idle-time=3.0` | Wait until pane has no output for N seconds | | `tmux-cli capture --pane=N` | Capture current pane output | | `tmux-cli list_panes` | List all panes (JSON with IDs and status) | | `tmux-cli kill --pane=N` | Kill a pane (cannot kill your own) | | `tmux-cli interrupt --pane=N` | Send Ctrl+C to a pane | | `tmux-cli escape --pane=N` | Send Escape to a pane | ### Pane identifiers - Just the pane number: `2` (current window) - Full format: `session:window.pane` (e.g. `myapp:1.2`) ### Tips - Use `wait_idle` instead of polling with repeated `capture` calls - Save the pane ID returned by `launch` for subsequent commands - Use `capture` to check state before sending input - For long-running Codex tasks, increase `--idle-time` (e.g. `--idle-time=15.0`) ## Reports - `reports/current.md` always has the latest porting status. - `reports/report_{commit_id}.md` snapshots are generated on each commit via pre-commit hook. - Run `./reports/generate-report.sh` manually to regenerate.