htmlgraph 0.26.14__py3-none-any.whl → 0.26.15__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/__init__.py CHANGED
@@ -95,7 +95,7 @@ from htmlgraph.types import (
95
95
  )
96
96
  from htmlgraph.work_type_utils import infer_work_type, infer_work_type_from_id
97
97
 
98
- __version__ = "0.26.14"
98
+ __version__ = "0.26.15"
99
99
  __all__ = [
100
100
  # Exceptions
101
101
  "HtmlGraphError",
@@ -2,5 +2,5 @@
2
2
  "dismissed_at": null,
3
3
  "dismissed_by": null,
4
4
  "session_id": null,
5
- "show_count": 471
5
+ "show_count": 485
6
6
  }
Binary file
htmlgraph/db/schema.py CHANGED
@@ -105,6 +105,7 @@ class HtmlGraphDB:
105
105
  ("created_at", "DATETIME DEFAULT CURRENT_TIMESTAMP"),
106
106
  ("updated_at", "DATETIME DEFAULT CURRENT_TIMESTAMP"),
107
107
  ("model", "TEXT"),
108
+ ("claude_task_id", "TEXT"),
108
109
  ]
109
110
 
110
111
  for col_name, col_type in migrations:
@@ -226,6 +227,7 @@ class HtmlGraphDB:
226
227
  execution_duration_seconds REAL DEFAULT 0.0,
227
228
  status TEXT DEFAULT 'recorded',
228
229
  model TEXT,
230
+ claude_task_id TEXT,
229
231
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
230
232
  updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
231
233
  FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE ON UPDATE CASCADE,
@@ -443,6 +445,8 @@ class HtmlGraphDB:
443
445
  "CREATE INDEX IF NOT EXISTS idx_agent_events_session_tool ON agent_events(session_id, tool_name)",
444
446
  # Pattern: Timestamp range queries
445
447
  "CREATE INDEX IF NOT EXISTS idx_agent_events_timestamp ON agent_events(timestamp DESC)",
448
+ # Pattern: WHERE claude_task_id (task attribution queries)
449
+ "CREATE INDEX IF NOT EXISTS idx_agent_events_claude_task_id ON agent_events(claude_task_id)",
446
450
  # features indexes - optimized for kanban/filtering
447
451
  # Pattern: WHERE status ORDER BY priority DESC (feature list views)
448
452
  "CREATE INDEX IF NOT EXISTS idx_features_status_priority ON features(status, priority DESC, created_at DESC)",
@@ -517,6 +521,7 @@ class HtmlGraphDB:
517
521
  subagent_type: str | None = None,
518
522
  model: str | None = None,
519
523
  feature_id: str | None = None,
524
+ claude_task_id: str | None = None,
520
525
  ) -> bool:
521
526
  """
522
527
  Insert an agent event into the database.
@@ -541,6 +546,7 @@ class HtmlGraphDB:
541
546
  execution_duration_seconds: Execution time in seconds (optional)
542
547
  subagent_type: Subagent type for Task delegations (optional)
543
548
  model: Claude model name (e.g., claude-haiku, claude-opus, claude-sonnet) (optional)
549
+ claude_task_id: Claude Code's internal task ID for tool attribution (optional)
544
550
 
545
551
  Returns:
546
552
  True if insert successful, False otherwise
@@ -559,8 +565,8 @@ class HtmlGraphDB:
559
565
  INSERT INTO agent_events
560
566
  (event_id, agent_id, event_type, session_id, feature_id, tool_name,
561
567
  input_summary, output_summary, context, parent_agent_id,
562
- parent_event_id, cost_tokens, execution_duration_seconds, subagent_type, model)
563
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
568
+ parent_event_id, cost_tokens, execution_duration_seconds, subagent_type, model, claude_task_id)
569
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
564
570
  """,
565
571
  (
566
572
  event_id,
@@ -578,6 +584,7 @@ class HtmlGraphDB:
578
584
  execution_duration_seconds,
579
585
  subagent_type,
580
586
  model,
587
+ claude_task_id,
581
588
  ),
582
589
  )
583
590
  # Re-enable foreign key constraints
@@ -1583,6 +1590,105 @@ class HtmlGraphDB:
1583
1590
  logger.error(f"Error cleaning up old live events: {e}")
1584
1591
  return 0
1585
1592
 
1593
+ def get_events_for_task(self, claude_task_id: str) -> list[dict[str, Any]]:
1594
+ """
1595
+ Get all events (and their descendants) for a Claude Code task.
1596
+
1597
+ This enables answering "show me all the work (tool calls) that happened
1598
+ when this Task() was delegated".
1599
+
1600
+ Args:
1601
+ claude_task_id: Claude Code's internal task ID
1602
+
1603
+ Returns:
1604
+ List of event dictionaries, ordered by timestamp
1605
+ """
1606
+ if not self.connection:
1607
+ self.connect()
1608
+
1609
+ try:
1610
+ cursor = self.connection.cursor() # type: ignore[union-attr]
1611
+ cursor.execute(
1612
+ """
1613
+ WITH task_events AS (
1614
+ SELECT event_id FROM agent_events
1615
+ WHERE claude_task_id = ?
1616
+ )
1617
+ SELECT ae.* FROM agent_events ae
1618
+ WHERE ae.claude_task_id = ?
1619
+ OR ae.parent_event_id IN (
1620
+ SELECT event_id FROM task_events
1621
+ )
1622
+ ORDER BY ae.created_at
1623
+ """,
1624
+ (claude_task_id, claude_task_id),
1625
+ )
1626
+
1627
+ rows = cursor.fetchall()
1628
+ return [dict(row) for row in rows]
1629
+ except sqlite3.Error as e:
1630
+ logger.error(f"Error querying events for task: {e}")
1631
+ return []
1632
+
1633
+ def get_subagent_work(self, session_id: str) -> dict[str, list[dict[str, Any]]]:
1634
+ """
1635
+ Get all work grouped by which subagent did it.
1636
+
1637
+ This enables answering "which subagent did what work in this session?"
1638
+
1639
+ Args:
1640
+ session_id: Session ID to analyze
1641
+
1642
+ Returns:
1643
+ Dictionary mapping subagent_type to list of events they executed.
1644
+ Example: {
1645
+ 'researcher': [
1646
+ {'tool_name': 'Read', 'input_summary': '...', ...},
1647
+ {'tool_name': 'Grep', 'input_summary': '...', ...}
1648
+ ],
1649
+ 'general-purpose': [
1650
+ {'tool_name': 'Bash', 'input_summary': '...', ...}
1651
+ ]
1652
+ }
1653
+ """
1654
+ if not self.connection:
1655
+ self.connect()
1656
+
1657
+ try:
1658
+ cursor = self.connection.cursor() # type: ignore[union-attr]
1659
+ cursor.execute(
1660
+ """
1661
+ SELECT
1662
+ ae.subagent_type,
1663
+ ae.tool_name,
1664
+ ae.event_id,
1665
+ ae.input_summary,
1666
+ ae.output_summary,
1667
+ ae.created_at,
1668
+ ae.claude_task_id
1669
+ FROM agent_events ae
1670
+ WHERE ae.session_id = ?
1671
+ AND ae.subagent_type IS NOT NULL
1672
+ AND ae.event_type = 'tool_call'
1673
+ ORDER BY ae.subagent_type, ae.created_at
1674
+ """,
1675
+ (session_id,),
1676
+ )
1677
+
1678
+ # Group by subagent_type
1679
+ result: dict[str, list[dict[str, Any]]] = {}
1680
+ for row in cursor.fetchall():
1681
+ row_dict = dict(row)
1682
+ subagent = row_dict.pop("subagent_type")
1683
+ if subagent not in result:
1684
+ result[subagent] = []
1685
+ result[subagent].append(row_dict)
1686
+
1687
+ return result
1688
+ except sqlite3.Error as e:
1689
+ logger.error(f"Error querying subagent work: {e}")
1690
+ return {}
1691
+
1586
1692
  def close(self) -> None:
1587
1693
  """Clean up database connection."""
1588
1694
  self.disconnect()
@@ -544,6 +544,7 @@ def record_event_to_sqlite(
544
544
  subagent_type: str | None = None,
545
545
  model: str | None = None,
546
546
  feature_id: str | None = None,
547
+ claude_task_id: str | None = None,
547
548
  ) -> str | None:
548
549
  """
549
550
  Record a tool call event to SQLite database for dashboard queries.
@@ -561,6 +562,7 @@ def record_event_to_sqlite(
561
562
  subagent_type: Subagent type for Task delegations (optional)
562
563
  model: Claude model name (e.g., claude-haiku, claude-opus) (optional)
563
564
  feature_id: Feature ID for attribution (optional)
565
+ claude_task_id: Claude Code's internal task ID for tool attribution (optional)
564
566
 
565
567
  Returns:
566
568
  event_id if successful, None otherwise
@@ -591,6 +593,14 @@ def record_event_to_sqlite(
591
593
  "is_error": is_error,
592
594
  }
593
595
 
596
+ # Extract task_id from Tool response if not provided
597
+ if (
598
+ not claude_task_id
599
+ and tool_name == "Task"
600
+ and isinstance(tool_response, dict)
601
+ ):
602
+ claude_task_id = tool_response.get("task_id")
603
+
594
604
  # Insert event to SQLite
595
605
  success = db.insert_event(
596
606
  event_id=event_id,
@@ -606,6 +616,7 @@ def record_event_to_sqlite(
606
616
  subagent_type=subagent_type,
607
617
  model=model,
608
618
  feature_id=feature_id,
619
+ claude_task_id=claude_task_id,
609
620
  )
610
621
 
611
622
  if success:
@@ -49,48 +49,6 @@ async def run_event_tracking(
49
49
  Returns:
50
50
  Event tracking response: {"continue": True, "hookSpecificOutput": {...}}
51
51
  """
52
- # ============ DEBUG: Log Task() responses ============
53
- import json
54
-
55
- tool_name = hook_input.get("name", "") or hook_input.get("tool_name", "")
56
- if tool_name == "Task":
57
- tool_response = hook_input.get("tool_response", {})
58
-
59
- print("\n" + "=" * 60, file=sys.stderr)
60
- print("DEBUG: Task() PostToolUse Hook Input", file=sys.stderr)
61
- print("=" * 60, file=sys.stderr)
62
-
63
- print(f"\nTool Name: {tool_name}", file=sys.stderr)
64
- print(f"Hook Type: {hook_type}", file=sys.stderr)
65
-
66
- if isinstance(tool_response, dict):
67
- print("\nTool Response Type: dict", file=sys.stderr)
68
- print(f"Tool Response Keys: {list(tool_response.keys())}", file=sys.stderr)
69
-
70
- # Check for task_id field
71
- if "task_id" in tool_response:
72
- task_id = tool_response.get("task_id")
73
- print(f"\n✅ FOUND task_id: {task_id}", file=sys.stderr)
74
- else:
75
- print("\n❌ task_id NOT FOUND in response", file=sys.stderr)
76
-
77
- # Print full response for inspection
78
- print("\nFull Tool Response:", file=sys.stderr)
79
- try:
80
- response_str = json.dumps(tool_response, indent=2, default=str)
81
- print(response_str, file=sys.stderr)
82
- except Exception as e:
83
- print(f"Could not serialize response: {e}", file=sys.stderr)
84
- print(f"Raw response: {tool_response}", file=sys.stderr)
85
- else:
86
- print(
87
- f"\nTool Response Type: {type(tool_response).__name__}", file=sys.stderr
88
- )
89
- print(f"Tool Response Value: {tool_response}", file=sys.stderr)
90
-
91
- print("\n" + "=" * 60 + "\n", file=sys.stderr)
92
- # ============ END DEBUG ============
93
-
94
52
  try:
95
53
  loop = asyncio.get_event_loop()
96
54
 
htmlgraph/sdk.py CHANGED
@@ -2550,6 +2550,106 @@ class SDK:
2550
2550
 
2551
2551
  return analytics.get_recommendations(graph_dir=self._directory)
2552
2552
 
2553
+ # =========================================================================
2554
+ # Task Attribution - Subagent Work Tracking
2555
+ # =========================================================================
2556
+
2557
+ def get_task_attribution(self, task_id: str) -> dict[str, Any]:
2558
+ """
2559
+ Get attribution - which subagent did what work in this task?
2560
+
2561
+ Queries the database to find all events associated with a Claude Code task,
2562
+ showing which subagent executed each tool call.
2563
+
2564
+ Args:
2565
+ task_id: Claude Code's internal task ID (available from Task() response)
2566
+
2567
+ Returns:
2568
+ Dictionary with task_id, by_subagent mapping, and total_events count
2569
+
2570
+ Example:
2571
+ >>> sdk = SDK(agent="claude")
2572
+ >>> result = sdk.get_task_attribution("task-abc123-xyz789")
2573
+ >>> for subagent, events in result['by_subagent'].items():
2574
+ ... print(f"{subagent}:")
2575
+ ... for event in events:
2576
+ ... print(f" - {event['tool']}: {event['summary']}")
2577
+ >>> print(f"Total events: {result['total_events']}")
2578
+
2579
+ See also:
2580
+ get_subagent_work: Get all work grouped by subagent in a session
2581
+ """
2582
+ from htmlgraph.config import get_database_path
2583
+ from htmlgraph.db.schema import HtmlGraphDB
2584
+
2585
+ try:
2586
+ db = HtmlGraphDB(str(get_database_path()))
2587
+ events = db.get_events_for_task(task_id)
2588
+
2589
+ # Group by subagent_type
2590
+ by_subagent: dict[str, list[dict[str, Any]]] = {}
2591
+ for event in events:
2592
+ agent = event.get("subagent_type", "orchestrator")
2593
+ if agent not in by_subagent:
2594
+ by_subagent[agent] = []
2595
+ by_subagent[agent].append(
2596
+ {
2597
+ "tool": event.get("tool_name"),
2598
+ "summary": event.get("input_summary"),
2599
+ "timestamp": event.get("created_at"),
2600
+ "event_id": event.get("event_id"),
2601
+ "success": not event.get("is_error", False),
2602
+ }
2603
+ )
2604
+
2605
+ return {
2606
+ "task_id": task_id,
2607
+ "by_subagent": by_subagent,
2608
+ "total_events": len(events),
2609
+ }
2610
+ except Exception as e:
2611
+ return {
2612
+ "task_id": task_id,
2613
+ "by_subagent": {},
2614
+ "total_events": 0,
2615
+ "error": str(e),
2616
+ }
2617
+
2618
+ def get_subagent_work(self, session_id: str) -> dict[str, list[dict[str, Any]]]:
2619
+ """
2620
+ Get all work grouped by which subagent did it in a session.
2621
+
2622
+ Shows which subagent (researcher, general-purpose, etc.) executed each
2623
+ tool call within a session.
2624
+
2625
+ Args:
2626
+ session_id: Session ID to analyze
2627
+
2628
+ Returns:
2629
+ Dictionary mapping subagent_type to list of events they executed.
2630
+ Each event includes: tool_name, input_summary, output_summary, created_at, event_id
2631
+
2632
+ Example:
2633
+ >>> sdk = SDK(agent="claude")
2634
+ >>> work = sdk.get_subagent_work("sess-123")
2635
+ >>> for subagent, events in work.items():
2636
+ ... print(f"{subagent} ({len(events)} events):")
2637
+ ... for event in events:
2638
+ ... print(f" - {event['tool_name']}: {event['input_summary']}")
2639
+
2640
+ See also:
2641
+ get_task_attribution: Get work for a specific Claude Code task
2642
+ analyze_session: Get session metrics and analytics
2643
+ """
2644
+ from htmlgraph.config import get_database_path
2645
+ from htmlgraph.db.schema import HtmlGraphDB
2646
+
2647
+ try:
2648
+ db = HtmlGraphDB(str(get_database_path()))
2649
+ return db.get_subagent_work(session_id)
2650
+ except Exception:
2651
+ return {}
2652
+
2553
2653
  # =========================================================================
2554
2654
  # Help & Documentation
2555
2655
  # =========================================================================
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: htmlgraph
3
- Version: 0.26.14
3
+ Version: 0.26.15
4
4
  Summary: HTML is All You Need - Graph database on web standards
5
5
  Project-URL: Homepage, https://github.com/Shakes-tzd/htmlgraph
6
6
  Project-URL: Documentation, https://github.com/Shakes-tzd/htmlgraph#readme
@@ -1,4 +1,4 @@
1
- htmlgraph/__init__.py,sha256=aFjqr9RP4Lzx2kZCoH8PRKdbaMd4an9tAnvEG9xLapo,5718
1
+ htmlgraph/__init__.py,sha256=lbwP3tJgZg5ZD8OljSA3yJcTwB8HUqxD199BKoiMNB8,5718
2
2
  htmlgraph/agent_detection.py,sha256=wEmrDv4hssPX2OkEnJZBHPbalxcaloiJF_hOOow_5WE,3511
3
3
  htmlgraph/agent_registry.py,sha256=Usa_35by7p5gtpvHO7K3AcGimnorw-FzgPVa3cWTQ58,9448
4
4
  htmlgraph/agents.py,sha256=Yvu6x1nOfrW2WhRTAHiCuSpvqoVJXx1Mkzd59kwEczw,33466
@@ -46,7 +46,7 @@ htmlgraph/query_builder.py,sha256=aNtJ05GpGl9yUSSrX0D6pX_AgqlrrH-CulI_oP11PUk,18
46
46
  htmlgraph/reflection.py,sha256=j5oclTrmRGEFgGCPHh93QSasEG2IMAFdFXRj7tP-S2c,15662
47
47
  htmlgraph/repo_hash.py,sha256=rmRgfPs8Xl9FuiP3PERAz5l6qm5Goy_Q0O6RT-V5jVM,14887
48
48
  htmlgraph/routing.py,sha256=QYDY6bzYPmv6kocAXCqguB1cazN0i_xTo9EVCO3fO2Y,8803
49
- htmlgraph/sdk.py,sha256=l1jQFi1ox9pcJ6mrOU9qyBXGhq0lSVs86sBmJHnNnww,113660
49
+ htmlgraph/sdk.py,sha256=DY6hpa9pUcxBl6z7_kG6h1sgAFwwLSj3Zh0s6-6c-Q8,117532
50
50
  htmlgraph/server.py,sha256=WeDQqnAPUSeh5ffKZWSxrpclwIo45vLPwy_UVGVPtO8,56066
51
51
  htmlgraph/session_hooks.py,sha256=AOjpPMZo2s_d_KXuPiWDo8TIOdkXsEU0CoOHd4G5A10,9195
52
52
  htmlgraph/session_manager.py,sha256=bwo_SWYHQw9JFOtz6D6cTX7XUwY0WFMcMUbZy8eqEFc,93515
@@ -131,9 +131,9 @@ htmlgraph/cli/constants.py,sha256=S7hAih2Ka64c0sWqOdq7W762VRoBHri8w8XDDWqHCkE,70
131
131
  htmlgraph/cli/core.py,sha256=JhRL1iZhN3x4IeeVQkK4GnfAV7JQm5JDU6hG473GBOs,28878
132
132
  htmlgraph/cli/main.py,sha256=rSSSErlmFHrREbAydtytj3up8M_dQ9jFgYL1OmrSQas,4108
133
133
  htmlgraph/cli/models.py,sha256=7dEAwsroH2J_84Bq6i9Q0RLJsKQ9rNbX_daOfHdrb78,16033
134
- htmlgraph/cli/.htmlgraph/.session-warning-state.json,sha256=jKw9n3GDSPzcHwZZnRoW7eOJEbQPQ3FKpvo3kMY7lHw,93
134
+ htmlgraph/cli/.htmlgraph/.session-warning-state.json,sha256=uFIJVhXV7z0NmDjkgretnTiVHxXIqg7mbVCznWX46fQ,93
135
135
  htmlgraph/cli/.htmlgraph/agents.json,sha256=hVmmvoL4CDTIrhxH7VaM-jSDCj8kszWsUFY_LHae9DQ,1391
136
- htmlgraph/cli/.htmlgraph/htmlgraph.db,sha256=Ipk3K21EQyTT5hkimtL1dBiwHve-3zdpS4yP1wMMU-4,1343488
136
+ htmlgraph/cli/.htmlgraph/htmlgraph.db,sha256=3bdzMqg_s7d3bTFW3rei8ZA8MGFiPqVipj7MMJxtueM,1363968
137
137
  htmlgraph/cli/templates/__init__.py,sha256=7eh8oC8rce689HGuuYqJEMCElJCtg084xOMHZti2XL8,37
138
138
  htmlgraph/cli/templates/cost_dashboard.py,sha256=2FRaujRUYEDfA18c0QFju28yidfaVnMFH4pdcBaQ7Ao,11313
139
139
  htmlgraph/cli/work/__init__.py,sha256=yFK8G85F-Z9df-3LBM-3NbjCgidtLEVhkYGO1uf4QuI,4570
@@ -162,7 +162,7 @@ htmlgraph/cost_analysis/__init__.py,sha256=kuAA4Fd0gUplOWOiqs3CF4eO1wwekGs_3DaiF
162
162
  htmlgraph/cost_analysis/analyzer.py,sha256=TDKgRXeOQ-td5LZhkFob4ajEf-JssSCGKlMS3GysYJU,15040
163
163
  htmlgraph/db/__init__.py,sha256=1yWTyWrN2kcmW6mVKCUf4POSUXTOSaAljwEyyC0Xs1w,1033
164
164
  htmlgraph/db/queries.py,sha256=FtqOIBJC0EociEYNJr6gTVROqd9m5yZdVGYLxXNVSdk,22608
165
- htmlgraph/db/schema.py,sha256=RKeBkg9EkgAq8Vpg5dhQJeAewxEr_37oDLL--dg7hNI,60477
165
+ htmlgraph/db/schema.py,sha256=7t4Yjsml_pNN5wG7VNHnPrcFqNCr0xbZdSrKmA8pib0,64306
166
166
  htmlgraph/docs/API_REFERENCE.md,sha256=LYsYeHinF6GEsjMvrgdQSbgmMPsOh4ZQ1WK11niqNvo,17862
167
167
  htmlgraph/docs/HTTP_API.md,sha256=IrX-wZckFn-K3ztCVcT-zyGqJL2TtY1qYV7dUuC7kzc,13344
168
168
  htmlgraph/docs/INTEGRATION_GUIDE.md,sha256=uNNM0ipY0bFAkZaL1CkvnA_Wt2MVPGRBdA4927cZaHo,16910
@@ -192,7 +192,7 @@ htmlgraph/hooks/cigs_pretool_enforcer.py,sha256=Lyp4DDaw_sVHEcW-kzdegldyfXjvVD25
192
192
  htmlgraph/hooks/concurrent_sessions.py,sha256=qOiwDfynphVG0-2pVBakEzOwMORU8ebN1gMjcN4S0z0,6476
193
193
  htmlgraph/hooks/context.py,sha256=tJ4dIL8uTFHyqyuuMc-ETDuOikeD5cN3Mdjmfg6W0HE,13108
194
194
  htmlgraph/hooks/drift_handler.py,sha256=QckL5U5ooku51kI6mppGLsXzaKVt1Yx5uNu-iXZrgSk,17602
195
- htmlgraph/hooks/event_tracker.py,sha256=A58ByxOR4xX014pbUuGtfkN8KS22zkb9ajkTzNmp6mw,45916
195
+ htmlgraph/hooks/event_tracker.py,sha256=en7voeFYRiixOpJn-h99fMH6fEitj2DiJJ6tIrYvGBc,46344
196
196
  htmlgraph/hooks/git_commands.py,sha256=NPzthfzGJ_bkDi7soehHOxI9FLL-6BL8Tie9Byb_zf4,4803
197
197
  htmlgraph/hooks/hooks-config.example.json,sha256=tXpk-U-FZzGOoNJK2uiDMbIHCYEHA794J-El0fBwkqg,197
198
198
  htmlgraph/hooks/installer.py,sha256=nOctCFDEV7BEh7ZzxNY-apu1KZG0SHPMq74UPIOChqY,11756
@@ -203,7 +203,7 @@ htmlgraph/hooks/post-commit.sh,sha256=if65jNGZnEWsZPq_iYDNYunrZ1cmjPUEUbh6_4vfpO
203
203
  htmlgraph/hooks/post-merge.sh,sha256=gq-EeFLhDUVp-J2jyWMBVFcB0pdmH54Wu1SW_Gn-s2I,541
204
204
  htmlgraph/hooks/post_tool_use_failure.py,sha256=DHkJtuAOg5KSLfFZ1O-kePwaqmtNkbGQSEn4NplzvD8,8381
205
205
  htmlgraph/hooks/post_tool_use_handler.py,sha256=e0L8X4sU2H167HH96CgV6iYojd02AI9uyF8m4A1a-kU,8345
206
- htmlgraph/hooks/posttooluse.py,sha256=HOxW9lgJCnRLJRsdB7PFfAJkPWv-NiLjkF4wcBnjVUE,14606
206
+ htmlgraph/hooks/posttooluse.py,sha256=3usICpqlIdLKsijYY61BP2QezsB45MZ6evwFSobC9Yo,12822
207
207
  htmlgraph/hooks/pre-commit.sh,sha256=gTpbnHIBFxpAl7-REhXoS0NI4Pmlqo9pQEMEngTAU_A,3865
208
208
  htmlgraph/hooks/pre-push.sh,sha256=rNnkG8YmDtyk7OuJHOcbOYQR3MYFneaG6_w2X-Hl8Hs,660
209
209
  htmlgraph/hooks/pretooluse.py,sha256=5mW-hMmJZlFvahDfA9yCfPrtaN6yAlWTOchirE-zZdU,27327
@@ -252,12 +252,12 @@ htmlgraph/templates/AGENTS.md.template,sha256=f96h7V6ygwj-v-fanVI48eYMxR6t_se4be
252
252
  htmlgraph/templates/CLAUDE.md.template,sha256=h1kG2hTX2XYig2KszsHBfzrwa_4Cfcq2Pj4SwqzeDlM,1984
253
253
  htmlgraph/templates/GEMINI.md.template,sha256=gAGzE53Avki87BM_otqy5HdcYCoLsHgqaKjVzNzPMX8,1622
254
254
  htmlgraph/templates/orchestration-view.html,sha256=DlS7LlcjH0oO_KYILjuF1X42t8QhKLH4F85rkO54alY,10472
255
- htmlgraph-0.26.14.data/data/htmlgraph/dashboard.html,sha256=MUT6SaYnazoyDcvHz5hN1omYswyIoUfeoZLf2M_iblo,251268
256
- htmlgraph-0.26.14.data/data/htmlgraph/styles.css,sha256=oDUSC8jG-V-hKojOBO9J88hxAeY2wJrBYTq0uCwX_Y4,7135
257
- htmlgraph-0.26.14.data/data/htmlgraph/templates/AGENTS.md.template,sha256=f96h7V6ygwj-v-fanVI48eYMxR6t_se4bet1H4ZsDpI,7642
258
- htmlgraph-0.26.14.data/data/htmlgraph/templates/CLAUDE.md.template,sha256=h1kG2hTX2XYig2KszsHBfzrwa_4Cfcq2Pj4SwqzeDlM,1984
259
- htmlgraph-0.26.14.data/data/htmlgraph/templates/GEMINI.md.template,sha256=gAGzE53Avki87BM_otqy5HdcYCoLsHgqaKjVzNzPMX8,1622
260
- htmlgraph-0.26.14.dist-info/METADATA,sha256=BOzq9w86UFDhZgsaZCIMYf8Cp4nqHf8_rWEC_-7EOF4,10237
261
- htmlgraph-0.26.14.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
262
- htmlgraph-0.26.14.dist-info/entry_points.txt,sha256=Wmdo5cx8pt6NoMsssVE2mZH1CZLSUsrg_3iSWatiyn0,103
263
- htmlgraph-0.26.14.dist-info/RECORD,,
255
+ htmlgraph-0.26.15.data/data/htmlgraph/dashboard.html,sha256=MUT6SaYnazoyDcvHz5hN1omYswyIoUfeoZLf2M_iblo,251268
256
+ htmlgraph-0.26.15.data/data/htmlgraph/styles.css,sha256=oDUSC8jG-V-hKojOBO9J88hxAeY2wJrBYTq0uCwX_Y4,7135
257
+ htmlgraph-0.26.15.data/data/htmlgraph/templates/AGENTS.md.template,sha256=f96h7V6ygwj-v-fanVI48eYMxR6t_se4bet1H4ZsDpI,7642
258
+ htmlgraph-0.26.15.data/data/htmlgraph/templates/CLAUDE.md.template,sha256=h1kG2hTX2XYig2KszsHBfzrwa_4Cfcq2Pj4SwqzeDlM,1984
259
+ htmlgraph-0.26.15.data/data/htmlgraph/templates/GEMINI.md.template,sha256=gAGzE53Avki87BM_otqy5HdcYCoLsHgqaKjVzNzPMX8,1622
260
+ htmlgraph-0.26.15.dist-info/METADATA,sha256=_nK1I_FlE2APgcbSLEQNm59-GzD3H-TCA90lEMXTYN0,10237
261
+ htmlgraph-0.26.15.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
262
+ htmlgraph-0.26.15.dist-info/entry_points.txt,sha256=Wmdo5cx8pt6NoMsssVE2mZH1CZLSUsrg_3iSWatiyn0,103
263
+ htmlgraph-0.26.15.dist-info/RECORD,,