tweek 0.3.1__py3-none-any.whl → 0.4.1__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.
Files changed (61) hide show
  1. tweek/__init__.py +2 -2
  2. tweek/audit.py +2 -2
  3. tweek/cli.py +78 -6605
  4. tweek/cli_config.py +643 -0
  5. tweek/cli_configure.py +413 -0
  6. tweek/cli_core.py +718 -0
  7. tweek/cli_dry_run.py +390 -0
  8. tweek/cli_helpers.py +316 -0
  9. tweek/cli_install.py +1666 -0
  10. tweek/cli_logs.py +301 -0
  11. tweek/cli_mcp.py +148 -0
  12. tweek/cli_memory.py +343 -0
  13. tweek/cli_plugins.py +748 -0
  14. tweek/cli_protect.py +564 -0
  15. tweek/cli_proxy.py +405 -0
  16. tweek/cli_security.py +236 -0
  17. tweek/cli_skills.py +289 -0
  18. tweek/cli_uninstall.py +551 -0
  19. tweek/cli_vault.py +313 -0
  20. tweek/config/allowed_dirs.yaml +16 -17
  21. tweek/config/families.yaml +4 -1
  22. tweek/config/manager.py +17 -0
  23. tweek/config/patterns.yaml +29 -5
  24. tweek/config/templates/config.yaml.template +212 -0
  25. tweek/config/templates/env.template +45 -0
  26. tweek/config/templates/overrides.yaml.template +121 -0
  27. tweek/config/templates/tweek.yaml.template +20 -0
  28. tweek/config/templates.py +136 -0
  29. tweek/config/tiers.yaml +5 -4
  30. tweek/diagnostics.py +112 -32
  31. tweek/hooks/overrides.py +4 -0
  32. tweek/hooks/post_tool_use.py +46 -1
  33. tweek/hooks/pre_tool_use.py +149 -49
  34. tweek/integrations/openclaw.py +84 -0
  35. tweek/licensing.py +1 -1
  36. tweek/mcp/__init__.py +7 -9
  37. tweek/mcp/clients/chatgpt.py +2 -2
  38. tweek/mcp/clients/claude_desktop.py +2 -2
  39. tweek/mcp/clients/gemini.py +2 -2
  40. tweek/mcp/proxy.py +165 -1
  41. tweek/memory/provenance.py +438 -0
  42. tweek/memory/queries.py +2 -0
  43. tweek/memory/safety.py +23 -4
  44. tweek/memory/schemas.py +1 -0
  45. tweek/memory/store.py +101 -71
  46. tweek/plugins/screening/heuristic_scorer.py +1 -1
  47. tweek/security/integrity.py +77 -0
  48. tweek/security/llm_reviewer.py +170 -74
  49. tweek/security/local_reviewer.py +44 -2
  50. tweek/security/model_registry.py +73 -7
  51. tweek/skill_template/overrides-reference.md +1 -1
  52. tweek/skills/context.py +221 -0
  53. tweek/skills/scanner.py +2 -2
  54. {tweek-0.3.1.dist-info → tweek-0.4.1.dist-info}/METADATA +8 -7
  55. {tweek-0.3.1.dist-info → tweek-0.4.1.dist-info}/RECORD +60 -38
  56. tweek/mcp/server.py +0 -320
  57. {tweek-0.3.1.dist-info → tweek-0.4.1.dist-info}/WHEEL +0 -0
  58. {tweek-0.3.1.dist-info → tweek-0.4.1.dist-info}/entry_points.txt +0 -0
  59. {tweek-0.3.1.dist-info → tweek-0.4.1.dist-info}/licenses/LICENSE +0 -0
  60. {tweek-0.3.1.dist-info → tweek-0.4.1.dist-info}/licenses/NOTICE +0 -0
  61. {tweek-0.3.1.dist-info → tweek-0.4.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,221 @@
1
+ """
2
+ Tweek Skill Context Tracking
3
+
4
+ Detects active skill context from Claude Code's Skill tool invocations.
5
+ When PreToolUse sees tool_name=="Skill", the skill name is extracted from
6
+ tool_input and written to a breadcrumb file. Subsequent tool calls within
7
+ the same session read the breadcrumb to get skill context for tier lookup.
8
+
9
+ This bridges the gap where Claude Code's hook protocol doesn't include
10
+ skill_name: the Skill tool IS a regular tool, so PreToolUse sees it.
11
+
12
+ Security properties:
13
+ - Session-isolated: per-session breadcrumb files (no cross-session leakage)
14
+ - Auto-expiring: 60-second staleness timeout
15
+ - Atomic writes: write-to-temp + os.rename (POSIX atomic)
16
+ - Restricted permissions: 0o600 on breadcrumb files
17
+ - Fail-safe: any error falls to no-context = default tier
18
+ """
19
+
20
+ from __future__ import annotations
21
+
22
+ import json
23
+ import os
24
+ import tempfile
25
+ import time
26
+ from pathlib import Path
27
+ from typing import Optional
28
+
29
+ # Breadcrumb location — per-session files for isolation
30
+ TWEEK_STATE_DIR = Path.home() / ".tweek" / "state"
31
+
32
+ # Breadcrumb expires after 60 seconds of inactivity.
33
+ # Skills typically issue tool calls in rapid succession; 60s is generous
34
+ # while limiting the window for staleness-based attacks.
35
+ STALENESS_TIMEOUT_SECONDS = 60
36
+
37
+ # Maximum age before a per-session breadcrumb file is considered orphaned
38
+ # and eligible for cleanup (1 hour).
39
+ ORPHAN_CLEANUP_SECONDS = 3600
40
+
41
+
42
+ def _breadcrumb_path_for_session(session_id: str, state_dir: Optional[Path] = None) -> Path:
43
+ """Get the breadcrumb file path for a specific session.
44
+
45
+ Uses first 12 chars of session_id to avoid excessively long filenames
46
+ while maintaining sufficient uniqueness.
47
+ """
48
+ prefix = session_id[:12] if session_id else "unknown"
49
+ base = state_dir or TWEEK_STATE_DIR
50
+ return base / f"active_skill_{prefix}.json"
51
+
52
+
53
+ def write_skill_breadcrumb(
54
+ skill_name: str,
55
+ session_id: str,
56
+ *,
57
+ breadcrumb_path: Optional[Path] = None,
58
+ ) -> None:
59
+ """Record the active skill for this session.
60
+
61
+ Called when PreToolUse detects a Skill tool invocation.
62
+ Uses atomic write (temp file + rename) and restricts permissions to 0o600.
63
+
64
+ Args:
65
+ skill_name: The skill being invoked (from tool_input["skill"])
66
+ session_id: Current hook session ID for isolation
67
+ breadcrumb_path: Override for testing (bypasses per-session naming)
68
+ """
69
+ path = breadcrumb_path or _breadcrumb_path_for_session(session_id)
70
+ path.parent.mkdir(parents=True, exist_ok=True)
71
+
72
+ data = {
73
+ "skill": skill_name,
74
+ "session_id": session_id,
75
+ "timestamp": time.time(),
76
+ }
77
+
78
+ # Atomic write: write to temp file, then rename (POSIX atomic)
79
+ fd = None
80
+ tmp_path = None
81
+ try:
82
+ fd, tmp_path = tempfile.mkstemp(
83
+ dir=str(path.parent),
84
+ prefix=".skill_",
85
+ suffix=".tmp",
86
+ )
87
+ os.write(fd, json.dumps(data).encode("utf-8"))
88
+ os.close(fd)
89
+ fd = None # Mark as closed
90
+
91
+ # Restrict permissions before rename (owner read/write only)
92
+ os.chmod(tmp_path, 0o600)
93
+
94
+ # Atomic rename
95
+ os.rename(tmp_path, str(path))
96
+ tmp_path = None # Mark as renamed (don't clean up)
97
+ finally:
98
+ # Clean up on failure
99
+ if fd is not None:
100
+ try:
101
+ os.close(fd)
102
+ except OSError:
103
+ pass
104
+ if tmp_path is not None:
105
+ try:
106
+ os.unlink(tmp_path)
107
+ except OSError:
108
+ pass
109
+
110
+
111
+ def read_skill_context(
112
+ session_id: str,
113
+ *,
114
+ breadcrumb_path: Optional[Path] = None,
115
+ staleness_seconds: float = STALENESS_TIMEOUT_SECONDS,
116
+ ) -> Optional[str]:
117
+ """Read the active skill for the current session, if any.
118
+
119
+ Returns the skill name if a fresh, session-matching breadcrumb exists.
120
+ Returns None if no breadcrumb, wrong session, or stale.
121
+
122
+ Args:
123
+ session_id: Current hook session ID — must match breadcrumb
124
+ breadcrumb_path: Override for testing (bypasses per-session naming)
125
+ staleness_seconds: Max age in seconds before breadcrumb is stale
126
+ """
127
+ path = breadcrumb_path or _breadcrumb_path_for_session(session_id)
128
+
129
+ try:
130
+ if not path.exists():
131
+ return None
132
+
133
+ data = json.loads(path.read_text(encoding="utf-8"))
134
+
135
+ # Session isolation: only match same session
136
+ if data.get("session_id") != session_id:
137
+ return None
138
+
139
+ # Staleness check
140
+ ts = data.get("timestamp", 0)
141
+ if (time.time() - ts) > staleness_seconds:
142
+ # Expired — clean up
143
+ _clear_breadcrumb(path)
144
+ return None
145
+
146
+ return data.get("skill")
147
+
148
+ except (json.JSONDecodeError, OSError, KeyError):
149
+ return None
150
+
151
+
152
+ def clear_skill_breadcrumb(
153
+ session_id: Optional[str] = None,
154
+ *,
155
+ breadcrumb_path: Optional[Path] = None,
156
+ ) -> None:
157
+ """Clear the active skill breadcrumb.
158
+
159
+ Called on session end or UserPromptSubmit if needed.
160
+
161
+ Args:
162
+ session_id: If provided, clears the per-session breadcrumb.
163
+ breadcrumb_path: Override for testing.
164
+ """
165
+ if breadcrumb_path:
166
+ _clear_breadcrumb(breadcrumb_path)
167
+ elif session_id:
168
+ _clear_breadcrumb(_breadcrumb_path_for_session(session_id))
169
+
170
+
171
+ def cleanup_orphaned_breadcrumbs(
172
+ *,
173
+ state_dir: Optional[Path] = None,
174
+ max_age_seconds: float = ORPHAN_CLEANUP_SECONDS,
175
+ ) -> int:
176
+ """Remove breadcrumb files older than max_age_seconds.
177
+
178
+ Called periodically to prevent accumulation of stale session files.
179
+ Returns the number of files cleaned up.
180
+ """
181
+ base = state_dir or TWEEK_STATE_DIR
182
+ cleaned = 0
183
+
184
+ try:
185
+ if not base.exists():
186
+ return 0
187
+
188
+ now = time.time()
189
+ for f in base.glob("active_skill_*.json"):
190
+ try:
191
+ age = now - f.stat().st_mtime
192
+ if age > max_age_seconds:
193
+ f.unlink(missing_ok=True)
194
+ cleaned += 1
195
+ except OSError:
196
+ continue
197
+ except OSError:
198
+ pass
199
+
200
+ return cleaned
201
+
202
+
203
+ def _clear_breadcrumb(path: Path) -> None:
204
+ """Remove the breadcrumb file silently."""
205
+ try:
206
+ path.unlink(missing_ok=True)
207
+ except OSError:
208
+ pass
209
+
210
+
211
+ def extract_skill_from_tool_input(tool_input: dict) -> Optional[str]:
212
+ """Extract the skill name from a Skill tool's tool_input.
213
+
214
+ The Skill tool sends: {"skill": "commit", "args": "..."}
215
+
216
+ Returns the skill name or None if not a valid Skill invocation.
217
+ """
218
+ skill = tool_input.get("skill")
219
+ if isinstance(skill, str) and skill.strip():
220
+ return skill.strip()
221
+ return None
tweek/skills/scanner.py CHANGED
@@ -6,7 +6,7 @@ installation. Reuses existing Tweek infrastructure where possible.
6
6
 
7
7
  Layers:
8
8
  1. Structure Validation — file types, size, depth, symlinks
9
- 2. Pattern Matching — 259 regex patterns (reuses audit.py)
9
+ 2. Pattern Matching — 262 regex patterns (reuses audit.py)
10
10
  3. Secret Scanning — credential detection (reuses secret_scanner.py)
11
11
  4. AST Analysis — forbidden imports/calls (reuses git_security.py)
12
12
  5. Prompt Injection Scan — skill-specific instruction injection patterns
@@ -349,7 +349,7 @@ class SkillScanner:
349
349
  def _scan_patterns(
350
350
  self, skill_dir: Path, text_files: List[Path]
351
351
  ) -> ScanLayerResult:
352
- """Run 259 regex patterns against all text files."""
352
+ """Run 262 regex patterns against all text files."""
353
353
  result = ScanLayerResult(layer_name="patterns", passed=True)
354
354
 
355
355
  try:
@@ -1,13 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tweek
3
- Version: 0.3.1
3
+ Version: 0.4.1
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
7
7
  Project-URL: Homepage, https://gettweek.com
8
8
  Project-URL: Repository, https://github.com/gettweek/tweek
9
9
  Project-URL: Issues, https://github.com/gettweek/tweek/issues
10
- Keywords: claude,security,sandbox,ai,llm,tweek,claude-code,prompt-injection,mcp,credential-theft
10
+ Keywords: claude,security,dry-run,ai,llm,tweek,claude-code,prompt-injection,mcp,credential-theft
11
11
  Classifier: Development Status :: 4 - Beta
12
12
  Classifier: Intended Audience :: Developers
13
13
  Classifier: Operating System :: MacOS :: MacOS X
@@ -45,6 +45,7 @@ Provides-Extra: dev
45
45
  Requires-Dist: pytest>=7.0; extra == "dev"
46
46
  Requires-Dist: pytest-cov>=4.0; extra == "dev"
47
47
  Requires-Dist: pytest-xdist>=3.5.0; extra == "dev"
48
+ Requires-Dist: pytest-timeout>=2.2.0; extra == "dev"
48
49
  Requires-Dist: hypothesis>=6.98.0; extra == "dev"
49
50
  Requires-Dist: black>=23.0; extra == "dev"
50
51
  Requires-Dist: ruff>=0.1.0; extra == "dev"
@@ -124,7 +125,7 @@ tweek proxy setup # Cursor, Windsurf, Continue.dev (HTTP p
124
125
  tweek doctor
125
126
  ```
126
127
 
127
- That's it. Tweek auto-detects your tools, applies all 259 attack patterns across 6 defense layers, and runs 100% locally. Your code never leaves your machine.
128
+ That's it. Tweek auto-detects your tools, applies all 262 attack patterns across 6 defense layers, and runs 100% locally. Your code never leaves your machine.
128
129
 
129
130
  ---
130
131
 
@@ -166,7 +167,7 @@ Turn 3: cat ~/.ssh/id_rsa → BLOCKED: path_escalation anomaly
166
167
 
167
168
  **Response injection** — Malicious instructions hidden in tool responses are caught at ingestion.
168
169
 
169
- See the full [Attack Patterns Reference](docs/ATTACK_PATTERNS.md) for all 259 patterns across 11 categories.
170
+ See the full [Attack Patterns Reference](docs/ATTACK_PATTERNS.md) for all 262 patterns across 11 categories.
170
171
 
171
172
  ---
172
173
 
@@ -217,7 +218,7 @@ Every tool call passes through six independent screening layers. An attacker wou
217
218
 
218
219
  | Layer | What It Does |
219
220
  |-------|-------------|
220
- | **1. Pattern Matching** | 259 regex signatures catch known credential theft, exfiltration, and injection attacks instantly |
221
+ | **1. Pattern Matching** | 262 regex signatures catch known credential theft, exfiltration, and injection attacks instantly |
221
222
  | **2. Rate Limiting** | Detects burst attacks, automated probing, and resource theft sequences |
222
223
  | **3. Local Prompt Injection AI** | Custom-trained AI models built specifically to classify and detect prompt injection. Run 100% on your machine — no API calls, no cloud, no latency. Small enough to be fast, accurate enough to catch what regex can't. |
223
224
  | **4. Session Tracking** | Behavioral analysis across turns detects multi-step attacks that look innocent individually |
@@ -235,7 +236,7 @@ See [Defense Layers](docs/DEFENSE_LAYERS.md) for the deep dive and [Architecture
235
236
  | [Full Feature List](docs/FEATURES.md) | Complete feature inventory |
236
237
  | [Architecture](docs/ARCHITECTURE.md) | System design and interception layers |
237
238
  | [Defense Layers](docs/DEFENSE_LAYERS.md) | Screening pipeline deep dive |
238
- | [Attack Patterns](docs/ATTACK_PATTERNS.md) | Full 259-pattern library reference |
239
+ | [Attack Patterns](docs/ATTACK_PATTERNS.md) | Full 262-pattern library reference |
239
240
  | [Configuration](docs/CONFIGURATION.md) | Config files, tiers, and presets |
240
241
  | [CLI Reference](docs/CLI_REFERENCE.md) | All commands, flags, and examples |
241
242
  | [MCP Integration](docs/MCP_INTEGRATION.md) | MCP proxy and gateway setup |
@@ -244,7 +245,7 @@ See [Defense Layers](docs/DEFENSE_LAYERS.md) for the deep dive and [Architecture
244
245
  | [Credential Vault](docs/VAULT.md) | Vault setup and migration |
245
246
  | [Plugins](docs/PLUGINS.md) | Plugin development and registry |
246
247
  | [Logging](docs/LOGGING.md) | Event logging and audit trail |
247
- | [Sandbox](docs/SANDBOX.md) | Sandbox preview configuration |
248
+ | [Dry-Run](docs/DRY_RUN.md) | Dry-run preview configuration |
248
249
  | [Tweek vs. Claude Code](docs/COMPARISON.md) | Feature comparison with native security |
249
250
  | [Troubleshooting](docs/TROUBLESHOOTING.md) | Common issues and fixes |
250
251
 
@@ -1,46 +1,66 @@
1
- tweek/__init__.py,sha256=NppVIy7NWIJrgFbWfAVveJtg-UdwqA9ux98hciWBeLM,360
1
+ tweek/__init__.py,sha256=Yok2ar0ngfNDc-NyYeDnL5rfwdj_htDZ0SX9sUqD1lY,359
2
2
  tweek/_keygen.py,sha256=UapwIKNSwaRWdqHoJoF3hmKuiux6aIiFGe8WVskTbI8,1286
3
- tweek/audit.py,sha256=OmCUagbx_fkCorcrZt2ebTtDm-rr4fRKkZpxZdvZens,8868
4
- tweek/cli.py,sha256=Ad54k7bDws9Eg7z3oeEVR85Ni9DQz72JJVUFC1WV_zA,256803
5
- tweek/cli_helpers.py,sha256=Q2NTOkyRTOIPNLMqY2jA5_tuzDPksAGwGXYPRK3bzoY,5538
3
+ tweek/audit.py,sha256=AzjIpy6Jc-WzTrda9lb3nZbyaR_SDWUxo04pObJP2MQ,8868
4
+ tweek/cli.py,sha256=OOZrpcrwDGbmaHxIyvBw7MoVSlEdrFNAgIwWHI56p5M,2976
5
+ tweek/cli_config.py,sha256=rSQTkw0JAqm6w02Ah2_hiJ-wIxhnrjTgvFuw2A39qfs,24525
6
+ tweek/cli_configure.py,sha256=fHm2sWxjUWFu7ulup7T-zrQ3LYiYg_1Vf-m3E5hoKd8,14603
7
+ tweek/cli_core.py,sha256=0mgcJ_ZduuloOhyIn4ecTHROMtz_pDcAdlew-E45DPk,26843
8
+ tweek/cli_dry_run.py,sha256=8DBx3qKAZHY8VA6MsbsGBs6EyDGFxKsrtmuNaHJ22C8,14335
9
+ tweek/cli_helpers.py,sha256=_8aVj8e67MrP61ao7_AaEQSi9AfJQxW3eNvnjbSWT7g,16347
10
+ tweek/cli_install.py,sha256=5AaxZmOpDk9y8Ursy_CaU8JYn4mtMPWNtIhWNpb6an8,74111
11
+ tweek/cli_logs.py,sha256=uoJBKb85EYcIQnXxNfh15w235u9UWP1he-RlwnITWuA,10776
12
+ tweek/cli_mcp.py,sha256=mIKTUqTKLlVYc9054LdjfL-maiVAabPFkb_sLtoS0Gk,4787
13
+ tweek/cli_memory.py,sha256=Sw2TOt7RGsXBoH_q13bQjUK3WyvOy49bXefZ7atoaCY,11895
6
14
  tweek/cli_model.py,sha256=iMZStFqA0Nqyzm4rxSbhD4v-AqcO6h5NI72AR7cldoY,12853
7
- tweek/diagnostics.py,sha256=KbtXQH8QrRBoyIFWumL6q9--aQQdR0tUo2GzjMhwpII,24601
8
- tweek/licensing.py,sha256=wYN8wBYVCp1RbAi_sWeF7gKKBSU116ncX3tnZawYUpQ,11703
15
+ tweek/cli_plugins.py,sha256=3u8oJ0Wxb50taTc6Xofyy9voaPi62ozEfcP93VBY1oA,30059
16
+ tweek/cli_protect.py,sha256=q6VhmR2vnozdybUXJEnaofx0FVZSoQq39gWVh5xmjnc,22398
17
+ tweek/cli_proxy.py,sha256=J63CuL0bg2UVHbdavDgIcqiC1C8JS0kNG8pqHEAx9mw,14289
18
+ tweek/cli_security.py,sha256=FpPOY0YsSY5kOc9aNy8QBi9h4fpmQ7wiX3cKtRYmLzg,8482
19
+ tweek/cli_skills.py,sha256=N2D184i5gajKjrLdQuWxhdiXWGiE4NGCvPahMDZvliI,9045
20
+ tweek/cli_uninstall.py,sha256=sRDbtYxbJ9fnt-fBypEZOCR_UdTTo09RozOI_Xlo1Dc,21463
21
+ tweek/cli_vault.py,sha256=j2HUurcOCOUgObfnSiMrcJQ8k3BUs1aD-YqCNZzp98I,11457
22
+ tweek/diagnostics.py,sha256=aYtdLeTulbYF3KzIt-oqTDucYNJrBL85rsPXlPM07bg,27487
23
+ tweek/licensing.py,sha256=_t_X3wgd6F0VEoLrOags-AE2k3IZXw3WhWXFuQU4UYA,11703
9
24
  tweek/config/__init__.py,sha256=ENwimeLZd2gSJXpkASMY45hbMUDn2RwM-Zl_RMvpCbQ,772
10
- tweek/config/allowed_dirs.yaml,sha256=dMF_DqKgQThzkdIEoXzDBfAjbopGrk0HTkiM7ENmBaU,788
11
- tweek/config/families.yaml,sha256=jkNO0UsmX3MFlTKC9Or3p8_MlD3ZtHM0SrQIYFqx9i8,18212
12
- tweek/config/manager.py,sha256=Jk9l_UJM9e5_fxTvWFXrU0677u9HCttmunahp36woBE,40591
25
+ tweek/config/allowed_dirs.yaml,sha256=eHmX3QEJ-LBVdwH5tQBFeTFnlRewLvRG2jLJwBh3lOY,841
26
+ tweek/config/families.yaml,sha256=QAQD-6pnCOdiNXpXUPyeAKkYMlRcQmUpCMORkDeGA1Y,18348
27
+ tweek/config/manager.py,sha256=cs77QiAShd91RTMGxKgWUmz7qluRfQq0PogCpfxUAPA,41256
13
28
  tweek/config/models.py,sha256=RbVjC2pxnkrBKanS6QGDrHwPVkmss5ouG_dqAHf_C3Q,10018
14
- tweek/config/patterns.yaml,sha256=hu0lphSN0i_bY8kla65bTaBEQR8phhrb3BLC1KprMLw,85376
15
- tweek/config/tiers.yaml,sha256=9hIXQ9izVKXd8ptoCsQiBo2r_XY8RvIk7VWrhWggkbc,10191
29
+ tweek/config/patterns.yaml,sha256=5HHLGGCb0KmEAEo9KPc3eja0ykYjy53x66D-u7WY6No,86749
30
+ tweek/config/templates.py,sha256=aIGD3bDfx-J6vVBKQTNZr3IIh-O9yjcddRB8l1BxZPs,4440
31
+ tweek/config/tiers.yaml,sha256=gVQ80iOqirHzlJI9YEzpi6alqqmNtNNZh1nA4DQYPPs,10298
32
+ tweek/config/templates/config.yaml.template,sha256=i3QGrIuNjF9kqJNoMJmr62mja_8Rh9gMsc-YM6YzNSE,9120
33
+ tweek/config/templates/env.template,sha256=MCnGhE6WHU5Bk9HO6dkPfBtkur2QyK69cxzHUKBWPzs,1456
34
+ tweek/config/templates/overrides.yaml.template,sha256=T9CjpPayth_1bDH-iL0mSdTTMi27GmC8cNxnBaxRNWk,4170
35
+ tweek/config/templates/tweek.yaml.template,sha256=jdSE7e3JeS9vOWEGWK2VCr66HLxSSFpOkNNUcZQQrkg,777
16
36
  tweek/hooks/__init__.py,sha256=GcgDjPdhZayxmyZ4-GfBa-ISARNtt9087RsuprRq2-s,54
17
37
  tweek/hooks/break_glass.py,sha256=GNMhCtLWPylNMlQ5QfsoUkEjgIT1Uk1Ik7HvRWeE5N8,4636
18
38
  tweek/hooks/feedback.py,sha256=uuA4opHYyBHC5sElBz-fr2Je3cg2DAv-aRHvETZcag0,6555
19
- tweek/hooks/overrides.py,sha256=1Yw_NPpZMvcFG_uyNY-ouBKSSomnxOptRedSjzkkhmE,18635
20
- tweek/hooks/post_tool_use.py,sha256=22ugZdlZn2Q0eUcUucelrF18N7mCgaC_agb7kZT51Ww,17195
21
- tweek/hooks/pre_tool_use.py,sha256=70XbonRSGh8rYpDlI4R_Z5Ug2LwU4iLyLsS87I5xlqc,71743
39
+ tweek/hooks/overrides.py,sha256=9WfTfh5R_IstoR7SKlEIq-mgRbUTnnIiJYSTDV3_ekI,18762
40
+ tweek/hooks/post_tool_use.py,sha256=NVOgcd7wn5BL5TYQiTwvMFxy_68dWp5z6FoRYXypfaU,19195
41
+ tweek/hooks/pre_tool_use.py,sha256=qMGaRamkBUEXZFTYdiqFgmxLiTeH2ON4FHvcGKKxazg,76765
22
42
  tweek/integrations/__init__.py,sha256=sl7wFwbygmnruugX4bO2EUjoXxBlCpzTKbj-1zHuUPg,78
23
- tweek/integrations/openclaw.py,sha256=jX99__ODGI7Cq6gclSTK2pI5lsI7UGh5_iCHmq1R8RY,13798
43
+ tweek/integrations/openclaw.py,sha256=uSP_FPG5BFnk8o6Z-1PlXB8od4OX0p0nGN8xRof9XsE,16955
24
44
  tweek/integrations/openclaw_server.py,sha256=Ah7wxsxKE2lQmIdlrFINvt5jW9U_bqqERfG3X2N5Aps,12533
25
45
  tweek/logging/__init__.py,sha256=-HUdhMuDlGUwG3v2KE7xH7cClOSQ5kZIDcVO4cybVLI,228
26
46
  tweek/logging/bundle.py,sha256=eDP0Is-hna18goaHmvexXpoNAlFhmWoMG-STTLZ19_w,11911
27
47
  tweek/logging/json_logger.py,sha256=zXOsFAufj3MF0TboM5zSS7V8uNBDJea7YkJHR-uQgBA,4698
28
48
  tweek/logging/security_log.py,sha256=BwHDdrN0VCpqssStvsZdASFnyxVpANCq9xiSkFsEFFk,28486
29
- tweek/mcp/__init__.py,sha256=AOFDrzDfjOvICMcN15Hz-iNCT0Kf6oyUBB-iNEW5Vr4,791
49
+ tweek/mcp/__init__.py,sha256=UbBOrb15XrVIcyKoNLXos2N63Xw2_EeyKnaALkjfnME,610
30
50
  tweek/mcp/approval.py,sha256=WIFQi4ryXEFtgQyzQIshwgP5h_Th7Cxepx9NIhf2o_4,17885
31
51
  tweek/mcp/approval_cli.py,sha256=8WtmJF7KTLmdEF5wHqENaUJUzKEQej4CjRtFey4RcGg,11281
32
- tweek/mcp/proxy.py,sha256=0p5OEaRsFuNRcGR3rnqprkPjTdSSYgrsU_XXQiFPS8c,24819
52
+ tweek/mcp/proxy.py,sha256=aQb7FxNq1QvllL82rLAd4fyZUu5POpDPLByvRdN1bng,31073
33
53
  tweek/mcp/screening.py,sha256=ax5TK8ZSXb9uo5DFx3mxiYrBKjDBP0cTLNhA05TXb80,5421
34
- tweek/mcp/server.py,sha256=3pF3piXUNtIf2-SUJPCjGZPD42esg2KFsVXpaBXrq3E,10901
35
54
  tweek/mcp/clients/__init__.py,sha256=46tdDJRG_POVhRWLxzgeU2FjOoBKquCNf4jnHQ_FUn0,900
36
- tweek/mcp/clients/chatgpt.py,sha256=M7Mu-F1On47ijNlRj3KRb0S7tN3xkK7ZCjutAYoe8bw,3739
37
- tweek/mcp/clients/claude_desktop.py,sha256=ujkZm26l0QMlK1ectgae7VlJsl2tcOXhrWCsjyFvsdc,6624
38
- tweek/mcp/clients/gemini.py,sha256=2eKkX02gb8wuQoBeN6oo4DVmvn1R7D2mt8KGDdUFvQA,5653
55
+ tweek/mcp/clients/chatgpt.py,sha256=9nX-HODn-M9dR-39l_ltvHCjdiZfKs2i0dkb7-tSgdw,3739
56
+ tweek/mcp/clients/claude_desktop.py,sha256=c92vsomu0Ko5rqnS0157ziIpiVTO_BjaTKBxFzduyNw,6624
57
+ tweek/mcp/clients/gemini.py,sha256=IFGClXc2ytrheah0Ja7vrMLVDEhORcUdQWnEo29BOVE,5653
39
58
  tweek/memory/__init__.py,sha256=rUe3cc-Nh-8k7kEMHzF8ao2QRt-tnI9kZQAtU8GQT5M,843
40
- tweek/memory/queries.py,sha256=SdpO9VEmvuIuribJRb7W9JO_dvVC6fSdzAonaQ9kgbg,6640
41
- tweek/memory/safety.py,sha256=9nahGB5HGnOrA92X72WvcjAu8f6yTv5UE1uYk19_CBw,4586
42
- tweek/memory/schemas.py,sha256=-yTBhenL5x1w5FLiCFXVhi7ciROf5oPWgTwdz3tVslY,2045
43
- tweek/memory/store.py,sha256=d1RAgeDjRvmH6DgmQ8SopDw81K8nUxs3fNlN4-0awAc,35350
59
+ tweek/memory/provenance.py,sha256=zuVHRI9Krj4-YCEj-OJ_4P7xnmAHDelIyrN34446fhw,15628
60
+ tweek/memory/queries.py,sha256=MsUTMOai_iyVSfAmiRFcb_-E9KF2kah1WdeXOa27u-A,6712
61
+ tweek/memory/safety.py,sha256=Mv9R2bQxX2TcitIsgugY7gZmaWjxEahTyVTRTTr1ePA,5416
62
+ tweek/memory/schemas.py,sha256=WD2BIXgEYdG1rjn8MNNS1UWxc2x9bZ_7k736BkJERZg,2125
63
+ tweek/memory/store.py,sha256=Z9MwVsWkz76SncSwxaYmWT3uU4btq4CM-2JIuDkS744,36705
44
64
  tweek/platform/__init__.py,sha256=jIwiwsMU297T02JOymjAdvk7QheEJxgDspueV38pJJE,3757
45
65
  tweek/plugins/__init__.py,sha256=u2dsiOhUE2WbYArjoeyWbaaO99J0aZJU_Z_X83OzVWw,28437
46
66
  tweek/plugins/base.py,sha256=dcx-qjaYE7Dwr36JRNWQaQ1xaDZgb6-T3CTP45j3A24,33445
@@ -70,7 +90,7 @@ tweek/plugins/providers/bedrock.py,sha256=ADIdO7Kpz-kNq78Mq1pQpt8rfX9OIAR3NaMGiA
70
90
  tweek/plugins/providers/google.py,sha256=2wIt-lKXGb_vRcEz-_2zLHTyRdT_VFd3RYpEs_Vuxj0,6033
71
91
  tweek/plugins/providers/openai.py,sha256=LK3_4UIgj1XBORA2MTEI88DID67_9nXY1i8rbe3Yem0,7522
72
92
  tweek/plugins/screening/__init__.py,sha256=KijMffjrD35tbz0RBW4fb8elt36tdrNvlKBVmyeH-OA,1214
73
- tweek/plugins/screening/heuristic_scorer.py,sha256=emTYUT49-GJZhNc3wOZxjeOxJz8u7-GC7c8AVFPT7n8,17193
93
+ tweek/plugins/screening/heuristic_scorer.py,sha256=CuXR_KEoRbn9nRMdNbjzmA00WvBkp31tQTuS5E2t_sQ,17193
74
94
  tweek/plugins/screening/llm_reviewer.py,sha256=DJv4bd5iu0aXtfUyuQ5yb6UTKnyPaY0NW43JraiE90o,5135
75
95
  tweek/plugins/screening/local_model_reviewer.py,sha256=SCQDXvd5cq_w6IQP_G3RzOVDy6W2Xco0b4lKeYd14-0,5010
76
96
  tweek/plugins/screening/pattern_matcher.py,sha256=Zto8ZAJenZoN605LfHvoyNLzqYtJqJg02rH7GaAvPoo,8673
@@ -91,34 +111,36 @@ tweek/sandbox/registry.py,sha256=ZZDQYeJMNAJ0FrFEayo1KyC5r3qXSBx6Tu-JcXIMjtI,506
91
111
  tweek/screening/__init__.py,sha256=-QKzhN8TNqEOrooPunbQl_f6133LOXAszmiKyv8V07I,352
92
112
  tweek/screening/context.py,sha256=iZeD6-Fm7dNs5wlIu15MlMbIPzeTX_Pe0DUkK5xHpQ0,3030
93
113
  tweek/security/__init__.py,sha256=2qkoxVHzWeHdVWYHRYZG479Qpfodl6jNCQu_Wc3i1vM,901
114
+ tweek/security/integrity.py,sha256=QMW5Zu5PaZHC5DLwumnIq7CUOw-iqs_7AMlijLonXj4,2689
94
115
  tweek/security/language.py,sha256=690g63NoeKjwxPG0d38USa1w30QtsAohiT2SXBv-ON4,9128
95
- tweek/security/llm_reviewer.py,sha256=66DSIY1BKXWR5tamL85RpPwN6ihfCQ9PAbmXtwUoM14,49220
116
+ tweek/security/llm_reviewer.py,sha256=NnelRwC6ie_KzxV_2MYjuVPaWUVf61QN7ORuKSM5sVY,53335
96
117
  tweek/security/local_model.py,sha256=fqWQOSiAcWVIM1zzy6SosXVh9hNHJbLRzTJPy9I3sFs,10451
97
- tweek/security/local_reviewer.py,sha256=-kHWDmGnMH13cSv_7DiH4n7ZTZ3uqWZoPzQgYKQKwR0,4987
98
- tweek/security/model_registry.py,sha256=XscpZcWaaJwHldX2T9C1T1zSvJ3lm0aSW4nIhwRpUzc,11022
118
+ tweek/security/local_reviewer.py,sha256=0BzFx8U42KucBL14rpUbXZ8zxsu9ALHGhVosVcj0uh0,6890
119
+ tweek/security/model_registry.py,sha256=zi0mYyTzWc6BL2W7Kd1gCLNti0N8OygKpwL94Re8Kzw,13795
99
120
  tweek/security/rate_limiter.py,sha256=bY8VIkQ-wCbNOYTLwD4MsMBoHk59zPWeZCkuE8Zntm8,24185
100
121
  tweek/security/secret_scanner.py,sha256=G-bbMwsAJD197BEOnZJdn_qphS4RNPK_wpLfkpiLuFU,18774
101
122
  tweek/security/session_analyzer.py,sha256=-Ylp583VZ_YJRkN5JZrYpaK1sVbiM6KP7ZwLBzWpiCI,24260
102
123
  tweek/skill_template/SKILL.md,sha256=gBk_Ken77scVYeCs8imm1ASnNLDpBl-C0ufgWrrkQIA,10274
103
124
  tweek/skill_template/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
104
125
  tweek/skill_template/cli-reference.md,sha256=DdXIEfTPvYn6iybVwA-r3CKkV1Mlx5Ub_sJf_lJrV2k,6913
105
- tweek/skill_template/overrides-reference.md,sha256=xlc07wXXsCOrx60wMD7LZ7fn5Z_dhLuj5Mgx04-xGQ0,4509
126
+ tweek/skill_template/overrides-reference.md,sha256=xmTIdQ_Pe0FUIhEGkUniO1rxWzsubs-XULNBElYdRlA,4509
106
127
  tweek/skill_template/scripts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
107
128
  tweek/skill_template/scripts/check_installed.py,sha256=-pMmfgBjdbwb5u2t9rJ0dMBz7MGYgiZM5db3tiNZgO4,5878
108
129
  tweek/skills/__init__.py,sha256=DyTvK8n5Lb-idkJhXCVytpiZjNfWveCtNkSL6o8dxHM,1209
109
130
  tweek/skills/config.py,sha256=I95wK9CBj_UiHwFuxfE8yRl7cmFiqdY0hXfF3BHP0X8,4782
131
+ tweek/skills/context.py,sha256=15wn3wh_m4n954tsWtf4p8kBdtFmwN18TxPzOaGfGlc,6672
110
132
  tweek/skills/fingerprints.py,sha256=YjPsTxqotzGlyMIgfgewSoNDTLU8_-p9fY_a44LJTjU,6027
111
133
  tweek/skills/guard.py,sha256=1g3QVFwtW2T04PPCouAAEPxgoweVGEld0WL9eCE80js,8294
112
134
  tweek/skills/isolation.py,sha256=AmGwzD8xh70HL4f5aIrvYGm_ug1hHwu8tZXSAnsKiJk,16547
113
- tweek/skills/scanner.py,sha256=PaeZNnwxLTGls2O3hQaDgBhGw9jVJThPjfKCY_05_nI,27574
135
+ tweek/skills/scanner.py,sha256=YlH-yg3_JuwmBvmnpqA4PVfWyNBHaPSjBo6d9Ncuh8k,27574
114
136
  tweek/vault/__init__.py,sha256=L408fjdRYL8-VqLEsyyHSO9PkBDhd_2mPIbrCu53YhM,980
115
137
  tweek/vault/cross_platform.py,sha256=D4UvX_7OpSo8iRx5sc2OUUWQIk8JHhgeFBYk1MbyIj4,8251
116
138
  tweek/vault/keychain.py,sha256=XL18-SUj7HwuqxLXZDViuCH81--KMu68jN9Szn1aeyw,10624
117
- tweek-0.3.1.dist-info/licenses/LICENSE,sha256=rjoDzr1vAf0bsqZglpIyekU5aewIkCk4jHZZDvVI2BE,15269
118
- tweek-0.3.1.dist-info/licenses/NOTICE,sha256=taQokyDes5UTRNEC67G-13VmqvUyTOncrrT33pCcWL0,8729
139
+ tweek-0.4.1.dist-info/licenses/LICENSE,sha256=rjoDzr1vAf0bsqZglpIyekU5aewIkCk4jHZZDvVI2BE,15269
140
+ tweek-0.4.1.dist-info/licenses/NOTICE,sha256=taQokyDes5UTRNEC67G-13VmqvUyTOncrrT33pCcWL0,8729
119
141
  tweek-openclaw-plugin/node_modules/flatted/python/flatted.py,sha256=UYburBDqkySaTfSpntPCUJRxiBGcplusJM7ECX8FEgA,3860
120
- tweek-0.3.1.dist-info/METADATA,sha256=iR7qpsuY7fLnF2DO8OWFrqUTE2vuDv3_VNMWddDIZMU,11939
121
- tweek-0.3.1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
122
- tweek-0.3.1.dist-info/entry_points.txt,sha256=YXThD6UiF5XQXwqW33sphsvz-Bl4Zm6pm-xq-5wcCYE,1337
123
- tweek-0.3.1.dist-info/top_level.txt,sha256=jtNcCxjoGXN8IBqEVL0F3LHDrZD_B0S-4XF9-Ur7Pbc,28
124
- tweek-0.3.1.dist-info/RECORD,,
142
+ tweek-0.4.1.dist-info/METADATA,sha256=0yNrHwETKn3gL-nzeTgoFJiDkbMJPNjp7IpJOUyqKWA,11992
143
+ tweek-0.4.1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
144
+ tweek-0.4.1.dist-info/entry_points.txt,sha256=YXThD6UiF5XQXwqW33sphsvz-Bl4Zm6pm-xq-5wcCYE,1337
145
+ tweek-0.4.1.dist-info/top_level.txt,sha256=jtNcCxjoGXN8IBqEVL0F3LHDrZD_B0S-4XF9-Ur7Pbc,28
146
+ tweek-0.4.1.dist-info/RECORD,,