switchroom 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (718) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +447 -0
  3. package/bin/autoaccept.exp +81 -0
  4. package/bin/boot-self-test.sh +149 -0
  5. package/bin/bridge-watchdog.sh +967 -0
  6. package/bin/handoff-briefing.sh +206 -0
  7. package/bin/run-hook.sh +228 -0
  8. package/bin/switchroom.ts +4 -0
  9. package/bin/timezone-hook.sh +67 -0
  10. package/bin/user-profile-refresh-hook.sh +38 -0
  11. package/bin/workspace-dynamic-hook.sh +142 -0
  12. package/bin/workspace-stable-hook.sh +57 -0
  13. package/dist/cli/autoaccept-poll.js +118 -0
  14. package/dist/cli/switchroom.js +48557 -0
  15. package/package.json +95 -0
  16. package/profiles/_base/settings.json.hbs +15 -0
  17. package/profiles/_base/start.sh.hbs +383 -0
  18. package/profiles/_shared/telegram-style.md.hbs +140 -0
  19. package/profiles/coding/CLAUDE.md.hbs +57 -0
  20. package/profiles/coding/skills/architecture/SKILL.md +70 -0
  21. package/profiles/coding/skills/code-review/SKILL.md +58 -0
  22. package/profiles/coding/workspace/SOUL.md.hbs +25 -0
  23. package/profiles/default/CLAUDE.md +238 -0
  24. package/profiles/default/CLAUDE.md.hbs +113 -0
  25. package/profiles/default/workspace/CLAUDE.md.hbs +126 -0
  26. package/profiles/default/workspace/HEARTBEAT.md.hbs +40 -0
  27. package/profiles/default/workspace/IDENTITY.md.hbs +32 -0
  28. package/profiles/default/workspace/MEMORY.md.hbs +29 -0
  29. package/profiles/default/workspace/SOUL.md.hbs +61 -0
  30. package/profiles/default/workspace/TOOLS.md.hbs +29 -0
  31. package/profiles/default/workspace/USER.md.hbs +52 -0
  32. package/profiles/default/workspace/memory/.gitkeep +0 -0
  33. package/profiles/executive-assistant/CLAUDE.md.hbs +51 -0
  34. package/profiles/executive-assistant/skills/daily-briefing/SKILL.md +55 -0
  35. package/profiles/executive-assistant/skills/meeting-prep/SKILL.md +58 -0
  36. package/profiles/executive-assistant/workspace/SOUL.md.hbs +25 -0
  37. package/profiles/health-coach/CLAUDE.md.hbs +45 -0
  38. package/profiles/health-coach/skills/check-in/SKILL.md +41 -0
  39. package/profiles/health-coach/skills/weekly-review/SKILL.md +53 -0
  40. package/profiles/health-coach/workspace/SOUL.md.hbs +25 -0
  41. package/skills/buildkite-agent-infrastructure/SKILL.md +302 -0
  42. package/skills/buildkite-agent-infrastructure/agents/openai.yaml +6 -0
  43. package/skills/buildkite-agent-infrastructure/assets/buildkite-icon-large.png +0 -0
  44. package/skills/buildkite-agent-infrastructure/assets/buildkite-icon-small.png +0 -0
  45. package/skills/buildkite-agent-infrastructure/references/audit-logging.md +87 -0
  46. package/skills/buildkite-agent-infrastructure/references/graphql-mutations.md +690 -0
  47. package/skills/buildkite-agent-infrastructure/references/instance-shapes.md +38 -0
  48. package/skills/buildkite-agent-infrastructure/references/pipeline-templates.md +73 -0
  49. package/skills/buildkite-agent-infrastructure/references/self-hosted-agents.md +137 -0
  50. package/skills/buildkite-agent-infrastructure/references/sso-saml.md +92 -0
  51. package/skills/buildkite-agent-runtime/SKILL.md +476 -0
  52. package/skills/buildkite-agent-runtime/agents/openai.yaml +6 -0
  53. package/skills/buildkite-agent-runtime/assets/buildkite-icon-large.png +0 -0
  54. package/skills/buildkite-agent-runtime/assets/buildkite-icon-small.png +0 -0
  55. package/skills/buildkite-agent-runtime/references/flag-reference.md +417 -0
  56. package/skills/buildkite-agent-runtime/references/patterns-and-recipes.md +555 -0
  57. package/skills/buildkite-api/SKILL.md +285 -0
  58. package/skills/buildkite-api/agents/openai.yaml +6 -0
  59. package/skills/buildkite-api/assets/buildkite-icon-large.png +0 -0
  60. package/skills/buildkite-api/assets/buildkite-icon-small.png +0 -0
  61. package/skills/buildkite-api/references/graphql-reference.md +195 -0
  62. package/skills/buildkite-api/references/patterns.md +44 -0
  63. package/skills/buildkite-api/references/webhooks.md +161 -0
  64. package/skills/buildkite-cli/SKILL.md +379 -0
  65. package/skills/buildkite-cli/agents/openai.yaml +6 -0
  66. package/skills/buildkite-cli/assets/buildkite-icon-large.png +0 -0
  67. package/skills/buildkite-cli/assets/buildkite-icon-small.png +0 -0
  68. package/skills/buildkite-cli/references/command-reference.md +181 -0
  69. package/skills/buildkite-migration/SKILL.md +182 -0
  70. package/skills/buildkite-pipelines/SKILL.md +464 -0
  71. package/skills/buildkite-pipelines/agents/openai.yaml +6 -0
  72. package/skills/buildkite-pipelines/assets/buildkite-icon-large.png +0 -0
  73. package/skills/buildkite-pipelines/assets/buildkite-icon-small.png +0 -0
  74. package/skills/buildkite-pipelines/examples/basic-pipeline.yml +24 -0
  75. package/skills/buildkite-pipelines/examples/optimized-pipeline.yml +100 -0
  76. package/skills/buildkite-pipelines/references/advanced-patterns.md +286 -0
  77. package/skills/buildkite-pipelines/references/retry-and-error-codes.md +131 -0
  78. package/skills/buildkite-pipelines/references/step-types-reference.md +225 -0
  79. package/skills/buildkite-secure-delivery/SKILL.md +168 -0
  80. package/skills/buildkite-secure-delivery/agents/openai.yaml +6 -0
  81. package/skills/buildkite-secure-delivery/assets/buildkite-icon-large.png +0 -0
  82. package/skills/buildkite-secure-delivery/assets/buildkite-icon-small.png +0 -0
  83. package/skills/buildkite-secure-delivery/references/oidc-cloud-providers.md +83 -0
  84. package/skills/buildkite-secure-delivery/references/package-publishing.md +100 -0
  85. package/skills/buildkite-test-engine/SKILL.md +239 -0
  86. package/skills/buildkite-test-engine/agents/openai.yaml +6 -0
  87. package/skills/buildkite-test-engine/assets/buildkite-icon-large.png +0 -0
  88. package/skills/buildkite-test-engine/assets/buildkite-icon-small.png +0 -0
  89. package/skills/buildkite-test-engine/examples/bktec-splitting.yml +16 -0
  90. package/skills/buildkite-test-engine/examples/collector-pipeline.yml +11 -0
  91. package/skills/buildkite-test-engine/references/collectors.md +198 -0
  92. package/skills/buildkite-test-engine/references/splitting-examples.md +93 -0
  93. package/skills/docx/LICENSE.txt +30 -0
  94. package/skills/docx/SKILL.md +590 -0
  95. package/skills/docx/VENDORED.md +32 -0
  96. package/skills/docx/scripts/__init__.py +1 -0
  97. package/skills/docx/scripts/accept_changes.py +135 -0
  98. package/skills/docx/scripts/comment.py +318 -0
  99. package/skills/docx/scripts/office/helpers/__init__.py +0 -0
  100. package/skills/docx/scripts/office/helpers/merge_runs.py +199 -0
  101. package/skills/docx/scripts/office/helpers/simplify_redlines.py +197 -0
  102. package/skills/docx/scripts/office/pack.py +159 -0
  103. package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  104. package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  105. package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  106. package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  107. package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  108. package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  109. package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  110. package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  111. package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  112. package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  113. package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  114. package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  115. package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  116. package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  117. package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  118. package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  119. package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  120. package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  121. package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  122. package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  123. package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  124. package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  125. package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  126. package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  127. package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  128. package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  129. package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  130. package/skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  131. package/skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  132. package/skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  133. package/skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  134. package/skills/docx/scripts/office/schemas/mce/mc.xsd +75 -0
  135. package/skills/docx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
  136. package/skills/docx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
  137. package/skills/docx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
  138. package/skills/docx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
  139. package/skills/docx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
  140. package/skills/docx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  141. package/skills/docx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
  142. package/skills/docx/scripts/office/soffice.py +183 -0
  143. package/skills/docx/scripts/office/unpack.py +132 -0
  144. package/skills/docx/scripts/office/validate.py +111 -0
  145. package/skills/docx/scripts/office/validators/__init__.py +15 -0
  146. package/skills/docx/scripts/office/validators/__pycache__/__init__.cpython-313.pyc +0 -0
  147. package/skills/docx/scripts/office/validators/__pycache__/base.cpython-313.pyc +0 -0
  148. package/skills/docx/scripts/office/validators/base.py +847 -0
  149. package/skills/docx/scripts/office/validators/docx.py +446 -0
  150. package/skills/docx/scripts/office/validators/pptx.py +275 -0
  151. package/skills/docx/scripts/office/validators/redlining.py +247 -0
  152. package/skills/docx/scripts/templates/comments.xml +3 -0
  153. package/skills/docx/scripts/templates/commentsExtended.xml +3 -0
  154. package/skills/docx/scripts/templates/commentsExtensible.xml +3 -0
  155. package/skills/docx/scripts/templates/commentsIds.xml +3 -0
  156. package/skills/docx/scripts/templates/people.xml +3 -0
  157. package/skills/file-bug/SKILL.md +129 -0
  158. package/skills/humanizer/LICENSE +21 -0
  159. package/skills/humanizer/SKILL.md +559 -0
  160. package/skills/humanizer/VENDORED.md +38 -0
  161. package/skills/humanizer-calibrate/SKILL.md +144 -0
  162. package/skills/mcp-builder/LICENSE.txt +202 -0
  163. package/skills/mcp-builder/SKILL.md +236 -0
  164. package/skills/mcp-builder/VENDORED.md +32 -0
  165. package/skills/mcp-builder/reference/evaluation.md +602 -0
  166. package/skills/mcp-builder/reference/mcp_best_practices.md +249 -0
  167. package/skills/mcp-builder/reference/node_mcp_server.md +970 -0
  168. package/skills/mcp-builder/reference/python_mcp_server.md +719 -0
  169. package/skills/mcp-builder/scripts/connections.py +151 -0
  170. package/skills/mcp-builder/scripts/evaluation.py +373 -0
  171. package/skills/mcp-builder/scripts/example_evaluation.xml +22 -0
  172. package/skills/mcp-builder/scripts/requirements.txt +2 -0
  173. package/skills/pdf/LICENSE.txt +30 -0
  174. package/skills/pdf/SKILL.md +314 -0
  175. package/skills/pdf/VENDORED.md +32 -0
  176. package/skills/pdf/forms.md +294 -0
  177. package/skills/pdf/reference.md +612 -0
  178. package/skills/pdf/scripts/check_bounding_boxes.py +65 -0
  179. package/skills/pdf/scripts/check_fillable_fields.py +11 -0
  180. package/skills/pdf/scripts/convert_pdf_to_images.py +33 -0
  181. package/skills/pdf/scripts/create_validation_image.py +37 -0
  182. package/skills/pdf/scripts/extract_form_field_info.py +122 -0
  183. package/skills/pdf/scripts/extract_form_structure.py +115 -0
  184. package/skills/pdf/scripts/fill_fillable_fields.py +98 -0
  185. package/skills/pdf/scripts/fill_pdf_form_with_annotations.py +107 -0
  186. package/skills/pptx/LICENSE.txt +30 -0
  187. package/skills/pptx/SKILL.md +232 -0
  188. package/skills/pptx/VENDORED.md +32 -0
  189. package/skills/pptx/editing.md +205 -0
  190. package/skills/pptx/pptxgenjs.md +420 -0
  191. package/skills/pptx/scripts/__init__.py +0 -0
  192. package/skills/pptx/scripts/add_slide.py +195 -0
  193. package/skills/pptx/scripts/clean.py +286 -0
  194. package/skills/pptx/scripts/office/helpers/__init__.py +0 -0
  195. package/skills/pptx/scripts/office/helpers/merge_runs.py +199 -0
  196. package/skills/pptx/scripts/office/helpers/simplify_redlines.py +197 -0
  197. package/skills/pptx/scripts/office/pack.py +159 -0
  198. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  199. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  200. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  201. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  202. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  203. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  204. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  205. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  206. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  207. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  208. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  209. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  210. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  211. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  212. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  213. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  214. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  215. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  216. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  217. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  218. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  219. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  220. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  221. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  222. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  223. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  224. package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  225. package/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  226. package/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  227. package/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  228. package/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  229. package/skills/pptx/scripts/office/schemas/mce/mc.xsd +75 -0
  230. package/skills/pptx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
  231. package/skills/pptx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
  232. package/skills/pptx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
  233. package/skills/pptx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
  234. package/skills/pptx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
  235. package/skills/pptx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  236. package/skills/pptx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
  237. package/skills/pptx/scripts/office/soffice.py +183 -0
  238. package/skills/pptx/scripts/office/unpack.py +132 -0
  239. package/skills/pptx/scripts/office/validate.py +111 -0
  240. package/skills/pptx/scripts/office/validators/__init__.py +15 -0
  241. package/skills/pptx/scripts/office/validators/base.py +847 -0
  242. package/skills/pptx/scripts/office/validators/docx.py +446 -0
  243. package/skills/pptx/scripts/office/validators/pptx.py +275 -0
  244. package/skills/pptx/scripts/office/validators/redlining.py +247 -0
  245. package/skills/pptx/scripts/thumbnail.py +289 -0
  246. package/skills/skill-creator/LICENSE.txt +202 -0
  247. package/skills/skill-creator/SKILL.md +485 -0
  248. package/skills/skill-creator/VENDORED.md +32 -0
  249. package/skills/skill-creator/agents/analyzer.md +274 -0
  250. package/skills/skill-creator/agents/comparator.md +202 -0
  251. package/skills/skill-creator/agents/grader.md +223 -0
  252. package/skills/skill-creator/assets/eval_review.html +146 -0
  253. package/skills/skill-creator/eval-viewer/generate_review.py +471 -0
  254. package/skills/skill-creator/eval-viewer/viewer.html +1325 -0
  255. package/skills/skill-creator/references/schemas.md +430 -0
  256. package/skills/skill-creator/scripts/__init__.py +0 -0
  257. package/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
  258. package/skills/skill-creator/scripts/generate_report.py +326 -0
  259. package/skills/skill-creator/scripts/improve_description.py +247 -0
  260. package/skills/skill-creator/scripts/package_skill.py +136 -0
  261. package/skills/skill-creator/scripts/quick_validate.py +103 -0
  262. package/skills/skill-creator/scripts/run_eval.py +310 -0
  263. package/skills/skill-creator/scripts/run_loop.py +328 -0
  264. package/skills/skill-creator/scripts/utils.py +47 -0
  265. package/skills/switchroom-architecture/SKILL.md +60 -0
  266. package/skills/switchroom-architecture/cascade.md +112 -0
  267. package/skills/switchroom-architecture/sub-agents.md +87 -0
  268. package/skills/switchroom-architecture/telegram.md +94 -0
  269. package/skills/switchroom-cli/SKILL.md +274 -0
  270. package/skills/switchroom-health/SKILL.md +101 -0
  271. package/skills/switchroom-install/SKILL.md +116 -0
  272. package/skills/switchroom-manage/SKILL.md +90 -0
  273. package/skills/switchroom-status/SKILL.md +69 -0
  274. package/skills/switchroom-status/scripts/status.sh +69 -0
  275. package/skills/telegram-test-harness/SKILL.md +191 -0
  276. package/skills/token-helpers/SKILL.md +73 -0
  277. package/skills/token-helpers/scripts/google-cal-token.sh +62 -0
  278. package/skills/token-helpers/scripts/ms-graph-token.sh +70 -0
  279. package/skills/webapp-testing/LICENSE.txt +202 -0
  280. package/skills/webapp-testing/SKILL.md +96 -0
  281. package/skills/webapp-testing/VENDORED.md +32 -0
  282. package/skills/webapp-testing/examples/console_logging.py +35 -0
  283. package/skills/webapp-testing/examples/element_discovery.py +40 -0
  284. package/skills/webapp-testing/examples/static_html_automation.py +33 -0
  285. package/skills/webapp-testing/scripts/with_server.py +106 -0
  286. package/skills/xlsx/LICENSE.txt +30 -0
  287. package/skills/xlsx/SKILL.md +292 -0
  288. package/skills/xlsx/VENDORED.md +32 -0
  289. package/skills/xlsx/scripts/office/helpers/__init__.py +0 -0
  290. package/skills/xlsx/scripts/office/helpers/merge_runs.py +199 -0
  291. package/skills/xlsx/scripts/office/helpers/simplify_redlines.py +197 -0
  292. package/skills/xlsx/scripts/office/pack.py +159 -0
  293. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  294. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  295. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  296. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  297. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  298. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  299. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  300. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  301. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  302. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  303. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  304. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  305. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  306. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  307. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  308. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  309. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  310. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  311. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  312. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  313. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  314. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  315. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  316. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  317. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  318. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  319. package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  320. package/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  321. package/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  322. package/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  323. package/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  324. package/skills/xlsx/scripts/office/schemas/mce/mc.xsd +75 -0
  325. package/skills/xlsx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
  326. package/skills/xlsx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
  327. package/skills/xlsx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
  328. package/skills/xlsx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
  329. package/skills/xlsx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
  330. package/skills/xlsx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  331. package/skills/xlsx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
  332. package/skills/xlsx/scripts/office/soffice.py +183 -0
  333. package/skills/xlsx/scripts/office/unpack.py +132 -0
  334. package/skills/xlsx/scripts/office/validate.py +111 -0
  335. package/skills/xlsx/scripts/office/validators/__init__.py +15 -0
  336. package/skills/xlsx/scripts/office/validators/base.py +847 -0
  337. package/skills/xlsx/scripts/office/validators/docx.py +446 -0
  338. package/skills/xlsx/scripts/office/validators/pptx.py +275 -0
  339. package/skills/xlsx/scripts/office/validators/redlining.py +247 -0
  340. package/skills/xlsx/scripts/recalc.py +184 -0
  341. package/telegram-plugin/.claude-plugin/plugin.json +20 -0
  342. package/telegram-plugin/.mcp.json +14 -0
  343. package/telegram-plugin/LICENSE +21 -0
  344. package/telegram-plugin/README.md +352 -0
  345. package/telegram-plugin/active-pins-sweep.ts +204 -0
  346. package/telegram-plugin/active-pins.ts +146 -0
  347. package/telegram-plugin/active-reactions-sweep.ts +79 -0
  348. package/telegram-plugin/active-reactions.ts +134 -0
  349. package/telegram-plugin/admin-commands/dispatch.test.ts +149 -0
  350. package/telegram-plugin/admin-commands/index.ts +106 -0
  351. package/telegram-plugin/answer-stream.ts +565 -0
  352. package/telegram-plugin/ask-user.ts +179 -0
  353. package/telegram-plugin/attachment-path.ts +80 -0
  354. package/telegram-plugin/auth-code-redact.ts +83 -0
  355. package/telegram-plugin/auth-dashboard.ts +1104 -0
  356. package/telegram-plugin/auth-slot-parser.ts +497 -0
  357. package/telegram-plugin/auto-fallback-dispatcher.ts +68 -0
  358. package/telegram-plugin/auto-fallback.ts +348 -0
  359. package/telegram-plugin/bridge/bridge.ts +687 -0
  360. package/telegram-plugin/bridge/ipc-client.ts +326 -0
  361. package/telegram-plugin/bun.lock +218 -0
  362. package/telegram-plugin/card-format.ts +62 -0
  363. package/telegram-plugin/channel-envelope-safety.test.ts +56 -0
  364. package/telegram-plugin/channel-envelope-safety.ts +56 -0
  365. package/telegram-plugin/chat-lock.ts +65 -0
  366. package/telegram-plugin/context-exhaustion.ts +38 -0
  367. package/telegram-plugin/credits-watch.ts +220 -0
  368. package/telegram-plugin/dist/bridge/bridge.js +24758 -0
  369. package/telegram-plugin/dist/foreman/foreman.js +30723 -0
  370. package/telegram-plugin/dist/gateway/gateway.js +46497 -0
  371. package/telegram-plugin/dist/server.js +24551 -0
  372. package/telegram-plugin/dm-command-gate.ts +56 -0
  373. package/telegram-plugin/docs/gateway-server-split.md +133 -0
  374. package/telegram-plugin/docs/multi-agent-card-design.md +847 -0
  375. package/telegram-plugin/docs/pinned-progress-card-reliability.md +144 -0
  376. package/telegram-plugin/docs/stream-json-daemon-mode.md +477 -0
  377. package/telegram-plugin/docs/waiting-ux-spec.md +233 -0
  378. package/telegram-plugin/draft-stream.ts +442 -0
  379. package/telegram-plugin/draft-transport.ts +72 -0
  380. package/telegram-plugin/first-paint.ts +246 -0
  381. package/telegram-plugin/fleet-state.ts +246 -0
  382. package/telegram-plugin/foreman/foreman-create-flow.ts +202 -0
  383. package/telegram-plugin/foreman/foreman-handlers.ts +493 -0
  384. package/telegram-plugin/foreman/foreman.ts +1130 -0
  385. package/telegram-plugin/foreman/setup-flow.ts +345 -0
  386. package/telegram-plugin/foreman/setup-state.ts +239 -0
  387. package/telegram-plugin/foreman/state.ts +203 -0
  388. package/telegram-plugin/format.ts +685 -0
  389. package/telegram-plugin/gateway/access-validator.test.ts +95 -0
  390. package/telegram-plugin/gateway/access-validator.ts +37 -0
  391. package/telegram-plugin/gateway/boot-card.ts +582 -0
  392. package/telegram-plugin/gateway/boot-probes.ts +863 -0
  393. package/telegram-plugin/gateway/boot-reason.ts +51 -0
  394. package/telegram-plugin/gateway/boot-sweep-filter.test.ts +54 -0
  395. package/telegram-plugin/gateway/boot-sweep-filter.ts +32 -0
  396. package/telegram-plugin/gateway/clean-shutdown-marker.ts +183 -0
  397. package/telegram-plugin/gateway/disconnect-flush.ts +109 -0
  398. package/telegram-plugin/gateway/gateway.ts +10202 -0
  399. package/telegram-plugin/gateway/inbound-coalesce.ts +147 -0
  400. package/telegram-plugin/gateway/inject-handler.test.ts +221 -0
  401. package/telegram-plugin/gateway/inject-handler.ts +190 -0
  402. package/telegram-plugin/gateway/ipc-protocol.ts +151 -0
  403. package/telegram-plugin/gateway/ipc-server.ts +494 -0
  404. package/telegram-plugin/gateway/pid-file.ts +103 -0
  405. package/telegram-plugin/gateway/poll-health.ts +156 -0
  406. package/telegram-plugin/gateway/preamble-suppressor.ts +154 -0
  407. package/telegram-plugin/gateway/quota-cache.ts +125 -0
  408. package/telegram-plugin/gateway/resolve-calling-subagent.ts +78 -0
  409. package/telegram-plugin/gateway/restart-watchdog.ts +200 -0
  410. package/telegram-plugin/gateway/session-marker.ts +83 -0
  411. package/telegram-plugin/gateway/shutdown-drain.ts +162 -0
  412. package/telegram-plugin/gateway/startup-mutex.ts +285 -0
  413. package/telegram-plugin/gateway/startup-network-retry.ts +142 -0
  414. package/telegram-plugin/gateway/turn-active-marker.ts +176 -0
  415. package/telegram-plugin/gateway/unhandled-rejection-policy.ts +78 -0
  416. package/telegram-plugin/handoff-continuity.ts +200 -0
  417. package/telegram-plugin/history.ts +468 -0
  418. package/telegram-plugin/hooks/hooks.json +58 -0
  419. package/telegram-plugin/hooks/secret-guard-pretool.mjs +208 -0
  420. package/telegram-plugin/hooks/secret-scrub-stop.mjs +98 -0
  421. package/telegram-plugin/hooks/silent-end-interrupt-stop.mjs +111 -0
  422. package/telegram-plugin/hooks/subagent-tracker-posttool.mjs +296 -0
  423. package/telegram-plugin/hooks/subagent-tracker-pretool.mjs +261 -0
  424. package/telegram-plugin/html-sanitize.ts +244 -0
  425. package/telegram-plugin/idle-footer.ts +65 -0
  426. package/telegram-plugin/inline-keyboard-callbacks.ts +166 -0
  427. package/telegram-plugin/interrupt-marker.ts +66 -0
  428. package/telegram-plugin/issues-card.ts +371 -0
  429. package/telegram-plugin/issues-watcher.ts +125 -0
  430. package/telegram-plugin/model-unavailable.ts +325 -0
  431. package/telegram-plugin/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  432. package/telegram-plugin/operator-events-history.ts +94 -0
  433. package/telegram-plugin/operator-events.fixtures.json +161 -0
  434. package/telegram-plugin/operator-events.ts +421 -0
  435. package/telegram-plugin/package.json +55 -0
  436. package/telegram-plugin/permission-rule.ts +133 -0
  437. package/telegram-plugin/permission-title.ts +117 -0
  438. package/telegram-plugin/pin-event-log.ts +76 -0
  439. package/telegram-plugin/plugin-logger.ts +136 -0
  440. package/telegram-plugin/progress-card-driver.ts +2697 -0
  441. package/telegram-plugin/progress-card-pin-manager.ts +589 -0
  442. package/telegram-plugin/progress-card-pin-watchdog.ts +98 -0
  443. package/telegram-plugin/progress-card.ts +1409 -0
  444. package/telegram-plugin/pty-partial-handler.ts +247 -0
  445. package/telegram-plugin/pty-tail.ts +730 -0
  446. package/telegram-plugin/quota-check.ts +474 -0
  447. package/telegram-plugin/recent-outbound-dedup.ts +169 -0
  448. package/telegram-plugin/registry/api-registry.test.ts +201 -0
  449. package/telegram-plugin/registry/subagents-bugs.test.ts +454 -0
  450. package/telegram-plugin/registry/subagents-schema.ts +509 -0
  451. package/telegram-plugin/registry/subagents.test.ts +476 -0
  452. package/telegram-plugin/registry/turns-schema.test.ts +101 -0
  453. package/telegram-plugin/registry/turns-schema.ts +417 -0
  454. package/telegram-plugin/retry-api-call.ts +172 -0
  455. package/telegram-plugin/scripts/build.mjs +78 -0
  456. package/telegram-plugin/secret-detect/audit.ts +66 -0
  457. package/telegram-plugin/secret-detect/chunker.ts +37 -0
  458. package/telegram-plugin/secret-detect/entropy.ts +20 -0
  459. package/telegram-plugin/secret-detect/gitleaks-loader.ts +74 -0
  460. package/telegram-plugin/secret-detect/gitleaks.toml +27 -0
  461. package/telegram-plugin/secret-detect/index.ts +218 -0
  462. package/telegram-plugin/secret-detect/kv-scanner.ts +60 -0
  463. package/telegram-plugin/secret-detect/mask.ts +13 -0
  464. package/telegram-plugin/secret-detect/patterns.ts +115 -0
  465. package/telegram-plugin/secret-detect/pipeline.ts +144 -0
  466. package/telegram-plugin/secret-detect/rewrite.ts +26 -0
  467. package/telegram-plugin/secret-detect/secretlint-source.ts +95 -0
  468. package/telegram-plugin/secret-detect/slug.ts +44 -0
  469. package/telegram-plugin/secret-detect/staging.ts +85 -0
  470. package/telegram-plugin/secret-detect/suppressor.ts +34 -0
  471. package/telegram-plugin/secret-detect/url-redact.ts +60 -0
  472. package/telegram-plugin/secret-detect/vault-write.ts +56 -0
  473. package/telegram-plugin/server.js +41795 -0
  474. package/telegram-plugin/server.ts +171 -0
  475. package/telegram-plugin/session-tail.ts +884 -0
  476. package/telegram-plugin/shared/bot-runtime.ts +324 -0
  477. package/telegram-plugin/silent-reply.ts +58 -0
  478. package/telegram-plugin/slot-banner-driver.ts +147 -0
  479. package/telegram-plugin/slot-banner.ts +86 -0
  480. package/telegram-plugin/start.js +26 -0
  481. package/telegram-plugin/startup-reset.ts +45 -0
  482. package/telegram-plugin/status-reactions.ts +332 -0
  483. package/telegram-plugin/steering.ts +155 -0
  484. package/telegram-plugin/sticker-aliases.ts +249 -0
  485. package/telegram-plugin/stream-controller.ts +311 -0
  486. package/telegram-plugin/stream-reply-handler.ts +664 -0
  487. package/telegram-plugin/streaming-metrics.ts +134 -0
  488. package/telegram-plugin/streaming-report.ts +204 -0
  489. package/telegram-plugin/subagent-watcher.ts +880 -0
  490. package/telegram-plugin/telegram-button-constraints.ts +191 -0
  491. package/telegram-plugin/telegraph.ts +381 -0
  492. package/telegram-plugin/tests/HARNESS.md +340 -0
  493. package/telegram-plugin/tests/_progress-card-harness.ts +105 -0
  494. package/telegram-plugin/tests/active-pins-boot-reaper.test.ts +211 -0
  495. package/telegram-plugin/tests/active-pins-sweep.test.ts +309 -0
  496. package/telegram-plugin/tests/active-pins.test.ts +187 -0
  497. package/telegram-plugin/tests/active-reactions-sweep.test.ts +116 -0
  498. package/telegram-plugin/tests/active-reactions.test.ts +198 -0
  499. package/telegram-plugin/tests/answer-stream-dedup.test.ts +352 -0
  500. package/telegram-plugin/tests/answer-stream-silent-markers.test.ts +236 -0
  501. package/telegram-plugin/tests/answer-stream.test.ts +878 -0
  502. package/telegram-plugin/tests/ask-user.test.ts +203 -0
  503. package/telegram-plugin/tests/attachment-path.test.ts +199 -0
  504. package/telegram-plugin/tests/auth-account-identity-surface.test.ts +118 -0
  505. package/telegram-plugin/tests/auth-code-auto-capture.test.ts +144 -0
  506. package/telegram-plugin/tests/auth-code-redact.test.ts +248 -0
  507. package/telegram-plugin/tests/auth-dashboard-edge-cases.test.ts +260 -0
  508. package/telegram-plugin/tests/auth-dashboard-restart-flow.test.ts +140 -0
  509. package/telegram-plugin/tests/auth-dashboard-v3b.test.ts +559 -0
  510. package/telegram-plugin/tests/auth-dashboard.test.ts +1045 -0
  511. package/telegram-plugin/tests/auth-login-url-button.test.ts +122 -0
  512. package/telegram-plugin/tests/auth-slot-commands.test.ts +640 -0
  513. package/telegram-plugin/tests/auto-fallback-dispatcher.e2e.test.ts +183 -0
  514. package/telegram-plugin/tests/auto-fallback.test.ts +381 -0
  515. package/telegram-plugin/tests/boot-card-account-quota.test.ts +137 -0
  516. package/telegram-plugin/tests/boot-card-dedupe.test.ts +154 -0
  517. package/telegram-plugin/tests/boot-card-probe-target.test.ts +194 -0
  518. package/telegram-plugin/tests/boot-card-reason.test.ts +103 -0
  519. package/telegram-plugin/tests/boot-card-render.test.ts +219 -0
  520. package/telegram-plugin/tests/boot-probes.test.ts +451 -0
  521. package/telegram-plugin/tests/bot-api.harness.ts +116 -0
  522. package/telegram-plugin/tests/bot-runtime.test.ts +190 -0
  523. package/telegram-plugin/tests/bridge-anonymous-refuse.test.ts +60 -0
  524. package/telegram-plugin/tests/context-exhaustion.test.ts +114 -0
  525. package/telegram-plugin/tests/credits-watch.test.ts +221 -0
  526. package/telegram-plugin/tests/dm-command-gate.test.ts +176 -0
  527. package/telegram-plugin/tests/draft-stream.test.ts +752 -0
  528. package/telegram-plugin/tests/draft-transport.test.ts +141 -0
  529. package/telegram-plugin/tests/e2e.test.ts +436 -0
  530. package/telegram-plugin/tests/fake-bot-api.test.ts +213 -0
  531. package/telegram-plugin/tests/fake-bot-api.ts +617 -0
  532. package/telegram-plugin/tests/false-restart-banner.test.ts +253 -0
  533. package/telegram-plugin/tests/first-paint.test.ts +257 -0
  534. package/telegram-plugin/tests/fixtures/pty-tail-tmux-fragment.bin +6 -0
  535. package/telegram-plugin/tests/fixtures/service-log-current-claude-code.bin +3624 -0
  536. package/telegram-plugin/tests/fleet-state-watcher.test.ts +101 -0
  537. package/telegram-plugin/tests/fleet-state.test.ts +185 -0
  538. package/telegram-plugin/tests/foreman-create-flow.test.ts +359 -0
  539. package/telegram-plugin/tests/foreman-handlers.test.ts +347 -0
  540. package/telegram-plugin/tests/foreman-state.test.ts +164 -0
  541. package/telegram-plugin/tests/foreman-write-ops.test.ts +214 -0
  542. package/telegram-plugin/tests/gateway-409-retry-banner.test.ts +173 -0
  543. package/telegram-plugin/tests/gateway-boot-marker-clear.test.ts +72 -0
  544. package/telegram-plugin/tests/gateway-bridge.test.ts +811 -0
  545. package/telegram-plugin/tests/gateway-clean-shutdown-marker.test.ts +414 -0
  546. package/telegram-plugin/tests/gateway-disconnect-flush.test.ts +144 -0
  547. package/telegram-plugin/tests/gateway-message-validator.test.ts +133 -0
  548. package/telegram-plugin/tests/gateway-no-reply-single-emit.test.ts +103 -0
  549. package/telegram-plugin/tests/gateway-secret-detect.test.ts +127 -0
  550. package/telegram-plugin/tests/gateway-startup-mutex.test.ts +284 -0
  551. package/telegram-plugin/tests/gateway-startup-network-retry.test.ts +185 -0
  552. package/telegram-plugin/tests/gateway-startup-reset.test.ts +72 -0
  553. package/telegram-plugin/tests/gateway-update-placeholder-dispatch.test.ts +125 -0
  554. package/telegram-plugin/tests/handoff-continuity.test.ts +249 -0
  555. package/telegram-plugin/tests/harness-ordering-invariants.test.ts +243 -0
  556. package/telegram-plugin/tests/harness-parse-mode-validation.test.ts +114 -0
  557. package/telegram-plugin/tests/history.test.ts +364 -0
  558. package/telegram-plugin/tests/html-balanced.ts +63 -0
  559. package/telegram-plugin/tests/html-sanitize.test.ts +146 -0
  560. package/telegram-plugin/tests/idle-footer-wiring.test.ts +88 -0
  561. package/telegram-plugin/tests/idle-footer.test.ts +66 -0
  562. package/telegram-plugin/tests/inbound-coalesce.test.ts +127 -0
  563. package/telegram-plugin/tests/inline-keyboard-callbacks.test.ts +150 -0
  564. package/telegram-plugin/tests/interrupt-marker.test.ts +126 -0
  565. package/telegram-plugin/tests/ipc-protocol.test.ts +218 -0
  566. package/telegram-plugin/tests/ipc-server-anonymous-refuse.test.ts +82 -0
  567. package/telegram-plugin/tests/ipc-server-client.test.ts +323 -0
  568. package/telegram-plugin/tests/ipc-server-race.test.ts +183 -0
  569. package/telegram-plugin/tests/ipc-server-validate-operator.test.ts +91 -0
  570. package/telegram-plugin/tests/ipc-server-validate-pty-partial.test.ts +64 -0
  571. package/telegram-plugin/tests/ipc-server-validate-update-placeholder.test.ts +77 -0
  572. package/telegram-plugin/tests/ipc-validator.test.ts +274 -0
  573. package/telegram-plugin/tests/issues-card.test.ts +495 -0
  574. package/telegram-plugin/tests/issues-watcher.test.ts +165 -0
  575. package/telegram-plugin/tests/model-unavailable.test.ts +303 -0
  576. package/telegram-plugin/tests/multi-turn-continuity.test.ts +159 -0
  577. package/telegram-plugin/tests/operator-events-history.test.ts +125 -0
  578. package/telegram-plugin/tests/operator-events-session-tail.test.ts +192 -0
  579. package/telegram-plugin/tests/operator-events.test.ts +331 -0
  580. package/telegram-plugin/tests/outbound-ordering.test.ts +293 -0
  581. package/telegram-plugin/tests/parse-mode-rotation.test.ts +164 -0
  582. package/telegram-plugin/tests/permission-rule.test.ts +121 -0
  583. package/telegram-plugin/tests/permission-title.test.ts +106 -0
  584. package/telegram-plugin/tests/pin-event-log.test.ts +124 -0
  585. package/telegram-plugin/tests/plugin-logger.test.ts +97 -0
  586. package/telegram-plugin/tests/poll-health.test.ts +86 -0
  587. package/telegram-plugin/tests/preamble-suppressor.test.ts +285 -0
  588. package/telegram-plugin/tests/progress-card-api-failure-during-deferred.test.ts +73 -0
  589. package/telegram-plugin/tests/progress-card-close-paths-converge.test.ts +272 -0
  590. package/telegram-plugin/tests/progress-card-cross-turn.test.ts +258 -0
  591. package/telegram-plugin/tests/progress-card-dispose-preservepending.test.ts +81 -0
  592. package/telegram-plugin/tests/progress-card-draft-flag.test.ts +80 -0
  593. package/telegram-plugin/tests/progress-card-driver-eviction.test.ts +215 -0
  594. package/telegram-plugin/tests/progress-card-driver-fleet-shadow.test.ts +123 -0
  595. package/telegram-plugin/tests/progress-card-driver-force-complete-parent-done.test.ts +76 -0
  596. package/telegram-plugin/tests/progress-card-edit-timestamps-budget.test.ts +62 -0
  597. package/telegram-plugin/tests/progress-card-memory-bounds.test.ts +84 -0
  598. package/telegram-plugin/tests/progress-card-pin-failure-paths.test.ts +139 -0
  599. package/telegram-plugin/tests/progress-card-pin-manager.test.ts +773 -0
  600. package/telegram-plugin/tests/progress-card-pin-race-fast-turn.test.ts +66 -0
  601. package/telegram-plugin/tests/progress-card-pin-sidecar-partial-write.test.ts +64 -0
  602. package/telegram-plugin/tests/progress-card-pin-watchdog.test.ts +190 -0
  603. package/telegram-plugin/tests/progress-card-sigterm-pin-flush.test.ts +146 -0
  604. package/telegram-plugin/tests/progress-update.test.ts +236 -0
  605. package/telegram-plugin/tests/protocol-fixtures.test.ts +59 -0
  606. package/telegram-plugin/tests/protocol-fixtures.ts +198 -0
  607. package/telegram-plugin/tests/pty-partial-handler.test.ts +326 -0
  608. package/telegram-plugin/tests/pty-tail-real-fixture.test.ts +114 -0
  609. package/telegram-plugin/tests/pty-tail-tmux-fragment.test.ts +71 -0
  610. package/telegram-plugin/tests/pty-tail.test.ts +525 -0
  611. package/telegram-plugin/tests/quota-cache.test.ts +187 -0
  612. package/telegram-plugin/tests/quota-check.test.ts +622 -0
  613. package/telegram-plugin/tests/races.test.ts +842 -0
  614. package/telegram-plugin/tests/real-gateway-f1-ladder-integrity.test.ts +123 -0
  615. package/telegram-plugin/tests/real-gateway-f2-instant-draft.test.ts +82 -0
  616. package/telegram-plugin/tests/real-gateway-f3-late-card.test.ts +114 -0
  617. package/telegram-plugin/tests/real-gateway-harness.ts +699 -0
  618. package/telegram-plugin/tests/real-gateway-i6-turn-flush-replay-dedup.test.ts +313 -0
  619. package/telegram-plugin/tests/real-gateway-ipc-lifecycle.test.ts +299 -0
  620. package/telegram-plugin/tests/real-gateway-spec.test.ts +487 -0
  621. package/telegram-plugin/tests/real-gateway.smoke.test.ts +101 -0
  622. package/telegram-plugin/tests/recent-outbound-dedup.test.ts +192 -0
  623. package/telegram-plugin/tests/registry-turns.test.ts +432 -0
  624. package/telegram-plugin/tests/reply-terminal-reaction.test.ts +149 -0
  625. package/telegram-plugin/tests/resolve-calling-subagent.test.ts +269 -0
  626. package/telegram-plugin/tests/restart-watchdog.test.ts +224 -0
  627. package/telegram-plugin/tests/retry-api-call.test.ts +287 -0
  628. package/telegram-plugin/tests/secret-detect-audit.test.ts +58 -0
  629. package/telegram-plugin/tests/secret-detect-fail-closed.test.ts +83 -0
  630. package/telegram-plugin/tests/secret-detect-gitleaks.test.ts +32 -0
  631. package/telegram-plugin/tests/secret-detect-oauth-code.test.ts +308 -0
  632. package/telegram-plugin/tests/secret-detect-pipeline.test.ts +123 -0
  633. package/telegram-plugin/tests/secret-detect-secretlint.test.ts +101 -0
  634. package/telegram-plugin/tests/secret-detect-staging.test.ts +45 -0
  635. package/telegram-plugin/tests/secret-detect-suppressor-no-silent-allow.test.ts +67 -0
  636. package/telegram-plugin/tests/secret-detect.test.ts +223 -0
  637. package/telegram-plugin/tests/secret-guard-pretool.test.ts +194 -0
  638. package/telegram-plugin/tests/send-typing-action-validation.test.ts +61 -0
  639. package/telegram-plugin/tests/session-tail-capped.test.ts +285 -0
  640. package/telegram-plugin/tests/session-tail.test.ts +524 -0
  641. package/telegram-plugin/tests/setup-flow.test.ts +510 -0
  642. package/telegram-plugin/tests/setup-state.test.ts +146 -0
  643. package/telegram-plugin/tests/silent-reply-guard.test.ts +122 -0
  644. package/telegram-plugin/tests/slot-banner-driver.e2e.test.ts +350 -0
  645. package/telegram-plugin/tests/slot-banner.test.ts +74 -0
  646. package/telegram-plugin/tests/snapshot-serializer.ts +79 -0
  647. package/telegram-plugin/tests/spawn-detached-cgroup-escape.test.ts +51 -0
  648. package/telegram-plugin/tests/status-accent.test.ts +186 -0
  649. package/telegram-plugin/tests/status-reactions-allowed-filter.test.ts +132 -0
  650. package/telegram-plugin/tests/status-reactions.test.ts +314 -0
  651. package/telegram-plugin/tests/steering.test.ts +282 -0
  652. package/telegram-plugin/tests/sticker-aliases.test.ts +232 -0
  653. package/telegram-plugin/tests/stream-controller-html-fallback.test.ts +127 -0
  654. package/telegram-plugin/tests/stream-controller.test.ts +262 -0
  655. package/telegram-plugin/tests/stream-reply-error-paths.test.ts +208 -0
  656. package/telegram-plugin/tests/stream-reply-handler.test.ts +1292 -0
  657. package/telegram-plugin/tests/streaming-e2e.test.ts +389 -0
  658. package/telegram-plugin/tests/streaming-metrics.test.ts +201 -0
  659. package/telegram-plugin/tests/streaming-orchestration.test.ts +756 -0
  660. package/telegram-plugin/tests/subagent-registry-bugs.test.ts +725 -0
  661. package/telegram-plugin/tests/subagent-tracker-hooks.test.ts +213 -0
  662. package/telegram-plugin/tests/subagent-watcher-parent-marker.test.ts +274 -0
  663. package/telegram-plugin/tests/subagent-watcher-stall-notification.test.ts +243 -0
  664. package/telegram-plugin/tests/subagent-watcher.test.ts +877 -0
  665. package/telegram-plugin/tests/subagents-schema-init-order.test.ts +109 -0
  666. package/telegram-plugin/tests/sync-chat-running-subagents.test.ts +116 -0
  667. package/telegram-plugin/tests/telegram-button-constraints.test.ts +194 -0
  668. package/telegram-plugin/tests/telegram-format.test.ts +1093 -0
  669. package/telegram-plugin/tests/telegraph.test.ts +246 -0
  670. package/telegram-plugin/tests/tool-labels.test.ts +383 -0
  671. package/telegram-plugin/tests/turn-active-marker.test.ts +195 -0
  672. package/telegram-plugin/tests/turn-end-regressions.test.ts +489 -0
  673. package/telegram-plugin/tests/turn-flush-card-takeover.test.ts +218 -0
  674. package/telegram-plugin/tests/turn-flush-dedup-controller.test.ts +144 -0
  675. package/telegram-plugin/tests/turn-flush-prose-recovery.test.ts +78 -0
  676. package/telegram-plugin/tests/turn-flush-safety.test.ts +189 -0
  677. package/telegram-plugin/tests/turn-signal-tracker.test.ts +107 -0
  678. package/telegram-plugin/tests/turns-writer.test.ts +323 -0
  679. package/telegram-plugin/tests/two-zone-bg-carry-full-lifecycle.test.ts +131 -0
  680. package/telegram-plugin/tests/two-zone-bg-detection.test.ts +120 -0
  681. package/telegram-plugin/tests/two-zone-bg-done-when-all-terminal.test.ts +114 -0
  682. package/telegram-plugin/tests/two-zone-bg-early-turn-end.test.ts +87 -0
  683. package/telegram-plugin/tests/two-zone-bg-survives-next-turn.test.ts +211 -0
  684. package/telegram-plugin/tests/two-zone-card-cap.test.ts +62 -0
  685. package/telegram-plugin/tests/two-zone-card-fleet-row.test.ts +101 -0
  686. package/telegram-plugin/tests/two-zone-card-header-phases.test.ts +68 -0
  687. package/telegram-plugin/tests/two-zone-card-html-balance.test.ts +110 -0
  688. package/telegram-plugin/tests/two-zone-card-lifecycle.test.ts +128 -0
  689. package/telegram-plugin/tests/two-zone-card-sanitise.test.ts +58 -0
  690. package/telegram-plugin/tests/two-zone-card-snapshot.test.ts +133 -0
  691. package/telegram-plugin/tests/two-zone-concurrent-turns-isolation.test.ts +155 -0
  692. package/telegram-plugin/tests/two-zone-phasefor-precedence.test.ts +117 -0
  693. package/telegram-plugin/tests/two-zone-snapshot-extras.test.ts +143 -0
  694. package/telegram-plugin/tests/two-zone-stuck-edit-throttle.test.ts +149 -0
  695. package/telegram-plugin/tests/two-zone-stuck-header-escalation.test.ts +101 -0
  696. package/telegram-plugin/tests/two-zone-stuck-per-member.test.ts +114 -0
  697. package/telegram-plugin/tests/two-zone-stuck-recovery.test.ts +105 -0
  698. package/telegram-plugin/tests/typing-wrap.test.ts +141 -0
  699. package/telegram-plugin/tests/unhandled-rejection-policy.test.ts +147 -0
  700. package/telegram-plugin/tests/update-factory-edited-and-reactions.test.ts +108 -0
  701. package/telegram-plugin/tests/update-factory.ts +305 -0
  702. package/telegram-plugin/tests/vault-grant-wizard.test.ts +84 -0
  703. package/telegram-plugin/tests/vault-grants-revoke.test.ts +265 -0
  704. package/telegram-plugin/tests/vault-subcommands.test.ts +234 -0
  705. package/telegram-plugin/tests/voice-transcribe.test.ts +196 -0
  706. package/telegram-plugin/tests/waiting-ux-harness.ts +381 -0
  707. package/telegram-plugin/tests/waiting-ux.e2e.test.ts +233 -0
  708. package/telegram-plugin/tests/welcome-text.test.ts +407 -0
  709. package/telegram-plugin/tool-error-filter.ts +89 -0
  710. package/telegram-plugin/tool-labels.ts +330 -0
  711. package/telegram-plugin/tool-names.ts +53 -0
  712. package/telegram-plugin/turn-flush-prose-recovery.ts +40 -0
  713. package/telegram-plugin/turn-flush-safety.ts +109 -0
  714. package/telegram-plugin/turn-signal-tracker.ts +79 -0
  715. package/telegram-plugin/two-zone-card.ts +249 -0
  716. package/telegram-plugin/typing-wrap.ts +92 -0
  717. package/telegram-plugin/voice-transcribe.ts +166 -0
  718. package/telegram-plugin/welcome-text.ts +359 -0
@@ -0,0 +1,305 @@
1
+ /**
2
+ * Typed factories for Telegram Update objects, used by tests that drive
3
+ * a grammy bot via `bot.handleUpdate(update)`.
4
+ *
5
+ * Replaces raw-JSON update construction scattered across test files.
6
+ * Every builder takes a small `overrides` object so tests only have to
7
+ * specify the fields that matter for the behaviour under test; the rest
8
+ * gets sensible realistic defaults (date, message_id sequencing, etc).
9
+ *
10
+ * Shapes follow https://core.telegram.org/bots/api. `as` casts to grammy
11
+ * types are centralized here so the rest of the suite stays typed.
12
+ */
13
+
14
+ import type { Update } from 'grammy/types'
15
+
16
+ let updateIdCounter = 1000
17
+ let messageIdCounter = 2000
18
+
19
+ export function resetUpdateCounters(updateId = 1000, messageId = 2000): void {
20
+ updateIdCounter = updateId
21
+ messageIdCounter = messageId
22
+ }
23
+
24
+ export interface UserLike {
25
+ id: number
26
+ username?: string
27
+ first_name?: string
28
+ is_bot?: boolean
29
+ }
30
+
31
+ export interface ChatLike {
32
+ id: number
33
+ type: 'private' | 'group' | 'supergroup' | 'channel'
34
+ title?: string
35
+ username?: string
36
+ is_forum?: boolean
37
+ }
38
+
39
+ const DEFAULT_USER: UserLike = { id: 777, username: 'test_user', first_name: 'Test' }
40
+ const DEFAULT_PRIVATE_CHAT: ChatLike = { id: 777, type: 'private' }
41
+ const DEFAULT_FORUM_CHAT: ChatLike = {
42
+ id: -100123456789,
43
+ type: 'supergroup',
44
+ title: 'Test Forum',
45
+ is_forum: true,
46
+ }
47
+
48
+ function nowSec(): number { return Math.floor(Date.now() / 1000) }
49
+
50
+ /** Build a text-message Update. */
51
+ export function makeMessageUpdate(opts: {
52
+ text: string
53
+ chat?: Partial<ChatLike>
54
+ from?: Partial<UserLike>
55
+ message_thread_id?: number
56
+ is_topic_message?: boolean
57
+ reply_to_message?: { message_id: number; from?: Partial<UserLike>; text?: string }
58
+ entities?: Array<{ type: string; offset: number; length: number }>
59
+ update_id?: number
60
+ message_id?: number
61
+ }): Update {
62
+ const chat: ChatLike = { ...DEFAULT_PRIVATE_CHAT, ...opts.chat }
63
+ const from: UserLike = { ...DEFAULT_USER, ...opts.from }
64
+ const message_id = opts.message_id ?? messageIdCounter++
65
+ const update_id = opts.update_id ?? updateIdCounter++
66
+
67
+ const reply_to_message = opts.reply_to_message
68
+ ? {
69
+ message_id: opts.reply_to_message.message_id,
70
+ chat,
71
+ from: { ...DEFAULT_USER, ...opts.reply_to_message.from },
72
+ date: nowSec(),
73
+ text: opts.reply_to_message.text ?? '',
74
+ }
75
+ : undefined
76
+
77
+ return {
78
+ update_id,
79
+ message: {
80
+ message_id,
81
+ chat,
82
+ from,
83
+ date: nowSec(),
84
+ text: opts.text,
85
+ ...(opts.message_thread_id != null ? { message_thread_id: opts.message_thread_id } : {}),
86
+ ...(opts.is_topic_message === true ? { is_topic_message: true } : {}),
87
+ ...(opts.entities ? { entities: opts.entities } : {}),
88
+ ...(reply_to_message ? { reply_to_message } : {}),
89
+ },
90
+ } as unknown as Update
91
+ }
92
+
93
+ /** Build a message in a forum topic. */
94
+ export function makeTopicMessageUpdate(opts: {
95
+ text: string
96
+ message_thread_id: number
97
+ chat?: Partial<ChatLike>
98
+ from?: Partial<UserLike>
99
+ }): Update {
100
+ return makeMessageUpdate({
101
+ ...opts,
102
+ chat: { ...DEFAULT_FORUM_CHAT, ...opts.chat },
103
+ is_topic_message: true,
104
+ })
105
+ }
106
+
107
+ /** Build a callback_query Update (inline button tap). */
108
+ export function makeCallbackQueryUpdate(opts: {
109
+ data: string
110
+ chat?: Partial<ChatLike>
111
+ from?: Partial<UserLike>
112
+ inline_message_id?: string
113
+ message_id?: number
114
+ update_id?: number
115
+ }): Update {
116
+ const from: UserLike = { ...DEFAULT_USER, ...opts.from }
117
+ const chat: ChatLike = { ...DEFAULT_PRIVATE_CHAT, ...opts.chat }
118
+ const update_id = opts.update_id ?? updateIdCounter++
119
+ const message_id = opts.message_id ?? messageIdCounter++
120
+ return {
121
+ update_id,
122
+ callback_query: {
123
+ id: 'cbq-' + update_id,
124
+ from,
125
+ chat_instance: 'inst-' + update_id,
126
+ data: opts.data,
127
+ ...(opts.inline_message_id
128
+ ? { inline_message_id: opts.inline_message_id }
129
+ : {
130
+ message: {
131
+ message_id,
132
+ chat,
133
+ date: nowSec(),
134
+ text: '',
135
+ },
136
+ }),
137
+ },
138
+ } as unknown as Update
139
+ }
140
+
141
+ /** Build a my_chat_member Update (bot added/removed). */
142
+ export function makeMyChatMemberUpdate(opts: {
143
+ chat?: Partial<ChatLike>
144
+ from?: Partial<UserLike>
145
+ oldStatus?: 'left' | 'kicked' | 'member' | 'administrator' | 'creator'
146
+ newStatus?: 'left' | 'kicked' | 'member' | 'administrator' | 'creator'
147
+ update_id?: number
148
+ }): Update {
149
+ const chat: ChatLike = { ...DEFAULT_FORUM_CHAT, ...opts.chat }
150
+ const from: UserLike = { ...DEFAULT_USER, ...opts.from }
151
+ const update_id = opts.update_id ?? updateIdCounter++
152
+ const bot: UserLike = { id: 999, username: 'test_bot', first_name: 'TestBot', is_bot: true }
153
+ return {
154
+ update_id,
155
+ my_chat_member: {
156
+ chat,
157
+ from,
158
+ date: nowSec(),
159
+ old_chat_member: {
160
+ user: bot,
161
+ status: opts.oldStatus ?? 'left',
162
+ },
163
+ new_chat_member: {
164
+ user: bot,
165
+ status: opts.newStatus ?? 'administrator',
166
+ },
167
+ },
168
+ } as unknown as Update
169
+ }
170
+
171
+ /** Build a photo-attachment Update. */
172
+ export function makePhotoUpdate(opts: {
173
+ caption?: string
174
+ chat?: Partial<ChatLike>
175
+ from?: Partial<UserLike>
176
+ file_id?: string
177
+ file_size?: number
178
+ }): Update {
179
+ const chat: ChatLike = { ...DEFAULT_PRIVATE_CHAT, ...opts.chat }
180
+ const from: UserLike = { ...DEFAULT_USER, ...opts.from }
181
+ const update_id = updateIdCounter++
182
+ const message_id = messageIdCounter++
183
+ const file_id = opts.file_id ?? 'AgACAgIAAx0C-photo-' + update_id
184
+ const file_size = opts.file_size ?? 54321
185
+ return {
186
+ update_id,
187
+ message: {
188
+ message_id,
189
+ chat,
190
+ from,
191
+ date: nowSec(),
192
+ ...(opts.caption ? { caption: opts.caption } : {}),
193
+ photo: [
194
+ { file_id, file_unique_id: 'unique-' + file_id, file_size, width: 800, height: 600 },
195
+ ],
196
+ },
197
+ } as unknown as Update
198
+ }
199
+
200
+ /** Build an `edited_message` Update — user edits an existing message. */
201
+ export function makeEditedMessageUpdate(opts: {
202
+ message_id: number
203
+ text: string
204
+ chat?: Partial<ChatLike>
205
+ from?: Partial<UserLike>
206
+ message_thread_id?: number
207
+ /** Original send time. Defaults to "30 seconds ago" so edit_date > date stays plausible. */
208
+ date?: number
209
+ /** Edit time. Defaults to now. */
210
+ edit_date?: number
211
+ update_id?: number
212
+ }): Update {
213
+ const chat: ChatLike = { ...DEFAULT_PRIVATE_CHAT, ...opts.chat }
214
+ const from: UserLike = { ...DEFAULT_USER, ...opts.from }
215
+ const update_id = opts.update_id ?? updateIdCounter++
216
+ const date = opts.date ?? nowSec() - 30
217
+ const edit_date = opts.edit_date ?? nowSec()
218
+ return {
219
+ update_id,
220
+ edited_message: {
221
+ message_id: opts.message_id,
222
+ chat,
223
+ from,
224
+ date,
225
+ edit_date,
226
+ text: opts.text,
227
+ ...(opts.message_thread_id != null ? { message_thread_id: opts.message_thread_id } : {}),
228
+ },
229
+ } as unknown as Update
230
+ }
231
+
232
+ /**
233
+ * Build a `message_reaction` Update — a user adds/removes a reaction
234
+ * to a message. Telegram delivers these only if the bot has reactions
235
+ * subscribed (allowed_updates includes "message_reaction").
236
+ *
237
+ * Shape: `old_reaction` and `new_reaction` are arrays of ReactionType
238
+ * objects (`{ type: 'emoji', emoji: '👍' }` for standard, or
239
+ * `{ type: 'custom_emoji', custom_emoji_id: '...' }` for custom).
240
+ *
241
+ * Common usage: a user reacts with 👍 (old=[], new=[👍]) or removes
242
+ * the reaction (old=[👍], new=[]).
243
+ */
244
+ export function makeMessageReactionUpdate(opts: {
245
+ message_id: number
246
+ /** Emoji currently NOT yet on the message (transitioning to). Default: 👍. */
247
+ newEmoji?: string | null
248
+ /** Emoji previously on the message. Default: null (none). */
249
+ oldEmoji?: string | null
250
+ chat?: Partial<ChatLike>
251
+ user?: Partial<UserLike>
252
+ update_id?: number
253
+ }): Update {
254
+ const chat: ChatLike = { ...DEFAULT_PRIVATE_CHAT, ...opts.chat }
255
+ const user: UserLike = { ...DEFAULT_USER, ...opts.user }
256
+ const update_id = opts.update_id ?? updateIdCounter++
257
+ const oldEmoji = opts.oldEmoji ?? null
258
+ const newEmoji = opts.newEmoji === undefined ? '👍' : opts.newEmoji
259
+ const old_reaction = oldEmoji == null ? [] : [{ type: 'emoji', emoji: oldEmoji }]
260
+ const new_reaction = newEmoji == null ? [] : [{ type: 'emoji', emoji: newEmoji }]
261
+ return {
262
+ update_id,
263
+ message_reaction: {
264
+ chat,
265
+ message_id: opts.message_id,
266
+ user,
267
+ date: nowSec(),
268
+ old_reaction,
269
+ new_reaction,
270
+ },
271
+ } as unknown as Update
272
+ }
273
+
274
+ /** Build a document-attachment Update. */
275
+ export function makeDocumentUpdate(opts: {
276
+ file_name: string
277
+ mime_type?: string
278
+ chat?: Partial<ChatLike>
279
+ from?: Partial<UserLike>
280
+ file_id?: string
281
+ file_size?: number
282
+ }): Update {
283
+ const chat: ChatLike = { ...DEFAULT_PRIVATE_CHAT, ...opts.chat }
284
+ const from: UserLike = { ...DEFAULT_USER, ...opts.from }
285
+ const update_id = updateIdCounter++
286
+ const message_id = messageIdCounter++
287
+ const file_id = opts.file_id ?? 'BQACAgIAAx0C-doc-' + update_id
288
+ const file_size = opts.file_size ?? 1024
289
+ return {
290
+ update_id,
291
+ message: {
292
+ message_id,
293
+ chat,
294
+ from,
295
+ date: nowSec(),
296
+ document: {
297
+ file_id,
298
+ file_unique_id: 'unique-' + file_id,
299
+ file_name: opts.file_name,
300
+ mime_type: opts.mime_type ?? 'application/octet-stream',
301
+ file_size,
302
+ },
303
+ },
304
+ } as unknown as Update
305
+ }
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Structural tests for the /vault grant inline-keyboard wizard added in #227.
3
+ *
4
+ * Why structural: gateway/gateway.ts and server.ts do not export the bot
5
+ * command handlers — pure-functional invocation would require a full
6
+ * Grammy/Bot harness. We pin the behaviour at the file level with grep
7
+ * against the source so a regression in either file is caught.
8
+ *
9
+ * Both surfaces are tested in parallel: server.ts (monolith polling
10
+ * mode) and gateway/gateway.ts (split mode). The gateway port landed
11
+ * in PR #262; this file's gateway describe-block was added in
12
+ * follow-up #265.
13
+ */
14
+ import { describe, it, expect } from 'vitest'
15
+ import { readFileSync } from 'node:fs'
16
+ import { join, resolve } from 'node:path'
17
+ import { fileURLToPath } from 'node:url'
18
+
19
+ // Resolve paths relative to the repo root, derived from this test file's
20
+ // own location, instead of process.cwd() — which is brittle across run
21
+ // modes (vitest from repo root vs `bun test` from telegram-plugin/ vs
22
+ // CI's `cd telegram-plugin && bun test`). The repo root is two levels
23
+ // up from this file (telegram-plugin/tests/vault-grant-wizard.test.ts).
24
+ const TEST_DIR = (() => {
25
+ try {
26
+ return resolve(fileURLToPath(import.meta.url), '..')
27
+ } catch {
28
+ return resolve('.')
29
+ }
30
+ })()
31
+ const REPO_ROOT = resolve(TEST_DIR, '..', '..')
32
+
33
+ function readSrc(rel: string): string {
34
+ return readFileSync(join(REPO_ROOT, rel), 'utf8')
35
+ }
36
+
37
+ // #235 Wave 3 F4: server.ts monolith removed; assertions below now live
38
+ // only against gateway.ts (the single source of truth for the wizard).
39
+ // Pre-removal there was a parallel server.ts describe block here; see
40
+ // `telegram-plugin/docs/gateway-server-split.md` for the F4 cleanup notes.
41
+
42
+ describe('/vault grant inline-keyboard wizard — gateway (#227, #262, #265)', () => {
43
+ const gatewaySrc = readSrc('telegram-plugin/gateway/gateway.ts')
44
+
45
+ it('gateway.ts: dispatches /vault grant to the wizard entry', () => {
46
+ expect(gatewaySrc).toMatch(/\/vault grant/i)
47
+ expect(gatewaySrc).toContain("kind: 'grant-wizard'")
48
+ })
49
+
50
+ it('gateway.ts: wizard state-machine has step transitions', () => {
51
+ expect(gatewaySrc).toContain('grantWizardStep3')
52
+ expect(gatewaySrc).toContain('grantWizardConfirm')
53
+ expect(gatewaySrc).toContain('executeGrantWizard')
54
+ })
55
+
56
+ it('gateway.ts: wizard callback prefix vg: is registered', () => {
57
+ expect(gatewaySrc).toContain('vg:')
58
+ })
59
+
60
+ it('gateway.ts: expired-wizard sessions reply with a clear error', () => {
61
+ expect(gatewaySrc).toMatch(/Wizard session expired|Run \/vault grant to start again/i)
62
+ })
63
+
64
+ it('gateway.ts: custom-duration text-reply path exists', () => {
65
+ expect(gatewaySrc).toContain('awaitingCustomDuration')
66
+ })
67
+
68
+ it('gateway.ts: agent name validated before path join (#265 item 1)', () => {
69
+ const slice = gatewaySrc.slice(
70
+ gatewaySrc.indexOf('async function executeGrantWizard'),
71
+ gatewaySrc.indexOf('async function executeGrantWizard') + 4000,
72
+ )
73
+ expect(slice).toMatch(/assertSafeAgentName\(\s*state\.agent/)
74
+ })
75
+
76
+ it('gateway.ts: keys-continue empty branch can show its toast (#265 item 2)', () => {
77
+ const wizardSlice = gatewaySrc.slice(
78
+ gatewaySrc.indexOf("// #227 grant wizard callbacks"),
79
+ gatewaySrc.indexOf("// #227 grant wizard callbacks") + 6000,
80
+ )
81
+ expect(wizardSlice).toContain("Select at least one key.")
82
+ expect(wizardSlice).toContain('const ackSilently')
83
+ })
84
+ })
@@ -0,0 +1,265 @@
1
+ /**
2
+ * Structural tests for the /vault grants list + revoke implementation
3
+ * added in issue #228.
4
+ *
5
+ * Why structural: gateway/gateway.ts and server.ts do not export the bot
6
+ * command handlers, so pure-functional invocation would require a full
7
+ * Grammy/Bot harness. The broker client functions (listGrantsViaBroker,
8
+ * revokeGrantViaBroker) are separately unit-tested in
9
+ * src/vault/broker/server-grants.test.ts. What we pin here is:
10
+ *
11
+ * 1. Both server.ts and gateway/gateway.ts import listGrantsViaBroker and
12
+ * revokeGrantViaBroker from the broker client module.
13
+ * 2. The /vault command handler contains a `grants` branch that calls
14
+ * listGrantsViaBroker.
15
+ * 3. The grants list renders an inline keyboard with vg:revoke:<id> buttons.
16
+ * 4. A callback_query handler intercepts vg: prefixed data in both files.
17
+ * 5. The revoke callback handler invokes revokeGrantViaBroker on vg:confirm.
18
+ * 6. The confirmation flow uses an intermediate vg:confirm/<vg:cancel> card
19
+ * (not immediate revoke on first tap) — two-step confirmation.
20
+ * 7. /vault grants <agent> filter form parses the agent argument.
21
+ * 8. Help text in both files mentions /vault grants.
22
+ * 9. welcome-text.ts /vault section lists the grants subcommand.
23
+ *
24
+ * Each assertion covers BOTH server.ts (monolith polling mode) and
25
+ * gateway/gateway.ts (persistent gateway mode) so a regression in either
26
+ * file is caught.
27
+ */
28
+ import { describe, it, expect } from 'vitest'
29
+ import { readFileSync } from 'node:fs'
30
+ import { fileURLToPath } from 'node:url'
31
+ import { join, dirname } from 'node:path'
32
+
33
+ const __dir = dirname(fileURLToPath(import.meta.url))
34
+ const pluginDir = join(__dir, '..')
35
+
36
+ const gatewaySrc = readFileSync(join(pluginDir, 'gateway', 'gateway.ts'), 'utf8')
37
+
38
+ // ─── helpers ─────────────────────────────────────────────────────────────────
39
+
40
+ /** Slice the source from the first occurrence of `marker` for `len` chars. */
41
+ function sliceFrom(src: string, marker: string, len = 4000): string {
42
+ const idx = src.indexOf(marker)
43
+ if (idx === -1) return ''
44
+ return src.slice(idx, idx + len)
45
+ }
46
+
47
+ /** Returns the portion of `src` inside the `/vault` bot.command() handler. */
48
+ function vaultHandlerBlock(src: string): string {
49
+ const start = src.indexOf("bot.command('vault'")
50
+ if (start === -1) return ''
51
+ const nextCmd = src.indexOf('\nbot.command(', start + 1)
52
+ const end = nextCmd === -1 ? start + 12000 : nextCmd
53
+ return src.slice(start, end)
54
+ }
55
+
56
+ // ─── broker client imports ────────────────────────────────────────────────────
57
+
58
+ describe('/vault grants #228 — broker client imports', () => {
59
+ for (const [label, src] of [['gateway.ts', gatewaySrc]] as const) {
60
+ it(`${label} imports listGrantsViaBroker`, () => {
61
+ expect(src).toMatch(/listGrantsViaBroker/)
62
+ })
63
+
64
+ it(`${label} imports revokeGrantViaBroker`, () => {
65
+ expect(src).toMatch(/revokeGrantViaBroker/)
66
+ })
67
+ }
68
+ })
69
+
70
+ // ─── /vault grants dispatcher ────────────────────────────────────────────────
71
+
72
+ describe('/vault grants — dispatcher entry', () => {
73
+ for (const [label, src] of [['gateway.ts', gatewaySrc]] as const) {
74
+ const block = vaultHandlerBlock(src)
75
+
76
+ it(`${label}: has a grants branch inside the vault handler`, () => {
77
+ expect(block).toMatch(/sub === ['"]grants['"]/)
78
+ })
79
+
80
+ it(`${label}: grants branch calls listGrantsViaBroker`, () => {
81
+ // Use a larger slice (2000) — the keyboard.text('vg:revoke') call comes ~1580 chars in
82
+ const grantsBranch = sliceFrom(block, "sub === 'grants'", 2000)
83
+ expect(grantsBranch).toMatch(/listGrantsViaBroker\(/)
84
+ })
85
+ }
86
+ })
87
+
88
+ // ─── /vault grants — list rendering ──────────────────────────────────────────
89
+
90
+ describe('/vault grants — list rendering wires to list_grants', () => {
91
+ for (const [label, src] of [['gateway.ts', gatewaySrc]] as const) {
92
+ const block = vaultHandlerBlock(src)
93
+
94
+ it(`${label}: renders grouped grants with agent names as headers`, () => {
95
+ const grantsBranch = sliceFrom(block, "sub === 'grants'", 2000)
96
+ // Groups grants by agent_slug and renders agent name as a bold header
97
+ expect(grantsBranch).toMatch(/agent_slug/)
98
+ expect(grantsBranch).toMatch(/byAgent/)
99
+ })
100
+
101
+ it(`${label}: attaches inline keyboard with vg:revoke buttons`, () => {
102
+ // keyboard.text('Revoke', 'vg:revoke:<id>') is ~1580 chars into the grants branch
103
+ const grantsBranch = sliceFrom(block, "sub === 'grants'", 2000)
104
+ expect(grantsBranch).toMatch(/vg:revoke:/)
105
+ expect(grantsBranch).toMatch(/InlineKeyboard/)
106
+ })
107
+
108
+ it(`${label}: handles empty grants list with friendly message`, () => {
109
+ const grantsBranch = sliceFrom(block, "sub === 'grants'", 2000)
110
+ expect(grantsBranch).toMatch(/No active grants/)
111
+ })
112
+
113
+ it(`${label}: handles broker unreachable with error message`, () => {
114
+ const grantsBranch = sliceFrom(block, "sub === 'grants'", 2000)
115
+ expect(grantsBranch).toMatch(/unreachable/i)
116
+ })
117
+ }
118
+ })
119
+
120
+ // ─── /vault grants <agent> — filter form ─────────────────────────────────────
121
+
122
+ describe('/vault grants <agent> — agent filter argument', () => {
123
+ for (const [label, src] of [['gateway.ts', gatewaySrc]] as const) {
124
+ const block = vaultHandlerBlock(src)
125
+
126
+ it(`${label}: parses optional agent argument from args`, () => {
127
+ const grantsBranch = sliceFrom(block, "sub === 'grants'", 2000)
128
+ // Agent filter is read from args[1]
129
+ expect(grantsBranch).toMatch(/args\[1\]/)
130
+ })
131
+
132
+ it(`${label}: passes agentFilter to listGrantsViaBroker`, () => {
133
+ const grantsBranch = sliceFrom(block, "sub === 'grants'", 2000)
134
+ expect(grantsBranch).toMatch(/listGrantsViaBroker\(agentFilter\)/)
135
+ })
136
+
137
+ it(`${label}: filter note appears in empty-grants message when agent filter is set`, () => {
138
+ const grantsBranch = sliceFrom(block, "sub === 'grants'", 2000)
139
+ expect(grantsBranch).toMatch(/filterNote/)
140
+ })
141
+ }
142
+ })
143
+
144
+ // ─── vg: callback dispatch ────────────────────────────────────────────────────
145
+
146
+ describe('vg: callback query handler exists', () => {
147
+ for (const [label, src] of [['gateway.ts', gatewaySrc]] as const) {
148
+ it(`${label}: has a handler block that checks data.startsWith('vg:')`, () => {
149
+ expect(src).toMatch(/data\.startsWith\(['"]vg:['"]\)/)
150
+ })
151
+
152
+ it(`${label}: has a revokeMatch handler for vg:revoke: prefix`, () => {
153
+ // Use 'const revokeMatch' as a specific code marker (not a comment)
154
+ expect(src).toMatch(/const revokeMatch = \/\^vg:revoke:/)
155
+ })
156
+
157
+ it(`${label}: has a confirmMatch handler for vg:confirm: prefix`, () => {
158
+ expect(src).toMatch(/const confirmMatch = \/\^vg:confirm:/)
159
+ })
160
+
161
+ it(`${label}: has a cancelMatch handler for vg:cancel: prefix`, () => {
162
+ expect(src).toMatch(/const cancelMatch = \/\^vg:cancel:/)
163
+ })
164
+ }
165
+ })
166
+
167
+ // ─── revoke callback — invokes revokeGrantViaBroker ──────────────────────────
168
+
169
+ describe('vg:confirm callback invokes revokeGrantViaBroker', () => {
170
+ for (const [label, src] of [['gateway.ts', gatewaySrc]] as const) {
171
+ it(`${label}: vg:confirm branch calls revokeGrantViaBroker with the grant ID`, () => {
172
+ // Use 'const confirmMatch =' as the unique code marker (avoids comment occurrences)
173
+ const confirmArea = sliceFrom(src, 'const confirmMatch = /^vg:confirm:', 800)
174
+ expect(confirmArea).toMatch(/revokeGrantViaBroker\(grantId\)/)
175
+ })
176
+
177
+ it(`${label}: vg:confirm success replies with revoked confirmation text`, () => {
178
+ const confirmArea = sliceFrom(src, 'const confirmMatch = /^vg:confirm:', 800)
179
+ expect(confirmArea).toMatch(/revoked|Revoked/i)
180
+ })
181
+
182
+ it(`${label}: vg:confirm handles broker unreachable`, () => {
183
+ const confirmArea = sliceFrom(src, 'const confirmMatch = /^vg:confirm:', 800)
184
+ expect(confirmArea).toMatch(/unreachable/i)
185
+ })
186
+
187
+ it(`${label}: vg:confirm handles error result from broker`, () => {
188
+ const confirmArea = sliceFrom(src, 'const confirmMatch = /^vg:confirm:', 800)
189
+ expect(confirmArea).toMatch(/Revoke failed/i)
190
+ })
191
+ }
192
+ })
193
+
194
+ // ─── two-step confirmation flow ───────────────────────────────────────────────
195
+
196
+ describe('revoke flow uses two-step confirmation (no immediate revoke on first tap)', () => {
197
+ for (const [label, src] of [['gateway.ts', gatewaySrc]] as const) {
198
+ it(`${label}: vg:revoke tap shows confirmation card, not immediate revoke`, () => {
199
+ // Use 'const revokeMatch =' as the unique code marker
200
+ const revokeArea = sliceFrom(src, 'const revokeMatch = /^vg:revoke:', 1500)
201
+ // Must show a confirmation card with confirm/cancel buttons
202
+ expect(revokeArea).toMatch(/Confirm Revoke|confirm.*revoke/i)
203
+ // Must NOT call revokeGrantViaBroker in the first-tap handler
204
+ // (revokeGrantViaBroker is only called from confirmMatch, which appears later)
205
+ const firstTapArea = sliceFrom(src, 'const revokeMatch = /^vg:revoke:', 900)
206
+ expect(firstTapArea).not.toMatch(/revokeGrantViaBroker/)
207
+ })
208
+
209
+ it(`${label}: confirmation card shows vg:confirm and vg:cancel options`, () => {
210
+ const revokeArea = sliceFrom(src, 'const revokeMatch = /^vg:revoke:', 1500)
211
+ expect(revokeArea).toMatch(/vg:confirm:/)
212
+ expect(revokeArea).toMatch(/vg:cancel:/)
213
+ })
214
+ }
215
+ })
216
+
217
+ // ─── vg:cancel — dismiss without revoke ──────────────────────────────────────
218
+
219
+ describe('vg:cancel dismisses without revoking', () => {
220
+ for (const [label, src] of [['gateway.ts', gatewaySrc]] as const) {
221
+ it(`${label}: vg:cancel does NOT call revokeGrantViaBroker`, () => {
222
+ const cancelArea = sliceFrom(src, 'const cancelMatch = /^vg:cancel:', 500)
223
+ expect(cancelArea).not.toMatch(/revokeGrantViaBroker/)
224
+ })
225
+
226
+ it(`${label}: vg:cancel clears the inline keyboard`, () => {
227
+ const cancelArea = sliceFrom(src, 'const cancelMatch = /^vg:cancel:', 500)
228
+ expect(cancelArea).toMatch(/editMessageReplyMarkup|inline_keyboard/)
229
+ })
230
+ }
231
+ })
232
+
233
+ // ─── help text ───────────────────────────────────────────────────────────────
234
+
235
+ describe('/vault help text includes grants subcommand', () => {
236
+ for (const [label, src] of [['gateway.ts', gatewaySrc]] as const) {
237
+ const block = vaultHandlerBlock(src)
238
+
239
+ it(`${label}: /vault help lists grants subcommand`, () => {
240
+ const helpBranch = sliceFrom(block, "sub === 'help'", 1200)
241
+ expect(helpBranch).toMatch(/grants/)
242
+ })
243
+
244
+ it(`${label}: grants help entry mentions agent filter or 'tap to revoke'`, () => {
245
+ const helpBranch = sliceFrom(block, "sub === 'help'", 1200)
246
+ expect(helpBranch).toMatch(/revoke|agent/i)
247
+ })
248
+ }
249
+ })
250
+
251
+ // ─── switchroomHelpText (welcome-text.ts) ────────────────────────────────────
252
+
253
+ describe('switchroomHelpText — /vault grants entry', () => {
254
+ it('lists vault grants as a separate entry', async () => {
255
+ const { switchroomHelpText } = await import('../welcome-text.js')
256
+ const out = switchroomHelpText('assistant')
257
+ expect(out).toMatch(/vault.*grants/i)
258
+ })
259
+
260
+ it('grants entry mentions revoke capability', async () => {
261
+ const { switchroomHelpText } = await import('../welcome-text.js')
262
+ const out = switchroomHelpText('assistant')
263
+ expect(out).toMatch(/revoke/i)
264
+ })
265
+ })