Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 26 additions & 13 deletions src/cli/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,19 +51,32 @@ 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
Expand Down
27 changes: 20 additions & 7 deletions src/cli/init.ts
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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 }
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -1029,6 +1041,7 @@ export async function initExtension(
compatibility,
userConfig,
optionalFields,
effectiveManifestVersion,
);

// Write manifest
Expand Down