code-context-control 2.92.3__tar.gz → 2.95.0__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.
- {code_context_control-2.92.3/code_context_control.egg-info → code_context_control-2.95.0}/PKG-INFO +2 -2
- {code_context_control-2.92.3 → code_context_control-2.95.0}/README.md +1 -1
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/c3.py +197 -5
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/commands/parser.py +31 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/guide/credentials.html +115 -7
- code_context_control-2.95.0/cli/hook_session_stats.py +154 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hub_server.py +342 -6
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hub_ui/app.js +2 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hub_ui/components/drill_panel.js +2 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hub_ui/components/drill_views.js +2 -1
- code_context_control-2.95.0/cli/hub_ui/components/hub_cred_audit.js +255 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hub_ui/components/hub_credentials.js +782 -71
- code_context_control-2.95.0/cli/hub_ui/components/hub_tokens.js +384 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hub_ui/components/topbar.js +4 -4
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/mcp_server.py +12 -1
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/server.py +112 -4
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/tools/credentials.py +69 -4
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/ui/components/credentials.js +234 -38
- {code_context_control-2.92.3 → code_context_control-2.95.0/code_context_control.egg-info}/PKG-INFO +2 -2
- {code_context_control-2.92.3 → code_context_control-2.95.0}/code_context_control.egg-info/SOURCES.txt +7 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/pyproject.toml +1 -1
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/claude_md.py +1 -1
- code_context_control-2.95.0/services/cred_audit.py +248 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/credential_store.py +441 -53
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/session_manager.py +70 -2
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/telemetry.py +145 -1
- code_context_control-2.95.0/tests/test_cred_audit.py +229 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_credential_store.py +147 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_credentials_routes.py +120 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_credentials_tool.py +106 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_creds_cli_smoke.py +40 -0
- code_context_control-2.95.0/tests/test_env_parser.py +159 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_hub_credentials_routes_write.py +160 -0
- code_context_control-2.95.0/tests/test_token_tracking.py +321 -0
- code_context_control-2.95.0/tests/test_ui_jsx_syntax.py +149 -0
- code_context_control-2.92.3/cli/hook_session_stats.py +0 -69
- {code_context_control-2.92.3 → code_context_control-2.95.0}/LICENSE +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/__init__.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/_hook_utils.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/_shell_writes.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/commands/__init__.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/commands/common.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/docs.html +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/edits.html +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/guide/access.html +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/guide/bitbucket.html +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/guide/getting-started.html +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/guide/index.html +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/guide/masking.html +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/guide/oracle.html +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/guide/shared.css +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/guide/tools.html +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/guide/workflow.html +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hook_access_guard.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hook_artifact.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hook_auto_snapshot.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hook_c3_signal.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hook_c3read.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hook_dispatch.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hook_edit_ledger.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hook_edit_unlock.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hook_filter.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hook_ghost_files.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hook_pretool_enforce.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hook_prompt_recall.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hook_read.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hook_terse_advisor.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hub_ui/components/add_project.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hub_ui/components/config_editor.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hub_ui/components/drill_artifacts.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hub_ui/components/drill_health.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hub_ui/components/drill_subprojects.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hub_ui/components/drill_tasks.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hub_ui/components/global_search.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hub_ui/components/hub_ci.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hub_ui/components/hub_enforcement.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hub_ui/components/hub_locks.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hub_ui/components/mcp_manager.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hub_ui/components/modals.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hub_ui/components/project_card.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hub_ui/components/project_tree.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hub_ui/components/session_drawer.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hub_ui/components/settings_modal.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hub_ui/components/sidebar.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hub_ui/components/summary_bar.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hub_ui/components/task_board.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hub_ui/components/toasts.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hub_ui/state.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/hub_ui.html +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/mcp_proxy.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/progress.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/tools/__init__.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/tools/_grants.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/tools/_helpers.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/tools/agent.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/tools/artifacts.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/tools/bitbucket.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/tools/ci.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/tools/compress.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/tools/delegate.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/tools/edit.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/tools/edit_verify.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/tools/edits.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/tools/federate.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/tools/filter.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/tools/impact.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/tools/jira.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/tools/locks.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/tools/memory.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/tools/override.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/tools/project.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/tools/read.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/tools/search.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/tools/session.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/tools/shell.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/tools/status.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/tools/tasks.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/tools/validate.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/ui/api.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/ui/app.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/ui/components/access.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/ui/components/bitbucket.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/ui/components/chat.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/ui/components/dashboard.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/ui/components/edits.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/ui/components/enforcement.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/ui/components/instructions.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/ui/components/jira.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/ui/components/memory.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/ui/components/sessions.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/ui/components/settings.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/ui/components/sidebar.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/ui/components/tasks.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/ui/icons.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/ui/pm_shared.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/ui/shared.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/ui/theme.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/ui.html +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/ui_legacy.html +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/cli/ui_nano.html +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/code_context_control.egg-info/dependency_links.txt +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/code_context_control.egg-info/entry_points.txt +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/code_context_control.egg-info/requires.txt +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/code_context_control.egg-info/top_level.txt +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/core/__init__.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/core/config.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/core/ide.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/core/mcp_toml.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/core/web_security.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/__init__.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/config.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/mcp_oracle.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/oracle_server.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/oracle_ui.html +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/services/__init__.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/services/activity_reporter.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/services/api_auth.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/services/c3_bridge.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/services/chat_engine.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/services/chat_poll.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/services/chat_store.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/services/cross_memory.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/services/discovery_audit.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/services/federated_graph.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/services/health_checker.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/services/insight_engine.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/services/local_session.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/services/memory_reader.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/services/memory_writer.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/services/mobile_api.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/services/project_scanner.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/services/review_agent.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/services/tool_executor.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/services/tool_registry.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/ui/activity.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/ui/agents.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/ui/app.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/ui/busy.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/ui/chat/conversations.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/ui/chat/input.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/ui/chat/markdown.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/ui/chat/send.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/ui/chat/stream_renderer.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/ui/chat/toolbar.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/ui/core.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/ui/crossgraph.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/ui/header.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/ui/insights.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/ui/projects.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/ui/qrcode.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/ui/settings.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/ui/suggestions.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/oracle/ui/theme_tabs.js +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/__init__.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/access_guard.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/access_telemetry.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/activity_log.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/agent_base.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/agent_locks.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/agents.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/artifact_defs.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/artifact_store.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/auto_memory.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/background_service.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/bench/__init__.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/bench/external/__init__.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/bench/external/aider_polyglot.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/bench/external/swe_bench.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/benchmark_dashboard.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/bitbucket_client.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/bitbucket_credentials.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/ci_act.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/ci_cache.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/ci_expr.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/ci_failures.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/ci_github.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/ci_impact.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/ci_intel.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/ci_runner.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/ci_workflow.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/circuit_breaker.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/compressor.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/context_snapshot.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/conversation_store.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/cred_telemetry.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/doc_index.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/e2e_benchmark.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/e2e_evaluator.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/e2e_tasks.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/edit_ledger.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/embedding_index.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/enforcement_policy.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/error_reporting.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/file_memory.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/git_context.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/hub_service.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/indexer.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/jira_client.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/jira_cloud.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/jira_credentials.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/jira_data_center.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/jira_links.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/mask_activation.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/mask_mirror.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/mask_presets.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/memory.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/memory_consolidator.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/memory_distiller.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/memory_graph.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/memory_grounder.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/memory_queue.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/memory_scorer.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/metrics.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/notifications.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/ollama_bridge.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/ollama_client.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/ollama_credentials.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/oracle_service.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/output_filter.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/override_grants.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/override_policy.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/override_requests.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/override_wake.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/parser.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/project_manager.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/project_runtime.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/protocol.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/proxy_state.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/repo_map.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/repo_shape.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/retention.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/retrieval_broker.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/router.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/runtime.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/scanner.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/session_benchmark.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/session_preloader.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/subprojects.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/task_store.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/text_index.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/time_tracker.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/tool_classifier.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/transcript_index.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/validation_cache.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/vector_store.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/watcher.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/services/win_subprocess.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/setup.cfg +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_access_builtin_optout.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_access_guard.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_access_guard_meta.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_access_guard_shell_project.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_access_guard_surfaces.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_access_guard_wiring.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_activity_reporter.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_agent_locks.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_aider_polyglot.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_antigravity_transition.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_artifact_store.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_artifact_tool.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_background_service.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_bitbucket_cli_smoke.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_bitbucket_client.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_bitbucket_config_fallback.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_bitbucket_credentials.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_bitbucket_tool.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_c3_bridge_project_artifacts.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_c3_shell.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_chat_poll.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_ci_act.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_ci_cache.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_ci_expr.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_ci_impact.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_ci_intel.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_ci_runner.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_ci_workflow.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_circuit_breaker.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_claude_md_merge.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_cli_smoke.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_compressor_large_file.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_cooccurrence_bounds.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_cred_telemetry.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_credential_login_kind.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_credential_ui_parity.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_delegate_cascade.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_delegate_version_probe.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_e2e_benchmark.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_edit_ledger_deadline.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_edit_ledger_hook.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_edit_locking.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_edit_normalization.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_edit_verify.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_embedding_index_deadlock.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_enforcement_flip.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_enforcement_policy.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_enforcement_routes.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_failed_calls_do_not_unlock.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_federated_graph.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_filter_backoff.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_ghost_files.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_ghost_generation.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_git_branch_awareness.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_hook_access_guard.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_hook_codex_compat.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_hook_dispatch.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_hook_pretool_enforce.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_hook_prompt_recall.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_hook_smoke.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_hook_state.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_hook_utf8_stdio.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_hub_credentials_route.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_hub_enforcement_routes.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_hub_inspect_api.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_hub_locks_routes.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_hub_oracle_service_routes.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_hub_server_smoke.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_hub_subproject_links.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_ide_workflow_adaptation.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_init_clear_preserves_user_content.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_init_scan.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_install_mcp_entrypoint.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_jira_cli_smoke.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_jira_client.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_jira_config_fallback.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_jira_credentials.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_jira_links.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_jira_routes.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_jira_tool.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_lazy_store_init.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_mask_guard.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_mask_routes.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_mask_surfaces.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_mcp_host_guard.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_mcp_memory_timeout.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_mcp_server_smoke.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_mcp_toml.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_memory_distiller.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_memory_graph_api.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_memory_queue.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_memory_system.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_mobile_api.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_mobile_extras.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_mobile_override_routes.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_mobile_security_api.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_no_stale_model_pins.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_notification_dedup.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_notification_discipline.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_ollama_credentials.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_oracle_api_auth.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_oracle_apikey_api.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_oracle_c3_bridge.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_oracle_chat_engine.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_oracle_chat_store.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_oracle_discovery_api.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_oracle_discovery_audit.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_oracle_health_probe.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_oracle_local_auth.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_oracle_ollama_bridge.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_oracle_scanner_cache.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_oracle_security_fixes.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_oracle_session_bootstrap.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_oracle_subproject_awareness.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_oracle_ui_bundle.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_output_filter.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_override_grants.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_override_grants_mcp.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_override_requests.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_override_wake.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_permissions.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_pm_api.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_project_manager.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_project_manager_merge.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_project_tool.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_read_coercion.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_read_edit_parity.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_related_facts.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_repo_map.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_repo_shape.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_response_boilerplate.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_retention.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_review_digest.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_service_durability.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_session_benchmark.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_session_budget.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_shell_creds.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_shell_robustness.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_shell_write_ledger.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_shell_writes.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_subproject_exclusion.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_subproject_federation.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_subprojects.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_swe_bench.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_task_store.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_task_tool.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_time_tracker.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_token_telemetry.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_tool_registry.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_upgrade_and_version.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_validate.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_vault_write_guard.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_version_sync.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_web_security.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tests/test_windows_reliability.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tui/__init__.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tui/backend.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tui/main.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tui/screens/__init__.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tui/screens/benchmark_view.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tui/screens/claudemd_view.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tui/screens/compress_view.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tui/screens/index_view.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tui/screens/init_view.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tui/screens/mcp_view.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tui/screens/optimize_view.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tui/screens/pipe_view.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tui/screens/projects_view.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tui/screens/search_view.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tui/screens/session_view.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tui/screens/stats.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tui/screens/ui_view.py +0 -0
- {code_context_control-2.92.3 → code_context_control-2.95.0}/tui/theme.tcss +0 -0
{code_context_control-2.92.3/code_context_control.egg-info → code_context_control-2.95.0}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: code-context-control
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.95.0
|
|
4
4
|
Summary: Local MCP code-intelligence for AI coding tools: surgical search/read/edit, agent-config version history, path-level access + masking guards, and a multi-project hub.
|
|
5
5
|
Author-email: Dimitri Tselenchuk <dtselenc@gmail.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -208,7 +208,7 @@ C3 exposes **21 tools** as a native MCP server. Your IDE calls them directly:
|
|
|
208
208
|
| `c3_edits` | Edit-ledger queries, version diffs, restore points, per-branch filter, `verify` (did a failed `c3_edit` still land?) |
|
|
209
209
|
| `c3_task` | Per-project PM — tasks, dependencies, milestones, time tracking (v2.53.0) |
|
|
210
210
|
| `c3_artifacts` | Agent-config version history, diff & restore (v2.46.0) |
|
|
211
|
-
| `c3_credentials` | Named-secret vault; values never enter model context (v2.58.0) |
|
|
211
|
+
| `c3_credentials` | Named-secret vault; values never enter model context (v2.58.0). `import_env` bulk-imports a `.env` the agent still cannot read (v2.93.0) |
|
|
212
212
|
| `c3_bitbucket` | Bitbucket Data Center — PRs, branches, builds, admin (v2.30.0) |
|
|
213
213
|
| `c3_jira` | Jira Cloud + Data Center — JQL, issues, transitions (v2.56.0) |
|
|
214
214
|
| `c3_project` | Cross-project discovery & operations; guarded writes (v2.31.0) |
|
|
@@ -145,7 +145,7 @@ C3 exposes **21 tools** as a native MCP server. Your IDE calls them directly:
|
|
|
145
145
|
| `c3_edits` | Edit-ledger queries, version diffs, restore points, per-branch filter, `verify` (did a failed `c3_edit` still land?) |
|
|
146
146
|
| `c3_task` | Per-project PM — tasks, dependencies, milestones, time tracking (v2.53.0) |
|
|
147
147
|
| `c3_artifacts` | Agent-config version history, diff & restore (v2.46.0) |
|
|
148
|
-
| `c3_credentials` | Named-secret vault; values never enter model context (v2.58.0) |
|
|
148
|
+
| `c3_credentials` | Named-secret vault; values never enter model context (v2.58.0). `import_env` bulk-imports a `.env` the agent still cannot read (v2.93.0) |
|
|
149
149
|
| `c3_bitbucket` | Bitbucket Data Center — PRs, branches, builds, admin (v2.30.0) |
|
|
150
150
|
| `c3_jira` | Jira Cloud + Data Center — JQL, issues, transitions (v2.56.0) |
|
|
151
151
|
| `c3_project` | Cross-project discovery & operations; guarded writes (v2.31.0) |
|
|
@@ -92,7 +92,7 @@ console = Console() if HAS_RICH else None
|
|
|
92
92
|
# Config
|
|
93
93
|
CONFIG_DIR = ".c3"
|
|
94
94
|
CONFIG_FILE = ".c3/config.json"
|
|
95
|
-
__version__ = "2.
|
|
95
|
+
__version__ = "2.95.0"
|
|
96
96
|
|
|
97
97
|
|
|
98
98
|
def _compress_file_cli(compressor, path, mode="smart", **kw):
|
|
@@ -6114,11 +6114,75 @@ def _bb_cmd_set_default(args, project_path: str) -> None:
|
|
|
6114
6114
|
print(f"[OK] Default repo: {args.project}/{args.repo}")
|
|
6115
6115
|
|
|
6116
6116
|
|
|
6117
|
+
def cmd_tokens(args):
|
|
6118
|
+
"""Print token usage from the two local measurement logs.
|
|
6119
|
+
|
|
6120
|
+
Reads only; writes nothing. Counts come from .c3/tool_telemetry.jsonl
|
|
6121
|
+
(what C3's tools returned) and .c3/session_stats.jsonl (what the whole
|
|
6122
|
+
conversation cost, per the transcript).
|
|
6123
|
+
"""
|
|
6124
|
+
from services import telemetry
|
|
6125
|
+
|
|
6126
|
+
project_path = getattr(args, "project_path", ".") or "."
|
|
6127
|
+
days = max(0, int(getattr(args, "days", 30) or 0))
|
|
6128
|
+
limit = max(1, int(getattr(args, "limit", 15) or 15))
|
|
6129
|
+
tools = telemetry.aggregate_tool_telemetry(project_path, days=days)
|
|
6130
|
+
sess = telemetry.aggregate_session_stats(project_path, days=days)
|
|
6131
|
+
|
|
6132
|
+
if getattr(args, "json", False):
|
|
6133
|
+
print(json.dumps({"tools": tools, "sessions": sess}, indent=2))
|
|
6134
|
+
return
|
|
6135
|
+
|
|
6136
|
+
window = "all history" if days == 0 else f"last {days}d"
|
|
6137
|
+
print(f"\nToken usage — {window}")
|
|
6138
|
+
print(f" tool calls {tools['total_calls']:>14,}")
|
|
6139
|
+
print(f" tool tokens {tools['total_response_tokens']:>14,}")
|
|
6140
|
+
print(f" est. saved {tools['estimated_saved_vs_full_read']:>14,}"
|
|
6141
|
+
" (vs full-read baseline)")
|
|
6142
|
+
print(f" session tokens {sess['total_tokens']:>14,}"
|
|
6143
|
+
f" across {sess['session_count']} session(s)")
|
|
6144
|
+
if sess["rows_seen"] and sess["all_zero_rows"] == sess["rows_seen"]:
|
|
6145
|
+
# Do not let a log full of zeros read as "you used nothing".
|
|
6146
|
+
print(" note: every session row is zero — these predate the v2.95.0 "
|
|
6147
|
+
"Stop-hook fix; new sessions record real numbers.")
|
|
6148
|
+
|
|
6149
|
+
by = getattr(args, "by", "tool")
|
|
6150
|
+
if by == "tool":
|
|
6151
|
+
rows = sorted(({"name": k, **v} for k, v in tools["by_tool"].items()),
|
|
6152
|
+
key=lambda r: -r["response_tokens"])
|
|
6153
|
+
head, cols = "tool", ("calls", "tokens", "avg")
|
|
6154
|
+
elif by == "day":
|
|
6155
|
+
rows, head, cols = tools["by_day"][::-1], "day", ("calls", "tokens", "avg")
|
|
6156
|
+
elif by == "session":
|
|
6157
|
+
rows, head, cols = tools["by_session"], "session", ("calls", "tokens", "avg")
|
|
6158
|
+
else:
|
|
6159
|
+
rows, head, cols = tools["by_target"], "file", ("calls", "tokens", "avg")
|
|
6160
|
+
|
|
6161
|
+
if not rows:
|
|
6162
|
+
extra = (" (no file attribution recorded yet — targets are logged "
|
|
6163
|
+
"from v2.95.0 onward)" if by == "file" else " (nothing recorded)")
|
|
6164
|
+
print(f"\n{extra}")
|
|
6165
|
+
return
|
|
6166
|
+
|
|
6167
|
+
print(f"\n{head:<44}{cols[0]:>8}{cols[1]:>12}{cols[2]:>8}")
|
|
6168
|
+
print(" " + "-" * 70)
|
|
6169
|
+
for r in rows[:limit]:
|
|
6170
|
+
calls = r.get("calls", 0)
|
|
6171
|
+
toks = r.get("response_tokens", 0)
|
|
6172
|
+
name = str(r.get("name", ""))
|
|
6173
|
+
if len(name) > 43:
|
|
6174
|
+
name = "…" + name[-42:]
|
|
6175
|
+
print(f"{name:<44}{calls:>8}{toks:>12,}{toks // max(1, calls):>8}")
|
|
6176
|
+
if len(rows) > limit:
|
|
6177
|
+
print(f" … {len(rows) - limit} more (use --limit)")
|
|
6178
|
+
print()
|
|
6179
|
+
|
|
6180
|
+
|
|
6117
6181
|
def cmd_creds(args):
|
|
6118
6182
|
"""Credential vault management (global + per-project scopes)."""
|
|
6119
6183
|
sub = getattr(args, "creds_cmd", None)
|
|
6120
6184
|
if not sub:
|
|
6121
|
-
print("Usage: c3 creds {set,get,list,rm,import,usage} [args]")
|
|
6185
|
+
print("Usage: c3 creds {set,get,list,rm,import,usage,audit} [args]")
|
|
6122
6186
|
return
|
|
6123
6187
|
|
|
6124
6188
|
project_path = getattr(args, "project_path", ".") or "."
|
|
@@ -6135,6 +6199,8 @@ def cmd_creds(args):
|
|
|
6135
6199
|
_creds_cmd_import(args, project_path)
|
|
6136
6200
|
elif sub == "usage":
|
|
6137
6201
|
_creds_cmd_usage(args, project_path)
|
|
6202
|
+
elif sub == "audit":
|
|
6203
|
+
_creds_cmd_audit(args, project_path)
|
|
6138
6204
|
else:
|
|
6139
6205
|
print(f"Unknown creds subcommand: {sub}")
|
|
6140
6206
|
|
|
@@ -6321,6 +6387,25 @@ def _creds_cmd_rm(args, project_path: str) -> None:
|
|
|
6321
6387
|
print(f"[error] no credential named '{args.name}' in {scope} scope")
|
|
6322
6388
|
|
|
6323
6389
|
|
|
6390
|
+
def _creds_import_table(rows: list) -> None:
|
|
6391
|
+
"""Print one line per parsed row: what it is, not what it holds.
|
|
6392
|
+
|
|
6393
|
+
Length and fingerprint are enough to tell two keys apart and to spot a
|
|
6394
|
+
truncated paste; a value prefix would be part of the secret, so there
|
|
6395
|
+
isn't one.
|
|
6396
|
+
"""
|
|
6397
|
+
if not rows:
|
|
6398
|
+
print("Nothing to import — no KEY=VALUE lines found.")
|
|
6399
|
+
return
|
|
6400
|
+
width = max(len(str(r["name"])) for r in rows)
|
|
6401
|
+
print(f"{'NAME'.ljust(width)} LINE TYPE LEN FINGERPRINT STATUS")
|
|
6402
|
+
for r in rows:
|
|
6403
|
+
status = r["detail"] or r["action"]
|
|
6404
|
+
print(f"{str(r['name']).ljust(width)} {str(r['line']).rjust(4)} "
|
|
6405
|
+
f"{r['ctype']:<9} {str(r['value_len']).rjust(4)} "
|
|
6406
|
+
f"{(r['fingerprint'] or '-'):<11} {status}")
|
|
6407
|
+
|
|
6408
|
+
|
|
6324
6409
|
def _creds_cmd_import(args, project_path: str) -> None:
|
|
6325
6410
|
from services import credential_store as cred_store
|
|
6326
6411
|
|
|
@@ -6328,20 +6413,126 @@ def _creds_cmd_import(args, project_path: str) -> None:
|
|
|
6328
6413
|
if not env_path.exists():
|
|
6329
6414
|
print(f"[error] file not found: {env_path}")
|
|
6330
6415
|
return
|
|
6416
|
+
only = [n.strip() for n in str(getattr(args, "only", "") or "").split(",")
|
|
6417
|
+
if n.strip()] or None
|
|
6418
|
+
dry_run = bool(getattr(args, "dry_run", False))
|
|
6331
6419
|
try:
|
|
6332
|
-
text =
|
|
6420
|
+
text = cred_store.read_env_file(env_path)
|
|
6333
6421
|
result = cred_store.import_env(
|
|
6334
6422
|
text, scope=_creds_scope(args), project_path=project_path,
|
|
6335
6423
|
overwrite=bool(getattr(args, "overwrite", False)),
|
|
6424
|
+
preview=dry_run, only=only,
|
|
6425
|
+
source=str(env_path.resolve()), compare=dry_run,
|
|
6336
6426
|
)
|
|
6337
6427
|
except (cred_store.CredentialError, RuntimeError) as exc:
|
|
6338
6428
|
print(f"[error] {exc}")
|
|
6339
6429
|
return
|
|
6430
|
+
|
|
6431
|
+
if dry_run:
|
|
6432
|
+
_creds_import_table(result["rows"])
|
|
6433
|
+
print(f"\n[dry-run] {len(result['created'])} would be imported, "
|
|
6434
|
+
f"{len(result['skipped'])} skipped. Nothing was written.")
|
|
6435
|
+
return
|
|
6436
|
+
|
|
6340
6437
|
print(f"[OK] Imported {len(result['created'])} credential(s): "
|
|
6341
6438
|
f"{', '.join(result['created']) or '-'}")
|
|
6342
6439
|
if result["skipped"]:
|
|
6343
|
-
|
|
6344
|
-
|
|
6440
|
+
# Reasons come off the rows, which already carry human text — the old
|
|
6441
|
+
# output was a bare comma list that lumped four causes together.
|
|
6442
|
+
detail = {r["name"]: r["detail"] for r in result["rows"] if r["reason"]}
|
|
6443
|
+
print(f"Skipped {len(result['skipped'])}:")
|
|
6444
|
+
for name in result["skipped"]:
|
|
6445
|
+
print(f" {name} - {detail.get(name, 'skipped')}")
|
|
6446
|
+
notes = [r for r in result["rows"] if r["reason"] in ("no-assignment", "duplicate")]
|
|
6447
|
+
if notes:
|
|
6448
|
+
print(f"{len(notes)} line(s) ignored "
|
|
6449
|
+
"(no KEY=VALUE, or redefined later in the file).")
|
|
6450
|
+
if result["created"]:
|
|
6451
|
+
_creds_audit_import(project_path, _creds_scope(args), result["created"],
|
|
6452
|
+
env_path)
|
|
6453
|
+
|
|
6454
|
+
|
|
6455
|
+
def _creds_audit_import(project_path: str, scope: str, created: list,
|
|
6456
|
+
env_path) -> None:
|
|
6457
|
+
"""The CLI import was the one credential mutation with no audit trail —
|
|
6458
|
+
both REST paths logged and this did not. Names only, never values."""
|
|
6459
|
+
try:
|
|
6460
|
+
from services.edit_ledger import EditLedger
|
|
6461
|
+
ledger = EditLedger(str(project_path))
|
|
6462
|
+
ledger.log_edit(
|
|
6463
|
+
file=f"cred://{len(created)} entries",
|
|
6464
|
+
change_type="cred_import",
|
|
6465
|
+
summary=f"import {len(created)} entries ({scope}) from "
|
|
6466
|
+
f"{Path(env_path).name} via c3 creds",
|
|
6467
|
+
tags=["creds", "import"],
|
|
6468
|
+
detail={"kind": "creds", "action": "import", "scope": scope,
|
|
6469
|
+
"names": list(created), "source": Path(env_path).name},
|
|
6470
|
+
)
|
|
6471
|
+
for name in created:
|
|
6472
|
+
ledger.log_edit(
|
|
6473
|
+
file=f"cred://{name}", change_type="cred_set",
|
|
6474
|
+
summary=f"set {name} ({scope}) via c3 creds import",
|
|
6475
|
+
tags=["creds", "set"],
|
|
6476
|
+
detail={"kind": "creds", "action": "set", "name": name,
|
|
6477
|
+
"scope": scope},
|
|
6478
|
+
)
|
|
6479
|
+
except Exception:
|
|
6480
|
+
pass
|
|
6481
|
+
try:
|
|
6482
|
+
from services.activity_log import ActivityLog
|
|
6483
|
+
log = ActivityLog(str(project_path))
|
|
6484
|
+
for name in created:
|
|
6485
|
+
log.log("cred_action", {"kind": "creds", "action": "set",
|
|
6486
|
+
"name": name, "scope": scope, "via": "cli"})
|
|
6487
|
+
except Exception:
|
|
6488
|
+
pass
|
|
6489
|
+
|
|
6490
|
+
|
|
6491
|
+
def _creds_cmd_audit(args, project_path):
|
|
6492
|
+
"""One timeline of every credential change and use.
|
|
6493
|
+
|
|
6494
|
+
Reads only. Prints names and command TEMPLATES — the logs never hold a
|
|
6495
|
+
value, so there is nothing to redact on the way out.
|
|
6496
|
+
"""
|
|
6497
|
+
from services import cred_audit
|
|
6498
|
+
|
|
6499
|
+
res = cred_audit.audit_events(
|
|
6500
|
+
project_path,
|
|
6501
|
+
name=getattr(args, "name", "") or "",
|
|
6502
|
+
kind=getattr(args, "kind", "") or "",
|
|
6503
|
+
action=getattr(args, "action", "") or "",
|
|
6504
|
+
surface=getattr(args, "surface", "") or "",
|
|
6505
|
+
q=getattr(args, "q", "") or "",
|
|
6506
|
+
since=getattr(args, "since", "") or "",
|
|
6507
|
+
limit=getattr(args, "limit", 40) or 40,
|
|
6508
|
+
)
|
|
6509
|
+
if getattr(args, "as_json", False):
|
|
6510
|
+
print(json.dumps(res, indent=2))
|
|
6511
|
+
return
|
|
6512
|
+
|
|
6513
|
+
counts = res["counts"]
|
|
6514
|
+
print(f"\nCredential audit — {res['matched']} event(s): "
|
|
6515
|
+
f"{counts['use']} use, {counts['change']} change"
|
|
6516
|
+
+ (f", {counts['exposing']} exposing" if counts["exposing"] else ""))
|
|
6517
|
+
if not res["events"]:
|
|
6518
|
+
print(" (nothing recorded for these filters)\n")
|
|
6519
|
+
return
|
|
6520
|
+
|
|
6521
|
+
print(f"\n{'when':<20}{'kind':<8}{'action':<12}{'name':<24}{'where'}")
|
|
6522
|
+
print(" " + "-" * 84)
|
|
6523
|
+
for ev in res["events"]:
|
|
6524
|
+
when = str(ev["ts"])[:19].replace("T", " ")
|
|
6525
|
+
name = ev["name"] + (f".{ev['field']}" if ev["field"] else "")
|
|
6526
|
+
where = ev["surface"] or "?"
|
|
6527
|
+
if ev["scope"]:
|
|
6528
|
+
where += f" ({ev['scope']})"
|
|
6529
|
+
mark = " !" if ev["action"] in cred_audit.EXPOSING_ACTIONS else ""
|
|
6530
|
+
print(f"{when:<20}{ev['kind']:<8}{ev['action']:<12}{name[:23]:<24}{where}{mark}")
|
|
6531
|
+
if ev["cmd"]:
|
|
6532
|
+
print(f"{'':<20} cmd: {ev['cmd']}")
|
|
6533
|
+
if res["truncated"]:
|
|
6534
|
+
print(f" … {res['matched'] - res['returned']} more (use --limit)")
|
|
6535
|
+
print(f"\n {res['note']}\n")
|
|
6345
6536
|
|
|
6346
6537
|
|
|
6347
6538
|
def _creds_cmd_usage(args, project_path: str) -> None:
|
|
@@ -8769,6 +8960,7 @@ def main():
|
|
|
8769
8960
|
"bitbucket": cmd_bitbucket,
|
|
8770
8961
|
"jira": cmd_jira,
|
|
8771
8962
|
"creds": cmd_creds,
|
|
8963
|
+
"tokens": cmd_tokens,
|
|
8772
8964
|
"access": cmd_access,
|
|
8773
8965
|
"enforce": cmd_enforce,
|
|
8774
8966
|
"override": cmd_override,
|
|
@@ -407,6 +407,21 @@ def build_parser(version: str, parse_cli_ide_arg):
|
|
|
407
407
|
jr_default.add_argument("project_path", nargs="?", default=".")
|
|
408
408
|
|
|
409
409
|
# ── Credential vault (v2.58.0) ──────────────────────────────────────
|
|
410
|
+
# ── Tokens ──────────────────────────────────────────────────────────
|
|
411
|
+
p_tokens = subparsers.add_parser(
|
|
412
|
+
"tokens",
|
|
413
|
+
help="Token usage — per tool, per day, per session, per file",
|
|
414
|
+
)
|
|
415
|
+
p_tokens.add_argument("--days", type=int, default=30,
|
|
416
|
+
help="Window in days; 0 = all recorded history (default: 30)")
|
|
417
|
+
p_tokens.add_argument("--by", default="tool",
|
|
418
|
+
choices=["tool", "day", "session", "file"],
|
|
419
|
+
help="Which breakdown to print (default: tool)")
|
|
420
|
+
p_tokens.add_argument("--limit", type=int, default=15,
|
|
421
|
+
help="Rows to show (default: 15)")
|
|
422
|
+
p_tokens.add_argument("--json", action="store_true",
|
|
423
|
+
help="Emit the full aggregate as JSON")
|
|
424
|
+
|
|
410
425
|
p_creds = subparsers.add_parser(
|
|
411
426
|
"creds",
|
|
412
427
|
help="Credential vault — named secrets for agents (global + per-project)",
|
|
@@ -452,6 +467,8 @@ def build_parser(version: str, parse_cli_ide_arg):
|
|
|
452
467
|
cr_import.add_argument("env_file", help="Path to the .env file")
|
|
453
468
|
cr_import.add_argument("--global", dest="use_global", action="store_true", help="Import into the global scope")
|
|
454
469
|
cr_import.add_argument("--overwrite", action="store_true", help="Replace entries already registered in the target scope")
|
|
470
|
+
cr_import.add_argument("--dry-run", dest="dry_run", action="store_true", help="Show what would be imported; write nothing")
|
|
471
|
+
cr_import.add_argument("--only", default="", help="Comma-separated names to import (default: all)")
|
|
455
472
|
cr_import.add_argument("--path", dest="project_path", default=".", help="Project directory (default: current)")
|
|
456
473
|
|
|
457
474
|
cr_usage = creds_subs.add_parser(
|
|
@@ -461,6 +478,20 @@ def build_parser(version: str, parse_cli_ide_arg):
|
|
|
461
478
|
cr_usage.add_argument("--json", dest="as_json", action="store_true", help="Emit raw JSON")
|
|
462
479
|
cr_usage.add_argument("--path", dest="project_path", default=".", help="Project directory (default: current)")
|
|
463
480
|
|
|
481
|
+
cr_audit = creds_subs.add_parser(
|
|
482
|
+
"audit", help="Audit trail — every change AND use, on one timeline")
|
|
483
|
+
cr_audit.add_argument("name", nargs="?", default="", help="Limit to one credential (default: all)")
|
|
484
|
+
cr_audit.add_argument("--kind", default="", choices=["", "use", "change"],
|
|
485
|
+
help="Show only uses or only changes (default: both)")
|
|
486
|
+
cr_audit.add_argument("--action", default="",
|
|
487
|
+
help="Exact action: inject_env, template, reveal, cli_show, set, update, delete, import…")
|
|
488
|
+
cr_audit.add_argument("--surface", default="", help="Exact surface: shell, cli, mcp, ui, hub")
|
|
489
|
+
cr_audit.add_argument("--since", default="", help="ISO timestamp lower bound, e.g. 2026-08-01")
|
|
490
|
+
cr_audit.add_argument("-q", dest="q", default="", help="Free-text over name/field/cmd/project")
|
|
491
|
+
cr_audit.add_argument("--limit", type=int, default=40, help="Events to show (default: 40)")
|
|
492
|
+
cr_audit.add_argument("--json", dest="as_json", action="store_true", help="Emit raw JSON")
|
|
493
|
+
cr_audit.add_argument("--path", dest="project_path", default=".", help="Project directory (default: current)")
|
|
494
|
+
|
|
464
495
|
# ── Agent Locks (docs/agent-locks.md) ───────────────────────────────
|
|
465
496
|
# force-release is human-only: it bumps the fencing counter so a holder
|
|
466
497
|
# that comes back is stale by construction. Agents get c3_locks instead,
|
|
@@ -108,6 +108,7 @@
|
|
|
108
108
|
<a href="#structured" class="sidebar-link"><span class="icon">💳</span> Structured kinds</a>
|
|
109
109
|
<a href="#exposure" class="sidebar-link"><span class="icon">⚠️</span> Exposure flags</a>
|
|
110
110
|
<a href="#hub-ui" class="sidebar-link"><span class="icon">🖥️</span> Hub UI</a>
|
|
111
|
+
<a href="#bulk" class="sidebar-link"><span class="icon">☑️</span> Filters & bulk actions</a>
|
|
111
112
|
<a href="#search" class="sidebar-link"><span class="icon">🔎</span> Search & qualifiers</a>
|
|
112
113
|
<a href="#cli" class="sidebar-link"><span class="icon">💻</span> CLI commands</a>
|
|
113
114
|
<a href="#actions" class="sidebar-link"><span class="icon">⚙️</span> Tool actions</a>
|
|
@@ -134,6 +135,7 @@
|
|
|
134
135
|
<span class="pill pill-accent">v2.58.0 vault</span>
|
|
135
136
|
<span class="pill pill-accent">v2.59.0 Hub tab</span>
|
|
136
137
|
<span class="pill pill-accent">v2.61.0 search + drawer</span>
|
|
138
|
+
<span class="pill pill-accent">v2.94.0 filters + bulk + re-sync</span>
|
|
137
139
|
<span class="pill pill-green">OS keyring</span>
|
|
138
140
|
<span class="pill pill-purple">Injection-first</span>
|
|
139
141
|
<span class="pill pill-amber">Write-only wire</span>
|
|
@@ -202,9 +204,12 @@
|
|
|
202
204
|
<p>Anything shared across every project — a personal GitHub PAT, an OpenAI key — belongs in the global vault:</p>
|
|
203
205
|
<pre><code>c3 creds set OPENAI_API_KEY --global</code></pre>
|
|
204
206
|
|
|
205
|
-
<p>Bulk-import an existing <code>.env</code> file
|
|
206
|
-
<pre><code>c3 creds import .env
|
|
207
|
-
c3 creds import .env
|
|
207
|
+
<p>Bulk-import an existing <code>.env</code> file. A value spanning several lines inside one pair of quotes — a PEM key, a JSON service account — is imported whole and typed <code>multiline</code>; everything else becomes an entry of type <code>env</code>.</p>
|
|
208
|
+
<pre><code>c3 creds import .env --dry-run
|
|
209
|
+
c3 creds import .env
|
|
210
|
+
c3 creds import .env --global
|
|
211
|
+
c3 creds import .env --only STRIPE_KEY,DB_URL</code></pre>
|
|
212
|
+
<p><code>--dry-run</code> prints a table of what would land — name, line, type, value length, fingerprint, and a reason for anything it will skip — and writes nothing. Skips are per-name and explained: <em>already exists</em>, <em>not a usable credential name</em>, <em>no value</em>, <em>quote never closes</em>, <em>redefined later in the file</em>.</p>
|
|
208
213
|
|
|
209
214
|
<div class="callout callout-warn">
|
|
210
215
|
<p><strong>Importing does not delete the source file.</strong> Once the values are in the vault, remove the <code>.env</code> (or confirm it is gitignored) — otherwise you have simply added a second copy.</p>
|
|
@@ -389,7 +394,11 @@ c3_shell(cmd=<span class="str">'terraform apply'</span>, env_creds=<span class="
|
|
|
389
394
|
<section id="hub-ui" class="tool-section">
|
|
390
395
|
<h2>Hub UI</h2>
|
|
391
396
|
|
|
392
|
-
<p>Run <code>c3 hub</code> and open the <strong>Credentials</strong> tab in the top bar. It manages the global vault and every registered project from one place. The same manager appears in each project's drill panel
|
|
397
|
+
<p>Run <code>c3 hub</code> and open the <strong>Credentials</strong> tab in the top bar. It manages the global vault and every registered project from one place. The same manager appears in each project's drill panel, so those two are one interface.</p>
|
|
398
|
+
|
|
399
|
+
<div class="callout">
|
|
400
|
+
<p><strong>The per-project dashboard is a lesser surface.</strong> The dashboard served by <code>c3 serve</code> has its own, older credentials panel: it can create, edit and delete entries and it has a page-level usage view the hub lacks, but it has no filters, no sort, no settings drawer, no context menu and no bulk actions. Everything below describes the <em>hub</em> manager. Use the hub, or a project's drill panel, for anything beyond a quick edit.</p>
|
|
401
|
+
</div>
|
|
393
402
|
|
|
394
403
|
<h3>Two sub-tabs</h3>
|
|
395
404
|
<table class="kv-table">
|
|
@@ -437,13 +446,76 @@ c3_shell(cmd=<span class="str">'terraform apply'</span>, env_creds=<span class="
|
|
|
437
446
|
<tr><td class="grp-gated"><code>Delete credential…</code></td><td class="param-desc">Requires typing the credential name</td></tr>
|
|
438
447
|
</tbody>
|
|
439
448
|
</table>
|
|
449
|
+
<p>Four of these have bulk equivalents — see <a href="#bulk">Filters & bulk actions</a>. The two that <em>enable</em> exposure deliberately do not.</p>
|
|
440
450
|
|
|
441
451
|
<div class="callout callout-good">
|
|
442
452
|
<p><strong>Destructive actions state their blast radius.</strong> Deleting shows where the value is stored, that anything resolving the name will start failing, and — for a global entry — how many projects override it locally and are therefore unaffected. The confirm button stays disabled until you type the credential's name.</p>
|
|
443
453
|
</div>
|
|
444
454
|
|
|
445
455
|
<h3>Importing a <code>.env</code></h3>
|
|
446
|
-
<p><strong>Import .env</strong> in the manager toolbar
|
|
456
|
+
<p><strong>Import .env</strong> in the manager toolbar opens a chooser: pick a file, drop one on the panel, or paste <code>KEY=VALUE</code> lines. Comments and <code>export </code> prefixes are tolerated.</p>
|
|
457
|
+
<p>Nothing is written until you say so. <strong>Preview</strong> parses the file and shows a table of every row — name, line, type, value length, and a fingerprint — with anything it cannot import disabled and explained in place. Tick the rows you want and press <strong>Import</strong>. <em>Replace entries that already exist</em> is off by default, so a second import of the same file is a no-op rather than a silent overwrite.</p>
|
|
458
|
+
<p>Replacing an existing entry <strong>rotates its value and nothing else</strong>. The description you wrote, the custom env var, the type you chose, and the auto-inject and agent-read settings all survive. Before 2.93.0 an overwrite rebuilt the entry from scratch, which quietly turned auto-injection off.</p>
|
|
459
|
+
<p>If C3 read the file from a path on this machine, it remembers which file each entry came from — see <a href="#resync">Re-syncing a <code>.env</code></a>. A pasted body has no path to remember, so it records no source.</p>
|
|
460
|
+
<div class="callout callout-good">
|
|
461
|
+
<p><strong>The preview never shows a value, not even the first few characters.</strong> A prefix is part of the secret. Rows are identified by length and a <code>sha256</code> fingerprint, which is enough to tell two keys apart and to notice a truncated paste, and keeps the rule that a stored value never travels back to the browser.</p>
|
|
462
|
+
</div>
|
|
463
|
+
|
|
464
|
+
<h3 id="resync">Re-syncing a <code>.env</code></h3>
|
|
465
|
+
<p>A <code>.env</code> drifts all week; the first import is never the last one. When C3 imported entries from a path on this machine it records that path, and the manager grows an <strong>Imported from</strong> strip listing each remembered file with an entry count, when it was last synced, and a <strong>Re-sync</strong> button.</p>
|
|
466
|
+
<p>Re-sync re-reads the file <em>on the server</em> and compares every value against the stored one by digest, so it can tell you what changed without either value reaching the browser. Each row comes back as one of four answers:</p>
|
|
467
|
+
<table class="params-table">
|
|
468
|
+
<thead><tr><th>Row</th><th>Means</th></tr></thead>
|
|
469
|
+
<tbody>
|
|
470
|
+
<tr><td><code>unchanged</code></td><td class="param-desc">The vault already holds this exact value. Left unticked — rewriting it would be a keyring write and a ledger row for nothing.</td></tr>
|
|
471
|
+
<tr><td><code>changed</code></td><td class="param-desc">The file and the vault differ. Ticked by default.</td></tr>
|
|
472
|
+
<tr><td><code>new</code></td><td class="param-desc">In the file, not in the vault. Ticked by default.</td></tr>
|
|
473
|
+
<tr><td><code>no longer in the file</code></td><td class="param-desc">Imported from this file once, and the file has since dropped it. Listed separately and <strong>never deleted</strong>.</td></tr>
|
|
474
|
+
</tbody>
|
|
475
|
+
</table>
|
|
476
|
+
<div class="callout">
|
|
477
|
+
<p><strong>A key leaving a <code>.env</code> is not a signal to delete it.</strong> Plenty of credentials outlive the file that seeded them, so C3 reports the ones that vanished and stops there. If you do mean to remove them, select them in the list and delete them, where the confirmation can tell you what else that breaks.</p>
|
|
478
|
+
</div>
|
|
479
|
+
<div class="callout callout-warn">
|
|
480
|
+
<p><strong>Re-sync compares, it cannot adjudicate.</strong> It knows the file and the vault disagree; it does not know which one you changed. A value you edited in the vault by hand reads as <code>changed</code>, and re-syncing overwrites it with the file's. The file is the source of truth here — if the vault holds the newer value, update the file instead.</p>
|
|
481
|
+
</div>
|
|
482
|
+
<p>If the file changes between the preview and the import, the commit is refused rather than silently applying content you never saw: press <strong>Re-check</strong> to see the new answer.</p>
|
|
483
|
+
</section>
|
|
484
|
+
|
|
485
|
+
<hr class="divider">
|
|
486
|
+
|
|
487
|
+
<!-- ═══════════════════════════════════════ BULK ═══ -->
|
|
488
|
+
<section id="bulk" class="tool-section">
|
|
489
|
+
<h2>Filters & bulk actions</h2>
|
|
490
|
+
|
|
491
|
+
<h3>Narrowing the list</h3>
|
|
492
|
+
<p>Above every credential list is a row of chips — <code>agent-readable</code>, <code>auto-inject</code>, <code>structured</code>, <code>shadowing</code>, <code>from .env</code>, <code>never used</code>, <code>stale >30d</code> — each carrying a live count. Chips <strong>narrow</strong>: ticking two shows the rows matching both. They compose with the filter box and its <code>key:value</code> qualifiers, and <kbd>/</kbd> jumps to that box from anywhere on the page.</p>
|
|
493
|
+
<p>Sorting offers name, last used, most used, exposure and newest. <em>Exposure</em> floats the risky rows up: agent-readable counts double, auto-inject counts once.</p>
|
|
494
|
+
|
|
495
|
+
<h3>Selecting rows</h3>
|
|
496
|
+
<p><strong>Select</strong> in the toolbar turns on checkboxes. Click a row to tick it, <kbd>Shift</kbd>-click to extend a range, or use the header checkbox to take everything currently shown — which is what makes the chips useful: filter to <code>agent-readable</code>, select all, revoke.</p>
|
|
497
|
+
|
|
498
|
+
<table class="params-table action-table">
|
|
499
|
+
<thead><tr><th>Bulk action</th><th>Notes</th></tr></thead>
|
|
500
|
+
<tbody>
|
|
501
|
+
<tr><td class="grp-read"><code>Check resolution</code></td><td class="param-desc">Read-only. Confirms each value can still be decoded.</td></tr>
|
|
502
|
+
<tr><td class="grp-write"><code>Revoke agent read</code></td><td class="param-desc">Sets <code>agent_readable=false</code> on every selected entry.</td></tr>
|
|
503
|
+
<tr><td class="grp-write"><code>Disable auto-inject</code></td><td class="param-desc">Sets <code>inject=false</code> on every selected entry.</td></tr>
|
|
504
|
+
<tr><td class="grp-read"><code>Export CSV</code></td><td class="param-desc">Metadata only — name, scope, project, type, storage, env var, exposure, usage, source, description. <strong>No values</strong>, because none are in the browser to export.</td></tr>
|
|
505
|
+
<tr><td class="grp-gated"><code>Delete…</code></td><td class="param-desc">Requires typing <code>DELETE <count></code>.</td></tr>
|
|
506
|
+
</tbody>
|
|
507
|
+
</table>
|
|
508
|
+
|
|
509
|
+
<div class="callout callout-warn">
|
|
510
|
+
<p><strong>Bulk can only ever reduce exposure.</strong> There is no bulk "allow agent read" and no bulk "enable auto-inject". Granting stays one entry at a time behind a confirmation that names it, because a bulk grant widens access to many secrets from a single checkbox and the one row you did not mean to include is exactly the one that matters. The server enforces this allowlist too — it is not merely a missing button.</p>
|
|
511
|
+
<p>Bulk rename, retype, storage migration and copy-to-global are absent for a different reason: each silently changes which credential a consumer resolves, and no dialog makes that visible after the fact.</p>
|
|
512
|
+
</div>
|
|
513
|
+
|
|
514
|
+
<div class="callout callout-good">
|
|
515
|
+
<p><strong>Bulk delete says what else it breaks.</strong> Deleting a project entry does not remove the name — it hands it back to the global vault, so the project starts resolving the <em>global</em> value instead of failing. The confirmation lists exactly which of the selected rows do that, before you type the count.</p>
|
|
516
|
+
</div>
|
|
517
|
+
|
|
518
|
+
<p>A partial run reports as partial: the toast reads <code>7 ok, 2 failed</code> and names the first failure, rather than claiming nine successes. Every mutation is logged to the ledger by <code>(scope, project, name)</code> — a name alone is ambiguous when the same name legitimately lives in the global vault and in several projects at once.</p>
|
|
447
519
|
</section>
|
|
448
520
|
|
|
449
521
|
<hr class="divider">
|
|
@@ -476,6 +548,7 @@ c3_shell(cmd=<span class="str">'terraform apply'</span>, env_creds=<span class="
|
|
|
476
548
|
<tr><td class="param-name"><code>inject:</code></td><td class="param-desc">Auto-inject flag</td><td><code>inject:true</code></td></tr>
|
|
477
549
|
<tr><td class="param-name"><code>agent:</code></td><td class="param-desc"><code>agent_readable</code> flag</td><td><code>agent:true</code></td></tr>
|
|
478
550
|
<tr><td class="param-name"><code>shadow:</code></td><td class="param-desc">Involved in an override, either direction</td><td><code>shadow:true</code></td></tr>
|
|
551
|
+
<tr><td class="param-name"><code>source:</code></td><td class="param-desc">Which <code>.env</code> an import recorded; <code>source:none</code> for the hand-made ones</td><td><code>source:.env</code></td></tr>
|
|
479
552
|
</tbody>
|
|
480
553
|
</table>
|
|
481
554
|
|
|
@@ -506,7 +579,7 @@ c3_shell(cmd=<span class="str">'terraform apply'</span>, env_creds=<span class="
|
|
|
506
579
|
<tr><td class="grp-read"><code>c3 creds list</code></td><td class="param-desc">Merged view — project entries plus the globals visible here. Names and metadata only.</td></tr>
|
|
507
580
|
<tr><td class="grp-read"><code>c3 creds get NAME</code></td><td class="param-desc">Entry metadata, masked. <code>--show</code> prints the value to <em>your</em> terminal (not the agent's).</td></tr>
|
|
508
581
|
<tr><td class="grp-write"><code>c3 creds rm NAME</code></td><td class="param-desc">Delete the value and the registry entry. <code>--global</code> to target the shared vault.</td></tr>
|
|
509
|
-
<tr><td class="grp-write"><code>c3 creds import FILE</code></td><td class="param-desc">Import <code>KEY=VALUE</code> lines. Names already registered in the target scope are skipped unless you pass <code>--overwrite</code
|
|
582
|
+
<tr><td class="grp-write"><code>c3 creds import FILE</code></td><td class="param-desc">Import <code>KEY=VALUE</code> lines, including values quoted across several lines. Names already registered in the target scope are skipped unless you pass <code>--overwrite</code>, and each skip is reported with its reason. <code>--dry-run</code> shows what would land and writes nothing; <code>--only NAME,...</code> imports a subset; <code>--global</code> targets the shared vault.</td></tr>
|
|
510
583
|
</tbody>
|
|
511
584
|
</table>
|
|
512
585
|
|
|
@@ -595,9 +668,44 @@ c3_shell(cmd=<span class="str">'terraform apply'</span>, env_creds=<span class="
|
|
|
595
668
|
</tr>
|
|
596
669
|
</table>
|
|
597
670
|
|
|
598
|
-
<
|
|
671
|
+
<h3>The Audit view</h3>
|
|
672
|
+
<p>Those two logs answer different halves of the same question and, until v2.95.0, nothing joined them: <strong>changes</strong> live in the activity log, <strong>uses</strong> live in <code>.c3/cred_usage.jsonl</code>. <strong>Credentials → Audit</strong> in the hub merges them into one timeline, newest first, and every credential list has its own <strong>Audit</strong> button scoped to that vault.</p>
|
|
673
|
+
|
|
674
|
+
<table class="params-table">
|
|
675
|
+
<thead><tr><th>Column</th><th>What it tells you</th></tr></thead>
|
|
676
|
+
<tbody>
|
|
677
|
+
<tr><td><code>when</code></td><td class="param-desc">UTC timestamp of the event.</td></tr>
|
|
678
|
+
<tr><td><code>kind</code></td><td class="param-desc"><code>change</code> (created, edited, deleted, imported, bulk action) or <code>use</code>.</td></tr>
|
|
679
|
+
<tr><td><code>action</code></td><td class="param-desc"><code>inject_env</code>, <code>template</code>, <code>reveal</code>, <code>cli_show</code>, <code>set</code>, <code>update</code>, <code>delete</code>, <code>import</code>, <code>batch_*</code>.</td></tr>
|
|
680
|
+
<tr><td><code>name</code></td><td class="param-desc">The credential, with the field for a structured kind (<code>CARD.number</code>). Click it to filter the timeline to that one key.</td></tr>
|
|
681
|
+
<tr><td><code>where</code></td><td class="param-desc">Which project, or the global vault, plus the surface it came through — <code>shell</code>, <code>cli</code>, <code>mcp</code>, <code>ui</code>, <code>hub</code>.</td></tr>
|
|
682
|
+
<tr><td><code>cmd</code></td><td class="param-desc">For a shell use, the command that needed it — expandable.</td></tr>
|
|
683
|
+
<tr><td><code>exit</code></td><td class="param-desc">The command's exit code, so a credential used by a failing command is visible as such.</td></tr>
|
|
684
|
+
</tbody>
|
|
685
|
+
</table>
|
|
686
|
+
|
|
687
|
+
<div class="callout callout-warn">
|
|
688
|
+
<p><strong>The <code>exposing</code> filter is the one to reach for first.</strong> <code>reveal</code> and <code>cli_show</code> are the only two actions that put a plaintext value somewhere a person or a model can read it. Everything else hands the value to a subprocess and it is never surfaced. Those rows are badged and counted separately rather than left to be spotted in a list.</p>
|
|
689
|
+
</div>
|
|
690
|
+
|
|
691
|
+
<div class="callout callout-good">
|
|
692
|
+
<p><strong>There is nothing to redact in the trail.</strong> Neither log has ever stored a value. <code>cmd</code> is the <em>raw template</em> you typed — <code>{{cred:NPM_TOKEN}}</code> or <code>$NPM_TOKEN</code>, never the substitution — which is why the command is shown in full instead of masked. Masking it would imply there was something behind the mask.</p>
|
|
693
|
+
</div>
|
|
694
|
+
|
|
695
|
+
<p>A project's timeline includes the global vault, because a shared credential used from a project records into <code>~/.c3</code> rather than the project — reading only the project would lose exactly the entries a shared secret generates. The cross-project view reads that shared vault once, not once per project.</p>
|
|
696
|
+
|
|
697
|
+
<p>From the terminal:</p>
|
|
698
|
+
<pre><code>c3 creds audit <span class="cmt"># everything, newest first</span>
|
|
699
|
+
c3 creds audit NPM_TOKEN <span class="cmt"># one credential's whole history</span>
|
|
700
|
+
c3 creds audit --kind change <span class="cmt"># who changed what</span>
|
|
701
|
+
c3 creds audit --action reveal <span class="cmt"># every plaintext read</span>
|
|
702
|
+
c3 creds audit --since 2026-08-01 --json</code></pre>
|
|
703
|
+
|
|
704
|
+
<p>Or, for the change half alone, through the edit ledger:</p>
|
|
599
705
|
<pre><code>c3_edits(action=<span class="str">'history'</span>, file=<span class="str">'cred://NPM_TOKEN'</span>)</code></pre>
|
|
600
706
|
|
|
707
|
+
<p class="param-desc">Change rows come from the live activity log. Entries older than its last rotation are in the archive and are not merged into this view.</p>
|
|
708
|
+
|
|
601
709
|
<div class="callout">
|
|
602
710
|
<p><strong>The vault is excluded from the Oracle Discovery API.</strong> External LLMs reaching C3 over MCP/HTTP cannot see credential tools at all — not the metadata, not the names. The exclusion is a hard exclusion, not a permission check.</p>
|
|
603
711
|
</div>
|