@beignet/cli 0.0.40 → 0.0.41

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 (93) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/README.md +76 -10
  3. package/dist/analysis/source-index.d.ts +38 -0
  4. package/dist/analysis/source-index.d.ts.map +1 -0
  5. package/dist/analysis/source-index.js +271 -0
  6. package/dist/analysis/source-index.js.map +1 -0
  7. package/dist/analysis/workspace.d.ts +16 -0
  8. package/dist/analysis/workspace.d.ts.map +1 -0
  9. package/dist/analysis/workspace.js +134 -0
  10. package/dist/analysis/workspace.js.map +1 -0
  11. package/dist/app-map-schema.d.ts +5 -0
  12. package/dist/app-map-schema.d.ts.map +1 -0
  13. package/dist/app-map-schema.js +26 -0
  14. package/dist/app-map-schema.js.map +1 -0
  15. package/dist/app-map.d.ts +96 -0
  16. package/dist/app-map.d.ts.map +1 -0
  17. package/dist/app-map.js +1141 -0
  18. package/dist/app-map.js.map +1 -0
  19. package/dist/check.d.ts +7 -0
  20. package/dist/check.d.ts.map +1 -1
  21. package/dist/check.js +20 -5
  22. package/dist/check.js.map +1 -1
  23. package/dist/db.d.ts +32 -7
  24. package/dist/db.d.ts.map +1 -1
  25. package/dist/db.js +182 -14
  26. package/dist/db.js.map +1 -1
  27. package/dist/explain.d.ts +98 -0
  28. package/dist/explain.d.ts.map +1 -0
  29. package/dist/explain.js +512 -0
  30. package/dist/explain.js.map +1 -0
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +79 -2
  33. package/dist/index.js.map +1 -1
  34. package/dist/inspect.js +53 -3
  35. package/dist/inspect.js.map +1 -1
  36. package/dist/lib.d.ts +4 -0
  37. package/dist/lib.d.ts.map +1 -1
  38. package/dist/lib.js +2 -0
  39. package/dist/lib.js.map +1 -1
  40. package/dist/make.d.ts.map +1 -1
  41. package/dist/make.js +63 -2
  42. package/dist/make.js.map +1 -1
  43. package/dist/mcp.d.ts +1 -1
  44. package/dist/mcp.d.ts.map +1 -1
  45. package/dist/mcp.js +69 -1
  46. package/dist/mcp.js.map +1 -1
  47. package/dist/preflight.d.ts.map +1 -1
  48. package/dist/preflight.js +10 -0
  49. package/dist/preflight.js.map +1 -1
  50. package/dist/provider-add.d.ts.map +1 -1
  51. package/dist/provider-add.js +167 -13
  52. package/dist/provider-add.js.map +1 -1
  53. package/dist/provider-audit.d.ts +6 -0
  54. package/dist/provider-audit.d.ts.map +1 -1
  55. package/dist/provider-audit.js +63 -15
  56. package/dist/provider-audit.js.map +1 -1
  57. package/dist/templates/agents.d.ts.map +1 -1
  58. package/dist/templates/agents.js +17 -4
  59. package/dist/templates/agents.js.map +1 -1
  60. package/dist/templates/base.d.ts.map +1 -1
  61. package/dist/templates/base.js +10 -4
  62. package/dist/templates/base.js.map +1 -1
  63. package/dist/templates/index.d.ts +1 -1
  64. package/dist/templates/index.d.ts.map +1 -1
  65. package/dist/templates/index.js +8 -1
  66. package/dist/templates/index.js.map +1 -1
  67. package/dist/templates/server.d.ts +3 -0
  68. package/dist/templates/server.d.ts.map +1 -1
  69. package/dist/templates/server.js +55 -1
  70. package/dist/templates/server.js.map +1 -1
  71. package/dist/templates/shared.js +1 -1
  72. package/package.json +2 -2
  73. package/skills/app-structure/SKILL.md +22 -4
  74. package/src/analysis/source-index.ts +395 -0
  75. package/src/analysis/workspace.ts +180 -0
  76. package/src/app-map-schema.ts +28 -0
  77. package/src/app-map.ts +1705 -0
  78. package/src/check.ts +27 -4
  79. package/src/db.ts +232 -14
  80. package/src/explain.ts +786 -0
  81. package/src/index.ts +113 -2
  82. package/src/inspect.ts +70 -2
  83. package/src/lib.ts +36 -0
  84. package/src/make.ts +90 -2
  85. package/src/mcp.ts +107 -1
  86. package/src/preflight.ts +14 -0
  87. package/src/provider-add.ts +211 -12
  88. package/src/provider-audit.ts +127 -22
  89. package/src/templates/agents.ts +17 -4
  90. package/src/templates/base.ts +22 -4
  91. package/src/templates/index.ts +18 -1
  92. package/src/templates/server.ts +58 -1
  93. package/src/templates/shared.ts +1 -1
@@ -268,11 +268,13 @@ ${firstOpen}
268
268
  \`\`\`bash
269
269
  # in another terminal
270
270
  ${cli} routes
271
+ ${cli} map
271
272
  ${cli} check
272
273
  \`\`\`
273
274
 
274
- \`routes\` shows the contracts Beignet can inspect. \`check\` runs the whole
275
- validation loop in one pass: \`${cli} lint\` (dependency direction),
275
+ \`routes\` shows the contracts Beignet can inspect. \`map\` shows how features,
276
+ use cases, workflows, ports, providers, and tests connect. \`check\` runs the
277
+ whole validation loop in one pass: \`${cli} lint\` (dependency direction),
276
278
  \`${cli} doctor --strict\` (route, OpenAPI, and resource drift), and the
277
279
  \`lint\`, \`typecheck\`, and \`test\` package scripts. Use \`${format}\` to
278
280
  apply Biome formatting.
@@ -306,6 +308,10 @@ Use \`${cli} make feature projects --recipe full-slice\` when you want a richer
306
308
 
307
309
  ## App map
308
310
 
311
+ Run \`${cli} map\` for the current architecture or \`${cli} map --json\` for
312
+ the versioned graph used by coding agents. Add \`--feature todos\` to focus on
313
+ one slice and its direct relationships.
314
+
309
315
  - \`features/todos/contracts.ts\` owns the HTTP contract and reuses shared feature schemas.
310
316
  - \`features/todos/schemas.ts\` owns shared DTO and validation schemas used by contracts, use cases, ports, tests, and clients.
311
317
  - \`features/todos/client/\` may own todos-specific data-fetching helpers and React Query hooks.
@@ -391,8 +397,10 @@ export function providersDoc(ctx: TemplateContext): string {
391
397
  "- Package: `@beignet/core` (`@beignet/core/events`, `@beignet/core/jobs`)",
392
398
  "- Package: `@beignet/provider-jobs-inngest`",
393
399
  "- Peer dependency: `inngest`",
394
- "- The starter wires `createInngestJobsProvider()` in `server/providers.ts`.",
400
+ "- The starter shares one Inngest client between `createInngestJobsProvider(...)` and `app/api/inngest/route.ts`.",
395
401
  "- Define jobs with `defineJob(...)` and dispatch them through `ctx.ports.jobs.dispatch(...)`.",
402
+ "- `beignet make job` registers feature job collections in `server/inngest.ts`.",
403
+ "- Use `INNGEST_DEV=1` only locally; production needs `INNGEST_EVENT_KEY` and `INNGEST_SIGNING_KEY`.",
396
404
  "- Use `ctx.ports.inngest` only as an escape hatch for Inngest-specific workflow APIs; prefer `ctx.ports.jobs.dispatch(...)` for Beignet jobs.",
397
405
  "",
398
406
  );
@@ -471,7 +479,17 @@ export function envExample(ctx: TemplateContext): string {
471
479
  ];
472
480
 
473
481
  if (hasStarterProvider(ctx, "jobs-inngest")) {
474
- lines.push("INNGEST_APP_NAME=beignet-app", "# INNGEST_EVENT_KEY=", "");
482
+ lines.push(
483
+ "# Local development connects the app to the Inngest dev server.",
484
+ "INNGEST_APP_NAME=beignet-app",
485
+ "INNGEST_DEV=1",
486
+ "# Production cloud dispatch and endpoint verification.",
487
+ "# INNGEST_EVENT_KEY=",
488
+ "# INNGEST_SIGNING_KEY=",
489
+ "# Optional signing-key rotation fallback.",
490
+ "# INNGEST_SIGNING_KEY_FALLBACK=",
491
+ "",
492
+ );
475
493
  }
476
494
 
477
495
  if (hasStarterProvider(ctx, "mail-resend")) {
@@ -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 type { TemplateContext, TemplateFile } from "./shared.js";
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 },
@@ -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
@@ -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: "^3.54.0",
51
+ inngest: "^4.12.1",
52
52
  libsqlClient: "^0.14.0",
53
53
  vercelBlob: "^2.5.0",
54
54
  mysql2: "^3.12.0",