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,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared draft-transport helpers for answer-stream and draft-stream.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from answer-stream.ts so both the narrative answer-lane and the
|
|
5
|
+
* model-driven stream_reply lane can share the same regex constants and
|
|
6
|
+
* fallback logic without duplicating them.
|
|
7
|
+
*
|
|
8
|
+
* answer-stream.ts re-exports these symbols so existing callers (including
|
|
9
|
+
* tests that import directly from answer-stream.ts) continue to work.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
// Error patterns matching OpenClaw's shouldFallbackFromDraftTransport.
|
|
13
|
+
// Exported for tests.
|
|
14
|
+
export const DRAFT_METHOD_UNAVAILABLE_RE =
|
|
15
|
+
/(unknown method|method .*not (found|available|supported)|unsupported)/i
|
|
16
|
+
export const DRAFT_CHAT_UNSUPPORTED_RE = /(can't be used|can be used only)/i
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Returns true when a sendMessageDraft rejection means "this API is not
|
|
20
|
+
* available" rather than a transient network error.
|
|
21
|
+
*/
|
|
22
|
+
export function shouldFallbackFromDraftTransport(err: unknown): boolean {
|
|
23
|
+
const text =
|
|
24
|
+
typeof err === 'string'
|
|
25
|
+
? err
|
|
26
|
+
: err instanceof Error
|
|
27
|
+
? err.message
|
|
28
|
+
: typeof err === 'object' && err != null && 'description' in err
|
|
29
|
+
? typeof (err as { description: unknown }).description === 'string'
|
|
30
|
+
? (err as { description: string }).description
|
|
31
|
+
: ''
|
|
32
|
+
: ''
|
|
33
|
+
if (!/sendMessageDraft/i.test(text)) return false
|
|
34
|
+
return DRAFT_METHOD_UNAVAILABLE_RE.test(text) || DRAFT_CHAT_UNSUPPORTED_RE.test(text)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Symbol-keyed shared counter for draft-id allocation across concurrent
|
|
39
|
+
* streams (mirrors openclaw's getDraftStreamState). Using Symbol.for ensures
|
|
40
|
+
* the same counter is shared even if this module is loaded multiple times
|
|
41
|
+
* (e.g. from different bundle chunks).
|
|
42
|
+
*/
|
|
43
|
+
const DRAFT_STREAM_STATE_KEY = Symbol.for('switchroom.draftStreamState')
|
|
44
|
+
|
|
45
|
+
interface DraftStreamState {
|
|
46
|
+
nextDraftId: number
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function getDraftStreamState(): DraftStreamState {
|
|
50
|
+
const g = globalThis as Record<PropertyKey, unknown>
|
|
51
|
+
let state = g[DRAFT_STREAM_STATE_KEY] as DraftStreamState | undefined
|
|
52
|
+
if (!state) {
|
|
53
|
+
state = { nextDraftId: 0 }
|
|
54
|
+
g[DRAFT_STREAM_STATE_KEY] = state
|
|
55
|
+
}
|
|
56
|
+
return state
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Allocate a unique draft ID, wrapping at 2_147_483_647 (Telegram's int32
|
|
61
|
+
* max for draft_id). IDs start at 1 and cycle.
|
|
62
|
+
*/
|
|
63
|
+
export function allocateDraftId(): number {
|
|
64
|
+
const state = getDraftStreamState()
|
|
65
|
+
state.nextDraftId = state.nextDraftId >= 2_147_483_647 ? 1 : state.nextDraftId + 1
|
|
66
|
+
return state.nextDraftId
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Reset the shared draft-id counter — for tests only. */
|
|
70
|
+
export function __resetDraftIdForTests(): void {
|
|
71
|
+
getDraftStreamState().nextDraftId = 0
|
|
72
|
+
}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* First-paint seam (Phase 1 of #545).
|
|
3
|
+
*
|
|
4
|
+
* Pure function extracted from gateway.ts `handleInbound` for the
|
|
5
|
+
* status-reaction + progress-card-startTurn slice. Production behavior is
|
|
6
|
+
* unchanged: gateway.ts calls this with its module-level singletons. The
|
|
7
|
+
* seam exists so the waiting-UX harness can drive the real first-paint
|
|
8
|
+
* code path with fakes and assert wall-clock call timing of
|
|
9
|
+
* - bot.api.setMessageReaction (the 👀 ack)
|
|
10
|
+
* - progressDriver.startTurn (the progress card)
|
|
11
|
+
*
|
|
12
|
+
* Scope is deliberately narrow:
|
|
13
|
+
* - status-reaction setup (cancel-prior + setQueued, or 🤝/👀 for
|
|
14
|
+
* steer/queued mid-turn)
|
|
15
|
+
* - progressDriver.startTurn for fresh turns
|
|
16
|
+
* Out of scope (stays inline in gateway.ts):
|
|
17
|
+
* - draft pre-allocation, forum-topic placeholder, heartbeat scheduling
|
|
18
|
+
*
|
|
19
|
+
* The motivation for the narrow scope: pre-alloc/heartbeat code touches
|
|
20
|
+
* 6 more module-scoped maps + functions and would balloon this seam
|
|
21
|
+
* without making F2/F3 (no instant draft / late card) any more testable
|
|
22
|
+
* — those are about the FIRST visible signal (👀 + card.startTurn).
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import type { ReactionTypeEmoji } from 'grammy/types'
|
|
26
|
+
import { StatusReactionController } from './status-reactions.js'
|
|
27
|
+
import type { DraftStreamHandle } from './draft-stream.js'
|
|
28
|
+
|
|
29
|
+
// ─── Types ────────────────────────────────────────────────────────────────
|
|
30
|
+
|
|
31
|
+
export interface FirstPaintBotApi {
|
|
32
|
+
setMessageReaction(
|
|
33
|
+
chatId: string | number,
|
|
34
|
+
messageId: number,
|
|
35
|
+
reactions: Array<{ type: 'emoji'; emoji: ReactionTypeEmoji['emoji'] }>,
|
|
36
|
+
): Promise<unknown>
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface FirstPaintProgressDriver {
|
|
40
|
+
startTurn(args: {
|
|
41
|
+
chatId: string
|
|
42
|
+
threadId?: string
|
|
43
|
+
userText: string
|
|
44
|
+
replyToMessageId?: number
|
|
45
|
+
}): void
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface FirstPaintAccess {
|
|
49
|
+
/** When false, all status-reaction posting is suppressed. */
|
|
50
|
+
statusReactions?: boolean
|
|
51
|
+
/** Optional alternate ack emoji used when statusReactions is suppressed. */
|
|
52
|
+
ackReaction?: string
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface FirstPaintCtx {
|
|
56
|
+
chatId: string
|
|
57
|
+
messageId: number | undefined
|
|
58
|
+
messageThreadId: number | undefined
|
|
59
|
+
isSteerPrefix: boolean
|
|
60
|
+
effectiveText: string
|
|
61
|
+
/** ms epoch — used for the inbound_ack metric delta. */
|
|
62
|
+
inboundReceivedAt: number
|
|
63
|
+
access: FirstPaintAccess
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface FirstPaintDeps {
|
|
67
|
+
bot: { api: FirstPaintBotApi }
|
|
68
|
+
progressDriver: FirstPaintProgressDriver | undefined
|
|
69
|
+
activeStatusReactions: Map<string, StatusReactionController>
|
|
70
|
+
activeReactionMsgIds: Map<string, { chatId: string; messageId: number }>
|
|
71
|
+
activeTurnStartedAt: Map<string, number>
|
|
72
|
+
progressUpdateTurnCount: Map<string, number>
|
|
73
|
+
activeDraftStreams: Map<string, DraftStreamHandle>
|
|
74
|
+
activeDraftParseModes: Map<string, 'HTML' | 'MarkdownV2' | undefined>
|
|
75
|
+
suppressPtyPreview: Set<string>
|
|
76
|
+
/** Compute the status/stream key. Production uses `${chatId}:${threadId ?? '_'}`. */
|
|
77
|
+
statusKey: (chatId: string, threadId?: number) => string
|
|
78
|
+
streamKey: (chatId: string, threadId?: number) => string
|
|
79
|
+
/** Wipes activeReactionMsgIds + activeTurnStartedAt for the key. */
|
|
80
|
+
purgeReactionTracking: (key: string) => void
|
|
81
|
+
/** Records signal emission (issue #203 metrics). */
|
|
82
|
+
signalTracker: {
|
|
83
|
+
noteSignal: (key: string, ts: number) => void
|
|
84
|
+
reset: (key: string, ts: number) => void
|
|
85
|
+
}
|
|
86
|
+
/** Side-channel for active-reactions disk persistence. */
|
|
87
|
+
resolveAgentDirFromEnv: () => string | null | undefined
|
|
88
|
+
addActiveReaction: (
|
|
89
|
+
agentDir: string,
|
|
90
|
+
entry: { chatId: string; messageId: number; threadId: number | null; reactedAt: number },
|
|
91
|
+
) => void
|
|
92
|
+
/** Streaming-metrics emitter (#203). */
|
|
93
|
+
logStreamingEvent: (ev: { kind: 'inbound_ack'; chatId: string; messageId: number; ackDelayMs: number }) => void
|
|
94
|
+
/** Clock — defaults to Date.now in production; tests inject fake. */
|
|
95
|
+
now?: () => number
|
|
96
|
+
/**
|
|
97
|
+
* Factory for the per-turn StatusReactionController. Defaults to constructing
|
|
98
|
+
* a real `StatusReactionController(cb)`. Tests inject a recording stub so
|
|
99
|
+
* the harness can decouple from the real controller's internal scheduling.
|
|
100
|
+
*/
|
|
101
|
+
controllerFactory?: (cb: (emoji: string) => Promise<void>) => StatusReactionController
|
|
102
|
+
/**
|
|
103
|
+
* #542 fix: per-chat allowed-reactions filter sourced from getChat probe.
|
|
104
|
+
* Optional — when omitted, the controller is constructed without a filter
|
|
105
|
+
* (current behavior, possibly buggy if the chat restricts reactions).
|
|
106
|
+
* The default `controllerFactory` consults this getter; custom factories
|
|
107
|
+
* (e.g. test harnesses) may ignore it.
|
|
108
|
+
*/
|
|
109
|
+
getAllowedReactions?: (chatId: string) => Set<string> | null
|
|
110
|
+
/**
|
|
111
|
+
* Sink for stderr-style error reporting from the seam. Defaults to writing
|
|
112
|
+
* to `process.stderr`. Tests inject a recorder.
|
|
113
|
+
*/
|
|
114
|
+
logError?: (msg: string) => void
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export interface FirstPaintResult {
|
|
118
|
+
isSteering: boolean
|
|
119
|
+
priorTurnStartedAt: number | undefined
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// ─── Seam ────────────────────────────────────────────────────────────────
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Run the first-paint slice for an inbound user message. Mirrors lines
|
|
126
|
+
* 3973-4072 of gateway.ts as of `waiting-ux-harness` head. Returns the
|
|
127
|
+
* `isSteering` and `priorTurnStartedAt` signals the caller needs to gate
|
|
128
|
+
* downstream pre-alloc behavior.
|
|
129
|
+
*
|
|
130
|
+
* Behavior is identical to inline production:
|
|
131
|
+
* - missing msgId → nothing happens (no reaction, no card)
|
|
132
|
+
* - prior turn in flight + steer prefix → 🤝 on inbound, no new turn
|
|
133
|
+
* - prior turn in flight (queued mid-turn) → 👀 on inbound, no new turn
|
|
134
|
+
* - fresh turn → cancel any stale controller, start a new one, setQueued,
|
|
135
|
+
* reset signal tracker, persist active-reaction to disk, then
|
|
136
|
+
* progressDriver.startTurn
|
|
137
|
+
* - access.statusReactions === false + access.ackReaction → custom ack
|
|
138
|
+
* emoji on inbound; no controller; no startTurn
|
|
139
|
+
*/
|
|
140
|
+
export async function firstPaintTurn(
|
|
141
|
+
deps: FirstPaintDeps,
|
|
142
|
+
ctx: FirstPaintCtx,
|
|
143
|
+
): Promise<FirstPaintResult> {
|
|
144
|
+
const now = deps.now ?? Date.now
|
|
145
|
+
const { chatId, messageId: msgId, messageThreadId, isSteerPrefix, effectiveText, inboundReceivedAt, access } = ctx
|
|
146
|
+
|
|
147
|
+
let isSteering = false
|
|
148
|
+
let priorTurnStartedAt: number | undefined
|
|
149
|
+
|
|
150
|
+
if (msgId != null) {
|
|
151
|
+
const key = deps.statusKey(chatId, messageThreadId)
|
|
152
|
+
const priorActive = deps.activeStatusReactions.get(key)
|
|
153
|
+
const priorTurnInFlight = priorActive != null
|
|
154
|
+
isSteering = priorTurnInFlight && isSteerPrefix
|
|
155
|
+
if (priorTurnInFlight) priorTurnStartedAt = deps.activeTurnStartedAt.get(key)
|
|
156
|
+
|
|
157
|
+
if (access.statusReactions !== false) {
|
|
158
|
+
if (isSteering) {
|
|
159
|
+
void deps.bot.api
|
|
160
|
+
.setMessageReaction(chatId, msgId, [{ type: 'emoji', emoji: '🤝' as ReactionTypeEmoji['emoji'] }])
|
|
161
|
+
.catch(() => {})
|
|
162
|
+
} else if (priorTurnInFlight) {
|
|
163
|
+
void deps.bot.api
|
|
164
|
+
.setMessageReaction(chatId, msgId, [{ type: 'emoji', emoji: '👀' as ReactionTypeEmoji['emoji'] }])
|
|
165
|
+
.catch(() => {})
|
|
166
|
+
deps.logStreamingEvent({
|
|
167
|
+
kind: 'inbound_ack',
|
|
168
|
+
chatId,
|
|
169
|
+
messageId: msgId,
|
|
170
|
+
ackDelayMs: now() - inboundReceivedAt,
|
|
171
|
+
})
|
|
172
|
+
} else {
|
|
173
|
+
// Fresh turn — `priorTurnInFlight` is false here, so `priorActive`
|
|
174
|
+
// is provably undefined (priorTurnInFlight = priorActive != null).
|
|
175
|
+
// The earlier `if (priorActive)` block was dead code; removed.
|
|
176
|
+
const sKey = deps.streamKey(chatId, messageThreadId)
|
|
177
|
+
const priorStream = deps.activeDraftStreams.get(sKey)
|
|
178
|
+
if (priorStream && !priorStream.isFinal()) {
|
|
179
|
+
deps.activeDraftStreams.delete(sKey)
|
|
180
|
+
deps.activeDraftParseModes.delete(sKey)
|
|
181
|
+
await priorStream.finalize().catch(() => {})
|
|
182
|
+
}
|
|
183
|
+
deps.suppressPtyPreview.delete(sKey)
|
|
184
|
+
|
|
185
|
+
const allowed = deps.getAllowedReactions?.(chatId) ?? null
|
|
186
|
+
const makeCtrl = deps.controllerFactory ?? ((cb) => new StatusReactionController(cb, allowed))
|
|
187
|
+
const ctrl = makeCtrl(async (emoji) => {
|
|
188
|
+
await deps.bot.api.setMessageReaction(chatId, msgId, [
|
|
189
|
+
{ type: 'emoji', emoji: emoji as ReactionTypeEmoji['emoji'] },
|
|
190
|
+
])
|
|
191
|
+
deps.signalTracker.noteSignal(key, now())
|
|
192
|
+
})
|
|
193
|
+
deps.activeStatusReactions.set(key, ctrl)
|
|
194
|
+
deps.activeReactionMsgIds.set(key, { chatId, messageId: msgId })
|
|
195
|
+
deps.activeTurnStartedAt.set(key, now())
|
|
196
|
+
deps.progressUpdateTurnCount.set(key, 0)
|
|
197
|
+
ctrl.setQueued()
|
|
198
|
+
deps.logStreamingEvent({
|
|
199
|
+
kind: 'inbound_ack',
|
|
200
|
+
chatId,
|
|
201
|
+
messageId: msgId,
|
|
202
|
+
ackDelayMs: now() - inboundReceivedAt,
|
|
203
|
+
})
|
|
204
|
+
deps.signalTracker.reset(deps.statusKey(chatId, messageThreadId), now())
|
|
205
|
+
const agentDir = deps.resolveAgentDirFromEnv()
|
|
206
|
+
if (agentDir != null) {
|
|
207
|
+
deps.addActiveReaction(agentDir, {
|
|
208
|
+
chatId,
|
|
209
|
+
messageId: msgId,
|
|
210
|
+
threadId: messageThreadId ?? null,
|
|
211
|
+
reactedAt: now(),
|
|
212
|
+
})
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
} else if (access.ackReaction) {
|
|
216
|
+
void deps.bot.api
|
|
217
|
+
.setMessageReaction(chatId, msgId, [
|
|
218
|
+
{ type: 'emoji', emoji: access.ackReaction as ReactionTypeEmoji['emoji'] },
|
|
219
|
+
])
|
|
220
|
+
.catch(() => {})
|
|
221
|
+
deps.logStreamingEvent({
|
|
222
|
+
kind: 'inbound_ack',
|
|
223
|
+
chatId,
|
|
224
|
+
messageId: msgId,
|
|
225
|
+
ackDelayMs: now() - inboundReceivedAt,
|
|
226
|
+
})
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Start a new progress card only for fresh turns (no prior turn in flight).
|
|
231
|
+
if (!isSteering && priorTurnStartedAt == null) {
|
|
232
|
+
try {
|
|
233
|
+
deps.progressDriver?.startTurn({
|
|
234
|
+
chatId,
|
|
235
|
+
threadId: messageThreadId != null ? String(messageThreadId) : undefined,
|
|
236
|
+
userText: effectiveText,
|
|
237
|
+
replyToMessageId: msgId != null ? msgId : undefined,
|
|
238
|
+
})
|
|
239
|
+
} catch (err) {
|
|
240
|
+
const log = deps.logError ?? ((m: string) => process.stderr.write(m))
|
|
241
|
+
log(`telegram gateway: progress-card startTurn failed: ${(err as Error).message}\n`)
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return { isSteering, priorTurnStartedAt }
|
|
246
|
+
}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* P0 of #662 — fleet state struct + pure transition functions.
|
|
3
|
+
*
|
|
4
|
+
* `FleetMember` is the per-sub-agent unit the v2 two-zone status card
|
|
5
|
+
* (P1) will render. This module is pure data plumbing: the driver
|
|
6
|
+
* shadows a `Map<agentId, FleetMember>` alongside the legacy
|
|
7
|
+
* `chatState.subAgents` map and updates it through the reducers below
|
|
8
|
+
* at the same sites the legacy map is mutated. No render code, no
|
|
9
|
+
* timers, no globals — clocks and IDs are caller-supplied so tests can
|
|
10
|
+
* drive deterministic transitions.
|
|
11
|
+
*
|
|
12
|
+
* Status derivation (verified in #662): `session-tail.ts:101` defines
|
|
13
|
+
* `sub_agent_turn_end` as `{kind, agentId}` with NO terminal-status
|
|
14
|
+
* field, so failure must be derived: any `sub_agent_tool_result` with
|
|
15
|
+
* `isError=true` accumulates into `errorSeen`, and `applyTurnEnd` flips
|
|
16
|
+
* `status` to `failed` if any error was seen, else `done`.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
const ROLE_FALLBACK_LEN = 20
|
|
20
|
+
const SANITISE_MAX_LEN = 120
|
|
21
|
+
|
|
22
|
+
export type FleetStatus = 'running' | 'background' | 'done' | 'failed' | 'stuck' | 'killed' | 'capped'
|
|
23
|
+
|
|
24
|
+
export interface FleetMember {
|
|
25
|
+
agentId: string
|
|
26
|
+
/** Display label: description / subagentType / first-prompt slice / 'agent'. */
|
|
27
|
+
role: string
|
|
28
|
+
/** ms epoch when this member was registered (driver snapshot of `now()`). */
|
|
29
|
+
startedAt: number
|
|
30
|
+
toolCount: number
|
|
31
|
+
/** ms epoch of the most recent tool_use / tool_result for this member. */
|
|
32
|
+
lastActivityAt: number
|
|
33
|
+
/** Most recent tool call observed (name + sanitised arg for display). */
|
|
34
|
+
lastTool: { name: string; sanitisedArg: string } | null
|
|
35
|
+
status: FleetStatus
|
|
36
|
+
/** ms epoch when status became terminal (done/failed/killed); null otherwise. */
|
|
37
|
+
terminalAt: number | null
|
|
38
|
+
/** True if any sub_agent_tool_result with isError=true has been observed. */
|
|
39
|
+
errorSeen: boolean
|
|
40
|
+
/** Snapshot of driver's currentTurnKey at sub_agent_started. Stable across turns. */
|
|
41
|
+
originatingTurnKey: string
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface CreateFleetMemberArgs {
|
|
45
|
+
agentId: string
|
|
46
|
+
role: string
|
|
47
|
+
startedAt: number
|
|
48
|
+
originatingTurnKey: string
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function createFleetMember(args: CreateFleetMemberArgs): FleetMember {
|
|
52
|
+
return {
|
|
53
|
+
agentId: args.agentId,
|
|
54
|
+
role: args.role,
|
|
55
|
+
startedAt: args.startedAt,
|
|
56
|
+
toolCount: 0,
|
|
57
|
+
lastActivityAt: args.startedAt,
|
|
58
|
+
lastTool: null,
|
|
59
|
+
status: 'running',
|
|
60
|
+
terminalAt: null,
|
|
61
|
+
errorSeen: false,
|
|
62
|
+
originatingTurnKey: args.originatingTurnKey,
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function applyToolUse(
|
|
67
|
+
member: FleetMember,
|
|
68
|
+
toolName: string,
|
|
69
|
+
input: Record<string, unknown> | undefined,
|
|
70
|
+
now: number,
|
|
71
|
+
): FleetMember {
|
|
72
|
+
// P3 of #662 — recovery from stuck. A live tool event proves the
|
|
73
|
+
// sub-agent is alive again, so flip status back to running. Terminal
|
|
74
|
+
// statuses (done/failed/killed) are sticky and never reset here.
|
|
75
|
+
const status: FleetStatus = member.status === 'stuck' ? 'running' : member.status
|
|
76
|
+
return {
|
|
77
|
+
...member,
|
|
78
|
+
status,
|
|
79
|
+
toolCount: member.toolCount + 1,
|
|
80
|
+
lastActivityAt: now,
|
|
81
|
+
lastTool: { name: toolName, sanitisedArg: sanitiseToolArg(toolName, input ?? {}) },
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function applyToolResult(member: FleetMember, isError: boolean | undefined): FleetMember {
|
|
86
|
+
if (!isError) return member
|
|
87
|
+
if (member.errorSeen) return member
|
|
88
|
+
return { ...member, errorSeen: true }
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function applyTurnEnd(member: FleetMember, now: number): FleetMember {
|
|
92
|
+
// Idempotent — if already terminal, do nothing.
|
|
93
|
+
if (member.terminalAt != null) return member
|
|
94
|
+
return {
|
|
95
|
+
...member,
|
|
96
|
+
status: member.errorSeen ? 'failed' : 'done',
|
|
97
|
+
terminalAt: now,
|
|
98
|
+
lastActivityAt: now,
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Transition a fleet member to `capped` terminal state.
|
|
104
|
+
*
|
|
105
|
+
* Called when session-tail detects a truncated sub-agent transcript:
|
|
106
|
+
* >= CAP_TOOL_USE_THRESHOLD tool_uses recorded with no `type:result` /
|
|
107
|
+
* `subtype:end` / `type:final` terminal record. The sub-agent was killed
|
|
108
|
+
* mid-flight (parent restart, watchdog SIGTERM, etc.) before it could
|
|
109
|
+
* write its completion record. Idempotent — already-terminal members
|
|
110
|
+
* are left unchanged.
|
|
111
|
+
*/
|
|
112
|
+
export function applyCapped(member: FleetMember, now: number): FleetMember {
|
|
113
|
+
if (member.terminalAt != null) return member
|
|
114
|
+
return {
|
|
115
|
+
...member,
|
|
116
|
+
status: 'capped',
|
|
117
|
+
terminalAt: now,
|
|
118
|
+
lastActivityAt: now,
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export function markStuck(member: FleetMember, now: number, idleMs: number = 60_000): FleetMember {
|
|
123
|
+
if (member.status !== 'running') return member
|
|
124
|
+
if (now - member.lastActivityAt < idleMs) return member
|
|
125
|
+
return { ...member, status: 'stuck' }
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* P2 of #662 / fixes #64 — true if any fleet member is in
|
|
130
|
+
* `status: 'background'` AND has not yet reached terminal state. Used by
|
|
131
|
+
* the driver's dispose path to keep a PerChatState alive past parent
|
|
132
|
+
* turn_end while background sub-agents are still running, and by the v2
|
|
133
|
+
* renderer's phase resolver to choose ⏸ Background vs ✅ Done.
|
|
134
|
+
*/
|
|
135
|
+
export function hasLiveBackground(fleet: ReadonlyMap<string, FleetMember>): boolean {
|
|
136
|
+
for (const m of fleet.values()) {
|
|
137
|
+
if (m.status === 'background' && m.terminalAt == null) return true
|
|
138
|
+
}
|
|
139
|
+
return false
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export function cap(
|
|
143
|
+
members: readonly FleetMember[],
|
|
144
|
+
n: number = 5,
|
|
145
|
+
): { visible: FleetMember[]; hidden: number } {
|
|
146
|
+
const sorted = [...members].sort((a, b) => b.lastActivityAt - a.lastActivityAt)
|
|
147
|
+
if (sorted.length <= n) return { visible: sorted, hidden: 0 }
|
|
148
|
+
return { visible: sorted.slice(0, n), hidden: sorted.length - n }
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Sanitise a tool input for display on the fleet row.
|
|
153
|
+
*
|
|
154
|
+
* - Path-bearing tools (Read/Edit/Write/NotebookEdit) → basename only,
|
|
155
|
+
* so absolute paths under `/etc/secrets/` etc. don't leak into the
|
|
156
|
+
* pinned card.
|
|
157
|
+
* - Bash/command-bearing tools → the command, but with bearer-token-
|
|
158
|
+
* shaped substrings replaced with `[redacted]`.
|
|
159
|
+
* - Anything else → empty string. Renderer falls back to tool name only.
|
|
160
|
+
*
|
|
161
|
+
* Hard-capped at 120 chars; the fleet row is one line and Telegram caps
|
|
162
|
+
* the whole card at ~4096 bytes.
|
|
163
|
+
*/
|
|
164
|
+
export function sanitiseToolArg(name: string, raw: Record<string, unknown>): string {
|
|
165
|
+
let out = ''
|
|
166
|
+
switch (name) {
|
|
167
|
+
case 'Read':
|
|
168
|
+
case 'Edit':
|
|
169
|
+
case 'Write':
|
|
170
|
+
case 'NotebookEdit': {
|
|
171
|
+
const fp = raw.file_path
|
|
172
|
+
if (typeof fp === 'string' && fp.length > 0) out = basename(fp)
|
|
173
|
+
break
|
|
174
|
+
}
|
|
175
|
+
case 'Bash': {
|
|
176
|
+
const cmd = raw.command
|
|
177
|
+
if (typeof cmd === 'string') out = redactSecrets(cmd)
|
|
178
|
+
break
|
|
179
|
+
}
|
|
180
|
+
case 'Grep':
|
|
181
|
+
case 'Glob': {
|
|
182
|
+
const pat = raw.pattern
|
|
183
|
+
if (typeof pat === 'string') out = pat
|
|
184
|
+
break
|
|
185
|
+
}
|
|
186
|
+
case 'WebFetch':
|
|
187
|
+
case 'WebSearch': {
|
|
188
|
+
const url = raw.url ?? raw.query
|
|
189
|
+
if (typeof url === 'string') out = redactSecrets(url)
|
|
190
|
+
break
|
|
191
|
+
}
|
|
192
|
+
default: {
|
|
193
|
+
// Generic best-effort: the first string-valued field.
|
|
194
|
+
for (const v of Object.values(raw)) {
|
|
195
|
+
if (typeof v === 'string' && v.length > 0) {
|
|
196
|
+
out = redactSecrets(v)
|
|
197
|
+
break
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
if (out.length > SANITISE_MAX_LEN) out = out.slice(0, SANITISE_MAX_LEN - 1) + '…'
|
|
203
|
+
return out
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function basename(p: string): string {
|
|
207
|
+
const idx = p.lastIndexOf('/')
|
|
208
|
+
return idx === -1 ? p : p.slice(idx + 1)
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Bearer / sk-/secret-shaped tokens (>= 16 chars of base64-ish run). The pattern
|
|
212
|
+
// is intentionally conservative — we'd rather miss a token than blow away
|
|
213
|
+
// legitimate command text. The renderer's job is to be readable; secret
|
|
214
|
+
// scanning lives elsewhere.
|
|
215
|
+
const SECRET_PATTERNS: ReadonlyArray<RegExp> = [
|
|
216
|
+
/Bearer\s+[A-Za-z0-9._\-+/=]{16,}/g,
|
|
217
|
+
/sk-[A-Za-z0-9_\-]{16,}/g,
|
|
218
|
+
/\b[A-Fa-f0-9]{32,}\b/g, // long hex (e.g. API keys)
|
|
219
|
+
]
|
|
220
|
+
|
|
221
|
+
function redactSecrets(text: string): string {
|
|
222
|
+
let out = text
|
|
223
|
+
for (const re of SECRET_PATTERNS) out = out.replace(re, '[redacted]')
|
|
224
|
+
return out
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Resolve the fleet-row label for a freshly-dispatched sub-agent.
|
|
229
|
+
*
|
|
230
|
+
* Fallback chain (per #662 P0 spec): description → subagentType →
|
|
231
|
+
* first 20 chars of firstPromptText → "agent". `description` comes
|
|
232
|
+
* from the parent's Agent/Task tool_use input; `subagentType` is
|
|
233
|
+
* Claude Code's slot label (e.g. "general-purpose"); the prompt slice
|
|
234
|
+
* is the last-resort handle for ad-hoc dispatches that omit both.
|
|
235
|
+
*/
|
|
236
|
+
export function roleFromDispatch(
|
|
237
|
+
description: string | undefined,
|
|
238
|
+
subagentType: string | undefined,
|
|
239
|
+
firstPromptText: string,
|
|
240
|
+
): string {
|
|
241
|
+
if (description != null && description.trim().length > 0) return description.trim()
|
|
242
|
+
if (subagentType != null && subagentType.trim().length > 0) return subagentType.trim()
|
|
243
|
+
const slice = firstPromptText.slice(0, ROLE_FALLBACK_LEN).trim()
|
|
244
|
+
if (slice.length > 0) return firstPromptText.slice(0, ROLE_FALLBACK_LEN)
|
|
245
|
+
return 'agent'
|
|
246
|
+
}
|