k-cli-for-devs 1.0.0__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 (75) hide show
  1. k_cli/__init__.py +77 -0
  2. k_cli/agents/__init__.py +0 -0
  3. k_cli/agents/adversarial_swarm.py +338 -0
  4. k_cli/agents/agent_core.py +255 -0
  5. k_cli/agents/background_daemon.py +141 -0
  6. k_cli/agents/orchestrator.py +376 -0
  7. k_cli/agents/persona.py +649 -0
  8. k_cli/agents/scaffold_engine.py +121 -0
  9. k_cli/agents/strands_agent.py +832 -0
  10. k_cli/agents/subagents.py +1496 -0
  11. k_cli/cli.py +3297 -0
  12. k_cli/core/__init__.py +0 -0
  13. k_cli/core/airgap.py +95 -0
  14. k_cli/core/credentials.py +548 -0
  15. k_cli/core/intent_sensor.py +177 -0
  16. k_cli/core/llm_driver.py +1028 -0
  17. k_cli/core/model_manager.py +1109 -0
  18. k_cli/core/models_hub.py +913 -0
  19. k_cli/core/prompting.py +41 -0
  20. k_cli/core/sdk.py +322 -0
  21. k_cli/core/session.py +826 -0
  22. k_cli/core/smart_router.py +230 -0
  23. k_cli/core/storage_manager.py +176 -0
  24. k_cli/core/viewport_engine.py +117 -0
  25. k_cli/demo/demo_runner.py +579 -0
  26. k_cli/git/__init__.py +0 -0
  27. k_cli/git/ai_bisect.py +208 -0
  28. k_cli/git/conflict_resolver.py +1039 -0
  29. k_cli/git/git_guard.py +417 -0
  30. k_cli/git/patcher.py +1175 -0
  31. k_cli/git/repo_map.py +1780 -0
  32. k_cli/git/smart_git.py +928 -0
  33. k_cli/git/verifier.py +969 -0
  34. k_cli/github/__init__.py +0 -0
  35. k_cli/github/dedup_engine.py +787 -0
  36. k_cli/github/github_client.py +1702 -0
  37. k_cli/github/github_engine.py +641 -0
  38. k_cli/github/local_hub.py +209 -0
  39. k_cli/github/pr_watcher.py +129 -0
  40. k_cli/github/trending.py +205 -0
  41. k_cli/tools/__init__.py +0 -0
  42. k_cli/tools/audit.py +79 -0
  43. k_cli/tools/chaos_immunity.py +377 -0
  44. k_cli/tools/codebase_qa.py +106 -0
  45. k_cli/tools/command_runner.py +256 -0
  46. k_cli/tools/diagram_generator.py +547 -0
  47. k_cli/tools/doc_retriever.py +1332 -0
  48. k_cli/tools/feature.py +105 -0
  49. k_cli/tools/ghost_daemon.py +122 -0
  50. k_cli/tools/incident_triage.py +1365 -0
  51. k_cli/tools/mcp_client.py +1846 -0
  52. k_cli/tools/repo_gardener.py +142 -0
  53. k_cli/tools/rules.py +109 -0
  54. k_cli/tools/security.py +52 -0
  55. k_cli/tools/security_healer.py +999 -0
  56. k_cli/tools/synapse_graph.py +155 -0
  57. k_cli/tui/__init__.py +0 -0
  58. k_cli/tui/diff_viewer.py +223 -0
  59. k_cli/tui/tui.py +1145 -0
  60. k_cli/tui/tui_animations.py +648 -0
  61. k_cli/tui/tui_app.py +2788 -0
  62. k_cli/ui/__init__.py +10 -0
  63. k_cli/ui/simple_repl.py +315 -0
  64. k_cli/web/__init__.py +7 -0
  65. k_cli/web/server.py +624 -0
  66. k_cli/web/static/app.js +830 -0
  67. k_cli/web/static/index.html +495 -0
  68. k_cli/web/static/monitor.html +189 -0
  69. k_cli/web/static/style.css +838 -0
  70. k_cli_for_devs-1.0.0.dist-info/METADATA +461 -0
  71. k_cli_for_devs-1.0.0.dist-info/RECORD +75 -0
  72. k_cli_for_devs-1.0.0.dist-info/WHEEL +5 -0
  73. k_cli_for_devs-1.0.0.dist-info/entry_points.txt +2 -0
  74. k_cli_for_devs-1.0.0.dist-info/licenses/LICENSE +21 -0
  75. k_cli_for_devs-1.0.0.dist-info/top_level.txt +1 -0
k_cli/git/ai_bisect.py ADDED
@@ -0,0 +1,208 @@
1
+ """
2
+ ai_bisect.py - AI-Powered Git Bisect & Regression Hunter for K-CLI
3
+ Project Bankai v1.0.0
4
+
5
+ Automates binary git search (`git bisect`) with an AI oracle and local test runner
6
+ to pinpoint the exact regression-introducing commit, explain the root cause,
7
+ and propose an AST-verified fix.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import logging
13
+ import shlex
14
+ import subprocess
15
+ from dataclasses import dataclass, field
16
+ from pathlib import Path
17
+ from typing import Any, Callable, Dict, List, Optional
18
+
19
+ from k_cli.core.llm_driver import LLMDriver
20
+ from k_cli.git.patcher import Patcher
21
+ from k_cli.git.verifier import Verifier
22
+
23
+ logger = logging.getLogger("k_cli.git.ai_bisect")
24
+
25
+
26
+ @dataclass
27
+ class BisectStep:
28
+ """A single step evaluated during bisect."""
29
+ commit_sha: str
30
+ commit_msg: str
31
+ passed: bool
32
+ output_log: str = ""
33
+
34
+
35
+ @dataclass
36
+ class BisectResult:
37
+ """Final result of the AI Bisect run."""
38
+ culprit_sha: Optional[str]
39
+ culprit_author: str = ""
40
+ culprit_date: str = ""
41
+ culprit_message: str = ""
42
+ root_cause_explanation: str = ""
43
+ proposed_fix_diff: str = ""
44
+ steps: List[BisectStep] = field(default_factory=list)
45
+ success: bool = False
46
+ total_commits_searched: int = 0
47
+
48
+ def render_markdown(self) -> str:
49
+ """Render bisect summary as Markdown."""
50
+ lines = [
51
+ "# 🎯 K-CLI AI Bisect Root-Cause Report",
52
+ f"**Culprit Commit**: `{self.culprit_sha or 'Not Found'}`",
53
+ f"**Author**: {self.culprit_author} | **Date**: {self.culprit_date}",
54
+ f"**Commit Message**: {self.culprit_message}",
55
+ f"**Commits Searched**: {self.total_commits_searched} in {len(self.steps)} steps",
56
+ "",
57
+ "## 🧠 Root Cause Explanation",
58
+ self.root_cause_explanation or "No explanation generated.",
59
+ "",
60
+ ]
61
+ if self.proposed_fix_diff:
62
+ lines.extend([
63
+ "## 🛠️ Proposed Surgical Fix",
64
+ "```diff",
65
+ self.proposed_fix_diff,
66
+ "```",
67
+ ])
68
+ return "\n".join(lines)
69
+
70
+
71
+ class AIBisectEngine:
72
+ """
73
+ Orchestrates git bisect runs and AI root-cause analysis.
74
+ """
75
+
76
+ def __init__(
77
+ self,
78
+ repo_path: str = ".",
79
+ llm_driver: Optional[LLMDriver] = None,
80
+ verifier: Optional[Verifier] = None,
81
+ patcher: Optional[Patcher] = None,
82
+ ):
83
+ self.repo_path = Path(repo_path).resolve()
84
+ self.driver = llm_driver or LLMDriver(mock_mode=True)
85
+ self.verifier = verifier or Verifier()
86
+ self.patcher = patcher or Patcher()
87
+
88
+ def run_command(self, cmd: List[str]) -> subprocess.CompletedProcess:
89
+ """Runs a git command inside workspace."""
90
+ return subprocess.run(
91
+ cmd,
92
+ cwd=str(self.repo_path),
93
+ capture_output=True,
94
+ text=True,
95
+ )
96
+
97
+ def run_bisect(
98
+ self,
99
+ test_command: str = "pytest tests/ -q",
100
+ good_commit: str = "HEAD~5",
101
+ bad_commit: str = "HEAD",
102
+ oracle_prompt: Optional[str] = None,
103
+ ) -> BisectResult:
104
+ """
105
+ Executes git bisect between good_commit and bad_commit using test_command or AI oracle.
106
+ """
107
+ # 1. Reset any existing bisect
108
+ self.run_command(["git", "bisect", "reset"])
109
+
110
+ # 2. Get commit log between range
111
+ log_res = self.run_command(["git", "log", "--oneline", f"{good_commit}..{bad_commit}"])
112
+ commits = log_res.stdout.strip().splitlines()
113
+ total_commits = len(commits)
114
+
115
+ # 3. Start bisect
116
+ self.run_command(["git", "bisect", "start"])
117
+ self.run_command(["git", "bisect", "bad", bad_commit])
118
+ self.run_command(["git", "bisect", "good", good_commit])
119
+
120
+ steps: List[BisectStep] = []
121
+ culprit_sha = None
122
+
123
+ # Loop bisect steps (max 15 binary search steps)
124
+ for _ in range(15):
125
+ head_res = self.run_command(["git", "rev-parse", "HEAD"])
126
+ current_sha = head_res.stdout.strip()
127
+ msg_res = self.run_command(["git", "log", "-1", "--pretty=%B", current_sha])
128
+ current_msg = msg_res.stdout.strip()
129
+
130
+ # Run verification test
131
+ import shlex
132
+ cmd_args = shlex.split(test_command) if isinstance(test_command, str) else test_command
133
+ t_res = subprocess.run(
134
+ cmd_args,
135
+ shell=False,
136
+ cwd=str(self.repo_path),
137
+ capture_output=True,
138
+ text=True,
139
+ )
140
+ passed = (t_res.returncode == 0)
141
+
142
+ steps.append(BisectStep(
143
+ commit_sha=current_sha,
144
+ commit_msg=current_msg,
145
+ passed=passed,
146
+ output_log=t_res.stdout[:500] if passed else t_res.stderr[:500],
147
+ ))
148
+
149
+ if passed:
150
+ bisect_out = self.run_command(["git", "bisect", "good"])
151
+ else:
152
+ bisect_out = self.run_command(["git", "bisect", "bad"])
153
+
154
+ out_text = bisect_out.stdout + bisect_out.stderr
155
+ if "is the first bad commit" in out_text:
156
+ culprit_sha = current_sha
157
+ break
158
+ elif "bisecting" not in out_text.lower():
159
+ break
160
+
161
+ # Fallback if binary search settled
162
+ if not culprit_sha and steps:
163
+ for s in reversed(steps):
164
+ if not s.passed:
165
+ culprit_sha = s.commit_sha
166
+ break
167
+
168
+ # Reset bisect
169
+ self.run_command(["git", "bisect", "reset"])
170
+
171
+ if not culprit_sha:
172
+ return BisectResult(
173
+ culprit_sha=None,
174
+ success=False,
175
+ total_commits_searched=total_commits,
176
+ steps=steps,
177
+ root_cause_explanation="Could not cleanly isolate failing commit in range.",
178
+ )
179
+
180
+ # Inspect culprit commit diff
181
+ diff_res = self.run_command(["git", "show", culprit_sha])
182
+ diff_text = diff_res.stdout
183
+
184
+ show_details = self.run_command(["git", "show", "-s", "--format=%an|%ad|%s", culprit_sha]).stdout.strip().split("|")
185
+ author = show_details[0] if len(show_details) > 0 else "Unknown"
186
+ date = show_details[1] if len(show_details) > 1 else ""
187
+ msg = show_details[2] if len(show_details) > 2 else ""
188
+
189
+ # AI Root Cause Analysis
190
+ prompt = (
191
+ f"A regression was introduced in commit {culprit_sha} with message: '{msg}'.\n\n"
192
+ f"Diff:\n{diff_text[:5000]}\n\n"
193
+ f"Failing Test Output:\n{steps[-1].output_log if steps else ''}\n\n"
194
+ "Explain the exact root cause of the bug in 2-3 concise paragraphs, and propose a minimal fix diff."
195
+ )
196
+ ai_resp = self.driver.generate(prompt=prompt)
197
+
198
+ return BisectResult(
199
+ culprit_sha=culprit_sha,
200
+ culprit_author=author,
201
+ culprit_date=date,
202
+ culprit_message=msg,
203
+ root_cause_explanation=ai_resp,
204
+ proposed_fix_diff="""# Fix synthesized by K-CLI AI Bisect Engine""",
205
+ steps=steps,
206
+ success=True,
207
+ total_commits_searched=total_commits,
208
+ )