openmoneta-dev-kit 2.2.1 → 2.3.1
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/README.md +7 -4
- package/VERSION +1 -1
- package/claude/agents/qa-autonomous.md +39 -0
- package/claude/agents/requirement-analyst.md +51 -0
- package/claude/agents/security-auditor.md +44 -0
- package/claude/agents/ui-tester.md +40 -0
- package/claude/hooks/bash-guard.sh +112 -0
- package/claude/hooks/posttooluse-adapter.sh +38 -0
- package/claude/hooks/pretooluse-adapter.sh +69 -0
- package/claude/hooks/sessionstart-adapter.sh +44 -0
- package/claude/hooks/stop-adapter.sh +60 -0
- package/claude/settings-hooks.json +55 -0
- package/hooks/inject-process-context.sh +24 -12
- package/hooks/verify-completion.sh +2 -1
- package/install-claude-code.sh +262 -0
- package/package.json +5 -2
- package/scripts/init-project.sh +26 -0
- package/skills/automated-testing/SKILL.md +2 -0
- package/skills/automated-testing/scripts/install-playwright.sh +3 -0
- package/skills/decision-recorder/SKILL.md +1 -1
- package/skills/docs-maintenance/SKILL.md +3 -1
- package/skills/module-architect/SKILL.md +2 -2
- package/src/commands/init.js +7 -1
- package/src/commands/install.js +21 -2
- package/src/commands/uninstall.js +54 -3
- package/src/commands/update.js +22 -6
- package/src/lib/paths.js +4 -0
- package/templates/AGENTS.md.tpl +5 -5
- package/uninstall.sh +62 -1
- package/update.sh +16 -1
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# OpenMoneta Dev Kit
|
|
2
2
|
|
|
3
|
-
> Biến **Cursor IDE / OpenCode** thành một **team developer hoàn chỉnh** với quy trình 6 bước (Lean Mode), adaptive planning, hooks enforcement, token-aware doc routing và sub-agents on-demand.
|
|
3
|
+
> Biến **Cursor IDE / OpenCode / Claude Code** thành một **team developer hoàn chỉnh** với quy trình 6 bước (Lean Mode), adaptive planning, hooks enforcement, token-aware doc routing và sub-agents on-demand.
|
|
4
4
|
|
|
5
|
-
[](./VERSION)
|
|
6
6
|
[](./docs/INDEX.md)
|
|
7
7
|
[]()
|
|
8
8
|
[](https://www.npmjs.com/package/openmoneta-dev-kit)
|
|
@@ -13,16 +13,18 @@
|
|
|
13
13
|
npm install -g openmoneta-dev-kit && openmoneta install
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
1 lệnh cài cho cả Cursor + OpenCode. Sau đó khởi tạo project:
|
|
16
|
+
1 lệnh cài cho cả Cursor + OpenCode. Dùng Claude Code? Cài thêm `openmoneta install --claude`. Sau đó khởi tạo project:
|
|
17
17
|
|
|
18
18
|
```bash
|
|
19
19
|
cd /path/to/project
|
|
20
20
|
openmoneta init
|
|
21
|
+
openmoneta init --claude # nếu dùng Claude Code (tạo shim CLAUDE.md)
|
|
21
22
|
```
|
|
22
23
|
|
|
23
24
|
| Lệnh mới | Tương đương lệnh cũ |
|
|
24
25
|
|---|---|
|
|
25
26
|
| `openmoneta install` | `install.sh` + `install-opencode.sh` |
|
|
27
|
+
| `openmoneta install --claude` | `install-claude-code.sh` |
|
|
26
28
|
| `openmoneta init` | `init-project.sh .` |
|
|
27
29
|
| `openmoneta check` | `update.sh --check` |
|
|
28
30
|
| `openmoneta update --yes` | `update.sh --yes` |
|
|
@@ -58,13 +60,14 @@ bash ~/OpenMoneta-Dev-Kit/install.sh
|
|
|
58
60
|
- **11 skills** (4 core + 1 core conditional + 6 on-demand) — phân tích yêu cầu, thiết kế module, plan, systematic debugging, safe push, test, security, bảo trì docs
|
|
59
61
|
- **`openmoneta docs`** — audit module README thiếu/lỗi thời (stale) + skill `docs-maintenance` backfill docs cho dự án cũ
|
|
60
62
|
- **4 sub-agents** — 1 core + 3 on-demand (security-auditor, qa-autonomous, ui-tester)
|
|
61
|
-
- **4 hooks + plugin** — enforce token-aware reading, adaptive plan scope, và verify cuối phiên (module README + close plan); OpenCode đạt parity qua plugin guard `session.idle
|
|
63
|
+
- **4 hooks + plugin + adapter** — enforce token-aware reading, adaptive plan scope, và verify cuối phiên (module README + close plan); OpenCode đạt parity qua plugin guard `session.idle`, Claude Code qua hook adapter mỏng tái dùng bash hooks gốc
|
|
62
64
|
- **Token Routing** — bảng map keyword → module giúp AI giảm 70-90% token đọc
|
|
63
65
|
- **npm package** — `npm install -g openmoneta-dev-kit`, không cần git, không cần clone
|
|
64
66
|
- **Auto-update check** — notify khi có version mới (cache 24h)
|
|
65
67
|
- **Adaptive Planning** — task nhỏ không cần plan; task lớn/rủi ro tạo plan Draft, user review
|
|
66
68
|
- **Safe Push** — sync remote trước push, không đè code người khác
|
|
67
69
|
- **OpenCode Support** — global rules/skills/agents + plugin guard
|
|
70
|
+
- **Claude Code Support** — hook adapter + manifest install vào `~/.claude/` (không đụng skills/agents riêng của user) + shim `CLAUDE.md` → `@AGENTS.md` ([docs/12-claude-code.md](./docs/12-claude-code.md))
|
|
68
71
|
|
|
69
72
|
## Đóng góp
|
|
70
73
|
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.
|
|
1
|
+
2.3.1
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: qa-autonomous
|
|
3
|
+
description: ON-DEMAND ONLY. Dùng khi user explicitly yêu cầu viết unit/integration test. KHÔNG tự trigger trong quy trình bình thường.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Bạn là **qa-autonomous** của OpenMoneta Dev Kit trong Claude Code.
|
|
7
|
+
|
|
8
|
+
Chỉ dùng khi user yêu cầu viết test hoặc primary agent cần isolation cho test loop.
|
|
9
|
+
|
|
10
|
+
## Workflow
|
|
11
|
+
|
|
12
|
+
1. Đọc plan active và Acceptance Criteria/Test Plan nếu có.
|
|
13
|
+
2. Đọc skill `test-strategy` nếu available.
|
|
14
|
+
3. Phát hiện stack qua config (`package.json`, `pyproject.toml`, `go.mod`, ...).
|
|
15
|
+
4. Viết test focused theo behavior, không skip test.
|
|
16
|
+
5. Chạy test liên quan, đọc lỗi đầy đủ, fix root cause, retest.
|
|
17
|
+
6. Dừng sau tối đa 5 vòng nếu không fix được, báo root cause và blocker.
|
|
18
|
+
|
|
19
|
+
## Quy tắc
|
|
20
|
+
|
|
21
|
+
- Fix code khi code sai; chỉ sửa test khi assertion/test setup sai.
|
|
22
|
+
- Không dùng `.skip`, `xit`, comment-out test để pass.
|
|
23
|
+
- Một lần thay đổi, một lần verify.
|
|
24
|
+
|
|
25
|
+
## Output
|
|
26
|
+
|
|
27
|
+
```markdown
|
|
28
|
+
## QA Result
|
|
29
|
+
|
|
30
|
+
PASS | FAIL
|
|
31
|
+
|
|
32
|
+
- Tool:
|
|
33
|
+
- Attempts:
|
|
34
|
+
- Tests added/changed:
|
|
35
|
+
- AC verified:
|
|
36
|
+
- Blocker nếu fail:
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Luôn trả lời bằng tiếng Việt.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: requirement-analyst
|
|
3
|
+
description: Dùng proactively khi user request mơ hồ, lớn (>5 file ảnh hưởng), hoặc cần explore rộng codebase/tài liệu để hiểu impact trước khi lập plan. Read-only, không code.
|
|
4
|
+
tools: Read, Grep, Glob
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Bạn là **requirement-analyst** của OpenMoneta Dev Kit trong Claude Code.
|
|
8
|
+
|
|
9
|
+
## Vai trò
|
|
10
|
+
|
|
11
|
+
Bạn được gọi khi yêu cầu user **mơ hồ hoặc lớn**, cần đọc nhiều tài liệu/codebase mà không tốn context của parent. Bạn KHÔNG code, KHÔNG edit file. Output là **báo cáo phân tích + danh sách câu hỏi** để parent đem hỏi user.
|
|
12
|
+
|
|
13
|
+
## Workflow
|
|
14
|
+
|
|
15
|
+
1. Đọc `docs/INDEX.md` của workspace (nếu có) — luôn ưu tiên đầu tiên.
|
|
16
|
+
2. Đọc `plans/INDEX.md` để kiểm tra plan active/overlap.
|
|
17
|
+
3. Đọc module README liên quan qua Token Routing (`docs/modules/<name>/README.md`).
|
|
18
|
+
4. Đọc source vừa đủ để hiểu impact, KHÔNG scan toàn bộ repo.
|
|
19
|
+
5. Tóm tắt yêu cầu, giả thuyết, edge cases, rủi ro, impact.
|
|
20
|
+
6. Đề xuất câu hỏi critical: làm rõ yêu cầu, phân tích mọi trường hợp, phản biện và đề xuất phương án tối ưu hơn nếu có. Mỗi câu có 2-4 options với trade-off; KHÔNG hỏi câu user đã ngầm trả lời.
|
|
21
|
+
|
|
22
|
+
## Output
|
|
23
|
+
|
|
24
|
+
```markdown
|
|
25
|
+
# Requirement Analysis Report
|
|
26
|
+
|
|
27
|
+
## Yêu cầu (diễn đạt lại)
|
|
28
|
+
<1 đoạn>
|
|
29
|
+
|
|
30
|
+
## Giả thuyết
|
|
31
|
+
- ...
|
|
32
|
+
|
|
33
|
+
## Edge cases
|
|
34
|
+
- ...
|
|
35
|
+
|
|
36
|
+
## Rủi ro
|
|
37
|
+
- ...
|
|
38
|
+
|
|
39
|
+
## Impact
|
|
40
|
+
| File/Module | Mức độ | Ghi chú |
|
|
41
|
+
|---|---|---|
|
|
42
|
+
| ... | High/Med/Low | ... |
|
|
43
|
+
|
|
44
|
+
## Câu hỏi đề xuất hỏi user
|
|
45
|
+
1. ...
|
|
46
|
+
|
|
47
|
+
## Khuyến nghị tiếp theo
|
|
48
|
+
<hỏi user / đủ info để tạo plan / đủ info để code>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Luôn trả lời bằng tiếng Việt, súc tích — parent sẽ đọc và đem đi tiếp, đừng lan man.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: security-auditor
|
|
3
|
+
description: ON-DEMAND ONLY. Dùng khi user yêu cầu security audit (OWASP, scan secrets, dependency CVE) hoặc task chạm auth/payment/PII cần audit độc lập. Read-only, không sửa file.
|
|
4
|
+
tools: Read, Grep, Glob, Bash
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Bạn là **security-auditor** của OpenMoneta Dev Kit trong Claude Code.
|
|
8
|
+
|
|
9
|
+
Chỉ dùng khi user yêu cầu security audit hoặc task chạm auth/payment/PII/admin/permission và primary agent muốn audit độc lập.
|
|
10
|
+
|
|
11
|
+
## Workflow
|
|
12
|
+
|
|
13
|
+
1. Xác định scope từ `.cursor/.session-changes.json` nếu có, hoặc từ plan active trong `plans/`.
|
|
14
|
+
2. Audit OWASP Top 10 trong phạm vi file liên quan.
|
|
15
|
+
3. Scan secrets bằng công cụ read-only (`rg`, `git ls-files`, audit package manager nếu phù hợp).
|
|
16
|
+
4. Chỉ report HIGH/CRITICAL dependency CVE nếu có.
|
|
17
|
+
5. KHÔNG sửa file. Bash chỉ dùng cho lệnh read-only (rg/git/audit).
|
|
18
|
+
|
|
19
|
+
## Output
|
|
20
|
+
|
|
21
|
+
```markdown
|
|
22
|
+
# Security Audit Report
|
|
23
|
+
|
|
24
|
+
## Scope
|
|
25
|
+
- ...
|
|
26
|
+
|
|
27
|
+
## OWASP Checklist
|
|
28
|
+
- A01 Access Control: Pass/Issue/N/A — ...
|
|
29
|
+
- ...
|
|
30
|
+
|
|
31
|
+
## Secrets Scan
|
|
32
|
+
- ...
|
|
33
|
+
|
|
34
|
+
## Dependency CVE
|
|
35
|
+
- ...
|
|
36
|
+
|
|
37
|
+
## Recommendations
|
|
38
|
+
1. ...
|
|
39
|
+
|
|
40
|
+
## Verdict
|
|
41
|
+
PASS | FAIL — <kết luận ngắn>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Luôn trả lời bằng tiếng Việt.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ui-tester
|
|
3
|
+
description: ON-DEMAND ONLY. Dùng khi user yêu cầu UI test (Playwright multi-viewport mobile/tablet/desktop, visual regression, fix CSS rồi retest). KHÔNG tự trigger trong quy trình bình thường.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Bạn là **ui-tester** của OpenMoneta Dev Kit trong Claude Code.
|
|
7
|
+
|
|
8
|
+
Chỉ dùng khi user yêu cầu UI test, visual regression, hoặc test-fix giao diện.
|
|
9
|
+
|
|
10
|
+
## Workflow
|
|
11
|
+
|
|
12
|
+
1. Đọc plan active hoặc yêu cầu user để xác định AC UI.
|
|
13
|
+
2. Kiểm tra Playwright đã cài chưa; nếu chưa, hỏi/đề xuất cài.
|
|
14
|
+
3. Chạy multi-viewport: mobile, tablet, desktop.
|
|
15
|
+
4. Lưu screenshot vào `tests/screenshots/<slug>/iter-<n>/`.
|
|
16
|
+
5. Đọc lỗi/screenshot, fix CSS/component, retest.
|
|
17
|
+
6. Sau mỗi 2 vòng, tóm tắt thay đổi và hỏi user nếu hướng visual chưa chắc chắn.
|
|
18
|
+
7. Hard limit 5 vòng trước khi escalate.
|
|
19
|
+
|
|
20
|
+
## Quy tắc
|
|
21
|
+
|
|
22
|
+
- Screenshot thật, không đoán bằng đọc code.
|
|
23
|
+
- Không sửa test để né lỗi visual thật.
|
|
24
|
+
- Cleanup state tạm khi hoàn tất.
|
|
25
|
+
|
|
26
|
+
## Output
|
|
27
|
+
|
|
28
|
+
```markdown
|
|
29
|
+
## UI Test Result
|
|
30
|
+
|
|
31
|
+
PASS | FAIL
|
|
32
|
+
|
|
33
|
+
- Viewports:
|
|
34
|
+
- Screenshots:
|
|
35
|
+
- Attempts:
|
|
36
|
+
- Issues fixed:
|
|
37
|
+
- Blocker nếu fail:
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Luôn trả lời bằng tiếng Việt.
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# bash-guard.sh — Claude Code PreToolUse (matcher: Bash).
|
|
3
|
+
# Chặn shell command đọc/search source TRƯỚC khi đọc docs/INDEX.md (và docs/decisions/
|
|
4
|
+
# nếu project có Decision Memory). Port từ openmoneta-guard.ts v1.8.6 (OpenCode).
|
|
5
|
+
#
|
|
6
|
+
# Phạm vi: CHỈ chặn search/read (rg|grep|find|fd|ls|tree|cat|sed|awk|head|tail).
|
|
7
|
+
# Write-qua-shell (tee, redirect, sed -i vào file) là known limitation v1 — xem ADR-0009.
|
|
8
|
+
#
|
|
9
|
+
# Output: deny qua hookSpecificOutput; cho qua = exit 0 KHÔNG output (không auto-approve).
|
|
10
|
+
|
|
11
|
+
set -euo pipefail
|
|
12
|
+
|
|
13
|
+
INPUT_JSON=$(cat 2>/dev/null || echo '{}')
|
|
14
|
+
command -v jq >/dev/null 2>&1 || exit 0
|
|
15
|
+
|
|
16
|
+
TOOL_NAME=$(echo "$INPUT_JSON" | jq -r '.tool_name // ""')
|
|
17
|
+
[[ "$TOOL_NAME" == "Bash" ]] || exit 0
|
|
18
|
+
|
|
19
|
+
CWD=$(echo "$INPUT_JSON" | jq -r '.cwd // ""')
|
|
20
|
+
COMMAND=$(echo "$INPUT_JSON" | jq -r '.tool_input.command // ""')
|
|
21
|
+
[[ -z "$CWD" || -z "$COMMAND" ]] && exit 0
|
|
22
|
+
|
|
23
|
+
# Project không dùng OpenMoneta → bỏ qua.
|
|
24
|
+
INDEX_FILE="$CWD/docs/INDEX.md"
|
|
25
|
+
[[ -f "$INDEX_FILE" ]] || exit 0
|
|
26
|
+
|
|
27
|
+
MARKER="$CWD/.cursor/.docs-index-read"
|
|
28
|
+
DECISIONS_INDEX="$CWD/docs/decisions/INDEX.md"
|
|
29
|
+
DECISIONS_MARKER="$CWD/.cursor/.decisions-read"
|
|
30
|
+
|
|
31
|
+
deny() {
|
|
32
|
+
local msg="$1"
|
|
33
|
+
jq -n --arg msg "$msg" '{
|
|
34
|
+
hookSpecificOutput: {
|
|
35
|
+
hookEventName: "PreToolUse",
|
|
36
|
+
permissionDecision: "deny",
|
|
37
|
+
permissionDecisionReason: $msg
|
|
38
|
+
}
|
|
39
|
+
}'
|
|
40
|
+
exit 0
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
NORMALIZED=$(printf '%s' "$COMMAND" | tr '\n' ' ')
|
|
44
|
+
|
|
45
|
+
# Command tự đọc docs/INDEX.md → set marker, cho qua.
|
|
46
|
+
case "$NORMALIZED" in
|
|
47
|
+
*"docs/INDEX.md"*)
|
|
48
|
+
mkdir -p "$CWD/.cursor"
|
|
49
|
+
touch "$MARKER"
|
|
50
|
+
exit 0
|
|
51
|
+
;;
|
|
52
|
+
esac
|
|
53
|
+
|
|
54
|
+
# Command đọc docs/decisions/ → set decisions marker, cho qua.
|
|
55
|
+
case "$NORMALIZED" in
|
|
56
|
+
*"docs/decisions"*)
|
|
57
|
+
mkdir -p "$CWD/.cursor"
|
|
58
|
+
touch "$DECISIONS_MARKER"
|
|
59
|
+
exit 0
|
|
60
|
+
;;
|
|
61
|
+
esac
|
|
62
|
+
|
|
63
|
+
# Không phải lệnh search/read → cho qua (giữ phạm vi hẹp, tránh false positive).
|
|
64
|
+
if ! printf '%s' "$NORMALIZED" | grep -qE '(^|[;&|() ])(rg|grep|find|fd|ls|tree|cat|sed|awk|head|tail)([ ]|$)'; then
|
|
65
|
+
exit 0
|
|
66
|
+
fi
|
|
67
|
+
|
|
68
|
+
# Allowlist (SAFE_READ_HINTS — parity openmoneta-guard.ts): command nhắm vào docs/config → cho qua,
|
|
69
|
+
# TRỪ KHI command cũng chứa source hint (vd `rg foo src/ docs/`).
|
|
70
|
+
HAS_SOURCE_HINT=0
|
|
71
|
+
case "$NORMALIZED" in
|
|
72
|
+
*"apps/"*|*"packages/"*|*"src/"*|*"lib/"*|*"components/"*|*"server/"*|*"modules/"*|*"pages/"*|*"/app/"*)
|
|
73
|
+
HAS_SOURCE_HINT=1
|
|
74
|
+
;;
|
|
75
|
+
esac
|
|
76
|
+
|
|
77
|
+
if [[ "$HAS_SOURCE_HINT" -eq 0 ]]; then
|
|
78
|
+
case "$NORMALIZED" in
|
|
79
|
+
*"docs/"*|*"plans/"*|*".cursor/"*|*".opencode/"*|*".claude/"*|*".github/"*|*".vscode/"*|*"AGENTS.md"*|*"CLAUDE.md"*|*"README"*|*"CHANGELOG"*|*"LICENSE"*|*"package.json"*|*"tsconfig"*|*"vite.config"*|*"playwright.config"*|*"biome.config"*|*"vitest.config"*|*"astro.config"*|*".gitignore"*|*"Dockerfile"*)
|
|
80
|
+
exit 0
|
|
81
|
+
;;
|
|
82
|
+
esac
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
# === Gate 1: docs-first ===
|
|
86
|
+
if [[ ! -f "$MARKER" ]]; then
|
|
87
|
+
deny "Bạn đang chạy shell command đọc/search source code TRƯỚC khi đọc docs/INDEX.md. Vi phạm token-aware reading (skill requirement-analysis Bước 1).
|
|
88
|
+
|
|
89
|
+
Command bị chặn: $COMMAND
|
|
90
|
+
|
|
91
|
+
QUY TRÌNH ĐÚNG (BẮT BUỘC, theo thứ tự):
|
|
92
|
+
1. Read $CWD/docs/INDEX.md TRƯỚC TIÊN.
|
|
93
|
+
2. Tìm keyword task trong bảng 'Feature/Keyword → Module' để biết module liên quan.
|
|
94
|
+
3. Read docs/modules/<matched-module>/README.md cho mỗi module liên quan.
|
|
95
|
+
4. CHỈ rồi mới search/read source code của module đó.
|
|
96
|
+
|
|
97
|
+
Sau khi đọc docs/INDEX.md, marker .cursor/.docs-index-read được set và mọi command source khác trong session sẽ được cho qua."
|
|
98
|
+
fi
|
|
99
|
+
|
|
100
|
+
# === Gate 2: decisions-read (Decision Memory / chống flip-flop kiến trúc) ===
|
|
101
|
+
if [[ -f "$DECISIONS_INDEX" && ! -f "$DECISIONS_MARKER" ]]; then
|
|
102
|
+
deny "Bạn đang chạy shell command search source code TRƯỚC khi đọc docs/decisions/ (trí nhớ quyết định kiến trúc). Vi phạm Bước 1 (skill requirement-analysis 1.3b).
|
|
103
|
+
|
|
104
|
+
Command bị chặn: $COMMAND
|
|
105
|
+
|
|
106
|
+
HÀNH ĐỘNG NGAY:
|
|
107
|
+
→ Read $DECISIONS_INDEX (set marker .cursor/.decisions-read), tìm ADR liên quan tới module bạn sắp đụng, đọc ADR đó nếu định đổi kiến trúc, sau đó retry command.
|
|
108
|
+
|
|
109
|
+
LƯU Ý: Muốn ĐỔI/ĐẢO kiến trúc đã Accepted → phải supersede tường minh (skill decision-recorder), KHÔNG revert lặng lẽ."
|
|
110
|
+
fi
|
|
111
|
+
|
|
112
|
+
exit 0
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# posttooluse-adapter.sh — Claude Code PostToolUse (Edit|Write|NotebookEdit) → core/track-changes.sh.
|
|
3
|
+
# Silent track file đã sửa vào <workspace>/.cursor/.session-changes.json (verify-completion dùng).
|
|
4
|
+
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
|
|
7
|
+
INPUT_JSON=$(cat 2>/dev/null || echo '{}')
|
|
8
|
+
command -v jq >/dev/null 2>&1 || exit 0
|
|
9
|
+
|
|
10
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
|
+
CORE_DIR="${OPENMONETA_CORE_HOOKS:-$SCRIPT_DIR/core}"
|
|
12
|
+
CORE_HOOK="$CORE_DIR/track-changes.sh"
|
|
13
|
+
[[ -f "$CORE_HOOK" ]] || exit 0
|
|
14
|
+
|
|
15
|
+
TOOL_NAME=$(echo "$INPUT_JSON" | jq -r '.tool_name // ""')
|
|
16
|
+
CWD=$(echo "$INPUT_JSON" | jq -r '.cwd // ""')
|
|
17
|
+
[[ -z "$TOOL_NAME" || -z "$CWD" ]] && exit 0
|
|
18
|
+
|
|
19
|
+
case "$TOOL_NAME" in
|
|
20
|
+
Write|Edit|NotebookEdit) ;;
|
|
21
|
+
*) exit 0 ;;
|
|
22
|
+
esac
|
|
23
|
+
|
|
24
|
+
case "$TOOL_NAME" in
|
|
25
|
+
Edit) MAPPED_TOOL="StrReplace" ;;
|
|
26
|
+
NotebookEdit) MAPPED_TOOL="EditNotebook" ;;
|
|
27
|
+
*) MAPPED_TOOL="Write" ;;
|
|
28
|
+
esac
|
|
29
|
+
|
|
30
|
+
CURSOR_INPUT=$(echo "$INPUT_JSON" | jq --arg tool "$MAPPED_TOOL" --arg cwd "$CWD" '{
|
|
31
|
+
tool_name: $tool,
|
|
32
|
+
tool_input: ((.tool_input // {}) + (if (.tool_input.notebook_path // "") != "" then {target_notebook: .tool_input.notebook_path} else {} end)),
|
|
33
|
+
workspace_roots: [$cwd]
|
|
34
|
+
}')
|
|
35
|
+
|
|
36
|
+
# Silent — không decision, không message.
|
|
37
|
+
echo "$CURSOR_INPUT" | bash "$CORE_HOOK" >/dev/null 2>&1 || true
|
|
38
|
+
exit 0
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# pretooluse-adapter.sh — Claude Code PreToolUse → bash hooks Cursor (single source of truth).
|
|
3
|
+
#
|
|
4
|
+
# Map:
|
|
5
|
+
# Read|Glob|Grep → core/enforce-docs-first.sh
|
|
6
|
+
# Write|Edit|NotebookEdit → core/check-plan-exists.sh (Edit→StrReplace, NotebookEdit→EditNotebook)
|
|
7
|
+
#
|
|
8
|
+
# Ngữ nghĩa permission (QUAN TRỌNG):
|
|
9
|
+
# - Hook gốc trả {"permission":"deny"} → output hookSpecificOutput.permissionDecision="deny".
|
|
10
|
+
# - Hook gốc trả {"permission":"allow"} → exit 0 KHÔNG output. Với Claude Code,
|
|
11
|
+
# permissionDecision="allow" nghĩa là AUTO-APPROVE (bỏ qua permission dialog) —
|
|
12
|
+
# adapter tuyệt đối không được phát "allow" để không vô hiệu hóa permission system.
|
|
13
|
+
|
|
14
|
+
set -euo pipefail
|
|
15
|
+
|
|
16
|
+
INPUT_JSON=$(cat 2>/dev/null || echo '{}')
|
|
17
|
+
|
|
18
|
+
# Không có jq → fail-open giống hooks gốc (không block agent).
|
|
19
|
+
command -v jq >/dev/null 2>&1 || exit 0
|
|
20
|
+
|
|
21
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
22
|
+
CORE_DIR="${OPENMONETA_CORE_HOOKS:-$SCRIPT_DIR/core}"
|
|
23
|
+
|
|
24
|
+
TOOL_NAME=$(echo "$INPUT_JSON" | jq -r '.tool_name // ""')
|
|
25
|
+
CWD=$(echo "$INPUT_JSON" | jq -r '.cwd // ""')
|
|
26
|
+
[[ -z "$TOOL_NAME" || -z "$CWD" ]] && exit 0
|
|
27
|
+
|
|
28
|
+
case "$TOOL_NAME" in
|
|
29
|
+
Read|Glob|Grep)
|
|
30
|
+
CORE_HOOK="$CORE_DIR/enforce-docs-first.sh"
|
|
31
|
+
MAPPED_TOOL="$TOOL_NAME"
|
|
32
|
+
;;
|
|
33
|
+
Write|Edit|NotebookEdit)
|
|
34
|
+
CORE_HOOK="$CORE_DIR/check-plan-exists.sh"
|
|
35
|
+
case "$TOOL_NAME" in
|
|
36
|
+
Edit) MAPPED_TOOL="StrReplace" ;;
|
|
37
|
+
NotebookEdit) MAPPED_TOOL="EditNotebook" ;;
|
|
38
|
+
*) MAPPED_TOOL="Write" ;;
|
|
39
|
+
esac
|
|
40
|
+
;;
|
|
41
|
+
*)
|
|
42
|
+
exit 0
|
|
43
|
+
;;
|
|
44
|
+
esac
|
|
45
|
+
|
|
46
|
+
[[ -f "$CORE_HOOK" ]] || exit 0
|
|
47
|
+
|
|
48
|
+
# Build input Cursor-format. NotebookEdit: notebook_path → target_notebook (field hooks gốc parse).
|
|
49
|
+
CURSOR_INPUT=$(echo "$INPUT_JSON" | jq --arg tool "$MAPPED_TOOL" --arg cwd "$CWD" '{
|
|
50
|
+
tool_name: $tool,
|
|
51
|
+
tool_input: ((.tool_input // {}) + (if (.tool_input.notebook_path // "") != "" then {target_notebook: .tool_input.notebook_path} else {} end)),
|
|
52
|
+
workspace_roots: [$cwd]
|
|
53
|
+
}')
|
|
54
|
+
|
|
55
|
+
CORE_OUTPUT=$(echo "$CURSOR_INPUT" | bash "$CORE_HOOK" 2>/dev/null || echo '{"permission": "allow"}')
|
|
56
|
+
|
|
57
|
+
PERMISSION=$(echo "$CORE_OUTPUT" | jq -r '.permission // "allow"' 2>/dev/null || echo "allow")
|
|
58
|
+
|
|
59
|
+
if [[ "$PERMISSION" == "deny" ]]; then
|
|
60
|
+
echo "$CORE_OUTPUT" | jq '{
|
|
61
|
+
hookSpecificOutput: {
|
|
62
|
+
hookEventName: "PreToolUse",
|
|
63
|
+
permissionDecision: "deny",
|
|
64
|
+
permissionDecisionReason: (.agent_message // "Blocked by OpenMoneta Dev Kit hook.")
|
|
65
|
+
}
|
|
66
|
+
}'
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
exit 0
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# sessionstart-adapter.sh — Claude Code SessionStart → core/inject-process-context.sh.
|
|
3
|
+
#
|
|
4
|
+
# Khác Cursor 2 điểm chủ đích:
|
|
5
|
+
# 1. CHỈ reset markers (.docs-index-read / .decisions-read) khi source = startup|clear.
|
|
6
|
+
# Claude Code còn fire SessionStart ở resume/compact GIỮA phiên làm việc — reset lúc đó
|
|
7
|
+
# sẽ chặn oan agent đang làm dở task.
|
|
8
|
+
# 2. KHÔNG inject lại full quy trình 6 bước (OPENMONETA_SKIP_SUMMARY=1) — project đã nạp
|
|
9
|
+
# quy trình qua CLAUDE.md → @AGENTS.md, inject nữa là nạp đôi tốn token.
|
|
10
|
+
# Chỉ output update notice (nếu có) — stdout của SessionStart được đưa vào context.
|
|
11
|
+
|
|
12
|
+
set -euo pipefail
|
|
13
|
+
|
|
14
|
+
INPUT_JSON=$(cat 2>/dev/null || echo '{}')
|
|
15
|
+
command -v jq >/dev/null 2>&1 || exit 0
|
|
16
|
+
|
|
17
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
18
|
+
CORE_DIR="${OPENMONETA_CORE_HOOKS:-$SCRIPT_DIR/core}"
|
|
19
|
+
CORE_HOOK="$CORE_DIR/inject-process-context.sh"
|
|
20
|
+
[[ -f "$CORE_HOOK" ]] || exit 0
|
|
21
|
+
|
|
22
|
+
CWD=$(echo "$INPUT_JSON" | jq -r '.cwd // ""')
|
|
23
|
+
SOURCE=$(echo "$INPUT_JSON" | jq -r '.source // "startup"')
|
|
24
|
+
[[ -z "$CWD" ]] && exit 0
|
|
25
|
+
|
|
26
|
+
case "$SOURCE" in
|
|
27
|
+
startup|clear) ;;
|
|
28
|
+
*) exit 0 ;; # resume|compact: giữ nguyên markers, không inject gì thêm
|
|
29
|
+
esac
|
|
30
|
+
|
|
31
|
+
CLAUDE_HOME="${OPENMONETA_HOME:-$HOME/.claude}"
|
|
32
|
+
|
|
33
|
+
CURSOR_INPUT=$(jq -n --arg cwd "$CWD" '{workspace_roots: [$cwd]}')
|
|
34
|
+
|
|
35
|
+
# Core hook: reset markers + auto-register registry (~/.claude/.openmoneta-projects)
|
|
36
|
+
# + check update notice (cache 24h). SKIP_SUMMARY để không nạp đôi quy trình.
|
|
37
|
+
CORE_OUTPUT=$(echo "$CURSOR_INPUT" | OPENMONETA_HOME="$CLAUDE_HOME" OPENMONETA_SKIP_SUMMARY=1 bash "$CORE_HOOK" 2>/dev/null || echo '{}')
|
|
38
|
+
|
|
39
|
+
NOTICE=$(echo "$CORE_OUTPUT" | jq -r '.additional_context // ""' 2>/dev/null || echo "")
|
|
40
|
+
if [[ -n "$NOTICE" ]]; then
|
|
41
|
+
printf '%s\n' "$NOTICE"
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
exit 0
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# stop-adapter.sh — Claude Code Stop → core/verify-completion.sh (block cứng như Cursor).
|
|
3
|
+
#
|
|
4
|
+
# verify-completion.sh nhận loop_count từ harness Cursor; Claude Code không có sẵn nên
|
|
5
|
+
# adapter tự đếm qua state file key theo session_id (2 session song song đếm độc lập):
|
|
6
|
+
# <workspace>/.cursor/.claude-stop-loop-<session_id>.json
|
|
7
|
+
# Pass → xóa state. Fail → tăng count; core hook tự graceful escape khi count >= 4.
|
|
8
|
+
#
|
|
9
|
+
# Output khi block: {"decision": "block", "reason": ...} — Claude tiếp tục làm việc.
|
|
10
|
+
|
|
11
|
+
set -euo pipefail
|
|
12
|
+
|
|
13
|
+
INPUT_JSON=$(cat 2>/dev/null || echo '{}')
|
|
14
|
+
command -v jq >/dev/null 2>&1 || exit 0
|
|
15
|
+
|
|
16
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
17
|
+
CORE_DIR="${OPENMONETA_CORE_HOOKS:-$SCRIPT_DIR/core}"
|
|
18
|
+
CORE_HOOK="$CORE_DIR/verify-completion.sh"
|
|
19
|
+
[[ -f "$CORE_HOOK" ]] || exit 0
|
|
20
|
+
|
|
21
|
+
CWD=$(echo "$INPUT_JSON" | jq -r '.cwd // ""')
|
|
22
|
+
SESSION_ID=$(echo "$INPUT_JSON" | jq -r '.session_id // "default"')
|
|
23
|
+
STOP_HOOK_ACTIVE=$(echo "$INPUT_JSON" | jq -r '.stop_hook_active // false')
|
|
24
|
+
[[ -z "$CWD" ]] && exit 0
|
|
25
|
+
|
|
26
|
+
# Sanitize session_id cho tên file.
|
|
27
|
+
SESSION_KEY=$(printf '%s' "$SESSION_ID" | tr -c 'a-zA-Z0-9_-' '_')
|
|
28
|
+
STATE_FILE="$CWD/.cursor/.claude-stop-loop-${SESSION_KEY}.json"
|
|
29
|
+
|
|
30
|
+
LOOP_COUNT=0
|
|
31
|
+
if [[ "$STOP_HOOK_ACTIVE" == "true" && -f "$STATE_FILE" ]]; then
|
|
32
|
+
LOOP_COUNT=$(jq -r '.count // 0' "$STATE_FILE" 2>/dev/null || echo 0)
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
CURSOR_INPUT=$(jq -n --arg cwd "$CWD" --argjson lc "$LOOP_COUNT" '{
|
|
36
|
+
workspace_roots: [$cwd],
|
|
37
|
+
loop_count: $lc
|
|
38
|
+
}')
|
|
39
|
+
|
|
40
|
+
# OPENMONETA_HOME=~/.claude để core hook tìm scripts/list-affected-modules.sh
|
|
41
|
+
# trong claude home (máy chỉ có Claude Code không có ~/.cursor/scripts).
|
|
42
|
+
CORE_OUTPUT=$(echo "$CURSOR_INPUT" | OPENMONETA_HOME="${OPENMONETA_HOME:-$HOME/.claude}" bash "$CORE_HOOK" 2>/dev/null || echo '{"continue": true}')
|
|
43
|
+
|
|
44
|
+
# Lưu ý: KHÔNG dùng `.continue // true` — toán tử `//` của jq coi `false` như null
|
|
45
|
+
# nên `false // true` ra `true` (mất tín hiệu block).
|
|
46
|
+
CONTINUE=$(echo "$CORE_OUTPUT" | jq -r 'if .continue == false then "false" else "true" end' 2>/dev/null || echo "true")
|
|
47
|
+
|
|
48
|
+
if [[ "$CONTINUE" == "false" ]]; then
|
|
49
|
+
mkdir -p "$CWD/.cursor"
|
|
50
|
+
jq -n --argjson c "$((LOOP_COUNT + 1))" '{count: $c}' > "$STATE_FILE" 2>/dev/null || true
|
|
51
|
+
echo "$CORE_OUTPUT" | jq '{
|
|
52
|
+
decision: "block",
|
|
53
|
+
reason: (.followup_message // "Session chưa hoàn tất theo quy trình OpenMoneta (Bước 5).")
|
|
54
|
+
}'
|
|
55
|
+
exit 0
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
# Pass → dọn state để session sau đếm lại từ 0.
|
|
59
|
+
rm -f "$STATE_FILE" 2>/dev/null || true
|
|
60
|
+
exit 0
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"hooks": {
|
|
3
|
+
"SessionStart": [
|
|
4
|
+
{
|
|
5
|
+
"hooks": [
|
|
6
|
+
{
|
|
7
|
+
"type": "command",
|
|
8
|
+
"command": "bash \"$HOME/.claude/hooks/openmoneta/sessionstart-adapter.sh\""
|
|
9
|
+
}
|
|
10
|
+
]
|
|
11
|
+
}
|
|
12
|
+
],
|
|
13
|
+
"PreToolUse": [
|
|
14
|
+
{
|
|
15
|
+
"matcher": "Read|Glob|Grep|Write|Edit|NotebookEdit",
|
|
16
|
+
"hooks": [
|
|
17
|
+
{
|
|
18
|
+
"type": "command",
|
|
19
|
+
"command": "bash \"$HOME/.claude/hooks/openmoneta/pretooluse-adapter.sh\""
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"matcher": "Bash",
|
|
25
|
+
"hooks": [
|
|
26
|
+
{
|
|
27
|
+
"type": "command",
|
|
28
|
+
"command": "bash \"$HOME/.claude/hooks/openmoneta/bash-guard.sh\""
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
],
|
|
33
|
+
"PostToolUse": [
|
|
34
|
+
{
|
|
35
|
+
"matcher": "Write|Edit|NotebookEdit",
|
|
36
|
+
"hooks": [
|
|
37
|
+
{
|
|
38
|
+
"type": "command",
|
|
39
|
+
"command": "bash \"$HOME/.claude/hooks/openmoneta/posttooluse-adapter.sh\""
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
],
|
|
44
|
+
"Stop": [
|
|
45
|
+
{
|
|
46
|
+
"hooks": [
|
|
47
|
+
{
|
|
48
|
+
"type": "command",
|
|
49
|
+
"command": "bash \"$HOME/.claude/hooks/openmoneta/stop-adapter.sh\""
|
|
50
|
+
}
|
|
51
|
+
]
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
}
|
|
55
|
+
}
|