@nimblebrain/mpak-sdk
Advanced tools
+52
-2
@@ -48,3 +48,4 @@ "use strict"; | ||
| isSemverEqual: () => isSemverEqual, | ||
| parsePackageSpec: () => parsePackageSpec | ||
| parsePackageSpec: () => parsePackageSpec, | ||
| validateMcpb: () => validateMcpb | ||
| }); | ||
@@ -1393,2 +1394,50 @@ module.exports = __toCommonJS(index_exports); | ||
| // src/validate.ts | ||
| var import_node_fs5 = require("fs"); | ||
| var import_node_os3 = require("os"); | ||
| var import_node_path5 = require("path"); | ||
| var import_mpak_schemas3 = require("@nimblebrain/mpak-schemas"); | ||
| async function validateMcpb(mcpbPath) { | ||
| if (!(0, import_node_fs5.existsSync)(mcpbPath)) { | ||
| return { valid: false, errors: [`File does not exist: ${mcpbPath}`] }; | ||
| } | ||
| let tempDir; | ||
| try { | ||
| tempDir = (0, import_node_fs5.mkdtempSync)((0, import_node_path5.join)((0, import_node_os3.tmpdir)(), "mpak-validate-")); | ||
| try { | ||
| await extractZip(mcpbPath, tempDir); | ||
| } catch (err) { | ||
| return { | ||
| valid: false, | ||
| errors: [`Failed to open archive: ${err instanceof Error ? err.message : String(err)}`] | ||
| }; | ||
| } | ||
| const manifestPath = (0, import_node_path5.join)(tempDir, "manifest.json"); | ||
| if (!(0, import_node_fs5.existsSync)(manifestPath)) { | ||
| return { valid: false, errors: ["Bundle is missing manifest.json"] }; | ||
| } | ||
| let manifest; | ||
| try { | ||
| manifest = readJsonFromFile(manifestPath, import_mpak_schemas3.McpbManifestSchema); | ||
| } catch (err) { | ||
| return { | ||
| valid: false, | ||
| errors: [`Invalid manifest.json: ${err instanceof Error ? err.message : String(err)}`] | ||
| }; | ||
| } | ||
| const entryPoint = manifest.server.entry_point; | ||
| if (!(0, import_node_fs5.existsSync)((0, import_node_path5.join)(tempDir, entryPoint))) { | ||
| return { | ||
| valid: false, | ||
| errors: [`Entry point "${entryPoint}" does not exist in bundle`] | ||
| }; | ||
| } | ||
| return { valid: true, manifest }; | ||
| } finally { | ||
| if (tempDir) { | ||
| (0, import_node_fs5.rmSync)(tempDir, { recursive: true, force: true }); | ||
| } | ||
| } | ||
| } | ||
| // src/utils.ts | ||
@@ -1430,4 +1479,5 @@ function parsePackageSpec(spec) { | ||
| isSemverEqual, | ||
| parsePackageSpec | ||
| parsePackageSpec, | ||
| validateMcpb | ||
| }); | ||
| //# sourceMappingURL=index.cjs.map |
+20
-1
@@ -577,3 +577,22 @@ import { BundleSearchParamsInput, BundleSearchResponse, BundleDetail, VersionsResponse, VersionDetail, PlatformInfo, DownloadInfo, SkillSearchParamsInput, SkillSearchResponse, SkillDetail, SkillDownloadInfo, CacheMetadata, McpbManifest, CachedBundleInfo } from '@nimblebrain/mpak-schemas'; | ||
| interface McpbValidationSuccess { | ||
| valid: true; | ||
| manifest: McpbManifest; | ||
| errors?: undefined; | ||
| } | ||
| interface McpbValidationFailure { | ||
| valid: false; | ||
| manifest?: undefined; | ||
| errors: string[]; | ||
| } | ||
| type McpbValidationResult = McpbValidationSuccess | McpbValidationFailure; | ||
| /** | ||
| * Validate a local `.mcpb` file without side effects. | ||
| * | ||
| * Extracts to a temp directory, validates manifest schema and entry point | ||
| * existence, then cleans up. Does not touch the mpak cache. | ||
| */ | ||
| declare function validateMcpb(mcpbPath: string): Promise<McpbValidationResult>; | ||
| /** | ||
| * Parse a scoped package spec (`@scope/name` or `@scope/name@version`) | ||
@@ -748,2 +767,2 @@ * into its name and optional version components. | ||
| export { type ExtractZipOptions, MAX_UNCOMPRESSED_SIZE, Mpak, MpakBundleCache, type MpakBundleCacheOptions, MpakCacheCorruptedError, MpakClient, type MpakClientConfig, MpakConfigCorruptedError, MpakConfigError, MpakConfigManager, type MpakConfigManagerOptions, MpakError, MpakIntegrityError, MpakInvalidBundleError, MpakNetworkError, MpakNotFoundError, type MpakOptions, type PackageConfig, type PrepareServerOptions, type PrepareServerSpec, type ServerCommand, extractZip, isSemverEqual, parsePackageSpec }; | ||
| export { type ExtractZipOptions, MAX_UNCOMPRESSED_SIZE, type McpbValidationFailure, type McpbValidationResult, type McpbValidationSuccess, Mpak, MpakBundleCache, type MpakBundleCacheOptions, MpakCacheCorruptedError, MpakClient, type MpakClientConfig, MpakConfigCorruptedError, MpakConfigError, MpakConfigManager, type MpakConfigManagerOptions, MpakError, MpakIntegrityError, MpakInvalidBundleError, MpakNetworkError, MpakNotFoundError, type MpakOptions, type PackageConfig, type PrepareServerOptions, type PrepareServerSpec, type ServerCommand, extractZip, isSemverEqual, parsePackageSpec, validateMcpb }; |
+20
-1
@@ -577,3 +577,22 @@ import { BundleSearchParamsInput, BundleSearchResponse, BundleDetail, VersionsResponse, VersionDetail, PlatformInfo, DownloadInfo, SkillSearchParamsInput, SkillSearchResponse, SkillDetail, SkillDownloadInfo, CacheMetadata, McpbManifest, CachedBundleInfo } from '@nimblebrain/mpak-schemas'; | ||
| interface McpbValidationSuccess { | ||
| valid: true; | ||
| manifest: McpbManifest; | ||
| errors?: undefined; | ||
| } | ||
| interface McpbValidationFailure { | ||
| valid: false; | ||
| manifest?: undefined; | ||
| errors: string[]; | ||
| } | ||
| type McpbValidationResult = McpbValidationSuccess | McpbValidationFailure; | ||
| /** | ||
| * Validate a local `.mcpb` file without side effects. | ||
| * | ||
| * Extracts to a temp directory, validates manifest schema and entry point | ||
| * existence, then cleans up. Does not touch the mpak cache. | ||
| */ | ||
| declare function validateMcpb(mcpbPath: string): Promise<McpbValidationResult>; | ||
| /** | ||
| * Parse a scoped package spec (`@scope/name` or `@scope/name@version`) | ||
@@ -748,2 +767,2 @@ * into its name and optional version components. | ||
| export { type ExtractZipOptions, MAX_UNCOMPRESSED_SIZE, Mpak, MpakBundleCache, type MpakBundleCacheOptions, MpakCacheCorruptedError, MpakClient, type MpakClientConfig, MpakConfigCorruptedError, MpakConfigError, MpakConfigManager, type MpakConfigManagerOptions, MpakError, MpakIntegrityError, MpakInvalidBundleError, MpakNetworkError, MpakNotFoundError, type MpakOptions, type PackageConfig, type PrepareServerOptions, type PrepareServerSpec, type ServerCommand, extractZip, isSemverEqual, parsePackageSpec }; | ||
| export { type ExtractZipOptions, MAX_UNCOMPRESSED_SIZE, type McpbValidationFailure, type McpbValidationResult, type McpbValidationSuccess, Mpak, MpakBundleCache, type MpakBundleCacheOptions, MpakCacheCorruptedError, MpakClient, type MpakClientConfig, MpakConfigCorruptedError, MpakConfigError, MpakConfigManager, type MpakConfigManagerOptions, MpakError, MpakIntegrityError, MpakInvalidBundleError, MpakNetworkError, MpakNotFoundError, type MpakOptions, type PackageConfig, type PrepareServerOptions, type PrepareServerSpec, type ServerCommand, extractZip, isSemverEqual, parsePackageSpec, validateMcpb }; |
+50
-1
@@ -1348,2 +1348,50 @@ // src/mpakSDK.ts | ||
| // src/validate.ts | ||
| import { existsSync as existsSync5, mkdtempSync, rmSync as rmSync3 } from "fs"; | ||
| import { tmpdir as tmpdir2 } from "os"; | ||
| import { join as join5 } from "path"; | ||
| import { McpbManifestSchema as McpbManifestSchema3 } from "@nimblebrain/mpak-schemas"; | ||
| async function validateMcpb(mcpbPath) { | ||
| if (!existsSync5(mcpbPath)) { | ||
| return { valid: false, errors: [`File does not exist: ${mcpbPath}`] }; | ||
| } | ||
| let tempDir; | ||
| try { | ||
| tempDir = mkdtempSync(join5(tmpdir2(), "mpak-validate-")); | ||
| try { | ||
| await extractZip(mcpbPath, tempDir); | ||
| } catch (err) { | ||
| return { | ||
| valid: false, | ||
| errors: [`Failed to open archive: ${err instanceof Error ? err.message : String(err)}`] | ||
| }; | ||
| } | ||
| const manifestPath = join5(tempDir, "manifest.json"); | ||
| if (!existsSync5(manifestPath)) { | ||
| return { valid: false, errors: ["Bundle is missing manifest.json"] }; | ||
| } | ||
| let manifest; | ||
| try { | ||
| manifest = readJsonFromFile(manifestPath, McpbManifestSchema3); | ||
| } catch (err) { | ||
| return { | ||
| valid: false, | ||
| errors: [`Invalid manifest.json: ${err instanceof Error ? err.message : String(err)}`] | ||
| }; | ||
| } | ||
| const entryPoint = manifest.server.entry_point; | ||
| if (!existsSync5(join5(tempDir, entryPoint))) { | ||
| return { | ||
| valid: false, | ||
| errors: [`Entry point "${entryPoint}" does not exist in bundle`] | ||
| }; | ||
| } | ||
| return { valid: true, manifest }; | ||
| } finally { | ||
| if (tempDir) { | ||
| rmSync3(tempDir, { recursive: true, force: true }); | ||
| } | ||
| } | ||
| } | ||
| // src/utils.ts | ||
@@ -1384,4 +1432,5 @@ function parsePackageSpec(spec) { | ||
| isSemverEqual, | ||
| parsePackageSpec | ||
| parsePackageSpec, | ||
| validateMcpb | ||
| }; | ||
| //# sourceMappingURL=index.js.map |
+2
-2
| { | ||
| "name": "@nimblebrain/mpak-sdk", | ||
| "version": "0.6.0", | ||
| "version": "0.7.0", | ||
| "description": "TypeScript SDK for mpak registry - MCPB bundles and Agent Skills", | ||
@@ -55,3 +55,3 @@ "author": "NimbleBrain Inc <engineering@mpak.dev>", | ||
| "zod": "^4.3.6", | ||
| "@nimblebrain/mpak-schemas": "0.2.0" | ||
| "@nimblebrain/mpak-schemas": "0.3.0" | ||
| }, | ||
@@ -58,0 +58,0 @@ "devDependencies": { |
+1
-0
@@ -298,2 +298,3 @@ # @nimblebrain/mpak-sdk | ||
| | `isSemverEqual(a, b)` | Compare semver strings (ignores `v` prefix) | | ||
| | `validateMcpb(path)` | Async. Validate a local `.mcpb` file (manifest schema + entry-point existence) without touching the cache. Returns `{ valid: true, manifest }` or `{ valid: false, errors }`. | | ||
@@ -300,0 +301,0 @@ ### ConfigManager (`mpak.config`) |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
384078
3.15%3648
3.28%389
0.26%13
18.18%+ Added
- Removed