ccjk 12.0.6 → 12.0.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/README.md +14 -0
- package/README.zh-CN.md +13 -0
- package/dist/chunks/api-cli.mjs +1 -1
- package/dist/chunks/ccjk-agents.mjs +3 -2
- package/dist/chunks/ccjk-all.mjs +129 -1764
- package/dist/chunks/ccjk-hooks.mjs +5 -4
- package/dist/chunks/ccjk-mcp.mjs +7 -6
- package/dist/chunks/ccjk-setup.mjs +3 -2
- package/dist/chunks/ccjk-skills.mjs +6 -5
- package/dist/chunks/ccr.mjs +6 -5
- package/dist/chunks/check-updates.mjs +8 -8
- package/dist/chunks/claude-code-config-manager.mjs +1 -1
- package/dist/chunks/claude-code-incremental-manager.mjs +2 -2
- package/dist/chunks/codex-config-switch.mjs +1 -1
- package/dist/chunks/codex-provider-manager.mjs +1 -1
- package/dist/chunks/config-switch.mjs +1 -1
- package/dist/chunks/config.mjs +1 -1
- package/dist/chunks/config2.mjs +1 -1
- package/dist/chunks/config3.mjs +1 -1
- package/dist/chunks/constants.mjs +33 -2
- package/dist/chunks/dashboard.mjs +115 -3
- package/dist/chunks/features.mjs +3 -3
- package/dist/chunks/init.mjs +108 -4
- package/dist/chunks/installer2.mjs +7 -7
- package/dist/chunks/manager.mjs +1048 -0
- package/dist/chunks/mcp-cli.mjs +1 -1
- package/dist/chunks/mcp.mjs +1 -1
- package/dist/chunks/menu.mjs +22 -1
- package/dist/chunks/notification.mjs +5 -2
- package/dist/chunks/package.mjs +1 -1
- package/dist/chunks/quick-provider.mjs +1 -269
- package/dist/chunks/quick-setup.mjs +10 -10
- package/dist/chunks/remote.mjs +4 -1
- package/dist/chunks/simple-config.mjs +1 -1
- package/dist/chunks/skill.mjs +117 -9003
- package/dist/chunks/skill2.mjs +9003 -0
- package/dist/chunks/skills-sync.mjs +536 -55
- package/dist/chunks/skills.mjs +7 -1156
- package/dist/chunks/smart-defaults.mjs +87 -9
- package/dist/chunks/status.mjs +1 -1
- package/dist/chunks/uninstall.mjs +1 -1
- package/dist/chunks/update.mjs +2 -2
- package/dist/chunks/zero-config.mjs +6 -2
- package/dist/cli.mjs +3 -1
- package/dist/i18n/locales/en/cloud.json +40 -0
- package/dist/i18n/locales/zh-CN/cloud.json +40 -0
- package/dist/index.d.mts +2586 -2
- package/dist/index.d.ts +2586 -2
- package/dist/index.mjs +1340 -7
- package/dist/shared/ccjk.B364Fu0N.mjs +1819 -0
- package/dist/shared/ccjk.BtB1e5jm.mjs +171 -0
- package/dist/shared/{ccjk.BnpWvs9V.mjs → ccjk.BwfbSKN2.mjs} +1 -1
- package/dist/shared/{ccjk.AqnXPAzw.mjs → ccjk.C2jHOZVP.mjs} +1 -1
- package/dist/shared/{ccjk.BSYWk9ML.mjs → ccjk.Cjj8SVrn.mjs} +1 -1
- package/dist/shared/ccjk.D6ycHbak.mjs +270 -0
- package/dist/shared/ccjk.D8ZLYSZZ.mjs +299 -0
- package/dist/shared/{ccjk.s7OCVzdd.mjs → ccjk.DS7UESmF.mjs} +2 -1483
- package/dist/shared/{ccjk.BiCrMV5O.mjs → ccjk.DXRAZcix.mjs} +0 -28
- package/dist/shared/ccjk.UIvifqNE.mjs +1486 -0
- package/dist/shared/{ccjk.BDKUdmLk.mjs → ccjk.c-ETfBZ_.mjs} +208 -86
- package/package.json +5 -1
- package/templates/claude-code/common/settings.json +3 -1
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import { a as createCloudClient } from './shared/ccjk.B364Fu0N.mjs';
|
|
2
|
+
export { C as CachedCloudClient, b as CloudCache, d as CloudClient, F as FallbackCloudClient, R as RetryableCloudClient, T as TelemetryReporter, c as createCompleteCloudClient, g as getTelemetry, i as initializeTelemetry, r as retryUtils, s as stopTelemetry, t as telemetryUtils, e as trackEvent, w as withRetry } from './shared/ccjk.B364Fu0N.mjs';
|
|
3
|
+
export { C as CloudError, a as CloudErrorCode, b as CloudErrorFactory, f as formatErrorForLogging, g as getRetryDelay, h as handleCloudError, i as isAuthError, c as isRateLimitError, d as isRetryableError, e as isRetryableErrorCode } from './shared/ccjk.D8ZLYSZZ.mjs';
|
|
4
|
+
export { T as TemplatesClient, a as createTemplatesClient, g as getTemplatesClient } from './shared/ccjk.UIvifqNE.mjs';
|
|
5
|
+
import { e as extractString } from './shared/ccjk.C2jHOZVP.mjs';
|
|
6
|
+
export { a as extractDisplayName, i as i18nHelpers, n as normalizeRecommendation, b as normalizeRecommendations } from './shared/ccjk.C2jHOZVP.mjs';
|
|
1
7
|
import { exec, execSync, spawn } from 'node:child_process';
|
|
2
8
|
import { promises, existsSync, readdirSync, readFileSync, statSync, createReadStream } from 'node:fs';
|
|
3
9
|
import * as os from 'node:os';
|
|
@@ -8,14 +14,15 @@ import a from './chunks/index2.mjs';
|
|
|
8
14
|
import { g as getRuntimeVersion } from './shared/ccjk.gDEDGD_t.mjs';
|
|
9
15
|
import { j as join$1 } from './shared/ccjk.bQ7Dh1g4.mjs';
|
|
10
16
|
export { j as config } from './chunks/config.mjs';
|
|
11
|
-
export { e as extractDisplayName, a as extractString, i as i18nHelpers, n as normalizeRecommendation, b as normalizeRecommendations } from './shared/ccjk.AqnXPAzw.mjs';
|
|
12
17
|
export { a as loggerUtils } from './shared/ccjk.DG_o24cZ.mjs';
|
|
13
18
|
export { p as platform } from './chunks/platform.mjs';
|
|
14
19
|
import { Transform } from 'node:stream';
|
|
15
20
|
import { pipeline } from 'node:stream/promises';
|
|
16
|
-
import './shared/ccjk.BAGoDD49.mjs';
|
|
17
|
-
import 'node:process';
|
|
18
21
|
import 'node:url';
|
|
22
|
+
import 'node:crypto';
|
|
23
|
+
import './chunks/index5.mjs';
|
|
24
|
+
import 'node:process';
|
|
25
|
+
import './shared/ccjk.BAGoDD49.mjs';
|
|
19
26
|
import './shared/ccjk.RyizuzOI.mjs';
|
|
20
27
|
import './chunks/index3.mjs';
|
|
21
28
|
import 'node:readline';
|
|
@@ -26,16 +33,14 @@ import './shared/ccjk.Cjgrln_h.mjs';
|
|
|
26
33
|
import 'tty';
|
|
27
34
|
import 'fs';
|
|
28
35
|
import 'child_process';
|
|
29
|
-
import 'node:crypto';
|
|
30
36
|
import 'buffer';
|
|
31
37
|
import 'string_decoder';
|
|
32
38
|
import './chunks/constants.mjs';
|
|
33
|
-
import './chunks/index5.mjs';
|
|
34
39
|
import './chunks/claude-config.mjs';
|
|
35
40
|
import './chunks/json-config.mjs';
|
|
36
41
|
import './chunks/fs-operations.mjs';
|
|
37
42
|
import 'node:fs/promises';
|
|
38
|
-
import './shared/ccjk.
|
|
43
|
+
import './shared/ccjk.DXRAZcix.mjs';
|
|
39
44
|
import './chunks/main.mjs';
|
|
40
45
|
import 'module';
|
|
41
46
|
|
|
@@ -3605,4 +3610,1332 @@ function assert(condition, message) {
|
|
|
3605
3610
|
}
|
|
3606
3611
|
}
|
|
3607
3612
|
|
|
3608
|
-
|
|
3613
|
+
async function getCloudRecommendedHooks(projectInfo, options = {}) {
|
|
3614
|
+
const { includeCommunity = true, includePremium = false, limit = 10 } = options;
|
|
3615
|
+
try {
|
|
3616
|
+
const recommendations = await fetchCloudRecommendations(projectInfo, {
|
|
3617
|
+
includeCommunity,
|
|
3618
|
+
includePremium,
|
|
3619
|
+
limit
|
|
3620
|
+
});
|
|
3621
|
+
return recommendations;
|
|
3622
|
+
} catch (error) {
|
|
3623
|
+
console.error("Failed to fetch cloud recommendations:", error);
|
|
3624
|
+
return [];
|
|
3625
|
+
}
|
|
3626
|
+
}
|
|
3627
|
+
async function fetchCloudRecommendations(projectInfo, options) {
|
|
3628
|
+
const recommendations = [];
|
|
3629
|
+
const baseRecommendations = getBaseRecommendations(projectInfo);
|
|
3630
|
+
recommendations.push(...baseRecommendations);
|
|
3631
|
+
if (projectInfo.frameworks?.length > 0) {
|
|
3632
|
+
const frameworkRecs = getFrameworkRecommendations(projectInfo);
|
|
3633
|
+
recommendations.push(...frameworkRecs);
|
|
3634
|
+
}
|
|
3635
|
+
if (projectInfo.configFiles?.length > 0) {
|
|
3636
|
+
const toolRecs = getToolRecommendations(projectInfo);
|
|
3637
|
+
recommendations.push(...toolRecs);
|
|
3638
|
+
}
|
|
3639
|
+
let filtered = recommendations;
|
|
3640
|
+
if (!options.includeCommunity) {
|
|
3641
|
+
filtered = filtered.filter((r) => r.metadata?.tags?.includes("official"));
|
|
3642
|
+
}
|
|
3643
|
+
if (!options.includePremium) {
|
|
3644
|
+
filtered = filtered.filter((r) => !r.metadata?.tags?.includes("premium"));
|
|
3645
|
+
}
|
|
3646
|
+
if (options.limit > 0) {
|
|
3647
|
+
filtered = filtered.slice(0, options.limit);
|
|
3648
|
+
}
|
|
3649
|
+
filtered.sort((a, b) => (b.priority || 0) - (a.priority || 0));
|
|
3650
|
+
return filtered;
|
|
3651
|
+
}
|
|
3652
|
+
function getBaseRecommendations(projectInfo) {
|
|
3653
|
+
const recommendations = [];
|
|
3654
|
+
const projectType = projectInfo.projectType.toLowerCase();
|
|
3655
|
+
if (projectType.includes("typescript") || projectType.includes("javascript")) {
|
|
3656
|
+
recommendations.push(
|
|
3657
|
+
{
|
|
3658
|
+
name: "cloud-pre-commit-security",
|
|
3659
|
+
description: "Advanced security scanning (Cloud)",
|
|
3660
|
+
type: "pre-commit",
|
|
3661
|
+
category: "pre-commit",
|
|
3662
|
+
projectTypes: ["typescript", "javascript"],
|
|
3663
|
+
trigger: {
|
|
3664
|
+
matcher: "git:pre-commit"
|
|
3665
|
+
},
|
|
3666
|
+
action: {
|
|
3667
|
+
command: "ccjk-cloud",
|
|
3668
|
+
args: ["scan", "security", "--staged"],
|
|
3669
|
+
timeout: 6e4
|
|
3670
|
+
},
|
|
3671
|
+
enabled: true,
|
|
3672
|
+
priority: 200,
|
|
3673
|
+
metadata: {
|
|
3674
|
+
tags: ["official", "security", "cloud"],
|
|
3675
|
+
version: "1.0.0"
|
|
3676
|
+
}
|
|
3677
|
+
},
|
|
3678
|
+
{
|
|
3679
|
+
name: "cloud-dependency-check",
|
|
3680
|
+
description: "Check for vulnerable dependencies",
|
|
3681
|
+
type: "pre-commit",
|
|
3682
|
+
category: "pre-commit",
|
|
3683
|
+
projectTypes: ["typescript", "javascript"],
|
|
3684
|
+
trigger: {
|
|
3685
|
+
matcher: "git:pre-commit",
|
|
3686
|
+
condition: "package-lock.json || yarn.lock || pnpm-lock.yaml"
|
|
3687
|
+
},
|
|
3688
|
+
action: {
|
|
3689
|
+
command: "ccjk-cloud",
|
|
3690
|
+
args: ["audit", "dependencies"],
|
|
3691
|
+
timeout: 3e4
|
|
3692
|
+
},
|
|
3693
|
+
enabled: true,
|
|
3694
|
+
priority: 190,
|
|
3695
|
+
metadata: {
|
|
3696
|
+
tags: ["official", "security", "cloud"],
|
|
3697
|
+
version: "1.0.0"
|
|
3698
|
+
}
|
|
3699
|
+
}
|
|
3700
|
+
);
|
|
3701
|
+
}
|
|
3702
|
+
if (projectType.includes("python")) {
|
|
3703
|
+
recommendations.push(
|
|
3704
|
+
{
|
|
3705
|
+
name: "cloud-python-security",
|
|
3706
|
+
description: "Python security analysis",
|
|
3707
|
+
type: "pre-commit",
|
|
3708
|
+
category: "pre-commit",
|
|
3709
|
+
projectTypes: ["python"],
|
|
3710
|
+
trigger: {
|
|
3711
|
+
matcher: "git:pre-commit"
|
|
3712
|
+
},
|
|
3713
|
+
action: {
|
|
3714
|
+
command: "ccjk-cloud",
|
|
3715
|
+
args: ["scan", "python-security"],
|
|
3716
|
+
timeout: 45e3
|
|
3717
|
+
},
|
|
3718
|
+
enabled: true,
|
|
3719
|
+
priority: 200,
|
|
3720
|
+
metadata: {
|
|
3721
|
+
tags: ["official", "security", "cloud"],
|
|
3722
|
+
version: "1.0.0"
|
|
3723
|
+
}
|
|
3724
|
+
}
|
|
3725
|
+
);
|
|
3726
|
+
}
|
|
3727
|
+
if (projectType.includes("rust")) {
|
|
3728
|
+
recommendations.push(
|
|
3729
|
+
{
|
|
3730
|
+
name: "cloud-rust-audit",
|
|
3731
|
+
description: "Audit Rust dependencies for vulnerabilities",
|
|
3732
|
+
type: "pre-commit",
|
|
3733
|
+
category: "pre-commit",
|
|
3734
|
+
projectTypes: ["rust"],
|
|
3735
|
+
trigger: {
|
|
3736
|
+
matcher: "git:pre-commit",
|
|
3737
|
+
condition: "Cargo.lock"
|
|
3738
|
+
},
|
|
3739
|
+
action: {
|
|
3740
|
+
command: "ccjk-cloud",
|
|
3741
|
+
args: ["audit", "cargo"],
|
|
3742
|
+
timeout: 3e4
|
|
3743
|
+
},
|
|
3744
|
+
enabled: true,
|
|
3745
|
+
priority: 200,
|
|
3746
|
+
metadata: {
|
|
3747
|
+
tags: ["official", "security", "cloud"],
|
|
3748
|
+
version: "1.0.0"
|
|
3749
|
+
}
|
|
3750
|
+
}
|
|
3751
|
+
);
|
|
3752
|
+
}
|
|
3753
|
+
return recommendations;
|
|
3754
|
+
}
|
|
3755
|
+
function getFrameworkRecommendations(projectInfo) {
|
|
3756
|
+
const recommendations = [];
|
|
3757
|
+
for (const framework of projectInfo.frameworks) {
|
|
3758
|
+
const frameworkName = framework.name.toLowerCase();
|
|
3759
|
+
if (frameworkName.includes("react")) {
|
|
3760
|
+
recommendations.push(
|
|
3761
|
+
{
|
|
3762
|
+
name: "cloud-react-performance",
|
|
3763
|
+
description: "Analyze React bundle performance",
|
|
3764
|
+
type: "post-build",
|
|
3765
|
+
category: "lifecycle",
|
|
3766
|
+
projectTypes: ["typescript", "javascript"],
|
|
3767
|
+
trigger: {
|
|
3768
|
+
matcher: "command:*build*"
|
|
3769
|
+
},
|
|
3770
|
+
action: {
|
|
3771
|
+
command: "ccjk-cloud",
|
|
3772
|
+
args: ["analyze", "react-bundle"],
|
|
3773
|
+
timeout: 3e4
|
|
3774
|
+
},
|
|
3775
|
+
enabled: true,
|
|
3776
|
+
priority: 150,
|
|
3777
|
+
metadata: {
|
|
3778
|
+
tags: ["official", "react", "performance", "cloud"],
|
|
3779
|
+
version: "1.0.0"
|
|
3780
|
+
}
|
|
3781
|
+
}
|
|
3782
|
+
);
|
|
3783
|
+
}
|
|
3784
|
+
if (frameworkName.includes("vue")) {
|
|
3785
|
+
recommendations.push(
|
|
3786
|
+
{
|
|
3787
|
+
name: "cloud-vue-analysis",
|
|
3788
|
+
description: "Vue specific code analysis",
|
|
3789
|
+
type: "pre-commit",
|
|
3790
|
+
category: "pre-commit",
|
|
3791
|
+
projectTypes: ["typescript", "javascript"],
|
|
3792
|
+
trigger: {
|
|
3793
|
+
matcher: "git:pre-commit"
|
|
3794
|
+
},
|
|
3795
|
+
action: {
|
|
3796
|
+
command: "ccjk-cloud",
|
|
3797
|
+
args: ["analyze", "vue"],
|
|
3798
|
+
timeout: 2e4
|
|
3799
|
+
},
|
|
3800
|
+
enabled: true,
|
|
3801
|
+
priority: 150,
|
|
3802
|
+
metadata: {
|
|
3803
|
+
tags: ["official", "vue", "cloud"],
|
|
3804
|
+
version: "1.0.0"
|
|
3805
|
+
}
|
|
3806
|
+
}
|
|
3807
|
+
);
|
|
3808
|
+
}
|
|
3809
|
+
if (frameworkName.includes("django")) {
|
|
3810
|
+
recommendations.push(
|
|
3811
|
+
{
|
|
3812
|
+
name: "cloud-django-checks",
|
|
3813
|
+
description: "Run Django system checks",
|
|
3814
|
+
type: "pre-commit",
|
|
3815
|
+
category: "pre-commit",
|
|
3816
|
+
projectTypes: ["python"],
|
|
3817
|
+
trigger: {
|
|
3818
|
+
matcher: "git:pre-commit",
|
|
3819
|
+
condition: "*.py"
|
|
3820
|
+
},
|
|
3821
|
+
action: {
|
|
3822
|
+
command: "ccjk-cloud",
|
|
3823
|
+
args: ["django", "checks"],
|
|
3824
|
+
timeout: 15e3
|
|
3825
|
+
},
|
|
3826
|
+
enabled: true,
|
|
3827
|
+
priority: 150,
|
|
3828
|
+
metadata: {
|
|
3829
|
+
tags: ["official", "django", "cloud"],
|
|
3830
|
+
version: "1.0.0"
|
|
3831
|
+
}
|
|
3832
|
+
}
|
|
3833
|
+
);
|
|
3834
|
+
}
|
|
3835
|
+
}
|
|
3836
|
+
return recommendations;
|
|
3837
|
+
}
|
|
3838
|
+
function getToolRecommendations(projectInfo) {
|
|
3839
|
+
const recommendations = [];
|
|
3840
|
+
const configFiles = projectInfo.configFiles || [];
|
|
3841
|
+
if (configFiles.some((f) => f.includes("eslint"))) {
|
|
3842
|
+
recommendations.push({
|
|
3843
|
+
name: "cloud-eslint-advanced",
|
|
3844
|
+
description: "Advanced ESLint analysis with custom rules",
|
|
3845
|
+
type: "pre-commit",
|
|
3846
|
+
category: "pre-commit",
|
|
3847
|
+
projectTypes: ["typescript", "javascript"],
|
|
3848
|
+
trigger: {
|
|
3849
|
+
matcher: "git:pre-commit"
|
|
3850
|
+
},
|
|
3851
|
+
action: {
|
|
3852
|
+
command: "ccjk-cloud",
|
|
3853
|
+
args: ["lint", "eslint", "--advanced"],
|
|
3854
|
+
timeout: 25e3
|
|
3855
|
+
},
|
|
3856
|
+
enabled: true,
|
|
3857
|
+
priority: 140,
|
|
3858
|
+
metadata: {
|
|
3859
|
+
tags: ["official", "eslint", "cloud"],
|
|
3860
|
+
version: "1.0.0"
|
|
3861
|
+
}
|
|
3862
|
+
});
|
|
3863
|
+
}
|
|
3864
|
+
if (configFiles.some((f) => f.includes("jest") || f.includes("vitest") || f.includes("mocha"))) {
|
|
3865
|
+
recommendations.push({
|
|
3866
|
+
name: "cloud-test-intelligence",
|
|
3867
|
+
description: "Smart test execution based on changes",
|
|
3868
|
+
type: "pre-commit",
|
|
3869
|
+
category: "pre-commit",
|
|
3870
|
+
projectTypes: ["typescript", "javascript"],
|
|
3871
|
+
trigger: {
|
|
3872
|
+
matcher: "git:pre-commit"
|
|
3873
|
+
},
|
|
3874
|
+
action: {
|
|
3875
|
+
command: "ccjk-cloud",
|
|
3876
|
+
args: ["test", "intelligent"],
|
|
3877
|
+
timeout: 12e4
|
|
3878
|
+
},
|
|
3879
|
+
enabled: true,
|
|
3880
|
+
priority: 160,
|
|
3881
|
+
metadata: {
|
|
3882
|
+
tags: ["official", "testing", "cloud", "intelligent"],
|
|
3883
|
+
version: "1.0.0"
|
|
3884
|
+
}
|
|
3885
|
+
});
|
|
3886
|
+
}
|
|
3887
|
+
return recommendations;
|
|
3888
|
+
}
|
|
3889
|
+
async function submitHookAnalytics(hookName, projectInfo, result) {
|
|
3890
|
+
try {
|
|
3891
|
+
console.log(`Analytics: Hook ${hookName} ${result} for ${projectInfo.projectType} project`);
|
|
3892
|
+
} catch (_error) {
|
|
3893
|
+
}
|
|
3894
|
+
}
|
|
3895
|
+
async function getCommunityHooks(limit = 10, category) {
|
|
3896
|
+
const communityHooks = [
|
|
3897
|
+
{
|
|
3898
|
+
name: "community-commit-emoji",
|
|
3899
|
+
description: "Add emoji to commit messages based on changes",
|
|
3900
|
+
type: "post-commit",
|
|
3901
|
+
category: "lifecycle",
|
|
3902
|
+
projectTypes: ["typescript", "javascript", "python"],
|
|
3903
|
+
trigger: {
|
|
3904
|
+
matcher: "git:post-commit"
|
|
3905
|
+
},
|
|
3906
|
+
action: {
|
|
3907
|
+
command: "ccjk-community",
|
|
3908
|
+
args: ["commit-emoji"],
|
|
3909
|
+
timeout: 5e3
|
|
3910
|
+
},
|
|
3911
|
+
enabled: true,
|
|
3912
|
+
priority: 100,
|
|
3913
|
+
metadata: {
|
|
3914
|
+
tags: ["community", "git", "fun"],
|
|
3915
|
+
author: "ccjk-user-123",
|
|
3916
|
+
version: "1.0.0"
|
|
3917
|
+
}
|
|
3918
|
+
},
|
|
3919
|
+
{
|
|
3920
|
+
name: "community-code-poetry",
|
|
3921
|
+
description: "Generate poetry from your code",
|
|
3922
|
+
type: "post-commit",
|
|
3923
|
+
category: "lifecycle",
|
|
3924
|
+
projectTypes: ["typescript", "javascript", "python"],
|
|
3925
|
+
trigger: {
|
|
3926
|
+
matcher: "git:post-commit"
|
|
3927
|
+
},
|
|
3928
|
+
action: {
|
|
3929
|
+
command: "ccjk-community",
|
|
3930
|
+
args: ["code-poetry"],
|
|
3931
|
+
timeout: 1e4
|
|
3932
|
+
},
|
|
3933
|
+
enabled: false,
|
|
3934
|
+
priority: 50,
|
|
3935
|
+
metadata: {
|
|
3936
|
+
tags: ["community", "fun", "ai"],
|
|
3937
|
+
author: "poet-coder",
|
|
3938
|
+
version: "1.0.0"
|
|
3939
|
+
}
|
|
3940
|
+
}
|
|
3941
|
+
];
|
|
3942
|
+
let filtered = communityHooks;
|
|
3943
|
+
if (category) {
|
|
3944
|
+
filtered = filtered.filter((h) => h.category === category);
|
|
3945
|
+
}
|
|
3946
|
+
return filtered.slice(0, limit);
|
|
3947
|
+
}
|
|
3948
|
+
|
|
3949
|
+
async function getCloudRecommendations(analysis) {
|
|
3950
|
+
try {
|
|
3951
|
+
const client = createCloudClient();
|
|
3952
|
+
const response = await client.analyzeProject({
|
|
3953
|
+
projectRoot: analysis.rootPath || process.cwd(),
|
|
3954
|
+
dependencies: analysis.dependencies?.direct.reduce((acc, d) => {
|
|
3955
|
+
acc[d.name] = d.version || "*";
|
|
3956
|
+
return acc;
|
|
3957
|
+
}, {})
|
|
3958
|
+
});
|
|
3959
|
+
return (response.recommendations || []).map((rec) => {
|
|
3960
|
+
const config = rec.config;
|
|
3961
|
+
return {
|
|
3962
|
+
name: extractString(rec.name, rec.id || "Unknown Agent"),
|
|
3963
|
+
description: extractString(rec.description, "No description available"),
|
|
3964
|
+
skills: config?.skills || [],
|
|
3965
|
+
mcpServers: config?.mcpServers || [],
|
|
3966
|
+
persona: config?.persona,
|
|
3967
|
+
capabilities: config?.capabilities || [],
|
|
3968
|
+
confidence: rec.relevanceScore || 0.8,
|
|
3969
|
+
reason: "Recommended by CCJK Cloud"
|
|
3970
|
+
};
|
|
3971
|
+
});
|
|
3972
|
+
} catch (error) {
|
|
3973
|
+
console.warn("Failed to get cloud recommendations:", error);
|
|
3974
|
+
return [];
|
|
3975
|
+
}
|
|
3976
|
+
}
|
|
3977
|
+
async function getCloudSkillRecommendations(analysis) {
|
|
3978
|
+
try {
|
|
3979
|
+
const client = createCloudClient();
|
|
3980
|
+
const _response = await client.analyzeProject({
|
|
3981
|
+
projectRoot: analysis.rootPath || process.cwd(),
|
|
3982
|
+
dependencies: analysis.dependencies?.direct.reduce((acc, d) => {
|
|
3983
|
+
acc[d.name] = d.version || "*";
|
|
3984
|
+
return acc;
|
|
3985
|
+
}, {})
|
|
3986
|
+
});
|
|
3987
|
+
return [];
|
|
3988
|
+
} catch (error) {
|
|
3989
|
+
console.warn("Failed to get cloud skill recommendations:", error);
|
|
3990
|
+
return [];
|
|
3991
|
+
}
|
|
3992
|
+
}
|
|
3993
|
+
async function getCloudMcpRecommendations(analysis) {
|
|
3994
|
+
try {
|
|
3995
|
+
const client = createCloudClient();
|
|
3996
|
+
const _response = await client.analyzeProject({
|
|
3997
|
+
projectRoot: analysis.rootPath || process.cwd(),
|
|
3998
|
+
dependencies: analysis.dependencies?.direct.reduce((acc, d) => {
|
|
3999
|
+
acc[d.name] = d.version || "*";
|
|
4000
|
+
return acc;
|
|
4001
|
+
}, {})
|
|
4002
|
+
});
|
|
4003
|
+
return [];
|
|
4004
|
+
} catch (error) {
|
|
4005
|
+
console.warn("Failed to get cloud MCP recommendations:", error);
|
|
4006
|
+
return [];
|
|
4007
|
+
}
|
|
4008
|
+
}
|
|
4009
|
+
|
|
4010
|
+
const API_BASE_URL$2 = "https://api.claudehome.cn/api/v1";
|
|
4011
|
+
var RatingsApiErrorCode = /* @__PURE__ */ ((RatingsApiErrorCode2) => {
|
|
4012
|
+
RatingsApiErrorCode2["DUPLICATE_RATING"] = "DUPLICATE_RATING";
|
|
4013
|
+
RatingsApiErrorCode2["INVALID_RATING_VALUE"] = "INVALID_RATING_VALUE";
|
|
4014
|
+
RatingsApiErrorCode2["SKILL_NOT_FOUND"] = "SKILL_NOT_FOUND";
|
|
4015
|
+
RatingsApiErrorCode2["UNAUTHORIZED"] = "UNAUTHORIZED";
|
|
4016
|
+
RatingsApiErrorCode2["NETWORK_ERROR"] = "NETWORK_ERROR";
|
|
4017
|
+
RatingsApiErrorCode2["UNKNOWN_ERROR"] = "UNKNOWN_ERROR";
|
|
4018
|
+
return RatingsApiErrorCode2;
|
|
4019
|
+
})(RatingsApiErrorCode || {});
|
|
4020
|
+
class RatingsApiError extends Error {
|
|
4021
|
+
constructor(message, code, statusCode, details) {
|
|
4022
|
+
super(message);
|
|
4023
|
+
this.code = code;
|
|
4024
|
+
this.statusCode = statusCode;
|
|
4025
|
+
this.details = details;
|
|
4026
|
+
this.name = "RatingsApiError";
|
|
4027
|
+
}
|
|
4028
|
+
}
|
|
4029
|
+
function validateRating(rating) {
|
|
4030
|
+
if (!Number.isInteger(rating) || rating < 1 || rating > 5) {
|
|
4031
|
+
throw new RatingsApiError(
|
|
4032
|
+
`Invalid rating value: ${rating}. Rating must be an integer between 1 and 5.`,
|
|
4033
|
+
"INVALID_RATING_VALUE" /* INVALID_RATING_VALUE */
|
|
4034
|
+
);
|
|
4035
|
+
}
|
|
4036
|
+
}
|
|
4037
|
+
function buildQueryString(params) {
|
|
4038
|
+
const searchParams = new URLSearchParams();
|
|
4039
|
+
for (const [key, value] of Object.entries(params)) {
|
|
4040
|
+
if (value !== void 0) {
|
|
4041
|
+
searchParams.append(key, String(value));
|
|
4042
|
+
}
|
|
4043
|
+
}
|
|
4044
|
+
const queryString = searchParams.toString();
|
|
4045
|
+
return queryString ? `?${queryString}` : "";
|
|
4046
|
+
}
|
|
4047
|
+
async function handleResponse(response, context) {
|
|
4048
|
+
if (!response.ok) {
|
|
4049
|
+
let errorData = {};
|
|
4050
|
+
try {
|
|
4051
|
+
errorData = await response.json();
|
|
4052
|
+
} catch {
|
|
4053
|
+
}
|
|
4054
|
+
const errorMessage = errorData.message || errorData.error || `${context} failed`;
|
|
4055
|
+
const errorCode = mapHttpStatusToErrorCode(response.status, errorData.code);
|
|
4056
|
+
throw new RatingsApiError(
|
|
4057
|
+
errorMessage,
|
|
4058
|
+
errorCode,
|
|
4059
|
+
response.status,
|
|
4060
|
+
errorData
|
|
4061
|
+
);
|
|
4062
|
+
}
|
|
4063
|
+
try {
|
|
4064
|
+
const data = await response.json();
|
|
4065
|
+
if (data.success === false) {
|
|
4066
|
+
throw new RatingsApiError(
|
|
4067
|
+
data.error || `${context} failed`,
|
|
4068
|
+
"UNKNOWN_ERROR" /* UNKNOWN_ERROR */,
|
|
4069
|
+
response.status
|
|
4070
|
+
);
|
|
4071
|
+
}
|
|
4072
|
+
return data.data;
|
|
4073
|
+
} catch (error) {
|
|
4074
|
+
if (error instanceof RatingsApiError) {
|
|
4075
|
+
throw error;
|
|
4076
|
+
}
|
|
4077
|
+
throw new RatingsApiError(
|
|
4078
|
+
`Failed to parse response for ${context}`,
|
|
4079
|
+
"UNKNOWN_ERROR" /* UNKNOWN_ERROR */,
|
|
4080
|
+
response.status
|
|
4081
|
+
);
|
|
4082
|
+
}
|
|
4083
|
+
}
|
|
4084
|
+
function mapHttpStatusToErrorCode(status, serverCode) {
|
|
4085
|
+
if (serverCode === "DUPLICATE_RATING") {
|
|
4086
|
+
return "DUPLICATE_RATING" /* DUPLICATE_RATING */;
|
|
4087
|
+
}
|
|
4088
|
+
switch (status) {
|
|
4089
|
+
case 401:
|
|
4090
|
+
return "UNAUTHORIZED" /* UNAUTHORIZED */;
|
|
4091
|
+
case 404:
|
|
4092
|
+
return "SKILL_NOT_FOUND" /* SKILL_NOT_FOUND */;
|
|
4093
|
+
case 409:
|
|
4094
|
+
return "DUPLICATE_RATING" /* DUPLICATE_RATING */;
|
|
4095
|
+
case 422:
|
|
4096
|
+
return "INVALID_RATING_VALUE" /* INVALID_RATING_VALUE */;
|
|
4097
|
+
default:
|
|
4098
|
+
return "UNKNOWN_ERROR" /* UNKNOWN_ERROR */;
|
|
4099
|
+
}
|
|
4100
|
+
}
|
|
4101
|
+
async function getSkillRatings(skillId, params = {}) {
|
|
4102
|
+
if (!skillId || typeof skillId !== "string") {
|
|
4103
|
+
throw new RatingsApiError(
|
|
4104
|
+
"Skill ID is required and must be a string",
|
|
4105
|
+
"INVALID_RATING_VALUE" /* INVALID_RATING_VALUE */
|
|
4106
|
+
);
|
|
4107
|
+
}
|
|
4108
|
+
const queryString = buildQueryString({
|
|
4109
|
+
page: params.page,
|
|
4110
|
+
limit: params.limit,
|
|
4111
|
+
sort: params.sort
|
|
4112
|
+
});
|
|
4113
|
+
const url = `${API_BASE_URL$2}/skills/${encodeURIComponent(skillId)}/ratings${queryString}`;
|
|
4114
|
+
try {
|
|
4115
|
+
const response = await fetch(url, {
|
|
4116
|
+
method: "GET",
|
|
4117
|
+
headers: {
|
|
4118
|
+
"Content-Type": "application/json",
|
|
4119
|
+
"Accept": "application/json"
|
|
4120
|
+
}
|
|
4121
|
+
});
|
|
4122
|
+
return await handleResponse(response, "Get skill ratings");
|
|
4123
|
+
} catch (error) {
|
|
4124
|
+
if (error instanceof RatingsApiError) {
|
|
4125
|
+
throw error;
|
|
4126
|
+
}
|
|
4127
|
+
throw new RatingsApiError(
|
|
4128
|
+
`Network error while fetching ratings: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
4129
|
+
"NETWORK_ERROR" /* NETWORK_ERROR */
|
|
4130
|
+
);
|
|
4131
|
+
}
|
|
4132
|
+
}
|
|
4133
|
+
async function createRating(skillId, data, token) {
|
|
4134
|
+
if (!skillId || typeof skillId !== "string") {
|
|
4135
|
+
throw new RatingsApiError(
|
|
4136
|
+
"Skill ID is required and must be a string",
|
|
4137
|
+
"INVALID_RATING_VALUE" /* INVALID_RATING_VALUE */
|
|
4138
|
+
);
|
|
4139
|
+
}
|
|
4140
|
+
if (!token || typeof token !== "string") {
|
|
4141
|
+
throw new RatingsApiError(
|
|
4142
|
+
"Authentication token is required",
|
|
4143
|
+
"UNAUTHORIZED" /* UNAUTHORIZED */
|
|
4144
|
+
);
|
|
4145
|
+
}
|
|
4146
|
+
if (!data.userId || typeof data.userId !== "string") {
|
|
4147
|
+
throw new RatingsApiError(
|
|
4148
|
+
"User ID is required and must be a string",
|
|
4149
|
+
"INVALID_RATING_VALUE" /* INVALID_RATING_VALUE */
|
|
4150
|
+
);
|
|
4151
|
+
}
|
|
4152
|
+
validateRating(data.rating);
|
|
4153
|
+
const url = `${API_BASE_URL$2}/skills/${encodeURIComponent(skillId)}/ratings`;
|
|
4154
|
+
const requestBody = {
|
|
4155
|
+
userId: data.userId,
|
|
4156
|
+
rating: data.rating,
|
|
4157
|
+
...data.review !== void 0 && { review: data.review }
|
|
4158
|
+
};
|
|
4159
|
+
try {
|
|
4160
|
+
const response = await fetch(url, {
|
|
4161
|
+
method: "POST",
|
|
4162
|
+
headers: {
|
|
4163
|
+
"Content-Type": "application/json",
|
|
4164
|
+
"Accept": "application/json",
|
|
4165
|
+
"Authorization": `Bearer ${token}`
|
|
4166
|
+
},
|
|
4167
|
+
body: JSON.stringify(requestBody)
|
|
4168
|
+
});
|
|
4169
|
+
return await handleResponse(response, "Create rating");
|
|
4170
|
+
} catch (error) {
|
|
4171
|
+
if (error instanceof RatingsApiError) {
|
|
4172
|
+
throw error;
|
|
4173
|
+
}
|
|
4174
|
+
throw new RatingsApiError(
|
|
4175
|
+
`Network error while creating rating: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
4176
|
+
"NETWORK_ERROR" /* NETWORK_ERROR */
|
|
4177
|
+
);
|
|
4178
|
+
}
|
|
4179
|
+
}
|
|
4180
|
+
function isDuplicateRatingError(error) {
|
|
4181
|
+
return error instanceof RatingsApiError && error.code === "DUPLICATE_RATING" /* DUPLICATE_RATING */;
|
|
4182
|
+
}
|
|
4183
|
+
function isUnauthorizedError(error) {
|
|
4184
|
+
return error instanceof RatingsApiError && error.code === "UNAUTHORIZED" /* UNAUTHORIZED */;
|
|
4185
|
+
}
|
|
4186
|
+
function isSkillNotFoundError(error) {
|
|
4187
|
+
return error instanceof RatingsApiError && error.code === "SKILL_NOT_FOUND" /* SKILL_NOT_FOUND */;
|
|
4188
|
+
}
|
|
4189
|
+
const ratingsApi = {
|
|
4190
|
+
getSkillRatings,
|
|
4191
|
+
createRating,
|
|
4192
|
+
isDuplicateRatingError,
|
|
4193
|
+
isUnauthorizedError,
|
|
4194
|
+
isSkillNotFoundError
|
|
4195
|
+
};
|
|
4196
|
+
|
|
4197
|
+
const API_BASE_URL$1 = "https://api.claudehome.cn/api/v1";
|
|
4198
|
+
const DEFAULT_CACHE_TTL = 5 * 60 * 1e3;
|
|
4199
|
+
class SkillsMarketplaceApiError extends Error {
|
|
4200
|
+
/** HTTP status code */
|
|
4201
|
+
status;
|
|
4202
|
+
/** Error code from API response */
|
|
4203
|
+
code;
|
|
4204
|
+
/** Original response data */
|
|
4205
|
+
data;
|
|
4206
|
+
constructor(message, status, code, data) {
|
|
4207
|
+
super(message);
|
|
4208
|
+
this.name = "SkillsMarketplaceApiError";
|
|
4209
|
+
this.status = status;
|
|
4210
|
+
this.code = code;
|
|
4211
|
+
this.data = data;
|
|
4212
|
+
}
|
|
4213
|
+
}
|
|
4214
|
+
class ResponseCache {
|
|
4215
|
+
cache = /* @__PURE__ */ new Map();
|
|
4216
|
+
/**
|
|
4217
|
+
* Get cached data if valid
|
|
4218
|
+
* @param key - Cache key
|
|
4219
|
+
* @returns Cached data or undefined if not found/expired
|
|
4220
|
+
*/
|
|
4221
|
+
get(key) {
|
|
4222
|
+
const entry = this.cache.get(key);
|
|
4223
|
+
if (!entry) {
|
|
4224
|
+
return void 0;
|
|
4225
|
+
}
|
|
4226
|
+
const now = Date.now();
|
|
4227
|
+
if (now - entry.timestamp > entry.ttl) {
|
|
4228
|
+
this.cache.delete(key);
|
|
4229
|
+
return void 0;
|
|
4230
|
+
}
|
|
4231
|
+
return entry.data;
|
|
4232
|
+
}
|
|
4233
|
+
/**
|
|
4234
|
+
* Set cache entry
|
|
4235
|
+
* @param key - Cache key
|
|
4236
|
+
* @param data - Data to cache
|
|
4237
|
+
* @param ttl - Time to live in milliseconds
|
|
4238
|
+
*/
|
|
4239
|
+
set(key, data, ttl) {
|
|
4240
|
+
this.cache.set(key, {
|
|
4241
|
+
data,
|
|
4242
|
+
timestamp: Date.now(),
|
|
4243
|
+
ttl
|
|
4244
|
+
});
|
|
4245
|
+
}
|
|
4246
|
+
/**
|
|
4247
|
+
* Clear all cache entries
|
|
4248
|
+
*/
|
|
4249
|
+
clear() {
|
|
4250
|
+
this.cache.clear();
|
|
4251
|
+
}
|
|
4252
|
+
/**
|
|
4253
|
+
* Delete a specific cache entry
|
|
4254
|
+
* @param key - Cache key to delete
|
|
4255
|
+
*/
|
|
4256
|
+
delete(key) {
|
|
4257
|
+
this.cache.delete(key);
|
|
4258
|
+
}
|
|
4259
|
+
/**
|
|
4260
|
+
* Get cache size
|
|
4261
|
+
* @returns Number of cached entries
|
|
4262
|
+
*/
|
|
4263
|
+
get size() {
|
|
4264
|
+
return this.cache.size;
|
|
4265
|
+
}
|
|
4266
|
+
}
|
|
4267
|
+
const responseCache = new ResponseCache();
|
|
4268
|
+
function generateCacheKey(endpoint, params) {
|
|
4269
|
+
const sortedParams = params ? Object.keys(params).sort().reduce(
|
|
4270
|
+
(acc, key) => {
|
|
4271
|
+
if (params[key] !== void 0 && params[key] !== null) {
|
|
4272
|
+
acc[key] = params[key];
|
|
4273
|
+
}
|
|
4274
|
+
return acc;
|
|
4275
|
+
},
|
|
4276
|
+
{}
|
|
4277
|
+
) : {};
|
|
4278
|
+
return `${endpoint}:${JSON.stringify(sortedParams)}`;
|
|
4279
|
+
}
|
|
4280
|
+
function buildUrl$1(endpoint, params) {
|
|
4281
|
+
const url = new URL(`${API_BASE_URL$1}${endpoint}`);
|
|
4282
|
+
if (params) {
|
|
4283
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
4284
|
+
if (value !== void 0 && value !== null) {
|
|
4285
|
+
url.searchParams.append(key, String(value));
|
|
4286
|
+
}
|
|
4287
|
+
});
|
|
4288
|
+
}
|
|
4289
|
+
return url.toString();
|
|
4290
|
+
}
|
|
4291
|
+
async function fetchApi(endpoint, params, options = {}) {
|
|
4292
|
+
const { signal, cacheTtl = DEFAULT_CACHE_TTL, forceRefresh = false } = options;
|
|
4293
|
+
if (cacheTtl > 0 && !forceRefresh) {
|
|
4294
|
+
const cacheKey = generateCacheKey(endpoint, params);
|
|
4295
|
+
const cached = responseCache.get(cacheKey);
|
|
4296
|
+
if (cached !== void 0) {
|
|
4297
|
+
return cached;
|
|
4298
|
+
}
|
|
4299
|
+
}
|
|
4300
|
+
const url = buildUrl$1(endpoint, params);
|
|
4301
|
+
try {
|
|
4302
|
+
const response = await fetch(url, {
|
|
4303
|
+
method: "GET",
|
|
4304
|
+
headers: {
|
|
4305
|
+
"Accept": "application/json",
|
|
4306
|
+
"Content-Type": "application/json"
|
|
4307
|
+
},
|
|
4308
|
+
signal
|
|
4309
|
+
});
|
|
4310
|
+
if (!response.ok) {
|
|
4311
|
+
let errorData;
|
|
4312
|
+
let errorMessage = `HTTP ${response.status}: ${response.statusText}`;
|
|
4313
|
+
let errorCode;
|
|
4314
|
+
try {
|
|
4315
|
+
errorData = await response.json();
|
|
4316
|
+
if (typeof errorData === "object" && errorData !== null) {
|
|
4317
|
+
const err = errorData;
|
|
4318
|
+
if (typeof err.message === "string") {
|
|
4319
|
+
errorMessage = err.message;
|
|
4320
|
+
}
|
|
4321
|
+
if (typeof err.code === "string") {
|
|
4322
|
+
errorCode = err.code;
|
|
4323
|
+
}
|
|
4324
|
+
}
|
|
4325
|
+
} catch {
|
|
4326
|
+
}
|
|
4327
|
+
throw new SkillsMarketplaceApiError(errorMessage, response.status, errorCode, errorData);
|
|
4328
|
+
}
|
|
4329
|
+
const data = await response.json();
|
|
4330
|
+
if (cacheTtl > 0) {
|
|
4331
|
+
const cacheKey = generateCacheKey(endpoint, params);
|
|
4332
|
+
responseCache.set(cacheKey, data, cacheTtl);
|
|
4333
|
+
}
|
|
4334
|
+
return data;
|
|
4335
|
+
} catch (error) {
|
|
4336
|
+
if (error instanceof SkillsMarketplaceApiError) {
|
|
4337
|
+
throw error;
|
|
4338
|
+
}
|
|
4339
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
4340
|
+
throw new SkillsMarketplaceApiError("Request was cancelled", 0, "ABORT_ERROR");
|
|
4341
|
+
}
|
|
4342
|
+
if (error instanceof TypeError && error.message.includes("fetch")) {
|
|
4343
|
+
throw new SkillsMarketplaceApiError(
|
|
4344
|
+
"Network error: Unable to connect to the API",
|
|
4345
|
+
0,
|
|
4346
|
+
"NETWORK_ERROR"
|
|
4347
|
+
);
|
|
4348
|
+
}
|
|
4349
|
+
throw new SkillsMarketplaceApiError(
|
|
4350
|
+
error instanceof Error ? error.message : "Unknown error occurred",
|
|
4351
|
+
0,
|
|
4352
|
+
"UNKNOWN_ERROR"
|
|
4353
|
+
);
|
|
4354
|
+
}
|
|
4355
|
+
}
|
|
4356
|
+
async function getMarketplace(params = {}, options = {}) {
|
|
4357
|
+
return fetchApi("/skills/marketplace", params, options);
|
|
4358
|
+
}
|
|
4359
|
+
async function searchSkills(params, options = {}) {
|
|
4360
|
+
if (!params.q || params.q.trim() === "") {
|
|
4361
|
+
throw new SkillsMarketplaceApiError(
|
|
4362
|
+
"Search query (q) is required",
|
|
4363
|
+
400,
|
|
4364
|
+
"INVALID_PARAMS"
|
|
4365
|
+
);
|
|
4366
|
+
}
|
|
4367
|
+
return fetchApi("/skills/search", params, options);
|
|
4368
|
+
}
|
|
4369
|
+
async function getSearchSuggestions(params, options = {}) {
|
|
4370
|
+
if (!params.q || params.q.trim() === "") {
|
|
4371
|
+
throw new SkillsMarketplaceApiError(
|
|
4372
|
+
"Search query (q) is required",
|
|
4373
|
+
400,
|
|
4374
|
+
"INVALID_PARAMS"
|
|
4375
|
+
);
|
|
4376
|
+
}
|
|
4377
|
+
const suggestionOptions = {
|
|
4378
|
+
...options,
|
|
4379
|
+
cacheTtl: options.cacheTtl ?? 60 * 1e3
|
|
4380
|
+
};
|
|
4381
|
+
return fetchApi(
|
|
4382
|
+
"/skills/search/suggestions",
|
|
4383
|
+
params,
|
|
4384
|
+
suggestionOptions
|
|
4385
|
+
);
|
|
4386
|
+
}
|
|
4387
|
+
async function getTrendingKeywords(params = {}, options = {}) {
|
|
4388
|
+
const trendingOptions = {
|
|
4389
|
+
...options,
|
|
4390
|
+
cacheTtl: options.cacheTtl ?? 10 * 60 * 1e3
|
|
4391
|
+
};
|
|
4392
|
+
return fetchApi(
|
|
4393
|
+
"/skills/search/trending",
|
|
4394
|
+
params,
|
|
4395
|
+
trendingOptions
|
|
4396
|
+
);
|
|
4397
|
+
}
|
|
4398
|
+
function clearCache() {
|
|
4399
|
+
responseCache.clear();
|
|
4400
|
+
}
|
|
4401
|
+
function getCacheSize() {
|
|
4402
|
+
return responseCache.size;
|
|
4403
|
+
}
|
|
4404
|
+
function createAbortController() {
|
|
4405
|
+
return new AbortController();
|
|
4406
|
+
}
|
|
4407
|
+
const skillsMarketplaceApi = {
|
|
4408
|
+
getMarketplace,
|
|
4409
|
+
searchSkills,
|
|
4410
|
+
getSearchSuggestions,
|
|
4411
|
+
getTrendingKeywords,
|
|
4412
|
+
clearCache,
|
|
4413
|
+
getCacheSize,
|
|
4414
|
+
createAbortController
|
|
4415
|
+
};
|
|
4416
|
+
|
|
4417
|
+
function convertConfig(config) {
|
|
4418
|
+
if (!config || typeof config !== "object")
|
|
4419
|
+
return void 0;
|
|
4420
|
+
const obj = config;
|
|
4421
|
+
if ("command" in obj || "npmPackage" in obj) {
|
|
4422
|
+
return {
|
|
4423
|
+
type: typeof obj.type === "string" ? obj.type : void 0,
|
|
4424
|
+
command: typeof obj.command === "string" ? obj.command : void 0,
|
|
4425
|
+
args: Array.isArray(obj.args) ? obj.args.filter((a) => typeof a === "string") : void 0,
|
|
4426
|
+
env: typeof obj.env === "object" && obj.env ? obj.env : void 0,
|
|
4427
|
+
npmPackage: typeof obj.npmPackage === "string" ? obj.npmPackage : void 0,
|
|
4428
|
+
installCommand: typeof obj.installCommand === "string" ? obj.installCommand : void 0
|
|
4429
|
+
};
|
|
4430
|
+
}
|
|
4431
|
+
if ("enabled" in obj || "triggers" in obj) {
|
|
4432
|
+
return {
|
|
4433
|
+
enabled: typeof obj.enabled === "boolean" ? obj.enabled : void 0,
|
|
4434
|
+
priority: typeof obj.priority === "number" ? obj.priority : void 0,
|
|
4435
|
+
triggers: Array.isArray(obj.triggers) ? obj.triggers.filter((t) => typeof t === "string") : void 0,
|
|
4436
|
+
parameters: typeof obj.parameters === "object" && obj.parameters ? obj.parameters : void 0
|
|
4437
|
+
};
|
|
4438
|
+
}
|
|
4439
|
+
if ("persona" in obj || "capabilities" in obj) {
|
|
4440
|
+
return {
|
|
4441
|
+
persona: typeof obj.persona === "string" ? obj.persona : void 0,
|
|
4442
|
+
capabilities: Array.isArray(obj.capabilities) ? obj.capabilities.filter((c) => typeof c === "string") : void 0,
|
|
4443
|
+
skills: Array.isArray(obj.skills) ? obj.skills.filter((s) => typeof s === "string") : void 0,
|
|
4444
|
+
mcpServers: Array.isArray(obj.mcpServers) ? obj.mcpServers.filter((m) => typeof m === "string") : void 0,
|
|
4445
|
+
temperature: typeof obj.temperature === "number" ? obj.temperature : void 0,
|
|
4446
|
+
maxTokens: typeof obj.maxTokens === "number" ? obj.maxTokens : void 0
|
|
4447
|
+
};
|
|
4448
|
+
}
|
|
4449
|
+
if ("when" in obj) {
|
|
4450
|
+
return {
|
|
4451
|
+
command: typeof obj.command === "string" ? obj.command : void 0,
|
|
4452
|
+
args: Array.isArray(obj.args) ? obj.args.filter((a) => typeof a === "string") : void 0,
|
|
4453
|
+
when: typeof obj.when === "string" ? obj.when : void 0,
|
|
4454
|
+
enabled: typeof obj.enabled === "boolean" ? obj.enabled : void 0
|
|
4455
|
+
};
|
|
4456
|
+
}
|
|
4457
|
+
if ("steps" in obj) {
|
|
4458
|
+
return {
|
|
4459
|
+
steps: Array.isArray(obj.steps) ? obj.steps.filter((s) => typeof s === "string") : void 0,
|
|
4460
|
+
triggers: Array.isArray(obj.triggers) ? obj.triggers.filter((t) => typeof t === "string") : void 0,
|
|
4461
|
+
conditions: typeof obj.conditions === "object" && obj.conditions ? obj.conditions : void 0
|
|
4462
|
+
};
|
|
4463
|
+
}
|
|
4464
|
+
return void 0;
|
|
4465
|
+
}
|
|
4466
|
+
function convertParameterDefault(value) {
|
|
4467
|
+
if (value === null || value === void 0)
|
|
4468
|
+
return null;
|
|
4469
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean")
|
|
4470
|
+
return value;
|
|
4471
|
+
if (Array.isArray(value)) {
|
|
4472
|
+
if (value.every((v) => typeof v === "string"))
|
|
4473
|
+
return value;
|
|
4474
|
+
if (value.every((v) => typeof v === "number"))
|
|
4475
|
+
return value;
|
|
4476
|
+
return null;
|
|
4477
|
+
}
|
|
4478
|
+
if (typeof value === "object") {
|
|
4479
|
+
const obj = value;
|
|
4480
|
+
const converted = {};
|
|
4481
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
4482
|
+
if (typeof v === "string" || typeof v === "number" || typeof v === "boolean")
|
|
4483
|
+
converted[k] = v;
|
|
4484
|
+
}
|
|
4485
|
+
return converted;
|
|
4486
|
+
}
|
|
4487
|
+
return null;
|
|
4488
|
+
}
|
|
4489
|
+
function convertRecommendation(raw, preferredLang = "en") {
|
|
4490
|
+
return {
|
|
4491
|
+
id: raw.id,
|
|
4492
|
+
name: typeof raw.name === "string" ? { en: raw.name } : raw.name,
|
|
4493
|
+
description: typeof raw.description === "string" ? { en: raw.description } : raw.description,
|
|
4494
|
+
category: raw.category,
|
|
4495
|
+
relevanceScore: raw.relevanceScore,
|
|
4496
|
+
installCommand: raw.installCommand,
|
|
4497
|
+
config: convertConfig(raw.config),
|
|
4498
|
+
tags: raw.tags,
|
|
4499
|
+
dependencies: raw.dependencies
|
|
4500
|
+
};
|
|
4501
|
+
}
|
|
4502
|
+
function convertTemplateParameter(raw) {
|
|
4503
|
+
return {
|
|
4504
|
+
name: raw.name,
|
|
4505
|
+
type: raw.type,
|
|
4506
|
+
required: raw.required,
|
|
4507
|
+
default: convertParameterDefault(raw.default),
|
|
4508
|
+
description: typeof raw.description === "string" ? { en: raw.description } : raw.description
|
|
4509
|
+
};
|
|
4510
|
+
}
|
|
4511
|
+
function convertTemplate(raw, preferredLang = "en") {
|
|
4512
|
+
return {
|
|
4513
|
+
id: raw.id,
|
|
4514
|
+
type: raw.type,
|
|
4515
|
+
name: typeof raw.name === "string" ? { en: raw.name } : raw.name,
|
|
4516
|
+
description: typeof raw.description === "string" ? { en: raw.description } : raw.description,
|
|
4517
|
+
content: raw.content,
|
|
4518
|
+
version: raw.version,
|
|
4519
|
+
author: raw.author,
|
|
4520
|
+
tags: raw.tags,
|
|
4521
|
+
parameters: raw.parameters ? raw.parameters.map(convertTemplateParameter) : void 0,
|
|
4522
|
+
createdAt: raw.createdAt,
|
|
4523
|
+
updatedAt: raw.updatedAt
|
|
4524
|
+
};
|
|
4525
|
+
}
|
|
4526
|
+
function convertProjectAnalysisResponse(raw, preferredLang = "en") {
|
|
4527
|
+
return {
|
|
4528
|
+
requestId: raw.requestId,
|
|
4529
|
+
recommendations: raw.recommendations.map((r) => convertRecommendation(r, preferredLang)),
|
|
4530
|
+
projectType: raw.projectType,
|
|
4531
|
+
frameworks: raw.frameworks
|
|
4532
|
+
};
|
|
4533
|
+
}
|
|
4534
|
+
function convertBatchTemplateResponse(raw, preferredLang = "en") {
|
|
4535
|
+
const templates = {};
|
|
4536
|
+
for (const [id, template] of Object.entries(raw.templates)) {
|
|
4537
|
+
templates[id] = convertTemplate(template, preferredLang);
|
|
4538
|
+
}
|
|
4539
|
+
return {
|
|
4540
|
+
requestId: raw.requestId,
|
|
4541
|
+
templates,
|
|
4542
|
+
notFound: raw.notFound
|
|
4543
|
+
};
|
|
4544
|
+
}
|
|
4545
|
+
function validateProjectAnalysisRequest(request) {
|
|
4546
|
+
const errors = [];
|
|
4547
|
+
if (!request.projectRoot || typeof request.projectRoot !== "string")
|
|
4548
|
+
errors.push("projectRoot is required and must be a string");
|
|
4549
|
+
if (request.dependencies && typeof request.dependencies !== "object")
|
|
4550
|
+
errors.push("dependencies must be an object");
|
|
4551
|
+
if (request.devDependencies && typeof request.devDependencies !== "object")
|
|
4552
|
+
errors.push("devDependencies must be an object");
|
|
4553
|
+
if (request.language && !["en", "zh-CN"].includes(request.language))
|
|
4554
|
+
errors.push('language must be "en" or "zh-CN"');
|
|
4555
|
+
return {
|
|
4556
|
+
valid: errors.length === 0,
|
|
4557
|
+
errors
|
|
4558
|
+
};
|
|
4559
|
+
}
|
|
4560
|
+
function validateBatchTemplateRequest(request) {
|
|
4561
|
+
const errors = [];
|
|
4562
|
+
if (!Array.isArray(request.ids))
|
|
4563
|
+
errors.push("ids must be an array");
|
|
4564
|
+
else if (request.ids.length === 0)
|
|
4565
|
+
errors.push("ids array cannot be empty");
|
|
4566
|
+
else if (!request.ids.every((id) => typeof id === "string"))
|
|
4567
|
+
errors.push("all ids must be strings");
|
|
4568
|
+
if (request.language && !["en", "zh-CN"].includes(request.language))
|
|
4569
|
+
errors.push('language must be "en" or "zh-CN"');
|
|
4570
|
+
return {
|
|
4571
|
+
valid: errors.length === 0,
|
|
4572
|
+
errors
|
|
4573
|
+
};
|
|
4574
|
+
}
|
|
4575
|
+
function validateUsageReport(report) {
|
|
4576
|
+
const errors = [];
|
|
4577
|
+
if (!report.reportId || typeof report.reportId !== "string")
|
|
4578
|
+
errors.push("reportId is required and must be a string");
|
|
4579
|
+
const validMetricTypes = [
|
|
4580
|
+
"template_download",
|
|
4581
|
+
"recommendation_shown",
|
|
4582
|
+
"recommendation_accepted",
|
|
4583
|
+
"analysis_completed",
|
|
4584
|
+
"error_occurred"
|
|
4585
|
+
];
|
|
4586
|
+
if (!validMetricTypes.includes(report.metricType))
|
|
4587
|
+
errors.push(`metricType must be one of: ${validMetricTypes.join(", ")}`);
|
|
4588
|
+
if (!report.timestamp || typeof report.timestamp !== "string")
|
|
4589
|
+
errors.push("timestamp is required and must be a string");
|
|
4590
|
+
if (!report.ccjkVersion || typeof report.ccjkVersion !== "string")
|
|
4591
|
+
errors.push("ccjkVersion is required and must be a string");
|
|
4592
|
+
if (!report.nodeVersion || typeof report.nodeVersion !== "string")
|
|
4593
|
+
errors.push("nodeVersion is required and must be a string");
|
|
4594
|
+
if (!report.platform || typeof report.platform !== "string")
|
|
4595
|
+
errors.push("platform is required and must be a string");
|
|
4596
|
+
return {
|
|
4597
|
+
valid: errors.length === 0,
|
|
4598
|
+
errors
|
|
4599
|
+
};
|
|
4600
|
+
}
|
|
4601
|
+
function isRecommendationConfig(value) {
|
|
4602
|
+
return convertConfig(value) !== void 0;
|
|
4603
|
+
}
|
|
4604
|
+
function isTelemetryEventData(value) {
|
|
4605
|
+
if (!value || typeof value !== "object")
|
|
4606
|
+
return false;
|
|
4607
|
+
const obj = value;
|
|
4608
|
+
if (typeof obj.timestamp !== "number" && typeof obj.timestamp !== "string")
|
|
4609
|
+
return false;
|
|
4610
|
+
return true;
|
|
4611
|
+
}
|
|
4612
|
+
function isTemplateParameterValue(value) {
|
|
4613
|
+
if (value === null || value === void 0)
|
|
4614
|
+
return value === null;
|
|
4615
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean")
|
|
4616
|
+
return true;
|
|
4617
|
+
if (Array.isArray(value)) {
|
|
4618
|
+
if (value.length === 0)
|
|
4619
|
+
return true;
|
|
4620
|
+
const allStrings = value.every((v) => typeof v === "string");
|
|
4621
|
+
const allNumbers = value.every((v) => typeof v === "number");
|
|
4622
|
+
return allStrings || allNumbers;
|
|
4623
|
+
}
|
|
4624
|
+
if (typeof value === "object") {
|
|
4625
|
+
return Object.values(value).every(
|
|
4626
|
+
(v) => typeof v === "string" || typeof v === "number" || typeof v === "boolean"
|
|
4627
|
+
);
|
|
4628
|
+
}
|
|
4629
|
+
return false;
|
|
4630
|
+
}
|
|
4631
|
+
|
|
4632
|
+
const API_BASE_URL = "https://api.claudehome.cn/api/v1";
|
|
4633
|
+
function buildUrl(endpoint, params) {
|
|
4634
|
+
const url = new URL(`${API_BASE_URL}${endpoint}`);
|
|
4635
|
+
if (params) {
|
|
4636
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
4637
|
+
if (value !== void 0 && value !== null) {
|
|
4638
|
+
url.searchParams.append(key, String(value));
|
|
4639
|
+
}
|
|
4640
|
+
});
|
|
4641
|
+
}
|
|
4642
|
+
return url.toString();
|
|
4643
|
+
}
|
|
4644
|
+
async function authenticatedRequest(method, endpoint, options, body) {
|
|
4645
|
+
const { token, signal, timeout = 3e4 } = options;
|
|
4646
|
+
const url = buildUrl(endpoint);
|
|
4647
|
+
const controller = new AbortController();
|
|
4648
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
4649
|
+
const requestSignal = signal || controller.signal;
|
|
4650
|
+
try {
|
|
4651
|
+
const response = await fetch(url, {
|
|
4652
|
+
method,
|
|
4653
|
+
headers: {
|
|
4654
|
+
"Accept": "application/json",
|
|
4655
|
+
"Content-Type": "application/json",
|
|
4656
|
+
"Authorization": `Bearer ${token}`
|
|
4657
|
+
},
|
|
4658
|
+
body: body ? JSON.stringify(body) : void 0,
|
|
4659
|
+
signal: requestSignal
|
|
4660
|
+
});
|
|
4661
|
+
clearTimeout(timeoutId);
|
|
4662
|
+
if (!response.ok) {
|
|
4663
|
+
let errorData;
|
|
4664
|
+
let errorMessage = `HTTP ${response.status}: ${response.statusText}`;
|
|
4665
|
+
let errorCode;
|
|
4666
|
+
try {
|
|
4667
|
+
errorData = await response.json();
|
|
4668
|
+
if (typeof errorData === "object" && errorData !== null) {
|
|
4669
|
+
const err = errorData;
|
|
4670
|
+
if (typeof err.error === "string") {
|
|
4671
|
+
errorMessage = err.error;
|
|
4672
|
+
}
|
|
4673
|
+
if (typeof err.code === "string") {
|
|
4674
|
+
errorCode = err.code;
|
|
4675
|
+
}
|
|
4676
|
+
}
|
|
4677
|
+
} catch {
|
|
4678
|
+
}
|
|
4679
|
+
throw new SkillsMarketplaceApiError(errorMessage, response.status, errorCode, errorData);
|
|
4680
|
+
}
|
|
4681
|
+
const apiResponse = await response.json();
|
|
4682
|
+
if (!apiResponse.success) {
|
|
4683
|
+
throw new SkillsMarketplaceApiError(
|
|
4684
|
+
apiResponse.error || "Request failed",
|
|
4685
|
+
response.status,
|
|
4686
|
+
apiResponse.code
|
|
4687
|
+
);
|
|
4688
|
+
}
|
|
4689
|
+
if (!apiResponse.data) {
|
|
4690
|
+
throw new SkillsMarketplaceApiError(
|
|
4691
|
+
"No data in response",
|
|
4692
|
+
response.status,
|
|
4693
|
+
"NO_DATA"
|
|
4694
|
+
);
|
|
4695
|
+
}
|
|
4696
|
+
return apiResponse.data;
|
|
4697
|
+
} catch (error) {
|
|
4698
|
+
clearTimeout(timeoutId);
|
|
4699
|
+
if (error instanceof SkillsMarketplaceApiError) {
|
|
4700
|
+
throw error;
|
|
4701
|
+
}
|
|
4702
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
4703
|
+
throw new SkillsMarketplaceApiError("Request was cancelled", 0, "ABORT_ERROR");
|
|
4704
|
+
}
|
|
4705
|
+
if (error instanceof TypeError && error.message.includes("fetch")) {
|
|
4706
|
+
throw new SkillsMarketplaceApiError(
|
|
4707
|
+
"Network error: Unable to connect to the API",
|
|
4708
|
+
0,
|
|
4709
|
+
"NETWORK_ERROR"
|
|
4710
|
+
);
|
|
4711
|
+
}
|
|
4712
|
+
throw new SkillsMarketplaceApiError(
|
|
4713
|
+
error instanceof Error ? error.message : "Unknown error occurred",
|
|
4714
|
+
0,
|
|
4715
|
+
"UNKNOWN_ERROR"
|
|
4716
|
+
);
|
|
4717
|
+
}
|
|
4718
|
+
}
|
|
4719
|
+
async function getUserSkills(userId, options) {
|
|
4720
|
+
if (!userId || userId.trim() === "") {
|
|
4721
|
+
throw new SkillsMarketplaceApiError(
|
|
4722
|
+
"User ID is required",
|
|
4723
|
+
400,
|
|
4724
|
+
"INVALID_PARAMS"
|
|
4725
|
+
);
|
|
4726
|
+
}
|
|
4727
|
+
return authenticatedRequest(
|
|
4728
|
+
"GET",
|
|
4729
|
+
`/users/${userId}/skills`,
|
|
4730
|
+
options
|
|
4731
|
+
);
|
|
4732
|
+
}
|
|
4733
|
+
async function installSkill(userId, request, options) {
|
|
4734
|
+
if (!userId || userId.trim() === "") {
|
|
4735
|
+
throw new SkillsMarketplaceApiError(
|
|
4736
|
+
"User ID is required",
|
|
4737
|
+
400,
|
|
4738
|
+
"INVALID_PARAMS"
|
|
4739
|
+
);
|
|
4740
|
+
}
|
|
4741
|
+
if (!request.skillId || request.skillId.trim() === "") {
|
|
4742
|
+
throw new SkillsMarketplaceApiError(
|
|
4743
|
+
"Skill ID is required",
|
|
4744
|
+
400,
|
|
4745
|
+
"INVALID_PARAMS"
|
|
4746
|
+
);
|
|
4747
|
+
}
|
|
4748
|
+
return authenticatedRequest(
|
|
4749
|
+
"POST",
|
|
4750
|
+
`/users/${userId}/skills`,
|
|
4751
|
+
options,
|
|
4752
|
+
request
|
|
4753
|
+
);
|
|
4754
|
+
}
|
|
4755
|
+
async function uninstallSkill(userId, skillId, options) {
|
|
4756
|
+
if (!userId || userId.trim() === "") {
|
|
4757
|
+
throw new SkillsMarketplaceApiError(
|
|
4758
|
+
"User ID is required",
|
|
4759
|
+
400,
|
|
4760
|
+
"INVALID_PARAMS"
|
|
4761
|
+
);
|
|
4762
|
+
}
|
|
4763
|
+
if (!skillId || skillId.trim() === "") {
|
|
4764
|
+
throw new SkillsMarketplaceApiError(
|
|
4765
|
+
"Skill ID is required",
|
|
4766
|
+
400,
|
|
4767
|
+
"INVALID_PARAMS"
|
|
4768
|
+
);
|
|
4769
|
+
}
|
|
4770
|
+
return authenticatedRequest(
|
|
4771
|
+
"DELETE",
|
|
4772
|
+
`/users/${userId}/skills/${skillId}`,
|
|
4773
|
+
options
|
|
4774
|
+
);
|
|
4775
|
+
}
|
|
4776
|
+
async function updateSkill(userId, skillId, request, options) {
|
|
4777
|
+
if (!userId || userId.trim() === "") {
|
|
4778
|
+
throw new SkillsMarketplaceApiError(
|
|
4779
|
+
"User ID is required",
|
|
4780
|
+
400,
|
|
4781
|
+
"INVALID_PARAMS"
|
|
4782
|
+
);
|
|
4783
|
+
}
|
|
4784
|
+
if (!skillId || skillId.trim() === "") {
|
|
4785
|
+
throw new SkillsMarketplaceApiError(
|
|
4786
|
+
"Skill ID is required",
|
|
4787
|
+
400,
|
|
4788
|
+
"INVALID_PARAMS"
|
|
4789
|
+
);
|
|
4790
|
+
}
|
|
4791
|
+
if (!request.isEnabled && !request.config) {
|
|
4792
|
+
throw new SkillsMarketplaceApiError(
|
|
4793
|
+
"At least one of isEnabled or config must be provided",
|
|
4794
|
+
400,
|
|
4795
|
+
"INVALID_PARAMS"
|
|
4796
|
+
);
|
|
4797
|
+
}
|
|
4798
|
+
return authenticatedRequest(
|
|
4799
|
+
"PATCH",
|
|
4800
|
+
`/users/${userId}/skills/${skillId}`,
|
|
4801
|
+
options,
|
|
4802
|
+
request
|
|
4803
|
+
);
|
|
4804
|
+
}
|
|
4805
|
+
async function getRecommendations(userId, params = {}, options) {
|
|
4806
|
+
if (!userId || userId.trim() === "") {
|
|
4807
|
+
throw new SkillsMarketplaceApiError(
|
|
4808
|
+
"User ID is required",
|
|
4809
|
+
400,
|
|
4810
|
+
"INVALID_PARAMS"
|
|
4811
|
+
);
|
|
4812
|
+
}
|
|
4813
|
+
const endpoint = `/users/${userId}/recommendations`;
|
|
4814
|
+
const url = buildUrl(endpoint, params);
|
|
4815
|
+
const { token, signal, timeout = 3e4 } = options;
|
|
4816
|
+
const controller = new AbortController();
|
|
4817
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
4818
|
+
const requestSignal = signal || controller.signal;
|
|
4819
|
+
try {
|
|
4820
|
+
const response = await fetch(url, {
|
|
4821
|
+
method: "GET",
|
|
4822
|
+
headers: {
|
|
4823
|
+
"Accept": "application/json",
|
|
4824
|
+
"Content-Type": "application/json",
|
|
4825
|
+
"Authorization": `Bearer ${token}`
|
|
4826
|
+
},
|
|
4827
|
+
signal: requestSignal
|
|
4828
|
+
});
|
|
4829
|
+
clearTimeout(timeoutId);
|
|
4830
|
+
if (!response.ok) {
|
|
4831
|
+
let errorData;
|
|
4832
|
+
let errorMessage = `HTTP ${response.status}: ${response.statusText}`;
|
|
4833
|
+
let errorCode;
|
|
4834
|
+
try {
|
|
4835
|
+
errorData = await response.json();
|
|
4836
|
+
if (typeof errorData === "object" && errorData !== null) {
|
|
4837
|
+
const err = errorData;
|
|
4838
|
+
if (typeof err.error === "string") {
|
|
4839
|
+
errorMessage = err.error;
|
|
4840
|
+
}
|
|
4841
|
+
if (typeof err.code === "string") {
|
|
4842
|
+
errorCode = err.code;
|
|
4843
|
+
}
|
|
4844
|
+
}
|
|
4845
|
+
} catch {
|
|
4846
|
+
}
|
|
4847
|
+
throw new SkillsMarketplaceApiError(errorMessage, response.status, errorCode, errorData);
|
|
4848
|
+
}
|
|
4849
|
+
const apiResponse = await response.json();
|
|
4850
|
+
if (!apiResponse.success || !apiResponse.data) {
|
|
4851
|
+
throw new SkillsMarketplaceApiError(
|
|
4852
|
+
apiResponse.error || "Request failed",
|
|
4853
|
+
response.status,
|
|
4854
|
+
apiResponse.code
|
|
4855
|
+
);
|
|
4856
|
+
}
|
|
4857
|
+
return apiResponse.data;
|
|
4858
|
+
} catch (error) {
|
|
4859
|
+
clearTimeout(timeoutId);
|
|
4860
|
+
if (error instanceof SkillsMarketplaceApiError) {
|
|
4861
|
+
throw error;
|
|
4862
|
+
}
|
|
4863
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
4864
|
+
throw new SkillsMarketplaceApiError("Request was cancelled", 0, "ABORT_ERROR");
|
|
4865
|
+
}
|
|
4866
|
+
if (error instanceof TypeError && error.message.includes("fetch")) {
|
|
4867
|
+
throw new SkillsMarketplaceApiError(
|
|
4868
|
+
"Network error: Unable to connect to the API",
|
|
4869
|
+
0,
|
|
4870
|
+
"NETWORK_ERROR"
|
|
4871
|
+
);
|
|
4872
|
+
}
|
|
4873
|
+
throw new SkillsMarketplaceApiError(
|
|
4874
|
+
error instanceof Error ? error.message : "Unknown error occurred",
|
|
4875
|
+
0,
|
|
4876
|
+
"UNKNOWN_ERROR"
|
|
4877
|
+
);
|
|
4878
|
+
}
|
|
4879
|
+
}
|
|
4880
|
+
async function getUserQuota(userId, options) {
|
|
4881
|
+
if (!userId || userId.trim() === "") {
|
|
4882
|
+
throw new SkillsMarketplaceApiError(
|
|
4883
|
+
"User ID is required",
|
|
4884
|
+
400,
|
|
4885
|
+
"INVALID_PARAMS"
|
|
4886
|
+
);
|
|
4887
|
+
}
|
|
4888
|
+
return authenticatedRequest(
|
|
4889
|
+
"GET",
|
|
4890
|
+
`/users/${userId}/quota`,
|
|
4891
|
+
options
|
|
4892
|
+
);
|
|
4893
|
+
}
|
|
4894
|
+
function canInstallMore(quota) {
|
|
4895
|
+
return quota.remaining > 0;
|
|
4896
|
+
}
|
|
4897
|
+
function getQuotaUsagePercentage(quota) {
|
|
4898
|
+
if (quota.limit === 0) {
|
|
4899
|
+
return 0;
|
|
4900
|
+
}
|
|
4901
|
+
return Math.round(quota.used / quota.limit * 100);
|
|
4902
|
+
}
|
|
4903
|
+
function isSkillInstalled(skills, skillId) {
|
|
4904
|
+
return skills.some((skill) => skill.skillId === skillId);
|
|
4905
|
+
}
|
|
4906
|
+
function getEnabledSkills(skills) {
|
|
4907
|
+
return skills.filter((skill) => skill.isEnabled);
|
|
4908
|
+
}
|
|
4909
|
+
function getDisabledSkills(skills) {
|
|
4910
|
+
return skills.filter((skill) => !skill.isEnabled);
|
|
4911
|
+
}
|
|
4912
|
+
function sortByUsage(skills, order = "desc") {
|
|
4913
|
+
return [...skills].sort((a, b) => {
|
|
4914
|
+
return order === "desc" ? b.usageCount - a.usageCount : a.usageCount - b.usageCount;
|
|
4915
|
+
});
|
|
4916
|
+
}
|
|
4917
|
+
function sortByLastUsed(skills, order = "desc") {
|
|
4918
|
+
return [...skills].sort((a, b) => {
|
|
4919
|
+
const aTime = a.lastUsedAt ? new Date(a.lastUsedAt).getTime() : 0;
|
|
4920
|
+
const bTime = b.lastUsedAt ? new Date(b.lastUsedAt).getTime() : 0;
|
|
4921
|
+
return order === "desc" ? bTime - aTime : aTime - bTime;
|
|
4922
|
+
});
|
|
4923
|
+
}
|
|
4924
|
+
const userSkillsApi = {
|
|
4925
|
+
getUserSkills,
|
|
4926
|
+
installSkill,
|
|
4927
|
+
uninstallSkill,
|
|
4928
|
+
updateSkill,
|
|
4929
|
+
getRecommendations,
|
|
4930
|
+
getUserQuota,
|
|
4931
|
+
// Utility functions
|
|
4932
|
+
canInstallMore,
|
|
4933
|
+
getQuotaUsagePercentage,
|
|
4934
|
+
isSkillInstalled,
|
|
4935
|
+
getEnabledSkills,
|
|
4936
|
+
getDisabledSkills,
|
|
4937
|
+
sortByUsage,
|
|
4938
|
+
sortByLastUsed
|
|
4939
|
+
};
|
|
4940
|
+
|
|
4941
|
+
export { AiderTool, BaseCodeTool, BaseError, ClaudeCodeTool, ClineTool, CodexTool, ConfigManager, ConfigValidator, ConfigurationError, ContinueTool, CursorTool, InternalError, Logger, Mutex, NotFoundError, RatingsApiError, RatingsApiErrorCode, Semaphore, TimeoutError, ToolFactory, ToolRegistry, UnauthorizedError, ValidationError, index$6 as array, assert, assertDefined, index$5 as async, batchProcessFiles, camelCase, canInstallMore, capitalize, chunk, index$4 as command, commandExists, convertBatchTemplateResponse, convertConfig, convertParameterDefault, convertProjectAnalysisResponse, convertRecommendation, convertTemplate, convertTemplateParameter, copyFile, countLines, createCloudClient, createConfigManager, createLogger, createRating, createTool, createValidator, debounce, deepClone, deepMerge, deleteDir, deleteFile, difference, ensureDir, index$3 as error, executeCommand, executeCommandStream, exists, extractString, flatten, flatten$1 as flattenArray, formatError, index$2 as fs, generateCompactWelcome, generateRecommendations, generateWelcome, get, getArchitecture, getCacheDir, getCapabilitiesByType, getCapability, getCloudMcpRecommendations, getCloudRecommendations, getCloudRecommendedHooks, getCloudSkillRecommendations, getCommandPath, getCommandVersion, getCommunityHooks, getConfigDir, getDataDir, getDisabledSkills, getEnabledSkills, getErrorMessage, getFileInfo, getFileSize, getHomeDir, getPlatform, getPlatformInfo, getQuotaUsagePercentage, getRecommendations, getRegistry, getSkillRatings, getTempDir, getUserQuota, getUserSkills, has, installSkill, intersection, isArray, isBoolean, isDefined, isDirectory, isDuplicateRatingError, isEmail, isFile, isLargeFile, isLinux, isMacOS, isNumber, isObject, isRecommendationConfig, isSkillInstalled, isSkillNotFoundError, isString, isTelemetryEventData, isTemplateParameterValue, isURL, isUnauthorizedError, isUnix, isWindows, kebabCase, listDirs, listFiles, logger, moveFile, index$1 as object, omit, parallelLimit, partition, pascalCase, pick, processLargeFile, processLineByLine, ratingsApi, readFile, readJSON, retry, scanCapabilities, sequence, set, shuffle, skillsMarketplaceApi, sleep, slugify, snakeCase, sortByLastUsed, sortByUsage, streamJSON, streamWriteJSON, index as string, submitHookAnalytics, template, throttle, timeout, truncate, tryCatch, tryCatchAsync, unflatten, uninstallSkill, union, unique, updateSkill, userSkillsApi, validateBatchTemplateRequest, validateProjectAnalysisRequest, validateUsageReport, validation, validators, waitFor, wrapError, writeFile, writeJSON };
|