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.
- tweek/__init__.py +2 -2
- tweek/audit.py +2 -2
- tweek/cli.py +78 -6605
- tweek/cli_config.py +643 -0
- tweek/cli_configure.py +413 -0
- tweek/cli_core.py +718 -0
- tweek/cli_dry_run.py +390 -0
- tweek/cli_helpers.py +316 -0
- tweek/cli_install.py +1666 -0
- tweek/cli_logs.py +301 -0
- tweek/cli_mcp.py +148 -0
- tweek/cli_memory.py +343 -0
- tweek/cli_plugins.py +748 -0
- tweek/cli_protect.py +564 -0
- tweek/cli_proxy.py +405 -0
- tweek/cli_security.py +236 -0
- tweek/cli_skills.py +289 -0
- tweek/cli_uninstall.py +551 -0
- tweek/cli_vault.py +313 -0
- tweek/config/allowed_dirs.yaml +16 -17
- tweek/config/families.yaml +4 -1
- tweek/config/manager.py +17 -0
- tweek/config/patterns.yaml +29 -5
- tweek/config/templates/config.yaml.template +212 -0
- tweek/config/templates/env.template +45 -0
- tweek/config/templates/overrides.yaml.template +121 -0
- tweek/config/templates/tweek.yaml.template +20 -0
- tweek/config/templates.py +136 -0
- tweek/config/tiers.yaml +5 -4
- tweek/diagnostics.py +112 -32
- tweek/hooks/overrides.py +4 -0
- tweek/hooks/post_tool_use.py +46 -1
- tweek/hooks/pre_tool_use.py +149 -49
- tweek/integrations/openclaw.py +84 -0
- tweek/licensing.py +1 -1
- tweek/mcp/__init__.py +7 -9
- tweek/mcp/clients/chatgpt.py +2 -2
- tweek/mcp/clients/claude_desktop.py +2 -2
- tweek/mcp/clients/gemini.py +2 -2
- tweek/mcp/proxy.py +165 -1
- tweek/memory/provenance.py +438 -0
- tweek/memory/queries.py +2 -0
- tweek/memory/safety.py +23 -4
- tweek/memory/schemas.py +1 -0
- tweek/memory/store.py +101 -71
- tweek/plugins/screening/heuristic_scorer.py +1 -1
- tweek/security/integrity.py +77 -0
- tweek/security/llm_reviewer.py +170 -74
- tweek/security/local_reviewer.py +44 -2
- tweek/security/model_registry.py +73 -7
- tweek/skill_template/overrides-reference.md +1 -1
- tweek/skills/context.py +221 -0
- tweek/skills/scanner.py +2 -2
- {tweek-0.3.1.dist-info → tweek-0.4.1.dist-info}/METADATA +8 -7
- {tweek-0.3.1.dist-info → tweek-0.4.1.dist-info}/RECORD +60 -38
- tweek/mcp/server.py +0 -320
- {tweek-0.3.1.dist-info → tweek-0.4.1.dist-info}/WHEEL +0 -0
- {tweek-0.3.1.dist-info → tweek-0.4.1.dist-info}/entry_points.txt +0 -0
- {tweek-0.3.1.dist-info → tweek-0.4.1.dist-info}/licenses/LICENSE +0 -0
- {tweek-0.3.1.dist-info → tweek-0.4.1.dist-info}/licenses/NOTICE +0 -0
- {tweek-0.3.1.dist-info → tweek-0.4.1.dist-info}/top_level.txt +0 -0
tweek/skills/context.py
ADDED
|
@@ -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 —
|
|
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
|
|
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
|
+
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,
|
|
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
|
|
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
|
|
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** |
|
|
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
|
|
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
|
-
| [
|
|
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=
|
|
1
|
+
tweek/__init__.py,sha256=Yok2ar0ngfNDc-NyYeDnL5rfwdj_htDZ0SX9sUqD1lY,359
|
|
2
2
|
tweek/_keygen.py,sha256=UapwIKNSwaRWdqHoJoF3hmKuiux6aIiFGe8WVskTbI8,1286
|
|
3
|
-
tweek/audit.py,sha256=
|
|
4
|
-
tweek/cli.py,sha256=
|
|
5
|
-
tweek/
|
|
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/
|
|
8
|
-
tweek/
|
|
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=
|
|
11
|
-
tweek/config/families.yaml,sha256=
|
|
12
|
-
tweek/config/manager.py,sha256=
|
|
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=
|
|
15
|
-
tweek/config/
|
|
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=
|
|
20
|
-
tweek/hooks/post_tool_use.py,sha256=
|
|
21
|
-
tweek/hooks/pre_tool_use.py,sha256=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
37
|
-
tweek/mcp/clients/claude_desktop.py,sha256=
|
|
38
|
-
tweek/mcp/clients/gemini.py,sha256=
|
|
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/
|
|
41
|
-
tweek/memory/
|
|
42
|
-
tweek/memory/
|
|
43
|
-
tweek/memory/
|
|
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=
|
|
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=
|
|
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
|
|
98
|
-
tweek/security/model_registry.py,sha256=
|
|
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=
|
|
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=
|
|
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.
|
|
118
|
-
tweek-0.
|
|
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.
|
|
121
|
-
tweek-0.
|
|
122
|
-
tweek-0.
|
|
123
|
-
tweek-0.
|
|
124
|
-
tweek-0.
|
|
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,,
|