ai-forge-cli 0.4.6 → 0.4.9

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.
@@ -17,7 +17,7 @@ import { join } from "path";
17
17
  var add_component_default = defineCommand({
18
18
  meta: {
19
19
  name: "add:component",
20
- description: "Create a new React component"
20
+ description: "Create a React component. Creates: <target>/<Name>.tsx, updates index.ts. Default: src/components/ui/. Use --feature, --page, or --layout to target specific folders."
21
21
  },
22
22
  args: {
23
23
  name: {
@@ -24,7 +24,7 @@ import { join } from "path";
24
24
  var add_feature_default = defineCommand({
25
25
  meta: {
26
26
  name: "add:feature",
27
- description: "Create a new feature with vertical slice architecture"
27
+ description: "Create a full-stack feature. Creates: convex/features/<name>/ (schema, queries, mutations), src/features/<name>/ (hooks, components), src/routes/<name>/ (index, $id). Use for data-driven features with backend."
28
28
  },
29
29
  args: {
30
30
  name: {
@@ -17,7 +17,7 @@ import { join } from "path";
17
17
  var add_hook_default = defineCommand({
18
18
  meta: {
19
19
  name: "add:hook",
20
- description: "Create a new React hook"
20
+ description: "Create a React hook. Without --feature: creates src/hooks/<useName>.ts. With --feature: appends to src/features/<name>/hooks.ts. Auto-prefixes 'use' if needed."
21
21
  },
22
22
  args: {
23
23
  name: {
@@ -34,7 +34,7 @@ function runCommand(cmd, args, cwd) {
34
34
  var add_integration_default = defineCommand({
35
35
  meta: {
36
36
  name: "add:integration",
37
- description: "Add an infrastructure integration (auth, storage)"
37
+ description: "Add infrastructure. auth: creates convex/auth.ts, convex/users.ts, src/lib/auth.ts (useCurrentUser), components, routes. storage: creates convex/lib/storage.ts, src/components/storage/."
38
38
  },
39
39
  args: {
40
40
  name: {
@@ -69,7 +69,7 @@ async function setupAuth(cwd) {
69
69
  logger.blank();
70
70
  const step1 = logger.step("Installing dependencies...");
71
71
  try {
72
- await runCommand("pnpm", ["add", "@convex-dev/auth", "@auth/core"], cwd);
72
+ await runCommand("pnpm", ["add", "@convex-dev/auth", "@auth/core@^0.37.0"], cwd);
73
73
  step1.succeed("Dependencies installed");
74
74
  } catch {
75
75
  step1.fail("Failed to install dependencies");
@@ -82,6 +82,7 @@ async function setupAuth(cwd) {
82
82
  { template: "integration/auth/convex/auth.ts.hbs", dest: "convex/auth.ts" },
83
83
  { template: "integration/auth/convex/auth.config.ts.hbs", dest: "convex/auth.config.ts" },
84
84
  { template: "integration/auth/convex/http.ts.hbs", dest: "convex/http.ts" },
85
+ { template: "integration/auth/convex/users.ts.hbs", dest: "convex/users.ts" },
85
86
  { template: "integration/auth/src/lib/auth.ts.hbs", dest: "src/lib/auth.ts" }
86
87
  ];
87
88
  for (const file of backendFiles) {
@@ -162,18 +163,20 @@ AUTH_GOOGLE_SECRET=
162
163
  logger.log(` ${pc.green("\u2713")} ${pc.bold("Convex Auth configured!")}`);
163
164
  logger.blank();
164
165
  logger.log(" Created:");
165
- logger.log(" Backend: convex/auth.ts, convex/auth.config.ts");
166
+ logger.log(" Backend: convex/auth.ts, convex/users.ts");
167
+ logger.log(" Hooks: useAuth(), useCurrentUser()");
166
168
  logger.log(" Components: LoginForm, SignupForm, AuthGuard, UserMenu");
167
169
  logger.log(" Routes: /login, /signup");
168
170
  logger.blank();
169
171
  logger.log(" Next steps:");
170
- logger.log(" 1. Set up auth secrets: npx @convex-dev/auth");
171
- logger.log(" 2. Run: npx convex dev");
172
- logger.log(" 3. Visit: http://localhost:3000/login");
172
+ logger.log(" 1. Run: npx convex dev");
173
+ logger.log(" 2. Visit: http://localhost:3000/login");
173
174
  logger.blank();
174
175
  logger.log(" Usage:");
175
- logger.log(" - Protect routes: <AuthGuard><YourComponent /></AuthGuard>");
176
- logger.log(" - Add to header: <UserMenu />");
176
+ logger.log(' import { useCurrentUser, AuthGuard } from "~/lib/auth";');
177
+ logger.log(" const user = useCurrentUser(); // Get logged-in user");
178
+ logger.log(" <AuthGuard>...</AuthGuard> // Protect routes");
179
+ logger.log(" <UserMenu /> // Add to header");
177
180
  logger.blank();
178
181
  }
179
182
  async function setupStorage(cwd) {
@@ -20,7 +20,7 @@ var LAYOUT_PRESETS = ["dashboard", "auth", "marketing"];
20
20
  var add_layout_default = defineCommand({
21
21
  meta: {
22
22
  name: "add:layout",
23
- description: "Create a layout (dashboard, auth, marketing, or custom)"
23
+ description: "Create a layout wrapper for grouped routes. Creates: src/routes/<name>/_layout.tsx, index.tsx. Dashboard preset adds Sidebar/Header in src/components/layout/. Use for shared navigation."
24
24
  },
25
25
  args: {
26
26
  name: {
@@ -17,7 +17,7 @@ import { join } from "path";
17
17
  var add_page_default = defineCommand({
18
18
  meta: {
19
19
  name: "add:page",
20
- description: "Create a non-feature page (about, pricing, settings)"
20
+ description: "Create a standalone page without backend. Creates: src/routes/<name>.tsx, src/components/<name>/<Name>Content.tsx. Use for static pages like about, pricing, settings."
21
21
  },
22
22
  args: {
23
23
  name: {
@@ -17,7 +17,7 @@ import { join } from "path";
17
17
  var add_util_default = defineCommand({
18
18
  meta: {
19
19
  name: "add:util",
20
- description: "Create a new utility function in src/lib"
20
+ description: "Create a utility function. Creates: src/lib/<name>.ts, updates src/lib/index.ts. Use for shared helpers like formatDate, cn, validators."
21
21
  },
22
22
  args: {
23
23
  name: {
@@ -107,7 +107,16 @@ var componentSubdirValidator = {
107
107
  const subdirs = await fg2("src/components/*/", {
108
108
  cwd,
109
109
  onlyDirectories: true,
110
- ignore: ["src/components/ui"]
110
+ ignore: [
111
+ "src/components/ui",
112
+ // shadcn primitives
113
+ "src/components/auth",
114
+ // Created by forge add:integration auth
115
+ "src/components/storage",
116
+ // Created by forge add:integration storage
117
+ "src/components/layout"
118
+ // Created by forge add:layout
119
+ ]
111
120
  });
112
121
  for (const dir of subdirs) {
113
122
  warnings.push({
@@ -134,6 +143,8 @@ var hookLocationValidator = {
134
143
  ignore: [
135
144
  "node_modules/**",
136
145
  "dist/**",
146
+ "convex/**",
147
+ // Convex backend files are not React hooks
137
148
  "src/features/*/hooks.ts",
138
149
  // Valid location
139
150
  "src/hooks/**",
package/dist/index.js CHANGED
@@ -20,14 +20,14 @@ var main = defineCommand({
20
20
  },
21
21
  subCommands: {
22
22
  init: () => import("./init-C4FFZDSP.js").then((m) => m.default),
23
- "add:feature": () => import("./add-feature-VEY62Y5M.js").then((m) => m.default),
24
- "add:integration": () => import("./add-integration-NJ56UXSY.js").then((m) => m.default),
25
- "add:page": () => import("./add-page-GIC2ZXJI.js").then((m) => m.default),
26
- "add:layout": () => import("./add-layout-2KQPPTJX.js").then((m) => m.default),
27
- "add:component": () => import("./add-component-AQPCXQ4O.js").then((m) => m.default),
28
- "add:hook": () => import("./add-hook-OE4BKE6B.js").then((m) => m.default),
29
- "add:util": () => import("./add-util-T5JXAV4G.js").then((m) => m.default),
30
- check: () => import("./check-YMGJNKME.js").then((m) => m.default),
23
+ "add:feature": () => import("./add-feature-TYLPV3DB.js").then((m) => m.default),
24
+ "add:integration": () => import("./add-integration-FPTS7CM3.js").then((m) => m.default),
25
+ "add:page": () => import("./add-page-G75JUU77.js").then((m) => m.default),
26
+ "add:layout": () => import("./add-layout-IVTJUG6G.js").then((m) => m.default),
27
+ "add:component": () => import("./add-component-B3O3RZWD.js").then((m) => m.default),
28
+ "add:hook": () => import("./add-hook-VJC6P6AP.js").then((m) => m.default),
29
+ "add:util": () => import("./add-util-V5SQRVJC.js").then((m) => m.default),
30
+ check: () => import("./check-SD5NBZ26.js").then((m) => m.default),
31
31
  version: () => import("./version-VO3LHLDO.js").then((m) => m.default)
32
32
  },
33
33
  run({ args }) {
@@ -1,7 +1,13 @@
1
+ import { Password } from "@convex-dev/auth/providers/Password";
1
2
  import GitHub from "@auth/core/providers/github";
2
3
  import Google from "@auth/core/providers/google";
3
4
  import { convexAuth } from "@convex-dev/auth/server";
4
5
 
5
6
  export const { auth, signIn, signOut, store, isAuthenticated } = convexAuth({
6
- providers: [GitHub, Google],
7
+ providers: [
8
+ Password,
9
+ // Uncomment to enable OAuth (requires env vars):
10
+ // GitHub,
11
+ // Google,
12
+ ],
7
13
  });
@@ -0,0 +1,11 @@
1
+ import { query } from "./_generated/server";
2
+ import { getAuthUserId } from "@convex-dev/auth/server";
3
+
4
+ export const currentUser = query({
5
+ args: {},
6
+ handler: async (ctx) => {
7
+ const userId = await getAuthUserId(ctx);
8
+ if (!userId) return null;
9
+ return await ctx.db.get(userId);
10
+ },
11
+ });
@@ -1,4 +1,5 @@
1
- import { useConvexAuth } from "convex/react";
1
+ import { useConvexAuth, useQuery } from "convex/react";
2
+ import { api } from "convex/_generated/api";
2
3
 
3
4
  /**
4
5
  * Hook to get authentication state
@@ -8,6 +9,13 @@ export function useAuth() {
8
9
  return { isAuthenticated, isLoading };
9
10
  }
10
11
 
12
+ /**
13
+ * Hook to get the current user's data
14
+ */
15
+ export function useCurrentUser() {
16
+ return useQuery(api.users.currentUser);
17
+ }
18
+
11
19
  /**
12
20
  * Re-export auth components for convenience
13
21
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-forge-cli",
3
- "version": "0.4.6",
3
+ "version": "0.4.9",
4
4
  "description": "TypeScript stack scaffolding & enforcement CLI for TanStack Start + Convex",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1,7 +1,13 @@
1
+ import { Password } from "@convex-dev/auth/providers/Password";
1
2
  import GitHub from "@auth/core/providers/github";
2
3
  import Google from "@auth/core/providers/google";
3
4
  import { convexAuth } from "@convex-dev/auth/server";
4
5
 
5
6
  export const { auth, signIn, signOut, store, isAuthenticated } = convexAuth({
6
- providers: [GitHub, Google],
7
+ providers: [
8
+ Password,
9
+ // Uncomment to enable OAuth (requires env vars):
10
+ // GitHub,
11
+ // Google,
12
+ ],
7
13
  });
@@ -0,0 +1,11 @@
1
+ import { query } from "./_generated/server";
2
+ import { getAuthUserId } from "@convex-dev/auth/server";
3
+
4
+ export const currentUser = query({
5
+ args: {},
6
+ handler: async (ctx) => {
7
+ const userId = await getAuthUserId(ctx);
8
+ if (!userId) return null;
9
+ return await ctx.db.get(userId);
10
+ },
11
+ });
@@ -1,4 +1,5 @@
1
- import { useConvexAuth } from "convex/react";
1
+ import { useConvexAuth, useQuery } from "convex/react";
2
+ import { api } from "convex/_generated/api";
2
3
 
3
4
  /**
4
5
  * Hook to get authentication state
@@ -8,6 +9,13 @@ export function useAuth() {
8
9
  return { isAuthenticated, isLoading };
9
10
  }
10
11
 
12
+ /**
13
+ * Hook to get the current user's data
14
+ */
15
+ export function useCurrentUser() {
16
+ return useQuery(api.users.currentUser);
17
+ }
18
+
11
19
  /**
12
20
  * Re-export auth components for convenience
13
21
  */