@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 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
- # ai-harness
1
+ # AI Harness
2
2
 
3
- Framework tái sử dụng để hướng dẫn AI làm việc theo **Spec → Code → Test → Review** trong nhiều dự án.
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
- **Trạng thái:** 0.6.0 candidate; 6 adapters, 4 optional capabilities, 53 skills và CLI Node.js 22+ với lệnh `aih`, không cần Python hay thư viện runtime ngoài.
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
- ## Hướng dẫn quy trình phát triển phần mềm (full SDLC)
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
- Nếu lần đầu sử dụng, đọc theo thứ tự: **Cài → Product/BA/PO → UI/UX → OpenSpec → Code → Test/Review → CI/CD → Vận hành**.
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
- git clone git@github.com:manh0303/ai-harness.git
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
- cd /path/to/my-backend
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 new-change add-order
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
- `aih list` liệt kê cả adapters và capabilities; `aih skills` chỉ trả tên + mô tả,
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
- Module manifests có `module_version` và các metadata phụ thuộc, khuyến nghị, xung đột. Kiểm tra trước khi cài:
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
- ```bash
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
- Chế độ mặc định không có `--scope` vẫn chỉ gồm adapters. Foundation Hardening đã có trong source; đây vẫn là source candidate, chưa chứng minh npm registry có bản phát hành. Xem [release policy](docs/release-policy.md).
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
- ## Chọn adapter
30
+ ## Thành phần
202
31
 
203
- | Dự án | `--adapters` |
32
+ | Nhóm | Hỗ trợ |
204
33
  | --- | --- |
205
- | Java / Spring Boot | `java-spring` |
206
- | React hoặc Next.js | `react-nextjs` |
207
- | Astro micro-tools / static SEO | `astro` |
208
- | React Native / Expo | `react-native` |
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
- ## Nhận diện stack và dùng adapter
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
- ```bash
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
- `detect` báo adapter đề xuất kèm bằng chứng; chỉ đọc file ngay trong thư mục đích, không quét đệ quy
229
- monorepo. Dùng `--target apps/backend` cho từng module. Spring cần dấu hiệu Spring Boot trong Maven/Gradle;
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
- Mỗi adapter có `adapter.yaml`, `rules/`, `skills/`, `checks/verification.yaml` và `evals/cases.json`.
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
- ## Dự án nhận những gì?
48
+ ## Tài liệu
242
49
 
243
- | Đường dẫn | Cách quản lý |
50
+ | Mục đích | Hướng dẫn |
244
51
  | --- | --- |
245
- | `AGENTS.md` | Thêm/cập nhật một block có marker; giữ nguyên nội dung bên ngoài |
246
- | `.harness/core/`, `adapters/`, `integrations/`, `templates/` | Snapshot framework, được lock bằng hash |
247
- | `.agents/skills/harness-*/` | Skill dùng trong project; cách kích hoạt tùy assistant |
248
- | `.harness/lock.json` | Version, adapters và SHA-256 của nội dung được quản lý |
249
- | `.harness/project.json` | Dự án sở hữu; chọn adapter |
250
- | `.harness/local.md` | Dự án sở hữu; domain, build command, convention riêng |
251
- | `openspec/config.yaml` | Chỉ tạo nếu chưa có; giữ cấu hình hiện tại |
252
- | `openspec/changes/<id>/` | Chỉ tạo khi gọi `new-change`; còn TODO cần hoàn thiện |
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
- Xem [docs/openspec.md](docs/openspec.md). Chỉ archive sau khi mọi PR liên quan đã merge.
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
- ## License
306
-
307
- Dự án được cấp phép theo [MIT License](LICENSE) — cho phép sử dụng, sửa đổi và phân phối (kể cả thương mại) theo các điều kiện trong giấy phép. Repository vẫn **private** và package npm đã cấu hình `public`; việc thêm license không tự thay đổi quyền truy cập hoặc phát hành package.
308
-
309
- ## Tài liệu
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
- `harness.yaml` cố ý dùng JSON-compatible YAML 1.2 để CLI đọc bằng `JSON.parse`. Không dùng cú pháp YAML
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
+ }