# drooph0904/post-agent architecture

> Architecture diagram of the GitHub repository drooph0904/post-agent, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-22). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/drooph0904/post-agent
- Repository: https://github.com/drooph0904/post-agent

## Overview

1. **What this repo is**
   - `devpost` is a Python CLI package that turns recent Git activity into publication-ready social posts.
   - Its core job is to gather local project context, detect which commits are new, ask Claude to draft content, then either post to Reddit and copy a tweet to the clipboard or stop for user review.

2. **Primary entrypoint and commands**
   - `devpost/main.py` is the command boundary for the whole system.
   - The CLI supports operational modes like `setup`, `init`, `run`, `status`, `reset`, plus run-time flags such as `--dry-run` and `--force`.
   - This is the top-level orchestration layer that decides which subsystems participate in each command.

3. **Repository-local inputs**
   - Two local files shape behavior: `.env` for credentials/configuration and `project_context.md` for project-specific grounding text.
   - `project_context.example.md` and `.env.example` show the expected inputs and indicate that the tool is meant to be initialized per project.

4. **Commit discovery boundary**
   - `devpost/git_reader.py` isolates all interaction with the local Git repository.
   - Its role is to fetch commits in the correct time/hash window, depending on whether the run is using post-log state or a forced time-based window.
   - This module is the source of truth for “what changed since last post.”

5. **Persistent memory between runs**
   - `devpost/post_log.py` stores which commits have already been published.
   - This is the main stateful boundary in the system and what makes repeated runs idempotent.
   - The README describes both hash-based incremental mode and a fallback 24-hour mode, so the log is central to deciding whether there is anything new to publish.

6. **Agent orchestration and context injection**
   - `devpost/agent.py` is the central coordinator.
   - It combines commit data, persisted post-log state, and project context, then feeds that into Claude to generate output.
   - The README explicitly calls out context injection, tool orchestration, human-in-the-loop approval, and conditional tool selection as patterns implemented here.

7. **Generation and validation**
   - `devpost/tweet_builder.py` handles tweet creation and the self-correction loop described in the README.
   - This module appears responsible for enforcing output validity before downstream publishing, rather than trusting raw model output.
   - That makes it a quality gate between LLM generation and any external side effect.

8. **Publishing adapters**
   - `devpost/reddit_poster.py` is the external publishing boundary for Reddit.
   - The README says the system creates content for 6 subreddits and a tweet, which implies this module adapts one generated content set into multiple Reddit-specific posts.
   - Tweet delivery is handled differently: it is copied to the clipboard rather than directly posted, which keeps the Twitter/X step human-mediated.

9. **Human review and presentation**
   - `devpost/display.py` is the user-facing preview layer.
   - It appears to render the generated posts for approval before any external actions occur.
   - This creates a clear human-in-the-loop boundary: the agent prepares content, the user approves it, and only then do side effects happen.

10. **Configuration and setup**
   - `devpost/config.py` centralizes runtime configuration such as API keys, paths, and per-project settings.
   - `devpost/__init__.py` and the packaging files suggest this is distributed as an installable CLI rather than a library.
   - Setup/init flows likely create or validate the per-project context and environment needed for later runs.

11. **End-to-end data flow**
   - The typical run is: CLI command → config load → post-log check → Git commit retrieval → project context injection → Claude generation → tweet validation → preview/approval → Reddit publishing + tweet clipboard copy → post-log update.
   - The key architectural idea is that external side effects happen only after the content has been grounded in real commits and reviewed by a human.

12. **Testing boundaries**
   - The `tests/` folder mirrors the main subsystems: config, git reading, agent flow, post log, tweet building, Reddit posting, and CLI behavior.
   - That suggests the codebase is organized around clear seams, with unit tests validating each adapter and orchestration step independently.

Main entry points: [`devpost/main.py`](https://github.com/drooph0904/post-agent/blob/main/devpost/main.py) (Main CLI), [`devpost/agent.py`](https://github.com/drooph0904/post-agent/blob/main/devpost/agent.py) (Agent), [`devpost/config.py`](https://github.com/drooph0904/post-agent/blob/main/devpost/config.py) (Config), [`devpost/display.py`](https://github.com/drooph0904/post-agent/blob/main/devpost/display.py) (Preview UI)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_cli["CLI boundary"]
  node_main["Main CLI<br/>entrypoint<br/>[main.py]"]
end

subgraph group_core["Core logic"]
  node_config["Config<br/>[config.py]"]
  node_agent{{"Agent<br/>orchestrator<br/>[agent.py]"}}
  node_git_reader[("Git reader<br/>commit discovery<br/>[git_reader.py]")]
  node_post_log[("Post log<br/>persistent state<br/>[post_log.py]")]
  node_tweet_builder["Tweet builder<br/>generation gate<br/>[tweet_builder.py]"]
end

subgraph group_inputs["Project inputs"]
  node_env_file["Env file<br/>project input<br/>[.env.example]"]
  node_context_file["Project context<br/>project input"]
end

subgraph group_delivery["Delivery"]
  node_display["Preview UI<br/>human review<br/>[display.py]"]
  node_reddit_poster["Reddit poster<br/>publishing adapter<br/>[reddit_poster.py]"]
end

node_main -->|"load settings"| node_config
node_main -->|"check state"| node_post_log
node_main -->|"select commits"| node_git_reader
node_main -->|"orchestrate"| node_agent
node_main -->|"preview"| node_display
node_main -->|"publish"| node_reddit_poster
node_agent -->|"consume commits"| node_git_reader
node_agent -->|"read memory"| node_post_log
node_agent -->|"use config"| node_config
node_agent -->|"draft tweet"| node_tweet_builder
node_tweet_builder -->|"approved draft"| node_display
node_display -->|"approved publish"| node_reddit_poster
node_config -.->|"reads"| node_env_file
node_config -.->|"grounds"| node_context_file
node_reddit_poster -->|"mark published"| node_post_log

click node_main "https://github.com/drooph0904/post-agent/blob/main/devpost/main.py"
click node_config "https://github.com/drooph0904/post-agent/blob/main/devpost/config.py"
click node_agent "https://github.com/drooph0904/post-agent/blob/main/devpost/agent.py"
click node_git_reader "https://github.com/drooph0904/post-agent/blob/main/devpost/git_reader.py"
click node_post_log "https://github.com/drooph0904/post-agent/blob/main/devpost/post_log.py"
click node_tweet_builder "https://github.com/drooph0904/post-agent/blob/main/devpost/tweet_builder.py"
click node_display "https://github.com/drooph0904/post-agent/blob/main/devpost/display.py"
click node_reddit_poster "https://github.com/drooph0904/post-agent/blob/main/devpost/reddit_poster.py"
click node_env_file "https://github.com/drooph0904/post-agent/blob/main/.env.example"
click node_context_file "https://github.com/drooph0904/post-agent/blob/main/project_context.example.md"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_main toneBlue
class node_config,node_agent,node_git_reader,node_post_log,node_tweet_builder toneAmber
class node_env_file,node_context_file toneMint
class node_display,node_reddit_poster toneRose
```

## Components

### CLI boundary

Command entrypoint and runtime mode selection.

- [Main CLI](https://github.com/drooph0904/post-agent/blob/main/devpost/main.py): entrypoint · Top-level command dispatcher for setup, init, run, status, reset, and flags. · `devpost/main.py`

### Core logic

Commit discovery, state tracking, orchestration, and generation.

- [Config](https://github.com/drooph0904/post-agent/blob/main/devpost/config.py): runtime config · Loads paths, credentials, and per-project settings. · `devpost/config.py`
- [Agent](https://github.com/drooph0904/post-agent/blob/main/devpost/agent.py): orchestrator · Coordinates commit data, context injection, model calls, and approval flow. · `devpost/agent.py`
- [Git reader](https://github.com/drooph0904/post-agent/blob/main/devpost/git_reader.py): commit discovery · Reads local git history and selects the commit window to publish. · `devpost/git_reader.py`
- [Post log](https://github.com/drooph0904/post-agent/blob/main/devpost/post_log.py): persistent state · Remembers which commits were already published for idempotent runs. · `devpost/post_log.py`
- [Tweet builder](https://github.com/drooph0904/post-agent/blob/main/devpost/tweet_builder.py): generation gate · Builds tweet text and applies validation or self-correction before delivery. · `devpost/tweet_builder.py`

### Project inputs

Repository-local files that ground behavior and configuration.

- [Env file](https://github.com/drooph0904/post-agent/blob/main/.env.example): project input · Per-project environment and credential file expected during setup. · `.env.example`
- [Project context](https://github.com/drooph0904/post-agent/blob/main/project_context.example.md): project input · Grounding document that supplies project-specific context for generation. · `project_context.example.md`

### Delivery

Preview and publishing adapters for external side effects.

- [Preview UI](https://github.com/drooph0904/post-agent/blob/main/devpost/display.py): human review · Renders generated content for user approval before side effects. · `devpost/display.py`
- [Reddit poster](https://github.com/drooph0904/post-agent/blob/main/devpost/reddit_poster.py): publishing adapter · Transforms generated content into subreddit-specific Reddit posts. · `devpost/reddit_poster.py`

## Connections

- Main CLI → Config: load settings · Initializes runtime configuration before executing a command.
- Main CLI → Post log: check state · Reads publication history to determine whether anything is new.
- Main CLI → Git reader: select commits · Chooses the commit window for the current run.
- Main CLI → Agent: orchestrate · Hands control to the content-generation workflow.
- Main CLI → Preview UI: preview · Shows generated content for user review in interactive runs.
- Main CLI → Reddit poster: publish · Triggers Reddit delivery after approval.
- Agent → Git reader: consume commits · Uses commit data as the source material for drafting posts.
- Agent → Post log: read memory · Consults prior publication state to avoid duplicates.
- Agent → Config: use config · Uses configured paths and credentials while coordinating the run.
- Agent → Tweet builder: draft tweet · Hands model output to the tweet-building and validation gate.
- Tweet builder → Preview UI: approved draft · Sends validated output for human review.
- Preview UI → Reddit poster: approved publish · Allows publishing only after the preview step succeeds.
- Config → Env file: reads · Loads credentials and local runtime configuration from the project env file.
- Config → Project context: grounds · Uses project-specific context as input for generation.
- Reddit poster → Post log: mark published · Updates state after successful external posting.
