kunchi 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. kunchi-0.1.0/.github/workflows/publish.yml +33 -0
  2. kunchi-0.1.0/.gitignore +7 -0
  3. kunchi-0.1.0/.kunchi/config.yaml.example +3 -0
  4. kunchi-0.1.0/LICENSE +21 -0
  5. kunchi-0.1.0/PKG-INFO +168 -0
  6. kunchi-0.1.0/README.md +136 -0
  7. kunchi-0.1.0/docs/DESIGN.md +1265 -0
  8. kunchi-0.1.0/docs/MANUAL_TESTING.md +203 -0
  9. kunchi-0.1.0/docs/ROADMAP.md +241 -0
  10. kunchi-0.1.0/pyproject.toml +57 -0
  11. kunchi-0.1.0/src/kunchi/__init__.py +8 -0
  12. kunchi-0.1.0/src/kunchi/agents/__init__.py +4 -0
  13. kunchi-0.1.0/src/kunchi/agents/cli/__init__.py +0 -0
  14. kunchi-0.1.0/src/kunchi/agents/executor.py +155 -0
  15. kunchi-0.1.0/src/kunchi/agents/fake.py +98 -0
  16. kunchi-0.1.0/src/kunchi/agents/implementor_contract.py +3 -0
  17. kunchi-0.1.0/src/kunchi/agents/parsing.py +129 -0
  18. kunchi-0.1.0/src/kunchi/agents/planner_contract.py +21 -0
  19. kunchi-0.1.0/src/kunchi/agents/prompts.py +57 -0
  20. kunchi-0.1.0/src/kunchi/agents/registry.py +61 -0
  21. kunchi-0.1.0/src/kunchi/agents/validator_contract.py +6 -0
  22. kunchi-0.1.0/src/kunchi/auth/__init__.py +11 -0
  23. kunchi-0.1.0/src/kunchi/auth/models.py +24 -0
  24. kunchi-0.1.0/src/kunchi/auth/provider.py +15 -0
  25. kunchi-0.1.0/src/kunchi/auth/providers/__init__.py +3 -0
  26. kunchi-0.1.0/src/kunchi/auth/providers/memory.py +44 -0
  27. kunchi-0.1.0/src/kunchi/cli/__init__.py +5 -0
  28. kunchi-0.1.0/src/kunchi/cli/main.py +129 -0
  29. kunchi-0.1.0/src/kunchi/config/__init__.py +21 -0
  30. kunchi-0.1.0/src/kunchi/config/defaults.py +11 -0
  31. kunchi-0.1.0/src/kunchi/config/harness_config.py +76 -0
  32. kunchi-0.1.0/src/kunchi/config/resolver.py +51 -0
  33. kunchi-0.1.0/src/kunchi/events/__init__.py +3 -0
  34. kunchi-0.1.0/src/kunchi/events/bus.py +20 -0
  35. kunchi-0.1.0/src/kunchi/examples/__init__.py +0 -0
  36. kunchi-0.1.0/src/kunchi/examples/demo.py +47 -0
  37. kunchi-0.1.0/src/kunchi/examples/manual/README.md +38 -0
  38. kunchi-0.1.0/src/kunchi/examples/manual/__init__.py +1 -0
  39. kunchi-0.1.0/src/kunchi/examples/manual/_helpers.py +19 -0
  40. kunchi-0.1.0/src/kunchi/examples/manual/cli_agent_fake_binary.py +65 -0
  41. kunchi-0.1.0/src/kunchi/examples/manual/cli_runner.py +29 -0
  42. kunchi-0.1.0/src/kunchi/examples/manual/cursor_provider_argv.py +63 -0
  43. kunchi-0.1.0/src/kunchi/examples/manual/cursor_smoke.py +75 -0
  44. kunchi-0.1.0/src/kunchi/examples/manual/harness_fake.py +29 -0
  45. kunchi-0.1.0/src/kunchi/examples/manual/inspect_plan.py +32 -0
  46. kunchi-0.1.0/src/kunchi/examples/manual/list_plans.py +34 -0
  47. kunchi-0.1.0/src/kunchi/examples/manual/load_profile_file.py +44 -0
  48. kunchi-0.1.0/src/kunchi/examples/manual/mixed_config.py +43 -0
  49. kunchi-0.1.0/src/kunchi/examples/manual/shell_validator.py +38 -0
  50. kunchi-0.1.0/src/kunchi/examples/manual/trace.py +15 -0
  51. kunchi-0.1.0/src/kunchi/examples/manual/trace_harness.py +25 -0
  52. kunchi-0.1.0/src/kunchi/harness.py +193 -0
  53. kunchi-0.1.0/src/kunchi/hello.py +3 -0
  54. kunchi-0.1.0/src/kunchi/models/__init__.py +54 -0
  55. kunchi-0.1.0/src/kunchi/models/agent.py +42 -0
  56. kunchi-0.1.0/src/kunchi/models/artifact.py +8 -0
  57. kunchi-0.1.0/src/kunchi/models/context.py +23 -0
  58. kunchi-0.1.0/src/kunchi/models/events.py +159 -0
  59. kunchi-0.1.0/src/kunchi/models/output.py +52 -0
  60. kunchi-0.1.0/src/kunchi/models/plan.py +70 -0
  61. kunchi-0.1.0/src/kunchi/models/report.py +20 -0
  62. kunchi-0.1.0/src/kunchi/models/task.py +65 -0
  63. kunchi-0.1.0/src/kunchi/models/validation.py +19 -0
  64. kunchi-0.1.0/src/kunchi/plan/__init__.py +3 -0
  65. kunchi-0.1.0/src/kunchi/plan/engine.py +139 -0
  66. kunchi-0.1.0/src/kunchi/plan/parsing.py +191 -0
  67. kunchi-0.1.0/src/kunchi/plan/resume.py +28 -0
  68. kunchi-0.1.0/src/kunchi/profiles/__init__.py +7 -0
  69. kunchi-0.1.0/src/kunchi/profiles/base.py +35 -0
  70. kunchi-0.1.0/src/kunchi/profiles/cursor/__init__.py +3 -0
  71. kunchi-0.1.0/src/kunchi/profiles/cursor/profile.py +51 -0
  72. kunchi-0.1.0/src/kunchi/profiles/examples/cursor.yaml +33 -0
  73. kunchi-0.1.0/src/kunchi/profiles/examples/minimal.json +32 -0
  74. kunchi-0.1.0/src/kunchi/profiles/examples/minimal.yaml +20 -0
  75. kunchi-0.1.0/src/kunchi/profiles/fake/__init__.py +3 -0
  76. kunchi-0.1.0/src/kunchi/profiles/fake/profile.py +20 -0
  77. kunchi-0.1.0/src/kunchi/profiles/loader.py +51 -0
  78. kunchi-0.1.0/src/kunchi/profiles/registry.py +25 -0
  79. kunchi-0.1.0/src/kunchi/project/__init__.py +5 -0
  80. kunchi-0.1.0/src/kunchi/project/settings.py +178 -0
  81. kunchi-0.1.0/src/kunchi/providers/__init__.py +7 -0
  82. kunchi-0.1.0/src/kunchi/providers/agents/__init__.py +13 -0
  83. kunchi-0.1.0/src/kunchi/providers/agents/base.py +52 -0
  84. kunchi-0.1.0/src/kunchi/providers/agents/cli_agent.py +50 -0
  85. kunchi-0.1.0/src/kunchi/providers/agents/cursor/__init__.py +3 -0
  86. kunchi-0.1.0/src/kunchi/providers/agents/cursor/provider.py +188 -0
  87. kunchi-0.1.0/src/kunchi/providers/agents/registry.py +23 -0
  88. kunchi-0.1.0/src/kunchi/providers/agents/runner.py +102 -0
  89. kunchi-0.1.0/src/kunchi/providers/agents/shell/__init__.py +3 -0
  90. kunchi-0.1.0/src/kunchi/providers/agents/shell/agent.py +107 -0
  91. kunchi-0.1.0/src/kunchi/providers/vcs/__init__.py +4 -0
  92. kunchi-0.1.0/src/kunchi/providers/vcs/artifacts.py +15 -0
  93. kunchi-0.1.0/src/kunchi/providers/vcs/base.py +23 -0
  94. kunchi-0.1.0/src/kunchi/providers/vcs/git/__init__.py +3 -0
  95. kunchi-0.1.0/src/kunchi/providers/vcs/git/backend.py +94 -0
  96. kunchi-0.1.0/src/kunchi/providers/vcs/hg/__init__.py +3 -0
  97. kunchi-0.1.0/src/kunchi/providers/vcs/hg/backend.py +31 -0
  98. kunchi-0.1.0/src/kunchi/providers/vcs/registry.py +39 -0
  99. kunchi-0.1.0/src/kunchi/state/__init__.py +5 -0
  100. kunchi-0.1.0/src/kunchi/state/file.py +50 -0
  101. kunchi-0.1.0/src/kunchi/state/memory.py +22 -0
  102. kunchi-0.1.0/src/kunchi/state/store.py +13 -0
  103. kunchi-0.1.0/src/kunchi/task/__init__.py +3 -0
  104. kunchi-0.1.0/src/kunchi/task/engine.py +285 -0
  105. kunchi-0.1.0/src/kunchi/task/scheduler.py +20 -0
  106. kunchi-0.1.0/src/kunchi/tracing/__init__.py +31 -0
  107. kunchi-0.1.0/src/kunchi/tracing/format.py +330 -0
  108. kunchi-0.1.0/src/kunchi/tracing/monitor.py +190 -0
  109. kunchi-0.1.0/src/kunchi/tracing/preview.py +7 -0
  110. kunchi-0.1.0/src/kunchi/tracing/trace.py +59 -0
  111. kunchi-0.1.0/src/kunchi/validation/__init__.py +4 -0
  112. kunchi-0.1.0/src/kunchi/validation/feedback.py +44 -0
  113. kunchi-0.1.0/src/kunchi/validation/output.py +99 -0
  114. kunchi-0.1.0/tests/__init__.py +0 -0
  115. kunchi-0.1.0/tests/test_agent_trace_events.py +74 -0
  116. kunchi-0.1.0/tests/test_auth.py +61 -0
  117. kunchi-0.1.0/tests/test_cli_agent.py +111 -0
  118. kunchi-0.1.0/tests/test_cli_runner.py +151 -0
  119. kunchi-0.1.0/tests/test_cursor_harness_config.py +29 -0
  120. kunchi-0.1.0/tests/test_cursor_provider.py +112 -0
  121. kunchi-0.1.0/tests/test_feedback.py +129 -0
  122. kunchi-0.1.0/tests/test_file_plan_store.py +50 -0
  123. kunchi-0.1.0/tests/test_harness.py +38 -0
  124. kunchi-0.1.0/tests/test_hello.py +5 -0
  125. kunchi-0.1.0/tests/test_monitor_format.py +183 -0
  126. kunchi-0.1.0/tests/test_output_contract.py +13 -0
  127. kunchi-0.1.0/tests/test_output_validation.py +51 -0
  128. kunchi-0.1.0/tests/test_parsing.py +17 -0
  129. kunchi-0.1.0/tests/test_plan_engine.py +28 -0
  130. kunchi-0.1.0/tests/test_plan_listing.py +52 -0
  131. kunchi-0.1.0/tests/test_plan_parsing.py +173 -0
  132. kunchi-0.1.0/tests/test_plan_resume.py +87 -0
  133. kunchi-0.1.0/tests/test_profile_loader.py +50 -0
  134. kunchi-0.1.0/tests/test_profiles.py +57 -0
  135. kunchi-0.1.0/tests/test_project_settings.py +84 -0
  136. kunchi-0.1.0/tests/test_trace_format.py +150 -0
@@ -0,0 +1,33 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+ workflow_dispatch:
7
+
8
+ permissions:
9
+ id-token: write
10
+
11
+ jobs:
12
+ publish:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+
17
+ - uses: actions/setup-python@v5
18
+ with:
19
+ python-version: "3.12"
20
+
21
+ - name: Install build tools
22
+ run: python -m pip install --upgrade hatch
23
+
24
+ - name: Run tests
25
+ run: |
26
+ pip install -e ".[dev]"
27
+ pytest
28
+
29
+ - name: Build package
30
+ run: hatch build
31
+
32
+ - name: Publish to PyPI
33
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,7 @@
1
+ .venv/
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ .pytest_cache/
6
+ dist/
7
+ build/
@@ -0,0 +1,3 @@
1
+ # Optional Kunchi project overrides.
2
+ # profile: profile.yaml
3
+ # plan_store: plans
kunchi-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Hsiwei Chang
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
kunchi-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,168 @@
1
+ Metadata-Version: 2.4
2
+ Name: kunchi
3
+ Version: 0.1.0
4
+ Summary: A simple coding harness with planner-implementor-validator orchestration
5
+ Project-URL: Homepage, https://github.com/Hudsone/kunchi
6
+ Project-URL: Repository, https://github.com/Hudsone/kunchi
7
+ Project-URL: Issues, https://github.com/Hudsone/kunchi/issues
8
+ Project-URL: Documentation, https://github.com/Hudsone/kunchi/blob/main/docs/ROADMAP.md
9
+ Author-email: Hsiwei Chang <hudsone@gmail.com>
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: coding-agent,cursor,harness,orchestration
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Environment :: Console
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Software Development :: Build Tools
22
+ Classifier: Typing :: Typed
23
+ Requires-Python: >=3.11
24
+ Requires-Dist: pydantic>=2.0
25
+ Provides-Extra: dev
26
+ Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
27
+ Requires-Dist: pytest>=8.0; extra == 'dev'
28
+ Requires-Dist: pyyaml>=6.0; extra == 'dev'
29
+ Provides-Extra: yaml
30
+ Requires-Dist: pyyaml>=6.0; extra == 'yaml'
31
+ Description-Content-Type: text/markdown
32
+
33
+ # kunchi
34
+ A Simple Coding Harness (Python)
35
+
36
+ Multi-agent orchestration: planner → implementor → sequential validators, with output contracts and retry loops.
37
+
38
+ ## Quick start
39
+
40
+ ```bash
41
+ pip install kunchi
42
+ # or for development:
43
+ pip install -e ".[dev]"
44
+ pytest
45
+ python3 -m kunchi.examples.demo "Build a demo feature"
46
+ ```
47
+
48
+ The demo uses **fake agents** (no external CLIs) to exercise the full harness flow.
49
+
50
+ ### CLI (recommended for real repos)
51
+
52
+ ```bash
53
+ pip install -e ".[dev]"
54
+ cd /path/to/your/repo
55
+ kunchi init --template cursor # writes .kunchi/profile.yaml
56
+ export CURSOR_API_KEY=... # for cursor template
57
+ kunchi run "Your goal"
58
+ kunchi run "Your goal" --monitor # compact progress lines on stderr
59
+ kunchi run "Your goal" --trace # verbose debug trace on stdout
60
+ kunchi plans
61
+ kunchi resume PLAN_ID
62
+ ```
63
+
64
+ Use `kunchi init --template fake` to try the flow without Cursor. See [docs/ROADMAP.md](docs/ROADMAP.md#good-enough-to-start).
65
+
66
+ See [docs/MANUAL_TESTING.md](docs/MANUAL_TESTING.md) for manual smoke tests. Development progress and a **good enough to start** checklist are in [docs/ROADMAP.md](docs/ROADMAP.md#good-enough-to-start). Runnable scripts are in `src/kunchi/examples/manual/`:
67
+
68
+ ```bash
69
+ python3 -m kunchi.examples.manual.harness_fake
70
+ python3 -m kunchi.examples.manual.cli_runner
71
+ python3 -m kunchi.examples.manual.cli_agent_fake_binary
72
+ ```
73
+
74
+ ## hello()
75
+
76
+ `kunchi` exports a small public `hello()` helper (see `src/kunchi/hello.py`). It returns the string `"hello"`.
77
+
78
+ ```python
79
+ from kunchi import hello
80
+
81
+ hello() # "hello"
82
+ ```
83
+
84
+ ## Agent backends
85
+
86
+ **Fake agents** (default) — no external dependencies:
87
+
88
+ ```python
89
+ from kunchi import Harness, default_harness_config
90
+
91
+ harness = Harness(default_harness_config())
92
+ ```
93
+
94
+ **Cursor CLI** — requires the `agent` binary on PATH; tasks require `summary` + `git_commit` and run `ruff` / `pytest` shell validators before Cursor review:
95
+
96
+ ```python
97
+ from kunchi.harness import Harness, default_cursor_harness_config
98
+
99
+ harness = Harness(default_cursor_harness_config(workspace_path="/path/to/repo"))
100
+ ```
101
+
102
+ Profiles bundle fixed output contracts and validators; register custom ones or load from a dict:
103
+
104
+ ```python
105
+ from kunchi.harness import harness_config_from_profile
106
+ from kunchi.profiles import ProfileRegistry, load_profile
107
+
108
+ harness = Harness(harness_config_from_profile("cursor", "/path/to/repo"))
109
+
110
+ # Dynamic / file-based (same shape a planner could emit later):
111
+ from pathlib import Path
112
+
113
+ from kunchi.harness import harness_config_from_profile_file
114
+ from kunchi.profiles import ProfileRegistry, load_profile, load_profile_file
115
+
116
+ harness = Harness(harness_config_from_profile("cursor", "/path/to/repo"))
117
+
118
+ profile = load_profile_file(Path("my-profile.json"))
119
+ registry = ProfileRegistry.default()
120
+ registry.register(profile)
121
+ harness = Harness(harness_config_from_profile(profile.name, ".", registry=registry))
122
+
123
+ # Or in one step:
124
+ harness = Harness(harness_config_from_profile_file("my-profile.yaml", "/path/to/repo"))
125
+ ```
126
+
127
+ Or configure agents explicitly:
128
+
129
+ ```python
130
+ from kunchi import Harness, HarnessConfig
131
+ from kunchi.models.agent import AgentRole, AgentSpec
132
+ from kunchi.models.context import WorkspaceConfig
133
+
134
+ config = HarnessConfig(
135
+ planner=AgentSpec(id="planner", role=AgentRole.PLANNER, config={"cli": "cursor"}),
136
+ workspace=WorkspaceConfig(path="."),
137
+ default_validators=[
138
+ AgentSpec(id="lint", role=AgentRole.VALIDATOR, config={"cli": "shell", "command": "ruff check ."}),
139
+ ],
140
+ )
141
+ harness = Harness(config)
142
+ ```
143
+
144
+ ## Extending integrations
145
+
146
+ External system adapters live under `src/kunchi/providers/`:
147
+
148
+ - **Agent clients** (`providers/agents/`) — implement `AgentClient` and register in `AgentClientRegistry` (Cursor is built in)
149
+ - **VCS backends** (`providers/vcs/`) — implement `VCSBackend` and register in `VCSRegistry` (git is built in; hg is stubbed)
150
+
151
+ See [docs/DESIGN.md](docs/DESIGN.md) sections 9 and 17 for details.
152
+
153
+ Persist plan state to disk (resume / inspect after a run):
154
+
155
+ ```python
156
+ from kunchi import Harness, default_harness_config
157
+ from kunchi.state import FilePlanStore
158
+
159
+ harness = Harness(default_harness_config(), plan_store=FilePlanStore(".kunchi/plans"))
160
+ report = await harness.run("Build feature")
161
+
162
+ # After an interrupt or partial run, continue from persisted state:
163
+ report = await harness.resume(report.plan_id)
164
+
165
+ # List saved plans:
166
+ summaries = await harness.list_plans()
167
+ ```
168
+
kunchi-0.1.0/README.md ADDED
@@ -0,0 +1,136 @@
1
+ # kunchi
2
+ A Simple Coding Harness (Python)
3
+
4
+ Multi-agent orchestration: planner → implementor → sequential validators, with output contracts and retry loops.
5
+
6
+ ## Quick start
7
+
8
+ ```bash
9
+ pip install kunchi
10
+ # or for development:
11
+ pip install -e ".[dev]"
12
+ pytest
13
+ python3 -m kunchi.examples.demo "Build a demo feature"
14
+ ```
15
+
16
+ The demo uses **fake agents** (no external CLIs) to exercise the full harness flow.
17
+
18
+ ### CLI (recommended for real repos)
19
+
20
+ ```bash
21
+ pip install -e ".[dev]"
22
+ cd /path/to/your/repo
23
+ kunchi init --template cursor # writes .kunchi/profile.yaml
24
+ export CURSOR_API_KEY=... # for cursor template
25
+ kunchi run "Your goal"
26
+ kunchi run "Your goal" --monitor # compact progress lines on stderr
27
+ kunchi run "Your goal" --trace # verbose debug trace on stdout
28
+ kunchi plans
29
+ kunchi resume PLAN_ID
30
+ ```
31
+
32
+ Use `kunchi init --template fake` to try the flow without Cursor. See [docs/ROADMAP.md](docs/ROADMAP.md#good-enough-to-start).
33
+
34
+ See [docs/MANUAL_TESTING.md](docs/MANUAL_TESTING.md) for manual smoke tests. Development progress and a **good enough to start** checklist are in [docs/ROADMAP.md](docs/ROADMAP.md#good-enough-to-start). Runnable scripts are in `src/kunchi/examples/manual/`:
35
+
36
+ ```bash
37
+ python3 -m kunchi.examples.manual.harness_fake
38
+ python3 -m kunchi.examples.manual.cli_runner
39
+ python3 -m kunchi.examples.manual.cli_agent_fake_binary
40
+ ```
41
+
42
+ ## hello()
43
+
44
+ `kunchi` exports a small public `hello()` helper (see `src/kunchi/hello.py`). It returns the string `"hello"`.
45
+
46
+ ```python
47
+ from kunchi import hello
48
+
49
+ hello() # "hello"
50
+ ```
51
+
52
+ ## Agent backends
53
+
54
+ **Fake agents** (default) — no external dependencies:
55
+
56
+ ```python
57
+ from kunchi import Harness, default_harness_config
58
+
59
+ harness = Harness(default_harness_config())
60
+ ```
61
+
62
+ **Cursor CLI** — requires the `agent` binary on PATH; tasks require `summary` + `git_commit` and run `ruff` / `pytest` shell validators before Cursor review:
63
+
64
+ ```python
65
+ from kunchi.harness import Harness, default_cursor_harness_config
66
+
67
+ harness = Harness(default_cursor_harness_config(workspace_path="/path/to/repo"))
68
+ ```
69
+
70
+ Profiles bundle fixed output contracts and validators; register custom ones or load from a dict:
71
+
72
+ ```python
73
+ from kunchi.harness import harness_config_from_profile
74
+ from kunchi.profiles import ProfileRegistry, load_profile
75
+
76
+ harness = Harness(harness_config_from_profile("cursor", "/path/to/repo"))
77
+
78
+ # Dynamic / file-based (same shape a planner could emit later):
79
+ from pathlib import Path
80
+
81
+ from kunchi.harness import harness_config_from_profile_file
82
+ from kunchi.profiles import ProfileRegistry, load_profile, load_profile_file
83
+
84
+ harness = Harness(harness_config_from_profile("cursor", "/path/to/repo"))
85
+
86
+ profile = load_profile_file(Path("my-profile.json"))
87
+ registry = ProfileRegistry.default()
88
+ registry.register(profile)
89
+ harness = Harness(harness_config_from_profile(profile.name, ".", registry=registry))
90
+
91
+ # Or in one step:
92
+ harness = Harness(harness_config_from_profile_file("my-profile.yaml", "/path/to/repo"))
93
+ ```
94
+
95
+ Or configure agents explicitly:
96
+
97
+ ```python
98
+ from kunchi import Harness, HarnessConfig
99
+ from kunchi.models.agent import AgentRole, AgentSpec
100
+ from kunchi.models.context import WorkspaceConfig
101
+
102
+ config = HarnessConfig(
103
+ planner=AgentSpec(id="planner", role=AgentRole.PLANNER, config={"cli": "cursor"}),
104
+ workspace=WorkspaceConfig(path="."),
105
+ default_validators=[
106
+ AgentSpec(id="lint", role=AgentRole.VALIDATOR, config={"cli": "shell", "command": "ruff check ."}),
107
+ ],
108
+ )
109
+ harness = Harness(config)
110
+ ```
111
+
112
+ ## Extending integrations
113
+
114
+ External system adapters live under `src/kunchi/providers/`:
115
+
116
+ - **Agent clients** (`providers/agents/`) — implement `AgentClient` and register in `AgentClientRegistry` (Cursor is built in)
117
+ - **VCS backends** (`providers/vcs/`) — implement `VCSBackend` and register in `VCSRegistry` (git is built in; hg is stubbed)
118
+
119
+ See [docs/DESIGN.md](docs/DESIGN.md) sections 9 and 17 for details.
120
+
121
+ Persist plan state to disk (resume / inspect after a run):
122
+
123
+ ```python
124
+ from kunchi import Harness, default_harness_config
125
+ from kunchi.state import FilePlanStore
126
+
127
+ harness = Harness(default_harness_config(), plan_store=FilePlanStore(".kunchi/plans"))
128
+ report = await harness.run("Build feature")
129
+
130
+ # After an interrupt or partial run, continue from persisted state:
131
+ report = await harness.resume(report.plan_id)
132
+
133
+ # List saved plans:
134
+ summaries = await harness.list_plans()
135
+ ```
136
+