@visulima/vis 1.0.0-alpha.11 → 1.0.0-alpha.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/CHANGELOG.md +101 -0
  2. package/LICENSE.md +559 -186
  3. package/README.md +18 -0
  4. package/dist/bin.js +1 -9
  5. package/dist/config/index.d.ts +477 -556
  6. package/dist/config/index.js +1 -2
  7. package/dist/generate/index.js +1 -3
  8. package/dist/packem_chunks/applyDefaults.js +2 -336
  9. package/dist/packem_chunks/bin.js +234 -9552
  10. package/dist/packem_chunks/doctor-probe.js +2 -112
  11. package/dist/packem_chunks/fix.js +11 -234
  12. package/dist/packem_chunks/handler.js +1 -99
  13. package/dist/packem_chunks/handler10.js +2 -53
  14. package/dist/packem_chunks/handler11.js +1 -32
  15. package/dist/packem_chunks/handler12.js +5 -100
  16. package/dist/packem_chunks/handler13.js +1 -25
  17. package/dist/packem_chunks/handler14.js +18 -916
  18. package/dist/packem_chunks/handler15.js +15 -201
  19. package/dist/packem_chunks/handler16.js +1 -124
  20. package/dist/packem_chunks/handler17.js +1 -13
  21. package/dist/packem_chunks/handler18.js +1 -106
  22. package/dist/packem_chunks/handler19.js +1 -19
  23. package/dist/packem_chunks/handler2.js +2 -75
  24. package/dist/packem_chunks/handler20.js +5 -29
  25. package/dist/packem_chunks/handler21.js +1 -222
  26. package/dist/packem_chunks/handler22.js +1 -237
  27. package/dist/packem_chunks/handler23.js +5 -101
  28. package/dist/packem_chunks/handler24.js +1 -110
  29. package/dist/packem_chunks/handler25.js +3 -402
  30. package/dist/packem_chunks/handler26.js +1 -13
  31. package/dist/packem_chunks/handler27.js +1 -63
  32. package/dist/packem_chunks/handler28.js +7 -34
  33. package/dist/packem_chunks/handler29.js +21 -456
  34. package/dist/packem_chunks/handler3.js +4 -95
  35. package/dist/packem_chunks/handler30.js +3 -170
  36. package/dist/packem_chunks/handler31.js +1 -530
  37. package/dist/packem_chunks/handler32.js +2 -214
  38. package/dist/packem_chunks/handler33.js +25 -119
  39. package/dist/packem_chunks/handler34.js +2 -630
  40. package/dist/packem_chunks/handler35.js +3 -283
  41. package/dist/packem_chunks/handler36.js +22 -542
  42. package/dist/packem_chunks/handler37.js +410 -744
  43. package/dist/packem_chunks/handler38.js +22 -989
  44. package/dist/packem_chunks/handler39.js +22 -574
  45. package/dist/packem_chunks/handler4.js +2 -90
  46. package/dist/packem_chunks/handler40.js +22 -1685
  47. package/dist/packem_chunks/handler41.js +6 -1088
  48. package/dist/packem_chunks/handler42.js +5 -797
  49. package/dist/packem_chunks/handler43.js +10 -2658
  50. package/dist/packem_chunks/handler44.js +51 -3784
  51. package/dist/packem_chunks/handler45.js +25 -2574
  52. package/dist/packem_chunks/handler46.js +3 -3769
  53. package/dist/packem_chunks/handler47.js +21 -1485
  54. package/dist/packem_chunks/handler48.js +42 -0
  55. package/dist/packem_chunks/handler5.js +8 -174
  56. package/dist/packem_chunks/handler6.js +1 -95
  57. package/dist/packem_chunks/handler7.js +1 -115
  58. package/dist/packem_chunks/handler8.js +1 -12
  59. package/dist/packem_chunks/handler9.js +1 -29
  60. package/dist/packem_chunks/heal-accept.js +10 -522
  61. package/dist/packem_chunks/heal.js +14 -673
  62. package/dist/packem_chunks/index.js +7 -873
  63. package/dist/packem_chunks/loader.js +1 -23
  64. package/dist/packem_chunks/tar.js +3 -0
  65. package/dist/packem_shared/ai-analysis-hm8d2W7z.js +67 -0
  66. package/dist/packem_shared/ai-cache-DoiF80AR.js +1 -0
  67. package/dist/packem_shared/ai-fix-nn4zOE95.js +43 -0
  68. package/dist/packem_shared/cache-directory-CwHlJhgx.js +1 -0
  69. package/dist/packem_shared/dependency-scan-COr5n63B.js +2 -0
  70. package/dist/packem_shared/docker-D6OGr5_S.js +2 -0
  71. package/dist/packem_shared/failure-log-iUVLf6ts.js +2 -0
  72. package/dist/packem_shared/flakiness-D9wf0t56.js +1 -0
  73. package/dist/packem_shared/giget-CcEy_Elm.js +2 -0
  74. package/dist/packem_shared/index-DH-5hsrC.js +1 -0
  75. package/dist/packem_shared/otel-DxDUPJJH.js +6 -0
  76. package/dist/packem_shared/otelPlugin-CQq6poq8.js +1 -0
  77. package/dist/packem_shared/registry-CkubDdiY.js +2 -0
  78. package/dist/packem_shared/run-summary-utils-BfBvjzhY.js +1 -0
  79. package/dist/packem_shared/runtime-check-BXZ43CBW.js +1 -0
  80. package/dist/packem_shared/selectors-BylODRiM.js +3 -0
  81. package/dist/packem_shared/symbols-CQmER5MT.js +1 -0
  82. package/dist/packem_shared/toolchain-BgBOUHII.js +5 -0
  83. package/dist/packem_shared/typosquats-CcZl99B1.js +1 -0
  84. package/dist/packem_shared/use-measured-height-DjYgUOKk.js +1 -0
  85. package/dist/packem_shared/utils-DrNg0XTR.js +1 -0
  86. package/dist/packem_shared/verify-Baj5mFJ7.js +1 -0
  87. package/dist/packem_shared/vis-update-app-D1jl0UZZ.js +1 -0
  88. package/dist/packem_shared/xxh3-DrAUNq4n.js +1 -0
  89. package/index.js +556 -727
  90. package/package.json +19 -29
  91. package/schemas/project.schema.json +739 -297
  92. package/schemas/vis-config.schema.json +3365 -384
  93. package/templates/buildkite-ci/template.yml +20 -20
  94. package/dist/packem_shared/VisUpdateApp-D-Yz_wvg.js +0 -1316
  95. package/dist/packem_shared/_commonjsHelpers-BqLXS_qQ.js +0 -5
  96. package/dist/packem_shared/ai-analysis-CHeB1joD.js +0 -367
  97. package/dist/packem_shared/ai-cache-Be_jexe4.js +0 -142
  98. package/dist/packem_shared/ai-fix-B9iQVcD2.js +0 -379
  99. package/dist/packem_shared/cache-directory-2qvs4goY.js +0 -98
  100. package/dist/packem_shared/catalog-BJTtyi-O.js +0 -1371
  101. package/dist/packem_shared/dependency-scan-A0KSklpG.js +0 -188
  102. package/dist/packem_shared/docker-2iZzc280.js +0 -181
  103. package/dist/packem_shared/failure-log-Cz3Z4SKL.js +0 -100
  104. package/dist/packem_shared/flakiness-goTxXuCX.js +0 -180
  105. package/dist/packem_shared/otel-DCvqCTz_.js +0 -158
  106. package/dist/packem_shared/otelPlugin-DFaLDvJf.js +0 -3
  107. package/dist/packem_shared/registry-CbqXI0rc.js +0 -272
  108. package/dist/packem_shared/run-summary-utils-PVMl4aIh.js +0 -130
  109. package/dist/packem_shared/runtime-check-Cobi3p6l.js +0 -127
  110. package/dist/packem_shared/selectors-SM69TfqC.js +0 -194
  111. package/dist/packem_shared/symbols-Ta7g2nU-.js +0 -14
  112. package/dist/packem_shared/toolchain-BdZd9eBi.js +0 -975
  113. package/dist/packem_shared/typosquats-C-bCh3PX.js +0 -1210
  114. package/dist/packem_shared/use-measured-height-CNP0vT4M.js +0 -20
  115. package/dist/packem_shared/utils-CthVdBPS.js +0 -40
  116. package/dist/packem_shared/xxh3-Ck8mXNg1.js +0 -239
@@ -1,458 +1,23 @@
1
- import { createRequire as __cjs_createRequire } from "node:module";
1
+ var re=Object.defineProperty;var V=(t,n)=>re(t,"name",{value:n,configurable:!0});import{dim as b,yellow as Y,cyan as Z,magenta as _,red as ee}from"@visulima/colorize";import{isAccessibleSync as G,readFileSync as B,writeFileSync as Q}from"@visulima/fs";import{readYamlSync as se}from"@visulima/fs/yaml";import{join as H}from"@visulima/path";import{r as oe,R as ae,A as ce,p as a,V as le,b as de,U as ue,t as ge,F as W}from"./bin.js";import{l as fe,f as pe,s as he}from"../packem_shared/dependency-scan-COr5n63B.js";var ve=Object.defineProperty,S=V((t,n)=>ve(t,"name",{value:n,configurable:!0}),"o");const L=S(t=>Array.isArray(t)?t.filter(n=>typeof n=="string"):[],"toStringArray"),K=S((t,n)=>{for(const r of n)if(r===t||r.endsWith("*")&&t.startsWith(r.slice(0,-1)))return!0;return!1},"matchesGlobList"),te=S(t=>{const n=H(t,"pnpm-workspace.yaml");if(!G(n))return{excludedPackages:[],ignoredAdvisories:[]};try{const r=se(n);return{excludedPackages:[],ignoredAdvisories:[...L(r?.auditConfig?.ignoreCves),...L(r?.auditConfig?.ignoreGhsas)]}}catch{return{excludedPackages:[],ignoredAdvisories:[]}}},"readPnpmAuditExclusions"),ne=S(t=>{const n=H(t,".yarnrc.yml");if(!G(n))return{excludedPackages:[],ignoredAdvisories:[]};try{const r=se(n);return{excludedPackages:L(r?.npmAuditExcludePackages),ignoredAdvisories:L(r?.npmAuditIgnoreAdvisories)}}catch{return{excludedPackages:[],ignoredAdvisories:[]}}},"readYarnAuditExclusions"),me=S((t,n)=>{switch(n){case"pnpm":return te(t);case"yarn":return ne(t);default:return{excludedPackages:[],ignoredAdvisories:[]}}},"readNativeAuditExclusions"),X=S((t,n,r)=>{if(K(t,n.ignoredAdvisories))return!0;if(r){for(const l of r)if(K(l,n.ignoredAdvisories))return!0}return!1},"isAdvisoryExcluded"),$e=S((t,n)=>K(t,n.excludedPackages),"isPackageExcluded"),ke=S((t,n,r)=>{if(r.length===0)return["No advisory IDs to sync."];const l=[];switch(t){case"bun":{l.push(`bun has no audit config file. Use CLI flags: bun audit ${r.map(f=>`--ignore ${f}`).join(" ")}`);break}case"npm":{l.push("npm has no native audit exclusion config. vis accepted risks are the only layer.");break}case"pnpm":{const f=H(n,"pnpm-workspace.yaml");if(!G(f)){l.push("pnpm-workspace.yaml not found. Cannot sync.");break}const h=te(n),k=new Set(h.ignoredAdvisories.filter(c=>c.startsWith("CVE-"))),m=new Set(h.ignoredAdvisories.filter(c=>c.startsWith("GHSA-"))),y=r.filter(c=>c.startsWith("CVE-")),$=r.filter(c=>c.startsWith("GHSA-")),p=[...new Set([...k,...y])],d=[...new Set([...m,...$])],v=y.filter(c=>!k.has(c)).length,w=$.filter(c=>!m.has(c)).length;if(v===0&&w===0){l.push("All advisory IDs already present in pnpm-workspace.yaml.");break}let g=B(f);if(p.length>0){const c=` ignoreCves:
2
+ ${p.map(x=>` - ${x}`).join(`
3
+ `)}
4
+ `;/auditConfig:/.test(g)?g=/ignoreCves:/.test(g)?g.replace(/ignoreCves:\s*\n(?:\s+-\s+(?:\S.*|[\t\v\f \u00A0\u1680\u2000-\u200A\u202F\u205F\u3000\uFEFF])\n)*/,c):g.replace(/auditConfig:\s*\n/,`auditConfig:
5
+ ${c}`):g=`${g.trimEnd()}
2
6
 
3
- const __cjs_require = __cjs_createRequire(import.meta.url);
7
+ auditConfig:
8
+ ${c}`,v>0&&l.push(`Added ${String(v)} new CVE${v===1?"":"s"} to pnpm-workspace.yaml (${String(p.length)} total)`)}if(d.length>0){const c=` ignoreGhsas:
9
+ ${d.map(x=>` - ${x}`).join(`
10
+ `)}
11
+ `;/auditConfig:/.test(g)&&(g=/ignoreGhsas:/.test(g)?g.replace(/ignoreGhsas:\s*\n(?:\s+-\s+(?:\S.*|[\t\v\f \u00A0\u1680\u2000-\u200A\u202F\u205F\u3000\uFEFF])\n)*/,c):g.replace(/(auditConfig:[\s\S]*?)(\n\S|\n?$)/m,`$1${c}$2`)),w>0&&l.push(`Added ${String(w)} new GHSA${w===1?"":"s"} to pnpm-workspace.yaml (${String(d.length)} total)`)}Q(f,g);break}case"yarn":{const f=H(n,".yarnrc.yml");if(!G(f)){l.push(".yarnrc.yml not found. Cannot sync.");break}const h=ne(n),k=new Set(h.ignoredAdvisories),m=[...new Set([...k,...r])],y=r.filter(d=>!k.has(d)).length;if(y===0){l.push("All advisory IDs already present in .yarnrc.yml.");break}let $=B(f);const p=`npmAuditIgnoreAdvisories:
12
+ ${m.map(d=>` - "${d}"`).join(`
13
+ `)}
14
+ `;$=/npmAuditIgnoreAdvisories:/.test($)?$.replace(/npmAuditIgnoreAdvisories:\s*\n(?:\s+-\s+(?:\S.*|[\t\v\f \u00A0\u1680\u2000-\u200A\u202F\u205F\u3000\uFEFF])\n)*/,p):`${$.trimEnd()}
4
15
 
5
- const __cjs_getProcess = typeof globalThis !== "undefined" && typeof globalThis.process !== "undefined" ? globalThis.process : process;
6
-
7
- const __cjs_getBuiltinModule = (module) => {
8
- // Check if we're in Node.js and version supports getBuiltinModule
9
- if (typeof __cjs_getProcess !== "undefined" && __cjs_getProcess.versions && __cjs_getProcess.versions.node) {
10
- const [major, minor] = __cjs_getProcess.versions.node.split(".").map(Number);
11
- // Node.js 20.16.0+ and 22.3.0+
12
- if (major > 22 || (major === 22 && minor >= 3) || (major === 20 && minor >= 16)) {
13
- return __cjs_getProcess.getBuiltinModule(module);
14
- }
15
- }
16
- // Fallback to createRequire
17
- return __cjs_require(module);
18
- };
19
-
20
- const {
21
- createInterface
22
- } = __cjs_getBuiltinModule("node:readline");
23
- import { green, dim, red, yellow } from '@visulima/colorize';
24
- import { readJsonSync, writeJsonSync } from '@visulima/fs';
25
- import { findPackageManagerSync } from '@visulima/package';
26
- import { join } from '@visulima/path';
27
- import { coerce } from 'semver';
28
- import { r as resolveInstaller, F as runAdd, a as buildSocketOptions, p as pail, f as fetchSocketReports, d as discoverWorkspace, x as runInstall, t as findAcceptedRisk, G as formatReportSummary, H as scoreLabel, I as formatAcceptedRiskSnippet, J as getFullPackageName, j as scoreColor, D as DEFAULT_LOW_SCORE_THRESHOLD } from './bin.js';
29
- import { r as runTyposquatCheck } from '../packem_shared/typosquats-C-bCh3PX.js';
30
- import { r as readCatalogs } from '../packem_shared/catalog-BJTtyi-O.js';
31
- import { p as parsePackageArgument, t as toStringArray } from '../packem_shared/utils-CthVdBPS.js';
32
-
33
- const buildCatalogRef = (catalogName) => catalogName === "default" ? "catalog:" : `catalog:${catalogName}`;
34
- const labelForCatalog = (catalogName) => catalogName === "default" ? "default catalog" : `catalog "${catalogName}"`;
35
- const resolveFromCatalogs = (name, catalogs) => {
36
- const matchedCatalogs = [];
37
- for (const [key, deps] of catalogs) {
38
- if (key.includes(":")) {
39
- continue;
40
- }
41
- if (deps.has(name)) {
42
- matchedCatalogs.push(key);
43
- }
44
- }
45
- if (matchedCatalogs.length === 0) {
46
- return void 0;
47
- }
48
- if (matchedCatalogs.length === 1) {
49
- const [only] = matchedCatalogs;
50
- return { source: labelForCatalog(only), spec: buildCatalogRef(only) };
51
- }
52
- const preferred = matchedCatalogs.find((c) => c === "default") ?? matchedCatalogs[0];
53
- const others = matchedCatalogs.filter((c) => c !== preferred);
54
- return {
55
- candidates: [...matchedCatalogs],
56
- conflict: true,
57
- source: `${labelForCatalog(preferred)} (also in: ${others.map(labelForCatalog).join(", ")})`,
58
- spec: buildCatalogRef(preferred)
59
- };
60
- };
61
- const resolveFromSiblings = (name, catalogs) => {
62
- const tally = /* @__PURE__ */ new Map();
63
- for (const [key, deps] of catalogs) {
64
- if (!key.includes(":")) {
65
- continue;
66
- }
67
- const range = deps.get(name);
68
- if (range !== void 0) {
69
- tally.set(range, (tally.get(range) ?? 0) + 1);
70
- }
71
- }
72
- if (tally.size === 0) {
73
- return void 0;
74
- }
75
- const entries = [...tally.entries()];
76
- const total = entries.reduce((a, [, count]) => a + count, 0);
77
- if (entries.length === 1) {
78
- const [[range]] = entries;
79
- return {
80
- source: `siblings (${String(total)} pkg${total === 1 ? "" : "s"} on ${range})`,
81
- spec: range
82
- };
83
- }
84
- const sorted = [...entries].sort((a, b) => b[1] - a[1]);
85
- const [chosen, chosenCount] = sorted[0];
86
- const others = sorted.slice(1).map(([range, count]) => `${range} (×${String(count)})`);
87
- return {
88
- candidates: sorted.map(([range]) => range),
89
- conflict: true,
90
- source: `siblings (most common: ${chosen} ×${String(chosenCount)}; conflicts: ${others.join(", ")})`,
91
- spec: chosen
92
- };
93
- };
94
- const conformToCatalog = (name, catalogs) => {
95
- const fromCatalog = resolveFromCatalogs(name, catalogs);
96
- if (fromCatalog) {
97
- return fromCatalog;
98
- }
99
- return resolveFromSiblings(name, catalogs);
100
- };
101
-
102
- const resolveLatestVersions = async (packageNames, timeoutMs = 1e4) => {
103
- const results = /* @__PURE__ */ new Map();
104
- const controller = new AbortController();
105
- const timeout = setTimeout(() => {
106
- controller.abort();
107
- }, timeoutMs);
108
- try {
109
- const fetches = packageNames.map(async (name) => {
110
- try {
111
- const response = await fetch(`https://registry.npmjs.org/${name}/latest`, {
112
- headers: { Accept: "application/json" },
113
- signal: controller.signal
114
- });
115
- if (response.ok) {
116
- const data = await response.json();
117
- if (data.version) {
118
- results.set(name, data.version);
119
- }
120
- }
121
- } catch {
122
- }
123
- });
124
- await Promise.all(fetches);
125
- } finally {
126
- clearTimeout(timeout);
127
- }
128
- return results;
129
- };
130
- const displaySecurityReports = (reports, minimumScore, acceptedRisks) => {
131
- const lowScorePackages = [];
132
- for (const report of reports.values()) {
133
- const { overall } = report.score;
134
- const color = scoreColor(overall);
135
- const pct = `${String(Math.round(overall * 100))}%`;
136
- const alertCount = report.alerts.length;
137
- const fullName = getFullPackageName(report);
138
- const accepted = findAcceptedRisk(fullName, report.version, acceptedRisks);
139
- const colorFunction = color === "red" ? red : color === "yellow" ? yellow : green;
140
- if (accepted) {
141
- pail.info(` ${colorFunction(pct)} ${formatReportSummary(report)} ${dim(`[accepted: ${accepted.reason}]`)}`);
142
- } else {
143
- pail.info(` ${colorFunction(pct)} ${formatReportSummary(report)}`);
144
- }
145
- if (alertCount > 0) {
146
- const critHigh = report.alerts.filter((a) => a.severity === "critical" || a.severity === "high").length;
147
- if (critHigh > 0) {
148
- pail.warn(` ${String(critHigh)} critical/high alert${critHigh === 1 ? "" : "s"}`);
149
- }
150
- }
151
- if (overall < minimumScore && !accepted) {
152
- lowScorePackages.push(report);
153
- }
154
- }
155
- return lowScorePackages;
156
- };
157
- const confirmLowScorePackages = async (lowScorePackages, minimumScore) => {
158
- const rl = createInterface({ input: process.stdin, output: process.stdout });
159
- const ask = (question) => new Promise((resolve) => {
160
- rl.question(question, (answer2) => {
161
- resolve(answer2.trim());
162
- });
163
- });
164
- const pct = String(Math.round(minimumScore * 100));
165
- pail.warn("");
166
- pail.warn(`${String(lowScorePackages.length)} package${lowScorePackages.length === 1 ? "" : "s"} scored below the minimum threshold (${pct}%):`);
167
- for (const report of lowScorePackages) {
168
- const name = getFullPackageName(report);
169
- const score = `${String(Math.round(report.score.overall * 100))}%`;
170
- pail.warn(` • ${name}@${report.version} — score: ${score} (${scoreLabel(report.score.overall)})`);
171
- }
172
- pail.warn("");
173
- const answer = await ask("Continue adding these packages? [y/N] ");
174
- if (answer.toLowerCase() !== "y" && answer.toLowerCase() !== "yes") {
175
- rl.close();
176
- return false;
177
- }
178
- const rememberAnswer = await ask("Remember this decision? (prints config snippet) [y/N] ");
179
- rl.close();
180
- if (rememberAnswer.toLowerCase() === "y" || rememberAnswer.toLowerCase() === "yes") {
181
- pail.notice("");
182
- pail.notice("Add the following to security.socket.acceptedRisks in vis.config.ts:");
183
- pail.notice("");
184
- for (const report of lowScorePackages) {
185
- const fullName = getFullPackageName(report);
186
- const snippet = formatAcceptedRiskSnippet(fullName, report.version, report.score.overall, "Reviewed and accepted");
187
- pail.notice(snippet);
188
- }
189
- pail.notice("");
190
- }
191
- return true;
192
- };
193
- const runSocketPreCheck = async (packages, socketOptions, minimumScore, acceptedRisks) => {
194
- const parsed = packages.map(parsePackageArgument);
195
- const coercedSpecs = /* @__PURE__ */ new Map();
196
- for (const p of parsed) {
197
- if (p.versionSpec) {
198
- const coerced = coerce(p.versionSpec);
199
- if (coerced) {
200
- coercedSpecs.set(p.name, coerced.version);
201
- }
202
- }
203
- }
204
- const needsResolution = parsed.filter((p) => !coercedSpecs.has(p.name)).map((p) => p.name);
205
- const resolvedVersions = needsResolution.length > 0 ? await resolveLatestVersions(needsResolution) : /* @__PURE__ */ new Map();
206
- const lookupPackages = [];
207
- for (const p of parsed) {
208
- const version = coercedSpecs.get(p.name) ?? resolvedVersions.get(p.name);
209
- if (version) {
210
- lookupPackages.push({ name: p.name, version });
211
- }
212
- }
213
- if (lookupPackages.length === 0) {
214
- return true;
215
- }
216
- pail.info("");
217
- pail.info("Socket.dev security check:");
218
- const reports = await fetchSocketReports(lookupPackages, socketOptions);
219
- if (reports.size === 0) {
220
- pail.info(" Could not fetch security data. Proceeding.");
221
- return true;
222
- }
223
- const lowScorePackages = displaySecurityReports(reports, minimumScore, acceptedRisks);
224
- if (lowScorePackages.length === 0) {
225
- pail.info("");
226
- return true;
227
- }
228
- if (!process.stdin.isTTY) {
229
- pail.warn(
230
- `Aborting: ${String(lowScorePackages.length)} package${lowScorePackages.length === 1 ? "" : "s"} below minimum score. Use --no-socket-check to skip.`
231
- );
232
- return false;
233
- }
234
- return confirmLowScorePackages(lowScorePackages, minimumScore);
235
- };
236
- const SIBLING_SECTIONS = ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"];
237
- const pickDepSection = (options) => {
238
- if (options.savePeer) {
239
- return "peerDependencies";
240
- }
241
- if (options.saveOptional) {
242
- return "optionalDependencies";
243
- }
244
- if (options.saveDev) {
245
- return "devDependencies";
246
- }
247
- return "dependencies";
248
- };
249
- const applyExactPrefix = (spec, exact) => {
250
- if (spec.startsWith("catalog:")) {
251
- return spec;
252
- }
253
- if (!exact) {
254
- return spec;
255
- }
256
- return spec.replace(/^[\^~]/, "");
257
- };
258
- const planConformedSpecs = async (packages, catalogs) => {
259
- const slots = [];
260
- for (const argument of packages) {
261
- const { name, versionSpec } = parsePackageArgument(argument);
262
- if (!name) {
263
- continue;
264
- }
265
- if (versionSpec !== void 0) {
266
- slots.push({ explicit: versionSpec, name });
267
- continue;
268
- }
269
- const conformed = conformToCatalog(name, catalogs);
270
- if (conformed) {
271
- if (conformed.conflict) {
272
- pail.warn(`${name}: ambiguous constraint — picking ${conformed.spec} (${conformed.source}). Pass ${name}@<version> to override.`);
273
- }
274
- slots.push({ entry: { name, source: conformed.source, spec: conformed.spec }, kind: "resolved", name });
275
- continue;
276
- }
277
- slots.push({ kind: "missing", name });
278
- }
279
- const missingNames = slots.filter((s) => "kind" in s && s.kind === "missing").map((s) => s.name);
280
- const latest = missingNames.length > 0 ? await resolveLatestVersions(missingNames) : /* @__PURE__ */ new Map();
281
- return slots.map((slot) => {
282
- if ("explicit" in slot) {
283
- return { name: slot.name, source: "explicit", spec: slot.explicit };
284
- }
285
- if (slot.kind === "resolved") {
286
- return slot.entry;
287
- }
288
- const version = latest.get(slot.name);
289
- if (version === void 0) {
290
- throw new Error(`--to: cannot resolve a version for "${slot.name}" (not in any catalog or sibling, and registry lookup failed). Pass ${slot.name}@<version> explicitly.`);
291
- }
292
- const spec = `^${version}`;
293
- pail.info(`${slot.name}: no existing constraint — using registry latest (${spec}). Add to a catalog to share this version across workspace packages.`);
294
- return { name: slot.name, source: "registry latest", spec };
295
- });
296
- };
297
- const applyPlannedSpecsToPackageJson = (pkgJson, planned, section, exact) => {
298
- for (const { name, spec } of planned) {
299
- const finalSpec = applyExactPrefix(spec, exact);
300
- for (const otherSection of SIBLING_SECTIONS) {
301
- if (otherSection === section) {
302
- continue;
303
- }
304
- const block2 = pkgJson[otherSection];
305
- if (block2?.[name] !== void 0) {
306
- delete block2[name];
307
- if (Object.keys(block2).length === 0) {
308
- delete pkgJson[otherSection];
309
- }
310
- }
311
- }
312
- let block = pkgJson[section];
313
- if (block === void 0) {
314
- block = {};
315
- pkgJson[section] = block;
316
- }
317
- block[name] = finalSpec;
318
- }
319
- };
320
- const applyConformedAdd = async ({
321
- ignoreScripts,
322
- logger,
323
- options,
324
- packages,
325
- pm,
326
- target,
327
- visConfig,
328
- workspaceRoot
329
- }) => {
330
- const { workspace } = discoverWorkspace(workspaceRoot, visConfig ?? {});
331
- const project = workspace.projects[target];
332
- if (!project) {
333
- const available = Object.keys(workspace.projects).sort();
334
- throw new Error(
335
- `--to: workspace package "${target}" not found. Available: ${available.length > 0 ? available.slice(0, 10).join(", ") : "(none)"}${available.length > 10 ? `, ... (${String(available.length - 10)} more)` : ""}.`
336
- );
337
- }
338
- const targetPkgPath = join(workspaceRoot, project.root, "package.json");
339
- const { packageManager } = findPackageManagerSync(workspaceRoot);
340
- const catalogs = readCatalogs(workspaceRoot, packageManager);
341
- const section = pickDepSection(options);
342
- const exact = options.exact ?? false;
343
- const planned = await planConformedSpecs(packages, catalogs);
344
- if (planned.length === 0) {
345
- return 0;
346
- }
347
- const pkgJson = readJsonSync(targetPkgPath);
348
- applyPlannedSpecsToPackageJson(pkgJson, planned, section, exact);
349
- writeJsonSync(targetPkgPath, pkgJson, { detectIndent: true, overwrite: true });
350
- for (const entry of planned) {
351
- const finalSpec = applyExactPrefix(entry.spec, exact);
352
- pail.info(`${green("+")} ${entry.name}@${finalSpec} → ${target}/${section} (${dim(entry.source)})`);
353
- }
354
- return runInstall(
355
- pm,
356
- {
357
- dev: false,
358
- filter: [],
359
- force: false,
360
- frozenLockfile: false,
361
- ignoreScripts,
362
- lockfileOnly: false,
363
- noOptional: false,
364
- offline: false,
365
- prod: false,
366
- recursive: false,
367
- silent: false,
368
- workspaceRoot: false
369
- },
370
- workspaceRoot,
371
- logger
372
- );
373
- };
374
- const execute = async ({ argument, logger, options, visConfig, workspaceRoot: wsRoot }) => {
375
- let packages = argument;
376
- if (!packages || packages.length === 0) {
377
- throw new Error("No packages specified. Usage: vis add <packages...>");
378
- }
379
- if (!options.noTyposquatCheck) {
380
- const parsed = packages.map((p) => parsePackageArgument(p));
381
- const result = await runTyposquatCheck(
382
- parsed.map((p) => p.name),
383
- visConfig?.security?.typosquatAllowlist
384
- );
385
- if (!result.ok) {
386
- process.exitCode = 1;
387
- return;
388
- }
389
- packages = parsed.map((p, i) => {
390
- const corrected = result.packages[i];
391
- if (corrected !== p.name) {
392
- return p.versionSpec ? `${corrected}@${p.versionSpec}` : corrected ?? "";
393
- }
394
- return packages[i] ?? "";
395
- });
396
- }
397
- if (!options.noSocketCheck) {
398
- const socketOptions = buildSocketOptions(visConfig?.security?.socket);
399
- if (socketOptions) {
400
- const minimumScore = socketOptions.minimumScore ?? DEFAULT_LOW_SCORE_THRESHOLD;
401
- const shouldContinue = await runSocketPreCheck(packages, socketOptions, minimumScore, visConfig?.security?.socket?.acceptedRisks);
402
- if (!shouldContinue) {
403
- process.exitCode = 1;
404
- return;
405
- }
406
- }
407
- }
408
- const cwd = process.cwd();
409
- const pm = resolveInstaller(wsRoot ?? cwd, { configBackend: visConfig?.install?.backend });
410
- const ignoreScripts = !options.runScripts;
411
- if (options.to) {
412
- if (options.global || options.workspaceRoot) {
413
- throw new Error("--to is incompatible with --global / --workspace-root.");
414
- }
415
- if (options.filter && toStringArray(options.filter).length > 0) {
416
- throw new Error("--to and --filter are mutually exclusive — --to already targets one package.");
417
- }
418
- if (!wsRoot) {
419
- throw new Error("--to requires a monorepo workspace. Run from inside a pnpm/bun/yarn/npm workspace.");
420
- }
421
- const code2 = await applyConformedAdd({
422
- ignoreScripts,
423
- logger,
424
- options,
425
- packages,
426
- pm,
427
- target: options.to,
428
- visConfig,
429
- workspaceRoot: wsRoot
430
- });
431
- if (code2 !== 0) {
432
- process.exitCode = code2;
433
- }
434
- return;
435
- }
436
- const code = runAdd(
437
- pm,
438
- {
439
- exact: options.exact || false,
440
- filter: toStringArray(options.filter),
441
- global: options.global || false,
442
- optional: options.saveOptional || false,
443
- packages,
444
- peer: options.savePeer || false,
445
- saveDev: options.saveDev || false,
446
- workspace: options.workspace || false,
447
- workspaceRoot: options.workspaceRoot || false
448
- },
449
- cwd,
450
- logger,
451
- { ignoreScripts }
452
- );
453
- if (code !== 0) {
454
- process.exitCode = code;
455
- }
456
- };
457
-
458
- export { execute as default };
16
+ ${p}`,Q(f,$),l.push(`Synced ${String(y)} advisor${y===1?"y":"ies"} to .yarnrc.yml (${String(m.length)} total)`);break}default:l.push(`Unknown package manager: ${t}`)}return l},"syncAcceptedRisksToNativeConfig");var ye=Object.defineProperty,R=V((t,n)=>ye(t,"name",{value:n,configurable:!0}),"m");const U={CRITICAL:0,HIGH:1,LOW:3,MODERATE:2,UNKNOWN:4},Ae={critical:ee,high:_,low:Z,medium:Y},j=R((t,n)=>{const r=U[n.toUpperCase()]??U.MODERATE??2;return(U[t.toUpperCase()]??4)<=r},"severityPassesFilter"),Se={CRITICAL:ee,HIGH:_,LOW:Z,MODERATE:Y,UNKNOWN:b},we=R((t,n,r,l)=>{const f=Se[r.severity]??b,h=l?` ${b("[acknowledged]")}`:"",k=r.fixedVersions??[],m=k.length>0?` (fix: ${k.join(", ")})`:"";return` ${f(r.severity)} ${r.id} — ${t}@${n}${h}
17
+ ${r.summary}${m}`},"formatVulnLine"),Ce=R((t,n)=>{const r=oe(t),l=`${String(Math.round(t.score.overall*100))}%`,f=n?` ${b("[acknowledged]")}`:"",h=t.alerts.length>0?`, ${String(t.alerts.length)} alert${t.alerts.length===1?"":"s"}`:"";return` ${l} ${r}@${t.version} (${ae(t.score.overall)}${h})${f}`},"formatSocketLine"),Re=R(async(t,n,r,l)=>{const f=n.severity??"low",h=n.format==="json"||!!n.json,k=!!n.fix,m=!!n.showAccepted,y=r?.security?.socket,$=y?.acceptedRisks,p=ce(t),d=me(t,p.name);(d.ignoredAdvisories.length>0||d.excludedPackages.length>0)&&a.info(`Loaded ${String(d.ignoredAdvisories.length)} ignored advisor${d.ignoredAdvisories.length===1?"y":"ies"} and ${String(d.excludedPackages.length)} excluded package${d.excludedPackages.length===1?"":"s"} from ${p.name} config.`);const v=fe(t,p.name);if(v.length===0){a.info(`No ${p.name} lockfile entries found. Run ${p.name} install first.`);return}h||a.info(`Scanning ${String(v.length)} installed packages…`);const w=v.map(e=>({name:e.name,version:e.version})),g=le(y),c=pe(t,p.name),x=[{id:"vulnerabilities",label:"Known vulnerabilities (OSV)"},...g?[{id:"socket",label:"Socket.dev supply-chain reports"}]:[]],C=he(x,{live:!h}),ie=Date.now(),E=R(e=>{const s=Date.now()-e;return s>=1e3?`${(s/1e3).toFixed(1)}s`:`${String(Math.round(s))}ms`},"fmtElapsed");let q,J;try{const e=Date.now(),s=Date.now();C.start("vulnerabilities"),g&&C.start("socket"),[q,J]=await Promise.all([de(w).then(i=>{let o=0;for(const u of i.values())o+=u.length;return C.finish("vulnerabilities",o>0?"warn":"ok",o>0?`${String(o)} found · ${E(e)}`:`none found · ${E(e)}`),i}).catch(i=>{const o=i instanceof Error?i.message:String(i);return C.finish("vulnerabilities","error",o),new Map}),g?ue(w,g).then(i=>{let o=0,u=0;for(const D of i.values())o+=D.alerts.length,D.score.overall<W&&(u+=1);const O=o+u;return C.finish("socket",O>0?"warn":"ok",O>0?`${String(o)} alert${o===1?"":"s"}, ${String(u)} low-score · ${E(s)}`:`clean · ${E(s)}`),i}).catch(i=>{const o=i instanceof Error?i.message:String(i);return C.finish("socket","error",o),new Map}):Promise.resolve(new Map)])}finally{C.stop()}h||a.info(b(`Scan completed in ${E(ie)}`));const M=[];for(const e of v){if($e(e.name,d))continue;const s=q.get(e.name)??[],i=J.get(`${e.name}@${e.version}`),o=ge(e.name,e.version,$),u=s.length>0,O=i?i.score.overall<W:!1,D=i?i.alerts.length>0:!1;(u||O||D)&&M.push({acceptedRisk:o,name:e.name,socketReport:i,version:e.version,vulnerabilities:s})}const A=M.filter(e=>{const s=e.vulnerabilities.some(u=>j(u.severity,f)),i=e.socketReport?.alerts.some(u=>j(u.severity==="medium"?"MODERATE":u.severity.toUpperCase(),f)),o=e.socketReport&&e.socketReport.score.overall<W;return s||i||o});if(h){const e={duplicates:c.map(s=>({name:s.name,versionCount:s.versions.length,versions:s.versions})),packages:v.length,results:A.map(s=>({acceptedRisk:s.acceptedRisk??null,name:s.name,socketAlerts:s.socketReport?.alerts??[],socketScore:s.socketReport?.score.overall??null,version:s.version,vulnerabilities:s.vulnerabilities})),summary:{accepted:A.filter(s=>s.acceptedRisk).length,duplicatePackages:c.length,issues:A.filter(s=>!s.acceptedRisk).length,total:A.length}};process.stdout.write(`${JSON.stringify(e,void 0,2)}
18
+ `),n.exitCode&&e.summary.issues>0&&(process.exitCode=1);return}if(A.length===0){a.success(`No security issues found across ${String(v.length)} packages.`);return}const I={CRITICAL:[],HIGH:[],LOW:[],MODERATE:[]};for(const e of A)for(const s of e.vulnerabilities)if(j(s.severity,f)){const i=s.severity==="UNKNOWN"?"LOW":s.severity;I[i]?.push({entry:e,vuln:s})}let F=0,T=0;for(const e of["CRITICAL","HIGH","MODERATE","LOW"]){const s=I[e];if(!(!s||s.length===0)){a.info(`
19
+ ── ${e} (${String(s.length)}) ──`);for(const{entry:i,vuln:o}of s){const u=!!i.acceptedRisk||X(o.id,d,o.aliases);u&&(T++,!m)||(F++,a.info(we(i.name,i.version,o,u)),k&&(o.fixedVersions??[]).length>0&&a.notice(` Fix: update to ${o.fixedVersions.at(-1)}`))}}}const P=A.filter(e=>e.socketReport&&(e.socketReport.score.overall<W||e.socketReport.alerts.length>0));if(P.length>0){a.info(`
20
+ ── Socket.dev Supply Chain (${String(P.length)}) ──`);for(const e of P){if(!e.socketReport)continue;const s=!!e.acceptedRisk;if(!(s&&!m)){a.info(Ce(e.socketReport,s));for(const i of e.socketReport.alerts){const o=Ae[i.severity]??b;a.info(` ${o(`[${i.severity.toUpperCase()}]`)} ${i.type} — ${i.category}`)}}}}if(c.length>0){a.info(`
21
+ ── Duplicate Dependencies (${String(c.length)}) ──`);for(const e of c){const s=e.versions.join(", ");a.info(` ${e.name} — ${String(e.versions.length)} versions: ${Y(s)}`)}}const N=R(e=>!!e.acceptedRisk||e.vulnerabilities.length>0&&e.vulnerabilities.every(s=>X(s.id,d,s.aliases)),"isEntryExcluded"),z=A.filter(e=>!N(e)).length;if(a.info(""),a.info("─ Audit Summary"),a.info(` ${String(v.length)} packages scanned`),d.ignoredAdvisories.length>0&&a.info(` ${String(d.ignoredAdvisories.length)} ${p.name} audit exclusion${d.ignoredAdvisories.length===1?"":"s"} applied`),F>0){const e=I.CRITICAL?.filter(i=>!N(i.entry)).length??0,s=I.HIGH?.filter(i=>!N(i.entry)).length??0;a.error(` ${String(F)} vulnerabilit${F===1?"y":"ies"} found`),e>0&&a.error(` ${String(e)} critical`),s>0&&a.warn(` ${String(s)} high`)}else a.success(" No vulnerabilities found");if(P.length>0){const e=P.filter(s=>!N(s)).length;a.warn(` ${String(e)} package${e===1?"":"s"} with Socket.dev supply chain issues`)}if(c.length>0&&(a.warn(` ${String(c.length)} package${c.length===1?"":"s"} with duplicate versions`),a.notice(" Run 'vis dedupe' or your package manager's dedupe command to reduce duplicates.")),T>0&&(a.info(` ${String(T)} acknowledged (accepted risks)`),m||a.notice(" Use --show-accepted to see acknowledged issues.")),z===0&&a.success(`
22
+ All issues are acknowledged. No action required.`),n.sync&&$){const e=new Set;for(const i of M)if(i.acceptedRisk){for(const o of i.vulnerabilities)if((o.id.startsWith("CVE-")||o.id.startsWith("GHSA-"))&&e.add(o.id),o.aliases)for(const u of o.aliases)(u.startsWith("CVE-")||u.startsWith("GHSA-"))&&e.add(u)}const s=[...e];if(s.length>0){a.info("");const i=ke(p.name,t,s);for(const o of i)a.success(` ${o}`)}else a.info(`
23
+ No advisory IDs to sync to native PM config.`)}n.exitCode&&z>0&&(process.exitCode=1)},"executeAudit"),Oe=R(async({logger:t,options:n,visConfig:r,workspaceRoot:l})=>{if(!l)throw new Error("Could not determine workspace root. Run this command inside a monorepo.");await Re(l,n,r,t)},"execute");export{Oe as default};
@@ -1,95 +1,4 @@
1
- import { findPackageManagerSync } from '@visulima/package';
2
- import { v as validateAnalysisType, r as runAiAnalysis, f as formatAiAnalysis } from '../packem_shared/ai-analysis-CHeB1joD.js';
3
- import { f as fetchSocketReports, a as buildSocketOptions } from './bin.js';
4
- import { r as readCatalogs, f as fetchPackageVersions, p as parseVersion, a as fetchVulnerabilities, g as getUpdateType, e as extractPrefix } from '../packem_shared/catalog-BJTtyi-O.js';
5
-
6
- const VERSION_PREFIX_REGEX = /^[\^~>=<]+/;
7
- const execute = async ({ argument, logger, options, visConfig, workspaceRoot: wsRoot }) => {
8
- if (!wsRoot) {
9
- throw new Error("Could not determine workspace root. Run this command inside a monorepo.");
10
- }
11
- const positionalArguments = argument;
12
- const packageName = positionalArguments[0];
13
- if (!packageName) {
14
- throw new Error("Package name is required. Usage: vis analyze <package> [version]");
15
- }
16
- const targetVersionArgument = positionalArguments[1];
17
- const { packageManager } = findPackageManagerSync(wsRoot);
18
- let currentRange;
19
- let catalogName = "default";
20
- const catalogs = readCatalogs(wsRoot, packageManager);
21
- for (const [name, deps] of catalogs) {
22
- const range = deps.get(packageName);
23
- if (range) {
24
- currentRange = range;
25
- catalogName = name;
26
- break;
27
- }
28
- }
29
- if (!currentRange) {
30
- throw new Error(`Package "${packageName}" not found in any catalog or package.json. Make sure it exists in your workspace dependencies.`);
31
- }
32
- let targetVersion;
33
- if (targetVersionArgument) {
34
- targetVersion = targetVersionArgument;
35
- } else {
36
- logger.info(`Fetching latest version for ${packageName}...
37
- `);
38
- const info = await fetchPackageVersions(packageName);
39
- if (!info.latest) {
40
- throw new Error(`Could not determine latest version for "${packageName}".`);
41
- }
42
- targetVersion = info.latest;
43
- }
44
- const current = parseVersion(currentRange);
45
- const target = parseVersion(targetVersion);
46
- if (!current || !target) {
47
- throw new Error(`Could not parse versions: current="${currentRange}", target="${targetVersion}".`);
48
- }
49
- const updateType = getUpdateType(current, target);
50
- if (updateType === "none") {
51
- logger.info(`${packageName} is already at ${targetVersion}. Nothing to analyze.`);
52
- return;
53
- }
54
- const prefix = extractPrefix(currentRange);
55
- const entry = {
56
- catalogName,
57
- currentRange,
58
- newRange: `${prefix}${targetVersion}`,
59
- packageName,
60
- targetVersion,
61
- updateType
62
- };
63
- const analysisType = validateAnalysisType(options.aiType ?? "impact");
64
- if (analysisType === "security" || options.security) {
65
- logger.info("Checking for known vulnerabilities...\n");
66
- const version = currentRange.replace(VERSION_PREFIX_REGEX, "");
67
- const vulnMap = await fetchVulnerabilities([{ name: packageName, version }]);
68
- const vulns = vulnMap.get(packageName);
69
- if (vulns && vulns.length > 0) {
70
- entry.vulnerabilities = vulns;
71
- }
72
- const socketOptions = buildSocketOptions(visConfig?.security?.socket);
73
- if (socketOptions) {
74
- const reports = await fetchSocketReports([{ name: packageName, version }], socketOptions);
75
- const report = reports.get(`${packageName}@${version}`);
76
- if (report) {
77
- entry.socketReport = {
78
- alerts: report.alerts,
79
- license: report.license,
80
- score: report.score
81
- };
82
- }
83
- }
84
- }
85
- const result = await runAiAnalysis([entry], logger, visConfig?.ai, analysisType);
86
- const format = options.format ?? "table";
87
- if (format === "json") {
88
- process.stdout.write(`${JSON.stringify(result, void 0, 2)}
89
- `);
90
- } else {
91
- logger.info(formatAiAnalysis(result));
92
- }
93
- };
94
-
95
- export { execute as default };
1
+ var x=Object.defineProperty;var h=(n,t)=>x(n,"name",{value:t,configurable:!0});import{findPackageManagerSync as N}from"@visulima/package";import{H as P,e as U,Z as j}from"../packem_shared/ai-analysis-hm8d2W7z.js";import{g as M,a as O,E as b,i as T,L as z,b as S,V,U as q}from"./bin.js";var A=Object.defineProperty,F=h((n,t)=>A(n,"name",{value:t,configurable:!0}),"x");const H=/^[\^~>=<]+/,B=F(async({argument:n,logger:t,options:f,visConfig:u,workspaceRoot:g})=>{if(!g)throw new Error("Could not determine workspace root. Run this command inside a monorepo.");const p=n,e=p[0];if(!e)throw new Error("Package name is required. Usage: vis analyze <package> [version]");const m=p[1],{packageManager:E}=N(g);let o,w="default";const C=M(g,E);for(const[a,i]of C){const s=i.get(e);if(s){o=s,w=a;break}}if(!o)throw new Error(`Package "${e}" not found in any catalog or package.json. Make sure it exists in your workspace dependencies.`);let r;if(m)r=m;else{t.info(`Fetching latest version for ${e}...
2
+ `);const a=await O(e);if(!a.latest)throw new Error(`Could not determine latest version for "${e}".`);r=a.latest}const d=b(o),k=b(r);if(!d||!k)throw new Error(`Could not parse versions: current="${o}", target="${r}".`);const y=T(d,k);if(y==="none"){t.info(`${e} is already at ${r}. Nothing to analyze.`);return}const R=z(o),l={catalogName:w,currentRange:o,newRange:`${R}${r}`,packageName:e,targetVersion:r,updateType:y},v=P(f.aiType??"impact");if(v==="security"||f.security){t.info(`Checking for known vulnerabilities...
3
+ `);const a=o.replace(H,""),i=(await S([{name:e,version:a}])).get(e);i&&i.length>0&&(l.vulnerabilities=i);const s=V(u?.security?.socket);if(s){const c=(await q([{name:e,version:a}],s)).get(`${e}@${a}`);c&&(l.socketReport={alerts:c.alerts,license:c.license,score:c.score})}}const $=await U([l],t,u?.ai,v);(f.format??"table")==="json"?process.stdout.write(`${JSON.stringify($,void 0,2)}
4
+ `):t.info(j($))},"execute");export{B as default};