create-m5kdev 0.36.0 → 0.37.4
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/package.json +3 -3
- package/templates/minimal-app/.dockerignore.tpl +6 -0
- package/templates/minimal-app/apps/e2e/playwright.config.ts.tpl +3 -0
- package/templates/minimal-app/apps/e2e/servers.ts.tpl +1 -0
- package/templates/minimal-app/apps/e2e/tests/mcp-helpers.ts.tpl +406 -0
- package/templates/minimal-app/apps/e2e/tests/mcp.spec.ts.tpl +108 -0
- package/templates/minimal-app/apps/server/AGENTS.md.tpl +10 -0
- package/templates/minimal-app/apps/server/db.e2e.ts.tpl +1 -0
- package/templates/minimal-app/apps/server/db.ts.tpl +1 -0
- package/templates/minimal-app/apps/server/drizzle/0006_lazy_blue_marvel.sql +159 -0
- package/templates/minimal-app/apps/server/drizzle/0007_abnormal_ultimo.sql +2 -0
- package/templates/minimal-app/apps/server/drizzle/0008_steady_nekra.sql +87 -0
- package/templates/minimal-app/apps/server/drizzle/meta/0006_snapshot.json.tpl +3603 -0
- package/templates/minimal-app/apps/server/drizzle/meta/0007_snapshot.json.tpl +3620 -0
- package/templates/minimal-app/apps/server/drizzle/meta/0008_snapshot.json.tpl +3620 -0
- package/templates/minimal-app/apps/server/drizzle/meta/_journal.json.tpl +21 -0
- package/templates/minimal-app/apps/server/src/app.ts.tpl +8 -1
- package/templates/minimal-app/apps/server/src/modules/posts/posts.mcp.ts.tpl +17 -0
- package/templates/minimal-app/apps/server/src/modules/posts/posts.module.ts.tpl +11 -0
- package/templates/minimal-app/apps/server/src/modules/posts/posts.service.ts.tpl +13 -4
- package/templates/minimal-app/apps/server/src/schema.ts.tpl +13 -0
- package/templates/minimal-app/pnpm-workspace.yaml.tpl +14 -14
- package/templates/minimal-app/template.manifest.json +9 -0
|
@@ -43,6 +43,27 @@
|
|
|
43
43
|
"when": 1788253467922,
|
|
44
44
|
"tag": "0005_wonderful_the_professor",
|
|
45
45
|
"breakpoints": true
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"idx": 6,
|
|
49
|
+
"version": "6",
|
|
50
|
+
"when": 1788787832546,
|
|
51
|
+
"tag": "0006_lazy_blue_marvel",
|
|
52
|
+
"breakpoints": true
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"idx": 7,
|
|
56
|
+
"version": "6",
|
|
57
|
+
"when": 1788788533642,
|
|
58
|
+
"tag": "0007_abnormal_ultimo",
|
|
59
|
+
"breakpoints": true
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"idx": 8,
|
|
63
|
+
"version": "6",
|
|
64
|
+
"when": 1788789159968,
|
|
65
|
+
"tag": "0008_steady_nekra",
|
|
66
|
+
"breakpoints": true
|
|
46
67
|
}
|
|
47
68
|
]
|
|
48
69
|
}
|
|
@@ -10,6 +10,9 @@ import { EmailPreviewModule } from "@m5kdev/backend/modules/email/email.preview.
|
|
|
10
10
|
// m5k:files:start
|
|
11
11
|
import { FileModule } from "@m5kdev/backend/modules/file/file.module";
|
|
12
12
|
// m5k:files:end
|
|
13
|
+
// m5k:mcp:start
|
|
14
|
+
import { McpModule } from "@m5kdev/backend/modules/mcp/mcp.module";
|
|
15
|
+
// m5k:mcp:end
|
|
13
16
|
// m5k:notifications:start
|
|
14
17
|
import { NotificationModule } from "@m5kdev/backend/modules/notification/notification.module";
|
|
15
18
|
// m5k:notifications:end
|
|
@@ -94,7 +97,7 @@ export const builtBackendApp = createBackendApp(
|
|
|
94
97
|
outputDirectory: process.env.EMAIL_OUTPUT_DIRECTORY ?? ".emails",
|
|
95
98
|
},
|
|
96
99
|
auth: {
|
|
97
|
-
factory({ db, services, appConfig, i18n }) {
|
|
100
|
+
factory({ db, services, appConfig, i18n, mcp }) {
|
|
98
101
|
return createBetterAuth({
|
|
99
102
|
orm: db.orm,
|
|
100
103
|
schema: db.schema,
|
|
@@ -103,6 +106,7 @@ export const builtBackendApp = createBackendApp(
|
|
|
103
106
|
},
|
|
104
107
|
app: appConfig,
|
|
105
108
|
i18n,
|
|
109
|
+
mcp,
|
|
106
110
|
config: {
|
|
107
111
|
waitlist: enableWaitlist,
|
|
108
112
|
provisionedAccountEmailDomain:
|
|
@@ -118,6 +122,9 @@ export const builtBackendApp = createBackendApp(
|
|
|
118
122
|
[
|
|
119
123
|
new EmailModule(templates as never),
|
|
120
124
|
new AuthModule(),
|
|
125
|
+
// m5k:mcp:start
|
|
126
|
+
new McpModule(),
|
|
127
|
+
// m5k:mcp:end
|
|
121
128
|
// m5k:ai:start
|
|
122
129
|
new AIModule({
|
|
123
130
|
libs: { mastra, openrouter },
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { defineMcpCall } from "@m5kdev/backend/modules/mcp/mcp.define";
|
|
2
|
+
import type { McpOrganizationCallDefinition } from "@m5kdev/backend/modules/mcp/mcp.types";
|
|
3
|
+
import { postSchemas } from "./posts.dto";
|
|
4
|
+
import type { PostsService } from "./posts.service";
|
|
5
|
+
|
|
6
|
+
export function createPostsMcp(posts: PostsService): Record<string, McpOrganizationCallDefinition> {
|
|
7
|
+
return {
|
|
8
|
+
"list-posts": defineMcpCall()
|
|
9
|
+
.description("List posts in the selected Organization")
|
|
10
|
+
.input(postSchemas.input.list)
|
|
11
|
+
.handle(async (input, actor) => posts.list(input, { actor, user: { id: actor.userId } })),
|
|
12
|
+
"create-post": defineMcpCall()
|
|
13
|
+
.description("Create a draft post in the selected Organization")
|
|
14
|
+
.input(postSchemas.input.create)
|
|
15
|
+
.handle(async (input, actor) => posts.create(input, { actor, user: { id: actor.userId } })),
|
|
16
|
+
};
|
|
17
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// biome-ignore-all assist/source/organizeImports: feature-gated posts.mcp import stays in marker blocks
|
|
1
2
|
import { createBackendRouterMap } from "@m5kdev/backend/app";
|
|
2
3
|
import {
|
|
3
4
|
BaseModule,
|
|
@@ -10,6 +11,10 @@ import { postsGrants } from "./posts.grants";
|
|
|
10
11
|
import { PostsRepository } from "./posts.repository";
|
|
11
12
|
import { PostsService } from "./posts.service";
|
|
12
13
|
import { createPostsTRPC } from "./posts.trpc";
|
|
14
|
+
// m5k:mcp:start
|
|
15
|
+
import type { ModuleMcpContext } from "@m5kdev/backend/modules/base/base.module";
|
|
16
|
+
import { createPostsMcp } from "./posts.mcp";
|
|
17
|
+
// m5k:mcp:end
|
|
13
18
|
|
|
14
19
|
type PostsModuleDeps = Record<string, never>;
|
|
15
20
|
type PostsModuleTables = typeof postsTables;
|
|
@@ -54,4 +59,10 @@ export class PostsModule extends BaseModule<
|
|
|
54
59
|
override trpc({ trpc, services }: ModuleTRPCContext<PostsModuleDeps, PostsModuleServices>) {
|
|
55
60
|
return createBackendRouterMap("posts", createPostsTRPC(trpc, services.posts));
|
|
56
61
|
}
|
|
62
|
+
|
|
63
|
+
// m5k:mcp:start
|
|
64
|
+
override mcp({ services }: ModuleMcpContext<PostsModuleDeps, PostsModuleServices>) {
|
|
65
|
+
return createPostsMcp(services.posts);
|
|
66
|
+
}
|
|
67
|
+
// m5k:mcp:end
|
|
57
68
|
}
|
|
@@ -1,15 +1,21 @@
|
|
|
1
|
+
import type { AuthenticatedActor } from "@m5kdev/backend/base/base.actor";
|
|
2
|
+
import type { ServiceProcedureContext } from "@m5kdev/backend/base/base.procedure";
|
|
1
3
|
import { BasePermissionService } from "@m5kdev/backend/modules/base/base.service";
|
|
2
4
|
import { serializeSpanValue, withSpan } from "@m5kdev/backend/utils/telemetry";
|
|
3
|
-
import type { Context } from "@m5kdev/backend/utils/trpc";
|
|
4
5
|
import { err, ok } from "neverthrow";
|
|
5
6
|
import { postSchemas } from "./posts.dto";
|
|
6
7
|
import type { PostsRepository } from "./posts.repository";
|
|
7
8
|
import { createExcerpt, slugify } from "./posts.utils";
|
|
8
9
|
|
|
10
|
+
export interface PostsProcedureContext extends ServiceProcedureContext {
|
|
11
|
+
actor: AuthenticatedActor;
|
|
12
|
+
user: { id: string };
|
|
13
|
+
}
|
|
14
|
+
|
|
9
15
|
export class PostsService extends BasePermissionService<
|
|
10
16
|
{ posts: PostsRepository },
|
|
11
17
|
Record<string, never>,
|
|
12
|
-
|
|
18
|
+
PostsProcedureContext
|
|
13
19
|
> {
|
|
14
20
|
readonly list = this.procedure("list")
|
|
15
21
|
.input(postSchemas.input.list)
|
|
@@ -37,6 +43,9 @@ export class PostsService extends BasePermissionService<
|
|
|
37
43
|
.output(postSchemas.output.single)
|
|
38
44
|
.access({
|
|
39
45
|
action: "write",
|
|
46
|
+
entities: ({ ctx }) => ({
|
|
47
|
+
organizationId: ctx.actor.organizationId,
|
|
48
|
+
}),
|
|
40
49
|
})
|
|
41
50
|
.handle(async ({ input, ctx }) => {
|
|
42
51
|
const uniqueSlug = await this.repository.posts.resolveUniqueSlug({
|
|
@@ -47,9 +56,9 @@ export class PostsService extends BasePermissionService<
|
|
|
47
56
|
}
|
|
48
57
|
|
|
49
58
|
return this.repository.posts.create({
|
|
50
|
-
authorUserId: ctx.
|
|
59
|
+
authorUserId: ctx.actor.userId,
|
|
51
60
|
memberId: ctx.actor.memberId ?? null,
|
|
52
|
-
organizationId: ctx.
|
|
61
|
+
organizationId: ctx.actor.organizationId,
|
|
53
62
|
teamId: null,
|
|
54
63
|
title: input.title.trim(),
|
|
55
64
|
slug: uniqueSlug.value,
|
|
@@ -12,6 +12,19 @@ export {
|
|
|
12
12
|
verifications,
|
|
13
13
|
waitlist,
|
|
14
14
|
} from "@m5kdev/backend/modules/auth/auth.db";
|
|
15
|
+
// m5k:mcp:start
|
|
16
|
+
export {
|
|
17
|
+
jwks,
|
|
18
|
+
oauthAccessTokens,
|
|
19
|
+
oauthClientAssertions,
|
|
20
|
+
oauthClientResources,
|
|
21
|
+
oauthClients,
|
|
22
|
+
oauthConsents,
|
|
23
|
+
oauthRefreshTokens,
|
|
24
|
+
oauthResources,
|
|
25
|
+
} from "@m5kdev/backend/modules/auth/auth.oauth.db";
|
|
26
|
+
export { mcpAllowlistEntries } from "@m5kdev/backend/modules/mcp/mcp.db";
|
|
27
|
+
// m5k:mcp:end
|
|
15
28
|
// m5k:ai:start
|
|
16
29
|
export { aiUsage, chats } from "@m5kdev/backend/modules/ai/ai.db";
|
|
17
30
|
// m5k:ai:end
|
|
@@ -7,18 +7,18 @@ catalogs:
|
|
|
7
7
|
"@heroui/react": 3.0.3
|
|
8
8
|
"@heroui/styles": 3.0.3
|
|
9
9
|
"@libsql/client": 0.17.4
|
|
10
|
-
"@m5kdev/backend": 0.
|
|
11
|
-
"@m5kdev/commons": 0.
|
|
12
|
-
"@m5kdev/config": 0.
|
|
13
|
-
"@m5kdev/email": 0.
|
|
14
|
-
"@m5kdev/expo": 0.
|
|
15
|
-
"@m5kdev/frontend": 0.
|
|
16
|
-
"@m5kdev/module-clay": 0.
|
|
17
|
-
"@m5kdev/module-docx": 0.
|
|
18
|
-
"@m5kdev/module-pdf": 0.
|
|
19
|
-
"@m5kdev/module-social": 0.
|
|
20
|
-
"@m5kdev/module-video": 0.
|
|
21
|
-
"@m5kdev/web-ui": 0.
|
|
10
|
+
"@m5kdev/backend": 0.37.4
|
|
11
|
+
"@m5kdev/commons": 0.37.4
|
|
12
|
+
"@m5kdev/config": 0.37.4
|
|
13
|
+
"@m5kdev/email": 0.37.4
|
|
14
|
+
"@m5kdev/expo": 0.37.4
|
|
15
|
+
"@m5kdev/frontend": 0.37.4
|
|
16
|
+
"@m5kdev/module-clay": 0.37.4
|
|
17
|
+
"@m5kdev/module-docx": 0.37.4
|
|
18
|
+
"@m5kdev/module-pdf": 0.37.4
|
|
19
|
+
"@m5kdev/module-social": 0.37.4
|
|
20
|
+
"@m5kdev/module-video": 0.37.4
|
|
21
|
+
"@m5kdev/web-ui": 0.37.4
|
|
22
22
|
"@mastra/core": 1.51.0
|
|
23
23
|
"@openrouter/ai-sdk-provider": 3.0.0
|
|
24
24
|
"@opentelemetry/api": 1.9.0
|
|
@@ -35,7 +35,7 @@ catalogs:
|
|
|
35
35
|
"@types/react-dom": 19.2.3
|
|
36
36
|
"@vitejs/plugin-react": 4.2.0
|
|
37
37
|
babel-plugin-react-compiler: 1.0.0
|
|
38
|
-
better-auth: 1.
|
|
38
|
+
better-auth: 1.7.2
|
|
39
39
|
dotenv: 16.6.1
|
|
40
40
|
drizzle-kit: 0.31.10
|
|
41
41
|
drizzle-orm: 0.45.2
|
|
@@ -67,5 +67,5 @@ catalogs:
|
|
|
67
67
|
vite: 7.0.4
|
|
68
68
|
vite-plugin-i18next-loader: 3.1.2
|
|
69
69
|
vite-tsconfig-paths: 5.1.4
|
|
70
|
-
zod: 4.
|
|
70
|
+
zod: 4.4.3
|
|
71
71
|
catalogMode: strict
|
|
@@ -54,6 +54,15 @@
|
|
|
54
54
|
"apps/e2e/tests/conversation.spec.ts"
|
|
55
55
|
]
|
|
56
56
|
},
|
|
57
|
+
"mcp": {
|
|
58
|
+
"kind": "module",
|
|
59
|
+
"label": "MCP",
|
|
60
|
+
"paths": [
|
|
61
|
+
"apps/server/src/modules/posts/posts.mcp.ts",
|
|
62
|
+
"apps/e2e/tests/mcp.spec.ts",
|
|
63
|
+
"apps/e2e/tests/mcp-helpers.ts"
|
|
64
|
+
]
|
|
65
|
+
},
|
|
57
66
|
"notifications": {
|
|
58
67
|
"kind": "module",
|
|
59
68
|
"label": "Notifications",
|