@manhd_d/ai-harness 0.6.0 → 0.7.0
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.
- package/CHANGELOG.md +41 -0
- package/README.md +44 -297
- package/bin/aih.js +0 -0
- package/cli/environment.js +157 -0
- package/cli/harness.js +16 -1
- package/cli/main.js +36 -8
- package/cli/readiness.js +117 -0
- package/core/agents/planner.md +3 -0
- package/core/evals/cases.json +31 -0
- package/core/skills/harness-review/SKILL.md +2 -0
- package/core/skills/harness-spec/SKILL.md +6 -2
- package/core/workflows/clarification.md +28 -0
- package/core/workflows/project-setup.md +29 -0
- package/core/workflows/spec-to-code.md +8 -1
- package/docs/architecture.md +12 -1
- package/docs/change-readiness.md +67 -0
- package/docs/cli.md +25 -4
- package/docs/getting-started.md +73 -111
- package/docs/npm-release.md +38 -51
- package/docs/project-configuration.md +82 -0
- package/docs/release-policy.md +1 -1
- package/docs/versioning.md +19 -4
- package/evals/README.md +3 -0
- package/evals/real-task-comparison.md +49 -0
- package/harness.yaml +1 -1
- package/package.json +1 -1
- package/templates/AGENTS.md +7 -2
- package/templates/environment.json +6 -0
- package/templates/openspec/decisions.json +5 -0
- package/templates/openspec/verification.json +4 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## Unreleased — Project setup, clarification and readiness
|
|
4
|
+
- Add optional shared environment configuration and ignored machine path overrides, with redacted doctor diagnostics.
|
|
5
|
+
- Add read-only setup suggestions, host-led A/B/C clarification and next-step guidance.
|
|
6
|
+
- Scaffold decision/evidence sidecars and add structural implement/review readiness checks.
|
|
7
|
+
- Add behavior scenarios and a real-task comparison protocol; live-model evaluation remains unperformed.
|
|
8
|
+
|
|
9
|
+
## Unreleased — Simpler onboarding and release regression coverage
|
|
10
|
+
- Start with npm install, minimal module selection and project context; clarify advisory commands and the two-step CLI/snapshot update.
|
|
11
|
+
- Link progressive context rules from the generated AGENTS entry point; retain project ownership and runtime boundaries.
|
|
12
|
+
- Exercise legacy migrations against both the current and next patch version; document recovery from a failed immutable release tag.
|
|
13
|
+
|
|
14
|
+
## Unreleased — Release validation compatibility
|
|
15
|
+
- Accept Release Please's linked version headings for version 0.6.1 in both validation commands while retaining strict matching of the current distribution version.
|
|
16
|
+
|
|
17
|
+
## Unreleased — Release migration tests
|
|
18
|
+
- Fix legacy upgrade tests to assert the current Harness source version rather than hardcoding 0.6.0, allowing Release Please version PRs to pass CI without weakening migration checks.
|
|
19
|
+
|
|
3
20
|
## Unreleased — npm 12 pack metadata compatibility
|
|
4
21
|
- Make package smoke tests support both npm 10/11 array-form and npm 12 package-keyed JSON output from `npm pack --json`.
|
|
5
22
|
- Validate archive metadata before accessing `files`, with explicit diagnostics instead of an undefined-property crash.
|
|
@@ -42,6 +59,30 @@
|
|
|
42
59
|
- Check release metadata consistency and establish single-release-PR version discipline; retain v0.6.0 until a dedicated release PR.
|
|
43
60
|
|
|
44
61
|
|
|
62
|
+
## [0.7.0](https://github.com/manh0303/ai-harness/compare/v0.6.2...v0.7.0) (2026-10-12)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
### Features
|
|
66
|
+
|
|
67
|
+
* add project environment setup and clarification readiness ([384cf13](https://github.com/manh0303/ai-harness/commit/384cf13b8a96791c26f9e0769bd8e0ccb734c20b))
|
|
68
|
+
|
|
69
|
+
## [0.6.2](https://github.com/manh0303/ai-harness/compare/v0.6.1...v0.6.2) (2026-10-11)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
### Bug Fixes
|
|
73
|
+
|
|
74
|
+
* **release:** support linked Release Please changelog headings ([8084940](https://github.com/manh0303/ai-harness/commit/80849408a349305ef5cdfb0c0eb0206ea8242eb8))
|
|
75
|
+
* simplify onboarding and guard release version migrations ([43efbb2](https://github.com/manh0303/ai-harness/commit/43efbb24e26d190b7a2b8dd2fbd5a9a5ee5368a1))
|
|
76
|
+
* **test:** unblock Release Please version bump CI ([63ba179](https://github.com/manh0303/ai-harness/commit/63ba17974cafad40e6ff5b483c126afdfc49df44))
|
|
77
|
+
|
|
78
|
+
## [0.6.1](https://github.com/manh0303/ai-harness/compare/v0.6.0...v0.6.1) (2026-10-11)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
### Bug Fixes
|
|
82
|
+
|
|
83
|
+
* **release:** automate npm publishing with Release Please and OIDC ([d39f284](https://github.com/manh0303/ai-harness/commit/d39f2843bd2700d9be8f70981135b8502b691303))
|
|
84
|
+
* **release:** automate npm releases with Release Please and OIDC ([0b293c5](https://github.com/manh0303/ai-harness/commit/0b293c520601cf2f21ed10d0dd3973f659647cc0))
|
|
85
|
+
|
|
45
86
|
## 0.6.0 — DevOps capability and Kubernetes adapter candidate
|
|
46
87
|
- Add `devops` capability with six namespaced CI/CD, Docker, deployment, infrastructure, observability and incident-response skills plus two review-gated workflows.
|
|
47
88
|
- Add `kubernetes` adapter with Helm/workload/rollout skills, advisory verification checks and two safety evaluation scenarios.
|
package/README.md
CHANGED
|
@@ -1,329 +1,76 @@
|
|
|
1
|
-
#
|
|
1
|
+
# AI Harness
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
Core dùng chung; adapter chứa quy chuẩn công nghệ; CLI cài một bản có version vào từng repository.
|
|
3
|
+
**Bộ quy tắc, skills và workflows tái sử dụng để AI hỗ trợ phát triển phần mềm theo quy trình _Spec → Code → Test → Review_.**
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
Gói `@manhd_d/ai-harness` chưa phát hành lên npm registry; hiện cài từ repository private hoặc tarball.
|
|
8
|
-
Harness không tự gọi LLM, không tự sinh ứng dụng, không tạo agent runtime, không tự merge/deploy.
|
|
9
|
-
Các role/skill hướng dẫn assistant đang dùng; quyền thực tế do IDE/runtime, Git và CI kiểm soát.
|
|
5
|
+
AI Harness cài context vào từng repository qua CLI `aih`. Có thể kết hợp các technology adapters và capabilities theo nhu cầu; không phụ thuộc một IDE hay mô hình AI cụ thể.
|
|
10
6
|
|
|
11
|
-
|
|
7
|
+
> Yêu cầu **Node.js 22+**. CLI không tự chạy LLM, viết code, phê duyệt tài liệu, merge PR hoặc deploy.
|
|
12
8
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
- **[Getting started](docs/getting-started.md)** — cài CLI, chọn module, tạo change và kiểm tra.
|
|
16
|
-
- **[Hai luồng tài liệu](docs/documentation-workflows.md)** — idea-driven và document-driven, lưu trữ, version và handoff.
|
|
17
|
-
- **[Full SDLC: Idea → Production](docs/end-to-end-workflow.md)** — input/output, approval gate, cách phối hợp capabilities/adapters.
|
|
18
|
-
- **[Ma trận 53 skills](docs/skill-matrix.md)** — tra cứu skills theo stage/công nghệ và ID thật.
|
|
19
|
-
- **[Agent handoffs](docs/agent-handoffs.md)** — roles, trách nhiệm, ownership, evidence và bàn giao.
|
|
20
|
-
- **Walkthrough:** [Spring Boot API](docs/examples/spring-boot-api.md) · [Full-stack Next.js + Spring](docs/examples/fullstack-web.md) · [React Native](docs/examples/react-native-app.md) · [Python AI/RAG](docs/examples/ai-rag-service.md) · [Astro micro-tools](docs/examples/astro-micro-tools.md) · [Astro + AdSense](docs/examples/astro-adsense-microtools.md).
|
|
21
|
-
|
|
22
|
-
Harness cung cấp hướng dẫn cho AI runtime, **không** tự điều phối AI agent, tạo code, chạy test, merge hay deploy.
|
|
23
|
-
|
|
24
|
-
## Bắt đầu
|
|
25
|
-
|
|
26
|
-
**Để thử adapter Astro trước khi PR được merge**, checkout branch `feat/astro-lightweight-adapter` trước `npm pack`. Sau merge, ưu tiên commit/tag chính thức đã review. CLI vẫn báo 0.6.0 vì adapter mới chưa được phát hành qua release PR riêng.
|
|
27
|
-
|
|
28
|
-
Cài từ source đã review bằng tài khoản có quyền repository private:
|
|
9
|
+
## Cài đặt và dùng nhanh
|
|
29
10
|
|
|
30
11
|
```bash
|
|
31
|
-
|
|
32
|
-
cd ai-harness
|
|
33
|
-
# Nếu thử các tính năng chưa merge trong PR #10:
|
|
34
|
-
git switch feat/astro-lightweight-adapter
|
|
35
|
-
# Sau khi merge, ưu tiên tag/commit đã review thay vì feature branch.
|
|
36
|
-
npm pack
|
|
37
|
-
npm install -g ./manhd_d-ai-harness-0.6.0.tgz
|
|
12
|
+
npm install -g @manhd_d/ai-harness
|
|
38
13
|
|
|
39
|
-
|
|
40
|
-
aih init --adapters java-spring --dry-run
|
|
14
|
+
# Chạy trong một project đã tồn tại
|
|
41
15
|
aih init --adapters java-spring
|
|
42
16
|
aih check
|
|
43
|
-
aih
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
Sau khi cài, dùng `aih` từ bất kỳ repository ứng dụng nào. Đích mặc định là thư mục hiện tại;
|
|
47
|
-
`--target /path/to/project` vẫn được hỗ trợ. Thư mục đích phải tồn tại.
|
|
48
|
-
`aih --help` xem lệnh, `aih --version` xem phiên bản công cụ.
|
|
49
|
-
|
|
50
|
-
Khi chủ sở hữu đã phát hành npm package công khai, cách cài sẽ là
|
|
51
|
-
`npm install -g @manhd_d/ai-harness@0.6.0`. **Lệnh registry này chưa dùng được chỉ vì PR đã merge.**
|
|
52
|
-
Có thể cài tarball vào devDependencies rồi dùng `npx --no-install aih init` nếu không muốn cài global.
|
|
53
|
-
Xem [hướng dẫn đóng gói/phát hành](docs/npm-release.md).
|
|
54
|
-
|
|
55
|
-
Đây là cài **quy trình và context**, không scaffold source code Spring/React và không sửa build file.
|
|
56
|
-
|
|
57
|
-
## Hai chế độ tài liệu — Idea-driven / Document-driven
|
|
58
|
-
|
|
59
|
-
**Idea-driven:** Từ ý tưởng của developer → thảo luận → nghiên cứu có nguồn → PRD-lite hoặc BRD/PRD/SRS/use cases → duyệt → OpenSpec. **Document-driven:** Từ BRD/PRD/SRS/Confluence đã có của BA → kiểm tra source version, gap và traceability → technical spec và code. Không tự ghi đè tài liệu BA đã duyệt. Hai chế độ có thể sử dụng luân phiên trong cùng một dự án.
|
|
60
|
-
|
|
61
|
-
Xem hai hướng dẫn thực hành: [Bắt đầu từ ý tưởng](docs/examples/idea-driven-project.md) · [Dự án đã có tài liệu BA](docs/examples/document-driven-project.md). Xem thêm [Documentation workflows](docs/documentation-workflows.md) và [Confluence integration contract](integrations/confluence/README.md). `aih` only creates templates and ships instructions; AI host handles research/content, and external publishing requires independently authorized tooling.
|
|
62
|
-
|
|
63
|
-
```bash
|
|
64
|
-
aih init --capabilities product
|
|
65
|
-
aih new-doc idea # docs/discovery/idea.md
|
|
66
|
-
aih new-doc research # docs/discovery/research.md
|
|
67
|
-
aih new-doc prd-lite # docs/product/prd-lite.md
|
|
68
|
-
aih new-doc srs # docs/product/srs.md
|
|
69
|
-
aih new-doc use-cases # docs/product/use-cases.md
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
## Product documentation capability — BA / PM / PO
|
|
73
|
-
|
|
74
|
-
Capability `product` cung cấp 5 role contracts, 13 skills, 5 workflows và 16 templates
|
|
75
|
-
để chuyển ý tưởng hoặc nguồn Confluence được cấp quyền thành BRD, PRD, user stories,
|
|
76
|
-
acceptance criteria và requirement traceability. Mọi tài liệu hoàn thiện là dữ liệu
|
|
77
|
-
**do dự án sở hữu**, nằm trong `docs/discovery/` (ý tưởng, nghiên cứu) hoặc `docs/product/` (yêu cầu) của repository ứng dụng.
|
|
78
|
-
|
|
79
|
-
```bash
|
|
80
|
-
# Khởi tạo dự án mới chỉ cần Product
|
|
81
|
-
aih init --capabilities product
|
|
82
|
-
# Kết hợp Product + UI/UX + React
|
|
83
|
-
aih init --capabilities product,uiux --adapters react-nextjs
|
|
84
|
-
# Tạo file mẫu để AI điền bằng tài liệu được cấp phép, không tự điền nội dung
|
|
85
|
-
aih new-doc brd
|
|
86
|
-
aih new-doc prd
|
|
87
|
-
aih new-doc backlog
|
|
88
|
-
aih new-doc acceptance-criteria
|
|
89
|
-
aih new-doc traceability
|
|
90
|
-
aih skills
|
|
91
|
-
aih skill harness-product-prd-generation
|
|
92
|
-
aih check
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
Dự án đã cài đặt cần sửa `.harness/project.json`, bổ sung `product` vào
|
|
96
|
-
`capabilities` rồi chạy `aih update --dry-run`, `aih update`, `aih check`.
|
|
97
|
-
CLI chỉ tạo **bản mẫu** khi dùng `new-doc`. Việc phân tích và điền nội dung cần
|
|
98
|
-
AI runtime có quyền đọc nguồn, kiểm tra bằng chứng và được BA/PM/PO phê duyệt.
|
|
99
|
-
Xem [Product capability](capabilities/product/README.md).
|
|
100
|
-
|
|
101
|
-
## Astro cho micro-tools, React Islands và Cloudflare
|
|
102
|
-
|
|
103
|
-
Chọn [adapter Astro](adapters/astro/README.md) nếu bạn làm trang công cụ nhỏ, SEO landing page hoặc portfolio nhiều utilities. **Static-first:** TypeScript/browser xử lý trước; React Islands chỉ cho UI tương tác; Cloudflare Workers/API và MFE chỉ khi có nhu cầu thực. Astro Islands không phải các micro frontend deploy độc lập. Xem [walkthrough đầy đủ](docs/examples/astro-micro-tools.md).
|
|
104
|
-
|
|
105
|
-
```bash
|
|
106
|
-
cd /path/to/existing-astro-project
|
|
107
|
-
aih resolve --adapters astro --capabilities product,uiux
|
|
108
|
-
aih init --adapters astro --capabilities product,uiux --dry-run
|
|
109
|
-
aih init --adapters astro --capabilities product,uiux
|
|
110
|
-
aih check
|
|
111
|
-
aih skills
|
|
112
|
-
aih skill harness-astro-project-architecture
|
|
113
|
-
aih skill harness-astro-islands
|
|
114
|
-
aih skill harness-astro-cloudflare
|
|
115
|
-
aih verify --scope all # advisory; không tự chạy build/deploy
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
Không bắt buộc Product/UIUX; nếu chỉ cần code, dùng `aih init --adapters astro`. Trong dự án đã cài Harness: sửa `.harness/project.json` và chạy `aih update --dry-run`, `aih update`, `aih check`. `aih detect` nhận diện `astro` từ `package.json`; `react-dom` vì React Islands không tự khiến CLI cài `react-nextjs` trừ khi dự án còn dùng `next`. CLI chỉ cài rules/skills, **không** tạo Astro app, cài React hay deploy lên Cloudflare.
|
|
119
|
-
|
|
120
|
-
## Monetization — kiếm tiền hợp lệ từ quảng cáo
|
|
121
|
-
|
|
122
|
-
Capability `monetization` độc lập với Astro, React/Next.js và các adapter khác. Với website micro-tools miễn phí, ưu tiên **giá trị sản phẩm → SEO → kiểm tra AdSense/consent → ad placement an toàn → đo traffic và Page RPM thực tế**. Năm skills giúp phân tích các bước; không tự tạo tài khoản, xin duyệt site, nhúng ad code hoặc kéo doanh thu từ Google.
|
|
123
|
-
|
|
124
|
-
```bash
|
|
125
|
-
# Website Astro có mục tiêu doanh thu quảng cáo
|
|
126
|
-
aih resolve --adapters astro --capabilities monetization
|
|
127
|
-
aih init --adapters astro --capabilities monetization --dry-run
|
|
128
|
-
aih init --adapters astro --capabilities monetization
|
|
129
|
-
aih check
|
|
130
|
-
aih skill harness-monetization-adsense-integration
|
|
131
|
-
aih skill harness-monetization-ad-placement-ux
|
|
132
|
-
aih skill harness-monetization-analytics-revenue
|
|
133
|
-
aih verify --scope capabilities # manual checklist, không chạy provider checks
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
Nếu cần Product + UI/UX thì chọn `--capabilities product,uiux,monetization`. Dự án đã cài Harness phải sửa `.harness/project.json`, rồi `aih update --dry-run`, `aih update`, `aih check`. Templates monetization nằm trong `.harness/capabilities/monetization/templates/`; tự copy vào `docs/monetization/` khi được quyền — `aih new-doc` chỉ dùng cho Product.
|
|
137
|
-
|
|
138
|
-
Hướng dẫn: [Monetization](docs/monetization.md) · [Astro + AdSense walkthrough](docs/examples/astro-adsense-microtools.md) · [Capability README](capabilities/monetization/README.md). Không hứa AdSense sẽ phê duyệt hay đảm bảo thu nhập; quảng cáo phải tuân thủ chính sách và không được nhầm với nút tool.
|
|
139
|
-
|
|
140
|
-
## Optional UI/UX capability
|
|
141
|
-
|
|
142
|
-
UI/UX là **capability** độc lập với technology adapter. Chọn khi cần chuyển ý tưởng, PRD hoặc
|
|
143
|
-
Confluence thành requirement, UX flow, screen inventory rồi tạo Figma bằng agent đã kết nối.
|
|
144
|
-
Không tự động gọi LLM, đọc Confluence hay viết Figma. Phải cấp quyền MCP cho host và duyệt trước
|
|
145
|
-
khi chỉnh sửa file Figma hoặc màn hình đã được duyệt.
|
|
146
|
-
|
|
147
|
-
```bash
|
|
148
|
-
# Dự án chỉ cần design, không cần adapter công nghệ
|
|
149
|
-
aih init --capabilities uiux
|
|
150
|
-
|
|
151
|
-
# Dự án vừa React vừa thiết kế UI/UX
|
|
152
|
-
aih init --adapters react-nextjs --capabilities uiux
|
|
153
|
-
|
|
154
|
-
# Sau khi cài, xem metadata kỹ năng trước, chỉ nạp nội dung khi cần
|
|
155
|
-
aih skills
|
|
156
|
-
aih skill harness-uiux-figma-design
|
|
157
|
-
|
|
158
|
-
# Bổ sung UI/UX vào một project đã cài: sửa mảng capabilities
|
|
159
|
-
# trong .harness/project.json, sau đó:
|
|
160
|
-
aih update --dry-run
|
|
161
|
-
aih update
|
|
162
|
-
aih check
|
|
17
|
+
aih setup
|
|
163
18
|
```
|
|
164
19
|
|
|
165
|
-
|
|
166
|
-
`aih skill <name>` mới trả nội dung đầy đủ của skill đã cài và được lock. Không có network
|
|
167
|
-
download độc lập: npm tarball vẫn chứa mọi capability, nhưng dự án chỉ nhận capability đã chọn.
|
|
168
|
-
Xem [tài liệu capability](capabilities/uiux/README.md) và [quy trình docs-to-figma](capabilities/uiux/workflows/docs-to-figma.md).
|
|
169
|
-
|
|
170
|
-
## DevOps capability + Kubernetes adapter
|
|
171
|
-
|
|
172
|
-
`devops` cung cấp 6 skills cho CI/CD, Docker, release, infrastructure review,
|
|
173
|
-
observability và incident response, cùng 2 workflows có cổng phê duyệt.
|
|
174
|
-
`kubernetes` là adapter riêng cho manifest, Helm và rollout safety.
|
|
175
|
-
|
|
176
|
-
```bash
|
|
177
|
-
aih init --adapters java-spring,kubernetes --capabilities devops
|
|
178
|
-
# Kết hợp cả Product + UI/UX + DevOps
|
|
179
|
-
aih init --adapters java-spring,kubernetes --capabilities product,uiux,devops
|
|
180
|
-
aih skills
|
|
181
|
-
aih skill harness-devops-deployment
|
|
182
|
-
aih verify # chỉ gợi ý kiểm tra, không chạy
|
|
183
|
-
aih check
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
Các lệnh không gọi cloud API, không triển khai production hay cấp quyền kết nối.
|
|
187
|
-
Xem [DevOps capability](capabilities/devops/README.md) và [quy tắc adapters](docs/adapters.md).
|
|
188
|
-
|
|
189
|
-
## Module composition & evaluation (unreleased)
|
|
20
|
+
Tiếp theo, ghi stack, nghiệp vụ và lệnh test vào `.harness/local.md`; mở project trong AI IDE và yêu cầu assistant đọc `AGENTS.md` trước khi làm việc. Bạn giao task bình thường, AI đọc skill liên quan và báo cáo test thực chạy.
|
|
190
21
|
|
|
191
|
-
|
|
22
|
+
Thêm `--capabilities product` khi cần tài liệu BA; `aih new-doc prd-lite` tạo template, `aih new-change <id>` tạo spec nháp khi cần. Không bắt mọi task tạo đủ tài liệu. Xem [Getting started](docs/getting-started.md) và [CLI reference](docs/cli.md).
|
|
192
23
|
|
|
193
|
-
|
|
194
|
-
aih resolve --adapters java-spring,kubernetes --capabilities product,uiux,devops
|
|
195
|
-
aih verify --scope all # checklist tư vấn, không chạy
|
|
196
|
-
aih eval --scope all # báo cáo chưa chấm, không gọi model
|
|
197
|
-
```
|
|
24
|
+
**Phân biệt:** `aih check` kiểm tra file Harness; `aih verify` xuất checklist; build/test ứng dụng do AI host hoặc CI thực chạy. CLI không bảo đảm AI sẽ tuân thủ hướng dẫn; xem [đánh giá hành vi](evals/README.md).
|
|
198
25
|
|
|
199
|
-
|
|
26
|
+
`aih setup` đưa gợi ý câu hỏi cho AI host; AI hỏi phần còn mơ hồ bằng A/B/C có đề xuất và lưu câu trả lời.
|
|
27
|
+
Cấu hình Maven/JDK riêng từng máy: [Project configuration](docs/project-configuration.md).
|
|
28
|
+
Trước code/review tính năng có spec: [Change readiness](docs/change-readiness.md).
|
|
200
29
|
|
|
201
|
-
##
|
|
30
|
+
## Thành phần
|
|
202
31
|
|
|
203
|
-
|
|
|
32
|
+
| Nhóm | Hỗ trợ |
|
|
204
33
|
| --- | --- |
|
|
205
|
-
|
|
|
206
|
-
|
|
|
207
|
-
|
|
|
208
|
-
|
|
|
209
|
-
| Python AI, agent hoặc RAG | `ai-python` |
|
|
210
|
-
| Kubernetes / Helm workloads | `kubernetes` |
|
|
211
|
-
| Full-stack trong cùng repository | `java-spring,react-nextjs` |
|
|
212
|
-
| Chỉ core rules và workflow | Bỏ tùy chọn `--adapters` |
|
|
213
|
-
|
|
214
|
-
AI bằng Java có thể dùng `java-spring` cùng skill `harness-ai-evaluation`; không bắt buộc chuyển sang Python.
|
|
215
|
-
Với multi-repo, cài vào từng repo có thực hiện công việc. Ghi danh sách repo và thứ tự merge trong change.
|
|
34
|
+
| **Core** | Rules, agent roles, skills, workflows, review & verification |
|
|
35
|
+
| **Adapters** | Java Spring Boot, React/Next.js, React Native, Python AI/RAG, Kubernetes, Astro |
|
|
36
|
+
| **Capabilities** | Product/BA/PO, UI/UX & Figma, DevOps, Monetization/AdSense |
|
|
37
|
+
| **OpenSpec** | Template cho proposal, design, tasks và spec có review |
|
|
216
38
|
|
|
217
|
-
|
|
39
|
+
Bạn chỉ chọn module cần dùng, ví dụ `aih init --adapters astro --capabilities monetization` cho website công cụ nhỏ có quảng cáo. Xem [Astro adapter](adapters/astro/README.md) và [Monetization capability](capabilities/monetization/README.md).
|
|
218
40
|
|
|
219
|
-
|
|
220
|
-
aih list
|
|
221
|
-
aih detect
|
|
222
|
-
aih init --detect --dry-run
|
|
223
|
-
aih init --detect
|
|
224
|
-
aih verify
|
|
225
|
-
aih eval
|
|
226
|
-
```
|
|
41
|
+
## Hai luồng làm việc
|
|
227
42
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
React Native được phân biệt với web; AI/Python dựa trên tên thư viện trong pyproject/requirements.
|
|
231
|
-
Đây là heuristic: có thể bỏ sót dependency gián tiếp hoặc khớp comment. Review kết quả trước khi cài.
|
|
232
|
-
`init --detect` là lựa chọn chủ động; không tìm thấy stack thì dừng. `init` không có flag vẫn cài core-only.
|
|
233
|
-
Có thể dùng `--adapters` để chọn chính xác. Update giữ lựa chọn trong project.json, không tự nhận diện lại.
|
|
43
|
+
- **Idea-driven:** Ý tưởng → thảo luận/nghiên cứu → BRD/PRD/SRS → UI/UX → spec → code.
|
|
44
|
+
- **Document-driven:** BRD/PRD/SRS/Confluence đã có → phân tích gap → technical spec → code.
|
|
234
45
|
|
|
235
|
-
|
|
236
|
-
Skills của adapter đã chọn được cài vào `.agents/skills/harness-<adapter>-*`; Core giữ TDD/debug/review dùng chung.
|
|
237
|
-
`aih verify` chỉ xuất checklist và lệnh gợi ý, **không chạy test/build**. `aih eval` xuất tình huống và mẫu
|
|
238
|
-
báo cáo chưa chấm; `aih eval --report report.json` tổng hợp điểm có bằng chứng, **không gọi model**.
|
|
239
|
-
Xem [hướng dẫn adapter và đánh giá](docs/adapters.md) trước khi điền báo cáo.
|
|
46
|
+
Chi tiết: [Documentation workflows](docs/documentation-workflows.md) · [Confluence integration](integrations/confluence/README.md).
|
|
240
47
|
|
|
241
|
-
##
|
|
48
|
+
## Tài liệu
|
|
242
49
|
|
|
243
|
-
|
|
|
50
|
+
| Mục đích | Hướng dẫn |
|
|
244
51
|
| --- | --- |
|
|
245
|
-
|
|
|
246
|
-
|
|
|
247
|
-
|
|
|
248
|
-
|
|
|
249
|
-
|
|
|
250
|
-
|
|
|
251
|
-
|
|
|
252
|
-
|
|
|
253
|
-
|
|
254
|
-
Commit các file đã cài vào repository ứng dụng để cả team dùng đúng một phiên bản. Không commit secrets.
|
|
255
|
-
Hãy hướng assistant đọc `AGENTS.md`; việc tự phát hiện file/skill phụ thuộc công cụ bạn sử dụng.
|
|
256
|
-
CLI không cấu hình tài khoản, plugin cá nhân hoặc MCP server của assistant.
|
|
257
|
-
|
|
258
|
-
## Tùy biến và cập nhật
|
|
259
|
-
|
|
260
|
-
Cài phiên bản công cụ mới trước, rồi chạy `aih update` trong từng dự án để cập nhật snapshot.
|
|
261
|
-
Lockfile từ CLI Python 0.1 vẫn được hỗ trợ; xem [migration](docs/versioning.md).
|
|
262
|
-
|
|
263
|
-
Thêm quy ước vào `.harness/local.md` hoặc phần ngoài marker trong `AGENTS.md`.
|
|
264
|
-
Muốn đổi stack: chỉnh mảng `adapters` trong `.harness/project.json`, rồi chạy update.
|
|
265
|
-
|
|
266
|
-
```bash
|
|
267
|
-
aih update --dry-run
|
|
268
|
-
aih update
|
|
269
|
-
aih check
|
|
270
|
-
aih doctor
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
Source mặc định là package đã cài chứa CLI; có thể dùng `--source /path/to/reviewed-checkout` với init/update.
|
|
274
|
-
Cập nhật dừng khi file managed bị sửa, không có chế độ force. Đưa tùy biến sang local.md rồi restore
|
|
275
|
-
file managed từ commit cài trước đó. Major upgrade cần `--allow-major`; downgrade dùng Git revert.
|
|
276
|
-
Dry-run không để lại thay đổi file, nhưng tạo/xóa marker khóa trong lúc lập kế hoạch nên cần quyền ghi.
|
|
277
|
-
Doctor chỉ kiểm tra tool có trên PATH; không xác nhận version hay build chạy thành công.
|
|
278
|
-
|
|
279
|
-
## OpenSpec
|
|
280
|
-
|
|
281
|
-
Framework tạo cấu trúc tương thích workflow `spec-driven` và không cài OpenSpec thay bạn.
|
|
282
|
-
`new-change` tạo proposal/design/tasks/delta spec bằng template đã pin trong project; đây là bản nháp.
|
|
283
|
-
Hoàn thiện TODO, review yêu cầu, rồi dùng OpenSpec CLI do dự án cài và pin phiên bản:
|
|
284
|
-
|
|
285
|
-
```bash
|
|
286
|
-
# Chạy tại repository ứng dụng sau khi cài OpenSpec theo hướng dẫn upstream.
|
|
287
|
-
openspec validate add-order --strict
|
|
288
|
-
```
|
|
52
|
+
| Bắt đầu | [Getting started](docs/getting-started.md) |
|
|
53
|
+
| Phát triển end-to-end | [Full SDLC](docs/end-to-end-workflow.md) · [Agent handoffs](docs/agent-handoffs.md) |
|
|
54
|
+
| Tra cứu kỹ năng | [Skill matrix](docs/skill-matrix.md) · [CLI reference](docs/cli.md) |
|
|
55
|
+
| Tài liệu sản phẩm | [Idea-driven example](docs/examples/idea-driven-project.md) · [Document-driven example](docs/examples/document-driven-project.md) |
|
|
56
|
+
| Ví dụ backend/full-stack | [Spring Boot API](docs/examples/spring-boot-api.md) · [Spring + Next.js](docs/examples/fullstack-web.md) |
|
|
57
|
+
| Ví dụ mobile/AI | [React Native](docs/examples/react-native-app.md) · [Python AI/RAG](docs/examples/ai-rag-service.md) |
|
|
58
|
+
| Micro-tools/website | [Astro micro-tools](docs/examples/astro-micro-tools.md) · [Astro + AdSense](docs/examples/astro-adsense-microtools.md) · [Monetization](docs/monetization.md) |
|
|
59
|
+
| Phát hành npm | [Release guide](docs/npm-release.md) · [Changelog](CHANGELOG.md) |
|
|
289
60
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
## Kiểm thử
|
|
61
|
+
## Kiểm tra và cập nhật
|
|
293
62
|
|
|
294
63
|
```bash
|
|
64
|
+
# Trong repository AI Harness (maintainer)
|
|
295
65
|
npm test
|
|
296
66
|
npm run validate
|
|
297
67
|
npm run test:package
|
|
298
|
-
```
|
|
299
|
-
|
|
300
|
-
Test CLI chạy offline trên thư mục tạm: cài/update, preservation, drift, collision, traversal/symlink,
|
|
301
|
-
adapter selection, version guard, reproducibility, rollback và tạo change. CI cấu hình Node.js 22/24 trên Linux và Windows.
|
|
302
|
-
[evals/README.md](evals/README.md) có bộ tình huống và công cụ tổng hợp đánh giá hành vi AI riêng.
|
|
303
|
-
Test CLI pass không có nghĩa đã chạy Spring/Next/native build hay live evaluation của LLM.
|
|
304
68
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
- [Getting started](docs/getting-started.md)
|
|
312
|
-
- [Documentation workflows](docs/documentation-workflows.md)
|
|
313
|
-
- [Walkthrough Idea-driven](docs/examples/idea-driven-project.md)
|
|
314
|
-
- [Walkthrough Document-driven](docs/examples/document-driven-project.md)
|
|
315
|
-
- [Astro micro-tool walkthrough](docs/examples/astro-micro-tools.md)
|
|
316
|
-
- [Website advertising monetization](docs/monetization.md)
|
|
317
|
-
- [Astro + AdSense walkthrough](docs/examples/astro-adsense-microtools.md)
|
|
318
|
-
- [Full SDLC](docs/end-to-end-workflow.md)
|
|
319
|
-
- [Skill matrix](docs/skill-matrix.md)
|
|
320
|
-
- [Agent handoffs](docs/agent-handoffs.md)
|
|
321
|
-
- [Kiến trúc và ranh giới trách nhiệm](docs/architecture.md)
|
|
322
|
-
- [Versioning và migration](docs/versioning.md)
|
|
323
|
-
- [CLI contract](docs/cli.md)
|
|
324
|
-
- [Phân tích workspace tham khảo](docs/reference-analysis.md)
|
|
325
|
-
- [Hướng dẫn đóng góp](CONTRIBUTING.md)
|
|
326
|
-
- [Thay đổi phiên bản](CHANGELOG.md)
|
|
69
|
+
# Nâng CLI global, rồi cập nhật snapshot trong project
|
|
70
|
+
npm install -g @manhd_d/ai-harness@latest
|
|
71
|
+
aih update --dry-run
|
|
72
|
+
aih update
|
|
73
|
+
aih check
|
|
74
|
+
```
|
|
327
75
|
|
|
328
|
-
|
|
329
|
-
khác cho file này. `openspec/config.yaml` vẫn là YAML thông thường do OpenSpec đọc.
|
|
76
|
+
**License:** [MIT](LICENSE). GitHub source có thể private; package `@manhd_d/ai-harness` được phát hành công khai qua npm.
|
package/bin/aih.js
CHANGED
|
File without changes
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { safe, stat, isObject, SLUG, HarnessError } from './files.js';
|
|
4
|
+
|
|
5
|
+
export const ENVIRONMENT = '.harness/environment.json';
|
|
6
|
+
export const MACHINE = '.harness/machine.json';
|
|
7
|
+
export const emptyEnvironment = () => ({ schema_version: 1, tools: {}, files: {}, commands: {} });
|
|
8
|
+
const validText = s => typeof s === 'string' && s.trim().length > 0 && !/[\0\r\n]/.test(s);
|
|
9
|
+
const own = (o, k) => Object.hasOwn(o, k);
|
|
10
|
+
function requireThat(ok, message) { if (!ok) throw new HarnessError(message); }
|
|
11
|
+
|
|
12
|
+
export function readConfig(root, name) {
|
|
13
|
+
const p = safe(root, name), info = stat(p);
|
|
14
|
+
if (!info) return null;
|
|
15
|
+
requireThat(info.size <= 1024 * 1024, 'Configuration exceeds 1 MiB: ' + name);
|
|
16
|
+
// Never include parser input (possibly private machine paths) in diagnostics.
|
|
17
|
+
try { return JSON.parse(fs.readFileSync(p, 'utf8')); }
|
|
18
|
+
catch { throw new HarnessError('Invalid JSON: ' + name); }
|
|
19
|
+
}
|
|
20
|
+
function keys(value, allowed, label) {
|
|
21
|
+
requireThat(isObject(value) && Object.keys(value).every(k => allowed.includes(k)), 'Invalid fields: ' + label);
|
|
22
|
+
}
|
|
23
|
+
export function loadEnvironment(root) {
|
|
24
|
+
const shared = readConfig(root, ENVIRONMENT);
|
|
25
|
+
const machine = readConfig(root, MACHINE);
|
|
26
|
+
if (shared === null) {
|
|
27
|
+
requireThat(machine === null, 'Machine configuration requires environment.json');
|
|
28
|
+
return { configured: false, shared: emptyEnvironment(), machine: null };
|
|
29
|
+
}
|
|
30
|
+
keys(shared, ['schema_version', 'tools', 'files', 'commands'], ENVIRONMENT);
|
|
31
|
+
requireThat(shared.schema_version === 1, 'Unsupported environment schema');
|
|
32
|
+
for (const group of ['tools', 'files', 'commands']) {
|
|
33
|
+
requireThat(isObject(shared[group]), 'Missing environment map: ' + group);
|
|
34
|
+
for (const [id, value] of Object.entries(shared[group])) {
|
|
35
|
+
requireThat(SLUG.test(id), 'Invalid environment identifier');
|
|
36
|
+
const label = group + '/' + id;
|
|
37
|
+
if (group === 'commands') {
|
|
38
|
+
keys(value, ['tool', 'args'], label);
|
|
39
|
+
requireThat(validText(value.tool) && own(shared.tools, value.tool), 'Unknown command tool: ' + id);
|
|
40
|
+
requireThat(Array.isArray(value.args) && value.args.every(a => typeof a === 'string' && !/[\0\r\n]/.test(a)), 'Invalid arguments: ' + id);
|
|
41
|
+
} else {
|
|
42
|
+
const field = group === 'tools' ? 'executable' : 'path';
|
|
43
|
+
keys(value, [field, 'required'], label);
|
|
44
|
+
requireThat(validText(value[field]), 'Missing path: ' + label);
|
|
45
|
+
requireThat(value.required === undefined || typeof value.required === 'boolean', 'Invalid required flag: ' + label);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (machine !== null) {
|
|
50
|
+
keys(machine, ['schema_version', 'tools', 'files'], MACHINE);
|
|
51
|
+
requireThat(machine.schema_version === 1, 'Unsupported machine schema');
|
|
52
|
+
for (const group of ['tools', 'files']) {
|
|
53
|
+
if (machine[group] === undefined) continue;
|
|
54
|
+
requireThat(isObject(machine[group]), 'Invalid machine map: ' + group);
|
|
55
|
+
const field = group === 'tools' ? 'executable' : 'path';
|
|
56
|
+
for (const [id, value] of Object.entries(machine[group])) {
|
|
57
|
+
requireThat(SLUG.test(id) && own(shared[group], id), 'Machine override must reference a declared ' + group + ' entry');
|
|
58
|
+
keys(value, [field], 'machine ' + group + '/' + id);
|
|
59
|
+
requireThat(validText(value[field]), 'Invalid machine override: ' + group + '/' + id);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return { configured: true, shared, machine };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function expand(value, env) {
|
|
67
|
+
const missing = [];
|
|
68
|
+
const resolved = value.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g, (_, key) => {
|
|
69
|
+
if (!own(env, key) || !validText(env[key])) { missing.push(key); return ''; }
|
|
70
|
+
return env[key];
|
|
71
|
+
});
|
|
72
|
+
return { resolved, missing: [...new Set(missing)], invalid: /\$\{/.test(resolved) };
|
|
73
|
+
}
|
|
74
|
+
function pathStatus(value, root, executable, env) {
|
|
75
|
+
if ((process.platform !== 'win32' && /^[A-Za-z]:[\\/]|^\\\\/.test(value)) ||
|
|
76
|
+
(process.platform === 'win32' && value.startsWith('/'))) return 'platform-mismatch';
|
|
77
|
+
if (value.startsWith('~')) return 'unsupported-path'; // No implicit shell expansion.
|
|
78
|
+
const bare = !path.isAbsolute(value) && !/[\\/]/.test(value);
|
|
79
|
+
const candidates = executable && bare
|
|
80
|
+
? (env.PATH || '').split(path.delimiter).filter(Boolean).filter(path.isAbsolute).map(dir => path.join(dir, value))
|
|
81
|
+
: [path.resolve(root, value)];
|
|
82
|
+
const extensions = executable && process.platform === 'win32' && !path.extname(value)
|
|
83
|
+
? (env.PATHEXT || '.EXE;.CMD;.BAT').split(';').filter(e => /^\.[A-Za-z0-9]+$/.test(e)) : [''];
|
|
84
|
+
let notExecutable = false;
|
|
85
|
+
for (const candidate of candidates) for (const ext of extensions) {
|
|
86
|
+
try {
|
|
87
|
+
const p = candidate + ext;
|
|
88
|
+
if (!fs.statSync(p).isFile()) continue;
|
|
89
|
+
fs.accessSync(p, executable && process.platform !== 'win32' ? fs.constants.X_OK : fs.constants.F_OK);
|
|
90
|
+
return 'present';
|
|
91
|
+
} catch (e) { if (e.code === 'EACCES') notExecutable = true; }
|
|
92
|
+
}
|
|
93
|
+
return notExecutable ? 'not-accessible' : 'missing';
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function environmentReport(root, env = process.env) {
|
|
97
|
+
const { configured, shared, machine } = loadEnvironment(root);
|
|
98
|
+
const entries = [];
|
|
99
|
+
for (const group of ['tools', 'files']) for (const [id, value] of Object.entries(shared[group])) {
|
|
100
|
+
const field = group === 'tools' ? 'executable' : 'path';
|
|
101
|
+
const override = machine?.[group]?.[id];
|
|
102
|
+
const expanded = expand(override ? override[field] : value[field], env);
|
|
103
|
+
entries.push({ group, id, source: override ? 'machine' : 'project', required: value.required !== false,
|
|
104
|
+
status: expanded.missing.length ? 'missing-env' : expanded.invalid ? 'invalid-reference'
|
|
105
|
+
: pathStatus(expanded.resolved, root, group === 'tools', env),
|
|
106
|
+
missing_variables: expanded.missing });
|
|
107
|
+
}
|
|
108
|
+
// Arguments are references only; do not execute or print resolved values.
|
|
109
|
+
for (const [id, command] of Object.entries(shared.commands)) {
|
|
110
|
+
const args = command.args.map(a => expand(a, env));
|
|
111
|
+
const missing = [...new Set(args.flatMap(a => a.missing))];
|
|
112
|
+
entries.push({ group: 'commands', id, source: 'project', required: shared.tools[command.tool].required !== false,
|
|
113
|
+
status: missing.length ? 'missing-env' : args.some(a => a.invalid) ? 'invalid-reference' : 'declared',
|
|
114
|
+
missing_variables: missing });
|
|
115
|
+
}
|
|
116
|
+
const problems = entries.filter(e => e.required && !['present', 'declared'].includes(e.status))
|
|
117
|
+
.map(e => e.group + '/' + e.id + ': ' + e.status);
|
|
118
|
+
return { configured, machine_present: machine !== null, entries, problems,
|
|
119
|
+
note: 'Presence/reference checks only. No commands executed; values and arguments are omitted. Never store credentials here.' };
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export function setupPlan(root, adapters, env = process.env) {
|
|
123
|
+
const environment = environmentReport(root, env);
|
|
124
|
+
const configuredTools = environment.entries.some(e => e.group === 'tools');
|
|
125
|
+
const questions = [];
|
|
126
|
+
if (adapters.includes('java-spring') && !configuredTools) {
|
|
127
|
+
const wrapper = process.platform === 'win32' ? 'mvnw.cmd' : 'mvnw';
|
|
128
|
+
const hasWrapper = Boolean(stat(safe(root, wrapper)));
|
|
129
|
+
const gradle = ['gradlew', 'gradlew.bat', 'build.gradle', 'build.gradle.kts'].some(p => Boolean(stat(safe(root, p))));
|
|
130
|
+
if (gradle) {
|
|
131
|
+
questions.push({ id: 'build-tool', question: 'Which build tool does this project use?',
|
|
132
|
+
options: [{ label: 'A', value: 'gradle', description: 'Use the existing Gradle setup.' },
|
|
133
|
+
{ label: 'B', value: 'maven', description: 'Use Maven only if project conventions require it.' }],
|
|
134
|
+
recommendation: 'A', reason: 'Gradle files exist; confirm the project convention.', allow_free_text: true });
|
|
135
|
+
} else questions.push({ id: 'maven-mode', question: 'How should Maven be invoked?',
|
|
136
|
+
options: [{ label: 'A', value: 'wrapper', description: 'Use the repository Maven Wrapper.' },
|
|
137
|
+
{ label: 'B', value: 'path', description: 'Use Maven available on PATH.' },
|
|
138
|
+
{ label: 'C', value: 'custom', description: 'Use an internal Maven executable and optional settings file.' }],
|
|
139
|
+
recommendation: hasWrapper ? 'A' : null,
|
|
140
|
+
reason: hasWrapper ? 'A wrapper exists for this OS; review it before execution.' : 'No wrapper found for this OS; ask which Maven the team uses.',
|
|
141
|
+
allow_free_text: true });
|
|
142
|
+
}
|
|
143
|
+
if (!environment.configured || !environment.entries.length) questions.push({
|
|
144
|
+
id: 'project-context', question: 'Where are the authoritative project requirements and conventions?',
|
|
145
|
+
options: [{ label: 'A', value: 'repository', description: 'Use existing repository documentation and build files.' },
|
|
146
|
+
{ label: 'B', value: 'external', description: 'Use authorized BA/Confluence sources with revisions.' },
|
|
147
|
+
{ label: 'C', value: 'idea', description: 'Start from the user idea and clarify the scope.' }],
|
|
148
|
+
recommendation: null, reason: 'The host must inspect existing local.md and sources before recommending.',
|
|
149
|
+
allow_free_text: true
|
|
150
|
+
});
|
|
151
|
+
return { status: environment.problems.length ? 'blocked' : 'planned', environment, questions,
|
|
152
|
+
next_steps: ['Read AGENTS.md, .harness/local.md and the installed project-setup workflow.',
|
|
153
|
+
'Skip answered questions; ask at most 1–3 consequential questions with evidence-based recommendations.',
|
|
154
|
+
'Record shared decisions in local.md/environment.json; put only machine paths in ignored machine.json.',
|
|
155
|
+
'Run aih doctor, then use the reviewed project commands through your AI host.'],
|
|
156
|
+
note: 'Read-only host-facing suggestions, not an interactive terminal wizard or approval.' };
|
|
157
|
+
}
|