htmlgraph 0.24.2__py3-none-any.whl → 0.25.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 (103) hide show
  1. htmlgraph/__init__.py +20 -1
  2. htmlgraph/agent_detection.py +26 -10
  3. htmlgraph/analytics/cross_session.py +4 -3
  4. htmlgraph/analytics/work_type.py +52 -16
  5. htmlgraph/analytics_index.py +51 -19
  6. htmlgraph/api/__init__.py +3 -0
  7. htmlgraph/api/main.py +2115 -0
  8. htmlgraph/api/static/htmx.min.js +1 -0
  9. htmlgraph/api/static/style-redesign.css +1344 -0
  10. htmlgraph/api/static/style.css +1079 -0
  11. htmlgraph/api/templates/dashboard-redesign.html +812 -0
  12. htmlgraph/api/templates/dashboard.html +783 -0
  13. htmlgraph/api/templates/partials/activity-feed-hierarchical.html +326 -0
  14. htmlgraph/api/templates/partials/activity-feed.html +570 -0
  15. htmlgraph/api/templates/partials/agents-redesign.html +317 -0
  16. htmlgraph/api/templates/partials/agents.html +317 -0
  17. htmlgraph/api/templates/partials/event-traces.html +373 -0
  18. htmlgraph/api/templates/partials/features-kanban-redesign.html +509 -0
  19. htmlgraph/api/templates/partials/features.html +509 -0
  20. htmlgraph/api/templates/partials/metrics-redesign.html +346 -0
  21. htmlgraph/api/templates/partials/metrics.html +346 -0
  22. htmlgraph/api/templates/partials/orchestration-redesign.html +443 -0
  23. htmlgraph/api/templates/partials/orchestration.html +163 -0
  24. htmlgraph/api/templates/partials/spawners.html +375 -0
  25. htmlgraph/atomic_ops.py +560 -0
  26. htmlgraph/builders/base.py +55 -1
  27. htmlgraph/builders/bug.py +17 -2
  28. htmlgraph/builders/chore.py +17 -2
  29. htmlgraph/builders/epic.py +17 -2
  30. htmlgraph/builders/feature.py +25 -2
  31. htmlgraph/builders/phase.py +17 -2
  32. htmlgraph/builders/spike.py +27 -2
  33. htmlgraph/builders/track.py +14 -0
  34. htmlgraph/cigs/__init__.py +4 -0
  35. htmlgraph/cigs/reporter.py +818 -0
  36. htmlgraph/cli.py +1427 -401
  37. htmlgraph/cli_commands/__init__.py +1 -0
  38. htmlgraph/cli_commands/feature.py +195 -0
  39. htmlgraph/cli_framework.py +115 -0
  40. htmlgraph/collections/__init__.py +2 -0
  41. htmlgraph/collections/base.py +21 -0
  42. htmlgraph/collections/session.py +189 -0
  43. htmlgraph/collections/spike.py +7 -1
  44. htmlgraph/collections/task_delegation.py +236 -0
  45. htmlgraph/collections/traces.py +482 -0
  46. htmlgraph/config.py +113 -0
  47. htmlgraph/converter.py +41 -0
  48. htmlgraph/cost_analysis/__init__.py +5 -0
  49. htmlgraph/cost_analysis/analyzer.py +438 -0
  50. htmlgraph/dashboard.html +3315 -492
  51. htmlgraph-0.24.2.data/data/htmlgraph/dashboard.html → htmlgraph/dashboard.html.backup +2246 -248
  52. htmlgraph/dashboard.html.bak +7181 -0
  53. htmlgraph/dashboard.html.bak2 +7231 -0
  54. htmlgraph/dashboard.html.bak3 +7232 -0
  55. htmlgraph/db/__init__.py +38 -0
  56. htmlgraph/db/queries.py +790 -0
  57. htmlgraph/db/schema.py +1334 -0
  58. htmlgraph/deploy.py +26 -27
  59. htmlgraph/docs/API_REFERENCE.md +841 -0
  60. htmlgraph/docs/HTTP_API.md +750 -0
  61. htmlgraph/docs/INTEGRATION_GUIDE.md +752 -0
  62. htmlgraph/docs/ORCHESTRATION_PATTERNS.md +710 -0
  63. htmlgraph/docs/README.md +533 -0
  64. htmlgraph/docs/version_check.py +3 -1
  65. htmlgraph/error_handler.py +544 -0
  66. htmlgraph/event_log.py +2 -0
  67. htmlgraph/hooks/__init__.py +8 -0
  68. htmlgraph/hooks/bootstrap.py +169 -0
  69. htmlgraph/hooks/context.py +271 -0
  70. htmlgraph/hooks/drift_handler.py +521 -0
  71. htmlgraph/hooks/event_tracker.py +405 -15
  72. htmlgraph/hooks/post_tool_use_handler.py +257 -0
  73. htmlgraph/hooks/pretooluse.py +476 -6
  74. htmlgraph/hooks/prompt_analyzer.py +648 -0
  75. htmlgraph/hooks/session_handler.py +583 -0
  76. htmlgraph/hooks/state_manager.py +501 -0
  77. htmlgraph/hooks/subagent_stop.py +309 -0
  78. htmlgraph/hooks/task_enforcer.py +39 -0
  79. htmlgraph/models.py +111 -15
  80. htmlgraph/operations/fastapi_server.py +230 -0
  81. htmlgraph/orchestration/headless_spawner.py +22 -14
  82. htmlgraph/pydantic_models.py +476 -0
  83. htmlgraph/quality_gates.py +350 -0
  84. htmlgraph/repo_hash.py +511 -0
  85. htmlgraph/sdk.py +348 -10
  86. htmlgraph/server.py +194 -0
  87. htmlgraph/session_hooks.py +300 -0
  88. htmlgraph/session_manager.py +131 -1
  89. htmlgraph/session_registry.py +587 -0
  90. htmlgraph/session_state.py +436 -0
  91. htmlgraph/system_prompts.py +449 -0
  92. htmlgraph/templates/orchestration-view.html +350 -0
  93. htmlgraph/track_builder.py +19 -0
  94. htmlgraph/validation.py +115 -0
  95. htmlgraph-0.25.0.data/data/htmlgraph/dashboard.html +7417 -0
  96. {htmlgraph-0.24.2.dist-info → htmlgraph-0.25.0.dist-info}/METADATA +91 -64
  97. {htmlgraph-0.24.2.dist-info → htmlgraph-0.25.0.dist-info}/RECORD +103 -42
  98. {htmlgraph-0.24.2.data → htmlgraph-0.25.0.data}/data/htmlgraph/styles.css +0 -0
  99. {htmlgraph-0.24.2.data → htmlgraph-0.25.0.data}/data/htmlgraph/templates/AGENTS.md.template +0 -0
  100. {htmlgraph-0.24.2.data → htmlgraph-0.25.0.data}/data/htmlgraph/templates/CLAUDE.md.template +0 -0
  101. {htmlgraph-0.24.2.data → htmlgraph-0.25.0.data}/data/htmlgraph/templates/GEMINI.md.template +0 -0
  102. {htmlgraph-0.24.2.dist-info → htmlgraph-0.25.0.dist-info}/WHEEL +0 -0
  103. {htmlgraph-0.24.2.dist-info → htmlgraph-0.25.0.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,375 @@
1
+ <div class="spawners-view">
2
+ <h2>Spawner Activity Dashboard</h2>
3
+
4
+ <!-- Spawner Summary Cards -->
5
+ <div class="spawner-cards">
6
+ {% for spawner in spawner_stats %}
7
+ <div class="spawner-card spawner-{{ spawner.spawner_type|lower }}">
8
+ <h3>
9
+ {% if spawner.spawner_type == 'gemini' %}
10
+ Google Gemini (FREE)
11
+ {% elif spawner.spawner_type == 'codex' %}
12
+ OpenAI Codex (Paid)
13
+ {% elif spawner.spawner_type == 'copilot' %}
14
+ GitHub Copilot (Subscription)
15
+ {% else %}
16
+ {{ spawner.spawner_type|title }}
17
+ {% endif %}
18
+ </h3>
19
+ <div class="metrics">
20
+ <div class="metric">
21
+ <span class="label">Delegations</span>
22
+ <span class="value">{{ spawner.total_delegations }}</span>
23
+ </div>
24
+ <div class="metric">
25
+ <span class="label">Success Rate</span>
26
+ <span class="value">{{ spawner.success_rate or 0 }}%</span>
27
+ </div>
28
+ <div class="metric">
29
+ <span class="label">Avg Duration</span>
30
+ <span class="value">{{ spawner.avg_duration or 0 }}s</span>
31
+ </div>
32
+ <div class="metric">
33
+ <span class="label">Total Tokens</span>
34
+ <span class="value">{{ spawner.total_tokens or 0 }}</span>
35
+ </div>
36
+ <div class="metric">
37
+ <span class="label">Total Cost</span>
38
+ <span class="value">${{ spawner.total_cost or 0 }}</span>
39
+ </div>
40
+ </div>
41
+ </div>
42
+ {% endfor %}
43
+ {% if not spawner_stats %}
44
+ <div class="empty-state-card">
45
+ <p>No spawner activity yet</p>
46
+ <small>Spawner delegations will appear here as AI agents delegate work</small>
47
+ </div>
48
+ {% endif %}
49
+ </div>
50
+
51
+ <!-- Recent Spawner Activities -->
52
+ <div class="recent-activities">
53
+ <h3>Recent Spawner Activities</h3>
54
+ {% if recent_activities %}
55
+ <table class="spawner-table">
56
+ <thead>
57
+ <tr>
58
+ <th>Timestamp</th>
59
+ <th>Orchestrator</th>
60
+ <th>Spawner</th>
61
+ <th>Spawned AI</th>
62
+ <th>Task</th>
63
+ <th>Status</th>
64
+ <th>Duration</th>
65
+ <th>Tokens</th>
66
+ <th>Cost</th>
67
+ </tr>
68
+ </thead>
69
+ <tbody>
70
+ {% for activity in recent_activities %}
71
+ <tr class="activity-row spawner-{{ activity.spawner_type|lower }}">
72
+ <td class="timestamp-cell">{{ activity.timestamp }}</td>
73
+ <td class="agent-cell">{{ activity.orchestrator_agent }}</td>
74
+ <td class="spawner-cell">
75
+ <span class="spawner-badge spawner-{{ activity.spawner_type|lower }}">
76
+ {{ activity.spawner_type|upper }}
77
+ </span>
78
+ </td>
79
+ <td class="ai-badge">{{ activity.spawned_agent or 'unknown' }}</td>
80
+ <td class="task-cell" title="{{ activity.task }}">
81
+ {{ activity.task[:60] }}{% if activity.task and activity.task|length > 60 %}...{% endif %}
82
+ </td>
83
+ <td>
84
+ <span class="status-badge status-{{ activity.status }}">
85
+ {{ activity.status }}
86
+ </span>
87
+ </td>
88
+ <td class="duration-cell">{{ activity.duration or 0 }}s</td>
89
+ <td class="tokens-cell">{{ activity.tokens or 0 }}</td>
90
+ <td class="cost-cell">${{ activity.cost_usd or 0 }}</td>
91
+ </tr>
92
+ {% endfor %}
93
+ </tbody>
94
+ </table>
95
+ {% else %}
96
+ <div class="empty-state">
97
+ <p>No spawner activities recorded yet</p>
98
+ <small>Activities will appear here when agents delegate work to spawned models</small>
99
+ </div>
100
+ {% endif %}
101
+ </div>
102
+ </div>
103
+
104
+ <style>
105
+ .spawners-view {
106
+ padding: 1rem;
107
+ }
108
+
109
+ .spawner-cards {
110
+ display: grid;
111
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
112
+ gap: 1rem;
113
+ margin-bottom: 2rem;
114
+ }
115
+
116
+ .spawner-card {
117
+ padding: 1rem;
118
+ border-radius: 8px;
119
+ border: 1px solid;
120
+ }
121
+
122
+ .spawner-card.spawner-gemini {
123
+ background: #e8f5e9;
124
+ border-color: #4caf50;
125
+ color: #1b5e20;
126
+ }
127
+
128
+ .spawner-card.spawner-codex {
129
+ background: #e3f2fd;
130
+ border-color: #2196f3;
131
+ color: #0d47a1;
132
+ }
133
+
134
+ .spawner-card.spawner-copilot {
135
+ background: #f3e5f5;
136
+ border-color: #9c27b0;
137
+ color: #4a148c;
138
+ }
139
+
140
+ .spawner-card h3 {
141
+ margin: 0 0 1rem 0;
142
+ font-size: 1rem;
143
+ font-weight: 600;
144
+ }
145
+
146
+ .metrics {
147
+ display: grid;
148
+ grid-template-columns: 1fr 1fr;
149
+ gap: 0.75rem;
150
+ }
151
+
152
+ .metric {
153
+ display: flex;
154
+ flex-direction: column;
155
+ padding: 0.5rem;
156
+ background: rgba(255, 255, 255, 0.6);
157
+ border-radius: 4px;
158
+ }
159
+
160
+ .metric .label {
161
+ font-size: 0.75rem;
162
+ opacity: 0.8;
163
+ margin-bottom: 0.25rem;
164
+ }
165
+
166
+ .metric .value {
167
+ font-size: 1.25rem;
168
+ font-weight: bold;
169
+ }
170
+
171
+ .empty-state-card {
172
+ padding: 2rem;
173
+ text-align: center;
174
+ background: rgba(255, 255, 255, 0.05);
175
+ border-radius: 8px;
176
+ border: 1px dashed var(--border-subtle);
177
+ }
178
+
179
+ .empty-state-card p {
180
+ margin: 0 0 0.5rem 0;
181
+ font-weight: 500;
182
+ }
183
+
184
+ .empty-state-card small {
185
+ color: var(--text-muted);
186
+ }
187
+
188
+ .recent-activities {
189
+ margin-top: 2rem;
190
+ }
191
+
192
+ .recent-activities h3 {
193
+ margin: 0 0 1rem 0;
194
+ font-size: 1.1rem;
195
+ }
196
+
197
+ .spawner-table {
198
+ width: 100%;
199
+ border-collapse: collapse;
200
+ margin-top: 1rem;
201
+ font-size: 0.85rem;
202
+ background: var(--bg-base);
203
+ border: 1px solid var(--border-subtle);
204
+ border-radius: 4px;
205
+ overflow: hidden;
206
+ }
207
+
208
+ .spawner-table thead {
209
+ background: var(--bg-darker);
210
+ border-bottom: 1px solid var(--border-subtle);
211
+ }
212
+
213
+ .spawner-table th {
214
+ padding: 0.75rem 0.5rem;
215
+ text-align: left;
216
+ font-weight: 600;
217
+ color: var(--text-secondary);
218
+ font-size: 0.75rem;
219
+ text-transform: uppercase;
220
+ letter-spacing: 0.05em;
221
+ }
222
+
223
+ .spawner-table td {
224
+ padding: 0.75rem 0.5rem;
225
+ border-bottom: 1px solid var(--border-subtle);
226
+ }
227
+
228
+ .spawner-table tbody tr:last-child td {
229
+ border-bottom: none;
230
+ }
231
+
232
+ .activity-row.spawner-gemini {
233
+ background: rgba(76, 175, 80, 0.05);
234
+ }
235
+
236
+ .activity-row.spawner-gemini:hover {
237
+ background: rgba(76, 175, 80, 0.1);
238
+ }
239
+
240
+ .activity-row.spawner-codex {
241
+ background: rgba(33, 150, 243, 0.05);
242
+ }
243
+
244
+ .activity-row.spawner-codex:hover {
245
+ background: rgba(33, 150, 243, 0.1);
246
+ }
247
+
248
+ .activity-row.spawner-copilot {
249
+ background: rgba(156, 39, 176, 0.05);
250
+ }
251
+
252
+ .activity-row.spawner-copilot:hover {
253
+ background: rgba(156, 39, 176, 0.1);
254
+ }
255
+
256
+ .timestamp-cell {
257
+ font-family: 'JetBrains Mono', 'SF Mono', 'Monaco', monospace;
258
+ font-size: 0.75rem;
259
+ color: var(--text-muted);
260
+ white-space: nowrap;
261
+ }
262
+
263
+ .agent-cell {
264
+ font-weight: 500;
265
+ }
266
+
267
+ .spawner-cell {
268
+ text-align: center;
269
+ }
270
+
271
+ .ai-badge {
272
+ font-family: 'JetBrains Mono', 'SF Mono', 'Monaco', monospace;
273
+ font-size: 0.75rem;
274
+ background: rgba(255, 255, 255, 0.05);
275
+ padding: 0.25rem 0.4rem;
276
+ border-radius: 3px;
277
+ white-space: nowrap;
278
+ }
279
+
280
+ .task-cell {
281
+ max-width: 200px;
282
+ overflow: hidden;
283
+ text-overflow: ellipsis;
284
+ white-space: nowrap;
285
+ color: var(--text-secondary);
286
+ }
287
+
288
+ .status-badge {
289
+ display: inline-block;
290
+ padding: 0.25rem 0.5rem;
291
+ border-radius: 3px;
292
+ font-size: 0.7rem;
293
+ font-weight: 600;
294
+ text-transform: uppercase;
295
+ letter-spacing: 0.05em;
296
+ white-space: nowrap;
297
+ }
298
+
299
+ .status-badge.status-completed,
300
+ .status-badge.status-success {
301
+ background: rgba(34, 197, 94, 0.2);
302
+ color: #22c55e;
303
+ }
304
+
305
+ .status-badge.status-failed,
306
+ .status-badge.status-error {
307
+ background: rgba(239, 68, 68, 0.2);
308
+ color: #ef4444;
309
+ }
310
+
311
+ .status-badge.status-pending {
312
+ background: rgba(100, 200, 255, 0.2);
313
+ color: #64c8ff;
314
+ }
315
+
316
+ .status-badge.status-in_progress {
317
+ background: rgba(251, 191, 36, 0.2);
318
+ color: #fbbf24;
319
+ }
320
+
321
+ .duration-cell {
322
+ text-align: right;
323
+ font-family: 'JetBrains Mono', 'SF Mono', 'Monaco', monospace;
324
+ }
325
+
326
+ .tokens-cell {
327
+ text-align: right;
328
+ font-family: 'JetBrains Mono', 'SF Mono', 'Monaco', monospace;
329
+ }
330
+
331
+ .cost-cell {
332
+ text-align: right;
333
+ font-family: 'JetBrains Mono', 'SF Mono', 'Monaco', monospace;
334
+ font-weight: 600;
335
+ }
336
+
337
+ .empty-state {
338
+ padding: 2rem;
339
+ text-align: center;
340
+ color: var(--text-muted);
341
+ background: rgba(255, 255, 255, 0.03);
342
+ border-radius: 4px;
343
+ border: 1px dashed var(--border-subtle);
344
+ }
345
+
346
+ .empty-state p {
347
+ margin: 0 0 0.5rem 0;
348
+ }
349
+
350
+ /* Responsive adjustments */
351
+ @media (max-width: 1200px) {
352
+ .spawner-table {
353
+ font-size: 0.75rem;
354
+ }
355
+
356
+ .spawner-table th,
357
+ .spawner-table td {
358
+ padding: 0.5rem 0.35rem;
359
+ }
360
+
361
+ .task-cell {
362
+ max-width: 150px;
363
+ }
364
+ }
365
+
366
+ @media (max-width: 900px) {
367
+ .metrics {
368
+ grid-template-columns: 1fr;
369
+ }
370
+
371
+ .spawner-cards {
372
+ grid-template-columns: 1fr;
373
+ }
374
+ }
375
+ </style>