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/planning.py CHANGED
@@ -1,19 +1,94 @@
1
1
  """
2
- Pydantic models for HtmlGraph planning features (Conductor-style).
3
-
4
- This module provides models for:
5
- - Track: A collection of related work with spec + plan
6
- - Spec: Requirements document with acceptance criteria
7
- - Plan: Implementation plan with phases, tasks, and multiple views
8
- - Task: Individual work item within a plan
9
- - Phase: Logical grouping of tasks
2
+ Planning utilities for HtmlGraph (Conductor-style workflow).
3
+
4
+ This module provides Pydantic models for comprehensive project planning and tracking.
5
+ It implements a Conductor-style planning workflow where complex work is organized
6
+ into Tracks, each containing a Spec (requirements) and Plan (implementation strategy).
7
+
8
+ Available Classes:
9
+ - Track: Top-level container for a work stream with spec and plan
10
+ - Spec: Requirements document with priorities and acceptance criteria
11
+ - Plan: Implementation plan with phases, tasks, and multiple views (list/kanban/timeline/graph)
12
+ - Phase: Logical grouping of related tasks within a plan
13
+ - Task: Individual work item with estimates, blocking, and assignment
14
+ - Requirement: A requirement within a spec with verification status
15
+ - AcceptanceCriterion: An acceptance criterion for validating a spec
16
+
17
+ Conductor Workflow:
18
+ 1. Create Track: Define the work stream and its scope
19
+ 2. Write Spec: Document requirements and acceptance criteria
20
+ 3. Build Plan: Break work into phases and tasks
21
+ 4. Execute: Work through tasks, track progress
22
+ 5. Validate: Verify against acceptance criteria
23
+
24
+ Key Features:
25
+ - Multi-view rendering: List, Kanban, Timeline, and Graph views
26
+ - Dependency tracking: Tasks can be blocked by other tasks or features
27
+ - Progress tracking: Automatic completion percentage calculation
28
+ - HTML output: Rich, styled HTML documents with dashboard design system
29
+ - Linking: Tracks link to features and sessions for traceability
30
+
31
+ Usage:
32
+ from htmlgraph.planning import Track, Spec, Plan, Phase, Task
33
+ from htmlgraph.sdk import SDK
34
+
35
+ sdk = SDK(agent="claude")
36
+
37
+ # Create a track
38
+ track = Track(
39
+ id="track-001",
40
+ title="User Authentication System",
41
+ description="Complete auth system with OAuth",
42
+ status="active"
43
+ )
44
+
45
+ # Build a spec with requirements
46
+ spec = Spec(
47
+ id="spec-001",
48
+ title="Auth System Requirements",
49
+ track_id="track-001",
50
+ overview="OAuth-based authentication with JWT sessions",
51
+ requirements=[
52
+ Requirement(
53
+ id="req-001",
54
+ description="Support Google and GitHub OAuth",
55
+ priority="must-have"
56
+ )
57
+ ]
58
+ )
59
+
60
+ # Build a plan with phases and tasks
61
+ plan = Plan(
62
+ id="plan-001",
63
+ title="Auth Implementation Plan",
64
+ track_id="track-001",
65
+ phases=[
66
+ Phase(
67
+ id="1",
68
+ name="Foundation",
69
+ tasks=[
70
+ Task(
71
+ id="task-001",
72
+ description="Set up OAuth providers",
73
+ estimate_hours=4.0,
74
+ priority="high"
75
+ )
76
+ ]
77
+ )
78
+ ]
79
+ )
80
+
81
+ # Generate HTML outputs
82
+ spec_html = spec.to_html()
83
+ plan_html = plan.to_html()
10
84
  """
11
85
 
12
86
  from datetime import datetime
13
87
  from typing import Any, Literal
88
+
14
89
  from pydantic import BaseModel, Field
15
90
 
16
- from htmlgraph.models import Step, Edge
91
+ from htmlgraph.models import Step
17
92
 
18
93
 
19
94
  class Requirement(BaseModel):
@@ -25,7 +100,9 @@ class Requirement(BaseModel):
25
100
  verified: bool = False
26
101
  notes: str = ""
27
102
  related_tech: list[str] = Field(default_factory=list) # Links to tech stack
28
- feature_ids: list[str] = Field(default_factory=list) # Features satisfying this requirement
103
+ feature_ids: list[str] = Field(
104
+ default_factory=list
105
+ ) # Features satisfying this requirement
29
106
 
30
107
  def to_html(self) -> str:
31
108
  """Convert requirement to HTML article element."""
@@ -40,11 +117,11 @@ class Requirement(BaseModel):
40
117
  f'<li><a href="../../project/tech-stack.html#{tech}">{tech}</a></li>'
41
118
  for tech in self.related_tech
42
119
  )
43
- tech_links = f'''
120
+ tech_links = f"""
44
121
  <nav data-related>
45
122
  <h4>Related Tech:</h4>
46
123
  <ul>{tech_items}</ul>
47
- </nav>'''
124
+ </nav>"""
48
125
 
49
126
  notes_html = f"<p>{self.notes}</p>" if self.notes else ""
50
127
 
@@ -62,7 +139,9 @@ class AcceptanceCriterion(BaseModel):
62
139
  description: str
63
140
  completed: bool = False
64
141
  test_case: str | None = None
65
- feature_ids: list[str] = Field(default_factory=list) # Features satisfying this criterion
142
+ feature_ids: list[str] = Field(
143
+ default_factory=list
144
+ ) # Features satisfying this criterion
66
145
 
67
146
  def to_html(self) -> str:
68
147
  """Convert criterion to HTML list item."""
@@ -71,9 +150,9 @@ class AcceptanceCriterion(BaseModel):
71
150
 
72
151
  test_html = ""
73
152
  if self.test_case:
74
- test_html = f'<code>{self.test_case}</code>'
153
+ test_html = f"<code>{self.test_case}</code>"
75
154
 
76
- return f'<li{completed_attr}>{status} {self.description} {test_html}</li>'
155
+ return f"<li{completed_attr}>{status} {self.description} {test_html}</li>"
77
156
 
78
157
 
79
158
  class Spec(BaseModel):
@@ -111,35 +190,45 @@ class Spec(BaseModel):
111
190
  req_html = ""
112
191
  if self.requirements:
113
192
  req_items = "\n".join(req.to_html() for req in self.requirements)
114
- req_html = f'''
193
+ req_html = f"""
115
194
  <section data-section="requirements">
116
195
  <h2>Requirements</h2>
117
196
  <div class="requirements-list">
118
197
  {req_items}
119
198
  </div>
120
- </section>'''
199
+ </section>"""
121
200
 
122
201
  # Build acceptance criteria HTML
123
202
  ac_html = ""
124
203
  if self.acceptance_criteria:
125
- ac_items = "\n ".join(ac.to_html() for ac in self.acceptance_criteria)
126
- ac_html = f'''
204
+ ac_items = "\n ".join(
205
+ ac.to_html() for ac in self.acceptance_criteria
206
+ )
207
+ ac_html = f"""
127
208
  <section data-section="acceptance-criteria">
128
209
  <h2>Acceptance Criteria</h2>
129
210
  <ol class="criteria-list">
130
211
  {ac_items}
131
212
  </ol>
132
- </section>'''
213
+ </section>"""
133
214
 
134
215
  # Build links HTML with back navigation
135
- nav_html = f'''
216
+ nav_html = """
136
217
  <div class="spec-nav">
137
218
  <a href="index.html" class="nav-link">← Track</a>
138
219
  <a href="plan.html" class="nav-link">Plan →</a>
139
- </div>'''
140
-
141
- overview_html = f"<p>{self.overview}</p>" if self.overview else "<p class=\"muted\">No overview provided</p>"
142
- context_html = f"<p>{self.context}</p>" if self.context else "<p class=\"muted\">No context provided</p>"
220
+ </div>"""
221
+
222
+ overview_html = (
223
+ f"<p>{self.overview}</p>"
224
+ if self.overview
225
+ else '<p class="muted">No overview provided</p>'
226
+ )
227
+ context_html = (
228
+ f"<p>{self.context}</p>"
229
+ if self.context
230
+ else '<p class="muted">No context provided</p>'
231
+ )
143
232
 
144
233
  return f'''<!DOCTYPE html>
145
234
  <html lang="en">
@@ -379,7 +468,9 @@ class Task(BaseModel):
379
468
  # Relationships
380
469
  blocked_by: list[str] = Field(default_factory=list) # Task IDs or feature IDs
381
470
  subtasks: list[Step] = Field(default_factory=list)
382
- feature_ids: list[str] = Field(default_factory=list) # Features implementing this task
471
+ feature_ids: list[str] = Field(
472
+ default_factory=list
473
+ ) # Features implementing this task
383
474
 
384
475
  # Tracking
385
476
  started_at: datetime | None = None
@@ -390,7 +481,9 @@ class Task(BaseModel):
390
481
  completed_attr = f' data-completed="{str(self.completed).lower()}"'
391
482
  priority_attr = f' data-priority="{self.priority}"'
392
483
  assigned_attr = f' data-assigned="{self.assigned}"' if self.assigned else ""
393
- blocked_attr = f' data-blocked-by="{",".join(self.blocked_by)}"' if self.blocked_by else ""
484
+ blocked_attr = (
485
+ f' data-blocked-by="{",".join(self.blocked_by)}"' if self.blocked_by else ""
486
+ )
394
487
 
395
488
  status_icon = "✅" if self.completed else ("⏳" if self.started_at else "○")
396
489
 
@@ -399,23 +492,25 @@ class Task(BaseModel):
399
492
  if self.blocked_by:
400
493
  block_items = "".join(
401
494
  f'<li><a href="../../features/{bid}.html">Depends on: {bid}</a></li>'
402
- if bid.startswith("feature-") else
403
- f'<li>Depends on: {bid}</li>'
495
+ if bid.startswith("feature-")
496
+ else f"<li>Depends on: {bid}</li>"
404
497
  for bid in self.blocked_by
405
498
  )
406
- blocking_html = f'''
499
+ blocking_html = f"""
407
500
  <nav data-task-links>
408
501
  <ul>{block_items}</ul>
409
- </nav>'''
502
+ </nav>"""
410
503
 
411
504
  # Build subtasks
412
505
  subtasks_html = ""
413
506
  if self.subtasks:
414
- subtask_items = "\n ".join(st.to_html() for st in self.subtasks)
415
- subtasks_html = f'''
507
+ subtask_items = "\n ".join(
508
+ st.to_html() for st in self.subtasks
509
+ )
510
+ subtasks_html = f"""
416
511
  <ul data-subtasks>
417
512
  {subtask_items}
418
- </ul>'''
513
+ </ul>"""
419
514
 
420
515
  estimate_html = ""
421
516
  if self.estimate_hours:
@@ -525,7 +620,7 @@ class Plan(BaseModel):
525
620
 
526
621
  # Progress bar with dashboard styling
527
622
  completion = self.completion_percentage
528
- progress_html = f'''
623
+ progress_html = f"""
529
624
  <div class="progress-container">
530
625
  <div class="progress-info">
531
626
  <span class="progress-label">{completion}% Complete</span>
@@ -534,19 +629,19 @@ class Plan(BaseModel):
534
629
  <div class="progress-bar">
535
630
  <div class="progress-fill" style="width: {completion}%"></div>
536
631
  </div>
537
- </div>'''
632
+ </div>"""
538
633
 
539
634
  # Navigation for different views - matching dashboard view buttons exactly
540
- view_nav = '''
635
+ view_nav = """
541
636
  <div class="view-toggle">
542
637
  <button onclick="showView('list')" class="view-btn active" data-view="list">List</button>
543
638
  <button onclick="showView('kanban')" class="view-btn" data-view="kanban">Kanban</button>
544
639
  <button onclick="showView('timeline')" class="view-btn" data-view="timeline">Timeline</button>
545
640
  <button onclick="showView('graph')" class="view-btn" data-view="graph">Graph</button>
546
- </div>'''
641
+ </div>"""
547
642
 
548
643
  # JavaScript for view switching - updated for dashboard-style buttons
549
- js_code = '''
644
+ js_code = """
550
645
  <script>
551
646
  function showView(view) {
552
647
  // Hide all view containers
@@ -610,10 +705,10 @@ class Plan(BaseModel):
610
705
  // TODO: Implement graph visualization of dependencies
611
706
  console.log('Graph view');
612
707
  }
613
- </script>'''
708
+ </script>"""
614
709
 
615
710
  # Search and filter controls with dashboard styling
616
- controls_html = '''
711
+ controls_html = """
617
712
  <div class="controls">
618
713
  <input type="search" class="search-input" placeholder="Search tasks..." oninput="filterTasks(this.value)">
619
714
  <select class="agent-filter" onchange="filterByAgent(this.value)">
@@ -621,27 +716,27 @@ class Plan(BaseModel):
621
716
  <option value="claude">Claude</option>
622
717
  <option value="copilot">Copilot</option>
623
718
  </select>
624
- </div>'''
719
+ </div>"""
625
720
 
626
721
  # Navigation links to connect with existing features
627
- nav_links = '''
722
+ nav_links = """
628
723
  <div class="plan-nav">
629
724
  <a href="../../index.html" class="nav-link">← Dashboard</a>
630
725
  <a href="index.html" class="nav-link">Track</a>
631
726
  <a href="spec.html" class="nav-link">Spec</a>
632
- </div>'''
727
+ </div>"""
633
728
 
634
729
  # List view (default)
635
- list_view = f'''
730
+ list_view = f"""
636
731
  <div class="view-container" data-view="list">
637
732
  {controls_html}
638
733
  <div class="phases-container">
639
734
  {phases_html}
640
735
  </div>
641
- </div>'''
736
+ </div>"""
642
737
 
643
738
  # Kanban view - matching dashboard kanban styling
644
- kanban_view = '''
739
+ kanban_view = """
645
740
  <div class="view-container kanban-view" data-view="kanban" style="display: none;">
646
741
  <div class="kanban-board">
647
742
  <div class="kanban-column" data-status="todo">
@@ -657,26 +752,26 @@ class Plan(BaseModel):
657
752
  <div id="kanban-done" class="column-content"></div>
658
753
  </div>
659
754
  </div>
660
- </div>'''
755
+ </div>"""
661
756
 
662
757
  # Timeline view placeholder
663
- timeline_view = '''
758
+ timeline_view = """
664
759
  <div class="view-container" data-view="timeline" style="display: none;">
665
760
  <div class="timeline-placeholder">
666
761
  <p class="muted">Timeline view - Coming soon</p>
667
762
  <p class="muted">Will visualize tasks on a timeline with milestones</p>
668
763
  </div>
669
- </div>'''
764
+ </div>"""
670
765
 
671
766
  # Graph view placeholder
672
- graph_view = '''
767
+ graph_view = """
673
768
  <div class="view-container" data-view="graph" style="display: none;">
674
769
  <div class="graph-placeholder">
675
770
  <p class="muted">Dependency graph - Coming soon</p>
676
771
  <p class="muted">Will visualize task dependencies and blocking relationships</p>
677
772
  </div>
678
773
  <svg id="dependency-graph" width="100%" height="600"></svg>
679
- </div>'''
774
+ </div>"""
680
775
 
681
776
  return f'''<!DOCTYPE html>
682
777
  <html lang="en">