spawnpack 0.1.2 → 0.1.4

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
@@ -30,17 +30,17 @@ Install Bun first:
30
30
 
31
31
  ## Install
32
32
 
33
- ### Global install with Bun
34
-
35
- ```bash
36
- bun add -g spawnpack
37
- ```
38
-
39
- ### Global install with npm
40
-
41
- ```bash
42
- npm i -g spawnpack
43
- ```
33
+ ### Global install with Bun
34
+
35
+ ```bash
36
+ bun add -g spawnpack
37
+ ```
38
+
39
+ ### Global install with npm
40
+
41
+ ```bash
42
+ npm i -g spawnpack
43
+ ```
44
44
 
45
45
  ### One-off run with Bun
46
46
 
@@ -57,24 +57,24 @@ bun run src/index.ts
57
57
 
58
58
  ## Usage
59
59
 
60
- ```bash
61
- spawnpack
62
- ```
63
-
64
- Show the installed version:
65
-
66
- ```bash
67
- spawnpack -v
68
- spawnpack --version
69
- ```
60
+ ```bash
61
+ spawnpack
62
+ ```
63
+
64
+ Show the installed version:
65
+
66
+ ```bash
67
+ spawnpack -v
68
+ spawnpack --version
69
+ ```
70
70
 
71
71
  The wizard walks through:
72
72
 
73
73
  1. Project name and author
74
- 2. Namespace, addon identifier, and project ID
74
+ 2. Marketplace add-on structure toggle
75
75
  3. Destination folder
76
- 4. Marketplace add-on structure toggle
77
- 5. Scripting mode
76
+ 4. Script API setup
77
+ 5. Publisher ID and Project ID when needed
78
78
  6. Script packages
79
79
  7. `rgl` toggle
80
80
  8. Rockide toggle
@@ -88,7 +88,7 @@ Depending on your choices, Spawnpack can generate:
88
88
  - `packs/BP`
89
89
  - `packs/RP`
90
90
  - `data/scripts/main.ts`
91
- - `packs/BP/scripts/<namespace>/<projectId>/main.js`
91
+ - `packs/BP/scripts/<publisher-id>/<project-id>/main.js`
92
92
  - `package.json`
93
93
  - `tsconfig.json`
94
94
  - `dprint.json`
@@ -135,7 +135,7 @@ bun run build
135
135
  The npm package is configured to publish only:
136
136
 
137
137
  - `dist/spawnpack.js`
138
- - `templates/CLAUDE.md`
138
+ - `templates/CLAUDE.md`
139
139
  - `README.md`
140
140
  - `LICENSE`
141
141
  - `package.json`
package/dist/spawnpack.js CHANGED
@@ -1748,7 +1748,7 @@ function generatePackageJson(config, versions) {
1748
1748
  scripts.check = "bun --smol packs/BP/scripts";
1749
1749
  }
1750
1750
  const packageJson = {
1751
- name: `${config.namespace}-${config.projectId}`,
1751
+ name: `${config.identifier}-${config.projectId}`,
1752
1752
  version: PACK_VERSION2,
1753
1753
  private: true,
1754
1754
  type: "module",
@@ -1861,7 +1861,7 @@ function generateMainTs(config) {
1861
1861
  return `import { world } from "@minecraft/server";
1862
1862
 
1863
1863
  world.afterEvents.worldLoad.subscribe(() => {
1864
- console.warn("[${config.namespace}:${config.identifier}] Addon loaded!");
1864
+ console.warn("[${config.identifier}:${config.projectId}] Addon loaded!");
1865
1865
  });
1866
1866
  `;
1867
1867
  }
@@ -1869,7 +1869,7 @@ function generateMainJs(config) {
1869
1869
  return `import { world } from "@minecraft/server";
1870
1870
 
1871
1871
  world.afterEvents.worldLoad.subscribe(() => {
1872
- console.warn("[${config.namespace}:${config.identifier}] Addon loaded!");
1872
+ console.warn("[${config.identifier}:${config.projectId}] Addon loaded!");
1873
1873
  });
1874
1874
  `;
1875
1875
  }
@@ -1899,8 +1899,8 @@ Add your own API keys before using the MCP tools:
1899
1899
 
1900
1900
  - Exa API keys: https://dashboard.exa.ai/api-keys
1901
1901
  - Exa API key docs: https://exa.ai/docs/reference/team-management/create-api-key
1902
- - Hyperbrowser signup: https://app.hyperbrowser.ai/signup
1903
- - Hyperbrowser quickstart: https://hyperbrowser.ai/docs/quickstart
1902
+ - Browser Use API keys: https://cloud.browser-use.com/settings?tab=api-keys&new=1
1903
+ - Browser Use MCP docs: https://docs.browser-use.com/cloud/guides/mcp-server
1904
1904
 
1905
1905
  Update the placeholder values in \`.mcp.json\` with your own tokens.
1906
1906
 
@@ -1911,7 +1911,7 @@ Update the placeholder values in \`.mcp.json\` with your own tokens.
1911
1911
 
1912
1912
  - Behavior Pack: \`packs/BP\`
1913
1913
  - Resource Pack: \`packs/RP\`
1914
- - Scripting: ${config.scripting}
1914
+ - Script API setup: ${config.scripting}
1915
1915
  - Script source: ${scriptSource}
1916
1916
  - Runtime entry: ${runtimeEntry}
1917
1917
 
@@ -1942,10 +1942,10 @@ The generated \`config.json\` already points the script bundle to \`${runtimeEnt
1942
1942
  `;
1943
1943
  }
1944
1944
  function generateBlocksJson() {
1945
- return {};
1945
+ return { format_version: "1.21.40" };
1946
1946
  }
1947
1947
  function generateSoundsJson() {
1948
- return {};
1948
+ return { entity_sounds: {} };
1949
1949
  }
1950
1950
  function generateSoundDefinitions() {
1951
1951
  return { format_version: "1.14.0", sound_definitions: {} };
@@ -2059,12 +2059,12 @@ async function generateProject(config) {
2059
2059
  directories.push(...BP_NAMESPACED_DIRECTORIES.map((folder) => getScopedContentDirectory(bpPath, folder, config)), ...RP_NAMESPACED_DIRECTORIES.map((folder) => getScopedContentDirectory(rpPath, folder, config)), ...RP_NAMESPACED_NESTED_DIRECTORIES.map((segments) => getScopedNestedContentDirectory(rpPath, segments, config)));
2060
2060
  }
2061
2061
  if (config.scripting === "javascript") {
2062
- directories.push(join(bpPath, "scripts"), join(bpPath, "scripts", config.namespace), bpScriptPath);
2062
+ directories.push(join(bpPath, "scripts"), join(bpPath, "scripts", config.identifier), bpScriptPath);
2063
2063
  }
2064
2064
  if (config.scripting === "typescript") {
2065
2065
  directories.push(join(destination, "data"), dataScriptsPath);
2066
2066
  if (!config.useRgl) {
2067
- directories.push(join(bpPath, "scripts"), join(bpPath, "scripts", config.namespace), bpScriptPath);
2067
+ directories.push(join(bpPath, "scripts"), join(bpPath, "scripts", config.identifier), bpScriptPath);
2068
2068
  }
2069
2069
  }
2070
2070
  await Promise.all(directories.filter(shouldCreateDirectory).map((directory) => mkdir(directory, { recursive: true })));
@@ -2117,11 +2117,10 @@ function buildMcpServers() {
2117
2117
  EXA_API_KEY: "YOUR_EXA_API_KEY"
2118
2118
  }
2119
2119
  },
2120
- hyperbrowser: {
2121
- command: "npx",
2122
- args: ["-y", "hyperbrowser-mcp"],
2123
- env: {
2124
- HYPERBROWSER_API_KEY: "YOUR_HYPERBROWSER_API_KEY"
2120
+ "browser-use": {
2121
+ url: "https://api.browser-use.com/v3/mcp",
2122
+ headers: {
2123
+ "x-browser-use-api-key": "YOUR_BROWSER_USE_API_KEY"
2125
2124
  }
2126
2125
  },
2127
2126
  "sequential-thinking": {
@@ -2441,7 +2440,6 @@ function showReview(config) {
2441
2440
  "",
2442
2441
  `${border} ${import_picocolors.default.dim(padLabel("Project:"))} ${formatValue(config.projectName)}`,
2443
2442
  `${border} ${import_picocolors.default.dim(padLabel("Author:"))} ${config.author ? formatValue(config.author) : import_picocolors.default.dim("—")}`,
2444
- `${border} ${import_picocolors.default.dim(padLabel("Namespace:"))} ${formatValue(config.namespace)}`,
2445
2443
  ...config.useMarketplaceStructure ? [
2446
2444
  `${border} ${import_picocolors.default.dim(padLabel("Publisher ID:"))} ${formatValue(config.identifier)}`,
2447
2445
  `${border} ${import_picocolors.default.dim(padLabel("Project ID:"))} ${formatValue(config.projectId)}`,
@@ -2487,9 +2485,9 @@ function showPostGeneration(config) {
2487
2485
  }
2488
2486
  if (config.useAi) {
2489
2487
  usefulCommands.push("");
2490
- usefulCommands.push(`${teal(import_picocolors.default.bold("Note"))} ${import_picocolors.default.dim("Add your own Exa and Hyperbrowser MCP API keys in .mcp.json before using the AI tooling.")}`);
2488
+ 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.")}`);
2491
2489
  usefulCommands.push(` ${import_picocolors.default.dim("Exa:")} ${import_picocolors.default.cyan("https://dashboard.exa.ai/api-keys")}`);
2492
- usefulCommands.push(` ${import_picocolors.default.dim("Hyperbrowser:")} ${import_picocolors.default.cyan("https://app.hyperbrowser.ai/signup")}`);
2490
+ usefulCommands.push(` ${import_picocolors.default.dim("Browser Use:")} ${import_picocolors.default.cyan("https://cloud.browser-use.com/settings?tab=api-keys&new=1")}`);
2493
2491
  }
2494
2492
  O2.message([...nextSteps, "", ...usefulCommands].join(`
2495
2493
  `), {
@@ -2536,7 +2534,6 @@ async function runWizard() {
2536
2534
  return abortWizard();
2537
2535
  }
2538
2536
  const trimmedProjectName = projectName.trim();
2539
- const defaultNamespace = "sample";
2540
2537
  const suggestedProjectId = generateProjectId(trimmedProjectName);
2541
2538
  const author = await Ot({
2542
2539
  message: `${import_picocolors2.default.bold("Author")} ${import_picocolors2.default.dim("optional")}`,
@@ -2545,39 +2542,55 @@ async function runWizard() {
2545
2542
  if (q(author)) {
2546
2543
  return abortWizard();
2547
2544
  }
2548
- const namespace = await Ot({
2549
- message: `${import_picocolors2.default.bold("Namespace")} ${import_picocolors2.default.dim("used in identifiers like namespace:item_name")}`,
2550
- placeholder: defaultNamespace,
2551
- initialValue: defaultNamespace,
2545
+ const useMarketplaceStructure = await ot2({
2546
+ message: `${import_picocolors2.default.bold("Marketplace Add-On structure?")} ${import_picocolors2.default.dim("Nest BP/RP content under publisher_id/project_id for better coexistence")}`,
2547
+ initialValue: false
2548
+ });
2549
+ if (q(useMarketplaceStructure)) {
2550
+ return abortWizard();
2551
+ }
2552
+ const defaultPublisherId = sanitizeIdentifier(author.trim()) || sanitizeIdentifier(trimmedProjectName) || "sample";
2553
+ let identifierValue = defaultPublisherId;
2554
+ let projectIdValue = suggestedProjectId;
2555
+ const destination = await Ot({
2556
+ message: import_picocolors2.default.bold("Destination folder"),
2557
+ placeholder: ".",
2558
+ initialValue: ".",
2552
2559
  validate(value) {
2553
2560
  const trimmed = (value ?? "").trim();
2554
2561
  if (trimmed.length === 0) {
2555
- return "Namespace is required.";
2562
+ return "Destination folder is required.";
2563
+ }
2564
+ if (/[<>"|?*]/.test(trimmed)) {
2565
+ return 'Invalid characters in path (avoid < > " | ? *).';
2556
2566
  }
2557
- if (!/^[a-z0-9_]+$/.test(trimmed)) {
2558
- return "Use lowercase letters, numbers, and underscores only.";
2567
+ if (trimmed.length > 200) {
2568
+ return "Path is too long (max 200 characters).";
2559
2569
  }
2560
2570
  return;
2561
2571
  }
2562
2572
  });
2563
- if (q(namespace)) {
2573
+ if (q(destination)) {
2564
2574
  return abortWizard();
2565
2575
  }
2566
- const namespaceValue = namespace.trim();
2567
- const useMarketplaceStructure = await ot2({
2568
- message: `${import_picocolors2.default.bold("Marketplace Add-On structure?")} ${import_picocolors2.default.dim("Nest BP/RP content under publisher_id/project_id for better coexistence")}`,
2569
- initialValue: false
2576
+ const scripting = await _t({
2577
+ message: import_picocolors2.default.bold("Scripting API"),
2578
+ initialValue: "typescript",
2579
+ options: [
2580
+ { value: "none", label: "None", hint: "manifest-only addon scaffold" },
2581
+ { value: "javascript", label: "JavaScript", hint: "script entry with JS tooling" },
2582
+ { value: "typescript", label: "TypeScript", hint: "recommended" }
2583
+ ]
2570
2584
  });
2571
- if (q(useMarketplaceStructure)) {
2585
+ if (q(scripting)) {
2572
2586
  return abortWizard();
2573
2587
  }
2574
- let identifierValue = namespaceValue;
2575
- let projectIdValue = suggestedProjectId;
2576
- if (useMarketplaceStructure) {
2588
+ if (useMarketplaceStructure || scripting !== "none") {
2589
+ const publisherHint = useMarketplaceStructure ? "used for scoped folders like publisher_id/project_id" : "used for script folders and package naming";
2577
2590
  const publisherId = await Ot({
2578
- message: `${import_picocolors2.default.bold("Publisher ID")} ${import_picocolors2.default.dim("used for scoped folders like publisher_id/project_id")}`,
2579
- placeholder: namespaceValue,
2580
- initialValue: namespaceValue,
2591
+ message: `${import_picocolors2.default.bold("Publisher ID")} ${import_picocolors2.default.dim(publisherHint)}`,
2592
+ placeholder: defaultPublisherId,
2593
+ initialValue: defaultPublisherId,
2581
2594
  validate(value) {
2582
2595
  const trimmed = (value ?? "").trim();
2583
2596
  if (trimmed.length === 0) {
@@ -2610,39 +2623,6 @@ async function runWizard() {
2610
2623
  }
2611
2624
  projectIdValue = projectId.trim();
2612
2625
  }
2613
- const destination = await Ot({
2614
- message: import_picocolors2.default.bold("Destination folder"),
2615
- placeholder: ".",
2616
- initialValue: ".",
2617
- validate(value) {
2618
- const trimmed = (value ?? "").trim();
2619
- if (trimmed.length === 0) {
2620
- return "Destination folder is required.";
2621
- }
2622
- if (/[<>"|?*]/.test(trimmed)) {
2623
- return 'Invalid characters in path (avoid < > " | ? *).';
2624
- }
2625
- if (trimmed.length > 200) {
2626
- return "Path is too long (max 200 characters).";
2627
- }
2628
- return;
2629
- }
2630
- });
2631
- if (q(destination)) {
2632
- return abortWizard();
2633
- }
2634
- const scripting = await _t({
2635
- message: import_picocolors2.default.bold("Scripting API"),
2636
- initialValue: "typescript",
2637
- options: [
2638
- { value: "none", label: "None", hint: "manifest-only addon scaffold" },
2639
- { value: "javascript", label: "JavaScript", hint: "script entry with JS tooling" },
2640
- { value: "typescript", label: "TypeScript", hint: "recommended" }
2641
- ]
2642
- });
2643
- if (q(scripting)) {
2644
- return abortWizard();
2645
- }
2646
2626
  let scriptPackages = { ...DEFAULT_SCRIPT_PACKAGES };
2647
2627
  let useRgl = false;
2648
2628
  if (scripting !== "none") {
@@ -2687,7 +2667,6 @@ async function runWizard() {
2687
2667
  const config = {
2688
2668
  projectName: trimmedProjectName,
2689
2669
  author: author.trim(),
2690
- namespace: namespaceValue,
2691
2670
  identifier: identifierValue,
2692
2671
  projectId: projectIdValue,
2693
2672
  destination: destination.trim(),
package/package.json CHANGED
@@ -1,55 +1,55 @@
1
- {
2
- "name": "spawnpack",
3
- "version": "0.1.2",
4
- "description": "Minecraft Bedrock addon project generator — scaffold your BP+RP in seconds",
5
- "author": "veedy-dev",
6
- "license": "MIT",
7
- "type": "module",
8
- "bin": {
9
- "spawnpack": "bin/spawnpack.js"
10
- },
11
- "files": [
12
- "bin/spawnpack.js",
13
- "dist/spawnpack.js",
14
- "templates/CLAUDE.md",
15
- "README.md",
16
- "LICENSE",
17
- "package.json"
18
- ],
19
- "repository": {
20
- "type": "git",
21
- "url": "git+https://github.com/veedy-dev/spawnpack.git"
22
- },
23
- "bugs": {
24
- "url": "https://github.com/veedy-dev/spawnpack/issues"
25
- },
26
- "homepage": "https://github.com/veedy-dev/spawnpack#readme",
27
- "keywords": [
28
- "minecraft",
29
- "bedrock",
30
- "addon",
31
- "generator",
32
- "cli",
33
- "spawnpack",
34
- "regolith",
35
- "rgl"
36
- ],
37
- "engines": {
38
- "bun": ">=1.2.0"
39
- },
40
- "scripts": {
41
- "start": "bun run src/index.ts",
42
- "dev": "bun --watch src/index.ts",
43
- "build": "bun build src/index.ts --outfile dist/spawnpack.js --target node",
44
- "typecheck": "tsc --noEmit",
45
- "prepack": "bun run typecheck && bun run build"
46
- },
47
- "dependencies": {
48
- "@clack/prompts": "^1.2.0",
49
- "picocolors": "^1.1.1"
50
- },
51
- "devDependencies": {
52
- "@types/bun": "^1.2.0",
53
- "typescript": "^5.7.0"
54
- }
55
- }
1
+ {
2
+ "name": "spawnpack",
3
+ "version": "0.1.4",
4
+ "description": "Minecraft Bedrock addon project generator — scaffold your BP+RP in seconds",
5
+ "author": "veedy-dev",
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "bin": {
9
+ "spawnpack": "bin/spawnpack.js"
10
+ },
11
+ "files": [
12
+ "bin/spawnpack.js",
13
+ "dist/spawnpack.js",
14
+ "templates/CLAUDE.md",
15
+ "README.md",
16
+ "LICENSE",
17
+ "package.json"
18
+ ],
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/veedy-dev/spawnpack.git"
22
+ },
23
+ "bugs": {
24
+ "url": "https://github.com/veedy-dev/spawnpack/issues"
25
+ },
26
+ "homepage": "https://github.com/veedy-dev/spawnpack#readme",
27
+ "keywords": [
28
+ "minecraft",
29
+ "bedrock",
30
+ "addon",
31
+ "generator",
32
+ "cli",
33
+ "spawnpack",
34
+ "regolith",
35
+ "rgl"
36
+ ],
37
+ "engines": {
38
+ "bun": ">=1.2.0"
39
+ },
40
+ "scripts": {
41
+ "start": "bun run src/index.ts",
42
+ "dev": "bun --watch src/index.ts",
43
+ "build": "bun build src/index.ts --outfile dist/spawnpack.js --target node",
44
+ "typecheck": "tsc --noEmit",
45
+ "prepack": "bun run typecheck && bun run build"
46
+ },
47
+ "dependencies": {
48
+ "@clack/prompts": "^1.2.0",
49
+ "picocolors": "^1.1.1"
50
+ },
51
+ "devDependencies": {
52
+ "@types/bun": "^1.2.0",
53
+ "typescript": "^5.7.0"
54
+ }
55
+ }