Issues-FS
Project description
Issues-FS
A file-system-based, graph-oriented issue tracking library with hierarchical structure and pluggable storage backends.
Issues-FS stores issues as JSON files in .issues/ directories inside git repos, enabling version control with Git, offline access, and flexible deployment options. It provides the core data layer for building issue tracking applications -- both for human developers and AI agent workflows.
Key Features
- File-Based Storage -- Issues stored as
issue.jsonfiles, easily version-controlled with Git - Graph-Oriented Model -- Issues, types, and links form a traversable graph via MGraph-DB integration
- Hierarchical Structure -- Nest issues inside other issues via
issues/subfolders (projects > versions > tasks > subtasks) - Pluggable Backends -- Works with memory, local disk, S3, SQLite, or ZIP via Memory-FS
- Type-Safe -- Built with
osbot-utilsType_Safe patterns for runtime validation - Recursive Discovery -- Find issues at any depth in the hierarchy
- Human-Readable -- Plain JSON files in a simple folder structure, inspectable with any text editor
Installation
pip install issues-fs
For command-line usage, also install the CLI:
pip install issues-fs-cli
Quick Start
from memory_fs.Memory_FS import Memory_FS
from memory_fs.storage_fs.Storage_FS__Memory import Storage_FS__Memory
from memory_fs.storage_fs.Storage_FS__Local_Disk import Storage_FS__Local_Disk
from issues_fs.issues.graph_services.Graph__Repository import Graph__Repository
from issues_fs.issues.graph_services.Node__Service import Node__Service
from issues_fs.issues.graph_services.Type__Service import Type__Service
from issues_fs.issues.storage.Path__Handler__Graph_Node import Path__Handler__Graph_Node
# Setup with in-memory storage (great for testing)
storage_fs = Storage_FS__Memory()
memory_fs = Memory_FS(storage_fs=storage_fs)
path_handler = Path__Handler__Graph_Node(base_path='')
repository = Graph__Repository(memory_fs=memory_fs, path_handler=path_handler)
# Or use local disk storage
storage_fs = Storage_FS__Local_Disk(root_path='.issues')
memory_fs = Memory_FS(storage_fs=storage_fs)
path_handler = Path__Handler__Graph_Node(base_path='')
repository = Graph__Repository(memory_fs=memory_fs, path_handler=path_handler)
# Initialize services
type_service = Type__Service(repository=repository)
node_service = Node__Service(repository=repository)
# Initialize default types
type_service.initialize_default_types()
Core Operations
Create an Issue
from issues_fs.schemas.graph.Schema__Node__Create__Request import Schema__Node__Create__Request
request = Schema__Node__Create__Request(
node_type = 'task',
title = 'Implement user authentication',
description = 'Add OAuth2 support',
status = 'backlog',
tags = ['security', 'backend']
)
response = node_service.create_node(request)
if response.success:
print(f"Created: {response.node.label}") # Task-1
Load an Issue
from issues_fs.schemas.safe_str.Safe_Str__Graph_Types import Safe_Str__Node_Type, Safe_Str__Node_Label
node = repository.node_load(
node_type = Safe_Str__Node_Type('task'),
label = Safe_Str__Node_Label('Task-1')
)
print(node.title) # "Implement user authentication"
print(node.status) # "backlog"
Find All Issues (Recursive)
# Find all issues, including nested ones
all_nodes = repository.nodes_list_all()
for info in all_nodes:
print(f"{info.label} ({info.node_type}) at {info.path}")
# Filter by root path
project_nodes = repository.nodes_list_all(
root_path=Safe_Str__File__Path('data/project/Project-1')
)
Load by Path
# Load issue by folder path
node = repository.node_load_by_path(
Safe_Str__File__Path('data/project/Project-1/issues/Version-1/issues/Task-1')
)
# Find path for a label
path = repository.node_find_path_by_label(Safe_Str__Node_Label('Task-1'))
Update an Issue
from issues_fs.schemas.graph.Schema__Node__Update__Request import Schema__Node__Update__Request
request = Schema__Node__Update__Request(
status = 'in-progress',
tags = ['security', 'backend', 'urgent']
)
response = node_service.update_node(
node_type = Safe_Str__Node_Type('task'),
label = Safe_Str__Node_Label('Task-1'),
request = request
)
Delete an Issue
response = node_service.delete_node(
node_type = Safe_Str__Node_Type('task'),
label = Safe_Str__Node_Label('Task-1')
)
MGraph-DB Integration
For efficient graph queries and visualization:
from issues_fs.mgraph.MGraph__Issues__Domain import MGraph__Issues__Domain
# Create sync service
from issues_fs.issues.graph_services.Graph__Repository__Factory import Graph__Repository__Factory
factory = Graph__Repository__Factory(root_path='.issues')
repository = factory.create_repository()
# Query the graph
sync_service = MGraph__Issues__Sync__Service(
repository = repository,
path_handler = path_handler
)
# Lazy load graph (syncs from filesystem)
graph = sync_service.ensure_loaded()
# Query by label
node = graph.get_node_by_label('Task-1')
# Get children
children = graph.get_children(node.node_id)
# Get ancestors (path to root)
ancestors = graph.get_ancestors(node.node_id)
# Force resync after external changes
sync_service.full_sync()
CLI Usage
The Issues-FS CLI provides command-line access to all operations:
# List all issues in the current repo
issues-fs list
# Create a new issue
issues-fs create --type task --title "Fix login bug"
# Show issue details
issues-fs show Task-1
# Update status
issues-fs update Task-1 --status in-progress
Install the CLI separately: pip install issues-fs-cli
Storage Structure
Issues-FS uses a simple, human-readable folder structure:
.issues/
├── config/
│ ├── node-types.json # Issue type definitions
│ └── link-types.json # Link type definitions
├── data/
│ └── {type}/
│ └── {Label}/
│ ├── issue.json # Issue data
│ └── issues/ # Child issues
│ └── {Child-Label}/
│ └── issue.json
└── indexes/
└── issues.mgraph.json # MGraph-DB cache
Example Structure
.issues/
├── data/
│ └── project/
│ └── Project-1/
│ ├── issue.json
│ └── issues/
│ ├── Version-1/
│ │ ├── issue.json
│ │ └── issues/
│ │ ├── Task-1/
│ │ │ └── issue.json
│ │ └── Bug-2/
│ │ └── issue.json
│ └── Version-2/
│ └── issue.json
Issue JSON Schema
{
"node_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"node_type": "task",
"node_index": 1,
"label": "Task-1",
"title": "Implement user authentication",
"description": "Add OAuth2 support for user login",
"status": "in-progress",
"created_at": 1706745600000,
"updated_at": 1706832000000,
"tags": ["security", "backend"],
"links": [
{
"verb": "blocks",
"target_label": "Task-2"
}
],
"properties": {
"priority": "high",
"estimate": "3d"
}
}
Node Types
Default node types are created on initialization:
type_service.initialize_default_types()
| Type | Display Name | Default Status |
|---|---|---|
git-repo |
Git Repo | active |
project |
Project | active |
version |
Version | planned |
task |
Task | backlog |
bug |
Bug | open |
feature |
Feature | backlog |
user-story |
User Story | backlog |
Custom Types
from issues_fs.schemas.graph.Schema__Node__Type import Schema__Node__Type
custom_type = Schema__Node__Type(
name = 'epic',
display_name = 'Epic',
color = '#9B59B6',
icon = 'rocket',
statuses = ['draft', 'active', 'completed'],
default_status = 'draft'
)
type_service.create_node_type(custom_type)
Architecture
┌──────────────────────────────────────────────────────────┐
│ Services │
│ Node__Service │ Type__Service │ Link__Service │
└───────────────────────────┬──────────────────────────────┘
│
┌───────────────────────────▼──────────────────────────────┐
│ Graph__Repository │
│ (Data access layer with Type_Safe) │
└───────────────────────────┬──────────────────────────────┘
│
┌───────────────────────────▼──────────────────────────────┐
│ Memory-FS │
│ Storage_FS__Memory │ Storage_FS__Local_Disk │ S3 │ … │
└──────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────┐
│ MGraph Integration │
│ MGraph__Issues__Sync__Service → MGraph__Issues__Domain │
└──────────────────────────────────────────────────────────┘
Key Components
| Component | Purpose |
|---|---|
Graph__Repository |
Data access layer for nodes, types, indexes |
Graph__Repository__Factory |
Factory for creating configured repository instances |
Node__Service |
Business logic for CRUD operations |
Type__Service |
Manage node and link type definitions |
Link__Service |
Manage links between issues |
Comments__Service |
Manage comments on issues |
MGraph__Issues__Sync__Service |
Syncs filesystem to MGraph-DB |
MGraph__Issues__Domain |
Graph operations and indexes |
Path__Handler__Graph_Node |
Generate filesystem paths for graph nodes |
Path__Handler__Issues |
Generate filesystem paths for issue operations |
Module Structure
issues_fs/
├── issues/
│ ├── graph_services/ # Core services (Repository, Node, Type, Link, Comments)
│ ├── storage/ # Path handlers for filesystem operations
│ ├── phase_1/ # Root issue and children services
│ └── status/ # Issue status management
├── mgraph/ # MGraph-DB integration (domain model, sync, schemas)
├── schemas/ # Data models and type definitions
│ ├── graph/ # Graph node schemas (create, update, delete)
│ ├── issues/ # Issue-specific schemas
│ ├── identifiers/ # ID types and generators
│ ├── safe_str/ # Type-safe string primitives
│ ├── enums/ # Enumeration types
│ └── status/ # Status-related schemas
├── scripts/ # Utility scripts
├── utils/ # Version info and utilities
└── version/ # Package version management
The Issues-FS Ecosystem
This library is the core of a broader ecosystem coordinated through Issues-FS__Dev, which includes a CLI, web service, documentation, and a team of 10 AI agent roles that collaborate through Issues-FS itself.
Repository Map
Core Libraries
| Repository | Description |
|---|---|
| Issues-FS | This repo -- core Python library |
| Issues-FS__CLI | Command-line interface |
| Issues-FS__Docs | Architecture documents, design briefs, specifications |
Services
| Repository | Description |
|---|---|
| Issues-FS__Service | FastAPI web service |
| Issues-FS__Service__UI | Web UI |
| Issues-FS__Service__Client__Python | Python client for the service API |
Development
| Repository | Description |
|---|---|
| Issues-FS__Dev | Parent orchestration repo for all submodules |
Agent Roles
| Repository | Description |
|---|---|
| Issues-FS__Dev__Role__Dev | Dev agent -- implementation |
| Issues-FS__Dev__Role__Architect | Architect agent -- system design |
| Issues-FS__Dev__Role__QA | QA agent -- testing |
| Issues-FS__Dev__Role__AppSec | AppSec agent -- security |
| Issues-FS__Dev__Role__DevOps | DevOps agent -- CI/CD |
| Issues-FS__Dev__Role__Librarian | Librarian agent -- knowledge connectivity |
| Issues-FS__Dev__Role__Cartographer | Cartographer agent -- system mapping |
| Issues-FS__Dev__Role__Historian | Historian agent -- project narrative |
| Issues-FS__Dev__Role__Journalist | Journalist agent -- reporting |
| Issues-FS__Dev__Role__Conductor | Conductor agent -- orchestration |
Human
| Repository | Description |
|---|---|
| Issues-FS__Dev__Human__Dinis_Cruz | Stakeholder repo for Dinis Cruz |
Current Status
- Version: v0.4.5
- Tests: 475+ test methods across 36 test files
- Python: 3.12+
- Status: Actively developed
Development
Setup
git clone https://github.com/owasp-sbot/Issues-FS.git
cd Issues-FS
pip install -e ".[dev]"
Run Tests
pytest
Code Style
This project follows the OSBot Python Formatting Guide:
- Type_Safe inheritance on all classes
- Safe_* primitives for type validation
@type_safedecorator on public methods- Aligned imports/parameters at column 70-80
- Explicit
is True/is Falsefor booleans
Dependencies
- Memory-FS -- Pluggable filesystem abstraction
- MGraph-DB -- Graph database operations
- OSBot-Utils -- Type_Safe utilities
Use Cases
- Git-native issue tracking -- Store issues alongside code, branch/merge with PRs
- Offline-first workflows -- Full functionality without network access
- Custom integrations -- Simple JSON format for easy tooling
- Hierarchical project management -- Organize epics > features > tasks > subtasks
- Embedded issue tracking -- Add issue tracking to any Python application
- AI agent collaboration -- Agents read and write issues as structured graph nodes
License
Apache License 2.0 -- see LICENSE for details.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file issues_fs-0.6.0.tar.gz.
File metadata
- Download URL: issues_fs-0.6.0.tar.gz
- Upload date:
- Size: 64.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
809f298553b4ae1e97ea1d6810789d68dfb81ac010a9b5130e7de886b24f2eb4
|
|
| MD5 |
89a69ebe3ea32361ff34fce4f85f8314
|
|
| BLAKE2b-256 |
b0cc7cf873ef84bc68d414c65c2d328c722accbe832d5872374cf471bbc4f977
|
File details
Details for the file issues_fs-0.6.0-py3-none-any.whl.
File metadata
- Download URL: issues_fs-0.6.0-py3-none-any.whl
- Upload date:
- Size: 97.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
36051cf4904b3e785c4df51340bca2d4552136fd8ef602e78991173368d8d8bb
|
|
| MD5 |
5f445f0c8412b16ee0fe88fb41bbaf99
|
|
| BLAKE2b-256 |
25ebd0478b4e7a14065e5a640f42f845f06ffa5b28acac89c42b66041078073a
|