@pi-harness/pi-harness 0.1.28 → 0.1.30

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 (298) hide show
  1. package/README.md +1 -1
  2. package/apps/web/dist/assets/{index-1vaEg8Vr.js → index-B7pwZ76Z.js} +2 -2
  3. package/apps/web/dist/index.html +1 -1
  4. package/apps/web/package.json +1 -15
  5. package/apps/web/profile/cordis.yml +73 -73
  6. package/apps/web/server-dist/bin.js +4 -2
  7. package/apps/web/server-dist/bin.js.map +1 -1
  8. package/apps/web/src/server/bin.ts +4 -2
  9. package/apps/web/test/bin.test.ts +6 -0
  10. package/node_modules/@pi-harness/api-gateway/dist/index.d.ts.map +1 -1
  11. package/node_modules/@pi-harness/api-gateway/dist/index.js +5 -12
  12. package/node_modules/@pi-harness/api-gateway/dist/index.js.map +1 -1
  13. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/agent-teams.json +3 -3
  14. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/anchored-standard.json +3 -3
  15. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/annotation.json +3 -3
  16. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/archify.json +3 -3
  17. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/at-file.json +3 -3
  18. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/auto-mode.json +3 -3
  19. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/better-sidebar.json +3 -3
  20. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/browser-fetch.json +3 -3
  21. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/browser-session.json +3 -3
  22. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/canvas-draw.json +3 -3
  23. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/change-verifier.json +3 -3
  24. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/cleaner.json +3 -3
  25. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/cli-notifier.json +3 -3
  26. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/code2skill.json +3 -3
  27. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/colleague-skill.json +3 -3
  28. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/context-doctor.json +3 -3
  29. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/context.json +3 -3
  30. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/cost-meter.json +3 -3
  31. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/dependency-checker.json +3 -3
  32. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/docker-sandbox.json +3 -3
  33. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/fail-logger.json +3 -3
  34. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/genui.json +3 -3
  35. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/git-time-capsule.json +3 -3
  36. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/graph-memory.json +3 -3
  37. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/history-compressor.json +3 -3
  38. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/hol-guard.json +3 -3
  39. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/i18n-pair.json +3 -3
  40. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/image-compressor.json +3 -3
  41. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/llm-verifier.json +3 -3
  42. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/mcp-client.json +3 -3
  43. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/mcp-panel.json +3 -3
  44. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/memory.json +3 -3
  45. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/mirage-bridge.json +3 -3
  46. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/mock-server.json +3 -3
  47. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/modlens.json +3 -3
  48. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/module-search.json +3 -3
  49. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/obsidian-sync.json +3 -3
  50. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/openpets.json +3 -3
  51. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/plan-execute.json +3 -3
  52. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/plugin-check.json +3 -3
  53. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/plugin-dev.json +3 -3
  54. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/plugin-finder.json +3 -3
  55. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/plugin-radar.json +3 -3
  56. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/plugin-stars.json +3 -3
  57. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/prompt-guard.json +3 -3
  58. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/prompt-library.json +3 -3
  59. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/readme-gen.json +3 -3
  60. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/recall-unread.json +3 -3
  61. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/reverse-skill.json +3 -3
  62. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/reviewer-bot.json +3 -3
  63. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/runtime-doctor.json +3 -3
  64. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/secure-audit.json +3 -3
  65. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/session-bookmarks.json +3 -3
  66. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/session-bridge.json +3 -3
  67. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/session-compare.json +3 -3
  68. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/session-export.json +3 -3
  69. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/session-insights.json +3 -3
  70. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/session-search.json +3 -3
  71. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/skill-catalog.json +3 -3
  72. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/skill-guard.json +3 -3
  73. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/sql-lens.json +3 -3
  74. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/synapse.json +3 -3
  75. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/tab-manager.json +3 -3
  76. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/taskboard.json +3 -3
  77. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/telemetry-blocker.json +3 -3
  78. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/test-harness.json +3 -3
  79. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/theme-studio.json +3 -3
  80. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/token-guard.json +3 -3
  81. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/turn-rewind.json +3 -3
  82. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/undo-savepoint.json +3 -3
  83. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/vision-toolkit.json +3 -3
  84. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/web-research.json +3 -3
  85. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/workspace-navigator.json +3 -3
  86. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/workspace-search.json +3 -3
  87. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/yaml-validator.json +3 -3
  88. package/node_modules/@pi-harness/api-gateway/dist/marketplace.d.ts +0 -1
  89. package/node_modules/@pi-harness/api-gateway/dist/marketplace.d.ts.map +1 -1
  90. package/node_modules/@pi-harness/api-gateway/dist/marketplace.js +0 -3
  91. package/node_modules/@pi-harness/api-gateway/dist/marketplace.js.map +1 -1
  92. package/node_modules/@pi-harness/api-gateway/package.json +27 -1
  93. package/node_modules/@pi-harness/cli/dist/bin.js +2 -1
  94. package/node_modules/@pi-harness/cli/dist/bin.js.map +1 -1
  95. package/node_modules/@pi-harness/cli/dist/main.d.ts +2 -0
  96. package/node_modules/@pi-harness/cli/dist/main.d.ts.map +1 -1
  97. package/node_modules/@pi-harness/cli/dist/main.js +12 -2
  98. package/node_modules/@pi-harness/cli/dist/main.js.map +1 -1
  99. package/node_modules/@pi-harness/cli/dist/profiles.d.ts +3 -0
  100. package/node_modules/@pi-harness/cli/dist/profiles.d.ts.map +1 -0
  101. package/node_modules/@pi-harness/cli/dist/profiles.js +5 -0
  102. package/node_modules/@pi-harness/cli/dist/profiles.js.map +1 -0
  103. package/node_modules/@pi-harness/cli/package.json +3 -2
  104. package/node_modules/@pi-harness/cli/profiles/default/cordis.yml +122 -0
  105. package/node_modules/@pi-harness/cli/profiles/development/cordis.yml +47 -0
  106. package/node_modules/@pi-harness/host-webserver/package.json +1 -1
  107. package/node_modules/@pi-harness/web-app/package.json +1 -1
  108. package/package.json +88 -15
  109. package/packages/api-gateway/dist/index.d.ts.map +1 -1
  110. package/packages/api-gateway/dist/index.js +5 -12
  111. package/packages/api-gateway/dist/index.js.map +1 -1
  112. package/packages/api-gateway/dist/marketplace-entries/official/agent-teams.json +3 -3
  113. package/packages/api-gateway/dist/marketplace-entries/official/anchored-standard.json +3 -3
  114. package/packages/api-gateway/dist/marketplace-entries/official/annotation.json +3 -3
  115. package/packages/api-gateway/dist/marketplace-entries/official/archify.json +3 -3
  116. package/packages/api-gateway/dist/marketplace-entries/official/at-file.json +3 -3
  117. package/packages/api-gateway/dist/marketplace-entries/official/auto-mode.json +3 -3
  118. package/packages/api-gateway/dist/marketplace-entries/official/better-sidebar.json +3 -3
  119. package/packages/api-gateway/dist/marketplace-entries/official/browser-fetch.json +3 -3
  120. package/packages/api-gateway/dist/marketplace-entries/official/browser-session.json +3 -3
  121. package/packages/api-gateway/dist/marketplace-entries/official/canvas-draw.json +3 -3
  122. package/packages/api-gateway/dist/marketplace-entries/official/change-verifier.json +3 -3
  123. package/packages/api-gateway/dist/marketplace-entries/official/cleaner.json +3 -3
  124. package/packages/api-gateway/dist/marketplace-entries/official/cli-notifier.json +3 -3
  125. package/packages/api-gateway/dist/marketplace-entries/official/code2skill.json +3 -3
  126. package/packages/api-gateway/dist/marketplace-entries/official/colleague-skill.json +3 -3
  127. package/packages/api-gateway/dist/marketplace-entries/official/context-doctor.json +3 -3
  128. package/packages/api-gateway/dist/marketplace-entries/official/context.json +3 -3
  129. package/packages/api-gateway/dist/marketplace-entries/official/cost-meter.json +3 -3
  130. package/packages/api-gateway/dist/marketplace-entries/official/dependency-checker.json +3 -3
  131. package/packages/api-gateway/dist/marketplace-entries/official/docker-sandbox.json +3 -3
  132. package/packages/api-gateway/dist/marketplace-entries/official/fail-logger.json +3 -3
  133. package/packages/api-gateway/dist/marketplace-entries/official/genui.json +3 -3
  134. package/packages/api-gateway/dist/marketplace-entries/official/git-time-capsule.json +3 -3
  135. package/packages/api-gateway/dist/marketplace-entries/official/graph-memory.json +3 -3
  136. package/packages/api-gateway/dist/marketplace-entries/official/history-compressor.json +3 -3
  137. package/packages/api-gateway/dist/marketplace-entries/official/hol-guard.json +3 -3
  138. package/packages/api-gateway/dist/marketplace-entries/official/i18n-pair.json +3 -3
  139. package/packages/api-gateway/dist/marketplace-entries/official/image-compressor.json +3 -3
  140. package/packages/api-gateway/dist/marketplace-entries/official/llm-verifier.json +3 -3
  141. package/packages/api-gateway/dist/marketplace-entries/official/mcp-client.json +3 -3
  142. package/packages/api-gateway/dist/marketplace-entries/official/mcp-panel.json +3 -3
  143. package/packages/api-gateway/dist/marketplace-entries/official/memory.json +3 -3
  144. package/packages/api-gateway/dist/marketplace-entries/official/mirage-bridge.json +3 -3
  145. package/packages/api-gateway/dist/marketplace-entries/official/mock-server.json +3 -3
  146. package/packages/api-gateway/dist/marketplace-entries/official/modlens.json +3 -3
  147. package/packages/api-gateway/dist/marketplace-entries/official/module-search.json +3 -3
  148. package/packages/api-gateway/dist/marketplace-entries/official/obsidian-sync.json +3 -3
  149. package/packages/api-gateway/dist/marketplace-entries/official/openpets.json +3 -3
  150. package/packages/api-gateway/dist/marketplace-entries/official/plan-execute.json +3 -3
  151. package/packages/api-gateway/dist/marketplace-entries/official/plugin-check.json +3 -3
  152. package/packages/api-gateway/dist/marketplace-entries/official/plugin-dev.json +3 -3
  153. package/packages/api-gateway/dist/marketplace-entries/official/plugin-finder.json +3 -3
  154. package/packages/api-gateway/dist/marketplace-entries/official/plugin-radar.json +3 -3
  155. package/packages/api-gateway/dist/marketplace-entries/official/plugin-stars.json +3 -3
  156. package/packages/api-gateway/dist/marketplace-entries/official/prompt-guard.json +3 -3
  157. package/packages/api-gateway/dist/marketplace-entries/official/prompt-library.json +3 -3
  158. package/packages/api-gateway/dist/marketplace-entries/official/readme-gen.json +3 -3
  159. package/packages/api-gateway/dist/marketplace-entries/official/recall-unread.json +3 -3
  160. package/packages/api-gateway/dist/marketplace-entries/official/reverse-skill.json +3 -3
  161. package/packages/api-gateway/dist/marketplace-entries/official/reviewer-bot.json +3 -3
  162. package/packages/api-gateway/dist/marketplace-entries/official/runtime-doctor.json +3 -3
  163. package/packages/api-gateway/dist/marketplace-entries/official/secure-audit.json +3 -3
  164. package/packages/api-gateway/dist/marketplace-entries/official/session-bookmarks.json +3 -3
  165. package/packages/api-gateway/dist/marketplace-entries/official/session-bridge.json +3 -3
  166. package/packages/api-gateway/dist/marketplace-entries/official/session-compare.json +3 -3
  167. package/packages/api-gateway/dist/marketplace-entries/official/session-export.json +3 -3
  168. package/packages/api-gateway/dist/marketplace-entries/official/session-insights.json +3 -3
  169. package/packages/api-gateway/dist/marketplace-entries/official/session-search.json +3 -3
  170. package/packages/api-gateway/dist/marketplace-entries/official/skill-catalog.json +3 -3
  171. package/packages/api-gateway/dist/marketplace-entries/official/skill-guard.json +3 -3
  172. package/packages/api-gateway/dist/marketplace-entries/official/sql-lens.json +3 -3
  173. package/packages/api-gateway/dist/marketplace-entries/official/synapse.json +3 -3
  174. package/packages/api-gateway/dist/marketplace-entries/official/tab-manager.json +3 -3
  175. package/packages/api-gateway/dist/marketplace-entries/official/taskboard.json +3 -3
  176. package/packages/api-gateway/dist/marketplace-entries/official/telemetry-blocker.json +3 -3
  177. package/packages/api-gateway/dist/marketplace-entries/official/test-harness.json +3 -3
  178. package/packages/api-gateway/dist/marketplace-entries/official/theme-studio.json +3 -3
  179. package/packages/api-gateway/dist/marketplace-entries/official/token-guard.json +3 -3
  180. package/packages/api-gateway/dist/marketplace-entries/official/turn-rewind.json +3 -3
  181. package/packages/api-gateway/dist/marketplace-entries/official/undo-savepoint.json +3 -3
  182. package/packages/api-gateway/dist/marketplace-entries/official/vision-toolkit.json +3 -3
  183. package/packages/api-gateway/dist/marketplace-entries/official/web-research.json +3 -3
  184. package/packages/api-gateway/dist/marketplace-entries/official/workspace-navigator.json +3 -3
  185. package/packages/api-gateway/dist/marketplace-entries/official/workspace-search.json +3 -3
  186. package/packages/api-gateway/dist/marketplace-entries/official/yaml-validator.json +3 -3
  187. package/packages/api-gateway/dist/marketplace.d.ts +0 -1
  188. package/packages/api-gateway/dist/marketplace.d.ts.map +1 -1
  189. package/packages/api-gateway/dist/marketplace.js +0 -3
  190. package/packages/api-gateway/dist/marketplace.js.map +1 -1
  191. package/packages/api-gateway/package.json +27 -1
  192. package/packages/api-gateway/src/index.ts +4 -12
  193. package/packages/api-gateway/src/marketplace-entries/official/agent-teams.json +3 -3
  194. package/packages/api-gateway/src/marketplace-entries/official/anchored-standard.json +3 -3
  195. package/packages/api-gateway/src/marketplace-entries/official/annotation.json +3 -3
  196. package/packages/api-gateway/src/marketplace-entries/official/archify.json +3 -3
  197. package/packages/api-gateway/src/marketplace-entries/official/at-file.json +3 -3
  198. package/packages/api-gateway/src/marketplace-entries/official/auto-mode.json +3 -3
  199. package/packages/api-gateway/src/marketplace-entries/official/better-sidebar.json +3 -3
  200. package/packages/api-gateway/src/marketplace-entries/official/browser-fetch.json +3 -3
  201. package/packages/api-gateway/src/marketplace-entries/official/browser-session.json +3 -3
  202. package/packages/api-gateway/src/marketplace-entries/official/canvas-draw.json +3 -3
  203. package/packages/api-gateway/src/marketplace-entries/official/change-verifier.json +3 -3
  204. package/packages/api-gateway/src/marketplace-entries/official/cleaner.json +3 -3
  205. package/packages/api-gateway/src/marketplace-entries/official/cli-notifier.json +3 -3
  206. package/packages/api-gateway/src/marketplace-entries/official/code2skill.json +3 -3
  207. package/packages/api-gateway/src/marketplace-entries/official/colleague-skill.json +3 -3
  208. package/packages/api-gateway/src/marketplace-entries/official/context-doctor.json +3 -3
  209. package/packages/api-gateway/src/marketplace-entries/official/context.json +3 -3
  210. package/packages/api-gateway/src/marketplace-entries/official/cost-meter.json +3 -3
  211. package/packages/api-gateway/src/marketplace-entries/official/dependency-checker.json +3 -3
  212. package/packages/api-gateway/src/marketplace-entries/official/docker-sandbox.json +3 -3
  213. package/packages/api-gateway/src/marketplace-entries/official/fail-logger.json +3 -3
  214. package/packages/api-gateway/src/marketplace-entries/official/genui.json +3 -3
  215. package/packages/api-gateway/src/marketplace-entries/official/git-time-capsule.json +3 -3
  216. package/packages/api-gateway/src/marketplace-entries/official/graph-memory.json +3 -3
  217. package/packages/api-gateway/src/marketplace-entries/official/history-compressor.json +3 -3
  218. package/packages/api-gateway/src/marketplace-entries/official/hol-guard.json +3 -3
  219. package/packages/api-gateway/src/marketplace-entries/official/i18n-pair.json +3 -3
  220. package/packages/api-gateway/src/marketplace-entries/official/image-compressor.json +3 -3
  221. package/packages/api-gateway/src/marketplace-entries/official/llm-verifier.json +3 -3
  222. package/packages/api-gateway/src/marketplace-entries/official/mcp-client.json +3 -3
  223. package/packages/api-gateway/src/marketplace-entries/official/mcp-panel.json +3 -3
  224. package/packages/api-gateway/src/marketplace-entries/official/memory.json +3 -3
  225. package/packages/api-gateway/src/marketplace-entries/official/mirage-bridge.json +3 -3
  226. package/packages/api-gateway/src/marketplace-entries/official/mock-server.json +3 -3
  227. package/packages/api-gateway/src/marketplace-entries/official/modlens.json +3 -3
  228. package/packages/api-gateway/src/marketplace-entries/official/module-search.json +3 -3
  229. package/packages/api-gateway/src/marketplace-entries/official/obsidian-sync.json +3 -3
  230. package/packages/api-gateway/src/marketplace-entries/official/openpets.json +3 -3
  231. package/packages/api-gateway/src/marketplace-entries/official/plan-execute.json +3 -3
  232. package/packages/api-gateway/src/marketplace-entries/official/plugin-check.json +3 -3
  233. package/packages/api-gateway/src/marketplace-entries/official/plugin-dev.json +3 -3
  234. package/packages/api-gateway/src/marketplace-entries/official/plugin-finder.json +3 -3
  235. package/packages/api-gateway/src/marketplace-entries/official/plugin-radar.json +3 -3
  236. package/packages/api-gateway/src/marketplace-entries/official/plugin-stars.json +3 -3
  237. package/packages/api-gateway/src/marketplace-entries/official/prompt-guard.json +3 -3
  238. package/packages/api-gateway/src/marketplace-entries/official/prompt-library.json +3 -3
  239. package/packages/api-gateway/src/marketplace-entries/official/readme-gen.json +3 -3
  240. package/packages/api-gateway/src/marketplace-entries/official/recall-unread.json +3 -3
  241. package/packages/api-gateway/src/marketplace-entries/official/reverse-skill.json +3 -3
  242. package/packages/api-gateway/src/marketplace-entries/official/reviewer-bot.json +3 -3
  243. package/packages/api-gateway/src/marketplace-entries/official/runtime-doctor.json +3 -3
  244. package/packages/api-gateway/src/marketplace-entries/official/secure-audit.json +3 -3
  245. package/packages/api-gateway/src/marketplace-entries/official/session-bookmarks.json +3 -3
  246. package/packages/api-gateway/src/marketplace-entries/official/session-bridge.json +3 -3
  247. package/packages/api-gateway/src/marketplace-entries/official/session-compare.json +3 -3
  248. package/packages/api-gateway/src/marketplace-entries/official/session-export.json +3 -3
  249. package/packages/api-gateway/src/marketplace-entries/official/session-insights.json +3 -3
  250. package/packages/api-gateway/src/marketplace-entries/official/session-search.json +3 -3
  251. package/packages/api-gateway/src/marketplace-entries/official/skill-catalog.json +3 -3
  252. package/packages/api-gateway/src/marketplace-entries/official/skill-guard.json +3 -3
  253. package/packages/api-gateway/src/marketplace-entries/official/sql-lens.json +3 -3
  254. package/packages/api-gateway/src/marketplace-entries/official/synapse.json +3 -3
  255. package/packages/api-gateway/src/marketplace-entries/official/tab-manager.json +3 -3
  256. package/packages/api-gateway/src/marketplace-entries/official/taskboard.json +3 -3
  257. package/packages/api-gateway/src/marketplace-entries/official/telemetry-blocker.json +3 -3
  258. package/packages/api-gateway/src/marketplace-entries/official/test-harness.json +3 -3
  259. package/packages/api-gateway/src/marketplace-entries/official/theme-studio.json +3 -3
  260. package/packages/api-gateway/src/marketplace-entries/official/token-guard.json +3 -3
  261. package/packages/api-gateway/src/marketplace-entries/official/turn-rewind.json +3 -3
  262. package/packages/api-gateway/src/marketplace-entries/official/undo-savepoint.json +3 -3
  263. package/packages/api-gateway/src/marketplace-entries/official/vision-toolkit.json +3 -3
  264. package/packages/api-gateway/src/marketplace-entries/official/web-research.json +3 -3
  265. package/packages/api-gateway/src/marketplace-entries/official/workspace-navigator.json +3 -3
  266. package/packages/api-gateway/src/marketplace-entries/official/workspace-search.json +3 -3
  267. package/packages/api-gateway/src/marketplace-entries/official/yaml-validator.json +3 -3
  268. package/packages/api-gateway/src/marketplace.ts +0 -4
  269. package/packages/api-gateway/test/index.test.ts +140 -94
  270. package/packages/api-gateway/test/marketplace-schema.test.ts +1 -1
  271. package/packages/api-gateway/test/marketplace.test.ts +7 -9
  272. package/packages/api-gateway/test/packed-package.test.ts +95 -11
  273. package/packages/api-gateway/test/release-contract.test.ts +37 -6
  274. package/packages/api-gateway/test/release-package.test.ts +1 -1
  275. package/packages/api-gateway/test/release-version.test.ts +79 -3
  276. package/packages/bundle-web-app/package.json +1 -1
  277. package/packages/cli/dist/bin.js +2 -1
  278. package/packages/cli/dist/bin.js.map +1 -1
  279. package/packages/cli/dist/main.d.ts +2 -0
  280. package/packages/cli/dist/main.d.ts.map +1 -1
  281. package/packages/cli/dist/main.js +12 -2
  282. package/packages/cli/dist/main.js.map +1 -1
  283. package/packages/cli/dist/profiles.d.ts +3 -0
  284. package/packages/cli/dist/profiles.d.ts.map +1 -0
  285. package/packages/cli/dist/profiles.js +5 -0
  286. package/packages/cli/dist/profiles.js.map +1 -0
  287. package/packages/cli/package.json +3 -2
  288. package/packages/cli/profiles/default/cordis.yml +122 -0
  289. package/packages/cli/profiles/development/cordis.yml +47 -0
  290. package/packages/cli/src/bin.ts +2 -1
  291. package/packages/cli/src/main.ts +14 -2
  292. package/packages/cli/src/profiles.ts +6 -0
  293. package/packages/cli/test/binary.test.ts +5 -1
  294. package/packages/cli/test/broken-pipe.test.ts +1 -1
  295. package/packages/cli/test/cli.test.ts +1 -0
  296. package/packages/cli/test/main.test.ts +1 -0
  297. package/packages/cli/test/profiles.integration.test.ts +575 -0
  298. package/packages/host-webserver/package.json +1 -1
@@ -0,0 +1,575 @@
1
+ import { execFile } from "node:child_process";
2
+ import { mkdir, mkdtemp, readFile, writeFile } from "node:fs/promises";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { promisify } from "node:util";
6
+ import { afterEach, describe, expect, test } from "vitest";
7
+ import { bootHarness, provideStdioContext, resolveProfileConfig, type BootedHarness } from "@pi-harness/core";
8
+ import { provideLaunchContext } from "@pi-harness/plugin-api";
9
+ import { BUILTIN_PROFILES_DIR } from "../src/profiles.js";
10
+
11
+ const booted: BootedHarness[] = [];
12
+ const execFileAsync = promisify(execFile);
13
+
14
+ afterEach(async () => {
15
+ await Promise.all(booted.splice(0).map(async (harness) => harness.dispose()));
16
+ });
17
+
18
+ async function bootProfile(profile: string): Promise<{ harness: BootedHarness; cwd: string }> {
19
+ const cwd = await mkdtemp(join(tmpdir(), "pi-harness-profile-cwd-"));
20
+ const agentDir = await mkdtemp(join(tmpdir(), "pi-harness-profile-agent-"));
21
+ const configPath = await resolveProfileConfig({ profile, profilesDir: BUILTIN_PROFILES_DIR });
22
+ const harness = await bootHarness({
23
+ configPath,
24
+ prepare(context) {
25
+ provideLaunchContext(context, { cwd, agentDir, args: [], requestExit() {} });
26
+ provideStdioContext(context, {
27
+ readPrompt() {
28
+ return Promise.resolve("");
29
+ },
30
+ writeOutput() {},
31
+ writeError() {},
32
+ });
33
+ },
34
+ });
35
+ booted.push(harness);
36
+ return { harness, cwd };
37
+ }
38
+
39
+ describe("packaged profiles", () => {
40
+ test("exposes every production-profile tool with strict sequential execution metadata", async () => {
41
+ const { harness } = await bootProfile("default");
42
+ const tools = harness.context.get("piTools")?.snapshot().customTools ?? [];
43
+ expect(tools.length).toBeGreaterThan(0);
44
+ for (const tool of tools) {
45
+ expect(tool.executionMode, tool.name).toBe("sequential");
46
+ expect(tool.parameters, tool.name).toMatchObject({ type: "object", additionalProperties: false });
47
+ }
48
+ }, 30_000);
49
+
50
+ test("boots the default production profile without HMR", async () => {
51
+ const { harness, cwd } = await bootProfile("default");
52
+ const names = [...harness.context.loader.entries()].map((entry) => entry.options.name);
53
+
54
+ expect(harness.context.get("piModels")?.model.provider).toBe("deepseek");
55
+ expect(harness.context.get("piApplication")).toBeDefined();
56
+ expect(harness.context.get("hmr")).toBeUndefined();
57
+ expect(names).not.toContain("@deepseek-ai/cordis-plugin-hmr");
58
+ expect(names).toContain("@pi-harness/plugin-agent-teams");
59
+ expect(names).toContain("@pi-harness/plugin-modlens");
60
+ expect(names).toContain("@pi-harness/plugin-vision-toolkit");
61
+ expect(names).toContain("@pi-harness/plugin-git-time-capsule");
62
+ expect(names).toContain("@pi-harness/plugin-dependency-checker");
63
+ expect(names).toContain("@pi-harness/plugin-at-file");
64
+ expect(names).toContain("@pi-harness/plugin-test-harness");
65
+ expect(names).toContain("@pi-harness/plugin-session-insights");
66
+ expect(names).toContain("@pi-harness/plugin-plugin-stars");
67
+ expect(names).toContain("@pi-harness/plugin-session-bridge");
68
+ expect(names).toContain("@pi-harness/plugin-skill-guard");
69
+ expect(names).toContain("@pi-harness/plugin-recall-unread");
70
+ expect(names).toContain("@pi-harness/plugin-turn-rewind");
71
+ expect(names).toContain("@pi-harness/plugin-context-doctor");
72
+ expect(names).toEqual(
73
+ expect.arrayContaining([
74
+ "@pi-harness/plugin-sql-lens",
75
+ "@pi-harness/plugin-docker-sandbox",
76
+ "@pi-harness/plugin-mcp-client",
77
+ "@pi-harness/plugin-browser-fetch",
78
+ "@pi-harness/plugin-browser-session",
79
+ "@pi-harness/plugin-yaml-validator",
80
+ "@pi-harness/plugin-plugin-dev",
81
+ "@pi-harness/plugin-openpets",
82
+ "@pi-harness/plugin-skill-guard",
83
+ "@pi-harness/core/plugins/runtime",
84
+ "@pi-harness/plugin-context",
85
+ "@pi-harness/plugin-token-guard",
86
+ "@pi-harness/plugin-fail-logger",
87
+ "@pi-harness/core/plugins/stdio",
88
+ ]),
89
+ );
90
+
91
+ const sessionReportTool = harness.context
92
+ .get("piTools")
93
+ ?.snapshot()
94
+ .customTools.find((tool) => tool.name === "session_report");
95
+ if (sessionReportTool === undefined) throw new Error("default profile did not register session_report");
96
+ expect(
97
+ harness.context
98
+ .get("piRuntime")
99
+ ?.session.getAllTools()
100
+ .map((tool) => tool.name),
101
+ ).toContain("session_report");
102
+ const sessionReport = await sessionReportTool.execute("profile-session-report", {}, undefined, undefined, {} as never);
103
+ expect(typeof (sessionReport.details as { sessionId?: unknown }).sessionId).toBe("string");
104
+ expect(sessionReport.details).toMatchObject({
105
+ userMessages: 0,
106
+ assistantMessages: 0,
107
+ toolCalls: 0,
108
+ toolResults: 0,
109
+ totalMessages: 0,
110
+ tokens: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
111
+ cost: 0,
112
+ compaction: { status: "idle" },
113
+ });
114
+ const sessionInsightsPanel = (await harness.context.get("piPluginUi")?.snapshot())?.find((panel) => panel.id === "session-insights-panel");
115
+ expect(sessionInsightsPanel?.data).toEqual(sessionReport.details);
116
+
117
+ await writeFile(
118
+ join(cwd, "package.json"),
119
+ JSON.stringify({
120
+ scripts: { typecheck: "node profile-test-harness.mjs" },
121
+ dependencies: { present: "1.0.0", missing: "1.0.0", conflict: "^1.0.0", shared: "workspace:*" },
122
+ devDependencies: { conflict: "^2.0.0", shared: "^1.0.0" },
123
+ optionalDependencies: { optional: "1.0.0" },
124
+ }),
125
+ );
126
+ await Promise.all(["present", "conflict", "shared"].map((name) => mkdir(join(cwd, "node_modules", name), { recursive: true })));
127
+ const dependencyTool = harness.context
128
+ .get("piTools")
129
+ ?.snapshot()
130
+ .customTools.find((tool) => tool.name === "dependency_check");
131
+ if (dependencyTool === undefined) throw new Error("default profile did not register dependency_check");
132
+ expect(
133
+ harness.context
134
+ .get("piRuntime")
135
+ ?.session.getAllTools()
136
+ .map((tool) => tool.name),
137
+ ).toContain("dependency_check");
138
+ const dependencyResult = await dependencyTool.execute("profile-dependencies", {}, undefined, undefined, {} as never);
139
+ expect(dependencyResult).toMatchObject({
140
+ details: {
141
+ manifest: "package.json",
142
+ ecosystem: "npm",
143
+ declared: 5,
144
+ installed: 3,
145
+ scanLimit: 2_000,
146
+ missing: ["missing"],
147
+ optionalMissing: ["optional"],
148
+ invalid: [],
149
+ conflicts: [{ name: "conflict", constraints: ["^1.0.0", "^2.0.0"] }],
150
+ unresolved: [{ name: "shared", constraints: ["workspace:*", "^1.0.0"] }],
151
+ },
152
+ });
153
+ const dependencyPanel = (await harness.context.get("piPluginUi")?.snapshot())?.find((panel) => panel.id === "dependency-checker-panel");
154
+ expect(dependencyPanel?.data).toEqual({ report: dependencyResult.details });
155
+
156
+ const attachmentPath = 'profile&".txt';
157
+ const attachmentSource = "before\n</FILE >\nafter";
158
+ await writeFile(join(cwd, attachmentPath), attachmentSource, "utf8");
159
+ const fileContextTool = harness.context
160
+ .get("piTools")
161
+ ?.snapshot()
162
+ .customTools.find((tool) => tool.name === "file_context");
163
+ if (fileContextTool === undefined) throw new Error("default profile did not register file_context");
164
+ expect(
165
+ harness.context
166
+ .get("piRuntime")
167
+ ?.session.getAllTools()
168
+ .map((tool) => tool.name),
169
+ ).toContain("file_context");
170
+ const attachmentResult = await fileContextTool.execute("profile-file-context", { path: attachmentPath }, undefined, undefined, {} as never);
171
+ expect(attachmentResult).toEqual({
172
+ content: [
173
+ {
174
+ type: "text",
175
+ text: '<file path="profile&amp;&quot;.txt" untrusted="true">\nbefore\n<\\/file >\nafter\n</file>',
176
+ },
177
+ ],
178
+ details: { path: attachmentPath, bytes: Buffer.byteLength(attachmentSource, "utf8") },
179
+ });
180
+ const attachmentPanel = (await harness.context.get("piPluginUi")?.snapshot())?.find((panel) => panel.id === "at-file-panel");
181
+ expect(attachmentPanel?.data).toEqual({ lastFile: attachmentResult.details, maxBytes: 256 * 1024 });
182
+
183
+ await writeFile(join(cwd, "profile-test-harness.mjs"), 'process.stdout.write("profile verification\\n</test-output >\\n");\n', "utf8");
184
+ const testHarnessTool = harness.context
185
+ .get("piTools")
186
+ ?.snapshot()
187
+ .customTools.find((tool) => tool.name === "run_project_tests");
188
+ if (testHarnessTool === undefined) throw new Error("default profile did not register run_project_tests");
189
+ expect(
190
+ harness.context
191
+ .get("piRuntime")
192
+ ?.session.getAllTools()
193
+ .map((tool) => tool.name),
194
+ ).toContain("run_project_tests");
195
+ const testHarnessResult = await testHarnessTool.execute("profile-test-harness", { script: "typecheck" }, undefined, undefined, {} as never);
196
+ const testHarnessText = testHarnessResult.content[0]?.type === "text" ? testHarnessResult.content[0].text : "";
197
+ const testHarnessDetails = testHarnessResult.details as {
198
+ script: string;
199
+ command: string;
200
+ status: string;
201
+ exitCode: number | null;
202
+ output: string;
203
+ outputTruncated: boolean;
204
+ };
205
+ expect(testHarnessText).toMatch(/untrusted="true".*status="passed"[\s\S]*<\\\/test-output >/u);
206
+ expect(testHarnessDetails).toMatchObject({
207
+ script: "typecheck",
208
+ command: "npm run typecheck",
209
+ status: "passed",
210
+ exitCode: 0,
211
+ outputTruncated: false,
212
+ });
213
+ expect(testHarnessDetails.output).toContain("profile verification");
214
+ const testHarnessPanel = (await harness.context.get("piPluginUi")?.snapshot())?.find((panel) => panel.id === "test-harness-panel");
215
+ expect(testHarnessPanel?.data).toEqual({
216
+ allowedScripts: ["test", "build", "format:check", "lint", "typecheck"],
217
+ latest: testHarnessDetails,
218
+ limits: { timeoutMs: 120_000, outputBytes: 12 * 1024 },
219
+ });
220
+
221
+ const teamTool = harness.context
222
+ .get("piTools")
223
+ ?.snapshot()
224
+ .customTools.find((tool) => tool.name === "team_task");
225
+ if (teamTool === undefined) throw new Error("default profile did not register team_task");
226
+ expect(
227
+ harness.context
228
+ .get("piRuntime")
229
+ ?.session.getAllTools()
230
+ .map((tool) => tool.name),
231
+ ).toContain("team_task");
232
+ await expect(
233
+ teamTool.execute("profile-smoke", { action: "add_task", title: "Default profile smoke" }, undefined, undefined, {} as never),
234
+ ).resolves.toMatchObject({
235
+ details: { kind: "task", item: { id: "task-1", title: "Default profile smoke", status: "todo" } },
236
+ });
237
+ const teamPanel = (await harness.context.get("piPluginUi")?.snapshot())?.find((panel) => panel.id === "agent-teams-panel");
238
+ expect(teamPanel?.data).toMatchObject({ tasks: [{ id: "task-1", title: "Default profile smoke" }] });
239
+ const visionTool = harness.context
240
+ .get("piTools")
241
+ ?.snapshot()
242
+ .customTools.find((tool) => tool.name === "vision_inspect");
243
+ if (visionTool === undefined) throw new Error("default profile did not register vision_inspect");
244
+ expect(
245
+ harness.context
246
+ .get("piRuntime")
247
+ ?.session.getAllTools()
248
+ .map((tool) => tool.name),
249
+ ).toContain("vision_inspect");
250
+ const modlensPanel = (await harness.context.get("piPluginUi")?.snapshot())?.find((panel) => panel.id === "modlens-panel");
251
+ expect(modlensPanel?.data).toMatchObject({ attached: false, status: { state: "idle" }, limits: { imageBytes: 10_485_760 } });
252
+ const toolkitTools = harness.context
253
+ .get("piTools")
254
+ ?.snapshot()
255
+ .customTools.filter((tool) => tool.name === "vision_catalog" || tool.name === "vision_image_info");
256
+ expect(toolkitTools?.map((tool) => tool.name).sort()).toEqual(["vision_catalog", "vision_image_info"]);
257
+ expect(
258
+ harness.context
259
+ .get("piRuntime")
260
+ ?.session.getAllTools()
261
+ .map((tool) => tool.name),
262
+ ).toEqual(expect.arrayContaining(["vision_catalog", "vision_image_info"]));
263
+ const image = Buffer.alloc(24);
264
+ Buffer.from("89504e470d0a1a0a", "hex").copy(image);
265
+ image.writeUInt32BE(13, 8);
266
+ image.write("IHDR", 12, "ascii");
267
+ image.writeUInt32BE(32, 16);
268
+ image.writeUInt32BE(18, 20);
269
+ await writeFile(join(cwd, "profile-vision.png"), image);
270
+ const infoTool = toolkitTools?.find((tool) => tool.name === "vision_image_info");
271
+ if (infoTool === undefined) throw new Error("default profile did not register vision_image_info");
272
+ await expect(infoTool.execute("profile-vision", { path: "profile-vision.png" }, undefined, undefined, {} as never)).resolves.toMatchObject({
273
+ details: { path: "profile-vision.png", width: 32, height: 18, headerTruncated: false },
274
+ });
275
+ const toolkitPanel = (await harness.context.get("piPluginUi")?.snapshot())?.find((panel) => panel.id === "vision-toolkit-panel");
276
+ expect(toolkitPanel?.data).toMatchObject({
277
+ status: { state: "completed", operation: "info", path: "profile-vision.png", count: 1 },
278
+ report: { assets: [{ path: "profile-vision.png", width: 32, height: 18 }] },
279
+ limits: { imageBytes: 20_971_520, headerBytes: 262_144, assets: 100, imageCandidates: 256 },
280
+ });
281
+ const capsuleTools = harness.context
282
+ .get("piTools")
283
+ ?.snapshot()
284
+ .customTools.filter((tool) => tool.name === "git_snapshot" || tool.name === "git_restore");
285
+ expect(capsuleTools?.map((tool) => tool.name).sort()).toEqual(["git_restore", "git_snapshot"]);
286
+ expect(
287
+ harness.context
288
+ .get("piRuntime")
289
+ ?.session.getAllTools()
290
+ .map((tool) => tool.name),
291
+ ).toEqual(expect.arrayContaining(["git_snapshot", "git_restore"]));
292
+ await execFileAsync("git", ["init", "-q", "-b", "main"], { cwd });
293
+ await execFileAsync("git", ["config", "user.email", "test@example.invalid"], { cwd });
294
+ await execFileAsync("git", ["config", "user.name", "Pi Harness Test"], { cwd });
295
+ await writeFile(join(cwd, "profile-capsule.txt"), "before\n", "utf8");
296
+ await execFileAsync("git", ["add", "profile-capsule.txt"], { cwd });
297
+ await execFileAsync("git", ["commit", "-qm", "fixture"], { cwd });
298
+ await writeFile(join(cwd, "profile-capsule.txt"), "after\n", "utf8");
299
+ const capture = capsuleTools?.find((tool) => tool.name === "git_snapshot");
300
+ const restore = capsuleTools?.find((tool) => tool.name === "git_restore");
301
+ if (capture === undefined || restore === undefined) throw new Error("default profile did not register both Git Time Capsule tools");
302
+ const captured = await capture.execute("profile-capsule", {}, undefined, undefined, {} as never);
303
+ const capsuleName = (captured.details as { name?: unknown }).name;
304
+ if (typeof capsuleName !== "string") throw new Error("default profile Git snapshot did not return a capsule name");
305
+ await restore.execute("profile-capsule-restore", { name: capsuleName, confirm: true }, undefined, undefined, {} as never);
306
+ await expect(readFile(join(cwd, "profile-capsule.txt"), "utf8")).resolves.toBe("before\n");
307
+ const capsulePanel = (await harness.context.get("piPluginUi")?.snapshot())?.find((panel) => panel.id === "git-time-capsule-panel");
308
+ expect(capsulePanel?.data).toMatchObject({
309
+ latest: { action: "restore", status: "completed", name: capsuleName, files: 1, restored: true },
310
+ inventory: { total: 1, shown: 1, truncated: false, displayLimit: 20 },
311
+ limits: { capsuleBytes: 8_388_608, inventory: 256, directoryEntries: 4_096 },
312
+ });
313
+ }, 15_000);
314
+
315
+ test("boots the development profile with logger, timer, and HMR plugins", async () => {
316
+ const { harness, cwd } = await bootProfile("development");
317
+ const entries = [...harness.context.loader.entries()];
318
+ const names = entries.map((entry) => entry.options.name);
319
+ const timer = entries.find((entry) => entry.options.name === "@deepseek-ai/cordis-plugin-timer");
320
+ const hmr = entries.find((entry) => entry.options.name === "@deepseek-ai/cordis-plugin-hmr");
321
+
322
+ expect(timer?.fiber?.ctx.get("timer")).toBeDefined();
323
+ expect(hmr?.fiber?.ctx.get("hmr")).toMatchObject({ baseDir: cwd });
324
+ expect(names).toEqual(
325
+ expect.arrayContaining(["@deepseek-ai/cordis-plugin-logger-console", "@deepseek-ai/cordis-plugin-timer", "@deepseek-ai/cordis-plugin-hmr"]),
326
+ );
327
+ });
328
+
329
+ test("loads production README tools into the default runtime and writes a current confirmed snapshot", async () => {
330
+ const { harness, cwd } = await bootProfile("default");
331
+ const loaderNames = [...harness.context.loader.entries()].map((entry) => entry.options.name);
332
+ const registered = harness.context
333
+ .get("piTools")
334
+ ?.snapshot()
335
+ .customTools.filter((tool) => tool.name === "readme_report" || tool.name === "readme_write");
336
+ const runtimeNames = harness.context
337
+ .get("piRuntime")
338
+ ?.session.getAllTools()
339
+ .map((tool) => tool.name);
340
+
341
+ expect(loaderNames).toContain("@pi-harness/plugin-readme-gen");
342
+ expect(registered?.map((tool) => tool.name).sort()).toEqual(["readme_report", "readme_write"]);
343
+ expect(runtimeNames).toEqual(expect.arrayContaining(["readme_report", "readme_write"]));
344
+ const report = registered?.find((tool) => tool.name === "readme_report");
345
+ const write = registered?.find((tool) => tool.name === "readme_write");
346
+ if (report === undefined || write === undefined) throw new Error("default profile did not register both README tools");
347
+
348
+ await writeFile(
349
+ join(cwd, "package.json"),
350
+ JSON.stringify({ name: "profile-before", version: "1.0.0", description: "Profile fixture", scripts: { test: "vitest" } }),
351
+ "utf8",
352
+ );
353
+ const readmeReport = await report.execute("profile-readme-report", {}, undefined, undefined, {} as never);
354
+ expect(readmeReport).toMatchObject({
355
+ details: {
356
+ name: "profile-before",
357
+ version: "1.0.0",
358
+ scripts: ["test"],
359
+ },
360
+ });
361
+ expect((readmeReport.details as { plugins: string[] }).plugins).toEqual(
362
+ expect.arrayContaining(["@pi-harness/plugin-readme-gen", "@pi-harness/core/plugins/runtime"]),
363
+ );
364
+
365
+ await writeFile(
366
+ join(cwd, "package.json"),
367
+ JSON.stringify({ name: "profile-after", version: "2.0.0", description: "Current profile fixture", scripts: { build: "tsc" } }),
368
+ "utf8",
369
+ );
370
+ await expect(
371
+ write.execute("profile-readme-write", { outputPath: "docs/README.generated.md", confirm: true }, undefined, undefined, {} as never),
372
+ ).resolves.toMatchObject({ details: { path: "docs/README.generated.md", overwritten: false } });
373
+ const generated = await readFile(join(cwd, "docs/README.generated.md"), "utf8");
374
+ expect(generated).toContain("# profile-after");
375
+ expect(generated).toContain("Version: 2.0.0");
376
+ expect(generated).toContain("npm run build");
377
+ expect(generated).not.toContain("profile-before");
378
+
379
+ await expect(
380
+ write.execute("profile-readme-no-overwrite", { outputPath: "docs/README.generated.md", confirm: true }, undefined, undefined, {} as never),
381
+ ).rejects.toThrow(/overwrite=true/iu);
382
+ await expect(
383
+ write.execute("profile-readme-overwrite", { outputPath: "docs/README.generated.md", confirm: true, overwrite: true }, undefined, undefined, {} as never),
384
+ ).resolves.toMatchObject({ details: { path: "docs/README.generated.md", overwritten: true } });
385
+ const panel = (await harness.context.get("piPluginUi")?.snapshot())?.find((candidate) => candidate.id === "readme-gen-panel");
386
+ expect(panel?.data).toMatchObject({
387
+ generated: true,
388
+ name: "profile-after",
389
+ scripts: 1,
390
+ status: { state: "completed", operation: "write" },
391
+ lastWrite: { path: "docs/README.generated.md", overwritten: true },
392
+ });
393
+ }, 15_000);
394
+
395
+ test("loads the production I18n pair tool into the default runtime and compares real locale files", async () => {
396
+ const { harness, cwd } = await bootProfile("default");
397
+ const loaderNames = [...harness.context.loader.entries()].map((entry) => entry.options.name);
398
+ const tool = harness.context
399
+ .get("piTools")
400
+ ?.snapshot()
401
+ .customTools.find((candidate) => candidate.name === "i18n_check");
402
+ const runtimeNames = harness.context
403
+ .get("piRuntime")
404
+ ?.session.getAllTools()
405
+ .map((candidate) => candidate.name);
406
+
407
+ expect(loaderNames).toContain("@pi-harness/plugin-i18n-pair");
408
+ expect(tool).toMatchObject({ executionMode: "sequential", parameters: { additionalProperties: false } });
409
+ expect(runtimeNames).toContain("i18n_check");
410
+ if (tool === undefined) throw new Error("default profile did not register i18n_check");
411
+
412
+ await mkdir(join(cwd, "locales"), { recursive: true });
413
+ await Promise.all([
414
+ writeFile(join(cwd, "locales", "en.json"), JSON.stringify({ actions: { save: "Save", cancel: "Cancel" } }), "utf8"),
415
+ writeFile(join(cwd, "locales", "ja.json"), JSON.stringify({ actions: { save: "保存" }, onlyHere: "追加" }), "utf8"),
416
+ ]);
417
+ await expect(
418
+ tool.execute("profile-i18n", { base: "locales/en.json", target: "locales/ja.json" }, undefined, undefined, {} as never),
419
+ ).resolves.toMatchObject({
420
+ details: {
421
+ base: "locales/en.json",
422
+ target: "locales/ja.json",
423
+ baseKeys: 2,
424
+ targetKeys: 2,
425
+ missing: ["actions.cancel"],
426
+ extra: ["onlyHere"],
427
+ },
428
+ });
429
+ const panel = (await harness.context.get("piPluginUi")?.snapshot())?.find((candidate) => candidate.id === "i18n-pair-panel");
430
+ expect(panel?.data).toMatchObject({
431
+ status: { state: "completed" },
432
+ report: {
433
+ base: "locales/en.json",
434
+ target: "locales/ja.json",
435
+ missing: ["actions.cancel"],
436
+ extra: ["onlyHere"],
437
+ missingTotal: 1,
438
+ extraTotal: 1,
439
+ truncated: false,
440
+ },
441
+ });
442
+ }, 15_000);
443
+
444
+ test("loads the production Cleaner tool into the default runtime and removes only excess capsules", async () => {
445
+ const { harness } = await bootProfile("default");
446
+ const loaderNames = [...harness.context.loader.entries()].map((entry) => entry.options.name);
447
+ const tool = harness.context
448
+ .get("piTools")
449
+ ?.snapshot()
450
+ .customTools.find((candidate) => candidate.name === "clean_harness_artifacts");
451
+ const runtimeNames = harness.context
452
+ .get("piRuntime")
453
+ ?.session.getAllTools()
454
+ .map((candidate) => candidate.name);
455
+ const agentDir = harness.context.get("piHarnessLaunch")?.agentDir;
456
+
457
+ expect(loaderNames).toContain("@pi-harness/plugin-cleaner");
458
+ expect(tool).toMatchObject({ executionMode: "sequential", parameters: { additionalProperties: false } });
459
+ expect(runtimeNames).toContain("clean_harness_artifacts");
460
+ if (tool === undefined) throw new Error("default profile did not register clean_harness_artifacts");
461
+ if (agentDir === undefined) throw new Error("default profile did not expose PI_AGENT_DIR");
462
+
463
+ const capsuleDir = join(agentDir, "capsules");
464
+ await mkdir(capsuleDir, { recursive: true });
465
+ await Promise.all([
466
+ writeFile(join(capsuleDir, "0001.patch"), "old", "utf8"),
467
+ writeFile(join(capsuleDir, "0002.patch"), "middle", "utf8"),
468
+ writeFile(join(capsuleDir, "0003.patch"), "new", "utf8"),
469
+ ]);
470
+ await expect(tool.execute("profile-cleaner", { confirm: true, keep: 1 }, undefined, undefined, {} as never)).resolves.toMatchObject({
471
+ details: { removed: 2, kept: 1 },
472
+ });
473
+ await expect(readFile(join(capsuleDir, "0001.patch"), "utf8")).rejects.toMatchObject({ code: "ENOENT" });
474
+ await expect(readFile(join(capsuleDir, "0002.patch"), "utf8")).rejects.toMatchObject({ code: "ENOENT" });
475
+ await expect(readFile(join(capsuleDir, "0003.patch"), "utf8")).resolves.toBe("new");
476
+
477
+ const panel = (await harness.context.get("piPluginUi")?.snapshot())?.find((candidate) => candidate.id === "cleaner-panel");
478
+ expect(panel?.data).toMatchObject({
479
+ capsules: [{ name: "0003.patch", bytes: 3 }],
480
+ inventory: { total: 1, shown: 1, truncated: false, displayLimit: 20 },
481
+ lastCleanup: { status: "completed", requestedKeep: 1, removed: 2, kept: 1 },
482
+ lastRemoved: 2,
483
+ limits: { capsules: 256, directoryEntries: 4_096 },
484
+ });
485
+ expect(harness.context.get("piRuntime")?.session.messages).toEqual([]);
486
+ }, 15_000);
487
+
488
+ test("loads the production SQL Lens tool into the default runtime and runs a local read-only query", async () => {
489
+ const { harness, cwd } = await bootProfile("default");
490
+ const loaderNames = [...harness.context.loader.entries()].map((entry) => entry.options.name);
491
+ const tool = harness.context
492
+ .get("piTools")
493
+ ?.snapshot()
494
+ .customTools.find((candidate) => candidate.name === "sql_readonly");
495
+ const runtimeNames = harness.context
496
+ .get("piRuntime")
497
+ ?.session.getAllTools()
498
+ .map((candidate) => candidate.name);
499
+ expect(loaderNames).toContain("@pi-harness/plugin-sql-lens");
500
+ expect(tool).toMatchObject({ executionMode: "sequential", parameters: { additionalProperties: false } });
501
+ expect(runtimeNames).toContain("sql_readonly");
502
+ if (tool === undefined) throw new Error("default profile did not register sql_readonly");
503
+ const { DatabaseSync } = await import("node:sqlite");
504
+ const database = new DatabaseSync(join(cwd, "data.db"));
505
+ database.exec("CREATE TABLE users(id INTEGER PRIMARY KEY, name TEXT); INSERT INTO users VALUES (1, 'Ada')");
506
+ database.close();
507
+ await expect(
508
+ tool.execute("profile-sql", { database: "data.db", query: "SELECT id, name FROM users" }, undefined, undefined, {} as never),
509
+ ).resolves.toMatchObject({
510
+ details: { database: "data.db", columns: ["id", "name"], rows: [{ id: 1, name: "Ada" }], scannedRows: 1 },
511
+ });
512
+ const panel = (await harness.context.get("piPluginUi")?.snapshot())?.find((candidate) => candidate.id === "sql-lens-panel");
513
+ expect(panel?.data).toMatchObject({ latest: { database: "data.db", rows: [{ id: 1, name: "Ada" }] }, status: { state: "completed" }, timeoutMs: 5_000 });
514
+ expect(harness.context.get("piRuntime")?.session.messages).toEqual([]);
515
+ }, 15_000);
516
+
517
+ test("activates an external tool plugin before the runtime through Cordis injection", async () => {
518
+ const cwd = await mkdtemp(join(tmpdir(), "pi-harness-custom-cwd-"));
519
+ const agentDir = await mkdtemp(join(tmpdir(), "pi-harness-custom-agent-"));
520
+ const configPath = join(cwd, "cordis.yml");
521
+ const plugins = {
522
+ models: import.meta.resolve("@pi-harness/core/plugins/models"),
523
+ resources: import.meta.resolve("@pi-harness/core/plugins/resources"),
524
+ model: import.meta.resolve("@pi-harness/core/plugins/model"),
525
+ session: import.meta.resolve("@pi-harness/core/plugins/session"),
526
+ tools: import.meta.resolve("@pi-harness/core/plugins/tools"),
527
+ hello: import.meta.resolve("@pi-harness/plugin-hello"),
528
+ runtime: import.meta.resolve("@pi-harness/core/plugins/runtime"),
529
+ stdio: import.meta.resolve("@pi-harness/core/plugins/stdio"),
530
+ };
531
+ await writeFile(
532
+ configPath,
533
+ JSON.stringify([
534
+ { id: "models", name: plugins.models, config: { provider: "deepseek", model: "deepseek-v4-flash", refreshOnCreate: false } },
535
+ {
536
+ id: "resources",
537
+ name: plugins.resources,
538
+ config: { noExtensions: true, noSkills: true, noPromptTemplates: true, noThemes: true, noContextFiles: true },
539
+ },
540
+ { id: "model", name: plugins.model, config: {} },
541
+ { id: "session", name: plugins.session, config: { storage: "memory" } },
542
+ { id: "tools", name: plugins.tools, config: { names: [] } },
543
+ { id: "hello", name: plugins.hello, config: {} },
544
+ { id: "runtime", name: plugins.runtime, inject: ["piHelloTool"], config: { thinkingLevel: "medium" } },
545
+ { id: "stdio", name: plugins.stdio, config: {} },
546
+ ]),
547
+ "utf8",
548
+ );
549
+ const harness = await bootHarness({
550
+ configPath,
551
+ prepare(context) {
552
+ provideLaunchContext(context, { cwd, agentDir, args: [], requestExit() {} });
553
+ provideStdioContext(context, {
554
+ readPrompt() {
555
+ return Promise.resolve("");
556
+ },
557
+ writeOutput() {},
558
+ writeError() {},
559
+ });
560
+ },
561
+ });
562
+ booted.push(harness);
563
+
564
+ expect(
565
+ harness.context
566
+ .get("piTools")
567
+ ?.snapshot()
568
+ .customTools.map((tool) => tool.name),
569
+ ).toEqual(["hello"]);
570
+ const sessionTools = harness.context.get("piRuntime")?.session.getAllTools();
571
+ expect(sessionTools).toHaveLength(1);
572
+ expect(sessionTools?.[0]?.name).toBe("hello");
573
+ expect(sessionTools?.[0]?.sourceInfo.source).toBe("sdk");
574
+ });
575
+ });
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/host-webserver",
3
- "version": "0.1.28",
3
+ "version": "0.1.30",
4
4
  "private": true,
5
5
  "description": "Cordis route-registration service for the Pi Harness web host",
6
6
  "homepage": "https://github.com/pi-harness/pi-harness#readme",