@jaypie/mcp 0.1.10 → 0.2.1

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 (41) hide show
  1. package/dist/datadog.d.ts +212 -0
  2. package/dist/index.js +1461 -6
  3. package/dist/index.js.map +1 -1
  4. package/package.json +9 -5
  5. package/prompts/Development_Process.md +57 -35
  6. package/prompts/Jaypie_CDK_Constructs_and_Patterns.md +143 -19
  7. package/prompts/Jaypie_Express_Package.md +35 -15
  8. package/prompts/Jaypie_Init_Express_on_Lambda.md +66 -38
  9. package/prompts/Jaypie_Init_Lambda_Package.md +202 -83
  10. package/prompts/Jaypie_Init_Project_Subpackage.md +21 -26
  11. package/prompts/Jaypie_Legacy_Patterns.md +4 -0
  12. package/prompts/Jaypie_Repokit.md +103 -0
  13. package/prompts/Templates_CDK_Subpackage.md +113 -0
  14. package/prompts/Templates_Express_Subpackage.md +183 -0
  15. package/prompts/Templates_Project_Monorepo.md +326 -0
  16. package/prompts/Templates_Project_Subpackage.md +93 -0
  17. package/prompts/Jaypie_Mongoose_Models_Package.md +0 -231
  18. package/prompts/Jaypie_Mongoose_with_Express_CRUD.md +0 -1000
  19. package/prompts/templates/cdk-subpackage/bin/cdk.ts +0 -11
  20. package/prompts/templates/cdk-subpackage/cdk.json +0 -19
  21. package/prompts/templates/cdk-subpackage/lib/cdk-app.ts +0 -41
  22. package/prompts/templates/cdk-subpackage/lib/cdk-infrastructure.ts +0 -15
  23. package/prompts/templates/express-subpackage/index.ts +0 -8
  24. package/prompts/templates/express-subpackage/src/app.ts +0 -18
  25. package/prompts/templates/express-subpackage/src/handler.config.ts +0 -44
  26. package/prompts/templates/express-subpackage/src/routes/resource/__tests__/resourceGet.route.spec.ts +0 -29
  27. package/prompts/templates/express-subpackage/src/routes/resource/resourceGet.route.ts +0 -22
  28. package/prompts/templates/express-subpackage/src/routes/resource.router.ts +0 -11
  29. package/prompts/templates/express-subpackage/src/types/express.ts +0 -9
  30. package/prompts/templates/project-monorepo/.vscode/settings.json +0 -72
  31. package/prompts/templates/project-monorepo/eslint.config.mjs +0 -1
  32. package/prompts/templates/project-monorepo/gitignore +0 -11
  33. package/prompts/templates/project-monorepo/package.json +0 -20
  34. package/prompts/templates/project-monorepo/tsconfig.base.json +0 -18
  35. package/prompts/templates/project-monorepo/tsconfig.json +0 -6
  36. package/prompts/templates/project-monorepo/vitest.workspace.js +0 -3
  37. package/prompts/templates/project-subpackage/package.json +0 -16
  38. package/prompts/templates/project-subpackage/tsconfig.json +0 -11
  39. package/prompts/templates/project-subpackage/vite.config.ts +0 -21
  40. package/prompts/templates/project-subpackage/vitest.config.ts +0 -7
  41. package/prompts/templates/project-subpackage/vitest.setup.ts +0 -6
@@ -25,10 +25,10 @@ Create AWS Lambda functions that integrate with Jaypie for event-driven processi
25
25
  ```
26
26
  packages/lambda/
27
27
  ├── package.json # Define dependencies and scripts
28
- ├── tsconfig.json # TypeScript configuration
29
- ├── rollup.config.ts # Bundle configuration
30
- ├── vitest.config.ts # Test configuration
31
- ├── vitest.setup.ts # Test setup and mocks
28
+ ├── tsconfig.json # TypeScript configuration
29
+ ├── rollup.config.mjs # Bundle configuration
30
+ ├── vite.config.js # Test configuration
31
+ ├── testSetup.ts # Test setup and matchers
32
32
  └── src/
33
33
  ├── index.ts # Export handlers
34
34
  ├── worker.ts # Lambda function implementation
@@ -43,21 +43,37 @@ packages/lambda/
43
43
  "name": "@yourorg/lambda",
44
44
  "version": "0.1.0",
45
45
  "type": "module",
46
- "main": "dist/index.js",
47
- "types": "dist/index.d.ts",
46
+ "exports": {
47
+ ".": {
48
+ "types": "./dist/esm/index.d.ts",
49
+ "import": "./dist/esm/index.js",
50
+ "require": "./dist/cjs/index.cjs"
51
+ }
52
+ },
53
+ "main": "./dist/cjs/index.cjs",
54
+ "module": "./dist/esm/index.js",
55
+ "types": "./dist/esm/index.d.ts",
56
+ "files": [
57
+ "dist"
58
+ ],
48
59
  "scripts": {
49
60
  "build": "rollup --config",
61
+ "format": "npm run format:package && npm run format:lint",
62
+ "format:lint": "eslint --fix .",
63
+ "format:package": "sort-package-json ./package.json",
50
64
  "lint": "eslint .",
51
- "test": "vitest run",
65
+ "test": "vitest run .",
52
66
  "typecheck": "tsc --noEmit"
53
67
  },
54
68
  "dependencies": {
55
- "jaypie": "^1.1.0"
69
+ "@jaypie/core": "^1.1.0",
70
+ "@jaypie/lambda": "^1.1.0"
56
71
  },
57
72
  "devDependencies": {
58
73
  "@rollup/plugin-typescript": "^12.0.0",
59
74
  "@types/aws-lambda": "^8.10.0",
60
75
  "rollup": "^4.0.0",
76
+ "rollup-plugin-auto-external": "^2.0.0",
61
77
  "typescript": "^5.0.0"
62
78
  }
63
79
  }
@@ -74,107 +90,124 @@ packages/lambda/
74
90
  "declaration": true,
75
91
  "outDir": "./dist",
76
92
  "strict": true,
77
- "esModuleInterop": true
93
+ "esModuleInterop": true,
94
+ "skipLibCheck": true,
95
+ "forceConsistentCasingInFileNames": true
78
96
  },
79
97
  "include": ["src/**/*"],
80
- "exclude": ["node_modules", "dist"]
98
+ "exclude": ["node_modules", "dist", "src/__tests__"]
81
99
  }
82
100
  ```
83
101
 
84
102
  ### 4. Configure Rollup
85
103
 
86
- ```typescript
104
+ Create `rollup.config.mjs`:
105
+
106
+ ```javascript
107
+ import autoExternal from "rollup-plugin-auto-external";
87
108
  import typescript from "@rollup/plugin-typescript";
88
- import type { RollupOptions } from "rollup";
89
109
 
90
- const config: RollupOptions[] = [
110
+ export default [
111
+ // ES modules version
91
112
  {
92
- input: "src/worker.ts",
113
+ input: "src/index.ts",
93
114
  output: {
94
- file: "dist/worker.js",
115
+ dir: "dist/esm",
95
116
  format: "es",
96
- sourcemap: true
117
+ sourcemap: true,
97
118
  },
98
119
  plugins: [
120
+ autoExternal(),
99
121
  typescript({
100
- exclude: ["**/__tests__/**/*"]
101
- })
122
+ tsconfig: "./tsconfig.json",
123
+ declaration: true,
124
+ outDir: "dist/esm",
125
+ }),
102
126
  ],
103
- external: ["jaypie"]
104
127
  },
128
+ // CommonJS version
105
129
  {
106
130
  input: "src/index.ts",
107
131
  output: {
108
- file: "dist/index.js",
109
- format: "es",
110
- sourcemap: true
132
+ dir: "dist/cjs",
133
+ format: "cjs",
134
+ sourcemap: true,
135
+ exports: "named",
136
+ entryFileNames: "[name].cjs",
111
137
  },
112
138
  plugins: [
139
+ autoExternal(),
113
140
  typescript({
114
- exclude: ["**/__tests__/**/*"]
115
- })
141
+ tsconfig: "./tsconfig.json",
142
+ declaration: true,
143
+ outDir: "dist/cjs",
144
+ }),
116
145
  ],
117
- external: ["jaypie"]
118
- }
146
+ },
119
147
  ];
120
-
121
- export default config;
122
148
  ```
123
149
 
124
150
  ### 5. Setup Vitest
125
151
 
126
- ```typescript
127
- // vitest.config.ts
152
+ Create `vite.config.js`:
153
+
154
+ ```javascript
155
+ /// <reference types="vitest" />
156
+
128
157
  import { defineConfig } from "vite";
129
158
 
130
159
  export default defineConfig({
131
160
  test: {
132
- setupFiles: ["./vitest.setup.ts"]
133
- }
161
+ setupFiles: ["./testSetup.ts"],
162
+ },
134
163
  });
164
+ ```
135
165
 
136
- // vitest.setup.ts
166
+ Create `testSetup.ts`:
167
+
168
+ ```typescript
137
169
  import { matchers as jaypieMatchers } from "@jaypie/testkit";
138
170
  import * as extendedMatchers from "jest-extended";
139
- import { expect, vi } from "vitest";
171
+ import { expect } from "vitest";
140
172
 
141
173
  expect.extend(extendedMatchers);
142
174
  expect.extend(jaypieMatchers);
143
-
144
- vi.mock("jaypie", async () => vi.importActual("@jaypie/testkit/mock"));
145
175
  ```
146
176
 
177
+ Note: Do not mock `jaypie` in the setup file for lambda consumer packages. Mock in individual test files as needed.
178
+
147
179
  ### 6. Create Handler Implementation
148
180
 
149
181
  ```typescript
150
182
  // src/worker.ts
151
- import { lambdaHandler, log } from "jaypie";
152
- import type { Context } from "jaypie";
183
+ import { log } from "@jaypie/core";
184
+ import { lambdaHandler } from "@jaypie/lambda";
185
+ import type { LambdaContext } from "@jaypie/lambda";
153
186
 
154
187
  export interface WorkerEvent {
155
188
  message?: string;
156
189
  }
157
190
 
158
191
  export const handler = lambdaHandler(
159
- async (event: WorkerEvent, context: Context) => {
192
+ async (event: WorkerEvent, context?: LambdaContext) => {
160
193
  log.trace("worker: start");
161
-
194
+
162
195
  const message = event?.message || "Hello, world!";
163
-
196
+
164
197
  log.trace("worker: processing message", { message });
165
-
198
+
166
199
  const response = {
167
200
  status: "success",
168
201
  message,
169
- timestamp: new Date().toISOString()
202
+ timestamp: new Date().toISOString(),
170
203
  };
171
-
204
+
172
205
  log.trace("worker: complete");
173
206
  return response;
174
207
  },
175
208
  {
176
- name: "worker"
177
- }
209
+ name: "worker",
210
+ },
178
211
  );
179
212
  ```
180
213
 
@@ -187,59 +220,145 @@ export { handler as workerHandler } from "./worker.js";
187
220
 
188
221
  ### 8. Write Tests
189
222
 
223
+ Tests are organized in sections: Base Cases, Error Conditions, Security, Observability, Happy Paths, Features, Specific Scenarios. Omit sections that are not applicable.
224
+
190
225
  ```typescript
191
226
  // src/__tests__/worker.spec.ts
192
- import { vi, describe, it, expect, beforeEach } from "vitest";
193
- import { handler, WorkerEvent } from "../worker.js";
194
- import { log } from "jaypie";
195
- import type { Context } from "jaypie";
227
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
228
+
229
+ import { log } from "@jaypie/core";
230
+ import { restoreLog, spyLog } from "@jaypie/testkit";
231
+
232
+ // Subject
233
+ import { handler } from "../worker.js";
234
+ import type { WorkerEvent } from "../worker.js";
235
+
236
+ //
237
+ //
238
+ // Mock modules
239
+ //
196
240
 
197
- vi.mock("jaypie", async () => vi.importActual("@jaypie/testkit/mock"));
241
+ vi.mock("@jaypie/core", async () => {
242
+ const actual = await vi.importActual("@jaypie/core");
243
+ return {
244
+ ...actual,
245
+ };
246
+ });
247
+
248
+ //
249
+ //
250
+ // Mock environment
251
+ //
252
+
253
+ const DEFAULT_ENV = process.env;
254
+ beforeEach(() => {
255
+ process.env = { ...process.env };
256
+ spyLog(log);
257
+ });
258
+ afterEach(() => {
259
+ process.env = DEFAULT_ENV;
260
+ vi.clearAllMocks();
261
+ restoreLog(log);
262
+ });
263
+
264
+ //
265
+ //
266
+ // Run tests
267
+ //
198
268
 
199
269
  describe("worker Lambda handler", () => {
200
- beforeEach(() => {
201
- vi.clearAllMocks();
270
+ describe("Base Cases", () => {
271
+ it("Works", async () => {
272
+ const event: WorkerEvent = {};
273
+ const result = await handler(event);
274
+ expect(result).toBeDefined();
275
+ });
202
276
  });
203
277
 
204
- it("returns success with provided message", async () => {
205
- const event: WorkerEvent = {
206
- message: "Test message"
207
- };
208
-
209
- const result = await handler(event, {} as Context);
210
-
211
- expect(result).toHaveProperty("status", "success");
212
- expect(result).toHaveProperty("message", "Test message");
213
- expect(result).toHaveProperty("timestamp");
278
+ describe("Observability", () => {
279
+ it("Does not log above trace", async () => {
280
+ const event: WorkerEvent = { message: "Test" };
281
+ await handler(event);
282
+ expect(log).not.toBeCalledAboveTrace();
283
+ });
214
284
  });
215
285
 
216
- it("returns default message when none provided", async () => {
217
- const event = {} as WorkerEvent;
286
+ describe("Happy Paths", () => {
287
+ it("Returns success with provided message", async () => {
288
+ const event: WorkerEvent = {
289
+ message: "Test message",
290
+ };
218
291
 
219
- const result = await handler(event, {} as Context);
220
-
221
- expect(result).toHaveProperty("message", "Hello, world!");
222
- });
292
+ const result = await handler(event);
223
293
 
224
- it("logs trace for operations", async () => {
225
- const event: WorkerEvent = {
226
- message: "Test message"
227
- };
294
+ expect(result).toHaveProperty("status", "success");
295
+ expect(result).toHaveProperty("message", "Test message");
296
+ expect(result).toHaveProperty("timestamp");
297
+ });
298
+
299
+ it("Returns default message when none provided", async () => {
300
+ const event: WorkerEvent = {};
228
301
 
229
- await handler(event, {} as Context);
230
-
231
- expect(log.trace).toHaveBeenCalled();
232
- expect(log).not.toBeCalledAboveTrace();
302
+ const result = await handler(event);
303
+
304
+ expect(result).toHaveProperty("message", "Hello, world!");
305
+ });
233
306
  });
234
307
  });
235
308
  ```
236
309
 
237
- ### 9. Build and Deploy
310
+ ### 9. Build and Test
311
+
312
+ Build, lint, typecheck, and test the package:
238
313
 
239
314
  ```bash
240
- # Build the Lambda package
241
- npm run build
315
+ # Install dependencies (from monorepo root)
316
+ npm install <package> -w packages/lambda
317
+
318
+ # Lint and format
319
+ npm run format -w packages/lambda
320
+
321
+ # Type check
322
+ npm run typecheck -w packages/lambda
323
+
324
+ # Build the package
325
+ npm run build -w packages/lambda
326
+
327
+ # Run tests
328
+ npm run test -w packages/lambda
329
+ ```
330
+
331
+ ### 10. Deploy
332
+
333
+ Deploy using AWS CDK or other deployment tool. The Lambda handler will be referenced as "workerHandler" from the built package.
334
+
335
+ ## Important Notes
336
+
337
+ ### Import Patterns
338
+
339
+ - Import `lambdaHandler` from `@jaypie/lambda`, not from `jaypie`
340
+ - Import `log` from `@jaypie/core`, not from `jaypie`
341
+ - Use `LambdaContext` type from `@jaypie/lambda`, not `Context` from `jaypie`
342
+ - TypeScript files must use `.js` extension in relative imports (e.g., `from "./worker.js"`)
343
+
344
+ ### Test Structure
345
+
346
+ - Tests are organized in 7 sections: Base Cases, Error Conditions, Security, Observability, Happy Paths, Features, Specific Scenarios
347
+ - Omit sections that are not applicable
348
+ - Use `spyLog` and `restoreLog` from `@jaypie/testkit` for logging tests
349
+ - Use Jaypie matchers like `toBeCalledAboveTrace()` for observability tests
350
+ - Mock `@jaypie/core` in test files, not in `testSetup.ts`
351
+
352
+ ### Build Configuration
353
+
354
+ - Use `rollup-plugin-auto-external` to automatically exclude dependencies from bundles
355
+ - Build both ESM and CommonJS formats for maximum compatibility
356
+ - Use `vite.config.js` (not `vitest.config.ts`) for test configuration
357
+ - Use `testSetup.ts` (not `vitest.setup.ts`) for test setup
358
+
359
+ ### Code Style
242
360
 
243
- # Deploy using AWS CDK or other deployment tool
244
- # The Lambda handler will be referenced as "workerHandler"
245
- ```
361
+ - Use double quotes, trailing commas, semicolons
362
+ - Alphabetize imports and properties
363
+ - Define constants for hard-coded values at file top
364
+ - Never throw vanilla Error; use errors from `@jaypie/errors`
@@ -15,10 +15,11 @@ Create a subpackage within an existing monorepo project.
15
15
 
16
16
  ## Guidelines
17
17
 
18
- * Follow Jaypie_Project_Structure.md conventions
19
- * Subpackage names follow "@project-org/package-name" pattern
18
+ * Follow Jaypie_Ideal_Project_Structure.md conventions
19
+ * Subpackage names follow "@project-org/package-name" pattern (example: "@jaypie/errors")
20
20
  * Use `"version": "0.0.1"`, `"type": "module"`, and `"private": true`
21
21
  * Place packages in `packages/<package-name>/` directory
22
+ * Build tool: Use Vite for new TypeScript packages (template uses Vite). Some older packages use Rollup.
22
23
 
23
24
  ## Process
24
25
 
@@ -30,12 +31,12 @@ Create a subpackage within an existing monorepo project.
30
31
  └── tsconfig.json
31
32
  ```
32
33
 
33
- 2. Copy template files:
34
- * Copy `prompts/templates/project-subpackage/package.json` to `packages/<package-name>/package.json`
35
- * Copy `prompts/templates/project-subpackage/tsconfig.json` to `packages/<package-name>/tsconfig.json`
36
- * Copy `prompts/templates/project-subpackage/vite.config.ts` to `packages/<package-name>/vite.config.ts`
37
- * Copy `prompts/templates/project-subpackage/vitest.config.ts` to `packages/<package-name>/vitest.config.ts`
38
- * Copy `prompts/templates/project-subpackage/vitest.setup.ts` to `packages/<package-name>/vitest.setup.ts`
34
+ 2. Create template files using Templates_Project_Subpackage.md:
35
+ * Create `packages/<package-name>/package.json` from template
36
+ * Create `packages/<package-name>/tsconfig.json` from template
37
+ * Create `packages/<package-name>/vite.config.ts` from template
38
+ * Create `packages/<package-name>/vitest.config.ts` from template
39
+ * Create `packages/<package-name>/vitest.setup.ts` from template
39
40
 
40
41
  3. Update package.json:
41
42
  * Edit name from "@project-org/project-name" to "@project-org/<package-name>"
@@ -43,28 +44,22 @@ Create a subpackage within an existing monorepo project.
43
44
 
44
45
  4. Create basic src structure:
45
46
  * Create `src/index.ts` with basic export
46
- * Create `src/index.spec.ts` with basic test
47
+ * Create `src/__tests__/` directory for tests
48
+ * Create `src/__tests__/index.spec.ts` with basic test (use sections: Base Cases, Happy Paths)
47
49
 
48
50
  5. Update workspace configuration:
49
- * Update `references` in root `tsconfig.json`
50
- * Update `paths` in root `tsconfig.base.json`
51
- * Add package path to root `vitest.workspace.js`
52
- * Remove wildcards from `vitest.workspace.js` if present
51
+ * Add package path to `test.projects` array in root `vitest.config.ts` (format: "packages/<package-name>")
52
+ * Ensure packages are listed explicitly (no wildcards)
53
+ * Example: Add "packages/new-package" to the projects array
53
54
 
54
- 6. Install requested software:
55
- * Always use `npm --workspace ./packages/new-package install`
56
- * Never edit `package.json` from memory
55
+ 6. Install dependencies for the new package:
56
+ * Use `npm install <package-name> --workspace ./packages/<package-name>` to add dependencies
57
+ * Use `npm install <package-name> --workspace ./packages/<package-name> --save-dev` for dev dependencies
58
+ * Never manually edit `package.json` - always use npm commands to maintain package-lock.json
57
59
 
58
60
  ## Context
59
61
 
60
- prompts/prompts/Jaypie_Project_Structure.md
61
- prompts/templates/project-monorepo/tsconfig.base.json
62
- prompts/templates/project-subpackage/package.json
63
- prompts/templates/project-subpackage/tsconfig.json
64
- prompts/templates/project-subpackage/vite.config.ts
65
- prompts/templates/project-subpackage/vitest.config.ts
66
- prompts/templates/project-subpackage/vitest.setup.ts
62
+ prompts/Jaypie_Ideal_Project_Structure.md
63
+ prompts/Templates_Project_Subpackage.md
67
64
  package.json
68
- tsconfig.json
69
- tsconfig.base.json
70
- vitest.workspace.js
65
+ vitest.config.ts
@@ -4,6 +4,10 @@ description: Old conventions repositories should update and the new conventions
4
4
 
5
5
  # Jaypie Legacy Patterns
6
6
 
7
+ ## Mongoose
8
+
9
+ Use MongoDB directly or something else
10
+
7
11
  ## TypeScript, Not Vanilla JavaScript
8
12
 
9
13
  ## Vite for Builds
@@ -0,0 +1,103 @@
1
+ ---
2
+ description: development utilities bundle for Jaypie repositories
3
+ ---
4
+
5
+ # Jaypie Repokit
6
+
7
+ Essential development utilities bundled for Jaypie repositories. Provides common tools needed for build scripts, development workflows, and repository maintenance.
8
+
9
+ ## Installation
10
+
11
+ ```sh
12
+ npm install --save-dev @jaypie/repokit
13
+ ```
14
+
15
+ ## Exported Utilities
16
+
17
+ ### dotenv
18
+
19
+ Re-exports everything from `dotenv` for environment variable management.
20
+
21
+ ```typescript
22
+ import { config } from "@jaypie/repokit";
23
+
24
+ config(); // Load .env file
25
+ ```
26
+
27
+ ### rimraf
28
+
29
+ Re-exports `rimraf` for cross-platform file deletion.
30
+
31
+ ```typescript
32
+ import { rimraf } from "@jaypie/repokit";
33
+
34
+ await rimraf("./dist");
35
+ ```
36
+
37
+ ## CLI Tools (via npx)
38
+
39
+ The package includes CLI tools as dependencies that can be run via npx or in package.json scripts:
40
+
41
+ ### env-cmd
42
+
43
+ Run commands with environment variables from a file.
44
+
45
+ ```json
46
+ {
47
+ "scripts": {
48
+ "start:dev": "env-cmd -f .env.development node server.js"
49
+ }
50
+ }
51
+ ```
52
+
53
+ ### sort-package-json
54
+
55
+ Sort package.json files for consistent formatting.
56
+
57
+ ```json
58
+ {
59
+ "scripts": {
60
+ "format:package": "sort-package-json ./package.json"
61
+ }
62
+ }
63
+ ```
64
+
65
+ ### tsx
66
+
67
+ Run TypeScript files directly without compilation.
68
+
69
+ ```json
70
+ {
71
+ "scripts": {
72
+ "bin:script": "tsx scripts/my-script.ts"
73
+ }
74
+ }
75
+ ```
76
+
77
+ ## Common Usage Patterns
78
+
79
+ ### Build Scripts
80
+
81
+ ```json
82
+ {
83
+ "scripts": {
84
+ "clean": "rimraf ./dist",
85
+ "format:package": "sort-package-json ./package.json",
86
+ "bin:setup": "tsx scripts/setup.ts"
87
+ }
88
+ }
89
+ ```
90
+
91
+ ### Environment Management
92
+
93
+ ```typescript
94
+ // scripts/deploy.ts
95
+ import { config } from "@jaypie/repokit";
96
+
97
+ config({ path: ".env.production" });
98
+ console.log(process.env.API_KEY);
99
+ ```
100
+
101
+ ## Why Use Repokit
102
+
103
+ Instead of installing `dotenv`, `rimraf`, `env-cmd`, `sort-package-json`, and `tsx` individually in each package, install `@jaypie/repokit` once to get all essential development utilities. This ensures consistent versions across all Jaypie repositories.