framework-m-studio 0.5.2__tar.gz → 0.7.0__tar.gz

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 (169) hide show
  1. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/.gitignore +7 -1
  2. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/CHANGELOG.md +28 -0
  3. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/PKG-INFO +17 -3
  4. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/pyproject.toml +24 -19
  5. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/app.py +11 -11
  6. framework_m_studio-0.7.0/src/framework_m_studio/cli/__init__.py +127 -0
  7. framework_m_studio-0.7.0/src/framework_m_studio/cli/codegen.py +107 -0
  8. framework_m_studio-0.7.0/src/framework_m_studio/cli/contrib.py +73 -0
  9. framework_m_studio-0.7.0/src/framework_m_studio/cli/deps.py +175 -0
  10. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/cli/dev.py +15 -15
  11. framework_m_studio-0.7.0/src/framework_m_studio/cli/docs.py +939 -0
  12. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/cli/new.py +113 -4
  13. framework_m_studio-0.7.0/src/framework_m_studio/cli/quality.py +207 -0
  14. framework_m_studio-0.7.0/src/framework_m_studio/cli/release.py +773 -0
  15. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/cli/studio.py +16 -4
  16. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/cli/utility.py +61 -4
  17. framework_m_studio-0.7.0/src/framework_m_studio/cli/verify.py +45 -0
  18. framework_m_studio-0.7.0/src/framework_m_studio/core/frontend.py +188 -0
  19. framework_m_studio-0.7.0/src/framework_m_studio/core/gitops.py +123 -0
  20. framework_m_studio-0.7.0/src/framework_m_studio/core/shell.py +70 -0
  21. framework_m_studio-0.7.0/src/framework_m_studio/docs/ast_parsers.py +164 -0
  22. framework_m_studio-0.7.0/src/framework_m_studio/docs/audit.py +105 -0
  23. framework_m_studio-0.7.0/src/framework_m_studio/docs/exporters.py +146 -0
  24. framework_m_studio-0.7.0/src/framework_m_studio/docs/formatters.py +291 -0
  25. framework_m_studio-0.7.0/src/framework_m_studio/docs/generator.py +312 -0
  26. framework_m_studio-0.7.0/src/framework_m_studio/docs/openapi.py +134 -0
  27. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/git/github_provider.py +1 -1
  28. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/sdk_generator.py +1 -1
  29. framework_m_studio-0.7.0/src/framework_m_studio/static/assets/index-BT9-FyVu.css +1 -0
  30. framework_m_studio-0.7.0/src/framework_m_studio/static/assets/index-D11hOvMw.js +182 -0
  31. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/static/index.html +2 -2
  32. framework_m_studio-0.7.0/src/framework_m_studio/templates/plugin/package.json.template +33 -0
  33. framework_m_studio-0.7.0/src/framework_m_studio/templates/plugin/vite.config.mfe.ts.template +12 -0
  34. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/package.json +31 -30
  35. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/src/components/SandboxPreview.tsx +111 -12
  36. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/src/pages/doctypes/edit.tsx +1 -1
  37. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/src/pages/doctypes/list.tsx +1 -1
  38. framework_m_studio-0.7.0/studio_ui/src/services/mock_data.ts +128 -0
  39. framework_m_studio-0.5.2/tests/cli/test_init.py → framework_m_studio-0.7.0/tests/cli/test_new.py +61 -24
  40. framework_m_studio-0.7.0/tests/cli/test_verify.py +55 -0
  41. framework_m_studio-0.7.0/tests/core/test_frontend.py +85 -0
  42. framework_m_studio-0.7.0/tests/core/test_gitops.py +117 -0
  43. framework_m_studio-0.7.0/tests/core/test_shell.py +65 -0
  44. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/tests/test_api_routes.py +173 -0
  45. framework_m_studio-0.7.0/tests/test_cli.py +486 -0
  46. framework_m_studio-0.7.0/tests/test_cli_openapi.py +87 -0
  47. framework_m_studio-0.7.0/tests/test_contrib_cli.py +56 -0
  48. framework_m_studio-0.7.0/tests/test_deps_cli.py +263 -0
  49. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/tests/test_dev.py +7 -7
  50. framework_m_studio-0.7.0/tests/test_dev_cli_coverage.py +182 -0
  51. framework_m_studio-0.7.0/tests/test_docs_audit.py +98 -0
  52. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/tests/test_docs_generator.py +101 -60
  53. framework_m_studio-0.7.0/tests/test_docs_generator_enhanced.py +116 -0
  54. framework_m_studio-0.7.0/tests/test_frontend_integration.py +142 -0
  55. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/tests/test_protocol_scanner.py +32 -11
  56. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/tests/test_quality_cli.py +101 -130
  57. framework_m_studio-0.7.0/tests/test_release_cli.py +764 -0
  58. framework_m_studio-0.7.0/tests/test_screenshot_pipeline.py +92 -0
  59. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/tests/test_studio.py +27 -13
  60. framework_m_studio-0.7.0/tests/test_studio_codegen_generator.py +111 -0
  61. framework_m_studio-0.7.0/tests/test_utility_cli_enhanced.py +129 -0
  62. framework_m_studio-0.5.2/src/framework_m_studio/checklist_parser.py +0 -421
  63. framework_m_studio-0.5.2/src/framework_m_studio/cli/__init__.py +0 -761
  64. framework_m_studio-0.5.2/src/framework_m_studio/cli/build.py +0 -674
  65. framework_m_studio-0.5.2/src/framework_m_studio/cli/init.py +0 -137
  66. framework_m_studio-0.5.2/src/framework_m_studio/cli/quality.py +0 -157
  67. framework_m_studio-0.5.2/src/framework_m_studio/docs_generator.py +0 -645
  68. framework_m_studio-0.5.2/src/framework_m_studio/static/assets/index-CLjnj-4K.css +0 -1
  69. framework_m_studio-0.5.2/src/framework_m_studio/static/assets/index-Cmo7Rekg.js +0 -171
  70. framework_m_studio-0.5.2/src/framework_m_studio/templates/plugin/package.json.template +0 -17
  71. framework_m_studio-0.5.2/tests/__init__.py +0 -1
  72. framework_m_studio-0.5.2/tests/test_build.py +0 -972
  73. framework_m_studio-0.5.2/tests/test_build_extended.py +0 -591
  74. framework_m_studio-0.5.2/tests/test_cli.py +0 -159
  75. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/README.md +0 -0
  76. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/docs/api/index.md +0 -0
  77. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/docs/user-guide.md +0 -0
  78. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/__init__.py +0 -0
  79. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/codegen/__init__.py +0 -0
  80. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/codegen/generator.py +0 -0
  81. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/codegen/parser.py +0 -0
  82. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/codegen/templates/doctype.py.jinja2 +0 -0
  83. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/codegen/templates/test_doctype.py.jinja2 +0 -0
  84. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/codegen/test_generator.py +0 -0
  85. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/codegen/transformer.py +0 -0
  86. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/discovery.py +0 -0
  87. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/git/__init__.py +0 -0
  88. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/git/adapter.py +0 -0
  89. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/git/protocol.py +0 -0
  90. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/protocol_scanner.py +0 -0
  91. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/py.typed +0 -0
  92. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/routes.py +0 -0
  93. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/static/.gitkeep +0 -0
  94. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/static/favicon.ico +0 -0
  95. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/templates/frontend/.gitignore +0 -0
  96. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/templates/frontend/.npmrc +0 -0
  97. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/templates/frontend/README.md +0 -0
  98. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/templates/frontend/index.html +0 -0
  99. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/templates/frontend/package.json +0 -0
  100. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/templates/frontend/src/App.tsx +0 -0
  101. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/templates/frontend/src/components/AppNavbar.tsx +0 -0
  102. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/templates/frontend/src/components/AppSidebar.tsx +0 -0
  103. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/templates/frontend/src/index.tsx +0 -0
  104. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/templates/frontend/src/pages/LoginPage.tsx +0 -0
  105. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/templates/frontend/src/theme.css +0 -0
  106. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/templates/frontend/tsconfig.json +0 -0
  107. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/templates/frontend/vite.config.ts +0 -0
  108. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/templates/plugin/Dashboard.tsx.template +0 -0
  109. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/templates/plugin/README.md.template +0 -0
  110. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/templates/plugin/plugin.config.ts.template +0 -0
  111. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/templates/plugin/tsconfig.json.template +0 -0
  112. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/src/framework_m_studio/workspace.py +0 -0
  113. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/.gitignore +0 -0
  114. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/.npmrc +0 -0
  115. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/Dockerfile +0 -0
  116. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/README.MD +0 -0
  117. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/eslint.config.js +0 -0
  118. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/index.html +0 -0
  119. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/pnpm-lock.yaml +0 -0
  120. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/src/App.css +0 -0
  121. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/src/App.test.tsx +0 -0
  122. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/src/App.tsx +0 -0
  123. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/src/components/AutoForm.tsx +0 -0
  124. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/src/components/AutoTable.tsx +0 -0
  125. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/src/components/CodePreview.tsx +0 -0
  126. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/src/components/ControllerEditor.tsx +0 -0
  127. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/src/components/ERDView.tsx +0 -0
  128. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/src/components/FieldEditor.tsx +0 -0
  129. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/src/components/LayoutDesigner.tsx +0 -0
  130. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/src/components/ModuleExplorer.tsx +0 -0
  131. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/src/components/NestedEditorDrawer.tsx +0 -0
  132. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/src/components/TableFieldEditor.tsx +0 -0
  133. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/src/components/breadcrumb/index.tsx +0 -0
  134. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/src/components/fields/DefaultFieldComponents.tsx +0 -0
  135. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/src/components/fields/index.ts +0 -0
  136. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/src/components/fields/resolveFieldComponent.ts +0 -0
  137. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/src/components/layout/index.tsx +0 -0
  138. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/src/components/menu/index.tsx +0 -0
  139. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/src/index.css +0 -0
  140. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/src/index.tsx +0 -0
  141. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/src/pages/doctypes/index.ts +0 -0
  142. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/src/pages/index.ts +0 -0
  143. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/src/providers/ThemeContext.ts +0 -0
  144. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/src/providers/constants.ts +0 -0
  145. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/src/providers/data.ts +0 -0
  146. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/src/providers/theme.tsx +0 -0
  147. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/src/providers/useTheme.ts +0 -0
  148. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/src/registry/defaultComponents.ts +0 -0
  149. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/src/registry/fieldComponents.ts +0 -0
  150. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/src/registry/index.ts +0 -0
  151. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/src/setupTests.ts +0 -0
  152. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/src/utils/mockDataGenerator.ts +0 -0
  153. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/src/vite-env.d.ts +0 -0
  154. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/tsconfig.json +0 -0
  155. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/tsconfig.node.json +0 -0
  156. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/vite.config.ts +0 -0
  157. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/studio_ui/vitest.config.ts +0 -0
  158. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/tests/conftest.py +0 -0
  159. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/tests/test_discovery.py +0 -0
  160. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/tests/test_generator.py +0 -0
  161. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/tests/test_git_adapter.py +0 -0
  162. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/tests/test_git_protocol.py +0 -0
  163. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/tests/test_github_provider.py +0 -0
  164. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/tests/test_new_cli.py +0 -0
  165. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/tests/test_parser.py +0 -0
  166. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/tests/test_sdk_generator.py +0 -0
  167. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/tests/test_transformer.py +0 -0
  168. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/tests/test_utility_cli.py +0 -0
  169. {framework_m_studio-0.5.2 → framework_m_studio-0.7.0}/tests/test_workspace.py +0 -0
@@ -113,8 +113,14 @@ yarn-error.log*
113
113
 
114
114
  # Generated Documentation
115
115
  docs/developer/generated/
116
- docs/developer/protocols/
116
+ docs/developer/generated-core/
117
+ docs/user/generated/
117
118
  docs/machine/
119
+ docs/adr/index.md
120
+ docs/adr/_sidebar.json
121
+ docs/rfcs/index.md
122
+ docs/rfcs/_sidebar.json
123
+ docs/rfcs/_category_.json
118
124
 
119
125
  # Website
120
126
  website/.docusaurus/
@@ -1,5 +1,33 @@
1
1
  # Changelog
2
2
 
3
+ ## framework-m-studio v0.7.0
4
+
5
+ ### Features
6
+
7
+ - split cli modules and add security command (44214a1)
8
+ - refactor documentation generation CLI and add integration tests (81055f2)
9
+ - implement screenshot pipeline and automated docs generation (4c7ae26)
10
+ - enhance CLI commands and documentation generators (759045b)
11
+
12
+ ### Bug Fixes
13
+
14
+ - env for deps test (2b99410)
15
+ - add ipython as dependency (e81a27c)
16
+ - improve default target handling in quality commands (7a921ff)
17
+ - studio polish and cli polish (b8f62ec)
18
+ - generate explicit heading IDs in feature summary (9115617)
19
+ - mock environment for consistent source link tests (2946ab6)
20
+ - resolve B310 security vulnerability in OpenAPI export (aaea4a8)
21
+
22
+
23
+ ## framework-m-studio v0.6.0
24
+
25
+ ### Features
26
+
27
+ - add entrypoints discovery command (b24dbf1)
28
+ - implement mfe verification cli (bcd87a2)
29
+
30
+
3
31
  ## framework-m-studio v0.5.2
4
32
 
5
33
  ### Bug Fixes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: framework-m-studio
3
- Version: 0.5.2
3
+ Version: 0.7.0
4
4
  Summary: Framework M Studio - Visual DocType Builder & Developer Tools
5
5
  Project-URL: Homepage, https://gitlab.com/castlecraft/framework-m
6
6
  Project-URL: Documentation, https://gitlab.com/castlecraft/framework-m#readme
@@ -17,11 +17,25 @@ Classifier: Programming Language :: Python :: 3.12
17
17
  Classifier: Programming Language :: Python :: 3.13
18
18
  Classifier: Typing :: Typed
19
19
  Requires-Python: >=3.12
20
- Requires-Dist: framework-m-core>=0.7.1
21
- Requires-Dist: framework-m>=0.5.2
20
+ Requires-Dist: bandit>=1.9.4
21
+ Requires-Dist: build>=1.0.0
22
+ Requires-Dist: framework-m-core>=0.9.0
23
+ Requires-Dist: framework-m>=0.6.0
22
24
  Requires-Dist: honcho>=1.1.0
25
+ Requires-Dist: httpx>=0.27.0
26
+ Requires-Dist: ipython>=9.11.0
23
27
  Requires-Dist: jinja2>=3.1.0
24
28
  Requires-Dist: libcst>=1.0.0
29
+ Requires-Dist: mypy>=1.8.0
30
+ Requires-Dist: playwright>=1.58.0
31
+ Requires-Dist: pydantic>=2.12.5
32
+ Requires-Dist: pytest-asyncio>=0.23.0
33
+ Requires-Dist: pytest-cov>=4.1.0
34
+ Requires-Dist: pytest>=8.0.0
35
+ Requires-Dist: python-semantic-release>=9.0.0
36
+ Requires-Dist: pyyaml>=6.0.3
37
+ Requires-Dist: ruff>=0.3.0
38
+ Requires-Dist: twine>=5.0.0
25
39
  Description-Content-Type: text/markdown
26
40
 
27
41
  # Framework M Studio
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "framework-m-studio"
3
- version = "0.5.2"
3
+ version = "0.7.0"
4
4
  description = "Framework M Studio - Visual DocType Builder & Developer Tools"
5
5
  readme = "README.md"
6
6
  license = { text = "Apache-2.0" }
@@ -21,31 +21,38 @@ classifiers = [
21
21
  ]
22
22
 
23
23
  dependencies = [
24
- "framework-m-core>=0.7.1",
25
- "framework-m>=0.5.2",
24
+ "framework-m-core>=0.9.0",
25
+ "framework-m>=0.6.0",
26
26
  # Code generation
27
27
  "libcst>=1.0.0",
28
28
  "jinja2>=3.1.0",
29
29
  # Process management for dev command
30
30
  "honcho>=1.1.0",
31
- ]
32
-
33
- [tool.uv.sources]
34
- framework-m-core = { workspace = true }
35
- framework-m = { workspace = true }
36
-
37
- [dependency-groups]
38
- dev = [
31
+ "playwright>=1.58.0",
32
+ "pyyaml>=6.0.3",
33
+ "ipython>=9.11.0",
34
+ # Developer Tooling (wrapped by Studio CLI)
39
35
  "pytest>=8.0.0",
40
36
  "pytest-asyncio>=0.23.0",
41
37
  "pytest-cov>=4.1.0",
42
38
  "mypy>=1.8.0",
43
39
  "ruff>=0.3.0",
40
+ "bandit>=1.9.4",
44
41
  "httpx>=0.27.0",
45
42
  # Release tools
46
43
  "python-semantic-release>=9.0.0",
47
44
  "build>=1.0.0",
48
45
  "twine>=5.0.0",
46
+ "pydantic>=2.12.5",
47
+ ]
48
+
49
+ [tool.uv.sources]
50
+ framework-m-core = { workspace = true }
51
+ framework-m = { workspace = true }
52
+
53
+ [dependency-groups]
54
+ dev = [
55
+ "types-pyyaml>=6.0.12.20250915",
49
56
  ]
50
57
 
51
58
  [project.entry-points."framework_m_core.cli_commands"]
@@ -53,21 +60,19 @@ dev = [
53
60
  codegen = "framework_m_studio.cli:codegen_app"
54
61
  studio = "framework_m_studio.cli:studio_app"
55
62
  docs = "framework_m_studio.cli:docs_app"
56
- "docs:generate" = "framework_m_studio.cli:docs_generate"
57
- "docs:export" = "framework_m_studio.cli:docs_export"
58
- "docs:adr" = "framework_m_studio.cli:docs_adr"
59
- "docs:rfc" = "framework_m_studio.cli:docs_rfc"
60
- new = "framework_m_studio.cli.new:new_app_command"
61
- "new:doctype" = "framework_m_studio.cli.new:new_doctype_command"
62
- "new:app" = "framework_m_studio.cli.new:new_app_command"
63
- "init:frontend" = "framework_m_studio.cli.init:init_frontend_command"
63
+ new = "framework_m_studio.cli.new:new_app"
64
64
  test = "framework_m_studio.cli.quality:test_command"
65
65
  lint = "framework_m_studio.cli.quality:lint_command"
66
66
  format = "framework_m_studio.cli.quality:format_command"
67
67
  typecheck = "framework_m_studio.cli.quality:typecheck_command"
68
+ security = "framework_m_studio.cli.quality:security_command"
68
69
  console = "framework_m_studio.cli.utility:console_command"
69
70
  routes = "framework_m_studio.cli.utility:routes_command"
71
+ entrypoints = "framework_m_studio.cli.utility:entrypoints_command"
70
72
  dev = "framework_m_studio.cli.dev:dev_command"
73
+ release = "framework_m_studio.cli.release:release_app"
74
+ deps = "framework_m_studio.cli.deps:deps_app"
75
+ contrib = "framework_m_studio.cli.contrib:contrib_app"
71
76
 
72
77
 
73
78
  [project.urls]
@@ -60,24 +60,24 @@ def _get_spa_response(path: str) -> Response[bytes | dict[str, str]]:
60
60
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
61
61
  <title>Framework M Studio - Build Required</title>
62
62
  <style>
63
- body {
63
+ body {
64
64
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
65
- max-width: 600px;
66
- margin: 100px auto;
65
+ max-width: 600px;
66
+ margin: 100px auto;
67
67
  padding: 20px;
68
68
  line-height: 1.6;
69
69
  }
70
70
  h1 { color: #333; }
71
- code {
72
- background: #f4f4f4;
73
- padding: 2px 6px;
71
+ code {
72
+ background: #f4f4f4;
73
+ padding: 2px 6px;
74
74
  border-radius: 3px;
75
75
  font-family: monospace;
76
76
  }
77
77
  .api-links { margin-top: 30px; }
78
- .api-links a {
79
- display: block;
80
- margin: 10px 0;
78
+ .api-links a {
79
+ display: block;
80
+ margin: 10px 0;
81
81
  color: #0066cc;
82
82
  text-decoration: none;
83
83
  }
@@ -89,7 +89,7 @@ def _get_spa_response(path: str) -> Response[bytes | dict[str, str]]:
89
89
  <p>The Studio UI assets have not been built yet.</p>
90
90
  <p>To build the UI, run:</p>
91
91
  <pre><code>cd apps/studio/studio_ui && pnpm install && pnpm build</code></pre>
92
-
92
+
93
93
  <div class="api-links">
94
94
  <h3>Available API Endpoints:</h3>
95
95
  <a href="/studio/api/health">Health Check</a>
@@ -104,7 +104,7 @@ def _get_spa_response(path: str) -> Response[bytes | dict[str, str]]:
104
104
  )
105
105
 
106
106
  # Check for actual file
107
- file_path = STATIC_DIR / path
107
+ file_path = STATIC_DIR / path.lstrip("/")
108
108
  if file_path.is_file():
109
109
  # Serve the actual file with proper content type detection
110
110
  content = file_path.read_bytes()
@@ -0,0 +1,127 @@
1
+ """Framework M Studio CLI Commands.
2
+
3
+ This module provides CLI commands that are registered via entry points
4
+ when framework-m-studio is installed. These extend the base `m` CLI
5
+ with developer tools.
6
+
7
+ Entry Point Registration (pyproject.toml):
8
+ [project.entry-points."framework_m.cli_commands"]
9
+ codegen = "framework_m_studio.cli:codegen_app"
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ from typing import Annotated
15
+
16
+ import cyclopts
17
+
18
+ # Import utility commands and alias them for top-level registration
19
+ from framework_m_studio.cli.codegen import codegen_app, codegen_client, codegen_doctype
20
+ from framework_m_studio.cli.docs import (
21
+ docs_app,
22
+ docs_audit,
23
+ docs_generate,
24
+ docs_openapi,
25
+ docs_screenshots,
26
+ )
27
+ from framework_m_studio.cli.utility import console_command as console
28
+ from framework_m_studio.cli.utility import routes_command as routes
29
+ from framework_m_studio.cli.verify import verify_mfe_command as verify_mfe
30
+
31
+ # =============================================================================
32
+ # Studio Sub-App (Main command to start Studio server)
33
+ # =============================================================================
34
+
35
+ studio_app = cyclopts.App(
36
+ name="studio",
37
+ help="Start Framework M Studio visual editor",
38
+ )
39
+
40
+
41
+ @studio_app.default
42
+ def studio_serve(
43
+ port: Annotated[
44
+ int,
45
+ cyclopts.Parameter(
46
+ name="--port",
47
+ help="Port to run Studio on",
48
+ ),
49
+ ] = 9000,
50
+ host: Annotated[
51
+ str,
52
+ cyclopts.Parameter(
53
+ name="--host",
54
+ help="Host to bind to",
55
+ ),
56
+ ] = "0.0.0.0", # nosec B104
57
+ reload: Annotated[
58
+ bool,
59
+ cyclopts.Parameter(
60
+ name="--reload",
61
+ help="Enable auto-reload for development",
62
+ ),
63
+ ] = False,
64
+ cloud: Annotated[
65
+ bool,
66
+ cyclopts.Parameter(
67
+ name="--cloud",
68
+ help="Enable cloud mode (Git-backed workspaces)",
69
+ ),
70
+ ] = False,
71
+ ) -> None:
72
+ """Start Framework M Studio.
73
+
74
+ Examples:
75
+ m studio # Start on port 9000
76
+ m studio --port 8000 # Custom port
77
+ m studio --reload # Development mode
78
+ m studio --cloud # Enable cloud mode
79
+ """
80
+ import os
81
+ import webbrowser
82
+ from contextlib import suppress
83
+
84
+ import uvicorn
85
+
86
+ # Print startup banner
87
+ display_host = "localhost" if host in {"0.0.0.0", "::"} else host # nosec B104
88
+ print()
89
+ print("🎨 Starting Framework M Studio")
90
+ print(f" ➜ Local: http://{display_host}:{port}/studio/")
91
+ print(f" ➜ API: http://{display_host}:{port}/studio/api/")
92
+ print(f" 🔌 API Health: http://{display_host}:{port}/studio/api/health")
93
+ print()
94
+
95
+ if cloud:
96
+ print("☁️ Cloud mode enabled - Git-backed workspaces")
97
+ os.environ["STUDIO_CLOUD_MODE"] = "1"
98
+ print()
99
+
100
+ with suppress(Exception):
101
+ webbrowser.open_new_tab(f"http://{display_host}:{port}/studio/")
102
+
103
+ # Start uvicorn
104
+ uvicorn.run(
105
+ "framework_m_studio.app:app",
106
+ host=host,
107
+ port=port,
108
+ reload=reload,
109
+ log_level="info",
110
+ )
111
+
112
+
113
+ __all__ = [
114
+ "codegen_app",
115
+ "codegen_client",
116
+ "codegen_doctype",
117
+ "console",
118
+ "docs_app",
119
+ "docs_audit",
120
+ "docs_generate",
121
+ "docs_openapi",
122
+ "docs_screenshots",
123
+ "routes",
124
+ "studio_app",
125
+ "studio_serve",
126
+ "verify_mfe",
127
+ ]
@@ -0,0 +1,107 @@
1
+ """Codegen CLI Commands.
2
+
3
+ This module provides code generation tools for Framework M.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ from typing import Annotated
9
+
10
+ import cyclopts
11
+
12
+ codegen_app = cyclopts.App(
13
+ name="codegen",
14
+ help="Code generation tools for Framework M",
15
+ )
16
+
17
+
18
+ @codegen_app.command(name="client")
19
+ def codegen_client(
20
+ lang: Annotated[
21
+ str,
22
+ cyclopts.Parameter(
23
+ name="--lang",
24
+ help="Target language: ts (TypeScript) or py (Python)",
25
+ ),
26
+ ] = "ts",
27
+ out: Annotated[
28
+ str,
29
+ cyclopts.Parameter(
30
+ name="--out",
31
+ help="Output directory for generated code",
32
+ ),
33
+ ] = "./generated",
34
+ openapi_url: Annotated[
35
+ str,
36
+ cyclopts.Parameter(
37
+ name="--openapi-url",
38
+ help="URL to fetch OpenAPI schema from",
39
+ ),
40
+ ] = "http://localhost:8000/schema/openapi.json",
41
+ ) -> None:
42
+ """Generate API client from OpenAPI schema.
43
+
44
+ Examples:
45
+ m codegen client --lang ts --out ./frontend/src/api
46
+ m codegen client --lang py --out ./scripts/api_client
47
+ """
48
+ from pathlib import Path
49
+
50
+ from framework_m_studio.sdk_generator import (
51
+ fetch_openapi_schema,
52
+ generate_typescript_client,
53
+ generate_typescript_types,
54
+ )
55
+
56
+ print(f"Generating {lang.upper()} client...")
57
+ print(f" OpenAPI URL: {openapi_url}")
58
+ print(f" Output: {out}")
59
+
60
+ # Create output directory
61
+ output_path = Path(out)
62
+ output_path.mkdir(parents=True, exist_ok=True)
63
+
64
+ # Fetch schema and generate
65
+ schema = fetch_openapi_schema(openapi_url)
66
+ if lang.lower() == "ts":
67
+ types_code = generate_typescript_types(schema)
68
+ client_code = generate_typescript_client(schema)
69
+ (output_path / "types.ts").write_text(types_code)
70
+ (output_path / "client.ts").write_text(client_code)
71
+
72
+
73
+ @codegen_app.command(name="doctype")
74
+ def codegen_doctype(
75
+ name: Annotated[
76
+ str,
77
+ cyclopts.Parameter(help="DocType class name (PascalCase)"),
78
+ ],
79
+ app: Annotated[
80
+ str | None,
81
+ cyclopts.Parameter(
82
+ name="--app",
83
+ help="Target app directory",
84
+ ),
85
+ ] = None,
86
+ ) -> None:
87
+ """Generate DocType Python code from schema.
88
+
89
+ This is the programmatic version of the Studio UI's
90
+ DocType builder. Useful for CI/CD pipelines.
91
+
92
+ Examples:
93
+ m codegen doctype Invoice --app apps/billing
94
+ """
95
+ print(f"Generating DocType: {name}")
96
+ if app:
97
+ print(f" Target app: {app}")
98
+ print()
99
+ print("⚠️ Not yet implemented. Coming in Phase 07.")
100
+ print(" Will use LibCST for code generation")
101
+
102
+
103
+ __all__ = [
104
+ "codegen_app",
105
+ "codegen_client",
106
+ "codegen_doctype",
107
+ ]
@@ -0,0 +1,73 @@
1
+ """Contributor CLI Commands."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import os
7
+ import sys
8
+ from pathlib import Path
9
+ from typing import Annotated
10
+
11
+ import cyclopts
12
+
13
+ contrib_app = cyclopts.App(
14
+ name="contrib", help="Contributor tooling (CLA checks, etc.)"
15
+ )
16
+
17
+
18
+ @contrib_app.command(name="cla-check")
19
+ def cla_check_command(
20
+ user: Annotated[
21
+ str | None, cyclopts.Parameter(name="--user", help="GitLab/GitHub username")
22
+ ] = None,
23
+ contributors_file: Annotated[
24
+ str,
25
+ cyclopts.Parameter(
26
+ name="--contributors-file", help="Path to contributors JSON"
27
+ ),
28
+ ] = "contributors.json",
29
+ ) -> None:
30
+ """Check if a user has signed the Contributor License Agreement."""
31
+ target_user = user or os.environ.get("GITLAB_USER_LOGIN")
32
+
33
+ if not target_user:
34
+ print("No user provided. Skipping CLA check.")
35
+ return
36
+
37
+ contrib_path = Path(contributors_file)
38
+ if not contrib_path.exists():
39
+ print(
40
+ f"Error: Contributors file not found at {contributors_file}",
41
+ file=sys.stderr,
42
+ )
43
+ sys.exit(1)
44
+
45
+ try:
46
+ data = json.loads(contrib_path.read_text())
47
+ except json.JSONDecodeError:
48
+ print(f"Error: Invalid JSON in {contributors_file}", file=sys.stderr)
49
+ sys.exit(1)
50
+
51
+ # Support both the TDD test format and the real repository format
52
+ icla_users = data.get("icla", [])
53
+ if "users" in data and "gitlab" in data["users"]:
54
+ icla_users.extend(data["users"]["gitlab"])
55
+
56
+ if target_user in icla_users:
57
+ print(f"✅ User '{target_user}' has signed the ICLA.")
58
+ return
59
+
60
+ ccla_orgs = data.get("ccla", {})
61
+ for org, members in ccla_orgs.items():
62
+ if target_user in members:
63
+ print(
64
+ f"✅ User '{target_user}' is covered by CCLA for organization '{org}'."
65
+ )
66
+ return
67
+
68
+ print(f"❌ User '{target_user}' is not listed in {contributors_file}.")
69
+ print("Please sign the CLA by adding your username to the contributors file.")
70
+ sys.exit(1)
71
+
72
+
73
+ __all__ = ["cla_check_command", "contrib_app"]