research-copilot 0.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 (395) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +190 -0
  3. package/app/build/icon.icns +0 -0
  4. package/app/build/icon.ico +0 -0
  5. package/app/build/icon.png +0 -0
  6. package/app/out/main/index.mjs +6719 -0
  7. package/app/out/preload/index.js +141 -0
  8. package/app/out/renderer/assets/Inter-Variable-Latin-8kRkwJBP.woff2 +0 -0
  9. package/app/out/renderer/assets/Inter-Variable-LatinExt-B_-bZUTo.woff2 +0 -0
  10. package/app/out/renderer/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  11. package/app/out/renderer/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  12. package/app/out/renderer/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  13. package/app/out/renderer/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  14. package/app/out/renderer/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  15. package/app/out/renderer/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  16. package/app/out/renderer/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  17. package/app/out/renderer/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  18. package/app/out/renderer/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  19. package/app/out/renderer/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  20. package/app/out/renderer/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  21. package/app/out/renderer/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  22. package/app/out/renderer/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  23. package/app/out/renderer/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  24. package/app/out/renderer/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  25. package/app/out/renderer/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  26. package/app/out/renderer/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  27. package/app/out/renderer/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  28. package/app/out/renderer/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  29. package/app/out/renderer/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  30. package/app/out/renderer/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  31. package/app/out/renderer/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  32. package/app/out/renderer/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  33. package/app/out/renderer/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  34. package/app/out/renderer/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  35. package/app/out/renderer/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  36. package/app/out/renderer/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  37. package/app/out/renderer/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  38. package/app/out/renderer/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  39. package/app/out/renderer/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  40. package/app/out/renderer/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  41. package/app/out/renderer/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  42. package/app/out/renderer/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  43. package/app/out/renderer/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  44. package/app/out/renderer/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  45. package/app/out/renderer/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  46. package/app/out/renderer/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  47. package/app/out/renderer/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  48. package/app/out/renderer/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  49. package/app/out/renderer/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  50. package/app/out/renderer/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  51. package/app/out/renderer/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  52. package/app/out/renderer/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  53. package/app/out/renderer/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  54. package/app/out/renderer/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  55. package/app/out/renderer/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  56. package/app/out/renderer/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  57. package/app/out/renderer/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  58. package/app/out/renderer/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  59. package/app/out/renderer/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  60. package/app/out/renderer/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  61. package/app/out/renderer/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  62. package/app/out/renderer/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  63. package/app/out/renderer/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  64. package/app/out/renderer/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  65. package/app/out/renderer/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  66. package/app/out/renderer/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  67. package/app/out/renderer/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  68. package/app/out/renderer/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  69. package/app/out/renderer/assets/MilkdownMarkdownEditor-bLPxrCVb.js +89821 -0
  70. package/app/out/renderer/assets/MilkdownMarkdownEditor-tTNRIB2K.css +2555 -0
  71. package/app/out/renderer/assets/Tableau10-BqnYsPR6.js +9 -0
  72. package/app/out/renderer/assets/apl-fqmucPXA.js +140 -0
  73. package/app/out/renderer/assets/arc-J47ePHZ2.js +132 -0
  74. package/app/out/renderer/assets/array-DgktLKBx.js +6 -0
  75. package/app/out/renderer/assets/asciiarmor-DucZyvP0.js +56 -0
  76. package/app/out/renderer/assets/asn1-BnOEsgAm.js +144 -0
  77. package/app/out/renderer/assets/asterisk-QAlztEwS.js +345 -0
  78. package/app/out/renderer/assets/blockDiagram-c4efeb88-5uRQXgQJ.js +1817 -0
  79. package/app/out/renderer/assets/brainfuck-DZVCuF_t.js +53 -0
  80. package/app/out/renderer/assets/c4Diagram-c83219d4-C4iCTPEL.js +2464 -0
  81. package/app/out/renderer/assets/channel-ZAmhHE3g.js +7 -0
  82. package/app/out/renderer/assets/classDiagram-beda092f-7NOZxq_W.js +357 -0
  83. package/app/out/renderer/assets/classDiagram-v2-2358418a-5fPT-cUH.js +291 -0
  84. package/app/out/renderer/assets/clike-xqXYL6ge.js +805 -0
  85. package/app/out/renderer/assets/clojure-BhXMqnxz.js +849 -0
  86. package/app/out/renderer/assets/clone-CsnzsYXQ.js +8 -0
  87. package/app/out/renderer/assets/cmake-BGaNd9E7.js +71 -0
  88. package/app/out/renderer/assets/cobol-4yqQntpt.js +120 -0
  89. package/app/out/renderer/assets/coffeescript-D2dXvhEc.js +308 -0
  90. package/app/out/renderer/assets/commonlisp-CF_VNHQR.js +130 -0
  91. package/app/out/renderer/assets/createText-1719965b-Cji7KN4K.js +4904 -0
  92. package/app/out/renderer/assets/crystal-DyuLTqLs.js +398 -0
  93. package/app/out/renderer/assets/css-c-jst79C.js +1783 -0
  94. package/app/out/renderer/assets/cypher-Dlu_3r4V.js +121 -0
  95. package/app/out/renderer/assets/d-UURgV0Ux.js +179 -0
  96. package/app/out/renderer/assets/diff-B_Bi2Crb.js +25 -0
  97. package/app/out/renderer/assets/dockerfile-Bvk733Ga.js +201 -0
  98. package/app/out/renderer/assets/dtd-Dy74G54E.js +114 -0
  99. package/app/out/renderer/assets/dylan-TSb-Nfix.js +314 -0
  100. package/app/out/renderer/assets/ebnf-DAomQUbD.js +139 -0
  101. package/app/out/renderer/assets/ecl-B59qGGVg.js +178 -0
  102. package/app/out/renderer/assets/edges-96097737-CD0EvAZQ.js +1844 -0
  103. package/app/out/renderer/assets/eiffel-Dze7nlu3.js +134 -0
  104. package/app/out/renderer/assets/elm-DG7jkhNZ.js +176 -0
  105. package/app/out/renderer/assets/erDiagram-0228fc6a-DRYXBpi7.js +1321 -0
  106. package/app/out/renderer/assets/erlang-BO6gOnGA.js +674 -0
  107. package/app/out/renderer/assets/factor-CMxFHDqz.js +65 -0
  108. package/app/out/renderer/assets/fcl-CDDUNjTj.js +141 -0
  109. package/app/out/renderer/assets/flowDb-c6c81e3f-CuoIN-Cy.js +1713 -0
  110. package/app/out/renderer/assets/flowDiagram-50d868cf-CPWPLOml.js +1272 -0
  111. package/app/out/renderer/assets/flowDiagram-v2-4f6560a1-C_R12s4S.js +33 -0
  112. package/app/out/renderer/assets/flowchart-elk-definition-6af322e1-BdKUSFpi.js +92921 -0
  113. package/app/out/renderer/assets/forth-B9D2JCeE.js +116 -0
  114. package/app/out/renderer/assets/fortran-CAG2BFbe.js +467 -0
  115. package/app/out/renderer/assets/ganttDiagram-a2739b55-ygqT5HlG.js +3399 -0
  116. package/app/out/renderer/assets/gas-d3KEcW3x.js +294 -0
  117. package/app/out/renderer/assets/gherkin-DhZlEZiy.js +115 -0
  118. package/app/out/renderer/assets/gitGraphDiagram-82fe8481-D97GT4iA.js +1791 -0
  119. package/app/out/renderer/assets/graph-DpC13d95.js +1237 -0
  120. package/app/out/renderer/assets/groovy-CpwJiBl7.js +223 -0
  121. package/app/out/renderer/assets/haskell-BlGBCCe3.js +459 -0
  122. package/app/out/renderer/assets/haxe-7MlzfeYV.js +514 -0
  123. package/app/out/renderer/assets/http-BqypyemW.js +79 -0
  124. package/app/out/renderer/assets/idl-4HIGJlDI.js +985 -0
  125. package/app/out/renderer/assets/index-4-ziknCv.js +292 -0
  126. package/app/out/renderer/assets/index-5325376f-Bbs7Fbqr.js +663 -0
  127. package/app/out/renderer/assets/index-B2jip-rk.js +2489 -0
  128. package/app/out/renderer/assets/index-BKTVfokE.js +312 -0
  129. package/app/out/renderer/assets/index-BiJbFgVG.js +118 -0
  130. package/app/out/renderer/assets/index-Bn433Fat.js +83 -0
  131. package/app/out/renderer/assets/index-BqDyyRCx.js +39679 -0
  132. package/app/out/renderer/assets/index-BzFMeMPn.js +158 -0
  133. package/app/out/renderer/assets/index-C-_uCjZJ.css +2701 -0
  134. package/app/out/renderer/assets/index-C1ithNW1.js +1765 -0
  135. package/app/out/renderer/assets/index-CAJkRYkO.js +407 -0
  136. package/app/out/renderer/assets/index-CleO0-yj.js +690 -0
  137. package/app/out/renderer/assets/index-Cq4MH3sY.js +1020 -0
  138. package/app/out/renderer/assets/index-CtA0Xj22.js +705 -0
  139. package/app/out/renderer/assets/index-CvAZkqBZ.js +83 -0
  140. package/app/out/renderer/assets/index-D3UDN-5c.js +152 -0
  141. package/app/out/renderer/assets/index-D4F9R5ao.js +179 -0
  142. package/app/out/renderer/assets/index-D6RguhZ5.js +328 -0
  143. package/app/out/renderer/assets/index-DnEowqXv.js +386 -0
  144. package/app/out/renderer/assets/index-K8c8Mqdy.js +98 -0
  145. package/app/out/renderer/assets/index-Kh14gO6K.js +62 -0
  146. package/app/out/renderer/assets/index-WFd2jRnA.js +333 -0
  147. package/app/out/renderer/assets/index-WgMfkRFp.js +313 -0
  148. package/app/out/renderer/assets/index-Y4lKyF6t.js +1042 -0
  149. package/app/out/renderer/assets/index-fx307_f1.js +643 -0
  150. package/app/out/renderer/assets/infoDiagram-8eee0895-ptaVSwzq.js +511 -0
  151. package/app/out/renderer/assets/init-ZxktEp_H.js +16 -0
  152. package/app/out/renderer/assets/javascript-C3MnDRiU.js +994 -0
  153. package/app/out/renderer/assets/journeyDiagram-c64418c1-aloEGOQp.js +1184 -0
  154. package/app/out/renderer/assets/julia-Bs6JJhYG.js +407 -0
  155. package/app/out/renderer/assets/layout-ZeuHE_aY.js +2217 -0
  156. package/app/out/renderer/assets/line-CAgaGl-S.js +45 -0
  157. package/app/out/renderer/assets/linear-DIg7lTe1.js +539 -0
  158. package/app/out/renderer/assets/livescript-DmzgM3Yt.js +296 -0
  159. package/app/out/renderer/assets/lua-8cJgIlqe.js +256 -0
  160. package/app/out/renderer/assets/mathematica-DNLOL9PQ.js +110 -0
  161. package/app/out/renderer/assets/mbox-Ga7d4MMN.js +117 -0
  162. package/app/out/renderer/assets/mindmap-definition-8da855dc-B8XVoUxz.js +36054 -0
  163. package/app/out/renderer/assets/mirc-Dma3B8rS.js +107 -0
  164. package/app/out/renderer/assets/mllike-DHn7xckP.js +334 -0
  165. package/app/out/renderer/assets/modelica-0d55jYY0.js +147 -0
  166. package/app/out/renderer/assets/mscgen-DdqZYINH.js +135 -0
  167. package/app/out/renderer/assets/mumps-Btr8VblO.js +93 -0
  168. package/app/out/renderer/assets/nginx-DTDtBDVN.js +141 -0
  169. package/app/out/renderer/assets/nsis-3zG7tgur.js +62 -0
  170. package/app/out/renderer/assets/ntriples-CvgOYMpL.js +153 -0
  171. package/app/out/renderer/assets/octave-DYBj3-tl.js +200 -0
  172. package/app/out/renderer/assets/ordinal-DSZU4PqD.js +76 -0
  173. package/app/out/renderer/assets/oz-R_e8WMIi.js +231 -0
  174. package/app/out/renderer/assets/pascal-GD8iposT.js +105 -0
  175. package/app/out/renderer/assets/path-Cp2qmpkd.js +109 -0
  176. package/app/out/renderer/assets/perl-DL9mHpoi.js +1105 -0
  177. package/app/out/renderer/assets/pieDiagram-a8764435-DlwoeBU2.js +770 -0
  178. package/app/out/renderer/assets/pig-C_4T4YIV.js +101 -0
  179. package/app/out/renderer/assets/powershell-B0suO7Vd.js +328 -0
  180. package/app/out/renderer/assets/properties-BR-vP1aU.js +58 -0
  181. package/app/out/renderer/assets/protobuf-BxgpyhoW.js +77 -0
  182. package/app/out/renderer/assets/pug-By0kVCfm.js +405 -0
  183. package/app/out/renderer/assets/puppet-Bdao66PW.js +137 -0
  184. package/app/out/renderer/assets/python-CvWbmiX4.js +427 -0
  185. package/app/out/renderer/assets/q-CrbCVq4a.js +131 -0
  186. package/app/out/renderer/assets/quadrantDiagram-1e28029f-BaSi1XB4.js +1200 -0
  187. package/app/out/renderer/assets/r-V7nswm59.js +170 -0
  188. package/app/out/renderer/assets/requirementDiagram-08caed73-D3EFyegZ.js +1092 -0
  189. package/app/out/renderer/assets/rpm-C-DLY-If.js +109 -0
  190. package/app/out/renderer/assets/ruby-JDKLJNK0.js +330 -0
  191. package/app/out/renderer/assets/sankeyDiagram-a04cb91d-Cv44AsnM.js +1174 -0
  192. package/app/out/renderer/assets/sas-D2UG-yhZ.js +207 -0
  193. package/app/out/renderer/assets/scheme-BKzrkGJD.js +222 -0
  194. package/app/out/renderer/assets/sequenceDiagram-c5b8d532-CuUBu-x4.js +3337 -0
  195. package/app/out/renderer/assets/shell-BlsXDxCn.js +222 -0
  196. package/app/out/renderer/assets/sieve-CjwBwOY5.js +135 -0
  197. package/app/out/renderer/assets/simple-mode-DMneyfDu.js +130 -0
  198. package/app/out/renderer/assets/smalltalk-BOIGQuhN.js +121 -0
  199. package/app/out/renderer/assets/solr-CwD7U71z.js +69 -0
  200. package/app/out/renderer/assets/sparql-DYskk2vE.js +249 -0
  201. package/app/out/renderer/assets/spreadsheet-Bgtt3oLP.js +87 -0
  202. package/app/out/renderer/assets/sql-BSrOzCRI.js +354 -0
  203. package/app/out/renderer/assets/stateDiagram-1ecb1508-BOU34Zp4.js +454 -0
  204. package/app/out/renderer/assets/stateDiagram-v2-c2b004d7-BgRoffou.js +326 -0
  205. package/app/out/renderer/assets/stex-B6LNC55o.js +231 -0
  206. package/app/out/renderer/assets/styles-b4e223ce-BMr9TPuj.js +1483 -0
  207. package/app/out/renderer/assets/styles-ca3715f6-DgbNw99p.js +1363 -0
  208. package/app/out/renderer/assets/styles-d45a18b0-DtRYKYKf.js +574 -0
  209. package/app/out/renderer/assets/stylus-BkS-boTH.js +565 -0
  210. package/app/out/renderer/assets/svgDrawCommon-b86b1483-Bein03PD.js +100 -0
  211. package/app/out/renderer/assets/swift-FRZi1uvB.js +291 -0
  212. package/app/out/renderer/assets/tcl-CUcaCdmq.js +114 -0
  213. package/app/out/renderer/assets/textile-BnFpjsrl.js +414 -0
  214. package/app/out/renderer/assets/tiddlywiki-CjprD-Qp.js +218 -0
  215. package/app/out/renderer/assets/tiki-B4EPSQ1G.js +265 -0
  216. package/app/out/renderer/assets/timeline-definition-faaaa080-BlWpLE_4.js +1212 -0
  217. package/app/out/renderer/assets/toml-BOuWGMcf.js +76 -0
  218. package/app/out/renderer/assets/troff-E1bJ0PPL.js +61 -0
  219. package/app/out/renderer/assets/ttcn-cfg-Dc39-fIP.js +133 -0
  220. package/app/out/renderer/assets/ttcn-tKd4HLu4.js +192 -0
  221. package/app/out/renderer/assets/turtle-Dq7-1WAf.js +124 -0
  222. package/app/out/renderer/assets/vb-Dp90gtsv.js +196 -0
  223. package/app/out/renderer/assets/vbscript-CI6_mxxU.js +479 -0
  224. package/app/out/renderer/assets/velocity-BwIZK1TH.js +149 -0
  225. package/app/out/renderer/assets/verilog-DDCYnHN8.js +430 -0
  226. package/app/out/renderer/assets/vhdl-DCkMIyT9.js +158 -0
  227. package/app/out/renderer/assets/webidl-BTLTThCm.js +204 -0
  228. package/app/out/renderer/assets/xquery-BgiOC5Ce.js +525 -0
  229. package/app/out/renderer/assets/xychartDiagram-f5964ef8-Bhga-YXm.js +1799 -0
  230. package/app/out/renderer/assets/yacas-b5lAVEIl.js +130 -0
  231. package/app/out/renderer/assets/z80-BZV19vqv.js +93 -0
  232. package/app/out/renderer/index.html +13 -0
  233. package/app/out/skills/community-builtin/README.md +29 -0
  234. package/app/out/skills/community-builtin/document-docx/SKILL.md +44 -0
  235. package/app/out/skills/community-builtin/document-docx/scripts/docx-to-markdown.sh +20 -0
  236. package/app/out/skills/community-builtin/document-docx/scripts/extract-docx-text.sh +28 -0
  237. package/app/out/skills/community-builtin/document-docx/scripts/init-docx-template.sh +32 -0
  238. package/app/out/skills/community-builtin/document-docx/scripts/setup-docx-tools.sh +10 -0
  239. package/app/out/skills/community-builtin/markitdown/SKILL.md +105 -0
  240. package/app/out/skills/community-builtin/markitdown/scripts/batch-convert.sh +40 -0
  241. package/app/out/skills/community-builtin/markitdown/scripts/convert-file.sh +24 -0
  242. package/app/out/skills/community-builtin/markitdown/scripts/setup-markitdown.sh +10 -0
  243. package/app/out/skills/community-builtin/repo-quick-audit/SKILL.md +27 -0
  244. package/app/out/skills/community-builtin/repo-quick-audit/scripts/audit-basics.sh +19 -0
  245. package/app/out/skills/research-pilot-default-project-skills/README.md +23 -0
  246. package/app/out/skills/research-pilot-default-project-skills/citation-management/SKILL.md +39 -0
  247. package/app/out/skills/research-pilot-default-project-skills/citation-management/scripts/doi-to-bibtex.sh +25 -0
  248. package/app/out/skills/research-pilot-default-project-skills/citation-management/scripts/normalize-bibtex-keys.sh +51 -0
  249. package/app/out/skills/research-pilot-default-project-skills/citation-management/scripts/setup-citation-tools.sh +10 -0
  250. package/app/out/skills/research-pilot-default-project-skills/citation-management/scripts/validate-bib.sh +31 -0
  251. package/app/out/skills/research-pilot-default-project-skills/matplotlib/SKILL.md +34 -0
  252. package/app/out/skills/research-pilot-default-project-skills/matplotlib/references/api_reference.md +412 -0
  253. package/app/out/skills/research-pilot-default-project-skills/matplotlib/references/common_issues.md +563 -0
  254. package/app/out/skills/research-pilot-default-project-skills/matplotlib/references/plot_types.md +476 -0
  255. package/app/out/skills/research-pilot-default-project-skills/matplotlib/references/styling_guide.md +589 -0
  256. package/app/out/skills/research-pilot-default-project-skills/matplotlib/references/subagent_quickstart.md +30 -0
  257. package/app/out/skills/research-pilot-default-project-skills/matplotlib/scripts/plot_template.py +401 -0
  258. package/app/out/skills/research-pilot-default-project-skills/matplotlib/scripts/style_configurator.py +409 -0
  259. package/app/out/skills/research-pilot-default-project-skills/research-grants/SKILL.md +38 -0
  260. package/app/out/skills/research-pilot-default-project-skills/research-grants/scripts/check-grant-compliance.sh +40 -0
  261. package/app/out/skills/research-pilot-default-project-skills/research-grants/scripts/grant-summary-card.sh +32 -0
  262. package/app/out/skills/research-pilot-default-project-skills/research-grants/scripts/init-grant-structure.sh +70 -0
  263. package/app/package.json +77 -0
  264. package/bin/cli.mjs +56 -0
  265. package/lib/README.md +145 -0
  266. package/lib/skills/_generated.ts +13 -0
  267. package/lib/skills/builtin/brainstorming-research-ideas/SKILL.md +280 -0
  268. package/lib/skills/builtin/coding/SKILL.md +114 -0
  269. package/lib/skills/builtin/creative-thinking-for-research/SKILL.md +273 -0
  270. package/lib/skills/builtin/matplotlib/SKILL.md +361 -0
  271. package/lib/skills/builtin/matplotlib/references/api_reference.md +412 -0
  272. package/lib/skills/builtin/matplotlib/references/common_issues.md +563 -0
  273. package/lib/skills/builtin/matplotlib/references/plot_types.md +476 -0
  274. package/lib/skills/builtin/matplotlib/references/styling_guide.md +589 -0
  275. package/lib/skills/builtin/matplotlib/scripts/plot_template.py +401 -0
  276. package/lib/skills/builtin/matplotlib/scripts/style_configurator.py +409 -0
  277. package/lib/skills/builtin/paper-writing/SKILL.md +554 -0
  278. package/lib/skills/builtin/paper-writing/references/checklists.md +524 -0
  279. package/lib/skills/builtin/paper-writing/references/citation-workflow.md +562 -0
  280. package/lib/skills/builtin/paper-writing/references/reviewer-guidelines.md +462 -0
  281. package/lib/skills/builtin/paper-writing/references/sources.md +189 -0
  282. package/lib/skills/builtin/paper-writing/references/systems-conferences.md +260 -0
  283. package/lib/skills/builtin/paper-writing/references/writing-guide.md +476 -0
  284. package/lib/skills/builtin/paper-writing/templates/README.md +408 -0
  285. package/lib/skills/builtin/paper-writing/templates/aaai2026/README.md +534 -0
  286. package/lib/skills/builtin/paper-writing/templates/aaai2026/aaai2026-unified-supp.tex +144 -0
  287. package/lib/skills/builtin/paper-writing/templates/aaai2026/aaai2026-unified-template.tex +952 -0
  288. package/lib/skills/builtin/paper-writing/templates/aaai2026/aaai2026.bib +111 -0
  289. package/lib/skills/builtin/paper-writing/templates/aaai2026/aaai2026.bst +1493 -0
  290. package/lib/skills/builtin/paper-writing/templates/aaai2026/aaai2026.sty +315 -0
  291. package/lib/skills/builtin/paper-writing/templates/acl/README.md +50 -0
  292. package/lib/skills/builtin/paper-writing/templates/acl/acl.sty +312 -0
  293. package/lib/skills/builtin/paper-writing/templates/acl/acl_latex.tex +377 -0
  294. package/lib/skills/builtin/paper-writing/templates/acl/acl_lualatex.tex +101 -0
  295. package/lib/skills/builtin/paper-writing/templates/acl/acl_natbib.bst +1940 -0
  296. package/lib/skills/builtin/paper-writing/templates/acl/anthology.bib.txt +26 -0
  297. package/lib/skills/builtin/paper-writing/templates/acl/custom.bib +70 -0
  298. package/lib/skills/builtin/paper-writing/templates/acl/formatting.md +326 -0
  299. package/lib/skills/builtin/paper-writing/templates/asplos2027/main.tex +459 -0
  300. package/lib/skills/builtin/paper-writing/templates/asplos2027/references.bib +135 -0
  301. package/lib/skills/builtin/paper-writing/templates/colm2025/README.md +3 -0
  302. package/lib/skills/builtin/paper-writing/templates/colm2025/colm2025_conference.bib +11 -0
  303. package/lib/skills/builtin/paper-writing/templates/colm2025/colm2025_conference.bst +1440 -0
  304. package/lib/skills/builtin/paper-writing/templates/colm2025/colm2025_conference.pdf +0 -0
  305. package/lib/skills/builtin/paper-writing/templates/colm2025/colm2025_conference.sty +218 -0
  306. package/lib/skills/builtin/paper-writing/templates/colm2025/colm2025_conference.tex +305 -0
  307. package/lib/skills/builtin/paper-writing/templates/colm2025/fancyhdr.sty +485 -0
  308. package/lib/skills/builtin/paper-writing/templates/colm2025/math_commands.tex +508 -0
  309. package/lib/skills/builtin/paper-writing/templates/colm2025/natbib.sty +1246 -0
  310. package/lib/skills/builtin/paper-writing/templates/iclr2026/fancyhdr.sty +485 -0
  311. package/lib/skills/builtin/paper-writing/templates/iclr2026/iclr2026_conference.bib +24 -0
  312. package/lib/skills/builtin/paper-writing/templates/iclr2026/iclr2026_conference.bst +1440 -0
  313. package/lib/skills/builtin/paper-writing/templates/iclr2026/iclr2026_conference.pdf +0 -0
  314. package/lib/skills/builtin/paper-writing/templates/iclr2026/iclr2026_conference.sty +246 -0
  315. package/lib/skills/builtin/paper-writing/templates/iclr2026/iclr2026_conference.tex +414 -0
  316. package/lib/skills/builtin/paper-writing/templates/iclr2026/math_commands.tex +508 -0
  317. package/lib/skills/builtin/paper-writing/templates/iclr2026/natbib.sty +1246 -0
  318. package/lib/skills/builtin/paper-writing/templates/icml2026/algorithm.sty +79 -0
  319. package/lib/skills/builtin/paper-writing/templates/icml2026/algorithmic.sty +201 -0
  320. package/lib/skills/builtin/paper-writing/templates/icml2026/example_paper.bib +75 -0
  321. package/lib/skills/builtin/paper-writing/templates/icml2026/example_paper.pdf +0 -0
  322. package/lib/skills/builtin/paper-writing/templates/icml2026/example_paper.tex +662 -0
  323. package/lib/skills/builtin/paper-writing/templates/icml2026/fancyhdr.sty +864 -0
  324. package/lib/skills/builtin/paper-writing/templates/icml2026/icml2026.bst +1443 -0
  325. package/lib/skills/builtin/paper-writing/templates/icml2026/icml2026.sty +767 -0
  326. package/lib/skills/builtin/paper-writing/templates/icml2026/icml_numpapers.pdf +0 -0
  327. package/lib/skills/builtin/paper-writing/templates/neurips2025/Makefile +36 -0
  328. package/lib/skills/builtin/paper-writing/templates/neurips2025/extra_pkgs.tex +53 -0
  329. package/lib/skills/builtin/paper-writing/templates/neurips2025/main.tex +38 -0
  330. package/lib/skills/builtin/paper-writing/templates/neurips2025/neurips.sty +382 -0
  331. package/lib/skills/builtin/paper-writing/templates/nsdi2027/main.tex +426 -0
  332. package/lib/skills/builtin/paper-writing/templates/nsdi2027/references.bib +151 -0
  333. package/lib/skills/builtin/paper-writing/templates/nsdi2027/usenix-2020-09.sty +83 -0
  334. package/lib/skills/builtin/paper-writing/templates/osdi2026/main.tex +429 -0
  335. package/lib/skills/builtin/paper-writing/templates/osdi2026/references.bib +150 -0
  336. package/lib/skills/builtin/paper-writing/templates/osdi2026/usenix-2020-09.sty +83 -0
  337. package/lib/skills/builtin/paper-writing/templates/sosp2026/main.tex +532 -0
  338. package/lib/skills/builtin/paper-writing/templates/sosp2026/references.bib +148 -0
  339. package/lib/skills/builtin/research-grants/SKILL.md +958 -0
  340. package/lib/skills/builtin/research-grants/assets/budget_justification_template.md +453 -0
  341. package/lib/skills/builtin/research-grants/assets/nih_specific_aims_template.md +166 -0
  342. package/lib/skills/builtin/research-grants/assets/nsf_project_summary_template.md +92 -0
  343. package/lib/skills/builtin/research-grants/references/README.md +285 -0
  344. package/lib/skills/builtin/research-grants/references/broader_impacts.md +392 -0
  345. package/lib/skills/builtin/research-grants/references/darpa_guidelines.md +636 -0
  346. package/lib/skills/builtin/research-grants/references/doe_guidelines.md +586 -0
  347. package/lib/skills/builtin/research-grants/references/nih_guidelines.md +851 -0
  348. package/lib/skills/builtin/research-grants/references/nsf_guidelines.md +570 -0
  349. package/lib/skills/builtin/research-grants/references/nstc_guidelines.md +733 -0
  350. package/lib/skills/builtin/research-grants/references/specific_aims_guide.md +458 -0
  351. package/lib/skills/builtin/rewrite-humanize/SKILL.md +116 -0
  352. package/lib/skills/builtin/rewrite-humanize/references/cs-venue-tone.md +57 -0
  353. package/lib/skills/builtin/rewrite-humanize/references/lexicon.md +50 -0
  354. package/lib/skills/builtin/scholar-evaluation/SKILL.md +300 -0
  355. package/lib/skills/builtin/scholar-evaluation/references/evaluation_framework.md +663 -0
  356. package/lib/skills/builtin/scholar-evaluation/scripts/calculate_scores.py +379 -0
  357. package/lib/skills/builtin/scientific-schematics/SKILL.md +603 -0
  358. package/lib/skills/builtin/scientific-schematics/references/QUICK_REFERENCE.md +182 -0
  359. package/lib/skills/builtin/scientific-schematics/references/README.md +292 -0
  360. package/lib/skills/builtin/scientific-schematics/references/best_practices.md +560 -0
  361. package/lib/skills/builtin/scientific-schematics/scripts/__pycache__/generate_schematic.cpython-312.pyc +0 -0
  362. package/lib/skills/builtin/scientific-schematics/scripts/__pycache__/generate_schematic_ai.cpython-312.pyc +0 -0
  363. package/lib/skills/builtin/scientific-schematics/scripts/example_usage.sh +85 -0
  364. package/lib/skills/builtin/scientific-schematics/scripts/generate_schematic.py +141 -0
  365. package/lib/skills/builtin/scientific-schematics/scripts/generate_schematic_ai.py +910 -0
  366. package/lib/skills/builtin/scientific-visualization/SKILL.md +749 -0
  367. package/lib/skills/builtin/scientific-visualization/assets/color_palettes.py +197 -0
  368. package/lib/skills/builtin/scientific-visualization/assets/nature.mplstyle +63 -0
  369. package/lib/skills/builtin/scientific-visualization/assets/presentation.mplstyle +61 -0
  370. package/lib/skills/builtin/scientific-visualization/assets/publication.mplstyle +68 -0
  371. package/lib/skills/builtin/scientific-visualization/references/color_palettes.md +348 -0
  372. package/lib/skills/builtin/scientific-visualization/references/journal_requirements.md +320 -0
  373. package/lib/skills/builtin/scientific-visualization/references/matplotlib_examples.md +620 -0
  374. package/lib/skills/builtin/scientific-visualization/references/publication_guidelines.md +205 -0
  375. package/lib/skills/builtin/scientific-visualization/scripts/figure_export.py +343 -0
  376. package/lib/skills/builtin/scientific-visualization/scripts/style_presets.py +416 -0
  377. package/lib/skills/builtin/scientific-writing/SKILL.md +745 -0
  378. package/lib/skills/builtin/scientific-writing/assets/REPORT_FORMATTING_GUIDE.md +574 -0
  379. package/lib/skills/builtin/scientific-writing/assets/scientific_report.sty +606 -0
  380. package/lib/skills/builtin/scientific-writing/assets/scientific_report_template.tex +449 -0
  381. package/lib/skills/builtin/scientific-writing/references/citation_styles.md +720 -0
  382. package/lib/skills/builtin/scientific-writing/references/figures_tables.md +806 -0
  383. package/lib/skills/builtin/scientific-writing/references/imrad_structure.md +686 -0
  384. package/lib/skills/builtin/scientific-writing/references/professional_report_formatting.md +664 -0
  385. package/lib/skills/builtin/scientific-writing/references/reporting_guidelines.md +748 -0
  386. package/lib/skills/builtin/scientific-writing/references/writing_principles.md +824 -0
  387. package/lib/skills/builtin/seaborn/SKILL.md +674 -0
  388. package/lib/skills/builtin/seaborn/references/examples.md +822 -0
  389. package/lib/skills/builtin/seaborn/references/function_reference.md +770 -0
  390. package/lib/skills/builtin/seaborn/references/objects_interface.md +964 -0
  391. package/lib/skills/data-analysis/SKILL.md +285 -0
  392. package/lib/skills/generate-skill-content.mjs +58 -0
  393. package/lib/skills/index.ts +34 -0
  394. package/lib/skills/loader.ts +452 -0
  395. package/package.json +62 -0
@@ -0,0 +1,452 @@
1
+ /**
2
+ * Skills loader for Research Copilot.
3
+ *
4
+ * Discovers and parses SKILL.md files from three locations:
5
+ * 1. Built-in skills: lib/skills/builtin/ (shipped with app)
6
+ * 2. Workspace skills: .research-pilot/skills/ (per-project)
7
+ * 3. User skills: ~/.research-pilot/skills/ (user-global)
8
+ *
9
+ * Adapted from myRAM's skills.ts with simplified settings.
10
+ */
11
+
12
+ import fs from 'node:fs'
13
+ import os from 'node:os'
14
+ import path from 'node:path'
15
+ import { fileURLToPath } from 'node:url'
16
+
17
+ const SKILL_FILE_NAME = 'SKILL.md'
18
+ const MAX_SCAN_DEPTH = 3
19
+
20
+ /**
21
+ * Override for the builtin skills root directory.
22
+ * Must be set by the host (e.g. Electron main process) before loading skills,
23
+ * because `import.meta.url` resolves incorrectly after Vite bundling.
24
+ */
25
+ let _builtinSkillsRoot: string | null = null
26
+
27
+ export function setBuiltinSkillsRoot(dir: string): void {
28
+ _builtinSkillsRoot = dir
29
+ }
30
+
31
+ export interface SkillEntry {
32
+ name: string
33
+ description: string
34
+ category: string
35
+ depends: string[]
36
+ tags: string[]
37
+ triggers: string[] // Keywords/phrases that should trigger this skill
38
+ path: string
39
+ dir: string // Absolute path to skill directory (for running scripts)
40
+ source: 'builtin' | 'user' | 'workspace'
41
+ content: string
42
+ }
43
+
44
+ export interface SkillCatalogItem {
45
+ name: string
46
+ description: string
47
+ path: string
48
+ }
49
+
50
+ // ---------------------------------------------------------------------------
51
+ // Internal helpers
52
+ // ---------------------------------------------------------------------------
53
+
54
+ function safeReadText(filePath: string): string | null {
55
+ try {
56
+ return fs.readFileSync(filePath, 'utf8')
57
+ } catch {
58
+ return null
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Parse a top-level field from YAML frontmatter.
64
+ * Only matches lines that are NOT indented (top-level keys).
65
+ */
66
+ function parseFrontmatterField(content: string, field: string): string | undefined {
67
+ const match = content.match(/^---\n([\s\S]*?)\n---/)
68
+ if (!match) return undefined
69
+ const body = match[1]
70
+ const line = body
71
+ .split('\n')
72
+ .find((l) => l.match(new RegExp(`^${field}:\\s`)))
73
+ if (!line) return undefined
74
+ const value = line.slice(field.length + 1).trim().replace(/^["']|["']$/g, '')
75
+ return value || undefined
76
+ }
77
+
78
+ /**
79
+ * Parse a YAML inline array field like `tags: [a, b, c]` or `depends: [x, y]`.
80
+ */
81
+ function parseFrontmatterArrayField(content: string, field: string): string[] {
82
+ const raw = parseFrontmatterField(content, field)
83
+ if (!raw) return []
84
+ // Handle inline YAML array: [item1, item2, item3]
85
+ const arrayMatch = raw.match(/^\[(.*)\]$/)
86
+ if (arrayMatch) {
87
+ return arrayMatch[1]
88
+ .split(',')
89
+ .map((s) => s.trim().replace(/^["']|["']$/g, ''))
90
+ .filter(Boolean)
91
+ }
92
+ // Single value
93
+ return raw ? [raw] : []
94
+ }
95
+
96
+ function discoverSkillFiles(rootDir: string): string[] {
97
+ const files: string[] = []
98
+ const stack: Array<{ dir: string; depth: number }> = [{ dir: rootDir, depth: 0 }]
99
+
100
+ while (stack.length > 0) {
101
+ const current = stack.pop()
102
+ if (!current) continue
103
+ let entries: fs.Dirent[] = []
104
+ try {
105
+ entries = fs.readdirSync(current.dir, { withFileTypes: true })
106
+ } catch {
107
+ continue
108
+ }
109
+ for (const entry of entries) {
110
+ const abs = path.join(current.dir, entry.name)
111
+ if (entry.isFile() && entry.name === SKILL_FILE_NAME) {
112
+ files.push(abs)
113
+ continue
114
+ }
115
+ if (!entry.isDirectory()) continue
116
+ if (entry.name.startsWith('.')) continue
117
+ if (current.depth >= MAX_SCAN_DEPTH) continue
118
+ stack.push({ dir: abs, depth: current.depth + 1 })
119
+ }
120
+ }
121
+
122
+ return files
123
+ }
124
+
125
+ /**
126
+ * Parse a SKILL.md file into a SkillEntry.
127
+ * Requires frontmatter with `name:` and `description:`.
128
+ * Returns null if either is missing.
129
+ */
130
+ function parseSkillFile(skillFile: string, displayPath: string, source: SkillEntry['source']): SkillEntry | null {
131
+ const content = safeReadText(skillFile)
132
+ if (!content) return null
133
+ const name = parseFrontmatterField(content, 'name')
134
+ // Accept both 'description' and 'shortDescription' (myRAM compat)
135
+ const description = parseFrontmatterField(content, 'description')
136
+ ?? parseFrontmatterField(content, 'shortDescription')
137
+ if (!name || !description) return null
138
+ const category = parseFrontmatterField(content, 'category') ?? inferCategory(name, description)
139
+ const depends = parseFrontmatterArrayField(content, 'depends')
140
+ const tags = parseFrontmatterArrayField(content, 'tags')
141
+ const triggers = parseFrontmatterArrayField(content, 'triggers')
142
+ return {
143
+ name,
144
+ description,
145
+ category,
146
+ depends,
147
+ tags,
148
+ triggers,
149
+ path: displayPath,
150
+ dir: path.dirname(skillFile),
151
+ source,
152
+ content
153
+ }
154
+ }
155
+
156
+ /** Infer a category from skill name/description when not explicitly set. */
157
+ function inferCategory(name: string, description: string): string {
158
+ const text = `${name} ${description}`.toLowerCase()
159
+ if (/writ|manuscript|draft|prose|humaniz/.test(text)) return 'Writing & Review'
160
+ if (/visual|plot|chart|matplotlib|seaborn|figure/.test(text)) return 'Visualization'
161
+ if (/data|analy|statistic|ml|model/.test(text)) return 'Data & Analysis'
162
+ if (/literature|paper|search|review|academic|citation/.test(text)) return 'Literature & Search'
163
+ if (/grant|proposal|funding/.test(text)) return 'Grants & Proposals'
164
+ if (/evaluat|scholar|critique|assess/.test(text)) return 'Evaluation'
165
+ return 'General'
166
+ }
167
+
168
+ // ---------------------------------------------------------------------------
169
+ // Public API
170
+ // ---------------------------------------------------------------------------
171
+
172
+ /** Load built-in skills that ship with the software. */
173
+ export function loadBuiltinSkills(): SkillEntry[] {
174
+ // Use override if set (required in bundled Electron builds), else fallback to import.meta.url
175
+ const skillsRoot = _builtinSkillsRoot ?? path.dirname(fileURLToPath(import.meta.url))
176
+ if (!fs.existsSync(skillsRoot) || !fs.statSync(skillsRoot).isDirectory()) {
177
+ return []
178
+ }
179
+ const files = discoverSkillFiles(skillsRoot)
180
+ // Deduplicate by name (later files override earlier)
181
+ const byName = new Map<string, SkillEntry>()
182
+ for (const file of files) {
183
+ const entry = parseSkillFile(file, `[builtin] ${path.relative(skillsRoot, file)}`, 'builtin')
184
+ if (entry) byName.set(entry.name, entry)
185
+ }
186
+ return Array.from(byName.values()).sort((a, b) => a.name.localeCompare(b.name))
187
+ }
188
+
189
+ /** Load workspace-level skills from .research-pilot/skills/. */
190
+ export function loadWorkspaceSkills(workspacePath: string): SkillEntry[] {
191
+ const skillRoot = path.resolve(workspacePath, '.research-pilot', 'skills')
192
+ if (!fs.existsSync(skillRoot) || !fs.statSync(skillRoot).isDirectory()) {
193
+ return []
194
+ }
195
+ const files = discoverSkillFiles(skillRoot)
196
+ const entries = files
197
+ .map((file) => parseSkillFile(file, path.relative(workspacePath, file), 'workspace'))
198
+ .filter((entry): entry is SkillEntry => entry !== null)
199
+ return entries.sort((a, b) => a.name.localeCompare(b.name))
200
+ }
201
+
202
+ /** Load user-global skills from ~/.research-pilot/skills/. */
203
+ function loadUserSkills(): SkillEntry[] {
204
+ const userRoot = path.resolve(os.homedir(), '.research-pilot', 'skills')
205
+ if (!fs.existsSync(userRoot) || !fs.statSync(userRoot).isDirectory()) {
206
+ return []
207
+ }
208
+ const files = discoverSkillFiles(userRoot)
209
+ const entries = files
210
+ .map((file) => parseSkillFile(file, `[user] ~/.research-pilot/skills/${path.relative(userRoot, file)}`, 'user'))
211
+ .filter((entry): entry is SkillEntry => entry !== null)
212
+ return entries.sort((a, b) => a.name.localeCompare(b.name))
213
+ }
214
+
215
+ /**
216
+ * Load all skills: built-in + user-global + workspace.
217
+ * Override order (highest wins): workspace > user-global > built-in.
218
+ */
219
+ export function loadAllSkills(workspacePath: string): SkillEntry[] {
220
+ const builtin = loadBuiltinSkills()
221
+ const user = loadUserSkills()
222
+ const workspace = loadWorkspaceSkills(workspacePath)
223
+
224
+ const userNames = new Set(user.map((s) => s.name))
225
+ const workspaceNames = new Set(workspace.map((s) => s.name))
226
+ const merged = [
227
+ ...builtin.filter((s) => !userNames.has(s.name) && !workspaceNames.has(s.name)),
228
+ ...user.filter((s) => !workspaceNames.has(s.name)),
229
+ ...workspace
230
+ ]
231
+ return merged.sort((a, b) => a.name.localeCompare(b.name))
232
+ }
233
+
234
+ // ---------------------------------------------------------------------------
235
+ // Enabled skills config (persisted per-workspace)
236
+ // ---------------------------------------------------------------------------
237
+
238
+ export interface SkillManifest {
239
+ name: string
240
+ description: string
241
+ category: string
242
+ depends: string[]
243
+ tags: string[]
244
+ source: 'builtin' | 'user' | 'workspace'
245
+ enabled: boolean
246
+ enabledReason: 'direct' | 'dependency' | null
247
+ dependencyOf: string[] // Which directly-selected skills pulled this in
248
+ }
249
+
250
+ // ---------------------------------------------------------------------------
251
+ // Dependency resolution (BFS transitive)
252
+ // ---------------------------------------------------------------------------
253
+
254
+ interface ResolvedSkill {
255
+ reason: 'direct' | 'dependency'
256
+ dependencyOf: string[]
257
+ }
258
+
259
+ /**
260
+ * Resolve skill dependencies using BFS.
261
+ * Returns a map of skill name -> resolution info.
262
+ */
263
+ export function resolveSkillDependencies(
264
+ allSkills: SkillEntry[],
265
+ directSelection: string[]
266
+ ): Map<string, ResolvedSkill> {
267
+ const byName = new Map(allSkills.map((s) => [s.name, s]))
268
+ const result = new Map<string, ResolvedSkill>()
269
+ const queue: string[] = []
270
+
271
+ // Seed with directly selected skills
272
+ for (const name of directSelection) {
273
+ if (!byName.has(name)) continue
274
+ result.set(name, { reason: 'direct', dependencyOf: [] })
275
+ queue.push(name)
276
+ }
277
+
278
+ // BFS: resolve transitive dependencies
279
+ while (queue.length > 0) {
280
+ const current = queue.shift()!
281
+ const skill = byName.get(current)
282
+ if (!skill) continue
283
+
284
+ for (const depName of skill.depends) {
285
+ if (!byName.has(depName)) continue // skip unknown deps
286
+
287
+ const existing = result.get(depName)
288
+ if (existing) {
289
+ // Already resolved — just track who else depends on it
290
+ if (!existing.dependencyOf.includes(current)) {
291
+ existing.dependencyOf.push(current)
292
+ }
293
+ } else {
294
+ result.set(depName, { reason: 'dependency', dependencyOf: [current] })
295
+ queue.push(depName)
296
+ }
297
+ }
298
+ }
299
+
300
+ return result
301
+ }
302
+
303
+ /** Read enabled skills list from workspace config. Returns null if not set (= all enabled). */
304
+ export function readEnabledSkills(workspacePath: string): string[] | null {
305
+ const configPath = path.resolve(workspacePath, '.research-pilot', 'skills-config.json')
306
+ try {
307
+ const raw = fs.readFileSync(configPath, 'utf8')
308
+ const config = JSON.parse(raw)
309
+ if (Array.isArray(config.enabledSkills)) return config.enabledSkills
310
+ } catch {
311
+ // no config yet
312
+ }
313
+ return null
314
+ }
315
+
316
+ /** Write enabled skills list to workspace config. */
317
+ export function writeEnabledSkills(workspacePath: string, enabledSkills: string[]): void {
318
+ const configDir = path.resolve(workspacePath, '.research-pilot')
319
+ if (!fs.existsSync(configDir)) fs.mkdirSync(configDir, { recursive: true })
320
+ const configPath = path.join(configDir, 'skills-config.json')
321
+ fs.writeFileSync(configPath, JSON.stringify({ enabledSkills }, null, 2), 'utf8')
322
+ }
323
+
324
+ /** Build manifests for the UI: all skills with their enabled state and dependency info. */
325
+ export function buildSkillManifests(workspacePath: string): SkillManifest[] {
326
+ const allSkills = loadAllSkills(workspacePath)
327
+ const enabledList = readEnabledSkills(workspacePath)
328
+
329
+ // If no config, all are directly enabled
330
+ const directSelection = enabledList ?? allSkills.map((s) => s.name)
331
+ const resolved = resolveSkillDependencies(allSkills, directSelection)
332
+
333
+ return allSkills.map((s) => {
334
+ const r = resolved.get(s.name)
335
+ return {
336
+ name: s.name,
337
+ description: s.description,
338
+ category: s.category,
339
+ depends: s.depends,
340
+ tags: s.tags,
341
+ source: s.source,
342
+ enabled: !!r,
343
+ enabledReason: r?.reason ?? null,
344
+ dependencyOf: r?.dependencyOf ?? []
345
+ }
346
+ })
347
+ }
348
+
349
+ /** Install a skill from a directory into workspace skills. */
350
+ export function installSkillToWorkspace(
351
+ workspacePath: string,
352
+ skillName: string,
353
+ skillDir: string
354
+ ): void {
355
+ const destDir = path.resolve(workspacePath, '.research-pilot', 'skills', skillName)
356
+ if (!fs.existsSync(destDir)) fs.mkdirSync(destDir, { recursive: true })
357
+ // Copy all files from skillDir to destDir
358
+ copyDirSync(skillDir, destDir)
359
+ }
360
+
361
+ function copyDirSync(src: string, dest: string): void {
362
+ const entries = fs.readdirSync(src, { withFileTypes: true })
363
+ for (const entry of entries) {
364
+ const srcPath = path.join(src, entry.name)
365
+ const destPath = path.join(dest, entry.name)
366
+ if (entry.isDirectory()) {
367
+ if (!fs.existsSync(destPath)) fs.mkdirSync(destPath, { recursive: true })
368
+ copyDirSync(srcPath, destPath)
369
+ } else {
370
+ fs.copyFileSync(srcPath, destPath)
371
+ }
372
+ }
373
+ }
374
+
375
+ /** Build a catalog (summary without content) for UI display. */
376
+ export function buildSkillsCatalog(entries: SkillEntry[]): SkillCatalogItem[] {
377
+ return entries.map((entry) => ({
378
+ name: entry.name,
379
+ description: entry.description,
380
+ path: entry.path
381
+ }))
382
+ }
383
+
384
+ /** Find a skill by name (fuzzy: also tries substring match). */
385
+ export function getSkillByName(entries: SkillEntry[], name: string): SkillEntry | undefined {
386
+ const trimmed = name.trim()
387
+ if (!trimmed) return undefined
388
+ return entries.find((entry) => entry.name === trimmed)
389
+ }
390
+
391
+ /**
392
+ * Build a prompt section that lists available skills for the LLM.
393
+ * Injected into the system prompt so the agent knows what skills exist
394
+ * and can call `load_skill` to load full instructions on demand.
395
+ */
396
+ export function buildSkillsCatalogPrompt(entries: SkillEntry[]): string {
397
+ if (entries.length === 0) return ''
398
+ const lines = entries.map((e) => `- **${e.name}** [${e.category}]: ${e.description}`)
399
+ return [
400
+ '## Skills',
401
+ 'You have the following skills available. Call `load_skill(name)` to load full procedures for any skill before relying on it.',
402
+ '',
403
+ ...lines,
404
+ '',
405
+ 'Some skills may be pre-loaded as summaries below based on this request. Call `load_skill` for full procedures when needed.'
406
+ ].join('\n')
407
+ }
408
+
409
+ /**
410
+ * Build a compact skill summary (~500 tokens) for system prompt injection.
411
+ * Extracts frontmatter + Overview section from SKILL.md.
412
+ * Used by LLM skill matching to give the agent a richer hint than the one-line
413
+ * catalog description, without loading the full skill content.
414
+ */
415
+ export function buildSkillSummary(entry: SkillEntry, maxChars = 2000): string {
416
+ // Strip frontmatter
417
+ const bodyMatch = entry.content.match(/^---\n[\s\S]*?\n---\n*([\s\S]*)$/)
418
+ const body = bodyMatch?.[1] ?? entry.content
419
+
420
+ // Extract Overview + When to Use sections (typically the first ~500 tokens)
421
+ const sections = body.split(/\n## /)
422
+ const overview = sections[0]?.trim() ?? '' // text before first ## or the # heading section
423
+ const whenToUse = sections.find(s => /^When to Use/i.test(s))
424
+ const summaryParts = [overview]
425
+ if (whenToUse) summaryParts.push(`## ${whenToUse}`)
426
+
427
+ let summary = summaryParts.join('\n\n').trim()
428
+ if (summary.length > maxChars) {
429
+ summary = summary.slice(0, maxChars) + '\n\n[... call load_skill for full procedures]'
430
+ }
431
+ return summary
432
+ }
433
+
434
+ /**
435
+ * Build the full skill context string for a loaded skill.
436
+ * Returned as the tool result when `load_skill` is called.
437
+ */
438
+ export function buildSkillContext(entry: SkillEntry, maxChars = 50_000): string {
439
+ const header = [
440
+ 'Skill context loaded for this request. Follow these instructions where applicable.',
441
+ '',
442
+ `### Skill: ${entry.name}`,
443
+ `Path: ${entry.path}`,
444
+ `Directory: ${entry.dir}`,
445
+ ''
446
+ ].join('\n')
447
+
448
+ const body = entry.content.length > maxChars
449
+ ? entry.content.slice(0, maxChars) + '\n\n[... truncated]'
450
+ : entry.content
451
+ return header + body
452
+ }
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "research-copilot",
3
+ "version": "0.1.0",
4
+ "description": "AI-powered research assistant for scientists — literature search, data analysis, academic writing, and project management",
5
+ "type": "module",
6
+ "bin": {
7
+ "research-copilot": "./bin/cli.mjs"
8
+ },
9
+ "files": [
10
+ "bin/",
11
+ "app/out/",
12
+ "app/build/",
13
+ "app/package.json",
14
+ "lib/skills/",
15
+ "README.md",
16
+ "LICENSE"
17
+ ],
18
+ "workspaces": [
19
+ "app",
20
+ "lib",
21
+ "shared-ui",
22
+ "shared-electron"
23
+ ],
24
+ "scripts": {
25
+ "dev": "cd app && npx electron-vite dev",
26
+ "build": "cd app && npx electron-vite build",
27
+ "clean": "rm -rf app/out app/dist",
28
+ "prepublishOnly": "npm run build"
29
+ },
30
+ "keywords": [
31
+ "research",
32
+ "ai",
33
+ "academic",
34
+ "literature-search",
35
+ "data-analysis",
36
+ "electron",
37
+ "desktop"
38
+ ],
39
+ "author": "daidong",
40
+ "license": "MIT",
41
+ "repository": {
42
+ "type": "git",
43
+ "url": "git+https://github.com/daidong/PiPilot.git"
44
+ },
45
+ "homepage": "https://daidong.github.io/PiPilot/",
46
+ "engines": {
47
+ "node": ">=18"
48
+ },
49
+ "dependencies": {
50
+ "@mariozechner/pi-agent-core": "^0.61.1",
51
+ "@mariozechner/pi-ai": "^0.61.1",
52
+ "@mariozechner/pi-coding-agent": "^0.61.1",
53
+ "@sinclair/typebox": "^0.34.48",
54
+ "adm-zip": "^0.5.16",
55
+ "ajv": "^8.18.0",
56
+ "ajv-formats": "^3.0.1",
57
+ "electron": "^33.3.1",
58
+ "ignore": "^7.0.5",
59
+ "minimatch": "^10.2.4",
60
+ "node-pty": "^1.1.0"
61
+ }
62
+ }