9.6 KiB
AGENTS.md — Screencast (Linux) Agent Workflow
This document governs how Zed agents work in the screen_cast project. It is mandatory reading before any non-trivial implementation task.
Agent memory
Before starting work in a new agent conversation:
- read this
AGENTS.md; - read the
agent-memory/SKILL.mdskill; - read
.agents/MEMORY.mdfor the current project handoff; - read
docs/PHASES.mdto understand the current phase and milestones; - read any domain-specific
RUNBOOK.mdrelevant to the task (e.g.docs/RUNBOOK.mdordocs/multimedia/RUNBOOK.md).
Update .agents/MEMORY.md when the task produces significant state, blockers,
or decisions. Update the relevant RUNBOOK.md when the task reveals reusable
operational observations. Update docs/PHASES.md when a phase is completed or
its plan changes.
Skills
Skills are task-specific instructions and must be read before planning work.
Before producing a plan, identify all skills applicable to the task and read
their SKILL.md files.
Skills are self-contained directories under .agents/skills/.
When a skill is selected, read its SKILL.md and consult any relevant
documentation under that skill's references/ directory.
Skills are task-specific guidance, not a replacement for the mandatory project
workflow in this file. The agent must follow AGENTS.md even when no skill
applies.
Skill selection
- C++ project, Meson build, dependencies, or toolchain issues:
cpp-meson-build/SKILL.md - Linux screen/audio capture, PipeWire, xdg-desktop-portal, FFmpeg, VAAPI, or
codec work:
linux-multimedia-capture/SKILL.md - RTP/UDP networking, transport, signaling, NAT traversal, or encryption:
rtp-networking/SKILL.md - Overall screencast application architecture, sender/receiver modes,
protocol negotiation, or integration decisions:
screencast-app/SKILL.md
Multiple skills may apply. Read all applicable ones.
For example, implementing sender-side capture + encode will normally require:
cpp-meson-build/SKILL.mdlinux-multimedia-capture/SKILL.mdscreencast-app/SKILL.md
A networking change will normally require:
cpp-meson-build/SKILL.mdrtp-networking/SKILL.mdscreencast-app/SKILL.md
Do not assume that a skill is applicable merely because its subject is mentioned incidentally. Use the task's actual scope to determine applicability.
Mandatory development workflow
All non-trivial implementation tasks follow this workflow:
1. Understand
Before changing anything:
- read
AGENTS.md; - read all applicable skills;
- inspect the existing implementation and directory structure;
- search the project for related symbols, build rules, and tests;
- identify system dependencies (pkg-config names, headers, runtime packages);
- identify dependencies and integration points.
Do not modify files during this phase.
Plan against the phase roadmap
docs/PHASES.mddefines the project milestones and the current active phase.- Do not start implementation that belongs to a later phase unless the user explicitly asks for it or the current phase is already complete and validated.
- When planning work, identify which phase(s) the task touches and include that in the implementation plan.
- Update
docs/PHASES.mdwhen a phase is finished, blocked, or its scope changes; update.agents/MEMORY.mdat the same time.
2. Plan
Produce a concise implementation plan containing:
- understanding of the requirement;
- relevant existing project functionality;
- files/components likely to change;
- proposed implementation;
- build/dependency implications;
- tests to add or modify;
- multimedia/networking/security considerations;
- potential risks or unresolved questions.
3. Wait for approval
STOP after presenting the plan.
Do not create, modify, delete, or rename files until the user explicitly approves the plan.
Questions and clarification are allowed during this phase.
4. Implement
After approval:
- implement the approved plan;
- prefer existing project modules and standard library functionality;
- keep the change as small and focused as practical;
- do not introduce unrelated refactoring;
- follow the C++ and project conventions described in this file and in skills.
If implementation reveals that the approved plan is materially wrong or incomplete, stop and explain the discrepancy rather than silently expanding scope.
5. Validate
Run appropriate tests and checks.
At minimum:
- the project must still configure with Meson (
meson setup build); - the project must still compile (
ninja -C build); - unit/integration tests pass (
meson test -C build --print-errorlogs); - static analysis or formatting checks configured in the project;
- manual smoke test of the affected component where automated tests are insufficient.
For multimedia or networking changes, validate runtime behavior on an actual Linux desktop session (Wayland or X11) when feasible.
6. Review
Before considering the task complete, review the resulting changes for:
- correctness;
- integration with existing modules;
- reuse of existing functionality;
- maintainability (small headers, clear ownership, RAII);
- security (buffer handling, bounds checks, no secrets committed);
- thread safety and async I/O correctness;
- regression risk;
- build/dependency impact.
Verify before assuming
Never invent or assume the existence of an API.
Before using a:
- system library or package;
- header file or symbol;
- class, function, or macro;
- build option or pkg-config name;
- external protocol or service;
verify that it exists in the current environment, project dependencies, or a reliable source (distribution package index, upstream API docs, local header).
Do not infer existence from naming conventions, training knowledge, or similarly named components. If existence cannot be verified, stop and report the uncertainty.
In particular, never add a dependency merely because it would be a plausible package name.
Prefer framework and standard functionality
Before implementing custom functionality, search the project and the C++ standard library for an existing mechanism.
Prefer, in order:
- existing project functionality that already satisfies the requirement;
- C++ standard library facilities (
std::,<format>,<chrono>, etc.); - widely adopted third-party libraries already used by the project;
- a small project-specific implementation only when the above are insufficient.
Do not duplicate functionality merely because implementing it locally appears simpler.
When choosing a custom implementation over an existing mechanism, explain the reason in the plan.
Git
- Keep commits focused and logically coherent.
- Prefer one component or one phase per commit where practical.
- Do not mix unrelated changes.
- Review the staged diff before committing.
- Never commit secrets, credentials, local configuration, or generated build artifacts.
- Do not create a commit unless the user explicitly asks for one or the task explicitly requires it.
- When committing, write concise, descriptive messages in imperative mood.
Coding conventions
Language baseline
- C++20 is mandatory. The project must compile with
-std=c++20and all source must use C++20 idioms. - Prefer standard library facilities over hand-written alternatives.
- No C-style constructs when a modern C++ equivalent exists.
Modern C++ guidelines
- Ownership: use
std::unique_ptrandstd::shared_ptr; never use rawnew/deleteor raw owning pointers. - Optional values: use
std::optional<T>instead of sentinel values or out-parameters. - Fallible operations: use
std::expected<T,E>orstd::error_codefor recoverable errors. Avoid exceptions for control flow. - References and views: use
std::span<T>for non-owning contiguous data andstd::string_viewfor read-only strings. - Compile-time computation: prefer
constexpr,consteval, andstd::integral_constantwhere applicable. - Type safety: use
enum class,std::variant, andstd::optionalinstead of bare integers or bool flags. - Concurrency: prefer
std::jthread,std::stop_token, and standard synchronization primitives. Avoid manual thread lifecycle management. - Containers: use
std::vector,std::array,std::deque, and standard containers; avoid C arrays and raw buffers. - Formatting and time: use
<format>/std::formatand<chrono>instead ofprintf,sprintf, or manual time math. - Algorithms: prefer
std::rangesalgorithms over hand-rolled loops where clarity improves. - Lambdas and callable abstractions: use
std::functionsparingly; prefer function pointers, templates, orautoparameters for simple callbacks. - Concepts and constraints: use
requiresclauses orstd::conceptsto express interface contracts where beneficial.
Style
- Use
namespace scfor all project code. - Prefer
snake_casefor functions and variables,PascalCasefor types,SCREAMING_SNAKE_CASEfor constants. - Keep headers minimal and free of unnecessary includes; forward-declare where possible.
- Format code with the configured formatter (
clang-formatif available). - Run
clang-formaton every C++ source or header file before considering a change complete; do not commit unformatted code. - The project formatter config is
.clang-formatat the repository root.
Error handling
- Use explicit error handling. Prefer
std::expected,std::optional, orstd::error_codeover exceptions for recoverable errors. - Use RAII for resource cleanup; do not leave resources unreleased on error paths.
- Avoid
assertfor user-facing error conditions; use real error returns or logging.