tix¶
- class shai_tix.tix.Tix(dir_root: pathlib.Path)[source]¶
- session()[source]¶
Start a session with synchronized index database.
Rebuilds the SQLite index from filesystem on entry, ensuring all query_* methods return up-to-date results.
Usage:
tix = Tix(dir_root=path) with tix.session(): stories = tix.query_stories() tasks = tix.query_tasks()
- Returns:
Context manager yielding self
- iter_stories()[source]¶
Iterate over all story folders and yield Story objects.
Scans the stories directory and yields Story objects for each valid story folder found.
- Returns:
Generator yielding Story objects
- iter_tasks()[source]¶
Iterate over all task folders and yield Task objects.
Directly scans all task folders using glob pattern
stories/*/tasks/*for better efficiency, avoiding per-story API calls.- Returns:
Generator yielding Task objects
- iter_stories_or_tasks()[source]¶
Iterate over all stories and tasks using a single rglob scan.
Uses one
rglob("*")call to scan all paths, then filters by folder name prefix (story- or task-). No is_dir() check needed since Ticket.from_folder() validates the naming pattern.Paths are sorted to ensure depth-first order: each story appears before its tasks (shorter paths come first when sorted).
- Returns:
Generator yielding Story or Task objects
- ensure_dir_root()[source]¶
Ensure the root directory exists.
Creates the .tix directory if it doesn’t exist. This is called automatically before any database operations.
- rebuild_index_db()[source]¶
Rebuild the SQLite index database from filesystem.
Scans all story and task folders, creates ORM objects, and writes them to the SQLite database. Existing data is cleared first.
- get_next_id() int[source]¶
Get the next available ID from the index database.
Stories and tasks share the same global ID space. This method queries the database for max ID and returns max_id + 1. If no entities exist, returns 1.
- Returns:
Next available global ID
- query_stories(limit: int = 20) list[Story][source]¶
Query all stories from the index database.
Use within context manager to ensure database is synchronized.
- Parameters:
limit – Maximum number of stories to return
- Returns:
List of all Story objects from database, sorted by ID descending
- query_tasks(limit: int = 20) list[Task][source]¶
Query all tasks from the index database.
Use within context manager to ensure database is synchronized.
- Parameters:
limit – Maximum number of tasks to return
- Returns:
List of all Task objects from database, sorted by ID descending
- query_story(id: int) Story | None[source]¶
Query a single story by ID from the index database.
- Parameters:
id – Story ID to query
- Returns:
Story object if found, None otherwise
- query_task(id: int) Task | None[source]¶
Query a single task by ID from the index database.
- Parameters:
id – Task ID to query
- Returns:
Task object if found, None otherwise
- search_stories(title: str | None = None, date_lower: str | None = None, date_upper: str | None = None, id_lower: int | None = None, id_upper: int | None = None, status: list[StatusEnum] | None = None, limit: int = 20) list[Story][source]¶
Search stories by title, date range, ID range, and/or status.
At least one parameter must be provided. Results are sorted by ID descending (newest first).
Title matching: tokenizes the search string (splits on spaces and special characters, lowercases), matches if any token appears in the story title.
Status matching: when status list is provided, only stories with status in the list are returned. This requires reading metadata.json for each candidate story.
- Parameters:
title – Search string to match against story titles
date_lower – Minimum date (inclusive), format YYYY-MM-DD
date_upper – Maximum date (inclusive), format YYYY-MM-DD
id_lower – Minimum ID (inclusive)
id_upper – Maximum ID (inclusive)
status – List of status values to match (e.g., [StatusEnum.TODO, StatusEnum.IN_PROGRESS])
limit – Maximum number of stories to return
- Returns:
List of matching Story objects, sorted by ID descending
- Raises:
ValueError – If all parameters are None
- search_tasks(title: str | None = None, date_lower: str | None = None, date_upper: str | None = None, id_lower: int | None = None, id_upper: int | None = None, status: list[StatusEnum] | None = None, limit: int = 20) list[Task][source]¶
Search tasks by title, date range, ID range, and/or status.
At least one parameter must be provided. Results are sorted by ID descending (newest first).
Title matching: tokenizes the search string (splits on spaces and special characters, lowercases), matches if any token appears in the task title.
Status matching: when status list is provided, only tasks with status in the list are returned. This requires reading metadata.json for each candidate task.
- Parameters:
title – Search string to match against task titles
date_lower – Minimum date (inclusive), format YYYY-MM-DD
date_upper – Maximum date (inclusive), format YYYY-MM-DD
id_lower – Minimum ID (inclusive)
id_upper – Maximum ID (inclusive)
status – List of status values to match (e.g., [StatusEnum.TODO, StatusEnum.IN_PROGRESS])
limit – Maximum number of tasks to return
- Returns:
List of matching Task objects, sorted by ID descending
- Raises:
ValueError – If all parameters are None
- create_story(title: str, description: str | None = None) Story[source]¶
Create a new story with auto-generated ID.
Automatically assigns the next available ID and updates the index database.
- Parameters:
title – Story title (only letters, digits, and spaces allowed)
description – Optional story description
- Returns:
Created Story object
- Raises:
TitleValidationError – If title contains invalid characters
- get_story(id: int) Story | None[source]¶
Get a story by ID from the index database.
- Parameters:
id – Story ID to retrieve
- Returns:
Story object if found, None otherwise
- update_story(id: int, title: str | None = None, status: StatusEnum | None = None, description: str | None = None, report: str | None = None) Story | None[source]¶
Update a story’s metadata and content files.
Supports updating title, status, description, and report. When title changes, the story folder is renamed accordingly.
- Parameters:
id – Story ID to update
title – New title (optional, triggers folder rename)
status – New status value (optional)
description – New description content (optional)
report – New report content (optional)
- Returns:
Updated Story object, or None if story not found
- delete_story(id: int) bool[source]¶
Delete a story by ID from filesystem and index database.
Removes the story directory and all its tasks from filesystem, then removes the story from the index database.
- Parameters:
id – Story ID to delete
- Returns:
True if deleted, False if story not found
- create_task(story_id: int, title: str, description: str | None = None) Task[source]¶
Create a new task under a story with auto-generated ID.
- Parameters:
story_id – Parent story ID
title – Task title (only letters, digits, and spaces allowed)
description – Optional task description
- Returns:
Created Task object
- Raises:
TitleValidationError – If title contains invalid characters
ValueError – If parent story not found
- get_task(id: int) Task | None[source]¶
Get a task by ID from the index database.
- Parameters:
id – Task ID to retrieve
- Returns:
Task object if found, None otherwise
- update_task(id: int, title: str | None = None, status: StatusEnum | None = None, description: str | None = None, report: str | None = None) Task | None[source]¶
Update a task’s metadata and content files.
Supports updating title, status, description, and report. When title changes, the task folder is renamed accordingly.
- Parameters:
id – Task ID to update
title – New title (optional, triggers folder rename)
status – New status value (optional)
description – New description content (optional)
report – New report content (optional)
- Returns:
Updated Task object, or None if task not found