codee-agent 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.
Files changed (69) hide show
  1. codee/.gitignore +2 -0
  2. codee/__init__.py +0 -0
  3. codee/admin.py +1672 -0
  4. codee/admin_api.py +61 -0
  5. codee/admin_cli.py +86 -0
  6. codee/admin_service.py +1005 -0
  7. codee/executor.py +381 -0
  8. codee/init_cli.py +82 -0
  9. codee/lib/__init__.py +0 -0
  10. codee/lib/cron_describe.py +33 -0
  11. codee/lib/runs_db.py +195 -0
  12. codee/lib/test_runs_db.py +199 -0
  13. codee/lib/test_trigger_cron_skills.py +485 -0
  14. codee/lib/test_trigger_issue_skills.py +93 -0
  15. codee/lib/trigger_aws_sqs_skills.py +224 -0
  16. codee/lib/trigger_cron_skills.py +364 -0
  17. codee/lib/trigger_email_skills.py +225 -0
  18. codee/lib/trigger_issue_skills.py +107 -0
  19. codee/mail_server.py +45 -0
  20. codee/start_cli.py +98 -0
  21. codee/templates/AGENTS.md +42 -0
  22. codee/templates/CLAUDE.md +1 -0
  23. codee/templates/skills/aws-sqs-alarm-response/SKILL.md +23 -0
  24. codee/templates/skills/cron-research-5xx-errors/SKILL.md +17 -0
  25. codee/templates/skills/story-code-reviewer/SKILL.md +29 -0
  26. codee/templates/skills/story-developer/SKILL.md +26 -0
  27. codee/templates/skills/story-planner/SKILL.md +35 -0
  28. codee/templates/skills/story-planner/assets/readme-template.md +43 -0
  29. codee/templates/skills/story-qa/SKILL.md +28 -0
  30. codee/templates/skills/task-developer/SKILL.md +25 -0
  31. codee/templates/skills/task-qa/SKILL.md +26 -0
  32. codee/test_admin_api.py +64 -0
  33. codee/test_admin_cli.py +63 -0
  34. codee/test_admin_service.py +897 -0
  35. codee/test_executor.py +190 -0
  36. codee/test_init_cli.py +131 -0
  37. codee/test_memory_index.py +31 -0
  38. codee/test_start_cli.py +164 -0
  39. codee/workflow_graph.py +83 -0
  40. codee_admin/__init__.py +1 -0
  41. codee_admin/codee_admin.py +4 -0
  42. codee_agent-0.1.0.dist-info/METADATA +66 -0
  43. codee_agent-0.1.0.dist-info/RECORD +69 -0
  44. codee_agent-0.1.0.dist-info/WHEEL +4 -0
  45. codee_agent-0.1.0.dist-info/entry_points.txt +6 -0
  46. codee_agent-0.1.0.dist-info/licenses/LICENSE +21 -0
  47. codee_agent_abstract/__init__.py +0 -0
  48. codee_agent_abstract/provider.py +56 -0
  49. codee_agent_claude_code/__init__.py +0 -0
  50. codee_agent_claude_code/provider.py +90 -0
  51. codee_agent_github_copilot/__init__.py +0 -0
  52. codee_agent_github_copilot/provider.py +253 -0
  53. codee_agent_github_copilot/test.py +176 -0
  54. codee_database/__init__.py +0 -0
  55. codee_database/database.py +13 -0
  56. codee_database/oauth_tokens.py +148 -0
  57. codee_main_context/__init__.py +0 -0
  58. codee_main_context/context.py +127 -0
  59. codee_main_context/logging.py +111 -0
  60. codee_main_context/test_logging.py +90 -0
  61. codee_tasks_abstract/__init__.py +0 -0
  62. codee_tasks_abstract/provider.py +58 -0
  63. codee_tasks_azure_devops/__init__.py +0 -0
  64. codee_tasks_azure_devops/oauth.py +346 -0
  65. codee_tasks_azure_devops/provider.py +207 -0
  66. codee_tasks_azure_devops/test.py +462 -0
  67. codee_tasks_jira/__init__.py +0 -0
  68. codee_tasks_jira/provider.py +162 -0
  69. codee_tasks_jira/test.py +75 -0
codee/admin_api.py ADDED
@@ -0,0 +1,61 @@
1
+ """Plain HTTP endpoints served alongside the Reflex pages.
2
+
3
+ OAuth callbacks can't be Reflex pages: the authorization code would have to
4
+ travel through the browser and into a page's ``on_load`` before anything could
5
+ be done with it. Handling them as backend routes keeps the code and the client
6
+ secret server-side, and lets the browser be bounced straight back to /settings.
7
+
8
+ Reflex mounts its own ASGI app underneath this Starlette app (see
9
+ ``api_transformer`` in :mod:`codee.admin`), so these routes are matched first
10
+ and everything else falls through to the UI.
11
+ """
12
+ from urllib.parse import urlencode
13
+
14
+ from starlette.applications import Starlette
15
+ from starlette.requests import Request
16
+ from starlette.responses import RedirectResponse
17
+ from starlette.routing import Route
18
+
19
+ from codee.admin_service import AdminService
20
+ from codee_tasks_azure_devops.oauth import CALLBACK_PATH
21
+
22
+ SETTINGS_PATH = "/settings"
23
+
24
+ # Its own service instance: this route runs outside any Reflex session, and
25
+ # every handler re-reads settings from disk anyway.
26
+ _service = AdminService()
27
+
28
+
29
+ def _back_to_settings(connected: bool, message: str) -> RedirectResponse:
30
+ """Return to the settings page carrying the outcome for the UI to toast."""
31
+ query = urlencode(
32
+ {"azure": "connected" if connected else "error", "message": message})
33
+ # 303: the callback is a GET, and the browser should land on /settings as a
34
+ # fresh GET rather than replaying anything.
35
+ return RedirectResponse(f"{SETTINGS_PATH}?{query}", status_code=303)
36
+
37
+
38
+ def azure_devops_callback(request: Request) -> RedirectResponse:
39
+ """Entra ID redirects here with ?code&state, or with ?error on refusal.
40
+
41
+ Defined as a sync handler on purpose: the token exchange is a blocking HTTP
42
+ call, so Starlette runs it in a worker thread instead of stalling the event
43
+ loop that serves the rest of the admin UI.
44
+ """
45
+ params = request.query_params
46
+ if params.get("error"):
47
+ description = params.get("error_description") or params["error"]
48
+ return _back_to_settings(False, description.splitlines()[0])
49
+
50
+ code, state = params.get("code"), params.get("state")
51
+ if not code or not state:
52
+ return _back_to_settings(
53
+ False, "Azure DevOps did not return an authorization code.")
54
+
55
+ connected, message = _service.complete_azure_authorization(code, state)
56
+ return _back_to_settings(connected, message)
57
+
58
+
59
+ api_app = Starlette(routes=[
60
+ Route(CALLBACK_PATH, azure_devops_callback, methods=["GET"]),
61
+ ])
codee/admin_cli.py ADDED
@@ -0,0 +1,86 @@
1
+ """Console-script launcher for the Reflex admin UI."""
2
+ import argparse
3
+ import os
4
+ import sys
5
+ from pathlib import Path
6
+
7
+ from codee.admin_service import DEFAULT_ADMIN_PORT
8
+ from codee_main_context.context import data_dir, project_root
9
+ from codee_main_context.logging import (
10
+ configure_logging, enable_debug, get_logger, verbose_debug_enabled)
11
+
12
+
13
+ log = get_logger(__name__)
14
+
15
+
16
+ RXCONFIG = """import reflex as rx
17
+
18
+ config = rx.Config(
19
+ app_name="codee_admin",
20
+ telemetry_enabled=False,
21
+ show_built_with_reflex=False,
22
+ plugins=[
23
+ rx.plugins.RadixThemesPlugin(
24
+ theme=rx.theme(
25
+ accent_color="green",
26
+ gray_color="sage",
27
+ radius="small",
28
+ appearance="inherit",
29
+ )
30
+ ),
31
+ ],
32
+ disable_plugins=[rx.plugins.SitemapPlugin],
33
+ )
34
+ """
35
+
36
+
37
+ def _runtime_directory(root: Path) -> Path:
38
+ runtime = data_dir(root) / "reflex"
39
+ runtime.mkdir(parents=True, exist_ok=True)
40
+ config_path = runtime / "rxconfig.py"
41
+ if not config_path.exists() or config_path.read_text() != RXCONFIG:
42
+ config_path.write_text(RXCONFIG)
43
+ return runtime
44
+
45
+
46
+ def main() -> int:
47
+ parser = argparse.ArgumentParser(prog="codee-admin")
48
+ parser.add_argument("--port", "--server.port",
49
+ dest="port", type=int, default=DEFAULT_ADMIN_PORT)
50
+ parser.add_argument("-d", "--debug", action="store_true",
51
+ help="log debug messages")
52
+ arguments, reflex_arguments = parser.parse_known_args()
53
+
54
+ if arguments.debug:
55
+ enable_debug()
56
+ configure_logging()
57
+
58
+ root = project_root().resolve()
59
+ codee_data = data_dir(root).resolve()
60
+ os.environ["CODEE_PROJECT_ROOT"] = str(root)
61
+ os.environ["CODEE_DATA_DIR"] = str(codee_data)
62
+ os.environ["REFLEX_API_URL"] = f"http://127.0.0.1:{arguments.port}"
63
+ os.chdir(_runtime_directory(root))
64
+
65
+ from reflex.reflex import cli
66
+
67
+ sys.argv = [
68
+ "reflex",
69
+ "run",
70
+ "--env",
71
+ "prod",
72
+ "--single-port",
73
+ "--frontend-port",
74
+ str(arguments.port),
75
+ # Reflex keeps its own logger; only CODEE_DEBUG=all turns it up, since
76
+ # its debug output is far noisier than ours.
77
+ *(["--loglevel", "debug"] if verbose_debug_enabled() else []),
78
+ *reflex_arguments,
79
+ ]
80
+ log.debug("root=%s data=%s reflex argv=%s", root, codee_data, sys.argv)
81
+ cli()
82
+ return 0
83
+
84
+
85
+ if __name__ == "__main__":
86
+ sys.exit(main())