@synity/bitrix-skills 1.3.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 +169 -0
- package/LICENSE +21 -0
- package/README.md +83 -0
- package/bin/bitrix-skills.js +3 -0
- package/dist/cli.js +1510 -0
- package/dist/features/bx-task/install.js +111 -0
- package/dist/features/task-sync/index.js +1053 -0
- package/package.json +69 -0
- package/src/features/bx/assets/SKILL.md +34 -0
- package/src/features/bx/feature.json +8 -0
- package/src/features/bx-calendar/assets/SKILL.md +61 -0
- package/src/features/bx-calendar/assets/availability.md +65 -0
- package/src/features/bx-calendar/assets/meeting.md +87 -0
- package/src/features/bx-calendar/assets/reminder.md +71 -0
- package/src/features/bx-calendar/assets/sync.md +70 -0
- package/src/features/bx-calendar/feature.json +10 -0
- package/src/features/bx-crm/assets/SKILL.md +59 -0
- package/src/features/bx-crm/assets/commerce.md +96 -0
- package/src/features/bx-crm/assets/onboard.md +127 -0
- package/src/features/bx-crm/assets/report.md +98 -0
- package/src/features/bx-crm/assets/research.md +71 -0
- package/src/features/bx-crm/feature.json +10 -0
- package/src/features/bx-task/assets/SKILL.md +148 -0
- package/src/features/bx-task/assets/lib/bx-api.sh +39 -0
- package/src/features/bx-task/assets/lib/bx-checklist.sh +127 -0
- package/src/features/bx-task/assets/lib/bx-resolve-task.sh +41 -0
- package/src/features/bx-task/assets/lib/bx-state.sh +131 -0
- package/src/features/bx-task/assets/lib/bx-tasks.sh +109 -0
- package/src/features/bx-task/assets/references/bootstrap.md +184 -0
- package/src/features/bx-task/assets/references/feature.md +97 -0
- package/src/features/bx-task/assets/references/init-templates/cli-tool.md +47 -0
- package/src/features/bx-task/assets/references/init-templates/generic.md +31 -0
- package/src/features/bx-task/assets/references/init-templates/library.md +45 -0
- package/src/features/bx-task/assets/references/init-templates/monorepo.md +38 -0
- package/src/features/bx-task/assets/references/init-templates/npm-package.md +40 -0
- package/src/features/bx-task/assets/references/init-templates/web-app.md +46 -0
- package/src/features/bx-task/assets/references/init.md +107 -0
- package/src/features/bx-task/assets/references/roadmap.md +93 -0
- package/src/features/bx-task/assets/references/summary.md +269 -0
- package/src/features/bx-task/assets/references/sync.md +104 -0
- package/src/features/bx-task/assets/references/time-log.md +214 -0
- package/src/features/bx-task/feature.json +10 -0
- package/src/features/bx-task/install.ts +117 -0
- package/src/features/task-sync/assets/docs/bitrix-task-reference.md +318 -0
- package/src/features/task-sync/assets/docs/bitrix-task-sync.md +254 -0
- package/src/features/task-sync/assets/githooks/commit-msg +44 -0
- package/src/features/task-sync/assets/githooks/install.sh +15 -0
- package/src/features/task-sync/assets/manifest.json +108 -0
- package/src/features/task-sync/assets/rules/00-bitrix-task-sync.md +161 -0
- package/src/features/task-sync/assets/scripts/bitrix-attach-files.sh +55 -0
- package/src/features/task-sync/assets/scripts/bitrix-lib.sh +540 -0
- package/src/features/task-sync/assets/scripts/bitrix-render-digest.sh +116 -0
- package/src/features/task-sync/assets/scripts/bitrix-session-check.sh +51 -0
- package/src/features/task-sync/assets/scripts/bitrix-session-sync.sh +89 -0
- package/src/features/task-sync/assets/scripts/bitrix-skill-end.sh +165 -0
- package/src/features/task-sync/assets/scripts/bitrix-skill-start.sh +58 -0
- package/src/features/task-sync/assets/scripts/lib/bb-formatter.sh +110 -0
- package/src/features/task-sync/assets/scripts/lib/bitrix-lib.sh +540 -0
- package/src/features/task-sync/assets/scripts/lib/time-helpers.sh +57 -0
- package/src/features/task-sync/assets/workflows/bitrix-sync.yml +85 -0
- package/src/features/task-sync/commands/install.ts +296 -0
- package/src/features/task-sync/commands/uninstall.ts +189 -0
- package/src/features/task-sync/commands/update.ts +11 -0
- package/src/features/task-sync/commands/verify.ts +141 -0
- package/src/features/task-sync/feature.json +12 -0
- package/src/features/task-sync/index.ts +121 -0
- package/src/features/task-sync/lib/dest-map.ts +96 -0
- package/src/features/task-sync/lib/drift-check.ts +47 -0
- package/src/features/task-sync/lib/file-ops.ts +36 -0
- package/src/features/task-sync/lib/manifest.ts +66 -0
- package/src/features/task-sync/lib/project-root.ts +38 -0
- package/src/features/task-sync/lib/settings-merge.ts +112 -0
- package/src/features/task-sync/lib/skill-refs.ts +106 -0
- package/src/features/task-sync/lib/task-id-finder.ts +31 -0
- package/src/features/task-sync/lib/token-extractor.ts +52 -0
- package/src/features/task-sync/lib/version.ts +36 -0
- package/src/features/task-sync/types.ts +40 -0
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
# Bitrix Task Sync — Setup Guide
|
|
2
|
+
|
|
3
|
+
> **Recommended for brownfield projects:** Install via `npx @synity/bitrix-task-sync install` (see [packages/bitrix-task-sync/README.md](../packages/bitrix-task-sync/README.md)).
|
|
4
|
+
> Manual steps below for greenfield setup or reference.
|
|
5
|
+
>
|
|
6
|
+
> Quy trình bắt buộc: [.claude/rules/00-bitrix-task-sync.md](../.claude/rules/00-bitrix-task-sync.md)
|
|
7
|
+
> Reference cho agent (fields, hierarchy, checklist API): [bitrix-task-reference.md](bitrix-task-reference.md)
|
|
8
|
+
|
|
9
|
+
## Yêu cầu
|
|
10
|
+
|
|
11
|
+
- `curl` và `jq` đã cài trên máy dev
|
|
12
|
+
- Quyền tạo Incoming Webhook trên Bitrix24 portal (hoặc xin từ admin)
|
|
13
|
+
|
|
14
|
+
## Phân công Webhook vs MCP
|
|
15
|
+
|
|
16
|
+
| Mục đích | Công cụ |
|
|
17
|
+
|----------|---------|
|
|
18
|
+
| Hook tự động post comment / log time khi skill chạy | curl + Incoming Webhook → `bitrix-lib.sh` |
|
|
19
|
+
| GitHub Action post commit/PR notification | curl + Incoming Webhook (`BITRIX_WEBHOOK_URL` secret) |
|
|
20
|
+
| Agent query task data trong session | `bitrix-synity-mcp` |
|
|
21
|
+
| Agent sync plan phases → Bitrix checklist | `b24_sync_checklist()` — xem [reference §5](bitrix-task-reference.md#5-checklist-sync-api-plan-phases-bitrix) |
|
|
22
|
+
|
|
23
|
+
Shell scripts (hooks) không thể gọi MCP — MCP chỉ available trong Claude Code context.
|
|
24
|
+
|
|
25
|
+
## 1. Tạo Bitrix Incoming Webhook
|
|
26
|
+
|
|
27
|
+
1. Mở Bitrix24 portal → **Applications** → **Webhooks** → **Add Incoming Webhook**
|
|
28
|
+
2. Scope cần cấp: `task` (đọc/ghi task + comment + time log)
|
|
29
|
+
3. Copy URL dạng: `https://xxx.bitrix24.com/rest/1/abc123token/`
|
|
30
|
+
|
|
31
|
+
## 2. Set env var trên máy dev
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# ~/.zshrc hoặc ~/.bashrc
|
|
35
|
+
export BITRIX_WEBHOOK_URL="https://xxx.bitrix24.com/rest/1/abc123token/"
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Reload shell: `source ~/.zshrc`
|
|
39
|
+
|
|
40
|
+
Verify: `echo $BITRIX_WEBHOOK_URL`
|
|
41
|
+
|
|
42
|
+
## 3. Cấp quyền execute cho hook scripts
|
|
43
|
+
|
|
44
|
+
Chạy 1 lần sau khi clone repo:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
chmod +x .claude/scripts/bitrix-*.sh
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## 4. Thêm Task ID vào CLAUDE.md của project
|
|
51
|
+
|
|
52
|
+
Đặt ở root project hoặc feature folder — hook tự walk up để tìm. Feature folder override root.
|
|
53
|
+
|
|
54
|
+
```markdown
|
|
55
|
+
## Bitrix Task
|
|
56
|
+
PORTAL: https://xxx.bitrix24.com # optional — agent dùng để build link
|
|
57
|
+
GROUP_ID: 106 # optional — Bitrix Project/Workgroup ID (from URL /workgroups/group/{ID}/)
|
|
58
|
+
TASK_ID: 67890 # bắt buộc — hooks parse field này
|
|
59
|
+
CREATOR_ID: 6 # optional — agent dùng khi tạo task mới (default portal tamgiac: 6)
|
|
60
|
+
RESPONSIBLE_ID: 29 # optional — agent dùng khi assign; null → hỏi user
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Parent task không cần khai báo — Bitrix đã lưu quan hệ parent/child trong task.
|
|
64
|
+
|
|
65
|
+
## 5. GitHub Actions — sync commit về Bitrix
|
|
66
|
+
|
|
67
|
+
Thêm secret vào GitHub repo settings:
|
|
68
|
+
- Key: `BITRIX_WEBHOOK_URL`
|
|
69
|
+
- Value: Incoming Webhook URL ở bước 1
|
|
70
|
+
|
|
71
|
+
Copy workflow template vào project:
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
packages/create-bitrix-app/templates/.github/workflows/bitrix-sync.yml
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
→ Đặt vào: `.github/workflows/bitrix-sync.yml`
|
|
78
|
+
|
|
79
|
+
Workflow gồm 2 job:
|
|
80
|
+
- `preflight` — verify secret tồn tại + format URL hợp lệ. Thiếu/sai format → fail rõ ràng qua `::error::` annotation.
|
|
81
|
+
- `notify-bitrix` (`needs: preflight`) — parse `[B24:nnn]` từ PR body / branch name, post message vào task chat.
|
|
82
|
+
|
|
83
|
+
Format URL secret bắt buộc: `https://<portal>.bitrix24.<tld>/rest/<user_id>/<token>/`
|
|
84
|
+
|
|
85
|
+
## 6. Verify hoạt động
|
|
86
|
+
|
|
87
|
+
### Test hooks thủ công
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
# Simulate PreToolUse payload
|
|
91
|
+
echo '{"session_id":"test123","tool_name":"Skill","tool_input":{"skill":"debug","args":"test"}}' \
|
|
92
|
+
| bash .claude/scripts/bitrix-skill-start.sh
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Mở Bitrix task → tab Chat → kiểm tra có comment `🐛 [Claude] debug bắt đầu: test`.
|
|
96
|
+
|
|
97
|
+
### Test session sync
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
echo '{"session_id":"test123"}' | bash .claude/scripts/bitrix-session-sync.sh
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## 7. Commit message format
|
|
104
|
+
|
|
105
|
+
Mọi commit phải có `[B24:TASK_ID]` ở cuối message:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
git commit -m "feat: add crm deal sync [B24:67890]"
|
|
109
|
+
git commit -m "fix: handle rate limit [B24:67890]"
|
|
110
|
+
git commit -m "refactor: extract sync service [B24:67890]"
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## 8. Bật commit-msg hook (enforce Hard Rule #18)
|
|
114
|
+
|
|
115
|
+
Chạy 1 lần sau khi clone:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
bash .githooks/install.sh
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Hook reject commit không có `[B24:\d+]`. Bypass tạm thời (chỉ cho infra/scaffold):
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
ALLOW_NO_B24=1 git commit -m "chore: scaffold"
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Merge / revert / fixup commits được bỏ qua tự động.
|
|
128
|
+
|
|
129
|
+
## 9. SessionStart warning (enforce Hard Rule #17)
|
|
130
|
+
|
|
131
|
+
`SessionStart` hook tự động warn nếu CLAUDE.md không có `TASK_ID`:
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
⚠️ Hard Rule #17 violation: TASK_ID chưa set trong CLAUDE.md
|
|
135
|
+
Bitrix Task Sync sẽ KHÔNG hoạt động trong session này.
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Hook không block — chỉ in stderr. Wired sẵn trong `.claude/settings.json`.
|
|
139
|
+
|
|
140
|
+
## 10. E2E test (live webhook)
|
|
141
|
+
|
|
142
|
+
Test suite gọi webhook Bitrix24 thật để verify hooks end-to-end (skill-start, skill-end, session-sync, checklist parser, commit-msg, session-check).
|
|
143
|
+
|
|
144
|
+
### Yêu cầu
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
export BITRIX_WEBHOOK_URL="https://<portal>.bitrix24.com/rest/<user_id>/<token>/"
|
|
148
|
+
export TEST_TASK_ID=<dedicated-test-task-id>
|
|
149
|
+
export TEST_PORTAL="https://<portal>.bitrix24.com"
|
|
150
|
+
export TEST_USER_ID=<your-user-id>
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
⚠️ Tạo Bitrix task **dedicated cho test** (không dùng task production). Comments + checklist items sẽ được tạo và xóa nhiều lần.
|
|
154
|
+
|
|
155
|
+
### Chạy
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
# Toàn bộ suite
|
|
159
|
+
bash .claude/scripts/tests/e2e-bitrix-sync.sh
|
|
160
|
+
|
|
161
|
+
# Filter theo substring tên case
|
|
162
|
+
bash .claude/scripts/tests/e2e-bitrix-sync.sh case-a
|
|
163
|
+
bash .claude/scripts/tests/e2e-bitrix-sync.sh commit-msg
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Output mẫu
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
Bitrix Sync — E2E Tests
|
|
170
|
+
Webhook: https://tamgiac.bitrix24.com/rest/1/.../
|
|
171
|
+
Task: 2048
|
|
172
|
+
Session: e2e-1715251200-12345
|
|
173
|
+
|
|
174
|
+
Pre-cleanup...
|
|
175
|
+
|
|
176
|
+
Case: case-a-skill-start
|
|
177
|
+
skill-start posts comment to Bitrix
|
|
178
|
+
✓ hook exit 0
|
|
179
|
+
✓ file exists: ...
|
|
180
|
+
✓ state task_id matches
|
|
181
|
+
...
|
|
182
|
+
|
|
183
|
+
Post-cleanup...
|
|
184
|
+
─────────────────────────────
|
|
185
|
+
PASS · 24 assertions
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Khi nào fail
|
|
189
|
+
|
|
190
|
+
- Webhook URL hết hạn → recreate trên portal, update env
|
|
191
|
+
- TASK_ID không tồn tại / không thuộc portal → preflight fail rõ ràng
|
|
192
|
+
- Bitrix API rate limit → retry sau 1 phút
|
|
193
|
+
- case-d skip nếu `bitrix-checklist` parser chưa merge vào `bitrix-skill-end.sh`
|
|
194
|
+
|
|
195
|
+
Chi tiết: [.claude/scripts/tests/README.md](../.claude/scripts/tests/README.md)
|
|
196
|
+
|
|
197
|
+
## Troubleshooting
|
|
198
|
+
|
|
199
|
+
| Vấn đề | Kiểm tra |
|
|
200
|
+
|--------|---------|
|
|
201
|
+
| Không có comment trong Bitrix | `echo $BITRIX_WEBHOOK_URL` — đã set chưa? |
|
|
202
|
+
| Task ID không tìm thấy | `grep -r "TASK_ID" ./CLAUDE.md` |
|
|
203
|
+
| Hook không chạy | `cat .claude/settings.json` — có hook config chưa? |
|
|
204
|
+
| `jq: command not found` | `brew install jq` hoặc `apt install jq` |
|
|
205
|
+
| Webhook 401 error | Webhook token hết hạn — tạo lại trên portal |
|
|
206
|
+
| GitHub Action không trigger | Verify commit message có `[B24:\d+]` đúng format |
|
|
207
|
+
| Comment API 404 / method not found | `task.commentitem.add` deprecated — dùng `tasks.task.chat.message.send` (xem `bitrix-lib.sh`) |
|
|
208
|
+
| commit-msg hook không reject | `git config core.hooksPath` — phải = `.githooks`. Chạy `bash .githooks/install.sh` |
|
|
209
|
+
| SessionStart không warn | Verify `cat .claude/settings.json \| grep SessionStart` |
|
|
210
|
+
|
|
211
|
+
## v0.2 Features
|
|
212
|
+
|
|
213
|
+
### Token Tracking
|
|
214
|
+
|
|
215
|
+
Every session automatically tracks input + output token consumption. Stop hook reads the session transcript JSONL and sums all messages, then writes the total to a `UF_AI_TOKENS_TOTAL` custom field on the task (created on first run). Session digest displays: `🪙 Xk in / Yk out`.
|
|
216
|
+
|
|
217
|
+
**Setup:** No manual action required. The custom field is auto-created on first session with permissions for creator_id.
|
|
218
|
+
|
|
219
|
+
### Time Tracking Lifecycle
|
|
220
|
+
|
|
221
|
+
SessionStart hook automatically enables time tracking (`ALLOW_TIME_TRACKING = true`) on the task. First skill run calls `tasks.task.start` (status → in_progress); last skill run calls `tasks.task.pause`. Uses atomic flock counter to prevent race conditions across multiple concurrent hooks.
|
|
222
|
+
|
|
223
|
+
**Your responsibility:** The task status and elapsed time counter are maintained automatically. If manually closed in Bitrix, Stop hook force-pauses to prevent lingering running state.
|
|
224
|
+
|
|
225
|
+
### File Attachment
|
|
226
|
+
|
|
227
|
+
PostToolUse hook uploads artifact files (`.md`) for skills: plan, brainstorm, cook. Looks for a `\`\`\`bitrix-artifact\`\`\`` block in skill output with metadata:
|
|
228
|
+
```json
|
|
229
|
+
{
|
|
230
|
+
"path": "plans/260510-0247-feature-name/plan.md",
|
|
231
|
+
"title": "Feature Plan"
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Files upload to **Bitrix Drive** (scope: group or user). The `verify` command now reports detected disk scope.
|
|
236
|
+
|
|
237
|
+
**Your responsibility:** Skills that emit artifact blocks must specify valid file paths relative to repo root. Files must exist on disk before upload.
|
|
238
|
+
|
|
239
|
+
### Session Digest
|
|
240
|
+
|
|
241
|
+
Stop hook renders a comprehensive digest combining:
|
|
242
|
+
- Plan phase progress (if active plan detected)
|
|
243
|
+
- All skills run (with emoji, duration, result preview)
|
|
244
|
+
- Token consumption line
|
|
245
|
+
- Attached files list
|
|
246
|
+
- Recent commits matching `[B24:TASK_ID]`
|
|
247
|
+
- Task link (clickable)
|
|
248
|
+
|
|
249
|
+
Rendered via pure bash + `bitrix-render-digest.sh` (no external dependencies). Digest posted as single comment to task chat.
|
|
250
|
+
|
|
251
|
+
## Tiếp theo
|
|
252
|
+
|
|
253
|
+
- Agent runtime cần đọc field/hierarchy/epic/checklist API → [bitrix-task-reference.md](bitrix-task-reference.md)
|
|
254
|
+
- Quy trình bắt buộc + NEVER/ALWAYS → [.claude/rules/00-bitrix-task-sync.md](../.claude/rules/00-bitrix-task-sync.md)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# commit-msg hook — enforces Hard Rule #18: every commit must include [B24:<task-id>]
|
|
3
|
+
# Bypass: ALLOW_NO_B24=1 git commit -m "..." (chỉ dùng cho infra/scaffold trước khi có TASK_ID)
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
MSG_FILE="$1"
|
|
8
|
+
MSG=$(cat "$MSG_FILE")
|
|
9
|
+
|
|
10
|
+
# Skip merge / revert / fixup auto-messages
|
|
11
|
+
case "$MSG" in
|
|
12
|
+
Merge\ *|Revert\ *|fixup!\ *|squash!\ *|amend!\ *) exit 0 ;;
|
|
13
|
+
esac
|
|
14
|
+
|
|
15
|
+
# Allow explicit bypass via env var (logs to stderr)
|
|
16
|
+
if [[ "${ALLOW_NO_B24:-0}" == "1" ]]; then
|
|
17
|
+
echo "[commit-msg] ALLOW_NO_B24=1 — skipping [B24:nnn] check" >&2
|
|
18
|
+
exit 0
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
# Match [B24:123] anywhere in message (subject or body)
|
|
22
|
+
if echo "$MSG" | grep -qE '\[B24:[0-9]+\]'; then
|
|
23
|
+
exit 0
|
|
24
|
+
fi
|
|
25
|
+
|
|
26
|
+
cat >&2 <<EOF
|
|
27
|
+
|
|
28
|
+
❌ Hard Rule #18 violation: commit message thiếu [B24:<task-id>]
|
|
29
|
+
|
|
30
|
+
Format yêu cầu:
|
|
31
|
+
feat: mô tả ngắn [B24:12345]
|
|
32
|
+
fix: bug X [B24:12345]
|
|
33
|
+
|
|
34
|
+
Cách fix:
|
|
35
|
+
1. Đọc TASK_ID từ CLAUDE.md (root hoặc feature folder)
|
|
36
|
+
2. Sửa commit message hiện tại bằng:
|
|
37
|
+
git commit --amend
|
|
38
|
+
3. Hoặc bypass tạm thời (chỉ cho infra/scaffold):
|
|
39
|
+
ALLOW_NO_B24=1 git commit -m "..."
|
|
40
|
+
|
|
41
|
+
Setup chi tiết: docs/bitrix-task-sync.md
|
|
42
|
+
EOF
|
|
43
|
+
|
|
44
|
+
exit 1
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Install .githooks/* as the active git hook path for this repo.
|
|
3
|
+
# Run once per clone: bash .githooks/install.sh
|
|
4
|
+
set -e
|
|
5
|
+
|
|
6
|
+
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null) || {
|
|
7
|
+
echo "Error: not a git repository" >&2
|
|
8
|
+
exit 1
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
cd "$REPO_ROOT"
|
|
12
|
+
git config core.hooksPath .githooks
|
|
13
|
+
echo "✓ git core.hooksPath = .githooks"
|
|
14
|
+
echo " Active hooks:"
|
|
15
|
+
ls -1 .githooks | grep -v '^install\.sh$' | sed 's/^/ /'
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "0.3.0-pre",
|
|
3
|
+
"generatedAt": "2026-05-11T08:35:30.111Z",
|
|
4
|
+
"files": [
|
|
5
|
+
{
|
|
6
|
+
"src": "docs/bitrix-task-reference.md",
|
|
7
|
+
"sha256": "4f36e961f85012ce7cf29b5f655e005ea2625c62140e7fabf804d9c0a907a646",
|
|
8
|
+
"size": 13309,
|
|
9
|
+
"mode": 420
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"src": "docs/bitrix-task-sync.md",
|
|
13
|
+
"sha256": "7775183fe22fc2062d80efecd3e5a00f21ba82a17251231b7d60e1a819f3bbdf",
|
|
14
|
+
"size": 9441,
|
|
15
|
+
"mode": 420
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"src": "githooks/commit-msg",
|
|
19
|
+
"sha256": "de51341fbbdde7ccc48c626f3d33b4fff574f71fb7d7e4dba2605afe17cf89b6",
|
|
20
|
+
"size": 1147,
|
|
21
|
+
"mode": 493
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"src": "githooks/install.sh",
|
|
25
|
+
"sha256": "400f38ab13bf3561f75d0680bc7c7c8b2b86ce601a1f9b297b71a7c12bf9c79f",
|
|
26
|
+
"size": 423,
|
|
27
|
+
"mode": 493
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"src": "rules/00-bitrix-task-sync.md",
|
|
31
|
+
"sha256": "8aeebf844c49e8a483ad838e6458cad5b8c8fbe7bf87a6e159169f819e1cf7e9",
|
|
32
|
+
"size": 7396,
|
|
33
|
+
"mode": 420
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"src": "scripts/bitrix-attach-files.sh",
|
|
37
|
+
"sha256": "6cc520367e5b0d32da39a63a37f509e6f9908d36d03bbbc47a86c9df7d2e53aa",
|
|
38
|
+
"size": 1597,
|
|
39
|
+
"mode": 493
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"src": "scripts/bitrix-lib.sh",
|
|
43
|
+
"sha256": "bd9340cb3664ec8cf4def21e26cb2ac671e182663b1d05599b2f492a962f05aa",
|
|
44
|
+
"size": 19831,
|
|
45
|
+
"mode": 493
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"src": "scripts/bitrix-render-digest.sh",
|
|
49
|
+
"sha256": "4bcb8dd33405e76a6e11a3adc6e252e10f384292a13fcb10976d35837c1e7869",
|
|
50
|
+
"size": 4593,
|
|
51
|
+
"mode": 493
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"src": "scripts/bitrix-session-check.sh",
|
|
55
|
+
"sha256": "a505cb5989385b8d3fe4a88cffc4e529b4f624e87c37bdd30f5d57977648bfbb",
|
|
56
|
+
"size": 1593,
|
|
57
|
+
"mode": 493
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"src": "scripts/bitrix-session-sync.sh",
|
|
61
|
+
"sha256": "8438bb873d1f494620c8a6303a93940c2565100056a4ef78a1b225ea53728a2e",
|
|
62
|
+
"size": 3352,
|
|
63
|
+
"mode": 493
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"src": "scripts/bitrix-skill-end.sh",
|
|
67
|
+
"sha256": "fa45949889b9d0eac59ff7513cf9716097ba9c9276b4623245e7010410da1b33",
|
|
68
|
+
"size": 5891,
|
|
69
|
+
"mode": 493
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"src": "scripts/bitrix-skill-start.sh",
|
|
73
|
+
"sha256": "ae60b1278bcc89743c2bea2efa674f28ea7095e6f33abde50fc9c0e5e66965ba",
|
|
74
|
+
"size": 2013,
|
|
75
|
+
"mode": 493
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"src": "scripts/lib/bb-formatter.sh",
|
|
79
|
+
"sha256": "cda67373549b02a635d748648180fbcea56c38988b2bd3dc5e6a384254a4b7d0",
|
|
80
|
+
"size": 3098,
|
|
81
|
+
"mode": 493
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"src": "scripts/lib/bitrix-lib.sh",
|
|
85
|
+
"sha256": "bd9340cb3664ec8cf4def21e26cb2ac671e182663b1d05599b2f492a962f05aa",
|
|
86
|
+
"size": 19831,
|
|
87
|
+
"mode": 493
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"src": "scripts/lib/time-helpers.sh",
|
|
91
|
+
"sha256": "6c25ad1e32307147bee383ce34681a5ba5910d2c8a1ab83e4a00161dae41e774",
|
|
92
|
+
"size": 1371,
|
|
93
|
+
"mode": 493
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"src": "workflows/bitrix-sync.yml",
|
|
97
|
+
"sha256": "2eb583e6cad3d2c076994e5e3f477f8b653c1a510b29e5cf7056aa399fe57f9f",
|
|
98
|
+
"size": 3291,
|
|
99
|
+
"mode": 420
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"src": "skill/SKILL.md",
|
|
103
|
+
"sha256": "e9e4072710b43695354b4d1d31d002625778e8f1330b4e5666d0c0f9d6cd2303",
|
|
104
|
+
"size": 5208,
|
|
105
|
+
"mode": 420
|
|
106
|
+
}
|
|
107
|
+
]
|
|
108
|
+
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# Bitrix Task Sync — AI Workflow Protocol
|
|
2
|
+
|
|
3
|
+
> Quy trình bắt buộc cho mọi nhân sự Synity.
|
|
4
|
+
> Mục tiêu: toàn bộ quá trình phát triển với AI được lưu vào Bitrix Task
|
|
5
|
+
> để tracking timeline, không mất sau khi kết thúc session.
|
|
6
|
+
> Setup hooks: [docs/bitrix-task-sync.md](../../docs/bitrix-task-sync.md)
|
|
7
|
+
> Agent reference (fields/hierarchy/checklist API): [docs/bitrix-task-reference.md](../../docs/bitrix-task-reference.md)
|
|
8
|
+
|
|
9
|
+
## Tại sao bắt buộc
|
|
10
|
+
|
|
11
|
+
Khi làm việc với AI (brainstorm, research, cook, debug...):
|
|
12
|
+
- Kết quả chỉ tồn tại trong session chat → mất sau khi đóng
|
|
13
|
+
- Không có timeline cụ thể trong Bitrix → progress mơ hồ
|
|
14
|
+
- Không tracking được thời gian thực tế AI đã làm gì
|
|
15
|
+
|
|
16
|
+
Giải pháp: hooks tự động sync mọi AI activity → Bitrix Task chat.
|
|
17
|
+
|
|
18
|
+
## Phân công giữa Webhook và MCP
|
|
19
|
+
|
|
20
|
+
| Mục đích | Công cụ |
|
|
21
|
+
|----------|---------|
|
|
22
|
+
| Hook auto-post comment / log time khi skill chạy | curl + Incoming Webhook (`BITRIX_WEBHOOK_URL`) |
|
|
23
|
+
| GitHub Action post commit/PR notification | curl + Incoming Webhook (`BITRIX_WEBHOOK_URL` secret) |
|
|
24
|
+
| Agent query task data trong session | `bitrix-synity-mcp` |
|
|
25
|
+
|
|
26
|
+
Shell scripts (hooks) không thể gọi MCP — MCP chỉ available trong Claude Code context.
|
|
27
|
+
|
|
28
|
+
## Cơ chế hoạt động
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
Skill chạy (brainstorm/research/cook/debug/fix/review/plan)
|
|
32
|
+
│
|
|
33
|
+
├── PreToolUse hook → curl → Bitrix: "bắt đầu" + args
|
|
34
|
+
├── [Skill thực thi]
|
|
35
|
+
├── PostToolUse hook → curl → Bitrix: kết quả preview + log time
|
|
36
|
+
└── Stop hook → curl → Bitrix: session summary (tất cả skills + tổng giờ)
|
|
37
|
+
|
|
38
|
+
git push (commit có [B24:TASK_ID])
|
|
39
|
+
└── GitHub Action → curl → Bitrix: link commit/PR vào task chat
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## NEVER
|
|
43
|
+
|
|
44
|
+
- `NEVER` bắt đầu AI work session mà không có TASK_ID trong CLAUDE.md
|
|
45
|
+
- `NEVER` push commit mà không có `[B24:{TASK_ID}]` trong message
|
|
46
|
+
- `NEVER` tắt hooks Bitrix sync khi làm việc trên dự án Synity
|
|
47
|
+
- `NEVER` dùng TASK_ID của task khác — mỗi feature → đúng task của nó
|
|
48
|
+
- `NEVER` dùng curl/incoming webhook khi agent cần query task data — dùng `bitrix-synity-mcp`
|
|
49
|
+
|
|
50
|
+
## ALWAYS
|
|
51
|
+
|
|
52
|
+
- `ALWAYS` đặt TASK_ID trong CLAUDE.md trước khi bắt đầu session
|
|
53
|
+
- `ALWAYS` dùng format commit: `feat: mô tả [B24:{TASK_ID}]`
|
|
54
|
+
- `ALWAYS` đảm bảo env var `BITRIX_WEBHOOK_URL` được set trên máy dev (hooks dùng curl)
|
|
55
|
+
- `ALWAYS` dùng `bitrix-synity-mcp` khi agent cần query/đọc task data trong session
|
|
56
|
+
- `ALWAYS` verify Bitrix task nhận được comment sau session kết thúc
|
|
57
|
+
|
|
58
|
+
## CLAUDE.md Format — Task ID per project/feature
|
|
59
|
+
|
|
60
|
+
Root project CLAUDE.md:
|
|
61
|
+
```markdown
|
|
62
|
+
## Bitrix Task
|
|
63
|
+
PORTAL: https://xxx.bitrix24.com
|
|
64
|
+
GROUP_ID: 106
|
|
65
|
+
TASK_ID: 12345
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Feature folder (`apps/my-app/features/{feature-name}/CLAUDE.md`) override root:
|
|
69
|
+
```markdown
|
|
70
|
+
## Bitrix Task
|
|
71
|
+
TASK_ID: 67890
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Hook đọc từ thư mục hiện tại, walk up cho đến khi tìm được `TASK_ID`.
|
|
75
|
+
Parent task không cần khai báo — Bitrix đã lưu quan hệ parent/child trong task.
|
|
76
|
+
|
|
77
|
+
## Commit Message Format
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
feat: implement crm deal sync webhook [B24:67890]
|
|
81
|
+
fix: handle 429 rate limit on deal batch [B24:67890]
|
|
82
|
+
refactor: extract sync service to dedicated module [B24:67890]
|
|
83
|
+
docs: update crm-sync setup guide [B24:67890]
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
`67890` = TASK_ID trong CLAUDE.md của feature đang làm.
|
|
87
|
+
GitHub Action tự parse `[B24:\d+]` → post link commit/PR vào Bitrix task chat.
|
|
88
|
+
|
|
89
|
+
## Skill → Bitrix Comment Mapping
|
|
90
|
+
|
|
91
|
+
Format thống nhất do `bitrix-skill-start.sh` / `bitrix-skill-end.sh` sinh:
|
|
92
|
+
- Bắt đầu: `${EMOJI} [Claude] ${skill} bắt đầu: ${args}`
|
|
93
|
+
- Xong: `${EMOJI} [Claude] ${skill} xong (Xm)\n\n${result_preview_1500_chars}`
|
|
94
|
+
|
|
95
|
+
PostToolUse cũng log elapsed minutes vào `task.elapseditem.add` (rounded up, min 1 phút).
|
|
96
|
+
|
|
97
|
+
| Skill | Emoji | Bắt đầu | Xong |
|
|
98
|
+
|-------|:-----:|---------|------|
|
|
99
|
+
| brainstorm | 🧠 | brainstorm bắt đầu: [args] | brainstorm xong (Xm) + result preview |
|
|
100
|
+
| research | 🔍 | research bắt đầu: [args] | research xong (Xm) + result preview |
|
|
101
|
+
| cook | 👨🍳 | cook bắt đầu: [args] | cook xong (Xm) + result preview |
|
|
102
|
+
| debug | 🐛 | debug bắt đầu: [args] | debug xong (Xm) + result preview |
|
|
103
|
+
| fix | 🔧 | fix bắt đầu: [args] | fix xong (Xm) + result preview |
|
|
104
|
+
| review | 👀 | review bắt đầu: [args] | review xong (Xm) + result preview |
|
|
105
|
+
| plan / planner | 📋 | plan bắt đầu: [args] | plan xong (Xm) + result preview |
|
|
106
|
+
| test / tester | 🧪 | test bắt đầu: [args] | test xong (Xm) + result preview |
|
|
107
|
+
| security-review | 🔒 | security-review bắt đầu: [args] | security-review xong (Xm) + result preview |
|
|
108
|
+
| _khác (default)_ | ⚡ | ${skill} bắt đầu: [args] | ${skill} xong (Xm) + result preview |
|
|
109
|
+
|
|
110
|
+
Mapping emoji được định nghĩa trong `bitrix-lib.sh::skill_emoji()`. Thêm skill mới → cập nhật cả case statement và bảng này.
|
|
111
|
+
|
|
112
|
+
## Plan output → checklist auto-sync
|
|
113
|
+
|
|
114
|
+
Khi skill `plan` / `planner` chạy, agent PHẢI emit fenced block `bitrix-checklist` ở cuối plan output để hook PostToolUse tự sync sang Bitrix checklist.
|
|
115
|
+
|
|
116
|
+
````markdown
|
|
117
|
+
```bitrix-checklist
|
|
118
|
+
[
|
|
119
|
+
{"name":"Phase 1: Backend","items":["DB schema","Route handler","Tests"]},
|
|
120
|
+
{"name":"Phase 2: Frontend","items":["ListShell","Composable"]}
|
|
121
|
+
]
|
|
122
|
+
```
|
|
123
|
+
````
|
|
124
|
+
|
|
125
|
+
Spec đầy đủ: [docs/bitrix-task-reference.md §5](../../docs/bitrix-task-reference.md#5-checklist-sync-api-plan-phases-bitrix).
|
|
126
|
+
|
|
127
|
+
## Hook Files
|
|
128
|
+
|
|
129
|
+
```
|
|
130
|
+
.claude/
|
|
131
|
+
├── settings.json — wiring SessionStart/PreToolUse/PostToolUse/Stop
|
|
132
|
+
└── scripts/
|
|
133
|
+
├── bitrix-lib.sh — shared helpers
|
|
134
|
+
│ _b24_preflight, _b24_md_field, find_task_id, find_task_meta,
|
|
135
|
+
│ b24_call, b24_batch, b24_comment, b24_log_time,
|
|
136
|
+
│ b24_sync_checklist, skill_emoji
|
|
137
|
+
├── bitrix-session-check.sh — SessionStart: warn nếu thiếu TASK_ID
|
|
138
|
+
├── bitrix-skill-start.sh — PreToolUse: Skill → post "bắt đầu"
|
|
139
|
+
├── bitrix-skill-end.sh — PostToolUse: Skill → log time + post "xong"
|
|
140
|
+
└── bitrix-session-sync.sh — Stop: session summary
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Git hooks:
|
|
144
|
+
|
|
145
|
+
```
|
|
146
|
+
.githooks/
|
|
147
|
+
├── commit-msg — enforce [B24:nnn] tag (Hard Rule #18)
|
|
148
|
+
└── install.sh — set core.hooksPath = .githooks
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Chi tiết function signatures: xem [docs/bitrix-task-reference.md §5](../../docs/bitrix-task-reference.md#5-checklist-sync-api-plan-phases-bitrix).
|
|
152
|
+
|
|
153
|
+
## Skill Triggers
|
|
154
|
+
|
|
155
|
+
- Keywords: "bắt đầu feature", "start task" → đặt TASK_ID vào CLAUDE.md trước
|
|
156
|
+
- Keywords: "push", "commit" → verify commit có `[B24:TASK_ID]`
|
|
157
|
+
- Keywords: "session xong" → mở Bitrix task → verify có comment summary
|
|
158
|
+
- Keywords: "xem task", "đọc task", "task info" → dùng `bitrix-synity-mcp`
|
|
159
|
+
- Keywords: "field task", "task field", "deal field", "contact field", "structure", "shape", "schema portal" → BẮT BUỘC `bitrix-synity-mcp` để verify (Hard Rule #13). Annotate: `// MCP-DERIVED: <source> @ <ISO-timestamp>`
|
|
160
|
+
- Keywords: "list epic", "list workgroup", "tasks.api.scrum", "epic.list", "workgroup.list" → dùng `bitrix-synity-mcp` (KHÔNG curl/fetch)
|
|
161
|
+
- Keywords: "get task", "task #", "task detail" → dùng `bitrix-synity-mcp.task.get`
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Standalone artifact attach orchestrator — can be called manually or by hooks.
|
|
3
|
+
# Usage: bitrix-attach-files.sh <task_id> <session_id> <file1> [<file2> ...]
|
|
4
|
+
# Each file is uploaded to the task's group drive under AI Sessions/<repo>/<rel_dir>/
|
|
5
|
+
# and attached to the task. Prints drive file IDs to stdout (one per line).
|
|
6
|
+
# Exit 0 always — individual file failures are logged to stderr and skipped.
|
|
7
|
+
|
|
8
|
+
set -euo pipefail
|
|
9
|
+
source "$(dirname "$0")/bitrix-lib.sh"
|
|
10
|
+
|
|
11
|
+
_b24_preflight || exit 0
|
|
12
|
+
|
|
13
|
+
TASK_ID="${1:-}"
|
|
14
|
+
SESSION_ID="${2:-default}"
|
|
15
|
+
shift 2 2>/dev/null || true
|
|
16
|
+
|
|
17
|
+
if [[ -z "$TASK_ID" ]]; then
|
|
18
|
+
echo "Usage: bitrix-attach-files.sh <task_id> <session_id> <file1> [<file2> ...]" >&2
|
|
19
|
+
exit 1
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
[[ "$#" -eq 0 ]] && exit 0
|
|
23
|
+
|
|
24
|
+
ATTACHED=()
|
|
25
|
+
for FILE_PATH in "$@"; do
|
|
26
|
+
if [[ ! -f "$FILE_PATH" ]]; then
|
|
27
|
+
echo "[bitrix-attach-files] skip (not found): $FILE_PATH" >&2
|
|
28
|
+
continue
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
REL_DIR=$(dirname "$FILE_PATH")
|
|
32
|
+
DRIVE_ID=$(b24_attach_artifact "$TASK_ID" "$FILE_PATH" "$SESSION_ID" "$REL_DIR") || {
|
|
33
|
+
echo "[bitrix-attach-files] failed to attach: $FILE_PATH" >&2
|
|
34
|
+
continue
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if [[ -n "$DRIVE_ID" ]]; then
|
|
38
|
+
echo "$DRIVE_ID"
|
|
39
|
+
ATTACHED+=("$FILE_PATH")
|
|
40
|
+
fi
|
|
41
|
+
done
|
|
42
|
+
|
|
43
|
+
# Update session attach registry
|
|
44
|
+
if [[ ${#ATTACHED[@]} -gt 0 ]]; then
|
|
45
|
+
ATTACH_LOG="$SESSION_DIR/attached-${SESSION_ID}.json"
|
|
46
|
+
ATTACHED_JSON=$(printf '%s\n' "${ATTACHED[@]}" | jq -R . | jq -s .)
|
|
47
|
+
if [[ -f "$ATTACH_LOG" ]]; then
|
|
48
|
+
EXISTING=$(cat "$ATTACH_LOG")
|
|
49
|
+
echo "$EXISTING $ATTACHED_JSON" | jq -s '.[0] + .[1] | unique' > "$ATTACH_LOG"
|
|
50
|
+
else
|
|
51
|
+
echo "$ATTACHED_JSON" > "$ATTACH_LOG"
|
|
52
|
+
fi
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
exit 0
|