@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.
Files changed (77) hide show
  1. package/CHANGELOG.md +169 -0
  2. package/LICENSE +21 -0
  3. package/README.md +83 -0
  4. package/bin/bitrix-skills.js +3 -0
  5. package/dist/cli.js +1510 -0
  6. package/dist/features/bx-task/install.js +111 -0
  7. package/dist/features/task-sync/index.js +1053 -0
  8. package/package.json +69 -0
  9. package/src/features/bx/assets/SKILL.md +34 -0
  10. package/src/features/bx/feature.json +8 -0
  11. package/src/features/bx-calendar/assets/SKILL.md +61 -0
  12. package/src/features/bx-calendar/assets/availability.md +65 -0
  13. package/src/features/bx-calendar/assets/meeting.md +87 -0
  14. package/src/features/bx-calendar/assets/reminder.md +71 -0
  15. package/src/features/bx-calendar/assets/sync.md +70 -0
  16. package/src/features/bx-calendar/feature.json +10 -0
  17. package/src/features/bx-crm/assets/SKILL.md +59 -0
  18. package/src/features/bx-crm/assets/commerce.md +96 -0
  19. package/src/features/bx-crm/assets/onboard.md +127 -0
  20. package/src/features/bx-crm/assets/report.md +98 -0
  21. package/src/features/bx-crm/assets/research.md +71 -0
  22. package/src/features/bx-crm/feature.json +10 -0
  23. package/src/features/bx-task/assets/SKILL.md +148 -0
  24. package/src/features/bx-task/assets/lib/bx-api.sh +39 -0
  25. package/src/features/bx-task/assets/lib/bx-checklist.sh +127 -0
  26. package/src/features/bx-task/assets/lib/bx-resolve-task.sh +41 -0
  27. package/src/features/bx-task/assets/lib/bx-state.sh +131 -0
  28. package/src/features/bx-task/assets/lib/bx-tasks.sh +109 -0
  29. package/src/features/bx-task/assets/references/bootstrap.md +184 -0
  30. package/src/features/bx-task/assets/references/feature.md +97 -0
  31. package/src/features/bx-task/assets/references/init-templates/cli-tool.md +47 -0
  32. package/src/features/bx-task/assets/references/init-templates/generic.md +31 -0
  33. package/src/features/bx-task/assets/references/init-templates/library.md +45 -0
  34. package/src/features/bx-task/assets/references/init-templates/monorepo.md +38 -0
  35. package/src/features/bx-task/assets/references/init-templates/npm-package.md +40 -0
  36. package/src/features/bx-task/assets/references/init-templates/web-app.md +46 -0
  37. package/src/features/bx-task/assets/references/init.md +107 -0
  38. package/src/features/bx-task/assets/references/roadmap.md +93 -0
  39. package/src/features/bx-task/assets/references/summary.md +269 -0
  40. package/src/features/bx-task/assets/references/sync.md +104 -0
  41. package/src/features/bx-task/assets/references/time-log.md +214 -0
  42. package/src/features/bx-task/feature.json +10 -0
  43. package/src/features/bx-task/install.ts +117 -0
  44. package/src/features/task-sync/assets/docs/bitrix-task-reference.md +318 -0
  45. package/src/features/task-sync/assets/docs/bitrix-task-sync.md +254 -0
  46. package/src/features/task-sync/assets/githooks/commit-msg +44 -0
  47. package/src/features/task-sync/assets/githooks/install.sh +15 -0
  48. package/src/features/task-sync/assets/manifest.json +108 -0
  49. package/src/features/task-sync/assets/rules/00-bitrix-task-sync.md +161 -0
  50. package/src/features/task-sync/assets/scripts/bitrix-attach-files.sh +55 -0
  51. package/src/features/task-sync/assets/scripts/bitrix-lib.sh +540 -0
  52. package/src/features/task-sync/assets/scripts/bitrix-render-digest.sh +116 -0
  53. package/src/features/task-sync/assets/scripts/bitrix-session-check.sh +51 -0
  54. package/src/features/task-sync/assets/scripts/bitrix-session-sync.sh +89 -0
  55. package/src/features/task-sync/assets/scripts/bitrix-skill-end.sh +165 -0
  56. package/src/features/task-sync/assets/scripts/bitrix-skill-start.sh +58 -0
  57. package/src/features/task-sync/assets/scripts/lib/bb-formatter.sh +110 -0
  58. package/src/features/task-sync/assets/scripts/lib/bitrix-lib.sh +540 -0
  59. package/src/features/task-sync/assets/scripts/lib/time-helpers.sh +57 -0
  60. package/src/features/task-sync/assets/workflows/bitrix-sync.yml +85 -0
  61. package/src/features/task-sync/commands/install.ts +296 -0
  62. package/src/features/task-sync/commands/uninstall.ts +189 -0
  63. package/src/features/task-sync/commands/update.ts +11 -0
  64. package/src/features/task-sync/commands/verify.ts +141 -0
  65. package/src/features/task-sync/feature.json +12 -0
  66. package/src/features/task-sync/index.ts +121 -0
  67. package/src/features/task-sync/lib/dest-map.ts +96 -0
  68. package/src/features/task-sync/lib/drift-check.ts +47 -0
  69. package/src/features/task-sync/lib/file-ops.ts +36 -0
  70. package/src/features/task-sync/lib/manifest.ts +66 -0
  71. package/src/features/task-sync/lib/project-root.ts +38 -0
  72. package/src/features/task-sync/lib/settings-merge.ts +112 -0
  73. package/src/features/task-sync/lib/skill-refs.ts +106 -0
  74. package/src/features/task-sync/lib/task-id-finder.ts +31 -0
  75. package/src/features/task-sync/lib/token-extractor.ts +52 -0
  76. package/src/features/task-sync/lib/version.ts +36 -0
  77. package/src/features/task-sync/types.ts +40 -0
package/package.json ADDED
@@ -0,0 +1,69 @@
1
+ {
2
+ "name": "@synity/bitrix-skills",
3
+ "version": "1.3.0",
4
+ "description": "Multi-feature Bitrix24 tooling CLI for Synity projects",
5
+ "type": "module",
6
+ "bin": {
7
+ "bitrix-skills": "bin/bitrix-skills.js"
8
+ },
9
+ "files": [
10
+ "dist",
11
+ "bin",
12
+ "src/features",
13
+ "README.md",
14
+ "CHANGELOG.md"
15
+ ],
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "https://github.com/synity-tech/bitrix-tools.git"
19
+ },
20
+ "homepage": "https://github.com/synity-tech/bitrix-tools",
21
+ "bugs": {
22
+ "url": "https://github.com/synity-tech/bitrix-tools/issues"
23
+ },
24
+ "engines": {
25
+ "node": ">=20"
26
+ },
27
+ "scripts": {
28
+ "prebuild": "node scripts/prebuild-bash-sync.mjs && node scripts/sync-assets.mjs",
29
+ "build": "tsup --config tsup.config.ts",
30
+ "dev": "tsup --config tsup.config.ts --watch",
31
+ "prepublishOnly": "pnpm build",
32
+ "test": "vitest run",
33
+ "test:watch": "vitest",
34
+ "lint": "eslint src --ext .ts",
35
+ "release": "pnpm build && changeset publish",
36
+ "version": "changeset version",
37
+ "changeset": "changeset"
38
+ },
39
+ "publishConfig": {
40
+ "access": "public"
41
+ },
42
+ "keywords": [
43
+ "bitrix24",
44
+ "bitrix",
45
+ "task-sync",
46
+ "claude-code",
47
+ "ai-tools",
48
+ "hooks",
49
+ "synity"
50
+ ],
51
+ "author": "Synity Vietnam JSC <tech@synity.vn>",
52
+ "license": "MIT",
53
+ "dependencies": {
54
+ "@inquirer/checkbox": "^5.1.5",
55
+ "@inquirer/confirm": "^6.0.13",
56
+ "chalk": "^5.6.2",
57
+ "clipanion": "4.0.0-rc.4",
58
+ "deepmerge": "^4.3.1",
59
+ "execa": "^9.0.0",
60
+ "kleur": "^4.1.5"
61
+ },
62
+ "devDependencies": {
63
+ "@changesets/cli": "^2.31.0",
64
+ "@types/node": "^20.0.0",
65
+ "tsup": "^8.0.0",
66
+ "typescript": "^5.4.0",
67
+ "vitest": "^2.1.0"
68
+ }
69
+ }
@@ -0,0 +1,34 @@
1
+ ---
2
+ name: bx
3
+ description: "Bitrix24 hub — type /bx to discover all Bitrix24 skills. Routes to bx:crm (contacts/deals), bx:task (project tasks), bx:calendar (events/meetings)."
4
+ argument-hint: "[crm|task|calendar]"
5
+ version: "1.0.0"
6
+ ---
7
+
8
+ # /bx — Bitrix24 Skill Hub
9
+
10
+ Detect intent → invoke the right subskill directly.
11
+
12
+ | User intent | Invoke |
13
+ |-------------|--------|
14
+ | contact, deal, company, lead, phân tích KH, báo giá, invoice, pipeline report | `/bx:crm` |
15
+ | task, time-log, KB summary, sync session to Bitrix, init TASK_ID | `/bx:task` |
16
+ | meeting, lịch, calendar, nhắc nhở, schedule, kiểm tra lịch trống | `/bx:calendar` |
17
+
18
+ > **Tip:** If you already know the domain, invoke the subskill directly — faster than routing through `/bx`.
19
+
20
+ ---
21
+
22
+ ## If intent is ambiguous
23
+
24
+ Ask: **"CRM, task management, or calendar?"** then invoke the correct subskill.
25
+
26
+ ---
27
+
28
+ ## Subskill Quick Reference
29
+
30
+ | Skill | Version | Coverage |
31
+ |-------|---------|---------|
32
+ | `bx:crm` | v2.0.0 | contact/company/deal/lead, analysis, reports, commerce |
33
+ | `bx:task` | v1.1.0 | task CRUD, time-log, KB summary, session sync |
34
+ | `bx:calendar` | v1.0.0 | events, meetings, reminders, availability, CRM sync |
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "bx",
3
+ "displayName": "Bitrix Hub Skill",
4
+ "version": "1.0.0",
5
+ "target": "global",
6
+ "description": "Claude Code hub skill — routes to bx:crm, bx:task, bx:calendar. Install for discovery UX.",
7
+ "requires": {}
8
+ }
@@ -0,0 +1,61 @@
1
+ ---
2
+ name: bx:calendar
3
+ description: "Synity Bitrix24 Calendar via REST API. Use for: creating meetings, scheduling events, follow-up reminders, checking team availability, syncing CRM activities to calendar. NOT for CRM records (use bx:crm) or project tasks (use bx:task)."
4
+ argument-hint: "<subcommand> [args...]"
5
+ version: "1.0.0"
6
+ ---
7
+
8
+ # /bx:calendar — Bitrix24 Calendar Operations (Synity)
9
+
10
+ **Tool**: Bitrix24 REST API via `BITRIX_WEBHOOK_URL` — no MCP Synity helpers for calendar.
11
+
12
+ > ⛔ `bx:crm` = CRM entities (contact/deal). NOT for calendar events.
13
+ > ⛔ `bx:task` = project task management. NOT for calendar events.
14
+ > ✅ All calendar events, meetings, reminders, scheduling → this skill.
15
+
16
+ ---
17
+
18
+ ## Pre-flight (mandatory)
19
+
20
+ ```bash
21
+ # Required env var
22
+ echo $BITRIX_WEBHOOK_URL # must be set: https://<portal>.bitrix24.com/rest/<user>/<token>/
23
+
24
+ # Required tools
25
+ which jq curl
26
+ ```
27
+
28
+ ---
29
+
30
+ ## Detect Intent → Load File
31
+
32
+ | User intent | Load file |
33
+ |-------------|-----------|
34
+ | Create meeting, schedule event, link to CRM contact/deal | `meeting.md` |
35
+ | Set reminder, follow-up after meeting | `reminder.md` |
36
+ | Check availability, find free time slot | `availability.md` |
37
+ | Sync CRM activity to calendar event | `sync.md` |
38
+
39
+ ---
40
+
41
+ ## Mandatory Workflow
42
+
43
+ ```
44
+ 1. Detect intent → load the correct subfile above
45
+ 2. Follow SOP in that file (timezone, CRM binding)
46
+ 3. Execute via REST API (curl + jq)
47
+ 4. Verify result
48
+ ```
49
+
50
+ ---
51
+
52
+ ## REST API Basics
53
+
54
+ **Input parameters**: camelCase (`name`, `ownerId`, `from`, `to`)
55
+ **Response fields**: UPPER_SNAKE_CASE (`TZ_FROM`, `TZ_TO`, `ID`)
56
+
57
+ ```bash
58
+ # Generic REST call pattern
59
+ curl -s "${BITRIX_WEBHOOK_URL}calendar.event.add" \
60
+ -d "$(jq -n '{fields: {name: "...", ...}}')" | jq .
61
+ ```
@@ -0,0 +1,65 @@
1
+ # bx:calendar — Availability (Find Free Slots)
2
+
3
+ ---
4
+
5
+ ## Query Events for a User
6
+
7
+ ```bash
8
+ # Get all events for user 1 in a date range
9
+ curl -s "${BITRIX_WEBHOOK_URL}calendar.event.getlist" \
10
+ -d "$(jq -n '{
11
+ type: "user",
12
+ ownerId: 1,
13
+ from: "2026-05-16",
14
+ to: "2026-05-16"
15
+ }')" | jq '[.result[] | {id:.ID, name:.NAME, from:.DATE_FROM, to:.DATE_TO}]'
16
+ ```
17
+
18
+ **Parameters:**
19
+ | Parameter | Value |
20
+ |-----------|-------|
21
+ | `type` | `"user"` for personal calendar |
22
+ | `ownerId` | Bitrix24 user ID |
23
+ | `from` | Date string `"YYYY-MM-DD"` |
24
+ | `to` | Date string `"YYYY-MM-DD"` |
25
+
26
+ ---
27
+
28
+ ## Free Slot Algorithm
29
+
30
+ 1. Fetch busy events for each attendee in the target date range
31
+ 2. Normalize all event times to VN timezone (`Asia/Ho_Chi_Minh`, UTC+7)
32
+ 3. Merge busy intervals per attendee → find gaps ≥ `meetingDuration`
33
+ 4. Intersect free gaps across all attendees
34
+ 5. Filter to working hours: **08:00–17:30 VN** (configurable)
35
+
36
+ **Output format:**
37
+ ```
38
+ Free slots for [date]:
39
+ - 08:00–10:00 (2h)
40
+ - 13:00–15:30 (2.5h)
41
+ - 16:00–17:30 (1.5h)
42
+ ```
43
+
44
+ ---
45
+
46
+ ## Multi-User Availability Check
47
+
48
+ ```bash
49
+ # Check availability for users 1, 2, 3
50
+ for USER_ID in 1 2 3; do
51
+ echo "=== User $USER_ID ==="
52
+ curl -s "${BITRIX_WEBHOOK_URL}calendar.event.getlist" \
53
+ -d "$(jq -n --argjson uid $USER_ID '{type:"user", ownerId:$uid, from:"2026-05-16", to:"2026-05-16"}')" \
54
+ | jq '[.result[] | {from:.DATE_FROM, to:.DATE_TO, name:.NAME}]'
55
+ done
56
+ ```
57
+
58
+ ---
59
+
60
+ ## Notes
61
+
62
+ - Working hours assumption: 08:00–17:30 VN — adjust if user has different hours
63
+ - `calendar.event.getlist` returns events where the querying user has read access
64
+ - Response `DATE_FROM` / `DATE_TO` are in UPPER_SNAKE_CASE
65
+ - All-day events: `DATE_FROM` has no time component — treat as blocking 00:00–23:59
@@ -0,0 +1,87 @@
1
+ # bx:calendar — Meeting (Create Event + CRM Binding)
2
+
3
+ ---
4
+
5
+ ## Required Fields for calendar.event.add
6
+
7
+ | Parameter | Type | Notes |
8
+ |-----------|------|-------|
9
+ | `name` | string | Event title |
10
+ | `type` | string | `"user"` (personal) / `"group"` (team) / `"company_calendar"` |
11
+ | `ownerId` | number | User ID (for `type=user`) or group ID |
12
+ | `from` | string | ISO 8601: `"2026-05-15T10:00:00+07:00"` |
13
+ | `to` | string | ISO 8601: `"2026-05-15T11:00:00+07:00"` |
14
+ | `section` | number | Section ID from `calendar.section.getlist` |
15
+ | `timezone_from` | string | **Always `"Asia/Ho_Chi_Minh"` for VN meetings** |
16
+ | `timezone_to` | string | **Always `"Asia/Ho_Chi_Minh"` for VN meetings** |
17
+
18
+ ---
19
+
20
+ ## Timezone SOP (CRITICAL)
21
+
22
+ **Always set `timezone_from` and `timezone_to` = `"Asia/Ho_Chi_Minh"`** for VN meetings.
23
+
24
+ Omitting timezone → server stores UTC → all VN participants see wrong time.
25
+
26
+ Use ISO 8601 with offset in datetime strings:
27
+ ```
28
+ "2026-05-15T10:00:00+07:00" ✅ correct
29
+ "2026-05-15T03:00:00Z" ❌ confusing — use +07:00 explicitly
30
+ "2026-05-15 10:00:00" ❌ no timezone info
31
+ ```
32
+
33
+ ---
34
+
35
+ ## CRM Binding
36
+
37
+ Link the event to a CRM entity via `UF_CRM_CAL_EVENT`:
38
+
39
+ | Entity | Prefix format |
40
+ |--------|--------------|
41
+ | Deal | `D_<dealId>` → e.g. `"D_42"` |
42
+ | Contact | `CO_<contactId>` → e.g. `"CO_15"` |
43
+ | Company | `C_<companyId>` → e.g. `"C_7"` |
44
+
45
+ ```bash
46
+ # Example: meeting linked to deal 42 + contact 15
47
+ curl -s "${BITRIX_WEBHOOK_URL}calendar.event.add" \
48
+ -d "$(jq -n '{
49
+ name: "Demo call with Nguyen Van A",
50
+ type: "user",
51
+ ownerId: 1,
52
+ from: "2026-05-16T10:00:00+07:00",
53
+ to: "2026-05-16T11:00:00+07:00",
54
+ section: 3,
55
+ timezone_from: "Asia/Ho_Chi_Minh",
56
+ timezone_to: "Asia/Ho_Chi_Minh",
57
+ UF_CRM_CAL_EVENT: ["D_42", "CO_15"]
58
+ }')" | jq '.result'
59
+ ```
60
+
61
+ ---
62
+
63
+ ## Get Section ID
64
+
65
+ ```bash
66
+ curl -s "${BITRIX_WEBHOOK_URL}calendar.section.getlist" \
67
+ -d '{"type":"user","ownerId":1}' | jq '[.result[] | {id:.ID, name:.NAME}]'
68
+ ```
69
+
70
+ ---
71
+
72
+ ## Verify Checklist
73
+
74
+ - [ ] Event `ID` returned (not null)
75
+ - [ ] Response `TZ_FROM` = `"Asia/Ho_Chi_Minh"`
76
+ - [ ] `UF_CRM_CAL_EVENT` contains expected entity IDs
77
+ - [ ] `from` / `to` datetimes correct
78
+
79
+ ---
80
+
81
+ ## Common Mistakes
82
+
83
+ | Mistake | Result | Fix |
84
+ |---------|--------|-----|
85
+ | Omit `timezone_from`/`timezone_to` | Server timezone (UTC) stored | Always set both |
86
+ | Wrong CRM prefix (`DEAL_42` instead of `D_42`) | Binding silently ignored | Use exact prefixes above |
87
+ | Missing `section` field | API error | Fetch section ID first |
@@ -0,0 +1,71 @@
1
+ # bx:calendar — Reminder (Follow-up + Pre-meeting)
2
+
3
+ ---
4
+
5
+ ## Two Reminder Use Cases
6
+
7
+ ### Use Case 1 — Pre-meeting notification
8
+
9
+ Add `remind` array to event creation:
10
+
11
+ ```bash
12
+ curl -s "${BITRIX_WEBHOOK_URL}calendar.event.add" \
13
+ -d "$(jq -n '{
14
+ name: "Demo call",
15
+ type: "user",
16
+ ownerId: 1,
17
+ from: "2026-05-16T10:00:00+07:00",
18
+ to: "2026-05-16T11:00:00+07:00",
19
+ section: 3,
20
+ timezone_from: "Asia/Ho_Chi_Minh",
21
+ timezone_to: "Asia/Ho_Chi_Minh",
22
+ remind: [{type: "min", count: 15}]
23
+ }')" | jq '.result'
24
+ ```
25
+
26
+ **`remind` type values**: `"min"` | `"hour"` | `"day"`
27
+
28
+ **Standard offsets:**
29
+ - Pre-meeting: `{type: "min", count: 15}` (15 min before)
30
+ - Long event: `{type: "hour", count: 1}` (1 hour before)
31
+
32
+ ---
33
+
34
+ ### Use Case 2 — Post-meeting follow-up
35
+
36
+ Create a **new event** scheduled `+1 business day` after meeting end.
37
+
38
+ **Business day calculation rule:**
39
+ - If meeting ends Mon–Thu → follow-up = next day at 09:00
40
+ - If meeting ends Fri → follow-up = Monday at 09:00
41
+ - If meeting ends Sat/Sun → follow-up = Monday at 09:00
42
+ - VN public holidays: out of scope (skip manually if needed)
43
+
44
+ ```bash
45
+ # Follow-up event after meeting with deal 42
46
+ FOLLOW_UP_DATE="2026-05-17T09:00:00+07:00" # calculated +1 biz day
47
+ FOLLOW_UP_END="2026-05-17T09:30:00+07:00"
48
+
49
+ curl -s "${BITRIX_WEBHOOK_URL}calendar.event.add" \
50
+ -d "$(jq -n --arg d "$FOLLOW_UP_DATE" --arg e "$FOLLOW_UP_END" '{
51
+ name: "Follow-up: Demo call with Nguyen Van A",
52
+ type: "user",
53
+ ownerId: 1,
54
+ from: $d,
55
+ to: $e,
56
+ section: 3,
57
+ timezone_from: "Asia/Ho_Chi_Minh",
58
+ timezone_to: "Asia/Ho_Chi_Minh",
59
+ UF_CRM_CAL_EVENT: ["D_42"],
60
+ remind: [{type: "min", count: 30}]
61
+ }')" | jq '.result'
62
+ ```
63
+
64
+ ---
65
+
66
+ ## Verify Checklist
67
+
68
+ - [ ] Event `ID` returned
69
+ - [ ] For pre-meeting: `remind` array present in event details
70
+ - [ ] For follow-up: datetime is a business day at 09:00 VN time
71
+ - [ ] CRM deal/contact linked via `UF_CRM_CAL_EVENT`
@@ -0,0 +1,70 @@
1
+ # bx:calendar — Sync (CRM Activity → Calendar Event)
2
+
3
+ ---
4
+
5
+ ## Direction
6
+
7
+ **One-way only: CRM Activity → Calendar Event.**
8
+
9
+ No native Bitrix24 webhook for 2-way sync. After creation:
10
+ - Editing the calendar event does NOT update the CRM activity
11
+ - Editing the CRM activity does NOT update the calendar event
12
+ - Manual update required if either changes after sync
13
+
14
+ ---
15
+
16
+ ## Field Mapping
17
+
18
+ | CRM Activity field | Calendar event parameter | Notes |
19
+ |-------------------|-------------------------|-------|
20
+ | `SUBJECT` | `name` | Event title |
21
+ | `START_TIME` | `from` | ISO 8601 + `+07:00` offset |
22
+ | `END_TIME` | `to` | ISO 8601 + `+07:00` offset |
23
+ | `DESCRIPTION` | `description` | Optional |
24
+ | `OWNER_TYPE_ID` + `OWNER_ID` | `UF_CRM_CAL_EVENT` | e.g. deal → `["D_42"]` |
25
+ | `RESPONSIBLE_ID` | `ownerId` | Bitrix24 user ID |
26
+
27
+ ---
28
+
29
+ ## Sync Steps
30
+
31
+ **Step 1 — Read CRM activity**
32
+ ```bash
33
+ curl -s "${BITRIX_WEBHOOK_URL}crm.activity.get" \
34
+ -d '{"id": 789}' | jq '.result | {subject:.SUBJECT, start:.START_TIME, end:.END_TIME, owner_type:.OWNER_TYPE_ID, owner_id:.OWNER_ID}'
35
+ ```
36
+
37
+ **Step 2 — Map owner to CRM entity prefix**
38
+
39
+ | `OWNER_TYPE_ID` | Prefix |
40
+ |----------------|--------|
41
+ | 2 | `CO_` (contact) |
42
+ | 3 | `C_` (company) |
43
+ | 4 | `D_` (deal) |
44
+
45
+ **Step 3 — Create calendar event**
46
+ ```bash
47
+ curl -s "${BITRIX_WEBHOOK_URL}calendar.event.add" \
48
+ -d "$(jq -n '{
49
+ name: "Meeting: <SUBJECT>",
50
+ type: "user",
51
+ ownerId: <RESPONSIBLE_ID>,
52
+ from: "<START_TIME_ISO+07:00>",
53
+ to: "<END_TIME_ISO+07:00>",
54
+ section: 3,
55
+ timezone_from: "Asia/Ho_Chi_Minh",
56
+ timezone_to: "Asia/Ho_Chi_Minh",
57
+ UF_CRM_CAL_EVENT: ["D_<OWNER_ID>"]
58
+ }')" | jq '.result'
59
+ ```
60
+
61
+ **Step 4 — Verify**
62
+ - [ ] Calendar event `ID` returned
63
+ - [ ] `UF_CRM_CAL_EVENT` contains correct CRM entity
64
+ - [ ] `TZ_FROM` = `"Asia/Ho_Chi_Minh"` in response
65
+
66
+ ---
67
+
68
+ ## Limitation Note
69
+
70
+ > **After sync:** if you edit the calendar event or the CRM activity, the other side will NOT be updated automatically. This is a Bitrix24 platform limitation — no native 2-way sync via REST API. To update both, edit both manually.
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "bx-calendar",
3
+ "displayName": "Bitrix Calendar Skill",
4
+ "version": "1.0.0",
5
+ "target": "global",
6
+ "description": "Claude Code skill for Bitrix24 Calendar: meetings, reminders, team availability, CRM activity sync",
7
+ "requires": {
8
+ "env": ["BITRIX_WEBHOOK_URL"]
9
+ }
10
+ }
@@ -0,0 +1,59 @@
1
+ ---
2
+ name: bx:crm
3
+ description: "Synity Bitrix24 CRM via MCP Synity. Use for: contacts, companies, deals, leads, estimates, invoices, customer analysis, pipeline reports. NOT for project tasks (use bx:task) or calendar events (use bx:calendar)."
4
+ argument-hint: "<operation> [args]"
5
+ version: "2.0.0"
6
+ ---
7
+
8
+ # /bx:crm — Bitrix24 CRM via MCP Synity
9
+
10
+ **Tool**: MCP Synity at `b24-mcp.synity.so` — entry point is `codemode.search()` → `execute`.
11
+
12
+ > ⛔ `bx:task` = project task management. NOT for CRM entities.
13
+ > ⛔ `bx:calendar` = calendar events + meetings. NOT for CRM entities.
14
+ > ✅ All CRM (contact/company/deal/lead/estimate/invoice) → this skill.
15
+
16
+ ---
17
+
18
+ ## Detect Workflow → Load File
19
+
20
+ | User intent | Load file | Key helpers |
21
+ |-------------|-----------|-------------|
22
+ | create/update contact, company, deal, lead | `onboard.md` | upsertContact, upsertCompanyByTaxCode, createDealWithParties |
23
+ | analyze customer, signals, before meeting | `research.md` | customer360, contactSignals, dealSignals, customerJourney |
24
+ | pipeline report, forecast, AR, overdue | `report.md` | dealForecast, stuckInStage, arReport |
25
+ | estimate, báo giá, invoice, approve | `commerce.md` | createEstimate, approveEstimate, createSmartInvoice |
26
+
27
+ If intent spans multiple workflows → load `onboard.md` first, then load others as needed.
28
+
29
+ ---
30
+
31
+ ## Mandatory Workflow
32
+
33
+ ```
34
+ 1. Detect intent → load the correct subfile above
35
+ 2. Follow SOP rules / output protocol in that file
36
+ 3. codemode.search() to confirm helper schema
37
+ 4. Execute via the correct helper
38
+ 5. Verify result against checklist in the subfile
39
+ ```
40
+
41
+ Skipping steps 1 or 5 caused production bugs. Both are required.
42
+
43
+ ---
44
+
45
+ ## Discovery Reference
46
+
47
+ ```js
48
+ // Primary — always use first
49
+ codemode.search({ keywords: ["..."], entities: ["deal","contact","company"], intent: "write" })
50
+
51
+ // Only if search() returns empty
52
+ codemode.catalog() // ~40 unranked helpers
53
+
54
+ // For stage IDs / CRM type IDs
55
+ codemode.entityIds()
56
+
57
+ // Raw REST when no helper exists
58
+ codemode.request({ method: "POST", path: "/crm.xxx", body: { ... } })
59
+ ```
@@ -0,0 +1,96 @@
1
+ # bx:crm — Commerce (Quote-to-Cash Flow)
2
+
3
+ Covers: estimate → approve → smart invoice.
4
+
5
+ ---
6
+
7
+ ## Mandatory Flow Order
8
+
9
+ **Do NOT skip or reorder these steps.**
10
+
11
+ ```
12
+ 1. createEstimate
13
+ 2. setEstimateProducts
14
+ 3. [Customer confirmation]
15
+ 4. approveEstimate
16
+ 5. closeEstimatesForDeal
17
+ 6. createSmartInvoice
18
+ 7. setInvoiceProducts OR copyDealProductsToInvoice
19
+ ```
20
+
21
+ ---
22
+
23
+ ## Step Details
24
+
25
+ **Step 1 — Create estimate**
26
+ ```js
27
+ createEstimate({ dealId, title, currency })
28
+ // → returns estimateId
29
+ ```
30
+
31
+ **Step 2 — Set products**
32
+ ```js
33
+ // Option A: known products from catalog
34
+ findProducts({ query: "product name" }) // → [{id, name, price}]
35
+ setEstimateProducts({ estimateId, products: [{ id, price, quantity }] })
36
+
37
+ // Option B: custom line items
38
+ setEstimateProducts({ estimateId, products: [{ name, price, quantity }] })
39
+ ```
40
+
41
+ **Step 3 — Wait for customer confirmation** (offline step, no API call)
42
+
43
+ **Step 4 — Approve estimate**
44
+ ```js
45
+ approveEstimate({ estimateId })
46
+ ```
47
+
48
+ **Step 5 — Close other estimates for this deal**
49
+ ```js
50
+ closeEstimatesForDeal({ dealId }) // closes all non-approved estimates
51
+ ```
52
+
53
+ **Step 6 — Create smart invoice**
54
+ ```js
55
+ createSmartInvoice({ dealId, contactId, companyId })
56
+ // → returns invoiceId
57
+ // Always pass BOTH contactId AND companyId — no payer = template broken
58
+ ```
59
+
60
+ **Step 7 — Set invoice products (pick ONE method only)**
61
+ ```js
62
+ // Method A: copy from deal (recommended when deal products are set)
63
+ copyDealProductsToInvoice({ dealId, invoiceId })
64
+
65
+ // Method B: set manually
66
+ setInvoiceProducts({ invoiceId, products: [...] })
67
+ ```
68
+
69
+ ---
70
+
71
+ ## Verify Checklist (after invoice creation)
72
+
73
+ - [ ] Invoice `STATUS = 'N'` (new/unpaid)
74
+ - [ ] Payer: both `contactId` and `companyId` linked
75
+ - [ ] Products list matches approved estimate
76
+ - [ ] `OPPORTUNITY` on deal updated to match invoice total
77
+
78
+ ---
79
+
80
+ ## Common Mistakes
81
+
82
+ | Mistake | Result | Fix |
83
+ |---------|--------|-----|
84
+ | `createSmartInvoice` before `approveEstimate` | Duplicate amounts, wrong totals | Follow step order strictly |
85
+ | Using both `setInvoiceProducts` AND `copyDealProducts` | One overwrites the other | Pick ONE method only |
86
+ | Missing `contactId` or `companyId` on invoice | No payer linked → document template broken | Always pass both |
87
+
88
+ ---
89
+
90
+ ## Products Discovery
91
+
92
+ ```js
93
+ // Search product catalog before creating estimate
94
+ findProducts({ query: "keyword", limit: 10 })
95
+ // → [{ id, name, price, currency, unit }]
96
+ ```