@guren/server 0.2.0-alpha.7 → 1.0.0-rc.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.
Files changed (54) hide show
  1. package/dist/Application-DtWDHXr1.d.ts +2110 -0
  2. package/dist/BroadcastManager-AkIWUGJo.d.ts +466 -0
  3. package/dist/CacheManager-BkvHEOZX.d.ts +244 -0
  4. package/dist/ConsoleKernel-CqCVrdZs.d.ts +207 -0
  5. package/dist/EventManager-CmIoLt7r.d.ts +207 -0
  6. package/dist/Gate-CNkBYf8m.d.ts +268 -0
  7. package/dist/HealthManager-DUyMIzsZ.d.ts +141 -0
  8. package/dist/I18nManager-Dtgzsf5n.d.ts +270 -0
  9. package/dist/LogManager-7mxnkaPM.d.ts +256 -0
  10. package/dist/MailManager-DpMvYiP9.d.ts +292 -0
  11. package/dist/Scheduler-BstvSca7.d.ts +469 -0
  12. package/dist/StorageManager-oZTHqaza.d.ts +337 -0
  13. package/dist/api-token-JOif2CtG.d.ts +1792 -0
  14. package/dist/app-key-CsBfRC_Q.d.ts +214 -0
  15. package/dist/auth/index.d.ts +418 -0
  16. package/dist/auth/index.js +6742 -0
  17. package/dist/authorization/index.d.ts +129 -0
  18. package/dist/authorization/index.js +621 -0
  19. package/dist/broadcasting/index.d.ts +233 -0
  20. package/dist/broadcasting/index.js +907 -0
  21. package/dist/cache/index.d.ts +233 -0
  22. package/dist/cache/index.js +817 -0
  23. package/dist/encryption/index.d.ts +222 -0
  24. package/dist/encryption/index.js +602 -0
  25. package/dist/events/index.d.ts +155 -0
  26. package/dist/events/index.js +330 -0
  27. package/dist/health/index.d.ts +185 -0
  28. package/dist/health/index.js +379 -0
  29. package/dist/i18n/index.d.ts +101 -0
  30. package/dist/i18n/index.js +597 -0
  31. package/dist/index-9_Jzj5jo.d.ts +7 -0
  32. package/dist/index.d.ts +2628 -619
  33. package/dist/index.js +22229 -3116
  34. package/dist/lambda/index.d.ts +156 -0
  35. package/dist/lambda/index.js +91 -0
  36. package/dist/logging/index.d.ts +50 -0
  37. package/dist/logging/index.js +557 -0
  38. package/dist/mail/index.d.ts +288 -0
  39. package/dist/mail/index.js +695 -0
  40. package/dist/mcp/index.d.ts +139 -0
  41. package/dist/mcp/index.js +382 -0
  42. package/dist/notifications/index.d.ts +271 -0
  43. package/dist/notifications/index.js +741 -0
  44. package/dist/queue/index.d.ts +423 -0
  45. package/dist/queue/index.js +958 -0
  46. package/dist/runtime/index.d.ts +93 -0
  47. package/dist/runtime/index.js +834 -0
  48. package/dist/scheduling/index.d.ts +41 -0
  49. package/dist/scheduling/index.js +836 -0
  50. package/dist/storage/index.d.ts +196 -0
  51. package/dist/storage/index.js +832 -0
  52. package/dist/vite/index.js +203 -3
  53. package/package.json +93 -6
  54. package/dist/chunk-FK2XQSBF.js +0 -160
@@ -0,0 +1,139 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { S as ServiceProvider } from '../Application-DtWDHXr1.js';
3
+ import 'hono';
4
+ import '../api-token-JOif2CtG.js';
5
+ import 'vite';
6
+ import '../EventManager-CmIoLt7r.js';
7
+ import '../CacheManager-BkvHEOZX.js';
8
+ import '../MailManager-DpMvYiP9.js';
9
+ import '../LogManager-7mxnkaPM.js';
10
+ import '../I18nManager-Dtgzsf5n.js';
11
+ import '../BroadcastManager-AkIWUGJo.js';
12
+ import '../index-9_Jzj5jo.js';
13
+ import '../app-key-CsBfRC_Q.js';
14
+ import '../StorageManager-oZTHqaza.js';
15
+ import '../HealthManager-DUyMIzsZ.js';
16
+ import '../Scheduler-BstvSca7.js';
17
+ import '../Gate-CNkBYf8m.js';
18
+
19
+ /**
20
+ * CLI functions that the MCP server wraps.
21
+ * These are injected at runtime to avoid circular dependencies
22
+ * (@guren/server cannot depend on @guren/cli directly).
23
+ */
24
+ interface GurenCliApi {
25
+ generateContext(opts: {
26
+ cwd: string;
27
+ }): Promise<{
28
+ framework: {
29
+ name: string;
30
+ version: string;
31
+ };
32
+ models: Array<{
33
+ className: string;
34
+ }>;
35
+ routes: Array<unknown>;
36
+ pages: string[];
37
+ controllers: string[];
38
+ resources: string[];
39
+ events: string[];
40
+ jobs: string[];
41
+ middleware: string[];
42
+ listeners: string[];
43
+ validators: string[];
44
+ }>;
45
+ renderContextMarkdown(ctx: unknown): string;
46
+ runCheck(opts: {
47
+ cwd: string;
48
+ }): Promise<{
49
+ cwd: string;
50
+ checks: Array<{
51
+ key: string;
52
+ title: string;
53
+ status: string;
54
+ message: string;
55
+ suggestion?: string;
56
+ }>;
57
+ passCount: number;
58
+ warnCount: number;
59
+ failCount: number;
60
+ }>;
61
+ listModels(opts: {
62
+ appRoot: string;
63
+ }): Promise<Array<{
64
+ className: string;
65
+ filePath: string;
66
+ tableName?: string;
67
+ relationships: Array<{
68
+ name: string;
69
+ type: string;
70
+ relatedModel?: string;
71
+ }>;
72
+ usesAuth: boolean;
73
+ hasSoftDeletes: boolean;
74
+ }>>;
75
+ generateGuidelines(opts: {
76
+ cwd: string;
77
+ }): Promise<string>;
78
+ runDoctor(opts: {
79
+ cwd: string;
80
+ }): Promise<unknown>;
81
+ suggestNextSteps(opts: {
82
+ cwd: string;
83
+ }): Promise<unknown>;
84
+ makeFeature(name: string, opts: {
85
+ fields?: string;
86
+ withTest?: boolean;
87
+ force?: boolean;
88
+ }): Promise<string[]>;
89
+ makeController(name: string, opts: {
90
+ force?: boolean;
91
+ }): Promise<string | string[]>;
92
+ makeModel(name: string, opts: {
93
+ force?: boolean;
94
+ }): Promise<string | string[]>;
95
+ makeView(name: string, opts: {
96
+ force?: boolean;
97
+ }): Promise<string | string[]>;
98
+ makeTest(name: string, opts: {
99
+ force?: boolean;
100
+ }): Promise<string | string[]>;
101
+ makeRoute(name: string, opts: {
102
+ force?: boolean;
103
+ }): Promise<string | string[]>;
104
+ generateRouteTypes(opts: {
105
+ cwd: string;
106
+ }): Promise<unknown>;
107
+ generatePageTypes(opts: {
108
+ cwd: string;
109
+ }): Promise<unknown>;
110
+ generateDataTypes(opts: {
111
+ cwd: string;
112
+ }): Promise<unknown>;
113
+ generateChannelTypes(opts: {
114
+ cwd: string;
115
+ }): Promise<unknown>;
116
+ }
117
+ interface CreateMcpServerOptions {
118
+ cwd: string;
119
+ cli: GurenCliApi;
120
+ version?: string;
121
+ }
122
+ declare function createMcpServer(options: CreateMcpServerOptions): McpServer;
123
+
124
+ /**
125
+ * Registers the MCP (Model Context Protocol) endpoint at /_guren/mcp.
126
+ *
127
+ * This provider is only active in development mode (NODE_ENV !== 'production').
128
+ * It allows AI coding agents (Claude Code, Cursor, etc.) to introspect
129
+ * the project structure, run integrity checks, and scaffold code.
130
+ *
131
+ * @guren/cli is loaded via dynamic import to avoid circular dependencies
132
+ * (@guren/server -> @guren/cli -> @guren/core -> @guren/server).
133
+ */
134
+ declare class McpServiceProvider extends ServiceProvider {
135
+ register(): void;
136
+ boot(): Promise<void>;
137
+ }
138
+
139
+ export { type CreateMcpServerOptions, McpServiceProvider, createMcpServer };
@@ -0,0 +1,382 @@
1
+ // src/mcp/create-mcp-server.ts
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { z } from "zod";
4
+ function createMcpServer(options) {
5
+ const { cwd, cli, version = "0.2.0" } = options;
6
+ const server = new McpServer({
7
+ name: "guren",
8
+ version
9
+ });
10
+ server.tool(
11
+ "guren_get_context",
12
+ "Get a complete project context map including models, routes, pages, controllers, resources, events, jobs, middleware, listeners, and validators.",
13
+ {
14
+ format: z.enum(["json", "markdown"]).default("json").describe("Output format")
15
+ },
16
+ async ({ format }) => {
17
+ const ctx = await cli.generateContext({ cwd });
18
+ const text = format === "markdown" ? cli.renderContextMarkdown(ctx) : JSON.stringify(ctx, null, 2);
19
+ return { content: [{ type: "text", text }] };
20
+ }
21
+ );
22
+ server.tool(
23
+ "guren_check",
24
+ "Validate route-to-controller-to-page consistency, check for empty controller methods, missing test files, and missing generated manifests.",
25
+ {},
26
+ async () => {
27
+ const report = await cli.runCheck({ cwd });
28
+ return { content: [{ type: "text", text: JSON.stringify(report, null, 2) }] };
29
+ }
30
+ );
31
+ server.tool(
32
+ "guren_list_models",
33
+ "List all models with their table names, relationships, authentication trait, and soft deletes status.",
34
+ {},
35
+ async () => {
36
+ const models = await cli.listModels({ appRoot: cwd });
37
+ return { content: [{ type: "text", text: JSON.stringify(models, null, 2) }] };
38
+ }
39
+ );
40
+ server.tool(
41
+ "guren_generate_guidelines",
42
+ "Generate project-specific coding guidelines based on the current project structure, naming conventions, auth setup, models, validation patterns, and middleware.",
43
+ {},
44
+ async () => {
45
+ const guidelines = await cli.generateGuidelines({ cwd });
46
+ return { content: [{ type: "text", text: guidelines }] };
47
+ }
48
+ );
49
+ server.tool(
50
+ "guren_doctor",
51
+ "Run a comprehensive health check on the Guren project and optionally suggest actionable next steps.",
52
+ {
53
+ next: z.boolean().default(false).describe("Include actionable next steps")
54
+ },
55
+ async ({ next }) => {
56
+ const report = await cli.runDoctor({ cwd });
57
+ let text = JSON.stringify(report, null, 2);
58
+ if (next) {
59
+ const steps = await cli.suggestNextSteps({ cwd });
60
+ text = JSON.stringify({ ...report, nextSteps: steps }, null, 2);
61
+ }
62
+ return { content: [{ type: "text", text }] };
63
+ }
64
+ );
65
+ server.tool(
66
+ "guren_make_feature",
67
+ "Generate a complete CRUD feature: controller, model, views (Index, Show, New, Edit), validator, and resource. Optionally include test file.",
68
+ {
69
+ name: z.string().describe('Resource name in PascalCase (e.g., "Post", "BlogComment")'),
70
+ fields: z.string().optional().describe(
71
+ 'Comma-separated field definitions (e.g., "title:string,body:text,published:boolean")'
72
+ ),
73
+ withTest: z.boolean().default(false).describe("Generate test file"),
74
+ force: z.boolean().default(false).describe("Overwrite existing files")
75
+ },
76
+ async ({ name, fields, withTest, force }) => {
77
+ const originalCwd = process.cwd();
78
+ try {
79
+ process.chdir(cwd);
80
+ const createdFiles = await cli.makeFeature(name, { fields, withTest, force });
81
+ return {
82
+ content: [{ type: "text", text: JSON.stringify({ created: createdFiles }, null, 2) }]
83
+ };
84
+ } finally {
85
+ process.chdir(originalCwd);
86
+ }
87
+ }
88
+ );
89
+ server.tool(
90
+ "guren_make_component",
91
+ "Generate a single component: controller, model, middleware, event, job, listener, resource, view, test, mail, notification, seeder, factory, or migration.",
92
+ {
93
+ type: z.enum([
94
+ "controller",
95
+ "model",
96
+ "middleware",
97
+ "event",
98
+ "job",
99
+ "listener",
100
+ "resource",
101
+ "view",
102
+ "test",
103
+ "mail",
104
+ "notification",
105
+ "seeder",
106
+ "factory",
107
+ "provider",
108
+ "exception",
109
+ "command",
110
+ "channel"
111
+ ]).describe("Component type to generate"),
112
+ name: z.string().describe("Component name in PascalCase"),
113
+ force: z.boolean().default(false).describe("Overwrite existing files")
114
+ },
115
+ async ({ type, name, force }) => {
116
+ const originalCwd = process.cwd();
117
+ try {
118
+ process.chdir(cwd);
119
+ const makers = {
120
+ controller: cli.makeController,
121
+ model: cli.makeModel,
122
+ view: cli.makeView,
123
+ test: cli.makeTest,
124
+ route: cli.makeRoute
125
+ };
126
+ const maker = makers[type];
127
+ if (!maker) {
128
+ return {
129
+ content: [
130
+ {
131
+ type: "text",
132
+ text: `Component type "${type}" is not yet supported via MCP. Use the CLI: bunx guren make:${type} ${name}`
133
+ }
134
+ ],
135
+ isError: true
136
+ };
137
+ }
138
+ const result = await maker(name, { force });
139
+ const created = Array.isArray(result) ? result : [result];
140
+ return {
141
+ content: [{ type: "text", text: JSON.stringify({ created }, null, 2) }]
142
+ };
143
+ } finally {
144
+ process.chdir(originalCwd);
145
+ }
146
+ }
147
+ );
148
+ server.tool(
149
+ "guren_codegen",
150
+ "Generate type-safe route, page, data, and channel type manifests (.guren/*.gen.ts files).",
151
+ {},
152
+ async () => {
153
+ const originalCwd = process.cwd();
154
+ try {
155
+ process.chdir(cwd);
156
+ const generated = [];
157
+ try {
158
+ await cli.generateRouteTypes({ cwd });
159
+ generated.push(".guren/routes.gen.ts");
160
+ } catch {
161
+ }
162
+ try {
163
+ await cli.generatePageTypes({ cwd });
164
+ generated.push(".guren/pages.gen.ts");
165
+ } catch {
166
+ }
167
+ try {
168
+ await cli.generateDataTypes({ cwd });
169
+ generated.push(".guren/data.gen.ts");
170
+ } catch {
171
+ }
172
+ try {
173
+ await cli.generateChannelTypes({ cwd });
174
+ generated.push(".guren/channels.gen.ts");
175
+ } catch {
176
+ }
177
+ return {
178
+ content: [{ type: "text", text: JSON.stringify({ generated }, null, 2) }]
179
+ };
180
+ } finally {
181
+ process.chdir(originalCwd);
182
+ }
183
+ }
184
+ );
185
+ server.resource(
186
+ "context",
187
+ "guren://context",
188
+ {
189
+ description: "Current project structure map (models, routes, pages, controllers, etc.)",
190
+ mimeType: "application/json"
191
+ },
192
+ async (uri) => {
193
+ const ctx = await cli.generateContext({ cwd });
194
+ return {
195
+ contents: [
196
+ {
197
+ uri: uri.href,
198
+ mimeType: "application/json",
199
+ text: JSON.stringify(ctx, null, 2)
200
+ }
201
+ ]
202
+ };
203
+ }
204
+ );
205
+ server.resource(
206
+ "guidelines",
207
+ "guren://guidelines",
208
+ {
209
+ description: "Auto-generated project-specific coding guidelines",
210
+ mimeType: "text/markdown"
211
+ },
212
+ async (uri) => {
213
+ const guidelines = await cli.generateGuidelines({ cwd });
214
+ return {
215
+ contents: [
216
+ {
217
+ uri: uri.href,
218
+ mimeType: "text/markdown",
219
+ text: guidelines
220
+ }
221
+ ]
222
+ };
223
+ }
224
+ );
225
+ server.prompt(
226
+ "guren_review",
227
+ "Review code changes against project conventions and patterns. Automatically fetches project context and runs integrity checks first.",
228
+ async () => {
229
+ let contextSummary;
230
+ try {
231
+ const ctx = await cli.generateContext({ cwd });
232
+ const check = await cli.runCheck({ cwd });
233
+ contextSummary = [
234
+ "## Project Context",
235
+ `Framework: ${ctx.framework.name} v${ctx.framework.version}`,
236
+ `Models: ${ctx.models.map((m) => m.className).join(", ") || "none"}`,
237
+ `Controllers: ${ctx.controllers.join(", ") || "none"}`,
238
+ `Pages: ${ctx.pages.join(", ") || "none"}`,
239
+ "",
240
+ "## Integrity Check",
241
+ `Pass: ${check.passCount}, Warn: ${check.warnCount}, Fail: ${check.failCount}`,
242
+ ...check.checks.filter((c) => c.status !== "pass").map((c) => `- [${c.status}] ${c.title}: ${c.message}`)
243
+ ].join("\n");
244
+ } catch {
245
+ contextSummary = "Could not load project context.";
246
+ }
247
+ return {
248
+ messages: [
249
+ {
250
+ role: "user",
251
+ content: {
252
+ type: "text",
253
+ text: [
254
+ "Review the recent code changes in this Guren project.",
255
+ "Check for:",
256
+ "1. Adherence to project naming conventions and patterns",
257
+ "2. Route-controller-page consistency",
258
+ "3. Missing validation schemas",
259
+ "4. Missing tests for new controllers",
260
+ "5. Proper use of Model API (findOrFail, relationships)",
261
+ "",
262
+ contextSummary
263
+ ].join("\n")
264
+ }
265
+ }
266
+ ]
267
+ };
268
+ }
269
+ );
270
+ server.prompt(
271
+ "guren_plan_feature",
272
+ "Plan a new feature given the current project structure. Provide the feature description as an argument.",
273
+ { feature: z.string().describe("Description of the feature to plan") },
274
+ async ({ feature }) => {
275
+ let contextSummary;
276
+ try {
277
+ const ctx = await cli.generateContext({ cwd });
278
+ const models = await cli.listModels({ appRoot: cwd });
279
+ contextSummary = [
280
+ "## Current Project State",
281
+ `Models: ${models.map((m) => `${m.className}${m.tableName ? ` (${m.tableName})` : ""}`).join(", ") || "none"}`,
282
+ `Controllers: ${ctx.controllers.join(", ") || "none"}`,
283
+ `Routes: ${ctx.routes.length} defined`,
284
+ `Pages: ${ctx.pages.join(", ") || "none"}`,
285
+ "",
286
+ "## Model Relationships",
287
+ ...models.flatMap(
288
+ (m) => m.relationships.length > 0 ? [
289
+ `${m.className}: ${m.relationships.map((r) => `${r.type}(${r.name})`).join(", ")}`
290
+ ] : []
291
+ )
292
+ ].join("\n");
293
+ } catch {
294
+ contextSummary = "Could not load project context.";
295
+ }
296
+ return {
297
+ messages: [
298
+ {
299
+ role: "user",
300
+ content: {
301
+ type: "text",
302
+ text: [
303
+ `Plan the implementation of: ${feature}`,
304
+ "",
305
+ "Provide:",
306
+ "1. Which files to create/modify",
307
+ "2. Database schema changes (migration)",
308
+ "3. Model definition with relationships",
309
+ "4. Controller actions and validation schemas",
310
+ "5. Inertia page components",
311
+ "6. Route definitions",
312
+ "7. Test plan",
313
+ "",
314
+ contextSummary
315
+ ].join("\n")
316
+ }
317
+ }
318
+ ]
319
+ };
320
+ }
321
+ );
322
+ return server;
323
+ }
324
+
325
+ // src/container/ServiceProvider.ts
326
+ var ServiceProvider = class {
327
+ constructor(container) {
328
+ this.container = container;
329
+ }
330
+ /**
331
+ * Whether this provider should be deferred.
332
+ * Deferred providers are only loaded when one of their provided services is requested.
333
+ */
334
+ static deferred = false;
335
+ /**
336
+ * The services provided by this provider (for deferred loading).
337
+ */
338
+ static provides = [];
339
+ /**
340
+ * Get the services provided by the provider.
341
+ */
342
+ provides() {
343
+ return this.constructor.provides;
344
+ }
345
+ /**
346
+ * Check if this provider is deferred.
347
+ */
348
+ isDeferred() {
349
+ return this.constructor.deferred;
350
+ }
351
+ };
352
+
353
+ // src/mcp/McpServiceProvider.ts
354
+ var McpServiceProvider = class extends ServiceProvider {
355
+ register() {
356
+ }
357
+ async boot() {
358
+ if (process.env.NODE_ENV === "production") {
359
+ return;
360
+ }
361
+ const app = this.container.make("app");
362
+ const hono = app.hono;
363
+ const cwd = process.cwd();
364
+ const [{ WebStandardStreamableHTTPServerTransport }, cli] = await Promise.all([
365
+ import("@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js"),
366
+ // @ts-ignore — @guren/cli is available at runtime via the app's dependencies
367
+ import("@guren/cli")
368
+ ]);
369
+ hono.all("/_guren/mcp", async (c) => {
370
+ const mcpServer = createMcpServer({ cwd, cli });
371
+ const transport = new WebStandardStreamableHTTPServerTransport({
372
+ sessionIdGenerator: void 0
373
+ });
374
+ await mcpServer.connect(transport);
375
+ return transport.handleRequest(c.req.raw);
376
+ });
377
+ }
378
+ };
379
+ export {
380
+ McpServiceProvider,
381
+ createMcpServer
382
+ };