htmlgraph 0.9.3__py3-none-any.whl → 0.27.5__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 (331) hide show
  1. htmlgraph/.htmlgraph/.session-warning-state.json +6 -0
  2. htmlgraph/.htmlgraph/agents.json +72 -0
  3. htmlgraph/.htmlgraph/htmlgraph.db +0 -0
  4. htmlgraph/__init__.py +173 -17
  5. htmlgraph/__init__.pyi +123 -0
  6. htmlgraph/agent_detection.py +127 -0
  7. htmlgraph/agent_registry.py +45 -30
  8. htmlgraph/agents.py +160 -107
  9. htmlgraph/analytics/__init__.py +9 -2
  10. htmlgraph/analytics/cli.py +190 -51
  11. htmlgraph/analytics/cost_analyzer.py +391 -0
  12. htmlgraph/analytics/cost_monitor.py +664 -0
  13. htmlgraph/analytics/cost_reporter.py +675 -0
  14. htmlgraph/analytics/cross_session.py +617 -0
  15. htmlgraph/analytics/dependency.py +192 -100
  16. htmlgraph/analytics/pattern_learning.py +771 -0
  17. htmlgraph/analytics/session_graph.py +707 -0
  18. htmlgraph/analytics/strategic/__init__.py +80 -0
  19. htmlgraph/analytics/strategic/cost_optimizer.py +611 -0
  20. htmlgraph/analytics/strategic/pattern_detector.py +876 -0
  21. htmlgraph/analytics/strategic/preference_manager.py +709 -0
  22. htmlgraph/analytics/strategic/suggestion_engine.py +747 -0
  23. htmlgraph/analytics/work_type.py +190 -14
  24. htmlgraph/analytics_index.py +135 -51
  25. htmlgraph/api/__init__.py +3 -0
  26. htmlgraph/api/cost_alerts_websocket.py +416 -0
  27. htmlgraph/api/main.py +2498 -0
  28. htmlgraph/api/static/htmx.min.js +1 -0
  29. htmlgraph/api/static/style-redesign.css +1344 -0
  30. htmlgraph/api/static/style.css +1079 -0
  31. htmlgraph/api/templates/dashboard-redesign.html +1366 -0
  32. htmlgraph/api/templates/dashboard.html +794 -0
  33. htmlgraph/api/templates/partials/activity-feed-hierarchical.html +326 -0
  34. htmlgraph/api/templates/partials/activity-feed.html +1100 -0
  35. htmlgraph/api/templates/partials/agents-redesign.html +317 -0
  36. htmlgraph/api/templates/partials/agents.html +317 -0
  37. htmlgraph/api/templates/partials/event-traces.html +373 -0
  38. htmlgraph/api/templates/partials/features-kanban-redesign.html +509 -0
  39. htmlgraph/api/templates/partials/features.html +578 -0
  40. htmlgraph/api/templates/partials/metrics-redesign.html +346 -0
  41. htmlgraph/api/templates/partials/metrics.html +346 -0
  42. htmlgraph/api/templates/partials/orchestration-redesign.html +443 -0
  43. htmlgraph/api/templates/partials/orchestration.html +198 -0
  44. htmlgraph/api/templates/partials/spawners.html +375 -0
  45. htmlgraph/api/templates/partials/work-items.html +613 -0
  46. htmlgraph/api/websocket.py +538 -0
  47. htmlgraph/archive/__init__.py +24 -0
  48. htmlgraph/archive/bloom.py +234 -0
  49. htmlgraph/archive/fts.py +297 -0
  50. htmlgraph/archive/manager.py +583 -0
  51. htmlgraph/archive/search.py +244 -0
  52. htmlgraph/atomic_ops.py +560 -0
  53. htmlgraph/attribute_index.py +208 -0
  54. htmlgraph/bounded_paths.py +539 -0
  55. htmlgraph/builders/__init__.py +14 -0
  56. htmlgraph/builders/base.py +118 -29
  57. htmlgraph/builders/bug.py +150 -0
  58. htmlgraph/builders/chore.py +119 -0
  59. htmlgraph/builders/epic.py +150 -0
  60. htmlgraph/builders/feature.py +31 -6
  61. htmlgraph/builders/insight.py +195 -0
  62. htmlgraph/builders/metric.py +217 -0
  63. htmlgraph/builders/pattern.py +202 -0
  64. htmlgraph/builders/phase.py +162 -0
  65. htmlgraph/builders/spike.py +52 -19
  66. htmlgraph/builders/track.py +148 -72
  67. htmlgraph/cigs/__init__.py +81 -0
  68. htmlgraph/cigs/autonomy.py +385 -0
  69. htmlgraph/cigs/cost.py +475 -0
  70. htmlgraph/cigs/messages_basic.py +472 -0
  71. htmlgraph/cigs/messaging.py +365 -0
  72. htmlgraph/cigs/models.py +771 -0
  73. htmlgraph/cigs/pattern_storage.py +427 -0
  74. htmlgraph/cigs/patterns.py +503 -0
  75. htmlgraph/cigs/posttool_analyzer.py +234 -0
  76. htmlgraph/cigs/reporter.py +818 -0
  77. htmlgraph/cigs/tracker.py +317 -0
  78. htmlgraph/cli/.htmlgraph/.session-warning-state.json +6 -0
  79. htmlgraph/cli/.htmlgraph/agents.json +72 -0
  80. htmlgraph/cli/.htmlgraph/htmlgraph.db +0 -0
  81. htmlgraph/cli/__init__.py +42 -0
  82. htmlgraph/cli/__main__.py +6 -0
  83. htmlgraph/cli/analytics.py +1424 -0
  84. htmlgraph/cli/base.py +685 -0
  85. htmlgraph/cli/constants.py +206 -0
  86. htmlgraph/cli/core.py +954 -0
  87. htmlgraph/cli/main.py +147 -0
  88. htmlgraph/cli/models.py +475 -0
  89. htmlgraph/cli/templates/__init__.py +1 -0
  90. htmlgraph/cli/templates/cost_dashboard.py +399 -0
  91. htmlgraph/cli/work/__init__.py +239 -0
  92. htmlgraph/cli/work/browse.py +115 -0
  93. htmlgraph/cli/work/features.py +568 -0
  94. htmlgraph/cli/work/orchestration.py +676 -0
  95. htmlgraph/cli/work/report.py +728 -0
  96. htmlgraph/cli/work/sessions.py +466 -0
  97. htmlgraph/cli/work/snapshot.py +559 -0
  98. htmlgraph/cli/work/tracks.py +486 -0
  99. htmlgraph/cli_commands/__init__.py +1 -0
  100. htmlgraph/cli_commands/feature.py +195 -0
  101. htmlgraph/cli_framework.py +115 -0
  102. htmlgraph/collections/__init__.py +18 -0
  103. htmlgraph/collections/base.py +415 -98
  104. htmlgraph/collections/bug.py +53 -0
  105. htmlgraph/collections/chore.py +53 -0
  106. htmlgraph/collections/epic.py +53 -0
  107. htmlgraph/collections/feature.py +12 -26
  108. htmlgraph/collections/insight.py +100 -0
  109. htmlgraph/collections/metric.py +92 -0
  110. htmlgraph/collections/pattern.py +97 -0
  111. htmlgraph/collections/phase.py +53 -0
  112. htmlgraph/collections/session.py +194 -0
  113. htmlgraph/collections/spike.py +56 -16
  114. htmlgraph/collections/task_delegation.py +241 -0
  115. htmlgraph/collections/todo.py +511 -0
  116. htmlgraph/collections/traces.py +487 -0
  117. htmlgraph/config/cost_models.json +56 -0
  118. htmlgraph/config.py +190 -0
  119. htmlgraph/context_analytics.py +344 -0
  120. htmlgraph/converter.py +216 -28
  121. htmlgraph/cost_analysis/__init__.py +5 -0
  122. htmlgraph/cost_analysis/analyzer.py +438 -0
  123. htmlgraph/dashboard.html +2406 -307
  124. htmlgraph/dashboard.html.backup +6592 -0
  125. htmlgraph/dashboard.html.bak +7181 -0
  126. htmlgraph/dashboard.html.bak2 +7231 -0
  127. htmlgraph/dashboard.html.bak3 +7232 -0
  128. htmlgraph/db/__init__.py +38 -0
  129. htmlgraph/db/queries.py +790 -0
  130. htmlgraph/db/schema.py +1788 -0
  131. htmlgraph/decorators.py +317 -0
  132. htmlgraph/dependency_models.py +19 -2
  133. htmlgraph/deploy.py +142 -125
  134. htmlgraph/deployment_models.py +474 -0
  135. htmlgraph/docs/API_REFERENCE.md +841 -0
  136. htmlgraph/docs/HTTP_API.md +750 -0
  137. htmlgraph/docs/INTEGRATION_GUIDE.md +752 -0
  138. htmlgraph/docs/ORCHESTRATION_PATTERNS.md +717 -0
  139. htmlgraph/docs/README.md +532 -0
  140. htmlgraph/docs/__init__.py +77 -0
  141. htmlgraph/docs/docs_version.py +55 -0
  142. htmlgraph/docs/metadata.py +93 -0
  143. htmlgraph/docs/migrations.py +232 -0
  144. htmlgraph/docs/template_engine.py +143 -0
  145. htmlgraph/docs/templates/_sections/cli_reference.md.j2 +52 -0
  146. htmlgraph/docs/templates/_sections/core_concepts.md.j2 +29 -0
  147. htmlgraph/docs/templates/_sections/sdk_basics.md.j2 +69 -0
  148. htmlgraph/docs/templates/base_agents.md.j2 +78 -0
  149. htmlgraph/docs/templates/example_user_override.md.j2 +47 -0
  150. htmlgraph/docs/version_check.py +163 -0
  151. htmlgraph/edge_index.py +182 -27
  152. htmlgraph/error_handler.py +544 -0
  153. htmlgraph/event_log.py +100 -52
  154. htmlgraph/event_migration.py +13 -4
  155. htmlgraph/exceptions.py +49 -0
  156. htmlgraph/file_watcher.py +101 -28
  157. htmlgraph/find_api.py +75 -63
  158. htmlgraph/git_events.py +145 -63
  159. htmlgraph/graph.py +1122 -106
  160. htmlgraph/hooks/.htmlgraph/.session-warning-state.json +6 -0
  161. htmlgraph/hooks/.htmlgraph/agents.json +72 -0
  162. htmlgraph/hooks/.htmlgraph/index.sqlite +0 -0
  163. htmlgraph/hooks/__init__.py +45 -0
  164. htmlgraph/hooks/bootstrap.py +169 -0
  165. htmlgraph/hooks/cigs_pretool_enforcer.py +354 -0
  166. htmlgraph/hooks/concurrent_sessions.py +208 -0
  167. htmlgraph/hooks/context.py +350 -0
  168. htmlgraph/hooks/drift_handler.py +525 -0
  169. htmlgraph/hooks/event_tracker.py +1314 -0
  170. htmlgraph/hooks/git_commands.py +175 -0
  171. htmlgraph/hooks/hooks-config.example.json +12 -0
  172. htmlgraph/hooks/installer.py +343 -0
  173. htmlgraph/hooks/orchestrator.py +674 -0
  174. htmlgraph/hooks/orchestrator_reflector.py +223 -0
  175. htmlgraph/hooks/post-checkout.sh +28 -0
  176. htmlgraph/hooks/post-commit.sh +24 -0
  177. htmlgraph/hooks/post-merge.sh +26 -0
  178. htmlgraph/hooks/post_tool_use_failure.py +273 -0
  179. htmlgraph/hooks/post_tool_use_handler.py +257 -0
  180. htmlgraph/hooks/posttooluse.py +408 -0
  181. htmlgraph/hooks/pre-commit.sh +94 -0
  182. htmlgraph/hooks/pre-push.sh +28 -0
  183. htmlgraph/hooks/pretooluse.py +819 -0
  184. htmlgraph/hooks/prompt_analyzer.py +637 -0
  185. htmlgraph/hooks/session_handler.py +668 -0
  186. htmlgraph/hooks/session_summary.py +395 -0
  187. htmlgraph/hooks/state_manager.py +504 -0
  188. htmlgraph/hooks/subagent_detection.py +202 -0
  189. htmlgraph/hooks/subagent_stop.py +369 -0
  190. htmlgraph/hooks/task_enforcer.py +255 -0
  191. htmlgraph/hooks/task_validator.py +177 -0
  192. htmlgraph/hooks/validator.py +628 -0
  193. htmlgraph/ids.py +41 -27
  194. htmlgraph/index.d.ts +286 -0
  195. htmlgraph/learning.py +767 -0
  196. htmlgraph/mcp_server.py +69 -23
  197. htmlgraph/models.py +1586 -87
  198. htmlgraph/operations/README.md +62 -0
  199. htmlgraph/operations/__init__.py +79 -0
  200. htmlgraph/operations/analytics.py +339 -0
  201. htmlgraph/operations/bootstrap.py +289 -0
  202. htmlgraph/operations/events.py +244 -0
  203. htmlgraph/operations/fastapi_server.py +231 -0
  204. htmlgraph/operations/hooks.py +350 -0
  205. htmlgraph/operations/initialization.py +597 -0
  206. htmlgraph/operations/initialization.py.backup +228 -0
  207. htmlgraph/operations/server.py +303 -0
  208. htmlgraph/orchestration/__init__.py +58 -0
  209. htmlgraph/orchestration/claude_launcher.py +179 -0
  210. htmlgraph/orchestration/command_builder.py +72 -0
  211. htmlgraph/orchestration/headless_spawner.py +281 -0
  212. htmlgraph/orchestration/live_events.py +377 -0
  213. htmlgraph/orchestration/model_selection.py +327 -0
  214. htmlgraph/orchestration/plugin_manager.py +140 -0
  215. htmlgraph/orchestration/prompts.py +137 -0
  216. htmlgraph/orchestration/spawner_event_tracker.py +383 -0
  217. htmlgraph/orchestration/spawners/__init__.py +16 -0
  218. htmlgraph/orchestration/spawners/base.py +194 -0
  219. htmlgraph/orchestration/spawners/claude.py +173 -0
  220. htmlgraph/orchestration/spawners/codex.py +435 -0
  221. htmlgraph/orchestration/spawners/copilot.py +294 -0
  222. htmlgraph/orchestration/spawners/gemini.py +471 -0
  223. htmlgraph/orchestration/subprocess_runner.py +36 -0
  224. htmlgraph/orchestration/task_coordination.py +343 -0
  225. htmlgraph/orchestration.md +563 -0
  226. htmlgraph/orchestrator-system-prompt-optimized.txt +863 -0
  227. htmlgraph/orchestrator.py +669 -0
  228. htmlgraph/orchestrator_config.py +357 -0
  229. htmlgraph/orchestrator_mode.py +328 -0
  230. htmlgraph/orchestrator_validator.py +133 -0
  231. htmlgraph/parallel.py +646 -0
  232. htmlgraph/parser.py +160 -35
  233. htmlgraph/path_query.py +608 -0
  234. htmlgraph/pattern_matcher.py +636 -0
  235. htmlgraph/planning.py +147 -52
  236. htmlgraph/pydantic_models.py +476 -0
  237. htmlgraph/quality_gates.py +350 -0
  238. htmlgraph/query_builder.py +109 -72
  239. htmlgraph/query_composer.py +509 -0
  240. htmlgraph/reflection.py +443 -0
  241. htmlgraph/refs.py +344 -0
  242. htmlgraph/repo_hash.py +512 -0
  243. htmlgraph/repositories/__init__.py +292 -0
  244. htmlgraph/repositories/analytics_repository.py +455 -0
  245. htmlgraph/repositories/analytics_repository_standard.py +628 -0
  246. htmlgraph/repositories/feature_repository.py +581 -0
  247. htmlgraph/repositories/feature_repository_htmlfile.py +668 -0
  248. htmlgraph/repositories/feature_repository_memory.py +607 -0
  249. htmlgraph/repositories/feature_repository_sqlite.py +858 -0
  250. htmlgraph/repositories/filter_service.py +620 -0
  251. htmlgraph/repositories/filter_service_standard.py +445 -0
  252. htmlgraph/repositories/shared_cache.py +621 -0
  253. htmlgraph/repositories/shared_cache_memory.py +395 -0
  254. htmlgraph/repositories/track_repository.py +552 -0
  255. htmlgraph/repositories/track_repository_htmlfile.py +619 -0
  256. htmlgraph/repositories/track_repository_memory.py +508 -0
  257. htmlgraph/repositories/track_repository_sqlite.py +711 -0
  258. htmlgraph/routing.py +8 -19
  259. htmlgraph/scripts/deploy.py +1 -2
  260. htmlgraph/sdk/__init__.py +398 -0
  261. htmlgraph/sdk/__init__.pyi +14 -0
  262. htmlgraph/sdk/analytics/__init__.py +19 -0
  263. htmlgraph/sdk/analytics/engine.py +155 -0
  264. htmlgraph/sdk/analytics/helpers.py +178 -0
  265. htmlgraph/sdk/analytics/registry.py +109 -0
  266. htmlgraph/sdk/base.py +484 -0
  267. htmlgraph/sdk/constants.py +216 -0
  268. htmlgraph/sdk/core.pyi +308 -0
  269. htmlgraph/sdk/discovery.py +120 -0
  270. htmlgraph/sdk/help/__init__.py +12 -0
  271. htmlgraph/sdk/help/mixin.py +699 -0
  272. htmlgraph/sdk/mixins/__init__.py +15 -0
  273. htmlgraph/sdk/mixins/attribution.py +113 -0
  274. htmlgraph/sdk/mixins/mixin.py +410 -0
  275. htmlgraph/sdk/operations/__init__.py +12 -0
  276. htmlgraph/sdk/operations/mixin.py +427 -0
  277. htmlgraph/sdk/orchestration/__init__.py +17 -0
  278. htmlgraph/sdk/orchestration/coordinator.py +203 -0
  279. htmlgraph/sdk/orchestration/spawner.py +204 -0
  280. htmlgraph/sdk/planning/__init__.py +19 -0
  281. htmlgraph/sdk/planning/bottlenecks.py +93 -0
  282. htmlgraph/sdk/planning/mixin.py +211 -0
  283. htmlgraph/sdk/planning/parallel.py +186 -0
  284. htmlgraph/sdk/planning/queue.py +210 -0
  285. htmlgraph/sdk/planning/recommendations.py +87 -0
  286. htmlgraph/sdk/planning/smart_planning.py +319 -0
  287. htmlgraph/sdk/session/__init__.py +19 -0
  288. htmlgraph/sdk/session/continuity.py +57 -0
  289. htmlgraph/sdk/session/handoff.py +110 -0
  290. htmlgraph/sdk/session/info.py +309 -0
  291. htmlgraph/sdk/session/manager.py +103 -0
  292. htmlgraph/sdk/strategic/__init__.py +26 -0
  293. htmlgraph/sdk/strategic/mixin.py +563 -0
  294. htmlgraph/server.py +685 -180
  295. htmlgraph/services/__init__.py +10 -0
  296. htmlgraph/services/claiming.py +199 -0
  297. htmlgraph/session_hooks.py +300 -0
  298. htmlgraph/session_manager.py +1392 -175
  299. htmlgraph/session_registry.py +587 -0
  300. htmlgraph/session_state.py +436 -0
  301. htmlgraph/session_warning.py +201 -0
  302. htmlgraph/sessions/__init__.py +23 -0
  303. htmlgraph/sessions/handoff.py +756 -0
  304. htmlgraph/setup.py +34 -17
  305. htmlgraph/spike_index.py +143 -0
  306. htmlgraph/sync_docs.py +12 -15
  307. htmlgraph/system_prompts.py +450 -0
  308. htmlgraph/templates/AGENTS.md.template +366 -0
  309. htmlgraph/templates/CLAUDE.md.template +97 -0
  310. htmlgraph/templates/GEMINI.md.template +87 -0
  311. htmlgraph/templates/orchestration-view.html +350 -0
  312. htmlgraph/track_builder.py +146 -15
  313. htmlgraph/track_manager.py +69 -21
  314. htmlgraph/transcript.py +890 -0
  315. htmlgraph/transcript_analytics.py +699 -0
  316. htmlgraph/types.py +323 -0
  317. htmlgraph/validation.py +115 -0
  318. htmlgraph/watch.py +8 -5
  319. htmlgraph/work_type_utils.py +3 -2
  320. {htmlgraph-0.9.3.data → htmlgraph-0.27.5.data}/data/htmlgraph/dashboard.html +2406 -307
  321. htmlgraph-0.27.5.data/data/htmlgraph/templates/AGENTS.md.template +366 -0
  322. htmlgraph-0.27.5.data/data/htmlgraph/templates/CLAUDE.md.template +97 -0
  323. htmlgraph-0.27.5.data/data/htmlgraph/templates/GEMINI.md.template +87 -0
  324. {htmlgraph-0.9.3.dist-info → htmlgraph-0.27.5.dist-info}/METADATA +97 -64
  325. htmlgraph-0.27.5.dist-info/RECORD +337 -0
  326. {htmlgraph-0.9.3.dist-info → htmlgraph-0.27.5.dist-info}/entry_points.txt +1 -1
  327. htmlgraph/cli.py +0 -2688
  328. htmlgraph/sdk.py +0 -709
  329. htmlgraph-0.9.3.dist-info/RECORD +0 -61
  330. {htmlgraph-0.9.3.data → htmlgraph-0.27.5.data}/data/htmlgraph/styles.css +0 -0
  331. {htmlgraph-0.9.3.dist-info → htmlgraph-0.27.5.dist-info}/WHEEL +0 -0
@@ -0,0 +1,427 @@
1
+ """
2
+ Operations mixin for SDK - server, hooks, events, analytics operations.
3
+
4
+ Provides infrastructure operations for running HtmlGraph.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from typing import TYPE_CHECKING, Any
10
+
11
+ if TYPE_CHECKING:
12
+ from pathlib import Path
13
+
14
+
15
+ class OperationsMixin:
16
+ """
17
+ Mixin providing operations capabilities to SDK.
18
+
19
+ Adds methods for server, hooks, events, and analytics operations.
20
+ Requires SDK instance with _directory attribute.
21
+ """
22
+
23
+ _directory: Path
24
+
25
+ # =========================================================================
26
+ # Server Operations
27
+ # =========================================================================
28
+
29
+ def start_server(
30
+ self,
31
+ port: int = 8080,
32
+ host: str = "localhost",
33
+ watch: bool = True,
34
+ auto_port: bool = False,
35
+ ) -> Any:
36
+ """
37
+ Start HtmlGraph server for browsing graph via web UI.
38
+
39
+ Args:
40
+ port: Port to listen on (default: 8080)
41
+ host: Host to bind to (default: "localhost")
42
+ watch: Enable file watching for auto-reload (default: True)
43
+ auto_port: Automatically find available port if specified port is in use (default: False)
44
+
45
+ Returns:
46
+ ServerStartResult with handle, warnings, and config used
47
+
48
+ Raises:
49
+ PortInUseError: If port is in use and auto_port=False
50
+ ServerStartError: If server fails to start
51
+
52
+ Example:
53
+ >>> sdk = SDK(agent="claude")
54
+ >>> result = sdk.start_server(port=8080, watch=True)
55
+ >>> logger.info(f"Server running at {result.handle.url}")
56
+ >>> # Open browser to http://localhost:8080
57
+ >>>
58
+ >>> # Stop server when done
59
+ >>> sdk.stop_server(result.handle)
60
+
61
+ See also:
62
+ stop_server: Stop running server
63
+ get_server_status: Check if server is running
64
+ """
65
+ from htmlgraph.operations import server
66
+
67
+ return server.start_server(
68
+ port=port,
69
+ graph_dir=self._directory,
70
+ static_dir=self._directory.parent, # Project root for index.html
71
+ host=host,
72
+ watch=watch,
73
+ auto_port=auto_port,
74
+ )
75
+
76
+ def stop_server(self, handle: Any) -> None:
77
+ """
78
+ Stop a running HtmlGraph server.
79
+
80
+ Args:
81
+ handle: ServerHandle returned from start_server()
82
+
83
+ Raises:
84
+ ServerStartError: If shutdown fails
85
+
86
+ Example:
87
+ >>> sdk = SDK(agent="claude")
88
+ >>> result = sdk.start_server()
89
+ >>> # Work with server...
90
+ >>> sdk.stop_server(result.handle)
91
+ """
92
+ from htmlgraph.operations import server
93
+
94
+ server.stop_server(handle)
95
+
96
+ def get_server_status(self, handle: Any | None = None) -> Any:
97
+ """
98
+ Check server status.
99
+
100
+ Args:
101
+ handle: Optional ServerHandle to check
102
+
103
+ Returns:
104
+ ServerStatus indicating whether server is running
105
+
106
+ Example:
107
+ >>> sdk = SDK(agent="claude")
108
+ >>> result = sdk.start_server()
109
+ >>> status = sdk.get_server_status(result.handle)
110
+ >>> logger.info(f"Running: {status.running}")
111
+ """
112
+ from htmlgraph.operations import server
113
+
114
+ return server.get_server_status(handle)
115
+
116
+ # =========================================================================
117
+ # Hook Operations
118
+ # =========================================================================
119
+
120
+ def install_hooks(self, use_copy: bool = False) -> Any:
121
+ """
122
+ Install Git hooks for automatic tracking.
123
+
124
+ Installs hooks that automatically track sessions, activities, and features
125
+ as you work.
126
+
127
+ Args:
128
+ use_copy: Force copy instead of symlink (default: False)
129
+
130
+ Returns:
131
+ HookInstallResult with installation details
132
+
133
+ Raises:
134
+ HookInstallError: If installation fails
135
+ HookConfigError: If configuration is invalid
136
+
137
+ Example:
138
+ >>> sdk = SDK(agent="claude")
139
+ >>> result = sdk.install_hooks()
140
+ >>> logger.info(f"Installed: {result.installed}")
141
+ >>> logger.info(f"Skipped: {result.skipped}")
142
+ >>> if result.warnings:
143
+ ... logger.info(f"Warnings: {result.warnings}")
144
+
145
+ See also:
146
+ list_hooks: List installed hooks
147
+ validate_hook_config: Validate hook configuration
148
+ """
149
+ from htmlgraph.operations import hooks
150
+
151
+ return hooks.install_hooks(
152
+ project_dir=self._directory.parent,
153
+ use_copy=use_copy,
154
+ )
155
+
156
+ def list_hooks(self) -> Any:
157
+ """
158
+ List Git hooks status (enabled/disabled/missing).
159
+
160
+ Returns:
161
+ HookListResult with enabled, disabled, and missing hooks
162
+
163
+ Example:
164
+ >>> sdk = SDK(agent="claude")
165
+ >>> result = sdk.list_hooks()
166
+ >>> logger.info(f"Enabled: {result.enabled}")
167
+ >>> logger.info(f"Disabled: {result.disabled}")
168
+ >>> logger.info(f"Missing: {result.missing}")
169
+ """
170
+ from htmlgraph.operations import hooks
171
+
172
+ return hooks.list_hooks(project_dir=self._directory.parent)
173
+
174
+ def validate_hook_config(self) -> Any:
175
+ """
176
+ Validate hook configuration.
177
+
178
+ Returns:
179
+ HookValidationResult with validation status
180
+
181
+ Example:
182
+ >>> sdk = SDK(agent="claude")
183
+ >>> result = sdk.validate_hook_config()
184
+ >>> if not result.valid:
185
+ ... logger.info(f"Errors: {result.errors}")
186
+ >>> if result.warnings:
187
+ ... logger.info(f"Warnings: {result.warnings}")
188
+ """
189
+ from htmlgraph.operations import hooks
190
+
191
+ return hooks.validate_hook_config(project_dir=self._directory.parent)
192
+
193
+ # =========================================================================
194
+ # Event Operations
195
+ # =========================================================================
196
+
197
+ def export_sessions(self, overwrite: bool = False) -> Any:
198
+ """
199
+ Export legacy session HTML logs to JSONL events.
200
+
201
+ Converts HTML session files to JSONL format for efficient querying.
202
+
203
+ Args:
204
+ overwrite: Whether to overwrite existing JSONL files (default: False)
205
+
206
+ Returns:
207
+ EventExportResult with counts of written, skipped, failed files
208
+
209
+ Raises:
210
+ EventOperationError: If export fails
211
+
212
+ Example:
213
+ >>> sdk = SDK(agent="claude")
214
+ >>> result = sdk.export_sessions()
215
+ >>> logger.info(f"Exported {result.written} sessions")
216
+ >>> logger.info(f"Skipped {result.skipped} (already exist)")
217
+ >>> if result.failed > 0:
218
+ ... logger.info(f"Failed {result.failed} sessions")
219
+
220
+ See also:
221
+ rebuild_event_index: Rebuild SQLite index from JSONL
222
+ query_events: Query exported events
223
+ """
224
+ from htmlgraph.operations import events
225
+
226
+ return events.export_sessions(
227
+ graph_dir=self._directory,
228
+ overwrite=overwrite,
229
+ )
230
+
231
+ def rebuild_event_index(self) -> Any:
232
+ """
233
+ Rebuild SQLite analytics index from JSONL events.
234
+
235
+ Creates an optimized SQLite index for fast analytics queries.
236
+
237
+ Returns:
238
+ EventRebuildResult with db_path and counts of inserted/skipped events
239
+
240
+ Raises:
241
+ EventOperationError: If rebuild fails
242
+
243
+ Example:
244
+ >>> sdk = SDK(agent="claude")
245
+ >>> result = sdk.rebuild_event_index()
246
+ >>> logger.info(f"Rebuilt index: {result.db_path}")
247
+ >>> logger.info(f"Inserted {result.inserted} events")
248
+ >>> logger.info(f"Skipped {result.skipped} (duplicates)")
249
+
250
+ See also:
251
+ export_sessions: Export HTML sessions to JSONL first
252
+ """
253
+ from htmlgraph.operations import events
254
+
255
+ return events.rebuild_index(graph_dir=self._directory)
256
+
257
+ def query_events(
258
+ self,
259
+ session_id: str | None = None,
260
+ tool: str | None = None,
261
+ feature_id: str | None = None,
262
+ since: str | None = None,
263
+ limit: int | None = None,
264
+ ) -> Any:
265
+ """
266
+ Query events from JSONL logs with optional filters.
267
+
268
+ Args:
269
+ session_id: Filter by session ID (None = all sessions)
270
+ tool: Filter by tool name (e.g., 'Bash', 'Edit')
271
+ feature_id: Filter by attributed feature ID
272
+ since: Only events after this timestamp (ISO string)
273
+ limit: Maximum number of events to return
274
+
275
+ Returns:
276
+ EventQueryResult with matching events and total count
277
+
278
+ Raises:
279
+ EventOperationError: If query fails
280
+
281
+ Example:
282
+ >>> sdk = SDK(agent="claude")
283
+ >>> # Get all events for a session
284
+ >>> result = sdk.query_events(session_id="sess-123")
285
+ >>> logger.info(f"Found {result.total} events")
286
+ >>>
287
+ >>> # Get recent Bash events
288
+ >>> result = sdk.query_events(
289
+ ... tool="Bash",
290
+ ... since="2025-01-01T00:00:00Z",
291
+ ... limit=10
292
+ ... )
293
+ >>> for event in result.events:
294
+ ... logger.info(f"{event['timestamp']}: {event['summary']}")
295
+
296
+ See also:
297
+ export_sessions: Export sessions to JSONL first
298
+ get_event_stats: Get event statistics
299
+ """
300
+ from htmlgraph.operations import events
301
+
302
+ return events.query_events(
303
+ graph_dir=self._directory,
304
+ session_id=session_id,
305
+ tool=tool,
306
+ feature_id=feature_id,
307
+ since=since,
308
+ limit=limit,
309
+ )
310
+
311
+ def get_event_stats(self) -> Any:
312
+ """
313
+ Get statistics about events in the system.
314
+
315
+ Returns:
316
+ EventStats with counts of total events, sessions, and files
317
+
318
+ Example:
319
+ >>> sdk = SDK(agent="claude")
320
+ >>> stats = sdk.get_event_stats()
321
+ >>> logger.info(f"Total events: {stats.total_events}")
322
+ >>> logger.info(f"Sessions: {stats.session_count}")
323
+ >>> logger.info(f"JSONL files: {stats.file_count}")
324
+ """
325
+ from htmlgraph.operations import events
326
+
327
+ return events.get_event_stats(graph_dir=self._directory)
328
+
329
+ # =========================================================================
330
+ # Analytics Operations
331
+ # =========================================================================
332
+
333
+ def analyze_session(self, session_id: str) -> Any:
334
+ """
335
+ Compute detailed analytics for a single session.
336
+
337
+ Analyzes work distribution, spike-to-feature ratio, maintenance burden,
338
+ transition metrics, and more.
339
+
340
+ Args:
341
+ session_id: ID of the session to analyze
342
+
343
+ Returns:
344
+ AnalyticsSessionResult with session metrics and warnings
345
+
346
+ Raises:
347
+ AnalyticsOperationError: If session cannot be analyzed
348
+
349
+ Example:
350
+ >>> sdk = SDK(agent="claude")
351
+ >>> result = sdk.analyze_session("sess-123")
352
+ >>> logger.info(f"Primary work type: {result.metrics['primary_work_type']}")
353
+ >>> logger.info(f"Total events: {result.metrics['total_events']}")
354
+ >>> logger.info(f"Work distribution: {result.metrics['work_distribution']}")
355
+ >>> if result.warnings:
356
+ ... logger.info(f"Warnings: {result.warnings}")
357
+
358
+ See also:
359
+ analyze_project: Analyze entire project
360
+ """
361
+ from htmlgraph.operations import analytics
362
+
363
+ return analytics.analyze_session(
364
+ graph_dir=self._directory,
365
+ session_id=session_id,
366
+ )
367
+
368
+ def analyze_project(self) -> Any:
369
+ """
370
+ Compute project-wide analytics.
371
+
372
+ Analyzes all sessions, work distribution, spike-to-feature ratios,
373
+ maintenance burden, and session types across the entire project.
374
+
375
+ Returns:
376
+ AnalyticsProjectResult with project metrics and warnings
377
+
378
+ Raises:
379
+ AnalyticsOperationError: If project cannot be analyzed
380
+
381
+ Example:
382
+ >>> sdk = SDK(agent="claude")
383
+ >>> result = sdk.analyze_project()
384
+ >>> logger.info(f"Total sessions: {result.metrics['total_sessions']}")
385
+ >>> logger.info(f"Work distribution: {result.metrics['work_distribution']}")
386
+ >>> logger.info(f"Spike-to-feature ratio: {result.metrics['spike_to_feature_ratio']}")
387
+ >>> logger.info(f"Session types: {result.metrics['session_types']}")
388
+ >>> for session in result.metrics['recent_sessions']:
389
+ ... logger.info(f" {session['session_id']}: {session['primary_work_type']}")
390
+
391
+ See also:
392
+ analyze_session: Analyze a single session
393
+ get_work_recommendations: Get work recommendations
394
+ """
395
+ from htmlgraph.operations import analytics
396
+
397
+ return analytics.analyze_project(graph_dir=self._directory)
398
+
399
+ def get_work_recommendations(self) -> Any:
400
+ """
401
+ Get smart work recommendations based on project state.
402
+
403
+ Uses dependency analytics to recommend next tasks based on priority,
404
+ dependencies, and impact.
405
+
406
+ Returns:
407
+ RecommendationsResult with recommendations, reasoning, and warnings
408
+
409
+ Raises:
410
+ AnalyticsOperationError: If recommendations cannot be generated
411
+
412
+ Example:
413
+ >>> sdk = SDK(agent="claude")
414
+ >>> result = sdk.get_work_recommendations()
415
+ >>> for rec in result.recommendations:
416
+ ... logger.info(f"{rec['title']} (score: {rec['score']})")
417
+ ... logger.info(f" Reasons: {rec['reasons']}")
418
+ ... logger.info(f" Unlocks: {rec['unlocks']}")
419
+ >>> logger.info(f"Reasoning: {result.reasoning}")
420
+
421
+ See also:
422
+ recommend_next_work: Legacy method (backward compatibility)
423
+ get_work_queue: Get prioritized work queue
424
+ """
425
+ from htmlgraph.operations import analytics
426
+
427
+ return analytics.get_recommendations(graph_dir=self._directory)
@@ -0,0 +1,17 @@
1
+ """
2
+ Orchestration module for spawning and coordinating subagents.
3
+
4
+ Provides:
5
+ - OrchestrationMixin: Mixin for SDK with orchestration capabilities
6
+ - Spawner utilities for creating explorer/coder agents
7
+ - Coordinator for managing multi-agent workflows
8
+
9
+ Public API:
10
+ from htmlgraph.sdk.orchestration import OrchestrationMixin
11
+ """
12
+
13
+ from htmlgraph.sdk.orchestration.coordinator import OrchestrationMixin
14
+
15
+ __all__ = [
16
+ "OrchestrationMixin",
17
+ ]
@@ -0,0 +1,203 @@
1
+ """
2
+ Orchestration coordinator - manages subagent spawning and workflows.
3
+
4
+ Provides OrchestrationMixin with:
5
+ - orchestrator property (lazy-loaded SubagentOrchestrator)
6
+ - spawn_explorer() - Spawn explorer subagent for codebase discovery
7
+ - spawn_coder() - Spawn coder subagent for implementation
8
+ - orchestrate() - Full exploration + implementation workflow
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ from typing import TYPE_CHECKING, Any
14
+
15
+ if TYPE_CHECKING:
16
+ from htmlgraph.sdk import SDK as SDK_TYPE
17
+ else:
18
+ SDK_TYPE = "SDK" # type: ignore[misc,assignment]
19
+
20
+
21
+ class OrchestrationMixin:
22
+ """
23
+ Mixin providing orchestration capabilities to SDK.
24
+
25
+ Adds methods for spawning and coordinating subagents.
26
+ Requires SDK instance with _orchestrator attribute.
27
+ """
28
+
29
+ _orchestrator: Any
30
+ _directory: Any
31
+
32
+ def __init__(self) -> None:
33
+ """Initialize orchestration state."""
34
+ self._orchestrator = None
35
+
36
+ @property
37
+ def orchestrator(self) -> Any:
38
+ """
39
+ Get the subagent orchestrator for spawning explorer/coder agents.
40
+
41
+ Lazy-loaded on first access.
42
+
43
+ Returns:
44
+ SubagentOrchestrator instance
45
+
46
+ Example:
47
+ >>> sdk = SDK(agent="claude")
48
+ >>> explorer = sdk.orchestrator.spawn_explorer(
49
+ ... task="Find all API endpoints",
50
+ ... scope="src/"
51
+ ... )
52
+ """
53
+ if self._orchestrator is None:
54
+ from htmlgraph.orchestrator import SubagentOrchestrator
55
+
56
+ self._orchestrator = SubagentOrchestrator(self) # type: ignore[arg-type,assignment]
57
+ return self._orchestrator
58
+
59
+ def spawn_explorer(
60
+ self,
61
+ task: str,
62
+ scope: str | None = None,
63
+ patterns: list[str] | None = None,
64
+ questions: list[str] | None = None,
65
+ ) -> dict[str, Any]:
66
+ """
67
+ Spawn an explorer subagent for codebase discovery.
68
+
69
+ Explorer agents are optimized for finding files, searching patterns,
70
+ and mapping code without modifying anything.
71
+
72
+ Args:
73
+ task: What to explore/discover
74
+ scope: Directory scope (e.g., "src/")
75
+ patterns: Glob patterns to focus on
76
+ questions: Specific questions to answer
77
+
78
+ Returns:
79
+ Dict with prompt ready for Task tool
80
+
81
+ Note:
82
+ Returns dict with 'prompt', 'description', 'subagent_type' keys.
83
+ Returns empty dict if spawning fails.
84
+
85
+ Example:
86
+ >>> prompt = sdk.spawn_explorer(
87
+ ... task="Find all database models",
88
+ ... scope="src/models/",
89
+ ... questions=["What ORM is used?"]
90
+ ... )
91
+ >>> # Execute with Task tool
92
+ >>> Task(prompt=prompt["prompt"], description=prompt["description"])
93
+
94
+ See also:
95
+ spawn_coder: Spawn implementation agent with feature context
96
+ orchestrate: Full exploration + implementation workflow
97
+ """
98
+ subagent_prompt = self.orchestrator.spawn_explorer(
99
+ task=task,
100
+ scope=scope,
101
+ patterns=patterns,
102
+ questions=questions,
103
+ )
104
+ result: dict[str, Any] = subagent_prompt.to_task_kwargs()
105
+ return result
106
+
107
+ def spawn_coder(
108
+ self,
109
+ feature_id: str,
110
+ context: str | None = None,
111
+ files_to_modify: list[str] | None = None,
112
+ test_command: str | None = None,
113
+ ) -> dict[str, Any]:
114
+ """
115
+ Spawn a coder subagent for implementing changes.
116
+
117
+ Coder agents are optimized for reading, modifying, and testing code.
118
+
119
+ Args:
120
+ feature_id: Feature being implemented
121
+ context: Results from explorer (string summary)
122
+ files_to_modify: Specific files to change
123
+ test_command: Command to verify changes
124
+
125
+ Returns:
126
+ Dict with prompt ready for Task tool
127
+
128
+ Note:
129
+ Returns dict with 'prompt', 'description', 'subagent_type' keys.
130
+ Requires valid feature_id. Returns empty dict if feature not found.
131
+
132
+ Example:
133
+ >>> prompt = sdk.spawn_coder(
134
+ ... feature_id="feat-add-auth",
135
+ ... context=explorer_results,
136
+ ... test_command="uv run pytest tests/auth/"
137
+ ... )
138
+ >>> Task(prompt=prompt["prompt"], description=prompt["description"])
139
+
140
+ See also:
141
+ spawn_explorer: Explore codebase before implementation
142
+ orchestrate: Full exploration + implementation workflow
143
+ """
144
+ subagent_prompt = self.orchestrator.spawn_coder(
145
+ feature_id=feature_id,
146
+ context=context,
147
+ files_to_modify=files_to_modify,
148
+ test_command=test_command,
149
+ )
150
+ result: dict[str, Any] = subagent_prompt.to_task_kwargs()
151
+ return result
152
+
153
+ def orchestrate(
154
+ self,
155
+ feature_id: str,
156
+ exploration_scope: str | None = None,
157
+ test_command: str | None = None,
158
+ ) -> dict[str, Any]:
159
+ """
160
+ Orchestrate full feature implementation with explorer and coder.
161
+
162
+ Generates prompts for a two-phase workflow:
163
+ 1. Explorer discovers relevant code and patterns
164
+ 2. Coder implements the feature based on explorer findings
165
+
166
+ Args:
167
+ feature_id: Feature to implement
168
+ exploration_scope: Directory to explore
169
+ test_command: Test command for verification
170
+
171
+ Returns:
172
+ Dict with explorer and coder prompts
173
+
174
+ Example:
175
+ >>> prompts = sdk.orchestrate(
176
+ ... "feat-add-caching",
177
+ ... exploration_scope="src/cache/",
178
+ ... test_command="uv run pytest tests/cache/"
179
+ ... )
180
+ >>> # Phase 1: Run explorer
181
+ >>> Task(prompt=prompts["explorer"]["prompt"], ...)
182
+ >>> # Phase 2: Run coder with explorer results
183
+ >>> Task(prompt=prompts["coder"]["prompt"], ...)
184
+
185
+ See also:
186
+ spawn_explorer: Just the exploration phase
187
+ spawn_coder: Just the implementation phase
188
+ """
189
+ prompts = self.orchestrator.orchestrate_feature(
190
+ feature_id=feature_id,
191
+ exploration_scope=exploration_scope,
192
+ test_command=test_command,
193
+ )
194
+ return {
195
+ "explorer": prompts["explorer"].to_task_kwargs(),
196
+ "coder": prompts["coder"].to_task_kwargs(),
197
+ "workflow": [
198
+ "1. Execute explorer Task and collect results",
199
+ "2. Parse explorer results for files and patterns",
200
+ "3. Execute coder Task with explorer context",
201
+ "4. Verify coder results and update feature status",
202
+ ],
203
+ }