nrgrd 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.
Files changed (63) hide show
  1. nrgrd-0.1.0/.github/workflows/ci.yml +58 -0
  2. nrgrd-0.1.0/.github/workflows/release.yml +98 -0
  3. nrgrd-0.1.0/.gitignore +94 -0
  4. nrgrd-0.1.0/.python-version +1 -0
  5. nrgrd-0.1.0/LICENSE +21 -0
  6. nrgrd-0.1.0/PKG-INFO +188 -0
  7. nrgrd-0.1.0/README.md +156 -0
  8. nrgrd-0.1.0/pyproject.toml +60 -0
  9. nrgrd-0.1.0/src/nrgrd/__init__.py +7 -0
  10. nrgrd-0.1.0/src/nrgrd/__main__.py +5 -0
  11. nrgrd-0.1.0/src/nrgrd/agent/__init__.py +29 -0
  12. nrgrd-0.1.0/src/nrgrd/agent/events.py +86 -0
  13. nrgrd-0.1.0/src/nrgrd/agent/loop.py +182 -0
  14. nrgrd-0.1.0/src/nrgrd/agent/permissions.py +43 -0
  15. nrgrd-0.1.0/src/nrgrd/api/__init__.py +15 -0
  16. nrgrd-0.1.0/src/nrgrd/api/openai_compatible.py +186 -0
  17. nrgrd-0.1.0/src/nrgrd/api/provider.py +78 -0
  18. nrgrd-0.1.0/src/nrgrd/app.py +1603 -0
  19. nrgrd-0.1.0/src/nrgrd/config/__init__.py +15 -0
  20. nrgrd-0.1.0/src/nrgrd/config/config.py +141 -0
  21. nrgrd-0.1.0/src/nrgrd/config/credentials.py +135 -0
  22. nrgrd-0.1.0/src/nrgrd/context/__init__.py +6 -0
  23. nrgrd-0.1.0/src/nrgrd/context/models.py +17 -0
  24. nrgrd-0.1.0/src/nrgrd/context/tokens.py +55 -0
  25. nrgrd-0.1.0/src/nrgrd/mcp.py +316 -0
  26. nrgrd-0.1.0/src/nrgrd/screens/__init__.py +3 -0
  27. nrgrd-0.1.0/src/nrgrd/screens/connect.py +232 -0
  28. nrgrd-0.1.0/src/nrgrd/sessions/__init__.py +13 -0
  29. nrgrd-0.1.0/src/nrgrd/sessions/manager.py +146 -0
  30. nrgrd-0.1.0/src/nrgrd/sessions/store.py +363 -0
  31. nrgrd-0.1.0/src/nrgrd/system/__init__.py +13 -0
  32. nrgrd-0.1.0/src/nrgrd/system/prompt.py +126 -0
  33. nrgrd-0.1.0/src/nrgrd/theme/__init__.py +0 -0
  34. nrgrd-0.1.0/src/nrgrd/theme/colors.py +23 -0
  35. nrgrd-0.1.0/src/nrgrd/tools/__init__.py +56 -0
  36. nrgrd-0.1.0/src/nrgrd/tools/filesystem.py +35 -0
  37. nrgrd-0.1.0/src/nrgrd/tools/git.py +45 -0
  38. nrgrd-0.1.0/src/nrgrd/tools/registry.py +107 -0
  39. nrgrd-0.1.0/src/nrgrd/tools/search.py +98 -0
  40. nrgrd-0.1.0/src/nrgrd/tools/shell.py +64 -0
  41. nrgrd-0.1.0/src/nrgrd/widgets/__init__.py +0 -0
  42. nrgrd-0.1.0/src/nrgrd/widgets/logo.py +178 -0
  43. nrgrd-0.1.0/src/nrgrd/workspace/__init__.py +12 -0
  44. nrgrd-0.1.0/src/nrgrd/workspace/discovery.py +131 -0
  45. nrgrd-0.1.0/src/nrgrd/workspace/identity.py +58 -0
  46. nrgrd-0.1.0/src/nrgrd/workspace/mcp_server.py +74 -0
  47. nrgrd-0.1.0/src/nrgrd/workspace/tools.py +304 -0
  48. nrgrd-0.1.0/tests/__init__.py +0 -0
  49. nrgrd-0.1.0/tests/conftest.py +79 -0
  50. nrgrd-0.1.0/tests/helpers.py +35 -0
  51. nrgrd-0.1.0/tests/test_agent_loop.py +148 -0
  52. nrgrd-0.1.0/tests/test_app_regressions.py +133 -0
  53. nrgrd-0.1.0/tests/test_audit_regressions.py +209 -0
  54. nrgrd-0.1.0/tests/test_cancellation.py +123 -0
  55. nrgrd-0.1.0/tests/test_connect_screen.py +144 -0
  56. nrgrd-0.1.0/tests/test_context_safety.py +85 -0
  57. nrgrd-0.1.0/tests/test_credentials.py +64 -0
  58. nrgrd-0.1.0/tests/test_discovery.py +64 -0
  59. nrgrd-0.1.0/tests/test_logo.py +58 -0
  60. nrgrd-0.1.0/tests/test_permissions.py +42 -0
  61. nrgrd-0.1.0/tests/test_provider.py +171 -0
  62. nrgrd-0.1.0/tests/test_sessions.py +101 -0
  63. nrgrd-0.1.0/tests/test_tool_registry.py +43 -0
@@ -0,0 +1,58 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ${{ matrix.os }}
11
+ strategy:
12
+ fail-fast: false
13
+ matrix:
14
+ os: [ubuntu-latest, macos-latest, windows-latest]
15
+ # The oldest supported Python and the newest, on every platform.
16
+ python: ["3.11", "3.14"]
17
+ env:
18
+ UV_PYTHON: ${{ matrix.python }}
19
+
20
+ steps:
21
+ - uses: actions/checkout@v4
22
+ with:
23
+ fetch-depth: 0
24
+
25
+ - name: Install uv
26
+ uses: astral-sh/setup-uv@v5
27
+ with:
28
+ enable-cache: true
29
+
30
+ - name: Install the project
31
+ run: uv sync --dev
32
+
33
+ - name: Run tests
34
+ run: uv run pytest tests/ -q
35
+ env:
36
+ # No OS keyring exists on CI runners; the credential store must
37
+ # fall back to its file backend rather than hanging on a prompt.
38
+ PYTHON_KEYRING_BACKEND: keyring.backends.fail.Keyring
39
+
40
+ - name: Check the CLI starts
41
+ run: uv run nrgrd --version
42
+
43
+ package:
44
+ # Catches packaging breakage on the pull request, not at release time.
45
+ runs-on: ubuntu-latest
46
+ steps:
47
+ - uses: actions/checkout@v4
48
+ with:
49
+ fetch-depth: 0
50
+
51
+ - name: Install uv
52
+ uses: astral-sh/setup-uv@v5
53
+
54
+ - name: Build
55
+ run: uv build
56
+
57
+ - name: Validate package metadata
58
+ run: uvx twine check --strict dist/*
@@ -0,0 +1,98 @@
1
+ name: Release
2
+
3
+ # Pushing a tag like v0.1.0 builds, verifies, and publishes that version to
4
+ # PyPI, then creates the matching GitHub Release.
5
+ #
6
+ # A PyPI upload is permanent: a version number can never be uploaded twice,
7
+ # even after deleting it. So nothing is published until the tests pass, the
8
+ # built version matches the tag, and the wheel is proven to install and run.
9
+
10
+ on:
11
+ push:
12
+ tags: ["v*"]
13
+
14
+ jobs:
15
+ build:
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+ with:
20
+ # The version is derived from the git tag, which needs history.
21
+ fetch-depth: 0
22
+
23
+ - name: Install uv
24
+ uses: astral-sh/setup-uv@v5
25
+
26
+ - name: Run tests
27
+ run: uv run --dev pytest tests/ -q
28
+ env:
29
+ PYTHON_KEYRING_BACKEND: keyring.backends.fail.Keyring
30
+
31
+ - name: Build the wheel and sdist
32
+ run: uv build
33
+
34
+ - name: Check the built version matches the tag
35
+ run: |
36
+ uv run --no-project --with packaging python - <<'EOF'
37
+ import glob, os, sys
38
+ from packaging.version import Version
39
+
40
+ tag = os.environ["GITHUB_REF_NAME"].removeprefix("v")
41
+ wheel = os.path.basename(glob.glob("dist/*.whl")[0])
42
+ built = wheel.split("-")[1]
43
+ if Version(built) != Version(tag):
44
+ sys.exit(f"Tag {tag} built version {built}; refusing to publish.")
45
+ print(f"Version {built} matches tag.")
46
+ EOF
47
+
48
+ - name: Validate package metadata
49
+ run: uvx twine check --strict dist/*
50
+
51
+ - name: Smoke-test the wheel in a clean environment
52
+ run: |
53
+ uvx --from "$(ls dist/*.whl)" nrgrd --version
54
+ uvx --from "$(ls dist/*.whl)" nrgrd --help > /dev/null
55
+
56
+ - uses: actions/upload-artifact@v4
57
+ with:
58
+ name: dist
59
+ path: dist/
60
+
61
+ publish-pypi:
62
+ needs: build
63
+ runs-on: ubuntu-latest
64
+ # Must match the environment named in the PyPI trusted publisher.
65
+ environment:
66
+ name: pypi
67
+ url: https://pypi.org/project/nrgrd/
68
+ permissions:
69
+ # Trusted publishing: PyPI accepts a short-lived OIDC token from this
70
+ # workflow, so no API token is stored anywhere.
71
+ id-token: write
72
+ steps:
73
+ - uses: actions/download-artifact@v4
74
+ with:
75
+ name: dist
76
+ path: dist/
77
+
78
+ - name: Publish to PyPI
79
+ uses: pypa/gh-action-pypi-publish@release/v1
80
+
81
+ github-release:
82
+ # After PyPI, so a release page never advertises a version that failed
83
+ # to publish.
84
+ needs: publish-pypi
85
+ runs-on: ubuntu-latest
86
+ permissions:
87
+ contents: write
88
+ steps:
89
+ - uses: actions/download-artifact@v4
90
+ with:
91
+ name: dist
92
+ path: dist/
93
+
94
+ - name: Create the GitHub Release
95
+ uses: softprops/action-gh-release@v2
96
+ with:
97
+ files: dist/*
98
+ generate_release_notes: true
nrgrd-0.1.0/.gitignore ADDED
@@ -0,0 +1,94 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ *.egg
7
+ *.egg-info/
8
+ dist/
9
+ build/
10
+ eggs/
11
+ .installed.cfg
12
+ lib/
13
+ lib64/
14
+ parts/
15
+ sdist/
16
+ var/
17
+ wheels/
18
+ share/python-wheels/
19
+ *.manifest
20
+ *.spec
21
+
22
+ # Virtual environments
23
+ .venv/
24
+ venv/
25
+ ENV/
26
+ env/
27
+ .conda/
28
+
29
+ # IDEs and editors
30
+ .vscode/
31
+ .idea/
32
+ *.swp
33
+ *.swo
34
+ *~
35
+ .project
36
+ .classpath
37
+ .settings
38
+
39
+ # Testing
40
+ .pytest_cache/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py,cover
50
+ .hypothesis/
51
+ .testmondata
52
+
53
+ # Linting and type checking
54
+ .mypy_cache/
55
+ .dmypy.json
56
+ dmypy.json
57
+ .pyre/
58
+ .pytype/
59
+ .ruff_cache/
60
+ flake8-report.html
61
+
62
+ # Documentation
63
+ docs/_build/
64
+ docs/_static/
65
+ docs/_templates/
66
+ *.md.stamp
67
+ *.inv
68
+
69
+ # Logs
70
+ *.log
71
+ logs/
72
+
73
+ # Environment variables
74
+ .env
75
+ .env.local
76
+ .env.*.local
77
+
78
+ # OS generated files
79
+ .DS_Store
80
+ .DS_Store?
81
+ ._*
82
+ .Spotlight-V100
83
+ .Trashes
84
+ ehthumbs.db
85
+ Thumbs.db
86
+
87
+ # UV
88
+ uv.lock
89
+
90
+ # Project specific
91
+ .manui/
92
+
93
+ docs/
94
+ dist/
@@ -0,0 +1 @@
1
+ 3.14
nrgrd-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 NeuroGrid
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
nrgrd-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,188 @@
1
+ Metadata-Version: 2.5
2
+ Name: nrgrd
3
+ Version: 0.1.0
4
+ Summary: Terminal AI coding agent for OpenAI-compatible inference endpoints, built for NeuroGrid deployments
5
+ Project-URL: Homepage, https://neurogrid.cc
6
+ Project-URL: Repository, https://github.com/NeuroGrid-AI-exchange/neurogrid-tui
7
+ Project-URL: Issues, https://github.com/NeuroGrid-AI-exchange/neurogrid-tui/issues
8
+ Author: NeuroGrid
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: agent,ai,cli,coding-assistant,llm,neurogrid,openai-compatible,tui
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3 :: Only
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: 3.14
22
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
23
+ Classifier: Topic :: Software Development
24
+ Requires-Python: >=3.11
25
+ Requires-Dist: keyring>=25.0.0
26
+ Requires-Dist: openai>=2.50.0
27
+ Requires-Dist: platformdirs>=4.11.0
28
+ Requires-Dist: prompt-toolkit>=3.0.52
29
+ Requires-Dist: pydantic>=2.13.4
30
+ Requires-Dist: rich>=15.0.0
31
+ Description-Content-Type: text/markdown
32
+
33
+ # nrgrd
34
+
35
+ [![PyPI](https://img.shields.io/pypi/v/nrgrd)](https://pypi.org/project/nrgrd/)
36
+ ![Python](https://img.shields.io/badge/python-3.11%2B-blue)
37
+ ![License](https://img.shields.io/badge/license-MIT-green)
38
+ ![Status](https://img.shields.io/badge/status-alpha-orange)
39
+
40
+ **nrgrd** is [NeuroGrid](https://neurogrid.cc)'s Terminal User Interface (TUI)
41
+ for interacting with AI models from your terminal, Claude Code style. Built
42
+ on `rich` and `prompt-toolkit`, it points at any OpenAI-compatible
43
+ inference endpoint — including a NeuroGrid Marketplace deployment (the URL +
44
+ API key of the host you rented) — to chat, manage sessions, and run MCP
45
+ tools.
46
+
47
+ ## Features
48
+
49
+ - **Coding agent** — An iterative tool-use loop (`nrgrd.agent`) that reads, searches, edits, and runs commands in your repository until the task is done.
50
+ - **Workspace aware** — Detects git, language, package manager, and test framework at startup, so the agent doesn't waste turns rediscovering your project.
51
+ - **Interruptible** — Ctrl+C stops generation or a running tool without corrupting the conversation, keeping whatever was produced.
52
+ - **Named sessions** — Several conversations per project: list, resume, rename, delete.
53
+ - **CLI mode** — `nrgrd "fix the failing tests"` runs headless on the same runtime, for scripts and CI.
54
+ - **Native tools** — `list_files`, `read_file`, `write_file`, `edit_file`, `search`, `shell`, `git_status`, `git_diff`.
55
+ - **Permissions** — Read-only tools run automatically; file writes, shell commands, and MCP tools ask for approval first (or "always allow" for the session).
56
+ - **Immersive TUI** — Rich-rendered panels, streaming output, and slash-command completion.
57
+ - **Persistent sessions** — Saves conversation context and history locally.
58
+ - **Any compatible endpoint** — Behind a `ModelProvider` abstraction: a NeuroGrid deployment, vLLM, Ollama, LM Studio, or anything else speaking the same API. All nrgrd needs is a URL, a key, and a model name.
59
+ - **Keys kept out of the config file** — The API key lives in your OS credential store, and never appears in errors or logs.
60
+ - **Errors you can act on** — Failures name the endpoint and model involved and say what to change.
61
+ - **Built-in MCP** — Run and connect MCP servers straight from the terminal; their tools go through the same permission system.
62
+ - **CLI + TUI** — Use `nrgrd` for the interactive interface or `nrgrd-mcp` for the MCP server.
63
+
64
+ ## Installation
65
+
66
+ nrgrd runs on macOS, Linux and Windows, with Python 3.11 or newer.
67
+
68
+ ```bash
69
+ uv tool install nrgrd
70
+ nrgrd
71
+ ```
72
+
73
+ `uv tool install` puts `nrgrd` on your PATH in its own environment, and
74
+ downloads a suitable Python if you don't have one. Update with
75
+ `uv tool upgrade nrgrd`. If you prefer pipx: `pipx install nrgrd`.
76
+
77
+ Don't have uv? See [installing uv](https://docs.astral.sh/uv/getting-started/installation/).
78
+
79
+ ### From source
80
+
81
+ ```bash
82
+ git clone https://github.com/NeuroGrid-AI-exchange/neurogrid-tui.git
83
+ cd neurogrid-tui
84
+ uv sync
85
+ uv run nrgrd
86
+ ```
87
+
88
+ ## Usage
89
+
90
+ ```bash
91
+ nrgrd # interactive TUI
92
+ nrgrd "explain this repository" # one prompt, then exit
93
+ nrgrd --model qwen3-coder "fix the failing tests"
94
+ nrgrd --yes "run the tests" # approve gated tools automatically (CI)
95
+ ```
96
+
97
+ ### Commands
98
+
99
+ | Command | What it does |
100
+ |---|---|
101
+ | `/help` | List every command |
102
+ | `/config`, `/config edit` | Show or change the connection |
103
+ | `/con`, `/models` | Check the endpoint, list its models |
104
+ | `/tools`, `/permissions` | Show tools and how each is gated |
105
+ | `/session list`, `/session new\|resume\|rename\|delete <name>` | Manage sessions |
106
+ | `/diff`, `/context`, `/compact` | Review changes, context usage, summarise |
107
+ | `/mcp`, `/mcp edit`, `/mcp reload` | Manage MCP servers |
108
+
109
+ ## Configuration
110
+
111
+ The first time you run `nrgrd` it opens a **Connect to a model** screen and
112
+ asks for the three things a NeuroGrid deployment hands you:
113
+
114
+ ```
115
+ Endpoint https://<your-deployment>/v1
116
+ API key ••••••••••••
117
+ Model qwen3-coder
118
+ ```
119
+
120
+ It then queries the endpoint and lets you pick from the models it actually
121
+ serves. Run `/config edit` to change any of this later.
122
+
123
+ The endpoint and model are saved to `config.json` in the application's
124
+ config directory. **The API key is not** — it goes to your operating
125
+ system's credential store (Keychain, Windows Credential Manager, or a
126
+ Secret Service keyring). On machines with no usable keyring it falls back
127
+ to an owner-only (`0600`) file, and `/config` tells you which is in use. A
128
+ key left over in an older plaintext `config.json` is migrated out
129
+ automatically on startup.
130
+
131
+ No environment variables are involved.
132
+
133
+ ## Project structure
134
+
135
+ ```
136
+ nrgrd/
137
+ ├── src/nrgrd/
138
+ │ ├── app.py # TUI entry point (rendering only)
139
+ │ ├── agent/ # Agent runtime: loop, events, permissions — no TUI dependency
140
+ │ ├── tools/ # Tool registry: filesystem, search, shell, git, MCP adapter
141
+ │ ├── api/ # ModelProvider abstraction + the OpenAI-compatible one
142
+ │ ├── config/ # Configuration and credential storage
143
+ │ ├── context/ # Application state, models, token estimates
144
+ │ ├── screens/ # The connect / onboarding screen
145
+ │ ├── sessions/ # Session handling and storage
146
+ │ ├── system/ # System prompts
147
+ │ ├── theme/ # Color palette and styles
148
+ │ ├── widgets/ # Custom visual components
149
+ │ └── workspace/ # Filesystem tools, project discovery, MCP client
150
+ ├── docs/ # Reports and documentation
151
+ ├── tests/ # Agent/tool/permission tests (no TUI, no live endpoint needed)
152
+ └── pyproject.toml # Dependencies and project metadata
153
+ ```
154
+
155
+ The agent runtime never imports Rich or Textual — the TUI drives it by
156
+ iterating `agent.run(messages)` and rendering the events it yields. That
157
+ keeps the agent testable headlessly and reusable from a future CLI mode.
158
+
159
+ ## Releasing
160
+
161
+ Push a version tag. CI runs the tests, builds, checks the built version
162
+ matches the tag, and publishes to PyPI and GitHub Releases:
163
+
164
+ ```bash
165
+ git tag v0.1.0
166
+ git push origin v0.1.0
167
+ ```
168
+
169
+ The version comes from the tag; there is no version number to edit in
170
+ `pyproject.toml`.
171
+
172
+ ## Development
173
+
174
+ ```bash
175
+ # Install in editable mode, including dev dependencies
176
+ uv sync --dev
177
+
178
+ # Run the test suite
179
+ uv run pytest tests/
180
+
181
+ # Run linters / checks (if applicable)
182
+ uv run ruff check src/
183
+ uv run mypy src/
184
+ ```
185
+
186
+ ## License
187
+
188
+ [MIT](LICENSE) © NeuroGrid
nrgrd-0.1.0/README.md ADDED
@@ -0,0 +1,156 @@
1
+ # nrgrd
2
+
3
+ [![PyPI](https://img.shields.io/pypi/v/nrgrd)](https://pypi.org/project/nrgrd/)
4
+ ![Python](https://img.shields.io/badge/python-3.11%2B-blue)
5
+ ![License](https://img.shields.io/badge/license-MIT-green)
6
+ ![Status](https://img.shields.io/badge/status-alpha-orange)
7
+
8
+ **nrgrd** is [NeuroGrid](https://neurogrid.cc)'s Terminal User Interface (TUI)
9
+ for interacting with AI models from your terminal, Claude Code style. Built
10
+ on `rich` and `prompt-toolkit`, it points at any OpenAI-compatible
11
+ inference endpoint — including a NeuroGrid Marketplace deployment (the URL +
12
+ API key of the host you rented) — to chat, manage sessions, and run MCP
13
+ tools.
14
+
15
+ ## Features
16
+
17
+ - **Coding agent** — An iterative tool-use loop (`nrgrd.agent`) that reads, searches, edits, and runs commands in your repository until the task is done.
18
+ - **Workspace aware** — Detects git, language, package manager, and test framework at startup, so the agent doesn't waste turns rediscovering your project.
19
+ - **Interruptible** — Ctrl+C stops generation or a running tool without corrupting the conversation, keeping whatever was produced.
20
+ - **Named sessions** — Several conversations per project: list, resume, rename, delete.
21
+ - **CLI mode** — `nrgrd "fix the failing tests"` runs headless on the same runtime, for scripts and CI.
22
+ - **Native tools** — `list_files`, `read_file`, `write_file`, `edit_file`, `search`, `shell`, `git_status`, `git_diff`.
23
+ - **Permissions** — Read-only tools run automatically; file writes, shell commands, and MCP tools ask for approval first (or "always allow" for the session).
24
+ - **Immersive TUI** — Rich-rendered panels, streaming output, and slash-command completion.
25
+ - **Persistent sessions** — Saves conversation context and history locally.
26
+ - **Any compatible endpoint** — Behind a `ModelProvider` abstraction: a NeuroGrid deployment, vLLM, Ollama, LM Studio, or anything else speaking the same API. All nrgrd needs is a URL, a key, and a model name.
27
+ - **Keys kept out of the config file** — The API key lives in your OS credential store, and never appears in errors or logs.
28
+ - **Errors you can act on** — Failures name the endpoint and model involved and say what to change.
29
+ - **Built-in MCP** — Run and connect MCP servers straight from the terminal; their tools go through the same permission system.
30
+ - **CLI + TUI** — Use `nrgrd` for the interactive interface or `nrgrd-mcp` for the MCP server.
31
+
32
+ ## Installation
33
+
34
+ nrgrd runs on macOS, Linux and Windows, with Python 3.11 or newer.
35
+
36
+ ```bash
37
+ uv tool install nrgrd
38
+ nrgrd
39
+ ```
40
+
41
+ `uv tool install` puts `nrgrd` on your PATH in its own environment, and
42
+ downloads a suitable Python if you don't have one. Update with
43
+ `uv tool upgrade nrgrd`. If you prefer pipx: `pipx install nrgrd`.
44
+
45
+ Don't have uv? See [installing uv](https://docs.astral.sh/uv/getting-started/installation/).
46
+
47
+ ### From source
48
+
49
+ ```bash
50
+ git clone https://github.com/NeuroGrid-AI-exchange/neurogrid-tui.git
51
+ cd neurogrid-tui
52
+ uv sync
53
+ uv run nrgrd
54
+ ```
55
+
56
+ ## Usage
57
+
58
+ ```bash
59
+ nrgrd # interactive TUI
60
+ nrgrd "explain this repository" # one prompt, then exit
61
+ nrgrd --model qwen3-coder "fix the failing tests"
62
+ nrgrd --yes "run the tests" # approve gated tools automatically (CI)
63
+ ```
64
+
65
+ ### Commands
66
+
67
+ | Command | What it does |
68
+ |---|---|
69
+ | `/help` | List every command |
70
+ | `/config`, `/config edit` | Show or change the connection |
71
+ | `/con`, `/models` | Check the endpoint, list its models |
72
+ | `/tools`, `/permissions` | Show tools and how each is gated |
73
+ | `/session list`, `/session new\|resume\|rename\|delete <name>` | Manage sessions |
74
+ | `/diff`, `/context`, `/compact` | Review changes, context usage, summarise |
75
+ | `/mcp`, `/mcp edit`, `/mcp reload` | Manage MCP servers |
76
+
77
+ ## Configuration
78
+
79
+ The first time you run `nrgrd` it opens a **Connect to a model** screen and
80
+ asks for the three things a NeuroGrid deployment hands you:
81
+
82
+ ```
83
+ Endpoint https://<your-deployment>/v1
84
+ API key ••••••••••••
85
+ Model qwen3-coder
86
+ ```
87
+
88
+ It then queries the endpoint and lets you pick from the models it actually
89
+ serves. Run `/config edit` to change any of this later.
90
+
91
+ The endpoint and model are saved to `config.json` in the application's
92
+ config directory. **The API key is not** — it goes to your operating
93
+ system's credential store (Keychain, Windows Credential Manager, or a
94
+ Secret Service keyring). On machines with no usable keyring it falls back
95
+ to an owner-only (`0600`) file, and `/config` tells you which is in use. A
96
+ key left over in an older plaintext `config.json` is migrated out
97
+ automatically on startup.
98
+
99
+ No environment variables are involved.
100
+
101
+ ## Project structure
102
+
103
+ ```
104
+ nrgrd/
105
+ ├── src/nrgrd/
106
+ │ ├── app.py # TUI entry point (rendering only)
107
+ │ ├── agent/ # Agent runtime: loop, events, permissions — no TUI dependency
108
+ │ ├── tools/ # Tool registry: filesystem, search, shell, git, MCP adapter
109
+ │ ├── api/ # ModelProvider abstraction + the OpenAI-compatible one
110
+ │ ├── config/ # Configuration and credential storage
111
+ │ ├── context/ # Application state, models, token estimates
112
+ │ ├── screens/ # The connect / onboarding screen
113
+ │ ├── sessions/ # Session handling and storage
114
+ │ ├── system/ # System prompts
115
+ │ ├── theme/ # Color palette and styles
116
+ │ ├── widgets/ # Custom visual components
117
+ │ └── workspace/ # Filesystem tools, project discovery, MCP client
118
+ ├── docs/ # Reports and documentation
119
+ ├── tests/ # Agent/tool/permission tests (no TUI, no live endpoint needed)
120
+ └── pyproject.toml # Dependencies and project metadata
121
+ ```
122
+
123
+ The agent runtime never imports Rich or Textual — the TUI drives it by
124
+ iterating `agent.run(messages)` and rendering the events it yields. That
125
+ keeps the agent testable headlessly and reusable from a future CLI mode.
126
+
127
+ ## Releasing
128
+
129
+ Push a version tag. CI runs the tests, builds, checks the built version
130
+ matches the tag, and publishes to PyPI and GitHub Releases:
131
+
132
+ ```bash
133
+ git tag v0.1.0
134
+ git push origin v0.1.0
135
+ ```
136
+
137
+ The version comes from the tag; there is no version number to edit in
138
+ `pyproject.toml`.
139
+
140
+ ## Development
141
+
142
+ ```bash
143
+ # Install in editable mode, including dev dependencies
144
+ uv sync --dev
145
+
146
+ # Run the test suite
147
+ uv run pytest tests/
148
+
149
+ # Run linters / checks (if applicable)
150
+ uv run ruff check src/
151
+ uv run mypy src/
152
+ ```
153
+
154
+ ## License
155
+
156
+ [MIT](LICENSE) © NeuroGrid
@@ -0,0 +1,60 @@
1
+ [project]
2
+ name = "nrgrd"
3
+ dynamic = ["version"]
4
+ description = "Terminal AI coding agent for OpenAI-compatible inference endpoints, built for NeuroGrid deployments"
5
+ readme = "README.md"
6
+ requires-python = ">=3.11"
7
+ license = "MIT"
8
+ license-files = ["LICENSE"]
9
+ authors = [{ name = "NeuroGrid" }]
10
+ keywords = ["ai", "agent", "cli", "tui", "llm", "coding-assistant", "openai-compatible", "neurogrid"]
11
+ classifiers = [
12
+ "Development Status :: 3 - Alpha",
13
+ "Environment :: Console",
14
+ "Intended Audience :: Developers",
15
+ "Operating System :: OS Independent",
16
+ "Programming Language :: Python :: 3",
17
+ "Programming Language :: Python :: 3 :: Only",
18
+ "Programming Language :: Python :: 3.11",
19
+ "Programming Language :: Python :: 3.12",
20
+ "Programming Language :: Python :: 3.13",
21
+ "Programming Language :: Python :: 3.14",
22
+ "Topic :: Software Development",
23
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
24
+ ]
25
+ dependencies = [
26
+ "keyring>=25.0.0",
27
+ "openai>=2.50.0",
28
+ "platformdirs>=4.11.0",
29
+ "pydantic>=2.13.4",
30
+ "prompt-toolkit>=3.0.52",
31
+ "rich>=15.0.0",
32
+ ]
33
+
34
+ [project.urls]
35
+ Homepage = "https://neurogrid.cc"
36
+ Repository = "https://github.com/NeuroGrid-AI-exchange/neurogrid-tui"
37
+ Issues = "https://github.com/NeuroGrid-AI-exchange/neurogrid-tui/issues"
38
+
39
+ [project.scripts]
40
+ nrgrd = "nrgrd.app:main"
41
+ nrgrd-mcp = "nrgrd.workspace.mcp_server:main"
42
+
43
+ [dependency-groups]
44
+ dev = [
45
+ "pytest>=8.0.0",
46
+ ]
47
+
48
+ [build-system]
49
+ requires = ["hatchling", "hatch-vcs"]
50
+ build-backend = "hatchling.build"
51
+
52
+ # The version comes from the git tag (v0.1.0 -> 0.1.0), so the tag and the
53
+ # published package can never disagree again.
54
+ [tool.hatch.version]
55
+ source = "vcs"
56
+ fallback-version = "0.0.0"
57
+
58
+ [tool.hatch.version.raw-options]
59
+ # PyPI rejects local versions (the "+g1a2b3c" suffix on untagged commits).
60
+ local_scheme = "no-local-version"
@@ -0,0 +1,7 @@
1
+ from importlib.metadata import PackageNotFoundError, version
2
+
3
+ try:
4
+ # Set at build time from the git tag, so there is one source of truth.
5
+ __version__ = version("nrgrd")
6
+ except PackageNotFoundError: # Running from a checkout that was never installed.
7
+ __version__ = "0.0.0"
@@ -0,0 +1,5 @@
1
+ from nrgrd.app import main
2
+
3
+
4
+ if __name__ == "__main__":
5
+ main()