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.
- package/LICENSE +21 -0
- package/README.md +447 -0
- package/bin/autoaccept.exp +81 -0
- package/bin/boot-self-test.sh +149 -0
- package/bin/bridge-watchdog.sh +967 -0
- package/bin/handoff-briefing.sh +206 -0
- package/bin/run-hook.sh +228 -0
- package/bin/switchroom.ts +4 -0
- package/bin/timezone-hook.sh +67 -0
- package/bin/user-profile-refresh-hook.sh +38 -0
- package/bin/workspace-dynamic-hook.sh +142 -0
- package/bin/workspace-stable-hook.sh +57 -0
- package/dist/cli/autoaccept-poll.js +118 -0
- package/dist/cli/switchroom.js +48557 -0
- package/package.json +95 -0
- package/profiles/_base/settings.json.hbs +15 -0
- package/profiles/_base/start.sh.hbs +383 -0
- package/profiles/_shared/telegram-style.md.hbs +140 -0
- package/profiles/coding/CLAUDE.md.hbs +57 -0
- package/profiles/coding/skills/architecture/SKILL.md +70 -0
- package/profiles/coding/skills/code-review/SKILL.md +58 -0
- package/profiles/coding/workspace/SOUL.md.hbs +25 -0
- package/profiles/default/CLAUDE.md +238 -0
- package/profiles/default/CLAUDE.md.hbs +113 -0
- package/profiles/default/workspace/CLAUDE.md.hbs +126 -0
- package/profiles/default/workspace/HEARTBEAT.md.hbs +40 -0
- package/profiles/default/workspace/IDENTITY.md.hbs +32 -0
- package/profiles/default/workspace/MEMORY.md.hbs +29 -0
- package/profiles/default/workspace/SOUL.md.hbs +61 -0
- package/profiles/default/workspace/TOOLS.md.hbs +29 -0
- package/profiles/default/workspace/USER.md.hbs +52 -0
- package/profiles/default/workspace/memory/.gitkeep +0 -0
- package/profiles/executive-assistant/CLAUDE.md.hbs +51 -0
- package/profiles/executive-assistant/skills/daily-briefing/SKILL.md +55 -0
- package/profiles/executive-assistant/skills/meeting-prep/SKILL.md +58 -0
- package/profiles/executive-assistant/workspace/SOUL.md.hbs +25 -0
- package/profiles/health-coach/CLAUDE.md.hbs +45 -0
- package/profiles/health-coach/skills/check-in/SKILL.md +41 -0
- package/profiles/health-coach/skills/weekly-review/SKILL.md +53 -0
- package/profiles/health-coach/workspace/SOUL.md.hbs +25 -0
- package/skills/buildkite-agent-infrastructure/SKILL.md +302 -0
- package/skills/buildkite-agent-infrastructure/agents/openai.yaml +6 -0
- package/skills/buildkite-agent-infrastructure/assets/buildkite-icon-large.png +0 -0
- package/skills/buildkite-agent-infrastructure/assets/buildkite-icon-small.png +0 -0
- package/skills/buildkite-agent-infrastructure/references/audit-logging.md +87 -0
- package/skills/buildkite-agent-infrastructure/references/graphql-mutations.md +690 -0
- package/skills/buildkite-agent-infrastructure/references/instance-shapes.md +38 -0
- package/skills/buildkite-agent-infrastructure/references/pipeline-templates.md +73 -0
- package/skills/buildkite-agent-infrastructure/references/self-hosted-agents.md +137 -0
- package/skills/buildkite-agent-infrastructure/references/sso-saml.md +92 -0
- package/skills/buildkite-agent-runtime/SKILL.md +476 -0
- package/skills/buildkite-agent-runtime/agents/openai.yaml +6 -0
- package/skills/buildkite-agent-runtime/assets/buildkite-icon-large.png +0 -0
- package/skills/buildkite-agent-runtime/assets/buildkite-icon-small.png +0 -0
- package/skills/buildkite-agent-runtime/references/flag-reference.md +417 -0
- package/skills/buildkite-agent-runtime/references/patterns-and-recipes.md +555 -0
- package/skills/buildkite-api/SKILL.md +285 -0
- package/skills/buildkite-api/agents/openai.yaml +6 -0
- package/skills/buildkite-api/assets/buildkite-icon-large.png +0 -0
- package/skills/buildkite-api/assets/buildkite-icon-small.png +0 -0
- package/skills/buildkite-api/references/graphql-reference.md +195 -0
- package/skills/buildkite-api/references/patterns.md +44 -0
- package/skills/buildkite-api/references/webhooks.md +161 -0
- package/skills/buildkite-cli/SKILL.md +379 -0
- package/skills/buildkite-cli/agents/openai.yaml +6 -0
- package/skills/buildkite-cli/assets/buildkite-icon-large.png +0 -0
- package/skills/buildkite-cli/assets/buildkite-icon-small.png +0 -0
- package/skills/buildkite-cli/references/command-reference.md +181 -0
- package/skills/buildkite-migration/SKILL.md +182 -0
- package/skills/buildkite-pipelines/SKILL.md +464 -0
- package/skills/buildkite-pipelines/agents/openai.yaml +6 -0
- package/skills/buildkite-pipelines/assets/buildkite-icon-large.png +0 -0
- package/skills/buildkite-pipelines/assets/buildkite-icon-small.png +0 -0
- package/skills/buildkite-pipelines/examples/basic-pipeline.yml +24 -0
- package/skills/buildkite-pipelines/examples/optimized-pipeline.yml +100 -0
- package/skills/buildkite-pipelines/references/advanced-patterns.md +286 -0
- package/skills/buildkite-pipelines/references/retry-and-error-codes.md +131 -0
- package/skills/buildkite-pipelines/references/step-types-reference.md +225 -0
- package/skills/buildkite-secure-delivery/SKILL.md +168 -0
- package/skills/buildkite-secure-delivery/agents/openai.yaml +6 -0
- package/skills/buildkite-secure-delivery/assets/buildkite-icon-large.png +0 -0
- package/skills/buildkite-secure-delivery/assets/buildkite-icon-small.png +0 -0
- package/skills/buildkite-secure-delivery/references/oidc-cloud-providers.md +83 -0
- package/skills/buildkite-secure-delivery/references/package-publishing.md +100 -0
- package/skills/buildkite-test-engine/SKILL.md +239 -0
- package/skills/buildkite-test-engine/agents/openai.yaml +6 -0
- package/skills/buildkite-test-engine/assets/buildkite-icon-large.png +0 -0
- package/skills/buildkite-test-engine/assets/buildkite-icon-small.png +0 -0
- package/skills/buildkite-test-engine/examples/bktec-splitting.yml +16 -0
- package/skills/buildkite-test-engine/examples/collector-pipeline.yml +11 -0
- package/skills/buildkite-test-engine/references/collectors.md +198 -0
- package/skills/buildkite-test-engine/references/splitting-examples.md +93 -0
- package/skills/docx/LICENSE.txt +30 -0
- package/skills/docx/SKILL.md +590 -0
- package/skills/docx/VENDORED.md +32 -0
- package/skills/docx/scripts/__init__.py +1 -0
- package/skills/docx/scripts/accept_changes.py +135 -0
- package/skills/docx/scripts/comment.py +318 -0
- package/skills/docx/scripts/office/helpers/__init__.py +0 -0
- package/skills/docx/scripts/office/helpers/merge_runs.py +199 -0
- package/skills/docx/scripts/office/helpers/simplify_redlines.py +197 -0
- package/skills/docx/scripts/office/pack.py +159 -0
- package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/skills/docx/scripts/office/schemas/mce/mc.xsd +75 -0
- package/skills/docx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
- package/skills/docx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
- package/skills/docx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
- package/skills/docx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/skills/docx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/skills/docx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/skills/docx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/skills/docx/scripts/office/soffice.py +183 -0
- package/skills/docx/scripts/office/unpack.py +132 -0
- package/skills/docx/scripts/office/validate.py +111 -0
- package/skills/docx/scripts/office/validators/__init__.py +15 -0
- package/skills/docx/scripts/office/validators/__pycache__/__init__.cpython-313.pyc +0 -0
- package/skills/docx/scripts/office/validators/__pycache__/base.cpython-313.pyc +0 -0
- package/skills/docx/scripts/office/validators/base.py +847 -0
- package/skills/docx/scripts/office/validators/docx.py +446 -0
- package/skills/docx/scripts/office/validators/pptx.py +275 -0
- package/skills/docx/scripts/office/validators/redlining.py +247 -0
- package/skills/docx/scripts/templates/comments.xml +3 -0
- package/skills/docx/scripts/templates/commentsExtended.xml +3 -0
- package/skills/docx/scripts/templates/commentsExtensible.xml +3 -0
- package/skills/docx/scripts/templates/commentsIds.xml +3 -0
- package/skills/docx/scripts/templates/people.xml +3 -0
- package/skills/file-bug/SKILL.md +129 -0
- package/skills/humanizer/LICENSE +21 -0
- package/skills/humanizer/SKILL.md +559 -0
- package/skills/humanizer/VENDORED.md +38 -0
- package/skills/humanizer-calibrate/SKILL.md +144 -0
- package/skills/mcp-builder/LICENSE.txt +202 -0
- package/skills/mcp-builder/SKILL.md +236 -0
- package/skills/mcp-builder/VENDORED.md +32 -0
- package/skills/mcp-builder/reference/evaluation.md +602 -0
- package/skills/mcp-builder/reference/mcp_best_practices.md +249 -0
- package/skills/mcp-builder/reference/node_mcp_server.md +970 -0
- package/skills/mcp-builder/reference/python_mcp_server.md +719 -0
- package/skills/mcp-builder/scripts/connections.py +151 -0
- package/skills/mcp-builder/scripts/evaluation.py +373 -0
- package/skills/mcp-builder/scripts/example_evaluation.xml +22 -0
- package/skills/mcp-builder/scripts/requirements.txt +2 -0
- package/skills/pdf/LICENSE.txt +30 -0
- package/skills/pdf/SKILL.md +314 -0
- package/skills/pdf/VENDORED.md +32 -0
- package/skills/pdf/forms.md +294 -0
- package/skills/pdf/reference.md +612 -0
- package/skills/pdf/scripts/check_bounding_boxes.py +65 -0
- package/skills/pdf/scripts/check_fillable_fields.py +11 -0
- package/skills/pdf/scripts/convert_pdf_to_images.py +33 -0
- package/skills/pdf/scripts/create_validation_image.py +37 -0
- package/skills/pdf/scripts/extract_form_field_info.py +122 -0
- package/skills/pdf/scripts/extract_form_structure.py +115 -0
- package/skills/pdf/scripts/fill_fillable_fields.py +98 -0
- package/skills/pdf/scripts/fill_pdf_form_with_annotations.py +107 -0
- package/skills/pptx/LICENSE.txt +30 -0
- package/skills/pptx/SKILL.md +232 -0
- package/skills/pptx/VENDORED.md +32 -0
- package/skills/pptx/editing.md +205 -0
- package/skills/pptx/pptxgenjs.md +420 -0
- package/skills/pptx/scripts/__init__.py +0 -0
- package/skills/pptx/scripts/add_slide.py +195 -0
- package/skills/pptx/scripts/clean.py +286 -0
- package/skills/pptx/scripts/office/helpers/__init__.py +0 -0
- package/skills/pptx/scripts/office/helpers/merge_runs.py +199 -0
- package/skills/pptx/scripts/office/helpers/simplify_redlines.py +197 -0
- package/skills/pptx/scripts/office/pack.py +159 -0
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/skills/pptx/scripts/office/schemas/mce/mc.xsd +75 -0
- package/skills/pptx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
- package/skills/pptx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
- package/skills/pptx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
- package/skills/pptx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/skills/pptx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/skills/pptx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/skills/pptx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/skills/pptx/scripts/office/soffice.py +183 -0
- package/skills/pptx/scripts/office/unpack.py +132 -0
- package/skills/pptx/scripts/office/validate.py +111 -0
- package/skills/pptx/scripts/office/validators/__init__.py +15 -0
- package/skills/pptx/scripts/office/validators/base.py +847 -0
- package/skills/pptx/scripts/office/validators/docx.py +446 -0
- package/skills/pptx/scripts/office/validators/pptx.py +275 -0
- package/skills/pptx/scripts/office/validators/redlining.py +247 -0
- package/skills/pptx/scripts/thumbnail.py +289 -0
- package/skills/skill-creator/LICENSE.txt +202 -0
- package/skills/skill-creator/SKILL.md +485 -0
- package/skills/skill-creator/VENDORED.md +32 -0
- package/skills/skill-creator/agents/analyzer.md +274 -0
- package/skills/skill-creator/agents/comparator.md +202 -0
- package/skills/skill-creator/agents/grader.md +223 -0
- package/skills/skill-creator/assets/eval_review.html +146 -0
- package/skills/skill-creator/eval-viewer/generate_review.py +471 -0
- package/skills/skill-creator/eval-viewer/viewer.html +1325 -0
- package/skills/skill-creator/references/schemas.md +430 -0
- package/skills/skill-creator/scripts/__init__.py +0 -0
- package/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
- package/skills/skill-creator/scripts/generate_report.py +326 -0
- package/skills/skill-creator/scripts/improve_description.py +247 -0
- package/skills/skill-creator/scripts/package_skill.py +136 -0
- package/skills/skill-creator/scripts/quick_validate.py +103 -0
- package/skills/skill-creator/scripts/run_eval.py +310 -0
- package/skills/skill-creator/scripts/run_loop.py +328 -0
- package/skills/skill-creator/scripts/utils.py +47 -0
- package/skills/switchroom-architecture/SKILL.md +60 -0
- package/skills/switchroom-architecture/cascade.md +112 -0
- package/skills/switchroom-architecture/sub-agents.md +87 -0
- package/skills/switchroom-architecture/telegram.md +94 -0
- package/skills/switchroom-cli/SKILL.md +274 -0
- package/skills/switchroom-health/SKILL.md +101 -0
- package/skills/switchroom-install/SKILL.md +116 -0
- package/skills/switchroom-manage/SKILL.md +90 -0
- package/skills/switchroom-status/SKILL.md +69 -0
- package/skills/switchroom-status/scripts/status.sh +69 -0
- package/skills/telegram-test-harness/SKILL.md +191 -0
- package/skills/token-helpers/SKILL.md +73 -0
- package/skills/token-helpers/scripts/google-cal-token.sh +62 -0
- package/skills/token-helpers/scripts/ms-graph-token.sh +70 -0
- package/skills/webapp-testing/LICENSE.txt +202 -0
- package/skills/webapp-testing/SKILL.md +96 -0
- package/skills/webapp-testing/VENDORED.md +32 -0
- package/skills/webapp-testing/examples/console_logging.py +35 -0
- package/skills/webapp-testing/examples/element_discovery.py +40 -0
- package/skills/webapp-testing/examples/static_html_automation.py +33 -0
- package/skills/webapp-testing/scripts/with_server.py +106 -0
- package/skills/xlsx/LICENSE.txt +30 -0
- package/skills/xlsx/SKILL.md +292 -0
- package/skills/xlsx/VENDORED.md +32 -0
- package/skills/xlsx/scripts/office/helpers/__init__.py +0 -0
- package/skills/xlsx/scripts/office/helpers/merge_runs.py +199 -0
- package/skills/xlsx/scripts/office/helpers/simplify_redlines.py +197 -0
- package/skills/xlsx/scripts/office/pack.py +159 -0
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/skills/xlsx/scripts/office/schemas/mce/mc.xsd +75 -0
- package/skills/xlsx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
- package/skills/xlsx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
- package/skills/xlsx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
- package/skills/xlsx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/skills/xlsx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/skills/xlsx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/skills/xlsx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/skills/xlsx/scripts/office/soffice.py +183 -0
- package/skills/xlsx/scripts/office/unpack.py +132 -0
- package/skills/xlsx/scripts/office/validate.py +111 -0
- package/skills/xlsx/scripts/office/validators/__init__.py +15 -0
- package/skills/xlsx/scripts/office/validators/base.py +847 -0
- package/skills/xlsx/scripts/office/validators/docx.py +446 -0
- package/skills/xlsx/scripts/office/validators/pptx.py +275 -0
- package/skills/xlsx/scripts/office/validators/redlining.py +247 -0
- package/skills/xlsx/scripts/recalc.py +184 -0
- package/telegram-plugin/.claude-plugin/plugin.json +20 -0
- package/telegram-plugin/.mcp.json +14 -0
- package/telegram-plugin/LICENSE +21 -0
- package/telegram-plugin/README.md +352 -0
- package/telegram-plugin/active-pins-sweep.ts +204 -0
- package/telegram-plugin/active-pins.ts +146 -0
- package/telegram-plugin/active-reactions-sweep.ts +79 -0
- package/telegram-plugin/active-reactions.ts +134 -0
- package/telegram-plugin/admin-commands/dispatch.test.ts +149 -0
- package/telegram-plugin/admin-commands/index.ts +106 -0
- package/telegram-plugin/answer-stream.ts +565 -0
- package/telegram-plugin/ask-user.ts +179 -0
- package/telegram-plugin/attachment-path.ts +80 -0
- package/telegram-plugin/auth-code-redact.ts +83 -0
- package/telegram-plugin/auth-dashboard.ts +1104 -0
- package/telegram-plugin/auth-slot-parser.ts +497 -0
- package/telegram-plugin/auto-fallback-dispatcher.ts +68 -0
- package/telegram-plugin/auto-fallback.ts +348 -0
- package/telegram-plugin/bridge/bridge.ts +687 -0
- package/telegram-plugin/bridge/ipc-client.ts +326 -0
- package/telegram-plugin/bun.lock +218 -0
- package/telegram-plugin/card-format.ts +62 -0
- package/telegram-plugin/channel-envelope-safety.test.ts +56 -0
- package/telegram-plugin/channel-envelope-safety.ts +56 -0
- package/telegram-plugin/chat-lock.ts +65 -0
- package/telegram-plugin/context-exhaustion.ts +38 -0
- package/telegram-plugin/credits-watch.ts +220 -0
- package/telegram-plugin/dist/bridge/bridge.js +24758 -0
- package/telegram-plugin/dist/foreman/foreman.js +30723 -0
- package/telegram-plugin/dist/gateway/gateway.js +46497 -0
- package/telegram-plugin/dist/server.js +24551 -0
- package/telegram-plugin/dm-command-gate.ts +56 -0
- package/telegram-plugin/docs/gateway-server-split.md +133 -0
- package/telegram-plugin/docs/multi-agent-card-design.md +847 -0
- package/telegram-plugin/docs/pinned-progress-card-reliability.md +144 -0
- package/telegram-plugin/docs/stream-json-daemon-mode.md +477 -0
- package/telegram-plugin/docs/waiting-ux-spec.md +233 -0
- package/telegram-plugin/draft-stream.ts +442 -0
- package/telegram-plugin/draft-transport.ts +72 -0
- package/telegram-plugin/first-paint.ts +246 -0
- package/telegram-plugin/fleet-state.ts +246 -0
- package/telegram-plugin/foreman/foreman-create-flow.ts +202 -0
- package/telegram-plugin/foreman/foreman-handlers.ts +493 -0
- package/telegram-plugin/foreman/foreman.ts +1130 -0
- package/telegram-plugin/foreman/setup-flow.ts +345 -0
- package/telegram-plugin/foreman/setup-state.ts +239 -0
- package/telegram-plugin/foreman/state.ts +203 -0
- package/telegram-plugin/format.ts +685 -0
- package/telegram-plugin/gateway/access-validator.test.ts +95 -0
- package/telegram-plugin/gateway/access-validator.ts +37 -0
- package/telegram-plugin/gateway/boot-card.ts +582 -0
- package/telegram-plugin/gateway/boot-probes.ts +863 -0
- package/telegram-plugin/gateway/boot-reason.ts +51 -0
- package/telegram-plugin/gateway/boot-sweep-filter.test.ts +54 -0
- package/telegram-plugin/gateway/boot-sweep-filter.ts +32 -0
- package/telegram-plugin/gateway/clean-shutdown-marker.ts +183 -0
- package/telegram-plugin/gateway/disconnect-flush.ts +109 -0
- package/telegram-plugin/gateway/gateway.ts +10202 -0
- package/telegram-plugin/gateway/inbound-coalesce.ts +147 -0
- package/telegram-plugin/gateway/inject-handler.test.ts +221 -0
- package/telegram-plugin/gateway/inject-handler.ts +190 -0
- package/telegram-plugin/gateway/ipc-protocol.ts +151 -0
- package/telegram-plugin/gateway/ipc-server.ts +494 -0
- package/telegram-plugin/gateway/pid-file.ts +103 -0
- package/telegram-plugin/gateway/poll-health.ts +156 -0
- package/telegram-plugin/gateway/preamble-suppressor.ts +154 -0
- package/telegram-plugin/gateway/quota-cache.ts +125 -0
- package/telegram-plugin/gateway/resolve-calling-subagent.ts +78 -0
- package/telegram-plugin/gateway/restart-watchdog.ts +200 -0
- package/telegram-plugin/gateway/session-marker.ts +83 -0
- package/telegram-plugin/gateway/shutdown-drain.ts +162 -0
- package/telegram-plugin/gateway/startup-mutex.ts +285 -0
- package/telegram-plugin/gateway/startup-network-retry.ts +142 -0
- package/telegram-plugin/gateway/turn-active-marker.ts +176 -0
- package/telegram-plugin/gateway/unhandled-rejection-policy.ts +78 -0
- package/telegram-plugin/handoff-continuity.ts +200 -0
- package/telegram-plugin/history.ts +468 -0
- package/telegram-plugin/hooks/hooks.json +58 -0
- package/telegram-plugin/hooks/secret-guard-pretool.mjs +208 -0
- package/telegram-plugin/hooks/secret-scrub-stop.mjs +98 -0
- package/telegram-plugin/hooks/silent-end-interrupt-stop.mjs +111 -0
- package/telegram-plugin/hooks/subagent-tracker-posttool.mjs +296 -0
- package/telegram-plugin/hooks/subagent-tracker-pretool.mjs +261 -0
- package/telegram-plugin/html-sanitize.ts +244 -0
- package/telegram-plugin/idle-footer.ts +65 -0
- package/telegram-plugin/inline-keyboard-callbacks.ts +166 -0
- package/telegram-plugin/interrupt-marker.ts +66 -0
- package/telegram-plugin/issues-card.ts +371 -0
- package/telegram-plugin/issues-watcher.ts +125 -0
- package/telegram-plugin/model-unavailable.ts +325 -0
- package/telegram-plugin/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/telegram-plugin/operator-events-history.ts +94 -0
- package/telegram-plugin/operator-events.fixtures.json +161 -0
- package/telegram-plugin/operator-events.ts +421 -0
- package/telegram-plugin/package.json +55 -0
- package/telegram-plugin/permission-rule.ts +133 -0
- package/telegram-plugin/permission-title.ts +117 -0
- package/telegram-plugin/pin-event-log.ts +76 -0
- package/telegram-plugin/plugin-logger.ts +136 -0
- package/telegram-plugin/progress-card-driver.ts +2697 -0
- package/telegram-plugin/progress-card-pin-manager.ts +589 -0
- package/telegram-plugin/progress-card-pin-watchdog.ts +98 -0
- package/telegram-plugin/progress-card.ts +1409 -0
- package/telegram-plugin/pty-partial-handler.ts +247 -0
- package/telegram-plugin/pty-tail.ts +730 -0
- package/telegram-plugin/quota-check.ts +474 -0
- package/telegram-plugin/recent-outbound-dedup.ts +169 -0
- package/telegram-plugin/registry/api-registry.test.ts +201 -0
- package/telegram-plugin/registry/subagents-bugs.test.ts +454 -0
- package/telegram-plugin/registry/subagents-schema.ts +509 -0
- package/telegram-plugin/registry/subagents.test.ts +476 -0
- package/telegram-plugin/registry/turns-schema.test.ts +101 -0
- package/telegram-plugin/registry/turns-schema.ts +417 -0
- package/telegram-plugin/retry-api-call.ts +172 -0
- package/telegram-plugin/scripts/build.mjs +78 -0
- package/telegram-plugin/secret-detect/audit.ts +66 -0
- package/telegram-plugin/secret-detect/chunker.ts +37 -0
- package/telegram-plugin/secret-detect/entropy.ts +20 -0
- package/telegram-plugin/secret-detect/gitleaks-loader.ts +74 -0
- package/telegram-plugin/secret-detect/gitleaks.toml +27 -0
- package/telegram-plugin/secret-detect/index.ts +218 -0
- package/telegram-plugin/secret-detect/kv-scanner.ts +60 -0
- package/telegram-plugin/secret-detect/mask.ts +13 -0
- package/telegram-plugin/secret-detect/patterns.ts +115 -0
- package/telegram-plugin/secret-detect/pipeline.ts +144 -0
- package/telegram-plugin/secret-detect/rewrite.ts +26 -0
- package/telegram-plugin/secret-detect/secretlint-source.ts +95 -0
- package/telegram-plugin/secret-detect/slug.ts +44 -0
- package/telegram-plugin/secret-detect/staging.ts +85 -0
- package/telegram-plugin/secret-detect/suppressor.ts +34 -0
- package/telegram-plugin/secret-detect/url-redact.ts +60 -0
- package/telegram-plugin/secret-detect/vault-write.ts +56 -0
- package/telegram-plugin/server.js +41795 -0
- package/telegram-plugin/server.ts +171 -0
- package/telegram-plugin/session-tail.ts +884 -0
- package/telegram-plugin/shared/bot-runtime.ts +324 -0
- package/telegram-plugin/silent-reply.ts +58 -0
- package/telegram-plugin/slot-banner-driver.ts +147 -0
- package/telegram-plugin/slot-banner.ts +86 -0
- package/telegram-plugin/start.js +26 -0
- package/telegram-plugin/startup-reset.ts +45 -0
- package/telegram-plugin/status-reactions.ts +332 -0
- package/telegram-plugin/steering.ts +155 -0
- package/telegram-plugin/sticker-aliases.ts +249 -0
- package/telegram-plugin/stream-controller.ts +311 -0
- package/telegram-plugin/stream-reply-handler.ts +664 -0
- package/telegram-plugin/streaming-metrics.ts +134 -0
- package/telegram-plugin/streaming-report.ts +204 -0
- package/telegram-plugin/subagent-watcher.ts +880 -0
- package/telegram-plugin/telegram-button-constraints.ts +191 -0
- package/telegram-plugin/telegraph.ts +381 -0
- package/telegram-plugin/tests/HARNESS.md +340 -0
- package/telegram-plugin/tests/_progress-card-harness.ts +105 -0
- package/telegram-plugin/tests/active-pins-boot-reaper.test.ts +211 -0
- package/telegram-plugin/tests/active-pins-sweep.test.ts +309 -0
- package/telegram-plugin/tests/active-pins.test.ts +187 -0
- package/telegram-plugin/tests/active-reactions-sweep.test.ts +116 -0
- package/telegram-plugin/tests/active-reactions.test.ts +198 -0
- package/telegram-plugin/tests/answer-stream-dedup.test.ts +352 -0
- package/telegram-plugin/tests/answer-stream-silent-markers.test.ts +236 -0
- package/telegram-plugin/tests/answer-stream.test.ts +878 -0
- package/telegram-plugin/tests/ask-user.test.ts +203 -0
- package/telegram-plugin/tests/attachment-path.test.ts +199 -0
- package/telegram-plugin/tests/auth-account-identity-surface.test.ts +118 -0
- package/telegram-plugin/tests/auth-code-auto-capture.test.ts +144 -0
- package/telegram-plugin/tests/auth-code-redact.test.ts +248 -0
- package/telegram-plugin/tests/auth-dashboard-edge-cases.test.ts +260 -0
- package/telegram-plugin/tests/auth-dashboard-restart-flow.test.ts +140 -0
- package/telegram-plugin/tests/auth-dashboard-v3b.test.ts +559 -0
- package/telegram-plugin/tests/auth-dashboard.test.ts +1045 -0
- package/telegram-plugin/tests/auth-login-url-button.test.ts +122 -0
- package/telegram-plugin/tests/auth-slot-commands.test.ts +640 -0
- package/telegram-plugin/tests/auto-fallback-dispatcher.e2e.test.ts +183 -0
- package/telegram-plugin/tests/auto-fallback.test.ts +381 -0
- package/telegram-plugin/tests/boot-card-account-quota.test.ts +137 -0
- package/telegram-plugin/tests/boot-card-dedupe.test.ts +154 -0
- package/telegram-plugin/tests/boot-card-probe-target.test.ts +194 -0
- package/telegram-plugin/tests/boot-card-reason.test.ts +103 -0
- package/telegram-plugin/tests/boot-card-render.test.ts +219 -0
- package/telegram-plugin/tests/boot-probes.test.ts +451 -0
- package/telegram-plugin/tests/bot-api.harness.ts +116 -0
- package/telegram-plugin/tests/bot-runtime.test.ts +190 -0
- package/telegram-plugin/tests/bridge-anonymous-refuse.test.ts +60 -0
- package/telegram-plugin/tests/context-exhaustion.test.ts +114 -0
- package/telegram-plugin/tests/credits-watch.test.ts +221 -0
- package/telegram-plugin/tests/dm-command-gate.test.ts +176 -0
- package/telegram-plugin/tests/draft-stream.test.ts +752 -0
- package/telegram-plugin/tests/draft-transport.test.ts +141 -0
- package/telegram-plugin/tests/e2e.test.ts +436 -0
- package/telegram-plugin/tests/fake-bot-api.test.ts +213 -0
- package/telegram-plugin/tests/fake-bot-api.ts +617 -0
- package/telegram-plugin/tests/false-restart-banner.test.ts +253 -0
- package/telegram-plugin/tests/first-paint.test.ts +257 -0
- package/telegram-plugin/tests/fixtures/pty-tail-tmux-fragment.bin +6 -0
- package/telegram-plugin/tests/fixtures/service-log-current-claude-code.bin +3624 -0
- package/telegram-plugin/tests/fleet-state-watcher.test.ts +101 -0
- package/telegram-plugin/tests/fleet-state.test.ts +185 -0
- package/telegram-plugin/tests/foreman-create-flow.test.ts +359 -0
- package/telegram-plugin/tests/foreman-handlers.test.ts +347 -0
- package/telegram-plugin/tests/foreman-state.test.ts +164 -0
- package/telegram-plugin/tests/foreman-write-ops.test.ts +214 -0
- package/telegram-plugin/tests/gateway-409-retry-banner.test.ts +173 -0
- package/telegram-plugin/tests/gateway-boot-marker-clear.test.ts +72 -0
- package/telegram-plugin/tests/gateway-bridge.test.ts +811 -0
- package/telegram-plugin/tests/gateway-clean-shutdown-marker.test.ts +414 -0
- package/telegram-plugin/tests/gateway-disconnect-flush.test.ts +144 -0
- package/telegram-plugin/tests/gateway-message-validator.test.ts +133 -0
- package/telegram-plugin/tests/gateway-no-reply-single-emit.test.ts +103 -0
- package/telegram-plugin/tests/gateway-secret-detect.test.ts +127 -0
- package/telegram-plugin/tests/gateway-startup-mutex.test.ts +284 -0
- package/telegram-plugin/tests/gateway-startup-network-retry.test.ts +185 -0
- package/telegram-plugin/tests/gateway-startup-reset.test.ts +72 -0
- package/telegram-plugin/tests/gateway-update-placeholder-dispatch.test.ts +125 -0
- package/telegram-plugin/tests/handoff-continuity.test.ts +249 -0
- package/telegram-plugin/tests/harness-ordering-invariants.test.ts +243 -0
- package/telegram-plugin/tests/harness-parse-mode-validation.test.ts +114 -0
- package/telegram-plugin/tests/history.test.ts +364 -0
- package/telegram-plugin/tests/html-balanced.ts +63 -0
- package/telegram-plugin/tests/html-sanitize.test.ts +146 -0
- package/telegram-plugin/tests/idle-footer-wiring.test.ts +88 -0
- package/telegram-plugin/tests/idle-footer.test.ts +66 -0
- package/telegram-plugin/tests/inbound-coalesce.test.ts +127 -0
- package/telegram-plugin/tests/inline-keyboard-callbacks.test.ts +150 -0
- package/telegram-plugin/tests/interrupt-marker.test.ts +126 -0
- package/telegram-plugin/tests/ipc-protocol.test.ts +218 -0
- package/telegram-plugin/tests/ipc-server-anonymous-refuse.test.ts +82 -0
- package/telegram-plugin/tests/ipc-server-client.test.ts +323 -0
- package/telegram-plugin/tests/ipc-server-race.test.ts +183 -0
- package/telegram-plugin/tests/ipc-server-validate-operator.test.ts +91 -0
- package/telegram-plugin/tests/ipc-server-validate-pty-partial.test.ts +64 -0
- package/telegram-plugin/tests/ipc-server-validate-update-placeholder.test.ts +77 -0
- package/telegram-plugin/tests/ipc-validator.test.ts +274 -0
- package/telegram-plugin/tests/issues-card.test.ts +495 -0
- package/telegram-plugin/tests/issues-watcher.test.ts +165 -0
- package/telegram-plugin/tests/model-unavailable.test.ts +303 -0
- package/telegram-plugin/tests/multi-turn-continuity.test.ts +159 -0
- package/telegram-plugin/tests/operator-events-history.test.ts +125 -0
- package/telegram-plugin/tests/operator-events-session-tail.test.ts +192 -0
- package/telegram-plugin/tests/operator-events.test.ts +331 -0
- package/telegram-plugin/tests/outbound-ordering.test.ts +293 -0
- package/telegram-plugin/tests/parse-mode-rotation.test.ts +164 -0
- package/telegram-plugin/tests/permission-rule.test.ts +121 -0
- package/telegram-plugin/tests/permission-title.test.ts +106 -0
- package/telegram-plugin/tests/pin-event-log.test.ts +124 -0
- package/telegram-plugin/tests/plugin-logger.test.ts +97 -0
- package/telegram-plugin/tests/poll-health.test.ts +86 -0
- package/telegram-plugin/tests/preamble-suppressor.test.ts +285 -0
- package/telegram-plugin/tests/progress-card-api-failure-during-deferred.test.ts +73 -0
- package/telegram-plugin/tests/progress-card-close-paths-converge.test.ts +272 -0
- package/telegram-plugin/tests/progress-card-cross-turn.test.ts +258 -0
- package/telegram-plugin/tests/progress-card-dispose-preservepending.test.ts +81 -0
- package/telegram-plugin/tests/progress-card-draft-flag.test.ts +80 -0
- package/telegram-plugin/tests/progress-card-driver-eviction.test.ts +215 -0
- package/telegram-plugin/tests/progress-card-driver-fleet-shadow.test.ts +123 -0
- package/telegram-plugin/tests/progress-card-driver-force-complete-parent-done.test.ts +76 -0
- package/telegram-plugin/tests/progress-card-edit-timestamps-budget.test.ts +62 -0
- package/telegram-plugin/tests/progress-card-memory-bounds.test.ts +84 -0
- package/telegram-plugin/tests/progress-card-pin-failure-paths.test.ts +139 -0
- package/telegram-plugin/tests/progress-card-pin-manager.test.ts +773 -0
- package/telegram-plugin/tests/progress-card-pin-race-fast-turn.test.ts +66 -0
- package/telegram-plugin/tests/progress-card-pin-sidecar-partial-write.test.ts +64 -0
- package/telegram-plugin/tests/progress-card-pin-watchdog.test.ts +190 -0
- package/telegram-plugin/tests/progress-card-sigterm-pin-flush.test.ts +146 -0
- package/telegram-plugin/tests/progress-update.test.ts +236 -0
- package/telegram-plugin/tests/protocol-fixtures.test.ts +59 -0
- package/telegram-plugin/tests/protocol-fixtures.ts +198 -0
- package/telegram-plugin/tests/pty-partial-handler.test.ts +326 -0
- package/telegram-plugin/tests/pty-tail-real-fixture.test.ts +114 -0
- package/telegram-plugin/tests/pty-tail-tmux-fragment.test.ts +71 -0
- package/telegram-plugin/tests/pty-tail.test.ts +525 -0
- package/telegram-plugin/tests/quota-cache.test.ts +187 -0
- package/telegram-plugin/tests/quota-check.test.ts +622 -0
- package/telegram-plugin/tests/races.test.ts +842 -0
- package/telegram-plugin/tests/real-gateway-f1-ladder-integrity.test.ts +123 -0
- package/telegram-plugin/tests/real-gateway-f2-instant-draft.test.ts +82 -0
- package/telegram-plugin/tests/real-gateway-f3-late-card.test.ts +114 -0
- package/telegram-plugin/tests/real-gateway-harness.ts +699 -0
- package/telegram-plugin/tests/real-gateway-i6-turn-flush-replay-dedup.test.ts +313 -0
- package/telegram-plugin/tests/real-gateway-ipc-lifecycle.test.ts +299 -0
- package/telegram-plugin/tests/real-gateway-spec.test.ts +487 -0
- package/telegram-plugin/tests/real-gateway.smoke.test.ts +101 -0
- package/telegram-plugin/tests/recent-outbound-dedup.test.ts +192 -0
- package/telegram-plugin/tests/registry-turns.test.ts +432 -0
- package/telegram-plugin/tests/reply-terminal-reaction.test.ts +149 -0
- package/telegram-plugin/tests/resolve-calling-subagent.test.ts +269 -0
- package/telegram-plugin/tests/restart-watchdog.test.ts +224 -0
- package/telegram-plugin/tests/retry-api-call.test.ts +287 -0
- package/telegram-plugin/tests/secret-detect-audit.test.ts +58 -0
- package/telegram-plugin/tests/secret-detect-fail-closed.test.ts +83 -0
- package/telegram-plugin/tests/secret-detect-gitleaks.test.ts +32 -0
- package/telegram-plugin/tests/secret-detect-oauth-code.test.ts +308 -0
- package/telegram-plugin/tests/secret-detect-pipeline.test.ts +123 -0
- package/telegram-plugin/tests/secret-detect-secretlint.test.ts +101 -0
- package/telegram-plugin/tests/secret-detect-staging.test.ts +45 -0
- package/telegram-plugin/tests/secret-detect-suppressor-no-silent-allow.test.ts +67 -0
- package/telegram-plugin/tests/secret-detect.test.ts +223 -0
- package/telegram-plugin/tests/secret-guard-pretool.test.ts +194 -0
- package/telegram-plugin/tests/send-typing-action-validation.test.ts +61 -0
- package/telegram-plugin/tests/session-tail-capped.test.ts +285 -0
- package/telegram-plugin/tests/session-tail.test.ts +524 -0
- package/telegram-plugin/tests/setup-flow.test.ts +510 -0
- package/telegram-plugin/tests/setup-state.test.ts +146 -0
- package/telegram-plugin/tests/silent-reply-guard.test.ts +122 -0
- package/telegram-plugin/tests/slot-banner-driver.e2e.test.ts +350 -0
- package/telegram-plugin/tests/slot-banner.test.ts +74 -0
- package/telegram-plugin/tests/snapshot-serializer.ts +79 -0
- package/telegram-plugin/tests/spawn-detached-cgroup-escape.test.ts +51 -0
- package/telegram-plugin/tests/status-accent.test.ts +186 -0
- package/telegram-plugin/tests/status-reactions-allowed-filter.test.ts +132 -0
- package/telegram-plugin/tests/status-reactions.test.ts +314 -0
- package/telegram-plugin/tests/steering.test.ts +282 -0
- package/telegram-plugin/tests/sticker-aliases.test.ts +232 -0
- package/telegram-plugin/tests/stream-controller-html-fallback.test.ts +127 -0
- package/telegram-plugin/tests/stream-controller.test.ts +262 -0
- package/telegram-plugin/tests/stream-reply-error-paths.test.ts +208 -0
- package/telegram-plugin/tests/stream-reply-handler.test.ts +1292 -0
- package/telegram-plugin/tests/streaming-e2e.test.ts +389 -0
- package/telegram-plugin/tests/streaming-metrics.test.ts +201 -0
- package/telegram-plugin/tests/streaming-orchestration.test.ts +756 -0
- package/telegram-plugin/tests/subagent-registry-bugs.test.ts +725 -0
- package/telegram-plugin/tests/subagent-tracker-hooks.test.ts +213 -0
- package/telegram-plugin/tests/subagent-watcher-parent-marker.test.ts +274 -0
- package/telegram-plugin/tests/subagent-watcher-stall-notification.test.ts +243 -0
- package/telegram-plugin/tests/subagent-watcher.test.ts +877 -0
- package/telegram-plugin/tests/subagents-schema-init-order.test.ts +109 -0
- package/telegram-plugin/tests/sync-chat-running-subagents.test.ts +116 -0
- package/telegram-plugin/tests/telegram-button-constraints.test.ts +194 -0
- package/telegram-plugin/tests/telegram-format.test.ts +1093 -0
- package/telegram-plugin/tests/telegraph.test.ts +246 -0
- package/telegram-plugin/tests/tool-labels.test.ts +383 -0
- package/telegram-plugin/tests/turn-active-marker.test.ts +195 -0
- package/telegram-plugin/tests/turn-end-regressions.test.ts +489 -0
- package/telegram-plugin/tests/turn-flush-card-takeover.test.ts +218 -0
- package/telegram-plugin/tests/turn-flush-dedup-controller.test.ts +144 -0
- package/telegram-plugin/tests/turn-flush-prose-recovery.test.ts +78 -0
- package/telegram-plugin/tests/turn-flush-safety.test.ts +189 -0
- package/telegram-plugin/tests/turn-signal-tracker.test.ts +107 -0
- package/telegram-plugin/tests/turns-writer.test.ts +323 -0
- package/telegram-plugin/tests/two-zone-bg-carry-full-lifecycle.test.ts +131 -0
- package/telegram-plugin/tests/two-zone-bg-detection.test.ts +120 -0
- package/telegram-plugin/tests/two-zone-bg-done-when-all-terminal.test.ts +114 -0
- package/telegram-plugin/tests/two-zone-bg-early-turn-end.test.ts +87 -0
- package/telegram-plugin/tests/two-zone-bg-survives-next-turn.test.ts +211 -0
- package/telegram-plugin/tests/two-zone-card-cap.test.ts +62 -0
- package/telegram-plugin/tests/two-zone-card-fleet-row.test.ts +101 -0
- package/telegram-plugin/tests/two-zone-card-header-phases.test.ts +68 -0
- package/telegram-plugin/tests/two-zone-card-html-balance.test.ts +110 -0
- package/telegram-plugin/tests/two-zone-card-lifecycle.test.ts +128 -0
- package/telegram-plugin/tests/two-zone-card-sanitise.test.ts +58 -0
- package/telegram-plugin/tests/two-zone-card-snapshot.test.ts +133 -0
- package/telegram-plugin/tests/two-zone-concurrent-turns-isolation.test.ts +155 -0
- package/telegram-plugin/tests/two-zone-phasefor-precedence.test.ts +117 -0
- package/telegram-plugin/tests/two-zone-snapshot-extras.test.ts +143 -0
- package/telegram-plugin/tests/two-zone-stuck-edit-throttle.test.ts +149 -0
- package/telegram-plugin/tests/two-zone-stuck-header-escalation.test.ts +101 -0
- package/telegram-plugin/tests/two-zone-stuck-per-member.test.ts +114 -0
- package/telegram-plugin/tests/two-zone-stuck-recovery.test.ts +105 -0
- package/telegram-plugin/tests/typing-wrap.test.ts +141 -0
- package/telegram-plugin/tests/unhandled-rejection-policy.test.ts +147 -0
- package/telegram-plugin/tests/update-factory-edited-and-reactions.test.ts +108 -0
- package/telegram-plugin/tests/update-factory.ts +305 -0
- package/telegram-plugin/tests/vault-grant-wizard.test.ts +84 -0
- package/telegram-plugin/tests/vault-grants-revoke.test.ts +265 -0
- package/telegram-plugin/tests/vault-subcommands.test.ts +234 -0
- package/telegram-plugin/tests/voice-transcribe.test.ts +196 -0
- package/telegram-plugin/tests/waiting-ux-harness.ts +381 -0
- package/telegram-plugin/tests/waiting-ux.e2e.test.ts +233 -0
- package/telegram-plugin/tests/welcome-text.test.ts +407 -0
- package/telegram-plugin/tool-error-filter.ts +89 -0
- package/telegram-plugin/tool-labels.ts +330 -0
- package/telegram-plugin/tool-names.ts +53 -0
- package/telegram-plugin/turn-flush-prose-recovery.ts +40 -0
- package/telegram-plugin/turn-flush-safety.ts +109 -0
- package/telegram-plugin/turn-signal-tracker.ts +79 -0
- package/telegram-plugin/two-zone-card.ts +249 -0
- package/telegram-plugin/typing-wrap.ts +92 -0
- package/telegram-plugin/voice-transcribe.ts +166 -0
- 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
|
+
})
|