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 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
- - `.mcp.json`
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 toggle
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
- - `.mcp.json`
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
- ## Development
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
- - `README.md`
140
- - `LICENSE`
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 getScriptDependencies(config, versions) {
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(...getScriptDependencies(config, versions));
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 aiSection = config.useAi ? `## AI Tooling
1897
+ const aiDocFilename = getAiDocFilename(config.aiSetup);
1898
+ const aiSection = aiDocFilename !== null ? `## AI Tooling
1895
1899
 
1896
- Spawnpack generated \`CLAUDE.md\` and \`.mcp.json\` for AI-assisted development.
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
- ".mcp.json",
2168
- ".claude/",
2169
- ".serena/"
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
- async function createClaudeMdContent() {
2176
- for (const templateUrl of CLAUDE_TEMPLATE_URLS) {
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(CLAUDE_TEMPLATE_URLS[0]).text();
2195
+ return await Bun.file(templateUrls[0]).text();
2184
2196
  }
2185
- async function generateClaudeMd(projectPath) {
2186
- const claudePath = join3(projectPath, "CLAUDE.md");
2187
- const content = await createClaudeMdContent();
2188
- await Bun.write(claudePath, content).then(() => {
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
- await generateClaudeMd(projectPath);
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
- if (config.useAi) {
2427
- lines.push(import_picocolors.default.dim("├─ CLAUDE.md"));
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:"))} ${formatToggle(config.useAi)}`,
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.useAi) {
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 useAi = await ot2({
2661
- message: `${import_picocolors2.default.bold("AI setup?")} ${import_picocolors2.default.dim("generate CLAUDE.md with Bedrock development rules")}`,
2662
- initialValue: false
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(useAi)) {
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
- useAi,
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.useAi) {
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.4",
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"