claude-jacked 0.3.2__tar.gz → 0.3.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/PKG-INFO +1 -1
  2. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/jacked/__init__.py +1 -1
  3. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/jacked/data/hooks/security_gatekeeper.py +25 -12
  4. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/pyproject.toml +1 -1
  5. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/.claude/settings.local.json +0 -0
  6. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/.github/workflows/publish.yml +0 -0
  7. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/.gitignore +0 -0
  8. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/LICENSE +0 -0
  9. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/README.md +0 -0
  10. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/design/session_indexing_improvements.md +0 -0
  11. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/docs/DESIGN.md +0 -0
  12. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/install.sh +0 -0
  13. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/jacked/cli.py +0 -0
  14. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/jacked/client.py +0 -0
  15. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/jacked/config.py +0 -0
  16. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/jacked/data/agents/code-simplicity-reviewer.md +0 -0
  17. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/jacked/data/agents/defensive-error-handler.md +0 -0
  18. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/jacked/data/agents/double-check-reviewer.md +0 -0
  19. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/jacked/data/agents/git-pr-workflow-manager.md +0 -0
  20. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/jacked/data/agents/issue-pr-coordinator.md +0 -0
  21. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/jacked/data/agents/pr-workflow-checker.md +0 -0
  22. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/jacked/data/agents/readme-maintainer.md +0 -0
  23. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/jacked/data/agents/test-coverage-engineer.md +0 -0
  24. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/jacked/data/agents/test-coverage-improver.md +0 -0
  25. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/jacked/data/agents/wiki-documentation-architect.md +0 -0
  26. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/jacked/data/commands/audit-rules.md +0 -0
  27. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/jacked/data/commands/dc.md +0 -0
  28. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/jacked/data/commands/learn.md +0 -0
  29. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/jacked/data/commands/pr.md +0 -0
  30. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/jacked/data/commands/redo.md +0 -0
  31. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/jacked/data/commands/techdebt.md +0 -0
  32. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/jacked/data/rules/jacked_behaviors.md +0 -0
  33. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/jacked/data/skills/jacked/SKILL.md +0 -0
  34. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/jacked/index_write_tracker.py +0 -0
  35. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/jacked/indexer.py +0 -0
  36. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/jacked/retriever.py +0 -0
  37. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/jacked/searcher.py +0 -0
  38. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/jacked/transcript.py +0 -0
  39. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/tests/__init__.py +0 -0
  40. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/tests/conftest.py +0 -0
  41. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/tests/debugging/test_gatekeeper.py +0 -0
  42. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/tests/test_config.py +0 -0
  43. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/tests/test_index_write_tracker.py +0 -0
  44. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/tests/test_indexer_incremental.py +0 -0
  45. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/tests/test_transcript.py +0 -0
  46. {claude_jacked-0.3.2 → claude_jacked-0.3.3}/uninstall.sh +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: claude-jacked
3
- Version: 0.3.2
3
+ Version: 0.3.3
4
4
  Summary: Smart reviewers, commands, and session search for Claude Code
5
5
  Project-URL: Homepage, https://github.com/jackneil/claude-jacked
6
6
  Project-URL: Repository, https://github.com/jackneil/claude-jacked
@@ -8,7 +8,7 @@ Install extras for additional features:
8
8
  pip install "claude-jacked[all]" — everything
9
9
  """
10
10
 
11
- __version__ = "0.3.2"
11
+ __version__ = "0.3.3"
12
12
 
13
13
 
14
14
  def _qdrant_available() -> bool:
@@ -64,6 +64,9 @@ SAFE_EXACT = {
64
64
  # e.g., C:/Users/jack/.conda/envs/krac_llm/python.exe → python
65
65
  PATH_STRIP_RE = re.compile(r'^(?:.*[/\\])?([^/\\]+?)(?:\.exe)?(?:\s|$)', re.IGNORECASE)
66
66
 
67
+ # Strip leading env var assignments: HOME=/x PATH="/y:$PATH" cmd → cmd
68
+ ENV_ASSIGN_RE = re.compile(r"""^(?:\w+=(?:"[^"]*"|'[^']*'|\S+)\s+)+""")
69
+
67
70
  # Universal safe: any command that just asks for version or help
68
71
  VERSION_HELP_RE = re.compile(r'^\S+\s+(-[Vv]|--version|-h|--help)\s*$')
69
72
 
@@ -195,14 +198,18 @@ def check_permissions(command: str, cwd: str) -> bool:
195
198
  patterns.extend(_load_permissions(project_dir / ".claude" / "settings.json"))
196
199
  patterns.extend(_load_permissions(project_dir / ".claude" / "settings.local.json"))
197
200
 
201
+ cmd_core = _strip_env_prefix(command)
202
+ candidates = [command, cmd_core] if cmd_core != command else [command]
203
+
198
204
  for pat in patterns:
199
205
  prefix, is_wildcard = _parse_bash_pattern(pat)
200
- if is_wildcard:
201
- if command.startswith(prefix):
202
- return True
203
- else:
204
- if command == prefix:
205
- return True
206
+ for cmd in candidates:
207
+ if is_wildcard:
208
+ if cmd.startswith(prefix):
209
+ return True
210
+ else:
211
+ if cmd == prefix:
212
+ return True
206
213
 
207
214
  return False
208
215
 
@@ -223,9 +230,14 @@ def _get_base_command(command: str) -> str:
223
230
  return stripped
224
231
 
225
232
 
233
+ def _strip_env_prefix(cmd: str) -> str:
234
+ """Strip leading env var assignments: HOME=/x PATH="/y" cmd → cmd"""
235
+ return ENV_ASSIGN_RE.sub('', cmd).strip()
236
+
237
+
226
238
  def local_evaluate(command: str) -> str | None:
227
239
  """Evaluate command locally. Returns 'YES', 'NO', or None (ambiguous)."""
228
- cmd = command.strip()
240
+ cmd = _strip_env_prefix(command.strip())
229
241
  base = _get_base_command(cmd)
230
242
 
231
243
  # Check deny patterns first (on original command, not stripped)
@@ -353,11 +365,12 @@ def main():
353
365
 
354
366
  # Tier 0: Deny check FIRST — security always wins over permissions
355
367
  cmd_stripped = command.strip()
368
+ cmd_core = _strip_env_prefix(cmd_stripped)
356
369
  for pattern in DENY_PATTERNS:
357
- if pattern.search(cmd_stripped):
370
+ if pattern.search(cmd_stripped) or pattern.search(cmd_core):
358
371
  elapsed = time.time() - start
359
372
  log(f"DENY MATCH ({elapsed:.3f}s)")
360
- log(f"DECISION: PASS ({elapsed:.3f}s)")
373
+ log(f"DECISION: ASK USER ({elapsed:.3f}s)")
361
374
  sys.exit(0)
362
375
 
363
376
  # Tier 1: Check Claude's own permission rules
@@ -380,7 +393,7 @@ def main():
380
393
  # Shouldn't hit this since deny checked above, but just in case
381
394
  elapsed = time.time() - start
382
395
  log(f"LOCAL SAID: NO ({elapsed:.3f}s)")
383
- log(f"DECISION: PASS ({elapsed:.3f}s)")
396
+ log(f"DECISION: ASK USER ({elapsed:.3f}s)")
384
397
  sys.exit(0)
385
398
 
386
399
  # Tier 3+4: API then CLI for ambiguous commands
@@ -396,7 +409,7 @@ def main():
396
409
  elapsed = time.time() - start
397
410
 
398
411
  if response is None:
399
- log(f"DECISION: PASS (no response, {elapsed:.1f}s)")
412
+ log(f"DECISION: ASK USER (no response, {elapsed:.1f}s)")
400
413
  sys.exit(0)
401
414
 
402
415
  response_upper = response.upper()
@@ -406,7 +419,7 @@ def main():
406
419
  log(f"DECISION: ALLOW ({elapsed:.1f}s)")
407
420
  emit_allow()
408
421
  else:
409
- log(f"DECISION: PASS ({elapsed:.1f}s)")
422
+ log(f"DECISION: ASK USER ({elapsed:.1f}s)")
410
423
 
411
424
  sys.exit(0)
412
425
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "claude-jacked"
7
- version = "0.3.2"
7
+ version = "0.3.3"
8
8
  description = "Smart reviewers, commands, and session search for Claude Code"
9
9
  readme = "README.md"
10
10
  license = "MIT"
File without changes
File without changes
File without changes
File without changes