create-m5kdev 0.31.5 → 0.31.8

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-m5kdev",
3
- "version": "0.31.5",
3
+ "version": "0.31.8",
4
4
  "license": "GPL-3.0-only",
5
5
  "repository": {
6
6
  "type": "git",
@@ -0,0 +1,214 @@
1
+ ---
2
+ globs: apps/**/server/src/modules/**/*.prompt.ts
3
+ alwaysApply: false
4
+ ---
5
+
6
+ # Module Prompt File Style Guide
7
+
8
+ Conventions for complex AI prompt modules. A prompt file owns the complete
9
+ configuration for one AI operation and exposes it through one factory
10
+ function. Callers should not need to know how the prompt, schema, model
11
+ settings, or extraction strategy are assembled.
12
+
13
+ ## File Location
14
+
15
+ ```text
16
+ apps/<app>/server/src/modules/<module>/<use-case>.prompt.ts
17
+ ```
18
+
19
+ Use one file per AI use case. If a module has unrelated operations, split them
20
+ into separate prompt files instead of exporting multiple factories from one
21
+ file.
22
+
23
+ ## Core Contract
24
+
25
+ - The only exported runtime value is one named factory function:
26
+ `create<UseCase>Prompt(...)`.
27
+ - The factory is synchronous and returns the options object for exactly one of:
28
+ `AIService.agentText`, `AIService.agentObject`, `AIService.generateText`, or
29
+ `AIService.generateObject`.
30
+ - The consumer passes the returned object directly to the chosen AI method.
31
+ - Keep prompt templates, Zod schemas, lookup tables, rules, and helper
32
+ functions private to the file.
33
+ - Export types only when another module genuinely needs them; do not export
34
+ internal prompt-building details.
35
+ - Do not call `AIService` from a prompt file. Prompt modules build parameters;
36
+ services own execution, error handling, and orchestration.
37
+
38
+ For agent methods, the factory returns the method's second argument. The agent
39
+ name remains explicit at the service call site.
40
+
41
+ ```ts
42
+ await this.service.ai.agentText("researcher", createResearchPrompt(input));
43
+ await this.service.ai.agentObject("classifier", createClassificationPrompt(input));
44
+ await this.service.ai.generateText(createSummaryPrompt(input));
45
+ await this.service.ai.generateObject(createEntryPrompt(input));
46
+ ```
47
+
48
+ Spread extra prompt configuration into the result at the call site (like adding `ctx` if needed). If
49
+ an option is part of the use case, accept the relevant domain input and decide
50
+ the option inside the factory.
51
+
52
+ ## Type the Returned Parameters
53
+
54
+ Use the public parameter types for direct generation:
55
+
56
+ ```ts
57
+ import type {
58
+ AIServiceGenerateObjectParams,
59
+ AIServiceGenerateTextParams,
60
+ } from "@m5kdev/backend/modules/ai/ai.service";
61
+ ```
62
+
63
+ For agent options, derive the second-argument type from `AIService`:
64
+
65
+ ```ts
66
+ import type { AIService } from "@m5kdev/backend/modules/ai/ai.service";
67
+
68
+ type AgentTextPromptOptions = Parameters<AIService["agentText"]>[1];
69
+ type AgentObjectPromptOptions = Parameters<AIService["agentObject"]>[1];
70
+ ```
71
+
72
+ Prefer an explicit return type. When `satisfies` preserves a concrete schema
73
+ more accurately, return the object with `satisfies` instead.
74
+
75
+ ## Canonical Object Prompt
76
+
77
+ ```ts
78
+ import { Prompt } from "@m5kdev/backend/modules/ai/ai.prompt";
79
+ import type { AIServiceGenerateObjectParams } from "@m5kdev/backend/modules/ai/ai.service";
80
+ import { z } from "zod";
81
+
82
+ type CreateEntryPromptParams = {
83
+ transcript: string;
84
+ category: "diary" | "review";
85
+ };
86
+
87
+ const entrySchema = z.object({
88
+ title: z.string().describe("A short entry title"),
89
+ content: z.string().describe("The formatted entry in Markdown"),
90
+ });
91
+
92
+ const categoryInstructions = {
93
+ diary: "Preserve the personal, chronological voice.",
94
+ review: "Organize the subject, impressions, and overall opinion.",
95
+ } as const;
96
+
97
+ const entryPrompt = new Prompt<{
98
+ transcript: string;
99
+ instructions: string;
100
+ }>(`
101
+ <instructions>
102
+ {{instructions}}
103
+ </instructions>
104
+
105
+ <transcript>
106
+ {{transcript}}
107
+ </transcript>
108
+ `);
109
+
110
+ export function createEntryPrompt(
111
+ params: CreateEntryPromptParams
112
+ ): AIServiceGenerateObjectParams<typeof entrySchema> {
113
+ return {
114
+ schema: entrySchema,
115
+ presetModels: {
116
+ category: "creative",
117
+ tokenProfile: "lg",
118
+ },
119
+ prompt: entryPrompt.compile({
120
+ transcript: params.transcript,
121
+ instructions: categoryInstructions[params.category],
122
+ }),
123
+ };
124
+ }
125
+ ```
126
+
127
+ The service consumes it without reconstructing or overriding its options:
128
+
129
+ ```ts
130
+ return this.service.ai.generateObject(createEntryPrompt(input));
131
+ ```
132
+
133
+ ## Text and Agent Variants
134
+
135
+ ### `generateText`
136
+
137
+ ```ts
138
+ export function createSummaryPrompt(
139
+ params: SummaryPromptParams
140
+ ): AIServiceGenerateTextParams {
141
+ return {
142
+ prompt: summaryPrompt.compile(params),
143
+ presetModels: { category: "chat", tokenProfile: "md" },
144
+ };
145
+ }
146
+ ```
147
+
148
+ ### `agentText`
149
+
150
+ ```ts
151
+ type AgentTextPromptOptions = Parameters<AIService["agentText"]>[1];
152
+
153
+ export function createResearchPrompt(
154
+ params: ResearchPromptParams
155
+ ): AgentTextPromptOptions {
156
+ return {
157
+ prompt: researchPrompt.compile(params),
158
+ };
159
+ }
160
+ ```
161
+
162
+ ### `agentObject`
163
+
164
+ ```ts
165
+ type AgentObjectPromptOptions = Parameters<AIService["agentObject"]>[1];
166
+
167
+ export function createClassificationPrompt(params: ClassificationPromptParams) {
168
+ return {
169
+ schema: classificationSchema,
170
+ prompt: classificationPrompt.compile(params),
171
+ } satisfies AgentObjectPromptOptions;
172
+ }
173
+ ```
174
+
175
+ ## Complex Prompt Composition
176
+
177
+ Complexity belongs behind the factory boundary:
178
+
179
+ - Define reusable `Prompt<Context>` instances at module scope and call
180
+ `.compile(...)` only inside the factory.
181
+ - Use typed lookup maps for category-, locale-, or mode-specific instructions.
182
+ - Select dynamic schemas and `safeSchema` inside the factory.
183
+ - Keep static rules in named constants rather than one enormous interpolated
184
+ template.
185
+ - Put model preferences, retry settings, token profiles, and other generation
186
+ options in the returned object.
187
+ - Return either `prompt` or `messages` according to the target method's type;
188
+ do not build both.
189
+ - Accept domain data such as transcript, category, or locale. Do not accept an
190
+ `AIService`, repository, request context, or other execution dependency.
191
+ - Keep the factory deterministic and free of I/O, logging, mutation, and
192
+ environment reads.
193
+
194
+ ## Do Not
195
+
196
+ ```ts
197
+ // Wrong: exports raw building blocks and makes every caller assemble options.
198
+ export const prompt = new Prompt(...);
199
+ export const schema = z.object(...);
200
+
201
+ // Wrong: returns only a compiled string instead of method parameters.
202
+ export function createEntryPrompt(input: Input) {
203
+ return prompt.compile(input);
204
+ }
205
+
206
+ // Wrong: executes the AI operation in the prompt module.
207
+ export async function createEntryPrompt(ai: AIService, input: Input) {
208
+ return ai.generateObject({ schema, prompt: prompt.compile(input) });
209
+ }
210
+
211
+ // Wrong: multiple public prompt factories in one use-case file.
212
+ export function createEntryPrompt(...) { ... }
213
+ export function createTitlePrompt(...) { ... }
214
+ ```
@@ -5,12 +5,12 @@ catalog:
5
5
  "@heroui/react": 3.0.3
6
6
  "@heroui/styles": 3.0.3
7
7
  "@libsql/client": 0.17.4
8
- "@m5kdev/backend": 0.31.6
9
- "@m5kdev/commons": 0.31.6
10
- "@m5kdev/config": 0.31.6
11
- "@m5kdev/email": 0.31.6
12
- "@m5kdev/frontend": 0.31.6
13
- "@m5kdev/web-ui": 0.31.6
8
+ "@m5kdev/backend": 0.31.9
9
+ "@m5kdev/commons": 0.31.9
10
+ "@m5kdev/config": 0.31.9
11
+ "@m5kdev/email": 0.31.9
12
+ "@m5kdev/frontend": 0.31.9
13
+ "@m5kdev/web-ui": 0.31.9
14
14
  "@playwright/test": 1.57.0
15
15
  "@react-email/components": 1.0.1
16
16
  "@tailwindcss/vite": 4.1.11
@@ -33,7 +33,7 @@ catalog:
33
33
  drizzle-zod: 0.8.3
34
34
  express: 4.21.2
35
35
  i18next: 25.3.2
36
- ioredis: 5.7.0
36
+ ioredis: 5.11.1
37
37
  lucide-react: 0.488.0
38
38
  neverthrow: 8.2.0
39
39
  nuqs: 2.4.3