@rainy-updates/cli 0.5.4 → 0.5.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.
Files changed (66) hide show
  1. package/CHANGELOG.md +136 -0
  2. package/README.md +5 -0
  3. package/dist/bin/cli.js +16 -438
  4. package/dist/bin/dispatch.d.ts +16 -0
  5. package/dist/bin/dispatch.js +150 -0
  6. package/dist/bin/help.d.ts +1 -0
  7. package/dist/bin/help.js +284 -0
  8. package/dist/commands/audit/runner.js +43 -26
  9. package/dist/commands/dashboard/parser.d.ts +2 -0
  10. package/dist/commands/dashboard/parser.js +59 -0
  11. package/dist/commands/dashboard/runner.d.ts +2 -0
  12. package/dist/commands/dashboard/runner.js +47 -0
  13. package/dist/commands/doctor/parser.js +12 -0
  14. package/dist/commands/doctor/runner.js +5 -2
  15. package/dist/commands/ga/parser.d.ts +2 -0
  16. package/dist/commands/ga/parser.js +50 -0
  17. package/dist/commands/ga/runner.d.ts +2 -0
  18. package/dist/commands/ga/runner.js +129 -0
  19. package/dist/commands/resolve/runner.js +7 -3
  20. package/dist/commands/review/parser.js +6 -0
  21. package/dist/commands/review/runner.js +4 -3
  22. package/dist/core/analysis/options.d.ts +6 -0
  23. package/dist/core/analysis/options.js +69 -0
  24. package/dist/core/analysis/review-items.d.ts +4 -0
  25. package/dist/core/analysis/review-items.js +128 -0
  26. package/dist/core/analysis/run-silenced.d.ts +1 -0
  27. package/dist/core/analysis/run-silenced.js +14 -0
  28. package/dist/core/analysis-bundle.d.ts +4 -0
  29. package/dist/core/analysis-bundle.js +33 -0
  30. package/dist/core/artifacts.d.ts +3 -0
  31. package/dist/core/artifacts.js +48 -0
  32. package/dist/core/check.js +6 -1
  33. package/dist/core/doctor/findings.d.ts +2 -0
  34. package/dist/core/doctor/findings.js +166 -0
  35. package/dist/core/doctor/render.d.ts +3 -0
  36. package/dist/core/doctor/render.js +44 -0
  37. package/dist/core/doctor/result.d.ts +2 -0
  38. package/dist/core/doctor/result.js +55 -0
  39. package/dist/core/doctor/score.d.ts +5 -0
  40. package/dist/core/doctor/score.js +28 -0
  41. package/dist/core/options.d.ts +7 -1
  42. package/dist/core/options.js +14 -0
  43. package/dist/core/review-model.d.ts +3 -3
  44. package/dist/core/review-model.js +55 -245
  45. package/dist/core/review-verdict.d.ts +2 -0
  46. package/dist/core/review-verdict.js +14 -0
  47. package/dist/core/summary.js +19 -0
  48. package/dist/output/format.js +22 -0
  49. package/dist/output/github.js +12 -0
  50. package/dist/output/sarif.js +16 -0
  51. package/dist/types/index.d.ts +120 -0
  52. package/dist/ui/dashboard/DashboardTUI.d.ts +6 -0
  53. package/dist/ui/dashboard/DashboardTUI.js +34 -0
  54. package/dist/ui/dashboard/components/DetailPanel.d.ts +4 -0
  55. package/dist/ui/dashboard/components/DetailPanel.js +30 -0
  56. package/dist/ui/dashboard/components/Footer.d.ts +4 -0
  57. package/dist/ui/dashboard/components/Footer.js +9 -0
  58. package/dist/ui/dashboard/components/Header.d.ts +4 -0
  59. package/dist/ui/dashboard/components/Header.js +12 -0
  60. package/dist/ui/dashboard/components/Sidebar.d.ts +4 -0
  61. package/dist/ui/dashboard/components/Sidebar.js +23 -0
  62. package/dist/ui/dashboard/store.d.ts +34 -0
  63. package/dist/ui/dashboard/store.js +148 -0
  64. package/dist/ui/tui.d.ts +2 -2
  65. package/dist/ui/tui.js +310 -79
  66. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,142 @@
2
2
 
3
3
  All notable changes to this project are documented in this file.
4
4
 
5
+ ## [0.5.7] - 2026-03-01
6
+
7
+ Final stabilization release for the `v0.5` series, focused on modularization, doctor scan quality, and maintainability.
8
+
9
+ ### Added
10
+
11
+ - **Doctor scan upgrades inspired by high-level audit CLIs**:
12
+ - normalized doctor findings with categories and severities,
13
+ - deterministic dependency health score (`0-100`),
14
+ - score labels and next-action reasoning,
15
+ - agent-oriented doctor output via `doctor --agent-report`.
16
+ - **New modular doctor core** under `src/core/doctor/`:
17
+ - findings derivation,
18
+ - score calculation,
19
+ - result assembly,
20
+ - rendering.
21
+ - **New modular analysis helpers** under `src/core/analysis/`:
22
+ - analysis option adapters,
23
+ - review item enrichment,
24
+ - silenced runner wrapper.
25
+ - **New CLI seam modules**:
26
+ - `src/bin/dispatch.ts`
27
+ - `src/bin/help.ts`
28
+ - `src/core/review-verdict.ts`
29
+ - **New help coverage** in `tests/help.test.ts`.
30
+
31
+ ### Changed
32
+
33
+ - `doctor` now behaves as a stronger high-level scan surface:
34
+ - `State`
35
+ - `Score`
36
+ - `PrimaryRisk`
37
+ - `NextAction`
38
+ - `NextActionReason`
39
+ - Summary and machine outputs now carry additive doctor metadata:
40
+ - `dependencyHealthScore`,
41
+ - `findingCountsByCategory`,
42
+ - `findingCountsBySeverity`,
43
+ - `primaryFindingCode`,
44
+ - `primaryFindingCategory`,
45
+ - `nextActionReason`.
46
+ - GitHub output, SARIF, and human-readable metrics/table output now expose the new doctor summary fields additively.
47
+ - `src/core/review-model.ts` was reduced to review aggregation responsibilities, with doctor logic extracted into focused modules.
48
+ - `src/core/analysis-bundle.ts` was reduced to a thin coordinator, with item enrichment and option adaptation moved into dedicated modules.
49
+ - `src/bin/cli.ts` was simplified by extracting command dispatch and help rendering into standalone modules.
50
+
51
+ ### Tests
52
+
53
+ - Added coverage for doctor score/findings behavior and agent report rendering.
54
+ - Added coverage for new GitHub output and SARIF fields.
55
+ - Added help rendering coverage after extracting CLI help into its own module.
56
+
57
+ ## [0.5.6] - 2026-03-01
58
+
59
+ GA readiness, shared analysis plumbing, and richer review operations.
60
+
61
+ ### Added
62
+
63
+ - **New `ga` command** for release and CI readiness auditing:
64
+ - package manager detection,
65
+ - workspace discovery,
66
+ - lockfile presence checks,
67
+ - cache backend inspection,
68
+ - dist build verification,
69
+ - benchmark gate presence,
70
+ - README / CHANGELOG contract checks.
71
+ - **Artifact run metadata**:
72
+ - stable `runId`,
73
+ - generated artifact manifests under `.artifacts/`,
74
+ - additive JSON / SARIF / GitHub output fields for run and decision metadata.
75
+ - **Review and doctor changelog-aware flags**:
76
+ - `review --show-changelog`
77
+ - `doctor --include-changelog`
78
+ - **Interactive review console upgrades**:
79
+ - filter rail,
80
+ - grouping and sorting modes,
81
+ - inline search,
82
+ - detail tabs,
83
+ - help overlay,
84
+ - bulk selection shortcuts,
85
+ - explicit policy and decision-state rendering.
86
+
87
+ ### Changed
88
+
89
+ - `review` and `doctor` now consume a single shared analysis bundle across check, audit, resolve, health, licenses, and unused dependency signals.
90
+ - Update records now carry additive operator metadata:
91
+ - `policyAction`,
92
+ - `decisionState`,
93
+ - `releaseNotesSummary`,
94
+ - `workspaceGroup`,
95
+ - `groupKey`,
96
+ - `selectedByDefault`,
97
+ - `blockedReason`,
98
+ - `monitorReason`.
99
+ - Summary/output contracts now add:
100
+ - `runId`,
101
+ - `artifactManifest`,
102
+ - `blockedPackages`,
103
+ - `reviewPackages`,
104
+ - `monitorPackages`,
105
+ - `cacheBackend`,
106
+ - `degradedSources`,
107
+ - `gaReady`.
108
+ - `check` now records the active cache backend in summary output and attaches workspace grouping metadata to updates.
109
+ - CLI help now documents:
110
+ - `ga`,
111
+ - `--show-changelog`,
112
+ - `--include-changelog`,
113
+ - `--show-links`.
114
+
115
+ ### Tests
116
+
117
+ - Added parser coverage for `ga`, `review --show-changelog`, and `doctor --include-changelog`.
118
+ - Added output coverage for new GitHub output fields.
119
+ - Added GA readiness command coverage.
120
+
121
+ ## [0.5.5] - 2026-03-01
122
+
123
+ Interactive Dashboard TUI overhaul and domain logic integration.
124
+
125
+ ### Added
126
+
127
+ - **Fully functional Interactive Dashboard TUI** (`dashboard` command):
128
+ - Built with Ink for a high-performance (60FPS+) CLI experience.
129
+ - Quick Actions directly bound to core CLI domain logic:
130
+ - **`[R]esolve`**: Runs peer-conflict resolution in the background and updates the UI with severity levels.
131
+ - **`[A]udit`**: Runs security audits in the background and surfaces CVE advisories and risk levels inline.
132
+ - **`<Enter>`**: Applies selected updates and exits the TUI to run the native package manager install.
133
+ - Zero-dependency atomic state manager (`useSyncExternalStore`) to ensure efficient rendering and avoid React Context cascading updates.
134
+ - Seamless background task execution with non-blocking modal overlays (`resolving`, `auditing`).
135
+
136
+ ### Changed
137
+
138
+ - Added `silent: true` flag to `AuditOptions` and `ResolveOptions` to prevent standard stream pollution during background TUI operations.
139
+ - Modified `dashboard` command runner to natively hand-off installation duties to the core `upgrade` flow upon `<Enter>`.
140
+
5
141
  ## [0.5.4] - 2026-03-01
6
142
 
7
143
  Production hotfix for interactive review stability.
package/README.md CHANGED
@@ -107,6 +107,7 @@ npx @rainy-updates/cli ci --workspace --mode strict
107
107
  - `doctor` — summarize the current dependency situation
108
108
  - `review` — decide what to do with security, risk, peer, and policy context
109
109
  - `upgrade` — apply the approved change set
110
+ - `ga` — audit GA and CI readiness for the current checkout
110
111
 
111
112
  ### Supporting workflow
112
113
 
@@ -136,6 +137,7 @@ rup doctor --workspace
136
137
  # 3) Review and decide
137
138
  npx @rainy-updates/cli review --security-only
138
139
  rup review --interactive
140
+ rup review --show-changelog
139
141
 
140
142
  # 4) Apply upgrades with workspace sync
141
143
  npx @rainy-updates/cli upgrade --target latest --workspace --sync --install
@@ -181,6 +183,9 @@ rup bisect axios --cmd "bun test" # if installed
181
183
 
182
184
  # 12) Focus review on high-risk changes
183
185
  rup review --risk high --diff major
186
+
187
+ # 13) Audit GA / CI readiness
188
+ rup ga --workspace
184
189
  ```
185
190
 
186
191
  ## What it does in production
package/dist/bin/cli.js CHANGED
@@ -4,14 +4,9 @@ import path from "node:path";
4
4
  import process from "node:process";
5
5
  import { fileURLToPath } from "node:url";
6
6
  import { parseCliArgs } from "../core/options.js";
7
- import { check } from "../core/check.js";
8
- import { upgrade } from "../core/upgrade.js";
9
- import { warmCache } from "../core/warm-cache.js";
10
- import { runCi } from "../core/ci.js";
11
- import { initCiWorkflow } from "../core/init-ci.js";
12
- import { diffBaseline, saveBaseline } from "../core/baseline.js";
13
7
  import { applyFixPr } from "../core/fix-pr.js";
14
8
  import { applyFixPrBatches } from "../core/fix-pr-batch.js";
9
+ import { createRunId, writeArtifactManifest } from "../core/artifacts.js";
15
10
  import { renderResult } from "../output/format.js";
16
11
  import { writeGitHubOutput } from "../output/github.js";
17
12
  import { createSarifReport } from "../output/sarif.js";
@@ -19,6 +14,8 @@ import { renderPrReport } from "../output/pr-report.js";
19
14
  import { writeFileAtomic } from "../utils/io.js";
20
15
  import { resolveFailReason } from "../core/summary.js";
21
16
  import { stableStringify } from "../utils/stable-json.js";
17
+ import { handleDirectCommand, runPrimaryCommand } from "./dispatch.js";
18
+ import { renderHelp } from "./help.js";
22
19
  async function main() {
23
20
  try {
24
21
  const argv = process.argv.slice(2);
@@ -31,120 +28,16 @@ async function main() {
31
28
  return;
32
29
  }
33
30
  const parsed = await parseCliArgs(argv);
34
- if (parsed.command === "init-ci") {
35
- const workflow = await initCiWorkflow(parsed.options.cwd, parsed.options.force, {
36
- mode: parsed.options.mode,
37
- schedule: parsed.options.schedule,
38
- });
39
- process.stdout.write(workflow.created
40
- ? `Created CI workflow at ${workflow.path}\n`
41
- : `CI workflow already exists at ${workflow.path}. Use --force to overwrite.\n`);
42
- return;
43
- }
44
- if (parsed.command === "baseline") {
45
- if (parsed.options.action === "save") {
46
- const saved = await saveBaseline(parsed.options);
47
- process.stdout.write(`Saved baseline at ${saved.filePath} (${saved.entries} entries)\n`);
48
- return;
49
- }
50
- const diff = await diffBaseline(parsed.options);
51
- const changes = diff.added.length + diff.removed.length + diff.changed.length;
52
- if (changes === 0) {
53
- process.stdout.write(`No baseline drift detected (${diff.filePath}).\n`);
54
- return;
55
- }
56
- process.stdout.write(`Baseline drift detected (${diff.filePath}).\n`);
57
- if (diff.added.length > 0) {
58
- process.stdout.write(`Added: ${diff.added.length}\n`);
59
- }
60
- if (diff.removed.length > 0) {
61
- process.stdout.write(`Removed: ${diff.removed.length}\n`);
62
- }
63
- if (diff.changed.length > 0) {
64
- process.stdout.write(`Changed: ${diff.changed.length}\n`);
65
- }
66
- process.exitCode = 1;
67
- return;
68
- }
69
- // ─── v0.5.1 commands: lazy-loaded, isolated from check pipeline ──────────
70
- if (parsed.command === "bisect") {
71
- const { runBisect } = await import("../commands/bisect/runner.js");
72
- const result = await runBisect(parsed.options);
73
- process.exitCode = result.breakingVersion ? 1 : 0;
74
- return;
75
- }
76
- if (parsed.command === "audit") {
77
- const { runAudit } = await import("../commands/audit/runner.js");
78
- const result = await runAudit(parsed.options);
79
- process.exitCode = result.advisories.length > 0 ? 1 : 0;
80
- return;
81
- }
82
- if (parsed.command === "health") {
83
- const { runHealth } = await import("../commands/health/runner.js");
84
- const result = await runHealth(parsed.options);
85
- process.exitCode = result.totalFlagged > 0 ? 1 : 0;
86
- return;
87
- }
88
- // ─── v0.5.4 commands ─────────────────────────────────────────────────────
89
- if (parsed.command === "unused") {
90
- const { runUnused } = await import("../commands/unused/runner.js");
91
- const result = await runUnused(parsed.options);
92
- process.exitCode =
93
- result.totalUnused > 0 || result.totalMissing > 0 ? 1 : 0;
94
- return;
95
- }
96
- if (parsed.command === "resolve") {
97
- const { runResolve } = await import("../commands/resolve/runner.js");
98
- const result = await runResolve(parsed.options);
99
- process.exitCode = result.errorConflicts > 0 ? 1 : 0;
100
- return;
101
- }
102
- if (parsed.command === "licenses") {
103
- const { runLicenses } = await import("../commands/licenses/runner.js");
104
- const result = await runLicenses(parsed.options);
105
- process.exitCode = result.totalViolations > 0 ? 1 : 0;
106
- return;
107
- }
108
- if (parsed.command === "snapshot") {
109
- const { runSnapshot } = await import("../commands/snapshot/runner.js");
110
- const result = await runSnapshot(parsed.options);
111
- process.exitCode = result.errors.length > 0 ? 1 : 0;
112
- return;
113
- }
114
- if (parsed.command === "review") {
115
- const { runReview } = await import("../commands/review/runner.js");
116
- const result = await runReview(parsed.options);
117
- process.exitCode =
118
- result.summary.verdict === "blocked" ||
119
- result.summary.verdict === "actionable" ||
120
- result.summary.verdict === "review"
121
- ? 1
122
- : 0;
123
- return;
124
- }
125
- if (parsed.command === "doctor") {
126
- const { runDoctor } = await import("../commands/doctor/runner.js");
127
- const result = await runDoctor(parsed.options);
128
- process.exitCode = result.verdict === "safe" ? 0 : 1;
31
+ if (await handleDirectCommand(parsed))
129
32
  return;
130
- }
131
- if (parsed.options.interactive &&
132
- (parsed.command === "check" ||
133
- parsed.command === "upgrade" ||
134
- parsed.command === "ci")) {
135
- const { runReview } = await import("../commands/review/runner.js");
136
- const result = await runReview({
137
- ...parsed.options,
138
- securityOnly: false,
139
- risk: undefined,
140
- diff: undefined,
141
- applySelected: parsed.command === "upgrade",
142
- });
143
- process.exitCode =
144
- result.summary.verdict === "safe" && result.updates.length === 0 ? 0 : 1;
145
- return;
146
- }
147
- const result = await runCommand(parsed);
33
+ if (parsed.command !== "check" &&
34
+ parsed.command !== "upgrade" &&
35
+ parsed.command !== "warm-cache" &&
36
+ parsed.command !== "ci") {
37
+ throw new Error(`Unhandled command: ${parsed.command}`);
38
+ }
39
+ const result = await runPrimaryCommand(parsed);
40
+ result.summary.runId = createRunId(parsed.command, parsed.options, result);
148
41
  if (parsed.options.fixPr &&
149
42
  (parsed.command === "check" ||
150
43
  parsed.command === "upgrade" ||
@@ -179,6 +72,10 @@ async function main() {
179
72
  const markdown = renderPrReport(result);
180
73
  await writeFileAtomic(parsed.options.prReportFile, markdown + "\n");
181
74
  }
75
+ const artifactManifest = await writeArtifactManifest(parsed.command, parsed.options, result);
76
+ if (artifactManifest) {
77
+ result.summary.artifactManifest = artifactManifest.artifactManifestPath;
78
+ }
182
79
  result.summary.failReason = resolveFailReason(result.updates, result.errors, parsed.options.failOn, parsed.options.maxUpdates, parsed.options.ci);
183
80
  const renderStartedAt = Date.now();
184
81
  let rendered = renderResult(result, parsed.options.format, {
@@ -221,325 +118,6 @@ async function main() {
221
118
  }
222
119
  }
223
120
  void main();
224
- function renderHelp(command) {
225
- const isCommand = command && !command.startsWith("-");
226
- if (isCommand && command === "check") {
227
- return `rainy-updates check [options]
228
-
229
- Detect candidate dependency updates. This is the first step in the flow:
230
- check detects
231
- doctor summarizes
232
- review decides
233
- upgrade applies
234
-
235
- Options:
236
- --workspace
237
- --target patch|minor|major|latest
238
- --filter <pattern>
239
- --reject <pattern>
240
- --dep-kinds deps,dev,optional,peer
241
- --concurrency <n>
242
- --registry-timeout-ms <n>
243
- --registry-retries <n>
244
- --cache-ttl <seconds>
245
- --stream
246
- --policy-file <path>
247
- --offline
248
- --fix-pr
249
- --fix-branch <name>
250
- --fix-commit-message <text>
251
- --fix-dry-run
252
- --fix-pr-no-checkout
253
- --fix-pr-batch-size <n>
254
- --no-pr-report
255
- --json-file <path>
256
- --github-output <path>
257
- --sarif-file <path>
258
- --pr-report-file <path>
259
- --fail-on none|patch|minor|major|any
260
- --max-updates <n>
261
- --group-by none|name|scope|kind|risk
262
- --group-max <n>
263
- --cooldown-days <n>
264
- --pr-limit <n>
265
- --only-changed
266
- --interactive
267
- --show-impact
268
- --show-homepage
269
- --lockfile-mode preserve|update|error
270
- --log-level error|warn|info|debug
271
- --ci`;
272
- }
273
- if (isCommand && command === "warm-cache") {
274
- return `rainy-updates warm-cache [options]
275
-
276
- Pre-warm local metadata cache for faster CI checks.
277
-
278
- Options:
279
- --workspace
280
- --target patch|minor|major|latest
281
- --filter <pattern>
282
- --reject <pattern>
283
- --dep-kinds deps,dev,optional,peer
284
- --concurrency <n>
285
- --registry-timeout-ms <n>
286
- --registry-retries <n>
287
- --cache-ttl <seconds>
288
- --offline
289
- --stream
290
- --json-file <path>
291
- --github-output <path>
292
- --sarif-file <path>
293
- --pr-report-file <path>`;
294
- }
295
- if (isCommand && command === "upgrade") {
296
- return `rainy-updates upgrade [options]
297
-
298
- Apply an approved change set to package.json manifests.
299
-
300
- Options:
301
- --workspace
302
- --sync
303
- --install
304
- --pm auto|npm|pnpm
305
- --target patch|minor|major|latest
306
- --policy-file <path>
307
- --concurrency <n>
308
- --registry-timeout-ms <n>
309
- --registry-retries <n>
310
- --fix-pr
311
- --fix-branch <name>
312
- --fix-commit-message <text>
313
- --fix-dry-run
314
- --fix-pr-no-checkout
315
- --fix-pr-batch-size <n>
316
- --interactive
317
- --lockfile-mode preserve|update|error
318
- --no-pr-report
319
- --json-file <path>
320
- --pr-report-file <path>`;
321
- }
322
- if (isCommand && command === "ci") {
323
- return `rainy-updates ci [options]
324
-
325
- Run CI-oriented automation around the same lifecycle:
326
- check detects
327
- doctor summarizes
328
- review decides
329
- upgrade applies
330
-
331
- Options:
332
- --workspace
333
- --mode minimal|strict|enterprise
334
- --group-by none|name|scope|kind|risk
335
- --group-max <n>
336
- --cooldown-days <n>
337
- --pr-limit <n>
338
- --only-changed
339
- --offline
340
- --concurrency <n>
341
- --registry-timeout-ms <n>
342
- --registry-retries <n>
343
- --stream
344
- --fix-pr
345
- --fix-branch <name>
346
- --fix-commit-message <text>
347
- --fix-dry-run
348
- --fix-pr-no-checkout
349
- --fix-pr-batch-size <n>
350
- --no-pr-report
351
- --json-file <path>
352
- --github-output <path>
353
- --sarif-file <path>
354
- --pr-report-file <path>
355
- --fail-on none|patch|minor|major|any
356
- --max-updates <n>
357
- --lockfile-mode preserve|update|error
358
- --log-level error|warn|info|debug
359
- --ci`;
360
- }
361
- if (isCommand && command === "init-ci") {
362
- return `rainy-updates init-ci [options]
363
-
364
- Create a GitHub Actions workflow template at:
365
- .github/workflows/rainy-updates.yml
366
-
367
- Options:
368
- --force
369
- --mode minimal|strict|enterprise
370
- --schedule weekly|daily|off`;
371
- }
372
- if (isCommand && command === "baseline") {
373
- return `rainy-updates baseline [options]
374
-
375
- Save or compare dependency baseline snapshots.
376
-
377
- Options:
378
- --save
379
- --check
380
- --file <path>
381
- --workspace
382
- --dep-kinds deps,dev,optional,peer
383
- --ci`;
384
- }
385
- if (isCommand && command === "audit") {
386
- return `rainy-updates audit [options]
387
-
388
- Scan dependencies for CVEs using OSV.dev and GitHub Advisory Database.
389
-
390
- Options:
391
- --workspace
392
- --severity critical|high|medium|low
393
- --summary
394
- --report table|summary|json
395
- --source auto|osv|github|all
396
- --fix
397
- --dry-run
398
- --commit
399
- --pm auto|npm|pnpm|bun|yarn
400
- --json-file <path>
401
- --concurrency <n>
402
- --registry-timeout-ms <n>`;
403
- }
404
- if (isCommand && command === "review") {
405
- return `rainy-updates review [options]
406
-
407
- Review is the decision center of Rainy Updates.
408
- Use it to inspect risk, security, peer, license, and policy context before applying changes.
409
-
410
- Options:
411
- --workspace
412
- --interactive
413
- --security-only
414
- --risk critical|high|medium|low
415
- --diff patch|minor|major|latest
416
- --apply-selected
417
- --policy-file <path>
418
- --json-file <path>
419
- --concurrency <n>
420
- --registry-timeout-ms <n>
421
- --registry-retries <n>`;
422
- }
423
- if (isCommand && command === "doctor") {
424
- return `rainy-updates doctor [options]
425
-
426
- Produce a fast summary verdict and point the operator to review when action is needed.
427
-
428
- Options:
429
- --workspace
430
- --verdict-only
431
- --json-file <path>`;
432
- }
433
- return `rainy-updates (rup / rainy-up) <command> [options]
434
-
435
- Commands:
436
- check Detect candidate updates
437
- doctor Summarize what matters
438
- review Decide what to do
439
- upgrade Apply the approved change set
440
- ci Run CI-focused orchestration
441
- warm-cache Warm local cache for fast/offline checks
442
- init-ci Scaffold GitHub Actions workflow
443
- baseline Save/check dependency baseline snapshots
444
- audit Scan dependencies for CVEs (OSV.dev + GitHub)
445
- health Detect stale/deprecated/unmaintained packages
446
- bisect Find which version of a dep introduced a failure
447
- unused Detect unused or missing npm dependencies
448
- resolve Check peer dependency conflicts (pure-TS, no subprocess)
449
- licenses Scan dependency licenses and generate SPDX SBOM
450
- snapshot Save, list, restore, and diff dependency state snapshots
451
-
452
- Global options:
453
- --cwd <path>
454
- --workspace
455
- --target patch|minor|major|latest
456
- --format table|json|minimal|github|metrics
457
- --json-file <path>
458
- --github-output <path>
459
- --sarif-file <path>
460
- --pr-report-file <path>
461
- --policy-file <path>
462
- --fail-on none|patch|minor|major|any
463
- --max-updates <n>
464
- --group-by none|name|scope|kind|risk
465
- --group-max <n>
466
- --cooldown-days <n>
467
- --pr-limit <n>
468
- --only-changed
469
- --interactive
470
- --show-impact
471
- --show-homepage
472
- --mode minimal|strict|enterprise
473
- --fix-pr
474
- --fix-branch <name>
475
- --fix-commit-message <text>
476
- --fix-dry-run
477
- --fix-pr-no-checkout
478
- --fix-pr-batch-size <n>
479
- --no-pr-report
480
- --log-level error|warn|info|debug
481
- --concurrency <n>
482
- --registry-timeout-ms <n>
483
- --registry-retries <n>
484
- --cache-ttl <seconds>
485
- --offline
486
- --stream
487
- --lockfile-mode preserve|update|error
488
- --ci
489
- --help, -h
490
- --version, -v`;
491
- }
492
- async function runCommand(parsed) {
493
- if (parsed.command === "review") {
494
- const { runReview } = await import("../commands/review/runner.js");
495
- const result = await runReview(parsed.options);
496
- return {
497
- projectPath: result.projectPath,
498
- packagePaths: result.items.map((item) => item.update.packagePath),
499
- packageManager: "unknown",
500
- target: result.target,
501
- timestamp: new Date().toISOString(),
502
- summary: result.summary,
503
- updates: result.updates,
504
- errors: result.errors,
505
- warnings: result.warnings,
506
- };
507
- }
508
- if (parsed.command === "doctor") {
509
- const { runDoctor } = await import("../commands/doctor/runner.js");
510
- const result = await runDoctor(parsed.options);
511
- return {
512
- projectPath: result.review.projectPath,
513
- packagePaths: result.review.items.map((item) => item.update.packagePath),
514
- packageManager: "unknown",
515
- target: result.review.target,
516
- timestamp: new Date().toISOString(),
517
- summary: result.summary,
518
- updates: result.review.updates,
519
- errors: result.review.errors,
520
- warnings: result.review.warnings,
521
- };
522
- }
523
- if (parsed.command === "upgrade") {
524
- return await upgrade(parsed.options);
525
- }
526
- if (parsed.command === "warm-cache") {
527
- return await warmCache(parsed.options);
528
- }
529
- if (parsed.command === "ci") {
530
- return await runCi(parsed.options);
531
- }
532
- if (parsed.options.fixPr) {
533
- const upgradeOptions = {
534
- ...parsed.options,
535
- install: false,
536
- packageManager: "auto",
537
- sync: false,
538
- };
539
- return await upgrade(upgradeOptions);
540
- }
541
- return await check(parsed.options);
542
- }
543
121
  async function readPackageVersion() {
544
122
  const currentFile = fileURLToPath(import.meta.url);
545
123
  const packageJsonPath = path.resolve(path.dirname(currentFile), "../../package.json");
@@ -0,0 +1,16 @@
1
+ import type { ParsedCliArgs } from "../core/options.js";
2
+ import type { CheckOptions, CheckResult, UpgradeOptions } from "../types/index.js";
3
+ export declare function handleDirectCommand(parsed: ParsedCliArgs): Promise<boolean>;
4
+ export declare function runPrimaryCommand(parsed: {
5
+ command: "check";
6
+ options: CheckOptions;
7
+ } | {
8
+ command: "upgrade";
9
+ options: UpgradeOptions;
10
+ } | {
11
+ command: "warm-cache";
12
+ options: CheckOptions;
13
+ } | {
14
+ command: "ci";
15
+ options: CheckOptions;
16
+ }): Promise<CheckResult>;