@clubedge/create-clubedge-app 0.43.0 → 0.43.1

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/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  All notable changes to `create-clubedge-app` are documented here.
4
4
 
5
+ ## 0.43.1
6
+
7
+ - **`try` shows Railway's reason when Railway refuses a VM** (#144):
8
+ - Before, it said Railway may have changed its free VM and told you to update the CLI, which no update fixes.
9
+ - It now prints Railway's own explanation, then Railway's limits, the usual cause: 3 free VMs per network per day, and no anonymous VMs while Railway is busy.
10
+ - Still on Starter `v0.27.1`.
11
+
5
12
  ## 0.43.0
6
13
 
7
14
  - **Upgrades keep each app's own version** (#134, by @ahmed-husssain):
package/README.md CHANGED
@@ -381,7 +381,7 @@ Projects created with `--infra neon` also have `.github/workflows/preview.yml`,
381
381
  Each CLI release is tested against one specific Starter release:
382
382
 
383
383
  ```text
384
- create-clubedge-app v0.43.0
384
+ create-clubedge-app v0.43.1
385
385
  |
386
386
  v
387
387
  Clubedge Starter v0.27.1
@@ -392,7 +392,7 @@ The current relationship is:
392
392
 
393
393
  | CLI release | Default Starter release | Meaning |
394
394
  | --- | --- | --- |
395
- | `create-clubedge-app@0.43.0` | `clubedge-starter@v0.27.1` | The CLI's required, tested default |
395
+ | `create-clubedge-app@0.43.1` | `clubedge-starter@v0.27.1` | The CLI's required, tested default |
396
396
 
397
397
  This means the same CLI version always scaffolds the same Starter revision by default. The CLI does not silently follow Starter `main`.
398
398
 
@@ -31,11 +31,12 @@ export function hostKeyFingerprint(key) {
31
31
  }
32
32
  /**
33
33
  * Finds Railway's JSON status line in a command's stderr. Returns null when there is none, and
34
- * throws when there is one without the fields this CLI needs.
34
+ * throws when there is one without the fields this CLI needs, with Railway's reason when it
35
+ * refused the VM.
35
36
  */
36
37
  export function parseRailwayStatus(stderr) {
37
- for (const line of stderr.split(/\r?\n/)) {
38
- const trimmed = line.trim();
38
+ const lines = stderr.split(/\r?\n/).map((line) => line.trim());
39
+ for (const trimmed of lines) {
39
40
  if (!trimmed.startsWith("{"))
40
41
  continue;
41
42
  let value;
@@ -47,6 +48,8 @@ export function parseRailwayStatus(stderr) {
47
48
  }
48
49
  if (typeof value.status !== "string")
49
50
  continue;
51
+ if (value.status === "error")
52
+ throw new Error(railwayRefusal(value, lines));
50
53
  const previewUrl = value.preview_url;
51
54
  const claimUrl = value.human_claim_url;
52
55
  const expiresAt = new Date(String(value.build_expires_at));
@@ -57,6 +60,19 @@ export function parseRailwayStatus(stderr) {
57
60
  }
58
61
  return null;
59
62
  }
63
+ /**
64
+ * Why Railway refused a VM, in its own words: a message in its status line, else the text it
65
+ * wrote around that line, else the line itself. Its limits come after, since they are the usual
66
+ * cause.
67
+ */
68
+ function railwayRefusal(value, lines) {
69
+ const said = ["message", "error", "reason", "description", "detail"]
70
+ .map((key) => value[key])
71
+ .find((text) => typeof text === "string" && text.trim() !== "");
72
+ const around = lines.filter((line) => line && !line.startsWith("{")).join(" ");
73
+ const reason = (said?.trim() || around || `its answer was ${JSON.stringify(value)}`).slice(0, 500).replace(/\.$/, "");
74
+ return `Railway did not start a VM: ${reason}. Railway allows 3 free VMs per network per day and turns anonymous VMs off while it is busy, so try again later or from another network; see ${railwayFreeVmUrl}.`;
75
+ }
60
76
  /** Where the CLI keeps its own SSH key for Railway, apart from the user's ~/.ssh. */
61
77
  export function railwayKeyPath(env = process.env, platform = process.platform) {
62
78
  const configHome = env.XDG_CONFIG_HOME || (platform === "win32" && env.APPDATA ? env.APPDATA : join(homedir(), ".config"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clubedge/create-clubedge-app",
3
- "version": "0.43.0",
3
+ "version": "0.43.1",
4
4
  "description": "Create React apps from Clubedge Starter with a CLI or local MCP server.",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@10.9.0",