iaip-mcp-pde 2.0.2

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 (46) hide show
  1. package/README.md +187 -0
  2. package/dist/cli.d.ts +18 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +385 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/index.d.ts +15 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +34 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/mcp-server.d.ts +59 -0
  11. package/dist/mcp-server.d.ts.map +1 -0
  12. package/dist/mcp-server.js +293 -0
  13. package/dist/mcp-server.js.map +1 -0
  14. package/dist/parser.d.ts +19 -0
  15. package/dist/parser.d.ts.map +1 -0
  16. package/dist/parser.js +89 -0
  17. package/dist/parser.js.map +1 -0
  18. package/dist/pde-engine.d.ts +54 -0
  19. package/dist/pde-engine.d.ts.map +1 -0
  20. package/dist/pde-engine.js +85 -0
  21. package/dist/pde-engine.js.map +1 -0
  22. package/dist/prompts.d.ts +10 -0
  23. package/dist/prompts.d.ts.map +1 -0
  24. package/dist/prompts.js +93 -0
  25. package/dist/prompts.js.map +1 -0
  26. package/dist/storage.d.ts +44 -0
  27. package/dist/storage.d.ts.map +1 -0
  28. package/dist/storage.js +369 -0
  29. package/dist/storage.js.map +1 -0
  30. package/dist/types.d.ts +108 -0
  31. package/dist/types.d.ts.map +1 -0
  32. package/dist/types.js +24 -0
  33. package/dist/types.js.map +1 -0
  34. package/package.json +63 -0
  35. package/rispecs/pde-data-models.rispec.md +182 -0
  36. package/rispecs/pde-overview.rispec.md +157 -0
  37. package/rispecs/pde-parent-child-schema.rispec.md +525 -0
  38. package/rispecs/pde-prompts.rispec.md +144 -0
  39. package/rispecs/pde-resources.rispec.md +101 -0
  40. package/rispecs/pde-tools.rispec.md +179 -0
  41. package/rispecs/relation-to-mcp-structural-thinking.kin.md +66 -0
  42. package/scenarios/01-simple-decomposition.md +88 -0
  43. package/scenarios/02-multi-intent-workflow.md +112 -0
  44. package/scenarios/03-ceremonial-alignment.md +155 -0
  45. package/scenarios/04-dependency-resolution.md +163 -0
  46. package/scenarios/05-checkpoint-recovery.md +171 -0
@@ -0,0 +1,525 @@
1
+ # PDE Parent-Child Schema & Folder-Based Output
2
+ > EAST Phase Design — parent_pde_uuid feature for mcp-pde v2.1
3
+ > Issue: jgwill/src#421 | Related: #418, #419
4
+
5
+ **Version**: 2.1.0-design
6
+ **Document ID**: pde-parent-child-schema-v2.1
7
+
8
+ ## Creative Intent
9
+
10
+ ### Desired Outcome
11
+ PDEs form **parent-child hierarchies** stored in timestamped folders, enabling multi-level decomposition (mission → sub-missions), traceable lineage, and human-navigable `.pde/` layouts.
12
+
13
+ ### Current Reality
14
+ - Storage: flat `.pde/<uuid>.json` + `.pde/<uuid>.md`
15
+ - No parent-child relationship
16
+ - No timestamp in filenames
17
+ - Manually created prototype exists: `.pde/2603261642--a448b195-c4ba-4d92-8220-a9ac92bc6d60/`
18
+
19
+ ---
20
+
21
+ ## 1. Schema Changes
22
+
23
+ ### 1a. `StoredDecomposition` — Add `parent_pde_id`
24
+
25
+ **File**: `src/types.ts` (lines 110-118)
26
+
27
+ ```typescript
28
+ export interface StoredDecomposition {
29
+ id: string;
30
+ timestamp: string;
31
+ prompt: string;
32
+ result: DecompositionResult;
33
+ options: DecompositionOptions;
34
+ markdownPath?: string;
35
+ // --- NEW (v2.1) ---
36
+ /** UUID of parent PDE. When set, this PDE is stored inside the parent's folder. */
37
+ parent_pde_id?: string;
38
+ /** Folder name: <yyMMddHHmm>--<id>. Computed at save time. */
39
+ folder_name?: string;
40
+ }
41
+ ```
42
+
43
+ **Non-breaking**: Both new fields are optional. Old JSON files without them load normally.
44
+
45
+ ### 1b. MCP Tool Input Types — Add `parent_pde_id`
46
+
47
+ **File**: `src/types.ts` (lines 124-145)
48
+
49
+ ```typescript
50
+ export interface DecomposeInput {
51
+ prompt: string;
52
+ options?: Partial<DecompositionOptions>;
53
+ workdir?: string;
54
+ // --- NEW (v2.1) ---
55
+ /** Parent PDE UUID. If set, child will be stored inside parent's folder. */
56
+ parent_pde_id?: string;
57
+ }
58
+
59
+ export interface ParseResponseInput {
60
+ llm_response: string;
61
+ original_prompt: string;
62
+ workdir?: string;
63
+ options?: Partial<DecompositionOptions>;
64
+ // --- NEW (v2.1) ---
65
+ parent_pde_id?: string;
66
+ }
67
+
68
+ export interface ListDecompositionsInput {
69
+ workdir?: string;
70
+ limit?: number;
71
+ // --- NEW (v2.1) ---
72
+ /** When set, only list children of this parent PDE. */
73
+ parent_pde_id?: string;
74
+ }
75
+ ```
76
+
77
+ `GetDecompositionInput` and `ExportMarkdownInput` need **no changes** — `pde_get` resolves paths by scanning both old flat format and new folder format.
78
+
79
+ ---
80
+
81
+ ## 2. New Folder-Based Output Format
82
+
83
+ ### 2a. Layout
84
+
85
+ ```
86
+ .pde/
87
+ ├── <uuid>.json # Old format (still supported for reads)
88
+ ├── <uuid>.md # Old format (still supported for reads)
89
+
90
+ ├── <yyMMddHHmm>--<parent-uuid>/ # NEW: folder-based parent
91
+ │ ├── pde-<parent-uuid>.json # Parent decomposition
92
+ │ ├── pde-<parent-uuid>.md # Parent markdown
93
+ │ ├── AGENTS.md # Agent instructions (optional)
94
+ │ │
95
+ │ ├── <yyMMddHHmm>--<child-uuid>/ # Child PDE folder
96
+ │ │ ├── pde-<child-uuid>.json
97
+ │ │ └── pde-<child-uuid>.md
98
+ │ │
99
+ │ └── <yyMMddHHmm>--<child2-uuid>/ # Another child
100
+ │ ├── pde-<child2-uuid>.json
101
+ │ └── pde-<child2-uuid>.md
102
+ ```
103
+
104
+ ### 2b. Timestamp Format
105
+
106
+ `yyMMddHHmm` — e.g., `2604030845` for 2026-04-03 08:45.
107
+
108
+ **Helper function** (new in `storage.ts`):
109
+
110
+ ```typescript
111
+ function formatTimestamp(date: Date = new Date()): string {
112
+ const yy = String(date.getFullYear()).slice(2);
113
+ const MM = String(date.getMonth() + 1).padStart(2, '0');
114
+ const dd = String(date.getDate()).padStart(2, '0');
115
+ const HH = String(date.getHours()).padStart(2, '0');
116
+ const mm = String(date.getMinutes()).padStart(2, '0');
117
+ return `${yy}${MM}${dd}${HH}${mm}`;
118
+ }
119
+ ```
120
+
121
+ ### 2c. Folder Name Construction
122
+
123
+ ```typescript
124
+ function buildFolderName(id: string, date?: Date): string {
125
+ return `${formatTimestamp(date)}--${id}`;
126
+ }
127
+ ```
128
+
129
+ ### 2d. When Folder Format Is Used
130
+
131
+ | Condition | Storage Format |
132
+ |-----------|---------------|
133
+ | `parent_pde_id` is set | Child stored in parent's folder: `.pde/<parent-folder>/<yyMMddHHmm>--<child-uuid>/` |
134
+ | No `parent_pde_id` | **New default**: `.pde/<yyMMddHHmm>--<uuid>/pde-<uuid>.json|md` |
135
+ | Reading old PDE | Falls back to `.pde/<uuid>.json` if folder not found |
136
+
137
+ **All new writes use folder format.** Old flat files are read-only legacy.
138
+
139
+ ---
140
+
141
+ ## 3. File Modifications List
142
+
143
+ ### `src/types.ts`
144
+ | Line(s) | Change |
145
+ |---------|--------|
146
+ | 110-118 | Add `parent_pde_id?: string` and `folder_name?: string` to `StoredDecomposition` |
147
+ | 124-129 | Add `parent_pde_id?: string` to `DecomposeInput` |
148
+ | 136-139 | Add `parent_pde_id?: string` to `ListDecompositionsInput` |
149
+ | (new) | Add `ParseResponseInput` interface (currently inline-typed in mcp-server.ts) |
150
+
151
+ ### `src/storage.ts`
152
+ | Function | Change |
153
+ |----------|--------|
154
+ | `ensureDir()` | Support subfolder creation for parent/child paths |
155
+ | `saveDecomposition()` | **Major**: Accept `parent_pde_id`, compute folder path, write to `<folder>/pde-<id>.json|md` |
156
+ | `loadDecomposition()` | **Major**: Scan both `<id>.json` (legacy) and `*--<id>/pde-<id>.json` (new) |
157
+ | `listDecompositions()` | **Major**: Scan folders recursively; support `parent_pde_id` filter |
158
+ | (new) | `formatTimestamp()`, `buildFolderName()`, `resolveDecompositionPath()` helpers |
159
+
160
+ ### `src/pde-engine.ts`
161
+ | Method | Change |
162
+ |--------|--------|
163
+ | `parseAndStore()` | Accept `parent_pde_id` param, pass through to `saveDecomposition()` |
164
+ | `get()` | Use new `resolveDecompositionPath()` for path resolution |
165
+ | `list()` | Pass `parent_pde_id` filter to `listDecompositions()` |
166
+
167
+ ### `src/mcp-server.ts`
168
+ | Tool | Change |
169
+ |------|--------|
170
+ | `pde_decompose` | Add `parent_pde_id` to inputSchema and response echo |
171
+ | `pde_parse_response` | Add `parent_pde_id` to inputSchema; pass to `engine.parseAndStore()` |
172
+ | `pde_list` | Add `parent_pde_id` to inputSchema; pass to `engine.list()` |
173
+ | `pde_get` | No schema change (resolution is internal) |
174
+
175
+ ### `src/cli.ts`
176
+ | Command | Change |
177
+ |---------|--------|
178
+ | `decompose` | Add `--parent` / `-p` flag |
179
+ | `parse` | Add `--parent` / `-p` flag |
180
+ | `list` | Add `--parent` / `-p` flag for filtering children |
181
+ | Console output | Update path display to show folder structure |
182
+
183
+ ### `tests/pde-engine.test.ts`
184
+ | Test | Change |
185
+ |------|--------|
186
+ | `parseAndStore` | Add tests for folder-based storage |
187
+ | `parseAndStore` | Add tests for parent_pde_id child storage |
188
+ | `get` | Add tests for resolving both formats |
189
+ | `list` | Add tests for parent_pde_id filter |
190
+
191
+ ### `rispecs/pde-data-models.rispec.md`
192
+ | Section | Change |
193
+ |---------|--------|
194
+ | Storage Types | Document `parent_pde_id`, `folder_name` fields |
195
+
196
+ ### `rispecs/pde-tools.rispec.md`
197
+ | Section | Change |
198
+ |---------|--------|
199
+ | Tool 1-4 schemas | Document `parent_pde_id` parameter |
200
+
201
+ ---
202
+
203
+ ## 4. API Surface Changes
204
+
205
+ ### Tool: `pde_decompose`
206
+
207
+ ```diff
208
+ inputSchema: {
209
+ properties: {
210
+ prompt: { type: 'string' },
211
+ options: { ... },
212
+ + parent_pde_id: {
213
+ + type: 'string',
214
+ + description: 'UUID of parent PDE. Echoed in response for pass-through to pde_parse_response.'
215
+ + },
216
+ },
217
+ }
218
+ ```
219
+
220
+ Response adds `parent_pde_id` echo for pipeline continuity.
221
+
222
+ ### Tool: `pde_parse_response`
223
+
224
+ ```diff
225
+ inputSchema: {
226
+ properties: {
227
+ llm_response: { type: 'string' },
228
+ original_prompt: { type: 'string' },
229
+ workdir: { type: 'string' },
230
+ options: { ... },
231
+ + parent_pde_id: {
232
+ + type: 'string',
233
+ + description: 'UUID of parent PDE. When set, stores this decomposition inside the parent folder.'
234
+ + },
235
+ },
236
+ }
237
+ ```
238
+
239
+ ### Tool: `pde_list`
240
+
241
+ ```diff
242
+ inputSchema: {
243
+ properties: {
244
+ workdir: { type: 'string' },
245
+ limit: { type: 'number' },
246
+ + parent_pde_id: {
247
+ + type: 'string',
248
+ + description: 'When set, only list children of this parent PDE.'
249
+ + },
250
+ },
251
+ }
252
+ ```
253
+
254
+ ### Tool: `pde_get`
255
+
256
+ No input schema changes. Resolution logic updated internally.
257
+
258
+ ---
259
+
260
+ ## 5. Key Implementation: `storage.ts` Changes
261
+
262
+ ### `resolveDecompositionPath()` — NEW
263
+
264
+ ```typescript
265
+ /**
266
+ * Resolve the JSON file path for a decomposition ID.
267
+ * Tries new folder format first, falls back to legacy flat format.
268
+ */
269
+ function resolveDecompositionPath(
270
+ workdir: string,
271
+ id: string,
272
+ parentId?: string
273
+ ): string | null {
274
+ const pdeDir = join(workdir, PDE_DIR);
275
+
276
+ // If parentId given, look inside parent's folder
277
+ if (parentId) {
278
+ const parentFolder = findFolderById(pdeDir, parentId);
279
+ if (parentFolder) {
280
+ const childFolder = findFolderById(join(pdeDir, parentFolder), id);
281
+ if (childFolder) {
282
+ const path = join(pdeDir, parentFolder, childFolder, `pde-${id}.json`);
283
+ if (existsSync(path)) return path;
284
+ }
285
+ }
286
+ }
287
+
288
+ // Try new folder format: .pde/*--<id>/pde-<id>.json
289
+ const folder = findFolderById(pdeDir, id);
290
+ if (folder) {
291
+ const path = join(pdeDir, folder, `pde-${id}.json`);
292
+ if (existsSync(path)) return path;
293
+ }
294
+
295
+ // Recurse into all folders to find nested children
296
+ if (existsSync(pdeDir)) {
297
+ for (const entry of readdirSync(pdeDir)) {
298
+ const subdir = join(pdeDir, entry);
299
+ if (statSync(subdir).isDirectory()) {
300
+ const childFolder = findFolderById(subdir, id);
301
+ if (childFolder) {
302
+ const path = join(subdir, childFolder, `pde-${id}.json`);
303
+ if (existsSync(path)) return path;
304
+ }
305
+ }
306
+ }
307
+ }
308
+
309
+ // Legacy flat format: .pde/<id>.json
310
+ const legacyPath = join(pdeDir, `${id}.json`);
311
+ if (existsSync(legacyPath)) return legacyPath;
312
+
313
+ return null;
314
+ }
315
+
316
+ /**
317
+ * Find a folder matching *--<id> pattern in a directory.
318
+ */
319
+ function findFolderById(dir: string, id: string): string | null {
320
+ if (!existsSync(dir)) return null;
321
+ const suffix = `--${id}`;
322
+ const match = readdirSync(dir).find(
323
+ (f) => f.endsWith(suffix) && statSync(join(dir, f)).isDirectory()
324
+ );
325
+ return match || null;
326
+ }
327
+ ```
328
+
329
+ ### `saveDecomposition()` — UPDATED
330
+
331
+ ```typescript
332
+ export function saveDecomposition(
333
+ workdir: string,
334
+ id: string,
335
+ prompt: string,
336
+ result: DecompositionResult,
337
+ options: DecompositionOptions,
338
+ parentPdeId?: string // NEW parameter
339
+ ): StoredDecomposition {
340
+ const pdeDir = join(workdir, PDE_DIR);
341
+ const now = new Date();
342
+ const folderName = buildFolderName(id, now);
343
+
344
+ let targetDir: string;
345
+
346
+ if (parentPdeId) {
347
+ // Find parent's folder
348
+ const parentFolder = findFolderById(pdeDir, parentPdeId);
349
+ if (!parentFolder) {
350
+ throw new Error(
351
+ `Parent PDE ${parentPdeId} not found in ${pdeDir}. ` +
352
+ `Parent must be saved first.`
353
+ );
354
+ }
355
+ targetDir = join(pdeDir, parentFolder, folderName);
356
+ } else {
357
+ // Top-level: new folder format
358
+ targetDir = join(pdeDir, folderName);
359
+ }
360
+
361
+ mkdirSync(targetDir, { recursive: true });
362
+
363
+ const stored: StoredDecomposition = {
364
+ id,
365
+ timestamp: now.toISOString(),
366
+ prompt,
367
+ result,
368
+ options,
369
+ parent_pde_id: parentPdeId,
370
+ folder_name: folderName,
371
+ };
372
+
373
+ // Save JSON
374
+ const jsonPath = join(targetDir, `pde-${id}.json`);
375
+ writeFileSync(jsonPath, JSON.stringify(stored, null, 2), "utf-8");
376
+
377
+ // Save Markdown
378
+ const mdPath = join(targetDir, `pde-${id}.md`);
379
+ const md = decompositionToMarkdown(result, prompt);
380
+ writeFileSync(mdPath, md, "utf-8");
381
+ stored.markdownPath = mdPath;
382
+
383
+ return stored;
384
+ }
385
+ ```
386
+
387
+ ### `loadDecomposition()` — UPDATED
388
+
389
+ ```typescript
390
+ export function loadDecomposition(
391
+ workdir: string,
392
+ id: string
393
+ ): StoredDecomposition | null {
394
+ const resolved = resolveDecompositionPath(workdir, id);
395
+ if (!resolved) return null;
396
+ const raw = readFileSync(resolved, "utf-8");
397
+ return JSON.parse(raw) as StoredDecomposition;
398
+ }
399
+ ```
400
+
401
+ ### `listDecompositions()` — UPDATED
402
+
403
+ ```typescript
404
+ export function listDecompositions(
405
+ workdir: string,
406
+ limit?: number,
407
+ parentPdeId?: string // NEW parameter
408
+ ): StoredDecomposition[] {
409
+ const pdeDir = join(workdir, PDE_DIR);
410
+ if (!existsSync(pdeDir)) return [];
411
+
412
+ const results: StoredDecomposition[] = [];
413
+
414
+ if (parentPdeId) {
415
+ // List children of a specific parent
416
+ const parentFolder = findFolderById(pdeDir, parentPdeId);
417
+ if (!parentFolder) return [];
418
+ const parentDir = join(pdeDir, parentFolder);
419
+ for (const entry of readdirSync(parentDir)) {
420
+ if (entry.includes('--') && statSync(join(parentDir, entry)).isDirectory()) {
421
+ const childId = entry.split('--').pop()!;
422
+ const jsonPath = join(parentDir, entry, `pde-${childId}.json`);
423
+ if (existsSync(jsonPath)) {
424
+ results.push(JSON.parse(readFileSync(jsonPath, 'utf-8')));
425
+ }
426
+ }
427
+ }
428
+ } else {
429
+ // List all top-level decompositions
430
+
431
+ // New format: folders matching *--<uuid>/
432
+ for (const entry of readdirSync(pdeDir)) {
433
+ const fullPath = join(pdeDir, entry);
434
+ if (entry.includes('--') && statSync(fullPath).isDirectory()) {
435
+ const id = entry.split('--').pop()!;
436
+ const jsonPath = join(fullPath, `pde-${id}.json`);
437
+ if (existsSync(jsonPath)) {
438
+ results.push(JSON.parse(readFileSync(jsonPath, 'utf-8')));
439
+ }
440
+ }
441
+ }
442
+
443
+ // Legacy format: .pde/<uuid>.json
444
+ for (const entry of readdirSync(pdeDir)) {
445
+ if (entry.endsWith('.json') && !entry.startsWith('pde-')) {
446
+ const fullPath = join(pdeDir, entry);
447
+ if (statSync(fullPath).isFile()) {
448
+ results.push(JSON.parse(readFileSync(fullPath, 'utf-8')));
449
+ }
450
+ }
451
+ }
452
+ }
453
+
454
+ // Sort by timestamp descending
455
+ results.sort((a, b) => b.timestamp.localeCompare(a.timestamp));
456
+ return limit ? results.slice(0, limit) : results;
457
+ }
458
+ ```
459
+
460
+ ---
461
+
462
+ ## 6. Migration Strategy
463
+
464
+ ### Backward Compatibility Rules
465
+
466
+ 1. **Old `.pde/<uuid>.json` files are never moved or modified** — they remain readable
467
+ 2. **All new writes use folder format** — even top-level PDEs without a parent
468
+ 3. **`pde_get` resolves transparently** — tries folder format first, falls back to flat
469
+ 4. **`pde_list` merges both formats** — deduplicates by ID if a PDE exists in both
470
+ 5. **No migration script needed** — coexistence is the strategy
471
+
472
+ ### Version Bump
473
+
474
+ - `package.json`: `2.0.1` → `2.1.0` (minor: new non-breaking features)
475
+ - `mcp-server.ts`: server version `2.0.0` → `2.1.0`
476
+
477
+ ### Risk Assessment
478
+
479
+ | Risk | Mitigation |
480
+ |------|-----------|
481
+ | Parent folder not found when saving child | Throw clear error: "Parent must be saved first" |
482
+ | UUID collision in folder scan | UUID v4 collision probability is negligible |
483
+ | Performance with many folders | `readdirSync` is fast; add caching later if needed |
484
+ | Breaking existing .pde/ consumers | Old format still works; new fields are optional |
485
+
486
+ ---
487
+
488
+ ## 7. Implementation Estimate
489
+
490
+ ### This Session (Phase 1 — EAST Design) ✅
491
+ - [x] Analyze codebase completely
492
+ - [x] Design schema changes
493
+ - [x] Identify all insertion points with line numbers
494
+ - [x] Write design document (this file)
495
+
496
+ ### Next Session (Phase 2 — SOUTH/WEST Implementation)
497
+ **Estimated: 1 focused session**
498
+
499
+ 1. **`src/types.ts`** — Add fields (~5 min)
500
+ 2. **`src/storage.ts`** — Implement folder logic (~45 min, most complex)
501
+ 3. **`src/pde-engine.ts`** — Pass-through params (~10 min)
502
+ 4. **`src/mcp-server.ts`** — Tool schema additions (~15 min)
503
+ 5. **`src/cli.ts`** — `--parent` flag (~10 min)
504
+ 6. **Tests** — New test cases for folder format + parent-child (~30 min)
505
+ 7. **rispecs update** — Document new schemas (~10 min)
506
+ 8. **Build + verify** — `npm run build && npm test` (~5 min)
507
+
508
+ ### Deferred (Phase 3 — NORTH)
509
+ - `AGENTS.md` auto-generation inside PDE folders
510
+ - Recursive child listing (grandchildren)
511
+ - `pde_tree` tool for visualizing hierarchy
512
+ - coaia-pde adoption of the new format
513
+ - mia-code/miaco widget upgrades (separate repos, separate issues)
514
+
515
+ ---
516
+
517
+ ## 8. Structural Tension Summary
518
+
519
+ | Aspect | Current Reality | Desired Outcome |
520
+ |--------|----------------|-----------------|
521
+ | **Storage** | Flat `.pde/<uuid>.json` | Timestamped folders with parent-child nesting |
522
+ | **Lineage** | None — each PDE is an island | `parent_pde_id` traces decomposition → sub-decomposition |
523
+ | **Navigability** | UUIDs are opaque | `<yyMMddHHmm>--<uuid>/` folders show time + structure |
524
+ | **Agent support** | No `AGENTS.md` convention | Folder format naturally hosts `AGENTS.md` alongside PDE |
525
+ | **Backward compat** | N/A | Old flat files remain readable forever |
@@ -0,0 +1,144 @@
1
+ # PDE-MCP Prompts Specification
2
+ > MCP Prompt Template Definitions for Prompt Decomposition Engine v2
3
+
4
+ **Version**: 2.0.0
5
+ **Document ID**: pde-mcp-prompts-v2
6
+
7
+ ## Creative Intent
8
+
9
+ ### Desired Outcome
10
+ LLM agents **access** a single reusable prompt template (`pde-decompose`) that produces a complete `DecompositionResult` JSON in one LLM call, replacing the v1 five-layer chained approach.
11
+
12
+ ## Prompt Definitions
13
+
14
+ ### Prompt 1: `pde-decompose`
15
+
16
+ **Purpose**: System prompt for LLM-driven prompt decomposition — instructs the LLM to output a `DecompositionResult` JSON object in a single call.
17
+
18
+ **What This Enables**: Any LLM (Claude, Gemini, GPT) produces a structured, consistent decomposition regardless of provider.
19
+
20
+ **Arguments**:
21
+ ```typescript
22
+ {
23
+ userPrompt: string; // Required: The prompt to decompose
24
+ extractImplicit?: string; // "true" (default) | "false"
25
+ mapDependencies?: string; // "true" (default) | "false"
26
+ }
27
+ ```
28
+
29
+ **System Prompt Structure**:
30
+ ```
31
+ You are a Prompt Decomposition Engine (PDE).
32
+
33
+ CRITICAL: Your response must be ONLY a valid JSON object. Do not include:
34
+ - Markdown code fences (no ```json)
35
+ - Explanatory text before or after the JSON
36
+ - Any commentary or notes
37
+
38
+ Just output the raw JSON object starting with { and ending with }.
39
+
40
+ Analyze the user's prompt and output with this exact structure:
41
+ <JSON_SCHEMA_EXAMPLE>
42
+
43
+ Directions mapping (Medicine Wheel / Four Directions):
44
+ - EAST (🌅 Vision): Understanding what is being asked, clarifying requirements, envisioning desired outcomes
45
+ - SOUTH (🔥 Analysis): Research, learning, investigation, growth tasks
46
+ - WEST (🌊 Validation): Testing, reflection, review, accountability tasks
47
+ - NORTH (❄️ Action): Implementation, execution, delivery, wisdom tasks
48
+
49
+ [extractImplicit rule: extract implicit intents from hedging language OR only explicit intents]
50
+ [mapDependencies rule: map dependency fields OR set all to null]
51
+
52
+ Rules:
53
+ - Assign confidence scores (0.0-1.0) based on how clearly the intent is stated.
54
+ - Flag ambiguities where the prompt uses "somehow", "probably", "maybe", or leaves method unspecified.
55
+ - Generate actionStack as an ordered list respecting dependencies, each item mapped to a direction.
56
+ - For secondary intents, distinguish explicit from implicit.
57
+ - The primary intent is the single most important action.
58
+ - context.assumptions captures statements assumed true but not verified.
59
+ ```
60
+
61
+ **User Message Format**:
62
+ ```
63
+ Prompt to decompose:
64
+ "<userPrompt>"
65
+ ```
66
+
67
+ **Expected JSON Output** (DecompositionResult schema):
68
+ ```json
69
+ {
70
+ "primary": {
71
+ "action": "main action verb",
72
+ "target": "what the action applies to",
73
+ "urgency": "immediate|session|persistent",
74
+ "confidence": 0.95
75
+ },
76
+ "secondary": [
77
+ {
78
+ "action": "action verb",
79
+ "target": "target",
80
+ "implicit": false,
81
+ "dependency": "what this depends on or null",
82
+ "confidence": 0.8
83
+ }
84
+ ],
85
+ "context": {
86
+ "files_needed": ["list of files"],
87
+ "tools_required": ["list of tools"],
88
+ "assumptions": ["statements assumed true"]
89
+ },
90
+ "outputs": {
91
+ "artifacts": ["new files to create"],
92
+ "updates": ["existing files to update"],
93
+ "communications": ["PRs, issues, docs"]
94
+ },
95
+ "directions": {
96
+ "east": [{"text": "vision items", "confidence": 0.9, "implicit": false}],
97
+ "south": [{"text": "analysis items", "confidence": 0.8, "implicit": false}],
98
+ "west": [{"text": "validation items", "confidence": 0.7, "implicit": true}],
99
+ "north": [{"text": "action items", "confidence": 0.9, "implicit": false}]
100
+ },
101
+ "actionStack": [
102
+ {"text": "task description", "direction": "east", "dependency": null, "completed": false},
103
+ {"text": "next task", "direction": "south", "dependency": "prior task", "completed": false}
104
+ ],
105
+ "ambiguities": [
106
+ {"text": "ambiguous part", "suggestion": "how to clarify"}
107
+ ]
108
+ }
109
+ ```
110
+
111
+ ## Prompt Access via MCP
112
+
113
+ ### Via `GetPrompt` (MCP prompt primitive)
114
+ ```
115
+ name: pde-decompose
116
+ arguments:
117
+ userPrompt: "Create user auth with JWT, PostgreSQL, tests, deploy to staging"
118
+ extractImplicit: "true"
119
+ mapDependencies: "true"
120
+ ```
121
+
122
+ Returns a `messages` array with a single user message combining system prompt + user message.
123
+
124
+ ### Via `pde_decompose` Tool (preferred for agents)
125
+ The `pde_decompose` tool is the preferred access pattern — it returns `systemPrompt` and `userMessage` separately, so the calling agent can send them as proper system/user roles to their LLM provider.
126
+
127
+ ```
128
+ pde_decompose({ prompt: "...", options: { extractImplicit: true, mapDependencies: true } })
129
+ → {
130
+ instructions: "Send systemPrompt as system message...",
131
+ systemPrompt: "You are a Prompt Decomposition Engine...",
132
+ userMessage: 'Prompt to decompose:\n"..."',
133
+ original_prompt: "..."
134
+ }
135
+ ```
136
+
137
+ ## Options Behavior
138
+
139
+ | Option | Default | Effect |
140
+ |--------|---------|--------|
141
+ | `extractImplicit: true` | ✅ | Extracts implicit intents from hedging language ("which I assume", "you will need", "somehow", "I expect", "probably", "should"). Marks them `implicit: true`. |
142
+ | `extractImplicit: false` | — | Only explicit intents. All `implicit: false`. |
143
+ | `mapDependencies: true` | ✅ | Maps `dependency` fields in secondary intents and actionStack to show ordering requirements. |
144
+ | `mapDependencies: false` | — | All `dependency` fields set to `null`. |