htmlgraph 0.26.5__py3-none-any.whl → 0.26.6__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.
- htmlgraph/.htmlgraph/.session-warning-state.json +1 -1
- htmlgraph/__init__.py +1 -1
- htmlgraph/api/main.py +50 -10
- htmlgraph/api/templates/dashboard-redesign.html +608 -54
- htmlgraph/api/templates/partials/activity-feed.html +21 -0
- htmlgraph/api/templates/partials/features.html +81 -12
- htmlgraph/api/templates/partials/orchestration.html +35 -0
- htmlgraph/cli/.htmlgraph/.session-warning-state.json +6 -0
- htmlgraph/cli/.htmlgraph/agents.json +72 -0
- htmlgraph/cli/__init__.py +42 -0
- htmlgraph/cli/__main__.py +6 -0
- htmlgraph/cli/analytics.py +939 -0
- htmlgraph/cli/base.py +660 -0
- htmlgraph/cli/constants.py +206 -0
- htmlgraph/cli/core.py +856 -0
- htmlgraph/cli/main.py +143 -0
- htmlgraph/cli/models.py +462 -0
- htmlgraph/cli/templates/__init__.py +1 -0
- htmlgraph/cli/templates/cost_dashboard.py +398 -0
- htmlgraph/cli/work/__init__.py +159 -0
- htmlgraph/cli/work/features.py +567 -0
- htmlgraph/cli/work/orchestration.py +675 -0
- htmlgraph/cli/work/sessions.py +465 -0
- htmlgraph/cli/work/tracks.py +485 -0
- htmlgraph/dashboard.html +6414 -634
- htmlgraph/db/schema.py +8 -3
- htmlgraph/docs/ORCHESTRATION_PATTERNS.md +20 -13
- htmlgraph/docs/README.md +2 -3
- htmlgraph/hooks/event_tracker.py +157 -25
- htmlgraph/hooks/git_commands.py +175 -0
- htmlgraph/hooks/orchestrator.py +137 -71
- htmlgraph/hooks/orchestrator_reflector.py +23 -0
- htmlgraph/hooks/pretooluse.py +29 -6
- htmlgraph/hooks/session_handler.py +28 -0
- htmlgraph/hooks/session_summary.py +391 -0
- htmlgraph/hooks/subagent_detection.py +202 -0
- htmlgraph/hooks/validator.py +192 -79
- htmlgraph/operations/__init__.py +18 -0
- htmlgraph/operations/initialization.py +596 -0
- htmlgraph/operations/initialization.py.backup +228 -0
- htmlgraph/orchestration/__init__.py +16 -1
- htmlgraph/orchestration/claude_launcher.py +185 -0
- htmlgraph/orchestration/command_builder.py +71 -0
- htmlgraph/orchestration/headless_spawner.py +72 -1332
- htmlgraph/orchestration/plugin_manager.py +136 -0
- htmlgraph/orchestration/prompts.py +137 -0
- htmlgraph/orchestration/spawners/__init__.py +16 -0
- htmlgraph/orchestration/spawners/base.py +194 -0
- htmlgraph/orchestration/spawners/claude.py +170 -0
- htmlgraph/orchestration/spawners/codex.py +442 -0
- htmlgraph/orchestration/spawners/copilot.py +299 -0
- htmlgraph/orchestration/spawners/gemini.py +478 -0
- htmlgraph/orchestration/subprocess_runner.py +33 -0
- htmlgraph/orchestration.md +563 -0
- htmlgraph/orchestrator-system-prompt-optimized.txt +620 -55
- htmlgraph/orchestrator_config.py +357 -0
- htmlgraph/orchestrator_mode.py +45 -12
- htmlgraph/transcript.py +16 -4
- htmlgraph-0.26.6.data/data/htmlgraph/dashboard.html +6592 -0
- {htmlgraph-0.26.5.dist-info → htmlgraph-0.26.6.dist-info}/METADATA +1 -1
- {htmlgraph-0.26.5.dist-info → htmlgraph-0.26.6.dist-info}/RECORD +67 -33
- {htmlgraph-0.26.5.dist-info → htmlgraph-0.26.6.dist-info}/entry_points.txt +1 -1
- htmlgraph/cli.py +0 -7256
- htmlgraph-0.26.5.data/data/htmlgraph/dashboard.html +0 -812
- {htmlgraph-0.26.5.data → htmlgraph-0.26.6.data}/data/htmlgraph/styles.css +0 -0
- {htmlgraph-0.26.5.data → htmlgraph-0.26.6.data}/data/htmlgraph/templates/AGENTS.md.template +0 -0
- {htmlgraph-0.26.5.data → htmlgraph-0.26.6.data}/data/htmlgraph/templates/CLAUDE.md.template +0 -0
- {htmlgraph-0.26.5.data → htmlgraph-0.26.6.data}/data/htmlgraph/templates/GEMINI.md.template +0 -0
- {htmlgraph-0.26.5.dist-info → htmlgraph-0.26.6.dist-info}/WHEEL +0 -0
htmlgraph/__init__.py
CHANGED
htmlgraph/api/main.py
CHANGED
|
@@ -87,6 +87,7 @@ class EventModel(BaseModel):
|
|
|
87
87
|
input_summary: str | None = None
|
|
88
88
|
output_summary: str | None = None
|
|
89
89
|
session_id: str
|
|
90
|
+
feature_id: str | None = None
|
|
90
91
|
parent_event_id: str | None = None
|
|
91
92
|
status: str
|
|
92
93
|
model: str | None = None
|
|
@@ -394,7 +395,7 @@ def get_app(db_path: str) -> FastAPI:
|
|
|
394
395
|
query = """
|
|
395
396
|
SELECT e.event_id, e.agent_id, e.event_type, e.timestamp, e.tool_name,
|
|
396
397
|
e.input_summary, e.output_summary, e.session_id,
|
|
397
|
-
e.parent_event_id, e.status, e.model
|
|
398
|
+
e.parent_event_id, e.status, e.model, e.feature_id
|
|
398
399
|
FROM agent_events e
|
|
399
400
|
WHERE 1=1
|
|
400
401
|
"""
|
|
@@ -431,6 +432,7 @@ def get_app(db_path: str) -> FastAPI:
|
|
|
431
432
|
parent_event_id=row[8],
|
|
432
433
|
status=row[9],
|
|
433
434
|
model=row[10],
|
|
435
|
+
feature_id=row[11],
|
|
434
436
|
)
|
|
435
437
|
for row in rows
|
|
436
438
|
]
|
|
@@ -769,7 +771,8 @@ def get_app(db_path: str) -> FastAPI:
|
|
|
769
771
|
session_id,
|
|
770
772
|
status,
|
|
771
773
|
model,
|
|
772
|
-
parent_event_id
|
|
774
|
+
parent_event_id,
|
|
775
|
+
feature_id
|
|
773
776
|
FROM agent_events
|
|
774
777
|
WHERE event_type IN ({event_type_placeholders})
|
|
775
778
|
"""
|
|
@@ -801,6 +804,7 @@ def get_app(db_path: str) -> FastAPI:
|
|
|
801
804
|
"status": row[9],
|
|
802
805
|
"model": row[10],
|
|
803
806
|
"parent_event_id": row[11],
|
|
807
|
+
"feature_id": row[12],
|
|
804
808
|
}
|
|
805
809
|
)
|
|
806
810
|
|
|
@@ -1022,7 +1026,8 @@ def get_app(db_path: str) -> FastAPI:
|
|
|
1022
1026
|
agent_id,
|
|
1023
1027
|
model,
|
|
1024
1028
|
context,
|
|
1025
|
-
subagent_type
|
|
1029
|
+
subagent_type,
|
|
1030
|
+
feature_id
|
|
1026
1031
|
FROM agent_events
|
|
1027
1032
|
WHERE parent_event_id = ?
|
|
1028
1033
|
ORDER BY timestamp ASC
|
|
@@ -1055,6 +1060,7 @@ def get_app(db_path: str) -> FastAPI:
|
|
|
1055
1060
|
model = row[7]
|
|
1056
1061
|
context_json = row[8]
|
|
1057
1062
|
subagent_type = row[9]
|
|
1063
|
+
feature_id = row[10]
|
|
1058
1064
|
|
|
1059
1065
|
# Parse context to extract spawner metadata
|
|
1060
1066
|
context = {}
|
|
@@ -1103,6 +1109,7 @@ def get_app(db_path: str) -> FastAPI:
|
|
|
1103
1109
|
"agent": agent,
|
|
1104
1110
|
"depth": depth,
|
|
1105
1111
|
"model": model,
|
|
1112
|
+
"feature_id": feature_id,
|
|
1106
1113
|
}
|
|
1107
1114
|
|
|
1108
1115
|
# Include spawner metadata if present
|
|
@@ -1689,7 +1696,7 @@ def get_app(db_path: str) -> FastAPI:
|
|
|
1689
1696
|
# OPTIMIZATION: Use composite index idx_features_status_priority
|
|
1690
1697
|
# for efficient filtering and ordering
|
|
1691
1698
|
query = """
|
|
1692
|
-
SELECT id, type, title, status, priority, assigned_to, created_at, updated_at
|
|
1699
|
+
SELECT id, type, title, status, priority, assigned_to, created_at, updated_at, description
|
|
1693
1700
|
FROM features
|
|
1694
1701
|
WHERE 1=1
|
|
1695
1702
|
"""
|
|
@@ -1699,18 +1706,38 @@ def get_app(db_path: str) -> FastAPI:
|
|
|
1699
1706
|
query += " AND status = ?"
|
|
1700
1707
|
params.append(status)
|
|
1701
1708
|
|
|
1702
|
-
query += " ORDER BY priority DESC, created_at DESC LIMIT
|
|
1709
|
+
query += " ORDER BY priority DESC, created_at DESC LIMIT 1000"
|
|
1703
1710
|
|
|
1704
1711
|
exec_start = time.time()
|
|
1705
1712
|
cursor = await db.execute(query, params)
|
|
1706
1713
|
rows = await cursor.fetchall()
|
|
1714
|
+
|
|
1715
|
+
# Query all unique agents per feature for attribution chain
|
|
1716
|
+
# This only works for events that have feature_id populated
|
|
1717
|
+
agents_query = """
|
|
1718
|
+
SELECT feature_id, agent_id
|
|
1719
|
+
FROM agent_events
|
|
1720
|
+
WHERE feature_id IS NOT NULL
|
|
1721
|
+
GROUP BY feature_id, agent_id
|
|
1722
|
+
"""
|
|
1723
|
+
agents_cursor = await db.execute(agents_query)
|
|
1724
|
+
agents_rows = await agents_cursor.fetchall()
|
|
1725
|
+
|
|
1726
|
+
feature_agents: dict[str, list[str]] = {}
|
|
1727
|
+
for row in agents_rows:
|
|
1728
|
+
fid, aid = row[0], row[1]
|
|
1729
|
+
if fid not in feature_agents:
|
|
1730
|
+
feature_agents[fid] = []
|
|
1731
|
+
feature_agents[fid].append(aid)
|
|
1732
|
+
|
|
1707
1733
|
exec_time_ms = (time.time() - exec_start) * 1000
|
|
1708
1734
|
|
|
1709
1735
|
for row in rows:
|
|
1736
|
+
feature_id = row[0]
|
|
1710
1737
|
feature_status = row[3]
|
|
1711
1738
|
features_by_status.setdefault(feature_status, []).append(
|
|
1712
1739
|
{
|
|
1713
|
-
"id":
|
|
1740
|
+
"id": feature_id,
|
|
1714
1741
|
"type": row[1],
|
|
1715
1742
|
"title": row[2],
|
|
1716
1743
|
"status": feature_status,
|
|
@@ -1718,6 +1745,8 @@ def get_app(db_path: str) -> FastAPI:
|
|
|
1718
1745
|
"assigned_to": row[5],
|
|
1719
1746
|
"created_at": row[6],
|
|
1720
1747
|
"updated_at": row[7],
|
|
1748
|
+
"description": row[8],
|
|
1749
|
+
"contributors": feature_agents.get(feature_id, []),
|
|
1721
1750
|
}
|
|
1722
1751
|
)
|
|
1723
1752
|
|
|
@@ -2162,7 +2191,9 @@ def get_app(db_path: str) -> FastAPI:
|
|
|
2162
2191
|
# Only fetch events AFTER last_timestamp to stream new events only
|
|
2163
2192
|
query = """
|
|
2164
2193
|
SELECT event_id, agent_id, event_type, timestamp, tool_name,
|
|
2165
|
-
input_summary, output_summary, session_id, status, model
|
|
2194
|
+
input_summary, output_summary, session_id, status, model,
|
|
2195
|
+
parent_event_id, execution_duration_seconds, context,
|
|
2196
|
+
cost_tokens
|
|
2166
2197
|
FROM agent_events
|
|
2167
2198
|
WHERE timestamp > ?
|
|
2168
2199
|
ORDER BY timestamp ASC
|
|
@@ -2180,6 +2211,14 @@ def get_app(db_path: str) -> FastAPI:
|
|
|
2180
2211
|
|
|
2181
2212
|
# Send events in order (no need to reverse with ASC)
|
|
2182
2213
|
for row in rows_list:
|
|
2214
|
+
# Parse context JSON if present
|
|
2215
|
+
context_data = {}
|
|
2216
|
+
if row[12]: # context column
|
|
2217
|
+
try:
|
|
2218
|
+
context_data = json.loads(row[12])
|
|
2219
|
+
except (json.JSONDecodeError, TypeError):
|
|
2220
|
+
pass
|
|
2221
|
+
|
|
2183
2222
|
event_data = {
|
|
2184
2223
|
"type": "event",
|
|
2185
2224
|
"event_id": row[0],
|
|
@@ -2192,9 +2231,10 @@ def get_app(db_path: str) -> FastAPI:
|
|
|
2192
2231
|
"session_id": row[7],
|
|
2193
2232
|
"status": row[8],
|
|
2194
2233
|
"model": row[9],
|
|
2195
|
-
"parent_event_id":
|
|
2196
|
-
"
|
|
2197
|
-
"
|
|
2234
|
+
"parent_event_id": row[10],
|
|
2235
|
+
"execution_duration_seconds": row[11] or 0.0,
|
|
2236
|
+
"cost_tokens": row[13] or 0,
|
|
2237
|
+
"context": context_data,
|
|
2198
2238
|
}
|
|
2199
2239
|
await websocket.send_json(event_data)
|
|
2200
2240
|
|