# AGENTS.md ## Repo layout - `pipeline-runner/` — C++11 application built with PIP (Platform Independent Primitives). - `pipeline-runner/src/main.cpp` — entry point, config loading, server start. - `pipeline-runner/src/server.h/.cpp` — PIHTTPServer routes, all API endpoints. - `pipeline-runner/src/pipeline.h/.cpp` — Pipeline/Prompt structs, JSON file I/O, log functions. - `pipeline-runner/src/runner.h/.cpp` — async pipeline execution (PIThread + PIProcess per step). - `pipeline-runner/src/messageutils.h/.cpp` — HTTP response helpers (JSON, error, success). - `pipeline-runner/pipeline-runner.conf` — JSON config file (port, directories). - `pipeline-runner/tests/` — gtest tests for pipeline storage and runner. - `pipeline-runner/CMakeLists.txt` — CMake build config with PIP + gtest (FetchContent). - `pipeline-runner/build.sh` — build + test script (incremental by default, `--rebuild` for clean). - `pipeline-runner/storage/pipelines/` — JSON files for persisted pipelines. - `pipeline-runner/storage/logs/` — execution logs (one file per run). ## Dev commands - Build + test: `./pipeline-runner/build.sh` (incremental, auto-configures on first run). - Clean build + test: `./pipeline-runner/build.sh --rebuild`. - Build with FAKE mode: `./pipeline-runner/build.sh --rebuild --fake` (uses fake process executor, no opencode needed). - Switching `--fake` on/off triggers a clean + reconfigure automatically. - Run: `cd pipeline-runner/build && ./pipeline-runner ../pipeline-runner.conf` - Test XML report: generated at `pipeline-runner/build/test-results.xml` after each test run. - CMake uses `-S -B ` and `cmake --build -j$(nproc)` (no `cd build && make`). ## Build requirements - **PIP library** must be installed system-wide (`find_package(PIP REQUIRED)`). - gtest is fetched via custom mirror: `https://git.shstk.ru/mirrors/googletest.git` (v1.14.0). - `CMAKE_EXPORT_COMPILE_COMMANDS ON` — `compile_commands.json` is generated in build dir for LSP. - `CMakeLists.txt` uses `file(GLOB ...)` for sources — new `.cpp` files require re-running `cmake ..`. - RPATH is set to `$ORIGIN;$ORIGIN/lib` so the binary finds PIP shared libs from its directory. ## Formatting - Tabs (width 4), LF line endings, UTF-8 — enforced by `.editorconfig`. - `.clang-format` column limit: 140. Use `clang-format -i` on changed files. ## API endpoints | Method | Path | Description | |--------|------|-------------| | GET | `/api/pipelines` | List all pipelines | | POST | `/api/pipelines` | Create pipeline (JSON body) | | GET | `/api/pipelines/{id}` | Get single pipeline | | DELETE | `/api/pipelines/{id}` | Delete pipeline | | POST | `/api/runs` | Start execution (`{"pipeline_id": "..."}`) | | GET | `/api/runs/{run_id}/status` | Poll run status + step results | | GET | `/api/runs/{run_id}/log` | Get log file contents | ## Key behaviors - C++11 standard — no modern C++ features (no `auto` return type deduction, no `std::optional`, etc.). - All source code is in the **global namespace** (no namespace wrapping). - Pipeline execution runs `opencode run --title ` per step via `PIProcess` (not a shell). - Each step has a **300-second timeout** (`proc.waitForFinish(PISystemTime::fromSeconds(300))`). - Pipeline stops on first step error (non-zero return code). - Each run executes in a separate `PIThread` (thread object is intentionally leaked; PIP manages lifetime). - Run state is **in-memory only** — lost on server restart. Log files persist to disk. - CORS headers are added to all responses (`Access-Control-Allow-Origin: *`). - Config paths (`pipelines_dir`, `logs_dir`) are relative to the **process working directory**, not the binary path. - Tests use `/tmp/pipeline-runner-test/` with manual setup/cleanup per test — **not isolated**, do not run in parallel.