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
htmlgraph/setup.py CHANGED
@@ -8,13 +8,10 @@ Automates setup of HtmlGraph for different AI CLI platforms:
8
8
  - Gemini CLI (extension installation)
9
9
  """
10
10
 
11
- import json
12
- import os
13
11
  import shutil
14
12
  import subprocess
15
- import sys
16
13
  from pathlib import Path
17
- from typing import Optional
14
+ from typing import Any
18
15
 
19
16
 
20
17
  def check_command_exists(command: str) -> bool:
@@ -22,8 +19,11 @@ def check_command_exists(command: str) -> bool:
22
19
  return shutil.which(command) is not None
23
20
 
24
21
 
25
- def run_command(cmd: list[str], capture=False, check=True) -> subprocess.CompletedProcess:
22
+ def run_command(
23
+ cmd: list[str], capture: bool = False, check: bool = True
24
+ ) -> subprocess.CompletedProcess[Any]:
26
25
  """Run a shell command."""
26
+ result: subprocess.CompletedProcess[Any]
27
27
  try:
28
28
  if capture:
29
29
  result = subprocess.run(cmd, capture_output=True, text=True, check=check)
@@ -38,7 +38,7 @@ def run_command(cmd: list[str], capture=False, check=True) -> subprocess.Complet
38
38
  raise
39
39
 
40
40
 
41
- def setup_claude(args):
41
+ def setup_claude(args: Any) -> bool:
42
42
  """Set up HtmlGraph for Claude Code."""
43
43
  print("🔧 Setting up HtmlGraph for Claude Code...")
44
44
  print()
@@ -74,7 +74,9 @@ def setup_claude(args):
74
74
 
75
75
  # Try to get version
76
76
  if "@" in result.stdout:
77
- version_line = [line for line in result.stdout.split("\n") if "htmlgraph" in line]
77
+ version_line = [
78
+ line for line in result.stdout.split("\n") if "htmlgraph" in line
79
+ ]
78
80
  if version_line:
79
81
  print(f" {version_line[0].strip()}")
80
82
  else:
@@ -99,7 +101,7 @@ def setup_claude(args):
99
101
  return True
100
102
 
101
103
 
102
- def setup_codex(args):
104
+ def setup_codex(args: Any) -> bool:
103
105
  """Set up HtmlGraph for Codex CLI."""
104
106
  print("🔧 Setting up HtmlGraph for Codex CLI...")
105
107
  print()
@@ -142,7 +144,7 @@ def setup_codex(args):
142
144
  else:
143
145
  print("⚠️ SKILL.md not found - skill may be incomplete")
144
146
  else:
145
- print(f"\n⚠️ HtmlGraph skill not installed")
147
+ print("\n⚠️ HtmlGraph skill not installed")
146
148
  print("\n📥 Installation options:")
147
149
 
148
150
  # Check if we're in the HtmlGraph repo
@@ -167,7 +169,9 @@ def setup_codex(args):
167
169
  print(f" cp -r htmlgraph/packages/codex-skill {htmlgraph_skill_dir}")
168
170
 
169
171
  print("\n Option 3: Download manually:")
170
- print(" https://github.com/Shakes-tzd/htmlgraph/tree/main/packages/codex-skill")
172
+ print(
173
+ " https://github.com/Shakes-tzd/htmlgraph/tree/main/packages/codex-skill"
174
+ )
171
175
 
172
176
  # Check MCP configuration
173
177
  print("\n🔌 Checking MCP configuration...")
@@ -190,7 +194,7 @@ def setup_codex(args):
190
194
  return True
191
195
 
192
196
 
193
- def setup_gemini(args):
197
+ def setup_gemini(args: Any) -> bool:
194
198
  """Set up HtmlGraph for Gemini CLI."""
195
199
  print("🔧 Setting up HtmlGraph for Gemini CLI...")
196
200
  print()
@@ -207,7 +211,9 @@ def setup_gemini(args):
207
211
  print("\n🎯 Checking for HtmlGraph extension...")
208
212
 
209
213
  try:
210
- result = run_command(["gemini", "extensions", "list"], capture=True, check=False)
214
+ result = run_command(
215
+ ["gemini", "extensions", "list"], capture=True, check=False
216
+ )
211
217
  if result.returncode == 0 and "htmlgraph" in result.stdout.lower():
212
218
  print("✅ HtmlGraph extension already installed")
213
219
  else:
@@ -217,19 +223,28 @@ def setup_gemini(args):
217
223
  # Check if we're in the HtmlGraph repo
218
224
  repo_extension = Path.cwd() / "packages" / "gemini-extension"
219
225
  if repo_extension.exists():
220
- print(f"\n Option 1: Install from this repo:")
226
+ print("\n Option 1: Install from this repo:")
221
227
  print(f" gemini extensions install {repo_extension.absolute()}")
222
228
 
223
229
  if args.auto_install:
224
230
  print("\n Auto-installing...")
225
231
  try:
226
- run_command(["gemini", "extensions", "install", str(repo_extension.absolute())])
232
+ run_command(
233
+ [
234
+ "gemini",
235
+ "extensions",
236
+ "install",
237
+ str(repo_extension.absolute()),
238
+ ]
239
+ )
227
240
  print(" ✅ Extension installed")
228
241
  except Exception as e:
229
242
  print(f" ❌ Failed to install extension: {e}")
230
243
 
231
244
  print("\n Option 2: Install from GitHub:")
232
- print(" gemini extensions install https://github.com/Shakes-tzd/htmlgraph/tree/main/packages/gemini-extension")
245
+ print(
246
+ " gemini extensions install https://github.com/Shakes-tzd/htmlgraph/tree/main/packages/gemini-extension"
247
+ )
233
248
 
234
249
  print("\n Option 3: Create manually:")
235
250
  print(" gemini extensions create htmlgraph-tracker")
@@ -252,7 +267,7 @@ def setup_gemini(args):
252
267
  return True
253
268
 
254
269
 
255
- def setup_all(args):
270
+ def setup_all(args: Any) -> bool:
256
271
  """Set up HtmlGraph for all supported platforms."""
257
272
  print("🚀 Setting up HtmlGraph for all supported platforms...")
258
273
  print("=" * 60)
@@ -287,7 +302,9 @@ def setup_all(args):
287
302
  print("=" * 60)
288
303
  for platform, success in results.items():
289
304
  status = "✅" if success else "⚠️ "
290
- print(f"{status} {platform.upper()}: {'Ready' if success else 'Needs attention'}")
305
+ print(
306
+ f"{status} {platform.upper()}: {'Ready' if success else 'Needs attention'}"
307
+ )
291
308
  print()
292
309
 
293
310
  return all(results.values())
@@ -0,0 +1,143 @@
1
+ """
2
+ Lightweight index for tracking active auto-generated spikes.
3
+
4
+ This avoids the expensive operation of scanning all spike files on SessionManager init.
5
+ Instead, we maintain a simple JSON index that tracks only active auto-spikes.
6
+ """
7
+
8
+ import json
9
+ import logging
10
+ from pathlib import Path
11
+ from typing import Any
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ class ActiveAutoSpikeIndex:
17
+ """
18
+ Fast index for tracking active auto-generated spikes (session-init, transition, conversation-init).
19
+
20
+ This is much faster than scanning all spike files on startup.
21
+ The index is a simple JSON file that maps spike_id -> metadata.
22
+ """
23
+
24
+ def __init__(self, graph_dir: Path):
25
+ """
26
+ Initialize the index.
27
+
28
+ Args:
29
+ graph_dir: .htmlgraph directory
30
+ """
31
+ self.graph_dir = Path(graph_dir)
32
+ self.index_path = self.graph_dir / "active-auto-spikes.json"
33
+ self._data: dict[str, dict[str, Any]] = {}
34
+ self._loaded = False
35
+
36
+ def load(self) -> None:
37
+ """Load index from disk (lazy)."""
38
+ if self._loaded:
39
+ return
40
+
41
+ if self.index_path.exists():
42
+ try:
43
+ with open(self.index_path) as f:
44
+ self._data = json.load(f)
45
+ except (json.JSONDecodeError, OSError) as e:
46
+ logger.warning(
47
+ f"Failed to load active-auto-spikes index: {e}. Starting fresh."
48
+ )
49
+ self._data = {}
50
+ else:
51
+ self._data = {}
52
+
53
+ self._loaded = True
54
+
55
+ def save(self) -> None:
56
+ """Save index to disk."""
57
+ try:
58
+ with open(self.index_path, "w") as f:
59
+ json.dump(self._data, f, indent=2)
60
+ except OSError as e:
61
+ logger.warning(f"Failed to save active-auto-spikes index: {e}")
62
+
63
+ def add(
64
+ self, spike_id: str, spike_subtype: str, session_id: str | None = None
65
+ ) -> None:
66
+ """
67
+ Add an active auto-spike to the index.
68
+
69
+ Args:
70
+ spike_id: Spike ID
71
+ spike_subtype: Spike subtype (session-init, transition, conversation-init)
72
+ session_id: Optional session ID
73
+ """
74
+ self.load()
75
+ self._data[spike_id] = {
76
+ "spike_subtype": spike_subtype,
77
+ "session_id": session_id,
78
+ }
79
+ self.save()
80
+
81
+ def remove(self, spike_id: str) -> None:
82
+ """
83
+ Remove a spike from the index (when completed or deleted).
84
+
85
+ Args:
86
+ spike_id: Spike ID to remove
87
+ """
88
+ self.load()
89
+ if spike_id in self._data:
90
+ del self._data[spike_id]
91
+ self.save()
92
+
93
+ def get_all(self) -> set[str]:
94
+ """
95
+ Get all active auto-spike IDs.
96
+
97
+ Returns:
98
+ Set of spike IDs
99
+ """
100
+ self.load()
101
+ return set(self._data.keys())
102
+
103
+ def clear(self) -> None:
104
+ """Clear the index (for testing or cleanup)."""
105
+ self._data = {}
106
+ self.save()
107
+
108
+ def rebuild_from_disk(self) -> int:
109
+ """
110
+ Rebuild the index by scanning all spike files on disk.
111
+
112
+ This is the expensive operation we're trying to avoid during normal init.
113
+ Only call this when necessary (e.g., after manual file edits or corruption).
114
+
115
+ Returns:
116
+ Number of active auto-spikes found
117
+ """
118
+ from htmlgraph.converter import NodeConverter
119
+
120
+ spikes_dir = self.graph_dir / "spikes"
121
+ if not spikes_dir.exists():
122
+ self.clear()
123
+ return 0
124
+
125
+ spike_converter = NodeConverter(spikes_dir)
126
+ self._data = {}
127
+
128
+ # Scan all spikes for active auto-generated ones
129
+ for spike in spike_converter.load_all():
130
+ if (
131
+ spike.type == "spike"
132
+ and getattr(spike, "auto_generated", False)
133
+ and getattr(spike, "spike_subtype", None)
134
+ in ("session-init", "transition", "conversation-init")
135
+ and spike.status == "in-progress"
136
+ ):
137
+ self._data[spike.id] = {
138
+ "spike_subtype": spike.spike_subtype,
139
+ "session_id": getattr(spike, "session_id", None),
140
+ }
141
+
142
+ self.save()
143
+ return len(self._data)
htmlgraph/sync_docs.py CHANGED
@@ -15,8 +15,6 @@ Usage:
15
15
  import argparse
16
16
  import sys
17
17
  from pathlib import Path
18
- from typing import Dict, List
19
-
20
18
 
21
19
  # Platform-specific file templates
22
20
  PLATFORM_TEMPLATES = {
@@ -97,9 +95,9 @@ def generate_platform_file(platform: str, project_root: Path) -> str:
97
95
  f"Unknown platform: {platform}. Available: {', '.join(PLATFORM_TEMPLATES.keys())}"
98
96
  )
99
97
 
100
- content = f"""# {template['title']}
98
+ content = f"""# {template["title"]}
101
99
 
102
- **Platform-specific instructions for {template['platform_name']} AI agents.**
100
+ **Platform-specific instructions for {template["platform_name"]} AI agents.**
103
101
 
104
102
  ---
105
103
 
@@ -117,13 +115,13 @@ The main AGENTS.md file contains:
117
115
 
118
116
  ---
119
117
 
120
- ## {template['platform_name']}-Specific Notes
118
+ ## {template["platform_name"]}-Specific Notes
121
119
 
122
- {template['notes']}
120
+ {template["notes"]}
123
121
 
124
122
  ---
125
123
 
126
- ## Commands Available in {template['platform_name']}
124
+ ## Commands Available in {template["platform_name"]}
127
125
 
128
126
  All HtmlGraph commands are available through the extension/plugin:
129
127
 
@@ -160,7 +158,7 @@ def check_file_references_agents(filepath: Path) -> bool:
160
158
  return "AGENTS.md" in content
161
159
 
162
160
 
163
- def check_all_files(project_root: Path) -> Dict[str, bool]:
161
+ def check_all_files(project_root: Path) -> dict[str, bool]:
164
162
  """Check all platform files for AGENTS.md references."""
165
163
  results = {}
166
164
 
@@ -177,7 +175,8 @@ def check_all_files(project_root: Path) -> Dict[str, bool]:
177
175
 
178
176
  # Check package-specific skill files (actual locations)
179
177
  skill_files = {
180
- "claude-plugin": project_root / "packages/claude-plugin/skills/htmlgraph-tracker/SKILL.md",
178
+ "claude-plugin": project_root
179
+ / "packages/claude-plugin/skills/htmlgraph-tracker/SKILL.md",
181
180
  "gemini-extension": project_root / "packages/gemini-extension/GEMINI.md",
182
181
  "codex-skill": project_root / "packages/codex-skill/SKILL.md",
183
182
  }
@@ -190,7 +189,7 @@ def check_all_files(project_root: Path) -> Dict[str, bool]:
190
189
  return results
191
190
 
192
191
 
193
- def sync_all_files(project_root: Path, dry_run: bool = False) -> List[str]:
192
+ def sync_all_files(project_root: Path, dry_run: bool = False) -> list[str]:
194
193
  """Synchronize all platform files to reference AGENTS.md."""
195
194
  changes = []
196
195
 
@@ -222,7 +221,7 @@ def sync_all_files(project_root: Path, dry_run: bool = False) -> List[str]:
222
221
  return changes
223
222
 
224
223
 
225
- def main():
224
+ def main() -> int:
226
225
  parser = argparse.ArgumentParser(
227
226
  description="Synchronize AI agent memory files for a project"
228
227
  )
@@ -291,14 +290,12 @@ def main():
291
290
  filepath = project_root / template["filename"]
292
291
 
293
292
  if filepath.exists() and not args.force:
294
- print(
295
- f"⚠️ {filepath.name} already exists. Use --force to overwrite."
296
- )
293
+ print(f"⚠️ {filepath.name} already exists. Use --force to overwrite.")
297
294
  return 1
298
295
 
299
296
  filepath.write_text(content)
300
297
  print(f"✅ Created: {filepath}")
301
- print(f"\nThe file references AGENTS.md for core documentation.")
298
+ print("\nThe file references AGENTS.md for core documentation.")
302
299
  return 0
303
300
 
304
301
  except ValueError as e: