Scaffold C++20 screencast project with Meson, agent workflow, and phase plan
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
# Project Memory — screen_cast
|
||||
|
||||
Last updated: initial scaffold.
|
||||
|
||||
## Project state
|
||||
|
||||
- Empty project scaffolded with Meson build, C++20, module headers, and agent
|
||||
workflow files.
|
||||
- No implementation yet; headers are placeholders.
|
||||
- Phase plan is in `docs/PHASES.md`. Agents are now explicitly instructed in
|
||||
`AGENTS.md` to read `docs/PHASES.md` before planning and not to start work
|
||||
belonging to a later phase unless requested.
|
||||
|
||||
## Decisions
|
||||
|
||||
- Language: C++20 with explicit modern-C++ guidelines in `AGENTS.md` and
|
||||
`cpp-meson-build/SKILL.md`.
|
||||
- Build system: Meson.
|
||||
- Capture: PipeWire + xdg-desktop-portal.
|
||||
- Encode/Decode: FFmpeg (libavcodec, libavutil, libswscale).
|
||||
- Transport: RTP over UDP; signaling via WebSocket/JSON.
|
||||
- Discovery: mDNS/Avahi.
|
||||
- Rendering: SDL2 or SDL3 + OpenGL.
|
||||
- Namespace: `sc`.
|
||||
|
||||
## Active blockers
|
||||
|
||||
None.
|
||||
|
||||
## Open questions
|
||||
|
||||
- GUI framework (Qt6 vs. none / CLI only) — deferred to later phase.
|
||||
- Hardware acceleration strategy (VAAPI / Vulkan Video / NVENC) — evaluate after
|
||||
software encode path works.
|
||||
@@ -0,0 +1,51 @@
|
||||
---
|
||||
name: agent-memory
|
||||
description: |
|
||||
Persistent handoff memory for multi-session agent work on the screen_cast
|
||||
project. Read this skill at the start of every new agent conversation so the
|
||||
current thread can bootstrap context from the repository rather than from chat
|
||||
history.
|
||||
disable-model-invocation: false
|
||||
---
|
||||
|
||||
## Always read at the start of a new conversation
|
||||
|
||||
1. `AGENTS.md` — mandatory project workflow.
|
||||
2. This skill (`agent-memory/SKILL.md`).
|
||||
3. `.agents/MEMORY.md` — current handoff log.
|
||||
4. Any domain-specific `RUNBOOK.md` relevant to the task (e.g.
|
||||
`docs/RUNBOOK.md`).
|
||||
5. All other skills applicable to the task (see `AGENTS.md` skill selection).
|
||||
|
||||
## Purpose
|
||||
|
||||
Zed agent threads do not share conversation history. This project therefore
|
||||
keeps the shared state in the repository itself:
|
||||
|
||||
- `.agents/MEMORY.md` — rolling handoff log: current focus, completed work,
|
||||
open blockers, decisions, files that matter.
|
||||
- `<domain>/RUNBOOK.md` — operational memory for recurring workflows
|
||||
(build/CI, capture validation, networking smoke tests).
|
||||
|
||||
Both files are ordinary markdown under git, so their history is preserved.
|
||||
|
||||
## After significant work
|
||||
|
||||
Update `.agents/MEMORY.md`:
|
||||
|
||||
- **Current focus**: one-line summary of what the thread was working on.
|
||||
- **Completed**: concrete outcomes, file paths, commits.
|
||||
- **Open issues / blockers**: anything unresolved at the end of the thread.
|
||||
- **Decisions & conventions**: choices that future threads must respect.
|
||||
- **Files that matter right now**: paths the next thread should read first.
|
||||
|
||||
Update domain `RUNBOOK.md` when the task reveals a reusable observation:
|
||||
|
||||
- non-obvious build or dependency workarounds;
|
||||
- validation steps that caught errors;
|
||||
- commands or snippets that should be reused.
|
||||
|
||||
## When starting a new thread
|
||||
|
||||
Paste a brief handoff if helpful, but **do not rely on it**. Always verify the
|
||||
actual current state from the memory files, git log, and the relevant code.
|
||||
@@ -0,0 +1,91 @@
|
||||
---
|
||||
name: cpp-meson-build
|
||||
description: |
|
||||
Guidelines for C++20 development and Meson build management in the
|
||||
screen_cast project. Read before changing source files, build files,
|
||||
dependencies, or toolchain configuration.
|
||||
disable-model-invocation: false
|
||||
---
|
||||
|
||||
# cpp-meson-build
|
||||
|
||||
Guidelines for C++20 development and Meson build management in the `screen_cast`
|
||||
project.
|
||||
|
||||
## Scope
|
||||
|
||||
Use this skill for:
|
||||
|
||||
- Adding or changing C++ source files, headers, or namespaces.
|
||||
- Modifying `meson.build` files, compiler flags, or targets.
|
||||
- Adding or updating dependencies (system libraries, pkg-config, subprojects).
|
||||
- Toolchain, sanitizer, static-analysis, or formatter configuration.
|
||||
|
||||
## Meson conventions
|
||||
|
||||
- Keep `meson.build` files declarative and readable.
|
||||
- Prefer `dependency()` with `pkg-config` names over manual `-l` flags.
|
||||
- Pin required C++ standard: `cpp_std = 'c++20'`.
|
||||
- Put one target per `meson.build` file where practical.
|
||||
- Use `include_directories('include')` for the public API headers.
|
||||
- Declare unit tests with `test()` and keep them deterministic.
|
||||
|
||||
## Dependency verification
|
||||
|
||||
Before adding a new dependency:
|
||||
|
||||
- verify the pkg-config file exists on the target system (e.g.
|
||||
`pkg-config --exists libavcodec`);
|
||||
- check that the required headers compile;
|
||||
- update `meson.build` and this skill's `references/` if needed.
|
||||
|
||||
## Error handling
|
||||
|
||||
- Prefer `std::expected<T,E>`, `std::optional<T>`, or `std::error_code` over
|
||||
exceptions for recoverable failures.
|
||||
- Use RAII wrappers; avoid raw owning pointers.
|
||||
- Keep headers minimal and forward-declare where possible.
|
||||
|
||||
## Modern C++ guidelines
|
||||
|
||||
All project code must use C++20 idioms:
|
||||
|
||||
- **Ownership**: use `std::unique_ptr` and `std::shared_ptr`; no raw `new`/`delete`
|
||||
or raw owning pointers.
|
||||
- **Optional values**: use `std::optional<T>` instead of sentinel values or
|
||||
out-parameters.
|
||||
- **Fallible operations**: use `std::expected<T,E>` or `std::error_code` for
|
||||
recoverable errors; avoid exceptions for control flow.
|
||||
- **Views**: use `std::span<T>` for non-owning buffers and `std::string_view`
|
||||
for read-only strings.
|
||||
- **Compile-time**: prefer `constexpr`/`consteval` where possible.
|
||||
- **Type safety**: prefer `enum class`, `std::variant`, and `std::optional`
|
||||
over bare integers or bool flags.
|
||||
- **Concurrency**: prefer `std::jthread`, `std::stop_token`, and standard
|
||||
synchronization primitives.
|
||||
- **Containers**: use standard containers; avoid C arrays and raw buffers.
|
||||
- **Formatting/time**: use `<format>` / `std::format` and `<chrono>`.
|
||||
- **Algorithms**: prefer `std::ranges` over hand-rolled loops where it
|
||||
improves clarity.
|
||||
- **Callables**: avoid `std::function` unless type erasure is required.
|
||||
- **Concepts**: use `requires` clauses to express interface contracts where
|
||||
beneficial.
|
||||
|
||||
Reject C-style patterns (`printf`, `sprintf`, manual memory management with
|
||||
`malloc`/`free`, raw arrays) when a standard-library equivalent exists.
|
||||
|
||||
## Useful commands
|
||||
|
||||
```sh
|
||||
meson setup build
|
||||
meson compile -C build
|
||||
meson test -C build --print-errorlogs
|
||||
meson configure build
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
- `meson.build` (project root)
|
||||
- `meson_options.txt` (if present)
|
||||
- `docs/ARCHITECTURE.md`
|
||||
- `docs/PHASES.md`
|
||||
@@ -0,0 +1,57 @@
|
||||
---
|
||||
name: linux-multimedia-capture
|
||||
description: |
|
||||
Guidelines for Linux screen/audio capture, FFmpeg encoding/decoding, and
|
||||
hardware acceleration in the screen_cast project.
|
||||
disable-model-invocation: false
|
||||
---
|
||||
|
||||
# linux-multimedia-capture
|
||||
|
||||
Guidelines for Linux screen/audio capture, FFmpeg encoding/decoding, and
|
||||
hardware acceleration in the `screen_cast` project.
|
||||
|
||||
## Scope
|
||||
|
||||
Use this skill for:
|
||||
|
||||
- Screen or window capture (PipeWire, xdg-desktop-portal D-Bus interfaces).
|
||||
- Audio capture or playback (PipeWire audio nodes).
|
||||
- Video encoding/decoding with FFmpeg/libavcodec.
|
||||
- Pixel format conversion, scaling (libswscale, libavutil).
|
||||
- Hardware acceleration (VAAPI, Vulkan Video, NVENC) via FFmpeg.
|
||||
|
||||
## Capture
|
||||
|
||||
- Use PipeWire with the `xdg-desktop-portal` screen-cast portal for Wayland and
|
||||
X11 compatibility.
|
||||
- Prefer screencast source types that request monitor, window, or virtual.
|
||||
- Treat portal session tokens, node IDs, and stream FDs as owned resources;
|
||||
close and destroy them on error paths.
|
||||
|
||||
## Encoding / decoding
|
||||
|
||||
- Use `AVCodecContext`, `AVFrame`, and `AVPacket` through RAII wrappers.
|
||||
- Validate codec capabilities (e.g. supported pixel formats, thread counts).
|
||||
- For H.264 baseline path use `libx264` or `h264_vaapi` when available.
|
||||
- Parse NAL units carefully before packetizing; reject malformed data.
|
||||
|
||||
## Hardware acceleration
|
||||
|
||||
- Probe available encoders with `avcodec_find_encoder_by_name()`.
|
||||
- Prefer VAAPI on Intel/AMD, NVENC on NVIDIA, Vulkan Video where supported.
|
||||
- Keep a software fallback path for compatibility.
|
||||
|
||||
## Security / safety
|
||||
|
||||
- Bounds-check all buffer sizes before copying into packets.
|
||||
- Validate resolution, stride, and pixel-format assumptions from the portal.
|
||||
- Avoid exposing capture tokens or session handles in logs.
|
||||
|
||||
## References
|
||||
|
||||
- PipeWire API docs and `libpipewire-0.3`
|
||||
- `libportal` (optional wrapper for the desktop portal)
|
||||
- FFmpeg documentation: `doc/APIchanges`, `doc/examples`
|
||||
- `docs/ARCHITECTURE.md`
|
||||
- `docs/PHASES.md`
|
||||
@@ -0,0 +1,69 @@
|
||||
---
|
||||
name: rtp-networking
|
||||
description: |
|
||||
Guidelines for RTP/UDP transport, signaling, discovery, NAT traversal, and
|
||||
encryption in the screen_cast project.
|
||||
disable-model-invocation: false
|
||||
---
|
||||
|
||||
# rtp-networking
|
||||
|
||||
Guidelines for RTP/UDP transport, signaling, discovery, NAT traversal, and
|
||||
encryption in the `screen_cast` project.
|
||||
|
||||
## Scope
|
||||
|
||||
Use this skill for:
|
||||
|
||||
- RTP packetization, depacketization, and sequencing.
|
||||
- UDP socket I/O and async event loops.
|
||||
- Peer discovery (mDNS/DNS-SD).
|
||||
- Session signaling and control channels.
|
||||
- Optional SRTP/DTLS or ICE-lite/NAT traversal.
|
||||
|
||||
## Transport
|
||||
|
||||
- Default transport is **RTP over IPv4/IPv6 UDP**.
|
||||
- Use a small, project-specific RTP header parser/serializer (12-byte base
|
||||
header plus extensions if needed).
|
||||
- Fragment large NAL units across RTP packets using FU-A fragmentation for
|
||||
H.264.
|
||||
|
||||
## Resilience
|
||||
|
||||
- Start without retransmission; add **NACK / PLI** once the baseline path works.
|
||||
- Keep a jitter buffer on the receiver to absorb network jitter without adding
|
||||
excessive latency.
|
||||
- Sequence numbers drive depacketization; detect loss and request key frames on
|
||||
large gaps.
|
||||
|
||||
## Discovery
|
||||
|
||||
- Use **Avahi** (`avahi-client`) for mDNS/DNS-SD service announcements.
|
||||
- Service name example: `_screencast._tcp` for signaling, `_screencast-rtp._udp`
|
||||
for media.
|
||||
|
||||
## Signaling
|
||||
|
||||
- Control channel is JSON over WebSocket or plain TCP.
|
||||
- Negotiate at least: codec, resolution, frame rate, UDP endpoints, session ID.
|
||||
- Keep signaling independent of media transport so either can evolve.
|
||||
|
||||
## Security (future)
|
||||
|
||||
- SRTP key exchange via DTLS or pre-shared keys over the signaling channel.
|
||||
- Do not hardcode keys; rotate per session.
|
||||
|
||||
## Async I/O
|
||||
|
||||
- Prefer an existing event loop library (e.g. `asio`, `libuv`) over raw threads
|
||||
and `select()`.
|
||||
- Keep network and capture threads separated with lock-free queues where
|
||||
practical.
|
||||
|
||||
## References
|
||||
|
||||
- RFC 3550 (RTP), RFC 6184 (H.264 RTP payload)
|
||||
- Avahi client documentation
|
||||
- `docs/ARCHITECTURE.md`
|
||||
- `docs/PHASES.md`
|
||||
@@ -0,0 +1,73 @@
|
||||
---
|
||||
name: screencast-app
|
||||
description: |
|
||||
Overall screencast application architecture, sender/receiver modes,
|
||||
protocol negotiation, and integration decisions in the screen_cast project.
|
||||
disable-model-invocation: false
|
||||
---
|
||||
|
||||
# screencast-app
|
||||
|
||||
Overall screencast application architecture, sender/receiver modes, protocol
|
||||
negotiation, and integration decisions in the `screen_cast` project.
|
||||
|
||||
## Scope
|
||||
|
||||
Use this skill for:
|
||||
|
||||
- Designing sender/receiver flows and state machines.
|
||||
- Deciding on CLI/GUI entry points and common application lifecycle.
|
||||
- Session negotiation formats and codec selection.
|
||||
- Integrating capture, encode, network, decode, and render modules.
|
||||
- Defining public API boundaries and module ownership.
|
||||
|
||||
## High-level architecture
|
||||
|
||||
```
|
||||
Sender: Capture → Encode → Packetize → RTP/UDP
|
||||
Receiver: RTP/UDP → Depacketize → Decode → Render
|
||||
Control: Signaling (WebSocket/JSON) + Discovery (mDNS)
|
||||
```
|
||||
|
||||
- The same binary supports both `--send` and `--receive` modes.
|
||||
- Each mode owns a pipeline object that wires the modules together.
|
||||
- Keep modules isolated; each module owns its thread(s) and exposes a small
|
||||
boundary to the pipeline.
|
||||
|
||||
## Pipeline rules
|
||||
|
||||
- Frame ownership is transferred with `std::unique_ptr` or shared frame pool.
|
||||
- Timestamp everything in the capture clock domain and carry RTP timestamps
|
||||
through the pipeline.
|
||||
- On sender error, drain packets in flight before shutting down.
|
||||
- On receiver error, request a key frame (PLI) or restart decoder if necessary.
|
||||
|
||||
## Protocol negotiation
|
||||
|
||||
Minimum negotiated fields:
|
||||
|
||||
- `codec`: `h264` initially.
|
||||
- `width`, `height`, `frame_rate`.
|
||||
- `rtp_endpoint`: `host:port` for media.
|
||||
- `signaling_endpoint`: host/port for control (optional if already connected).
|
||||
- `session_id`: unique string to correlate media and control.
|
||||
|
||||
## CLI / entry points
|
||||
|
||||
- `screencast --send [--target monitor|window]`
|
||||
- `screencast --receive [--peer-address ADDR]`
|
||||
- Optional `--signaling-url`, `--codec`, `--bitrate`, `--hwaccel` flags.
|
||||
|
||||
## GUI
|
||||
|
||||
- GUI is optional and lives in a separate target/library.
|
||||
- The core library must be usable from CLI and tests without a GUI.
|
||||
|
||||
## References
|
||||
|
||||
- `docs/ARCHITECTURE.md`
|
||||
- `docs/PHASES.md` — must be consulted before starting implementation; do not
|
||||
work on a later phase unless the current phase is complete or the user
|
||||
explicitly requests it.
|
||||
- Other domain skills: `linux-multimedia-capture`, `rtp-networking`,
|
||||
`cpp-meson-build`
|
||||
Reference in New Issue
Block a user