@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.
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 +387 -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,94 +0,0 @@
1
- # Interaktionsmodi — Dual-Mode Kontrakt
2
-
3
- Der Trainings-Skill läuft in fünf Clients. Nur **Claude Code** hat ein natives Auswahl-Tool.
4
- Der Tutor erkennt den Client aus Station 0 (`<CLIENT_NAME>`) und wählt den Modus **einmal** für die gesamte Session.
5
-
6
- ---
7
-
8
- ## Modus 1 — Claude Code: `AskUserQuestion`
9
-
10
- Nutze das Tool für **jede** strukturierte Auswahl:
11
- - Track-Wahl (Station 0, Teil B)
12
- - Sizing-/Konfig-Entscheidungen (CPU/RAM/Disk, DNS-Proxy-Modus, Auth ja/nein)
13
- - alle Multiple-Choice-Verständnisfragen
14
- - alle 10 Abschlussfragen
15
-
16
- Regeln:
17
- - 2–4 echte Optionen pro Frage. Die vom Skill empfohlene Option steht an Position 1 mit `(Empfohlen)` im Label.
18
- - `header` ≤ 12 Zeichen (z. B. `Track`, `RAM`, `DNS-Modus`, `Frage 3`).
19
- - **„Other" (Freitext) fügt das Tool automatisch hinzu** — nicht selbst als Option auflisten.
20
- - `preview` einsetzen, wenn **Vergleich** der Kern ist: YAML-Profilvarianten nebeneinander, Ressourcen-Sizing, `🟠 proxied` vs `⚪ DNS-only`. NICHT bei einfachen Ja/Nein-Abzweigungen.
21
- - Single-Select als Default. `multiSelect: true` nur wenn Mehrfachauswahl fachlich sinnvoll ist (z. B. „welche Zusatzpakete brauchst du?").
22
-
23
- Auswertung:
24
- - Gewählte Option → direkt weiterverarbeiten.
25
- - „Other"-Freitext → siehe Freitext-Regeln unten.
26
-
27
- ---
28
-
29
- ## Modus 2 — AGY / Cursor / Claude Desktop / OpenCode / unbekannt: Text-Schema
30
-
31
- Formatiere jede Auswahl als nummerierte Liste:
32
-
33
- ```
34
- <Frage>
35
-
36
- A) <Option 1>
37
- B) <Option 2>
38
- C) <Option 3>
39
- D) <Option 4>
40
- E) etwas anderes → beschreib es in eigenen Worten
41
- ```
42
-
43
- - `E)` ist der Freitext-Kanal (Äquivalent zu „Other").
44
- - Bei Verständnisfragen mit nur 2–4 Sachoptionen entfällt `E)` **nur in der Abschlussprüfung** (dort ist Freitext ungültig); in Stationsfragen bleibt `E)` erhalten.
45
- - **Fehleingaben still normalisieren:** `b`, `b.`, `B)`, „Antwort B", „die zweite", „option 2" → alle zu `B`. Nicht belehren, einfach die gemeinte Option verarbeiten.
46
- - Mehrdeutige oder leere Antwort → einmal kurz rückfragen: „Meinst du A oder C?"
47
-
48
- ---
49
-
50
- ## Freitext-Regeln (modusübergreifend)
51
-
52
- | Kontext | Freitext erlaubt? | Verhalten |
53
- | :-- | :-- | :-- |
54
- | Station 0 Teil A (Name, User, Client) | ja, immer offen | direkt übernehmen |
55
- | Station 0 Teil B (Workload) | **ja, erwünscht** | Freitext → **Track E**, Rohziel für `build_profile.py` merken |
56
- | Sizing-/Konfig-Fragen (Station 2, Track E) | **ja, erwünscht** | Freitext parsen (Zahlen, Paketnamen, Ports); bei Lücken gezielt nachfragen |
57
- | Zwischen-Verständnisfragen der Stationen 0.5–5 | ja | Freitext inhaltlich bewerten; bei „fast richtig" sokratisch nachhaken |
58
- | **Abschlussprüfung (10 Fragen)** | **nein** | Freitext → **einmalig** um Auswahl A–D bitten. Bleibt Trainee bei Freitext → **0 Punkte** für die Frage, weiter zur nächsten |
59
-
60
- ---
61
-
62
- ## Mapping Workload-Auswahl → Track
63
-
64
- | Auswahl Station 0 Teil B | Track | Track-Datei |
65
- | :-- | :-- | :-- |
66
- | A · AI-Agent Sandbox | `A` | `references/track-a-ai-agent.md` |
67
- | B · WordPress / Web-App | `B` | `references/track-b-wordpress.md` |
68
- | C · Mailserver | `C` | `references/track-c-mailserver.md` |
69
- | D · Clean Debian / DB / Worker | `D` | `references/track-d-debian.md` |
70
- | „Other" / E · Freitext | `E` | `references/track-e-custom.md` |
71
-
72
- Track E kann nach dem Interview auf einen konkreten Basis-Track „andocken" (web-artig → B-Muster, mail-artig → C-Muster, intern → D-Muster). Die Track-E-Datei steuert das.
73
-
74
- ---
75
-
76
- ## Beispiel — Track-Wahl in beiden Modi
77
-
78
- **Claude Code (`AskUserQuestion`):**
79
- - question: „Was möchtest du auf der BDB SaaS Host Fleet konkret betreiben?"
80
- - header: `Workload`
81
- - options: `AI-Agent Sandbox` / `WordPress / Web-App` / `Mailserver` / `Clean Debian / DB / Worker`
82
- - (Tool ergänzt „Other" automatisch → Track E)
83
- - optional `preview` je Option: 4–6 Zeilen, was der Track lehrt + Basis-Template
84
-
85
- **Text-Modus:**
86
- ```
87
- Was möchtest du auf der BDB SaaS Host Fleet konkret betreiben?
88
-
89
- A) AI-Agent Sandbox – autonome Agenten, restricted shell, agent-sudo
90
- B) WordPress / Web-App – öffentlich, Caddy + Authelia 2FA, Cloudflare proxied
91
- C) Mailserver – Froxlor/Postfix/Dovecot, eigene Kundendomain, DNS-Blueprint
92
- D) Clean Debian – generischer Container, Datenbank/Worker, selbst konfiguriert
93
- E) etwas anderes → beschreib deinen Workload in eigenen Worten
94
- ```
@@ -1,111 +0,0 @@
1
- # Track A — AI-Agent Sandbox
2
-
3
- **Ziel-Workload:** autonome AI-Agenten in isolierter, restricted-shell Umgebung.
4
- **Basis-Template (real):** `server-config/templates/incus/profile-ai-agent.yaml`
5
- **Container-Name im Training:** `c-A-<TRAINEE_USER>` · **Profil-Name:** `A-<TRAINEE_USER>`
6
-
7
- ---
8
-
9
- ## Station 2 — Incus Profile Engineering (Track A)
10
-
11
- ### 2.1 Echtes Template inspizieren
12
- Der Trainee öffnet `profile-ai-agent.yaml` und liest laut vor, was er sieht. Erwartete Struktur:
13
- - `config.limits.cpu: "2"`, `config.limits.memory: 2GiB` — harte Quotas.
14
- - `config.cloud-init.user-data` (**nicht** `user.user-data`) mit `#cloud-config`.
15
- - `packages:` nodejs, npm, python3, python3-venv, python3-pip, git, build-essential.
16
- - `users:` — ein User `agent` mit **`shell: /bin/rbash`** und einer einzigen sudo-Regel (`systemctl --no-pager status *`).
17
- - `write_files:` — eine `README.txt` im Home des Agenten.
18
- - **kein `devices:`** → `eth0`/`root` kommen aus dem `default`-Profil.
19
-
20
- Frage zum Verständnis (nicht Prüfung): „Was kann der User `agent` mit `/bin/rbash` NICHT?" → kein `cd`, keine absoluten Pfade, kein `>`-Redirect, kein Ändern von `PATH`.
21
-
22
- ### 2.2 Eigenes Profil generieren
23
- Interview (per `AskUserQuestion` / Text):
24
- - RAM: 1 / 2 / 4 GiB (Default 2, Node-Limit ≤ 8)
25
- - CPU: 1 / 2 (Default 2)
26
- - Zusatz-Runtime: „nur Python" / „nur Node" / „beides" (Default beides)
27
- - Agent-Framework vorinstallieren? `fastmcp` via pip / `@modelcontextprotocol/sdk` via npm / nichts
28
-
29
- ```bash
30
- python3 ~/.agents/skills/bdbsaastraining/scripts/build_profile.py \
31
- --track A --user <TRAINEE_USER> \
32
- --ram 2 --cpu 2 --runtime both --agent-framework fastmcp
33
- ```
34
- Output: `~/profile-A-<TRAINEE_USER>.yaml` + zeilenweise Erklärung.
35
- Der Generator behält `shell: /bin/rbash` bei (Kernkonzept) und ergänzt bei `--agent-framework fastmcp` einen `runcmd`-Schritt `python3 -m venv /home/agent/venv && /home/agent/venv/bin/pip install fastmcp` (statt es dem Trainee später als `ModuleNotFoundError` zu überlassen).
36
-
37
- ### 2.3 Registrieren & prüfen
38
- ```bash
39
- sudo incus profile create A-<TRAINEE_USER>
40
- sudo incus profile edit A-<TRAINEE_USER> < ~/profile-A-<TRAINEE_USER>.yaml
41
- sudo incus profile show A-<TRAINEE_USER>
42
- ```
43
-
44
- **Verständnisfrage 2 → `exam-pool.md` → `CORE_2`** (incusbr0 / Bridge).
45
-
46
- ---
47
-
48
- ## Station 3 — Deployment & Agent-Task (Track A)
49
-
50
- ```bash
51
- sudo incus launch images:debian/13 c-A-<TRAINEE_USER> -p default -p A-<TRAINEE_USER>
52
- sudo incus list
53
- sudo incus exec c-A-<TRAINEE_USER> -- cloud-init status --wait
54
- ```
55
-
56
- ### 3.1 In die Sandbox als unprivilegierter Agent
57
- ```bash
58
- sudo incus exec c-A-<TRAINEE_USER> -- su - agent
59
- # Erwartung: rbash-Prompt. Test:
60
- cd /tmp # -> rbash: cd: restricted
61
- ```
62
- > Falls der Trainee den User `agentrunner` erwartet (aus altem Skill-Stand): den gibt es NICHT. Der reale User heißt `agent`.
63
-
64
- ### 3.2 Realer Agent-Task — MCP-Tool im Container bauen
65
- ```bash
66
- # als agent, im Home:
67
- cat > build_mcp.py <<'PY'
68
- from fastmcp import FastMCP
69
- mcp = FastMCP("demo-agent-service")
70
-
71
- @mcp.tool()
72
- def analyze_lead(email: str, company: str) -> dict:
73
- return {"status": "analyzed", "email": email, "company": company, "score": 95}
74
-
75
- if __name__ == "__main__":
76
- mcp.run(transport="stdio")
77
- PY
78
- /home/agent/venv/bin/python build_mcp.py --help 2>&1 | head
79
- ```
80
- Didaktik: Selbst wenn das Skript crasht oder eine Endlosschleife baut — der Host ist durch die 2-GiB-Quota + Incus-Sandbox unberührt.
81
-
82
- **Verständnisfrage 3 → `exam-pool.md` → `CORE_1`** (Sandbox-Vorteil).
83
-
84
- ---
85
-
86
- ## Station 4 — FastMCP & Guardrails (Track A-Fokus)
87
-
88
- Zusätzlich zum gemeinsamen Station-4-Ablauf (siehe `SKILL.md`):
89
- - Der Trainee ruft `create_lldap_user(username="agent-demo-<TRAINEE_USER>", group="ai_agents", owner="<TRAINEE_USER>")` auf und beobachtet die Antwort (`status: "success"`, Hinweis auf Background-Worker).
90
- - Erklärung `agent-sudo`: auf einer Agent-SSH-Session ist `sudo` gesperrt; der Agent nutzt `agent-sudo <cmd>`. `agent-sudo ls /etc` → Auto-Approve. `agent-sudo systemctl restart caddy` → Queue.
91
-
92
- **Track-Fragen für die Prüfung:** `A_1`, `A_2`, `A_3`, `A_4`.
93
-
94
- ---
95
-
96
- ## Station 5 — Interne Gateway-Route (Track A)
97
-
98
- Der Agent exponiert ein kleines Web-UI (z. B. Port 8000) — **nur** hinter Authelia, nie roh öffentlich:
99
- ```
100
- remoteos_add_route(
101
- domain="agent-<TRAINEE_USER>.<DOMAIN>",
102
- upstream_port=8000,
103
- require_auth=True,
104
- target_node="netcup",
105
- service_type="web",
106
- sync_cloudflare=True
107
- )
108
- ```
109
- > **Gateway-Lücke:** `/tools/add_route` ist am Remote-Gateway ein Stub. Der Trainee verifiziert daher zusätzlich direkt auf dem Server: `sudo caddy validate --config /etc/caddy/Caddyfile` und prüft, ob ein `forward_auth`-Block für die Domain existiert. Alternativ Konzept erklären: ohne 2FA-Session → 302 auf `auth.<DOMAIN>`.
110
-
111
- **Verständnisfrage 5 → `exam-pool.md` → `A_3`** (agent-sudo Klassifikation) — oder als Prüfungsfrage aufheben und hier `CORE_5` (Queue-Verhalten) stellen.
@@ -1,111 +0,0 @@
1
- # Track B — WordPress / Web-App
2
-
3
- **Ziel-Workload:** öffentlich erreichbare Web-Anwendung hinter Caddy + Authelia 2FA.
4
- **Basis-Template (real):** `server-config/templates/incus/profile-wordpress.yaml`
5
- **Container:** `c-B-<TRAINEE_USER>` · **Profil:** `B-<TRAINEE_USER>`
6
-
7
- ---
8
-
9
- ## Station 2 — Incus Profile Engineering (Track B)
10
-
11
- ### 2.1 Echtes Template inspizieren
12
- `profile-wordpress.yaml`:
13
- - `config.limits.cpu: "2"`, `config.limits.memory: 4GiB`.
14
- - `config.cloud-init.user-data` → `#cloud-config` mit `package_update: true`, `package_upgrade: true`.
15
- - `packages:` nginx, mariadb-server, redis-server, php-fpm, php-mysql, php-redis, php-curl, php-gd, php-xml, php-mbstring, certbot.
16
- - `runcmd:` — erzeugt DB `wp` + User `wp` mit Zufallspasswort (`openssl rand -hex 16` → `/root/.wp-db-credentials`, `chmod 0600`), dann `systemctl enable --now nginx mariadb redis-server php8.2-fpm`.
17
- - **kein `devices:`** → aus `default`.
18
-
19
- **Bekannter Bug (Diagnose-Übung):** `php8.2-fpm` ist hart kodiert. Debian 13 (trixie) liefert PHP 8.4 → die Unit `php8.2-fpm` existiert nicht, der `systemctl`-Aufruf schlägt fehl. Der Generator ersetzt das durch die real installierte Version (`php-fpm` Meta-Paket → Dienst per `systemctl enable --now $(systemctl list-units 'php*-fpm*' ...)` bzw. parametrisiert `php8.4-fpm`).
20
-
21
- ### 2.2 Eigenes Profil generieren
22
- Interview:
23
- - RAM: 2 / 4 GiB (Default 4, Node-Limit ≤ 8)
24
- - Disk-Quota: 20 / 40 / 60 GiB (Default 40)
25
- - DB-Engine: MariaDB (Default) / PostgreSQL
26
- - Object-Cache Redis: ja (Default) / nein
27
- - WordPress automatisch per `wp-cli` installieren? ja / nein (nur Stack)
28
-
29
- ```bash
30
- python3 ~/.agents/skills/bdbsaastraining/scripts/build_profile.py \
31
- --track B --user <TRAINEE_USER> \
32
- --ram 4 --disk 40 --db mariadb --redis yes --wpcli yes
33
- ```
34
- Output: `~/profile-B-<TRAINEE_USER>.yaml`. Der Generator fixt den `php8.2-fpm`-Bug und fügt bei `--wpcli yes` einen `runcmd`-Schritt für `wp core download && wp config create ...` hinzu.
35
-
36
- ### 2.3 Registrieren & prüfen
37
- ```bash
38
- sudo incus profile create B-<TRAINEE_USER>
39
- sudo incus profile edit B-<TRAINEE_USER> < ~/profile-B-<TRAINEE_USER>.yaml
40
- sudo incus profile show B-<TRAINEE_USER>
41
- ```
42
-
43
- **Verständnisfrage 2 → `exam-pool.md` → `B_1`** (packages in cloud-init).
44
-
45
- ---
46
-
47
- ## Station 3 — Deployment & Verify (Track B)
48
-
49
- ```bash
50
- sudo incus launch images:debian/13 c-B-<TRAINEE_USER> -p default -p B-<TRAINEE_USER>
51
- sudo incus exec c-B-<TRAINEE_USER> -- cloud-init status --wait
52
- sudo incus exec c-B-<TRAINEE_USER> -- systemctl --failed
53
- ```
54
- Verifikation:
55
- ```bash
56
- CT_IP=$(sudo incus list c-B-<TRAINEE_USER> -c4 --format csv | cut -d' ' -f1)
57
- curl -sI "http://$CT_IP/" | head -1 # -> HTTP/1.1 200 / 301 (nginx lebt)
58
- sudo incus exec c-B-<TRAINEE_USER> -- cat /root/.wp-db-credentials
59
- ```
60
- Wenn `systemctl --failed` `php8.2-fpm` zeigt → Diagnose-Übung: `systemctl list-units 'php*'`, richtigen Dienstnamen finden, im generierten Profil ist es bereits gefixt (Trainee vergleicht).
61
-
62
- **Verständnisfrage 3 → `exam-pool.md` → `B_4`** (php-Version-Bug).
63
-
64
- ---
65
-
66
- ## Station 4 — FastMCP & Guardrails
67
-
68
- Gemeinsamer Ablauf (`SKILL.md`). Track-B-Betonung: `remoteos_create_instance` würde für einen echten Kunden so aussehen —
69
- ```
70
- remoteos_create_instance(
71
- client_name="kunde-mueller",
72
- domain="shop.kunde-mueller.de",
73
- template="wordpress",
74
- environment="staging1",
75
- target_node="netcup",
76
- cpu_cores=2, ram_gb=4, disk_gb=40
77
- )
78
- ```
79
- `staging1` → sofort, `environment="production"` → 4-Augen-Queue (siehe `classify_risk`).
80
-
81
- **Track-Fragen:** `B_1`, `B_2`, `B_3`, `B_4`.
82
-
83
- ---
84
-
85
- ## Station 5 — Öffentliche Web-Route (Track B)
86
-
87
- ```
88
- remoteos_add_route(
89
- domain="app-<TRAINEE_USER>.<DOMAIN>",
90
- upstream_port=80,
91
- require_auth=True,
92
- target_node="netcup",
93
- service_type="web",
94
- sync_cloudflare=True
95
- )
96
- ```
97
- Erwartetes Verhalten (Konzept, da `/tools/add_route` Stub):
98
- - Caddy bekommt `forward_auth 127.0.0.1:9091 { uri /api/authz/forward-auth ... }` + `reverse_proxy` auf die Container-IP.
99
- - Cloudflare A-Record `app-<TRAINEE_USER>` → Netcup-IP, **`🟠 proxied`** (`service_type="web"` ⇒ `proxied: true`).
100
-
101
- Verifikation auf dem Server:
102
- ```bash
103
- sudo caddy validate --config /etc/caddy/Caddyfile
104
- curl -sI https://app-<TRAINEE_USER>.<DOMAIN> | grep -Ei 'location|http/' # -> 302 auth.<DOMAIN>
105
- ```
106
- DNS-Blueprint für eine echte Kundendomain zusätzlich:
107
- ```
108
- remoteos_get_dns_blueprint(domain="kunde-mueller.de", service_type="web")
109
- ```
110
-
111
- **Verständnisfrage 5 → `exam-pool.md` → `B_2`** (proxied-Modus) oder `B_3` (forward_auth 302).
@@ -1,107 +0,0 @@
1
- # Track C — Mailserver (Froxlor / Postfix / Dovecot)
2
-
3
- **Ziel-Workload:** Kunden-Mailserver mit eigener Domain.
4
- **Basis-Template (real):** `server-config/templates/incus/profile-mailserver-froxlor.yaml`
5
- **Container:** `c-C-<TRAINEE_USER>` · **Profil:** `C-<TRAINEE_USER>`
6
-
7
- ---
8
-
9
- ## Station 2 — Incus Profile Engineering (Track C)
10
-
11
- ### 2.1 Echtes Template inspizieren
12
- `profile-mailserver-froxlor.yaml`:
13
- - **Top-Level `name:` UND `description:`** (dieses Template hat beides — anders als die anderen).
14
- - `config.limits.cpu: "2"`, `config.limits.memory: 4GiB`.
15
- - `config.cloud-init.user-data` → `packages:` postfix, dovecot-imapd, dovecot-pop3d, mariadb-server, php-fpm, php-mysql, php-cli, certbot, nginx, curl, gnupg.
16
- - `write_files:` — `/root/install_froxlor.sh` (Rechte `0755`), setzt die offizielle Froxlor-Debian-Repo + Key ein, `apt-get install froxlor`.
17
- - `runcmd:` — `[ "/bin/bash", "/root/install_froxlor.sh" ]`.
18
-
19
- > Für `incus profile edit` **muss der Top-Level `name:` raus** (bzw. exakt gleich dem CLI-Profilnamen). Der Generator entfernt ihn.
20
- > `php8.2-fpm` im `install_froxlor.sh` ist wie bei Track B versionsabhängig — Diagnose-Übung, im Generat gefixt.
21
-
22
- ### 2.2 Eigenes Profil generieren
23
- Interview:
24
- - Kundendomain (Freitext, z. B. `kunde-mueller.de`) — Pflicht für Station 5
25
- - Anzahl Postfächer: 5 / 10 / 20 (beeinflusst Disk-Empfehlung)
26
- - POP3 zusätzlich zu IMAP? ja / nein (Default nur IMAP)
27
- - Webmail (Roundcube) mit ausliefern? ja / nein
28
-
29
- ```bash
30
- python3 ~/.agents/skills/bdbsaastraining/scripts/build_profile.py \
31
- --track C --user <TRAINEE_USER> \
32
- --customer-domain kunde-mueller.de --mailboxes 10 --pop3 no --webmail yes
33
- ```
34
-
35
- ### 2.3 Registrieren & prüfen
36
- ```bash
37
- sudo incus profile create C-<TRAINEE_USER>
38
- sudo incus profile edit C-<TRAINEE_USER> < ~/profile-C-<TRAINEE_USER>.yaml
39
- sudo incus profile show C-<TRAINEE_USER>
40
- ```
41
-
42
- **Verständnisfrage 2 → `exam-pool.md` → `C_1`** (write_files vs runcmd).
43
-
44
- ---
45
-
46
- ## Station 3 — Deployment & Verify (Track C)
47
-
48
- ```bash
49
- sudo incus launch images:debian/13 c-C-<TRAINEE_USER> -p default -p C-<TRAINEE_USER>
50
- sudo incus exec c-C-<TRAINEE_USER> -- cloud-init status --wait
51
- ```
52
- Verifikation:
53
- ```bash
54
- sudo incus exec c-C-<TRAINEE_USER> -- postconf mail_version
55
- sudo incus exec c-C-<TRAINEE_USER> -- systemctl is-active postfix dovecot
56
- sudo incus exec c-C-<TRAINEE_USER> -- ss -tlnp | grep -E ':25|:143|:993'
57
- sudo incus exec c-C-<TRAINEE_USER> -- ls -la /var/www/froxlor 2>/dev/null || echo "froxlor install noch nicht fertig"
58
- ```
59
-
60
- **Verständnisfrage 3 → `exam-pool.md` → `CORE_6`** (Mail nie proxied).
61
-
62
- ---
63
-
64
- ## Station 4 — FastMCP & Guardrails
65
-
66
- Gemeinsamer Ablauf. Track-C-Betonung — echter Provisioning-Call für einen Mail-Kunden:
67
- ```
68
- remoteos_create_instance(
69
- client_name="kunde-mueller",
70
- domain="mail.kunde-mueller.de",
71
- template="froxlor-mail",
72
- environment="staging1",
73
- target_node="netcup"
74
- )
75
- ```
76
- Antwort enthält bei einer externen Kundendomain (nicht die Fleet-Domain) **kein** Cloudflare-Sync, sondern ein `dns_blueprint`-Feld (Mailserver-Variante).
77
-
78
- **Track-Fragen:** `C_1`, `C_2`, `C_3`, `C_4`.
79
-
80
- ---
81
-
82
- ## Station 5 — DNS-Blueprint für die Kundendomain (Track C)
83
-
84
- ```
85
- remoteos_get_dns_blueprint(
86
- domain="<CUSTOMER_DOMAIN>",
87
- service_type="mail",
88
- target_node="netcup"
89
- )
90
- ```
91
- Der Trainee liest das generierte Paket und ordnet jeden Record zu:
92
- - **A** `mail.<domain>` → Netcup-IP, **⚪ DNS-only**
93
- - **MX** `<domain>` → `mail.<domain>` Prio 10
94
- - **TXT SPF** `v=spf1 a mx ~all` (o. ä.)
95
- - **TXT DKIM** `default._domainkey.<domain>` (öffentlicher Key aus dem Container)
96
- - **TXT DMARC** `_dmarc.<domain>` `v=DMARC1; p=quarantine; ...`
97
- - **CNAME** `autodiscover` / `autoconfig`
98
-
99
- Wichtig: Die Fleet verwaltet nur ihre eigene Domain (`*.<FLEET_DOMAIN>`) per Cloudflare-API. Für **BYOD-Kundendomains** trägt der Kunde diese Records bei **seinem eigenen** DNS-Provider ein — deshalb Blueprint statt API-Call.
100
-
101
- DKIM-Key aus dem Container holen:
102
- ```bash
103
- sudo incus exec c-C-<TRAINEE_USER> -- cat /etc/dkimkeys/<domain>/default.txt 2>/dev/null || \
104
- sudo incus exec c-C-<TRAINEE_USER> -- opendkim-genkey --help
105
- ```
106
-
107
- **Verständnisfrage 5 → `exam-pool.md` → `C_4`** (BYOD Blueprint).
@@ -1,109 +0,0 @@
1
- # Track D — Clean Debian / Datenbank / Worker
2
-
3
- **Ziel-Workload:** generischer System-Container (PostgreSQL, Redis, BullMQ-Worker, Cron-Jobs …), selbst konfiguriert.
4
- **Basis-Template:** KEINES — es gibt kein `profile-debian-clean.yaml`. Station 2 = Profil von Grund auf.
5
- **Container:** `c-D-<TRAINEE_USER>` · **Profil:** `D-<TRAINEE_USER>`
6
-
7
- > Hinweis: Das MCP-Schema kennt `template="debian-clean"`, aber `incus_client.create_from_profile` erwartet ein Incus-Profil dieses Namens auf dem Host — das existiert nicht. Deshalb geht Track D bewusst den manuellen `incus profile create/edit`-Weg. Das ist der eigentliche Lernwert: „Custom Profile Engineering".
8
-
9
- ---
10
-
11
- ## Station 2 — Incus Profile von Grund auf (Track D)
12
-
13
- ### 2.1 Vergleichsbasis
14
- Der Trainee öffnet EIN mitgeliefertes Template (z. B. `profile-ai-agent.yaml`) nur als Formvorlage und markiert, was für einen minimalen DB-Container **weg** kann (nodejs, npm, build-essential, rbash-User).
15
-
16
- ### 2.2 Interview → minimales Profil
17
- - Workload-Art: PostgreSQL / Redis / Node-Worker (BullMQ) / „nur Debian, ich installiere selbst"
18
- - RAM: 1 / 2 / 4 GiB (Node-Limit ≤ 8)
19
- - CPU-Kerne: 1 / 2 · CPU-Deckel: `limits.cpu.allowance` 50% / 100%
20
- - Disk-Quota: 10 / 20 / 30 GiB
21
- - Persistenter Datenpfad als eigenes `devices:`-Disk (empfohlen für DB): ja / nein
22
-
23
- ```bash
24
- python3 ~/.agents/skills/bdbsaastraining/scripts/build_profile.py \
25
- --track D --user <TRAINEE_USER> \
26
- --workload postgres --ram 2 --cpu 2 --cpu-allowance 50 --disk 20 --data-device yes
27
- ```
28
- Ergebnis-Skelett (illustrativ, real generiert der Generator):
29
- ```yaml
30
- config:
31
- limits.cpu: "2"
32
- limits.cpu.allowance: 50%
33
- limits.memory: 2GiB
34
- cloud-init.user-data: |
35
- #cloud-config
36
- package_update: true
37
- packages: [postgresql, postgresql-client]
38
- runcmd:
39
- - systemctl enable --now postgresql
40
- description: "RC Cloud Clean Debian — postgres (D-<TRAINEE_USER>)"
41
- devices:
42
- data:
43
- type: disk
44
- pool: default
45
- source: ""
46
- path: /var/lib/postgresql
47
- size: 20GiB
48
- ```
49
-
50
- ### 2.3 Registrieren & prüfen
51
- ```bash
52
- sudo incus profile create D-<TRAINEE_USER>
53
- sudo incus profile edit D-<TRAINEE_USER> < ~/profile-D-<TRAINEE_USER>.yaml
54
- sudo incus profile show D-<TRAINEE_USER>
55
- ```
56
-
57
- **Verständnisfrage 2 → `exam-pool.md` → `D_1`** (Profil von Grund auf) oder `D_4` (limits.cpu.allowance).
58
-
59
- ---
60
-
61
- ## Station 3 — Deployment & Verify (Track D)
62
-
63
- ```bash
64
- sudo incus launch images:debian/13 c-D-<TRAINEE_USER> -p default -p D-<TRAINEE_USER>
65
- sudo incus exec c-D-<TRAINEE_USER> -- cloud-init status --wait
66
- ```
67
- Verifikation je nach Workload:
68
- ```bash
69
- # postgres:
70
- sudo incus exec c-D-<TRAINEE_USER> -- sudo -u postgres psql -c "SELECT version();"
71
- # redis:
72
- sudo incus exec c-D-<TRAINEE_USER> -- redis-cli ping
73
- # quota-check:
74
- sudo incus config show c-D-<TRAINEE_USER> | grep -E 'limits|size'
75
- ```
76
-
77
- **Verständnisfrage 3 → `exam-pool.md` → `D_2`** (Snapshot/Migration).
78
-
79
- ---
80
-
81
- ## Station 4 — FastMCP & Guardrails
82
-
83
- Gemeinsamer Ablauf. Track-D-Betonung: Lifecycle über MCP —
84
- ```
85
- remoteos_manage_instance(container_name="c-D-<TRAINEE_USER>", action="stop", reason="Bootcamp D Lifecycle-Test")
86
- remoteos_manage_instance(container_name="c-D-<TRAINEE_USER>", action="start", reason="Bootcamp D Lifecycle-Test")
87
- ```
88
- `start`/`stop` → sofort (`RiskLevel.STAGING`). `restart`/`delete` → Queue.
89
-
90
- **Track-Fragen:** `D_1`, `D_2`, `D_3`, `D_4`.
91
-
92
- ---
93
-
94
- ## Station 5 — Bewusst KEINE öffentliche Route (Track D)
95
-
96
- Ein DB/Worker-Container gehört **nicht** ins öffentliche Internet. Zwei Optionen:
97
-
98
- **Option 1 — nur intern über die Bridge:** Die App im selben Netz erreicht die DB über die Container-IP auf `incusbr0`. Nichts weiter zu tun.
99
-
100
- **Option 2 — gezieltes Port-Forwarding zum Host (kein Caddy, kein DNS):**
101
- ```bash
102
- sudo incus config device add c-D-<TRAINEE_USER> pg proxy \
103
- listen=tcp:127.0.0.1:15432 connect=tcp:127.0.0.1:5432
104
- ```
105
- → DB nur auf `127.0.0.1:15432` des Hosts, erreichbar für lokale Prozesse / SSH-Tunnel, nie extern.
106
-
107
- Wenn der Trainee doch eine Admin-Weboberfläche (pgAdmin) exponieren will → wie Track B, aber `require_auth=True` ist Pflicht und Cloudflare `🟠 proxied`.
108
-
109
- **Verständnisfrage 5 → `exam-pool.md` → `D_3`** (keine öffentliche Route für DB).
@@ -1,83 +0,0 @@
1
- # Track E — Custom Workload (frei beschrieben)
2
-
3
- **Auslöser:** Der Trainee hat in Station 0 „Other" / `E)` gewählt und seinen Workload in eigenen Worten beschrieben.
4
- **Ziel:** Aus dem Freitext ein reales, valides Incus-Profil ableiten und das Training an den passenden Basis-Track andocken.
5
-
6
- ---
7
-
8
- ## E.0 — Interview (nach dem Freitext)
9
-
10
- Frage strukturiert nach, was im Freitext fehlt. Nutze `AskUserQuestion` / Text-Schema:
11
-
12
- 1. **Grundcharakter** → bestimmt das Basis-Muster:
13
- - „öffentlich per HTTP(S) erreichbar, mit Login" → **B-Muster** (Caddy + Authelia + Cloudflare proxied)
14
- - „E-Mail / SMTP / IMAP" → **C-Muster** (DNS-Blueprint, DNS-only)
15
- - „nur intern / Datenbank / Worker / Batch" → **D-Muster** (keine öffentliche Route)
16
- - „autonome Agenten / Code-Ausführung" → **A-Muster** (rbash, ai_agents, agent-sudo)
17
- 2. **Ressourcen:** RAM (1–8 GiB), CPU (1–2), CPU-Deckel (50/100 %), Disk (10–60 GiB)
18
- 3. **Pakete:** welche Dienste/Runtimes? (Freitext-Liste, Generator validiert gegen Debian-13-Paketnamen und warnt bei Unbekanntem)
19
- 4. **Ports:** welche TCP-Ports lauscht der Dienst? intern / öffentlich?
20
- 5. **Auth:** braucht der öffentliche Endpunkt Authelia-2FA? (Default: ja, wenn öffentlich)
21
- 6. **Persistenz:** eigener Daten-`devices:`-Block? (Default ja bei DB-artigen Workloads)
22
-
23
- Speichere: `<E_BASE>` ∈ {A, B, C, D}.
24
-
25
- ---
26
-
27
- ## E.1 — Profil generieren
28
-
29
- ```bash
30
- python3 ~/.agents/skills/bdbsaastraining/scripts/build_profile.py \
31
- --track E --user <TRAINEE_USER> \
32
- --base <E_BASE> \
33
- --ram <N> --cpu <N> --cpu-allowance <50|100> --disk <N> \
34
- --packages "pkg1,pkg2,pkg3" \
35
- --ports "8000/public,9000/internal" \
36
- --auth <yes|no> --data-device <yes|no> \
37
- --describe "<originaler Freitext des Trainees>"
38
- ```
39
-
40
- Der Generator:
41
- - nimmt das `<E_BASE>`-Template als Ausgangsbasis (bzw. ein Minimal-Skelett bei `--base D`),
42
- - ersetzt `packages:` durch die validierte Liste,
43
- - setzt `limits.*` aus den Sizing-Antworten,
44
- - **warnt** (nicht abbricht) bei: `ram > 8`, `disk > 100`, unbekannten Paketnamen, öffentlichem Port ohne `--auth yes`,
45
- - entfernt Top-Level `name:`,
46
- - schreibt `~/profile-E-<TRAINEE_USER>.yaml` + zeilenweise Erklärung + Liste aller Warnungen.
47
-
48
- Bei `ram > 8`: Hinweis, dass der Primary-Node (`ram_gb ≤ 8` im MCP-Schema) das nicht trägt → Workload auf Auxiliary-Node (Oracle, 24 GB) planen.
49
-
50
- ---
51
-
52
- ## E.2 — Station 2 / 3 / 5 nach Basis-Muster
53
-
54
- Ab hier folgst du der Datei des Basis-Tracks `<E_BASE>` für Struktur und Befehle, aber mit den Custom-Werten:
55
-
56
- | `<E_BASE>` | Station 2/3 wie | Station 5 wie |
57
- | :-- | :-- | :-- |
58
- | A | `track-a-ai-agent.md` (rbash-User, Sandbox-Task) | interne Gateway-Route, `require_auth=True` |
59
- | B | `track-b-wordpress.md` (Stack-Verify per `curl`) | öffentliche Route, Caddy forward_auth, CF `🟠 proxied` |
60
- | C | `track-c-mailserver.md` (`postconf`, Ports) | `remoteos_get_dns_blueprint(service_type="mail")`, `⚪ DNS-only` |
61
- | D | `track-d-debian.md` (minimal, Quotas, Snapshot) | keine öffentliche Route / `incus proxy` Device |
62
-
63
- Container-Name: `c-E-<TRAINEE_USER>` · Profil: `E-<TRAINEE_USER>`.
64
-
65
- Verifikation immer zuerst:
66
- ```bash
67
- sudo incus profile show E-<TRAINEE_USER>
68
- sudo incus launch images:debian/13 c-E-<TRAINEE_USER> -p default -p E-<TRAINEE_USER>
69
- sudo incus exec c-E-<TRAINEE_USER> -- cloud-init status --wait
70
- ```
71
-
72
- ---
73
-
74
- ## E.3 — Station 4 (gemeinsam)
75
-
76
- Wie in `SKILL.md`, mit `container_name="c-E-<TRAINEE_USER>"` und Pflichtfeld `reason`.
77
-
78
- ---
79
-
80
- ## Prüfung — Track E
81
-
82
- **Track-Fragen:** `E_1`, `E_2`, `E_3`, `E_4` (aus `exam-pool.md`).
83
- Zusätzlich: Wenn `<E_BASE>` z. B. `B` war, darf der Tutor bis zu 2 der 4 Track-Fragen durch passende `B_*`-Fragen ersetzen, damit die Prüfung zum tatsächlich Gelernten passt. Immer 6 Kern + 4 Track = 10.