@agentxm/extension-discovery 0.28.4-bootstrap.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.
Files changed (72) hide show
  1. package/LICENSE +110 -0
  2. package/dist/src/discover.d.ts +34 -0
  3. package/dist/src/discover.js +133 -0
  4. package/dist/src/index.d.ts +13 -0
  5. package/dist/src/index.js +12 -0
  6. package/dist/src/internal/environment.d.ts +14 -0
  7. package/dist/src/internal/environment.js +15 -0
  8. package/dist/src/packaging/bazel.d.ts +27 -0
  9. package/dist/src/packaging/bazel.js +125 -0
  10. package/dist/src/packaging/cargo.d.ts +32 -0
  11. package/dist/src/packaging/cargo.js +270 -0
  12. package/dist/src/packaging/cocoapods.d.ts +26 -0
  13. package/dist/src/packaging/cocoapods.js +187 -0
  14. package/dist/src/packaging/composer.d.ts +26 -0
  15. package/dist/src/packaging/composer.js +144 -0
  16. package/dist/src/packaging/conan.d.ts +30 -0
  17. package/dist/src/packaging/conan.js +238 -0
  18. package/dist/src/packaging/conda.d.ts +26 -0
  19. package/dist/src/packaging/conda.js +320 -0
  20. package/dist/src/packaging/cpan.d.ts +29 -0
  21. package/dist/src/packaging/cpan.js +189 -0
  22. package/dist/src/packaging/cran.d.ts +29 -0
  23. package/dist/src/packaging/cran.js +176 -0
  24. package/dist/src/packaging/detect.d.ts +16 -0
  25. package/dist/src/packaging/detect.js +25 -0
  26. package/dist/src/packaging/detected-package.d.ts +14 -0
  27. package/dist/src/packaging/detected-package.js +20 -0
  28. package/dist/src/packaging/docker.d.ts +27 -0
  29. package/dist/src/packaging/docker.js +256 -0
  30. package/dist/src/packaging/gem.d.ts +26 -0
  31. package/dist/src/packaging/gem.js +234 -0
  32. package/dist/src/packaging/golang.d.ts +26 -0
  33. package/dist/src/packaging/golang.js +169 -0
  34. package/dist/src/packaging/hackage.d.ts +26 -0
  35. package/dist/src/packaging/hackage.js +305 -0
  36. package/dist/src/packaging/hex.d.ts +28 -0
  37. package/dist/src/packaging/hex.js +186 -0
  38. package/dist/src/packaging/huggingface.d.ts +20 -0
  39. package/dist/src/packaging/huggingface.js +112 -0
  40. package/dist/src/packaging/index.d.ts +44 -0
  41. package/dist/src/packaging/index.js +120 -0
  42. package/dist/src/packaging/jsr.d.ts +30 -0
  43. package/dist/src/packaging/jsr.js +227 -0
  44. package/dist/src/packaging/julia.d.ts +27 -0
  45. package/dist/src/packaging/julia.js +165 -0
  46. package/dist/src/packaging/luarocks.d.ts +28 -0
  47. package/dist/src/packaging/luarocks.js +159 -0
  48. package/dist/src/packaging/maven.d.ts +27 -0
  49. package/dist/src/packaging/maven.js +471 -0
  50. package/dist/src/packaging/mojo.d.ts +29 -0
  51. package/dist/src/packaging/mojo.js +148 -0
  52. package/dist/src/packaging/npm.d.ts +26 -0
  53. package/dist/src/packaging/npm.js +190 -0
  54. package/dist/src/packaging/nuget.d.ts +26 -0
  55. package/dist/src/packaging/nuget.js +240 -0
  56. package/dist/src/packaging/opam.d.ts +27 -0
  57. package/dist/src/packaging/opam.js +287 -0
  58. package/dist/src/packaging/pub.d.ts +26 -0
  59. package/dist/src/packaging/pub.js +357 -0
  60. package/dist/src/packaging/pypi.d.ts +23 -0
  61. package/dist/src/packaging/pypi.js +448 -0
  62. package/dist/src/packaging/read.d.ts +20 -0
  63. package/dist/src/packaging/read.js +31 -0
  64. package/dist/src/packaging/reader-io.d.ts +29 -0
  65. package/dist/src/packaging/reader-io.js +29 -0
  66. package/dist/src/packaging/swift.d.ts +26 -0
  67. package/dist/src/packaging/swift.js +141 -0
  68. package/dist/src/packaging/types.d.ts +43 -0
  69. package/dist/src/packaging/types.js +8 -0
  70. package/dist/src/packaging/zig.d.ts +32 -0
  71. package/dist/src/packaging/zig.js +151 -0
  72. package/package.json +54 -0
@@ -0,0 +1,190 @@
1
+ /**
2
+ * npm package detector and reader for package-compatibility discovery.
3
+ *
4
+ * @experimental This API is unstable and may change without notice.
5
+ * @packageDocumentation
6
+ */
7
+ import * as Effect from "effect/Effect";
8
+ import * as Option from "effect/Option";
9
+ import * as Path from "effect/Path";
10
+ import * as Result from "effect/Result";
11
+ import * as Schema from "effect/Schema";
12
+ import { makeDetectedPackage } from "./detected-package.js";
13
+ import { PackageTypeSchema } from "@agentxm/extension-model/unstable/packaging/package-type";
14
+ import { decodeAxmMeta, parseJsonOptional, readFileOptional } from "./reader-io.js";
15
+ const npmType = Schema.decodeUnknownSync(PackageTypeSchema)("npm");
16
+ /** Schema to extract the optional "axm" field from a package.json object. */
17
+ const AxmContainerSchema = Schema.Struct({
18
+ axm: Schema.optional(Schema.Unknown),
19
+ });
20
+ const decodeAxmContainer = Schema.decodeUnknownResult(AxmContainerSchema);
21
+ /** Prefixes that indicate non-registry specifiers to skip. */
22
+ const SKIP_PREFIXES = ["file:", "link:", "workspace:", "git+", "git:", "github:"];
23
+ /** Returns true if the specifier should be skipped (non-registry). */
24
+ const isSkippedSpecifier = (specifier) => {
25
+ if (SKIP_PREFIXES.some((prefix) => specifier.startsWith(prefix)))
26
+ return true;
27
+ // URL-based specifiers
28
+ if (specifier.startsWith("http://") || specifier.startsWith("https://"))
29
+ return true;
30
+ return false;
31
+ };
32
+ /**
33
+ * Returns true if the specifier is an exact semver version (no range operators).
34
+ * Exact versions match: digits and dots only, e.g. "18.2.0", "1.0.0-beta.1".
35
+ */
36
+ const isExactVersion = (specifier) => /^\d+\.\d+\.\d+(?:[-+][a-zA-Z0-9._+-]*)?$/.test(specifier);
37
+ /**
38
+ * Parse an npm alias specifier like "npm:real-name@version" or "npm:@scope/name@version".
39
+ * Returns { name, specifier } where name is the real package name and specifier is the version part.
40
+ */
41
+ const parseNpmAlias = (specifier) => {
42
+ if (!specifier.startsWith("npm:"))
43
+ return undefined;
44
+ const rest = specifier.slice(4); // Remove "npm:" prefix
45
+ // Handle scoped: npm:@scope/name@version
46
+ if (rest.startsWith("@")) {
47
+ const atIdx = rest.indexOf("@", 1);
48
+ if (atIdx === -1)
49
+ return { name: rest, specifier: "*" };
50
+ return { name: rest.slice(0, atIdx), specifier: rest.slice(atIdx + 1) };
51
+ }
52
+ // Handle unscoped: npm:name@version
53
+ const atIdx = rest.indexOf("@");
54
+ if (atIdx === -1)
55
+ return { name: rest, specifier: "*" };
56
+ return { name: rest.slice(0, atIdx), specifier: rest.slice(atIdx + 1) };
57
+ };
58
+ /**
59
+ * Parse a package name into namespace and name parts.
60
+ * "@scope/name" -> { namespace: "@scope", name: "name" }
61
+ * "name" -> { name: "name" }
62
+ */
63
+ const parsePackageName = (pkgName) => {
64
+ if (pkgName.startsWith("@")) {
65
+ const slashIdx = pkgName.indexOf("/");
66
+ if (slashIdx > 0) {
67
+ return { namespace: pkgName.slice(0, slashIdx), name: pkgName.slice(slashIdx + 1) };
68
+ }
69
+ }
70
+ return { name: pkgName };
71
+ };
72
+ /**
73
+ * Convert a single dependency entry to a DetectedPackage, or undefined if skipped.
74
+ */
75
+ const depToPurl = (depName, specifier, source) => {
76
+ if (isSkippedSpecifier(specifier))
77
+ return undefined;
78
+ // Resolve npm aliases to real package name
79
+ const alias = parseNpmAlias(specifier);
80
+ const resolvedName = alias ? alias.name : depName;
81
+ const resolvedSpecifier = alias ? alias.specifier : specifier;
82
+ const { namespace, name } = parsePackageName(resolvedName);
83
+ const version = isExactVersion(resolvedSpecifier) ? resolvedSpecifier : undefined;
84
+ return Option.getOrUndefined(makeDetectedPackage({
85
+ type: npmType,
86
+ ...(namespace === undefined ? {} : { namespace }),
87
+ name,
88
+ ...(version === undefined ? {} : { version }),
89
+ source,
90
+ }));
91
+ };
92
+ /**
93
+ * Schema to loosely decode the dependency-relevant shape of package.json.
94
+ * Accepts any object shape and extracts the three dependency sections
95
+ * as optional string-to-string records.
96
+ */
97
+ const DependencySectionsSchema = Schema.Struct({
98
+ dependencies: Schema.optional(Schema.Record(Schema.String, Schema.String)),
99
+ devDependencies: Schema.optional(Schema.Record(Schema.String, Schema.String)),
100
+ peerDependencies: Schema.optional(Schema.Record(Schema.String, Schema.String)),
101
+ });
102
+ const decodeDependencySections = Schema.decodeUnknownResult(DependencySectionsSchema);
103
+ /**
104
+ * Extract dependencies from a parsed package.json value.
105
+ */
106
+ const extractDeps = (manifest, source) => {
107
+ const decoded = decodeDependencySections(manifest);
108
+ if (Result.isFailure(decoded))
109
+ return [];
110
+ const sections = [
111
+ decoded.success.dependencies,
112
+ decoded.success.devDependencies,
113
+ decoded.success.peerDependencies,
114
+ ];
115
+ const results = [];
116
+ for (const deps of sections) {
117
+ if (deps === undefined)
118
+ continue;
119
+ for (const [name, specifier] of Object.entries(deps)) {
120
+ const detected = depToPurl(name, specifier, source);
121
+ if (detected !== undefined)
122
+ results.push(detected);
123
+ }
124
+ }
125
+ return results;
126
+ };
127
+ /**
128
+ * npm package detector.
129
+ *
130
+ * Scans `package.json` in the project directory and extracts dependencies
131
+ * from `dependencies`, `devDependencies`, and `peerDependencies`.
132
+ *
133
+ * @experimental This API is unstable and may change without notice.
134
+ */
135
+ export const npmDetector = {
136
+ type: npmType,
137
+ detect: Effect.fn("detect.npm")(function* (projectDir) {
138
+ const path = yield* Path.Path;
139
+ const manifestPath = path.join(projectDir, "package.json");
140
+ const content = yield* readFileOptional(manifestPath);
141
+ if (Option.isNone(content))
142
+ return [];
143
+ const parsed = yield* parseJsonOptional(content.value, "package.json");
144
+ if (Option.isNone(parsed))
145
+ return [];
146
+ return extractDeps(parsed.value, manifestPath);
147
+ }, Effect.annotateLogs({ detector: "npm" }), Effect.withSpan("detect.npm")),
148
+ };
149
+ /**
150
+ * npm package reader.
151
+ *
152
+ * Reads `node_modules/<name>/package.json` for each detected npm package
153
+ * and extracts the `"axm"` field containing recommendation metadata.
154
+ *
155
+ * @experimental This API is unstable and may change without notice.
156
+ */
157
+ export const npmReader = {
158
+ type: npmType,
159
+ read: Effect.fn("read.npm")(function* (pkg) {
160
+ const path = yield* Path.Path;
161
+ // Derive project directory from the source manifest path
162
+ const projectDir = path.dirname(pkg.source);
163
+ // Reconstruct the package name from purl parts
164
+ const pkgName = pkg.purl.namespace ? `${pkg.purl.namespace}/${pkg.purl.name}` : pkg.purl.name;
165
+ const pkgJsonPath = path.join(projectDir, "node_modules", pkgName, "package.json");
166
+ const content = yield* readFileOptional(pkgJsonPath);
167
+ if (Option.isNone(content))
168
+ return Option.none();
169
+ const parsed = yield* parseJsonOptional(content.value, pkgName);
170
+ if (Option.isNone(parsed))
171
+ return Option.none();
172
+ // Extract and validate the "axm" field using schema
173
+ const axmContainerResult = decodeAxmContainer(parsed.value);
174
+ if (Result.isFailure(axmContainerResult)) {
175
+ // No valid axm field present (or missing entirely)
176
+ return Option.none();
177
+ }
178
+ const axmRaw = axmContainerResult.success.axm;
179
+ if (axmRaw === undefined)
180
+ return Option.none();
181
+ // Validate axm metadata structure
182
+ const metaResult = decodeAxmMeta(axmRaw);
183
+ if (Result.isFailure(metaResult)) {
184
+ yield* Effect.logWarning(`Invalid axm metadata in ${pkgName}: schema validation failed`);
185
+ return Option.none();
186
+ }
187
+ return Option.some(metaResult.success.extensions);
188
+ }, Effect.annotateLogs({ reader: "npm" }), Effect.withSpan("read.npm")),
189
+ };
190
+ //# sourceMappingURL=npm.js.map
@@ -0,0 +1,26 @@
1
+ /**
2
+ * NuGet package detector and reader for package-compatibility discovery.
3
+ *
4
+ * @experimental This API is unstable and may change without notice.
5
+ * @packageDocumentation
6
+ */
7
+ import type { PackageDetector, PackageReader } from "./types.js";
8
+ /**
9
+ * NuGet package detector.
10
+ *
11
+ * Scans `.csproj`, `.fsproj`, `.vbproj`, `Directory.Packages.props`,
12
+ * and `packages.config` files in the project directory.
13
+ *
14
+ * @experimental This API is unstable and may change without notice.
15
+ */
16
+ export declare const nugetDetector: PackageDetector;
17
+ /**
18
+ * NuGet package reader.
19
+ *
20
+ * Reads `axm.json` from `~/.nuget/packages/{id}/{version}/` for each
21
+ * detected NuGet package and extracts recommendation metadata.
22
+ *
23
+ * @experimental This API is unstable and may change without notice.
24
+ */
25
+ export declare const nugetReader: PackageReader;
26
+ //# sourceMappingURL=nuget.d.ts.map
@@ -0,0 +1,240 @@
1
+ /**
2
+ * NuGet package detector and reader for package-compatibility discovery.
3
+ *
4
+ * @experimental This API is unstable and may change without notice.
5
+ * @packageDocumentation
6
+ */
7
+ // Intentional escape hatch: node:os homedir() has no @effect/platform equivalent.
8
+ import * as os from "node:os";
9
+ import * as Effect from "effect/Effect";
10
+ import * as FileSystem from "effect/FileSystem";
11
+ import * as Option from "effect/Option";
12
+ import * as Path from "effect/Path";
13
+ import * as Result from "effect/Result";
14
+ import * as Schema from "effect/Schema";
15
+ import { readEnv } from "../internal/environment.js";
16
+ import { makeDetectedPackage } from "./detected-package.js";
17
+ import { PackageTypeSchema } from "@agentxm/extension-model/unstable/packaging/package-type";
18
+ import { decodeAxmMeta, parseJsonOptional, readFileOptional } from "./reader-io.js";
19
+ const nugetType = Schema.decodeUnknownSync(PackageTypeSchema)("nuget");
20
+ /**
21
+ * Returns true if the version string is a NuGet version range.
22
+ * Ranges use brackets/parens like [1.0,2.0), (,1.0], etc.
23
+ */
24
+ const isNugetVersionRange = (version) => /^[[(]/.test(version) || /[)\]]$/.test(version);
25
+ /**
26
+ * Returns true if the version string is a floating version (e.g., "1.0.*").
27
+ */
28
+ const isFloatingVersion = (version) => version.includes("*");
29
+ /**
30
+ * Returns true if the version is an exact version (not a range or floating).
31
+ */
32
+ const isExactVersion = (version) => !isNugetVersionRange(version) && !isFloatingVersion(version) && version.trim() !== "";
33
+ /**
34
+ * Create a DetectedPackage from a NuGet package name and optional version.
35
+ * Names are lowercased per NuGet case-insensitivity.
36
+ */
37
+ const makeNugetPackage = (name, version, source) => {
38
+ const loweredName = name.toLowerCase();
39
+ const resolvedVersion = version !== undefined && isExactVersion(version) ? version : undefined;
40
+ return Option.getOrUndefined(makeDetectedPackage({
41
+ type: nugetType,
42
+ name: loweredName,
43
+ ...(resolvedVersion === undefined ? {} : { version: resolvedVersion }),
44
+ source,
45
+ }));
46
+ };
47
+ const appendNugetPackage = (results, name, version, source) => {
48
+ const detected = makeNugetPackage(name, version, source);
49
+ if (detected !== undefined)
50
+ results.push(detected);
51
+ };
52
+ /**
53
+ * Extract an XML attribute value from a tag string.
54
+ */
55
+ const extractAttribute = (tag, attrName) => {
56
+ const regex = new RegExp(`${attrName}\\s*=\\s*"([^"]*)"`, "i");
57
+ const match = regex.exec(tag);
58
+ return match?.[1];
59
+ };
60
+ /**
61
+ * Parse .csproj/.fsproj/.vbproj content and extract PackageReference elements.
62
+ */
63
+ const parseProjectFile = (content, source) => {
64
+ const results = [];
65
+ // Match self-closing PackageReference tags
66
+ const selfClosingRegex = /<PackageReference\s+[^>]*\/>/gi;
67
+ let match;
68
+ while ((match = selfClosingRegex.exec(content)) !== null) {
69
+ const tag = match[0];
70
+ const name = extractAttribute(tag, "Include");
71
+ if (name === undefined)
72
+ continue;
73
+ const version = extractAttribute(tag, "Version");
74
+ appendNugetPackage(results, name, version, source);
75
+ }
76
+ // Match PackageReference with child elements (e.g. <Version> child)
77
+ const blockRegex = /<PackageReference\s+([^>]*)>([\s\S]*?)<\/PackageReference>/gi;
78
+ while ((match = blockRegex.exec(content)) !== null) {
79
+ const attrs = match[1];
80
+ const body = match[2];
81
+ if (attrs === undefined)
82
+ continue;
83
+ const name = extractAttribute(attrs, "Include");
84
+ if (name === undefined)
85
+ continue;
86
+ // Try attribute first, then child element
87
+ let version = extractAttribute(attrs, "Version");
88
+ if (version === undefined && body !== undefined) {
89
+ const versionMatch = /<Version>\s*(.*?)\s*<\/Version>/i.exec(body);
90
+ version = versionMatch?.[1];
91
+ }
92
+ appendNugetPackage(results, name, version, source);
93
+ }
94
+ return results;
95
+ };
96
+ /**
97
+ * Parse Directory.Packages.props content and extract PackageVersion elements.
98
+ */
99
+ const parseDirectoryPackagesProps = (content, source) => {
100
+ const results = [];
101
+ const pkgVersionRegex = /<PackageVersion\s+[^>]*\/>/gi;
102
+ let match;
103
+ while ((match = pkgVersionRegex.exec(content)) !== null) {
104
+ const tag = match[0];
105
+ const name = extractAttribute(tag, "Include");
106
+ if (name === undefined)
107
+ continue;
108
+ const version = extractAttribute(tag, "Version");
109
+ appendNugetPackage(results, name, version, source);
110
+ }
111
+ return results;
112
+ };
113
+ /**
114
+ * Parse packages.config content and extract package elements.
115
+ */
116
+ const parsePackagesConfig = (content, source) => {
117
+ const results = [];
118
+ const pkgRegex = /<package\s+[^>]*\/>/gi;
119
+ let match;
120
+ while ((match = pkgRegex.exec(content)) !== null) {
121
+ const tag = match[0];
122
+ const name = extractAttribute(tag, "id");
123
+ if (name === undefined)
124
+ continue;
125
+ const version = extractAttribute(tag, "version");
126
+ appendNugetPackage(results, name, version, source);
127
+ }
128
+ return results;
129
+ };
130
+ /**
131
+ * Deduplicate packages by lowercased name.
132
+ */
133
+ const deduplicatePackages = (packages) => {
134
+ const seen = new Set();
135
+ const results = [];
136
+ for (const pkg of packages) {
137
+ const key = pkg.purl.name.toLowerCase();
138
+ if (!seen.has(key)) {
139
+ seen.add(key);
140
+ results.push(pkg);
141
+ }
142
+ }
143
+ return results;
144
+ };
145
+ /**
146
+ * NuGet package detector.
147
+ *
148
+ * Scans `.csproj`, `.fsproj`, `.vbproj`, `Directory.Packages.props`,
149
+ * and `packages.config` files in the project directory.
150
+ *
151
+ * @experimental This API is unstable and may change without notice.
152
+ */
153
+ export const nugetDetector = {
154
+ type: nugetType,
155
+ detect: Effect.fn("detect.nuget")(function* (projectDir) {
156
+ const path = yield* Path.Path;
157
+ const fs = yield* FileSystem.FileSystem;
158
+ const allPackages = [];
159
+ // Find and parse project files (*.csproj, *.fsproj, *.vbproj)
160
+ const entries = yield* fs.readDirectory(projectDir).pipe(Effect.option);
161
+ if (Option.isSome(entries)) {
162
+ const projectFiles = entries.value.filter((e) => e.endsWith(".csproj") || e.endsWith(".fsproj") || e.endsWith(".vbproj"));
163
+ for (const file of projectFiles) {
164
+ const filePath = path.join(projectDir, file);
165
+ const content = yield* readFileOptional(filePath);
166
+ if (Option.isSome(content)) {
167
+ if (content.value.includes("<")) {
168
+ const deps = parseProjectFile(content.value, filePath);
169
+ allPackages.push(...deps);
170
+ }
171
+ else {
172
+ yield* Effect.logWarning(`Malformed ${file}: not valid XML, skipping`);
173
+ }
174
+ }
175
+ }
176
+ }
177
+ // Parse Directory.Packages.props
178
+ const propsPath = path.join(projectDir, "Directory.Packages.props");
179
+ const propsContent = yield* readFileOptional(propsPath);
180
+ if (Option.isSome(propsContent)) {
181
+ if (propsContent.value.includes("<")) {
182
+ const propsDeps = parseDirectoryPackagesProps(propsContent.value, propsPath);
183
+ allPackages.push(...propsDeps);
184
+ }
185
+ else {
186
+ yield* Effect.logWarning("Malformed Directory.Packages.props: not valid XML, skipping");
187
+ }
188
+ }
189
+ // Parse packages.config
190
+ const packagesConfigPath = path.join(projectDir, "packages.config");
191
+ const packagesConfigContent = yield* readFileOptional(packagesConfigPath);
192
+ if (Option.isSome(packagesConfigContent)) {
193
+ if (packagesConfigContent.value.includes("<")) {
194
+ const configDeps = parsePackagesConfig(packagesConfigContent.value, packagesConfigPath);
195
+ allPackages.push(...configDeps);
196
+ }
197
+ else {
198
+ yield* Effect.logWarning("Malformed packages.config: not valid XML, skipping");
199
+ }
200
+ }
201
+ return deduplicatePackages(allPackages);
202
+ }, Effect.annotateLogs({ detector: "nuget" }), Effect.withSpan("detect.nuget")),
203
+ };
204
+ /**
205
+ * Resolve the NuGet packages folder path.
206
+ */
207
+ const resolveNugetPackagesFolder = () => Effect.sync(() => readEnv("NUGET_PACKAGES") ?? `${os.homedir()}/.nuget/packages`);
208
+ /**
209
+ * NuGet package reader.
210
+ *
211
+ * Reads `axm.json` from `~/.nuget/packages/{id}/{version}/` for each
212
+ * detected NuGet package and extracts recommendation metadata.
213
+ *
214
+ * @experimental This API is unstable and may change without notice.
215
+ */
216
+ export const nugetReader = {
217
+ type: nugetType,
218
+ read: Effect.fn("read.nuget")(function* (pkg) {
219
+ const path = yield* Path.Path;
220
+ const packagesFolder = yield* resolveNugetPackagesFolder();
221
+ // NuGet uses lowercased package IDs in directory names
222
+ const pkgId = pkg.purl.name.toLowerCase();
223
+ const version = pkg.purl.version ?? "0.0.0";
224
+ const axmJsonPath = path.join(packagesFolder, pkgId, version, "axm.json");
225
+ const content = yield* readFileOptional(axmJsonPath);
226
+ if (Option.isNone(content))
227
+ return Option.none();
228
+ const parsed = yield* parseJsonOptional(content.value, `${pkgId}@${version}/axm.json`);
229
+ if (Option.isNone(parsed))
230
+ return Option.none();
231
+ // Validate axm metadata structure
232
+ const metaResult = decodeAxmMeta(parsed.value);
233
+ if (Result.isFailure(metaResult)) {
234
+ yield* Effect.logWarning(`Invalid axm metadata in ${pkgId}@${version}: schema validation failed`);
235
+ return Option.none();
236
+ }
237
+ return Option.some(metaResult.success.extensions);
238
+ }, Effect.annotateLogs({ reader: "nuget" }), Effect.withSpan("read.nuget")),
239
+ };
240
+ //# sourceMappingURL=nuget.js.map
@@ -0,0 +1,27 @@
1
+ /**
2
+ * opam (OCaml) package detector and reader for package-compatibility discovery.
3
+ *
4
+ * @experimental This API is unstable and may change without notice.
5
+ * @packageDocumentation
6
+ */
7
+ import type { PackageDetector, PackageReader } from "./types.js";
8
+ /**
9
+ * opam package detector.
10
+ *
11
+ * Scans `*.opam` files for `depends` fields and `dune-project` for
12
+ * `(depends ...)` s-expressions. Skips `ocaml` and `dune` build tooling.
13
+ * Dependencies are deduplicated by name.
14
+ *
15
+ * @experimental This API is unstable and may change without notice.
16
+ */
17
+ export declare const opamDetector: PackageDetector;
18
+ /**
19
+ * opam package reader.
20
+ *
21
+ * Reads `x-axm` prefixed custom fields from `.opam` files in the
22
+ * opam switch at `~/.opam/<switch>/lib/<pkg>/opam`.
23
+ *
24
+ * @experimental This API is unstable and may change without notice.
25
+ */
26
+ export declare const opamReader: PackageReader;
27
+ //# sourceMappingURL=opam.d.ts.map