@hybridlabor-api/aos 4.4.1 → 4.4.2-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (305) hide show
  1. package/.agents/skills/firecrawl/SKILL.md +149 -0
  2. package/.agents/skills/firecrawl/rules/install.md +82 -0
  3. package/.agents/skills/firecrawl/rules/security.md +26 -0
  4. package/.agents/skills/firecrawl-agent/SKILL.md +58 -0
  5. package/.agents/skills/firecrawl-build/SKILL.md +39 -0
  6. package/.agents/skills/firecrawl-build-interact/SKILL.md +68 -0
  7. package/.agents/skills/firecrawl-build-onboarding/SKILL.md +103 -0
  8. package/.agents/skills/firecrawl-build-onboarding/references/auth-flow.md +39 -0
  9. package/.agents/skills/firecrawl-build-onboarding/references/project-setup.md +20 -0
  10. package/.agents/skills/firecrawl-build-onboarding/references/sdk-installation.md +17 -0
  11. package/.agents/skills/firecrawl-build-scrape/SKILL.md +69 -0
  12. package/.agents/skills/firecrawl-build-search/SKILL.md +69 -0
  13. package/.agents/skills/firecrawl-crawl/SKILL.md +59 -0
  14. package/.agents/skills/firecrawl-download/SKILL.md +70 -0
  15. package/.agents/skills/firecrawl-interact/SKILL.md +84 -0
  16. package/.agents/skills/firecrawl-map/SKILL.md +51 -0
  17. package/.agents/skills/firecrawl-scrape/SKILL.md +69 -0
  18. package/.agents/skills/firecrawl-search/SKILL.md +60 -0
  19. package/CLAUDE.md +573 -0
  20. package/README.de.md +0 -8
  21. package/README.md +0 -8
  22. package/README.pt.md +0 -8
  23. package/assets/brand/ao-ant-mark.svg +91 -0
  24. package/assets/brand/bdb-core-mark.svg +34 -0
  25. package/assets/brand/heimdall-guardian-mark.svg +16 -0
  26. package/assets/brand/memb-crystal-mark.svg +18 -0
  27. package/bin/aos-config.mjs +89 -0
  28. package/bin/aos-dashboard.mjs +608 -0
  29. package/bin/aos-uninstall.mjs +227 -0
  30. package/docs/sessions/audit-2026-09-14-silent-failures.md +114 -0
  31. package/docs/skills_table.md +0 -3
  32. package/installer.js +471 -237
  33. package/mcps/RhinoMCP/cc-plugin/.claude/settings.json +10 -0
  34. package/mcps/after-effects-mcp/build/index.js +840 -0
  35. package/mcps/after-effects-mcp/build/scripts/applyEffect.jsx +153 -0
  36. package/mcps/after-effects-mcp/build/scripts/applyEffectTemplate.jsx +218 -0
  37. package/mcps/after-effects-mcp/build/scripts/createComposition.jsx +71 -0
  38. package/mcps/after-effects-mcp/build/scripts/createShapeLayer.jsx +147 -0
  39. package/mcps/after-effects-mcp/build/scripts/createSolidLayer.jsx +114 -0
  40. package/mcps/after-effects-mcp/build/scripts/createTextLayer.jsx +115 -0
  41. package/mcps/after-effects-mcp/build/scripts/getLayerInfo.jsx +192 -0
  42. package/mcps/after-effects-mcp/build/scripts/getProjectInfo.jsx +90 -0
  43. package/mcps/after-effects-mcp/build/scripts/listCompositions.jsx +50 -0
  44. package/mcps/after-effects-mcp/build/scripts/mcp-bridge-auto.jsx +1773 -0
  45. package/mcps/after-effects-mcp/build/scripts/setLayerProperties.jsx +160 -0
  46. package/mcps/computer-use-mcp/dist/client.d.ts +150 -0
  47. package/mcps/computer-use-mcp/dist/client.js +136 -0
  48. package/mcps/computer-use-mcp/dist/entrypoint.d.ts +16 -0
  49. package/mcps/computer-use-mcp/dist/entrypoint.js +26 -0
  50. package/mcps/computer-use-mcp/dist/native.d.ts +212 -0
  51. package/mcps/computer-use-mcp/dist/native.js +50 -0
  52. package/mcps/computer-use-mcp/dist/server.d.ts +32 -0
  53. package/mcps/computer-use-mcp/dist/server.js +342 -0
  54. package/mcps/computer-use-mcp/dist/session.d.ts +101 -0
  55. package/mcps/computer-use-mcp/dist/session.js +2372 -0
  56. package/package.json +13 -4
  57. package/skills/global_config/aos-project-init/SKILL.md +97 -130
  58. package/skills/global_config/aos-project-init/assets/openwikiignore.template +62 -0
  59. package/skills/global_config/aos-project-init/scripts/aos-project-doctor.mjs +38 -1
  60. package/skills/global_config/aos-setup/SKILL.md +98 -8
  61. package/skills/global_config/aos-setup/scripts/aos-doctor.mjs +21 -2
  62. package/skills/global_config/ask-tim/SKILL.md +2 -7
  63. package/skills/global_config/openwiki-skill/scripts/openwiki_daemon.py +65 -12
  64. package/bin/setup-saas.mjs +0 -792
  65. package/mcps/blender-mcp-server/.dockerignore +0 -19
  66. package/mcps/blender-mcp-server/.github/workflows/ci.yml +0 -67
  67. package/mcps/blender-mcp-server/.github/workflows/publish-pypi.yml +0 -54
  68. package/mcps/blender-mcp-server/CHANGELOG.md +0 -64
  69. package/mcps/blender-mcp-server/CONTRIBUTING.md +0 -107
  70. package/mcps/blender-mcp-server/Dockerfile +0 -19
  71. package/mcps/blender-mcp-server/LICENSE +0 -21
  72. package/mcps/blender-mcp-server/README.md +0 -409
  73. package/mcps/blender-mcp-server/addon/__init__.py +0 -1440
  74. package/mcps/blender-mcp-server/addon/models.py +0 -223
  75. package/mcps/blender-mcp-server/pyproject.toml +0 -120
  76. package/mcps/blender-mcp-server/scripts/blender_bridge_request.py +0 -71
  77. package/mcps/blender-mcp-server/scripts/blender_create_test_cube.py +0 -49
  78. package/mcps/blender-mcp-server/scripts/blender_scene_info.py +0 -38
  79. package/mcps/blender-mcp-server/scripts/build_addon_zip.sh +0 -29
  80. package/mcps/blender-mcp-server/scripts/demos/README.md +0 -186
  81. package/mcps/blender-mcp-server/scripts/demos/dam_break_scene.py +0 -276
  82. package/mcps/blender-mcp-server/scripts/demos/open_dam_break_gui.py +0 -33
  83. package/mcps/blender-mcp-server/scripts/demos/pipe_movement_study.py +0 -518
  84. package/mcps/blender-mcp-server/scripts/demos/pipe_pressure_failure_scene.py +0 -806
  85. package/mcps/blender-mcp-server/scripts/demos/procedural_dam_break_scene.py +0 -600
  86. package/mcps/blender-mcp-server/scripts/demos/run_dam_break.py +0 -510
  87. package/mcps/blender-mcp-server/scripts/launch_blender_gui.py +0 -41
  88. package/mcps/blender-mcp-server/scripts/library/README.md +0 -64
  89. package/mcps/blender-mcp-server/scripts/library/apply_transforms.py +0 -46
  90. package/mcps/blender-mcp-server/scripts/library/camera.py +0 -51
  91. package/mcps/blender-mcp-server/scripts/library/collections.py +0 -65
  92. package/mcps/blender-mcp-server/scripts/library/create_mesh.py +0 -41
  93. package/mcps/blender-mcp-server/scripts/library/effector.py +0 -48
  94. package/mcps/blender-mcp-server/scripts/library/fluid_domain.py +0 -80
  95. package/mcps/blender-mcp-server/scripts/library/fluid_inflow.py +0 -98
  96. package/mcps/blender-mcp-server/scripts/library/frame_range.py +0 -35
  97. package/mcps/blender-mcp-server/scripts/library/keyframes.py +0 -59
  98. package/mcps/blender-mcp-server/scripts/library/rigid_body.py +0 -52
  99. package/mcps/blender-mcp-server/scripts/library/save_blend.py +0 -40
  100. package/mcps/blender-mcp-server/scripts/server_start.sh +0 -26
  101. package/mcps/blender-mcp-server/src/blender_mcp_server/__init__.py +0 -3
  102. package/mcps/blender-mcp-server/src/blender_mcp_server/headless.py +0 -330
  103. package/mcps/blender-mcp-server/src/blender_mcp_server/server.py +0 -606
  104. package/mcps/davinci-mcp-professional/.bandit +0 -35
  105. package/mcps/davinci-mcp-professional/.claude/commands/security-review.md +0 -191
  106. package/mcps/davinci-mcp-professional/.claude/settings.json +0 -1
  107. package/mcps/davinci-mcp-professional/.editorconfig +0 -27
  108. package/mcps/davinci-mcp-professional/.gitattributes +0 -207
  109. package/mcps/davinci-mcp-professional/.github/CODEOWNERS +0 -2
  110. package/mcps/davinci-mcp-professional/.github/ISSUE_TEMPLATE/bug_report.md +0 -33
  111. package/mcps/davinci-mcp-professional/.github/ISSUE_TEMPLATE/feature_request.md +0 -19
  112. package/mcps/davinci-mcp-professional/.github/PULL_REQUEST_TEMPLATE.md +0 -20
  113. package/mcps/davinci-mcp-professional/.github/SECURITY.md +0 -97
  114. package/mcps/davinci-mcp-professional/.github/dependabot.yml +0 -27
  115. package/mcps/davinci-mcp-professional/.github/workflows/ci.yml +0 -39
  116. package/mcps/davinci-mcp-professional/ATTRIBUTION.md +0 -4
  117. package/mcps/davinci-mcp-professional/AUTHORS.md +0 -9
  118. package/mcps/davinci-mcp-professional/BUGS.md +0 -55
  119. package/mcps/davinci-mcp-professional/CLAUDE.md +0 -229
  120. package/mcps/davinci-mcp-professional/CONTRIBUTING.md +0 -51
  121. package/mcps/davinci-mcp-professional/COPYING.md +0 -228
  122. package/mcps/davinci-mcp-professional/Doxyfile +0 -379
  123. package/mcps/davinci-mcp-professional/README.md +0 -143
  124. package/mcps/davinci-mcp-professional/SECURITY.md +0 -40
  125. package/mcps/davinci-mcp-professional/USING.md +0 -301
  126. package/mcps/davinci-mcp-professional/VERSION.md +0 -13
  127. package/mcps/davinci-mcp-professional/build.py +0 -169
  128. package/mcps/davinci-mcp-professional/claude_desktop_config_template.json +0 -11
  129. package/mcps/davinci-mcp-professional/hooks/ci-check.sh +0 -29
  130. package/mcps/davinci-mcp-professional/hooks/pre-push +0 -46
  131. package/mcps/davinci-mcp-professional/main.py +0 -40
  132. package/mcps/davinci-mcp-professional/mcp_server.py +0 -30
  133. package/mcps/davinci-mcp-professional/pyproject.toml +0 -115
  134. package/mcps/davinci-mcp-professional/security_audit.py +0 -379
  135. package/mcps/davinci-mcp-professional/src/davinci_mcp/__init__.py +0 -19
  136. package/mcps/davinci-mcp-professional/src/davinci_mcp/cli.py +0 -138
  137. package/mcps/davinci-mcp-professional/src/davinci_mcp/resolve_client.py +0 -342
  138. package/mcps/davinci-mcp-professional/src/davinci_mcp/resources/__init__.py +0 -60
  139. package/mcps/davinci-mcp-professional/src/davinci_mcp/server.py +0 -185
  140. package/mcps/davinci-mcp-professional/src/davinci_mcp/tools/__init__.py +0 -146
  141. package/mcps/davinci-mcp-professional/src/davinci_mcp/types.py +0 -125
  142. package/mcps/davinci-mcp-professional/src/davinci_mcp/utils/__init__.py +0 -19
  143. package/mcps/davinci-mcp-professional/src/davinci_mcp/utils/platform.py +0 -239
  144. package/mcps/davinci-mcp-professional/test.py +0 -186
  145. package/mcps/davinci-mcp-professional/uv.lock +0 -2073
  146. package/mcps/davinci-resolve-mcp/.claude/skills/media-analysis.md +0 -44
  147. package/mcps/davinci-resolve-mcp/.clinerules +0 -17
  148. package/mcps/davinci-resolve-mcp/.cursorrules +0 -17
  149. package/mcps/davinci-resolve-mcp/.github/copilot-instructions.md +0 -17
  150. package/mcps/davinci-resolve-mcp/.github/workflows/npm-publish.yml +0 -109
  151. package/mcps/davinci-resolve-mcp/.windsurfrules +0 -17
  152. package/mcps/davinci-resolve-mcp/AGENTS.md +0 -114
  153. package/mcps/davinci-resolve-mcp/CHANGELOG.md +0 -2648
  154. package/mcps/davinci-resolve-mcp/CLAUDE.md +0 -15
  155. package/mcps/davinci-resolve-mcp/LICENSE +0 -21
  156. package/mcps/davinci-resolve-mcp/README.md +0 -173
  157. package/mcps/davinci-resolve-mcp/SECURITY.md +0 -53
  158. package/mcps/davinci-resolve-mcp/bin/davinci-resolve-mcp.mjs +0 -450
  159. package/mcps/davinci-resolve-mcp/examples/README.md +0 -53
  160. package/mcps/davinci-resolve-mcp/examples/markers/README.md +0 -81
  161. package/mcps/davinci-resolve-mcp/examples/media/README.md +0 -94
  162. package/mcps/davinci-resolve-mcp/examples/timeline/README.md +0 -98
  163. package/mcps/davinci-resolve-mcp/install.py +0 -1687
  164. package/mcps/davinci-resolve-mcp/package.json +0 -52
  165. package/mcps/davinci-resolve-mcp/release-notes/v2.22.0.md +0 -51
  166. package/mcps/davinci-resolve-mcp/release-notes/v2.23.0.md +0 -51
  167. package/mcps/davinci-resolve-mcp/release-notes/v2.23.1.md +0 -35
  168. package/mcps/davinci-resolve-mcp/release-notes/v2.24.1.md +0 -32
  169. package/mcps/davinci-resolve-mcp/scripts/audit_api_parity.py +0 -275
  170. package/mcps/davinci-resolve-mcp/scripts/audit_readwrite_symmetry.py +0 -80
  171. package/mcps/davinci-resolve-mcp/scripts/doctor.py +0 -227
  172. package/mcps/davinci-resolve-mcp/scripts/gen_api_limitations.py +0 -144
  173. package/mcps/davinci-resolve-mcp/scripts/live_media_analysis_polish_probe.py +0 -65
  174. package/mcps/davinci-resolve-mcp/scripts/measure_bridge_cost.py +0 -65
  175. package/mcps/davinci-resolve-mcp/scripts/regen_panel_screenshots.py +0 -76
  176. package/mcps/davinci-resolve-mcp/src/__init__.py +0 -3
  177. package/mcps/davinci-resolve-mcp/src/analysis_dashboard.py +0 -15505
  178. package/mcps/davinci-resolve-mcp/src/batch_cli.py +0 -540
  179. package/mcps/davinci-resolve-mcp/src/control_panel.py +0 -13
  180. package/mcps/davinci-resolve-mcp/src/granular/__init__.py +0 -17
  181. package/mcps/davinci-resolve-mcp/src/granular/common.py +0 -741
  182. package/mcps/davinci-resolve-mcp/src/granular/folder.py +0 -420
  183. package/mcps/davinci-resolve-mcp/src/granular/gallery.py +0 -306
  184. package/mcps/davinci-resolve-mcp/src/granular/graph.py +0 -309
  185. package/mcps/davinci-resolve-mcp/src/granular/media_pool.py +0 -679
  186. package/mcps/davinci-resolve-mcp/src/granular/media_pool_item.py +0 -1020
  187. package/mcps/davinci-resolve-mcp/src/granular/media_storage.py +0 -179
  188. package/mcps/davinci-resolve-mcp/src/granular/project.py +0 -1654
  189. package/mcps/davinci-resolve-mcp/src/granular/resolve_control.py +0 -538
  190. package/mcps/davinci-resolve-mcp/src/granular/timeline.py +0 -1075
  191. package/mcps/davinci-resolve-mcp/src/granular/timeline_item.py +0 -2251
  192. package/mcps/davinci-resolve-mcp/src/resolve_mcp_server.py +0 -43
  193. package/mcps/davinci-resolve-mcp/src/server.py +0 -24116
  194. package/mcps/davinci-resolve-mcp/src/utils/__init__.py +0 -3
  195. package/mcps/davinci-resolve-mcp/src/utils/actor_identity.py +0 -46
  196. package/mcps/davinci-resolve-mcp/src/utils/analysis_caps.py +0 -678
  197. package/mcps/davinci-resolve-mcp/src/utils/analysis_memory.py +0 -755
  198. package/mcps/davinci-resolve-mcp/src/utils/analysis_runs.py +0 -307
  199. package/mcps/davinci-resolve-mcp/src/utils/analysis_store.py +0 -945
  200. package/mcps/davinci-resolve-mcp/src/utils/api_truth.py +0 -525
  201. package/mcps/davinci-resolve-mcp/src/utils/app_control.py +0 -319
  202. package/mcps/davinci-resolve-mcp/src/utils/audio_fairlight_live_probe.py +0 -263
  203. package/mcps/davinci-resolve-mcp/src/utils/brain_edits.py +0 -387
  204. package/mcps/davinci-resolve-mcp/src/utils/bridge_metrics.py +0 -76
  205. package/mcps/davinci-resolve-mcp/src/utils/cdl.py +0 -20
  206. package/mcps/davinci-resolve-mcp/src/utils/clip_query.py +0 -85
  207. package/mcps/davinci-resolve-mcp/src/utils/cloud_operations.py +0 -192
  208. package/mcps/davinci-resolve-mcp/src/utils/color_grade_live_probe.py +0 -444
  209. package/mcps/davinci-resolve-mcp/src/utils/contracts.py +0 -102
  210. package/mcps/davinci-resolve-mcp/src/utils/cut_ir.py +0 -115
  211. package/mcps/davinci-resolve-mcp/src/utils/dctl_templates.py +0 -368
  212. package/mcps/davinci-resolve-mcp/src/utils/deep_vision.py +0 -643
  213. package/mcps/davinci-resolve-mcp/src/utils/destructive_hook.py +0 -606
  214. package/mcps/davinci-resolve-mcp/src/utils/edit_engine.py +0 -737
  215. package/mcps/davinci-resolve-mcp/src/utils/embeddings.py +0 -922
  216. package/mcps/davinci-resolve-mcp/src/utils/entities.py +0 -579
  217. package/mcps/davinci-resolve-mcp/src/utils/extension_authoring_live_probe.py +0 -292
  218. package/mcps/davinci-resolve-mcp/src/utils/failure_tracker.py +0 -119
  219. package/mcps/davinci-resolve-mcp/src/utils/fuse_templates.py +0 -1968
  220. package/mcps/davinci-resolve-mcp/src/utils/fusion_composition_live_probe.py +0 -284
  221. package/mcps/davinci-resolve-mcp/src/utils/fusion_group_settings.py +0 -334
  222. package/mcps/davinci-resolve-mcp/src/utils/layout_presets.py +0 -333
  223. package/mcps/davinci-resolve-mcp/src/utils/mcp_stdio.py +0 -32
  224. package/mcps/davinci-resolve-mcp/src/utils/mcp_transport.py +0 -128
  225. package/mcps/davinci-resolve-mcp/src/utils/media_analysis.py +0 -7690
  226. package/mcps/davinci-resolve-mcp/src/utils/media_analysis_jobs.py +0 -805
  227. package/mcps/davinci-resolve-mcp/src/utils/media_pool_changes.py +0 -121
  228. package/mcps/davinci-resolve-mcp/src/utils/media_pool_ingest_live_probe.py +0 -592
  229. package/mcps/davinci-resolve-mcp/src/utils/multicam.py +0 -393
  230. package/mcps/davinci-resolve-mcp/src/utils/object_inspection.py +0 -301
  231. package/mcps/davinci-resolve-mcp/src/utils/page_lock.py +0 -75
  232. package/mcps/davinci-resolve-mcp/src/utils/platform.py +0 -157
  233. package/mcps/davinci-resolve-mcp/src/utils/proc.py +0 -26
  234. package/mcps/davinci-resolve-mcp/src/utils/project_cleanup.py +0 -73
  235. package/mcps/davinci-resolve-mcp/src/utils/project_lifecycle_live_probe.py +0 -376
  236. package/mcps/davinci-resolve-mcp/src/utils/project_lint.py +0 -131
  237. package/mcps/davinci-resolve-mcp/src/utils/project_properties.py +0 -601
  238. package/mcps/davinci-resolve-mcp/src/utils/project_spec.py +0 -459
  239. package/mcps/davinci-resolve-mcp/src/utils/readback.py +0 -91
  240. package/mcps/davinci-resolve-mcp/src/utils/render_deliver_live_probe.py +0 -384
  241. package/mcps/davinci-resolve-mcp/src/utils/resolve_ai_governance.py +0 -214
  242. package/mcps/davinci-resolve-mcp/src/utils/resolve_ai_ledger.py +0 -244
  243. package/mcps/davinci-resolve-mcp/src/utils/resolve_busy.py +0 -171
  244. package/mcps/davinci-resolve-mcp/src/utils/resolve_connection.py +0 -77
  245. package/mcps/davinci-resolve-mcp/src/utils/review_annotation_live_probe.py +0 -352
  246. package/mcps/davinci-resolve-mcp/src/utils/script_templates.py +0 -1193
  247. package/mcps/davinci-resolve-mcp/src/utils/shot_relationships.py +0 -544
  248. package/mcps/davinci-resolve-mcp/src/utils/structural_diff.py +0 -175
  249. package/mcps/davinci-resolve-mcp/src/utils/sync_detection.py +0 -889
  250. package/mcps/davinci-resolve-mcp/src/utils/timeline_brain_db.py +0 -826
  251. package/mcps/davinci-resolve-mcp/src/utils/timeline_conform_live_probe.py +0 -280
  252. package/mcps/davinci-resolve-mcp/src/utils/timeline_kernel_live_probe.py +0 -1092
  253. package/mcps/davinci-resolve-mcp/src/utils/timeline_kernel_probe.py +0 -185
  254. package/mcps/davinci-resolve-mcp/src/utils/timeline_title_text.py +0 -87
  255. package/mcps/davinci-resolve-mcp/src/utils/timeline_versioning.py +0 -730
  256. package/mcps/davinci-resolve-mcp/src/utils/update_check.py +0 -685
  257. package/mcps/vectorworks-mcp/.dockerignore +0 -8
  258. package/mcps/vectorworks-mcp/Dockerfile +0 -28
  259. package/mcps/vectorworks-mcp/README.md +0 -156
  260. package/mcps/vectorworks-mcp/app/__init__.py +0 -2
  261. package/mcps/vectorworks-mcp/app/api.py +0 -52
  262. package/mcps/vectorworks-mcp/app/chunking.py +0 -56
  263. package/mcps/vectorworks-mcp/app/config.py +0 -29
  264. package/mcps/vectorworks-mcp/app/embeddings.py +0 -28
  265. package/mcps/vectorworks-mcp/app/indexer.py +0 -106
  266. package/mcps/vectorworks-mcp/app/main.py +0 -33
  267. package/mcps/vectorworks-mcp/app/mcp_server.py +0 -71
  268. package/mcps/vectorworks-mcp/app/search.py +0 -54
  269. package/mcps/vectorworks-mcp/app/utils.py +0 -14
  270. package/mcps/vectorworks-mcp/data/.gitkeep +0 -1
  271. package/mcps/vectorworks-mcp/data/vw-app-help/VW2022_PluginScript.htm +0 -95
  272. package/mcps/vectorworks-mcp/data/vw-app-help/VW2022_ScriptEditor.htm +0 -266
  273. package/mcps/vectorworks-mcp/data/vw-app-help/VW2022_Scripting.htm +0 -106
  274. package/mcps/vectorworks-mcp/data/vw-app-help/VW2023_CreatingScriptedPlugins.htm +0 -327
  275. package/mcps/vectorworks-mcp/data/vw-app-help/VW2024_RunningScripts.htm +0 -116
  276. package/mcps/vectorworks-mcp/data/vw-devwiki/VS_Function_Reference_category.html +0 -2129
  277. package/mcps/vectorworks-mcp/data/vw-jp-ref/ObjectsSymbols.html +0 -2035
  278. package/mcps/vectorworks-mcp/data/vw-jp-ref/ScriptFunctionReference.html +0 -29
  279. package/mcps/vectorworks-mcp/design.md +0 -57
  280. package/mcps/vectorworks-mcp/docker-compose.yml +0 -18
  281. package/mcps/vectorworks-mcp/index/.gitkeep +0 -1
  282. package/mcps/vectorworks-mcp/index/meta.jsonl +0 -3956
  283. package/mcps/vectorworks-mcp/index/vw.faiss +0 -0
  284. package/mcps/vectorworks-mcp/requirements.txt +0 -10
  285. package/mcps/vectorworks-mcp/scripts/fetch_docs_minimal.sh +0 -84
  286. package/mcps/vectorworks-mcp/scripts/fetch_github_vectorworks.sh +0 -85
  287. package/mcps/vectorworks-mcp/templates/index.html +0 -40
  288. package/scripts/ecosystem-health-audit.js +0 -257
  289. package/skills/bdb-dev-os-skill/SKILL.md +0 -49
  290. package/skills/bdb-dev-os-skill/package.json +0 -11
  291. package/skills/bdbsaastraining/SKILL.md +0 -316
  292. package/skills/bdbsaastraining/references/exam-pool.md +0 -313
  293. package/skills/bdbsaastraining/references/interaction-modes.md +0 -94
  294. package/skills/bdbsaastraining/references/track-a-ai-agent.md +0 -111
  295. package/skills/bdbsaastraining/references/track-b-wordpress.md +0 -111
  296. package/skills/bdbsaastraining/references/track-c-mailserver.md +0 -107
  297. package/skills/bdbsaastraining/references/track-d-debian.md +0 -109
  298. package/skills/bdbsaastraining/references/track-e-custom.md +0 -83
  299. package/skills/bdbsaastraining/scripts/build_profile.py +0 -529
  300. package/skills/bdbsaastraining/scripts/generate_certificate.py +0 -161
  301. package/skills/bdbsaastraining/scripts/preflight_check.sh +0 -150
  302. package/skills/bdbsaastraining/templates/certificate_template.html +0 -508
  303. package/skills/global_config/bdb-ecosystem-health/SKILL.md +0 -68
  304. package/skills/global_config/bdbsaas-ops/SKILL.md +0 -16
  305. package/skills/global_config/bdbsaashost/SKILL.md +0 -125
@@ -1,227 +0,0 @@
1
- #!/usr/bin/env python3
2
- """Read-only diagnostics for a local DaVinci Resolve MCP setup.
3
-
4
- Checks the checkout, Python interpreter, Resolve app and scripting-API paths,
5
- MCP client configs, and probes the DaVinciResolveScript bridge without
6
- mutating anything. Prints OK/WARN/FAIL lines (or JSON with --json) and exits
7
- nonzero only when a FAIL is present.
8
-
9
- Run: `python3 scripts/doctor.py`
10
-
11
- Overridable via environment: DAVINCI_MCP_REPO, DAVINCI_MCP_PYTHON,
12
- CODEX_HOME, CLAUDE_DESKTOP_CONFIG, RESOLVE_APP, RESOLVE_SCRIPT_API,
13
- RESOLVE_SCRIPT_MODULES, RESOLVE_SCRIPT_LIB.
14
- """
15
-
16
- from __future__ import annotations
17
-
18
- import argparse
19
- import json
20
- import os
21
- import re
22
- import subprocess
23
- import sys
24
- from pathlib import Path
25
- from typing import Any
26
-
27
-
28
- def find_repo_root() -> Path:
29
- env_repo = os.environ.get("DAVINCI_MCP_REPO")
30
- if env_repo:
31
- return Path(env_repo).expanduser().resolve()
32
- current = Path(__file__).resolve()
33
- for candidate in [current, *current.parents]:
34
- if (candidate / "src" / "server.py").exists():
35
- return candidate
36
- return current.parents[1]
37
-
38
-
39
- REPO = find_repo_root()
40
- PYTHON = Path(os.environ.get("DAVINCI_MCP_PYTHON", REPO / "venv" / "bin" / "python")).expanduser()
41
- if not PYTHON.exists():
42
- PYTHON = REPO / ".venv" / "bin" / "python"
43
- if not PYTHON.exists():
44
- PYTHON = Path(sys.executable)
45
- SERVER = REPO / "src" / "server.py"
46
- CODEX_HOME = Path(os.environ.get("CODEX_HOME", "~/.codex")).expanduser()
47
- CODEX_CONFIG = CODEX_HOME / "config.toml"
48
- CLAUDE_CONFIG = Path(
49
- os.environ.get(
50
- "CLAUDE_DESKTOP_CONFIG",
51
- "~/Library/Application Support/Claude/claude_desktop_config.json",
52
- )
53
- ).expanduser()
54
- RESOLVE_APP = Path(os.environ.get("RESOLVE_APP", "/Applications/DaVinci Resolve/DaVinci Resolve.app"))
55
- RESOLVE_API = Path(
56
- os.environ.get(
57
- "RESOLVE_SCRIPT_API",
58
- "/Library/Application Support/Blackmagic Design/DaVinci Resolve/Developer/Scripting",
59
- )
60
- )
61
- RESOLVE_MODULES = Path(os.environ.get("RESOLVE_SCRIPT_MODULES", RESOLVE_API / "Modules"))
62
- RESOLVE_LIB = Path(
63
- os.environ.get(
64
- "RESOLVE_SCRIPT_LIB",
65
- "/Applications/DaVinci Resolve/DaVinci Resolve.app/Contents/Libraries/Fusion/fusionscript.so",
66
- )
67
- )
68
-
69
-
70
- def run(cmd: list[str], timeout: int = 12) -> dict[str, Any]:
71
- try:
72
- proc = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout)
73
- return {
74
- "ok": proc.returncode == 0,
75
- "returncode": proc.returncode,
76
- "stdout": proc.stdout.strip(),
77
- "stderr": proc.stderr.strip(),
78
- }
79
- except Exception as exc:
80
- return {"ok": False, "returncode": None, "stdout": "", "stderr": str(exc)}
81
-
82
-
83
- def run_in_repo(cmd: list[str], timeout: int = 12) -> dict[str, Any]:
84
- try:
85
- proc = subprocess.run(cmd, cwd=REPO, capture_output=True, text=True, timeout=timeout)
86
- return {
87
- "ok": proc.returncode == 0,
88
- "returncode": proc.returncode,
89
- "stdout": proc.stdout.strip(),
90
- "stderr": proc.stderr.strip(),
91
- }
92
- except Exception as exc:
93
- return {"ok": False, "returncode": None, "stdout": "", "stderr": str(exc)}
94
-
95
-
96
- def check(results: list[dict[str, str]], status: str, name: str, detail: str) -> None:
97
- results.append({"status": status, "name": name, "detail": detail})
98
-
99
-
100
- def file_contains(path: Path, needles: list[str]) -> tuple[bool, str]:
101
- if not path.exists():
102
- return False, "missing"
103
- text = path.read_text(errors="replace")
104
- missing = [needle for needle in needles if needle not in text]
105
- if missing:
106
- return False, "missing: " + ", ".join(missing)
107
- return True, "contains davinci-resolve MCP entry"
108
-
109
-
110
- def version_from_server() -> str:
111
- if not SERVER.exists():
112
- return "unknown"
113
- match = re.search(r'^VERSION\s*=\s*"([^"]+)"', SERVER.read_text(errors="replace"), re.M)
114
- return match.group(1) if match else "unknown"
115
-
116
-
117
- def git_summary() -> str:
118
- if not (REPO / ".git").exists():
119
- return "not a git checkout"
120
- status = run_in_repo(["git", "status", "--short", "--branch"], timeout=8)
121
- return status["stdout"] or status["stderr"] or "git status produced no output"
122
-
123
-
124
- def git_head() -> str:
125
- if not (REPO / ".git").exists():
126
- return "not a git checkout"
127
- head = run_in_repo(["git", "describe", "--tags", "--always", "--dirty"], timeout=8)
128
- return head["stdout"] or head["stderr"] or "git describe produced no output"
129
-
130
-
131
- def resolve_probe() -> dict[str, Any]:
132
- if not PYTHON.exists():
133
- return {"import_ok": False, "error": f"{PYTHON} is missing"}
134
-
135
- code = f"""
136
- import json
137
- import sys
138
- sys.path.insert(0, {str(RESOLVE_MODULES)!r})
139
- try:
140
- import DaVinciResolveScript as dvr
141
- resolve = dvr.scriptapp("Resolve")
142
- payload = {{
143
- "import_ok": True,
144
- "module": getattr(dvr, "__file__", None),
145
- "resolve_connected": bool(resolve),
146
- "product": resolve.GetProductName() if resolve else None,
147
- "version": resolve.GetVersionString() if resolve else None,
148
- }}
149
- except Exception as exc:
150
- payload = {{"import_ok": False, "error": repr(exc)}}
151
- print(json.dumps(payload))
152
- """
153
- env = {
154
- **os.environ,
155
- "RESOLVE_SCRIPT_API": str(RESOLVE_API),
156
- "RESOLVE_SCRIPT_LIB": str(RESOLVE_LIB),
157
- "PYTHONPATH": str(RESOLVE_MODULES),
158
- }
159
- proc = subprocess.run([str(PYTHON), "-c", code], capture_output=True, text=True, timeout=12, env=env)
160
- output = (proc.stdout or proc.stderr).strip()
161
- try:
162
- payload = json.loads(output)
163
- except json.JSONDecodeError:
164
- payload = {"import_ok": False, "error": output or f"probe exited {proc.returncode}"}
165
- payload["returncode"] = proc.returncode
166
- return payload
167
-
168
-
169
- def collect() -> list[dict[str, str]]:
170
- results: list[dict[str, str]] = []
171
-
172
- check(results, "OK" if REPO.exists() else "FAIL", "MCP checkout", str(REPO))
173
- check(results, "OK" if SERVER.exists() else "FAIL", "Server entrypoint", str(SERVER))
174
- check(results, "OK" if PYTHON.exists() else "FAIL", "Python", str(PYTHON))
175
- check(results, "OK" if RESOLVE_APP.exists() else "FAIL", "Resolve app", str(RESOLVE_APP))
176
- check(results, "OK" if RESOLVE_API.exists() else "FAIL", "Resolve scripting API", str(RESOLVE_API))
177
- check(results, "OK" if RESOLVE_MODULES.exists() else "FAIL", "Resolve scripting modules", str(RESOLVE_MODULES))
178
- check(results, "OK" if RESOLVE_LIB.exists() else "FAIL", "Resolve scripting library", str(RESOLVE_LIB))
179
-
180
- needles = [str(SERVER)]
181
- ok, detail = file_contains(CODEX_CONFIG, needles)
182
- check(results, "OK" if ok else "WARN", "Codex MCP config", f"{CODEX_CONFIG}: {detail}")
183
- ok, detail = file_contains(CLAUDE_CONFIG, needles)
184
- check(results, "OK" if ok else "WARN", "Claude Desktop MCP config", f"{CLAUDE_CONFIG}: {detail}")
185
-
186
- pyver = run([str(PYTHON), "--version"]) if PYTHON.exists() else {"ok": False, "stdout": "", "stderr": "missing"}
187
- check(results, "OK" if pyver["ok"] else "FAIL", "Python version", pyver["stdout"] or pyver["stderr"])
188
-
189
- probe = resolve_probe()
190
- if probe.get("import_ok"):
191
- check(results, "OK", "DaVinciResolveScript import", str(probe.get("module")))
192
- if probe.get("resolve_connected"):
193
- detail = f"{probe.get('product')} {probe.get('version')}"
194
- check(results, "OK", "Resolve scripting connection", detail)
195
- else:
196
- check(
197
- results,
198
- "WARN",
199
- "Resolve scripting connection",
200
- 'Module import worked, but scriptapp("Resolve") returned no object. Open DaVinci Resolve Studio, set Preferences > General > External scripting using = Local, and restart Resolve.',
201
- )
202
- else:
203
- check(results, "FAIL", "DaVinciResolveScript import", str(probe.get("error")))
204
-
205
- check(results, "OK", "MCP server version", version_from_server())
206
- check(results, "OK", "MCP git head", git_head())
207
- check(results, "OK", "Git status", git_summary())
208
- return results
209
-
210
-
211
- def main() -> int:
212
- parser = argparse.ArgumentParser(description=__doc__)
213
- parser.add_argument("--json", action="store_true", help="Print machine-readable JSON")
214
- args = parser.parse_args()
215
-
216
- results = collect()
217
- if args.json:
218
- print(json.dumps({"checks": results}, indent=2))
219
- else:
220
- for item in results:
221
- print(f"[{item['status']}] {item['name']}: {item['detail']}")
222
-
223
- return 1 if any(item["status"] == "FAIL" for item in results) else 0
224
-
225
-
226
- if __name__ == "__main__":
227
- raise SystemExit(main())
@@ -1,144 +0,0 @@
1
- #!/usr/bin/env python3
2
- """Generate the Blackmagic-facing DaVinci Resolve API limitations report.
3
-
4
- The single source of truth is the ``submit``-tagged entries in
5
- ``src/utils/api_truth.py`` (see ``submittable_limitations``). This script renders
6
- them into ``docs/reference/api-limitations.md`` — a curated, behaviorally-verified
7
- list that can be submitted to Blackmagic Design's developer feedback, split into
8
- capabilities they should *add* and behaviors they should *fix*.
9
-
10
- The output is deterministic (no timestamps) so ``tests.test_api_limitations_doc``
11
- can assert the committed file matches. Regenerate after editing any ``submit``
12
- entry:
13
-
14
- venv/bin/python scripts/gen_api_limitations.py
15
-
16
- Run with ``--check`` to fail (exit 1) when the committed doc is stale.
17
- """
18
- from __future__ import annotations
19
-
20
- import sys
21
- from pathlib import Path
22
-
23
- REPO_ROOT = Path(__file__).resolve().parent.parent
24
- if str(REPO_ROOT) not in sys.path:
25
- sys.path.insert(0, str(REPO_ROOT))
26
-
27
- from src.utils.api_truth import ( # noqa: E402
28
- VERIFIED_ON,
29
- submittable_limitations,
30
- )
31
-
32
- DOC_PATH = REPO_ROOT / "docs" / "reference" / "api-limitations.md"
33
- ISSUE_URL = "https://github.com/samuelgursky/davinci-resolve-mcp/issues"
34
-
35
-
36
- def _render_entry(entry: dict) -> str:
37
- lines = [f"### {entry['symbol']}", ""]
38
- obj = entry.get("object")
39
- if obj:
40
- lines.append(f"- **Object:** `{obj}`")
41
- sig = entry.get("signature")
42
- if sig:
43
- lines.append(f"- **Signature:** `{sig}`")
44
- lines.append(f"- **Behavior:** {entry['reality']}")
45
- rec = entry.get("recommended")
46
- if rec:
47
- lines.append(f"- **Workaround / current handling:** {rec}")
48
- issue = entry.get("issue")
49
- if issue is not None:
50
- lines.append(f"- **Reference:** [issue #{issue}]({ISSUE_URL}/{issue})")
51
- tags = entry.get("tags")
52
- if tags:
53
- lines.append(f"- **Tags:** {', '.join(tags)}")
54
- lines.append("")
55
- return "\n".join(lines)
56
-
57
-
58
- def render() -> str:
59
- groups = submittable_limitations()
60
- missing = groups["missing"]
61
- bugs = groups["bug"]
62
-
63
- out = [
64
- "# DaVinci Resolve Scripting API — Limitations & Feedback",
65
- "",
66
- "<!-- GENERATED FILE — do not edit by hand.",
67
- " Source: src/utils/api_truth.py (entries tagged `submit`).",
68
- " Regenerate: venv/bin/python scripts/gen_api_limitations.py -->",
69
- "",
70
- "This is a curated, behaviorally-verified list of DaVinci Resolve scripting",
71
- "API gaps and bugs encountered while building this MCP server, intended for",
72
- "submission to Blackmagic Design's developer feedback. Every item was",
73
- "observed against live Resolve; each entry notes the current workaround (or",
74
- "that none exists).",
75
- "",
76
- f"**Verified on:** {VERIFIED_ON}",
77
- "",
78
- f"**Totals:** {len(missing)} missing capabilities, {len(bugs)} bugs / "
79
- "unreliable behaviors.",
80
- "",
81
- "The authoritative source is the runtime-queryable `api_truth` ledger",
82
- "(`resolve_control api_truth \"<query>\"`); this document is generated from",
83
- "it and stays in sync via a drift guard.",
84
- "",
85
- "### Scope & completeness",
86
- "",
87
- "This list is **not guaranteed exhaustive.** It combines (a) issues hit",
88
- "while building this MCP server, (b) a `dir()` surface audit of the live",
89
- "Resolve API objects (ProjectManager, Project, MediaPool, MediaPoolItem,",
90
- "Timeline, TimelineItem, Graph) diffed against Resolve's UI feature set,",
91
- "and (c) a live mutating harness (`tests/live_api_gap_verification.py`)",
92
- "that attempts each operation against a disposable project built from",
93
- "synthetic media and confirms it fails while a related control succeeds.",
94
- "That catches absent methods and documented constraints, but not subtler",
95
- "issues: parameters that exist yet misbehave, version-specific regressions,",
96
- "or capabilities we simply never exercised. New findings are added as",
97
- "`submit`-tagged `api_truth` entries and this document is regenerated.",
98
- "",
99
- "Note: `hasattr()`/`getattr()` cannot be used to probe this API — the",
100
- "Python bridge fabricates a callable for any attribute name (see the",
101
- "`hasattr` bug below). Method existence here was checked with `dir()`.",
102
- "",
103
- "## Missing Capabilities (please add)",
104
- "",
105
- "Functionality that exists in the Resolve UI but has no scripting API",
106
- "equivalent, blocking full automation.",
107
- "",
108
- ]
109
- for entry in missing:
110
- out.append(_render_entry(entry))
111
-
112
- out += [
113
- "## Bugs / Unreliable Behavior (please fix)",
114
- "",
115
- "Methods that exist but misbehave — silent failures, unreliable return",
116
- "values, or automation-hostile modal prompts.",
117
- "",
118
- ]
119
- for entry in bugs:
120
- out.append(_render_entry(entry))
121
-
122
- return "\n".join(out).rstrip() + "\n"
123
-
124
-
125
- def main(argv: list[str]) -> int:
126
- content = render()
127
- if "--check" in argv:
128
- current = DOC_PATH.read_text() if DOC_PATH.exists() else ""
129
- if current != content:
130
- print(
131
- f"STALE: {DOC_PATH.relative_to(REPO_ROOT)} is out of date.\n"
132
- "Run: venv/bin/python scripts/gen_api_limitations.py",
133
- file=sys.stderr,
134
- )
135
- return 1
136
- print(f"OK: {DOC_PATH.relative_to(REPO_ROOT)} is up to date.")
137
- return 0
138
- DOC_PATH.write_text(content)
139
- print(f"Wrote {DOC_PATH.relative_to(REPO_ROOT)}")
140
- return 0
141
-
142
-
143
- if __name__ == "__main__":
144
- raise SystemExit(main(sys.argv[1:]))
@@ -1,65 +0,0 @@
1
- #!/usr/bin/env python3
2
- """Opt-in live probe for media-analysis polish.
3
-
4
- This script connects to the currently open Resolve project and exercises only
5
- source-safe planning/review surfaces. It may write analysis artifacts under the
6
- project analysis root, but it does not import, transcode, proxy, move, rename,
7
- or write beside source media.
8
- """
9
-
10
- from __future__ import annotations
11
-
12
- import argparse
13
- import asyncio
14
- import json
15
- import os
16
- import sys
17
- from pathlib import Path
18
-
19
-
20
- PROJECT_ROOT = Path(__file__).resolve().parent.parent
21
- if str(PROJECT_ROOT) not in sys.path:
22
- sys.path.insert(0, str(PROJECT_ROOT))
23
-
24
- from src.server import media_analysis # noqa: E402
25
-
26
-
27
- async def main() -> int:
28
- parser = argparse.ArgumentParser(description="Run a source-safe live media-analysis polish probe.")
29
- parser.add_argument("--target", default="project", help="project, selected, bin:<path>, or absolute file path")
30
- parser.add_argument("--depth", default="standard", choices=["quick", "standard", "deep", "custom"])
31
- parser.add_argument("--analysis-root", default=None, help="Optional base analysis root; project subdir is still added")
32
- parser.add_argument("--max-samples", type=int, default=8, help="Marker thumbnail samples for review")
33
- parser.add_argument("--execute", action="store_true", help="Execute analysis instead of dry-run planning")
34
- parser.add_argument("--persist", action="store_true", help="Keep executed analysis artifacts under the project root")
35
- args = parser.parse_args()
36
-
37
- common = {
38
- "target": args.target,
39
- "depth": args.depth,
40
- "analysis_root": args.analysis_root,
41
- "dry_run": not args.execute,
42
- "persist": args.persist,
43
- "session_only": bool(args.execute and not args.persist),
44
- "reuse_existing": True,
45
- "max_analysis_frames": 8,
46
- "vision": {"enabled": False},
47
- "transcription": {"enabled": False},
48
- }
49
- plan = await media_analysis("plan", common)
50
- review = await media_analysis("review_timeline_markers", {
51
- "analysis_root": args.analysis_root,
52
- "max_samples": args.max_samples,
53
- "vision": {"enabled": False},
54
- })
55
- print(json.dumps({
56
- "success": bool(plan.get("success")),
57
- "cwd": os.getcwd(),
58
- "plan": plan,
59
- "marker_review": review,
60
- }, indent=2, ensure_ascii=False))
61
- return 0 if plan.get("success") else 1
62
-
63
-
64
- if __name__ == "__main__":
65
- raise SystemExit(asyncio.run(main()))
@@ -1,65 +0,0 @@
1
- #!/usr/bin/env python3
2
- """Measure DaVinci Resolve bridge round-trips for representative operations.
3
-
4
- Wraps the live project in a counting proxy and runs a few common traversals,
5
- reporting how many attribute accesses + method calls (each a bridge round-trip)
6
- they cost. This is the measurement that gates whether a property cache is worth
7
- building. Run against an OPEN project; it only reads.
8
-
9
- PYTHONPATH=. venv/bin/python scripts/measure_bridge_cost.py
10
- """
11
- import sys
12
-
13
- import src.server as s
14
- from src.utils.bridge_metrics import measure
15
-
16
-
17
- def _walk_media_pool(project_proxy):
18
- """A typical media-pool traversal: every folder, every clip, name + a property."""
19
- mp = project_proxy.GetMediaPool()
20
- root = mp.GetRootFolder()
21
- clips_seen = 0
22
-
23
- def walk(folder):
24
- nonlocal clips_seen
25
- for clip in (folder.GetClipList() or []):
26
- clip.GetName()
27
- clip.GetClipProperty("Type")
28
- clips_seen += 1
29
- for sub in (folder.GetSubFolderList() or []):
30
- walk(sub)
31
-
32
- walk(root)
33
- return clips_seen
34
-
35
-
36
- def main():
37
- r = s.get_resolve()
38
- if not r:
39
- print("Not connected to Resolve.")
40
- return 1
41
- proj = r.GetProjectManager().GetCurrentProject()
42
- if not proj:
43
- print("No project open.")
44
- return 1
45
-
46
- clips_holder = {}
47
-
48
- def op(proj_proxy):
49
- clips_holder["n"] = _walk_media_pool(proj_proxy)
50
-
51
- counts = measure(op, proj)
52
- n = clips_holder.get("n", 0)
53
- total = counts["attr_access"] + counts["calls"]
54
- print(f"project: {proj.GetName()!r}")
55
- print(f"clips walked: {n}")
56
- print(f"bridge attr-accesses: {counts['attr_access']}")
57
- print(f"bridge method-calls: {counts['calls']}")
58
- print(f"total round-trips: {total}")
59
- if n:
60
- print(f"round-trips per clip: {total / n:.1f}")
61
- return 0
62
-
63
-
64
- if __name__ == "__main__":
65
- sys.exit(main())
@@ -1,76 +0,0 @@
1
- #!/usr/bin/env python3
2
- """Regenerate the control-panel doc screenshots from a live panel.
3
-
4
- Drives the panel's hash deep links headlessly and writes 1280x800 captures
5
- into docs/images/control-panel/. Run whenever the panel UI changes visibly.
6
-
7
- Setup:
8
- 1. venv/bin/pip install playwright (chromium is fetched on first run if absent)
9
- 2. Start the panel bound to a project that HAS an analyzed clip, e.g.:
10
- venv/bin/python -m src.control_panel --no-open
11
- (Bind to a rich analysis context if the live Resolve project is empty.)
12
- 3. venv/bin/python scripts/regen_panel_screenshots.py [--clip-id <id>] [--port 8765]
13
-
14
- The clip id defaults to the first analyzed clip reported by /api/clips.
15
- """
16
- from __future__ import annotations
17
-
18
- import argparse
19
- import json
20
- import pathlib
21
- import sys
22
- import urllib.request
23
-
24
- OUT_DIR = pathlib.Path(__file__).resolve().parent.parent / "docs" / "images" / "control-panel"
25
-
26
-
27
- def first_clip_id(base: str) -> str:
28
- with urllib.request.urlopen(f"{base}/api/clips", timeout=10) as resp:
29
- payload = json.load(resp)
30
- clips = payload.get("clips") or []
31
- if not clips:
32
- sys.exit("No analyzed clips in the panel's project — bind the panel to a project with analysis data first.")
33
- return clips[0]["clip_id"]
34
-
35
-
36
- def main() -> int:
37
- parser = argparse.ArgumentParser(description=__doc__)
38
- parser.add_argument("--port", type=int, default=8765)
39
- parser.add_argument("--clip-id", default=None)
40
- args = parser.parse_args()
41
- base = f"http://127.0.0.1:{args.port}"
42
-
43
- try:
44
- from playwright.sync_api import sync_playwright
45
- except ImportError:
46
- sys.exit("playwright not installed: venv/bin/pip install playwright")
47
-
48
- clip = args.clip_id or first_clip_id(base)
49
- shots = [
50
- ("#overview", "01-overview.png", 3000),
51
- ("#analysis/review", "02-review-bin-grid.png", 3500),
52
- (f"#analysis/review/clip/{clip}", "03-clip-detail.png", 4000),
53
- (f"#analysis/review/clip/{clip}/transcript", "04-transcript.png", 4000),
54
- (f"#analysis/review/clip/{clip}/shot/3", "05-shot-detail.png", 4500),
55
- ("#analysis/media", "06-inventory.png", 3500),
56
- ("#diagnostics/resolve", "07-diagnostics-resolve.png", 3000),
57
- ("#preferences/analysis", "08-preferences-analysis.png", 3000),
58
- ("#aiconsole", "09-ai-console.png", 3000),
59
- ("#analysis/review/history", "10-history.png", 3500),
60
- ("#analysis/review/plans", "11-edit-plans.png", 3500),
61
- ]
62
- with sync_playwright() as pw:
63
- browser = pw.chromium.launch()
64
- page = browser.new_page(viewport={"width": 1280, "height": 800})
65
- for hash_, name, wait in shots:
66
- page.goto(f"{base}/{hash_}")
67
- page.wait_for_timeout(wait)
68
- page.screenshot(path=str(OUT_DIR / name))
69
- print("shot:", name)
70
- browser.close()
71
- print(f"done — {len(shots)} screenshots in {OUT_DIR}")
72
- return 0
73
-
74
-
75
- if __name__ == "__main__":
76
- raise SystemExit(main())
@@ -1,3 +0,0 @@
1
- """
2
- DaVinci Resolve MCP Server Package
3
- """