@thierrynakoa/fire-flow 12.2.2 → 13.0.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/CREDITS.md +25 -0
- package/DOMINION-FLOW-OVERVIEW.md +182 -38
- package/README.md +399 -690
- package/TROUBLESHOOTING.md +264 -367
- package/agents/fire-debugger.md +54 -0
- package/agents/fire-executor.md +1610 -1033
- package/agents/fire-fact-checker.md +1 -1
- package/agents/fire-planner.md +85 -17
- package/agents/fire-project-researcher.md +1 -1
- package/agents/fire-researcher.md +4 -22
- package/agents/{fire-phoenix-analyst.md → fire-resurrection-analyst.md} +394 -394
- package/agents/fire-reviewer.md +552 -499
- package/agents/fire-verifier.md +114 -19
- package/bin/cli.js +18 -101
- package/commands/fire-0-orient.md +2 -2
- package/commands/fire-1a-new.md +50 -15
- package/commands/fire-1c-setup.md +33 -5
- package/commands/fire-1d-discuss.md +87 -1
- package/commands/fire-2-plan.md +556 -527
- package/commands/fire-3-execute.md +2046 -1356
- package/commands/fire-4-verify.md +975 -906
- package/commands/fire-5-handoff.md +46 -5
- package/commands/fire-6-resume.md +2 -31
- package/commands/fire-add-new-skill.md +138 -19
- package/commands/fire-autonomous.md +14 -2
- package/commands/fire-complete-milestone.md +1 -1
- package/commands/fire-cost.md +179 -183
- package/commands/fire-debug.md +1 -6
- package/commands/fire-loop-resume.md +2 -2
- package/commands/fire-loop-stop.md +1 -1
- package/commands/fire-loop.md +2 -15
- package/commands/fire-map-codebase.md +1 -1
- package/commands/fire-migrate-database.md +548 -0
- package/commands/fire-new-milestone.md +1 -1
- package/commands/fire-reflect.md +1 -2
- package/commands/fire-research.md +142 -21
- package/commands/{fire-phoenix.md → fire-resurrect.md} +859 -603
- package/commands/fire-scaffold.md +297 -0
- package/commands/fire-search.md +1 -2
- package/commands/fire-security-scan.md +483 -484
- package/commands/fire-setup.md +359 -0
- package/commands/fire-skill.md +770 -0
- package/commands/fire-skills-diff.md +506 -506
- package/commands/fire-skills-history.md +388 -388
- package/commands/fire-skills-rollback.md +7 -7
- package/commands/fire-skills-sync.md +470 -470
- package/commands/fire-test.md +5 -5
- package/commands/fire-todos.md +1 -1
- package/commands/fire-update.md +5 -5
- package/commands/fire-validate-skills.md +282 -0
- package/commands/fire-verify-uat.md +9 -177
- package/commands/fire-vuln-scan.md +492 -493
- package/hooks/run-hook.sh +8 -8
- package/hooks/run-session-end.sh +7 -7
- package/hooks/session-end.sh +90 -90
- package/hooks/session-start.sh +1 -1
- package/package.json +4 -25
- package/plugin.json +7 -7
- package/references/autonomy-levels.md +235 -0
- package/references/behavioral-directives.md +95 -3
- package/references/blocker-tracking.md +1 -1
- package/references/circuit-breaker.md +93 -2
- package/references/context-engineering.md +227 -9
- package/references/honesty-protocols.md +70 -1
- package/references/issue-to-pr-pipeline.md +149 -150
- package/references/metrics-and-trends.md +1 -2
- package/references/research-improvements.md +4 -108
- package/references/sdlc-mapping.md +73 -0
- package/references/state-machine.md +151 -0
- package/skills-library/AVAILABLE_TOOLS_REFERENCE.md +333 -0
- package/skills-library/SKILLS-INDEX.md +57 -558
- package/skills-library/SKILLS_LIBRARY_INDEX.md +532 -0
- package/skills-library/_general/api-patterns/api-field-name-mismatch.md +107 -0
- package/skills-library/_general/api-patterns/streaming-command-timeout.md +122 -0
- package/skills-library/_general/api-patterns/streaming-proxy-cors-bypass.md +102 -0
- package/skills-library/_general/automation/settings-gui-generator.md +172 -0
- package/skills-library/_general/database-solutions/data-type-mapping-reference.md +181 -0
- package/skills-library/_general/database-solutions/mysql-limit-offset-string-coercion.md +102 -0
- package/skills-library/_general/database-solutions/mysql-to-pg-migration.md +195 -0
- package/skills-library/_general/database-solutions/orm-schema-portability.md +193 -0
- package/skills-library/_general/database-solutions/persistent-analysis-storage.md +207 -0
- package/skills-library/_general/database-solutions/pg-to-mysql-schema-migration-methodology.md +190 -0
- package/skills-library/_general/database-solutions/sql-dialect-compatibility-matrix.md +306 -0
- package/skills-library/_general/database-solutions/sqlite-to-pg-migration.md +219 -0
- package/skills-library/_general/frontend/canvas-bubble-animation-grouping.md +270 -0
- package/skills-library/_general/frontend/color-token-migration.md +112 -0
- package/skills-library/_general/frontend/framer-motion-layoutid-grouping.md +150 -0
- package/skills-library/_general/frontend/pyqt6-settings-dialog.md +191 -0
- package/skills-library/_general/frontend/react-flow-animated-layout-switching.md +101 -0
- package/skills-library/_general/frontend/react-hooks-order-debugging.md +141 -0
- package/skills-library/_general/frontend/redux-localstorage-auth-desync.md +126 -0
- package/skills-library/_general/frontend/safari-csp-theme-color-debugging.md +124 -0
- package/skills-library/_general/frontend/safari-sw-cache-poisoning.md +138 -0
- package/skills-library/_general/frontend/svg-sparkline-no-charting-library.md +131 -0
- package/skills-library/_general/growth-marketing/oss-daily-growth-intelligence.md +224 -0
- package/skills-library/_general/integrations/claude-code-local-mcp-integration.md +250 -0
- package/skills-library/_general/integrations/mcp-composite-tool-orchestration.md +200 -0
- package/skills-library/_general/methodology/AGENT_SDK_STANDALONE_TOOLING.md +181 -0
- package/skills-library/_general/methodology/AGENT_TEAMS_GUIDE.md +169 -0
- package/skills-library/_general/methodology/ALAS_STATEFUL_EXECUTION.md +207 -0
- package/skills-library/_general/methodology/AUTO_REVIEWER_SUBAGENT.md +211 -0
- package/skills-library/_general/methodology/CONSISTENCY_CHECK_AMBIGUITY_GATE.md +96 -0
- package/skills-library/_general/methodology/DEAD_ENDS_SHELF.md +4 -4
- package/skills-library/_general/methodology/DISTILL_NOT_DUMP.md +108 -0
- package/skills-library/_general/methodology/EXECUTION_PROGRESS_MONITOR.md +157 -0
- package/skills-library/_general/methodology/HIERARCHICAL_REVIEW_MARS.md +122 -0
- package/skills-library/_general/methodology/MCP_INTER_AGENT_BRIDGE.md +207 -0
- package/skills-library/_general/methodology/MERMAID_WIZARD_DIAGRAMS.md +77 -0
- package/skills-library/_general/methodology/MISSING_DIMENSION_DETECTOR.md +89 -0
- package/skills-library/_general/methodology/MULTI_AGENT_COORDINATION.md +397 -0
- package/skills-library/_general/methodology/OBSERVATION_MASKING.md +100 -0
- package/skills-library/_general/methodology/PHOENIX_REBUILD_METHODOLOGY.md +82 -11
- package/skills-library/_general/methodology/REVIEW_BACKTRACK_PANEL.md +140 -0
- package/skills-library/_general/methodology/REVIEW_FIX_LOOP.md +117 -0
- package/skills-library/_general/methodology/VOTING_VERDICT_ARBITRATION.md +155 -0
- package/skills-library/_general/methodology/ZERO_FRICTION_CLI_SETUP.md +2 -2
- package/skills-library/_general/methodology/dead-code-activation.md +123 -0
- package/skills-library/_general/methodology/debug-swarm-researcher-escape-hatch.md +240 -240
- package/skills-library/_general/methodology/shell-autonomous-loop-fixplan.md +1 -1
- package/skills-library/_general/patterns-standards/GOF_DESIGN_PATTERNS_FOR_AI_AGENTS.md +5 -5
- package/skills-library/_general/patterns-standards/cascading-failure-diagnosis.md +119 -0
- package/skills-library/_general/patterns-standards/domain-specific-layout-algorithms.md +209 -0
- package/skills-library/_general/patterns-standards/python-desktop-app-architecture.md +399 -0
- package/skills-library/_general/patterns-standards/realtime-monitoring-dashboard.md +457 -0
- package/skills-library/_general/patterns-standards/togglable-processing-pipeline.md +169 -0
- package/skills-library/_general/performance/liveclock-extraction.md +112 -0
- package/skills-library/_general/performance/ref-based-canvas-animation.md +117 -0
- package/skills-library/_general/performance/use-visible-interval.md +131 -0
- package/skills-library/_general/testing/playwright-firefox-withcredentials-auth-issue.md +104 -0
- package/skills-library/_quarantine/README.md +30 -0
- package/skills-library/api-patterns/BROADCAST_SCHEDULER_SHARED_EXECUTE_FUNCTION.md +150 -0
- package/skills-library/api-patterns/ERROR_RESPONSE_STANDARDS.md +145 -0
- package/skills-library/api-patterns/EXPRESS_ROUTE_ORDERING_MIDDLEWARE_INTERCEPTION.md +326 -0
- package/skills-library/api-patterns/PAGINATION_PATTERNS.md +137 -0
- package/skills-library/api-patterns/PODCAST_PROGRESS_TRACKING_THREE_ROOT_CAUSES.md +277 -0
- package/skills-library/api-patterns/RATE_LIMITING_TOGGLE.md +155 -0
- package/skills-library/api-patterns/graphql-content-queries.md +708 -0
- package/skills-library/appointment-scheduler-design.md +423 -0
- package/skills-library/automation/AUTO_POPULATE_COMPLETE_GUIDE.md +631 -0
- package/skills-library/automation/CC_WORKFLOW_STUDIO.md +83 -0
- package/skills-library/automation/CLAUDE_CODE_SWARM_MODE.md +95 -0
- package/skills-library/automation/DAEMON_TRIGGER_FILE_IPC.md +195 -0
- package/skills-library/automation/scheduled-content-publishing.md +608 -0
- package/skills-library/awesome-workflows/Blogging-Platform-Instructions/view_commands.md +25 -0
- package/skills-library/awesome-workflows/CREDENTIAL-SECURITY-WORKFLOW.md +109 -0
- package/skills-library/awesome-workflows/DEBUGGING-WORKFLOW.md +124 -0
- package/skills-library/awesome-workflows/Design-Review-Workflow/README.md +31 -0
- package/skills-library/awesome-workflows/Design-Review-Workflow/design-principles-example.md +129 -0
- package/skills-library/awesome-workflows/Design-Review-Workflow/design-review-agent.md +107 -0
- package/skills-library/awesome-workflows/Design-Review-Workflow/design-review-claude-md-snippet.md +24 -0
- package/skills-library/awesome-workflows/Design-Review-Workflow/design-review-slash-command.md +38 -0
- package/skills-library/awesome-workflows/PARALLEL-RESEARCH-WORKFLOW.md +89 -0
- package/skills-library/awesome-workflows/PHASE-EXECUTION-WORKFLOW.md +97 -0
- package/skills-library/awesome-workflows/SESSION-HANDOFF-WORKFLOW.md +116 -0
- package/skills-library/cms-patterns/content-branch-preview.md +515 -0
- package/skills-library/cms-patterns/inline-visual-editing.md +666 -0
- package/skills-library/cms-patterns/mdx-component-content.md +649 -0
- package/skills-library/cms-patterns/media-manager-abstraction.md +827 -0
- package/skills-library/cms-patterns/schema-driven-form-generator.md +838 -0
- package/skills-library/complexity-metrics/complexity-divider.md +707 -0
- package/skills-library/complexity-metrics/work-with-complexity.md +193 -0
- package/skills-library/creative-multimedia/animation-stack-guide.md +577 -0
- package/skills-library/creative-multimedia/audio-enhancement-pipeline.md +625 -0
- package/skills-library/creative-multimedia/content-repurposing-pipeline.md +1146 -0
- package/skills-library/creative-multimedia/data-visualization-generator.md +862 -0
- package/skills-library/creative-multimedia/doc-to-podcast-pipeline.md +2184 -0
- package/skills-library/creative-multimedia/ffmpeg-command-generator.md +405 -0
- package/skills-library/creative-multimedia/image-optimization-pipeline.md +605 -0
- package/skills-library/creative-multimedia/multi-format-content-generator.md +1759 -0
- package/skills-library/creative-multimedia/og-image-generator.md +635 -0
- package/skills-library/creative-multimedia/podcast-audio-composition.md +1355 -0
- package/skills-library/creative-multimedia/podcast-quality-evaluation.md +1452 -0
- package/skills-library/creative-multimedia/podcast-script-generation.md +1841 -0
- package/skills-library/creative-multimedia/svg-generation.md +750 -0
- package/skills-library/creative-multimedia/text-to-speech-provider-selector.md +1414 -0
- package/skills-library/creative-multimedia/transcription-pipeline-selector.md +677 -0
- package/skills-library/creative-multimedia/video-streaming-setup.md +559 -0
- package/skills-library/database-solutions/AI_RESPONSE_DATABASE_CACHING.md +520 -0
- package/skills-library/database-solutions/CONDITIONAL_SQL_MIGRATION_PATTERN.md +119 -0
- package/skills-library/database-solutions/DATABASE_COLUMN_NAME_MISMATCH.md +393 -0
- package/skills-library/database-solutions/DATABASE_SCHEMA.md +394 -0
- package/skills-library/database-solutions/DATABASE_SCHEMA_VERIFICATION_GUIDE.md +348 -0
- package/skills-library/database-solutions/DATABASE_STRATEGY.md +71 -0
- package/skills-library/database-solutions/ES_MODULE_SEED_SCRIPT_PATTERN.md +52 -0
- package/skills-library/database-solutions/MIGRATION_GUIDE.md +3 -0
- package/skills-library/database-solutions/PLPGSQL_VARIABLE_CONFLICT_FIX.md +208 -0
- package/skills-library/database-solutions/POSTGRESQL_JSONB_DOUBLE_STRINGIFY_FIX.md +245 -0
- package/skills-library/database-solutions/POSTGRESQL_LICENSE_TABLE_DESIGN.md +393 -0
- package/skills-library/database-solutions/POSTGRESQL_UUID_DOCUMENT_RAG_DUAL_SCOPE.md +732 -0
- package/skills-library/database-solutions/POSTGRES_SQL_TEMPLATE_BINDING_ERROR.md +240 -0
- package/skills-library/database-solutions/PRISMA_DB_PUSH_DATA_LOSS_PREVENTION.md +141 -0
- package/skills-library/database-solutions/PRODUCTION_QUERY_OPTIMIZATION_RESTART_FIX.md +389 -0
- package/skills-library/database-solutions/RLS_SECURITY_GUIDE.md +107 -0
- package/skills-library/database-solutions/SCHEMA_ENHANCEMENTS_GUIDE.md +373 -0
- package/skills-library/database-solutions/SCHEMA_MIGRATION_GUIDE.md +368 -0
- package/skills-library/database-solutions/SCHEMA_VERIFICATION_QUICK_REFERENCE.md +104 -0
- package/skills-library/database-solutions/ai-erd-generator.md +1213 -0
- package/skills-library/database-solutions/content-publishing-states.md +631 -0
- package/skills-library/database-solutions/database-schema-designer.md +522 -0
- package/skills-library/database-solutions/er-diagram-components.md +569 -0
- package/skills-library/database-solutions/er-to-ddl-mapping.md +1405 -0
- package/skills-library/database-solutions/erd-creator-textbook-research.md +433 -0
- package/skills-library/database-solutions/erd-react-flow-architecture.md +1965 -0
- package/skills-library/database-solutions/mariadb-aggregate-function-replacement.md +145 -0
- package/skills-library/database-solutions/normalization-validator.md +778 -0
- package/skills-library/database-solutions/postgres-full-text-search-content.md +494 -0
- package/skills-library/database-solutions/postgresql-to-mysql-runtime-translation.md +286 -0
- package/skills-library/database-solutions/regex-alternation-ordering-sql-types.md +92 -0
- package/skills-library/database-solutions/reserved-word-context-aware-quoting.md +142 -0
- package/skills-library/database-solutions/sql-ddl-generator.md +756 -0
- package/skills-library/database-solutions/supabase-connection-pooler-fix.md +102 -0
- package/skills-library/deployment-security/CPANEL_NODE_DEPLOYMENT.md +166 -0
- package/skills-library/deployment-security/DEPLOYMENT.md +275 -0
- package/skills-library/deployment-security/DEPLOYMENT_CHECKLIST.md +363 -0
- package/skills-library/deployment-security/DEPLOYMENT_PLAN.md +669 -0
- package/skills-library/deployment-security/KNEX_DATABASE_ABSTRACTION.md +444 -0
- package/skills-library/deployment-security/LICENSE_KEY_SYSTEM.md +206 -0
- package/skills-library/deployment-security/NODE18_DEPENDENCY_COMPATIBILITY.md +284 -0
- package/skills-library/deployment-security/PHP_INSTALLER_WIZARD_GUIDE.md +315 -0
- package/skills-library/deployment-security/PM2_ENVIRONMENT_VARIABLE_CACHING.md +256 -0
- package/skills-library/deployment-security/PM2_MEMORY_EXHAUSTION_FIX.md +370 -0
- package/skills-library/deployment-security/PRODUCTION_DEPLOYMENT_GUIDE.md +592 -0
- package/skills-library/deployment-security/PRODUCTION_HARDENING_DOCUMENTATION.md +307 -0
- package/skills-library/deployment-security/PRODUCTION_RECOVERY_CHERRY_PICK_PATTERN.md +202 -0
- package/skills-library/deployment-security/PYINSTALLER_CUDA_WHISPER_BUNDLING.md +236 -0
- package/skills-library/deployment-security/SECURITY.md +41 -0
- package/skills-library/deployment-security/SMTP_SSL_HOSTNAME_MISMATCH_SHARED_HOSTING.md +220 -0
- package/skills-library/deployment-security/SPA_SEO_OPTIMIZATION_CPANEL.md +200 -0
- package/skills-library/deployment-security/SUPABASE_EDGE_FUNCTIONS.md +338 -0
- package/skills-library/deployment-security/VERCEL_GITHUB_DEPLOYMENT_GUIDE.md +858 -0
- package/skills-library/deployment-security/VPS_DEPLOYMENT_READINESS.md +356 -0
- package/skills-library/deployment-security/deployment-changes-not-applying.md +241 -0
- package/skills-library/deployment-security/env-file-management-production-local.md +203 -0
- package/skills-library/deployment-security/express-secure-file-downloads.md +413 -0
- package/skills-library/deployment-security/react-production-deployment-desktop-guide.md +2011 -0
- package/skills-library/deployment-security/self-hosted-supabase-coolify-guide.md +1684 -0
- package/skills-library/deployment-security/unique-features-ai-strategy-plaid-security.md +1613 -0
- package/skills-library/deployment-security/vps-deployment.md +135 -0
- package/skills-library/document-processing/WORD_EXPORT_MARKDOWN_FORMATTING.md +482 -0
- package/skills-library/document-processing/document-ai-landingai-integration.md +677 -0
- package/skills-library/document-processing/express-secure-file-downloads-mern.md +413 -0
- package/skills-library/document-processing/express-secure-file-downloads.md +413 -0
- package/skills-library/document-processing/md-to-word-converter.md +318 -0
- package/skills-library/document-processing/pdf-forms-integration/README.md +101 -0
- package/skills-library/document-processing/pdf-forms-integration/SKILL.md +662 -0
- package/skills-library/ecommerce/ADMIN_PRODUCTS_GUIDE.md +428 -0
- package/skills-library/ecommerce/ECOMMERCE_API_REFERENCE.md +776 -0
- package/skills-library/ecommerce/ECOMMERCE_COMPLETION_SUMMARY.md +673 -0
- package/skills-library/ecommerce/ECOMMERCE_IMPLEMENTATION_GUIDE.md +729 -0
- package/skills-library/ecommerce/ECOMMERCE_QUICK_REFERENCE.md +521 -0
- package/skills-library/ecommerce/ECOMMERCE_TESTING_CHECKLIST.md +565 -0
- package/skills-library/ecommerce/ECOMMERCE_WORKFLOW_GUIDE.md +1059 -0
- package/skills-library/ecommerce/PRODUCT_CREATION_EXPANDED.md +522 -0
- package/skills-library/ecommerce/agentic-commerce-protocol.md +203 -0
- package/skills-library/ecommerce/cart-abandonment-recovery.md +236 -0
- package/skills-library/ecommerce/cart-architecture-patterns.md +300 -0
- package/skills-library/ecommerce/cart-item-count-indicator.md +264 -0
- package/skills-library/ecommerce/checkout-ux-conversion.md +227 -0
- package/skills-library/ecommerce/composable-commerce-selection.md +166 -0
- package/skills-library/ecommerce/ecommerce-analytics-patterns.md +167 -0
- package/skills-library/ecommerce/fraud-detection-patterns.md +179 -0
- package/skills-library/ecommerce/inventory-stock-management.md +270 -0
- package/skills-library/ecommerce/order-saga-state-machine.md +336 -0
- package/skills-library/ecommerce/payment-provider-abstraction.md +245 -0
- package/skills-library/ecommerce/pci-compliance-checklist.md +192 -0
- package/skills-library/ecommerce/refund-chargeback-handling.md +177 -0
- package/skills-library/ecommerce/shipping-carrier-integration.md +218 -0
- package/skills-library/ecommerce/webhook-idempotency-patterns.md +253 -0
- package/skills-library/excalidraw-diagrams/.github/workflows/ci.yml +558 -0
- package/skills-library/excalidraw-diagrams/.github/workflows/prompt-gallery.yml +448 -0
- package/skills-library/excalidraw-diagrams/.github/workflows/release.yml +42 -0
- package/skills-library/excalidraw-diagrams/.github/workflows/test-reusable-ci.yml +25 -0
- package/skills-library/excalidraw-diagrams/CLAUDE.md +57 -0
- package/skills-library/excalidraw-diagrams/LICENSE +21 -0
- package/skills-library/excalidraw-diagrams/README.md +178 -0
- package/skills-library/excalidraw-diagrams/SKILL.md +715 -0
- package/skills-library/form-solutions/BUTTON_TYPE_FORM_SUBMISSION.md +336 -0
- package/skills-library/form-solutions/FILLABLE_PDF_IMPLEMENTATION.md +226 -0
- package/skills-library/form-solutions/SURVEYJS_QUESTIONNAIRE_SYSTEM.md +367 -0
- package/skills-library/form-solutions/tiptap-minimal-setup.md +690 -0
- package/skills-library/frontend/scholarly-classification-bubble-map.md +149 -0
- package/skills-library/infrastructure/ci-cd-pipeline-builder.md +517 -0
- package/skills-library/infrastructure/observability-designer.md +264 -0
- package/skills-library/infrastructure/performance-profiler.md +621 -0
- package/skills-library/installer-wizard-patterns.md +249 -0
- package/skills-library/integrations/CLAUDE_CODE_TOKEN_ANALYTICS.md +160 -0
- package/skills-library/integrations/CONFIGURABLE_AI_PROVIDER_SELECTION.md +728 -0
- package/skills-library/integrations/SOCKET_IO_BROADCAST_ALL_VS_ROOM.md +141 -0
- package/skills-library/integrations/VIRTUAL_MEETINGS_IMPLEMENTATION.md +374 -0
- package/skills-library/integrations/WORDPRESS_LEARNDASH_DATA_RECOVERY.md +53 -0
- package/skills-library/integrations/YOUTUBE_API_SETUP.md +141 -0
- package/skills-library/integrations/YOUTUBE_BOOKMARKING_EXPLANATION.md +252 -0
- package/skills-library/integrations/YOUTUBE_BOOKMARKING_SOLUTION.md +268 -0
- package/skills-library/integrations/YOUTUBE_OAUTH_SETUP_GUIDE.md +200 -0
- package/skills-library/integrations/YOUTUBE_VIDEO_FIX_COMPLETE.md +192 -0
- package/skills-library/integrations/ai-ml/GEMINI_AI_RAG_PIPELINE_COMPLETE_GUIDE.md +195 -0
- package/skills-library/integrations/ai-ml/GEMINI_IMAGE_GENERATION_SETUP.md +64 -0
- package/skills-library/integrations/cloudflare/cloudflare-turnstile-debugging.md +202 -0
- package/skills-library/integrations/cloudflare/cloudflare-turnstile-implementation.md +476 -0
- package/skills-library/integrations/cloudflare-turnstile-debugging.md +202 -0
- package/skills-library/integrations/cloudflare-turnstile-implementation.md +476 -0
- package/skills-library/integrations/ghost-creator-monetization-pattern.md +454 -0
- package/skills-library/integrations/headless-cms-architecture.md +484 -0
- package/skills-library/integrations/headless-cms-stack-selection.md +183 -0
- package/skills-library/integrations/payload-cms-patterns.md +674 -0
- package/skills-library/integrations/realtimestt-openwakeword-cuda-windows.md +229 -0
- package/skills-library/integrations/rss-podcast-integration.md +300 -0
- package/skills-library/integrations/wordpress/WORDPRESS_LEARNDASH_DATA_RECOVERY.md +53 -0
- package/skills-library/integrations/youtube/YOUTUBE_API_SETUP.md +141 -0
- package/skills-library/integrations/youtube/YOUTUBE_BOOKMARKING_EXPLANATION.md +252 -0
- package/skills-library/integrations/youtube/YOUTUBE_BOOKMARKING_SOLUTION.md +268 -0
- package/skills-library/integrations/youtube/YOUTUBE_OAUTH_SETUP_GUIDE.md +200 -0
- package/skills-library/integrations/youtube/YOUTUBE_VIDEO_FIX_COMPLETE.md +192 -0
- package/skills-library/marketing/campaign-analytics.md +97 -0
- package/skills-library/marketing/content-creator.md +105 -0
- package/skills-library/marketing/marketing-strategy-pmm.md +94 -0
- package/skills-library/marketing/social-media-analyzer.md +81 -0
- package/skills-library/methodology/ADVANCED_ORCHESTRATION_PATTERNS.md +401 -0
- package/skills-library/methodology/AGENT_SELF_IMPROVEMENT_LOOP.md +179 -0
- package/skills-library/methodology/BREATH_BASED_PARALLEL_EXECUTION.md +1 -1
- package/skills-library/methodology/CLEANSING_CYCLE.md +358 -0
- package/skills-library/methodology/CONFIDENCE_ANNOTATION_PATTERN.md +143 -0
- package/skills-library/methodology/CRITICAL_PATTERNS_DOCUMENTATION_COMPLETE.md +204 -0
- package/skills-library/methodology/DELIVERABLES_SUMMARY.md +341 -0
- package/skills-library/methodology/DIFFICULTY_AWARE_AGENT_ROUTING.md +252 -0
- package/skills-library/methodology/EVOLUTIONARY_SKILL_SYNTHESIS.md +219 -0
- package/skills-library/methodology/GLOMERULUS_DECISION_GATE.md +223 -0
- package/skills-library/methodology/HIBERNATION_SYSTEM.md +231 -0
- package/skills-library/methodology/INSTRUMENTATION_OVER_RESTRICTION.md +192 -0
- package/skills-library/methodology/MASTER_COMPLETION_SUMMARY.md +444 -0
- package/skills-library/methodology/MASTER_SESSION_COMPLETION.md +743 -0
- package/skills-library/methodology/MERN_QUICK_REFERENCE.md +358 -0
- package/skills-library/methodology/ORGAN_AGENT_MAPPING.md +177 -0
- package/skills-library/methodology/PARALLEL_WAVE_BASED_REFACTORING.md +440 -0
- package/skills-library/methodology/QUICK_REFERENCE.md +358 -0
- package/skills-library/methodology/SDFT_ONPOLICY_SELF_DISTILLATION.md +186 -0
- package/skills-library/methodology/SELF_QUESTIONING_TASK_GENERATION.md +270 -0
- package/skills-library/methodology/SESSION_COMPLETION_SUMMARY.md +304 -0
- package/skills-library/methodology/SESSION_SUMMARY.md +432 -0
- package/skills-library/methodology/WARRIOR_WORKFLOW_DEBUGGING_PROTOCOL.md +252 -0
- package/skills-library/methodology/tech-debt-tracker.md +570 -0
- package/skills-library/parallel-debug/SKILL.md +60 -0
- package/skills-library/patterns-standards/API_PATTERN_FIX_SUMMARY.md +236 -0
- package/skills-library/patterns-standards/BATCH_OPERATIONS_WITH_PROGRESS_MODAL.md +362 -0
- package/skills-library/patterns-standards/CRITICAL_CODING_PATTERNS.md +639 -0
- package/skills-library/patterns-standards/DARK_MODE_MODAL_VISIBILITY.md +258 -0
- package/skills-library/patterns-standards/ERROR_RESILIENCE_IMPLEMENTATION.md +375 -0
- package/skills-library/patterns-standards/ES_MODULE_IMPORT_HOISTING_DOTENV.md +298 -0
- package/skills-library/patterns-standards/NESTED_BACKDROP_FILTER_CSS_ARTIFACT_FIX.md +76 -0
- package/skills-library/patterns-standards/ORDERED_DETECTOR_PIPELINE_GRACEFUL_FALLBACK.md +333 -0
- package/skills-library/patterns-standards/PHASE_IMPORT_ERROR_DEBUGGING.md +271 -0
- package/skills-library/patterns-standards/PYNPUT_GLOBAL_HOTKEY_VK_MATCHING.md +252 -0
- package/skills-library/patterns-standards/REACT_USEEFFECT_CASCADE_RESET_FIX.md +132 -0
- package/skills-library/patterns-standards/SUBMENU_HOVER_DROPDOWN_PATTERN.md +225 -0
- package/skills-library/patterns-standards/TAILWIND_TEXT_VISIBILITY_OVERRIDE.md +322 -0
- package/skills-library/patterns-standards/THEME_AWARE_CSS_VARIABLES_PATTERN.md +209 -0
- package/skills-library/patterns-standards/THEME_USER_OBJECT_PROPERTY_NAMING.md +194 -0
- package/skills-library/patterns-standards/TOOLTIP_BLOCKING_CLICKS_FIX.md +267 -0
- package/skills-library/patterns-standards/claude-code-plugin-structure.md +235 -0
- package/skills-library/patterns-standards/react-i18next-setup.md +429 -0
- package/skills-library/patterns-standards/thesys-c1-generative-ui-integration.md +967 -0
- package/skills-library/plugin-development/CLAUDE_CODE_COMMAND_REGISTRATION_SILENT_FAILURE.md +315 -0
- package/skills-library/plugin-development/plugin-command-namespace-vs-global.md +390 -0
- package/skills-library/plugin-development/plugin-doc-auto-generation.md +172 -0
- package/skills-library/security/GITHUB_REPO_SECURITY_AUDIT.md +115 -0
- package/skills-library/security/admin-deletion-safety.md +396 -0
- package/skills-library/security/application-vuln-patterns.md +477 -0
- package/skills-library/security/env-secrets-manager.md +686 -0
- package/skills-library/security/secure-ai-application-templates.md +347 -0
- package/skills-library/security/sql-injection-prevention-postgresjs.md +151 -0
- package/skills-library/supabase-connection-pooler-fix.md +102 -0
- package/skills-library/system-context/POWERSHELL_BASH_INTEROP.md +82 -0
- package/skills-library/system-context/SERVICE_LIFECYCLE_MANAGEMENT.md +119 -0
- package/skills-library/system-context/SKILL.md +40 -0
- package/skills-library/system-context/WINDOWS_DEV_ENVIRONMENT.md +73 -0
- package/skills-library/testing/E2E_PLAYWRIGHT_PATTERNS.md +99 -0
- package/skills-library/testing/INTEGRATION_TEST_STRATEGY.md +82 -0
- package/skills-library/testing/RED_GREEN_BUGFIX_GATE.md +203 -0
- package/skills-library/testing/TEST_DATA_MANAGEMENT.md +69 -0
- package/skills-library/testing/VITEST_UNIT_TEST_PATTERNS.md +75 -0
- package/skills-library/testing/playwright-api-security-tests.md +202 -0
- package/skills-library/toolbox/SKILL.md +84 -0
- package/skills-library/toolbox/code-graph-and-web-scraping-mcps.md +237 -0
- package/skills-library/ui-ux-pro-max/ACCESSIBILITY_ESSENTIALS.md +115 -0
- package/skills-library/ui-ux-pro-max/DESIGN_SYSTEM_SCAFFOLDING.md +133 -0
- package/skills-library/ui-ux-pro-max/RESPONSIVE_LAYOUT_PATTERNS.md +119 -0
- package/skills-library/ui-ux-pro-max/SKILL.md +386 -0
- package/skills-library/ui-ux-pro-max/data/charts.csv +26 -0
- package/skills-library/ui-ux-pro-max/data/colors.csv +97 -0
- package/skills-library/ui-ux-pro-max/data/icons.csv +101 -0
- package/skills-library/ui-ux-pro-max/data/landing.csv +31 -0
- package/skills-library/ui-ux-pro-max/data/products.csv +97 -0
- package/skills-library/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/skills-library/ui-ux-pro-max/data/stacks/astro.csv +54 -0
- package/skills-library/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/skills-library/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/skills-library/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
- package/skills-library/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/skills-library/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/skills-library/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/skills-library/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/skills-library/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/skills-library/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/skills-library/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/skills-library/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/skills-library/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/skills-library/ui-ux-pro-max/data/styles.csv +68 -0
- package/skills-library/ui-ux-pro-max/data/typography.csv +58 -0
- package/skills-library/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
- package/skills-library/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/skills-library/ui-ux-pro-max/data/web-interface.csv +31 -0
- package/skills-library/wordpress-style-theme-components.md +1526 -0
- package/templates/ASSUMPTIONS.md +1 -1
- package/templates/DECISION_LOG.md +0 -1
- package/templates/phase-prompt.md +1 -1
- package/templates/phoenix-comparison.md +6 -6
- package/templates/skill-api-integration.md +106 -0
- package/templates/skill-architecture-pattern.md +92 -0
- package/templates/skill-debug-pattern.md +98 -0
- package/templates/skill-devops-recipe.md +107 -0
- package/templates/skill-general.md +65 -0
- package/templates/skill-ui-component.md +113 -0
- package/version.json +7 -3
- package/workflows/handoff-session.md +2 -2
- package/workflows/new-project.md +2 -2
- package/workflows/plan-phase.md +1 -1
- package/.claude-plugin/plugin.json +0 -64
- package/skills-library/_general/methodology/LIVE_BREADCRUMB_PROTOCOL.md +0 -242
- package/skills-library/_general/methodology/llm-judge-memory-crud.md +0 -241
- package/skills-library/methodology/REFLEXION_MEMORY_PATTERN.md +0 -183
- package/skills-library/methodology/RESEARCH_BACKED_WORKFLOW_UPGRADE.md +0 -263
- package/skills-library/methodology/SABBATH_REST_PATTERN.md +0 -267
- package/skills-library/methodology/STONE_AND_SCAFFOLD.md +0 -220
- package/skills-library/specialists/api-architecture/api-designer.md +0 -49
- package/skills-library/specialists/api-architecture/graphql-architect.md +0 -49
- package/skills-library/specialists/api-architecture/mcp-developer.md +0 -51
- package/skills-library/specialists/api-architecture/microservices-architect.md +0 -50
- package/skills-library/specialists/api-architecture/websocket-engineer.md +0 -48
- package/skills-library/specialists/backend/django-expert.md +0 -52
- package/skills-library/specialists/backend/fastapi-expert.md +0 -52
- package/skills-library/specialists/backend/laravel-specialist.md +0 -52
- package/skills-library/specialists/backend/nestjs-expert.md +0 -51
- package/skills-library/specialists/backend/rails-expert.md +0 -53
- package/skills-library/specialists/backend/spring-boot-engineer.md +0 -56
- package/skills-library/specialists/data-ml/fine-tuning-expert.md +0 -48
- package/skills-library/specialists/data-ml/ml-pipeline.md +0 -47
- package/skills-library/specialists/data-ml/pandas-pro.md +0 -47
- package/skills-library/specialists/data-ml/rag-architect.md +0 -51
- package/skills-library/specialists/data-ml/spark-engineer.md +0 -47
- package/skills-library/specialists/frontend/angular-architect.md +0 -52
- package/skills-library/specialists/frontend/flutter-expert.md +0 -51
- package/skills-library/specialists/frontend/nextjs-developer.md +0 -54
- package/skills-library/specialists/frontend/react-native-expert.md +0 -50
- package/skills-library/specialists/frontend/vue-expert.md +0 -51
- package/skills-library/specialists/infrastructure/chaos-engineer.md +0 -74
- package/skills-library/specialists/infrastructure/cloud-architect.md +0 -70
- package/skills-library/specialists/infrastructure/database-optimizer.md +0 -64
- package/skills-library/specialists/infrastructure/devops-engineer.md +0 -70
- package/skills-library/specialists/infrastructure/kubernetes-specialist.md +0 -52
- package/skills-library/specialists/infrastructure/monitoring-expert.md +0 -70
- package/skills-library/specialists/infrastructure/sre-engineer.md +0 -70
- package/skills-library/specialists/infrastructure/terraform-engineer.md +0 -51
- package/skills-library/specialists/languages/cpp-pro.md +0 -74
- package/skills-library/specialists/languages/csharp-developer.md +0 -69
- package/skills-library/specialists/languages/dotnet-core-expert.md +0 -54
- package/skills-library/specialists/languages/golang-pro.md +0 -51
- package/skills-library/specialists/languages/java-architect.md +0 -49
- package/skills-library/specialists/languages/javascript-pro.md +0 -68
- package/skills-library/specialists/languages/kotlin-specialist.md +0 -68
- package/skills-library/specialists/languages/php-pro.md +0 -49
- package/skills-library/specialists/languages/python-pro.md +0 -52
- package/skills-library/specialists/languages/react-expert.md +0 -51
- package/skills-library/specialists/languages/rust-engineer.md +0 -50
- package/skills-library/specialists/languages/sql-pro.md +0 -56
- package/skills-library/specialists/languages/swift-expert.md +0 -69
- package/skills-library/specialists/languages/typescript-pro.md +0 -51
- package/skills-library/specialists/platform/atlassian-mcp.md +0 -52
- package/skills-library/specialists/platform/embedded-systems.md +0 -53
- package/skills-library/specialists/platform/game-developer.md +0 -53
- package/skills-library/specialists/platform/salesforce-developer.md +0 -53
- package/skills-library/specialists/platform/shopify-expert.md +0 -49
- package/skills-library/specialists/platform/wordpress-pro.md +0 -49
- package/skills-library/specialists/quality/browser-use-expert.md +0 -210
- package/skills-library/specialists/quality/code-documenter.md +0 -51
- package/skills-library/specialists/quality/code-reviewer.md +0 -67
- package/skills-library/specialists/quality/debugging-wizard.md +0 -51
- package/skills-library/specialists/quality/fullstack-guardian.md +0 -51
- package/skills-library/specialists/quality/legacy-modernizer.md +0 -50
- package/skills-library/specialists/quality/playwright-expert.md +0 -65
- package/skills-library/specialists/quality/spec-miner.md +0 -56
- package/skills-library/specialists/quality/test-master.md +0 -65
- package/skills-library/specialists/security/secure-code-guardian.md +0 -55
- package/skills-library/specialists/security/security-reviewer.md +0 -53
- package/skills-library/specialists/workflow/architecture-designer.md +0 -53
- package/skills-library/specialists/workflow/cli-developer.md +0 -70
- package/skills-library/specialists/workflow/feature-forge.md +0 -65
- package/skills-library/specialists/workflow/prompt-engineer.md +0 -54
- package/skills-library/specialists/workflow/the-fool.md +0 -62
- /package/skills-library/{performance → _general/performance}/cache-augmented-generation.md +0 -0
- /package/skills-library/{debugging → parallel-debug}/FAILURE_TAXONOMY_CLASSIFICATION.md +0 -0
- /package/skills-library/{debugging → parallel-debug}/THREE_AGENT_HYPOTHESIS_DEBUGGING.md +0 -0
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: domain-specific-layout-algorithms
|
|
3
|
+
category: patterns-standards
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
contributed: 2026-02-26
|
|
6
|
+
contributor: scribe-bible
|
|
7
|
+
last_updated: 2026-02-26
|
|
8
|
+
tags: [layout, algorithm, graph, visualization, react-flow, spatial, domain-driven]
|
|
9
|
+
difficulty: hard
|
|
10
|
+
usage_count: 0
|
|
11
|
+
success_rate: 100
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Domain-Specific Layout Algorithms
|
|
15
|
+
|
|
16
|
+
## Problem
|
|
17
|
+
|
|
18
|
+
Generic graph layout algorithms (dagre, force-directed, radial) arrange nodes mathematically but ignore domain semantics. A chiastic literary structure should look like an arc/mirror, not a random force graph. Parallel ideas should be in lanes, not scattered. Your domain has spatial metaphors that users intuitively understand, but no charting library provides layouts that encode domain meaning.
|
|
19
|
+
|
|
20
|
+
## Solution Pattern
|
|
21
|
+
|
|
22
|
+
Create a **layout algorithm registry** — a set of pure functions that each take `(nodes, edges, options)` and return repositioned nodes. Each function encodes one domain-specific spatial metaphor. Wire them into your existing layout engine's switch statement so they integrate seamlessly with generic algorithms.
|
|
23
|
+
|
|
24
|
+
The pattern: layout functions are **pure position calculators**. They don't render anything — they just assign `x, y` coordinates to nodes based on domain rules. The rendering layer (React Flow, D3, Canvas) handles display.
|
|
25
|
+
|
|
26
|
+
## Code Example
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
// ─── Type Contract ──────────────────────────────────────
|
|
30
|
+
interface GraphNode {
|
|
31
|
+
id: string;
|
|
32
|
+
position: { x: number; y: number };
|
|
33
|
+
data: Record<string, any>;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
interface GraphEdge {
|
|
37
|
+
id: string;
|
|
38
|
+
source: string;
|
|
39
|
+
target: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
interface LayoutOptions {
|
|
43
|
+
spacing?: number;
|
|
44
|
+
centerX?: number;
|
|
45
|
+
centerY?: number;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
type LayoutFunction = (
|
|
49
|
+
nodes: GraphNode[],
|
|
50
|
+
edges: GraphEdge[],
|
|
51
|
+
options: LayoutOptions
|
|
52
|
+
) => GraphNode[];
|
|
53
|
+
|
|
54
|
+
// ─── Domain Layout: Mirror Arc (for chiastic/symmetric structures) ─────
|
|
55
|
+
export function layoutMirrorArc(
|
|
56
|
+
nodes: GraphNode[],
|
|
57
|
+
edges: GraphEdge[],
|
|
58
|
+
options: LayoutOptions
|
|
59
|
+
): GraphNode[] {
|
|
60
|
+
const { spacing = 200, centerX = 400, centerY = 300 } = options;
|
|
61
|
+
const n = nodes.length;
|
|
62
|
+
const mid = Math.floor(n / 2);
|
|
63
|
+
|
|
64
|
+
return nodes.map((node, i) => {
|
|
65
|
+
// Distance from center (0 at edges, max at midpoint)
|
|
66
|
+
const distFromMid = Math.abs(i - mid);
|
|
67
|
+
const indent = (mid - distFromMid) * (spacing * 0.4);
|
|
68
|
+
|
|
69
|
+
return {
|
|
70
|
+
...node,
|
|
71
|
+
position: {
|
|
72
|
+
x: centerX + indent, // Indent toward center = arc shape
|
|
73
|
+
y: (i * spacing * 0.7), // Vertical stack
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// ─── Domain Layout: Parallel Lanes (for parallel/synonymous structures) ─
|
|
80
|
+
export function layoutParallelLanes(
|
|
81
|
+
nodes: GraphNode[],
|
|
82
|
+
edges: GraphEdge[],
|
|
83
|
+
options: LayoutOptions
|
|
84
|
+
): GraphNode[] {
|
|
85
|
+
const { spacing = 200 } = options;
|
|
86
|
+
|
|
87
|
+
// Split into pairs (A-line, B-line)
|
|
88
|
+
return nodes.map((node, i) => {
|
|
89
|
+
const pairIndex = Math.floor(i / 2);
|
|
90
|
+
const isLineB = i % 2 === 1;
|
|
91
|
+
|
|
92
|
+
return {
|
|
93
|
+
...node,
|
|
94
|
+
position: {
|
|
95
|
+
x: isLineB ? spacing * 2 : 0, // Two columns
|
|
96
|
+
y: pairIndex * spacing * 0.8, // Aligned rows
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// ─── Domain Layout: Ascending Staircase (for climactic/progressive) ─────
|
|
103
|
+
export function layoutAscendingStaircase(
|
|
104
|
+
nodes: GraphNode[],
|
|
105
|
+
edges: GraphEdge[],
|
|
106
|
+
options: LayoutOptions
|
|
107
|
+
): GraphNode[] {
|
|
108
|
+
const { spacing = 200 } = options;
|
|
109
|
+
|
|
110
|
+
return nodes.map((node, i) => ({
|
|
111
|
+
...node,
|
|
112
|
+
position: {
|
|
113
|
+
x: i * spacing * 0.6, // Step right
|
|
114
|
+
y: (nodes.length - 1 - i) * spacing * 0.5, // Step up (y=0 is top)
|
|
115
|
+
},
|
|
116
|
+
}));
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// ─── Domain Layout: Narrative Arc (parabolic curve) ─────────────────────
|
|
120
|
+
export function layoutNarrativeArc(
|
|
121
|
+
nodes: GraphNode[],
|
|
122
|
+
edges: GraphEdge[],
|
|
123
|
+
options: LayoutOptions
|
|
124
|
+
): GraphNode[] {
|
|
125
|
+
const { spacing = 200, centerY = 300 } = options;
|
|
126
|
+
const n = nodes.length;
|
|
127
|
+
const peakHeight = spacing * 2;
|
|
128
|
+
|
|
129
|
+
return nodes.map((node, i) => {
|
|
130
|
+
const t = n > 1 ? i / (n - 1) : 0.5; // 0 to 1
|
|
131
|
+
const y = -4 * peakHeight * t * (t - 1); // Parabola: peak at midpoint
|
|
132
|
+
|
|
133
|
+
return {
|
|
134
|
+
...node,
|
|
135
|
+
position: {
|
|
136
|
+
x: i * spacing,
|
|
137
|
+
y: centerY - y, // Invert for screen coords
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// ─── Registry: Wire into layout engine ──────────────────
|
|
144
|
+
const LAYOUT_REGISTRY: Record<string, LayoutFunction> = {
|
|
145
|
+
// Generic algorithms
|
|
146
|
+
'dagre': layoutDagre,
|
|
147
|
+
'force': layoutForce,
|
|
148
|
+
'radial': layoutRadial,
|
|
149
|
+
// Domain-specific algorithms
|
|
150
|
+
'mirror-arc': layoutMirrorArc,
|
|
151
|
+
'parallel-lanes': layoutParallelLanes,
|
|
152
|
+
'ascending-staircase': layoutAscendingStaircase,
|
|
153
|
+
'narrative-arc': layoutNarrativeArc,
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
export function applyLayout(
|
|
157
|
+
nodes: GraphNode[],
|
|
158
|
+
edges: GraphEdge[],
|
|
159
|
+
options: LayoutOptions & { algorithm: string }
|
|
160
|
+
): GraphNode[] {
|
|
161
|
+
const layoutFn = LAYOUT_REGISTRY[options.algorithm];
|
|
162
|
+
if (!layoutFn) throw new Error(`Unknown layout: ${options.algorithm}`);
|
|
163
|
+
return layoutFn(nodes, edges, options);
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Implementation Steps
|
|
168
|
+
|
|
169
|
+
1. Define a `LayoutFunction` type signature: `(nodes, edges, options) => nodes`
|
|
170
|
+
2. Identify your domain's spatial metaphors (what shapes do experts draw on whiteboards?)
|
|
171
|
+
3. Implement each metaphor as a pure function that assigns `x, y` positions
|
|
172
|
+
4. Create a registry mapping algorithm names to functions
|
|
173
|
+
5. Wire the registry into your existing `applyLayout()` switch/dispatch
|
|
174
|
+
6. Extend your `LayoutAlgorithm` TypeScript union type with the new names
|
|
175
|
+
7. Add UI buttons/dropdown to let users select domain-specific layouts
|
|
176
|
+
|
|
177
|
+
## When to Use
|
|
178
|
+
|
|
179
|
+
- You have domain concepts with natural spatial representations (hierarchy, timeline, symmetry, opposition, progression, cycles)
|
|
180
|
+
- Generic layouts (force, dagre) produce technically correct but semantically meaningless graphs
|
|
181
|
+
- Your users think in domain-specific spatial terms ("chiastic structure", "parallel tracks", "escalation ladder")
|
|
182
|
+
- You already have a graph visualization framework (React Flow, D3, Cytoscape)
|
|
183
|
+
|
|
184
|
+
## When NOT to Use
|
|
185
|
+
|
|
186
|
+
- Generic data with no domain-specific spatial meaning
|
|
187
|
+
- When dagre/force layouts are sufficient for the use case
|
|
188
|
+
- Small graphs (<5 nodes) where layout differences are imperceptible
|
|
189
|
+
- When users expect standard graph layouts (network diagrams, org charts)
|
|
190
|
+
|
|
191
|
+
## Common Mistakes
|
|
192
|
+
|
|
193
|
+
- Making layout functions impure (fetching data, mutating state) — keep them as pure position calculators
|
|
194
|
+
- Hardcoding pixel values — use the `spacing` option so layouts scale
|
|
195
|
+
- Forgetting edge cases: 0 nodes, 1 node, odd/even counts
|
|
196
|
+
- Not providing a fallback layout when node count doesn't match expected structure
|
|
197
|
+
- Coupling layout logic to the rendering framework — keep layouts as plain `{x, y}` calculators
|
|
198
|
+
|
|
199
|
+
## Related Skills
|
|
200
|
+
|
|
201
|
+
- [react-flow-animated-layout-switching](../_general/frontend/react-flow-animated-layout-switching.md) — Animate transitions between layouts
|
|
202
|
+
- [fullstack-bible-study-platform](fullstack-bible-study-platform.md) — Platform where these patterns were proven
|
|
203
|
+
|
|
204
|
+
## References
|
|
205
|
+
|
|
206
|
+
- Dagre.js: https://github.com/dagrejs/dagre (generic directed graph layout)
|
|
207
|
+
- Discovered in: scribe-bible theological layouts (Phases 1 & 3)
|
|
208
|
+
- 14 domain-specific layout algorithms: 7 for parallelism viewer, 7 for shared concept map engine
|
|
209
|
+
- Spatial metaphors: chiastic mirror arcs, parallel lanes, antithetical opposing splits, climactic ascending staircases, cascade waterfalls, concentric rings, narrative parabolic arcs
|
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Python Desktop App Architecture
|
|
3
|
+
category: patterns-standards
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
contributed: 2026-02-24
|
|
6
|
+
tags: [python, pyqt6, desktop-app, pystray, audio, stt, tts, overlay, threading, signals]
|
|
7
|
+
difficulty: hard
|
|
8
|
+
usage_count: 0
|
|
9
|
+
success_rate: 100
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Python Desktop App Architecture
|
|
13
|
+
|
|
14
|
+
## Problem
|
|
15
|
+
|
|
16
|
+
Building a Python desktop application that combines real-time audio processing (STT/TTS), a transparent overlay UI, system tray integration, background processing threads, and external monitoring — all without freezing the GUI or corrupting shared state.
|
|
17
|
+
|
|
18
|
+
The core challenge is threading: STT engines run continuous audio loops, TTS engines queue and play audio, hotkey listeners block on input, and the GUI must remain responsive. Python's GIL and Qt's thread-affinity rules make naive approaches crash or deadlock.
|
|
19
|
+
|
|
20
|
+
## Solution Pattern
|
|
21
|
+
|
|
22
|
+
**PyQt6 overlay + pystray tray + Qt signal bridge + status sidecar**
|
|
23
|
+
|
|
24
|
+
Use PyQt6 as the primary GUI framework with its event loop on the main thread. Run all blocking I/O (STT, TTS, hotkeys, tray) on dedicated background threads. Bridge thread-to-GUI communication exclusively through Qt signals (which are thread-safe and auto-queued). Expose application state via a lightweight HTTP sidecar for external monitoring.
|
|
25
|
+
|
|
26
|
+
## Architecture
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
Main Thread (Qt Event Loop)
|
|
30
|
+
|
|
|
31
|
+
+-- Overlay (QWidget, transparent, always-on-top)
|
|
32
|
+
+-- Settings Dialog (QDialog, modal)
|
|
33
|
+
+-- Text Processor (post-processing pipeline)
|
|
34
|
+
+-- Claude Client (API calls, async-compatible)
|
|
35
|
+
|
|
|
36
|
+
+-- [Qt Signals] <-- STT Thread (RealtimeSTT, continuous mic loop)
|
|
37
|
+
+-- [Qt Signals] <-- TTS Thread (edge-tts/piper, audio queue)
|
|
38
|
+
+-- [Qt Signals] <-- Tray Thread (pystray, blocks on menu loop)
|
|
39
|
+
+-- [Qt Signals] <-- Hotkey Thread (keyboard listener)
|
|
40
|
+
+-- [Thread] <-- Status Server (HTTPServer on port 7899)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Component Breakdown
|
|
44
|
+
|
|
45
|
+
| Component | Role | Thread | Communication |
|
|
46
|
+
|-----------|------|--------|---------------|
|
|
47
|
+
| `main.py` | Orchestrator (~700 lines), wires all components | Main | Direct calls |
|
|
48
|
+
| `overlay.py` | Transparent QWidget, shows transcription/status | Main | Qt signals in |
|
|
49
|
+
| `settings_dialog.py` | QDialog for config editing | Main (modal) | Direct config access |
|
|
50
|
+
| `stt_engine.py` | RealtimeSTT with Whisper, continuous listen | Background | Qt signals out |
|
|
51
|
+
| `tts_engine.py` | edge-tts + piper-tts, audio queue via sounddevice | Background | Qt signals out |
|
|
52
|
+
| `tray.py` | pystray system tray with menu | Background | Qt signals out |
|
|
53
|
+
| `config.py` | YAML config with deep_merge defaults | Any (read-only after load) | Direct import |
|
|
54
|
+
| `claude_client.py` | Anthropic SDK, streaming responses | Main (async) | Direct calls |
|
|
55
|
+
| `status_server.py` | HTTPServer sidecar, JSON state endpoint | Background | Reads shared state |
|
|
56
|
+
| `text_processor.py` | Post-processing pipeline (corrections, formatting) | Main | Direct calls |
|
|
57
|
+
| `transcription_history.py` | Timestamped log of all transcriptions | Main | Direct calls |
|
|
58
|
+
|
|
59
|
+
## Code Examples
|
|
60
|
+
|
|
61
|
+
### Qt Signal Bridge Pattern
|
|
62
|
+
|
|
63
|
+
The fundamental pattern: background threads emit Qt signals, the main thread handles them safely.
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
from PyQt6.QtCore import QObject, pyqtSignal, QThread
|
|
67
|
+
|
|
68
|
+
class STTSignals(QObject):
|
|
69
|
+
"""Signals emitted by the STT engine thread."""
|
|
70
|
+
text_detected = pyqtSignal(str) # Partial transcription
|
|
71
|
+
text_finalized = pyqtSignal(str) # Final transcription
|
|
72
|
+
status_changed = pyqtSignal(str) # "listening", "processing", "idle"
|
|
73
|
+
error_occurred = pyqtSignal(str) # Error message
|
|
74
|
+
wake_word_detected = pyqtSignal() # Wake word trigger
|
|
75
|
+
|
|
76
|
+
class STTEngine(QThread):
|
|
77
|
+
def __init__(self, config: dict):
|
|
78
|
+
super().__init__()
|
|
79
|
+
self.signals = STTSignals()
|
|
80
|
+
self.config = config
|
|
81
|
+
self._running = True
|
|
82
|
+
|
|
83
|
+
def run(self):
|
|
84
|
+
"""Runs on background thread. NEVER touch GUI here."""
|
|
85
|
+
from RealtimeSTT import AudioToTextRecorder
|
|
86
|
+
recorder = AudioToTextRecorder(
|
|
87
|
+
model=self.config.get("model", "base.en"),
|
|
88
|
+
language=self.config.get("language", "en"),
|
|
89
|
+
on_recording_start=lambda: self.signals.status_changed.emit("listening"),
|
|
90
|
+
on_recording_stop=lambda: self.signals.status_changed.emit("processing"),
|
|
91
|
+
)
|
|
92
|
+
while self._running:
|
|
93
|
+
text = recorder.text()
|
|
94
|
+
if text and text.strip():
|
|
95
|
+
self.signals.text_finalized.emit(text.strip())
|
|
96
|
+
|
|
97
|
+
def stop(self):
|
|
98
|
+
self._running = False
|
|
99
|
+
self.quit()
|
|
100
|
+
self.wait(3000)
|
|
101
|
+
|
|
102
|
+
# In main.py orchestrator:
|
|
103
|
+
class VoiceBridgeApp:
|
|
104
|
+
def __init__(self):
|
|
105
|
+
self.stt = STTEngine(config["stt"])
|
|
106
|
+
self.overlay = Overlay()
|
|
107
|
+
|
|
108
|
+
# Connect signal to GUI update (thread-safe via Qt signal queue)
|
|
109
|
+
self.stt.signals.text_finalized.connect(self.overlay.show_transcription)
|
|
110
|
+
self.stt.signals.status_changed.connect(self.overlay.update_status)
|
|
111
|
+
self.stt.signals.wake_word_detected.connect(self.on_wake_word)
|
|
112
|
+
|
|
113
|
+
self.stt.start() # Launches background thread
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Config Pattern with deep_merge
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
import yaml
|
|
120
|
+
from pathlib import Path
|
|
121
|
+
from copy import deepcopy
|
|
122
|
+
|
|
123
|
+
DEFAULT_CONFIG = {
|
|
124
|
+
"stt": {
|
|
125
|
+
"model": "base.en",
|
|
126
|
+
"language": "en",
|
|
127
|
+
"wake_word": "hey claude",
|
|
128
|
+
"wake_word_debounce_ms": 2000,
|
|
129
|
+
"silence_threshold": 0.5,
|
|
130
|
+
},
|
|
131
|
+
"tts": {
|
|
132
|
+
"engine": "edge-tts", # "edge-tts" or "piper"
|
|
133
|
+
"voice": "en-US-AriaNeural",
|
|
134
|
+
"rate": "+0%",
|
|
135
|
+
"volume": "+0%",
|
|
136
|
+
"piper_model": None,
|
|
137
|
+
},
|
|
138
|
+
"overlay": {
|
|
139
|
+
"position": "bottom-right",
|
|
140
|
+
"opacity": 0.85,
|
|
141
|
+
"font_size": 14,
|
|
142
|
+
"show_on_transcription": True,
|
|
143
|
+
"auto_hide_seconds": 5,
|
|
144
|
+
},
|
|
145
|
+
"status_server": {
|
|
146
|
+
"enabled": True,
|
|
147
|
+
"port": 7899,
|
|
148
|
+
},
|
|
149
|
+
"hotkeys": {
|
|
150
|
+
"toggle_listening": "ctrl+shift+l",
|
|
151
|
+
"push_to_talk": "ctrl+shift+space",
|
|
152
|
+
},
|
|
153
|
+
"claude": {
|
|
154
|
+
"model": "claude-sonnet-4-20250514",
|
|
155
|
+
"max_tokens": 1024,
|
|
156
|
+
},
|
|
157
|
+
"post_processing": {
|
|
158
|
+
"capitalize_sentences": True,
|
|
159
|
+
"fix_common_words": True,
|
|
160
|
+
"remove_filler_words": False,
|
|
161
|
+
},
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
CONFIG_PATH = Path.home() / ".voice-bridge" / "config.yaml"
|
|
165
|
+
|
|
166
|
+
def deep_merge(base: dict, override: dict) -> dict:
|
|
167
|
+
"""Recursively merge override into base. Override wins on conflicts."""
|
|
168
|
+
result = deepcopy(base)
|
|
169
|
+
for key, value in override.items():
|
|
170
|
+
if key in result and isinstance(result[key], dict) and isinstance(value, dict):
|
|
171
|
+
result[key] = deep_merge(result[key], value)
|
|
172
|
+
else:
|
|
173
|
+
result[key] = deepcopy(value)
|
|
174
|
+
return result
|
|
175
|
+
|
|
176
|
+
def load_config() -> dict:
|
|
177
|
+
"""Load config with defaults. Old config files automatically gain new keys."""
|
|
178
|
+
if CONFIG_PATH.exists():
|
|
179
|
+
with open(CONFIG_PATH, "r") as f:
|
|
180
|
+
user_config = yaml.safe_load(f) or {}
|
|
181
|
+
return deep_merge(DEFAULT_CONFIG, user_config)
|
|
182
|
+
return deepcopy(DEFAULT_CONFIG)
|
|
183
|
+
|
|
184
|
+
def save_config(config: dict):
|
|
185
|
+
"""Save only user-modified values (diff against defaults)."""
|
|
186
|
+
CONFIG_PATH.parent.mkdir(parents=True, exist_ok=True)
|
|
187
|
+
with open(CONFIG_PATH, "w") as f:
|
|
188
|
+
yaml.dump(config, f, default_flow_style=False, sort_keys=False)
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Status Sidecar Pattern
|
|
192
|
+
|
|
193
|
+
```python
|
|
194
|
+
import json
|
|
195
|
+
import threading
|
|
196
|
+
from http.server import HTTPServer, BaseHTTPRequestHandler
|
|
197
|
+
from datetime import datetime
|
|
198
|
+
|
|
199
|
+
class StatusHandler(BaseHTTPRequestHandler):
|
|
200
|
+
"""Lightweight HTTP handler exposing app state as JSON."""
|
|
201
|
+
app_state = {} # Shared reference, set by orchestrator
|
|
202
|
+
|
|
203
|
+
def do_GET(self):
|
|
204
|
+
if self.path == "/status":
|
|
205
|
+
state = {
|
|
206
|
+
"service": "voice-bridge",
|
|
207
|
+
"version": "4.0.0",
|
|
208
|
+
"timestamp": datetime.now().isoformat(),
|
|
209
|
+
"uptime_seconds": self.app_state.get("uptime", 0),
|
|
210
|
+
"stt": {
|
|
211
|
+
"status": self.app_state.get("stt_status", "unknown"),
|
|
212
|
+
"model": self.app_state.get("stt_model", ""),
|
|
213
|
+
"total_transcriptions": self.app_state.get("transcription_count", 0),
|
|
214
|
+
},
|
|
215
|
+
"tts": {
|
|
216
|
+
"engine": self.app_state.get("tts_engine", ""),
|
|
217
|
+
"queue_size": self.app_state.get("tts_queue_size", 0),
|
|
218
|
+
},
|
|
219
|
+
"overlay": {
|
|
220
|
+
"visible": self.app_state.get("overlay_visible", False),
|
|
221
|
+
},
|
|
222
|
+
}
|
|
223
|
+
self.send_response(200)
|
|
224
|
+
self.send_header("Content-Type", "application/json")
|
|
225
|
+
self.send_header("Access-Control-Allow-Origin", "*")
|
|
226
|
+
self.end_headers()
|
|
227
|
+
self.wfile.write(json.dumps(state, indent=2).encode())
|
|
228
|
+
else:
|
|
229
|
+
self.send_error(404)
|
|
230
|
+
|
|
231
|
+
def log_message(self, format, *args):
|
|
232
|
+
pass # Suppress console spam
|
|
233
|
+
|
|
234
|
+
class StatusServer:
|
|
235
|
+
def __init__(self, port: int, app_state: dict):
|
|
236
|
+
StatusHandler.app_state = app_state
|
|
237
|
+
self.server = HTTPServer(("127.0.0.1", port), StatusHandler)
|
|
238
|
+
self.thread = threading.Thread(target=self.server.serve_forever, daemon=True)
|
|
239
|
+
|
|
240
|
+
def start(self):
|
|
241
|
+
self.thread.start()
|
|
242
|
+
|
|
243
|
+
def stop(self):
|
|
244
|
+
self.server.shutdown()
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### Post-Processing Pipeline with Fail-Fast Ordering
|
|
248
|
+
|
|
249
|
+
```python
|
|
250
|
+
class TextProcessor:
|
|
251
|
+
"""Pipeline of text transformations with fail-fast ordering."""
|
|
252
|
+
def __init__(self, config: dict):
|
|
253
|
+
self.steps = []
|
|
254
|
+
# Order matters: cheapest/most-likely-to-reject first
|
|
255
|
+
if config.get("remove_filler_words"):
|
|
256
|
+
self.steps.append(self._remove_fillers)
|
|
257
|
+
if config.get("fix_common_words"):
|
|
258
|
+
self.steps.append(self._fix_common_words)
|
|
259
|
+
if config.get("capitalize_sentences"):
|
|
260
|
+
self.steps.append(self._capitalize_sentences)
|
|
261
|
+
|
|
262
|
+
def process(self, text: str) -> str:
|
|
263
|
+
for step in self.steps:
|
|
264
|
+
text = step(text)
|
|
265
|
+
if not text.strip():
|
|
266
|
+
return "" # Fail fast: empty after processing
|
|
267
|
+
return text
|
|
268
|
+
|
|
269
|
+
def _remove_fillers(self, text: str) -> str:
|
|
270
|
+
fillers = ["um", "uh", "like", "you know", "basically", "actually"]
|
|
271
|
+
for filler in fillers:
|
|
272
|
+
text = text.replace(f" {filler} ", " ")
|
|
273
|
+
return text.strip()
|
|
274
|
+
|
|
275
|
+
def _fix_common_words(self, text: str) -> str:
|
|
276
|
+
corrections = {"claude": "Claude", "python": "Python", "github": "GitHub"}
|
|
277
|
+
for wrong, right in corrections.items():
|
|
278
|
+
text = text.replace(wrong, right)
|
|
279
|
+
return text
|
|
280
|
+
|
|
281
|
+
def _capitalize_sentences(self, text: str) -> str:
|
|
282
|
+
import re
|
|
283
|
+
return re.sub(r'(^|[.!?]\s+)([a-z])', lambda m: m.group(1) + m.group(2).upper(), text)
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### Overlay with Always-On-Top Transparency
|
|
287
|
+
|
|
288
|
+
```python
|
|
289
|
+
from PyQt6.QtWidgets import QWidget, QLabel, QVBoxLayout
|
|
290
|
+
from PyQt6.QtCore import Qt, QTimer, pyqtSlot
|
|
291
|
+
from PyQt6.QtGui import QFont
|
|
292
|
+
|
|
293
|
+
class Overlay(QWidget):
|
|
294
|
+
def __init__(self, config: dict):
|
|
295
|
+
super().__init__()
|
|
296
|
+
self.config = config
|
|
297
|
+
self.setWindowFlags(
|
|
298
|
+
Qt.WindowType.FramelessWindowHint
|
|
299
|
+
| Qt.WindowType.WindowStaysOnTopHint
|
|
300
|
+
| Qt.WindowType.Tool # Hides from taskbar
|
|
301
|
+
)
|
|
302
|
+
self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)
|
|
303
|
+
self.setWindowOpacity(config.get("opacity", 0.85))
|
|
304
|
+
|
|
305
|
+
self.label = QLabel("")
|
|
306
|
+
self.label.setFont(QFont("Segoe UI", config.get("font_size", 14)))
|
|
307
|
+
self.label.setStyleSheet("""
|
|
308
|
+
QLabel {
|
|
309
|
+
color: white;
|
|
310
|
+
background-color: rgba(0, 0, 0, 180);
|
|
311
|
+
border-radius: 8px;
|
|
312
|
+
padding: 12px 16px;
|
|
313
|
+
}
|
|
314
|
+
""")
|
|
315
|
+
layout = QVBoxLayout()
|
|
316
|
+
layout.addWidget(self.label)
|
|
317
|
+
self.setLayout(layout)
|
|
318
|
+
|
|
319
|
+
self.hide_timer = QTimer()
|
|
320
|
+
self.hide_timer.setSingleShot(True)
|
|
321
|
+
self.hide_timer.timeout.connect(self.hide)
|
|
322
|
+
|
|
323
|
+
@pyqtSlot(str)
|
|
324
|
+
def show_transcription(self, text: str):
|
|
325
|
+
"""Called via Qt signal from STT thread. Safe to update GUI here."""
|
|
326
|
+
self.label.setText(text)
|
|
327
|
+
self._position_overlay()
|
|
328
|
+
self.show()
|
|
329
|
+
auto_hide = self.config.get("auto_hide_seconds", 5)
|
|
330
|
+
if auto_hide > 0:
|
|
331
|
+
self.hide_timer.start(auto_hide * 1000)
|
|
332
|
+
|
|
333
|
+
def _position_overlay(self):
|
|
334
|
+
from PyQt6.QtWidgets import QApplication
|
|
335
|
+
screen = QApplication.primaryScreen().geometry()
|
|
336
|
+
pos = self.config.get("position", "bottom-right")
|
|
337
|
+
margin = 20
|
|
338
|
+
self.adjustSize()
|
|
339
|
+
if pos == "bottom-right":
|
|
340
|
+
self.move(screen.width() - self.width() - margin,
|
|
341
|
+
screen.height() - self.height() - margin - 40)
|
|
342
|
+
elif pos == "top-right":
|
|
343
|
+
self.move(screen.width() - self.width() - margin, margin)
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
## Implementation Steps
|
|
347
|
+
|
|
348
|
+
1. **Define DEFAULT_CONFIG first** -- Every feature starts as a config entry with a sensible default. This is config-first development.
|
|
349
|
+
2. **Build the config loader** with `deep_merge` so old config files automatically gain new keys.
|
|
350
|
+
3. **Create the overlay** as a standalone QWidget. Test it independently by showing/hiding with a timer.
|
|
351
|
+
4. **Build the STT engine** as a QThread subclass with signals. Test it standalone (print signals to console).
|
|
352
|
+
5. **Connect STT signals to overlay** -- This validates the threading model before adding complexity.
|
|
353
|
+
6. **Add TTS engine** with an audio queue pattern (sounddevice playback on its own thread).
|
|
354
|
+
7. **Add pystray tray** on a background thread with Qt signals for menu actions (toggle, settings, quit).
|
|
355
|
+
8. **Add the status sidecar** -- HTTPServer on a daemon thread, reading shared state dict.
|
|
356
|
+
9. **Build settings dialog** as a QDialog that reads/writes the config dict and calls `save_config`.
|
|
357
|
+
10. **Wire the orchestrator** (main.py) that instantiates everything, connects all signals, and runs `app.exec()`.
|
|
358
|
+
11. **Add post-processing pipeline** with fail-fast ordering (cheapest filters first).
|
|
359
|
+
12. **Add transcription history** for session logging and replay.
|
|
360
|
+
|
|
361
|
+
## When to Use
|
|
362
|
+
|
|
363
|
+
- Python desktop app with real-time audio input/output
|
|
364
|
+
- System tray applications that need a floating overlay
|
|
365
|
+
- Applications mixing blocking I/O (mic, network) with a responsive GUI
|
|
366
|
+
- Apps that need to expose internal state to external dashboards
|
|
367
|
+
- Any Python GUI app where multiple long-running background tasks must coexist
|
|
368
|
+
|
|
369
|
+
## When NOT to Use
|
|
370
|
+
|
|
371
|
+
- Simple CLI tools -- overkill for non-GUI apps
|
|
372
|
+
- Web applications -- use a web framework instead
|
|
373
|
+
- Applications that only need a tray icon without overlay -- pystray alone is simpler
|
|
374
|
+
- Cross-platform mobile apps -- use Flutter, React Native, or Kivy instead
|
|
375
|
+
- If you only need audio recording without real-time processing -- use simpler subprocess calls
|
|
376
|
+
|
|
377
|
+
## Common Mistakes
|
|
378
|
+
|
|
379
|
+
1. **Updating GUI from background thread** -- Qt crashes or silently corrupts. ALWAYS use signals or `QMetaObject.invokeMethod`. Never call `widget.setText()` from a non-main thread.
|
|
380
|
+
2. **Forgetting `daemon=True` on utility threads** -- The app hangs on exit because non-daemon threads block process termination.
|
|
381
|
+
3. **Not using `deep_merge` for config** -- Adding a new config key breaks users with existing config files. Their YAML lacks the new key, and code crashes on `KeyError`.
|
|
382
|
+
4. **Blocking the Qt event loop** -- Long API calls or TTS generation on the main thread freezes the overlay. Use QThread or `asyncio` integration.
|
|
383
|
+
5. **pystray blocking the main thread** -- pystray's `icon.run()` blocks. It MUST run on a background thread, with Qt signals bridging menu actions back to the main thread.
|
|
384
|
+
6. **Wake word debounce** -- Without debounce, the wake word fires multiple times in rapid succession. Use a timestamp check with a configurable cooldown (e.g., 2000ms).
|
|
385
|
+
7. **Not handling audio device changes** -- Users plug/unplug headphones. STT and TTS engines need graceful recovery or device re-enumeration.
|
|
386
|
+
|
|
387
|
+
## Related Skills
|
|
388
|
+
|
|
389
|
+
- `togglable-processing-pipeline.md` -- Fail-fast pipeline pattern used in text processor
|
|
390
|
+
- `realtime-monitoring-dashboard.md` -- The dashboard that consumes the status sidecar
|
|
391
|
+
- `multi-project-autonomous-build.md` -- The methodology used to build this alongside other projects
|
|
392
|
+
|
|
393
|
+
## References
|
|
394
|
+
|
|
395
|
+
- Contributed from: **voice-bridge-v4** (`C:\path\to\repos\voice-bridge-v3`)
|
|
396
|
+
- PyQt6 threading docs: https://doc.qt.io/qt-6/threads-qobject.html
|
|
397
|
+
- pystray docs: https://pystray.readthedocs.io/
|
|
398
|
+
- RealtimeSTT: https://github.com/KoljaB/RealtimeSTT
|
|
399
|
+
- edge-tts: https://github.com/rany2/edge-tts
|