Skip to content

Commit 5fd99f8

Browse files
committed
Add cartridge minter tool
1 parent c537217 commit 5fd99f8

3 files changed

Lines changed: 198 additions & 0 deletions

File tree

tools/cartridge-minter/README.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Cartridge Minter
2+
3+
The Cartridge Minter is a tool for packaging, signing, and versioning cartridges for the BoJ server.
4+
5+
## Features
6+
7+
- Package cartridges into distributable artifacts
8+
- Generate A2ML manifests and panll descriptors
9+
- Sign cartridges for security and authenticity
10+
- Version cartridges using semantic versioning
11+
12+
## Installation
13+
14+
```bash
15+
cd tools/cartridge-minter
16+
npm install
17+
```
18+
19+
## Usage
20+
21+
### Command Line
22+
23+
```bash
24+
node minter.js <cartridge-dir> <output-dir> [--sign] [--version <version>]
25+
```
26+
27+
### Options
28+
29+
- `<cartridge-dir>`: Path to the cartridge directory containing `cartridge.json`
30+
- `<output-dir>`: Path to the output directory for the minted cartridge
31+
- `--sign`: Sign the cartridge (placeholder for actual signing logic)
32+
- `--version <version>`: Specify the version of the cartridge (default: `0.1.0`)
33+
34+
### Example
35+
36+
```bash
37+
node minter.js ../../cartridges/my-cartridge output --sign --version 1.0.0
38+
```
39+
40+
### Programmatic Usage
41+
42+
```javascript
43+
import { mintCartridge } from './minter.js';
44+
45+
const result = await mintCartridge('path/to/cartridge', 'path/to/output', {
46+
sign: true,
47+
version: '1.0.0',
48+
});
49+
50+
console.log('Cartridge minted:', result);
51+
```
52+
53+
## Output
54+
55+
The Cartridge Minter generates the following files:
56+
57+
- `<cartridge-name>.a2ml.json`: A2ML manifest for the cartridge
58+
- `<cartridge-name>.panll.json`: panll descriptor for the cartridge
59+
60+
## License
61+
62+
This tool is licensed under the PMPL-1.0-or-later license. See the LICENSE file for more information.

tools/cartridge-minter/minter.js

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
#!/usr/bin/env node
2+
// SPDX-License-Identifier: PMPL-1.0-or-later
3+
// Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
4+
5+
// Cartridge Minter — Package, sign, and version cartridges
6+
7+
import { readFile, writeFile, mkdir, readdir } from 'node:fs/promises';
8+
import { join, dirname } from 'node:path';
9+
import { exec } from 'node:child_process';
10+
import { promisify } from 'node:util';
11+
12+
const execAsync = promisify(exec);
13+
14+
async function readJsonFile(filePath) {
15+
const content = await readFile(filePath, 'utf8');
16+
return JSON.parse(content);
17+
}
18+
19+
async function writeJsonFile(filePath, data) {
20+
await writeFile(filePath, JSON.stringify(data, null, 2), 'utf8');
21+
}
22+
23+
async function ensureDirectoryExists(directory) {
24+
await mkdir(directory, { recursive: true });
25+
}
26+
27+
async function mintCartridge(cartridgeDir, outputDir, options = {}) {
28+
const { sign = false, version = '0.1.0' } = options;
29+
30+
// Read cartridge.json
31+
const cartridgeJsonPath = join(cartridgeDir, 'cartridge.json');
32+
const cartridge = await readJsonFile(cartridgeJsonPath);
33+
34+
// Update version
35+
cartridge.version = version;
36+
37+
// Generate A2ML Manifest
38+
const a2mlManifest = {
39+
spdx: 'PMPL-1.0-or-later',
40+
name: cartridge.name,
41+
version: cartridge.version,
42+
description: cartridge.description,
43+
domain: cartridge.domain,
44+
tier: cartridge.tier,
45+
protocols: cartridge.protocols,
46+
tools: cartridge.tools,
47+
};
48+
49+
// Generate panll Descriptor
50+
const panllDescriptor = {
51+
name: cartridge.name,
52+
version: cartridge.version,
53+
description: cartridge.description,
54+
domain: cartridge.domain,
55+
tier: cartridge.tier,
56+
protocols: cartridge.protocols,
57+
tools: cartridge.tools,
58+
};
59+
60+
// Ensure output directory exists
61+
await ensureDirectoryExists(outputDir);
62+
63+
// Write A2ML Manifest
64+
const a2mlManifestPath = join(outputDir, `${cartridge.name}.a2ml.json`);
65+
await writeJsonFile(a2mlManifestPath, a2mlManifest);
66+
67+
// Write panll Descriptor
68+
const panllDescriptorPath = join(outputDir, `${cartridge.name}.panll.json`);
69+
await writeJsonFile(panllDescriptorPath, panllDescriptor);
70+
71+
// Sign the cartridge (placeholder for actual signing logic)
72+
if (sign) {
73+
console.log('Signing cartridge (placeholder)...');
74+
// In a real implementation, you would use a tool like Sigstore or GPG to sign the cartridge
75+
}
76+
77+
return {
78+
cartridge,
79+
a2mlManifest,
80+
panllDescriptor,
81+
a2mlManifestPath,
82+
panllDescriptorPath,
83+
};
84+
}
85+
86+
async function main() {
87+
const args = process.argv.slice(2);
88+
89+
if (args.length < 2) {
90+
console.error('Usage: node minter.js <cartridge-dir> <output-dir> [--sign] [--version <version>]');
91+
process.exit(1);
92+
}
93+
94+
const cartridgeDir = args[0];
95+
const outputDir = args[1];
96+
const sign = args.includes('--sign');
97+
const versionIndex = args.indexOf('--version');
98+
const version = versionIndex !== -1 ? args[versionIndex + 1] : '0.1.0';
99+
100+
try {
101+
console.log(`Minting cartridge from ${cartridgeDir}...`);
102+
const result = await mintCartridge(cartridgeDir, outputDir, { sign, version });
103+
104+
console.log('Cartridge minted successfully:');
105+
console.log(` Name: ${result.cartridge.name}`);
106+
console.log(` Version: ${result.cartridge.version}`);
107+
console.log(` A2ML Manifest: ${result.a2mlManifestPath}`);
108+
console.log(` panll Descriptor: ${result.panllDescriptorPath}`);
109+
110+
if (sign) {
111+
console.log(' Signed: Yes');
112+
}
113+
} catch (error) {
114+
console.error('Error minting cartridge:', error);
115+
process.exit(1);
116+
}
117+
}
118+
119+
if (import.meta.url === `file://${process.argv[1]}`) {
120+
main();
121+
}
122+
123+
export { mintCartridge };
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"name": "cartridge-minter",
3+
"version": "0.1.0",
4+
"description": "Cartridge Minter — Package, sign, and version cartridges",
5+
"main": "minter.js",
6+
"scripts": {
7+
"test": "echo \"Error: no test specified\" && exit 1"
8+
},
9+
"keywords": ["boj-server", "cartridge", "minter"],
10+
"author": "Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>",
11+
"license": "PMPL-1.0-or-later",
12+
"type": "module"
13+
}

0 commit comments

Comments
 (0)