shellbrain 0.1.26__tar.gz → 0.1.27__tar.gz
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.
- {shellbrain-0.1.26 → shellbrain-0.1.27}/PKG-INFO +1 -1
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/cli/main.py +12 -7
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/metrics/artifacts.py +18 -1
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/metrics/render_html.py +260 -16
- {shellbrain-0.1.26 → shellbrain-0.1.27}/pyproject.toml +1 -1
- {shellbrain-0.1.26 → shellbrain-0.1.27}/shellbrain.egg-info/PKG-INFO +1 -1
- {shellbrain-0.1.26 → shellbrain-0.1.27}/README.md +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/__init__.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/__main__.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/boot/__init__.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/boot/_dsn_resolution.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/boot/admin_db.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/boot/config.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/boot/create_policy.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/boot/db.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/boot/embeddings.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/boot/home.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/boot/migrations.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/boot/read_policy.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/boot/repos.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/boot/retrieval.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/boot/thresholds.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/boot/update_policy.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/boot/use_cases.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/config/__init__.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/config/defaults/create_policy.yaml +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/config/defaults/read_policy.yaml +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/config/defaults/runtime.yaml +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/config/defaults/thresholds.yaml +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/config/defaults/update_policy.yaml +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/config/loader.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/__init__.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/contracts/__init__.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/contracts/concepts.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/contracts/errors.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/contracts/requests.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/contracts/responses.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/entities/__init__.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/entities/associations.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/entities/concepts.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/entities/episodes.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/entities/evidence.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/entities/facts.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/entities/guidance.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/entities/identity.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/entities/memory.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/entities/runtime_context.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/entities/session_state.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/entities/telemetry.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/entities/utility.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/interfaces/__init__.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/interfaces/clock.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/interfaces/config.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/interfaces/embeddings.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/interfaces/idgen.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/interfaces/repos.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/interfaces/retrieval.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/interfaces/session_state_store.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/interfaces/unit_of_work.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/policies/__init__.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/policies/_shared/__init__.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/policies/_shared/executor.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/policies/_shared/side_effects.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/policies/create_policy/__init__.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/policies/create_policy/pipeline.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/policies/read_policy/__init__.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/policies/read_policy/bm25.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/policies/read_policy/context_pack_builder.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/policies/read_policy/expansion.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/policies/read_policy/fusion_rrf.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/policies/read_policy/lexical_query.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/policies/read_policy/pipeline.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/policies/read_policy/scoring.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/policies/read_policy/seed_retrieval.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/policies/update_policy/__init__.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/policies/update_policy/pipeline.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/use_cases/__init__.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/use_cases/build_guidance.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/use_cases/create_memory.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/use_cases/manage_concepts.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/use_cases/manage_session_state.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/use_cases/read_concepts.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/use_cases/read_memory.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/use_cases/record_episode_sync_telemetry.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/use_cases/record_model_usage_telemetry.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/use_cases/record_operation_telemetry.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/use_cases/sync_episode.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/use_cases/update_memory.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/migrations/__init__.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/migrations/env.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/migrations/versions/20260226_0001_initial_schema.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/migrations/versions/20260312_0002_add_hard_invariants.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/migrations/versions/20260312_0003_drop_create_confidence.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/migrations/versions/20260313_0004_episode_sync_hardening.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/migrations/versions/20260313_0005_evidence_episode_event_refs.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/migrations/versions/20260318_0006_usage_telemetry_schema.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/migrations/versions/20260319_0007_identity_session_guidance.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/migrations/versions/20260320_0008_instance_metadata_and_backup_safety.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/migrations/versions/20260410_0009_frontier_memory_family.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/migrations/versions/20260414_0010_model_usage_telemetry.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/migrations/versions/20260414_0011_usage_problem_tokens_multi_solution_metrics.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/migrations/versions/20260415_0012_read_pack_cost_and_read_roi.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/migrations/versions/20260421_0013_concept_context_graph.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/migrations/versions/20260422_0014_concept_read_telemetry.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/migrations/versions/20260422_0015_problem_runs.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/migrations/versions/__init__.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/onboarding_assets/__init__.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/onboarding_assets/claude/CLAUDE.md +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/onboarding_assets/claude/skills/shellbrain-session-start/SKILL.md +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/onboarding_assets/claude/skills/shellbrain-usage-review/SKILL.md +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/onboarding_assets/codex/AGENTS.md +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/onboarding_assets/codex/shellbrain-session-start/SKILL.md +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/onboarding_assets/codex/shellbrain-session-start/agents/openai.yaml +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/onboarding_assets/codex/shellbrain-session-start/assets/shellbrain-large.svg +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/onboarding_assets/codex/shellbrain-session-start/assets/shellbrain-small.svg +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/onboarding_assets/codex/shellbrain-session-start/assets/shellbrain_logo.png +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/onboarding_assets/codex/shellbrain-session-start/references/request-shapes.md +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/onboarding_assets/codex/shellbrain-session-start/references/session-workflow.md +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/onboarding_assets/codex/shellbrain-usage-review/SKILL.md +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/onboarding_assets/codex/shellbrain-usage-review/agents/openai.yaml +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/onboarding_assets/codex/shellbrain-usage-review/assets/shellbrain-small.svg +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/onboarding_assets/codex/shellbrain-usage-review/assets/shellbrain_logo.png +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/onboarding_assets/cursor/skills/shellbrain-session-start/SKILL.md +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/onboarding_assets/cursor/skills/shellbrain-usage-review/SKILL.md +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/__init__.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/admin/__init__.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/admin/agent_behavior_analysis.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/admin/analytics.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/admin/analytics_diagnostics.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/admin/analytics_queries.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/admin/backup.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/admin/destructive_guard.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/admin/doctor.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/admin/external_runtime.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/admin/init.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/admin/init_errors.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/admin/instance_guard.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/admin/machine_state.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/admin/managed_runtime.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/admin/model_usage_backfill.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/admin/privileges.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/admin/repo_state.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/admin/restore.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/admin/storage_setup.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/admin/upgrade.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/cli/__init__.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/cli/handlers.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/cli/hydration.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/cli/presenter_json.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/cli/schema_validation.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/db/__init__.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/db/engine.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/db/models/__init__.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/db/models/associations.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/db/models/concepts.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/db/models/episodes.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/db/models/evidence.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/db/models/experiences.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/db/models/instance_metadata.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/db/models/memories.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/db/models/metadata.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/db/models/problem_runs.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/db/models/registry.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/db/models/telemetry.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/db/models/utility.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/db/models/views.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/db/repos/__init__.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/db/repos/relational/__init__.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/db/repos/relational/associations_repo.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/db/repos/relational/concepts_repo.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/db/repos/relational/episodes_repo.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/db/repos/relational/evidence_repo.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/db/repos/relational/experiences_repo.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/db/repos/relational/memories_repo.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/db/repos/relational/read_policy_repo.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/db/repos/relational/telemetry_repo.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/db/repos/relational/utility_repo.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/db/repos/semantic/__init__.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/db/repos/semantic/keyword_retrieval_repo.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/db/repos/semantic/semantic_retrieval_repo.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/db/session.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/db/uow.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/embeddings/__init__.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/embeddings/local_provider.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/embeddings/query_vector_search.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/episodes/__init__.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/episodes/claude_code.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/episodes/codex.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/episodes/cursor.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/episodes/launcher.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/episodes/model_usage.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/episodes/normalization.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/episodes/poller.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/episodes/poller_lock.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/episodes/source_discovery.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/episodes/tool_filter.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/identity/__init__.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/identity/claude_hook_install.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/identity/claude_runtime.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/identity/codex_runtime.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/identity/compatibility.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/identity/cursor_statusline.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/identity/resolver.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/metrics/__init__.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/metrics/browser.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/metrics/pager.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/metrics/queries.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/metrics/service.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/onboarding/__init__.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/onboarding/host_assets.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/session_state/__init__.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/session_state/file_store.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/telemetry/__init__.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/telemetry/operation_summary.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/telemetry/session_selection.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/telemetry/sync_summary.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/validation/__init__.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/validation/integrity_validation.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/app/periphery/validation/semantic_validation.py +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/setup.cfg +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/shellbrain.egg-info/SOURCES.txt +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/shellbrain.egg-info/dependency_links.txt +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/shellbrain.egg-info/entry_points.txt +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/shellbrain.egg-info/requires.txt +0 -0
- {shellbrain-0.1.26 → shellbrain-0.1.27}/shellbrain.egg-info/top_level.txt +0 -0
|
@@ -260,7 +260,7 @@ _BACKFILL_TOKEN_USAGE_HELP = dedent(
|
|
|
260
260
|
|
|
261
261
|
_METRICS_HELP = dedent(
|
|
262
262
|
"""\
|
|
263
|
-
Generate lightweight metrics snapshots, write local artifacts, and
|
|
263
|
+
Generate lightweight metrics snapshots, write local artifacts, and open one browser dashboard that switches repos with arrow keys.
|
|
264
264
|
|
|
265
265
|
Example:
|
|
266
266
|
shellbrain metrics
|
|
@@ -385,7 +385,7 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
385
385
|
metrics_parser = subparsers.add_parser(
|
|
386
386
|
"metrics",
|
|
387
387
|
help="Browse Shellbrain metrics across repos.",
|
|
388
|
-
description="Generate local metrics snapshots and
|
|
388
|
+
description="Generate local metrics snapshots and open one browser dashboard for all repos.",
|
|
389
389
|
epilog=_METRICS_HELP,
|
|
390
390
|
formatter_class=_HelpFormatter,
|
|
391
391
|
)
|
|
@@ -869,10 +869,9 @@ def _run_metrics_command(args: argparse.Namespace) -> int:
|
|
|
869
869
|
from app.boot.admin_db import get_optional_admin_db_dsn
|
|
870
870
|
from app.boot.db import get_optional_db_dsn
|
|
871
871
|
from app.periphery.db.engine import get_engine
|
|
872
|
-
from app.periphery.metrics.artifacts import write_metrics_artifacts
|
|
872
|
+
from app.periphery.metrics.artifacts import write_metrics_artifacts, write_metrics_index_artifact
|
|
873
873
|
from app.periphery.metrics.browser import open_metrics_dashboard
|
|
874
|
-
from app.periphery.metrics.
|
|
875
|
-
from app.periphery.metrics.render_html import render_metrics_dashboard
|
|
874
|
+
from app.periphery.metrics.render_html import render_metrics_browser_dashboard, render_metrics_dashboard
|
|
876
875
|
from app.periphery.metrics.service import build_metrics_snapshot, list_metrics_repo_ids
|
|
877
876
|
|
|
878
877
|
if bool(getattr(args, "repo_id", None) or getattr(args, "repo_root", None) or getattr(args, "no_sync", False)):
|
|
@@ -901,11 +900,17 @@ def _run_metrics_command(args: argparse.Namespace) -> int:
|
|
|
901
900
|
paths = write_metrics_artifacts(repo_id=repo_id, snapshot=snapshot, html=html)
|
|
902
901
|
entries.append({"snapshot": snapshot, "paths": paths})
|
|
903
902
|
|
|
903
|
+
overview_path = write_metrics_index_artifact(
|
|
904
|
+
html=render_metrics_browser_dashboard([entry["snapshot"] for entry in entries])
|
|
905
|
+
)
|
|
906
|
+
opened_dashboard = bool(open_metrics_dashboard(overview_path))
|
|
904
907
|
print(f"Generated Shellbrain metrics for {len(entries)} repos")
|
|
905
908
|
print(f"Window: last {window_days} days")
|
|
906
909
|
print("Artifacts: updated in place")
|
|
907
|
-
|
|
908
|
-
|
|
910
|
+
if opened_dashboard:
|
|
911
|
+
print("Browser: opened dashboard; use left/right arrow keys in the browser to switch repos")
|
|
912
|
+
else:
|
|
913
|
+
print(f"Browser: could not open automatically; open {overview_path}")
|
|
909
914
|
return 0
|
|
910
915
|
except (RuntimeError, ValueError) as exc:
|
|
911
916
|
print(str(exc), file=sys.stderr)
|
|
@@ -14,12 +14,18 @@ from app.boot.home import get_shellbrain_home
|
|
|
14
14
|
_NON_ALNUM = re.compile(r"[^a-z0-9]+")
|
|
15
15
|
|
|
16
16
|
|
|
17
|
+
def get_metrics_root_dir() -> Path:
|
|
18
|
+
"""Return the machine-owned root directory for metrics browser artifacts."""
|
|
19
|
+
|
|
20
|
+
return get_shellbrain_home() / "reports" / "metrics"
|
|
21
|
+
|
|
22
|
+
|
|
17
23
|
def get_metrics_artifact_dir(*, repo_id: str) -> Path:
|
|
18
24
|
"""Return the machine-owned artifact directory for one repo's metrics outputs."""
|
|
19
25
|
|
|
20
26
|
normalized = _NON_ALNUM.sub("-", repo_id.lower()).strip("-") or "repo"
|
|
21
27
|
digest = hashlib.sha1(repo_id.encode("utf-8")).hexdigest()[:8]
|
|
22
|
-
return
|
|
28
|
+
return get_metrics_root_dir() / f"{normalized}-{digest}"
|
|
23
29
|
|
|
24
30
|
|
|
25
31
|
def write_metrics_artifacts(*, repo_id: str, snapshot: dict[str, Any], html: str) -> dict[str, Path]:
|
|
@@ -42,3 +48,14 @@ def write_metrics_artifacts(*, repo_id: str, snapshot: dict[str, Any], html: str
|
|
|
42
48
|
"md_path": md_path,
|
|
43
49
|
"html_path": html_path,
|
|
44
50
|
}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def write_metrics_index_artifact(*, html: str) -> Path:
|
|
54
|
+
"""Write the combined browser dashboard for all repo metrics snapshots."""
|
|
55
|
+
|
|
56
|
+
artifact_dir = get_metrics_root_dir()
|
|
57
|
+
artifact_dir.mkdir(parents=True, exist_ok=True)
|
|
58
|
+
|
|
59
|
+
html_path = artifact_dir / "index.html"
|
|
60
|
+
html_path.write_text(html, encoding="utf-8")
|
|
61
|
+
return html_path
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
from html import escape
|
|
6
|
-
from typing import Any
|
|
6
|
+
from typing import Any, Sequence
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
_PAGE_CSS = """
|
|
@@ -220,9 +220,266 @@ body {
|
|
|
220
220
|
"""
|
|
221
221
|
|
|
222
222
|
|
|
223
|
+
_BROWSER_CSS = """
|
|
224
|
+
.browser-shell {
|
|
225
|
+
max-width: 1440px;
|
|
226
|
+
margin: 0 auto;
|
|
227
|
+
padding: 24px 28px 64px;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
.browser-masthead {
|
|
231
|
+
display: flex;
|
|
232
|
+
justify-content: space-between;
|
|
233
|
+
gap: 24px;
|
|
234
|
+
align-items: flex-end;
|
|
235
|
+
padding-bottom: 18px;
|
|
236
|
+
border-bottom: 1px solid var(--border);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.browser-masthead h1 {
|
|
240
|
+
font-size: 28px;
|
|
241
|
+
font-weight: 700;
|
|
242
|
+
letter-spacing: -0.03em;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
.browser-meta {
|
|
246
|
+
display: flex;
|
|
247
|
+
gap: 8px;
|
|
248
|
+
align-items: center;
|
|
249
|
+
flex-wrap: wrap;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
.browser-keyhint {
|
|
253
|
+
margin-top: 12px;
|
|
254
|
+
color: var(--muted);
|
|
255
|
+
font-size: 12px;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
.repo-tab-row {
|
|
259
|
+
margin-top: 18px;
|
|
260
|
+
display: flex;
|
|
261
|
+
gap: 8px;
|
|
262
|
+
flex-wrap: wrap;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
.repo-tab {
|
|
266
|
+
appearance: none;
|
|
267
|
+
border: 1px solid var(--border);
|
|
268
|
+
border-radius: 999px;
|
|
269
|
+
background: var(--surface);
|
|
270
|
+
color: var(--text-dim);
|
|
271
|
+
padding: 8px 12px;
|
|
272
|
+
font: inherit;
|
|
273
|
+
font-size: 12px;
|
|
274
|
+
cursor: pointer;
|
|
275
|
+
transition: background 140ms ease, color 140ms ease, border-color 140ms ease;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
.repo-tab.is-active {
|
|
279
|
+
background: var(--accent);
|
|
280
|
+
border-color: var(--accent);
|
|
281
|
+
color: white;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
.repo-browser {
|
|
285
|
+
margin-top: 20px;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
.repo-panel[hidden] {
|
|
289
|
+
display: none !important;
|
|
290
|
+
}
|
|
291
|
+
"""
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
_BROWSER_SCRIPT = """
|
|
295
|
+
<script>
|
|
296
|
+
(() => {
|
|
297
|
+
const panels = Array.from(document.querySelectorAll(".repo-panel"));
|
|
298
|
+
const tabs = Array.from(document.querySelectorAll(".repo-tab"));
|
|
299
|
+
const position = document.getElementById("repo-position");
|
|
300
|
+
const status = document.getElementById("repo-status");
|
|
301
|
+
if (!panels.length) {
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
let index = 0;
|
|
306
|
+
|
|
307
|
+
const show = (nextIndex) => {
|
|
308
|
+
index = (nextIndex + panels.length) % panels.length;
|
|
309
|
+
panels.forEach((panel, panelIndex) => {
|
|
310
|
+
const active = panelIndex === index;
|
|
311
|
+
panel.hidden = !active;
|
|
312
|
+
panel.setAttribute("aria-hidden", active ? "false" : "true");
|
|
313
|
+
});
|
|
314
|
+
tabs.forEach((tab, tabIndex) => {
|
|
315
|
+
const active = tabIndex === index;
|
|
316
|
+
tab.classList.toggle("is-active", active);
|
|
317
|
+
tab.setAttribute("aria-pressed", active ? "true" : "false");
|
|
318
|
+
tab.tabIndex = active ? 0 : -1;
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
const activePanel = panels[index];
|
|
322
|
+
const repoId = activePanel.dataset.repoId || "";
|
|
323
|
+
const tone = activePanel.dataset.tone || "neutral";
|
|
324
|
+
const statusText = activePanel.dataset.status || "unknown";
|
|
325
|
+
|
|
326
|
+
if (position) {
|
|
327
|
+
position.textContent = `${index + 1} / ${panels.length}`;
|
|
328
|
+
}
|
|
329
|
+
if (status) {
|
|
330
|
+
status.className = `pill ${tone}`;
|
|
331
|
+
status.textContent = statusText.replaceAll("_", " ");
|
|
332
|
+
status.setAttribute("aria-label", `${repoId} status ${statusText}`);
|
|
333
|
+
}
|
|
334
|
+
document.title = `Shellbrain Metrics - ${repoId}`;
|
|
335
|
+
if (window.history && window.history.replaceState) {
|
|
336
|
+
window.history.replaceState(null, "", `#repo-${index + 1}`);
|
|
337
|
+
}
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
document.addEventListener("keydown", (event) => {
|
|
341
|
+
if (event.defaultPrevented || event.altKey || event.ctrlKey || event.metaKey) {
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
const target = event.target;
|
|
346
|
+
const tagName = target && target.tagName ? target.tagName.toLowerCase() : "";
|
|
347
|
+
if (tagName === "input" || tagName === "textarea" || tagName === "select") {
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
if (target && target.isContentEditable) {
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
if (event.key === "ArrowRight") {
|
|
355
|
+
event.preventDefault();
|
|
356
|
+
show(index + 1);
|
|
357
|
+
}
|
|
358
|
+
if (event.key === "ArrowLeft") {
|
|
359
|
+
event.preventDefault();
|
|
360
|
+
show(index - 1);
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
tabs.forEach((tab, tabIndex) => {
|
|
365
|
+
tab.addEventListener("click", () => show(tabIndex));
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
const hashMatch = window.location.hash.match(/^#repo-(\\d+)$/);
|
|
369
|
+
if (hashMatch) {
|
|
370
|
+
const parsed = Number(hashMatch[1]);
|
|
371
|
+
if (!Number.isNaN(parsed) && parsed >= 1 && parsed <= panels.length) {
|
|
372
|
+
index = parsed - 1;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
show(index);
|
|
377
|
+
})();
|
|
378
|
+
</script>
|
|
379
|
+
"""
|
|
380
|
+
|
|
381
|
+
|
|
223
382
|
def render_metrics_dashboard(snapshot: dict[str, Any]) -> str:
|
|
224
383
|
"""Render one self-contained HTML dashboard from a metrics snapshot."""
|
|
225
384
|
|
|
385
|
+
return f"""<!DOCTYPE html>
|
|
386
|
+
<html lang="en">
|
|
387
|
+
<head>
|
|
388
|
+
<meta charset="UTF-8">
|
|
389
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
390
|
+
<title>Shellbrain Metrics</title>
|
|
391
|
+
<link rel="icon" href="data:,">
|
|
392
|
+
<style>{_PAGE_CSS}</style>
|
|
393
|
+
</head>
|
|
394
|
+
<body>
|
|
395
|
+
<div class="shell">
|
|
396
|
+
{_render_snapshot_content(snapshot)}
|
|
397
|
+
</div>
|
|
398
|
+
</body>
|
|
399
|
+
</html>
|
|
400
|
+
"""
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
def render_metrics_browser_dashboard(snapshots: Sequence[dict[str, Any]]) -> str:
|
|
404
|
+
"""Render one browser dashboard that switches repos with in-page arrow-key navigation."""
|
|
405
|
+
|
|
406
|
+
normalized = [snapshot for snapshot in snapshots if isinstance(snapshot, dict)]
|
|
407
|
+
if not normalized:
|
|
408
|
+
return """<!DOCTYPE html>
|
|
409
|
+
<html lang="en">
|
|
410
|
+
<head>
|
|
411
|
+
<meta charset="UTF-8">
|
|
412
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
413
|
+
<title>Shellbrain Metrics</title>
|
|
414
|
+
<link rel="icon" href="data:,">
|
|
415
|
+
<style>body{font-family:system-ui,sans-serif;padding:24px}</style>
|
|
416
|
+
</head>
|
|
417
|
+
<body><p>No metrics snapshots are available.</p></body>
|
|
418
|
+
</html>
|
|
419
|
+
"""
|
|
420
|
+
|
|
421
|
+
first_snapshot = normalized[0]
|
|
422
|
+
tabs = "".join(
|
|
423
|
+
f"<button type=\"button\" class=\"repo-tab{' is-active' if index == 0 else ''}\" aria-pressed=\"{'true' if index == 0 else 'false'}\">{escape(str(snapshot['repo_id']))}</button>"
|
|
424
|
+
for index, snapshot in enumerate(normalized)
|
|
425
|
+
)
|
|
426
|
+
panels = "".join(
|
|
427
|
+
_render_browser_panel(snapshot=snapshot, index=index)
|
|
428
|
+
for index, snapshot in enumerate(normalized)
|
|
429
|
+
)
|
|
430
|
+
first_tone = _tone_for_status(str(first_snapshot["status"]))
|
|
431
|
+
|
|
432
|
+
return f"""<!DOCTYPE html>
|
|
433
|
+
<html lang="en">
|
|
434
|
+
<head>
|
|
435
|
+
<meta charset="UTF-8">
|
|
436
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
437
|
+
<title>Shellbrain Metrics - {escape(str(first_snapshot["repo_id"]))}</title>
|
|
438
|
+
<link rel="icon" href="data:,">
|
|
439
|
+
<style>{_PAGE_CSS}{_BROWSER_CSS}</style>
|
|
440
|
+
</head>
|
|
441
|
+
<body>
|
|
442
|
+
<div class="browser-shell">
|
|
443
|
+
<header class="browser-masthead">
|
|
444
|
+
<div>
|
|
445
|
+
<p class="eyebrow">Shellbrain Metrics</p>
|
|
446
|
+
<h1>All Repos</h1>
|
|
447
|
+
<div class="subtle">Opened automatically. Use the left and right arrow keys in this page to switch repos.</div>
|
|
448
|
+
</div>
|
|
449
|
+
<div class="browser-meta">
|
|
450
|
+
<span id="repo-position" class="pill neutral">1 / {len(normalized)}</span>
|
|
451
|
+
<span id="repo-status" class="pill {first_tone}">{escape(str(first_snapshot["status"]).replace("_", " "))}</span>
|
|
452
|
+
</div>
|
|
453
|
+
</header>
|
|
454
|
+
<div class="browser-keyhint">Left/Right arrow keys switch repos in this page. No terminal input is required.</div>
|
|
455
|
+
<nav class="repo-tab-row" aria-label="Tracked repos">
|
|
456
|
+
{tabs}
|
|
457
|
+
</nav>
|
|
458
|
+
<main class="repo-browser">
|
|
459
|
+
{panels}
|
|
460
|
+
</main>
|
|
461
|
+
</div>
|
|
462
|
+
{_BROWSER_SCRIPT}
|
|
463
|
+
</body>
|
|
464
|
+
</html>
|
|
465
|
+
"""
|
|
466
|
+
|
|
467
|
+
|
|
468
|
+
def _render_browser_panel(*, snapshot: dict[str, Any], index: int) -> str:
|
|
469
|
+
"""Render one repo panel for the multi-repo browser dashboard."""
|
|
470
|
+
|
|
471
|
+
tone = _tone_for_status(str(snapshot["status"]))
|
|
472
|
+
hidden_attr = "" if index == 0 else " hidden"
|
|
473
|
+
return f"""
|
|
474
|
+
<section class="repo-panel" data-repo-id="{escape(str(snapshot["repo_id"]))}" data-status="{escape(str(snapshot["status"]))}" data-tone="{tone}" aria-hidden="{'false' if index == 0 else 'true'}"{hidden_attr}>
|
|
475
|
+
{_render_snapshot_content(snapshot)}
|
|
476
|
+
</section>
|
|
477
|
+
"""
|
|
478
|
+
|
|
479
|
+
|
|
480
|
+
def _render_snapshot_content(snapshot: dict[str, Any]) -> str:
|
|
481
|
+
"""Render the shared snapshot content used by single-repo and multi-repo dashboards."""
|
|
482
|
+
|
|
226
483
|
status_tone = _tone_for_status(str(snapshot["status"]))
|
|
227
484
|
alert_html = ""
|
|
228
485
|
if snapshot["alerts"]:
|
|
@@ -238,17 +495,7 @@ def render_metrics_dashboard(snapshot: dict[str, Any]) -> str:
|
|
|
238
495
|
generated_at = escape(str(snapshot["generated_at"]).replace("T", " ").replace("+00:00", " UTC"))
|
|
239
496
|
current_window = snapshot["current_window"]
|
|
240
497
|
|
|
241
|
-
return f"""
|
|
242
|
-
<html lang="en">
|
|
243
|
-
<head>
|
|
244
|
-
<meta charset="UTF-8">
|
|
245
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
246
|
-
<title>Shellbrain Metrics</title>
|
|
247
|
-
<link rel="icon" href="data:,">
|
|
248
|
-
<style>{_PAGE_CSS}</style>
|
|
249
|
-
</head>
|
|
250
|
-
<body>
|
|
251
|
-
<div class="shell">
|
|
498
|
+
return f"""
|
|
252
499
|
<section class="status-strip {status_tone}">
|
|
253
500
|
<div>
|
|
254
501
|
<p class="eyebrow">Shellbrain Metrics</p>
|
|
@@ -279,10 +526,7 @@ def render_metrics_dashboard(snapshot: dict[str, Any]) -> str:
|
|
|
279
526
|
{metric_cards}
|
|
280
527
|
</section>
|
|
281
528
|
</main>
|
|
282
|
-
|
|
283
|
-
</body>
|
|
284
|
-
</html>
|
|
285
|
-
"""
|
|
529
|
+
"""
|
|
286
530
|
|
|
287
531
|
|
|
288
532
|
def _render_metric_card(metric: dict[str, Any]) -> str:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{shellbrain-0.1.26 → shellbrain-0.1.27}/app/core/policies/read_policy/context_pack_builder.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{shellbrain-0.1.26 → shellbrain-0.1.27}/app/migrations/versions/20260226_0001_initial_schema.py
RENAMED
|
File without changes
|
{shellbrain-0.1.26 → shellbrain-0.1.27}/app/migrations/versions/20260312_0002_add_hard_invariants.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|