code-context-control 2.85.0__tar.gz → 2.88.2__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.85.0/code_context_control.egg-info → code_context_control-2.88.2}/PKG-INFO +3 -2
- {code_context_control-2.85.0 → code_context_control-2.88.2}/README.md +2 -1
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/c3.py +146 -9
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/commands/parser.py +15 -2
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/guide/credentials.html +80 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hook_access_guard.py +25 -3
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hook_pretool_enforce.py +2 -1
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hub_server.py +47 -2
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hub_ui/components/drill_panel.js +2 -2
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hub_ui/components/hub_credentials.js +227 -23
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/mcp_server.py +21 -7
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/server.py +48 -10
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/tools/credentials.py +105 -4
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/tools/shell.py +108 -8
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/tools/tasks.py +22 -1
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/ui/components/credentials.js +251 -23
- {code_context_control-2.85.0 → code_context_control-2.88.2/code_context_control.egg-info}/PKG-INFO +3 -2
- {code_context_control-2.85.0 → code_context_control-2.88.2}/code_context_control.egg-info/SOURCES.txt +2 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/oracle_server.py +4 -4
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/services/local_session.py +28 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/services/mobile_api.py +43 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/pyproject.toml +1 -1
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/access_guard.py +27 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/claude_md.py +1 -1
- code_context_control-2.88.2/services/cred_telemetry.py +303 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/credential_store.py +399 -23
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/parser.py +24 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/scanner.py +35 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/task_store.py +63 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_access_guard.py +72 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_c3_shell.py +101 -0
- code_context_control-2.88.2/tests/test_cred_telemetry.py +189 -0
- code_context_control-2.88.2/tests/test_credential_store.py +525 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_credentials_routes.py +82 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_credentials_tool.py +96 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_delegate_cascade.py +52 -1
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_hook_access_guard.py +30 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_hub_credentials_routes_write.py +54 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_init_scan.py +76 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_mobile_security_api.py +32 -1
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_oracle_session_bootstrap.py +101 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_pm_api.py +25 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_shell_creds.py +85 -2
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_task_store.py +45 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_task_tool.py +13 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_validate.py +57 -0
- code_context_control-2.85.0/tests/test_credential_store.py +0 -270
- {code_context_control-2.85.0 → code_context_control-2.88.2}/LICENSE +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/__init__.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/_hook_utils.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/commands/__init__.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/commands/common.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/docs.html +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/edits.html +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/guide/access.html +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/guide/bitbucket.html +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/guide/getting-started.html +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/guide/index.html +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/guide/masking.html +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/guide/oracle.html +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/guide/shared.css +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/guide/tools.html +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/guide/workflow.html +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hook_artifact.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hook_auto_snapshot.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hook_c3_signal.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hook_c3read.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hook_dispatch.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hook_edit_ledger.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hook_edit_unlock.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hook_filter.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hook_ghost_files.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hook_prompt_recall.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hook_read.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hook_session_stats.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hook_terse_advisor.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hub_ui/app.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hub_ui/components/add_project.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hub_ui/components/config_editor.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hub_ui/components/drill_artifacts.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hub_ui/components/drill_health.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hub_ui/components/drill_subprojects.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hub_ui/components/drill_tasks.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hub_ui/components/drill_views.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hub_ui/components/global_search.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hub_ui/components/hub_ci.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hub_ui/components/hub_enforcement.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hub_ui/components/hub_locks.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hub_ui/components/mcp_manager.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hub_ui/components/modals.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hub_ui/components/project_card.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hub_ui/components/project_tree.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hub_ui/components/session_drawer.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hub_ui/components/settings_modal.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hub_ui/components/sidebar.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hub_ui/components/summary_bar.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hub_ui/components/task_board.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hub_ui/components/toasts.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hub_ui/components/topbar.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hub_ui/state.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hub_ui.html +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/mcp_proxy.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/progress.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/tools/__init__.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/tools/_grants.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/tools/_helpers.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/tools/agent.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/tools/artifacts.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/tools/bitbucket.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/tools/ci.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/tools/compress.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/tools/delegate.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/tools/edit.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/tools/edit_verify.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/tools/edits.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/tools/federate.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/tools/filter.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/tools/impact.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/tools/jira.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/tools/locks.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/tools/memory.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/tools/override.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/tools/project.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/tools/read.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/tools/search.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/tools/session.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/tools/status.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/tools/validate.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/ui/api.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/ui/app.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/ui/components/access.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/ui/components/bitbucket.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/ui/components/chat.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/ui/components/dashboard.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/ui/components/edits.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/ui/components/enforcement.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/ui/components/instructions.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/ui/components/jira.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/ui/components/memory.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/ui/components/sessions.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/ui/components/settings.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/ui/components/sidebar.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/ui/components/tasks.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/ui/icons.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/ui/pm_shared.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/ui/shared.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/ui/theme.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/ui.html +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/ui_legacy.html +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/cli/ui_nano.html +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/code_context_control.egg-info/dependency_links.txt +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/code_context_control.egg-info/entry_points.txt +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/code_context_control.egg-info/requires.txt +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/code_context_control.egg-info/top_level.txt +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/core/__init__.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/core/config.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/core/ide.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/core/mcp_toml.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/core/web_security.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/__init__.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/config.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/mcp_oracle.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/oracle_ui.html +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/services/__init__.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/services/activity_reporter.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/services/api_auth.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/services/c3_bridge.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/services/chat_engine.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/services/chat_poll.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/services/chat_store.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/services/cross_memory.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/services/discovery_audit.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/services/federated_graph.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/services/health_checker.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/services/insight_engine.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/services/memory_reader.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/services/memory_writer.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/services/project_scanner.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/services/review_agent.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/services/tool_executor.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/services/tool_registry.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/ui/activity.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/ui/agents.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/ui/app.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/ui/busy.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/ui/chat/conversations.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/ui/chat/input.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/ui/chat/markdown.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/ui/chat/send.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/ui/chat/stream_renderer.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/ui/chat/toolbar.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/ui/core.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/ui/crossgraph.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/ui/header.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/ui/insights.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/ui/projects.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/ui/qrcode.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/ui/settings.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/ui/suggestions.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/oracle/ui/theme_tabs.js +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/__init__.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/access_telemetry.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/activity_log.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/agent_base.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/agent_locks.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/agents.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/artifact_defs.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/artifact_store.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/auto_memory.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/bench/__init__.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/bench/external/__init__.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/bench/external/aider_polyglot.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/bench/external/swe_bench.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/benchmark_dashboard.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/bitbucket_client.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/bitbucket_credentials.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/ci_act.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/ci_cache.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/ci_expr.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/ci_failures.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/ci_github.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/ci_impact.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/ci_intel.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/ci_runner.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/ci_workflow.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/circuit_breaker.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/compressor.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/context_snapshot.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/conversation_store.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/doc_index.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/e2e_benchmark.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/e2e_evaluator.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/e2e_tasks.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/edit_ledger.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/embedding_index.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/enforcement_policy.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/error_reporting.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/file_memory.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/git_context.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/hub_service.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/indexer.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/jira_client.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/jira_cloud.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/jira_credentials.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/jira_data_center.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/jira_links.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/mask_activation.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/mask_mirror.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/mask_presets.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/memory.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/memory_consolidator.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/memory_distiller.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/memory_graph.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/memory_grounder.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/memory_queue.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/memory_scorer.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/metrics.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/notifications.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/ollama_bridge.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/ollama_client.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/ollama_credentials.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/output_filter.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/override_grants.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/override_policy.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/override_requests.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/override_wake.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/project_manager.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/project_runtime.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/protocol.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/proxy_state.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/repo_map.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/retention.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/retrieval_broker.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/router.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/runtime.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/session_benchmark.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/session_manager.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/session_preloader.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/subprojects.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/telemetry.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/text_index.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/time_tracker.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/tool_classifier.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/transcript_index.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/validation_cache.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/vector_store.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/watcher.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/services/win_subprocess.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/setup.cfg +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_access_builtin_optout.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_access_guard_meta.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_access_guard_shell_project.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_access_guard_surfaces.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_access_guard_wiring.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_activity_reporter.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_agent_locks.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_aider_polyglot.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_antigravity_transition.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_artifact_store.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_artifact_tool.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_bitbucket_cli_smoke.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_bitbucket_client.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_bitbucket_config_fallback.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_bitbucket_credentials.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_bitbucket_tool.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_c3_bridge_project_artifacts.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_chat_poll.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_ci_act.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_ci_cache.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_ci_expr.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_ci_impact.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_ci_intel.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_ci_runner.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_ci_workflow.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_circuit_breaker.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_claude_md_merge.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_cli_smoke.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_compressor_large_file.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_creds_cli_smoke.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_delegate_version_probe.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_e2e_benchmark.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_edit_ledger_deadline.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_edit_ledger_hook.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_edit_locking.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_edit_normalization.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_edit_verify.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_embedding_index_deadlock.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_enforcement_flip.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_enforcement_policy.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_enforcement_routes.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_federated_graph.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_filter_backoff.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_ghost_files.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_ghost_generation.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_git_branch_awareness.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_hook_codex_compat.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_hook_dispatch.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_hook_pretool_enforce.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_hook_prompt_recall.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_hook_smoke.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_hook_state.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_hook_utf8_stdio.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_hub_credentials_route.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_hub_enforcement_routes.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_hub_inspect_api.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_hub_locks_routes.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_hub_server_smoke.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_hub_subproject_links.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_ide_workflow_adaptation.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_install_mcp_entrypoint.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_jira_cli_smoke.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_jira_client.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_jira_config_fallback.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_jira_credentials.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_jira_links.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_jira_routes.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_jira_tool.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_lazy_store_init.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_mask_guard.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_mask_routes.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_mask_surfaces.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_mcp_host_guard.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_mcp_memory_timeout.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_mcp_server_smoke.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_mcp_toml.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_memory_distiller.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_memory_graph_api.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_memory_queue.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_memory_system.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_mobile_api.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_mobile_extras.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_mobile_override_routes.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_no_stale_model_pins.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_notification_dedup.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_notification_discipline.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_ollama_credentials.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_oracle_api_auth.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_oracle_apikey_api.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_oracle_c3_bridge.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_oracle_chat_engine.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_oracle_chat_store.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_oracle_discovery_api.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_oracle_discovery_audit.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_oracle_local_auth.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_oracle_ollama_bridge.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_oracle_scanner_cache.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_oracle_security_fixes.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_oracle_subproject_awareness.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_oracle_ui_bundle.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_output_filter.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_override_grants.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_override_grants_mcp.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_override_requests.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_override_wake.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_permissions.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_project_manager.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_project_manager_merge.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_project_tool.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_read_coercion.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_read_edit_parity.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_related_facts.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_repo_map.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_response_boilerplate.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_retention.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_review_digest.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_service_durability.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_session_benchmark.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_session_budget.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_shell_robustness.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_subproject_exclusion.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_subproject_federation.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_subprojects.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_swe_bench.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_time_tracker.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_token_telemetry.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_tool_registry.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_upgrade_and_version.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_vault_write_guard.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_version_sync.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_web_security.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tests/test_windows_reliability.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tui/__init__.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tui/backend.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tui/main.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tui/screens/__init__.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tui/screens/benchmark_view.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tui/screens/claudemd_view.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tui/screens/compress_view.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tui/screens/index_view.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tui/screens/init_view.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tui/screens/mcp_view.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tui/screens/optimize_view.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tui/screens/pipe_view.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tui/screens/projects_view.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tui/screens/search_view.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tui/screens/session_view.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tui/screens/stats.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tui/screens/ui_view.py +0 -0
- {code_context_control-2.85.0 → code_context_control-2.88.2}/tui/theme.tcss +0 -0
{code_context_control-2.85.0/code_context_control.egg-info → code_context_control-2.88.2}/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.88.2
|
|
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
|
|
@@ -178,7 +178,7 @@ Twelve tabs. The dashboard above shows token savings, indexed files, the live se
|
|
|
178
178
|
<img src="https://raw.githubusercontent.com/drknowhow/code-context-control/main/docs/screenshots/2026-07/ui_tasks.png" alt="C3 Tasks" width="900">
|
|
179
179
|
</p>
|
|
180
180
|
|
|
181
|
-
**Tasks** (v2.45.0, extended v2.53.0) is a durable per-project tracker — dependencies and subtasks, milestones, decision notes, full event history, health reports, and both automatic and manual time tracking. It rolls up into the Hub's cross-project board.
|
|
181
|
+
**Tasks** (v2.45.0, extended v2.53.0) is a durable per-project tracker — dependencies and subtasks, milestones, decision notes, full event history, health reports, and both automatic and manual time tracking. It rolls up into the Hub's cross-project board. Shipped milestones can be **completed** (v2.86.0) — they leave the board while their tasks keep the milestone link, unlike archiving, which detaches them.
|
|
182
182
|
|
|
183
183
|
**Instructions** keeps your agent-facing docs in sync. C3-generated content sits inside a `<!-- C3:BEGIN … -->` block; anything you write outside it is preserved. Since v2.60.0 generated docs point at `.c3/MAP.md` — a machine-owned, byte-stable repo map C3 refreshes automatically — instead of embedding a tree that goes stale. `AGENTS.md` serves both Codex and Antigravity; `GEMINI.md` is read if present but no longer generated (the Gemini CLI profile was removed in v2.52).
|
|
184
184
|
|
|
@@ -243,6 +243,7 @@ c3 access mask activate # purge pre-mask artifacts, buil
|
|
|
243
243
|
- **`deny` means deny-enumerate too** — denied paths never appear in search results, maps, or the vector index.
|
|
244
244
|
- **Masked means read-only, always.** Cropped rows have no inverse, so an edit in transformed coordinates would corrupt the one file you protected.
|
|
245
245
|
- **Four deterministic presets, no LLM in the read path:** `redact_secrets`, `redact_columns` (salted one-way pseudonyms — joins survive, no reverse dictionary), `sample_rows`, `signatures_only`.
|
|
246
|
+
- **Sensible defaults out of the box** (v2.86.0). A fresh install seeds `*.pem`, `id_rsa*`, and `*.key` as deny rules in global scope — visible in `c3 access list` and removable like any rule you wrote yourself. Delete one and it stays deleted.
|
|
246
247
|
- **Rule changes are human-only** (UI tab or CLI) and ledger-logged. Agents have no mutation surface.
|
|
247
248
|
- **Built-ins can be switched off when you need to** (v2.65.0). `**/.env*`, `**/.c3/**`, `**/.claude/settings*.json` and `**/.git/**` yield to `c3 access builtin disable <glob>`, which makes you retype the glob first. It takes **two keys** — a config entry *and* a keyring attestation — so an agent that manages to write `config.json` still cannot grant itself write access to your settings. The credential vault stays absolute.
|
|
248
249
|
- **Honest coverage.** This guards *cooperative* agents against mistakes and prompt injection. It is not a sandbox — a raw shell outside C3's tools still sees the real bytes.
|
|
@@ -115,7 +115,7 @@ Twelve tabs. The dashboard above shows token savings, indexed files, the live se
|
|
|
115
115
|
<img src="https://raw.githubusercontent.com/drknowhow/code-context-control/main/docs/screenshots/2026-07/ui_tasks.png" alt="C3 Tasks" width="900">
|
|
116
116
|
</p>
|
|
117
117
|
|
|
118
|
-
**Tasks** (v2.45.0, extended v2.53.0) is a durable per-project tracker — dependencies and subtasks, milestones, decision notes, full event history, health reports, and both automatic and manual time tracking. It rolls up into the Hub's cross-project board.
|
|
118
|
+
**Tasks** (v2.45.0, extended v2.53.0) is a durable per-project tracker — dependencies and subtasks, milestones, decision notes, full event history, health reports, and both automatic and manual time tracking. It rolls up into the Hub's cross-project board. Shipped milestones can be **completed** (v2.86.0) — they leave the board while their tasks keep the milestone link, unlike archiving, which detaches them.
|
|
119
119
|
|
|
120
120
|
**Instructions** keeps your agent-facing docs in sync. C3-generated content sits inside a `<!-- C3:BEGIN … -->` block; anything you write outside it is preserved. Since v2.60.0 generated docs point at `.c3/MAP.md` — a machine-owned, byte-stable repo map C3 refreshes automatically — instead of embedding a tree that goes stale. `AGENTS.md` serves both Codex and Antigravity; `GEMINI.md` is read if present but no longer generated (the Gemini CLI profile was removed in v2.52).
|
|
121
121
|
|
|
@@ -180,6 +180,7 @@ c3 access mask activate # purge pre-mask artifacts, buil
|
|
|
180
180
|
- **`deny` means deny-enumerate too** — denied paths never appear in search results, maps, or the vector index.
|
|
181
181
|
- **Masked means read-only, always.** Cropped rows have no inverse, so an edit in transformed coordinates would corrupt the one file you protected.
|
|
182
182
|
- **Four deterministic presets, no LLM in the read path:** `redact_secrets`, `redact_columns` (salted one-way pseudonyms — joins survive, no reverse dictionary), `sample_rows`, `signatures_only`.
|
|
183
|
+
- **Sensible defaults out of the box** (v2.86.0). A fresh install seeds `*.pem`, `id_rsa*`, and `*.key` as deny rules in global scope — visible in `c3 access list` and removable like any rule you wrote yourself. Delete one and it stays deleted.
|
|
183
184
|
- **Rule changes are human-only** (UI tab or CLI) and ledger-logged. Agents have no mutation surface.
|
|
184
185
|
- **Built-ins can be switched off when you need to** (v2.65.0). `**/.env*`, `**/.c3/**`, `**/.claude/settings*.json` and `**/.git/**` yield to `c3 access builtin disable <glob>`, which makes you retype the glob first. It takes **two keys** — a config entry *and* a keyring attestation — so an agent that manages to write `config.json` still cannot grant itself write access to your settings. The credential vault stays absolute.
|
|
185
186
|
- **Honest coverage.** This guards *cooperative* agents against mistakes and prompt injection. It is not a sandbox — a raw shell outside C3's tools still sees the real bytes.
|
|
@@ -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.88.2"
|
|
96
96
|
|
|
97
97
|
|
|
98
98
|
def _compress_file_cli(compressor, path, mode="smart", **kw):
|
|
@@ -5535,6 +5535,14 @@ def cmd_install_mcp(args):
|
|
|
5535
5535
|
except Exception as e:
|
|
5536
5536
|
print(f"Warning: Could not update global CLAUDE.md: {e}")
|
|
5537
5537
|
|
|
5538
|
+
# ── Default Access Guard rules (first run only) ─────────────
|
|
5539
|
+
from services import access_guard
|
|
5540
|
+
seeded = access_guard.seed_default_global_rules()
|
|
5541
|
+
if seeded.get("seeded"):
|
|
5542
|
+
rules = ", ".join(seeded["rules"])
|
|
5543
|
+
print(f"Seeded default Access Guard deny rules into global scope: {rules}")
|
|
5544
|
+
print(" (remove with: c3 access remove <glob> --kind deny --global)")
|
|
5545
|
+
|
|
5538
5546
|
# ── Install /terse skill for supported IDEs ──────────────────
|
|
5539
5547
|
if profile.name in ("claude-code", "codex"):
|
|
5540
5548
|
try:
|
|
@@ -5891,7 +5899,7 @@ def cmd_creds(args):
|
|
|
5891
5899
|
"""Credential vault management (global + per-project scopes)."""
|
|
5892
5900
|
sub = getattr(args, "creds_cmd", None)
|
|
5893
5901
|
if not sub:
|
|
5894
|
-
print("Usage: c3 creds {set,get,list,rm,import} [args]")
|
|
5902
|
+
print("Usage: c3 creds {set,get,list,rm,import,usage} [args]")
|
|
5895
5903
|
return
|
|
5896
5904
|
|
|
5897
5905
|
project_path = getattr(args, "project_path", ".") or "."
|
|
@@ -5906,6 +5914,8 @@ def cmd_creds(args):
|
|
|
5906
5914
|
_creds_cmd_rm(args, project_path)
|
|
5907
5915
|
elif sub == "import":
|
|
5908
5916
|
_creds_cmd_import(args, project_path)
|
|
5917
|
+
elif sub == "usage":
|
|
5918
|
+
_creds_cmd_usage(args, project_path)
|
|
5909
5919
|
else:
|
|
5910
5920
|
print(f"Unknown creds subcommand: {sub}")
|
|
5911
5921
|
|
|
@@ -5920,6 +5930,9 @@ def _creds_entry_line(name: str, entry: dict) -> str:
|
|
|
5920
5930
|
f"{name:<24} {entry.get('scope', '?'):<8} {entry.get('type', 'token'):<10}"
|
|
5921
5931
|
f" len={entry.get('value_len', '?')}",
|
|
5922
5932
|
]
|
|
5933
|
+
display = entry.get("display") or {}
|
|
5934
|
+
if display:
|
|
5935
|
+
parts.append(" ".join(str(v) for v in display.values() if v))
|
|
5923
5936
|
if entry.get("env_var"):
|
|
5924
5937
|
parts.append(f"env_var={entry['env_var']}")
|
|
5925
5938
|
if flags:
|
|
@@ -5929,16 +5942,49 @@ def _creds_entry_line(name: str, entry: dict) -> str:
|
|
|
5929
5942
|
return " ".join(parts)
|
|
5930
5943
|
|
|
5931
5944
|
|
|
5945
|
+
_CREDS_HIDDEN_FIELDS = {"number", "cvc", "ssn"} # prompted via getpass
|
|
5946
|
+
|
|
5947
|
+
|
|
5948
|
+
def _creds_prompt_structured(name: str, ctype: str) -> str:
|
|
5949
|
+
"""Interactive per-field prompt for a structured entry; returns JSON.
|
|
5950
|
+
Sensitive fields use a hidden prompt; empty optional fields are skipped."""
|
|
5951
|
+
import getpass
|
|
5952
|
+
import json as _json
|
|
5953
|
+
|
|
5954
|
+
from services import credential_store as cred_store
|
|
5955
|
+
|
|
5956
|
+
required, optional = cred_store.schema_fields(ctype)
|
|
5957
|
+
print(f"Enter {ctype} fields for '{name}' "
|
|
5958
|
+
"(optional fields: press Enter to skip):")
|
|
5959
|
+
fields: dict = {}
|
|
5960
|
+
for fname in list(required) + list(optional):
|
|
5961
|
+
tag = "" if fname in required else " (optional)"
|
|
5962
|
+
if fname in _CREDS_HIDDEN_FIELDS:
|
|
5963
|
+
raw = getpass.getpass(f" {fname}{tag}: ")
|
|
5964
|
+
else:
|
|
5965
|
+
raw = input(f" {fname}{tag}: ")
|
|
5966
|
+
if raw.strip():
|
|
5967
|
+
fields[fname] = raw.strip()
|
|
5968
|
+
return _json.dumps(fields)
|
|
5969
|
+
|
|
5970
|
+
|
|
5932
5971
|
def _creds_cmd_set(args, project_path: str) -> None:
|
|
5933
5972
|
import getpass
|
|
5934
5973
|
|
|
5935
5974
|
from services import credential_store as cred_store
|
|
5936
5975
|
|
|
5976
|
+
ctype = getattr(args, "ctype", "token") or "token"
|
|
5937
5977
|
value = getattr(args, "value", "") or ""
|
|
5938
5978
|
if getattr(args, "stdin", False):
|
|
5939
5979
|
value = sys.stdin.read().rstrip("\n")
|
|
5940
5980
|
if not value:
|
|
5941
|
-
|
|
5981
|
+
if ctype in cred_store.STRUCTURED_TYPES:
|
|
5982
|
+
value = _creds_prompt_structured(args.name, ctype)
|
|
5983
|
+
if value == "{}":
|
|
5984
|
+
print("Cancelled -- no fields entered.")
|
|
5985
|
+
return
|
|
5986
|
+
else:
|
|
5987
|
+
value = getpass.getpass(f"Value for {args.name}: ")
|
|
5942
5988
|
if not value:
|
|
5943
5989
|
print("Cancelled -- value required.")
|
|
5944
5990
|
return
|
|
@@ -5948,7 +5994,7 @@ def _creds_cmd_set(args, project_path: str) -> None:
|
|
|
5948
5994
|
args.name, value,
|
|
5949
5995
|
scope=scope, project_path=project_path,
|
|
5950
5996
|
description=getattr(args, "desc", "") or "",
|
|
5951
|
-
ctype=
|
|
5997
|
+
ctype=ctype,
|
|
5952
5998
|
env_var=getattr(args, "env_var", "") or "",
|
|
5953
5999
|
agent_readable=bool(getattr(args, "agent_readable", False)),
|
|
5954
6000
|
inject=bool(getattr(args, "inject", False)),
|
|
@@ -5963,6 +6009,19 @@ def _creds_cmd_set(args, project_path: str) -> None:
|
|
|
5963
6009
|
"into its context and transcripts.")
|
|
5964
6010
|
|
|
5965
6011
|
|
|
6012
|
+
def _creds_count_show(refs, project_path: str) -> None:
|
|
6013
|
+
"""Count a terminal --show like any other use: state counter + history."""
|
|
6014
|
+
from services import credential_store as cred_store
|
|
6015
|
+
try:
|
|
6016
|
+
cred_store.touch_last_used(
|
|
6017
|
+
sorted({str(r).partition(".")[0] for r in refs}), project_path)
|
|
6018
|
+
from services import cred_telemetry as ct
|
|
6019
|
+
ct.record_use(refs, project_path=project_path,
|
|
6020
|
+
action=ct.ACTION_CLI_SHOW, surface="cli")
|
|
6021
|
+
except Exception:
|
|
6022
|
+
pass
|
|
6023
|
+
|
|
6024
|
+
|
|
5966
6025
|
def _creds_cmd_get(args, project_path: str) -> None:
|
|
5967
6026
|
from services import credential_store as cred_store
|
|
5968
6027
|
|
|
@@ -5973,11 +6032,46 @@ def _creds_cmd_get(args, project_path: str) -> None:
|
|
|
5973
6032
|
print(_creds_entry_line(args.name, entry))
|
|
5974
6033
|
print(f"storage={entry.get('storage', 'keyring')} "
|
|
5975
6034
|
f"created={entry.get('created', '?')} updated={entry.get('updated', '?')}")
|
|
5976
|
-
|
|
5977
|
-
|
|
5978
|
-
if
|
|
5979
|
-
|
|
5980
|
-
print(
|
|
6035
|
+
stype = cred_store.structured_type(args.name, project_path=project_path)
|
|
6036
|
+
field = (getattr(args, "field", "") or "").strip()
|
|
6037
|
+
if not stype:
|
|
6038
|
+
fp = cred_store.fingerprint(args.name, project_path=project_path)
|
|
6039
|
+
print(f"fingerprint={fp or 'unresolvable'}")
|
|
6040
|
+
if field:
|
|
6041
|
+
print(f"[error] '{args.name}' is not structured -- --field does not apply")
|
|
6042
|
+
return
|
|
6043
|
+
if getattr(args, "show", False):
|
|
6044
|
+
value = cred_store.get_value(args.name, project_path=project_path)
|
|
6045
|
+
print(value if value is not None
|
|
6046
|
+
else "[error] value missing from store")
|
|
6047
|
+
if value is not None:
|
|
6048
|
+
_creds_count_show([args.name], project_path)
|
|
6049
|
+
return
|
|
6050
|
+
print(f"fields: {', '.join(entry.get('fields') or []) or 'none recorded'}")
|
|
6051
|
+
if not getattr(args, "show", False):
|
|
6052
|
+
if field:
|
|
6053
|
+
print("[hint] add --show to print the field value")
|
|
6054
|
+
return
|
|
6055
|
+
# --show: the deliberate human read-back path (terminal only; the wire
|
|
6056
|
+
# never carries these values). Counted as usage like any other reveal.
|
|
6057
|
+
if field:
|
|
6058
|
+
value = cred_store.get_value(args.name, project_path=project_path,
|
|
6059
|
+
field=field)
|
|
6060
|
+
if value is None:
|
|
6061
|
+
print(f"[error] no field '{field}' on '{args.name}'")
|
|
6062
|
+
return
|
|
6063
|
+
print(value)
|
|
6064
|
+
_creds_count_show([f"{args.name}.{field}"], project_path)
|
|
6065
|
+
else:
|
|
6066
|
+
fields = cred_store.get_structured_fields(
|
|
6067
|
+
args.name, project_path=project_path)
|
|
6068
|
+
if fields is None:
|
|
6069
|
+
print("[error] value missing from store")
|
|
6070
|
+
return
|
|
6071
|
+
width = max(len(k) for k in fields)
|
|
6072
|
+
for key in sorted(fields):
|
|
6073
|
+
print(f"{key:<{width}} {fields[key]}")
|
|
6074
|
+
_creds_count_show([args.name], project_path)
|
|
5981
6075
|
|
|
5982
6076
|
|
|
5983
6077
|
def _creds_cmd_list(args, project_path: str) -> None:
|
|
@@ -6031,6 +6125,39 @@ def _creds_cmd_import(args, project_path: str) -> None:
|
|
|
6031
6125
|
"(use --overwrite to replace)")
|
|
6032
6126
|
|
|
6033
6127
|
|
|
6128
|
+
def _creds_cmd_usage(args, project_path: str) -> None:
|
|
6129
|
+
import json as _json
|
|
6130
|
+
|
|
6131
|
+
from services import cred_telemetry as ct
|
|
6132
|
+
|
|
6133
|
+
name = getattr(args, "name", "") or ""
|
|
6134
|
+
limit = max(1, int(getattr(args, "limit", 20) or 20))
|
|
6135
|
+
agg = ct.aggregate(project_path, name=name)
|
|
6136
|
+
recent = ct.search_events(project_path, name=name, limit=limit)
|
|
6137
|
+
if getattr(args, "as_json", False):
|
|
6138
|
+
print(_json.dumps({"aggregate": agg, "recent": recent}, indent=2))
|
|
6139
|
+
return
|
|
6140
|
+
if not agg["total"]:
|
|
6141
|
+
target = f" for '{name}'" if name else ""
|
|
6142
|
+
print(f"No recorded credential uses{target} yet.")
|
|
6143
|
+
return
|
|
6144
|
+
surf = " ".join(f"{s}:{c}" for s, c in sorted(agg["by_surface"].items()))
|
|
6145
|
+
print(f"{agg['total']} use(s) across {len(agg['rows'])} credential(s)"
|
|
6146
|
+
f" [{surf}]")
|
|
6147
|
+
for row in agg["rows"]:
|
|
6148
|
+
fields = f" fields: {', '.join(row['fields'])}" if row["fields"] else ""
|
|
6149
|
+
print(f" {row['name']:<24} {row['hits']:>4}x last {row['last_ts'] or '?'}"
|
|
6150
|
+
f" projects={row['projects']}{fields}")
|
|
6151
|
+
print(f"recent (newest first, {len(recent['events'])}"
|
|
6152
|
+
f"/{recent['matched']}):")
|
|
6153
|
+
for e in recent["events"]:
|
|
6154
|
+
ref = e["name"] + (f".{e['field']}" if e.get("field") else "")
|
|
6155
|
+
exit_part = f" exit={e['exit']}" if "exit" in e else ""
|
|
6156
|
+
cmd_part = f" {e['cmd']}" if e.get("cmd") else ""
|
|
6157
|
+
print(f" {e.get('ts', '?')} {e.get('action', '?'):<10} {ref:<28}"
|
|
6158
|
+
f" [{e.get('surface', '?')}]{exit_part}{cmd_part}")
|
|
6159
|
+
|
|
6160
|
+
|
|
6034
6161
|
def cmd_ci(args):
|
|
6035
6162
|
"""AgentCI entry point — exits with the finding.
|
|
6036
6163
|
|
|
@@ -6603,6 +6730,16 @@ def _override_audit(grant: dict, project_path: str) -> None:
|
|
|
6603
6730
|
|
|
6604
6731
|
def cmd_access(args):
|
|
6605
6732
|
"""Access Guard rule management — human-only mutation surface (spec §1)."""
|
|
6733
|
+
from services import access_guard
|
|
6734
|
+
|
|
6735
|
+
# First `c3 access` touch seeds the removable defaults (spec §1). A
|
|
6736
|
+
# no-op forever after: any existing access section, even an emptied
|
|
6737
|
+
# one, means the user has taken over the scope.
|
|
6738
|
+
seeded = access_guard.seed_default_global_rules()
|
|
6739
|
+
if seeded.get("seeded"):
|
|
6740
|
+
print(f"[seeded] default global deny rules: {', '.join(seeded['rules'])}")
|
|
6741
|
+
print(" Remove any of them: c3 access remove <glob> --kind deny --global\n")
|
|
6742
|
+
|
|
6606
6743
|
sub = getattr(args, "access_cmd", None)
|
|
6607
6744
|
if not sub:
|
|
6608
6745
|
print("Usage: c3 access {list,add,remove,check,stats,mask,builtin} [args]")
|
|
@@ -417,9 +417,14 @@ def build_parser(version: str, parse_cli_ide_arg):
|
|
|
417
417
|
"set", help="Create or update a credential (value via hidden prompt)"
|
|
418
418
|
)
|
|
419
419
|
cr_set.add_argument("name", help="Entry name (env-var safe: [A-Za-z_][A-Za-z0-9_]*)")
|
|
420
|
-
cr_set.add_argument("--value", default="", help="Secret value (prompted via getpass if omitted — preferred)")
|
|
420
|
+
cr_set.add_argument("--value", default="", help="Secret value (prompted via getpass if omitted — preferred). Structured types take a JSON object of fields")
|
|
421
421
|
cr_set.add_argument("--stdin", action="store_true", help="Read the value from stdin (piped/multiline values)")
|
|
422
|
-
cr_set.add_argument("--type", dest="ctype",
|
|
422
|
+
cr_set.add_argument("--type", dest="ctype",
|
|
423
|
+
choices=["token", "env", "multiline",
|
|
424
|
+
"address", "identity", "card"],
|
|
425
|
+
default="token",
|
|
426
|
+
help="Entry type; address/identity/card are structured "
|
|
427
|
+
"(field payload, inject-only, never revealable to the agent)")
|
|
423
428
|
cr_set.add_argument("--desc", default="", help="Human description shown in list/UI")
|
|
424
429
|
cr_set.add_argument("--env-var", default="", help="Env var name used at injection (default: entry name)")
|
|
425
430
|
cr_set.add_argument("--agent-readable", action="store_true", help="Allow the agent to reveal the decoded value into its context (default: injection-only)")
|
|
@@ -432,6 +437,7 @@ def build_parser(version: str, parse_cli_ide_arg):
|
|
|
432
437
|
cr_get = creds_subs.add_parser("get", help="Show entry metadata (masked; --show prints the value)")
|
|
433
438
|
cr_get.add_argument("name")
|
|
434
439
|
cr_get.add_argument("--show", action="store_true", help="Print the decoded value to the terminal")
|
|
440
|
+
cr_get.add_argument("--field", default="", help="For structured entries: limit --show to one field (e.g. number)")
|
|
435
441
|
cr_get.add_argument("--path", dest="project_path", default=".", help="Project directory (default: current)")
|
|
436
442
|
|
|
437
443
|
cr_list = creds_subs.add_parser("list", help="List credentials visible to this project")
|
|
@@ -448,6 +454,13 @@ def build_parser(version: str, parse_cli_ide_arg):
|
|
|
448
454
|
cr_import.add_argument("--overwrite", action="store_true", help="Replace entries already registered in the target scope")
|
|
449
455
|
cr_import.add_argument("--path", dest="project_path", default=".", help="Project directory (default: current)")
|
|
450
456
|
|
|
457
|
+
cr_usage = creds_subs.add_parser(
|
|
458
|
+
"usage", help="Usage history — when, where, and how often credentials were used")
|
|
459
|
+
cr_usage.add_argument("name", nargs="?", default="", help="Limit to one credential (default: all)")
|
|
460
|
+
cr_usage.add_argument("--limit", type=int, default=20, help="Recent events to show (default: 20)")
|
|
461
|
+
cr_usage.add_argument("--json", dest="as_json", action="store_true", help="Emit raw JSON")
|
|
462
|
+
cr_usage.add_argument("--path", dest="project_path", default=".", help="Project directory (default: current)")
|
|
463
|
+
|
|
451
464
|
# ── Agent Locks (docs/agent-locks.md) ───────────────────────────────
|
|
452
465
|
# force-release is human-only: it bumps the fencing counter so a holder
|
|
453
466
|
# that comes back is stale by construction. Agents get c3_locks instead,
|
|
@@ -105,11 +105,13 @@
|
|
|
105
105
|
<a href="#storage" class="sidebar-link"><span class="icon">🗄️</span> Where values live</a>
|
|
106
106
|
<a href="#scopes" class="sidebar-link"><span class="icon">🌍</span> Scopes & overriding</a>
|
|
107
107
|
<a href="#agent-use" class="sidebar-link"><span class="icon">🤖</span> How agents use them</a>
|
|
108
|
+
<a href="#structured" class="sidebar-link"><span class="icon">💳</span> Structured kinds</a>
|
|
108
109
|
<a href="#exposure" class="sidebar-link"><span class="icon">⚠️</span> Exposure flags</a>
|
|
109
110
|
<a href="#hub-ui" class="sidebar-link"><span class="icon">🖥️</span> Hub UI</a>
|
|
110
111
|
<a href="#search" class="sidebar-link"><span class="icon">🔎</span> Search & qualifiers</a>
|
|
111
112
|
<a href="#cli" class="sidebar-link"><span class="icon">💻</span> CLI commands</a>
|
|
112
113
|
<a href="#actions" class="sidebar-link"><span class="icon">⚙️</span> Tool actions</a>
|
|
114
|
+
<a href="#usage" class="sidebar-link"><span class="icon">📊</span> Usage history</a>
|
|
113
115
|
<a href="#audit" class="sidebar-link"><span class="icon">📝</span> Audit trail</a>
|
|
114
116
|
<a href="#troubleshooting" class="sidebar-link"><span class="icon">🛠️</span> Troubleshooting</a>
|
|
115
117
|
</div>
|
|
@@ -293,6 +295,48 @@ c3_shell(cmd=<span class="str">'terraform apply'</span>, env_creds=<span class="
|
|
|
293
295
|
|
|
294
296
|
<hr class="divider">
|
|
295
297
|
|
|
298
|
+
<!-- ═══════════════════════════════════ STRUCTURED ═══ -->
|
|
299
|
+
<section id="structured" class="tool-section">
|
|
300
|
+
<h2>Structured kinds — cards, addresses, identity (v2.87.0)</h2>
|
|
301
|
+
|
|
302
|
+
<p>Three entry types hold <strong>named fields</strong> instead of one opaque value:
|
|
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) and
|
|
305
|
+
<code>identity</code> (full_name, optional dob/ssn/phone/email). The payload is stored as one
|
|
306
|
+
canonical JSON object through the same keyring / encrypted-sidecar path as any other value.</p>
|
|
307
|
+
|
|
308
|
+
<p>They are <strong>inject-only by construction</strong>, which is stricter than a normal secret:</p>
|
|
309
|
+
<ul>
|
|
310
|
+
<li><strong>Reveal is permanently disabled</strong> — <code>agent_readable</code> and
|
|
311
|
+
<code>inject</code> are refused at every surface, for every caller, forever. There is no flag to flip.</li>
|
|
312
|
+
<li><strong>Only single fields cross the boundary.</strong> The agent addresses a field —
|
|
313
|
+
<code>env_creds='CARD.number'</code> (exported as <code>$CARD_NUMBER</code>) or
|
|
314
|
+
<code>{{cred:CARD.number}}</code> inline — and a bare <code>{{cred:CARD}}</code> fails with
|
|
315
|
+
the field list rather than expanding the whole payload.</li>
|
|
316
|
+
<li><strong>The registry shows a projection, not the data.</strong> Lists and the UI display
|
|
317
|
+
<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. Field <em>names</em> are public;
|
|
319
|
+
field <em>values</em> never transit any HTTP response — a sweep test enforces this.</li>
|
|
320
|
+
<li><strong>Echoes redact per field</strong> to <code>[cred:NAME.field]</code>. Caveat: the
|
|
321
|
+
redactor only tracks values of 4+ characters, so a 3-digit CVC or 2-letter state that a
|
|
322
|
+
child process echoes cannot be scrubbed after the fact. The real guarantee remains
|
|
323
|
+
decode-at-the-subprocess-boundary; redaction is the belt over it.</li>
|
|
324
|
+
<li><strong>The type boundary is immutable.</strong> A card cannot be rewritten into a
|
|
325
|
+
plain token (or vice versa) by <code>set</code>, metadata update, or <code>.env</code>
|
|
326
|
+
import — delete and re-create is the only path across, and a keyring attestation keeps an
|
|
327
|
+
entry structured even if <code>.c3/config.json</code> is edited by hand.</li>
|
|
328
|
+
</ul>
|
|
329
|
+
|
|
330
|
+
<p>Updating one field never requires retyping the rest: a partial payload
|
|
331
|
+
<strong>merges</strong> (<code>{"expiry": "01/30"}</code> updates the expiry, JSON
|
|
332
|
+
<code>null</code> deletes an optional field). Read-back for <em>you</em> is terminal-only:
|
|
333
|
+
<code>c3 creds get NAME --show</code> (all fields) or <code>--show --field number</code> —
|
|
334
|
+
the browser and the mobile gateway never carry the values, and mobile cannot create
|
|
335
|
+
structured entries at all.</p>
|
|
336
|
+
</section>
|
|
337
|
+
|
|
338
|
+
<hr class="divider">
|
|
339
|
+
|
|
296
340
|
<!-- ═══════════════════════════════════════ EXPOSURE ═══ -->
|
|
297
341
|
<section id="exposure" class="tool-section">
|
|
298
342
|
<h2>Exposure flags</h2>
|
|
@@ -478,6 +522,42 @@ c3_shell(cmd=<span class="str">'terraform apply'</span>, env_creds=<span class="
|
|
|
478
522
|
<hr class="divider">
|
|
479
523
|
|
|
480
524
|
<!-- ═══════════════════════════════════════ AUDIT ═══ -->
|
|
525
|
+
<section id="usage" class="tool-section">
|
|
526
|
+
<h2>Usage history (v2.88.0)</h2>
|
|
527
|
+
|
|
528
|
+
<p>Every time a value leaves the vault — an <code>env_creds</code> injection, a
|
|
529
|
+
<code>{{cred:NAME}}</code> expansion, a gated reveal, a terminal
|
|
530
|
+
<code>c3 creds get --show</code> — one event is appended to the owning scope's
|
|
531
|
+
<code>.c3/cred_usage.jsonl</code>: timestamp, name (and field for structured entries),
|
|
532
|
+
action, surface, project, exit code, and the command in its <strong>raw template
|
|
533
|
+
form</strong>, capped at 120 characters. Never the expanded string, never a value.
|
|
534
|
+
A global credential's usage from every project lands in <code>~/.c3</code>, so its
|
|
535
|
+
history is complete in one place.</p>
|
|
536
|
+
|
|
537
|
+
<p>Reading it back:</p>
|
|
538
|
+
<ul>
|
|
539
|
+
<li><strong>UI</strong> — the Credentials tab's <em>usage</em> sub-view (totals,
|
|
540
|
+
per-credential counts by surface, expandable recent events) and the hub drawer's
|
|
541
|
+
“Usage & relationships” section.</li>
|
|
542
|
+
<li><strong>CLI</strong> — <code>c3 creds usage [NAME] [--limit N] [--json]</code>.</li>
|
|
543
|
+
<li><strong>Agent</strong> — <code>c3_credentials(action='usage')</code>. Scoped on
|
|
544
|
+
purpose: the agent sees full events (including command previews) only for the
|
|
545
|
+
<em>current</em> project; other projects' use of a shared global credential is
|
|
546
|
+
reduced to counts, so one project's agent cannot read another's command lines
|
|
547
|
+
through the vault. Your surfaces (UI/CLI) show everything.</li>
|
|
548
|
+
<li><strong>REST</strong> — <code>GET /api/credentials/usage</code> and
|
|
549
|
+
<code>GET /api/credentials/<name>/usage</code> (hub:
|
|
550
|
+
<code>/api/projects/credentials/usage</code>).</li>
|
|
551
|
+
</ul>
|
|
552
|
+
|
|
553
|
+
<p>The log rotates at 512KB (one <code>.1</code> generation retained), both filenames
|
|
554
|
+
are vault-write-protected and gitignored, and the lightweight
|
|
555
|
+
<code>last_used</code>/<code>use_count</code> counters you already see on list rows
|
|
556
|
+
keep working exactly as before — they are the summary; this is the history.</p>
|
|
557
|
+
</section>
|
|
558
|
+
|
|
559
|
+
<hr class="divider">
|
|
560
|
+
|
|
481
561
|
<section id="audit" class="tool-section">
|
|
482
562
|
<h2>Audit trail</h2>
|
|
483
563
|
|
|
@@ -41,7 +41,24 @@ _MAX_TOKENS = 200
|
|
|
41
41
|
# "NTFS alternate data stream". The ADS check stays strict for real path
|
|
42
42
|
# arguments (_WRITE_TOOLS/_READ_TOOLS); here it only produced false denies on
|
|
43
43
|
# commit messages, curl, and gh (#50).
|
|
44
|
-
|
|
44
|
+
#
|
|
45
|
+
# UNANCHORED, and that is the fix rather than an oversight. `^…://` only ever
|
|
46
|
+
# recognised a token that BEGINS with a scheme, which is the same
|
|
47
|
+
# whitelist-a-shape mistake #50 made and this module's own header calls out —
|
|
48
|
+
# and the `_SYNTAX_CHARS` generalisation does not cover the gap, because a
|
|
49
|
+
# token can carry a URL and no syntax at all. Observed 2026-08-11: the single
|
|
50
|
+
# argument of
|
|
51
|
+
# printf '\n---\n\nhttps://claude.ai/code/session_01Hs28…\n' >> body.md
|
|
52
|
+
# strips to `\n---\n\nhttps://claude.ai/…`, which has a separator (`\` and
|
|
53
|
+
# `/`), no syntax characters, no `::`, and no leading scheme. It reached
|
|
54
|
+
# ag.check, canonicalised to a residual colon, and hard-denied a command whose
|
|
55
|
+
# only file argument was an ordinary markdown path. Third logged instance of
|
|
56
|
+
# this class in five days (two on 2026-08-07 were Windows paths inside Python
|
|
57
|
+
# string literals).
|
|
58
|
+
#
|
|
59
|
+
# A token containing `://` anywhere is a network literal, not an NTFS stream:
|
|
60
|
+
# a real stream is `file:name:$TYPE`, and no spelling of it contains `//`.
|
|
61
|
+
_SCHEME_RE = re.compile(r"[a-z][a-z0-9+.\-]*://", re.IGNORECASE)
|
|
45
62
|
# IPv6 literal or CIDR: >=2 colons, hex groups only, optional [] and /prefix.
|
|
46
63
|
# 'C:/x/f.txt:stream' has one colon and non-hex parts, so it never matches.
|
|
47
64
|
_IPV6_RE = re.compile(
|
|
@@ -104,8 +121,13 @@ _CD_RE = re.compile(
|
|
|
104
121
|
|
|
105
122
|
|
|
106
123
|
def _is_network_token(tok: str) -> bool:
|
|
107
|
-
"""True for URLs and IPv6 literals/CIDRs — never for an ADS spelling.
|
|
108
|
-
|
|
124
|
+
"""True for URLs and IPv6 literals/CIDRs — never for an ADS spelling.
|
|
125
|
+
|
|
126
|
+
``search`` for the scheme (a URL anywhere in the token disqualifies it as
|
|
127
|
+
a path), ``match`` for IPv6 — that pattern is a whole-token shape and
|
|
128
|
+
anchoring is what keeps `C:/x/f.txt:stream` from matching it.
|
|
129
|
+
"""
|
|
130
|
+
return bool(_SCHEME_RE.search(tok) or _IPV6_RE.match(tok))
|
|
109
131
|
|
|
110
132
|
|
|
111
133
|
def _is_scope_token(tok: str) -> bool:
|
|
@@ -113,7 +113,8 @@ _WRITE_CLASS_ALWAYS = frozenset({"Edit", "Write", "MultiEdit"})
|
|
|
113
113
|
# Vault files no native write may touch, regardless of unlock state.
|
|
114
114
|
# Mirrors services.credential_store.VAULT_PROTECTED_FILES (parity-tested);
|
|
115
115
|
# duplicated because hooks must stay import-light.
|
|
116
|
-
_VAULT_FILES = frozenset({"config.json", "secrets.enc", "cred_state.json"
|
|
116
|
+
_VAULT_FILES = frozenset({"config.json", "secrets.enc", "cred_state.json",
|
|
117
|
+
"cred_usage.jsonl", "cred_usage.jsonl.1"})
|
|
117
118
|
|
|
118
119
|
# Redirect messages per native tool
|
|
119
120
|
_REDIRECTS = {
|
|
@@ -2026,7 +2026,9 @@ def api_projects_credentials_set():
|
|
|
2026
2026
|
str(data.get("path") or "").strip(), scope, mutation=True)
|
|
2027
2027
|
if err:
|
|
2028
2028
|
return err
|
|
2029
|
-
value =
|
|
2029
|
+
value = data.get("value")
|
|
2030
|
+
# Structured kinds submit a field OBJECT; the store takes JSON text.
|
|
2031
|
+
value = json.dumps(value) if isinstance(value, dict) else str(value or "")
|
|
2030
2032
|
ctype = str(data.get("type") or data.get("ctype") or "token")
|
|
2031
2033
|
try:
|
|
2032
2034
|
if value:
|
|
@@ -2123,11 +2125,40 @@ def api_projects_credentials_check(name):
|
|
|
2123
2125
|
"name": name,
|
|
2124
2126
|
"scope": entry["scope"],
|
|
2125
2127
|
"storage": entry.get("storage", "keyring"),
|
|
2126
|
-
|
|
2128
|
+
# is_resolvable, not get_value: a structured entry never resolves
|
|
2129
|
+
# whole, but its payload being decodable is what "check" asks.
|
|
2130
|
+
"resolvable": cred_store.is_resolvable(name, project_path=store_path),
|
|
2127
2131
|
"fingerprint": cred_store.fingerprint(name, project_path=store_path),
|
|
2128
2132
|
})
|
|
2129
2133
|
|
|
2130
2134
|
|
|
2135
|
+
@app.route("/api/projects/credentials/usage", methods=["GET"])
|
|
2136
|
+
def api_projects_credentials_usage():
|
|
2137
|
+
"""Usage history — `path` scopes to a project (merged view); omit it for
|
|
2138
|
+
the global vault only. `name` filters to one credential. Names, counts
|
|
2139
|
+
and cmd previews only; never values."""
|
|
2140
|
+
from services import cred_telemetry as ct
|
|
2141
|
+
from services import credential_store as cred_store
|
|
2142
|
+
path = (request.args.get("path") or "").strip()
|
|
2143
|
+
if path:
|
|
2144
|
+
try:
|
|
2145
|
+
base = str(_resolve_project_path(path))
|
|
2146
|
+
except ValueError as e:
|
|
2147
|
+
return jsonify({"error": str(e)}), 404
|
|
2148
|
+
else:
|
|
2149
|
+
home = cred_store.global_base()
|
|
2150
|
+
if home is None:
|
|
2151
|
+
return jsonify({"error": "global scope unresolvable"}), 500
|
|
2152
|
+
base = str(home)
|
|
2153
|
+
name = (request.args.get("name") or "").strip()
|
|
2154
|
+
return jsonify({
|
|
2155
|
+
"path": base if path else "",
|
|
2156
|
+
"aggregate": ct.aggregate(base, name=name),
|
|
2157
|
+
"recent": ct.search_events(base, name=name,
|
|
2158
|
+
limit=request.args.get("limit", 100)),
|
|
2159
|
+
})
|
|
2160
|
+
|
|
2161
|
+
|
|
2131
2162
|
@app.route("/api/hub/credentials/overview", methods=["GET"])
|
|
2132
2163
|
def api_hub_credentials_overview():
|
|
2133
2164
|
"""Cross-project credential inventory: the global vault plus each
|
|
@@ -2740,6 +2771,20 @@ def api_pm_milestone():
|
|
|
2740
2771
|
return jsonify({"error": "id is required"}), 400
|
|
2741
2772
|
|
|
2742
2773
|
if request.method == "PUT":
|
|
2774
|
+
# {complete: true} / {reopen: true} switch lifecycle; tasks keep
|
|
2775
|
+
# their milestone link (unlike DELETE = archive + detach).
|
|
2776
|
+
if data.get("complete"):
|
|
2777
|
+
res = store.complete_milestone(ms_id)
|
|
2778
|
+
if "error" in res:
|
|
2779
|
+
return jsonify(res), 400
|
|
2780
|
+
_pm_audit(resolved, "milestone", "complete", res["id"])
|
|
2781
|
+
return jsonify({"completed": True, "milestone": res})
|
|
2782
|
+
if data.get("reopen"):
|
|
2783
|
+
res = store.reopen_milestone(ms_id)
|
|
2784
|
+
if "error" in res:
|
|
2785
|
+
return jsonify(res), 400
|
|
2786
|
+
_pm_audit(resolved, "milestone", "reopen", res["id"])
|
|
2787
|
+
return jsonify({"reopened": True, "milestone": res})
|
|
2743
2788
|
res = store.update_milestone(ms_id, expected_rev=data.get("expected_rev"),
|
|
2744
2789
|
**(data.get("fields") or {}))
|
|
2745
2790
|
if "error" in res:
|
{code_context_control-2.85.0 → code_context_control-2.88.2}/cli/hub_ui/components/drill_panel.js
RENAMED
|
@@ -182,8 +182,8 @@ function DrillPanel({ project, tab, setTab, onClose, onChanged, onOpenModal, pro
|
|
|
182
182
|
</button>
|
|
183
183
|
</div>
|
|
184
184
|
<div style={{
|
|
185
|
-
display: 'flex', gap: 2, padding: '4px 20px 0',
|
|
186
|
-
borderBottom: `1px solid ${T.border}`,
|
|
185
|
+
display: 'flex', flexWrap: 'wrap', gap: 2, padding: '4px 20px 0',
|
|
186
|
+
borderBottom: `1px solid ${T.border}`, flexShrink: 0,
|
|
187
187
|
}}>
|
|
188
188
|
{tabs.map(([id, label]) => (
|
|
189
189
|
<button key={id} onClick={() => setTab(id)} style={{
|