observal-cli 0.2.0__tar.gz

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 (479) hide show
  1. observal_cli-0.2.0/.dockerignore +5 -0
  2. observal_cli-0.2.0/.editorconfig +18 -0
  3. observal_cli-0.2.0/.env.example +62 -0
  4. observal_cli-0.2.0/.gitattributes +2 -0
  5. observal_cli-0.2.0/.github/ISSUE_TEMPLATE/bug_report_form.yml +38 -0
  6. observal_cli-0.2.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
  7. observal_cli-0.2.0/.github/ISSUE_TEMPLATE/feature_request.yml +38 -0
  8. observal_cli-0.2.0/.github/pull_request_template.md +36 -0
  9. observal_cli-0.2.0/.github/workflows/ci.yml +281 -0
  10. observal_cli-0.2.0/.github/workflows/codeql.yml +34 -0
  11. observal_cli-0.2.0/.github/workflows/dco.yml +14 -0
  12. observal_cli-0.2.0/.github/workflows/deploy.yml +44 -0
  13. observal_cli-0.2.0/.github/workflows/publish.yml +48 -0
  14. observal_cli-0.2.0/.gitignore +41 -0
  15. observal_cli-0.2.0/.pre-commit-config.yaml +42 -0
  16. observal_cli-0.2.0/AGENTS.md +284 -0
  17. observal_cli-0.2.0/CHANGELOG.md +337 -0
  18. observal_cli-0.2.0/CODE_OF_CONDUCT.md +133 -0
  19. observal_cli-0.2.0/CONTRIBUTING.md +235 -0
  20. observal_cli-0.2.0/LICENSE +108 -0
  21. observal_cli-0.2.0/Makefile +84 -0
  22. observal_cli-0.2.0/PKG-INFO +528 -0
  23. observal_cli-0.2.0/README.md +492 -0
  24. observal_cli-0.2.0/SECURITY.md +49 -0
  25. observal_cli-0.2.0/SETUP.md +470 -0
  26. observal_cli-0.2.0/demo/README.md +74 -0
  27. observal_cli-0.2.0/demo/run_demo.sh +579 -0
  28. observal_cli-0.2.0/demo/test_all_types.sh +381 -0
  29. observal_cli-0.2.0/docker/Dockerfile.api +25 -0
  30. observal_cli-0.2.0/docker/Dockerfile.web +27 -0
  31. observal_cli-0.2.0/docker/docker-compose.yml +231 -0
  32. observal_cli-0.2.0/docker/entrypoint.sh +22 -0
  33. observal_cli-0.2.0/docs/cli.md +369 -0
  34. observal_cli-0.2.0/docs/eval.md +112 -0
  35. observal_cli-0.2.0/docs/images/ObservalLogo-removebg-preview.png +0 -0
  36. observal_cli-0.2.0/docs/images/agent-builder.png +0 -0
  37. observal_cli-0.2.0/docs/images/agents-list.png +0 -0
  38. observal_cli-0.2.0/docs/images/command-palette.png +0 -0
  39. observal_cli-0.2.0/docs/images/components-list.png +0 -0
  40. observal_cli-0.2.0/docs/images/dashboard.png +0 -0
  41. observal_cli-0.2.0/docs/images/errors.png +0 -0
  42. observal_cli-0.2.0/docs/images/eval-no-config.png +0 -0
  43. observal_cli-0.2.0/docs/images/leaderboard.png +0 -0
  44. observal_cli-0.2.0/docs/images/login-local.png +0 -0
  45. observal_cli-0.2.0/docs/images/registry-home.png +0 -0
  46. observal_cli-0.2.0/docs/images/review.png +0 -0
  47. observal_cli-0.2.0/docs/images/session-info-claude-code.png +0 -0
  48. observal_cli-0.2.0/docs/images/settings.png +0 -0
  49. observal_cli-0.2.0/docs/images/traces.png +0 -0
  50. observal_cli-0.2.0/docs/images/users.png +0 -0
  51. observal_cli-0.2.0/docs/kiro-compatibility-matrix.md +102 -0
  52. observal_cli-0.2.0/docs/kiro-research-notes.md +415 -0
  53. observal_cli-0.2.0/docs/kiro-setup.md +298 -0
  54. observal_cli-0.2.0/docs/logo-light.svg +28 -0
  55. observal_cli-0.2.0/docs/logo.svg +28 -0
  56. observal_cli-0.2.0/docs/superpowers/specs/2026-04-19-unarchive-agent-design.md +117 -0
  57. observal_cli-0.2.0/ee/LICENSE +172 -0
  58. observal_cli-0.2.0/ee/README.md +80 -0
  59. observal_cli-0.2.0/ee/__init__.py +55 -0
  60. observal_cli-0.2.0/ee/docs/cli.md +93 -0
  61. observal_cli-0.2.0/ee/observal_server/__init__.py +0 -0
  62. observal_cli-0.2.0/ee/observal_server/middleware/__init__.py +0 -0
  63. observal_cli-0.2.0/ee/observal_server/middleware/enterprise_guard.py +36 -0
  64. observal_cli-0.2.0/ee/observal_server/routes/__init__.py +19 -0
  65. observal_cli-0.2.0/ee/observal_server/routes/audit.py +152 -0
  66. observal_cli-0.2.0/ee/observal_server/routes/scim.py +35 -0
  67. observal_cli-0.2.0/ee/observal_server/routes/sso_saml.py +23 -0
  68. observal_cli-0.2.0/ee/observal_server/services/__init__.py +0 -0
  69. observal_cli-0.2.0/ee/observal_server/services/audit.py +172 -0
  70. observal_cli-0.2.0/ee/observal_server/services/config_validator.py +34 -0
  71. observal_cli-0.2.0/ee/plugins/__init__.py +1 -0
  72. observal_cli-0.2.0/grafana/dashboards/agent-activity.json +500 -0
  73. observal_cli-0.2.0/grafana/dashboards/audit-log.json +472 -0
  74. observal_cli-0.2.0/grafana/dashboards/cost-tracking.json +445 -0
  75. observal_cli-0.2.0/grafana/dashboards/error-rates.json +480 -0
  76. observal_cli-0.2.0/grafana/dashboards/performance-resources.json +661 -0
  77. observal_cli-0.2.0/grafana/dashboards/scores-eval.json +468 -0
  78. observal_cli-0.2.0/grafana/dashboards/session-overview.json +376 -0
  79. observal_cli-0.2.0/grafana/dashboards/token-usage.json +406 -0
  80. observal_cli-0.2.0/grafana/dashboards/tool-call-frequency.json +468 -0
  81. observal_cli-0.2.0/grafana/provisioning/dashboards/default.yaml +12 -0
  82. observal_cli-0.2.0/grafana/provisioning/datasources/clickhouse.yaml +17 -0
  83. observal_cli-0.2.0/magic-agent.json +28 -0
  84. observal_cli-0.2.0/observal-server/README.md +92 -0
  85. observal_cli-0.2.0/observal-server/alembic/README +1 -0
  86. observal_cli-0.2.0/observal-server/alembic/env.py +61 -0
  87. observal_cli-0.2.0/observal-server/alembic/script.py.mako +28 -0
  88. observal_cli-0.2.0/observal-server/alembic/versions/.gitkeep +0 -0
  89. observal_cli-0.2.0/observal-server/alembic/versions/0001_add_rbac_roles_and_is_demo.py +74 -0
  90. observal_cli-0.2.0/observal-server/alembic/versions/0002_add_password_reset_tokens.py +39 -0
  91. observal_cli-0.2.0/observal-server/alembic/versions/0003_add_api_keys_table.py +24 -0
  92. observal_cli-0.2.0/observal-server/alembic/versions/0004_normalize_email_case.py +63 -0
  93. observal_cli-0.2.0/observal-server/alembic/versions/0005_drop_password_reset_tokens.py +42 -0
  94. observal_cli-0.2.0/observal-server/alembic/versions/0006_drop_api_keys_and_legacy_key_hash.py +53 -0
  95. observal_cli-0.2.0/observal-server/alembic/versions/0007_add_alert_history.py +66 -0
  96. observal_cli-0.2.0/observal-server/alembic/versions/0008_add_mcp_framework_column.py +43 -0
  97. observal_cli-0.2.0/observal-server/alembic/versions/0009_add_docker_image_to_mcp_listings.py +43 -0
  98. observal_cli-0.2.0/observal-server/alembic/versions/0010_add_agents_name_uniqueness.py +62 -0
  99. observal_cli-0.2.0/observal-server/alembic/versions/0011_agent_review_and_bundles.py +90 -0
  100. observal_cli-0.2.0/observal-server/alembic/versions/0012_add_username_to_users.py +39 -0
  101. observal_cli-0.2.0/observal-server/alembic/versions/0013_add_mcp_command_args_url_headers.py +171 -0
  102. observal_cli-0.2.0/observal-server/alembic/versions/0014_add_draft_to_listing_status.py +33 -0
  103. observal_cli-0.2.0/observal-server/alembic/versions/0015_add_webhook_secret_to_alert_rules.py +46 -0
  104. observal_cli-0.2.0/observal-server/alembic/versions/0016_add_ide_feature_fields.py +58 -0
  105. observal_cli-0.2.0/observal-server/alembic.ini +43 -0
  106. observal_cli-0.2.0/observal-server/api/__init__.py +0 -0
  107. observal_cli-0.2.0/observal-server/api/deps.py +236 -0
  108. observal_cli-0.2.0/observal-server/api/graphql.py +619 -0
  109. observal_cli-0.2.0/observal-server/api/middleware/__init__.py +0 -0
  110. observal_cli-0.2.0/observal-server/api/middleware/content_type.py +135 -0
  111. observal_cli-0.2.0/observal-server/api/middleware/request_id.py +42 -0
  112. observal_cli-0.2.0/observal-server/api/ratelimit.py +14 -0
  113. observal_cli-0.2.0/observal-server/api/routes/__init__.py +0 -0
  114. observal_cli-0.2.0/observal-server/api/routes/admin.py +706 -0
  115. observal_cli-0.2.0/observal-server/api/routes/agent.py +1217 -0
  116. observal_cli-0.2.0/observal-server/api/routes/alert.py +249 -0
  117. observal_cli-0.2.0/observal-server/api/routes/auth.py +570 -0
  118. observal_cli-0.2.0/observal-server/api/routes/bulk.py +141 -0
  119. observal_cli-0.2.0/observal-server/api/routes/component_source.py +127 -0
  120. observal_cli-0.2.0/observal-server/api/routes/config.py +16 -0
  121. observal_cli-0.2.0/observal-server/api/routes/dashboard.py +888 -0
  122. observal_cli-0.2.0/observal-server/api/routes/eval.py +413 -0
  123. observal_cli-0.2.0/observal-server/api/routes/feedback.py +127 -0
  124. observal_cli-0.2.0/observal-server/api/routes/hook.py +238 -0
  125. observal_cli-0.2.0/observal-server/api/routes/jwks.py +27 -0
  126. observal_cli-0.2.0/observal-server/api/routes/mcp.py +351 -0
  127. observal_cli-0.2.0/observal-server/api/routes/otel_dashboard.py +1157 -0
  128. observal_cli-0.2.0/observal-server/api/routes/otlp.py +827 -0
  129. observal_cli-0.2.0/observal-server/api/routes/prompt.py +282 -0
  130. observal_cli-0.2.0/observal-server/api/routes/review.py +384 -0
  131. observal_cli-0.2.0/observal-server/api/routes/sandbox.py +235 -0
  132. observal_cli-0.2.0/observal-server/api/routes/scan.py +219 -0
  133. observal_cli-0.2.0/observal-server/api/routes/skill.py +246 -0
  134. observal_cli-0.2.0/observal-server/api/routes/telemetry.py +445 -0
  135. observal_cli-0.2.0/observal-server/api/sanitize.py +10 -0
  136. observal_cli-0.2.0/observal-server/config.py +74 -0
  137. observal_cli-0.2.0/observal-server/database.py +14 -0
  138. observal_cli-0.2.0/observal-server/main.py +300 -0
  139. observal_cli-0.2.0/observal-server/models/__init__.py +76 -0
  140. observal_cli-0.2.0/observal-server/models/agent.py +93 -0
  141. observal_cli-0.2.0/observal-server/models/agent_component.py +26 -0
  142. observal_cli-0.2.0/observal-server/models/alert.py +27 -0
  143. observal_cli-0.2.0/observal-server/models/alert_history.py +24 -0
  144. observal_cli-0.2.0/observal-server/models/base.py +5 -0
  145. observal_cli-0.2.0/observal-server/models/component_bundle.py +18 -0
  146. observal_cli-0.2.0/observal-server/models/component_source.py +32 -0
  147. observal_cli-0.2.0/observal-server/models/download.py +44 -0
  148. observal_cli-0.2.0/observal-server/models/enterprise_config.py +21 -0
  149. observal_cli-0.2.0/observal-server/models/eval.py +88 -0
  150. observal_cli-0.2.0/observal-server/models/exporter_config.py +25 -0
  151. observal_cli-0.2.0/observal-server/models/feedback.py +25 -0
  152. observal_cli-0.2.0/observal-server/models/hook.py +64 -0
  153. observal_cli-0.2.0/observal-server/models/mcp.py +93 -0
  154. observal_cli-0.2.0/observal-server/models/organization.py +22 -0
  155. observal_cli-0.2.0/observal-server/models/password_reset_token.py +18 -0
  156. observal_cli-0.2.0/observal-server/models/prompt.py +57 -0
  157. observal_cli-0.2.0/observal-server/models/sandbox.py +60 -0
  158. observal_cli-0.2.0/observal-server/models/sanitization.py +23 -0
  159. observal_cli-0.2.0/observal-server/models/scoring.py +300 -0
  160. observal_cli-0.2.0/observal-server/models/skill.py +65 -0
  161. observal_cli-0.2.0/observal-server/models/submission.py +23 -0
  162. observal_cli-0.2.0/observal-server/models/user.py +52 -0
  163. observal_cli-0.2.0/observal-server/pyproject.toml +44 -0
  164. observal_cli-0.2.0/observal-server/schemas/__init__.py +0 -0
  165. observal_cli-0.2.0/observal-server/schemas/admin.py +55 -0
  166. observal_cli-0.2.0/observal-server/schemas/agent.py +216 -0
  167. observal_cli-0.2.0/observal-server/schemas/alert.py +85 -0
  168. observal_cli-0.2.0/observal-server/schemas/auth.py +126 -0
  169. observal_cli-0.2.0/observal-server/schemas/bulk.py +42 -0
  170. observal_cli-0.2.0/observal-server/schemas/component_source.py +34 -0
  171. observal_cli-0.2.0/observal-server/schemas/constants.py +205 -0
  172. observal_cli-0.2.0/observal-server/schemas/dashboard.py +247 -0
  173. observal_cli-0.2.0/observal-server/schemas/eval.py +116 -0
  174. observal_cli-0.2.0/observal-server/schemas/feedback.py +28 -0
  175. observal_cli-0.2.0/observal-server/schemas/hook.py +124 -0
  176. observal_cli-0.2.0/observal-server/schemas/judge_output.py +64 -0
  177. observal_cli-0.2.0/observal-server/schemas/mcp.py +217 -0
  178. observal_cli-0.2.0/observal-server/schemas/prompt.py +90 -0
  179. observal_cli-0.2.0/observal-server/schemas/sandbox.py +111 -0
  180. observal_cli-0.2.0/observal-server/schemas/skill.py +115 -0
  181. observal_cli-0.2.0/observal-server/schemas/telemetry.py +137 -0
  182. observal_cli-0.2.0/observal-server/services/__init__.py +0 -0
  183. observal_cli-0.2.0/observal-server/services/agent_builder.py +611 -0
  184. observal_cli-0.2.0/observal-server/services/agent_config_generator.py +459 -0
  185. observal_cli-0.2.0/observal-server/services/agent_resolver.py +261 -0
  186. observal_cli-0.2.0/observal-server/services/alert_evaluator.py +249 -0
  187. observal_cli-0.2.0/observal-server/services/cache.py +85 -0
  188. observal_cli-0.2.0/observal-server/services/clickhouse.py +922 -0
  189. observal_cli-0.2.0/observal-server/services/codex_config_generator.py +26 -0
  190. observal_cli-0.2.0/observal-server/services/config_generator.py +220 -0
  191. observal_cli-0.2.0/observal-server/services/crypto.py +386 -0
  192. observal_cli-0.2.0/observal-server/services/demo_accounts.py +114 -0
  193. observal_cli-0.2.0/observal-server/services/download_tracker.py +141 -0
  194. observal_cli-0.2.0/observal-server/services/eval/__init__.py +0 -0
  195. observal_cli-0.2.0/observal-server/services/eval/adversarial_scorer.py +161 -0
  196. observal_cli-0.2.0/observal-server/services/eval/canary.py +252 -0
  197. observal_cli-0.2.0/observal-server/services/eval/eval_engine.py +247 -0
  198. observal_cli-0.2.0/observal-server/services/eval/eval_service.py +533 -0
  199. observal_cli-0.2.0/observal-server/services/eval/eval_watchdog.py +100 -0
  200. observal_cli-0.2.0/observal-server/services/eval/ragas_eval.py +341 -0
  201. observal_cli-0.2.0/observal-server/services/eval/sanitizer.py +269 -0
  202. observal_cli-0.2.0/observal-server/services/eval/score_aggregator.py +328 -0
  203. observal_cli-0.2.0/observal-server/services/eval/slm_scorer.py +322 -0
  204. observal_cli-0.2.0/observal-server/services/eval/structural_scorer.py +486 -0
  205. observal_cli-0.2.0/observal-server/services/events.py +145 -0
  206. observal_cli-0.2.0/observal-server/services/git_mirror_service.py +252 -0
  207. observal_cli-0.2.0/observal-server/services/hook_config_generator.py +65 -0
  208. observal_cli-0.2.0/observal-server/services/hook_materializer.py +617 -0
  209. observal_cli-0.2.0/observal-server/services/ide_feature_inference.py +50 -0
  210. observal_cli-0.2.0/observal-server/services/jwt_service.py +81 -0
  211. observal_cli-0.2.0/observal-server/services/mcp_validator.py +826 -0
  212. observal_cli-0.2.0/observal-server/services/redis.py +93 -0
  213. observal_cli-0.2.0/observal-server/services/registry_telemetry.py +106 -0
  214. observal_cli-0.2.0/observal-server/services/sandbox_config_generator.py +20 -0
  215. observal_cli-0.2.0/observal-server/services/secrets_redactor.py +237 -0
  216. observal_cli-0.2.0/observal-server/services/security_events.py +147 -0
  217. observal_cli-0.2.0/observal-server/services/skill_config_generator.py +98 -0
  218. observal_cli-0.2.0/observal-server/services/versioning.py +32 -0
  219. observal_cli-0.2.0/observal-server/services/webhook_delivery.py +231 -0
  220. observal_cli-0.2.0/observal-server/services/webhook_signer.py +88 -0
  221. observal_cli-0.2.0/observal-server/tests/__init__.py +0 -0
  222. observal_cli-0.2.0/observal-server/tests/conftest.py +21 -0
  223. observal_cli-0.2.0/observal-server/tests/test_config.py +57 -0
  224. observal_cli-0.2.0/observal-server/tests/test_crypto.py +412 -0
  225. observal_cli-0.2.0/observal-server/tests/test_jwt.py +279 -0
  226. observal_cli-0.2.0/observal-server/tests/test_multi_tenancy.py +403 -0
  227. observal_cli-0.2.0/observal-server/tests/test_payload_protection.py +362 -0
  228. observal_cli-0.2.0/observal-server/tests/test_rbac.py +114 -0
  229. observal_cli-0.2.0/observal-server/tests/test_security_events.py +155 -0
  230. observal_cli-0.2.0/observal-server/uv.lock +1769 -0
  231. observal_cli-0.2.0/observal-server/worker.py +124 -0
  232. observal_cli-0.2.0/observal_cli/README.md +150 -0
  233. observal_cli-0.2.0/observal_cli/__init__.py +0 -0
  234. observal_cli-0.2.0/observal_cli/analyzer.py +565 -0
  235. observal_cli-0.2.0/observal_cli/branding.py +19 -0
  236. observal_cli-0.2.0/observal_cli/client.py +264 -0
  237. observal_cli-0.2.0/observal_cli/cmd_agent.py +783 -0
  238. observal_cli-0.2.0/observal_cli/cmd_auth.py +823 -0
  239. observal_cli-0.2.0/observal_cli/cmd_doctor.py +674 -0
  240. observal_cli-0.2.0/observal_cli/cmd_hook.py +246 -0
  241. observal_cli-0.2.0/observal_cli/cmd_mcp.py +1044 -0
  242. observal_cli-0.2.0/observal_cli/cmd_migrate.py +764 -0
  243. observal_cli-0.2.0/observal_cli/cmd_ops.py +1250 -0
  244. observal_cli-0.2.0/observal_cli/cmd_profile.py +308 -0
  245. observal_cli-0.2.0/observal_cli/cmd_prompt.py +200 -0
  246. observal_cli-0.2.0/observal_cli/cmd_pull.py +324 -0
  247. observal_cli-0.2.0/observal_cli/cmd_sandbox.py +178 -0
  248. observal_cli-0.2.0/observal_cli/cmd_scan.py +1056 -0
  249. observal_cli-0.2.0/observal_cli/cmd_skill.py +202 -0
  250. observal_cli-0.2.0/observal_cli/cmd_uninstall.py +340 -0
  251. observal_cli-0.2.0/observal_cli/config.py +160 -0
  252. observal_cli-0.2.0/observal_cli/constants.py +151 -0
  253. observal_cli-0.2.0/observal_cli/hooks/__init__.py +0 -0
  254. observal_cli-0.2.0/observal_cli/hooks/buffer_event.py +97 -0
  255. observal_cli-0.2.0/observal_cli/hooks/flush_buffer.py +141 -0
  256. observal_cli-0.2.0/observal_cli/hooks/kiro_hook.py +210 -0
  257. observal_cli-0.2.0/observal_cli/hooks/kiro_stop_hook.py +220 -0
  258. observal_cli-0.2.0/observal_cli/hooks/observal-hook.sh +31 -0
  259. observal_cli-0.2.0/observal_cli/hooks/observal-stop-hook.sh +134 -0
  260. observal_cli-0.2.0/observal_cli/hooks/payload_crypto.py +78 -0
  261. observal_cli-0.2.0/observal_cli/hooks_spec.py +154 -0
  262. observal_cli-0.2.0/observal_cli/main.py +105 -0
  263. observal_cli-0.2.0/observal_cli/prompts.py +92 -0
  264. observal_cli-0.2.0/observal_cli/proxy.py +205 -0
  265. observal_cli-0.2.0/observal_cli/render.py +139 -0
  266. observal_cli-0.2.0/observal_cli/requirements.txt +3 -0
  267. observal_cli-0.2.0/observal_cli/sandbox_runner.py +217 -0
  268. observal_cli-0.2.0/observal_cli/settings_reconciler.py +188 -0
  269. observal_cli-0.2.0/observal_cli/shim.py +459 -0
  270. observal_cli-0.2.0/observal_cli/telemetry_buffer.py +163 -0
  271. observal_cli-0.2.0/otel-collector-config.yaml +98 -0
  272. observal_cli-0.2.0/pyproject.toml +131 -0
  273. observal_cli-0.2.0/renovate.json +37 -0
  274. observal_cli-0.2.0/scripts/check_migrations.py +106 -0
  275. observal_cli-0.2.0/scripts/new_migration.sh +75 -0
  276. observal_cli-0.2.0/scripts/seed_test_skill.py +196 -0
  277. observal_cli-0.2.0/test-agent.json +28 -0
  278. observal_cli-0.2.0/tests/README.md +100 -0
  279. observal_cli-0.2.0/tests/__init__.py +1 -0
  280. observal_cli-0.2.0/tests/conftest.py +5 -0
  281. observal_cli-0.2.0/tests/eval/__init__.py +0 -0
  282. observal_cli-0.2.0/tests/eval/test_adversarial_self.py +496 -0
  283. observal_cli-0.2.0/tests/eval/test_eval_completeness.py +518 -0
  284. observal_cli-0.2.0/tests/eval/test_eval_phase8.py +172 -0
  285. observal_cli-0.2.0/tests/eval/test_phase8a_sanitizer.py +456 -0
  286. observal_cli-0.2.0/tests/eval/test_phase8b_matching.py +220 -0
  287. observal_cli-0.2.0/tests/eval/test_phase8d_adversarial.py +244 -0
  288. observal_cli-0.2.0/tests/eval/test_phase8e_canary.py +279 -0
  289. observal_cli-0.2.0/tests/eval/test_phase8g_pipeline.py +381 -0
  290. observal_cli-0.2.0/tests/eval/test_ragas_eval.py +130 -0
  291. observal_cli-0.2.0/tests/eval/test_score_aggregator.py +257 -0
  292. observal_cli-0.2.0/tests/eval/test_slm_scorer.py +248 -0
  293. observal_cli-0.2.0/tests/eval/test_structural_scorer.py +183 -0
  294. observal_cli-0.2.0/tests/mock_mcp.py +89 -0
  295. observal_cli-0.2.0/tests/test_agent_composition.py +1448 -0
  296. observal_cli-0.2.0/tests/test_agent_config_generator.py +880 -0
  297. observal_cli-0.2.0/tests/test_agent_review.py +250 -0
  298. observal_cli-0.2.0/tests/test_alert_evaluator.py +452 -0
  299. observal_cli-0.2.0/tests/test_audit_logging.py +335 -0
  300. observal_cli-0.2.0/tests/test_auth_redis_down.py +154 -0
  301. observal_cli-0.2.0/tests/test_bulk.py +264 -0
  302. observal_cli-0.2.0/tests/test_bundles.py +265 -0
  303. observal_cli-0.2.0/tests/test_cli_errors.py +96 -0
  304. observal_cli-0.2.0/tests/test_clickhouse_phase1.py +406 -0
  305. observal_cli-0.2.0/tests/test_clickhouse_retention.py +84 -0
  306. observal_cli-0.2.0/tests/test_constants_sync.py +45 -0
  307. observal_cli-0.2.0/tests/test_demo_accounts.py +190 -0
  308. observal_cli-0.2.0/tests/test_deployment_guards.py +65 -0
  309. observal_cli-0.2.0/tests/test_docker_detection.py +423 -0
  310. observal_cli-0.2.0/tests/test_draft_workflow.py +350 -0
  311. observal_cli-0.2.0/tests/test_enterprise.py +198 -0
  312. observal_cli-0.2.0/tests/test_env_detection_and_config.py +968 -0
  313. observal_cli-0.2.0/tests/test_events.py +176 -0
  314. observal_cli-0.2.0/tests/test_field_validation.py +247 -0
  315. observal_cli-0.2.0/tests/test_git_mirror.py +463 -0
  316. observal_cli-0.2.0/tests/test_graphql_phase6.py +294 -0
  317. observal_cli-0.2.0/tests/test_health.py +197 -0
  318. observal_cli-0.2.0/tests/test_ingest_phase2.py +296 -0
  319. observal_cli-0.2.0/tests/test_migrate.py +985 -0
  320. observal_cli-0.2.0/tests/test_payload_crypto.py +261 -0
  321. observal_cli-0.2.0/tests/test_phase9_10.py +149 -0
  322. observal_cli-0.2.0/tests/test_proxy_phase4.py +169 -0
  323. observal_cli-0.2.0/tests/test_pull_and_agent_cli.py +806 -0
  324. observal_cli-0.2.0/tests/test_registry_types.py +671 -0
  325. observal_cli-0.2.0/tests/test_resilience.py +262 -0
  326. observal_cli-0.2.0/tests/test_review_queue.py +422 -0
  327. observal_cli-0.2.0/tests/test_sanitize.py +35 -0
  328. observal_cli-0.2.0/tests/test_scan_kiro_home.py +352 -0
  329. observal_cli-0.2.0/tests/test_schema_redesign.py +584 -0
  330. observal_cli-0.2.0/tests/test_secrets_redactor.py +332 -0
  331. observal_cli-0.2.0/tests/test_settings_reconciler.py +346 -0
  332. observal_cli-0.2.0/tests/test_shim_phase3.py +339 -0
  333. observal_cli-0.2.0/tests/test_skill_config_generator.py +144 -0
  334. observal_cli-0.2.0/tests/test_telemetry_collection.py +268 -0
  335. observal_cli-0.2.0/tests/test_uninstall.py +299 -0
  336. observal_cli-0.2.0/tests/test_uninstall_windows.py +240 -0
  337. observal_cli-0.2.0/tests/test_versioning.py +64 -0
  338. observal_cli-0.2.0/tests/test_webhook_delivery.py +231 -0
  339. observal_cli-0.2.0/tests/test_webhook_signer.py +142 -0
  340. observal_cli-0.2.0/tests/test_webhook_signer_properties.py +61 -0
  341. observal_cli-0.2.0/tests/test_worker_phase5.py +162 -0
  342. observal_cli-0.2.0/uv.lock +907 -0
  343. observal_cli-0.2.0/web/.gitignore +44 -0
  344. observal_cli-0.2.0/web/AGENTS.md +5 -0
  345. observal_cli-0.2.0/web/README.md +424 -0
  346. observal_cli-0.2.0/web/e2e/helpers.ts +224 -0
  347. observal_cli-0.2.0/web/e2e/kiro-agent-compat.spec.ts +118 -0
  348. observal_cli-0.2.0/web/e2e/kiro-cli.spec.ts +102 -0
  349. observal_cli-0.2.0/web/e2e/kiro-hooks.spec.ts +133 -0
  350. observal_cli-0.2.0/web/e2e/kiro-lifecycle.spec.ts +119 -0
  351. observal_cli-0.2.0/web/e2e/kiro-live.spec.ts +49 -0
  352. observal_cli-0.2.0/web/e2e/kiro-otlp-logs.spec.ts +122 -0
  353. observal_cli-0.2.0/web/e2e/kiro-otlp-traces.spec.ts +57 -0
  354. observal_cli-0.2.0/web/e2e/kiro-web-agents.spec.ts +42 -0
  355. observal_cli-0.2.0/web/e2e/kiro-web-traces.spec.ts +87 -0
  356. observal_cli-0.2.0/web/e2e/shim-merge.spec.ts +345 -0
  357. observal_cli-0.2.0/web/e2e/sso-login.spec.ts +304 -0
  358. observal_cli-0.2.0/web/e2e/unarchive-agent.spec.ts +167 -0
  359. observal_cli-0.2.0/web/eslint.config.mjs +17 -0
  360. observal_cli-0.2.0/web/next.config.ts +20 -0
  361. observal_cli-0.2.0/web/package.json +74 -0
  362. observal_cli-0.2.0/web/playwright.config.ts +22 -0
  363. observal_cli-0.2.0/web/pnpm-lock.yaml +5976 -0
  364. observal_cli-0.2.0/web/pnpm-workspace.yaml +3 -0
  365. observal_cli-0.2.0/web/postcss.config.mjs +7 -0
  366. observal_cli-0.2.0/web/public/file.svg +1 -0
  367. observal_cli-0.2.0/web/public/globe.svg +1 -0
  368. observal_cli-0.2.0/web/public/next.svg +1 -0
  369. observal_cli-0.2.0/web/public/vercel.svg +1 -0
  370. observal_cli-0.2.0/web/public/window.svg +1 -0
  371. observal_cli-0.2.0/web/src/app/(admin)/dashboard/page.tsx +235 -0
  372. observal_cli-0.2.0/web/src/app/(admin)/errors/page.tsx +247 -0
  373. observal_cli-0.2.0/web/src/app/(admin)/eval/[agentId]/page.tsx +226 -0
  374. observal_cli-0.2.0/web/src/app/(admin)/eval/page.tsx +139 -0
  375. observal_cli-0.2.0/web/src/app/(admin)/layout.tsx +25 -0
  376. observal_cli-0.2.0/web/src/app/(admin)/review/page.tsx +684 -0
  377. observal_cli-0.2.0/web/src/app/(admin)/settings/page.tsx +273 -0
  378. observal_cli-0.2.0/web/src/app/(admin)/users/page.tsx +296 -0
  379. observal_cli-0.2.0/web/src/app/(auth)/layout.tsx +14 -0
  380. observal_cli-0.2.0/web/src/app/(auth)/login/page.tsx +316 -0
  381. observal_cli-0.2.0/web/src/app/(registry)/agents/[id]/page.tsx +803 -0
  382. observal_cli-0.2.0/web/src/app/(registry)/agents/builder/page.tsx +1146 -0
  383. observal_cli-0.2.0/web/src/app/(registry)/agents/leaderboard/page.tsx +249 -0
  384. observal_cli-0.2.0/web/src/app/(registry)/agents/page.tsx +681 -0
  385. observal_cli-0.2.0/web/src/app/(registry)/components/[id]/page.tsx +313 -0
  386. observal_cli-0.2.0/web/src/app/(registry)/components/page.tsx +439 -0
  387. observal_cli-0.2.0/web/src/app/(registry)/layout.tsx +22 -0
  388. observal_cli-0.2.0/web/src/app/(registry)/page.tsx +333 -0
  389. observal_cli-0.2.0/web/src/app/(user)/layout.tsx +25 -0
  390. observal_cli-0.2.0/web/src/app/(user)/traces/[id]/page.tsx +1777 -0
  391. observal_cli-0.2.0/web/src/app/(user)/traces/page.tsx +458 -0
  392. observal_cli-0.2.0/web/src/app/favicon.ico +0 -0
  393. observal_cli-0.2.0/web/src/app/globals.css +559 -0
  394. observal_cli-0.2.0/web/src/app/icon.png +0 -0
  395. observal_cli-0.2.0/web/src/app/layout.tsx +47 -0
  396. observal_cli-0.2.0/web/src/app/providers.tsx +24 -0
  397. observal_cli-0.2.0/web/src/components/builder/preview-panel.tsx +344 -0
  398. observal_cli-0.2.0/web/src/components/builder/sortable-component-list.tsx +117 -0
  399. observal_cli-0.2.0/web/src/components/builder/validation-panel.tsx +66 -0
  400. observal_cli-0.2.0/web/src/components/dashboard/agent-aggregate-chart.tsx +90 -0
  401. observal_cli-0.2.0/web/src/components/dashboard/bar-list.tsx +51 -0
  402. observal_cli-0.2.0/web/src/components/dashboard/dashboard-card.tsx +51 -0
  403. observal_cli-0.2.0/web/src/components/dashboard/dimension-radar.tsx +68 -0
  404. observal_cli-0.2.0/web/src/components/dashboard/export-button.tsx +38 -0
  405. observal_cli-0.2.0/web/src/components/dashboard/latency-heatmap.tsx +94 -0
  406. observal_cli-0.2.0/web/src/components/dashboard/no-data.tsx +36 -0
  407. observal_cli-0.2.0/web/src/components/dashboard/penalty-accordion.tsx +107 -0
  408. observal_cli-0.2.0/web/src/components/dashboard/query-error.tsx +24 -0
  409. observal_cli-0.2.0/web/src/components/dashboard/stat-card.tsx +37 -0
  410. observal_cli-0.2.0/web/src/components/dashboard/time-range-select.tsx +38 -0
  411. observal_cli-0.2.0/web/src/components/dashboard/top-items-card.tsx +46 -0
  412. observal_cli-0.2.0/web/src/components/dashboard/trend-chart.tsx +81 -0
  413. observal_cli-0.2.0/web/src/components/layouts/admin-guard.tsx +11 -0
  414. observal_cli-0.2.0/web/src/components/layouts/auth-guard.tsx +19 -0
  415. observal_cli-0.2.0/web/src/components/layouts/dashboard-shell.tsx +25 -0
  416. observal_cli-0.2.0/web/src/components/layouts/page-header.tsx +115 -0
  417. observal_cli-0.2.0/web/src/components/layouts/role-guard.tsx +10 -0
  418. observal_cli-0.2.0/web/src/components/nav/command-menu.tsx +72 -0
  419. observal_cli-0.2.0/web/src/components/nav/github-star-banner.tsx +47 -0
  420. observal_cli-0.2.0/web/src/components/nav/nav-user.tsx +94 -0
  421. observal_cli-0.2.0/web/src/components/nav/registry-sidebar.tsx +216 -0
  422. observal_cli-0.2.0/web/src/components/registry/agent-card.tsx +103 -0
  423. observal_cli-0.2.0/web/src/components/registry/component-card.tsx +85 -0
  424. observal_cli-0.2.0/web/src/components/registry/feedback-list.tsx +19 -0
  425. observal_cli-0.2.0/web/src/components/registry/ide-badges.tsx +48 -0
  426. observal_cli-0.2.0/web/src/components/registry/install-dialog.tsx +101 -0
  427. observal_cli-0.2.0/web/src/components/registry/metrics-panel.tsx +73 -0
  428. observal_cli-0.2.0/web/src/components/registry/pull-command.tsx +78 -0
  429. observal_cli-0.2.0/web/src/components/registry/registry-detail.tsx +125 -0
  430. observal_cli-0.2.0/web/src/components/registry/registry-table.tsx +147 -0
  431. observal_cli-0.2.0/web/src/components/registry/review-form.tsx +101 -0
  432. observal_cli-0.2.0/web/src/components/registry/status-badge.tsx +36 -0
  433. observal_cli-0.2.0/web/src/components/registry/submit-component-dialog.tsx +717 -0
  434. observal_cli-0.2.0/web/src/components/shared/empty-state.tsx +46 -0
  435. observal_cli-0.2.0/web/src/components/shared/error-state.tsx +24 -0
  436. observal_cli-0.2.0/web/src/components/shared/skeleton-layouts.tsx +73 -0
  437. observal_cli-0.2.0/web/src/components/traces/span-tree.tsx +373 -0
  438. observal_cli-0.2.0/web/src/components/traces/trace-detail.tsx +162 -0
  439. observal_cli-0.2.0/web/src/components/traces/trace-list.tsx +216 -0
  440. observal_cli-0.2.0/web/src/components/ui/avatar.tsx +40 -0
  441. observal_cli-0.2.0/web/src/components/ui/badge.tsx +31 -0
  442. observal_cli-0.2.0/web/src/components/ui/breadcrumb.tsx +87 -0
  443. observal_cli-0.2.0/web/src/components/ui/button.tsx +53 -0
  444. observal_cli-0.2.0/web/src/components/ui/card.tsx +47 -0
  445. observal_cli-0.2.0/web/src/components/ui/command.tsx +125 -0
  446. observal_cli-0.2.0/web/src/components/ui/dialog.tsx +90 -0
  447. observal_cli-0.2.0/web/src/components/ui/dropdown-menu.tsx +170 -0
  448. observal_cli-0.2.0/web/src/components/ui/input.tsx +22 -0
  449. observal_cli-0.2.0/web/src/components/ui/label.tsx +21 -0
  450. observal_cli-0.2.0/web/src/components/ui/popover.tsx +31 -0
  451. observal_cli-0.2.0/web/src/components/ui/progress.tsx +25 -0
  452. observal_cli-0.2.0/web/src/components/ui/resizable.tsx +51 -0
  453. observal_cli-0.2.0/web/src/components/ui/scroll-area.tsx +42 -0
  454. observal_cli-0.2.0/web/src/components/ui/select.tsx +129 -0
  455. observal_cli-0.2.0/web/src/components/ui/separator.tsx +26 -0
  456. observal_cli-0.2.0/web/src/components/ui/sheet.tsx +105 -0
  457. observal_cli-0.2.0/web/src/components/ui/sidebar.tsx +480 -0
  458. observal_cli-0.2.0/web/src/components/ui/skeleton.tsx +7 -0
  459. observal_cli-0.2.0/web/src/components/ui/sonner.tsx +29 -0
  460. observal_cli-0.2.0/web/src/components/ui/switch.tsx +29 -0
  461. observal_cli-0.2.0/web/src/components/ui/table.tsx +63 -0
  462. observal_cli-0.2.0/web/src/components/ui/tabs.tsx +55 -0
  463. observal_cli-0.2.0/web/src/components/ui/textarea.tsx +21 -0
  464. observal_cli-0.2.0/web/src/components/ui/theme-switcher.tsx +43 -0
  465. observal_cli-0.2.0/web/src/components/ui/tooltip.tsx +30 -0
  466. observal_cli-0.2.0/web/src/hooks/use-admin-guard.ts +12 -0
  467. observal_cli-0.2.0/web/src/hooks/use-api.ts +696 -0
  468. observal_cli-0.2.0/web/src/hooks/use-auth.ts +80 -0
  469. observal_cli-0.2.0/web/src/hooks/use-deployment-config.ts +21 -0
  470. observal_cli-0.2.0/web/src/hooks/use-mobile.ts +19 -0
  471. observal_cli-0.2.0/web/src/hooks/use-role-guard.ts +64 -0
  472. observal_cli-0.2.0/web/src/lib/api.ts +395 -0
  473. observal_cli-0.2.0/web/src/lib/export.ts +30 -0
  474. observal_cli-0.2.0/web/src/lib/graphql-ws.ts +58 -0
  475. observal_cli-0.2.0/web/src/lib/ide-features.ts +58 -0
  476. observal_cli-0.2.0/web/src/lib/query-client.ts +11 -0
  477. observal_cli-0.2.0/web/src/lib/types.ts +339 -0
  478. observal_cli-0.2.0/web/src/lib/utils.ts +16 -0
  479. observal_cli-0.2.0/web/tsconfig.json +34 -0
@@ -0,0 +1,5 @@
1
+ **/node_modules
2
+ **/.next
3
+ **/.git
4
+ **/__pycache__
5
+ **/.venv
@@ -0,0 +1,18 @@
1
+ root = true
2
+
3
+ [*]
4
+ indent_style = space
5
+ indent_size = 4
6
+ end_of_line = lf
7
+ charset = utf-8
8
+ trim_trailing_whitespace = true
9
+ insert_final_newline = true
10
+
11
+ [*.{ts,tsx,js,jsx,json,css,html,yaml,yml}]
12
+ indent_size = 2
13
+
14
+ [*.md]
15
+ trim_trailing_whitespace = false
16
+
17
+ [Makefile]
18
+ indent_style = tab
@@ -0,0 +1,62 @@
1
+ # Core settings (have sensible defaults, override for production)
2
+ DATABASE_URL=postgresql+asyncpg://postgres:postgres@observal-db:5432/observal
3
+ # Recommended: generate a unique key for production
4
+ # python3 -c "import secrets; print(secrets.token_urlsafe(32))"
5
+ SECRET_KEY=change-me-to-a-random-string
6
+ CLICKHOUSE_URL=clickhouse://default:clickhouse@observal-clickhouse:8123/observal
7
+ REDIS_URL=redis://observal-redis:6379
8
+
9
+ # Postgres container credentials
10
+ POSTGRES_USER=postgres
11
+ POSTGRES_PASSWORD=postgres
12
+
13
+ # Optional: ClickHouse credentials
14
+ CLICKHOUSE_USER=default
15
+ CLICKHOUSE_PASSWORD=clickhouse
16
+
17
+ # Optional: Eval engine (LLM-as-judge)
18
+ EVAL_MODEL_URL=
19
+ EVAL_MODEL_API_KEY=
20
+ EVAL_MODEL_NAME=
21
+ EVAL_MODEL_PROVIDER=
22
+
23
+ # Optional: AWS credentials for Bedrock eval engine
24
+ AWS_ACCESS_KEY_ID=
25
+ AWS_SECRET_ACCESS_KEY=
26
+ AWS_SESSION_TOKEN=
27
+ AWS_REGION=us-east-1
28
+
29
+ # Optional: OAuth / SSO (disabled when unset)
30
+ OAUTH_CLIENT_ID=
31
+ OAUTH_CLIENT_SECRET=
32
+ OAUTH_SERVER_METADATA_URL=
33
+
34
+ # Deployment mode: "local" (default) or "enterprise"
35
+ # Local mode: self-registration, bootstrap endpoint, built-in account creation
36
+ # Enterprise mode: SSO-only login, SCIM provisioning, no self-registration
37
+ DEPLOYMENT_MODE=local
38
+
39
+ # ClickHouse data retention (days). Set to 0 to disable TTL.
40
+ DATA_RETENTION_DAYS=90
41
+
42
+ # Demo accounts — seeded on first startup when no real users exist.
43
+ # Automatically cleaned up when a real super_admin is created.
44
+ # Set all 8 vars to enable, or leave unset to skip demo seeding.
45
+ DEMO_SUPER_ADMIN_EMAIL=super@demo.example
46
+ DEMO_SUPER_ADMIN_PASSWORD=super-changeme
47
+ DEMO_ADMIN_EMAIL=admin@demo.example
48
+ DEMO_ADMIN_PASSWORD=admin-changeme
49
+ DEMO_REVIEWER_EMAIL=reviewer@demo.example
50
+ DEMO_REVIEWER_PASSWORD=reviewer-changeme
51
+ DEMO_USER_EMAIL=user@demo.example
52
+ DEMO_USER_PASSWORD=user-changeme
53
+
54
+ # Host port mappings (change these if defaults conflict with other services)
55
+ # API_HOST_PORT=8000
56
+ # POSTGRES_HOST_PORT=5432
57
+ # CLICKHOUSE_HOST_PORT=8123
58
+ # REDIS_HOST_PORT=6379
59
+ # WEB_HOST_PORT=3000
60
+ # OTEL_GRPC_HOST_PORT=4317
61
+ # OTEL_HTTP_HOST_PORT=4318
62
+ # GRAFANA_HOST_PORT=3001
@@ -0,0 +1,2 @@
1
+ # Force LF line endings for shell scripts (prevents CRLF breakage in Docker on Windows)
2
+ *.sh text eol=lf
@@ -0,0 +1,38 @@
1
+ name: 🐞 Bug
2
+ description: File a bug
3
+ type: "Bug"
4
+ labels: ["Needs Triage"]
5
+
6
+ body:
7
+
8
+ - type: checkboxes
9
+ id: contact
10
+ attributes:
11
+ label: Checked for duplicates?
12
+ description: Quickly search our [issues](https://github.com/BlazeUp-AI/Observal/issues) to see if a similar issue exists
13
+ options:
14
+ - label: This issue is not a duplicate
15
+ required: true
16
+
17
+ - type: textarea
18
+ id: steps
19
+ attributes:
20
+ label: What are the steps to reproduce this bug?
21
+ description: Briefly explain what you did which caused this bug to occur
22
+ validations:
23
+ required: true
24
+
25
+ - type: textarea
26
+ id: expected-behaviour
27
+ attributes:
28
+ label: Expected behaviour
29
+ description: Briefly describe what happened, and what should have happened
30
+ validations:
31
+ required: true
32
+
33
+ - type: textarea
34
+ id: extra_info
35
+ attributes:
36
+ label: (Optional) Anything else you want to share?
37
+ placeholder: List any extra information
38
+
@@ -0,0 +1,5 @@
1
+ blank_issues_enabled: true
2
+ contact_links:
3
+ - name: Github Discussions
4
+ url: https://github.com/BlazeUp-AI/Observal/discussions
5
+ about: Post on the forums for questions, support and feature requests!
@@ -0,0 +1,38 @@
1
+ name: 💡 Feature Request
2
+ description: Suggest an idea for this project
3
+ title: "[FEATURE] "
4
+ labels: ["accepted"]
5
+ body:
6
+ - type: markdown
7
+ attributes:
8
+ value: |
9
+ **Have a quick idea or want to gauge interest first?**
10
+ Consider starting a conversation in our [GitHub Discussions](https://github.com/BlazeUp-AI/Observal/discussions) before filing a formal feature request.
11
+
12
+ - type: textarea
13
+ id: problem
14
+ attributes:
15
+ label: Is your feature request related to a problem? Please describe.
16
+ description: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
17
+ validations:
18
+ required: true
19
+
20
+ - type: textarea
21
+ id: solution
22
+ attributes:
23
+ label: Describe the solution you'd like
24
+ description: A clear and concise description of what you want to happen.
25
+ validations:
26
+ required: true
27
+
28
+ - type: textarea
29
+ id: alternatives
30
+ attributes:
31
+ label: Describe alternatives you've considered
32
+ description: A clear and concise description of any alternative solutions or features you've considered.
33
+
34
+ - type: textarea
35
+ id: additional_context
36
+ attributes:
37
+ label: Additional context
38
+ description: Add any other context or screenshots about the feature request here.
@@ -0,0 +1,36 @@
1
+ <!--- Please fill the necessary details below -->
2
+ ## Purpose / Description
3
+ _Describe the problem or feature and motivation_
4
+
5
+ ## Fixes
6
+ * Fixes #<!-- replace this comment with the issue number e.g. 'Fixes #100'-->
7
+
8
+ ## Approach
9
+ _How does this change address the problem?_
10
+
11
+ ## How Has This Been Tested?
12
+
13
+ Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration
14
+
15
+ ## Learning (optional, can help others)
16
+ _Describe the research stage_
17
+
18
+ _Links to blog posts, patterns, libraries or addons used to solve this problem_
19
+
20
+ ## Checklist
21
+ _Please, go through these checks before submitting the PR._
22
+
23
+ - [ ] All commits are signed off (`git commit -s`) per the [DCO](https://developercertificate.org/)
24
+ - [ ] You have a descriptive commit message with a short title (first line, max 50 chars).
25
+ - [ ] You have commented your code, particularly in hard-to-understand areas
26
+ - [ ] You have performed a self-review of your own code
27
+ - [ ] UI changes: include screenshots of all affected screens (in particular showing any new or changed strings)
28
+
29
+ <!--- Uncomment this section ONLY if this PR introduces new resources (external libraries, icons etc)
30
+ ## Licenses
31
+ _For each new external resource, add a row to the table below:_
32
+
33
+ | Library | Description | License |
34
+ | --- | --- | --- |
35
+ | Sample Icon Library | Sample Description | [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) |
36
+ --->
@@ -0,0 +1,281 @@
1
+ # ─────────────────────────────────────────────────────────────────────────────
2
+ # Observal CI — runs on every PR targeting main and on pushes to main.
3
+ #
4
+ # Recommended branch-protection rules (Settings → Branches → main):
5
+ # Required status checks:
6
+ # • lint
7
+ # • test (3.11)
8
+ # • test (3.12)
9
+ # • test (3.13)
10
+ # • web-lint
11
+ # • docker-build
12
+ # • security-scan
13
+ # Require a pull request before merging
14
+ # Require approvals: 1
15
+ # Do not allow bypassing the above settings
16
+ # ─────────────────────────────────────────────────────────────────────────────
17
+
18
+ name: CI
19
+
20
+ on:
21
+ pull_request:
22
+ branches: [main]
23
+ push:
24
+ branches: [main]
25
+
26
+ concurrency:
27
+ group: ci-${{ github.ref }}
28
+ cancel-in-progress: true
29
+
30
+ # ── Job 0: Path filtering ─────────────────────────────────────────────────────
31
+ jobs:
32
+ changes:
33
+ runs-on: ubuntu-latest
34
+ permissions:
35
+ pull-requests: read
36
+ outputs:
37
+ python: ${{ steps.filter.outputs.python }}
38
+ web: ${{ steps.filter.outputs.web }}
39
+ docker: ${{ steps.filter.outputs.docker }}
40
+ steps:
41
+ - uses: actions/checkout@v6
42
+ - uses: dorny/paths-filter@v4
43
+ id: filter
44
+ with:
45
+ filters: |
46
+ python:
47
+ - 'observal_cli/**/*.py'
48
+ - 'observal-server/**/*.py'
49
+ - 'tests/**/*.py'
50
+ - 'pyproject.toml'
51
+ - 'uv.lock'
52
+ - 'Makefile'
53
+ - '.pre-commit-config.yaml'
54
+ - '.github/workflows/ci.yml'
55
+ web:
56
+ - 'web/**'
57
+ - '.github/workflows/ci.yml'
58
+ docker:
59
+ - 'docker/**'
60
+ - 'observal_cli/**'
61
+ - 'observal-server/**'
62
+ - 'web/**'
63
+ - 'pyproject.toml'
64
+ - 'uv.lock'
65
+ - 'web/package.json'
66
+ - 'web/pnpm-lock.yaml'
67
+ - '.env.example'
68
+ - '.github/workflows/ci.yml'
69
+
70
+ # ── Job 1: Python lint ────────────────────────────────────────────────────────
71
+ lint:
72
+ name: lint
73
+ runs-on: ubuntu-latest
74
+ needs: changes
75
+ steps:
76
+ - name: Skip if no Python changes
77
+ if: needs.changes.outputs.python != 'true'
78
+ run: |
79
+ echo "::notice::No Python changes detected, skipping lint"
80
+ echo "This job reports success to satisfy branch protection"
81
+
82
+ - uses: actions/checkout@v6
83
+ if: needs.changes.outputs.python == 'true'
84
+
85
+ - uses: astral-sh/setup-uv@v7
86
+ if: needs.changes.outputs.python == 'true'
87
+ with:
88
+ enable-cache: true
89
+
90
+ - name: Install Python 3.13
91
+ if: needs.changes.outputs.python == 'true'
92
+ run: uv python install 3.13
93
+
94
+ - name: ruff check
95
+ if: needs.changes.outputs.python == 'true'
96
+ run: uv run --with ruff==0.15.10 ruff check .
97
+
98
+ - name: ruff format --check
99
+ if: needs.changes.outputs.python == 'true'
100
+ run: uv run --with ruff==0.15.10 ruff format --check .
101
+
102
+ # ── Job 2: Python tests (matrix) ──────────────────────────────────────────────
103
+ test:
104
+ name: test (${{ matrix.python-version }})
105
+ runs-on: ubuntu-latest
106
+ needs: changes
107
+ strategy:
108
+ fail-fast: false
109
+ matrix:
110
+ python-version: ["3.11", "3.12", "3.13"]
111
+
112
+ steps:
113
+ - name: Skip if no Python changes
114
+ if: needs.changes.outputs.python != 'true'
115
+ run: |
116
+ echo "::notice::No Python changes detected, skipping test"
117
+ echo "This job reports success to satisfy branch protection"
118
+
119
+ - uses: actions/checkout@v6
120
+ if: needs.changes.outputs.python == 'true'
121
+
122
+ - uses: astral-sh/setup-uv@v7
123
+ if: needs.changes.outputs.python == 'true'
124
+ with:
125
+ enable-cache: true
126
+
127
+ - name: Install Python ${{ matrix.python-version }}
128
+ if: needs.changes.outputs.python == 'true'
129
+ run: uv python install ${{ matrix.python-version }}
130
+
131
+ - name: Install project dependencies
132
+ if: needs.changes.outputs.python == 'true'
133
+ run: |
134
+ cd observal-server
135
+ uv sync --python ${{ matrix.python-version }} --group dev
136
+
137
+ - name: Run pytest
138
+ if: needs.changes.outputs.python == 'true'
139
+ run: |
140
+ cd observal-server
141
+ uv run \
142
+ --python ${{ matrix.python-version }} \
143
+ --with asyncpg \
144
+ --with hypothesis \
145
+ pytest ../tests/ -q
146
+
147
+ # ── Job 3: Next.js lint + typecheck ───────────────────────────────────────────
148
+ web-lint:
149
+ name: web-lint
150
+ runs-on: ubuntu-latest
151
+ needs: changes
152
+ defaults:
153
+ run:
154
+ working-directory: web
155
+
156
+ steps:
157
+ - name: Skip if no web changes
158
+ if: needs.changes.outputs.web != 'true'
159
+ working-directory: .
160
+ run: |
161
+ echo "::notice::No web changes detected, skipping web-lint"
162
+ echo "This job reports success to satisfy branch protection"
163
+
164
+ - uses: actions/checkout@v6
165
+ if: needs.changes.outputs.web == 'true'
166
+
167
+ - uses: pnpm/action-setup@v4
168
+ if: needs.changes.outputs.web == 'true'
169
+ with:
170
+ version: 10
171
+
172
+ - uses: actions/setup-node@v6
173
+ if: needs.changes.outputs.web == 'true'
174
+ with:
175
+ node-version: 24
176
+ cache: pnpm
177
+ cache-dependency-path: web/pnpm-lock.yaml
178
+
179
+ - name: Install dependencies
180
+ if: needs.changes.outputs.web == 'true'
181
+ run: pnpm install --frozen-lockfile
182
+
183
+ - name: ESLint
184
+ if: needs.changes.outputs.web == 'true'
185
+ run: pnpm run lint
186
+
187
+ - name: TypeScript typecheck
188
+ if: needs.changes.outputs.web == 'true'
189
+ run: pnpm run typecheck
190
+
191
+ # ── Job 4: Import boundary check ─────────────────────────────────────────────
192
+ import-boundary:
193
+ name: import-boundary
194
+ runs-on: ubuntu-latest
195
+ needs: changes
196
+ if: needs.changes.outputs.python == 'true'
197
+ steps:
198
+ - uses: actions/checkout@v6
199
+
200
+ - name: Check ee/ import boundary
201
+ run: |
202
+ echo "Checking that core does not import from ee/..."
203
+ VIOLATIONS=$(grep -rn "from ee\b\|import ee\b" observal-server/ observal_cli/ --include="*.py" | grep -v "main.py" || true)
204
+ if [ -n "$VIOLATIONS" ]; then
205
+ echo "::error::Import boundary violation — core must not import from ee/"
206
+ echo "$VIOLATIONS"
207
+ exit 1
208
+ fi
209
+ echo "✓ No import boundary violations found"
210
+
211
+ # ── Job 5: Docker build ───────────────────────────────────────────────────────
212
+ docker-build:
213
+ name: docker-build
214
+ runs-on: ubuntu-latest
215
+ needs: changes
216
+ defaults:
217
+ run:
218
+ working-directory: docker
219
+
220
+ steps:
221
+ - name: Skip if no Docker changes
222
+ if: needs.changes.outputs.docker != 'true'
223
+ working-directory: .
224
+ run: |
225
+ echo "::notice::No Docker changes detected, skipping docker-build"
226
+ echo "This job reports success to satisfy branch protection"
227
+
228
+ - uses: actions/checkout@v6
229
+ if: needs.changes.outputs.docker == 'true'
230
+
231
+ - name: Create stub .env
232
+ if: needs.changes.outputs.docker == 'true'
233
+ run: touch ../.env
234
+
235
+ - name: Build images
236
+ if: needs.changes.outputs.docker == 'true'
237
+ run: docker compose build
238
+
239
+ # ── Job 5: Python SAST with bandit ──────────────────────────────────────────
240
+ security-scan:
241
+ name: security-scan
242
+ runs-on: ubuntu-latest
243
+ steps:
244
+ - uses: actions/checkout@v6
245
+ - uses: astral-sh/setup-uv@v7
246
+ with:
247
+ enable-cache: true
248
+ - name: Install Python 3.12
249
+ run: uv python install 3.12
250
+ - name: Run bandit
251
+ run: uv run --with bandit bandit -r observal-server/ observal_cli/ -c pyproject.toml -f json -o bandit-report.json || true
252
+ - name: Check bandit results
253
+ run: uv run --with bandit bandit -r observal-server/ observal_cli/ -c pyproject.toml -ll
254
+
255
+ # ── Job 6: Dependency audit ─────────────────────────────────────────────────
256
+ dependency-audit:
257
+ name: dependency-audit
258
+ runs-on: ubuntu-latest
259
+ steps:
260
+ - uses: actions/checkout@v6
261
+
262
+ - name: Python dependency audit
263
+ uses: astral-sh/setup-uv@v7
264
+ with:
265
+ enable-cache: true
266
+ - name: Run pip-audit
267
+ # TODO: burn down pre-existing advisories then remove || true
268
+ run: |
269
+ uv python install 3.12
270
+ cd observal-server
271
+ uv run --with pip-audit pip-audit --strict --desc || true
272
+
273
+ - name: JS dependency audit
274
+ uses: pnpm/action-setup@v4
275
+ with:
276
+ version: 10
277
+ - name: Run pnpm audit
278
+ run: |
279
+ cd web
280
+ pnpm install --frozen-lockfile
281
+ pnpm audit --prod || true
@@ -0,0 +1,34 @@
1
+ name: CodeQL
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+ schedule:
9
+ - cron: '0 6 * * 1'
10
+
11
+ jobs:
12
+ analyze:
13
+ name: Analyze
14
+ runs-on: ubuntu-latest
15
+ permissions:
16
+ security-events: write
17
+ actions: read
18
+ contents: read
19
+ strategy:
20
+ fail-fast: false
21
+ matrix:
22
+ language: [javascript-typescript, python]
23
+ steps:
24
+ - uses: actions/checkout@v6
25
+ - name: Initialize CodeQL
26
+ uses: github/codeql-action/init@v3
27
+ with:
28
+ languages: ${{ matrix.language }}
29
+ - name: Autobuild
30
+ uses: github/codeql-action/autobuild@v3
31
+ - name: Perform CodeQL Analysis
32
+ uses: github/codeql-action/analyze@v3
33
+ with:
34
+ category: "/language:${{ matrix.language }}"
@@ -0,0 +1,14 @@
1
+ name: DCO Check
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [main]
6
+
7
+ jobs:
8
+ dco:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - name: DCO Check
12
+ uses: christophebedard/dco-check@0.5.0
13
+ env:
14
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,44 @@
1
+ name: Deploy to EC2
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ workflow_dispatch:
7
+
8
+ concurrency:
9
+ group: deploy-ec2
10
+ cancel-in-progress: false
11
+
12
+ jobs:
13
+ deploy:
14
+ runs-on: ubuntu-latest
15
+ timeout-minutes: 15
16
+ steps:
17
+ - name: Deploy to EC2
18
+ uses: appleboy/ssh-action@v1
19
+ with:
20
+ host: ${{ secrets.EC2_HOST }}
21
+ username: ubuntu
22
+ key: ${{ secrets.EC2_SSH_KEY }}
23
+ script_stop: true
24
+ script: |
25
+ cd ~/Observal
26
+ git fetch origin main
27
+ git reset --hard origin/main
28
+
29
+ cd docker
30
+ docker compose up -d --build --remove-orphans
31
+
32
+ # Wait for API health check
33
+ for i in $(seq 1 30); do
34
+ if curl -sf http://localhost:8000/health > /dev/null 2>&1; then
35
+ echo "API is healthy"
36
+ exit 0
37
+ fi
38
+ echo "Waiting for API... ($i/30)"
39
+ sleep 5
40
+ done
41
+
42
+ echo "API failed health check"
43
+ docker compose logs observal-api --tail 30
44
+ exit 1
@@ -0,0 +1,48 @@
1
+ # ─────────────────────────────────────────────────────────────────────────────
2
+ # Publish observal CLI to PyPI on a v* tag.
3
+ #
4
+ # Uses PyPI Trusted Publishing (OIDC) — no PYPI_API_TOKEN secret required.
5
+ # Configure on PyPI: Project → Publishing → Add a trusted publisher with
6
+ # owner = BlazeUp-AI, repo = Observal, workflow = publish.yml,
7
+ # environment = pypi.
8
+ #
9
+ # Tag a release with `git tag -s vX.Y.Z && git push origin vX.Y.Z`.
10
+ # ─────────────────────────────────────────────────────────────────────────────
11
+
12
+ name: Publish
13
+
14
+ on:
15
+ push:
16
+ tags: ['v*']
17
+
18
+ jobs:
19
+ publish:
20
+ name: Build and publish to PyPI
21
+ runs-on: ubuntu-latest
22
+ environment: pypi
23
+ permissions:
24
+ id-token: write # required for PyPI Trusted Publishing
25
+ contents: read
26
+
27
+ steps:
28
+ - uses: actions/checkout@v4
29
+
30
+ - name: Install uv
31
+ uses: astral-sh/setup-uv@v3
32
+ with:
33
+ enable-cache: true
34
+
35
+ - name: Verify tag matches pyproject version
36
+ run: |
37
+ tag="${GITHUB_REF#refs/tags/v}"
38
+ pkg=$(uv run --with tomli python -c "import tomli, pathlib; print(tomli.loads(pathlib.Path('pyproject.toml').read_text())['project']['version'])")
39
+ if [ "$tag" != "$pkg" ]; then
40
+ echo "::error::Tag v$tag does not match pyproject version $pkg"
41
+ exit 1
42
+ fi
43
+
44
+ - name: Build sdist and wheel
45
+ run: uv build
46
+
47
+ - name: Publish to PyPI
48
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,41 @@
1
+ __pycache__/
2
+ *.pyc
3
+ *.pyo
4
+ .env
5
+ *.egg-info/
6
+ dist/
7
+ build/
8
+ .eggs/
9
+
10
+ # IDE
11
+ .vscode/
12
+ .idea/
13
+ *.swp
14
+ *.swo
15
+ *~
16
+
17
+ # OS
18
+ .DS_Store
19
+ Thumbs.db
20
+
21
+ # Python
22
+ .mypy_cache/
23
+ .ruff_cache/
24
+ .pytest_cache/
25
+ htmlcov/
26
+ .coverage
27
+ *.cover
28
+
29
+ # Node
30
+ observal-web/node_modules/
31
+ observal-web/dist/
32
+
33
+ # Docker
34
+ docker/data/
35
+
36
+ # Local config
37
+ .kiro/
38
+ .claude/
39
+ CLAUDE.md
40
+ graphify-out/
41
+ observal-web/tsconfig.tsbuildinfo