polycoding 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cli/__init__.py +53 -0
- cli/db.py +67 -0
- cli/flow.py +187 -0
- cli/main.py +44 -0
- cli/project.py +166 -0
- cli/server.py +127 -0
- cli/utils.py +70 -0
- cli/worker.py +124 -0
- github_app/__init__.py +13 -0
- github_app/app.py +224 -0
- github_app/auth.py +137 -0
- github_app/config.py +38 -0
- github_app/installation_manager.py +194 -0
- github_app/label_mapper.py +112 -0
- github_app/models.py +112 -0
- github_app/webhook_handler.py +217 -0
- persistence/__init__.py +5 -0
- persistence/config.py +12 -0
- persistence/postgres.py +346 -0
- persistence/registry.py +111 -0
- persistence/tasks.py +178 -0
- polycoding-0.1.0.dist-info/METADATA +225 -0
- polycoding-0.1.0.dist-info/RECORD +41 -0
- polycoding-0.1.0.dist-info/WHEEL +4 -0
- polycoding-0.1.0.dist-info/entry_points.txt +3 -0
- polycoding-0.1.0.dist-info/licenses/LICENSE +20 -0
- project_manager/README.md +668 -0
- project_manager/__init__.py +29 -0
- project_manager/base.py +202 -0
- project_manager/config.py +36 -0
- project_manager/conversation/__init__.py +19 -0
- project_manager/conversation/flow.py +233 -0
- project_manager/conversation/types.py +64 -0
- project_manager/flow_runner.py +160 -0
- project_manager/git_utils.py +30 -0
- project_manager/github.py +367 -0
- project_manager/github_conversation.py +144 -0
- project_manager/github_projects_client.py +329 -0
- project_manager/hooks.py +377 -0
- project_manager/module.py +66 -0
- project_manager/types.py +79 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"""Project management module implementation for the Polycode plugin system."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
import pluggy
|
|
7
|
+
|
|
8
|
+
from modules.context import ModuleContext
|
|
9
|
+
|
|
10
|
+
log = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ProjectManagerModule:
|
|
14
|
+
"""Project management module for flow lifecycle integration.
|
|
15
|
+
|
|
16
|
+
This module provides GitHub-specific operations (PR creation, merging,
|
|
17
|
+
issue management) as a plugin that responds to flow lifecycle hooks.
|
|
18
|
+
It bridges the gap between generic flow phases and provider-specific
|
|
19
|
+
project management operations.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
name = "project_manager"
|
|
23
|
+
version = "0.1.0"
|
|
24
|
+
dependencies: list[str] = []
|
|
25
|
+
|
|
26
|
+
@classmethod
|
|
27
|
+
def on_load(cls, context: ModuleContext) -> None:
|
|
28
|
+
"""Initialize project manager module.
|
|
29
|
+
|
|
30
|
+
The module doesn't require any special initialization - the
|
|
31
|
+
project manager factory is created when hooks are registered.
|
|
32
|
+
"""
|
|
33
|
+
log.info(f"📦 Project manager module loaded (v{cls.version})")
|
|
34
|
+
|
|
35
|
+
@classmethod
|
|
36
|
+
def register_hooks(cls, hook_manager: pluggy.PluginManager) -> None:
|
|
37
|
+
"""Register project management hooks.
|
|
38
|
+
|
|
39
|
+
Creates and registers ProjectManagerHooks with a factory function
|
|
40
|
+
that instantiates the appropriate ProjectManager based on config.
|
|
41
|
+
"""
|
|
42
|
+
from project_manager import GitHubProjectManager
|
|
43
|
+
from project_manager.hooks import ProjectManagerHooks
|
|
44
|
+
|
|
45
|
+
def project_manager_factory(config):
|
|
46
|
+
"""Factory function to create project manager based on provider."""
|
|
47
|
+
provider = getattr(config, "provider", "github")
|
|
48
|
+
if provider == "github":
|
|
49
|
+
return GitHubProjectManager(config)
|
|
50
|
+
raise ValueError(f"Unknown project manager provider: {provider}")
|
|
51
|
+
|
|
52
|
+
hook_manager.register(ProjectManagerHooks(project_manager_factory))
|
|
53
|
+
log.info("🏹 Registered ProjectManagerHooks")
|
|
54
|
+
|
|
55
|
+
@classmethod
|
|
56
|
+
def get_models(cls) -> list[type]:
|
|
57
|
+
"""Return ORM models for this module.
|
|
58
|
+
|
|
59
|
+
Project manager doesn't define any database models.
|
|
60
|
+
"""
|
|
61
|
+
return []
|
|
62
|
+
|
|
63
|
+
@classmethod
|
|
64
|
+
def get_tasks(cls) -> list[dict[str, Any]]:
|
|
65
|
+
"""Return Celery task definitions for this module."""
|
|
66
|
+
return []
|
project_manager/types.py
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"""Common types for project management."""
|
|
2
|
+
|
|
3
|
+
from enum import Enum
|
|
4
|
+
from typing import Any, Optional
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class IssueStatus(str, Enum):
|
|
10
|
+
"""Standardized issue status values."""
|
|
11
|
+
|
|
12
|
+
TODO = "todo"
|
|
13
|
+
READY = "ready"
|
|
14
|
+
IN_PROGRESS = "in_progress"
|
|
15
|
+
REVIEWING = "reviewing"
|
|
16
|
+
DONE = "done"
|
|
17
|
+
BLOCKED = "blocked"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class Issue(BaseModel):
|
|
21
|
+
"""Generic issue representation."""
|
|
22
|
+
|
|
23
|
+
id: int
|
|
24
|
+
number: int
|
|
25
|
+
title: str
|
|
26
|
+
body: str | None = None
|
|
27
|
+
node_id: str | None = None
|
|
28
|
+
url: str | None = None
|
|
29
|
+
labels: list[str] = []
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class ProjectItem(BaseModel):
|
|
33
|
+
"""Generic project item representation."""
|
|
34
|
+
|
|
35
|
+
id: str
|
|
36
|
+
issue_number: int
|
|
37
|
+
title: str
|
|
38
|
+
body: str | None = None
|
|
39
|
+
status: str | None = None
|
|
40
|
+
issue_id: int | None = None
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class StatusMapping(BaseModel):
|
|
44
|
+
"""Maps standardized statuses to provider-specific values."""
|
|
45
|
+
|
|
46
|
+
todo: str = "Todo"
|
|
47
|
+
ready: str = "Ready"
|
|
48
|
+
in_progress: str = "In progress"
|
|
49
|
+
reviewing: str = "In review"
|
|
50
|
+
done: str = "Done"
|
|
51
|
+
blocked: str = "Blocked"
|
|
52
|
+
|
|
53
|
+
def to_provider_status(self, status: IssueStatus) -> str:
|
|
54
|
+
"""Convert standardized status to provider-specific value."""
|
|
55
|
+
return getattr(self, status.value)
|
|
56
|
+
|
|
57
|
+
@classmethod
|
|
58
|
+
def from_dict(cls, data: dict[str, str]) -> "StatusMapping":
|
|
59
|
+
"""Create mapping from dictionary."""
|
|
60
|
+
return cls(
|
|
61
|
+
todo=data.get("todo", "Todo"),
|
|
62
|
+
ready=data.get("ready", "Ready"),
|
|
63
|
+
in_progress=data.get("in_progress", "In progress"),
|
|
64
|
+
reviewing=data.get("reviewing", "In review"),
|
|
65
|
+
done=data.get("done", "Done"),
|
|
66
|
+
blocked=data.get("blocked", "Blocked"),
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class ProjectConfig(BaseModel):
|
|
71
|
+
"""Configuration for a project manager."""
|
|
72
|
+
|
|
73
|
+
provider: str
|
|
74
|
+
repo_owner: str
|
|
75
|
+
repo_name: str
|
|
76
|
+
project_identifier: Optional[str] = None
|
|
77
|
+
status_mapping: StatusMapping = StatusMapping()
|
|
78
|
+
token: str | None = None
|
|
79
|
+
extra: dict[str, Any] = {}
|