@synity/bitrix-skills 1.3.5 → 1.3.7
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 +8 -4
- package/README.md +19 -6
- package/dist/cli.js +5 -62
- package/package.json +1 -1
- package/src/features/bx/feature.json +1 -0
- package/src/features/bx-calendar/feature.json +1 -0
- package/src/features/bx-crm/assets/SKILL.md +1 -1
- package/src/features/bx-crm/assets/onboard.md +0 -37
- package/src/features/bx-crm/feature.json +1 -0
- package/src/features/task-sync/assets/manifest.json +2 -2
- package/src/features/task-sync/assets/skill/SKILL.md +196 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 1.3.
|
|
3
|
+
## 1.3.7
|
|
4
4
|
|
|
5
5
|
### Patch Changes
|
|
6
6
|
|
|
7
|
-
- fix(
|
|
7
|
+
- fix(task-sync): add missing assets/skill/SKILL.md that caused ENOENT on update
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
docs(task-sync): document --key flag and fix stale package name (@synity/bitrix-task-sync → @synity/bitrix-skills) in SKILL.md and README to prevent agent hallucinating --token flag
|
|
10
10
|
|
|
11
11
|
## 1.3.1
|
|
12
12
|
|
|
13
13
|
### Patch Changes
|
|
14
14
|
|
|
15
|
-
-
|
|
15
|
+
- dfe3549: fix: mark stub features (bx, bx-calendar, bx-crm) as `planned`
|
|
16
|
+
|
|
17
|
+
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.
|
|
18
|
+
|
|
19
|
+
Now they're filtered out by the existing `f.status !== 'planned'` check (install.ts:121). Will flip back to `active` when install handlers land.
|
|
16
20
|
|
|
17
21
|
## 1.3.0
|
|
18
22
|
|
package/README.md
CHANGED
|
@@ -31,15 +31,28 @@ npx @synity/bitrix-skills install --all # all features
|
|
|
31
31
|
npx @synity/bitrix-skills install task-sync # specific feature
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
+
### Paid features (`task-sync`)
|
|
35
|
+
|
|
36
|
+
`task-sync` requires a license key to unlock:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npx @synity/bitrix-skills install task-sync --key <your-license-key>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Free tier installs all other features (`bx`, `bx-task`, `bx-crm`, `bx-calendar`) without a key.
|
|
43
|
+
|
|
44
|
+
> **Note:** The flag is `--key`, not `--token`.
|
|
45
|
+
|
|
34
46
|
## Commands
|
|
35
47
|
|
|
36
48
|
```bash
|
|
37
|
-
bitrix-skills install [features...]
|
|
38
|
-
bitrix-skills install --all
|
|
39
|
-
bitrix-skills
|
|
40
|
-
bitrix-skills
|
|
41
|
-
bitrix-skills
|
|
42
|
-
bitrix-skills
|
|
49
|
+
bitrix-skills install [features...] # install with picker or by name
|
|
50
|
+
bitrix-skills install --all # install all features
|
|
51
|
+
bitrix-skills install task-sync --key <key> # install paid feature with license key
|
|
52
|
+
bitrix-skills list # show available + installed status
|
|
53
|
+
bitrix-skills verify # verify installed file checksums
|
|
54
|
+
bitrix-skills update # update installed features to latest
|
|
55
|
+
bitrix-skills uninstall <feature> # remove a feature
|
|
43
56
|
bitrix-skills --version
|
|
44
57
|
```
|
|
45
58
|
|
package/dist/cli.js
CHANGED
|
@@ -947,11 +947,8 @@ init_esm_shims();
|
|
|
947
947
|
import { Command, Option } from "clipanion";
|
|
948
948
|
import chalk from "chalk";
|
|
949
949
|
import { existsSync as existsSync4 } from "fs";
|
|
950
|
-
import { access as access4, mkdir as mkdir4, copyFile as copyFile3, readdir as readdir2 } from "fs/promises";
|
|
951
950
|
import { createInterface } from "readline";
|
|
952
|
-
import {
|
|
953
|
-
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
954
|
-
import { homedir as homedir2 } from "os";
|
|
951
|
+
import { join as join4, relative as relative2 } from "path";
|
|
955
952
|
|
|
956
953
|
// src/lib/feature-registry.ts
|
|
957
954
|
init_esm_shims();
|
|
@@ -1049,11 +1046,11 @@ function computeChecksum(filepath) {
|
|
|
1049
1046
|
|
|
1050
1047
|
// src/commands/install.ts
|
|
1051
1048
|
function promptKey() {
|
|
1052
|
-
return new Promise((
|
|
1049
|
+
return new Promise((resolve2) => {
|
|
1053
1050
|
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
1054
1051
|
rl.question(chalk.cyan("License key (Enter to skip \u2014 free tier only): "), (answer) => {
|
|
1055
1052
|
rl.close();
|
|
1056
|
-
|
|
1053
|
+
resolve2(answer.trim());
|
|
1057
1054
|
});
|
|
1058
1055
|
});
|
|
1059
1056
|
}
|
|
@@ -1089,55 +1086,6 @@ async function installTaskSync(cwd) {
|
|
|
1089
1086
|
return { ok: false, message: `task-sync: ${err.message}` };
|
|
1090
1087
|
}
|
|
1091
1088
|
}
|
|
1092
|
-
async function getGlobalSkillAssetsDir(name) {
|
|
1093
|
-
const here = dirname3(fileURLToPath5(import.meta.url));
|
|
1094
|
-
const candidates = [
|
|
1095
|
-
resolve2(here, `../../src/features/${name}/assets`),
|
|
1096
|
-
// dist/commands/install.js
|
|
1097
|
-
resolve2(here, `../src/features/${name}/assets`),
|
|
1098
|
-
// dist/cli.js (inlined bundle)
|
|
1099
|
-
resolve2(here, `../features/${name}/assets`)
|
|
1100
|
-
// src/commands/ (dev/ts-node)
|
|
1101
|
-
];
|
|
1102
|
-
for (const c of candidates) {
|
|
1103
|
-
try {
|
|
1104
|
-
await access4(c);
|
|
1105
|
-
return c;
|
|
1106
|
-
} catch {
|
|
1107
|
-
}
|
|
1108
|
-
}
|
|
1109
|
-
return candidates[0];
|
|
1110
|
-
}
|
|
1111
|
-
async function copyDirRecursive(srcDir, destDir, files) {
|
|
1112
|
-
await mkdir4(destDir, { recursive: true });
|
|
1113
|
-
const entries = await readdir2(srcDir, { withFileTypes: true });
|
|
1114
|
-
for (const entry of entries) {
|
|
1115
|
-
const srcPath = join4(srcDir, entry.name);
|
|
1116
|
-
const destPath = join4(destDir, entry.name);
|
|
1117
|
-
if (entry.isDirectory()) {
|
|
1118
|
-
await copyDirRecursive(srcPath, destPath, files);
|
|
1119
|
-
} else {
|
|
1120
|
-
await copyFile3(srcPath, destPath);
|
|
1121
|
-
files.push(destPath);
|
|
1122
|
-
}
|
|
1123
|
-
}
|
|
1124
|
-
}
|
|
1125
|
-
async function installGlobalSkill(name) {
|
|
1126
|
-
const skillDest = resolve2(homedir2(), ".claude", "skills", name);
|
|
1127
|
-
const installedAbsPaths = [];
|
|
1128
|
-
try {
|
|
1129
|
-
const assetsDir = await getGlobalSkillAssetsDir(name);
|
|
1130
|
-
await copyDirRecursive(assetsDir, skillDest, installedAbsPaths);
|
|
1131
|
-
return {
|
|
1132
|
-
ok: true,
|
|
1133
|
-
message: `${name}: ${installedAbsPaths.length} files \u2192 ${skillDest}`,
|
|
1134
|
-
installPath: skillDest,
|
|
1135
|
-
installedAbsPaths
|
|
1136
|
-
};
|
|
1137
|
-
} catch (err) {
|
|
1138
|
-
return { ok: false, message: `${name}: ${err.message}`, installPath: skillDest, installedAbsPaths };
|
|
1139
|
-
}
|
|
1140
|
-
}
|
|
1141
1089
|
async function installBxTask(cwd) {
|
|
1142
1090
|
try {
|
|
1143
1091
|
const { install: install2 } = await Promise.resolve().then(() => (init_install2(), install_exports2));
|
|
@@ -1259,15 +1207,10 @@ Installing ${chalk.bold(name)}...
|
|
|
1259
1207
|
ok = r.ok;
|
|
1260
1208
|
message = r.message;
|
|
1261
1209
|
if (r.installPath) {
|
|
1262
|
-
|
|
1210
|
+
const { homedir: homedir2 } = await import("os");
|
|
1211
|
+
installPath = join4(homedir2(), ".claude", "skills", "bx-task");
|
|
1263
1212
|
}
|
|
1264
1213
|
installedAbsPaths = r.installedAbsPaths ?? [];
|
|
1265
|
-
} else if (featureInfo.target === "global") {
|
|
1266
|
-
const r = await installGlobalSkill(name);
|
|
1267
|
-
ok = r.ok;
|
|
1268
|
-
message = r.message;
|
|
1269
|
-
installPath = r.installPath;
|
|
1270
|
-
installedAbsPaths = r.installedAbsPaths;
|
|
1271
1214
|
} else {
|
|
1272
1215
|
this.context.stderr.write(chalk.yellow(` ! No install handler for feature: ${name}
|
|
1273
1216
|
`));
|
package/package.json
CHANGED
|
@@ -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` |
|
|
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,42 +69,6 @@ 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
|
-
|
|
108
72
|
## Lead — Create + Products
|
|
109
73
|
|
|
110
74
|
Use lead when the prospect is unqualified or missing deal-level budget/timeline.
|
|
@@ -165,7 +129,6 @@ Omit `idempotencyKey`. **Verified 2026-05-15:** D1 table `idempotency_keys` miss
|
|
|
165
129
|
- [ ] Contact: VN phone stored with `+84`; HONORIFIC matches [vn-norms.md](./vn-norms.md).
|
|
166
130
|
- [ ] Company: `RQ_VAT_ID` populated, address entity exists, MST format valid.
|
|
167
131
|
- [ ] Deal: `STAGE_ID` set, `OPPORTUNITY > 0`, payer linked.
|
|
168
|
-
- [ ] Deal (with products): products set; `OPPORTUNITY` matches product total.
|
|
169
132
|
- [ ] Lead: `SOURCE_ID` set, phone/email present, products set when user requested products.
|
|
170
133
|
- [ ] Update: only intended fields changed.
|
|
171
134
|
|
|
@@ -100,8 +100,8 @@
|
|
|
100
100
|
},
|
|
101
101
|
{
|
|
102
102
|
"src": "skill/SKILL.md",
|
|
103
|
-
"sha256": "
|
|
104
|
-
"size":
|
|
103
|
+
"sha256": "c9c954308515242f9c4c9d935a6bb456d4b3fee10513dc9e7c835d61bf10ff27",
|
|
104
|
+
"size": 6230,
|
|
105
105
|
"mode": 420
|
|
106
106
|
}
|
|
107
107
|
]
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bitrix-sync-install
|
|
3
|
+
description: |
|
|
4
|
+
Install Bitrix Task Sync vào brownfield project (existing repo).
|
|
5
|
+
Wraps `npx @synity/bitrix-skills` 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-skills](https://www.npmjs.com/package/@synity/bitrix-skills) 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
|
+
> **IMPORTANT — flag names:** The CLI uses `--key` for license key. There is NO `--token` flag. Using `--token` causes `Unknown Syntax Error`. Always use `--key`.
|
|
20
|
+
|
|
21
|
+
## Workflow (7 steps with user confirmation)
|
|
22
|
+
|
|
23
|
+
### Step 1 — Detect project state
|
|
24
|
+
|
|
25
|
+
Run via Bash to inspect current dir:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pwd && ls -la .claude .githooks docs CLAUDE.md 2>/dev/null
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Show user what already exists. **Decision:**
|
|
32
|
+
- If `.claude/scripts/bitrix-*.sh` already exists → skip to Step 7 (verify only)
|
|
33
|
+
- Else → proceed Step 2
|
|
34
|
+
|
|
35
|
+
### Step 2 — Preflight check
|
|
36
|
+
|
|
37
|
+
Confirm bash deps present:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
command -v jq && command -v curl && command -v awk && echo "OK"
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
If any missing → abort, instruct user to install (`brew install jq` on macOS).
|
|
44
|
+
|
|
45
|
+
### Step 3 — Dry-run install
|
|
46
|
+
|
|
47
|
+
Check if user has a license key:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# Ask user: "Bạn có license key cho task-sync không?" (optional)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Dry-run:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# Without key (free tier — installs bx, bx-task, bx-crm, bx-calendar; skips task-sync):
|
|
57
|
+
npx -y @synity/bitrix-skills install task-sync --dry-run
|
|
58
|
+
|
|
59
|
+
# With key (unlocks task-sync):
|
|
60
|
+
npx -y @synity/bitrix-skills install task-sync --key <license-key> --dry-run
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Show planned actions.
|
|
64
|
+
|
|
65
|
+
> **Flag:** `--key` — NOT `--token`. There is no `--token` flag in this CLI.
|
|
66
|
+
|
|
67
|
+
### Step 4 — Confirm + install
|
|
68
|
+
|
|
69
|
+
Use `AskUserQuestion`:
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
Question: "Proceed with install? (review the dry-run plan above)"
|
|
73
|
+
Options:
|
|
74
|
+
- "Yes, install" — runs `npx ... install`
|
|
75
|
+
- "No, abort" — exit skill
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
If yes:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
# Without key:
|
|
82
|
+
npx -y @synity/bitrix-skills install task-sync
|
|
83
|
+
|
|
84
|
+
# With key:
|
|
85
|
+
npx -y @synity/bitrix-skills install task-sync --key <license-key>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Step 5 — TASK_ID setup
|
|
89
|
+
|
|
90
|
+
Read `CLAUDE.md` (project root). Search for `TASK_ID:` pattern.
|
|
91
|
+
|
|
92
|
+
**Missing case:**
|
|
93
|
+
1. `AskUserQuestion` for `PORTAL` URL (e.g. `https://yourname.bitrix24.com`)
|
|
94
|
+
2. `AskUserQuestion` for `TASK_ID` (numeric task ID from Bitrix24 task URL)
|
|
95
|
+
3. Validate `TASK_ID` is numeric (reject `1234abc`)
|
|
96
|
+
4. Use `Edit` to insert at end of CLAUDE.md:
|
|
97
|
+
|
|
98
|
+
```markdown
|
|
99
|
+
|
|
100
|
+
## Bitrix Task
|
|
101
|
+
|
|
102
|
+
PORTAL: {portal_url}
|
|
103
|
+
TASK_ID: {task_id}
|
|
104
|
+
|
|
105
|
+
<!-- AI session activity auto-syncs to this task via .claude/scripts/bitrix-*.sh hooks -->
|
|
106
|
+
<!-- See docs/bitrix-task-sync.md for setup details -->
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**Present case:** display existing TASK_ID + ask user to confirm or update.
|
|
110
|
+
|
|
111
|
+
### Step 6 — Webhook env var
|
|
112
|
+
|
|
113
|
+
Check current shell env:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
[ -n "$BITRIX_WEBHOOK_URL" ] && echo SET || echo UNSET
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
If `UNSET`, `AskUserQuestion`:
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
Question: "Where to add BITRIX_WEBHOOK_URL?"
|
|
123
|
+
Options:
|
|
124
|
+
- ".envrc (direnv)"
|
|
125
|
+
- "~/.zshrc"
|
|
126
|
+
- "~/.bashrc"
|
|
127
|
+
- "Skip — I'll do it manually"
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
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.
|
|
131
|
+
|
|
132
|
+
Example output:
|
|
133
|
+
```
|
|
134
|
+
Add this line to ~/.zshrc:
|
|
135
|
+
export BITRIX_WEBHOOK_URL="https://yourname.bitrix24.com/rest/USER_ID/TOKEN/"
|
|
136
|
+
Then run: source ~/.zshrc
|
|
137
|
+
|
|
138
|
+
(Press confirm when done)
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Step 7 — Verify
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
npx -y @synity/bitrix-skills verify
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Interpret exit codes:
|
|
148
|
+
|
|
149
|
+
| Code | Meaning | User Action |
|
|
150
|
+
|------|---------|-------------|
|
|
151
|
+
| 0 | Success — comment posted | Done. |
|
|
152
|
+
| 1 | TASK_ID missing in CLAUDE.md | Re-run Step 5 |
|
|
153
|
+
| 2 | BITRIX_WEBHOOK_URL not set | Re-run Step 6 |
|
|
154
|
+
| 3 | Webhook call failed (network/token error) | Verify webhook URL is correct + has perms |
|
|
155
|
+
| 4 | Manifest drift detected | Run `npx @synity/bitrix-skills update` to repair |
|
|
156
|
+
|
|
157
|
+
## Final summary
|
|
158
|
+
|
|
159
|
+
On success, print:
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
✓ Bitrix Task Sync installed and verified
|
|
163
|
+
|
|
164
|
+
Next: every commit must include [B24:{TASK_ID}] tag, e.g.:
|
|
165
|
+
feat: implement deal sync [B24:{task_id}]
|
|
166
|
+
|
|
167
|
+
AI activity (skills) auto-syncs to: {portal_url}/company/personal/user/USER/tasks/task/view/{task_id}/
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Failure modes
|
|
171
|
+
|
|
172
|
+
| Symptom | Likely cause | Fix |
|
|
173
|
+
|---------|--------------|-----|
|
|
174
|
+
| `command not found: jq` | macOS without homebrew | `brew install jq curl` |
|
|
175
|
+
| `npx: not found` | Node not installed | Install Node 20+ from nodejs.org |
|
|
176
|
+
| `git: not a repository` | Not in git repo | `git init` first |
|
|
177
|
+
| Webhook returns 401 | Bad token | Regenerate webhook in Bitrix24 → Apps → Webhooks |
|
|
178
|
+
| `TASK_ID: 1234abc` rejected | Non-numeric value | Use ID from task URL, e.g. `12345` |
|
|
179
|
+
| `Unknown Syntax Error: Invalid option name ("--token=...")` | Used `--token` instead of `--key` | **Always use `--key <value>`, never `--token`** |
|
|
180
|
+
| `task-sync: paid feature, key invalid` | License key not recognized | Verify key is correct; free tier skips task-sync |
|
|
181
|
+
|
|
182
|
+
## Re-run behavior
|
|
183
|
+
|
|
184
|
+
Re-running on already-installed project:
|
|
185
|
+
- Step 1 detects existing `.claude/scripts/bitrix-*.sh`
|
|
186
|
+
- Skips to Step 7 (verify only)
|
|
187
|
+
- If verify passes → "Already installed and working"
|
|
188
|
+
- If verify fails → suggests `npx @synity/bitrix-skills update`
|
|
189
|
+
|
|
190
|
+
## Notes
|
|
191
|
+
|
|
192
|
+
- **Package name**: `@synity/bitrix-skills` (NOT `@synity/bitrix-task-sync` — that is the old deprecated package).
|
|
193
|
+
- **License key flag**: `--key <value>` — there is NO `--token` flag. Using `--token` throws `Unknown Syntax Error`.
|
|
194
|
+
- **Project-scope only**: skill operates on current cwd's git root. Does NOT touch other projects.
|
|
195
|
+
- **Idempotent**: re-run = no-op if state is good.
|
|
196
|
+
- **No secrets logged**: skill never echoes `BITRIX_WEBHOOK_URL` value, only its set/unset status.
|