makima-cli 0.1.0__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.
- makima_cli-0.1.0/PKG-INFO +54 -0
- makima_cli-0.1.0/README.md +42 -0
- makima_cli-0.1.0/makima/__init__.py +0 -0
- makima_cli-0.1.0/makima/config.py +13 -0
- makima_cli-0.1.0/makima/core/__init__.py +0 -0
- makima_cli-0.1.0/makima/core/agent.py +133 -0
- makima_cli-0.1.0/makima/core/context.py +47 -0
- makima_cli-0.1.0/makima/core/memory.py +23 -0
- makima_cli-0.1.0/makima/main.py +8 -0
- makima_cli-0.1.0/makima/providers/base.py +7 -0
- makima_cli-0.1.0/makima/providers/groq_provider.py +25 -0
- makima_cli-0.1.0/makima/tools/__init__.py +10 -0
- makima_cli-0.1.0/makima/tools/file_tools.py +65 -0
- makima_cli-0.1.0/makima/tools/registry.py +67 -0
- makima_cli-0.1.0/makima/tools/shell_tools.py +20 -0
- makima_cli-0.1.0/makima_cli.egg-info/PKG-INFO +54 -0
- makima_cli-0.1.0/makima_cli.egg-info/SOURCES.txt +21 -0
- makima_cli-0.1.0/makima_cli.egg-info/dependency_links.txt +1 -0
- makima_cli-0.1.0/makima_cli.egg-info/entry_points.txt +2 -0
- makima_cli-0.1.0/makima_cli.egg-info/requires.txt +5 -0
- makima_cli-0.1.0/makima_cli.egg-info/top_level.txt +1 -0
- makima_cli-0.1.0/pyproject.toml +25 -0
- makima_cli-0.1.0/setup.cfg +4 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: makima-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: AI coding assistant for your terminal
|
|
5
|
+
Requires-Python: >=3.10
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: groq
|
|
8
|
+
Requires-Dist: python-dotenv
|
|
9
|
+
Requires-Dist: gitpython
|
|
10
|
+
Requires-Dist: rich
|
|
11
|
+
Requires-Dist: pyfiglet
|
|
12
|
+
|
|
13
|
+
# Makima CLI 🤖
|
|
14
|
+
|
|
15
|
+
An AI-powered coding assistant that runs in your terminal. Point it at any codebase and ask questions, make edits, and run commands — all from a clean CLI interface.
|
|
16
|
+
|
|
17
|
+
## Features
|
|
18
|
+
|
|
19
|
+
- Understands your entire codebase
|
|
20
|
+
- Answers questions about your code
|
|
21
|
+
- Edits files with auto git backup before changes
|
|
22
|
+
- Creates new files
|
|
23
|
+
- Runs terminal commands with confirmation
|
|
24
|
+
- Works on any project
|
|
25
|
+
- Clean terminal UI with syntax highlighting
|
|
26
|
+
|
|
27
|
+
## Install
|
|
28
|
+
|
|
29
|
+
git clone https://github.com/yourusername/makima-cli.git
|
|
30
|
+
cd makima-cli
|
|
31
|
+
pip install -r requirements.txt
|
|
32
|
+
|
|
33
|
+
## Setup
|
|
34
|
+
|
|
35
|
+
Create a .env file in the project root:
|
|
36
|
+
GROQ_API_KEY=your_key_here
|
|
37
|
+
|
|
38
|
+
Get a free API key at https://console.groq.com
|
|
39
|
+
|
|
40
|
+
## Usage
|
|
41
|
+
|
|
42
|
+
Point it at any project:
|
|
43
|
+
python main.py /path/to/your/project
|
|
44
|
+
|
|
45
|
+
Or run from inside a project folder:
|
|
46
|
+
cd your-project
|
|
47
|
+
python /path/to/makima-cli/main.py
|
|
48
|
+
|
|
49
|
+
## Built With
|
|
50
|
+
|
|
51
|
+
- Python
|
|
52
|
+
- Groq API
|
|
53
|
+
- Rich
|
|
54
|
+
- GitPython
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Makima CLI 🤖
|
|
2
|
+
|
|
3
|
+
An AI-powered coding assistant that runs in your terminal. Point it at any codebase and ask questions, make edits, and run commands — all from a clean CLI interface.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Understands your entire codebase
|
|
8
|
+
- Answers questions about your code
|
|
9
|
+
- Edits files with auto git backup before changes
|
|
10
|
+
- Creates new files
|
|
11
|
+
- Runs terminal commands with confirmation
|
|
12
|
+
- Works on any project
|
|
13
|
+
- Clean terminal UI with syntax highlighting
|
|
14
|
+
|
|
15
|
+
## Install
|
|
16
|
+
|
|
17
|
+
git clone https://github.com/yourusername/makima-cli.git
|
|
18
|
+
cd makima-cli
|
|
19
|
+
pip install -r requirements.txt
|
|
20
|
+
|
|
21
|
+
## Setup
|
|
22
|
+
|
|
23
|
+
Create a .env file in the project root:
|
|
24
|
+
GROQ_API_KEY=your_key_here
|
|
25
|
+
|
|
26
|
+
Get a free API key at https://console.groq.com
|
|
27
|
+
|
|
28
|
+
## Usage
|
|
29
|
+
|
|
30
|
+
Point it at any project:
|
|
31
|
+
python main.py /path/to/your/project
|
|
32
|
+
|
|
33
|
+
Or run from inside a project folder:
|
|
34
|
+
cd your-project
|
|
35
|
+
python /path/to/makima-cli/main.py
|
|
36
|
+
|
|
37
|
+
## Built With
|
|
38
|
+
|
|
39
|
+
- Python
|
|
40
|
+
- Groq API
|
|
41
|
+
- Rich
|
|
42
|
+
- GitPython
|
|
File without changes
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
from dotenv import load_dotenv
|
|
4
|
+
load_dotenv()
|
|
5
|
+
|
|
6
|
+
GROQ_API_KEY = os.getenv("GROQ_API_KEY")
|
|
7
|
+
MODEL_NAME = "qwen/qwen3.6-27b"
|
|
8
|
+
TOKEN_LIMIT = 10000
|
|
9
|
+
# PROJECT_ROOT = os.getcwd()
|
|
10
|
+
PROJECT_ROOT = sys.argv[1] if len(sys.argv) > 1 else os.getcwd()
|
|
11
|
+
|
|
12
|
+
if not GROQ_API_KEY:
|
|
13
|
+
raise ValueError("GROQ_API_KEY not set in .env file")
|
|
File without changes
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from makima.config import PROJECT_ROOT,MODEL_NAME
|
|
3
|
+
from makima.core.context import ContextManager
|
|
4
|
+
from makima.core.memory import Memory
|
|
5
|
+
from makima.tools import TOOL_REGISTRY
|
|
6
|
+
from makima.tools.registry import TOOL_SCHEMAS
|
|
7
|
+
from makima.providers.groq_provider import GroqProvider
|
|
8
|
+
from rich.console import Console
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
console = Console()
|
|
12
|
+
|
|
13
|
+
ctx = ContextManager()
|
|
14
|
+
context = ctx.build_context()
|
|
15
|
+
|
|
16
|
+
SYSTEM_PROMPT = f"""
|
|
17
|
+
You are a coding assistant. The project is at: {PROJECT_ROOT}
|
|
18
|
+
|
|
19
|
+
Rules:
|
|
20
|
+
- Always use list_files first to find exact paths
|
|
21
|
+
- Always use read_file before editing any file
|
|
22
|
+
- Use full absolute paths always
|
|
23
|
+
- Be concise and direct
|
|
24
|
+
- old_str must be an exact match of multiple lines from the file
|
|
25
|
+
- Never explain what you are about to do. Never say "Let me..." or "I'll first...".
|
|
26
|
+
- Just call the tool immediately and silently.
|
|
27
|
+
- Only speak in plain text when you have a FINAL answer for the user.
|
|
28
|
+
- Call only ONE tool per response. Wait for the tool result before calling the next tool.
|
|
29
|
+
- Never output multiple tool calls in one response.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
import pyfiglet
|
|
33
|
+
from rich.panel import Panel
|
|
34
|
+
from rich.text import Text
|
|
35
|
+
from rich.rule import Rule
|
|
36
|
+
from rich.markdown import Markdown
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def run_agent():
|
|
40
|
+
provider = GroqProvider()
|
|
41
|
+
memory = Memory(system_prompt=SYSTEM_PROMPT)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
ascii_art = pyfiglet.figlet_format("Makima", font="big")
|
|
45
|
+
console.print(f"[bold #FF6B35]{ascii_art}[/]")
|
|
46
|
+
|
|
47
|
+
# info line underneath, no box
|
|
48
|
+
console.print(f"[dim] Your AI Coding Assistant[/]")
|
|
49
|
+
console.print(f"[green] Project :[/] {PROJECT_ROOT}")
|
|
50
|
+
console.print(f"[green] Files :[/] {len(ctx.files)} files loaded")
|
|
51
|
+
console.print(f"[green] Model :[/] {MODEL_NAME}")
|
|
52
|
+
console.print(f"[dim] Type 'exit' to quit[/]")
|
|
53
|
+
console.print(Rule(style="#FF6B35")) # clean horizontal line separator
|
|
54
|
+
console.print()
|
|
55
|
+
|
|
56
|
+
while True:
|
|
57
|
+
user_input = console.input("[bold blue]You:[/] ")
|
|
58
|
+
if user_input.strip() == "exit":
|
|
59
|
+
break
|
|
60
|
+
|
|
61
|
+
memory.add_user(user_input)
|
|
62
|
+
|
|
63
|
+
while True:
|
|
64
|
+
try:
|
|
65
|
+
with console.status("[yellow]thinking...[/]"):
|
|
66
|
+
stream = provider.stream_chat(
|
|
67
|
+
messages=memory.get(),
|
|
68
|
+
tools=TOOL_SCHEMAS
|
|
69
|
+
)
|
|
70
|
+
chunks = list(stream)
|
|
71
|
+
except Exception as e:
|
|
72
|
+
console.print(f"[red]Error: {e}[/]")
|
|
73
|
+
break
|
|
74
|
+
|
|
75
|
+
#variables to collect the response
|
|
76
|
+
text_buffer = ""
|
|
77
|
+
tool_name = ""
|
|
78
|
+
tool_args = ""
|
|
79
|
+
tool_call_id = ""
|
|
80
|
+
is_tool_call = False
|
|
81
|
+
|
|
82
|
+
# console.print("[bold green]Agent:[/] ", end="")
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
for chunk in chunks:
|
|
86
|
+
delta = chunk.choices[0].delta
|
|
87
|
+
|
|
88
|
+
#text chunk
|
|
89
|
+
if delta.content:
|
|
90
|
+
# print(delta.content, end="", flush=True)
|
|
91
|
+
text_buffer += delta.content
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
# tool call chunk
|
|
95
|
+
if delta.tool_calls:
|
|
96
|
+
is_tool_call = True
|
|
97
|
+
tc = delta.tool_calls[0]
|
|
98
|
+
if tc.id:
|
|
99
|
+
tool_call_id = tc.id
|
|
100
|
+
if tc.function.name:
|
|
101
|
+
tool_name += tc.function.name
|
|
102
|
+
if tc.function.arguments:
|
|
103
|
+
tool_args += tc.function.arguments
|
|
104
|
+
|
|
105
|
+
# print()
|
|
106
|
+
|
|
107
|
+
if is_tool_call:
|
|
108
|
+
console.print(f"[dim]âš¡ {tool_name}[/]")
|
|
109
|
+
|
|
110
|
+
with console.status(f"[yellow]calling {tool_name}...[/]"):
|
|
111
|
+
args = json.loads(tool_args)
|
|
112
|
+
tool_fn = TOOL_REGISTRY.get(tool_name)
|
|
113
|
+
result = tool_fn(**args) if tool_fn else "Unknown tool"
|
|
114
|
+
|
|
115
|
+
# build the assistant message manually for memory
|
|
116
|
+
memory.add_raw({
|
|
117
|
+
"role": "assistant",
|
|
118
|
+
"tool_calls": [{
|
|
119
|
+
"id": tool_call_id,
|
|
120
|
+
"type": "function",
|
|
121
|
+
"function": {
|
|
122
|
+
"name": tool_name,
|
|
123
|
+
"arguments": tool_args
|
|
124
|
+
}
|
|
125
|
+
}]
|
|
126
|
+
})
|
|
127
|
+
memory.add_tool_result(tool_call_id, str(result))
|
|
128
|
+
|
|
129
|
+
else:
|
|
130
|
+
console.print("[bold green]Agent:[/]")
|
|
131
|
+
console.print(Markdown(text_buffer))
|
|
132
|
+
memory.add_assistant(text_buffer)
|
|
133
|
+
break
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
from makima.config import PROJECT_ROOT,TOKEN_LIMIT
|
|
2
|
+
from makima.tools.file_tools import read_file,list_files
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ContextManager:
|
|
7
|
+
def __init__(self):
|
|
8
|
+
self.files = []
|
|
9
|
+
self.total_tokens = 0
|
|
10
|
+
self.scan_files()
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def scan_files(self):
|
|
14
|
+
skip = {"__pycache__", ".git", "node_modules", ".env",".venv"}
|
|
15
|
+
skip_ext = {".pyc", ".png", ".jpg", ".jpeg", ".gif", ".ico"}
|
|
16
|
+
self.files = []
|
|
17
|
+
|
|
18
|
+
for folder, subfolders, files in os.walk(PROJECT_ROOT):
|
|
19
|
+
subfolders[:] = [f for f in subfolders if f not in skip]
|
|
20
|
+
|
|
21
|
+
for file in files:
|
|
22
|
+
|
|
23
|
+
if any(file.endswith(ext) for ext in skip_ext):
|
|
24
|
+
continue
|
|
25
|
+
file_path = os.path.join(folder,file)
|
|
26
|
+
self.files.append(file_path)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def count_tokens(self,text):
|
|
30
|
+
return len(text) // 4
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def build_context(self):
|
|
34
|
+
|
|
35
|
+
context = ""
|
|
36
|
+
|
|
37
|
+
for file in self.files:
|
|
38
|
+
content = read_file(file)
|
|
39
|
+
|
|
40
|
+
self.total_tokens += self.count_tokens(content)
|
|
41
|
+
|
|
42
|
+
if self.total_tokens > TOKEN_LIMIT:
|
|
43
|
+
return "TOO LARGE CONTEXT"
|
|
44
|
+
else:
|
|
45
|
+
context += f"\n--- {file} ---\n{content}\n"
|
|
46
|
+
|
|
47
|
+
return context
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
class Memory:
|
|
2
|
+
|
|
3
|
+
def __init__(self, system_prompt: str):
|
|
4
|
+
self.messages = [{"role": "system", "content": system_prompt}]
|
|
5
|
+
|
|
6
|
+
def add_user(self, text: str):
|
|
7
|
+
self.messages.append({"role": "user", "content": text})
|
|
8
|
+
|
|
9
|
+
def add_assistant(self, text: str):
|
|
10
|
+
self.messages.append({"role": "assistant", "content": text})
|
|
11
|
+
|
|
12
|
+
def add_tool_result(self, tool_call_id: str, content: str):
|
|
13
|
+
self.messages.append({
|
|
14
|
+
"role": "tool",
|
|
15
|
+
"tool_call_id": tool_call_id,
|
|
16
|
+
"content": content
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
def add_raw(self, message):
|
|
20
|
+
self.messages.append(message)
|
|
21
|
+
|
|
22
|
+
def get(self) -> list:
|
|
23
|
+
return self.messages
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from groq import Groq
|
|
2
|
+
from makima.providers.base import LLMProvider
|
|
3
|
+
from makima.config import GROQ_API_KEY, MODEL_NAME
|
|
4
|
+
|
|
5
|
+
class GroqProvider(LLMProvider):
|
|
6
|
+
|
|
7
|
+
def __init__(self):
|
|
8
|
+
self.client = Groq(api_key=GROQ_API_KEY)
|
|
9
|
+
|
|
10
|
+
def chat(self, messages: list, tools: list) -> object:
|
|
11
|
+
return self.client.chat.completions.create(
|
|
12
|
+
model=MODEL_NAME,
|
|
13
|
+
messages=messages,
|
|
14
|
+
tools=tools,
|
|
15
|
+
max_tokens=1024
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
def stream_chat(self, messages: list, tools: list):
|
|
19
|
+
return self.client.chat.completions.create(
|
|
20
|
+
model=MODEL_NAME,
|
|
21
|
+
messages=messages,
|
|
22
|
+
tools=tools,
|
|
23
|
+
max_tokens=1024,
|
|
24
|
+
stream=True
|
|
25
|
+
)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
from makima.tools.file_tools import read_file, list_files, edit_file, create_file
|
|
2
|
+
from makima.tools.shell_tools import run_command
|
|
3
|
+
|
|
4
|
+
TOOL_REGISTRY = {
|
|
5
|
+
"read_file": read_file,
|
|
6
|
+
"list_files": list_files,
|
|
7
|
+
"edit_file": edit_file,
|
|
8
|
+
"run_command": run_command,
|
|
9
|
+
"create_file": create_file,
|
|
10
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
from makima.config import PROJECT_ROOT
|
|
2
|
+
import os
|
|
3
|
+
import git
|
|
4
|
+
|
|
5
|
+
def read_file(path):
|
|
6
|
+
if not os.path.exists(path):
|
|
7
|
+
path = os.path.join(PROJECT_ROOT, path)
|
|
8
|
+
try:
|
|
9
|
+
with open(path, "r") as content:
|
|
10
|
+
return content.read()
|
|
11
|
+
except Exception as e:
|
|
12
|
+
return f"There is an Error while Reading your files. Error - {e}"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def list_files():
|
|
16
|
+
skip = {"__pycache__", ".git", "node_modules", ".env",".venv"}
|
|
17
|
+
output = []
|
|
18
|
+
|
|
19
|
+
for folder, subfolders, files in os.walk(PROJECT_ROOT):
|
|
20
|
+
|
|
21
|
+
subfolders[:] = [f for f in subfolders if f not in skip]
|
|
22
|
+
|
|
23
|
+
output.append(folder)
|
|
24
|
+
for file in files:
|
|
25
|
+
output.append(" " + file)
|
|
26
|
+
|
|
27
|
+
return "\n".join(output)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def edit_file(path, old_str, new_str):
|
|
31
|
+
auto_commit(path)
|
|
32
|
+
|
|
33
|
+
if not os.path.exists(path):
|
|
34
|
+
path = os.path.join(PROJECT_ROOT,path)
|
|
35
|
+
|
|
36
|
+
readed_content = read_file(path)
|
|
37
|
+
if old_str in readed_content:
|
|
38
|
+
new_contents = readed_content.replace(old_str,new_str,1)
|
|
39
|
+
else:
|
|
40
|
+
return f"content that i tried to change is missing"
|
|
41
|
+
|
|
42
|
+
with open(path,"w") as f:
|
|
43
|
+
f.write(new_contents)
|
|
44
|
+
return f"Done. Edited {path}"
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def create_file(path, content):
|
|
49
|
+
if os.path.exists(path):
|
|
50
|
+
return f"File already exists: {path}"
|
|
51
|
+
|
|
52
|
+
os.makedirs(os.path.dirname(path), exist_ok=True)
|
|
53
|
+
|
|
54
|
+
with open(path, "w") as f:
|
|
55
|
+
f.write(content)
|
|
56
|
+
return f"Created path: {path}"
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def auto_commit(path):
|
|
60
|
+
try:
|
|
61
|
+
repo = git.Repo(PROJECT_ROOT)
|
|
62
|
+
repo.git.add(path)
|
|
63
|
+
repo.index.commit(f"auto-backup before edit: {path}")
|
|
64
|
+
except Exception as e:
|
|
65
|
+
pass
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
TOOL_SCHEMAS = [
|
|
2
|
+
{
|
|
3
|
+
"type": "function",
|
|
4
|
+
"function": {
|
|
5
|
+
"name": "read_file",
|
|
6
|
+
"description": "Read a file and return its contents",
|
|
7
|
+
"parameters": {
|
|
8
|
+
"type": "object",
|
|
9
|
+
"properties": {
|
|
10
|
+
"path": {"type": "string", "description": "Full absolute path to the file"}
|
|
11
|
+
},
|
|
12
|
+
"required": ["path"]
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"type": "function",
|
|
18
|
+
"function": {
|
|
19
|
+
"name": "list_files",
|
|
20
|
+
"description": "List all files in the project",
|
|
21
|
+
"parameters": {"type": "object", "properties": {}}
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"type": "function",
|
|
26
|
+
"function": {
|
|
27
|
+
"name": "edit_file",
|
|
28
|
+
"description": "Edit a file by replacing old_str with new_str",
|
|
29
|
+
"parameters": {
|
|
30
|
+
"type": "object",
|
|
31
|
+
"properties": {
|
|
32
|
+
"path": {"type": "string"},
|
|
33
|
+
"old_str": {"type": "string"},
|
|
34
|
+
"new_str": {"type": "string"}
|
|
35
|
+
},
|
|
36
|
+
"required": ["path", "old_str", "new_str"]
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"type": "function",
|
|
42
|
+
"function": {
|
|
43
|
+
"name": "run_command",
|
|
44
|
+
"description": "Run a terminal command and return output",
|
|
45
|
+
"parameters": {
|
|
46
|
+
"type": "object",
|
|
47
|
+
"properties": {"cmd": {"type": "string"}},
|
|
48
|
+
"required": ["cmd"]
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"type": "function",
|
|
54
|
+
"function": {
|
|
55
|
+
"name": "create_file",
|
|
56
|
+
"description": "Create a new file with given content",
|
|
57
|
+
"parameters": {
|
|
58
|
+
"type": "object",
|
|
59
|
+
"properties": {
|
|
60
|
+
"path": {"type": "string"},
|
|
61
|
+
"content": {"type": "string"}
|
|
62
|
+
},
|
|
63
|
+
"required": ["path", "content"]
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
]
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def run_command(cmd):
|
|
5
|
+
print(f"Commands going to Run: {cmd}")
|
|
6
|
+
User_answer = input("Run This? (Y/N): ")
|
|
7
|
+
User_answer = User_answer.lower()
|
|
8
|
+
|
|
9
|
+
if User_answer != "y":
|
|
10
|
+
return "Command cancelled"
|
|
11
|
+
|
|
12
|
+
result = subprocess.run(
|
|
13
|
+
cmd,
|
|
14
|
+
shell=True,
|
|
15
|
+
capture_output=True,
|
|
16
|
+
text=True,
|
|
17
|
+
timeout=30
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
return result.stdout + result.stderr
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: makima-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: AI coding assistant for your terminal
|
|
5
|
+
Requires-Python: >=3.10
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: groq
|
|
8
|
+
Requires-Dist: python-dotenv
|
|
9
|
+
Requires-Dist: gitpython
|
|
10
|
+
Requires-Dist: rich
|
|
11
|
+
Requires-Dist: pyfiglet
|
|
12
|
+
|
|
13
|
+
# Makima CLI 🤖
|
|
14
|
+
|
|
15
|
+
An AI-powered coding assistant that runs in your terminal. Point it at any codebase and ask questions, make edits, and run commands — all from a clean CLI interface.
|
|
16
|
+
|
|
17
|
+
## Features
|
|
18
|
+
|
|
19
|
+
- Understands your entire codebase
|
|
20
|
+
- Answers questions about your code
|
|
21
|
+
- Edits files with auto git backup before changes
|
|
22
|
+
- Creates new files
|
|
23
|
+
- Runs terminal commands with confirmation
|
|
24
|
+
- Works on any project
|
|
25
|
+
- Clean terminal UI with syntax highlighting
|
|
26
|
+
|
|
27
|
+
## Install
|
|
28
|
+
|
|
29
|
+
git clone https://github.com/yourusername/makima-cli.git
|
|
30
|
+
cd makima-cli
|
|
31
|
+
pip install -r requirements.txt
|
|
32
|
+
|
|
33
|
+
## Setup
|
|
34
|
+
|
|
35
|
+
Create a .env file in the project root:
|
|
36
|
+
GROQ_API_KEY=your_key_here
|
|
37
|
+
|
|
38
|
+
Get a free API key at https://console.groq.com
|
|
39
|
+
|
|
40
|
+
## Usage
|
|
41
|
+
|
|
42
|
+
Point it at any project:
|
|
43
|
+
python main.py /path/to/your/project
|
|
44
|
+
|
|
45
|
+
Or run from inside a project folder:
|
|
46
|
+
cd your-project
|
|
47
|
+
python /path/to/makima-cli/main.py
|
|
48
|
+
|
|
49
|
+
## Built With
|
|
50
|
+
|
|
51
|
+
- Python
|
|
52
|
+
- Groq API
|
|
53
|
+
- Rich
|
|
54
|
+
- GitPython
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
makima/__init__.py
|
|
4
|
+
makima/config.py
|
|
5
|
+
makima/main.py
|
|
6
|
+
makima/core/__init__.py
|
|
7
|
+
makima/core/agent.py
|
|
8
|
+
makima/core/context.py
|
|
9
|
+
makima/core/memory.py
|
|
10
|
+
makima/providers/base.py
|
|
11
|
+
makima/providers/groq_provider.py
|
|
12
|
+
makima/tools/__init__.py
|
|
13
|
+
makima/tools/file_tools.py
|
|
14
|
+
makima/tools/registry.py
|
|
15
|
+
makima/tools/shell_tools.py
|
|
16
|
+
makima_cli.egg-info/PKG-INFO
|
|
17
|
+
makima_cli.egg-info/SOURCES.txt
|
|
18
|
+
makima_cli.egg-info/dependency_links.txt
|
|
19
|
+
makima_cli.egg-info/entry_points.txt
|
|
20
|
+
makima_cli.egg-info/requires.txt
|
|
21
|
+
makima_cli.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
makima
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "makima-cli"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "AI coding assistant for your terminal"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = {file = "LICENSE"}
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
dependencies = [
|
|
13
|
+
"groq",
|
|
14
|
+
"python-dotenv",
|
|
15
|
+
"gitpython",
|
|
16
|
+
"rich",
|
|
17
|
+
"pyfiglet",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
[project.scripts]
|
|
21
|
+
makima = "makima.main:main"
|
|
22
|
+
|
|
23
|
+
[tool.setuptools.packages.find]
|
|
24
|
+
where = ["."]
|
|
25
|
+
include = ["makima*"]
|