tweek 0.1.0__py3-none-any.whl
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/__init__.py +16 -0
- tweek/cli.py +3390 -0
- tweek/cli_helpers.py +193 -0
- tweek/config/__init__.py +13 -0
- tweek/config/allowed_dirs.yaml +23 -0
- tweek/config/manager.py +1064 -0
- tweek/config/patterns.yaml +751 -0
- tweek/config/tiers.yaml +129 -0
- tweek/diagnostics.py +589 -0
- tweek/hooks/__init__.py +1 -0
- tweek/hooks/pre_tool_use.py +861 -0
- tweek/integrations/__init__.py +3 -0
- tweek/integrations/moltbot.py +243 -0
- tweek/licensing.py +398 -0
- tweek/logging/__init__.py +9 -0
- tweek/logging/bundle.py +350 -0
- tweek/logging/json_logger.py +150 -0
- tweek/logging/security_log.py +745 -0
- tweek/mcp/__init__.py +24 -0
- tweek/mcp/approval.py +456 -0
- tweek/mcp/approval_cli.py +356 -0
- tweek/mcp/clients/__init__.py +37 -0
- tweek/mcp/clients/chatgpt.py +112 -0
- tweek/mcp/clients/claude_desktop.py +203 -0
- tweek/mcp/clients/gemini.py +178 -0
- tweek/mcp/proxy.py +667 -0
- tweek/mcp/screening.py +175 -0
- tweek/mcp/server.py +317 -0
- tweek/platform/__init__.py +131 -0
- tweek/plugins/__init__.py +835 -0
- tweek/plugins/base.py +1080 -0
- tweek/plugins/compliance/__init__.py +30 -0
- tweek/plugins/compliance/gdpr.py +333 -0
- tweek/plugins/compliance/gov.py +324 -0
- tweek/plugins/compliance/hipaa.py +285 -0
- tweek/plugins/compliance/legal.py +322 -0
- tweek/plugins/compliance/pci.py +361 -0
- tweek/plugins/compliance/soc2.py +275 -0
- tweek/plugins/detectors/__init__.py +30 -0
- tweek/plugins/detectors/continue_dev.py +206 -0
- tweek/plugins/detectors/copilot.py +254 -0
- tweek/plugins/detectors/cursor.py +192 -0
- tweek/plugins/detectors/moltbot.py +205 -0
- tweek/plugins/detectors/windsurf.py +214 -0
- tweek/plugins/git_discovery.py +395 -0
- tweek/plugins/git_installer.py +491 -0
- tweek/plugins/git_lockfile.py +338 -0
- tweek/plugins/git_registry.py +503 -0
- tweek/plugins/git_security.py +482 -0
- tweek/plugins/providers/__init__.py +30 -0
- tweek/plugins/providers/anthropic.py +181 -0
- tweek/plugins/providers/azure_openai.py +289 -0
- tweek/plugins/providers/bedrock.py +248 -0
- tweek/plugins/providers/google.py +197 -0
- tweek/plugins/providers/openai.py +230 -0
- tweek/plugins/scope.py +130 -0
- tweek/plugins/screening/__init__.py +26 -0
- tweek/plugins/screening/llm_reviewer.py +149 -0
- tweek/plugins/screening/pattern_matcher.py +273 -0
- tweek/plugins/screening/rate_limiter.py +174 -0
- tweek/plugins/screening/session_analyzer.py +159 -0
- tweek/proxy/__init__.py +302 -0
- tweek/proxy/addon.py +223 -0
- tweek/proxy/interceptor.py +313 -0
- tweek/proxy/server.py +315 -0
- tweek/sandbox/__init__.py +71 -0
- tweek/sandbox/executor.py +382 -0
- tweek/sandbox/linux.py +278 -0
- tweek/sandbox/profile_generator.py +323 -0
- tweek/screening/__init__.py +13 -0
- tweek/screening/context.py +81 -0
- tweek/security/__init__.py +22 -0
- tweek/security/llm_reviewer.py +348 -0
- tweek/security/rate_limiter.py +682 -0
- tweek/security/secret_scanner.py +506 -0
- tweek/security/session_analyzer.py +600 -0
- tweek/vault/__init__.py +40 -0
- tweek/vault/cross_platform.py +251 -0
- tweek/vault/keychain.py +288 -0
- tweek-0.1.0.dist-info/METADATA +335 -0
- tweek-0.1.0.dist-info/RECORD +85 -0
- tweek-0.1.0.dist-info/WHEEL +5 -0
- tweek-0.1.0.dist-info/entry_points.txt +25 -0
- tweek-0.1.0.dist-info/licenses/LICENSE +190 -0
- tweek-0.1.0.dist-info/top_level.txt +1 -0
tweek/cli_helpers.py
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Tweek CLI Helpers
|
|
4
|
+
|
|
5
|
+
Shared formatting utilities for consistent CLI output across all commands.
|
|
6
|
+
Provides colored status messages, health banners, command example formatting,
|
|
7
|
+
and progress spinners.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from contextlib import contextmanager
|
|
11
|
+
from typing import List, Tuple
|
|
12
|
+
|
|
13
|
+
from rich.console import Console
|
|
14
|
+
from rich.panel import Panel
|
|
15
|
+
from rich.table import Table
|
|
16
|
+
|
|
17
|
+
# Single shared Console instance for the entire CLI
|
|
18
|
+
console = Console()
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def print_success(message: str) -> None:
|
|
22
|
+
"""Print a success message with green checkmark."""
|
|
23
|
+
console.print(f"[green]\u2713[/green] {message}")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def print_warning(message: str) -> None:
|
|
27
|
+
"""Print a warning message with yellow triangle."""
|
|
28
|
+
console.print(f"[yellow]\u26a0[/yellow] {message}")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def print_error(message: str, fix_hint: str = "") -> None:
|
|
32
|
+
"""Print an error message with red X and optional fix hint."""
|
|
33
|
+
console.print(f"[red]\u2717[/red] {message}")
|
|
34
|
+
if fix_hint:
|
|
35
|
+
console.print(f" [dim]Hint: {fix_hint}[/dim]")
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def print_health_banner(checks: "List") -> None:
|
|
39
|
+
"""
|
|
40
|
+
Print a compact health verdict banner as a Rich Panel.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
checks: List of HealthCheck results from run_health_checks().
|
|
44
|
+
"""
|
|
45
|
+
from tweek.diagnostics import get_health_verdict, CheckStatus
|
|
46
|
+
|
|
47
|
+
verdict_text, color = get_health_verdict(checks)
|
|
48
|
+
|
|
49
|
+
ok_count = sum(1 for c in checks if c.status == CheckStatus.OK)
|
|
50
|
+
total_non_skip = sum(1 for c in checks if c.status != CheckStatus.SKIPPED)
|
|
51
|
+
|
|
52
|
+
panel = Panel(
|
|
53
|
+
f"[bold {color}]{verdict_text}[/bold {color}]\n"
|
|
54
|
+
f"[dim]Run 'tweek doctor' for details[/dim]",
|
|
55
|
+
border_style=color,
|
|
56
|
+
padding=(0, 2),
|
|
57
|
+
)
|
|
58
|
+
console.print(panel)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def format_command_example(command: str, description: str) -> str:
|
|
62
|
+
"""
|
|
63
|
+
Format a single command example line.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
command: The command string, e.g., "tweek install --scope global"
|
|
67
|
+
description: Brief explanation of what it does.
|
|
68
|
+
|
|
69
|
+
Returns:
|
|
70
|
+
Formatted string like " tweek install --scope global Install globally"
|
|
71
|
+
"""
|
|
72
|
+
return f" {command:<40s} {description}"
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def build_examples_epilog(examples: List[Tuple[str, str]]) -> str:
|
|
76
|
+
"""
|
|
77
|
+
Build a formatted epilog string with command examples.
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
examples: List of (command, description) tuples.
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
Multi-line string suitable for Click's epilog parameter.
|
|
84
|
+
"""
|
|
85
|
+
lines = ["\nExamples:"]
|
|
86
|
+
for cmd, desc in examples:
|
|
87
|
+
lines.append(format_command_example(cmd, desc))
|
|
88
|
+
return "\n".join(lines) + "\n"
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
@contextmanager
|
|
92
|
+
def spinner(message: str):
|
|
93
|
+
"""
|
|
94
|
+
Context manager for showing a Rich spinner during long operations.
|
|
95
|
+
|
|
96
|
+
Usage:
|
|
97
|
+
with spinner("Installing hooks"):
|
|
98
|
+
do_slow_work()
|
|
99
|
+
|
|
100
|
+
Args:
|
|
101
|
+
message: Text to display next to the spinner.
|
|
102
|
+
"""
|
|
103
|
+
with console.status(f"[bold cyan]{message}...", spinner="dots"):
|
|
104
|
+
yield
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def format_tier_color(tier_value: str) -> str:
|
|
108
|
+
"""
|
|
109
|
+
Return a Rich-markup colored string for a security tier value.
|
|
110
|
+
|
|
111
|
+
Args:
|
|
112
|
+
tier_value: One of "safe", "default", "risky", "dangerous".
|
|
113
|
+
|
|
114
|
+
Returns:
|
|
115
|
+
Rich-markup string with appropriate color.
|
|
116
|
+
"""
|
|
117
|
+
colors = {
|
|
118
|
+
"safe": "green",
|
|
119
|
+
"default": "white",
|
|
120
|
+
"risky": "yellow",
|
|
121
|
+
"dangerous": "red",
|
|
122
|
+
}
|
|
123
|
+
color = colors.get(tier_value.lower(), "white")
|
|
124
|
+
return f"[{color}]{tier_value}[/{color}]"
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def print_doctor_results(checks: "List") -> None:
|
|
128
|
+
"""
|
|
129
|
+
Print full doctor output with all check results.
|
|
130
|
+
|
|
131
|
+
Args:
|
|
132
|
+
checks: List of HealthCheck results from run_health_checks().
|
|
133
|
+
"""
|
|
134
|
+
from tweek.diagnostics import get_health_verdict, CheckStatus
|
|
135
|
+
|
|
136
|
+
console.print()
|
|
137
|
+
console.print("[bold]Tweek Health Check[/bold]")
|
|
138
|
+
console.print("\u2500" * 50)
|
|
139
|
+
|
|
140
|
+
status_styles = {
|
|
141
|
+
CheckStatus.OK: ("[green]OK[/green] ", "green"),
|
|
142
|
+
CheckStatus.WARNING: ("[yellow]WARN[/yellow] ", "yellow"),
|
|
143
|
+
CheckStatus.ERROR: ("[red]ERROR[/red] ", "red"),
|
|
144
|
+
CheckStatus.SKIPPED: ("[dim]SKIP[/dim] ", "dim"),
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
for check in checks:
|
|
148
|
+
style_text, _ = status_styles.get(check.status, ("[dim]???[/dim] ", "dim"))
|
|
149
|
+
console.print(f" {style_text} {check.label:<22s} {check.message}")
|
|
150
|
+
|
|
151
|
+
# Verdict
|
|
152
|
+
verdict_text, color = get_health_verdict(checks)
|
|
153
|
+
console.print()
|
|
154
|
+
console.print(f" [bold {color}]Verdict: {verdict_text}[/bold {color}]")
|
|
155
|
+
|
|
156
|
+
# Fix hints for non-OK checks
|
|
157
|
+
fixable = [c for c in checks if c.fix_hint and c.status in (CheckStatus.ERROR, CheckStatus.WARNING)]
|
|
158
|
+
if fixable:
|
|
159
|
+
console.print()
|
|
160
|
+
console.print(" [bold]Suggested fixes:[/bold]")
|
|
161
|
+
for check in fixable:
|
|
162
|
+
console.print(f" {check.label}: {check.fix_hint}")
|
|
163
|
+
|
|
164
|
+
console.print()
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def print_doctor_json(checks: "List") -> None:
|
|
168
|
+
"""
|
|
169
|
+
Print doctor results as JSON for machine consumption.
|
|
170
|
+
|
|
171
|
+
Args:
|
|
172
|
+
checks: List of HealthCheck results from run_health_checks().
|
|
173
|
+
"""
|
|
174
|
+
import json
|
|
175
|
+
from tweek.diagnostics import get_health_verdict
|
|
176
|
+
|
|
177
|
+
verdict_text, _ = get_health_verdict(checks)
|
|
178
|
+
|
|
179
|
+
output = {
|
|
180
|
+
"verdict": verdict_text,
|
|
181
|
+
"checks": [
|
|
182
|
+
{
|
|
183
|
+
"name": c.name,
|
|
184
|
+
"label": c.label,
|
|
185
|
+
"status": c.status.value,
|
|
186
|
+
"message": c.message,
|
|
187
|
+
"fix_hint": c.fix_hint or None,
|
|
188
|
+
}
|
|
189
|
+
for c in checks
|
|
190
|
+
],
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
console.print_json(json.dumps(output, indent=2))
|
tweek/config/__init__.py
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""Tweek configuration module."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from .manager import ConfigManager, SecurityTier, ConfigIssue, ConfigChange, get_config
|
|
6
|
+
|
|
7
|
+
CONFIG_DIR = Path(__file__).parent
|
|
8
|
+
PATTERNS_FILE = CONFIG_DIR / "patterns.yaml"
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"ConfigManager", "SecurityTier", "ConfigIssue", "ConfigChange",
|
|
12
|
+
"get_config", "CONFIG_DIR", "PATTERNS_FILE",
|
|
13
|
+
]
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Tweek Directory Safety Configuration
|
|
2
|
+
#
|
|
3
|
+
# This file controls WHERE Tweek hooks are active.
|
|
4
|
+
# This is a SAFETY FEATURE to prevent accidental activation in production.
|
|
5
|
+
#
|
|
6
|
+
# Options:
|
|
7
|
+
# global_enabled: true - Activate Tweek everywhere (production mode)
|
|
8
|
+
# allowed_directories: - List of directories where Tweek activates
|
|
9
|
+
#
|
|
10
|
+
# IMPORTANT: Without this file, Tweek is DISABLED everywhere.
|
|
11
|
+
|
|
12
|
+
# Set to true to enable Tweek globally (for production deployment)
|
|
13
|
+
global_enabled: false
|
|
14
|
+
|
|
15
|
+
# Directories where Tweek hooks will activate
|
|
16
|
+
# Tweek will also activate in subdirectories of these paths
|
|
17
|
+
allowed_directories:
|
|
18
|
+
# Test environment only (safe for development)
|
|
19
|
+
- ~/AI/tweek/test-environment
|
|
20
|
+
|
|
21
|
+
# Add more directories as needed:
|
|
22
|
+
# - ~/projects/sensitive-project
|
|
23
|
+
# - /path/to/another/project
|