@pellux/goodvibes-sdk 0.25.0 → 0.25.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/dist/_internal/platform/intelligence/lsp/service.d.ts.map +1 -1
  2. package/dist/_internal/platform/intelligence/lsp/service.js +18 -9
  3. package/dist/_internal/platform/providers/anthropic-vertex.d.ts.map +1 -1
  4. package/dist/_internal/platform/providers/anthropic-vertex.js +135 -2
  5. package/dist/_internal/platform/version.js +1 -1
  6. package/dist/_internal/platform/watchers/registry.d.ts.map +1 -1
  7. package/dist/_internal/platform/watchers/registry.js +4 -1
  8. package/package.json +9 -8
  9. package/vendor/bash-language-server/CHANGELOG.md +453 -0
  10. package/vendor/bash-language-server/GOODVIBES_PATCH.md +22 -0
  11. package/vendor/bash-language-server/README.md +230 -0
  12. package/vendor/bash-language-server/out/analyser.d.ts +187 -0
  13. package/vendor/bash-language-server/out/analyser.js +782 -0
  14. package/vendor/bash-language-server/out/analyser.js.map +1 -0
  15. package/vendor/bash-language-server/out/builtins.d.ts +2 -0
  16. package/vendor/bash-language-server/out/builtins.js +71 -0
  17. package/vendor/bash-language-server/out/builtins.js.map +1 -0
  18. package/vendor/bash-language-server/out/cli.d.ts +3 -0
  19. package/vendor/bash-language-server/out/cli.js +74 -0
  20. package/vendor/bash-language-server/out/cli.js.map +1 -0
  21. package/vendor/bash-language-server/out/config.d.ts +88 -0
  22. package/vendor/bash-language-server/out/config.js +96 -0
  23. package/vendor/bash-language-server/out/config.js.map +1 -0
  24. package/vendor/bash-language-server/out/executables.d.ts +19 -0
  25. package/vendor/bash-language-server/out/executables.js +86 -0
  26. package/vendor/bash-language-server/out/executables.js.map +1 -0
  27. package/vendor/bash-language-server/out/parser.d.ts +2 -0
  28. package/vendor/bash-language-server/out/parser.js +36 -0
  29. package/vendor/bash-language-server/out/parser.js.map +1 -0
  30. package/vendor/bash-language-server/out/reserved-words.d.ts +2 -0
  31. package/vendor/bash-language-server/out/reserved-words.js +33 -0
  32. package/vendor/bash-language-server/out/reserved-words.js.map +1 -0
  33. package/vendor/bash-language-server/out/server.d.ts +56 -0
  34. package/vendor/bash-language-server/out/server.js +756 -0
  35. package/vendor/bash-language-server/out/server.js.map +1 -0
  36. package/vendor/bash-language-server/out/shellcheck/config.d.ts +5 -0
  37. package/vendor/bash-language-server/out/shellcheck/config.js +17 -0
  38. package/vendor/bash-language-server/out/shellcheck/config.js.map +1 -0
  39. package/vendor/bash-language-server/out/shellcheck/directive.d.ts +18 -0
  40. package/vendor/bash-language-server/out/shellcheck/directive.js +62 -0
  41. package/vendor/bash-language-server/out/shellcheck/directive.js.map +1 -0
  42. package/vendor/bash-language-server/out/shellcheck/index.d.ts +22 -0
  43. package/vendor/bash-language-server/out/shellcheck/index.js +229 -0
  44. package/vendor/bash-language-server/out/shellcheck/index.js.map +1 -0
  45. package/vendor/bash-language-server/out/shellcheck/types.d.ts +175 -0
  46. package/vendor/bash-language-server/out/shellcheck/types.js +35 -0
  47. package/vendor/bash-language-server/out/shellcheck/types.js.map +1 -0
  48. package/vendor/bash-language-server/out/shfmt/index.d.ts +18 -0
  49. package/vendor/bash-language-server/out/shfmt/index.js +151 -0
  50. package/vendor/bash-language-server/out/shfmt/index.js.map +1 -0
  51. package/vendor/bash-language-server/out/snippets.d.ts +2 -0
  52. package/vendor/bash-language-server/out/snippets.js +671 -0
  53. package/vendor/bash-language-server/out/snippets.js.map +1 -0
  54. package/vendor/bash-language-server/out/types.d.ts +13 -0
  55. package/vendor/bash-language-server/out/types.js +12 -0
  56. package/vendor/bash-language-server/out/types.js.map +1 -0
  57. package/vendor/bash-language-server/out/util/array.d.ts +14 -0
  58. package/vendor/bash-language-server/out/util/array.js +36 -0
  59. package/vendor/bash-language-server/out/util/array.js.map +1 -0
  60. package/vendor/bash-language-server/out/util/async.d.ts +13 -0
  61. package/vendor/bash-language-server/out/util/async.js +24 -0
  62. package/vendor/bash-language-server/out/util/async.js.map +1 -0
  63. package/vendor/bash-language-server/out/util/declarations.d.ts +88 -0
  64. package/vendor/bash-language-server/out/util/declarations.js +295 -0
  65. package/vendor/bash-language-server/out/util/declarations.js.map +1 -0
  66. package/vendor/bash-language-server/out/util/discriminate.d.ts +1 -0
  67. package/vendor/bash-language-server/out/util/discriminate.js +7 -0
  68. package/vendor/bash-language-server/out/util/discriminate.js.map +1 -0
  69. package/vendor/bash-language-server/out/util/fs.d.ts +6 -0
  70. package/vendor/bash-language-server/out/util/fs.js +73 -0
  71. package/vendor/bash-language-server/out/util/fs.js.map +1 -0
  72. package/vendor/bash-language-server/out/util/logger.d.ts +35 -0
  73. package/vendor/bash-language-server/out/util/logger.js +105 -0
  74. package/vendor/bash-language-server/out/util/logger.js.map +1 -0
  75. package/vendor/bash-language-server/out/util/lsp.d.ts +5 -0
  76. package/vendor/bash-language-server/out/util/lsp.js +13 -0
  77. package/vendor/bash-language-server/out/util/lsp.js.map +1 -0
  78. package/vendor/bash-language-server/out/util/platform.d.ts +1 -0
  79. package/vendor/bash-language-server/out/util/platform.js +7 -0
  80. package/vendor/bash-language-server/out/util/platform.js.map +1 -0
  81. package/vendor/bash-language-server/out/util/sh.d.ts +16 -0
  82. package/vendor/bash-language-server/out/util/sh.js +132 -0
  83. package/vendor/bash-language-server/out/util/sh.js.map +1 -0
  84. package/vendor/bash-language-server/out/util/shebang.d.ts +10 -0
  85. package/vendor/bash-language-server/out/util/shebang.js +53 -0
  86. package/vendor/bash-language-server/out/util/shebang.js.map +1 -0
  87. package/vendor/bash-language-server/out/util/sourcing.d.ts +15 -0
  88. package/vendor/bash-language-server/out/util/sourcing.js +182 -0
  89. package/vendor/bash-language-server/out/util/sourcing.js.map +1 -0
  90. package/vendor/bash-language-server/out/util/tree-sitter.d.ts +22 -0
  91. package/vendor/bash-language-server/out/util/tree-sitter.js +110 -0
  92. package/vendor/bash-language-server/out/util/tree-sitter.js.map +1 -0
  93. package/vendor/bash-language-server/package.json +52 -0
  94. package/vendor/bash-language-server/parser.info +2 -0
  95. package/vendor/bash-language-server/tree-sitter-bash.wasm +0 -0
  96. package/scripts/postinstall-patch-minimatch.mjs +0 -285
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.forEach = forEach;
4
+ exports.range = range;
5
+ exports.isDefinition = isDefinition;
6
+ exports.isReference = isReference;
7
+ exports.isVariableInReadCommand = isVariableInReadCommand;
8
+ exports.isExpansion = isExpansion;
9
+ exports.findParent = findParent;
10
+ exports.findParentOfType = findParentOfType;
11
+ exports.resolveStaticString = resolveStaticString;
12
+ const LSP = require("vscode-languageserver/node");
13
+ /**
14
+ * Recursively iterate over all nodes in a tree.
15
+ *
16
+ * @param node The node to start iterating from
17
+ * @param callback The callback to call for each node. Return false to stop following children.
18
+ */
19
+ function forEach(node, callback) {
20
+ const followChildren = callback(node) !== false;
21
+ if (followChildren && node.children.length) {
22
+ node.children.forEach((n) => forEach(n, callback));
23
+ }
24
+ }
25
+ function range(n) {
26
+ return LSP.Range.create(n.startPosition.row, n.startPosition.column, n.endPosition.row, n.endPosition.column);
27
+ }
28
+ function isDefinition(n) {
29
+ switch (n.type) {
30
+ case 'variable_assignment':
31
+ case 'function_definition':
32
+ return true;
33
+ default:
34
+ return false;
35
+ }
36
+ }
37
+ function isReference(n) {
38
+ switch (n.type) {
39
+ case 'variable_name':
40
+ case 'command_name':
41
+ return true;
42
+ default:
43
+ return false;
44
+ }
45
+ }
46
+ function isVariableInReadCommand(n) {
47
+ var _a, _b, _c, _d;
48
+ if (n.type === 'word' &&
49
+ ((_a = n.parent) === null || _a === void 0 ? void 0 : _a.type) === 'command' &&
50
+ ((_b = n.parent.firstChild) === null || _b === void 0 ? void 0 : _b.text) === 'read' &&
51
+ !n.text.startsWith('-') &&
52
+ !/^-.*[dinNptu]$/.test((_d = (_c = n.previousSibling) === null || _c === void 0 ? void 0 : _c.text) !== null && _d !== void 0 ? _d : '')) {
53
+ return true;
54
+ }
55
+ return false;
56
+ }
57
+ function isExpansion(n) {
58
+ switch (n.type) {
59
+ case 'expansion':
60
+ case 'simple_expansion':
61
+ return true;
62
+ default:
63
+ return false;
64
+ }
65
+ }
66
+ function findParent(start, predicate) {
67
+ let node = start.parent;
68
+ while (node !== null) {
69
+ if (predicate(node)) {
70
+ return node;
71
+ }
72
+ node = node.parent;
73
+ }
74
+ return null;
75
+ }
76
+ function findParentOfType(start, type) {
77
+ if (typeof type === 'string') {
78
+ return findParent(start, (n) => n.type === type);
79
+ }
80
+ return findParent(start, (n) => type.includes(n.type));
81
+ }
82
+ /**
83
+ * Resolves the full string value of a node
84
+ * Returns null if the value can't be statically determined (ie, it contains a variable or command substition).
85
+ * Supports: word, string, raw_string, and concatenation
86
+ */
87
+ function resolveStaticString(node) {
88
+ if (node.type === 'concatenation') {
89
+ const values = [];
90
+ for (const child of node.namedChildren) {
91
+ const value = resolveStaticString(child);
92
+ if (value === null)
93
+ return null;
94
+ values.push(value);
95
+ }
96
+ return values.join('');
97
+ }
98
+ if (node.type === 'word')
99
+ return node.text;
100
+ if (node.type === 'string' || node.type === 'raw_string') {
101
+ if (node.namedChildCount === 0)
102
+ return node.text.slice(1, -1);
103
+ const children = node.namedChildren;
104
+ if (children.length === 1 && children[0].type === 'string_content')
105
+ return children[0].text;
106
+ return null;
107
+ }
108
+ return null;
109
+ }
110
+ //# sourceMappingURL=tree-sitter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree-sitter.js","sourceRoot":"","sources":["../../src/util/tree-sitter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "bash-language-server",
3
+ "description": "A language server for Bash",
4
+ "author": "Mads Hartmann",
5
+ "license": "MIT",
6
+ "version": "5.6.0",
7
+ "main": "./out/server.js",
8
+ "typings": "./out/server.d.ts",
9
+ "bin": {
10
+ "bash-language-server": "./out/cli.js"
11
+ },
12
+ "files": [
13
+ "out",
14
+ "tree-sitter-bash.wasm",
15
+ "parser.info",
16
+ "README.md",
17
+ "CHANGELOG.md",
18
+ "GOODVIBES_PATCH.md"
19
+ ],
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "https://github.com/bash-lsp/bash-language-server"
23
+ },
24
+ "engines": {
25
+ "node": ">=16"
26
+ },
27
+ "dependencies": {
28
+ "editorconfig": "3.0.2",
29
+ "fast-glob": "3.3.3",
30
+ "fuzzy-search": "3.2.1",
31
+ "node-fetch": "2.7.0",
32
+ "turndown": "7.2.0",
33
+ "vscode-languageserver": "8.0.2",
34
+ "vscode-languageserver-textdocument": "1.0.12",
35
+ "web-tree-sitter": "0.24.5",
36
+ "zod": "3.24.2"
37
+ },
38
+ "scripts": {
39
+ "prepublishOnly": "cd ../ && pnpm compile && cp README.md server/"
40
+ },
41
+ "goodvibesPatch": {
42
+ "source": "bash-language-server@5.6.0",
43
+ "sourceIntegrity": "sha512-DCuV+/BZAAozsp5blvi6jDnU/ZDaTpJpWM0zqwGjnirfqv7iBsMK32xOze/jipxU0PUZ6CBUKgRUMKI7Kk70Lg==",
44
+ "reason": "Keep bundled Bash LSP while replacing editorconfig@2.0.1 -> minimatch@10.0.1 with editorconfig@3.0.2 -> minimatch@~10.2.4."
45
+ },
46
+ "devDependencies": {
47
+ "@types/fuzzy-search": "2.1.5",
48
+ "@types/node-fetch": "2.6.12",
49
+ "@types/turndown": "5.0.5",
50
+ "@types/urijs": "1.19.25"
51
+ }
52
+ }
@@ -0,0 +1,2 @@
1
+ "https://api.github.com/repos/tree-sitter/tree-sitter-bash/git/commits/c8713e50f0bd77d080832fc61ad128bc8f2934e9"
2
+ tree-sitter-cli "0.23.0"
@@ -1,285 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * postinstall-patch-minimatch.mjs
4
- *
5
- * Upgrades vulnerable minimatch transitive installs in consumer node_modules.
6
- *
7
- * Context: bash-language-server@5.6.0 hard-pins editorconfig@2.0.1, which
8
- * hard-pins minimatch@10.0.1. npm/bun ignore overrides fields in published
9
- * packages, so the root overrides in this SDK cannot fix consumer trees.
10
- * This postinstall patcher reaches into the consumer's node_modules and
11
- * upgrades any minimatch in the vulnerable range >=10.0.0 <10.2.3 in place.
12
- *
13
- * Advisory IDs addressed:
14
- * GHSA-3ppc-4f35-3m26, GHSA-7r86-cg39-jmmj, GHSA-23c5-xmqv-rm74
15
- *
16
- * Node stdlib only. No third-party dependencies. Requires Node 18+.
17
- */
18
-
19
- import { createGunzip } from 'node:zlib';
20
- import {
21
- existsSync,
22
- mkdirSync,
23
- readdirSync,
24
- readFileSync,
25
- writeFileSync,
26
- } from 'node:fs';
27
- import { dirname, join, relative } from 'node:path';
28
-
29
- const PATCH_VERSION = '10.2.5';
30
- const REGISTRY_URL = `https://registry.npmjs.org/minimatch/-/minimatch-${PATCH_VERSION}.tgz`;
31
-
32
- /**
33
- * Parse semver string into major/minor/patch integers.
34
- * @param {string} v
35
- * @returns {{ major: number, minor: number, patch: number } | null}
36
- */
37
- function parseVersion(v) {
38
- const m = /^(\d+)\.(\d+)\.(\d+)/.exec(v);
39
- if (!m) return null;
40
- return {
41
- major: parseInt(m[1], 10),
42
- minor: parseInt(m[2], 10),
43
- patch: parseInt(m[3], 10),
44
- };
45
- }
46
-
47
- /**
48
- * Returns true if version is in the vulnerable range: >=10.0.0 <10.2.3
49
- * @param {string} v
50
- * @returns {boolean}
51
- */
52
- function isVulnerable(v) {
53
- const p = parseVersion(v);
54
- if (!p) return false;
55
- if (p.major !== 10) return false;
56
- if (p.minor < 2) return true;
57
- if (p.minor === 2 && p.patch < 3) return true;
58
- return false;
59
- }
60
-
61
- /**
62
- * Minimal synchronous tar extractor. Handles ustar-compatible archives.
63
- * Supports regular files and directories. Strips the leading "package/"
64
- * prefix that npm tarballs use.
65
- *
66
- * @param {Buffer} tarball - raw (already gunzip-decoded) tar data
67
- * @param {string} destDir - destination directory (the minimatch package root)
68
- */
69
- function extractTar(tarball, destDir) {
70
- const BLOCK = 512;
71
- let offset = 0;
72
-
73
- while (offset + BLOCK <= tarball.length) {
74
- const header = tarball.subarray(offset, offset + BLOCK);
75
- offset += BLOCK;
76
-
77
- // End-of-archive: two consecutive zero blocks.
78
- if (header.every((b) => b === 0)) break;
79
-
80
- const nameRaw = header.subarray(0, 100).toString('utf8').replace(/\0.*$/, '');
81
- if (!nameRaw) break;
82
-
83
- const prefixRaw = header.subarray(345, 500).toString('utf8').replace(/\0.*$/, '');
84
- const fullName = prefixRaw ? `${prefixRaw}/${nameRaw}` : nameRaw;
85
-
86
- const sizeOctal = header.subarray(124, 136).toString('utf8').replace(/\0.*$/, '').trim();
87
- const size = parseInt(sizeOctal, 8) || 0;
88
-
89
- const typeFlag = String.fromCharCode(header[156]);
90
- const isDir = typeFlag === '5';
91
- const isFile = typeFlag === '0' || typeFlag === '\0';
92
-
93
- const blocks = Math.ceil(size / BLOCK);
94
- const fileData = isFile ? tarball.subarray(offset, offset + size) : null;
95
- offset += blocks * BLOCK;
96
-
97
- // Strip leading "package/" prefix (npm tarballs use "package/" as root).
98
- let relPath = fullName;
99
- if (relPath.startsWith('package/')) {
100
- relPath = relPath.slice('package/'.length);
101
- } else if (relPath === 'package') {
102
- continue;
103
- }
104
-
105
- // Safety: reject absolute paths and path traversal.
106
- if (!relPath || relPath.startsWith('/') || relPath.includes('..')) continue;
107
-
108
- const destPath = join(destDir, relPath);
109
-
110
- if (isDir || relPath.endsWith('/')) {
111
- mkdirSync(destPath, { recursive: true });
112
- } else if (isFile && fileData !== null) {
113
- mkdirSync(dirname(destPath), { recursive: true });
114
- writeFileSync(destPath, fileData);
115
- }
116
- }
117
- }
118
-
119
- /**
120
- * Download and gunzip the minimatch tgz from npm registry.
121
- * Returns the raw tar buffer (decompressed).
122
- * @returns {Promise<Buffer>}
123
- */
124
- async function fetchTarball() {
125
- const resp = await fetch(REGISTRY_URL);
126
- if (!resp.ok) {
127
- throw new Error(`fetch ${REGISTRY_URL} → ${resp.status} ${resp.statusText}`);
128
- }
129
- const compressed = Buffer.from(await resp.arrayBuffer());
130
-
131
- return new Promise((resolve, reject) => {
132
- const gunzip = createGunzip();
133
- /** @type {Buffer[]} */
134
- const chunks = [];
135
- gunzip.on('data', (chunk) => chunks.push(/** @type {Buffer} */ (chunk)));
136
- gunzip.on('end', () => resolve(Buffer.concat(chunks)));
137
- gunzip.on('error', reject);
138
- gunzip.end(compressed);
139
- });
140
- }
141
-
142
- /**
143
- * Walk node_modules and return paths to every minimatch/package.json found.
144
- * Covers three layouts:
145
- * - flat: node_modules/minimatch/package.json
146
- * - nested: node_modules/foo/node_modules/minimatch/package.json
147
- * - pnpm: node_modules/.pnpm/minimatch@X/node_modules/minimatch/package.json
148
- *
149
- * @param {string} nodeModules - absolute path to the node_modules root
150
- * @returns {string[]}
151
- */
152
- function findMinimatchPaths(nodeModules) {
153
- /** @type {string[]} */
154
- const results = [];
155
-
156
- /** @param {string} dir */
157
- function scan(dir) {
158
- /** @type {string[]} */
159
- let entries;
160
- try {
161
- entries = readdirSync(dir);
162
- } catch {
163
- return;
164
- }
165
-
166
- for (const entry of entries) {
167
- // Skip hidden dirs except .pnpm (pnpm virtual store).
168
- if (entry.startsWith('.') && entry !== '.pnpm') continue;
169
-
170
- const full = join(dir, entry);
171
-
172
- if (entry === 'minimatch') {
173
- const pkgJson = join(full, 'package.json');
174
- if (existsSync(pkgJson)) results.push(pkgJson);
175
- // Don't recurse into minimatch's own directory.
176
- continue;
177
- }
178
-
179
- if (entry === '.pnpm') {
180
- // pnpm isolated installs: .pnpm/<name@version>/node_modules/<name>
181
- /** @type {string[]} */
182
- let pnpmEntries;
183
- try {
184
- pnpmEntries = readdirSync(full);
185
- } catch {
186
- continue;
187
- }
188
- for (const pnpmEntry of pnpmEntries) {
189
- // Check for minimatch directly in this pnpm store entry.
190
- const pnpmMinimatch = join(full, pnpmEntry, 'node_modules', 'minimatch');
191
- const pkgJson = join(pnpmMinimatch, 'package.json');
192
- if (existsSync(pkgJson)) results.push(pkgJson);
193
- // Also scan nested node_modules inside pnpm store entries.
194
- const nested = join(full, pnpmEntry, 'node_modules');
195
- if (existsSync(nested)) scan(nested);
196
- }
197
- continue;
198
- }
199
-
200
- // Scoped namespace (@scope) — recurse one level.
201
- if (entry.startsWith('@')) {
202
- scan(full);
203
- continue;
204
- }
205
-
206
- // Regular package — check for nested node_modules.
207
- const nested = join(full, 'node_modules');
208
- if (existsSync(nested)) scan(nested);
209
- }
210
- }
211
-
212
- scan(nodeModules);
213
- return results;
214
- }
215
-
216
- async function main() {
217
- // npm sets INIT_CWD to the consumer project root during postinstall.
218
- // Fallback to process.cwd() which is the package root during npm install.
219
- const consumerRoot = process.env.INIT_CWD ?? process.cwd();
220
- const nodeModules = join(consumerRoot, 'node_modules');
221
-
222
- if (!existsSync(nodeModules)) {
223
- console.log('[pellux-patch] node_modules not found, skipping minimatch patch');
224
- process.exit(0);
225
- }
226
-
227
- /** @type {string[]} */
228
- let pkgJsonPaths;
229
- try {
230
- pkgJsonPaths = findMinimatchPaths(nodeModules);
231
- } catch (err) {
232
- console.warn(
233
- `[pellux-patch] warning: failed to scan node_modules: ${/** @type {Error} */ (err)?.message ?? err}`,
234
- );
235
- process.exit(0);
236
- }
237
-
238
- /** @type {Array<{ pkgJsonPath: string, version: string, dir: string }>} */
239
- const vulnerable = [];
240
-
241
- for (const pkgJsonPath of pkgJsonPaths) {
242
- try {
243
- const pkg = JSON.parse(readFileSync(pkgJsonPath, 'utf8'));
244
- const ver = /** @type {string} */ (pkg.version ?? '');
245
- if (isVulnerable(ver)) {
246
- vulnerable.push({ pkgJsonPath, version: ver, dir: dirname(pkgJsonPath) });
247
- }
248
- } catch {
249
- // Unreadable package.json — skip silently.
250
- }
251
- }
252
-
253
- if (vulnerable.length === 0) {
254
- console.log('[pellux-patch] no vulnerable minimatch detected');
255
- process.exit(0);
256
- }
257
-
258
- /** @type {Buffer | null} */
259
- let tarball = null;
260
-
261
- for (const { pkgJsonPath, version, dir } of vulnerable) {
262
- const rel = relative(consumerRoot, pkgJsonPath);
263
- try {
264
- if (tarball === null) {
265
- tarball = await fetchTarball();
266
- }
267
- extractTar(tarball, dir);
268
- console.log(`[pellux-patch] upgraded minimatch at ${rel}: ${version} → ${PATCH_VERSION}`);
269
- } catch (err) {
270
- // Never fail the consumer's install — log and continue.
271
- console.warn(
272
- `[pellux-patch] warning: failed to patch ${rel}: ${/** @type {Error} */ (err)?.message ?? err}`,
273
- );
274
- }
275
- }
276
- }
277
-
278
- main().catch((err) => {
279
- // Belt-and-suspenders: catch any top-level unhandled rejection and warn,
280
- // never propagate — postinstall must never break a consumer install.
281
- console.warn(
282
- `[pellux-patch] warning: postinstall patcher encountered an error: ${/** @type {Error} */ (err)?.message ?? err}`,
283
- );
284
- process.exit(0);
285
- });