Conventions
Naming
- Files: snake_case for Python modules.
- Modules ending in
_fetch,_list,_show,_search,_poll,_mark,_clear,_status, or_servename one CLI command each. - Modules starting with
_are package-private helpers. - Test files are
test_<module>.pymatching the module under test. - Variables: snake_case (e.g.
thread_ts,latest_reply,user_names). - Functions / Methods: snake_case (e.g.
fetch_thread,load_thread_messages,fetch_search). - Classes: PascalCase, value objects as frozen dataclasses (e.g.
SlackClient,CachedMessage,ThreadRef,FetchResult,Credentials). - Constants: UPPER_SNAKE_CASE (e.g.
SCHEMA,SEARCH_SCHEMA,DEFAULT_LIMIT,MAX_RETRIES,CHANNEL_PREFIXES). - Private helpers: prefixed with an underscore (e.g.
_build_client,_format_ts,_latest_ts,_log_sql). - CLI subcommands: noun-verb groups built with cyclopts (e.g.
conversations fetch,channels list,users fetch,conversations read mark).
Directory Structure
The package is slackx, exposed through two console scripts: slackx and slack-fake-server.
slackx/
src/
slackx/
__init__.py
cache.py # Async fetch orchestration and result dataclasses
config.py # Credentials, XDG paths, credential resolution
slack_api.py # Async Slack Web API client (httpx)
storage.py # SQLite schema, CRUD, FTS5 search, read markers
urls.py # Permalink parsing into ThreadRef
workspace.py # Per-workspace cache database resolution
cli/
__init__.py # main entry point, registers command modules
commands/ # One module per command (cache_clear, channels_fetch, ...)
_internal/ # Shared app, args, client, rendering helpers (_render, _blocks, _mrkdwn, _style, _format, _fields, _refs, _poll, _duration, _channels, _client, _shared)
server/
app.py # FastAPI JSON API and static SPA serving
static/ # Served SPA assets
fake_slack/
__init__.py # slack-fake-server entry point
commands/ # run command
_internal/ # Fake Slack API internals (_config, _constants, _cursor, _data_pools, _generate, _handler, _rate_limiter, _server, _workspace)
tests/
test_blocks.py # Tests for rich block rendering
test_cache.py # Tests for cache orchestration
test_cli.py # Tests for CLI surface
test_config.py # Tests for config resolution
test_fake_slack.py # Tests for fake Slack server
test_mrkdwn.py # Tests for mrkdwn rendering
test_server.py # Tests for FastAPI JSON API
test_slack_api.py # Tests for Slack API client
test_storage.py # Tests for SQLite storage
test_style.py # Tests for terminal style rendering
test_urls.py # Tests for URL parsing
test_workspace.py # Tests for per-workspace database resolution
docs/ # mkdocs user guide, developer guide, and SDLC feature docs
web/dist/ # Built SPA served by the serve command
.sdlc/ # SDLC context, features, and templates
pyproject.toml # Project metadata, deps, tool config
README.md # User-facing documentation
Coding Standards
- Use frozen dataclasses for value objects (ThreadRef, Credentials, FetchResult, and similar).
- Use structlog for all logging; never use the stdlib logging module directly.
- Use
from __future__ import annotationsin modules that use modern type syntax. - Import the Slack client and cache functions lazily in CLI commands to avoid loading httpx when it is not needed.
- Use cyclopts for the CLI, with shared
Annotatedargument types incli/_internal/_shared.py. - Use context managers for database connections and transactions.
- Give public functions docstrings, and add brief docstrings to private helpers with non-obvious behavior.
- Use a TYPE_CHECKING guard for type-only imports.
- Keep
__init__.pyfiles minimal, for package initialization and entry points. - Test with pytest; use the
tmp_pathfixture for temporary databases andmonkeypatchfor environment and dependency injection. - Run
ruff checkandruff formatbefore committing; line length is 100 and lint selects E, F, I, B, UP, SIM.
Commit Messages
- Most commits use a short, imperative description without a prefix (e.g. "Move read tracking under conversations and mark read on show", "Group CLI commands into noun-verb subcommands").
- Some commits use a Conventional Commits prefix with an optional scope (e.g.
feat(web): ...,feat(cli): ...,chore: ...). - No prefix style is enforced; the repository mixes both forms.
Branching
mainis the default branch and what remote tracking points to.- Work happens on named branches merged back into
main, for examplesdlc,rich-output,serve-render-links, andspa. - Dependabot opens branches under
dependabot/.... - No branch name prefix convention is enforced.
SDLC Documentation Style
- One sentence per line in markdown files for easier diff and review.
- Use sentence case for headings, not title case.
- Prefer bullet lists over prose paragraphs.
- Use tables for structured data (requirements, specifications, and similar).
- Keep overview paragraphs to one or two sentences.