duh-cli 0.2.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 (206) hide show
  1. duh_cli-0.2.0/.coverage +0 -0
  2. duh_cli-0.2.0/.duh/templates/code-review.md +15 -0
  3. duh_cli-0.2.0/.github/workflows/ci.yml +38 -0
  4. duh_cli-0.2.0/.github/workflows/publish.yml +48 -0
  5. duh_cli-0.2.0/.gitignore +9 -0
  6. duh_cli-0.2.0/.playwright-mcp/page-2026-04-07T08-35-15-630Z.yml +6 -0
  7. duh_cli-0.2.0/LICENSE +15 -0
  8. duh_cli-0.2.0/PKG-INFO +249 -0
  9. duh_cli-0.2.0/README.md +213 -0
  10. duh_cli-0.2.0/bin/duh-sdk-shim +2 -0
  11. duh_cli-0.2.0/docs/adrs/ADR-001-project-vision.md +48 -0
  12. duh_cli-0.2.0/docs/adrs/ADR-002-kernel-design.md +66 -0
  13. duh_cli-0.2.0/docs/adrs/ADR-003-ports-and-adapters.md +115 -0
  14. duh_cli-0.2.0/docs/adrs/ADR-004-tool-protocol.md +77 -0
  15. duh_cli-0.2.0/docs/adrs/ADR-005-safety-architecture.md +67 -0
  16. duh_cli-0.2.0/docs/adrs/ADR-006-context-engineering.md +75 -0
  17. duh_cli-0.2.0/docs/adrs/ADR-007-session-persistence.md +81 -0
  18. duh_cli-0.2.0/docs/adrs/ADR-008-cli-design.md +128 -0
  19. duh_cli-0.2.0/docs/adrs/ADR-009-provider-adapters.md +158 -0
  20. duh_cli-0.2.0/docs/adrs/ADR-010-mcp-integration.md +110 -0
  21. duh_cli-0.2.0/docs/adrs/ADR-011-tui-architecture.md +110 -0
  22. duh_cli-0.2.0/docs/adrs/ADR-012-multi-agent.md +123 -0
  23. duh_cli-0.2.0/docs/adrs/ADR-013-hook-system.md +150 -0
  24. duh_cli-0.2.0/docs/adrs/ADR-014-plugin-architecture.md +144 -0
  25. duh_cli-0.2.0/docs/adrs/ADR-015-configuration.md +235 -0
  26. duh_cli-0.2.0/docs/adrs/ADR-016-memory-system.md +147 -0
  27. duh_cli-0.2.0/docs/adrs/ADR-017-skills-system.md +147 -0
  28. duh_cli-0.2.0/docs/adrs/ADR-018-progressive-disclosure.md +132 -0
  29. duh_cli-0.2.0/docs/adrs/ADR-019-next-phase-plan.md +83 -0
  30. duh_cli-0.2.0/docs/adrs/ADR-020-wave-roadmap.md +67 -0
  31. duh_cli-0.2.0/docs/architecture-comparison.md +244 -0
  32. duh_cli-0.2.0/docs/benchmark-results.md +88 -0
  33. duh_cli-0.2.0/docs/social-media-drafts.md +199 -0
  34. duh_cli-0.2.0/duh/__init__.py +6 -0
  35. duh_cli-0.2.0/duh/__main__.py +5 -0
  36. duh_cli-0.2.0/duh/adapters/__init__.py +6 -0
  37. duh_cli-0.2.0/duh/adapters/anthropic.py +324 -0
  38. duh_cli-0.2.0/duh/adapters/approvers.py +88 -0
  39. duh_cli-0.2.0/duh/adapters/file_store.py +151 -0
  40. duh_cli-0.2.0/duh/adapters/mcp_executor.py +314 -0
  41. duh_cli-0.2.0/duh/adapters/memory_store.py +323 -0
  42. duh_cli-0.2.0/duh/adapters/native_executor.py +147 -0
  43. duh_cli-0.2.0/duh/adapters/ollama.py +359 -0
  44. duh_cli-0.2.0/duh/adapters/openai.py +309 -0
  45. duh_cli-0.2.0/duh/adapters/renderers.py +165 -0
  46. duh_cli-0.2.0/duh/adapters/simple_compactor.py +362 -0
  47. duh_cli-0.2.0/duh/adapters/structured_logging.py +169 -0
  48. duh_cli-0.2.0/duh/agents.py +219 -0
  49. duh_cli-0.2.0/duh/cli/__init__.py +5 -0
  50. duh_cli-0.2.0/duh/cli/doctor.py +144 -0
  51. duh_cli-0.2.0/duh/cli/main.py +63 -0
  52. duh_cli-0.2.0/duh/cli/ndjson.py +37 -0
  53. duh_cli-0.2.0/duh/cli/parser.py +81 -0
  54. duh_cli-0.2.0/duh/cli/repl.py +1178 -0
  55. duh_cli-0.2.0/duh/cli/runner.py +474 -0
  56. duh_cli-0.2.0/duh/cli/sdk_runner.py +321 -0
  57. duh_cli-0.2.0/duh/config.py +306 -0
  58. duh_cli-0.2.0/duh/hooks.py +382 -0
  59. duh_cli-0.2.0/duh/kernel/__init__.py +27 -0
  60. duh_cli-0.2.0/duh/kernel/backoff.py +167 -0
  61. duh_cli-0.2.0/duh/kernel/deps.py +56 -0
  62. duh_cli-0.2.0/duh/kernel/engine.py +344 -0
  63. duh_cli-0.2.0/duh/kernel/file_tracker.py +153 -0
  64. duh_cli-0.2.0/duh/kernel/git_context.py +142 -0
  65. duh_cli-0.2.0/duh/kernel/health_check.py +150 -0
  66. duh_cli-0.2.0/duh/kernel/job_queue.py +132 -0
  67. duh_cli-0.2.0/duh/kernel/loop.py +225 -0
  68. duh_cli-0.2.0/duh/kernel/memory.py +118 -0
  69. duh_cli-0.2.0/duh/kernel/messages.py +112 -0
  70. duh_cli-0.2.0/duh/kernel/plan_mode.py +214 -0
  71. duh_cli-0.2.0/duh/kernel/skill.py +314 -0
  72. duh_cli-0.2.0/duh/kernel/tasks.py +104 -0
  73. duh_cli-0.2.0/duh/kernel/templates.py +205 -0
  74. duh_cli-0.2.0/duh/kernel/tokens.py +162 -0
  75. duh_cli-0.2.0/duh/kernel/tool.py +126 -0
  76. duh_cli-0.2.0/duh/kernel/undo.py +103 -0
  77. duh_cli-0.2.0/duh/plugins.py +313 -0
  78. duh_cli-0.2.0/duh/ports/__init__.py +21 -0
  79. duh_cli-0.2.0/duh/ports/approver.py +26 -0
  80. duh_cli-0.2.0/duh/ports/context.py +26 -0
  81. duh_cli-0.2.0/duh/ports/executor.py +30 -0
  82. duh_cli-0.2.0/duh/ports/memory.py +57 -0
  83. duh_cli-0.2.0/duh/ports/provider.py +48 -0
  84. duh_cli-0.2.0/duh/ports/renderer.py +68 -0
  85. duh_cli-0.2.0/duh/ports/store.py +26 -0
  86. duh_cli-0.2.0/duh/tools/__init__.py +43 -0
  87. duh_cli-0.2.0/duh/tools/agent_tool.py +38 -0
  88. duh_cli-0.2.0/duh/tools/bash.py +247 -0
  89. duh_cli-0.2.0/duh/tools/bash_security.py +306 -0
  90. duh_cli-0.2.0/duh/tools/db_tool.py +283 -0
  91. duh_cli-0.2.0/duh/tools/docker_tool.py +223 -0
  92. duh_cli-0.2.0/duh/tools/edit.py +144 -0
  93. duh_cli-0.2.0/duh/tools/github_tool.py +255 -0
  94. duh_cli-0.2.0/duh/tools/glob_tool.py +68 -0
  95. duh_cli-0.2.0/duh/tools/grep.py +101 -0
  96. duh_cli-0.2.0/duh/tools/http_tool.py +195 -0
  97. duh_cli-0.2.0/duh/tools/lsp_tool.py +428 -0
  98. duh_cli-0.2.0/duh/tools/mcp_tool.py +76 -0
  99. duh_cli-0.2.0/duh/tools/memory_tool.py +150 -0
  100. duh_cli-0.2.0/duh/tools/multi_edit.py +173 -0
  101. duh_cli-0.2.0/duh/tools/notebook_edit.py +243 -0
  102. duh_cli-0.2.0/duh/tools/read.py +180 -0
  103. duh_cli-0.2.0/duh/tools/registry.py +205 -0
  104. duh_cli-0.2.0/duh/tools/skill_tool.py +103 -0
  105. duh_cli-0.2.0/duh/tools/task_tool.py +140 -0
  106. duh_cli-0.2.0/duh/tools/test_impact.py +237 -0
  107. duh_cli-0.2.0/duh/tools/tool_search.py +206 -0
  108. duh_cli-0.2.0/duh/tools/web_fetch.py +142 -0
  109. duh_cli-0.2.0/duh/tools/web_search.py +124 -0
  110. duh_cli-0.2.0/duh/tools/worktree.py +237 -0
  111. duh_cli-0.2.0/duh/tools/write.py +82 -0
  112. duh_cli-0.2.0/pyproject.toml +55 -0
  113. duh_cli-0.2.0/tests/__init__.py +0 -0
  114. duh_cli-0.2.0/tests/e2e_claudeflow_smoke.py +131 -0
  115. duh_cli-0.2.0/tests/e2e_sdk_smoke.py +124 -0
  116. duh_cli-0.2.0/tests/e2e_uc_api_smoke.py +161 -0
  117. duh_cli-0.2.0/tests/e2e_uc_chat_smoke.py +131 -0
  118. duh_cli-0.2.0/tests/integration/__init__.py +0 -0
  119. duh_cli-0.2.0/tests/integration/test_cli_e2e.py +50 -0
  120. duh_cli-0.2.0/tests/integration/test_full_pipeline.py +1155 -0
  121. duh_cli-0.2.0/tests/integration/test_hooks_e2e.py +534 -0
  122. duh_cli-0.2.0/tests/integration/test_mcp_playwright.py +228 -0
  123. duh_cli-0.2.0/tests/integration/test_ruflow_orchestration.py +109 -0
  124. duh_cli-0.2.0/tests/unit/__init__.py +0 -0
  125. duh_cli-0.2.0/tests/unit/test_agent_model_selection.py +396 -0
  126. duh_cli-0.2.0/tests/unit/test_agent_tool_coverage.py +209 -0
  127. duh_cli-0.2.0/tests/unit/test_agents.py +194 -0
  128. duh_cli-0.2.0/tests/unit/test_anthropic_adapter.py +193 -0
  129. duh_cli-0.2.0/tests/unit/test_anthropic_adapter_full.py +692 -0
  130. duh_cli-0.2.0/tests/unit/test_approvers.py +104 -0
  131. duh_cli-0.2.0/tests/unit/test_backoff.py +397 -0
  132. duh_cli-0.2.0/tests/unit/test_bash_security.py +299 -0
  133. duh_cli-0.2.0/tests/unit/test_brief_mode.py +174 -0
  134. duh_cli-0.2.0/tests/unit/test_cli.py +304 -0
  135. duh_cli-0.2.0/tests/unit/test_cli_full.py +503 -0
  136. duh_cli-0.2.0/tests/unit/test_compactor.py +321 -0
  137. duh_cli-0.2.0/tests/unit/test_config.py +355 -0
  138. duh_cli-0.2.0/tests/unit/test_context_dashboard.py +222 -0
  139. duh_cli-0.2.0/tests/unit/test_conversation_search.py +164 -0
  140. duh_cli-0.2.0/tests/unit/test_cost_control.py +322 -0
  141. duh_cli-0.2.0/tests/unit/test_cross_shell.py +320 -0
  142. duh_cli-0.2.0/tests/unit/test_db_tool.py +418 -0
  143. duh_cli-0.2.0/tests/unit/test_deps.py +64 -0
  144. duh_cli-0.2.0/tests/unit/test_docker_tool.py +383 -0
  145. duh_cli-0.2.0/tests/unit/test_edit_diff.py +196 -0
  146. duh_cli-0.2.0/tests/unit/test_engine.py +90 -0
  147. duh_cli-0.2.0/tests/unit/test_fallback_model.py +263 -0
  148. duh_cli-0.2.0/tests/unit/test_file_permissions.py +282 -0
  149. duh_cli-0.2.0/tests/unit/test_file_store.py +404 -0
  150. duh_cli-0.2.0/tests/unit/test_file_store_full.py +58 -0
  151. duh_cli-0.2.0/tests/unit/test_file_tracker.py +454 -0
  152. duh_cli-0.2.0/tests/unit/test_git_context.py +337 -0
  153. duh_cli-0.2.0/tests/unit/test_git_warnings.py +247 -0
  154. duh_cli-0.2.0/tests/unit/test_github_tool.py +393 -0
  155. duh_cli-0.2.0/tests/unit/test_health_check.py +279 -0
  156. duh_cli-0.2.0/tests/unit/test_history_dedup.py +346 -0
  157. duh_cli-0.2.0/tests/unit/test_hooks.py +530 -0
  158. duh_cli-0.2.0/tests/unit/test_http_tool.py +414 -0
  159. duh_cli-0.2.0/tests/unit/test_job_queue.py +294 -0
  160. duh_cli-0.2.0/tests/unit/test_loop.py +351 -0
  161. duh_cli-0.2.0/tests/unit/test_loop_exhaustive.py +542 -0
  162. duh_cli-0.2.0/tests/unit/test_loop_full.py +98 -0
  163. duh_cli-0.2.0/tests/unit/test_lsp_tool.py +370 -0
  164. duh_cli-0.2.0/tests/unit/test_mcp_executor.py +421 -0
  165. duh_cli-0.2.0/tests/unit/test_mcp_tool.py +214 -0
  166. duh_cli-0.2.0/tests/unit/test_memory.py +492 -0
  167. duh_cli-0.2.0/tests/unit/test_messages.py +128 -0
  168. duh_cli-0.2.0/tests/unit/test_messages_exhaustive.py +339 -0
  169. duh_cli-0.2.0/tests/unit/test_multi_edit.py +259 -0
  170. duh_cli-0.2.0/tests/unit/test_native_executor.py +178 -0
  171. duh_cli-0.2.0/tests/unit/test_ndjson.py +69 -0
  172. duh_cli-0.2.0/tests/unit/test_notebook_edit.py +470 -0
  173. duh_cli-0.2.0/tests/unit/test_ollama_adapter.py +200 -0
  174. duh_cli-0.2.0/tests/unit/test_ollama_adapter_full.py +356 -0
  175. duh_cli-0.2.0/tests/unit/test_openai_adapter.py +129 -0
  176. duh_cli-0.2.0/tests/unit/test_output_limits.py +233 -0
  177. duh_cli-0.2.0/tests/unit/test_packaging.py +70 -0
  178. duh_cli-0.2.0/tests/unit/test_persistent_memory.py +477 -0
  179. duh_cli-0.2.0/tests/unit/test_plan_mode.py +360 -0
  180. duh_cli-0.2.0/tests/unit/test_plugins.py +430 -0
  181. duh_cli-0.2.0/tests/unit/test_ports.py +130 -0
  182. duh_cli-0.2.0/tests/unit/test_ports_full.py +23 -0
  183. duh_cli-0.2.0/tests/unit/test_readline_history.py +189 -0
  184. duh_cli-0.2.0/tests/unit/test_registry_coverage.py +306 -0
  185. duh_cli-0.2.0/tests/unit/test_renderers.py +217 -0
  186. duh_cli-0.2.0/tests/unit/test_repl.py +129 -0
  187. duh_cli-0.2.0/tests/unit/test_repl_coverage.py +767 -0
  188. duh_cli-0.2.0/tests/unit/test_runner_coverage.py +847 -0
  189. duh_cli-0.2.0/tests/unit/test_sdk_runner.py +224 -0
  190. duh_cli-0.2.0/tests/unit/test_sdk_runner_coverage.py +577 -0
  191. duh_cli-0.2.0/tests/unit/test_session_autosave.py +328 -0
  192. duh_cli-0.2.0/tests/unit/test_skills.py +685 -0
  193. duh_cli-0.2.0/tests/unit/test_streaming_errors.py +553 -0
  194. duh_cli-0.2.0/tests/unit/test_structured_logging.py +294 -0
  195. duh_cli-0.2.0/tests/unit/test_tasks.py +343 -0
  196. duh_cli-0.2.0/tests/unit/test_templates.py +354 -0
  197. duh_cli-0.2.0/tests/unit/test_test_impact.py +314 -0
  198. duh_cli-0.2.0/tests/unit/test_tokens.py +519 -0
  199. duh_cli-0.2.0/tests/unit/test_tool.py +129 -0
  200. duh_cli-0.2.0/tests/unit/test_tool_gaps.py +512 -0
  201. duh_cli-0.2.0/tests/unit/test_tool_search.py +274 -0
  202. duh_cli-0.2.0/tests/unit/test_tool_timeouts.py +243 -0
  203. duh_cli-0.2.0/tests/unit/test_tools.py +510 -0
  204. duh_cli-0.2.0/tests/unit/test_undo.py +346 -0
  205. duh_cli-0.2.0/tests/unit/test_web_tools.py +477 -0
  206. duh_cli-0.2.0/tests/unit/test_worktree.py +342 -0
Binary file
@@ -0,0 +1,15 @@
1
+ ---
2
+ name: code-review
3
+ description: Wrap a prompt in a thorough code review context.
4
+ ---
5
+
6
+ You are an expert code reviewer. Examine the following with an eye for:
7
+ - Correctness and edge cases
8
+ - Performance and efficiency
9
+ - Security vulnerabilities
10
+ - Readability and maintainability
11
+ - Adherence to project conventions
12
+
13
+ Be direct and specific. Cite line numbers when possible.
14
+
15
+ $PROMPT
@@ -0,0 +1,38 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ timeout-minutes: 10
13
+ strategy:
14
+ matrix:
15
+ python-version: ["3.12"]
16
+
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+
20
+ - name: Set up Python ${{ matrix.python-version }}
21
+ uses: actions/setup-python@v5
22
+ with:
23
+ python-version: ${{ matrix.python-version }}
24
+
25
+ - name: Cache pip
26
+ uses: actions/cache@v4
27
+ with:
28
+ path: ~/.cache/pip
29
+ key: ${{ runner.os }}-pip-${{ hashFiles('pyproject.toml') }}
30
+ restore-keys: |
31
+ ${{ runner.os }}-pip-
32
+
33
+ - name: Install dependencies
34
+ run: pip install -e ".[dev]"
35
+
36
+ - name: Run tests
37
+ continue-on-error: false
38
+ run: pytest -q --tb=short --ignore=tests/integration
@@ -0,0 +1,48 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ permissions:
9
+ id-token: write
10
+
11
+ jobs:
12
+ build:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+
17
+ - name: Set up Python
18
+ uses: actions/setup-python@v5
19
+ with:
20
+ python-version: "3.12"
21
+
22
+ - name: Install build tools
23
+ run: pip install build
24
+
25
+ - name: Build wheel and sdist
26
+ run: python -m build
27
+
28
+ - name: Upload artifacts
29
+ uses: actions/upload-artifact@v4
30
+ with:
31
+ name: dist
32
+ path: dist/
33
+
34
+ publish:
35
+ needs: build
36
+ runs-on: ubuntu-latest
37
+ environment: pypi
38
+ permissions:
39
+ id-token: write
40
+ steps:
41
+ - name: Download artifacts
42
+ uses: actions/download-artifact@v4
43
+ with:
44
+ name: dist
45
+ path: dist/
46
+
47
+ - name: Publish to PyPI
48
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,9 @@
1
+ .venv/
2
+ __pycache__/
3
+ *.pyc
4
+ *.egg-info/
5
+ dist/
6
+ build/
7
+ .pytest_cache/
8
+ .mypy_cache/
9
+ *.egg
@@ -0,0 +1,6 @@
1
+ - generic [ref=e2]:
2
+ - heading "Example Domain" [level=1] [ref=e3]
3
+ - paragraph [ref=e4]: This domain is for use in documentation examples without needing permission. Avoid use in operations.
4
+ - paragraph [ref=e5]:
5
+ - link "Learn more" [ref=e6] [cursor=pointer]:
6
+ - /url: https://iana.org/domains/example
duh_cli-0.2.0/LICENSE ADDED
@@ -0,0 +1,15 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
duh_cli-0.2.0/PKG-INFO ADDED
@@ -0,0 +1,249 @@
1
+ Metadata-Version: 2.4
2
+ Name: duh-cli
3
+ Version: 0.2.0
4
+ Summary: D.U.H. — Duh is a Universal Harness. Provider-agnostic AI coding agent.
5
+ Project-URL: Homepage, https://github.com/nikhilvallishayee/duh
6
+ Project-URL: Repository, https://github.com/nikhilvallishayee/duh
7
+ Project-URL: Issues, https://github.com/nikhilvallishayee/duh/issues
8
+ Author: Nikhil Vallishayee
9
+ License-Expression: Apache-2.0
10
+ License-File: LICENSE
11
+ Keywords: agent,ai,claude,cli,coding,harness,mcp,ollama,openai
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: Apache Software License
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Topic :: Software Development
18
+ Requires-Python: >=3.12
19
+ Requires-Dist: anthropic>=0.40.0
20
+ Requires-Dist: httpx>=0.27.0
21
+ Requires-Dist: pydantic>=2.0
22
+ Provides-Extra: all
23
+ Requires-Dist: openai>=1.0; extra == 'all'
24
+ Requires-Dist: rich>=13.0; extra == 'all'
25
+ Provides-Extra: dev
26
+ Requires-Dist: openai>=1.0; extra == 'dev'
27
+ Requires-Dist: pytest; extra == 'dev'
28
+ Requires-Dist: pytest-asyncio; extra == 'dev'
29
+ Requires-Dist: pytest-cov; extra == 'dev'
30
+ Requires-Dist: rich>=13.0; extra == 'dev'
31
+ Provides-Extra: openai
32
+ Requires-Dist: openai>=1.0; extra == 'openai'
33
+ Provides-Extra: rich
34
+ Requires-Dist: rich>=13.0; extra == 'rich'
35
+ Description-Content-Type: text/markdown
36
+
37
+ # D.U.H. — D.U.H. is a Universal Harness
38
+
39
+ [![CI](https://github.com/nikhilvallishayee/duh/actions/workflows/ci.yml/badge.svg)](https://github.com/nikhilvallishayee/duh/actions/workflows/ci.yml)
40
+ [![Tests](https://img.shields.io/badge/tests-2309%20passing-brightgreen)]()
41
+ [![Coverage](https://img.shields.io/badge/coverage-90%25-green)]()
42
+ [![Python](https://img.shields.io/badge/python-3.12%2B-blue)]()
43
+ [![License](https://img.shields.io/badge/license-Apache%202.0-blue)](LICENSE)
44
+
45
+ > An evolving, open-source alternative to Claude Code, OpenCode, Codex, and Cline.
46
+
47
+ Provider-agnostic AI coding harness. Use Claude, GPT-4o, or Ollama local models through one interface. Drop-in replacement for Claude Code in any Claude Agent SDK app.
48
+
49
+ ## Quick Start
50
+
51
+ ```bash
52
+ pip install duh-cli
53
+ export ANTHROPIC_API_KEY=sk-ant-... # or OPENAI_API_KEY, or just use Ollama
54
+ duh -p "fix the bug in auth.py" # print mode
55
+ duh # interactive REPL
56
+ ```
57
+
58
+ ## Benchmark: D.U.H. vs Claude Code
59
+
60
+ Same model (Haiku 4.5), same prompt, same API, 3 runs each, isolated directories:
61
+
62
+ | Metric | Claude Code | D.U.H. |
63
+ |---|---|---|
64
+ | **Avg time** | 63.2s | **45.7s** (-28%) |
65
+ | **Avg tests generated** | 10.5 | **18** (+71%) |
66
+ | **Success rate** | 2/3 (67%) | **3/3 (100%)** |
67
+ | **Self-correction** | Minimal | **Active** (fixes own test failures) |
68
+
69
+ Full methodology: [docs/benchmark-results.md](docs/benchmark-results.md)
70
+
71
+ ## Feature Comparison
72
+
73
+ | Feature | D.U.H. | Claude Code | OpenCode | Codex | Cline |
74
+ |---|---|---|---|---|---|
75
+ | **Open source** | Apache 2.0 | No | Yes | No | Yes |
76
+ | **Providers** | 3 (Claude, GPT, Ollama) | Anthropic only | 75+ | OpenAI only | Multi |
77
+ | **SDK drop-in** | Yes | N/A | No | No | No |
78
+ | **Skill format parity** | .claude/ + .duh/ | .claude/ | No | No | No |
79
+ | **Multi-agent** | 4 types + model selection | 60+ types | No | Yes | No |
80
+ | **MCP support** | Adapter (verified) | Full | No | Yes | Extension |
81
+ | **Hooks** | 6 events + shell exec | Hooks | No | Yes | No |
82
+ | **Safety layers** | 3 (schema + approval + 61 patterns) | 3 | 1 | Sandbox | 1 |
83
+ | **Context management** | Auto-compact + dedup | 16 modules | Auto at 95% | Yes | Manual |
84
+ | **TUI** | Rich markdown REPL | Ink (React) | Bubble Tea | Bubble Tea | IDE |
85
+ | **Session persistence** | Auto-save per turn | Full | SQLite | Yes | IDE |
86
+ | **Background jobs** | bg: prefix + /jobs | Full | No | Yes | No |
87
+ | **Plan mode** | /plan (design-first) | Yes | No | Yes | No |
88
+ | **Notebook editing** | .ipynb cells | Yes | No | No | No |
89
+ | **Git worktrees** | EnterWorktree/Exit | Yes | No | No | No |
90
+ | **File undo** | /undo stack | Limited | No | No | IDE |
91
+ | **Cost control** | --max-cost + budget | Limited | No | No | No |
92
+ | **Test impact** | TestImpact tool | No | No | No | No |
93
+ | **LSP** | Static analysis | Full LSP | Yes | Yes | IDE |
94
+ | **Docker** | DockerTool | No | No | No | No |
95
+ | **Database** | SQL query tool | No | No | No | No |
96
+ | **GitHub PR** | gh CLI integration | No | No | No | No |
97
+ | **HTTP testing** | HTTPTool | No | No | No | No |
98
+ | **Tests** | 2309 | Internal | Unknown | Unknown | Unknown |
99
+
100
+ ## What You Can Do
101
+
102
+ ```bash
103
+ # Code generation and modification
104
+ duh -p "add input validation to the API endpoints" --dangerously-skip-permissions
105
+
106
+ # Interactive REPL with 17 commands
107
+ duh
108
+ duh> /help # see all commands
109
+ duh> /plan add user auth # design first, then execute
110
+ duh> /model claude-opus-4-6 # switch models mid-session
111
+ duh> /brief on # concise mode
112
+ duh> /context # token usage dashboard
113
+ duh> /search "auth" # search conversation history
114
+ duh> /undo # revert last file change
115
+ duh> /tasks # track work items
116
+ duh> /git # repo status
117
+ duh> /pr list # GitHub PRs
118
+ duh> /health # provider connectivity
119
+ duh> /cost # estimated spend
120
+ duh> /jobs # background tasks
121
+
122
+ # Multi-agent with model selection
123
+ duh -p "research the API, then implement" --max-turns 20
124
+ # Model spawns researcher (haiku) and coder (sonnet) subagents
125
+
126
+ # SDK compatibility — drop-in for Claude Code
127
+ from claude_agent_sdk import ClaudeAgentOptions, query
128
+ async for msg in query(
129
+ prompt="fix the bug",
130
+ options=ClaudeAgentOptions(cli_path="/path/to/duh-sdk-shim")
131
+ ):
132
+ print(msg)
133
+
134
+ # Background jobs
135
+ duh> bg: pytest tests/ -v # runs tests in background
136
+ duh> /jobs # check status
137
+
138
+ # Template-driven prompts
139
+ duh> /template code-review # use a saved prompt pattern
140
+
141
+ # Docker integration
142
+ duh -p "build and test in Docker"
143
+
144
+ # Database inspection
145
+ duh -p "show me the schema and recent users"
146
+ ```
147
+
148
+ ## Architecture
149
+
150
+ ```
151
+ duh/
152
+ kernel/ # Core loop (provider-agnostic, zero external imports)
153
+ loop.py # prompt → model → tool → result (async generator)
154
+ engine.py # session wrapper + auto-compaction + budget control
155
+ backoff.py # exponential retry for transient API errors
156
+ tokens.py # token estimation + cost calculation
157
+ tasks.py # task tracking with checkbox display
158
+ plan_mode.py # design-first two-phase workflows
159
+ undo.py # file modification rollback
160
+ git_context.py # branch, status, warnings in system prompt
161
+ skill.py # .claude/ + .duh/ skill loading
162
+ memory.py # per-project persistent facts
163
+
164
+ adapters/ # Provider wrappers (translate to uniform events)
165
+ anthropic.py # Claude (streaming + backoff)
166
+ openai.py # GPT-4o, o1 (streaming + backoff)
167
+ ollama.py # Local models (tool call extraction fallback)
168
+ mcp_executor.py # MCP server connection + tool execution
169
+ structured_logging.py # JSONL audit log
170
+
171
+ tools/ # 25+ tools
172
+ read, write, edit, multi_edit, bash, glob, grep,
173
+ skill, tool_search, web_fetch, web_search, task,
174
+ notebook_edit, memory (store + recall), test_impact,
175
+ lsp, worktree (enter + exit), github, http, docker,
176
+ database, agent, mcp_tool
177
+
178
+ cli/ # CLI interface
179
+ main.py # Entry point + signal handling
180
+ parser.py # 20+ flags including --brief, --max-cost, --log-json
181
+ runner.py # Print mode
182
+ repl.py # Rich REPL with 17 slash commands
183
+ sdk_runner.py # Claude Agent SDK NDJSON protocol
184
+ ndjson.py # Stream-JSON helpers
185
+ ```
186
+
187
+ ## Providers
188
+
189
+ | Provider | Status | Models | Auto-detect |
190
+ |---|---|---|---|
191
+ | **Anthropic** | Working | Sonnet 4.6, Opus 4.6, Haiku 4.5 | ANTHROPIC_API_KEY or --model claude-* |
192
+ | **OpenAI** | Working | GPT-4o, o1, any OpenAI-compatible | OPENAI_API_KEY or --model gpt-* |
193
+ | **Ollama** | Working | Any local model | Ollama running on localhost |
194
+
195
+ ## Safety
196
+
197
+ 3-layer defense:
198
+ 1. **Schema validation** — tool inputs checked before execution
199
+ 2. **Approval gates** — InteractiveApprover prompts for dangerous tools, RuleApprover for policy
200
+ 3. **Command security** — 61 patterns (26 dangerous + 10 moderate + 18 PS dangerous + 7 PS moderate)
201
+
202
+ Bash security blocks: `rm -rf /`, fork bombs, `dd`, `mkfs`, pipe-to-shell, `eval`, `sudo`, reverse shells, and more. PowerShell patterns included for Windows.
203
+
204
+ ## Skills
205
+
206
+ D.U.H. loads skills from Claude Code directories natively:
207
+
208
+ ```
209
+ ~/.claude/skills/ → Claude Code global skills
210
+ ~/.config/duh/skills/ → D.U.H. global skills
211
+ .claude/skills/ → Claude Code project skills
212
+ .duh/skills/ → D.U.H. project skills (highest priority)
213
+ ```
214
+
215
+ Both `skill-name/SKILL.md` (directory) and `skill-name.md` (flat) layouts. All Claude Code frontmatter fields supported.
216
+
217
+ ## CLI Reference
218
+
219
+ ```
220
+ duh # interactive REPL
221
+ duh -p "prompt" # print mode
222
+ duh -p "prompt" --model gpt-4o # specific model
223
+ duh -p "prompt" --provider openai # force provider
224
+ duh -p "prompt" --brief # concise responses
225
+ duh -p "prompt" --max-cost 1.00 # budget limit ($1)
226
+ duh -p "prompt" --max-turns 20 # iteration limit
227
+ duh -p "prompt" --dangerously-skip-permissions
228
+ duh -p "prompt" --fallback-model haiku # auto-switch on overload
229
+ duh -p "prompt" --output-format stream-json # NDJSON for SDK
230
+ duh -p "prompt" --log-json # structured audit log
231
+ duh --input-format stream-json # SDK mode (stdin NDJSON)
232
+ duh doctor # diagnostics + connectivity
233
+ duh --version
234
+ ```
235
+
236
+ ## Development
237
+
238
+ ```bash
239
+ git clone https://github.com/nikhilvallishayee/duh
240
+ cd duh
241
+ python3.12 -m venv .venv && source .venv/bin/activate
242
+ pip install -e ".[dev]"
243
+ pytest -q --tb=short # 2309 tests, ~23s
244
+ pytest --cov=duh --cov-report=term # 90% coverage
245
+ ```
246
+
247
+ ## License
248
+
249
+ Apache 2.0
@@ -0,0 +1,213 @@
1
+ # D.U.H. — D.U.H. is a Universal Harness
2
+
3
+ [![CI](https://github.com/nikhilvallishayee/duh/actions/workflows/ci.yml/badge.svg)](https://github.com/nikhilvallishayee/duh/actions/workflows/ci.yml)
4
+ [![Tests](https://img.shields.io/badge/tests-2309%20passing-brightgreen)]()
5
+ [![Coverage](https://img.shields.io/badge/coverage-90%25-green)]()
6
+ [![Python](https://img.shields.io/badge/python-3.12%2B-blue)]()
7
+ [![License](https://img.shields.io/badge/license-Apache%202.0-blue)](LICENSE)
8
+
9
+ > An evolving, open-source alternative to Claude Code, OpenCode, Codex, and Cline.
10
+
11
+ Provider-agnostic AI coding harness. Use Claude, GPT-4o, or Ollama local models through one interface. Drop-in replacement for Claude Code in any Claude Agent SDK app.
12
+
13
+ ## Quick Start
14
+
15
+ ```bash
16
+ pip install duh-cli
17
+ export ANTHROPIC_API_KEY=sk-ant-... # or OPENAI_API_KEY, or just use Ollama
18
+ duh -p "fix the bug in auth.py" # print mode
19
+ duh # interactive REPL
20
+ ```
21
+
22
+ ## Benchmark: D.U.H. vs Claude Code
23
+
24
+ Same model (Haiku 4.5), same prompt, same API, 3 runs each, isolated directories:
25
+
26
+ | Metric | Claude Code | D.U.H. |
27
+ |---|---|---|
28
+ | **Avg time** | 63.2s | **45.7s** (-28%) |
29
+ | **Avg tests generated** | 10.5 | **18** (+71%) |
30
+ | **Success rate** | 2/3 (67%) | **3/3 (100%)** |
31
+ | **Self-correction** | Minimal | **Active** (fixes own test failures) |
32
+
33
+ Full methodology: [docs/benchmark-results.md](docs/benchmark-results.md)
34
+
35
+ ## Feature Comparison
36
+
37
+ | Feature | D.U.H. | Claude Code | OpenCode | Codex | Cline |
38
+ |---|---|---|---|---|---|
39
+ | **Open source** | Apache 2.0 | No | Yes | No | Yes |
40
+ | **Providers** | 3 (Claude, GPT, Ollama) | Anthropic only | 75+ | OpenAI only | Multi |
41
+ | **SDK drop-in** | Yes | N/A | No | No | No |
42
+ | **Skill format parity** | .claude/ + .duh/ | .claude/ | No | No | No |
43
+ | **Multi-agent** | 4 types + model selection | 60+ types | No | Yes | No |
44
+ | **MCP support** | Adapter (verified) | Full | No | Yes | Extension |
45
+ | **Hooks** | 6 events + shell exec | Hooks | No | Yes | No |
46
+ | **Safety layers** | 3 (schema + approval + 61 patterns) | 3 | 1 | Sandbox | 1 |
47
+ | **Context management** | Auto-compact + dedup | 16 modules | Auto at 95% | Yes | Manual |
48
+ | **TUI** | Rich markdown REPL | Ink (React) | Bubble Tea | Bubble Tea | IDE |
49
+ | **Session persistence** | Auto-save per turn | Full | SQLite | Yes | IDE |
50
+ | **Background jobs** | bg: prefix + /jobs | Full | No | Yes | No |
51
+ | **Plan mode** | /plan (design-first) | Yes | No | Yes | No |
52
+ | **Notebook editing** | .ipynb cells | Yes | No | No | No |
53
+ | **Git worktrees** | EnterWorktree/Exit | Yes | No | No | No |
54
+ | **File undo** | /undo stack | Limited | No | No | IDE |
55
+ | **Cost control** | --max-cost + budget | Limited | No | No | No |
56
+ | **Test impact** | TestImpact tool | No | No | No | No |
57
+ | **LSP** | Static analysis | Full LSP | Yes | Yes | IDE |
58
+ | **Docker** | DockerTool | No | No | No | No |
59
+ | **Database** | SQL query tool | No | No | No | No |
60
+ | **GitHub PR** | gh CLI integration | No | No | No | No |
61
+ | **HTTP testing** | HTTPTool | No | No | No | No |
62
+ | **Tests** | 2309 | Internal | Unknown | Unknown | Unknown |
63
+
64
+ ## What You Can Do
65
+
66
+ ```bash
67
+ # Code generation and modification
68
+ duh -p "add input validation to the API endpoints" --dangerously-skip-permissions
69
+
70
+ # Interactive REPL with 17 commands
71
+ duh
72
+ duh> /help # see all commands
73
+ duh> /plan add user auth # design first, then execute
74
+ duh> /model claude-opus-4-6 # switch models mid-session
75
+ duh> /brief on # concise mode
76
+ duh> /context # token usage dashboard
77
+ duh> /search "auth" # search conversation history
78
+ duh> /undo # revert last file change
79
+ duh> /tasks # track work items
80
+ duh> /git # repo status
81
+ duh> /pr list # GitHub PRs
82
+ duh> /health # provider connectivity
83
+ duh> /cost # estimated spend
84
+ duh> /jobs # background tasks
85
+
86
+ # Multi-agent with model selection
87
+ duh -p "research the API, then implement" --max-turns 20
88
+ # Model spawns researcher (haiku) and coder (sonnet) subagents
89
+
90
+ # SDK compatibility — drop-in for Claude Code
91
+ from claude_agent_sdk import ClaudeAgentOptions, query
92
+ async for msg in query(
93
+ prompt="fix the bug",
94
+ options=ClaudeAgentOptions(cli_path="/path/to/duh-sdk-shim")
95
+ ):
96
+ print(msg)
97
+
98
+ # Background jobs
99
+ duh> bg: pytest tests/ -v # runs tests in background
100
+ duh> /jobs # check status
101
+
102
+ # Template-driven prompts
103
+ duh> /template code-review # use a saved prompt pattern
104
+
105
+ # Docker integration
106
+ duh -p "build and test in Docker"
107
+
108
+ # Database inspection
109
+ duh -p "show me the schema and recent users"
110
+ ```
111
+
112
+ ## Architecture
113
+
114
+ ```
115
+ duh/
116
+ kernel/ # Core loop (provider-agnostic, zero external imports)
117
+ loop.py # prompt → model → tool → result (async generator)
118
+ engine.py # session wrapper + auto-compaction + budget control
119
+ backoff.py # exponential retry for transient API errors
120
+ tokens.py # token estimation + cost calculation
121
+ tasks.py # task tracking with checkbox display
122
+ plan_mode.py # design-first two-phase workflows
123
+ undo.py # file modification rollback
124
+ git_context.py # branch, status, warnings in system prompt
125
+ skill.py # .claude/ + .duh/ skill loading
126
+ memory.py # per-project persistent facts
127
+
128
+ adapters/ # Provider wrappers (translate to uniform events)
129
+ anthropic.py # Claude (streaming + backoff)
130
+ openai.py # GPT-4o, o1 (streaming + backoff)
131
+ ollama.py # Local models (tool call extraction fallback)
132
+ mcp_executor.py # MCP server connection + tool execution
133
+ structured_logging.py # JSONL audit log
134
+
135
+ tools/ # 25+ tools
136
+ read, write, edit, multi_edit, bash, glob, grep,
137
+ skill, tool_search, web_fetch, web_search, task,
138
+ notebook_edit, memory (store + recall), test_impact,
139
+ lsp, worktree (enter + exit), github, http, docker,
140
+ database, agent, mcp_tool
141
+
142
+ cli/ # CLI interface
143
+ main.py # Entry point + signal handling
144
+ parser.py # 20+ flags including --brief, --max-cost, --log-json
145
+ runner.py # Print mode
146
+ repl.py # Rich REPL with 17 slash commands
147
+ sdk_runner.py # Claude Agent SDK NDJSON protocol
148
+ ndjson.py # Stream-JSON helpers
149
+ ```
150
+
151
+ ## Providers
152
+
153
+ | Provider | Status | Models | Auto-detect |
154
+ |---|---|---|---|
155
+ | **Anthropic** | Working | Sonnet 4.6, Opus 4.6, Haiku 4.5 | ANTHROPIC_API_KEY or --model claude-* |
156
+ | **OpenAI** | Working | GPT-4o, o1, any OpenAI-compatible | OPENAI_API_KEY or --model gpt-* |
157
+ | **Ollama** | Working | Any local model | Ollama running on localhost |
158
+
159
+ ## Safety
160
+
161
+ 3-layer defense:
162
+ 1. **Schema validation** — tool inputs checked before execution
163
+ 2. **Approval gates** — InteractiveApprover prompts for dangerous tools, RuleApprover for policy
164
+ 3. **Command security** — 61 patterns (26 dangerous + 10 moderate + 18 PS dangerous + 7 PS moderate)
165
+
166
+ Bash security blocks: `rm -rf /`, fork bombs, `dd`, `mkfs`, pipe-to-shell, `eval`, `sudo`, reverse shells, and more. PowerShell patterns included for Windows.
167
+
168
+ ## Skills
169
+
170
+ D.U.H. loads skills from Claude Code directories natively:
171
+
172
+ ```
173
+ ~/.claude/skills/ → Claude Code global skills
174
+ ~/.config/duh/skills/ → D.U.H. global skills
175
+ .claude/skills/ → Claude Code project skills
176
+ .duh/skills/ → D.U.H. project skills (highest priority)
177
+ ```
178
+
179
+ Both `skill-name/SKILL.md` (directory) and `skill-name.md` (flat) layouts. All Claude Code frontmatter fields supported.
180
+
181
+ ## CLI Reference
182
+
183
+ ```
184
+ duh # interactive REPL
185
+ duh -p "prompt" # print mode
186
+ duh -p "prompt" --model gpt-4o # specific model
187
+ duh -p "prompt" --provider openai # force provider
188
+ duh -p "prompt" --brief # concise responses
189
+ duh -p "prompt" --max-cost 1.00 # budget limit ($1)
190
+ duh -p "prompt" --max-turns 20 # iteration limit
191
+ duh -p "prompt" --dangerously-skip-permissions
192
+ duh -p "prompt" --fallback-model haiku # auto-switch on overload
193
+ duh -p "prompt" --output-format stream-json # NDJSON for SDK
194
+ duh -p "prompt" --log-json # structured audit log
195
+ duh --input-format stream-json # SDK mode (stdin NDJSON)
196
+ duh doctor # diagnostics + connectivity
197
+ duh --version
198
+ ```
199
+
200
+ ## Development
201
+
202
+ ```bash
203
+ git clone https://github.com/nikhilvallishayee/duh
204
+ cd duh
205
+ python3.12 -m venv .venv && source .venv/bin/activate
206
+ pip install -e ".[dev]"
207
+ pytest -q --tb=short # 2309 tests, ~23s
208
+ pytest --cov=duh --cov-report=term # 90% coverage
209
+ ```
210
+
211
+ ## License
212
+
213
+ Apache 2.0
@@ -0,0 +1,2 @@
1
+ #!/bin/bash
2
+ exec /Users/nomind/Code/duh/.venv/bin/python3 -m duh "$@"
@@ -0,0 +1,48 @@
1
+ # ADR-001: Project Vision
2
+
3
+ **Status**: Accepted
4
+ **Date**: 2026-04-07
5
+
6
+ ## Context
7
+
8
+ AI coding agents are becoming essential developer tools, but every harness is either:
9
+ - Locked to one provider (e.g. Anthropic-only harnesses)
10
+ - Missing production safety (Aider → no permissions)
11
+ - Too complex to understand (production harnesses grow to hundreds of thousands of lines)
12
+ - Not extensible via standards (Aider → no MCP)
13
+
14
+ ## Decision
15
+
16
+ Build D.U.H. — **Duh is a Universal Harness** — the first production-grade, open-source, provider-agnostic AI coding harness with a clean kernel under 5K LOC.
17
+
18
+ ## Principles
19
+
20
+ 1. **Core loop must be basically good** — ship what works, improve iteratively
21
+ 2. **Ports and adapters** — core never imports provider SDKs
22
+ 3. **Remove duplication, improve names** — in small cycles
23
+ 4. **Evolutionary design** — refactor when the 3rd use case reveals the pattern
24
+ 5. **Unix composability** — stdout for data, stderr for humans, --json for machines
25
+ 6. **Human-first CLI** — errors tell what to do, 30-second time-to-value
26
+ 7. **Extensibility through plugins** — community adds without modifying core
27
+ 8. **Safety as architecture** — defense in depth, schema filtering
28
+ 9. **Context engineering** — first-class concern, not afterthought
29
+ 10. **Properties not rules** — composable, predictable, idiomatic, domain-based
30
+
31
+ ## Architecture
32
+
33
+ ```
34
+ duh/
35
+ kernel/ # <5K LOC — the agentic loop, zero external deps
36
+ ports/ # abstract interfaces for providers, tools, safety
37
+ adapters/ # concrete implementations
38
+ tools/ # pluggable tool set
39
+ ui/ # pluggable TUI
40
+ cli/ # CLI entry point
41
+ ```
42
+
43
+ ## Consequences
44
+
45
+ - Every feature starts with a test, then a spec, then code
46
+ - Every commit builds on the previous — clean, incremental, reviewable
47
+ - Reference implementations studied: leading TS, Python, Go, and Rust harnesses
48
+ - No single codebase is copied — universal patterns are extracted