feat: add --manifest-version option to init command

Allow developers to specify which manifest version to use when
initializing a new manifest.json file.

Usage: mcpb init --manifest-version 0.3

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Joan Xie 2025-12-03 20:11:58 -08:00
commit 761e834ba8
No known key found for this signature in database
2 changed files with 43 additions and 20 deletions

View file

@ -51,19 +51,29 @@ program
.command("init [directory]")
.description("Create a new MCPB extension manifest")
.option("-y, --yes", "Accept all defaults (non-interactive mode)")
.action((directory?: string, options?: { yes?: boolean }) => {
void (async () => {
try {
const success = await initExtension(directory, options?.yes);
process.exit(success ? 0 : 1);
} catch (error) {
console.error(
`ERROR: ${error instanceof Error ? error.message : "Unknown error"}`,
);
process.exit(1);
}
})();
});
.option(
"--manifest-version <version>",
"Manifest version to use in the generated manifest",
)
.action(
(directory?: string, options?: { yes?: boolean; manifestVersion?: string }) => {
void (async () => {
try {
const success = await initExtension(
directory,
options?.yes,
options?.manifestVersion,
);
process.exit(success ? 0 : 1);
} catch (error) {
console.error(
`ERROR: ${error instanceof Error ? error.message : "Unknown error"}`,
);
process.exit(1);
}
})();
},
);
// Validate command
program

View file

@ -1,12 +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 {
DEFAULT_MANIFEST_VERSION,
MANIFEST_SCHEMAS,
} from "../shared/constants.js";
import type { McpbManifestAny } from "../types.js";
interface PackageJson {
name?: string;
@ -877,18 +877,19 @@ export function buildManifest(
license: string;
repository?: { type: string; url: string };
},
manifestVersion: keyof typeof MANIFEST_SCHEMAS = DEFAULT_MANIFEST_VERSION,
// localization?: {
// resources: string;
// default_locale: string;
// },
): z.infer<typeof McpbManifestSchema> {
): McpbManifestAny {
const { name, displayName, version, description, authorName } = basicInfo;
const { authorEmail, authorUrl } = authorInfo;
const { serverType, entryPoint, mcp_config } = serverConfig;
const { keywords, license, repository } = optionalFields;
return {
manifest_version: DEFAULT_MANIFEST_VERSION,
manifest_version: manifestVersion,
name,
...(displayName && displayName !== name
? { display_name: displayName }
@ -945,10 +946,21 @@ export function printNextSteps() {
export async function initExtension(
targetPath: string = process.cwd(),
nonInteractive = false,
manifestVersion?: string,
): Promise<boolean> {
const resolvedPath = resolve(targetPath);
const manifestPath = join(resolvedPath, "manifest.json");
// Validate manifest version if provided
if (manifestVersion && !(manifestVersion in MANIFEST_SCHEMAS)) {
console.error(
`ERROR: Invalid manifest version "${manifestVersion}". Supported versions: ${Object.keys(MANIFEST_SCHEMAS).join(", ")}`,
);
return false;
}
const effectiveManifestVersion = (manifestVersion ||
DEFAULT_MANIFEST_VERSION) as keyof typeof MANIFEST_SCHEMAS;
if (existsSync(manifestPath)) {
if (nonInteractive) {
console.log(
@ -1029,6 +1041,7 @@ export async function initExtension(
compatibility,
userConfig,
optionalFields,
effectiveManifestVersion,
);
// Write manifest