code-context-control 2.92.4__tar.gz → 2.96.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.4/code_context_control.egg-info → code_context_control-2.96.0}/PKG-INFO +4 -4
- {code_context_control-2.92.4 → code_context_control-2.96.0}/README.md +3 -3
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/c3.py +313 -13
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/commands/parser.py +40 -2
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/guide/credentials.html +115 -7
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/guide/tools.html +16 -1
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/guide/workflow.html +40 -10
- code_context_control-2.96.0/cli/hook_session_stats.py +154 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_server.py +465 -9
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/app.js +2 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/drill_panel.js +6 -2
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/drill_views.js +2 -1
- code_context_control-2.96.0/cli/hub_ui/components/hub_cred_audit.js +255 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/hub_credentials.js +782 -71
- code_context_control-2.96.0/cli/hub_ui/components/hub_tokens.js +384 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/modals.js +309 -16
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/project_card.js +26 -24
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/project_tree.js +44 -40
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/topbar.js +1 -1
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/state.js +46 -11
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/mcp_server.py +22 -3
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/server.py +112 -4
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/credentials.py +69 -4
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/federate.py +7 -3
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/project.py +77 -20
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/components/credentials.js +234 -38
- {code_context_control-2.92.4 → code_context_control-2.96.0/code_context_control.egg-info}/PKG-INFO +4 -4
- {code_context_control-2.92.4 → code_context_control-2.96.0}/code_context_control.egg-info/SOURCES.txt +8 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/c3_bridge.py +31 -5
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/federated_graph.py +21 -2
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/project_scanner.py +19 -9
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/tool_registry.py +10 -5
- {code_context_control-2.92.4 → code_context_control-2.96.0}/pyproject.toml +1 -1
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/claude_md.py +2 -2
- code_context_control-2.96.0/services/cred_audit.py +248 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/credential_store.py +441 -53
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/project_manager.py +30 -2
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/repo_map.py +6 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/session_manager.py +70 -2
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/subprojects.py +426 -56
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/telemetry.py +145 -1
- code_context_control-2.96.0/tests/test_cred_audit.py +229 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_credential_store.py +147 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_credentials_routes.py +120 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_credentials_tool.py +106 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_creds_cli_smoke.py +40 -0
- code_context_control-2.96.0/tests/test_env_parser.py +159 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_hub_credentials_routes_write.py +160 -0
- code_context_control-2.96.0/tests/test_subproject_depth_consumers.py +205 -0
- code_context_control-2.96.0/tests/test_subproject_linkage_api.py +305 -0
- code_context_control-2.96.0/tests/test_subprojects.py +651 -0
- code_context_control-2.96.0/tests/test_token_tracking.py +321 -0
- code_context_control-2.96.0/tests/test_ui_jsx_syntax.py +149 -0
- code_context_control-2.92.4/cli/hook_session_stats.py +0 -69
- code_context_control-2.92.4/tests/test_subprojects.py +0 -294
- code_context_control-2.92.4/tests/test_ui_jsx_syntax.py +0 -68
- {code_context_control-2.92.4 → code_context_control-2.96.0}/LICENSE +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/__init__.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/_hook_utils.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/_shell_writes.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/commands/__init__.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/commands/common.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/docs.html +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/edits.html +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/guide/access.html +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/guide/bitbucket.html +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/guide/getting-started.html +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/guide/index.html +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/guide/masking.html +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/guide/oracle.html +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/guide/shared.css +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hook_access_guard.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hook_artifact.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hook_auto_snapshot.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hook_c3_signal.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hook_c3read.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hook_dispatch.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hook_edit_ledger.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hook_edit_unlock.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hook_filter.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hook_ghost_files.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hook_pretool_enforce.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hook_prompt_recall.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hook_read.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hook_terse_advisor.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/add_project.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/config_editor.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/drill_artifacts.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/drill_health.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/drill_subprojects.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/drill_tasks.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/global_search.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/hub_ci.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/hub_enforcement.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/hub_locks.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/mcp_manager.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/session_drawer.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/settings_modal.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/sidebar.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/summary_bar.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/task_board.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui/components/toasts.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/hub_ui.html +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/mcp_proxy.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/progress.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/__init__.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/_grants.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/_helpers.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/agent.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/artifacts.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/bitbucket.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/ci.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/compress.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/delegate.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/edit.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/edit_verify.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/edits.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/filter.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/impact.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/jira.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/locks.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/memory.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/override.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/read.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/search.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/session.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/shell.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/status.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/tasks.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/tools/validate.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/api.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/app.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/components/access.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/components/bitbucket.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/components/chat.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/components/dashboard.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/components/edits.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/components/enforcement.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/components/instructions.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/components/jira.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/components/memory.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/components/sessions.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/components/settings.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/components/sidebar.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/components/tasks.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/icons.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/pm_shared.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/shared.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui/theme.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui.html +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui_legacy.html +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/cli/ui_nano.html +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/code_context_control.egg-info/dependency_links.txt +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/code_context_control.egg-info/entry_points.txt +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/code_context_control.egg-info/requires.txt +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/code_context_control.egg-info/top_level.txt +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/core/__init__.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/core/config.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/core/ide.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/core/mcp_toml.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/core/web_security.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/__init__.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/config.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/mcp_oracle.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/oracle_server.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/oracle_ui.html +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/__init__.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/activity_reporter.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/api_auth.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/chat_engine.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/chat_poll.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/chat_store.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/cross_memory.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/discovery_audit.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/health_checker.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/insight_engine.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/local_session.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/memory_reader.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/memory_writer.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/mobile_api.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/review_agent.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/services/tool_executor.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/activity.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/agents.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/app.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/busy.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/chat/conversations.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/chat/input.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/chat/markdown.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/chat/send.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/chat/stream_renderer.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/chat/toolbar.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/core.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/crossgraph.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/header.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/insights.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/projects.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/qrcode.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/settings.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/suggestions.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/oracle/ui/theme_tabs.js +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/__init__.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/access_guard.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/access_telemetry.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/activity_log.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/agent_base.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/agent_locks.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/agents.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/artifact_defs.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/artifact_store.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/auto_memory.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/background_service.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/bench/__init__.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/bench/external/__init__.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/bench/external/aider_polyglot.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/bench/external/swe_bench.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/benchmark_dashboard.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/bitbucket_client.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/bitbucket_credentials.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/ci_act.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/ci_cache.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/ci_expr.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/ci_failures.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/ci_github.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/ci_impact.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/ci_intel.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/ci_runner.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/ci_workflow.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/circuit_breaker.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/compressor.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/context_snapshot.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/conversation_store.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/cred_telemetry.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/doc_index.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/e2e_benchmark.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/e2e_evaluator.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/e2e_tasks.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/edit_ledger.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/embedding_index.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/enforcement_policy.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/error_reporting.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/file_memory.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/git_context.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/hub_service.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/indexer.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/jira_client.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/jira_cloud.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/jira_credentials.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/jira_data_center.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/jira_links.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/mask_activation.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/mask_mirror.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/mask_presets.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/memory.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/memory_consolidator.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/memory_distiller.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/memory_graph.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/memory_grounder.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/memory_queue.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/memory_scorer.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/metrics.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/notifications.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/ollama_bridge.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/ollama_client.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/ollama_credentials.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/oracle_service.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/output_filter.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/override_grants.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/override_policy.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/override_requests.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/override_wake.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/parser.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/project_runtime.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/protocol.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/proxy_state.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/repo_shape.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/retention.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/retrieval_broker.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/router.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/runtime.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/scanner.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/session_benchmark.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/session_preloader.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/task_store.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/text_index.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/time_tracker.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/tool_classifier.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/transcript_index.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/validation_cache.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/vector_store.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/watcher.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/services/win_subprocess.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/setup.cfg +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_access_builtin_optout.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_access_guard.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_access_guard_meta.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_access_guard_shell_project.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_access_guard_surfaces.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_access_guard_wiring.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_activity_reporter.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_agent_locks.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_aider_polyglot.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_antigravity_transition.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_artifact_store.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_artifact_tool.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_background_service.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_bitbucket_cli_smoke.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_bitbucket_client.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_bitbucket_config_fallback.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_bitbucket_credentials.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_bitbucket_tool.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_c3_bridge_project_artifacts.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_c3_shell.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_chat_poll.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_ci_act.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_ci_cache.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_ci_expr.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_ci_impact.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_ci_intel.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_ci_runner.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_ci_workflow.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_circuit_breaker.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_claude_md_merge.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_cli_smoke.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_compressor_large_file.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_cooccurrence_bounds.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_cred_telemetry.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_credential_login_kind.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_credential_ui_parity.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_delegate_cascade.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_delegate_version_probe.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_e2e_benchmark.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_edit_ledger_deadline.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_edit_ledger_hook.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_edit_locking.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_edit_normalization.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_edit_verify.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_embedding_index_deadlock.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_enforcement_flip.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_enforcement_policy.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_enforcement_routes.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_failed_calls_do_not_unlock.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_federated_graph.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_filter_backoff.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_ghost_files.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_ghost_generation.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_git_branch_awareness.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_hook_access_guard.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_hook_codex_compat.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_hook_dispatch.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_hook_pretool_enforce.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_hook_prompt_recall.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_hook_smoke.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_hook_state.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_hook_utf8_stdio.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_hub_credentials_route.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_hub_enforcement_routes.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_hub_inspect_api.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_hub_locks_routes.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_hub_oracle_service_routes.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_hub_server_smoke.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_hub_subproject_links.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_ide_workflow_adaptation.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_init_clear_preserves_user_content.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_init_scan.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_install_mcp_entrypoint.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_jira_cli_smoke.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_jira_client.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_jira_config_fallback.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_jira_credentials.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_jira_links.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_jira_routes.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_jira_tool.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_lazy_store_init.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_mask_guard.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_mask_routes.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_mask_surfaces.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_mcp_host_guard.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_mcp_memory_timeout.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_mcp_server_smoke.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_mcp_toml.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_memory_distiller.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_memory_graph_api.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_memory_queue.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_memory_system.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_mobile_api.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_mobile_extras.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_mobile_override_routes.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_mobile_security_api.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_no_stale_model_pins.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_notification_dedup.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_notification_discipline.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_ollama_credentials.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_oracle_api_auth.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_oracle_apikey_api.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_oracle_c3_bridge.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_oracle_chat_engine.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_oracle_chat_store.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_oracle_discovery_api.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_oracle_discovery_audit.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_oracle_health_probe.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_oracle_local_auth.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_oracle_ollama_bridge.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_oracle_scanner_cache.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_oracle_security_fixes.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_oracle_session_bootstrap.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_oracle_subproject_awareness.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_oracle_ui_bundle.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_output_filter.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_override_grants.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_override_grants_mcp.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_override_requests.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_override_wake.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_permissions.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_pm_api.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_project_manager.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_project_manager_merge.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_project_tool.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_read_coercion.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_read_edit_parity.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_related_facts.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_repo_map.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_repo_shape.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_response_boilerplate.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_retention.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_review_digest.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_service_durability.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_session_benchmark.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_session_budget.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_shell_creds.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_shell_robustness.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_shell_write_ledger.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_shell_writes.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_subproject_exclusion.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_subproject_federation.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_swe_bench.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_task_store.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_task_tool.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_time_tracker.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_token_telemetry.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_tool_registry.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_upgrade_and_version.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_validate.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_vault_write_guard.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_version_sync.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_web_security.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tests/test_windows_reliability.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tui/__init__.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tui/backend.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tui/main.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tui/screens/__init__.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tui/screens/benchmark_view.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tui/screens/claudemd_view.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tui/screens/compress_view.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tui/screens/index_view.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tui/screens/init_view.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tui/screens/mcp_view.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tui/screens/optimize_view.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tui/screens/pipe_view.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tui/screens/projects_view.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tui/screens/search_view.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tui/screens/session_view.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tui/screens/stats.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tui/screens/ui_view.py +0 -0
- {code_context_control-2.92.4 → code_context_control-2.96.0}/tui/theme.tcss +0 -0
{code_context_control-2.92.4/code_context_control.egg-info → code_context_control-2.96.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.96.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
|
|
@@ -149,7 +149,7 @@ Every C3-initialized project registers itself here on `c3 init`. Filter by activ
|
|
|
149
149
|
|
|
150
150
|
Three top-level views — **Projects**, **Tasks** (a cross-project kanban), and **Credentials** — plus a drill-in panel per project covering Overview, Sub-projects, Tasks, Artifacts, Memory, Ledger, Sessions, Health, Budget, Credentials, Config, and MCP.
|
|
151
151
|
|
|
152
|
-
**Sub-projects** make
|
|
152
|
+
**Sub-projects** make one project a first-class child of another, with its own `.c3`. It can be a nested repo — the parent's index then excludes its subtree — or a project anywhere else on disk, linked by path. Hierarchies nest up to 8 levels, and `c3_search` / `c3_memory` fan out on demand (`scope='all'`, or one by name). → [Sub-projects guide](https://github.com/drknowhow/code-context-control/blob/main/docs/sub-projects.md)
|
|
153
153
|
|
|
154
154
|
### Per-project UI
|
|
155
155
|
|
|
@@ -208,10 +208,10 @@ 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
|
-
| `c3_project` | Cross-project discovery & operations; guarded writes (v2.31.0) |
|
|
214
|
+
| `c3_project` | Cross-project discovery & operations; sub-project hierarchy (link by path, inspect, multi-level tree); guarded writes (v2.31.0) |
|
|
215
215
|
|
|
216
216
|
Every tool is **read-only safe in plan mode** except `c3_edit`, `c3_shell`, `c3_ci(action='run'|'rerun')`, `c3_artifacts(action='restore')`, `c3_delegate` with write delegation enabled, and write actions on `c3_bitbucket` / `c3_jira` / `c3_credentials` / `c3_project` / `c3_task` / `c3_locks`.
|
|
217
217
|
|
|
@@ -86,7 +86,7 @@ Every C3-initialized project registers itself here on `c3 init`. Filter by activ
|
|
|
86
86
|
|
|
87
87
|
Three top-level views — **Projects**, **Tasks** (a cross-project kanban), and **Credentials** — plus a drill-in panel per project covering Overview, Sub-projects, Tasks, Artifacts, Memory, Ledger, Sessions, Health, Budget, Credentials, Config, and MCP.
|
|
88
88
|
|
|
89
|
-
**Sub-projects** make
|
|
89
|
+
**Sub-projects** make one project a first-class child of another, with its own `.c3`. It can be a nested repo — the parent's index then excludes its subtree — or a project anywhere else on disk, linked by path. Hierarchies nest up to 8 levels, and `c3_search` / `c3_memory` fan out on demand (`scope='all'`, or one by name). → [Sub-projects guide](https://github.com/drknowhow/code-context-control/blob/main/docs/sub-projects.md)
|
|
90
90
|
|
|
91
91
|
### Per-project UI
|
|
92
92
|
|
|
@@ -145,10 +145,10 @@ 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
|
-
| `c3_project` | Cross-project discovery & operations; guarded writes (v2.31.0) |
|
|
151
|
+
| `c3_project` | Cross-project discovery & operations; sub-project hierarchy (link by path, inspect, multi-level tree); guarded writes (v2.31.0) |
|
|
152
152
|
|
|
153
153
|
Every tool is **read-only safe in plan mode** except `c3_edit`, `c3_shell`, `c3_ci(action='run'|'rerun')`, `c3_artifacts(action='restore')`, `c3_delegate` with write delegation enabled, and write actions on `c3_bitbucket` / `c3_jira` / `c3_credentials` / `c3_project` / `c3_task` / `c3_locks`.
|
|
154
154
|
|
|
@@ -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.96.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:
|
|
@@ -7795,14 +7986,117 @@ def cmd_sub(args):
|
|
|
7795
7986
|
print(f"No .c3 found in {parent}. Run 'c3 init' there first.")
|
|
7796
7987
|
return
|
|
7797
7988
|
# Import after the cheap guard — the registry module needs a resolvable home.
|
|
7798
|
-
from services.subprojects import
|
|
7989
|
+
from services.subprojects import (
|
|
7990
|
+
MAX_DEPTH,
|
|
7991
|
+
VALID_CASCADE_OPS,
|
|
7992
|
+
SubprojectManager,
|
|
7993
|
+
inspect_path,
|
|
7994
|
+
)
|
|
7799
7995
|
|
|
7800
7996
|
sm = SubprojectManager(parent)
|
|
7801
7997
|
sub = getattr(args, "sub_cmd", "list") or "list"
|
|
7802
7998
|
target = getattr(args, "target", None)
|
|
7803
7999
|
as_json = getattr(args, "json", False)
|
|
8000
|
+
depth = getattr(args, "depth", None) or MAX_DEPTH
|
|
8001
|
+
|
|
8002
|
+
if sub == "inspect":
|
|
8003
|
+
if not target:
|
|
8004
|
+
print("Usage: c3 sub inspect <path> [--json]")
|
|
8005
|
+
return
|
|
8006
|
+
rep = inspect_path(target, detect=not getattr(args, "no_detect", False))
|
|
8007
|
+
if as_json:
|
|
8008
|
+
print(json.dumps(rep, indent=2))
|
|
8009
|
+
return
|
|
8010
|
+
print(f"\n{rep['path']}")
|
|
8011
|
+
if not rep["is_dir"]:
|
|
8012
|
+
print(" not a folder")
|
|
8013
|
+
return
|
|
8014
|
+
proj = rep.get("project")
|
|
8015
|
+
if proj:
|
|
8016
|
+
reg = "registered" if rep["registered"] else "NOT registered"
|
|
8017
|
+
print(f" C3 project: {proj['name']} (v{proj.get('c3_version') or '?'}, "
|
|
8018
|
+
f"ide={proj.get('ide') or '?'}, {reg})")
|
|
8019
|
+
print(f" {proj['facts_count']} facts, {proj['sessions']} sessions, "
|
|
8020
|
+
f"{proj['edit_ledger_entries']} ledger entries, "
|
|
8021
|
+
f"{proj['notification_count']} alerts")
|
|
8022
|
+
else:
|
|
8023
|
+
print(" no .c3 — not a C3 project yet")
|
|
8024
|
+
if rep["ancestors"]:
|
|
8025
|
+
chain = " < ".join(a["name"] for a in rep["ancestors"])
|
|
8026
|
+
print(f" parent chain (depth {rep['depth']}): {chain}")
|
|
8027
|
+
else:
|
|
8028
|
+
print(" top-level (no parent)")
|
|
8029
|
+
if rep["children"]:
|
|
8030
|
+
print(f" {len(rep['children'])} sub-project(s):")
|
|
8031
|
+
for c in rep["children"]:
|
|
8032
|
+
print(f" - {c['name']:<22} [{c['link_kind']}/{c['status']}] {c['path']}")
|
|
8033
|
+
if rep["detected"]:
|
|
8034
|
+
print(f" {len(rep['detected'])} unlinked project(s) detected inside:")
|
|
8035
|
+
for d in rep["detected"]:
|
|
8036
|
+
print(f" ? {d['name']:<22} {d['path']}")
|
|
8037
|
+
print(" (suggestions only — link with `c3 sub link <path>`)")
|
|
8038
|
+
for w in rep["warnings"]:
|
|
8039
|
+
print(f" warning: {w}")
|
|
7804
8040
|
|
|
7805
|
-
|
|
8041
|
+
elif sub == "tree":
|
|
8042
|
+
t = sm.tree(depth=depth)
|
|
8043
|
+
if as_json:
|
|
8044
|
+
print(json.dumps(t, indent=2))
|
|
8045
|
+
return
|
|
8046
|
+
r = t["rollup"]
|
|
8047
|
+
print(f"\n{t['parent']['name']} ({t['parent']['path']})")
|
|
8048
|
+
|
|
8049
|
+
def _render(rows, indent=" "):
|
|
8050
|
+
for row in rows:
|
|
8051
|
+
flag = "" if row["status"] == "ok" else f" [{row['status']}]"
|
|
8052
|
+
kind = "" if row["link_kind"] == "nested" else " (linked)"
|
|
8053
|
+
print(f"{indent}- {row['name']}{kind}{flag}")
|
|
8054
|
+
_render(row.get("children") or [], indent + " ")
|
|
8055
|
+
|
|
8056
|
+
_render(t["children"])
|
|
8057
|
+
if not t["children"]:
|
|
8058
|
+
print(" No sub-projects designated. Use `c3 sub link <path>`.")
|
|
8059
|
+
return
|
|
8060
|
+
line = f"\n{r['children']} descendant(s), {r['direct_children']} direct"
|
|
8061
|
+
if r["issues"]:
|
|
8062
|
+
line += f" -- {r['issues']} with issues (run `c3 sub check --fix`)"
|
|
8063
|
+
print(line)
|
|
8064
|
+
|
|
8065
|
+
elif sub == "link":
|
|
8066
|
+
if not target:
|
|
8067
|
+
print("Usage: c3 sub link <path> [--parent PATH] [--name NAME] [--init]")
|
|
8068
|
+
return
|
|
8069
|
+
# link is designation for a project that already exists anywhere on
|
|
8070
|
+
# disk; add is for a folder this parent should initialize.
|
|
8071
|
+
want_init = getattr(args, "init", False)
|
|
8072
|
+
candidate = target if Path(target).is_absolute() else str(Path(parent) / target)
|
|
8073
|
+
probe = inspect_path(candidate, detect=False)
|
|
8074
|
+
if probe["is_dir"] and not probe["has_c3"] and not want_init:
|
|
8075
|
+
err = (f"not a C3 project: {probe['path']} — "
|
|
8076
|
+
"pass --init to initialize it, or run `c3 init` there first")
|
|
8077
|
+
if as_json:
|
|
8078
|
+
print(json.dumps({"added": False, "error": err}, indent=2))
|
|
8079
|
+
else:
|
|
8080
|
+
print(f"Failed: {err}")
|
|
8081
|
+
return
|
|
8082
|
+
result = sm.add(
|
|
8083
|
+
target,
|
|
8084
|
+
name=getattr(args, "name", None),
|
|
8085
|
+
ide=getattr(args, "ide", None),
|
|
8086
|
+
run_init=want_init,
|
|
8087
|
+
reindex_parent=not getattr(args, "no_reindex_parent", False),
|
|
8088
|
+
)
|
|
8089
|
+
if as_json:
|
|
8090
|
+
print(json.dumps(result, indent=2))
|
|
8091
|
+
return
|
|
8092
|
+
if not result.get("added"):
|
|
8093
|
+
print(f"Failed: {result.get('error')}")
|
|
8094
|
+
return
|
|
8095
|
+
where = "by path" if result["link_kind"] == "external" else f"at {result['rel_path']}"
|
|
8096
|
+
print(f"\n[OK] Linked {result['name']} {where} (depth {result['depth']})")
|
|
8097
|
+
print(f" {result['path']}")
|
|
8098
|
+
|
|
8099
|
+
elif sub == "add":
|
|
7806
8100
|
if not target:
|
|
7807
8101
|
print("Usage: c3 sub add <folder> [--parent PATH] [--name NAME]")
|
|
7808
8102
|
return
|
|
@@ -7835,16 +8129,19 @@ def cmd_sub(args):
|
|
|
7835
8129
|
if not children:
|
|
7836
8130
|
print("No sub-projects designated. Use `c3 sub add <folder>`.")
|
|
7837
8131
|
return
|
|
7838
|
-
fmt = "{:<22} {:<16} {:>6} {:>7} {}"
|
|
7839
|
-
print(fmt.format("NAME", "STATUS", "FACTS", "ALERTS", "
|
|
7840
|
-
print("-" *
|
|
8132
|
+
fmt = "{:<22} {:<16} {:<9} {:>6} {:>7} {}"
|
|
8133
|
+
print(fmt.format("NAME", "STATUS", "LINK", "FACTS", "ALERTS", "LOCATION"))
|
|
8134
|
+
print("-" * 90)
|
|
7841
8135
|
for c in children:
|
|
8136
|
+
# An external child has no rel_path — show where it actually lives.
|
|
8137
|
+
location = c.get("rel_path") or c.get("path", "")
|
|
7842
8138
|
print(fmt.format(
|
|
7843
8139
|
(c.get("name") or "?")[:21],
|
|
7844
8140
|
c.get("status", "?"),
|
|
8141
|
+
c.get("link_kind", "nested"),
|
|
7845
8142
|
c.get("facts_count", 0),
|
|
7846
8143
|
c.get("notification_count", 0),
|
|
7847
|
-
|
|
8144
|
+
location,
|
|
7848
8145
|
))
|
|
7849
8146
|
issues = sum(1 for c in children if c["status"] != "ok")
|
|
7850
8147
|
line = f"\n{len(children)} sub-project(s)"
|
|
@@ -7884,7 +8181,8 @@ def cmd_sub(args):
|
|
|
7884
8181
|
return
|
|
7885
8182
|
result = sm.cascade(target,
|
|
7886
8183
|
include_parent=getattr(args, "include_parent", False),
|
|
7887
|
-
mcp=getattr(args, "mcp", False)
|
|
8184
|
+
mcp=getattr(args, "mcp", False),
|
|
8185
|
+
depth=depth)
|
|
7888
8186
|
if as_json:
|
|
7889
8187
|
print(json.dumps(result, indent=2))
|
|
7890
8188
|
return
|
|
@@ -7905,7 +8203,8 @@ def cmd_sub(args):
|
|
|
7905
8203
|
print("No sub-projects designated.")
|
|
7906
8204
|
return
|
|
7907
8205
|
for c in result["children"]:
|
|
7908
|
-
|
|
8206
|
+
location = c.get("rel_path") or c.get("path", "")
|
|
8207
|
+
print(f" [{c['status']:<16}] {c.get('name') or '?':<22} {location}")
|
|
7909
8208
|
for o in result["orphans"]:
|
|
7910
8209
|
print(f" [orphan_registry ] {o}")
|
|
7911
8210
|
for f in result.get("fixed", []):
|
|
@@ -8769,6 +9068,7 @@ def main():
|
|
|
8769
9068
|
"bitbucket": cmd_bitbucket,
|
|
8770
9069
|
"jira": cmd_jira,
|
|
8771
9070
|
"creds": cmd_creds,
|
|
9071
|
+
"tokens": cmd_tokens,
|
|
8772
9072
|
"access": cmd_access,
|
|
8773
9073
|
"enforce": cmd_enforce,
|
|
8774
9074
|
"override": cmd_override,
|
|
@@ -152,7 +152,7 @@ def build_parser(version: str, parse_cli_ide_arg):
|
|
|
152
152
|
p_sub.add_argument(
|
|
153
153
|
"sub_cmd",
|
|
154
154
|
nargs="?",
|
|
155
|
-
choices=["add", "list", "remove", "run", "check"],
|
|
155
|
+
choices=["add", "link", "inspect", "list", "tree", "remove", "run", "check"],
|
|
156
156
|
default="list",
|
|
157
157
|
help="Sub-command (default: list)",
|
|
158
158
|
)
|
|
@@ -160,7 +160,8 @@ def build_parser(version: str, parse_cli_ide_arg):
|
|
|
160
160
|
"target",
|
|
161
161
|
nargs="?",
|
|
162
162
|
default=None,
|
|
163
|
-
help="Folder (add),
|
|
163
|
+
help="Folder (add), path to an existing project (link|inspect), "
|
|
164
|
+
"sub-project name/path (remove), or operation update|reindex|health (run)",
|
|
164
165
|
)
|
|
165
166
|
p_sub.add_argument("--parent", default=".", help="Parent project path (default: current directory)")
|
|
166
167
|
p_sub.add_argument("--name", default=None, help="Display name for the sub-project (add)")
|
|
@@ -173,6 +174,12 @@ def build_parser(version: str, parse_cli_ide_arg):
|
|
|
173
174
|
p_sub.add_argument("--mcp", action="store_true", help="Also reinstall MCP config on update (run update)")
|
|
174
175
|
p_sub.add_argument("--fix", action="store_true", help="Repair links from the parent config (check)")
|
|
175
176
|
p_sub.add_argument("--prune", action="store_true", help="With --fix: drop entries whose folder is gone (check)")
|
|
177
|
+
p_sub.add_argument("--depth", default=None, type=int,
|
|
178
|
+
help="Levels to descend (tree|run); default: the full hierarchy")
|
|
179
|
+
p_sub.add_argument("--init", action="store_true",
|
|
180
|
+
help="Initialize the folder if it is not a C3 project yet (link)")
|
|
181
|
+
p_sub.add_argument("--no-detect", action="store_true",
|
|
182
|
+
help="Skip the scan for unlinked nested projects (inspect)")
|
|
176
183
|
p_sub.add_argument("--json", action="store_true", help="Emit JSON output")
|
|
177
184
|
|
|
178
185
|
p_perms = subparsers.add_parser("permissions",
|
|
@@ -407,6 +414,21 @@ def build_parser(version: str, parse_cli_ide_arg):
|
|
|
407
414
|
jr_default.add_argument("project_path", nargs="?", default=".")
|
|
408
415
|
|
|
409
416
|
# ── Credential vault (v2.58.0) ──────────────────────────────────────
|
|
417
|
+
# ── Tokens ──────────────────────────────────────────────────────────
|
|
418
|
+
p_tokens = subparsers.add_parser(
|
|
419
|
+
"tokens",
|
|
420
|
+
help="Token usage — per tool, per day, per session, per file",
|
|
421
|
+
)
|
|
422
|
+
p_tokens.add_argument("--days", type=int, default=30,
|
|
423
|
+
help="Window in days; 0 = all recorded history (default: 30)")
|
|
424
|
+
p_tokens.add_argument("--by", default="tool",
|
|
425
|
+
choices=["tool", "day", "session", "file"],
|
|
426
|
+
help="Which breakdown to print (default: tool)")
|
|
427
|
+
p_tokens.add_argument("--limit", type=int, default=15,
|
|
428
|
+
help="Rows to show (default: 15)")
|
|
429
|
+
p_tokens.add_argument("--json", action="store_true",
|
|
430
|
+
help="Emit the full aggregate as JSON")
|
|
431
|
+
|
|
410
432
|
p_creds = subparsers.add_parser(
|
|
411
433
|
"creds",
|
|
412
434
|
help="Credential vault — named secrets for agents (global + per-project)",
|
|
@@ -452,6 +474,8 @@ def build_parser(version: str, parse_cli_ide_arg):
|
|
|
452
474
|
cr_import.add_argument("env_file", help="Path to the .env file")
|
|
453
475
|
cr_import.add_argument("--global", dest="use_global", action="store_true", help="Import into the global scope")
|
|
454
476
|
cr_import.add_argument("--overwrite", action="store_true", help="Replace entries already registered in the target scope")
|
|
477
|
+
cr_import.add_argument("--dry-run", dest="dry_run", action="store_true", help="Show what would be imported; write nothing")
|
|
478
|
+
cr_import.add_argument("--only", default="", help="Comma-separated names to import (default: all)")
|
|
455
479
|
cr_import.add_argument("--path", dest="project_path", default=".", help="Project directory (default: current)")
|
|
456
480
|
|
|
457
481
|
cr_usage = creds_subs.add_parser(
|
|
@@ -461,6 +485,20 @@ def build_parser(version: str, parse_cli_ide_arg):
|
|
|
461
485
|
cr_usage.add_argument("--json", dest="as_json", action="store_true", help="Emit raw JSON")
|
|
462
486
|
cr_usage.add_argument("--path", dest="project_path", default=".", help="Project directory (default: current)")
|
|
463
487
|
|
|
488
|
+
cr_audit = creds_subs.add_parser(
|
|
489
|
+
"audit", help="Audit trail — every change AND use, on one timeline")
|
|
490
|
+
cr_audit.add_argument("name", nargs="?", default="", help="Limit to one credential (default: all)")
|
|
491
|
+
cr_audit.add_argument("--kind", default="", choices=["", "use", "change"],
|
|
492
|
+
help="Show only uses or only changes (default: both)")
|
|
493
|
+
cr_audit.add_argument("--action", default="",
|
|
494
|
+
help="Exact action: inject_env, template, reveal, cli_show, set, update, delete, import…")
|
|
495
|
+
cr_audit.add_argument("--surface", default="", help="Exact surface: shell, cli, mcp, ui, hub")
|
|
496
|
+
cr_audit.add_argument("--since", default="", help="ISO timestamp lower bound, e.g. 2026-08-01")
|
|
497
|
+
cr_audit.add_argument("-q", dest="q", default="", help="Free-text over name/field/cmd/project")
|
|
498
|
+
cr_audit.add_argument("--limit", type=int, default=40, help="Events to show (default: 40)")
|
|
499
|
+
cr_audit.add_argument("--json", dest="as_json", action="store_true", help="Emit raw JSON")
|
|
500
|
+
cr_audit.add_argument("--path", dest="project_path", default=".", help="Project directory (default: current)")
|
|
501
|
+
|
|
464
502
|
# ── Agent Locks (docs/agent-locks.md) ───────────────────────────────
|
|
465
503
|
# force-release is human-only: it bumps the fencing counter so a holder
|
|
466
504
|
# that comes back is stale by construction. Agents get c3_locks instead,
|