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,326 @@
1
+ <div class="view-container activity-feed-view">
2
+ <div class="view-header">
3
+ <h2>Agent Activity Feed</h2>
4
+ <div class="view-info">
5
+ <small>Table view of all agent activity - most recent events at top</small>
6
+ </div>
7
+ <div class="view-filters">
8
+ <input type="text"
9
+ class="filter-input"
10
+ placeholder="Filter by agent..."
11
+ hx-get="/views/activity-feed"
12
+ hx-target="#content-area"
13
+ hx-trigger="input changed delay:500ms"
14
+ name="agent_id">
15
+ </div>
16
+ </div>
17
+
18
+ <div class="activity-list table-view">
19
+ {% if hierarchical_events %}
20
+ <table class="activity-table">
21
+ <thead>
22
+ <tr>
23
+ <th class="col-agent">Agent</th>
24
+ <th class="col-tool">Tool</th>
25
+ <th class="col-input">Input</th>
26
+ <th class="col-output">Output</th>
27
+ <th class="col-status">Status</th>
28
+ <th class="col-timestamp">Timestamp</th>
29
+ </tr>
30
+ </thead>
31
+ <tbody>
32
+ {% for group in hierarchical_events %}
33
+ <!-- Parent Event -->
34
+ <tr class="activity-row parent-row event-{{ group.parent.status }} {% if group.has_children %}has-children{% endif %}"
35
+ data-event-id="{{ group.parent.event_id }}"
36
+ {% if group.has_children %}onclick="toggleChildren(this)"{% endif %}
37
+ style="border-left: 4px solid var(--accent);">
38
+ <td class="col-agent">
39
+ {% if group.has_children %}
40
+ <span class="expand-icon">&#9654;</span>
41
+ {% endif %}
42
+ <span class="agent-badge agent-{{ group.parent.agent_id|lower }}">{{ group.parent.agent_id }}</span>
43
+ {% if group.has_children %}
44
+ <span class="child-count" title="{{ group.children|length }} child event(s)">({{ group.children|length }})</span>
45
+ {% endif %}
46
+ </td>
47
+ <td class="col-tool">
48
+ <span class="event-type-badge" title="{{ group.parent.event_type }}">
49
+ {% if group.parent.event_type == 'delegation' %}
50
+ &#128279;
51
+ {% elif group.parent.event_type == 'tool_call' %}
52
+ &#128296;
53
+ {% elif group.parent.event_type == 'completion' %}
54
+ &#127881;
55
+ {% else %}
56
+ &#128203;
57
+ {% endif %}
58
+ </span>
59
+ {% if group.parent.tool_name %}
60
+ <code class="tool-name">{{ group.parent.tool_name }}</code>
61
+ {% else %}
62
+ <span class="text-muted">-</span>
63
+ {% endif %}
64
+ </td>
65
+ <td class="col-input">
66
+ {% if group.parent.input_summary %}
67
+ <span class="truncate" title="{{ group.parent.input_summary }}">{{ group.parent.input_summary[:150] }}{% if group.parent.input_summary|length > 150 %}...{% endif %}</span>
68
+ {% else %}
69
+ <span class="text-muted">-</span>
70
+ {% endif %}
71
+ </td>
72
+ <td class="col-output">
73
+ {% if group.parent.output_summary %}
74
+ <span class="truncate" title="{{ group.parent.output_summary }}">{{ group.parent.output_summary[:150] }}{% if group.parent.output_summary|length > 150 %}...{% endif %}</span>
75
+ {% else %}
76
+ <span class="text-muted">-</span>
77
+ {% endif %}
78
+
79
+ {% if group.parent.cost_tokens or group.parent.execution_duration_seconds %}
80
+ <div class="event-metrics">
81
+ {% if group.parent.cost_tokens %}
82
+ <span class="metric-item">{{ group.parent.cost_tokens }} tokens</span>
83
+ {% endif %}
84
+ {% if group.parent.execution_duration_seconds %}
85
+ <span class="metric-item">{{ "%.2f"|format(group.parent.execution_duration_seconds) }}s</span>
86
+ {% endif %}
87
+ </div>
88
+ {% endif %}
89
+ </td>
90
+ <td class="col-status">
91
+ <span class="status-badge status-{{ group.parent.status }}">{{ group.parent.status }}</span>
92
+ </td>
93
+ <td class="col-timestamp">
94
+ <span class="timestamp-text" data-utc-time="{{ group.parent.timestamp }}">{{ group.parent.timestamp }}</span>
95
+ </td>
96
+ </tr>
97
+
98
+ <!-- Child Events (Sub-traces) - Hidden by default -->
99
+ {% if group.has_children %}
100
+ {% for child in group.children %}
101
+ <tr class="activity-row child-row event-{{ child.status }} hidden"
102
+ data-event-id="{{ child.event_id }}"
103
+ data-parent="{{ group.parent.event_id }}">
104
+ <td class="col-agent">
105
+ <span class="child-indicator">&#8627;</span>
106
+ <span class="agent-badge agent-{{ child.agent_id|lower }}">{{ child.agent_id }}</span>
107
+ </td>
108
+ <td class="col-tool">
109
+ <span class="event-type-badge" title="{{ child.event_type }}">
110
+ {% if child.event_type == 'tool_call' %}
111
+ &#128296;
112
+ {% elif child.event_type == 'tool_result' %}
113
+ &#9989;
114
+ {% elif child.event_type == 'error' %}
115
+ &#10060;
116
+ {% elif child.event_type == 'delegation' %}
117
+ &#128279;
118
+ {% elif child.event_type == 'completion' %}
119
+ &#127881;
120
+ {% else %}
121
+ &#128204;
122
+ {% endif %}
123
+ </span>
124
+ {% if child.tool_name %}
125
+ <code class="tool-name">{{ child.tool_name }}</code>
126
+ {% else %}
127
+ <span class="text-muted">-</span>
128
+ {% endif %}
129
+ </td>
130
+ <td class="col-input">
131
+ {% if child.input_summary %}
132
+ <span class="truncate" title="{{ child.input_summary }}">{{ child.input_summary[:150] }}{% if child.input_summary|length > 150 %}...{% endif %}</span>
133
+ {% else %}
134
+ <span class="text-muted">-</span>
135
+ {% endif %}
136
+ </td>
137
+ <td class="col-output">
138
+ {% if child.output_summary %}
139
+ <span class="truncate" title="{{ child.output_summary }}">{{ child.output_summary[:150] }}{% if child.output_summary|length > 150 %}...{% endif %}</span>
140
+ {% else %}
141
+ <span class="text-muted">-</span>
142
+ {% endif %}
143
+
144
+ {% if child.cost_tokens or child.execution_duration_seconds %}
145
+ <div class="event-metrics">
146
+ {% if child.cost_tokens %}
147
+ <span class="metric-item">{{ child.cost_tokens }} tokens</span>
148
+ {% endif %}
149
+ {% if child.execution_duration_seconds %}
150
+ <span class="metric-item">{{ "%.2f"|format(child.execution_duration_seconds) }}s</span>
151
+ {% endif %}
152
+ </div>
153
+ {% endif %}
154
+ </td>
155
+ <td class="col-status">
156
+ <span class="status-badge status-{{ child.status }}">{{ child.status }}</span>
157
+ </td>
158
+ <td class="col-timestamp">
159
+ <span class="timestamp-text" data-utc-time="{{ child.timestamp }}">{{ child.timestamp }}</span>
160
+ </td>
161
+ </tr>
162
+ {% endfor %}
163
+ {% endif %}
164
+ {% endfor %}
165
+ </tbody>
166
+ </table>
167
+ {% else %}
168
+ <div class="empty-state">
169
+ <p>No events found</p>
170
+ <small>Agent activity will appear here as tasks are executed</small>
171
+ </div>
172
+ {% endif %}
173
+ </div>
174
+
175
+ <!-- Auto-refresh indicator -->
176
+ <div class="auto-refresh-indicator">
177
+ <span class="refresh-dot"></span>
178
+ Live updates enabled (via WebSocket)
179
+ </div>
180
+ </div>
181
+
182
+ <style>
183
+ /* Activity Feed Column Widths - Redesigned */
184
+ .activity-table {
185
+ width: 100%;
186
+ border-collapse: separate;
187
+ border-spacing: 0;
188
+ table-layout: fixed;
189
+ }
190
+
191
+ .activity-table .col-agent { width: 120px; }
192
+ .activity-table .col-tool { width: 100px; }
193
+ .activity-table .col-input { width: auto; }
194
+ .activity-table .col-output { width: auto; }
195
+ .activity-table .col-status { width: 100px; }
196
+ .activity-table .col-timestamp { width: 140px; }
197
+
198
+ /* Make input/output columns flexible and wide */
199
+ .activity-table td.col-input,
200
+ .activity-table td.col-output {
201
+ max-width: 0;
202
+ overflow: hidden;
203
+ text-overflow: ellipsis;
204
+ }
205
+
206
+ .activity-table .truncate {
207
+ display: block;
208
+ overflow: hidden;
209
+ text-overflow: ellipsis;
210
+ white-space: nowrap;
211
+ max-width: 100%;
212
+ }
213
+
214
+ /* Expandable Tracing Structure */
215
+ .expand-icon {
216
+ cursor: pointer;
217
+ display: inline-block;
218
+ margin-right: 0.5rem;
219
+ transition: transform 0.2s ease;
220
+ font-size: 0.7rem;
221
+ color: var(--text-muted);
222
+ }
223
+
224
+ .expand-icon.expanded {
225
+ transform: rotate(90deg);
226
+ }
227
+
228
+ .parent-row.has-children {
229
+ cursor: pointer;
230
+ }
231
+
232
+ .parent-row.has-children:hover {
233
+ background: var(--bg-hover);
234
+ }
235
+
236
+ .child-count {
237
+ font-size: 0.75rem;
238
+ color: var(--text-muted);
239
+ margin-left: 0.5rem;
240
+ }
241
+
242
+ .child-row {
243
+ background: rgba(0, 0, 0, 0.3);
244
+ border-left: 4px solid var(--text-muted) !important;
245
+ }
246
+
247
+ .child-row.hidden {
248
+ display: none;
249
+ }
250
+
251
+ .child-indicator {
252
+ color: var(--text-muted);
253
+ margin-right: 0.5rem;
254
+ font-size: 1rem;
255
+ }
256
+
257
+ /* Event Metrics styling */
258
+ .event-metrics {
259
+ font-size: 0.65rem;
260
+ color: var(--text-muted);
261
+ margin-top: 0.25rem;
262
+ }
263
+
264
+ .event-metrics .metric-item {
265
+ margin-right: 0.5rem;
266
+ }
267
+
268
+ /* Responsive adjustments */
269
+ @media (max-width: 1200px) {
270
+ .activity-table .col-agent { width: 100px; }
271
+ .activity-table .col-tool { width: 90px; }
272
+ .activity-table .col-status { width: 90px; }
273
+ .activity-table .col-timestamp { width: 120px; }
274
+ }
275
+
276
+ @media (max-width: 900px) {
277
+ .activity-table .col-agent { width: 80px; }
278
+ .activity-table .col-tool { width: 80px; }
279
+ .activity-table .col-status { width: 80px; }
280
+ .activity-table .col-timestamp { width: 100px; }
281
+ }
282
+ </style>
283
+
284
+ <script>
285
+ // Toggle child rows visibility
286
+ function toggleChildren(parentRow) {
287
+ const eventId = parentRow.dataset.eventId;
288
+ const children = document.querySelectorAll(`[data-parent="${eventId}"]`);
289
+ const expandIcon = parentRow.querySelector('.expand-icon');
290
+
291
+ children.forEach(child => {
292
+ child.classList.toggle('hidden');
293
+ });
294
+
295
+ if (expandIcon) {
296
+ expandIcon.classList.toggle('expanded');
297
+ }
298
+ }
299
+
300
+ // Expand all parent rows
301
+ function expandAll() {
302
+ document.querySelectorAll('.parent-row.has-children').forEach(row => {
303
+ const eventId = row.dataset.eventId;
304
+ const children = document.querySelectorAll(`[data-parent="${eventId}"]`);
305
+ const expandIcon = row.querySelector('.expand-icon');
306
+
307
+ children.forEach(child => {
308
+ child.classList.remove('hidden');
309
+ });
310
+
311
+ if (expandIcon) {
312
+ expandIcon.classList.add('expanded');
313
+ }
314
+ });
315
+ }
316
+
317
+ // Collapse all parent rows
318
+ function collapseAll() {
319
+ document.querySelectorAll('.child-row').forEach(child => {
320
+ child.classList.add('hidden');
321
+ });
322
+ document.querySelectorAll('.expand-icon').forEach(icon => {
323
+ icon.classList.remove('expanded');
324
+ });
325
+ }
326
+ </script>