@pellux/goodvibes-sdk 0.25.0 → 0.25.2
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/dist/_internal/daemon/otlp-protobuf.d.ts +3 -0
- package/dist/_internal/daemon/otlp-protobuf.d.ts.map +1 -0
- package/dist/_internal/daemon/otlp-protobuf.js +968 -0
- package/dist/_internal/daemon/telemetry-routes.d.ts.map +1 -1
- package/dist/_internal/daemon/telemetry-routes.js +22 -13
- package/dist/_internal/platform/intelligence/lsp/service.d.ts.map +1 -1
- package/dist/_internal/platform/intelligence/lsp/service.js +18 -9
- package/dist/_internal/platform/providers/anthropic-vertex.d.ts.map +1 -1
- package/dist/_internal/platform/providers/anthropic-vertex.js +135 -2
- package/dist/_internal/platform/version.js +1 -1
- package/dist/_internal/platform/watchers/registry.d.ts.map +1 -1
- package/dist/_internal/platform/watchers/registry.js +4 -1
- package/package.json +9 -8
- package/vendor/bash-language-server/CHANGELOG.md +453 -0
- package/vendor/bash-language-server/GOODVIBES_PATCH.md +22 -0
- package/vendor/bash-language-server/README.md +230 -0
- package/vendor/bash-language-server/out/analyser.d.ts +187 -0
- package/vendor/bash-language-server/out/analyser.js +782 -0
- package/vendor/bash-language-server/out/analyser.js.map +1 -0
- package/vendor/bash-language-server/out/builtins.d.ts +2 -0
- package/vendor/bash-language-server/out/builtins.js +71 -0
- package/vendor/bash-language-server/out/builtins.js.map +1 -0
- package/vendor/bash-language-server/out/cli.d.ts +3 -0
- package/vendor/bash-language-server/out/cli.js +74 -0
- package/vendor/bash-language-server/out/cli.js.map +1 -0
- package/vendor/bash-language-server/out/config.d.ts +88 -0
- package/vendor/bash-language-server/out/config.js +96 -0
- package/vendor/bash-language-server/out/config.js.map +1 -0
- package/vendor/bash-language-server/out/executables.d.ts +19 -0
- package/vendor/bash-language-server/out/executables.js +86 -0
- package/vendor/bash-language-server/out/executables.js.map +1 -0
- package/vendor/bash-language-server/out/parser.d.ts +2 -0
- package/vendor/bash-language-server/out/parser.js +36 -0
- package/vendor/bash-language-server/out/parser.js.map +1 -0
- package/vendor/bash-language-server/out/reserved-words.d.ts +2 -0
- package/vendor/bash-language-server/out/reserved-words.js +33 -0
- package/vendor/bash-language-server/out/reserved-words.js.map +1 -0
- package/vendor/bash-language-server/out/server.d.ts +56 -0
- package/vendor/bash-language-server/out/server.js +756 -0
- package/vendor/bash-language-server/out/server.js.map +1 -0
- package/vendor/bash-language-server/out/shellcheck/config.d.ts +5 -0
- package/vendor/bash-language-server/out/shellcheck/config.js +17 -0
- package/vendor/bash-language-server/out/shellcheck/config.js.map +1 -0
- package/vendor/bash-language-server/out/shellcheck/directive.d.ts +18 -0
- package/vendor/bash-language-server/out/shellcheck/directive.js +62 -0
- package/vendor/bash-language-server/out/shellcheck/directive.js.map +1 -0
- package/vendor/bash-language-server/out/shellcheck/index.d.ts +22 -0
- package/vendor/bash-language-server/out/shellcheck/index.js +229 -0
- package/vendor/bash-language-server/out/shellcheck/index.js.map +1 -0
- package/vendor/bash-language-server/out/shellcheck/types.d.ts +175 -0
- package/vendor/bash-language-server/out/shellcheck/types.js +35 -0
- package/vendor/bash-language-server/out/shellcheck/types.js.map +1 -0
- package/vendor/bash-language-server/out/shfmt/index.d.ts +18 -0
- package/vendor/bash-language-server/out/shfmt/index.js +151 -0
- package/vendor/bash-language-server/out/shfmt/index.js.map +1 -0
- package/vendor/bash-language-server/out/snippets.d.ts +2 -0
- package/vendor/bash-language-server/out/snippets.js +671 -0
- package/vendor/bash-language-server/out/snippets.js.map +1 -0
- package/vendor/bash-language-server/out/types.d.ts +13 -0
- package/vendor/bash-language-server/out/types.js +12 -0
- package/vendor/bash-language-server/out/types.js.map +1 -0
- package/vendor/bash-language-server/out/util/array.d.ts +14 -0
- package/vendor/bash-language-server/out/util/array.js +36 -0
- package/vendor/bash-language-server/out/util/array.js.map +1 -0
- package/vendor/bash-language-server/out/util/async.d.ts +13 -0
- package/vendor/bash-language-server/out/util/async.js +24 -0
- package/vendor/bash-language-server/out/util/async.js.map +1 -0
- package/vendor/bash-language-server/out/util/declarations.d.ts +88 -0
- package/vendor/bash-language-server/out/util/declarations.js +295 -0
- package/vendor/bash-language-server/out/util/declarations.js.map +1 -0
- package/vendor/bash-language-server/out/util/discriminate.d.ts +1 -0
- package/vendor/bash-language-server/out/util/discriminate.js +7 -0
- package/vendor/bash-language-server/out/util/discriminate.js.map +1 -0
- package/vendor/bash-language-server/out/util/fs.d.ts +6 -0
- package/vendor/bash-language-server/out/util/fs.js +73 -0
- package/vendor/bash-language-server/out/util/fs.js.map +1 -0
- package/vendor/bash-language-server/out/util/logger.d.ts +35 -0
- package/vendor/bash-language-server/out/util/logger.js +105 -0
- package/vendor/bash-language-server/out/util/logger.js.map +1 -0
- package/vendor/bash-language-server/out/util/lsp.d.ts +5 -0
- package/vendor/bash-language-server/out/util/lsp.js +13 -0
- package/vendor/bash-language-server/out/util/lsp.js.map +1 -0
- package/vendor/bash-language-server/out/util/platform.d.ts +1 -0
- package/vendor/bash-language-server/out/util/platform.js +7 -0
- package/vendor/bash-language-server/out/util/platform.js.map +1 -0
- package/vendor/bash-language-server/out/util/sh.d.ts +16 -0
- package/vendor/bash-language-server/out/util/sh.js +132 -0
- package/vendor/bash-language-server/out/util/sh.js.map +1 -0
- package/vendor/bash-language-server/out/util/shebang.d.ts +10 -0
- package/vendor/bash-language-server/out/util/shebang.js +53 -0
- package/vendor/bash-language-server/out/util/shebang.js.map +1 -0
- package/vendor/bash-language-server/out/util/sourcing.d.ts +15 -0
- package/vendor/bash-language-server/out/util/sourcing.js +182 -0
- package/vendor/bash-language-server/out/util/sourcing.js.map +1 -0
- package/vendor/bash-language-server/out/util/tree-sitter.d.ts +22 -0
- package/vendor/bash-language-server/out/util/tree-sitter.js +110 -0
- package/vendor/bash-language-server/out/util/tree-sitter.js.map +1 -0
- package/vendor/bash-language-server/package.json +52 -0
- package/vendor/bash-language-server/parser.info +2 -0
- package/vendor/bash-language-server/tree-sitter-bash.wasm +0 -0
- package/dist/_internal/platform/runtime/contracts/index.d.ts +0 -40
- package/dist/_internal/platform/runtime/contracts/index.d.ts.map +0 -1
- package/dist/_internal/platform/runtime/contracts/index.js +0 -133
- package/dist/_internal/platform/runtime/contracts/migrations/index.d.ts +0 -75
- package/dist/_internal/platform/runtime/contracts/migrations/index.d.ts.map +0 -1
- package/dist/_internal/platform/runtime/contracts/migrations/index.js +0 -158
- package/dist/_internal/platform/runtime/contracts/migrations/schemas.d.ts +0 -57
- package/dist/_internal/platform/runtime/contracts/migrations/schemas.d.ts.map +0 -1
- package/dist/_internal/platform/runtime/contracts/migrations/schemas.js +0 -157
- package/dist/_internal/platform/runtime/contracts/types.d.ts +0 -123
- package/dist/_internal/platform/runtime/contracts/types.d.ts.map +0 -1
- package/dist/_internal/platform/runtime/contracts/types.js +0 -41
- package/dist/_internal/platform/runtime/contracts/validators/event-envelope.d.ts +0 -24
- package/dist/_internal/platform/runtime/contracts/validators/event-envelope.d.ts.map +0 -1
- package/dist/_internal/platform/runtime/contracts/validators/event-envelope.js +0 -104
- package/dist/_internal/platform/runtime/contracts/validators/index.d.ts +0 -11
- package/dist/_internal/platform/runtime/contracts/validators/index.d.ts.map +0 -1
- package/dist/_internal/platform/runtime/contracts/validators/index.js +0 -10
- package/dist/_internal/platform/runtime/contracts/validators/runtime-state.d.ts +0 -23
- package/dist/_internal/platform/runtime/contracts/validators/runtime-state.d.ts.map +0 -1
- package/dist/_internal/platform/runtime/contracts/validators/runtime-state.js +0 -101
- package/dist/_internal/platform/runtime/contracts/validators/session.d.ts +0 -24
- package/dist/_internal/platform/runtime/contracts/validators/session.d.ts.map +0 -1
- package/dist/_internal/platform/runtime/contracts/validators/session.js +0 -103
- package/dist/_internal/platform/runtime/contracts/version.d.ts +0 -84
- package/dist/_internal/platform/runtime/contracts/version.d.ts.map +0 -1
- package/dist/_internal/platform/runtime/contracts/version.js +0 -41
- package/scripts/postinstall-patch-minimatch.mjs +0 -285
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Compatibility Contracts — Session Validator
|
|
3
|
-
*
|
|
4
|
-
* Performs runtime shape validation for the session persistence format
|
|
5
|
-
* (messages array + meta object). Returns a structured ValidationResult.
|
|
6
|
-
*
|
|
7
|
-
* @module contracts/validators/session
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* Validates that `data` conforms to the expected session persistence shape.
|
|
11
|
-
*
|
|
12
|
-
* Checks:
|
|
13
|
-
* - `data` is a non-null object
|
|
14
|
-
* - `sessionId` is a non-empty string
|
|
15
|
-
* - `messages` is an array (contents are not deeply validated)
|
|
16
|
-
* - `meta` is a non-null, non-array object
|
|
17
|
-
* - `meta.version` (if present) has numeric `major`, `minor`, `patch` fields
|
|
18
|
-
*
|
|
19
|
-
* @param data - The raw persisted data to validate.
|
|
20
|
-
* @returns A ValidationResult with structured errors if any field is invalid.
|
|
21
|
-
*/
|
|
22
|
-
export function validateSession(data) {
|
|
23
|
-
const errors = [];
|
|
24
|
-
if (data === null || typeof data !== 'object') {
|
|
25
|
-
errors.push({
|
|
26
|
-
path: '',
|
|
27
|
-
message: 'Session must be a non-null object',
|
|
28
|
-
expected: 'object',
|
|
29
|
-
actual: data === null ? 'null' : typeof data,
|
|
30
|
-
});
|
|
31
|
-
return { valid: false, errors };
|
|
32
|
-
}
|
|
33
|
-
const record = data;
|
|
34
|
-
// Validate sessionId: non-empty string
|
|
35
|
-
const sessionIdRaw = record['sessionId'];
|
|
36
|
-
if (typeof sessionIdRaw !== 'string' || sessionIdRaw.length === 0) {
|
|
37
|
-
errors.push({
|
|
38
|
-
path: 'sessionId',
|
|
39
|
-
message: "Field 'sessionId' must be a non-empty string",
|
|
40
|
-
expected: 'non-empty string',
|
|
41
|
-
actual: sessionIdRaw === undefined ? 'undefined' : sessionIdRaw === null ? 'null' : typeof sessionIdRaw,
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
// Validate messages: array
|
|
45
|
-
const messagesRaw = record['messages'];
|
|
46
|
-
if (!Array.isArray(messagesRaw)) {
|
|
47
|
-
errors.push({
|
|
48
|
-
path: 'messages',
|
|
49
|
-
message: "Field 'messages' must be an array",
|
|
50
|
-
expected: 'array',
|
|
51
|
-
actual: messagesRaw === undefined ? 'undefined' : messagesRaw === null ? 'null' : typeof messagesRaw,
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
// Validate meta: non-null, non-array object
|
|
55
|
-
const metaRaw = record['meta'];
|
|
56
|
-
if (metaRaw === undefined || metaRaw === null || typeof metaRaw !== 'object' || Array.isArray(metaRaw)) {
|
|
57
|
-
errors.push({
|
|
58
|
-
path: 'meta',
|
|
59
|
-
message: "Field 'meta' must be a non-null, non-array object",
|
|
60
|
-
expected: 'object',
|
|
61
|
-
actual: metaRaw === undefined ? 'undefined' : metaRaw === null ? 'null' : Array.isArray(metaRaw) ? 'array' : typeof metaRaw,
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
// Detect version from meta.version if present
|
|
65
|
-
let detectedVersion;
|
|
66
|
-
if (metaRaw !== undefined && metaRaw !== null && typeof metaRaw === 'object' && !Array.isArray(metaRaw)) {
|
|
67
|
-
const meta = metaRaw;
|
|
68
|
-
const versionRaw = meta['version'];
|
|
69
|
-
if (versionRaw !== undefined && versionRaw !== null && typeof versionRaw === 'object') {
|
|
70
|
-
const v = versionRaw;
|
|
71
|
-
const allNumeric = typeof v['major'] === 'number' &&
|
|
72
|
-
typeof v['minor'] === 'number' &&
|
|
73
|
-
typeof v['patch'] === 'number';
|
|
74
|
-
if (allNumeric) {
|
|
75
|
-
detectedVersion = {
|
|
76
|
-
major: v['major'],
|
|
77
|
-
minor: v['minor'],
|
|
78
|
-
patch: v['patch'],
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
82
|
-
let actualStr;
|
|
83
|
-
try {
|
|
84
|
-
actualStr = JSON.stringify(versionRaw);
|
|
85
|
-
}
|
|
86
|
-
catch {
|
|
87
|
-
actualStr = String(versionRaw);
|
|
88
|
-
}
|
|
89
|
-
errors.push({
|
|
90
|
-
path: 'meta.version',
|
|
91
|
-
message: "Field 'meta.version' must have numeric major, minor, patch components",
|
|
92
|
-
expected: '{ major: number, minor: number, patch: number }',
|
|
93
|
-
actual: actualStr,
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
return {
|
|
99
|
-
valid: errors.length === 0,
|
|
100
|
-
errors,
|
|
101
|
-
version: detectedVersion,
|
|
102
|
-
};
|
|
103
|
-
}
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Compatibility Contracts — Current Schema Versions
|
|
3
|
-
*
|
|
4
|
-
* Declares the authoritative current schema version for each versioned domain.
|
|
5
|
-
* Bump these when making structural changes to the corresponding schema.
|
|
6
|
-
*
|
|
7
|
-
* @module contracts/version
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* Current schema versions for all versioned runtime domains.
|
|
11
|
-
*
|
|
12
|
-
* Rules for bumping:
|
|
13
|
-
* - Bump `major` when the change is breaking (requires migration)
|
|
14
|
-
* - Bump `minor` when adding optional fields (additive, backward-compatible)
|
|
15
|
-
* - Bump `patch` for non-structural documentation or annotation changes
|
|
16
|
-
*/
|
|
17
|
-
export declare const SCHEMA_VERSIONS: {
|
|
18
|
-
/** Top-level RuntimeState snapshot schema. */
|
|
19
|
-
readonly runtimeState: {
|
|
20
|
-
readonly major: 1;
|
|
21
|
-
readonly minor: 0;
|
|
22
|
-
readonly patch: 0;
|
|
23
|
-
};
|
|
24
|
-
/** RuntimeEventEnvelope schema for event persistence and replay. */
|
|
25
|
-
readonly eventEnvelope: {
|
|
26
|
-
readonly major: 1;
|
|
27
|
-
readonly minor: 1;
|
|
28
|
-
readonly patch: 0;
|
|
29
|
-
};
|
|
30
|
-
/** Session persistence format (messages + meta). */
|
|
31
|
-
readonly session: {
|
|
32
|
-
readonly major: 1;
|
|
33
|
-
readonly minor: 0;
|
|
34
|
-
readonly patch: 0;
|
|
35
|
-
};
|
|
36
|
-
/** Plugin manifest and capability descriptor schema. */
|
|
37
|
-
readonly pluginManifest: {
|
|
38
|
-
readonly major: 1;
|
|
39
|
-
readonly minor: 0;
|
|
40
|
-
readonly patch: 0;
|
|
41
|
-
};
|
|
42
|
-
/** RuntimeTask record schema used in task domain persistence. */
|
|
43
|
-
readonly taskRecord: {
|
|
44
|
-
readonly major: 1;
|
|
45
|
-
readonly minor: 0;
|
|
46
|
-
readonly patch: 0;
|
|
47
|
-
};
|
|
48
|
-
};
|
|
49
|
-
/**
|
|
50
|
-
* The minimum schema version supported for migration for each domain.
|
|
51
|
-
*
|
|
52
|
-
* Data older than this version cannot be migrated and must be discarded
|
|
53
|
-
* or re-initialized. This is updated when old migration steps are pruned.
|
|
54
|
-
*/
|
|
55
|
-
export declare const MIN_SUPPORTED_VERSIONS: {
|
|
56
|
-
readonly runtimeState: {
|
|
57
|
-
readonly major: 1;
|
|
58
|
-
readonly minor: 0;
|
|
59
|
-
readonly patch: 0;
|
|
60
|
-
};
|
|
61
|
-
readonly eventEnvelope: {
|
|
62
|
-
readonly major: 1;
|
|
63
|
-
readonly minor: 0;
|
|
64
|
-
readonly patch: 0;
|
|
65
|
-
};
|
|
66
|
-
readonly session: {
|
|
67
|
-
readonly major: 1;
|
|
68
|
-
readonly minor: 0;
|
|
69
|
-
readonly patch: 0;
|
|
70
|
-
};
|
|
71
|
-
readonly pluginManifest: {
|
|
72
|
-
readonly major: 1;
|
|
73
|
-
readonly minor: 0;
|
|
74
|
-
readonly patch: 0;
|
|
75
|
-
};
|
|
76
|
-
readonly taskRecord: {
|
|
77
|
-
readonly major: 1;
|
|
78
|
-
readonly minor: 0;
|
|
79
|
-
readonly patch: 0;
|
|
80
|
-
};
|
|
81
|
-
};
|
|
82
|
-
/** Union of all known contract names. */
|
|
83
|
-
export type ContractName = keyof typeof SCHEMA_VERSIONS;
|
|
84
|
-
//# sourceMappingURL=version.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../../../../src/_internal/platform/runtime/contracts/version.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe;IAC1B,8CAA8C;;;;;;IAE9C,oEAAoE;;;;;;IAEpE,oDAAoD;;;;;;IAEpD,wDAAwD;;;;;;IAExD,iEAAiE;;;;;;CAEzD,CAAC;AAEX;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;CAMzB,CAAC;AAEX,yCAAyC;AACzC,MAAM,MAAM,YAAY,GAAG,MAAM,OAAO,eAAe,CAAC"}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Compatibility Contracts — Current Schema Versions
|
|
3
|
-
*
|
|
4
|
-
* Declares the authoritative current schema version for each versioned domain.
|
|
5
|
-
* Bump these when making structural changes to the corresponding schema.
|
|
6
|
-
*
|
|
7
|
-
* @module contracts/version
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* Current schema versions for all versioned runtime domains.
|
|
11
|
-
*
|
|
12
|
-
* Rules for bumping:
|
|
13
|
-
* - Bump `major` when the change is breaking (requires migration)
|
|
14
|
-
* - Bump `minor` when adding optional fields (additive, backward-compatible)
|
|
15
|
-
* - Bump `patch` for non-structural documentation or annotation changes
|
|
16
|
-
*/
|
|
17
|
-
export const SCHEMA_VERSIONS = {
|
|
18
|
-
/** Top-level RuntimeState snapshot schema. */
|
|
19
|
-
runtimeState: { major: 1, minor: 0, patch: 0 },
|
|
20
|
-
/** RuntimeEventEnvelope schema for event persistence and replay. */
|
|
21
|
-
eventEnvelope: { major: 1, minor: 1, patch: 0 },
|
|
22
|
-
/** Session persistence format (messages + meta). */
|
|
23
|
-
session: { major: 1, minor: 0, patch: 0 },
|
|
24
|
-
/** Plugin manifest and capability descriptor schema. */
|
|
25
|
-
pluginManifest: { major: 1, minor: 0, patch: 0 },
|
|
26
|
-
/** RuntimeTask record schema used in task domain persistence. */
|
|
27
|
-
taskRecord: { major: 1, minor: 0, patch: 0 },
|
|
28
|
-
};
|
|
29
|
-
/**
|
|
30
|
-
* The minimum schema version supported for migration for each domain.
|
|
31
|
-
*
|
|
32
|
-
* Data older than this version cannot be migrated and must be discarded
|
|
33
|
-
* or re-initialized. This is updated when old migration steps are pruned.
|
|
34
|
-
*/
|
|
35
|
-
export const MIN_SUPPORTED_VERSIONS = {
|
|
36
|
-
runtimeState: { major: 1, minor: 0, patch: 0 },
|
|
37
|
-
eventEnvelope: { major: 1, minor: 0, patch: 0 },
|
|
38
|
-
session: { major: 1, minor: 0, patch: 0 },
|
|
39
|
-
pluginManifest: { major: 1, minor: 0, patch: 0 },
|
|
40
|
-
taskRecord: { major: 1, minor: 0, patch: 0 },
|
|
41
|
-
};
|
|
@@ -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
|
-
});
|