@percepta/create 3.0.1 → 3.1.2

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.
Files changed (47) hide show
  1. package/README.md +16 -9
  2. package/dist/{chunk-GEVZERMP.js → chunk-CG7IJSB4.js} +33 -2
  3. package/dist/{chunk-R4FWPE4A.js → chunk-DCM7JOSC.js} +2 -2
  4. package/dist/index.js +281 -82
  5. package/dist/{init-Z4VGBHAK.js → init-XDWSYHYK.js} +1 -1
  6. package/dist/{status-MITGDLTT.js → status-BTHGN6QH.js} +1 -1
  7. package/dist/{sync-J4SFZHDX.js → sync-3Q27L7XZ.js} +1 -1
  8. package/dist/{upstream-AQI7P4EU.js → upstream-C5KFAHVR.js} +1 -1
  9. package/package.json +3 -2
  10. package/templates/monorepo/gitignore.template +1 -0
  11. package/templates/webapp/.github/workflows/__APP_NAME__-ryvn-release.yaml +3 -2
  12. package/templates/webapp/AGENTS.md +8 -2
  13. package/templates/webapp/Dockerfile +0 -1
  14. package/templates/webapp/README.md +1 -0
  15. package/templates/webapp/agent-skills/database.md +1 -0
  16. package/templates/webapp/agent-skills/deploy.md +45 -32
  17. package/templates/webapp/agent-skills/oneshot.md +3 -3
  18. package/templates/webapp/deploy/README.md +32 -6
  19. package/templates/webapp/deploy/ryvn/__APP_NAME__.service.yaml +0 -2
  20. package/templates/webapp/deploy/ryvn/environments/percepta-test/installations/__APP_NAME__.env.percepta-test.serviceinstallation.yaml +28 -31
  21. package/templates/webapp/drizzle.config.ts +15 -6
  22. package/templates/webapp/env.example.template +1 -0
  23. package/templates/webapp/eslint.config.mjs +8 -0
  24. package/templates/webapp/gitignore.template +1 -0
  25. package/templates/webapp/package.json.template +6 -6
  26. package/templates/webapp/scripts/open-ryvn-deploy-pr.ts +495 -0
  27. package/templates/webapp/scripts/seed.ts +1 -1
  28. package/templates/webapp/scripts/setup-database.ts +16 -1
  29. package/templates/webapp/scripts/start.sh +3 -2
  30. package/templates/webapp/src/app/(app)/layout.tsx +1 -5
  31. package/templates/webapp/src/app/(auth)/auth/signin/CredentialsSignInForm.tsx +11 -1
  32. package/templates/webapp/src/app/(auth)/auth/signup/CredentialsSignUpForm.tsx +113 -0
  33. package/templates/webapp/src/app/(auth)/auth/signup/page.tsx +30 -0
  34. package/templates/webapp/src/app/global-error.tsx +3 -1
  35. package/templates/webapp/src/components/FaroProvider.tsx +2 -4
  36. package/templates/webapp/src/components/form/FormItem.tsx +2 -2
  37. package/templates/webapp/src/config/getEnvConfig.ts +1 -0
  38. package/templates/webapp/src/drizzle/db.ts +5 -1
  39. package/templates/webapp/src/drizzle/migrations/0000_eager_grandmaster.sql +3 -3
  40. package/templates/webapp/src/drizzle/migrations/meta/0000_snapshot.json +7 -19
  41. package/templates/webapp/src/drizzle/searchPath.test.ts +21 -0
  42. package/templates/webapp/src/drizzle/searchPath.ts +16 -0
  43. package/templates/webapp/src/drizzle/ssl.ts +5 -0
  44. package/templates/webapp/src/lib/auth/index.ts +1 -1
  45. package/templates/webapp/src/lib/auth-client.ts +1 -1
  46. package/templates/webapp/src/services/observability/initFaro.ts +1 -1
  47. package/templates/webapp/src/styles/globals.css +0 -7
package/README.md CHANGED
@@ -8,7 +8,7 @@ Scaffold and manage Mosaic packages.
8
8
  npx @percepta/create
9
9
  ```
10
10
 
11
- That's it. The CLI prompts you for the project name and (depending on context) whether it's a webapp. Defaults yield a running app — sign in as `admin@example.com` / `password`.
11
+ That's it. The CLI prompts you for the package type, repo name, and package name as needed. Defaults yield a running app — sign in as `admin@example.com` / `password`.
12
12
 
13
13
  ## Options (mostly for automation)
14
14
 
@@ -17,7 +17,9 @@ The bare command above is the canonical UX. The flags below exist for tests and
17
17
  | Option | Description |
18
18
  |--------|-------------|
19
19
  | `-t, --type <type>` | Package type: `monorepo`, `webapp`, or `library` (skips the type prompt) |
20
- | `--name <name>` | Project name (skips the name prompt) |
20
+ | `--name <name>` | Package/app name (skips the package name prompt) |
21
+ | `--repo-name <name>` | Repo name when creating a new monorepo (skips the repo name prompt) |
22
+ | `--cwd <dir>` | Run as if the CLI was started from `<dir>` |
21
23
  | `--skip-install` | Skip dependency installation, which also skips the auto-run setup + dev + browser, leaving you with manual next-steps |
22
24
  | `-y, --yes` | Skip all prompts; requires `--name` |
23
25
 
@@ -33,7 +35,7 @@ The bare command above is the canonical UX. The flags below exist for tests and
33
35
 
34
36
  `create` auto-detects whether you're inside an existing pnpm monorepo (by walking up for `pnpm-workspace.yaml`) and changes its prompts accordingly:
35
37
 
36
- - **Outside a monorepo** — pick `Monorepo` (default) or `Library`. If `Monorepo`, you're asked "Initialize with a webapp?" (Y/n, default Y). Picking the webapp option scaffolds a monorepo with a webapp inside `packages/<name>/`. Declining gives you an empty monorepo.
38
+ - **Outside a monorepo** — you're asked "Initialize with a webapp?" (Y/n, default Y), then for the repo name. Picking the webapp option also asks for the webapp name and scaffolds it inside `packages/<webapp-name>/`. Declining gives you an empty monorepo.
37
39
  - **Inside a monorepo** — pick `Webapp` (default) or `Library` to add a new package under the workspace pattern.
38
40
 
39
41
  ## Happy-path: zero-friction webapp
@@ -41,9 +43,10 @@ The bare command above is the canonical UX. The flags below exist for tests and
41
43
  When you scaffold a webapp (the default flow), `create` automatically runs:
42
44
 
43
45
  1. `pnpm install` (at the monorepo root)
44
- 2. `pnpm run setup` Docker Compose Postgres + Drizzle migrations + seed user
45
- 3. `pnpm dev` — Next.js dev server
46
- 4. Opens the served URL in your default browser
46
+ 2. `pnpm install --ignore-workspace` (inside the webapp package, to create the Docker build lockfile)
47
+ 3. `pnpm run setup` — Docker Compose Postgres + Drizzle migrations + seed user
48
+ 4. `pnpm dev` Next.js dev server
49
+ 5. Opens the served URL in your default browser
47
50
 
48
51
  Sign in as `admin@example.com` / `password` to start building.
49
52
 
@@ -74,9 +77,13 @@ pnpm build
74
77
  ### Testing locally
75
78
 
76
79
  ```bash
77
- pnpm build
78
- npm link
79
- create test-app
80
+ pnpm create:local --cwd /tmp --name test-app --yes --skip-install
81
+ ```
82
+
83
+ From the repo root, the same script can be run with a filter:
84
+
85
+ ```bash
86
+ pnpm --filter @percepta/create create:local --cwd /tmp --name test-app --yes --skip-install
80
87
  ```
81
88
 
82
89
  ### Syncing template files
@@ -77,17 +77,48 @@ async function promptInsideMonorepoType() {
77
77
  }
78
78
  async function promptProjectDetails(defaults) {
79
79
  const inMonorepo = defaults.monorepoContext?.found ?? false;
80
+ const cwd = defaults.cwd ?? process.cwd();
80
81
  let projectType;
81
82
  let finalName;
82
83
  if (inMonorepo) {
83
84
  projectType = defaults.projectType ?? await promptInsideMonorepoType();
85
+ await defaults.beforeNamePrompt?.(projectType);
84
86
  finalName = defaults.name || await promptName("Package name?");
85
87
  } else {
86
- finalName = defaults.name || await promptName("Project name?");
87
88
  projectType = defaults.projectType ?? await promptOutsideMonorepoType();
89
+ await defaults.beforeNamePrompt?.(projectType);
90
+ const repoName = defaults.repoName || (projectType === "monorepo" ? defaults.name : void 0) || await promptName("Repo name?");
91
+ const repoTitle = toTitleCase(repoName);
92
+ if (projectType === "monorepo") {
93
+ finalName = repoName;
94
+ const finalTitle3 = repoTitle;
95
+ const finalDirectory3 = path.resolve(cwd, repoName);
96
+ return {
97
+ projectType,
98
+ directory: finalDirectory3,
99
+ name: finalName,
100
+ title: finalTitle3,
101
+ installDeps: !defaults.skipInstall,
102
+ monorepoName: repoName,
103
+ monorepoTitle: repoTitle
104
+ };
105
+ }
106
+ const packageNamePrompt = projectType === "webapp" ? "Webapp name?" : "Library name?";
107
+ finalName = defaults.name || await promptName(packageNamePrompt);
108
+ const finalTitle2 = toTitleCase(finalName);
109
+ const finalDirectory2 = path.resolve(cwd, repoName);
110
+ return {
111
+ projectType,
112
+ directory: finalDirectory2,
113
+ name: finalName,
114
+ title: finalTitle2,
115
+ installDeps: !defaults.skipInstall,
116
+ monorepoName: repoName,
117
+ monorepoTitle: repoTitle
118
+ };
88
119
  }
89
120
  const finalTitle = finalName ? toTitleCase(finalName) : "";
90
- const finalDirectory = !inMonorepo && finalName ? path.resolve(process.cwd(), finalName) : "";
121
+ const finalDirectory = !inMonorepo && finalName ? path.resolve(cwd, finalName) : "";
91
122
  return {
92
123
  projectType,
93
124
  directory: finalDirectory,
@@ -11,14 +11,14 @@ function getLatestTemplateTag(type, repoPath) {
11
11
  { cwd: repoPath, encoding: "utf-8" }
12
12
  ).trim();
13
13
  if (!tags) return null;
14
- return tags.split("\n")[0];
14
+ return tags.split("\n")[0] ?? null;
15
15
  } catch {
16
16
  return null;
17
17
  }
18
18
  }
19
19
  function getTemplateVersionFromTag(tag) {
20
20
  const parts = tag.split("/");
21
- return parts[parts.length - 1];
21
+ return parts[parts.length - 1] ?? "";
22
22
  }
23
23
  function getTemplateDiff(repoPath, templatePath, fromTag, toTag) {
24
24
  return execFileSync(