nimcode 0.4.0__tar.gz → 0.4.2__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 (50) hide show
  1. nimcode-0.4.2/PKG-INFO +226 -0
  2. {nimcode-0.4.0 → nimcode-0.4.2}/README.md +55 -20
  3. {nimcode-0.4.0 → nimcode-0.4.2}/setup.py +5 -0
  4. nimcode-0.4.2/src/nimcode/__version__.py +1 -0
  5. {nimcode-0.4.0 → nimcode-0.4.2}/src/nimcode/agent.py +26 -6
  6. {nimcode-0.4.0 → nimcode-0.4.2}/src/nimcode/cli.py +52 -26
  7. {nimcode-0.4.0 → nimcode-0.4.2}/src/nimcode/repl.py +73 -15
  8. {nimcode-0.4.0 → nimcode-0.4.2}/src/nimcode/tools.py +40 -9
  9. nimcode-0.4.2/src/nimcode.egg-info/PKG-INFO +226 -0
  10. {nimcode-0.4.0 → nimcode-0.4.2}/src/nimcode.egg-info/SOURCES.txt +2 -0
  11. {nimcode-0.4.0 → nimcode-0.4.2}/tests/test_cli.py +37 -0
  12. nimcode-0.4.2/tests/test_plan_injection.py +152 -0
  13. {nimcode-0.4.0 → nimcode-0.4.2}/tests/test_repl.py +8 -1
  14. {nimcode-0.4.0 → nimcode-0.4.2}/tests/test_repl_extra.py +7 -1
  15. nimcode-0.4.2/tests/test_repl_fixes.py +171 -0
  16. {nimcode-0.4.0 → nimcode-0.4.2}/tests/test_version.py +3 -3
  17. nimcode-0.4.0/PKG-INFO +0 -13
  18. nimcode-0.4.0/src/nimcode/__version__.py +0 -1
  19. nimcode-0.4.0/src/nimcode.egg-info/PKG-INFO +0 -13
  20. {nimcode-0.4.0 → nimcode-0.4.2}/setup.cfg +0 -0
  21. {nimcode-0.4.0 → nimcode-0.4.2}/src/nimcode/__init__.py +0 -0
  22. {nimcode-0.4.0 → nimcode-0.4.2}/src/nimcode/config.py +0 -0
  23. {nimcode-0.4.0 → nimcode-0.4.2}/src/nimcode/lenient_parser.py +0 -0
  24. {nimcode-0.4.0 → nimcode-0.4.2}/src/nimcode/mcp_client.py +0 -0
  25. {nimcode-0.4.0 → nimcode-0.4.2}/src/nimcode/memory.py +0 -0
  26. {nimcode-0.4.0 → nimcode-0.4.2}/src/nimcode/model_registry.py +0 -0
  27. {nimcode-0.4.0 → nimcode-0.4.2}/src/nimcode/nim_client.py +0 -0
  28. {nimcode-0.4.0 → nimcode-0.4.2}/src/nimcode/permissions.py +0 -0
  29. {nimcode-0.4.0 → nimcode-0.4.2}/src/nimcode/plugin_manager.py +0 -0
  30. {nimcode-0.4.0 → nimcode-0.4.2}/src/nimcode/rag.py +0 -0
  31. {nimcode-0.4.0 → nimcode-0.4.2}/src/nimcode/repo_map.py +0 -0
  32. {nimcode-0.4.0 → nimcode-0.4.2}/src/nimcode/updater.py +0 -0
  33. {nimcode-0.4.0 → nimcode-0.4.2}/src/nimcode/watcher.py +0 -0
  34. {nimcode-0.4.0 → nimcode-0.4.2}/src/nimcode.egg-info/dependency_links.txt +0 -0
  35. {nimcode-0.4.0 → nimcode-0.4.2}/src/nimcode.egg-info/entry_points.txt +0 -0
  36. {nimcode-0.4.0 → nimcode-0.4.2}/src/nimcode.egg-info/requires.txt +0 -0
  37. {nimcode-0.4.0 → nimcode-0.4.2}/src/nimcode.egg-info/top_level.txt +0 -0
  38. {nimcode-0.4.0 → nimcode-0.4.2}/tests/test_agent.py +0 -0
  39. {nimcode-0.4.0 → nimcode-0.4.2}/tests/test_config.py +0 -0
  40. {nimcode-0.4.0 → nimcode-0.4.2}/tests/test_lenient_parser.py +0 -0
  41. {nimcode-0.4.0 → nimcode-0.4.2}/tests/test_mcp_client.py +0 -0
  42. {nimcode-0.4.0 → nimcode-0.4.2}/tests/test_memory.py +0 -0
  43. {nimcode-0.4.0 → nimcode-0.4.2}/tests/test_model_registry.py +0 -0
  44. {nimcode-0.4.0 → nimcode-0.4.2}/tests/test_nim_client.py +0 -0
  45. {nimcode-0.4.0 → nimcode-0.4.2}/tests/test_permissions.py +0 -0
  46. {nimcode-0.4.0 → nimcode-0.4.2}/tests/test_plugin_manager.py +0 -0
  47. {nimcode-0.4.0 → nimcode-0.4.2}/tests/test_repl_trust.py +0 -0
  48. {nimcode-0.4.0 → nimcode-0.4.2}/tests/test_repo_map.py +0 -0
  49. {nimcode-0.4.0 → nimcode-0.4.2}/tests/test_tools.py +0 -0
  50. {nimcode-0.4.0 → nimcode-0.4.2}/tests/test_updater.py +0 -0
nimcode-0.4.2/PKG-INFO ADDED
@@ -0,0 +1,226 @@
1
+ Metadata-Version: 2.4
2
+ Name: nimcode
3
+ Version: 0.4.2
4
+ Summary: A standalone, robust coding agent for NVIDIA NIM models.
5
+ Home-page: https://github.com/Batunash/nimcode
6
+ Author: Autonomous Agent
7
+ Requires-Python: >=3.8
8
+ Description-Content-Type: text/markdown
9
+ Requires-Dist: httpx>=0.27.0
10
+ Requires-Dist: rich>=13.7.0
11
+ Requires-Dist: prompt_toolkit>=3.0.0
12
+ Requires-Dist: mcp>=1.2.0
13
+ Requires-Dist: watchdog>=3.0.0
14
+ Dynamic: author
15
+ Dynamic: description
16
+ Dynamic: description-content-type
17
+ Dynamic: home-page
18
+ Dynamic: requires-dist
19
+ Dynamic: requires-python
20
+ Dynamic: summary
21
+
22
+ <div align="center">
23
+
24
+ # 🚀 NimCode
25
+
26
+ **The Autonomous AI Coding Assistant for the NVIDIA NIM Ecosystem**
27
+
28
+ [![PyPI version](https://badge.fury.io/py/nimcode.svg)](https://badge.fury.io/py/nimcode)
29
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
30
+
31
+ *A powerful, standalone REPL and CLI agent that writes, edits, and plans code like a senior developer—powered by LLaMa 3.1 70B (and other cutting-edge models) and the lightning-fast NVIDIA NIM API.*
32
+
33
+ </div>
34
+
35
+ ---
36
+
37
+ ## 🌟 Overview
38
+
39
+ NimCode is your autonomous coding pair-programmer. Built with a rich interactive terminal interface, it doesn't just autocomplete code—it plans architectures based on real documents (SDD, PRD, RFC), executes terminal commands, writes complete files, and manages your workspace.
40
+
41
+ ### ✅ What Works Right Now
42
+ - **OS-Aware Agent**: Automatically detects Windows/Linux/macOS and uses the correct shell commands. No more `mkdir -p` on Windows.
43
+ - **SDD/PRD-Aware Planning**: `/plan` mode reads your actual documents and produces implementation plans grounded in real file names, modules, and requirements—not generic PM templates.
44
+ - **Paginated File Reading**: Large files (like SDDs) are read in chunks with `offset`/`limit` so nothing gets truncated.
45
+ - **VS Code Deep Integration**: Native IPC communication allowing NimCode to read active editors, send patches, and act as your intelligent coding panel within VS Code.
46
+ - **RAG & Semantic Search**: Zero-dependency TF-IDF/BM25 based indexer that instantly scans massive workspaces and retrieves context-aware code snippets.
47
+ - **Autonomous Auto-Fixer**: The `/fix` command creates a self-healing feedback loop—runs your broken commands, analyzes tracebacks, and automatically iterates on code patches until the build passes.
48
+ - **Multi-Model & Local Support**: Flexible `api_base_url` configuration to seamlessly switch between NVIDIA NIM, Ollama, or vLLM endpoints. Dynamic model list fetched from the API at runtime.
49
+ - **Smart Permission Engine**: Granular control over file writes and command executions, featuring an auto-bypass mechanism and interactive `(a)ccept / (r)eject` diff previews. Non-interactive/CI mode is secure by default (Bash denied unless explicitly allowed).
50
+ - **Robust Interactive REPL**: Multiline support (Alt+Enter), syntax highlighting, and beautiful `rich`-powered UI menus.
51
+ - **Automated Workflows**: Automatic linting and formatting using `black`, `flake8`, and `prettier` behind the scenes.
52
+ - **Model Context Protocol (MCP)**: Native integration for MCP tools allowing infinite extensibility.
53
+ - **Context Management**: Auto-compact with per-model context window awareness. `/thinkback` shows real session statistics.
54
+ - **Live Sync**: Workspace watcher automatically updates the repo map in the agent's context when files change.
55
+
56
+ ### 🚀 What We're Working On (Roadmap)
57
+ - **Sub-agent Swarms**: Perfecting `/delegate` and `/swarm` to distribute complex tasks among specialized AI roles.
58
+ - **Advanced Diagnostics**: Refining `/bughunter`, `/security-review`, and `/doctor` for automated codebase auditing.
59
+ - **Test-Driven Development**: Upgrading `/tdd` and `/testgen` to automatically write tests and ensure 100% coverage before committing.
60
+ - **Infrastructure & DevOps**: Implementing `/terraform-god` and `/sql-tune` for automated cloud provisioning and database query optimization.
61
+
62
+ ---
63
+
64
+ ## 📦 Installation & Update
65
+
66
+ ```bash
67
+ # First time install
68
+ pip install nimcode
69
+
70
+ # Update to latest version
71
+ pip install --upgrade nimcode
72
+ ```
73
+
74
+ > **⚠️ If NimCode shows an old version number at startup**, you likely have an older install. Run `pip install --upgrade nimcode` to get the latest fixes.
75
+
76
+ ## 🚀 Quick Start
77
+
78
+ 1. **Get an API Key**: Grab a free NVIDIA API key from [build.nvidia.com](https://build.nvidia.com/).
79
+ 2. **Login**: Connect your local environment by running:
80
+ ```bash
81
+ nimcode login
82
+ ```
83
+ 3. **Start Coding**:
84
+ - Launch the interactive REPL:
85
+ ```bash
86
+ nimcode
87
+ ```
88
+ - Or run a one-off task directly from the command line:
89
+ ```bash
90
+ nimcode /plan "Build a classic Snake game using HTML5 Canvas"
91
+ ```
92
+
93
+ ---
94
+
95
+ ## 💻 Complete Command Reference
96
+
97
+ Inside the `nimcode` REPL, you can type natural language or use any of the following slash commands:
98
+
99
+ ### Mode Toggles & Execution
100
+ - **`/code`**: Enter standard coding mode (default mode, prompts for dangerous actions).
101
+ - **`/plan`**: Enter planning mode. NimCode will **read your actual documents/files first**, then write a concrete implementation plan to `.nimcode/plans/`.
102
+ - **`/trust`**: Enter trust mode. The AI will run commands and edit files completely autonomously without asking for `(a)ccept / (r)eject`. Turn limit removed.
103
+ - **`/untrust`**: Disable trust mode and restore permission prompts.
104
+
105
+ ### Interface & Settings
106
+ - **`/models`**: Open an interactive UI to select your preferred NVIDIA NIM model.
107
+ - **`/theme`**: Open an interactive UI to change your syntax highlighting theme.
108
+ - **`/config`**: View and edit global NimCode configuration settings.
109
+
110
+ ### Workspace & Context Management
111
+ - **`/clear`**: Clear the current conversation history to reset context.
112
+ - **`/compact`**: Compact the context window to save tokens while keeping essential memories.
113
+ - **`/context`**: View and manage the loaded context window.
114
+ - **`/rewind`**: Rewind the conversation history by a few steps.
115
+ - **`/undo`**: Revert the last file modification made by the AI.
116
+ - **`/thinkback`**: View real session statistics (turns, token estimates, message history).
117
+
118
+ ### Project & Search
119
+ - **`/index`**: Index the current project files to enable lightning-fast Semantic Search.
120
+ - **`/map`**: Generate a high-level semantic architecture map of the codebase.
121
+ - **`/research`**: Enter deep-research mode for reading documentation or large files.
122
+
123
+ ### Automation & Git
124
+ - **`/commit`**: Analyze all staged git changes and automatically generate a conventional commit message.
125
+ - **`/fix`**: Run a specific shell command and let the AI automatically iterate to fix any resulting errors.
126
+ - **`/autofix-pr`**: Pulls the current active GitHub Pull Request, reads comments, and automatically fixes the mentioned issues.
127
+
128
+ ### Advanced Development Modes
129
+ - **`/testgen <file>`**: Generate unit tests for a specific file, aiming for 100% coverage.
130
+ - **`/tdd`**: Enter Test-Driven Development mode. The AI will write tests first, verify they fail, and then implement the code to pass them.
131
+ - **`/bughunter`**: Initiate an automated search for logical bugs and edge cases across the codebase.
132
+ - **`/security-review`**: Audit the codebase for common vulnerabilities (e.g., OWASP top 10).
133
+ - **`/ultraplan <task>`**: Generate a master ultra-detailed, dependency-graphed execution plan.
134
+
135
+ ### AI & Agents
136
+ - **`/delegate <role> <task>`**: Spawn an independent sub-agent with a specific role to handle a background task.
137
+ - **`/swarm`**: Orchestrate multiple sub-agents to tackle a complex architectural epic simultaneously.
138
+ - **`/grill-me`**: Interrogation mode. The AI will ask *you* hard questions to refine your system design and edge cases.
139
+ - **`/learn`**: Teach NimCode a new persistent skill or framework rule that it will remember for future sessions.
140
+ - **`/vision`**: Capture the screen and analyze UI elements using Vision AI models.
141
+ - **`/mcp install`**: Install and configure new Model Context Protocol tools.
142
+
143
+ ---
144
+
145
+ ## ⚙️ How it Works
146
+
147
+ NimCode creates a `.nimcode` directory inside your projects. This directory acts as the **agent's personal workspace**, not your project's source code:
148
+ - `.nimcode/plans/`: All generated step-by-step markdown plans live here.
149
+ - `.nimcode/skills/`: Custom guidelines, framework rules, or memories you teach the agent.
150
+ - `.nimcode/history/`: File backups for `/undo` capabilities.
151
+
152
+ > **Important**: NimCode writes your actual source code to your project root, not inside `.nimcode/`. The `.nimcode/` folder is only for the agent's internal notes.
153
+
154
+ ### Advanced Configuration
155
+
156
+ NimCode's behavior can be fully customized through `~/.nimcode/settings.json` (global) or `.nimcode/settings.json` (per-project). Setting any timeout to `0` disables it (infinite).
157
+
158
+ ```json
159
+ {
160
+ "model": "meta/llama-3.1-70b-instruct",
161
+ "api_base_url": "https://integrate.api.nvidia.com/v1",
162
+ "timeout_command": 1200,
163
+ "timeout_llm": 120,
164
+ "timeout_format": 10,
165
+ "timeout_browser": 15000,
166
+ "timeout_updater": 3,
167
+ "max_turns": 200,
168
+ "max_tokens": 120000,
169
+ "max_retries": 15,
170
+ "retry_base_delay": 2.0,
171
+ "retry_max_delay": 60.0,
172
+ "allow_bash_non_interactive": false
173
+ }
174
+ ```
175
+
176
+ | Setting | Default | Description |
177
+ |---------|---------|-------------|
178
+ | `model` | `meta/llama-3.1-70b-instruct` | Default LLM model |
179
+ | `api_base_url` | NVIDIA NIM endpoint | Switch to Ollama/vLLM by changing this |
180
+ | `timeout_command` | 1200 | Max seconds for bash commands (0 = infinite) |
181
+ | `timeout_llm` | 120 | Max seconds for LLM API calls (0 = infinite) |
182
+ | `timeout_format` | 10 | Max seconds for formatters like black/prettier |
183
+ | `timeout_browser` | 15000 | Max ms for browser actions |
184
+ | `timeout_updater` | 3 | Max seconds for update checks |
185
+ | `max_turns` | 200 | Max agent turns per session (0 = unlimited) |
186
+ | `max_tokens` | 120000 | Token budget before auto-compact |
187
+ | `max_retries` | 15 | Max API retry attempts on transient errors |
188
+ | `retry_base_delay` | 2.0 | Base delay for exponential backoff (seconds) |
189
+ | `retry_max_delay` | 60.0 | Max delay cap for backoff (seconds) |
190
+ | `allow_bash_non_interactive` | false | Allow Bash commands in non-interactive/CI mode |
191
+
192
+ ---
193
+
194
+ ## 📋 Changelog
195
+
196
+ ### v0.4.0 (Latest)
197
+ - 🐛 **System prompt is now OS-aware**: Correctly uses Windows (`mkdir`, `copy`) or Unix (`mkdir -p`, `cp`) commands based on the detected OS
198
+ - 🐛 **Plan quality massively improved**: `/plan` mode now reads your actual documents (SDD, PRD, etc.) and generates concrete plans with real file paths and code — not generic PM templates
199
+ - 🐛 **Fixed `_distill_memory` 400 error**: Context compaction no longer crashes with a Bad Request error
200
+ - 🐛 **Fixed version tracking**: `CURRENT_VERSION` was hardcoded as `3.0.0`; now reads from a single source of truth
201
+ - 🐛 **`/thinkback` shows real data**: Previously showed hardcoded fake table; now shows actual session statistics
202
+ - 🐛 **LiveSync fixed**: `repo_map` module was missing, causing the workspace watcher to silently fail
203
+ - 🔒 **Security**: Non-interactive mode no longer auto-approves Bash commands
204
+ - ⚙️ **Fully configurable**: `max_turns`, `max_tokens`, `max_retries`, retry delays all configurable via settings
205
+ - ⚙️ **Dynamic model list**: Fetched from NIM API at runtime with fallback to known models
206
+ - ⚙️ **Paginated file reading**: `Read` tool supports `offset`/`limit` for large files
207
+ - ✅ **178 tests passing**
208
+
209
+ ### v0.3.4
210
+ - All timeouts configurable via settings (0 = infinite)
211
+
212
+ ---
213
+
214
+ ## 🛡️ Requirements
215
+
216
+ - Python 3.8+
217
+ - An NVIDIA NIM API Key (`NIM_API_KEY`)
218
+
219
+ ## 🤝 Contributing
220
+
221
+ Contributions, issues, and feature requests are welcome! Feel free to check out our [issues page](#).
222
+
223
+ ---
224
+ <div align="center">
225
+ <i>Built with ❤️ for the open-source developer community.</i>
226
+ </div>
@@ -15,17 +15,22 @@
15
15
 
16
16
  ## 🌟 Overview
17
17
 
18
- NimCode is your autonomous coding pair-programmer. Built with a rich interactive terminal interface, it doesn't just autocomplete code—it plans architectures, executes terminal commands, writes complete files, formats code automatically, and manages your workspace.
18
+ NimCode is your autonomous coding pair-programmer. Built with a rich interactive terminal interface, it doesn't just autocomplete code—it plans architectures based on real documents (SDD, PRD, RFC), executes terminal commands, writes complete files, and manages your workspace.
19
19
 
20
- ### 🛠️ What We've Built So Far
20
+ ### What Works Right Now
21
+ - **OS-Aware Agent**: Automatically detects Windows/Linux/macOS and uses the correct shell commands. No more `mkdir -p` on Windows.
22
+ - **SDD/PRD-Aware Planning**: `/plan` mode reads your actual documents and produces implementation plans grounded in real file names, modules, and requirements—not generic PM templates.
23
+ - **Paginated File Reading**: Large files (like SDDs) are read in chunks with `offset`/`limit` so nothing gets truncated.
21
24
  - **VS Code Deep Integration**: Native IPC communication allowing NimCode to read active editors, send patches, and act as your intelligent coding panel within VS Code.
22
25
  - **RAG & Semantic Search**: Zero-dependency TF-IDF/BM25 based indexer that instantly scans massive workspaces and retrieves context-aware code snippets.
23
- - **Autonomous Auto-Fixer**: The `/fix` command creates a self-healing feedback loop—it runs your broken commands, analyzes the tracebacks, and automatically iterates on code patches until the build passes.
24
- - **Multi-Model & Local Support**: Flexible `api_base_url` configuration to seamlessly switch between NVIDIA NIM, Ollama, or vLLM endpoints.
25
- - **Smart Permission Engine**: Granular control over file writes and command executions, featuring an auto-bypass mechanism and interactive `(a)ccept / (r)eject` diff previews.
26
+ - **Autonomous Auto-Fixer**: The `/fix` command creates a self-healing feedback loop—runs your broken commands, analyzes tracebacks, and automatically iterates on code patches until the build passes.
27
+ - **Multi-Model & Local Support**: Flexible `api_base_url` configuration to seamlessly switch between NVIDIA NIM, Ollama, or vLLM endpoints. Dynamic model list fetched from the API at runtime.
28
+ - **Smart Permission Engine**: Granular control over file writes and command executions, featuring an auto-bypass mechanism and interactive `(a)ccept / (r)eject` diff previews. Non-interactive/CI mode is secure by default (Bash denied unless explicitly allowed).
26
29
  - **Robust Interactive REPL**: Multiline support (Alt+Enter), syntax highlighting, and beautiful `rich`-powered UI menus.
27
30
  - **Automated Workflows**: Automatic linting and formatting using `black`, `flake8`, and `prettier` behind the scenes.
28
31
  - **Model Context Protocol (MCP)**: Native integration for MCP tools allowing infinite extensibility.
32
+ - **Context Management**: Auto-compact with per-model context window awareness. `/thinkback` shows real session statistics.
33
+ - **Live Sync**: Workspace watcher automatically updates the repo map in the agent's context when files change.
29
34
 
30
35
  ### 🚀 What We're Working On (Roadmap)
31
36
  - **Sub-agent Swarms**: Perfecting `/delegate` and `/swarm` to distribute complex tasks among specialized AI roles.
@@ -35,14 +40,18 @@ NimCode is your autonomous coding pair-programmer. Built with a rich interactive
35
40
 
36
41
  ---
37
42
 
38
- ## 📦 Installation
39
-
40
- NimCode is available globally via PyPI. You can install it anywhere in seconds:
43
+ ## 📦 Installation & Update
41
44
 
42
45
  ```bash
46
+ # First time install
43
47
  pip install nimcode
48
+
49
+ # Update to latest version
50
+ pip install --upgrade nimcode
44
51
  ```
45
52
 
53
+ > **⚠️ If NimCode shows an old version number at startup**, you likely have an older install. Run `pip install --upgrade nimcode` to get the latest fixes.
54
+
46
55
  ## 🚀 Quick Start
47
56
 
48
57
  1. **Get an API Key**: Grab a free NVIDIA API key from [build.nvidia.com](https://build.nvidia.com/).
@@ -64,17 +73,17 @@ pip install nimcode
64
73
 
65
74
  ## 💻 Complete Command Reference
66
75
 
67
- Inside the `nimcode` REPL, you can type natural language or use any of the following slash commands to trigger specific workflows:
76
+ Inside the `nimcode` REPL, you can type natural language or use any of the following slash commands:
68
77
 
69
78
  ### Mode Toggles & Execution
70
79
  - **`/code`**: Enter standard coding mode (default mode, prompts for dangerous actions).
71
- - **`/plan`**: Enter planning mode (read-only safe mode). The AI will research and write a markdown plan before modifying code.
72
- - **`/trust`**: Enter trust mode. The AI will run commands and edit files completely autonomously without asking for `(a)ccept / (r)eject`.
80
+ - **`/plan`**: Enter planning mode. NimCode will **read your actual documents/files first**, then write a concrete implementation plan to `.nimcode/plans/`.
81
+ - **`/trust`**: Enter trust mode. The AI will run commands and edit files completely autonomously without asking for `(a)ccept / (r)eject`. Turn limit removed.
73
82
  - **`/untrust`**: Disable trust mode and restore permission prompts.
74
83
 
75
84
  ### Interface & Settings
76
- - **`/models`**: Open an interactive UI to select your preferred NVIDIA NIM model (e.g., meta/llama-3.1-70b-instruct).
77
- - **`/theme`**: Open an interactive UI to change your syntax highlighting theme (e.g., monokai, dracula, nord, github).
85
+ - **`/models`**: Open an interactive UI to select your preferred NVIDIA NIM model.
86
+ - **`/theme`**: Open an interactive UI to change your syntax highlighting theme.
78
87
  - **`/config`**: View and edit global NimCode configuration settings.
79
88
 
80
89
  ### Workspace & Context Management
@@ -83,6 +92,7 @@ Inside the `nimcode` REPL, you can type natural language or use any of the follo
83
92
  - **`/context`**: View and manage the loaded context window.
84
93
  - **`/rewind`**: Rewind the conversation history by a few steps.
85
94
  - **`/undo`**: Revert the last file modification made by the AI.
95
+ - **`/thinkback`**: View real session statistics (turns, token estimates, message history).
86
96
 
87
97
  ### Project & Search
88
98
  - **`/index`**: Index the current project files to enable lightning-fast Semantic Search.
@@ -99,9 +109,7 @@ Inside the `nimcode` REPL, you can type natural language or use any of the follo
99
109
  - **`/tdd`**: Enter Test-Driven Development mode. The AI will write tests first, verify they fail, and then implement the code to pass them.
100
110
  - **`/bughunter`**: Initiate an automated search for logical bugs and edge cases across the codebase.
101
111
  - **`/security-review`**: Audit the codebase for common vulnerabilities (e.g., OWASP top 10).
102
- - **`/sql-tune`**: Database telepathy mode. Analyzes and auto-tunes SQL queries for maximum performance.
103
- - **`/terraform-god`**: Cloud architect mode. Auto-provisions scalable best-practice Terraform infrastructure.
104
- - **`/decompile <binary>`**: Reverse engineering mode using tools like `objdump` and `radare2`.
112
+ - **`/ultraplan <task>`**: Generate a master ultra-detailed, dependency-graphed execution plan.
105
113
 
106
114
  ### AI & Agents
107
115
  - **`/delegate <role> <task>`**: Spawn an independent sub-agent with a specific role to handle a background task.
@@ -109,24 +117,27 @@ Inside the `nimcode` REPL, you can type natural language or use any of the follo
109
117
  - **`/grill-me`**: Interrogation mode. The AI will ask *you* hard questions to refine your system design and edge cases.
110
118
  - **`/learn`**: Teach NimCode a new persistent skill or framework rule that it will remember for future sessions.
111
119
  - **`/vision`**: Capture the screen and analyze UI elements using Vision AI models.
112
- - **`/voice`**: Record your voice for 5 seconds and transcribe it as a prompt.
113
120
  - **`/mcp install`**: Install and configure new Model Context Protocol tools.
114
121
 
115
122
  ---
116
123
 
117
124
  ## ⚙️ How it Works
118
125
 
119
- NimCode creates a `.nimcode` directory inside your projects. This directory acts as the "brain" for that specific workspace:
120
- - `.nimcode/plans/`: All your generated step-by-step markdown plans live here.
121
- - `.nimcode/skills/`: Any custom guidelines, framework rules, or memories you teach the agent.
126
+ NimCode creates a `.nimcode` directory inside your projects. This directory acts as the **agent's personal workspace**, not your project's source code:
127
+ - `.nimcode/plans/`: All generated step-by-step markdown plans live here.
128
+ - `.nimcode/skills/`: Custom guidelines, framework rules, or memories you teach the agent.
122
129
  - `.nimcode/history/`: File backups for `/undo` capabilities.
123
130
 
131
+ > **Important**: NimCode writes your actual source code to your project root, not inside `.nimcode/`. The `.nimcode/` folder is only for the agent's internal notes.
132
+
124
133
  ### Advanced Configuration
125
134
 
126
135
  NimCode's behavior can be fully customized through `~/.nimcode/settings.json` (global) or `.nimcode/settings.json` (per-project). Setting any timeout to `0` disables it (infinite).
127
136
 
128
137
  ```json
129
138
  {
139
+ "model": "meta/llama-3.1-70b-instruct",
140
+ "api_base_url": "https://integrate.api.nvidia.com/v1",
130
141
  "timeout_command": 1200,
131
142
  "timeout_llm": 120,
132
143
  "timeout_format": 10,
@@ -143,6 +154,8 @@ NimCode's behavior can be fully customized through `~/.nimcode/settings.json` (g
143
154
 
144
155
  | Setting | Default | Description |
145
156
  |---------|---------|-------------|
157
+ | `model` | `meta/llama-3.1-70b-instruct` | Default LLM model |
158
+ | `api_base_url` | NVIDIA NIM endpoint | Switch to Ollama/vLLM by changing this |
146
159
  | `timeout_command` | 1200 | Max seconds for bash commands (0 = infinite) |
147
160
  | `timeout_llm` | 120 | Max seconds for LLM API calls (0 = infinite) |
148
161
  | `timeout_format` | 10 | Max seconds for formatters like black/prettier |
@@ -155,6 +168,28 @@ NimCode's behavior can be fully customized through `~/.nimcode/settings.json` (g
155
168
  | `retry_max_delay` | 60.0 | Max delay cap for backoff (seconds) |
156
169
  | `allow_bash_non_interactive` | false | Allow Bash commands in non-interactive/CI mode |
157
170
 
171
+ ---
172
+
173
+ ## 📋 Changelog
174
+
175
+ ### v0.4.0 (Latest)
176
+ - 🐛 **System prompt is now OS-aware**: Correctly uses Windows (`mkdir`, `copy`) or Unix (`mkdir -p`, `cp`) commands based on the detected OS
177
+ - 🐛 **Plan quality massively improved**: `/plan` mode now reads your actual documents (SDD, PRD, etc.) and generates concrete plans with real file paths and code — not generic PM templates
178
+ - 🐛 **Fixed `_distill_memory` 400 error**: Context compaction no longer crashes with a Bad Request error
179
+ - 🐛 **Fixed version tracking**: `CURRENT_VERSION` was hardcoded as `3.0.0`; now reads from a single source of truth
180
+ - 🐛 **`/thinkback` shows real data**: Previously showed hardcoded fake table; now shows actual session statistics
181
+ - 🐛 **LiveSync fixed**: `repo_map` module was missing, causing the workspace watcher to silently fail
182
+ - 🔒 **Security**: Non-interactive mode no longer auto-approves Bash commands
183
+ - ⚙️ **Fully configurable**: `max_turns`, `max_tokens`, `max_retries`, retry delays all configurable via settings
184
+ - ⚙️ **Dynamic model list**: Fetched from NIM API at runtime with fallback to known models
185
+ - ⚙️ **Paginated file reading**: `Read` tool supports `offset`/`limit` for large files
186
+ - ✅ **178 tests passing**
187
+
188
+ ### v0.3.4
189
+ - All timeouts configurable via settings (0 = infinite)
190
+
191
+ ---
192
+
158
193
  ## 🛡️ Requirements
159
194
 
160
195
  - Python 3.8+
@@ -1,5 +1,6 @@
1
1
  from setuptools import setup, find_packages
2
2
  import os
3
+ from pathlib import Path
3
4
 
4
5
  # Single source of truth for version
5
6
  version = {}
@@ -25,4 +26,8 @@ setup(
25
26
  },
26
27
  author="Autonomous Agent",
27
28
  description="A standalone, robust coding agent for NVIDIA NIM models.",
29
+ long_description=Path("README.md").read_text(encoding="utf-8"),
30
+ long_description_content_type="text/markdown",
31
+ url="https://github.com/Batunash/nimcode",
32
+ python_requires=">=3.8",
28
33
  )
@@ -0,0 +1 @@
1
+ __version__ = "0.4.2"
@@ -30,11 +30,12 @@ Format:
30
30
 
31
31
  Available Tools:
32
32
  - Bash: {{"tool": "Bash", "args": {{"command": "string"}}}}
33
- - Read: {{"tool": "Read", "args": {{"file_path": "string"}}}}
33
+ - Read: {{"tool": "Read", "args": {{"file_path": "string", "offset": "int (optional, 1-based line number to start from)", "limit": "int (optional, max number of lines to return)"}}}}
34
34
  - Write: {{"tool": "Write", "args": {{"file_path": "string", "content": "string"}}}}
35
35
  - Edit: {{"tool": "Edit", "args": {{"file_path": "string", "old_string": "string", "new_string": "string"}}}}
36
36
  - Glob: {{"tool": "Glob", "args": {{"pattern": "string"}}}}
37
37
  - Grep: {{"tool": "Grep", "args": {{"query": "string", "directory": "string"}}}}
38
+ - AskQuestion: {{"tool": "AskQuestion", "args": {{"question": "string", "options": ["string (optional list of choices)"]}}}} — Ask the USER a clarifying question when requirements are ambiguous. Wait for their reply before continuing. Preferred in /grill-me, /plan, and whenever you lack information.
38
39
 
39
40
  Before calling a tool, you may optionally use a <think> block to reason about your plan.
40
41
  <think>
@@ -173,21 +174,40 @@ class Agent:
173
174
 
174
175
  self.permission_engine = PermissionEngine(mode=permission_mode)
175
176
 
177
+ def _session_history_path(self) -> str:
178
+ """Path for serialized session history.
179
+
180
+ Uses a fresh '.nimcode/sessions/' subdir — NOT '.nimcode/history/' — because
181
+ repl.py's PromptSession already uses '.nimcode/history' as a *file* for
182
+ prompt_toolkit FileHistory. A path cannot be both a file and a directory:
183
+ trying to makedirs('.nimcode/history') while FileHistory treats it as a file
184
+ raises NotADirectoryError, which save_history's try/except would silently
185
+ swallow (re-breaking --resume). 'sessions' is collision-free. This also keeps
186
+ session JSON separate from NIMCODE.md, the human-readable log appended by
187
+ MemoryManager.log_to_nimcode_md — fixing the original Bug B (two producers
188
+ overwriting each other -> JSONDecodeError on load)."""
189
+ return os.path.join(os.getcwd(), ".nimcode", "sessions", "session.json")
190
+
176
191
  def save_history(self):
177
- """Saves current conversation to NIMCODE.md"""
192
+ """Saves current conversation (machine-readable JSON) to .nimcode/sessions/session.json."""
178
193
  try:
179
194
  import json
180
- with open("NIMCODE.md", "w", encoding="utf-8") as f:
195
+ path = self._session_history_path()
196
+ # Ensure the parent dir exists (handles one-shot `nimcode "prompt"` and
197
+ # `--resume` paths that don't go through the REPL's .nimcode bootstrap).
198
+ os.makedirs(os.path.dirname(path), exist_ok=True)
199
+ with open(path, "w", encoding="utf-8") as f:
181
200
  json.dump(self.messages, f)
182
201
  except Exception as e:
183
202
  logger.error(f"Failed to save history: {e}")
184
203
 
185
204
  def load_history(self):
186
- """Loads conversation from NIMCODE.md"""
205
+ """Loads conversation from .nimcode/sessions/session.json (if present)."""
187
206
  try:
188
207
  import json
189
- if os.path.exists("NIMCODE.md"):
190
- with open("NIMCODE.md", "r", encoding="utf-8") as f:
208
+ path = self._session_history_path()
209
+ if os.path.exists(path):
210
+ with open(path, "r", encoding="utf-8") as f:
191
211
  self.messages = json.load(f)
192
212
  except Exception as e:
193
213
  logger.error(f"Failed to load history: {e}")
@@ -1,5 +1,6 @@
1
1
  import argparse
2
2
  import asyncio
3
+ import logging
3
4
  import os
4
5
  import sys
5
6
  from rich.console import Console
@@ -7,6 +8,7 @@ from .agent import Agent
7
8
  from .config import load_settings, save_global_setting
8
9
  from .permissions import PermissionMode
9
10
 
11
+ logger = logging.getLogger(__name__)
10
12
  console = Console()
11
13
 
12
14
  def run_login():
@@ -24,11 +26,14 @@ def run_login():
24
26
 
25
27
  def run_doctor():
26
28
  console.print("[bold cyan]NimCode Doctor[/bold cyan] - Diagnostics")
27
- key = os.environ.get("NIM_API_KEY")
28
- if key:
29
- console.print("[green][OK][/green] NIM_API_KEY environment variable is set.")
29
+ env_key = os.environ.get("NIM_API_KEY")
30
+ settings = load_settings()
31
+ settings_key = settings.get("api_key")
32
+ if env_key or settings_key:
33
+ source = "environment variable" if env_key else "settings.json (`nimcode login`)"
34
+ console.print(f"[green][OK][/green] NIM API key found via {source}.")
30
35
  else:
31
- console.print("[red][X][/red] NIM_API_KEY environment variable is missing.")
36
+ console.print("[red][X][/red] No NIM API key found. Set NIM_API_KEY or run `nimcode login`.")
32
37
 
33
38
  # Check .nimcode existence
34
39
  if os.path.exists(".nimcode"):
@@ -43,26 +48,36 @@ def install_hook():
43
48
  if not os.path.exists(".git"):
44
49
  console.print("[red][X][/red] Not a git repository.")
45
50
  return
46
-
51
+
47
52
  hook_path = os.path.join(".git", "hooks", "prepare-commit-msg")
48
53
  with open(hook_path, "w", encoding="utf-8") as f:
49
54
  f.write("#!/bin/sh\n")
50
55
  f.write("# NimCode auto-commit hook\n")
56
+ f.write("# Only generate a message if the user hasn't supplied one.\n")
51
57
  f.write("if [ -z \"$(cat $1)\" ]; then\n")
52
- f.write(" nimcode /commit > $1\n")
58
+ f.write(" nimcode \"Generate a conventional commit message for the currently staged changes. Use the Bash tool to run 'git diff --staged', then write ONLY the commit message (no preamble, no explanation) to stdout.\" > \"$1\"\n")
53
59
  f.write("fi\n")
54
-
55
- import stat
56
- os.chmod(hook_path, os.stat(hook_path).st_mode | stat.S_IEXEC)
60
+
61
+ # Make it executable. On Windows the stat bit is a no-op, but Git for Windows
62
+ # runs hooks regardless; guard against platforms where chmod is unsupported.
63
+ try:
64
+ import stat
65
+ os.chmod(hook_path, os.stat(hook_path).st_mode | stat.S_IEXEC)
66
+ except Exception as e:
67
+ logger.debug("Could not set executable bit on hook (non-fatal): %s", e)
57
68
  console.print(f"[green][OK][/green] Git hook installed to {hook_path}")
58
69
 
59
70
  def _silence_anyio_errors():
60
71
  import sys
61
72
  original_hook = sys.unraisablehook
62
73
  def custom_unraisablehook(unraisable):
74
+ # These are known teardown-noise patterns from anyio/MCP that surface on Ctrl+C.
75
+ # Log at debug (traceable) instead of silently swallowing, so genuine errors still surface.
63
76
  if unraisable.exc_type == RuntimeError and "exit cancel scope in a different task" in str(unraisable.exc_value):
77
+ logger.debug("anyio cancel-scope teardown noise (suppressed): %s", unraisable.exc_value)
64
78
  return
65
79
  if unraisable.exc_type == BaseExceptionGroup and "unhandled errors in a TaskGroup" in str(unraisable.exc_value):
80
+ logger.debug("anyio TaskGroup teardown noise (suppressed): %s", unraisable.exc_value)
66
81
  return
67
82
  original_hook(unraisable)
68
83
  sys.unraisablehook = custom_unraisablehook
@@ -87,9 +102,9 @@ def main():
87
102
  parser.add_argument("prompt", nargs="?", default=None, help="The task you want NimCode to accomplish. If omitted, starts interactive REPL.")
88
103
  parser.add_argument("--api-key", "-k", default=None, help="NVIDIA NIM API Key. Can also be set via NIM_API_KEY environment variable.")
89
104
  parser.add_argument("--model", "-m", default="meta/llama-3.1-70b-instruct", help="Model ID to use from NIM.")
90
- parser.add_argument("--max-turns", "-t", type=int, default=30, help="Maximum number of turns the agent is allowed to run.")
105
+ parser.add_argument("--max-turns", "-t", type=int, default=None, help="Maximum number of turns the agent is allowed to run. If omitted, uses settings.json max_turns (default 200; 0 = unlimited).")
91
106
  parser.add_argument("--permission-mode", "-p", type=PermissionMode, choices=list(PermissionMode), default=PermissionMode.DEFAULT, help="Permission mode for mutating tools.")
92
- parser.add_argument("--resume", "-r", action="store_true", help="Resume from the last session stored in NIMCODE.md.")
107
+ parser.add_argument("--resume", "-r", action="store_true", help="Resume from the last session stored in .nimcode/sessions/session.json.")
93
108
 
94
109
  args = parser.parse_args()
95
110
 
@@ -127,10 +142,14 @@ def main():
127
142
  msg = context.get("message", "")
128
143
  exception = context.get("exception", None)
129
144
  if "unhandled errors in a TaskGroup" in str(msg) or "unhandled errors in a TaskGroup" in str(exception):
145
+ logger.debug("TaskGroup teardown noise (suppressed): %s", exception or msg)
130
146
  return
131
147
  if exception and isinstance(exception, RuntimeError) and "exit cancel scope in a different task" in str(exception):
148
+ logger.debug("anyio cancel-scope teardown noise (suppressed): %s", exception)
132
149
  return
133
- if "asynchronous generator" in str(msg):
150
+ # Only swallow the specific shutdown-warning shapes, not all async generator messages.
151
+ if "asynchronous generator" in str(msg) and ("never awaited" in str(msg) or "GeneratorExit" in str(msg)):
152
+ logger.debug("async generator teardown noise (suppressed): %s", msg)
134
153
  return
135
154
  loop.default_exception_handler(context)
136
155
  loop.set_exception_handler(custom_exception_handler)
@@ -139,25 +158,32 @@ def main():
139
158
  await repl.start_repl()
140
159
  except asyncio.CancelledError:
141
160
  pass
161
+ except KeyboardInterrupt:
162
+ console.print("\n[bold yellow]Goodbye![/bold yellow]")
142
163
 
143
164
  piped_input = None
144
165
  if not sys.stdin.isatty():
145
166
  piped_input = sys.stdin.read().strip()
146
167
 
147
- if piped_input:
148
- console.print(f"[bold green]Starting NimCode[/bold green] with model [cyan]{args.model}[/cyan]")
149
- prompt = f"{piped_input}\n\n{args.prompt or ''}".strip()
150
- console.print(f"Task (with piped input): {prompt}")
151
- asyncio.run(agent.run(prompt))
152
- elif args.prompt:
153
- console.print(f"[bold green]Starting NimCode[/bold green] with model [cyan]{args.model}[/cyan]")
154
- console.print(f"Task: {args.prompt}")
155
- asyncio.run(agent.run(args.prompt))
156
- else:
157
- from .repl import NimcodeREPL
158
- repl = NimcodeREPL(agent)
159
- asyncio.run(safe_start_repl(repl))
160
-
168
+ try:
169
+ if piped_input:
170
+ console.print(f"[bold green]Starting NimCode[/bold green] with model [cyan]{args.model}[/cyan]")
171
+ prompt = f"{piped_input}\n\n{args.prompt or ''}".strip()
172
+ console.print(f"Task (with piped input): {prompt}")
173
+ asyncio.run(agent.run(prompt))
174
+ elif args.prompt:
175
+ console.print(f"[bold green]Starting NimCode[/bold green] with model [cyan]{args.model}[/cyan]")
176
+ console.print(f"Task: {args.prompt}")
177
+ asyncio.run(agent.run(args.prompt))
178
+ else:
179
+ from .repl import NimcodeREPL
180
+ repl = NimcodeREPL(agent)
181
+ asyncio.run(safe_start_repl(repl))
182
+ except KeyboardInterrupt:
183
+ # Ctrl+C during an active async stream/await — graceful exit, no traceback.
184
+ console.print("\n[bold yellow]Interrupted. Exiting NimCode.[/bold yellow]")
185
+ return
186
+
161
187
  # We don't print "Done!" for REPL to keep it clean on exit
162
188
  if args.prompt or piped_input:
163
189
  console.print("[bold green]Done![/bold green]")