torusguard 1.3.5 → 1.4.0

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 (194) hide show
  1. package/.torusguard/.manifest.json +37 -36
  2. package/.torusguard/runs/report-latest.html +5862 -315
  3. package/.torusguard/runs/results-latest.sarif +20 -0
  4. package/.torusguard/runs/run-20260918-104221-audit/findings.json +1 -0
  5. package/.torusguard/runs/run-20260918-104221-audit/findings.md +8 -0
  6. package/.torusguard/runs/run-20260918-104221-audit/manifest.json +12 -0
  7. package/.torusguard/runs/run-20260918-104221-audit/summary.md +5 -0
  8. package/.torusguard/runs/run-20260918-104236-audit/findings.json +2314 -0
  9. package/.torusguard/runs/run-20260918-104236-audit/findings.md +960 -0
  10. package/.torusguard/runs/run-20260918-104236-audit/manifest.json +12 -0
  11. package/.torusguard/runs/run-20260918-104236-audit/summary.md +5 -0
  12. package/.torusguard/runs/run-20260918-105723-audit/findings.json +2382 -0
  13. package/.torusguard/runs/run-20260918-105723-audit/findings.md +960 -0
  14. package/.torusguard/runs/run-20260918-105723-audit/manifest.json +12 -0
  15. package/.torusguard/runs/run-20260918-105723-audit/summary.md +5 -0
  16. package/.torusguard/runs/run-20260918-105731-audit/findings.json +1 -0
  17. package/.torusguard/runs/run-20260918-105731-audit/findings.md +8 -0
  18. package/.torusguard/runs/run-20260918-105731-audit/manifest.json +12 -0
  19. package/.torusguard/runs/run-20260918-105731-audit/summary.md +5 -0
  20. package/.torusguard/runs/run-20260918-105940-audit/findings.json +1 -0
  21. package/.torusguard/runs/run-20260918-105940-audit/findings.md +8 -0
  22. package/.torusguard/runs/run-20260918-105940-audit/manifest.json +13 -0
  23. package/.torusguard/runs/run-20260918-105940-audit/remediation.md +7 -0
  24. package/.torusguard/runs/run-20260918-105940-audit/summary.md +5 -0
  25. package/.torusguard/runs/run-20260919-145701-audit/findings.json +1 -0
  26. package/.torusguard/runs/run-20260919-145701-audit/findings.md +8 -0
  27. package/.torusguard/runs/run-20260919-145701-audit/manifest.json +12 -0
  28. package/.torusguard/runs/run-20260919-145701-audit/summary.md +5 -0
  29. package/.torusguard/runs/run-20260919-151729-audit/findings.json +1 -0
  30. package/.torusguard/runs/run-20260919-151729-audit/findings.md +8 -0
  31. package/.torusguard/runs/run-20260919-151729-audit/manifest.json +13 -0
  32. package/.torusguard/runs/run-20260919-151729-audit/remediation.md +7 -0
  33. package/.torusguard/runs/run-20260919-151729-audit/summary.md +5 -0
  34. package/.torusguard/runs/run-20260919-152340-audit/findings.json +1 -0
  35. package/.torusguard/runs/run-20260919-152340-audit/findings.md +8 -0
  36. package/.torusguard/runs/run-20260919-152340-audit/manifest.json +12 -0
  37. package/.torusguard/runs/run-20260919-152340-audit/summary.md +5 -0
  38. package/.torusguard/runs/run-20260919-152345-audit/findings.json +1 -0
  39. package/.torusguard/runs/run-20260919-152345-audit/findings.md +8 -0
  40. package/.torusguard/runs/run-20260919-152345-audit/manifest.json +12 -0
  41. package/.torusguard/runs/run-20260919-152345-audit/summary.md +5 -0
  42. package/.torusguard/runs/run-20260919-153500-audit/findings.json +1 -0
  43. package/.torusguard/runs/run-20260919-153500-audit/findings.md +8 -0
  44. package/.torusguard/runs/run-20260919-153500-audit/manifest.json +12 -0
  45. package/.torusguard/runs/run-20260919-153500-audit/summary.md +5 -0
  46. package/.torusguard/scripts/__pycache__/apply_runner.cpython-314.pyc +0 -0
  47. package/.torusguard/scripts/__pycache__/audit_runner.cpython-314.pyc +0 -0
  48. package/.torusguard/scripts/__pycache__/diff_guard.cpython-314.pyc +0 -0
  49. package/.torusguard/scripts/__pycache__/finding_scorer.cpython-314.pyc +0 -0
  50. package/.torusguard/scripts/__pycache__/harden_runner.cpython-314.pyc +0 -0
  51. package/.torusguard/scripts/__pycache__/html_reporter.cpython-314.pyc +0 -0
  52. package/.torusguard/scripts/__pycache__/manifest_builder.cpython-314.pyc +0 -0
  53. package/.torusguard/scripts/__pycache__/memory_engine.cpython-314.pyc +0 -0
  54. package/.torusguard/scripts/__pycache__/monorepo_detector.cpython-314.pyc +0 -0
  55. package/.torusguard/scripts/__pycache__/recheck_runner.cpython-314.pyc +0 -0
  56. package/.torusguard/scripts/__pycache__/recipes_runner.cpython-314.pyc +0 -0
  57. package/.torusguard/scripts/__pycache__/report_sync.cpython-314.pyc +0 -0
  58. package/.torusguard/scripts/__pycache__/run_manager.cpython-314.pyc +0 -0
  59. package/.torusguard/scripts/__pycache__/sarif_exporter.cpython-314.pyc +0 -0
  60. package/.torusguard/scripts/__pycache__/stack_detect.cpython-314.pyc +0 -0
  61. package/.torusguard/scripts/__pycache__/term_ui.cpython-314.pyc +0 -0
  62. package/.torusguard/scripts/apply_runner.py +108 -9
  63. package/.torusguard/scripts/audit_runner.py +336 -24
  64. package/.torusguard/scripts/harden_runner.py +124 -70
  65. package/.torusguard/scripts/html_reporter.py +3585 -648
  66. package/.torusguard/scripts/manifest_builder.py +2 -0
  67. package/.torusguard/scripts/recheck_runner.py +5 -4
  68. package/.torusguard/scripts/recipes_runner.py +91 -8
  69. package/.torusguard/scripts/report_sync.py +496 -73
  70. package/.torusguard/scripts/sarif_exporter.py +48 -8
  71. package/.torusguard/scripts/stack_detect.py +44 -2
  72. package/.torusguard/scripts/status_runner.py +267 -0
  73. package/.torusguard/scripts/term_ui.py +1 -1
  74. package/.torusguard/skills/torusguard/SKILL.md +75 -72
  75. package/.torusguard/skills/torusguard-apply/SKILL.md +84 -80
  76. package/.torusguard/skills/torusguard-audit/SKILL.md +87 -83
  77. package/.torusguard/skills/torusguard-authorize/SKILL.md +7 -2
  78. package/.torusguard/skills/torusguard-exploit-check/SKILL.md +7 -2
  79. package/.torusguard/skills/torusguard-full/SKILL.md +7 -2
  80. package/.torusguard/skills/torusguard-harden/SKILL.md +98 -94
  81. package/.torusguard/skills/torusguard-init/SKILL.md +68 -64
  82. package/.torusguard/skills/torusguard-recheck/SKILL.md +81 -77
  83. package/.torusguard/skills/torusguard-report/SKILL.md +93 -72
  84. package/.torusguard/skills/torusguard-status/SKILL.md +62 -58
  85. package/.torusguard/skills/torusguard-verify/SKILL.md +7 -2
  86. package/.torusguard/skills/torusguard-web-validate/SKILL.md +7 -2
  87. package/.torusguard/workflows/apply.md +1 -1
  88. package/.torusguard/workflows/audit.md +1 -1
  89. package/.torusguard/workflows/authorize.md +1 -1
  90. package/.torusguard/workflows/exploit-check.md +1 -1
  91. package/.torusguard/workflows/harden.md +1 -1
  92. package/.torusguard/workflows/init.md +1 -1
  93. package/.torusguard/workflows/memory.md +1 -1
  94. package/.torusguard/workflows/recheck.md +1 -1
  95. package/.torusguard/workflows/report.md +1 -1
  96. package/.torusguard/workflows/status.md +1 -1
  97. package/.torusguard/workflows/verify.md +1 -1
  98. package/.torusguard/workflows/web-validate.md +1 -1
  99. package/README.md +115 -81
  100. package/bin/torusguard.js +244 -38
  101. package/package.json +6 -2
  102. package/skills/torusguard/SKILL.md +1 -1
  103. package/skills/torusguard/__pycache__/bootstrap.cpython-314.pyc +0 -0
  104. package/skills/torusguard/bootstrap.py +52 -8
  105. package/skills/torusguard/payload/.manifest.json +51 -36
  106. package/skills/torusguard/payload/scripts/__pycache__/apply_runner.cpython-314.pyc +0 -0
  107. package/skills/torusguard/payload/scripts/__pycache__/audit_runner.cpython-311.pyc +0 -0
  108. package/skills/torusguard/payload/scripts/__pycache__/audit_runner.cpython-314.pyc +0 -0
  109. package/skills/torusguard/payload/scripts/__pycache__/diff_guard.cpython-311.pyc +0 -0
  110. package/skills/torusguard/payload/scripts/__pycache__/diff_guard.cpython-314.pyc +0 -0
  111. package/skills/torusguard/payload/scripts/__pycache__/finding_scorer.cpython-311.pyc +0 -0
  112. package/skills/torusguard/payload/scripts/__pycache__/finding_scorer.cpython-314.pyc +0 -0
  113. package/skills/torusguard/payload/scripts/__pycache__/harden_runner.cpython-314.pyc +0 -0
  114. package/skills/torusguard/payload/scripts/__pycache__/html_reporter.cpython-311.pyc +0 -0
  115. package/skills/torusguard/payload/scripts/__pycache__/html_reporter.cpython-314.pyc +0 -0
  116. package/skills/torusguard/payload/scripts/__pycache__/manifest_builder.cpython-314.pyc +0 -0
  117. package/skills/torusguard/payload/scripts/__pycache__/memory_engine.cpython-311.pyc +0 -0
  118. package/skills/torusguard/payload/scripts/__pycache__/memory_engine.cpython-314.pyc +0 -0
  119. package/skills/torusguard/payload/scripts/__pycache__/monorepo_detector.cpython-311.pyc +0 -0
  120. package/skills/torusguard/payload/scripts/__pycache__/monorepo_detector.cpython-314.pyc +0 -0
  121. package/skills/torusguard/payload/scripts/__pycache__/recheck_runner.cpython-314.pyc +0 -0
  122. package/skills/torusguard/payload/scripts/__pycache__/report_sync.cpython-311.pyc +0 -0
  123. package/skills/torusguard/payload/scripts/__pycache__/report_sync.cpython-314.pyc +0 -0
  124. package/skills/torusguard/payload/scripts/__pycache__/rules_sync.cpython-311.pyc +0 -0
  125. package/skills/torusguard/payload/scripts/__pycache__/run_manager.cpython-311.pyc +0 -0
  126. package/skills/torusguard/payload/scripts/__pycache__/run_manager.cpython-314.pyc +0 -0
  127. package/skills/torusguard/payload/scripts/__pycache__/sarif_exporter.cpython-314.pyc +0 -0
  128. package/skills/torusguard/payload/scripts/__pycache__/stack_detect.cpython-311.pyc +0 -0
  129. package/skills/torusguard/payload/scripts/__pycache__/stack_detect.cpython-314.pyc +0 -0
  130. package/skills/torusguard/payload/scripts/__pycache__/term_ui.cpython-311.pyc +0 -0
  131. package/skills/torusguard/payload/scripts/__pycache__/term_ui.cpython-314.pyc +0 -0
  132. package/skills/torusguard/payload/scripts/apply_runner.py +108 -9
  133. package/skills/torusguard/payload/scripts/audit_runner.py +336 -24
  134. package/skills/torusguard/payload/scripts/harden_runner.py +124 -70
  135. package/skills/torusguard/payload/scripts/html_reporter.py +3585 -648
  136. package/skills/torusguard/payload/scripts/manifest_builder.py +2 -0
  137. package/skills/torusguard/payload/scripts/recheck_runner.py +5 -4
  138. package/skills/torusguard/payload/scripts/recipes_runner.py +91 -8
  139. package/skills/torusguard/payload/scripts/report_sync.py +496 -73
  140. package/skills/torusguard/payload/scripts/sarif_exporter.py +48 -8
  141. package/skills/torusguard/payload/scripts/stack_detect.py +44 -2
  142. package/skills/torusguard/payload/scripts/status_runner.py +267 -0
  143. package/skills/torusguard/payload/scripts/term_ui.py +1 -1
  144. package/skills/torusguard/payload/skills/torusguard/SKILL.md +1 -1
  145. package/skills/torusguard/payload/skills/torusguard-apply/SKILL.md +1 -1
  146. package/skills/torusguard/payload/skills/torusguard-audit/SKILL.md +1 -1
  147. package/skills/torusguard/payload/skills/torusguard-authorize/SKILL.md +1 -1
  148. package/skills/torusguard/payload/skills/torusguard-exploit-check/SKILL.md +1 -1
  149. package/skills/torusguard/payload/skills/torusguard-full/SKILL.md +1 -1
  150. package/skills/torusguard/payload/skills/torusguard-harden/SKILL.md +1 -1
  151. package/skills/torusguard/payload/skills/torusguard-init/SKILL.md +1 -1
  152. package/skills/torusguard/payload/skills/torusguard-recheck/SKILL.md +1 -1
  153. package/skills/torusguard/payload/skills/torusguard-report/SKILL.md +40 -23
  154. package/skills/torusguard/payload/skills/torusguard-status/SKILL.md +1 -1
  155. package/skills/torusguard/payload/skills/torusguard-verify/SKILL.md +1 -1
  156. package/skills/torusguard/payload/skills/torusguard-web-validate/SKILL.md +1 -1
  157. package/skills/torusguard/payload/workflows/apply.md +9 -1
  158. package/skills/torusguard/payload/workflows/audit.md +8 -2
  159. package/skills/torusguard/payload/workflows/authorize.md +1 -1
  160. package/skills/torusguard/payload/workflows/exploit-check.md +1 -1
  161. package/skills/torusguard/payload/workflows/harden.md +6 -1
  162. package/skills/torusguard/payload/workflows/init.md +7 -1
  163. package/skills/torusguard/payload/workflows/memory.md +1 -1
  164. package/skills/torusguard/payload/workflows/recheck.md +1 -1
  165. package/skills/torusguard/payload/workflows/recipes.md +55 -0
  166. package/skills/torusguard/payload/workflows/report.md +59 -55
  167. package/skills/torusguard/payload/workflows/status.md +4 -1
  168. package/skills/torusguard/payload/workflows/torusguard-apply.md +110 -0
  169. package/skills/torusguard/payload/workflows/torusguard-audit.md +105 -0
  170. package/skills/torusguard/payload/workflows/torusguard-authorize.md +96 -0
  171. package/skills/torusguard/payload/workflows/torusguard-exploit-check.md +98 -0
  172. package/skills/torusguard/payload/workflows/torusguard-harden.md +104 -0
  173. package/skills/torusguard/payload/workflows/torusguard-init.md +106 -0
  174. package/skills/torusguard/payload/workflows/torusguard-recheck.md +101 -0
  175. package/skills/torusguard/payload/workflows/torusguard-recipes.md +55 -0
  176. package/skills/torusguard/payload/workflows/torusguard-report.md +105 -0
  177. package/skills/torusguard/payload/workflows/torusguard-status.md +103 -0
  178. package/skills/torusguard/payload/workflows/torusguard-verify.md +100 -0
  179. package/skills/torusguard/payload/workflows/torusguard-web-validate.md +96 -0
  180. package/skills/torusguard/payload/workflows/torusguard.md +19 -0
  181. package/skills/torusguard/payload/workflows/verify.md +1 -1
  182. package/skills/torusguard/payload/workflows/web-validate.md +1 -1
  183. package/skills/torusguard-apply/SKILL.md +1 -1
  184. package/skills/torusguard-audit/SKILL.md +1 -1
  185. package/skills/torusguard-authorize/SKILL.md +1 -1
  186. package/skills/torusguard-exploit-check/SKILL.md +1 -1
  187. package/skills/torusguard-full/SKILL.md +1 -1
  188. package/skills/torusguard-harden/SKILL.md +1 -1
  189. package/skills/torusguard-init/SKILL.md +1 -1
  190. package/skills/torusguard-recheck/SKILL.md +1 -1
  191. package/skills/torusguard-report/SKILL.md +40 -23
  192. package/skills/torusguard-status/SKILL.md +1 -1
  193. package/skills/torusguard-verify/SKILL.md +1 -1
  194. package/skills/torusguard-web-validate/SKILL.md +1 -1
@@ -33,6 +33,8 @@ def scan_workspace_files(base_dir):
33
33
  dirs.remove("snapshots")
34
34
  if "memory" in dirs:
35
35
  dirs.remove("memory")
36
+ if "reports" in dirs:
37
+ dirs.remove("reports")
36
38
  if "__pycache__" in dirs:
37
39
  dirs.remove("__pycache__")
38
40
 
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env python3
2
2
  """
3
- TorusGuard Targeted Differential Recheck Engine (v1.3.5)
3
+ TorusGuard Targeted Differential Recheck Engine (v1.3.6)
4
4
  Executes scoped differential re-audits verifying only impacted files and adjacent boundaries.
5
5
  Evaluates formal status transitions (Confirmed Fixed vs Regressed vs Unresolved), updates run manifest,
6
6
  and records verification telemetry in the persistent security memory subsystem.
@@ -57,7 +57,7 @@ def box_line(content: str, width: int = 67, border: str = "│", border_color: s
57
57
  return term_ui.format_box_line(content, width=width, border=border, border_color=border_color)
58
58
  return f" {border_color}{border}{RESET} {content}"
59
59
 
60
- def box_header(title: str, subtitle: str = "", version: str = "v1.3.5", border_color: str = CYAN) -> str:
60
+ def box_header(title: str, subtitle: str = "", version: str = "v1.3.6", border_color: str = CYAN) -> str:
61
61
  if term_ui:
62
62
  return term_ui.card_header(title, subtitle, version, border_color)
63
63
  return f"=== {title} ({version}) ==="
@@ -106,7 +106,7 @@ def execute_recheck(target_root: Path, run_id_arg: Optional[str] = None) -> Dict
106
106
 
107
107
  # Header Card
108
108
  print()
109
- print(box_header("🛡️ TORUSGUARD DIFFERENTIAL RECHECK ENGINE", "Targeted Differential AST Scan & Regression Verification", "v1.3.5"))
109
+ print(box_header("🛡️ TORUSGUARD DIFFERENTIAL RECHECK ENGINE", "Targeted Differential AST Scan & Regression Verification", "v1.3.6"))
110
110
  print()
111
111
 
112
112
  print(border_top("Recheck Verification Scope"))
@@ -233,11 +233,12 @@ def execute_recheck(target_root: Path, run_id_arg: Optional[str] = None) -> Dict
233
233
  def main():
234
234
  parser = argparse.ArgumentParser(description="TorusGuard Differential Recheck Engine")
235
235
  parser.add_argument("path", nargs="?", default=".", help="Target project root directory")
236
+ parser.add_argument("--target", "-t", help="Target project root directory (alias for path)")
236
237
  parser.add_argument("--run", "-r", help="Explicit run ID to recheck")
237
238
  parser.add_argument("--json", action="store_true", help="Output raw JSON")
238
239
  args = parser.parse_args()
239
240
 
240
- target = Path(args.path).resolve()
241
+ target = Path(args.target or args.path).resolve()
241
242
  result = execute_recheck(target, run_id_arg=args.run)
242
243
 
243
244
  if args.json:
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env python3
2
2
  """
3
- TorusGuard Golden Fix Recipe Explorer (v1.3.5)
3
+ TorusGuard Golden Fix Recipe Explorer (v1.4.0)
4
4
  Inspect, list, and export reusable, verified AST remediation code snippets
5
5
  distilled from passing security patches and persistent memory patterns.
6
6
  Standardized 75-column terminal UI formatting.
@@ -47,7 +47,7 @@ def box_line(content: str, width: int = 67, border: str = "│", border_color: s
47
47
  return term_ui.format_box_line(content, width=width, border=border, border_color=border_color)
48
48
  return f" {border_color}{border}{RESET} {content}"
49
49
 
50
- def box_header(title: str, subtitle: str = "", version: str = "v1.3.5", border_color: str = CYAN) -> str:
50
+ def box_header(title: str, subtitle: str = "", version: str = "v1.4.0", border_color: str = CYAN) -> str:
51
51
  if term_ui:
52
52
  return term_ui.card_header(title, subtitle, version, border_color)
53
53
  return f"=== {title} ({version}) ==="
@@ -63,28 +63,100 @@ def border_bottom(border_color: str = CYAN, double: bool = False) -> str:
63
63
  return "└" + "─" * 71 + "┘"
64
64
 
65
65
 
66
- def list_recipes(target_root: Path, detail_id: Optional[str] = None, json_output: bool = False) -> None:
66
+ def list_recipes(target_root: Path, detail_id: Optional[str] = None, search_query: Optional[str] = None, export_path: Optional[str] = None, apply_id: Optional[str] = None, json_output: bool = False) -> None:
67
67
  patterns_file = target_root / ".torusguard" / "memory" / "patterns.json"
68
68
  recipes: List[Dict[str, Any]] = []
69
69
 
70
70
  if patterns_file.is_file():
71
71
  try:
72
72
  patterns = json.loads(patterns_file.read_text(encoding="utf-8"))
73
- recipes = [p for p in patterns if p.get("pattern_type") == "golden_fix_recipe"]
73
+ if isinstance(patterns, list):
74
+ recipes = [p for p in patterns if p.get("pattern_type") == "golden_fix_recipe"]
75
+ elif isinstance(patterns, dict) and "patterns" in patterns:
76
+ recipes = [p for p in patterns["patterns"] if p.get("pattern_type") == "golden_fix_recipe"]
74
77
  except Exception:
75
78
  recipes = []
76
79
 
80
+ # 1. Search filtering
81
+ if search_query:
82
+ sq = search_query.lower()
83
+ recipes = [
84
+ r for r in recipes
85
+ if sq in r.get("rule_id", "").lower()
86
+ or sq in r.get("recipe_id", "").lower()
87
+ or sq in r.get("description", "").lower()
88
+ or sq in r.get("recipe_data", {}).get("diff_snippet", "").lower()
89
+ ]
90
+
91
+ # 2. Export requested
92
+ if export_path:
93
+ out_p = Path(export_path)
94
+ if not out_p.is_absolute():
95
+ out_p = (target_root / out_p).resolve()
96
+ out_p.parent.mkdir(parents=True, exist_ok=True)
97
+ if out_p.suffix.lower() == ".json":
98
+ out_p.write_text(json.dumps(recipes, indent=2), encoding="utf-8")
99
+ else:
100
+ md_lines = [
101
+ "# TorusGuard Golden Fix Recipes Catalog",
102
+ f"- Total Recipes: {len(recipes)}",
103
+ f"- Exported From: {target_root}",
104
+ ""
105
+ ]
106
+ for r in recipes:
107
+ md_lines.append(f"## [{r.get('rule_id')}] {r.get('recipe_id')}")
108
+ md_lines.append(f"- **Description:** {r.get('description')}")
109
+ rdata = r.get("recipe_data", {})
110
+ md_lines.append(f"- **Verified Count:** {rdata.get('verified_count', 1)}x")
111
+ md_lines.append("```diff")
112
+ md_lines.append(rdata.get("diff_snippet", ""))
113
+ md_lines.append("```\n")
114
+ out_p.write_text("\n".join(md_lines), encoding="utf-8")
115
+ print(f"\n {GREEN}✔ Exported {len(recipes)} golden recipe(s) to:{RESET} {CYAN}{out_p}{RESET}\n")
116
+ return
117
+
118
+ # 3. Apply inspection requested
119
+ if apply_id:
120
+ target_rec = next((r for r in recipes if r.get("recipe_id") == apply_id or apply_id in r.get("recipe_id", "")), None)
121
+ if not target_rec:
122
+ print(f"\n {RED}✖ Recipe '{apply_id}' not found in golden recipe memory.{RESET}\n")
123
+ return
124
+ rdata = target_rec.get("recipe_data", {})
125
+ print()
126
+ print(box_header("🛡️ GOLDEN RECIPE APPLICATION PREVIEW", f"Recipe ID: {target_rec.get('recipe_id')}", "v1.4.0"))
127
+ print()
128
+ print(border_top("Recipe Metadata"))
129
+ print(box_line(f"Rule ID: {YELLOW}{target_rec.get('rule_id')}{RESET}"))
130
+ print(box_line(f"Description: {WHITE}{target_rec.get('description')}{RESET}"))
131
+ metrics = rdata.get("ponytail_metrics", {})
132
+ print(box_line(f"Ponytail: {GREEN}+{metrics.get('additions', 0)} / -{metrics.get('deletions', 0)} lines{RESET}"))
133
+ print(border_bottom())
134
+ print()
135
+ print(f" {BOLD}Diff Projection:{RESET}")
136
+ print(" ```diff")
137
+ for line in rdata.get("diff_snippet", "").splitlines():
138
+ if line.startswith("+"):
139
+ print(f" {GREEN}{line}{RESET}")
140
+ elif line.startswith("-"):
141
+ print(f" {RED}{line}{RESET}")
142
+ else:
143
+ print(f" {DIM}{line}{RESET}")
144
+ print(" ```")
145
+ print(f"\n {DIM}To apply automatically across all matching findings, run: {CYAN}npx torusguard harden && npx torusguard apply{RESET}\n")
146
+ return
147
+
77
148
  if json_output:
78
149
  print(json.dumps(recipes, indent=2))
79
150
  return
80
151
 
81
152
  # Header Card
82
153
  print()
83
- print(box_header("🛡️ TORUSGUARD GOLDEN FIX RECIPES", "Distilled Ponytail Fixes (<= 35 add, <= 25 del) in Persistent Memory", "v1.3.5"))
154
+ sub_title = f"Filtered by '{search_query}'" if search_query else "Distilled Ponytail Fixes (<= 35 add, <= 25 del) in Persistent Memory"
155
+ print(box_header("🛡️ TORUSGUARD GOLDEN FIX RECIPES", sub_title, "v1.4.0"))
84
156
  print()
85
157
 
86
158
  if not recipes:
87
- print(f" {YELLOW}ℹ No golden fix recipes captured yet.{RESET}")
159
+ print(f" {YELLOW}ℹ No golden fix recipes found matching query.{RESET}")
88
160
  print(f" Run {CYAN}npx torusguard harden{RESET} followed by {CYAN}npx torusguard apply{RESET} to distill verified recipes.\n")
89
161
  return
90
162
 
@@ -125,12 +197,23 @@ def list_recipes(target_root: Path, detail_id: Optional[str] = None, json_output
125
197
  def main():
126
198
  parser = argparse.ArgumentParser(description="TorusGuard Golden Fix Recipe Explorer")
127
199
  parser.add_argument("path", nargs="?", default=".", help="Target project root directory")
200
+ parser.add_argument("--target", "-t", help="Target project root directory (alias for path)")
128
201
  parser.add_argument("--detail", "-d", help="Inspect specific recipe ID")
202
+ parser.add_argument("--search", "-s", help="Filter recipes by rule, keyword, or language")
203
+ parser.add_argument("--export", "-e", help="Export recipes to JSON or Markdown file path")
204
+ parser.add_argument("--apply", "-a", help="Project and display application diff for specific recipe ID")
129
205
  parser.add_argument("--json", action="store_true", help="Output raw JSON")
130
206
  args = parser.parse_args()
131
207
 
132
- target = Path(args.path).resolve()
133
- list_recipes(target, detail_id=args.detail, json_output=args.json)
208
+ target = Path(args.target or args.path).resolve()
209
+ list_recipes(
210
+ target,
211
+ detail_id=args.detail,
212
+ search_query=args.search,
213
+ export_path=args.export,
214
+ apply_id=args.apply,
215
+ json_output=args.json
216
+ )
134
217
 
135
218
 
136
219
  if __name__ == "__main__":