htmlgraph 0.20.1__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 (304) 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 +51 -1
  5. htmlgraph/__init__.pyi +123 -0
  6. htmlgraph/agent_detection.py +26 -10
  7. htmlgraph/agent_registry.py +2 -1
  8. htmlgraph/analytics/__init__.py +8 -1
  9. htmlgraph/analytics/cli.py +86 -20
  10. htmlgraph/analytics/cost_analyzer.py +391 -0
  11. htmlgraph/analytics/cost_monitor.py +664 -0
  12. htmlgraph/analytics/cost_reporter.py +675 -0
  13. htmlgraph/analytics/cross_session.py +617 -0
  14. htmlgraph/analytics/dependency.py +10 -6
  15. htmlgraph/analytics/pattern_learning.py +771 -0
  16. htmlgraph/analytics/session_graph.py +707 -0
  17. htmlgraph/analytics/strategic/__init__.py +80 -0
  18. htmlgraph/analytics/strategic/cost_optimizer.py +611 -0
  19. htmlgraph/analytics/strategic/pattern_detector.py +876 -0
  20. htmlgraph/analytics/strategic/preference_manager.py +709 -0
  21. htmlgraph/analytics/strategic/suggestion_engine.py +747 -0
  22. htmlgraph/analytics/work_type.py +67 -27
  23. htmlgraph/analytics_index.py +53 -20
  24. htmlgraph/api/__init__.py +3 -0
  25. htmlgraph/api/cost_alerts_websocket.py +416 -0
  26. htmlgraph/api/main.py +2498 -0
  27. htmlgraph/api/static/htmx.min.js +1 -0
  28. htmlgraph/api/static/style-redesign.css +1344 -0
  29. htmlgraph/api/static/style.css +1079 -0
  30. htmlgraph/api/templates/dashboard-redesign.html +1366 -0
  31. htmlgraph/api/templates/dashboard.html +794 -0
  32. htmlgraph/api/templates/partials/activity-feed-hierarchical.html +326 -0
  33. htmlgraph/api/templates/partials/activity-feed.html +1100 -0
  34. htmlgraph/api/templates/partials/agents-redesign.html +317 -0
  35. htmlgraph/api/templates/partials/agents.html +317 -0
  36. htmlgraph/api/templates/partials/event-traces.html +373 -0
  37. htmlgraph/api/templates/partials/features-kanban-redesign.html +509 -0
  38. htmlgraph/api/templates/partials/features.html +578 -0
  39. htmlgraph/api/templates/partials/metrics-redesign.html +346 -0
  40. htmlgraph/api/templates/partials/metrics.html +346 -0
  41. htmlgraph/api/templates/partials/orchestration-redesign.html +443 -0
  42. htmlgraph/api/templates/partials/orchestration.html +198 -0
  43. htmlgraph/api/templates/partials/spawners.html +375 -0
  44. htmlgraph/api/templates/partials/work-items.html +613 -0
  45. htmlgraph/api/websocket.py +538 -0
  46. htmlgraph/archive/__init__.py +24 -0
  47. htmlgraph/archive/bloom.py +234 -0
  48. htmlgraph/archive/fts.py +297 -0
  49. htmlgraph/archive/manager.py +583 -0
  50. htmlgraph/archive/search.py +244 -0
  51. htmlgraph/atomic_ops.py +560 -0
  52. htmlgraph/attribute_index.py +2 -1
  53. htmlgraph/bounded_paths.py +539 -0
  54. htmlgraph/builders/base.py +57 -2
  55. htmlgraph/builders/bug.py +19 -3
  56. htmlgraph/builders/chore.py +19 -3
  57. htmlgraph/builders/epic.py +19 -3
  58. htmlgraph/builders/feature.py +27 -3
  59. htmlgraph/builders/insight.py +2 -1
  60. htmlgraph/builders/metric.py +2 -1
  61. htmlgraph/builders/pattern.py +2 -1
  62. htmlgraph/builders/phase.py +19 -3
  63. htmlgraph/builders/spike.py +29 -3
  64. htmlgraph/builders/track.py +42 -1
  65. htmlgraph/cigs/__init__.py +81 -0
  66. htmlgraph/cigs/autonomy.py +385 -0
  67. htmlgraph/cigs/cost.py +475 -0
  68. htmlgraph/cigs/messages_basic.py +472 -0
  69. htmlgraph/cigs/messaging.py +365 -0
  70. htmlgraph/cigs/models.py +771 -0
  71. htmlgraph/cigs/pattern_storage.py +427 -0
  72. htmlgraph/cigs/patterns.py +503 -0
  73. htmlgraph/cigs/posttool_analyzer.py +234 -0
  74. htmlgraph/cigs/reporter.py +818 -0
  75. htmlgraph/cigs/tracker.py +317 -0
  76. htmlgraph/cli/.htmlgraph/.session-warning-state.json +6 -0
  77. htmlgraph/cli/.htmlgraph/agents.json +72 -0
  78. htmlgraph/cli/.htmlgraph/htmlgraph.db +0 -0
  79. htmlgraph/cli/__init__.py +42 -0
  80. htmlgraph/cli/__main__.py +6 -0
  81. htmlgraph/cli/analytics.py +1424 -0
  82. htmlgraph/cli/base.py +685 -0
  83. htmlgraph/cli/constants.py +206 -0
  84. htmlgraph/cli/core.py +954 -0
  85. htmlgraph/cli/main.py +147 -0
  86. htmlgraph/cli/models.py +475 -0
  87. htmlgraph/cli/templates/__init__.py +1 -0
  88. htmlgraph/cli/templates/cost_dashboard.py +399 -0
  89. htmlgraph/cli/work/__init__.py +239 -0
  90. htmlgraph/cli/work/browse.py +115 -0
  91. htmlgraph/cli/work/features.py +568 -0
  92. htmlgraph/cli/work/orchestration.py +676 -0
  93. htmlgraph/cli/work/report.py +728 -0
  94. htmlgraph/cli/work/sessions.py +466 -0
  95. htmlgraph/cli/work/snapshot.py +559 -0
  96. htmlgraph/cli/work/tracks.py +486 -0
  97. htmlgraph/cli_commands/__init__.py +1 -0
  98. htmlgraph/cli_commands/feature.py +195 -0
  99. htmlgraph/cli_framework.py +115 -0
  100. htmlgraph/collections/__init__.py +2 -0
  101. htmlgraph/collections/base.py +197 -14
  102. htmlgraph/collections/bug.py +2 -1
  103. htmlgraph/collections/chore.py +2 -1
  104. htmlgraph/collections/epic.py +2 -1
  105. htmlgraph/collections/feature.py +2 -1
  106. htmlgraph/collections/insight.py +2 -1
  107. htmlgraph/collections/metric.py +2 -1
  108. htmlgraph/collections/pattern.py +2 -1
  109. htmlgraph/collections/phase.py +2 -1
  110. htmlgraph/collections/session.py +194 -0
  111. htmlgraph/collections/spike.py +13 -2
  112. htmlgraph/collections/task_delegation.py +241 -0
  113. htmlgraph/collections/todo.py +14 -1
  114. htmlgraph/collections/traces.py +487 -0
  115. htmlgraph/config/cost_models.json +56 -0
  116. htmlgraph/config.py +190 -0
  117. htmlgraph/context_analytics.py +2 -1
  118. htmlgraph/converter.py +116 -7
  119. htmlgraph/cost_analysis/__init__.py +5 -0
  120. htmlgraph/cost_analysis/analyzer.py +438 -0
  121. htmlgraph/dashboard.html +2246 -248
  122. htmlgraph/dashboard.html.backup +6592 -0
  123. htmlgraph/dashboard.html.bak +7181 -0
  124. htmlgraph/dashboard.html.bak2 +7231 -0
  125. htmlgraph/dashboard.html.bak3 +7232 -0
  126. htmlgraph/db/__init__.py +38 -0
  127. htmlgraph/db/queries.py +790 -0
  128. htmlgraph/db/schema.py +1788 -0
  129. htmlgraph/decorators.py +317 -0
  130. htmlgraph/dependency_models.py +2 -1
  131. htmlgraph/deploy.py +26 -27
  132. htmlgraph/docs/API_REFERENCE.md +841 -0
  133. htmlgraph/docs/HTTP_API.md +750 -0
  134. htmlgraph/docs/INTEGRATION_GUIDE.md +752 -0
  135. htmlgraph/docs/ORCHESTRATION_PATTERNS.md +717 -0
  136. htmlgraph/docs/README.md +532 -0
  137. htmlgraph/docs/__init__.py +77 -0
  138. htmlgraph/docs/docs_version.py +55 -0
  139. htmlgraph/docs/metadata.py +93 -0
  140. htmlgraph/docs/migrations.py +232 -0
  141. htmlgraph/docs/template_engine.py +143 -0
  142. htmlgraph/docs/templates/_sections/cli_reference.md.j2 +52 -0
  143. htmlgraph/docs/templates/_sections/core_concepts.md.j2 +29 -0
  144. htmlgraph/docs/templates/_sections/sdk_basics.md.j2 +69 -0
  145. htmlgraph/docs/templates/base_agents.md.j2 +78 -0
  146. htmlgraph/docs/templates/example_user_override.md.j2 +47 -0
  147. htmlgraph/docs/version_check.py +163 -0
  148. htmlgraph/edge_index.py +2 -1
  149. htmlgraph/error_handler.py +544 -0
  150. htmlgraph/event_log.py +86 -37
  151. htmlgraph/event_migration.py +2 -1
  152. htmlgraph/file_watcher.py +12 -8
  153. htmlgraph/find_api.py +2 -1
  154. htmlgraph/git_events.py +67 -9
  155. htmlgraph/hooks/.htmlgraph/.session-warning-state.json +6 -0
  156. htmlgraph/hooks/.htmlgraph/agents.json +72 -0
  157. htmlgraph/hooks/.htmlgraph/index.sqlite +0 -0
  158. htmlgraph/hooks/__init__.py +8 -0
  159. htmlgraph/hooks/bootstrap.py +169 -0
  160. htmlgraph/hooks/cigs_pretool_enforcer.py +354 -0
  161. htmlgraph/hooks/concurrent_sessions.py +208 -0
  162. htmlgraph/hooks/context.py +350 -0
  163. htmlgraph/hooks/drift_handler.py +525 -0
  164. htmlgraph/hooks/event_tracker.py +790 -99
  165. htmlgraph/hooks/git_commands.py +175 -0
  166. htmlgraph/hooks/installer.py +5 -1
  167. htmlgraph/hooks/orchestrator.py +327 -76
  168. htmlgraph/hooks/orchestrator_reflector.py +31 -4
  169. htmlgraph/hooks/post_tool_use_failure.py +32 -7
  170. htmlgraph/hooks/post_tool_use_handler.py +257 -0
  171. htmlgraph/hooks/posttooluse.py +92 -19
  172. htmlgraph/hooks/pretooluse.py +527 -7
  173. htmlgraph/hooks/prompt_analyzer.py +637 -0
  174. htmlgraph/hooks/session_handler.py +668 -0
  175. htmlgraph/hooks/session_summary.py +395 -0
  176. htmlgraph/hooks/state_manager.py +504 -0
  177. htmlgraph/hooks/subagent_detection.py +202 -0
  178. htmlgraph/hooks/subagent_stop.py +369 -0
  179. htmlgraph/hooks/task_enforcer.py +99 -4
  180. htmlgraph/hooks/validator.py +212 -91
  181. htmlgraph/ids.py +2 -1
  182. htmlgraph/learning.py +125 -100
  183. htmlgraph/mcp_server.py +2 -1
  184. htmlgraph/models.py +217 -18
  185. htmlgraph/operations/README.md +62 -0
  186. htmlgraph/operations/__init__.py +79 -0
  187. htmlgraph/operations/analytics.py +339 -0
  188. htmlgraph/operations/bootstrap.py +289 -0
  189. htmlgraph/operations/events.py +244 -0
  190. htmlgraph/operations/fastapi_server.py +231 -0
  191. htmlgraph/operations/hooks.py +350 -0
  192. htmlgraph/operations/initialization.py +597 -0
  193. htmlgraph/operations/initialization.py.backup +228 -0
  194. htmlgraph/operations/server.py +303 -0
  195. htmlgraph/orchestration/__init__.py +58 -0
  196. htmlgraph/orchestration/claude_launcher.py +179 -0
  197. htmlgraph/orchestration/command_builder.py +72 -0
  198. htmlgraph/orchestration/headless_spawner.py +281 -0
  199. htmlgraph/orchestration/live_events.py +377 -0
  200. htmlgraph/orchestration/model_selection.py +327 -0
  201. htmlgraph/orchestration/plugin_manager.py +140 -0
  202. htmlgraph/orchestration/prompts.py +137 -0
  203. htmlgraph/orchestration/spawner_event_tracker.py +383 -0
  204. htmlgraph/orchestration/spawners/__init__.py +16 -0
  205. htmlgraph/orchestration/spawners/base.py +194 -0
  206. htmlgraph/orchestration/spawners/claude.py +173 -0
  207. htmlgraph/orchestration/spawners/codex.py +435 -0
  208. htmlgraph/orchestration/spawners/copilot.py +294 -0
  209. htmlgraph/orchestration/spawners/gemini.py +471 -0
  210. htmlgraph/orchestration/subprocess_runner.py +36 -0
  211. htmlgraph/{orchestration.py → orchestration/task_coordination.py} +16 -8
  212. htmlgraph/orchestration.md +563 -0
  213. htmlgraph/orchestrator-system-prompt-optimized.txt +863 -0
  214. htmlgraph/orchestrator.py +2 -1
  215. htmlgraph/orchestrator_config.py +357 -0
  216. htmlgraph/orchestrator_mode.py +115 -4
  217. htmlgraph/parallel.py +2 -1
  218. htmlgraph/parser.py +86 -6
  219. htmlgraph/path_query.py +608 -0
  220. htmlgraph/pattern_matcher.py +636 -0
  221. htmlgraph/pydantic_models.py +476 -0
  222. htmlgraph/quality_gates.py +350 -0
  223. htmlgraph/query_builder.py +2 -1
  224. htmlgraph/query_composer.py +509 -0
  225. htmlgraph/reflection.py +443 -0
  226. htmlgraph/refs.py +344 -0
  227. htmlgraph/repo_hash.py +512 -0
  228. htmlgraph/repositories/__init__.py +292 -0
  229. htmlgraph/repositories/analytics_repository.py +455 -0
  230. htmlgraph/repositories/analytics_repository_standard.py +628 -0
  231. htmlgraph/repositories/feature_repository.py +581 -0
  232. htmlgraph/repositories/feature_repository_htmlfile.py +668 -0
  233. htmlgraph/repositories/feature_repository_memory.py +607 -0
  234. htmlgraph/repositories/feature_repository_sqlite.py +858 -0
  235. htmlgraph/repositories/filter_service.py +620 -0
  236. htmlgraph/repositories/filter_service_standard.py +445 -0
  237. htmlgraph/repositories/shared_cache.py +621 -0
  238. htmlgraph/repositories/shared_cache_memory.py +395 -0
  239. htmlgraph/repositories/track_repository.py +552 -0
  240. htmlgraph/repositories/track_repository_htmlfile.py +619 -0
  241. htmlgraph/repositories/track_repository_memory.py +508 -0
  242. htmlgraph/repositories/track_repository_sqlite.py +711 -0
  243. htmlgraph/sdk/__init__.py +398 -0
  244. htmlgraph/sdk/__init__.pyi +14 -0
  245. htmlgraph/sdk/analytics/__init__.py +19 -0
  246. htmlgraph/sdk/analytics/engine.py +155 -0
  247. htmlgraph/sdk/analytics/helpers.py +178 -0
  248. htmlgraph/sdk/analytics/registry.py +109 -0
  249. htmlgraph/sdk/base.py +484 -0
  250. htmlgraph/sdk/constants.py +216 -0
  251. htmlgraph/sdk/core.pyi +308 -0
  252. htmlgraph/sdk/discovery.py +120 -0
  253. htmlgraph/sdk/help/__init__.py +12 -0
  254. htmlgraph/sdk/help/mixin.py +699 -0
  255. htmlgraph/sdk/mixins/__init__.py +15 -0
  256. htmlgraph/sdk/mixins/attribution.py +113 -0
  257. htmlgraph/sdk/mixins/mixin.py +410 -0
  258. htmlgraph/sdk/operations/__init__.py +12 -0
  259. htmlgraph/sdk/operations/mixin.py +427 -0
  260. htmlgraph/sdk/orchestration/__init__.py +17 -0
  261. htmlgraph/sdk/orchestration/coordinator.py +203 -0
  262. htmlgraph/sdk/orchestration/spawner.py +204 -0
  263. htmlgraph/sdk/planning/__init__.py +19 -0
  264. htmlgraph/sdk/planning/bottlenecks.py +93 -0
  265. htmlgraph/sdk/planning/mixin.py +211 -0
  266. htmlgraph/sdk/planning/parallel.py +186 -0
  267. htmlgraph/sdk/planning/queue.py +210 -0
  268. htmlgraph/sdk/planning/recommendations.py +87 -0
  269. htmlgraph/sdk/planning/smart_planning.py +319 -0
  270. htmlgraph/sdk/session/__init__.py +19 -0
  271. htmlgraph/sdk/session/continuity.py +57 -0
  272. htmlgraph/sdk/session/handoff.py +110 -0
  273. htmlgraph/sdk/session/info.py +309 -0
  274. htmlgraph/sdk/session/manager.py +103 -0
  275. htmlgraph/sdk/strategic/__init__.py +26 -0
  276. htmlgraph/sdk/strategic/mixin.py +563 -0
  277. htmlgraph/server.py +295 -107
  278. htmlgraph/session_hooks.py +300 -0
  279. htmlgraph/session_manager.py +285 -3
  280. htmlgraph/session_registry.py +587 -0
  281. htmlgraph/session_state.py +436 -0
  282. htmlgraph/session_warning.py +2 -1
  283. htmlgraph/sessions/__init__.py +23 -0
  284. htmlgraph/sessions/handoff.py +756 -0
  285. htmlgraph/system_prompts.py +450 -0
  286. htmlgraph/templates/orchestration-view.html +350 -0
  287. htmlgraph/track_builder.py +33 -1
  288. htmlgraph/track_manager.py +38 -0
  289. htmlgraph/transcript.py +18 -5
  290. htmlgraph/validation.py +115 -0
  291. htmlgraph/watch.py +2 -1
  292. htmlgraph/work_type_utils.py +2 -1
  293. {htmlgraph-0.20.1.data → htmlgraph-0.27.5.data}/data/htmlgraph/dashboard.html +2246 -248
  294. {htmlgraph-0.20.1.dist-info → htmlgraph-0.27.5.dist-info}/METADATA +95 -64
  295. htmlgraph-0.27.5.dist-info/RECORD +337 -0
  296. {htmlgraph-0.20.1.dist-info → htmlgraph-0.27.5.dist-info}/entry_points.txt +1 -1
  297. htmlgraph/cli.py +0 -4839
  298. htmlgraph/sdk.py +0 -2359
  299. htmlgraph-0.20.1.dist-info/RECORD +0 -118
  300. {htmlgraph-0.20.1.data → htmlgraph-0.27.5.data}/data/htmlgraph/styles.css +0 -0
  301. {htmlgraph-0.20.1.data → htmlgraph-0.27.5.data}/data/htmlgraph/templates/AGENTS.md.template +0 -0
  302. {htmlgraph-0.20.1.data → htmlgraph-0.27.5.data}/data/htmlgraph/templates/CLAUDE.md.template +0 -0
  303. {htmlgraph-0.20.1.data → htmlgraph-0.27.5.data}/data/htmlgraph/templates/GEMINI.md.template +0 -0
  304. {htmlgraph-0.20.1.dist-info → htmlgraph-0.27.5.dist-info}/WHEEL +0 -0
@@ -0,0 +1,6 @@
1
+ {
2
+ "dismissed_at": null,
3
+ "dismissed_by": null,
4
+ "session_id": null,
5
+ "show_count": 59
6
+ }
@@ -0,0 +1,72 @@
1
+ {
2
+ "version": "1.0",
3
+ "updated": "2026-01-11T04:13:54.354401",
4
+ "agents": {
5
+ "claude": {
6
+ "id": "claude",
7
+ "name": "Claude",
8
+ "capabilities": [
9
+ "python",
10
+ "javascript",
11
+ "typescript",
12
+ "html",
13
+ "css",
14
+ "code-review",
15
+ "testing",
16
+ "documentation",
17
+ "debugging",
18
+ "refactoring",
19
+ "architecture",
20
+ "api-design"
21
+ ],
22
+ "max_parallel_tasks": 3,
23
+ "preferred_complexity": [
24
+ "low",
25
+ "medium",
26
+ "high",
27
+ "very-high"
28
+ ],
29
+ "active": true,
30
+ "metadata": {}
31
+ },
32
+ "gemini": {
33
+ "id": "gemini",
34
+ "name": "Gemini",
35
+ "capabilities": [
36
+ "python",
37
+ "data-analysis",
38
+ "documentation",
39
+ "testing",
40
+ "code-review",
41
+ "javascript"
42
+ ],
43
+ "max_parallel_tasks": 2,
44
+ "preferred_complexity": [
45
+ "low",
46
+ "medium",
47
+ "high"
48
+ ],
49
+ "active": true,
50
+ "metadata": {}
51
+ },
52
+ "codex": {
53
+ "id": "codex",
54
+ "name": "Codex",
55
+ "capabilities": [
56
+ "python",
57
+ "javascript",
58
+ "debugging",
59
+ "testing",
60
+ "code-generation",
61
+ "documentation"
62
+ ],
63
+ "max_parallel_tasks": 2,
64
+ "preferred_complexity": [
65
+ "low",
66
+ "medium"
67
+ ],
68
+ "active": true,
69
+ "metadata": {}
70
+ }
71
+ }
72
+ }
Binary file
htmlgraph/__init__.py CHANGED
@@ -5,12 +5,43 @@ A lightweight graph database framework using HTML files as nodes,
5
5
  hyperlinks as edges, and CSS selectors as the query language.
6
6
  """
7
7
 
8
+ import logging
9
+
10
+ from rich.console import Console
11
+ from rich.logging import RichHandler
12
+
13
+ # Configure Rich logging for entire SDK
14
+ # CRITICAL: Use stderr=True to prevent pollution of stdout (hooks output JSON to stdout)
15
+ logging.basicConfig(
16
+ handlers=[
17
+ RichHandler(
18
+ console=Console(stderr=True),
19
+ show_time=True,
20
+ show_level=True,
21
+ rich_tracebacks=True,
22
+ )
23
+ ],
24
+ level=logging.INFO,
25
+ format="%(message)s",
26
+ datefmt="[%X]",
27
+ )
28
+
29
+ # SDK now lives in sdk/core.py - clean import from sdk package
8
30
  from htmlgraph.agent_detection import detect_agent_name, get_agent_display_name
9
31
  from htmlgraph.agents import AgentInterface
10
32
  from htmlgraph.analytics import Analytics, DependencyAnalytics
33
+ from htmlgraph.atomic_ops import (
34
+ AtomicFileWriter,
35
+ DirectoryLocker,
36
+ atomic_rename,
37
+ cleanup_orphaned_temp_files,
38
+ safe_temp_file,
39
+ validate_atomic_write,
40
+ )
11
41
  from htmlgraph.builders import BaseBuilder, FeatureBuilder, SpikeBuilder
12
42
  from htmlgraph.collections import BaseCollection, FeatureCollection, SpikeCollection
13
43
  from htmlgraph.context_analytics import ContextAnalytics, ContextUsage
44
+ from htmlgraph.decorators import RetryError, retry, retry_async
14
45
  from htmlgraph.edge_index import EdgeIndex, EdgeRef
15
46
  from htmlgraph.exceptions import (
16
47
  ClaimConflictError,
@@ -55,9 +86,12 @@ from htmlgraph.orchestration import (
55
86
  from htmlgraph.orchestrator_mode import OrchestratorMode, OrchestratorModeManager
56
87
  from htmlgraph.parallel import AggregateResult, ParallelAnalysis, ParallelWorkflow
57
88
  from htmlgraph.query_builder import Condition, Operator, QueryBuilder
89
+ from htmlgraph.reflection import ComputationalReflection, get_reflection_context
90
+ from htmlgraph.repo_hash import RepoHash
58
91
  from htmlgraph.sdk import SDK
59
92
  from htmlgraph.server import serve
60
93
  from htmlgraph.session_manager import SessionManager
94
+ from htmlgraph.session_registry import SessionRegistry
61
95
  from htmlgraph.types import (
62
96
  ActiveWorkItem,
63
97
  AggregateResultsDict,
@@ -84,7 +118,7 @@ from htmlgraph.types import (
84
118
  )
85
119
  from htmlgraph.work_type_utils import infer_work_type, infer_work_type_from_id
86
120
 
87
- __version__ = "0.20.1"
121
+ __version__ = "0.27.5"
88
122
  __all__ = [
89
123
  # Exceptions
90
124
  "HtmlGraphError",
@@ -92,6 +126,10 @@ __all__ = [
92
126
  "SessionNotFoundError",
93
127
  "ClaimConflictError",
94
128
  "ValidationError",
129
+ "RetryError",
130
+ # Decorators
131
+ "retry",
132
+ "retry_async",
95
133
  # Core models
96
134
  "Node",
97
135
  "Edge",
@@ -122,6 +160,8 @@ __all__ = [
122
160
  "find_all",
123
161
  "AgentInterface",
124
162
  "SessionManager",
163
+ "SessionRegistry",
164
+ "RepoHash",
125
165
  "SDK",
126
166
  "Analytics", # Phase 2: Work Type Analytics
127
167
  "DependencyAnalytics", # Advanced dependency-aware analytics
@@ -178,6 +218,9 @@ __all__ = [
178
218
  # Active Learning Persistence
179
219
  "LearningPersistence",
180
220
  "auto_persist_on_session_end",
221
+ # Computational Reflection (pre-computed context injection)
222
+ "ComputationalReflection",
223
+ "get_reflection_context",
181
224
  # Orchestrator Mode Management
182
225
  "OrchestratorMode",
183
226
  "OrchestratorModeManager",
@@ -186,4 +229,11 @@ __all__ = [
186
229
  "get_results_by_task_id",
187
230
  "parallel_delegate",
188
231
  "generate_task_id",
232
+ # Atomic file operations (Phase 1.3: Session File Tracking)
233
+ "AtomicFileWriter",
234
+ "DirectoryLocker",
235
+ "atomic_rename",
236
+ "cleanup_orphaned_temp_files",
237
+ "safe_temp_file",
238
+ "validate_atomic_write",
189
239
  ]
htmlgraph/__init__.pyi ADDED
@@ -0,0 +1,123 @@
1
+ """
2
+ Type stub for htmlgraph package.
3
+
4
+ This stub provides type information for mypy when the SDK class
5
+ is loaded dynamically via importlib at runtime.
6
+ """
7
+
8
+ from htmlgraph.agent_detection import detect_agent_name as detect_agent_name
9
+ from htmlgraph.agent_detection import get_agent_display_name as get_agent_display_name
10
+ from htmlgraph.agents import AgentInterface as AgentInterface
11
+ from htmlgraph.analytics import Analytics as Analytics
12
+
13
+ # Analytics
14
+ from htmlgraph.analytics import DependencyAnalytics as DependencyAnalytics
15
+ from htmlgraph.atomic_ops import AtomicFileWriter as AtomicFileWriter
16
+ from htmlgraph.atomic_ops import DirectoryLocker as DirectoryLocker
17
+ from htmlgraph.atomic_ops import atomic_rename as atomic_rename
18
+ from htmlgraph.atomic_ops import (
19
+ cleanup_orphaned_temp_files as cleanup_orphaned_temp_files,
20
+ )
21
+ from htmlgraph.atomic_ops import safe_temp_file as safe_temp_file
22
+ from htmlgraph.atomic_ops import validate_atomic_write as validate_atomic_write
23
+ from htmlgraph.builders import BaseBuilder as BaseBuilder
24
+ from htmlgraph.builders import FeatureBuilder as FeatureBuilder
25
+ from htmlgraph.builders import SpikeBuilder as SpikeBuilder
26
+ from htmlgraph.collections import BaseCollection as BaseCollection
27
+
28
+ # Collections
29
+ from htmlgraph.collections import FeatureCollection as FeatureCollection
30
+ from htmlgraph.collections import SpikeCollection as SpikeCollection
31
+ from htmlgraph.context_analytics import ContextAnalytics as ContextAnalytics
32
+ from htmlgraph.context_analytics import ContextUsage as ContextUsage
33
+ from htmlgraph.decorators import RetryError as RetryError
34
+ from htmlgraph.decorators import retry as retry
35
+ from htmlgraph.decorators import retry_async as retry_async
36
+ from htmlgraph.edge_index import EdgeIndex as EdgeIndex
37
+ from htmlgraph.edge_index import EdgeRef as EdgeRef
38
+ from htmlgraph.exceptions import ClaimConflictError as ClaimConflictError
39
+ from htmlgraph.exceptions import HtmlGraphError as HtmlGraphError
40
+ from htmlgraph.exceptions import NodeNotFoundError as NodeNotFoundError
41
+ from htmlgraph.exceptions import SessionNotFoundError as SessionNotFoundError
42
+ from htmlgraph.exceptions import ValidationError as ValidationError
43
+ from htmlgraph.find_api import FindAPI as FindAPI
44
+ from htmlgraph.find_api import find as find
45
+ from htmlgraph.find_api import find_all as find_all
46
+ from htmlgraph.graph import CompiledQuery as CompiledQuery
47
+ from htmlgraph.graph import HtmlGraph as HtmlGraph
48
+ from htmlgraph.ids import generate_hierarchical_id as generate_hierarchical_id
49
+ from htmlgraph.ids import generate_id as generate_id
50
+ from htmlgraph.ids import is_legacy_id as is_legacy_id
51
+ from htmlgraph.ids import is_valid_id as is_valid_id
52
+ from htmlgraph.ids import parse_id as parse_id
53
+ from htmlgraph.learning import LearningPersistence as LearningPersistence
54
+ from htmlgraph.learning import (
55
+ auto_persist_on_session_end as auto_persist_on_session_end,
56
+ )
57
+ from htmlgraph.models import ActivityEntry as ActivityEntry
58
+ from htmlgraph.models import AggregatedMetric as AggregatedMetric
59
+ from htmlgraph.models import Chore as Chore
60
+ from htmlgraph.models import ContextSnapshot as ContextSnapshot
61
+ from htmlgraph.models import Edge as Edge
62
+ from htmlgraph.models import Graph as Graph
63
+ from htmlgraph.models import MaintenanceType as MaintenanceType
64
+ from htmlgraph.models import Node as Node
65
+ from htmlgraph.models import Pattern as Pattern
66
+ from htmlgraph.models import Session as Session
67
+ from htmlgraph.models import SessionInsight as SessionInsight
68
+ from htmlgraph.models import Spike as Spike
69
+ from htmlgraph.models import SpikeType as SpikeType
70
+ from htmlgraph.models import Step as Step
71
+ from htmlgraph.models import WorkType as WorkType
72
+ from htmlgraph.orchestration import delegate_with_id as delegate_with_id
73
+ from htmlgraph.orchestration import generate_task_id as generate_task_id
74
+ from htmlgraph.orchestration import get_results_by_task_id as get_results_by_task_id
75
+ from htmlgraph.orchestration import parallel_delegate as parallel_delegate
76
+ from htmlgraph.orchestrator_mode import OrchestratorMode as OrchestratorMode
77
+ from htmlgraph.orchestrator_mode import (
78
+ OrchestratorModeManager as OrchestratorModeManager,
79
+ )
80
+ from htmlgraph.parallel import AggregateResult as AggregateResult
81
+ from htmlgraph.parallel import ParallelAnalysis as ParallelAnalysis
82
+ from htmlgraph.parallel import ParallelWorkflow as ParallelWorkflow
83
+ from htmlgraph.query_builder import Condition as Condition
84
+ from htmlgraph.query_builder import Operator as Operator
85
+ from htmlgraph.query_builder import QueryBuilder as QueryBuilder
86
+ from htmlgraph.reflection import ComputationalReflection as ComputationalReflection
87
+ from htmlgraph.reflection import get_reflection_context as get_reflection_context
88
+ from htmlgraph.repo_hash import RepoHash as RepoHash
89
+ from htmlgraph.sdk.core import SDK as SDK
90
+ from htmlgraph.server import serve as serve
91
+ from htmlgraph.session_manager import SessionManager as SessionManager
92
+ from htmlgraph.session_registry import SessionRegistry as SessionRegistry
93
+ from htmlgraph.types import ActiveWorkItem as ActiveWorkItem
94
+ from htmlgraph.types import AggregateResultsDict as AggregateResultsDict
95
+ from htmlgraph.types import BottleneckDict as BottleneckDict
96
+ from htmlgraph.types import FeatureSummary as FeatureSummary
97
+ from htmlgraph.types import HighRiskTask as HighRiskTask
98
+ from htmlgraph.types import ImpactAnalysisDict as ImpactAnalysisDict
99
+ from htmlgraph.types import OrchestrationResult as OrchestrationResult
100
+ from htmlgraph.types import ParallelGuidelines as ParallelGuidelines
101
+ from htmlgraph.types import ParallelPlanResult as ParallelPlanResult
102
+ from htmlgraph.types import ParallelWorkInfo as ParallelWorkInfo
103
+ from htmlgraph.types import PlanningContext as PlanningContext
104
+ from htmlgraph.types import ProjectStatus as ProjectStatus
105
+ from htmlgraph.types import RiskAssessmentDict as RiskAssessmentDict
106
+ from htmlgraph.types import SessionAnalytics as SessionAnalytics
107
+ from htmlgraph.types import SessionStartInfo as SessionStartInfo
108
+ from htmlgraph.types import SessionSummary as SessionSummary
109
+ from htmlgraph.types import SmartPlanResult as SmartPlanResult
110
+ from htmlgraph.types import SubagentPrompt as SubagentPrompt
111
+ from htmlgraph.types import TaskPrompt as TaskPrompt
112
+ from htmlgraph.types import TrackCreationResult as TrackCreationResult
113
+ from htmlgraph.types import WorkQueueItem as WorkQueueItem
114
+ from htmlgraph.types import WorkRecommendation as WorkRecommendation
115
+ from htmlgraph.work_type_utils import infer_work_type as infer_work_type
116
+ from htmlgraph.work_type_utils import infer_work_type_from_id as infer_work_type_from_id
117
+
118
+ __version__: str
119
+
120
+ # SDK is imported from htmlgraph.sdk.core (see import above)
121
+ # Re-exported here for backward compatibility
122
+
123
+ __all__: list[str]
@@ -14,34 +14,48 @@ def detect_agent_name() -> str:
14
14
  Detect the current agent/interface name based on environment.
15
15
 
16
16
  Returns:
17
- Agent name (e.g., "claude", "gemini", "cli")
17
+ Agent name (e.g., "claude-code", "gemini", "cli")
18
18
 
19
19
  Detection order:
20
20
  1. HTMLGRAPH_AGENT environment variable (explicit override)
21
- 2. Claude Code detection (CLAUDE_CODE_VERSION, parent process)
22
- 3. Gemini detection (GEMINI environment markers)
23
- 4. Fall back to "cli"
21
+ 2. HTMLGRAPH_PARENT_AGENT (set by hooks for session context)
22
+ 3. Gemini detection (GEMINI environment markers) - checked before Claude to allow override
23
+ 4. Claude Code detection (CLAUDECODE env var, parent process)
24
+ 5. Fall back to "cli" only if no AI agent detected
24
25
  """
25
26
  # 1. Explicit override
26
27
  explicit = os.environ.get("HTMLGRAPH_AGENT")
27
28
  if explicit:
28
29
  return explicit.strip()
29
30
 
30
- # 2. Claude Code detection
31
- if _is_claude_code():
32
- return "claude"
31
+ # 2. Parent agent context (set by HtmlGraph hooks)
32
+ parent_agent = os.environ.get("HTMLGRAPH_PARENT_AGENT")
33
+ if parent_agent:
34
+ return parent_agent.strip()
33
35
 
34
- # 3. Gemini detection
36
+ # 3. Gemini detection (checked before Claude to allow explicit override)
35
37
  if _is_gemini():
36
38
  return "gemini"
37
39
 
38
- # 4. Default to CLI
40
+ # 4. Claude Code detection
41
+ if _is_claude_code():
42
+ return "claude-code"
43
+
44
+ # 5. Default to CLI only if no AI agent detected
39
45
  return "cli"
40
46
 
41
47
 
42
48
  def _is_claude_code() -> bool:
43
49
  """Check if running in Claude Code environment."""
44
50
  # Check for Claude Code environment variables
51
+ # CLAUDECODE=1 is set by Claude Code CLI
52
+ if os.environ.get("CLAUDECODE"):
53
+ return True
54
+
55
+ # CLAUDE_CODE_ENTRYPOINT indicates the entry point (cli, api, etc.)
56
+ if os.environ.get("CLAUDE_CODE_ENTRYPOINT"):
57
+ return True
58
+
45
59
  if os.environ.get("CLAUDE_CODE_VERSION"):
46
60
  return True
47
61
 
@@ -100,12 +114,14 @@ def get_agent_display_name(agent: str) -> str:
100
114
  """
101
115
  display_names = {
102
116
  "claude": "Claude",
103
- "claude-code": "Claude",
117
+ "claude-code": "Claude Code",
104
118
  "gemini": "Gemini",
105
119
  "cli": "CLI",
106
120
  "haiku": "Haiku",
107
121
  "opus": "Opus",
108
122
  "sonnet": "Sonnet",
123
+ "claude-opus-4-5-20251101": "Claude Opus 4.5",
124
+ "claude-sonnet-4-20250514": "Claude Sonnet 4",
109
125
  }
110
126
 
111
127
  return display_names.get(agent.lower(), agent.title())
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+
1
3
  """
2
4
  Agent Registry - Manages agent capabilities and routing.
3
5
 
@@ -7,7 +9,6 @@ Provides:
7
9
  - Capability matching for task routing
8
10
  """
9
11
 
10
- from __future__ import annotations
11
12
 
12
13
  import json
13
14
  from dataclasses import dataclass, field
@@ -1,13 +1,20 @@
1
1
  """
2
2
  Analytics modules for HtmlGraph.
3
3
 
4
- Provides work type analysis, dependency analytics, and CLI analytics.
4
+ Provides work type analysis, dependency analytics, cross-session analytics, CLI analytics,
5
+ and cost attribution analysis for OTEL ROI.
5
6
  """
6
7
 
8
+ from htmlgraph.analytics.cost_analyzer import CostAnalyzer
9
+ from htmlgraph.analytics.cost_reporter import CostReporter
10
+ from htmlgraph.analytics.cross_session import CrossSessionAnalytics
7
11
  from htmlgraph.analytics.dependency import DependencyAnalytics
8
12
  from htmlgraph.analytics.work_type import Analytics
9
13
 
10
14
  __all__ = [
11
15
  "Analytics",
12
16
  "DependencyAnalytics",
17
+ "CrossSessionAnalytics",
18
+ "CostAnalyzer",
19
+ "CostReporter",
13
20
  ]
@@ -5,6 +5,8 @@ This module provides the `htmlgraph analytics` command for analyzing work patter
5
5
  """
6
6
 
7
7
  import argparse
8
+ from collections.abc import Iterator
9
+ from contextlib import AbstractContextManager, nullcontext
8
10
  from pathlib import Path
9
11
 
10
12
  from rich import box
@@ -19,6 +21,7 @@ from htmlgraph.converter import html_to_session
19
21
  def cmd_analytics(args: argparse.Namespace) -> int:
20
22
  """Display work type analytics with beautiful rich formatting."""
21
23
  console = Console()
24
+ quiet = getattr(args, "quiet", False)
22
25
 
23
26
  try:
24
27
  sdk = SDK(agent=args.agent or "cli")
@@ -46,21 +49,67 @@ def cmd_analytics(args: argparse.Namespace) -> int:
46
49
  # Determine scope
47
50
  if args.session_id:
48
51
  # Single session analysis
49
- _display_session_analytics(console, sdk, args.session_id, args.graph_dir)
52
+ _display_session_analytics(
53
+ console, sdk, args.session_id, args.graph_dir, quiet=quiet
54
+ )
50
55
  elif args.recent:
51
56
  # Recent sessions
52
57
  _display_recent_sessions(
53
- console, sdk, session_files[: args.recent], args.graph_dir
58
+ console, sdk, session_files[: args.recent], args.graph_dir, quiet=quiet
54
59
  )
55
60
  else:
56
61
  # Project-wide overview
57
- _display_project_analytics(console, sdk, session_files, args.graph_dir)
62
+ _display_project_analytics(
63
+ console, sdk, session_files, args.graph_dir, quiet=quiet
64
+ )
58
65
 
59
66
  return 0
60
67
 
61
68
 
69
+ def _status_context(
70
+ console: Console, quiet: bool, message: str
71
+ ) -> AbstractContextManager[object]:
72
+ if quiet:
73
+ return nullcontext()
74
+ return console.status(message)
75
+
76
+
77
+ def _iter_with_progress(
78
+ console: Console, quiet: bool, items: list[Path], description: str
79
+ ) -> Iterator[Path]:
80
+ if quiet:
81
+ for item in items:
82
+ yield item
83
+ return
84
+ try:
85
+ from rich.progress import (
86
+ BarColumn,
87
+ Progress,
88
+ SpinnerColumn,
89
+ TextColumn,
90
+ TimeElapsedColumn,
91
+ )
92
+ except Exception:
93
+ for item in items:
94
+ yield item
95
+ return
96
+
97
+ with Progress(
98
+ SpinnerColumn(),
99
+ TextColumn("{task.description}"),
100
+ BarColumn(),
101
+ TimeElapsedColumn(),
102
+ console=console,
103
+ transient=True,
104
+ ) as progress:
105
+ task_id = progress.add_task(description, total=len(items))
106
+ for item in items:
107
+ yield item
108
+ progress.advance(task_id)
109
+
110
+
62
111
  def _display_session_analytics(
63
- console: Console, sdk: SDK, session_id: str, graph_dir: str
112
+ console: Console, sdk: "SDK", session_id: str, graph_dir: str, quiet: bool
64
113
  ) -> None:
65
114
  """Display analytics for a single session."""
66
115
  from htmlgraph.converter import html_to_session
@@ -72,19 +121,23 @@ def _display_session_analytics(
72
121
  return
73
122
 
74
123
  try:
75
- session = html_to_session(session_path)
124
+ with _status_context(console, quiet, "Loading session data..."):
125
+ session = html_to_session(session_path)
76
126
  except Exception as e:
77
127
  console.print(f"[red]Error loading session: {e}[/red]")
78
128
  return
79
129
 
80
130
  # Get analytics
81
- dist = sdk.analytics.work_type_distribution(session_id=session_id)
82
- ratio = sdk.analytics.spike_to_feature_ratio(session_id=session_id)
83
- burden = sdk.analytics.maintenance_burden(session_id=session_id)
84
- primary = sdk.analytics.calculate_session_primary_work_type(session_id)
85
- breakdown = sdk.analytics.calculate_session_work_breakdown(session_id)
86
- total_events = sum(breakdown.values()) if breakdown else session.event_count
87
- transition_metrics = sdk.analytics.transition_time_metrics(session_id=session_id)
131
+ with _status_context(console, quiet, "Computing session analytics..."):
132
+ dist = sdk.analytics.work_type_distribution(session_id=session_id)
133
+ ratio = sdk.analytics.spike_to_feature_ratio(session_id=session_id)
134
+ burden = sdk.analytics.maintenance_burden(session_id=session_id)
135
+ primary = sdk.analytics.calculate_session_primary_work_type(session_id)
136
+ breakdown = sdk.analytics.calculate_session_work_breakdown(session_id)
137
+ total_events = sum(breakdown.values()) if breakdown else session.event_count
138
+ transition_metrics = sdk.analytics.transition_time_metrics(
139
+ session_id=session_id
140
+ )
88
141
 
89
142
  # Header panel
90
143
  header = Panel(
@@ -167,7 +220,11 @@ def _display_session_analytics(
167
220
 
168
221
 
169
222
  def _display_recent_sessions(
170
- console: Console, sdk: SDK, session_files: list[Path], graph_dir: str
223
+ console: Console,
224
+ sdk: "SDK",
225
+ session_files: list[Path],
226
+ graph_dir: str,
227
+ quiet: bool,
171
228
  ) -> None:
172
229
  """Display analytics for recent sessions."""
173
230
  console.print(
@@ -188,7 +245,9 @@ def _display_recent_sessions(
188
245
  table.add_column("Primary Type", style="yellow")
189
246
  table.add_column("Spike Ratio", justify="right")
190
247
 
191
- for session_path in session_files:
248
+ for session_path in _iter_with_progress(
249
+ console, quiet, session_files, "Processing sessions"
250
+ ):
192
251
  try:
193
252
  session = html_to_session(session_path)
194
253
  session_id = session.id
@@ -226,7 +285,11 @@ def _display_recent_sessions(
226
285
 
227
286
 
228
287
  def _display_project_analytics(
229
- console: Console, sdk: SDK, session_files: list[Path], graph_dir: str
288
+ console: Console,
289
+ sdk: "SDK",
290
+ session_files: list[Path],
291
+ graph_dir: str,
292
+ quiet: bool,
230
293
  ) -> None:
231
294
  """Display project-wide analytics."""
232
295
  console.print(
@@ -240,10 +303,11 @@ def _display_project_analytics(
240
303
  console.print()
241
304
 
242
305
  # Get project-wide metrics
243
- all_dist = sdk.analytics.work_type_distribution()
244
- all_ratio = sdk.analytics.spike_to_feature_ratio()
245
- all_burden = sdk.analytics.maintenance_burden()
246
- all_transition = sdk.analytics.transition_time_metrics()
306
+ with _status_context(console, quiet, "Computing project analytics..."):
307
+ all_dist = sdk.analytics.work_type_distribution()
308
+ all_ratio = sdk.analytics.spike_to_feature_ratio()
309
+ all_burden = sdk.analytics.maintenance_burden()
310
+ all_transition = sdk.analytics.transition_time_metrics()
247
311
 
248
312
  # Work distribution table
249
313
  if all_dist:
@@ -341,7 +405,9 @@ def _display_project_analytics(
341
405
  console.print("[bold]Recent Sessions:[/bold]")
342
406
  recent_files = session_files[:5]
343
407
 
344
- for session_path in recent_files:
408
+ for session_path in _iter_with_progress(
409
+ console, quiet, recent_files, "Loading recent sessions"
410
+ ):
345
411
  try:
346
412
  session = html_to_session(session_path)
347
413
  primary = (