@rainy-updates/cli 0.5.1-rc.3 → 0.5.2-rc.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.
Files changed (78) hide show
  1. package/CHANGELOG.md +145 -2
  2. package/README.md +92 -26
  3. package/dist/bin/cli.js +87 -7
  4. package/dist/commands/audit/fetcher.d.ts +6 -0
  5. package/dist/commands/audit/fetcher.js +79 -0
  6. package/dist/commands/audit/mapper.d.ts +16 -0
  7. package/dist/commands/audit/mapper.js +61 -0
  8. package/dist/commands/audit/parser.d.ts +3 -0
  9. package/dist/commands/audit/parser.js +87 -0
  10. package/dist/commands/audit/runner.d.ts +7 -0
  11. package/dist/commands/audit/runner.js +64 -0
  12. package/dist/commands/bisect/engine.d.ts +12 -0
  13. package/dist/commands/bisect/engine.js +89 -0
  14. package/dist/commands/bisect/oracle.d.ts +7 -0
  15. package/dist/commands/bisect/oracle.js +36 -0
  16. package/dist/commands/bisect/parser.d.ts +2 -0
  17. package/dist/commands/bisect/parser.js +73 -0
  18. package/dist/commands/bisect/runner.d.ts +6 -0
  19. package/dist/commands/bisect/runner.js +27 -0
  20. package/dist/commands/health/parser.d.ts +2 -0
  21. package/dist/commands/health/parser.js +90 -0
  22. package/dist/commands/health/runner.d.ts +7 -0
  23. package/dist/commands/health/runner.js +130 -0
  24. package/dist/commands/licenses/parser.d.ts +2 -0
  25. package/dist/commands/licenses/parser.js +116 -0
  26. package/dist/commands/licenses/runner.d.ts +9 -0
  27. package/dist/commands/licenses/runner.js +163 -0
  28. package/dist/commands/licenses/sbom.d.ts +10 -0
  29. package/dist/commands/licenses/sbom.js +70 -0
  30. package/dist/commands/resolve/graph/builder.d.ts +20 -0
  31. package/dist/commands/resolve/graph/builder.js +183 -0
  32. package/dist/commands/resolve/graph/conflict.d.ts +20 -0
  33. package/dist/commands/resolve/graph/conflict.js +52 -0
  34. package/dist/commands/resolve/graph/resolver.d.ts +17 -0
  35. package/dist/commands/resolve/graph/resolver.js +71 -0
  36. package/dist/commands/resolve/parser.d.ts +2 -0
  37. package/dist/commands/resolve/parser.js +89 -0
  38. package/dist/commands/resolve/runner.d.ts +13 -0
  39. package/dist/commands/resolve/runner.js +136 -0
  40. package/dist/commands/snapshot/parser.d.ts +2 -0
  41. package/dist/commands/snapshot/parser.js +80 -0
  42. package/dist/commands/snapshot/runner.d.ts +11 -0
  43. package/dist/commands/snapshot/runner.js +115 -0
  44. package/dist/commands/snapshot/store.d.ts +35 -0
  45. package/dist/commands/snapshot/store.js +158 -0
  46. package/dist/commands/unused/matcher.d.ts +22 -0
  47. package/dist/commands/unused/matcher.js +95 -0
  48. package/dist/commands/unused/parser.d.ts +2 -0
  49. package/dist/commands/unused/parser.js +95 -0
  50. package/dist/commands/unused/runner.d.ts +11 -0
  51. package/dist/commands/unused/runner.js +113 -0
  52. package/dist/commands/unused/scanner.d.ts +18 -0
  53. package/dist/commands/unused/scanner.js +129 -0
  54. package/dist/config/loader.d.ts +5 -1
  55. package/dist/config/policy.d.ts +4 -0
  56. package/dist/config/policy.js +2 -0
  57. package/dist/core/check.js +56 -3
  58. package/dist/core/fix-pr-batch.js +3 -2
  59. package/dist/core/fix-pr.js +19 -4
  60. package/dist/core/impact.d.ts +36 -0
  61. package/dist/core/impact.js +82 -0
  62. package/dist/core/init-ci.js +3 -3
  63. package/dist/core/options.d.ts +22 -1
  64. package/dist/core/options.js +151 -13
  65. package/dist/core/summary.d.ts +1 -0
  66. package/dist/core/summary.js +11 -1
  67. package/dist/core/upgrade.js +10 -0
  68. package/dist/core/warm-cache.js +19 -1
  69. package/dist/output/format.js +4 -0
  70. package/dist/output/github.js +3 -0
  71. package/dist/registry/npm.d.ts +9 -2
  72. package/dist/registry/npm.js +87 -17
  73. package/dist/types/index.d.ts +236 -0
  74. package/dist/utils/lockfile.d.ts +5 -0
  75. package/dist/utils/lockfile.js +44 -0
  76. package/dist/utils/semver.d.ts +18 -0
  77. package/dist/utils/semver.js +88 -3
  78. package/package.json +13 -4
@@ -2,6 +2,7 @@ export type DependencyKind = "dependencies" | "devDependencies" | "optionalDepen
2
2
  export type TargetLevel = "patch" | "minor" | "major" | "latest";
3
3
  export type GroupBy = "none" | "name" | "scope" | "kind" | "risk";
4
4
  export type CiProfile = "minimal" | "strict" | "enterprise";
5
+ export type LockfileMode = "preserve" | "update" | "error";
5
6
  export type OutputFormat = "table" | "json" | "minimal" | "github" | "metrics";
6
7
  export type FailOnLevel = "none" | "patch" | "minor" | "major" | "any";
7
8
  export type LogLevel = "error" | "warn" | "info" | "debug";
@@ -20,7 +21,10 @@ export interface RunOptions {
20
21
  githubOutputFile?: string;
21
22
  sarifFile?: string;
22
23
  concurrency: number;
24
+ registryTimeoutMs: number;
25
+ registryRetries: number;
23
26
  offline: boolean;
27
+ stream: boolean;
24
28
  policyFile?: string;
25
29
  prReportFile?: string;
26
30
  failOn?: FailOnLevel;
@@ -39,6 +43,7 @@ export interface RunOptions {
39
43
  prLimit?: number;
40
44
  onlyChanged: boolean;
41
45
  ciProfile: CiProfile;
46
+ lockfileMode: LockfileMode;
42
47
  }
43
48
  export interface CheckOptions extends RunOptions {
44
49
  }
@@ -59,6 +64,15 @@ export interface PackageDependency {
59
64
  range: string;
60
65
  kind: DependencyKind;
61
66
  }
67
+ export interface ImpactScore {
68
+ rank: "critical" | "high" | "medium" | "low";
69
+ score: number;
70
+ factors: {
71
+ diffTypeWeight: number;
72
+ hasAdvisory: boolean;
73
+ affectedWorkspaceCount: number;
74
+ };
75
+ }
62
76
  export interface PackageUpdate {
63
77
  packagePath: string;
64
78
  name: string;
@@ -68,7 +82,10 @@ export interface PackageUpdate {
68
82
  toVersionResolved: string;
69
83
  diffType: TargetLevel;
70
84
  filtered: boolean;
85
+ autofix: boolean;
71
86
  reason?: string;
87
+ impactScore?: ImpactScore;
88
+ homepage?: string;
72
89
  }
73
90
  export interface Summary {
74
91
  contractVersion: "2";
@@ -84,6 +101,7 @@ export interface Summary {
84
101
  total: number;
85
102
  offlineCacheMiss: number;
86
103
  registryFailure: number;
104
+ registryAuthFailure: number;
87
105
  other: number;
88
106
  };
89
107
  warningCounts: {
@@ -106,6 +124,8 @@ export interface Summary {
106
124
  cooldownSkipped: number;
107
125
  ciProfile: CiProfile;
108
126
  prLimitHit: boolean;
127
+ streamedEvents: number;
128
+ policyOverridesApplied: number;
109
129
  }
110
130
  export interface CheckResult {
111
131
  projectPath: string;
@@ -141,3 +161,219 @@ export interface CachedVersion {
141
161
  export interface VersionResolver {
142
162
  resolveLatestVersion(packageName: string): Promise<string | null>;
143
163
  }
164
+ export type AuditSeverity = "critical" | "high" | "medium" | "low";
165
+ export type AuditReportFormat = "table" | "json";
166
+ export interface AuditOptions {
167
+ cwd: string;
168
+ workspace: boolean;
169
+ severity?: AuditSeverity;
170
+ fix: boolean;
171
+ dryRun: boolean;
172
+ reportFormat: AuditReportFormat;
173
+ jsonFile?: string;
174
+ concurrency: number;
175
+ registryTimeoutMs: number;
176
+ }
177
+ export interface CveAdvisory {
178
+ cveId: string;
179
+ packageName: string;
180
+ severity: AuditSeverity;
181
+ vulnerableRange: string;
182
+ patchedVersion: string | null;
183
+ title: string;
184
+ url: string;
185
+ }
186
+ export interface AuditResult {
187
+ advisories: CveAdvisory[];
188
+ autoFixable: number;
189
+ errors: string[];
190
+ warnings: string[];
191
+ }
192
+ export interface BisectOptions {
193
+ cwd: string;
194
+ packageName: string;
195
+ versionRange?: string;
196
+ testCommand: string;
197
+ concurrency: number;
198
+ registryTimeoutMs: number;
199
+ cacheTtlSeconds: number;
200
+ dryRun: boolean;
201
+ }
202
+ export type BisectOutcome = "good" | "bad" | "skip";
203
+ export interface BisectResult {
204
+ packageName: string;
205
+ breakingVersion: string | null;
206
+ lastGoodVersion: string | null;
207
+ totalVersionsTested: number;
208
+ iterations: number;
209
+ }
210
+ export type HealthFlag = "stale" | "deprecated" | "archived" | "unmaintained";
211
+ export interface HealthOptions {
212
+ cwd: string;
213
+ workspace: boolean;
214
+ staleDays: number;
215
+ includeDeprecated: boolean;
216
+ includeAlternatives: boolean;
217
+ reportFormat: "table" | "json";
218
+ jsonFile?: string;
219
+ concurrency: number;
220
+ registryTimeoutMs: number;
221
+ }
222
+ export interface PackageHealthMetric {
223
+ name: string;
224
+ currentVersion: string;
225
+ lastPublished: string | null;
226
+ isDeprecated: boolean;
227
+ deprecatedMessage?: string;
228
+ isArchived: boolean;
229
+ daysSinceLastRelease: number | null;
230
+ flags: HealthFlag[];
231
+ }
232
+ export interface HealthResult {
233
+ metrics: PackageHealthMetric[];
234
+ totalFlagged: number;
235
+ errors: string[];
236
+ warnings: string[];
237
+ }
238
+ export interface PeerNode {
239
+ name: string;
240
+ resolvedVersion: string;
241
+ peerRequirements: Map<string, string>;
242
+ }
243
+ export interface PeerGraph {
244
+ nodes: Map<string, PeerNode>;
245
+ roots: string[];
246
+ }
247
+ export type PeerConflictSeverity = "error" | "warning";
248
+ export interface PeerConflict {
249
+ requester: string;
250
+ peer: string;
251
+ requiredRange: string;
252
+ resolvedVersion: string;
253
+ severity: PeerConflictSeverity;
254
+ suggestion: string;
255
+ }
256
+ export interface ResolveOptions {
257
+ cwd: string;
258
+ workspace: boolean;
259
+ afterUpdate: boolean;
260
+ safe: boolean;
261
+ jsonFile?: string;
262
+ concurrency: number;
263
+ registryTimeoutMs: number;
264
+ cacheTtlSeconds: number;
265
+ }
266
+ export interface ResolveResult {
267
+ conflicts: PeerConflict[];
268
+ errorConflicts: number;
269
+ warningConflicts: number;
270
+ errors: string[];
271
+ warnings: string[];
272
+ }
273
+ export type UnusedKind = "declared-not-imported" | "imported-not-declared";
274
+ export interface UnusedDependency {
275
+ name: string;
276
+ kind: UnusedKind;
277
+ declaredIn?: string;
278
+ importedFrom?: string;
279
+ }
280
+ export interface UnusedOptions {
281
+ cwd: string;
282
+ workspace: boolean;
283
+ srcDirs: string[];
284
+ includeDevDependencies: boolean;
285
+ fix: boolean;
286
+ dryRun: boolean;
287
+ jsonFile?: string;
288
+ concurrency: number;
289
+ }
290
+ export interface UnusedResult {
291
+ unused: UnusedDependency[];
292
+ missing: UnusedDependency[];
293
+ totalUnused: number;
294
+ totalMissing: number;
295
+ errors: string[];
296
+ warnings: string[];
297
+ }
298
+ export interface PackageLicense {
299
+ name: string;
300
+ version: string;
301
+ license: string;
302
+ spdxExpression: string | null;
303
+ homepage?: string;
304
+ repository?: string;
305
+ }
306
+ export interface SbomDocument {
307
+ spdxVersion: "SPDX-2.3";
308
+ dataLicense: "CC0-1.0";
309
+ name: string;
310
+ documentNamespace: string;
311
+ packages: SbomPackage[];
312
+ relationships: SbomRelationship[];
313
+ }
314
+ export interface SbomPackage {
315
+ SPDXID: string;
316
+ name: string;
317
+ versionInfo: string;
318
+ downloadLocation: string;
319
+ licenseConcluded: string;
320
+ licenseDeclared: string;
321
+ copyrightText: string;
322
+ }
323
+ export interface SbomRelationship {
324
+ spdxElementId: string;
325
+ relationshipType: "DESCRIBES" | "DEPENDS_ON";
326
+ relatedSpdxElement: string;
327
+ }
328
+ export interface LicenseOptions {
329
+ cwd: string;
330
+ workspace: boolean;
331
+ allow?: string[];
332
+ deny?: string[];
333
+ sbomFile?: string;
334
+ jsonFile?: string;
335
+ diffMode: boolean;
336
+ concurrency: number;
337
+ registryTimeoutMs: number;
338
+ cacheTtlSeconds: number;
339
+ }
340
+ export interface LicenseResult {
341
+ packages: PackageLicense[];
342
+ violations: PackageLicense[];
343
+ totalViolations: number;
344
+ errors: string[];
345
+ warnings: string[];
346
+ }
347
+ export interface SnapshotEntry {
348
+ id: string;
349
+ label: string;
350
+ createdAt: number;
351
+ manifests: Record<string, string>;
352
+ lockfileHashes: Record<string, string>;
353
+ }
354
+ export type SnapshotAction = "save" | "list" | "restore" | "diff";
355
+ export interface SnapshotOptions {
356
+ cwd: string;
357
+ workspace: boolean;
358
+ action: SnapshotAction;
359
+ label?: string;
360
+ snapshotId?: string;
361
+ storeFile?: string;
362
+ }
363
+ export interface SnapshotResult {
364
+ action: SnapshotAction;
365
+ snapshotId?: string;
366
+ label?: string;
367
+ entries?: Array<{
368
+ id: string;
369
+ label: string;
370
+ createdAt: string;
371
+ }>;
372
+ diff?: Array<{
373
+ name: string;
374
+ from: string;
375
+ to: string;
376
+ }>;
377
+ errors: string[];
378
+ warnings: string[];
379
+ }
@@ -0,0 +1,5 @@
1
+ import type { LockfileMode } from "../types/index.js";
2
+ export type LockfileSnapshot = Map<string, string | null>;
3
+ export declare function captureLockfileSnapshot(cwd: string): Promise<LockfileSnapshot>;
4
+ export declare function changedLockfiles(cwd: string, before: LockfileSnapshot): Promise<string[]>;
5
+ export declare function validateLockfileMode(mode: LockfileMode, install: boolean): void;
@@ -0,0 +1,44 @@
1
+ import { promises as fs } from "node:fs";
2
+ import path from "node:path";
3
+ import { createHash } from "node:crypto";
4
+ const LOCKFILE_NAMES = ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock", "bun.lock"];
5
+ export async function captureLockfileSnapshot(cwd) {
6
+ const snapshot = new Map();
7
+ for (const name of LOCKFILE_NAMES) {
8
+ const filePath = path.join(cwd, name);
9
+ try {
10
+ const content = await fs.readFile(filePath);
11
+ snapshot.set(filePath, hashBuffer(content));
12
+ }
13
+ catch {
14
+ snapshot.set(filePath, null);
15
+ }
16
+ }
17
+ return snapshot;
18
+ }
19
+ export async function changedLockfiles(cwd, before) {
20
+ const changed = [];
21
+ for (const name of LOCKFILE_NAMES) {
22
+ const filePath = path.join(cwd, name);
23
+ let current = null;
24
+ try {
25
+ const content = await fs.readFile(filePath);
26
+ current = hashBuffer(content);
27
+ }
28
+ catch {
29
+ current = null;
30
+ }
31
+ if ((before.get(filePath) ?? null) !== current) {
32
+ changed.push(filePath);
33
+ }
34
+ }
35
+ return changed.sort((a, b) => a.localeCompare(b));
36
+ }
37
+ export function validateLockfileMode(mode, install) {
38
+ if (mode === "update" && !install) {
39
+ throw new Error("--lockfile-mode update requires --install to update lockfiles deterministically.");
40
+ }
41
+ }
42
+ function hashBuffer(value) {
43
+ return createHash("sha256").update(value).digest("hex");
44
+ }
@@ -12,3 +12,21 @@ export declare function pickTargetVersion(currentRange: string, latestVersion: s
12
12
  export declare function pickTargetVersionFromAvailable(currentRange: string, availableVersions: string[], latestVersion: string, target: TargetLevel): string | null;
13
13
  export declare function applyRangeStyle(previousRange: string, version: string): string;
14
14
  export declare function clampTarget(requested: TargetLevel, maxAllowed?: TargetLevel): TargetLevel;
15
+ /**
16
+ * Checks whether a concrete version satisfies a semver range expression.
17
+ *
18
+ * Handles the common npm range operators used in peerDependencies:
19
+ * exact: "1.2.3" → version must equal
20
+ * ^: "^1.2.3" → major must match, version must be >=
21
+ * ~: "~1.2.3" → major+minor must match, version must be >=
22
+ * >=: ">=1.2.3" → version must be >=
23
+ * <=: "<=1.2.3" → version must be <=
24
+ * >: ">1.2.3" → version must be >
25
+ * <: "<1.2.3" → version must be <
26
+ * *: "*" | "" → always true
27
+ * ranges: ">=1 <3" → all space-separated clauses AND-ed together
28
+ *
29
+ * Does NOT handle || unions or hyphen ranges — those are rare in peerDependencies
30
+ * and degrade gracefully (returns true to avoid false-positive conflicts).
31
+ */
32
+ export declare function satisfies(version: string, range: string): boolean;
@@ -45,13 +45,16 @@ export function pickTargetVersion(currentRange, latestVersion, target) {
45
45
  if (!current || target === "latest")
46
46
  return latestVersion;
47
47
  if (target === "patch") {
48
- if (current.major === latest.major && current.minor === latest.minor && latest.patch > current.patch) {
48
+ if (current.major === latest.major &&
49
+ current.minor === latest.minor &&
50
+ latest.patch > current.patch) {
49
51
  return latestVersion;
50
52
  }
51
53
  return null;
52
54
  }
53
55
  if (target === "minor") {
54
- if (current.major === latest.major && compareVersions(latest, current) > 0) {
56
+ if (current.major === latest.major &&
57
+ compareVersions(latest, current) > 0) {
55
58
  return latestVersion;
56
59
  }
57
60
  return null;
@@ -83,7 +86,8 @@ export function pickTargetVersionFromAvailable(currentRange, availableVersions,
83
86
  return sameMajor.length > 0 ? sameMajor[sameMajor.length - 1].raw : null;
84
87
  }
85
88
  if (target === "patch") {
86
- const sameLine = parsed.filter((item) => item.parsed.major === current.major && item.parsed.minor === current.minor);
89
+ const sameLine = parsed.filter((item) => item.parsed.major === current.major &&
90
+ item.parsed.minor === current.minor);
87
91
  return sameLine.length > 0 ? sameLine[sameLine.length - 1].raw : null;
88
92
  }
89
93
  return latestVersion;
@@ -102,3 +106,84 @@ export function clampTarget(requested, maxAllowed) {
102
106
  return requested;
103
107
  return TARGET_ORDER[Math.min(requestedIndex, allowedIndex)];
104
108
  }
109
+ /**
110
+ * Checks whether a concrete version satisfies a semver range expression.
111
+ *
112
+ * Handles the common npm range operators used in peerDependencies:
113
+ * exact: "1.2.3" → version must equal
114
+ * ^: "^1.2.3" → major must match, version must be >=
115
+ * ~: "~1.2.3" → major+minor must match, version must be >=
116
+ * >=: ">=1.2.3" → version must be >=
117
+ * <=: "<=1.2.3" → version must be <=
118
+ * >: ">1.2.3" → version must be >
119
+ * <: "<1.2.3" → version must be <
120
+ * *: "*" | "" → always true
121
+ * ranges: ">=1 <3" → all space-separated clauses AND-ed together
122
+ *
123
+ * Does NOT handle || unions or hyphen ranges — those are rare in peerDependencies
124
+ * and degrade gracefully (returns true to avoid false-positive conflicts).
125
+ */
126
+ export function satisfies(version, range) {
127
+ const trimmedRange = range.trim();
128
+ if (!trimmedRange || trimmedRange === "*")
129
+ return true;
130
+ const parsed = parseVersion(version);
131
+ if (!parsed)
132
+ return true; // non-semver versions (e.g. "latest", "workspace:*") pass through
133
+ // Handle OR unions — split on " || " and return true if any clause matches
134
+ if (trimmedRange.includes("||")) {
135
+ return trimmedRange
136
+ .split("||")
137
+ .some((clause) => satisfies(version, clause.trim()));
138
+ }
139
+ // Handle AND ranges — split on whitespace and require all clauses to match
140
+ const clauses = trimmedRange.split(/\s+/).filter(Boolean);
141
+ if (clauses.length > 1) {
142
+ return clauses.every((clause) => satisfies(version, clause));
143
+ }
144
+ const clause = clauses[0] ?? "";
145
+ const op = parseRangeOperator(clause);
146
+ if (!op)
147
+ return true;
148
+ const cmp = compareVersions(parsed, op.version);
149
+ switch (op.operator) {
150
+ case "^": {
151
+ // same major, version >= bound
152
+ return parsed.major === op.version.major && cmp >= 0;
153
+ }
154
+ case "~": {
155
+ // same major+minor, version >= bound
156
+ return (parsed.major === op.version.major &&
157
+ parsed.minor === op.version.minor &&
158
+ cmp >= 0);
159
+ }
160
+ case ">=":
161
+ return cmp >= 0;
162
+ case "<=":
163
+ return cmp <= 0;
164
+ case ">":
165
+ return cmp > 0;
166
+ case "<":
167
+ return cmp < 0;
168
+ case "=":
169
+ return cmp === 0;
170
+ default:
171
+ return true;
172
+ }
173
+ }
174
+ function parseRangeOperator(clause) {
175
+ const ops = [">=", "<=", "^", "~", ">", "<", "="];
176
+ for (const op of ops) {
177
+ if (clause.startsWith(op)) {
178
+ const versionStr = clause.slice(op.length);
179
+ const parsed = parseVersion(versionStr);
180
+ if (parsed)
181
+ return { operator: op, version: parsed };
182
+ }
183
+ }
184
+ // Bare version string — treat as exact
185
+ const parsed = parseVersion(clause);
186
+ if (parsed)
187
+ return { operator: "=", version: parsed };
188
+ return null;
189
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@rainy-updates/cli",
3
- "version": "0.5.1-rc.3",
4
- "description": "Agentic CLI to check and upgrade npm/pnpm dependencies for CI workflows",
3
+ "version": "0.5.2-rc.1",
4
+ "description": "The fastest DevOps-first dependency CLI. Checks, audits, upgrades, bisects, and automates npm/pnpm dependencies in CI.",
5
5
  "type": "module",
6
6
  "private": false,
7
7
  "license": "MIT",
@@ -18,12 +18,21 @@
18
18
  "updates",
19
19
  "cli",
20
20
  "ci",
21
+ "devops",
21
22
  "npm",
22
23
  "pnpm",
23
- "monorepo"
24
+ "monorepo",
25
+ "audit",
26
+ "security",
27
+ "bisect",
28
+ "ncu",
29
+ "taze",
30
+ "renovate"
24
31
  ],
25
32
  "bin": {
26
- "rainy-updates": "./dist/bin/cli.js"
33
+ "rainy-updates": "./dist/bin/cli.js",
34
+ "rainy-up": "./dist/bin/cli.js",
35
+ "rup": "./dist/bin/cli.js"
27
36
  },
28
37
  "types": "./dist/index.d.ts",
29
38
  "exports": {