@mytechtoday/augment-extensions 0.2.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (420) hide show
  1. package/README.md +614 -39
  2. package/augment-extensions/coding-standards/bash/README.md +196 -0
  3. package/augment-extensions/coding-standards/bash/module.json +163 -0
  4. package/augment-extensions/coding-standards/bash/rules/naming-conventions.md +336 -0
  5. package/augment-extensions/coding-standards/bash/rules/universal-standards.md +289 -0
  6. package/augment-extensions/coding-standards/css/README.md +40 -0
  7. package/augment-extensions/coding-standards/css/examples/css-examples.css +550 -0
  8. package/augment-extensions/coding-standards/css/module.json +44 -0
  9. package/augment-extensions/coding-standards/css/rules/css-modern-features.md +448 -0
  10. package/augment-extensions/coding-standards/css/rules/css-standards.md +492 -0
  11. package/augment-extensions/coding-standards/html/README.md +40 -0
  12. package/augment-extensions/coding-standards/html/examples/html-examples.html +267 -0
  13. package/augment-extensions/coding-standards/html/examples/responsive-layout.html +505 -0
  14. package/augment-extensions/coding-standards/html/module.json +44 -0
  15. package/augment-extensions/coding-standards/html/rules/html-standards.md +349 -0
  16. package/augment-extensions/coding-standards/html-css-js/README.md +194 -0
  17. package/augment-extensions/coding-standards/html-css-js/examples/async-examples.js +487 -0
  18. package/augment-extensions/coding-standards/html-css-js/examples/css-examples.css +550 -0
  19. package/augment-extensions/coding-standards/html-css-js/examples/dom-examples.js +667 -0
  20. package/augment-extensions/coding-standards/html-css-js/examples/html-examples.html +267 -0
  21. package/augment-extensions/coding-standards/html-css-js/examples/javascript-examples.js +612 -0
  22. package/augment-extensions/coding-standards/html-css-js/examples/responsive-layout.html +505 -0
  23. package/augment-extensions/coding-standards/html-css-js/module.json +48 -0
  24. package/augment-extensions/coding-standards/html-css-js/rules/async-patterns.md +515 -0
  25. package/augment-extensions/coding-standards/html-css-js/rules/css-modern-features.md +448 -0
  26. package/augment-extensions/coding-standards/html-css-js/rules/css-standards.md +492 -0
  27. package/augment-extensions/coding-standards/html-css-js/rules/dom-manipulation.md +439 -0
  28. package/augment-extensions/coding-standards/html-css-js/rules/html-standards.md +349 -0
  29. package/augment-extensions/coding-standards/html-css-js/rules/javascript-standards.md +486 -0
  30. package/augment-extensions/coding-standards/html-css-js/rules/performance.md +463 -0
  31. package/augment-extensions/coding-standards/html-css-js/rules/tooling.md +543 -0
  32. package/augment-extensions/coding-standards/js/README.md +46 -0
  33. package/augment-extensions/coding-standards/js/examples/async-examples.js +487 -0
  34. package/augment-extensions/coding-standards/js/examples/dom-examples.js +667 -0
  35. package/augment-extensions/coding-standards/js/examples/javascript-examples.js +612 -0
  36. package/augment-extensions/coding-standards/js/module.json +49 -0
  37. package/augment-extensions/coding-standards/js/rules/async-patterns.md +515 -0
  38. package/augment-extensions/coding-standards/js/rules/dom-manipulation.md +439 -0
  39. package/augment-extensions/coding-standards/js/rules/javascript-standards.md +486 -0
  40. package/augment-extensions/coding-standards/js/rules/performance.md +463 -0
  41. package/augment-extensions/coding-standards/js/rules/tooling.md +543 -0
  42. package/augment-extensions/coding-standards/php/README.md +248 -0
  43. package/augment-extensions/coding-standards/php/examples/api-endpoint-example.php +204 -0
  44. package/augment-extensions/coding-standards/php/examples/cli-command-example.php +206 -0
  45. package/augment-extensions/coding-standards/php/examples/legacy-refactoring-example.php +234 -0
  46. package/augment-extensions/coding-standards/php/examples/web-application-example.php +211 -0
  47. package/augment-extensions/coding-standards/php/examples/woocommerce-extension-example.php +215 -0
  48. package/augment-extensions/coding-standards/php/examples/wordpress-plugin-example.php +189 -0
  49. package/augment-extensions/coding-standards/php/module.json +166 -0
  50. package/augment-extensions/coding-standards/php/rules/api-development.md +480 -0
  51. package/augment-extensions/coding-standards/php/rules/category-configuration.md +332 -0
  52. package/augment-extensions/coding-standards/php/rules/cli-tools.md +472 -0
  53. package/augment-extensions/coding-standards/php/rules/cms-integration.md +561 -0
  54. package/augment-extensions/coding-standards/php/rules/code-quality.md +402 -0
  55. package/augment-extensions/coding-standards/php/rules/documentation.md +425 -0
  56. package/augment-extensions/coding-standards/php/rules/ecommerce.md +627 -0
  57. package/augment-extensions/coding-standards/php/rules/error-handling.md +336 -0
  58. package/augment-extensions/coding-standards/php/rules/legacy-migration.md +677 -0
  59. package/augment-extensions/coding-standards/php/rules/naming-conventions.md +279 -0
  60. package/augment-extensions/coding-standards/php/rules/performance.md +392 -0
  61. package/augment-extensions/coding-standards/php/rules/psr-standards.md +186 -0
  62. package/augment-extensions/coding-standards/php/rules/security.md +358 -0
  63. package/augment-extensions/coding-standards/php/rules/testing.md +403 -0
  64. package/augment-extensions/coding-standards/php/rules/type-declarations.md +331 -0
  65. package/augment-extensions/coding-standards/php/rules/web-applications.md +426 -0
  66. package/augment-extensions/coding-standards/powershell/README.md +154 -0
  67. package/augment-extensions/coding-standards/powershell/examples/admin-example.ps1 +272 -0
  68. package/augment-extensions/coding-standards/powershell/examples/automation-example.ps1 +173 -0
  69. package/augment-extensions/coding-standards/powershell/examples/cloud-example.ps1 +243 -0
  70. package/augment-extensions/coding-standards/powershell/examples/cross-platform-example.ps1 +297 -0
  71. package/augment-extensions/coding-standards/powershell/examples/dsc-example.ps1 +224 -0
  72. package/augment-extensions/coding-standards/powershell/examples/legacy-migration-example.ps1 +340 -0
  73. package/augment-extensions/coding-standards/powershell/examples/module-example.psm1 +255 -0
  74. package/augment-extensions/coding-standards/powershell/module.json +165 -0
  75. package/augment-extensions/coding-standards/powershell/rules/administrative-tools.md +439 -0
  76. package/augment-extensions/coding-standards/powershell/rules/automation-scripts.md +240 -0
  77. package/augment-extensions/coding-standards/powershell/rules/cloud-orchestration.md +384 -0
  78. package/augment-extensions/coding-standards/powershell/rules/configuration-schema.md +383 -0
  79. package/augment-extensions/coding-standards/powershell/rules/cross-platform-scripts.md +482 -0
  80. package/augment-extensions/coding-standards/powershell/rules/dsc-configurations.md +296 -0
  81. package/augment-extensions/coding-standards/powershell/rules/error-handling.md +314 -0
  82. package/augment-extensions/coding-standards/powershell/rules/legacy-migrations.md +466 -0
  83. package/augment-extensions/coding-standards/powershell/rules/modules-functions.md +244 -0
  84. package/augment-extensions/coding-standards/powershell/rules/naming-conventions.md +266 -0
  85. package/augment-extensions/coding-standards/powershell/rules/performance-optimization.md +209 -0
  86. package/augment-extensions/coding-standards/powershell/rules/security-practices.md +314 -0
  87. package/augment-extensions/coding-standards/powershell/rules/testing-guidelines.md +268 -0
  88. package/augment-extensions/coding-standards/powershell/rules/universal-standards.md +197 -0
  89. package/augment-extensions/coding-standards/python/README.md +12 -8
  90. package/augment-extensions/coding-standards/python/examples/best-practices.py +373 -0
  91. package/augment-extensions/coding-standards/python/module.json +8 -4
  92. package/augment-extensions/coding-standards/python/rules/async-patterns.md +884 -0
  93. package/augment-extensions/coding-standards/python/rules/documentation.md +831 -0
  94. package/augment-extensions/coding-standards/python/rules/error-handling.md +855 -68
  95. package/augment-extensions/coding-standards/python/rules/testing.md +409 -0
  96. package/augment-extensions/coding-standards/python/rules/tooling.md +446 -0
  97. package/augment-extensions/coding-standards/python/rules/type-hints.md +115 -50
  98. package/augment-extensions/collections/html-css-js/README.md +82 -0
  99. package/augment-extensions/collections/html-css-js/collection.json +41 -0
  100. package/augment-extensions/domain-rules/database/README.md +161 -0
  101. package/augment-extensions/domain-rules/database/examples/flat-database-example.md +793 -0
  102. package/augment-extensions/domain-rules/database/examples/hybrid-database-example.md +1132 -0
  103. package/augment-extensions/domain-rules/database/examples/nosql-document-example.md +868 -0
  104. package/augment-extensions/domain-rules/database/examples/nosql-graph-example.md +805 -0
  105. package/augment-extensions/domain-rules/database/examples/relational-schema-example.md +621 -0
  106. package/augment-extensions/domain-rules/database/examples/vector-database-example.md +965 -0
  107. package/augment-extensions/domain-rules/database/module.json +28 -0
  108. package/augment-extensions/domain-rules/database/rules/flat-databases.md +624 -0
  109. package/augment-extensions/domain-rules/database/rules/nosql-databases.md +588 -0
  110. package/augment-extensions/domain-rules/database/rules/nosql-document-stores.md +856 -0
  111. package/augment-extensions/domain-rules/database/rules/nosql-graph-databases.md +778 -0
  112. package/augment-extensions/domain-rules/database/rules/nosql-key-value-stores.md +963 -0
  113. package/augment-extensions/domain-rules/database/rules/performance-optimization.md +1076 -0
  114. package/augment-extensions/domain-rules/database/rules/relational-databases.md +697 -0
  115. package/augment-extensions/domain-rules/database/rules/relational-indexing.md +671 -0
  116. package/augment-extensions/domain-rules/database/rules/relational-query-optimization.md +607 -0
  117. package/augment-extensions/domain-rules/database/rules/relational-schema-design.md +907 -0
  118. package/augment-extensions/domain-rules/database/rules/relational-transactions.md +783 -0
  119. package/augment-extensions/domain-rules/database/rules/security-standards.md +980 -0
  120. package/augment-extensions/domain-rules/database/rules/universal-best-practices.md +485 -0
  121. package/augment-extensions/domain-rules/database/rules/vector-databases.md +521 -0
  122. package/augment-extensions/domain-rules/database/rules/vector-embeddings.md +858 -0
  123. package/augment-extensions/domain-rules/database/rules/vector-indexing.md +934 -0
  124. package/augment-extensions/domain-rules/design/color/themes/catppuccin-latte/README.md +23 -0
  125. package/augment-extensions/domain-rules/design/color/themes/catppuccin-latte/module.json +26 -0
  126. package/augment-extensions/domain-rules/design/color/themes/catppuccin-mocha/README.md +23 -0
  127. package/augment-extensions/domain-rules/design/color/themes/catppuccin-mocha/module.json +26 -0
  128. package/augment-extensions/domain-rules/design/color/themes/dracula/README.md +23 -0
  129. package/augment-extensions/domain-rules/design/color/themes/dracula/module.json +26 -0
  130. package/augment-extensions/domain-rules/design/color/themes/gruvbox-dark/README.md +23 -0
  131. package/augment-extensions/domain-rules/design/color/themes/gruvbox-dark/module.json +26 -0
  132. package/augment-extensions/domain-rules/design/color/themes/gruvbox-light/README.md +23 -0
  133. package/augment-extensions/domain-rules/design/color/themes/gruvbox-light/module.json +26 -0
  134. package/augment-extensions/domain-rules/design/color/themes/high-contrast/README.md +27 -0
  135. package/augment-extensions/domain-rules/design/color/themes/high-contrast/module.json +26 -0
  136. package/augment-extensions/domain-rules/design/color/themes/monokai/README.md +23 -0
  137. package/augment-extensions/domain-rules/design/color/themes/monokai/module.json +26 -0
  138. package/augment-extensions/domain-rules/design/color/themes/nord/README.md +23 -0
  139. package/augment-extensions/domain-rules/design/color/themes/nord/module.json +26 -0
  140. package/augment-extensions/domain-rules/design/color/themes/one-dark/README.md +23 -0
  141. package/augment-extensions/domain-rules/design/color/themes/one-dark/module.json +26 -0
  142. package/augment-extensions/domain-rules/design/color/themes/one-light/README.md +23 -0
  143. package/augment-extensions/domain-rules/design/color/themes/one-light/module.json +26 -0
  144. package/augment-extensions/domain-rules/design/color/themes/solarized-dark/README.md +23 -0
  145. package/augment-extensions/domain-rules/design/color/themes/solarized-dark/module.json +26 -0
  146. package/augment-extensions/domain-rules/design/color/themes/solarized-light/README.md +23 -0
  147. package/augment-extensions/domain-rules/design/color/themes/solarized-light/module.json +26 -0
  148. package/augment-extensions/domain-rules/design/color/themes/tokyo-night/README.md +23 -0
  149. package/augment-extensions/domain-rules/design/color/themes/tokyo-night/module.json +26 -0
  150. package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/README.md +136 -0
  151. package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/SCHEMA-VALIDATION-REPORT.md +216 -0
  152. package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/examples/brand-kit-example.yaml +292 -0
  153. package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/examples/campaign-brief-example.yaml +389 -0
  154. package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/examples/content-calendar-example.yaml +643 -0
  155. package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/examples/email-newsletter-example.md +376 -0
  156. package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/examples/landing-page-example.md +934 -0
  157. package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/examples/ppc-ad-copy-example.md +301 -0
  158. package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/examples/seo-blog-post-example.md +347 -0
  159. package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/examples/social-media-campaign-example.md +606 -0
  160. package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/module.json +50 -0
  161. package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/rules/affiliate-influencer-marketing.md +593 -0
  162. package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/rules/asset-management.md +418 -0
  163. package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/rules/brand-consistency.md +210 -0
  164. package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/rules/content-marketing.md +337 -0
  165. package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/rules/conversion-optimization.md +455 -0
  166. package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/rules/direct-sales.md +499 -0
  167. package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/rules/email-marketing.md +439 -0
  168. package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/rules/legal-compliance.md +227 -0
  169. package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/rules/ppc-advertising.md +569 -0
  170. package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/rules/seo-optimization.md +470 -0
  171. package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/rules/social-media-marketing.md +414 -0
  172. package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/rules/universal-marketing.md +177 -0
  173. package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/schemas/asset-inventory.schema.json +247 -0
  174. package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/schemas/brand-kit.schema.json +326 -0
  175. package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/schemas/campaign-brief.schema.json +342 -0
  176. package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/schemas/color-palette.schema.json +223 -0
  177. package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/schemas/content-template.schema.json +383 -0
  178. package/augment-extensions/domain-rules/mcp/README.md +150 -0
  179. package/augment-extensions/domain-rules/mcp/examples/compressed-example.md +522 -0
  180. package/augment-extensions/domain-rules/mcp/examples/graph-augmented-example.md +520 -0
  181. package/augment-extensions/domain-rules/mcp/examples/hybrid-example.md +570 -0
  182. package/augment-extensions/domain-rules/mcp/examples/state-based-example.md +427 -0
  183. package/augment-extensions/domain-rules/mcp/examples/token-based-example.md +435 -0
  184. package/augment-extensions/domain-rules/mcp/examples/vector-based-example.md +502 -0
  185. package/augment-extensions/domain-rules/mcp/module.json +49 -0
  186. package/augment-extensions/domain-rules/mcp/rules/compressed-mcp.md +595 -0
  187. package/augment-extensions/domain-rules/mcp/rules/configuration.md +345 -0
  188. package/augment-extensions/domain-rules/mcp/rules/graph-augmented-mcp.md +687 -0
  189. package/augment-extensions/domain-rules/mcp/rules/hybrid-mcp.md +636 -0
  190. package/augment-extensions/domain-rules/mcp/rules/state-based-mcp.md +484 -0
  191. package/augment-extensions/domain-rules/mcp/rules/testing-validation.md +360 -0
  192. package/augment-extensions/domain-rules/mcp/rules/token-based-mcp.md +393 -0
  193. package/augment-extensions/domain-rules/mcp/rules/universal-rules.md +194 -0
  194. package/augment-extensions/domain-rules/mcp/rules/vector-based-mcp.md +625 -0
  195. package/augment-extensions/workflows/beads/module.json +4 -3
  196. package/augment-extensions/workflows/beads-integration/IMPLEMENTATION-STATUS.md +145 -0
  197. package/augment-extensions/workflows/beads-integration/README.md +143 -0
  198. package/augment-extensions/workflows/beads-integration/config/defaults.json +32 -0
  199. package/augment-extensions/workflows/beads-integration/config/schema.json +140 -0
  200. package/augment-extensions/workflows/beads-integration/examples/basic-task-generation.md +293 -0
  201. package/augment-extensions/workflows/beads-integration/module.json +75 -0
  202. package/augment-extensions/workflows/beads-integration/rules/core-rules.md +219 -0
  203. package/augment-extensions/workflows/beads-integration/rules/effectiveness-standards.md +256 -0
  204. package/augment-extensions/workflows/beads-integration/rules/task-generation.md +607 -0
  205. package/augment-extensions/workflows/database/README.md +195 -0
  206. package/augment-extensions/workflows/database/ai-prompt-testing.md +295 -0
  207. package/augment-extensions/workflows/database/examples/migration-example.md +498 -0
  208. package/augment-extensions/workflows/database/examples/optimization-example.md +496 -0
  209. package/augment-extensions/workflows/database/examples/schema-design-example.md +444 -0
  210. package/augment-extensions/workflows/database/module.json +42 -0
  211. package/augment-extensions/workflows/database/rules/data-migration.md +249 -0
  212. package/augment-extensions/workflows/database/rules/documentation-standards.md +339 -0
  213. package/augment-extensions/workflows/database/rules/migration-workflow.md +352 -0
  214. package/augment-extensions/workflows/database/rules/optimization-workflow.md +435 -0
  215. package/augment-extensions/workflows/database/rules/schema-design-workflow.md +535 -0
  216. package/augment-extensions/workflows/database/rules/testing-patterns.md +305 -0
  217. package/augment-extensions/workflows/database/rules/workflow.md +458 -0
  218. package/augment-extensions/workflows/openspec/module.json +4 -3
  219. package/augment-extensions/writing-standards/screenplay/README.md +300 -0
  220. package/augment-extensions/writing-standards/screenplay/_templates/README.md +121 -0
  221. package/augment-extensions/writing-standards/screenplay/_templates/genre-template.md +153 -0
  222. package/augment-extensions/writing-standards/screenplay/_templates/style-template.md +243 -0
  223. package/augment-extensions/writing-standards/screenplay/_templates/theme-template.md +213 -0
  224. package/augment-extensions/writing-standards/screenplay/examples/aaa-hollywood-scene.fountain +164 -0
  225. package/augment-extensions/writing-standards/screenplay/examples/beat-sheet-example.yaml +95 -0
  226. package/augment-extensions/writing-standards/screenplay/examples/character-profile-example.yaml +116 -0
  227. package/augment-extensions/writing-standards/screenplay/examples/commercial-30sec.fountain +151 -0
  228. package/augment-extensions/writing-standards/screenplay/examples/independent-monologue.fountain +67 -0
  229. package/augment-extensions/writing-standards/screenplay/examples/news-segment.fountain +142 -0
  230. package/augment-extensions/writing-standards/screenplay/examples/plot-outline-example.yaml +184 -0
  231. package/augment-extensions/writing-standards/screenplay/examples/tv-episode-teaser.fountain +204 -0
  232. package/augment-extensions/writing-standards/screenplay/genres/README.md +181 -0
  233. package/augment-extensions/writing-standards/screenplay/genres/examples/.gitkeep +2 -0
  234. package/augment-extensions/writing-standards/screenplay/genres/module.json +70 -0
  235. package/augment-extensions/writing-standards/screenplay/genres/rules/.gitkeep +2 -0
  236. package/augment-extensions/writing-standards/screenplay/genres/rules/action.md +399 -0
  237. package/augment-extensions/writing-standards/screenplay/genres/rules/adventure.md +407 -0
  238. package/augment-extensions/writing-standards/screenplay/genres/rules/animation.md +293 -0
  239. package/augment-extensions/writing-standards/screenplay/genres/rules/biographical.md +293 -0
  240. package/augment-extensions/writing-standards/screenplay/genres/rules/comedy.md +401 -0
  241. package/augment-extensions/writing-standards/screenplay/genres/rules/documentary.md +293 -0
  242. package/augment-extensions/writing-standards/screenplay/genres/rules/drama.md +409 -0
  243. package/augment-extensions/writing-standards/screenplay/genres/rules/fantasy.md +293 -0
  244. package/augment-extensions/writing-standards/screenplay/genres/rules/historical.md +293 -0
  245. package/augment-extensions/writing-standards/screenplay/genres/rules/horror.md +268 -0
  246. package/augment-extensions/writing-standards/screenplay/genres/rules/musical.md +294 -0
  247. package/augment-extensions/writing-standards/screenplay/genres/rules/mystery.md +293 -0
  248. package/augment-extensions/writing-standards/screenplay/genres/rules/noir.md +294 -0
  249. package/augment-extensions/writing-standards/screenplay/genres/rules/romance.md +293 -0
  250. package/augment-extensions/writing-standards/screenplay/genres/rules/sci-fi.md +289 -0
  251. package/augment-extensions/writing-standards/screenplay/genres/rules/superhero.md +293 -0
  252. package/augment-extensions/writing-standards/screenplay/genres/rules/thriller.md +294 -0
  253. package/augment-extensions/writing-standards/screenplay/genres/rules/western.md +293 -0
  254. package/augment-extensions/writing-standards/screenplay/module.json +124 -0
  255. package/augment-extensions/writing-standards/screenplay/rules/aaa-hollywood-films.md +339 -0
  256. package/augment-extensions/writing-standards/screenplay/rules/ai-integration-testing.md +329 -0
  257. package/augment-extensions/writing-standards/screenplay/rules/character-development.md +169 -0
  258. package/augment-extensions/writing-standards/screenplay/rules/commercials.md +437 -0
  259. package/augment-extensions/writing-standards/screenplay/rules/dialogue-writing.md +263 -0
  260. package/augment-extensions/writing-standards/screenplay/rules/diversity-inclusion.md +261 -0
  261. package/augment-extensions/writing-standards/screenplay/rules/examples-guide.md +315 -0
  262. package/augment-extensions/writing-standards/screenplay/rules/formatting-validation.md +413 -0
  263. package/augment-extensions/writing-standards/screenplay/rules/fountain-format.md +372 -0
  264. package/augment-extensions/writing-standards/screenplay/rules/independent-films.md +374 -0
  265. package/augment-extensions/writing-standards/screenplay/rules/live-tv-productions.md +443 -0
  266. package/augment-extensions/writing-standards/screenplay/rules/narrative-structures.md +207 -0
  267. package/augment-extensions/writing-standards/screenplay/rules/news-broadcasts.md +444 -0
  268. package/augment-extensions/writing-standards/screenplay/rules/pacing-timing.md +331 -0
  269. package/augment-extensions/writing-standards/screenplay/rules/quality-review-checklist.md +334 -0
  270. package/augment-extensions/writing-standards/screenplay/rules/quick-reference.md +299 -0
  271. package/augment-extensions/writing-standards/screenplay/rules/screen-continuity.md +263 -0
  272. package/augment-extensions/writing-standards/screenplay/rules/streaming-content.md +412 -0
  273. package/augment-extensions/writing-standards/screenplay/rules/trope-management.md +370 -0
  274. package/augment-extensions/writing-standards/screenplay/rules/tv-series.md +374 -0
  275. package/augment-extensions/writing-standards/screenplay/rules/universal-formatting.md +339 -0
  276. package/augment-extensions/writing-standards/screenplay/rules/vscode-integration.md +277 -0
  277. package/augment-extensions/writing-standards/screenplay/rules/web-content.md +393 -0
  278. package/augment-extensions/writing-standards/screenplay/schemas/beat-sheet.json +332 -0
  279. package/augment-extensions/writing-standards/screenplay/schemas/character-profile.json +247 -0
  280. package/augment-extensions/writing-standards/screenplay/schemas/feature-selection.json +200 -0
  281. package/augment-extensions/writing-standards/screenplay/schemas/plot-outline.json +233 -0
  282. package/augment-extensions/writing-standards/screenplay/schemas/screenplay-config.json +245 -0
  283. package/augment-extensions/writing-standards/screenplay/schemas/trope-inventory.json +221 -0
  284. package/augment-extensions/writing-standards/screenplay/styles/README.md +159 -0
  285. package/augment-extensions/writing-standards/screenplay/styles/examples/.gitkeep +2 -0
  286. package/augment-extensions/writing-standards/screenplay/styles/examples/style-applications.md +1449 -0
  287. package/augment-extensions/writing-standards/screenplay/styles/module.json +64 -0
  288. package/augment-extensions/writing-standards/screenplay/styles/rules/.gitkeep +2 -0
  289. package/augment-extensions/writing-standards/screenplay/styles/rules/dialogue-centric.md +520 -0
  290. package/augment-extensions/writing-standards/screenplay/styles/rules/ensemble.md +499 -0
  291. package/augment-extensions/writing-standards/screenplay/styles/rules/epic.md +497 -0
  292. package/augment-extensions/writing-standards/screenplay/styles/rules/experimental.md +492 -0
  293. package/augment-extensions/writing-standards/screenplay/styles/rules/flashback.md +509 -0
  294. package/augment-extensions/writing-standards/screenplay/styles/rules/linear.md +490 -0
  295. package/augment-extensions/writing-standards/screenplay/styles/rules/minimalist.md +499 -0
  296. package/augment-extensions/writing-standards/screenplay/styles/rules/non-linear.md +501 -0
  297. package/augment-extensions/writing-standards/screenplay/styles/rules/poetic.md +499 -0
  298. package/augment-extensions/writing-standards/screenplay/styles/rules/realistic.md +498 -0
  299. package/augment-extensions/writing-standards/screenplay/styles/rules/satirical.md +499 -0
  300. package/augment-extensions/writing-standards/screenplay/styles/rules/surreal.md +508 -0
  301. package/augment-extensions/writing-standards/screenplay/styles/rules/voice-over.md +500 -0
  302. package/augment-extensions/writing-standards/screenplay/themes/README.md +158 -0
  303. package/augment-extensions/writing-standards/screenplay/themes/examples/.gitkeep +2 -0
  304. package/augment-extensions/writing-standards/screenplay/themes/examples/common-mistakes-and-fixes.md +643 -0
  305. package/augment-extensions/writing-standards/screenplay/themes/examples/complete-scene-example.md +311 -0
  306. package/augment-extensions/writing-standards/screenplay/themes/examples/individual-theme-examples.md +562 -0
  307. package/augment-extensions/writing-standards/screenplay/themes/examples/multi-theme-weaving.md +538 -0
  308. package/augment-extensions/writing-standards/screenplay/themes/examples/theme-application-guide.md +432 -0
  309. package/augment-extensions/writing-standards/screenplay/themes/examples/theme-integration-across-acts.md +637 -0
  310. package/augment-extensions/writing-standards/screenplay/themes/module.json +66 -0
  311. package/augment-extensions/writing-standards/screenplay/themes/rules/.gitkeep +2 -0
  312. package/augment-extensions/writing-standards/screenplay/themes/rules/ambition.md +458 -0
  313. package/augment-extensions/writing-standards/screenplay/themes/rules/betrayal.md +490 -0
  314. package/augment-extensions/writing-standards/screenplay/themes/rules/environment.md +458 -0
  315. package/augment-extensions/writing-standards/screenplay/themes/rules/fate.md +459 -0
  316. package/augment-extensions/writing-standards/screenplay/themes/rules/friendship.md +491 -0
  317. package/augment-extensions/writing-standards/screenplay/themes/rules/growth.md +491 -0
  318. package/augment-extensions/writing-standards/screenplay/themes/rules/identity.md +490 -0
  319. package/augment-extensions/writing-standards/screenplay/themes/rules/isolation.md +464 -0
  320. package/augment-extensions/writing-standards/screenplay/themes/rules/justice.md +461 -0
  321. package/augment-extensions/writing-standards/screenplay/themes/rules/love.md +489 -0
  322. package/augment-extensions/writing-standards/screenplay/themes/rules/power.md +494 -0
  323. package/augment-extensions/writing-standards/screenplay/themes/rules/redemption.md +483 -0
  324. package/augment-extensions/writing-standards/screenplay/themes/rules/revenge.md +489 -0
  325. package/augment-extensions/writing-standards/screenplay/themes/rules/survival.md +496 -0
  326. package/augment-extensions/writing-standards/screenplay/themes/rules/technology.md +463 -0
  327. package/cli/MODULES.md +302 -0
  328. package/cli/dist/cli.js +168 -10
  329. package/cli/dist/cli.js.map +1 -1
  330. package/cli/dist/commands/catalog.d.ts +13 -0
  331. package/cli/dist/commands/catalog.d.ts.map +1 -0
  332. package/cli/dist/commands/catalog.js +104 -0
  333. package/cli/dist/commands/catalog.js.map +1 -0
  334. package/cli/dist/commands/gui.d.ts +6 -0
  335. package/cli/dist/commands/gui.d.ts.map +1 -0
  336. package/cli/dist/commands/gui.js +211 -0
  337. package/cli/dist/commands/gui.js.map +1 -0
  338. package/cli/dist/commands/init.d.ts.map +1 -1
  339. package/cli/dist/commands/init.js +12 -0
  340. package/cli/dist/commands/init.js.map +1 -1
  341. package/cli/dist/commands/install-rules.d.ts +14 -0
  342. package/cli/dist/commands/install-rules.d.ts.map +1 -0
  343. package/cli/dist/commands/install-rules.js +127 -0
  344. package/cli/dist/commands/install-rules.js.map +1 -0
  345. package/cli/dist/commands/link.d.ts.map +1 -1
  346. package/cli/dist/commands/link.js +9 -11
  347. package/cli/dist/commands/link.js.map +1 -1
  348. package/cli/dist/commands/list.d.ts.map +1 -1
  349. package/cli/dist/commands/list.js +11 -28
  350. package/cli/dist/commands/list.js.map +1 -1
  351. package/cli/dist/commands/mcp.d.ts +48 -0
  352. package/cli/dist/commands/mcp.d.ts.map +1 -0
  353. package/cli/dist/commands/mcp.js +229 -0
  354. package/cli/dist/commands/mcp.js.map +1 -0
  355. package/cli/dist/commands/self-remove.d.ts +7 -0
  356. package/cli/dist/commands/self-remove.d.ts.map +1 -0
  357. package/cli/dist/commands/self-remove.js +179 -0
  358. package/cli/dist/commands/self-remove.js.map +1 -0
  359. package/cli/dist/commands/show.d.ts +19 -0
  360. package/cli/dist/commands/show.d.ts.map +1 -1
  361. package/cli/dist/commands/show.js +478 -63
  362. package/cli/dist/commands/show.js.map +1 -1
  363. package/cli/dist/commands/skill.d.ts +67 -0
  364. package/cli/dist/commands/skill.d.ts.map +1 -0
  365. package/cli/dist/commands/skill.js +513 -0
  366. package/cli/dist/commands/skill.js.map +1 -0
  367. package/cli/dist/commands/unlink.d.ts +6 -0
  368. package/cli/dist/commands/unlink.d.ts.map +1 -0
  369. package/cli/dist/commands/unlink.js +115 -0
  370. package/cli/dist/commands/unlink.js.map +1 -0
  371. package/cli/dist/commands/validate.d.ts +6 -0
  372. package/cli/dist/commands/validate.d.ts.map +1 -0
  373. package/cli/dist/commands/validate.js +159 -0
  374. package/cli/dist/commands/validate.js.map +1 -0
  375. package/cli/dist/types/gui.d.ts +62 -0
  376. package/cli/dist/types/gui.d.ts.map +1 -0
  377. package/cli/dist/types/gui.js +30 -0
  378. package/cli/dist/types/gui.js.map +1 -0
  379. package/cli/dist/utils/catalog-sync.d.ts +22 -0
  380. package/cli/dist/utils/catalog-sync.d.ts.map +1 -0
  381. package/cli/dist/utils/catalog-sync.js +157 -0
  382. package/cli/dist/utils/catalog-sync.js.map +1 -0
  383. package/cli/dist/utils/character-count.d.ts +56 -0
  384. package/cli/dist/utils/character-count.d.ts.map +1 -0
  385. package/cli/dist/utils/character-count.js +190 -0
  386. package/cli/dist/utils/character-count.js.map +1 -0
  387. package/cli/dist/utils/documentation-validator.d.ts +18 -0
  388. package/cli/dist/utils/documentation-validator.d.ts.map +1 -0
  389. package/cli/dist/utils/documentation-validator.js +233 -0
  390. package/cli/dist/utils/documentation-validator.js.map +1 -0
  391. package/cli/dist/utils/gui-helpers.d.ts +23 -0
  392. package/cli/dist/utils/gui-helpers.d.ts.map +1 -0
  393. package/cli/dist/utils/gui-helpers.js +159 -0
  394. package/cli/dist/utils/gui-helpers.js.map +1 -0
  395. package/cli/dist/utils/install-rules.d.ts +32 -0
  396. package/cli/dist/utils/install-rules.d.ts.map +1 -0
  397. package/cli/dist/utils/install-rules.js +375 -0
  398. package/cli/dist/utils/install-rules.js.map +1 -0
  399. package/cli/dist/utils/mcp-integration.d.ts +70 -0
  400. package/cli/dist/utils/mcp-integration.d.ts.map +1 -0
  401. package/cli/dist/utils/mcp-integration.js +292 -0
  402. package/cli/dist/utils/mcp-integration.js.map +1 -0
  403. package/cli/dist/utils/module-system.d.ts +232 -0
  404. package/cli/dist/utils/module-system.d.ts.map +1 -0
  405. package/cli/dist/utils/module-system.js +900 -0
  406. package/cli/dist/utils/module-system.js.map +1 -0
  407. package/cli/dist/utils/modules-catalog.d.ts +33 -0
  408. package/cli/dist/utils/modules-catalog.d.ts.map +1 -0
  409. package/cli/dist/utils/modules-catalog.js +163 -0
  410. package/cli/dist/utils/modules-catalog.js.map +1 -0
  411. package/cli/dist/utils/rule-install-hooks.d.ts +19 -0
  412. package/cli/dist/utils/rule-install-hooks.d.ts.map +1 -0
  413. package/cli/dist/utils/rule-install-hooks.js +224 -0
  414. package/cli/dist/utils/rule-install-hooks.js.map +1 -0
  415. package/cli/dist/utils/skill-system.d.ts +95 -0
  416. package/cli/dist/utils/skill-system.d.ts.map +1 -0
  417. package/cli/dist/utils/skill-system.js +313 -0
  418. package/cli/dist/utils/skill-system.js.map +1 -0
  419. package/modules.md +559 -105
  420. package/package.json +17 -6
@@ -1,25 +1,35 @@
1
1
  # Python Error Handling
2
2
 
3
- Proper exception handling patterns for robust Python code.
3
+ Comprehensive exception handling patterns for robust Python code, including custom exceptions, context managers, and contextlib utilities.
4
4
 
5
5
  ## Basic Exception Handling
6
6
 
7
+ ### Specific Exceptions
8
+
9
+ Always catch specific exceptions rather than using bare `except:` clauses.
10
+
7
11
  ```python
8
12
  # Good - Specific exception
9
13
  try:
10
14
  result = int(user_input)
11
15
  except ValueError as e:
12
- print(f"Invalid input: {e}")
16
+ logger.error(f"Invalid input: {e}")
13
17
  result = 0
14
18
 
15
19
  # Bad - Bare except
16
20
  try:
17
21
  result = int(user_input)
18
- except: # Don't do this
22
+ except: # Don't do this - catches SystemExit, KeyboardInterrupt, etc.
23
+ result = 0
24
+
25
+ # Bad - Too broad
26
+ try:
27
+ result = int(user_input)
28
+ except Exception: # Still too broad for most cases
19
29
  result = 0
20
30
  ```
21
31
 
22
- ## Multiple Exceptions
32
+ ### Multiple Exceptions
23
33
 
24
34
  ```python
25
35
  # Handle different exceptions differently
@@ -27,195 +37,972 @@ try:
27
37
  with open(file_path) as f:
28
38
  data = json.load(f)
29
39
  except FileNotFoundError:
30
- print(f"File not found: {file_path}")
40
+ logger.warning(f"File not found: {file_path}")
31
41
  data = {}
32
42
  except json.JSONDecodeError as e:
33
- print(f"Invalid JSON: {e}")
43
+ logger.error(f"Invalid JSON in {file_path}: {e}")
34
44
  data = {}
35
45
  except PermissionError:
36
- print(f"Permission denied: {file_path}")
37
- data = {}
46
+ logger.error(f"Permission denied: {file_path}")
47
+ raise # Re-raise if we can't handle it
38
48
 
39
49
  # Handle multiple exceptions the same way
40
50
  try:
41
51
  result = perform_operation()
42
52
  except (ValueError, TypeError, KeyError) as e:
43
- print(f"Operation failed: {e}")
53
+ logger.error(f"Operation failed: {e}")
44
54
  result = None
45
55
  ```
46
56
 
47
- ## Finally and Else
57
+ ## Try-Except-Else-Finally
58
+
59
+ ### The Complete Pattern
60
+
61
+ ```python
62
+ try:
63
+ # Code that might raise exceptions
64
+ result = risky_operation()
65
+ except ValueError as e:
66
+ # Handle specific exception
67
+ logger.error(f"Value error: {e}")
68
+ result = None
69
+ except TypeError as e:
70
+ # Handle another specific exception
71
+ logger.error(f"Type error: {e}")
72
+ result = None
73
+ else:
74
+ # Runs only if no exception was raised
75
+ logger.info("Operation succeeded")
76
+ process_result(result)
77
+ finally:
78
+ # Always runs, even if exception occurred or return was called
79
+ cleanup_resources()
80
+ ```
81
+
82
+ ### Using Else Clause
83
+
84
+ The `else` clause runs only if no exception was raised in the `try` block.
48
85
 
49
86
  ```python
50
- # Using finally for cleanup
87
+ # Good - Separates success logic from try block
88
+ try:
89
+ data = load_data(file_path)
90
+ except FileNotFoundError:
91
+ logger.error(f"File not found: {file_path}")
92
+ return None
93
+ else:
94
+ # Only runs if load_data succeeded
95
+ validate_data(data)
96
+ return process_data(data)
97
+
98
+ # Less clear - success logic mixed with risky code
99
+ try:
100
+ data = load_data(file_path)
101
+ validate_data(data) # This is also in the try block
102
+ return process_data(data)
103
+ except FileNotFoundError:
104
+ logger.error(f"File not found: {file_path}")
105
+ return None
106
+ ```
107
+
108
+ ### Using Finally for Cleanup
109
+
110
+ ```python
111
+ # Manual cleanup with finally
112
+ file = None
51
113
  try:
52
114
  file = open(file_path)
53
115
  data = file.read()
54
116
  except FileNotFoundError:
55
- print("File not found")
117
+ logger.error("File not found")
56
118
  data = None
57
119
  finally:
58
- if 'file' in locals():
120
+ if file is not None:
59
121
  file.close()
60
122
 
61
- # Using else for success case
123
+ # Better - Use context manager instead (see below)
62
124
  try:
63
- result = risky_operation()
64
- except ValueError:
65
- print("Operation failed")
66
- else:
67
- print("Operation succeeded")
68
- process_result(result)
69
- finally:
70
- cleanup()
125
+ with open(file_path) as file:
126
+ data = file.read()
127
+ except FileNotFoundError:
128
+ logger.error("File not found")
129
+ data = None
71
130
  ```
72
131
 
73
132
  ## Context Managers
74
133
 
134
+ Context managers provide automatic resource management using the `with` statement. They ensure cleanup code runs even if exceptions occur.
135
+
136
+ ### Built-in Context Managers
137
+
75
138
  ```python
76
- # Preferred - Automatic cleanup
139
+ # File handling - Automatic close
77
140
  with open(file_path) as f:
78
141
  data = f.read()
142
+ # File is automatically closed here, even if exception occurred
79
143
 
80
- # Multiple context managers
144
+ # Multiple context managers (Python 3.1+)
81
145
  with open(input_file) as f_in, open(output_file, 'w') as f_out:
82
146
  data = f_in.read()
83
147
  f_out.write(process(data))
84
148
 
85
- # Custom context manager
149
+ # Parenthesized context managers (Python 3.10+)
150
+ with (
151
+ open(input_file) as f_in,
152
+ open(output_file, 'w') as f_out,
153
+ open(log_file, 'a') as f_log,
154
+ ):
155
+ data = f_in.read()
156
+ f_out.write(process(data))
157
+ f_log.write(f"Processed {input_file}\n")
158
+
159
+ # Threading locks
160
+ import threading
161
+
162
+ lock = threading.Lock()
163
+ with lock:
164
+ # Critical section - lock is automatically released
165
+ shared_resource.modify()
166
+ ```
167
+
168
+ ### Custom Context Managers - Class-Based
169
+
170
+ ```python
171
+ from typing import Optional
172
+
173
+ class DatabaseConnection:
174
+ """Context manager for database connections."""
175
+
176
+ def __init__(self, db_url: str):
177
+ self.db_url = db_url
178
+ self.conn: Optional[Connection] = None
179
+
180
+ def __enter__(self) -> Connection:
181
+ """Establish connection when entering context."""
182
+ self.conn = connect(self.db_url)
183
+ logger.info(f"Connected to {self.db_url}")
184
+ return self.conn
185
+
186
+ def __exit__(self, exc_type, exc_val, exc_tb) -> bool:
187
+ """Close connection when exiting context.
188
+
189
+ Args:
190
+ exc_type: Exception type if exception occurred, None otherwise
191
+ exc_val: Exception value if exception occurred, None otherwise
192
+ exc_tb: Exception traceback if exception occurred, None otherwise
193
+
194
+ Returns:
195
+ False to propagate exceptions, True to suppress them
196
+ """
197
+ if self.conn is not None:
198
+ self.conn.close()
199
+ logger.info(f"Closed connection to {self.db_url}")
200
+
201
+ # Log exception if one occurred
202
+ if exc_type is not None:
203
+ logger.error(f"Exception in database context: {exc_val}")
204
+
205
+ # Return False to propagate exception, True to suppress it
206
+ return False
207
+
208
+ # Usage
209
+ with DatabaseConnection("postgresql://localhost/mydb") as conn:
210
+ conn.execute("SELECT * FROM users")
211
+ ```
212
+
213
+ ### Custom Context Managers - contextlib.contextmanager
214
+
215
+ The `@contextmanager` decorator provides a simpler way to create context managers using generators.
216
+
217
+ ```python
86
218
  from contextlib import contextmanager
219
+ from typing import Generator, Optional
220
+ import time
87
221
 
88
222
  @contextmanager
89
- def database_connection(db_url: str):
223
+ def database_connection(db_url: str) -> Generator[Connection, None, None]:
224
+ """Context manager for database connections.
225
+
226
+ Args:
227
+ db_url: Database connection URL
228
+
229
+ Yields:
230
+ Active database connection
231
+
232
+ Example:
233
+ with database_connection("postgresql://...") as conn:
234
+ conn.execute("SELECT * FROM users")
235
+ """
90
236
  conn = connect(db_url)
91
237
  try:
238
+ logger.info(f"Connected to {db_url}")
92
239
  yield conn
240
+ except Exception as e:
241
+ logger.error(f"Database error: {e}")
242
+ raise
93
243
  finally:
94
244
  conn.close()
245
+ logger.info(f"Closed connection to {db_url}")
246
+
247
+ @contextmanager
248
+ def timer(name: str) -> Generator[None, None, None]:
249
+ """Context manager to time code execution.
250
+
251
+ Args:
252
+ name: Name of the timed operation
253
+
254
+ Example:
255
+ with timer("data processing"):
256
+ process_large_dataset()
257
+ """
258
+ start = time.time()
259
+ try:
260
+ yield
261
+ finally:
262
+ elapsed = time.time() - start
263
+ logger.info(f"{name} took {elapsed:.2f} seconds")
264
+
265
+ @contextmanager
266
+ def temporary_directory() -> Generator[Path, None, None]:
267
+ """Context manager for temporary directory.
268
+
269
+ Yields:
270
+ Path to temporary directory
271
+
272
+ Example:
273
+ with temporary_directory() as tmpdir:
274
+ (tmpdir / "file.txt").write_text("data")
275
+ # Directory is automatically deleted here
276
+ """
277
+ import tempfile
278
+ import shutil
279
+
280
+ tmpdir = Path(tempfile.mkdtemp())
281
+ try:
282
+ yield tmpdir
283
+ finally:
284
+ shutil.rmtree(tmpdir, ignore_errors=True)
285
+ ```
286
+
287
+ ### contextlib Utilities
288
+
289
+ ```python
290
+ from contextlib import (
291
+ contextmanager,
292
+ suppress,
293
+ redirect_stdout,
294
+ redirect_stderr,
295
+ ExitStack,
296
+ nullcontext,
297
+ )
298
+ import io
299
+
300
+ # suppress - Ignore specific exceptions
301
+ from contextlib import suppress
302
+
303
+ # Instead of try-except
304
+ try:
305
+ os.remove(file_path)
306
+ except FileNotFoundError:
307
+ pass
308
+
309
+ # Use suppress
310
+ with suppress(FileNotFoundError):
311
+ os.remove(file_path)
312
+
313
+ # Suppress multiple exceptions
314
+ with suppress(FileNotFoundError, PermissionError):
315
+ os.remove(file_path)
316
+
317
+ # redirect_stdout/redirect_stderr - Redirect output
318
+ output = io.StringIO()
319
+ with redirect_stdout(output):
320
+ print("This goes to output variable")
321
+ print("Not to console")
322
+
323
+ captured = output.getvalue() # "This goes to output variable\nNot to console\n"
324
+
325
+ # ExitStack - Manage dynamic number of context managers
326
+ from contextlib import ExitStack
327
+
328
+ def process_files(file_paths: list[str]) -> None:
329
+ """Process multiple files with dynamic context managers."""
330
+ with ExitStack() as stack:
331
+ # Open all files and register them with the stack
332
+ files = [stack.enter_context(open(path)) for path in file_paths]
333
+
334
+ # Process all files
335
+ for f in files:
336
+ process_file(f)
337
+
338
+ # All files automatically closed when exiting
339
+
340
+ # ExitStack with callbacks
341
+ with ExitStack() as stack:
342
+ # Register cleanup callbacks
343
+ stack.callback(cleanup_temp_files)
344
+ stack.callback(logger.info, "Processing complete")
345
+
346
+ # Do work
347
+ process_data()
348
+
349
+ # Callbacks run in LIFO order when exiting
350
+
351
+ # nullcontext - Conditional context manager (Python 3.7+)
352
+ from contextlib import nullcontext
353
+
354
+ def process_data(use_lock: bool = False) -> None:
355
+ """Process data with optional locking."""
356
+ lock = threading.Lock() if use_lock else nullcontext()
357
+
358
+ with lock:
359
+ # This works whether lock is a real Lock or nullcontext
360
+ modify_shared_resource()
361
+ ```
362
+
363
+ ### Async Context Managers
364
+
365
+ ```python
366
+ from contextlib import asynccontextmanager
367
+ from typing import AsyncGenerator
368
+
369
+ class AsyncDatabaseConnection:
370
+ """Async context manager for database connections."""
371
+
372
+ async def __aenter__(self) -> AsyncConnection:
373
+ self.conn = await async_connect(self.db_url)
374
+ return self.conn
375
+
376
+ async def __aexit__(self, exc_type, exc_val, exc_tb) -> bool:
377
+ await self.conn.close()
378
+ return False
379
+
380
+ # Using @asynccontextmanager decorator
381
+ @asynccontextmanager
382
+ async def async_database_connection(
383
+ db_url: str
384
+ ) -> AsyncGenerator[AsyncConnection, None]:
385
+ """Async context manager for database connections."""
386
+ conn = await async_connect(db_url)
387
+ try:
388
+ yield conn
389
+ finally:
390
+ await conn.close()
95
391
 
96
392
  # Usage
97
- with database_connection("postgresql://...") as conn:
98
- conn.execute("SELECT * FROM users")
393
+ async def fetch_users():
394
+ async with async_database_connection("postgresql://...") as conn:
395
+ return await conn.fetch("SELECT * FROM users")
99
396
  ```
100
397
 
101
398
  ## Custom Exceptions
102
399
 
400
+ Create custom exceptions for domain-specific errors. This makes error handling more precise and code more maintainable.
401
+
402
+ ### Basic Custom Exceptions
403
+
103
404
  ```python
104
- # Define custom exceptions
405
+ # Simple custom exception
105
406
  class ValidationError(Exception):
106
- """Raised when validation fails"""
407
+ """Raised when validation fails."""
107
408
  pass
108
409
 
410
+ # Custom exception with additional attributes
109
411
  class AuthenticationError(Exception):
110
- """Raised when authentication fails"""
412
+ """Raised when authentication fails."""
413
+
111
414
  def __init__(self, user_id: int, message: str = "Authentication failed"):
112
415
  self.user_id = user_id
113
416
  self.message = message
114
417
  super().__init__(self.message)
115
418
 
419
+ def __str__(self) -> str:
420
+ return f"AuthenticationError(user_id={self.user_id}): {self.message}"
421
+
422
+ # Custom exception with multiple attributes
423
+ class DatabaseError(Exception):
424
+ """Raised when database operation fails."""
425
+
426
+ def __init__(
427
+ self,
428
+ message: str,
429
+ query: str,
430
+ error_code: Optional[int] = None,
431
+ ):
432
+ self.message = message
433
+ self.query = query
434
+ self.error_code = error_code
435
+ super().__init__(self.message)
436
+
116
437
  # Usage
117
438
  def validate_email(email: str) -> None:
439
+ """Validate email format.
440
+
441
+ Args:
442
+ email: Email address to validate
443
+
444
+ Raises:
445
+ ValidationError: If email format is invalid
446
+ """
118
447
  if '@' not in email:
119
- raise ValidationError(f"Invalid email: {email}")
448
+ raise ValidationError(f"Invalid email format: {email}")
449
+
450
+ if not email.endswith(('.com', '.org', '.net')):
451
+ raise ValidationError(f"Invalid email domain: {email}")
120
452
 
121
453
  def authenticate_user(user_id: int, password: str) -> User:
454
+ """Authenticate user with password.
455
+
456
+ Args:
457
+ user_id: User ID
458
+ password: User password
459
+
460
+ Returns:
461
+ Authenticated user object
462
+
463
+ Raises:
464
+ AuthenticationError: If authentication fails
465
+ """
122
466
  if not verify_password(user_id, password):
123
- raise AuthenticationError(user_id)
467
+ raise AuthenticationError(user_id, "Invalid password")
124
468
  return get_user(user_id)
125
469
  ```
126
470
 
471
+ ### Exception Hierarchies
472
+
473
+ Create exception hierarchies for related errors.
474
+
475
+ ```python
476
+ # Base exception for application
477
+ class AppError(Exception):
478
+ """Base exception for all application errors."""
479
+ pass
480
+
481
+ # Database errors
482
+ class DatabaseError(AppError):
483
+ """Base exception for database-related errors."""
484
+ pass
485
+
486
+ class ConnectionError(DatabaseError):
487
+ """Database connection errors."""
488
+ pass
489
+
490
+ class QueryError(DatabaseError):
491
+ """Database query errors."""
492
+
493
+ def __init__(self, message: str, query: str):
494
+ self.query = query
495
+ super().__init__(f"{message}: {query}")
496
+
497
+ class TransactionError(DatabaseError):
498
+ """Database transaction errors."""
499
+ pass
500
+
501
+ # API errors
502
+ class APIError(AppError):
503
+ """Base exception for API-related errors."""
504
+
505
+ def __init__(self, message: str, status_code: int):
506
+ self.status_code = status_code
507
+ super().__init__(f"[{status_code}] {message}")
508
+
509
+ class NotFoundError(APIError):
510
+ """Resource not found."""
511
+
512
+ def __init__(self, resource: str, resource_id: str):
513
+ self.resource = resource
514
+ self.resource_id = resource_id
515
+ super().__init__(
516
+ f"{resource} not found: {resource_id}",
517
+ status_code=404,
518
+ )
519
+
520
+ class UnauthorizedError(APIError):
521
+ """Unauthorized access."""
522
+
523
+ def __init__(self, message: str = "Unauthorized"):
524
+ super().__init__(message, status_code=401)
525
+
526
+ # Usage - Catch specific or broad exceptions
527
+ try:
528
+ user = get_user(user_id)
529
+ except NotFoundError as e:
530
+ # Handle specific error
531
+ logger.warning(f"User not found: {e.resource_id}")
532
+ except APIError as e:
533
+ # Handle any API error
534
+ logger.error(f"API error: {e}")
535
+ except AppError as e:
536
+ # Handle any application error
537
+ logger.error(f"Application error: {e}")
538
+ ```
539
+
540
+ ### Rich Exception Information
541
+
542
+ ```python
543
+ from typing import Any, Optional
544
+ from dataclasses import dataclass
545
+
546
+ @dataclass
547
+ class ErrorContext:
548
+ """Context information for errors."""
549
+ operation: str
550
+ user_id: Optional[int] = None
551
+ request_id: Optional[str] = None
552
+ metadata: dict[str, Any] = None
553
+
554
+ def __post_init__(self):
555
+ if self.metadata is None:
556
+ self.metadata = {}
557
+
558
+ class OperationError(Exception):
559
+ """Exception with rich context information."""
560
+
561
+ def __init__(self, message: str, context: ErrorContext):
562
+ self.message = message
563
+ self.context = context
564
+ super().__init__(self.message)
565
+
566
+ def __str__(self) -> str:
567
+ ctx = self.context
568
+ parts = [f"OperationError: {self.message}"]
569
+ parts.append(f" Operation: {ctx.operation}")
570
+ if ctx.user_id:
571
+ parts.append(f" User ID: {ctx.user_id}")
572
+ if ctx.request_id:
573
+ parts.append(f" Request ID: {ctx.request_id}")
574
+ if ctx.metadata:
575
+ parts.append(f" Metadata: {ctx.metadata}")
576
+ return "\n".join(parts)
577
+
578
+ # Usage
579
+ def process_payment(user_id: int, amount: float, request_id: str) -> None:
580
+ """Process payment with rich error context."""
581
+ context = ErrorContext(
582
+ operation="process_payment",
583
+ user_id=user_id,
584
+ request_id=request_id,
585
+ metadata={"amount": amount},
586
+ )
587
+
588
+ try:
589
+ charge_card(user_id, amount)
590
+ except CardDeclinedError as e:
591
+ raise OperationError("Payment declined", context) from e
592
+ except InsufficientFundsError as e:
593
+ raise OperationError("Insufficient funds", context) from e
594
+ ```
595
+
127
596
  ## Exception Chaining
128
597
 
598
+ Exception chaining preserves the original exception context, making debugging easier.
599
+
600
+ ### Using 'from' for Chaining
601
+
129
602
  ```python
130
- # Preserve original exception
603
+ # Good - Preserve original exception with 'from'
131
604
  try:
132
605
  result = process_data(data)
133
606
  except ValueError as e:
134
607
  raise ProcessingError("Failed to process data") from e
608
+ # Traceback will show both ProcessingError and original ValueError
135
609
 
136
- # Suppress original exception (rare)
610
+ # Good - Explicit chaining with context
611
+ try:
612
+ user_data = json.loads(raw_data)
613
+ except json.JSONDecodeError as e:
614
+ raise ValidationError(
615
+ f"Invalid JSON in user data: {e.msg}"
616
+ ) from e
617
+
618
+ # Rare - Suppress original exception with 'from None'
137
619
  try:
138
620
  result = process_data(data)
139
621
  except ValueError:
622
+ # Only use 'from None' when original exception is not relevant
140
623
  raise ProcessingError("Failed to process data") from None
141
624
  ```
142
625
 
626
+ ### Implicit Chaining
627
+
628
+ ```python
629
+ # Implicit chaining - exception raised during exception handling
630
+ try:
631
+ result = process_data(data)
632
+ except ValueError as e:
633
+ # If log_error raises an exception, both will be in traceback
634
+ log_error(e)
635
+ raise ProcessingError("Failed to process data")
636
+ ```
637
+
638
+ ### Accessing Exception Chain
639
+
640
+ ```python
641
+ try:
642
+ try:
643
+ risky_operation()
644
+ except ValueError as e:
645
+ raise ProcessingError("Processing failed") from e
646
+ except ProcessingError as e:
647
+ # Access the original exception
648
+ original = e.__cause__ # The exception after 'from'
649
+ context = e.__context__ # The exception being handled when this was raised
650
+
651
+ logger.error(f"Processing error: {e}")
652
+ logger.error(f"Original error: {original}")
653
+ ```
654
+
143
655
  ## Logging Exceptions
144
656
 
657
+ Proper exception logging is crucial for debugging and monitoring.
658
+
659
+ ### Basic Exception Logging
660
+
145
661
  ```python
146
662
  import logging
147
663
 
148
664
  logger = logging.getLogger(__name__)
149
665
 
150
- # Log exception with traceback
666
+ # Log exception with full traceback
151
667
  try:
152
668
  result = risky_operation()
153
669
  except Exception as e:
154
- logger.exception("Operation failed") # Includes traceback
155
- raise
670
+ logger.exception("Operation failed") # Includes full traceback
671
+ raise # Re-raise after logging
156
672
 
157
673
  # Log without traceback
158
674
  try:
159
675
  result = risky_operation()
160
676
  except ValueError as e:
161
- logger.error(f"Invalid value: {e}")
677
+ logger.error(f"Invalid value: {e}") # No traceback
678
+ result = default_value
679
+
680
+ # Log with different levels
681
+ try:
682
+ result = optional_operation()
683
+ except FileNotFoundError:
684
+ logger.warning("Optional file not found, using defaults")
162
685
  result = default_value
686
+ except PermissionError as e:
687
+ logger.error(f"Permission denied: {e}")
688
+ raise
689
+ ```
690
+
691
+ ### Structured Logging
692
+
693
+ ```python
694
+ import logging
695
+ from typing import Any
696
+
697
+ logger = logging.getLogger(__name__)
698
+
699
+ # Log with structured data
700
+ try:
701
+ process_user_data(user_id, data)
702
+ except ValidationError as e:
703
+ logger.error(
704
+ "Validation failed",
705
+ extra={
706
+ "user_id": user_id,
707
+ "error_type": type(e).__name__,
708
+ "error_message": str(e),
709
+ },
710
+ )
711
+ raise
712
+
713
+ # Log with exception info without traceback
714
+ try:
715
+ result = risky_operation()
716
+ except ValueError as e:
717
+ logger.error(
718
+ "Operation failed: %s",
719
+ e,
720
+ exc_info=False, # Don't include traceback
721
+ )
722
+ ```
723
+
724
+ ### Custom Exception Logging
725
+
726
+ ```python
727
+ class LoggingException(Exception):
728
+ """Exception that logs itself when raised."""
729
+
730
+ def __init__(self, message: str, level: int = logging.ERROR):
731
+ self.message = message
732
+ self.level = level
733
+ super().__init__(self.message)
734
+
735
+ # Log when exception is created
736
+ logger = logging.getLogger(self.__class__.__module__)
737
+ logger.log(self.level, f"{self.__class__.__name__}: {message}")
738
+
739
+ # Usage
740
+ def process_data(data: dict[str, Any]) -> None:
741
+ if not data:
742
+ raise LoggingException("Empty data received", level=logging.WARNING)
163
743
  ```
164
744
 
165
745
  ## Best Practices
166
746
 
167
- 1. **Catch specific exceptions** - Never use bare `except:`
168
- 2. **Use context managers** - Prefer `with` for resource management
169
- 3. **Don't silence exceptions** - Log or handle them properly
170
- 4. **Create custom exceptions** - For domain-specific errors
171
- 5. **Use exception chaining** - Preserve error context with `from`
172
- 6. **Clean up resources** - Use `finally` or context managers
173
- 7. **Fail fast** - Don't catch exceptions you can't handle
174
- 8. **Document exceptions** - Use docstrings to document raised exceptions
747
+ ### DO
748
+
749
+ **Catch specific exceptions** - Never use bare `except:` or catch `Exception` unless absolutely necessary
750
+
751
+ **Use context managers** - Prefer `with` statement for resource management
752
+
753
+ **Log exceptions properly** - Use `logger.exception()` to include tracebacks
754
+
755
+ ✅ **Create custom exceptions** - For domain-specific errors with clear names
756
+
757
+ ✅ **Use exception chaining** - Preserve error context with `from`
758
+
759
+ ✅ **Document exceptions** - List raised exceptions in docstrings
760
+
761
+ ✅ **Fail fast** - Don't catch exceptions you can't handle
762
+
763
+ ✅ **Clean up resources** - Use `finally` or context managers
764
+
765
+ ✅ **Use contextlib utilities** - `suppress`, `ExitStack`, etc. for cleaner code
175
766
 
176
- ## Anti-Patterns to Avoid
767
+ **Create exception hierarchies** - For related errors
768
+
769
+ ### DON'T
770
+
771
+ ❌ **Don't use bare except** - Catches SystemExit, KeyboardInterrupt, etc.
177
772
 
178
773
  ```python
179
- # DON'T: Bare except
774
+ # Bad
180
775
  try:
181
776
  do_something()
182
- except:
777
+ except: # Catches everything, including KeyboardInterrupt
183
778
  pass
184
779
 
185
- # DON'T: Catch Exception without re-raising
780
+ # Good
781
+ try:
782
+ do_something()
783
+ except (ValueError, TypeError) as e:
784
+ logger.error(f"Expected error: {e}")
785
+ ```
786
+
787
+ ❌ **Don't silence exceptions** - Always log or handle them
788
+
789
+ ```python
790
+ # Bad
186
791
  try:
187
792
  critical_operation()
188
793
  except Exception:
189
- print("Error occurred")
794
+ pass # Silent failure
190
795
 
191
- # DON'T: Use exceptions for flow control
796
+ # Good
797
+ try:
798
+ critical_operation()
799
+ except Exception as e:
800
+ logger.exception("Critical operation failed")
801
+ raise
802
+ ```
803
+
804
+ ❌ **Don't use exceptions for flow control** - Use appropriate methods
805
+
806
+ ```python
807
+ # Bad - Using exception for flow control
192
808
  try:
193
809
  value = my_dict[key]
194
810
  except KeyError:
195
811
  value = default
196
812
 
197
- # DO: Use get() instead
813
+ # Good - Use dict.get()
198
814
  value = my_dict.get(key, default)
815
+
816
+ # Bad - Using exception for flow control
817
+ try:
818
+ index = my_list.index(item)
819
+ except ValueError:
820
+ index = -1
821
+
822
+ # Good - Use 'in' operator
823
+ index = my_list.index(item) if item in my_list else -1
199
824
  ```
200
825
 
201
- ## Exception Hierarchy
826
+ **Don't catch Exception without re-raising** - Unless you can truly handle it
202
827
 
203
828
  ```python
204
- # Create exception hierarchy
205
- class AppError(Exception):
206
- """Base exception for application"""
207
- pass
829
+ # Bad
830
+ try:
831
+ critical_operation()
832
+ except Exception:
833
+ print("Error occurred") # Swallows the exception
208
834
 
209
- class DatabaseError(AppError):
210
- """Database-related errors"""
211
- pass
835
+ # Good
836
+ try:
837
+ critical_operation()
838
+ except Exception as e:
839
+ logger.exception("Critical operation failed")
840
+ raise # Re-raise after logging
841
+ ```
212
842
 
213
- class ConnectionError(DatabaseError):
214
- """Database connection errors"""
215
- pass
843
+ **Don't lose exception context** - Use exception chaining
216
844
 
217
- class QueryError(DatabaseError):
218
- """Database query errors"""
219
- pass
845
+ ```python
846
+ # Bad - Loses original exception
847
+ try:
848
+ process_data(data)
849
+ except ValueError:
850
+ raise ProcessingError("Failed") # Original error is lost
851
+
852
+ # Good - Preserves original exception
853
+ try:
854
+ process_data(data)
855
+ except ValueError as e:
856
+ raise ProcessingError("Failed") from e
220
857
  ```
221
858
 
859
+ ## Advanced Patterns
860
+
861
+ ### Exception Groups (Python 3.11+)
862
+
863
+ ```python
864
+ # Raise multiple exceptions at once
865
+ raise ExceptionGroup("Multiple errors occurred", [
866
+ ValueError("Invalid value"),
867
+ TypeError("Invalid type"),
868
+ ])
869
+
870
+ # Catch exception groups
871
+ try:
872
+ raise ExceptionGroup("errors", [ValueError("bad"), TypeError("wrong")])
873
+ except* ValueError as eg:
874
+ # Handle all ValueError instances
875
+ for e in eg.exceptions:
876
+ logger.error(f"Value error: {e}")
877
+ except* TypeError as eg:
878
+ # Handle all TypeError instances
879
+ for e in eg.exceptions:
880
+ logger.error(f"Type error: {e}")
881
+ ```
882
+
883
+ ### Retry Logic with Exceptions
884
+
885
+ ```python
886
+ from typing import TypeVar, Callable
887
+ import time
888
+
889
+ T = TypeVar('T')
890
+
891
+ def retry(
892
+ func: Callable[..., T],
893
+ max_attempts: int = 3,
894
+ delay: float = 1.0,
895
+ exceptions: tuple[type[Exception], ...] = (Exception,),
896
+ ) -> T:
897
+ """Retry function on exception.
898
+
899
+ Args:
900
+ func: Function to retry
901
+ max_attempts: Maximum number of attempts
902
+ delay: Delay between attempts in seconds
903
+ exceptions: Tuple of exceptions to catch
904
+
905
+ Returns:
906
+ Result of successful function call
907
+
908
+ Raises:
909
+ Last exception if all attempts fail
910
+ """
911
+ last_exception = None
912
+
913
+ for attempt in range(max_attempts):
914
+ try:
915
+ return func()
916
+ except exceptions as e:
917
+ last_exception = e
918
+ logger.warning(
919
+ f"Attempt {attempt + 1}/{max_attempts} failed: {e}"
920
+ )
921
+ if attempt < max_attempts - 1:
922
+ time.sleep(delay)
923
+
924
+ # All attempts failed
925
+ raise last_exception
926
+
927
+ # Usage
928
+ result = retry(
929
+ lambda: fetch_data_from_api(),
930
+ max_attempts=3,
931
+ delay=2.0,
932
+ exceptions=(ConnectionError, TimeoutError),
933
+ )
934
+ ```
935
+
936
+ ### Validation with Multiple Errors
937
+
938
+ ```python
939
+ from typing import List
940
+
941
+ class ValidationErrors(Exception):
942
+ """Exception containing multiple validation errors."""
943
+
944
+ def __init__(self, errors: List[str]):
945
+ self.errors = errors
946
+ super().__init__(f"{len(errors)} validation errors")
947
+
948
+ def __str__(self) -> str:
949
+ return "\n".join([
950
+ f"Validation failed with {len(self.errors)} errors:",
951
+ *[f" - {error}" for error in self.errors],
952
+ ])
953
+
954
+ def validate_user(user_data: dict) -> None:
955
+ """Validate user data, collecting all errors.
956
+
957
+ Args:
958
+ user_data: User data to validate
959
+
960
+ Raises:
961
+ ValidationErrors: If validation fails
962
+ """
963
+ errors = []
964
+
965
+ if not user_data.get("email"):
966
+ errors.append("Email is required")
967
+ elif "@" not in user_data["email"]:
968
+ errors.append("Email must contain @")
969
+
970
+ if not user_data.get("username"):
971
+ errors.append("Username is required")
972
+ elif len(user_data["username"]) < 3:
973
+ errors.append("Username must be at least 3 characters")
974
+
975
+ if not user_data.get("age"):
976
+ errors.append("Age is required")
977
+ elif user_data["age"] < 18:
978
+ errors.append("User must be at least 18 years old")
979
+
980
+ if errors:
981
+ raise ValidationErrors(errors)
982
+
983
+ # Usage
984
+ try:
985
+ validate_user({"email": "invalid", "username": "ab"})
986
+ except ValidationErrors as e:
987
+ logger.error(str(e))
988
+ # Validation failed with 3 errors:
989
+ # - Email must contain @
990
+ # - Username must be at least 3 characters
991
+ # - Age is required
992
+ ```
993
+
994
+ ## Summary
995
+
996
+ **Key Takeaways:**
997
+
998
+ 1. **Always catch specific exceptions** - Never use bare `except:`
999
+ 2. **Use context managers** - For automatic resource cleanup
1000
+ 3. **Create custom exceptions** - With clear hierarchies for domain errors
1001
+ 4. **Use contextlib utilities** - `@contextmanager`, `suppress`, `ExitStack`
1002
+ 5. **Chain exceptions** - Preserve error context with `from`
1003
+ 6. **Log exceptions properly** - Use `logger.exception()` for tracebacks
1004
+ 7. **Document exceptions** - In docstrings with `Raises:` section
1005
+ 8. **Don't use exceptions for flow control** - Use appropriate methods instead
1006
+ 9. **Fail fast** - Don't catch exceptions you can't handle
1007
+ 10. **Clean up resources** - Use `finally` or context managers
1008
+