@bastani/atomic 0.5.11 → 0.5.12-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/adapt/SKILL.md +199 -0
- package/.agents/skills/advanced-evaluation/SKILL.md +402 -0
- package/.agents/skills/advanced-evaluation/references/bias-mitigation.md +288 -0
- package/.agents/skills/advanced-evaluation/references/evaluation-pipeline.md +43 -0
- package/.agents/skills/advanced-evaluation/references/implementation-patterns.md +315 -0
- package/.agents/skills/advanced-evaluation/references/metrics-guide.md +331 -0
- package/.agents/skills/advanced-evaluation/scripts/evaluation_example.py +392 -0
- package/.agents/skills/animate/SKILL.md +175 -0
- package/.agents/skills/arrange/SKILL.md +124 -0
- package/.agents/skills/audit/SKILL.md +148 -0
- package/.agents/skills/bdi-mental-states/SKILL.md +311 -0
- package/.agents/skills/bdi-mental-states/references/bdi-ontology-core.md +207 -0
- package/.agents/skills/bdi-mental-states/references/framework-integration.md +582 -0
- package/.agents/skills/bdi-mental-states/references/rdf-examples.md +315 -0
- package/.agents/skills/bdi-mental-states/references/sparql-competency.md +420 -0
- package/.agents/skills/bolder/SKILL.md +117 -0
- package/.agents/skills/bun/SKILL.md +199 -0
- package/.agents/skills/clarify/SKILL.md +183 -0
- package/.agents/skills/colorize/SKILL.md +143 -0
- package/.agents/skills/context-compression/SKILL.md +272 -0
- package/.agents/skills/context-compression/references/evaluation-framework.md +213 -0
- package/.agents/skills/context-compression/scripts/compression_evaluator.py +862 -0
- package/.agents/skills/context-compression/tests/test_compression_evaluator.py +56 -0
- package/.agents/skills/context-degradation/SKILL.md +206 -0
- package/.agents/skills/context-degradation/references/patterns.md +314 -0
- package/.agents/skills/context-degradation/scripts/degradation_detector.py +614 -0
- package/.agents/skills/context-fundamentals/SKILL.md +201 -0
- package/.agents/skills/context-fundamentals/references/context-components.md +283 -0
- package/.agents/skills/context-fundamentals/scripts/context_manager.py +533 -0
- package/.agents/skills/context-optimization/SKILL.md +195 -0
- package/.agents/skills/context-optimization/references/optimization_techniques.md +272 -0
- package/.agents/skills/context-optimization/scripts/compaction.py +562 -0
- package/.agents/skills/create-spec/SKILL.md +244 -0
- package/.agents/skills/critique/SKILL.md +225 -0
- package/.agents/skills/critique/reference/cognitive-load.md +106 -0
- package/.agents/skills/critique/reference/heuristics-scoring.md +234 -0
- package/.agents/skills/critique/reference/personas.md +178 -0
- package/.agents/skills/delight/SKILL.md +304 -0
- package/.agents/skills/distill/SKILL.md +122 -0
- package/.agents/skills/docx/LICENSE.txt +30 -0
- package/.agents/skills/docx/SKILL.md +590 -0
- package/.agents/skills/docx/scripts/__init__.py +1 -0
- package/.agents/skills/docx/scripts/accept_changes.py +135 -0
- package/.agents/skills/docx/scripts/comment.py +318 -0
- package/.agents/skills/docx/scripts/office/helpers/__init__.py +0 -0
- package/.agents/skills/docx/scripts/office/helpers/merge_runs.py +199 -0
- package/.agents/skills/docx/scripts/office/helpers/simplify_redlines.py +197 -0
- package/.agents/skills/docx/scripts/office/pack.py +159 -0
- package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/.agents/skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/.agents/skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/.agents/skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/.agents/skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/.agents/skills/docx/scripts/office/schemas/mce/mc.xsd +75 -0
- package/.agents/skills/docx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
- package/.agents/skills/docx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
- package/.agents/skills/docx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
- package/.agents/skills/docx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/.agents/skills/docx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/.agents/skills/docx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/.agents/skills/docx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/.agents/skills/docx/scripts/office/soffice.py +183 -0
- package/.agents/skills/docx/scripts/office/unpack.py +132 -0
- package/.agents/skills/docx/scripts/office/validate.py +111 -0
- package/.agents/skills/docx/scripts/office/validators/__init__.py +15 -0
- package/.agents/skills/docx/scripts/office/validators/base.py +847 -0
- package/.agents/skills/docx/scripts/office/validators/docx.py +446 -0
- package/.agents/skills/docx/scripts/office/validators/pptx.py +275 -0
- package/.agents/skills/docx/scripts/office/validators/redlining.py +247 -0
- package/.agents/skills/docx/scripts/templates/comments.xml +3 -0
- package/.agents/skills/docx/scripts/templates/commentsExtended.xml +3 -0
- package/.agents/skills/docx/scripts/templates/commentsExtensible.xml +3 -0
- package/.agents/skills/docx/scripts/templates/commentsIds.xml +3 -0
- package/.agents/skills/docx/scripts/templates/people.xml +3 -0
- package/.agents/skills/evaluation/SKILL.md +251 -0
- package/.agents/skills/evaluation/references/metrics.md +339 -0
- package/.agents/skills/evaluation/scripts/evaluator.py +627 -0
- package/.agents/skills/explain-code/SKILL.md +230 -0
- package/.agents/skills/extract/SKILL.md +91 -0
- package/.agents/skills/filesystem-context/SKILL.md +287 -0
- package/.agents/skills/filesystem-context/references/implementation-patterns.md +549 -0
- package/.agents/skills/filesystem-context/scripts/filesystem_context.py +425 -0
- package/.agents/skills/find-skills/SKILL.md +142 -0
- package/.agents/skills/frontend-design/SKILL.md +147 -0
- package/.agents/skills/frontend-design/reference/color-and-contrast.md +132 -0
- package/.agents/skills/frontend-design/reference/interaction-design.md +195 -0
- package/.agents/skills/frontend-design/reference/motion-design.md +99 -0
- package/.agents/skills/frontend-design/reference/responsive-design.md +114 -0
- package/.agents/skills/frontend-design/reference/spatial-design.md +100 -0
- package/.agents/skills/frontend-design/reference/typography.md +133 -0
- package/.agents/skills/frontend-design/reference/ux-writing.md +107 -0
- package/.agents/skills/gh-commit/SKILL.md +243 -0
- package/.agents/skills/gh-create-pr/SKILL.md +93 -0
- package/.agents/skills/harden/SKILL.md +354 -0
- package/.agents/skills/hosted-agents/SKILL.md +260 -0
- package/.agents/skills/hosted-agents/references/infrastructure-patterns.md +700 -0
- package/.agents/skills/hosted-agents/scripts/sandbox_manager.py +590 -0
- package/.agents/skills/impeccable/SKILL.md +365 -0
- package/.agents/skills/impeccable/reference/color-and-contrast.md +105 -0
- package/.agents/skills/impeccable/reference/craft.md +70 -0
- package/.agents/skills/impeccable/reference/extract.md +70 -0
- package/.agents/skills/impeccable/reference/interaction-design.md +195 -0
- package/.agents/skills/impeccable/reference/motion-design.md +99 -0
- package/.agents/skills/impeccable/reference/responsive-design.md +114 -0
- package/.agents/skills/impeccable/reference/spatial-design.md +100 -0
- package/.agents/skills/impeccable/reference/typography.md +142 -0
- package/.agents/skills/impeccable/reference/ux-writing.md +107 -0
- package/.agents/skills/impeccable/scripts/cleanup-deprecated.mjs +214 -0
- package/.agents/skills/init/SKILL.md +138 -0
- package/.agents/skills/layout/SKILL.md +125 -0
- package/.agents/skills/liteparse/SKILL.md +222 -0
- package/.agents/skills/memory-systems/SKILL.md +219 -0
- package/.agents/skills/memory-systems/references/implementation.md +551 -0
- package/.agents/skills/memory-systems/scripts/memory_store.py +616 -0
- package/.agents/skills/multi-agent-patterns/SKILL.md +257 -0
- package/.agents/skills/multi-agent-patterns/references/frameworks.md +433 -0
- package/.agents/skills/multi-agent-patterns/scripts/coordination.py +613 -0
- package/.agents/skills/normalize/SKILL.md +70 -0
- package/.agents/skills/onboard/SKILL.md +245 -0
- package/.agents/skills/opentui/SKILL.md +201 -0
- package/.agents/skills/opentui/references/animation/REFERENCE.md +431 -0
- package/.agents/skills/opentui/references/components/REFERENCE.md +144 -0
- package/.agents/skills/opentui/references/components/code-diff.md +672 -0
- package/.agents/skills/opentui/references/components/containers.md +417 -0
- package/.agents/skills/opentui/references/components/inputs.md +531 -0
- package/.agents/skills/opentui/references/components/text-display.md +386 -0
- package/.agents/skills/opentui/references/core/REFERENCE.md +145 -0
- package/.agents/skills/opentui/references/core/api.md +543 -0
- package/.agents/skills/opentui/references/core/configuration.md +168 -0
- package/.agents/skills/opentui/references/core/gotchas.md +393 -0
- package/.agents/skills/opentui/references/core/patterns.md +449 -0
- package/.agents/skills/opentui/references/keyboard/REFERENCE.md +617 -0
- package/.agents/skills/opentui/references/layout/REFERENCE.md +337 -0
- package/.agents/skills/opentui/references/layout/patterns.md +444 -0
- package/.agents/skills/opentui/references/react/REFERENCE.md +174 -0
- package/.agents/skills/opentui/references/react/api.md +436 -0
- package/.agents/skills/opentui/references/react/configuration.md +302 -0
- package/.agents/skills/opentui/references/react/gotchas.md +443 -0
- package/.agents/skills/opentui/references/react/patterns.md +501 -0
- package/.agents/skills/opentui/references/solid/REFERENCE.md +201 -0
- package/.agents/skills/opentui/references/solid/api.md +564 -0
- package/.agents/skills/opentui/references/solid/configuration.md +316 -0
- package/.agents/skills/opentui/references/solid/gotchas.md +427 -0
- package/.agents/skills/opentui/references/solid/patterns.md +560 -0
- package/.agents/skills/opentui/references/testing/REFERENCE.md +614 -0
- package/.agents/skills/optimize/SKILL.md +266 -0
- package/.agents/skills/overdrive/SKILL.md +142 -0
- package/.agents/skills/pdf/LICENSE.txt +30 -0
- package/.agents/skills/pdf/SKILL.md +314 -0
- package/.agents/skills/pdf/forms.md +294 -0
- package/.agents/skills/pdf/reference.md +612 -0
- package/.agents/skills/pdf/scripts/check_bounding_boxes.py +65 -0
- package/.agents/skills/pdf/scripts/check_fillable_fields.py +11 -0
- package/.agents/skills/pdf/scripts/convert_pdf_to_images.py +33 -0
- package/.agents/skills/pdf/scripts/create_validation_image.py +37 -0
- package/.agents/skills/pdf/scripts/extract_form_field_info.py +122 -0
- package/.agents/skills/pdf/scripts/extract_form_structure.py +115 -0
- package/.agents/skills/pdf/scripts/fill_fillable_fields.py +98 -0
- package/.agents/skills/pdf/scripts/fill_pdf_form_with_annotations.py +107 -0
- package/.agents/skills/playwright-cli/SKILL.md +344 -0
- package/.agents/skills/playwright-cli/references/element-attributes.md +23 -0
- package/.agents/skills/playwright-cli/references/playwright-tests.md +39 -0
- package/.agents/skills/playwright-cli/references/request-mocking.md +87 -0
- package/.agents/skills/playwright-cli/references/running-code.md +231 -0
- package/.agents/skills/playwright-cli/references/session-management.md +169 -0
- package/.agents/skills/playwright-cli/references/storage-state.md +275 -0
- package/.agents/skills/playwright-cli/references/test-generation.md +88 -0
- package/.agents/skills/playwright-cli/references/tracing.md +139 -0
- package/.agents/skills/playwright-cli/references/video-recording.md +143 -0
- package/.agents/skills/polish/SKILL.md +224 -0
- package/.agents/skills/pptx/LICENSE.txt +30 -0
- package/.agents/skills/pptx/SKILL.md +232 -0
- package/.agents/skills/pptx/editing.md +205 -0
- package/.agents/skills/pptx/pptxgenjs.md +420 -0
- package/.agents/skills/pptx/scripts/__init__.py +0 -0
- package/.agents/skills/pptx/scripts/add_slide.py +195 -0
- package/.agents/skills/pptx/scripts/clean.py +286 -0
- package/.agents/skills/pptx/scripts/office/helpers/__init__.py +0 -0
- package/.agents/skills/pptx/scripts/office/helpers/merge_runs.py +199 -0
- package/.agents/skills/pptx/scripts/office/helpers/simplify_redlines.py +197 -0
- package/.agents/skills/pptx/scripts/office/pack.py +159 -0
- package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/.agents/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/.agents/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/.agents/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/.agents/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/.agents/skills/pptx/scripts/office/schemas/mce/mc.xsd +75 -0
- package/.agents/skills/pptx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
- package/.agents/skills/pptx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
- package/.agents/skills/pptx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
- package/.agents/skills/pptx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/.agents/skills/pptx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/.agents/skills/pptx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/.agents/skills/pptx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/.agents/skills/pptx/scripts/office/soffice.py +183 -0
- package/.agents/skills/pptx/scripts/office/unpack.py +132 -0
- package/.agents/skills/pptx/scripts/office/validate.py +111 -0
- package/.agents/skills/pptx/scripts/office/validators/__init__.py +15 -0
- package/.agents/skills/pptx/scripts/office/validators/base.py +847 -0
- package/.agents/skills/pptx/scripts/office/validators/docx.py +446 -0
- package/.agents/skills/pptx/scripts/office/validators/pptx.py +275 -0
- package/.agents/skills/pptx/scripts/office/validators/redlining.py +247 -0
- package/.agents/skills/pptx/scripts/thumbnail.py +289 -0
- package/.agents/skills/project-development/SKILL.md +291 -0
- package/.agents/skills/project-development/references/case-studies.md +388 -0
- package/.agents/skills/project-development/references/pipeline-patterns.md +610 -0
- package/.agents/skills/project-development/scripts/pipeline_template.py +796 -0
- package/.agents/skills/prompt-engineer/SKILL.md +263 -0
- package/.agents/skills/prompt-engineer/references/advanced_patterns.md +271 -0
- package/.agents/skills/prompt-engineer/references/core_prompting.md +137 -0
- package/.agents/skills/prompt-engineer/references/quality_improvement.md +193 -0
- package/.agents/skills/quieter/SKILL.md +103 -0
- package/.agents/skills/research-codebase/SKILL.md +227 -0
- package/.agents/skills/shape/SKILL.md +96 -0
- package/.agents/skills/skill-creator/LICENSE.txt +202 -0
- package/.agents/skills/skill-creator/SKILL.md +485 -0
- package/.agents/skills/skill-creator/agents/analyzer.md +274 -0
- package/.agents/skills/skill-creator/agents/comparator.md +202 -0
- package/.agents/skills/skill-creator/agents/grader.md +223 -0
- package/.agents/skills/skill-creator/assets/eval_review.html +146 -0
- package/.agents/skills/skill-creator/eval-viewer/generate_review.py +471 -0
- package/.agents/skills/skill-creator/eval-viewer/viewer.html +1325 -0
- package/.agents/skills/skill-creator/references/schemas.md +430 -0
- package/.agents/skills/skill-creator/scripts/__init__.py +0 -0
- package/.agents/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
- package/.agents/skills/skill-creator/scripts/generate_report.py +326 -0
- package/.agents/skills/skill-creator/scripts/improve_description.py +247 -0
- package/.agents/skills/skill-creator/scripts/package_skill.py +136 -0
- package/.agents/skills/skill-creator/scripts/quick_validate.py +103 -0
- package/.agents/skills/skill-creator/scripts/run_eval.py +310 -0
- package/.agents/skills/skill-creator/scripts/run_loop.py +328 -0
- package/.agents/skills/skill-creator/scripts/utils.py +47 -0
- package/.agents/skills/sl-commit/SKILL.md +51 -0
- package/.agents/skills/sl-submit-diff/SKILL.md +55 -0
- package/.agents/skills/teach-impeccable/SKILL.md +71 -0
- package/.agents/skills/test-driven-development/SKILL.md +371 -0
- package/.agents/skills/test-driven-development/testing-anti-patterns.md +299 -0
- package/.agents/skills/tool-design/SKILL.md +271 -0
- package/.agents/skills/tool-design/references/architectural_reduction.md +210 -0
- package/.agents/skills/tool-design/references/best_practices.md +176 -0
- package/.agents/skills/tool-design/scripts/description_generator.py +528 -0
- package/.agents/skills/typescript-advanced-types/SKILL.md +719 -0
- package/.agents/skills/typescript-expert/SKILL.md +428 -0
- package/.agents/skills/typescript-expert/references/tsconfig-strict.json +92 -0
- package/.agents/skills/typescript-expert/references/typescript-cheatsheet.md +383 -0
- package/.agents/skills/typescript-expert/references/utility-types.ts +335 -0
- package/.agents/skills/typescript-expert/scripts/ts_diagnostic.py +203 -0
- package/.agents/skills/typescript-react-reviewer/SKILL.md +200 -0
- package/.agents/skills/typescript-react-reviewer/references/antipatterns.md +510 -0
- package/.agents/skills/typescript-react-reviewer/references/checklist.md +267 -0
- package/.agents/skills/typescript-react-reviewer/references/react19-patterns.md +305 -0
- package/.agents/skills/typeset/SKILL.md +116 -0
- package/.agents/skills/workflow-creator/SKILL.md +337 -0
- package/.agents/skills/workflow-creator/references/agent-sessions.md +789 -0
- package/.agents/skills/workflow-creator/references/computation-and-validation.md +224 -0
- package/.agents/skills/workflow-creator/references/control-flow.md +450 -0
- package/.agents/skills/workflow-creator/references/discovery-and-verification.md +156 -0
- package/.agents/skills/workflow-creator/references/failure-modes.md +732 -0
- package/.agents/skills/workflow-creator/references/getting-started.md +289 -0
- package/.agents/skills/workflow-creator/references/session-config.md +355 -0
- package/.agents/skills/workflow-creator/references/state-and-data-flow.md +374 -0
- package/.agents/skills/workflow-creator/references/user-input.md +206 -0
- package/.agents/skills/workflow-creator/references/workflow-inputs.md +274 -0
- package/.agents/skills/xlsx/LICENSE.txt +30 -0
- package/.agents/skills/xlsx/SKILL.md +292 -0
- package/.agents/skills/xlsx/scripts/office/helpers/__init__.py +0 -0
- package/.agents/skills/xlsx/scripts/office/helpers/merge_runs.py +199 -0
- package/.agents/skills/xlsx/scripts/office/helpers/simplify_redlines.py +197 -0
- package/.agents/skills/xlsx/scripts/office/pack.py +159 -0
- package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/.agents/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/.agents/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/.agents/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/.agents/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/.agents/skills/xlsx/scripts/office/schemas/mce/mc.xsd +75 -0
- package/.agents/skills/xlsx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
- package/.agents/skills/xlsx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
- package/.agents/skills/xlsx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
- package/.agents/skills/xlsx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/.agents/skills/xlsx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/.agents/skills/xlsx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/.agents/skills/xlsx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/.agents/skills/xlsx/scripts/office/soffice.py +183 -0
- package/.agents/skills/xlsx/scripts/office/unpack.py +132 -0
- package/.agents/skills/xlsx/scripts/office/validate.py +111 -0
- package/.agents/skills/xlsx/scripts/office/validators/__init__.py +15 -0
- package/.agents/skills/xlsx/scripts/office/validators/base.py +847 -0
- package/.agents/skills/xlsx/scripts/office/validators/docx.py +446 -0
- package/.agents/skills/xlsx/scripts/office/validators/pptx.py +275 -0
- package/.agents/skills/xlsx/scripts/office/validators/redlining.py +247 -0
- package/.agents/skills/xlsx/scripts/recalc.py +184 -0
- package/.claude/agents/reviewer.md +1 -0
- package/.github/agents/reviewer.md +1 -0
- package/.opencode/agents/reviewer.md +1 -0
- package/README.md +274 -169
- package/package.json +6 -7
- package/src/commands/cli/init/index.ts +2 -2
- package/src/commands/cli/init/scm.ts +7 -8
- package/src/commands/cli/workflow-command.test.ts +74 -0
- package/src/commands/cli/workflow.ts +7 -2
- package/src/scripts/bundle-configs.ts +128 -0
- package/src/sdk/components/compact-switcher.tsx +1 -1
- package/src/sdk/components/orchestrator-panel-store.ts +13 -0
- package/src/sdk/components/orchestrator-panel.tsx +10 -0
- package/src/sdk/components/statusline.tsx +13 -1
- package/src/sdk/components/workflow-picker-panel.tsx +407 -296
- package/src/sdk/providers/claude.ts +50 -0
- package/src/sdk/runtime/executor.ts +111 -32
- package/src/sdk/types.ts +7 -0
- package/src/sdk/workflows/builtin/ralph/claude/index.ts +132 -76
- package/src/sdk/workflows/builtin/ralph/copilot/index.ts +129 -71
- package/src/sdk/workflows/builtin/ralph/helpers/git.ts +184 -17
- package/src/sdk/workflows/builtin/ralph/helpers/prompts.ts +463 -79
- package/src/sdk/workflows/builtin/ralph/opencode/index.ts +124 -80
- package/src/services/system/auto-sync.ts +31 -51
- package/src/services/system/skills.ts +56 -60
- package/dist/lib/path-root-guard.d.ts +0 -4
- package/dist/lib/path-root-guard.d.ts.map +0 -1
- package/dist/sdk/components/color-utils.d.ts +0 -4
- package/dist/sdk/components/color-utils.d.ts.map +0 -1
- package/dist/sdk/components/compact-switcher.d.ts +0 -10
- package/dist/sdk/components/compact-switcher.d.ts.map +0 -1
- package/dist/sdk/components/connectors.d.ts +0 -15
- package/dist/sdk/components/connectors.d.ts.map +0 -1
- package/dist/sdk/components/connectors.test.d.ts +0 -2
- package/dist/sdk/components/connectors.test.d.ts.map +0 -1
- package/dist/sdk/components/edge.d.ts +0 -4
- package/dist/sdk/components/edge.d.ts.map +0 -1
- package/dist/sdk/components/error-boundary.d.ts +0 -23
- package/dist/sdk/components/error-boundary.d.ts.map +0 -1
- package/dist/sdk/components/graph-theme.d.ts +0 -17
- package/dist/sdk/components/graph-theme.d.ts.map +0 -1
- package/dist/sdk/components/header.d.ts +0 -3
- package/dist/sdk/components/header.d.ts.map +0 -1
- package/dist/sdk/components/hooks.d.ts +0 -15
- package/dist/sdk/components/hooks.d.ts.map +0 -1
- package/dist/sdk/components/layout.d.ts +0 -27
- package/dist/sdk/components/layout.d.ts.map +0 -1
- package/dist/sdk/components/layout.test.d.ts +0 -2
- package/dist/sdk/components/layout.test.d.ts.map +0 -1
- package/dist/sdk/components/node-card.d.ts +0 -10
- package/dist/sdk/components/node-card.d.ts.map +0 -1
- package/dist/sdk/components/orchestrator-panel-contexts.d.ts +0 -16
- package/dist/sdk/components/orchestrator-panel-contexts.d.ts.map +0 -1
- package/dist/sdk/components/orchestrator-panel-store.d.ts +0 -46
- package/dist/sdk/components/orchestrator-panel-store.d.ts.map +0 -1
- package/dist/sdk/components/orchestrator-panel-store.test.d.ts +0 -2
- package/dist/sdk/components/orchestrator-panel-store.test.d.ts.map +0 -1
- package/dist/sdk/components/orchestrator-panel-types.d.ts +0 -18
- package/dist/sdk/components/orchestrator-panel-types.d.ts.map +0 -1
- package/dist/sdk/components/orchestrator-panel.d.ts +0 -52
- package/dist/sdk/components/orchestrator-panel.d.ts.map +0 -1
- package/dist/sdk/components/session-graph-panel.d.ts +0 -7
- package/dist/sdk/components/session-graph-panel.d.ts.map +0 -1
- package/dist/sdk/components/status-helpers.d.ts +0 -6
- package/dist/sdk/components/status-helpers.d.ts.map +0 -1
- package/dist/sdk/components/statusline.d.ts +0 -7
- package/dist/sdk/components/statusline.d.ts.map +0 -1
- package/dist/sdk/components/workflow-picker-panel.d.ts +0 -123
- package/dist/sdk/components/workflow-picker-panel.d.ts.map +0 -1
- package/dist/sdk/define-workflow.d.ts +0 -78
- package/dist/sdk/define-workflow.d.ts.map +0 -1
- package/dist/sdk/define-workflow.test.d.ts +0 -2
- package/dist/sdk/define-workflow.test.d.ts.map +0 -1
- package/dist/sdk/errors.d.ts +0 -24
- package/dist/sdk/errors.d.ts.map +0 -1
- package/dist/sdk/errors.test.d.ts +0 -2
- package/dist/sdk/errors.test.d.ts.map +0 -1
- package/dist/sdk/index.d.ts +0 -13
- package/dist/sdk/index.d.ts.map +0 -1
- package/dist/sdk/providers/claude.d.ts +0 -170
- package/dist/sdk/providers/claude.d.ts.map +0 -1
- package/dist/sdk/providers/copilot.d.ts +0 -11
- package/dist/sdk/providers/copilot.d.ts.map +0 -1
- package/dist/sdk/providers/opencode.d.ts +0 -11
- package/dist/sdk/providers/opencode.d.ts.map +0 -1
- package/dist/sdk/runtime/discovery.d.ts +0 -86
- package/dist/sdk/runtime/discovery.d.ts.map +0 -1
- package/dist/sdk/runtime/executor-entry.d.ts +0 -11
- package/dist/sdk/runtime/executor-entry.d.ts.map +0 -1
- package/dist/sdk/runtime/executor.d.ts +0 -72
- package/dist/sdk/runtime/executor.d.ts.map +0 -1
- package/dist/sdk/runtime/executor.test.d.ts +0 -2
- package/dist/sdk/runtime/executor.test.d.ts.map +0 -1
- package/dist/sdk/runtime/graph-inference.d.ts +0 -35
- package/dist/sdk/runtime/graph-inference.d.ts.map +0 -1
- package/dist/sdk/runtime/loader.d.ts +0 -70
- package/dist/sdk/runtime/loader.d.ts.map +0 -1
- package/dist/sdk/runtime/panel.d.ts +0 -9
- package/dist/sdk/runtime/panel.d.ts.map +0 -1
- package/dist/sdk/runtime/theme.d.ts +0 -28
- package/dist/sdk/runtime/theme.d.ts.map +0 -1
- package/dist/sdk/runtime/tmux.d.ts +0 -297
- package/dist/sdk/runtime/tmux.d.ts.map +0 -1
- package/dist/sdk/types.d.ts +0 -295
- package/dist/sdk/types.d.ts.map +0 -1
- package/dist/sdk/workflows/builtin/deep-research-codebase/claude/index.d.ts +0 -62
- package/dist/sdk/workflows/builtin/deep-research-codebase/claude/index.d.ts.map +0 -1
- package/dist/sdk/workflows/builtin/deep-research-codebase/copilot/index.d.ts +0 -46
- package/dist/sdk/workflows/builtin/deep-research-codebase/copilot/index.d.ts.map +0 -1
- package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/heuristic.d.ts +0 -26
- package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/heuristic.d.ts.map +0 -1
- package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/prompts.d.ts +0 -92
- package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/prompts.d.ts.map +0 -1
- package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/scout.d.ts +0 -57
- package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/scout.d.ts.map +0 -1
- package/dist/sdk/workflows/builtin/deep-research-codebase/opencode/index.d.ts +0 -49
- package/dist/sdk/workflows/builtin/deep-research-codebase/opencode/index.d.ts.map +0 -1
- package/dist/sdk/workflows/builtin/ralph/claude/index.d.ts +0 -14
- package/dist/sdk/workflows/builtin/ralph/claude/index.d.ts.map +0 -1
- package/dist/sdk/workflows/builtin/ralph/copilot/index.d.ts +0 -14
- package/dist/sdk/workflows/builtin/ralph/copilot/index.d.ts.map +0 -1
- package/dist/sdk/workflows/builtin/ralph/helpers/git.d.ts +0 -17
- package/dist/sdk/workflows/builtin/ralph/helpers/git.d.ts.map +0 -1
- package/dist/sdk/workflows/builtin/ralph/helpers/prompts.d.ts +0 -119
- package/dist/sdk/workflows/builtin/ralph/helpers/prompts.d.ts.map +0 -1
- package/dist/sdk/workflows/builtin/ralph/helpers/review.d.ts +0 -20
- package/dist/sdk/workflows/builtin/ralph/helpers/review.d.ts.map +0 -1
- package/dist/sdk/workflows/builtin/ralph/opencode/index.d.ts +0 -14
- package/dist/sdk/workflows/builtin/ralph/opencode/index.d.ts.map +0 -1
- package/dist/sdk/workflows/index.d.ts +0 -24
- package/dist/sdk/workflows/index.d.ts.map +0 -1
- package/dist/services/config/definitions.d.ts +0 -85
- package/dist/services/config/definitions.d.ts.map +0 -1
- package/dist/services/system/copy.d.ts +0 -77
- package/dist/services/system/copy.d.ts.map +0 -1
- package/dist/services/system/detect.d.ts +0 -75
- package/dist/services/system/detect.d.ts.map +0 -1
- package/tsconfig.json +0 -33
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* declared `WorkflowInput`). Free-form workflows fall back to
|
|
11
11
|
* a single `prompt` text field.
|
|
12
12
|
*
|
|
13
|
-
* Pressing ⌃
|
|
13
|
+
* Pressing ⌃d in the prompt phase validates required fields and opens a
|
|
14
14
|
* CONFIRM modal that shows the fully-composed shell command before
|
|
15
15
|
* submission. y/↵ confirms, n/esc cancels back to the form.
|
|
16
16
|
*
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
import {
|
|
30
30
|
createCliRenderer,
|
|
31
31
|
type CliRenderer,
|
|
32
|
+
type KeyEvent,
|
|
32
33
|
type TextareaRenderable,
|
|
33
34
|
} from "@opentui/core";
|
|
34
35
|
import {
|
|
@@ -36,7 +37,7 @@ import {
|
|
|
36
37
|
useKeyboard,
|
|
37
38
|
type Root,
|
|
38
39
|
} from "@opentui/react";
|
|
39
|
-
import { useState, useEffect, useMemo, useRef, useCallback } from "react";
|
|
40
|
+
import { useState, useEffect, useMemo, useRef, useCallback, useContext, createContext, memo } from "react";
|
|
40
41
|
import { useLatest } from "./hooks.ts";
|
|
41
42
|
import { resolveTheme, type TerminalTheme } from "../runtime/theme.ts";
|
|
42
43
|
import type { AgentType, WorkflowInput } from "../types.ts";
|
|
@@ -67,13 +68,12 @@ export interface PickerTheme {
|
|
|
67
68
|
borderActive: string;
|
|
68
69
|
}
|
|
69
70
|
|
|
70
|
-
export function buildPickerTheme(base: TerminalTheme): PickerTheme {
|
|
71
|
+
export function buildPickerTheme(base: TerminalTheme, isDark: boolean): PickerTheme {
|
|
71
72
|
// For dark mode the prototype values track Catppuccin Mocha. For light
|
|
72
73
|
// mode we derive muted variants from the base palette — the specific
|
|
73
74
|
// extras (`info`, `mauve`, the three-level background ladder) have no
|
|
74
75
|
// direct entries in `TerminalTheme`, so we pick close-enough Catppuccin
|
|
75
76
|
// values to keep the picker visually consistent with the orchestrator.
|
|
76
|
-
const isDark = base.bg !== "#eff1f5";
|
|
77
77
|
return {
|
|
78
78
|
background: base.bg,
|
|
79
79
|
backgroundPanel: isDark ? "#181825" : "#e6e9ef",
|
|
@@ -93,6 +93,17 @@ export function buildPickerTheme(base: TerminalTheme): PickerTheme {
|
|
|
93
93
|
};
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
+
// ─── Theme Context ─────────────────────────────
|
|
97
|
+
// Avoids drilling `theme` through every component in the tree.
|
|
98
|
+
|
|
99
|
+
const PickerThemeContext = createContext<PickerTheme | null>(null);
|
|
100
|
+
|
|
101
|
+
function usePickerTheme(): PickerTheme {
|
|
102
|
+
const theme = useContext(PickerThemeContext);
|
|
103
|
+
if (!theme) throw new Error("usePickerTheme must be used within a PickerThemeContext provider");
|
|
104
|
+
return theme;
|
|
105
|
+
}
|
|
106
|
+
|
|
96
107
|
// ─── Types ──────────────────────────────────────
|
|
97
108
|
|
|
98
109
|
type Source = "local" | "global" | "builtin";
|
|
@@ -115,6 +126,10 @@ const DEFAULT_PROMPT_INPUT: WorkflowInput = {
|
|
|
115
126
|
placeholder: "describe your task…",
|
|
116
127
|
};
|
|
117
128
|
|
|
129
|
+
/** Stable single-element array for free-form workflows — avoids allocating
|
|
130
|
+
* a new `[DEFAULT_PROMPT_INPUT]` on every useMemo recomputation. */
|
|
131
|
+
const DEFAULT_FIELDS: WorkflowInput[] = [DEFAULT_PROMPT_INPUT];
|
|
132
|
+
|
|
118
133
|
// ─── Helpers ────────────────────────────────────
|
|
119
134
|
|
|
120
135
|
const SOURCE_DISPLAY: Record<Source, string> = {
|
|
@@ -135,6 +150,13 @@ const SOURCE_COLOR: Record<Source, keyof PickerTheme> = {
|
|
|
135
150
|
builtin: "info",
|
|
136
151
|
};
|
|
137
152
|
|
|
153
|
+
/** Higher number wins when two workflows share a name. */
|
|
154
|
+
const SOURCE_PRECEDENCE: Record<Source, number> = {
|
|
155
|
+
global: 0,
|
|
156
|
+
local: 1,
|
|
157
|
+
builtin: 2,
|
|
158
|
+
};
|
|
159
|
+
|
|
138
160
|
/**
|
|
139
161
|
* Subsequence fuzzy match — Telescope-style. Returns a score (lower =
|
|
140
162
|
* better) or null for no match. Adjacent matches are rewarded; jumps over
|
|
@@ -175,13 +197,31 @@ type ListRow =
|
|
|
175
197
|
| { kind: "section"; source: Source }
|
|
176
198
|
| { kind: "entry"; entry: ListEntry };
|
|
177
199
|
|
|
200
|
+
/**
|
|
201
|
+
* Deduplicate workflows by name using builtin > local > global precedence.
|
|
202
|
+
* When two workflows share a name, only the higher-precedence entry is kept.
|
|
203
|
+
*/
|
|
204
|
+
export function deduplicateByName(
|
|
205
|
+
workflows: WorkflowWithMetadata[],
|
|
206
|
+
): WorkflowWithMetadata[] {
|
|
207
|
+
const byName = new Map<string, WorkflowWithMetadata>();
|
|
208
|
+
for (const wf of workflows) {
|
|
209
|
+
const existing = byName.get(wf.name);
|
|
210
|
+
if (!existing || SOURCE_PRECEDENCE[wf.source] > SOURCE_PRECEDENCE[existing.source]) {
|
|
211
|
+
byName.set(wf.name, wf);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
return Array.from(byName.values());
|
|
215
|
+
}
|
|
216
|
+
|
|
178
217
|
export function buildEntries(
|
|
179
218
|
query: string,
|
|
180
219
|
workflows: WorkflowWithMetadata[],
|
|
181
220
|
): ListEntry[] {
|
|
221
|
+
const deduped = deduplicateByName(workflows);
|
|
182
222
|
type Scored = { wf: WorkflowWithMetadata; score: number };
|
|
183
223
|
const scored: Scored[] = [];
|
|
184
|
-
for (const wf of
|
|
224
|
+
for (const wf of deduped) {
|
|
185
225
|
const nameScore = fuzzyMatch(query, wf.name);
|
|
186
226
|
const descScore = fuzzyMatch(query, wf.description);
|
|
187
227
|
const best =
|
|
@@ -240,13 +280,12 @@ export function isFieldValid(field: WorkflowInput, value: string): boolean {
|
|
|
240
280
|
|
|
241
281
|
// ─── Components ─────────────────────────────────
|
|
242
282
|
|
|
243
|
-
function SectionLabel({
|
|
244
|
-
theme,
|
|
283
|
+
const SectionLabel = memo(function SectionLabel({
|
|
245
284
|
label,
|
|
246
285
|
}: {
|
|
247
|
-
theme: PickerTheme;
|
|
248
286
|
label: string;
|
|
249
287
|
}) {
|
|
288
|
+
const theme = usePickerTheme();
|
|
250
289
|
return (
|
|
251
290
|
<box height={1} flexDirection="row">
|
|
252
291
|
<text>
|
|
@@ -257,19 +296,18 @@ function SectionLabel({
|
|
|
257
296
|
</text>
|
|
258
297
|
</box>
|
|
259
298
|
);
|
|
260
|
-
}
|
|
299
|
+
});
|
|
261
300
|
|
|
262
301
|
function FilterBar({
|
|
263
|
-
theme,
|
|
264
302
|
query,
|
|
265
303
|
focused,
|
|
266
304
|
onInput,
|
|
267
305
|
}: {
|
|
268
|
-
theme: PickerTheme;
|
|
269
306
|
query: string;
|
|
270
307
|
focused: boolean;
|
|
271
308
|
onInput: (value: string) => void;
|
|
272
309
|
}) {
|
|
310
|
+
const theme = usePickerTheme();
|
|
273
311
|
return (
|
|
274
312
|
<box
|
|
275
313
|
minHeight={3}
|
|
@@ -301,37 +339,38 @@ function FilterBar({
|
|
|
301
339
|
);
|
|
302
340
|
}
|
|
303
341
|
|
|
304
|
-
function WorkflowList({
|
|
305
|
-
theme,
|
|
342
|
+
const WorkflowList = memo(function WorkflowList({
|
|
306
343
|
rows,
|
|
307
344
|
focusedEntryIdx,
|
|
308
345
|
}: {
|
|
309
|
-
theme: PickerTheme;
|
|
310
346
|
rows: ListRow[];
|
|
311
347
|
focusedEntryIdx: number;
|
|
312
348
|
}) {
|
|
313
|
-
|
|
314
|
-
return (
|
|
315
|
-
<box paddingLeft={2} paddingTop={2}>
|
|
316
|
-
<text>
|
|
317
|
-
<span fg={theme.textDim}>no matches</span>
|
|
318
|
-
</text>
|
|
319
|
-
</box>
|
|
320
|
-
);
|
|
321
|
-
}
|
|
322
|
-
|
|
349
|
+
const theme = usePickerTheme();
|
|
323
350
|
// Pre-compute entry indices so the render pass is side-effect-free.
|
|
351
|
+
// Must live before any early return to satisfy the Rules of Hooks.
|
|
324
352
|
const entryIndexByRow = useMemo(() => {
|
|
325
353
|
const map = new Map<number, number>();
|
|
326
354
|
let counter = 0;
|
|
327
355
|
for (let i = 0; i < rows.length; i++) {
|
|
328
|
-
|
|
356
|
+
const row = rows[i];
|
|
357
|
+
if (row && row.kind === "entry") {
|
|
329
358
|
map.set(i, counter++);
|
|
330
359
|
}
|
|
331
360
|
}
|
|
332
361
|
return map;
|
|
333
362
|
}, [rows]);
|
|
334
363
|
|
|
364
|
+
if (rows.length === 0) {
|
|
365
|
+
return (
|
|
366
|
+
<box paddingLeft={2} paddingTop={2}>
|
|
367
|
+
<text>
|
|
368
|
+
<span fg={theme.textDim}>no matches</span>
|
|
369
|
+
</text>
|
|
370
|
+
</box>
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
|
|
335
374
|
return (
|
|
336
375
|
<box flexDirection="column">
|
|
337
376
|
{rows.map((row, i) => {
|
|
@@ -339,7 +378,7 @@ function WorkflowList({
|
|
|
339
378
|
const src = row.source;
|
|
340
379
|
return (
|
|
341
380
|
<box
|
|
342
|
-
key={`
|
|
381
|
+
key={`section-${src}`}
|
|
343
382
|
height={2}
|
|
344
383
|
paddingTop={1}
|
|
345
384
|
paddingLeft={2}
|
|
@@ -361,7 +400,7 @@ function WorkflowList({
|
|
|
361
400
|
|
|
362
401
|
return (
|
|
363
402
|
<box
|
|
364
|
-
key={`
|
|
403
|
+
key={`wf-${wf.name}`}
|
|
365
404
|
height={1}
|
|
366
405
|
flexDirection="row"
|
|
367
406
|
backgroundColor={isFocused ? theme.border : "transparent"}
|
|
@@ -381,20 +420,21 @@ function WorkflowList({
|
|
|
381
420
|
})}
|
|
382
421
|
</box>
|
|
383
422
|
);
|
|
384
|
-
}
|
|
423
|
+
});
|
|
385
424
|
|
|
386
|
-
function ArgumentRow({
|
|
387
|
-
theme,
|
|
425
|
+
const ArgumentRow = memo(function ArgumentRow({
|
|
388
426
|
field,
|
|
389
427
|
}: {
|
|
390
|
-
theme: PickerTheme;
|
|
391
428
|
field: WorkflowInput;
|
|
392
429
|
}) {
|
|
430
|
+
const theme = usePickerTheme();
|
|
393
431
|
const isRequired = field.required ?? false;
|
|
394
432
|
const tagCol = isRequired ? theme.warning : theme.textDim;
|
|
395
433
|
const tagLabel = isRequired ? "required" : "optional";
|
|
396
|
-
const
|
|
397
|
-
field.type === "enum" && field.values && field.values.length > 0
|
|
434
|
+
const enumValues =
|
|
435
|
+
field.type === "enum" && field.values && field.values.length > 0
|
|
436
|
+
? field.values
|
|
437
|
+
: null;
|
|
398
438
|
|
|
399
439
|
return (
|
|
400
440
|
<box flexDirection="column" paddingLeft={2} paddingRight={2}>
|
|
@@ -418,10 +458,10 @@ function ArgumentRow({
|
|
|
418
458
|
</box>
|
|
419
459
|
) : null}
|
|
420
460
|
|
|
421
|
-
{
|
|
461
|
+
{enumValues ? (
|
|
422
462
|
<box height={1}>
|
|
423
463
|
<text>
|
|
424
|
-
<span fg={theme.textDim}>{
|
|
464
|
+
<span fg={theme.textDim}>{enumValues.join(" · ")}</span>
|
|
425
465
|
</text>
|
|
426
466
|
</box>
|
|
427
467
|
) : null}
|
|
@@ -429,17 +469,16 @@ function ArgumentRow({
|
|
|
429
469
|
<box height={1} />
|
|
430
470
|
</box>
|
|
431
471
|
);
|
|
432
|
-
}
|
|
472
|
+
});
|
|
433
473
|
|
|
434
|
-
function Preview({
|
|
435
|
-
theme,
|
|
474
|
+
const Preview = memo(function Preview({
|
|
436
475
|
wf,
|
|
437
476
|
}: {
|
|
438
|
-
theme: PickerTheme;
|
|
439
477
|
wf: WorkflowWithMetadata;
|
|
440
478
|
}) {
|
|
441
|
-
const
|
|
442
|
-
|
|
479
|
+
const theme = usePickerTheme();
|
|
480
|
+
const args: readonly WorkflowInput[] =
|
|
481
|
+
wf.inputs.length > 0 ? wf.inputs : DEFAULT_FIELDS;
|
|
443
482
|
|
|
444
483
|
return (
|
|
445
484
|
<box
|
|
@@ -475,22 +514,21 @@ function Preview({
|
|
|
475
514
|
|
|
476
515
|
<box height={2} />
|
|
477
516
|
|
|
478
|
-
<SectionLabel
|
|
517
|
+
<SectionLabel label="ARGUMENTS" />
|
|
479
518
|
<box height={1} />
|
|
480
519
|
{args.map((f) => (
|
|
481
|
-
<ArgumentRow key={f.name}
|
|
520
|
+
<ArgumentRow key={f.name} field={f} />
|
|
482
521
|
))}
|
|
483
522
|
</box>
|
|
484
523
|
);
|
|
485
|
-
}
|
|
524
|
+
});
|
|
486
525
|
|
|
487
526
|
function EmptyPreview({
|
|
488
|
-
theme,
|
|
489
527
|
query,
|
|
490
528
|
}: {
|
|
491
|
-
theme: PickerTheme;
|
|
492
529
|
query: string;
|
|
493
530
|
}) {
|
|
531
|
+
const theme = usePickerTheme();
|
|
494
532
|
return (
|
|
495
533
|
<box
|
|
496
534
|
flexDirection="column"
|
|
@@ -529,20 +567,22 @@ function EmptyPreview({
|
|
|
529
567
|
const TEXT_FIELD_LINES = 3;
|
|
530
568
|
|
|
531
569
|
|
|
570
|
+
const NOOP_CHANGE_REF: React.RefObject<((value: string) => void) | null> = { current: null };
|
|
571
|
+
|
|
532
572
|
function TextAreaContent({
|
|
533
|
-
theme,
|
|
534
573
|
value,
|
|
535
574
|
placeholder,
|
|
536
575
|
focused,
|
|
537
576
|
onChangeRef,
|
|
538
577
|
}: {
|
|
539
|
-
theme: PickerTheme;
|
|
540
578
|
value: string;
|
|
541
579
|
placeholder: string;
|
|
542
580
|
focused: boolean;
|
|
543
|
-
onChangeRef
|
|
581
|
+
onChangeRef?: React.RefObject<((value: string) => void) | null>;
|
|
544
582
|
}) {
|
|
583
|
+
const theme = usePickerTheme();
|
|
545
584
|
const ref = useRef<TextareaRenderable>(null);
|
|
585
|
+
const changeRef = onChangeRef ?? NOOP_CHANGE_REF;
|
|
546
586
|
|
|
547
587
|
// Sync external value → textarea when it diverges (e.g. initial value).
|
|
548
588
|
useEffect(() => {
|
|
@@ -556,12 +596,12 @@ function TextAreaContent({
|
|
|
556
596
|
const ta = ref.current;
|
|
557
597
|
if (!ta) return;
|
|
558
598
|
ta.onContentChange = () => {
|
|
559
|
-
|
|
599
|
+
changeRef.current?.(ta.plainText);
|
|
560
600
|
};
|
|
561
601
|
return () => {
|
|
562
602
|
ta.onContentChange = undefined;
|
|
563
603
|
};
|
|
564
|
-
}, [
|
|
604
|
+
}, [changeRef]);
|
|
565
605
|
|
|
566
606
|
return (
|
|
567
607
|
<textarea
|
|
@@ -581,18 +621,17 @@ function TextAreaContent({
|
|
|
581
621
|
}
|
|
582
622
|
|
|
583
623
|
function StringContent({
|
|
584
|
-
theme,
|
|
585
624
|
value,
|
|
586
625
|
placeholder,
|
|
587
626
|
focused,
|
|
588
627
|
onInput,
|
|
589
628
|
}: {
|
|
590
|
-
theme: PickerTheme;
|
|
591
629
|
value: string;
|
|
592
630
|
placeholder: string;
|
|
593
631
|
focused: boolean;
|
|
594
632
|
onInput: (value: string) => void;
|
|
595
633
|
}) {
|
|
634
|
+
const theme = usePickerTheme();
|
|
596
635
|
return (
|
|
597
636
|
<input
|
|
598
637
|
value={value}
|
|
@@ -609,16 +648,15 @@ function StringContent({
|
|
|
609
648
|
}
|
|
610
649
|
|
|
611
650
|
function EnumContent({
|
|
612
|
-
theme,
|
|
613
651
|
values,
|
|
614
652
|
selected,
|
|
615
653
|
focused,
|
|
616
654
|
}: {
|
|
617
|
-
theme: PickerTheme;
|
|
618
655
|
values: string[];
|
|
619
656
|
selected: string;
|
|
620
657
|
focused: boolean;
|
|
621
658
|
}) {
|
|
659
|
+
const theme = usePickerTheme();
|
|
622
660
|
return (
|
|
623
661
|
<box height={1} flexDirection="row">
|
|
624
662
|
{values.map((v, i) => {
|
|
@@ -652,21 +690,20 @@ function EnumContent({
|
|
|
652
690
|
);
|
|
653
691
|
}
|
|
654
692
|
|
|
655
|
-
function Field({
|
|
656
|
-
theme,
|
|
693
|
+
const Field = memo(function Field({
|
|
657
694
|
field,
|
|
658
695
|
value,
|
|
659
696
|
focused,
|
|
660
|
-
|
|
697
|
+
onFieldInput,
|
|
661
698
|
onTextChangeRef,
|
|
662
699
|
}: {
|
|
663
|
-
theme: PickerTheme;
|
|
664
700
|
field: WorkflowInput;
|
|
665
701
|
value: string;
|
|
666
702
|
focused: boolean;
|
|
667
|
-
|
|
668
|
-
onTextChangeRef
|
|
703
|
+
onFieldInput: (fieldName: string, value: string) => void;
|
|
704
|
+
onTextChangeRef?: React.RefObject<((value: string) => void) | null>;
|
|
669
705
|
}) {
|
|
706
|
+
const theme = usePickerTheme();
|
|
670
707
|
const borderCol = focused ? theme.primary : theme.border;
|
|
671
708
|
const bgCol = focused ? theme.backgroundPanel : theme.backgroundElement;
|
|
672
709
|
|
|
@@ -676,6 +713,12 @@ function Field({
|
|
|
676
713
|
const tagLabel = field.required ? "required" : "optional";
|
|
677
714
|
const captionDesc = field.description ? " · " + field.description : "";
|
|
678
715
|
|
|
716
|
+
// Bind the field name once so the parent doesn't need a per-field closure.
|
|
717
|
+
const onInput = useCallback(
|
|
718
|
+
(v: string) => onFieldInput(field.name, v),
|
|
719
|
+
[onFieldInput, field.name],
|
|
720
|
+
);
|
|
721
|
+
|
|
679
722
|
return (
|
|
680
723
|
<box flexDirection="column">
|
|
681
724
|
<box
|
|
@@ -693,7 +736,6 @@ function Field({
|
|
|
693
736
|
>
|
|
694
737
|
{field.type === "text" ? (
|
|
695
738
|
<TextAreaContent
|
|
696
|
-
theme={theme}
|
|
697
739
|
value={value}
|
|
698
740
|
placeholder={field.placeholder ?? ""}
|
|
699
741
|
focused={focused}
|
|
@@ -701,7 +743,6 @@ function Field({
|
|
|
701
743
|
/>
|
|
702
744
|
) : field.type === "string" ? (
|
|
703
745
|
<StringContent
|
|
704
|
-
theme={theme}
|
|
705
746
|
value={value}
|
|
706
747
|
placeholder={field.placeholder ?? ""}
|
|
707
748
|
focused={focused}
|
|
@@ -709,7 +750,6 @@ function Field({
|
|
|
709
750
|
/>
|
|
710
751
|
) : field.type === "enum" ? (
|
|
711
752
|
<EnumContent
|
|
712
|
-
theme={theme}
|
|
713
753
|
values={field.values ?? []}
|
|
714
754
|
selected={value}
|
|
715
755
|
focused={focused}
|
|
@@ -729,10 +769,9 @@ function Field({
|
|
|
729
769
|
<box height={1} />
|
|
730
770
|
</box>
|
|
731
771
|
);
|
|
732
|
-
}
|
|
772
|
+
});
|
|
733
773
|
|
|
734
774
|
function InputPhase({
|
|
735
|
-
theme,
|
|
736
775
|
workflow,
|
|
737
776
|
agent,
|
|
738
777
|
fields,
|
|
@@ -741,15 +780,15 @@ function InputPhase({
|
|
|
741
780
|
onFieldInput,
|
|
742
781
|
onTextChangeRef,
|
|
743
782
|
}: {
|
|
744
|
-
theme: PickerTheme;
|
|
745
783
|
workflow: WorkflowWithMetadata;
|
|
746
784
|
agent: AgentType;
|
|
747
|
-
fields: WorkflowInput[];
|
|
785
|
+
fields: readonly WorkflowInput[];
|
|
748
786
|
values: Record<string, string>;
|
|
749
787
|
focusedFieldIdx: number;
|
|
750
788
|
onFieldInput: (fieldName: string, value: string) => void;
|
|
751
789
|
onTextChangeRef: React.RefObject<((value: string) => void) | null>;
|
|
752
790
|
}) {
|
|
791
|
+
const theme = usePickerTheme();
|
|
753
792
|
const isStructured = workflow.inputs.length > 0;
|
|
754
793
|
|
|
755
794
|
return (
|
|
@@ -816,12 +855,15 @@ function InputPhase({
|
|
|
816
855
|
{fields.map((f, i) => (
|
|
817
856
|
<Field
|
|
818
857
|
key={f.name}
|
|
819
|
-
theme={theme}
|
|
820
858
|
field={f}
|
|
821
859
|
value={values[f.name] ?? ""}
|
|
822
860
|
focused={i === focusedFieldIdx}
|
|
823
|
-
|
|
824
|
-
onTextChangeRef={
|
|
861
|
+
onFieldInput={onFieldInput}
|
|
862
|
+
onTextChangeRef={
|
|
863
|
+
f.type === "text" && i === focusedFieldIdx
|
|
864
|
+
? onTextChangeRef
|
|
865
|
+
: undefined
|
|
866
|
+
}
|
|
825
867
|
/>
|
|
826
868
|
))}
|
|
827
869
|
</box>
|
|
@@ -829,14 +871,13 @@ function InputPhase({
|
|
|
829
871
|
}
|
|
830
872
|
|
|
831
873
|
function ConfirmModal({
|
|
832
|
-
theme,
|
|
833
874
|
workflow,
|
|
834
875
|
agent,
|
|
835
876
|
}: {
|
|
836
|
-
theme: PickerTheme;
|
|
837
877
|
workflow: WorkflowWithMetadata;
|
|
838
878
|
agent: AgentType;
|
|
839
879
|
}) {
|
|
880
|
+
const theme = usePickerTheme();
|
|
840
881
|
return (
|
|
841
882
|
<box
|
|
842
883
|
position="absolute"
|
|
@@ -897,16 +938,28 @@ function ConfirmModal({
|
|
|
897
938
|
);
|
|
898
939
|
}
|
|
899
940
|
|
|
900
|
-
// Stable hint arrays —
|
|
901
|
-
|
|
941
|
+
// Stable hint arrays — pre-built so they never create new references.
|
|
942
|
+
type Hint = { key: string; label: string; dim?: boolean };
|
|
943
|
+
|
|
944
|
+
const PICK_HINTS: Hint[] = [
|
|
902
945
|
{ key: "↑↓", label: "navigate" },
|
|
903
946
|
{ key: "↵", label: "select" },
|
|
904
947
|
{ key: "esc", label: "quit" },
|
|
905
948
|
];
|
|
906
|
-
const CONFIRM_HINTS:
|
|
949
|
+
const CONFIRM_HINTS: Hint[] = [
|
|
907
950
|
{ key: "y", label: "submit" },
|
|
908
951
|
{ key: "n", label: "cancel" },
|
|
909
952
|
];
|
|
953
|
+
const PROMPT_HINTS_VALID: Hint[] = [
|
|
954
|
+
{ key: "tab", label: "to navigate forward" },
|
|
955
|
+
{ key: "shift+tab", label: "to navigate backward" },
|
|
956
|
+
{ key: "ctrl+d", label: "to run" },
|
|
957
|
+
];
|
|
958
|
+
const PROMPT_HINTS_INVALID: Hint[] = [
|
|
959
|
+
{ key: "tab", label: "to navigate forward" },
|
|
960
|
+
{ key: "shift+tab", label: "to navigate backward" },
|
|
961
|
+
{ key: "ctrl+d", label: "to run", dim: true },
|
|
962
|
+
];
|
|
910
963
|
|
|
911
964
|
// Per-agent brand color used as the Header pill background.
|
|
912
965
|
const AGENT_PILL_COLOR: Record<AgentType, keyof PickerTheme> = {
|
|
@@ -915,19 +968,18 @@ const AGENT_PILL_COLOR: Record<AgentType, keyof PickerTheme> = {
|
|
|
915
968
|
opencode: "mauve",
|
|
916
969
|
};
|
|
917
970
|
|
|
918
|
-
function Header({
|
|
919
|
-
theme,
|
|
971
|
+
const Header = memo(function Header({
|
|
920
972
|
phase,
|
|
921
973
|
confirmOpen,
|
|
922
974
|
selectedAgent,
|
|
923
975
|
scopedCount,
|
|
924
976
|
}: {
|
|
925
|
-
theme: PickerTheme;
|
|
926
977
|
phase: Phase;
|
|
927
978
|
confirmOpen: boolean;
|
|
928
979
|
selectedAgent: AgentType;
|
|
929
980
|
scopedCount: number;
|
|
930
981
|
}) {
|
|
982
|
+
const theme = usePickerTheme();
|
|
931
983
|
const phaseLabel = confirmOpen
|
|
932
984
|
? "confirm"
|
|
933
985
|
: phase === "pick"
|
|
@@ -965,21 +1017,20 @@ function Header({
|
|
|
965
1017
|
</text>
|
|
966
1018
|
</box>
|
|
967
1019
|
);
|
|
968
|
-
}
|
|
1020
|
+
});
|
|
969
1021
|
|
|
970
|
-
function Statusline({
|
|
971
|
-
theme,
|
|
1022
|
+
const Statusline = memo(function Statusline({
|
|
972
1023
|
phase,
|
|
973
1024
|
confirmOpen,
|
|
974
1025
|
hints,
|
|
975
1026
|
focusedWf,
|
|
976
1027
|
}: {
|
|
977
|
-
theme: PickerTheme;
|
|
978
1028
|
phase: Phase;
|
|
979
1029
|
confirmOpen: boolean;
|
|
980
1030
|
hints: { key: string; label: string; dim?: boolean }[];
|
|
981
1031
|
focusedWf: WorkflowWithMetadata | undefined;
|
|
982
1032
|
}) {
|
|
1033
|
+
const theme = usePickerTheme();
|
|
983
1034
|
const modeLabel = confirmOpen
|
|
984
1035
|
? "CONFIRM"
|
|
985
1036
|
: phase === "pick"
|
|
@@ -1033,166 +1084,131 @@ function Statusline({
|
|
|
1033
1084
|
</box>
|
|
1034
1085
|
</box>
|
|
1035
1086
|
);
|
|
1036
|
-
}
|
|
1087
|
+
});
|
|
1037
1088
|
|
|
1038
|
-
// ───
|
|
1089
|
+
// ─── Keyboard hook ─────────────────────────────
|
|
1039
1090
|
|
|
1040
|
-
interface
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1091
|
+
interface PickerKeyboardState {
|
|
1092
|
+
entries: ListEntry[];
|
|
1093
|
+
clampedEntryIdx: number;
|
|
1094
|
+
savedEntryIdx: number;
|
|
1095
|
+
focusedWf: WorkflowWithMetadata | undefined;
|
|
1096
|
+
fieldValues: Record<string, string>;
|
|
1097
|
+
isFormValid: boolean;
|
|
1098
|
+
invalidFieldIndices: number[];
|
|
1099
|
+
currentFields: readonly WorkflowInput[];
|
|
1100
|
+
currentField: WorkflowInput | undefined;
|
|
1101
|
+
phase: Phase;
|
|
1102
|
+
confirmOpen: boolean;
|
|
1044
1103
|
onSubmit: (result: WorkflowPickerResult) => void;
|
|
1045
1104
|
onCancel: () => void;
|
|
1105
|
+
setPhase: (p: Phase) => void;
|
|
1106
|
+
setEntryIdx: React.Dispatch<React.SetStateAction<number>>;
|
|
1107
|
+
setSavedEntryIdx: (i: number) => void;
|
|
1108
|
+
setFieldValues: React.Dispatch<React.SetStateAction<Record<string, string>>>;
|
|
1109
|
+
setFocusedFieldIdx: React.Dispatch<React.SetStateAction<number>>;
|
|
1110
|
+
setConfirmOpen: (open: boolean) => void;
|
|
1046
1111
|
}
|
|
1047
1112
|
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
const
|
|
1056
|
-
const
|
|
1057
|
-
const
|
|
1058
|
-
const
|
|
1059
|
-
const
|
|
1060
|
-
const
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
const
|
|
1065
|
-
|
|
1066
|
-
const
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
const invalidFieldIndices = useMemo(() => {
|
|
1085
|
-
const out: number[] = [];
|
|
1086
|
-
for (let i = 0; i < currentFields.length; i++) {
|
|
1087
|
-
const f = currentFields[i]!;
|
|
1088
|
-
const v = fieldValues[f.name] ?? "";
|
|
1089
|
-
if (!isFieldValid(f, v)) out.push(i);
|
|
1113
|
+
/**
|
|
1114
|
+
* Encapsulates all keyboard handling for the picker's three phases
|
|
1115
|
+
* (pick, prompt, confirm). Reads state through refs to avoid stale
|
|
1116
|
+
* closures — useKeyboard captures the first callback identity.
|
|
1117
|
+
*/
|
|
1118
|
+
function usePickerKeyboard(state: PickerKeyboardState): void {
|
|
1119
|
+
const onSubmitRef = useLatest(state.onSubmit);
|
|
1120
|
+
const onCancelRef = useLatest(state.onCancel);
|
|
1121
|
+
const entriesRef = useLatest(state.entries);
|
|
1122
|
+
const entryIdxRef = useLatest(state.clampedEntryIdx);
|
|
1123
|
+
const savedEntryIdxRef = useLatest(state.savedEntryIdx);
|
|
1124
|
+
const focusedWfRef = useLatest(state.focusedWf);
|
|
1125
|
+
const fieldValuesRef = useLatest(state.fieldValues);
|
|
1126
|
+
const isFormValidRef = useLatest(state.isFormValid);
|
|
1127
|
+
const invalidFieldIndicesRef = useLatest(state.invalidFieldIndices);
|
|
1128
|
+
const currentFieldsRef = useLatest(state.currentFields);
|
|
1129
|
+
const currentFieldRef = useLatest(state.currentField);
|
|
1130
|
+
const phaseRef = useLatest(state.phase);
|
|
1131
|
+
const confirmOpenRef = useLatest(state.confirmOpen);
|
|
1132
|
+
|
|
1133
|
+
const {
|
|
1134
|
+
setPhase,
|
|
1135
|
+
setEntryIdx,
|
|
1136
|
+
setSavedEntryIdx,
|
|
1137
|
+
setFieldValues,
|
|
1138
|
+
setFocusedFieldIdx,
|
|
1139
|
+
setConfirmOpen,
|
|
1140
|
+
} = state;
|
|
1141
|
+
|
|
1142
|
+
const onConfirmKey = useCallback((key: KeyEvent) => {
|
|
1143
|
+
key.stopPropagation();
|
|
1144
|
+
if (key.name === "y" || key.name === "return") {
|
|
1145
|
+
const wf = focusedWfRef.current;
|
|
1146
|
+
if (!wf) return;
|
|
1147
|
+
onSubmitRef.current({ workflow: wf, inputs: { ...fieldValuesRef.current } });
|
|
1148
|
+
return;
|
|
1090
1149
|
}
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
// Wire the textarea change callback so field values stay in sync.
|
|
1096
|
-
// The ref is written here (not in a child) so the parent state
|
|
1097
|
-
// always reflects the latest textarea content.
|
|
1098
|
-
const focusedField = currentField;
|
|
1099
|
-
textChangeRef.current = focusedField
|
|
1100
|
-
? (text: string) => {
|
|
1101
|
-
setFieldValues((prev) => ({ ...prev, [focusedField.name]: text }));
|
|
1102
|
-
}
|
|
1103
|
-
: null;
|
|
1104
|
-
|
|
1105
|
-
// Stable callback for field input — the setter is referentially stable.
|
|
1106
|
-
const onFieldInput = useCallback(
|
|
1107
|
-
(name: string, v: string) => setFieldValues((prev) => ({ ...prev, [name]: v })),
|
|
1108
|
-
[],
|
|
1109
|
-
);
|
|
1110
|
-
|
|
1111
|
-
// Stable refs for values read inside the keyboard handler,
|
|
1112
|
-
// preventing stale closures when useKeyboard holds the first callback.
|
|
1113
|
-
const entriesRef = useLatest(entries);
|
|
1114
|
-
const focusedWfRef = useLatest(focusedWf);
|
|
1115
|
-
const fieldValuesRef = useLatest(fieldValues);
|
|
1116
|
-
const isFormValidRef = useLatest(isFormValid);
|
|
1117
|
-
const invalidFieldIndicesRef = useLatest(invalidFieldIndices);
|
|
1118
|
-
const currentFieldsRef = useLatest(currentFields);
|
|
1119
|
-
const currentFieldRef = useLatest(currentField);
|
|
1120
|
-
const phaseRef = useLatest(phase);
|
|
1121
|
-
const confirmOpenRef = useLatest(confirmOpen);
|
|
1150
|
+
if (key.name === "n" || key.name === "escape") {
|
|
1151
|
+
setConfirmOpen(false);
|
|
1152
|
+
}
|
|
1153
|
+
}, []);
|
|
1122
1154
|
|
|
1123
|
-
|
|
1124
|
-
if (key.
|
|
1125
|
-
|
|
1155
|
+
const onPickKey = useCallback((key: KeyEvent) => {
|
|
1156
|
+
if (key.name === "escape") {
|
|
1157
|
+
key.stopPropagation();
|
|
1158
|
+
onCancelRef.current();
|
|
1126
1159
|
return;
|
|
1127
1160
|
}
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
const wf = focusedWfRef.current;
|
|
1132
|
-
if (!wf) return;
|
|
1133
|
-
onSubmit({ workflow: wf, inputs: { ...fieldValuesRef.current } });
|
|
1134
|
-
return;
|
|
1135
|
-
}
|
|
1136
|
-
if (key.name === "n" || key.name === "escape") {
|
|
1137
|
-
setConfirmOpen(false);
|
|
1138
|
-
return;
|
|
1139
|
-
}
|
|
1161
|
+
if (key.name === "up" || (key.ctrl && key.name === "k")) {
|
|
1162
|
+
key.stopPropagation();
|
|
1163
|
+
setEntryIdx(Math.max(0, entryIdxRef.current - 1));
|
|
1140
1164
|
return;
|
|
1141
1165
|
}
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
if (wf) {
|
|
1161
|
-
const inputs: WorkflowInput[] =
|
|
1162
|
-
wf.inputs.length > 0
|
|
1163
|
-
? [...wf.inputs]
|
|
1164
|
-
: [DEFAULT_PROMPT_INPUT];
|
|
1165
|
-
const initial: Record<string, string> = {};
|
|
1166
|
-
for (const f of inputs) {
|
|
1167
|
-
initial[f.name] =
|
|
1168
|
-
f.default ??
|
|
1169
|
-
(f.type === "enum" ? (f.values?.[0] ?? "") : "");
|
|
1170
|
-
}
|
|
1171
|
-
setFieldValues(initial);
|
|
1172
|
-
setFocusedFieldIdx(0);
|
|
1173
|
-
setPhase("prompt");
|
|
1166
|
+
if (key.name === "down" || (key.ctrl && key.name === "j")) {
|
|
1167
|
+
key.stopPropagation();
|
|
1168
|
+
setEntryIdx(Math.min(entriesRef.current.length - 1, entryIdxRef.current + 1));
|
|
1169
|
+
return;
|
|
1170
|
+
}
|
|
1171
|
+
if (key.name === "return") {
|
|
1172
|
+
key.stopPropagation();
|
|
1173
|
+
const wf = focusedWfRef.current;
|
|
1174
|
+
if (wf) {
|
|
1175
|
+
const inputs: readonly WorkflowInput[] =
|
|
1176
|
+
wf.inputs.length > 0
|
|
1177
|
+
? wf.inputs
|
|
1178
|
+
: DEFAULT_FIELDS;
|
|
1179
|
+
const initial: Record<string, string> = {};
|
|
1180
|
+
for (const f of inputs) {
|
|
1181
|
+
initial[f.name] =
|
|
1182
|
+
f.default ??
|
|
1183
|
+
(f.type === "enum" ? (f.values?.[0] ?? "") : "");
|
|
1174
1184
|
}
|
|
1175
|
-
|
|
1185
|
+
setFieldValues(initial);
|
|
1186
|
+
setFocusedFieldIdx(0);
|
|
1187
|
+
setSavedEntryIdx(entryIdxRef.current);
|
|
1188
|
+
setPhase("prompt");
|
|
1176
1189
|
}
|
|
1177
|
-
// All other keys (typing, backspace, arrows) are handled by the
|
|
1178
|
-
// native <input> component in the FilterBar.
|
|
1179
|
-
return;
|
|
1180
1190
|
}
|
|
1191
|
+
}, []);
|
|
1181
1192
|
|
|
1182
|
-
|
|
1193
|
+
const onPromptKey = useCallback((key: KeyEvent) => {
|
|
1183
1194
|
if (key.name === "escape") {
|
|
1195
|
+
key.stopPropagation();
|
|
1196
|
+
setEntryIdx(savedEntryIdxRef.current);
|
|
1184
1197
|
setPhase("pick");
|
|
1185
1198
|
return;
|
|
1186
1199
|
}
|
|
1187
|
-
if (key.ctrl && key.name === "
|
|
1200
|
+
if (key.ctrl && key.name === "d") {
|
|
1201
|
+
key.stopPropagation();
|
|
1188
1202
|
if (!isFormValidRef.current) {
|
|
1189
|
-
|
|
1203
|
+
const firstInvalid = invalidFieldIndicesRef.current[0];
|
|
1204
|
+
if (firstInvalid !== undefined) setFocusedFieldIdx(firstInvalid);
|
|
1190
1205
|
return;
|
|
1191
1206
|
}
|
|
1192
1207
|
setConfirmOpen(true);
|
|
1193
1208
|
return;
|
|
1194
1209
|
}
|
|
1195
1210
|
if (key.name === "tab") {
|
|
1211
|
+
key.stopPropagation();
|
|
1196
1212
|
setFocusedFieldIdx((i: number) => {
|
|
1197
1213
|
const len = currentFieldsRef.current.length;
|
|
1198
1214
|
if (len <= 1) return 0;
|
|
@@ -1203,11 +1219,11 @@ export function WorkflowPicker({
|
|
|
1203
1219
|
const field = currentFieldRef.current;
|
|
1204
1220
|
if (!field) return;
|
|
1205
1221
|
|
|
1206
|
-
// Enum fields use left/right to cycle values.
|
|
1207
1222
|
if (field.type === "enum") {
|
|
1208
1223
|
const values = field.values ?? [];
|
|
1209
1224
|
if (values.length === 0) return;
|
|
1210
1225
|
if (key.name === "left" || key.name === "right") {
|
|
1226
|
+
key.stopPropagation();
|
|
1211
1227
|
setFieldValues((prev: Record<string, string>) => {
|
|
1212
1228
|
const cur = prev[field.name] ?? values[0] ?? "";
|
|
1213
1229
|
const idx = Math.max(0, values.indexOf(cur));
|
|
@@ -1219,100 +1235,192 @@ export function WorkflowPicker({
|
|
|
1219
1235
|
return;
|
|
1220
1236
|
}
|
|
1221
1237
|
|
|
1222
|
-
// For string fields, return advances focus to the next field
|
|
1223
|
-
// (the native <input> fires onSubmit, but we handle it here so
|
|
1224
|
-
// the focus-cycling logic stays in one place).
|
|
1225
1238
|
if (field.type === "string" && key.name === "return") {
|
|
1239
|
+
key.stopPropagation();
|
|
1226
1240
|
setFocusedFieldIdx((i: number) =>
|
|
1227
1241
|
Math.min(currentFieldsRef.current.length - 1, i + 1),
|
|
1228
1242
|
);
|
|
1243
|
+
}
|
|
1244
|
+
}, []);
|
|
1245
|
+
|
|
1246
|
+
useKeyboard((key) => {
|
|
1247
|
+
if (key.ctrl && key.name === "c") {
|
|
1248
|
+
key.stopPropagation();
|
|
1249
|
+
onCancelRef.current();
|
|
1229
1250
|
return;
|
|
1230
1251
|
}
|
|
1231
|
-
|
|
1232
|
-
|
|
1252
|
+
if (confirmOpenRef.current) return onConfirmKey(key);
|
|
1253
|
+
if (phaseRef.current === "pick") return onPickKey(key);
|
|
1254
|
+
onPromptKey(key);
|
|
1233
1255
|
});
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
// ─── App ────────────────────────────────────────
|
|
1259
|
+
|
|
1260
|
+
interface PickerAppProps {
|
|
1261
|
+
theme: PickerTheme;
|
|
1262
|
+
agent: AgentType;
|
|
1263
|
+
workflows: WorkflowWithMetadata[];
|
|
1264
|
+
onSubmit: (result: WorkflowPickerResult) => void;
|
|
1265
|
+
onCancel: () => void;
|
|
1266
|
+
}
|
|
1234
1267
|
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1268
|
+
export function WorkflowPicker({
|
|
1269
|
+
theme,
|
|
1270
|
+
agent,
|
|
1271
|
+
workflows,
|
|
1272
|
+
onSubmit,
|
|
1273
|
+
onCancel,
|
|
1274
|
+
}: PickerAppProps) {
|
|
1275
|
+
const [phase, setPhase] = useState<Phase>("pick");
|
|
1276
|
+
const [query, setQuery] = useState("");
|
|
1277
|
+
const [entryIdx, setEntryIdx] = useState(0);
|
|
1278
|
+
const [savedEntryIdx, setSavedEntryIdx] = useState(0);
|
|
1279
|
+
const [fieldValues, setFieldValues] = useState<Record<string, string>>({});
|
|
1280
|
+
const [focusedFieldIdx, setFocusedFieldIdx] = useState(0);
|
|
1281
|
+
const [confirmOpen, setConfirmOpen] = useState(false);
|
|
1282
|
+
|
|
1283
|
+
const entries = useMemo(() => buildEntries(query, workflows), [query, workflows]);
|
|
1284
|
+
const rows = useMemo(() => buildRows(entries, query), [entries, query]);
|
|
1285
|
+
|
|
1286
|
+
// Clamp index when the list shrinks (e.g. typing filters entries out).
|
|
1287
|
+
// Derived during render — keyboard handlers read the clamped value via
|
|
1288
|
+
// refs (useLatest) so no sync-back effect is needed.
|
|
1289
|
+
const clampedEntryIdx = Math.min(entryIdx, Math.max(0, entries.length - 1));
|
|
1290
|
+
|
|
1291
|
+
const focusedWf = entries[clampedEntryIdx]?.workflow;
|
|
1292
|
+
|
|
1293
|
+
const currentFields = useMemo<readonly WorkflowInput[]>(
|
|
1294
|
+
() => focusedWf && focusedWf.inputs.length > 0
|
|
1295
|
+
? focusedWf.inputs
|
|
1296
|
+
: DEFAULT_FIELDS,
|
|
1297
|
+
[focusedWf],
|
|
1298
|
+
);
|
|
1299
|
+
const currentField = currentFields[focusedFieldIdx];
|
|
1300
|
+
|
|
1301
|
+
const invalidFieldIndices = useMemo(() => {
|
|
1302
|
+
const out: number[] = [];
|
|
1303
|
+
for (let i = 0; i < currentFields.length; i++) {
|
|
1304
|
+
const f = currentFields[i];
|
|
1305
|
+
if (!f) continue;
|
|
1306
|
+
const v = fieldValues[f.name] ?? "";
|
|
1307
|
+
if (!isFieldValid(f, v)) out.push(i);
|
|
1308
|
+
}
|
|
1309
|
+
return out;
|
|
1310
|
+
}, [currentFields, fieldValues]);
|
|
1311
|
+
const isFormValid = invalidFieldIndices.length === 0;
|
|
1312
|
+
|
|
1313
|
+
// Textarea change callback ref — useLatest keeps .current in sync
|
|
1314
|
+
// each render so the textarea effect doesn't need to re-attach.
|
|
1315
|
+
const textChangeRef = useLatest(
|
|
1316
|
+
currentField
|
|
1317
|
+
? (text: string) => {
|
|
1318
|
+
setFieldValues((prev) => ({ ...prev, [currentField.name]: text }));
|
|
1319
|
+
}
|
|
1320
|
+
: null,
|
|
1321
|
+
);
|
|
1322
|
+
|
|
1323
|
+
// Stable callback for field input — the setter is referentially stable.
|
|
1324
|
+
const onFieldInput = useCallback(
|
|
1325
|
+
(name: string, v: string) => setFieldValues((prev) => ({ ...prev, [name]: v })),
|
|
1326
|
+
[],
|
|
1327
|
+
);
|
|
1328
|
+
|
|
1329
|
+
usePickerKeyboard({
|
|
1330
|
+
entries,
|
|
1331
|
+
clampedEntryIdx,
|
|
1332
|
+
savedEntryIdx,
|
|
1333
|
+
focusedWf,
|
|
1334
|
+
fieldValues,
|
|
1335
|
+
isFormValid,
|
|
1336
|
+
invalidFieldIndices,
|
|
1337
|
+
currentFields,
|
|
1338
|
+
currentField,
|
|
1339
|
+
phase,
|
|
1340
|
+
confirmOpen,
|
|
1341
|
+
onSubmit,
|
|
1342
|
+
onCancel,
|
|
1343
|
+
setPhase,
|
|
1344
|
+
setEntryIdx,
|
|
1345
|
+
setSavedEntryIdx,
|
|
1346
|
+
setFieldValues,
|
|
1347
|
+
setFocusedFieldIdx,
|
|
1348
|
+
setConfirmOpen,
|
|
1349
|
+
});
|
|
1242
1350
|
|
|
1243
1351
|
const hints = confirmOpen
|
|
1244
|
-
?
|
|
1352
|
+
? CONFIRM_HINTS
|
|
1245
1353
|
: phase === "pick"
|
|
1246
|
-
?
|
|
1247
|
-
:
|
|
1354
|
+
? PICK_HINTS
|
|
1355
|
+
: isFormValid
|
|
1356
|
+
? PROMPT_HINTS_VALID
|
|
1357
|
+
: PROMPT_HINTS_INVALID;
|
|
1248
1358
|
|
|
1249
1359
|
return (
|
|
1250
|
-
<
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1360
|
+
<PickerThemeContext value={theme}>
|
|
1361
|
+
<box
|
|
1362
|
+
position="relative"
|
|
1363
|
+
width="100%"
|
|
1364
|
+
height="100%"
|
|
1365
|
+
flexDirection="column"
|
|
1366
|
+
backgroundColor={theme.background}
|
|
1367
|
+
>
|
|
1368
|
+
<Header
|
|
1369
|
+
phase={phase}
|
|
1370
|
+
confirmOpen={confirmOpen}
|
|
1371
|
+
selectedAgent={agent}
|
|
1372
|
+
scopedCount={workflows.length}
|
|
1373
|
+
/>
|
|
1264
1374
|
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1375
|
+
{phase === "pick" ? (
|
|
1376
|
+
<box
|
|
1377
|
+
flexGrow={1}
|
|
1378
|
+
flexDirection="row"
|
|
1379
|
+
paddingLeft={2}
|
|
1380
|
+
paddingRight={2}
|
|
1381
|
+
paddingTop={1}
|
|
1382
|
+
>
|
|
1383
|
+
<box width={36} flexDirection="column">
|
|
1384
|
+
<FilterBar query={query} focused={phase === "pick"} onInput={setQuery} />
|
|
1385
|
+
<box height={1} />
|
|
1386
|
+
<WorkflowList
|
|
1387
|
+
rows={rows}
|
|
1388
|
+
focusedEntryIdx={clampedEntryIdx}
|
|
1389
|
+
/>
|
|
1390
|
+
</box>
|
|
1391
|
+
<box width={1} backgroundColor={theme.border} />
|
|
1392
|
+
<box flexGrow={1} flexDirection="column">
|
|
1393
|
+
{focusedWf ? (
|
|
1394
|
+
<Preview wf={focusedWf} />
|
|
1395
|
+
) : (
|
|
1396
|
+
<EmptyPreview query={query} />
|
|
1397
|
+
)}
|
|
1398
|
+
</box>
|
|
1289
1399
|
</box>
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
/>
|
|
1302
|
-
) : null}
|
|
1400
|
+
) : phase === "prompt" && focusedWf ? (
|
|
1401
|
+
<InputPhase
|
|
1402
|
+
workflow={focusedWf}
|
|
1403
|
+
agent={agent}
|
|
1404
|
+
fields={currentFields}
|
|
1405
|
+
values={fieldValues}
|
|
1406
|
+
focusedFieldIdx={confirmOpen ? -1 : focusedFieldIdx}
|
|
1407
|
+
onFieldInput={onFieldInput}
|
|
1408
|
+
onTextChangeRef={textChangeRef}
|
|
1409
|
+
/>
|
|
1410
|
+
) : null}
|
|
1303
1411
|
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
/>
|
|
1412
|
+
<Statusline
|
|
1413
|
+
phase={phase}
|
|
1414
|
+
confirmOpen={confirmOpen}
|
|
1415
|
+
hints={hints}
|
|
1416
|
+
focusedWf={focusedWf}
|
|
1417
|
+
/>
|
|
1311
1418
|
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1419
|
+
{confirmOpen && focusedWf ? (
|
|
1420
|
+
<ConfirmModal workflow={focusedWf} agent={agent} />
|
|
1421
|
+
) : null}
|
|
1422
|
+
</box>
|
|
1423
|
+
</PickerThemeContext>
|
|
1316
1424
|
);
|
|
1317
1425
|
}
|
|
1318
1426
|
|
|
@@ -1346,7 +1454,8 @@ export class WorkflowPickerPanel {
|
|
|
1346
1454
|
this.resolveSelection = resolve;
|
|
1347
1455
|
});
|
|
1348
1456
|
|
|
1349
|
-
const
|
|
1457
|
+
const isDark = renderer.themeMode !== "light";
|
|
1458
|
+
const theme = buildPickerTheme(resolveTheme(renderer.themeMode), isDark);
|
|
1350
1459
|
this.root = createRoot(renderer);
|
|
1351
1460
|
this.root.render(
|
|
1352
1461
|
<ErrorBoundary
|
|
@@ -1428,7 +1537,9 @@ export class WorkflowPickerPanel {
|
|
|
1428
1537
|
}
|
|
1429
1538
|
try {
|
|
1430
1539
|
this.renderer.destroy();
|
|
1431
|
-
} catch {
|
|
1540
|
+
} catch (err) {
|
|
1541
|
+
console.error("[WorkflowPickerPanel] destroy failed:", err);
|
|
1542
|
+
}
|
|
1432
1543
|
}
|
|
1433
1544
|
|
|
1434
1545
|
private handleSubmit(result: WorkflowPickerResult): void {
|