@hybridlabor-api/aos 4.4.1 → 4.4.2-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/firecrawl/SKILL.md +149 -0
- package/.agents/skills/firecrawl/rules/install.md +82 -0
- package/.agents/skills/firecrawl/rules/security.md +26 -0
- package/.agents/skills/firecrawl-agent/SKILL.md +58 -0
- package/.agents/skills/firecrawl-build/SKILL.md +39 -0
- package/.agents/skills/firecrawl-build-interact/SKILL.md +68 -0
- package/.agents/skills/firecrawl-build-onboarding/SKILL.md +103 -0
- package/.agents/skills/firecrawl-build-onboarding/references/auth-flow.md +39 -0
- package/.agents/skills/firecrawl-build-onboarding/references/project-setup.md +20 -0
- package/.agents/skills/firecrawl-build-onboarding/references/sdk-installation.md +17 -0
- package/.agents/skills/firecrawl-build-scrape/SKILL.md +69 -0
- package/.agents/skills/firecrawl-build-search/SKILL.md +69 -0
- package/.agents/skills/firecrawl-crawl/SKILL.md +59 -0
- package/.agents/skills/firecrawl-download/SKILL.md +70 -0
- package/.agents/skills/firecrawl-interact/SKILL.md +84 -0
- package/.agents/skills/firecrawl-map/SKILL.md +51 -0
- package/.agents/skills/firecrawl-scrape/SKILL.md +69 -0
- package/.agents/skills/firecrawl-search/SKILL.md +60 -0
- package/CLAUDE.md +573 -0
- package/README.de.md +0 -8
- package/README.md +0 -8
- package/README.pt.md +0 -8
- package/assets/brand/ao-ant-mark.svg +91 -0
- package/assets/brand/bdb-core-mark.svg +34 -0
- package/assets/brand/heimdall-guardian-mark.svg +16 -0
- package/assets/brand/memb-crystal-mark.svg +18 -0
- package/bin/aos-config.mjs +89 -0
- package/bin/aos-dashboard.mjs +608 -0
- package/bin/aos-uninstall.mjs +227 -0
- package/docs/sessions/audit-2026-09-14-silent-failures.md +114 -0
- package/docs/skills_table.md +0 -3
- package/installer.js +387 -237
- package/mcps/RhinoMCP/cc-plugin/.claude/settings.json +10 -0
- package/mcps/after-effects-mcp/build/index.js +840 -0
- package/mcps/after-effects-mcp/build/scripts/applyEffect.jsx +153 -0
- package/mcps/after-effects-mcp/build/scripts/applyEffectTemplate.jsx +218 -0
- package/mcps/after-effects-mcp/build/scripts/createComposition.jsx +71 -0
- package/mcps/after-effects-mcp/build/scripts/createShapeLayer.jsx +147 -0
- package/mcps/after-effects-mcp/build/scripts/createSolidLayer.jsx +114 -0
- package/mcps/after-effects-mcp/build/scripts/createTextLayer.jsx +115 -0
- package/mcps/after-effects-mcp/build/scripts/getLayerInfo.jsx +192 -0
- package/mcps/after-effects-mcp/build/scripts/getProjectInfo.jsx +90 -0
- package/mcps/after-effects-mcp/build/scripts/listCompositions.jsx +50 -0
- package/mcps/after-effects-mcp/build/scripts/mcp-bridge-auto.jsx +1773 -0
- package/mcps/after-effects-mcp/build/scripts/setLayerProperties.jsx +160 -0
- package/mcps/computer-use-mcp/dist/client.d.ts +150 -0
- package/mcps/computer-use-mcp/dist/client.js +136 -0
- package/mcps/computer-use-mcp/dist/entrypoint.d.ts +16 -0
- package/mcps/computer-use-mcp/dist/entrypoint.js +26 -0
- package/mcps/computer-use-mcp/dist/native.d.ts +212 -0
- package/mcps/computer-use-mcp/dist/native.js +50 -0
- package/mcps/computer-use-mcp/dist/server.d.ts +32 -0
- package/mcps/computer-use-mcp/dist/server.js +342 -0
- package/mcps/computer-use-mcp/dist/session.d.ts +101 -0
- package/mcps/computer-use-mcp/dist/session.js +2372 -0
- package/package.json +13 -4
- package/skills/global_config/aos-project-init/SKILL.md +97 -130
- package/skills/global_config/aos-project-init/assets/openwikiignore.template +62 -0
- package/skills/global_config/aos-project-init/scripts/aos-project-doctor.mjs +38 -1
- package/skills/global_config/aos-setup/SKILL.md +98 -8
- package/skills/global_config/aos-setup/scripts/aos-doctor.mjs +21 -2
- package/skills/global_config/ask-tim/SKILL.md +2 -7
- package/skills/global_config/openwiki-skill/scripts/openwiki_daemon.py +65 -12
- package/bin/setup-saas.mjs +0 -792
- package/mcps/blender-mcp-server/.dockerignore +0 -19
- package/mcps/blender-mcp-server/.github/workflows/ci.yml +0 -67
- package/mcps/blender-mcp-server/.github/workflows/publish-pypi.yml +0 -54
- package/mcps/blender-mcp-server/CHANGELOG.md +0 -64
- package/mcps/blender-mcp-server/CONTRIBUTING.md +0 -107
- package/mcps/blender-mcp-server/Dockerfile +0 -19
- package/mcps/blender-mcp-server/LICENSE +0 -21
- package/mcps/blender-mcp-server/README.md +0 -409
- package/mcps/blender-mcp-server/addon/__init__.py +0 -1440
- package/mcps/blender-mcp-server/addon/models.py +0 -223
- package/mcps/blender-mcp-server/pyproject.toml +0 -120
- package/mcps/blender-mcp-server/scripts/blender_bridge_request.py +0 -71
- package/mcps/blender-mcp-server/scripts/blender_create_test_cube.py +0 -49
- package/mcps/blender-mcp-server/scripts/blender_scene_info.py +0 -38
- package/mcps/blender-mcp-server/scripts/build_addon_zip.sh +0 -29
- package/mcps/blender-mcp-server/scripts/demos/README.md +0 -186
- package/mcps/blender-mcp-server/scripts/demos/dam_break_scene.py +0 -276
- package/mcps/blender-mcp-server/scripts/demos/open_dam_break_gui.py +0 -33
- package/mcps/blender-mcp-server/scripts/demos/pipe_movement_study.py +0 -518
- package/mcps/blender-mcp-server/scripts/demos/pipe_pressure_failure_scene.py +0 -806
- package/mcps/blender-mcp-server/scripts/demos/procedural_dam_break_scene.py +0 -600
- package/mcps/blender-mcp-server/scripts/demos/run_dam_break.py +0 -510
- package/mcps/blender-mcp-server/scripts/launch_blender_gui.py +0 -41
- package/mcps/blender-mcp-server/scripts/library/README.md +0 -64
- package/mcps/blender-mcp-server/scripts/library/apply_transforms.py +0 -46
- package/mcps/blender-mcp-server/scripts/library/camera.py +0 -51
- package/mcps/blender-mcp-server/scripts/library/collections.py +0 -65
- package/mcps/blender-mcp-server/scripts/library/create_mesh.py +0 -41
- package/mcps/blender-mcp-server/scripts/library/effector.py +0 -48
- package/mcps/blender-mcp-server/scripts/library/fluid_domain.py +0 -80
- package/mcps/blender-mcp-server/scripts/library/fluid_inflow.py +0 -98
- package/mcps/blender-mcp-server/scripts/library/frame_range.py +0 -35
- package/mcps/blender-mcp-server/scripts/library/keyframes.py +0 -59
- package/mcps/blender-mcp-server/scripts/library/rigid_body.py +0 -52
- package/mcps/blender-mcp-server/scripts/library/save_blend.py +0 -40
- package/mcps/blender-mcp-server/scripts/server_start.sh +0 -26
- package/mcps/blender-mcp-server/src/blender_mcp_server/__init__.py +0 -3
- package/mcps/blender-mcp-server/src/blender_mcp_server/headless.py +0 -330
- package/mcps/blender-mcp-server/src/blender_mcp_server/server.py +0 -606
- package/mcps/davinci-mcp-professional/.bandit +0 -35
- package/mcps/davinci-mcp-professional/.claude/commands/security-review.md +0 -191
- package/mcps/davinci-mcp-professional/.claude/settings.json +0 -1
- package/mcps/davinci-mcp-professional/.editorconfig +0 -27
- package/mcps/davinci-mcp-professional/.gitattributes +0 -207
- package/mcps/davinci-mcp-professional/.github/CODEOWNERS +0 -2
- package/mcps/davinci-mcp-professional/.github/ISSUE_TEMPLATE/bug_report.md +0 -33
- package/mcps/davinci-mcp-professional/.github/ISSUE_TEMPLATE/feature_request.md +0 -19
- package/mcps/davinci-mcp-professional/.github/PULL_REQUEST_TEMPLATE.md +0 -20
- package/mcps/davinci-mcp-professional/.github/SECURITY.md +0 -97
- package/mcps/davinci-mcp-professional/.github/dependabot.yml +0 -27
- package/mcps/davinci-mcp-professional/.github/workflows/ci.yml +0 -39
- package/mcps/davinci-mcp-professional/ATTRIBUTION.md +0 -4
- package/mcps/davinci-mcp-professional/AUTHORS.md +0 -9
- package/mcps/davinci-mcp-professional/BUGS.md +0 -55
- package/mcps/davinci-mcp-professional/CLAUDE.md +0 -229
- package/mcps/davinci-mcp-professional/CONTRIBUTING.md +0 -51
- package/mcps/davinci-mcp-professional/COPYING.md +0 -228
- package/mcps/davinci-mcp-professional/Doxyfile +0 -379
- package/mcps/davinci-mcp-professional/README.md +0 -143
- package/mcps/davinci-mcp-professional/SECURITY.md +0 -40
- package/mcps/davinci-mcp-professional/USING.md +0 -301
- package/mcps/davinci-mcp-professional/VERSION.md +0 -13
- package/mcps/davinci-mcp-professional/build.py +0 -169
- package/mcps/davinci-mcp-professional/claude_desktop_config_template.json +0 -11
- package/mcps/davinci-mcp-professional/hooks/ci-check.sh +0 -29
- package/mcps/davinci-mcp-professional/hooks/pre-push +0 -46
- package/mcps/davinci-mcp-professional/main.py +0 -40
- package/mcps/davinci-mcp-professional/mcp_server.py +0 -30
- package/mcps/davinci-mcp-professional/pyproject.toml +0 -115
- package/mcps/davinci-mcp-professional/security_audit.py +0 -379
- package/mcps/davinci-mcp-professional/src/davinci_mcp/__init__.py +0 -19
- package/mcps/davinci-mcp-professional/src/davinci_mcp/cli.py +0 -138
- package/mcps/davinci-mcp-professional/src/davinci_mcp/resolve_client.py +0 -342
- package/mcps/davinci-mcp-professional/src/davinci_mcp/resources/__init__.py +0 -60
- package/mcps/davinci-mcp-professional/src/davinci_mcp/server.py +0 -185
- package/mcps/davinci-mcp-professional/src/davinci_mcp/tools/__init__.py +0 -146
- package/mcps/davinci-mcp-professional/src/davinci_mcp/types.py +0 -125
- package/mcps/davinci-mcp-professional/src/davinci_mcp/utils/__init__.py +0 -19
- package/mcps/davinci-mcp-professional/src/davinci_mcp/utils/platform.py +0 -239
- package/mcps/davinci-mcp-professional/test.py +0 -186
- package/mcps/davinci-mcp-professional/uv.lock +0 -2073
- package/mcps/davinci-resolve-mcp/.claude/skills/media-analysis.md +0 -44
- package/mcps/davinci-resolve-mcp/.clinerules +0 -17
- package/mcps/davinci-resolve-mcp/.cursorrules +0 -17
- package/mcps/davinci-resolve-mcp/.github/copilot-instructions.md +0 -17
- package/mcps/davinci-resolve-mcp/.github/workflows/npm-publish.yml +0 -109
- package/mcps/davinci-resolve-mcp/.windsurfrules +0 -17
- package/mcps/davinci-resolve-mcp/AGENTS.md +0 -114
- package/mcps/davinci-resolve-mcp/CHANGELOG.md +0 -2648
- package/mcps/davinci-resolve-mcp/CLAUDE.md +0 -15
- package/mcps/davinci-resolve-mcp/LICENSE +0 -21
- package/mcps/davinci-resolve-mcp/README.md +0 -173
- package/mcps/davinci-resolve-mcp/SECURITY.md +0 -53
- package/mcps/davinci-resolve-mcp/bin/davinci-resolve-mcp.mjs +0 -450
- package/mcps/davinci-resolve-mcp/examples/README.md +0 -53
- package/mcps/davinci-resolve-mcp/examples/markers/README.md +0 -81
- package/mcps/davinci-resolve-mcp/examples/media/README.md +0 -94
- package/mcps/davinci-resolve-mcp/examples/timeline/README.md +0 -98
- package/mcps/davinci-resolve-mcp/install.py +0 -1687
- package/mcps/davinci-resolve-mcp/package.json +0 -52
- package/mcps/davinci-resolve-mcp/release-notes/v2.22.0.md +0 -51
- package/mcps/davinci-resolve-mcp/release-notes/v2.23.0.md +0 -51
- package/mcps/davinci-resolve-mcp/release-notes/v2.23.1.md +0 -35
- package/mcps/davinci-resolve-mcp/release-notes/v2.24.1.md +0 -32
- package/mcps/davinci-resolve-mcp/scripts/audit_api_parity.py +0 -275
- package/mcps/davinci-resolve-mcp/scripts/audit_readwrite_symmetry.py +0 -80
- package/mcps/davinci-resolve-mcp/scripts/doctor.py +0 -227
- package/mcps/davinci-resolve-mcp/scripts/gen_api_limitations.py +0 -144
- package/mcps/davinci-resolve-mcp/scripts/live_media_analysis_polish_probe.py +0 -65
- package/mcps/davinci-resolve-mcp/scripts/measure_bridge_cost.py +0 -65
- package/mcps/davinci-resolve-mcp/scripts/regen_panel_screenshots.py +0 -76
- package/mcps/davinci-resolve-mcp/src/__init__.py +0 -3
- package/mcps/davinci-resolve-mcp/src/analysis_dashboard.py +0 -15505
- package/mcps/davinci-resolve-mcp/src/batch_cli.py +0 -540
- package/mcps/davinci-resolve-mcp/src/control_panel.py +0 -13
- package/mcps/davinci-resolve-mcp/src/granular/__init__.py +0 -17
- package/mcps/davinci-resolve-mcp/src/granular/common.py +0 -741
- package/mcps/davinci-resolve-mcp/src/granular/folder.py +0 -420
- package/mcps/davinci-resolve-mcp/src/granular/gallery.py +0 -306
- package/mcps/davinci-resolve-mcp/src/granular/graph.py +0 -309
- package/mcps/davinci-resolve-mcp/src/granular/media_pool.py +0 -679
- package/mcps/davinci-resolve-mcp/src/granular/media_pool_item.py +0 -1020
- package/mcps/davinci-resolve-mcp/src/granular/media_storage.py +0 -179
- package/mcps/davinci-resolve-mcp/src/granular/project.py +0 -1654
- package/mcps/davinci-resolve-mcp/src/granular/resolve_control.py +0 -538
- package/mcps/davinci-resolve-mcp/src/granular/timeline.py +0 -1075
- package/mcps/davinci-resolve-mcp/src/granular/timeline_item.py +0 -2251
- package/mcps/davinci-resolve-mcp/src/resolve_mcp_server.py +0 -43
- package/mcps/davinci-resolve-mcp/src/server.py +0 -24116
- package/mcps/davinci-resolve-mcp/src/utils/__init__.py +0 -3
- package/mcps/davinci-resolve-mcp/src/utils/actor_identity.py +0 -46
- package/mcps/davinci-resolve-mcp/src/utils/analysis_caps.py +0 -678
- package/mcps/davinci-resolve-mcp/src/utils/analysis_memory.py +0 -755
- package/mcps/davinci-resolve-mcp/src/utils/analysis_runs.py +0 -307
- package/mcps/davinci-resolve-mcp/src/utils/analysis_store.py +0 -945
- package/mcps/davinci-resolve-mcp/src/utils/api_truth.py +0 -525
- package/mcps/davinci-resolve-mcp/src/utils/app_control.py +0 -319
- package/mcps/davinci-resolve-mcp/src/utils/audio_fairlight_live_probe.py +0 -263
- package/mcps/davinci-resolve-mcp/src/utils/brain_edits.py +0 -387
- package/mcps/davinci-resolve-mcp/src/utils/bridge_metrics.py +0 -76
- package/mcps/davinci-resolve-mcp/src/utils/cdl.py +0 -20
- package/mcps/davinci-resolve-mcp/src/utils/clip_query.py +0 -85
- package/mcps/davinci-resolve-mcp/src/utils/cloud_operations.py +0 -192
- package/mcps/davinci-resolve-mcp/src/utils/color_grade_live_probe.py +0 -444
- package/mcps/davinci-resolve-mcp/src/utils/contracts.py +0 -102
- package/mcps/davinci-resolve-mcp/src/utils/cut_ir.py +0 -115
- package/mcps/davinci-resolve-mcp/src/utils/dctl_templates.py +0 -368
- package/mcps/davinci-resolve-mcp/src/utils/deep_vision.py +0 -643
- package/mcps/davinci-resolve-mcp/src/utils/destructive_hook.py +0 -606
- package/mcps/davinci-resolve-mcp/src/utils/edit_engine.py +0 -737
- package/mcps/davinci-resolve-mcp/src/utils/embeddings.py +0 -922
- package/mcps/davinci-resolve-mcp/src/utils/entities.py +0 -579
- package/mcps/davinci-resolve-mcp/src/utils/extension_authoring_live_probe.py +0 -292
- package/mcps/davinci-resolve-mcp/src/utils/failure_tracker.py +0 -119
- package/mcps/davinci-resolve-mcp/src/utils/fuse_templates.py +0 -1968
- package/mcps/davinci-resolve-mcp/src/utils/fusion_composition_live_probe.py +0 -284
- package/mcps/davinci-resolve-mcp/src/utils/fusion_group_settings.py +0 -334
- package/mcps/davinci-resolve-mcp/src/utils/layout_presets.py +0 -333
- package/mcps/davinci-resolve-mcp/src/utils/mcp_stdio.py +0 -32
- package/mcps/davinci-resolve-mcp/src/utils/mcp_transport.py +0 -128
- package/mcps/davinci-resolve-mcp/src/utils/media_analysis.py +0 -7690
- package/mcps/davinci-resolve-mcp/src/utils/media_analysis_jobs.py +0 -805
- package/mcps/davinci-resolve-mcp/src/utils/media_pool_changes.py +0 -121
- package/mcps/davinci-resolve-mcp/src/utils/media_pool_ingest_live_probe.py +0 -592
- package/mcps/davinci-resolve-mcp/src/utils/multicam.py +0 -393
- package/mcps/davinci-resolve-mcp/src/utils/object_inspection.py +0 -301
- package/mcps/davinci-resolve-mcp/src/utils/page_lock.py +0 -75
- package/mcps/davinci-resolve-mcp/src/utils/platform.py +0 -157
- package/mcps/davinci-resolve-mcp/src/utils/proc.py +0 -26
- package/mcps/davinci-resolve-mcp/src/utils/project_cleanup.py +0 -73
- package/mcps/davinci-resolve-mcp/src/utils/project_lifecycle_live_probe.py +0 -376
- package/mcps/davinci-resolve-mcp/src/utils/project_lint.py +0 -131
- package/mcps/davinci-resolve-mcp/src/utils/project_properties.py +0 -601
- package/mcps/davinci-resolve-mcp/src/utils/project_spec.py +0 -459
- package/mcps/davinci-resolve-mcp/src/utils/readback.py +0 -91
- package/mcps/davinci-resolve-mcp/src/utils/render_deliver_live_probe.py +0 -384
- package/mcps/davinci-resolve-mcp/src/utils/resolve_ai_governance.py +0 -214
- package/mcps/davinci-resolve-mcp/src/utils/resolve_ai_ledger.py +0 -244
- package/mcps/davinci-resolve-mcp/src/utils/resolve_busy.py +0 -171
- package/mcps/davinci-resolve-mcp/src/utils/resolve_connection.py +0 -77
- package/mcps/davinci-resolve-mcp/src/utils/review_annotation_live_probe.py +0 -352
- package/mcps/davinci-resolve-mcp/src/utils/script_templates.py +0 -1193
- package/mcps/davinci-resolve-mcp/src/utils/shot_relationships.py +0 -544
- package/mcps/davinci-resolve-mcp/src/utils/structural_diff.py +0 -175
- package/mcps/davinci-resolve-mcp/src/utils/sync_detection.py +0 -889
- package/mcps/davinci-resolve-mcp/src/utils/timeline_brain_db.py +0 -826
- package/mcps/davinci-resolve-mcp/src/utils/timeline_conform_live_probe.py +0 -280
- package/mcps/davinci-resolve-mcp/src/utils/timeline_kernel_live_probe.py +0 -1092
- package/mcps/davinci-resolve-mcp/src/utils/timeline_kernel_probe.py +0 -185
- package/mcps/davinci-resolve-mcp/src/utils/timeline_title_text.py +0 -87
- package/mcps/davinci-resolve-mcp/src/utils/timeline_versioning.py +0 -730
- package/mcps/davinci-resolve-mcp/src/utils/update_check.py +0 -685
- package/mcps/vectorworks-mcp/.dockerignore +0 -8
- package/mcps/vectorworks-mcp/Dockerfile +0 -28
- package/mcps/vectorworks-mcp/README.md +0 -156
- package/mcps/vectorworks-mcp/app/__init__.py +0 -2
- package/mcps/vectorworks-mcp/app/api.py +0 -52
- package/mcps/vectorworks-mcp/app/chunking.py +0 -56
- package/mcps/vectorworks-mcp/app/config.py +0 -29
- package/mcps/vectorworks-mcp/app/embeddings.py +0 -28
- package/mcps/vectorworks-mcp/app/indexer.py +0 -106
- package/mcps/vectorworks-mcp/app/main.py +0 -33
- package/mcps/vectorworks-mcp/app/mcp_server.py +0 -71
- package/mcps/vectorworks-mcp/app/search.py +0 -54
- package/mcps/vectorworks-mcp/app/utils.py +0 -14
- package/mcps/vectorworks-mcp/data/.gitkeep +0 -1
- package/mcps/vectorworks-mcp/data/vw-app-help/VW2022_PluginScript.htm +0 -95
- package/mcps/vectorworks-mcp/data/vw-app-help/VW2022_ScriptEditor.htm +0 -266
- package/mcps/vectorworks-mcp/data/vw-app-help/VW2022_Scripting.htm +0 -106
- package/mcps/vectorworks-mcp/data/vw-app-help/VW2023_CreatingScriptedPlugins.htm +0 -327
- package/mcps/vectorworks-mcp/data/vw-app-help/VW2024_RunningScripts.htm +0 -116
- package/mcps/vectorworks-mcp/data/vw-devwiki/VS_Function_Reference_category.html +0 -2129
- package/mcps/vectorworks-mcp/data/vw-jp-ref/ObjectsSymbols.html +0 -2035
- package/mcps/vectorworks-mcp/data/vw-jp-ref/ScriptFunctionReference.html +0 -29
- package/mcps/vectorworks-mcp/design.md +0 -57
- package/mcps/vectorworks-mcp/docker-compose.yml +0 -18
- package/mcps/vectorworks-mcp/index/.gitkeep +0 -1
- package/mcps/vectorworks-mcp/index/meta.jsonl +0 -3956
- package/mcps/vectorworks-mcp/index/vw.faiss +0 -0
- package/mcps/vectorworks-mcp/requirements.txt +0 -10
- package/mcps/vectorworks-mcp/scripts/fetch_docs_minimal.sh +0 -84
- package/mcps/vectorworks-mcp/scripts/fetch_github_vectorworks.sh +0 -85
- package/mcps/vectorworks-mcp/templates/index.html +0 -40
- package/scripts/ecosystem-health-audit.js +0 -257
- package/skills/bdb-dev-os-skill/SKILL.md +0 -49
- package/skills/bdb-dev-os-skill/package.json +0 -11
- package/skills/bdbsaastraining/SKILL.md +0 -316
- package/skills/bdbsaastraining/references/exam-pool.md +0 -313
- package/skills/bdbsaastraining/references/interaction-modes.md +0 -94
- package/skills/bdbsaastraining/references/track-a-ai-agent.md +0 -111
- package/skills/bdbsaastraining/references/track-b-wordpress.md +0 -111
- package/skills/bdbsaastraining/references/track-c-mailserver.md +0 -107
- package/skills/bdbsaastraining/references/track-d-debian.md +0 -109
- package/skills/bdbsaastraining/references/track-e-custom.md +0 -83
- package/skills/bdbsaastraining/scripts/build_profile.py +0 -529
- package/skills/bdbsaastraining/scripts/generate_certificate.py +0 -161
- package/skills/bdbsaastraining/scripts/preflight_check.sh +0 -150
- package/skills/bdbsaastraining/templates/certificate_template.html +0 -508
- package/skills/global_config/bdb-ecosystem-health/SKILL.md +0 -68
- package/skills/global_config/bdbsaas-ops/SKILL.md +0 -16
- package/skills/global_config/bdbsaashost/SKILL.md +0 -125
|
@@ -1,306 +0,0 @@
|
|
|
1
|
-
"""Gallery, still album, and powergrade tools."""
|
|
2
|
-
|
|
3
|
-
from src.granular.common import * # noqa: F401,F403
|
|
4
|
-
|
|
5
|
-
resolve = ResolveProxy()
|
|
6
|
-
|
|
7
|
-
@mcp.tool(annotations=READ_ONLY_TOOL)
|
|
8
|
-
def get_gallery_album_name() -> Dict[str, Any]:
|
|
9
|
-
"""Get the name of the current gallery album."""
|
|
10
|
-
resolve = get_resolve()
|
|
11
|
-
if resolve is None:
|
|
12
|
-
return {"error": "Not connected to DaVinci Resolve"}
|
|
13
|
-
project = resolve.GetProjectManager().GetCurrentProject()
|
|
14
|
-
if not project:
|
|
15
|
-
return {"error": "No project open"}
|
|
16
|
-
gallery = project.GetGallery()
|
|
17
|
-
if not gallery:
|
|
18
|
-
return {"error": "Failed to get Gallery"}
|
|
19
|
-
name = gallery.GetAlbumName()
|
|
20
|
-
return {"album_name": name if name else ""}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
@mcp.tool()
|
|
24
|
-
def set_gallery_album_name(name: str) -> Dict[str, Any]:
|
|
25
|
-
"""Set the name of the current gallery album.
|
|
26
|
-
|
|
27
|
-
Args:
|
|
28
|
-
name: New album name.
|
|
29
|
-
"""
|
|
30
|
-
resolve = get_resolve()
|
|
31
|
-
if resolve is None:
|
|
32
|
-
return {"error": "Not connected to DaVinci Resolve"}
|
|
33
|
-
project = resolve.GetProjectManager().GetCurrentProject()
|
|
34
|
-
if not project:
|
|
35
|
-
return {"error": "No project open"}
|
|
36
|
-
gallery = project.GetGallery()
|
|
37
|
-
if not gallery:
|
|
38
|
-
return {"error": "Failed to get Gallery"}
|
|
39
|
-
result = gallery.SetAlbumName(name)
|
|
40
|
-
return {"success": bool(result)}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
@mcp.tool()
|
|
44
|
-
def get_gallery_still_albums() -> Dict[str, Any]:
|
|
45
|
-
"""Get list of all gallery still albums."""
|
|
46
|
-
resolve = get_resolve()
|
|
47
|
-
if resolve is None:
|
|
48
|
-
return {"error": "Not connected to DaVinci Resolve"}
|
|
49
|
-
project = resolve.GetProjectManager().GetCurrentProject()
|
|
50
|
-
if not project:
|
|
51
|
-
return {"error": "No project open"}
|
|
52
|
-
gallery = project.GetGallery()
|
|
53
|
-
if not gallery:
|
|
54
|
-
return {"error": "Failed to get Gallery"}
|
|
55
|
-
albums = gallery.GetGalleryStillAlbums()
|
|
56
|
-
return {"albums": [str(a) for a in albums] if albums else []}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
@mcp.tool()
|
|
60
|
-
def get_gallery_power_grade_albums() -> Dict[str, Any]:
|
|
61
|
-
"""Get list of all gallery power grade albums."""
|
|
62
|
-
resolve = get_resolve()
|
|
63
|
-
if resolve is None:
|
|
64
|
-
return {"error": "Not connected to DaVinci Resolve"}
|
|
65
|
-
project = resolve.GetProjectManager().GetCurrentProject()
|
|
66
|
-
if not project:
|
|
67
|
-
return {"error": "No project open"}
|
|
68
|
-
gallery = project.GetGallery()
|
|
69
|
-
if not gallery:
|
|
70
|
-
return {"error": "Failed to get Gallery"}
|
|
71
|
-
albums = gallery.GetGalleryPowerGradeAlbums()
|
|
72
|
-
return {"albums": [str(a) for a in albums] if albums else []}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
@mcp.tool()
|
|
76
|
-
def get_current_still_album() -> Dict[str, Any]:
|
|
77
|
-
"""Get the current still album."""
|
|
78
|
-
resolve = get_resolve()
|
|
79
|
-
if resolve is None:
|
|
80
|
-
return {"error": "Not connected to DaVinci Resolve"}
|
|
81
|
-
project = resolve.GetProjectManager().GetCurrentProject()
|
|
82
|
-
if not project:
|
|
83
|
-
return {"error": "No project open"}
|
|
84
|
-
gallery = project.GetGallery()
|
|
85
|
-
if not gallery:
|
|
86
|
-
return {"error": "Failed to get Gallery"}
|
|
87
|
-
album = gallery.GetCurrentStillAlbum()
|
|
88
|
-
return {"has_album": album is not None}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
@mcp.tool()
|
|
92
|
-
def set_current_still_album(album_index: int) -> Dict[str, Any]:
|
|
93
|
-
"""Set the current still album by index.
|
|
94
|
-
|
|
95
|
-
Args:
|
|
96
|
-
album_index: 0-based index of the album in GetGalleryStillAlbums() list.
|
|
97
|
-
"""
|
|
98
|
-
resolve = get_resolve()
|
|
99
|
-
if resolve is None:
|
|
100
|
-
return {"error": "Not connected to DaVinci Resolve"}
|
|
101
|
-
project = resolve.GetProjectManager().GetCurrentProject()
|
|
102
|
-
if not project:
|
|
103
|
-
return {"error": "No project open"}
|
|
104
|
-
gallery = project.GetGallery()
|
|
105
|
-
if not gallery:
|
|
106
|
-
return {"error": "Failed to get Gallery"}
|
|
107
|
-
albums = gallery.GetGalleryStillAlbums()
|
|
108
|
-
if not albums or album_index >= len(albums):
|
|
109
|
-
return {"error": f"No album at index {album_index}"}
|
|
110
|
-
result = gallery.SetCurrentStillAlbum(albums[album_index])
|
|
111
|
-
return {"success": bool(result)}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
@mcp.tool()
|
|
115
|
-
def create_gallery_still_album(album_name: str = "") -> Dict[str, Any]:
|
|
116
|
-
"""Create a new gallery still album.
|
|
117
|
-
|
|
118
|
-
Args:
|
|
119
|
-
album_name: Optional name for the new album.
|
|
120
|
-
"""
|
|
121
|
-
resolve = get_resolve()
|
|
122
|
-
if resolve is None:
|
|
123
|
-
return {"error": "Not connected to DaVinci Resolve"}
|
|
124
|
-
project = resolve.GetProjectManager().GetCurrentProject()
|
|
125
|
-
if not project:
|
|
126
|
-
return {"error": "No project open"}
|
|
127
|
-
gallery = project.GetGallery()
|
|
128
|
-
if not gallery:
|
|
129
|
-
return {"error": "Failed to get Gallery"}
|
|
130
|
-
if album_name:
|
|
131
|
-
album = gallery.CreateGalleryStillAlbum(album_name)
|
|
132
|
-
else:
|
|
133
|
-
album = gallery.CreateGalleryStillAlbum()
|
|
134
|
-
return {"success": album is not None}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
@mcp.tool()
|
|
138
|
-
def create_gallery_power_grade_album(album_name: str = "") -> Dict[str, Any]:
|
|
139
|
-
"""Create a new gallery power grade album.
|
|
140
|
-
|
|
141
|
-
Args:
|
|
142
|
-
album_name: Optional name for the new album.
|
|
143
|
-
"""
|
|
144
|
-
resolve = get_resolve()
|
|
145
|
-
if resolve is None:
|
|
146
|
-
return {"error": "Not connected to DaVinci Resolve"}
|
|
147
|
-
project = resolve.GetProjectManager().GetCurrentProject()
|
|
148
|
-
if not project:
|
|
149
|
-
return {"error": "No project open"}
|
|
150
|
-
gallery = project.GetGallery()
|
|
151
|
-
if not gallery:
|
|
152
|
-
return {"error": "Failed to get Gallery"}
|
|
153
|
-
if album_name:
|
|
154
|
-
album = gallery.CreateGalleryPowerGradeAlbum(album_name)
|
|
155
|
-
else:
|
|
156
|
-
album = gallery.CreateGalleryPowerGradeAlbum()
|
|
157
|
-
return {"success": album is not None}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
@mcp.tool()
|
|
161
|
-
def get_album_stills(album_index: int = 0) -> Dict[str, Any]:
|
|
162
|
-
"""Get list of stills in a gallery album.
|
|
163
|
-
|
|
164
|
-
Args:
|
|
165
|
-
album_index: 0-based index of the album. Default: 0.
|
|
166
|
-
"""
|
|
167
|
-
resolve = get_resolve()
|
|
168
|
-
if resolve is None:
|
|
169
|
-
return {"error": "Not connected to DaVinci Resolve"}
|
|
170
|
-
project = resolve.GetProjectManager().GetCurrentProject()
|
|
171
|
-
if not project:
|
|
172
|
-
return {"error": "No project open"}
|
|
173
|
-
gallery = project.GetGallery()
|
|
174
|
-
if not gallery:
|
|
175
|
-
return {"error": "Failed to get Gallery"}
|
|
176
|
-
albums = gallery.GetGalleryStillAlbums()
|
|
177
|
-
if not albums or album_index >= len(albums):
|
|
178
|
-
return {"error": f"No album at index {album_index}"}
|
|
179
|
-
stills = albums[album_index].GetStills()
|
|
180
|
-
return {"still_count": len(stills) if stills else 0}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
@mcp.tool()
|
|
184
|
-
def get_still_label(album_index: int, still_index: int) -> Dict[str, Any]:
|
|
185
|
-
"""Get the label of a still in a gallery album.
|
|
186
|
-
|
|
187
|
-
Args:
|
|
188
|
-
album_index: 0-based album index.
|
|
189
|
-
still_index: 0-based still index.
|
|
190
|
-
"""
|
|
191
|
-
resolve = get_resolve()
|
|
192
|
-
if resolve is None:
|
|
193
|
-
return {"error": "Not connected to DaVinci Resolve"}
|
|
194
|
-
project = resolve.GetProjectManager().GetCurrentProject()
|
|
195
|
-
if not project:
|
|
196
|
-
return {"error": "No project open"}
|
|
197
|
-
gallery = project.GetGallery()
|
|
198
|
-
albums = gallery.GetGalleryStillAlbums()
|
|
199
|
-
if not albums or album_index >= len(albums):
|
|
200
|
-
return {"error": f"No album at index {album_index}"}
|
|
201
|
-
stills = albums[album_index].GetStills()
|
|
202
|
-
if not stills or still_index >= len(stills):
|
|
203
|
-
return {"error": f"No still at index {still_index}"}
|
|
204
|
-
label = albums[album_index].GetLabel(stills[still_index])
|
|
205
|
-
return {"label": label if label else ""}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
@mcp.tool()
|
|
209
|
-
def set_still_label(album_index: int, still_index: int, label: str) -> Dict[str, Any]:
|
|
210
|
-
"""Set the label of a still in a gallery album.
|
|
211
|
-
|
|
212
|
-
Args:
|
|
213
|
-
album_index: 0-based album index.
|
|
214
|
-
still_index: 0-based still index.
|
|
215
|
-
label: New label for the still.
|
|
216
|
-
"""
|
|
217
|
-
resolve = get_resolve()
|
|
218
|
-
if resolve is None:
|
|
219
|
-
return {"error": "Not connected to DaVinci Resolve"}
|
|
220
|
-
project = resolve.GetProjectManager().GetCurrentProject()
|
|
221
|
-
if not project:
|
|
222
|
-
return {"error": "No project open"}
|
|
223
|
-
gallery = project.GetGallery()
|
|
224
|
-
albums = gallery.GetGalleryStillAlbums()
|
|
225
|
-
if not albums or album_index >= len(albums):
|
|
226
|
-
return {"error": f"No album at index {album_index}"}
|
|
227
|
-
stills = albums[album_index].GetStills()
|
|
228
|
-
if not stills or still_index >= len(stills):
|
|
229
|
-
return {"error": f"No still at index {still_index}"}
|
|
230
|
-
result = albums[album_index].SetLabel(stills[still_index], label)
|
|
231
|
-
return {"success": bool(result)}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
@mcp.tool()
|
|
235
|
-
def import_stills_to_album(album_index: int, file_paths: List[str]) -> Dict[str, Any]:
|
|
236
|
-
"""Import stills from file paths into a gallery album.
|
|
237
|
-
|
|
238
|
-
Args:
|
|
239
|
-
album_index: 0-based album index.
|
|
240
|
-
file_paths: List of absolute file paths to import.
|
|
241
|
-
"""
|
|
242
|
-
resolve = get_resolve()
|
|
243
|
-
if resolve is None:
|
|
244
|
-
return {"error": "Not connected to DaVinci Resolve"}
|
|
245
|
-
project = resolve.GetProjectManager().GetCurrentProject()
|
|
246
|
-
if not project:
|
|
247
|
-
return {"error": "No project open"}
|
|
248
|
-
gallery = project.GetGallery()
|
|
249
|
-
albums = gallery.GetGalleryStillAlbums()
|
|
250
|
-
if not albums or album_index >= len(albums):
|
|
251
|
-
return {"error": f"No album at index {album_index}"}
|
|
252
|
-
result = albums[album_index].ImportStills(file_paths)
|
|
253
|
-
return {"success": bool(result)}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
@mcp.tool()
|
|
257
|
-
def export_stills_from_album(album_index: int, folder_path: str, file_prefix: str = "still", format: str = "dpx") -> Dict[str, Any]:
|
|
258
|
-
"""Export stills from a gallery album.
|
|
259
|
-
|
|
260
|
-
Args:
|
|
261
|
-
album_index: 0-based album index.
|
|
262
|
-
folder_path: Directory to export to.
|
|
263
|
-
file_prefix: Filename prefix. Default: 'still'.
|
|
264
|
-
format: File format (dpx, cin, tif, jpg, png, ppm, bmp, xpm, drx). Default: 'dpx'.
|
|
265
|
-
"""
|
|
266
|
-
resolve = get_resolve()
|
|
267
|
-
if resolve is None:
|
|
268
|
-
return {"error": "Not connected to DaVinci Resolve"}
|
|
269
|
-
project = resolve.GetProjectManager().GetCurrentProject()
|
|
270
|
-
if not project:
|
|
271
|
-
return {"error": "No project open"}
|
|
272
|
-
gallery = project.GetGallery()
|
|
273
|
-
albums = gallery.GetGalleryStillAlbums()
|
|
274
|
-
if not albums or album_index >= len(albums):
|
|
275
|
-
return {"error": f"No album at index {album_index}"}
|
|
276
|
-
stills = albums[album_index].GetStills()
|
|
277
|
-
if not stills:
|
|
278
|
-
return {"error": "No stills in album"}
|
|
279
|
-
result = albums[album_index].ExportStills(stills, folder_path, file_prefix, format)
|
|
280
|
-
return {"success": bool(result)}
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
@mcp.tool()
|
|
284
|
-
def delete_stills_from_album(album_index: int, still_indices: List[int]) -> Dict[str, Any]:
|
|
285
|
-
"""Delete stills from a gallery album.
|
|
286
|
-
|
|
287
|
-
Args:
|
|
288
|
-
album_index: 0-based album index.
|
|
289
|
-
still_indices: List of 0-based still indices to delete.
|
|
290
|
-
"""
|
|
291
|
-
resolve = get_resolve()
|
|
292
|
-
if resolve is None:
|
|
293
|
-
return {"error": "Not connected to DaVinci Resolve"}
|
|
294
|
-
project = resolve.GetProjectManager().GetCurrentProject()
|
|
295
|
-
if not project:
|
|
296
|
-
return {"error": "No project open"}
|
|
297
|
-
gallery = project.GetGallery()
|
|
298
|
-
albums = gallery.GetGalleryStillAlbums()
|
|
299
|
-
if not albums or album_index >= len(albums):
|
|
300
|
-
return {"error": f"No album at index {album_index}"}
|
|
301
|
-
stills = albums[album_index].GetStills()
|
|
302
|
-
if not stills:
|
|
303
|
-
return {"error": "No stills in album"}
|
|
304
|
-
to_delete = [stills[i] for i in still_indices if i < len(stills)]
|
|
305
|
-
result = albums[album_index].DeleteStills(to_delete)
|
|
306
|
-
return {"success": bool(result)}
|
|
@@ -1,309 +0,0 @@
|
|
|
1
|
-
"""Color page graph, LUT, and color-group tools."""
|
|
2
|
-
|
|
3
|
-
from src.granular.common import * # noqa: F401,F403
|
|
4
|
-
|
|
5
|
-
resolve = ResolveProxy()
|
|
6
|
-
|
|
7
|
-
@mcp.tool()
|
|
8
|
-
def graph_get_num_nodes(item_index: int = 0, track_type: str = "video", track_index: int = 1) -> Dict[str, Any]:
|
|
9
|
-
"""Get number of nodes in the color graph for a timeline item.
|
|
10
|
-
|
|
11
|
-
Args:
|
|
12
|
-
item_index: 0-based item index. Default: 0.
|
|
13
|
-
track_type: 'video' or 'audio'. Default: 'video'.
|
|
14
|
-
track_index: 1-based track index. Default: 1.
|
|
15
|
-
"""
|
|
16
|
-
item, err = _get_timeline_item(track_type, track_index, item_index)
|
|
17
|
-
if err:
|
|
18
|
-
return err
|
|
19
|
-
graph = item.GetNodeGraph()
|
|
20
|
-
if not graph:
|
|
21
|
-
return {"error": "No node graph available"}
|
|
22
|
-
return {"num_nodes": graph.GetNumNodes()}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
@mcp.tool()
|
|
26
|
-
def graph_set_lut(node_index: int, lut_path: str, item_index: int = 0, track_type: str = "video", track_index: int = 1) -> Dict[str, Any]:
|
|
27
|
-
"""Set LUT on a node in the color graph.
|
|
28
|
-
|
|
29
|
-
Args:
|
|
30
|
-
node_index: 1-based node index.
|
|
31
|
-
lut_path: Absolute or relative LUT path.
|
|
32
|
-
item_index: 0-based timeline item index. Default: 0.
|
|
33
|
-
track_type: 'video' or 'audio'. Default: 'video'.
|
|
34
|
-
track_index: 1-based track index. Default: 1.
|
|
35
|
-
"""
|
|
36
|
-
item, err = _get_timeline_item(track_type, track_index, item_index)
|
|
37
|
-
if err:
|
|
38
|
-
return err
|
|
39
|
-
graph = item.GetNodeGraph()
|
|
40
|
-
if not graph:
|
|
41
|
-
return {"error": "No node graph available"}
|
|
42
|
-
result = graph.SetLUT(node_index, lut_path)
|
|
43
|
-
return {"success": bool(result)}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
@mcp.tool()
|
|
47
|
-
def graph_get_lut(node_index: int, item_index: int = 0, track_type: str = "video", track_index: int = 1) -> Dict[str, Any]:
|
|
48
|
-
"""Get LUT path on a node in the color graph.
|
|
49
|
-
|
|
50
|
-
Args:
|
|
51
|
-
node_index: 1-based node index.
|
|
52
|
-
item_index: 0-based timeline item index. Default: 0.
|
|
53
|
-
track_type: 'video' or 'audio'. Default: 'video'.
|
|
54
|
-
track_index: 1-based track index. Default: 1.
|
|
55
|
-
"""
|
|
56
|
-
item, err = _get_timeline_item(track_type, track_index, item_index)
|
|
57
|
-
if err:
|
|
58
|
-
return err
|
|
59
|
-
graph = item.GetNodeGraph()
|
|
60
|
-
if not graph:
|
|
61
|
-
return {"error": "No node graph available"}
|
|
62
|
-
lut = graph.GetLUT(node_index)
|
|
63
|
-
return {"node_index": node_index, "lut_path": lut if lut else ""}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
@mcp.tool()
|
|
67
|
-
def graph_set_node_cache_mode(node_index: int, cache_value: int, item_index: int = 0, track_type: str = "video", track_index: int = 1) -> Dict[str, Any]:
|
|
68
|
-
"""Set the cache mode on a node.
|
|
69
|
-
|
|
70
|
-
Args:
|
|
71
|
-
node_index: 1-based node index.
|
|
72
|
-
cache_value: -1=Auto, 0=Disabled, 1=Enabled.
|
|
73
|
-
item_index: 0-based timeline item index. Default: 0.
|
|
74
|
-
track_type: 'video' or 'audio'. Default: 'video'.
|
|
75
|
-
track_index: 1-based track index. Default: 1.
|
|
76
|
-
"""
|
|
77
|
-
item, err = _get_timeline_item(track_type, track_index, item_index)
|
|
78
|
-
if err:
|
|
79
|
-
return err
|
|
80
|
-
graph = item.GetNodeGraph()
|
|
81
|
-
if not graph:
|
|
82
|
-
return {"error": "No node graph available"}
|
|
83
|
-
result = graph.SetNodeCacheMode(node_index, cache_value)
|
|
84
|
-
return {"success": bool(result)}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
@mcp.tool()
|
|
88
|
-
def graph_get_node_cache_mode(node_index: int, item_index: int = 0, track_type: str = "video", track_index: int = 1) -> Dict[str, Any]:
|
|
89
|
-
"""Get the cache mode of a node.
|
|
90
|
-
|
|
91
|
-
Args:
|
|
92
|
-
node_index: 1-based node index.
|
|
93
|
-
item_index: 0-based timeline item index. Default: 0.
|
|
94
|
-
track_type: 'video' or 'audio'. Default: 'video'.
|
|
95
|
-
track_index: 1-based track index. Default: 1.
|
|
96
|
-
"""
|
|
97
|
-
item, err = _get_timeline_item(track_type, track_index, item_index)
|
|
98
|
-
if err:
|
|
99
|
-
return err
|
|
100
|
-
graph = item.GetNodeGraph()
|
|
101
|
-
if not graph:
|
|
102
|
-
return {"error": "No node graph available"}
|
|
103
|
-
mode = graph.GetNodeCacheMode(node_index)
|
|
104
|
-
modes = {-1: "Auto", 0: "Disabled", 1: "Enabled"}
|
|
105
|
-
return {"node_index": node_index, "cache_mode": mode, "mode_name": modes.get(mode, "Unknown")}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
@mcp.tool()
|
|
109
|
-
def graph_get_node_label(node_index: int, item_index: int = 0, track_type: str = "video", track_index: int = 1) -> Dict[str, Any]:
|
|
110
|
-
"""Get the label of a node.
|
|
111
|
-
|
|
112
|
-
Args:
|
|
113
|
-
node_index: 1-based node index.
|
|
114
|
-
item_index: 0-based timeline item index. Default: 0.
|
|
115
|
-
track_type: 'video' or 'audio'. Default: 'video'.
|
|
116
|
-
track_index: 1-based track index. Default: 1.
|
|
117
|
-
"""
|
|
118
|
-
item, err = _get_timeline_item(track_type, track_index, item_index)
|
|
119
|
-
if err:
|
|
120
|
-
return err
|
|
121
|
-
graph = item.GetNodeGraph()
|
|
122
|
-
if not graph:
|
|
123
|
-
return {"error": "No node graph available"}
|
|
124
|
-
label = graph.GetNodeLabel(node_index)
|
|
125
|
-
return {"node_index": node_index, "label": label if label else ""}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
@mcp.tool()
|
|
129
|
-
def graph_get_tools_in_node(node_index: int, item_index: int = 0, track_type: str = "video", track_index: int = 1) -> Dict[str, Any]:
|
|
130
|
-
"""Get list of tools used in a node.
|
|
131
|
-
|
|
132
|
-
Args:
|
|
133
|
-
node_index: 1-based node index.
|
|
134
|
-
item_index: 0-based timeline item index. Default: 0.
|
|
135
|
-
track_type: 'video' or 'audio'. Default: 'video'.
|
|
136
|
-
track_index: 1-based track index. Default: 1.
|
|
137
|
-
"""
|
|
138
|
-
item, err = _get_timeline_item(track_type, track_index, item_index)
|
|
139
|
-
if err:
|
|
140
|
-
return err
|
|
141
|
-
graph = item.GetNodeGraph()
|
|
142
|
-
if not graph:
|
|
143
|
-
return {"error": "No node graph available"}
|
|
144
|
-
tools = graph.GetToolsInNode(node_index)
|
|
145
|
-
return {"node_index": node_index, "tools": tools if tools else []}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
@mcp.tool()
|
|
149
|
-
def graph_set_node_enabled(node_index: int, is_enabled: bool, item_index: int = 0, track_type: str = "video", track_index: int = 1) -> Dict[str, Any]:
|
|
150
|
-
"""Enable or disable a node.
|
|
151
|
-
|
|
152
|
-
Args:
|
|
153
|
-
node_index: 1-based node index.
|
|
154
|
-
is_enabled: True to enable, False to disable.
|
|
155
|
-
item_index: 0-based timeline item index. Default: 0.
|
|
156
|
-
track_type: 'video' or 'audio'. Default: 'video'.
|
|
157
|
-
track_index: 1-based track index. Default: 1.
|
|
158
|
-
"""
|
|
159
|
-
item, err = _get_timeline_item(track_type, track_index, item_index)
|
|
160
|
-
if err:
|
|
161
|
-
return err
|
|
162
|
-
graph = item.GetNodeGraph()
|
|
163
|
-
if not graph:
|
|
164
|
-
return {"error": "No node graph available"}
|
|
165
|
-
result = graph.SetNodeEnabled(node_index, is_enabled)
|
|
166
|
-
return {"success": bool(result)}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
@mcp.tool()
|
|
170
|
-
def graph_apply_grade_from_drx(drx_path: str, grade_mode: int = 0, item_index: int = 0, track_type: str = "video", track_index: int = 1) -> Dict[str, Any]:
|
|
171
|
-
"""Apply a grade from a .drx file to a timeline item's graph.
|
|
172
|
-
|
|
173
|
-
Args:
|
|
174
|
-
drx_path: Absolute path to the .drx file.
|
|
175
|
-
grade_mode: 0=No keyframes, 1=Source Timecode aligned, 2=Start Frames aligned.
|
|
176
|
-
item_index: 0-based timeline item index. Default: 0.
|
|
177
|
-
track_type: 'video' or 'audio'. Default: 'video'.
|
|
178
|
-
track_index: 1-based track index. Default: 1.
|
|
179
|
-
"""
|
|
180
|
-
item, err = _get_timeline_item(track_type, track_index, item_index)
|
|
181
|
-
if err:
|
|
182
|
-
return err
|
|
183
|
-
graph = item.GetNodeGraph()
|
|
184
|
-
if not graph:
|
|
185
|
-
return {"error": "No node graph available"}
|
|
186
|
-
result = graph.ApplyGradeFromDRX(drx_path, grade_mode)
|
|
187
|
-
return {"success": bool(result)}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
@mcp.tool()
|
|
191
|
-
def graph_apply_arri_cdl_lut(item_index: int = 0, track_type: str = "video", track_index: int = 1) -> Dict[str, Any]:
|
|
192
|
-
"""Apply ARRI CDL and LUT to a timeline item's graph.
|
|
193
|
-
|
|
194
|
-
Args:
|
|
195
|
-
item_index: 0-based timeline item index. Default: 0.
|
|
196
|
-
track_type: 'video' or 'audio'. Default: 'video'.
|
|
197
|
-
track_index: 1-based track index. Default: 1.
|
|
198
|
-
"""
|
|
199
|
-
item, err = _get_timeline_item(track_type, track_index, item_index)
|
|
200
|
-
if err:
|
|
201
|
-
return err
|
|
202
|
-
graph = item.GetNodeGraph()
|
|
203
|
-
if not graph:
|
|
204
|
-
return {"error": "No node graph available"}
|
|
205
|
-
result = graph.ApplyArriCdlLut()
|
|
206
|
-
return {"success": bool(result)}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
@mcp.tool()
|
|
210
|
-
def graph_reset_all_grades(item_index: int = 0, track_type: str = "video", track_index: int = 1) -> Dict[str, Any]:
|
|
211
|
-
"""Reset all grades on a timeline item's graph.
|
|
212
|
-
|
|
213
|
-
Args:
|
|
214
|
-
item_index: 0-based timeline item index. Default: 0.
|
|
215
|
-
track_type: 'video' or 'audio'. Default: 'video'.
|
|
216
|
-
track_index: 1-based track index. Default: 1.
|
|
217
|
-
"""
|
|
218
|
-
item, err = _get_timeline_item(track_type, track_index, item_index)
|
|
219
|
-
if err:
|
|
220
|
-
return err
|
|
221
|
-
graph = item.GetNodeGraph()
|
|
222
|
-
if not graph:
|
|
223
|
-
return {"error": "No node graph available"}
|
|
224
|
-
result = graph.ResetAllGrades()
|
|
225
|
-
return {"success": bool(result)}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
@mcp.tool()
|
|
229
|
-
def get_color_group_clips(group_name: str) -> Dict[str, Any]:
|
|
230
|
-
"""Get clips in a color group for the current timeline.
|
|
231
|
-
|
|
232
|
-
Args:
|
|
233
|
-
group_name: Name of the color group.
|
|
234
|
-
"""
|
|
235
|
-
resolve = get_resolve()
|
|
236
|
-
if resolve is None:
|
|
237
|
-
return {"error": "Not connected to DaVinci Resolve"}
|
|
238
|
-
project = resolve.GetProjectManager().GetCurrentProject()
|
|
239
|
-
if not project:
|
|
240
|
-
return {"error": "No project open"}
|
|
241
|
-
groups = project.GetColorGroupsList()
|
|
242
|
-
target = None
|
|
243
|
-
if groups:
|
|
244
|
-
for g in groups:
|
|
245
|
-
if g.GetName() == group_name:
|
|
246
|
-
target = g
|
|
247
|
-
break
|
|
248
|
-
if not target:
|
|
249
|
-
return {"error": f"Color group '{group_name}' not found"}
|
|
250
|
-
clips = target.GetClipsInTimeline()
|
|
251
|
-
if clips:
|
|
252
|
-
return {"group": group_name, "clips": [{"name": c.GetName()} for c in clips]}
|
|
253
|
-
return {"group": group_name, "clips": []}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
@mcp.tool()
|
|
257
|
-
def get_color_group_pre_clip_node_graph(group_name: str) -> Dict[str, Any]:
|
|
258
|
-
"""Get the pre-clip node graph for a color group.
|
|
259
|
-
|
|
260
|
-
Args:
|
|
261
|
-
group_name: Name of the color group.
|
|
262
|
-
"""
|
|
263
|
-
resolve = get_resolve()
|
|
264
|
-
if resolve is None:
|
|
265
|
-
return {"error": "Not connected to DaVinci Resolve"}
|
|
266
|
-
project = resolve.GetProjectManager().GetCurrentProject()
|
|
267
|
-
if not project:
|
|
268
|
-
return {"error": "No project open"}
|
|
269
|
-
groups = project.GetColorGroupsList()
|
|
270
|
-
target = None
|
|
271
|
-
if groups:
|
|
272
|
-
for g in groups:
|
|
273
|
-
if g.GetName() == group_name:
|
|
274
|
-
target = g
|
|
275
|
-
break
|
|
276
|
-
if not target:
|
|
277
|
-
return {"error": f"Color group '{group_name}' not found"}
|
|
278
|
-
graph = target.GetPreClipNodeGraph()
|
|
279
|
-
if graph:
|
|
280
|
-
return {"group": group_name, "graph_type": "pre_clip", "num_nodes": graph.GetNumNodes()}
|
|
281
|
-
return {"error": "No pre-clip node graph available"}
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
@mcp.tool()
|
|
285
|
-
def get_color_group_post_clip_node_graph(group_name: str) -> Dict[str, Any]:
|
|
286
|
-
"""Get the post-clip node graph for a color group.
|
|
287
|
-
|
|
288
|
-
Args:
|
|
289
|
-
group_name: Name of the color group.
|
|
290
|
-
"""
|
|
291
|
-
resolve = get_resolve()
|
|
292
|
-
if resolve is None:
|
|
293
|
-
return {"error": "Not connected to DaVinci Resolve"}
|
|
294
|
-
project = resolve.GetProjectManager().GetCurrentProject()
|
|
295
|
-
if not project:
|
|
296
|
-
return {"error": "No project open"}
|
|
297
|
-
groups = project.GetColorGroupsList()
|
|
298
|
-
target = None
|
|
299
|
-
if groups:
|
|
300
|
-
for g in groups:
|
|
301
|
-
if g.GetName() == group_name:
|
|
302
|
-
target = g
|
|
303
|
-
break
|
|
304
|
-
if not target:
|
|
305
|
-
return {"error": f"Color group '{group_name}' not found"}
|
|
306
|
-
graph = target.GetPostClipNodeGraph()
|
|
307
|
-
if graph:
|
|
308
|
-
return {"group": group_name, "graph_type": "post_clip", "num_nodes": graph.GetNumNodes()}
|
|
309
|
-
return {"error": "No post-clip node graph available"}
|