danclaw/
├── README.md # Project overview, architecture, getting started
├── PROJECT_STRUCTURE.md # This file — directory layout and module descriptions
├── PRD.md # Product requirements document
├── plans/
│ └── danclaw.md # Implementation plan with phases and acceptance criteria
├── .env.example # Environment variable template (secrets placeholder)
├── .env # Actual secrets (git-ignored)
├── .dockerignore # Docker build context exclusions
├── .gitignore # Git ignore rules
├── pyproject.toml # Project metadata and dependencies
├── Dockerfile # Container image for the dispatcher service
├── docker-compose.yml # Multi-service orchestration with SQLite volume and .env
├── logging_config/
│ ├── __init__.py # Re-exports setup_logging
│ ├── setup.py # JSONFormatter and setup_logging: structured JSON logging for all components
│ └── README.md # Module documentation
├── cli/
│ ├── __init__.py # Python package marker
│ ├── agent.py # CLI entry point: `agent chat`, `agent list`, and `agent attach` subcommands over Unix socket
│ └── README.md # Module documentation
├── config/
│ ├── __init__.py # Re-exports load_config, validate_config, DanClawConfig, AgentConfig, ConfigError
│ ├── loader.py # Config loader: reads, validates, returns structured config
│ ├── danclaw.json # Main config: agent definitions, listener settings
│ └── README.md # Module documentation
├── dispatcher/
│ ├── __init__.py # Re-exports StandardMessage, init_db, Dispatcher, DispatchResult, etc.
│ ├── __main__.py # Entry point: config loading, DB init, SocketServer startup, signal handling
│ ├── database.py # SQLite schema init (sessions, messages, channel_bindings)
│ ├── dispatcher.py # Core Dispatcher class: routes messages through session → executor → storage pipeline
│ ├── executor.py # AI executor protocol, ExecutorResult, MockExecutor (canned responses), ClaudeExecutor (claude -p subprocess), CodexExecutor (codex -q subprocess), and FallbackExecutor (ordered fallback chain)
│ ├── models.py # StandardMessage frozen dataclass with serialization helpers
│ ├── permissions.py # Permission resolver: computes effective tool sets for channel + user pairs
│ ├── repository.py # Async repository abstraction for all DB access (CRUD on sessions, messages, channel_bindings)
│ ├── session_manager.py # High-level session lifecycle manager (get-or-create, state transitions, active listing)
│ ├── socket_server.py # Asyncio Unix domain socket server with client registry and fanout push
│ ├── telemetry.py # In-memory telemetry event recording (TelemetryEvent, TelemetryCollector)
│ └── README.md # Module documentation
├── listeners/
│ ├── __init__.py # Python package marker
│ ├── README.md # Module documentation
│ └── slack/
│ ├── __init__.py # Re-exports SlackListener
│ ├── listener.py # SlackListener: Socket Mode listener using slack-bolt
│ ├── __main__.py # Entry point for running as standalone process
│ └── README.md # Module documentation
├── personas/
│ ├── __init__.py # Re-exports load_persona, PersonaError
│ ├── loader.py # Persona loader: reads markdown files by name
│ ├── default.md # Default agent persona (system prompt)
│ ├── admin.md # Admin agent persona (full access, no approval gates)
│ └── README.md # Module documentation
├── tools/
│ ├── __init__.py # Python package marker
│ ├── obsidian_read.py # Read a file from an Obsidian vault (subprocess tool)
│ ├── obsidian_write.py # Create or update a file in an Obsidian vault (subprocess tool)
│ ├── obsidian_search.py # Search/list files in an Obsidian vault by name or content (subprocess tool)
│ ├── git_ops.py # Git add, commit, push operations (admin tool)
│ ├── deploy.py # Deploy tool: pull, rebuild, restart services (admin tool)
│ ├── trigger_deploy.py # Agent-callable deploy entry point with auto project root detection
│ ├── instrumented.py # Telemetry-instrumented wrappers for all tool functions
│ └── README.md # Module documentation
├── scripts/
│ └── e2e_test.py # Standalone end-to-end smoke test (requires claude CLI)
└── tests/ # Test suite
├── conftest.py # Shared test helpers (make_config)
├── test_admin_agent.py # Tests for admin agent config, permissions, dispatch, and git ops integration
├── test_e2e_claude.py # End-to-end integration test via ClaudeExecutor (manual marker)
├── test_git_ops.py # Tests for git add/commit/push tool functions and CLI
├── test_git_ops_telemetry.py # Tests for telemetry-instrumented git operation wrappers
├── test_deploy.py # Tests for deploy tool: pull, build, restart sequence
├── test_deploy_restriction.py # Tests for deploy restriction: non-admin channels/users cannot trigger deploy
├── test_deploy_telemetry.py # Tests for telemetry-instrumented deploy wrapper
├── test_trigger_deploy.py # Tests for agent-triggered deploy: tool, telemetry, permissions, and dispatcher integration
└── test_telemetry_query.py # Tests for telemetry query/filter/pagination methods
External Channel → Listener → StandardMessage → Dispatcher → Agent (AI Executor) → Response
↕
SQLite (sessions, messages)