semantifold 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +61 -15
- package/build/index.d.ts +52 -2
- package/build/index.d.ts.map +1 -1
- package/build/index.js +60 -8
- package/build/src/artifact-path.d.ts +23 -1
- package/build/src/artifact-path.d.ts.map +1 -1
- package/build/src/artifact-path.js +45 -3
- package/build/src/artifacts.d.ts.map +1 -1
- package/build/src/artifacts.js +66 -1
- package/build/src/backends/android.d.ts +49 -0
- package/build/src/backends/android.d.ts.map +1 -0
- package/build/src/backends/android.js +1274 -0
- package/build/src/backends/c-validation.d.ts.map +1 -1
- package/build/src/backends/c-validation.js +7 -3
- package/build/src/backends/cpp-validation.d.ts.map +1 -1
- package/build/src/backends/cpp-validation.js +7 -3
- package/build/src/backends/csharp.js +7 -1
- package/build/src/backends/dart-runtime.d.ts +2 -0
- package/build/src/backends/dart-runtime.d.ts.map +1 -0
- package/build/src/backends/dart-runtime.js +41 -0
- package/build/src/backends/dart.d.ts +20 -0
- package/build/src/backends/dart.d.ts.map +1 -0
- package/build/src/backends/dart.js +321 -0
- package/build/src/backends/effects.d.ts +60 -0
- package/build/src/backends/effects.d.ts.map +1 -0
- package/build/src/backends/effects.js +746 -0
- package/build/src/backends/go.js +18 -4
- package/build/src/backends/identifiers.d.ts +36 -4
- package/build/src/backends/identifiers.d.ts.map +1 -1
- package/build/src/backends/identifiers.js +160 -10
- package/build/src/backends/index.d.ts.map +1 -1
- package/build/src/backends/index.js +27 -4
- package/build/src/backends/ios.d.ts +68 -0
- package/build/src/backends/ios.d.ts.map +1 -0
- package/build/src/backends/ios.js +1503 -0
- package/build/src/backends/java.d.ts.map +1 -1
- package/build/src/backends/java.js +429 -36
- package/build/src/backends/javascript.d.ts +6 -0
- package/build/src/backends/javascript.d.ts.map +1 -1
- package/build/src/backends/javascript.js +380 -24
- package/build/src/backends/kotlin-runtime.d.ts +3 -0
- package/build/src/backends/kotlin-runtime.d.ts.map +1 -0
- package/build/src/backends/kotlin-runtime.js +29 -0
- package/build/src/backends/kotlin.d.ts +33 -0
- package/build/src/backends/kotlin.d.ts.map +1 -0
- package/build/src/backends/kotlin.js +138 -0
- package/build/src/backends/native-validation.d.ts +2 -2
- package/build/src/backends/native-validation.d.ts.map +1 -1
- package/build/src/backends/native-validation.js +2 -2
- package/build/src/backends/ordered-expressions.d.ts.map +1 -1
- package/build/src/backends/ordered-expressions.js +39 -7
- package/build/src/backends/php-stdlib-support.d.ts +19 -0
- package/build/src/backends/php-stdlib-support.d.ts.map +1 -0
- package/build/src/backends/php-stdlib-support.js +227 -0
- package/build/src/backends/php.d.ts.map +1 -1
- package/build/src/backends/php.js +448 -33
- package/build/src/backends/program.d.ts +83 -0
- package/build/src/backends/program.d.ts.map +1 -0
- package/build/src/backends/program.js +1309 -0
- package/build/src/backends/python.js +7 -1
- package/build/src/backends/ruby.d.ts.map +1 -1
- package/build/src/backends/ruby.js +310 -24
- package/build/src/backends/rust-runtime.d.ts +7 -0
- package/build/src/backends/rust-runtime.d.ts.map +1 -0
- package/build/src/backends/rust-runtime.js +32 -0
- package/build/src/backends/rust-validation.d.ts +9 -0
- package/build/src/backends/rust-validation.d.ts.map +1 -0
- package/build/src/backends/rust-validation.js +78 -0
- package/build/src/backends/rust.d.ts +24 -0
- package/build/src/backends/rust.d.ts.map +1 -0
- package/build/src/backends/rust.js +344 -0
- package/build/src/backends/scalars.d.ts +14 -6
- package/build/src/backends/scalars.d.ts.map +1 -1
- package/build/src/backends/scalars.js +167 -17
- package/build/src/backends/shared.d.ts +23 -4
- package/build/src/backends/shared.d.ts.map +1 -1
- package/build/src/backends/shared.js +2174 -62
- package/build/src/backends/stdlib-support.d.ts +14 -0
- package/build/src/backends/stdlib-support.d.ts.map +1 -0
- package/build/src/backends/stdlib-support.js +237 -0
- package/build/src/backends/swift-runtime.d.ts +3 -0
- package/build/src/backends/swift-runtime.d.ts.map +1 -0
- package/build/src/backends/swift-runtime.js +14 -0
- package/build/src/backends/swift.d.ts +8 -0
- package/build/src/backends/swift.d.ts.map +1 -0
- package/build/src/backends/swift.js +127 -0
- package/build/src/backends/typescript.d.ts.map +1 -1
- package/build/src/backends/typescript.js +344 -24
- package/build/src/backends/wasm.d.ts +43 -0
- package/build/src/backends/wasm.d.ts.map +1 -0
- package/build/src/backends/wasm.js +2164 -0
- package/build/src/backends/writer.d.ts +255 -4
- package/build/src/backends/writer.d.ts.map +1 -1
- package/build/src/backends/writer.js +491 -3
- package/build/src/diagnostic.d.ts +4 -3
- package/build/src/diagnostic.d.ts.map +1 -1
- package/build/src/diagnostic.js +5 -3
- package/build/src/frontends/c.d.ts.map +1 -1
- package/build/src/frontends/c.js +5 -3
- package/build/src/frontends/cpp.d.ts.map +1 -1
- package/build/src/frontends/cpp.js +5 -3
- package/build/src/frontends/csharp.d.ts.map +1 -1
- package/build/src/frontends/csharp.js +7 -3
- package/build/src/frontends/dart.d.ts +10 -0
- package/build/src/frontends/dart.d.ts.map +1 -0
- package/build/src/frontends/dart.js +913 -0
- package/build/src/frontends/index.d.ts +3 -1
- package/build/src/frontends/index.d.ts.map +1 -1
- package/build/src/frontends/index.js +15 -5
- package/build/src/frontends/java.d.ts +110 -1
- package/build/src/frontends/java.d.ts.map +1 -1
- package/build/src/frontends/java.js +1725 -70
- package/build/src/frontends/javascript-typescript.d.ts +69 -1
- package/build/src/frontends/javascript-typescript.d.ts.map +1 -1
- package/build/src/frontends/javascript-typescript.js +1825 -93
- package/build/src/frontends/kotlin.d.ts +10 -0
- package/build/src/frontends/kotlin.d.ts.map +1 -0
- package/build/src/frontends/kotlin.js +685 -0
- package/build/src/frontends/php.d.ts +118 -1
- package/build/src/frontends/php.d.ts.map +1 -1
- package/build/src/frontends/php.js +1583 -76
- package/build/src/frontends/program.d.ts +74 -0
- package/build/src/frontends/program.d.ts.map +1 -0
- package/build/src/frontends/program.js +989 -0
- package/build/src/frontends/ruby.d.ts +68 -1
- package/build/src/frontends/ruby.d.ts.map +1 -1
- package/build/src/frontends/ruby.js +1446 -101
- package/build/src/frontends/rust-parser.d.ts +11 -0
- package/build/src/frontends/rust-parser.d.ts.map +1 -0
- package/build/src/frontends/rust-parser.js +15 -0
- package/build/src/frontends/rust.d.ts +14 -0
- package/build/src/frontends/rust.d.ts.map +1 -0
- package/build/src/frontends/rust.js +715 -0
- package/build/src/frontends/scalars.d.ts +10 -0
- package/build/src/frontends/scalars.d.ts.map +1 -1
- package/build/src/frontends/scalars.js +28 -2
- package/build/src/frontends/swift.d.ts +10 -0
- package/build/src/frontends/swift.d.ts.map +1 -0
- package/build/src/frontends/swift.js +860 -0
- package/build/src/frontends/types.d.ts +186 -0
- package/build/src/frontends/types.d.ts.map +1 -0
- package/build/src/frontends/types.js +634 -0
- package/build/src/language-registry.d.ts +46 -4
- package/build/src/language-registry.d.ts.map +1 -1
- package/build/src/language-registry.js +177 -13
- package/build/src/mapping.d.ts +2 -2
- package/build/src/mapping.d.ts.map +1 -1
- package/build/src/mapping.js +31 -10
- package/build/src/semantic/capabilities.d.ts +66 -0
- package/build/src/semantic/capabilities.d.ts.map +1 -0
- package/build/src/semantic/capabilities.js +649 -0
- package/build/src/semantic/effects.d.ts +26 -0
- package/build/src/semantic/effects.d.ts.map +1 -0
- package/build/src/semantic/effects.js +764 -0
- package/build/src/semantic/generics.d.ts +23 -0
- package/build/src/semantic/generics.d.ts.map +1 -0
- package/build/src/semantic/generics.js +61 -0
- package/build/src/semantic/lifetime.d.ts +37 -0
- package/build/src/semantic/lifetime.d.ts.map +1 -0
- package/build/src/semantic/lifetime.js +527 -0
- package/build/src/semantic/provenance.d.ts +9 -2
- package/build/src/semantic/provenance.d.ts.map +1 -1
- package/build/src/semantic/provenance.js +462 -20
- package/build/src/semantic/scalars.d.ts +11 -0
- package/build/src/semantic/scalars.d.ts.map +1 -1
- package/build/src/semantic/scalars.js +16 -1
- package/build/src/semantic/stdlib.d.ts +254 -0
- package/build/src/semantic/stdlib.d.ts.map +1 -0
- package/build/src/semantic/stdlib.js +880 -0
- package/build/src/semantic/types.d.ts +3108 -178
- package/build/src/semantic/types.d.ts.map +1 -1
- package/build/src/semantic/types.js +730 -15
- package/build/src/semantic/validate.d.ts +85 -5
- package/build/src/semantic/validate.d.ts.map +1 -1
- package/build/src/semantic/validate.js +2576 -98
- package/build/src/stdlib-facades.d.ts +304 -0
- package/build/src/stdlib-facades.d.ts.map +1 -0
- package/build/src/stdlib-facades.js +1167 -0
- package/build/src/stdlib-negotiation.d.ts +69 -0
- package/build/src/stdlib-negotiation.d.ts.map +1 -0
- package/build/src/stdlib-negotiation.js +403 -0
- package/build/src/stdlib-providers.d.ts +72 -0
- package/build/src/stdlib-providers.d.ts.map +1 -0
- package/build/src/stdlib-providers.js +339 -0
- package/build/src/toolchains.d.ts +55 -1
- package/build/src/toolchains.d.ts.map +1 -1
- package/build/src/toolchains.js +15 -4
- package/docs/android.md +79 -0
- package/docs/architecture.md +47 -13
- package/docs/dart.md +60 -0
- package/docs/goals.md +3 -3
- package/docs/ios.md +121 -0
- package/docs/kotlin.md +42 -0
- package/docs/language-support.md +238 -26
- package/docs/multi-file-modules.md +52 -0
- package/docs/parser-qualification.md +121 -8
- package/docs/plans/2026-09-05-standard-library-portability.md +10 -10
- package/docs/rust.md +88 -0
- package/docs/source-maps.md +17 -7
- package/docs/specification.md +5 -0
- package/docs/standard-library-portability.md +39 -8
- package/docs/swift.md +44 -0
- package/docs/testing.md +381 -4
- package/docs/webassembly.md +52 -0
- package/index.js +66 -8
- package/node_modules/semantifold-tree-sitter-legacy-internal/README.md +2 -2
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/LICENSE +21 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/README.md +45 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/binding.gyp +30 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding.cc +20 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding_test.js +9 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.d.ts +28 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.js +11 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/grammar.js +1630 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/package.json +64 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-arm64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-x64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-arm64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-x64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-arm64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-x64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/highlights.scm +159 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/injections.scm +9 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/tags.scm +60 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/grammar.json +9405 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/node-types.json +5399 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/parser.c +192569 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/scanner.c +393 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/alloc.h +54 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/array.h +290 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/parser.h +266 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter-rust.wasm +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter.json +53 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/package.json +3 -2
- package/node_modules/semantifold-tree-sitter-legacy-internal/src/c.js +5 -4
- package/package.json +5 -2
- package/src/artifact-path.js +47 -2
- package/src/artifacts.js +67 -0
- package/src/backends/android.js +1370 -0
- package/src/backends/c-validation.js +6 -1
- package/src/backends/cpp-validation.js +6 -1
- package/src/backends/csharp.js +3 -0
- package/src/backends/dart-runtime.js +41 -0
- package/src/backends/dart.js +326 -0
- package/src/backends/effects.js +705 -0
- package/src/backends/go.js +14 -2
- package/src/backends/identifiers.js +166 -9
- package/src/backends/index.js +27 -2
- package/src/backends/ios.js +1612 -0
- package/src/backends/java.js +454 -36
- package/src/backends/javascript.js +389 -23
- package/src/backends/kotlin-runtime.js +29 -0
- package/src/backends/kotlin.js +144 -0
- package/src/backends/native-validation.js +1 -1
- package/src/backends/ordered-expressions.js +40 -6
- package/src/backends/php-stdlib-support.js +239 -0
- package/src/backends/php.js +469 -32
- package/src/backends/program.js +1408 -0
- package/src/backends/python.js +3 -0
- package/src/backends/ruby.js +326 -23
- package/src/backends/rust-runtime.js +34 -0
- package/src/backends/rust-validation.js +75 -0
- package/src/backends/rust.js +335 -0
- package/src/backends/scalars.js +141 -16
- package/src/backends/shared.js +2314 -115
- package/src/backends/stdlib-support.js +234 -0
- package/src/backends/swift-runtime.js +14 -0
- package/src/backends/swift.js +132 -0
- package/src/backends/typescript.js +349 -23
- package/src/backends/wasm.js +2208 -0
- package/src/backends/writer.js +545 -2
- package/src/diagnostic.js +4 -2
- package/src/frontends/c.js +4 -2
- package/src/frontends/cpp.js +4 -2
- package/src/frontends/csharp.js +4 -2
- package/src/frontends/dart.js +963 -0
- package/src/frontends/index.js +14 -4
- package/src/frontends/java.js +1977 -69
- package/src/frontends/javascript-typescript.js +2046 -102
- package/src/frontends/kotlin.js +713 -0
- package/src/frontends/php.js +1725 -79
- package/src/frontends/program.js +1062 -0
- package/src/frontends/ruby.js +1624 -98
- package/src/frontends/rust-parser.js +18 -0
- package/src/frontends/rust.js +714 -0
- package/src/frontends/scalars.js +31 -1
- package/src/frontends/swift.js +893 -0
- package/src/frontends/types.js +750 -0
- package/src/language-registry.js +182 -12
- package/src/mapping.js +33 -9
- package/src/semantic/capabilities.js +671 -0
- package/src/semantic/effects.js +737 -0
- package/src/semantic/generics.js +58 -0
- package/src/semantic/lifetime.js +517 -0
- package/src/semantic/provenance.js +412 -19
- package/src/semantic/scalars.js +17 -0
- package/src/semantic/stdlib.js +921 -0
- package/src/semantic/types.js +810 -14
- package/src/semantic/validate.js +2934 -209
- package/src/stdlib-facades.js +1211 -0
- package/src/stdlib-negotiation.js +446 -0
- package/src/stdlib-providers.js +377 -0
- package/src/toolchains.js +16 -3
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import {isDenseArray} from "./array.js"
|
|
4
|
+
import {isSafeArtifactPath} from "./artifact-path.js"
|
|
5
|
+
import {SemantifoldDiagnostic} from "./diagnostic.js"
|
|
6
|
+
import {languageRegistry} from "./language-registry.js"
|
|
7
|
+
import {
|
|
8
|
+
listStdlibModules,
|
|
9
|
+
parseStdlibVersion,
|
|
10
|
+
parseStdlibVersionRange,
|
|
11
|
+
protectedEntryName,
|
|
12
|
+
resolveStdlibModule
|
|
13
|
+
} from "./semantic/stdlib.js"
|
|
14
|
+
|
|
15
|
+
export {protectedEntryName} from "./semantic/stdlib.js"
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @typedef StdlibProviderRecord
|
|
19
|
+
* @property {{mediaType: string, path: string}} artifact - Generated provider artifact declaration.
|
|
20
|
+
* @property {readonly {module: string, range: string}[]} dependencies - Canonical module dependencies with declared ranges.
|
|
21
|
+
* @property {string} identity - Stable provider identity rooted at the target.
|
|
22
|
+
* @property {Readonly<Record<string, string>>} nativeEntries - Operation to protected native entry name.
|
|
23
|
+
* @property {readonly {module: string, operations: string[], version: string}[]} provides - Exactly one provided canonical module.
|
|
24
|
+
* @property {string} runtimeProfile - Closed target runtime/provider profile.
|
|
25
|
+
* @property {string} target - Adopted target language identity.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @typedef StdlibProviderRegistry
|
|
30
|
+
* @property {readonly StdlibProviderRecord[]} records - Registered provider records in stable order.
|
|
31
|
+
* @property {{(target: string, module: string, version: string): readonly StdlibProviderRecord[]}} providersFor - Exact provider lookup.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
const providerIdentityPrefix = "semantifold.provider."
|
|
35
|
+
/** @type {Readonly<Record<string, string>>} */
|
|
36
|
+
const targetExtensions = Object.freeze({
|
|
37
|
+
javascript: "js",
|
|
38
|
+
java: "java",
|
|
39
|
+
php: "php",
|
|
40
|
+
ruby: "rb",
|
|
41
|
+
typescript: "ts"
|
|
42
|
+
})
|
|
43
|
+
const builtinProviderTargets = Object.freeze(["php", "ruby", "javascript", "typescript", "java"])
|
|
44
|
+
const probeIdentity = "semantifold.task034.resource-probe"
|
|
45
|
+
const probeOperations = Object.freeze(["probeEffect", "probeAcquire", "probeRead", "probeClose", "probeTrace"])
|
|
46
|
+
const recordKeys = Object.freeze(["artifact", "dependencies", "identity", "nativeEntries", "provides", "runtimeProfile", "target"])
|
|
47
|
+
const task037ProviderModules = Object.freeze([
|
|
48
|
+
Object.freeze({dependencies: [], identity: "semantifold.resource", operations: ["v1_close"]}),
|
|
49
|
+
Object.freeze({dependencies: [{module: "semantifold.resource", range: "1"}], identity: "semantifold.socket-client", operations: ["v1_connect"]}),
|
|
50
|
+
Object.freeze({dependencies: [{module: "semantifold.resource", range: "1"}], identity: "semantifold.text-stream", operations: ["v1_read_line"]}),
|
|
51
|
+
Object.freeze({dependencies: [], identity: "semantifold.output", operations: ["v1_write_line"]})
|
|
52
|
+
])
|
|
53
|
+
/** @type {Readonly<Record<string, string>>} */
|
|
54
|
+
const legacyRuntimeProfiles = Object.freeze({
|
|
55
|
+
javascript: "node24-core-v1",
|
|
56
|
+
java: "java17-core-v1",
|
|
57
|
+
php: "php82-core-v1",
|
|
58
|
+
ruby: "ruby3-core-v1",
|
|
59
|
+
typescript: "node24-typescript7-core-v1"
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Creates the versioned target host stdlib provider registry.
|
|
64
|
+
* @param {unknown} records - Ordered provider records; built-in providers by default.
|
|
65
|
+
* @returns {Readonly<StdlibProviderRegistry>} Frozen registry.
|
|
66
|
+
*/
|
|
67
|
+
export function createStdlibProviderRegistry(records = builtinProviderRecords()) {
|
|
68
|
+
if (!isDenseArray(records)) invalidProvider("Provider records must be an ordered dense array.")
|
|
69
|
+
|
|
70
|
+
/** @type {StdlibProviderRecord[]} */
|
|
71
|
+
const validated = []
|
|
72
|
+
/** @type {Set<string>} */
|
|
73
|
+
const identities = new Set()
|
|
74
|
+
|
|
75
|
+
for (const candidate of records) {
|
|
76
|
+
const record = validateProviderRecord(candidate)
|
|
77
|
+
|
|
78
|
+
if (identities.has(record.identity)) invalidProvider(`Duplicate stdlib provider identity '${record.identity}'.`)
|
|
79
|
+
identities.add(record.identity)
|
|
80
|
+
validated.push(record)
|
|
81
|
+
}
|
|
82
|
+
const frozenRecords = deepFreeze(validated)
|
|
83
|
+
|
|
84
|
+
return Object.freeze(/** @type {Readonly<StdlibProviderRegistry>} */ ({
|
|
85
|
+
records: frozenRecords,
|
|
86
|
+
providersFor(target, module, version) {
|
|
87
|
+
if (typeof target != "string" || typeof module != "string" || typeof version != "string") return Object.freeze([])
|
|
88
|
+
return Object.freeze(frozenRecords.filter((record) =>
|
|
89
|
+
record.target == target && record.provides[0].module == module && record.provides[0].version == version))
|
|
90
|
+
}
|
|
91
|
+
}))
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Lists the built-in target host providers for the probe contract in stable target order.
|
|
96
|
+
* @returns {readonly StdlibProviderRecord[]} Frozen provider records.
|
|
97
|
+
*/
|
|
98
|
+
export function listStdlibProviders() {
|
|
99
|
+
return builtinProviderRegistry().records
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Authoritative built-in provider lookup keyed by exact target, module, and version.
|
|
104
|
+
* @type {{providersFor(target: string, module: string, version: string): readonly StdlibProviderRecord[]}}
|
|
105
|
+
*/
|
|
106
|
+
export const stdlibProviderRegistry = {
|
|
107
|
+
providersFor(target, module, version) {
|
|
108
|
+
return builtinProviderRegistry().providersFor(target, module, version)
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Validates one provider record against the target roles and canonical contract registry.
|
|
114
|
+
* @param {unknown} candidate - Candidate record.
|
|
115
|
+
* @returns {StdlibProviderRecord} Detached frozen record.
|
|
116
|
+
*/
|
|
117
|
+
function validateProviderRecord(candidate) {
|
|
118
|
+
if (!isPlainObject(candidate)) invalidProvider("Every stdlib provider record must be a plain object.")
|
|
119
|
+
if (Object.keys(candidate).sort().join(",") != recordKeys.join(",")) {
|
|
120
|
+
invalidProvider("Every stdlib provider record declares the exact provider record fields.")
|
|
121
|
+
}
|
|
122
|
+
const target = /** @type {string} */ (candidate.target)
|
|
123
|
+
|
|
124
|
+
if (typeof target != "string" || !providerTargetRegistered(target)) {
|
|
125
|
+
invalidProvider(`Stdlib provider target '${String(target)}' is not an adopted target host provider.`)
|
|
126
|
+
}
|
|
127
|
+
const identity = /** @type {string} */ (candidate.identity)
|
|
128
|
+
const identityPrefix = providerIdentityPrefix + target + "."
|
|
129
|
+
|
|
130
|
+
if (typeof identity != "string" || !identity.startsWith(identityPrefix) || identity.length == identityPrefix.length) {
|
|
131
|
+
invalidProvider(`Stdlib provider identity '${String(identity)}' must be rooted at '${identityPrefix}'.`)
|
|
132
|
+
}
|
|
133
|
+
const provides = /** @type {unknown} */ (candidate.provides)
|
|
134
|
+
|
|
135
|
+
if (!isDenseArray(provides) || provides.length != 1) invalidProvider("Every stdlib provider provides exactly one canonical module.")
|
|
136
|
+
const provision = /** @type {unknown} */ (provides[0])
|
|
137
|
+
|
|
138
|
+
if (!isPlainObject(provision) || Object.keys(provision).sort().join(",") != "module,operations,version") {
|
|
139
|
+
invalidProvider("Every stdlib provider provision declares the exact provision fields.")
|
|
140
|
+
}
|
|
141
|
+
const module = /** @type {string} */ (provision.module)
|
|
142
|
+
|
|
143
|
+
if (typeof module != "string" || !/^[a-z][a-z0-9.-]*$/u.test(module)) {
|
|
144
|
+
invalidProvider(`Stdlib provider module '${String(module)}' is not a canonical identity.`)
|
|
145
|
+
}
|
|
146
|
+
const version = /** @type {string} */ (provision.version)
|
|
147
|
+
|
|
148
|
+
if (parseStdlibVersion(version) === null) {
|
|
149
|
+
throw new SemantifoldDiagnostic({
|
|
150
|
+
code: "STDLIB_VERSION_MALFORMED",
|
|
151
|
+
language: target,
|
|
152
|
+
message: `Stdlib provider version '${String(version)}' is not a strict semantic version.`
|
|
153
|
+
})
|
|
154
|
+
}
|
|
155
|
+
const operations = /** @type {unknown} */ (provision.operations)
|
|
156
|
+
|
|
157
|
+
if (!isDenseArray(operations) || operations.length == 0 || !operations.every((operation) =>
|
|
158
|
+
typeof operation == "string" && /^[A-Za-z_][A-Za-z0-9_]*$/u.test(operation)) ||
|
|
159
|
+
new Set(/** @type {string[]} */ (operations)).size != operations.length) {
|
|
160
|
+
invalidProvider(`Stdlib provider '${identity}' declares invalid operations.`)
|
|
161
|
+
}
|
|
162
|
+
const operationList = /** @type {string[]} */ (operations)
|
|
163
|
+
|
|
164
|
+
if (moduleKnown(module)) validateProvision(module, version, operationList)
|
|
165
|
+
const nativeEntries = /** @type {unknown} */ (candidate.nativeEntries)
|
|
166
|
+
|
|
167
|
+
if (!isPlainObject(nativeEntries) || Object.keys(nativeEntries).sort().join(",") !=
|
|
168
|
+
[...operationList].sort().join(",")) {
|
|
169
|
+
invalidProvider(`Stdlib provider '${identity}' native entries must match its operations exactly.`)
|
|
170
|
+
}
|
|
171
|
+
for (const operation of operationList) {
|
|
172
|
+
const expectedEntry = module == probeIdentity
|
|
173
|
+
? protectedEntryName(target, operation)
|
|
174
|
+
: protectedEntryName(target, module, operation)
|
|
175
|
+
|
|
176
|
+
if (/** @type {string} */ (nativeEntries[operation]) != expectedEntry) {
|
|
177
|
+
invalidProvider(`Stdlib provider '${identity}' declares an invalid protected native entry.`)
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
const artifact = /** @type {unknown} */ (candidate.artifact)
|
|
181
|
+
|
|
182
|
+
if (!isPlainObject(artifact) || Object.keys(artifact).sort().join(",") != "mediaType,path") {
|
|
183
|
+
invalidProvider(`Stdlib provider '${identity}' declares an invalid artifact.`)
|
|
184
|
+
}
|
|
185
|
+
const mediaType = /** @type {string} */ (artifact.mediaType)
|
|
186
|
+
const path = /** @type {string} */ (artifact.path)
|
|
187
|
+
const derivedPath = `providers/${target}/${module.replaceAll(".", "/")}.${targetExtensions[target]}`
|
|
188
|
+
|
|
189
|
+
if (typeof mediaType != "string" || mediaType.length == 0 || typeof path != "string" ||
|
|
190
|
+
path != derivedPath || !isSafeArtifactPath(path)) {
|
|
191
|
+
invalidProvider(`Stdlib provider '${identity}' artifact must be generated at '${derivedPath}'.`)
|
|
192
|
+
}
|
|
193
|
+
const dependencies = /** @type {unknown} */ (candidate.dependencies)
|
|
194
|
+
|
|
195
|
+
if (!isDenseArray(dependencies)) invalidProvider(`Stdlib provider '${identity}' dependencies must be a dense array.`)
|
|
196
|
+
/** @type {{module: string, range: string}[]} */
|
|
197
|
+
const validatedDependencies = []
|
|
198
|
+
|
|
199
|
+
for (const dependency of dependencies) {
|
|
200
|
+
if (!isPlainObject(dependency) || Object.keys(dependency).sort().join(",") != "module,range") {
|
|
201
|
+
invalidProvider(`Stdlib provider '${identity}' declares an invalid dependency.`)
|
|
202
|
+
}
|
|
203
|
+
const dependencyModule = /** @type {string} */ (dependency.module)
|
|
204
|
+
const dependencyRange = /** @type {string} */ (dependency.range)
|
|
205
|
+
|
|
206
|
+
if (typeof dependencyModule != "string" || !/^[a-z][a-z0-9.-]*$/u.test(dependencyModule) ||
|
|
207
|
+
parseStdlibVersionRange(dependencyRange) === null) {
|
|
208
|
+
throw new SemantifoldDiagnostic({
|
|
209
|
+
code: "STDLIB_VERSION_MALFORMED",
|
|
210
|
+
language: target,
|
|
211
|
+
message: `Stdlib provider dependency range '${String(dependencyRange)}' is not a canonical version range.`
|
|
212
|
+
})
|
|
213
|
+
}
|
|
214
|
+
validatedDependencies.push({module: dependencyModule, range: /** @type {string} */ (dependencyRange)})
|
|
215
|
+
}
|
|
216
|
+
const runtimeProfile = /** @type {string} */ (candidate.runtimeProfile)
|
|
217
|
+
|
|
218
|
+
if (typeof runtimeProfile != "string" || !/^[a-z][a-z0-9-]*-v[1-9][0-9]*$/u.test(runtimeProfile)) {
|
|
219
|
+
invalidProvider(`Stdlib provider '${identity}' declares an invalid runtime profile.`)
|
|
220
|
+
}
|
|
221
|
+
if (module != probeIdentity && (target != "php" || runtimeProfile != "php82-core-streams-v1")) {
|
|
222
|
+
invalidProvider(`Stdlib provider '${identity}' does not use the Task 037 PHP 8.2 core-streams profile.`)
|
|
223
|
+
}
|
|
224
|
+
return deepFreeze(/** @type {StdlibProviderRecord} */ ({
|
|
225
|
+
artifact: {mediaType, path},
|
|
226
|
+
dependencies: validatedDependencies,
|
|
227
|
+
identity,
|
|
228
|
+
nativeEntries: Object.freeze(Object.fromEntries(operationList.map((operation) => [
|
|
229
|
+
operation,
|
|
230
|
+
/** @type {string} */ (nativeEntries[operation])
|
|
231
|
+
]))),
|
|
232
|
+
provides: [{module, operations: operationList, version: /** @type {string} */ (version)}],
|
|
233
|
+
runtimeProfile,
|
|
234
|
+
target
|
|
235
|
+
}))
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Checks the provisioned module version and operations against the canonical contract registry.
|
|
240
|
+
* @param {string} module - Canonical module identity.
|
|
241
|
+
* @param {string} version - Strict provider version.
|
|
242
|
+
* @param {string[]} operations - Provided operations.
|
|
243
|
+
* @returns {void}
|
|
244
|
+
*/
|
|
245
|
+
function validateProvision(module, version, operations) {
|
|
246
|
+
const listed = listStdlibModules().find(({identity}) => identity == module)
|
|
247
|
+
|
|
248
|
+
if (!listed || !listed.versions.includes(version)) {
|
|
249
|
+
invalidProvider(`Stdlib provider version '${version}' is not registered for module '${module}'.`)
|
|
250
|
+
}
|
|
251
|
+
const declared = new Set(resolveStdlibModule(module, version).operations.map(({name}) => name))
|
|
252
|
+
|
|
253
|
+
for (const operation of operations) {
|
|
254
|
+
if (!declared.has(operation)) {
|
|
255
|
+
throw new SemantifoldDiagnostic({
|
|
256
|
+
code: "STDLIB_OPERATION_UNDECLARED",
|
|
257
|
+
language: module,
|
|
258
|
+
message: `Operation '${operation}' is not declared by canonical module '${module}'.`
|
|
259
|
+
})
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Reports whether a target is registered with the provider role.
|
|
266
|
+
* @param {unknown} target - Candidate target identity.
|
|
267
|
+
* @returns {boolean} Whether the target adopts the provider role.
|
|
268
|
+
*/
|
|
269
|
+
function providerTargetRegistered(target) {
|
|
270
|
+
if (typeof target != "string") return false
|
|
271
|
+
try {
|
|
272
|
+
return languageRegistry.record(target).provider === true
|
|
273
|
+
} catch {
|
|
274
|
+
return false
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Reports whether a module identity is known to the built-in canonical contract registry.
|
|
280
|
+
* @param {string} module - Canonical module identity.
|
|
281
|
+
* @returns {boolean} Whether the identity resolves.
|
|
282
|
+
*/
|
|
283
|
+
function moduleKnown(module) {
|
|
284
|
+
try {
|
|
285
|
+
resolveStdlibModule(module)
|
|
286
|
+
return true
|
|
287
|
+
} catch {
|
|
288
|
+
return false
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Builds the built-in provider records for the adopted targets.
|
|
294
|
+
* @returns {unknown[]} Unvalidated built-in records.
|
|
295
|
+
*/
|
|
296
|
+
function builtinProviderRecords() {
|
|
297
|
+
const probeProviders = builtinProviderTargets.map((target) => ({
|
|
298
|
+
artifact: {
|
|
299
|
+
mediaType: /** @type {string} */ (languageRegistry.record(target).mediaType),
|
|
300
|
+
path: `providers/${target}/${probeIdentity.replaceAll(".", "/")}.${targetExtensions[target]}`
|
|
301
|
+
},
|
|
302
|
+
dependencies: [],
|
|
303
|
+
identity: `semantifold.provider.${target}.${probeIdentity}`,
|
|
304
|
+
nativeEntries: Object.fromEntries(probeOperations.map((operation) => [operation, protectedEntryName(target, operation)])),
|
|
305
|
+
provides: [{module: probeIdentity, operations: [...probeOperations], version: "1.0.0"}],
|
|
306
|
+
runtimeProfile: legacyRuntimeProfiles[target],
|
|
307
|
+
target
|
|
308
|
+
}))
|
|
309
|
+
const task037Providers = task037ProviderModules.map((module) => ({
|
|
310
|
+
artifact: {
|
|
311
|
+
mediaType: /** @type {string} */ (languageRegistry.record("php").mediaType),
|
|
312
|
+
path: `providers/php/${module.identity.replaceAll(".", "/")}.php`
|
|
313
|
+
},
|
|
314
|
+
dependencies: module.dependencies,
|
|
315
|
+
identity: `semantifold.provider.php.${module.identity}`,
|
|
316
|
+
nativeEntries: Object.fromEntries(module.operations.map((operation) => [
|
|
317
|
+
operation,
|
|
318
|
+
protectedEntryName("php", module.identity, operation)
|
|
319
|
+
])),
|
|
320
|
+
provides: [{module: module.identity, operations: module.operations, version: "1.0.0"}],
|
|
321
|
+
runtimeProfile: "php82-core-streams-v1",
|
|
322
|
+
target: "php"
|
|
323
|
+
}))
|
|
324
|
+
|
|
325
|
+
return [...probeProviders, ...task037Providers]
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/** @type {Readonly<StdlibProviderRegistry> | null} */
|
|
329
|
+
let builtinProviderRegistryValue = null
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Lazily materializes the built-in provider registry after language-registry initialization.
|
|
333
|
+
* @returns {Readonly<StdlibProviderRegistry>} Built-in registry.
|
|
334
|
+
*/
|
|
335
|
+
function builtinProviderRegistry() {
|
|
336
|
+
if (builtinProviderRegistryValue === null) {
|
|
337
|
+
builtinProviderRegistryValue = createStdlibProviderRegistry(builtinProviderRecords())
|
|
338
|
+
}
|
|
339
|
+
return builtinProviderRegistryValue
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Throws a normalized provider-registry diagnostic.
|
|
344
|
+
* @param {string} message - Failure detail.
|
|
345
|
+
* @returns {never} Always throws.
|
|
346
|
+
*/
|
|
347
|
+
function invalidProvider(message) {
|
|
348
|
+
throw new SemantifoldDiagnostic({code: "STDLIB_PROVIDER_INVALID", language: "stdlib", message})
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Checks for an ordinary string-keyed object.
|
|
353
|
+
* @param {unknown} value - Candidate value.
|
|
354
|
+
* @returns {value is Record<string, unknown>} Whether the value is a plain object.
|
|
355
|
+
*/
|
|
356
|
+
function isPlainObject(value) {
|
|
357
|
+
if (typeof value != "object" || value === null) return false
|
|
358
|
+
const prototype = Object.getPrototypeOf(value)
|
|
359
|
+
|
|
360
|
+
return prototype === Object.prototype || prototype === null
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* Deep-freezes a detached value.
|
|
365
|
+
* @template T
|
|
366
|
+
* @param {T} value - Detached value.
|
|
367
|
+
* @returns {Readonly<T>} Frozen value.
|
|
368
|
+
*/
|
|
369
|
+
function deepFreeze(value) {
|
|
370
|
+
if (typeof value != "object" || value === null || Object.isFrozen(value)) return /** @type {Readonly<T>} */ (value)
|
|
371
|
+
Object.freeze(value)
|
|
372
|
+
|
|
373
|
+
for (const property of Object.getOwnPropertyNames(value)) {
|
|
374
|
+
deepFreeze(/** @type {unknown} */ ((/** @type {Record<string, unknown>} */ (value))[property]))
|
|
375
|
+
}
|
|
376
|
+
return /** @type {Readonly<T>} */ (value)
|
|
377
|
+
}
|
package/src/toolchains.js
CHANGED
|
@@ -11,17 +11,28 @@ import {isSupportedTimeoutMs, maximumTimeoutMs} from "./timeout.js"
|
|
|
11
11
|
const defaultTimeoutMs = 10_000
|
|
12
12
|
|
|
13
13
|
export const canonicalToolchains = deepFreeze({
|
|
14
|
+
dart: definition("dart", "SEMANTIFOLD_DART", ["--version"],
|
|
15
|
+
/^Dart SDK version: 3\.13\.3 \(stable\) \(Tue Sep 1 01:07:17 2026 -0700\) on "linux_x64"$/u),
|
|
14
16
|
php: definition("php", "SEMANTIFOLD_PHP", ["--version"], /^PHP 8\./u),
|
|
17
|
+
php82: definition("php", "SEMANTIFOLD_PHP", ["--version"], /^PHP (?:8\.(?:[2-9]|[1-9][0-9]+)|(?:9|[1-9][0-9]+)\.[0-9]+)\./u),
|
|
15
18
|
ruby: definition("ruby", "SEMANTIFOLD_RUBY", ["--version"], /^ruby 3\./u),
|
|
16
19
|
node: definition("node", "SEMANTIFOLD_NODE", ["--version"], /^v24\./u),
|
|
17
20
|
tsc: definition("tsc", "SEMANTIFOLD_TSC", ["--version"], /^Version 7\./u),
|
|
18
21
|
javac: definition("javac", "SEMANTIFOLD_JAVAC", ["-version"], /^javac (?:1[7-9]|2[0-9])\./u),
|
|
19
22
|
java: definition("java", "SEMANTIFOLD_JAVA", ["-version"], /^(?:openjdk|java) version "(?:1[7-9]|2[0-9])\./u),
|
|
23
|
+
java25: definition("java", "SEMANTIFOLD_JAVA", ["-version"],
|
|
24
|
+
/^openjdk version "25\.0\.4" 2026-07-21\nOpenJDK Runtime Environment \(build 25\.0\.4\+7-1-((?:24|26)\.04)-Ubuntu\)\nOpenJDK 64-Bit Server VM \(build 25\.0\.4\+7-1-\1-Ubuntu, mixed mode, sharing\)$/u),
|
|
25
|
+
kotlinc: definition("kotlinc", "SEMANTIFOLD_KOTLINC", ["-version"], /^info: kotlinc-jvm 2\.4\.20 \(JRE 25\.0\.4\+7-1-(?:24|26)\.04-Ubuntu\)$/u),
|
|
20
26
|
python: definition("python3", "SEMANTIFOLD_PYTHON", ["--version"], /^Python 3\./u),
|
|
21
27
|
dotnet: definition("dotnet", "SEMANTIFOLD_DOTNET", ["--version"], /^10\./u),
|
|
22
28
|
go: definition("go", "SEMANTIFOLD_GO", ["version"], /^go version go1\.26\.\d+ linux\/amd64$/u),
|
|
23
29
|
clangpp: definition("clang++", "SEMANTIFOLD_CLANGPP", ["--version"], /^Ubuntu clang version 21\.1\.8 [^\n]+\nTarget: x86_64-pc-linux-gnu\n/u),
|
|
24
|
-
clang: definition("clang", "SEMANTIFOLD_CLANG", ["--version"], /^Ubuntu clang version 21\.1\.8 [^\n]+\nTarget: x86_64-pc-linux-gnu\n/u)
|
|
30
|
+
clang: definition("clang", "SEMANTIFOLD_CLANG", ["--version"], /^Ubuntu clang version 21\.1\.8 [^\n]+\nTarget: x86_64-pc-linux-gnu\n/u),
|
|
31
|
+
rustc: definition("rustc", "SEMANTIFOLD_RUSTC", ["--version", "--verbose"], /^rustc 1\.98\.1 \(48a229cea 2026-09-01\)\nbinary: rustc\ncommit-hash: 48a229ceaefd4985c50990b14116b6d856af0985\ncommit-date: 2026-09-01\nhost: x86_64-unknown-linux-gnu\nrelease: 1\.98\.1\nLLVM version: 22\.1\.8$/u),
|
|
32
|
+
cargo: definition("cargo", "SEMANTIFOLD_CARGO", ["--version", "--verbose"], /^cargo 1\.98\.1 \(797e8a9bc 2026-08-05\)\nrelease: 1\.98\.1\ncommit-hash: 797e8a9bca276c1c9f9f738d2a20f484fa4eea9d\ncommit-date: 2026-08-05\nhost: x86_64-unknown-linux-gnu\n/u),
|
|
33
|
+
swiftc: definition("swiftc", "SEMANTIFOLD_SWIFTC", ["--driver-mode=swiftc", "--version"], /^Swift version 6\.3\.3 \(swift-6\.3\.3-RELEASE\)\nTarget: x86_64-unknown-linux-gnu$/u),
|
|
34
|
+
"wasm-validate": definition("wasm-validate", "SEMANTIFOLD_WASM_VALIDATE", ["--version"], /^1\.0\.36$/u),
|
|
35
|
+
chromium: definition("chromium", "SEMANTIFOLD_CHROMIUM", ["--version"], /^Google Chrome 152\.0\.7977\.82$/u)
|
|
25
36
|
})
|
|
26
37
|
|
|
27
38
|
/**
|
|
@@ -68,7 +79,7 @@ export async function discoverCanonicalToolchain(id, options = {}) {
|
|
|
68
79
|
* @param {Readonly<Record<string, string | undefined>>} [input.environment] - Explicit discovery environment.
|
|
69
80
|
* @param {string} input.id - Toolchain ID.
|
|
70
81
|
* @param {string} [input.override] - Configured absolute executable path.
|
|
71
|
-
* @param {RegExp} [input.supportedVersion] - Full
|
|
82
|
+
* @param {RegExp} [input.supportedVersion] - Full selected-stream version policy.
|
|
72
83
|
* @param {number} [input.timeoutMs] - Version command timeout.
|
|
73
84
|
* @param {string[]} input.versionArguments - Exact version argument array.
|
|
74
85
|
* @returns {Promise<import("./semantic/types.js").DiscoveredToolchain>} Discovered tool.
|
|
@@ -132,7 +143,9 @@ export async function discoverToolchain(input) {
|
|
|
132
143
|
}
|
|
133
144
|
|
|
134
145
|
const {stderr, stdout} = result
|
|
135
|
-
const
|
|
146
|
+
const normalizedStdout = stdout.trim()
|
|
147
|
+
const normalizedStderr = stderr.trim()
|
|
148
|
+
const versionOutput = normalizedStdout.length > 0 ? normalizedStdout : normalizedStderr
|
|
136
149
|
const version = versionOutput.split(/\r?\n/u)[0] ?? ""
|
|
137
150
|
|
|
138
151
|
if (version.length == 0) {
|