@mmnto/cli 0.41.0 → 0.43.0

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.
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Universal Baseline Lessons — battle-tested traps extracted from
3
+ * PR reviews in vercel/next.js, facebook/react, trpc/trpc,
4
+ * prisma/prisma, tailwindlabs/tailwindcss, and drizzle-team/drizzle-orm.
5
+ *
6
+ * These ship with `totem init` to give every project immediate value.
7
+ * Each lesson was born from real pain, not theory.
8
+ *
9
+ * @see .strategy/baselines/candidate-prs.md for source PRs
10
+ * @see proposal 028 (mining public baselines)
11
+ */
12
+ export declare const UNIVERSAL_BASELINE_MARKER = "<!-- totem:universal-baseline -->";
13
+ export declare const UNIVERSAL_BASELINE_LESSONS: Array<{
14
+ heading: string;
15
+ tags: string[];
16
+ body: string;
17
+ }>;
18
+ /**
19
+ * Pre-rendered markdown string for writing to `.totem/lessons/baseline.md`.
20
+ * Format matches `parseLessonsFile()` expectations so lessons index correctly.
21
+ */
22
+ export declare const UNIVERSAL_BASELINE_MARKDOWN: string;
23
+ //# sourceMappingURL=universal-baseline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"universal-baseline.d.ts","sourceRoot":"","sources":["../../src/assets/universal-baseline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,eAAO,MAAM,yBAAyB,sCAAsC,CAAC;AAE7E,eAAO,MAAM,0BAA0B,EAAE,KAAK,CAAC;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd,CA2TA,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,2BAA2B,QAM1B,CAAC"}
@@ -0,0 +1,329 @@
1
+ /**
2
+ * Universal Baseline Lessons — battle-tested traps extracted from
3
+ * PR reviews in vercel/next.js, facebook/react, trpc/trpc,
4
+ * prisma/prisma, tailwindlabs/tailwindcss, and drizzle-team/drizzle-orm.
5
+ *
6
+ * These ship with `totem init` to give every project immediate value.
7
+ * Each lesson was born from real pain, not theory.
8
+ *
9
+ * @see .strategy/baselines/candidate-prs.md for source PRs
10
+ * @see proposal 028 (mining public baselines)
11
+ */
12
+ export const UNIVERSAL_BASELINE_MARKER = '<!-- totem:universal-baseline -->';
13
+ export const UNIVERSAL_BASELINE_LESSONS = [
14
+ // ─── Async & Promises ─────────────────────────────
15
+ {
16
+ heading: 'Unhandled promise rejections crash Node processes',
17
+ tags: ['async', 'node', 'universal'],
18
+ body: 'Every async function called without await, and every Promise without a .catch(), is a potential unhandled rejection that crashes the process in Node 15+. Always handle rejections at the call site or use a global handler. Source: vercel/next.js#15049.',
19
+ },
20
+ {
21
+ heading: 'Synchronous assumptions in async boundaries',
22
+ tags: ['async', 'api', 'universal'],
23
+ body: 'Functions that accept callbacks or return values synchronously but are consumed in async contexts (fetch wrappers, middleware, headers) create subtle timing bugs. If a function CAN be async, treat it as async everywhere. Source: trpc/trpc#902.',
24
+ },
25
+ {
26
+ heading: 'Missing state transitions in async lifecycles',
27
+ tags: ['async', 'state', 'universal'],
28
+ body: 'WebSocket connections, database pools, and HTTP clients have distinct states (connecting, open, closing, closed). Skipping a state transition (e.g., marking a connection as "open" without going through "connecting") causes race conditions in reconnection logic. Source: trpc/trpc#5119.',
29
+ },
30
+ // ─── React & Hooks ────────────────────────────────
31
+ {
32
+ heading: 'Stale closure from missing effect dependencies',
33
+ tags: ['react', 'hooks', 'universal'],
34
+ body: 'useEffect and useCallback capture variables from their closure scope. If a dependency is omitted from the array, the callback uses a stale value from a previous render. This causes bugs that are invisible in dev but corrupt state in production. Source: facebook/react#29705.',
35
+ },
36
+ {
37
+ heading: 'Effects must clean up subscriptions and timers',
38
+ tags: ['react', 'hooks', 'universal'],
39
+ body: 'Every useEffect that creates a subscription, timer, or event listener MUST return a cleanup function. Without cleanup, effects leak memory and cause "setState on unmounted component" warnings. React StrictMode double-invokes effects specifically to catch this. Source: facebook/react#30954.',
40
+ },
41
+ {
42
+ heading: 'Impure effects break in StrictMode and Concurrent Mode',
43
+ tags: ['react', 'hooks', 'universal'],
44
+ body: 'Effects that mutate external state (DOM, global variables, network) without idempotency will produce double side-effects when React double-invokes them in development. Design every effect to be safe to run twice. Source: facebook/react#19523.',
45
+ },
46
+ // ─── Server/Client Boundaries ─────────────────────
47
+ {
48
+ heading: 'Server-only code leaking into client bundles',
49
+ tags: ['nextjs', 'ssr', 'universal'],
50
+ body: 'Importing server-side constants, database clients, or API keys in shared modules causes them to be bundled into the client. Move server-only code to dedicated files and use "use server" or "server-only" guards. Source: vercel/next.js#59239.',
51
+ },
52
+ {
53
+ heading: 'Hydration mismatch from environment-dependent rendering',
54
+ tags: ['nextjs', 'ssr', 'universal'],
55
+ body: 'Any rendering that differs between server and client (Date.now(), window checks, random values) causes hydration mismatches. Use useEffect for client-only rendering, not conditional checks in the render body. Source: vercel/next.js#44857.',
56
+ },
57
+ // ─── Environment & Config ─────────────────────────
58
+ {
59
+ heading: 'Runtime crashes from missing environment variables',
60
+ tags: ['config', 'env', 'universal'],
61
+ body: 'Accessing process.env.MY_VAR without validation causes undefined-as-string bugs that surface only in production. Validate ALL required environment variables at build time using a schema (Zod, envalid) and fail fast. Source: t3-oss/create-t3-app#147.',
62
+ },
63
+ {
64
+ heading: 'Build-time vs runtime env var confusion',
65
+ tags: ['config', 'env', 'universal'],
66
+ body: 'Environment variables inlined at build time (NEXT_PUBLIC_, VITE_) are frozen into the bundle. Variables needed at runtime must be read from the server environment, not from the build. Mixing these up causes secrets to leak into client bundles or values to be stale. Source: vercel/next.js#6212.',
67
+ },
68
+ {
69
+ heading: 'Hardcoded localhost URLs in production code',
70
+ tags: ['config', 'url', 'universal'],
71
+ body: 'WebSocket connections, API endpoints, and asset URLs that hardcode localhost or 127.0.0.1 work in dev but break in production. Always derive URLs from configuration or the request context. Source: vercel/next.js#30632.',
72
+ },
73
+ // ─── TypeScript & Types ───────────────────────────
74
+ {
75
+ heading: 'Dropped generic arguments in wrapper functions',
76
+ tags: ['typescript', 'generics', 'universal'],
77
+ body: 'When wrapping a generic function, failing to forward the type parameter narrows the return type to the default. This silently loses type safety for all callers. Always propagate generics through wrapper layers. Source: vercel/next.js#52498.',
78
+ },
79
+ {
80
+ heading: 'Type assertions (as) bypass safety checks',
81
+ tags: ['typescript', 'safety', 'universal'],
82
+ body: '"as unknown as X" and "as any" suppress TypeScript errors without fixing the underlying type mismatch. Every type assertion is a potential runtime crash. Use type guards or schema validation (Zod) at system boundaries instead.',
83
+ },
84
+ // ─── Database & ORM ───────────────────────────────
85
+ {
86
+ heading: 'Schema drift between migrations and actual database',
87
+ tags: ['database', 'migration', 'universal'],
88
+ body: 'The migration history in version control can diverge from the actual database schema if migrations are applied manually or out of order. Always diff the expected schema against the live database before deploying. Source: prisma/prisma#11440.',
89
+ },
90
+ {
91
+ heading: 'Destructive operations without baseline validation',
92
+ tags: ['database', 'safety', 'universal'],
93
+ body: 'Database reset, seed, or migration commands that operate without first validating the current state can destroy production data. Always snapshot or validate state before destructive operations. Source: prisma/prisma#16098.',
94
+ },
95
+ // ─── Performance & Resources ──────────────────────
96
+ {
97
+ heading: 'Synchronous work blocking the main thread',
98
+ tags: ['performance', 'browser', 'universal'],
99
+ body: 'CPU-intensive operations (parsing, sorting, encryption) on the main thread freeze the UI. Use requestIdleCallback, Web Workers, or async chunking for non-critical work. Source: vercel/next.js#14580.',
100
+ },
101
+ {
102
+ heading: 'Unbounded payload sizes in state mechanisms',
103
+ tags: ['performance', 'security', 'universal'],
104
+ body: 'Cookies, headers, localStorage, and URL params have size limits. Storing unbounded data (user preferences, preview data, session state) without size validation causes silent truncation or server errors. Source: vercel/next.js#10831.',
105
+ },
106
+ // ─── CSS & Styling ────────────────────────────────
107
+ {
108
+ heading: 'CSS config changes require full rebuild',
109
+ tags: ['css', 'tailwind', 'universal'],
110
+ body: 'Changes to Tailwind config, PostCSS plugins, or CSS-in-JS theme tokens are not picked up by HMR. The dev server must be restarted. Fail to document this and developers waste hours debugging "why my styles aren\'t updating." Source: tailwindlabs/tailwindcss.',
111
+ },
112
+ // ─── Error Handling ───────────────────────────────
113
+ {
114
+ heading: 'Empty catch blocks hide critical failures',
115
+ tags: ['error-handling', 'universal'],
116
+ body: 'catch (e) {} swallows the error silently. The operation appears to succeed but downstream code operates on undefined or stale data. At minimum, log the error. Better: re-throw or return a typed error result.',
117
+ },
118
+ {
119
+ heading: 'Dev tooling modifying execution paths incorrectly',
120
+ tags: ['dx', 'tooling', 'universal'],
121
+ body: 'Development overlays or debuggers that inject elements or modify the component tree must defer execution until after initial hydration. Injecting UI too early causes position-dependent hooks (like useId) to generate inconsistent values between server and client. Source: vercel/next.js#75199.',
122
+ },
123
+ {
124
+ heading: 'Environment-specific URL handling leaking across boundaries',
125
+ tags: ['config', 'url', 'universal'],
126
+ body: 'Local development often uses specialized protocols (e.g., file:// or turbopack://) that do not exist in production environments. Code handling source maps, static assets, or metadata must normalize these URIs at the environment boundary to prevent broken paths when deployed. Source: vercel/next.js#71489.',
127
+ },
128
+ {
129
+ heading: 'Regex/Matcher divergence between dev and prod runtimes',
130
+ tags: ['routing', 'regex', 'universal'],
131
+ body: 'Middleware matchers or routing regular expressions that rely on environment-specific syntax or Node.js features may fail silently when compiled for Edge or V8 runtimes in production. Always test complex matchers in the target execution environment. Source: vercel/next.js#69602.',
132
+ },
133
+ {
134
+ heading: 'Swallowing critical errors during SSR',
135
+ tags: ['ssr', 'error-handling', 'universal'],
136
+ body: 'Hydration errors or SSR mismatches should not be caught and silenced by generic error boundaries without explicit logging. Masking these errors during development leads to unstable UI state and broken interactive elements in production. Source: vercel/next.js#44857.',
137
+ },
138
+ {
139
+ heading: 'Compiler transforms breaking CSS-in-JS injection',
140
+ tags: ['compiler', 'css', 'universal'],
141
+ body: 'Custom AST transformations or compiler plugins (like SWC/Babel) can inadvertently strip or reorder the styled-component injection tags required by CSS-in-JS libraries. Always ensure CSS extraction logic is preserved during AST compilation. Source: vercel/next.js#34687.',
142
+ },
143
+ {
144
+ heading: 'Internal modules establishing cyclic dependencies on ambient type declarations',
145
+ tags: ['typescript', 'types', 'universal'],
146
+ body: "Internal framework code should never import directly from auto-generated ambient type declaration files (e.g., next-env.d.ts). This creates a cyclic dependency where the framework relies on the user's generated types to compile. Source: vercel/next.js#34394.",
147
+ },
148
+ {
149
+ heading: 'Context flags misaligned during edge compilation',
150
+ tags: ['compiler', 'edge', 'universal'],
151
+ body: 'When compiling code for Edge runtimes, standard environmental flags (like isServer or isClient) must be explicitly handled. Assuming Edge is purely "client" or purely "server" leads to incorrectly stripping required polyfills or exposing sensitive logic. Source: vercel/next.js#30242.',
152
+ },
153
+ {
154
+ heading: 'FS watchers failing to handle atomic file renames',
155
+ tags: ['fs', 'tooling', 'universal'],
156
+ body: 'When building file-system watchers, do not assume files are only "created" or "modified". Editors and OS operations frequently use atomic renames (moving a temp file over an existing file). Failure to handle the "rename" event leads to stale caches and missed updates. Source: vercel/next.js#10351.',
157
+ },
158
+ {
159
+ heading: 'Style injection breaking modular chunk loading',
160
+ tags: ['css', 'bundler', 'universal'],
161
+ body: "Injecting global CSS script tags directly into granular, dynamically loaded JavaScript chunks can cause race conditions or duplicate style definitions. CSS should be extracted and managed by the bundler's dedicated style loader, not inline scripts. Source: vercel/next.js#9306.",
162
+ },
163
+ {
164
+ heading: 'Hardcoding third-party SDK dependencies into core logic',
165
+ tags: ['architecture', 'coupling', 'universal'],
166
+ body: 'Core routing or state management logic should never directly import third-party SDKs (e.g., Auth0, Stripe). Abstract these behind provider interfaces. Hardcoding them prevents replacing the vendor and breaks the application if the SDK is unavailable. Source: vercel/next.js#8802.',
167
+ },
168
+ {
169
+ heading: 'Leaking proprietary rendering logic into generic component trees',
170
+ tags: ['architecture', 'react', 'universal'],
171
+ body: 'Framework-specific rendering paradigms (like AMP or specific SSR wrappers) should not leak down into generic, reusable UI components. Passing framework-specific props deeply into the tree prevents those components from being used in other contexts. Source: vercel/next.js#7669.',
172
+ },
173
+ {
174
+ heading: 'Hook rules violation inside memoization callbacks',
175
+ tags: ['react', 'hooks', 'universal'],
176
+ body: 'Never call a React Hook (useContext, useState) inside the callback function passed to useMemo, useCallback, or React.memo. This breaks the fundamental rule of hooks (call order) because the memoized function is executed unpredictably. Source: facebook/react#14608.',
177
+ },
178
+ {
179
+ heading: 'Race conditions during batched state updates',
180
+ tags: ['react', 'state', 'universal'],
181
+ body: 'When deriving state from props (e.g., getDerivedStateFromProps), assume that multiple state updates might be batched together. Relying on the intermediate state synchronously before the batch completes will result in torn UI or dropped updates. Source: facebook/react#12408.',
182
+ },
183
+ {
184
+ heading: 'Swallowing nested errors across rendering boundaries',
185
+ tags: ['react', 'error-handling', 'universal'],
186
+ body: 'When building error boundaries or guarded execution callbacks, ensure that an error thrown in a deeply nested renderer (like a portal or a custom renderer) correctly bubbles up to the primary boundary. Swallowing cross-boundary errors masks fatal crashes. Source: facebook/react#10270.',
187
+ },
188
+ {
189
+ heading: 'Monolithic structures containing untestable generic utilities',
190
+ tags: ['architecture', 'testing', 'universal'],
191
+ body: 'Do not hide generic, pure utility functions (e.g., string formatting, math calculations) inside massive, stateful class components or UI modules. Extract them into separate files so they can be unit tested in isolation without mocking the DOM. Source: facebook/react#9658.',
192
+ },
193
+ {
194
+ heading: 'Insufficient context in error logging for dynamically typed inputs',
195
+ tags: ['error-handling', 'dx', 'universal'],
196
+ body: 'When throwing errors about invalid inputs (e.g., "Expected a string, got object"), always include a stack trace or the specific key/component name that caused the error. Generic type errors without context are impossible to debug in large trees. Source: facebook/react#8495.',
197
+ },
198
+ {
199
+ heading: 'Silent failures in static lifecycle methods',
200
+ tags: ['react', 'error-handling', 'universal'],
201
+ body: 'Errors thrown inside static lifecycle methods (like getDerivedStateFromProps) can sometimes fail silently if the framework does not explicitly wrap them in a logging boundary, as they execute outside the standard render flow. Always log exceptions at the boundary. Source: facebook/react#15797.',
202
+ },
203
+ {
204
+ heading: 'Serialization failures when passing complex objects to devtools',
205
+ tags: ['tooling', 'serialization', 'universal'],
206
+ body: 'When exposing internal state to DevTools or logger overlays, ensure the payload is serializable. Passing complex objects with circular references, functions, or Symbols will crash the DevTools bridge. Use useDebugValue with a formatter. Source: facebook/react#18070.',
207
+ },
208
+ {
209
+ heading: 'Bypassing standard synthetic event systems for performance',
210
+ tags: ['react', 'events', 'universal'],
211
+ body: "Bypassing the framework's synthetic event system (e.g., attaching raw DOM event listeners) to gain performance often breaks event pooling, batching, and cross-platform compatibility (like React Native). Only bypass the event system when absolutely necessary and document the trade-off. Source: facebook/react#23232.",
212
+ },
213
+ {
214
+ heading: 'Compiler transforms invalidating internal context tracking',
215
+ tags: ['compiler', 'react', 'universal'],
216
+ body: 'When writing AST transforms or compiler optimizations, do not rewrite or reorder calls to `useContext` or other hooks that rely on internal fiber state tracking. Moving a hook call outside of its expected execution context breaks the React runtime. Source: facebook/react#30612.',
217
+ },
218
+ {
219
+ heading: 'Memory leaks caused by calling setState on unmounted components',
220
+ tags: ['react', 'memory', 'universal'],
221
+ body: 'Always cancel active asynchronous requests (fetch, setTimeout) when a component unmounts. Calling `setState` after the component is destroyed causes memory leaks and React warnings. Use AbortController or a mounted flag ref. Source: facebook/react#12531.',
222
+ },
223
+ {
224
+ heading: 'Leaking heavy development-only assertions into production bundles',
225
+ tags: ['performance', 'bundler', 'universal'],
226
+ body: 'Costly validation logic, deep object comparisons, and verbose error strings must be wrapped in `if (__DEV__)` or `if (process.env.NODE_ENV !== "production")` blocks so the bundler can strip them out via Dead Code Elimination. Source: facebook/react#10316.',
227
+ },
228
+ {
229
+ heading: 'Assuming `setState` is synchronous',
230
+ tags: ['react', 'state', 'universal'],
231
+ body: 'Never read `this.state` or a state variable immediately after calling `setState`. State updates are batched and asynchronous. If the next state depends on the previous state, use the updater function form: `setState((prev) => prev + 1)`. Source: facebook/react#9329.',
232
+ },
233
+ {
234
+ heading: 'Evaluating defaultProps before lazy component resolution',
235
+ tags: ['react', 'lazy', 'universal'],
236
+ body: 'When using lazy loading or dynamic imports, do not attempt to merge or evaluate `defaultProps` before the underlying module has fully resolved. This causes synchronous crashes. Defer prop resolution until the render phase. Source: facebook/react#14112.',
237
+ },
238
+ {
239
+ heading: 'Connection pooling leaks in underlying HTTP clients',
240
+ tags: ['database', 'network', 'universal'],
241
+ body: 'When initializing database clients or ORMs (like Prisma), ensure the underlying HTTP client (e.g., undici or node-fetch) has strict timeouts and connection pool limits. Infinite keep-alive connections will exhaust server sockets under load. Source: prisma/prisma#8831.',
242
+ },
243
+ {
244
+ heading: 'Type loss across SQL aggregate boundaries',
245
+ tags: ['database', 'typescript', 'universal'],
246
+ body: 'When executing raw SQL or aggregate functions (`count`, `sum`) in a type-safe ORM, ensure the return type is explicitly cast or parsed. SQL drivers often return aggregates as strings (e.g., "10" instead of 10) to prevent precision loss, breaking TS assumptions. Source: drizzle-team/drizzle-orm#1487.',
247
+ },
248
+ {
249
+ heading: 'Lateral joins breaking query builder schema resolution',
250
+ tags: ['database', 'sql', 'universal'],
251
+ body: 'Advanced SQL features like `LATERAL` joins introduce dynamic scoping where subqueries reference columns from preceding tables. Query builders must correctly resolve these scope chains, or they will generate invalid SQL or lose type safety. Source: drizzle-team/drizzle-orm#1079.',
252
+ },
253
+ {
254
+ heading: 'Driver-specific adapters leaking into core query logic',
255
+ tags: ['database', 'architecture', 'universal'],
256
+ body: 'Keep SQL query generation strictly separated from driver-specific execution (e.g., Postgres vs MySQL vs SQLite). Passing driver connection objects deep into the query builder tightly couples the ORM to a specific database vendor. Source: drizzle-team/drizzle-orm#5222.',
257
+ },
258
+ {
259
+ heading: 'Desync between .env templates and validation schemas',
260
+ tags: ['config', 'env', 'universal'],
261
+ body: 'If you maintain a `.env.example` file and a Zod schema for environment variables, they must be kept in perfect sync. Adding a variable to one without the other causes either failing builds or confusing onboarding experiences. Source: t3-oss/create-t3-app#430.',
262
+ },
263
+ {
264
+ heading: 'Incomplete database lifecycles in scaffolding templates',
265
+ tags: ['database', 'tooling', 'universal'],
266
+ body: 'When providing scripts to setup a project, ensure the database lifecycle is complete: generation, migration, and seeding. Providing a `db:generate` script without a `db:migrate` script leaves the developer in a broken state upon initial launch. Source: t3-oss/create-t3-app#1893.',
267
+ },
268
+ {
269
+ heading: 'Side-effect imports executing out of order due to lack of sorting',
270
+ tags: ['javascript', 'imports', 'universal'],
271
+ body: 'If modules rely on side-effects (e.g., polyfills, global CSS, or environment initializers), the import order is critical. Use an automated tool (like Prettier plugin or ESLint) to deterministically sort imports to prevent fragile execution orders. Source: t3-oss/create-t3-app#1392.',
272
+ },
273
+ {
274
+ heading: 'Hardcoded component logic inside top-level layout files',
275
+ tags: ['architecture', 'react', 'universal'],
276
+ body: 'Root `_app.tsx` or `layout.tsx` files should be as thin as possible, containing only context providers and structure. Hardcoding complex UI logic (like splash screens or modals) directly in the layout makes it impossible to reuse or test. Extract to components. Source: t3-oss/create-t3-app#178.',
277
+ },
278
+ {
279
+ heading: 'Scaffolding scripts failing to respect existing .git states',
280
+ tags: ['tooling', 'git', 'universal'],
281
+ body: 'CLI tools that generate projects (like `create-t3-app` or `totem init`) must check if a `.git` directory already exists before attempting to run `git init`. Blindly initializing git can corrupt an existing repository or submodule structure. Source: t3-oss/create-t3-app#4.',
282
+ },
283
+ {
284
+ heading: 'Specificity overrides breaking AST/string serialization',
285
+ tags: ['css', 'compiler', 'universal'],
286
+ body: 'When parsing or generating CSS (e.g., adding `!important`), ensure the AST formatter correctly handles the spacing and placement of the token. Appending `!important` without respecting the original declaration structure leads to malformed CSS strings. Source: tailwindlabs/tailwindcss#14611.',
287
+ },
288
+ {
289
+ heading: 'Implicit ordering dependencies in CSS cascade generation',
290
+ tags: ['css', 'architecture', 'universal'],
291
+ body: 'When generating utility classes (like Tailwind), the final output order determines the CSS cascade specificity. Do not rely on the implicit order of object keys in JavaScript. Use explicit directives (`@layer`, `@tailwind`) to guarantee the cascade order. Source: tailwindlabs/tailwindcss#88.',
292
+ },
293
+ // ─── AI-Assisted Workflows (Solo Dev / Cursor Guardrails) ─────────
294
+ {
295
+ heading: 'Isolation of localized component changes',
296
+ tags: ['workflow', 'ai-agent', 'universal'],
297
+ body: 'When asked to implement a local feature (e.g., adding a button state), DO NOT rewrite the surrounding layout, change the CSS framework, or refactor sibling components unless explicitly instructed. Isolate the state change locally to prevent cascading breakages.',
298
+ },
299
+ {
300
+ heading: 'Premature abstraction of duplicated code',
301
+ tags: ['architecture', 'ai-agent', 'universal'],
302
+ body: 'Do not abstract repetitive code (like fetch calls or UI wrappers) into complex generic utilities until the exact pattern has been duplicated at least three times in separate domains (The Rule of Three). Premature generic abstraction ruins prototyping velocity.',
303
+ },
304
+ {
305
+ heading: 'Silent failures and "TODO" placeholders',
306
+ tags: ['workflow', 'dx', 'universal'],
307
+ body: 'If a requested feature cannot be fully implemented due to missing context or complexity, you MUST throw an explicit error or insert a highly visible UI warning (e.g., `<div style="color:red">NOT IMPLEMENTED</div>`). Never fail silently by returning null or leaving a hidden `// TODO` comment.',
308
+ },
309
+ {
310
+ heading: 'Monolithic file generation',
311
+ tags: ['architecture', 'ai-agent', 'universal'],
312
+ body: 'When generating new features, actively resist dumping all logic into a single 500+ line file. If a file grows beyond a single distinct responsibility, you must immediately extract its sub-components or utilities into sibling files before proceeding with the feature.',
313
+ },
314
+ {
315
+ heading: 'Destructive architectural refactoring without permission',
316
+ tags: ['workflow', 'safety', 'universal'],
317
+ body: 'Never alter the fundamental architecture of the project (e.g., switching from App Router to Pages Router, changing the ORM paradigm, or moving directories) as a side-effect of fulfilling a smaller feature request. Architectural shifts require explicit human approval.',
318
+ },
319
+ ];
320
+ /**
321
+ * Pre-rendered markdown string for writing to `.totem/lessons/baseline.md`.
322
+ * Format matches `parseLessonsFile()` expectations so lessons index correctly.
323
+ */
324
+ export const UNIVERSAL_BASELINE_MARKDOWN = [
325
+ UNIVERSAL_BASELINE_MARKER,
326
+ '',
327
+ ...UNIVERSAL_BASELINE_LESSONS.map((l) => `## Lesson — ${l.heading}\n\n**Tags:** ${l.tags.join(', ')}\n\n${l.body}`),
328
+ ].join('\n\n');
329
+ //# sourceMappingURL=universal-baseline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"universal-baseline.js","sourceRoot":"","sources":["../../src/assets/universal-baseline.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../src/commands/compile.ts"],"names":[],"mappings":"AA2FA,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,wBAAsB,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAuL3E"}
1
+ {"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../src/commands/compile.ts"],"names":[],"mappings":"AA6GA,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,wBAAsB,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAmM3E"}
@@ -1,7 +1,3 @@
1
- import * as path from 'node:path';
2
- import { exportLessons, hashLesson, loadCompiledRulesFile, parseCompilerResponse, readAllLessons, saveCompiledRulesFile, validateRegex, } from '@mmnto/totem';
3
- import { log } from '../ui.js';
4
- import { loadConfig, loadEnv, resolveConfigPath, runOrchestrator } from '../utils.js';
5
1
  // ─── Constants ──────────────────────────────────────
6
2
  const TAG = 'Compile';
7
3
  const COMPILED_RULES_FILE = 'compiled-rules.json';
@@ -23,6 +19,14 @@ You are a deterministic rule compiler. Your job is to read a single natural-lang
23
19
  - **By package/directory:** \`["packages/mcp/**/*.ts"]\` — for rules about MCP-specific patterns in a monorepo.
24
20
  - **By exclusion:** \`["packages/cli/**/*.ts", "!**/*.test.ts"]\` — exclude test files that legitimately use the flagged pattern.
25
21
  - **Infer scope from context:** If a lesson mentions "MCP tool returns", "CLI output", "LanceDB filters", or a specific package, scope to that package. Only omit \`fileGlobs\` if the rule genuinely applies to ALL files (e.g., universal TypeScript style rules).
22
+ - **CRITICAL — Supported glob syntax only:**
23
+ - \`*.ext\` — match extension anywhere
24
+ - \`dir/**/*.ext\` — directory + recursive + extension
25
+ - \`dir/**\` — everything under directory
26
+ - \`dir/*.ext\` — direct children only
27
+ - \`!pattern\` — negation prefix
28
+ - **DO NOT use** brace expansion \`{a,b}\`, nested globstars \`**/dir/**\`, or regex-style patterns.
29
+ - **DO NOT use** \`**/*.{ts,js}\`. Instead use separate entries: \`["**/*.ts", "**/*.js"]\`.
26
30
 
27
31
  ## Output Schema
28
32
  \`\`\`json
@@ -70,7 +74,34 @@ Output: {"compilable": true, "pattern": "text:\\\\s*(?!formatXmlResponse)\\\\b\\
70
74
  Lesson: "Use @clack/prompts instead of inquirer for CLI interactions"
71
75
  Output: {"compilable": true, "pattern": "import.*from\\\\s+['\"]inquirer['\"]", "message": "Use @clack/prompts instead of inquirer", "fileGlobs": ["packages/cli/**/*.ts"]}
72
76
  `;
77
+ // ─── Glob sanitization ─────────────────────────────
78
+ /**
79
+ * Expand brace patterns and strip unsupported glob syntax.
80
+ * e.g., "**\/*.{ts,js}" → ["**\/*.ts", "**\/*.js"]
81
+ */
82
+ function sanitizeFileGlobs(globs) {
83
+ const result = [];
84
+ for (const glob of globs) {
85
+ // Expand brace patterns: **/*.{ts,js} → **/*.ts, **/*.js
86
+ const braceMatch = /^(.*)\{([^}]+)\}(.*)$/.exec(glob);
87
+ if (braceMatch) {
88
+ const prefix = braceMatch[1];
89
+ const alternatives = braceMatch[2].split(',').map((s) => s.trim());
90
+ const suffix = braceMatch[3];
91
+ for (const alt of alternatives) {
92
+ result.push(prefix + alt + suffix);
93
+ }
94
+ continue;
95
+ }
96
+ result.push(glob);
97
+ }
98
+ return result;
99
+ }
73
100
  export async function compileCommand(options) {
101
+ const path = await import('node:path');
102
+ const { log } = await import('../ui.js');
103
+ const { loadConfig, loadEnv, resolveConfigPath, runOrchestrator } = await import('../utils.js');
104
+ const { exportLessons, hashLesson, loadCompiledRulesFile, parseCompilerResponse, readAllLessons, saveCompiledRulesFile, validateRegex, } = await import('@mmnto/totem');
74
105
  const cwd = process.cwd();
75
106
  const configPath = resolveConfigPath(cwd);
76
107
  loadEnv(cwd);
@@ -177,6 +208,7 @@ export async function compileCommand(options) {
177
208
  }
178
209
  const now = new Date().toISOString();
179
210
  const existing = existingByHash.get(lesson.hash);
211
+ const sanitizedGlobs = parsed.fileGlobs ? sanitizeFileGlobs(parsed.fileGlobs) : undefined;
180
212
  newRules.push({
181
213
  lessonHash: lesson.hash,
182
214
  lessonHeading: lesson.heading,
@@ -185,9 +217,7 @@ export async function compileCommand(options) {
185
217
  engine: 'regex',
186
218
  compiledAt: now,
187
219
  createdAt: existing?.createdAt ?? now,
188
- ...(parsed.fileGlobs && parsed.fileGlobs.length > 0
189
- ? { fileGlobs: parsed.fileGlobs }
190
- : {}),
220
+ ...(sanitizedGlobs && sanitizedGlobs.length > 0 ? { fileGlobs: sanitizedGlobs } : {}),
191
221
  });
192
222
  compiled++;
193
223
  log.success(TAG, `[${lesson.heading}] Compiled: /${parsed.pattern}/`); // totem-ignore
@@ -1 +1 @@
1
- {"version":3,"file":"compile.js","sourceRoot":"","sources":["../../src/commands/compile.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"compile.js","sourceRoot":"","sources":["../../src/commands/compile.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,QAAQ,MAAM,wBAAwB,CAAC;AAInD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAWjD,eAAO,MAAM,cAAc,IAAI,CAAC;AAMhC,eAAO,MAAM,eAAe,gvJA4C3B,CAAC;AAaF,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IACpD,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAUD,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAInF;AAID;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,MAAM,GAAE,MAA0B,GACjC;IAAE,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAqB5D;AAuID;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG;IACrD,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IACzC,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAuDA;AAgFD,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACnC;IAAE,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAoD5D;AAyFD,KAAK,aAAa,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE7D,wBAAsB,cAAc,CAClC,OAAO,EAAE,YAAY,EAAE,EACvB,aAAa,EAAE,aAAa,GAC3B,OAAO,CAAC,MAAM,CAAC,CA6CjB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAoB9D;AAED;;;;GAIG;AACH,wBAAsB,sBAAsB,CAC1C,YAAY,EAAE,MAAM,EACpB,EAAE,EAAE,QAAQ,CAAC,SAAS,GACrB,OAAO,CAAC,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAC,CA6B7C;AAID,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;AAE9D,kFAAkF;AAClF,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAchE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CA+BpF;AAgCD,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAuVjD"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,QAAQ,MAAM,wBAAwB,CAAC;AAInD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAcjD,eAAO,MAAM,cAAc,IAAI,CAAC;AAMhC,eAAO,MAAM,eAAe,gvJA4C3B,CAAC;AAaF,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IACpD,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAUD,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAInF;AAID;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,MAAM,GAAE,MAA0B,GACjC;IAAE,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAqB5D;AAuID;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG;IACrD,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IACzC,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAuDA;AAgFD,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACnC;IAAE,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAoD5D;AAyFD,KAAK,aAAa,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE7D,wBAAsB,cAAc,CAClC,OAAO,EAAE,YAAY,EAAE,EACvB,aAAa,EAAE,aAAa,GAC3B,OAAO,CAAC,MAAM,CAAC,CA6CjB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAqB9D;AAED;;;;GAIG;AACH,wBAAsB,sBAAsB,CAC1C,YAAY,EAAE,MAAM,EACpB,EAAE,EAAE,QAAQ,CAAC,SAAS,GACrB,OAAO,CAAC,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAC,CAiC7C;AAID,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;AAE9D,kFAAkF;AAClF,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAchE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CA+BpF;AAgCD,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAuVjD"}
@@ -3,7 +3,7 @@ import * as path from 'node:path';
3
3
  import { stdin as input, stdout as output } from 'node:process';
4
4
  import * as readline from 'node:readline/promises';
5
5
  import { z } from 'zod';
6
- import { BASELINE_MARKER, UNIVERSAL_LESSONS_MARKDOWN } from '../assets/universal-lessons.js';
6
+ import { UNIVERSAL_BASELINE_MARKDOWN, UNIVERSAL_BASELINE_MARKER, } from '../assets/universal-baseline.js';
7
7
  import { bold, brand, dim, log, printBanner, success } from '../ui.js';
8
8
  import { IS_WIN } from '../utils.js';
9
9
  import { installEnforcementHooks, installPostMergeHook } from './install-hooks.js';
@@ -487,20 +487,20 @@ export default config;
487
487
  * Checks for API keys in env and .env, and optionally for a running Ollama instance.
488
488
  */
489
489
  export function detectEmbeddingTier(cwd) {
490
- // Check env (including already-loaded .env)
491
- if (process.env['OPENAI_API_KEY'] && /\S/.test(process.env['OPENAI_API_KEY']))
492
- return 'openai';
493
490
  // Read .env file once (loadEnv may not have run yet)
494
491
  const envPath = path.join(cwd, '.env');
495
492
  const envContent = fs.existsSync(envPath) ? fs.readFileSync(envPath, 'utf-8') : '';
496
- if (/^\s*OPENAI_API_KEY\s*=\s*\S+/m.test(envContent))
497
- return 'openai';
498
- // Gemini: single-key DX — GEMINI_API_KEY covers both orchestrator and embeddings
499
- if ((process.env['GEMINI_API_KEY'] && /\S/.test(process.env['GEMINI_API_KEY'])) ||
493
+ const hasGemini = (process.env['GEMINI_API_KEY'] && /\S/.test(process.env['GEMINI_API_KEY'])) ||
500
494
  (process.env['GOOGLE_API_KEY'] && /\S/.test(process.env['GOOGLE_API_KEY'])) ||
501
- /^\s*(?:GEMINI_API_KEY|GOOGLE_API_KEY)\s*=\s*\S+/m.test(envContent)) {
495
+ /^\s*(?:GEMINI_API_KEY|GOOGLE_API_KEY)\s*=\s*\S+/m.test(envContent);
496
+ const hasOpenai = (process.env['OPENAI_API_KEY'] && /\S/.test(process.env['OPENAI_API_KEY'])) ||
497
+ /^\s*OPENAI_API_KEY\s*=\s*\S+/m.test(envContent);
498
+ // Gemini first — task-type aware embeddings, best retrieval quality
499
+ if (hasGemini)
502
500
  return 'gemini';
503
- }
501
+ // OpenAI — widely available, low friction
502
+ if (hasOpenai)
503
+ return 'openai';
504
504
  return 'none';
505
505
  }
506
506
  /**
@@ -512,7 +512,8 @@ export async function installBaselineLessons(baselinePath, rl) {
512
512
  try {
513
513
  if (fs.existsSync(baselinePath)) {
514
514
  const existing = fs.readFileSync(baselinePath, 'utf-8');
515
- if (existing.includes(BASELINE_MARKER))
515
+ if (existing.includes(UNIVERSAL_BASELINE_MARKER) ||
516
+ existing.includes('<!-- totem:baseline -->'))
516
517
  return 'exists';
517
518
  }
518
519
  // In non-TTY mode (CI, piped input), default to installing
@@ -527,7 +528,7 @@ export async function installBaselineLessons(baselinePath, rl) {
527
528
  if (!fs.existsSync(dir)) {
528
529
  fs.mkdirSync(dir, { recursive: true });
529
530
  }
530
- fs.writeFileSync(baselinePath, UNIVERSAL_LESSONS_MARKDOWN, 'utf-8');
531
+ fs.writeFileSync(baselinePath, UNIVERSAL_BASELINE_MARKDOWN, 'utf-8');
531
532
  return 'installed';
532
533
  }
533
534
  catch (err) {