docagent-cli 0.0.35__py3-none-any.whl
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.
- docagent_cli/__init__.py +36 -0
- docagent_cli/__main__.py +6 -0
- docagent_cli/_ask_user_types.py +90 -0
- docagent_cli/_cli_context.py +27 -0
- docagent_cli/_debug.py +52 -0
- docagent_cli/_env_vars.py +56 -0
- docagent_cli/_server_config.py +352 -0
- docagent_cli/_session_stats.py +114 -0
- docagent_cli/_testing_models.py +144 -0
- docagent_cli/_version.py +17 -0
- docagent_cli/agent.py +1193 -0
- docagent_cli/app.py +4979 -0
- docagent_cli/app.tcss +283 -0
- docagent_cli/ask_user.py +301 -0
- docagent_cli/built_in_skills/__init__.py +5 -0
- docagent_cli/built_in_skills/doc-coauthoring/SKILL.md +375 -0
- docagent_cli/built_in_skills/docx/LICENSE.txt +30 -0
- docagent_cli/built_in_skills/docx/SKILL.md +590 -0
- docagent_cli/built_in_skills/docx/scripts/__init__.py +1 -0
- docagent_cli/built_in_skills/docx/scripts/accept_changes.py +135 -0
- docagent_cli/built_in_skills/docx/scripts/comment.py +318 -0
- docagent_cli/built_in_skills/docx/scripts/office/helpers/__init__.py +0 -0
- docagent_cli/built_in_skills/docx/scripts/office/helpers/merge_runs.py +199 -0
- docagent_cli/built_in_skills/docx/scripts/office/helpers/simplify_redlines.py +197 -0
- docagent_cli/built_in_skills/docx/scripts/office/pack.py +159 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/mce/mc.xsd +75 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- docagent_cli/built_in_skills/docx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
- docagent_cli/built_in_skills/docx/scripts/office/soffice.py +183 -0
- docagent_cli/built_in_skills/docx/scripts/office/unpack.py +132 -0
- docagent_cli/built_in_skills/docx/scripts/office/validate.py +111 -0
- docagent_cli/built_in_skills/docx/scripts/office/validators/__init__.py +15 -0
- docagent_cli/built_in_skills/docx/scripts/office/validators/base.py +847 -0
- docagent_cli/built_in_skills/docx/scripts/office/validators/docx.py +446 -0
- docagent_cli/built_in_skills/docx/scripts/office/validators/pptx.py +275 -0
- docagent_cli/built_in_skills/docx/scripts/office/validators/redlining.py +247 -0
- docagent_cli/built_in_skills/docx/scripts/templates/comments.xml +3 -0
- docagent_cli/built_in_skills/docx/scripts/templates/commentsExtended.xml +3 -0
- docagent_cli/built_in_skills/docx/scripts/templates/commentsExtensible.xml +3 -0
- docagent_cli/built_in_skills/docx/scripts/templates/commentsIds.xml +3 -0
- docagent_cli/built_in_skills/docx/scripts/templates/people.xml +3 -0
- docagent_cli/built_in_skills/pdf/LICENSE.txt +30 -0
- docagent_cli/built_in_skills/pdf/SKILL.md +314 -0
- docagent_cli/built_in_skills/pdf/forms.md +294 -0
- docagent_cli/built_in_skills/pdf/reference.md +612 -0
- docagent_cli/built_in_skills/pdf/scripts/check_bounding_boxes.py +65 -0
- docagent_cli/built_in_skills/pdf/scripts/check_fillable_fields.py +11 -0
- docagent_cli/built_in_skills/pdf/scripts/convert_pdf_to_images.py +33 -0
- docagent_cli/built_in_skills/pdf/scripts/create_validation_image.py +37 -0
- docagent_cli/built_in_skills/pdf/scripts/extract_form_field_info.py +122 -0
- docagent_cli/built_in_skills/pdf/scripts/extract_form_structure.py +115 -0
- docagent_cli/built_in_skills/pdf/scripts/fill_fillable_fields.py +98 -0
- docagent_cli/built_in_skills/pdf/scripts/fill_pdf_form_with_annotations.py +107 -0
- docagent_cli/built_in_skills/pptx/LICENSE.txt +30 -0
- docagent_cli/built_in_skills/pptx/SKILL.md +232 -0
- docagent_cli/built_in_skills/pptx/editing.md +205 -0
- docagent_cli/built_in_skills/pptx/pptxgenjs.md +420 -0
- docagent_cli/built_in_skills/pptx/scripts/__init__.py +0 -0
- docagent_cli/built_in_skills/pptx/scripts/add_slide.py +195 -0
- docagent_cli/built_in_skills/pptx/scripts/clean.py +286 -0
- docagent_cli/built_in_skills/pptx/scripts/office/helpers/__init__.py +0 -0
- docagent_cli/built_in_skills/pptx/scripts/office/helpers/merge_runs.py +199 -0
- docagent_cli/built_in_skills/pptx/scripts/office/helpers/simplify_redlines.py +197 -0
- docagent_cli/built_in_skills/pptx/scripts/office/pack.py +159 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/mce/mc.xsd +75 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- docagent_cli/built_in_skills/pptx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
- docagent_cli/built_in_skills/pptx/scripts/office/soffice.py +183 -0
- docagent_cli/built_in_skills/pptx/scripts/office/unpack.py +132 -0
- docagent_cli/built_in_skills/pptx/scripts/office/validate.py +111 -0
- docagent_cli/built_in_skills/pptx/scripts/office/validators/__init__.py +15 -0
- docagent_cli/built_in_skills/pptx/scripts/office/validators/base.py +847 -0
- docagent_cli/built_in_skills/pptx/scripts/office/validators/docx.py +446 -0
- docagent_cli/built_in_skills/pptx/scripts/office/validators/pptx.py +275 -0
- docagent_cli/built_in_skills/pptx/scripts/office/validators/redlining.py +247 -0
- docagent_cli/built_in_skills/pptx/scripts/thumbnail.py +289 -0
- docagent_cli/built_in_skills/remember/SKILL.md +118 -0
- docagent_cli/built_in_skills/skill-creator/LICENSE.txt +202 -0
- docagent_cli/built_in_skills/skill-creator/SKILL.md +485 -0
- docagent_cli/built_in_skills/skill-creator/agents/analyzer.md +274 -0
- docagent_cli/built_in_skills/skill-creator/agents/comparator.md +202 -0
- docagent_cli/built_in_skills/skill-creator/agents/grader.md +223 -0
- docagent_cli/built_in_skills/skill-creator/assets/eval_review.html +146 -0
- docagent_cli/built_in_skills/skill-creator/eval-viewer/generate_review.py +471 -0
- docagent_cli/built_in_skills/skill-creator/eval-viewer/viewer.html +1325 -0
- docagent_cli/built_in_skills/skill-creator/references/schemas.md +430 -0
- docagent_cli/built_in_skills/skill-creator/scripts/__init__.py +0 -0
- docagent_cli/built_in_skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
- docagent_cli/built_in_skills/skill-creator/scripts/generate_report.py +326 -0
- docagent_cli/built_in_skills/skill-creator/scripts/improve_description.py +247 -0
- docagent_cli/built_in_skills/skill-creator/scripts/package_skill.py +136 -0
- docagent_cli/built_in_skills/skill-creator/scripts/quick_validate.py +103 -0
- docagent_cli/built_in_skills/skill-creator/scripts/run_eval.py +310 -0
- docagent_cli/built_in_skills/skill-creator/scripts/run_loop.py +328 -0
- docagent_cli/built_in_skills/skill-creator/scripts/utils.py +47 -0
- docagent_cli/built_in_skills/theme-factory/LICENSE.txt +202 -0
- docagent_cli/built_in_skills/theme-factory/SKILL.md +59 -0
- docagent_cli/built_in_skills/theme-factory/theme-showcase.pdf +0 -0
- docagent_cli/built_in_skills/theme-factory/themes/arctic-frost.md +19 -0
- docagent_cli/built_in_skills/theme-factory/themes/botanical-garden.md +19 -0
- docagent_cli/built_in_skills/theme-factory/themes/desert-rose.md +19 -0
- docagent_cli/built_in_skills/theme-factory/themes/forest-canopy.md +19 -0
- docagent_cli/built_in_skills/theme-factory/themes/golden-hour.md +19 -0
- docagent_cli/built_in_skills/theme-factory/themes/midnight-galaxy.md +19 -0
- docagent_cli/built_in_skills/theme-factory/themes/modern-minimalist.md +19 -0
- docagent_cli/built_in_skills/theme-factory/themes/ocean-depths.md +19 -0
- docagent_cli/built_in_skills/theme-factory/themes/sunset-boulevard.md +19 -0
- docagent_cli/built_in_skills/theme-factory/themes/tech-innovation.md +19 -0
- docagent_cli/built_in_skills/xlsx/LICENSE.txt +30 -0
- docagent_cli/built_in_skills/xlsx/SKILL.md +292 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/helpers/__init__.py +0 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/helpers/merge_runs.py +199 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/helpers/simplify_redlines.py +197 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/pack.py +159 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/mce/mc.xsd +75 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/soffice.py +183 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/unpack.py +132 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/validate.py +111 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/validators/__init__.py +15 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/validators/base.py +847 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/validators/docx.py +446 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/validators/pptx.py +275 -0
- docagent_cli/built_in_skills/xlsx/scripts/office/validators/redlining.py +247 -0
- docagent_cli/built_in_skills/xlsx/scripts/recalc.py +184 -0
- docagent_cli/clipboard.py +128 -0
- docagent_cli/command_registry.py +284 -0
- docagent_cli/config.py +2418 -0
- docagent_cli/configurable_model.py +162 -0
- docagent_cli/default_agent_prompt.md +12 -0
- docagent_cli/editor.py +142 -0
- docagent_cli/file_ops.py +473 -0
- docagent_cli/formatting.py +28 -0
- docagent_cli/hooks.py +206 -0
- docagent_cli/input.py +787 -0
- docagent_cli/integrations/__init__.py +1 -0
- docagent_cli/integrations/sandbox_factory.py +873 -0
- docagent_cli/integrations/sandbox_provider.py +71 -0
- docagent_cli/local_context.py +718 -0
- docagent_cli/main.py +1641 -0
- docagent_cli/mcp_tools.py +707 -0
- docagent_cli/mcp_trust.py +168 -0
- docagent_cli/media_utils.py +478 -0
- docagent_cli/model_config.py +1620 -0
- docagent_cli/non_interactive.py +948 -0
- docagent_cli/offload.py +371 -0
- docagent_cli/output.py +69 -0
- docagent_cli/project_utils.py +188 -0
- docagent_cli/py.typed +0 -0
- docagent_cli/remote_client.py +515 -0
- docagent_cli/server.py +520 -0
- docagent_cli/server_graph.py +196 -0
- docagent_cli/server_manager.py +365 -0
- docagent_cli/sessions.py +1262 -0
- docagent_cli/skills/__init__.py +18 -0
- docagent_cli/skills/commands.py +1090 -0
- docagent_cli/skills/load.py +192 -0
- docagent_cli/subagents.py +173 -0
- docagent_cli/system_prompt.md +247 -0
- docagent_cli/textual_adapter.py +1352 -0
- docagent_cli/theme.py +842 -0
- docagent_cli/token_state.py +31 -0
- docagent_cli/tool_display.py +298 -0
- docagent_cli/tools.py +236 -0
- docagent_cli/ui.py +420 -0
- docagent_cli/unicode_security.py +516 -0
- docagent_cli/update_check.py +454 -0
- docagent_cli/widgets/__init__.py +9 -0
- docagent_cli/widgets/_links.py +63 -0
- docagent_cli/widgets/approval.py +442 -0
- docagent_cli/widgets/ask_user.py +398 -0
- docagent_cli/widgets/autocomplete.py +691 -0
- docagent_cli/widgets/chat_input.py +1827 -0
- docagent_cli/widgets/diff.py +248 -0
- docagent_cli/widgets/history.py +188 -0
- docagent_cli/widgets/loading.py +177 -0
- docagent_cli/widgets/mcp_viewer.py +362 -0
- docagent_cli/widgets/message_store.py +675 -0
- docagent_cli/widgets/messages.py +1751 -0
- docagent_cli/widgets/model_selector.py +964 -0
- docagent_cli/widgets/status.py +372 -0
- docagent_cli/widgets/theme_selector.py +164 -0
- docagent_cli/widgets/thread_selector.py +1905 -0
- docagent_cli/widgets/tool_renderers.py +148 -0
- docagent_cli/widgets/tool_widgets.py +274 -0
- docagent_cli/widgets/welcome.py +339 -0
- docagent_cli-0.0.35.data/data/docagent_cli/default_agent_prompt.md +12 -0
- docagent_cli-0.0.35.dist-info/METADATA +200 -0
- docagent_cli-0.0.35.dist-info/RECORD +300 -0
- docagent_cli-0.0.35.dist-info/WHEEL +4 -0
- docagent_cli-0.0.35.dist-info/entry_points.txt +3 -0
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
"""Status bar widget for docagent-cli."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
from contextlib import suppress
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from typing import TYPE_CHECKING, Any
|
|
9
|
+
|
|
10
|
+
from textual.containers import Horizontal
|
|
11
|
+
from textual.content import Content
|
|
12
|
+
from textual.css.query import NoMatches
|
|
13
|
+
from textual.reactive import reactive
|
|
14
|
+
from textual.widget import Widget
|
|
15
|
+
from textual.widgets import Static
|
|
16
|
+
|
|
17
|
+
from docagent_cli.config import get_glyphs
|
|
18
|
+
|
|
19
|
+
logger = logging.getLogger(__name__)
|
|
20
|
+
|
|
21
|
+
if TYPE_CHECKING:
|
|
22
|
+
from textual import events
|
|
23
|
+
from textual.app import ComposeResult, RenderResult
|
|
24
|
+
from textual.geometry import Size
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class ModelLabel(Widget):
|
|
28
|
+
"""A label that displays a model name, right-aligned with smart truncation.
|
|
29
|
+
|
|
30
|
+
When the full `provider:model` text doesn't fit, the provider is dropped
|
|
31
|
+
first. If the bare model name still doesn't fit, it is left-truncated
|
|
32
|
+
with a leading ellipsis so the most distinctive tail stays visible.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
provider: reactive[str] = reactive("", layout=True)
|
|
36
|
+
model: reactive[str] = reactive("", layout=True)
|
|
37
|
+
|
|
38
|
+
def get_content_width(self, container: Size, viewport: Size) -> int: # noqa: ARG002
|
|
39
|
+
"""Return the intrinsic width so `width: auto` works.
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
container: Size of the container.
|
|
43
|
+
viewport: Size of the viewport.
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
Character length of the full provider:model string.
|
|
47
|
+
"""
|
|
48
|
+
if not self.model:
|
|
49
|
+
return 0
|
|
50
|
+
full = f"{self.provider}:{self.model}" if self.provider else self.model
|
|
51
|
+
return len(full)
|
|
52
|
+
|
|
53
|
+
def render(self) -> RenderResult:
|
|
54
|
+
"""Render the model label with width-aware truncation.
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
Text content, truncated from the left when necessary.
|
|
58
|
+
"""
|
|
59
|
+
width = self.content_size.width
|
|
60
|
+
if not self.model or width <= 0:
|
|
61
|
+
return ""
|
|
62
|
+
full = f"{self.provider}:{self.model}" if self.provider else self.model
|
|
63
|
+
if len(full) <= width:
|
|
64
|
+
return Content(full)
|
|
65
|
+
if len(self.model) <= width:
|
|
66
|
+
return Content(self.model)
|
|
67
|
+
if width > 1:
|
|
68
|
+
return Content("\u2026" + self.model[-(width - 1) :])
|
|
69
|
+
return Content("\u2026")
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class StatusBar(Horizontal):
|
|
73
|
+
"""Status bar showing mode, auto-approve, cwd, git branch, tokens, and model."""
|
|
74
|
+
|
|
75
|
+
DEFAULT_CSS = """
|
|
76
|
+
StatusBar {
|
|
77
|
+
height: 1;
|
|
78
|
+
dock: bottom;
|
|
79
|
+
background: $surface;
|
|
80
|
+
padding: 0 1;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
StatusBar .status-mode {
|
|
84
|
+
width: auto;
|
|
85
|
+
padding: 0 1;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
StatusBar .status-mode.normal {
|
|
89
|
+
display: none;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
StatusBar .status-mode.shell {
|
|
93
|
+
background: $mode-bash;
|
|
94
|
+
color: white;
|
|
95
|
+
text-style: bold;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
StatusBar .status-mode.command {
|
|
99
|
+
background: $mode-command;
|
|
100
|
+
color: white;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
StatusBar .status-auto-approve {
|
|
104
|
+
width: auto;
|
|
105
|
+
padding: 0 1;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
StatusBar .status-auto-approve.on {
|
|
109
|
+
background: $success;
|
|
110
|
+
color: $background;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
StatusBar .status-auto-approve.off {
|
|
114
|
+
background: $warning;
|
|
115
|
+
color: $background;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
StatusBar .status-message {
|
|
119
|
+
width: auto;
|
|
120
|
+
padding: 0 1;
|
|
121
|
+
color: $text-muted;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
StatusBar .status-message.thinking {
|
|
125
|
+
color: $warning;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
StatusBar .status-cwd {
|
|
129
|
+
width: auto;
|
|
130
|
+
text-align: right;
|
|
131
|
+
color: $text-muted;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
StatusBar .status-branch {
|
|
135
|
+
width: auto;
|
|
136
|
+
color: $text-muted;
|
|
137
|
+
padding: 0 1;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
StatusBar .status-left-collapsible {
|
|
141
|
+
width: 1fr;
|
|
142
|
+
min-width: 0;
|
|
143
|
+
height: 1;
|
|
144
|
+
overflow-x: hidden;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
StatusBar .status-tokens {
|
|
148
|
+
width: auto;
|
|
149
|
+
padding: 0 1;
|
|
150
|
+
color: $text-muted;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
StatusBar ModelLabel {
|
|
154
|
+
width: auto;
|
|
155
|
+
padding: 0 2;
|
|
156
|
+
color: $text-muted;
|
|
157
|
+
text-align: right;
|
|
158
|
+
}
|
|
159
|
+
"""
|
|
160
|
+
"""Mode badges and auto-approve pills use distinct colors for at-a-glance status."""
|
|
161
|
+
|
|
162
|
+
mode: reactive[str] = reactive("normal", init=False)
|
|
163
|
+
status_message: reactive[str] = reactive("", init=False)
|
|
164
|
+
auto_approve: reactive[bool] = reactive(default=False, init=False)
|
|
165
|
+
cwd: reactive[str] = reactive("", init=False)
|
|
166
|
+
branch: reactive[str] = reactive("", init=False)
|
|
167
|
+
tokens: reactive[int] = reactive(0, init=False)
|
|
168
|
+
|
|
169
|
+
def __init__(self, cwd: str | Path | None = None, **kwargs: Any) -> None:
|
|
170
|
+
"""Initialize the status bar.
|
|
171
|
+
|
|
172
|
+
Args:
|
|
173
|
+
cwd: Current working directory to display
|
|
174
|
+
**kwargs: Additional arguments passed to parent
|
|
175
|
+
"""
|
|
176
|
+
super().__init__(**kwargs)
|
|
177
|
+
# Store initial cwd - will be used in compose()
|
|
178
|
+
self._initial_cwd = str(cwd) if cwd else str(Path.cwd())
|
|
179
|
+
|
|
180
|
+
def compose(self) -> ComposeResult: # noqa: PLR6301 — Textual widget method
|
|
181
|
+
"""Compose the status bar layout.
|
|
182
|
+
|
|
183
|
+
Yields:
|
|
184
|
+
Widgets for mode, auto-approve, message, cwd, branch, tokens, and
|
|
185
|
+
model display.
|
|
186
|
+
"""
|
|
187
|
+
yield Static("", classes="status-mode normal", id="mode-indicator")
|
|
188
|
+
yield Static(
|
|
189
|
+
"manual | shift+tab to cycle",
|
|
190
|
+
classes="status-auto-approve off",
|
|
191
|
+
id="auto-approve-indicator",
|
|
192
|
+
)
|
|
193
|
+
with Horizontal(classes="status-left-collapsible"):
|
|
194
|
+
yield Static("", classes="status-message", id="status-message")
|
|
195
|
+
yield Static("", classes="status-cwd", id="cwd-display")
|
|
196
|
+
yield Static("", classes="status-branch", id="branch-display")
|
|
197
|
+
yield Static("", classes="status-tokens", id="tokens-display")
|
|
198
|
+
yield ModelLabel(id="model-display")
|
|
199
|
+
|
|
200
|
+
_BRANCH_WIDTH_THRESHOLD = 100
|
|
201
|
+
"""Hide git branch display below this terminal width."""
|
|
202
|
+
_CWD_WIDTH_THRESHOLD = 70
|
|
203
|
+
"""Hide cwd display below this terminal width."""
|
|
204
|
+
|
|
205
|
+
def on_resize(self, event: events.Resize) -> None:
|
|
206
|
+
"""Manage visibility of status items based on terminal width.
|
|
207
|
+
|
|
208
|
+
Priority (highest first): model, cwd, git branch.
|
|
209
|
+
"""
|
|
210
|
+
width = event.size.width
|
|
211
|
+
with suppress(NoMatches):
|
|
212
|
+
self.query_one("#branch-display", Static).display = (
|
|
213
|
+
width >= self._BRANCH_WIDTH_THRESHOLD
|
|
214
|
+
)
|
|
215
|
+
with suppress(NoMatches):
|
|
216
|
+
self.query_one("#cwd-display", Static).display = (
|
|
217
|
+
width >= self._CWD_WIDTH_THRESHOLD
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
def on_mount(self) -> None:
|
|
221
|
+
"""Set reactive values after mount to trigger watchers safely."""
|
|
222
|
+
from docagent_cli.config import settings
|
|
223
|
+
|
|
224
|
+
self.cwd = self._initial_cwd
|
|
225
|
+
# Set initial model display
|
|
226
|
+
label = self.query_one("#model-display", ModelLabel)
|
|
227
|
+
label.provider = settings.model_provider or ""
|
|
228
|
+
label.model = settings.model_name or ""
|
|
229
|
+
|
|
230
|
+
def watch_mode(self, mode: str) -> None:
|
|
231
|
+
"""Update mode indicator when mode changes."""
|
|
232
|
+
try:
|
|
233
|
+
indicator = self.query_one("#mode-indicator", Static)
|
|
234
|
+
except NoMatches:
|
|
235
|
+
return
|
|
236
|
+
indicator.remove_class("normal", "shell", "command")
|
|
237
|
+
|
|
238
|
+
if mode == "shell":
|
|
239
|
+
indicator.update("SHELL")
|
|
240
|
+
indicator.add_class("shell")
|
|
241
|
+
elif mode == "command":
|
|
242
|
+
indicator.update("CMD")
|
|
243
|
+
indicator.add_class("command")
|
|
244
|
+
else:
|
|
245
|
+
indicator.update("")
|
|
246
|
+
indicator.add_class("normal")
|
|
247
|
+
|
|
248
|
+
def watch_auto_approve(self, new_value: bool) -> None:
|
|
249
|
+
"""Update auto-approve indicator when state changes."""
|
|
250
|
+
try:
|
|
251
|
+
indicator = self.query_one("#auto-approve-indicator", Static)
|
|
252
|
+
except NoMatches:
|
|
253
|
+
return
|
|
254
|
+
indicator.remove_class("on", "off")
|
|
255
|
+
|
|
256
|
+
if new_value:
|
|
257
|
+
indicator.update("auto | shift+tab to cycle")
|
|
258
|
+
indicator.add_class("on")
|
|
259
|
+
else:
|
|
260
|
+
indicator.update("manual | shift+tab to cycle")
|
|
261
|
+
indicator.add_class("off")
|
|
262
|
+
|
|
263
|
+
def watch_cwd(self, new_value: str) -> None:
|
|
264
|
+
"""Update cwd display when it changes."""
|
|
265
|
+
try:
|
|
266
|
+
display = self.query_one("#cwd-display", Static)
|
|
267
|
+
except NoMatches:
|
|
268
|
+
return
|
|
269
|
+
display.update(self._format_cwd(new_value))
|
|
270
|
+
|
|
271
|
+
def watch_branch(self, new_value: str) -> None:
|
|
272
|
+
"""Update branch display when it changes."""
|
|
273
|
+
try:
|
|
274
|
+
display = self.query_one("#branch-display", Static)
|
|
275
|
+
except NoMatches:
|
|
276
|
+
return
|
|
277
|
+
icon = get_glyphs().git_branch
|
|
278
|
+
display.update(f"{icon} {new_value}" if new_value else "")
|
|
279
|
+
|
|
280
|
+
def watch_status_message(self, new_value: str) -> None:
|
|
281
|
+
"""Update status message display."""
|
|
282
|
+
try:
|
|
283
|
+
msg_widget = self.query_one("#status-message", Static)
|
|
284
|
+
except NoMatches:
|
|
285
|
+
return
|
|
286
|
+
|
|
287
|
+
msg_widget.remove_class("thinking")
|
|
288
|
+
if new_value:
|
|
289
|
+
msg_widget.update(new_value)
|
|
290
|
+
if "thinking" in new_value.lower() or "executing" in new_value.lower():
|
|
291
|
+
msg_widget.add_class("thinking")
|
|
292
|
+
else:
|
|
293
|
+
msg_widget.update("")
|
|
294
|
+
|
|
295
|
+
def _format_cwd(self, cwd_path: str = "") -> str:
|
|
296
|
+
"""Format the current working directory for display.
|
|
297
|
+
|
|
298
|
+
Returns:
|
|
299
|
+
Formatted path string, using ~ for home directory when possible.
|
|
300
|
+
"""
|
|
301
|
+
path = Path(cwd_path or self.cwd or self._initial_cwd)
|
|
302
|
+
try:
|
|
303
|
+
# Try to use ~ for home directory
|
|
304
|
+
home = Path.home()
|
|
305
|
+
if path.is_relative_to(home):
|
|
306
|
+
return "~/" + path.relative_to(home).as_posix()
|
|
307
|
+
except (ValueError, RuntimeError):
|
|
308
|
+
pass
|
|
309
|
+
return str(path)
|
|
310
|
+
|
|
311
|
+
def set_mode(self, mode: str) -> None:
|
|
312
|
+
"""Set the current input mode.
|
|
313
|
+
|
|
314
|
+
Args:
|
|
315
|
+
mode: One of "normal", "shell", or "command"
|
|
316
|
+
"""
|
|
317
|
+
self.mode = mode
|
|
318
|
+
|
|
319
|
+
def set_auto_approve(self, *, enabled: bool) -> None:
|
|
320
|
+
"""Set the auto-approve state.
|
|
321
|
+
|
|
322
|
+
Args:
|
|
323
|
+
enabled: Whether auto-approve is enabled
|
|
324
|
+
"""
|
|
325
|
+
self.auto_approve = enabled
|
|
326
|
+
|
|
327
|
+
def set_status_message(self, message: str) -> None:
|
|
328
|
+
"""Set the status message.
|
|
329
|
+
|
|
330
|
+
Args:
|
|
331
|
+
message: Status message to display (empty string to clear)
|
|
332
|
+
"""
|
|
333
|
+
self.status_message = message
|
|
334
|
+
|
|
335
|
+
def watch_tokens(self, new_value: int) -> None:
|
|
336
|
+
"""Update token display when count changes."""
|
|
337
|
+
try:
|
|
338
|
+
display = self.query_one("#tokens-display", Static)
|
|
339
|
+
except NoMatches:
|
|
340
|
+
return
|
|
341
|
+
|
|
342
|
+
if new_value > 0:
|
|
343
|
+
# Format with K suffix for thousands
|
|
344
|
+
if new_value >= 1000: # noqa: PLR2004 # Count formatting threshold
|
|
345
|
+
display.update(f"{new_value / 1000:.1f}K tokens")
|
|
346
|
+
else:
|
|
347
|
+
display.update(f"{new_value} tokens")
|
|
348
|
+
else:
|
|
349
|
+
display.update("")
|
|
350
|
+
|
|
351
|
+
def set_tokens(self, count: int) -> None:
|
|
352
|
+
"""Set the token count.
|
|
353
|
+
|
|
354
|
+
Args:
|
|
355
|
+
count: Current context token count
|
|
356
|
+
"""
|
|
357
|
+
self.tokens = count
|
|
358
|
+
|
|
359
|
+
def hide_tokens(self) -> None:
|
|
360
|
+
"""Hide the token display (e.g., during streaming)."""
|
|
361
|
+
self.query_one("#tokens-display", Static).update("")
|
|
362
|
+
|
|
363
|
+
def set_model(self, *, provider: str, model: str) -> None:
|
|
364
|
+
"""Update the model display text.
|
|
365
|
+
|
|
366
|
+
Args:
|
|
367
|
+
provider: Model provider name (e.g., `'anthropic'`).
|
|
368
|
+
model: Model name (e.g., `'claude-sonnet-4-5'`).
|
|
369
|
+
"""
|
|
370
|
+
label = self.query_one("#model-display", ModelLabel)
|
|
371
|
+
label.provider = provider
|
|
372
|
+
label.model = model
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"""Interactive theme selector screen for /theme command."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
from typing import TYPE_CHECKING, ClassVar
|
|
7
|
+
|
|
8
|
+
from textual.binding import Binding, BindingType
|
|
9
|
+
from textual.containers import Vertical
|
|
10
|
+
from textual.screen import ModalScreen
|
|
11
|
+
from textual.widgets import OptionList, Static
|
|
12
|
+
from textual.widgets.option_list import Option
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from textual.app import ComposeResult
|
|
16
|
+
|
|
17
|
+
from docagent_cli import theme
|
|
18
|
+
from docagent_cli.config import get_glyphs, is_ascii_mode
|
|
19
|
+
|
|
20
|
+
logger = logging.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ThemeSelectorScreen(ModalScreen[str | None]):
|
|
24
|
+
"""Modal dialog for theme selection with live preview.
|
|
25
|
+
|
|
26
|
+
Displays available themes in an `OptionList`. Navigating the option list
|
|
27
|
+
applies a live preview by swapping the app theme. Returns the selected
|
|
28
|
+
theme name on Enter, or `None` on Esc (restoring the original theme).
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
BINDINGS: ClassVar[list[BindingType]] = [
|
|
32
|
+
Binding("escape", "cancel", "Cancel", show=False),
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
CSS = """
|
|
36
|
+
ThemeSelectorScreen {
|
|
37
|
+
align: center middle;
|
|
38
|
+
background: transparent;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
ThemeSelectorScreen > Vertical {
|
|
42
|
+
width: 50;
|
|
43
|
+
max-width: 90%;
|
|
44
|
+
height: auto;
|
|
45
|
+
max-height: 80%;
|
|
46
|
+
background: $surface;
|
|
47
|
+
border: solid $primary;
|
|
48
|
+
padding: 1 2;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
ThemeSelectorScreen .theme-selector-title {
|
|
52
|
+
text-style: bold;
|
|
53
|
+
color: $primary;
|
|
54
|
+
text-align: center;
|
|
55
|
+
margin-bottom: 1;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
ThemeSelectorScreen OptionList {
|
|
59
|
+
height: auto;
|
|
60
|
+
max-height: 16;
|
|
61
|
+
background: $background;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
ThemeSelectorScreen .theme-selector-help {
|
|
65
|
+
height: 1;
|
|
66
|
+
color: $text-muted;
|
|
67
|
+
text-style: italic;
|
|
68
|
+
margin-top: 1;
|
|
69
|
+
text-align: center;
|
|
70
|
+
}
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
def __init__(self, current_theme: str) -> None:
|
|
74
|
+
"""Initialize the ThemeSelectorScreen.
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
current_theme: The currently active theme name (to highlight).
|
|
78
|
+
"""
|
|
79
|
+
super().__init__()
|
|
80
|
+
self._current_theme = current_theme
|
|
81
|
+
self._original_theme = current_theme
|
|
82
|
+
|
|
83
|
+
def compose(self) -> ComposeResult:
|
|
84
|
+
"""Compose the screen layout.
|
|
85
|
+
|
|
86
|
+
Yields:
|
|
87
|
+
Widgets for the theme selector UI.
|
|
88
|
+
"""
|
|
89
|
+
glyphs = get_glyphs()
|
|
90
|
+
options: list[Option] = []
|
|
91
|
+
highlight_index = 0
|
|
92
|
+
|
|
93
|
+
for i, (name, entry) in enumerate(theme.ThemeEntry.REGISTRY.items()):
|
|
94
|
+
label = entry.label
|
|
95
|
+
if name == self._current_theme:
|
|
96
|
+
label = f"{label} (current)"
|
|
97
|
+
highlight_index = i
|
|
98
|
+
options.append(Option(label, id=name))
|
|
99
|
+
|
|
100
|
+
with Vertical():
|
|
101
|
+
yield Static("Select Theme", classes="theme-selector-title")
|
|
102
|
+
option_list = OptionList(*options, id="theme-options")
|
|
103
|
+
option_list.highlighted = highlight_index
|
|
104
|
+
yield option_list
|
|
105
|
+
help_text = (
|
|
106
|
+
f"{glyphs.arrow_up}/{glyphs.arrow_down} preview"
|
|
107
|
+
f" {glyphs.bullet} Enter select"
|
|
108
|
+
f" {glyphs.bullet} Esc cancel"
|
|
109
|
+
)
|
|
110
|
+
yield Static(help_text, classes="theme-selector-help")
|
|
111
|
+
|
|
112
|
+
def on_mount(self) -> None:
|
|
113
|
+
"""Apply ASCII border if needed."""
|
|
114
|
+
if is_ascii_mode():
|
|
115
|
+
container = self.query_one(Vertical)
|
|
116
|
+
colors = theme.get_theme_colors(self)
|
|
117
|
+
container.styles.border = ("ascii", colors.success)
|
|
118
|
+
|
|
119
|
+
def on_option_list_option_highlighted(
|
|
120
|
+
self, event: OptionList.OptionHighlighted
|
|
121
|
+
) -> None:
|
|
122
|
+
"""Live-preview the highlighted theme.
|
|
123
|
+
|
|
124
|
+
Args:
|
|
125
|
+
event: The option highlighted event.
|
|
126
|
+
"""
|
|
127
|
+
name = event.option.id
|
|
128
|
+
if name is not None and name in theme.ThemeEntry.REGISTRY:
|
|
129
|
+
try:
|
|
130
|
+
self.app.theme = name
|
|
131
|
+
# refresh_css only repaints the active (modal) screen's layout;
|
|
132
|
+
# force the screen beneath us to repaint so the user sees the
|
|
133
|
+
# preview through the transparent scrim.
|
|
134
|
+
stack = self.app.screen_stack
|
|
135
|
+
if len(stack) > 1:
|
|
136
|
+
stack[-2].refresh(layout=True)
|
|
137
|
+
except Exception:
|
|
138
|
+
logger.warning("Failed to preview theme '%s'", name, exc_info=True)
|
|
139
|
+
try:
|
|
140
|
+
self.app.theme = self._original_theme
|
|
141
|
+
except Exception:
|
|
142
|
+
logger.warning(
|
|
143
|
+
"Failed to restore original theme '%s'",
|
|
144
|
+
self._original_theme,
|
|
145
|
+
exc_info=True,
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
def on_option_list_option_selected(self, event: OptionList.OptionSelected) -> None:
|
|
149
|
+
"""Commit the selected theme.
|
|
150
|
+
|
|
151
|
+
Args:
|
|
152
|
+
event: The option selected event.
|
|
153
|
+
"""
|
|
154
|
+
name = event.option.id
|
|
155
|
+
if name is not None and name in theme.ThemeEntry.REGISTRY:
|
|
156
|
+
self.dismiss(name)
|
|
157
|
+
else:
|
|
158
|
+
logger.warning("Selected theme '%s' is no longer available", name)
|
|
159
|
+
self.dismiss(None)
|
|
160
|
+
|
|
161
|
+
def action_cancel(self) -> None:
|
|
162
|
+
"""Restore the original theme and dismiss."""
|
|
163
|
+
self.app.theme = self._original_theme
|
|
164
|
+
self.dismiss(None)
|