Skip to content

Commit ab5f793

Browse files
feat: add --manifest-version option to pack command
Allow developers to optionally specify which manifest version to use when packing a bundle. This is useful when targeting a specific version for compatibility with different consumers of the MCPB format. Usage: mcpb pack --manifest-version 0.2 The option: - Validates the specified version is supported (0.1, 0.2, 0.3, 0.4) - Updates the manifest_version field in the packed manifest.json - Removes legacy dxt_version field if present - Re-validates the manifest against the target version schema 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 3635e20 commit ab5f793

File tree

2 files changed

+63
-17
lines changed

2 files changed

+63
-17
lines changed

src/cli/cli.ts

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -88,22 +88,33 @@ program
8888
program
8989
.command("pack [directory] [output]")
9090
.description("Pack a directory into an MCPB extension")
91-
.action((directory: string = process.cwd(), output?: string) => {
92-
void (async () => {
93-
try {
94-
const success = await packExtension({
95-
extensionPath: directory,
96-
outputPath: output,
97-
});
98-
process.exit(success ? 0 : 1);
99-
} catch (error) {
100-
console.error(
101-
`ERROR: ${error instanceof Error ? error.message : "Unknown error"}`,
102-
);
103-
process.exit(1);
104-
}
105-
})();
106-
});
91+
.option(
92+
"--manifest-version <version>",
93+
"Override manifest version in the output bundle (e.g., 0.1, 0.2, 0.3, 0.4)",
94+
)
95+
.action(
96+
(
97+
directory: string = process.cwd(),
98+
output?: string,
99+
options?: { manifestVersion?: string },
100+
) => {
101+
void (async () => {
102+
try {
103+
const success = await packExtension({
104+
extensionPath: directory,
105+
outputPath: output,
106+
manifestVersion: options?.manifestVersion,
107+
});
108+
process.exit(success ? 0 : 1);
109+
} catch (error) {
110+
console.error(
111+
`ERROR: ${error instanceof Error ? error.message : "Unknown error"}`,
112+
);
113+
process.exit(1);
114+
}
115+
})();
116+
},
117+
);
107118

108119
// Unpack command
109120
program

src/cli/pack.ts

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ interface PackOptions {
2222
extensionPath: string;
2323
outputPath?: string;
2424
silent?: boolean;
25+
manifestVersion?: string;
2526
}
2627

2728
function formatFileSize(bytes: number): string {
@@ -50,10 +51,22 @@ export async function packExtension({
5051
extensionPath,
5152
outputPath,
5253
silent,
54+
manifestVersion: targetManifestVersion,
5355
}: PackOptions): Promise<boolean> {
5456
const resolvedPath = resolve(extensionPath);
5557
const logger = getLogger({ silent });
5658

59+
// Validate target manifest version if provided
60+
if (
61+
targetManifestVersion &&
62+
!(targetManifestVersion in MANIFEST_SCHEMAS)
63+
) {
64+
logger.error(
65+
`ERROR: Invalid manifest version "${targetManifestVersion}". Supported versions: ${Object.keys(MANIFEST_SCHEMAS).join(", ")}`,
66+
);
67+
return false;
68+
}
69+
5770
// Check if directory exists
5871
if (!existsSync(resolvedPath) || !statSync(resolvedPath).isDirectory()) {
5972
logger.error(`ERROR: Directory not found: ${extensionPath}`);
@@ -90,10 +103,11 @@ export async function packExtension({
90103

91104
// Read and parse manifest
92105
let manifest;
106+
let finalManifestContent: string;
93107
try {
94108
const manifestContent = readFileSync(manifestPath, "utf-8");
95109
const manifestData = JSON.parse(manifestContent);
96-
const manifestVersion = getManifestVersionFromRawData(manifestData);
110+
let manifestVersion = getManifestVersionFromRawData(manifestData);
97111
if (!manifestVersion) {
98112
logger.error(
99113
`ERROR: Manifest version mismatch. Expected "${Object.keys(MANIFEST_SCHEMAS).join(" or ")}", found "${manifestVersion}"`,
@@ -104,7 +118,20 @@ export async function packExtension({
104118
return false;
105119
}
106120

121+
// Override manifest version if target version is specified
122+
if (targetManifestVersion && targetManifestVersion !== manifestVersion) {
123+
logger.log(
124+
`Overriding manifest version from ${manifestVersion} to ${targetManifestVersion}`,
125+
);
126+
manifestData.manifest_version = targetManifestVersion;
127+
// Remove legacy dxt_version if present to avoid confusion
128+
delete manifestData.dxt_version;
129+
manifestVersion =
130+
targetManifestVersion as keyof typeof MANIFEST_SCHEMAS;
131+
}
132+
107133
manifest = MANIFEST_SCHEMAS[manifestVersion].parse(manifestData);
134+
finalManifestContent = JSON.stringify(manifestData, null, 2);
108135
} catch (error) {
109136
logger.error("ERROR: Failed to parse manifest.json");
110137
if (error instanceof Error) {
@@ -135,6 +162,14 @@ export async function packExtension({
135162
mcpbIgnorePatterns,
136163
);
137164

165+
// Override manifest.json with potentially modified content (version override)
166+
if (files[manifestPath]) {
167+
files[manifestPath] = {
168+
...files[manifestPath],
169+
data: Buffer.from(finalManifestContent, "utf-8"),
170+
};
171+
}
172+
138173
// Print package header
139174
logger.log(`\n📦 ${manifest.name}@${manifest.version}`);
140175

0 commit comments

Comments
 (0)