testeiya 0.2.1 → 0.3.1-5.1

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 (405) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +325 -171
  3. package/dist/prompt/context.js +79 -0
  4. package/dist/prompt/context.js.map +1 -0
  5. package/dist/prompt/index.js +60 -0
  6. package/dist/prompt/index.js.map +1 -0
  7. package/dist/prompt/print.js +30 -0
  8. package/dist/prompt/print.js.map +1 -0
  9. package/dist/prompt/project-info.js +2 -0
  10. package/dist/prompt/project-info.js.map +1 -0
  11. package/{src/prompt/system-prompt.ts → dist/prompt/system-prompt.js} +38 -25
  12. package/dist/prompt/system-prompt.js.map +1 -0
  13. package/dist/prompt/testomatio.js +264 -0
  14. package/dist/prompt/testomatio.js.map +1 -0
  15. package/dist/prompt/tools.js +70 -0
  16. package/dist/prompt/tools.js.map +1 -0
  17. package/dist/prompt/vocab.js +8 -0
  18. package/dist/prompt/vocab.js.map +1 -0
  19. package/dist/src/args.js +224 -0
  20. package/dist/src/args.js.map +1 -0
  21. package/dist/src/cli.js +105 -0
  22. package/dist/src/cli.js.map +1 -0
  23. package/dist/src/doctor.js +171 -0
  24. package/dist/src/doctor.js.map +1 -0
  25. package/dist/src/env.js +103 -0
  26. package/dist/src/env.js.map +1 -0
  27. package/dist/src/mcp-extension.js +9 -0
  28. package/dist/src/mcp-extension.js.map +1 -0
  29. package/dist/src/mcp.js +139 -0
  30. package/dist/src/mcp.js.map +1 -0
  31. package/dist/src/model.js +71 -0
  32. package/dist/src/model.js.map +1 -0
  33. package/dist/src/models.js +38 -0
  34. package/dist/src/models.js.map +1 -0
  35. package/dist/src/output.js +216 -0
  36. package/dist/src/output.js.map +1 -0
  37. package/dist/src/result.js +41 -0
  38. package/dist/src/result.js.map +1 -0
  39. package/dist/src/run.js +313 -0
  40. package/dist/src/run.js.map +1 -0
  41. package/dist/src/session.js +98 -0
  42. package/dist/src/session.js.map +1 -0
  43. package/dist/src/sessions.js +72 -0
  44. package/dist/src/sessions.js.map +1 -0
  45. package/dist/src/skills.js +130 -0
  46. package/dist/src/skills.js.map +1 -0
  47. package/dist/vendor/mcp.js +14801 -0
  48. package/mcp-tools.json +2967 -0
  49. package/package.json +34 -43
  50. package/prompt/context.ts +101 -0
  51. package/prompt/index.ts +102 -0
  52. package/prompt/print.ts +32 -0
  53. package/prompt/project-info.ts +30 -0
  54. package/prompt/system-prompt.ts +187 -0
  55. package/{src/prompt → prompt}/testomatio.ts +120 -9
  56. package/prompt/tools.ts +72 -0
  57. package/prompt/vocab.ts +7 -0
  58. package/skills/codeceptjs/ci-fix-tests/SKILL.md +7 -8
  59. package/skills/codeceptjs/codeceptjs-auth/SKILL.md +47 -64
  60. package/skills/codeceptjs/codeceptjs-exploration/SKILL.md +56 -47
  61. package/skills/codeceptjs/codeceptjs-fundamentals/SKILL.md +144 -106
  62. package/skills/codeceptjs/codeceptjs-run-analysis/SKILL.md +50 -57
  63. package/skills/codeceptjs/debugging-codeceptjs-tests/SKILL.md +88 -196
  64. package/skills/codeceptjs/migrate-codeceptjs-4/SKILL.md +4 -5
  65. package/skills/codeceptjs/migrate-cypress-to-codeceptjs/SKILL.md +25 -36
  66. package/skills/codeceptjs/migrate-protractor-to-codeceptjs/SKILL.md +23 -36
  67. package/skills/codeceptjs/migrate-selenium-java-to-codeceptjs/SKILL.md +23 -36
  68. package/skills/codeceptjs/migrate-testcafe-to-codeceptjs/SKILL.md +23 -35
  69. package/skills/codeceptjs/refactoring-codeceptjs-tests/SKILL.md +50 -53
  70. package/skills/codeceptjs/writing-codeceptjs-tests/SKILL.md +87 -191
  71. package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/SKILL.md +1 -1
  72. package/{skills.lock.json → skills/skills.lock.json} +45 -37
  73. package/skills/skills.yaml +35 -0
  74. package/skills/testomatio/explorbot/explorbot-fundamentals/SKILL.md +49 -61
  75. package/skills/testomatio/explorbot/explorbot-fundamentals/references/no-install.md +36 -0
  76. package/skills/testomatio/explorbot/explorbot-plan/SKILL.md +20 -7
  77. package/skills/testomatio/explorbot/explorbot-setup/SKILL.md +41 -289
  78. package/skills/testomatio/explorbot/prima/SKILL.md +87 -0
  79. package/skills/testomatio/qa-process/qa-explain-behavior/SKILL.md +111 -0
  80. package/skills/testomatio/qa-process/qa-explain-behavior/references/answer-shapes.md +116 -0
  81. package/skills/testomatio/qa-process/qa-explain-behavior/references/examples.md +157 -0
  82. package/skills/testomatio/qa-process/qa-lead-strategy-advisor/SKILL.md +91 -0
  83. package/skills/testomatio/qa-process/qa-lead-strategy-advisor/references/output-format.md +71 -0
  84. package/skills/testomatio/qa-process/testing-workflow/SKILL.md +227 -0
  85. package/skills/testomatio/test-automation/qa-data-seeder/SKILL.md +83 -0
  86. package/skills/testomatio/test-automation/run-tests-with-testomatio-reporter/SKILL.md +5 -3
  87. package/skills/testomatio/test-automation/setup-change-aware-pr-testing/SKILL.md +190 -0
  88. package/skills/testomatio/test-automation/setup-ci-automation/SKILL.md +76 -0
  89. package/skills/testomatio/test-management/qa-split-testing-levels-pyramid/SKILL.md +55 -0
  90. package/skills/testomatio/test-management/qa-sprint-report-by-testomatio/SKILL.md +220 -0
  91. package/skills/testomatio/test-management/qa-sprint-report-by-testomatio/references/qa-sprint-report.md +126 -0
  92. package/skills/testomatio/test-management/qa-test-code-coverage/SKILL.md +1 -1
  93. package/skills/testomatio/test-management/qa-thinking/SKILL.md +25 -25
  94. package/skills/testomatio/test-management/testomatio-mcp/SKILL.md +14 -1
  95. package/skills/testomatio/test-management/testomatio-mcp/references/MCP_SETUP.md +8 -0
  96. package/assets/testeiya-logo-dark.svg +0 -16
  97. package/assets/testeiya-logo.svg +0 -15
  98. package/models.catalog.json +0 -6963
  99. package/skills/playwright-best-practices-skill/LICENSE.md +0 -7
  100. package/skills/playwright-best-practices-skill/README.md +0 -147
  101. package/skills/testeiya/README.md +0 -29
  102. package/skills/testeiya/answer-formatting/SKILL.md +0 -30
  103. package/skills/testeiya/check-cucumber/SKILL.md +0 -200
  104. package/skills/testeiya/check-tests/SKILL.md +0 -260
  105. package/skills/testeiya/manual-run-assistant/SKILL.md +0 -61
  106. package/skills/testeiya/testomatio-docs/INDEX.md +0 -175
  107. package/skills/testeiya/testomatio-docs/SKILL.md +0 -102
  108. package/skills/testeiya/testomatio-docs/docs/advanced/ai-powered-features/ai-agents.md +0 -144
  109. package/skills/testeiya/testomatio-docs/docs/advanced/ai-powered-features/ai-powered-features.md +0 -531
  110. package/skills/testeiya/testomatio-docs/docs/advanced/ai-powered-features/ai-requirements.md +0 -437
  111. package/skills/testeiya/testomatio-docs/docs/advanced/api-access/index.md +0 -191
  112. package/skills/testeiya/testomatio-docs/docs/advanced/branches-folder/index.md +0 -277
  113. package/skills/testeiya/testomatio-docs/docs/advanced/bulk-edit-folder/bulk-edit-demos.mdx +0 -39
  114. package/skills/testeiya/testomatio-docs/docs/advanced/bulk-edit-folder/bulk-edit-on-suite-and-test-level.md +0 -122
  115. package/skills/testeiya/testomatio-docs/docs/advanced/bulk-edit-folder/what-is-bulk-edit.md +0 -170
  116. package/skills/testeiya/testomatio-docs/docs/advanced/jira-plugin/branches.md +0 -53
  117. package/skills/testeiya/testomatio-docs/docs/advanced/jira-plugin/index.mdx +0 -98
  118. package/skills/testeiya/testomatio-docs/docs/advanced/jira-plugin/jira-issue.md +0 -151
  119. package/skills/testeiya/testomatio-docs/docs/advanced/jira-plugin/runs-and-reports.md +0 -377
  120. package/skills/testeiya/testomatio-docs/docs/advanced/jira-plugin/work-in-jira.md +0 -267
  121. package/skills/testeiya/testomatio-docs/docs/advanced/living-doc/index.md +0 -138
  122. package/skills/testeiya/testomatio-docs/docs/advanced/milestones/index.md +0 -220
  123. package/skills/testeiya/testomatio-docs/docs/advanced/shortcuts/index.md +0 -48
  124. package/skills/testeiya/testomatio-docs/docs/advanced/tags-labels/labels-and-custom-fields.md +0 -201
  125. package/skills/testeiya/testomatio-docs/docs/advanced/tags-labels/tags-or-labels.md +0 -94
  126. package/skills/testeiya/testomatio-docs/docs/advanced/tags-labels/tags.md +0 -243
  127. package/skills/testeiya/testomatio-docs/docs/advanced/test-artifacts/index.md +0 -135
  128. package/skills/testeiya/testomatio-docs/docs/advanced/tql/index.md +0 -394
  129. package/skills/testeiya/testomatio-docs/docs/getting-started/index.md +0 -290
  130. package/skills/testeiya/testomatio-docs/docs/integrations/continuous-integration/azure.md +0 -96
  131. package/skills/testeiya/testomatio-docs/docs/integrations/continuous-integration/bamboo.md +0 -94
  132. package/skills/testeiya/testomatio-docs/docs/integrations/continuous-integration/bitbucket.md +0 -106
  133. package/skills/testeiya/testomatio-docs/docs/integrations/continuous-integration/circle.md +0 -115
  134. package/skills/testeiya/testomatio-docs/docs/integrations/continuous-integration/github.md +0 -120
  135. package/skills/testeiya/testomatio-docs/docs/integrations/continuous-integration/gitlab.md +0 -88
  136. package/skills/testeiya/testomatio-docs/docs/integrations/continuous-integration/index.mdx +0 -151
  137. package/skills/testeiya/testomatio-docs/docs/integrations/continuous-integration/jenkins.md +0 -121
  138. package/skills/testeiya/testomatio-docs/docs/integrations/continuous-integration/teamcity.md +0 -96
  139. package/skills/testeiya/testomatio-docs/docs/integrations/issues-management/azure.md +0 -31
  140. package/skills/testeiya/testomatio-docs/docs/integrations/issues-management/clickup.md +0 -54
  141. package/skills/testeiya/testomatio-docs/docs/integrations/issues-management/confluence.md +0 -34
  142. package/skills/testeiya/testomatio-docs/docs/integrations/issues-management/github.md +0 -31
  143. package/skills/testeiya/testomatio-docs/docs/integrations/issues-management/gitlab.md +0 -93
  144. package/skills/testeiya/testomatio-docs/docs/integrations/issues-management/index.md +0 -131
  145. package/skills/testeiya/testomatio-docs/docs/integrations/issues-management/jira.md +0 -164
  146. package/skills/testeiya/testomatio-docs/docs/integrations/issues-management/linear.md +0 -29
  147. package/skills/testeiya/testomatio-docs/docs/integrations/issues-management/shortcut.md +0 -67
  148. package/skills/testeiya/testomatio-docs/docs/integrations/issues-management/youtrack.md +0 -94
  149. package/skills/testeiya/testomatio-docs/docs/integrations/report-notifications/azure-devops.md +0 -53
  150. package/skills/testeiya/testomatio-docs/docs/integrations/report-notifications/email.md +0 -71
  151. package/skills/testeiya/testomatio-docs/docs/integrations/report-notifications/jira.md +0 -52
  152. package/skills/testeiya/testomatio-docs/docs/integrations/report-notifications/ms-teams.md +0 -60
  153. package/skills/testeiya/testomatio-docs/docs/integrations/report-notifications/rules.md +0 -267
  154. package/skills/testeiya/testomatio-docs/docs/integrations/report-notifications/slack.md +0 -82
  155. package/skills/testeiya/testomatio-docs/docs/integrations/report-notifications/telegram.md +0 -73
  156. package/skills/testeiya/testomatio-docs/docs/integrations/scim-provisioning/index.mdx +0 -207
  157. package/skills/testeiya/testomatio-docs/docs/integrations/scim-provisioning/okta.md +0 -204
  158. package/skills/testeiya/testomatio-docs/docs/integrations/single-sign-on/azure.md +0 -95
  159. package/skills/testeiya/testomatio-docs/docs/integrations/single-sign-on/google.md +0 -75
  160. package/skills/testeiya/testomatio-docs/docs/integrations/single-sign-on/index.mdx +0 -33
  161. package/skills/testeiya/testomatio-docs/docs/integrations/single-sign-on/okta.md +0 -108
  162. package/skills/testeiya/testomatio-docs/docs/integrations/single-sign-on/saml.md +0 -66
  163. package/skills/testeiya/testomatio-docs/docs/legal/compliance/gdpr.md +0 -95
  164. package/skills/testeiya/testomatio-docs/docs/legal/compliance/index.mdx +0 -94
  165. package/skills/testeiya/testomatio-docs/docs/legal/compliance/privacy.md +0 -26
  166. package/skills/testeiya/testomatio-docs/docs/legal/compliance/terms.md +0 -32
  167. package/skills/testeiya/testomatio-docs/docs/legal/security/index.mdx +0 -242
  168. package/skills/testeiya/testomatio-docs/docs/legal/security/jira.md +0 -140
  169. package/skills/testeiya/testomatio-docs/docs/legal/security/subprocessors.md +0 -76
  170. package/skills/testeiya/testomatio-docs/docs/management/company/administration.md +0 -363
  171. package/skills/testeiya/testomatio-docs/docs/management/company/audit-log.md +0 -41
  172. package/skills/testeiya/testomatio-docs/docs/management/company/plan-features-comparison.md +0 -240
  173. package/skills/testeiya/testomatio-docs/docs/management/company/subscriptions.md +0 -326
  174. package/skills/testeiya/testomatio-docs/docs/management/company/trials.md +0 -75
  175. package/skills/testeiya/testomatio-docs/docs/management/company/users-and-permissions/accountant.md +0 -49
  176. package/skills/testeiya/testomatio-docs/docs/management/company/users-and-permissions/index.mdx +0 -285
  177. package/skills/testeiya/testomatio-docs/docs/management/company/users-and-permissions/read-only-user.md +0 -67
  178. package/skills/testeiya/testomatio-docs/docs/management/company/users-and-permissions/teams.md +0 -138
  179. package/skills/testeiya/testomatio-docs/docs/management/project/settings.md +0 -87
  180. package/skills/testeiya/testomatio-docs/docs/management/project/templates.md +0 -546
  181. package/skills/testeiya/testomatio-docs/docs/project/analytics/index.md +0 -326
  182. package/skills/testeiya/testomatio-docs/docs/project/import-export/export-tests/classical-tests-markdown-format.md +0 -386
  183. package/skills/testeiya/testomatio-docs/docs/project/import-export/export-tests/download-manual-tests-as-files.md +0 -378
  184. package/skills/testeiya/testomatio-docs/docs/project/import-export/export-tests/export-to-obsidian.md +0 -112
  185. package/skills/testeiya/testomatio-docs/docs/project/import-export/export-tests/export-to-spreadsheet.md +0 -127
  186. package/skills/testeiya/testomatio-docs/docs/project/import-export/import/auto-import.md +0 -63
  187. package/skills/testeiya/testomatio-docs/docs/project/import-export/import/import-tests-from-Allure-TestOps.md +0 -49
  188. package/skills/testeiya/testomatio-docs/docs/project/import-export/import/import-tests-from-QTest.md +0 -41
  189. package/skills/testeiya/testomatio-docs/docs/project/import-export/import/import-tests-from-Qase.md +0 -39
  190. package/skills/testeiya/testomatio-docs/docs/project/import-export/import/import-tests-from-Zephyr.md +0 -37
  191. package/skills/testeiya/testomatio-docs/docs/project/import-export/import/import-tests-from-csv-xlsx.md +0 -117
  192. package/skills/testeiya/testomatio-docs/docs/project/import-export/import/import-tests-from-cucumber.md +0 -93
  193. package/skills/testeiya/testomatio-docs/docs/project/import-export/import/import-tests-from-qmetry.md +0 -44
  194. package/skills/testeiya/testomatio-docs/docs/project/import-export/import/import-tests-from-source-code.md +0 -117
  195. package/skills/testeiya/testomatio-docs/docs/project/import-export/import/import-tests-from-testcaselabs.md +0 -44
  196. package/skills/testeiya/testomatio-docs/docs/project/import-export/import/import-tests-from-testmo.md +0 -47
  197. package/skills/testeiya/testomatio-docs/docs/project/import-export/import/import-tests-from-testrail.md +0 -82
  198. package/skills/testeiya/testomatio-docs/docs/project/import-export/import/import-tests-from-xray.md +0 -55
  199. package/skills/testeiya/testomatio-docs/docs/project/plans/index.md +0 -334
  200. package/skills/testeiya/testomatio-docs/docs/project/pulse/index.md +0 -104
  201. package/skills/testeiya/testomatio-docs/docs/project/runs/archive-runs-and-groups.md +0 -176
  202. package/skills/testeiya/testomatio-docs/docs/project/runs/custom-statuses.md +0 -195
  203. package/skills/testeiya/testomatio-docs/docs/project/runs/environments.md +0 -203
  204. package/skills/testeiya/testomatio-docs/docs/project/runs/managing-runs.md +0 -455
  205. package/skills/testeiya/testomatio-docs/docs/project/runs/merge-strategies.md +0 -137
  206. package/skills/testeiya/testomatio-docs/docs/project/runs/reports.md +0 -329
  207. package/skills/testeiya/testomatio-docs/docs/project/runs/rungroups.md +0 -342
  208. package/skills/testeiya/testomatio-docs/docs/project/runs/running-automated-tests.md +0 -256
  209. package/skills/testeiya/testomatio-docs/docs/project/runs/running-manual-and-automated-tests.md +0 -331
  210. package/skills/testeiya/testomatio-docs/docs/project/runs/running-tests-manually.md +0 -633
  211. package/skills/testeiya/testomatio-docs/docs/project/runs/temporary-tests-notes.md +0 -223
  212. package/skills/testeiya/testomatio-docs/docs/project/steps-snippets/snippets.md +0 -68
  213. package/skills/testeiya/testomatio-docs/docs/project/steps-snippets/steps.md +0 -181
  214. package/skills/testeiya/testomatio-docs/docs/project/tests/bdd-test-case-editor.md +0 -98
  215. package/skills/testeiya/testomatio-docs/docs/project/tests/classical-test-case-editor.md +0 -354
  216. package/skills/testeiya/testomatio-docs/docs/project/tests/classical-vs-bdd.md +0 -169
  217. package/skills/testeiya/testomatio-docs/docs/project/tests/copy-and-move-your-tests.md +0 -156
  218. package/skills/testeiya/testomatio-docs/docs/project/tests/other-features-for-test-case-design.md +0 -412
  219. package/skills/testeiya/testomatio-docs/docs/project/tests/test-case-creation-and-editing.md +0 -527
  220. package/skills/testeiya/testomatio-docs/docs/support/index.md +0 -75
  221. package/skills/testeiya/testomatio-docs/docs/test-reporting/artifacts.md +0 -388
  222. package/skills/testeiya/testomatio-docs/docs/test-reporting/cli.md +0 -215
  223. package/skills/testeiya/testomatio-docs/docs/test-reporting/configuration.md +0 -247
  224. package/skills/testeiya/testomatio-docs/docs/test-reporting/frameworks.md +0 -490
  225. package/skills/testeiya/testomatio-docs/docs/test-reporting/functions.md +0 -144
  226. package/skills/testeiya/testomatio-docs/docs/test-reporting/index.mdx +0 -48
  227. package/skills/testeiya/testomatio-docs/docs/test-reporting/junit.md +0 -248
  228. package/skills/testeiya/testomatio-docs/docs/test-reporting/logger.md +0 -138
  229. package/skills/testeiya/testomatio-docs/docs/test-reporting/php.md +0 -77
  230. package/skills/testeiya/testomatio-docs/docs/test-reporting/pipes/bitbucket.md +0 -72
  231. package/skills/testeiya/testomatio-docs/docs/test-reporting/pipes/csv.md +0 -23
  232. package/skills/testeiya/testomatio-docs/docs/test-reporting/pipes/debug.md +0 -18
  233. package/skills/testeiya/testomatio-docs/docs/test-reporting/pipes/github.md +0 -63
  234. package/skills/testeiya/testomatio-docs/docs/test-reporting/pipes/gitlab.md +0 -29
  235. package/skills/testeiya/testomatio-docs/docs/test-reporting/pipes/html.md +0 -80
  236. package/skills/testeiya/testomatio-docs/docs/test-reporting/pipes/index.mdx +0 -57
  237. package/skills/testeiya/testomatio-docs/docs/test-reporting/pipes/testomatio.md +0 -331
  238. package/skills/testeiya/testomatio-docs/docs/test-reporting/python.md +0 -229
  239. package/skills/testeiya/testomatio-docs/docs/test-reporting/workflows.md +0 -325
  240. package/skills/testeiya/testomatio-docs/docs/tutorials/Interacting-via-API.md +0 -159
  241. package/skills/testeiya/testomatio-docs/docs/tutorials/Manual-Testing-Classic.md +0 -164
  242. package/skills/testeiya/testomatio-docs/docs/tutorials/Set-Up-Read-Only-Access.md +0 -85
  243. package/skills/testeiya/testomatio-docs/docs/tutorials/Using-AI-in-Testing.md +0 -163
  244. package/skills/testeiya/testomatio-docs/docs/tutorials/Working-with-Jira.md +0 -125
  245. package/skills/testeiya/testomatio-docs/docs/tutorials/java.md +0 -478
  246. package/skills/testeiya/testomatio-docs/docs/tutorials/playwright.md +0 -207
  247. package/skills/testeiya/testomatio-docs/docs/tutorials/webdriver.md +0 -218
  248. package/skills/testeiya/testomatio-docs/docs.lock.json +0 -6
  249. package/skills/testeiya/testomatio-reporter/SKILL.md +0 -307
  250. package/skills/testomatio/test-automation/setup-pr-testing/SKILL.md +0 -199
  251. package/skills.yaml +0 -21
  252. package/src/ai-debug.ts +0 -188
  253. package/src/api/agent-get.ts +0 -22
  254. package/src/api/agent-start.ts +0 -384
  255. package/src/api/client-log.ts +0 -29
  256. package/src/api/context.ts +0 -332
  257. package/src/api/debug-layout.ts +0 -47
  258. package/src/api/debug-report.ts +0 -29
  259. package/src/api/debug-snapshot.ts +0 -30
  260. package/src/api/debug-stream.ts +0 -52
  261. package/src/api/files-delete.ts +0 -184
  262. package/src/api/files-read.ts +0 -41
  263. package/src/api/files-rename.ts +0 -99
  264. package/src/api/files-tree.ts +0 -292
  265. package/src/api/files-write.ts +0 -41
  266. package/src/api/mcp.ts +0 -603
  267. package/src/api/memory.ts +0 -69
  268. package/src/api/open-external.ts +0 -39
  269. package/src/api/playwright-cli.ts +0 -606
  270. package/src/api/providers.ts +0 -457
  271. package/src/api/read-env-token.ts +0 -33
  272. package/src/api/sessions.ts +0 -79
  273. package/src/api/settings.ts +0 -120
  274. package/src/api/skills.ts +0 -58
  275. package/src/api/testomatio-attachment.ts +0 -89
  276. package/src/api/testomatio-auth.ts +0 -284
  277. package/src/api/testomatio-proxy.ts +0 -197
  278. package/src/api/testomatio-run-stats.ts +0 -81
  279. package/src/api/testomatio-target.ts +0 -225
  280. package/src/api/testomatio-transcription.ts +0 -82
  281. package/src/api/workspace-search.ts +0 -96
  282. package/src/api/workspace-sync.ts +0 -151
  283. package/src/api/workspace.ts +0 -165
  284. package/src/app-server.ts +0 -556
  285. package/src/bridge.ts +0 -251
  286. package/src/check-tests.ts +0 -156
  287. package/src/cli.ts +0 -17
  288. package/src/commands.ts +0 -244
  289. package/src/config.ts +0 -183
  290. package/src/connection.ts +0 -658
  291. package/src/context-store.ts +0 -265
  292. package/src/debug-bus.ts +0 -405
  293. package/src/extensions/tool-gate.ts +0 -220
  294. package/src/extensions/webui/ask-channel.ts +0 -52
  295. package/src/extensions/webui/index.ts +0 -184
  296. package/src/extensions/webui/tools/ask-question.ts +0 -88
  297. package/src/extensions/webui/tools/query-result.ts +0 -79
  298. package/src/extensions/webui/tools/render-chart.ts +0 -53
  299. package/src/extensions/webui/tools/render-item.ts +0 -61
  300. package/src/extensions/webui/tools/render-list.ts +0 -170
  301. package/src/extensions/webui/tools/render-result.ts +0 -85
  302. package/src/extensions/webui/tools/render-tree.ts +0 -71
  303. package/src/extensions/webui/tools/ui-widget.ts +0 -54
  304. package/src/extensions/webui/tools/widget-result.ts +0 -13
  305. package/src/extensions/webui/widget-channel.ts +0 -50
  306. package/src/file-log.ts +0 -196
  307. package/src/git-tracked.ts +0 -68
  308. package/src/gitignore.ts +0 -53
  309. package/src/json-store.ts +0 -43
  310. package/src/load-env.ts +0 -70
  311. package/src/loader-style.ts +0 -96
  312. package/src/main.ts +0 -140
  313. package/src/mcp-catalog.ts +0 -96
  314. package/src/models-catalog.ts +0 -72
  315. package/src/permissions.ts +0 -120
  316. package/src/project-dir.ts +0 -189
  317. package/src/project-info.ts +0 -108
  318. package/src/prompt/app-ui.ts +0 -59
  319. package/src/prompt/browser.ts +0 -27
  320. package/src/prompt/index.ts +0 -62
  321. package/src/prompt/tools.ts +0 -27
  322. package/src/server-info.ts +0 -62
  323. package/src/session-factory.ts +0 -442
  324. package/src/session-store.ts +0 -115
  325. package/src/shell-env.ts +0 -45
  326. package/src/skills.ts +0 -163
  327. package/src/sync-snapshot.ts +0 -140
  328. package/src/telemetry.ts +0 -239
  329. package/src/testomatio-auth.ts +0 -299
  330. package/src/testomatio.ts +0 -98
  331. package/src/theme.ts +0 -30
  332. package/src/user-env.ts +0 -94
  333. package/src/welcome.ts +0 -194
  334. package/src/workspace/safe-path.ts +0 -85
  335. package/src/workspace/test-md.ts +0 -70
  336. package/src/workspace-model.ts +0 -440
  337. package/testeiya.config.json +0 -14
  338. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/advanced/authentication-flows.md +0 -0
  339. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/advanced/authentication.md +0 -0
  340. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/advanced/clock-mocking.md +0 -0
  341. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/advanced/mobile-testing.md +0 -0
  342. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/advanced/multi-context.md +0 -0
  343. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/advanced/multi-user.md +0 -0
  344. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/advanced/network-advanced.md +0 -0
  345. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/advanced/third-party.md +0 -0
  346. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/architecture/pom-vs-fixtures.md +0 -0
  347. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/architecture/test-architecture.md +0 -0
  348. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/architecture/when-to-mock.md +0 -0
  349. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/browser-apis/browser-apis.md +0 -0
  350. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/browser-apis/iframes.md +0 -0
  351. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/browser-apis/service-workers.md +0 -0
  352. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/browser-apis/websockets.md +0 -0
  353. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/core/annotations.md +0 -0
  354. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/core/assertions-waiting.md +0 -0
  355. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/core/configuration.md +0 -0
  356. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/core/fixtures-hooks.md +0 -0
  357. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/core/global-setup.md +0 -0
  358. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/core/locators.md +0 -0
  359. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/core/page-object-model.md +0 -0
  360. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/core/projects-dependencies.md +0 -0
  361. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/core/test-data.md +0 -0
  362. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/core/test-suite-structure.md +0 -0
  363. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/core/test-tags.md +0 -0
  364. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/debugging/console-errors.md +0 -0
  365. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/debugging/debugging.md +0 -0
  366. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/debugging/error-testing.md +0 -0
  367. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/debugging/flaky-tests.md +0 -0
  368. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/frameworks/angular.md +0 -0
  369. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/frameworks/nextjs.md +0 -0
  370. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/frameworks/react.md +0 -0
  371. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/frameworks/vue.md +0 -0
  372. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/infrastructure-ci-cd/ci-cd.md +0 -0
  373. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/infrastructure-ci-cd/docker.md +0 -0
  374. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/infrastructure-ci-cd/github-actions.md +0 -0
  375. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/infrastructure-ci-cd/gitlab.md +0 -0
  376. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/infrastructure-ci-cd/other-providers.md +0 -0
  377. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/infrastructure-ci-cd/parallel-sharding.md +0 -0
  378. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/infrastructure-ci-cd/performance.md +0 -0
  379. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/infrastructure-ci-cd/reporting.md +0 -0
  380. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/infrastructure-ci-cd/test-coverage.md +0 -0
  381. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/testing-patterns/accessibility.md +0 -0
  382. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/testing-patterns/api-testing.md +0 -0
  383. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/testing-patterns/browser-extensions.md +0 -0
  384. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/testing-patterns/canvas-webgl.md +0 -0
  385. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/testing-patterns/component-testing.md +0 -0
  386. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/testing-patterns/drag-drop.md +0 -0
  387. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/testing-patterns/electron.md +0 -0
  388. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/testing-patterns/file-operations.md +0 -0
  389. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/testing-patterns/file-upload-download.md +0 -0
  390. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/testing-patterns/forms-validation.md +0 -0
  391. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/testing-patterns/graphql-testing.md +0 -0
  392. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/testing-patterns/i18n.md +0 -0
  393. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/testing-patterns/performance-testing.md +0 -0
  394. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/testing-patterns/security-testing.md +0 -0
  395. /package/skills/{playwright-best-practices-skill → playwright/playwright-best-practices}/testing-patterns/visual-regression.md +0 -0
  396. /package/skills/{playwright-cli → playwright/playwright-cli}/SKILL.md +0 -0
  397. /package/skills/{playwright-cli → playwright/playwright-cli}/references/element-attributes.md +0 -0
  398. /package/skills/{playwright-cli → playwright/playwright-cli}/references/playwright-tests.md +0 -0
  399. /package/skills/{playwright-cli → playwright/playwright-cli}/references/request-mocking.md +0 -0
  400. /package/skills/{playwright-cli → playwright/playwright-cli}/references/running-code.md +0 -0
  401. /package/skills/{playwright-cli → playwright/playwright-cli}/references/session-management.md +0 -0
  402. /package/skills/{playwright-cli → playwright/playwright-cli}/references/storage-state.md +0 -0
  403. /package/skills/{playwright-cli → playwright/playwright-cli}/references/test-generation.md +0 -0
  404. /package/skills/{playwright-cli → playwright/playwright-cli}/references/tracing.md +0 -0
  405. /package/skills/{playwright-cli → playwright/playwright-cli}/references/video-recording.md +0 -0
package/src/telemetry.ts DELETED
@@ -1,239 +0,0 @@
1
- // OpenTelemetry → Langfuse observability for the agent.
2
- //
3
- // Two parts:
4
- // 1. initTelemetry() — one-time NodeSDK + LangfuseSpanProcessor bootstrap,
5
- // gated on LANGFUSE_PUBLIC_KEY + LANGFUSE_SECRET_KEY. A no-op (and no
6
- // dependency cost at runtime) when the keys are absent. Called from
7
- // app-server.ts right after the .env files are loaded.
8
- // 2. createTelemetryExtension() — a per-session extension that turns the
9
- // agent's hook events into a Langfuse trace tree:
10
- // before_agent_start → root (agent) observation = one trace per prompt
11
- // message_start/_end → child generation (LLM call) with usage + cost
12
- // tool_execution_start/_end → child tool observation (args + result)
13
- // agent_end → close the trace and flush
14
- // All prompts of one agent session share the SDK sessionId, so Langfuse
15
- // groups them into a single session.
16
-
17
- import { NodeSDK } from "@opentelemetry/sdk-node";
18
- import { LangfuseSpanProcessor } from "@langfuse/otel";
19
- import { startObservation, LangfuseOtelSpanAttributes } from "@langfuse/tracing";
20
- import type {
21
- LangfuseAgent,
22
- LangfuseGeneration,
23
- LangfuseTool,
24
- ObservationLevel,
25
- } from "@langfuse/tracing";
26
- import type { ExtensionFactory } from "@oh-my-pi/pi-coding-agent";
27
-
28
- let processor: LangfuseSpanProcessor | undefined;
29
- let sdk: NodeSDK | undefined;
30
- let enabled = false;
31
-
32
- export function initTelemetry(): void {
33
- if (sdk) return;
34
-
35
- const publicKey = process.env.LANGFUSE_PUBLIC_KEY;
36
- const secretKey = process.env.LANGFUSE_SECRET_KEY;
37
- if (!publicKey || !secretKey) {
38
- console.log(
39
- "[telemetry] Langfuse disabled — set LANGFUSE_PUBLIC_KEY + LANGFUSE_SECRET_KEY to enable",
40
- );
41
- return;
42
- }
43
-
44
- const baseUrl = process.env.LANGFUSE_BASE_URL ?? process.env.LANGFUSE_BASEURL;
45
- processor = new LangfuseSpanProcessor({ publicKey, secretKey, baseUrl });
46
- sdk = new NodeSDK({ spanProcessors: [processor] });
47
- sdk.start();
48
- enabled = true;
49
- console.log(`[telemetry] Langfuse enabled → ${baseUrl ?? "https://cloud.langfuse.com"}`);
50
- }
51
-
52
- export function isTelemetryEnabled(): boolean {
53
- return enabled;
54
- }
55
-
56
- export async function flushTelemetry(): Promise<void> {
57
- if (!processor) return;
58
- try {
59
- await processor.forceFlush();
60
- } catch (err) {
61
- console.error(
62
- "[telemetry] flush failed:",
63
- err instanceof Error ? err.message : err,
64
- );
65
- }
66
- }
67
-
68
- export function createTelemetryExtension(meta: TelemetryMeta): ExtensionFactory {
69
- return ((pi: any) => {
70
- let root: LangfuseAgent | undefined;
71
- let generation: LangfuseGeneration | undefined;
72
- let contextMessages: unknown;
73
- const tools = new Map<string, LangfuseTool>();
74
-
75
- pi.on("before_agent_start", (event: any, ctx: any) => {
76
- if (root) endTrace();
77
- const prompt = event?.prompt ?? "";
78
- const name = traceName(prompt);
79
- root = startObservation(name, { input: prompt }, { asType: "agent" });
80
- root.update({
81
- metadata: {
82
- cwd: meta.cwd,
83
- model: meta.modelId,
84
- provider: meta.provider,
85
- projectIds: meta.projectIds,
86
- },
87
- });
88
- const span = root.otelSpan;
89
- span.setAttribute(LangfuseOtelSpanAttributes.TRACE_NAME, name);
90
- span.setAttribute(LangfuseOtelSpanAttributes.TRACE_INPUT, serialize(prompt));
91
- span.setAttribute(
92
- LangfuseOtelSpanAttributes.TRACE_TAGS,
93
- JSON.stringify(["testeiya", meta.mode]),
94
- );
95
- const sessionId = ctx?.sessionManager?.getSessionId?.();
96
- if (sessionId) {
97
- span.setAttribute(LangfuseOtelSpanAttributes.TRACE_SESSION_ID, sessionId);
98
- }
99
- });
100
-
101
- pi.on("context", (event: any) => {
102
- contextMessages = event?.messages;
103
- });
104
-
105
- pi.on("message_start", (event: any) => {
106
- if (!root) return;
107
- if (event?.message?.role !== "assistant") return;
108
- generation = root.startObservation(
109
- "llm-generation",
110
- { input: contextMessages ?? [], model: meta.modelId },
111
- { asType: "generation" },
112
- );
113
- });
114
-
115
- pi.on("message_end", (event: any) => {
116
- const msg = event?.message;
117
- if (!generation || msg?.role !== "assistant") return;
118
- generation.update({
119
- model: msg.model ?? meta.modelId,
120
- output: msg.content,
121
- usageDetails: usageDetails(msg.usage),
122
- costDetails: costDetails(msg.usage),
123
- });
124
- generation.end();
125
- generation = undefined;
126
- });
127
-
128
- pi.on("tool_execution_start", (event: any) => {
129
- if (!root) return;
130
- const name = event?.toolName ?? "tool";
131
- tools.set(
132
- event.toolCallId,
133
- root.startObservation(
134
- name,
135
- { input: event?.args, metadata: { toolName: name, intent: event?.intent } },
136
- { asType: "tool" },
137
- ),
138
- );
139
- });
140
-
141
- pi.on("tool_execution_end", (event: any) => {
142
- const span = tools.get(event?.toolCallId);
143
- if (!span) return;
144
- let level: ObservationLevel = "DEFAULT";
145
- if (event?.isError) level = "ERROR";
146
- span.update({ output: event?.result, level });
147
- span.end();
148
- tools.delete(event.toolCallId);
149
- });
150
-
151
- pi.on("agent_end", (event: any) => {
152
- if (!root) return;
153
- const output = finalText(event?.messages);
154
- root.otelSpan.setAttribute(
155
- LangfuseOtelSpanAttributes.TRACE_OUTPUT,
156
- serialize(output),
157
- );
158
- root.update({ output });
159
- endTrace();
160
- void flushTelemetry();
161
- });
162
-
163
- function endTrace(): void {
164
- for (const span of tools.values()) span.end();
165
- tools.clear();
166
- if (generation) {
167
- generation.end();
168
- generation = undefined;
169
- }
170
- if (root) {
171
- root.end();
172
- root = undefined;
173
- }
174
- }
175
- }) as ExtensionFactory;
176
- }
177
-
178
- function usageDetails(usage: any): Record<string, number> | undefined {
179
- if (!usage) return undefined;
180
- return {
181
- input: usage.input,
182
- output: usage.output,
183
- cache_read_input_tokens: usage.cacheRead,
184
- cache_creation_input_tokens: usage.cacheWrite,
185
- total: usage.totalTokens,
186
- };
187
- }
188
-
189
- function costDetails(usage: any): Record<string, number> | undefined {
190
- if (!usage?.cost) return undefined;
191
- return {
192
- input: usage.cost.input,
193
- output: usage.cost.output,
194
- total: usage.cost.total,
195
- };
196
- }
197
-
198
- function finalText(messages: any): string | undefined {
199
- if (!Array.isArray(messages)) return undefined;
200
- for (let i = messages.length - 1; i >= 0; i--) {
201
- if (messages[i]?.role === "assistant") return textOf(messages[i].content);
202
- }
203
- return undefined;
204
- }
205
-
206
- function textOf(content: any): string | undefined {
207
- if (typeof content === "string") return content;
208
- if (!Array.isArray(content)) return undefined;
209
- return content
210
- .filter((c) => c?.type === "text")
211
- .map((c) => c.text)
212
- .join("\n");
213
- }
214
-
215
- function traceName(prompt: unknown): string {
216
- let text = "";
217
- if (typeof prompt === "string") text = prompt;
218
- const firstLine = text.split("\n")[0]?.trim() ?? "";
219
- if (!firstLine) return "agent-run";
220
- if (firstLine.length <= 60) return firstLine;
221
- return `${firstLine.slice(0, 60)}…`;
222
- }
223
-
224
- function serialize(value: unknown): string {
225
- if (typeof value === "string") return value;
226
- try {
227
- return JSON.stringify(value) ?? "";
228
- } catch {
229
- return String(value);
230
- }
231
- }
232
-
233
- interface TelemetryMeta {
234
- cwd: string;
235
- mode: string;
236
- modelId?: string;
237
- provider?: string;
238
- projectIds?: string[];
239
- }
@@ -1,299 +0,0 @@
1
- // Testomat.io user-scope JWT bootstrap for the web/desktop app.
2
- //
3
- // Ported from the TUI's `src/testomatio-auth.ts` (testomatio/testeiya#11) but
4
- // trimmed to the pieces a UI flow needs — there are no terminal prompts here.
5
- // The HTTP layer in `api/testomatio-auth.ts` drives the actual login UI.
6
- //
7
- // Flow:
8
- // 1. The user opens `${baseUrl}/app-auth`, signs in, copies the
9
- // pasted token, and submits it from the onboarding screen.
10
- // 2. We GET /api/projects with that JWT to enumerate accessible projects.
11
- // 3. The chosen project's per-project `api_key` (`tstmt_...`) is what MCP /
12
- // check-tests already expect on the `TESTOMATIO` env var.
13
- //
14
- // The user JWT (`eyJ...`) is user-scoped and long-lived. We persist it to
15
- // `~/.testeiya/testomatio-auth.json` (mode 0600) — deliberately a SEPARATE file
16
- // from `~/.testeiya/auth.json`, which the SDK's `AuthStorage` owns for the LLM
17
- // provider key. Writing our own JSON into that file would corrupt it.
18
-
19
- import { rmSync } from "node:fs";
20
- import { HOME_DIR } from "./project-dir.js";
21
- import { readJson, writeJson } from "./json-store.js";
22
- import { join } from "node:path";
23
-
24
- const AUTH_FILE = join(HOME_DIR, "testomatio-auth.json");
25
- // Persistent precache of the (slow) project list — survives app restarts, so
26
- // opening a project never waits on a network round-trip. Holds full projects
27
- // incl. api_key, same trust level as the JWT in AUTH_FILE, so mode 0600.
28
- const PROJECTS_CACHE_FILE = join(HOME_DIR, "testomatio-projects.json");
29
- export const DEFAULT_BASE_URL = "https://app.testomat.io";
30
-
31
- export interface StoredAuth {
32
- token: string;
33
- baseUrl: string;
34
- projectId?: string;
35
- }
36
-
37
- export interface Project {
38
- id: string;
39
- title: string;
40
- apiKey: string;
41
- framework?: string;
42
- testsCount?: number;
43
- }
44
-
45
- export class UnauthorizedError extends Error {
46
- constructor(message = "Testomat.io rejected the stored token.") {
47
- super(message);
48
- this.name = "UnauthorizedError";
49
- }
50
- }
51
-
52
- /** Strip a trailing slash so `${baseUrl}/path` never doubles up. */
53
- export function normalizeBaseUrl(url?: string): string {
54
- const raw = (url || process.env.TESTOMATIO_URL || DEFAULT_BASE_URL).trim();
55
- return (raw || DEFAULT_BASE_URL).replace(/\/+$/, "");
56
- }
57
-
58
- /** Browser URL the user opens to mint a JWT for the app. */
59
- export function signInUrl(baseUrl: string): string {
60
- return `${normalizeBaseUrl(baseUrl)}/app-auth?app_name=Testeiya`;
61
- }
62
-
63
- export function loadStoredAuth(): StoredAuth | null {
64
- const raw = readJson<Partial<StoredAuth>>(AUTH_FILE, {});
65
- if (typeof raw?.token !== "string" || !raw.token.trim()) return null;
66
- return {
67
- token: raw.token,
68
- baseUrl: raw.baseUrl || DEFAULT_BASE_URL,
69
- projectId: typeof raw.projectId === "string" ? raw.projectId : undefined,
70
- };
71
- }
72
-
73
- export function saveStoredAuth(auth: StoredAuth): void {
74
- // mode 0o600: same trust level as the JWT it stores.
75
- writeJson(AUTH_FILE, auth, { mode: 0o600 });
76
- }
77
-
78
- export function clearStoredAuth(): void {
79
- try {
80
- rmSync(AUTH_FILE, { force: true });
81
- } catch {
82
- /* best-effort */
83
- }
84
- clearProjectsCache();
85
- }
86
-
87
- /** Network timeout for Testomat.io API calls, so a hung request surfaces as a
88
- * visible error instead of an infinite spinner. Generous because accounts with
89
- * hundreds of projects can take 10s+ to serialize. Must stay below the Bun
90
- * server's idleTimeout (see app-server.ts) so the handler can return a clean
91
- * error before the client socket is reset. */
92
- const FETCH_TIMEOUT_MS = 30_000;
93
-
94
- // Short-lived server-side cache of the (slow) project list, keyed by token+host.
95
- // The dialog status check, the connect call, and opening a project all need the
96
- // same list within seconds of each other — without this each one re-downloads
97
- // hundreds of projects (~10s every time). Kept brief so freshly-created or
98
- // renamed projects still show up on the next interaction.
99
- const PROJECTS_TTL_MS = 60_000;
100
- const projectsCache = new Map<string, { at: number; projects: Project[] }>();
101
-
102
- function projectsCacheKey(token: string, baseUrl: string): string {
103
- return `${normalizeBaseUrl(baseUrl)}::${token}`;
104
- }
105
-
106
- function saveProjectsToDisk(token: string, baseUrl: string, projects: Project[]): void {
107
- try {
108
- // mode 0o600: holds full projects incl. api_key, same trust as the JWT.
109
- writeJson(
110
- PROJECTS_CACHE_FILE,
111
- { key: projectsCacheKey(token, baseUrl), at: Date.now(), projects },
112
- { mode: 0o600 }
113
- );
114
- } catch {
115
- /* best-effort — cache is an optimization */
116
- }
117
- }
118
-
119
- function loadProjectsFromDisk(
120
- token: string,
121
- baseUrl: string
122
- ): { at: number; projects: Project[] } | null {
123
- try {
124
- const raw = readJson<{ key?: string; at?: number; projects?: Project[] }>(
125
- PROJECTS_CACHE_FILE,
126
- {}
127
- );
128
- if (raw.key !== projectsCacheKey(token, baseUrl)) return null;
129
- if (!Array.isArray(raw.projects) || raw.projects.length === 0) return null;
130
- return { at: typeof raw.at === "number" ? raw.at : 0, projects: raw.projects };
131
- } catch {
132
- return null;
133
- }
134
- }
135
-
136
- /**
137
- * Return cached projects without ever hitting the network: fresh in-memory
138
- * entry, else any disk cache (regardless of age). Returns null when nothing is
139
- * cached. Callers that want freshness should pair this with a background
140
- * `fetchProjects(token, baseUrl, { force: true })`.
141
- */
142
- export function getCachedProjects(token: string, baseUrl: string): Project[] | null {
143
- const mem = projectsCache.get(projectsCacheKey(token, baseUrl));
144
- if (mem && Date.now() - mem.at < PROJECTS_TTL_MS) return mem.projects;
145
- const disk = loadProjectsFromDisk(token, baseUrl);
146
- if (disk) {
147
- // Warm the in-memory cache from disk so repeat calls this session are instant.
148
- projectsCache.set(projectsCacheKey(token, baseUrl), {
149
- at: disk.at,
150
- projects: disk.projects,
151
- });
152
- return disk.projects;
153
- }
154
- return null;
155
- }
156
-
157
- export interface FetchProjectsOptions {
158
- /** Bypass the cache and always hit the network. */
159
- force?: boolean;
160
- }
161
-
162
- export async function fetchProjects(
163
- token: string,
164
- baseUrl: string,
165
- opts: FetchProjectsOptions = {}
166
- ): Promise<Project[]> {
167
- const url = `${normalizeBaseUrl(baseUrl)}/api/projects`;
168
- const cacheKey = projectsCacheKey(token, baseUrl);
169
-
170
- const cached = projectsCache.get(cacheKey);
171
- if (!opts.force && cached && Date.now() - cached.at < PROJECTS_TTL_MS) {
172
- console.log(
173
- `[tio-auth] using cached project list (${cached.projects.length}, age ${
174
- Date.now() - cached.at
175
- }ms)`
176
- );
177
- return cached.projects;
178
- }
179
-
180
- console.log(`[tio-auth] GET ${url} (token ${maskToken(token)})`);
181
-
182
- const startedAt = Date.now();
183
- let res: Response;
184
- try {
185
- res = await fetch(url, {
186
- headers: { Authorization: `Bearer ${token}`, Accept: "application/json" },
187
- signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
188
- });
189
- } catch (err) {
190
- const timedOut = err instanceof Error && err.name === "TimeoutError";
191
- const reason = timedOut
192
- ? `timed out after ${FETCH_TIMEOUT_MS}ms`
193
- : err instanceof Error
194
- ? err.message
195
- : String(err);
196
- console.error(`[tio-auth] GET ${url} failed: ${reason}`);
197
- const hint = timedOut
198
- ? ` Check that this machine can reach ${normalizeBaseUrl(baseUrl)} (VPN/DNS/firewall) and that TESTOMATIO_URL is correct.`
199
- : "";
200
- throw new Error(`Could not reach ${url} — ${reason}.${hint}`);
201
- }
202
- const ms = Date.now() - startedAt;
203
- console.log(`[tio-auth] → HTTP ${res.status} ${res.statusText} (${ms}ms)`);
204
-
205
- // Testomat.io returns 401 for missing tokens and 403 for rejected/expired
206
- // tokens — treat both as "re-authorize".
207
- if (res.status === 401 || res.status === 403) throw new UnauthorizedError();
208
- if (!res.ok) {
209
- throw new Error(`Failed to fetch projects: HTTP ${res.status} ${res.statusText}`);
210
- }
211
- const body = (await res.json()) as {
212
- data?: Array<{ id?: string; attributes?: Record<string, unknown> }>;
213
- };
214
- const list = Array.isArray(body?.data) ? body.data : [];
215
- const projects: Project[] = [];
216
- let missingKey = 0;
217
- for (const entry of list) {
218
- const id = typeof entry?.id === "string" ? entry.id : null;
219
- const attrs = entry?.attributes ?? {};
220
- const title = typeof attrs.title === "string" ? attrs.title : id ?? "";
221
- // Testomat.io's JSON:API serializes attributes in kebab-case (`api-key`);
222
- // accept the snake_case form too for forward-compatibility.
223
- const rawKey = attrs["api-key"] ?? attrs.api_key;
224
- const apiKey = typeof rawKey === "string" ? rawKey : "";
225
- const framework = typeof attrs.framework === "string" ? attrs.framework : undefined;
226
- const rawCount = attrs["tests-count"] ?? attrs.tests_count;
227
- const testsCount = typeof rawCount === "number" ? rawCount : undefined;
228
- if (!id) continue;
229
- if (!apiKey) {
230
- missingKey++;
231
- continue;
232
- }
233
- projects.push({ id, title, apiKey, framework, testsCount });
234
- }
235
- console.log(
236
- `[tio-auth] parsed ${projects.length}/${list.length} project(s)` +
237
- (missingKey ? ` (${missingKey} skipped — no api-key in response)` : "") +
238
- `: ${projects.map((p) => p.id).join(", ") || "(none)"}`
239
- );
240
- projectsCache.set(cacheKey, { at: Date.now(), projects });
241
- saveProjectsToDisk(token, baseUrl, projects);
242
- return projects;
243
- }
244
-
245
- /** Drop the cached project list (e.g. on logout). */
246
- export function clearProjectsCache(): void {
247
- projectsCache.clear();
248
- try {
249
- rmSync(PROJECTS_CACHE_FILE, { force: true });
250
- } catch {
251
- /* best-effort */
252
- }
253
- }
254
-
255
- /** Render a token as `eyJ…abcd` for safe logging — never log the full JWT. */
256
- export function maskToken(token: string): string {
257
- if (!token) return "(empty)";
258
- if (token.length <= 12) return `${token.slice(0, 3)}…`;
259
- return `${token.slice(0, 4)}…${token.slice(-4)}`;
260
- }
261
-
262
- // ── CLI (TUI) auth restore ───────────────────────────────────────────────────
263
- // Non-interactive: reuse the stored token + last selected project when they
264
- // resolve, else return null so the TUI starts unconnected and the in-session
265
- // `/connect` command takes over. Never prompts, never throws.
266
-
267
- export async function restoreTestomatioAuth(
268
- opts: RestoreAuthOptions = {}
269
- ): Promise<RestoredAuth | null> {
270
- const stored = loadStoredAuth();
271
- if (!stored?.projectId) return null;
272
- if (opts.baseUrl && normalizeBaseUrl(opts.baseUrl) !== normalizeBaseUrl(stored.baseUrl)) {
273
- return null;
274
- }
275
-
276
- let projects = getCachedProjects(stored.token, stored.baseUrl);
277
- if (!projects) {
278
- try {
279
- projects = await fetchProjects(stored.token, stored.baseUrl);
280
- } catch {
281
- return null;
282
- }
283
- }
284
-
285
- const project = projects.find((p) => p.id === stored.projectId);
286
- if (!project) return null;
287
- return { token: stored.token, baseUrl: stored.baseUrl, project, projects };
288
- }
289
-
290
- export interface RestoreAuthOptions {
291
- baseUrl?: string;
292
- }
293
-
294
- export interface RestoredAuth {
295
- token: string;
296
- baseUrl: string;
297
- project: Project;
298
- projects: Project[];
299
- }
package/src/testomatio.ts DELETED
@@ -1,98 +0,0 @@
1
- // Testomat.io environment/config parsing for the TUI agent.
2
- // Loads `.env` (so TESTOMATIO* vars are available before the session starts),
3
- // exposes the parsed config, and reports whether the Testomat.io MCP is wired up.
4
-
5
- import { existsSync } from "node:fs";
6
- import { join } from "node:path";
7
-
8
- const ENV_FILES = [".env", ".env.local"];
9
-
10
- /**
11
- * Load `.env` / `.env.local` from `cwd` into `process.env`.
12
- * Must run BEFORE createTesteiyaSession (it reads the provider API key and
13
- * the TESTOMATIO token from the environment). No-op if the file is missing.
14
- */
15
- export function loadDotEnv(cwd = process.cwd()): void {
16
- for (const file of ENV_FILES) {
17
- const path = join(cwd, file);
18
- if (!existsSync(path)) continue;
19
- try {
20
- // Node ≥ 20.12 / 22 built-in — no dotenv dependency needed.
21
- process.loadEnvFile(path);
22
- } catch {
23
- // Older Node or a parse error — env may still be set another way; ignore.
24
- }
25
- }
26
- }
27
-
28
- export interface TestomatioConfig {
29
- /** `TESTOMATIO` — the API key handed to bash/skills. */
30
- token?: string;
31
- /** `TESTOMATIO_URL` — backend URL override. */
32
- url?: string;
33
- /** `TESTOMATIO_PROJECT_ID` (or legacy `TESTOMATIO_PROJECT`). */
34
- projectId?: string;
35
- /** `TESTOMATIO_PROJECT_TOKEN` — per-project token used by the MCP server. */
36
- projectToken?: string;
37
- /** `TESTOMATIO_BASE_URL` — base URL passed to the MCP server. */
38
- baseUrl?: string;
39
- }
40
-
41
- /** Parse all TESTOMATIO* vars out of the current environment. */
42
- export function getTestomatioConfig(): TestomatioConfig {
43
- const e = process.env;
44
- return {
45
- token: e.TESTOMATIO,
46
- url: e.TESTOMATIO_URL,
47
- projectId: e.TESTOMATIO_PROJECT_ID ?? e.TESTOMATIO_PROJECT,
48
- projectToken: e.TESTOMATIO_PROJECT_TOKEN,
49
- baseUrl: e.TESTOMATIO_BASE_URL,
50
- };
51
- }
52
-
53
- /** Whether a `TESTOMATIO` key is present. */
54
- export function hasTestomatioKey(cfg: TestomatioConfig = getTestomatioConfig()): boolean {
55
- return Boolean(cfg.token && cfg.token.trim());
56
- }
57
-
58
- /** Mask a token for display: first 4 + last 4, never the middle. */
59
- export function maskToken(token?: string): string {
60
- if (!token) return "";
61
- return token.length <= 8 ? "****" : `${token.slice(0, 4)}…${token.slice(-4)}`;
62
- }
63
-
64
- interface McpLike {
65
- getConnectionStatus?(name: string): string;
66
- getTools?(): Array<{ name?: string; mcpServerName?: string }>;
67
- }
68
-
69
- /**
70
- * True if the Testomat.io MCP server is connected (its tools are loaded).
71
- * Checks loaded tools' `mcpServerName`/`name`, then known server names.
72
- */
73
- export function isTestomatioMcpEnabled(mcp: McpLike | undefined): boolean {
74
- if (!mcp) return false;
75
- const re = /testomat/i;
76
- const tools = mcp.getTools?.() ?? [];
77
- if (tools.some(t => re.test(t?.mcpServerName ?? "") || re.test(t?.name ?? ""))) {
78
- return true;
79
- }
80
- for (const name of ["testomat-mcp", "testomatio"]) {
81
- if (mcp.getConnectionStatus?.(name) === "connected") return true;
82
- }
83
- return false;
84
- }
85
-
86
- /**
87
- * One-line status summary for the startup banner, or null if no key is set.
88
- * e.g. "within Testomat.io project 1a2b3c4d (token tstm…ab12) · MCP enabled"
89
- */
90
- export function testomatioStatusLine(
91
- mcp: McpLike | undefined,
92
- cfg: TestomatioConfig = getTestomatioConfig(),
93
- ): string | null {
94
- if (!hasTestomatioKey(cfg)) return null;
95
- const where = cfg.projectId ? ` ${cfg.projectId}` : "";
96
- const mcpState = isTestomatioMcpEnabled(mcp) ? "MCP enabled" : "MCP not connected";
97
- return `within Testomat.io project${where} (token ${maskToken(cfg.token)}) · ${mcpState}`;
98
- }
package/src/theme.ts DELETED
@@ -1,30 +0,0 @@
1
- // Testeiya branding: theme selection + input border styling.
2
- // Keeps all raw ANSI / color concerns out of main.ts.
3
-
4
- import { setTheme } from "@oh-my-pi/pi-coding-agent";
5
- import { theme as themeSingleton } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
6
-
7
- const TC_VIOLET = "\x1b[38;2;139;92;246m"; // #8b5cf6 brand primary
8
- const TC_RESET = "\x1b[0m";
9
-
10
- /** Colorize a string in the Testeiya input-border violet. */
11
- export const testeiyaBorder = (s: string): string => `${TC_VIOLET}${s}${TC_RESET}`;
12
-
13
- interface ThemableInteractive {
14
- editor: { setBorderVisible(v: boolean): void; borderColor: (s: string) => string };
15
- }
16
-
17
- /**
18
- * Apply the Testeiya look: obsidian base theme + violet input border that
19
- * survives bash/python mode exits (the SDK restores the "off" thinking border).
20
- */
21
- export function applyTesteiyaTheme(interactive: ThemableInteractive): void {
22
- setTheme("obsidian"); // alternatives: "dark-sakura", "dark-tokyo-night"
23
- interactive.editor.setBorderVisible(true);
24
-
25
- const origThinkingBorder = themeSingleton.getThinkingBorderColor.bind(themeSingleton);
26
- (themeSingleton as any).getThinkingBorderColor = (level: any) =>
27
- level === "off" ? testeiyaBorder : origThinkingBorder(level);
28
-
29
- interactive.editor.borderColor = testeiyaBorder;
30
- }