create-factory 0.1.0-alpha.5 → 0.1.0-alpha.7

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
@@ -1,5 +1,28 @@
1
1
  # create-factory
2
2
 
3
+ ## 0.1.0-alpha.7
4
+
5
+ ### Minor Changes
6
+
7
+ - Added EU and US region selection when creating Factory platform projects, with a --region flag for non-interactive setup. ([#20040](https://github.com/mastra-ai/mastra/pull/20040))
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated the generated project README for the single-server setup: the Factory UI and API are both served from `http://localhost:4111`, OAuth callback instructions use the server origin, and the removed `dev:prod` / `build:ui` scripts are no longer documented. ([#20036](https://github.com/mastra-ai/mastra/pull/20036))
12
+
13
+ - Stop shipping `pnpm-workspace.yaml` and `package-lock.json` in projects scaffolded by `npm create factory`. The template generator now excludes the web project's pnpm workspace marker and lockfiles, and the sync workflow validates the template in a throwaway copy so `npm install` artifacts can no longer leak into the published template repository. ([#20041](https://github.com/mastra-ai/mastra/pull/20041))
14
+
15
+ ## 0.1.0-alpha.6
16
+
17
+ ### Patch Changes
18
+
19
+ - Improved the create-factory sign-in and success experience: ([#20024](https://github.com/mastra-ai/mastra/pull/20024))
20
+
21
+ - When no Mastra platform session exists, the CLI now pauses with "Mastra account is required, press enter to continue..." before opening the browser auth flow instead of opening it unannounced.
22
+ - The success message now summarizes the infrastructure provisioned on Mastra platform (project, Postgres database, credentials in .env), notes that deployed code agent sessions run inside Mastra platform sandboxes, and links to https://projects.mastra.ai for managing the project.
23
+
24
+ - Fixed generated Factory projects to serve the UI and API from a single Mastra development server. ([#20019](https://github.com/mastra-ai/mastra/pull/20019))
25
+
3
26
  ## 0.1.0-alpha.5
4
27
 
5
28
  ### Patch Changes
package/README.md CHANGED
@@ -22,7 +22,7 @@ Options:
22
22
  --template <template-name> Create a project from a template (public GitHub URL) (default: "https://github.com/mastra-ai/softwarefactory-template")
23
23
  --no-platform Skip Mastra platform sign-in, project, and Neon provisioning
24
24
  --org <org> Mastra organization id or name — skips the interactive org picker
25
- --region <region> Neon region id (passed to the platform verbatim)
25
+ --region <region> Platform project region (eu or us); prompts when omitted
26
26
  -v, --version output the version number
27
27
  -h, --help display help for command
28
28
  ```
package/dist/index.js CHANGED
@@ -72,7 +72,7 @@ var Analytics = class {
72
72
  import fs3 from "fs";
73
73
  import path3 from "path";
74
74
  import * as p from "@clack/prompts";
75
- import { fetchOrgs, getToken, resolveCurrentOrg } from "mastra/internal/auth";
75
+ import { fetchOrgs, getToken, loadCredentials, resolveCurrentOrg } from "mastra/internal/auth";
76
76
  import color from "picocolors";
77
77
  import { x as x2 } from "tinyexec";
78
78
 
@@ -131,12 +131,13 @@ var PlatformApiError = class extends Error {
131
131
  async function createServerProject({
132
132
  token,
133
133
  orgId,
134
- name
134
+ name,
135
+ region
135
136
  }) {
136
137
  const res = await platformFetch(`${MASTRA_PLATFORM_API_URL}/v1/server/projects`, {
137
138
  method: "POST",
138
139
  headers: { ...authHeaders(token, orgId), "Content-Type": "application/json" },
139
- body: JSON.stringify({ name, factoryEnabled: true })
140
+ body: JSON.stringify({ name, region, factoryEnabled: true })
140
141
  });
141
142
  if (!res.ok) {
142
143
  throw new PlatformApiError(res.status, `Failed to create project \u2014 ${await extractError(res)}`);
@@ -172,7 +173,7 @@ async function attachNeonDatabase({
172
173
  {
173
174
  method: "POST",
174
175
  headers: { ...authHeaders(token, orgId), "Content-Type": "application/json" },
175
- body: JSON.stringify({ kind: "neon", name, ...regionId ? { regionId } : {} })
176
+ body: JSON.stringify({ kind: "neon", name, regionId })
176
177
  }
177
178
  );
178
179
  if (!res.ok) {
@@ -384,8 +385,21 @@ function getInstallArgs(packageManager) {
384
385
  }
385
386
 
386
387
  // src/create.ts
388
+ var PROJECT_REGION_OPTIONS = [
389
+ { value: "eu", label: "\u{1F1EA}\u{1F1FA} eu" },
390
+ { value: "us", label: "\u{1F1FA}\u{1F1F8} us" }
391
+ ];
392
+ var NEON_REGION_BY_PROJECT_REGION = {
393
+ eu: "aws-eu-central-1",
394
+ us: "aws-us-west-2"
395
+ };
396
+ function parseProjectRegion(region) {
397
+ if (region === "eu" || region === "us") return region;
398
+ throw new Error(`Invalid --region "${region}". Expected one of: eu, us.`);
399
+ }
387
400
  async function create(args) {
388
401
  p.intro(color.inverse(" Mastra Factory "));
402
+ const requestedRegion = args.region ? parseProjectRegion(args.region) : void 0;
389
403
  const projectName = args.projectName ?? await p.text({
390
404
  message: "What do you want to name your project?",
391
405
  placeholder: "my-mastra-factory",
@@ -443,7 +457,7 @@ You can retry manually: cd ${projectName} && ${packageManager} install`
443
457
  platformResult = await runPlatformProvisioning({
444
458
  projectName,
445
459
  projectPath,
446
- region: args.region,
460
+ region: requestedRegion,
447
461
  org: args.org
448
462
  });
449
463
  } catch (err) {
@@ -484,14 +498,17 @@ You can retry manually: cd ${projectName} && ${packageManager} install`
484
498
  `${color.cyan("cd")} ${projectName}`,
485
499
  color.cyan(`${packageManager} run dev`),
486
500
  "",
487
- `Factory UI ${color.underline("http://localhost:5173")}`,
488
- `Mastra Studio ${color.underline("http://localhost:4111")}`,
501
+ `Factory UI ${color.underline("http://localhost:4111")}`,
489
502
  ""
490
503
  ];
491
504
  if (platformResult) {
492
505
  lines.push(
493
- `${color.green("Platform connected.")} Project ${color.cyan(platformResult.project.name)} in ${color.cyan(platformResult.orgName)}.`,
494
- `Wrote ${color.cyan("MASTRA_PROJECT_ID")}, ${color.cyan("MASTRA_PLATFORM_SECRET_KEY")}, and ${color.cyan("DATABASE_URL")} to ${color.cyan(".env")}.`
506
+ `${color.green("Provisioned on Mastra platform")} in ${color.cyan(platformResult.orgName)}:`,
507
+ ` - Project ${color.cyan(platformResult.project.name)}`,
508
+ ` - Postgres database (credentials written to ${color.cyan(".env")})`,
509
+ "",
510
+ "When deployed, code agent sessions run inside Mastra platform sandboxes.",
511
+ `Manage your project at ${color.underline("https://projects.mastra.ai")}`
495
512
  );
496
513
  } else if (args.noPlatform) {
497
514
  lines.push(
@@ -522,16 +539,34 @@ async function runPlatformProvisioning({
522
539
  flushed = true;
523
540
  };
524
541
  try {
542
+ const willOpenAuthFlow = !process.env.MASTRA_API_TOKEN && !await loadCredentials();
543
+ if (willOpenAuthFlow) {
544
+ const proceed = await p.text({
545
+ message: "Mastra account is required, press enter to continue...",
546
+ defaultValue: ""
547
+ });
548
+ if (p.isCancel(proceed)) {
549
+ throw new Error("Sign-in cancelled.");
550
+ }
551
+ }
525
552
  p.log.info("Signing in to Mastra\u2026");
526
553
  const token = await getToken();
527
554
  const { orgId, orgName } = org ? await resolveOrgFromFlag(token, org) : await resolveCurrentOrg(token, { forcePrompt: true });
528
555
  p.log.info(`Using organization ${color.cyan(orgName)}.`);
529
556
  envAccumulator.MASTRA_ORGANIZATION_ID = orgId;
557
+ const projectRegion = region ?? await p.select({
558
+ message: "Where should your Factory project run?",
559
+ options: [...PROJECT_REGION_OPTIONS]
560
+ });
561
+ if (p.isCancel(projectRegion)) {
562
+ p.cancel("Operation cancelled");
563
+ process.exit(0);
564
+ }
530
565
  const projectSpinner = p.spinner();
531
566
  projectSpinner.start(`Creating platform project "${projectName}"\u2026`);
532
567
  let project;
533
568
  try {
534
- project = await createServerProject({ token, orgId, name: projectName });
569
+ project = await createServerProject({ token, orgId, name: projectName, region: projectRegion });
535
570
  projectSpinner.stop(`Created platform project ${color.cyan(project.slug)}.`);
536
571
  } catch (err) {
537
572
  projectSpinner.stop("Project creation failed.");
@@ -562,7 +597,7 @@ async function runPlatformProvisioning({
562
597
  orgId,
563
598
  projectId: project.id,
564
599
  name: sanitizeDatabaseName(projectName),
565
- regionId: region
600
+ regionId: NEON_REGION_BY_PROJECT_REGION[projectRegion]
566
601
  });
567
602
  const ready = await waitForDatabaseReady({
568
603
  token,
@@ -633,7 +668,7 @@ var pkg = JSON.parse(
633
668
  var analytics = new Analytics(pkg.version);
634
669
  var program = new Command();
635
670
  var DEFAULT_TEMPLATE_REPO = "https://github.com/mastra-ai/softwarefactory-template";
636
- program.name("create-factory").description("Create a new Mastra Factory project").argument("[project-name]", "Directory name of the project").option("--template <template-name>", "Create a project from a template (public GitHub URL)", DEFAULT_TEMPLATE_REPO).option("--no-platform", "Skip Mastra platform sign-in, project, and Neon provisioning").option("--org <org>", "Mastra organization id or name \u2014 skips the interactive org picker").option("--region <region>", "Neon region id (passed to the platform verbatim)").version(pkg.version, "-v, --version").action(async (projectNameArg, args) => {
671
+ program.name("create-factory").description("Create a new Mastra Factory project").argument("[project-name]", "Directory name of the project").option("--template <template-name>", "Create a project from a template (public GitHub URL)", DEFAULT_TEMPLATE_REPO).option("--no-platform", "Skip Mastra platform sign-in, project, and Neon provisioning").option("--org <org>", "Mastra organization id or name \u2014 skips the interactive org picker").option("--region <region>", "Platform project region (eu or us); prompts when omitted").version(pkg.version, "-v, --version").action(async (projectNameArg, args) => {
637
672
  await create({
638
673
  projectName: projectNameArg,
639
674
  template: args.template,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-factory",
3
- "version": "0.1.0-alpha.5",
3
+ "version": "0.1.0-alpha.7",
4
4
  "description": "Create a Mastra Factory project: an agent-powered software delivery environment built on Mastra. Run `npm create factory` to scaffold and get started.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",