diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..7ee9358 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,154 @@ +# Repository Guidelines + +## Project Structure & Module Organization +Keep source under `src/` with entrypoints in `src/cli/` and shared helpers in `src/lib/`. Purpose-built agents belong in `src/agents/` so they can import shared utilities without cyclic dependencies. Use `tests/` for automated coverage and mirror package names (for example, `tests/agents/test_sync.py` for `src/agents/sync.py`). Configuration, schema stubs, and reusable scripts should live in `config/` and `scripts/`. If you introduce assets for demos, drop them into `examples/` and document any generated files in `docs/`. + +## Build, Test, and Development Commands +Create a virtual environment before contributing: +``` +python -m venv .venv && source .venv/bin/activate +pip install -r requirements.txt +``` +Run the CLI locally with `python -m codex_cli --help` to confirm new commands register correctly. Use `make fmt` to apply formatters, `make lint` for static analysis (wrapping `ruff check` and `mypy`), and `make test` to execute the full automated suite (`pytest -q`). Keep the `Makefile` in sync if you add tooling so every contributor has a single entry point. + +## Coding Style & Naming Conventions +Follow Black’s default 88-character line width and prefer explicit imports. Module, package, and directory names stay lowercase with underscores (`data_loader.py`), while classes use CapWords. Functions and variables use snake_case, and constants are UPPER_CASE. Run `ruff format` before committing; it enforces import ordering and docstring rules. Add type hints everywhere new public APIs are exposed and fail the build if `mypy` reports violations. + +## Testing Guidelines +Write pytest tests alongside the feature in the mirrored path and name test modules `test_.py`. Each scenario should assert both success and failure modes, and regression cases belong in `tests/regression/`. Target ≥90 % coverage for touched packages and add `pytest.mark.slow` to long-running cases so they can be skipped via `pytest -m "not slow"`. When introducing asynchronous agents, include an integration test that exercises the command through the CLI entrypoint. + +## Commit & Pull Request Guidelines +Use Conventional Commits (`feat:`, `fix:`, `docs:`, `chore:`) so changelog generation stays deterministic. Commits should be scoped to a single concern; reorganize noisy diffs before opening a PR. Every pull request needs: a short summary, linked issue or task ID, test results (paste the command output), and screenshots or terminal captures if you change interactive flows. Request reviews from another agent maintainer and wait for CI to pass before merging via squash. + +## Local Codex Rules (Do Not Commit) +- Any Codex-only instructions, handover notes, context files, or local operational scratch docs are local artifacts and must never be committed or pushed to git. +- Keep Codex-only materials under local folders (for example `ci-observer-handover/`) outside project repos whenever possible. +- Before any commit in a project repo, verify Codex-only files are not staged. + +## Workspace Organization Rules +- `~/codex-cli` is a workspace root. New topics must always start in a new project folder under `~/codex-cli/projects//`. +- Avoid loose files in workspace root. Files must be organized by project/theme folders. +- Every project folder must contain its own `AGENTS.md`. +- Project-level directives from conversation should be added to that project `AGENTS.md` (automatically when clear, or directly when user requests). +- If Codex detects a potentially useful new general rule, Codex must ask user for confirmation before adding it to this global `AGENTS.md`. +- At the end of each task, Codex must ask whether temporary screenshots/files can be deleted, then clean up unneeded artifacts to keep workspace tidy. + +## Command Formatting Rule (Global) +- When providing shell commands, always format them as a numbered list. +- Each command must be a single standalone line with no leading spaces/tabs before the command text. +- Prefer one command per list item so users can execute step-by-step safely. + +## Fast-Fix Triage Rule (Global) +- Scope: this rule applies to troubleshooting, incident response, and stabilization of existing systems/workflows. +- For existing systems, default to the fastest viable fix path first. +- Before proposing complex fixes, always do a strict 1:1 mismatch check between: +- workflow variables/commands +- compose or runtime service configuration +- currently running container/image/runtime state +- If a direct mismatch exists (for example credentials, DB name, host, port, container name), propose and prioritize the minimal alignment fix first. +- Do not propose plugin, network, or platform-level workarounds before the mismatch check is explicitly completed or ruled out. +- When the user asks for speed, return one primary fix path (not multiple alternatives), with minimal change scope. +- For greenfield/from-scratch work, this rule is not mandatory; prioritize design clarity, architecture fit, and implementation flow. + +## Session Management +- Session logs live in `.codex/sessions/` as JSON files (one per session). +- Session naming: `__.json`. +- Search sessions: `python3 .codex/save-session.py list ` or `.codex/search.py find `. +- Show latest state for a project: `python3 .codex/save-session.py --latest `. +- Save current session: `python3 .codex/save-session.py save --project --model --status --summary "..." --decisions "a|b|c" --pending "x|y|z" --files "f1,f2"`. +- Generate HANDOFF.md: `python3 .codex/save-session.py --handoff `. +- Per-project state: `projects//.sessions/latest.json` and `projects//HANDOFF.md`. +- Re-index from JSON files: `python3 .codex/search.py reindex`. + +## Cross-Model Session Continuity (CRITICAL) + +THIS RULE APPLIES TO ALL MODELS (codex, deepseek, opencode). + +### When starting a session in any project: +1. READ `projects//HANDOFF.md` first — this tells you where the last session ended. +2. If HANDOFF.md exists, you MUST read it and continue from the state described. +3. Understand: what was built, key decisions made, pending tasks, files touched, Docker state. +4. If the previous session was from a different model, adapt to that model's decisions — do NOT restart or redesign. + +### When ending a session: +1. AUTO-SAVE the session state: + ``` + python3 .codex/save-session.py save \ + --project \ + --model \ + --status complete|in-progress \ + --summary "<2-3 sentences on what was done>" \ + --decisions "decision1|decision2|..." \ + --pending "pending1|pending2|..." \ + --files "src/main.py,frontend/index.html,..." \ + --tags "tag1,tag2" + ``` +2. This automatically generates HANDOFF.md for the next session. +3. If you cannot run the script, at minimum update the HANDOFF.md manually. + +### Handoff protocol (when switching models mid-project): +- Example: codex started building an API, then crashed. User opens deepseek. +- Deepseek reads HANDOFF.md → sees: "FastAPI app, 4 endpoints, SQLite, pending: add auth". +- Deepseek continues: adds auth to the same FastAPI app, preserves existing code. +- Deepseek saves new session → HANDOFF.md updated for next time. +- No "let me rewrite this differently" — respect the previous model's architectural decisions. + +### Per-project structure: +``` +projects// +├── AGENTS.md # Project rules +├── HANDOFF.md # AUTO-GENERATED — read on session start +├── .sessions/ +│ ├── latest.json # Most recent session snapshot +│ └── .json # Historical snapshots +├── src/ # Source code +└── ... # Other project files +``` + +## VPN & Critical Infrastructure Safety Rule (Global) + +Applies to ALL models (deepseek, codex, opencode) across ALL sessions. + +### Critical infrastructure that MUST NOT be broken: +- **Oracle VPS** (`130.162.209.80`, hostname `vpn-server`): WireGuard (wg-easy), nginx-proxy, Authelia SSO +- **Mini PC** (`192.168.0.240`, hostname `home-core-dev`): Home Assistant, Pi-hole, WireGuard client +- **WireGuard tunnel** between Oracle VPS (10.8.0.1) and Mini PC (10.8.0.6) +- **SSH access** to both machines + +### Rules: +1. Any action that could disrupt WireGuard, iptables, nginx, Docker networking, SSH config, or routing MUST be presented to the user for explicit approval BEFORE execution. +2. Before making any such change, propose a specific fallback/revert plan. +3. Never `wg-quick down` without confirming the user has an alternative access path. +4. Never change `AllowedIPs`, `iptables` rules, SSH `authorized_keys`, or Docker network configs without user approval. +5. After any VPS reboot, verify and restore: WireGuard `192.168.0.0/24` AllowedIPs on wg-easy mini-pc peer, host route, nginx container route, and wg-easy MASQUERADE rule. +6. Always read `_shared/contexts/network-topology.md` before making network-related changes. +7. Always read `projects/mini-pc-openclaw/HANDOFF.md` before touching mini-pc or Oracle VPS infrastructure. + +### Quick-post-reboot fix checklist: +``` +# On Oracle VPS: +WG_IP=$(docker inspect wg-easy --format '{{.NetworkSettings.Networks.vpn_default.IPAddress}}') +docker exec wg-easy wg set wg0 peer xekIYyq18hcW9vP3LoRbMG/w0q4UcxX1c0cK96NJFQA= allowed-ips 10.8.0.6/32,192.168.0.0/24 +docker exec wg-easy ip route add 192.168.0.0/24 dev wg0 2>/dev/null || true +docker exec wg-easy iptables -t nat -C POSTROUTING -o wg0 -j MASQUERADE 2>/dev/null || docker exec wg-easy iptables -t nat -A POSTROUTING -o wg0 -j MASQUERADE +ip route replace 192.168.0.0/24 via $WG_IP +docker exec nginx-proxy ip route replace 192.168.0.0/24 via $WG_IP +``` + +## Model-Specific Rules + +### deepseek-v4-pro (DeepSeek) +- Full read access to `~/codex-cli` workspace. +- Cannot view images — user must save screenshot to file and describe, or use OCR. +- Preferred stack: Python/FastAPI, Vanilla JS, Docker Compose, SQLite. +- Config: `.codex/models/deepseek.yml`. + +### codex (Default / OpenAI / Anthropic) +- Full read-write access to `~/codex-cli` workspace. +- Can view images if model supports vision. +- Preferred stack: Python, React/NextJS, Docker, PostgreSQL. +- Config: `.codex/models/codex.yml`. + +### Shared Context +- Reusable context (hardware specs, network config, credentials schema) should go in `_shared/contexts/`. +- Example: `_shared/contexts/home-core-dev-specs.md` for the mini PC hardware. diff --git a/HANDOFF_mini-pc-openclaw.md b/HANDOFF_mini-pc-openclaw.md new file mode 100644 index 0000000..518bc3b --- /dev/null +++ b/HANDOFF_mini-pc-openclaw.md @@ -0,0 +1,37 @@ +# mini-pc-openclaw — Session Handoff + +**Last Session:** 2026-05-18_171921_mini-pc-openclaw +**Model:** deepseek-v4-pro +**Status:** complete +**Updated:** 2026-05-18T17:19:21.294703 + +## Summary +Popravljen WireGuard tunel do mini-pc-ja (deepseek regenerisao kljuceve, novi peer 10.8.0.6). Postavljen Authelia SSO na oracle-vps za sve *.dzonicasa.xyz servise. Nginx prebacen sa basic auth na auth_request. Resetovan nginx password. Ocisceni logovi i docker. Azuriran docs portal i HANDOFF.md. + +## Key Decisions +- Koristimo Authelia sa path-based routing na docs.dzonicasa.xyz/authelia/ +- Mini-pc WireGuard koristi nove kljuceve kao peer 10.8.0.6 +- Nginx auth_request koristi /api/verify endpoint (vraca 401) +- SNAT/MASQUERADE na wg-easy za 192.168.0.0/24 saobracaj + +## Pending Tasks +- [ ] Dodati swap na oracle-vps +- [ ] Popraviti DNS resolving na oracle-vps hostu (trenutno static /etc/resolv.conf) +- [ ] Restartovati certbot kontejner za SSL renewal + +## Network Topology +See `_shared/contexts/network-topology.md` for full VPN/machine/credential map. +- **Lenovo laptop** has Wolkabout office VPN config at `/etc/wireguard/njovanovic.conf` +- Oracle VPS VPN is accessed through Wolkabout VPN (no separate config on lenovo) +- **Duplicate file**: `/etc/wireguard/njovanovic.conf.conf` — same as `njovanovic.conf`, can be deleted + +## Files Touched +- `oracle:~/nginx-proxy/conf.d/*.conf` +- `oracle:~/authelia/configuration.yml` +- `oracle:~/authelia/users.yml` +- `oracle:~/docker_projects/vpn/etc_wireguard/wg0.conf` +- `oracle:~/docker_projects/vpn/etc_wireguard/wg0.json` +- `mini-pc:/etc/wireguard/wg0.conf` + +--- +*Auto-generated from session `2026-05-18_171921_mini-pc-openclaw`. Run `python3 .codex/save-session.py --handoff mini-pc-openclaw` to regenerate.* \ No newline at end of file diff --git a/README.md b/README.md index 486973a..e4e1b40 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,18 @@ # codex-cli-shared -Shared codex-cli configs, handoffs, and network topology \ No newline at end of file +Central repository for codex-cli configurations shared across all machines. + +## Contents +- `AGENTS.md` - Global rules (VPN safety, session management, etc.) +- `_shared_contexts_network-topology.md` - Full network/VPN/credentials map +- `HANDOFF_mini-pc-openclaw.md` - Latest session handoff for mini-pc project + +## Machines +- **lenovo** - Office laptop (Debian) +- **vpn-server** - Oracle VPS (130.162.209.80) +- **home-core-dev** - Mini PC (192.168.0.240) + +## Setup on each machine +```bash +git clone https://git.dzonicasa.xyz/dzoni/codex-cli-shared.git ~/codex-cli-shared +``` diff --git a/_shared_contexts_network-topology.md b/_shared_contexts_network-topology.md new file mode 100644 index 0000000..0a54501 --- /dev/null +++ b/_shared_contexts_network-topology.md @@ -0,0 +1,71 @@ +# Network Topology — dzonicasa.xyz + +## Machines + +| Name | Device | LAN IP | WireGuard IP | Location | +|------|--------|--------|-------------|----------| +| home-core-dev | Mini PC | 192.168.0.240 | 10.8.0.6 | Home | +| lenovo | Laptop | DHCP | 10.8.0.3 | Mobile | +| vpn-server | Oracle VPS | 10.0.0.197 | 10.8.0.1 | Cloud | + +## VPNs + +### 1. Wolkabout Office VPN +- **Endpoint**: `79.101.44.157:51820` +- **Config on lenovo**: `/etc/wireguard/njovanovic.conf` (and duplicate `njovanovic.conf.conf`) +- **Lenovo IP**: `10.8.0.3/24` +- **DNS**: `10.0.50.15` +- **PrivateKey**: `yFNg+e6esP1K5PofLKNZQqFJ1+InjC9DpXhFldECm1o=` +- **Peer PublicKey**: `HsupulTLfUrQXUNSu2NMpM9RsUja5drl73a9bvZz31s=` +- **PSK**: `s3zCeMxAr44V/QDiyf4opHgcwtZfoDojL/JvJ/b5s0Q=` +- **AllowedIPs**: `0.0.0.0/0` (full tunnel) + +### 2. Oracle VPS Personal VPN (wg-easy) +- **Endpoint**: `130.162.209.80:51820` +- **Web UI**: `http://localhost:51821` (SSH tunnel, password `WZaadgj6`) +- **Subnet**: `10.8.0.0/24` + +#### Peers on Oracle VPS: +| Name | WG IP | Public Key | +|------|-------|-----------| +| dzoni-mob (OLD) | 10.8.0.2 | `T+2YH4hS970lyRsCmxybHzEaCszWZPIyoU31uRXgO2M=` | +| dzoni-lenovo | 10.8.0.3 | `bP3tvdeAEHqZnVXBKd7qqe9S9PhI3nMX7DhNQ200sj8=` | +| mini-pc (CURRENT) | 10.8.0.6 | `xekIYyq18hcW9vP3LoRbMG/w0q4UcxX1c0cK96NJFQA=` | + +#### Mini PC WireGuard Config (`/etc/wireguard/wg0.conf`): +```ini +[Interface] +PrivateKey = 8F/FUxwzSRAo8TS49YIRRpEnktQ9dNWlrg4JXFiFvnI= +Address = 10.8.0.6/24 + +[Peer] +PublicKey = d5Vvb77K6aI0IvcpzBfRBWwCk6ou6BNh710y0spylyE= +PresharedKey = sNicM+F7kR+uRMWy2ZREhS/clOco5lSV+xQSnz+wUP0= +Endpoint = 130.162.209.80:51820 +AllowedIPs = 10.8.0.0/24 +PersistentKeepalive = 25 +``` + +## Routing Flow +``` +Office → Wolkabout VPN (79.101.44.157) → Oracle VPS (130.162.209.80) → nginx → WireGuard → Mini PC (192.168.0.240) +``` + +## Services (via nginx on Oracle VPS) + +| Service | URL | Backend | +|---------|-----|---------| +| Home Assistant | `https://ha.dzonicasa.xyz` | `192.168.0.240:8123` | +| Pi-hole | `https://pihole.dzonicasa.xyz` | `192.168.0.240:8180` | +| Docs Portal | `https://docs.dzonicasa.xyz` | Static + Authelia | +| Authelia SSO | `https://docs.dzonicasa.xyz/authelia/` | `authelia:9091` | + +## Oracle VPS SSH Access +``` +ssh -i ~/.ssh/ssh-key-2024-10-17.key ubuntu@130.162.209.80 +``` + +## Mini PC SSH Access +``` +ssh devops@192.168.0.240 +```