@synity/bitrix-skills 1.3.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/bin/bitrix-skills.js +0 -0
- package/dist/cli.js +74 -31
- package/dist/features/task-sync/index.js +0 -0
- package/package.json +13 -16
- package/src/features/bx/feature.json +5 -3
- package/src/features/bx-calendar/feature.json +7 -3
- package/src/features/bx-crm/feature.json +7 -3
- package/src/features/bx-task/assets/lib/bx-api.sh +0 -0
- package/src/features/bx-task/assets/lib/bx-resolve-task.sh +0 -0
- package/src/features/bx-task/feature.json +6 -3
- package/src/features/task-sync/assets/githooks/commit-msg +0 -0
- package/src/features/task-sync/assets/githooks/install.sh +0 -0
- package/src/features/task-sync/assets/scripts/bitrix-attach-files.sh +0 -0
- package/src/features/task-sync/assets/scripts/bitrix-lib.sh +0 -0
- package/src/features/task-sync/assets/scripts/bitrix-render-digest.sh +0 -0
- package/src/features/task-sync/assets/scripts/bitrix-session-check.sh +0 -0
- package/src/features/task-sync/assets/scripts/bitrix-session-sync.sh +0 -0
- package/src/features/task-sync/assets/scripts/bitrix-skill-end.sh +0 -0
- package/src/features/task-sync/assets/scripts/bitrix-skill-start.sh +0 -0
- package/src/features/task-sync/feature.json +9 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.3.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- dfe3549: fix: mark stub features (bx, bx-calendar, bx-crm) as `planned`
|
|
8
|
+
|
|
9
|
+
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.
|
|
10
|
+
|
|
11
|
+
Now they're filtered out by the existing `f.status !== 'planned'` check (install.ts:121). Will flip back to `active` when install handlers land.
|
|
12
|
+
|
|
3
13
|
## 1.3.0
|
|
4
14
|
|
|
5
15
|
### Minor Changes
|
package/bin/bitrix-skills.js
CHANGED
|
File without changes
|
package/dist/cli.js
CHANGED
|
@@ -947,6 +947,7 @@ 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 { createInterface } from "readline";
|
|
950
951
|
import { join as join4, relative as relative2 } from "path";
|
|
951
952
|
|
|
952
953
|
// src/lib/feature-registry.ts
|
|
@@ -992,6 +993,32 @@ function listFeatures(featuresDir) {
|
|
|
992
993
|
return features;
|
|
993
994
|
}
|
|
994
995
|
|
|
996
|
+
// src/lib/license.ts
|
|
997
|
+
init_esm_shims();
|
|
998
|
+
var LICENSE_WORKER_URL = "https://license-gate.synity.workers.dev";
|
|
999
|
+
async function verifyLicense(key) {
|
|
1000
|
+
if (!key || key.trim() === "") {
|
|
1001
|
+
return { ok: true, tier: 0 };
|
|
1002
|
+
}
|
|
1003
|
+
try {
|
|
1004
|
+
const res = await fetch(`${LICENSE_WORKER_URL}/verify`, {
|
|
1005
|
+
method: "POST",
|
|
1006
|
+
headers: { "Content-Type": "application/json" },
|
|
1007
|
+
body: JSON.stringify({ key: key.trim() }),
|
|
1008
|
+
signal: AbortSignal.timeout(8e3)
|
|
1009
|
+
});
|
|
1010
|
+
if (!res.ok) {
|
|
1011
|
+
const body = await res.json().catch(() => ({}));
|
|
1012
|
+
return { ok: false, tier: 0, error: body["error"] ?? `HTTP ${res.status}` };
|
|
1013
|
+
}
|
|
1014
|
+
const data = await res.json();
|
|
1015
|
+
return { ok: true, tier: data.tier ?? 0, email: data.email, expiresAt: data.expiresAt };
|
|
1016
|
+
} catch (err) {
|
|
1017
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1018
|
+
return { ok: false, tier: 0, error: `Network error: ${msg}` };
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
|
|
995
1022
|
// src/lib/manifest.ts
|
|
996
1023
|
init_esm_shims();
|
|
997
1024
|
import { createHash } from "crypto";
|
|
@@ -1018,6 +1045,15 @@ function computeChecksum(filepath) {
|
|
|
1018
1045
|
}
|
|
1019
1046
|
|
|
1020
1047
|
// src/commands/install.ts
|
|
1048
|
+
function promptKey() {
|
|
1049
|
+
return new Promise((resolve2) => {
|
|
1050
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
1051
|
+
rl.question(chalk.cyan("License key (Enter to skip \u2014 free tier only): "), (answer) => {
|
|
1052
|
+
rl.close();
|
|
1053
|
+
resolve2(answer.trim());
|
|
1054
|
+
});
|
|
1055
|
+
});
|
|
1056
|
+
}
|
|
1021
1057
|
var DEFAULT_CLI_OPTS = {
|
|
1022
1058
|
dryRun: false,
|
|
1023
1059
|
force: false,
|
|
@@ -1075,16 +1111,17 @@ var InstallCommand = class extends Command {
|
|
|
1075
1111
|
static usage = Command.Usage({
|
|
1076
1112
|
description: "Install features into the current project",
|
|
1077
1113
|
details: `
|
|
1078
|
-
|
|
1079
|
-
|
|
1114
|
+
Installs all free features automatically.
|
|
1115
|
+
With a license key (--key or prompted), unlocks paid tier features.
|
|
1116
|
+
Pass feature names to install specific features only.
|
|
1080
1117
|
`,
|
|
1081
1118
|
examples: [
|
|
1082
|
-
["Install all features", "bitrix-skills install
|
|
1083
|
-
["Install
|
|
1084
|
-
["
|
|
1119
|
+
["Install all free features", "bitrix-skills install"],
|
|
1120
|
+
["Install with license key", "bitrix-skills install --key YOUR_KEY"],
|
|
1121
|
+
["Install specific features", "bitrix-skills install task-sync bx-task"]
|
|
1085
1122
|
]
|
|
1086
1123
|
});
|
|
1087
|
-
|
|
1124
|
+
key = Option.String("--key", { description: "License key to unlock paid tier features" });
|
|
1088
1125
|
featuresFlag = Option.String("--features", { description: "Comma-separated feature names" });
|
|
1089
1126
|
featureArgs = Option.Rest({ required: 0 });
|
|
1090
1127
|
async execute() {
|
|
@@ -1101,36 +1138,32 @@ var InstallCommand = class extends Command {
|
|
|
1101
1138
|
)
|
|
1102
1139
|
);
|
|
1103
1140
|
}
|
|
1141
|
+
let userTier = 0;
|
|
1142
|
+
const rawKey = this.key ?? (process.stdin.isTTY ? await promptKey() : "");
|
|
1143
|
+
if (rawKey) {
|
|
1144
|
+
const license = await verifyLicense(rawKey);
|
|
1145
|
+
if (!license.ok) {
|
|
1146
|
+
this.context.stderr.write(chalk.red(` \u2717 License error: ${license.error}
|
|
1147
|
+
`));
|
|
1148
|
+
this.context.stderr.write(chalk.gray(" Continuing with free tier only.\n"));
|
|
1149
|
+
} else {
|
|
1150
|
+
userTier = license.tier;
|
|
1151
|
+
const tierLabel = userTier === 0 ? "free" : `tier ${userTier}`;
|
|
1152
|
+
const who = license.email ? ` (${license.email})` : "";
|
|
1153
|
+
this.context.stdout.write(chalk.green(` \u2713 License verified${who} \u2014 ${tierLabel}
|
|
1154
|
+
`));
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1104
1157
|
let selectedNames;
|
|
1105
|
-
const installable = available.filter(
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1158
|
+
const installable = available.filter(
|
|
1159
|
+
(f) => f.status !== "planned" && (f.tier ?? 0) <= userTier
|
|
1160
|
+
);
|
|
1161
|
+
if (this.featuresFlag) {
|
|
1109
1162
|
selectedNames = this.featuresFlag.split(",").map((s) => s.trim()).filter(Boolean);
|
|
1110
1163
|
} else if (this.featureArgs.length > 0) {
|
|
1111
1164
|
selectedNames = this.featureArgs;
|
|
1112
1165
|
} else {
|
|
1113
|
-
|
|
1114
|
-
this.context.stderr.write(
|
|
1115
|
-
chalk.red("error: no TTY detected. Use --all or specify feature names.\n")
|
|
1116
|
-
);
|
|
1117
|
-
return 1;
|
|
1118
|
-
}
|
|
1119
|
-
const checkbox = (await import("@inquirer/checkbox")).default;
|
|
1120
|
-
const choices = installable.map((f) => ({
|
|
1121
|
-
name: `${f.name} \u2014 ${f.description}`,
|
|
1122
|
-
value: f.name,
|
|
1123
|
-
checked: false
|
|
1124
|
-
}));
|
|
1125
|
-
const picked = await checkbox({
|
|
1126
|
-
message: "Select features to install:",
|
|
1127
|
-
choices
|
|
1128
|
-
});
|
|
1129
|
-
if (picked.length === 0) {
|
|
1130
|
-
this.context.stdout.write(chalk.gray("No features selected.\n"));
|
|
1131
|
-
return 0;
|
|
1132
|
-
}
|
|
1133
|
-
selectedNames = picked;
|
|
1166
|
+
selectedNames = installable.map((f) => f.name);
|
|
1134
1167
|
}
|
|
1135
1168
|
const availableNames = new Set(available.map((f) => f.name));
|
|
1136
1169
|
const invalid = selectedNames.filter((n) => !availableNames.has(n));
|
|
@@ -1141,6 +1174,16 @@ var InstallCommand = class extends Command {
|
|
|
1141
1174
|
`));
|
|
1142
1175
|
return 1;
|
|
1143
1176
|
}
|
|
1177
|
+
const tierLocked = selectedNames.filter((n) => {
|
|
1178
|
+
const f = available.find((a) => a.name === n);
|
|
1179
|
+
return f && (f.tier ?? 0) > userTier;
|
|
1180
|
+
});
|
|
1181
|
+
if (tierLocked.length > 0) {
|
|
1182
|
+
this.context.stderr.write(chalk.red(`Tier-locked features: ${tierLocked.join(", ")}
|
|
1183
|
+
`));
|
|
1184
|
+
this.context.stderr.write(chalk.gray(" Provide a valid license key via --key to unlock.\n"));
|
|
1185
|
+
return 1;
|
|
1186
|
+
}
|
|
1144
1187
|
const existing = readManifest(cwd);
|
|
1145
1188
|
let manifest = existing ?? { version: "1", features: [] };
|
|
1146
1189
|
let anyFailure = false;
|
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@synity/bitrix-skills",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "Multi-feature Bitrix24 tooling CLI for Synity projects",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -24,18 +24,6 @@
|
|
|
24
24
|
"engines": {
|
|
25
25
|
"node": ">=20"
|
|
26
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
27
|
"publishConfig": {
|
|
40
28
|
"access": "public"
|
|
41
29
|
},
|
|
@@ -51,8 +39,6 @@
|
|
|
51
39
|
"author": "Synity Vietnam JSC <tech@synity.vn>",
|
|
52
40
|
"license": "MIT",
|
|
53
41
|
"dependencies": {
|
|
54
|
-
"@inquirer/checkbox": "^5.1.5",
|
|
55
|
-
"@inquirer/confirm": "^6.0.13",
|
|
56
42
|
"chalk": "^5.6.2",
|
|
57
43
|
"clipanion": "4.0.0-rc.4",
|
|
58
44
|
"deepmerge": "^4.3.1",
|
|
@@ -65,5 +51,16 @@
|
|
|
65
51
|
"tsup": "^8.0.0",
|
|
66
52
|
"typescript": "^5.4.0",
|
|
67
53
|
"vitest": "^2.1.0"
|
|
54
|
+
},
|
|
55
|
+
"scripts": {
|
|
56
|
+
"prebuild": "node scripts/prebuild-bash-sync.mjs && node scripts/sync-assets.mjs",
|
|
57
|
+
"build": "tsup --config tsup.config.ts",
|
|
58
|
+
"dev": "tsup --config tsup.config.ts --watch",
|
|
59
|
+
"test": "vitest run",
|
|
60
|
+
"test:watch": "vitest",
|
|
61
|
+
"lint": "eslint src --ext .ts",
|
|
62
|
+
"release": "pnpm build && changeset publish",
|
|
63
|
+
"version": "changeset version",
|
|
64
|
+
"changeset": "changeset"
|
|
68
65
|
}
|
|
69
|
-
}
|
|
66
|
+
}
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
"displayName": "Bitrix Hub Skill",
|
|
4
4
|
"version": "1.0.0",
|
|
5
5
|
"target": "global",
|
|
6
|
-
"description": "Claude Code hub skill
|
|
7
|
-
"
|
|
8
|
-
}
|
|
6
|
+
"description": "Claude Code hub skill \u2014 routes to bx:crm, bx:task, bx:calendar. Install for discovery UX.",
|
|
7
|
+
"status": "planned",
|
|
8
|
+
"requires": {},
|
|
9
|
+
"tier": 0
|
|
10
|
+
}
|
|
@@ -4,7 +4,11 @@
|
|
|
4
4
|
"version": "1.0.0",
|
|
5
5
|
"target": "global",
|
|
6
6
|
"description": "Claude Code skill for Bitrix24 Calendar: meetings, reminders, team availability, CRM activity sync",
|
|
7
|
+
"status": "planned",
|
|
7
8
|
"requires": {
|
|
8
|
-
"env": [
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
"env": [
|
|
10
|
+
"BITRIX_WEBHOOK_URL"
|
|
11
|
+
]
|
|
12
|
+
},
|
|
13
|
+
"tier": 0
|
|
14
|
+
}
|
|
@@ -4,7 +4,11 @@
|
|
|
4
4
|
"version": "2.0.0",
|
|
5
5
|
"target": "global",
|
|
6
6
|
"description": "Claude Code skill for Bitrix24 CRM: contacts, companies, deals, leads, estimates, invoices, customer analysis, pipeline reports",
|
|
7
|
+
"status": "planned",
|
|
7
8
|
"requires": {
|
|
8
|
-
"mcp": [
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
"mcp": [
|
|
10
|
+
"bitrix-synity-mcp"
|
|
11
|
+
]
|
|
12
|
+
},
|
|
13
|
+
"tier": 0
|
|
14
|
+
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -4,9 +4,14 @@
|
|
|
4
4
|
"version": "0.3.0-pre",
|
|
5
5
|
"target": "project",
|
|
6
6
|
"description": "AI session sync to Bitrix task chat via hooks",
|
|
7
|
-
"needs": [
|
|
7
|
+
"needs": [
|
|
8
|
+
"bash-lib"
|
|
9
|
+
],
|
|
8
10
|
"requires": {
|
|
9
|
-
"env": [
|
|
11
|
+
"env": [
|
|
12
|
+
"BITRIX_WEBHOOK_URL"
|
|
13
|
+
],
|
|
10
14
|
"task_id": true
|
|
11
|
-
}
|
|
12
|
-
|
|
15
|
+
},
|
|
16
|
+
"tier": 0
|
|
17
|
+
}
|