nc1709 1.15.4__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 (86) hide show
  1. nc1709/__init__.py +13 -0
  2. nc1709/agent/__init__.py +36 -0
  3. nc1709/agent/core.py +505 -0
  4. nc1709/agent/mcp_bridge.py +245 -0
  5. nc1709/agent/permissions.py +298 -0
  6. nc1709/agent/tools/__init__.py +21 -0
  7. nc1709/agent/tools/base.py +440 -0
  8. nc1709/agent/tools/bash_tool.py +367 -0
  9. nc1709/agent/tools/file_tools.py +454 -0
  10. nc1709/agent/tools/notebook_tools.py +516 -0
  11. nc1709/agent/tools/search_tools.py +322 -0
  12. nc1709/agent/tools/task_tool.py +284 -0
  13. nc1709/agent/tools/web_tools.py +555 -0
  14. nc1709/agents/__init__.py +17 -0
  15. nc1709/agents/auto_fix.py +506 -0
  16. nc1709/agents/test_generator.py +507 -0
  17. nc1709/checkpoints.py +372 -0
  18. nc1709/cli.py +3380 -0
  19. nc1709/cli_ui.py +1080 -0
  20. nc1709/cognitive/__init__.py +149 -0
  21. nc1709/cognitive/anticipation.py +594 -0
  22. nc1709/cognitive/context_engine.py +1046 -0
  23. nc1709/cognitive/council.py +824 -0
  24. nc1709/cognitive/learning.py +761 -0
  25. nc1709/cognitive/router.py +583 -0
  26. nc1709/cognitive/system.py +519 -0
  27. nc1709/config.py +155 -0
  28. nc1709/custom_commands.py +300 -0
  29. nc1709/executor.py +333 -0
  30. nc1709/file_controller.py +354 -0
  31. nc1709/git_integration.py +308 -0
  32. nc1709/github_integration.py +477 -0
  33. nc1709/image_input.py +446 -0
  34. nc1709/linting.py +519 -0
  35. nc1709/llm_adapter.py +667 -0
  36. nc1709/logger.py +192 -0
  37. nc1709/mcp/__init__.py +18 -0
  38. nc1709/mcp/client.py +370 -0
  39. nc1709/mcp/manager.py +407 -0
  40. nc1709/mcp/protocol.py +210 -0
  41. nc1709/mcp/server.py +473 -0
  42. nc1709/memory/__init__.py +20 -0
  43. nc1709/memory/embeddings.py +325 -0
  44. nc1709/memory/indexer.py +474 -0
  45. nc1709/memory/sessions.py +432 -0
  46. nc1709/memory/vector_store.py +451 -0
  47. nc1709/models/__init__.py +86 -0
  48. nc1709/models/detector.py +377 -0
  49. nc1709/models/formats.py +315 -0
  50. nc1709/models/manager.py +438 -0
  51. nc1709/models/registry.py +497 -0
  52. nc1709/performance/__init__.py +343 -0
  53. nc1709/performance/cache.py +705 -0
  54. nc1709/performance/pipeline.py +611 -0
  55. nc1709/performance/tiering.py +543 -0
  56. nc1709/plan_mode.py +362 -0
  57. nc1709/plugins/__init__.py +17 -0
  58. nc1709/plugins/agents/__init__.py +18 -0
  59. nc1709/plugins/agents/django_agent.py +912 -0
  60. nc1709/plugins/agents/docker_agent.py +623 -0
  61. nc1709/plugins/agents/fastapi_agent.py +887 -0
  62. nc1709/plugins/agents/git_agent.py +731 -0
  63. nc1709/plugins/agents/nextjs_agent.py +867 -0
  64. nc1709/plugins/base.py +359 -0
  65. nc1709/plugins/manager.py +411 -0
  66. nc1709/plugins/registry.py +337 -0
  67. nc1709/progress.py +443 -0
  68. nc1709/prompts/__init__.py +22 -0
  69. nc1709/prompts/agent_system.py +180 -0
  70. nc1709/prompts/task_prompts.py +340 -0
  71. nc1709/prompts/unified_prompt.py +133 -0
  72. nc1709/reasoning_engine.py +541 -0
  73. nc1709/remote_client.py +266 -0
  74. nc1709/shell_completions.py +349 -0
  75. nc1709/slash_commands.py +649 -0
  76. nc1709/task_classifier.py +408 -0
  77. nc1709/version_check.py +177 -0
  78. nc1709/web/__init__.py +8 -0
  79. nc1709/web/server.py +950 -0
  80. nc1709/web/templates/index.html +1127 -0
  81. nc1709-1.15.4.dist-info/METADATA +858 -0
  82. nc1709-1.15.4.dist-info/RECORD +86 -0
  83. nc1709-1.15.4.dist-info/WHEEL +5 -0
  84. nc1709-1.15.4.dist-info/entry_points.txt +2 -0
  85. nc1709-1.15.4.dist-info/licenses/LICENSE +9 -0
  86. nc1709-1.15.4.dist-info/top_level.txt +1 -0
nc1709/progress.py ADDED
@@ -0,0 +1,443 @@
1
+ """
2
+ Progress Indicators
3
+ Rich progress bars and status displays for long-running operations
4
+ """
5
+ import sys
6
+ import time
7
+ import threading
8
+ from typing import Optional, Callable, List, Any
9
+ from enum import Enum
10
+ from contextlib import contextmanager
11
+
12
+
13
+ class SpinnerStyle(Enum):
14
+ """Available spinner styles"""
15
+ DOTS = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]
16
+ BRAILLE = ["⣾", "⣽", "⣻", "⢿", "⡿", "⣟", "⣯", "⣷"]
17
+ ARROWS = ["←", "↖", "↑", "↗", "→", "↘", "↓", "↙"]
18
+ CLOCK = ["🕐", "🕑", "🕒", "🕓", "🕔", "🕕", "🕖", "🕗", "🕘", "🕙", "🕚", "🕛"]
19
+ MOON = ["🌑", "🌒", "🌓", "🌔", "🌕", "🌖", "🌗", "🌘"]
20
+ BOUNCE = ["⠁", "⠂", "⠄", "⠂"]
21
+ SIMPLE = ["-", "\\", "|", "/"]
22
+
23
+
24
+ class ProgressBar:
25
+ """Simple progress bar for terminal output"""
26
+
27
+ def __init__(
28
+ self,
29
+ total: int,
30
+ description: str = "",
31
+ width: int = 40,
32
+ fill_char: str = "█",
33
+ empty_char: str = "░"
34
+ ):
35
+ """Initialize progress bar
36
+
37
+ Args:
38
+ total: Total number of steps
39
+ description: Description text
40
+ width: Width of progress bar in characters
41
+ fill_char: Character for filled portion
42
+ empty_char: Character for empty portion
43
+ """
44
+ self.total = total
45
+ self.description = description
46
+ self.width = width
47
+ self.fill_char = fill_char
48
+ self.empty_char = empty_char
49
+ self.current = 0
50
+ self.start_time = time.time()
51
+
52
+ def update(self, amount: int = 1) -> None:
53
+ """Update progress
54
+
55
+ Args:
56
+ amount: Amount to increment
57
+ """
58
+ self.current = min(self.current + amount, self.total)
59
+ self._render()
60
+
61
+ def set(self, value: int) -> None:
62
+ """Set progress to specific value
63
+
64
+ Args:
65
+ value: New progress value
66
+ """
67
+ self.current = min(value, self.total)
68
+ self._render()
69
+
70
+ def _render(self) -> None:
71
+ """Render progress bar to terminal"""
72
+ percentage = self.current / self.total if self.total > 0 else 0
73
+ filled_width = int(self.width * percentage)
74
+ empty_width = self.width - filled_width
75
+
76
+ bar = self.fill_char * filled_width + self.empty_char * empty_width
77
+
78
+ # Calculate elapsed time and ETA
79
+ elapsed = time.time() - self.start_time
80
+ if percentage > 0:
81
+ eta = elapsed / percentage - elapsed
82
+ eta_str = f" ETA: {self._format_time(eta)}"
83
+ else:
84
+ eta_str = ""
85
+
86
+ # Build progress line
87
+ desc = f"{self.description}: " if self.description else ""
88
+ line = f"\r{desc}[{bar}] {self.current}/{self.total} ({percentage*100:.1f}%){eta_str}"
89
+
90
+ sys.stdout.write(line)
91
+ sys.stdout.flush()
92
+
93
+ if self.current >= self.total:
94
+ print() # New line when complete
95
+
96
+ def _format_time(self, seconds: float) -> str:
97
+ """Format seconds as human-readable time"""
98
+ if seconds < 60:
99
+ return f"{seconds:.0f}s"
100
+ elif seconds < 3600:
101
+ return f"{seconds/60:.1f}m"
102
+ else:
103
+ return f"{seconds/3600:.1f}h"
104
+
105
+ def finish(self) -> None:
106
+ """Mark progress as complete"""
107
+ self.set(self.total)
108
+
109
+
110
+ class Spinner:
111
+ """Animated spinner for indeterminate progress"""
112
+
113
+ def __init__(
114
+ self,
115
+ message: str = "Processing",
116
+ style: SpinnerStyle = SpinnerStyle.DOTS
117
+ ):
118
+ """Initialize spinner
119
+
120
+ Args:
121
+ message: Message to display with spinner
122
+ style: Spinner animation style
123
+ """
124
+ self.message = message
125
+ self.frames = style.value
126
+ self.frame_index = 0
127
+ self.running = False
128
+ self._thread: Optional[threading.Thread] = None
129
+ self._lock = threading.Lock()
130
+
131
+ def start(self) -> "Spinner":
132
+ """Start spinner animation"""
133
+ self.running = True
134
+ self._thread = threading.Thread(target=self._animate, daemon=True)
135
+ self._thread.start()
136
+ return self
137
+
138
+ def stop(self, final_message: Optional[str] = None) -> None:
139
+ """Stop spinner animation
140
+
141
+ Args:
142
+ final_message: Optional message to display after stopping
143
+ """
144
+ self.running = False
145
+ if self._thread:
146
+ self._thread.join(timeout=0.5)
147
+
148
+ # Clear spinner line
149
+ sys.stdout.write("\r" + " " * (len(self.message) + 10) + "\r")
150
+ sys.stdout.flush()
151
+
152
+ if final_message:
153
+ print(final_message)
154
+
155
+ def _animate(self) -> None:
156
+ """Animation loop"""
157
+ while self.running:
158
+ with self._lock:
159
+ frame = self.frames[self.frame_index]
160
+ sys.stdout.write(f"\r{frame} {self.message}")
161
+ sys.stdout.flush()
162
+ self.frame_index = (self.frame_index + 1) % len(self.frames)
163
+ time.sleep(0.1)
164
+
165
+ def update_message(self, message: str) -> None:
166
+ """Update spinner message
167
+
168
+ Args:
169
+ message: New message
170
+ """
171
+ with self._lock:
172
+ # Clear old message
173
+ old_len = len(self.message) + 10
174
+ sys.stdout.write("\r" + " " * old_len + "\r")
175
+ self.message = message
176
+
177
+ def __enter__(self) -> "Spinner":
178
+ return self.start()
179
+
180
+ def __exit__(self, *args) -> None:
181
+ self.stop()
182
+
183
+
184
+ class StatusLine:
185
+ """Status line that updates in place"""
186
+
187
+ def __init__(self):
188
+ """Initialize status line"""
189
+ self.current_line = ""
190
+
191
+ def update(self, message: str, prefix: str = "→") -> None:
192
+ """Update status line
193
+
194
+ Args:
195
+ message: Status message
196
+ prefix: Prefix character/emoji
197
+ """
198
+ # Clear old line
199
+ clear_len = len(self.current_line) + 5
200
+ sys.stdout.write("\r" + " " * clear_len + "\r")
201
+
202
+ # Write new line
203
+ self.current_line = f"{prefix} {message}"
204
+ sys.stdout.write(self.current_line)
205
+ sys.stdout.flush()
206
+
207
+ def success(self, message: str) -> None:
208
+ """Show success message"""
209
+ self.update(message, "✅")
210
+ print() # New line after success
211
+
212
+ def error(self, message: str) -> None:
213
+ """Show error message"""
214
+ self.update(message, "❌")
215
+ print() # New line after error
216
+
217
+ def info(self, message: str) -> None:
218
+ """Show info message"""
219
+ self.update(message, "ℹ️")
220
+
221
+ def warning(self, message: str) -> None:
222
+ """Show warning message"""
223
+ self.update(message, "⚠️")
224
+
225
+ def clear(self) -> None:
226
+ """Clear status line"""
227
+ clear_len = len(self.current_line) + 5
228
+ sys.stdout.write("\r" + " " * clear_len + "\r")
229
+ sys.stdout.flush()
230
+ self.current_line = ""
231
+
232
+
233
+ class MultiStepProgress:
234
+ """Progress indicator for multi-step operations"""
235
+
236
+ def __init__(self, steps: List[str]):
237
+ """Initialize multi-step progress
238
+
239
+ Args:
240
+ steps: List of step descriptions
241
+ """
242
+ self.steps = steps
243
+ self.current_step = 0
244
+ self.step_statuses: List[str] = ["pending"] * len(steps)
245
+
246
+ def start_step(self, index: Optional[int] = None) -> None:
247
+ """Start a step
248
+
249
+ Args:
250
+ index: Step index (uses current_step if None)
251
+ """
252
+ if index is None:
253
+ index = self.current_step
254
+
255
+ self.step_statuses[index] = "running"
256
+ self._render()
257
+
258
+ def complete_step(self, index: Optional[int] = None) -> None:
259
+ """Mark step as complete
260
+
261
+ Args:
262
+ index: Step index (uses current_step if None)
263
+ """
264
+ if index is None:
265
+ index = self.current_step
266
+
267
+ self.step_statuses[index] = "completed"
268
+ self.current_step = index + 1
269
+ self._render()
270
+
271
+ def fail_step(self, index: Optional[int] = None, error: str = "") -> None:
272
+ """Mark step as failed
273
+
274
+ Args:
275
+ index: Step index (uses current_step if None)
276
+ error: Error message
277
+ """
278
+ if index is None:
279
+ index = self.current_step
280
+
281
+ self.step_statuses[index] = f"failed: {error}" if error else "failed"
282
+ self._render()
283
+
284
+ def _render(self) -> None:
285
+ """Render progress to terminal"""
286
+ print() # New line before rendering
287
+ print("=" * 50)
288
+
289
+ for i, (step, status) in enumerate(zip(self.steps, self.step_statuses)):
290
+ if status == "completed":
291
+ icon = "✅"
292
+ elif status == "running":
293
+ icon = "🔄"
294
+ elif status.startswith("failed"):
295
+ icon = "❌"
296
+ else:
297
+ icon = "⬜"
298
+
299
+ step_num = f"[{i + 1}/{len(self.steps)}]"
300
+ print(f" {icon} {step_num} {step}")
301
+
302
+ if status.startswith("failed:"):
303
+ error_msg = status.split(": ", 1)[1]
304
+ print(f" └─ Error: {error_msg}")
305
+
306
+ print("=" * 50)
307
+
308
+ def is_complete(self) -> bool:
309
+ """Check if all steps are complete"""
310
+ return all(s == "completed" for s in self.step_statuses)
311
+
312
+ def has_failures(self) -> bool:
313
+ """Check if any step failed"""
314
+ return any(s.startswith("failed") for s in self.step_statuses)
315
+
316
+
317
+ @contextmanager
318
+ def spinner_context(message: str, style: SpinnerStyle = SpinnerStyle.DOTS):
319
+ """Context manager for spinner
320
+
321
+ Usage:
322
+ with spinner_context("Loading...") as spinner:
323
+ do_something()
324
+ spinner.update_message("Almost done...")
325
+ """
326
+ spinner = Spinner(message, style)
327
+ try:
328
+ yield spinner.start()
329
+ finally:
330
+ spinner.stop()
331
+
332
+
333
+ @contextmanager
334
+ def progress_context(
335
+ total: int,
336
+ description: str = "",
337
+ callback: Optional[Callable[[ProgressBar], None]] = None
338
+ ):
339
+ """Context manager for progress bar
340
+
341
+ Usage:
342
+ with progress_context(100, "Processing") as progress:
343
+ for i in range(100):
344
+ do_work()
345
+ progress.update()
346
+ """
347
+ progress = ProgressBar(total, description)
348
+ try:
349
+ yield progress
350
+ finally:
351
+ progress.finish()
352
+
353
+
354
+ class TaskProgress:
355
+ """High-level progress tracker for NC1709 tasks"""
356
+
357
+ def __init__(self, task_description: str):
358
+ """Initialize task progress
359
+
360
+ Args:
361
+ task_description: Description of the task
362
+ """
363
+ self.description = task_description
364
+ self.status = StatusLine()
365
+ self.start_time = time.time()
366
+
367
+ def thinking(self, detail: str = "") -> None:
368
+ """Show thinking/processing state"""
369
+ msg = f"Thinking: {self.description}"
370
+ if detail:
371
+ msg += f" ({detail})"
372
+ self.status.update(msg, "🧠")
373
+
374
+ def generating(self, detail: str = "") -> None:
375
+ """Show generating state"""
376
+ msg = f"Generating: {self.description}"
377
+ if detail:
378
+ msg += f" ({detail})"
379
+ self.status.update(msg, "✨")
380
+
381
+ def executing(self, detail: str = "") -> None:
382
+ """Show executing state"""
383
+ msg = f"Executing: {self.description}"
384
+ if detail:
385
+ msg += f" ({detail})"
386
+ self.status.update(msg, "⚡")
387
+
388
+ def complete(self, result: str = "") -> None:
389
+ """Mark task as complete"""
390
+ elapsed = time.time() - self.start_time
391
+ msg = f"Completed: {self.description} ({elapsed:.1f}s)"
392
+ if result:
393
+ msg += f" - {result}"
394
+ self.status.success(msg)
395
+
396
+ def failed(self, error: str) -> None:
397
+ """Mark task as failed"""
398
+ elapsed = time.time() - self.start_time
399
+ msg = f"Failed: {self.description} ({elapsed:.1f}s) - {error}"
400
+ self.status.error(msg)
401
+
402
+
403
+ # Convenience functions
404
+ def show_spinner(message: str, duration: float = 0) -> Spinner:
405
+ """Show a spinner with message
406
+
407
+ Args:
408
+ message: Spinner message
409
+ duration: Auto-stop after duration seconds (0 = manual stop)
410
+
411
+ Returns:
412
+ Spinner instance
413
+ """
414
+ spinner = Spinner(message)
415
+ spinner.start()
416
+
417
+ if duration > 0:
418
+ def stop_after():
419
+ time.sleep(duration)
420
+ spinner.stop()
421
+ threading.Thread(target=stop_after, daemon=True).start()
422
+
423
+ return spinner
424
+
425
+
426
+ def show_progress(
427
+ items: List[Any],
428
+ description: str = "",
429
+ process_func: Optional[Callable[[Any], None]] = None
430
+ ) -> None:
431
+ """Show progress while processing items
432
+
433
+ Args:
434
+ items: Items to process
435
+ description: Progress description
436
+ process_func: Function to call for each item
437
+ """
438
+ progress = ProgressBar(len(items), description)
439
+
440
+ for item in items:
441
+ if process_func:
442
+ process_func(item)
443
+ progress.update()
@@ -0,0 +1,22 @@
1
+ """
2
+ NC1709 Prompt System
3
+
4
+ Provides task-specific prompts to improve LLM performance on different types of requests.
5
+ """
6
+
7
+ from .agent_system import get_agent_prompt, AGENT_SYSTEM_PROMPT
8
+ from .task_prompts import (
9
+ detect_task_type,
10
+ get_task_prompt,
11
+ get_full_prompt,
12
+ TaskType,
13
+ )
14
+
15
+ __all__ = [
16
+ 'get_agent_prompt',
17
+ 'AGENT_SYSTEM_PROMPT',
18
+ 'detect_task_type',
19
+ 'get_task_prompt',
20
+ 'get_full_prompt',
21
+ 'TaskType',
22
+ ]
@@ -0,0 +1,180 @@
1
+ """
2
+ NC1709 Agent System Prompt
3
+
4
+ This is the core prompt that defines how the AI assistant behaves.
5
+ Fine-tuning this is the #1 lever for improving output quality.
6
+ """
7
+
8
+ AGENT_SYSTEM_PROMPT = """You are NC1709, an expert AI software engineer. You don't just give advice - you actively read, analyze, and modify code using tools.
9
+
10
+ ## Tools Available
11
+
12
+ | Tool | Purpose | Required Parameters |
13
+ |------|---------|---------------------|
14
+ | Read | Read file contents | file_path |
15
+ | Write | Create/overwrite file | file_path, content |
16
+ | Edit | Replace text in file | file_path, old_string, new_string |
17
+ | Glob | Find files by pattern | pattern |
18
+ | Grep | Search file contents | pattern |
19
+ | Bash | Run shell command | command |
20
+ | WebSearch | Search the internet for current information | query |
21
+ | WebFetch | Fetch and read web page content | url |
22
+
23
+ ## Tool Format
24
+
25
+ ```tool
26
+ {{"tool": "Name", "parameters": {{"key": "value"}}}}
27
+ ```
28
+
29
+ ## Core Behaviors
30
+
31
+ ### 1. ALWAYS Gather Context First
32
+ Before answering questions about code:
33
+ - Use Glob to find relevant files (*.py, *.js, *.ts, etc.)
34
+ - Read README.md, package.json, pyproject.toml first
35
+ - Read the actual source files before commenting on them
36
+
37
+ ### 2. Skip Generated/Vendor Directories
38
+ NEVER explore: node_modules, venv, __pycache__, .git, dist, build, .next, vendor, target
39
+
40
+ ### 3. Be Specific and Actionable
41
+ BAD: "You should add error handling"
42
+ GOOD: "In `src/api.py:45`, the `fetch_data()` function doesn't handle network errors. Add try/except:"
43
+
44
+ ### 4. Use Multiple Tools Per Response
45
+ You can call multiple tools. For efficiency:
46
+ ```tool
47
+ {{"tool": "Glob", "parameters": {{"pattern": "*.py"}}}}
48
+ ```
49
+ Then after seeing results:
50
+ ```tool
51
+ {{"tool": "Read", "parameters": {{"file_path": "src/main.py"}}}}
52
+ ```
53
+
54
+ ### 5. For Code Audits
55
+ 1. Find project config files (package.json, pyproject.toml)
56
+ 2. Identify main source directories
57
+ 3. Read core files (not all files - focus on entry points, API routes, models)
58
+ 4. Report issues with file:line references:
59
+ - Security vulnerabilities (SQL injection, XSS, secrets in code)
60
+ - Missing error handling
61
+ - Code smells (duplication, complexity)
62
+ - Missing tests
63
+ - Outdated patterns
64
+
65
+ ### 6. For Code Changes
66
+ 1. Read the file first (ALWAYS)
67
+ 2. Show the specific change with Edit tool
68
+ 3. Verify the change doesn't break imports/references
69
+
70
+ ### 7. For Debugging
71
+ 1. Read the error message carefully
72
+ 2. Find and read the file mentioned
73
+ 3. Search for related code with Grep
74
+ 4. Propose a specific fix
75
+
76
+ ### 8. For Questions Requiring Current Information (IMPORTANT!)
77
+
78
+ **ALWAYS use WebSearch first** when users ask about:
79
+ - Current events, news, sports scores, match results
80
+ - Today's information, recent happenings
81
+ - Latest versions, documentation, or updates
82
+ - Real-time data (weather, stocks, etc.)
83
+ - Anything that requires up-to-date information
84
+
85
+ DO NOT tell users you don't have access to current information. USE THE TOOL:
86
+ ```tool
87
+ {{"tool": "WebSearch", "parameters": {{"query": "India vs South Africa cricket match today December 2024 score"}}}}
88
+ ```
89
+
90
+ After getting search results, use WebFetch to read the full page:
91
+ ```tool
92
+ {{"tool": "WebFetch", "parameters": {{"url": "https://espncricinfo.com/match-url"}}}}
93
+ ```
94
+
95
+ **NEVER say "I don't have access to real-time data" - USE WebSearch!**
96
+
97
+ ## Response Style
98
+
99
+ - Be concise. Don't explain what tools do.
100
+ - Don't say "I'll help you" or "Let me". Just do it.
101
+ - Don't apologize or hedge. Be confident.
102
+ - Reference specific files and line numbers.
103
+ - Show code snippets when relevant.
104
+
105
+ ## What NOT To Do
106
+
107
+ - Don't run `ls -R` or `find .` (too verbose)
108
+ - Don't describe node_modules or venv contents
109
+ - Don't give generic advice without reading code
110
+ - Don't say "I would need to..." - use the tools
111
+ - Don't ask clarifying questions if you can find the answer with tools
112
+ - Don't repeat the user's question back to them
113
+
114
+ ## Working Directory
115
+
116
+ {cwd}
117
+ """
118
+
119
+
120
+ def get_agent_prompt(cwd: str) -> str:
121
+ """Get the agent system prompt with context filled in."""
122
+ return AGENT_SYSTEM_PROMPT.format(cwd=cwd)
123
+
124
+
125
+ # Task-specific prompt additions
126
+ AUDIT_ADDITION = """
127
+ ## Audit Checklist
128
+
129
+ When auditing, check for:
130
+
131
+ **Security**
132
+ - [ ] Hardcoded secrets/API keys
133
+ - [ ] SQL injection vulnerabilities
134
+ - [ ] XSS vulnerabilities (unescaped output)
135
+ - [ ] Insecure dependencies
136
+ - [ ] Missing authentication/authorization
137
+ - [ ] Exposed sensitive data in logs
138
+
139
+ **Code Quality**
140
+ - [ ] Functions over 50 lines
141
+ - [ ] Duplicated code
142
+ - [ ] Missing error handling
143
+ - [ ] Unused imports/variables
144
+ - [ ] Inconsistent naming conventions
145
+ - [ ] Missing type hints (Python) or TypeScript
146
+
147
+ **Architecture**
148
+ - [ ] Circular dependencies
149
+ - [ ] God classes/modules
150
+ - [ ] Missing separation of concerns
151
+ - [ ] Hardcoded configuration
152
+
153
+ **Testing**
154
+ - [ ] Test coverage exists
155
+ - [ ] Tests are meaningful (not just existence checks)
156
+ - [ ] Edge cases covered
157
+ """
158
+
159
+ REFACTOR_ADDITION = """
160
+ ## Refactoring Guidelines
161
+
162
+ When refactoring:
163
+ 1. Make ONE change at a time
164
+ 2. Preserve all existing functionality
165
+ 3. Don't change function signatures unless asked
166
+ 4. Keep the same file structure unless restructuring is requested
167
+ 5. Update imports if you move/rename things
168
+ """
169
+
170
+ DEBUG_ADDITION = """
171
+ ## Debugging Guidelines
172
+
173
+ When debugging:
174
+ 1. Read the full error message and stack trace
175
+ 2. Find the exact file and line mentioned
176
+ 3. Read surrounding context (10 lines before/after)
177
+ 4. Search for similar patterns in codebase
178
+ 5. Check if the error is in user code or dependencies
179
+ 6. Propose a minimal fix that addresses root cause
180
+ """