code-context-control 2.89.1__tar.gz → 2.91.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.89.1/code_context_control.egg-info → code_context_control-2.91.0}/PKG-INFO +2 -2
- {code_context_control-2.89.1 → code_context_control-2.91.0}/README.md +1 -1
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/c3.py +30 -1
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/commands/parser.py +9 -2
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/guide/credentials.html +22 -5
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/guide/oracle.html +18 -3
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hub_server.py +57 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hub_ui/app.js +2 -1
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hub_ui/components/hub_credentials.js +26 -3
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hub_ui/components/settings_modal.js +148 -33
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/mcp_server.py +9 -5
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/tools/credentials.py +9 -1
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/ui/components/credentials.js +26 -3
- {code_context_control-2.89.1 → code_context_control-2.91.0/code_context_control.egg-info}/PKG-INFO +2 -2
- {code_context_control-2.89.1 → code_context_control-2.91.0}/code_context_control.egg-info/SOURCES.txt +7 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/oracle_server.py +17 -9
- {code_context_control-2.89.1 → code_context_control-2.91.0}/pyproject.toml +1 -1
- code_context_control-2.91.0/services/background_service.py +662 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/claude_md.py +1 -1
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/credential_store.py +83 -3
- code_context_control-2.91.0/services/hub_service.py +78 -0
- code_context_control-2.91.0/services/oracle_service.py +141 -0
- code_context_control-2.91.0/tests/test_background_service.py +445 -0
- code_context_control-2.91.0/tests/test_credential_login_kind.py +191 -0
- code_context_control-2.91.0/tests/test_credential_ui_parity.py +146 -0
- code_context_control-2.91.0/tests/test_hub_oracle_service_routes.py +146 -0
- code_context_control-2.91.0/tests/test_oracle_health_probe.py +73 -0
- code_context_control-2.89.1/services/hub_service.py +0 -585
- {code_context_control-2.89.1 → code_context_control-2.91.0}/LICENSE +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/__init__.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/_hook_utils.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/commands/__init__.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/commands/common.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/docs.html +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/edits.html +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/guide/access.html +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/guide/bitbucket.html +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/guide/getting-started.html +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/guide/index.html +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/guide/masking.html +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/guide/shared.css +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/guide/tools.html +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/guide/workflow.html +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hook_access_guard.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hook_artifact.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hook_auto_snapshot.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hook_c3_signal.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hook_c3read.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hook_dispatch.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hook_edit_ledger.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hook_edit_unlock.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hook_filter.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hook_ghost_files.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hook_pretool_enforce.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hook_prompt_recall.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hook_read.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hook_session_stats.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hook_terse_advisor.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hub_ui/components/add_project.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hub_ui/components/config_editor.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hub_ui/components/drill_artifacts.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hub_ui/components/drill_health.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hub_ui/components/drill_panel.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hub_ui/components/drill_subprojects.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hub_ui/components/drill_tasks.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hub_ui/components/drill_views.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hub_ui/components/global_search.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hub_ui/components/hub_ci.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hub_ui/components/hub_enforcement.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hub_ui/components/hub_locks.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hub_ui/components/mcp_manager.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hub_ui/components/modals.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hub_ui/components/project_card.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hub_ui/components/project_tree.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hub_ui/components/session_drawer.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hub_ui/components/sidebar.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hub_ui/components/summary_bar.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hub_ui/components/task_board.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hub_ui/components/toasts.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hub_ui/components/topbar.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hub_ui/state.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hub_ui.html +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/mcp_proxy.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/progress.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/server.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/tools/__init__.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/tools/_grants.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/tools/_helpers.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/tools/agent.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/tools/artifacts.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/tools/bitbucket.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/tools/ci.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/tools/compress.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/tools/delegate.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/tools/edit.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/tools/edit_verify.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/tools/edits.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/tools/federate.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/tools/filter.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/tools/impact.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/tools/jira.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/tools/locks.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/tools/memory.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/tools/override.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/tools/project.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/tools/read.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/tools/search.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/tools/session.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/tools/shell.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/tools/status.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/tools/tasks.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/tools/validate.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/ui/api.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/ui/app.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/ui/components/access.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/ui/components/bitbucket.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/ui/components/chat.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/ui/components/dashboard.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/ui/components/edits.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/ui/components/enforcement.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/ui/components/instructions.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/ui/components/jira.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/ui/components/memory.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/ui/components/sessions.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/ui/components/settings.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/ui/components/sidebar.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/ui/components/tasks.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/ui/icons.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/ui/pm_shared.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/ui/shared.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/ui/theme.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/ui.html +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/ui_legacy.html +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/cli/ui_nano.html +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/code_context_control.egg-info/dependency_links.txt +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/code_context_control.egg-info/entry_points.txt +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/code_context_control.egg-info/requires.txt +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/code_context_control.egg-info/top_level.txt +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/core/__init__.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/core/config.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/core/ide.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/core/mcp_toml.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/core/web_security.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/__init__.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/config.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/mcp_oracle.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/oracle_ui.html +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/services/__init__.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/services/activity_reporter.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/services/api_auth.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/services/c3_bridge.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/services/chat_engine.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/services/chat_poll.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/services/chat_store.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/services/cross_memory.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/services/discovery_audit.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/services/federated_graph.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/services/health_checker.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/services/insight_engine.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/services/local_session.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/services/memory_reader.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/services/memory_writer.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/services/mobile_api.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/services/project_scanner.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/services/review_agent.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/services/tool_executor.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/services/tool_registry.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/ui/activity.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/ui/agents.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/ui/app.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/ui/busy.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/ui/chat/conversations.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/ui/chat/input.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/ui/chat/markdown.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/ui/chat/send.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/ui/chat/stream_renderer.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/ui/chat/toolbar.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/ui/core.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/ui/crossgraph.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/ui/header.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/ui/insights.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/ui/projects.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/ui/qrcode.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/ui/settings.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/ui/suggestions.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/oracle/ui/theme_tabs.js +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/__init__.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/access_guard.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/access_telemetry.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/activity_log.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/agent_base.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/agent_locks.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/agents.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/artifact_defs.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/artifact_store.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/auto_memory.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/bench/__init__.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/bench/external/__init__.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/bench/external/aider_polyglot.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/bench/external/swe_bench.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/benchmark_dashboard.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/bitbucket_client.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/bitbucket_credentials.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/ci_act.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/ci_cache.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/ci_expr.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/ci_failures.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/ci_github.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/ci_impact.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/ci_intel.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/ci_runner.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/ci_workflow.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/circuit_breaker.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/compressor.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/context_snapshot.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/conversation_store.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/cred_telemetry.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/doc_index.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/e2e_benchmark.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/e2e_evaluator.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/e2e_tasks.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/edit_ledger.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/embedding_index.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/enforcement_policy.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/error_reporting.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/file_memory.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/git_context.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/indexer.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/jira_client.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/jira_cloud.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/jira_credentials.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/jira_data_center.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/jira_links.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/mask_activation.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/mask_mirror.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/mask_presets.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/memory.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/memory_consolidator.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/memory_distiller.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/memory_graph.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/memory_grounder.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/memory_queue.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/memory_scorer.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/metrics.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/notifications.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/ollama_bridge.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/ollama_client.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/ollama_credentials.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/output_filter.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/override_grants.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/override_policy.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/override_requests.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/override_wake.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/parser.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/project_manager.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/project_runtime.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/protocol.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/proxy_state.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/repo_map.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/retention.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/retrieval_broker.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/router.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/runtime.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/scanner.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/session_benchmark.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/session_manager.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/session_preloader.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/subprojects.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/task_store.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/telemetry.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/text_index.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/time_tracker.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/tool_classifier.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/transcript_index.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/validation_cache.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/vector_store.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/watcher.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/services/win_subprocess.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/setup.cfg +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_access_builtin_optout.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_access_guard.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_access_guard_meta.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_access_guard_shell_project.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_access_guard_surfaces.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_access_guard_wiring.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_activity_reporter.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_agent_locks.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_aider_polyglot.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_antigravity_transition.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_artifact_store.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_artifact_tool.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_bitbucket_cli_smoke.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_bitbucket_client.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_bitbucket_config_fallback.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_bitbucket_credentials.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_bitbucket_tool.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_c3_bridge_project_artifacts.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_c3_shell.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_chat_poll.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_ci_act.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_ci_cache.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_ci_expr.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_ci_impact.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_ci_intel.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_ci_runner.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_ci_workflow.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_circuit_breaker.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_claude_md_merge.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_cli_smoke.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_compressor_large_file.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_cred_telemetry.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_credential_store.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_credentials_routes.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_credentials_tool.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_creds_cli_smoke.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_delegate_cascade.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_delegate_version_probe.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_e2e_benchmark.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_edit_ledger_deadline.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_edit_ledger_hook.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_edit_locking.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_edit_normalization.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_edit_verify.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_embedding_index_deadlock.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_enforcement_flip.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_enforcement_policy.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_enforcement_routes.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_federated_graph.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_filter_backoff.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_ghost_files.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_ghost_generation.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_git_branch_awareness.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_hook_access_guard.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_hook_codex_compat.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_hook_dispatch.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_hook_pretool_enforce.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_hook_prompt_recall.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_hook_smoke.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_hook_state.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_hook_utf8_stdio.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_hub_credentials_route.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_hub_credentials_routes_write.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_hub_enforcement_routes.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_hub_inspect_api.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_hub_locks_routes.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_hub_server_smoke.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_hub_subproject_links.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_ide_workflow_adaptation.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_init_scan.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_install_mcp_entrypoint.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_jira_cli_smoke.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_jira_client.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_jira_config_fallback.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_jira_credentials.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_jira_links.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_jira_routes.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_jira_tool.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_lazy_store_init.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_mask_guard.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_mask_routes.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_mask_surfaces.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_mcp_host_guard.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_mcp_memory_timeout.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_mcp_server_smoke.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_mcp_toml.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_memory_distiller.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_memory_graph_api.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_memory_queue.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_memory_system.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_mobile_api.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_mobile_extras.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_mobile_override_routes.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_mobile_security_api.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_no_stale_model_pins.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_notification_dedup.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_notification_discipline.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_ollama_credentials.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_oracle_api_auth.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_oracle_apikey_api.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_oracle_c3_bridge.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_oracle_chat_engine.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_oracle_chat_store.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_oracle_discovery_api.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_oracle_discovery_audit.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_oracle_local_auth.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_oracle_ollama_bridge.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_oracle_scanner_cache.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_oracle_security_fixes.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_oracle_session_bootstrap.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_oracle_subproject_awareness.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_oracle_ui_bundle.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_output_filter.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_override_grants.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_override_grants_mcp.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_override_requests.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_override_wake.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_permissions.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_pm_api.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_project_manager.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_project_manager_merge.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_project_tool.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_read_coercion.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_read_edit_parity.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_related_facts.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_repo_map.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_response_boilerplate.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_retention.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_review_digest.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_service_durability.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_session_benchmark.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_session_budget.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_shell_creds.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_shell_robustness.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_subproject_exclusion.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_subproject_federation.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_subprojects.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_swe_bench.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_task_store.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_task_tool.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_time_tracker.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_token_telemetry.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_tool_registry.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_upgrade_and_version.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_validate.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_vault_write_guard.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_version_sync.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_web_security.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tests/test_windows_reliability.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tui/__init__.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tui/backend.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tui/main.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tui/screens/__init__.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tui/screens/benchmark_view.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tui/screens/claudemd_view.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tui/screens/compress_view.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tui/screens/index_view.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tui/screens/init_view.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tui/screens/mcp_view.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tui/screens/optimize_view.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tui/screens/pipe_view.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tui/screens/projects_view.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tui/screens/search_view.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tui/screens/session_view.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tui/screens/stats.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tui/screens/ui_view.py +0 -0
- {code_context_control-2.89.1 → code_context_control-2.91.0}/tui/theme.tcss +0 -0
{code_context_control-2.89.1/code_context_control.egg-info → code_context_control-2.91.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.91.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
|
|
@@ -137,7 +137,7 @@ Full notes: [Upgrading](https://github.com/drknowhow/code-context-control/blob/m
|
|
|
137
137
|
|
|
138
138
|
## The UI
|
|
139
139
|
|
|
140
|
-
Three local web apps, no Electron — pure Flask + vanilla JS: the **Hub** (`c3 hub`, port 3330), the **per-project UI** (`c3 ui`), and the optional **Oracle** (`c3 oracle serve`).
|
|
140
|
+
Three local web apps, no Electron — pure Flask + vanilla JS: the **Hub** (`c3 hub`, port 3330), the **per-project UI** (`c3 ui`), and the optional **Oracle** (`c3 oracle serve`). Both servers can run as windowless login services — `c3 hub --install`, `c3 oracle serve --install`, or the buttons in Hub → Settings.
|
|
141
141
|
|
|
142
142
|
### Project Hub — multi-project mission control
|
|
143
143
|
|
|
@@ -74,7 +74,7 @@ Full notes: [Upgrading](https://github.com/drknowhow/code-context-control/blob/m
|
|
|
74
74
|
|
|
75
75
|
## The UI
|
|
76
76
|
|
|
77
|
-
Three local web apps, no Electron — pure Flask + vanilla JS: the **Hub** (`c3 hub`, port 3330), the **per-project UI** (`c3 ui`), and the optional **Oracle** (`c3 oracle serve`).
|
|
77
|
+
Three local web apps, no Electron — pure Flask + vanilla JS: the **Hub** (`c3 hub`, port 3330), the **per-project UI** (`c3 ui`), and the optional **Oracle** (`c3 oracle serve`). Both servers can run as windowless login services — `c3 hub --install`, `c3 oracle serve --install`, or the buttons in Hub → Settings.
|
|
78
78
|
|
|
79
79
|
### Project Hub — multi-project mission control
|
|
80
80
|
|
|
@@ -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.91.0"
|
|
96
96
|
|
|
97
97
|
|
|
98
98
|
def _compress_file_cli(compressor, path, mode="smart", **kw):
|
|
@@ -7426,10 +7426,39 @@ def _oracle_open(args):
|
|
|
7426
7426
|
webbrowser.open(url)
|
|
7427
7427
|
|
|
7428
7428
|
|
|
7429
|
+
def _oracle_service_cmd(args):
|
|
7430
|
+
"""`c3 oracle serve --install | --uninstall | --status` — mirrors `c3 hub`."""
|
|
7431
|
+
from services.oracle_service import OracleService
|
|
7432
|
+
svc = OracleService()
|
|
7433
|
+
port = getattr(args, "port", None) or svc.default_port()
|
|
7434
|
+
|
|
7435
|
+
if getattr(args, "install", False):
|
|
7436
|
+
res = svc.install(port)
|
|
7437
|
+
print(res.get("output", "Service installed."))
|
|
7438
|
+
if res.get("success"):
|
|
7439
|
+
print(f"Oracle will start at login (no terminal window); log: {svc.LOG_FILE}")
|
|
7440
|
+
return
|
|
7441
|
+
if getattr(args, "uninstall", False):
|
|
7442
|
+
res = svc.uninstall()
|
|
7443
|
+
print(res.get("output", "Service uninstalled."))
|
|
7444
|
+
return
|
|
7445
|
+
res = svc.status()
|
|
7446
|
+
print(f"Oracle Service Status ({res.get('platform', 'unknown')}):")
|
|
7447
|
+
print(f" Installed: {res.get('installed')}")
|
|
7448
|
+
print(f" Running : {res.get('running')}")
|
|
7449
|
+
print(f" Port : {res.get('port')} (bind {res.get('bind_host')}, MCP {res.get('mcp_port')})")
|
|
7450
|
+
print(f" URL : {res.get('url')}")
|
|
7451
|
+
print(f" Method : {res.get('method')}")
|
|
7452
|
+
print(f" Log : {res.get('log_path')}")
|
|
7453
|
+
|
|
7454
|
+
|
|
7429
7455
|
def cmd_oracle(args):
|
|
7430
7456
|
"""Oracle dashboard server + Discovery API key management."""
|
|
7431
7457
|
sub = getattr(args, "oracle_cmd", None)
|
|
7432
7458
|
if sub in ("serve", "start"):
|
|
7459
|
+
if any(getattr(args, f, False) for f in ("install", "uninstall", "status")):
|
|
7460
|
+
_oracle_service_cmd(args)
|
|
7461
|
+
return
|
|
7433
7462
|
# Lazy import: run_oracle builds all Oracle services (matches
|
|
7434
7463
|
# cmd_hub's deferred-import style so bare `c3` stays fast).
|
|
7435
7464
|
from oracle.oracle_server import run_oracle
|
|
@@ -421,9 +421,9 @@ def build_parser(version: str, parse_cli_ide_arg):
|
|
|
421
421
|
cr_set.add_argument("--stdin", action="store_true", help="Read the value from stdin (piped/multiline values)")
|
|
422
422
|
cr_set.add_argument("--type", dest="ctype",
|
|
423
423
|
choices=["token", "env", "multiline",
|
|
424
|
-
"address", "identity", "card"],
|
|
424
|
+
"address", "identity", "card", "login"],
|
|
425
425
|
default="token",
|
|
426
|
-
help="Entry type; address/identity/card are structured "
|
|
426
|
+
help="Entry type; address/identity/card/login are structured "
|
|
427
427
|
"(field payload, inject-only, never revealable to the agent)")
|
|
428
428
|
cr_set.add_argument("--desc", default="", help="Human description shown in list/UI")
|
|
429
429
|
cr_set.add_argument("--env-var", default="", help="Env var name used at injection (default: entry name)")
|
|
@@ -824,6 +824,13 @@ def build_parser(version: str, parse_cli_ide_arg):
|
|
|
824
824
|
help="Server port (default: config 'port', 3331)")
|
|
825
825
|
or_serve.add_argument("--no-browser", action="store_true",
|
|
826
826
|
help="Don't open the browser")
|
|
827
|
+
or_serve.add_argument("--install", action="store_true",
|
|
828
|
+
help="Register the Oracle as a login/startup service "
|
|
829
|
+
"(no terminal window) and start it now")
|
|
830
|
+
or_serve.add_argument("--uninstall", action="store_true",
|
|
831
|
+
help="Remove the Oracle's startup service registration")
|
|
832
|
+
or_serve.add_argument("--status", action="store_true",
|
|
833
|
+
help="Show the Oracle's startup service status")
|
|
827
834
|
or_open = or_subs.add_parser(
|
|
828
835
|
"open",
|
|
829
836
|
help="Sign in to a running dashboard via a single-use URL",
|
|
@@ -297,12 +297,14 @@ c3_shell(cmd=<span class="str">'terraform apply'</span>, env_creds=<span class="
|
|
|
297
297
|
|
|
298
298
|
<!-- ═══════════════════════════════════ STRUCTURED ═══ -->
|
|
299
299
|
<section id="structured" class="tool-section">
|
|
300
|
-
<h2>Structured kinds — cards, addresses, identity (v2.87.0)</h2>
|
|
300
|
+
<h2>Structured kinds — cards, addresses, identity, logins (v2.87.0)</h2>
|
|
301
301
|
|
|
302
|
-
<p>
|
|
302
|
+
<p>Four entry types hold <strong>named fields</strong> instead of one opaque value:
|
|
303
303
|
<code>card</code> (cardholder, number, expiry, optional cvc/billing_zip — Luhn-checked),
|
|
304
|
-
<code>address</code> (street1, city, state, zip, optional recipient/street2/country/phone)
|
|
305
|
-
<code>identity</code> (full_name, optional dob/ssn/phone/email)
|
|
304
|
+
<code>address</code> (street1, city, state, zip, optional recipient/street2/country/phone),
|
|
305
|
+
<code>identity</code> (full_name, optional dob/ssn/phone/email) and
|
|
306
|
+
<code>login</code> (site_id, canonical_origin, username, password, optional totp_secret —
|
|
307
|
+
v2.90.0). The payload is stored as one
|
|
306
308
|
canonical JSON object through the same keyring / encrypted-sidecar path as any other value.</p>
|
|
307
309
|
|
|
308
310
|
<p>They are <strong>inject-only by construction</strong>, which is stricter than a normal secret:</p>
|
|
@@ -315,7 +317,10 @@ c3_shell(cmd=<span class="str">'terraform apply'</span>, env_creds=<span class="
|
|
|
315
317
|
the field list rather than expanding the whole payload.</li>
|
|
316
318
|
<li><strong>The registry shows a projection, not the data.</strong> Lists and the UI display
|
|
317
319
|
<code>visa ••••4242</code> for a card (brand + last4, deliberately <em>not</em> expiry),
|
|
318
|
-
city/state for an address, the name for an identity
|
|
320
|
+
city/state for an address, the name for an identity, and
|
|
321
|
+
<code>github · https://github.com · 2FA</code> for a login — site, origin and a 2FA
|
|
322
|
+
boolean, with the <em>username withheld on purpose</em>, because username + origin is
|
|
323
|
+
half the credential. Field <em>names</em> are public;
|
|
319
324
|
field <em>values</em> never transit any HTTP response — a sweep test enforces this.</li>
|
|
320
325
|
<li><strong>Echoes redact per field</strong> to <code>[cred:NAME.field]</code>. Caveat: the
|
|
321
326
|
redactor only tracks values of 4+ characters, so a 3-digit CVC or 2-letter state that a
|
|
@@ -333,6 +338,18 @@ c3_shell(cmd=<span class="str">'terraform apply'</span>, env_creds=<span class="
|
|
|
333
338
|
<code>c3 creds get NAME --show</code> (all fields) or <code>--show --field number</code> —
|
|
334
339
|
the browser and the mobile gateway never carry the values, and mobile cannot create
|
|
335
340
|
structured entries at all.</p>
|
|
341
|
+
|
|
342
|
+
<p><strong><code>login</code> is storage only, and that is a design constraint, not a
|
|
343
|
+
gap.</strong> C3 has no browser surface and must not grow one: a login runner in which the
|
|
344
|
+
<em>agent</em> picks the destination URL turns page-content prompt injection into credential
|
|
345
|
+
exfiltration, and a check written into a script that already holds the plaintext in its own
|
|
346
|
+
environment is not a boundary — the script can simply not call it. That is what
|
|
347
|
+
<code>canonical_origin</code> is for: https-only, stored normalized
|
|
348
|
+
(<code>scheme://host[:port]</code>, no path/query/fragment/userinfo, host lowercased), so a
|
|
349
|
+
separate <em>out-of-process</em> runner that the agent does not author can pin a credential to
|
|
350
|
+
exactly one origin and check the live top-level frame before typing. That runner is
|
|
351
|
+
deliberately not shipped in this package. <code>totp_secret</code> must be base32 — a
|
|
352
|
+
malformed seed produces wrong codes that look exactly like a wrong password.</p>
|
|
336
353
|
</section>
|
|
337
354
|
|
|
338
355
|
<hr class="divider">
|
|
@@ -168,9 +168,10 @@
|
|
|
168
168
|
<div class="step-grid">
|
|
169
169
|
<div class="step-card">
|
|
170
170
|
<span class="step-num">1</span><h4>Start the Oracle</h4>
|
|
171
|
-
<pre><code>
|
|
172
|
-
|
|
173
|
-
|
|
171
|
+
<pre><code>c3 oracle serve --no-browser
|
|
172
|
+
<span class="com"># or: run it at login, no terminal window</span>
|
|
173
|
+
c3 oracle serve --install</code></pre>
|
|
174
|
+
<p style="font-size: 12px; color: var(--text-dim); margin: 8px 0 0;">Prints the REST + MCP URLs and ensures an API key exists. The MCP server starts in a background thread. <code>--install</code> registers a windowless background service (Task Scheduler / launchd / systemd) and starts it now — the same buttons live in <strong>Hub → Settings → Oracle service</strong>.</p>
|
|
174
175
|
</div>
|
|
175
176
|
<div class="step-card">
|
|
176
177
|
<span class="step-num">2</span><h4>Get the token</h4>
|
|
@@ -325,8 +326,14 @@ curl -X POST \
|
|
|
325
326
|
<tr><td><code>c3 oracle api key</code></td> <td>Print just the token (generating one if needed)</td></tr>
|
|
326
327
|
<tr><td><code>c3 oracle api rotate</code></td> <td>Replace the token with a fresh one</td></tr>
|
|
327
328
|
<tr><td><code>c3 oracle api clear</code></td> <td>Delete the stored token from the keyring</td></tr>
|
|
329
|
+
<tr><td><code>c3 oracle serve</code></td> <td>Run the dashboard + discovery endpoints in this terminal (<code>--no-browser</code>, <code>--port</code>)</td></tr>
|
|
330
|
+
<tr><td><code>c3 oracle serve --install</code></td> <td>Register the Oracle as a login/startup service — no terminal window — and start it now. Windows: Task Scheduler (Run-key fallback); macOS: launchd; Linux: systemd user unit</td></tr>
|
|
331
|
+
<tr><td><code>c3 oracle serve --uninstall</code></td> <td>Remove the startup registration (a running Oracle keeps running)</td></tr>
|
|
332
|
+
<tr><td><code>c3 oracle serve --status</code></td> <td>Installed? Running? Port, bind host, URL, and the launcher log path</td></tr>
|
|
333
|
+
<tr><td><code>c3 oracle open</code></td> <td>Sign in to a running dashboard via a single-use URL</td></tr>
|
|
328
334
|
</tbody>
|
|
329
335
|
</table>
|
|
336
|
+
<p style="font-size: 12px; color: var(--text-dim); margin: 8px 0 0;">The Hub exposes the same controls under <strong>Settings → Oracle service</strong> (Install / Uninstall / Start / Stop / Open). Starting the Oracle from there also fills in the Hub's <em>Oracle URL</em> when it is empty, so the Open Oracle button appears in the top bar.</p>
|
|
330
337
|
</section>
|
|
331
338
|
|
|
332
339
|
<hr class="divider">
|
|
@@ -373,6 +380,14 @@ curl -X POST \
|
|
|
373
380
|
<td><code>The 'keyring' package is required</code></td>
|
|
374
381
|
<td><code>pip install keyring</code> — a C3 dependency that may be missing if you upgraded without re-installing.</td>
|
|
375
382
|
</tr>
|
|
383
|
+
<tr>
|
|
384
|
+
<td>Oracle is down after a reboot</td>
|
|
385
|
+
<td>Nothing restarts a terminal-launched Oracle. Register it once with <code>c3 oracle serve --install</code> (or Hub → Settings → Oracle service → Install); it then starts at login with no window. Startup problems land in <code>~/.c3/oracle/service.log</code> (the launcher) and <code>~/.c3/oracle/oracle.log</code> (the server).</td>
|
|
386
|
+
</tr>
|
|
387
|
+
<tr>
|
|
388
|
+
<td>Installed, but "stopped" right after login</td>
|
|
389
|
+
<td>If <code>bind_host</code> is a LAN/VPN address, the launcher waits up to 120 s for that address to come up before binding, and Task Scheduler retries a failed start three times a minute apart. Check <code>service.log</code> for <em>waiting for bind host</em>; if the address never appears, the Oracle starts anyway and fails to bind — fix the interface or set <code>bind_host</code> to <code>0.0.0.0</code>.</td>
|
|
390
|
+
</tr>
|
|
376
391
|
</tbody>
|
|
377
392
|
</table>
|
|
378
393
|
</section>
|
|
@@ -3407,6 +3407,63 @@ def api_hub_restart():
|
|
|
3407
3407
|
return jsonify({"restarting": True})
|
|
3408
3408
|
|
|
3409
3409
|
|
|
3410
|
+
# ─── Routes: oracle service (background daemon for `c3 oracle serve`) ───────
|
|
3411
|
+
#
|
|
3412
|
+
# Same shape as the hub's own service routes above. Port and bind host come
|
|
3413
|
+
# from ~/.c3/oracle/config.json, not from the hub config. A successful
|
|
3414
|
+
# install/start fills an EMPTY hub `oracle_url` with the Oracle's address so
|
|
3415
|
+
# the top bar's Open Oracle link appears without a second trip to settings.
|
|
3416
|
+
|
|
3417
|
+
def _oracle_service():
|
|
3418
|
+
from services.oracle_service import OracleService
|
|
3419
|
+
return OracleService()
|
|
3420
|
+
|
|
3421
|
+
|
|
3422
|
+
def _adopt_oracle_url(svc, result: dict) -> dict:
|
|
3423
|
+
result = dict(result or {})
|
|
3424
|
+
if not result.get("success"):
|
|
3425
|
+
return result
|
|
3426
|
+
cfg = _read_hub_config()
|
|
3427
|
+
if not (cfg.get("oracle_url") or "").strip():
|
|
3428
|
+
cfg["oracle_url"] = svc.url()
|
|
3429
|
+
_write_hub_config(cfg)
|
|
3430
|
+
result["oracle_url_set"] = True
|
|
3431
|
+
result["oracle_url"] = cfg["oracle_url"]
|
|
3432
|
+
return result
|
|
3433
|
+
|
|
3434
|
+
|
|
3435
|
+
@app.route("/api/oracle/service", methods=["GET"])
|
|
3436
|
+
def api_oracle_service_status():
|
|
3437
|
+
"""Whether the Oracle is registered as a startup service / currently up."""
|
|
3438
|
+
return jsonify(_oracle_service().status())
|
|
3439
|
+
|
|
3440
|
+
|
|
3441
|
+
@app.route("/api/oracle/service/install", methods=["POST"])
|
|
3442
|
+
def api_oracle_service_install():
|
|
3443
|
+
"""Register the Oracle to start at login (windowless) and start it now."""
|
|
3444
|
+
svc = _oracle_service()
|
|
3445
|
+
return jsonify(_adopt_oracle_url(svc, svc.install()))
|
|
3446
|
+
|
|
3447
|
+
|
|
3448
|
+
@app.route("/api/oracle/service/uninstall", methods=["POST"])
|
|
3449
|
+
def api_oracle_service_uninstall():
|
|
3450
|
+
"""Remove the Oracle's startup registration (does not stop a running one)."""
|
|
3451
|
+
return jsonify(_oracle_service().uninstall())
|
|
3452
|
+
|
|
3453
|
+
|
|
3454
|
+
@app.route("/api/oracle/service/start", methods=["POST"])
|
|
3455
|
+
def api_oracle_service_start():
|
|
3456
|
+
"""Start the Oracle as a detached background process (no terminal)."""
|
|
3457
|
+
svc = _oracle_service()
|
|
3458
|
+
return jsonify(_adopt_oracle_url(svc, svc.start()))
|
|
3459
|
+
|
|
3460
|
+
|
|
3461
|
+
@app.route("/api/oracle/service/stop", methods=["POST"])
|
|
3462
|
+
def api_oracle_service_stop():
|
|
3463
|
+
"""Kill the Oracle process listening on its configured port."""
|
|
3464
|
+
return jsonify(_oracle_service().stop())
|
|
3465
|
+
|
|
3466
|
+
|
|
3410
3467
|
# ─── Routes: sessions ────────────────────────────────────────────────────────
|
|
3411
3468
|
|
|
3412
3469
|
@app.route("/api/sessions/start", methods=["POST"])
|
|
@@ -142,7 +142,8 @@ function App() {
|
|
|
142
142
|
onOpenProject={(p, tab) => { setSearchOpen(false); openDrill(p, tab || 'overview'); }} />
|
|
143
143
|
{modal &&
|
|
144
144
|
<HubModals modal={modal} projects={projects}
|
|
145
|
-
onClose={() => setModal(null)}
|
|
145
|
+
onClose={() => setModal(null)}
|
|
146
|
+
onChanged={() => { loadConfig(); loadProjects(); }} />}
|
|
146
147
|
<ToastHost />
|
|
147
148
|
</div>
|
|
148
149
|
);
|
{code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hub_ui/components/hub_credentials.js
RENAMED
|
@@ -15,10 +15,14 @@ const HUB_CREDS_EMPTY_FORM = {
|
|
|
15
15
|
fields: {},
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
-
// Structured kinds (v2.87.0): per-type field sets composed
|
|
19
|
-
// object client-side. `hidden` fields render as password inputs.
|
|
20
|
-
// entries are inject-only — the server refuses agent_readable/inject and
|
|
18
|
+
// Structured kinds (v2.87.0; `login` v2.90.0): per-type field sets composed
|
|
19
|
+
// into a JSON object client-side. `hidden` fields render as password inputs.
|
|
20
|
+
// These entries are inject-only — the server refuses agent_readable/inject and
|
|
21
21
|
// there is no reveal path anywhere.
|
|
22
|
+
// This table MUST mirror services/credential_store._SCHEMAS — a kind the store
|
|
23
|
+
// accepts and this table omits is unreachable from the browser and, worse,
|
|
24
|
+
// renders as a plain secret with exposure toggles the server will refuse.
|
|
25
|
+
// tests/test_credential_ui_parity.py asserts the two stay in step.
|
|
22
26
|
const CREDS_STRUCTURED = {
|
|
23
27
|
card: { required: ['cardholder', 'number', 'expiry'],
|
|
24
28
|
optional: ['cvc', 'billing_zip'], hidden: ['number', 'cvc'] },
|
|
@@ -26,11 +30,20 @@ const CREDS_STRUCTURED = {
|
|
|
26
30
|
optional: ['recipient', 'street2', 'country', 'phone'], hidden: [] },
|
|
27
31
|
identity: { required: ['full_name'],
|
|
28
32
|
optional: ['dob', 'ssn', 'phone', 'email'], hidden: ['ssn', 'dob'] },
|
|
33
|
+
login: { required: ['site_id', 'canonical_origin', 'username', 'password'],
|
|
34
|
+
optional: ['totp_secret'], hidden: ['password', 'totp_secret'] },
|
|
29
35
|
};
|
|
30
36
|
|
|
31
37
|
const credsDisplayText = (entry) => {
|
|
32
38
|
const d = entry.display || {};
|
|
33
39
|
if (entry.type === 'card') return `${d.brand || 'card'} ••••${d.last4 || '????'}`;
|
|
40
|
+
// login's projection carries has_totp as a BOOLEAN — the generic join below
|
|
41
|
+
// would render it as the word "true". Username is absent by design.
|
|
42
|
+
if (entry.type === 'login') {
|
|
43
|
+
const bits = [d.site_id, d.origin].filter(Boolean);
|
|
44
|
+
if (d.has_totp) bits.push('2FA');
|
|
45
|
+
return bits.join(' · ');
|
|
46
|
+
}
|
|
34
47
|
const vals = Object.values(d).filter(Boolean);
|
|
35
48
|
return vals.length ? vals.join(', ') : '';
|
|
36
49
|
};
|
|
@@ -1168,6 +1181,7 @@ function CredsManager({ path, projectName, onChanged }) {
|
|
|
1168
1181
|
<option value="card">card — credit/debit card (inject-only)</option>
|
|
1169
1182
|
<option value="address">address — postal address (inject-only)</option>
|
|
1170
1183
|
<option value="identity">identity — personal info (inject-only)</option>
|
|
1184
|
+
<option value="login">login — website login (inject-only, storage only)</option>
|
|
1171
1185
|
</select>
|
|
1172
1186
|
</div>
|
|
1173
1187
|
<div>
|
|
@@ -1192,6 +1206,15 @@ function CredsManager({ path, projectName, onChanged }) {
|
|
|
1192
1206
|
(<span className="mono">{'{{cred:NAME.field}}'}</span> /{' '}
|
|
1193
1207
|
<span className="mono">env_creds='NAME.field'</span>) but can never
|
|
1194
1208
|
reveal them, and they never auto-inject.
|
|
1209
|
+
{form.type === 'login' && (
|
|
1210
|
+
<div style={{ marginTop: 4 }}>
|
|
1211
|
+
Storage only — C3 has no browser and does not log in to anything.{' '}
|
|
1212
|
+
<span className="mono">canonical_origin</span> is https-only and
|
|
1213
|
+
stored normalized so a separate out-of-process runner can pin this
|
|
1214
|
+
credential to exactly one origin before typing it.{' '}
|
|
1215
|
+
<span className="mono">totp_secret</span> is base32.
|
|
1216
|
+
</div>
|
|
1217
|
+
)}
|
|
1195
1218
|
</div>
|
|
1196
1219
|
) : (
|
|
1197
1220
|
<div style={{ display: 'flex', gap: 18, marginTop: 10, fontSize: 12, color: T.text }}>
|
{code_context_control-2.89.1 → code_context_control-2.91.0}/cli/hub_ui/components/settings_modal.js
RENAMED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
// ─── Hub settings modal ─────────────────────────────────────────
|
|
2
2
|
// Config: GET/POST /api/hub/config {port, auto_open_browser, oracle_url,
|
|
3
|
-
// runtime_cache_size}.
|
|
3
|
+
// runtime_cache_size}. Hub service: GET /api/hub/service + POST
|
|
4
4
|
// /api/hub/service/install|uninstall|start|stop. Restart: POST /api/hub/restart.
|
|
5
|
+
// Oracle service: GET /api/oracle/service + POST
|
|
6
|
+
// /api/oracle/service/install|uninstall|start|stop — runs `c3 oracle serve`
|
|
7
|
+
// windowless in the background; install also registers it to start at login.
|
|
5
8
|
// Theme is handled by the topbar; bind host is CLI/config-file only (read-only here).
|
|
6
9
|
|
|
10
|
+
let _oraclePollTimer = null;
|
|
11
|
+
|
|
7
12
|
function SettingsModal({ onClose, onChanged }) {
|
|
8
13
|
const [cfg, setCfg] = useState(null);
|
|
9
14
|
const [port, setPort] = useState('');
|
|
@@ -11,14 +16,32 @@ function SettingsModal({ onClose, onChanged }) {
|
|
|
11
16
|
const [oracleUrl, setOracleUrl] = useState('');
|
|
12
17
|
const [cacheSize, setCacheSize] = useState(8);
|
|
13
18
|
const [saving, setSaving] = useState(false);
|
|
14
|
-
const [svc, setSvc] = useState(null); // {installed, running, method, port, log_path} | {error}
|
|
19
|
+
const [svc, setSvc] = useState(null); // hub: {installed, running, method, port, log_path} | {error}
|
|
15
20
|
const [svcBusy, setSvcBusy] = useState('');
|
|
16
|
-
const [
|
|
21
|
+
const [osvc, setOsvc] = useState(null); // oracle: same shape + {url, bind_host, mcp_port}
|
|
22
|
+
const [osvcBusy, setOsvcBusy] = useState('');
|
|
23
|
+
const [confirmAction, setConfirmAction] = useState(null); // 'stop' | 'uninstall' | 'oracle-stop' | 'oracle-uninstall'
|
|
17
24
|
|
|
18
25
|
const loadSvc = async () => {
|
|
19
26
|
try { setSvc(await api.get('/api/hub/service')); }
|
|
20
27
|
catch { setSvc({ error: true }); }
|
|
21
28
|
};
|
|
29
|
+
const loadOsvc = async () => {
|
|
30
|
+
try { setOsvc(await api.get('/api/oracle/service')); }
|
|
31
|
+
catch { setOsvc({ error: true }); }
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// After a start the Oracle needs a few seconds before /api/health answers —
|
|
35
|
+
// poll until it reports running, give up after ~30 s.
|
|
36
|
+
const pollOsvc = (attempt = 0) => {
|
|
37
|
+
clearTimeout(_oraclePollTimer);
|
|
38
|
+
_oraclePollTimer = setTimeout(async () => {
|
|
39
|
+
let d = null;
|
|
40
|
+
try { d = await api.get('/api/oracle/service'); setOsvc(d); }
|
|
41
|
+
catch { setOsvc({ error: true }); }
|
|
42
|
+
if (d && !d.running && attempt < 12) pollOsvc(attempt + 1);
|
|
43
|
+
}, attempt === 0 ? 1500 : 2500);
|
|
44
|
+
};
|
|
22
45
|
|
|
23
46
|
useEffect(() => {
|
|
24
47
|
(async () => {
|
|
@@ -33,7 +56,9 @@ function SettingsModal({ onClose, onChanged }) {
|
|
|
33
56
|
notify('Could not load hub config', 'err');
|
|
34
57
|
}
|
|
35
58
|
loadSvc();
|
|
59
|
+
loadOsvc();
|
|
36
60
|
})();
|
|
61
|
+
return () => clearTimeout(_oraclePollTimer);
|
|
37
62
|
}, []);
|
|
38
63
|
|
|
39
64
|
const save = async () => {
|
|
@@ -81,6 +106,27 @@ function SettingsModal({ onClose, onChanged }) {
|
|
|
81
106
|
setTimeout(loadSvc, 800);
|
|
82
107
|
};
|
|
83
108
|
|
|
109
|
+
const osvcAction = async (action) => {
|
|
110
|
+
setConfirmAction(null);
|
|
111
|
+
setOsvcBusy(action);
|
|
112
|
+
try {
|
|
113
|
+
const d = await api.post(`/api/oracle/service/${action}`, {});
|
|
114
|
+
const ok = d.success !== false;
|
|
115
|
+
notify(d.output || `Oracle ${action} ${ok ? 'succeeded' : 'failed'}`, ok ? 'ok' : 'err');
|
|
116
|
+
if (ok && d.oracle_url_set) {
|
|
117
|
+
// The hub had no oracle_url; the server filled it so the top-bar link appears.
|
|
118
|
+
setOracleUrl(d.oracle_url || '');
|
|
119
|
+
notify(`Oracle URL set to ${d.oracle_url} — the Open Oracle button is now in the top bar`);
|
|
120
|
+
if (onChanged) onChanged();
|
|
121
|
+
}
|
|
122
|
+
if (ok && (action === 'start' || action === 'install')) pollOsvc();
|
|
123
|
+
} catch (e) {
|
|
124
|
+
notify(`Oracle ${action} failed: ${e.message}`, 'err');
|
|
125
|
+
}
|
|
126
|
+
setOsvcBusy('');
|
|
127
|
+
setTimeout(loadOsvc, 800);
|
|
128
|
+
};
|
|
129
|
+
|
|
84
130
|
const restartHub = async () => {
|
|
85
131
|
try { await api.post('/api/hub/restart', {}); } catch { /* server drops mid-response */ }
|
|
86
132
|
notify('Hub restarting…', 'warn');
|
|
@@ -109,16 +155,56 @@ function SettingsModal({ onClose, onChanged }) {
|
|
|
109
155
|
fontSize: 13, outline: 'none', fontFamily: 'inherit',
|
|
110
156
|
});
|
|
111
157
|
|
|
158
|
+
// Shared status line for both service blocks.
|
|
159
|
+
const svcSummary = (s) => {
|
|
160
|
+
let label, color;
|
|
161
|
+
if (!s) { label = 'checking…'; color = T.textMuted; }
|
|
162
|
+
else if (s.error) { label = 'unavailable'; color = T.error; }
|
|
163
|
+
else if (!s.installed) {
|
|
164
|
+
label = s.running === true ? 'running (not installed)' : 'not installed';
|
|
165
|
+
color = s.running === true ? T.accent : T.textMuted;
|
|
166
|
+
} else {
|
|
167
|
+
label = s.running === true ? 'running' : s.running === false ? 'stopped' : 'installed';
|
|
168
|
+
color = s.running !== false ? T.accent : T.textMuted;
|
|
169
|
+
}
|
|
170
|
+
return { label, color };
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
const serviceStatus = (s) => {
|
|
174
|
+
const { label, color } = svcSummary(s);
|
|
175
|
+
return (
|
|
176
|
+
<div>
|
|
177
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 8 }}>
|
|
178
|
+
<GlowDot color={color} />
|
|
179
|
+
<span className="mono" style={{ fontSize: 12, color }}>{label}</span>
|
|
180
|
+
{s && !s.error && s.method && (
|
|
181
|
+
<span className="mono" style={{ fontSize: 11, color: T.textDim }}>
|
|
182
|
+
{s.method}{s.port ? ` (port ${s.port})` : ''}
|
|
183
|
+
</span>
|
|
184
|
+
)}
|
|
185
|
+
</div>
|
|
186
|
+
{s && !s.error && s.log_path && (
|
|
187
|
+
<div className="mono" style={{ fontSize: 11, color: T.textDim, marginBottom: 8, wordBreak: 'break-all' }}>
|
|
188
|
+
log: {s.log_path}
|
|
189
|
+
</div>
|
|
190
|
+
)}
|
|
191
|
+
</div>
|
|
192
|
+
);
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
const busyLine = (what) => (
|
|
196
|
+
<div style={{ fontSize: 11, color: T.textMuted, marginTop: 8, animation: 'pulse 1s infinite' }}>
|
|
197
|
+
{what}…
|
|
198
|
+
</div>
|
|
199
|
+
);
|
|
200
|
+
|
|
112
201
|
const svcInstalled = svc && !svc.error && svc.installed;
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
const svcColor = !svc ? T.textMuted
|
|
120
|
-
: svc.error ? T.error
|
|
121
|
-
: (svc.installed && svc.running !== false) ? T.accent : T.textMuted;
|
|
202
|
+
const osvcInstalled = osvc && !osvc.error && osvc.installed;
|
|
203
|
+
const osvcRunning = osvc && !osvc.error && osvc.running === true;
|
|
204
|
+
const openOracle = () => {
|
|
205
|
+
const url = oracleUrl.trim() || (osvc && osvc.url) || '';
|
|
206
|
+
if (url) window.open(url, '_blank', 'noopener');
|
|
207
|
+
};
|
|
122
208
|
|
|
123
209
|
return (
|
|
124
210
|
<Modal title="Hub Settings" width={520} onClose={onClose}>
|
|
@@ -138,27 +224,14 @@ function SettingsModal({ onClose, onChanged }) {
|
|
|
138
224
|
), 'Max project runtimes kept warm for drill-in and global search.')}
|
|
139
225
|
{fieldRow('Oracle URL', (
|
|
140
226
|
<input value={oracleUrl} onChange={e => setOracleUrl(e.target.value)}
|
|
141
|
-
placeholder="http://localhost:
|
|
142
|
-
), 'Optional — link to a running C3 Oracle instance.')}
|
|
227
|
+
placeholder="http://localhost:3331" className="mono" style={inputStyle(220)} />
|
|
228
|
+
), 'Optional — link to a running C3 Oracle instance. Filled in automatically when you start the Oracle below.')}
|
|
143
229
|
<div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: 10 }}>
|
|
144
230
|
<Btn onClick={save} disabled={saving || !cfg}>{saving ? 'Saving…' : 'Save settings'}</Btn>
|
|
145
231
|
</div>
|
|
146
232
|
|
|
147
233
|
{sectionLabel('Startup service')}
|
|
148
|
-
|
|
149
|
-
<GlowDot color={svcColor} />
|
|
150
|
-
<span className="mono" style={{ fontSize: 12, color: svcColor }}>{svcLabel}</span>
|
|
151
|
-
{svc && !svc.error && svc.method && (
|
|
152
|
-
<span className="mono" style={{ fontSize: 11, color: T.textDim }}>
|
|
153
|
-
{svc.method}{svc.port ? ` (port ${svc.port})` : ''}
|
|
154
|
-
</span>
|
|
155
|
-
)}
|
|
156
|
-
</div>
|
|
157
|
-
{svc && !svc.error && svc.log_path && (
|
|
158
|
-
<div className="mono" style={{ fontSize: 11, color: T.textDim, marginBottom: 8, wordBreak: 'break-all' }}>
|
|
159
|
-
log: {svc.log_path}
|
|
160
|
-
</div>
|
|
161
|
-
)}
|
|
234
|
+
{serviceStatus(svc)}
|
|
162
235
|
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
|
|
163
236
|
<Btn variant="ghost" onClick={() => svcAction('install')} disabled={!!svcBusy}>
|
|
164
237
|
{svcInstalled ? 'Reinstall' : 'Install'}
|
|
@@ -174,11 +247,7 @@ function SettingsModal({ onClose, onChanged }) {
|
|
|
174
247
|
<I name="refresh" size={12} color={T.textMuted} />Restart hub
|
|
175
248
|
</Btn>
|
|
176
249
|
</div>
|
|
177
|
-
{svcBusy && (
|
|
178
|
-
<div style={{ fontSize: 11, color: T.textMuted, marginTop: 8, animation: 'pulse 1s infinite' }}>
|
|
179
|
-
{svcBusy}…
|
|
180
|
-
</div>
|
|
181
|
-
)}
|
|
250
|
+
{svcBusy && busyLine(svcBusy)}
|
|
182
251
|
{cfg && (
|
|
183
252
|
<div style={{ fontSize: 11, color: T.textDim, marginTop: 10 }}>
|
|
184
253
|
{cfg.has_terminal
|
|
@@ -187,6 +256,40 @@ function SettingsModal({ onClose, onChanged }) {
|
|
|
187
256
|
</div>
|
|
188
257
|
)}
|
|
189
258
|
|
|
259
|
+
{sectionLabel('Oracle service')}
|
|
260
|
+
{serviceStatus(osvc)}
|
|
261
|
+
{osvc && !osvc.error && (
|
|
262
|
+
<div className="mono" style={{ fontSize: 11, color: T.textDim, marginBottom: 8, wordBreak: 'break-all' }}>
|
|
263
|
+
bind {osvc.bind_host || '127.0.0.1'} · MCP port {osvc.mcp_port || 3332} · {osvc.url}
|
|
264
|
+
</div>
|
|
265
|
+
)}
|
|
266
|
+
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
|
|
267
|
+
<Btn variant="ghost" onClick={() => osvcAction('install')} disabled={!!osvcBusy}>
|
|
268
|
+
{osvcInstalled ? 'Reinstall' : 'Install'}
|
|
269
|
+
</Btn>
|
|
270
|
+
{osvcInstalled && (
|
|
271
|
+
<Btn variant="ghost" onClick={() => setConfirmAction('oracle-uninstall')} disabled={!!osvcBusy}>Uninstall</Btn>
|
|
272
|
+
)}
|
|
273
|
+
{!osvcRunning && (
|
|
274
|
+
<Btn variant="ghost" onClick={() => osvcAction('start')} disabled={!!osvcBusy || !osvc}>
|
|
275
|
+
<I name="play" size={12} color={T.textMuted} />Start oracle
|
|
276
|
+
</Btn>
|
|
277
|
+
)}
|
|
278
|
+
{osvcRunning && (
|
|
279
|
+
<Btn variant="ghost" color={T.error} onClick={() => setConfirmAction('oracle-stop')} disabled={!!osvcBusy}>Stop oracle</Btn>
|
|
280
|
+
)}
|
|
281
|
+
{osvcRunning && (
|
|
282
|
+
<Btn variant="ghost" onClick={openOracle}>
|
|
283
|
+
<I name="external" size={12} color={T.textMuted} />Open
|
|
284
|
+
</Btn>
|
|
285
|
+
)}
|
|
286
|
+
</div>
|
|
287
|
+
{osvcBusy && busyLine(`oracle ${osvcBusy}`)}
|
|
288
|
+
<div style={{ fontSize: 11, color: T.textDim, marginTop: 10 }}>
|
|
289
|
+
Runs <span className="mono">c3 oracle serve</span> in the background — no terminal window.
|
|
290
|
+
Install also registers it to start at login, so it survives reboots.
|
|
291
|
+
</div>
|
|
292
|
+
|
|
190
293
|
{confirmAction === 'stop' && (
|
|
191
294
|
<ConfirmDialog title="Stop Hub"
|
|
192
295
|
message="The page will become unreachable until the hub is restarted (c3 hub)."
|
|
@@ -199,6 +302,18 @@ function SettingsModal({ onClose, onChanged }) {
|
|
|
199
302
|
confirmLabel="Uninstall" danger
|
|
200
303
|
onConfirm={() => svcAction('uninstall')} onCancel={() => setConfirmAction(null)} />
|
|
201
304
|
)}
|
|
305
|
+
{confirmAction === 'oracle-stop' && (
|
|
306
|
+
<ConfirmDialog title="Stop Oracle"
|
|
307
|
+
message="Kills the Oracle process (dashboard, discovery API and MCP endpoint). It will start again at the next login if installed, or via Start oracle."
|
|
308
|
+
confirmLabel="Stop" danger
|
|
309
|
+
onConfirm={() => osvcAction('stop')} onCancel={() => setConfirmAction(null)} />
|
|
310
|
+
)}
|
|
311
|
+
{confirmAction === 'oracle-uninstall' && (
|
|
312
|
+
<ConfirmDialog title="Uninstall Oracle Service"
|
|
313
|
+
message="The Oracle will no longer auto-start on login. A running Oracle keeps running."
|
|
314
|
+
confirmLabel="Uninstall" danger
|
|
315
|
+
onConfirm={() => osvcAction('uninstall')} onCancel={() => setConfirmAction(null)} />
|
|
316
|
+
)}
|
|
202
317
|
</Modal>
|
|
203
318
|
);
|
|
204
319
|
}
|
|
@@ -1039,15 +1039,19 @@ async def c3_credentials(
|
|
|
1039
1039
|
often it was used: counts by surface, recent events for THIS project, other
|
|
1040
1040
|
projects reduced to counts), reveal (name — only entries the user marked
|
|
1041
1041
|
agent_readable), set (name, value [scope=project|global]
|
|
1042
|
-
[ctype=token|env|multiline|address|identity|card] [description] [env_var]
|
|
1043
|
-
delete (name [scope]).
|
|
1042
|
+
[ctype=token|env|multiline|address|identity|card|login] [description] [env_var]
|
|
1043
|
+
[inject]), delete (name [scope]).
|
|
1044
1044
|
To USE a credential, do NOT reveal it — pass env_creds='NAME1,NAME2' to c3_shell
|
|
1045
1045
|
(injected as env vars) or write {{cred:NAME}} inside the cmd (expanded server-side);
|
|
1046
1046
|
the decoded value never enters model context.
|
|
1047
|
-
STRUCTURED kinds (address/identity/card) hold named fields: set takes value
|
|
1048
|
-
JSON object (card: cardholder/number/expiry[/cvc/billing_zip]; address:
|
|
1047
|
+
STRUCTURED kinds (address/identity/card/login) hold named fields: set takes value
|
|
1048
|
+
as a JSON object (card: cardholder/number/expiry[/cvc/billing_zip]; address:
|
|
1049
1049
|
street1/city/state/zip[/recipient/street2/country/phone]; identity:
|
|
1050
|
-
full_name[/dob/ssn/phone/email]
|
|
1050
|
+
full_name[/dob/ssn/phone/email]; login: site_id/canonical_origin/username/password
|
|
1051
|
+
[/totp_secret]). `login` is STORAGE ONLY — C3 has no browser and never types a
|
|
1052
|
+
password anywhere. canonical_origin is https-only and stored normalized so an
|
|
1053
|
+
external runner can bind the credential to one origin; do NOT build a browser
|
|
1054
|
+
login runner in this package. Address a FIELD at the boundary —
|
|
1051
1055
|
env_creds='CARD.number' (env $CARD_NUMBER) or {{cred:CARD.number}} in cmd. Reveal
|
|
1052
1056
|
is permanently disabled for them and they never auto-inject; have the user enter
|
|
1053
1057
|
the values via the Credentials UI or `c3 creds set` so they never enter the chat.
|
|
@@ -9,9 +9,17 @@ credential is c3_shell: ``env_creds='NAME1,NAME2'`` (env injection) or
|
|
|
9
9
|
``{{cred:NAME}}`` in the command (server-side expansion) — the decoded value
|
|
10
10
|
never enters model context.
|
|
11
11
|
|
|
12
|
-
Structured kinds (address/identity/card) go further: reveal is permanently
|
|
12
|
+
Structured kinds (address/identity/card/login) go further: reveal is permanently
|
|
13
13
|
disabled regardless of flags, and only individual FIELDS are addressable —
|
|
14
14
|
``env_creds='CARD.number'`` or ``{{cred:CARD.number}}``.
|
|
15
|
+
|
|
16
|
+
``login`` is storage only. C3 has no browser surface and must not grow one:
|
|
17
|
+
a login runner in which the AGENT chooses the destination URL turns page-content
|
|
18
|
+
prompt injection into credential exfiltration, and a guard written into a script
|
|
19
|
+
that already holds the plaintext is not a boundary. The ``canonical_origin``
|
|
20
|
+
field is stored (https-only, normalized) so that a separate, out-of-process
|
|
21
|
+
runner can pin the credential to one origin and validate the live top-level
|
|
22
|
+
frame before typing. That runner is deliberately somebody else's package.
|
|
15
23
|
"""
|
|
16
24
|
from __future__ import annotations
|
|
17
25
|
|