noah-code 0.2.2__tar.gz → 0.2.3__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.
- {noah_code-0.2.2 → noah_code-0.2.3}/.github/workflows/ci.yml +16 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/.gitignore +3 -0
- noah_code-0.2.3/.pre-commit-config.yaml +8 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/PKG-INFO +15 -11
- {noah_code-0.2.2 → noah_code-0.2.3}/README.md +12 -9
- {noah_code-0.2.2 → noah_code-0.2.3}/docs/configuration.md +18 -7
- {noah_code-0.2.2 → noah_code-0.2.3}/docs/development.md +20 -9
- {noah_code-0.2.2 → noah_code-0.2.3}/docs/extensions.md +16 -4
- {noah_code-0.2.2 → noah_code-0.2.3}/docs/interactive-reference.md +54 -12
- {noah_code-0.2.2 → noah_code-0.2.3}/docs/releases/v0.1.1.md +1 -1
- {noah_code-0.2.2 → noah_code-0.2.3}/docs/releases/v0.2.0.md +3 -3
- noah_code-0.2.3/docs/releases/v0.2.3.md +50 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/pyproject.toml +29 -2
- noah_code-0.2.3/src/noah_code/__init__.py +3 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/src/noah_code/__main__.py +1 -1
- {noah_code-0.2.2 → noah_code-0.2.3}/src/noah_code/agent.py +222 -42
- {noah_code-0.2.2 → noah_code-0.2.3}/src/noah_code/agents.py +41 -17
- {noah_code-0.2.2 → noah_code-0.2.3}/src/noah_code/approvals.py +15 -2
- noah_code-0.2.3/src/noah_code/budget.py +230 -0
- noah_code-0.2.3/src/noah_code/checkpoints.py +186 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/src/noah_code/cli.py +285 -35
- {noah_code-0.2.2 → noah_code-0.2.3}/src/noah_code/commands.py +96 -22
- {noah_code-0.2.2 → noah_code-0.2.3}/src/noah_code/config.py +79 -9
- noah_code-0.2.3/src/noah_code/custom_commands.py +222 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/src/noah_code/event_bridge.py +40 -2
- {noah_code-0.2.2 → noah_code-0.2.3}/src/noah_code/events.py +6 -0
- noah_code-0.2.3/src/noah_code/github.py +193 -0
- noah_code-0.2.3/src/noah_code/hooks.py +136 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/src/noah_code/host.py +849 -132
- {noah_code-0.2.2 → noah_code-0.2.3}/src/noah_code/llm.py +14 -0
- noah_code-0.2.3/src/noah_code/llm_replies.py +96 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/src/noah_code/mcp_setup.py +2 -2
- noah_code-0.2.3/src/noah_code/nooa_compat.py +69 -0
- noah_code-0.2.3/src/noah_code/permissions.py +1003 -0
- noah_code-0.2.3/src/noah_code/project_notes.py +115 -0
- noah_code-0.2.3/src/noah_code/redaction.py +75 -0
- noah_code-0.2.3/src/noah_code/secure_files.py +265 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/src/noah_code/sessions.py +113 -10
- {noah_code-0.2.2 → noah_code-0.2.3}/src/noah_code/skills_setup.py +2 -1
- {noah_code-0.2.2 → noah_code-0.2.3}/src/noah_code/snapshots.py +5 -0
- noah_code-0.2.3/src/noah_code/steer.py +73 -0
- noah_code-0.2.3/src/noah_code/summarization.py +120 -0
- noah_code-0.2.3/src/noah_code/tools/diff_tools.py +263 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/src/noah_code/tools/git_tools.py +1 -1
- noah_code-0.2.3/src/noah_code/tools/github_tools.py +93 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/src/noah_code/tools/lsp_tools.py +13 -9
- noah_code-0.2.3/src/noah_code/tools/memory_tools.py +62 -0
- noah_code-0.2.3/src/noah_code/tools/plan_tools.py +90 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/src/noah_code/tools/process_tools.py +12 -3
- {noah_code-0.2.2 → noah_code-0.2.3}/src/noah_code/tools/question_tools.py +5 -1
- noah_code-0.2.3/src/noah_code/tools/task_tools.py +219 -0
- noah_code-0.2.3/src/noah_code/tools/web_tools.py +384 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/src/noah_code/tools/workspace_tools.py +316 -65
- {noah_code-0.2.2 → noah_code-0.2.3}/src/noah_code/ui/textual.css +5 -5
- {noah_code-0.2.2 → noah_code-0.2.3}/src/noah_code/ui/textual_app.py +523 -72
- {noah_code-0.2.2 → noah_code-0.2.3}/src/noah_code/usage.py +35 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/src/noah_code/workspace.py +3 -0
- noah_code-0.2.3/src/noah_code/worktree.py +242 -0
- noah_code-0.2.3/tests/test_agents.py +130 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/tests/test_approvals.py +1 -1
- noah_code-0.2.3/tests/test_budget.py +149 -0
- noah_code-0.2.3/tests/test_cache_context.py +262 -0
- noah_code-0.2.3/tests/test_checkpoints.py +135 -0
- noah_code-0.2.3/tests/test_cli.py +274 -0
- noah_code-0.2.3/tests/test_compaction_eviction.py +136 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/tests/test_config.py +73 -3
- noah_code-0.2.3/tests/test_console_ui.py +140 -0
- noah_code-0.2.3/tests/test_custom_commands.py +150 -0
- noah_code-0.2.3/tests/test_diff_tools.py +108 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/tests/test_efficiency.py +0 -8
- {noah_code-0.2.2 → noah_code-0.2.3}/tests/test_event_bridge.py +46 -1
- noah_code-0.2.3/tests/test_github.py +182 -0
- noah_code-0.2.3/tests/test_hooks.py +200 -0
- noah_code-0.2.3/tests/test_host.py +1475 -0
- noah_code-0.2.3/tests/test_llm_replies.py +128 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/tests/test_lsp_tools.py +2 -2
- noah_code-0.2.3/tests/test_permissions.py +541 -0
- noah_code-0.2.3/tests/test_plan_memory_tools.py +82 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/tests/test_process_tools.py +19 -4
- noah_code-0.2.3/tests/test_project_notes.py +134 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/tests/test_question_tools.py +1 -1
- noah_code-0.2.3/tests/test_redaction.py +60 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/tests/test_sessions.py +95 -0
- noah_code-0.2.3/tests/test_steer.py +72 -0
- noah_code-0.2.3/tests/test_task_tools.py +268 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/tests/test_textual_tui.py +386 -11
- {noah_code-0.2.2 → noah_code-0.2.3}/tests/test_updates.py +4 -4
- {noah_code-0.2.2 → noah_code-0.2.3}/tests/test_wave1_e2e.py +8 -3
- {noah_code-0.2.2 → noah_code-0.2.3}/tests/test_web_tools.py +80 -2
- {noah_code-0.2.2 → noah_code-0.2.3}/tests/test_workspace_tools.py +249 -3
- noah_code-0.2.3/tests/test_worktree.py +92 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/uv.lock +208 -2
- noah_code-0.2.2/src/noah_code/__init__.py +0 -3
- noah_code-0.2.2/src/noah_code/benchmark.py +0 -140
- noah_code-0.2.2/src/noah_code/custom_commands.py +0 -103
- noah_code-0.2.2/src/noah_code/permissions.py +0 -483
- noah_code-0.2.2/src/noah_code/summarization.py +0 -34
- noah_code-0.2.2/src/noah_code/tools/task_tools.py +0 -126
- noah_code-0.2.2/src/noah_code/tools/web_tools.py +0 -176
- noah_code-0.2.2/tests/test_agents.py +0 -52
- noah_code-0.2.2/tests/test_cli.py +0 -155
- noah_code-0.2.2/tests/test_custom_commands.py +0 -50
- noah_code-0.2.2/tests/test_host.py +0 -610
- noah_code-0.2.2/tests/test_permissions.py +0 -152
- noah_code-0.2.2/tests/test_task_tools.py +0 -77
- {noah_code-0.2.2 → noah_code-0.2.3}/.github/workflows/release.yml +0 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/docs/assets/noah-in-action.svg +0 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/docs/releases/v0.1.0.md +0 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/docs/releases/v0.2.1.md +0 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/docs/releases/v0.2.2.md +0 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/docs/security.md +0 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/install.sh +0 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/src/noah_code/composer.py +0 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/src/noah_code/credentials.py +0 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/src/noah_code/macos_sandbox.py +0 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/src/noah_code/providers.py +0 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/src/noah_code/themes.py +0 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/src/noah_code/tool_output.py +0 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/src/noah_code/tools/__init__.py +0 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/src/noah_code/tools/media_tools.py +0 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/src/noah_code/ui/__init__.py +0 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/src/noah_code/ui/console.py +0 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/src/noah_code/ui/protocol.py +0 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/src/noah_code/updates.py +0 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/tests/conftest.py +0 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/tests/test_agent_security.py +0 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/tests/test_composer.py +0 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/tests/test_credentials.py +0 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/tests/test_event_bridge_and_shell.py +0 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/tests/test_git_tools.py +0 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/tests/test_installer.py +0 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/tests/test_llm.py +0 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/tests/test_mcp_setup.py +0 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/tests/test_providers.py +0 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/tests/test_run_exit.py +0 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/tests/test_skills_setup.py +0 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/tests/test_snapshots.py +0 -0
- {noah_code-0.2.2 → noah_code-0.2.3}/tests/test_summarization.py +0 -0
|
@@ -9,10 +9,15 @@ on:
|
|
|
9
9
|
permissions:
|
|
10
10
|
contents: read
|
|
11
11
|
|
|
12
|
+
concurrency:
|
|
13
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
14
|
+
cancel-in-progress: true
|
|
15
|
+
|
|
12
16
|
jobs:
|
|
13
17
|
quality:
|
|
14
18
|
name: Python ${{ matrix.python-version }} quality
|
|
15
19
|
runs-on: ubuntu-latest
|
|
20
|
+
timeout-minutes: 30
|
|
16
21
|
strategy:
|
|
17
22
|
fail-fast: false
|
|
18
23
|
matrix:
|
|
@@ -46,7 +51,17 @@ jobs:
|
|
|
46
51
|
- name: Lint
|
|
47
52
|
run: uv run ruff check src tests
|
|
48
53
|
|
|
54
|
+
- name: Type check
|
|
55
|
+
run: uv run mypy src/noah_code
|
|
56
|
+
|
|
57
|
+
- name: Test with coverage (3.12 only)
|
|
58
|
+
if: matrix.python-version == '3.12'
|
|
59
|
+
run: |
|
|
60
|
+
uv run pytest tests --cov=noah_code --cov-report=term-missing \
|
|
61
|
+
--cov-fail-under=70 -W error::pytest.PytestUnraisableExceptionWarning
|
|
62
|
+
|
|
49
63
|
- name: Test
|
|
64
|
+
if: matrix.python-version != '3.12'
|
|
50
65
|
run: uv run pytest tests -W error::pytest.PytestUnraisableExceptionWarning
|
|
51
66
|
|
|
52
67
|
- name: Build distributions
|
|
@@ -55,6 +70,7 @@ jobs:
|
|
|
55
70
|
platform:
|
|
56
71
|
name: ${{ matrix.name }} smoke test
|
|
57
72
|
runs-on: ${{ matrix.runner }}
|
|
73
|
+
timeout-minutes: 40
|
|
58
74
|
strategy:
|
|
59
75
|
fail-fast: false
|
|
60
76
|
matrix:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: noah-code
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: Noah Code terminal coding agent, built on NVIDIA OO Agents (NOOA)
|
|
5
5
|
Project-URL: Homepage, https://github.com/skundu42/noah-code
|
|
6
6
|
Project-URL: Documentation, https://github.com/skundu42/noah-code#readme
|
|
@@ -28,9 +28,10 @@ Requires-Dist: pydantic>=2.5.0
|
|
|
28
28
|
Requires-Dist: pyyaml>=6.0.0
|
|
29
29
|
Requires-Dist: rich>=13.0.0
|
|
30
30
|
Requires-Dist: textual>=1.0.0
|
|
31
|
-
Requires-Dist: tomli>=2.0.0; python_version < '3.11'
|
|
32
31
|
Provides-Extra: dev
|
|
32
|
+
Requires-Dist: mypy>=1.13.0; extra == 'dev'
|
|
33
33
|
Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
|
|
34
|
+
Requires-Dist: pytest-cov>=5.0.0; extra == 'dev'
|
|
34
35
|
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
35
36
|
Requires-Dist: ruff>=0.8.0; extra == 'dev'
|
|
36
37
|
Provides-Extra: mcp
|
|
@@ -45,7 +46,7 @@ Description-Content-Type: text/markdown
|
|
|
45
46
|
|
|
46
47
|
# Noah Code
|
|
47
48
|
|
|
48
|
-
**A terminal coding
|
|
49
|
+
**A terminal coding agent built on NVIDIA's NOAA framework**
|
|
49
50
|
|
|
50
51
|
[](https://pypi.org/project/noah-code/)
|
|
51
52
|
[](https://github.com/skundu42/noah-code/actions/workflows/ci.yml)
|
|
@@ -57,9 +58,9 @@ Description-Content-Type: text/markdown
|
|
|
57
58
|
|
|
58
59
|
<p align="center"><sub>The real Textual interface, captured from a deterministic Noah Code session.</sub></p>
|
|
59
60
|
|
|
60
|
-
Noah keeps the conversation central while the context rail tracks
|
|
61
|
-
|
|
62
|
-
records, and every session remains scoped to its repository.
|
|
61
|
+
Noah keeps the conversation central while the context rail tracks live work, Git changes, session,
|
|
62
|
+
model usage, and the current plan. Tool execution stays visible, completed work compacts into
|
|
63
|
+
readable records, and every session remains scoped to its repository.
|
|
63
64
|
|
|
64
65
|
Built on the [NVIDIA OO Agents (NOOA)](https://github.com/NVIDIA-NeMo/labs-OO-Agents) runtime.
|
|
65
66
|
|
|
@@ -96,6 +97,9 @@ configuration or session history.
|
|
|
96
97
|
file edits even after restarting Noah.
|
|
97
98
|
- **Persistent sessions.** Resume repository-scoped conversations, todos, model choices, and
|
|
98
99
|
automatically compacted context without losing the full underlying tool results.
|
|
100
|
+
- **Token-efficient by construction.** Lean tool-output bounds with disk-backed recall, condensed
|
|
101
|
+
subagent results, cache-stable request prefixes (volatile status arrives as appended events),
|
|
102
|
+
and pointer-eviction compaction — measured live with `/tokens`.
|
|
99
103
|
- **Explicit control.** Switch between implementation-focused **build** mode and read-only
|
|
100
104
|
**plan** mode, with ordered `allow`, `ask`, and `deny` permission rules.
|
|
101
105
|
- **Extensible workflows.** Add slash commands, opt-in skills, MCP servers, or markdown subagents;
|
|
@@ -143,7 +147,6 @@ noah --version
|
|
|
143
147
|
noah doctor .
|
|
144
148
|
noah config show .
|
|
145
149
|
noah update --check
|
|
146
|
-
noah benchmark .
|
|
147
150
|
```
|
|
148
151
|
|
|
149
152
|
The package also installs `noah-code` and `nc` as equivalent entry points. Because `nc` commonly
|
|
@@ -164,12 +167,13 @@ Type `/` to search the full command and configuration reference. The most common
|
|
|
164
167
|
| `/theme` | Choose Atom One Dark, Noah Ocean, Graphite, or High Contrast |
|
|
165
168
|
| `/diff` | Review staged and unstaged changes |
|
|
166
169
|
| `/undo` / `/redo` | Traverse the persistent edit journal |
|
|
167
|
-
| `/tokens` | Inspect tokens, cache usage, model wait, and tool output |
|
|
170
|
+
| `/tokens` | Inspect tokens, cache usage, prefix stability, model wait, and tool output |
|
|
168
171
|
| `/efficiency` | Switch between `fast`, `balanced`, and `deep` budgets |
|
|
169
172
|
|
|
170
|
-
On wide terminals, the side rail
|
|
171
|
-
|
|
172
|
-
|
|
173
|
+
On wide terminals, the side rail prioritizes the active operation, Git branch and change counts,
|
|
174
|
+
session, model usage, update state, and plan. Git status is refreshed in the background at turn
|
|
175
|
+
boundaries, so the animated working state stays responsive. The main pane remains centered on the
|
|
176
|
+
Noah mark until the first prompt, then becomes the conversation and execution timeline.
|
|
173
177
|
|
|
174
178
|
## Models and providers
|
|
175
179
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# Noah Code
|
|
4
4
|
|
|
5
|
-
**A terminal coding
|
|
5
|
+
**A terminal coding agent built on NVIDIA's NOAA framework**
|
|
6
6
|
|
|
7
7
|
[](https://pypi.org/project/noah-code/)
|
|
8
8
|
[](https://github.com/skundu42/noah-code/actions/workflows/ci.yml)
|
|
@@ -14,9 +14,9 @@
|
|
|
14
14
|
|
|
15
15
|
<p align="center"><sub>The real Textual interface, captured from a deterministic Noah Code session.</sub></p>
|
|
16
16
|
|
|
17
|
-
Noah keeps the conversation central while the context rail tracks
|
|
18
|
-
|
|
19
|
-
records, and every session remains scoped to its repository.
|
|
17
|
+
Noah keeps the conversation central while the context rail tracks live work, Git changes, session,
|
|
18
|
+
model usage, and the current plan. Tool execution stays visible, completed work compacts into
|
|
19
|
+
readable records, and every session remains scoped to its repository.
|
|
20
20
|
|
|
21
21
|
Built on the [NVIDIA OO Agents (NOOA)](https://github.com/NVIDIA-NeMo/labs-OO-Agents) runtime.
|
|
22
22
|
|
|
@@ -53,6 +53,9 @@ configuration or session history.
|
|
|
53
53
|
file edits even after restarting Noah.
|
|
54
54
|
- **Persistent sessions.** Resume repository-scoped conversations, todos, model choices, and
|
|
55
55
|
automatically compacted context without losing the full underlying tool results.
|
|
56
|
+
- **Token-efficient by construction.** Lean tool-output bounds with disk-backed recall, condensed
|
|
57
|
+
subagent results, cache-stable request prefixes (volatile status arrives as appended events),
|
|
58
|
+
and pointer-eviction compaction — measured live with `/tokens`.
|
|
56
59
|
- **Explicit control.** Switch between implementation-focused **build** mode and read-only
|
|
57
60
|
**plan** mode, with ordered `allow`, `ask`, and `deny` permission rules.
|
|
58
61
|
- **Extensible workflows.** Add slash commands, opt-in skills, MCP servers, or markdown subagents;
|
|
@@ -100,7 +103,6 @@ noah --version
|
|
|
100
103
|
noah doctor .
|
|
101
104
|
noah config show .
|
|
102
105
|
noah update --check
|
|
103
|
-
noah benchmark .
|
|
104
106
|
```
|
|
105
107
|
|
|
106
108
|
The package also installs `noah-code` and `nc` as equivalent entry points. Because `nc` commonly
|
|
@@ -121,12 +123,13 @@ Type `/` to search the full command and configuration reference. The most common
|
|
|
121
123
|
| `/theme` | Choose Atom One Dark, Noah Ocean, Graphite, or High Contrast |
|
|
122
124
|
| `/diff` | Review staged and unstaged changes |
|
|
123
125
|
| `/undo` / `/redo` | Traverse the persistent edit journal |
|
|
124
|
-
| `/tokens` | Inspect tokens, cache usage, model wait, and tool output |
|
|
126
|
+
| `/tokens` | Inspect tokens, cache usage, prefix stability, model wait, and tool output |
|
|
125
127
|
| `/efficiency` | Switch between `fast`, `balanced`, and `deep` budgets |
|
|
126
128
|
|
|
127
|
-
On wide terminals, the side rail
|
|
128
|
-
|
|
129
|
-
|
|
129
|
+
On wide terminals, the side rail prioritizes the active operation, Git branch and change counts,
|
|
130
|
+
session, model usage, update state, and plan. Git status is refreshed in the background at turn
|
|
131
|
+
boundaries, so the animated working state stays responsive. The main pane remains centered on the
|
|
132
|
+
Noah mark until the first prompt, then becomes the conversation and execution timeline.
|
|
130
133
|
|
|
131
134
|
## Models and providers
|
|
132
135
|
|
|
@@ -234,9 +234,10 @@ objective, decisions, files, validation, blockers, and next steps.
|
|
|
234
234
|
| Mode | Behavior |
|
|
235
235
|
|------|----------|
|
|
236
236
|
| `build` | Reads are allowed; edits and shell commands follow permission rules and ask by default |
|
|
237
|
-
| `plan` | Reads are allowed; file edits and mutating shell commands are denied |
|
|
237
|
+
| `plan` | Reads are allowed; file edits and mutating shell commands are denied. `self.plan.write` may pin `.noah-code/plan.md` |
|
|
238
238
|
|
|
239
|
-
Switch modes with `--mode`, `/mode build`, or `/mode plan`. The
|
|
239
|
+
Switch modes with `--mode`, `/mode build`, or `/mode plan`. The agent can propose a switch with
|
|
240
|
+
`self.plan.enter()` / `self.plan.exit_to_build()` after writing a plan. The active mode is stored with the
|
|
240
241
|
session.
|
|
241
242
|
|
|
242
243
|
Permission rules are evaluated in order, and the last matching rule wins. The default policy:
|
|
@@ -246,13 +247,23 @@ Permission rules are evaluated in order, and the last matching rule wins. The de
|
|
|
246
247
|
databases. `.env.example` remains readable.
|
|
247
248
|
- Asks before workspace edits, shell commands, web fetches, web searches, and subagents.
|
|
248
249
|
- Allows the question tool so the agent can pause for a structured choice.
|
|
249
|
-
- Denies `git push`, `git clean`,
|
|
250
|
+
- Denies `git push`, `git clean`, `git reset --hard`, and mutating `gh pr`
|
|
251
|
+
(`create`, `checkout`, `merge`, `close`, `ready`, `review`). Push and PR
|
|
252
|
+
mutations go through `/pr` / `self.github` instead.
|
|
253
|
+
- Allows listing and viewing pull requests; asks before create, push, checkout,
|
|
254
|
+
or comment.
|
|
250
255
|
- Keeps file tools inside the active workspace and asks before skill or MCP access.
|
|
251
256
|
- Denies plan-mode mutations regardless of broader allow rules. Plan mode may still run
|
|
252
|
-
read-only subagents.
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
257
|
+
read-only subagents. Its shell allowlist accepts only literal, unqualified read-only programs;
|
|
258
|
+
test collection and interpreter execution are not treated as read-only because they can load
|
|
259
|
+
repository code.
|
|
260
|
+
|
|
261
|
+
`--auto` changes routine ask decisions to allow but never overrides an explicit deny.
|
|
262
|
+
Elevated-risk commands such as file removal, downloads, and package installation still require
|
|
263
|
+
explicit approval. Compound shell commands and mutating or unrecognized Git commands cannot be
|
|
264
|
+
silently auto-approved. Interpreters, eval/source commands, and indirect execution wrappers, plus
|
|
265
|
+
arguments hidden behind variable, command, ANSI-C, or brace expansion, are denied under `--auto`;
|
|
266
|
+
run without `--auto` when one of these commands needs explicit approval.
|
|
256
267
|
|
|
257
268
|
## Installation and updates
|
|
258
269
|
|
|
@@ -7,28 +7,39 @@ Install the development environment and run the local checks:
|
|
|
7
7
|
```bash
|
|
8
8
|
uv sync --extra dev --extra mcp --extra tracing
|
|
9
9
|
uv run ruff check src tests
|
|
10
|
+
uv run mypy src/noah_code
|
|
10
11
|
uv run pytest tests
|
|
11
12
|
uv build
|
|
12
13
|
```
|
|
13
14
|
|
|
14
|
-
The default test suite is hermetic and does not require network access or provider keys.
|
|
15
|
+
The default test suite is hermetic and does not require network access or provider keys. A single
|
|
16
|
+
opt-in test performs a live HTTP fetch; run it explicitly on a connected machine:
|
|
15
17
|
|
|
16
|
-
|
|
18
|
+
```bash
|
|
19
|
+
uv run pytest tests -m integration
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Measure coverage (a 70% total gate runs in CI):
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
uv run pytest tests --cov=noah_code --cov-report=term-missing
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Optional git hooks mirror the lint gate:
|
|
17
29
|
|
|
18
30
|
```bash
|
|
19
|
-
|
|
20
|
-
uv run noah benchmark . --json
|
|
31
|
+
uvx pre-commit install
|
|
21
32
|
```
|
|
22
33
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
per-token estimate; use `/tokens` during a real session for provider-reported usage.
|
|
34
|
+
Use `/tokens` during a real session to inspect provider-reported token use, cache hits, model wait,
|
|
35
|
+
tool output, and estimated cost.
|
|
26
36
|
|
|
27
37
|
## CI
|
|
28
38
|
|
|
29
39
|
GitHub Actions runs the complete test suite on Python 3.12 and 3.13, plus platform smoke tests on
|
|
30
|
-
Linux and macOS for arm64 and x86_64. Every pull request and push to `main` must pass lint,
|
|
31
|
-
lockfile validation, and a package build.
|
|
40
|
+
Linux and macOS for arm64 and x86_64. Every pull request and push to `main` must pass lint, static
|
|
41
|
+
type checking (mypy), tests with a 70% coverage floor, lockfile validation, and a package build.
|
|
42
|
+
Concurrent runs for the same reference are cancelled automatically.
|
|
32
43
|
|
|
33
44
|
## Releases
|
|
34
45
|
|
|
@@ -6,7 +6,7 @@ Add reusable Markdown prompts in either location:
|
|
|
6
6
|
|
|
7
7
|
- `~/.config/noah-code/commands/*.md` for user commands.
|
|
8
8
|
- `.noah-code/commands/*.md` for repository commands. Repository commands override user commands
|
|
9
|
-
with the same name.
|
|
9
|
+
with the same non-built-in name. A repository cannot shadow Noah's built-in slash commands.
|
|
10
10
|
|
|
11
11
|
For example, `.noah-code/commands/fix.md`:
|
|
12
12
|
|
|
@@ -25,8 +25,13 @@ through `$9`. Front matter may also select a mode or model.
|
|
|
25
25
|
## Subagents
|
|
26
26
|
|
|
27
27
|
The parent agent invokes nested NOOA agents with `self.task.run("explore", prompt)` or
|
|
28
|
-
`self.task.run("general", prompt)
|
|
29
|
-
|
|
28
|
+
`self.task.run("general", prompt)`, and fans out independent units concurrently with
|
|
29
|
+
`self.task.run_many([("explore", "..."), ("general", "...")])`. Each child gets isolated
|
|
30
|
+
in-memory session storage, its own permission-engine clone (so concurrent children never race
|
|
31
|
+
on mode), and the same approval broker. Results are bounded: oversized transcripts are
|
|
32
|
+
condensed by the lightweight model (fallback: truncation with a recall pointer) before they
|
|
33
|
+
enter the parent's context. Tune with `subagent_result_max_chars` and
|
|
34
|
+
`max_concurrent_subagents` under `[efficiency]`. Add project or user markdown agents:
|
|
30
35
|
|
|
31
36
|
- `~/.config/noah-code/agents/*.md`
|
|
32
37
|
- `.noah-code/agents/*.md`
|
|
@@ -39,7 +44,14 @@ readonly: true
|
|
|
39
44
|
Review the assigned change. Cite files. Do not edit.
|
|
40
45
|
```
|
|
41
46
|
|
|
42
|
-
`/agents` lists discovered names. Project files override user files with the same stem
|
|
47
|
+
`/agents` lists discovered names. Project files override user files with the same stem, except that
|
|
48
|
+
the built-in `explore` and `general` agents are reserved and cannot be replaced by repository
|
|
49
|
+
content.
|
|
50
|
+
|
|
51
|
+
Repository command and agent files are limited to 64 KiB and must be ordinary, singly linked files
|
|
52
|
+
inside their expected `.noah-code` directory. Symlinks, hardlinks, linked directories, special
|
|
53
|
+
files, and oversized files are ignored. User-level files remain linkable because they are trusted
|
|
54
|
+
configuration owned by the user.
|
|
43
55
|
|
|
44
56
|
## Skills
|
|
45
57
|
|
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
|
|
5
5
|
| Key | Action |
|
|
6
6
|
|-----|--------|
|
|
7
|
-
| `Enter` | Send the current message |
|
|
7
|
+
| `Enter` | Send the current message, or queue a follow-up while a turn is running |
|
|
8
8
|
| `Shift+Enter` | Insert a newline without sending |
|
|
9
9
|
| `Tab` | Toggle `build`/`plan` mode; accept the highlighted slash option while suggestions are open |
|
|
10
10
|
| `Ctrl+P` | Open the command palette |
|
|
11
11
|
| `Ctrl+K` | Open the searchable skills picker |
|
|
12
12
|
| `Ctrl+O` | Open the session picker |
|
|
13
13
|
| `Ctrl+N` | Start a new session |
|
|
14
|
-
| `Ctrl+C` | Cancel the active turn; press twice while idle to quit |
|
|
14
|
+
| `Ctrl+C` | Cancel the active turn and clear queued follow-ups; press twice while idle to quit |
|
|
15
15
|
| `Ctrl+Q` | Quit |
|
|
16
16
|
| `F1` or `?` | Show help |
|
|
17
17
|
| `F2` | Open recent activity and full captured output |
|
|
@@ -22,10 +22,11 @@ At an approval prompt, press `1` to approve once, `2` to remember the approval f
|
|
|
22
22
|
session, or `3`/`Esc` to reject it.
|
|
23
23
|
|
|
24
24
|
The TUI uses Atom One Dark by default and also includes Noah Ocean, Graphite, and High Contrast.
|
|
25
|
-
Switch and persist the active palette with `/theme`. Its conversation-first layout adapts to
|
|
26
|
-
110 columns or wider, a
|
|
27
|
-
|
|
28
|
-
the
|
|
25
|
+
Switch and persist the active palette with `/theme`. Its conversation-first layout adapts to
|
|
26
|
+
terminal size. At 110 columns or wider, a change-ledger rail prioritizes the current action, Git
|
|
27
|
+
branch and staged/modified/new counts, session, model usage, and up to six open or blocked todos.
|
|
28
|
+
Narrow terminals retain the transcript, live activity, suggestions, and composer without the rail.
|
|
29
|
+
Terminals 25 rows high or shorter use compact spacing.
|
|
29
30
|
|
|
30
31
|
Type `/` in the composer to open the inline command list; the list remains visible and filters
|
|
31
32
|
continuously. Use `Up`/`Down` to highlight a command, `Enter` or `Tab` to complete it, and `Esc` to
|
|
@@ -33,8 +34,29 @@ close the list. Press `Enter` again to run the completed command. Typing `/confi
|
|
|
33
34
|
to every resolved configuration path and its current redacted value.
|
|
34
35
|
|
|
35
36
|
Until a session has its first user prompt, the main pane keeps the Noah mark centered. Startup,
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
repository changes, model, mode, usage, and update state live in the context rail on wide
|
|
38
|
+
terminals. Git status is collected in a background worker at startup and turn boundaries; spinner
|
|
39
|
+
frames update only the header and working banner. Existing sessions with user history restore
|
|
40
|
+
their transcript normally.
|
|
41
|
+
|
|
42
|
+
### Mid-turn follow-ups
|
|
43
|
+
|
|
44
|
+
While Noah is working, the composer stays open. `Enter` queues the current text instead of starting
|
|
45
|
+
a second turn. Chrome shows `queued · n`. When the in-flight `handle()` returns (`DONE`,
|
|
46
|
+
`NEED_INPUT`, or `WAIT`), the host injects the next item in the same journaled turn — one persist
|
|
47
|
+
and one checkpoint for the whole steered run. `/undo` therefore reverts every follow-up together.
|
|
48
|
+
|
|
49
|
+
The queue holds at most 5 items. A sixth `Enter` drops the oldest and status-prints
|
|
50
|
+
`steer dropped oldest`. `@path` mentions and `/attach` paths expand when the item is injected, not
|
|
51
|
+
when it is queued. A follow-up that names files Noah cannot resolve is dropped; later items stay.
|
|
52
|
+
`Ctrl+C` cancels the turn and clears the queue. Switching or starting a session also clears it.
|
|
53
|
+
|
|
54
|
+
Approval and `ask.question` modals keep the composer. Queueing resumes after the modal closes.
|
|
55
|
+
|
|
56
|
+
These slash commands still run while a turn is in progress: `/status`, `/tokens`, `/todos`,
|
|
57
|
+
`/help`, `/trace`. `/attach PATH` remembers the file for the next queued follow-up. `/exit` cancels
|
|
58
|
+
the turn (and the queue) then leaves. Mutating commands wait until the turn finishes, including
|
|
59
|
+
`/undo`, `/redo`, `/mode`, `/model`, `/diff`, `/new`, `/sessions`, `/worktree`, `/pr`, `/plan`, `/memory`, and `/compact`.
|
|
38
60
|
|
|
39
61
|
Tool and shell output is batched into a live execution panel instead of forcing one full-screen
|
|
40
62
|
redraw for every chunk. While a turn is running, a spinner names the current action the way
|
|
@@ -57,7 +79,11 @@ latest 100 activity records, bounded by the configured `max_output_chars` per ac
|
|
|
57
79
|
| `/reasoning [EFFORT]` | Show or set default/none/minimal/low/medium/high/xhigh for this session |
|
|
58
80
|
| `/reasoning --global EFFORT` | Set reasoning effort for this and future sessions |
|
|
59
81
|
| `/providers [use PROVIDER MODEL]` | Search and securely configure API providers |
|
|
60
|
-
| `/session`, `/sessions`, `/new`, `/continue` | Inspect, switch, create, and resume sessions |
|
|
82
|
+
| `/session`, `/sessions`, `/new`, `/continue` | Inspect, switch, create, and resume sessions. `/sessions` lists the whole git-repo family (primary checkout plus isolated copies) |
|
|
83
|
+
| `/worktree` | Opt-in isolation: create a linked git worktree and start a new session there. Subcommands: `create [NAME]`, `list`, `remove NAME`. `/new` stays on the current directory. CLI: `noah worktree create` prints a path and does not start a session |
|
|
84
|
+
| `/pr` | First-class GitHub pull-request loop. Subcommands: `list`, `view [N]`, `create [TITLE]`, `push`, `checkout N`, `comment N TEXT`. `/pr 12` views PR 12. Create pushes HEAD through the host (never via bash) then opens the PR. CLI: `noah pr` |
|
|
85
|
+
| `/plan` | Show the pinned `.noah-code/plan.md`. `/plan clear` dismisses it. In plan mode the agent writes this file with `self.plan.write`, then `self.plan.exit_to_build` asks to switch to build and follow it |
|
|
86
|
+
| `/memory` | Show project conventions in `.noah-code/memory.md`. `/memory save FACT`, `/memory forget TEXT`, `/memory clear`. The agent can `self.memory.save`; successful turns may auto-extract tagged conventions |
|
|
61
87
|
| `/compact` | Apply a coding checkpoint to eligible older context |
|
|
62
88
|
| `/tokens` | Show tokens, cache hits, cost, model wait, and tool-output volume |
|
|
63
89
|
| `/efficiency [fast|balanced|deep]` | Show or switch live tool-output budgets |
|
|
@@ -95,11 +121,23 @@ after resuming it. Other sessions and repositories keep their existing defaults
|
|
|
95
121
|
noah sessions list .
|
|
96
122
|
noah sessions show SESSION_ID
|
|
97
123
|
noah sessions delete SESSION_ID
|
|
124
|
+
noah worktree create [NAME]
|
|
125
|
+
noah worktree list
|
|
126
|
+
noah worktree remove NAME
|
|
127
|
+
noah pr list
|
|
128
|
+
noah pr view [N]
|
|
129
|
+
noah pr create [TITLE]
|
|
130
|
+
noah pr push
|
|
131
|
+
noah pr checkout N
|
|
132
|
+
noah pr comment N TEXT
|
|
98
133
|
```
|
|
99
134
|
|
|
100
135
|
Each session has a NOOA-backed SQLite database plus metadata for its workspace identity, model,
|
|
101
136
|
mode, title, remembered permission rules, todos, and edit journal. Session files are created with
|
|
102
|
-
private filesystem permissions
|
|
137
|
+
private filesystem permissions. `/sessions` lists every session in the same git repository family
|
|
138
|
+
(primary checkout plus Noah worktree copies). Switching or `noah --session` / `--continue` rebinds
|
|
139
|
+
the workspace to that session's stored path. A missing copy errors with `worktree missing` instead
|
|
140
|
+
of falling back to the current directory. Deleting a session does not remove its worktree.
|
|
103
141
|
|
|
104
142
|
The latest 50 persisted user, agent, summary, error, and activity events are restored after the
|
|
105
143
|
TUI's first paint. `F3` loads older history in read-only pages of 50, so resuming a long session
|
|
@@ -146,9 +184,13 @@ Lifecycle updates appear in the TUI without copying continuous logs into model c
|
|
|
146
184
|
The parent agent can run isolated NOOA subagents with `self.task.run("explore", ...)` or
|
|
147
185
|
`self.task.run("general", ...)`. Explore is read-only. General can edit but does not own todos.
|
|
148
186
|
Custom agents are markdown files in `.noah-code/agents/` or `~/.config/noah-code/agents/`. List
|
|
149
|
-
them with `/agents`.
|
|
187
|
+
them with `/agents`. Repository files cannot replace the built-in `explore` or `general` agents,
|
|
188
|
+
and unsafe linked or oversized repository definitions are ignored. Plan mode can run read-only
|
|
189
|
+
agents only.
|
|
150
190
|
|
|
151
|
-
`self.web.fetch(url)` and `self.web.search(query)` ask before leaving the machine.
|
|
191
|
+
`self.web.fetch(url)` and `self.web.search(query)` ask before leaving the machine. Fetch follows a
|
|
192
|
+
bounded number of redirects and accepts only public HTTP(S) destinations; private, loopback,
|
|
193
|
+
link-local, and mixed public/private DNS results are rejected at every hop.
|
|
152
194
|
`self.ask.question(header, prompt, options)` pauses the turn for a structured choice.
|
|
153
195
|
|
|
154
196
|
Type `@path` in the composer to inline a workspace file or attach a PNG/JPEG/WebP/GIF as a NOOA
|
|
@@ -16,7 +16,7 @@ repositories.
|
|
|
16
16
|
- Added paginated, read-only conversation history through `F3` when resuming sessions.
|
|
17
17
|
- Added keyboard-driven command and session pickers, safer approval cards, scroll locking, and new
|
|
18
18
|
output indicators.
|
|
19
|
-
- Batched high-volume shell events and bounded display history;
|
|
19
|
+
- Batched high-volume shell events and bounded display history; a 2,000-chunk stress measurement
|
|
20
20
|
improved from approximately 454 ms to 123 ms.
|
|
21
21
|
|
|
22
22
|
## Reliability
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Noah Code v0.2.0
|
|
2
2
|
|
|
3
|
-
This release turns Noah Code into a more capable, responsive coding
|
|
3
|
+
This release turns Noah Code into a more capable, responsive coding agent while keeping its
|
|
4
4
|
NOOA-based execution path compact and token efficient.
|
|
5
5
|
|
|
6
6
|
## Highlights
|
|
@@ -26,8 +26,8 @@ NOOA-based execution path compact and token efficient.
|
|
|
26
26
|
- Added `fast`, `balanced`, and `deep` efficiency profiles, compact NOOA trajectory rendering,
|
|
27
27
|
bounded reopenable tool previews, batched repository inspection, and cache-friendly context
|
|
28
28
|
refreshes.
|
|
29
|
-
- Added `/tokens` reporting
|
|
30
|
-
|
|
29
|
+
- Added `/tokens` reporting for inspecting prompt-cache, model-wait, tool-output, and estimated
|
|
30
|
+
token usage.
|
|
31
31
|
- Upgraded the runtime integration to NOOA 0.0.9.
|
|
32
32
|
|
|
33
33
|
## Reliability
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Noah Code v0.2.3
|
|
2
|
+
|
|
3
|
+
This release focuses Noah Code on the core coding-agent product while making long-running work
|
|
4
|
+
safer, more recoverable, and easier to follow from the terminal.
|
|
5
|
+
|
|
6
|
+
## Agent workflow
|
|
7
|
+
|
|
8
|
+
- Added mid-turn steering so follow-up instructions can be queued without interrupting active work.
|
|
9
|
+
- Added durable plan handoff and project memory, including explicit plan-mode boundaries and a
|
|
10
|
+
guided transition back to build mode.
|
|
11
|
+
- Added isolated Git worktrees, repository-family sessions, and a first-class GitHub pull-request
|
|
12
|
+
workflow for listing, reviewing, creating, pushing, checking out, and commenting on PRs.
|
|
13
|
+
- Added session budgets, turn-boundary Git checkpoints, configurable hooks, and persistent undo/redo
|
|
14
|
+
safeguards for more controlled autonomous work.
|
|
15
|
+
- Improved conversational handling, context compaction, tool-result retention, and subagent result
|
|
16
|
+
shaping to keep long sessions useful and token efficient.
|
|
17
|
+
|
|
18
|
+
## Interface
|
|
19
|
+
|
|
20
|
+
- Redesigned the wide-terminal context rail around the current action, Git branch and staged,
|
|
21
|
+
modified, and untracked counts, session and model state, usage and cost, and the active plan.
|
|
22
|
+
- Moved Git status collection to a background worker and stopped spinner frames from rebuilding the
|
|
23
|
+
rail or rereading plan state, keeping the TUI responsive during active turns.
|
|
24
|
+
- Added contextual busy/idle key hints, clearer live activity, paginated history, searchable
|
|
25
|
+
commands and sessions, and a detailed change ledger with validation and checkpoint controls.
|
|
26
|
+
|
|
27
|
+
## Security and reliability
|
|
28
|
+
|
|
29
|
+
- Enforced read-only plan-mode boundaries across tools, shell execution, task delegation, and
|
|
30
|
+
project-note writes.
|
|
31
|
+
- Hardened permission parsing, credential and error redaction, generated-code isolation, secure file
|
|
32
|
+
handling, and session persistence against races and concurrent edits.
|
|
33
|
+
- Made web access DNS-pinned, redirect-safe, and public-unicast-only to prevent private-network and
|
|
34
|
+
mixed-resolution request forgery.
|
|
35
|
+
- Removed the SWE-bench runner, offline benchmark command, automation-only `exec` driver, and LLM
|
|
36
|
+
response record/replay cache so the package is solely the core product.
|
|
37
|
+
- Expanded the hermetic suite to 470 passing tests across the runtime, interface, security, and
|
|
38
|
+
repository workflows.
|
|
39
|
+
|
|
40
|
+
## Upgrade
|
|
41
|
+
|
|
42
|
+
Existing managed installations can run:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
noah update
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
New installations can use the one-command installer from the README.
|
|
49
|
+
|
|
50
|
+
**Full changelog:** https://github.com/skundu42/noah-code/compare/v0.2.2...v0.2.3
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "noah-code"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.3"
|
|
4
4
|
description = "Noah Code terminal coding agent, built on NVIDIA OO Agents (NOOA)"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.12,<3.14"
|
|
@@ -28,7 +28,6 @@ dependencies = [
|
|
|
28
28
|
"pydantic>=2.5.0",
|
|
29
29
|
"PyYAML>=6.0.0",
|
|
30
30
|
"packaging>=24.0",
|
|
31
|
-
"tomli>=2.0.0; python_version < '3.11'",
|
|
32
31
|
"rich>=13.0.0",
|
|
33
32
|
"textual>=1.0.0",
|
|
34
33
|
]
|
|
@@ -44,7 +43,9 @@ Releases = "https://github.com/skundu42/noah-code/releases"
|
|
|
44
43
|
dev = [
|
|
45
44
|
"pytest>=8.0.0",
|
|
46
45
|
"pytest-asyncio>=0.24.0",
|
|
46
|
+
"pytest-cov>=5.0.0",
|
|
47
47
|
"ruff>=0.8.0",
|
|
48
|
+
"mypy>=1.13.0",
|
|
48
49
|
]
|
|
49
50
|
tui = [
|
|
50
51
|
"textual>=1.0.0",
|
|
@@ -77,6 +78,8 @@ package = true
|
|
|
77
78
|
asyncio_mode = "auto"
|
|
78
79
|
asyncio_default_fixture_loop_scope = "function"
|
|
79
80
|
testpaths = ["tests"]
|
|
81
|
+
# Keep the default suite hermetic; opt in with `pytest -m integration`.
|
|
82
|
+
addopts = ["-m", "not integration"]
|
|
80
83
|
markers = [
|
|
81
84
|
"integration: tests that may touch the network (deselect by default)",
|
|
82
85
|
]
|
|
@@ -89,3 +92,27 @@ src = ["src", "tests"]
|
|
|
89
92
|
[tool.ruff.lint]
|
|
90
93
|
select = ["E", "F", "I", "UP", "B", "SIM"]
|
|
91
94
|
ignore = ["E501"]
|
|
95
|
+
|
|
96
|
+
[tool.mypy]
|
|
97
|
+
python_version = "3.12"
|
|
98
|
+
files = ["src/noah_code"]
|
|
99
|
+
check_untyped_defs = true
|
|
100
|
+
no_implicit_optional = true
|
|
101
|
+
warn_redundant_casts = true
|
|
102
|
+
warn_unused_ignores = true
|
|
103
|
+
# NOOA's tool/skill framework stacks @hidden/@property and spec() decorators
|
|
104
|
+
# in ways mypy's plugin model does not describe; these codes are noise here.
|
|
105
|
+
disable_error_code = ["prop-decorator", "empty-body"]
|
|
106
|
+
|
|
107
|
+
[[tool.mypy.overrides]]
|
|
108
|
+
# nooa resolves attributes lazily (PEP 562) and litellm ships no stubs;
|
|
109
|
+
# treat every public surface as Any instead of half-analyzing sources.
|
|
110
|
+
module = ["nooa", "nooa.*", "nooa_cli", "nooa_cli.*", "litellm", "litellm.*"]
|
|
111
|
+
follow_imports = "skip"
|
|
112
|
+
ignore_missing_imports = true
|
|
113
|
+
|
|
114
|
+
[dependency-groups]
|
|
115
|
+
dev = [
|
|
116
|
+
"mypy>=2.3.1",
|
|
117
|
+
"types-pyyaml>=6.0.12.20260815",
|
|
118
|
+
]
|