@ema.co/mcp-toolkit 2026.1.25 → 2026.1.26-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.

Potentially problematic release.


This version of @ema.co/mcp-toolkit might be problematic. Click here for more details.

Files changed (87) hide show
  1. package/README.md +10 -2
  2. package/dist/mcp/handlers/action/index.js +3 -18
  3. package/dist/mcp/handlers/data/index.js +385 -41
  4. package/dist/mcp/handlers/data/templates.js +107 -0
  5. package/dist/mcp/handlers/deprecation.js +50 -0
  6. package/dist/mcp/handlers/env/index.js +8 -4
  7. package/dist/mcp/handlers/knowledge/index.js +44 -237
  8. package/dist/mcp/handlers/persona/create.js +47 -18
  9. package/dist/mcp/handlers/persona/index.js +14 -11
  10. package/dist/mcp/handlers/persona/update.js +4 -2
  11. package/dist/mcp/handlers/persona/version.js +234 -0
  12. package/dist/mcp/handlers/sync/index.js +3 -18
  13. package/dist/mcp/handlers/template/index.js +75 -10
  14. package/dist/mcp/handlers/workflow/analyze.js +171 -0
  15. package/dist/mcp/handlers/workflow/compare.js +70 -0
  16. package/dist/mcp/handlers/workflow/deploy.js +73 -0
  17. package/dist/mcp/handlers/workflow/generate.js +350 -0
  18. package/dist/mcp/handlers/workflow/index.js +294 -0
  19. package/dist/mcp/handlers/workflow/modify.js +456 -0
  20. package/dist/mcp/handlers/workflow/optimize.js +136 -0
  21. package/dist/mcp/handlers/workflow/types.js +4 -0
  22. package/dist/mcp/handlers/workflow/utils.js +30 -0
  23. package/dist/mcp/handlers-consolidated.js +73 -2696
  24. package/dist/mcp/prompts.js +83 -43
  25. package/dist/mcp/resources.js +382 -57
  26. package/dist/mcp/server.js +199 -391
  27. package/dist/mcp/{tools-v2.js → tools.js} +20 -54
  28. package/dist/mcp/workflow-operations.js +2 -2
  29. package/dist/sdk/client-adapter.js +267 -32
  30. package/dist/sdk/client.js +45 -16
  31. package/dist/sdk/ema-client.js +183 -0
  32. package/dist/sdk/generated/deprecated-actions.js +171 -0
  33. package/dist/sdk/generated/template-fallbacks.js +123 -0
  34. package/dist/sdk/guidance.js +65 -11
  35. package/dist/sdk/index.js +3 -1
  36. package/dist/sdk/knowledge.js +139 -86
  37. package/dist/sdk/workflow-intent.js +27 -0
  38. package/dist/sdk/workflow-transformer.js +0 -342
  39. package/docs/mcp-tools-guide.md +37 -45
  40. package/package.json +10 -4
  41. package/dist/mcp/handlers/persona/analyze.js +0 -275
  42. package/dist/mcp/handlers/persona/compare.js +0 -32
  43. package/dist/mcp/tools-consolidated.js +0 -875
  44. package/dist/mcp/tools-legacy.js +0 -736
  45. package/docs/CODEBASE-ANALYSIS-2026-01-23.md +0 -936
  46. package/docs/CODEBASE-ANALYSIS-PRIORITIZED.md +0 -774
  47. package/docs/api-contracts.md +0 -216
  48. package/docs/auto-builder-analysis.md +0 -271
  49. package/docs/blog/mcp-tool-design-lessons.md +0 -309
  50. package/docs/data-architecture.md +0 -166
  51. package/docs/demos/ap-invoice-generation.md +0 -347
  52. package/docs/demos/ap-invoice-processing.md +0 -271
  53. package/docs/ema-auto-builder-guide.html +0 -394
  54. package/docs/lessons-learned.md +0 -209
  55. package/docs/llm-native-workflow-design.md +0 -252
  56. package/docs/local-generation.md +0 -508
  57. package/docs/mcp-flow-diagram.md +0 -135
  58. package/docs/migration/action-composition-migration.md +0 -270
  59. package/docs/naming-conventions.md +0 -278
  60. package/docs/proposals/HANDOFF-tool-restructure.md +0 -526
  61. package/docs/proposals/action-composition.md +0 -490
  62. package/docs/proposals/explicit-method-restructure.md +0 -328
  63. package/docs/proposals/mcp-tool-restructure-2026-01.md +0 -366
  64. package/docs/proposals/self-contained-guidance.md +0 -427
  65. package/docs/proto-sdk-generation.md +0 -242
  66. package/docs/release-impact.md +0 -102
  67. package/docs/release-process.md +0 -157
  68. package/docs/staging.RULE.md +0 -142
  69. package/docs/test-persona-creation.md +0 -196
  70. package/docs/tool-consolidation-v2.md +0 -225
  71. package/docs/tool-response-standards.md +0 -256
  72. package/resources/demo-kits/README.md +0 -175
  73. package/resources/demo-kits/finance-ap/manifest.json +0 -150
  74. package/resources/demo-kits/tags.json +0 -91
  75. package/resources/docs/getting-started.md +0 -97
  76. package/resources/templates/auto-builder-rules.md +0 -224
  77. package/resources/templates/chat-ai/README.md +0 -119
  78. package/resources/templates/chat-ai/persona-config.json +0 -111
  79. package/resources/templates/dashboard-ai/README.md +0 -156
  80. package/resources/templates/dashboard-ai/persona-config.json +0 -180
  81. package/resources/templates/demo-scenarios/README.md +0 -63
  82. package/resources/templates/demo-scenarios/test-published-package.md +0 -116
  83. package/resources/templates/document-gen-ai/README.md +0 -132
  84. package/resources/templates/document-gen-ai/persona-config.json +0 -316
  85. package/resources/templates/voice-ai/README.md +0 -123
  86. package/resources/templates/voice-ai/persona-config.json +0 -74
  87. package/resources/templates/voice-ai/workflow-prompt.md +0 -121
@@ -1,774 +0,0 @@
1
- # Prioritized Codebase Issues
2
-
3
- **Date**: January 23, 2026
4
-
5
- ---
6
-
7
- ## Impact vs Effort Matrix
8
-
9
- ```
10
- HIGH IMPACT
11
-
12
- ┌────────────────────┼────────────────────┐
13
- │ │ │
14
- │ QUICK WINS │ BIG BETS │
15
- │ (Do First) │ (Plan Carefully) │
16
- │ │ │
17
- LOW ├────────────────────┼────────────────────┤ HIGH
18
- EFFORT │ EFFORT
19
- │ │ │
20
- │ FILL-INS │ MONEY PITS │
21
- │ (If Time) │ (Avoid/Defer) │
22
- │ │ │
23
- └────────────────────┼────────────────────┘
24
-
25
- LOW IMPACT
26
- ```
27
-
28
- ---
29
-
30
- ## Section 1: Quick Wins (High Impact, Low Effort)
31
-
32
- These deliver immediate value with minimal risk. Do these first.
33
-
34
- ### QW-1: Add Graceful Shutdown Handler
35
-
36
- **Effort**: 30 min | **Impact**: Prevents data corruption, resource leaks
37
-
38
- ```typescript
39
- // src/mcp/server.ts - Add near server initialization
40
- process.on("SIGTERM", () => {
41
- server.close();
42
- process.exit(0);
43
- });
44
- process.on("SIGINT", () => {
45
- server.close();
46
- process.exit(0);
47
- });
48
- ```
49
-
50
- ---
51
-
52
- ### QW-2: Extract Shared EmaApiError Class
53
-
54
- **Effort**: 30 min | **Impact**: Eliminates duplicate code, single source of truth
55
-
56
- **Files to change**:
57
-
58
- - Create `src/sdk/errors.ts`
59
- - Update `src/sdk/client.ts`
60
- - Update `src/sdk/ema-client.ts`
61
-
62
- ```typescript
63
- // src/sdk/errors.ts
64
- export class EmaApiError extends Error {
65
- constructor(
66
- message: string,
67
- public readonly statusCode: number,
68
- public readonly body: unknown,
69
- ) {
70
- super(message);
71
- this.name = "EmaApiError";
72
- }
73
- }
74
- ```
75
-
76
- ---
77
-
78
- ### QW-3: Add Coverage Thresholds
79
-
80
- **Effort**: 15 min | **Impact**: Prevents test coverage regression
81
-
82
- ```typescript
83
- // vitest.config.ts - Add to coverage section
84
- coverage: {
85
- thresholds: {
86
- lines: 70,
87
- functions: 70,
88
- branches: 60,
89
- statements: 70
90
- }
91
- }
92
- ```
93
-
94
- ---
95
-
96
- ### QW-4: Use structuredClone Instead of JSON.parse/stringify
97
-
98
- **Effort**: 1 hour | **Impact**: 30-50% faster cloning, lower memory
99
-
100
- **Files**: `src/sdk/client.ts:494`, `src/mcp/handlers-consolidated.ts:1137`, `src/sync.ts:149`
101
-
102
- ```typescript
103
- // Before
104
- const cloned = JSON.parse(JSON.stringify(workflow));
105
-
106
- // After
107
- const cloned = structuredClone(workflow);
108
- ```
109
-
110
- ---
111
-
112
- ### QW-5: Consolidate checkDeprecatedParams
113
-
114
- **Effort**: 45 min | **Impact**: DRY, single place to update
115
-
116
- **Current locations** (delete from):
117
-
118
- - `src/mcp/handlers-consolidated.ts:219`
119
- - `src/mcp/handlers/sync/index.ts:16`
120
- - `src/mcp/handlers/action/index.ts:20`
121
-
122
- **Move to**: `src/mcp/handlers/utils.ts` (already exists)
123
-
124
- ---
125
-
126
- ### QW-6: Fix Unknown Action Type Silent Fallback
127
-
128
- **Effort**: 30 min | **Impact**: Prevents silent runtime errors
129
-
130
- ```typescript
131
- // src/sdk/workflow-transformer.ts:392-415
132
- function mapToActionType(rawName: string): ActionType | 'unknown' {
133
- const mapping: Record<string, ActionType> = { ... };
134
- const result = mapping[rawName];
135
- if (!result) {
136
- console.warn(`Unknown action type: ${rawName}, preserving as-is`);
137
- return 'unknown';
138
- }
139
- return result;
140
- }
141
- ```
142
-
143
- ---
144
-
145
- ### QW-7: Add Workflow Namespace Validation
146
-
147
- **Effort**: 30 min | **Impact**: Prevents silent deployment failures
148
-
149
- ```typescript
150
- // src/sdk/workflow-transformer.ts - Add before line 552
151
- function validateWorkflowNamespace(ns: unknown): boolean {
152
- if (!ns || typeof ns !== "object") return false;
153
- const namespace = ns as { namespaces?: unknown[]; name?: string };
154
- return (
155
- Array.isArray(namespace.namespaces) && typeof namespace.name === "string"
156
- );
157
- }
158
-
159
- // Then use it
160
- if (!validateWorkflowNamespace(originalDef.workflowName)) {
161
- throw new Error("Invalid workflow namespace structure");
162
- }
163
- compiled.workflow_def.workflowName = originalDef.workflowName;
164
- ```
165
-
166
- ---
167
-
168
- ### Quick Wins Summary
169
-
170
- | ID | Task | Effort | Impact |
171
- | ---- | ---------------------------- | ------ | ----------------- |
172
- | QW-1 | Graceful shutdown | 30 min | Data safety |
173
- | QW-2 | Extract EmaApiError | 30 min | DRY |
174
- | QW-3 | Coverage thresholds | 15 min | Quality gate |
175
- | QW-4 | Use structuredClone | 1 hour | Performance |
176
- | QW-5 | Consolidate deprecated check | 45 min | DRY |
177
- | QW-6 | Fix action type fallback | 30 min | Error prevention |
178
- | QW-7 | Namespace validation | 30 min | Deployment safety |
179
-
180
- **Total Quick Wins**: ~4 hours for 7 high-impact fixes
181
-
182
- ---
183
-
184
- ## Section 2: Security Fixes (Must Do)
185
-
186
- Security issues grouped by attack surface.
187
-
188
- ### SEC-1: Input Validation (HIGH)
189
-
190
- **Effort**: 4 hours | **Impact**: Prevents injection, corruption
191
-
192
- **Add Zod validation at handler entry points**:
193
-
194
- ```typescript
195
- // src/mcp/handlers/utils.ts - Add
196
- import { z } from "zod";
197
-
198
- export const PersonaIdSchema = z.string().uuid();
199
- export const FilePathSchema = z
200
- .string()
201
- .refine((p) => !p.includes("..") && !p.startsWith("/"), "Invalid file path");
202
-
203
- // Use in handlers
204
- const id = PersonaIdSchema.parse(args.id);
205
- ```
206
-
207
- **Priority handlers**:
208
-
209
- 1. `handlePersona` - persona CRUD
210
- 2. `handleData` - file operations
211
- 3. `handleKnowledge` - file uploads
212
-
213
- ---
214
-
215
- ### SEC-2: Path Traversal Fix (CRITICAL)
216
-
217
- **Effort**: 1 hour | **Impact**: Prevents unauthorized file access
218
-
219
- ```typescript
220
- // src/mcp/handlers/utils.ts - Add
221
- export function validateAndResolvePath(
222
- userPath: string,
223
- baseDir: string,
224
- ): string {
225
- const resolved = path.resolve(baseDir, userPath);
226
- const normalized = path.normalize(resolved);
227
-
228
- if (!normalized.startsWith(path.resolve(baseDir))) {
229
- throw new Error("Path traversal detected");
230
- }
231
-
232
- return normalized;
233
- }
234
- ```
235
-
236
- **Apply to**:
237
-
238
- - `src/mcp/server.ts:3930-3937` (file upload)
239
- - `src/mcp/server.ts:4140-4149` (file operations)
240
-
241
- ---
242
-
243
- ### SEC-3: Sanitize Error Messages (HIGH)
244
-
245
- **Effort**: 2 hours | **Impact**: Prevents information disclosure
246
-
247
- ```typescript
248
- // src/sdk/errors.ts - Add
249
- export function sanitizeErrorForResponse(error: unknown): string {
250
- if (error instanceof EmaApiError) {
251
- // Log full details internally
252
- console.error("API Error", { status: error.statusCode, body: error.body });
253
- // Return sanitized message
254
- return `API error (${error.statusCode}): Operation failed`;
255
- }
256
- return error instanceof Error ? error.message : "Unknown error";
257
- }
258
- ```
259
-
260
- **Apply to**:
261
-
262
- - `src/mcp/server.ts:5829`
263
- - `src/sdk/client.ts:532-613`
264
-
265
- ---
266
-
267
- ### SEC-4: Debug Logging Token Safety (MEDIUM)
268
-
269
- **Effort**: 1 hour | **Impact**: Prevents token exposure
270
-
271
- ```typescript
272
- // src/sdk/logging.ts - Add
273
- export function sanitizeForLogging(obj: unknown): unknown {
274
- if (typeof obj !== "object" || obj === null) return obj;
275
- const sanitized = { ...obj } as Record<string, unknown>;
276
- const sensitiveKeys = [
277
- "token",
278
- "bearer",
279
- "authorization",
280
- "api_key",
281
- "password",
282
- ];
283
- for (const key of Object.keys(sanitized)) {
284
- if (sensitiveKeys.some((k) => key.toLowerCase().includes(k))) {
285
- sanitized[key] = "[REDACTED]";
286
- }
287
- }
288
- return sanitized;
289
- }
290
- ```
291
-
292
- ---
293
-
294
- ### Security Fixes Summary
295
-
296
- | ID | Task | Effort | Severity |
297
- | ----- | ------------------ | ------- | -------- |
298
- | SEC-1 | Input validation | 4 hours | HIGH |
299
- | SEC-2 | Path traversal fix | 1 hour | CRITICAL |
300
- | SEC-3 | Sanitize errors | 2 hours | HIGH |
301
- | SEC-4 | Token safety | 1 hour | MEDIUM |
302
-
303
- **Total Security**: ~8 hours
304
-
305
- ---
306
-
307
- ## Section 3: Performance Fixes
308
-
309
- Issues ordered by user-visible impact.
310
-
311
- ### PERF-1: Parallelize Sync Operations (CRITICAL)
312
-
313
- **Effort**: 2 hours | **Impact**: 3-10x faster sync
314
-
315
- **N+1 Query Fix** (`src/sync.ts:259-273`):
316
-
317
- ```typescript
318
- // Before: Sequential
319
- for (let p of personas) {
320
- if (!p.workflow_def) {
321
- const full = await masterClient.getPersonaById(p.id);
322
- }
323
- }
324
-
325
- // After: Parallel batches
326
- const missingWorkflow = personas.filter((p) => !p.workflow_def);
327
- const batches = chunk(missingWorkflow, 10); // 10 at a time
328
- for (const batch of batches) {
329
- const results = await Promise.all(
330
- batch.map((p) => masterClient.getPersonaById(p.id)),
331
- );
332
- // Merge results...
333
- }
334
- ```
335
-
336
- **Target Sync Fix** (`src/sync.ts:316-334`):
337
-
338
- ```typescript
339
- // Before: Sequential
340
- for (const target of targets) {
341
- await syncToTarget(persona, target);
342
- }
343
-
344
- // After: Parallel
345
- const results = await Promise.allSettled(
346
- targets.map((target) => syncToTarget(persona, target)),
347
- );
348
- ```
349
-
350
- ---
351
-
352
- ### PERF-2: Async File I/O (HIGH)
353
-
354
- **Effort**: 4 hours | **Impact**: Unblocks event loop
355
-
356
- **File**: `src/sdk/version-storage.ts`
357
-
358
- Convert all sync operations:
359
-
360
- ```typescript
361
- // Before
362
- const content = fs.readFileSync(path, 'utf8');
363
- fs.writeFileSync(path, data);
364
- if (fs.existsSync(path)) { ... }
365
-
366
- // After
367
- import { readFile, writeFile, access } from 'fs/promises';
368
-
369
- const content = await readFile(path, 'utf8');
370
- await writeFile(path, data);
371
- try {
372
- await access(path);
373
- // exists
374
- } catch {
375
- // doesn't exist
376
- }
377
- ```
378
-
379
- **Methods to update** (15 total):
380
-
381
- - `getLatestSnapshot` → `getLatestSnapshotAsync`
382
- - `saveSnapshot` → `saveSnapshotAsync`
383
- - etc.
384
-
385
- ---
386
-
387
- ### PERF-3: Cache Prepared Statements (MEDIUM)
388
-
389
- **Effort**: 1 hour | **Impact**: Faster SQLite queries
390
-
391
- ```typescript
392
- // src/sdk/state.ts - Change pattern
393
- class StateStore {
394
- // Cache statements at class level
395
- private readonly getMappingStmt: Statement;
396
- private readonly upsertMappingStmt: Statement;
397
-
398
- constructor(dbPath: string) {
399
- this.db = new Database(dbPath);
400
- // Prepare once
401
- this.getMappingStmt = this.db.prepare(`SELECT ...`);
402
- this.upsertMappingStmt = this.db.prepare(`INSERT ...`);
403
- }
404
-
405
- getMapping(id: string) {
406
- return this.getMappingStmt.get(id); // Use cached
407
- }
408
- }
409
- ```
410
-
411
- ---
412
-
413
- ### PERF-4: Eliminate Double API Call (MEDIUM)
414
-
415
- **Effort**: 1 hour | **Impact**: 50% fewer update API calls
416
-
417
- ```typescript
418
- // src/sdk/client.ts:476-550
419
- // Before: Always fetch existing persona
420
- async updateAiEmployee(req: UpdateRequest) {
421
- const existing = await this.getPersonaById(req.id); // Extra call!
422
- // ...fix namespace...
423
- return this.doUpdate(req);
424
- }
425
-
426
- // After: Only fetch if namespace missing
427
- async updateAiEmployee(req: UpdateRequest) {
428
- if (req.workflow && !hasValidNamespace(req.workflow)) {
429
- const existing = await this.getPersonaById(req.id);
430
- copyNamespace(existing.workflow_def, req.workflow);
431
- }
432
- return this.doUpdate(req);
433
- }
434
- ```
435
-
436
- ---
437
-
438
- ### Performance Fixes Summary
439
-
440
- | ID | Task | Effort | Speedup |
441
- | ------ | --------------------- | ------- | --------- |
442
- | PERF-1 | Parallelize sync | 2 hours | 3-10x |
443
- | PERF-2 | Async file I/O | 4 hours | Unblocks |
444
- | PERF-3 | Cache statements | 1 hour | ~20% |
445
- | PERF-4 | Eliminate double call | 1 hour | 50% fewer |
446
-
447
- **Total Performance**: ~8 hours
448
-
449
- ---
450
-
451
- ## Section 4: Architecture Fixes
452
-
453
- Structural issues that compound over time.
454
-
455
- ### ARCH-1: Fix Circular Dependency (CRITICAL)
456
-
457
- **Effort**: 2 hours | **Impact**: Prevents module failures
458
-
459
- **Problem**:
460
-
461
- ```
462
- src/sync.ts → imports → src/sdk/config.ts
463
- src/sdk/sync.ts → imports → src/sync.ts (circular!)
464
- ```
465
-
466
- **Solution**:
467
-
468
- 1. Create `src/sdk/sync-engine.ts` with core logic
469
- 2. Move `fingerprintPersona`, `syncOnce`, `transformWorkflowForTarget`
470
- 3. Have `src/sdk/sync.ts` re-export
471
- 4. Make `src/sync.ts` a thin wrapper or delete
472
-
473
- ```
474
- src/sdk/sync-engine.ts ← NEW: core logic
475
- src/sdk/sync.ts ← re-exports sync-engine
476
- src/sync.ts ← DELETE or thin wrapper
477
- ```
478
-
479
- ---
480
-
481
- ### ARCH-2: Complete Handler Modularization (HIGH)
482
-
483
- **Effort**: 8 hours | **Impact**: Maintainability, testability
484
-
485
- **Current state**:
486
-
487
- - `handlers-consolidated.ts`: 3,381 lines
488
- - `server.ts`: 5,914 lines
489
-
490
- **Target state**:
491
-
492
- ```
493
- src/mcp/handlers/
494
- ├── persona/ ✅ Done
495
- ├── data/ ✅ Done
496
- ├── action/ ✅ Done
497
- ├── sync/ ✅ Done
498
- ├── workflow/ ❌ NEW - Extract from handlers-consolidated
499
- ├── version/ ❌ NEW - Extract version_* modes
500
- └── utils.ts ✅ Done
501
- ```
502
-
503
- **Steps**:
504
-
505
- 1. Create `src/mcp/handlers/workflow/index.ts`
506
- 2. Move `handleWorkflow` (962 lines) to workflow handler
507
- 3. Create `src/mcp/handlers/version/index.ts`
508
- 4. Move version modes (330 lines)
509
- 5. Reduce `handlers-consolidated.ts` to dispatch only
510
-
511
- ---
512
-
513
- ### ARCH-3: Split server.ts (MEDIUM)
514
-
515
- **Effort**: 4 hours | **Impact**: Readability, maintainability
516
-
517
- **Current**: 5,914 lines doing many things
518
-
519
- **Target**:
520
-
521
- ```
522
- src/mcp/
523
- ├── server.ts ← 500 lines: init, routing only
524
- ├── tools/
525
- │ ├── index.ts ← tool registration
526
- │ └── helpers.ts ← tool helpers
527
- ├── middleware/
528
- │ └── error-handler.ts
529
- └── lifecycle.ts ← startup, shutdown
530
- ```
531
-
532
- ---
533
-
534
- ### Architecture Fixes Summary
535
-
536
- | ID | Task | Effort | Impact |
537
- | ------ | ---------------- | ------- | --------------- |
538
- | ARCH-1 | Fix circular dep | 2 hours | Stability |
539
- | ARCH-2 | Extract handlers | 8 hours | Maintainability |
540
- | ARCH-3 | Split server.ts | 4 hours | Readability |
541
-
542
- **Total Architecture**: ~14 hours
543
-
544
- ---
545
-
546
- ## Section 5: Test Coverage
547
-
548
- Focus on highest-risk untested code.
549
-
550
- ### TEST-1: SDK Client Tests (HIGH)
551
-
552
- **Effort**: 8 hours | **Impact**: Core API client coverage
553
-
554
- **Untested files** (highest risk):
555
-
556
- - `src/sdk/client.ts` (2,400 lines)
557
- - `src/sdk/ema-client.ts` (405 lines)
558
-
559
- **Test approach**:
560
-
561
- ```typescript
562
- // test/sdk/ema-client.test.ts
563
- import { vi } from "vitest";
564
- import { EmaClientV2 } from "../src/sdk/ema-client";
565
-
566
- vi.mock("../src/sdk/generated/api-client", () => ({
567
- getPersonas: vi.fn(),
568
- updatePersona: vi.fn(),
569
- }));
570
-
571
- describe("EmaClientV2", () => {
572
- it("handles API errors correctly", async () => {
573
- // Mock 404 response
574
- // Assert EmaApiError thrown
575
- });
576
-
577
- it("preserves workflow namespace on update", async () => {
578
- // Critical business logic
579
- });
580
- });
581
- ```
582
-
583
- ---
584
-
585
- ### TEST-2: Workflow Validator/Optimizer Tests (MEDIUM)
586
-
587
- **Effort**: 4 hours | **Impact**: Validation logic coverage
588
-
589
- **Untested**:
590
-
591
- - `src/sdk/workflow-validator.ts`
592
- - `src/sdk/workflow-optimizer.ts`
593
-
594
- ---
595
-
596
- ### TEST-3: Error Path Tests (MEDIUM)
597
-
598
- **Effort**: 4 hours | **Impact**: Resilience coverage
599
-
600
- Add tests for:
601
-
602
- - Network failures
603
- - Timeout scenarios
604
- - Malformed responses
605
- - Concurrent operations
606
-
607
- ---
608
-
609
- ### Test Coverage Summary
610
-
611
- | ID | Task | Effort | Coverage Gain |
612
- | ------ | ---------------- | ------- | ------------- |
613
- | TEST-1 | SDK client tests | 8 hours | +15% |
614
- | TEST-2 | Validator tests | 4 hours | +5% |
615
- | TEST-3 | Error path tests | 4 hours | +5% |
616
-
617
- **Total Testing**: ~16 hours
618
-
619
- ---
620
-
621
- ## Section 6: Code Quality
622
-
623
- Technical debt that slows development.
624
-
625
- ### QUAL-1: Reduce Type Assertions (HIGH)
626
-
627
- **Effort**: 8 hours | **Impact**: Type safety
628
-
629
- **Focus files** (highest assertion count):
630
-
631
- 1. `src/sdk/workflow-fixer.ts` - 4 `as unknown` casts
632
- 2. `src/sdk/intent-architect.ts` - 1 unsafe cast
633
- 3. `src/mcp/handlers-consolidated.ts` - Many `as Record<...>`
634
-
635
- **Strategy**: Add type guards:
636
-
637
- ```typescript
638
- // src/sdk/type-guards.ts
639
- export function isWorkflowDef(obj: unknown): obj is WorkflowDef {
640
- return (
641
- typeof obj === "object" &&
642
- obj !== null &&
643
- "actions" in obj &&
644
- Array.isArray((obj as { actions: unknown }).actions)
645
- );
646
- }
647
-
648
- // Usage
649
- if (!isWorkflowDef(workflowDef)) {
650
- throw new Error("Invalid workflow definition");
651
- }
652
- // Now TypeScript knows it's WorkflowDef
653
- ```
654
-
655
- ---
656
-
657
- ### QUAL-2: Remove Dead Code (LOW)
658
-
659
- **Effort**: 2 hours | **Impact**: Cleaner codebase
660
-
661
- - Remove 100+ lines of commented code in `server.ts`
662
- - Run `npm run lint:unused` to find unused exports
663
- - Delete or extract to separate "legacy" file
664
-
665
- ---
666
-
667
- ### QUAL-3: Address Critical TODOs (MEDIUM)
668
-
669
- **Effort**: Varies | **Impact**: Completes incomplete features
670
-
671
- **High-priority TODOs**:
672
-
673
- ```typescript
674
- // src/mcp/server.ts:1624
675
- "TODO: Add support for 3rd party data sources";
676
-
677
- // src/mcp/handlers-consolidated.ts:359
678
- "TODO: Deprecate handleWorkflow and move remaining logic";
679
- ```
680
-
681
- ---
682
-
683
- ### Code Quality Summary
684
-
685
- | ID | Task | Effort | Impact |
686
- | ------ | ---------------- | ------- | ------------ |
687
- | QUAL-1 | Type guards | 8 hours | Safety |
688
- | QUAL-2 | Remove dead code | 2 hours | Cleanliness |
689
- | QUAL-3 | Address TODOs | Varies | Completeness |
690
-
691
- ---
692
-
693
- ## Recommended Execution Order
694
-
695
- ### Sprint 1: Quick Wins + Critical Security (1 week)
696
-
697
- | Day | Tasks | Hours |
698
- | --- | -------------------------- | ----- |
699
- | 1 | QW-1, QW-2, QW-3 | 1.25h |
700
- | 1 | SEC-2 (path traversal) | 1h |
701
- | 2 | QW-4, QW-5, QW-6, QW-7 | 2.75h |
702
- | 2 | SEC-3 (error sanitization) | 2h |
703
- | 3 | ARCH-1 (circular dep) | 2h |
704
- | 3 | SEC-1 (input validation) | 4h |
705
- | 4 | PERF-1 (parallelize sync) | 2h |
706
- | 5 | Buffer / PR review | - |
707
-
708
- **Sprint 1 Total**: ~15 hours of work
709
-
710
- ### Sprint 2: Performance + Architecture (1 week)
711
-
712
- | Day | Tasks | Hours |
713
- | --- | --------------------------- | ----- |
714
- | 1-2 | PERF-2 (async file I/O) | 4h |
715
- | 2 | PERF-3, PERF-4 | 2h |
716
- | 3-4 | ARCH-2 (handler extraction) | 8h |
717
- | 5 | Buffer / PR review | - |
718
-
719
- **Sprint 2 Total**: ~14 hours of work
720
-
721
- ### Sprint 3: Testing + Quality (1 week)
722
-
723
- | Day | Tasks | Hours |
724
- | --- | ------------------------- | ----- |
725
- | 1-2 | TEST-1 (SDK client tests) | 8h |
726
- | 3 | TEST-2, TEST-3 | 8h |
727
- | 4-5 | QUAL-1 (type guards) | 8h |
728
-
729
- **Sprint 3 Total**: ~24 hours of work
730
-
731
- ---
732
-
733
- ## Quick Reference Card
734
-
735
- ### Do Today (< 2 hours total)
736
-
737
- 1. ✅ Add graceful shutdown (30 min)
738
- 2. ✅ Add coverage thresholds (15 min)
739
- 3. ✅ Fix action type fallback (30 min)
740
- 4. ✅ Add namespace validation (30 min)
741
-
742
- ### Do This Week
743
-
744
- 1. 🔒 Fix path traversal
745
- 2. 🔒 Add input validation
746
- 3. 🔒 Sanitize error messages
747
- 4. 🏗️ Fix circular dependency
748
- 5. ⚡ Parallelize sync operations
749
-
750
- ### Do This Month
751
-
752
- 1. ⚡ Async file I/O migration
753
- 2. 🏗️ Complete handler extraction
754
- 3. 🧪 Add SDK client tests
755
- 4. 🔧 Add type guards
756
-
757
- ---
758
-
759
- ## Metrics to Track
760
-
761
- After implementing fixes:
762
-
763
- | Metric | Current | Target |
764
- | ------------------------ | ------- | ------ |
765
- | Test coverage | ~45% | 70% |
766
- | `any` types | 102 | <20 |
767
- | Type assertions | 2000+ | <500 |
768
- | Sync time (100 personas) | ~30s | ~5s |
769
- | server.ts lines | 5,914 | <1,000 |
770
- | Critical issues | 8 | 0 |
771
-
772
- ---
773
-
774
- _Generated: January 23, 2026_