guard-cli 0.1.2__tar.gz → 0.1.4__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 (50) hide show
  1. {guard_cli-0.1.2 → guard_cli-0.1.4}/PKG-INFO +1 -1
  2. {guard_cli-0.1.2 → guard_cli-0.1.4}/guard_cli/cli.py +6 -0
  3. {guard_cli-0.1.2 → guard_cli-0.1.4}/guard_cli/hook.py +8 -18
  4. {guard_cli-0.1.2 → guard_cli-0.1.4}/guard_cli.egg-info/PKG-INFO +1 -1
  5. {guard_cli-0.1.2 → guard_cli-0.1.4}/pyproject.toml +1 -1
  6. {guard_cli-0.1.2 → guard_cli-0.1.4}/tests/test_api_and_hook.py +31 -0
  7. {guard_cli-0.1.2 → guard_cli-0.1.4}/LICENSE +0 -0
  8. {guard_cli-0.1.2 → guard_cli-0.1.4}/README.md +0 -0
  9. {guard_cli-0.1.2 → guard_cli-0.1.4}/guard_cli/__init__.py +0 -0
  10. {guard_cli-0.1.2 → guard_cli-0.1.4}/guard_cli/agent_integration.py +0 -0
  11. {guard_cli-0.1.2 → guard_cli-0.1.4}/guard_cli/api.py +0 -0
  12. {guard_cli-0.1.2 → guard_cli-0.1.4}/guard_cli/backend.py +0 -0
  13. {guard_cli-0.1.2 → guard_cli-0.1.4}/guard_cli/db.py +0 -0
  14. {guard_cli-0.1.2 → guard_cli-0.1.4}/guard_cli/decision.py +0 -0
  15. {guard_cli-0.1.2 → guard_cli-0.1.4}/guard_cli/doctor_cmd.py +0 -0
  16. {guard_cli-0.1.2 → guard_cli-0.1.4}/guard_cli/events.py +0 -0
  17. {guard_cli-0.1.2 → guard_cli-0.1.4}/guard_cli/feedback.py +0 -0
  18. {guard_cli-0.1.2 → guard_cli-0.1.4}/guard_cli/ingest/__init__.py +0 -0
  19. {guard_cli-0.1.2 → guard_cli-0.1.4}/guard_cli/ingest/coverage.py +0 -0
  20. {guard_cli-0.1.2 → guard_cli-0.1.4}/guard_cli/ingest/static.py +0 -0
  21. {guard_cli-0.1.2 → guard_cli-0.1.4}/guard_cli/init_cmd.py +0 -0
  22. {guard_cli-0.1.2 → guard_cli-0.1.4}/guard_cli/integrations/__init__.py +0 -0
  23. {guard_cli-0.1.2 → guard_cli-0.1.4}/guard_cli/integrations/antigravity.py +0 -0
  24. {guard_cli-0.1.2 → guard_cli-0.1.4}/guard_cli/integrations/claude.py +0 -0
  25. {guard_cli-0.1.2 → guard_cli-0.1.4}/guard_cli/state.py +0 -0
  26. {guard_cli-0.1.2 → guard_cli-0.1.4}/guard_cli/thin_slice.py +0 -0
  27. {guard_cli-0.1.2 → guard_cli-0.1.4}/guard_cli.egg-info/SOURCES.txt +0 -0
  28. {guard_cli-0.1.2 → guard_cli-0.1.4}/guard_cli.egg-info/dependency_links.txt +0 -0
  29. {guard_cli-0.1.2 → guard_cli-0.1.4}/guard_cli.egg-info/entry_points.txt +0 -0
  30. {guard_cli-0.1.2 → guard_cli-0.1.4}/guard_cli.egg-info/requires.txt +0 -0
  31. {guard_cli-0.1.2 → guard_cli-0.1.4}/guard_cli.egg-info/top_level.txt +0 -0
  32. {guard_cli-0.1.2 → guard_cli-0.1.4}/setup.cfg +0 -0
  33. {guard_cli-0.1.2 → guard_cli-0.1.4}/tests/test_antigravity_integration.py +0 -0
  34. {guard_cli-0.1.2 → guard_cli-0.1.4}/tests/test_antigravity_pre_recording_fixes.py +0 -0
  35. {guard_cli-0.1.2 → guard_cli-0.1.4}/tests/test_backend.py +0 -0
  36. {guard_cli-0.1.2 → guard_cli-0.1.4}/tests/test_commit_bypass.py +0 -0
  37. {guard_cli-0.1.2 → guard_cli-0.1.4}/tests/test_commit_bypass_fresh_session.py +0 -0
  38. {guard_cli-0.1.2 → guard_cli-0.1.4}/tests/test_coverage.py +0 -0
  39. {guard_cli-0.1.2 → guard_cli-0.1.4}/tests/test_db.py +0 -0
  40. {guard_cli-0.1.2 → guard_cli-0.1.4}/tests/test_decision.py +0 -0
  41. {guard_cli-0.1.2 → guard_cli-0.1.4}/tests/test_doctor_cmd.py +0 -0
  42. {guard_cli-0.1.2 → guard_cli-0.1.4}/tests/test_embedded_platform.py +0 -0
  43. {guard_cli-0.1.2 → guard_cli-0.1.4}/tests/test_event_reasons.py +0 -0
  44. {guard_cli-0.1.2 → guard_cli-0.1.4}/tests/test_feedback.py +0 -0
  45. {guard_cli-0.1.2 → guard_cli-0.1.4}/tests/test_fingerprint_invalidation.py +0 -0
  46. {guard_cli-0.1.2 → guard_cli-0.1.4}/tests/test_hook_timeout.py +0 -0
  47. {guard_cli-0.1.2 → guard_cli-0.1.4}/tests/test_init_cmd.py +0 -0
  48. {guard_cli-0.1.2 → guard_cli-0.1.4}/tests/test_integration_init_doctor.py +0 -0
  49. {guard_cli-0.1.2 → guard_cli-0.1.4}/tests/test_static.py +0 -0
  50. {guard_cli-0.1.2 → guard_cli-0.1.4}/tests/test_thin_slice.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: guard-cli
3
- Version: 0.1.2
3
+ Version: 0.1.4
4
4
  Summary: Graph-powered safety layer for AI coding agents built on FalkorDB
5
5
  License-Expression: MIT
6
6
  Project-URL: Homepage, https://github.com/thisisvaishnav/guard
@@ -287,16 +287,19 @@ def main(argv=None) -> int:
287
287
  hk_inst.add_argument("--repo", default=None, help="path to repo root")
288
288
  hk_inst.add_argument("--shared", action="store_true", help="install to settings.json instead of settings.local.json")
289
289
  hk_inst.add_argument("--antigravity", action="store_true", help="install to Antigravity .agents/hooks.json instead of Claude Code settings")
290
+ hk_inst.set_defaults(fn=cmd_hook_install)
290
291
 
291
292
  hk_uninst = hk_sub.add_parser("uninstall", help="Uninstall Stop hook from agent settings (Claude Code by default, Antigravity with --antigravity)")
292
293
  hk_uninst.add_argument("--repo", default=None, help="path to repo root")
293
294
  hk_uninst.add_argument("--shared", action="store_true", help="uninstall from settings.json instead of settings.local.json")
294
295
  hk_uninst.add_argument("--antigravity", action="store_true", help="uninstall from Antigravity .agents/hooks.json instead of Claude Code settings")
296
+ hk_uninst.set_defaults(fn=cmd_hook_uninstall)
295
297
 
296
298
  hk_stat = hk_sub.add_parser("status", help="Check hook installation status (Claude Code by default, Antigravity with --antigravity)")
297
299
  hk_stat.add_argument("--repo", default=None, help="path to repo root")
298
300
  hk_stat.add_argument("--shared", action="store_true", help="check settings.json instead of settings.local.json")
299
301
  hk_stat.add_argument("--antigravity", action="store_true", help="check Antigravity .agents/hooks.json instead of Claude Code settings")
302
+ hk_stat.set_defaults(fn=cmd_hook_status)
300
303
 
301
304
  fb = sub.add_parser("feedback")
302
305
  fb.add_argument("--function", required=True, help="Function ID where fault was missed")
@@ -336,6 +339,9 @@ def main(argv=None) -> int:
336
339
  cov.set_defaults(fn=cmd_covering_tests)
337
340
 
338
341
  args = p.parse_args(argv)
342
+ if not hasattr(args, "fn"):
343
+ p.print_help()
344
+ return 1
339
345
  return args.fn(args)
340
346
 
341
347
 
@@ -530,16 +530,11 @@ def run_stop_hook(
530
530
  if is_antigravity:
531
531
  resp: dict[str, Any] = {"decision": "stop", "reason": reason or ""}
532
532
  payload = json.dumps(resp) + "\n"
533
- if saved_stdout is not None:
533
+ target_out = real_out if real_out is not None else saved_stdout
534
+ if target_out is not None:
534
535
  try:
535
- saved_stdout.write(payload)
536
- saved_stdout.flush()
537
- except Exception:
538
- pass
539
- if real_out is not None and real_out is not saved_stdout:
540
- try:
541
- real_out.write(payload)
542
- real_out.flush()
536
+ target_out.write(payload)
537
+ target_out.flush()
543
538
  except Exception:
544
539
  pass
545
540
  return 0
@@ -548,16 +543,11 @@ def run_stop_hook(
548
543
  if is_antigravity:
549
544
  resp: dict[str, Any] = {"decision": "continue", "reason": reason_text}
550
545
  payload = json.dumps(resp) + "\n"
551
- if saved_stdout is not None:
552
- try:
553
- saved_stdout.write(payload)
554
- saved_stdout.flush()
555
- except Exception:
556
- pass
557
- if real_out is not None and real_out is not saved_stdout:
546
+ target_out = real_out if real_out is not None else saved_stdout
547
+ if target_out is not None:
558
548
  try:
559
- real_out.write(payload)
560
- real_out.flush()
549
+ target_out.write(payload)
550
+ target_out.flush()
561
551
  except Exception:
562
552
  pass
563
553
  sys.stderr.write(reason_text)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: guard-cli
3
- Version: 0.1.2
3
+ Version: 0.1.4
4
4
  Summary: Graph-powered safety layer for AI coding agents built on FalkorDB
5
5
  License-Expression: MIT
6
6
  Project-URL: Homepage, https://github.com/thisisvaishnav/guard
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "guard-cli"
7
- version = "0.1.2"
7
+ version = "0.1.4"
8
8
  description = "Graph-powered safety layer for AI coding agents built on FalkorDB"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -421,3 +421,34 @@ def test_claude_settings_uninstall_only_removes_guard(temp_repo):
421
421
 
422
422
  stat = claude.status(repo_path=temp_repo, shared=False)
423
423
  assert stat["installed"] is False
424
+
425
+
426
+ def test_cli_hook_subcommands(temp_repo, capsys):
427
+ """Test CLI dispatch for hook status, install, and uninstall."""
428
+ from guard_cli.cli import main
429
+
430
+ # Status before install
431
+ ret = main(["hook", "status", "--repo", str(temp_repo)])
432
+ assert ret == 0
433
+ captured = capsys.readouterr().out
434
+ data = json.loads(captured)
435
+ assert "claude" in data
436
+ assert "antigravity" in data
437
+ assert data["antigravity"]["installed"] is False
438
+
439
+ # Install antigravity hook
440
+ ret = main(["hook", "install", "--repo", str(temp_repo), "--antigravity"])
441
+ assert ret == 0
442
+ capsys.readouterr()
443
+
444
+ # Status after install
445
+ ret = main(["hook", "status", "--repo", str(temp_repo)])
446
+ assert ret == 0
447
+ captured = capsys.readouterr().out
448
+ data = json.loads(captured)
449
+ assert data["antigravity"]["installed"] is True
450
+
451
+ # Uninstall antigravity hook
452
+ ret = main(["hook", "uninstall", "--repo", str(temp_repo), "--antigravity"])
453
+ assert ret == 0
454
+
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes