Skip to main content

Issues-FS

Project description

Issues-FS

PyPI version Python 3.12+ License: Apache 2.0

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.json files, 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-utils Type_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_safe decorator on public methods
  • Aligned imports/parameters at column 70-80
  • Explicit is True / is False for booleans

Dependencies

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

issues_fs-0.6.0.tar.gz (64.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

issues_fs-0.6.0-py3-none-any.whl (97.3 kB view details)

Uploaded Python 3

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

Hashes for issues_fs-0.6.0.tar.gz
Algorithm Hash digest
SHA256 809f298553b4ae1e97ea1d6810789d68dfb81ac010a9b5130e7de886b24f2eb4
MD5 89a69ebe3ea32361ff34fce4f85f8314
BLAKE2b-256 b0cc7cf873ef84bc68d414c65c2d328c722accbe832d5872374cf471bbc4f977

See more details on using hashes here.

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

Hashes for issues_fs-0.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 36051cf4904b3e785c4df51340bca2d4552136fd8ef602e78991173368d8d8bb
MD5 5f445f0c8412b16ee0fe88fb41bbaf99
BLAKE2b-256 25ebd0478b4e7a14065e5a640f42f845f06ffa5b28acac89c42b66041078073a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page