harness-flow 4.1.1__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 (101) hide show
  1. harness_flow-4.1.1/.github/workflows/ci.yml +81 -0
  2. harness_flow-4.1.1/.github/workflows/release.yml +181 -0
  3. harness_flow-4.1.1/.gitignore +31 -0
  4. harness_flow-4.1.1/ARCHITECTURE.md +221 -0
  5. harness_flow-4.1.1/CHANGELOG.md +40 -0
  6. harness_flow-4.1.1/LICENSE +21 -0
  7. harness_flow-4.1.1/PKG-INFO +294 -0
  8. harness_flow-4.1.1/README.md +256 -0
  9. harness_flow-4.1.1/README.zh-CN.md +198 -0
  10. harness_flow-4.1.1/docs/historical.md +64 -0
  11. harness_flow-4.1.1/install.sh +83 -0
  12. harness_flow-4.1.1/pyproject.toml +65 -0
  13. harness_flow-4.1.1/scripts/release.sh +141 -0
  14. harness_flow-4.1.1/src/harness/__init__.py +8 -0
  15. harness_flow-4.1.1/src/harness/__main__.py +5 -0
  16. harness_flow-4.1.1/src/harness/cli.py +91 -0
  17. harness_flow-4.1.1/src/harness/commands/__init__.py +0 -0
  18. harness_flow-4.1.1/src/harness/commands/init.py +273 -0
  19. harness_flow-4.1.1/src/harness/commands/install.py +44 -0
  20. harness_flow-4.1.1/src/harness/commands/status.py +177 -0
  21. harness_flow-4.1.1/src/harness/commands/update.py +147 -0
  22. harness_flow-4.1.1/src/harness/core/__init__.py +0 -0
  23. harness_flow-4.1.1/src/harness/core/config.py +184 -0
  24. harness_flow-4.1.1/src/harness/core/context.py +57 -0
  25. harness_flow-4.1.1/src/harness/core/events.py +107 -0
  26. harness_flow-4.1.1/src/harness/core/progress.py +162 -0
  27. harness_flow-4.1.1/src/harness/core/registry.py +334 -0
  28. harness_flow-4.1.1/src/harness/core/roles.py +26 -0
  29. harness_flow-4.1.1/src/harness/core/scanner.py +173 -0
  30. harness_flow-4.1.1/src/harness/core/state.py +104 -0
  31. harness_flow-4.1.1/src/harness/core/tracker.py +129 -0
  32. harness_flow-4.1.1/src/harness/core/ui.py +255 -0
  33. harness_flow-4.1.1/src/harness/i18n/__init__.py +47 -0
  34. harness_flow-4.1.1/src/harness/i18n/en.py +84 -0
  35. harness_flow-4.1.1/src/harness/i18n/zh.py +84 -0
  36. harness_flow-4.1.1/src/harness/integrations/__init__.py +0 -0
  37. harness_flow-4.1.1/src/harness/integrations/git_ops.py +136 -0
  38. harness_flow-4.1.1/src/harness/integrations/memverse.py +92 -0
  39. harness_flow-4.1.1/src/harness/native/__init__.py +1 -0
  40. harness_flow-4.1.1/src/harness/native/skill_gen.py +273 -0
  41. harness_flow-4.1.1/src/harness/templates/config.toml.j2 +30 -0
  42. harness_flow-4.1.1/src/harness/templates/native/agent-architect.md.j2 +90 -0
  43. harness_flow-4.1.1/src/harness/templates/native/agent-engineer.md.j2 +95 -0
  44. harness_flow-4.1.1/src/harness/templates/native/agent-product-owner.md.j2 +90 -0
  45. harness_flow-4.1.1/src/harness/templates/native/agent-project-manager.md.j2 +90 -0
  46. harness_flow-4.1.1/src/harness/templates/native/agent-qa.md.j2 +95 -0
  47. harness_flow-4.1.1/src/harness/templates/native/review-checklist.md +178 -0
  48. harness_flow-4.1.1/src/harness/templates/native/rule-fix-first.mdc.j2 +66 -0
  49. harness_flow-4.1.1/src/harness/templates/native/rule-safety-guardrails.mdc.j2 +73 -0
  50. harness_flow-4.1.1/src/harness/templates/native/rule-trust-boundary.mdc.j2 +14 -0
  51. harness_flow-4.1.1/src/harness/templates/native/rule-workflow.mdc.j2 +28 -0
  52. harness_flow-4.1.1/src/harness/templates/native/sections/_bypass-immunity.md.j2 +12 -0
  53. harness_flow-4.1.1/src/harness/templates/native/sections/_code-review.md.j2 +103 -0
  54. harness_flow-4.1.1/src/harness/templates/native/sections/_error-recovery.md.j2 +17 -0
  55. harness_flow-4.1.1/src/harness/templates/native/sections/_hook-points.md.j2 +14 -0
  56. harness_flow-4.1.1/src/harness/templates/native/sections/_plan-content.md.j2 +23 -0
  57. harness_flow-4.1.1/src/harness/templates/native/sections/_plan-core.md.j2 +78 -0
  58. harness_flow-4.1.1/src/harness/templates/native/sections/_plan-review.md.j2 +72 -0
  59. harness_flow-4.1.1/src/harness/templates/native/sections/_review-gate.md.j2 +60 -0
  60. harness_flow-4.1.1/src/harness/templates/native/sections/_trust-boundary.md.j2 +7 -0
  61. harness_flow-4.1.1/src/harness/templates/native/sections/_vision-content.md.j2 +9 -0
  62. harness_flow-4.1.1/src/harness/templates/native/sections/_vision-core.md.j2 +10 -0
  63. harness_flow-4.1.1/src/harness/templates/native/sections/_workspace-preflight.md.j2 +88 -0
  64. harness_flow-4.1.1/src/harness/templates/native/skill-brainstorm.md.j2 +77 -0
  65. harness_flow-4.1.1/src/harness/templates/native/skill-build.md.j2 +181 -0
  66. harness_flow-4.1.1/src/harness/templates/native/skill-doc-release.md.j2 +145 -0
  67. harness_flow-4.1.1/src/harness/templates/native/skill-eval.md.j2 +79 -0
  68. harness_flow-4.1.1/src/harness/templates/native/skill-investigate.md.j2 +184 -0
  69. harness_flow-4.1.1/src/harness/templates/native/skill-learn.md.j2 +176 -0
  70. harness_flow-4.1.1/src/harness/templates/native/skill-plan.md.j2 +52 -0
  71. harness_flow-4.1.1/src/harness/templates/native/skill-retro.md.j2 +280 -0
  72. harness_flow-4.1.1/src/harness/templates/native/skill-ship.md.j2 +506 -0
  73. harness_flow-4.1.1/src/harness/templates/native/skill-vision.md.j2 +64 -0
  74. harness_flow-4.1.1/src/harness/templates/native/specialists/performance.md +63 -0
  75. harness_flow-4.1.1/src/harness/templates/native/specialists/red-team.md +61 -0
  76. harness_flow-4.1.1/src/harness/templates/native/specialists/security.md +65 -0
  77. harness_flow-4.1.1/src/harness/templates/native/specialists/testing.md +58 -0
  78. harness_flow-4.1.1/src/harness/templates/vision.md.j2 +20 -0
  79. harness_flow-4.1.1/src/harness/templates/vision.zh.md.j2 +20 -0
  80. harness_flow-4.1.1/src/harness/utils/__init__.py +1 -0
  81. harness_flow-4.1.1/tests/__init__.py +0 -0
  82. harness_flow-4.1.1/tests/fixtures/codex-output-sample.txt +9 -0
  83. harness_flow-4.1.1/tests/fixtures/cursor-stream-json-sample.jsonl +10 -0
  84. harness_flow-4.1.1/tests/test_cli.py +23 -0
  85. harness_flow-4.1.1/tests/test_config.py +92 -0
  86. harness_flow-4.1.1/tests/test_context.py +53 -0
  87. harness_flow-4.1.1/tests/test_env_config.py +61 -0
  88. harness_flow-4.1.1/tests/test_events.py +47 -0
  89. harness_flow-4.1.1/tests/test_gate_thresholds.py +182 -0
  90. harness_flow-4.1.1/tests/test_git_ops.py +165 -0
  91. harness_flow-4.1.1/tests/test_init.py +215 -0
  92. harness_flow-4.1.1/tests/test_install.py +47 -0
  93. harness_flow-4.1.1/tests/test_progress.py +203 -0
  94. harness_flow-4.1.1/tests/test_registry.py +238 -0
  95. harness_flow-4.1.1/tests/test_roles_extended.py +26 -0
  96. harness_flow-4.1.1/tests/test_scanner.py +145 -0
  97. harness_flow-4.1.1/tests/test_skill_gen_extended.py +891 -0
  98. harness_flow-4.1.1/tests/test_state.py +287 -0
  99. harness_flow-4.1.1/tests/test_status.py +194 -0
  100. harness_flow-4.1.1/tests/test_ui.py +156 -0
  101. harness_flow-4.1.1/tests/test_update.py +166 -0
@@ -0,0 +1,81 @@
1
+ name: CI
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [main]
6
+ workflow_call:
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ test:
13
+ runs-on: ubuntu-latest
14
+ strategy:
15
+ fail-fast: false
16
+ matrix:
17
+ python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
18
+
19
+ steps:
20
+ - uses: actions/checkout@v5
21
+
22
+ - name: Set up Python ${{ matrix.python-version }}
23
+ uses: actions/setup-python@v6
24
+ with:
25
+ python-version: ${{ matrix.python-version }}
26
+
27
+ - name: Configure git for tests
28
+ run: |
29
+ git config --global user.name "CI"
30
+ git config --global user.email "ci@test"
31
+
32
+ - name: Install dependencies
33
+ run: |
34
+ python -m pip install --upgrade pip
35
+ pip install -e ".[dev]"
36
+
37
+ - name: Lint with ruff
38
+ run: |
39
+ ruff check src/ tests/
40
+
41
+ - name: Run tests
42
+ run: |
43
+ python -m pytest tests/ -v --tb=short
44
+
45
+ build:
46
+ runs-on: ubuntu-latest
47
+ needs: test
48
+ steps:
49
+ - uses: actions/checkout@v5
50
+
51
+ - name: Set up Python
52
+ uses: actions/setup-python@v6
53
+ with:
54
+ python-version: "3.12"
55
+
56
+ - name: Install build tools
57
+ run: pip install build
58
+
59
+ - name: Build wheel and sdist
60
+ run: python -m build
61
+
62
+ - name: Verify wheel contents
63
+ run: |
64
+ python -c "
65
+ import zipfile, sys
66
+ whl = next(p for p in __import__('pathlib').Path('dist').iterdir() if p.suffix == '.whl')
67
+ with zipfile.ZipFile(whl) as z:
68
+ names = z.namelist()
69
+ templates = [n for n in names if 'templates/' in n]
70
+ py_files = [n for n in names if n.endswith('.py')]
71
+ print(f'Templates: {len(templates)}, Python: {len(py_files)}, Total: {len(names)}')
72
+ assert len(templates) >= 20, f'Expected >=20 template files, got {len(templates)}'
73
+ assert len(py_files) >= 15, f'Expected >=15 Python files, got {len(py_files)}'
74
+ print('Wheel contents verified.')
75
+ "
76
+
77
+ - name: Upload wheel artifact
78
+ uses: actions/upload-artifact@v5
79
+ with:
80
+ name: dist
81
+ path: dist/
@@ -0,0 +1,181 @@
1
+ name: CD — Release to PyPI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ workflow_dispatch:
7
+ inputs:
8
+ publish_only:
9
+ description: 'Publish current version without bumping (for retry after failed publish)'
10
+ required: false
11
+ type: boolean
12
+ default: false
13
+
14
+ concurrency:
15
+ group: release
16
+ cancel-in-progress: false
17
+
18
+ permissions:
19
+ contents: write
20
+ id-token: write
21
+
22
+ jobs:
23
+ cd:
24
+ runs-on: ubuntu-latest
25
+ environment:
26
+ name: pypi
27
+ url: https://pypi.org/p/harness-flow
28
+ steps:
29
+ - uses: actions/checkout@v5
30
+ with:
31
+ fetch-depth: 0
32
+ fetch-tags: true
33
+
34
+ - name: Detect release intent from merged PR
35
+ id: intent
36
+ env:
37
+ GH_TOKEN: ${{ github.token }}
38
+ run: |
39
+ if [ "${{ inputs.publish_only }}" = "true" ]; then
40
+ echo "skip=false" >> "$GITHUB_OUTPUT"
41
+ echo "publish_only=true" >> "$GITHUB_OUTPUT"
42
+ echo "Manual publish-only mode — skipping bump"
43
+ exit 0
44
+ fi
45
+
46
+ COMMIT_MSG=$(git log -1 --format='%B')
47
+
48
+ if echo "$COMMIT_MSG" | grep -qi '\[skip release\]'; then
49
+ echo "skip=true" >> "$GITHUB_OUTPUT"
50
+ echo "Commit message contains [skip release] — skipping"
51
+ exit 0
52
+ fi
53
+
54
+ PR_NUMBER=$(gh api "repos/${{ github.repository }}/commits/${{ github.sha }}/pulls" -q '.[0].number' 2>/dev/null || echo "")
55
+
56
+ BUMP_LEVEL="patch"
57
+ if [ -n "$PR_NUMBER" ]; then
58
+ LABELS=$(gh pr view "$PR_NUMBER" --json labels -q '.labels[].name' 2>/dev/null || echo "")
59
+ if echo "$LABELS" | grep -q 'no-release'; then
60
+ echo "skip=true" >> "$GITHUB_OUTPUT"
61
+ echo "PR #$PR_NUMBER has no-release label — skipping"
62
+ exit 0
63
+ fi
64
+ if echo "$LABELS" | grep -q 'release:major'; then
65
+ BUMP_LEVEL="major"
66
+ elif echo "$LABELS" | grep -q 'release:minor'; then
67
+ BUMP_LEVEL="minor"
68
+ fi
69
+ fi
70
+
71
+ echo "skip=false" >> "$GITHUB_OUTPUT"
72
+ echo "publish_only=false" >> "$GITHUB_OUTPUT"
73
+ echo "bump_level=$BUMP_LEVEL" >> "$GITHUB_OUTPUT"
74
+ echo "Release intent: bump=$BUMP_LEVEL (PR #${PR_NUMBER:-none})"
75
+
76
+ - name: Set up Python
77
+ if: steps.intent.outputs.skip != 'true'
78
+ uses: actions/setup-python@v6
79
+ with:
80
+ python-version: "3.12"
81
+
82
+ - name: Configure git identity
83
+ if: steps.intent.outputs.skip != 'true'
84
+ run: |
85
+ git config user.name "github-actions[bot]"
86
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
87
+
88
+ - name: Bump version
89
+ if: steps.intent.outputs.skip != 'true' && steps.intent.outputs.publish_only != 'true'
90
+ id: bump
91
+ run: |
92
+ git pull --rebase origin main
93
+ chmod +x scripts/release.sh
94
+ ./scripts/release.sh bump ${{ steps.intent.outputs.bump_level }}
95
+ VERSION=$(python3 -c "
96
+ import re
97
+ with open('pyproject.toml') as f:
98
+ m = re.search(r'version\s*=\s*\"([^\"]+)\"', f.read())
99
+ print(m.group(1))
100
+ ")
101
+ echo "version=$VERSION" >> "$GITHUB_OUTPUT"
102
+ echo "tag=v$VERSION" >> "$GITHUB_OUTPUT"
103
+
104
+ - name: Read current version (publish-only mode)
105
+ if: steps.intent.outputs.publish_only == 'true'
106
+ id: current
107
+ run: |
108
+ VERSION=$(python3 -c "
109
+ import re
110
+ with open('pyproject.toml') as f:
111
+ m = re.search(r'version\s*=\s*\"([^\"]+)\"', f.read())
112
+ print(m.group(1))
113
+ ")
114
+ echo "version=$VERSION" >> "$GITHUB_OUTPUT"
115
+ echo "tag=v$VERSION" >> "$GITHUB_OUTPUT"
116
+ echo "Publish-only: version=$VERSION"
117
+
118
+ - name: Resolve version outputs
119
+ if: steps.intent.outputs.skip != 'true'
120
+ id: ver
121
+ run: |
122
+ if [ "${{ steps.intent.outputs.publish_only }}" = "true" ]; then
123
+ echo "version=${{ steps.current.outputs.version }}" >> "$GITHUB_OUTPUT"
124
+ echo "tag=${{ steps.current.outputs.tag }}" >> "$GITHUB_OUTPUT"
125
+ else
126
+ echo "version=${{ steps.bump.outputs.version }}" >> "$GITHUB_OUTPUT"
127
+ echo "tag=${{ steps.bump.outputs.tag }}" >> "$GITHUB_OUTPUT"
128
+ fi
129
+
130
+ - name: Check if already released
131
+ if: steps.intent.outputs.skip != 'true'
132
+ id: check
133
+ env:
134
+ GH_TOKEN: ${{ github.token }}
135
+ run: |
136
+ TAG="${{ steps.ver.outputs.tag }}"
137
+ if gh release view "$TAG" --json tagName &>/dev/null; then
138
+ echo "skip=true" >> "$GITHUB_OUTPUT"
139
+ echo "Release $TAG already exists — skipping"
140
+ else
141
+ echo "skip=false" >> "$GITHUB_OUTPUT"
142
+ echo "Will release $TAG"
143
+ fi
144
+
145
+ - name: Commit version bump
146
+ if: steps.intent.outputs.skip != 'true' && steps.check.outputs.skip != 'true' && steps.intent.outputs.publish_only != 'true'
147
+ run: |
148
+ git add pyproject.toml
149
+ git commit -m "chore: bump version to ${{ steps.ver.outputs.version }}"
150
+ git push origin main
151
+
152
+ - name: Create and push tag
153
+ if: steps.intent.outputs.skip != 'true' && steps.check.outputs.skip != 'true' && steps.intent.outputs.publish_only != 'true'
154
+ run: |
155
+ TAG="${{ steps.ver.outputs.tag }}"
156
+ if git rev-parse "$TAG" &>/dev/null; then
157
+ echo "Tag $TAG already exists — skipping"
158
+ else
159
+ git tag "$TAG"
160
+ git push origin "$TAG"
161
+ fi
162
+
163
+ - name: Install build tools
164
+ if: steps.intent.outputs.skip != 'true' && steps.check.outputs.skip != 'true'
165
+ run: pip install build
166
+
167
+ - name: Build package
168
+ if: steps.intent.outputs.skip != 'true' && steps.check.outputs.skip != 'true'
169
+ run: python -m build
170
+
171
+ - name: Publish to PyPI
172
+ if: steps.intent.outputs.skip != 'true' && steps.check.outputs.skip != 'true'
173
+ uses: pypa/gh-action-pypi-publish@release/v1
174
+
175
+ - name: Create GitHub Release
176
+ if: steps.intent.outputs.skip != 'true' && steps.check.outputs.skip != 'true'
177
+ uses: softprops/action-gh-release@v2
178
+ with:
179
+ tag_name: ${{ steps.ver.outputs.tag }}
180
+ generate_release_notes: true
181
+ files: dist/*
@@ -0,0 +1,31 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *$py.class
4
+ *.egg-info/
5
+ dist/
6
+ build/
7
+ .eggs/
8
+ *.egg
9
+ .venv/
10
+ venv/
11
+ env/
12
+ .env
13
+ *.so
14
+ .mypy_cache/
15
+ .ruff_cache/
16
+ .pytest_cache/
17
+ htmlcov/
18
+ .coverage
19
+ *.log
20
+ .DS_Store
21
+ .idea/
22
+ .cursor/
23
+
24
+ # harness — .agents/ 是本地运行时目录,不纳入版本控制
25
+ # 包含 state.json、.stop、tasks/、archive/ 等运行时产物
26
+ # config.toml 和 vision.md 如需团队共享,可通过 git add -f 手动添加
27
+ .agents/
28
+
29
+ # harness — do not track runtime state
30
+ .agents/state.json
31
+ .agents/.stop
@@ -0,0 +1,221 @@
1
+ # Architecture (v4.0.0 — native-only)
2
+
3
+ This document explains **why** harness-flow is structured the way it is after the native-only refactor. Execution lives in **Cursor**: the Python package bootstraps configuration, generates IDE artifacts, and maintains local state—not an external orchestration loop.
4
+
5
+ For module-level behavior, read the code and docstrings. For day-to-day usage, see `README.md`.
6
+
7
+ ## System overview
8
+
9
+ ```
10
+ ┌─────────────────────────────────────────────────────────────────┐
11
+ │ harness CLI (Typer) │
12
+ │ init · install · status · update │
13
+ └────────────────────────────┬────────────────────────────────────┘
14
+
15
+ ┌───────────────────┼───────────────────┐
16
+ ▼ ▼ ▼
17
+ .agents/* core/* native/skill_gen
18
+ config, vision, config, state, Jinja2 → .cursor/
19
+ state, progress scanner, ui, … skills, agents, rules
20
+
21
+
22
+ integrations/
23
+ git_ops, memverse
24
+
25
+
26
+ ┌─────────────────────────────────────────────────────────────────┐
27
+ │ Cursor IDE — skills, subagents, rules execute the workflow │
28
+ └─────────────────────────────────────────────────────────────────┘
29
+ ```
30
+
31
+ **Principle:** Cursor is the execution engine. Harness generates and refreshes the artifacts Cursor runs; there is no separate process supervisor or IDE driver layer in this package.
32
+
33
+ ---
34
+
35
+ ## CLI layer (`src/harness/cli.py`)
36
+
37
+ Built with **Typer**. Four commands:
38
+
39
+ | Command | Purpose |
40
+ |-----------|---------|
41
+ | `init` | Interactive project bootstrap (see below). |
42
+ | `install` | Regenerate `.cursor/` native artifacts from current config. |
43
+ | `status` | Load session state and render a Rich dashboard. |
44
+ | `update` | Check PyPI, optional pip upgrade, reinstall artifacts, config migration hints. |
45
+
46
+ ---
47
+
48
+ ## Commands (`src/harness/commands/`)
49
+
50
+ ### `init.py`
51
+
52
+ Wizard (interactive by default; `--non-interactive` / `-y` for defaults):
53
+
54
+ 1. **Language** — `en` or `zh`; drives i18n for the session.
55
+ 2. **Project info** — name and description.
56
+ 3. **Trunk branch** — detected from git when possible, user-confirmed.
57
+ 4. **CI** — project scan (`scanner`) suggests commands; user picks or enters a custom gate command.
58
+ 5. **Memverse** — enable/disable and domain prefix for the Memverse MCP integration.
59
+ 6. **Vision** — optional immediate vision flow vs. deferred (placeholder file still created when skipped).
60
+
61
+ **Writes:** `.agents/config.toml` (from `templates/config.toml.j2`), `.agents/vision.md` when appropriate, then calls `generate_native_artifacts()` so `.cursor/` is populated. Updates `.gitignore` for harness-local files (e.g. `.agents/state.json`, `.agents/.stop`).
62
+
63
+ ### `install.py`
64
+
65
+ Resolves language (CLI flag or project config), loads `HarnessConfig`, calls **`generate_native_artifacts()`** with optional `--force` to overwrite generated files.
66
+
67
+ ### `status.py`
68
+
69
+ Loads **`SessionState`** from `.agents/state.json` and renders progress via **Rich** (`core/ui.py` patterns).
70
+
71
+ ### `update.py`
72
+
73
+ Queries PyPI for newer versions, runs **`pip install --upgrade harness-flow`** when requested, reinstalls native artifacts, and runs lightweight **config migration** checks with user-visible warnings.
74
+
75
+ ---
76
+
77
+ ## Core (`src/harness/core/`)
78
+
79
+ ### `config.py`
80
+
81
+ **Pydantic** models: `ProjectConfig`, `CIConfig`, `ModelsConfig`, `NativeModeConfig`, `WorkflowConfig`, `HarnessConfig`, plus nested integration config (e.g. Memverse).
82
+
83
+ - **`HarnessConfig` uses `ConfigDict(extra="ignore")`** so older TOML keys do not break loading.
84
+ - **`HarnessConfig.load()`** builds the effective config by deep-merging, then validates:
85
+ - Start from **project** `.agents/config.toml` (if present).
86
+ - Merge **`~/.harness/config.toml`** under it so **project wins** on conflicts.
87
+ - Merge **`HARNESS_*` environment variables** on top (highest precedence).
88
+ - Missing keys fall back to **model defaults**.
89
+
90
+ `ModelsConfig` carries `default`, `role_overrides`, and `role_configs`; unknown keys under `[models]` are ignored. Native workflows primarily use `native.*` and project/CI/workflow fields.
91
+
92
+ ### `roles.py`
93
+
94
+ Minimal constants only:
95
+
96
+ - **`ALL_ROLES`** — empty `frozenset` (no routed roles in native-only mode).
97
+ - **`NATIVE_REVIEW_ROLES`** — the five native review roles: `architect`, `product_owner`, `engineer`, `qa`, `project_manager`.
98
+ - **`SCORING_DIMENSIONS`** — evaluation dimension labels (used by tests for validation).
99
+ - **`DEFAULT_RUNTIME`** — default runtime label (`"cursor"`) for registry/events/tracker.
100
+
101
+ ### `state.py`
102
+
103
+ **`SessionState`**, **`TaskRecord`**, **`CompletedTask`** (and related types) with **JSON** persistence under `.agents/state.json` for resume-friendly dashboards.
104
+
105
+ ### `progress.py`
106
+
107
+ **`suggest_next_action`** and **`update_progress`** helpers for markdown progress narratives (e.g. `.agents/progress.md`) aligned with native workflows.
108
+
109
+ ### `scanner.py`
110
+
111
+ Scans the repository layout to **suggest CI commands** during `init`.
112
+
113
+ ### `ui.py`
114
+
115
+ **Rich** helpers for terminal output (tables, panels, styling) used by status and other commands.
116
+
117
+ ### `events.py`
118
+
119
+ Structured **JSONL** event logging for observability of harness-adjacent activity.
120
+
121
+ ### `registry.py`
122
+
123
+ **SQLite**-backed registry for agent run metadata (local audit trail).
124
+
125
+ ### `context.py`
126
+
127
+ **Task execution context** shared by code paths that still need a unified “where is the task root / config” view.
128
+
129
+ ---
130
+
131
+ ## Native mode generator (`src/harness/native/`)
132
+
133
+ ### `skill_gen.py`
134
+
135
+ - Loads **Jinja2** templates from `src/harness/templates/native/`.
136
+ - Builds a **template context** from `HarnessConfig` (CI command, trunk branch, native gates, hooks, per-role model hints, etc.) plus small static principle blocks where templates expect them.
137
+ - **`generate_native_artifacts()`** writes:
138
+ - **10 skills** under `.cursor/skills/harness/<skill-name>/SKILL.md`
139
+ - **5 agents** under `.cursor/agents/*.md`
140
+ - **4 rules** under `.cursor/rules/*.mdc`
141
+ - **Eval resources** (checklist and specialist docs) under `.cursor/skills/harness/harness-eval/`
142
+ - **`.cursor/worktrees.json`** for parallel worktree setup (skipped if the file already exists unless `force`)
143
+
144
+ Idempotent by default for `worktrees.json`; skills/agents/rules are regenerated according to `install`/`force` behavior.
145
+
146
+ ---
147
+
148
+ ## Templates (`src/harness/templates/`)
149
+
150
+ - **`config.toml.j2`** — project config emitted by `init`.
151
+ - **`native/`** — Jinja2 sources for skills, agents, rules, and shared **sections** (e.g. plan/review gates, trust boundary, CI verification).
152
+ - **`vision.md.j2` / `vision.zh.md.j2`** — initial vision stubs.
153
+
154
+ All user-visible harness **behavior** in the IDE is intended to flow from these templates plus `HarnessConfig`, so upgrades can refresh prompts without forking business logic across Python files.
155
+
156
+ ---
157
+
158
+ ## Integrations (`src/harness/integrations/`)
159
+
160
+ - **`git_ops.py`** — git helpers (rebase, merge, cleanup) used where the workflow still touches branches.
161
+ - **`memverse.py`** — Memverse MCP integration for learnings and memory sync aligned with skills.
162
+
163
+ ---
164
+
165
+ ## Design principles
166
+
167
+ 1. **Cursor IDE is the execution engine** — Harness generates **skills, agents, and rules** that Cursor’s agent runtime executes. No in-package external CLI orchestration of other IDEs.
168
+ 2. **Five-role adversarial review** — The five native roles review **plans and code** in parallel; templates encode how dispatch and aggregation behave.
169
+ 3. **Fix-First auto-remediation** — Review output is classified into **AUTO-FIX** vs **ASK** before presentation (encoded in generated rules/skills, not in a Python state machine).
170
+ 4. **Config cascade** — **Project** and **global** TOML merge with **project overriding global**; **`HARNESS_*` env vars** override both; Pydantic validates the result.
171
+ 5. **Backward compatibility** — **`extra="ignore"`** on `HarnessConfig` allows stale keys from older installs to load safely.
172
+ 6. **Template-driven generation** — Native artifacts are rendered from **Jinja2**; Python supplies context and file placement only.
173
+ 7. **Local-first** — State, config, registry, and logs are **on disk**; PyPI is only needed for **package updates**, not for routine development.
174
+
175
+ ---
176
+
177
+ ## Artifact layout (high level)
178
+
179
+ **Project (`.agents/`)**
180
+
181
+ - `config.toml` — harness configuration.
182
+ - `vision.md` — product/engineering vision for skills.
183
+ - `state.json` — session state (typically gitignored).
184
+ - `progress.md` — human-readable progress log.
185
+ - `.stop` — optional graceful stop flag (typically gitignored).
186
+ - `tasks/`, `archive/` — task artifacts and history (convention from harness workflow docs).
187
+
188
+ **Generated IDE (`.cursor/`)**
189
+
190
+ - `skills/harness/**` — generated skills and eval resources.
191
+ - `agents/*.md` — five review agents plus any future template outputs.
192
+ - `rules/*.mdc` — always-on rules (workflow, trust boundary, Fix-First, safety).
193
+ - `worktrees.json` — optional parallel-agent worktree bootstrap commands.
194
+
195
+ ---
196
+
197
+ ## Internationalization
198
+
199
+ Module-level catalogs (`i18n/en.py`, `i18n/zh.py`) expose `t(key, **kwargs)`. Missing keys fall back to English. CLI and generator user-facing strings go through this layer when applicable.
200
+
201
+ ---
202
+
203
+ ## Testing orientation
204
+
205
+ Tests are organized around **fast, local behavior**: configuration loading (including env overrides), state/progress, scanner suggestions, skill generation output, install/update flows, git helpers, registry, and UI pieces—without requiring a live Cursor session. Template and config drift is caught by tests that assert on generated files or loaded models.
206
+
207
+ ---
208
+
209
+ ## Design decisions (native era)
210
+
211
+ ### Why generate `.cursor/` instead of shipping static files?
212
+
213
+ Project-specific **CI command**, **trunk branch**, **review gates**, and **hooks** must flow into prompts. Templating from `HarnessConfig` keeps one SSOT and allows `harness install` to refresh IDE assets after config edits.
214
+
215
+ ### Why keep `ALL_ROLES` empty?
216
+
217
+ Older configs and code paths referenced a unified role set for model validation. An empty `ALL_ROLES` preserves **compatibility** while native mode keys off **`NATIVE_REVIEW_ROLES`** only.
218
+
219
+ ### Why SQLite for the registry?
220
+
221
+ A **local, queryable** history of runs supports debugging and audit without a hosted service—consistent with the local-first stance.
@@ -0,0 +1,40 @@
1
+ # Changelog
2
+
3
+ ## 4.1.0
4
+
5
+ ### Breaking Changes
6
+
7
+ - **Project renamed** from `harness-orchestrator` to `harness-flow`. Install with `pip install harness-flow`. The Python package name (`harness`) and CLI command (`harness`) are unchanged.
8
+ - **Migration:** If upgrading from `harness-orchestrator`, run `pip uninstall harness-orchestrator && pip install harness-flow`.
9
+
10
+ ## 4.0.0 (2026-04-02)
11
+
12
+ ### Breaking Changes
13
+
14
+ - **Removed orchestrator mode** — The external CLI-driven orchestrator (`harness run`, `harness auto`, `harness stop`, `harness vision`) has been removed. Harness now operates exclusively in cursor-native mode.
15
+ - **Removed CLI commands**: `run`, `auto`, `stop`, `vision`
16
+ - **Removed modules**: `harness.orchestrator`, `harness.drivers`, `harness.methodology`, `harness.agents` (packaged agent definitions)
17
+ - **Removed config fields**: `workflow.mode`, `workflow.profile`, `workflow.dual_evaluation`, `[drivers]` section, `integrations.memverse.driver`
18
+ - **Removed role registry**: Orchestrator roles (planner, builder, evaluator, alignment_evaluator, strategist, reflector) removed from `harness.core.roles`
19
+
20
+ ### Migration
21
+
22
+ - **Old configs are safe**: `HarnessConfig` now uses `extra="ignore"`, so `.agents/config.toml` files with `[drivers]` or removed `[workflow]` fields will load without errors.
23
+ - **Use Cursor skills instead of CLI**: `/harness-plan`, `/harness-vision`, `/harness-brainstorm` replace the removed CLI commands.
24
+ - **Run `harness install --force`** after upgrading to regenerate native artifacts.
25
+
26
+ ### What's kept
27
+
28
+ - Full cursor-native mode: skill generation, 5-role review system, Fix-First auto-remediation
29
+ - CLI commands: `init`, `install`, `status`, `update`
30
+ - Core infrastructure: config, state, UI, events, registry, git ops, scanner
31
+ - All native templates and generated artifacts
32
+
33
+ ### Simplified
34
+
35
+ - `harness init` wizard: 6 steps (was 9) — no IDE probing, no mode selection
36
+ - `harness install`: only generates native artifacts (no IDE agent copying)
37
+ - `config.py`: cleaner model without driver configs
38
+ - `roles.py`: minimal exports (NATIVE_REVIEW_ROLES, SCORING_DIMENSIONS)
39
+ - `state.py`: data models only (StateMachine removed)
40
+ - i18n catalogs: ~72 keys each (was ~270+)
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Arthas Zeng
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.