@rainy-updates/cli 0.5.7 → 0.6.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 (105) hide show
  1. package/CHANGELOG.md +134 -0
  2. package/README.md +90 -31
  3. package/dist/bin/cli.js +11 -126
  4. package/dist/bin/dispatch.js +35 -32
  5. package/dist/bin/help.js +79 -2
  6. package/dist/bin/main.d.ts +1 -0
  7. package/dist/bin/main.js +126 -0
  8. package/dist/cache/cache.js +13 -11
  9. package/dist/commands/audit/parser.js +38 -2
  10. package/dist/commands/audit/runner.js +41 -61
  11. package/dist/commands/audit/targets.js +13 -13
  12. package/dist/commands/bisect/oracle.js +31 -11
  13. package/dist/commands/bisect/parser.js +3 -3
  14. package/dist/commands/bisect/runner.js +16 -8
  15. package/dist/commands/changelog/fetcher.js +11 -5
  16. package/dist/commands/dashboard/parser.js +144 -1
  17. package/dist/commands/dashboard/runner.d.ts +2 -2
  18. package/dist/commands/dashboard/runner.js +67 -37
  19. package/dist/commands/doctor/parser.js +53 -4
  20. package/dist/commands/doctor/runner.js +2 -2
  21. package/dist/commands/ga/parser.js +43 -4
  22. package/dist/commands/ga/runner.js +22 -13
  23. package/dist/commands/health/parser.js +38 -2
  24. package/dist/commands/health/runner.js +5 -1
  25. package/dist/commands/hook/parser.d.ts +2 -0
  26. package/dist/commands/hook/parser.js +40 -0
  27. package/dist/commands/hook/runner.d.ts +2 -0
  28. package/dist/commands/hook/runner.js +174 -0
  29. package/dist/commands/licenses/parser.js +39 -0
  30. package/dist/commands/licenses/runner.js +9 -5
  31. package/dist/commands/resolve/graph/builder.js +5 -1
  32. package/dist/commands/resolve/parser.js +39 -0
  33. package/dist/commands/resolve/runner.js +14 -4
  34. package/dist/commands/review/parser.js +101 -4
  35. package/dist/commands/review/runner.js +31 -5
  36. package/dist/commands/snapshot/parser.js +39 -0
  37. package/dist/commands/snapshot/runner.js +21 -18
  38. package/dist/commands/snapshot/store.d.ts +0 -12
  39. package/dist/commands/snapshot/store.js +26 -38
  40. package/dist/commands/unused/parser.js +39 -0
  41. package/dist/commands/unused/runner.js +10 -8
  42. package/dist/commands/unused/scanner.d.ts +2 -1
  43. package/dist/commands/unused/scanner.js +65 -52
  44. package/dist/config/loader.d.ts +2 -2
  45. package/dist/config/loader.js +2 -5
  46. package/dist/config/policy.js +20 -11
  47. package/dist/core/analysis/run-silenced.js +0 -1
  48. package/dist/core/artifacts.js +6 -5
  49. package/dist/core/baseline.js +3 -5
  50. package/dist/core/check.js +7 -3
  51. package/dist/core/ci.js +52 -1
  52. package/dist/core/decision-plan.d.ts +14 -0
  53. package/dist/core/decision-plan.js +107 -0
  54. package/dist/core/doctor/result.js +8 -5
  55. package/dist/core/fix-pr-batch.js +38 -28
  56. package/dist/core/fix-pr.js +27 -24
  57. package/dist/core/init-ci.js +34 -28
  58. package/dist/core/options.d.ts +4 -1
  59. package/dist/core/options.js +152 -4
  60. package/dist/core/review-model.js +3 -0
  61. package/dist/core/summary.js +6 -0
  62. package/dist/core/upgrade.js +64 -2
  63. package/dist/core/verification.d.ts +2 -0
  64. package/dist/core/verification.js +108 -0
  65. package/dist/core/warm-cache.js +7 -3
  66. package/dist/generated/version.d.ts +1 -0
  67. package/dist/generated/version.js +2 -0
  68. package/dist/git/scope.d.ts +19 -0
  69. package/dist/git/scope.js +167 -0
  70. package/dist/index.d.ts +2 -1
  71. package/dist/index.js +1 -0
  72. package/dist/output/format.js +15 -0
  73. package/dist/output/github.js +6 -0
  74. package/dist/output/sarif.js +12 -18
  75. package/dist/parsers/package-json.js +2 -4
  76. package/dist/pm/detect.d.ts +40 -1
  77. package/dist/pm/detect.js +152 -9
  78. package/dist/pm/install.d.ts +3 -1
  79. package/dist/pm/install.js +18 -17
  80. package/dist/registry/npm.js +34 -76
  81. package/dist/rup +0 -0
  82. package/dist/types/index.d.ts +134 -5
  83. package/dist/ui/tui.d.ts +4 -1
  84. package/dist/ui/tui.js +156 -67
  85. package/dist/utils/io.js +5 -6
  86. package/dist/utils/lockfile.js +24 -19
  87. package/dist/utils/runtime-paths.d.ts +4 -0
  88. package/dist/utils/runtime-paths.js +35 -0
  89. package/dist/utils/runtime.d.ts +7 -0
  90. package/dist/utils/runtime.js +32 -0
  91. package/dist/workspace/discover.d.ts +7 -1
  92. package/dist/workspace/discover.js +67 -54
  93. package/package.json +24 -19
  94. package/dist/ui/dashboard/DashboardTUI.d.ts +0 -6
  95. package/dist/ui/dashboard/DashboardTUI.js +0 -34
  96. package/dist/ui/dashboard/components/DetailPanel.d.ts +0 -4
  97. package/dist/ui/dashboard/components/DetailPanel.js +0 -30
  98. package/dist/ui/dashboard/components/Footer.d.ts +0 -4
  99. package/dist/ui/dashboard/components/Footer.js +0 -9
  100. package/dist/ui/dashboard/components/Header.d.ts +0 -4
  101. package/dist/ui/dashboard/components/Header.js +0 -12
  102. package/dist/ui/dashboard/components/Sidebar.d.ts +0 -4
  103. package/dist/ui/dashboard/components/Sidebar.js +0 -23
  104. package/dist/ui/dashboard/store.d.ts +0 -34
  105. package/dist/ui/dashboard/store.js +0 -148
@@ -1,8 +1,7 @@
1
- import { promises as fs } from "node:fs";
2
- import os from "node:os";
3
1
  import path from "node:path";
4
- import process from "node:process";
5
2
  import { asyncPool } from "../utils/async-pool.js";
3
+ import { getHomeDir } from "../utils/runtime-paths.js";
4
+ import { getRuntimeCwd, readEnv } from "../utils/runtime.js";
6
5
  const DEFAULT_TIMEOUT_MS = 8000;
7
6
  const USER_AGENT = "@rainy-updates/cli";
8
7
  const DEFAULT_REGISTRY = "https://registry.npmjs.org/";
@@ -52,7 +51,9 @@ export class NpmRegistryClient {
52
51
  catch (error) {
53
52
  lastError = String(error);
54
53
  if (attempt < retries) {
55
- const backoffMs = error instanceof RetryableRegistryError ? error.waitMs : computeBackoffMs(attempt);
54
+ const backoffMs = error instanceof RetryableRegistryError
55
+ ? error.waitMs
56
+ : computeBackoffMs(attempt);
56
57
  await sleep(backoffMs);
57
58
  }
58
59
  }
@@ -136,10 +137,7 @@ class RetryableRegistryError extends Error {
136
137
  }
137
138
  }
138
139
  async function createRequester(cwd) {
139
- const registryConfig = await loadRegistryConfig(cwd ?? process.cwd());
140
- const undiciRequester = await tryCreateUndiciRequester(registryConfig);
141
- if (undiciRequester)
142
- return undiciRequester;
140
+ const registryConfig = await loadRegistryConfig(cwd ?? getRuntimeCwd());
143
141
  return async (packageName, timeoutMs) => {
144
142
  const controller = new AbortController();
145
143
  const timeout = setTimeout(() => controller.abort(), timeoutMs);
@@ -158,7 +156,9 @@ async function createRequester(cwd) {
158
156
  headers,
159
157
  signal: controller.signal,
160
158
  });
161
- const data = (await response.json().catch(() => null));
159
+ const data = (await response
160
+ .json()
161
+ .catch(() => null));
162
162
  return {
163
163
  status: response.status,
164
164
  data,
@@ -170,74 +170,17 @@ async function createRequester(cwd) {
170
170
  }
171
171
  };
172
172
  }
173
- async function tryCreateUndiciRequester(registryConfig) {
174
- try {
175
- const dynamicImport = Function("specifier", "return import(specifier)");
176
- const undici = await dynamicImport("undici");
177
- return async (packageName, timeoutMs) => {
178
- const controller = new AbortController();
179
- const timeout = setTimeout(() => controller.abort(), timeoutMs);
180
- const registry = resolveRegistryForPackage(packageName, registryConfig);
181
- const url = buildRegistryUrl(registry, packageName);
182
- const authHeader = resolveAuthHeader(registry, registryConfig);
183
- const headers = {
184
- accept: "application/json",
185
- "user-agent": USER_AGENT,
186
- };
187
- if (authHeader) {
188
- headers.authorization = authHeader;
189
- }
190
- try {
191
- const res = await undici.request(url, {
192
- method: "GET",
193
- headers,
194
- signal: controller.signal,
195
- });
196
- const bodyText = await res.body.text();
197
- let data = null;
198
- try {
199
- data = JSON.parse(bodyText);
200
- }
201
- catch {
202
- data = null;
203
- }
204
- const retryAfter = (() => {
205
- const header = res.headers["retry-after"];
206
- if (Array.isArray(header))
207
- return header[0] ?? null;
208
- if (typeof header === "string")
209
- return header;
210
- return null;
211
- })();
212
- return {
213
- status: res.statusCode,
214
- data,
215
- retryAfterMs: parseRetryAfterHeader(retryAfter),
216
- };
217
- }
218
- finally {
219
- clearTimeout(timeout);
220
- }
221
- };
222
- }
223
- catch {
224
- return null;
225
- }
226
- }
227
173
  export async function loadRegistryConfig(cwd) {
228
- const homeNpmrc = path.join(os.homedir(), ".npmrc");
174
+ const homeNpmrc = path.join(getHomeDir(), ".npmrc");
229
175
  const projectNpmrc = path.join(cwd, ".npmrc");
230
176
  const merged = new Map();
231
177
  for (const filePath of [homeNpmrc, projectNpmrc]) {
232
- try {
233
- const content = await fs.readFile(filePath, "utf8");
234
- const parsed = parseNpmrc(content);
235
- for (const [key, value] of parsed) {
236
- merged.set(key, value);
237
- }
238
- }
239
- catch {
240
- // ignore missing/unreadable file
178
+ const content = await readOptionalTextFile(filePath);
179
+ if (!content)
180
+ continue;
181
+ const parsed = parseNpmrc(content);
182
+ for (const [key, value] of parsed) {
183
+ merged.set(key, value);
241
184
  }
242
185
  }
243
186
  const defaultRegistry = normalizeRegistryUrl(merged.get("registry") ?? DEFAULT_REGISTRY);
@@ -272,18 +215,33 @@ export async function loadRegistryConfig(cwd) {
272
215
  authByRegistry.set(registry, current);
273
216
  }
274
217
  if (merged.get("always-auth") === "true") {
275
- const current = authByRegistry.get(defaultRegistry) ?? { alwaysAuth: false };
218
+ const current = authByRegistry.get(defaultRegistry) ?? {
219
+ alwaysAuth: false,
220
+ };
276
221
  current.alwaysAuth = true;
277
222
  authByRegistry.set(defaultRegistry, current);
278
223
  }
279
224
  return { defaultRegistry, scopedRegistries, authByRegistry };
280
225
  }
226
+ async function readOptionalTextFile(filePath) {
227
+ try {
228
+ const file = Bun.file(filePath);
229
+ if (!(await file.exists()))
230
+ return null;
231
+ return await file.text();
232
+ }
233
+ catch {
234
+ return null;
235
+ }
236
+ }
281
237
  function parseNpmrc(content) {
282
238
  const values = new Map();
283
239
  const lines = content.split(/\r?\n/);
284
240
  for (const line of lines) {
285
241
  const trimmed = line.trim();
286
- if (trimmed.length === 0 || trimmed.startsWith("#") || trimmed.startsWith(";"))
242
+ if (trimmed.length === 0 ||
243
+ trimmed.startsWith("#") ||
244
+ trimmed.startsWith(";"))
287
245
  continue;
288
246
  const separator = trimmed.indexOf("=");
289
247
  if (separator <= 0)
@@ -297,7 +255,7 @@ function parseNpmrc(content) {
297
255
  return values;
298
256
  }
299
257
  function substituteEnvValue(value) {
300
- return value.replace(/\$\{([^}]+)\}/g, (_match, name) => process.env[name] ?? "");
258
+ return value.replace(/\$\{([^}]+)\}/g, (_match, name) => readEnv(name) ?? "");
301
259
  }
302
260
  function normalizeRegistryUrl(value) {
303
261
  const normalized = value.endsWith("/") ? value : `${value}/`;
package/dist/rup ADDED
Binary file
@@ -1,10 +1,19 @@
1
1
  export type DependencyKind = "dependencies" | "devDependencies" | "optionalDependencies" | "peerDependencies";
2
+ export type SupportedPackageManager = "bun" | "npm" | "pnpm" | "yarn";
3
+ export type DetectedPackageManager = SupportedPackageManager | "unknown";
4
+ export type SelectedPackageManager = "auto" | SupportedPackageManager;
2
5
  export type TargetLevel = "patch" | "minor" | "major" | "latest";
3
6
  export type GroupBy = "none" | "name" | "scope" | "kind" | "risk";
4
7
  export type CiProfile = "minimal" | "strict" | "enterprise";
5
8
  export type LockfileMode = "preserve" | "update" | "error";
6
9
  export type Verdict = "safe" | "review" | "blocked" | "actionable";
7
10
  export type RiskLevel = "critical" | "high" | "medium" | "low";
11
+ export type DashboardMode = "check" | "review" | "upgrade";
12
+ export type QueueFocus = "all" | "security" | "risk" | "major" | "blocked" | "workspace";
13
+ export type InteractiveSurface = "dashboard";
14
+ export type VerificationState = "not-run" | "passed" | "failed";
15
+ export type VerificationMode = "none" | "install" | "test" | "install,test";
16
+ export type CiGate = "check" | "doctor" | "review" | "upgrade";
8
17
  export type DoctorFindingSeverity = "error" | "warning";
9
18
  export type DoctorScoreLabel = "Strong" | "Needs Review" | "Action Needed" | "Blocked / Critical";
10
19
  export type DoctorFindingCategory = "Security" | "Compatibility" | "Policy" | "Operational Health" | "Licensing" | "Unused / Cleanup" | "Release Risk" | "Registry / Execution" | "Workspace Integrity";
@@ -51,18 +60,29 @@ export interface RunOptions {
51
60
  cooldownDays?: number;
52
61
  prLimit?: number;
53
62
  onlyChanged: boolean;
63
+ affected?: boolean;
64
+ staged?: boolean;
65
+ baseRef?: string;
66
+ headRef?: string;
67
+ sinceRef?: string;
54
68
  ciProfile: CiProfile;
55
69
  lockfileMode: LockfileMode;
56
70
  interactive: boolean;
57
71
  showImpact: boolean;
58
72
  showHomepage: boolean;
73
+ decisionPlanFile?: string;
74
+ verify: VerificationMode;
75
+ testCommand?: string;
76
+ verificationReportFile?: string;
77
+ ciGate: CiGate;
59
78
  }
60
79
  export interface CheckOptions extends RunOptions {
61
80
  }
62
81
  export interface UpgradeOptions extends RunOptions {
63
82
  install: boolean;
64
- packageManager: "auto" | "npm" | "pnpm";
83
+ packageManager: SelectedPackageManager;
65
84
  sync: boolean;
85
+ fromPlanFile?: string;
66
86
  }
67
87
  export interface BaselineOptions {
68
88
  cwd: string;
@@ -146,8 +166,51 @@ export interface ArtifactManifest {
146
166
  githubOutputFile?: string;
147
167
  sarifFile?: string;
148
168
  prReportFile?: string;
169
+ verificationReportFile?: string;
149
170
  };
150
171
  }
172
+ export interface VerificationCheck {
173
+ name: "install" | "test";
174
+ command: string;
175
+ passed: boolean;
176
+ exitCode: number;
177
+ durationMs: number;
178
+ error?: string;
179
+ }
180
+ export interface VerificationResult {
181
+ mode: VerificationMode;
182
+ passed: boolean;
183
+ checks: VerificationCheck[];
184
+ }
185
+ export interface DecisionPlanItem {
186
+ packagePath: string;
187
+ name: string;
188
+ kind: DependencyKind;
189
+ fromRange: string;
190
+ toRange: string;
191
+ toVersionResolved: string;
192
+ diffType: TargetLevel;
193
+ riskLevel?: RiskLevel;
194
+ riskScore?: number;
195
+ policyAction?: PolicyAction;
196
+ decisionState?: DecisionState;
197
+ selected: boolean;
198
+ }
199
+ export interface DecisionPlan {
200
+ contractVersion: "1";
201
+ createdAt: string;
202
+ sourceCommand: string;
203
+ mode: DashboardMode;
204
+ focus: QueueFocus;
205
+ projectPath: string;
206
+ target: TargetLevel;
207
+ interactiveSurface: InteractiveSurface;
208
+ summary: {
209
+ totalItems: number;
210
+ selectedItems: number;
211
+ };
212
+ items: DecisionPlanItem[];
213
+ }
151
214
  export interface Summary {
152
215
  contractVersion: "2";
153
216
  scannedPackages: number;
@@ -213,11 +276,17 @@ export interface Summary {
213
276
  primaryFindingCode?: string;
214
277
  primaryFindingCategory?: DoctorFindingCategory;
215
278
  nextActionReason?: string;
279
+ suggestedCommand?: string;
280
+ decisionPlan?: string;
281
+ interactiveSurface?: InteractiveSurface;
282
+ queueFocus?: QueueFocus;
283
+ verificationState?: VerificationState;
284
+ verificationFailures?: number;
216
285
  }
217
286
  export interface CheckResult {
218
287
  projectPath: string;
219
288
  packagePaths: string[];
220
- packageManager: "npm" | "pnpm" | "unknown";
289
+ packageManager: DetectedPackageManager;
221
290
  target: TargetLevel;
222
291
  timestamp: string;
223
292
  summary: Summary;
@@ -231,6 +300,7 @@ export interface UpgradeResult extends CheckResult {
231
300
  export interface PackageManifest {
232
301
  name?: string;
233
302
  version?: string;
303
+ packageManager?: string;
234
304
  dependencies?: Record<string, string>;
235
305
  devDependencies?: Record<string, string>;
236
306
  optionalDependencies?: Record<string, string>;
@@ -256,11 +326,16 @@ export type AuditSourceStatusLevel = "ok" | "partial" | "failed";
256
326
  export interface AuditOptions {
257
327
  cwd: string;
258
328
  workspace: boolean;
329
+ affected?: boolean;
330
+ staged?: boolean;
331
+ baseRef?: string;
332
+ headRef?: string;
333
+ sinceRef?: string;
259
334
  severity?: AuditSeverity;
260
335
  fix: boolean;
261
336
  dryRun: boolean;
262
337
  commit: boolean;
263
- packageManager: "auto" | "npm" | "pnpm" | "bun" | "yarn";
338
+ packageManager: SelectedPackageManager;
264
339
  reportFormat: AuditReportFormat;
265
340
  sourceMode: AuditSourceMode;
266
341
  jsonFile?: string;
@@ -332,6 +407,11 @@ export type HealthFlag = "stale" | "deprecated" | "archived" | "unmaintained";
332
407
  export interface HealthOptions {
333
408
  cwd: string;
334
409
  workspace: boolean;
410
+ affected?: boolean;
411
+ staged?: boolean;
412
+ baseRef?: string;
413
+ headRef?: string;
414
+ sinceRef?: string;
335
415
  staleDays: number;
336
416
  includeDeprecated: boolean;
337
417
  includeAlternatives: boolean;
@@ -377,6 +457,11 @@ export interface PeerConflict {
377
457
  export interface ResolveOptions {
378
458
  cwd: string;
379
459
  workspace: boolean;
460
+ affected?: boolean;
461
+ staged?: boolean;
462
+ baseRef?: string;
463
+ headRef?: string;
464
+ sinceRef?: string;
380
465
  afterUpdate: boolean;
381
466
  safe: boolean;
382
467
  jsonFile?: string;
@@ -432,6 +517,7 @@ export interface ReviewResult {
432
517
  updates: PackageUpdate[];
433
518
  errors: string[];
434
519
  warnings: string[];
520
+ decisionPlan?: DecisionPlan;
435
521
  }
436
522
  export interface ReviewOptions extends CheckOptions {
437
523
  securityOnly: boolean;
@@ -439,6 +525,7 @@ export interface ReviewOptions extends CheckOptions {
439
525
  diff?: TargetLevel;
440
526
  applySelected: boolean;
441
527
  showChangelog?: boolean;
528
+ queueFocus?: QueueFocus;
442
529
  }
443
530
  export interface DoctorOptions extends CheckOptions {
444
531
  verdictOnly: boolean;
@@ -482,11 +569,16 @@ export interface AnalysisBundle {
482
569
  }
483
570
  export interface DashboardOptions extends CheckOptions {
484
571
  view?: "dependencies" | "security" | "health";
572
+ mode: DashboardMode;
573
+ focus: QueueFocus;
574
+ applySelected: boolean;
485
575
  }
486
576
  export interface DashboardResult {
487
577
  completed: boolean;
488
578
  errors: string[];
489
579
  warnings: string[];
580
+ selectedUpdates: number;
581
+ decisionPlanFile?: string;
490
582
  }
491
583
  export type UnusedKind = "declared-not-imported" | "imported-not-declared";
492
584
  export interface UnusedDependency {
@@ -498,6 +590,11 @@ export interface UnusedDependency {
498
590
  export interface UnusedOptions {
499
591
  cwd: string;
500
592
  workspace: boolean;
593
+ affected?: boolean;
594
+ staged?: boolean;
595
+ baseRef?: string;
596
+ headRef?: string;
597
+ sinceRef?: string;
501
598
  srcDirs: string[];
502
599
  includeDevDependencies: boolean;
503
600
  fix: boolean;
@@ -546,6 +643,11 @@ export interface SbomRelationship {
546
643
  export interface LicenseOptions {
547
644
  cwd: string;
548
645
  workspace: boolean;
646
+ affected?: boolean;
647
+ staged?: boolean;
648
+ baseRef?: string;
649
+ headRef?: string;
650
+ sinceRef?: string;
549
651
  allow?: string[];
550
652
  deny?: string[];
551
653
  sbomFile?: string;
@@ -573,6 +675,11 @@ export type SnapshotAction = "save" | "list" | "restore" | "diff";
573
675
  export interface SnapshotOptions {
574
676
  cwd: string;
575
677
  workspace: boolean;
678
+ affected?: boolean;
679
+ staged?: boolean;
680
+ baseRef?: string;
681
+ headRef?: string;
682
+ sinceRef?: string;
576
683
  action: SnapshotAction;
577
684
  label?: string;
578
685
  snapshotId?: string;
@@ -595,20 +702,42 @@ export interface SnapshotResult {
595
702
  errors: string[];
596
703
  warnings: string[];
597
704
  }
705
+ export type HookAction = "install" | "uninstall" | "doctor";
706
+ export interface HookOptions {
707
+ cwd: string;
708
+ action: HookAction;
709
+ }
710
+ export interface HookResult {
711
+ action: HookAction;
712
+ hookDir?: string;
713
+ installed: string[];
714
+ removed: string[];
715
+ checked: Array<{
716
+ name: "pre-commit" | "pre-push";
717
+ status: "managed" | "missing" | "foreign";
718
+ }>;
719
+ errors: string[];
720
+ warnings: string[];
721
+ }
598
722
  export interface GaOptions {
599
723
  cwd: string;
600
724
  workspace: boolean;
725
+ affected?: boolean;
726
+ staged?: boolean;
727
+ baseRef?: string;
728
+ headRef?: string;
729
+ sinceRef?: string;
601
730
  jsonFile?: string;
602
731
  }
603
732
  export interface GaCheck {
604
- name: "package-manager" | "workspace-discovery" | "lockfile" | "cache-backend" | "dist-build" | "benchmark-gates" | "docs-contract";
733
+ name: "package-manager" | "workspace-discovery" | "lockfile" | "cache-backend" | "dist-build" | "runtime-artifacts" | "benchmark-gates" | "docs-contract";
605
734
  status: "pass" | "warn" | "fail";
606
735
  detail: string;
607
736
  }
608
737
  export interface GaResult {
609
738
  ready: boolean;
610
739
  projectPath: string;
611
- packageManager: "npm" | "pnpm" | "unknown";
740
+ packageManager: DetectedPackageManager;
612
741
  workspacePackages: number;
613
742
  cacheBackend: "sqlite" | "file";
614
743
  checks: GaCheck[];
package/dist/ui/tui.d.ts CHANGED
@@ -1,2 +1,5 @@
1
1
  import type { ReviewItem } from "../types/index.js";
2
- export declare function runTui(items: ReviewItem[]): Promise<ReviewItem[]>;
2
+ export declare function runTui(items: ReviewItem[], options?: {
3
+ title?: string;
4
+ subtitle?: string;
5
+ }): Promise<ReviewItem[]>;