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.
- duh_cli-0.2.0/.coverage +0 -0
- duh_cli-0.2.0/.duh/templates/code-review.md +15 -0
- duh_cli-0.2.0/.github/workflows/ci.yml +38 -0
- duh_cli-0.2.0/.github/workflows/publish.yml +48 -0
- duh_cli-0.2.0/.gitignore +9 -0
- duh_cli-0.2.0/.playwright-mcp/page-2026-04-07T08-35-15-630Z.yml +6 -0
- duh_cli-0.2.0/LICENSE +15 -0
- duh_cli-0.2.0/PKG-INFO +249 -0
- duh_cli-0.2.0/README.md +213 -0
- duh_cli-0.2.0/bin/duh-sdk-shim +2 -0
- duh_cli-0.2.0/docs/adrs/ADR-001-project-vision.md +48 -0
- duh_cli-0.2.0/docs/adrs/ADR-002-kernel-design.md +66 -0
- duh_cli-0.2.0/docs/adrs/ADR-003-ports-and-adapters.md +115 -0
- duh_cli-0.2.0/docs/adrs/ADR-004-tool-protocol.md +77 -0
- duh_cli-0.2.0/docs/adrs/ADR-005-safety-architecture.md +67 -0
- duh_cli-0.2.0/docs/adrs/ADR-006-context-engineering.md +75 -0
- duh_cli-0.2.0/docs/adrs/ADR-007-session-persistence.md +81 -0
- duh_cli-0.2.0/docs/adrs/ADR-008-cli-design.md +128 -0
- duh_cli-0.2.0/docs/adrs/ADR-009-provider-adapters.md +158 -0
- duh_cli-0.2.0/docs/adrs/ADR-010-mcp-integration.md +110 -0
- duh_cli-0.2.0/docs/adrs/ADR-011-tui-architecture.md +110 -0
- duh_cli-0.2.0/docs/adrs/ADR-012-multi-agent.md +123 -0
- duh_cli-0.2.0/docs/adrs/ADR-013-hook-system.md +150 -0
- duh_cli-0.2.0/docs/adrs/ADR-014-plugin-architecture.md +144 -0
- duh_cli-0.2.0/docs/adrs/ADR-015-configuration.md +235 -0
- duh_cli-0.2.0/docs/adrs/ADR-016-memory-system.md +147 -0
- duh_cli-0.2.0/docs/adrs/ADR-017-skills-system.md +147 -0
- duh_cli-0.2.0/docs/adrs/ADR-018-progressive-disclosure.md +132 -0
- duh_cli-0.2.0/docs/adrs/ADR-019-next-phase-plan.md +83 -0
- duh_cli-0.2.0/docs/adrs/ADR-020-wave-roadmap.md +67 -0
- duh_cli-0.2.0/docs/architecture-comparison.md +244 -0
- duh_cli-0.2.0/docs/benchmark-results.md +88 -0
- duh_cli-0.2.0/docs/social-media-drafts.md +199 -0
- duh_cli-0.2.0/duh/__init__.py +6 -0
- duh_cli-0.2.0/duh/__main__.py +5 -0
- duh_cli-0.2.0/duh/adapters/__init__.py +6 -0
- duh_cli-0.2.0/duh/adapters/anthropic.py +324 -0
- duh_cli-0.2.0/duh/adapters/approvers.py +88 -0
- duh_cli-0.2.0/duh/adapters/file_store.py +151 -0
- duh_cli-0.2.0/duh/adapters/mcp_executor.py +314 -0
- duh_cli-0.2.0/duh/adapters/memory_store.py +323 -0
- duh_cli-0.2.0/duh/adapters/native_executor.py +147 -0
- duh_cli-0.2.0/duh/adapters/ollama.py +359 -0
- duh_cli-0.2.0/duh/adapters/openai.py +309 -0
- duh_cli-0.2.0/duh/adapters/renderers.py +165 -0
- duh_cli-0.2.0/duh/adapters/simple_compactor.py +362 -0
- duh_cli-0.2.0/duh/adapters/structured_logging.py +169 -0
- duh_cli-0.2.0/duh/agents.py +219 -0
- duh_cli-0.2.0/duh/cli/__init__.py +5 -0
- duh_cli-0.2.0/duh/cli/doctor.py +144 -0
- duh_cli-0.2.0/duh/cli/main.py +63 -0
- duh_cli-0.2.0/duh/cli/ndjson.py +37 -0
- duh_cli-0.2.0/duh/cli/parser.py +81 -0
- duh_cli-0.2.0/duh/cli/repl.py +1178 -0
- duh_cli-0.2.0/duh/cli/runner.py +474 -0
- duh_cli-0.2.0/duh/cli/sdk_runner.py +321 -0
- duh_cli-0.2.0/duh/config.py +306 -0
- duh_cli-0.2.0/duh/hooks.py +382 -0
- duh_cli-0.2.0/duh/kernel/__init__.py +27 -0
- duh_cli-0.2.0/duh/kernel/backoff.py +167 -0
- duh_cli-0.2.0/duh/kernel/deps.py +56 -0
- duh_cli-0.2.0/duh/kernel/engine.py +344 -0
- duh_cli-0.2.0/duh/kernel/file_tracker.py +153 -0
- duh_cli-0.2.0/duh/kernel/git_context.py +142 -0
- duh_cli-0.2.0/duh/kernel/health_check.py +150 -0
- duh_cli-0.2.0/duh/kernel/job_queue.py +132 -0
- duh_cli-0.2.0/duh/kernel/loop.py +225 -0
- duh_cli-0.2.0/duh/kernel/memory.py +118 -0
- duh_cli-0.2.0/duh/kernel/messages.py +112 -0
- duh_cli-0.2.0/duh/kernel/plan_mode.py +214 -0
- duh_cli-0.2.0/duh/kernel/skill.py +314 -0
- duh_cli-0.2.0/duh/kernel/tasks.py +104 -0
- duh_cli-0.2.0/duh/kernel/templates.py +205 -0
- duh_cli-0.2.0/duh/kernel/tokens.py +162 -0
- duh_cli-0.2.0/duh/kernel/tool.py +126 -0
- duh_cli-0.2.0/duh/kernel/undo.py +103 -0
- duh_cli-0.2.0/duh/plugins.py +313 -0
- duh_cli-0.2.0/duh/ports/__init__.py +21 -0
- duh_cli-0.2.0/duh/ports/approver.py +26 -0
- duh_cli-0.2.0/duh/ports/context.py +26 -0
- duh_cli-0.2.0/duh/ports/executor.py +30 -0
- duh_cli-0.2.0/duh/ports/memory.py +57 -0
- duh_cli-0.2.0/duh/ports/provider.py +48 -0
- duh_cli-0.2.0/duh/ports/renderer.py +68 -0
- duh_cli-0.2.0/duh/ports/store.py +26 -0
- duh_cli-0.2.0/duh/tools/__init__.py +43 -0
- duh_cli-0.2.0/duh/tools/agent_tool.py +38 -0
- duh_cli-0.2.0/duh/tools/bash.py +247 -0
- duh_cli-0.2.0/duh/tools/bash_security.py +306 -0
- duh_cli-0.2.0/duh/tools/db_tool.py +283 -0
- duh_cli-0.2.0/duh/tools/docker_tool.py +223 -0
- duh_cli-0.2.0/duh/tools/edit.py +144 -0
- duh_cli-0.2.0/duh/tools/github_tool.py +255 -0
- duh_cli-0.2.0/duh/tools/glob_tool.py +68 -0
- duh_cli-0.2.0/duh/tools/grep.py +101 -0
- duh_cli-0.2.0/duh/tools/http_tool.py +195 -0
- duh_cli-0.2.0/duh/tools/lsp_tool.py +428 -0
- duh_cli-0.2.0/duh/tools/mcp_tool.py +76 -0
- duh_cli-0.2.0/duh/tools/memory_tool.py +150 -0
- duh_cli-0.2.0/duh/tools/multi_edit.py +173 -0
- duh_cli-0.2.0/duh/tools/notebook_edit.py +243 -0
- duh_cli-0.2.0/duh/tools/read.py +180 -0
- duh_cli-0.2.0/duh/tools/registry.py +205 -0
- duh_cli-0.2.0/duh/tools/skill_tool.py +103 -0
- duh_cli-0.2.0/duh/tools/task_tool.py +140 -0
- duh_cli-0.2.0/duh/tools/test_impact.py +237 -0
- duh_cli-0.2.0/duh/tools/tool_search.py +206 -0
- duh_cli-0.2.0/duh/tools/web_fetch.py +142 -0
- duh_cli-0.2.0/duh/tools/web_search.py +124 -0
- duh_cli-0.2.0/duh/tools/worktree.py +237 -0
- duh_cli-0.2.0/duh/tools/write.py +82 -0
- duh_cli-0.2.0/pyproject.toml +55 -0
- duh_cli-0.2.0/tests/__init__.py +0 -0
- duh_cli-0.2.0/tests/e2e_claudeflow_smoke.py +131 -0
- duh_cli-0.2.0/tests/e2e_sdk_smoke.py +124 -0
- duh_cli-0.2.0/tests/e2e_uc_api_smoke.py +161 -0
- duh_cli-0.2.0/tests/e2e_uc_chat_smoke.py +131 -0
- duh_cli-0.2.0/tests/integration/__init__.py +0 -0
- duh_cli-0.2.0/tests/integration/test_cli_e2e.py +50 -0
- duh_cli-0.2.0/tests/integration/test_full_pipeline.py +1155 -0
- duh_cli-0.2.0/tests/integration/test_hooks_e2e.py +534 -0
- duh_cli-0.2.0/tests/integration/test_mcp_playwright.py +228 -0
- duh_cli-0.2.0/tests/integration/test_ruflow_orchestration.py +109 -0
- duh_cli-0.2.0/tests/unit/__init__.py +0 -0
- duh_cli-0.2.0/tests/unit/test_agent_model_selection.py +396 -0
- duh_cli-0.2.0/tests/unit/test_agent_tool_coverage.py +209 -0
- duh_cli-0.2.0/tests/unit/test_agents.py +194 -0
- duh_cli-0.2.0/tests/unit/test_anthropic_adapter.py +193 -0
- duh_cli-0.2.0/tests/unit/test_anthropic_adapter_full.py +692 -0
- duh_cli-0.2.0/tests/unit/test_approvers.py +104 -0
- duh_cli-0.2.0/tests/unit/test_backoff.py +397 -0
- duh_cli-0.2.0/tests/unit/test_bash_security.py +299 -0
- duh_cli-0.2.0/tests/unit/test_brief_mode.py +174 -0
- duh_cli-0.2.0/tests/unit/test_cli.py +304 -0
- duh_cli-0.2.0/tests/unit/test_cli_full.py +503 -0
- duh_cli-0.2.0/tests/unit/test_compactor.py +321 -0
- duh_cli-0.2.0/tests/unit/test_config.py +355 -0
- duh_cli-0.2.0/tests/unit/test_context_dashboard.py +222 -0
- duh_cli-0.2.0/tests/unit/test_conversation_search.py +164 -0
- duh_cli-0.2.0/tests/unit/test_cost_control.py +322 -0
- duh_cli-0.2.0/tests/unit/test_cross_shell.py +320 -0
- duh_cli-0.2.0/tests/unit/test_db_tool.py +418 -0
- duh_cli-0.2.0/tests/unit/test_deps.py +64 -0
- duh_cli-0.2.0/tests/unit/test_docker_tool.py +383 -0
- duh_cli-0.2.0/tests/unit/test_edit_diff.py +196 -0
- duh_cli-0.2.0/tests/unit/test_engine.py +90 -0
- duh_cli-0.2.0/tests/unit/test_fallback_model.py +263 -0
- duh_cli-0.2.0/tests/unit/test_file_permissions.py +282 -0
- duh_cli-0.2.0/tests/unit/test_file_store.py +404 -0
- duh_cli-0.2.0/tests/unit/test_file_store_full.py +58 -0
- duh_cli-0.2.0/tests/unit/test_file_tracker.py +454 -0
- duh_cli-0.2.0/tests/unit/test_git_context.py +337 -0
- duh_cli-0.2.0/tests/unit/test_git_warnings.py +247 -0
- duh_cli-0.2.0/tests/unit/test_github_tool.py +393 -0
- duh_cli-0.2.0/tests/unit/test_health_check.py +279 -0
- duh_cli-0.2.0/tests/unit/test_history_dedup.py +346 -0
- duh_cli-0.2.0/tests/unit/test_hooks.py +530 -0
- duh_cli-0.2.0/tests/unit/test_http_tool.py +414 -0
- duh_cli-0.2.0/tests/unit/test_job_queue.py +294 -0
- duh_cli-0.2.0/tests/unit/test_loop.py +351 -0
- duh_cli-0.2.0/tests/unit/test_loop_exhaustive.py +542 -0
- duh_cli-0.2.0/tests/unit/test_loop_full.py +98 -0
- duh_cli-0.2.0/tests/unit/test_lsp_tool.py +370 -0
- duh_cli-0.2.0/tests/unit/test_mcp_executor.py +421 -0
- duh_cli-0.2.0/tests/unit/test_mcp_tool.py +214 -0
- duh_cli-0.2.0/tests/unit/test_memory.py +492 -0
- duh_cli-0.2.0/tests/unit/test_messages.py +128 -0
- duh_cli-0.2.0/tests/unit/test_messages_exhaustive.py +339 -0
- duh_cli-0.2.0/tests/unit/test_multi_edit.py +259 -0
- duh_cli-0.2.0/tests/unit/test_native_executor.py +178 -0
- duh_cli-0.2.0/tests/unit/test_ndjson.py +69 -0
- duh_cli-0.2.0/tests/unit/test_notebook_edit.py +470 -0
- duh_cli-0.2.0/tests/unit/test_ollama_adapter.py +200 -0
- duh_cli-0.2.0/tests/unit/test_ollama_adapter_full.py +356 -0
- duh_cli-0.2.0/tests/unit/test_openai_adapter.py +129 -0
- duh_cli-0.2.0/tests/unit/test_output_limits.py +233 -0
- duh_cli-0.2.0/tests/unit/test_packaging.py +70 -0
- duh_cli-0.2.0/tests/unit/test_persistent_memory.py +477 -0
- duh_cli-0.2.0/tests/unit/test_plan_mode.py +360 -0
- duh_cli-0.2.0/tests/unit/test_plugins.py +430 -0
- duh_cli-0.2.0/tests/unit/test_ports.py +130 -0
- duh_cli-0.2.0/tests/unit/test_ports_full.py +23 -0
- duh_cli-0.2.0/tests/unit/test_readline_history.py +189 -0
- duh_cli-0.2.0/tests/unit/test_registry_coverage.py +306 -0
- duh_cli-0.2.0/tests/unit/test_renderers.py +217 -0
- duh_cli-0.2.0/tests/unit/test_repl.py +129 -0
- duh_cli-0.2.0/tests/unit/test_repl_coverage.py +767 -0
- duh_cli-0.2.0/tests/unit/test_runner_coverage.py +847 -0
- duh_cli-0.2.0/tests/unit/test_sdk_runner.py +224 -0
- duh_cli-0.2.0/tests/unit/test_sdk_runner_coverage.py +577 -0
- duh_cli-0.2.0/tests/unit/test_session_autosave.py +328 -0
- duh_cli-0.2.0/tests/unit/test_skills.py +685 -0
- duh_cli-0.2.0/tests/unit/test_streaming_errors.py +553 -0
- duh_cli-0.2.0/tests/unit/test_structured_logging.py +294 -0
- duh_cli-0.2.0/tests/unit/test_tasks.py +343 -0
- duh_cli-0.2.0/tests/unit/test_templates.py +354 -0
- duh_cli-0.2.0/tests/unit/test_test_impact.py +314 -0
- duh_cli-0.2.0/tests/unit/test_tokens.py +519 -0
- duh_cli-0.2.0/tests/unit/test_tool.py +129 -0
- duh_cli-0.2.0/tests/unit/test_tool_gaps.py +512 -0
- duh_cli-0.2.0/tests/unit/test_tool_search.py +274 -0
- duh_cli-0.2.0/tests/unit/test_tool_timeouts.py +243 -0
- duh_cli-0.2.0/tests/unit/test_tools.py +510 -0
- duh_cli-0.2.0/tests/unit/test_undo.py +346 -0
- duh_cli-0.2.0/tests/unit/test_web_tools.py +477 -0
- duh_cli-0.2.0/tests/unit/test_worktree.py +342 -0
duh_cli-0.2.0/.coverage
ADDED
|
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
|
duh_cli-0.2.0/.gitignore
ADDED
|
@@ -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
|
+
[](https://github.com/nikhilvallishayee/duh/actions/workflows/ci.yml)
|
|
40
|
+
[]()
|
|
41
|
+
[]()
|
|
42
|
+
[]()
|
|
43
|
+
[](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
|
duh_cli-0.2.0/README.md
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
# D.U.H. — D.U.H. is a Universal Harness
|
|
2
|
+
|
|
3
|
+
[](https://github.com/nikhilvallishayee/duh/actions/workflows/ci.yml)
|
|
4
|
+
[]()
|
|
5
|
+
[]()
|
|
6
|
+
[]()
|
|
7
|
+
[](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,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
|