modular-studio 1.0.5 → 1.1.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.
Files changed (232) hide show
  1. package/README.md +122 -122
  2. package/dist/assets/Badge-Bsy2H_p2.js +1 -0
  3. package/dist/assets/GraphPanel-D4X3faxA.js +47 -0
  4. package/dist/assets/{Input-Bgp734xs.js → Input-Dyb88Erk.js} +1 -1
  5. package/dist/assets/KnowledgeTab-BccWz7Np.js +5 -0
  6. package/dist/assets/MemoryTab-Y_66cE01.js +16 -0
  7. package/dist/assets/QualificationTab-Dm9dEIpM.js +1 -0
  8. package/dist/assets/ReviewTab-BrfXSyyf.js +104 -0
  9. package/dist/assets/{Section-DoJrmytO.js → Section-68XDCFTl.js} +1 -1
  10. package/dist/assets/TestTab-CLKRT63X.js +42 -0
  11. package/dist/assets/ToolsTab-xumi9Uds.js +1 -0
  12. package/dist/assets/icons-CS8RUPBi.js +1 -0
  13. package/dist/assets/index-B2bm0161.css +1 -0
  14. package/dist/assets/index-C626nWuA.js +422 -0
  15. package/dist/assets/services-BDk6yY4o.js +369 -0
  16. package/dist/index.html +18 -18
  17. package/dist-server/bin/modular-mcp.js +1 -0
  18. package/dist-server/server/index.d.ts.map +1 -1
  19. package/dist-server/server/index.js +34 -0
  20. package/dist-server/server/mcp/manager.d.ts +3 -0
  21. package/dist-server/server/mcp/manager.d.ts.map +1 -1
  22. package/dist-server/server/mcp/manager.js +80 -5
  23. package/dist-server/server/migrations/index.d.ts +11 -0
  24. package/dist-server/server/migrations/index.d.ts.map +1 -0
  25. package/dist-server/server/migrations/index.js +57 -0
  26. package/dist-server/server/routes/agents.d.ts.map +1 -1
  27. package/dist-server/server/routes/agents.js +27 -0
  28. package/dist-server/server/routes/analytics.d.ts +3 -0
  29. package/dist-server/server/routes/analytics.d.ts.map +1 -0
  30. package/dist-server/server/routes/analytics.js +24 -0
  31. package/dist-server/server/routes/cache.d.ts +3 -0
  32. package/dist-server/server/routes/cache.d.ts.map +1 -0
  33. package/dist-server/server/routes/cache.js +55 -0
  34. package/dist-server/server/routes/connectors/airtable.d.ts +7 -0
  35. package/dist-server/server/routes/connectors/airtable.d.ts.map +1 -0
  36. package/dist-server/server/routes/connectors/airtable.js +119 -0
  37. package/dist-server/server/routes/connectors/confluence.d.ts +7 -0
  38. package/dist-server/server/routes/connectors/confluence.d.ts.map +1 -0
  39. package/dist-server/server/routes/connectors/confluence.js +176 -0
  40. package/dist-server/server/routes/connectors/github.d.ts +7 -0
  41. package/dist-server/server/routes/connectors/github.d.ts.map +1 -0
  42. package/dist-server/server/routes/connectors/github.js +195 -0
  43. package/dist-server/server/routes/connectors/gmail.d.ts +7 -0
  44. package/dist-server/server/routes/connectors/gmail.d.ts.map +1 -0
  45. package/dist-server/server/routes/connectors/gmail.js +115 -0
  46. package/dist-server/server/routes/connectors/google-docs.d.ts +10 -0
  47. package/dist-server/server/routes/connectors/google-docs.d.ts.map +1 -0
  48. package/dist-server/server/routes/connectors/google-docs.js +165 -0
  49. package/dist-server/server/routes/connectors/google-drive.d.ts +7 -0
  50. package/dist-server/server/routes/connectors/google-drive.d.ts.map +1 -0
  51. package/dist-server/server/routes/connectors/google-drive.js +163 -0
  52. package/dist-server/server/routes/connectors/google-sheets.d.ts +7 -0
  53. package/dist-server/server/routes/connectors/google-sheets.d.ts.map +1 -0
  54. package/dist-server/server/routes/connectors/google-sheets.js +90 -0
  55. package/dist-server/server/routes/connectors/hubspot.d.ts +7 -0
  56. package/dist-server/server/routes/connectors/hubspot.d.ts.map +1 -0
  57. package/dist-server/server/routes/connectors/hubspot.js +134 -0
  58. package/dist-server/server/routes/connectors/index.d.ts +6 -0
  59. package/dist-server/server/routes/connectors/index.d.ts.map +1 -0
  60. package/dist-server/server/routes/connectors/index.js +38 -0
  61. package/dist-server/server/routes/connectors/jira.d.ts +7 -0
  62. package/dist-server/server/routes/connectors/jira.d.ts.map +1 -0
  63. package/dist-server/server/routes/connectors/jira.js +151 -0
  64. package/dist-server/server/routes/connectors/linear.d.ts +7 -0
  65. package/dist-server/server/routes/connectors/linear.d.ts.map +1 -0
  66. package/dist-server/server/routes/connectors/linear.js +154 -0
  67. package/dist-server/server/routes/connectors/notion.d.ts +10 -0
  68. package/dist-server/server/routes/connectors/notion.d.ts.map +1 -0
  69. package/dist-server/server/routes/connectors/notion.js +201 -0
  70. package/dist-server/server/routes/connectors/plane.d.ts +10 -0
  71. package/dist-server/server/routes/connectors/plane.d.ts.map +1 -0
  72. package/dist-server/server/routes/connectors/plane.js +189 -0
  73. package/dist-server/server/routes/connectors/shared.d.ts +25 -0
  74. package/dist-server/server/routes/connectors/shared.d.ts.map +1 -0
  75. package/dist-server/server/routes/connectors/shared.js +202 -0
  76. package/dist-server/server/routes/connectors/slack.d.ts +7 -0
  77. package/dist-server/server/routes/connectors/slack.d.ts.map +1 -0
  78. package/dist-server/server/routes/connectors/slack.js +153 -0
  79. package/dist-server/server/routes/connectors.d.ts.map +1 -1
  80. package/dist-server/server/routes/connectors.js +47 -17
  81. package/dist-server/server/routes/cost.d.ts +3 -0
  82. package/dist-server/server/routes/cost.d.ts.map +1 -0
  83. package/dist-server/server/routes/cost.js +113 -0
  84. package/dist-server/server/routes/graph.d.ts +11 -0
  85. package/dist-server/server/routes/graph.d.ts.map +1 -0
  86. package/dist-server/server/routes/graph.js +213 -0
  87. package/dist-server/server/routes/lessons.d.ts +3 -0
  88. package/dist-server/server/routes/lessons.d.ts.map +1 -0
  89. package/dist-server/server/routes/lessons.js +160 -0
  90. package/dist-server/server/routes/llm.d.ts.map +1 -1
  91. package/dist-server/server/routes/llm.js +85 -18
  92. package/dist-server/server/routes/memory.d.ts.map +1 -1
  93. package/dist-server/server/routes/memory.js +31 -0
  94. package/dist-server/server/routes/metaprompt-v2.d.ts +3 -0
  95. package/dist-server/server/routes/metaprompt-v2.d.ts.map +1 -0
  96. package/dist-server/server/routes/metaprompt-v2.js +104 -0
  97. package/dist-server/server/routes/qualification.d.ts.map +1 -1
  98. package/dist-server/server/routes/qualification.js +342 -334
  99. package/dist-server/server/routes/repo-index.d.ts.map +1 -1
  100. package/dist-server/server/routes/repo-index.js +7 -0
  101. package/dist-server/server/routes/skills-search.d.ts.map +1 -1
  102. package/dist-server/server/routes/skills-search.js +192 -26
  103. package/dist-server/server/routes/tool-analytics.d.ts +3 -0
  104. package/dist-server/server/routes/tool-analytics.d.ts.map +1 -0
  105. package/dist-server/server/routes/tool-analytics.js +47 -0
  106. package/dist-server/server/services/adapters/hindsightAdapter.d.ts +28 -0
  107. package/dist-server/server/services/adapters/hindsightAdapter.d.ts.map +1 -0
  108. package/dist-server/server/services/adapters/hindsightAdapter.js +63 -0
  109. package/dist-server/server/services/adapters/postgresAdapter.js +30 -30
  110. package/dist-server/server/services/adapters/sqliteAdapter.d.ts +1 -0
  111. package/dist-server/server/services/adapters/sqliteAdapter.d.ts.map +1 -1
  112. package/dist-server/server/services/adapters/sqliteAdapter.js +66 -36
  113. package/dist-server/server/services/agentStore.d.ts +2 -1
  114. package/dist-server/server/services/agentStore.d.ts.map +1 -1
  115. package/dist-server/server/services/agentStore.js +2 -1
  116. package/dist-server/server/services/correctionDetector.d.ts +22 -0
  117. package/dist-server/server/services/correctionDetector.d.ts.map +1 -0
  118. package/dist-server/server/services/correctionDetector.js +91 -0
  119. package/dist-server/server/services/credentialStore.d.ts +10 -0
  120. package/dist-server/server/services/credentialStore.d.ts.map +1 -0
  121. package/dist-server/server/services/credentialStore.js +123 -0
  122. package/dist-server/server/services/hindsightClient.d.ts +15 -0
  123. package/dist-server/server/services/hindsightClient.d.ts.map +1 -0
  124. package/dist-server/server/services/hindsightClient.js +48 -0
  125. package/dist-server/server/services/lessonExtractor.d.ts +21 -0
  126. package/dist-server/server/services/lessonExtractor.d.ts.map +1 -0
  127. package/dist-server/server/services/lessonExtractor.js +92 -0
  128. package/dist-server/server/services/repoIndexer.d.ts +7 -1
  129. package/dist-server/server/services/repoIndexer.d.ts.map +1 -1
  130. package/dist-server/server/services/repoIndexer.js +295 -94
  131. package/dist-server/server/services/responseCache.d.ts +24 -0
  132. package/dist-server/server/services/responseCache.d.ts.map +1 -0
  133. package/dist-server/server/services/responseCache.js +163 -0
  134. package/dist-server/server/services/sqliteStore.d.ts +72 -0
  135. package/dist-server/server/services/sqliteStore.d.ts.map +1 -1
  136. package/dist-server/server/services/sqliteStore.js +291 -13
  137. package/dist-server/src/config.d.ts +2 -0
  138. package/dist-server/src/config.d.ts.map +1 -0
  139. package/dist-server/src/config.js +3 -0
  140. package/dist-server/src/graph/db.d.ts +46 -0
  141. package/dist-server/src/graph/db.d.ts.map +1 -0
  142. package/dist-server/src/graph/db.js +241 -0
  143. package/dist-server/src/graph/extractors/code.d.ts +12 -0
  144. package/dist-server/src/graph/extractors/code.d.ts.map +1 -0
  145. package/dist-server/src/graph/extractors/code.js +239 -0
  146. package/dist-server/src/graph/extractors/cross-type.d.ts +16 -0
  147. package/dist-server/src/graph/extractors/cross-type.d.ts.map +1 -0
  148. package/dist-server/src/graph/extractors/cross-type.js +67 -0
  149. package/dist-server/src/graph/extractors/markdown.d.ts +29 -0
  150. package/dist-server/src/graph/extractors/markdown.d.ts.map +1 -0
  151. package/dist-server/src/graph/extractors/markdown.js +224 -0
  152. package/dist-server/src/graph/extractors/yaml.d.ts +15 -0
  153. package/dist-server/src/graph/extractors/yaml.d.ts.map +1 -0
  154. package/dist-server/src/graph/extractors/yaml.js +104 -0
  155. package/dist-server/src/graph/index.d.ts +62 -0
  156. package/dist-server/src/graph/index.d.ts.map +1 -0
  157. package/dist-server/src/graph/index.js +67 -0
  158. package/dist-server/src/graph/packer.d.ts +19 -0
  159. package/dist-server/src/graph/packer.d.ts.map +1 -0
  160. package/dist-server/src/graph/packer.js +134 -0
  161. package/dist-server/src/graph/resolver.d.ts +12 -0
  162. package/dist-server/src/graph/resolver.d.ts.map +1 -0
  163. package/dist-server/src/graph/resolver.js +81 -0
  164. package/dist-server/src/graph/scanner.d.ts +34 -0
  165. package/dist-server/src/graph/scanner.d.ts.map +1 -0
  166. package/dist-server/src/graph/scanner.js +252 -0
  167. package/dist-server/src/graph/traverser.d.ts +17 -0
  168. package/dist-server/src/graph/traverser.d.ts.map +1 -0
  169. package/dist-server/src/graph/traverser.js +185 -0
  170. package/dist-server/src/graph/types.d.ts +117 -0
  171. package/dist-server/src/graph/types.d.ts.map +1 -0
  172. package/dist-server/src/graph/types.js +63 -0
  173. package/dist-server/src/metaprompt/v2/assembler.d.ts +3 -0
  174. package/dist-server/src/metaprompt/v2/assembler.d.ts.map +1 -0
  175. package/dist-server/src/metaprompt/v2/assembler.js +261 -0
  176. package/dist-server/src/metaprompt/v2/context-strategist.d.ts +3 -0
  177. package/dist-server/src/metaprompt/v2/context-strategist.d.ts.map +1 -0
  178. package/dist-server/src/metaprompt/v2/context-strategist.js +173 -0
  179. package/dist-server/src/metaprompt/v2/evaluator.d.ts +3 -0
  180. package/dist-server/src/metaprompt/v2/evaluator.d.ts.map +1 -0
  181. package/dist-server/src/metaprompt/v2/evaluator.js +281 -0
  182. package/dist-server/src/metaprompt/v2/index.d.ts +41 -0
  183. package/dist-server/src/metaprompt/v2/index.d.ts.map +1 -0
  184. package/dist-server/src/metaprompt/v2/index.js +90 -0
  185. package/dist-server/src/metaprompt/v2/parser.d.ts +3 -0
  186. package/dist-server/src/metaprompt/v2/parser.d.ts.map +1 -0
  187. package/dist-server/src/metaprompt/v2/parser.js +138 -0
  188. package/dist-server/src/metaprompt/v2/pattern-selector.d.ts +3 -0
  189. package/dist-server/src/metaprompt/v2/pattern-selector.d.ts.map +1 -0
  190. package/dist-server/src/metaprompt/v2/pattern-selector.js +154 -0
  191. package/dist-server/src/metaprompt/v2/researcher.d.ts +3 -0
  192. package/dist-server/src/metaprompt/v2/researcher.d.ts.map +1 -0
  193. package/dist-server/src/metaprompt/v2/researcher.js +194 -0
  194. package/dist-server/src/metaprompt/v2/tool-discovery.d.ts +74 -0
  195. package/dist-server/src/metaprompt/v2/tool-discovery.d.ts.map +1 -0
  196. package/dist-server/src/metaprompt/v2/tool-discovery.js +290 -0
  197. package/dist-server/src/metaprompt/v2/types.d.ts +154 -0
  198. package/dist-server/src/metaprompt/v2/types.d.ts.map +1 -0
  199. package/dist-server/src/metaprompt/v2/types.js +2 -0
  200. package/dist-server/src/services/contradictionDetector.js +1 -1
  201. package/dist-server/src/services/llmService.d.ts +61 -0
  202. package/dist-server/src/services/llmService.d.ts.map +1 -0
  203. package/dist-server/src/services/llmService.js +222 -0
  204. package/dist-server/src/store/knowledgeBase.d.ts +6 -1
  205. package/dist-server/src/store/knowledgeBase.d.ts.map +1 -1
  206. package/dist-server/src/store/knowledgeBase.js +0 -1
  207. package/dist-server/src/store/lessonStore.d.ts +26 -0
  208. package/dist-server/src/store/lessonStore.d.ts.map +1 -0
  209. package/dist-server/src/store/lessonStore.js +64 -0
  210. package/dist-server/src/store/mcp-registry.d.ts +29 -0
  211. package/dist-server/src/store/mcp-registry.d.ts.map +1 -0
  212. package/dist-server/src/store/mcp-registry.js +1303 -0
  213. package/dist-server/src/store/memoryStore.d.ts +12 -1
  214. package/dist-server/src/store/memoryStore.d.ts.map +1 -1
  215. package/dist-server/src/store/memoryStore.js +9 -0
  216. package/dist-server/src/types/registry.types.d.ts +13 -0
  217. package/dist-server/src/types/registry.types.d.ts.map +1 -0
  218. package/dist-server/src/types/registry.types.js +2 -0
  219. package/dist-server/tsconfig.server.tsbuildinfo +1 -1
  220. package/package.json +15 -1
  221. package/scripts/cleanup-worktrees.ps1 +29 -0
  222. package/dist/assets/Badge-22Ai0eyi.js +0 -1
  223. package/dist/assets/KnowledgeTab-DABxirZh.js +0 -4
  224. package/dist/assets/MemoryTab-DZeYElIT.js +0 -16
  225. package/dist/assets/QualificationTab-Dfpy3J30.js +0 -1
  226. package/dist/assets/ReviewTab-SD8lQuCc.js +0 -103
  227. package/dist/assets/TestTab-PDyMF8Fw.js +0 -33
  228. package/dist/assets/ToolsTab-B83qGCmG.js +0 -1
  229. package/dist/assets/icons-C2EV-le6.js +0 -1
  230. package/dist/assets/index-DkpMAxX7.css +0 -1
  231. package/dist/assets/index-q24ug5Qs.js +0 -143
  232. package/dist/assets/services-BaKotDf0.js +0 -343
@@ -0,0 +1,281 @@
1
+ import { fetchCompletion } from '../../services/llmService.js';
2
+ function parseJSON(text) {
3
+ try {
4
+ return JSON.parse(text);
5
+ }
6
+ catch { /* continue */ }
7
+ const fenceMatch = text.match(/```(?:json)?\s*([\s\S]*?)```/);
8
+ if (fenceMatch) {
9
+ try {
10
+ return JSON.parse(fenceMatch[1].trim());
11
+ }
12
+ catch { /* continue */ }
13
+ }
14
+ const braceMatch = text.match(/\{[\s\S]*\}/);
15
+ if (braceMatch) {
16
+ try {
17
+ return JSON.parse(braceMatch[0]);
18
+ }
19
+ catch { /* continue */ }
20
+ }
21
+ return null;
22
+ }
23
+ /**
24
+ * Check: every named expert and methodology from parsing appears as
25
+ * an operationalized workflow step (not just in persona text).
26
+ */
27
+ function checkFrameworkCoverage(_parsed, research, assembled) {
28
+ const missing = [];
29
+ const stepText = assembled.workflow_steps.map(s => `${s.name} ${s.process} ${s.output}`).join(' ').toLowerCase();
30
+ for (const ef of research.expert_frameworks) {
31
+ const nameInSteps = stepText.includes(ef.expert_name.toLowerCase()) ||
32
+ stepText.includes(ef.framework_name.toLowerCase());
33
+ if (!nameInSteps) {
34
+ missing.push(`${ef.expert_name} (${ef.framework_name})`);
35
+ }
36
+ }
37
+ for (const mf of research.methodology_frameworks) {
38
+ if (!stepText.includes(mf.name.toLowerCase())) {
39
+ missing.push(mf.name);
40
+ }
41
+ }
42
+ if (missing.length === 0) {
43
+ return { passed: true };
44
+ }
45
+ return {
46
+ passed: false,
47
+ issue: `Missing from workflow steps: ${missing.join(', ')}`,
48
+ fix_applied: 'Added missing framework steps during assembly post-processing',
49
+ };
50
+ }
51
+ /**
52
+ * Check: no step contains vague phrases like "apply best practices",
53
+ * "use appropriate methods", "leverage expertise".
54
+ */
55
+ function checkSpecificity(assembled) {
56
+ const vaguePatterns = [
57
+ /apply\s+best\s+practices/i,
58
+ /use\s+appropriate\s+methods/i,
59
+ /leverage\s+(your\s+)?expertise/i,
60
+ /utilize\s+(your\s+)?knowledge/i,
61
+ /as\s+needed/i,
62
+ /when\s+appropriate/i,
63
+ ];
64
+ const vagueSteps = [];
65
+ for (const step of assembled.workflow_steps) {
66
+ const combined = `${step.process} ${step.input} ${step.output}`;
67
+ for (const pattern of vaguePatterns) {
68
+ if (pattern.test(combined)) {
69
+ vagueSteps.push(`Step ${step.number} "${step.name}": matches "${pattern.source}"`);
70
+ break;
71
+ }
72
+ }
73
+ }
74
+ if (vagueSteps.length === 0)
75
+ return { passed: true };
76
+ return {
77
+ passed: false,
78
+ issue: `Vague language in steps: ${vagueSteps.join('; ')}`,
79
+ };
80
+ }
81
+ /**
82
+ * Check: no sentence in persona repeated in workflow or role.
83
+ */
84
+ function checkPersonaDuplication(assembled) {
85
+ const personaSentences = assembled.persona.split(/[.!?]+/).map(s => s.trim().toLowerCase()).filter(s => s.length > 20);
86
+ const workflowText = assembled.workflow_steps.map(s => s.process).join(' ').toLowerCase();
87
+ const roleText = assembled.role.toLowerCase();
88
+ const duplicates = [];
89
+ for (const sentence of personaSentences) {
90
+ if (workflowText.includes(sentence) || roleText.includes(sentence)) {
91
+ duplicates.push(sentence.slice(0, 60) + '...');
92
+ }
93
+ }
94
+ if (duplicates.length === 0)
95
+ return { passed: true };
96
+ return {
97
+ passed: false,
98
+ issue: `Persona/workflow duplication: ${duplicates.join('; ')}`,
99
+ };
100
+ }
101
+ /**
102
+ * Check: total always_loaded tokens < 60% of budget.
103
+ */
104
+ function checkContextEfficiency(context) {
105
+ if (context.classified_documents.length === 0)
106
+ return { passed: true };
107
+ const ratio = context.total_always_loaded_tokens / context.token_budget;
108
+ if (ratio <= 0.6)
109
+ return { passed: true };
110
+ return {
111
+ passed: false,
112
+ issue: `Always-loaded context is ${Math.round(ratio * 100)}% of budget (${context.total_always_loaded_tokens}/${context.token_budget}). Should be ≤60%.`,
113
+ fix_applied: 'Documents were auto-demoted during context strategy phase',
114
+ };
115
+ }
116
+ /**
117
+ * Check: persistence, tool_discipline, and planning are present.
118
+ */
119
+ function checkAgenticCompleteness(assembled) {
120
+ const missing = [];
121
+ if (!assembled.agentic_pillars.persistence)
122
+ missing.push('persistence');
123
+ if (!assembled.agentic_pillars.tool_discipline)
124
+ missing.push('tool_discipline');
125
+ if (!assembled.agentic_pillars.planning)
126
+ missing.push('planning');
127
+ if (missing.length === 0)
128
+ return { passed: true };
129
+ return {
130
+ passed: false,
131
+ issue: `Missing agentic pillars: ${missing.join(', ')}`,
132
+ };
133
+ }
134
+ /**
135
+ * Check: output format has specific fields, not just "markdown".
136
+ */
137
+ function checkOutputSpecificity(assembled) {
138
+ const schema = assembled.output_schema;
139
+ if (schema.primary_artifact?.name &&
140
+ schema.primary_artifact?.required_fields?.length > 0) {
141
+ return { passed: true };
142
+ }
143
+ return {
144
+ passed: false,
145
+ issue: 'Output schema missing specific fields or artifact definition',
146
+ };
147
+ }
148
+ /**
149
+ * Convert assembled agent to YAML string.
150
+ */
151
+ function toYaml(assembled, parsed) {
152
+ const lines = [];
153
+ lines.push('---');
154
+ lines.push(`name: ${parsed.role || 'Generated Agent'}`);
155
+ lines.push(`description: ${assembled.role}`);
156
+ lines.push('---');
157
+ lines.push('');
158
+ lines.push('## Persona');
159
+ lines.push(assembled.persona);
160
+ lines.push('');
161
+ lines.push('## Agentic Directives');
162
+ lines.push(`- **Persistence:** ${assembled.agentic_pillars.persistence}`);
163
+ lines.push(`- **Tool Discipline:** ${assembled.agentic_pillars.tool_discipline}`);
164
+ lines.push(`- **Planning:** ${assembled.agentic_pillars.planning}`);
165
+ lines.push('');
166
+ lines.push('## Workflow');
167
+ for (const step of assembled.workflow_steps) {
168
+ lines.push(`### Step ${step.number}: ${step.name}`);
169
+ lines.push(`**Input:** ${step.input}`);
170
+ lines.push(`**Process:**`);
171
+ lines.push(step.process);
172
+ lines.push(`**Output:** ${step.output}`);
173
+ if (step.decision_rules.length > 0) {
174
+ lines.push(`**Decision Rules:**`);
175
+ for (const rule of step.decision_rules) {
176
+ lines.push(`- ${rule}`);
177
+ }
178
+ }
179
+ if (step.tools_used.length > 0) {
180
+ lines.push(`**Tools:** ${step.tools_used.join(', ')}`);
181
+ }
182
+ lines.push('');
183
+ }
184
+ lines.push('## Output Schema');
185
+ lines.push(`**Primary:** ${assembled.output_schema.primary_artifact.name} (${assembled.output_schema.primary_artifact.format})`);
186
+ lines.push(`**Required fields:** ${assembled.output_schema.primary_artifact.required_fields.join(', ')}`);
187
+ if (assembled.output_schema.secondary_artifacts.length > 0) {
188
+ lines.push('**Secondary:**');
189
+ for (const sa of assembled.output_schema.secondary_artifacts) {
190
+ lines.push(`- ${sa.name} (${sa.format})`);
191
+ }
192
+ }
193
+ lines.push('');
194
+ if (assembled.context_strategy) {
195
+ lines.push('## Context Strategy');
196
+ lines.push(assembled.context_strategy);
197
+ lines.push('');
198
+ }
199
+ lines.push('## Self-Check');
200
+ for (const q of assembled.self_check.questions) {
201
+ lines.push(`- ${q}`);
202
+ }
203
+ lines.push(`**Action:** ${assembled.self_check.action}`);
204
+ return lines.join('\n');
205
+ }
206
+ export async function runEvaluator(parsed, research, assembled, context, llmConfig) {
207
+ // Run all 6 criteria
208
+ const criteria_results = {
209
+ framework_coverage: checkFrameworkCoverage(parsed, research, assembled),
210
+ specificity: checkSpecificity(assembled),
211
+ persona_duplication: checkPersonaDuplication(assembled),
212
+ context_efficiency: checkContextEfficiency(context),
213
+ agentic_completeness: checkAgenticCompleteness(assembled),
214
+ output_specificity: checkOutputSpecificity(assembled),
215
+ };
216
+ const warnings = [];
217
+ const failedCriteria = Object.entries(criteria_results).filter(([, r]) => !r.passed);
218
+ // If specificity fails, attempt LLM-based fix (1 retry max)
219
+ if (criteria_results.specificity && !criteria_results.specificity.passed) {
220
+ const vagueSteps = assembled.workflow_steps.filter(step => {
221
+ const combined = `${step.process} ${step.input} ${step.output}`;
222
+ return /apply\s+best\s+practices|use\s+appropriate|leverage\s+expertise|utilize\s+knowledge|as\s+needed|when\s+appropriate/i.test(combined);
223
+ });
224
+ if (vagueSteps.length > 0) {
225
+ try {
226
+ const fixText = await fetchCompletion({
227
+ providerId: llmConfig.providerId,
228
+ model: llmConfig.model,
229
+ messages: [
230
+ {
231
+ role: 'system',
232
+ content: 'Rewrite these workflow step processes to be specific and actionable. Replace ALL vague language with concrete procedures, scoring criteria, or decision rules. Return a JSON array of {number, process} objects.',
233
+ },
234
+ {
235
+ role: 'user',
236
+ content: JSON.stringify(vagueSteps.map(s => ({ number: s.number, name: s.name, process: s.process }))),
237
+ },
238
+ ],
239
+ temperature: 0.2,
240
+ maxTokens: 2048,
241
+ });
242
+ const fixes = parseJSON(fixText);
243
+ if (fixes && Array.isArray(fixes)) {
244
+ for (const fix of fixes) {
245
+ const step = assembled.workflow_steps.find(s => s.number === fix.number);
246
+ if (step && fix.process) {
247
+ step.process = fix.process;
248
+ }
249
+ }
250
+ criteria_results.specificity = checkSpecificity(assembled);
251
+ if (criteria_results.specificity.passed) {
252
+ criteria_results.specificity.fix_applied = 'Vague language replaced via LLM refinement';
253
+ }
254
+ }
255
+ }
256
+ catch {
257
+ warnings.push('Specificity auto-fix failed — vague language remains in some steps');
258
+ }
259
+ }
260
+ }
261
+ // Collect remaining warnings
262
+ for (const [name, result] of failedCriteria) {
263
+ if (!result.passed && !result.fix_applied) {
264
+ warnings.push(`${name}: ${result.issue}`);
265
+ }
266
+ }
267
+ // Add research confidence warnings
268
+ for (const ef of research.expert_frameworks) {
269
+ if (ef.research_confidence === 'low') {
270
+ warnings.push(`⚠️ Low confidence on ${ef.expert_name}'s framework — verify accuracy`);
271
+ }
272
+ }
273
+ const passed = Object.values(criteria_results).every(r => r.passed);
274
+ const finalYaml = toYaml(assembled, parsed);
275
+ return {
276
+ passed,
277
+ criteria_results,
278
+ final_yaml: finalYaml,
279
+ warnings,
280
+ };
281
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Metaprompt V2 Pipeline Orchestrator
3
+ *
4
+ * Runs the 6-phase research-augmented agent generation pipeline:
5
+ * Parse → Research → Pattern Select → Context Strategy → Assemble → Evaluate
6
+ */
7
+ import type { V2PipelineConfig, V2PipelineResult } from './types.js';
8
+ export type { V2PipelineConfig, V2PipelineResult };
9
+ export interface PipelineOptions {
10
+ /** Provider ID for LLM calls */
11
+ providerId: string;
12
+ /** Model for fast phases (1,2,3,4,6) — typically Sonnet */
13
+ sonnetModel: string;
14
+ /** Model for assembly phase (5) — typically Opus */
15
+ opusModel: string;
16
+ /** Token budget for context strategy. Default: 4000 */
17
+ tokenBudget?: number;
18
+ /** Progress callback — called after each phase completes */
19
+ onPhaseComplete?: (phase: string, elapsed: number) => void;
20
+ /** Warning callback — called when a phase fails non-fatally (e.g. tool discovery) */
21
+ onPhaseWarning?: (phase: string, message: string) => void;
22
+ /** Already-installed IDs to exclude from suggestions */
23
+ installed?: {
24
+ skillIds: string[];
25
+ mcpIds: string[];
26
+ connectorIds: string[];
27
+ };
28
+ }
29
+ /**
30
+ * Run the full V2 metaprompt pipeline.
31
+ *
32
+ * @param userInput - Natural language description of the desired agent
33
+ * @param options - Pipeline configuration (models, budget, callbacks)
34
+ * @returns Full pipeline result with timing data
35
+ */
36
+ export declare function runV2Pipeline(userInput: string, options: PipelineOptions): Promise<V2PipelineResult>;
37
+ /**
38
+ * Quick convenience: run pipeline and return just the YAML.
39
+ */
40
+ export declare function generateAgentV2(userInput: string, options: PipelineOptions): Promise<string>;
41
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/metaprompt/v2/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAiB,MAAM,YAAY,CAAC;AAEpF,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,CAAC;AAEnD,MAAM,WAAW,eAAe;IAC9B,gCAAgC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,WAAW,EAAE,MAAM,CAAC;IACpB,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAC;IAClB,uDAAuD;IACvD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4DAA4D;IAC5D,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3D,qFAAqF;IACrF,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1D,wDAAwD;IACxD,SAAS,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,YAAY,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;CAC9E;AAUD;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,gBAAgB,CAAC,CAsE3B;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,MAAM,CAAC,CAGjB"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Metaprompt V2 Pipeline Orchestrator
3
+ *
4
+ * Runs the 6-phase research-augmented agent generation pipeline:
5
+ * Parse → Research → Pattern Select → Context Strategy → Assemble → Evaluate
6
+ */
7
+ import { runParser } from './parser.js';
8
+ import { runResearcher } from './researcher.js';
9
+ import { runPatternSelector } from './pattern-selector.js';
10
+ import { runContextStrategist } from './context-strategist.js';
11
+ import { runAssembler } from './assembler.js';
12
+ import { runEvaluator } from './evaluator.js';
13
+ import { discoverTools } from './tool-discovery.js';
14
+ function sonnetConfig(opts) {
15
+ return { providerId: opts.providerId, model: opts.sonnetModel };
16
+ }
17
+ function opusConfig(opts) {
18
+ return { providerId: opts.providerId, model: opts.opusModel };
19
+ }
20
+ /**
21
+ * Run the full V2 metaprompt pipeline.
22
+ *
23
+ * @param userInput - Natural language description of the desired agent
24
+ * @param options - Pipeline configuration (models, budget, callbacks)
25
+ * @returns Full pipeline result with timing data
26
+ */
27
+ export async function runV2Pipeline(userInput, options) {
28
+ if (!userInput.trim())
29
+ throw new Error('Agent description cannot be empty');
30
+ const timing = {};
31
+ const tokenBudget = options.tokenBudget ?? 4000;
32
+ const notify = options.onPhaseComplete ?? (() => { });
33
+ const warn = options.onPhaseWarning ?? ((phase, msg) => console.warn(`[V2:${phase}] ${msg}`));
34
+ // Phase 1: Parse
35
+ let t = Date.now();
36
+ const parsed = await runParser(userInput, sonnetConfig(options));
37
+ timing.parse = Date.now() - t;
38
+ notify('parse', timing.parse);
39
+ // Start tool discovery in parallel (best-effort, won't block pipeline)
40
+ const toolPromise = discoverTools(parsed, options.installed ?? { skillIds: [], mcpIds: [], connectorIds: [] }).catch((err) => {
41
+ warn('tool_discovery', err instanceof Error ? err.message : String(err));
42
+ return [];
43
+ });
44
+ // Phase 2: Research
45
+ t = Date.now();
46
+ const research = await runResearcher(parsed, sonnetConfig(options));
47
+ timing.research = Date.now() - t;
48
+ notify('research', timing.research);
49
+ // Phase 3: Pattern Selection
50
+ t = Date.now();
51
+ const pattern = await runPatternSelector(parsed, research, sonnetConfig(options));
52
+ timing.pattern = Date.now() - t;
53
+ notify('pattern', timing.pattern);
54
+ // Phase 4: Context Strategy
55
+ t = Date.now();
56
+ const context = await runContextStrategist(parsed, tokenBudget, sonnetConfig(options));
57
+ timing.context = Date.now() - t;
58
+ notify('context', timing.context);
59
+ // Phase 5: Assembly (uses Opus for depth)
60
+ t = Date.now();
61
+ const assembled = await runAssembler(parsed, research, pattern, context, opusConfig(options));
62
+ timing.assemble = Date.now() - t;
63
+ notify('assemble', timing.assemble);
64
+ // Phase 6: Evaluate
65
+ t = Date.now();
66
+ const evaluation = await runEvaluator(parsed, research, assembled, context, sonnetConfig(options));
67
+ timing.evaluate = Date.now() - t;
68
+ notify('evaluate', timing.evaluate);
69
+ timing.total = Object.values(timing).reduce((a, b) => a + b, 0) - (timing.total ?? 0);
70
+ // Await tool discovery (started after Phase 1, should be done by now)
71
+ const discoveredTools = await toolPromise;
72
+ notify('tool_discovery', 0);
73
+ return {
74
+ parsed,
75
+ research,
76
+ pattern,
77
+ context,
78
+ assembled,
79
+ evaluation,
80
+ timing,
81
+ discoveredTools,
82
+ };
83
+ }
84
+ /**
85
+ * Quick convenience: run pipeline and return just the YAML.
86
+ */
87
+ export async function generateAgentV2(userInput, options) {
88
+ const result = await runV2Pipeline(userInput, options);
89
+ return result.evaluation.final_yaml;
90
+ }
@@ -0,0 +1,3 @@
1
+ import type { LLMCallConfig, ParsedInput } from './types.js';
2
+ export declare function runParser(userInput: string, llmConfig: LLMCallConfig): Promise<ParsedInput>;
3
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../../../src/metaprompt/v2/parser.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAsH7D,wBAAsB,SAAS,CAC7B,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,aAAa,GACvB,OAAO,CAAC,WAAW,CAAC,CAetB"}
@@ -0,0 +1,138 @@
1
+ import { fetchCompletion } from '../../services/llmService.js';
2
+ const FEW_SHOT_EXAMPLES = `
3
+ ## Example 1: PM Agent (Teresa Torres / RICE)
4
+ Input: "Build a PM agent for SaaS B2B that uses Teresa Torres' continuous discovery approach and RICE prioritization. It will analyze customer interviews and Zoom transcripts to extract feature requests and map opportunities."
5
+
6
+ Output:
7
+ {
8
+ "role": "Product Manager",
9
+ "domain": "SaaS B2B",
10
+ "named_experts": ["Teresa Torres"],
11
+ "named_methodologies": ["RICE"],
12
+ "implied_methodologies": ["opportunity mapping", "customer interview analysis", "JTBD"],
13
+ "tools_requested": ["Zoom", "Filesystem"],
14
+ "documents": [
15
+ { "path": "customer-interviews/", "inferred_type": "signal", "size_estimate": "large" },
16
+ { "path": "zoom-transcripts/", "inferred_type": "signal", "size_estimate": "large" }
17
+ ],
18
+ "success_criteria": ["Features trace to customer evidence", "Opportunities mapped before solutions"],
19
+ "constraints": ["Do not jump from pain point to solution without opportunity mapping"],
20
+ "output_expectations": ["Opportunity solution tree", "RICE-scored backlog"]
21
+ }
22
+
23
+ ## Example 2: Legal Agent
24
+ Input: "I need a contract review agent for our legal team. It should apply IRAC analysis methodology to contracts, flag risk clauses, and follow Tina Turner's risk classification framework. Clients include Fortune 500 companies."
25
+
26
+ Output:
27
+ {
28
+ "role": "Legal Analyst",
29
+ "domain": "Contract Review",
30
+ "named_experts": ["Tina Turner"],
31
+ "named_methodologies": ["IRAC"],
32
+ "implied_methodologies": ["risk classification", "clause analysis"],
33
+ "tools_requested": ["Filesystem"],
34
+ "documents": [],
35
+ "success_criteria": ["All risk clauses flagged", "IRAC applied to each clause"],
36
+ "constraints": ["Do not provide legal advice, only analysis"],
37
+ "output_expectations": ["Contract risk report", "Flagged clauses list"]
38
+ }
39
+
40
+ NOTE: "Tina Turner" appears as a risk classification framework author — treat as named expert.
41
+ "Fortune 500 companies" are CLIENTS/STAKEHOLDERS — NOT named experts.
42
+
43
+ ## Example 3: Engineering Agent
44
+ Input: "Create a code review agent that follows Google's engineering practices, applies the DORA metrics framework, and uses Martin Fowler's refactoring catalog. It should review PRs and suggest improvements."
45
+
46
+ Output:
47
+ {
48
+ "role": "Senior Software Engineer",
49
+ "domain": "Code Review",
50
+ "named_experts": ["Martin Fowler"],
51
+ "named_methodologies": ["DORA metrics", "Google engineering practices"],
52
+ "implied_methodologies": ["code smell detection", "refactoring patterns"],
53
+ "tools_requested": ["GitHub", "Filesystem"],
54
+ "documents": [],
55
+ "success_criteria": ["Every suggestion references specific refactoring pattern", "DORA impact assessed"],
56
+ "constraints": ["Do not approve PRs with critical issues"],
57
+ "output_expectations": ["PR review with inline comments", "DORA impact assessment"]
58
+ }
59
+
60
+ ## Example 4: Marketing Agent
61
+ Input: "Build a content marketing agent using Seth Godin's permission marketing principles and the AIDA framework. It should create email campaigns and analyze conversion funnels for our e-commerce platform."
62
+
63
+ Output:
64
+ {
65
+ "role": "Content Marketing Strategist",
66
+ "domain": "E-commerce Marketing",
67
+ "named_experts": ["Seth Godin"],
68
+ "named_methodologies": ["AIDA", "permission marketing"],
69
+ "implied_methodologies": ["conversion funnel analysis", "email segmentation"],
70
+ "tools_requested": ["email platform", "analytics"],
71
+ "documents": [],
72
+ "success_criteria": ["Campaigns respect permission principles", "AIDA structure applied"],
73
+ "constraints": ["No unsolicited contact", "Must track consent"],
74
+ "output_expectations": ["Email campaign drafts", "Funnel analysis report"]
75
+ }
76
+ `;
77
+ const PARSER_SYSTEM_PROMPT = `You are a precision extractor for AI agent specifications. Given a user's description of an agent they want, extract structured entities as JSON.
78
+
79
+ CRITICAL RULES:
80
+ 1. named_experts: ONLY people referenced as sources of METHODOLOGY, FRAMEWORK, or APPROACH. NOT clients, NOT stakeholders, NOT companies.
81
+ 2. named_methodologies: Explicitly named frameworks (RICE, JTBD, IRAC, DORA, AIDA, etc.)
82
+ 3. implied_methodologies: Methods SUGGESTED by the task description but not named (e.g., "prioritize features" implies RICE/ICE/MoSCoW)
83
+ 4. Return ONLY a valid JSON object — no markdown, no explanation.
84
+
85
+ ${FEW_SHOT_EXAMPLES}
86
+
87
+ Now extract from the user's input.`;
88
+ function parseJSON(text) {
89
+ try {
90
+ return JSON.parse(text);
91
+ }
92
+ catch { /* continue */ }
93
+ const fenceMatch = text.match(/```(?:json)?\s*([\s\S]*?)```/);
94
+ if (fenceMatch) {
95
+ try {
96
+ return JSON.parse(fenceMatch[1].trim());
97
+ }
98
+ catch { /* continue */ }
99
+ }
100
+ const braceMatch = text.match(/\{[\s\S]*\}/);
101
+ if (braceMatch) {
102
+ try {
103
+ return JSON.parse(braceMatch[0]);
104
+ }
105
+ catch { /* continue */ }
106
+ }
107
+ return null;
108
+ }
109
+ function ensureDefaults(parsed) {
110
+ return {
111
+ role: parsed.role ?? '',
112
+ domain: parsed.domain ?? '',
113
+ named_experts: parsed.named_experts ?? [],
114
+ named_methodologies: parsed.named_methodologies ?? [],
115
+ implied_methodologies: parsed.implied_methodologies ?? [],
116
+ tools_requested: parsed.tools_requested ?? [],
117
+ documents: parsed.documents ?? [],
118
+ success_criteria: parsed.success_criteria ?? [],
119
+ constraints: parsed.constraints ?? [],
120
+ output_expectations: parsed.output_expectations ?? [],
121
+ };
122
+ }
123
+ export async function runParser(userInput, llmConfig) {
124
+ const text = await fetchCompletion({
125
+ providerId: llmConfig.providerId,
126
+ model: llmConfig.model,
127
+ messages: [
128
+ { role: 'system', content: PARSER_SYSTEM_PROMPT },
129
+ { role: 'user', content: userInput },
130
+ ],
131
+ temperature: 0.1,
132
+ maxTokens: 2048,
133
+ });
134
+ const parsed = parseJSON(text);
135
+ if (!parsed)
136
+ throw new Error(`Parser: could not parse LLM response as JSON. Raw: ${text.slice(0, 200)}`);
137
+ return ensureDefaults(parsed);
138
+ }
@@ -0,0 +1,3 @@
1
+ import type { LLMCallConfig, ParsedInput, ResearchResult, PatternSelection } from './types.js';
2
+ export declare function runPatternSelector(parsed: ParsedInput, research: ResearchResult, llmConfig: LLMCallConfig): Promise<PatternSelection>;
3
+ //# sourceMappingURL=pattern-selector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pattern-selector.d.ts","sourceRoot":"","sources":["../../../../src/metaprompt/v2/pattern-selector.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,cAAc,EAAE,gBAAgB,EAAmB,MAAM,YAAY,CAAC;AAwFhH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,WAAW,EACnB,QAAQ,EAAE,cAAc,EACxB,SAAS,EAAE,aAAa,GACvB,OAAO,CAAC,gBAAgB,CAAC,CA2D3B"}