@cullit/core 1.18.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +16 -6
- package/dist/index.js +68 -3
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -71,7 +71,7 @@ interface PipelineResult {
|
|
|
71
71
|
duration: number;
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
declare const VERSION = "
|
|
74
|
+
declare const VERSION = "2.0.0";
|
|
75
75
|
declare const DEFAULT_CATEGORIES: string[];
|
|
76
76
|
declare const DEFAULT_MODELS: Record<string, string>;
|
|
77
77
|
declare const AI_PROVIDERS: readonly ["anthropic", "openai", "gemini", "ollama", "none"];
|
|
@@ -82,6 +82,12 @@ declare const CHANGE_CATEGORIES: readonly ["features", "fixes", "breaking", "imp
|
|
|
82
82
|
declare const AUDIENCES: readonly ["developer", "end-user", "executive"];
|
|
83
83
|
declare const TONES: readonly ["professional", "casual", "terse", "edgy", "hype", "snarky"];
|
|
84
84
|
declare const SOURCE_TYPES: readonly ["local", "jira", "linear", "gitlab", "bitbucket", "multi-repo"];
|
|
85
|
+
declare const TIERS: readonly ["free", "basic", "pro", "team", "enterprise"];
|
|
86
|
+
declare const PAID_TIERS: readonly ["basic", "pro", "team", "enterprise"];
|
|
87
|
+
declare const TEAM_TIERS: readonly ["team", "enterprise"];
|
|
88
|
+
declare const TEAM_PLANS: readonly ["team-5", "team-10", "team-25"];
|
|
89
|
+
type TeamPlan = (typeof TEAM_PLANS)[number];
|
|
90
|
+
declare const TEAM_PLAN_SEATS: Record<TeamPlan, number>;
|
|
85
91
|
|
|
86
92
|
type LogLevel = 'quiet' | 'normal' | 'verbose';
|
|
87
93
|
interface Logger {
|
|
@@ -219,7 +225,7 @@ declare function analyzeReleaseReadiness(cwd?: string): ReleaseAdvisory;
|
|
|
219
225
|
* validateLicense() performs async remote validation with caching.
|
|
220
226
|
* resolveLicense() remains sync for quick format-only checks (display).
|
|
221
227
|
*/
|
|
222
|
-
type LicenseTier = 'free' | 'pro' | 'team' | 'enterprise';
|
|
228
|
+
type LicenseTier = 'free' | 'basic' | 'pro' | 'team' | 'enterprise';
|
|
223
229
|
interface LicenseStatus {
|
|
224
230
|
tier: LicenseTier;
|
|
225
231
|
valid: boolean;
|
|
@@ -315,9 +321,13 @@ declare function fetchWithTimeout(url: string, init: RequestInit, timeoutMs?: nu
|
|
|
315
321
|
/**
|
|
316
322
|
* Rate Limiter — Sliding-window rate limiter with pluggable backends.
|
|
317
323
|
*
|
|
324
|
+
* Backends:
|
|
325
|
+
* - MemoryRateLimiter (default) — in-process, single instance only
|
|
326
|
+
* - RedisRateLimiter — shared across instances via REDIS_URL
|
|
327
|
+
*
|
|
318
328
|
* Usage:
|
|
319
329
|
* const limiter = createRateLimiter({ limit: 30, windowMs: 60_000 });
|
|
320
|
-
* const result = limiter.check('user-ip-or-key');
|
|
330
|
+
* const result = await limiter.check('user-ip-or-key');
|
|
321
331
|
* if (!result.allowed) { // reject }
|
|
322
332
|
*/
|
|
323
333
|
interface RateLimitResult {
|
|
@@ -327,9 +337,9 @@ interface RateLimitResult {
|
|
|
327
337
|
resetAt: number;
|
|
328
338
|
}
|
|
329
339
|
interface RateLimiter {
|
|
330
|
-
check(key: string): RateLimitResult
|
|
340
|
+
check(key: string): RateLimitResult | Promise<RateLimitResult>;
|
|
331
341
|
/** Remove all tracked entries */
|
|
332
|
-
reset(): void
|
|
342
|
+
reset(): void | Promise<void>;
|
|
333
343
|
}
|
|
334
344
|
interface RateLimiterOptions {
|
|
335
345
|
/** Max requests per window (default: 30) */
|
|
@@ -378,4 +388,4 @@ declare function runPipeline(from: string, to: string, config: CullConfig, optio
|
|
|
378
388
|
templateProfile?: string;
|
|
379
389
|
}): Promise<PipelineResult>;
|
|
380
390
|
|
|
381
|
-
export { AI_PROVIDERS, AUDIENCES, CHANGE_CATEGORIES, type ChangeCategory, type ChangeEntry, type Collector, type CollectorFactory, CoreErrorCode, type CoreErrorCodeValue, CullitError, DEFAULT_CATEGORIES, DEFAULT_MODELS, ENRICHMENT_TYPES, type EnrichedContext, type EnrichedTicket, type Enricher, type EnricherFactory, FilePublisher, type Generator, type GeneratorFactory, GitCollector, type GitCommit, type GitDiff, type LicenseStatus, type LicenseTier, type LogLevel, type Logger, MultiRepoCollector, OUTPUT_FORMATS, PUBLISHER_TYPES, type PipelineResult, type Publisher, type PublisherFactory, type RateLimitResult, type RateLimiter, type RateLimiterOptions, type ReleaseAdvisory, type ReleaseNotes, SOURCE_TYPES, type SemverBump, StdoutPublisher, TONES, type TeamFeature, TemplateGenerator, type UsageLimits, VERSION, analyzeReleaseReadiness, createLogger, createRateLimiter, escapeHtml, fetchWithTimeout, formatNotes, getCollector, getEnricher, getFeatureGating, getFormatter, getGenerator, getLatestTag, getPublisher, getRecentTags, getTierLimits, hasCollector, hasEnricher, hasGenerator, hasPublisher, isEnrichmentAllowed, isFeatureAllowed, isProviderAllowed, isPublisherAllowed, listCollectors, listEnrichers, listFormatters, listGenerators, listPublishers, registerCollector, registerEnricher, registerFormatter, registerGenerator, registerPublisher, reportUsage, resolveLicense, runPipeline, upgradeMessage, validateLicense };
|
|
391
|
+
export { AI_PROVIDERS, AUDIENCES, CHANGE_CATEGORIES, type ChangeCategory, type ChangeEntry, type Collector, type CollectorFactory, CoreErrorCode, type CoreErrorCodeValue, CullitError, DEFAULT_CATEGORIES, DEFAULT_MODELS, ENRICHMENT_TYPES, type EnrichedContext, type EnrichedTicket, type Enricher, type EnricherFactory, FilePublisher, type Generator, type GeneratorFactory, GitCollector, type GitCommit, type GitDiff, type LicenseStatus, type LicenseTier, type LogLevel, type Logger, MultiRepoCollector, OUTPUT_FORMATS, PAID_TIERS, PUBLISHER_TYPES, type PipelineResult, type Publisher, type PublisherFactory, type RateLimitResult, type RateLimiter, type RateLimiterOptions, type ReleaseAdvisory, type ReleaseNotes, SOURCE_TYPES, type SemverBump, StdoutPublisher, TEAM_PLANS, TEAM_PLAN_SEATS, TEAM_TIERS, TIERS, TONES, type TeamFeature, type TeamPlan, TemplateGenerator, type UsageLimits, VERSION, analyzeReleaseReadiness, createLogger, createRateLimiter, escapeHtml, fetchWithTimeout, formatNotes, getCollector, getEnricher, getFeatureGating, getFormatter, getGenerator, getLatestTag, getPublisher, getRecentTags, getTierLimits, hasCollector, hasEnricher, hasGenerator, hasPublisher, isEnrichmentAllowed, isFeatureAllowed, isProviderAllowed, isPublisherAllowed, listCollectors, listEnrichers, listFormatters, listGenerators, listPublishers, registerCollector, registerEnricher, registerFormatter, registerGenerator, registerPublisher, reportUsage, resolveLicense, runPipeline, upgradeMessage, validateLicense };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/constants.ts
|
|
2
|
-
var VERSION = "
|
|
2
|
+
var VERSION = "2.0.0";
|
|
3
3
|
var DEFAULT_CATEGORIES = ["features", "fixes", "breaking", "improvements", "chores"];
|
|
4
4
|
var DEFAULT_MODELS = {
|
|
5
5
|
anthropic: "claude-sonnet-4-20250514",
|
|
@@ -15,6 +15,15 @@ var CHANGE_CATEGORIES = ["features", "fixes", "breaking", "improvements", "chore
|
|
|
15
15
|
var AUDIENCES = ["developer", "end-user", "executive"];
|
|
16
16
|
var TONES = ["professional", "casual", "terse", "edgy", "hype", "snarky"];
|
|
17
17
|
var SOURCE_TYPES = ["local", "jira", "linear", "gitlab", "bitbucket", "multi-repo"];
|
|
18
|
+
var TIERS = ["free", "basic", "pro", "team", "enterprise"];
|
|
19
|
+
var PAID_TIERS = ["basic", "pro", "team", "enterprise"];
|
|
20
|
+
var TEAM_TIERS = ["team", "enterprise"];
|
|
21
|
+
var TEAM_PLANS = ["team-5", "team-10", "team-25"];
|
|
22
|
+
var TEAM_PLAN_SEATS = {
|
|
23
|
+
"team-5": 5,
|
|
24
|
+
"team-10": 10,
|
|
25
|
+
"team-25": 25
|
|
26
|
+
};
|
|
18
27
|
|
|
19
28
|
// src/logger.ts
|
|
20
29
|
function createLogger(level = "normal") {
|
|
@@ -796,7 +805,7 @@ async function validateLicense() {
|
|
|
796
805
|
if (res.ok) {
|
|
797
806
|
const data = await res.json();
|
|
798
807
|
const status2 = {
|
|
799
|
-
tier: data.tier === "team" || data.tier === "enterprise" ? data.tier : data.tier === "pro" ? "pro" : "free",
|
|
808
|
+
tier: data.tier === "team" || data.tier === "enterprise" ? data.tier : data.tier === "pro" ? "pro" : data.tier === "basic" ? "basic" : "free",
|
|
800
809
|
valid: data.valid !== false,
|
|
801
810
|
message: data.message
|
|
802
811
|
};
|
|
@@ -838,6 +847,7 @@ function upgradeMessage(feature) {
|
|
|
838
847
|
}
|
|
839
848
|
var TIER_LIMITS = {
|
|
840
849
|
free: { generationsPerMonth: 5, maxProjects: 3 },
|
|
850
|
+
basic: { generationsPerMonth: 50, maxProjects: 10 },
|
|
841
851
|
pro: { generationsPerMonth: 500, maxProjects: 100 },
|
|
842
852
|
team: { generationsPerMonth: 2e3, maxProjects: 250 },
|
|
843
853
|
enterprise: { generationsPerMonth: Infinity, maxProjects: Infinity }
|
|
@@ -850,7 +860,7 @@ var FEATURE_TIERS = {
|
|
|
850
860
|
approvals: /* @__PURE__ */ new Set(["team", "enterprise"]),
|
|
851
861
|
shared_history: /* @__PURE__ */ new Set(["team", "enterprise"]),
|
|
852
862
|
project_templates: /* @__PURE__ */ new Set(["team", "enterprise"]),
|
|
853
|
-
hosted_changelog: /* @__PURE__ */ new Set(["pro", "team", "enterprise"]),
|
|
863
|
+
hosted_changelog: /* @__PURE__ */ new Set(["basic", "pro", "team", "enterprise"]),
|
|
854
864
|
branded_widget: /* @__PURE__ */ new Set(["team", "enterprise"]),
|
|
855
865
|
team_publishers: /* @__PURE__ */ new Set(["team", "enterprise"]),
|
|
856
866
|
org_settings: /* @__PURE__ */ new Set(["team", "enterprise"]),
|
|
@@ -986,8 +996,58 @@ var MemoryRateLimiter = class {
|
|
|
986
996
|
}
|
|
987
997
|
};
|
|
988
998
|
function createRateLimiter(opts) {
|
|
999
|
+
const redisUrl = process.env["REDIS_URL"];
|
|
1000
|
+
if (redisUrl) {
|
|
1001
|
+
return new RedisRateLimiter(redisUrl, opts);
|
|
1002
|
+
}
|
|
989
1003
|
return new MemoryRateLimiter(opts);
|
|
990
1004
|
}
|
|
1005
|
+
var RedisRateLimiter = class {
|
|
1006
|
+
limit;
|
|
1007
|
+
windowMs;
|
|
1008
|
+
redisUrl;
|
|
1009
|
+
prefix;
|
|
1010
|
+
constructor(redisUrl, opts = {}) {
|
|
1011
|
+
this.limit = opts.limit ?? 30;
|
|
1012
|
+
this.windowMs = opts.windowMs ?? 6e4;
|
|
1013
|
+
this.redisUrl = redisUrl;
|
|
1014
|
+
this.prefix = "cullit:rl:";
|
|
1015
|
+
}
|
|
1016
|
+
async check(key) {
|
|
1017
|
+
const now = Date.now();
|
|
1018
|
+
const windowStart = now - this.windowMs;
|
|
1019
|
+
const redisKey = this.prefix + key;
|
|
1020
|
+
try {
|
|
1021
|
+
const res = await fetch(this.redisUrl, {
|
|
1022
|
+
method: "POST",
|
|
1023
|
+
headers: { "Content-Type": "application/json" },
|
|
1024
|
+
body: JSON.stringify([
|
|
1025
|
+
["ZREMRANGEBYSCORE", redisKey, "0", String(windowStart)],
|
|
1026
|
+
["ZCARD", redisKey],
|
|
1027
|
+
["ZADD", redisKey, String(now), `${now}-${Math.random().toString(36).slice(2, 8)}`],
|
|
1028
|
+
["PEXPIRE", redisKey, String(this.windowMs)]
|
|
1029
|
+
]),
|
|
1030
|
+
signal: AbortSignal.timeout(3e3)
|
|
1031
|
+
});
|
|
1032
|
+
if (!res.ok) return this.fallbackAllow(now);
|
|
1033
|
+
const results = await res.json();
|
|
1034
|
+
const count = results[1]?.result ?? 0;
|
|
1035
|
+
const remaining = Math.max(0, this.limit - count);
|
|
1036
|
+
const resetAt = Math.ceil((now + this.windowMs) / 1e3);
|
|
1037
|
+
if (count >= this.limit) {
|
|
1038
|
+
return { allowed: false, remaining: 0, resetAt };
|
|
1039
|
+
}
|
|
1040
|
+
return { allowed: true, remaining: remaining - 1, resetAt };
|
|
1041
|
+
} catch {
|
|
1042
|
+
return this.fallbackAllow(now);
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
fallbackAllow(now) {
|
|
1046
|
+
return { allowed: true, remaining: this.limit, resetAt: Math.ceil((now + this.windowMs) / 1e3) };
|
|
1047
|
+
}
|
|
1048
|
+
async reset() {
|
|
1049
|
+
}
|
|
1050
|
+
};
|
|
991
1051
|
|
|
992
1052
|
// src/index.ts
|
|
993
1053
|
registerCollector("local", (config) => new GitCollector(config.source?.repoPath));
|
|
@@ -1210,9 +1270,14 @@ export {
|
|
|
1210
1270
|
GitCollector,
|
|
1211
1271
|
MultiRepoCollector,
|
|
1212
1272
|
OUTPUT_FORMATS,
|
|
1273
|
+
PAID_TIERS,
|
|
1213
1274
|
PUBLISHER_TYPES,
|
|
1214
1275
|
SOURCE_TYPES,
|
|
1215
1276
|
StdoutPublisher,
|
|
1277
|
+
TEAM_PLANS,
|
|
1278
|
+
TEAM_PLAN_SEATS,
|
|
1279
|
+
TEAM_TIERS,
|
|
1280
|
+
TIERS,
|
|
1216
1281
|
TONES,
|
|
1217
1282
|
TemplateGenerator,
|
|
1218
1283
|
VERSION,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cullit/core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Core engine for Cullit — AI-powered release note generation.",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"access": "public"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@cullit/config": "
|
|
41
|
+
"@cullit/config": "2.0.0"
|
|
42
42
|
},
|
|
43
43
|
"scripts": {
|
|
44
44
|
"build": "tsup src/index.ts --format esm --dts --clean",
|