@conterra/vuln-scan 1.0.12 → 1.0.14

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 CHANGED
@@ -179,6 +179,13 @@ These variables can also be defined in a `.env` file in the working directory.
179
179
  Two summary files are written directly into `outDir`:
180
180
 
181
181
  - `scan-summary.txt` - The console "scan summary" output as plain text.
182
+ New vulnerabilities are annotated with a VEX-lookup hint so it is clear that
183
+ "new" means "no project-level VEX entry yet":
184
+ - `(VEX entry missing)` - the VEX store contains a
185
+ statement for this CVE (for another product), but none that applies to
186
+ this project. Adding/importing a project-level entry will silence it.
187
+ - `(VEX file missing)` - the CVE has not been triaged anywhere in the
188
+ VEX store yet.
182
189
  - `scan-summary.json` - Machine-readable summary, for post-processing or downstream tools. Example (truncated):
183
190
 
184
191
  ```json
@@ -418,17 +425,77 @@ These can also be set in a `.env` file in the working directory.
418
425
  | `addToBoard[].matchProjects` | no | Glob patterns to activate this entry. Defaults to `["*"]`. |
419
426
  | `autoCloseBelowSeverity` | no | Default auto-close threshold inherited by every `issues[]` entry that does not override it. One of `UNKNOWN`, `LOW`, `MEDIUM`, `HIGH`, `CRITICAL`. |
420
427
  | `issues[].autoCloseBelowSeverity` | no | Per-rule override of the top-level threshold. |
428
+ | `issues[].projectOverrides` | no | Per-project overrides of this rule's `autoCloseBelowSeverity`. See below. |
421
429
 
422
430
  `addToBoard` resolution: only entries whose `matchProjects` cover the vulnerability's affected scan projects are considered. The **first** matching scrum entry (with `sprintBoardId`) claims the sprint; further scrum entries are ignored. Kanban entries (no `sprintBoardId`) all contribute their labels.
423
431
 
424
432
  #### Auto-close low-severity issues
425
433
 
426
- When `autoCloseBelowSeverity` (top-level or per-issue rule) is set, newly-created issues whose vulnerability severity is **strictly below** the threshold are immediately transitioned to a status whose Jira status category is `done` (the first such transition exposed by the workflow is used, regardless of the status's display name and locale). The board/sprint assignment, labels and comment described above still happen *before* the transition, so the issue is reachable on the configured board even though it starts out closed. A short German-language comment is added explaining the auto-closure.
434
+ When `autoCloseBelowSeverity` (top-level or per-issue rule) is set, newly-created issues whose vulnerability severity is **strictly below** the threshold are immediately transitioned to a status whose Jira status category is `done` (the first such transition exposed by the workflow is used, regardless of the status's display name and locale). The board/sprint assignment, labels and comment described above still happen *before* the transition, so the issue is reachable on the configured board even though it starts out closed. A short German-language comment is added explaining the auto-closure (see below).
427
435
 
428
436
  For *existing* issues, the threshold only suppresses re-opening: when a closed sub-threshold issue gains a newly-affected project, the project label and "Zusätzlich gemeldet für" comment are added as usual, but the issue is **not** re-opened (and never re-closed). Issues at or above the threshold keep the existing re-open + re-add-to-active-sprint behavior.
429
437
 
430
438
  Threshold semantics mirror `ct-vuln-auto-vex`: with `"HIGH"`, severities `MEDIUM`, `LOW` and `UNKNOWN` are auto-closed, while `HIGH` and `CRITICAL` stay open.
431
439
 
440
+ ##### Auto-acknowledgement comments
441
+
442
+ The Jira reporter posts one of three German comment shapes depending on the per-project resolver outcome (see `projectOverrides` below for the bucket definitions):
443
+
444
+ - **Auto-close comment** — posted after a successful close transition. Lists every project that was auto-acknowledged together with its effective threshold:
445
+
446
+ ```
447
+ Automatisch geschlossen: Schwere MEDIUM liegt unterhalb der konfigurierten Auto-Close-Schwelle.
448
+ Auto-akzeptiert für:
449
+ - mapapps@4.20.0 (Schwelle HIGH)
450
+ - other-tool@1.0.0 (Schwelle CRITICAL)
451
+ ```
452
+
453
+ - **Partial-ack comment** (`Teilweise auto-akzeptiert`) — posted on a newly-created issue that stays open because the issue's matching projects split across both buckets. Names which projects are implicitly auto-acknowledged and which still require manual evaluation:
454
+
455
+ ```
456
+ Teilweise auto-akzeptiert. Schwere HIGH.
457
+ Auto-akzeptiert für:
458
+ - other-tool@1.0.0 (Schwelle CRITICAL)
459
+ Manuelle Bewertung erforderlich für:
460
+ - mapapps@4.20.0 (Schwelle HIGH)
461
+ ```
462
+
463
+ The comment is suppressed when all matching projects fall in a single bucket (the auto-close path covers all-auto-acknowledged; the all-manual case posts nothing).
464
+
465
+ - **Reopen-reason append** — when a closed sub-threshold issue is re-opened because newly-affected projects raise the bar, the consolidated reopen-reason comment is extended with the same `Auto-akzeptiert für` / `Manuelle Bewertung erforderlich für` sections (scoped to the newly added projects). The reporter does not post a second comment for the bucket split.
466
+
467
+ Projects that have no effective threshold configured (no `projectOverrides` match, no rule-level / top-level `autoCloseBelowSeverity`) are omitted from these listings — they neither block nor enable the auto-close decision in any new way.
468
+
469
+ ##### `issues[].projectOverrides` — per-project stricter thresholds
470
+
471
+ `projectOverrides` mirrors the [`projectOverrides`](#projectoverrides--per-project-stricter-thresholds) block of `auto-vex-conf.json`, so the same LTSS / regular-release-line policy can be expressed in both tools. Each entry binds one severity threshold to a list of glob patterns matched against the `name@version` project identifier (same shape used in `vuln-scan-conf.json#projects[]` and in Jira `reportProjects`). Only `*` wildcards are supported.
472
+
473
+ For every vulnerability covered by a rule:
474
+
475
+ 1. Each `matchingProject` (an affected project that matches the rule's `reportProjects`) resolves to an effective threshold — the strictest (lowest) matching `projectOverrides` entry, falling back to `issues[].autoCloseBelowSeverity` and finally the top-level `autoCloseBelowSeverity`.
476
+ 2. The issue's threshold is the **strictest across all matchingProjects**. A new issue is therefore only auto-closed when the vulnerability is strictly below the threshold for *every* matching project; any project that still requires deeper analysis keeps the issue open.
477
+ 3. Existing closed sub-threshold issues are never re-opened by `projectOverrides` — but raising the bar (e.g. via an LTSS override) above the live severity *does* re-open them, just as if `autoCloseBelowSeverity` itself had been raised.
478
+
479
+ Example mirroring the matching `auto-vex-conf.json`:
480
+
481
+ ```jsonc
482
+ {
483
+ "jiraProject": "PLATFORM",
484
+ "issueType": "CVE",
485
+ "reportProjects": ["*"],
486
+ "autoCloseBelowSeverity": "CRITICAL",
487
+ "projectOverrides": [
488
+ {
489
+ "projects": ["mapapps@4.20.*", "mapapps-sdi@5.8.*"],
490
+ "autoCloseBelowSeverity": "HIGH",
491
+ "comment": "LTSS means to analyze 'HIGH and CRITICAL'"
492
+ }
493
+ ]
494
+ }
495
+ ```
496
+
497
+ With this rule, a `MEDIUM` CVE that affects only `mapapps@4.20.0` is auto-closed (below `HIGH`); the same CVE bleeding into a non-LTSS project keeps the issue open if its effective threshold treats `MEDIUM` as actionable.
498
+
432
499
  ### CLI
433
500
 
434
501
  ```
@@ -467,12 +534,35 @@ Place this file next to `vuln-scan-conf.json`.
467
534
  }
468
535
  ```
469
536
 
470
- | Field | Required | Default | Description |
471
- | ----------------- | -------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
472
- | `impactStatement` | yes | - | `impact_statement` written into every auto-generated VEX statement. |
473
- | `maxSeverity` | no | `"HIGH"` | Exclusive threshold; CVEs strictly below this severity get a statement. One of `UNKNOWN`, `LOW`, `MEDIUM`, `HIGH`, `CRITICAL`. With the default, `MEDIUM` is auto-vexed but `HIGH` is not. |
474
- | `author` | no | `"conterra"` | `author` field of the OpenVEX document. |
475
- | `subDir` | no | `"auto"` | Sub-directory of `vexDir` for generated files. |
537
+ | Field | Required | Default | Description |
538
+ | ------------------ | -------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
539
+ | `impactStatement` | yes | - | `impact_statement` written into every auto-generated VEX statement. |
540
+ | `maxSeverity` | no | `"HIGH"` | Exclusive threshold; CVEs strictly below this severity get a statement. One of `UNKNOWN`, `LOW`, `MEDIUM`, `HIGH`, `CRITICAL`. With the default, `MEDIUM` is auto-vexed but `HIGH` is not. |
541
+ | `author` | no | `"conterra"` | `author` field of the OpenVEX document. |
542
+ | `subDir` | no | `"auto"` | Sub-directory of `vexDir` for generated files. |
543
+ | `projectOverrides` | no | `[]` | Per-project stricter thresholds. See below. |
544
+
545
+ #### `projectOverrides` — per-project stricter thresholds
546
+
547
+ By default the global `maxSeverity` applies uniformly. `projectOverrides` lets you raise the bar for selected projects so they require manual review at lower severities. Each entry binds one severity threshold to a list of glob patterns matched against the `name@version` project identifier (same shape used in `vuln-scan-conf.json#projects[]` and in Jira `reportProjects`). Only `*` wildcards are supported. If several entries match the same project, the strictest (lowest) `maxSeverity` wins.
548
+
549
+ ```json
550
+ {
551
+ "impactStatement": "Auto-acknowledged: no evidence of exploitability.",
552
+ "maxSeverity": "CRITICAL",
553
+ "projectOverrides": [
554
+ {
555
+ "projects": ["mapapps@4.20.*"],
556
+ "maxSeverity": "HIGH",
557
+ "comment": "Stricter review for the upcoming release line."
558
+ }
559
+ ]
560
+ }
561
+ ```
562
+
563
+ With the example above, all projects auto-VEX everything below `CRITICAL`, but for `mapapps@4.20.x` only severities below `HIGH` are auto-VEXed — `HIGH` and `CRITICAL` keep reaching manual triage (and the Jira reporter, since they remain in `scan-summary.json`).
564
+
565
+ When a single CVE is associated with **both** a "strict" and a "lax" project, the generated statement covers only the lax projects' PURLs. The strict project's PURL is left out, so the CVE re-surfaces for that project on the next scan and flows into Jira normally. Adding a new (or tighter) override on a subsequent run invalidates any pre-existing auto-VEX product whose owning project now resolves to a stricter effective threshold — even if the live severity itself hasn't changed.
476
566
 
477
567
  ### Usage
478
568
 
@@ -493,8 +583,8 @@ $ ct-vuln-auto-vex --write-missing-marker
493
583
  ### Behaviour
494
584
 
495
585
  - Only entries from `summary.vulnerabilities` are processed; this map already contains only newly detected CVEs, so previously declared vulnerabilities are never re-processed.
496
- - Each generated statement records the authoritative severity threshold via `status_notes: "auto_vex_max_severity=<maxSeverity>"`. This marker is parsed by the scanner and the auto-vex tool itself on subsequent runs.
497
- - **Severity-escalation invalidation:** on every run, all statements under `<vexDir>/<subDir>` are inspected. For each statement, if the live severity in `scan-summary.json` is no longer strictly below the recorded `auto_vex_max_severity`, the affected product is removed (and the file is deleted if no products remain). Legacy statements without the marker fall back to the current `maxSeverity`.
586
+ - Each generated statement records the authoritative severity threshold via `status_notes: "auto_vex_max_severity=<threshold>"`, where `<threshold>` is the effective per-project threshold for the PURLs in that specific statement (the strictest matching `projectOverrides` entry, or `maxSeverity` when none matches). When a single CVE affects multiple projects whose effective thresholds differ, one statement is emitted per threshold bucket so the marker stays accurate per PURL. The marker is parsed by the scanner and the auto-vex tool itself on subsequent runs.
587
+ - **Severity-escalation invalidation:** on every run, all statements under `<vexDir>/<subDir>` are inspected. For each product on each statement, the effective threshold is the strictest of (a) the recorded `auto_vex_max_severity` marker (or the current `maxSeverity` for legacy statements without a marker) and (b) the per-project effective threshold from `projectOverrides`. If the live severity is no longer strictly below that threshold, the product is removed (and the file is deleted if no products remain). This means adding or tightening a `projectOverrides` entry invalidates pre-existing auto-VEX products for the matched projects on the next run, even when the live severity hasn't changed.
498
588
  - During the next scan, the matcher in `VexStore` also skips auto VEX statements whose recorded threshold is exceeded — so an escalated CVE re-surfaces on the same run that detects the escalation, even before the next `ct-vuln-auto-vex` cleanup. Manual VEX statements (no marker) are unaffected by both checks.
499
589
  - `--write-missing-marker` is a one-off migration mode: it stamps `auto_vex_max_severity=<maxSeverity>` into every statement under `<vexDir>/<subDir>` that lacks any `status_notes`. Existing markers are preserved; unrelated manual notes are left alone (with a warning). The invalidation pass and statement creation are skipped in this mode; combine with `--dry-run` to preview.
500
590
  - If `<vexDir>/<subDir>/<CVE-ID>.json` already exists, the new statement is **appended** (document version is bumped). Manual edits in the same file are preserved.
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var I=Object.create;var w=Object.defineProperty;var D=Object.getOwnPropertyDescriptor;var A=Object.getOwnPropertyNames;var T=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var j=(r,t,e,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of A(t))!_.call(r,i)&&i!==e&&w(r,i,{get:()=>t[i],enumerable:!(n=D(t,i))||n.enumerable});return r};var x=(r,t,e)=>(e=r!=null?I(T(r)):{},j(t||!r||!r.__esModule?w(e,"default",{value:r,enumerable:!0}):e,r));var c=x(require("path")),g=require("fs/promises");var a=require("fs/promises");async function m(r){try{return await L(r)?JSON.parse(await(0,a.readFile)(r,{encoding:"utf-8"})):void 0}catch(t){throw new Error(`Error reading JSON file ${r}: ${t}`,{cause:t})}}async function P(r,t){let e=JSON.stringify(t,null,4)+`
3
- `,n=await U(r,e);await(0,a.writeFile)(r,n,{encoding:"utf-8"})}async function L(r){try{return await(0,a.access)(r,a.constants.F_OK),!0}catch{return!1}}async function U(r,t){let e=await $();if(!e)return t;let n=await e.resolveConfig(r);return n?await e.format(t,{...n,filepath:r}):t}var R;function $(){return R??=import("prettier").catch(()=>{})}var u=["UNKNOWN","LOW","MEDIUM","HIGH","CRITICAL"];var h=class r{constructor(t){this.workingDir=t}workingDir;static DEFAULT_MAVEN_REPO="https://repository.conterra.de/repository/maven-mirror-ct";static DEFAULT_VEX_SUBDIR="input/vex";static DEFAULT_OUT_SUBDIR="output";static DEFAULT_CACHE_SUBDIR="cache";static DEFAULT_SCANNERS=["grype","trivy","ossindex"];normalize(t,e){let n=t.findNoLongerDetectedVulnerabilitiesOnlyForSnapshots??!1;return{projectConfigFileLocation:e,onNewVulnerabilities:t.onNewVulnerabilities??(t.failOnNewVulnerabilities?"fail":"warn"),onNoLongerDetectedVulnerabilities:t.onNoLongerDetectedVulnerabilities??"ignore",reportNoLongerDetectedVulnerabilities:t.reportNoLongerDetectedVulnerabilities??!0,consoleReport:t.consoleReport??"BY_PROJECT_DETAILED",createSubDirsForProject:t.createSubDirsForProject??!0,mavenRepo:t.mavenRepo??r.DEFAULT_MAVEN_REPO,vexUrls:t.vexUrls??[],vexDir:this.resolvePath(t.vexDir)??(0,c.resolve)(this.workingDir,r.DEFAULT_VEX_SUBDIR),outDir:this.resolvePath(t.outDir)??(0,c.resolve)(this.workingDir,r.DEFAULT_OUT_SUBDIR),cacheDir:this.resolvePath(t.cacheDir)??(0,c.resolve)(this.workingDir,r.DEFAULT_CACHE_SUBDIR),scanners:this.normalizeScanners(t.scanners,e),projects:this.normalizeProjects(t.projects??[],n)}}normalizeScanners(t,e){return(t??r.DEFAULT_SCANNERS).map(i=>{if(typeof i!="string")throw new Error(`Invalid scanner name '${String(i)}' in configuration file '${e}'`);let o=i.split("@");if(o.length>2)throw new Error(`Invalid scanner name '${i}' in configuration file '${e}'`);return{name:o[0],version:o[1]??""}})}normalizeProjects(t,e){return t.map(n=>{let i=n;if(!i.name)throw new Error("Project name is missing on entry: "+JSON.stringify(i));if(!i.version)throw new Error("Project version is missing on entry: "+JSON.stringify(i));if(!i.purl)throw new Error("Project purl is missing on entry: "+JSON.stringify(i));let o={...i,purlAliases:i.purlAliases??[],enabled:i.enabled??!0,silent:i.silent??!1,minimumSeverity:i.minimumSeverity??"UNKNOWN"};return o.sbomFile?{...o,sbomFile:this.resolvePath(o.sbomFile)??o.sbomFile}:{...o,detectNoLongerUsedVulnerabilities:e?o.purl.endsWith("-SNAPSHOT"):!0}})}resolvePath(t){if(t)return c.default.isAbsolute(t)?t:(0,c.resolve)(this.workingDir,t)}},d=class{constructor(t){this.workingDir=t;this.normalizer=new h(t)}workingDir;normalizer;projectConfigCache;async loadProjectConfig(){return this.projectConfigCache??=this.doLoadProjectConfig(),this.projectConfigCache}async doLoadProjectConfig(){let t=(0,c.resolve)(this.workingDir,"vuln-scan-conf.json"),e=await m(t);if(!e)throw new Error(`Missing project configuration file '${t}'`);return this.normalizer.normalize(e,t)}async loadJiraConfig(t){let e=await(0,g.readFile)(t,"utf8"),n=JSON.parse(e);if(!n.issues&&n.issue&&(n.issues=n.issue),!n.jiraUrl||typeof n.jiraUrl!="string")throw new Error("jira-conf.json: missing or invalid 'jiraUrl' field");if(!Array.isArray(n.issues))throw new Error("jira-conf.json: missing or invalid 'issues' array");this.validateAutoCloseSeverity(n.autoCloseBelowSeverity,"jira-conf.json: invalid 'autoCloseBelowSeverity'");for(let[i,o]of n.issues.entries())o&&typeof o=="object"&&this.validateAutoCloseSeverity(o.autoCloseBelowSeverity,`jira-conf.json: invalid 'issues[${i}].autoCloseBelowSeverity'`);return n}validateAutoCloseSeverity(t,e){if(t!==void 0&&!u.includes(t))throw new Error(`${e} value '${String(t)}'. Must be one of: ${u.join(", ")}`)}async loadAutoVexConfig(t){let e=await(0,g.readFile)(t,"utf8"),n=JSON.parse(e);if(!n.impactStatement||typeof n.impactStatement!="string")throw new Error("auto-vex-conf.json: missing or invalid 'impactStatement' field (must be a non-empty string)");if(n.maxSeverity!==void 0&&!u.includes(n.maxSeverity))throw new Error(`auto-vex-conf.json: invalid 'maxSeverity' value '${String(n.maxSeverity)}'. Must be one of: ${u.join(", ")}`);return n}};var N=require("fs/promises"),v=require("path");var E=require("crypto");var M="https://openvex.dev/ns/v0.2.0";function V(r,t="conterra"){let n=`https://openvex.dev/docs/public/vex-${(0,E.randomUUID)()}`,i=r.timestamp??new Date().toISOString();return{"@context":M,"@id":n,author:t,timestamp:i,last_updated:i,version:1,statements:[r]}}function b(r,t){let e=t.timestamp??new Date().toISOString();return{...r,last_updated:e,version:r.version+1,statements:[...r.statements,t]}}var f=require("fs/promises"),p=require("path");var l=class{constructor(t){this.location=t}location;_content=void 0;_exists=!1;get exists(){return this._exists}get content(){return this._content}set content(t){this._content=t,this._exists=t!==void 0}async read(){let t=await m(this.location);this._content=t??void 0,this._exists=this._content!==void 0}async write(){if(this._content===void 0)throw new Error(`Cannot write VexFile: content is undefined (${this.location})`);await(0,f.mkdir)((0,p.dirname)((0,p.resolve)(this.location)),{recursive:!0}),await P(this.location,this._content)}async delete(){await(0,f.unlink)(this.location),this._exists=!1}upsert(t,e){return this._content===void 0?(this._content=V(t,e),this._exists=!0,{created:!0}):(this._content=b(this._content,t),{created:!1})}addProductId(t,e){this.assertContentLoaded("addProductId");let n=!1;for(let i of this._content.statements){if(!i.products||i.products.some(s=>s["@id"]===e))continue;let o=i.products.findIndex(s=>s["@id"]===t);o!==-1&&(i.products.splice(o+1,0,{"@id":e}),n=!0)}return n}removeProductId(t,e){this.assertContentLoaded("removeProductId");let n=this._content.statements,i=[],o=!1;for(let s of n){if(e&&!C(s).has(e)||!s.products)continue;let y=s.products.findIndex(F=>F["@id"]===t);y!==-1&&(s.products.splice(y,1),o=!0,s.products.length===0&&i.push(s))}if(!o)return"unchanged";for(let s of i)n.splice(n.indexOf(s),1);return n.length===0?"emptied":"changed"}hasStatementForProduct(t){return this.assertContentLoaded("hasStatementForProduct"),this._content.statements.some(e=>e.products?.some(n=>n["@id"]===t)??!1)}assertContentLoaded(t){if(this._content===void 0)throw new Error(`VexFile.${t}(): content is not loaded. Call read() first (${this.location})`)}};async function S(r,t){for(let e of await(0,N.readdir)(r,{withFileTypes:!0}))e.name.endsWith(".json")?await t(new l((0,v.resolve)(e.parentPath,e.name))):e.isDirectory()&&await S((0,v.resolve)(e.parentPath,e.name),t)}function C(r){let t=r.vulnerability.name;return new Set([t,...r.vulnerability.aliases??[]])}async function O({workingDir:r,existingPurl:t,newPurl:e}){let n=await new d(r).loadProjectConfig();await S(n.vexDir,async i=>{await i.read(),i.addProductId(t,e)&&(console.info(`Add ${e} to ${i.location}`),await i.write())})}var B=process.cwd();(async()=>{let{existingPurl:r,newPurl:t}=await X();await O({workingDir:B,existingPurl:r,newPurl:t})})();async function X(){let r=process.argv[2];if(!r)throw new Error("Existing purl parameter missing.");let t=process.argv[3];if(!t)throw new Error("New purl parameter missing.");return{existingPurl:r,newPurl:t}}
2
+ "use strict";var F=Object.create;var E=Object.defineProperty;var D=Object.getOwnPropertyDescriptor;var T=Object.getOwnPropertyNames;var $=Object.getPrototypeOf,L=Object.prototype.hasOwnProperty;var U=(r,t,e,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of T(t))!L.call(r,i)&&i!==e&&E(r,i,{get:()=>t[i],enumerable:!(n=D(t,i))||n.enumerable});return r};var b=(r,t,e)=>(e=r!=null?F($(r)):{},U(t||!r||!r.__esModule?E(e,"default",{value:r,enumerable:!0}):e,r));var d=b(require("path")),S=require("fs/promises");var a=require("fs/promises");async function l(r){try{return await R(r)?JSON.parse(await(0,a.readFile)(r,{encoding:"utf-8"})):void 0}catch(t){throw new Error(`Error reading JSON file ${r}: ${t}`,{cause:t})}}async function j(r,t){let e=JSON.stringify(t,null,4)+`
3
+ `,n=await M(r,e);await(0,a.writeFile)(r,n,{encoding:"utf-8"})}async function R(r){try{return await(0,a.access)(r,a.constants.F_OK),!0}catch{return!1}}async function M(r,t){let e=await k();if(!e)return t;let n=await e.resolveConfig(r);return n?await e.format(t,{...n,filepath:r}):t}var B;function k(){return B??=import("prettier").catch(()=>{})}var u=["UNKNOWN","LOW","MEDIUM","HIGH","CRITICAL"];var y=class r{constructor(t){this.workingDir=t}workingDir;static DEFAULT_MAVEN_REPO="https://repository.conterra.de/repository/maven-mirror-ct";static DEFAULT_VEX_SUBDIR="input/vex";static DEFAULT_OUT_SUBDIR="output";static DEFAULT_CACHE_SUBDIR="cache";static DEFAULT_SCANNERS=["grype","trivy","ossindex"];normalize(t,e){let n=t.findNoLongerDetectedVulnerabilitiesOnlyForSnapshots??!1;return{projectConfigFileLocation:e,onNewVulnerabilities:t.onNewVulnerabilities??(t.failOnNewVulnerabilities?"fail":"warn"),onNoLongerDetectedVulnerabilities:t.onNoLongerDetectedVulnerabilities??"ignore",reportNoLongerDetectedVulnerabilities:t.reportNoLongerDetectedVulnerabilities??!0,consoleReport:t.consoleReport??"BY_PROJECT_DETAILED",createSubDirsForProject:t.createSubDirsForProject??!0,mavenRepo:t.mavenRepo??r.DEFAULT_MAVEN_REPO,vexUrls:t.vexUrls??[],vexDir:this.resolvePath(t.vexDir)??(0,d.resolve)(this.workingDir,r.DEFAULT_VEX_SUBDIR),outDir:this.resolvePath(t.outDir)??(0,d.resolve)(this.workingDir,r.DEFAULT_OUT_SUBDIR),cacheDir:this.resolvePath(t.cacheDir)??(0,d.resolve)(this.workingDir,r.DEFAULT_CACHE_SUBDIR),scanners:this.normalizeScanners(t.scanners,e),projects:this.normalizeProjects(t.projects??[],n)}}normalizeScanners(t,e){return(t??r.DEFAULT_SCANNERS).map(i=>{if(typeof i!="string")throw new Error(`Invalid scanner name '${String(i)}' in configuration file '${e}'`);let o=i.split("@");if(o.length>2)throw new Error(`Invalid scanner name '${i}' in configuration file '${e}'`);return{name:o[0],version:o[1]??""}})}normalizeProjects(t,e){return t.map(n=>{let i=n;if(!i.name)throw new Error("Project name is missing on entry: "+JSON.stringify(i));if(!i.version)throw new Error("Project version is missing on entry: "+JSON.stringify(i));if(!i.purl)throw new Error("Project purl is missing on entry: "+JSON.stringify(i));let o={...i,purlAliases:i.purlAliases??[],enabled:i.enabled??!0,silent:i.silent??!1,minimumSeverity:i.minimumSeverity??"UNKNOWN"};return o.sbomFile?{...o,sbomFile:this.resolvePath(o.sbomFile)??o.sbomFile}:{...o,detectNoLongerUsedVulnerabilities:e?o.purl.endsWith("-SNAPSHOT"):!0}})}resolvePath(t){if(t)return d.default.isAbsolute(t)?t:(0,d.resolve)(this.workingDir,t)}},f=class{constructor(t){this.workingDir=t;this.normalizer=new y(t)}workingDir;normalizer;projectConfigCache;async loadProjectConfig(){return this.projectConfigCache??=this.doLoadProjectConfig(),this.projectConfigCache}async doLoadProjectConfig(){let t=(0,d.resolve)(this.workingDir,"vuln-scan-conf.json"),e=await l(t);if(!e)throw new Error(`Missing project configuration file '${t}'`);return this.normalizer.normalize(e,t)}async loadJiraConfig(t){let e=await(0,S.readFile)(t,"utf8"),n=JSON.parse(e);if(!n.issues&&n.issue&&(n.issues=n.issue),!n.jiraUrl||typeof n.jiraUrl!="string")throw new Error("jira-conf.json: missing or invalid 'jiraUrl' field");if(!Array.isArray(n.issues))throw new Error("jira-conf.json: missing or invalid 'issues' array");this.validateAutoCloseSeverity(n.autoCloseBelowSeverity,"jira-conf.json: invalid 'autoCloseBelowSeverity'");for(let[i,o]of n.issues.entries())if(o&&typeof o=="object"){let s=o;this.validateAutoCloseSeverity(s.autoCloseBelowSeverity,`jira-conf.json: invalid 'issues[${i}].autoCloseBelowSeverity'`),this.validateAutoCloseProjectOverrides(s.projectOverrides,`jira-conf.json: invalid 'issues[${i}].projectOverrides'`)}return n}validateAutoCloseSeverity(t,e){if(t!==void 0&&!u.includes(t))throw new Error(`${e} value '${String(t)}'. Must be one of: ${u.join(", ")}`)}validateAutoCloseProjectOverrides(t,e){if(t!==void 0){if(!Array.isArray(t))throw new Error(`${e}: must be an array`);for(let n=0;n<t.length;n++){let i=t[n],o=`${e}[${n}]`;if(i==null||typeof i!="object")throw new Error(`${o}: must be an object`);let s=i,c=s.projects;if(!Array.isArray(c)||c.length===0)throw new Error(`${o}.projects: must be a non-empty array of strings`);for(let m=0;m<c.length;m++){let P=c[m];if(typeof P!="string"||P.length===0)throw new Error(`${o}.projects[${m}]: must be a non-empty string`)}if(s.autoCloseBelowSeverity===void 0)throw new Error(`${o}.autoCloseBelowSeverity: is required`);if(this.validateAutoCloseSeverity(s.autoCloseBelowSeverity,`${o}.autoCloseBelowSeverity`),s.comment!==void 0&&typeof s.comment!="string")throw new Error(`${o}.comment: must be a string`)}}}async loadAutoVexConfig(t){let e=await(0,S.readFile)(t,"utf8"),n=JSON.parse(e);if(!n.impactStatement||typeof n.impactStatement!="string")throw new Error("auto-vex-conf.json: missing or invalid 'impactStatement' field (must be a non-empty string)");if(n.maxSeverity!==void 0&&!u.includes(n.maxSeverity))throw new Error(`auto-vex-conf.json: invalid 'maxSeverity' value '${String(n.maxSeverity)}'. Must be one of: ${u.join(", ")}`);if(n.projectOverrides!==void 0){if(!Array.isArray(n.projectOverrides))throw new Error("auto-vex-conf.json: 'projectOverrides' must be an array");for(let[i,o]of n.projectOverrides.entries()){if(!o||typeof o!="object")throw new Error(`auto-vex-conf.json: 'projectOverrides[${i}]' must be an object`);let s=o;if(!Array.isArray(s.projects)||s.projects.length===0||!s.projects.every(c=>typeof c=="string"&&c.length>0))throw new Error(`auto-vex-conf.json: 'projectOverrides[${i}].projects' must be a non-empty array of non-empty strings`);if(!u.includes(s.maxSeverity))throw new Error(`auto-vex-conf.json: invalid 'projectOverrides[${i}].maxSeverity' value '${String(s.maxSeverity)}'. Must be one of: ${u.join(", ")}`)}}return n}};var _=require("fs/promises"),w=require("path");var C=require("crypto");var V="auto_vex_max_severity=";function p(r){let t=r.status_notes;if(!t||!t.startsWith(V))return;let e=t.slice(V.length).trim();return u.includes(e)?e:void 0}var X="https://openvex.dev/ns/v0.2.0";function O(r,t="conterra"){let n=`https://openvex.dev/docs/public/vex-${(0,C.randomUUID)()}`,i=r.timestamp??new Date().toISOString();return{"@context":X,"@id":n,author:t,timestamp:i,last_updated:i,version:1,statements:[r]}}function A(r,t){let e=t.timestamp??new Date().toISOString();return{...r,last_updated:e,version:r.version+1,statements:[...r.statements,t]}}var h=require("fs/promises"),v=require("path");var g=class{constructor(t){this.location=t}location;_content=void 0;_exists=!1;get exists(){return this._exists}get content(){return this._content}set content(t){this._content=t,this._exists=t!==void 0}async read(){let t=await l(this.location);this._content=t??void 0,this._exists=this._content!==void 0}async write(){if(this._content===void 0)throw new Error(`Cannot write VexFile: content is undefined (${this.location})`);await(0,h.mkdir)((0,v.dirname)((0,v.resolve)(this.location)),{recursive:!0}),await j(this.location,this._content)}async delete(){await(0,h.unlink)(this.location),this._exists=!1}upsert(t,e){if(this._content===void 0)return this._content=O(t,e),this._exists=!0,{created:!0,changed:!0};let n=p(t);if(n!==void 0){let i=this._content.statements.findIndex(o=>o.vulnerability.name===t.vulnerability.name&&o.status===t.status&&p(o)===n);if(i!==-1){let o=this._content.statements[i];return W(o,t)?{created:!1,changed:!1}:(o.products=t.products,o.impact_statement=t.impact_statement,o.action_statement=t.action_statement,o.justification=t.justification,o.status_notes=t.status_notes,o.timestamp=t.timestamp,this._content.version+=1,this._content.last_updated=t.timestamp??new Date().toISOString(),{created:!1,changed:!0})}}return this._content=A(this._content,t),{created:!1,changed:!0}}addProductId(t,e){this.assertContentLoaded("addProductId");let n=!1;for(let i of this._content.statements){if(!i.products||i.products.some(s=>s["@id"]===e))continue;let o=i.products.findIndex(s=>s["@id"]===t);o!==-1&&(i.products.splice(o+1,0,{"@id":e}),n=!0)}return n}removeProductId(t,e){this.assertContentLoaded("removeProductId");let n=this._content.statements,i=[],o=!1;for(let s of n){if(e&&!N(s).has(e)||!s.products)continue;let c=s.products.findIndex(m=>m["@id"]===t);c!==-1&&(s.products.splice(c,1),o=!0,s.products.length===0&&i.push(s))}if(!o)return"unchanged";for(let s of i)n.splice(n.indexOf(s),1);return n.length===0?"emptied":"changed"}hasStatementForProduct(t){return this.assertContentLoaded("hasStatementForProduct"),this._content.statements.some(e=>e.products?.some(n=>n["@id"]===t)??!1)}assertContentLoaded(t){if(this._content===void 0)throw new Error(`VexFile.${t}(): content is not loaded. Call read() first (${this.location})`)}};function W(r,t){return r.impact_statement!==t.impact_statement||r.action_statement!==t.action_statement||r.justification!==t.justification||r.status_notes!==t.status_notes?!1:H(r.products,t.products)}function H(r,t){let e=o=>Array.from(new Set((o??[]).map(s=>s["@id"]).filter(s=>typeof s=="string"))).sort(),n=e(r),i=e(t);return n.length!==i.length?!1:n.every((o,s)=>o===i[s])}async function x(r,t){for(let e of await(0,_.readdir)(r,{withFileTypes:!0}))e.name.endsWith(".json")?await t(new g((0,w.resolve)(e.parentPath,e.name))):e.isDirectory()&&await x((0,w.resolve)(e.parentPath,e.name),t)}function N(r){let t=r.vulnerability.name;return new Set([t,...r.vulnerability.aliases??[]])}async function I({workingDir:r,existingPurl:t,newPurl:e}){let n=await new f(r).loadProjectConfig();await x(n.vexDir,async i=>{await i.read(),i.addProductId(t,e)&&(console.info(`Add ${e} to ${i.location}`),await i.write())})}var J=process.cwd();(async()=>{let{existingPurl:r,newPurl:t}=await z();await I({workingDir:J,existingPurl:r,newPurl:t})})();async function z(){let r=process.argv[2];if(!r)throw new Error("Existing purl parameter missing.");let t=process.argv[3];if(!t)throw new Error("New purl parameter missing.");return{existingPurl:r,newPurl:t}}
@@ -1,20 +1,20 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var Zt=Object.create;var Qe=Object.defineProperty;var er=Object.getOwnPropertyDescriptor;var tr=Object.getOwnPropertyNames;var rr=Object.getPrototypeOf,nr=Object.prototype.hasOwnProperty;var Ze=(t,e)=>()=>{try{return e||t((e={exports:{}}).exports,e),e.exports}catch(r){throw e=0,r}};var ir=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of tr(e))!nr.call(t,i)&&i!==r&&Qe(t,i,{get:()=>e[i],enumerable:!(n=er(e,i))||n.enumerable});return t};var k=(t,e,r)=>(r=t!=null?Zt(rr(t)):{},ir(e||!t||!t.__esModule?Qe(r,"default",{value:t,enumerable:!0}):r,t));var St=Ze((ei,wt)=>{"use strict";wt.exports=Dr;function Er(t){let e={defaultWidth:0,output:process.stdout,tty:require("tty")};return t?(Object.keys(e).forEach(function(r){t[r]||(t[r]=e[r])}),t):e}function Dr(t){let e=Er(t);if(e.output.getWindowSize)return e.output.getWindowSize()[0]||e.defaultWidth;if(e.tty.getWindowSize)return e.tty.getWindowSize()[1]||e.defaultWidth;if(e.output.columns)return e.output.columns;if(process.env.CLI_WIDTH){let r=parseInt(process.env.CLI_WIDTH,10);if(!isNaN(r)&&r!==0)return r}return e.defaultWidth}});var Nt=Ze((mi,_t)=>{var Vr=require("stream"),Ae=class extends Vr{#r=null;constructor(e={}){super(e),this.writable=this.readable=!0,this.muted=!1,this.on("pipe",this._onpipe),this.replace=e.replace,this._prompt=e.prompt||null,this._hadControl=!1}#t(e,r){return this._dest?this._dest[e]:this._src?this._src[e]:r}#e(e,...r){typeof this._dest?.[e]=="function"&&this._dest[e](...r),typeof this._src?.[e]=="function"&&this._src[e](...r)}get isTTY(){return this.#r!==null?this.#r:this.#t("isTTY",!1)}set isTTY(e){this.#r=e}get rows(){return this.#t("rows")}get columns(){return this.#t("columns")}mute(){this.muted=!0}unmute(){this.muted=!1}_onpipe(e){this._src=e}pipe(e,r){return this._dest=e,super.pipe(e,r)}pause(){if(this._src)return this._src.pause()}resume(){if(this._src)return this._src.resume()}write(e){if(this.muted){if(!this.replace)return!0;if(e.match(/^\u001b/))return e.indexOf(this._prompt)===0&&(e=e.slice(this._prompt.length),e=e.replace(/./g,this.replace),e=this._prompt+e),this._hadControl=!0,this.emit("data",e);this._prompt&&this._hadControl&&e.indexOf(this._prompt)===0&&(this._hadControl=!1,this.emit("data",this._prompt),e=e.slice(this._prompt.length)),e=e.toString().replace(/./g,this.replace)}this.emit("data",e)}end(e){this.muted&&(e&&this.replace?e=e.toString().replace(/./g,this.replace):e=null),e&&this.emit("data",e),this.emit("end")}destroy(...e){return this.#e("destroy",...e)}destroySoon(...e){return this.#e("destroySoon",...e)}close(...e){return this.#e("close",...e)}};_t.exports=Ae});var O=k(require("path")),Le=require("fs/promises");var B=require("fs/promises");async function X(t){try{return await or(t)?JSON.parse(await(0,B.readFile)(t,{encoding:"utf-8"})):void 0}catch(e){throw new Error(`Error reading JSON file ${t}: ${e}`,{cause:e})}}async function re(t,e){let r=JSON.stringify(e,null,4)+`
3
- `,n=await sr(t,r);await(0,B.writeFile)(t,n,{encoding:"utf-8"})}async function or(t){try{return await(0,B.access)(t,B.constants.F_OK),!0}catch{return!1}}async function sr(t,e){let r=await lr();if(!r)return e;let n=await r.resolveConfig(t);return n?await r.format(e,{...n,filepath:t}):e}var ar;function lr(){return ar??=import("prettier").catch(()=>{})}var z=["UNKNOWN","LOW","MEDIUM","HIGH","CRITICAL"];var Re=class t{constructor(e){this.workingDir=e}workingDir;static DEFAULT_MAVEN_REPO="https://repository.conterra.de/repository/maven-mirror-ct";static DEFAULT_VEX_SUBDIR="input/vex";static DEFAULT_OUT_SUBDIR="output";static DEFAULT_CACHE_SUBDIR="cache";static DEFAULT_SCANNERS=["grype","trivy","ossindex"];normalize(e,r){let n=e.findNoLongerDetectedVulnerabilitiesOnlyForSnapshots??!1;return{projectConfigFileLocation:r,onNewVulnerabilities:e.onNewVulnerabilities??(e.failOnNewVulnerabilities?"fail":"warn"),onNoLongerDetectedVulnerabilities:e.onNoLongerDetectedVulnerabilities??"ignore",reportNoLongerDetectedVulnerabilities:e.reportNoLongerDetectedVulnerabilities??!0,consoleReport:e.consoleReport??"BY_PROJECT_DETAILED",createSubDirsForProject:e.createSubDirsForProject??!0,mavenRepo:e.mavenRepo??t.DEFAULT_MAVEN_REPO,vexUrls:e.vexUrls??[],vexDir:this.resolvePath(e.vexDir)??(0,O.resolve)(this.workingDir,t.DEFAULT_VEX_SUBDIR),outDir:this.resolvePath(e.outDir)??(0,O.resolve)(this.workingDir,t.DEFAULT_OUT_SUBDIR),cacheDir:this.resolvePath(e.cacheDir)??(0,O.resolve)(this.workingDir,t.DEFAULT_CACHE_SUBDIR),scanners:this.normalizeScanners(e.scanners,r),projects:this.normalizeProjects(e.projects??[],n)}}normalizeScanners(e,r){return(e??t.DEFAULT_SCANNERS).map(i=>{if(typeof i!="string")throw new Error(`Invalid scanner name '${String(i)}' in configuration file '${r}'`);let s=i.split("@");if(s.length>2)throw new Error(`Invalid scanner name '${i}' in configuration file '${r}'`);return{name:s[0],version:s[1]??""}})}normalizeProjects(e,r){return e.map(n=>{let i=n;if(!i.name)throw new Error("Project name is missing on entry: "+JSON.stringify(i));if(!i.version)throw new Error("Project version is missing on entry: "+JSON.stringify(i));if(!i.purl)throw new Error("Project purl is missing on entry: "+JSON.stringify(i));let s={...i,purlAliases:i.purlAliases??[],enabled:i.enabled??!0,silent:i.silent??!1,minimumSeverity:i.minimumSeverity??"UNKNOWN"};return s.sbomFile?{...s,sbomFile:this.resolvePath(s.sbomFile)??s.sbomFile}:{...s,detectNoLongerUsedVulnerabilities:r?s.purl.endsWith("-SNAPSHOT"):!0}})}resolvePath(e){if(e)return O.default.isAbsolute(e)?e:(0,O.resolve)(this.workingDir,e)}},V=class{constructor(e){this.workingDir=e;this.normalizer=new Re(e)}workingDir;normalizer;projectConfigCache;async loadProjectConfig(){return this.projectConfigCache??=this.doLoadProjectConfig(),this.projectConfigCache}async doLoadProjectConfig(){let e=(0,O.resolve)(this.workingDir,"vuln-scan-conf.json"),r=await X(e);if(!r)throw new Error(`Missing project configuration file '${e}'`);return this.normalizer.normalize(r,e)}async loadJiraConfig(e){let r=await(0,Le.readFile)(e,"utf8"),n=JSON.parse(r);if(!n.issues&&n.issue&&(n.issues=n.issue),!n.jiraUrl||typeof n.jiraUrl!="string")throw new Error("jira-conf.json: missing or invalid 'jiraUrl' field");if(!Array.isArray(n.issues))throw new Error("jira-conf.json: missing or invalid 'issues' array");this.validateAutoCloseSeverity(n.autoCloseBelowSeverity,"jira-conf.json: invalid 'autoCloseBelowSeverity'");for(let[i,s]of n.issues.entries())s&&typeof s=="object"&&this.validateAutoCloseSeverity(s.autoCloseBelowSeverity,`jira-conf.json: invalid 'issues[${i}].autoCloseBelowSeverity'`);return n}validateAutoCloseSeverity(e,r){if(e!==void 0&&!z.includes(e))throw new Error(`${r} value '${String(e)}'. Must be one of: ${z.join(", ")}`)}async loadAutoVexConfig(e){let r=await(0,Le.readFile)(e,"utf8"),n=JSON.parse(r);if(!n.impactStatement||typeof n.impactStatement!="string")throw new Error("auto-vex-conf.json: missing or invalid 'impactStatement' field (must be a non-empty string)");if(n.maxSeverity!==void 0&&!z.includes(n.maxSeverity))throw new Error(`auto-vex-conf.json: invalid 'maxSeverity' value '${String(n.maxSeverity)}'. Must be one of: ${z.join(", ")}`);return n}};var ue=class{constructor(e){this.configFilePath=e}configFilePath;async readRawConfig(){let e=await X(this.configFilePath);if(!e)throw new Error(`Missing project configuration file '${this.configFilePath}'`);return e}async insertAfter(e,r){let n=await this.readRawConfig(),i=n.projects??[],s=i.findIndex(o=>o.name===e.name&&o.version===e.version);if(s===-1)throw new Error(`Reference project ${e.name}@${e.version} not found in config`);i.splice(s+1,0,r),n.projects=i,await re(this.configFilePath,n)}async remove(e,r){let n=await this.readRawConfig(),i=n.projects??[],s=i.findIndex(o=>o.name===e&&o.version===r);return s===-1?!1:(i.splice(s,1),n.projects=i,await re(this.configFilePath,n),!0)}};var it=require("fs/promises"),Ie=require("path");var et=require("crypto");var cr="https://openvex.dev/ns/v0.2.0";function tt(t,e="conterra"){let n=`https://openvex.dev/docs/public/vex-${(0,et.randomUUID)()}`,i=t.timestamp??new Date().toISOString();return{"@context":cr,"@id":n,author:e,timestamp:i,last_updated:i,version:1,statements:[t]}}function rt(t,e){let r=e.timestamp??new Date().toISOString();return{...t,last_updated:r,version:t.version+1,statements:[...t.statements,e]}}var de=require("fs/promises"),pe=require("path");var fe=class{constructor(e){this.location=e}location;_content=void 0;_exists=!1;get exists(){return this._exists}get content(){return this._content}set content(e){this._content=e,this._exists=e!==void 0}async read(){let e=await X(this.location);this._content=e??void 0,this._exists=this._content!==void 0}async write(){if(this._content===void 0)throw new Error(`Cannot write VexFile: content is undefined (${this.location})`);await(0,de.mkdir)((0,pe.dirname)((0,pe.resolve)(this.location)),{recursive:!0}),await re(this.location,this._content)}async delete(){await(0,de.unlink)(this.location),this._exists=!1}upsert(e,r){return this._content===void 0?(this._content=tt(e,r),this._exists=!0,{created:!0}):(this._content=rt(this._content,e),{created:!1})}addProductId(e,r){this.assertContentLoaded("addProductId");let n=!1;for(let i of this._content.statements){if(!i.products||i.products.some(o=>o["@id"]===r))continue;let s=i.products.findIndex(o=>o["@id"]===e);s!==-1&&(i.products.splice(s+1,0,{"@id":r}),n=!0)}return n}removeProductId(e,r){this.assertContentLoaded("removeProductId");let n=this._content.statements,i=[],s=!1;for(let o of n){if(r&&!nt(o).has(r)||!o.products)continue;let a=o.products.findIndex(c=>c["@id"]===e);a!==-1&&(o.products.splice(a,1),s=!0,o.products.length===0&&i.push(o))}if(!s)return"unchanged";for(let o of i)n.splice(n.indexOf(o),1);return n.length===0?"emptied":"changed"}hasStatementForProduct(e){return this.assertContentLoaded("hasStatementForProduct"),this._content.statements.some(r=>r.products?.some(n=>n["@id"]===e)??!1)}assertContentLoaded(e){if(this._content===void 0)throw new Error(`VexFile.${e}(): content is not loaded. Call read() first (${this.location})`)}};async function Fe(t,e){for(let r of await(0,it.readdir)(t,{withFileTypes:!0}))r.name.endsWith(".json")?await e(new fe((0,Ie.resolve)(r.parentPath,r.name))):r.isDirectory()&&await Fe((0,Ie.resolve)(r.parentPath,r.name),e)}function nt(t){let e=t.vulnerability.name;return new Set([e,...t.vulnerability.aliases??[]])}async function ot({workingDir:t,existingPurl:e,newPurl:r}){let n=await new V(t).loadProjectConfig();await Fe(n.vexDir,async i=>{await i.read(),i.addProductId(e,r)&&(console.info(`Add ${r} to ${i.location}`),await i.write())})}async function st({workingDir:t,projectName:e,referenceProjectVersion:r,targetProjectVersion:n}){let i=await new V(t).loadProjectConfig();if(!i.projectConfigFileLocation)throw new Error("Missing project configuration file.");let s=i.projects.find(a=>a.name===e&&a.version===r);if(!s)throw new Error(`Project ${e} with version ${r} not found.`);let o=i.projects.find(a=>a.name===e&&a.version===n);o||(o=await ur(e,i.projectConfigFileLocation,s,n)),await ot({workingDir:t,existingPurl:s.purl,newPurl:o.purl})}async function ur(t,e,r,n){let i=new ue(e),o=(await i.readRawConfig()).projects.find(c=>c.name===r.name&&c.version===r.version),a={...o};return a.version=n,a.purl=o.purl.replace(o.version,n),"sbomMavenCoordinates"in a?a.sbomMavenCoordinates=o.sbomMavenCoordinates.replace(o.version,n):"sbomFile"in a&&(a.sbomFile=o.sbomFile.replace(o.version,n)),console.info(`Add project ${t} with version ${n} to ${e}`),await i.insertAfter(r,a),a}var fr=["emacs","vim"],dr=new Set(fr);function pr(t){return dr.has(t)}function at(){let t=process.env.INQUIRER_KEYBINDINGS;return t?Array.from(new Set(t.toLowerCase().split(/[\s,]+/).filter(pr))):[]}var ne=(t,e=[])=>t.name==="up"||e.includes("vim")&&t.name==="k"||e.includes("emacs")&&t.ctrl&&t.name==="p",me=(t,e=[])=>t.name==="down"||e.includes("vim")&&t.name==="j"||e.includes("emacs")&&t.ctrl&&t.name==="n";var ie=t=>t.name==="backspace",oe=t=>t.name==="tab",Ce=t=>"1234567890".includes(t.name),M=t=>t.name==="enter"||t.name==="return";var he=class extends Error{name="AbortPromptError";message="Prompt was aborted";constructor(e){super(),this.cause=e?.cause}},ge=class extends Error{name="CancelPromptError";message="Prompt was canceled"},se=class extends Error{name="ExitPromptError"},we=class extends Error{name="HookError"},Y=class extends Error{name="ValidationError"};var ft=require("node:async_hooks");var Se=require("node:async_hooks");var lt=new Se.AsyncLocalStorage;function mr(t){return{rl:t,hooks:[],hooksCleanup:[],hooksEffect:[],index:0,handleChange(){}}}function ct(t,e){let r=mr(t);return lt.run(r,()=>{function n(i){r.handleChange=()=>{r.index=0,i()},r.handleChange()}return e(n)})}function $(){let t=lt.getStore();if(!t)throw new we("[Inquirer] Hook functions can only be called from within a prompt");return t}function Te(){return $().rl}function Be(t){let e=(...r)=>{let n=$(),i=!1,s=n.handleChange;n.handleChange=()=>{i=!0};let o=t(...r);return i&&s(),n.handleChange=s,o};return Se.AsyncResource.bind(e)}function Q(t){let e=$(),{index:r}=e,n={get(){return e.hooks[r]},set(s){e.hooks[r]=s},initialized:r in e.hooks},i=t(n);return e.index++,i}function ut(){$().handleChange()}var W={queue(t){let e=$(),{index:r}=e;e.hooksEffect.push(()=>{e.hooksCleanup[r]?.();let n=t(Te());if(n!=null&&typeof n!="function")throw new Y("useEffect return value must be a cleanup function or nothing.");e.hooksCleanup[r]=n})},run(){let t=$();Be(()=>{t.hooksEffect.forEach(e=>{e()}),t.hooksEffect.length=0})()},clearAll(){let t=$();t.hooksCleanup.forEach(e=>{e?.()}),t.hooksEffect.length=0,t.hooksCleanup.length=0}};function hr(t){return typeof t=="function"}function D(t){return Q(e=>{let r=ft.AsyncResource.bind(function(s){e.get()!==s&&(e.set(s),ut())});if(e.initialized)return[e.get(),r];let n=hr(t)?t():t;return e.set(n),[n,r]})}function _(t,e){Q(r=>{let n=r.get();(!Array.isArray(n)||e.some((s,o)=>!Object.is(s,n[o])))&&W.queue(t),r.set(e)})}var T=require("node:util");var C=k(require("node:process"),1);function gr(){return C.default.platform.startsWith("win")?!!C.default.env.CI||!!C.default.env.WT_SESSION||!!C.default.env.TERMINUS_SUBLIME||C.default.env.ConEmuTask==="{cmd::Cmder}"||C.default.env.TERM_PROGRAM==="Terminus-Sublime"||C.default.env.TERM_PROGRAM==="vscode"||C.default.env.TERM==="xterm-256color"||C.default.env.TERM==="alacritty"||C.default.env.TERMINAL_EMULATOR==="JetBrains-JediTerm":C.default.env.TERM!=="linux"}var dt={circleQuestionMark:"(?)",questionMarkPrefix:"(?)",square:"\u2588",squareDarkShade:"\u2593",squareMediumShade:"\u2592",squareLightShade:"\u2591",squareTop:"\u2580",squareBottom:"\u2584",squareLeft:"\u258C",squareRight:"\u2590",squareCenter:"\u25A0",bullet:"\u25CF",dot:"\u2024",ellipsis:"\u2026",pointerSmall:"\u203A",triangleUp:"\u25B2",triangleUpSmall:"\u25B4",triangleDown:"\u25BC",triangleDownSmall:"\u25BE",triangleLeftSmall:"\u25C2",triangleRightSmall:"\u25B8",home:"\u2302",heart:"\u2665",musicNote:"\u266A",musicNoteBeamed:"\u266B",arrowUp:"\u2191",arrowDown:"\u2193",arrowLeft:"\u2190",arrowRight:"\u2192",arrowLeftRight:"\u2194",arrowUpDown:"\u2195",almostEqual:"\u2248",notEqual:"\u2260",lessOrEqual:"\u2264",greaterOrEqual:"\u2265",identical:"\u2261",infinity:"\u221E",subscriptZero:"\u2080",subscriptOne:"\u2081",subscriptTwo:"\u2082",subscriptThree:"\u2083",subscriptFour:"\u2084",subscriptFive:"\u2085",subscriptSix:"\u2086",subscriptSeven:"\u2087",subscriptEight:"\u2088",subscriptNine:"\u2089",oneHalf:"\xBD",oneThird:"\u2153",oneQuarter:"\xBC",oneFifth:"\u2155",oneSixth:"\u2159",oneEighth:"\u215B",twoThirds:"\u2154",twoFifths:"\u2156",threeQuarters:"\xBE",threeFifths:"\u2157",threeEighths:"\u215C",fourFifths:"\u2158",fiveSixths:"\u215A",fiveEighths:"\u215D",sevenEighths:"\u215E",line:"\u2500",lineBold:"\u2501",lineDouble:"\u2550",lineDashed0:"\u2504",lineDashed1:"\u2505",lineDashed2:"\u2508",lineDashed3:"\u2509",lineDashed4:"\u254C",lineDashed5:"\u254D",lineDashed6:"\u2574",lineDashed7:"\u2576",lineDashed8:"\u2578",lineDashed9:"\u257A",lineDashed10:"\u257C",lineDashed11:"\u257E",lineDashed12:"\u2212",lineDashed13:"\u2013",lineDashed14:"\u2010",lineDashed15:"\u2043",lineVertical:"\u2502",lineVerticalBold:"\u2503",lineVerticalDouble:"\u2551",lineVerticalDashed0:"\u2506",lineVerticalDashed1:"\u2507",lineVerticalDashed2:"\u250A",lineVerticalDashed3:"\u250B",lineVerticalDashed4:"\u254E",lineVerticalDashed5:"\u254F",lineVerticalDashed6:"\u2575",lineVerticalDashed7:"\u2577",lineVerticalDashed8:"\u2579",lineVerticalDashed9:"\u257B",lineVerticalDashed10:"\u257D",lineVerticalDashed11:"\u257F",lineDownLeft:"\u2510",lineDownLeftArc:"\u256E",lineDownBoldLeftBold:"\u2513",lineDownBoldLeft:"\u2512",lineDownLeftBold:"\u2511",lineDownDoubleLeftDouble:"\u2557",lineDownDoubleLeft:"\u2556",lineDownLeftDouble:"\u2555",lineDownRight:"\u250C",lineDownRightArc:"\u256D",lineDownBoldRightBold:"\u250F",lineDownBoldRight:"\u250E",lineDownRightBold:"\u250D",lineDownDoubleRightDouble:"\u2554",lineDownDoubleRight:"\u2553",lineDownRightDouble:"\u2552",lineUpLeft:"\u2518",lineUpLeftArc:"\u256F",lineUpBoldLeftBold:"\u251B",lineUpBoldLeft:"\u251A",lineUpLeftBold:"\u2519",lineUpDoubleLeftDouble:"\u255D",lineUpDoubleLeft:"\u255C",lineUpLeftDouble:"\u255B",lineUpRight:"\u2514",lineUpRightArc:"\u2570",lineUpBoldRightBold:"\u2517",lineUpBoldRight:"\u2516",lineUpRightBold:"\u2515",lineUpDoubleRightDouble:"\u255A",lineUpDoubleRight:"\u2559",lineUpRightDouble:"\u2558",lineUpDownLeft:"\u2524",lineUpBoldDownBoldLeftBold:"\u252B",lineUpBoldDownBoldLeft:"\u2528",lineUpDownLeftBold:"\u2525",lineUpBoldDownLeftBold:"\u2529",lineUpDownBoldLeftBold:"\u252A",lineUpDownBoldLeft:"\u2527",lineUpBoldDownLeft:"\u2526",lineUpDoubleDownDoubleLeftDouble:"\u2563",lineUpDoubleDownDoubleLeft:"\u2562",lineUpDownLeftDouble:"\u2561",lineUpDownRight:"\u251C",lineUpBoldDownBoldRightBold:"\u2523",lineUpBoldDownBoldRight:"\u2520",lineUpDownRightBold:"\u251D",lineUpBoldDownRightBold:"\u2521",lineUpDownBoldRightBold:"\u2522",lineUpDownBoldRight:"\u251F",lineUpBoldDownRight:"\u251E",lineUpDoubleDownDoubleRightDouble:"\u2560",lineUpDoubleDownDoubleRight:"\u255F",lineUpDownRightDouble:"\u255E",lineDownLeftRight:"\u252C",lineDownBoldLeftBoldRightBold:"\u2533",lineDownLeftBoldRightBold:"\u252F",lineDownBoldLeftRight:"\u2530",lineDownBoldLeftBoldRight:"\u2531",lineDownBoldLeftRightBold:"\u2532",lineDownLeftRightBold:"\u252E",lineDownLeftBoldRight:"\u252D",lineDownDoubleLeftDoubleRightDouble:"\u2566",lineDownDoubleLeftRight:"\u2565",lineDownLeftDoubleRightDouble:"\u2564",lineUpLeftRight:"\u2534",lineUpBoldLeftBoldRightBold:"\u253B",lineUpLeftBoldRightBold:"\u2537",lineUpBoldLeftRight:"\u2538",lineUpBoldLeftBoldRight:"\u2539",lineUpBoldLeftRightBold:"\u253A",lineUpLeftRightBold:"\u2536",lineUpLeftBoldRight:"\u2535",lineUpDoubleLeftDoubleRightDouble:"\u2569",lineUpDoubleLeftRight:"\u2568",lineUpLeftDoubleRightDouble:"\u2567",lineUpDownLeftRight:"\u253C",lineUpBoldDownBoldLeftBoldRightBold:"\u254B",lineUpDownBoldLeftBoldRightBold:"\u2548",lineUpBoldDownLeftBoldRightBold:"\u2547",lineUpBoldDownBoldLeftRightBold:"\u254A",lineUpBoldDownBoldLeftBoldRight:"\u2549",lineUpBoldDownLeftRight:"\u2540",lineUpDownBoldLeftRight:"\u2541",lineUpDownLeftBoldRight:"\u253D",lineUpDownLeftRightBold:"\u253E",lineUpBoldDownBoldLeftRight:"\u2542",lineUpDownLeftBoldRightBold:"\u253F",lineUpBoldDownLeftBoldRight:"\u2543",lineUpBoldDownLeftRightBold:"\u2544",lineUpDownBoldLeftBoldRight:"\u2545",lineUpDownBoldLeftRightBold:"\u2546",lineUpDoubleDownDoubleLeftDoubleRightDouble:"\u256C",lineUpDoubleDownDoubleLeftRight:"\u256B",lineUpDownLeftDoubleRightDouble:"\u256A",lineCross:"\u2573",lineBackslash:"\u2572",lineSlash:"\u2571"},pt={tick:"\u2714",info:"\u2139",warning:"\u26A0",cross:"\u2718",squareSmall:"\u25FB",squareSmallFilled:"\u25FC",circle:"\u25EF",circleFilled:"\u25C9",circleDotted:"\u25CC",circleDouble:"\u25CE",circleCircle:"\u24DE",circleCross:"\u24E7",circlePipe:"\u24BE",radioOn:"\u25C9",radioOff:"\u25EF",checkboxOn:"\u2612",checkboxOff:"\u2610",checkboxCircleOn:"\u24E7",checkboxCircleOff:"\u24BE",pointer:"\u276F",triangleUpOutline:"\u25B3",triangleLeft:"\u25C0",triangleRight:"\u25B6",lozenge:"\u25C6",lozengeOutline:"\u25C7",hamburger:"\u2630",smiley:"\u32E1",mustache:"\u0DF4",star:"\u2605",play:"\u25B6",nodejs:"\u2B22",oneSeventh:"\u2150",oneNinth:"\u2151",oneTenth:"\u2152"},wr={tick:"\u221A",info:"i",warning:"\u203C",cross:"\xD7",squareSmall:"\u25A1",squareSmallFilled:"\u25A0",circle:"( )",circleFilled:"(*)",circleDotted:"( )",circleDouble:"( )",circleCircle:"(\u25CB)",circleCross:"(\xD7)",circlePipe:"(\u2502)",radioOn:"(*)",radioOff:"( )",checkboxOn:"[\xD7]",checkboxOff:"[ ]",checkboxCircleOn:"(\xD7)",checkboxCircleOff:"( )",pointer:">",triangleUpOutline:"\u2206",triangleLeft:"\u25C4",triangleRight:"\u25BA",lozenge:"\u2666",lozengeOutline:"\u25CA",hamburger:"\u2261",smiley:"\u263A",mustache:"\u250C\u2500\u2510",star:"\u2736",play:"\u25BA",nodejs:"\u2666",oneSeventh:"1/7",oneNinth:"1/9",oneTenth:"1/10"},Sr={...dt,...pt},xr={...dt,...wr},yr=gr(),br=yr?Sr:xr,Z=br,_n=Object.entries(pt);var vr={prefix:{idle:(0,T.styleText)("blue","?"),done:(0,T.styleText)("green",Z.tick)},spinner:{interval:80,frames:["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"].map(t=>(0,T.styleText)("yellow",t))},keybindings:[],style:{answer:t=>(0,T.styleText)("cyan",t),message:t=>(0,T.styleText)("bold",t),error:t=>(0,T.styleText)("red",`> ${t}`),defaultAnswer:t=>(0,T.styleText)("dim",`(${t})`),help:t=>(0,T.styleText)("dim",t),highlight:t=>(0,T.styleText)("cyan",t),key:t=>(0,T.styleText)("cyan",(0,T.styleText)("bold",`<${t}>`))}};function mt(){return{...vr,keybindings:at()}}function ht(t){if(typeof t!="object"||t===null)return!1;let e=t;for(;Object.getPrototypeOf(e)!==null;)e=Object.getPrototypeOf(e);return Object.getPrototypeOf(t)===e}function gt(...t){let e={};for(let r of t)for(let[n,i]of Object.entries(r)){let s=e[n];e[n]=ht(s)&&ht(i)?gt(s,i):i}return e}function N(...t){let e=[mt(),...t.filter(r=>r!=null)];return gt(...e)}function K({status:t="idle",theme:e}){let[r,n]=D(!1),[i,s]=D(0),{prefix:o,spinner:a}=N(e);return _(()=>{if(t==="loading"){let u,f=-1,l=setTimeout(()=>{n(!0),u=setInterval(()=>{f=f+1,s(f%a.frames.length)},a.interval)},300);return()=>{clearTimeout(l),clearInterval(u)}}else n(!1)},[t]),r?a.frames[i]:typeof o=="string"?o:o[t==="loading"?"idle":t]??o.idle}function ae(t,e){return Q(r=>{let n=r.get();if(!n||n.dependencies.length!==e.length||n.dependencies.some((i,s)=>i!==e[s])){let i=t();return r.set({value:i,dependencies:e}),i}return n.value})}function H(t){return D({current:t})[0]}function G(t){let e=H(t);e.current=t,_(r=>{let n=!1,i=Be((s,o)=>{n||e.current(o,r)});return r.input.on("keypress",i),()=>{n=!0,r.input.removeListener("keypress",i)}},[])}var Ut=k(St(),1);var xt=(()=>{let t=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g;return e=>{let r=0;for(t.lastIndex=0;t.test(e);)r+=1;return e.length-r}})(),yt=t=>t===12288||t>=65281&&t<=65376||t>=65504&&t<=65510,bt=t=>t===8987||t===9001||t>=12272&&t<=12287||t>=12289&&t<=12350||t>=12441&&t<=12543||t>=12549&&t<=12591||t>=12593&&t<=12686||t>=12688&&t<=12771||t>=12783&&t<=12830||t>=12832&&t<=12871||t>=12880&&t<=19903||t>=65040&&t<=65049||t>=65072&&t<=65106||t>=65108&&t<=65126||t>=65128&&t<=65131||t>=127488&&t<=127490||t>=127504&&t<=127547||t>=127552&&t<=127560||t>=131072&&t<=196605||t>=196608&&t<=262141;var Pr=/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]|\u001b\]8;[^;]*;.*?(?:\u0007|\u001b\u005c)/y,Lr=/[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y,vt=/(?:(?![\uFF61-\uFF9F\uFF00-\uFFEF])[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}\p{Script=Tangut}]){1,1000}/yu,Rr=/\t{1,1000}/y,Et=new RegExp("[\\u{1F1E6}-\\u{1F1FF}]{2}|\\u{1F3F4}[\\u{E0061}-\\u{E007A}]{2}[\\u{E0030}-\\u{E0039}\\u{E0061}-\\u{E007A}]{1,3}\\u{E007F}|(?:\\p{Emoji}\\uFE0F\\u20E3?|\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|\\p{Emoji_Presentation})(?:\\u200D(?:\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|\\p{Emoji_Presentation}|\\p{Emoji}\\uFE0F\\u20E3?))*","yu"),Ir=/(?:[\x20-\x7E\xA0-\xFF](?!\uFE0F)){1,1000}/y,Fr=new RegExp("\\p{M}+","gu"),Cr={limit:1/0,ellipsis:""},Dt=(t,e={},r={})=>{let n=e.limit??1/0,i=e.ellipsis??"",s=e?.ellipsisWidth??(i?Dt(i,Cr,r).width:0),o=0,a=r.controlWidth??0,c=r.tabWidth??8,u=r.emojiWidth??2,f=2,l=r.regularWidth??1,p=r.wideWidth??f,S=[[Ir,l],[Pr,o],[Lr,a],[Rr,c],[Et,u],[vt,p]],h=0,d=0,m=t.length,x=0,g=!1,y=m,b=Math.max(0,n-s),P=0,L=0,I=0,F=0;e:for(;;){if(L>P||d>=m&&d>h){let w=t.slice(P,L)||t.slice(h,d);x=0;for(let v of w.replaceAll(Fr,"")){let E=v.codePointAt(0)||0;if(yt(E)?F=f:bt(E)?F=p:F=l,I+F>b&&(y=Math.min(y,Math.max(P,h)+x)),I+F>n){g=!0;break e}x+=v.length,I+=F}P=L=0}if(d>=m)break e;for(let w=0,v=S.length;w<v;w++){let[E,R]=S[w];if(E.lastIndex=d,E.test(t)){if(x=E===vt?xt(t.slice(d,E.lastIndex)):E===Et?1:E.lastIndex-d,F=x*R,I+F>b&&(y=Math.min(y,d+Math.floor((b-I)/R))),I+F>n){g=!0;break e}I+=F,P=h,L=d,d=h=E.lastIndex;continue e}}d+=1}return{width:g?b:I,index:g?y:m,truncated:g,ellipsed:g&&n>=s}},Pt=Dt;var Tr={limit:1/0,ellipsis:"",ellipsisWidth:0},Br=(t,e={})=>Pt(t,Tr,e).width,A=Br;var xe="\x1B",Ct="\x9B",jr=39,Ue="\x07",Tt="[",Ur="]",Bt="m",_e=`${Ur}8;;`,Lt=new RegExp(`(?:\\${Tt}(?<code>\\d+)m|\\${_e}(?<uri>.*)${Ue})`,"y"),Rt=t=>{if(t>=30&&t<=37||t>=90&&t<=97)return 39;if(t>=40&&t<=47||t>=100&&t<=107)return 49;if(t===1||t===2)return 22;if(t===3)return 23;if(t===4)return 24;if(t===7)return 27;if(t===8)return 28;if(t===9)return 29;if(t===0)return 0},It=t=>`${xe}${Tt}${t}${Bt}`,Ft=t=>`${xe}${_e}${t}${Ue}`,je=(t,e,r)=>{let n=e[Symbol.iterator](),i=!1,s=!1,o=t.at(-1),a=o===void 0?0:A(o),c=n.next(),u=n.next(),f=0;for(;!c.done;){let l=c.value,p=A(l);a+p<=r?t[t.length-1]+=l:(t.push(l),a=0),(l===xe||l===Ct)&&(i=!0,s=e.startsWith(_e,f+1)),i?s?l===Ue&&(i=!1,s=!1):l===Bt&&(i=!1):(a+=p,a===r&&!u.done&&(t.push(""),a=0)),c=u,u=n.next(),f+=l.length}o=t.at(-1),!a&&o!==void 0&&o.length&&t.length>1&&(t[t.length-2]+=t.pop())},_r=t=>{let e=t.split(" "),r=e.length;for(;r&&!A(e[r-1]);)r--;return r===e.length?t:e.slice(0,r).join(" ")+e.slice(r).join("")},Nr=(t,e,r={})=>{if(r.trim!==!1&&t.trim()==="")return"";let n="",i,s,o=t.split(" "),a=[""],c=0;for(let l=0;l<o.length;l++){let p=o[l];if(r.trim!==!1){let h=a.at(-1)??"",d=h.trimStart();h.length!==d.length&&(a[a.length-1]=d,c=A(d))}l!==0&&(c>=e&&(r.wordWrap===!1||r.trim===!1)&&(a.push(""),c=0),(c||r.trim===!1)&&(a[a.length-1]+=" ",c++));let S=A(p);if(r.hard&&S>e){let h=e-c,d=1+Math.floor((S-h-1)/e);Math.floor((S-1)/e)<d&&a.push(""),je(a,p,e),c=A(a.at(-1)??"");continue}if(c+S>e&&c&&S){if(r.wordWrap===!1&&c<e){je(a,p,e),c=A(a.at(-1)??"");continue}a.push(""),c=0}if(c+S>e&&r.wordWrap===!1){je(a,p,e),c=A(a.at(-1)??"");continue}a[a.length-1]+=p,c+=S}r.trim!==!1&&(a=a.map(l=>_r(l)));let u=a.join(`
4
- `),f=!1;for(let l=0;l<u.length;l++){let p=u[l];if(n+=p,f)f=!1;else if(f=p>="\uD800"&&p<="\uDBFF",f)continue;if(p===xe||p===Ct){Lt.lastIndex=l+1;let h=Lt.exec(u)?.groups;if(h?.code!==void 0){let d=Number.parseFloat(h.code);i=d===jr?void 0:d}else h?.uri!==void 0&&(s=h.uri.length===0?void 0:h.uri)}if(u[l+1]===`
5
- `){s&&(n+=Ft(""));let S=i?Rt(i):void 0;i&&S&&(n+=It(S))}else p===`
6
- `&&(i&&Rt(i)&&(n+=It(i)),s&&(n+=Ft(s)))}return n},Ar=/\r?\n/;function jt(t,e,r){return String(t).normalize().split(Ar).map(n=>Nr(n,e,r)).join(`
2
+ "use strict";var tr=Object.create;var Ze=Object.defineProperty;var rr=Object.getOwnPropertyDescriptor;var nr=Object.getOwnPropertyNames;var ir=Object.getPrototypeOf,or=Object.prototype.hasOwnProperty;var et=(t,e)=>()=>{try{return e||t((e={exports:{}}).exports,e),e.exports}catch(r){throw e=0,r}};var sr=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of nr(e))!or.call(t,i)&&i!==r&&Ze(t,i,{get:()=>e[i],enumerable:!(n=rr(e,i))||n.enumerable});return t};var $=(t,e,r)=>(r=t!=null?tr(ir(t)):{},sr(e||!t||!t.__esModule?Ze(r,"default",{value:t,enumerable:!0}):r,t));var yt=et((ni,xt)=>{"use strict";xt.exports=Rr;function jr(t){let e={defaultWidth:0,output:process.stdout,tty:require("tty")};return t?(Object.keys(e).forEach(function(r){t[r]||(t[r]=e[r])}),t):e}function Rr(t){let e=jr(t);if(e.output.getWindowSize)return e.output.getWindowSize()[0]||e.defaultWidth;if(e.tty.getWindowSize)return e.tty.getWindowSize()[1]||e.defaultWidth;if(e.output.columns)return e.output.columns;if(process.env.CLI_WIDTH){let r=parseInt(process.env.CLI_WIDTH,10);if(!isNaN(r)&&r!==0)return r}return e.defaultWidth}});var Nt=et((wi,Ot)=>{var Wr=require("stream"),Ne=class extends Wr{#r=null;constructor(e={}){super(e),this.writable=this.readable=!0,this.muted=!1,this.on("pipe",this._onpipe),this.replace=e.replace,this._prompt=e.prompt||null,this._hadControl=!1}#t(e,r){return this._dest?this._dest[e]:this._src?this._src[e]:r}#e(e,...r){typeof this._dest?.[e]=="function"&&this._dest[e](...r),typeof this._src?.[e]=="function"&&this._src[e](...r)}get isTTY(){return this.#r!==null?this.#r:this.#t("isTTY",!1)}set isTTY(e){this.#r=e}get rows(){return this.#t("rows")}get columns(){return this.#t("columns")}mute(){this.muted=!0}unmute(){this.muted=!1}_onpipe(e){this._src=e}pipe(e,r){return this._dest=e,super.pipe(e,r)}pause(){if(this._src)return this._src.pause()}resume(){if(this._src)return this._src.resume()}write(e){if(this.muted){if(!this.replace)return!0;if(e.match(/^\u001b/))return e.indexOf(this._prompt)===0&&(e=e.slice(this._prompt.length),e=e.replace(/./g,this.replace),e=this._prompt+e),this._hadControl=!0,this.emit("data",e);this._prompt&&this._hadControl&&e.indexOf(this._prompt)===0&&(this._hadControl=!1,this.emit("data",this._prompt),e=e.slice(this._prompt.length)),e=e.toString().replace(/./g,this.replace)}this.emit("data",e)}end(e){this.muted&&(e&&this.replace?e=e.toString().replace(/./g,this.replace):e=null),e&&this.emit("data",e),this.emit("end")}destroy(...e){return this.#e("destroy",...e)}destroySoon(...e){return this.#e("destroySoon",...e)}close(...e){return this.#e("close",...e)}};Ot.exports=Ne});var V=$(require("path")),je=require("fs/promises");var T=require("fs/promises");async function z(t){try{return await ar(t)?JSON.parse(await(0,T.readFile)(t,{encoding:"utf-8"})):void 0}catch(e){throw new Error(`Error reading JSON file ${t}: ${e}`,{cause:e})}}async function re(t,e){let r=JSON.stringify(e,null,4)+`
3
+ `,n=await lr(t,r);await(0,T.writeFile)(t,n,{encoding:"utf-8"})}async function ar(t){try{return await(0,T.access)(t,T.constants.F_OK),!0}catch{return!1}}async function lr(t,e){let r=await ur();if(!r)return e;let n=await r.resolveConfig(t);return n?await r.format(e,{...n,filepath:t}):e}var cr;function ur(){return cr??=import("prettier").catch(()=>{})}var U=["UNKNOWN","LOW","MEDIUM","HIGH","CRITICAL"];var Re=class t{constructor(e){this.workingDir=e}workingDir;static DEFAULT_MAVEN_REPO="https://repository.conterra.de/repository/maven-mirror-ct";static DEFAULT_VEX_SUBDIR="input/vex";static DEFAULT_OUT_SUBDIR="output";static DEFAULT_CACHE_SUBDIR="cache";static DEFAULT_SCANNERS=["grype","trivy","ossindex"];normalize(e,r){let n=e.findNoLongerDetectedVulnerabilitiesOnlyForSnapshots??!1;return{projectConfigFileLocation:r,onNewVulnerabilities:e.onNewVulnerabilities??(e.failOnNewVulnerabilities?"fail":"warn"),onNoLongerDetectedVulnerabilities:e.onNoLongerDetectedVulnerabilities??"ignore",reportNoLongerDetectedVulnerabilities:e.reportNoLongerDetectedVulnerabilities??!0,consoleReport:e.consoleReport??"BY_PROJECT_DETAILED",createSubDirsForProject:e.createSubDirsForProject??!0,mavenRepo:e.mavenRepo??t.DEFAULT_MAVEN_REPO,vexUrls:e.vexUrls??[],vexDir:this.resolvePath(e.vexDir)??(0,V.resolve)(this.workingDir,t.DEFAULT_VEX_SUBDIR),outDir:this.resolvePath(e.outDir)??(0,V.resolve)(this.workingDir,t.DEFAULT_OUT_SUBDIR),cacheDir:this.resolvePath(e.cacheDir)??(0,V.resolve)(this.workingDir,t.DEFAULT_CACHE_SUBDIR),scanners:this.normalizeScanners(e.scanners,r),projects:this.normalizeProjects(e.projects??[],n)}}normalizeScanners(e,r){return(e??t.DEFAULT_SCANNERS).map(i=>{if(typeof i!="string")throw new Error(`Invalid scanner name '${String(i)}' in configuration file '${r}'`);let o=i.split("@");if(o.length>2)throw new Error(`Invalid scanner name '${i}' in configuration file '${r}'`);return{name:o[0],version:o[1]??""}})}normalizeProjects(e,r){return e.map(n=>{let i=n;if(!i.name)throw new Error("Project name is missing on entry: "+JSON.stringify(i));if(!i.version)throw new Error("Project version is missing on entry: "+JSON.stringify(i));if(!i.purl)throw new Error("Project purl is missing on entry: "+JSON.stringify(i));let o={...i,purlAliases:i.purlAliases??[],enabled:i.enabled??!0,silent:i.silent??!1,minimumSeverity:i.minimumSeverity??"UNKNOWN"};return o.sbomFile?{...o,sbomFile:this.resolvePath(o.sbomFile)??o.sbomFile}:{...o,detectNoLongerUsedVulnerabilities:r?o.purl.endsWith("-SNAPSHOT"):!0}})}resolvePath(e){if(e)return V.default.isAbsolute(e)?e:(0,V.resolve)(this.workingDir,e)}},k=class{constructor(e){this.workingDir=e;this.normalizer=new Re(e)}workingDir;normalizer;projectConfigCache;async loadProjectConfig(){return this.projectConfigCache??=this.doLoadProjectConfig(),this.projectConfigCache}async doLoadProjectConfig(){let e=(0,V.resolve)(this.workingDir,"vuln-scan-conf.json"),r=await z(e);if(!r)throw new Error(`Missing project configuration file '${e}'`);return this.normalizer.normalize(r,e)}async loadJiraConfig(e){let r=await(0,je.readFile)(e,"utf8"),n=JSON.parse(r);if(!n.issues&&n.issue&&(n.issues=n.issue),!n.jiraUrl||typeof n.jiraUrl!="string")throw new Error("jira-conf.json: missing or invalid 'jiraUrl' field");if(!Array.isArray(n.issues))throw new Error("jira-conf.json: missing or invalid 'issues' array");this.validateAutoCloseSeverity(n.autoCloseBelowSeverity,"jira-conf.json: invalid 'autoCloseBelowSeverity'");for(let[i,o]of n.issues.entries())if(o&&typeof o=="object"){let s=o;this.validateAutoCloseSeverity(s.autoCloseBelowSeverity,`jira-conf.json: invalid 'issues[${i}].autoCloseBelowSeverity'`),this.validateAutoCloseProjectOverrides(s.projectOverrides,`jira-conf.json: invalid 'issues[${i}].projectOverrides'`)}return n}validateAutoCloseSeverity(e,r){if(e!==void 0&&!U.includes(e))throw new Error(`${r} value '${String(e)}'. Must be one of: ${U.join(", ")}`)}validateAutoCloseProjectOverrides(e,r){if(e!==void 0){if(!Array.isArray(e))throw new Error(`${r}: must be an array`);for(let n=0;n<e.length;n++){let i=e[n],o=`${r}[${n}]`;if(i==null||typeof i!="object")throw new Error(`${o}: must be an object`);let s=i,a=s.projects;if(!Array.isArray(a)||a.length===0)throw new Error(`${o}.projects: must be a non-empty array of strings`);for(let c=0;c<a.length;c++){let u=a[c];if(typeof u!="string"||u.length===0)throw new Error(`${o}.projects[${c}]: must be a non-empty string`)}if(s.autoCloseBelowSeverity===void 0)throw new Error(`${o}.autoCloseBelowSeverity: is required`);if(this.validateAutoCloseSeverity(s.autoCloseBelowSeverity,`${o}.autoCloseBelowSeverity`),s.comment!==void 0&&typeof s.comment!="string")throw new Error(`${o}.comment: must be a string`)}}}async loadAutoVexConfig(e){let r=await(0,je.readFile)(e,"utf8"),n=JSON.parse(r);if(!n.impactStatement||typeof n.impactStatement!="string")throw new Error("auto-vex-conf.json: missing or invalid 'impactStatement' field (must be a non-empty string)");if(n.maxSeverity!==void 0&&!U.includes(n.maxSeverity))throw new Error(`auto-vex-conf.json: invalid 'maxSeverity' value '${String(n.maxSeverity)}'. Must be one of: ${U.join(", ")}`);if(n.projectOverrides!==void 0){if(!Array.isArray(n.projectOverrides))throw new Error("auto-vex-conf.json: 'projectOverrides' must be an array");for(let[i,o]of n.projectOverrides.entries()){if(!o||typeof o!="object")throw new Error(`auto-vex-conf.json: 'projectOverrides[${i}]' must be an object`);let s=o;if(!Array.isArray(s.projects)||s.projects.length===0||!s.projects.every(a=>typeof a=="string"&&a.length>0))throw new Error(`auto-vex-conf.json: 'projectOverrides[${i}].projects' must be a non-empty array of non-empty strings`);if(!U.includes(s.maxSeverity))throw new Error(`auto-vex-conf.json: invalid 'projectOverrides[${i}].maxSeverity' value '${String(s.maxSeverity)}'. Must be one of: ${U.join(", ")}`)}}return n}};var ue=class{constructor(e){this.configFilePath=e}configFilePath;async readRawConfig(){let e=await z(this.configFilePath);if(!e)throw new Error(`Missing project configuration file '${this.configFilePath}'`);return e}async insertAfter(e,r){let n=await this.readRawConfig(),i=n.projects??[],o=i.findIndex(s=>s.name===e.name&&s.version===e.version);if(o===-1)throw new Error(`Reference project ${e.name}@${e.version} not found in config`);i.splice(o+1,0,r),n.projects=i,await re(this.configFilePath,n)}async remove(e,r){let n=await this.readRawConfig(),i=n.projects??[],o=i.findIndex(s=>s.name===e&&s.version===r);return o===-1?!1:(i.splice(o,1),n.projects=i,await re(this.configFilePath,n),!0)}};var st=require("fs/promises"),Ie=require("path");var rt=require("crypto");var tt="auto_vex_max_severity=";function fe(t){let e=t.status_notes;if(!e||!e.startsWith(tt))return;let r=e.slice(tt.length).trim();return U.includes(r)?r:void 0}var fr="https://openvex.dev/ns/v0.2.0";function nt(t,e="conterra"){let n=`https://openvex.dev/docs/public/vex-${(0,rt.randomUUID)()}`,i=t.timestamp??new Date().toISOString();return{"@context":fr,"@id":n,author:e,timestamp:i,last_updated:i,version:1,statements:[t]}}function it(t,e){let r=e.timestamp??new Date().toISOString();return{...t,last_updated:r,version:t.version+1,statements:[...t.statements,e]}}var pe=require("fs/promises"),me=require("path");var de=class{constructor(e){this.location=e}location;_content=void 0;_exists=!1;get exists(){return this._exists}get content(){return this._content}set content(e){this._content=e,this._exists=e!==void 0}async read(){let e=await z(this.location);this._content=e??void 0,this._exists=this._content!==void 0}async write(){if(this._content===void 0)throw new Error(`Cannot write VexFile: content is undefined (${this.location})`);await(0,pe.mkdir)((0,me.dirname)((0,me.resolve)(this.location)),{recursive:!0}),await re(this.location,this._content)}async delete(){await(0,pe.unlink)(this.location),this._exists=!1}upsert(e,r){if(this._content===void 0)return this._content=nt(e,r),this._exists=!0,{created:!0,changed:!0};let n=fe(e);if(n!==void 0){let i=this._content.statements.findIndex(o=>o.vulnerability.name===e.vulnerability.name&&o.status===e.status&&fe(o)===n);if(i!==-1){let o=this._content.statements[i];return dr(o,e)?{created:!1,changed:!1}:(o.products=e.products,o.impact_statement=e.impact_statement,o.action_statement=e.action_statement,o.justification=e.justification,o.status_notes=e.status_notes,o.timestamp=e.timestamp,this._content.version+=1,this._content.last_updated=e.timestamp??new Date().toISOString(),{created:!1,changed:!0})}}return this._content=it(this._content,e),{created:!1,changed:!0}}addProductId(e,r){this.assertContentLoaded("addProductId");let n=!1;for(let i of this._content.statements){if(!i.products||i.products.some(s=>s["@id"]===r))continue;let o=i.products.findIndex(s=>s["@id"]===e);o!==-1&&(i.products.splice(o+1,0,{"@id":r}),n=!0)}return n}removeProductId(e,r){this.assertContentLoaded("removeProductId");let n=this._content.statements,i=[],o=!1;for(let s of n){if(r&&!ot(s).has(r)||!s.products)continue;let a=s.products.findIndex(c=>c["@id"]===e);a!==-1&&(s.products.splice(a,1),o=!0,s.products.length===0&&i.push(s))}if(!o)return"unchanged";for(let s of i)n.splice(n.indexOf(s),1);return n.length===0?"emptied":"changed"}hasStatementForProduct(e){return this.assertContentLoaded("hasStatementForProduct"),this._content.statements.some(r=>r.products?.some(n=>n["@id"]===e)??!1)}assertContentLoaded(e){if(this._content===void 0)throw new Error(`VexFile.${e}(): content is not loaded. Call read() first (${this.location})`)}};function dr(t,e){return t.impact_statement!==e.impact_statement||t.action_statement!==e.action_statement||t.justification!==e.justification||t.status_notes!==e.status_notes?!1:pr(t.products,e.products)}function pr(t,e){let r=o=>Array.from(new Set((o??[]).map(s=>s["@id"]).filter(s=>typeof s=="string"))).sort(),n=r(t),i=r(e);return n.length!==i.length?!1:n.every((o,s)=>o===i[s])}async function Ce(t,e){for(let r of await(0,st.readdir)(t,{withFileTypes:!0}))r.name.endsWith(".json")?await e(new de((0,Ie.resolve)(r.parentPath,r.name))):r.isDirectory()&&await Ce((0,Ie.resolve)(r.parentPath,r.name),e)}function ot(t){let e=t.vulnerability.name;return new Set([e,...t.vulnerability.aliases??[]])}async function at({workingDir:t,existingPurl:e,newPurl:r}){let n=await new k(t).loadProjectConfig();await Ce(n.vexDir,async i=>{await i.read(),i.addProductId(e,r)&&(console.info(`Add ${r} to ${i.location}`),await i.write())})}async function lt({workingDir:t,projectName:e,referenceProjectVersion:r,targetProjectVersion:n}){let i=await new k(t).loadProjectConfig();if(!i.projectConfigFileLocation)throw new Error("Missing project configuration file.");let o=i.projects.find(a=>a.name===e&&a.version===r);if(!o)throw new Error(`Project ${e} with version ${r} not found.`);let s=i.projects.find(a=>a.name===e&&a.version===n);s||(s=await mr(e,i.projectConfigFileLocation,o,n)),await at({workingDir:t,existingPurl:o.purl,newPurl:s.purl})}async function mr(t,e,r,n){let i=new ue(e),s=(await i.readRawConfig()).projects.find(c=>c.name===r.name&&c.version===r.version),a={...s};return a.version=n,a.purl=s.purl.replace(s.version,n),"sbomMavenCoordinates"in a?a.sbomMavenCoordinates=s.sbomMavenCoordinates.replace(s.version,n):"sbomFile"in a&&(a.sbomFile=s.sbomFile.replace(s.version,n)),console.info(`Add project ${t} with version ${n} to ${e}`),await i.insertAfter(r,a),a}var hr=["emacs","vim"],gr=new Set(hr);function wr(t){return gr.has(t)}function ct(){let t=process.env.INQUIRER_KEYBINDINGS;return t?Array.from(new Set(t.toLowerCase().split(/[\s,]+/).filter(wr))):[]}var ne=(t,e=[])=>t.name==="up"||e.includes("vim")&&t.name==="k"||e.includes("emacs")&&t.ctrl&&t.name==="p",he=(t,e=[])=>t.name==="down"||e.includes("vim")&&t.name==="j"||e.includes("emacs")&&t.ctrl&&t.name==="n";var ie=t=>t.name==="backspace",oe=t=>t.name==="tab",Fe=t=>"1234567890".includes(t.name),M=t=>t.name==="enter"||t.name==="return";var ge=class extends Error{name="AbortPromptError";message="Prompt was aborted";constructor(e){super(),this.cause=e?.cause}},we=class extends Error{name="CancelPromptError";message="Prompt was canceled"},se=class extends Error{name="ExitPromptError"},Se=class extends Error{name="HookError"},Y=class extends Error{name="ValidationError"};var pt=require("node:async_hooks");var xe=require("node:async_hooks");var ut=new xe.AsyncLocalStorage;function Sr(t){return{rl:t,hooks:[],hooksCleanup:[],hooksEffect:[],index:0,handleChange(){}}}function ft(t,e){let r=Sr(t);return ut.run(r,()=>{function n(i){r.handleChange=()=>{r.index=0,i()},r.handleChange()}return e(n)})}function W(){let t=ut.getStore();if(!t)throw new Se("[Inquirer] Hook functions can only be called from within a prompt");return t}function Te(){return W().rl}function _e(t){let e=(...r)=>{let n=W(),i=!1,o=n.handleChange;n.handleChange=()=>{i=!0};let s=t(...r);return i&&o(),n.handleChange=o,s};return xe.AsyncResource.bind(e)}function Q(t){let e=W(),{index:r}=e,n={get(){return e.hooks[r]},set(o){e.hooks[r]=o},initialized:r in e.hooks},i=t(n);return e.index++,i}function dt(){W().handleChange()}var K={queue(t){let e=W(),{index:r}=e;e.hooksEffect.push(()=>{e.hooksCleanup[r]?.();let n=t(Te());if(n!=null&&typeof n!="function")throw new Y("useEffect return value must be a cleanup function or nothing.");e.hooksCleanup[r]=n})},run(){let t=W();_e(()=>{t.hooksEffect.forEach(e=>{e()}),t.hooksEffect.length=0})()},clearAll(){let t=W();t.hooksCleanup.forEach(e=>{e?.()}),t.hooksEffect.length=0,t.hooksCleanup.length=0}};function xr(t){return typeof t=="function"}function D(t){return Q(e=>{let r=pt.AsyncResource.bind(function(o){e.get()!==o&&(e.set(o),dt())});if(e.initialized)return[e.get(),r];let n=xr(t)?t():t;return e.set(n),[n,r]})}function A(t,e){Q(r=>{let n=r.get();(!Array.isArray(n)||e.some((o,s)=>!Object.is(o,n[s])))&&K.queue(t),r.set(e)})}var F=require("node:util");var C=$(require("node:process"),1);function yr(){return C.default.platform.startsWith("win")?!!C.default.env.CI||!!C.default.env.WT_SESSION||!!C.default.env.TERMINUS_SUBLIME||C.default.env.ConEmuTask==="{cmd::Cmder}"||C.default.env.TERM_PROGRAM==="Terminus-Sublime"||C.default.env.TERM_PROGRAM==="vscode"||C.default.env.TERM==="xterm-256color"||C.default.env.TERM==="alacritty"||C.default.env.TERMINAL_EMULATOR==="JetBrains-JediTerm":C.default.env.TERM!=="linux"}var mt={circleQuestionMark:"(?)",questionMarkPrefix:"(?)",square:"\u2588",squareDarkShade:"\u2593",squareMediumShade:"\u2592",squareLightShade:"\u2591",squareTop:"\u2580",squareBottom:"\u2584",squareLeft:"\u258C",squareRight:"\u2590",squareCenter:"\u25A0",bullet:"\u25CF",dot:"\u2024",ellipsis:"\u2026",pointerSmall:"\u203A",triangleUp:"\u25B2",triangleUpSmall:"\u25B4",triangleDown:"\u25BC",triangleDownSmall:"\u25BE",triangleLeftSmall:"\u25C2",triangleRightSmall:"\u25B8",home:"\u2302",heart:"\u2665",musicNote:"\u266A",musicNoteBeamed:"\u266B",arrowUp:"\u2191",arrowDown:"\u2193",arrowLeft:"\u2190",arrowRight:"\u2192",arrowLeftRight:"\u2194",arrowUpDown:"\u2195",almostEqual:"\u2248",notEqual:"\u2260",lessOrEqual:"\u2264",greaterOrEqual:"\u2265",identical:"\u2261",infinity:"\u221E",subscriptZero:"\u2080",subscriptOne:"\u2081",subscriptTwo:"\u2082",subscriptThree:"\u2083",subscriptFour:"\u2084",subscriptFive:"\u2085",subscriptSix:"\u2086",subscriptSeven:"\u2087",subscriptEight:"\u2088",subscriptNine:"\u2089",oneHalf:"\xBD",oneThird:"\u2153",oneQuarter:"\xBC",oneFifth:"\u2155",oneSixth:"\u2159",oneEighth:"\u215B",twoThirds:"\u2154",twoFifths:"\u2156",threeQuarters:"\xBE",threeFifths:"\u2157",threeEighths:"\u215C",fourFifths:"\u2158",fiveSixths:"\u215A",fiveEighths:"\u215D",sevenEighths:"\u215E",line:"\u2500",lineBold:"\u2501",lineDouble:"\u2550",lineDashed0:"\u2504",lineDashed1:"\u2505",lineDashed2:"\u2508",lineDashed3:"\u2509",lineDashed4:"\u254C",lineDashed5:"\u254D",lineDashed6:"\u2574",lineDashed7:"\u2576",lineDashed8:"\u2578",lineDashed9:"\u257A",lineDashed10:"\u257C",lineDashed11:"\u257E",lineDashed12:"\u2212",lineDashed13:"\u2013",lineDashed14:"\u2010",lineDashed15:"\u2043",lineVertical:"\u2502",lineVerticalBold:"\u2503",lineVerticalDouble:"\u2551",lineVerticalDashed0:"\u2506",lineVerticalDashed1:"\u2507",lineVerticalDashed2:"\u250A",lineVerticalDashed3:"\u250B",lineVerticalDashed4:"\u254E",lineVerticalDashed5:"\u254F",lineVerticalDashed6:"\u2575",lineVerticalDashed7:"\u2577",lineVerticalDashed8:"\u2579",lineVerticalDashed9:"\u257B",lineVerticalDashed10:"\u257D",lineVerticalDashed11:"\u257F",lineDownLeft:"\u2510",lineDownLeftArc:"\u256E",lineDownBoldLeftBold:"\u2513",lineDownBoldLeft:"\u2512",lineDownLeftBold:"\u2511",lineDownDoubleLeftDouble:"\u2557",lineDownDoubleLeft:"\u2556",lineDownLeftDouble:"\u2555",lineDownRight:"\u250C",lineDownRightArc:"\u256D",lineDownBoldRightBold:"\u250F",lineDownBoldRight:"\u250E",lineDownRightBold:"\u250D",lineDownDoubleRightDouble:"\u2554",lineDownDoubleRight:"\u2553",lineDownRightDouble:"\u2552",lineUpLeft:"\u2518",lineUpLeftArc:"\u256F",lineUpBoldLeftBold:"\u251B",lineUpBoldLeft:"\u251A",lineUpLeftBold:"\u2519",lineUpDoubleLeftDouble:"\u255D",lineUpDoubleLeft:"\u255C",lineUpLeftDouble:"\u255B",lineUpRight:"\u2514",lineUpRightArc:"\u2570",lineUpBoldRightBold:"\u2517",lineUpBoldRight:"\u2516",lineUpRightBold:"\u2515",lineUpDoubleRightDouble:"\u255A",lineUpDoubleRight:"\u2559",lineUpRightDouble:"\u2558",lineUpDownLeft:"\u2524",lineUpBoldDownBoldLeftBold:"\u252B",lineUpBoldDownBoldLeft:"\u2528",lineUpDownLeftBold:"\u2525",lineUpBoldDownLeftBold:"\u2529",lineUpDownBoldLeftBold:"\u252A",lineUpDownBoldLeft:"\u2527",lineUpBoldDownLeft:"\u2526",lineUpDoubleDownDoubleLeftDouble:"\u2563",lineUpDoubleDownDoubleLeft:"\u2562",lineUpDownLeftDouble:"\u2561",lineUpDownRight:"\u251C",lineUpBoldDownBoldRightBold:"\u2523",lineUpBoldDownBoldRight:"\u2520",lineUpDownRightBold:"\u251D",lineUpBoldDownRightBold:"\u2521",lineUpDownBoldRightBold:"\u2522",lineUpDownBoldRight:"\u251F",lineUpBoldDownRight:"\u251E",lineUpDoubleDownDoubleRightDouble:"\u2560",lineUpDoubleDownDoubleRight:"\u255F",lineUpDownRightDouble:"\u255E",lineDownLeftRight:"\u252C",lineDownBoldLeftBoldRightBold:"\u2533",lineDownLeftBoldRightBold:"\u252F",lineDownBoldLeftRight:"\u2530",lineDownBoldLeftBoldRight:"\u2531",lineDownBoldLeftRightBold:"\u2532",lineDownLeftRightBold:"\u252E",lineDownLeftBoldRight:"\u252D",lineDownDoubleLeftDoubleRightDouble:"\u2566",lineDownDoubleLeftRight:"\u2565",lineDownLeftDoubleRightDouble:"\u2564",lineUpLeftRight:"\u2534",lineUpBoldLeftBoldRightBold:"\u253B",lineUpLeftBoldRightBold:"\u2537",lineUpBoldLeftRight:"\u2538",lineUpBoldLeftBoldRight:"\u2539",lineUpBoldLeftRightBold:"\u253A",lineUpLeftRightBold:"\u2536",lineUpLeftBoldRight:"\u2535",lineUpDoubleLeftDoubleRightDouble:"\u2569",lineUpDoubleLeftRight:"\u2568",lineUpLeftDoubleRightDouble:"\u2567",lineUpDownLeftRight:"\u253C",lineUpBoldDownBoldLeftBoldRightBold:"\u254B",lineUpDownBoldLeftBoldRightBold:"\u2548",lineUpBoldDownLeftBoldRightBold:"\u2547",lineUpBoldDownBoldLeftRightBold:"\u254A",lineUpBoldDownBoldLeftBoldRight:"\u2549",lineUpBoldDownLeftRight:"\u2540",lineUpDownBoldLeftRight:"\u2541",lineUpDownLeftBoldRight:"\u253D",lineUpDownLeftRightBold:"\u253E",lineUpBoldDownBoldLeftRight:"\u2542",lineUpDownLeftBoldRightBold:"\u253F",lineUpBoldDownLeftBoldRight:"\u2543",lineUpBoldDownLeftRightBold:"\u2544",lineUpDownBoldLeftBoldRight:"\u2545",lineUpDownBoldLeftRightBold:"\u2546",lineUpDoubleDownDoubleLeftDoubleRightDouble:"\u256C",lineUpDoubleDownDoubleLeftRight:"\u256B",lineUpDownLeftDoubleRightDouble:"\u256A",lineCross:"\u2573",lineBackslash:"\u2572",lineSlash:"\u2571"},ht={tick:"\u2714",info:"\u2139",warning:"\u26A0",cross:"\u2718",squareSmall:"\u25FB",squareSmallFilled:"\u25FC",circle:"\u25EF",circleFilled:"\u25C9",circleDotted:"\u25CC",circleDouble:"\u25CE",circleCircle:"\u24DE",circleCross:"\u24E7",circlePipe:"\u24BE",radioOn:"\u25C9",radioOff:"\u25EF",checkboxOn:"\u2612",checkboxOff:"\u2610",checkboxCircleOn:"\u24E7",checkboxCircleOff:"\u24BE",pointer:"\u276F",triangleUpOutline:"\u25B3",triangleLeft:"\u25C0",triangleRight:"\u25B6",lozenge:"\u25C6",lozengeOutline:"\u25C7",hamburger:"\u2630",smiley:"\u32E1",mustache:"\u0DF4",star:"\u2605",play:"\u25B6",nodejs:"\u2B22",oneSeventh:"\u2150",oneNinth:"\u2151",oneTenth:"\u2152"},br={tick:"\u221A",info:"i",warning:"\u203C",cross:"\xD7",squareSmall:"\u25A1",squareSmallFilled:"\u25A0",circle:"( )",circleFilled:"(*)",circleDotted:"( )",circleDouble:"( )",circleCircle:"(\u25CB)",circleCross:"(\xD7)",circlePipe:"(\u2502)",radioOn:"(*)",radioOff:"( )",checkboxOn:"[\xD7]",checkboxOff:"[ ]",checkboxCircleOn:"(\xD7)",checkboxCircleOff:"( )",pointer:">",triangleUpOutline:"\u2206",triangleLeft:"\u25C4",triangleRight:"\u25BA",lozenge:"\u2666",lozengeOutline:"\u25CA",hamburger:"\u2261",smiley:"\u263A",mustache:"\u250C\u2500\u2510",star:"\u2736",play:"\u25BA",nodejs:"\u2666",oneSeventh:"1/7",oneNinth:"1/9",oneTenth:"1/10"},vr={...mt,...ht},Er={...mt,...br},Dr=yr(),Pr=Dr?vr:Er,Z=Pr,Nn=Object.entries(ht);var Lr={prefix:{idle:(0,F.styleText)("blue","?"),done:(0,F.styleText)("green",Z.tick)},spinner:{interval:80,frames:["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"].map(t=>(0,F.styleText)("yellow",t))},keybindings:[],style:{answer:t=>(0,F.styleText)("cyan",t),message:t=>(0,F.styleText)("bold",t),error:t=>(0,F.styleText)("red",`> ${t}`),defaultAnswer:t=>(0,F.styleText)("dim",`(${t})`),help:t=>(0,F.styleText)("dim",t),highlight:t=>(0,F.styleText)("cyan",t),key:t=>(0,F.styleText)("cyan",(0,F.styleText)("bold",`<${t}>`))}};function gt(){return{...Lr,keybindings:ct()}}function wt(t){if(typeof t!="object"||t===null)return!1;let e=t;for(;Object.getPrototypeOf(e)!==null;)e=Object.getPrototypeOf(e);return Object.getPrototypeOf(t)===e}function St(...t){let e={};for(let r of t)for(let[n,i]of Object.entries(r)){let o=e[n];e[n]=wt(o)&&wt(i)?St(o,i):i}return e}function O(...t){let e=[gt(),...t.filter(r=>r!=null)];return St(...e)}function H({status:t="idle",theme:e}){let[r,n]=D(!1),[i,o]=D(0),{prefix:s,spinner:a}=O(e);return A(()=>{if(t==="loading"){let u,f=-1,l=setTimeout(()=>{n(!0),u=setInterval(()=>{f=f+1,o(f%a.frames.length)},a.interval)},300);return()=>{clearTimeout(l),clearInterval(u)}}else n(!1)},[t]),r?a.frames[i]:typeof s=="string"?s:s[t==="loading"?"idle":t]??s.idle}function ae(t,e){return Q(r=>{let n=r.get();if(!n||n.dependencies.length!==e.length||n.dependencies.some((i,o)=>i!==e[o])){let i=t();return r.set({value:i,dependencies:e}),i}return n.value})}function G(t){return D({current:t})[0]}function J(t){let e=G(t);e.current=t,A(r=>{let n=!1,i=_e((o,s)=>{n||e.current(s,r)});return r.input.on("keypress",i),()=>{n=!0,r.input.removeListener("keypress",i)}},[])}var At=$(yt(),1);var bt=(()=>{let t=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g;return e=>{let r=0;for(t.lastIndex=0;t.test(e);)r+=1;return e.length-r}})(),vt=t=>t===12288||t>=65281&&t<=65376||t>=65504&&t<=65510,Et=t=>t===8987||t===9001||t>=12272&&t<=12287||t>=12289&&t<=12350||t>=12441&&t<=12543||t>=12549&&t<=12591||t>=12593&&t<=12686||t>=12688&&t<=12771||t>=12783&&t<=12830||t>=12832&&t<=12871||t>=12880&&t<=19903||t>=65040&&t<=65049||t>=65072&&t<=65106||t>=65108&&t<=65126||t>=65128&&t<=65131||t>=127488&&t<=127490||t>=127504&&t<=127547||t>=127552&&t<=127560||t>=131072&&t<=196605||t>=196608&&t<=262141;var Ir=/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]|\u001b\]8;[^;]*;.*?(?:\u0007|\u001b\u005c)/y,Cr=/[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y,Dt=/(?:(?![\uFF61-\uFF9F\uFF00-\uFFEF])[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}\p{Script=Tangut}]){1,1000}/yu,Fr=/\t{1,1000}/y,Pt=new RegExp("[\\u{1F1E6}-\\u{1F1FF}]{2}|\\u{1F3F4}[\\u{E0061}-\\u{E007A}]{2}[\\u{E0030}-\\u{E0039}\\u{E0061}-\\u{E007A}]{1,3}\\u{E007F}|(?:\\p{Emoji}\\uFE0F\\u20E3?|\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|\\p{Emoji_Presentation})(?:\\u200D(?:\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|\\p{Emoji_Presentation}|\\p{Emoji}\\uFE0F\\u20E3?))*","yu"),Tr=/(?:[\x20-\x7E\xA0-\xFF](?!\uFE0F)){1,1000}/y,_r=new RegExp("\\p{M}+","gu"),Br={limit:1/0,ellipsis:""},Lt=(t,e={},r={})=>{let n=e.limit??1/0,i=e.ellipsis??"",o=e?.ellipsisWidth??(i?Lt(i,Br,r).width:0),s=0,a=r.controlWidth??0,c=r.tabWidth??8,u=r.emojiWidth??2,f=2,l=r.regularWidth??1,p=r.wideWidth??f,S=[[Tr,l],[Ir,s],[Cr,a],[Fr,c],[Pt,u],[Dt,p]],h=0,d=0,m=t.length,x=0,g=!1,y=m,b=Math.max(0,n-o),P=0,L=0,R=0,I=0;e:for(;;){if(L>P||d>=m&&d>h){let w=t.slice(P,L)||t.slice(h,d);x=0;for(let v of w.replaceAll(_r,"")){let E=v.codePointAt(0)||0;if(vt(E)?I=f:Et(E)?I=p:I=l,R+I>b&&(y=Math.min(y,Math.max(P,h)+x)),R+I>n){g=!0;break e}x+=v.length,R+=I}P=L=0}if(d>=m)break e;for(let w=0,v=S.length;w<v;w++){let[E,j]=S[w];if(E.lastIndex=d,E.test(t)){if(x=E===Dt?bt(t.slice(d,E.lastIndex)):E===Pt?1:E.lastIndex-d,I=x*j,R+I>b&&(y=Math.min(y,d+Math.floor((b-R)/j))),R+I>n){g=!0;break e}R+=I,P=h,L=d,d=h=E.lastIndex;continue e}}d+=1}return{width:g?b:R,index:g?y:m,truncated:g,ellipsed:g&&n>=o}},jt=Lt;var Ur={limit:1/0,ellipsis:"",ellipsisWidth:0},Ar=(t,e={})=>jt(t,Ur,e).width,N=Ar;var ye="\x1B",Tt="\x9B",Or=39,Ue="\x07",_t="[",Nr="]",Bt="m",Ae=`${Nr}8;;`,Rt=new RegExp(`(?:\\${_t}(?<code>\\d+)m|\\${Ae}(?<uri>.*)${Ue})`,"y"),It=t=>{if(t>=30&&t<=37||t>=90&&t<=97)return 39;if(t>=40&&t<=47||t>=100&&t<=107)return 49;if(t===1||t===2)return 22;if(t===3)return 23;if(t===4)return 24;if(t===7)return 27;if(t===8)return 28;if(t===9)return 29;if(t===0)return 0},Ct=t=>`${ye}${_t}${t}${Bt}`,Ft=t=>`${ye}${Ae}${t}${Ue}`,Be=(t,e,r)=>{let n=e[Symbol.iterator](),i=!1,o=!1,s=t.at(-1),a=s===void 0?0:N(s),c=n.next(),u=n.next(),f=0;for(;!c.done;){let l=c.value,p=N(l);a+p<=r?t[t.length-1]+=l:(t.push(l),a=0),(l===ye||l===Tt)&&(i=!0,o=e.startsWith(Ae,f+1)),i?o?l===Ue&&(i=!1,o=!1):l===Bt&&(i=!1):(a+=p,a===r&&!u.done&&(t.push(""),a=0)),c=u,u=n.next(),f+=l.length}s=t.at(-1),!a&&s!==void 0&&s.length&&t.length>1&&(t[t.length-2]+=t.pop())},Vr=t=>{let e=t.split(" "),r=e.length;for(;r&&!N(e[r-1]);)r--;return r===e.length?t:e.slice(0,r).join(" ")+e.slice(r).join("")},kr=(t,e,r={})=>{if(r.trim!==!1&&t.trim()==="")return"";let n="",i,o,s=t.split(" "),a=[""],c=0;for(let l=0;l<s.length;l++){let p=s[l];if(r.trim!==!1){let h=a.at(-1)??"",d=h.trimStart();h.length!==d.length&&(a[a.length-1]=d,c=N(d))}l!==0&&(c>=e&&(r.wordWrap===!1||r.trim===!1)&&(a.push(""),c=0),(c||r.trim===!1)&&(a[a.length-1]+=" ",c++));let S=N(p);if(r.hard&&S>e){let h=e-c,d=1+Math.floor((S-h-1)/e);Math.floor((S-1)/e)<d&&a.push(""),Be(a,p,e),c=N(a.at(-1)??"");continue}if(c+S>e&&c&&S){if(r.wordWrap===!1&&c<e){Be(a,p,e),c=N(a.at(-1)??"");continue}a.push(""),c=0}if(c+S>e&&r.wordWrap===!1){Be(a,p,e),c=N(a.at(-1)??"");continue}a[a.length-1]+=p,c+=S}r.trim!==!1&&(a=a.map(l=>Vr(l)));let u=a.join(`
4
+ `),f=!1;for(let l=0;l<u.length;l++){let p=u[l];if(n+=p,f)f=!1;else if(f=p>="\uD800"&&p<="\uDBFF",f)continue;if(p===ye||p===Tt){Rt.lastIndex=l+1;let h=Rt.exec(u)?.groups;if(h?.code!==void 0){let d=Number.parseFloat(h.code);i=d===Or?void 0:d}else h?.uri!==void 0&&(o=h.uri.length===0?void 0:h.uri)}if(u[l+1]===`
5
+ `){o&&(n+=Ft(""));let S=i?It(i):void 0;i&&S&&(n+=Ct(S))}else p===`
6
+ `&&(i&&It(i)&&(n+=Ct(i)),o&&(n+=Ft(o)))}return n},$r=/\r?\n/;function Ut(t,e,r){return String(t).normalize().split($r).map(n=>kr(n,e,r)).join(`
7
7
  `)}function le(t,e){return t.split(`
8
- `).flatMap(r=>jt(r,e,{trim:!1,wordWrap:!1}).split(`
8
+ `).flatMap(r=>Ut(r,e,{trim:!1,wordWrap:!1}).split(`
9
9
  `).map(n=>n.trimEnd())).join(`
10
- `)}function ye(){return(0,Ut.default)({defaultWidth:80,output:Te().output})}function Or({active:t,renderedItems:e,pageSize:r,loop:n}){let i=H({lastPointer:t,lastActive:void 0}),{lastPointer:s,lastActive:o}=i.current,a=Math.floor(r/2),c=e.reduce((l,p)=>l+p.length,0),u=e.slice(0,t).reduce((l,p)=>l+p.length,0),f=u;if(c>r)if(n)f=s,o!=null&&o<t&&t-o<r&&(f=Math.min(a,Math.abs(t-o)===1?Math.min(s+(e[o]?.length??0),Math.max(u,s)):s+t-o));else{let l=e.slice(t).reduce((p,S)=>p+S.length,0);f=l<r-a?r-l:Math.min(u,a)}return i.current.lastPointer=f,i.current.lastActive=t,f}function Ne({items:t,active:e,renderItem:r,pageSize:n,loop:i=!0}){let s=ye(),o=x=>(x%t.length+t.length)%t.length,a=t.map((x,g)=>x==null?[]:le(r({item:x,index:g,isActive:g===e}),s).split(`
11
- `)),c=a.reduce((x,g)=>x+g.length,0),u=x=>a[x]??[],f=Or({active:e,renderedItems:a,pageSize:n,loop:i}),l=u(e).slice(0,n),p=f+l.length<=n?f:n-l.length,S=Array.from({length:n});S.splice(p,l.length,...l);let h=new Set([e]),d=p+l.length,m=o(e+1);for(;d<n&&!h.has(m)&&(i&&c>n?m!==e:m>e);){let g=u(m).slice(0,n-d);S.splice(d,g.length,...g),h.add(m),d+=g.length,m=o(m+1)}for(d=p-1,m=o(e-1);d>=0&&!h.has(m)&&(i&&c>n?m!==e:m<e);){let x=u(m),g=x.slice(Math.max(0,x.length-d-1));S.splice(d-g.length+1,g.length,...g),h.add(m),d-=g.length,m=o(m-1)}return S.filter(x=>typeof x=="string").join(`
12
- `)}var Wt=k(require("node:readline"),1),Kt=require("node:async_hooks"),Ht=k(Nt(),1);var J=[];J.push("SIGHUP","SIGINT","SIGTERM");process.platform!=="win32"&&J.push("SIGALRM","SIGABRT","SIGVTALRM","SIGXCPU","SIGXFSZ","SIGUSR2","SIGTRAP","SIGSYS","SIGQUIT","SIGIOT");process.platform==="linux"&&J.push("SIGIO","SIGPOLL","SIGPWR","SIGSTKFLT");var be=t=>!!t&&typeof t=="object"&&typeof t.removeListener=="function"&&typeof t.emit=="function"&&typeof t.reallyExit=="function"&&typeof t.listeners=="function"&&typeof t.kill=="function"&&typeof t.pid=="number"&&typeof t.on=="function",Oe=Symbol.for("signal-exit emitter"),Ve=globalThis,kr=Object.defineProperty.bind(Object),ke=class{emitted={afterExit:!1,exit:!1};listeners={afterExit:[],exit:[]};count=0;id=Math.random();constructor(){if(Ve[Oe])return Ve[Oe];kr(Ve,Oe,{value:this,writable:!1,enumerable:!1,configurable:!1})}on(e,r){this.listeners[e].push(r)}removeListener(e,r){let n=this.listeners[e],i=n.indexOf(r);i!==-1&&(i===0&&n.length===1?n.length=0:n.splice(i,1))}emit(e,r,n){if(this.emitted[e])return!1;this.emitted[e]=!0;let i=!1;for(let s of this.listeners[e])i=s(r,n)===!0||i;return e==="exit"&&(i=this.emit("afterExit",r,n)||i),i}},ve=class{},Mr=t=>({onExit(e,r){return t.onExit(e,r)},load(){return t.load()},unload(){return t.unload()}}),Me=class extends ve{onExit(){return()=>{}}load(){}unload(){}},$e=class extends ve{#r=We.platform==="win32"?"SIGINT":"SIGHUP";#t=new ke;#e;#o;#s;#i={};#n=!1;constructor(e){super(),this.#e=e,this.#i={};for(let r of J)this.#i[r]=()=>{let n=this.#e.listeners(r),{count:i}=this.#t,s=e;if(typeof s.__signal_exit_emitter__=="object"&&typeof s.__signal_exit_emitter__.count=="number"&&(i+=s.__signal_exit_emitter__.count),n.length===i){this.unload();let o=this.#t.emit("exit",null,r),a=r==="SIGHUP"?this.#r:r;o||e.kill(e.pid,a)}};this.#s=e.reallyExit,this.#o=e.emit}onExit(e,r){if(!be(this.#e))return()=>{};this.#n===!1&&this.load();let n=r?.alwaysLast?"afterExit":"exit";return this.#t.on(n,e),()=>{this.#t.removeListener(n,e),this.#t.listeners.exit.length===0&&this.#t.listeners.afterExit.length===0&&this.unload()}}load(){if(!this.#n){this.#n=!0,this.#t.count+=1;for(let e of J)try{let r=this.#i[e];r&&this.#e.on(e,r)}catch{}this.#e.emit=(e,...r)=>this.#l(e,...r),this.#e.reallyExit=e=>this.#a(e)}}unload(){this.#n&&(this.#n=!1,J.forEach(e=>{let r=this.#i[e];if(!r)throw new Error("Listener not defined for signal: "+e);try{this.#e.removeListener(e,r)}catch{}}),this.#e.emit=this.#o,this.#e.reallyExit=this.#s,this.#t.count-=1)}#a(e){return be(this.#e)?(this.#e.exitCode=e||0,this.#t.emit("exit",this.#e.exitCode,null),this.#s.call(this.#e,this.#e.exitCode)):0}#l(e,...r){let n=this.#o;if(e==="exit"&&be(this.#e)){typeof r[0]=="number"&&(this.#e.exitCode=r[0]);let i=n.call(this.#e,e,...r);return this.#t.emit("exit",this.#e.exitCode,null),i}else return n.call(this.#e,e,...r)}},We=globalThis.process,{onExit:At,load:wi,unload:Si}=Mr(be(We)?new $e(We):new Me);var $t=require("node:util");var Vt="\x1B[?25l",kt="\x1B[?25h",Ke=(t=1)=>t>0?`\x1B[${t}A`:"",He=(t=1)=>t>0?`\x1B[${t}B`:"",Ge=(t,e)=>typeof e=="number"&&!Number.isNaN(e)?`\x1B[${e+1};${t+1}H`:`\x1B[${t+1}G`,Ot="\x1B[2K",Je=t=>t>0?(Ot+Ke(1)).repeat(t-1)+Ot+"\x1B[G":"";var Mt=t=>t.split(`
13
- `).length,Wr=t=>t.split(`
14
- `).pop()??"",ce=class{height=0;extraLinesUnderPrompt=0;cursorPos;rl;constructor(e){this.rl=e,this.cursorPos=e.getCursorPos()}write(e){this.rl.output.unmute(),this.rl.output.write(e),this.rl.output.mute()}render(e,r=""){let n=Wr(e),i=(0,$t.stripVTControlCharacters)(n),s=i;this.rl.line.length>0&&(s=s.slice(0,-this.rl.line.length)),this.rl.setPrompt(s),this.cursorPos=this.rl.getCursorPos();let o=ye();e=le(e,o),r=le(r,o),i.length%o===0&&(e+=`
10
+ `)}function be(){return(0,At.default)({defaultWidth:80,output:Te().output})}function Mr({active:t,renderedItems:e,pageSize:r,loop:n}){let i=G({lastPointer:t,lastActive:void 0}),{lastPointer:o,lastActive:s}=i.current,a=Math.floor(r/2),c=e.reduce((l,p)=>l+p.length,0),u=e.slice(0,t).reduce((l,p)=>l+p.length,0),f=u;if(c>r)if(n)f=o,s!=null&&s<t&&t-s<r&&(f=Math.min(a,Math.abs(t-s)===1?Math.min(o+(e[s]?.length??0),Math.max(u,o)):o+t-s));else{let l=e.slice(t).reduce((p,S)=>p+S.length,0);f=l<r-a?r-l:Math.min(u,a)}return i.current.lastPointer=f,i.current.lastActive=t,f}function Oe({items:t,active:e,renderItem:r,pageSize:n,loop:i=!0}){let o=be(),s=x=>(x%t.length+t.length)%t.length,a=t.map((x,g)=>x==null?[]:le(r({item:x,index:g,isActive:g===e}),o).split(`
11
+ `)),c=a.reduce((x,g)=>x+g.length,0),u=x=>a[x]??[],f=Mr({active:e,renderedItems:a,pageSize:n,loop:i}),l=u(e).slice(0,n),p=f+l.length<=n?f:n-l.length,S=Array.from({length:n});S.splice(p,l.length,...l);let h=new Set([e]),d=p+l.length,m=s(e+1);for(;d<n&&!h.has(m)&&(i&&c>n?m!==e:m>e);){let g=u(m).slice(0,n-d);S.splice(d,g.length,...g),h.add(m),d+=g.length,m=s(m+1)}for(d=p-1,m=s(e-1);d>=0&&!h.has(m)&&(i&&c>n?m!==e:m<e);){let x=u(m),g=x.slice(Math.max(0,x.length-d-1));S.splice(d-g.length+1,g.length,...g),h.add(m),d-=g.length,m=s(m-1)}return S.filter(x=>typeof x=="string").join(`
12
+ `)}var Ht=$(require("node:readline"),1),Gt=require("node:async_hooks"),Jt=$(Nt(),1);var q=[];q.push("SIGHUP","SIGINT","SIGTERM");process.platform!=="win32"&&q.push("SIGALRM","SIGABRT","SIGVTALRM","SIGXCPU","SIGXFSZ","SIGUSR2","SIGTRAP","SIGSYS","SIGQUIT","SIGIOT");process.platform==="linux"&&q.push("SIGIO","SIGPOLL","SIGPWR","SIGSTKFLT");var ve=t=>!!t&&typeof t=="object"&&typeof t.removeListener=="function"&&typeof t.emit=="function"&&typeof t.reallyExit=="function"&&typeof t.listeners=="function"&&typeof t.kill=="function"&&typeof t.pid=="number"&&typeof t.on=="function",Ve=Symbol.for("signal-exit emitter"),ke=globalThis,Kr=Object.defineProperty.bind(Object),$e=class{emitted={afterExit:!1,exit:!1};listeners={afterExit:[],exit:[]};count=0;id=Math.random();constructor(){if(ke[Ve])return ke[Ve];Kr(ke,Ve,{value:this,writable:!1,enumerable:!1,configurable:!1})}on(e,r){this.listeners[e].push(r)}removeListener(e,r){let n=this.listeners[e],i=n.indexOf(r);i!==-1&&(i===0&&n.length===1?n.length=0:n.splice(i,1))}emit(e,r,n){if(this.emitted[e])return!1;this.emitted[e]=!0;let i=!1;for(let o of this.listeners[e])i=o(r,n)===!0||i;return e==="exit"&&(i=this.emit("afterExit",r,n)||i),i}},Ee=class{},Hr=t=>({onExit(e,r){return t.onExit(e,r)},load(){return t.load()},unload(){return t.unload()}}),Me=class extends Ee{onExit(){return()=>{}}load(){}unload(){}},We=class extends Ee{#r=Ke.platform==="win32"?"SIGINT":"SIGHUP";#t=new $e;#e;#o;#s;#i={};#n=!1;constructor(e){super(),this.#e=e,this.#i={};for(let r of q)this.#i[r]=()=>{let n=this.#e.listeners(r),{count:i}=this.#t,o=e;if(typeof o.__signal_exit_emitter__=="object"&&typeof o.__signal_exit_emitter__.count=="number"&&(i+=o.__signal_exit_emitter__.count),n.length===i){this.unload();let s=this.#t.emit("exit",null,r),a=r==="SIGHUP"?this.#r:r;s||e.kill(e.pid,a)}};this.#s=e.reallyExit,this.#o=e.emit}onExit(e,r){if(!ve(this.#e))return()=>{};this.#n===!1&&this.load();let n=r?.alwaysLast?"afterExit":"exit";return this.#t.on(n,e),()=>{this.#t.removeListener(n,e),this.#t.listeners.exit.length===0&&this.#t.listeners.afterExit.length===0&&this.unload()}}load(){if(!this.#n){this.#n=!0,this.#t.count+=1;for(let e of q)try{let r=this.#i[e];r&&this.#e.on(e,r)}catch{}this.#e.emit=(e,...r)=>this.#l(e,...r),this.#e.reallyExit=e=>this.#a(e)}}unload(){this.#n&&(this.#n=!1,q.forEach(e=>{let r=this.#i[e];if(!r)throw new Error("Listener not defined for signal: "+e);try{this.#e.removeListener(e,r)}catch{}}),this.#e.emit=this.#o,this.#e.reallyExit=this.#s,this.#t.count-=1)}#a(e){return ve(this.#e)?(this.#e.exitCode=e||0,this.#t.emit("exit",this.#e.exitCode,null),this.#s.call(this.#e,this.#e.exitCode)):0}#l(e,...r){let n=this.#o;if(e==="exit"&&ve(this.#e)){typeof r[0]=="number"&&(this.#e.exitCode=r[0]);let i=n.call(this.#e,e,...r);return this.#t.emit("exit",this.#e.exitCode,null),i}else return n.call(this.#e,e,...r)}},Ke=globalThis.process,{onExit:Vt,load:yi,unload:bi}=Hr(ve(Ke)?new We(Ke):new Me);var Kt=require("node:util");var $t="\x1B[?25l",Mt="\x1B[?25h",He=(t=1)=>t>0?`\x1B[${t}A`:"",Ge=(t=1)=>t>0?`\x1B[${t}B`:"",Je=(t,e)=>typeof e=="number"&&!Number.isNaN(e)?`\x1B[${e+1};${t+1}H`:`\x1B[${t+1}G`,kt="\x1B[2K",qe=t=>t>0?(kt+He(1)).repeat(t-1)+kt+"\x1B[G":"";var Wt=t=>t.split(`
13
+ `).length,Jr=t=>t.split(`
14
+ `).pop()??"",ce=class{height=0;extraLinesUnderPrompt=0;cursorPos;rl;constructor(e){this.rl=e,this.cursorPos=e.getCursorPos()}write(e){this.rl.output.unmute(),this.rl.output.write(e),this.rl.output.mute()}render(e,r=""){let n=Jr(e),i=(0,Kt.stripVTControlCharacters)(n),o=i;this.rl.line.length>0&&(o=o.slice(0,-this.rl.line.length)),this.rl.setPrompt(o),this.cursorPos=this.rl.getCursorPos();let s=be();e=le(e,s),r=le(r,s),i.length%s===0&&(e+=`
15
15
  `);let a=e+(r?`
16
- `+r:""),u=Math.floor(i.length/o)-this.cursorPos.rows+(r?Mt(r):0);u>0&&(a+=Ke(u)),a+=Ge(this.cursorPos.cols),this.write(He(this.extraLinesUnderPrompt)+Je(this.height)+a),this.extraLinesUnderPrompt=u,this.height=Mt(a)}checkCursorPos(){let e=this.rl.getCursorPos();e.cols!==this.cursorPos.cols&&(this.write(Ge(e.cols)),this.cursorPos=e)}done({clearContent:e}){this.rl.setPrompt("");let r=He(this.extraLinesUnderPrompt);r+=e?Je(this.height):`
17
- `,r+="\x1B[G",r+=kt,this.write(r),this.rl.close()}};var Ee=class extends Promise{static withResolver(){let e,r;return{promise:new Promise((i,s)=>{e=i,r=s}),resolve:e,reject:r}}};var Gt=k(require("node:path"),1),Kr=globalThis.setImmediate;function Hr(){let t=Error.prepareStackTrace,e=[];try{Error.prepareStackTrace=(r,n)=>{let i=n.slice(1);return e=i,i},new Error().stack}catch{return e}return Error.prepareStackTrace=t,e}function q(t){let e=Hr();return(n,i={})=>{let{input:s=process.stdin,signal:o}=i,a=new Set,c=new Ht.default;c.pipe(i.output??process.stdout);let u=Wt.createInterface({terminal:!0,input:s,output:c});c.mute();let f=new ce(u),{promise:l,resolve:p,reject:S}=Ee.withResolver(),h=()=>S(new ge);if(o){let m=()=>S(new he({cause:o.reason}));if(o.aborted)return m(),Object.assign(l,{cancel:h});o.addEventListener("abort",m),a.add(()=>o.removeEventListener("abort",m))}a.add(At((m,x)=>{S(new se(`User force closed the prompt with ${m} ${x}`))}));let d=()=>S(new se("User force closed the prompt with SIGINT"));return u.on("SIGINT",d),a.add(()=>u.removeListener("SIGINT",d)),ct(u,m=>{let x=Kt.AsyncResource.bind(()=>W.clearAll());u.on("close",x),a.add(()=>u.removeListener("close",x));let g=()=>{let y=()=>f.checkCursorPos();u.input.on("keypress",y),a.add(()=>u.input.removeListener("keypress",y));let b=null;m(()=>{let P=!1;try{let L=t(n,w=>{P?p(w):b={value:w}});if(L===void 0){let w=e[1]?.getFileName();throw w&&!w.startsWith("file://")&&(w=Gt.default.resolve(w)),new Error(`Prompt functions must return a string.
18
- at ${w}`)}let[I,F]=typeof L=="string"?[L]:L;f.render(I,F),W.run()}catch(L){S(L)}if(P=!0,b!==null){let{value:L}=b;b=null,p(L)}})};return"readableFlowing"in s?Kr(g):g(),Object.assign(l.then(y=>(W.clearAll(),y),y=>{throw W.clearAll(),y}).finally(()=>{a.forEach(y=>y()),f.done({clearContent:!!i.clearPromptOnDone}),c.end()}).then(()=>l),{cancel:h})})}}var Jt=require("node:util");var j=class{separator=(0,Jt.styleText)("dim",Array.from({length:15}).join(Z.line));type="separator";constructor(e){e&&(this.separator=e)}static isSeparator(e){return!!(e&&typeof e=="object"&&"type"in e&&e.type==="separator")}};function qt(t,e){let r=e!==!1;return/^(y|yes)/i.test(t)?r=!0:/^(n|no)/i.test(t)&&(r=!1),r}function Xt(t){return t?"Yes":"No"}var qe=q((t,e)=>{let{transformer:r=Xt}=t,[n,i]=D("idle"),[s,o]=D(""),a=N(t.theme),c=K({status:n,theme:a});G((p,S)=>{if(n==="idle")if(M(p)){let h=qt(s,t.default);o(r(h)),i("done"),e(h)}else if(oe(p)){let h=Xt(!qt(s,t.default));S.clearLine(0),S.write(h),o(h)}else o(S.line)});let u=s,f="";n==="done"?u=a.style.answer(s):f=` ${a.style.defaultAnswer(t.default===!1?"y/N":"Y/n")}`;let l=a.style.message(t.message,n);return`${c} ${l}${f} ${u}`});var Gr={validationFailureMode:"keep"},Xe=q((t,e)=>{let{prefill:r="tab"}=t,n=N(Gr,t.theme),[i,s]=D("idle"),[o,a]=D(String(t.default??"")),[c,u]=D(),[f,l]=D(""),p=K({status:i,theme:n});async function S(g){let{required:y,pattern:b,patternError:P="Invalid input"}=t;return y&&!g?"You must provide a value":b&&!b.test(g)?P:typeof t.validate=="function"?await t.validate(g)||"You must provide a valid value":!0}G(async(g,y)=>{if(i==="idle")if(M(g)){let b=f||o;s("loading");let P=await S(b);P===!0?(l(b),s("done"),e(b)):(n.validationFailureMode==="clear"?l(""):y.write(f),u(P),s("idle"))}else ie(g)&&!f?a(""):oe(g)&&!f?(a(""),y.clearLine(0),y.write(o),l(o)):(l(y.line),u(void 0))}),_(g=>{r==="editable"&&o&&(g.write(o),l(o))},[]);let h=n.style.message(t.message,i),d=f;typeof t.transformer=="function"?d=t.transformer(f,{isFinal:i==="done"}):i==="done"&&(d=n.style.answer(f));let m;o&&i!=="done"&&!f&&(m=n.style.defaultAnswer(o));let x="";return c&&(x=n.style.error(c)),[[p,h,m,d].filter(g=>g!==void 0).join(" "),x]});var ee=require("node:util");var Jr={icon:{cursor:Z.pointer},style:{disabled:t=>(0,ee.styleText)("dim",t),description:t=>(0,ee.styleText)("cyan",t),keysHelpTip:t=>t.map(([e,r])=>`${(0,ee.styleText)("bold",e)} ${(0,ee.styleText)("dim",r)}`).join((0,ee.styleText)("dim"," \u2022 "))},i18n:{disabledError:"This option is disabled and cannot be selected."},indexMode:"hidden"};function ze(t){return!j.isSeparator(t)&&!t.disabled}function Ye(t){return!j.isSeparator(t)}function qr(t){return t.map(e=>{if(j.isSeparator(e))return e;if(typeof e!="object"||e===null||!("value"in e)){let i=String(e);return{value:e,name:i,short:i,disabled:!1}}let r=e.name??String(e.value),n={value:e.value,name:r,short:e.short??r,disabled:e.disabled??!1};return e.description&&(n.description=e.description),n})}var De=q((t,e)=>{let{loop:r=!0,pageSize:n=7}=t,i=N(Jr,t.theme),{keybindings:s}=i,[o,a]=D("idle"),c=K({status:o,theme:i}),u=H(),f=!s.includes("vim"),l=ae(()=>qr(t.choices),[t.choices]),p=ae(()=>{let w=l.findIndex(Ye),v=l.findLastIndex(Ye);if(w===-1)throw new Y("[select prompt] No selectable choices. All choices are disabled.");return{first:w,last:v}},[l]),S=ae(()=>"default"in t?l.findIndex(w=>ze(w)&&w.value===t.default):-1,[t.default,l]),[h,d]=D(S===-1?p.first:S),m=l[h];if(m==null||j.isSeparator(m))throw new Error("Active index does not point to a choice");let[x,g]=D();G((w,v)=>{if(clearTimeout(u.current),x&&g(void 0),M(w))m.disabled?g(i.i18n.disabledError):(a("done"),e(m.value));else if(ne(w,s)||me(w,s)){if(v.clearLine(0),r||ne(w,s)&&h!==p.first||me(w,s)&&h!==p.last){let E=ne(w,s)?-1:1,R=h;do R=(R+E+l.length)%l.length;while(!Ye(l[R]));d(R)}}else if(Ce(w)&&!Number.isNaN(Number(v.line))){let E=Number(v.line)-1,R=-1,U=l.findIndex(te=>j.isSeparator(te)?!1:(R++,R===E)),Pe=l[U];Pe!=null&&ze(Pe)&&d(U),u.current=setTimeout(()=>{v.clearLine(0)},700)}else if(ie(w))v.clearLine(0);else if(f){let E=v.line.toLowerCase(),R=l.findIndex(U=>j.isSeparator(U)||!ze(U)?!1:U.name.toLowerCase().startsWith(E));R!==-1&&d(R),u.current=setTimeout(()=>{v.clearLine(0)},700)}}),_(()=>()=>{clearTimeout(u.current)},[]);let y=i.style.message(t.message,o),b=i.style.keysHelpTip([["\u2191\u2193","navigate"],["\u23CE","select"]]),P=0,L=Ne({items:l,active:h,renderItem({item:w,isActive:v,index:E}){if(j.isSeparator(w))return P++,` ${w.separator}`;let R=v?i.icon.cursor:" ",U=i.indexMode==="number"?`${E+1-P}. `:"";if(w.disabled){let te=typeof w.disabled=="string"?w.disabled:"(disabled)",Qt=v?i.icon.cursor:"-";return i.style.disabled(`${Qt} ${U}${w.name} ${te}`)}return(v?i.style.highlight:te=>te)(`${R} ${U}${w.name}`)},pageSize:n,loop:r});if(o==="done")return[c,y,i.style.answer(m.short)].filter(Boolean).join(" ");let{description:I}=m;return`${[[c,y].filter(Boolean).join(" "),L," ",I?i.style.description(I):"",x?i.style.error(x):"",b].filter(Boolean).join(`
19
- `).trimEnd()}${Vt}`});async function zt(t){let e=new Map;for(let o of t.projects){let a=e.get(o.name);a?a.push(o.version):e.set(o.name,[o.version])}let r=Array.from(e.keys()).sort(),n=await De({message:"Choose project name:",choices:r.map(o=>({name:o,value:o})),pageSize:15}),i=(e.get(n)??[]).sort(),s=await De({message:"Choose project version:",choices:i.map(o=>({name:o,value:o})),pageSize:15});return{projectName:n,projectVersion:s}}var Yt=process.cwd();(async()=>{let{projectName:t,referenceProjectVersion:e,targetProjectVersion:r}=await Xr();await st({workingDir:Yt,projectName:t,referenceProjectVersion:e,targetProjectVersion:r})})();async function Xr(){let t=process.argv[2];if(!t)return zr();let e=process.argv[3];if(!e)throw new Error("Missing reference project version.");let r=process.argv[4];if(!r)throw new Error("Missing target project version.");return{projectName:t,referenceProjectVersion:e,targetProjectVersion:r}}async function zr(){try{let t=await new V(Yt).loadProjectConfig(),{projectName:e,projectVersion:r}=await zt(t),n=await Xe({message:`Enter the target project version (e.g. ${r}):`,required:!0});return await qe({message:`New project ${e}@${n} will be added based on ${r}.
16
+ `+r:""),u=Math.floor(i.length/s)-this.cursorPos.rows+(r?Wt(r):0);u>0&&(a+=He(u)),a+=Je(this.cursorPos.cols),this.write(Ge(this.extraLinesUnderPrompt)+qe(this.height)+a),this.extraLinesUnderPrompt=u,this.height=Wt(a)}checkCursorPos(){let e=this.rl.getCursorPos();e.cols!==this.cursorPos.cols&&(this.write(Je(e.cols)),this.cursorPos=e)}done({clearContent:e}){this.rl.setPrompt("");let r=Ge(this.extraLinesUnderPrompt);r+=e?qe(this.height):`
17
+ `,r+="\x1B[G",r+=Mt,this.write(r),this.rl.close()}};var De=class extends Promise{static withResolver(){let e,r;return{promise:new Promise((i,o)=>{e=i,r=o}),resolve:e,reject:r}}};var qt=$(require("node:path"),1),qr=globalThis.setImmediate;function Xr(){let t=Error.prepareStackTrace,e=[];try{Error.prepareStackTrace=(r,n)=>{let i=n.slice(1);return e=i,i},new Error().stack}catch{return e}return Error.prepareStackTrace=t,e}function X(t){let e=Xr();return(n,i={})=>{let{input:o=process.stdin,signal:s}=i,a=new Set,c=new Jt.default;c.pipe(i.output??process.stdout);let u=Ht.createInterface({terminal:!0,input:o,output:c});c.mute();let f=new ce(u),{promise:l,resolve:p,reject:S}=De.withResolver(),h=()=>S(new we);if(s){let m=()=>S(new ge({cause:s.reason}));if(s.aborted)return m(),Object.assign(l,{cancel:h});s.addEventListener("abort",m),a.add(()=>s.removeEventListener("abort",m))}a.add(Vt((m,x)=>{S(new se(`User force closed the prompt with ${m} ${x}`))}));let d=()=>S(new se("User force closed the prompt with SIGINT"));return u.on("SIGINT",d),a.add(()=>u.removeListener("SIGINT",d)),ft(u,m=>{let x=Gt.AsyncResource.bind(()=>K.clearAll());u.on("close",x),a.add(()=>u.removeListener("close",x));let g=()=>{let y=()=>f.checkCursorPos();u.input.on("keypress",y),a.add(()=>u.input.removeListener("keypress",y));let b=null;m(()=>{let P=!1;try{let L=t(n,w=>{P?p(w):b={value:w}});if(L===void 0){let w=e[1]?.getFileName();throw w&&!w.startsWith("file://")&&(w=qt.default.resolve(w)),new Error(`Prompt functions must return a string.
18
+ at ${w}`)}let[R,I]=typeof L=="string"?[L]:L;f.render(R,I),K.run()}catch(L){S(L)}if(P=!0,b!==null){let{value:L}=b;b=null,p(L)}})};return"readableFlowing"in o?qr(g):g(),Object.assign(l.then(y=>(K.clearAll(),y),y=>{throw K.clearAll(),y}).finally(()=>{a.forEach(y=>y()),f.done({clearContent:!!i.clearPromptOnDone}),c.end()}).then(()=>l),{cancel:h})})}}var Xt=require("node:util");var _=class{separator=(0,Xt.styleText)("dim",Array.from({length:15}).join(Z.line));type="separator";constructor(e){e&&(this.separator=e)}static isSeparator(e){return!!(e&&typeof e=="object"&&"type"in e&&e.type==="separator")}};function zt(t,e){let r=e!==!1;return/^(y|yes)/i.test(t)?r=!0:/^(n|no)/i.test(t)&&(r=!1),r}function Yt(t){return t?"Yes":"No"}var Xe=X((t,e)=>{let{transformer:r=Yt}=t,[n,i]=D("idle"),[o,s]=D(""),a=O(t.theme),c=H({status:n,theme:a});J((p,S)=>{if(n==="idle")if(M(p)){let h=zt(o,t.default);s(r(h)),i("done"),e(h)}else if(oe(p)){let h=Yt(!zt(o,t.default));S.clearLine(0),S.write(h),s(h)}else s(S.line)});let u=o,f="";n==="done"?u=a.style.answer(o):f=` ${a.style.defaultAnswer(t.default===!1?"y/N":"Y/n")}`;let l=a.style.message(t.message,n);return`${c} ${l}${f} ${u}`});var zr={validationFailureMode:"keep"},ze=X((t,e)=>{let{prefill:r="tab"}=t,n=O(zr,t.theme),[i,o]=D("idle"),[s,a]=D(String(t.default??"")),[c,u]=D(),[f,l]=D(""),p=H({status:i,theme:n});async function S(g){let{required:y,pattern:b,patternError:P="Invalid input"}=t;return y&&!g?"You must provide a value":b&&!b.test(g)?P:typeof t.validate=="function"?await t.validate(g)||"You must provide a valid value":!0}J(async(g,y)=>{if(i==="idle")if(M(g)){let b=f||s;o("loading");let P=await S(b);P===!0?(l(b),o("done"),e(b)):(n.validationFailureMode==="clear"?l(""):y.write(f),u(P),o("idle"))}else ie(g)&&!f?a(""):oe(g)&&!f?(a(""),y.clearLine(0),y.write(s),l(s)):(l(y.line),u(void 0))}),A(g=>{r==="editable"&&s&&(g.write(s),l(s))},[]);let h=n.style.message(t.message,i),d=f;typeof t.transformer=="function"?d=t.transformer(f,{isFinal:i==="done"}):i==="done"&&(d=n.style.answer(f));let m;s&&i!=="done"&&!f&&(m=n.style.defaultAnswer(s));let x="";return c&&(x=n.style.error(c)),[[p,h,m,d].filter(g=>g!==void 0).join(" "),x]});var ee=require("node:util");var Yr={icon:{cursor:Z.pointer},style:{disabled:t=>(0,ee.styleText)("dim",t),description:t=>(0,ee.styleText)("cyan",t),keysHelpTip:t=>t.map(([e,r])=>`${(0,ee.styleText)("bold",e)} ${(0,ee.styleText)("dim",r)}`).join((0,ee.styleText)("dim"," \u2022 "))},i18n:{disabledError:"This option is disabled and cannot be selected."},indexMode:"hidden"};function Ye(t){return!_.isSeparator(t)&&!t.disabled}function Qe(t){return!_.isSeparator(t)}function Qr(t){return t.map(e=>{if(_.isSeparator(e))return e;if(typeof e!="object"||e===null||!("value"in e)){let i=String(e);return{value:e,name:i,short:i,disabled:!1}}let r=e.name??String(e.value),n={value:e.value,name:r,short:e.short??r,disabled:e.disabled??!1};return e.description&&(n.description=e.description),n})}var Pe=X((t,e)=>{let{loop:r=!0,pageSize:n=7}=t,i=O(Yr,t.theme),{keybindings:o}=i,[s,a]=D("idle"),c=H({status:s,theme:i}),u=G(),f=!o.includes("vim"),l=ae(()=>Qr(t.choices),[t.choices]),p=ae(()=>{let w=l.findIndex(Qe),v=l.findLastIndex(Qe);if(w===-1)throw new Y("[select prompt] No selectable choices. All choices are disabled.");return{first:w,last:v}},[l]),S=ae(()=>"default"in t?l.findIndex(w=>Ye(w)&&w.value===t.default):-1,[t.default,l]),[h,d]=D(S===-1?p.first:S),m=l[h];if(m==null||_.isSeparator(m))throw new Error("Active index does not point to a choice");let[x,g]=D();J((w,v)=>{if(clearTimeout(u.current),x&&g(void 0),M(w))m.disabled?g(i.i18n.disabledError):(a("done"),e(m.value));else if(ne(w,o)||he(w,o)){if(v.clearLine(0),r||ne(w,o)&&h!==p.first||he(w,o)&&h!==p.last){let E=ne(w,o)?-1:1,j=h;do j=(j+E+l.length)%l.length;while(!Qe(l[j]));d(j)}}else if(Fe(w)&&!Number.isNaN(Number(v.line))){let E=Number(v.line)-1,j=-1,B=l.findIndex(te=>_.isSeparator(te)?!1:(j++,j===E)),Le=l[B];Le!=null&&Ye(Le)&&d(B),u.current=setTimeout(()=>{v.clearLine(0)},700)}else if(ie(w))v.clearLine(0);else if(f){let E=v.line.toLowerCase(),j=l.findIndex(B=>_.isSeparator(B)||!Ye(B)?!1:B.name.toLowerCase().startsWith(E));j!==-1&&d(j),u.current=setTimeout(()=>{v.clearLine(0)},700)}}),A(()=>()=>{clearTimeout(u.current)},[]);let y=i.style.message(t.message,s),b=i.style.keysHelpTip([["\u2191\u2193","navigate"],["\u23CE","select"]]),P=0,L=Oe({items:l,active:h,renderItem({item:w,isActive:v,index:E}){if(_.isSeparator(w))return P++,` ${w.separator}`;let j=v?i.icon.cursor:" ",B=i.indexMode==="number"?`${E+1-P}. `:"";if(w.disabled){let te=typeof w.disabled=="string"?w.disabled:"(disabled)",er=v?i.icon.cursor:"-";return i.style.disabled(`${er} ${B}${w.name} ${te}`)}return(v?i.style.highlight:te=>te)(`${j} ${B}${w.name}`)},pageSize:n,loop:r});if(s==="done")return[c,y,i.style.answer(m.short)].filter(Boolean).join(" ");let{description:R}=m;return`${[[c,y].filter(Boolean).join(" "),L," ",R?i.style.description(R):"",x?i.style.error(x):"",b].filter(Boolean).join(`
19
+ `).trimEnd()}${$t}`});async function Qt(t){let e=new Map;for(let s of t.projects){let a=e.get(s.name);a?a.push(s.version):e.set(s.name,[s.version])}let r=Array.from(e.keys()).sort(),n=await Pe({message:"Choose project name:",choices:r.map(s=>({name:s,value:s})),pageSize:15}),i=(e.get(n)??[]).sort(),o=await Pe({message:"Choose project version:",choices:i.map(s=>({name:s,value:s})),pageSize:15});return{projectName:n,projectVersion:o}}var Zt=process.cwd();(async()=>{let{projectName:t,referenceProjectVersion:e,targetProjectVersion:r}=await Zr();await lt({workingDir:Zt,projectName:t,referenceProjectVersion:e,targetProjectVersion:r})})();async function Zr(){let t=process.argv[2];if(!t)return en();let e=process.argv[3];if(!e)throw new Error("Missing reference project version.");let r=process.argv[4];if(!r)throw new Error("Missing target project version.");return{projectName:t,referenceProjectVersion:e,targetProjectVersion:r}}async function en(){try{let t=await new k(Zt).loadProjectConfig(),{projectName:e,projectVersion:r}=await Qt(t),n=await ze({message:`Enter the target project version (e.g. ${r}):`,required:!0});return await Xe({message:`New project ${e}@${n} will be added based on ${r}.
20
20
  Do you want to proceed?`})||(console.log("Aborted."),process.exit(0)),{projectName:e,referenceProjectVersion:r,targetProjectVersion:n}}catch(t){console.error(`Error: ${t}`),process.exitCode=1;return}}