htmlgraph 0.26.25__py3-none-any.whl → 0.27.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. htmlgraph/__init__.py +23 -1
  2. htmlgraph/__init__.pyi +123 -0
  3. htmlgraph/agent_registry.py +2 -1
  4. htmlgraph/analytics/cli.py +3 -3
  5. htmlgraph/analytics/cost_analyzer.py +5 -1
  6. htmlgraph/analytics/cross_session.py +13 -9
  7. htmlgraph/analytics/dependency.py +10 -6
  8. htmlgraph/analytics/work_type.py +15 -11
  9. htmlgraph/analytics_index.py +2 -1
  10. htmlgraph/api/main.py +58 -28
  11. htmlgraph/attribute_index.py +2 -1
  12. htmlgraph/builders/base.py +2 -1
  13. htmlgraph/builders/bug.py +2 -1
  14. htmlgraph/builders/chore.py +2 -1
  15. htmlgraph/builders/epic.py +2 -1
  16. htmlgraph/builders/feature.py +2 -1
  17. htmlgraph/builders/insight.py +2 -1
  18. htmlgraph/builders/metric.py +2 -1
  19. htmlgraph/builders/pattern.py +2 -1
  20. htmlgraph/builders/phase.py +2 -1
  21. htmlgraph/builders/spike.py +2 -1
  22. htmlgraph/builders/track.py +2 -1
  23. htmlgraph/cli/analytics.py +2 -1
  24. htmlgraph/cli/base.py +2 -1
  25. htmlgraph/cli/core.py +2 -1
  26. htmlgraph/cli/main.py +2 -1
  27. htmlgraph/cli/models.py +2 -1
  28. htmlgraph/cli/templates/cost_dashboard.py +2 -1
  29. htmlgraph/cli/work/__init__.py +2 -1
  30. htmlgraph/cli/work/browse.py +2 -1
  31. htmlgraph/cli/work/features.py +2 -1
  32. htmlgraph/cli/work/orchestration.py +2 -1
  33. htmlgraph/cli/work/report.py +2 -1
  34. htmlgraph/cli/work/sessions.py +2 -1
  35. htmlgraph/cli/work/snapshot.py +2 -1
  36. htmlgraph/cli/work/tracks.py +2 -1
  37. htmlgraph/collections/base.py +10 -5
  38. htmlgraph/collections/bug.py +2 -1
  39. htmlgraph/collections/chore.py +2 -1
  40. htmlgraph/collections/epic.py +2 -1
  41. htmlgraph/collections/feature.py +2 -1
  42. htmlgraph/collections/insight.py +2 -1
  43. htmlgraph/collections/metric.py +2 -1
  44. htmlgraph/collections/pattern.py +2 -1
  45. htmlgraph/collections/phase.py +2 -1
  46. htmlgraph/collections/session.py +12 -7
  47. htmlgraph/collections/spike.py +6 -1
  48. htmlgraph/collections/task_delegation.py +7 -2
  49. htmlgraph/collections/todo.py +2 -1
  50. htmlgraph/collections/traces.py +15 -10
  51. htmlgraph/context_analytics.py +2 -1
  52. htmlgraph/dependency_models.py +2 -1
  53. htmlgraph/edge_index.py +2 -1
  54. htmlgraph/event_log.py +81 -66
  55. htmlgraph/event_migration.py +2 -1
  56. htmlgraph/file_watcher.py +12 -8
  57. htmlgraph/find_api.py +2 -1
  58. htmlgraph/git_events.py +6 -2
  59. htmlgraph/hooks/cigs_pretool_enforcer.py +5 -1
  60. htmlgraph/hooks/drift_handler.py +3 -3
  61. htmlgraph/hooks/event_tracker.py +40 -61
  62. htmlgraph/hooks/installer.py +5 -1
  63. htmlgraph/hooks/orchestrator.py +4 -0
  64. htmlgraph/hooks/orchestrator_reflector.py +4 -0
  65. htmlgraph/hooks/post_tool_use_failure.py +7 -3
  66. htmlgraph/hooks/posttooluse.py +4 -0
  67. htmlgraph/hooks/prompt_analyzer.py +5 -5
  68. htmlgraph/hooks/session_handler.py +2 -1
  69. htmlgraph/hooks/session_summary.py +6 -2
  70. htmlgraph/hooks/validator.py +8 -4
  71. htmlgraph/ids.py +2 -1
  72. htmlgraph/learning.py +2 -1
  73. htmlgraph/mcp_server.py +2 -1
  74. htmlgraph/operations/analytics.py +2 -1
  75. htmlgraph/operations/bootstrap.py +2 -1
  76. htmlgraph/operations/events.py +2 -1
  77. htmlgraph/operations/fastapi_server.py +2 -1
  78. htmlgraph/operations/hooks.py +2 -1
  79. htmlgraph/operations/initialization.py +2 -1
  80. htmlgraph/operations/server.py +2 -1
  81. htmlgraph/orchestration/claude_launcher.py +23 -20
  82. htmlgraph/orchestration/command_builder.py +2 -1
  83. htmlgraph/orchestration/headless_spawner.py +6 -2
  84. htmlgraph/orchestration/model_selection.py +7 -3
  85. htmlgraph/orchestration/plugin_manager.py +24 -19
  86. htmlgraph/orchestration/spawners/claude.py +5 -2
  87. htmlgraph/orchestration/spawners/codex.py +12 -19
  88. htmlgraph/orchestration/spawners/copilot.py +13 -18
  89. htmlgraph/orchestration/spawners/gemini.py +12 -19
  90. htmlgraph/orchestration/subprocess_runner.py +6 -3
  91. htmlgraph/orchestration/task_coordination.py +16 -8
  92. htmlgraph/orchestrator.py +2 -1
  93. htmlgraph/parallel.py +2 -1
  94. htmlgraph/query_builder.py +2 -1
  95. htmlgraph/reflection.py +2 -1
  96. htmlgraph/refs.py +2 -1
  97. htmlgraph/repo_hash.py +2 -1
  98. htmlgraph/sdk/__init__.py +398 -0
  99. htmlgraph/sdk/__init__.pyi +14 -0
  100. htmlgraph/sdk/analytics/__init__.py +19 -0
  101. htmlgraph/sdk/analytics/engine.py +155 -0
  102. htmlgraph/sdk/analytics/helpers.py +178 -0
  103. htmlgraph/sdk/analytics/registry.py +109 -0
  104. htmlgraph/sdk/base.py +484 -0
  105. htmlgraph/sdk/constants.py +216 -0
  106. htmlgraph/sdk/core.pyi +308 -0
  107. htmlgraph/sdk/discovery.py +120 -0
  108. htmlgraph/sdk/help/__init__.py +12 -0
  109. htmlgraph/sdk/help/mixin.py +699 -0
  110. htmlgraph/sdk/mixins/__init__.py +15 -0
  111. htmlgraph/sdk/mixins/attribution.py +113 -0
  112. htmlgraph/sdk/mixins/mixin.py +410 -0
  113. htmlgraph/sdk/operations/__init__.py +12 -0
  114. htmlgraph/sdk/operations/mixin.py +427 -0
  115. htmlgraph/sdk/orchestration/__init__.py +17 -0
  116. htmlgraph/sdk/orchestration/coordinator.py +203 -0
  117. htmlgraph/sdk/orchestration/spawner.py +204 -0
  118. htmlgraph/sdk/planning/__init__.py +19 -0
  119. htmlgraph/sdk/planning/bottlenecks.py +93 -0
  120. htmlgraph/sdk/planning/mixin.py +211 -0
  121. htmlgraph/sdk/planning/parallel.py +186 -0
  122. htmlgraph/sdk/planning/queue.py +210 -0
  123. htmlgraph/sdk/planning/recommendations.py +87 -0
  124. htmlgraph/sdk/planning/smart_planning.py +319 -0
  125. htmlgraph/sdk/session/__init__.py +19 -0
  126. htmlgraph/sdk/session/continuity.py +57 -0
  127. htmlgraph/sdk/session/handoff.py +110 -0
  128. htmlgraph/sdk/session/info.py +309 -0
  129. htmlgraph/sdk/session/manager.py +103 -0
  130. htmlgraph/server.py +21 -17
  131. htmlgraph/session_warning.py +2 -1
  132. htmlgraph/sessions/handoff.py +4 -3
  133. htmlgraph/system_prompts.py +2 -1
  134. htmlgraph/track_builder.py +2 -1
  135. htmlgraph/transcript.py +2 -1
  136. htmlgraph/watch.py +2 -1
  137. htmlgraph/work_type_utils.py +2 -1
  138. {htmlgraph-0.26.25.dist-info → htmlgraph-0.27.0.dist-info}/METADATA +15 -1
  139. {htmlgraph-0.26.25.dist-info → htmlgraph-0.27.0.dist-info}/RECORD +146 -114
  140. htmlgraph/sdk.py +0 -3500
  141. {htmlgraph-0.26.25.data → htmlgraph-0.27.0.data}/data/htmlgraph/dashboard.html +0 -0
  142. {htmlgraph-0.26.25.data → htmlgraph-0.27.0.data}/data/htmlgraph/styles.css +0 -0
  143. {htmlgraph-0.26.25.data → htmlgraph-0.27.0.data}/data/htmlgraph/templates/AGENTS.md.template +0 -0
  144. {htmlgraph-0.26.25.data → htmlgraph-0.27.0.data}/data/htmlgraph/templates/CLAUDE.md.template +0 -0
  145. {htmlgraph-0.26.25.data → htmlgraph-0.27.0.data}/data/htmlgraph/templates/GEMINI.md.template +0 -0
  146. {htmlgraph-0.26.25.dist-info → htmlgraph-0.27.0.dist-info}/WHEEL +0 -0
  147. {htmlgraph-0.26.25.dist-info → htmlgraph-0.27.0.dist-info}/entry_points.txt +0 -0
@@ -1,12 +1,14 @@
1
1
  """Copilot spawner implementation."""
2
2
 
3
+ import logging
3
4
  import subprocess
4
- import sys
5
5
  import time
6
6
  from typing import TYPE_CHECKING, Any
7
7
 
8
8
  from .base import AIResult, BaseSpawner
9
9
 
10
+ logger = logging.getLogger(__name__)
11
+
10
12
  if TYPE_CHECKING:
11
13
  from htmlgraph.sdk import SDK
12
14
 
@@ -129,15 +131,11 @@ class CopilotSpawner(BaseSpawner):
129
131
 
130
132
  # Record subprocess invocation if tracker is available
131
133
  subprocess_event_id = None
132
- print(
133
- f"DEBUG: tracker={tracker is not None}, parent_event_id={parent_event_id}",
134
- file=sys.stderr,
134
+ logger.warning(
135
+ f"DEBUG: tracker={tracker is not None}, parent_event_id={parent_event_id}"
135
136
  )
136
137
  if tracker and parent_event_id:
137
- print(
138
- "DEBUG: Recording subprocess invocation for Copilot...",
139
- file=sys.stderr,
140
- )
138
+ logger.debug("Recording subprocess invocation for Copilot...")
141
139
  try:
142
140
  subprocess_event = tracker.record_tool_call(
143
141
  tool_name="subprocess.copilot",
@@ -147,23 +145,20 @@ class CopilotSpawner(BaseSpawner):
147
145
  )
148
146
  if subprocess_event:
149
147
  subprocess_event_id = subprocess_event.get("event_id")
150
- print(
151
- f"DEBUG: Subprocess event created for Copilot: {subprocess_event_id}",
152
- file=sys.stderr,
148
+ logger.warning(
149
+ f"DEBUG: Subprocess event created for Copilot: {subprocess_event_id}"
153
150
  )
154
151
  else:
155
- print("DEBUG: subprocess_event was None", file=sys.stderr)
152
+ logger.debug("subprocess_event was None")
156
153
  except Exception as e:
157
154
  # Tracking failure should not break execution
158
- print(
159
- f"DEBUG: Exception recording Copilot subprocess: {e}",
160
- file=sys.stderr,
155
+ logger.warning(
156
+ f"DEBUG: Exception recording Copilot subprocess: {e}"
161
157
  )
162
158
  pass
163
159
  else:
164
- print(
165
- f"DEBUG: Skipping Copilot subprocess tracking - tracker={tracker is not None}, parent_event_id={parent_event_id}",
166
- file=sys.stderr,
160
+ logger.warning(
161
+ f"DEBUG: Skipping Copilot subprocess tracking - tracker={tracker is not None}, parent_event_id={parent_event_id}"
167
162
  )
168
163
 
169
164
  result = subprocess.run(
@@ -1,13 +1,15 @@
1
1
  """Gemini spawner implementation."""
2
2
 
3
3
  import json
4
+ import logging
4
5
  import subprocess
5
- import sys
6
6
  import time
7
7
  from typing import TYPE_CHECKING, Any
8
8
 
9
9
  from .base import AIResult, BaseSpawner
10
10
 
11
+ logger = logging.getLogger(__name__)
12
+
11
13
  if TYPE_CHECKING:
12
14
  from htmlgraph.sdk import SDK
13
15
 
@@ -220,15 +222,11 @@ class GeminiSpawner(BaseSpawner):
220
222
 
221
223
  # Record subprocess invocation if tracker is available
222
224
  subprocess_event_id = None
223
- print(
224
- f"DEBUG: tracker={tracker is not None}, parent_event_id={parent_event_id}",
225
- file=sys.stderr,
225
+ logger.warning(
226
+ f"DEBUG: tracker={tracker is not None}, parent_event_id={parent_event_id}"
226
227
  )
227
228
  if tracker and parent_event_id:
228
- print(
229
- "DEBUG: Recording subprocess invocation for Gemini...",
230
- file=sys.stderr,
231
- )
229
+ logger.debug("Recording subprocess invocation for Gemini...")
232
230
  try:
233
231
  subprocess_event = tracker.record_tool_call(
234
232
  tool_name="subprocess.gemini",
@@ -238,23 +236,18 @@ class GeminiSpawner(BaseSpawner):
238
236
  )
239
237
  if subprocess_event:
240
238
  subprocess_event_id = subprocess_event.get("event_id")
241
- print(
242
- f"DEBUG: Subprocess event created for Gemini: {subprocess_event_id}",
243
- file=sys.stderr,
239
+ logger.warning(
240
+ f"DEBUG: Subprocess event created for Gemini: {subprocess_event_id}"
244
241
  )
245
242
  else:
246
- print("DEBUG: subprocess_event was None", file=sys.stderr)
243
+ logger.debug("subprocess_event was None")
247
244
  except Exception as e:
248
245
  # Tracking failure should not break execution
249
- print(
250
- f"DEBUG: Exception recording Gemini subprocess: {e}",
251
- file=sys.stderr,
252
- )
246
+ logger.warning(f"DEBUG: Exception recording Gemini subprocess: {e}")
253
247
  pass
254
248
  else:
255
- print(
256
- f"DEBUG: Skipping Gemini subprocess tracking - tracker={tracker is not None}, parent_event_id={parent_event_id}",
257
- file=sys.stderr,
249
+ logger.warning(
250
+ f"DEBUG: Skipping Gemini subprocess tracking - tracker={tracker is not None}, parent_event_id={parent_event_id}"
258
251
  )
259
252
 
260
253
  # Execute with timeout and stderr redirection
@@ -1,13 +1,16 @@
1
+ from __future__ import annotations
2
+
1
3
  """Subprocess execution with standardized error handling.
2
4
 
3
5
  Provides consistent error handling for Claude Code CLI invocations.
4
6
  """
5
7
 
6
- from __future__ import annotations
7
-
8
+ import logging
8
9
  import subprocess
9
10
  import sys
10
11
 
12
+ logger = logging.getLogger(__name__)
13
+
11
14
 
12
15
  class SubprocessRunner:
13
16
  """Execute subprocess commands with error handling."""
@@ -25,7 +28,7 @@ class SubprocessRunner:
25
28
  try:
26
29
  subprocess.run(cmd, check=False)
27
30
  except FileNotFoundError:
28
- print("Error: 'claude' command not found.", file=sys.stderr)
31
+ logger.warning("Error: 'claude' command not found.")
29
32
  print(
30
33
  "Please install Claude Code CLI: https://code.claude.com",
31
34
  file=sys.stderr,
@@ -1,3 +1,7 @@
1
+ import logging
2
+
3
+ logger = logging.getLogger(__name__)
4
+
1
5
  """
2
6
  Orchestration helpers for reliable parallel task coordination.
3
7
 
@@ -7,9 +11,13 @@ Provides Task ID pattern for retrieving results from parallel delegations.
7
11
  import time
8
12
  import uuid
9
13
  from datetime import datetime, timedelta
10
- from typing import Any
14
+ from typing import TYPE_CHECKING, Any
11
15
 
12
- from htmlgraph.sdk import SDK
16
+ if TYPE_CHECKING:
17
+ from htmlgraph.sdk import SDK
18
+ else:
19
+ # Avoid circular import during module initialization
20
+ SDK = None
13
21
 
14
22
 
15
23
  def generate_task_id() -> str:
@@ -72,7 +80,7 @@ Provide detailed findings in your response.
72
80
 
73
81
 
74
82
  def get_results_by_task_id(
75
- sdk: SDK,
83
+ sdk: "SDK",
76
84
  task_id: str,
77
85
  timeout: int = 60,
78
86
  poll_interval: int = 2,
@@ -138,7 +146,7 @@ def get_results_by_task_id(
138
146
 
139
147
 
140
148
  def parallel_delegate(
141
- sdk: SDK,
149
+ sdk: "SDK",
142
150
  tasks: list[dict[str, str]],
143
151
  timeout: int = 120,
144
152
  ) -> dict[str, dict[str, Any]]:
@@ -161,7 +169,7 @@ def parallel_delegate(
161
169
  ])
162
170
 
163
171
  for task_id, result in results.items():
164
- print(f"{task_id}: {result['findings']}")
172
+ logger.info(f"{task_id}: {result['findings']}")
165
173
  """
166
174
  # Generate task IDs and enhanced prompts
167
175
  task_mapping = {}
@@ -189,7 +197,7 @@ def parallel_delegate(
189
197
 
190
198
 
191
199
  def save_task_results(
192
- sdk: SDK,
200
+ sdk: "SDK",
193
201
  task_id: str,
194
202
  description: str,
195
203
  results: str,
@@ -263,7 +271,7 @@ def save_task_results(
263
271
 
264
272
 
265
273
  def validate_and_save(
266
- sdk: SDK,
274
+ sdk: "SDK",
267
275
  task_id: str,
268
276
  description: str,
269
277
  results: str,
@@ -303,7 +311,7 @@ def validate_and_save(
303
311
  )
304
312
 
305
313
  if outcome["validated"]:
306
- print(f"✅ Saved to spike: {outcome['spike_id']}")
314
+ logger.info(f"✅ Saved to spike: {outcome['spike_id']}")
307
315
  """
308
316
  validated = True
309
317
  validation_results = None
htmlgraph/orchestrator.py CHANGED
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+
1
3
  """
2
4
  SubagentOrchestrator for context-preserving delegation.
3
5
 
@@ -83,7 +85,6 @@ Key Patterns
83
85
  4. Parallel execution: Multiple subagents can work simultaneously
84
86
  """
85
87
 
86
- from __future__ import annotations
87
88
 
88
89
  from dataclasses import dataclass, field
89
90
  from datetime import datetime
htmlgraph/parallel.py CHANGED
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+
1
3
  """
2
4
  Parallel workflow execution coordinator for multi-agent task processing.
3
5
 
@@ -76,7 +78,6 @@ Best Practices:
76
78
  - Limit to 3-5 parallel agents for optimal results
77
79
  """
78
80
 
79
- from __future__ import annotations
80
81
 
81
82
  from dataclasses import dataclass, field
82
83
  from datetime import datetime
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+
1
3
  """
2
4
  Fluent Query Builder for HtmlGraph.
3
5
 
@@ -24,7 +26,6 @@ Example:
24
26
  .execute()
25
27
  """
26
28
 
27
- from __future__ import annotations
28
29
 
29
30
  import re
30
31
  from collections.abc import Callable, Iterator
htmlgraph/reflection.py CHANGED
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+
1
3
  """
2
4
  Computational Reflection Module.
3
5
 
@@ -23,7 +25,6 @@ Usage:
23
25
  # }
24
26
  """
25
27
 
26
- from __future__ import annotations
27
28
 
28
29
  from dataclasses import dataclass
29
30
  from datetime import datetime, timedelta
htmlgraph/refs.py CHANGED
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+
1
3
  """
2
4
  Short reference manager for graph nodes.
3
5
 
@@ -5,7 +7,6 @@ Manages persistent mapping of short refs (@f1, @t2, @b5) to full node IDs,
5
7
  enabling AI-friendly snapshots and queries.
6
8
  """
7
9
 
8
- from __future__ import annotations
9
10
 
10
11
  import json
11
12
  from datetime import datetime
htmlgraph/repo_hash.py CHANGED
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+
1
3
  """
2
4
  Repository Hashing and Git Awareness Module.
3
5
 
@@ -22,7 +24,6 @@ Architecture:
22
24
  - monorepo_project: "project-name" (if in monorepo)
23
25
  """
24
26
 
25
- from __future__ import annotations
26
27
 
27
28
  import hashlib
28
29
  import logging