@hybridlabor-api/aos 4.4.0 → 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 (306) 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/hooks/memb-inject.mjs +6 -0
  20. package/CLAUDE.md +573 -0
  21. package/README.de.md +0 -8
  22. package/README.md +0 -8
  23. package/README.pt.md +0 -8
  24. package/assets/brand/ao-ant-mark.svg +91 -0
  25. package/assets/brand/bdb-core-mark.svg +34 -0
  26. package/assets/brand/heimdall-guardian-mark.svg +16 -0
  27. package/assets/brand/memb-crystal-mark.svg +18 -0
  28. package/bin/aos-config.mjs +89 -0
  29. package/bin/aos-dashboard.mjs +608 -0
  30. package/bin/aos-uninstall.mjs +227 -0
  31. package/docs/sessions/audit-2026-09-14-silent-failures.md +114 -0
  32. package/docs/skills_table.md +0 -3
  33. package/installer.js +428 -237
  34. package/mcps/RhinoMCP/cc-plugin/.claude/settings.json +10 -0
  35. package/mcps/after-effects-mcp/build/index.js +840 -0
  36. package/mcps/after-effects-mcp/build/scripts/applyEffect.jsx +153 -0
  37. package/mcps/after-effects-mcp/build/scripts/applyEffectTemplate.jsx +218 -0
  38. package/mcps/after-effects-mcp/build/scripts/createComposition.jsx +71 -0
  39. package/mcps/after-effects-mcp/build/scripts/createShapeLayer.jsx +147 -0
  40. package/mcps/after-effects-mcp/build/scripts/createSolidLayer.jsx +114 -0
  41. package/mcps/after-effects-mcp/build/scripts/createTextLayer.jsx +115 -0
  42. package/mcps/after-effects-mcp/build/scripts/getLayerInfo.jsx +192 -0
  43. package/mcps/after-effects-mcp/build/scripts/getProjectInfo.jsx +90 -0
  44. package/mcps/after-effects-mcp/build/scripts/listCompositions.jsx +50 -0
  45. package/mcps/after-effects-mcp/build/scripts/mcp-bridge-auto.jsx +1773 -0
  46. package/mcps/after-effects-mcp/build/scripts/setLayerProperties.jsx +160 -0
  47. package/mcps/computer-use-mcp/dist/client.d.ts +150 -0
  48. package/mcps/computer-use-mcp/dist/client.js +136 -0
  49. package/mcps/computer-use-mcp/dist/entrypoint.d.ts +16 -0
  50. package/mcps/computer-use-mcp/dist/entrypoint.js +26 -0
  51. package/mcps/computer-use-mcp/dist/native.d.ts +212 -0
  52. package/mcps/computer-use-mcp/dist/native.js +50 -0
  53. package/mcps/computer-use-mcp/dist/server.d.ts +32 -0
  54. package/mcps/computer-use-mcp/dist/server.js +342 -0
  55. package/mcps/computer-use-mcp/dist/session.d.ts +101 -0
  56. package/mcps/computer-use-mcp/dist/session.js +2372 -0
  57. package/package.json +13 -4
  58. package/skills/global_config/aos-project-init/SKILL.md +97 -130
  59. package/skills/global_config/aos-project-init/assets/openwikiignore.template +62 -0
  60. package/skills/global_config/aos-project-init/scripts/aos-project-doctor.mjs +38 -1
  61. package/skills/global_config/aos-setup/SKILL.md +110 -11
  62. package/skills/global_config/aos-setup/scripts/aos-doctor.mjs +48 -4
  63. package/skills/global_config/ask-tim/SKILL.md +2 -7
  64. package/skills/global_config/openwiki-skill/scripts/openwiki_daemon.py +65 -12
  65. package/bin/setup-saas.mjs +0 -792
  66. package/mcps/blender-mcp-server/.dockerignore +0 -19
  67. package/mcps/blender-mcp-server/.github/workflows/ci.yml +0 -67
  68. package/mcps/blender-mcp-server/.github/workflows/publish-pypi.yml +0 -54
  69. package/mcps/blender-mcp-server/CHANGELOG.md +0 -64
  70. package/mcps/blender-mcp-server/CONTRIBUTING.md +0 -107
  71. package/mcps/blender-mcp-server/Dockerfile +0 -19
  72. package/mcps/blender-mcp-server/LICENSE +0 -21
  73. package/mcps/blender-mcp-server/README.md +0 -409
  74. package/mcps/blender-mcp-server/addon/__init__.py +0 -1440
  75. package/mcps/blender-mcp-server/addon/models.py +0 -223
  76. package/mcps/blender-mcp-server/pyproject.toml +0 -120
  77. package/mcps/blender-mcp-server/scripts/blender_bridge_request.py +0 -71
  78. package/mcps/blender-mcp-server/scripts/blender_create_test_cube.py +0 -49
  79. package/mcps/blender-mcp-server/scripts/blender_scene_info.py +0 -38
  80. package/mcps/blender-mcp-server/scripts/build_addon_zip.sh +0 -29
  81. package/mcps/blender-mcp-server/scripts/demos/README.md +0 -186
  82. package/mcps/blender-mcp-server/scripts/demos/dam_break_scene.py +0 -276
  83. package/mcps/blender-mcp-server/scripts/demos/open_dam_break_gui.py +0 -33
  84. package/mcps/blender-mcp-server/scripts/demos/pipe_movement_study.py +0 -518
  85. package/mcps/blender-mcp-server/scripts/demos/pipe_pressure_failure_scene.py +0 -806
  86. package/mcps/blender-mcp-server/scripts/demos/procedural_dam_break_scene.py +0 -600
  87. package/mcps/blender-mcp-server/scripts/demos/run_dam_break.py +0 -510
  88. package/mcps/blender-mcp-server/scripts/launch_blender_gui.py +0 -41
  89. package/mcps/blender-mcp-server/scripts/library/README.md +0 -64
  90. package/mcps/blender-mcp-server/scripts/library/apply_transforms.py +0 -46
  91. package/mcps/blender-mcp-server/scripts/library/camera.py +0 -51
  92. package/mcps/blender-mcp-server/scripts/library/collections.py +0 -65
  93. package/mcps/blender-mcp-server/scripts/library/create_mesh.py +0 -41
  94. package/mcps/blender-mcp-server/scripts/library/effector.py +0 -48
  95. package/mcps/blender-mcp-server/scripts/library/fluid_domain.py +0 -80
  96. package/mcps/blender-mcp-server/scripts/library/fluid_inflow.py +0 -98
  97. package/mcps/blender-mcp-server/scripts/library/frame_range.py +0 -35
  98. package/mcps/blender-mcp-server/scripts/library/keyframes.py +0 -59
  99. package/mcps/blender-mcp-server/scripts/library/rigid_body.py +0 -52
  100. package/mcps/blender-mcp-server/scripts/library/save_blend.py +0 -40
  101. package/mcps/blender-mcp-server/scripts/server_start.sh +0 -26
  102. package/mcps/blender-mcp-server/src/blender_mcp_server/__init__.py +0 -3
  103. package/mcps/blender-mcp-server/src/blender_mcp_server/headless.py +0 -330
  104. package/mcps/blender-mcp-server/src/blender_mcp_server/server.py +0 -606
  105. package/mcps/davinci-mcp-professional/.bandit +0 -35
  106. package/mcps/davinci-mcp-professional/.claude/commands/security-review.md +0 -191
  107. package/mcps/davinci-mcp-professional/.claude/settings.json +0 -1
  108. package/mcps/davinci-mcp-professional/.editorconfig +0 -27
  109. package/mcps/davinci-mcp-professional/.gitattributes +0 -207
  110. package/mcps/davinci-mcp-professional/.github/CODEOWNERS +0 -2
  111. package/mcps/davinci-mcp-professional/.github/ISSUE_TEMPLATE/bug_report.md +0 -33
  112. package/mcps/davinci-mcp-professional/.github/ISSUE_TEMPLATE/feature_request.md +0 -19
  113. package/mcps/davinci-mcp-professional/.github/PULL_REQUEST_TEMPLATE.md +0 -20
  114. package/mcps/davinci-mcp-professional/.github/SECURITY.md +0 -97
  115. package/mcps/davinci-mcp-professional/.github/dependabot.yml +0 -27
  116. package/mcps/davinci-mcp-professional/.github/workflows/ci.yml +0 -39
  117. package/mcps/davinci-mcp-professional/ATTRIBUTION.md +0 -4
  118. package/mcps/davinci-mcp-professional/AUTHORS.md +0 -9
  119. package/mcps/davinci-mcp-professional/BUGS.md +0 -55
  120. package/mcps/davinci-mcp-professional/CLAUDE.md +0 -229
  121. package/mcps/davinci-mcp-professional/CONTRIBUTING.md +0 -51
  122. package/mcps/davinci-mcp-professional/COPYING.md +0 -228
  123. package/mcps/davinci-mcp-professional/Doxyfile +0 -379
  124. package/mcps/davinci-mcp-professional/README.md +0 -143
  125. package/mcps/davinci-mcp-professional/SECURITY.md +0 -40
  126. package/mcps/davinci-mcp-professional/USING.md +0 -301
  127. package/mcps/davinci-mcp-professional/VERSION.md +0 -13
  128. package/mcps/davinci-mcp-professional/build.py +0 -169
  129. package/mcps/davinci-mcp-professional/claude_desktop_config_template.json +0 -11
  130. package/mcps/davinci-mcp-professional/hooks/ci-check.sh +0 -29
  131. package/mcps/davinci-mcp-professional/hooks/pre-push +0 -46
  132. package/mcps/davinci-mcp-professional/main.py +0 -40
  133. package/mcps/davinci-mcp-professional/mcp_server.py +0 -30
  134. package/mcps/davinci-mcp-professional/pyproject.toml +0 -115
  135. package/mcps/davinci-mcp-professional/security_audit.py +0 -379
  136. package/mcps/davinci-mcp-professional/src/davinci_mcp/__init__.py +0 -19
  137. package/mcps/davinci-mcp-professional/src/davinci_mcp/cli.py +0 -138
  138. package/mcps/davinci-mcp-professional/src/davinci_mcp/resolve_client.py +0 -342
  139. package/mcps/davinci-mcp-professional/src/davinci_mcp/resources/__init__.py +0 -60
  140. package/mcps/davinci-mcp-professional/src/davinci_mcp/server.py +0 -185
  141. package/mcps/davinci-mcp-professional/src/davinci_mcp/tools/__init__.py +0 -146
  142. package/mcps/davinci-mcp-professional/src/davinci_mcp/types.py +0 -125
  143. package/mcps/davinci-mcp-professional/src/davinci_mcp/utils/__init__.py +0 -19
  144. package/mcps/davinci-mcp-professional/src/davinci_mcp/utils/platform.py +0 -239
  145. package/mcps/davinci-mcp-professional/test.py +0 -186
  146. package/mcps/davinci-mcp-professional/uv.lock +0 -2073
  147. package/mcps/davinci-resolve-mcp/.claude/skills/media-analysis.md +0 -44
  148. package/mcps/davinci-resolve-mcp/.clinerules +0 -17
  149. package/mcps/davinci-resolve-mcp/.cursorrules +0 -17
  150. package/mcps/davinci-resolve-mcp/.github/copilot-instructions.md +0 -17
  151. package/mcps/davinci-resolve-mcp/.github/workflows/npm-publish.yml +0 -109
  152. package/mcps/davinci-resolve-mcp/.windsurfrules +0 -17
  153. package/mcps/davinci-resolve-mcp/AGENTS.md +0 -114
  154. package/mcps/davinci-resolve-mcp/CHANGELOG.md +0 -2648
  155. package/mcps/davinci-resolve-mcp/CLAUDE.md +0 -15
  156. package/mcps/davinci-resolve-mcp/LICENSE +0 -21
  157. package/mcps/davinci-resolve-mcp/README.md +0 -173
  158. package/mcps/davinci-resolve-mcp/SECURITY.md +0 -53
  159. package/mcps/davinci-resolve-mcp/bin/davinci-resolve-mcp.mjs +0 -450
  160. package/mcps/davinci-resolve-mcp/examples/README.md +0 -53
  161. package/mcps/davinci-resolve-mcp/examples/markers/README.md +0 -81
  162. package/mcps/davinci-resolve-mcp/examples/media/README.md +0 -94
  163. package/mcps/davinci-resolve-mcp/examples/timeline/README.md +0 -98
  164. package/mcps/davinci-resolve-mcp/install.py +0 -1687
  165. package/mcps/davinci-resolve-mcp/package.json +0 -52
  166. package/mcps/davinci-resolve-mcp/release-notes/v2.22.0.md +0 -51
  167. package/mcps/davinci-resolve-mcp/release-notes/v2.23.0.md +0 -51
  168. package/mcps/davinci-resolve-mcp/release-notes/v2.23.1.md +0 -35
  169. package/mcps/davinci-resolve-mcp/release-notes/v2.24.1.md +0 -32
  170. package/mcps/davinci-resolve-mcp/scripts/audit_api_parity.py +0 -275
  171. package/mcps/davinci-resolve-mcp/scripts/audit_readwrite_symmetry.py +0 -80
  172. package/mcps/davinci-resolve-mcp/scripts/doctor.py +0 -227
  173. package/mcps/davinci-resolve-mcp/scripts/gen_api_limitations.py +0 -144
  174. package/mcps/davinci-resolve-mcp/scripts/live_media_analysis_polish_probe.py +0 -65
  175. package/mcps/davinci-resolve-mcp/scripts/measure_bridge_cost.py +0 -65
  176. package/mcps/davinci-resolve-mcp/scripts/regen_panel_screenshots.py +0 -76
  177. package/mcps/davinci-resolve-mcp/src/__init__.py +0 -3
  178. package/mcps/davinci-resolve-mcp/src/analysis_dashboard.py +0 -15505
  179. package/mcps/davinci-resolve-mcp/src/batch_cli.py +0 -540
  180. package/mcps/davinci-resolve-mcp/src/control_panel.py +0 -13
  181. package/mcps/davinci-resolve-mcp/src/granular/__init__.py +0 -17
  182. package/mcps/davinci-resolve-mcp/src/granular/common.py +0 -741
  183. package/mcps/davinci-resolve-mcp/src/granular/folder.py +0 -420
  184. package/mcps/davinci-resolve-mcp/src/granular/gallery.py +0 -306
  185. package/mcps/davinci-resolve-mcp/src/granular/graph.py +0 -309
  186. package/mcps/davinci-resolve-mcp/src/granular/media_pool.py +0 -679
  187. package/mcps/davinci-resolve-mcp/src/granular/media_pool_item.py +0 -1020
  188. package/mcps/davinci-resolve-mcp/src/granular/media_storage.py +0 -179
  189. package/mcps/davinci-resolve-mcp/src/granular/project.py +0 -1654
  190. package/mcps/davinci-resolve-mcp/src/granular/resolve_control.py +0 -538
  191. package/mcps/davinci-resolve-mcp/src/granular/timeline.py +0 -1075
  192. package/mcps/davinci-resolve-mcp/src/granular/timeline_item.py +0 -2251
  193. package/mcps/davinci-resolve-mcp/src/resolve_mcp_server.py +0 -43
  194. package/mcps/davinci-resolve-mcp/src/server.py +0 -24116
  195. package/mcps/davinci-resolve-mcp/src/utils/__init__.py +0 -3
  196. package/mcps/davinci-resolve-mcp/src/utils/actor_identity.py +0 -46
  197. package/mcps/davinci-resolve-mcp/src/utils/analysis_caps.py +0 -678
  198. package/mcps/davinci-resolve-mcp/src/utils/analysis_memory.py +0 -755
  199. package/mcps/davinci-resolve-mcp/src/utils/analysis_runs.py +0 -307
  200. package/mcps/davinci-resolve-mcp/src/utils/analysis_store.py +0 -945
  201. package/mcps/davinci-resolve-mcp/src/utils/api_truth.py +0 -525
  202. package/mcps/davinci-resolve-mcp/src/utils/app_control.py +0 -319
  203. package/mcps/davinci-resolve-mcp/src/utils/audio_fairlight_live_probe.py +0 -263
  204. package/mcps/davinci-resolve-mcp/src/utils/brain_edits.py +0 -387
  205. package/mcps/davinci-resolve-mcp/src/utils/bridge_metrics.py +0 -76
  206. package/mcps/davinci-resolve-mcp/src/utils/cdl.py +0 -20
  207. package/mcps/davinci-resolve-mcp/src/utils/clip_query.py +0 -85
  208. package/mcps/davinci-resolve-mcp/src/utils/cloud_operations.py +0 -192
  209. package/mcps/davinci-resolve-mcp/src/utils/color_grade_live_probe.py +0 -444
  210. package/mcps/davinci-resolve-mcp/src/utils/contracts.py +0 -102
  211. package/mcps/davinci-resolve-mcp/src/utils/cut_ir.py +0 -115
  212. package/mcps/davinci-resolve-mcp/src/utils/dctl_templates.py +0 -368
  213. package/mcps/davinci-resolve-mcp/src/utils/deep_vision.py +0 -643
  214. package/mcps/davinci-resolve-mcp/src/utils/destructive_hook.py +0 -606
  215. package/mcps/davinci-resolve-mcp/src/utils/edit_engine.py +0 -737
  216. package/mcps/davinci-resolve-mcp/src/utils/embeddings.py +0 -922
  217. package/mcps/davinci-resolve-mcp/src/utils/entities.py +0 -579
  218. package/mcps/davinci-resolve-mcp/src/utils/extension_authoring_live_probe.py +0 -292
  219. package/mcps/davinci-resolve-mcp/src/utils/failure_tracker.py +0 -119
  220. package/mcps/davinci-resolve-mcp/src/utils/fuse_templates.py +0 -1968
  221. package/mcps/davinci-resolve-mcp/src/utils/fusion_composition_live_probe.py +0 -284
  222. package/mcps/davinci-resolve-mcp/src/utils/fusion_group_settings.py +0 -334
  223. package/mcps/davinci-resolve-mcp/src/utils/layout_presets.py +0 -333
  224. package/mcps/davinci-resolve-mcp/src/utils/mcp_stdio.py +0 -32
  225. package/mcps/davinci-resolve-mcp/src/utils/mcp_transport.py +0 -128
  226. package/mcps/davinci-resolve-mcp/src/utils/media_analysis.py +0 -7690
  227. package/mcps/davinci-resolve-mcp/src/utils/media_analysis_jobs.py +0 -805
  228. package/mcps/davinci-resolve-mcp/src/utils/media_pool_changes.py +0 -121
  229. package/mcps/davinci-resolve-mcp/src/utils/media_pool_ingest_live_probe.py +0 -592
  230. package/mcps/davinci-resolve-mcp/src/utils/multicam.py +0 -393
  231. package/mcps/davinci-resolve-mcp/src/utils/object_inspection.py +0 -301
  232. package/mcps/davinci-resolve-mcp/src/utils/page_lock.py +0 -75
  233. package/mcps/davinci-resolve-mcp/src/utils/platform.py +0 -157
  234. package/mcps/davinci-resolve-mcp/src/utils/proc.py +0 -26
  235. package/mcps/davinci-resolve-mcp/src/utils/project_cleanup.py +0 -73
  236. package/mcps/davinci-resolve-mcp/src/utils/project_lifecycle_live_probe.py +0 -376
  237. package/mcps/davinci-resolve-mcp/src/utils/project_lint.py +0 -131
  238. package/mcps/davinci-resolve-mcp/src/utils/project_properties.py +0 -601
  239. package/mcps/davinci-resolve-mcp/src/utils/project_spec.py +0 -459
  240. package/mcps/davinci-resolve-mcp/src/utils/readback.py +0 -91
  241. package/mcps/davinci-resolve-mcp/src/utils/render_deliver_live_probe.py +0 -384
  242. package/mcps/davinci-resolve-mcp/src/utils/resolve_ai_governance.py +0 -214
  243. package/mcps/davinci-resolve-mcp/src/utils/resolve_ai_ledger.py +0 -244
  244. package/mcps/davinci-resolve-mcp/src/utils/resolve_busy.py +0 -171
  245. package/mcps/davinci-resolve-mcp/src/utils/resolve_connection.py +0 -77
  246. package/mcps/davinci-resolve-mcp/src/utils/review_annotation_live_probe.py +0 -352
  247. package/mcps/davinci-resolve-mcp/src/utils/script_templates.py +0 -1193
  248. package/mcps/davinci-resolve-mcp/src/utils/shot_relationships.py +0 -544
  249. package/mcps/davinci-resolve-mcp/src/utils/structural_diff.py +0 -175
  250. package/mcps/davinci-resolve-mcp/src/utils/sync_detection.py +0 -889
  251. package/mcps/davinci-resolve-mcp/src/utils/timeline_brain_db.py +0 -826
  252. package/mcps/davinci-resolve-mcp/src/utils/timeline_conform_live_probe.py +0 -280
  253. package/mcps/davinci-resolve-mcp/src/utils/timeline_kernel_live_probe.py +0 -1092
  254. package/mcps/davinci-resolve-mcp/src/utils/timeline_kernel_probe.py +0 -185
  255. package/mcps/davinci-resolve-mcp/src/utils/timeline_title_text.py +0 -87
  256. package/mcps/davinci-resolve-mcp/src/utils/timeline_versioning.py +0 -730
  257. package/mcps/davinci-resolve-mcp/src/utils/update_check.py +0 -685
  258. package/mcps/vectorworks-mcp/.dockerignore +0 -8
  259. package/mcps/vectorworks-mcp/Dockerfile +0 -28
  260. package/mcps/vectorworks-mcp/README.md +0 -156
  261. package/mcps/vectorworks-mcp/app/__init__.py +0 -2
  262. package/mcps/vectorworks-mcp/app/api.py +0 -52
  263. package/mcps/vectorworks-mcp/app/chunking.py +0 -56
  264. package/mcps/vectorworks-mcp/app/config.py +0 -29
  265. package/mcps/vectorworks-mcp/app/embeddings.py +0 -28
  266. package/mcps/vectorworks-mcp/app/indexer.py +0 -106
  267. package/mcps/vectorworks-mcp/app/main.py +0 -33
  268. package/mcps/vectorworks-mcp/app/mcp_server.py +0 -71
  269. package/mcps/vectorworks-mcp/app/search.py +0 -54
  270. package/mcps/vectorworks-mcp/app/utils.py +0 -14
  271. package/mcps/vectorworks-mcp/data/.gitkeep +0 -1
  272. package/mcps/vectorworks-mcp/data/vw-app-help/VW2022_PluginScript.htm +0 -95
  273. package/mcps/vectorworks-mcp/data/vw-app-help/VW2022_ScriptEditor.htm +0 -266
  274. package/mcps/vectorworks-mcp/data/vw-app-help/VW2022_Scripting.htm +0 -106
  275. package/mcps/vectorworks-mcp/data/vw-app-help/VW2023_CreatingScriptedPlugins.htm +0 -327
  276. package/mcps/vectorworks-mcp/data/vw-app-help/VW2024_RunningScripts.htm +0 -116
  277. package/mcps/vectorworks-mcp/data/vw-devwiki/VS_Function_Reference_category.html +0 -2129
  278. package/mcps/vectorworks-mcp/data/vw-jp-ref/ObjectsSymbols.html +0 -2035
  279. package/mcps/vectorworks-mcp/data/vw-jp-ref/ScriptFunctionReference.html +0 -29
  280. package/mcps/vectorworks-mcp/design.md +0 -57
  281. package/mcps/vectorworks-mcp/docker-compose.yml +0 -18
  282. package/mcps/vectorworks-mcp/index/.gitkeep +0 -1
  283. package/mcps/vectorworks-mcp/index/meta.jsonl +0 -3956
  284. package/mcps/vectorworks-mcp/index/vw.faiss +0 -0
  285. package/mcps/vectorworks-mcp/requirements.txt +0 -10
  286. package/mcps/vectorworks-mcp/scripts/fetch_docs_minimal.sh +0 -84
  287. package/mcps/vectorworks-mcp/scripts/fetch_github_vectorworks.sh +0 -85
  288. package/mcps/vectorworks-mcp/templates/index.html +0 -40
  289. package/scripts/ecosystem-health-audit.js +0 -257
  290. package/skills/bdb-dev-os-skill/SKILL.md +0 -49
  291. package/skills/bdb-dev-os-skill/package.json +0 -11
  292. package/skills/bdbsaastraining/SKILL.md +0 -316
  293. package/skills/bdbsaastraining/references/exam-pool.md +0 -313
  294. package/skills/bdbsaastraining/references/interaction-modes.md +0 -94
  295. package/skills/bdbsaastraining/references/track-a-ai-agent.md +0 -111
  296. package/skills/bdbsaastraining/references/track-b-wordpress.md +0 -111
  297. package/skills/bdbsaastraining/references/track-c-mailserver.md +0 -107
  298. package/skills/bdbsaastraining/references/track-d-debian.md +0 -109
  299. package/skills/bdbsaastraining/references/track-e-custom.md +0 -83
  300. package/skills/bdbsaastraining/scripts/build_profile.py +0 -529
  301. package/skills/bdbsaastraining/scripts/generate_certificate.py +0 -161
  302. package/skills/bdbsaastraining/scripts/preflight_check.sh +0 -150
  303. package/skills/bdbsaastraining/templates/certificate_template.html +0 -508
  304. package/skills/global_config/bdb-ecosystem-health/SKILL.md +0 -68
  305. package/skills/global_config/bdbsaas-ops/SKILL.md +0 -16
  306. 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.