Source Importers¶
Source importers fetch context from external services and synthesize it into knowledge entries and decisions. Unlike adapters (bidirectional, model AI tools) and EDA parsers (local files), source importers connect to remote APIs.
Architecture¶
The src/ctx/sources/ package is separate from adapters and EDA parsers:
- Adapters (
src/ctx/adapters/): bidirectional import/export for AI tools - EDA parsers (
src/ctx/eda/parsers/): import-only, local files - Sources (
src/ctx/sources/): import-only, remote services
Data models¶
SourceConfig¶
Configuration for a source import operation:
@dataclass
class SourceConfig:
repo: str # "owner/repo" (required)
labels: list[str] = [] # Filter by labels
state: str = "all" # "open", "closed", "all"
since: str = "" # ISO date filter
issue_number: int | None = None # Single issue import
limit: int = 50 # Max issues to fetch
as_decisions: bool = False # Import closed issues as decisions
SourceItem¶
A single item produced by a source importer:
@dataclass
class SourceItem:
type: str # "knowledge" or "decision"
key: str # e.g. "github-issue-ihp-open-pdk-835"
content: str # Synthesized markdown
source: str # Origin URL or reference
# Decision-specific fields (populated when type == "decision")
title: str = ""
context: str = ""
decision_text: str = ""
consequences: str = ""
GitHub Source¶
The GitHubSource class (src/ctx/sources/github.py) imports GitHub issues as knowledge entries or decisions.
Why gh CLI¶
The implementation uses the gh CLI instead of PyGithub or the REST API directly:
- Zero additional dependencies
- Authentication handled by
gh auth - JSON output via
--jsonflag - Consistent with the project's subprocess patterns
Prerequisite
The gh CLI must be installed and authenticated (gh auth login) before using the GitHub source importer.
Key pattern¶
Issues are stored with the key pattern: github-issue-<repo-slug>-<number>
Example: github-issue-ihp-open-pdk-835
Repo auto-detection¶
When --repo is not specified, GitHubSource parses git remote -v output to detect the GitHub repository from SSH or HTTPS patterns.
Comment ranking¶
When synthesizing issue content, comments are ranked by quality:
- Author association: OWNER > MEMBER > CONTRIBUTOR > others
- Reactions: Higher reaction count ranks higher
- Code blocks: Comments with code are preferred
- Position: Later comments break ties
Bot comments and very short comments (under 20 characters) are filtered out.
Decision synthesis¶
When --as-decisions is used with closed issues:
- A knowledge entry is created with the full synthesized issue content
- A decision record (ADR) is also created with:
title: Issue titlecontext: Issue body (truncated)decision_text: Resolution from closing comment or top-ranked commentconsequences: Extracted from issue labels and milestone
Methods¶
| Method | Description |
|---|---|
fetch_issues(config) | Fetch issues from GitHub via gh CLI |
fetch_single_issue(config) | Fetch a single issue by number |
synthesize_issue(issue_data) | Convert raw issue JSON to markdown |
import_issues(config, store) | Full pipeline: fetch, synthesize, write to store |
detect_repo() | Auto-detect repo from git remote |
CLI usage¶
Import all open issues¶
Import a single issue¶
Filter by labels¶
Import closed issues as decisions¶
Filter by date¶
Preview without writing¶
All options¶
| Option | Default | Description |
|---|---|---|
--repo | Auto-detected | Repository in owner/repo format |
--issue | -- | Single issue number to import |
--labels | -- | Comma-separated label filter |
--state | all | Issue state: open, closed, all |
--since | -- | ISO date filter (e.g. 2025-01-01) |
--limit | 50 | Maximum number of issues to fetch |
--as-decisions | False | Also create decision records for closed issues |
--dry-run | False | Preview without writing |
--format | text | Output format: text or json |