@beignet/cli 0.0.40 → 0.0.42
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 +19 -0
- package/README.md +139 -17
- package/dist/analysis/source-index.d.ts +38 -0
- package/dist/analysis/source-index.d.ts.map +1 -0
- package/dist/analysis/source-index.js +271 -0
- package/dist/analysis/source-index.js.map +1 -0
- package/dist/analysis/workspace.d.ts +16 -0
- package/dist/analysis/workspace.d.ts.map +1 -0
- package/dist/analysis/workspace.js +134 -0
- package/dist/analysis/workspace.js.map +1 -0
- package/dist/app-map-schema.d.ts +5 -0
- package/dist/app-map-schema.d.ts.map +1 -0
- package/dist/app-map-schema.js +26 -0
- package/dist/app-map-schema.js.map +1 -0
- package/dist/app-map.d.ts +96 -0
- package/dist/app-map.d.ts.map +1 -0
- package/dist/app-map.js +1141 -0
- package/dist/app-map.js.map +1 -0
- package/dist/check.d.ts +7 -0
- package/dist/check.d.ts.map +1 -1
- package/dist/check.js +20 -5
- package/dist/check.js.map +1 -1
- package/dist/choices.d.ts +18 -0
- package/dist/choices.d.ts.map +1 -1
- package/dist/choices.js +35 -0
- package/dist/choices.js.map +1 -1
- package/dist/db.d.ts +49 -13
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +202 -21
- package/dist/db.js.map +1 -1
- package/dist/doctor-fixes.d.ts +64 -0
- package/dist/doctor-fixes.d.ts.map +1 -0
- package/dist/doctor-fixes.js +142 -0
- package/dist/doctor-fixes.js.map +1 -0
- package/dist/explain.d.ts +100 -0
- package/dist/explain.d.ts.map +1 -0
- package/dist/explain.js +606 -0
- package/dist/explain.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +165 -21
- package/dist/index.js.map +1 -1
- package/dist/inspect.d.ts +33 -9
- package/dist/inspect.d.ts.map +1 -1
- package/dist/inspect.js +406 -119
- package/dist/inspect.js.map +1 -1
- package/dist/lib.d.ts +10 -2
- package/dist/lib.d.ts.map +1 -1
- package/dist/lib.js +5 -2
- package/dist/lib.js.map +1 -1
- package/dist/make/shared.js +3 -3
- package/dist/make/shared.js.map +1 -1
- package/dist/make.d.ts.map +1 -1
- package/dist/make.js +63 -2
- package/dist/make.js.map +1 -1
- package/dist/mcp.d.ts +1 -1
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +188 -12
- package/dist/mcp.js.map +1 -1
- package/dist/preflight.d.ts.map +1 -1
- package/dist/preflight.js +10 -0
- package/dist/preflight.js.map +1 -1
- package/dist/provider-add.d.ts.map +1 -1
- package/dist/provider-add.js +167 -13
- package/dist/provider-add.js.map +1 -1
- package/dist/provider-audit.d.ts +6 -0
- package/dist/provider-audit.d.ts.map +1 -1
- package/dist/provider-audit.js +63 -15
- package/dist/provider-audit.js.map +1 -1
- package/dist/templates/agents.d.ts.map +1 -1
- package/dist/templates/agents.js +35 -6
- package/dist/templates/agents.js.map +1 -1
- package/dist/templates/base.d.ts.map +1 -1
- package/dist/templates/base.js +13 -7
- package/dist/templates/base.js.map +1 -1
- package/dist/templates/index.d.ts +1 -1
- package/dist/templates/index.d.ts.map +1 -1
- package/dist/templates/index.js +8 -1
- package/dist/templates/index.js.map +1 -1
- package/dist/templates/server.d.ts +3 -0
- package/dist/templates/server.d.ts.map +1 -1
- package/dist/templates/server.js +55 -1
- package/dist/templates/server.js.map +1 -1
- package/dist/templates/shared.d.ts +2 -1
- package/dist/templates/shared.d.ts.map +1 -1
- package/dist/templates/shared.js +8 -5
- package/dist/templates/shared.js.map +1 -1
- package/package.json +3 -2
- package/skills/app-structure/SKILL.md +48 -6
- package/src/analysis/source-index.ts +395 -0
- package/src/analysis/workspace.ts +180 -0
- package/src/app-map-schema.ts +28 -0
- package/src/app-map.ts +1705 -0
- package/src/check.ts +27 -4
- package/src/choices.ts +57 -0
- package/src/db.ts +276 -28
- package/src/doctor-fixes.ts +252 -0
- package/src/explain.ts +894 -0
- package/src/index.ts +237 -31
- package/src/inspect.ts +567 -147
- package/src/lib.ts +64 -1
- package/src/make/shared.ts +3 -3
- package/src/make.ts +90 -2
- package/src/mcp.ts +292 -12
- package/src/preflight.ts +14 -0
- package/src/provider-add.ts +211 -12
- package/src/provider-audit.ts +127 -22
- package/src/templates/agents.ts +35 -6
- package/src/templates/base.ts +25 -6
- package/src/templates/index.ts +18 -1
- package/src/templates/server.ts +58 -1
- package/src/templates/shared.ts +15 -7
package/src/templates/base.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { databaseLocalUrl, databaseStartCommand } from "../choices.js";
|
|
2
2
|
import { shadcnDependencies, shadcnDevDependencies } from "./shadcn.js";
|
|
3
3
|
import {
|
|
4
|
+
currentGeneratedPackageScripts,
|
|
4
5
|
externalVersions,
|
|
5
6
|
hasStarterProvider,
|
|
6
7
|
json,
|
|
@@ -97,11 +98,11 @@ export function packageJson(ctx: TemplateContext): string {
|
|
|
97
98
|
start: "next start",
|
|
98
99
|
lint: "biome lint .",
|
|
99
100
|
format: "biome format --write .",
|
|
100
|
-
test:
|
|
101
|
+
test: currentGeneratedPackageScripts.test,
|
|
101
102
|
typecheck: "tsc --noEmit",
|
|
102
103
|
"db:generate": "drizzle-kit generate",
|
|
103
104
|
"db:migrate": "drizzle-kit migrate",
|
|
104
|
-
"db:reset": "
|
|
105
|
+
"db:reset": currentGeneratedPackageScripts["db:reset"],
|
|
105
106
|
};
|
|
106
107
|
|
|
107
108
|
return json({
|
|
@@ -268,11 +269,13 @@ ${firstOpen}
|
|
|
268
269
|
\`\`\`bash
|
|
269
270
|
# in another terminal
|
|
270
271
|
${cli} routes
|
|
272
|
+
${cli} map
|
|
271
273
|
${cli} check
|
|
272
274
|
\`\`\`
|
|
273
275
|
|
|
274
|
-
\`routes\` shows the contracts Beignet can inspect. \`
|
|
275
|
-
|
|
276
|
+
\`routes\` shows the contracts Beignet can inspect. \`map\` shows how features,
|
|
277
|
+
use cases, workflows, ports, providers, and tests connect. \`check\` runs the
|
|
278
|
+
whole validation loop in one pass: \`${cli} lint\` (dependency direction),
|
|
276
279
|
\`${cli} doctor --strict\` (route, OpenAPI, and resource drift), and the
|
|
277
280
|
\`lint\`, \`typecheck\`, and \`test\` package scripts. Use \`${format}\` to
|
|
278
281
|
apply Biome formatting.
|
|
@@ -306,6 +309,10 @@ Use \`${cli} make feature projects --recipe full-slice\` when you want a richer
|
|
|
306
309
|
|
|
307
310
|
## App map
|
|
308
311
|
|
|
312
|
+
Run \`${cli} map\` for the current architecture or \`${cli} map --json\` for
|
|
313
|
+
the versioned graph used by coding agents. Add \`--feature todos\` to focus on
|
|
314
|
+
one slice and its direct relationships.
|
|
315
|
+
|
|
309
316
|
- \`features/todos/contracts.ts\` owns the HTTP contract and reuses shared feature schemas.
|
|
310
317
|
- \`features/todos/schemas.ts\` owns shared DTO and validation schemas used by contracts, use cases, ports, tests, and clients.
|
|
311
318
|
- \`features/todos/client/\` may own todos-specific data-fetching helpers and React Query hooks.
|
|
@@ -391,8 +398,10 @@ export function providersDoc(ctx: TemplateContext): string {
|
|
|
391
398
|
"- Package: `@beignet/core` (`@beignet/core/events`, `@beignet/core/jobs`)",
|
|
392
399
|
"- Package: `@beignet/provider-jobs-inngest`",
|
|
393
400
|
"- Peer dependency: `inngest`",
|
|
394
|
-
"- The starter
|
|
401
|
+
"- The starter shares one Inngest client between `createInngestJobsProvider(...)` and `app/api/inngest/route.ts`.",
|
|
395
402
|
"- Define jobs with `defineJob(...)` and dispatch them through `ctx.ports.jobs.dispatch(...)`.",
|
|
403
|
+
"- `beignet make job` registers feature job collections in `server/inngest.ts`.",
|
|
404
|
+
"- Use `INNGEST_DEV=1` only locally; production needs `INNGEST_EVENT_KEY` and `INNGEST_SIGNING_KEY`.",
|
|
396
405
|
"- Use `ctx.ports.inngest` only as an escape hatch for Inngest-specific workflow APIs; prefer `ctx.ports.jobs.dispatch(...)` for Beignet jobs.",
|
|
397
406
|
"",
|
|
398
407
|
);
|
|
@@ -471,7 +480,17 @@ export function envExample(ctx: TemplateContext): string {
|
|
|
471
480
|
];
|
|
472
481
|
|
|
473
482
|
if (hasStarterProvider(ctx, "jobs-inngest")) {
|
|
474
|
-
lines.push(
|
|
483
|
+
lines.push(
|
|
484
|
+
"# Local development connects the app to the Inngest dev server.",
|
|
485
|
+
"INNGEST_APP_NAME=beignet-app",
|
|
486
|
+
"INNGEST_DEV=1",
|
|
487
|
+
"# Production cloud dispatch and endpoint verification.",
|
|
488
|
+
"# INNGEST_EVENT_KEY=",
|
|
489
|
+
"# INNGEST_SIGNING_KEY=",
|
|
490
|
+
"# Optional signing-key rotation fallback.",
|
|
491
|
+
"# INNGEST_SIGNING_KEY_FALLBACK=",
|
|
492
|
+
"",
|
|
493
|
+
);
|
|
475
494
|
}
|
|
476
495
|
|
|
477
496
|
if (hasStarterProvider(ctx, "mail-resend")) {
|
package/src/templates/index.ts
CHANGED
|
@@ -19,6 +19,8 @@ import { dbFiles } from "./db/index.js";
|
|
|
19
19
|
import {
|
|
20
20
|
betterAuth,
|
|
21
21
|
env,
|
|
22
|
+
inngestClient,
|
|
23
|
+
inngestRegistry,
|
|
22
24
|
ports,
|
|
23
25
|
portWiring,
|
|
24
26
|
server,
|
|
@@ -26,7 +28,11 @@ import {
|
|
|
26
28
|
serverProviders,
|
|
27
29
|
} from "./server.js";
|
|
28
30
|
import { shadcnTemplateFiles } from "./shadcn.js";
|
|
29
|
-
import
|
|
31
|
+
import {
|
|
32
|
+
hasStarterProvider,
|
|
33
|
+
type TemplateContext,
|
|
34
|
+
type TemplateFile,
|
|
35
|
+
} from "./shared.js";
|
|
30
36
|
import { shellTemplateFiles } from "./shell.js";
|
|
31
37
|
import { testSupportTemplateFiles } from "./testing.js";
|
|
32
38
|
import { todosFiles } from "./todos.js";
|
|
@@ -144,6 +150,17 @@ export function getTemplateFiles(ctx: TemplateContext): TemplateFile[] {
|
|
|
144
150
|
{ path: "server/providers.ts", content: serverProviders(ctx) },
|
|
145
151
|
];
|
|
146
152
|
|
|
153
|
+
if (hasStarterProvider(ctx, "jobs-inngest")) {
|
|
154
|
+
templateFiles.push(
|
|
155
|
+
{ path: "infra/inngest.ts", content: inngestClient() },
|
|
156
|
+
{ path: "server/inngest.ts", content: inngestRegistry() },
|
|
157
|
+
{
|
|
158
|
+
path: "app/api/inngest/route.ts",
|
|
159
|
+
content: serverFiles.inngestRoute,
|
|
160
|
+
},
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
|
|
147
164
|
if (ctx.api) {
|
|
148
165
|
templateFiles.push(
|
|
149
166
|
{ path: "app/layout.tsx", content: serverFiles.apiLayout },
|
package/src/templates/server.ts
CHANGED
|
@@ -24,6 +24,9 @@ export function serverProviders(ctx: TemplateContext): string {
|
|
|
24
24
|
: undefined,
|
|
25
25
|
'import * as schema from "@/infra/db/schema";',
|
|
26
26
|
'import { databaseClient } from "@/infra/db/client";',
|
|
27
|
+
hasStarterProvider(ctx, "jobs-inngest")
|
|
28
|
+
? 'import { inngest } from "@/infra/inngest";'
|
|
29
|
+
: undefined,
|
|
27
30
|
'import { starterDatabaseProvider } from "@/infra/db/provider";',
|
|
28
31
|
'import { auth } from "@/lib/better-auth";',
|
|
29
32
|
'import type { AuthSessionMetadata, AuthUser } from "@/ports/auth";',
|
|
@@ -36,7 +39,7 @@ export function serverProviders(ctx: TemplateContext): string {
|
|
|
36
39
|
`\t${db.providerInstance},`,
|
|
37
40
|
"\tstarterDatabaseProvider,",
|
|
38
41
|
hasStarterProvider(ctx, "jobs-inngest")
|
|
39
|
-
? "\tcreateInngestJobsProvider(),"
|
|
42
|
+
? "\tcreateInngestJobsProvider({ client: inngest }),"
|
|
40
43
|
: undefined,
|
|
41
44
|
hasStarterProvider(ctx, "mail-resend")
|
|
42
45
|
? "\tcreateResendMailProvider(),"
|
|
@@ -162,6 +165,14 @@ export function env(ctx: TemplateContext): string {
|
|
|
162
165
|
\t\t\t.default("${databaseLocalUrl(ctx.database, ctx.name)}"),
|
|
163
166
|
\t\t${ctx.database === "postgres" ? "POSTGRES" : "MYSQL"}_DB_POOL_MAX: z.coerce.number().int().positive().default(5),`;
|
|
164
167
|
|
|
168
|
+
const inngestEnvLines = hasStarterProvider(ctx, "jobs-inngest")
|
|
169
|
+
? `\t\tINNGEST_APP_NAME: z.string().min(1).default("beignet-app"),
|
|
170
|
+
\t\tINNGEST_DEV: z.enum(["0", "1"]).optional(),
|
|
171
|
+
\t\tINNGEST_EVENT_KEY: z.string().min(1).optional(),
|
|
172
|
+
\t\tINNGEST_SIGNING_KEY: z.string().min(1).optional(),
|
|
173
|
+
\t\tINNGEST_SIGNING_KEY_FALLBACK: z.string().min(1).optional(),`
|
|
174
|
+
: "";
|
|
175
|
+
|
|
165
176
|
return `import { createEnv } from "@beignet/core/config";
|
|
166
177
|
import { z } from "zod";
|
|
167
178
|
|
|
@@ -198,6 +209,7 @@ ${databaseEnvLines}
|
|
|
198
209
|
.default("info"),
|
|
199
210
|
LOG_FORMAT: z.enum(["pretty", "json"]).default("json"),
|
|
200
211
|
LOG_SERVICE: z.string().default("beignet-app"),
|
|
212
|
+
${inngestEnvLines}
|
|
201
213
|
},
|
|
202
214
|
runtimeEnv: process.env,
|
|
203
215
|
});
|
|
@@ -209,6 +221,42 @@ export const isDevtoolsEnabled =
|
|
|
209
221
|
`;
|
|
210
222
|
}
|
|
211
223
|
|
|
224
|
+
export function inngestClient(): string {
|
|
225
|
+
return `import { Inngest } from "inngest";
|
|
226
|
+
import { env } from "@/lib/env";
|
|
227
|
+
|
|
228
|
+
/** Shared by the Beignet jobs provider and the Inngest serve endpoint. */
|
|
229
|
+
export const inngest = new Inngest({
|
|
230
|
+
id: env.INNGEST_APP_NAME,
|
|
231
|
+
});
|
|
232
|
+
`;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export function inngestRegistry(): string {
|
|
236
|
+
return `import { createServiceActor } from "@beignet/core/ports";
|
|
237
|
+
import { createInngestJobFunctions } from "@beignet/provider-jobs-inngest";
|
|
238
|
+
import type { AppContext } from "@/app-context";
|
|
239
|
+
import { inngest } from "@/infra/inngest";
|
|
240
|
+
import { getServer } from "@/server";
|
|
241
|
+
|
|
242
|
+
/** Central registry updated by \`beignet make job\`. */
|
|
243
|
+
export const inngestJobs = [] as const;
|
|
244
|
+
|
|
245
|
+
export const inngestFunctions = createInngestJobFunctions<AppContext>({
|
|
246
|
+
client: inngest,
|
|
247
|
+
jobs: inngestJobs,
|
|
248
|
+
ctx: async () => {
|
|
249
|
+
const server = await getServer();
|
|
250
|
+
return server.createServiceContext({
|
|
251
|
+
actor: createServiceActor("beignet-inngest"),
|
|
252
|
+
});
|
|
253
|
+
},
|
|
254
|
+
instrumentation: async () => (await getServer()).ports,
|
|
255
|
+
errorReporter: async () => (await getServer()).ports.errorReporter,
|
|
256
|
+
});
|
|
257
|
+
`;
|
|
258
|
+
}
|
|
259
|
+
|
|
212
260
|
export function betterAuth(ctx: TemplateContext): string {
|
|
213
261
|
const connectionByDatabase = {
|
|
214
262
|
sqlite: `import { betterAuth } from "better-auth";
|
|
@@ -672,6 +720,15 @@ export function GET(request: Request): Promise<Response> {
|
|
|
672
720
|
export function POST(request: Request): Promise<Response> {
|
|
673
721
|
return handleAuthRoute("POST", request);
|
|
674
722
|
}
|
|
723
|
+
`,
|
|
724
|
+
inngestRoute: `import { serve } from "inngest/next";
|
|
725
|
+
import { inngest } from "@/infra/inngest";
|
|
726
|
+
import { inngestFunctions } from "@/server/inngest";
|
|
727
|
+
|
|
728
|
+
export const { GET, POST, PUT } = serve({
|
|
729
|
+
client: inngest,
|
|
730
|
+
functions: inngestFunctions,
|
|
731
|
+
});
|
|
675
732
|
`,
|
|
676
733
|
// API-only scaffold frontend: a minimal layout and landing page that point
|
|
677
734
|
// at the contract-backed API surface, plus a typed client without React
|
package/src/templates/shared.ts
CHANGED
|
@@ -48,7 +48,7 @@ export const externalVersions = {
|
|
|
48
48
|
bullmq: "^5.0.0",
|
|
49
49
|
drizzleKit: "^0.31.10",
|
|
50
50
|
drizzleOrm: "^0.45.2",
|
|
51
|
-
inngest: "^
|
|
51
|
+
inngest: "^4.12.1",
|
|
52
52
|
libsqlClient: "^0.14.0",
|
|
53
53
|
vercelBlob: "^2.5.0",
|
|
54
54
|
mysql2: "^3.12.0",
|
|
@@ -67,18 +67,26 @@ export const externalVersions = {
|
|
|
67
67
|
upstashRedis: "^1.0.0",
|
|
68
68
|
};
|
|
69
69
|
|
|
70
|
-
export const legacyGeneratedPackageScripts: Record<string, string> =
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
70
|
+
export const legacyGeneratedPackageScripts: Record<string, readonly string[]> =
|
|
71
|
+
{
|
|
72
|
+
"db:reset": ["bun infra/db/reset.ts"],
|
|
73
|
+
"db:seed": ["bun server/seed.ts"],
|
|
74
|
+
test: ["bun test", "tsx lib/beignet-test-runner.ts"],
|
|
75
|
+
};
|
|
75
76
|
|
|
76
77
|
export const currentGeneratedPackageScripts: Record<string, string> = {
|
|
77
78
|
"db:reset": "tsx infra/db/reset.ts",
|
|
78
79
|
"db:seed": "tsx server/seed.ts",
|
|
79
|
-
test: "tsx lib/beignet-test-runner.ts",
|
|
80
|
+
test: "node --import tsx lib/beignet-test-runner.ts",
|
|
80
81
|
};
|
|
81
82
|
|
|
83
|
+
export function isLegacyGeneratedPackageScript(
|
|
84
|
+
name: string,
|
|
85
|
+
command: string | undefined,
|
|
86
|
+
): boolean {
|
|
87
|
+
return legacyGeneratedPackageScripts[name]?.includes(command ?? "") ?? false;
|
|
88
|
+
}
|
|
89
|
+
|
|
82
90
|
/**
|
|
83
91
|
* Dialect-specific names used when rendering database-aware templates.
|
|
84
92
|
*/
|