htmlgraph 0.20.1__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.
- htmlgraph/.htmlgraph/.session-warning-state.json +6 -0
- htmlgraph/.htmlgraph/agents.json +72 -0
- htmlgraph/.htmlgraph/htmlgraph.db +0 -0
- htmlgraph/__init__.py +51 -1
- htmlgraph/__init__.pyi +123 -0
- htmlgraph/agent_detection.py +26 -10
- htmlgraph/agent_registry.py +2 -1
- htmlgraph/analytics/__init__.py +8 -1
- htmlgraph/analytics/cli.py +86 -20
- htmlgraph/analytics/cost_analyzer.py +391 -0
- htmlgraph/analytics/cost_monitor.py +664 -0
- htmlgraph/analytics/cost_reporter.py +675 -0
- htmlgraph/analytics/cross_session.py +617 -0
- htmlgraph/analytics/dependency.py +10 -6
- htmlgraph/analytics/pattern_learning.py +771 -0
- htmlgraph/analytics/session_graph.py +707 -0
- htmlgraph/analytics/strategic/__init__.py +80 -0
- htmlgraph/analytics/strategic/cost_optimizer.py +611 -0
- htmlgraph/analytics/strategic/pattern_detector.py +876 -0
- htmlgraph/analytics/strategic/preference_manager.py +709 -0
- htmlgraph/analytics/strategic/suggestion_engine.py +747 -0
- htmlgraph/analytics/work_type.py +67 -27
- htmlgraph/analytics_index.py +53 -20
- htmlgraph/api/__init__.py +3 -0
- htmlgraph/api/cost_alerts_websocket.py +416 -0
- htmlgraph/api/main.py +2498 -0
- htmlgraph/api/static/htmx.min.js +1 -0
- htmlgraph/api/static/style-redesign.css +1344 -0
- htmlgraph/api/static/style.css +1079 -0
- htmlgraph/api/templates/dashboard-redesign.html +1366 -0
- htmlgraph/api/templates/dashboard.html +794 -0
- htmlgraph/api/templates/partials/activity-feed-hierarchical.html +326 -0
- htmlgraph/api/templates/partials/activity-feed.html +1100 -0
- htmlgraph/api/templates/partials/agents-redesign.html +317 -0
- htmlgraph/api/templates/partials/agents.html +317 -0
- htmlgraph/api/templates/partials/event-traces.html +373 -0
- htmlgraph/api/templates/partials/features-kanban-redesign.html +509 -0
- htmlgraph/api/templates/partials/features.html +578 -0
- htmlgraph/api/templates/partials/metrics-redesign.html +346 -0
- htmlgraph/api/templates/partials/metrics.html +346 -0
- htmlgraph/api/templates/partials/orchestration-redesign.html +443 -0
- htmlgraph/api/templates/partials/orchestration.html +198 -0
- htmlgraph/api/templates/partials/spawners.html +375 -0
- htmlgraph/api/templates/partials/work-items.html +613 -0
- htmlgraph/api/websocket.py +538 -0
- htmlgraph/archive/__init__.py +24 -0
- htmlgraph/archive/bloom.py +234 -0
- htmlgraph/archive/fts.py +297 -0
- htmlgraph/archive/manager.py +583 -0
- htmlgraph/archive/search.py +244 -0
- htmlgraph/atomic_ops.py +560 -0
- htmlgraph/attribute_index.py +2 -1
- htmlgraph/bounded_paths.py +539 -0
- htmlgraph/builders/base.py +57 -2
- htmlgraph/builders/bug.py +19 -3
- htmlgraph/builders/chore.py +19 -3
- htmlgraph/builders/epic.py +19 -3
- htmlgraph/builders/feature.py +27 -3
- htmlgraph/builders/insight.py +2 -1
- htmlgraph/builders/metric.py +2 -1
- htmlgraph/builders/pattern.py +2 -1
- htmlgraph/builders/phase.py +19 -3
- htmlgraph/builders/spike.py +29 -3
- htmlgraph/builders/track.py +42 -1
- htmlgraph/cigs/__init__.py +81 -0
- htmlgraph/cigs/autonomy.py +385 -0
- htmlgraph/cigs/cost.py +475 -0
- htmlgraph/cigs/messages_basic.py +472 -0
- htmlgraph/cigs/messaging.py +365 -0
- htmlgraph/cigs/models.py +771 -0
- htmlgraph/cigs/pattern_storage.py +427 -0
- htmlgraph/cigs/patterns.py +503 -0
- htmlgraph/cigs/posttool_analyzer.py +234 -0
- htmlgraph/cigs/reporter.py +818 -0
- htmlgraph/cigs/tracker.py +317 -0
- htmlgraph/cli/.htmlgraph/.session-warning-state.json +6 -0
- htmlgraph/cli/.htmlgraph/agents.json +72 -0
- htmlgraph/cli/.htmlgraph/htmlgraph.db +0 -0
- htmlgraph/cli/__init__.py +42 -0
- htmlgraph/cli/__main__.py +6 -0
- htmlgraph/cli/analytics.py +1424 -0
- htmlgraph/cli/base.py +685 -0
- htmlgraph/cli/constants.py +206 -0
- htmlgraph/cli/core.py +954 -0
- htmlgraph/cli/main.py +147 -0
- htmlgraph/cli/models.py +475 -0
- htmlgraph/cli/templates/__init__.py +1 -0
- htmlgraph/cli/templates/cost_dashboard.py +399 -0
- htmlgraph/cli/work/__init__.py +239 -0
- htmlgraph/cli/work/browse.py +115 -0
- htmlgraph/cli/work/features.py +568 -0
- htmlgraph/cli/work/orchestration.py +676 -0
- htmlgraph/cli/work/report.py +728 -0
- htmlgraph/cli/work/sessions.py +466 -0
- htmlgraph/cli/work/snapshot.py +559 -0
- htmlgraph/cli/work/tracks.py +486 -0
- htmlgraph/cli_commands/__init__.py +1 -0
- htmlgraph/cli_commands/feature.py +195 -0
- htmlgraph/cli_framework.py +115 -0
- htmlgraph/collections/__init__.py +2 -0
- htmlgraph/collections/base.py +197 -14
- htmlgraph/collections/bug.py +2 -1
- htmlgraph/collections/chore.py +2 -1
- htmlgraph/collections/epic.py +2 -1
- htmlgraph/collections/feature.py +2 -1
- htmlgraph/collections/insight.py +2 -1
- htmlgraph/collections/metric.py +2 -1
- htmlgraph/collections/pattern.py +2 -1
- htmlgraph/collections/phase.py +2 -1
- htmlgraph/collections/session.py +194 -0
- htmlgraph/collections/spike.py +13 -2
- htmlgraph/collections/task_delegation.py +241 -0
- htmlgraph/collections/todo.py +14 -1
- htmlgraph/collections/traces.py +487 -0
- htmlgraph/config/cost_models.json +56 -0
- htmlgraph/config.py +190 -0
- htmlgraph/context_analytics.py +2 -1
- htmlgraph/converter.py +116 -7
- htmlgraph/cost_analysis/__init__.py +5 -0
- htmlgraph/cost_analysis/analyzer.py +438 -0
- htmlgraph/dashboard.html +2246 -248
- htmlgraph/dashboard.html.backup +6592 -0
- htmlgraph/dashboard.html.bak +7181 -0
- htmlgraph/dashboard.html.bak2 +7231 -0
- htmlgraph/dashboard.html.bak3 +7232 -0
- htmlgraph/db/__init__.py +38 -0
- htmlgraph/db/queries.py +790 -0
- htmlgraph/db/schema.py +1788 -0
- htmlgraph/decorators.py +317 -0
- htmlgraph/dependency_models.py +2 -1
- htmlgraph/deploy.py +26 -27
- htmlgraph/docs/API_REFERENCE.md +841 -0
- htmlgraph/docs/HTTP_API.md +750 -0
- htmlgraph/docs/INTEGRATION_GUIDE.md +752 -0
- htmlgraph/docs/ORCHESTRATION_PATTERNS.md +717 -0
- htmlgraph/docs/README.md +532 -0
- htmlgraph/docs/__init__.py +77 -0
- htmlgraph/docs/docs_version.py +55 -0
- htmlgraph/docs/metadata.py +93 -0
- htmlgraph/docs/migrations.py +232 -0
- htmlgraph/docs/template_engine.py +143 -0
- htmlgraph/docs/templates/_sections/cli_reference.md.j2 +52 -0
- htmlgraph/docs/templates/_sections/core_concepts.md.j2 +29 -0
- htmlgraph/docs/templates/_sections/sdk_basics.md.j2 +69 -0
- htmlgraph/docs/templates/base_agents.md.j2 +78 -0
- htmlgraph/docs/templates/example_user_override.md.j2 +47 -0
- htmlgraph/docs/version_check.py +163 -0
- htmlgraph/edge_index.py +2 -1
- htmlgraph/error_handler.py +544 -0
- htmlgraph/event_log.py +86 -37
- htmlgraph/event_migration.py +2 -1
- htmlgraph/file_watcher.py +12 -8
- htmlgraph/find_api.py +2 -1
- htmlgraph/git_events.py +67 -9
- htmlgraph/hooks/.htmlgraph/.session-warning-state.json +6 -0
- htmlgraph/hooks/.htmlgraph/agents.json +72 -0
- htmlgraph/hooks/.htmlgraph/index.sqlite +0 -0
- htmlgraph/hooks/__init__.py +8 -0
- htmlgraph/hooks/bootstrap.py +169 -0
- htmlgraph/hooks/cigs_pretool_enforcer.py +354 -0
- htmlgraph/hooks/concurrent_sessions.py +208 -0
- htmlgraph/hooks/context.py +350 -0
- htmlgraph/hooks/drift_handler.py +525 -0
- htmlgraph/hooks/event_tracker.py +790 -99
- htmlgraph/hooks/git_commands.py +175 -0
- htmlgraph/hooks/installer.py +5 -1
- htmlgraph/hooks/orchestrator.py +327 -76
- htmlgraph/hooks/orchestrator_reflector.py +31 -4
- htmlgraph/hooks/post_tool_use_failure.py +32 -7
- htmlgraph/hooks/post_tool_use_handler.py +257 -0
- htmlgraph/hooks/posttooluse.py +92 -19
- htmlgraph/hooks/pretooluse.py +527 -7
- htmlgraph/hooks/prompt_analyzer.py +637 -0
- htmlgraph/hooks/session_handler.py +668 -0
- htmlgraph/hooks/session_summary.py +395 -0
- htmlgraph/hooks/state_manager.py +504 -0
- htmlgraph/hooks/subagent_detection.py +202 -0
- htmlgraph/hooks/subagent_stop.py +369 -0
- htmlgraph/hooks/task_enforcer.py +99 -4
- htmlgraph/hooks/validator.py +212 -91
- htmlgraph/ids.py +2 -1
- htmlgraph/learning.py +125 -100
- htmlgraph/mcp_server.py +2 -1
- htmlgraph/models.py +217 -18
- htmlgraph/operations/README.md +62 -0
- htmlgraph/operations/__init__.py +79 -0
- htmlgraph/operations/analytics.py +339 -0
- htmlgraph/operations/bootstrap.py +289 -0
- htmlgraph/operations/events.py +244 -0
- htmlgraph/operations/fastapi_server.py +231 -0
- htmlgraph/operations/hooks.py +350 -0
- htmlgraph/operations/initialization.py +597 -0
- htmlgraph/operations/initialization.py.backup +228 -0
- htmlgraph/operations/server.py +303 -0
- htmlgraph/orchestration/__init__.py +58 -0
- htmlgraph/orchestration/claude_launcher.py +179 -0
- htmlgraph/orchestration/command_builder.py +72 -0
- htmlgraph/orchestration/headless_spawner.py +281 -0
- htmlgraph/orchestration/live_events.py +377 -0
- htmlgraph/orchestration/model_selection.py +327 -0
- htmlgraph/orchestration/plugin_manager.py +140 -0
- htmlgraph/orchestration/prompts.py +137 -0
- htmlgraph/orchestration/spawner_event_tracker.py +383 -0
- htmlgraph/orchestration/spawners/__init__.py +16 -0
- htmlgraph/orchestration/spawners/base.py +194 -0
- htmlgraph/orchestration/spawners/claude.py +173 -0
- htmlgraph/orchestration/spawners/codex.py +435 -0
- htmlgraph/orchestration/spawners/copilot.py +294 -0
- htmlgraph/orchestration/spawners/gemini.py +471 -0
- htmlgraph/orchestration/subprocess_runner.py +36 -0
- htmlgraph/{orchestration.py → orchestration/task_coordination.py} +16 -8
- htmlgraph/orchestration.md +563 -0
- htmlgraph/orchestrator-system-prompt-optimized.txt +863 -0
- htmlgraph/orchestrator.py +2 -1
- htmlgraph/orchestrator_config.py +357 -0
- htmlgraph/orchestrator_mode.py +115 -4
- htmlgraph/parallel.py +2 -1
- htmlgraph/parser.py +86 -6
- htmlgraph/path_query.py +608 -0
- htmlgraph/pattern_matcher.py +636 -0
- htmlgraph/pydantic_models.py +476 -0
- htmlgraph/quality_gates.py +350 -0
- htmlgraph/query_builder.py +2 -1
- htmlgraph/query_composer.py +509 -0
- htmlgraph/reflection.py +443 -0
- htmlgraph/refs.py +344 -0
- htmlgraph/repo_hash.py +512 -0
- htmlgraph/repositories/__init__.py +292 -0
- htmlgraph/repositories/analytics_repository.py +455 -0
- htmlgraph/repositories/analytics_repository_standard.py +628 -0
- htmlgraph/repositories/feature_repository.py +581 -0
- htmlgraph/repositories/feature_repository_htmlfile.py +668 -0
- htmlgraph/repositories/feature_repository_memory.py +607 -0
- htmlgraph/repositories/feature_repository_sqlite.py +858 -0
- htmlgraph/repositories/filter_service.py +620 -0
- htmlgraph/repositories/filter_service_standard.py +445 -0
- htmlgraph/repositories/shared_cache.py +621 -0
- htmlgraph/repositories/shared_cache_memory.py +395 -0
- htmlgraph/repositories/track_repository.py +552 -0
- htmlgraph/repositories/track_repository_htmlfile.py +619 -0
- htmlgraph/repositories/track_repository_memory.py +508 -0
- htmlgraph/repositories/track_repository_sqlite.py +711 -0
- htmlgraph/sdk/__init__.py +398 -0
- htmlgraph/sdk/__init__.pyi +14 -0
- htmlgraph/sdk/analytics/__init__.py +19 -0
- htmlgraph/sdk/analytics/engine.py +155 -0
- htmlgraph/sdk/analytics/helpers.py +178 -0
- htmlgraph/sdk/analytics/registry.py +109 -0
- htmlgraph/sdk/base.py +484 -0
- htmlgraph/sdk/constants.py +216 -0
- htmlgraph/sdk/core.pyi +308 -0
- htmlgraph/sdk/discovery.py +120 -0
- htmlgraph/sdk/help/__init__.py +12 -0
- htmlgraph/sdk/help/mixin.py +699 -0
- htmlgraph/sdk/mixins/__init__.py +15 -0
- htmlgraph/sdk/mixins/attribution.py +113 -0
- htmlgraph/sdk/mixins/mixin.py +410 -0
- htmlgraph/sdk/operations/__init__.py +12 -0
- htmlgraph/sdk/operations/mixin.py +427 -0
- htmlgraph/sdk/orchestration/__init__.py +17 -0
- htmlgraph/sdk/orchestration/coordinator.py +203 -0
- htmlgraph/sdk/orchestration/spawner.py +204 -0
- htmlgraph/sdk/planning/__init__.py +19 -0
- htmlgraph/sdk/planning/bottlenecks.py +93 -0
- htmlgraph/sdk/planning/mixin.py +211 -0
- htmlgraph/sdk/planning/parallel.py +186 -0
- htmlgraph/sdk/planning/queue.py +210 -0
- htmlgraph/sdk/planning/recommendations.py +87 -0
- htmlgraph/sdk/planning/smart_planning.py +319 -0
- htmlgraph/sdk/session/__init__.py +19 -0
- htmlgraph/sdk/session/continuity.py +57 -0
- htmlgraph/sdk/session/handoff.py +110 -0
- htmlgraph/sdk/session/info.py +309 -0
- htmlgraph/sdk/session/manager.py +103 -0
- htmlgraph/sdk/strategic/__init__.py +26 -0
- htmlgraph/sdk/strategic/mixin.py +563 -0
- htmlgraph/server.py +295 -107
- htmlgraph/session_hooks.py +300 -0
- htmlgraph/session_manager.py +285 -3
- htmlgraph/session_registry.py +587 -0
- htmlgraph/session_state.py +436 -0
- htmlgraph/session_warning.py +2 -1
- htmlgraph/sessions/__init__.py +23 -0
- htmlgraph/sessions/handoff.py +756 -0
- htmlgraph/system_prompts.py +450 -0
- htmlgraph/templates/orchestration-view.html +350 -0
- htmlgraph/track_builder.py +33 -1
- htmlgraph/track_manager.py +38 -0
- htmlgraph/transcript.py +18 -5
- htmlgraph/validation.py +115 -0
- htmlgraph/watch.py +2 -1
- htmlgraph/work_type_utils.py +2 -1
- {htmlgraph-0.20.1.data → htmlgraph-0.27.5.data}/data/htmlgraph/dashboard.html +2246 -248
- {htmlgraph-0.20.1.dist-info → htmlgraph-0.27.5.dist-info}/METADATA +95 -64
- htmlgraph-0.27.5.dist-info/RECORD +337 -0
- {htmlgraph-0.20.1.dist-info → htmlgraph-0.27.5.dist-info}/entry_points.txt +1 -1
- htmlgraph/cli.py +0 -4839
- htmlgraph/sdk.py +0 -2359
- htmlgraph-0.20.1.dist-info/RECORD +0 -118
- {htmlgraph-0.20.1.data → htmlgraph-0.27.5.data}/data/htmlgraph/styles.css +0 -0
- {htmlgraph-0.20.1.data → htmlgraph-0.27.5.data}/data/htmlgraph/templates/AGENTS.md.template +0 -0
- {htmlgraph-0.20.1.data → htmlgraph-0.27.5.data}/data/htmlgraph/templates/CLAUDE.md.template +0 -0
- {htmlgraph-0.20.1.data → htmlgraph-0.27.5.data}/data/htmlgraph/templates/GEMINI.md.template +0 -0
- {htmlgraph-0.20.1.dist-info → htmlgraph-0.27.5.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "1.0",
|
|
3
|
+
"updated": "2026-01-11T04:13:54.354401",
|
|
4
|
+
"agents": {
|
|
5
|
+
"claude": {
|
|
6
|
+
"id": "claude",
|
|
7
|
+
"name": "Claude",
|
|
8
|
+
"capabilities": [
|
|
9
|
+
"python",
|
|
10
|
+
"javascript",
|
|
11
|
+
"typescript",
|
|
12
|
+
"html",
|
|
13
|
+
"css",
|
|
14
|
+
"code-review",
|
|
15
|
+
"testing",
|
|
16
|
+
"documentation",
|
|
17
|
+
"debugging",
|
|
18
|
+
"refactoring",
|
|
19
|
+
"architecture",
|
|
20
|
+
"api-design"
|
|
21
|
+
],
|
|
22
|
+
"max_parallel_tasks": 3,
|
|
23
|
+
"preferred_complexity": [
|
|
24
|
+
"low",
|
|
25
|
+
"medium",
|
|
26
|
+
"high",
|
|
27
|
+
"very-high"
|
|
28
|
+
],
|
|
29
|
+
"active": true,
|
|
30
|
+
"metadata": {}
|
|
31
|
+
},
|
|
32
|
+
"gemini": {
|
|
33
|
+
"id": "gemini",
|
|
34
|
+
"name": "Gemini",
|
|
35
|
+
"capabilities": [
|
|
36
|
+
"python",
|
|
37
|
+
"data-analysis",
|
|
38
|
+
"documentation",
|
|
39
|
+
"testing",
|
|
40
|
+
"code-review",
|
|
41
|
+
"javascript"
|
|
42
|
+
],
|
|
43
|
+
"max_parallel_tasks": 2,
|
|
44
|
+
"preferred_complexity": [
|
|
45
|
+
"low",
|
|
46
|
+
"medium",
|
|
47
|
+
"high"
|
|
48
|
+
],
|
|
49
|
+
"active": true,
|
|
50
|
+
"metadata": {}
|
|
51
|
+
},
|
|
52
|
+
"codex": {
|
|
53
|
+
"id": "codex",
|
|
54
|
+
"name": "Codex",
|
|
55
|
+
"capabilities": [
|
|
56
|
+
"python",
|
|
57
|
+
"javascript",
|
|
58
|
+
"debugging",
|
|
59
|
+
"testing",
|
|
60
|
+
"code-generation",
|
|
61
|
+
"documentation"
|
|
62
|
+
],
|
|
63
|
+
"max_parallel_tasks": 2,
|
|
64
|
+
"preferred_complexity": [
|
|
65
|
+
"low",
|
|
66
|
+
"medium"
|
|
67
|
+
],
|
|
68
|
+
"active": true,
|
|
69
|
+
"metadata": {}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
Binary file
|
htmlgraph/__init__.py
CHANGED
|
@@ -5,12 +5,43 @@ A lightweight graph database framework using HTML files as nodes,
|
|
|
5
5
|
hyperlinks as edges, and CSS selectors as the query language.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
+
import logging
|
|
9
|
+
|
|
10
|
+
from rich.console import Console
|
|
11
|
+
from rich.logging import RichHandler
|
|
12
|
+
|
|
13
|
+
# Configure Rich logging for entire SDK
|
|
14
|
+
# CRITICAL: Use stderr=True to prevent pollution of stdout (hooks output JSON to stdout)
|
|
15
|
+
logging.basicConfig(
|
|
16
|
+
handlers=[
|
|
17
|
+
RichHandler(
|
|
18
|
+
console=Console(stderr=True),
|
|
19
|
+
show_time=True,
|
|
20
|
+
show_level=True,
|
|
21
|
+
rich_tracebacks=True,
|
|
22
|
+
)
|
|
23
|
+
],
|
|
24
|
+
level=logging.INFO,
|
|
25
|
+
format="%(message)s",
|
|
26
|
+
datefmt="[%X]",
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
# SDK now lives in sdk/core.py - clean import from sdk package
|
|
8
30
|
from htmlgraph.agent_detection import detect_agent_name, get_agent_display_name
|
|
9
31
|
from htmlgraph.agents import AgentInterface
|
|
10
32
|
from htmlgraph.analytics import Analytics, DependencyAnalytics
|
|
33
|
+
from htmlgraph.atomic_ops import (
|
|
34
|
+
AtomicFileWriter,
|
|
35
|
+
DirectoryLocker,
|
|
36
|
+
atomic_rename,
|
|
37
|
+
cleanup_orphaned_temp_files,
|
|
38
|
+
safe_temp_file,
|
|
39
|
+
validate_atomic_write,
|
|
40
|
+
)
|
|
11
41
|
from htmlgraph.builders import BaseBuilder, FeatureBuilder, SpikeBuilder
|
|
12
42
|
from htmlgraph.collections import BaseCollection, FeatureCollection, SpikeCollection
|
|
13
43
|
from htmlgraph.context_analytics import ContextAnalytics, ContextUsage
|
|
44
|
+
from htmlgraph.decorators import RetryError, retry, retry_async
|
|
14
45
|
from htmlgraph.edge_index import EdgeIndex, EdgeRef
|
|
15
46
|
from htmlgraph.exceptions import (
|
|
16
47
|
ClaimConflictError,
|
|
@@ -55,9 +86,12 @@ from htmlgraph.orchestration import (
|
|
|
55
86
|
from htmlgraph.orchestrator_mode import OrchestratorMode, OrchestratorModeManager
|
|
56
87
|
from htmlgraph.parallel import AggregateResult, ParallelAnalysis, ParallelWorkflow
|
|
57
88
|
from htmlgraph.query_builder import Condition, Operator, QueryBuilder
|
|
89
|
+
from htmlgraph.reflection import ComputationalReflection, get_reflection_context
|
|
90
|
+
from htmlgraph.repo_hash import RepoHash
|
|
58
91
|
from htmlgraph.sdk import SDK
|
|
59
92
|
from htmlgraph.server import serve
|
|
60
93
|
from htmlgraph.session_manager import SessionManager
|
|
94
|
+
from htmlgraph.session_registry import SessionRegistry
|
|
61
95
|
from htmlgraph.types import (
|
|
62
96
|
ActiveWorkItem,
|
|
63
97
|
AggregateResultsDict,
|
|
@@ -84,7 +118,7 @@ from htmlgraph.types import (
|
|
|
84
118
|
)
|
|
85
119
|
from htmlgraph.work_type_utils import infer_work_type, infer_work_type_from_id
|
|
86
120
|
|
|
87
|
-
__version__ = "0.
|
|
121
|
+
__version__ = "0.27.5"
|
|
88
122
|
__all__ = [
|
|
89
123
|
# Exceptions
|
|
90
124
|
"HtmlGraphError",
|
|
@@ -92,6 +126,10 @@ __all__ = [
|
|
|
92
126
|
"SessionNotFoundError",
|
|
93
127
|
"ClaimConflictError",
|
|
94
128
|
"ValidationError",
|
|
129
|
+
"RetryError",
|
|
130
|
+
# Decorators
|
|
131
|
+
"retry",
|
|
132
|
+
"retry_async",
|
|
95
133
|
# Core models
|
|
96
134
|
"Node",
|
|
97
135
|
"Edge",
|
|
@@ -122,6 +160,8 @@ __all__ = [
|
|
|
122
160
|
"find_all",
|
|
123
161
|
"AgentInterface",
|
|
124
162
|
"SessionManager",
|
|
163
|
+
"SessionRegistry",
|
|
164
|
+
"RepoHash",
|
|
125
165
|
"SDK",
|
|
126
166
|
"Analytics", # Phase 2: Work Type Analytics
|
|
127
167
|
"DependencyAnalytics", # Advanced dependency-aware analytics
|
|
@@ -178,6 +218,9 @@ __all__ = [
|
|
|
178
218
|
# Active Learning Persistence
|
|
179
219
|
"LearningPersistence",
|
|
180
220
|
"auto_persist_on_session_end",
|
|
221
|
+
# Computational Reflection (pre-computed context injection)
|
|
222
|
+
"ComputationalReflection",
|
|
223
|
+
"get_reflection_context",
|
|
181
224
|
# Orchestrator Mode Management
|
|
182
225
|
"OrchestratorMode",
|
|
183
226
|
"OrchestratorModeManager",
|
|
@@ -186,4 +229,11 @@ __all__ = [
|
|
|
186
229
|
"get_results_by_task_id",
|
|
187
230
|
"parallel_delegate",
|
|
188
231
|
"generate_task_id",
|
|
232
|
+
# Atomic file operations (Phase 1.3: Session File Tracking)
|
|
233
|
+
"AtomicFileWriter",
|
|
234
|
+
"DirectoryLocker",
|
|
235
|
+
"atomic_rename",
|
|
236
|
+
"cleanup_orphaned_temp_files",
|
|
237
|
+
"safe_temp_file",
|
|
238
|
+
"validate_atomic_write",
|
|
189
239
|
]
|
htmlgraph/__init__.pyi
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Type stub for htmlgraph package.
|
|
3
|
+
|
|
4
|
+
This stub provides type information for mypy when the SDK class
|
|
5
|
+
is loaded dynamically via importlib at runtime.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from htmlgraph.agent_detection import detect_agent_name as detect_agent_name
|
|
9
|
+
from htmlgraph.agent_detection import get_agent_display_name as get_agent_display_name
|
|
10
|
+
from htmlgraph.agents import AgentInterface as AgentInterface
|
|
11
|
+
from htmlgraph.analytics import Analytics as Analytics
|
|
12
|
+
|
|
13
|
+
# Analytics
|
|
14
|
+
from htmlgraph.analytics import DependencyAnalytics as DependencyAnalytics
|
|
15
|
+
from htmlgraph.atomic_ops import AtomicFileWriter as AtomicFileWriter
|
|
16
|
+
from htmlgraph.atomic_ops import DirectoryLocker as DirectoryLocker
|
|
17
|
+
from htmlgraph.atomic_ops import atomic_rename as atomic_rename
|
|
18
|
+
from htmlgraph.atomic_ops import (
|
|
19
|
+
cleanup_orphaned_temp_files as cleanup_orphaned_temp_files,
|
|
20
|
+
)
|
|
21
|
+
from htmlgraph.atomic_ops import safe_temp_file as safe_temp_file
|
|
22
|
+
from htmlgraph.atomic_ops import validate_atomic_write as validate_atomic_write
|
|
23
|
+
from htmlgraph.builders import BaseBuilder as BaseBuilder
|
|
24
|
+
from htmlgraph.builders import FeatureBuilder as FeatureBuilder
|
|
25
|
+
from htmlgraph.builders import SpikeBuilder as SpikeBuilder
|
|
26
|
+
from htmlgraph.collections import BaseCollection as BaseCollection
|
|
27
|
+
|
|
28
|
+
# Collections
|
|
29
|
+
from htmlgraph.collections import FeatureCollection as FeatureCollection
|
|
30
|
+
from htmlgraph.collections import SpikeCollection as SpikeCollection
|
|
31
|
+
from htmlgraph.context_analytics import ContextAnalytics as ContextAnalytics
|
|
32
|
+
from htmlgraph.context_analytics import ContextUsage as ContextUsage
|
|
33
|
+
from htmlgraph.decorators import RetryError as RetryError
|
|
34
|
+
from htmlgraph.decorators import retry as retry
|
|
35
|
+
from htmlgraph.decorators import retry_async as retry_async
|
|
36
|
+
from htmlgraph.edge_index import EdgeIndex as EdgeIndex
|
|
37
|
+
from htmlgraph.edge_index import EdgeRef as EdgeRef
|
|
38
|
+
from htmlgraph.exceptions import ClaimConflictError as ClaimConflictError
|
|
39
|
+
from htmlgraph.exceptions import HtmlGraphError as HtmlGraphError
|
|
40
|
+
from htmlgraph.exceptions import NodeNotFoundError as NodeNotFoundError
|
|
41
|
+
from htmlgraph.exceptions import SessionNotFoundError as SessionNotFoundError
|
|
42
|
+
from htmlgraph.exceptions import ValidationError as ValidationError
|
|
43
|
+
from htmlgraph.find_api import FindAPI as FindAPI
|
|
44
|
+
from htmlgraph.find_api import find as find
|
|
45
|
+
from htmlgraph.find_api import find_all as find_all
|
|
46
|
+
from htmlgraph.graph import CompiledQuery as CompiledQuery
|
|
47
|
+
from htmlgraph.graph import HtmlGraph as HtmlGraph
|
|
48
|
+
from htmlgraph.ids import generate_hierarchical_id as generate_hierarchical_id
|
|
49
|
+
from htmlgraph.ids import generate_id as generate_id
|
|
50
|
+
from htmlgraph.ids import is_legacy_id as is_legacy_id
|
|
51
|
+
from htmlgraph.ids import is_valid_id as is_valid_id
|
|
52
|
+
from htmlgraph.ids import parse_id as parse_id
|
|
53
|
+
from htmlgraph.learning import LearningPersistence as LearningPersistence
|
|
54
|
+
from htmlgraph.learning import (
|
|
55
|
+
auto_persist_on_session_end as auto_persist_on_session_end,
|
|
56
|
+
)
|
|
57
|
+
from htmlgraph.models import ActivityEntry as ActivityEntry
|
|
58
|
+
from htmlgraph.models import AggregatedMetric as AggregatedMetric
|
|
59
|
+
from htmlgraph.models import Chore as Chore
|
|
60
|
+
from htmlgraph.models import ContextSnapshot as ContextSnapshot
|
|
61
|
+
from htmlgraph.models import Edge as Edge
|
|
62
|
+
from htmlgraph.models import Graph as Graph
|
|
63
|
+
from htmlgraph.models import MaintenanceType as MaintenanceType
|
|
64
|
+
from htmlgraph.models import Node as Node
|
|
65
|
+
from htmlgraph.models import Pattern as Pattern
|
|
66
|
+
from htmlgraph.models import Session as Session
|
|
67
|
+
from htmlgraph.models import SessionInsight as SessionInsight
|
|
68
|
+
from htmlgraph.models import Spike as Spike
|
|
69
|
+
from htmlgraph.models import SpikeType as SpikeType
|
|
70
|
+
from htmlgraph.models import Step as Step
|
|
71
|
+
from htmlgraph.models import WorkType as WorkType
|
|
72
|
+
from htmlgraph.orchestration import delegate_with_id as delegate_with_id
|
|
73
|
+
from htmlgraph.orchestration import generate_task_id as generate_task_id
|
|
74
|
+
from htmlgraph.orchestration import get_results_by_task_id as get_results_by_task_id
|
|
75
|
+
from htmlgraph.orchestration import parallel_delegate as parallel_delegate
|
|
76
|
+
from htmlgraph.orchestrator_mode import OrchestratorMode as OrchestratorMode
|
|
77
|
+
from htmlgraph.orchestrator_mode import (
|
|
78
|
+
OrchestratorModeManager as OrchestratorModeManager,
|
|
79
|
+
)
|
|
80
|
+
from htmlgraph.parallel import AggregateResult as AggregateResult
|
|
81
|
+
from htmlgraph.parallel import ParallelAnalysis as ParallelAnalysis
|
|
82
|
+
from htmlgraph.parallel import ParallelWorkflow as ParallelWorkflow
|
|
83
|
+
from htmlgraph.query_builder import Condition as Condition
|
|
84
|
+
from htmlgraph.query_builder import Operator as Operator
|
|
85
|
+
from htmlgraph.query_builder import QueryBuilder as QueryBuilder
|
|
86
|
+
from htmlgraph.reflection import ComputationalReflection as ComputationalReflection
|
|
87
|
+
from htmlgraph.reflection import get_reflection_context as get_reflection_context
|
|
88
|
+
from htmlgraph.repo_hash import RepoHash as RepoHash
|
|
89
|
+
from htmlgraph.sdk.core import SDK as SDK
|
|
90
|
+
from htmlgraph.server import serve as serve
|
|
91
|
+
from htmlgraph.session_manager import SessionManager as SessionManager
|
|
92
|
+
from htmlgraph.session_registry import SessionRegistry as SessionRegistry
|
|
93
|
+
from htmlgraph.types import ActiveWorkItem as ActiveWorkItem
|
|
94
|
+
from htmlgraph.types import AggregateResultsDict as AggregateResultsDict
|
|
95
|
+
from htmlgraph.types import BottleneckDict as BottleneckDict
|
|
96
|
+
from htmlgraph.types import FeatureSummary as FeatureSummary
|
|
97
|
+
from htmlgraph.types import HighRiskTask as HighRiskTask
|
|
98
|
+
from htmlgraph.types import ImpactAnalysisDict as ImpactAnalysisDict
|
|
99
|
+
from htmlgraph.types import OrchestrationResult as OrchestrationResult
|
|
100
|
+
from htmlgraph.types import ParallelGuidelines as ParallelGuidelines
|
|
101
|
+
from htmlgraph.types import ParallelPlanResult as ParallelPlanResult
|
|
102
|
+
from htmlgraph.types import ParallelWorkInfo as ParallelWorkInfo
|
|
103
|
+
from htmlgraph.types import PlanningContext as PlanningContext
|
|
104
|
+
from htmlgraph.types import ProjectStatus as ProjectStatus
|
|
105
|
+
from htmlgraph.types import RiskAssessmentDict as RiskAssessmentDict
|
|
106
|
+
from htmlgraph.types import SessionAnalytics as SessionAnalytics
|
|
107
|
+
from htmlgraph.types import SessionStartInfo as SessionStartInfo
|
|
108
|
+
from htmlgraph.types import SessionSummary as SessionSummary
|
|
109
|
+
from htmlgraph.types import SmartPlanResult as SmartPlanResult
|
|
110
|
+
from htmlgraph.types import SubagentPrompt as SubagentPrompt
|
|
111
|
+
from htmlgraph.types import TaskPrompt as TaskPrompt
|
|
112
|
+
from htmlgraph.types import TrackCreationResult as TrackCreationResult
|
|
113
|
+
from htmlgraph.types import WorkQueueItem as WorkQueueItem
|
|
114
|
+
from htmlgraph.types import WorkRecommendation as WorkRecommendation
|
|
115
|
+
from htmlgraph.work_type_utils import infer_work_type as infer_work_type
|
|
116
|
+
from htmlgraph.work_type_utils import infer_work_type_from_id as infer_work_type_from_id
|
|
117
|
+
|
|
118
|
+
__version__: str
|
|
119
|
+
|
|
120
|
+
# SDK is imported from htmlgraph.sdk.core (see import above)
|
|
121
|
+
# Re-exported here for backward compatibility
|
|
122
|
+
|
|
123
|
+
__all__: list[str]
|
htmlgraph/agent_detection.py
CHANGED
|
@@ -14,34 +14,48 @@ def detect_agent_name() -> str:
|
|
|
14
14
|
Detect the current agent/interface name based on environment.
|
|
15
15
|
|
|
16
16
|
Returns:
|
|
17
|
-
Agent name (e.g., "claude", "gemini", "cli")
|
|
17
|
+
Agent name (e.g., "claude-code", "gemini", "cli")
|
|
18
18
|
|
|
19
19
|
Detection order:
|
|
20
20
|
1. HTMLGRAPH_AGENT environment variable (explicit override)
|
|
21
|
-
2.
|
|
22
|
-
3. Gemini detection (GEMINI environment markers)
|
|
23
|
-
4.
|
|
21
|
+
2. HTMLGRAPH_PARENT_AGENT (set by hooks for session context)
|
|
22
|
+
3. Gemini detection (GEMINI environment markers) - checked before Claude to allow override
|
|
23
|
+
4. Claude Code detection (CLAUDECODE env var, parent process)
|
|
24
|
+
5. Fall back to "cli" only if no AI agent detected
|
|
24
25
|
"""
|
|
25
26
|
# 1. Explicit override
|
|
26
27
|
explicit = os.environ.get("HTMLGRAPH_AGENT")
|
|
27
28
|
if explicit:
|
|
28
29
|
return explicit.strip()
|
|
29
30
|
|
|
30
|
-
# 2.
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
# 2. Parent agent context (set by HtmlGraph hooks)
|
|
32
|
+
parent_agent = os.environ.get("HTMLGRAPH_PARENT_AGENT")
|
|
33
|
+
if parent_agent:
|
|
34
|
+
return parent_agent.strip()
|
|
33
35
|
|
|
34
|
-
# 3. Gemini detection
|
|
36
|
+
# 3. Gemini detection (checked before Claude to allow explicit override)
|
|
35
37
|
if _is_gemini():
|
|
36
38
|
return "gemini"
|
|
37
39
|
|
|
38
|
-
# 4.
|
|
40
|
+
# 4. Claude Code detection
|
|
41
|
+
if _is_claude_code():
|
|
42
|
+
return "claude-code"
|
|
43
|
+
|
|
44
|
+
# 5. Default to CLI only if no AI agent detected
|
|
39
45
|
return "cli"
|
|
40
46
|
|
|
41
47
|
|
|
42
48
|
def _is_claude_code() -> bool:
|
|
43
49
|
"""Check if running in Claude Code environment."""
|
|
44
50
|
# Check for Claude Code environment variables
|
|
51
|
+
# CLAUDECODE=1 is set by Claude Code CLI
|
|
52
|
+
if os.environ.get("CLAUDECODE"):
|
|
53
|
+
return True
|
|
54
|
+
|
|
55
|
+
# CLAUDE_CODE_ENTRYPOINT indicates the entry point (cli, api, etc.)
|
|
56
|
+
if os.environ.get("CLAUDE_CODE_ENTRYPOINT"):
|
|
57
|
+
return True
|
|
58
|
+
|
|
45
59
|
if os.environ.get("CLAUDE_CODE_VERSION"):
|
|
46
60
|
return True
|
|
47
61
|
|
|
@@ -100,12 +114,14 @@ def get_agent_display_name(agent: str) -> str:
|
|
|
100
114
|
"""
|
|
101
115
|
display_names = {
|
|
102
116
|
"claude": "Claude",
|
|
103
|
-
"claude-code": "Claude",
|
|
117
|
+
"claude-code": "Claude Code",
|
|
104
118
|
"gemini": "Gemini",
|
|
105
119
|
"cli": "CLI",
|
|
106
120
|
"haiku": "Haiku",
|
|
107
121
|
"opus": "Opus",
|
|
108
122
|
"sonnet": "Sonnet",
|
|
123
|
+
"claude-opus-4-5-20251101": "Claude Opus 4.5",
|
|
124
|
+
"claude-sonnet-4-20250514": "Claude Sonnet 4",
|
|
109
125
|
}
|
|
110
126
|
|
|
111
127
|
return display_names.get(agent.lower(), agent.title())
|
htmlgraph/agent_registry.py
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
"""
|
|
2
4
|
Agent Registry - Manages agent capabilities and routing.
|
|
3
5
|
|
|
@@ -7,7 +9,6 @@ Provides:
|
|
|
7
9
|
- Capability matching for task routing
|
|
8
10
|
"""
|
|
9
11
|
|
|
10
|
-
from __future__ import annotations
|
|
11
12
|
|
|
12
13
|
import json
|
|
13
14
|
from dataclasses import dataclass, field
|
htmlgraph/analytics/__init__.py
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Analytics modules for HtmlGraph.
|
|
3
3
|
|
|
4
|
-
Provides work type analysis, dependency analytics,
|
|
4
|
+
Provides work type analysis, dependency analytics, cross-session analytics, CLI analytics,
|
|
5
|
+
and cost attribution analysis for OTEL ROI.
|
|
5
6
|
"""
|
|
6
7
|
|
|
8
|
+
from htmlgraph.analytics.cost_analyzer import CostAnalyzer
|
|
9
|
+
from htmlgraph.analytics.cost_reporter import CostReporter
|
|
10
|
+
from htmlgraph.analytics.cross_session import CrossSessionAnalytics
|
|
7
11
|
from htmlgraph.analytics.dependency import DependencyAnalytics
|
|
8
12
|
from htmlgraph.analytics.work_type import Analytics
|
|
9
13
|
|
|
10
14
|
__all__ = [
|
|
11
15
|
"Analytics",
|
|
12
16
|
"DependencyAnalytics",
|
|
17
|
+
"CrossSessionAnalytics",
|
|
18
|
+
"CostAnalyzer",
|
|
19
|
+
"CostReporter",
|
|
13
20
|
]
|
htmlgraph/analytics/cli.py
CHANGED
|
@@ -5,6 +5,8 @@ This module provides the `htmlgraph analytics` command for analyzing work patter
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
import argparse
|
|
8
|
+
from collections.abc import Iterator
|
|
9
|
+
from contextlib import AbstractContextManager, nullcontext
|
|
8
10
|
from pathlib import Path
|
|
9
11
|
|
|
10
12
|
from rich import box
|
|
@@ -19,6 +21,7 @@ from htmlgraph.converter import html_to_session
|
|
|
19
21
|
def cmd_analytics(args: argparse.Namespace) -> int:
|
|
20
22
|
"""Display work type analytics with beautiful rich formatting."""
|
|
21
23
|
console = Console()
|
|
24
|
+
quiet = getattr(args, "quiet", False)
|
|
22
25
|
|
|
23
26
|
try:
|
|
24
27
|
sdk = SDK(agent=args.agent or "cli")
|
|
@@ -46,21 +49,67 @@ def cmd_analytics(args: argparse.Namespace) -> int:
|
|
|
46
49
|
# Determine scope
|
|
47
50
|
if args.session_id:
|
|
48
51
|
# Single session analysis
|
|
49
|
-
_display_session_analytics(
|
|
52
|
+
_display_session_analytics(
|
|
53
|
+
console, sdk, args.session_id, args.graph_dir, quiet=quiet
|
|
54
|
+
)
|
|
50
55
|
elif args.recent:
|
|
51
56
|
# Recent sessions
|
|
52
57
|
_display_recent_sessions(
|
|
53
|
-
console, sdk, session_files[: args.recent], args.graph_dir
|
|
58
|
+
console, sdk, session_files[: args.recent], args.graph_dir, quiet=quiet
|
|
54
59
|
)
|
|
55
60
|
else:
|
|
56
61
|
# Project-wide overview
|
|
57
|
-
_display_project_analytics(
|
|
62
|
+
_display_project_analytics(
|
|
63
|
+
console, sdk, session_files, args.graph_dir, quiet=quiet
|
|
64
|
+
)
|
|
58
65
|
|
|
59
66
|
return 0
|
|
60
67
|
|
|
61
68
|
|
|
69
|
+
def _status_context(
|
|
70
|
+
console: Console, quiet: bool, message: str
|
|
71
|
+
) -> AbstractContextManager[object]:
|
|
72
|
+
if quiet:
|
|
73
|
+
return nullcontext()
|
|
74
|
+
return console.status(message)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def _iter_with_progress(
|
|
78
|
+
console: Console, quiet: bool, items: list[Path], description: str
|
|
79
|
+
) -> Iterator[Path]:
|
|
80
|
+
if quiet:
|
|
81
|
+
for item in items:
|
|
82
|
+
yield item
|
|
83
|
+
return
|
|
84
|
+
try:
|
|
85
|
+
from rich.progress import (
|
|
86
|
+
BarColumn,
|
|
87
|
+
Progress,
|
|
88
|
+
SpinnerColumn,
|
|
89
|
+
TextColumn,
|
|
90
|
+
TimeElapsedColumn,
|
|
91
|
+
)
|
|
92
|
+
except Exception:
|
|
93
|
+
for item in items:
|
|
94
|
+
yield item
|
|
95
|
+
return
|
|
96
|
+
|
|
97
|
+
with Progress(
|
|
98
|
+
SpinnerColumn(),
|
|
99
|
+
TextColumn("{task.description}"),
|
|
100
|
+
BarColumn(),
|
|
101
|
+
TimeElapsedColumn(),
|
|
102
|
+
console=console,
|
|
103
|
+
transient=True,
|
|
104
|
+
) as progress:
|
|
105
|
+
task_id = progress.add_task(description, total=len(items))
|
|
106
|
+
for item in items:
|
|
107
|
+
yield item
|
|
108
|
+
progress.advance(task_id)
|
|
109
|
+
|
|
110
|
+
|
|
62
111
|
def _display_session_analytics(
|
|
63
|
-
console: Console, sdk: SDK, session_id: str, graph_dir: str
|
|
112
|
+
console: Console, sdk: "SDK", session_id: str, graph_dir: str, quiet: bool
|
|
64
113
|
) -> None:
|
|
65
114
|
"""Display analytics for a single session."""
|
|
66
115
|
from htmlgraph.converter import html_to_session
|
|
@@ -72,19 +121,23 @@ def _display_session_analytics(
|
|
|
72
121
|
return
|
|
73
122
|
|
|
74
123
|
try:
|
|
75
|
-
session
|
|
124
|
+
with _status_context(console, quiet, "Loading session data..."):
|
|
125
|
+
session = html_to_session(session_path)
|
|
76
126
|
except Exception as e:
|
|
77
127
|
console.print(f"[red]Error loading session: {e}[/red]")
|
|
78
128
|
return
|
|
79
129
|
|
|
80
130
|
# Get analytics
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
131
|
+
with _status_context(console, quiet, "Computing session analytics..."):
|
|
132
|
+
dist = sdk.analytics.work_type_distribution(session_id=session_id)
|
|
133
|
+
ratio = sdk.analytics.spike_to_feature_ratio(session_id=session_id)
|
|
134
|
+
burden = sdk.analytics.maintenance_burden(session_id=session_id)
|
|
135
|
+
primary = sdk.analytics.calculate_session_primary_work_type(session_id)
|
|
136
|
+
breakdown = sdk.analytics.calculate_session_work_breakdown(session_id)
|
|
137
|
+
total_events = sum(breakdown.values()) if breakdown else session.event_count
|
|
138
|
+
transition_metrics = sdk.analytics.transition_time_metrics(
|
|
139
|
+
session_id=session_id
|
|
140
|
+
)
|
|
88
141
|
|
|
89
142
|
# Header panel
|
|
90
143
|
header = Panel(
|
|
@@ -167,7 +220,11 @@ def _display_session_analytics(
|
|
|
167
220
|
|
|
168
221
|
|
|
169
222
|
def _display_recent_sessions(
|
|
170
|
-
console: Console,
|
|
223
|
+
console: Console,
|
|
224
|
+
sdk: "SDK",
|
|
225
|
+
session_files: list[Path],
|
|
226
|
+
graph_dir: str,
|
|
227
|
+
quiet: bool,
|
|
171
228
|
) -> None:
|
|
172
229
|
"""Display analytics for recent sessions."""
|
|
173
230
|
console.print(
|
|
@@ -188,7 +245,9 @@ def _display_recent_sessions(
|
|
|
188
245
|
table.add_column("Primary Type", style="yellow")
|
|
189
246
|
table.add_column("Spike Ratio", justify="right")
|
|
190
247
|
|
|
191
|
-
for session_path in
|
|
248
|
+
for session_path in _iter_with_progress(
|
|
249
|
+
console, quiet, session_files, "Processing sessions"
|
|
250
|
+
):
|
|
192
251
|
try:
|
|
193
252
|
session = html_to_session(session_path)
|
|
194
253
|
session_id = session.id
|
|
@@ -226,7 +285,11 @@ def _display_recent_sessions(
|
|
|
226
285
|
|
|
227
286
|
|
|
228
287
|
def _display_project_analytics(
|
|
229
|
-
console: Console,
|
|
288
|
+
console: Console,
|
|
289
|
+
sdk: "SDK",
|
|
290
|
+
session_files: list[Path],
|
|
291
|
+
graph_dir: str,
|
|
292
|
+
quiet: bool,
|
|
230
293
|
) -> None:
|
|
231
294
|
"""Display project-wide analytics."""
|
|
232
295
|
console.print(
|
|
@@ -240,10 +303,11 @@ def _display_project_analytics(
|
|
|
240
303
|
console.print()
|
|
241
304
|
|
|
242
305
|
# Get project-wide metrics
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
306
|
+
with _status_context(console, quiet, "Computing project analytics..."):
|
|
307
|
+
all_dist = sdk.analytics.work_type_distribution()
|
|
308
|
+
all_ratio = sdk.analytics.spike_to_feature_ratio()
|
|
309
|
+
all_burden = sdk.analytics.maintenance_burden()
|
|
310
|
+
all_transition = sdk.analytics.transition_time_metrics()
|
|
247
311
|
|
|
248
312
|
# Work distribution table
|
|
249
313
|
if all_dist:
|
|
@@ -341,7 +405,9 @@ def _display_project_analytics(
|
|
|
341
405
|
console.print("[bold]Recent Sessions:[/bold]")
|
|
342
406
|
recent_files = session_files[:5]
|
|
343
407
|
|
|
344
|
-
for session_path in
|
|
408
|
+
for session_path in _iter_with_progress(
|
|
409
|
+
console, quiet, recent_files, "Loading recent sessions"
|
|
410
|
+
):
|
|
345
411
|
try:
|
|
346
412
|
session = html_to_session(session_path)
|
|
347
413
|
primary = (
|