@caddis/cli 0.2.6 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundles/antigravity-plugin/agents/claude-md-curator.md +1 -1
- package/bundles/antigravity-plugin/agents/knowledge-transfer.md +17 -32
- package/bundles/antigravity-plugin/caddis_statusline.py +825 -0
- package/bundles/antigravity-plugin/claude-md/folder-agents.md.tmpl +21 -0
- package/bundles/antigravity-plugin/guard_agy.py +60 -9
- package/bundles/antigravity-plugin/plugin.json +1 -1
- package/bundles/antigravity-plugin/scripts/caddis_gate.py +524 -0
- package/bundles/antigravity-plugin/scripts/caddis_inventory.py +439 -0
- package/bundles/antigravity-plugin/scripts/caddis_migrate_dir.py +270 -0
- package/bundles/antigravity-plugin/scripts/caddis_spawn.py +300 -0
- package/bundles/antigravity-plugin/scripts/caddis_statusline.py +825 -0
- package/bundles/antigravity-plugin/scripts/caddis_tidy.py +366 -0
- package/bundles/antigravity-plugin/scripts/check_doc_coverage.py +924 -0
- package/bundles/antigravity-plugin/scripts/claude-deepseek.ps1 +4 -0
- package/bundles/antigravity-plugin/scripts/claude-deepseek.sh +3 -0
- package/bundles/antigravity-plugin/scripts/claude-glm.ps1 +4 -0
- package/bundles/antigravity-plugin/scripts/claude-glm.sh +3 -0
- package/bundles/antigravity-plugin/scripts/claude-oss.ps1 +64 -0
- package/bundles/antigravity-plugin/scripts/claude-oss.sh +60 -0
- package/bundles/antigravity-plugin/scripts/claudster_config.py +121 -0
- package/bundles/antigravity-plugin/scripts/claudster_doctor.py +356 -0
- package/bundles/antigravity-plugin/scripts/claudster_init.py +400 -0
- package/bundles/antigravity-plugin/scripts/claudster_migrate_rules.py +300 -0
- package/bundles/antigravity-plugin/scripts/enforcement_inventory.py +261 -0
- package/bundles/antigravity-plugin/scripts/hook_log.py +156 -0
- package/bundles/antigravity-plugin/scripts/new-machine.ps1 +170 -0
- package/bundles/antigravity-plugin/scripts/oss_ask.py +98 -0
- package/bundles/antigravity-plugin/scripts/oss_model.py +174 -0
- package/bundles/antigravity-plugin/scripts/oss_review.py +718 -0
- package/bundles/antigravity-plugin/scripts/setup_project_ai.py +1432 -0
- package/bundles/antigravity-plugin/scripts/usage_review.py +1323 -0
- package/bundles/antigravity-plugin/session_end_agy.py +52 -8
- package/bundles/antigravity-plugin/skills/_registry.md +1 -0
- package/bundles/antigravity-plugin/skills/advisory-hub/SKILL.md +44 -0
- package/bundles/antigravity-plugin/skills/code-review/SKILL.md +11 -0
- package/bundles/antigravity-plugin/skills/fastapi-dev/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/feature-plan/SKILL.md +21 -0
- package/bundles/antigravity-plugin/skills/gate-review/SKILL.md +11 -0
- package/bundles/antigravity-plugin/skills/implement/SKILL.md +36 -0
- package/bundles/antigravity-plugin/skills/security-review/SKILL.md +9 -0
- package/bundles/antigravity-plugin/skills/ship/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/ship-merge/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/ship-pr/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/statusline/SKILL.md +105 -0
- package/bundles/antigravity-plugin/skills/use-model/SKILL.md +15 -3
- package/bundles/antigravity-plugin/skills/validate-phase/SKILL.md +31 -0
- package/bundles/antigravity-plugin/warm_start_agy.py +117 -11
- package/bundles/antigravity-plugin-extras/plugin.json +1 -1
- package/bundles/antigravity-plugin-extras/skills/architecture-design/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/caching-patterns/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/webapp-development/SKILL.md +1 -1
- package/bundles/codex/.codex/config.toml.example +36 -0
- package/bundles/codex/.codex/skills/coding/api-design/SKILL.md +249 -0
- package/bundles/codex/.codex/skills/coding/backend-development/SKILL.md +305 -0
- package/bundles/codex/.codex/skills/coding/code-review/SKILL.md +140 -0
- package/bundles/codex/.codex/skills/coding/codebase-audit/SKILL.md +204 -0
- package/bundles/codex/.codex/skills/coding/dashboard-perf-sweep/SKILL.md +132 -0
- package/bundles/codex/.codex/skills/coding/dashboard-perf-sweep/scripts/perf_sweep.py +249 -0
- package/bundles/codex/.codex/skills/coding/error-handling/SKILL.md +260 -0
- package/bundles/codex/.codex/skills/coding/fastapi-dev/SKILL.md +300 -0
- package/bundles/codex/.codex/skills/coding/javascript-typescript/SKILL.md +142 -0
- package/bundles/codex/.codex/skills/coding/python/SKILL.md +388 -0
- package/bundles/codex/.codex/skills/coding/refactoring/SKILL.md +486 -0
- package/bundles/codex/.codex/skills/coding/security-review/SKILL.md +205 -0
- package/bundles/codex/.codex/skills/coding/sql/SKILL.md +321 -0
- package/bundles/codex/.codex/skills/data/database-design/SKILL.md +177 -0
- package/bundles/codex/.codex/skills/data/db-diagram/SKILL.md +148 -0
- package/bundles/codex/.codex/skills/data/db-diagram/scripts/sql_to_graph.py +1212 -0
- package/bundles/codex/.codex/skills/devops/ci-cd-pipeline/SKILL.md +315 -0
- package/bundles/codex/.codex/skills/devops/gh-cli/SKILL.md +195 -0
- package/bundles/codex/.codex/skills/devops/git-commit/SKILL.md +285 -0
- package/bundles/codex/.codex/skills/devops/using-git-worktrees/SKILL.md +217 -0
- package/bundles/codex/.codex/skills/devops/windows-deployment/SKILL.md +880 -0
- package/bundles/codex/.codex/skills/docs/code-documentation/SKILL.md +271 -0
- package/bundles/codex/.codex/skills/docs/explainer-doc/SKILL.md +97 -0
- package/bundles/codex/.codex/skills/docs/technical-writing/SKILL.md +286 -0
- package/bundles/codex/.codex/skills/docs/writing-plans/SKILL.md +387 -0
- package/bundles/codex/.codex/skills/frontend/css-architecture/SKILL.md +305 -0
- package/bundles/codex/.codex/skills/frontend/css-architecture/references/RESPONSIVE-DESIGN.md +604 -0
- package/bundles/codex/.codex/skills/frontend/frontend-design/SKILL.md +193 -0
- package/bundles/codex/.codex/skills/frontend/frontend-design/references/my-tech-stack.md +127 -0
- package/bundles/codex/.codex/skills/frontend/mockup/SKILL.md +242 -0
- package/bundles/codex/.codex/skills/frontend/react-best-practices/SKILL.md +269 -0
- package/bundles/codex/.codex/skills/frontend/react-dev/README.md +404 -0
- package/bundles/codex/.codex/skills/frontend/react-dev/SKILL.md +459 -0
- package/bundles/codex/.codex/skills/frontend/react-dev/examples/generic-components.md +579 -0
- package/bundles/codex/.codex/skills/frontend/react-dev/examples/server-components.md +579 -0
- package/bundles/codex/.codex/skills/frontend/react-dev/references/event-handlers.md +574 -0
- package/bundles/codex/.codex/skills/frontend/react-dev/references/hooks.md +456 -0
- package/bundles/codex/.codex/skills/frontend/react-dev/references/react-19-patterns.md +638 -0
- package/bundles/codex/.codex/skills/frontend/react-dev/references/react-router.md +1002 -0
- package/bundles/codex/.codex/skills/frontend/react-dev/references/tanstack-router.md +587 -0
- package/bundles/codex/.codex/skills/frontend/ui-review/SKILL.md +176 -0
- package/bundles/codex/.codex/skills/frontend/ui-review/references/framework-fixes.md +471 -0
- package/bundles/codex/.codex/skills/frontend/ui-review/references/visual-checklist.md +236 -0
- package/bundles/codex/.codex/skills/frontend/warm-editorial-ui/DESIGN_TOKENS.md +487 -0
- package/bundles/codex/.codex/skills/frontend/warm-editorial-ui/IMPLEMENTATION_GUIDE.md +177 -0
- package/bundles/codex/.codex/skills/frontend/warm-editorial-ui/SKILL.md +732 -0
- package/bundles/codex/.codex/skills/media/draw-io/SKILL.md +162 -0
- package/bundles/codex/.codex/skills/media/draw-io/references/aws-icons.md +677 -0
- package/bundles/codex/.codex/skills/media/draw-io/references/layout-guidelines.md +142 -0
- package/bundles/codex/.codex/skills/media/draw-io/references/troubleshooting.md +118 -0
- package/bundles/codex/.codex/skills/media/draw-io/references/workflows.md +103 -0
- package/bundles/codex/.codex/skills/media/draw-io/scripts/convert-drawio-to-png.sh +25 -0
- package/bundles/codex/.codex/skills/media/draw-io/scripts/find_aws_icon.py +79 -0
- package/bundles/codex/.codex/skills/media/mermaid-diagrams/SKILL.md +292 -0
- package/bundles/codex/.codex/skills/media/mermaid-diagrams/references/ENHANCEMENTS.md +264 -0
- package/bundles/codex/.codex/skills/media/mermaid-diagrams/references/MERMAID-SUMMARY.md +137 -0
- package/bundles/codex/.codex/skills/media/mermaid-diagrams/references/advanced-features.md +556 -0
- package/bundles/codex/.codex/skills/media/mermaid-diagrams/references/architecture-diagrams.md +192 -0
- package/bundles/codex/.codex/skills/media/mermaid-diagrams/references/c4-diagrams.md +410 -0
- package/bundles/codex/.codex/skills/media/mermaid-diagrams/references/class-diagrams.md +361 -0
- package/bundles/codex/.codex/skills/media/mermaid-diagrams/references/erd-diagrams.md +510 -0
- package/bundles/codex/.codex/skills/media/mermaid-diagrams/references/flowcharts.md +450 -0
- package/bundles/codex/.codex/skills/media/mermaid-diagrams/references/sequence-diagrams.md +394 -0
- package/bundles/codex/.codex/skills/media/mermaid-diagrams/references/troubleshooting.md +335 -0
- package/bundles/codex/.codex/skills/media/mermaid-diagrams/references/workflows.md +418 -0
- package/bundles/codex/.codex/skills/media/particle-art/SKILL.md +243 -0
- package/bundles/codex/.codex/skills/media/particle-art/references/canvas-utils.ts +171 -0
- package/bundles/codex/.codex/skills/media/particle-art/references/dot-field.template.tsx +203 -0
- package/bundles/codex/.codex/skills/media/particle-art/references/flow-field.template.tsx +263 -0
- package/bundles/codex/.codex/skills/media/particle-art/references/node-shape.template.tsx +261 -0
- package/bundles/codex/.codex/skills/media/particle-art/references/shape-sampler.ts +281 -0
- package/bundles/codex/.codex/skills/media/particle-art/references/stipple-morph.template.tsx +167 -0
- package/bundles/codex/.codex/skills/media/particle-art/references/stipple.template.tsx +175 -0
- package/bundles/codex/.codex/skills/media/particle-art/references/trail-ghost.template.tsx +266 -0
- package/bundles/codex/.codex/skills/media/particle-art/references/usage-examples.md +320 -0
- package/bundles/codex/.codex/skills/testing/playwright/API_REFERENCE.md +653 -0
- package/bundles/codex/.codex/skills/testing/playwright/SKILL.md +454 -0
- package/bundles/codex/.codex/skills/testing/playwright/lib/helpers.js +441 -0
- package/bundles/codex/.codex/skills/testing/playwright/package.json +26 -0
- package/bundles/codex/.codex/skills/testing/playwright/run.js +228 -0
- package/bundles/codex/.codex/skills/testing/tdd-workflow/SKILL.md +188 -0
- package/bundles/codex/.codex/skills/testing/test-strategy/SKILL.md +155 -0
- package/bundles/codex/.codex/skills/testing/webapp-testing/LICENSE.txt +202 -0
- package/bundles/codex/.codex/skills/testing/webapp-testing/SKILL.md +97 -0
- package/bundles/codex/.codex/skills/testing/webapp-testing/examples/console_logging.py +35 -0
- package/bundles/codex/.codex/skills/testing/webapp-testing/examples/element_discovery.py +40 -0
- package/bundles/codex/.codex/skills/testing/webapp-testing/examples/static_html_automation.py +33 -0
- package/bundles/codex/.codex/skills/testing/webapp-testing/scripts/with_server.py +106 -0
- package/bundles/codex/.codex/skills/workflow/advisory-hub/SKILL.md +227 -0
- package/bundles/codex/.codex/skills/workflow/advisory-hub/reference/context-template.md +214 -0
- package/bundles/codex/.codex/skills/workflow/advisory-hub/reference/hub-handbook.md +233 -0
- package/bundles/codex/.codex/skills/workflow/advisory-hub/reference/report-contract.md +94 -0
- package/bundles/codex/.codex/skills/workflow/advisory-hub/reference/succession.md +118 -0
- package/bundles/codex/.codex/skills/workflow/best-practices/SKILL.md +500 -0
- package/bundles/codex/.codex/skills/workflow/best-practices/agents/best-practices-referencer.md +263 -0
- package/bundles/codex/.codex/skills/workflow/best-practices/agents/codebase-context-builder.md +326 -0
- package/bundles/codex/.codex/skills/workflow/best-practices/agents/task-intent-analyzer.md +245 -0
- package/bundles/codex/.codex/skills/workflow/best-practices/references/anti-patterns.md +571 -0
- package/bundles/codex/.codex/skills/workflow/best-practices/references/before-after-examples.md +1114 -0
- package/bundles/codex/.codex/skills/workflow/best-practices/references/best-practices-guide.md +513 -0
- package/bundles/codex/.codex/skills/workflow/best-practices/references/common-workflows.md +692 -0
- package/bundles/codex/.codex/skills/workflow/best-practices/references/prompt-patterns.md +547 -0
- package/bundles/codex/.codex/skills/workflow/brainstorming/SKILL.md +57 -0
- package/bundles/codex/.codex/skills/workflow/context-curator/SKILL.md +157 -0
- package/bundles/codex/.codex/skills/workflow/golden-plan/SKILL.md +586 -0
- package/bundles/codex/.codex/skills/workflow/preflight/SKILL.md +440 -0
- package/bundles/codex/.codex/skills/workflow/skill-creator/LICENSE.txt +202 -0
- package/bundles/codex/.codex/skills/workflow/skill-creator/SKILL.md +491 -0
- package/bundles/codex/.codex/skills/workflow/skill-creator/agents/analyzer.md +274 -0
- package/bundles/codex/.codex/skills/workflow/skill-creator/agents/comparator.md +202 -0
- package/bundles/codex/.codex/skills/workflow/skill-creator/agents/grader.md +223 -0
- package/bundles/codex/.codex/skills/workflow/skill-creator/assets/eval_review.html +146 -0
- package/bundles/codex/.codex/skills/workflow/skill-creator/eval-viewer/generate_review.py +471 -0
- package/bundles/codex/.codex/skills/workflow/skill-creator/eval-viewer/viewer.html +1325 -0
- package/bundles/codex/.codex/skills/workflow/skill-creator/references/schemas.md +430 -0
- package/bundles/codex/.codex/skills/workflow/skill-creator/scripts/__init__.py +0 -0
- package/bundles/codex/.codex/skills/workflow/skill-creator/scripts/aggregate_benchmark.py +401 -0
- package/bundles/codex/.codex/skills/workflow/skill-creator/scripts/generate_report.py +326 -0
- package/bundles/codex/.codex/skills/workflow/skill-creator/scripts/improve_description.py +247 -0
- package/bundles/codex/.codex/skills/workflow/skill-creator/scripts/package_skill.py +136 -0
- package/bundles/codex/.codex/skills/workflow/skill-creator/scripts/quick_validate.py +103 -0
- package/bundles/codex/.codex/skills/workflow/skill-creator/scripts/run_eval.py +310 -0
- package/bundles/codex/.codex/skills/workflow/skill-creator/scripts/run_loop.py +328 -0
- package/bundles/codex/.codex/skills/workflow/skill-creator/scripts/utils.py +47 -0
- package/bundles/codex/AGENTS.md +146 -0
- package/bundles/manifest.json +4 -3
- package/dist/claude-deepseek.js +544 -0
- package/dist/claude-glm.js +544 -0
- package/dist/claude-oss.js +544 -0
- package/dist/cli.js +542 -90
- package/package.json +5 -2
- package/bundles/antigravity-plugin/statusline-command-agy.sh +0 -91
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/ArsenalSC-OFL.txt +0 -93
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/BigShoulders-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/BigShoulders-OFL.txt +0 -93
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/BigShoulders-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Boldonse-OFL.txt +0 -93
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Boldonse-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt +0 -93
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/CrimsonPro-OFL.txt +0 -93
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/DMMono-OFL.txt +0 -93
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/DMMono-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/EricaOne-OFL.txt +0 -94
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/EricaOne-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/GeistMono-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/GeistMono-OFL.txt +0 -93
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/GeistMono-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Gloock-OFL.txt +0 -93
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Gloock-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/IBMPlexMono-OFL.txt +0 -93
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/InstrumentSans-OFL.txt +0 -93
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Italiana-OFL.txt +0 -93
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Italiana-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt +0 -93
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Jura-Light.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Jura-Medium.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Jura-OFL.txt +0 -93
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/LibreBaskerville-OFL.txt +0 -93
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Lora-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Lora-BoldItalic.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Lora-Italic.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Lora-OFL.txt +0 -93
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Lora-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/NationalPark-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/NationalPark-OFL.txt +0 -93
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/NationalPark-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt +0 -93
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Outfit-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Outfit-OFL.txt +0 -93
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Outfit-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/PixelifySans-Medium.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/PixelifySans-OFL.txt +0 -93
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/PoiretOne-OFL.txt +0 -93
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/PoiretOne-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/RedHatMono-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/RedHatMono-OFL.txt +0 -93
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/RedHatMono-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Silkscreen-OFL.txt +0 -93
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Silkscreen-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/SmoochSans-Medium.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/SmoochSans-OFL.txt +0 -93
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Tektur-OFL.txt +0 -93
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Tektur-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/WorkSans-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/WorkSans-Italic.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/WorkSans-OFL.txt +0 -93
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/WorkSans-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/YoungSerif-OFL.txt +0 -93
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fastapi-dev
|
|
3
|
+
description: Build FastAPI backends with standard patterns, error handling, and testing
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# FastAPI Development
|
|
7
|
+
|
|
8
|
+
> **Project Context** — Read `project-config.md` in the repo root for brand tokens, shared-library paths, and deployment targets.
|
|
9
|
+
|
|
10
|
+
## When to Use
|
|
11
|
+
|
|
12
|
+
Invoke this skill when:
|
|
13
|
+
- Creating a new FastAPI backend for a project
|
|
14
|
+
- Adding API endpoints for Streamlit frontends
|
|
15
|
+
- Implementing repository pattern with SQL Server
|
|
16
|
+
- Setting up dependency injection chains
|
|
17
|
+
- Configuring CORS for Streamlit ↔ FastAPI communication
|
|
18
|
+
- Deploying FastAPI on IIS/on-premise infrastructure
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Project Structure
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
backend/
|
|
26
|
+
├── app/
|
|
27
|
+
│ ├── __init__.py
|
|
28
|
+
│ ├── main.py # FastAPI application entry
|
|
29
|
+
│ ├── config.py # Settings (pydantic-settings)
|
|
30
|
+
│ ├── dependencies.py # Shared DI providers
|
|
31
|
+
│ ├── routers/
|
|
32
|
+
│ │ ├── __init__.py
|
|
33
|
+
│ │ ├── records.py # Records endpoints
|
|
34
|
+
│ │ └── analytics.py # Analytics endpoints
|
|
35
|
+
│ ├── models/
|
|
36
|
+
│ │ ├── __init__.py
|
|
37
|
+
│ │ ├── record.py # Pydantic request/response models
|
|
38
|
+
│ │ └── user.py
|
|
39
|
+
│ ├── services/
|
|
40
|
+
│ │ ├── __init__.py
|
|
41
|
+
│ │ └── record_service.py
|
|
42
|
+
│ └── repositories/
|
|
43
|
+
│ ├── __init__.py
|
|
44
|
+
│ └── record_repo.py
|
|
45
|
+
├── tests/
|
|
46
|
+
├── .env
|
|
47
|
+
└── requirements.txt
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Steps
|
|
53
|
+
|
|
54
|
+
### Step 1: Configuration (pydantic-settings)
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
# app/config.py
|
|
58
|
+
from functools import lru_cache
|
|
59
|
+
from pydantic_settings import BaseSettings
|
|
60
|
+
from pydantic import Field
|
|
61
|
+
|
|
62
|
+
class Settings(BaseSettings):
|
|
63
|
+
app_name: str = "API"
|
|
64
|
+
debug: bool = False
|
|
65
|
+
db_server: str = Field(..., description="SQL Server host")
|
|
66
|
+
db_name: str = Field(..., description="Database name")
|
|
67
|
+
db_password: str = Field(..., repr=False)
|
|
68
|
+
api_key: str = Field(..., repr=False)
|
|
69
|
+
allowed_origins: list[str] = ["http://localhost:8501"]
|
|
70
|
+
ollama_base_url: str = "http://localhost:11434"
|
|
71
|
+
ollama_model: str = "llama3.1"
|
|
72
|
+
|
|
73
|
+
class Config:
|
|
74
|
+
env_file = ".env"
|
|
75
|
+
|
|
76
|
+
@lru_cache
|
|
77
|
+
def get_settings() -> Settings:
|
|
78
|
+
return Settings()
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Step 2: Pydantic Models (Base/Create/Update/Response pattern)
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
# app/models/record.py
|
|
85
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
86
|
+
from uuid import UUID
|
|
87
|
+
from datetime import datetime
|
|
88
|
+
from typing import Literal
|
|
89
|
+
|
|
90
|
+
class RecordBase(BaseModel):
|
|
91
|
+
customer_id: str = Field(..., min_length=1, max_length=50, example="CUST001")
|
|
92
|
+
record_type: Literal["billing", "service", "technical"]
|
|
93
|
+
description: str = Field(..., min_length=10, max_length=5000)
|
|
94
|
+
priority: int = Field(default=3, ge=1, le=5)
|
|
95
|
+
|
|
96
|
+
class RecordCreate(RecordBase):
|
|
97
|
+
pass
|
|
98
|
+
|
|
99
|
+
class RecordUpdate(BaseModel):
|
|
100
|
+
status: Literal["open", "in_progress", "resolved"] | None = None
|
|
101
|
+
resolution_notes: str | None = Field(None, max_length=2000)
|
|
102
|
+
priority: int | None = Field(None, ge=1, le=5)
|
|
103
|
+
|
|
104
|
+
class RecordResponse(RecordBase):
|
|
105
|
+
model_config = ConfigDict(from_attributes=True)
|
|
106
|
+
id: UUID
|
|
107
|
+
status: str
|
|
108
|
+
created_at: datetime
|
|
109
|
+
updated_at: datetime | None = None
|
|
110
|
+
|
|
111
|
+
class RecordList(BaseModel):
|
|
112
|
+
items: list[RecordResponse]
|
|
113
|
+
total: int
|
|
114
|
+
page: int
|
|
115
|
+
per_page: int
|
|
116
|
+
pages: int
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Step 3: Dependency Injection Chain
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
# app/dependencies.py
|
|
123
|
+
from typing import Annotated, Generator
|
|
124
|
+
from fastapi import Depends, Header, HTTPException
|
|
125
|
+
from libs.data import DatabaseAdapter
|
|
126
|
+
|
|
127
|
+
def get_db_adapter() -> Generator[DatabaseAdapter, None, None]:
|
|
128
|
+
adapter = DatabaseAdapter()
|
|
129
|
+
try:
|
|
130
|
+
yield adapter
|
|
131
|
+
finally:
|
|
132
|
+
adapter.close()
|
|
133
|
+
|
|
134
|
+
def get_record_repository(
|
|
135
|
+
db: Annotated[DatabaseAdapter, Depends(get_db_adapter)]
|
|
136
|
+
) -> RecordRepository:
|
|
137
|
+
return RecordRepository(db)
|
|
138
|
+
|
|
139
|
+
def get_record_service(
|
|
140
|
+
repo: Annotated[RecordRepository, Depends(get_record_repository)]
|
|
141
|
+
) -> RecordService:
|
|
142
|
+
return RecordService(repo)
|
|
143
|
+
|
|
144
|
+
async def verify_api_key(
|
|
145
|
+
x_api_key: Annotated[str, Header(..., description="API Key")]
|
|
146
|
+
) -> str:
|
|
147
|
+
if x_api_key != get_settings().api_key:
|
|
148
|
+
raise HTTPException(status_code=401, detail="Invalid API key")
|
|
149
|
+
return x_api_key
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Step 4: Router Pattern
|
|
153
|
+
|
|
154
|
+
```python
|
|
155
|
+
# app/routers/records.py
|
|
156
|
+
from fastapi import APIRouter, Depends, Query
|
|
157
|
+
from typing import Annotated
|
|
158
|
+
|
|
159
|
+
router = APIRouter(prefix="/records", tags=["records"])
|
|
160
|
+
|
|
161
|
+
@router.get("/", response_model=RecordList)
|
|
162
|
+
async def list_records(
|
|
163
|
+
service: Annotated[RecordService, Depends(get_record_service)],
|
|
164
|
+
page: int = Query(1, ge=1),
|
|
165
|
+
per_page: int = Query(25, ge=1, le=100),
|
|
166
|
+
status: str | None = None,
|
|
167
|
+
):
|
|
168
|
+
return await service.list_records(page=page, per_page=per_page, status=status)
|
|
169
|
+
|
|
170
|
+
@router.post("/", response_model=RecordResponse, status_code=201)
|
|
171
|
+
async def create_record(
|
|
172
|
+
record: RecordCreate,
|
|
173
|
+
service: Annotated[RecordService, Depends(get_record_service)],
|
|
174
|
+
):
|
|
175
|
+
return await service.create_record(record)
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Step 5: Application Entry
|
|
179
|
+
|
|
180
|
+
```python
|
|
181
|
+
# app/main.py
|
|
182
|
+
from fastapi import FastAPI, Request
|
|
183
|
+
from fastapi.middleware.cors import CORSMiddleware
|
|
184
|
+
from fastapi.responses import JSONResponse
|
|
185
|
+
from loguru import logger
|
|
186
|
+
|
|
187
|
+
app = FastAPI(title="API", version="1.0.0")
|
|
188
|
+
|
|
189
|
+
# CORS for Streamlit frontends
|
|
190
|
+
app.add_middleware(
|
|
191
|
+
CORSMiddleware,
|
|
192
|
+
allow_origins=get_settings().allowed_origins,
|
|
193
|
+
allow_credentials=True,
|
|
194
|
+
allow_methods=["*"],
|
|
195
|
+
allow_headers=["*"],
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
app.include_router(records_router)
|
|
199
|
+
|
|
200
|
+
@app.get("/health")
|
|
201
|
+
async def health_check():
|
|
202
|
+
return {"status": "healthy", "service": "API"}
|
|
203
|
+
|
|
204
|
+
@app.exception_handler(Exception)
|
|
205
|
+
async def global_exception_handler(request: Request, exc: Exception):
|
|
206
|
+
logger.exception(f"Unhandled error on {request.url.path}: {exc}")
|
|
207
|
+
return JSONResponse(status_code=500, content={"detail": "An internal error occurred"})
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Step 6: SQL Server Connection
|
|
211
|
+
|
|
212
|
+
```python
|
|
213
|
+
# Using pyodbc for MSSQL with Windows Auth
|
|
214
|
+
import pyodbc
|
|
215
|
+
|
|
216
|
+
conn_str = (
|
|
217
|
+
"DRIVER={ODBC Driver 18 for SQL Server};"
|
|
218
|
+
f"SERVER={settings.db_server};"
|
|
219
|
+
f"DATABASE={settings.db_name};"
|
|
220
|
+
"Trusted_Connection=yes;"
|
|
221
|
+
"Encrypt=yes;"
|
|
222
|
+
"TrustServerCertificate=yes;"
|
|
223
|
+
)
|
|
224
|
+
conn = pyodbc.connect(conn_str, timeout=10)
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## Patterns and Examples
|
|
230
|
+
|
|
231
|
+
### Repository Pattern
|
|
232
|
+
|
|
233
|
+
```python
|
|
234
|
+
class RecordRepository:
|
|
235
|
+
def __init__(self, adapter: DatabaseAdapter):
|
|
236
|
+
self._adapter = adapter
|
|
237
|
+
|
|
238
|
+
def get_by_id(self, record_id: UUID) -> dict | None:
|
|
239
|
+
query = "SELECT * FROM AppRecords WHERE CaseID = ?"
|
|
240
|
+
return self._adapter.fetch_one(query, (str(record_id),))
|
|
241
|
+
|
|
242
|
+
def get_paginated(self, page: int, per_page: int, status: str | None) -> tuple[list, int]:
|
|
243
|
+
count_query = "SELECT COUNT(*) FROM AppRecords"
|
|
244
|
+
params = []
|
|
245
|
+
if status:
|
|
246
|
+
count_query += " WHERE Status = ?"
|
|
247
|
+
params.append(status)
|
|
248
|
+
total = self._adapter.fetch_scalar(count_query, params)
|
|
249
|
+
|
|
250
|
+
query = "SELECT * FROM AppRecords"
|
|
251
|
+
if status:
|
|
252
|
+
query += " WHERE Status = ?"
|
|
253
|
+
query += " ORDER BY [Created Date Time] DESC OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"
|
|
254
|
+
params.extend([(page - 1) * per_page, per_page])
|
|
255
|
+
items = self._adapter.fetch_all(query, params)
|
|
256
|
+
return items, total
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### Error Handling with loguru
|
|
260
|
+
|
|
261
|
+
```python
|
|
262
|
+
from loguru import logger
|
|
263
|
+
|
|
264
|
+
@router.post("/")
|
|
265
|
+
async def create_record(record: RecordCreate, service: ...):
|
|
266
|
+
try:
|
|
267
|
+
result = await service.create_record(record)
|
|
268
|
+
logger.info(f"Created record {result.id} for customer {record.customer_id}")
|
|
269
|
+
return result
|
|
270
|
+
except ValidationError as e:
|
|
271
|
+
logger.warning(f"Validation error: {e}")
|
|
272
|
+
raise HTTPException(status_code=422, detail=str(e))
|
|
273
|
+
except Exception as e:
|
|
274
|
+
logger.exception(f"Failed to create record: {e}")
|
|
275
|
+
raise HTTPException(status_code=500, detail="Internal error")
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## Checklist
|
|
281
|
+
|
|
282
|
+
- [ ] Project structure follows standard pattern (routers/models/services/repositories)
|
|
283
|
+
- [ ] Pydantic models use Base/Create/Update/Response hierarchy
|
|
284
|
+
- [ ] Dependency injection chain: adapter -> repo -> service
|
|
285
|
+
- [ ] CORS configured for Streamlit frontend origins
|
|
286
|
+
- [ ] Health check endpoint at `/health`
|
|
287
|
+
- [ ] Global exception handler with loguru logging
|
|
288
|
+
- [ ] SQL queries use parameterized inputs (no f-strings)
|
|
289
|
+
- [ ] Configuration via pydantic-settings and .env file
|
|
290
|
+
- [ ] API key verification on protected endpoints
|
|
291
|
+
- [ ] All endpoints have proper response_model types
|
|
292
|
+
|
|
293
|
+
## Related Resources
|
|
294
|
+
|
|
295
|
+
| Resource | Path |
|
|
296
|
+
|----------|------|
|
|
297
|
+
| FastAPI instructions | `instructions/fastapi.instructions.md` |
|
|
298
|
+
| SQL expert skill | the `sql` skill |
|
|
299
|
+
| Python instructions | `instructions/python.instructions.md` |
|
|
300
|
+
| Security instructions | `instructions/security.instructions.md` |
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: javascript-typescript
|
|
3
|
+
description: JavaScript and TypeScript development with ES6+, Node.js, React, and modern web frameworks. Use for frontend, backend, or full-stack JavaScript/TypeScript projects.
|
|
4
|
+
source: wshobson/agents
|
|
5
|
+
license: MIT
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# JavaScript/TypeScript Development
|
|
9
|
+
|
|
10
|
+
## TypeScript Configuration
|
|
11
|
+
|
|
12
|
+
```json
|
|
13
|
+
{
|
|
14
|
+
"compilerOptions": {
|
|
15
|
+
"target": "ES2022",
|
|
16
|
+
"module": "ESNext",
|
|
17
|
+
"moduleResolution": "bundler",
|
|
18
|
+
"strict": true,
|
|
19
|
+
"noUncheckedIndexedAccess": true,
|
|
20
|
+
"noImplicitOverride": true,
|
|
21
|
+
"skipLibCheck": true,
|
|
22
|
+
"declaration": true,
|
|
23
|
+
"outDir": "./dist"
|
|
24
|
+
},
|
|
25
|
+
"include": ["src/**/*"],
|
|
26
|
+
"exclude": ["node_modules", "dist"]
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Type Patterns
|
|
31
|
+
|
|
32
|
+
### Utility Types
|
|
33
|
+
```typescript
|
|
34
|
+
// Pick specific properties
|
|
35
|
+
type UserPreview = Pick<User, 'id' | 'name'>;
|
|
36
|
+
|
|
37
|
+
// Omit properties
|
|
38
|
+
type CreateUser = Omit<User, 'id' | 'createdAt'>;
|
|
39
|
+
|
|
40
|
+
// Make all properties optional
|
|
41
|
+
type PartialUser = Partial<User>;
|
|
42
|
+
|
|
43
|
+
// Make all properties required
|
|
44
|
+
type RequiredUser = Required<User>;
|
|
45
|
+
|
|
46
|
+
// Extract union types
|
|
47
|
+
type Status = 'pending' | 'active' | 'inactive';
|
|
48
|
+
type ActiveStatus = Extract<Status, 'active' | 'pending'>;
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Discriminated Unions
|
|
52
|
+
```typescript
|
|
53
|
+
type Result<T> =
|
|
54
|
+
| { success: true; data: T }
|
|
55
|
+
| { success: false; error: Error };
|
|
56
|
+
|
|
57
|
+
function handleResult<T>(result: Result<T>) {
|
|
58
|
+
if (result.success) {
|
|
59
|
+
console.log(result.data); // T
|
|
60
|
+
} else {
|
|
61
|
+
console.error(result.error); // Error
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Generic Constraints
|
|
67
|
+
```typescript
|
|
68
|
+
interface HasId {
|
|
69
|
+
id: string | number;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function findById<T extends HasId>(items: T[], id: T['id']): T | undefined {
|
|
73
|
+
return items.find(item => item.id === id);
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Modern JavaScript
|
|
78
|
+
|
|
79
|
+
### Destructuring & Spread
|
|
80
|
+
```javascript
|
|
81
|
+
const { name, ...rest } = user;
|
|
82
|
+
const merged = { ...defaults, ...options };
|
|
83
|
+
const [first, ...others] = items;
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Optional Chaining & Nullish Coalescing
|
|
87
|
+
```javascript
|
|
88
|
+
const city = user?.address?.city ?? 'Unknown';
|
|
89
|
+
const count = data?.items?.length ?? 0;
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Array Methods
|
|
93
|
+
```javascript
|
|
94
|
+
const adults = users.filter(u => u.age >= 18);
|
|
95
|
+
const names = users.map(u => u.name);
|
|
96
|
+
const total = items.reduce((sum, item) => sum + item.price, 0);
|
|
97
|
+
const hasAdmin = users.some(u => u.role === 'admin');
|
|
98
|
+
const allActive = users.every(u => u.active);
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## React Patterns
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
// Props with children
|
|
105
|
+
interface CardProps {
|
|
106
|
+
title: string;
|
|
107
|
+
children: React.ReactNode;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Event handlers
|
|
111
|
+
interface ButtonProps {
|
|
112
|
+
onClick: (event: React.MouseEvent<HTMLButtonElement>) => void;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Custom hooks
|
|
116
|
+
function useLocalStorage<T>(key: string, initial: T) {
|
|
117
|
+
const [value, setValue] = useState<T>(() => {
|
|
118
|
+
const stored = localStorage.getItem(key);
|
|
119
|
+
return stored ? JSON.parse(stored) : initial;
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
useEffect(() => {
|
|
123
|
+
localStorage.setItem(key, JSON.stringify(value));
|
|
124
|
+
}, [key, value]);
|
|
125
|
+
|
|
126
|
+
return [value, setValue] as const;
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Node.js Patterns
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
// ES Modules
|
|
134
|
+
import { readFile } from 'node:fs/promises';
|
|
135
|
+
import { join } from 'node:path';
|
|
136
|
+
|
|
137
|
+
// Error handling
|
|
138
|
+
process.on('unhandledRejection', (reason) => {
|
|
139
|
+
console.error('Unhandled Rejection:', reason);
|
|
140
|
+
process.exit(1);
|
|
141
|
+
});
|
|
142
|
+
```
|