alpiecode 6.2.0__tar.gz → 7.0.1__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 (42) hide show
  1. {alpiecode-6.2.0 → alpiecode-7.0.1}/PKG-INFO +1 -1
  2. {alpiecode-6.2.0 → alpiecode-7.0.1}/pyproject.toml +1 -1
  3. {alpiecode-6.2.0 → alpiecode-7.0.1}/src/alpiecode.egg-info/PKG-INFO +1 -1
  4. {alpiecode-6.2.0 → alpiecode-7.0.1}/src/codeagent/__init__.py +1 -1
  5. {alpiecode-6.2.0 → alpiecode-7.0.1}/src/codeagent/extension/alpiecode.vsix +0 -0
  6. alpiecode-7.0.1/src/codeagent/ipython_ext.py +327 -0
  7. {alpiecode-6.2.0 → alpiecode-7.0.1}/src/codeagent/vscode_installer.py +12 -1
  8. alpiecode-6.2.0/src/codeagent/ipython_ext.py +0 -156
  9. {alpiecode-6.2.0 → alpiecode-7.0.1}/README.md +0 -0
  10. {alpiecode-6.2.0 → alpiecode-7.0.1}/setup.cfg +0 -0
  11. {alpiecode-6.2.0 → alpiecode-7.0.1}/src/alpiecode/__init__.py +0 -0
  12. {alpiecode-6.2.0 → alpiecode-7.0.1}/src/alpiecode.egg-info/SOURCES.txt +0 -0
  13. {alpiecode-6.2.0 → alpiecode-7.0.1}/src/alpiecode.egg-info/dependency_links.txt +0 -0
  14. {alpiecode-6.2.0 → alpiecode-7.0.1}/src/alpiecode.egg-info/entry_points.txt +0 -0
  15. {alpiecode-6.2.0 → alpiecode-7.0.1}/src/alpiecode.egg-info/requires.txt +0 -0
  16. {alpiecode-6.2.0 → alpiecode-7.0.1}/src/alpiecode.egg-info/top_level.txt +0 -0
  17. {alpiecode-6.2.0 → alpiecode-7.0.1}/src/codeagent/agent.py +0 -0
  18. {alpiecode-6.2.0 → alpiecode-7.0.1}/src/codeagent/backends/__init__.py +0 -0
  19. {alpiecode-6.2.0 → alpiecode-7.0.1}/src/codeagent/backends/base.py +0 -0
  20. {alpiecode-6.2.0 → alpiecode-7.0.1}/src/codeagent/backends/local_backend.py +0 -0
  21. {alpiecode-6.2.0 → alpiecode-7.0.1}/src/codeagent/backends/openai_backend.py +0 -0
  22. {alpiecode-6.2.0 → alpiecode-7.0.1}/src/codeagent/cache.py +0 -0
  23. {alpiecode-6.2.0 → alpiecode-7.0.1}/src/codeagent/cli.py +0 -0
  24. {alpiecode-6.2.0 → alpiecode-7.0.1}/src/codeagent/client.py +0 -0
  25. {alpiecode-6.2.0 → alpiecode-7.0.1}/src/codeagent/compaction.py +0 -0
  26. {alpiecode-6.2.0 → alpiecode-7.0.1}/src/codeagent/config.py +0 -0
  27. {alpiecode-6.2.0 → alpiecode-7.0.1}/src/codeagent/context.py +0 -0
  28. {alpiecode-6.2.0 → alpiecode-7.0.1}/src/codeagent/discovery.py +0 -0
  29. {alpiecode-6.2.0 → alpiecode-7.0.1}/src/codeagent/doctor.py +0 -0
  30. {alpiecode-6.2.0 → alpiecode-7.0.1}/src/codeagent/executor.py +0 -0
  31. {alpiecode-6.2.0 → alpiecode-7.0.1}/src/codeagent/github.py +0 -0
  32. {alpiecode-6.2.0 → alpiecode-7.0.1}/src/codeagent/guardian.py +0 -0
  33. {alpiecode-6.2.0 → alpiecode-7.0.1}/src/codeagent/local_model.py +0 -0
  34. {alpiecode-6.2.0 → alpiecode-7.0.1}/src/codeagent/media.py +0 -0
  35. {alpiecode-6.2.0 → alpiecode-7.0.1}/src/codeagent/memory.py +0 -0
  36. {alpiecode-6.2.0 → alpiecode-7.0.1}/src/codeagent/orchestrator.py +0 -0
  37. {alpiecode-6.2.0 → alpiecode-7.0.1}/src/codeagent/progress.py +0 -0
  38. {alpiecode-6.2.0 → alpiecode-7.0.1}/src/codeagent/prompt.py +0 -0
  39. {alpiecode-6.2.0 → alpiecode-7.0.1}/src/codeagent/server.py +0 -0
  40. {alpiecode-6.2.0 → alpiecode-7.0.1}/src/codeagent/session.py +0 -0
  41. {alpiecode-6.2.0 → alpiecode-7.0.1}/src/codeagent/tools.py +0 -0
  42. {alpiecode-6.2.0 → alpiecode-7.0.1}/src/codeagent/updater.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: alpiecode
3
- Version: 6.2.0
3
+ Version: 7.0.1
4
4
  Summary: AlpieCode — Autonomous AI Coding Agent CLI powered by local 169Pi GGUF VLM
5
5
  Requires-Python: >=3.9
6
6
  Requires-Dist: huggingface_hub>=0.20.0
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "alpiecode"
7
- version = "6.2.0"
7
+ version = "7.0.1"
8
8
  description = "AlpieCode — Autonomous AI Coding Agent CLI powered by local 169Pi GGUF VLM"
9
9
  requires-python = ">=3.9"
10
10
  dependencies = [
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: alpiecode
3
- Version: 6.2.0
3
+ Version: 7.0.1
4
4
  Summary: AlpieCode — Autonomous AI Coding Agent CLI powered by local 169Pi GGUF VLM
5
5
  Requires-Python: >=3.9
6
6
  Requires-Dist: huggingface_hub>=0.20.0
@@ -16,7 +16,7 @@ Supports:
16
16
  from pathlib import Path
17
17
  from typing import Optional, Any, Dict
18
18
 
19
- __version__ = "6.1.0"
19
+ __version__ = "7.0.0"
20
20
 
21
21
 
22
22
  def run(task: str, workdir: str = ".", reasoning_level: str = "medium", **kwargs):
@@ -0,0 +1,327 @@
1
+ """
2
+ IPython & Jupyter / Google Colab extension for AlpieCode.
3
+
4
+ Enables seamless usage of AlpieCode inside Jupyter Notebooks, JupyterLab,
5
+ and Google Colab via cell/line magic commands and rich interactive displays:
6
+
7
+ %load_ext alpiecode
8
+ %alpie write a quick pandas script to inspect data.csv
9
+ %%alpie
10
+ Create a complete PyTorch model training pipeline.
11
+ """
12
+
13
+ import html
14
+ import re
15
+ import sys
16
+ import warnings
17
+ from pathlib import Path
18
+ from typing import Optional, List, Dict, Any
19
+
20
+ # Suppress noisy Jupyter / Python 3.12+ deprecation warnings
21
+ warnings.filterwarnings("ignore", category=DeprecationWarning)
22
+ warnings.filterwarnings("ignore", category=FutureWarning)
23
+ warnings.filterwarnings("ignore", module="jupyter_client.*")
24
+ warnings.filterwarnings("ignore", module="ipykernel.*")
25
+
26
+ from .config import load_config
27
+ from .orchestrator import AgentOrchestrator, AgentEvent, resolve_backend
28
+ from .session import SessionManager
29
+ from .agent import run_agent
30
+
31
+
32
+ def _is_notebook() -> bool:
33
+ """Check if code is running inside a web browser notebook (Jupyter, Colab, VS Code Notebook)."""
34
+ try:
35
+ from IPython import get_ipython
36
+ shell = get_ipython()
37
+ if shell is None:
38
+ return False
39
+ shell_name = shell.__class__.__name__
40
+ if "TerminalInteractiveShell" in shell_name:
41
+ return False
42
+ if "ZMQInteractiveShell" in shell_name or hasattr(shell, "kernel") or "google.colab" in sys.modules:
43
+ return True
44
+ return False
45
+ except Exception:
46
+ return False
47
+
48
+
49
+ def _display_html(html_str: str):
50
+ """Render rich HTML in Jupyter or Google Colab."""
51
+ try:
52
+ from IPython.display import HTML, display
53
+ display(HTML(html_str))
54
+ except Exception:
55
+ print(html_str)
56
+
57
+
58
+ def _display_markdown(md_str: str):
59
+ """Render rich Markdown in Jupyter or Google Colab."""
60
+ try:
61
+ from IPython.display import Markdown, display
62
+ display(Markdown(md_str))
63
+ except Exception:
64
+ print(md_str)
65
+
66
+
67
+ def _get_notebook_context() -> str:
68
+ """Inspect active user variables in the notebook session (DataFrames, tensors, etc.)."""
69
+ try:
70
+ from IPython import get_ipython
71
+ ip = get_ipython()
72
+ if not ip or not hasattr(ip, "user_ns"):
73
+ return ""
74
+
75
+ var_summaries = []
76
+ for name, val in list(ip.user_ns.items()):
77
+ if name.startswith("_"):
78
+ continue
79
+ type_name = type(val).__name__
80
+ module_name = getattr(type(val), "__module__", "")
81
+
82
+ # Pandas DataFrame
83
+ if "pandas" in module_name and type_name == "DataFrame":
84
+ cols = list(val.columns)[:15]
85
+ var_summaries.append(f"- DataFrame `{name}`: shape={val.shape}, columns={cols}")
86
+ # Pandas Series
87
+ elif "pandas" in module_name and type_name == "Series":
88
+ var_summaries.append(f"- Series `{name}`: shape={val.shape}, dtype={val.dtype}")
89
+ # Numpy ndarray
90
+ elif "numpy" in module_name and type_name == "ndarray":
91
+ var_summaries.append(f"- NumPy Array `{name}`: shape={val.shape}, dtype={val.dtype}")
92
+ # PyTorch Tensor
93
+ elif "torch" in module_name and "Tensor" in type_name:
94
+ shape = list(val.shape) if hasattr(val, "shape") else []
95
+ var_summaries.append(f"- PyTorch Tensor `{name}`: shape={shape}, dtype={getattr(val, 'dtype', 'unknown')}")
96
+
97
+ if not var_summaries:
98
+ return ""
99
+ return "\n[Active In-Memory Notebook Variables]\n" + "\n".join(var_summaries[:8]) + "\n"
100
+ except Exception:
101
+ return ""
102
+
103
+
104
+ def _extract_primary_code_block(text: str) -> Optional[str]:
105
+ """Extract Python code block from assistant text to insert into cell."""
106
+ # Match ```python ... ``` or ```py ... ```
107
+ match = re.search(r"```(?:python|py)\n(.*?)```", text, flags=re.DOTALL)
108
+ if match:
109
+ return match.group(1).strip()
110
+ # Match generic ``` ... ```
111
+ match = re.search(r"```\n(.*?)```", text, flags=re.DOTALL)
112
+ if match:
113
+ return match.group(1).strip()
114
+ return None
115
+
116
+
117
+ def _render_colab_card(task: str, tool_actions: List[Dict[str, str]], content: str) -> str:
118
+ """Render a modern, sleek Colab/Jupyter responsive card."""
119
+ task_escaped = html.escape(task[:140])
120
+
121
+ actions_html = ""
122
+ if tool_actions:
123
+ actions_html = '<div style="margin-top: 8px; margin-bottom: 8px; font-family: ui-monospace, monospace; font-size: 12px;">'
124
+ for act in tool_actions:
125
+ name = html.escape(act.get("name", ""))
126
+ summary = html.escape(act.get("summary", ""))
127
+ status = act.get("status", "✓")
128
+ actions_html += (
129
+ f'<div style="display: flex; align-items: center; gap: 6px; padding: 3px 0; color: #94a3b8;">'
130
+ f'<span style="color: #38bdf8;">⏺</span> '
131
+ f'<strong style="color: #f1f5f9;">{name}</strong> '
132
+ f'<span style="color: #64748b;">{summary}</span>'
133
+ f'</div>'
134
+ )
135
+ actions_html += '</div>'
136
+
137
+ card = (
138
+ f'<div style="'
139
+ f'background: #0f172a; border: 1px solid #1e293b; border-left: 4px solid #38bdf8; '
140
+ f'border-radius: 8px; padding: 12px 16px; margin: 8px 0; font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, sans-serif;'
141
+ f'box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.3);">'
142
+ f'<div style="display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid #1e293b; padding-bottom: 8px;">'
143
+ f'<span style="font-weight: 600; font-size: 13px; color: #38bdf8; display: flex; align-items: center; gap: 6px;">'
144
+ f'⚡ AlpieCode Agent'
145
+ f'</span>'
146
+ f'<span style="font-size: 11px; color: #64748b; background: #1e293b; padding: 2px 8px; border-radius: 9999px;">'
147
+ f'Goal-Driven'
148
+ f'</span>'
149
+ f'</div>'
150
+ f'<div style="font-size: 13px; color: #cbd5e1; margin-top: 8px; font-weight: 500;">{task_escaped}</div>'
151
+ f'{actions_html}'
152
+ f'</div>'
153
+ )
154
+ return card
155
+
156
+
157
+ def alpie_magic(line: str, cell: Optional[str] = None):
158
+ """
159
+ %alpie <task> (line magic)
160
+ %%alpie (cell magic)
161
+ <multiline task>
162
+
163
+ Flags:
164
+ --insert, -i: Automatically insert generated code into the next cell
165
+ """
166
+ raw_task = (cell if cell is not None and cell.strip() else line).strip()
167
+ if not raw_task:
168
+ print("Usage: %alpie <task> OR %%alpie\n<multiline task>")
169
+ return
170
+
171
+ # Check for --insert flag
172
+ auto_insert = False
173
+ if raw_task.startswith("--insert ") or raw_task.startswith("-i "):
174
+ auto_insert = True
175
+ raw_task = re.sub(r"^(--insert|-i)\s+", "", raw_task).strip()
176
+
177
+ # Append in-memory notebook context (DataFrames, tensors)
178
+ nb_context = _get_notebook_context()
179
+ full_task = f"{raw_task}\n{nb_context}" if nb_context else raw_task
180
+
181
+ cfg = load_config()
182
+ workdir = Path(".").resolve()
183
+
184
+ if not _is_notebook():
185
+ # Running in standard terminal / ipython shell
186
+ run_agent(full_task, workdir, cfg, verbose=True)
187
+ return
188
+
189
+ # In Jupyter or Google Colab: run with rich streaming & UI
190
+ from IPython import get_ipython
191
+ ip = get_ipython()
192
+
193
+ backend = resolve_backend(cfg)
194
+ orchestrator = AgentOrchestrator(backend)
195
+ session_mgr = SessionManager()
196
+ session = session_mgr.create_session(workdir, max_tokens=cfg.n_ctx if not backend.is_available else 262_144)
197
+
198
+ tool_actions: List[Dict[str, str]] = []
199
+ final_content = ""
200
+
201
+ for event in orchestrator.run_task(session=session, task=full_task, cfg=cfg):
202
+ if event.type == "tool_call":
203
+ t_name = event.data.get("name", "")
204
+ t_args = event.data.get("arguments", {})
205
+ if isinstance(t_args, str):
206
+ try:
207
+ import json
208
+ t_args = json.loads(t_args)
209
+ except Exception:
210
+ t_args = {}
211
+
212
+ summary = ""
213
+ if t_name == "bash":
214
+ cmd = t_args.get("command", "")
215
+ summary = f"$ {cmd[:60]}..." if len(cmd) > 60 else f"$ {cmd}"
216
+ elif t_name in ("write_file", "edit_file", "read_file"):
217
+ summary = str(t_args.get("path", ""))
218
+ tool_actions.append({"name": t_name, "summary": summary})
219
+
220
+ elif event.type == "message":
221
+ final_content = event.data.get("content", "")
222
+
223
+ elif event.type == "done":
224
+ if not final_content:
225
+ final_content = event.data.get("summary", "")
226
+
227
+ # Clean up DONE: prefix
228
+ cleaned_content = final_content.strip()
229
+ if cleaned_content.upper().startswith("DONE:"):
230
+ cleaned_content = cleaned_content[5:].strip()
231
+
232
+ # Render modern card & markdown
233
+ _display_html(_render_colab_card(raw_task, tool_actions, cleaned_content))
234
+ if cleaned_content:
235
+ _display_markdown(cleaned_content)
236
+
237
+ # If code block is present, insert into next cell if requested or suggested
238
+ code_block = _extract_primary_code_block(cleaned_content)
239
+ if code_block and (auto_insert or (cell is not None and "code" in raw_task.lower())):
240
+ try:
241
+ ip.set_next_input(code_block, replace=False)
242
+ _display_html(
243
+ '<div style="font-size: 11px; color: #10b981; margin-top: 4px; font-family: sans-serif;">'
244
+ '✨ Code block automatically populated in next cell. Hit <b>Shift+Enter</b> to run.'
245
+ '</div>'
246
+ )
247
+ except Exception:
248
+ pass
249
+
250
+
251
+ def alpie_plan_magic(line: str, cell: Optional[str] = None):
252
+ """%alpie_plan <task> — Generate a structured implementation plan without making edits."""
253
+ task = (cell if cell is not None and cell.strip() else line).strip()
254
+ if not task:
255
+ print("Usage: %alpie_plan <task>")
256
+ return
257
+
258
+ plan_task = (
259
+ f"PLANNING ONLY — Do NOT make any file edits. "
260
+ f"Analyze the codebase and create a detailed implementation plan for the following task. "
261
+ f"Use list_files, read_file, and file_search to understand the project. "
262
+ f"Then use update_plan to write a structured plan with deliverables and checks. "
263
+ f"Finish with DONE: when the plan is complete.\n\n"
264
+ f"Task: {task}"
265
+ )
266
+
267
+ alpie_magic(plan_task)
268
+
269
+
270
+ def alpie_explain_magic(line: str):
271
+ """%alpie_explain <file_path_or_concept> — Explain code or architecture."""
272
+ target = line.strip()
273
+ if not target:
274
+ print("Usage: %alpie_explain <file_path_or_concept>")
275
+ return
276
+
277
+ workdir = Path(".").resolve()
278
+ target_path = workdir / target if not Path(target).is_absolute() else Path(target)
279
+
280
+ if target_path.exists() and target_path.is_file():
281
+ content = target_path.read_text(encoding="utf-8", errors="replace")
282
+ explain_task = (
283
+ f"EXPLANATION ONLY — Do NOT make any file edits.\n\n"
284
+ f"Please explain the file `{target}` in detail:\n"
285
+ f"1. Overview of its purpose and role\n"
286
+ f"2. Key functions, classes, and internal logic\n"
287
+ f"3. Dependencies and how it connects to the project\n"
288
+ f"4. Step-by-step walkthrough of how it executes\n\n"
289
+ f"File content ({target}):\n```\n{content[:16000]}\n```"
290
+ )
291
+ else:
292
+ explain_task = (
293
+ f"EXPLANATION ONLY — Do NOT make any file edits.\n\n"
294
+ f"Explain the following codebase concept or architecture in detail:\n"
295
+ f"Topic: {target}\n\n"
296
+ f"Use read_file or file_search if needed to understand codebase context."
297
+ )
298
+
299
+ alpie_magic(explain_task)
300
+
301
+
302
+ def alpie_doctor_magic(line: str = ""):
303
+ """%alpie_doctor — Run system health diagnostic checks."""
304
+ from .doctor import run_doctor
305
+ run_doctor()
306
+
307
+
308
+ def load_ipython_extension(ipython):
309
+ """Called by IPython when user runs `%load_ext alpiecode`."""
310
+ ipython.register_magic_function(alpie_magic, magic_kind="line_cell", magic_name="alpie")
311
+ ipython.register_magic_function(alpie_plan_magic, magic_kind="line_cell", magic_name="alpie_plan")
312
+ ipython.register_magic_function(alpie_explain_magic, magic_kind="line", magic_name="alpie_explain")
313
+ ipython.register_magic_function(alpie_doctor_magic, magic_kind="line", magic_name="alpie_doctor")
314
+ if _is_notebook():
315
+ _display_html(
316
+ '<div style="background: #0f172a; border-left: 4px solid #38bdf8; border-radius: 6px; padding: 8px 12px; margin: 4px 0; font-family: sans-serif; font-size: 13px; color: #e2e8f0;">'
317
+ '<strong style="color: #38bdf8;">✨ AlpieCode IPython & Colab Extension Loaded!</strong> '
318
+ '<span style="color: #94a3b8; font-size: 12px;">Try: <code>%alpie &lt;task&gt;</code> or <code>%%alpie</code> (supports <code>--insert</code> to populate code cells)</span>'
319
+ '</div>'
320
+ )
321
+ else:
322
+ print("✨ AlpieCode IPython/Jupyter Extension Loaded! Try: %alpie <task> or %%alpie")
323
+
324
+
325
+ def unload_ipython_extension(ipython):
326
+ """Called when user runs `%unload_ext alpiecode`."""
327
+ pass
@@ -110,7 +110,18 @@ def ensure_vscode_extension(auto_confirm: bool = False, quiet: bool = False) ->
110
110
  try:
111
111
  win_path = subprocess.check_output(["wslpath", "-w", str(vsix_path)], text=True).strip()
112
112
  if win_path:
113
- target_arg = win_path
113
+ # VS Code CLI on Windows disallows UNC paths (\wsl.localhost\...). Copy to Windows temp.
114
+ if win_path.startswith("\\"):
115
+ try:
116
+ win_temp = subprocess.check_output(["cmd.exe", "/c", "echo %TEMP%"], text=True).strip()
117
+ if win_temp and not win_temp.startswith("%"):
118
+ dest = f"{win_temp}\\alpiecode.vsix"
119
+ subprocess.run(["cmd.exe", "/c", f'copy /y "{win_path}" "{dest}"'], capture_output=True)
120
+ target_arg = dest
121
+ except Exception:
122
+ target_arg = win_path
123
+ else:
124
+ target_arg = win_path
114
125
  except Exception:
115
126
  pass
116
127
 
@@ -1,156 +0,0 @@
1
- """
2
- IPython & Jupyter / Google Colab extension for AlpieCode.
3
-
4
- Enables seamless usage of AlpieCode inside Jupyter Notebooks, JupyterLab,
5
- and Google Colab via cell/line magic commands and rich interactive displays:
6
-
7
- %load_ext alpiecode
8
- %alpie write a quick pandas script to inspect data.csv
9
- %%alpie
10
- Create a complete PyTorch model training pipeline.
11
- """
12
-
13
- import sys
14
- import warnings
15
- from pathlib import Path
16
- from typing import Optional
17
-
18
- # Suppress noisy Jupyter / Python 3.12+ deprecation warnings (e.g. datetime.utcnow in jupyter_client)
19
- warnings.filterwarnings("ignore", category=DeprecationWarning)
20
- warnings.filterwarnings("ignore", category=FutureWarning)
21
- warnings.filterwarnings("ignore", module="jupyter_client.*")
22
- warnings.filterwarnings("ignore", module="ipykernel.*")
23
-
24
- from .config import load_config
25
- from .agent import run_agent
26
-
27
-
28
- def _is_notebook() -> bool:
29
- """Check if code is running inside a Jupyter notebook or Google Colab."""
30
- try:
31
- from IPython import get_ipython
32
- shell = get_ipython()
33
- if shell is None:
34
- return False
35
- shell_name = shell.__class__.__name__
36
- if "ZMQInteractiveShell" in shell_name or "Shell" in shell_name:
37
- return True
38
- return False
39
- except Exception:
40
- return False
41
-
42
-
43
- def _display_html(html_str: str):
44
- """Render rich HTML in Jupyter or Google Colab."""
45
- try:
46
- from IPython.display import HTML, display
47
- display(HTML(html_str))
48
- except Exception:
49
- print(html_str)
50
-
51
-
52
- def _display_markdown(md_str: str):
53
- """Render rich Markdown in Jupyter or Google Colab."""
54
- try:
55
- from IPython.display import Markdown, display
56
- display(Markdown(md_str))
57
- except Exception:
58
- print(md_str)
59
-
60
-
61
- def alpie_magic(line: str, cell: Optional[str] = None):
62
- """
63
- %alpie <task> (line magic)
64
- %%alpie (cell magic)
65
- <multiline task>
66
- """
67
- task = (cell if cell is not None and cell.strip() else line).strip()
68
- if not task:
69
- print("Usage: %alpie <task> OR %%alpie\\n<multiline task>")
70
- return
71
-
72
- cfg = load_config()
73
- workdir = Path(".").resolve()
74
-
75
- if _is_notebook():
76
- _display_html(
77
- f'<div style="border-left: 3px solid #60a5fa; padding: 6px 12px; background: rgba(96,165,250,0.08); border-radius: 4px; font-family: sans-serif; margin-bottom: 8px;">'
78
- f'<strong style="color: #60a5fa;">⚡ AlpieCode Agent:</strong> {task[:120]}'
79
- f'</div>'
80
- )
81
-
82
- run_agent(task, workdir, cfg, verbose=True)
83
-
84
-
85
- def alpie_plan_magic(line: str, cell: Optional[str] = None):
86
- """%alpie_plan <task> — Generate a structured implementation plan without making edits."""
87
- task = (cell if cell is not None and cell.strip() else line).strip()
88
- if not task:
89
- print("Usage: %alpie_plan <task>")
90
- return
91
-
92
- plan_task = (
93
- f"PLANNING ONLY — Do NOT make any file edits. "
94
- f"Analyze the codebase and create a detailed implementation plan for the following task. "
95
- f"Use list_files, read_file, and file_search to understand the project. "
96
- f"Then use update_plan to write a structured plan with deliverables and checks. "
97
- f"Finish with DONE: when the plan is complete.\n\n"
98
- f"Task: {task}"
99
- )
100
-
101
- cfg = load_config()
102
- workdir = Path(".").resolve()
103
- run_agent(plan_task, workdir, cfg, verbose=True)
104
-
105
-
106
- def alpie_explain_magic(line: str):
107
- """%alpie_explain <file_path_or_concept> — Explain code or architecture."""
108
- target = line.strip()
109
- if not target:
110
- print("Usage: %alpie_explain <file_path_or_concept>")
111
- return
112
-
113
- cfg = load_config()
114
- workdir = Path(".").resolve()
115
- target_path = workdir / target if not Path(target).is_absolute() else Path(target)
116
-
117
- if target_path.exists() and target_path.is_file():
118
- content = target_path.read_text(encoding="utf-8", errors="replace")
119
- explain_task = (
120
- f"EXPLANATION ONLY — Do NOT make any file edits.\n\n"
121
- f"Please explain the file `{target}` in detail:\n"
122
- f"1. Overview of its purpose and role\n"
123
- f"2. Key functions, classes, and internal logic\n"
124
- f"3. Dependencies and how it connects to the project\n"
125
- f"4. Step-by-step walkthrough of how it executes\n\n"
126
- f"File content ({target}):\n```\n{content[:16000]}\n```"
127
- )
128
- else:
129
- explain_task = (
130
- f"EXPLANATION ONLY — Do NOT make any file edits.\n\n"
131
- f"Explain the following codebase concept or architecture in detail:\n"
132
- f"Topic: {target}\n\n"
133
- f"Use read_file or file_search if needed to understand codebase context."
134
- )
135
-
136
- run_agent(explain_task, workdir, cfg, verbose=True)
137
-
138
-
139
- def alpie_doctor_magic(line: str = ""):
140
- """%alpie_doctor — Run system health diagnostic checks."""
141
- from .doctor import run_doctor
142
- run_doctor()
143
-
144
-
145
- def load_ipython_extension(ipython):
146
- """Called by IPython when user runs `%load_ext alpiecode`."""
147
- ipython.register_magic_function(alpie_magic, magic_kind="line_cell", magic_name="alpie")
148
- ipython.register_magic_function(alpie_plan_magic, magic_kind="line_cell", magic_name="alpie_plan")
149
- ipython.register_magic_function(alpie_explain_magic, magic_kind="line", magic_name="alpie_explain")
150
- ipython.register_magic_function(alpie_doctor_magic, magic_kind="line", magic_name="alpie_doctor")
151
- print("✨ AlpieCode IPython/Jupyter Extension Loaded! Try: %alpie <task> or %%alpie")
152
-
153
-
154
- def unload_ipython_extension(ipython):
155
- """Called when user runs `%unload_ext alpiecode`."""
156
- pass
File without changes
File without changes