tweek 0.4.2__tar.gz → 0.4.3__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.
- {tweek-0.4.2/tweek.egg-info → tweek-0.4.3}/PKG-INFO +1 -1
- {tweek-0.4.2 → tweek-0.4.3}/pyproject.toml +1 -1
- {tweek-0.4.2 → tweek-0.4.3}/tweek/__init__.py +1 -1
- {tweek-0.4.2 → tweek-0.4.3}/tweek/cli_install.py +92 -28
- {tweek-0.4.2 → tweek-0.4.3/tweek.egg-info}/PKG-INFO +1 -1
- {tweek-0.4.2 → tweek-0.4.3}/LICENSE +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/NOTICE +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/README.md +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/setup.cfg +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_approval_queue.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_audit.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_break_glass.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_cli.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_cli_configure.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_cli_helpers.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_config_manager.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_config_models.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_config_templates.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_credential_scanner.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_diagnostics.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_enforcement.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_feedback.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_heuristic_chaining.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_heuristic_scorer.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_install_flow.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_install_resilience.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_installer_improvements.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_language_detection.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_licensing.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_llm_local.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_llm_reviewer.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_llm_reviewer_lazy.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_local_model.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_local_model_escalation.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_log_bundle.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_logging.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_logging_enhanced.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_mcp_clients.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_mcp_proxy.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_memory_scoped.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_model_integrity.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_openclaw_integration.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_overrides.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_path_boundary.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_pattern_families.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_pattern_matcher_redos.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_patterns.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_plugin_scoping.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_post_tool_use.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_prompt_injection_patterns.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_property_based.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_protect_command.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_provenance.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_provenance_integration.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_proxy_detection.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_rate_limiter.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_redaction.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_screening_context.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_session_analyzer.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_skill_context.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_tiered_help.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tests/test_vault_cross_platform.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/_keygen.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/audit.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/cli.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/cli_config.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/cli_configure.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/cli_core.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/cli_dry_run.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/cli_helpers.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/cli_logs.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/cli_mcp.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/cli_memory.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/cli_model.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/cli_plugins.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/cli_protect.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/cli_proxy.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/cli_security.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/cli_skills.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/cli_uninstall.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/cli_vault.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/config/__init__.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/config/allowed_dirs.yaml +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/config/families.yaml +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/config/manager.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/config/models.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/config/patterns.yaml +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/config/templates/config.yaml.template +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/config/templates/env.template +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/config/templates/overrides.yaml.template +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/config/templates/tweek.yaml.template +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/config/templates.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/config/tiers.yaml +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/diagnostics.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/hooks/__init__.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/hooks/break_glass.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/hooks/feedback.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/hooks/overrides.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/hooks/post_tool_use.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/hooks/pre_tool_use.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/hooks/wrapper_post_tool_use.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/hooks/wrapper_pre_tool_use.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/integrations/__init__.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/integrations/openclaw.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/integrations/openclaw_detection.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/integrations/openclaw_server.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/licensing.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/logging/__init__.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/logging/bundle.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/logging/json_logger.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/logging/security_log.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/mcp/__init__.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/mcp/approval.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/mcp/approval_cli.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/mcp/clients/__init__.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/mcp/clients/chatgpt.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/mcp/clients/claude_desktop.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/mcp/clients/gemini.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/mcp/proxy.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/mcp/screening.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/memory/__init__.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/memory/provenance.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/memory/queries.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/memory/safety.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/memory/schemas.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/memory/store.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/platform/__init__.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/plugins/__init__.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/plugins/base.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/plugins/compliance/__init__.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/plugins/compliance/gdpr.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/plugins/compliance/gov.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/plugins/compliance/hipaa.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/plugins/compliance/legal.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/plugins/compliance/pci.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/plugins/compliance/soc2.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/plugins/detectors/__init__.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/plugins/detectors/continue_dev.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/plugins/detectors/copilot.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/plugins/detectors/cursor.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/plugins/detectors/openclaw.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/plugins/detectors/windsurf.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/plugins/git_discovery.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/plugins/git_installer.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/plugins/git_lockfile.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/plugins/git_registry.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/plugins/git_security.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/plugins/providers/__init__.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/plugins/providers/anthropic.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/plugins/providers/azure_openai.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/plugins/providers/bedrock.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/plugins/providers/google.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/plugins/providers/openai.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/plugins/scope.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/plugins/screening/__init__.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/plugins/screening/heuristic_scorer.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/plugins/screening/llm_reviewer.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/plugins/screening/local_model_reviewer.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/plugins/screening/pattern_matcher.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/plugins/screening/rate_limiter.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/plugins/screening/session_analyzer.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/proxy/__init__.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/proxy/addon.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/proxy/interceptor.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/proxy/server.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/sandbox/__init__.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/sandbox/docker_bridge.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/sandbox/executor.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/sandbox/layers.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/sandbox/linux.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/sandbox/profile_generator.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/sandbox/project.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/sandbox/registry.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/screening/__init__.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/screening/context.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/security/__init__.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/security/integrity.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/security/language.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/security/llm_reviewer.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/security/local_model.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/security/local_reviewer.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/security/model_registry.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/security/rate_limiter.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/security/secret_scanner.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/security/session_analyzer.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/skill_template/SKILL.md +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/skill_template/__init__.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/skill_template/cli-reference.md +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/skill_template/overrides-reference.md +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/skill_template/scripts/__init__.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/skill_template/scripts/check_installed.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/skills/__init__.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/skills/config.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/skills/context.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/skills/fingerprints.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/skills/guard.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/skills/isolation.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/skills/scanner.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/vault/__init__.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/vault/cross_platform.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek/vault/keychain.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek-openclaw-plugin/node_modules/flatted/python/flatted.py +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek.egg-info/SOURCES.txt +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek.egg-info/dependency_links.txt +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek.egg-info/entry_points.txt +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek.egg-info/requires.txt +0 -0
- {tweek-0.4.2 → tweek-0.4.3}/tweek.egg-info/top_level.txt +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "tweek"
|
|
7
|
-
version = "0.4.
|
|
7
|
+
version = "0.4.3"
|
|
8
8
|
description = "Defense-in-depth security for AI coding assistants - protect credentials, code, and system from prompt injection attacks"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
|
@@ -234,6 +234,8 @@ def parse_env_keys(env_path: Path) -> List[str]:
|
|
|
234
234
|
def _ensure_local_model_deps() -> bool:
|
|
235
235
|
"""Install onnxruntime, tokenizers, numpy if missing.
|
|
236
236
|
|
|
237
|
+
Tries pip first, then uv pip (for uv-managed venvs that lack pip).
|
|
238
|
+
|
|
237
239
|
Returns True if deps are available after this call.
|
|
238
240
|
"""
|
|
239
241
|
try:
|
|
@@ -244,26 +246,54 @@ def _ensure_local_model_deps() -> bool:
|
|
|
244
246
|
except ImportError:
|
|
245
247
|
pass
|
|
246
248
|
|
|
247
|
-
|
|
249
|
+
import subprocess
|
|
250
|
+
import shutil
|
|
251
|
+
|
|
252
|
+
deps = ["onnxruntime>=1.16.0", "tokenizers>=0.15.0", "numpy>=1.24.0"]
|
|
253
|
+
console.print("\n[bold cyan]Installing classifier dependencies[/bold cyan]")
|
|
254
|
+
console.print(" [white]onnxruntime, tokenizers, numpy[/white]")
|
|
255
|
+
console.print()
|
|
256
|
+
|
|
257
|
+
# Method 1: Try pip (works for pip/pipx installs)
|
|
248
258
|
try:
|
|
249
|
-
import subprocess
|
|
250
259
|
result = subprocess.run(
|
|
251
|
-
[sys.executable, "-m", "pip", "install",
|
|
260
|
+
[sys.executable, "-m", "pip", "install", *deps],
|
|
252
261
|
capture_output=True,
|
|
253
262
|
text=True,
|
|
254
263
|
timeout=300,
|
|
255
264
|
)
|
|
256
265
|
if result.returncode == 0:
|
|
257
|
-
console.print("[green]\u2713[/green]
|
|
266
|
+
console.print("[green]\u2713[/green] Classifier dependencies installed")
|
|
258
267
|
return True
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
console.print(" [white]
|
|
266
|
-
|
|
268
|
+
except Exception:
|
|
269
|
+
pass
|
|
270
|
+
|
|
271
|
+
# Method 2: Try uv pip (works for uv tool installs where pip is absent)
|
|
272
|
+
uv_cmd = shutil.which("uv")
|
|
273
|
+
if uv_cmd:
|
|
274
|
+
console.print(" [white]pip not available in this environment, trying uv...[/white]")
|
|
275
|
+
try:
|
|
276
|
+
result = subprocess.run(
|
|
277
|
+
[uv_cmd, "pip", "install", "--python", sys.executable, *deps],
|
|
278
|
+
capture_output=True,
|
|
279
|
+
text=True,
|
|
280
|
+
timeout=300,
|
|
281
|
+
)
|
|
282
|
+
if result.returncode == 0:
|
|
283
|
+
console.print("[green]\u2713[/green] Classifier dependencies installed (via uv)")
|
|
284
|
+
return True
|
|
285
|
+
else:
|
|
286
|
+
console.print(f"[yellow]\u26a0[/yellow] uv pip install failed: {result.stderr.strip()[:200]}")
|
|
287
|
+
except Exception as e:
|
|
288
|
+
console.print(f"[yellow]\u26a0[/yellow] uv pip install failed: {e}")
|
|
289
|
+
|
|
290
|
+
console.print("[yellow]\u26a0[/yellow] Could not install classifier dependencies automatically")
|
|
291
|
+
console.print(" [white]Install manually:[/white]")
|
|
292
|
+
if uv_cmd:
|
|
293
|
+
console.print(f" uv pip install --python {sys.executable} tweek[local-models]")
|
|
294
|
+
else:
|
|
295
|
+
console.print(" pip install tweek[local-models]")
|
|
296
|
+
return False
|
|
267
297
|
|
|
268
298
|
|
|
269
299
|
def _download_local_model(quick: bool) -> bool:
|
|
@@ -293,7 +323,12 @@ def _download_local_model(quick: bool) -> bool:
|
|
|
293
323
|
console.print("\n[white]Local model module not available — skipping model download[/white]")
|
|
294
324
|
return False
|
|
295
325
|
|
|
296
|
-
|
|
326
|
+
console.print("\n[bold cyan]Local Classifier Setup[/bold cyan]")
|
|
327
|
+
console.print(" [white]The on-device classifier detects prompt injection without any API key.[/white]")
|
|
328
|
+
console.print()
|
|
329
|
+
|
|
330
|
+
# Step A: Ensure deps are installed
|
|
331
|
+
console.print(" [bold]1/2 Dependencies[/bold]")
|
|
297
332
|
deps_available = _ensure_local_model_deps()
|
|
298
333
|
if not deps_available:
|
|
299
334
|
return False
|
|
@@ -306,34 +341,37 @@ def _download_local_model(quick: bool) -> bool:
|
|
|
306
341
|
|
|
307
342
|
if not LOCAL_MODEL_AVAILABLE:
|
|
308
343
|
if not quick:
|
|
309
|
-
console.print("
|
|
344
|
+
console.print(" [yellow]\u26a0[/yellow] Dependencies installed but not functional — restart may be needed")
|
|
310
345
|
return False
|
|
311
346
|
|
|
347
|
+
# Step B: Download model
|
|
348
|
+
console.print()
|
|
349
|
+
console.print(" [bold]2/2 Model Download[/bold]")
|
|
350
|
+
|
|
312
351
|
default_name = get_default_model_name()
|
|
313
352
|
|
|
314
353
|
if is_model_installed(default_name):
|
|
315
|
-
console.print(f"
|
|
354
|
+
console.print(f" [green]\u2713[/green] Already installed ({default_name})")
|
|
316
355
|
return True
|
|
317
356
|
|
|
318
357
|
definition = get_model_definition(default_name)
|
|
319
358
|
if definition is None:
|
|
320
359
|
return False
|
|
321
360
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
console.print(f" License: {definition.license}")
|
|
327
|
-
console.print(f" [white]This enables on-device prompt injection detection (no API key needed)[/white]")
|
|
328
|
-
console.print()
|
|
361
|
+
console.print(f" Model: {definition.display_name}")
|
|
362
|
+
console.print(f" Size: ~{definition.size_mb:.0f} MB")
|
|
363
|
+
console.print(f" License: {definition.license}")
|
|
364
|
+
console.print()
|
|
329
365
|
|
|
330
|
-
from rich.progress import Progress, BarColumn, DownloadColumn, TransferSpeedColumn
|
|
366
|
+
from rich.progress import Progress, BarColumn, DownloadColumn, TransferSpeedColumn, TimeRemainingColumn
|
|
331
367
|
|
|
332
368
|
progress = Progress(
|
|
333
369
|
"[progress.description]{task.description}",
|
|
334
370
|
BarColumn(),
|
|
371
|
+
"[progress.percentage]{task.percentage:>3.0f}%",
|
|
335
372
|
DownloadColumn(),
|
|
336
373
|
TransferSpeedColumn(),
|
|
374
|
+
TimeRemainingColumn(),
|
|
337
375
|
console=console,
|
|
338
376
|
)
|
|
339
377
|
|
|
@@ -350,16 +388,16 @@ def _download_local_model(quick: bool) -> bool:
|
|
|
350
388
|
with progress:
|
|
351
389
|
download_model(default_name, progress_callback=progress_callback)
|
|
352
390
|
|
|
353
|
-
console.print(f"[green]\u2713[/green]
|
|
391
|
+
console.print(f" [green]\u2713[/green] Classifier model ready ({default_name})")
|
|
354
392
|
return True
|
|
355
393
|
|
|
356
394
|
except ModelDownloadError as e:
|
|
357
|
-
console.print(f"\n[yellow]\u26a0[/yellow] Could not download
|
|
358
|
-
console.print("
|
|
395
|
+
console.print(f"\n [yellow]\u26a0[/yellow] Could not download model: {e}")
|
|
396
|
+
console.print(" [white]Download later with: tweek model download[/white]")
|
|
359
397
|
return False
|
|
360
398
|
except Exception as e:
|
|
361
|
-
console.print(f"\n[yellow]\u26a0[/yellow] Model download failed: {e}")
|
|
362
|
-
console.print("
|
|
399
|
+
console.print(f"\n [yellow]\u26a0[/yellow] Model download failed: {e}")
|
|
400
|
+
console.print(" [white]Download later with: tweek model download[/white]")
|
|
363
401
|
return False
|
|
364
402
|
|
|
365
403
|
|
|
@@ -404,6 +442,12 @@ def _install_claude_code_hooks(install_global: bool, dev_test: bool, backup: boo
|
|
|
404
442
|
"proxy": False,
|
|
405
443
|
}
|
|
406
444
|
|
|
445
|
+
# ═══════════════════════════════════════════════════════════════
|
|
446
|
+
# PHASE 1: Environment Detection
|
|
447
|
+
# ═══════════════════════════════════════════════════════════════
|
|
448
|
+
console.print("[bold cyan]Phase 1/4: Environment Detection[/bold cyan]")
|
|
449
|
+
console.print()
|
|
450
|
+
|
|
407
451
|
# ─────────────────────────────────────────────────────────────
|
|
408
452
|
# Step 1: Detect Claude Code CLI
|
|
409
453
|
# ─────────────────────────────────────────────────────────────
|
|
@@ -567,6 +611,13 @@ def _install_claude_code_hooks(install_global: bool, dev_test: bool, backup: boo
|
|
|
567
611
|
except Exception as e:
|
|
568
612
|
console.print(f"[white]Warning: Could not check for proxy conflicts: {e}[/white]")
|
|
569
613
|
|
|
614
|
+
# ═══════════════════════════════════════════════════════════════
|
|
615
|
+
# PHASE 2: Hook & Skill Installation
|
|
616
|
+
# ═══════════════════════════════════════════════════════════════
|
|
617
|
+
console.print()
|
|
618
|
+
console.print("[bold cyan]Phase 2/4: Hook & Skill Installation[/bold cyan]")
|
|
619
|
+
console.print()
|
|
620
|
+
|
|
570
621
|
# ─────────────────────────────────────────────────────────────
|
|
571
622
|
# Step 5: Install hooks into settings.json
|
|
572
623
|
# ─────────────────────────────────────────────────────────────
|
|
@@ -730,6 +781,12 @@ def _install_claude_code_hooks(install_global: bool, dev_test: bool, backup: boo
|
|
|
730
781
|
console.print(f"[white]Tweek skill source not found \u2014 skill not installed[/white]")
|
|
731
782
|
console.print(f" [white]Skill can be installed manually from the tweek repository[/white]")
|
|
732
783
|
|
|
784
|
+
# ═══════════════════════════════════════════════════════════════
|
|
785
|
+
# PHASE 3: Classifier & Security
|
|
786
|
+
# ═══════════════════════════════════════════════════════════════
|
|
787
|
+
console.print()
|
|
788
|
+
console.print("[bold cyan]Phase 3/4: Classifier & Security Configuration[/bold cyan]")
|
|
789
|
+
|
|
733
790
|
# ─────────────────────────────────────────────────────────────
|
|
734
791
|
# Step 7: Download local classifier model
|
|
735
792
|
# ─────────────────────────────────────────────────────────────
|
|
@@ -1013,6 +1070,13 @@ def _install_claude_code_hooks(install_global: bool, dev_test: bool, backup: boo
|
|
|
1013
1070
|
except Exception as e:
|
|
1014
1071
|
console.print(f"\n[yellow]Warning: Could not save proxy config: {e}[/yellow]")
|
|
1015
1072
|
|
|
1073
|
+
# ═══════════════════════════════════════════════════════════════
|
|
1074
|
+
# PHASE 4: Verification & Summary
|
|
1075
|
+
# ═══════════════════════════════════════════════════════════════
|
|
1076
|
+
console.print()
|
|
1077
|
+
console.print("[bold cyan]Phase 4/4: Verification & Summary[/bold cyan]")
|
|
1078
|
+
console.print()
|
|
1079
|
+
|
|
1016
1080
|
# ─────────────────────────────────────────────────────────────
|
|
1017
1081
|
# Step 13: Post-install verification and summary
|
|
1018
1082
|
# ─────────────────────────────────────────────────────────────
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|