@synity/bitrix-skills 1.3.2 → 1.3.3
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 +1 -11
- package/dist/cli.js +1 -7
- package/package.json +1 -8
- package/src/features/bx/feature.json +0 -1
- package/src/features/bx-calendar/feature.json +0 -1
- package/src/features/bx-crm/assets/SKILL.md +1 -1
- package/src/features/bx-crm/assets/onboard.md +37 -0
- package/src/features/bx-crm/feature.json +0 -1
- package/src/features/task-sync/assets/skill/SKILL.md +0 -173
package/CHANGELOG.md
CHANGED
|
@@ -1,20 +1,10 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 1.3.2
|
|
4
|
-
|
|
5
|
-
### Patch Changes
|
|
6
|
-
|
|
7
|
-
- Restore `--all` flag on `install` command and fix non-TTY safety guard. Both behaviors were dropped in 1.3.0 cleanup but remained under test contract — `install --all` previously errored with "unknown option", and CI runs would silently bulk-install everything. Also repairs `sync-assets.mjs` so test/build pipelines populate `assets/scripts/` correctly after the single-repo migration.
|
|
8
|
-
|
|
9
3
|
## 1.3.1
|
|
10
4
|
|
|
11
5
|
### Patch Changes
|
|
12
6
|
|
|
13
|
-
-
|
|
14
|
-
|
|
15
|
-
Previously these features had `status: "active"` in feature.json but no install handler wired into `src/commands/install.ts`, causing `install --all` to print `! No install handler for feature: <name>` for each.
|
|
16
|
-
|
|
17
|
-
Now they're filtered out by the existing `f.status !== 'planned'` check (install.ts:121). Will flip back to `active` when install handlers land.
|
|
7
|
+
- bx-crm: add optional deal products flow to onboard.md — findProducts → setDealProducts after createDealWithParties. Fix findProducts param (query→name), document substring keyword behavior, note Commerce catalog scope requirement.
|
|
18
8
|
|
|
19
9
|
## 1.3.0
|
|
20
10
|
|
package/dist/cli.js
CHANGED
|
@@ -1123,7 +1123,6 @@ var InstallCommand = class extends Command {
|
|
|
1123
1123
|
});
|
|
1124
1124
|
key = Option.String("--key", { description: "License key to unlock paid tier features" });
|
|
1125
1125
|
featuresFlag = Option.String("--features", { description: "Comma-separated feature names" });
|
|
1126
|
-
all = Option.Boolean("--all", false, { description: "Install all installable features (required in non-TTY)" });
|
|
1127
1126
|
featureArgs = Option.Rest({ required: 0 });
|
|
1128
1127
|
async execute() {
|
|
1129
1128
|
const cwd = process.cwd();
|
|
@@ -1163,13 +1162,8 @@ var InstallCommand = class extends Command {
|
|
|
1163
1162
|
selectedNames = this.featuresFlag.split(",").map((s) => s.trim()).filter(Boolean);
|
|
1164
1163
|
} else if (this.featureArgs.length > 0) {
|
|
1165
1164
|
selectedNames = this.featureArgs;
|
|
1166
|
-
} else if (this.all || process.stdin.isTTY) {
|
|
1167
|
-
selectedNames = installable.map((f) => f.name);
|
|
1168
1165
|
} else {
|
|
1169
|
-
|
|
1170
|
-
chalk.red("Refusing to install in non-TTY without explicit selection.\n") + chalk.gray(" Pass --all, --features <csv>, or feature names as positional args.\n")
|
|
1171
|
-
);
|
|
1172
|
-
return 1;
|
|
1166
|
+
selectedNames = installable.map((f) => f.name);
|
|
1173
1167
|
}
|
|
1174
1168
|
const availableNames = new Set(available.map((f) => f.name));
|
|
1175
1169
|
const invalid = selectedNames.filter((n) => !availableNames.has(n));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@synity/bitrix-skills",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.3",
|
|
4
4
|
"description": "Multi-feature Bitrix24 tooling CLI for Synity projects",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -47,22 +47,15 @@
|
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@changesets/cli": "^2.31.0",
|
|
50
|
-
"@eslint/js": "^9.39.4",
|
|
51
50
|
"@types/node": "^20.0.0",
|
|
52
|
-
"@typescript-eslint/eslint-plugin": "^8.59.3",
|
|
53
|
-
"@typescript-eslint/parser": "^8.59.3",
|
|
54
|
-
"eslint": "^9.39.4",
|
|
55
|
-
"globals": "^17.6.0",
|
|
56
51
|
"tsup": "^8.0.0",
|
|
57
52
|
"typescript": "^5.4.0",
|
|
58
|
-
"typescript-eslint": "^8.59.3",
|
|
59
53
|
"vitest": "^2.1.0"
|
|
60
54
|
},
|
|
61
55
|
"scripts": {
|
|
62
56
|
"prebuild": "node scripts/prebuild-bash-sync.mjs && node scripts/sync-assets.mjs",
|
|
63
57
|
"build": "tsup --config tsup.config.ts",
|
|
64
58
|
"dev": "tsup --config tsup.config.ts --watch",
|
|
65
|
-
"pretest": "node scripts/prebuild-bash-sync.mjs && node scripts/sync-assets.mjs",
|
|
66
59
|
"test": "vitest run",
|
|
67
60
|
"test:watch": "vitest",
|
|
68
61
|
"lint": "eslint src --ext .ts",
|
|
@@ -15,7 +15,7 @@ Use this skill for CRM entities only: contacts, companies, deals, leads, estimat
|
|
|
15
15
|
|
|
16
16
|
| User intent | Load file | Key helpers |
|
|
17
17
|
|---|---|---|
|
|
18
|
-
| create/update contact, company, deal, lead | `onboard.md` | `upsertContact`, `upsertCompanyByTaxCode`, `createDealWithParties` |
|
|
18
|
+
| create/update contact, company, deal, lead | `onboard.md` | `upsertContact`, `upsertCompanyByTaxCode`, `createDealWithParties`, `setDealProducts`, `findProducts` |
|
|
19
19
|
| VN phone, honorific, address, MST format | `vn-norms.md` | normalization rules |
|
|
20
20
|
| convert/qualify lead to deal | `convert.md` | `convertLeadToDeal` |
|
|
21
21
|
| estimate, báo giá, invoice, payment link | `commerce.md` | `createEstimate`, `approveEstimate`, `createSmartInvoice` |
|
|
@@ -69,6 +69,42 @@ Timeline: <start date>
|
|
|
69
69
|
Notes: <context>
|
|
70
70
|
```
|
|
71
71
|
|
|
72
|
+
## Deal — Optional Products
|
|
73
|
+
|
|
74
|
+
Add products only when the user explicitly mentions product names or asks for products on the deal.
|
|
75
|
+
|
|
76
|
+
```js
|
|
77
|
+
// 1. Extract short keyword (1-2 words) from user's product name — do NOT pass full name
|
|
78
|
+
// name = substring match; "%keyword%" wildcard syntax breaks the param
|
|
79
|
+
const matches = await findProducts({ name: "<short keyword>", limit: 5 })
|
|
80
|
+
// → [{ id, name, sku, price, currency, vatRate, matched }]
|
|
81
|
+
|
|
82
|
+
// 2. Confirm match with user if multiple or ambiguous results
|
|
83
|
+
// 3. Add to deal (currency omitted — Bitrix inherits from deal)
|
|
84
|
+
await setDealProducts({
|
|
85
|
+
dealId,
|
|
86
|
+
items: [{ productId: matches[0].id, price: matches[0].price, quantity: 1 }],
|
|
87
|
+
mode: "replace"
|
|
88
|
+
})
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**MCP gap fallback** — use only when `setDealProducts` is absent from `codemode.catalog()`:
|
|
92
|
+
```js
|
|
93
|
+
codemode.request({
|
|
94
|
+
method: "POST",
|
|
95
|
+
path: "/crm.deal.productrows.set",
|
|
96
|
+
body: { id: dealId, rows: [{ PRODUCT_ID: id, PRICE: price, QUANTITY: quantity }] }
|
|
97
|
+
})
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**Rules:**
|
|
101
|
+
- Products are optional — add only when user mentions specific product names.
|
|
102
|
+
- Always `findProducts` to resolve name → id; never hardcode `PRODUCT_ID`.
|
|
103
|
+
- Pass a short keyword (1-2 words) to `findProducts({ name })`, not the full product name.
|
|
104
|
+
- Omit `currency` in items — Bitrix inherits it from the deal automatically.
|
|
105
|
+
- Custom line items (no catalog id): pass `{ name, price, quantity }` without `id`.
|
|
106
|
+
- Commerce catalog variants (SKU variants) require `catalog` scope on the MCP token; if 401, fall back to custom line item and note the MCP gap.
|
|
107
|
+
|
|
72
108
|
## Lead — Create + Products
|
|
73
109
|
|
|
74
110
|
Use lead when the prospect is unqualified or missing deal-level budget/timeline.
|
|
@@ -129,6 +165,7 @@ Omit `idempotencyKey`. **Verified 2026-05-15:** D1 table `idempotency_keys` miss
|
|
|
129
165
|
- [ ] Contact: VN phone stored with `+84`; HONORIFIC matches [vn-norms.md](./vn-norms.md).
|
|
130
166
|
- [ ] Company: `RQ_VAT_ID` populated, address entity exists, MST format valid.
|
|
131
167
|
- [ ] Deal: `STAGE_ID` set, `OPPORTUNITY > 0`, payer linked.
|
|
168
|
+
- [ ] Deal (with products): products set; `OPPORTUNITY` matches product total.
|
|
132
169
|
- [ ] Lead: `SOURCE_ID` set, phone/email present, products set when user requested products.
|
|
133
170
|
- [ ] Update: only intended fields changed.
|
|
134
171
|
|
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: bitrix-sync-install
|
|
3
|
-
description: |
|
|
4
|
-
Install Bitrix Task Sync vào brownfield project (existing repo).
|
|
5
|
-
Wraps `npx @synity/bitrix-task-sync` với interactive TASK_ID setup,
|
|
6
|
-
webhook env var detection, và live verify smoke test.
|
|
7
|
-
|
|
8
|
-
Use when:
|
|
9
|
-
- User says "install bitrix sync", "setup task tracking", "thêm bitrix sync vào dự án"
|
|
10
|
-
- User asks how to enable AI session sync to Bitrix24 task chat
|
|
11
|
-
- Brownfield project not scaffolded by `create-bitrix-app`
|
|
12
|
-
tools: [Bash, Read, Edit, AskUserQuestion]
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
# /bitrix-sync-install — Install Bitrix Task Sync (interactive)
|
|
16
|
-
|
|
17
|
-
Orchestrate installation of [@synity/bitrix-task-sync](https://www.npmjs.com/package/@synity/bitrix-task-sync) into the current project. **Skill = thin wrapper** — all file copy / settings merge / githook setup is delegated to the npm CLI. Skill only handles interactive bits CLI cannot do (CLAUDE.md edit, env var detection, user confirmation gates).
|
|
18
|
-
|
|
19
|
-
## Workflow (7 steps with user confirmation)
|
|
20
|
-
|
|
21
|
-
### Step 1 — Detect project state
|
|
22
|
-
|
|
23
|
-
Run via Bash to inspect current dir:
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
pwd && ls -la .claude .githooks docs CLAUDE.md 2>/dev/null
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
Show user what already exists. **Decision:**
|
|
30
|
-
- If `.claude/scripts/bitrix-*.sh` already exists → skip to Step 7 (verify only)
|
|
31
|
-
- Else → proceed Step 2
|
|
32
|
-
|
|
33
|
-
### Step 2 — Preflight check
|
|
34
|
-
|
|
35
|
-
Confirm bash deps present:
|
|
36
|
-
|
|
37
|
-
```bash
|
|
38
|
-
command -v jq && command -v curl && command -v awk && echo "OK"
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
If any missing → abort, instruct user to install (`brew install jq` on macOS).
|
|
42
|
-
|
|
43
|
-
### Step 3 — Dry-run install
|
|
44
|
-
|
|
45
|
-
```bash
|
|
46
|
-
npx -y @synity/bitrix-skills install --dry-run
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
Show planned actions. **Always pin exact version** (never `@latest`).
|
|
50
|
-
|
|
51
|
-
### Step 4 — Confirm + install
|
|
52
|
-
|
|
53
|
-
Use `AskUserQuestion`:
|
|
54
|
-
|
|
55
|
-
```
|
|
56
|
-
Question: "Proceed with install? (review the dry-run plan above)"
|
|
57
|
-
Options:
|
|
58
|
-
- "Yes, install" — runs `npx ... install`
|
|
59
|
-
- "No, abort" — exit skill
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
If yes:
|
|
63
|
-
|
|
64
|
-
```bash
|
|
65
|
-
npx -y @synity/bitrix-skills install
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
### Step 5 — TASK_ID setup
|
|
69
|
-
|
|
70
|
-
Read `CLAUDE.md` (project root). Search for `TASK_ID:` pattern.
|
|
71
|
-
|
|
72
|
-
**Missing case:**
|
|
73
|
-
1. `AskUserQuestion` for `PORTAL` URL (e.g. `https://yourname.bitrix24.com`)
|
|
74
|
-
2. `AskUserQuestion` for `TASK_ID` (numeric task ID from Bitrix24 task URL)
|
|
75
|
-
3. Validate `TASK_ID` is numeric (reject `1234abc`)
|
|
76
|
-
4. Use `Edit` to insert at end of CLAUDE.md:
|
|
77
|
-
|
|
78
|
-
```markdown
|
|
79
|
-
|
|
80
|
-
## Bitrix Task
|
|
81
|
-
|
|
82
|
-
PORTAL: {portal_url}
|
|
83
|
-
TASK_ID: {task_id}
|
|
84
|
-
|
|
85
|
-
<!-- AI session activity auto-syncs to this task via .claude/scripts/bitrix-*.sh hooks -->
|
|
86
|
-
<!-- See docs/bitrix-task-sync.md for setup details -->
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
**Present case:** display existing TASK_ID + ask user to confirm or update.
|
|
90
|
-
|
|
91
|
-
### Step 6 — Webhook env var
|
|
92
|
-
|
|
93
|
-
Check current shell env:
|
|
94
|
-
|
|
95
|
-
```bash
|
|
96
|
-
[ -n "$BITRIX_WEBHOOK_URL" ] && echo SET || echo UNSET
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
If `UNSET`, `AskUserQuestion`:
|
|
100
|
-
|
|
101
|
-
```
|
|
102
|
-
Question: "Where to add BITRIX_WEBHOOK_URL?"
|
|
103
|
-
Options:
|
|
104
|
-
- ".envrc (direnv)"
|
|
105
|
-
- "~/.zshrc"
|
|
106
|
-
- "~/.bashrc"
|
|
107
|
-
- "Skip — I'll do it manually"
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
Print the exact `export` command. Wait for user to confirm they ran `source <file>` (or restarted shell). **NEVER auto-edit shell rc files** — could conflict with user's setup.
|
|
111
|
-
|
|
112
|
-
Example output:
|
|
113
|
-
```
|
|
114
|
-
Add this line to ~/.zshrc:
|
|
115
|
-
export BITRIX_WEBHOOK_URL="https://yourname.bitrix24.com/rest/USER_ID/TOKEN/"
|
|
116
|
-
Then run: source ~/.zshrc
|
|
117
|
-
|
|
118
|
-
(Press confirm when done)
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
### Step 7 — Verify
|
|
122
|
-
|
|
123
|
-
```bash
|
|
124
|
-
npx -y @synity/bitrix-skills verify
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
Interpret exit codes:
|
|
128
|
-
|
|
129
|
-
| Code | Meaning | User Action |
|
|
130
|
-
|------|---------|-------------|
|
|
131
|
-
| 0 | Success — comment posted | Done. |
|
|
132
|
-
| 1 | TASK_ID missing in CLAUDE.md | Re-run Step 5 |
|
|
133
|
-
| 2 | BITRIX_WEBHOOK_URL not set | Re-run Step 6 |
|
|
134
|
-
| 3 | Webhook call failed (network/token error) | Verify webhook URL is correct + has perms |
|
|
135
|
-
| 4 | Manifest drift detected | Run `npx @synity/bitrix-task-sync update` to repair |
|
|
136
|
-
|
|
137
|
-
## Final summary
|
|
138
|
-
|
|
139
|
-
On success, print:
|
|
140
|
-
|
|
141
|
-
```
|
|
142
|
-
✓ Bitrix Task Sync installed and verified
|
|
143
|
-
|
|
144
|
-
Next: every commit must include [B24:{TASK_ID}] tag, e.g.:
|
|
145
|
-
feat: implement deal sync [B24:{task_id}]
|
|
146
|
-
|
|
147
|
-
AI activity (skills) auto-syncs to: {portal_url}/company/personal/user/USER/tasks/task/view/{task_id}/
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
## Failure modes
|
|
151
|
-
|
|
152
|
-
| Symptom | Likely cause | Fix |
|
|
153
|
-
|---------|--------------|-----|
|
|
154
|
-
| `command not found: jq` | macOS without homebrew | `brew install jq curl` |
|
|
155
|
-
| `npx: not found` | Node not installed | Install Node 20+ from nodejs.org |
|
|
156
|
-
| `git: not a repository` | Not in git repo | `git init` first |
|
|
157
|
-
| Webhook returns 401 | Bad token | Regenerate webhook in Bitrix24 → Apps → Webhooks |
|
|
158
|
-
| `TASK_ID: 1234abc` rejected | Non-numeric value | Use ID from task URL, e.g. `12345` |
|
|
159
|
-
|
|
160
|
-
## Re-run behavior
|
|
161
|
-
|
|
162
|
-
Re-running on already-installed project:
|
|
163
|
-
- Step 1 detects existing `.claude/scripts/bitrix-*.sh`
|
|
164
|
-
- Skips to Step 7 (verify only)
|
|
165
|
-
- If verify passes → "Already installed and working"
|
|
166
|
-
- If verify fails → suggests `update` command
|
|
167
|
-
|
|
168
|
-
## Notes
|
|
169
|
-
|
|
170
|
-
- **Pin version**: every `npx` example uses `@0.1.0` exact pin. Never `@latest`. User must explicitly bump after reading CHANGELOG.
|
|
171
|
-
- **Project-scope only**: skill operates on current cwd's git root. Does NOT touch other projects.
|
|
172
|
-
- **Idempotent**: re-run = no-op if state is good.
|
|
173
|
-
- **No secrets logged**: skill never echoes `BITRIX_WEBHOOK_URL` value, only its set/unset status.
|