tweek 0.2.1__py3-none-any.whl → 0.3.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/cli_helpers.py CHANGED
@@ -32,7 +32,7 @@ def print_error(message: str, fix_hint: str = "") -> None:
32
32
  """Print an error message with red X and optional fix hint."""
33
33
  console.print(f"[red]\u2717[/red] {message}")
34
34
  if fix_hint:
35
- console.print(f" [dim]Hint: {fix_hint}[/dim]")
35
+ console.print(f" [white]Hint: {fix_hint}[/white]")
36
36
 
37
37
 
38
38
  def print_health_banner(checks: "List") -> None:
@@ -51,7 +51,7 @@ def print_health_banner(checks: "List") -> None:
51
51
 
52
52
  panel = Panel(
53
53
  f"[bold {color}]{verdict_text}[/bold {color}]\n"
54
- f"[dim]Run 'tweek doctor' for details[/dim]",
54
+ f"[white]Run 'tweek doctor' for details[/white]",
55
55
  border_style=color,
56
56
  padding=(0, 2),
57
57
  )
@@ -63,11 +63,11 @@ def format_command_example(command: str, description: str) -> str:
63
63
  Format a single command example line.
64
64
 
65
65
  Args:
66
- command: The command string, e.g., "tweek install --scope global"
66
+ command: The command string, e.g., "tweek protect claude-code --scope global"
67
67
  description: Brief explanation of what it does.
68
68
 
69
69
  Returns:
70
- Formatted string like " tweek install --scope global Install globally"
70
+ Formatted string like " tweek protect claude-code --scope global Install globally"
71
71
  """
72
72
  return f" {command:<40s} {description}"
73
73
 
@@ -141,11 +141,11 @@ def print_doctor_results(checks: "List") -> None:
141
141
  CheckStatus.OK: ("[green]OK[/green] ", "green"),
142
142
  CheckStatus.WARNING: ("[yellow]WARN[/yellow] ", "yellow"),
143
143
  CheckStatus.ERROR: ("[red]ERROR[/red] ", "red"),
144
- CheckStatus.SKIPPED: ("[dim]SKIP[/dim] ", "dim"),
144
+ CheckStatus.SKIPPED: ("[white]SKIP[/white] ", "white"),
145
145
  }
146
146
 
147
147
  for check in checks:
148
- style_text, _ = status_styles.get(check.status, ("[dim]???[/dim] ", "dim"))
148
+ style_text, _ = status_styles.get(check.status, ("[white]???[/white] ", "white"))
149
149
  console.print(f" {style_text} {check.label:<22s} {check.message}")
150
150
 
151
151
  # Verdict
tweek/cli_model.py CHANGED
@@ -90,7 +90,7 @@ def model_download(name: str, force: bool):
90
90
  console.print()
91
91
  console.print(f"[green]Model downloaded to {model_dir}[/green]")
92
92
  console.print(
93
- f"[dim]Local screening is now active for risky/dangerous operations.[/dim]"
93
+ f"[white]Local screening is now active for risky/dangerous operations.[/white]"
94
94
  )
95
95
 
96
96
  except ModelDownloadError as e:
@@ -130,8 +130,8 @@ def model_list(available: bool):
130
130
  defn.display_name,
131
131
  f"~{defn.size_mb:.0f} MB",
132
132
  defn.license,
133
- "[green]yes[/green]" if installed else "[dim]no[/dim]",
134
- "[green]yes[/green]" if active else "[dim]-[/dim]",
133
+ "[green]yes[/green]" if installed else "[white]no[/white]",
134
+ "[green]yes[/green]" if active else "[white]-[/white]",
135
135
  )
136
136
 
137
137
  console.print(table)
@@ -158,7 +158,7 @@ def model_list(available: bool):
158
158
  name,
159
159
  defn.display_name if defn else name,
160
160
  size_str,
161
- "[green]yes[/green]" if active else "[dim]-[/dim]",
161
+ "[green]yes[/green]" if active else "[white]-[/white]",
162
162
  )
163
163
 
164
164
  console.print(table)
@@ -221,10 +221,10 @@ def model_status():
221
221
  )
222
222
  else:
223
223
  fallback_lines.append(
224
- " Cloud LLM: [dim]none (no API keys configured)[/dim]"
224
+ " Cloud LLM: [white]none (no API keys configured)[/white]"
225
225
  )
226
226
  except Exception:
227
- fallback_lines.append(" Cloud LLM: [dim]unavailable[/dim]")
227
+ fallback_lines.append(" Cloud LLM: [white]unavailable[/white]")
228
228
 
229
229
  # Overall status
230
230
  if LOCAL_MODEL_AVAILABLE and installed:
@@ -232,7 +232,7 @@ def model_status():
232
232
  elif LOCAL_MODEL_AVAILABLE and not installed:
233
233
  status = "[yellow]Ready[/yellow] - Dependencies installed, model not downloaded"
234
234
  else:
235
- status = "[dim]Inactive[/dim] - Install dependencies: pip install tweek[local-models]"
235
+ status = "[white]Inactive[/white] - Install dependencies: pip install tweek[local-models]"
236
236
 
237
237
  content = f"Status: {status}\n\n"
238
238
  content += "[bold]Dependencies[/bold]\n" + "\n".join(deps_lines) + "\n\n"
tweek/config/manager.py CHANGED
@@ -173,7 +173,7 @@ class ConfigManager:
173
173
  "plugins", "mcp", "proxy", "sandbox", "isolation_chamber",
174
174
  "llm_review", "local_model", "rate_limiting", "session_analysis",
175
175
  "path_boundary", "non_english_handling", "version", "tiers",
176
- "heuristic_scorer",
176
+ "heuristic_scorer", "openclaw",
177
177
  }
178
178
 
179
179
  def __init__(
tweek/diagnostics.py CHANGED
@@ -3,7 +3,7 @@
3
3
  Tweek Diagnostics Engine
4
4
 
5
5
  Health check system for verifying Tweek installation, configuration,
6
- and runtime dependencies. Used by `tweek doctor` and the status banner.
6
+ and runtime dependencies. Used by `tweek doctor` and the health banner.
7
7
  """
8
8
 
9
9
  import json
@@ -30,7 +30,7 @@ class HealthCheck:
30
30
  label: str # Human label: "Hook Installation"
31
31
  status: CheckStatus
32
32
  message: str # Description: "Global hooks installed at ~/.claude/"
33
- fix_hint: str = "" # Recovery: "Run: tweek install --scope global"
33
+ fix_hint: str = "" # Recovery: "Run: tweek protect claude-code --global"
34
34
 
35
35
 
36
36
  def run_health_checks(verbose: bool = False) -> List[HealthCheck]:
@@ -168,7 +168,7 @@ def _check_hooks_installed(verbose: bool = False) -> HealthCheck:
168
168
  label="Hook Installation",
169
169
  status=CheckStatus.WARNING,
170
170
  message="Installed in project only (./.claude)",
171
- fix_hint="Run: tweek install --scope global (to protect all projects)",
171
+ fix_hint="Run: tweek protect claude-code --global (to protect all projects)",
172
172
  )
173
173
  else:
174
174
  return HealthCheck(
@@ -176,7 +176,7 @@ def _check_hooks_installed(verbose: bool = False) -> HealthCheck:
176
176
  label="Hook Installation",
177
177
  status=CheckStatus.ERROR,
178
178
  message="No hooks installed",
179
- fix_hint="Run: tweek install",
179
+ fix_hint="Run: tweek protect claude-code",
180
180
  )
181
181
 
182
182
 
@@ -597,18 +597,53 @@ def _check_llm_review(verbose: bool = False) -> HealthCheck:
597
597
  get_llm_reviewer,
598
598
  _detect_local_server,
599
599
  FallbackReviewProvider,
600
+ DEFAULT_API_KEY_ENVS,
600
601
  )
602
+ from tweek.security.local_model import LOCAL_MODEL_AVAILABLE
601
603
 
602
604
  reviewer = get_llm_reviewer()
603
605
 
604
606
  if not reviewer.enabled:
607
+ # Check which env vars are missing to give specific guidance
608
+ missing_keys = []
609
+ for provider, env_names in DEFAULT_API_KEY_ENVS.items():
610
+ if isinstance(env_names, list):
611
+ if not any(os.environ.get(e) for e in env_names):
612
+ missing_keys.append(f"{' or '.join(env_names)} ({provider})")
613
+ else:
614
+ if not os.environ.get(env_names):
615
+ missing_keys.append(f"{env_names} ({provider})")
616
+
617
+ hint_parts = [
618
+ "To enable cloud LLM review for uncertain classifications:",
619
+ " Set one of: " + ", ".join(
620
+ k.split(" (")[0] for k in missing_keys
621
+ ),
622
+ ]
623
+
624
+ if not LOCAL_MODEL_AVAILABLE:
625
+ hint_parts.append(
626
+ " Or install the local model: pip install 'tweek[local]'"
627
+ )
628
+ else:
629
+ hint_parts.append(
630
+ " Local ONNX model is available but could not initialize"
631
+ )
632
+
633
+ hint_parts.append(
634
+ " Or install Ollama (https://ollama.ai) for local LLM review"
635
+ )
636
+ hint_parts.append(
637
+ " See: docs/CONFIGURATION.md or ~/.tweek/config.yaml"
638
+ )
639
+
605
640
  return HealthCheck(
606
641
  name="llm_review",
607
642
  label="LLM Review",
608
643
  status=CheckStatus.WARNING,
609
- message="No LLM provider available (review disabled)",
610
- fix_hint="Set ANTHROPIC_API_KEY, OPENAI_API_KEY, or GOOGLE_API_KEY. "
611
- "Or install Ollama: https://ollama.ai",
644
+ message="No LLM provider available review disabled, "
645
+ "pattern matching and heuristic scoring still active",
646
+ fix_hint="\n".join(hint_parts),
612
647
  )
613
648
 
614
649
  # Build status message
@@ -636,6 +671,23 @@ def _check_llm_review(verbose: bool = False) -> HealthCheck:
636
671
  except Exception:
637
672
  pass
638
673
 
674
+ # In verbose mode, report escalation path
675
+ if verbose:
676
+ if provider_name == "local":
677
+ # Check if cloud escalation is available
678
+ cloud_env_found = any(
679
+ os.environ.get(e) if isinstance(e, str)
680
+ else any(os.environ.get(v) for v in e)
681
+ for e in DEFAULT_API_KEY_ENVS.values()
682
+ )
683
+ if cloud_env_found:
684
+ parts.append("cloud escalation: available")
685
+ else:
686
+ parts.append("cloud escalation: not configured")
687
+
688
+ if LOCAL_MODEL_AVAILABLE:
689
+ parts.append("local ONNX: available")
690
+
639
691
  return HealthCheck(
640
692
  name="llm_review",
641
693
  label="LLM Review",
@@ -925,10 +925,10 @@ def process_hook(input_data: dict, logger: SecurityLogger) -> dict:
925
925
  }
926
926
  }
927
927
 
928
- # Block AI from running tweek trust/untrust/uninstall — human-only commands
928
+ # Block AI from running tweek trust/untrust/uninstall/unprotect — human-only commands
929
929
  command_stripped = command.strip()
930
- if re.match(r"tweek\s+(trust|untrust|uninstall)\b", command_stripped):
931
- if "uninstall" in command_stripped:
930
+ if re.match(r"tweek\s+(trust|untrust|uninstall|unprotect)\b", command_stripped):
931
+ if "uninstall" in command_stripped or "unprotect" in command_stripped:
932
932
  reason = (
933
933
  "TWEEK SELF-PROTECTION: Uninstall must be done by a human.\n"
934
934
  "Run this command directly in your terminal:\n"
tweek/mcp/approval_cli.py CHANGED
@@ -39,7 +39,7 @@ def display_pending(queue: ApprovalQueue) -> int:
39
39
  pending = queue.get_pending()
40
40
 
41
41
  if not pending:
42
- console.print("[dim]No pending approval requests.[/dim]")
42
+ console.print("[white]No pending approval requests.[/white]")
43
43
  return 0
44
44
 
45
45
  table = Table(title="Pending Approval Requests", show_lines=True)
@@ -112,7 +112,7 @@ def display_request_detail(request: ApprovalRequest):
112
112
  remaining = request.time_remaining
113
113
  if remaining > 0:
114
114
  lines.append("")
115
- lines.append(f"[dim]Auto-deny in {int(remaining)}s[/dim]")
115
+ lines.append(f"[white]Auto-deny in {int(remaining)}s[/white]")
116
116
 
117
117
  panel = Panel(
118
118
  "\n".join(lines),
@@ -160,7 +160,7 @@ def run_approval_daemon(
160
160
  # Prompt for decision
161
161
  decision = _prompt_decision(console, req)
162
162
  if decision == "quit":
163
- console.print("[dim]Exiting approval daemon.[/dim]")
163
+ console.print("[white]Exiting approval daemon.[/white]")
164
164
  return
165
165
  elif decision == "skip":
166
166
  continue
@@ -200,7 +200,7 @@ def run_approval_daemon(
200
200
  time.sleep(poll_interval)
201
201
 
202
202
  except KeyboardInterrupt:
203
- console.print("\n[dim]Approval daemon stopped.[/dim]")
203
+ console.print("\n[white]Approval daemon stopped.[/white]")
204
204
 
205
205
  # Print summary
206
206
  stats = queue.get_stats()
tweek/sandbox/linux.py CHANGED
@@ -237,13 +237,13 @@ def prompt_install_firejail(console) -> bool:
237
237
  pkg_info = get_linux_package_manager()
238
238
 
239
239
  if not pkg_info:
240
- console.print("[dim]Could not detect package manager.[/dim]")
240
+ console.print("[white]Could not detect package manager.[/white]")
241
241
  console.print("Install firejail manually: https://firejail.wordpress.com/download-2/")
242
242
  return False
243
243
 
244
244
  manager, command = pkg_info
245
- console.print(f"[dim]Detected package manager: {manager}[/dim]")
246
- console.print(f"[dim]Command: {' '.join(command)}[/dim]\n")
245
+ console.print(f"[white]Detected package manager: {manager}[/white]")
246
+ console.print(f"[white]Command: {' '.join(command)}[/white]\n")
247
247
 
248
248
  if Confirm.ask("Install firejail for full sandbox protection?", default=False):
249
249
  try:
@@ -260,13 +260,13 @@ def prompt_install_firejail(console) -> bool:
260
260
 
261
261
  except subprocess.CalledProcessError as e:
262
262
  console.print(f"[red]Installation failed (exit code {e.returncode})[/red]")
263
- console.print("[dim]Try running the install command manually with sudo[/dim]")
263
+ console.print("[white]Try running the install command manually with sudo[/white]")
264
264
  return False
265
265
  except KeyboardInterrupt:
266
266
  console.print("\n[yellow]Installation cancelled.[/yellow]")
267
267
  return False
268
268
  else:
269
- console.print("[dim]Skipping firejail. Sandbox layer will be disabled.[/dim]")
269
+ console.print("[white]Skipping firejail. Sandbox layer will be disabled.[/white]")
270
270
  return False
271
271
 
272
272
 
@@ -28,7 +28,7 @@ The script returns JSON with these fields:
28
28
  | Field | Meaning |
29
29
  |-------|---------|
30
30
  | `status: "fully_operational"` | Tweek is installed and hooks are active. Proceed to help user with their question. |
31
- | `status: "installed_no_hooks"` | Tweek is installed but hooks are not registered. Tell user to run `tweek install`. |
31
+ | `status: "installed_no_hooks"` | Tweek is installed but hooks are not registered. Tell user to run `tweek protect claude-code`. |
32
32
  | `status: "hooks_only"` | Hooks reference tweek but the package is missing. Tell user to reinstall. |
33
33
  | `status: "not_installed"` | Tweek is not present. Check `install_declined` before offering to install. |
34
34
  | `install_declined: true` | User previously declined installation. **Do not offer to install again** unless the user explicitly asks. |
@@ -142,7 +142,6 @@ Trust mode is auto-detected from the terminal environment. It can be overridden
142
142
 
143
143
  | Command | What It Does |
144
144
  |---------|-------------|
145
- | `tweek status` | Show installation status and active configuration |
146
145
  | `tweek doctor` | Health check — verify all layers are active |
147
146
  | `tweek doctor --verbose` | Detailed diagnostics with fix suggestions |
148
147
  | `tweek logs show` | View recent security events |
@@ -185,7 +184,7 @@ For the full configuration format and examples, see `overrides-reference.md` in
185
184
  | "Tweek isn't working" | Run `tweek doctor --verbose` and review the output. Common issues: hooks not registered, outdated patterns, missing dependencies. |
186
185
  | "How do I update patterns?" | Run `tweek update` to fetch the latest pattern definitions. |
187
186
  | "I want to pause tweek for this project" | Tell the user to run `tweek trust` in their terminal. This exempts the current project from screening. They can resume with `tweek untrust`. |
188
- | "I want to disable tweek entirely" | Tell the user to run `tweek uninstall` to remove hooks. Run `tweek install` to re-enable later. |
187
+ | "I want to disable tweek entirely" | Tell the user to run `tweek unprotect claude-code` to remove hooks. Run `tweek protect claude-code` to re-enable later. |
189
188
  | "What has tweek blocked recently?" | Run `tweek logs show` to see recent security events with details. |
190
189
 
191
190
  ---
@@ -6,12 +6,21 @@ Complete command reference for the `tweek` command-line tool.
6
6
 
7
7
  ## Installation & Setup
8
8
 
9
- ### `tweek install`
9
+ ### `tweek protect`
10
10
 
11
- Install Tweek hooks into the AI assistant's configuration.
11
+ Set up Tweek protection for AI tools. With no arguments, launches an interactive wizard.
12
12
 
13
13
  ```
14
- tweek install [OPTIONS]
14
+ tweek protect # Interactive wizard — detects and protects all tools
15
+ tweek protect --status # Show protection status for all tools
16
+ ```
17
+
18
+ ### `tweek protect claude-code`
19
+
20
+ Install Tweek hooks into Claude Code (replaces the former `tweek install` command).
21
+
22
+ ```
23
+ tweek protect claude-code [OPTIONS]
15
24
  ```
16
25
 
17
26
  | Option | Description |
@@ -25,15 +34,29 @@ tweek install [OPTIONS]
25
34
  | `--skip-env-scan` | Skip scanning for credential files to migrate |
26
35
  | `--backup / --no-backup` | Backup existing hooks before installation (default: backup) |
27
36
 
28
- ### `tweek uninstall`
37
+ ### `tweek protect claude-desktop`
38
+
39
+ Install Tweek as MCP server for Claude Desktop.
40
+
41
+ ### `tweek protect chatgpt`
42
+
43
+ Install Tweek as MCP server for ChatGPT Desktop.
29
44
 
30
- Remove Tweek hooks from configuration.
45
+ ### `tweek protect gemini`
46
+
47
+ Install Tweek as MCP server for Gemini CLI.
48
+
49
+ ### `tweek unprotect`
50
+
51
+ Remove Tweek protection from an AI tool (replaces the former `tweek uninstall` command).
31
52
 
32
53
  ```
33
- tweek uninstall [--global] [--confirm]
54
+ tweek unprotect <tool> [--confirm]
55
+ tweek unprotect --all [--confirm]
34
56
  ```
35
57
 
36
- By default removes from `./.claude/` (current project). Use `--global` to remove from `~/.claude/`.
58
+ By default removes from `./.claude/` (current project). Use `--global` to remove from `~/.claude/` (for claude-code).
59
+ Use `--all` to remove Tweek from all tools at once.
37
60
 
38
61
  ---
39
62
 
@@ -82,14 +105,6 @@ tweek untrust /path/to/project # Untrust specific directory
82
105
 
83
106
  ## Diagnostics
84
107
 
85
- ### `tweek status`
86
-
87
- Show installation status and active configuration.
88
-
89
- ```
90
- tweek status
91
- ```
92
-
93
108
  ### `tweek doctor`
94
109
 
95
110
  Run health checks on all screening layers.
@@ -313,12 +328,12 @@ tweek plugins search QUERY
313
328
 
314
329
  ## Proxy (API Interception)
315
330
 
316
- ### `tweek protect`
331
+ ### `tweek protect openclaw`
317
332
 
318
- Set up protection for an AI gateway.
333
+ Set up proxy protection for OpenClaw.
319
334
 
320
335
  ```
321
- tweek protect [openclaw|claude]
336
+ tweek protect openclaw
322
337
  ```
323
338
 
324
339
  ### `tweek proxy start / stop`
@@ -144,18 +144,18 @@ def check_installation():
144
144
  result["status"] = "fully_operational"
145
145
  elif result["tweek_in_path"] and not result["hooks_registered"]:
146
146
  result["status"] = "installed_no_hooks"
147
- result["install_command"] = "tweek install"
147
+ result["install_command"] = "tweek protect claude-code"
148
148
  elif not result["tweek_in_path"] and result["hooks_registered"]:
149
149
  result["status"] = "hooks_only"
150
150
  result["install_command"] = "pip install tweek"
151
151
  else:
152
152
  result["status"] = "not_installed"
153
153
  if result["pipx_available"]:
154
- result["install_command"] = "pipx install tweek && tweek install"
154
+ result["install_command"] = "pipx install tweek && tweek protect claude-code"
155
155
  elif result["pip_available"]:
156
- result["install_command"] = "pip install tweek && tweek install"
156
+ result["install_command"] = "pip install tweek && tweek protect claude-code"
157
157
  else:
158
- result["install_command"] = "python3 -m pip install tweek && tweek install"
158
+ result["install_command"] = "python3 -m pip install tweek && tweek protect claude-code"
159
159
 
160
160
  return result
161
161
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tweek
3
- Version: 0.2.1
3
+ Version: 0.3.0
4
4
  Summary: Defense-in-depth security for AI coding assistants - protect credentials, code, and system from prompt injection attacks
5
5
  Author: Tommy Mancino
6
6
  License-Expression: Apache-2.0
@@ -21,7 +21,9 @@ Classifier: Topic :: Software Development :: Quality Assurance
21
21
  Requires-Python: >=3.9
22
22
  Description-Content-Type: text/markdown
23
23
  License-File: LICENSE
24
+ License-File: NOTICE
24
25
  Requires-Dist: click>=8.0
26
+ Requires-Dist: pydantic>=2.0
25
27
  Requires-Dist: pyyaml>=6.0
26
28
  Requires-Dist: rich>=13.0
27
29
  Requires-Dist: keyring>=25.0
@@ -42,6 +44,7 @@ Requires-Dist: mitmproxy>=10.0; extra == "proxy"
42
44
  Provides-Extra: dev
43
45
  Requires-Dist: pytest>=7.0; extra == "dev"
44
46
  Requires-Dist: pytest-cov>=4.0; extra == "dev"
47
+ Requires-Dist: pytest-xdist>=3.5.0; extra == "dev"
45
48
  Requires-Dist: black>=23.0; extra == "dev"
46
49
  Requires-Dist: ruff>=0.1.0; extra == "dev"
47
50
  Requires-Dist: twine>=4.0; extra == "dev"
@@ -105,11 +108,12 @@ pip install --user tweek
105
108
  ### Protect Your Tools
106
109
 
107
110
  ```bash
108
- tweek install # Claude Code (CLI hooks)
111
+ tweek protect # Interactive wizard detects and protects all tools
112
+ tweek protect claude-code # Claude Code (CLI hooks)
109
113
  tweek protect openclaw # OpenClaw (HTTP proxy)
110
- tweek mcp install claude-desktop # Claude Desktop (MCP proxy)
111
- tweek mcp install chatgpt-desktop # ChatGPT Desktop (MCP proxy)
112
- tweek mcp install gemini # Gemini CLI (MCP proxy)
114
+ tweek protect claude-desktop # Claude Desktop (MCP proxy)
115
+ tweek protect chatgpt # ChatGPT Desktop (MCP proxy)
116
+ tweek protect gemini # Gemini CLI (MCP proxy)
113
117
  tweek proxy setup # Cursor, Windsurf, Continue.dev (HTTP proxy)
114
118
  ```
115
119
 
@@ -127,11 +131,11 @@ That's it. Tweek auto-detects your tools, applies all 259 attack patterns across
127
131
 
128
132
  | Client | Integration | Setup |
129
133
  |--------|------------|-------|
130
- | **Claude Code** | CLI hooks (native) | `tweek install` |
134
+ | **Claude Code** | CLI hooks (native) | `tweek protect claude-code` |
131
135
  | **OpenClaw** | Proxy wrapping | `tweek protect openclaw` |
132
- | **Claude Desktop** | MCP proxy | `tweek mcp install claude-desktop` |
133
- | **ChatGPT Desktop** | MCP proxy | `tweek mcp install chatgpt-desktop` |
134
- | **Gemini CLI** | MCP proxy | `tweek mcp install gemini` |
136
+ | **Claude Desktop** | MCP proxy | `tweek protect claude-desktop` |
137
+ | **ChatGPT Desktop** | MCP proxy | `tweek protect chatgpt` |
138
+ | **Gemini CLI** | MCP proxy | `tweek protect gemini` |
135
139
  | **Cursor** | HTTP proxy | `tweek proxy setup` |
136
140
  | **Windsurf** | HTTP proxy | `tweek proxy setup` |
137
141
  | **Continue.dev** | HTTP proxy | `tweek proxy setup` |
@@ -169,14 +173,16 @@ See the full [Attack Patterns Reference](docs/ATTACK_PATTERNS.md) for all 259 pa
169
173
 
170
174
  Most security tools that use AI send your data to an API. Tweek doesn't.
171
175
 
172
- Tweek ships with a **custom-trained prompt injection classifier** ([DeBERTa-v3-base](https://huggingface.co/protectai/deberta-v3-base-prompt-injection-v2)) that runs entirely on your machine via ONNX Runtime. No API keys. No cloud calls. No data leaves your computer.
176
+ Tweek uses [ProtectAI's DeBERTa-v3-base Prompt Injection v2](https://huggingface.co/protectai/deberta-v3-base-prompt-injection-v2) classifier, fine-tuned from [Microsoft's DeBERTa-v3-base](https://huggingface.co/microsoft/deberta-v3-base), running entirely on your machine via [ONNX Runtime](https://onnxruntime.ai). No API keys. No cloud calls. No data leaves your computer.
173
177
 
174
178
  | Property | Value |
175
179
  |----------|-------|
176
- | **Model** | DeBERTa-v3-base, fine-tuned for prompt injection |
177
- | **Runtime** | ONNX (CPU-only, single thread) |
180
+ | **Model** | [ProtectAI DeBERTa-v3-base Prompt Injection v2](https://huggingface.co/protectai/deberta-v3-base-prompt-injection-v2) (Apache 2.0) |
181
+ | **Base Model** | [Microsoft DeBERTa-v3-base](https://huggingface.co/microsoft/deberta-v3-base) (MIT) |
182
+ | **Runtime** | ONNX Runtime (CPU-only, single thread) |
178
183
  | **Privacy** | 100% on-device — zero network calls |
179
- | **License** | Apache 2.0 |
184
+
185
+ See [NOTICE](./NOTICE) for full third-party license texts and attribution.
180
186
 
181
187
  The local model handles the gray-area attacks that pattern matching alone cannot catch — encoded instructions, novel injection techniques, social engineering disguised as legitimate content. High-confidence results are returned instantly. Uncertain results can optionally escalate to a cloud LLM for deeper analysis (you bring your own API key).
182
188
 
@@ -278,4 +284,4 @@ To report a security vulnerability, email security@gettweek.com.
278
284
 
279
285
  ## License
280
286
 
281
- [Apache 2.0](LICENSE)
287
+ [Apache 2.0](LICENSE) | [Third-Party Notices](NOTICE)
@@ -1,15 +1,15 @@
1
- tweek/__init__.py,sha256=mZ5RaMD3SVWt8mcinSq8KlCaNLoVqgVu-9cewcMVlt0,360
1
+ tweek/__init__.py,sha256=v1mBM39Sp-MgonHi8fotmfcN7dxbow_Eh9xdbSYnjN4,360
2
2
  tweek/_keygen.py,sha256=UapwIKNSwaRWdqHoJoF3hmKuiux6aIiFGe8WVskTbI8,1286
3
3
  tweek/audit.py,sha256=Bp4RETwdiHpT2EEi45atZa0LlJUOtALhrc3UT8MHvF8,8868
4
- tweek/cli.py,sha256=J7L0xhfZ1DmzrVGwvEBTCRLYd5w5UakSGWH9DikOOSg,245768
5
- tweek/cli_helpers.py,sha256=adczf-8oHsc-TDdfJqPQoG4IgWEfJmRORm2NmVWaCOw,5494
6
- tweek/cli_model.py,sha256=QO6Q3iy0d-hsMLdgWwDiigqN0rjep4Ufa73VCZjVguc,12825
7
- tweek/diagnostics.py,sha256=eOiI6MlfqimzUeG7Uvwhcnen_FlINejfawLun5DY59o,22472
4
+ tweek/cli.py,sha256=0AxYSIQ56Y2OHNVGSocNksYkiiLfUFNx5XvBUzCtZZI,254670
5
+ tweek/cli_helpers.py,sha256=Q2NTOkyRTOIPNLMqY2jA5_tuzDPksAGwGXYPRK3bzoY,5538
6
+ tweek/cli_model.py,sha256=iMZStFqA0Nqyzm4rxSbhD4v-AqcO6h5NI72AR7cldoY,12853
7
+ tweek/diagnostics.py,sha256=KbtXQH8QrRBoyIFWumL6q9--aQQdR0tUo2GzjMhwpII,24601
8
8
  tweek/licensing.py,sha256=4Pt34t8Y60jaLMBYLjnmLs_0o_LUahOhGflhXeZtuPU,11703
9
9
  tweek/config/__init__.py,sha256=C_kQm0LqYdM67E9wNi6bsX2V7xz7GY4HiICb_XlrX8A,362
10
10
  tweek/config/allowed_dirs.yaml,sha256=dMF_DqKgQThzkdIEoXzDBfAjbopGrk0HTkiM7ENmBaU,788
11
11
  tweek/config/families.yaml,sha256=jkNO0UsmX3MFlTKC9Or3p8_MlD3ZtHM0SrQIYFqx9i8,18212
12
- tweek/config/manager.py,sha256=Cg6gG9c4zZpDTxy8WZ_T-diPBzV8DL2Hny-Yu9DBV6I,39335
12
+ tweek/config/manager.py,sha256=FTBJ4sMwnENH9tfvKB5d1SFve1R__k5j2KXb38vn1CA,39347
13
13
  tweek/config/patterns.yaml,sha256=8ow--0qdPJNjIY94j-vDEcrHt-TYgf9uuPCiqSMCIEQ,85376
14
14
  tweek/config/tiers.yaml,sha256=9hIXQ9izVKXd8ptoCsQiBo2r_XY8RvIk7VWrhWggkbc,10191
15
15
  tweek/hooks/__init__.py,sha256=GcgDjPdhZayxmyZ4-GfBa-ISARNtt9087RsuprRq2-s,54
@@ -17,7 +17,7 @@ tweek/hooks/break_glass.py,sha256=GNMhCtLWPylNMlQ5QfsoUkEjgIT1Uk1Ik7HvRWeE5N8,46
17
17
  tweek/hooks/feedback.py,sha256=uuA4opHYyBHC5sElBz-fr2Je3cg2DAv-aRHvETZcag0,6555
18
18
  tweek/hooks/overrides.py,sha256=1Yw_NPpZMvcFG_uyNY-ouBKSSomnxOptRedSjzkkhmE,18635
19
19
  tweek/hooks/post_tool_use.py,sha256=DiAnWOBd9t4vpMz1JsgUjYzToU6i-igesP2Vk83AAAc,17195
20
- tweek/hooks/pre_tool_use.py,sha256=Y4uIz-vB_39KHgL54HBOUCmX01Ze-8F-2vZIwK4655c,71688
20
+ tweek/hooks/pre_tool_use.py,sha256=70XbonRSGh8rYpDlI4R_Z5Ug2LwU4iLyLsS87I5xlqc,71743
21
21
  tweek/integrations/__init__.py,sha256=sl7wFwbygmnruugX4bO2EUjoXxBlCpzTKbj-1zHuUPg,78
22
22
  tweek/integrations/openclaw.py,sha256=jX99__ODGI7Cq6gclSTK2pI5lsI7UGh5_iCHmq1R8RY,13798
23
23
  tweek/integrations/openclaw_server.py,sha256=Ah7wxsxKE2lQmIdlrFINvt5jW9U_bqqERfG3X2N5Aps,12533
@@ -27,7 +27,7 @@ tweek/logging/json_logger.py,sha256=zXOsFAufj3MF0TboM5zSS7V8uNBDJea7YkJHR-uQgBA,
27
27
  tweek/logging/security_log.py,sha256=BwHDdrN0VCpqssStvsZdASFnyxVpANCq9xiSkFsEFFk,28486
28
28
  tweek/mcp/__init__.py,sha256=AOFDrzDfjOvICMcN15Hz-iNCT0Kf6oyUBB-iNEW5Vr4,791
29
29
  tweek/mcp/approval.py,sha256=WIFQi4ryXEFtgQyzQIshwgP5h_Th7Cxepx9NIhf2o_4,17885
30
- tweek/mcp/approval_cli.py,sha256=yXIDh75lci3DWyJtZG3izryIoO4jSXGDuaJRch3K1rg,11265
30
+ tweek/mcp/approval_cli.py,sha256=8WtmJF7KTLmdEF5wHqENaUJUzKEQej4CjRtFey4RcGg,11281
31
31
  tweek/mcp/proxy.py,sha256=0p5OEaRsFuNRcGR3rnqprkPjTdSSYgrsU_XXQiFPS8c,24819
32
32
  tweek/mcp/screening.py,sha256=ax5TK8ZSXb9uo5DFx3mxiYrBKjDBP0cTLNhA05TXb80,5421
33
33
  tweek/mcp/server.py,sha256=3pF3piXUNtIf2-SUJPCjGZPD42esg2KFsVXpaBXrq3E,10901
@@ -83,7 +83,7 @@ tweek/sandbox/__init__.py,sha256=bT4ZAQkY2WOELdrRwf87hVdePXq6QPmvBgDs4WqDWgU,229
83
83
  tweek/sandbox/docker_bridge.py,sha256=QD17ZuPVRgrbg0zFHdvji-VA11Jo5Td73_Kn6gbRaxc,5030
84
84
  tweek/sandbox/executor.py,sha256=MLgMps4CNH_rtbbvseIKuuusMUznv6U7njPKwVCT-Bo,13186
85
85
  tweek/sandbox/layers.py,sha256=Qd-kRfEKnBWax6n9h9COJeCTkvqnLAf157bHpGMfRYg,3263
86
- tweek/sandbox/linux.py,sha256=rF-w4q6uSt3rBoUnw0UXS1lFBdjooqV9YWVwQBaeTzM,8686
86
+ tweek/sandbox/linux.py,sha256=mKA3rI--TmJnVU6uE2kAxBAD8DGZjHUHlZ-sSLzuoWs,8706
87
87
  tweek/sandbox/profile_generator.py,sha256=J-nNold-J1YxuSaX5BdQ_lcCC03ElwPJT7fJ4UciXfc,10957
88
88
  tweek/sandbox/project.py,sha256=SqD4g4i1VqfWTdm--6gBzTC8AZCdHuyPLR37Y9jp30k,19575
89
89
  tweek/sandbox/registry.py,sha256=ZZDQYeJMNAJ0FrFEayo1KyC5r3qXSBx6Tu-JcXIMjtI,5060
@@ -98,12 +98,12 @@ tweek/security/model_registry.py,sha256=XscpZcWaaJwHldX2T9C1T1zSvJ3lm0aSW4nIhwRp
98
98
  tweek/security/rate_limiter.py,sha256=bY8VIkQ-wCbNOYTLwD4MsMBoHk59zPWeZCkuE8Zntm8,24185
99
99
  tweek/security/secret_scanner.py,sha256=G-bbMwsAJD197BEOnZJdn_qphS4RNPK_wpLfkpiLuFU,18774
100
100
  tweek/security/session_analyzer.py,sha256=-Ylp583VZ_YJRkN5JZrYpaK1sVbiM6KP7ZwLBzWpiCI,24260
101
- tweek/skill_template/SKILL.md,sha256=dLMlJOdUrzJ8hz2R3bcFEjtxCT0xIKMZnX2UQFZDwTs,10309
101
+ tweek/skill_template/SKILL.md,sha256=gBk_Ken77scVYeCs8imm1ASnNLDpBl-C0ufgWrrkQIA,10274
102
102
  tweek/skill_template/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
103
- tweek/skill_template/cli-reference.md,sha256=I9Uj_RgRINW2uYguj4dQ3uGmxzxm83zPQt20XkqlawA,6277
103
+ tweek/skill_template/cli-reference.md,sha256=DdXIEfTPvYn6iybVwA-r3CKkV1Mlx5Ub_sJf_lJrV2k,6913
104
104
  tweek/skill_template/overrides-reference.md,sha256=xlc07wXXsCOrx60wMD7LZ7fn5Z_dhLuj5Mgx04-xGQ0,4509
105
105
  tweek/skill_template/scripts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
106
- tweek/skill_template/scripts/check_installed.py,sha256=tYXZn49EThoQTexD0ehBue5T2qFQEXot2rJqw3T9p0s,5830
106
+ tweek/skill_template/scripts/check_installed.py,sha256=-pMmfgBjdbwb5u2t9rJ0dMBz7MGYgiZM5db3tiNZgO4,5878
107
107
  tweek/skills/__init__.py,sha256=DyTvK8n5Lb-idkJhXCVytpiZjNfWveCtNkSL6o8dxHM,1209
108
108
  tweek/skills/config.py,sha256=I95wK9CBj_UiHwFuxfE8yRl7cmFiqdY0hXfF3BHP0X8,4782
109
109
  tweek/skills/fingerprints.py,sha256=YjPsTxqotzGlyMIgfgewSoNDTLU8_-p9fY_a44LJTjU,6027
@@ -113,10 +113,11 @@ tweek/skills/scanner.py,sha256=PaeZNnwxLTGls2O3hQaDgBhGw9jVJThPjfKCY_05_nI,27574
113
113
  tweek/vault/__init__.py,sha256=L408fjdRYL8-VqLEsyyHSO9PkBDhd_2mPIbrCu53YhM,980
114
114
  tweek/vault/cross_platform.py,sha256=D4UvX_7OpSo8iRx5sc2OUUWQIk8JHhgeFBYk1MbyIj4,8251
115
115
  tweek/vault/keychain.py,sha256=XL18-SUj7HwuqxLXZDViuCH81--KMu68jN9Szn1aeyw,10624
116
- tweek-0.2.1.dist-info/licenses/LICENSE,sha256=rjoDzr1vAf0bsqZglpIyekU5aewIkCk4jHZZDvVI2BE,15269
116
+ tweek-0.3.0.dist-info/licenses/LICENSE,sha256=rjoDzr1vAf0bsqZglpIyekU5aewIkCk4jHZZDvVI2BE,15269
117
+ tweek-0.3.0.dist-info/licenses/NOTICE,sha256=taQokyDes5UTRNEC67G-13VmqvUyTOncrrT33pCcWL0,8729
117
118
  tweek-openclaw-plugin/node_modules/flatted/python/flatted.py,sha256=UYburBDqkySaTfSpntPCUJRxiBGcplusJM7ECX8FEgA,3860
118
- tweek-0.2.1.dist-info/METADATA,sha256=7ahRw8rb7M0OV4xVZpI_5e1MMrk2KZGont3GRymkhmw,11318
119
- tweek-0.2.1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
120
- tweek-0.2.1.dist-info/entry_points.txt,sha256=YXThD6UiF5XQXwqW33sphsvz-Bl4Zm6pm-xq-5wcCYE,1337
121
- tweek-0.2.1.dist-info/top_level.txt,sha256=jtNcCxjoGXN8IBqEVL0F3LHDrZD_B0S-4XF9-Ur7Pbc,28
122
- tweek-0.2.1.dist-info/RECORD,,
119
+ tweek-0.3.0.dist-info/METADATA,sha256=4eLu77u_VjfeqHnZ_-sIXRthm3In7dOHRnGkAaqQy2Y,11889
120
+ tweek-0.3.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
121
+ tweek-0.3.0.dist-info/entry_points.txt,sha256=YXThD6UiF5XQXwqW33sphsvz-Bl4Zm6pm-xq-5wcCYE,1337
122
+ tweek-0.3.0.dist-info/top_level.txt,sha256=jtNcCxjoGXN8IBqEVL0F3LHDrZD_B0S-4XF9-Ur7Pbc,28
123
+ tweek-0.3.0.dist-info/RECORD,,