spawnpack 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -15
- package/dist/spawnpack.js +74 -40
- package/package.json +2 -1
- package/templates/AGENTS.md +805 -0
- package/templates/CLAUDE.md +805 -803
package/README.md
CHANGED
|
@@ -16,10 +16,11 @@ It generates BP/RP structure, optional Script API setup, optional rgl integratio
|
|
|
16
16
|
- `@minecraft/math`
|
|
17
17
|
- Optional `rgl` setup for faster Bedrock builds
|
|
18
18
|
- Optional marketplace add-on structure using nested `namespace/projectId` folders in BP/RP content directories
|
|
19
|
-
- Optional Rockide recommendation during setup
|
|
20
|
-
- Optional AI setup:
|
|
21
|
-
- `CLAUDE.md`
|
|
22
|
-
-
|
|
19
|
+
- Optional Rockide recommendation during setup
|
|
20
|
+
- Optional AI setup:
|
|
21
|
+
- `CLAUDE.md` for Claude
|
|
22
|
+
- `AGENTS.md` for Other
|
|
23
|
+
- `.mcp.json`
|
|
23
24
|
|
|
24
25
|
## Runtime Requirement
|
|
25
26
|
|
|
@@ -78,7 +79,7 @@ The wizard walks through:
|
|
|
78
79
|
6. Script packages
|
|
79
80
|
7. `rgl` toggle
|
|
80
81
|
8. Rockide toggle
|
|
81
|
-
9. AI setup
|
|
82
|
+
9. AI setup choice (`None`, `Claude`, or `Other`)
|
|
82
83
|
10. Review screen and generation
|
|
83
84
|
|
|
84
85
|
## Generated project options
|
|
@@ -92,9 +93,10 @@ Depending on your choices, Spawnpack can generate:
|
|
|
92
93
|
- `package.json`
|
|
93
94
|
- `tsconfig.json`
|
|
94
95
|
- `dprint.json`
|
|
95
|
-
- `config.json` for `rgl`
|
|
96
|
-
- `CLAUDE.md`
|
|
97
|
-
-
|
|
96
|
+
- `config.json` for `rgl`
|
|
97
|
+
- `CLAUDE.md`
|
|
98
|
+
- `AGENTS.md`
|
|
99
|
+
- `.mcp.json`
|
|
98
100
|
|
|
99
101
|
## Marketplace structure mode
|
|
100
102
|
|
|
@@ -120,9 +122,11 @@ Spawnpack fetches the latest stable npm versions for:
|
|
|
120
122
|
- `@minecraft/vanilla-data`
|
|
121
123
|
- `@minecraft/math`
|
|
122
124
|
|
|
123
|
-
If version lookup fails, it falls back to baked stable defaults.
|
|
124
|
-
|
|
125
|
-
|
|
125
|
+
If version lookup fails, it falls back to baked stable defaults.
|
|
126
|
+
|
|
127
|
+
Only runtime Script API modules, currently `@minecraft/server` and `@minecraft/server-ui`, are written to the behavior pack manifest. npm-side libraries such as `@minecraft/vanilla-data` and `@minecraft/math` stay in the generated `package.json` for imports and bundling.
|
|
128
|
+
|
|
129
|
+
## Development
|
|
126
130
|
|
|
127
131
|
```bash
|
|
128
132
|
bun install
|
|
@@ -134,10 +138,11 @@ bun run build
|
|
|
134
138
|
|
|
135
139
|
The npm package is configured to publish only:
|
|
136
140
|
|
|
137
|
-
- `dist/spawnpack.js`
|
|
138
|
-
- `templates/CLAUDE.md`
|
|
139
|
-
- `
|
|
140
|
-
- `
|
|
141
|
+
- `dist/spawnpack.js`
|
|
142
|
+
- `templates/CLAUDE.md`
|
|
143
|
+
- `templates/AGENTS.md`
|
|
144
|
+
- `README.md`
|
|
145
|
+
- `LICENSE`
|
|
141
146
|
- `package.json`
|
|
142
147
|
|
|
143
148
|
Internal planning files, Serena state, and local AI/project notes are excluded from the published tarball.
|
package/dist/spawnpack.js
CHANGED
|
@@ -1571,13 +1571,22 @@ function getScriptDirectorySegments(config) {
|
|
|
1571
1571
|
function getScriptEntryPath(config) {
|
|
1572
1572
|
return [...getScriptDirectorySegments(config), "main.js"].join("/");
|
|
1573
1573
|
}
|
|
1574
|
+
function getAiDocFilename(aiSetup) {
|
|
1575
|
+
if (aiSetup === "claude") {
|
|
1576
|
+
return "CLAUDE.md";
|
|
1577
|
+
}
|
|
1578
|
+
if (aiSetup === "other") {
|
|
1579
|
+
return "AGENTS.md";
|
|
1580
|
+
}
|
|
1581
|
+
return null;
|
|
1582
|
+
}
|
|
1574
1583
|
|
|
1575
1584
|
// src/engine/manifests.ts
|
|
1576
1585
|
var PACK_VERSION = [1, 0, 0];
|
|
1577
1586
|
function getAuthors(author) {
|
|
1578
1587
|
return author.trim() === "" ? [] : [author];
|
|
1579
1588
|
}
|
|
1580
|
-
function
|
|
1589
|
+
function getManifestScriptDependencies(config, versions) {
|
|
1581
1590
|
const dependencies = [];
|
|
1582
1591
|
if (config.scriptPackages.server) {
|
|
1583
1592
|
dependencies.push({ module_name: "@minecraft/server", version: versions.server });
|
|
@@ -1585,12 +1594,6 @@ function getScriptDependencies(config, versions) {
|
|
|
1585
1594
|
if (config.scriptPackages.serverUi) {
|
|
1586
1595
|
dependencies.push({ module_name: "@minecraft/server-ui", version: versions.serverUi });
|
|
1587
1596
|
}
|
|
1588
|
-
if (config.scriptPackages.vanillaData) {
|
|
1589
|
-
dependencies.push({ module_name: "@minecraft/vanilla-data", version: versions.vanillaData });
|
|
1590
|
-
}
|
|
1591
|
-
if (config.scriptPackages.math) {
|
|
1592
|
-
dependencies.push({ module_name: "@minecraft/math", version: versions.math });
|
|
1593
|
-
}
|
|
1594
1597
|
return dependencies;
|
|
1595
1598
|
}
|
|
1596
1599
|
function getBpModules(config) {
|
|
@@ -1609,7 +1612,7 @@ function getBpModules(config) {
|
|
|
1609
1612
|
function generateBpManifest(config, bpUuid, rpUuid, versions) {
|
|
1610
1613
|
const dependencies = [{ uuid: rpUuid, version: PACK_VERSION }];
|
|
1611
1614
|
if (config.scripting !== "none") {
|
|
1612
|
-
dependencies.push(...
|
|
1615
|
+
dependencies.push(...getManifestScriptDependencies(config, versions));
|
|
1613
1616
|
}
|
|
1614
1617
|
return {
|
|
1615
1618
|
format_version: VERSIONS.manifestFormat,
|
|
@@ -1891,9 +1894,10 @@ function generateReadme(config) {
|
|
|
1891
1894
|
const runtimeEntry = config.scripting === "none" ? "None" : `packs/BP/${getScriptEntryPath(config)}`;
|
|
1892
1895
|
const installStep = config.scripting !== "none" ? "1. Install dependencies with `bun install` or `npm install`." : "1. No package install is required for this scaffold.";
|
|
1893
1896
|
const buildSteps = config.scripting === "none" ? "2. Edit your BP/RP JSON files directly inside `packs/`." : config.useRgl ? "2. Run `rgl watch` while developing to rebuild and export your add-on automatically.\n3. Run `rgl run build` when you want a production build." : config.scripting === "typescript" ? "2. Write your gameplay scripts in `data/scripts/`.\n3. Run `bun run build` or `npm run build` to compile TypeScript into `packs/BP/scripts/`." : "2. Write your gameplay scripts in `packs/BP/scripts/` and let Minecraft copy the pack into `com.mojang`.";
|
|
1894
|
-
const
|
|
1897
|
+
const aiDocFilename = getAiDocFilename(config.aiSetup);
|
|
1898
|
+
const aiSection = aiDocFilename !== null ? `## AI Tooling
|
|
1895
1899
|
|
|
1896
|
-
Spawnpack generated \`
|
|
1900
|
+
Spawnpack generated \`${aiDocFilename}\` and \`.mcp.json\` for AI-assisted development.
|
|
1897
1901
|
|
|
1898
1902
|
Add your own API keys before using the MCP tools:
|
|
1899
1903
|
|
|
@@ -1904,6 +1908,11 @@ Add your own API keys before using the MCP tools:
|
|
|
1904
1908
|
|
|
1905
1909
|
Update the placeholder values in \`.mcp.json\` with your own tokens.
|
|
1906
1910
|
|
|
1911
|
+
` : "";
|
|
1912
|
+
const scriptPackageSection = config.scripting !== "none" ? `## Script Packages
|
|
1913
|
+
|
|
1914
|
+
Selected npm packages are installed through \`package.json\`. Only runtime Script API modules such as \`@minecraft/server\` and \`@minecraft/server-ui\` are written to \`packs/BP/manifest.json\`; npm-side libraries such as \`@minecraft/vanilla-data\` and \`@minecraft/math\` are imported and bundled from \`package.json\`.
|
|
1915
|
+
|
|
1907
1916
|
` : "";
|
|
1908
1917
|
return `# ${config.projectName}
|
|
1909
1918
|
|
|
@@ -1928,7 +1937,7 @@ ${config.scripting === "none" ? "This project was generated without Script API s
|
|
|
1928
1937
|
- Add additional JavaScript files beside \`main.js\` and import them from there.
|
|
1929
1938
|
- Minecraft copies the BP/RP content directly into \`com.mojang\`, so there is no TypeScript compile step.`}
|
|
1930
1939
|
|
|
1931
|
-
${config.useRgl ? `## rgl Workflow
|
|
1940
|
+
${scriptPackageSection}${config.useRgl ? `## rgl Workflow
|
|
1932
1941
|
|
|
1933
1942
|
- \`rgl watch\` rebuilds your scripts and exports your add-on while you work.
|
|
1934
1943
|
- \`rgl run\` builds a development export once.
|
|
@@ -2162,30 +2171,37 @@ async function generateMcpConfig(projectPath) {
|
|
|
2162
2171
|
// src/provisioning/ai.ts
|
|
2163
2172
|
var AI_EXCLUDE_LINES = [
|
|
2164
2173
|
"# AI tool files",
|
|
2165
|
-
"CLAUDE.md",
|
|
2166
|
-
"AGENTS.md",
|
|
2167
|
-
"
|
|
2168
|
-
"
|
|
2169
|
-
"
|
|
2170
|
-
];
|
|
2171
|
-
var CLAUDE_TEMPLATE_URLS = [
|
|
2172
|
-
new URL("../templates/CLAUDE.md", import.meta.url),
|
|
2173
|
-
new URL("../../templates/CLAUDE.md", import.meta.url)
|
|
2174
|
+
"/CLAUDE.md",
|
|
2175
|
+
"/AGENTS.md",
|
|
2176
|
+
"/.mcp.json",
|
|
2177
|
+
"/.claude/",
|
|
2178
|
+
"/.serena/"
|
|
2174
2179
|
];
|
|
2175
|
-
|
|
2176
|
-
|
|
2180
|
+
function getTemplateUrls(filename) {
|
|
2181
|
+
return [
|
|
2182
|
+
new URL(`../templates/${filename}`, import.meta.url),
|
|
2183
|
+
new URL(`../../templates/${filename}`, import.meta.url)
|
|
2184
|
+
];
|
|
2185
|
+
}
|
|
2186
|
+
async function createAiDocContent(filename) {
|
|
2187
|
+
const templateUrls = getTemplateUrls(filename);
|
|
2188
|
+
for (const templateUrl of templateUrls) {
|
|
2177
2189
|
const templateFile = Bun.file(templateUrl);
|
|
2178
2190
|
const exists = await templateFile.exists().then((value) => value, () => false);
|
|
2179
2191
|
if (exists) {
|
|
2180
2192
|
return await templateFile.text();
|
|
2181
2193
|
}
|
|
2182
2194
|
}
|
|
2183
|
-
return await Bun.file(
|
|
2195
|
+
return await Bun.file(templateUrls[0]).text();
|
|
2184
2196
|
}
|
|
2185
|
-
async function
|
|
2186
|
-
const
|
|
2187
|
-
|
|
2188
|
-
|
|
2197
|
+
async function generateAiDoc(projectPath, aiSetup) {
|
|
2198
|
+
const filename = getAiDocFilename(aiSetup);
|
|
2199
|
+
if (filename === null) {
|
|
2200
|
+
return;
|
|
2201
|
+
}
|
|
2202
|
+
const outputPath = join3(projectPath, filename);
|
|
2203
|
+
const content = await createAiDocContent(filename);
|
|
2204
|
+
await Bun.write(outputPath, content).then(() => {
|
|
2189
2205
|
return;
|
|
2190
2206
|
}, () => {
|
|
2191
2207
|
return;
|
|
@@ -2218,8 +2234,11 @@ async function setupGitExcludes(projectPath) {
|
|
|
2218
2234
|
return;
|
|
2219
2235
|
});
|
|
2220
2236
|
}
|
|
2221
|
-
async function setupAi(projectPath) {
|
|
2222
|
-
|
|
2237
|
+
async function setupAi(projectPath, aiSetup) {
|
|
2238
|
+
if (aiSetup === "none") {
|
|
2239
|
+
return;
|
|
2240
|
+
}
|
|
2241
|
+
await generateAiDoc(projectPath, aiSetup);
|
|
2223
2242
|
await setupGitExcludes(projectPath);
|
|
2224
2243
|
await generateMcpConfig(projectPath);
|
|
2225
2244
|
}
|
|
@@ -2317,6 +2336,15 @@ function getScriptingLabel(choice) {
|
|
|
2317
2336
|
}
|
|
2318
2337
|
return "None";
|
|
2319
2338
|
}
|
|
2339
|
+
function getAiSetupLabel(choice) {
|
|
2340
|
+
if (choice === "claude") {
|
|
2341
|
+
return "Claude";
|
|
2342
|
+
}
|
|
2343
|
+
if (choice === "other") {
|
|
2344
|
+
return "Other";
|
|
2345
|
+
}
|
|
2346
|
+
return "None";
|
|
2347
|
+
}
|
|
2320
2348
|
function getSelectedPackages(scriptPackages) {
|
|
2321
2349
|
const packages = [];
|
|
2322
2350
|
if (scriptPackages.server) {
|
|
@@ -2423,8 +2451,9 @@ function showFolderTree(config) {
|
|
|
2423
2451
|
if (config.useRgl) {
|
|
2424
2452
|
lines.push(import_picocolors.default.dim("├─ config.json"));
|
|
2425
2453
|
}
|
|
2426
|
-
|
|
2427
|
-
|
|
2454
|
+
const aiDocFilename = getAiDocFilename(config.aiSetup);
|
|
2455
|
+
if (aiDocFilename !== null) {
|
|
2456
|
+
lines.push(import_picocolors.default.dim(`├─ ${aiDocFilename}`));
|
|
2428
2457
|
lines.push(import_picocolors.default.dim("├─ .mcp.json"));
|
|
2429
2458
|
}
|
|
2430
2459
|
lines.push(import_picocolors.default.dim("├─ .gitignore"));
|
|
@@ -2452,7 +2481,7 @@ function showReview(config) {
|
|
|
2452
2481
|
`${border} ${import_picocolors.default.dim(padLabel("Packages:"))} ${packages}`,
|
|
2453
2482
|
`${border} ${import_picocolors.default.dim(padLabel("rgl:"))} ${formatToggle(config.useRgl)}`,
|
|
2454
2483
|
`${border} ${import_picocolors.default.dim(padLabel("Rockide:"))} ${formatToggle(config.installRockide)}`,
|
|
2455
|
-
`${border} ${import_picocolors.default.dim(padLabel("AI Setup:"))} ${
|
|
2484
|
+
`${border} ${import_picocolors.default.dim(padLabel("AI Setup:"))} ${formatValue(getAiSetupLabel(config.aiSetup))}`,
|
|
2456
2485
|
"",
|
|
2457
2486
|
`${border} ${teal(import_picocolors.default.bold("Planned structure"))}`,
|
|
2458
2487
|
...showFolderTree(config).split(`
|
|
@@ -2483,7 +2512,7 @@ function showPostGeneration(config) {
|
|
|
2483
2512
|
if (config.scripting === "none" && !config.useRgl) {
|
|
2484
2513
|
usefulCommands.push(` ${import_picocolors.default.dim("No extra build commands needed for this scaffold")}`);
|
|
2485
2514
|
}
|
|
2486
|
-
if (config.
|
|
2515
|
+
if (config.aiSetup !== "none") {
|
|
2487
2516
|
usefulCommands.push("");
|
|
2488
2517
|
usefulCommands.push(`${teal(import_picocolors.default.bold("Note"))} ${import_picocolors.default.dim("Add your own Exa and Browser Use MCP API keys in .mcp.json before using the AI tooling.")}`);
|
|
2489
2518
|
usefulCommands.push(` ${import_picocolors.default.dim("Exa:")} ${import_picocolors.default.cyan("https://dashboard.exa.ai/api-keys")}`);
|
|
@@ -2657,11 +2686,16 @@ async function runWizard() {
|
|
|
2657
2686
|
if (q(installRockide2)) {
|
|
2658
2687
|
return abortWizard();
|
|
2659
2688
|
}
|
|
2660
|
-
const
|
|
2661
|
-
message:
|
|
2662
|
-
initialValue:
|
|
2689
|
+
const aiSetup = await _t({
|
|
2690
|
+
message: import_picocolors2.default.bold("AI setup"),
|
|
2691
|
+
initialValue: "none",
|
|
2692
|
+
options: [
|
|
2693
|
+
{ value: "none", label: "None", hint: "no AI docs or MCP config" },
|
|
2694
|
+
{ value: "claude", label: "Claude", hint: "generate CLAUDE.md and .mcp.json" },
|
|
2695
|
+
{ value: "other", label: "Other", hint: "generate AGENTS.md and .mcp.json" }
|
|
2696
|
+
]
|
|
2663
2697
|
});
|
|
2664
|
-
if (q(
|
|
2698
|
+
if (q(aiSetup)) {
|
|
2665
2699
|
return abortWizard();
|
|
2666
2700
|
}
|
|
2667
2701
|
const config = {
|
|
@@ -2674,7 +2708,7 @@ async function runWizard() {
|
|
|
2674
2708
|
scriptPackages: scripting === "none" ? { ...DEFAULT_SCRIPT_PACKAGES } : scriptPackages,
|
|
2675
2709
|
useMarketplaceStructure,
|
|
2676
2710
|
useRgl: scripting === "none" ? false : useRgl,
|
|
2677
|
-
|
|
2711
|
+
aiSetup,
|
|
2678
2712
|
installRockide: installRockide2
|
|
2679
2713
|
};
|
|
2680
2714
|
showReview(config);
|
|
@@ -2703,8 +2737,8 @@ if (config === null) {
|
|
|
2703
2737
|
var generation = fe();
|
|
2704
2738
|
generation.start(teal3("Generating your Bedrock addon scaffold..."));
|
|
2705
2739
|
await generateProject(config);
|
|
2706
|
-
if (config.
|
|
2707
|
-
await setupAi(config.destination);
|
|
2740
|
+
if (config.aiSetup !== "none") {
|
|
2741
|
+
await setupAi(config.destination, config.aiSetup);
|
|
2708
2742
|
}
|
|
2709
2743
|
await runProvisioning(config);
|
|
2710
2744
|
generation.stop(import_picocolors3.default.green("Spawnpack scaffold generated."));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spawnpack",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "Minecraft Bedrock addon project generator — scaffold your BP+RP in seconds",
|
|
5
5
|
"author": "veedy-dev",
|
|
6
6
|
"license": "MIT",
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"bin/spawnpack.js",
|
|
13
13
|
"dist/spawnpack.js",
|
|
14
14
|
"templates/CLAUDE.md",
|
|
15
|
+
"templates/AGENTS.md",
|
|
15
16
|
"README.md",
|
|
16
17
|
"LICENSE",
|
|
17
18
|
"package.json"
|