diff --git a/.vscode/settings.json b/.vscode/settings.json index 14ac857..73dc7c2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,5 +6,6 @@ "eslint.validate": ["typescript"], "[typescript]": { "editor.defaultFormatter": "dbaeumer.vscode-eslint" - } + }, + "typescript.tsdk": "node_modules/typescript/lib" } diff --git a/scripts/build-mcpb-schema.js b/scripts/build-mcpb-schema.js index dce003b..6d884e1 100644 --- a/scripts/build-mcpb-schema.js +++ b/scripts/build-mcpb-schema.js @@ -1,9 +1,7 @@ import { McpbManifestSchema as McpbManifestSchema_v0_1 } from "../dist/schemas/0.1.js"; import { McpbManifestSchema as McpbManifestSchema_v0_2 } from "../dist/schemas/0.2.js"; -import { - McpbManifestSchema as McpbManifestSchema_v0_3, - McpbSignatureInfoSchema, -} from "../dist/schemas/0.3.js"; +import { McpbManifestSchema as McpbManifestSchema_v0_3 } from "../dist/schemas/0.3.js"; +import { McpbSignatureInfoSchema } from "../dist/shared/common.js"; import { zodToJsonSchema } from "zod-to-json-schema"; import fs from "node:fs/promises"; import path from "node:path"; diff --git a/src/browser.ts b/src/browser.ts index 037b024..b8d3fa9 100644 --- a/src/browser.ts +++ b/src/browser.ts @@ -2,4 +2,3 @@ export * from "./schemas/index.js"; export * from "./shared/config.js"; export * from "./shared/constants.js"; -export * from "./types.js"; diff --git a/src/cli.ts b/src/cli.ts index a11144a..c5266d4 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -6,7 +6,6 @@ export * from "./cli/pack.js"; export * from "./schemas/index.js"; export * from "./shared/config.js"; export * from "./shared/constants.js"; -export * from "./types.js"; // Include node exports since CLI needs them export * from "./node/files.js"; diff --git a/src/cli/init.ts b/src/cli/init.ts index f6a99a6..9e62777 100644 --- a/src/cli/init.ts +++ b/src/cli/init.ts @@ -1,9 +1,12 @@ import { confirm, input, select } from "@inquirer/prompts"; import { existsSync, readFileSync, writeFileSync } from "fs"; import { basename, join, resolve } from "path"; +import type { z } from "zod"; +// Import the schema for DEFAULT_MANIFEST_VERSION +// TODO: Allow dynamic manifest version choice +import type { McpbManifestSchema } from "../schemas/0.2.js"; import { DEFAULT_MANIFEST_VERSION } from "../shared/constants.js"; -import type { McpbManifestDefault } from "../types.js"; interface PackageJson { name?: string; @@ -878,7 +881,7 @@ export function buildManifest( // resources: string; // default_locale: string; // }, -): McpbManifestDefault { +): z.infer { const { name, displayName, version, description, authorName } = basicInfo; const { authorEmail, authorUrl } = authorInfo; const { serverType, entryPoint, mcp_config } = serverConfig; diff --git a/src/index.ts b/src/index.ts index 1aad967..58387f8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,4 +8,3 @@ export * from "./node/validate.js"; export * from "./schemas/index.js"; export * from "./shared/config.js"; export * from "./shared/constants.js"; -export * from "./types.js"; diff --git a/src/node.ts b/src/node.ts index 193df7b..f7f48a0 100644 --- a/src/node.ts +++ b/src/node.ts @@ -7,4 +7,3 @@ export * from "./node/validate.js"; export * from "./schemas/index.js"; export * from "./shared/config.js"; export * from "./shared/constants.js"; -export * from "./types.js"; diff --git a/src/node/sign.ts b/src/node/sign.ts index bb83389..e0ed5ce 100644 --- a/src/node/sign.ts +++ b/src/node/sign.ts @@ -5,8 +5,9 @@ import forge from "node-forge"; import { tmpdir } from "os"; import { join } from "path"; import { promisify } from "util"; +import type { z } from "zod"; -import type { McpbSignatureInfo } from "../types.js"; +import type { McpbSignatureInfoSchema } from "../shared/common.js"; // Signature block markers const SIGNATURE_HEADER = "MCPB_SIG_V1"; @@ -101,7 +102,7 @@ export function signMcpbFile( */ export async function verifyMcpbFile( mcpbPath: string, -): Promise { +): Promise> { try { const fileContent = readFileSync(mcpbPath); diff --git a/src/schemas/0.1.ts b/src/schemas/0.1.ts index 4d77ccc..e41d69c 100644 --- a/src/schemas/0.1.ts +++ b/src/schemas/0.1.ts @@ -71,11 +71,6 @@ export const McpbUserConfigurationOptionSchema = z.strictObject({ max: z.number().optional(), }); -export const McpbUserConfigValuesSchema = z.record( - z.string(), - z.union([z.string(), z.number(), z.boolean(), z.array(z.string())]), -); - export const McpbManifestSchema = z .strictObject({ $schema: z.string().optional(), @@ -113,12 +108,3 @@ export const McpbManifestSchema = z message: "Either 'dxt_version' (deprecated) or 'manifest_version' must be provided", }); - -export const McpbSignatureInfoSchema = z.strictObject({ - status: z.enum(["signed", "unsigned", "self-signed"]), - publisher: z.string().optional(), - issuer: z.string().optional(), - valid_from: z.string().optional(), - valid_to: z.string().optional(), - fingerprint: z.string().optional(), -}); diff --git a/src/schemas/0.2.ts b/src/schemas/0.2.ts index f5d4d03..bb1de16 100644 --- a/src/schemas/0.2.ts +++ b/src/schemas/0.2.ts @@ -71,11 +71,6 @@ export const McpbUserConfigurationOptionSchema = z.strictObject({ max: z.number().optional(), }); -export const McpbUserConfigValuesSchema = z.record( - z.string(), - z.union([z.string(), z.number(), z.boolean(), z.array(z.string())]), -); - export const McpbManifestSchema = z .strictObject({ $schema: z.string().optional(), @@ -113,12 +108,3 @@ export const McpbManifestSchema = z message: "Either 'dxt_version' (deprecated) or 'manifest_version' must be provided", }); - -export const McpbSignatureInfoSchema = z.strictObject({ - status: z.enum(["signed", "unsigned", "self-signed"]), - publisher: z.string().optional(), - issuer: z.string().optional(), - valid_from: z.string().optional(), - valid_to: z.string().optional(), - fingerprint: z.string().optional(), -}); diff --git a/src/schemas/0.3.ts b/src/schemas/0.3.ts index 2bdc946..2ca0206 100644 --- a/src/schemas/0.3.ts +++ b/src/schemas/0.3.ts @@ -76,11 +76,6 @@ export const McpbUserConfigurationOptionSchema = z.strictObject({ max: z.number().optional(), }); -export const McpbUserConfigValuesSchema = z.record( - z.string(), - z.union([z.string(), z.number(), z.boolean(), z.array(z.string())]), -); - export const McpbManifestLocalizationSchema = z.strictObject({ resources: z .string() @@ -147,12 +142,3 @@ export const McpbManifestSchema = z message: "Either 'dxt_version' (deprecated) or 'manifest_version' must be provided", }); - -export const McpbSignatureInfoSchema = z.strictObject({ - status: z.enum(["signed", "unsigned", "self-signed"]), - publisher: z.string().optional(), - issuer: z.string().optional(), - valid_from: z.string().optional(), - valid_to: z.string().optional(), - fingerprint: z.string().optional(), -}); diff --git a/src/schemas_loose/0.1.ts b/src/schemas_loose/0.1.ts index 2ab5e56..406d6c1 100644 --- a/src/schemas_loose/0.1.ts +++ b/src/schemas_loose/0.1.ts @@ -73,11 +73,6 @@ export const McpbUserConfigurationOptionSchema = z.object({ max: z.number().optional(), }); -export const McpbUserConfigValuesSchema = z.record( - z.string(), - z.union([z.string(), z.number(), z.boolean(), z.array(z.string())]), -); - export const McpbManifestSchema = z .object({ $schema: z.string().optional(), @@ -115,12 +110,3 @@ export const McpbManifestSchema = z message: "Either 'dxt_version' (deprecated) or 'manifest_version' must be provided", }); - -export const McpbSignatureInfoSchema = z.object({ - status: z.enum(["signed", "unsigned", "self-signed"]), - publisher: z.string().optional(), - issuer: z.string().optional(), - valid_from: z.string().optional(), - valid_to: z.string().optional(), - fingerprint: z.string().optional(), -}); diff --git a/src/schemas_loose/0.2.ts b/src/schemas_loose/0.2.ts index 7cdbc1a..bc177d2 100644 --- a/src/schemas_loose/0.2.ts +++ b/src/schemas_loose/0.2.ts @@ -73,11 +73,6 @@ export const McpbUserConfigurationOptionSchema = z.object({ max: z.number().optional(), }); -export const McpbUserConfigValuesSchema = z.record( - z.string(), - z.union([z.string(), z.number(), z.boolean(), z.array(z.string())]), -); - export const McpbManifestSchema = z .object({ $schema: z.string().optional(), @@ -116,12 +111,3 @@ export const McpbManifestSchema = z message: "Either 'dxt_version' (deprecated) or 'manifest_version' must be provided", }); - -export const McpbSignatureInfoSchema = z.object({ - status: z.enum(["signed", "unsigned", "self-signed"]), - publisher: z.string().optional(), - issuer: z.string().optional(), - valid_from: z.string().optional(), - valid_to: z.string().optional(), - fingerprint: z.string().optional(), -}); diff --git a/src/schemas_loose/0.3.ts b/src/schemas_loose/0.3.ts index 87ac125..a96894b 100644 --- a/src/schemas_loose/0.3.ts +++ b/src/schemas_loose/0.3.ts @@ -77,11 +77,6 @@ export const McpbUserConfigurationOptionSchema = z.object({ max: z.number().optional(), }); -export const McpbUserConfigValuesSchema = z.record( - z.string(), - z.union([z.string(), z.number(), z.boolean(), z.array(z.string())]), -); - export const McpbManifestLocalizationSchema = z .object({ resources: z @@ -153,12 +148,3 @@ export const McpbManifestSchema = z message: "Either 'dxt_version' (deprecated) or 'manifest_version' must be provided", }); - -export const McpbSignatureInfoSchema = z.object({ - status: z.enum(["signed", "unsigned", "self-signed"]), - publisher: z.string().optional(), - issuer: z.string().optional(), - valid_from: z.string().optional(), - valid_to: z.string().optional(), - fingerprint: z.string().optional(), -}); diff --git a/src/shared/common.ts b/src/shared/common.ts new file mode 100644 index 0000000..9449ee7 --- /dev/null +++ b/src/shared/common.ts @@ -0,0 +1,15 @@ +import { z } from "zod"; + +export const McpbUserConfigValuesSchema = z.record( + z.string(), + z.union([z.string(), z.number(), z.boolean(), z.array(z.string())]), +); + +export const McpbSignatureInfoSchema = z.strictObject({ + status: z.enum(["signed", "unsigned", "self-signed"]), + publisher: z.string().optional(), + issuer: z.string().optional(), + valid_from: z.string().optional(), + valid_to: z.string().optional(), + fingerprint: z.string().optional(), +}); diff --git a/src/shared/config.ts b/src/shared/config.ts index 9ce016c..b4638bc 100644 --- a/src/shared/config.ts +++ b/src/shared/config.ts @@ -1,9 +1,7 @@ -import type { - Logger, - McpbManifestAny, - McpbUserConfigValues, - McpServerConfig, -} from "../types.js"; +import type { z } from "zod"; + +import type { Logger, McpbManifestAny } from "../types.js"; +import type { McpbUserConfigValuesSchema } from "./common.js"; /** * This file contains utility functions for handling MCPB configuration, @@ -88,14 +86,14 @@ interface GetMcpConfigForManifestOptions { manifest: McpbManifestAny; extensionPath: string; systemDirs: Record; - userConfig: McpbUserConfigValues; + userConfig: z.infer; pathSeparator: string; logger?: Logger; } export async function getMcpConfigForManifest( options: GetMcpConfigForManifestOptions, -): Promise { +): Promise { const { manifest, extensionPath, @@ -109,7 +107,7 @@ export async function getMcpConfigForManifest( return undefined; } - let result: McpServerConfig = { + let result: McpbManifestAny["server"]["mcp_config"] = { ...baseConfig, }; @@ -173,14 +171,17 @@ export async function getMcpConfigForManifest( } // Replace all variables in the config - result = replaceVariables(result, variables) as McpServerConfig; + result = replaceVariables( + result, + variables, + ) as McpbManifestAny["server"]["mcp_config"]; return result; } interface HasRequiredConfigMissingOptions { manifest: McpbManifestAny; - userConfig?: McpbUserConfigValues; + userConfig?: z.infer; } function isInvalidSingleValue(value: unknown): boolean { diff --git a/src/types.ts b/src/types.ts index c949a0d..655bffa 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,77 +1,12 @@ import type * as z from "zod"; -// Import schema types from the version matching DEFAULT_MANIFEST_VERSION -import type { - McpbManifestAuthorSchema, - McpbManifestCompatibilitySchema, - McpbManifestMcpConfigSchema, - McpbManifestPlatformOverrideSchema, - McpbManifestPromptSchema, - McpbManifestRepositorySchema, - McpbManifestServerSchema, - McpbManifestToolSchema, - McpbSignatureInfoSchema, - McpbUserConfigurationOptionSchema, - McpbUserConfigValuesSchema, - McpServerConfigSchema, -} from "./schemas/0.2.js"; import type { McpbManifestSchema as McpbManifestSchemaAny } from "./schemas/any.js"; -import type { VERSIONED_MANIFEST_SCHEMAS } from "./schemas/index.js"; -import type { DEFAULT_MANIFEST_VERSION } from "./shared/constants.js"; - -export type McpServerConfig = z.infer; - -export type McpbManifestAuthor = z.infer; - -export type McpbManifestRepository = z.infer< - typeof McpbManifestRepositorySchema ->; - -export type McpbManifestPlatformOverride = z.infer< - typeof McpbManifestPlatformOverrideSchema ->; - -export type McpbManifestMcpConfig = z.infer; - -export type McpbManifestServer = z.infer; - -export type McpbManifestCompatibility = z.infer< - typeof McpbManifestCompatibilitySchema ->; - -export type McpbManifestTool = z.infer; - -export type McpbManifestPrompt = z.infer; - -export type McpbUserConfigurationOption = z.infer< - typeof McpbUserConfigurationOptionSchema ->; - -export type McpbUserConfigValues = z.infer; /** * McpbManifest type representing the union of all manifest versions */ export type McpbManifestAny = z.infer; -/** - * McpbManifest type for the DEFAULT_MANIFEST_VERSION - * Use this for creating new manifests with the default version. - */ -export type McpbManifestDefault = z.infer< - (typeof VERSIONED_MANIFEST_SCHEMAS)[typeof DEFAULT_MANIFEST_VERSION] ->; - -/** - * @deprecated Use McpbManifestAny instead to support all manifest versions, or McpbManifestDefault for the default version. - */ -export type McpbManifest = McpbManifestDefault; - -/** - * Information about a MCPB package signature - */ -export type McpbSignatureInfo = z.infer; - export interface Logger { log: (...args: unknown[]) => void; error: (...args: unknown[]) => void; diff --git a/test/config.test.ts b/test/config.test.ts index 062c66e..1c34faf 100644 --- a/test/config.test.ts +++ b/test/config.test.ts @@ -3,7 +3,7 @@ import { hasRequiredConfigMissing, replaceVariables, } from "../src/shared/config"; -import type { Logger, McpbManifest } from "../src/types"; +import type { Logger, McpbManifestAny } from "../src/types"; describe("replaceVariables", () => { it("should replace variables in strings", () => { @@ -89,7 +89,7 @@ describe("getMcpConfigForManifest", () => { data: "/data", }; - const baseManifest: McpbManifest = { + const baseManifest: McpbManifestAny = { manifest_version: "0.2", name: "test-extension", version: "1.0.0", @@ -114,7 +114,7 @@ describe("getMcpConfigForManifest", () => { const manifest = { ...baseManifest, server: undefined, - } as unknown as McpbManifest; + } as unknown as McpbManifestAny; const result = await getMcpConfigForManifest({ manifest, @@ -129,7 +129,7 @@ describe("getMcpConfigForManifest", () => { }); it("should return undefined when required config is missing", async () => { - const manifest: McpbManifest = { + const manifest: McpbManifestAny = { ...baseManifest, user_config: { apiKey: { @@ -171,7 +171,7 @@ describe("getMcpConfigForManifest", () => { }); it("should apply platform overrides", async () => { - const manifest: McpbManifest = { + const manifest: McpbManifestAny = { ...baseManifest, server: { type: "node", @@ -203,7 +203,7 @@ describe("getMcpConfigForManifest", () => { }); it("should handle user config variable replacement with defaults", async () => { - const manifest: McpbManifest = { + const manifest: McpbManifestAny = { ...baseManifest, user_config: { port: { @@ -236,7 +236,7 @@ describe("getMcpConfigForManifest", () => { }); it("should handle user config variable replacement with user values", async () => { - const manifest: McpbManifest = { + const manifest: McpbManifestAny = { ...baseManifest, user_config: { paths: { @@ -270,7 +270,7 @@ describe("getMcpConfigForManifest", () => { }); it("should convert boolean user config values to strings", async () => { - const manifest: McpbManifest = { + const manifest: McpbManifestAny = { ...baseManifest, user_config: { verbose: { @@ -304,7 +304,7 @@ describe("getMcpConfigForManifest", () => { }); describe("hasRequiredConfigMissing", () => { - const baseManifest: McpbManifest = { + const baseManifest: McpbManifestAny = { manifest_version: "0.2", name: "test-extension", version: "1.0.0", @@ -329,7 +329,7 @@ describe("hasRequiredConfigMissing", () => { }); it("should return false when no config fields are required", () => { - const manifest: McpbManifest = { + const manifest: McpbManifestAny = { ...baseManifest, user_config: { port: { @@ -349,7 +349,7 @@ describe("hasRequiredConfigMissing", () => { }); it("should return false when required config is provided", () => { - const manifest: McpbManifest = { + const manifest: McpbManifestAny = { ...baseManifest, user_config: { apiKey: { @@ -369,7 +369,7 @@ describe("hasRequiredConfigMissing", () => { }); it("should return true when required config is undefined", () => { - const manifest: McpbManifest = { + const manifest: McpbManifestAny = { ...baseManifest, user_config: { apiKey: { @@ -389,7 +389,7 @@ describe("hasRequiredConfigMissing", () => { }); it("should return true when required config is empty string", () => { - const manifest: McpbManifest = { + const manifest: McpbManifestAny = { ...baseManifest, user_config: { apiKey: { @@ -409,7 +409,7 @@ describe("hasRequiredConfigMissing", () => { }); it("should return true when required config is array with invalid values", () => { - const manifest: McpbManifest = { + const manifest: McpbManifestAny = { ...baseManifest, user_config: { paths: { @@ -430,7 +430,7 @@ describe("hasRequiredConfigMissing", () => { }); it("should return true when required config is empty array", () => { - const manifest: McpbManifest = { + const manifest: McpbManifestAny = { ...baseManifest, user_config: { paths: { @@ -459,7 +459,7 @@ describe("hasRequiredConfigMissing", () => { }); it("should handle multiple required config fields", () => { - const manifest: McpbManifest = { + const manifest: McpbManifestAny = { ...baseManifest, user_config: { apiKey: {