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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (305) hide show
  1. package/.agents/skills/firecrawl/SKILL.md +149 -0
  2. package/.agents/skills/firecrawl/rules/install.md +82 -0
  3. package/.agents/skills/firecrawl/rules/security.md +26 -0
  4. package/.agents/skills/firecrawl-agent/SKILL.md +58 -0
  5. package/.agents/skills/firecrawl-build/SKILL.md +39 -0
  6. package/.agents/skills/firecrawl-build-interact/SKILL.md +68 -0
  7. package/.agents/skills/firecrawl-build-onboarding/SKILL.md +103 -0
  8. package/.agents/skills/firecrawl-build-onboarding/references/auth-flow.md +39 -0
  9. package/.agents/skills/firecrawl-build-onboarding/references/project-setup.md +20 -0
  10. package/.agents/skills/firecrawl-build-onboarding/references/sdk-installation.md +17 -0
  11. package/.agents/skills/firecrawl-build-scrape/SKILL.md +69 -0
  12. package/.agents/skills/firecrawl-build-search/SKILL.md +69 -0
  13. package/.agents/skills/firecrawl-crawl/SKILL.md +59 -0
  14. package/.agents/skills/firecrawl-download/SKILL.md +70 -0
  15. package/.agents/skills/firecrawl-interact/SKILL.md +84 -0
  16. package/.agents/skills/firecrawl-map/SKILL.md +51 -0
  17. package/.agents/skills/firecrawl-scrape/SKILL.md +69 -0
  18. package/.agents/skills/firecrawl-search/SKILL.md +60 -0
  19. package/CLAUDE.md +573 -0
  20. package/README.de.md +0 -8
  21. package/README.md +0 -8
  22. package/README.pt.md +0 -8
  23. package/assets/brand/ao-ant-mark.svg +91 -0
  24. package/assets/brand/bdb-core-mark.svg +34 -0
  25. package/assets/brand/heimdall-guardian-mark.svg +16 -0
  26. package/assets/brand/memb-crystal-mark.svg +18 -0
  27. package/bin/aos-config.mjs +89 -0
  28. package/bin/aos-dashboard.mjs +608 -0
  29. package/bin/aos-uninstall.mjs +227 -0
  30. package/docs/sessions/audit-2026-09-14-silent-failures.md +114 -0
  31. package/docs/skills_table.md +0 -3
  32. package/installer.js +471 -237
  33. package/mcps/RhinoMCP/cc-plugin/.claude/settings.json +10 -0
  34. package/mcps/after-effects-mcp/build/index.js +840 -0
  35. package/mcps/after-effects-mcp/build/scripts/applyEffect.jsx +153 -0
  36. package/mcps/after-effects-mcp/build/scripts/applyEffectTemplate.jsx +218 -0
  37. package/mcps/after-effects-mcp/build/scripts/createComposition.jsx +71 -0
  38. package/mcps/after-effects-mcp/build/scripts/createShapeLayer.jsx +147 -0
  39. package/mcps/after-effects-mcp/build/scripts/createSolidLayer.jsx +114 -0
  40. package/mcps/after-effects-mcp/build/scripts/createTextLayer.jsx +115 -0
  41. package/mcps/after-effects-mcp/build/scripts/getLayerInfo.jsx +192 -0
  42. package/mcps/after-effects-mcp/build/scripts/getProjectInfo.jsx +90 -0
  43. package/mcps/after-effects-mcp/build/scripts/listCompositions.jsx +50 -0
  44. package/mcps/after-effects-mcp/build/scripts/mcp-bridge-auto.jsx +1773 -0
  45. package/mcps/after-effects-mcp/build/scripts/setLayerProperties.jsx +160 -0
  46. package/mcps/computer-use-mcp/dist/client.d.ts +150 -0
  47. package/mcps/computer-use-mcp/dist/client.js +136 -0
  48. package/mcps/computer-use-mcp/dist/entrypoint.d.ts +16 -0
  49. package/mcps/computer-use-mcp/dist/entrypoint.js +26 -0
  50. package/mcps/computer-use-mcp/dist/native.d.ts +212 -0
  51. package/mcps/computer-use-mcp/dist/native.js +50 -0
  52. package/mcps/computer-use-mcp/dist/server.d.ts +32 -0
  53. package/mcps/computer-use-mcp/dist/server.js +342 -0
  54. package/mcps/computer-use-mcp/dist/session.d.ts +101 -0
  55. package/mcps/computer-use-mcp/dist/session.js +2372 -0
  56. package/package.json +13 -4
  57. package/skills/global_config/aos-project-init/SKILL.md +97 -130
  58. package/skills/global_config/aos-project-init/assets/openwikiignore.template +62 -0
  59. package/skills/global_config/aos-project-init/scripts/aos-project-doctor.mjs +38 -1
  60. package/skills/global_config/aos-setup/SKILL.md +98 -8
  61. package/skills/global_config/aos-setup/scripts/aos-doctor.mjs +21 -2
  62. package/skills/global_config/ask-tim/SKILL.md +2 -7
  63. package/skills/global_config/openwiki-skill/scripts/openwiki_daemon.py +65 -12
  64. package/bin/setup-saas.mjs +0 -792
  65. package/mcps/blender-mcp-server/.dockerignore +0 -19
  66. package/mcps/blender-mcp-server/.github/workflows/ci.yml +0 -67
  67. package/mcps/blender-mcp-server/.github/workflows/publish-pypi.yml +0 -54
  68. package/mcps/blender-mcp-server/CHANGELOG.md +0 -64
  69. package/mcps/blender-mcp-server/CONTRIBUTING.md +0 -107
  70. package/mcps/blender-mcp-server/Dockerfile +0 -19
  71. package/mcps/blender-mcp-server/LICENSE +0 -21
  72. package/mcps/blender-mcp-server/README.md +0 -409
  73. package/mcps/blender-mcp-server/addon/__init__.py +0 -1440
  74. package/mcps/blender-mcp-server/addon/models.py +0 -223
  75. package/mcps/blender-mcp-server/pyproject.toml +0 -120
  76. package/mcps/blender-mcp-server/scripts/blender_bridge_request.py +0 -71
  77. package/mcps/blender-mcp-server/scripts/blender_create_test_cube.py +0 -49
  78. package/mcps/blender-mcp-server/scripts/blender_scene_info.py +0 -38
  79. package/mcps/blender-mcp-server/scripts/build_addon_zip.sh +0 -29
  80. package/mcps/blender-mcp-server/scripts/demos/README.md +0 -186
  81. package/mcps/blender-mcp-server/scripts/demos/dam_break_scene.py +0 -276
  82. package/mcps/blender-mcp-server/scripts/demos/open_dam_break_gui.py +0 -33
  83. package/mcps/blender-mcp-server/scripts/demos/pipe_movement_study.py +0 -518
  84. package/mcps/blender-mcp-server/scripts/demos/pipe_pressure_failure_scene.py +0 -806
  85. package/mcps/blender-mcp-server/scripts/demos/procedural_dam_break_scene.py +0 -600
  86. package/mcps/blender-mcp-server/scripts/demos/run_dam_break.py +0 -510
  87. package/mcps/blender-mcp-server/scripts/launch_blender_gui.py +0 -41
  88. package/mcps/blender-mcp-server/scripts/library/README.md +0 -64
  89. package/mcps/blender-mcp-server/scripts/library/apply_transforms.py +0 -46
  90. package/mcps/blender-mcp-server/scripts/library/camera.py +0 -51
  91. package/mcps/blender-mcp-server/scripts/library/collections.py +0 -65
  92. package/mcps/blender-mcp-server/scripts/library/create_mesh.py +0 -41
  93. package/mcps/blender-mcp-server/scripts/library/effector.py +0 -48
  94. package/mcps/blender-mcp-server/scripts/library/fluid_domain.py +0 -80
  95. package/mcps/blender-mcp-server/scripts/library/fluid_inflow.py +0 -98
  96. package/mcps/blender-mcp-server/scripts/library/frame_range.py +0 -35
  97. package/mcps/blender-mcp-server/scripts/library/keyframes.py +0 -59
  98. package/mcps/blender-mcp-server/scripts/library/rigid_body.py +0 -52
  99. package/mcps/blender-mcp-server/scripts/library/save_blend.py +0 -40
  100. package/mcps/blender-mcp-server/scripts/server_start.sh +0 -26
  101. package/mcps/blender-mcp-server/src/blender_mcp_server/__init__.py +0 -3
  102. package/mcps/blender-mcp-server/src/blender_mcp_server/headless.py +0 -330
  103. package/mcps/blender-mcp-server/src/blender_mcp_server/server.py +0 -606
  104. package/mcps/davinci-mcp-professional/.bandit +0 -35
  105. package/mcps/davinci-mcp-professional/.claude/commands/security-review.md +0 -191
  106. package/mcps/davinci-mcp-professional/.claude/settings.json +0 -1
  107. package/mcps/davinci-mcp-professional/.editorconfig +0 -27
  108. package/mcps/davinci-mcp-professional/.gitattributes +0 -207
  109. package/mcps/davinci-mcp-professional/.github/CODEOWNERS +0 -2
  110. package/mcps/davinci-mcp-professional/.github/ISSUE_TEMPLATE/bug_report.md +0 -33
  111. package/mcps/davinci-mcp-professional/.github/ISSUE_TEMPLATE/feature_request.md +0 -19
  112. package/mcps/davinci-mcp-professional/.github/PULL_REQUEST_TEMPLATE.md +0 -20
  113. package/mcps/davinci-mcp-professional/.github/SECURITY.md +0 -97
  114. package/mcps/davinci-mcp-professional/.github/dependabot.yml +0 -27
  115. package/mcps/davinci-mcp-professional/.github/workflows/ci.yml +0 -39
  116. package/mcps/davinci-mcp-professional/ATTRIBUTION.md +0 -4
  117. package/mcps/davinci-mcp-professional/AUTHORS.md +0 -9
  118. package/mcps/davinci-mcp-professional/BUGS.md +0 -55
  119. package/mcps/davinci-mcp-professional/CLAUDE.md +0 -229
  120. package/mcps/davinci-mcp-professional/CONTRIBUTING.md +0 -51
  121. package/mcps/davinci-mcp-professional/COPYING.md +0 -228
  122. package/mcps/davinci-mcp-professional/Doxyfile +0 -379
  123. package/mcps/davinci-mcp-professional/README.md +0 -143
  124. package/mcps/davinci-mcp-professional/SECURITY.md +0 -40
  125. package/mcps/davinci-mcp-professional/USING.md +0 -301
  126. package/mcps/davinci-mcp-professional/VERSION.md +0 -13
  127. package/mcps/davinci-mcp-professional/build.py +0 -169
  128. package/mcps/davinci-mcp-professional/claude_desktop_config_template.json +0 -11
  129. package/mcps/davinci-mcp-professional/hooks/ci-check.sh +0 -29
  130. package/mcps/davinci-mcp-professional/hooks/pre-push +0 -46
  131. package/mcps/davinci-mcp-professional/main.py +0 -40
  132. package/mcps/davinci-mcp-professional/mcp_server.py +0 -30
  133. package/mcps/davinci-mcp-professional/pyproject.toml +0 -115
  134. package/mcps/davinci-mcp-professional/security_audit.py +0 -379
  135. package/mcps/davinci-mcp-professional/src/davinci_mcp/__init__.py +0 -19
  136. package/mcps/davinci-mcp-professional/src/davinci_mcp/cli.py +0 -138
  137. package/mcps/davinci-mcp-professional/src/davinci_mcp/resolve_client.py +0 -342
  138. package/mcps/davinci-mcp-professional/src/davinci_mcp/resources/__init__.py +0 -60
  139. package/mcps/davinci-mcp-professional/src/davinci_mcp/server.py +0 -185
  140. package/mcps/davinci-mcp-professional/src/davinci_mcp/tools/__init__.py +0 -146
  141. package/mcps/davinci-mcp-professional/src/davinci_mcp/types.py +0 -125
  142. package/mcps/davinci-mcp-professional/src/davinci_mcp/utils/__init__.py +0 -19
  143. package/mcps/davinci-mcp-professional/src/davinci_mcp/utils/platform.py +0 -239
  144. package/mcps/davinci-mcp-professional/test.py +0 -186
  145. package/mcps/davinci-mcp-professional/uv.lock +0 -2073
  146. package/mcps/davinci-resolve-mcp/.claude/skills/media-analysis.md +0 -44
  147. package/mcps/davinci-resolve-mcp/.clinerules +0 -17
  148. package/mcps/davinci-resolve-mcp/.cursorrules +0 -17
  149. package/mcps/davinci-resolve-mcp/.github/copilot-instructions.md +0 -17
  150. package/mcps/davinci-resolve-mcp/.github/workflows/npm-publish.yml +0 -109
  151. package/mcps/davinci-resolve-mcp/.windsurfrules +0 -17
  152. package/mcps/davinci-resolve-mcp/AGENTS.md +0 -114
  153. package/mcps/davinci-resolve-mcp/CHANGELOG.md +0 -2648
  154. package/mcps/davinci-resolve-mcp/CLAUDE.md +0 -15
  155. package/mcps/davinci-resolve-mcp/LICENSE +0 -21
  156. package/mcps/davinci-resolve-mcp/README.md +0 -173
  157. package/mcps/davinci-resolve-mcp/SECURITY.md +0 -53
  158. package/mcps/davinci-resolve-mcp/bin/davinci-resolve-mcp.mjs +0 -450
  159. package/mcps/davinci-resolve-mcp/examples/README.md +0 -53
  160. package/mcps/davinci-resolve-mcp/examples/markers/README.md +0 -81
  161. package/mcps/davinci-resolve-mcp/examples/media/README.md +0 -94
  162. package/mcps/davinci-resolve-mcp/examples/timeline/README.md +0 -98
  163. package/mcps/davinci-resolve-mcp/install.py +0 -1687
  164. package/mcps/davinci-resolve-mcp/package.json +0 -52
  165. package/mcps/davinci-resolve-mcp/release-notes/v2.22.0.md +0 -51
  166. package/mcps/davinci-resolve-mcp/release-notes/v2.23.0.md +0 -51
  167. package/mcps/davinci-resolve-mcp/release-notes/v2.23.1.md +0 -35
  168. package/mcps/davinci-resolve-mcp/release-notes/v2.24.1.md +0 -32
  169. package/mcps/davinci-resolve-mcp/scripts/audit_api_parity.py +0 -275
  170. package/mcps/davinci-resolve-mcp/scripts/audit_readwrite_symmetry.py +0 -80
  171. package/mcps/davinci-resolve-mcp/scripts/doctor.py +0 -227
  172. package/mcps/davinci-resolve-mcp/scripts/gen_api_limitations.py +0 -144
  173. package/mcps/davinci-resolve-mcp/scripts/live_media_analysis_polish_probe.py +0 -65
  174. package/mcps/davinci-resolve-mcp/scripts/measure_bridge_cost.py +0 -65
  175. package/mcps/davinci-resolve-mcp/scripts/regen_panel_screenshots.py +0 -76
  176. package/mcps/davinci-resolve-mcp/src/__init__.py +0 -3
  177. package/mcps/davinci-resolve-mcp/src/analysis_dashboard.py +0 -15505
  178. package/mcps/davinci-resolve-mcp/src/batch_cli.py +0 -540
  179. package/mcps/davinci-resolve-mcp/src/control_panel.py +0 -13
  180. package/mcps/davinci-resolve-mcp/src/granular/__init__.py +0 -17
  181. package/mcps/davinci-resolve-mcp/src/granular/common.py +0 -741
  182. package/mcps/davinci-resolve-mcp/src/granular/folder.py +0 -420
  183. package/mcps/davinci-resolve-mcp/src/granular/gallery.py +0 -306
  184. package/mcps/davinci-resolve-mcp/src/granular/graph.py +0 -309
  185. package/mcps/davinci-resolve-mcp/src/granular/media_pool.py +0 -679
  186. package/mcps/davinci-resolve-mcp/src/granular/media_pool_item.py +0 -1020
  187. package/mcps/davinci-resolve-mcp/src/granular/media_storage.py +0 -179
  188. package/mcps/davinci-resolve-mcp/src/granular/project.py +0 -1654
  189. package/mcps/davinci-resolve-mcp/src/granular/resolve_control.py +0 -538
  190. package/mcps/davinci-resolve-mcp/src/granular/timeline.py +0 -1075
  191. package/mcps/davinci-resolve-mcp/src/granular/timeline_item.py +0 -2251
  192. package/mcps/davinci-resolve-mcp/src/resolve_mcp_server.py +0 -43
  193. package/mcps/davinci-resolve-mcp/src/server.py +0 -24116
  194. package/mcps/davinci-resolve-mcp/src/utils/__init__.py +0 -3
  195. package/mcps/davinci-resolve-mcp/src/utils/actor_identity.py +0 -46
  196. package/mcps/davinci-resolve-mcp/src/utils/analysis_caps.py +0 -678
  197. package/mcps/davinci-resolve-mcp/src/utils/analysis_memory.py +0 -755
  198. package/mcps/davinci-resolve-mcp/src/utils/analysis_runs.py +0 -307
  199. package/mcps/davinci-resolve-mcp/src/utils/analysis_store.py +0 -945
  200. package/mcps/davinci-resolve-mcp/src/utils/api_truth.py +0 -525
  201. package/mcps/davinci-resolve-mcp/src/utils/app_control.py +0 -319
  202. package/mcps/davinci-resolve-mcp/src/utils/audio_fairlight_live_probe.py +0 -263
  203. package/mcps/davinci-resolve-mcp/src/utils/brain_edits.py +0 -387
  204. package/mcps/davinci-resolve-mcp/src/utils/bridge_metrics.py +0 -76
  205. package/mcps/davinci-resolve-mcp/src/utils/cdl.py +0 -20
  206. package/mcps/davinci-resolve-mcp/src/utils/clip_query.py +0 -85
  207. package/mcps/davinci-resolve-mcp/src/utils/cloud_operations.py +0 -192
  208. package/mcps/davinci-resolve-mcp/src/utils/color_grade_live_probe.py +0 -444
  209. package/mcps/davinci-resolve-mcp/src/utils/contracts.py +0 -102
  210. package/mcps/davinci-resolve-mcp/src/utils/cut_ir.py +0 -115
  211. package/mcps/davinci-resolve-mcp/src/utils/dctl_templates.py +0 -368
  212. package/mcps/davinci-resolve-mcp/src/utils/deep_vision.py +0 -643
  213. package/mcps/davinci-resolve-mcp/src/utils/destructive_hook.py +0 -606
  214. package/mcps/davinci-resolve-mcp/src/utils/edit_engine.py +0 -737
  215. package/mcps/davinci-resolve-mcp/src/utils/embeddings.py +0 -922
  216. package/mcps/davinci-resolve-mcp/src/utils/entities.py +0 -579
  217. package/mcps/davinci-resolve-mcp/src/utils/extension_authoring_live_probe.py +0 -292
  218. package/mcps/davinci-resolve-mcp/src/utils/failure_tracker.py +0 -119
  219. package/mcps/davinci-resolve-mcp/src/utils/fuse_templates.py +0 -1968
  220. package/mcps/davinci-resolve-mcp/src/utils/fusion_composition_live_probe.py +0 -284
  221. package/mcps/davinci-resolve-mcp/src/utils/fusion_group_settings.py +0 -334
  222. package/mcps/davinci-resolve-mcp/src/utils/layout_presets.py +0 -333
  223. package/mcps/davinci-resolve-mcp/src/utils/mcp_stdio.py +0 -32
  224. package/mcps/davinci-resolve-mcp/src/utils/mcp_transport.py +0 -128
  225. package/mcps/davinci-resolve-mcp/src/utils/media_analysis.py +0 -7690
  226. package/mcps/davinci-resolve-mcp/src/utils/media_analysis_jobs.py +0 -805
  227. package/mcps/davinci-resolve-mcp/src/utils/media_pool_changes.py +0 -121
  228. package/mcps/davinci-resolve-mcp/src/utils/media_pool_ingest_live_probe.py +0 -592
  229. package/mcps/davinci-resolve-mcp/src/utils/multicam.py +0 -393
  230. package/mcps/davinci-resolve-mcp/src/utils/object_inspection.py +0 -301
  231. package/mcps/davinci-resolve-mcp/src/utils/page_lock.py +0 -75
  232. package/mcps/davinci-resolve-mcp/src/utils/platform.py +0 -157
  233. package/mcps/davinci-resolve-mcp/src/utils/proc.py +0 -26
  234. package/mcps/davinci-resolve-mcp/src/utils/project_cleanup.py +0 -73
  235. package/mcps/davinci-resolve-mcp/src/utils/project_lifecycle_live_probe.py +0 -376
  236. package/mcps/davinci-resolve-mcp/src/utils/project_lint.py +0 -131
  237. package/mcps/davinci-resolve-mcp/src/utils/project_properties.py +0 -601
  238. package/mcps/davinci-resolve-mcp/src/utils/project_spec.py +0 -459
  239. package/mcps/davinci-resolve-mcp/src/utils/readback.py +0 -91
  240. package/mcps/davinci-resolve-mcp/src/utils/render_deliver_live_probe.py +0 -384
  241. package/mcps/davinci-resolve-mcp/src/utils/resolve_ai_governance.py +0 -214
  242. package/mcps/davinci-resolve-mcp/src/utils/resolve_ai_ledger.py +0 -244
  243. package/mcps/davinci-resolve-mcp/src/utils/resolve_busy.py +0 -171
  244. package/mcps/davinci-resolve-mcp/src/utils/resolve_connection.py +0 -77
  245. package/mcps/davinci-resolve-mcp/src/utils/review_annotation_live_probe.py +0 -352
  246. package/mcps/davinci-resolve-mcp/src/utils/script_templates.py +0 -1193
  247. package/mcps/davinci-resolve-mcp/src/utils/shot_relationships.py +0 -544
  248. package/mcps/davinci-resolve-mcp/src/utils/structural_diff.py +0 -175
  249. package/mcps/davinci-resolve-mcp/src/utils/sync_detection.py +0 -889
  250. package/mcps/davinci-resolve-mcp/src/utils/timeline_brain_db.py +0 -826
  251. package/mcps/davinci-resolve-mcp/src/utils/timeline_conform_live_probe.py +0 -280
  252. package/mcps/davinci-resolve-mcp/src/utils/timeline_kernel_live_probe.py +0 -1092
  253. package/mcps/davinci-resolve-mcp/src/utils/timeline_kernel_probe.py +0 -185
  254. package/mcps/davinci-resolve-mcp/src/utils/timeline_title_text.py +0 -87
  255. package/mcps/davinci-resolve-mcp/src/utils/timeline_versioning.py +0 -730
  256. package/mcps/davinci-resolve-mcp/src/utils/update_check.py +0 -685
  257. package/mcps/vectorworks-mcp/.dockerignore +0 -8
  258. package/mcps/vectorworks-mcp/Dockerfile +0 -28
  259. package/mcps/vectorworks-mcp/README.md +0 -156
  260. package/mcps/vectorworks-mcp/app/__init__.py +0 -2
  261. package/mcps/vectorworks-mcp/app/api.py +0 -52
  262. package/mcps/vectorworks-mcp/app/chunking.py +0 -56
  263. package/mcps/vectorworks-mcp/app/config.py +0 -29
  264. package/mcps/vectorworks-mcp/app/embeddings.py +0 -28
  265. package/mcps/vectorworks-mcp/app/indexer.py +0 -106
  266. package/mcps/vectorworks-mcp/app/main.py +0 -33
  267. package/mcps/vectorworks-mcp/app/mcp_server.py +0 -71
  268. package/mcps/vectorworks-mcp/app/search.py +0 -54
  269. package/mcps/vectorworks-mcp/app/utils.py +0 -14
  270. package/mcps/vectorworks-mcp/data/.gitkeep +0 -1
  271. package/mcps/vectorworks-mcp/data/vw-app-help/VW2022_PluginScript.htm +0 -95
  272. package/mcps/vectorworks-mcp/data/vw-app-help/VW2022_ScriptEditor.htm +0 -266
  273. package/mcps/vectorworks-mcp/data/vw-app-help/VW2022_Scripting.htm +0 -106
  274. package/mcps/vectorworks-mcp/data/vw-app-help/VW2023_CreatingScriptedPlugins.htm +0 -327
  275. package/mcps/vectorworks-mcp/data/vw-app-help/VW2024_RunningScripts.htm +0 -116
  276. package/mcps/vectorworks-mcp/data/vw-devwiki/VS_Function_Reference_category.html +0 -2129
  277. package/mcps/vectorworks-mcp/data/vw-jp-ref/ObjectsSymbols.html +0 -2035
  278. package/mcps/vectorworks-mcp/data/vw-jp-ref/ScriptFunctionReference.html +0 -29
  279. package/mcps/vectorworks-mcp/design.md +0 -57
  280. package/mcps/vectorworks-mcp/docker-compose.yml +0 -18
  281. package/mcps/vectorworks-mcp/index/.gitkeep +0 -1
  282. package/mcps/vectorworks-mcp/index/meta.jsonl +0 -3956
  283. package/mcps/vectorworks-mcp/index/vw.faiss +0 -0
  284. package/mcps/vectorworks-mcp/requirements.txt +0 -10
  285. package/mcps/vectorworks-mcp/scripts/fetch_docs_minimal.sh +0 -84
  286. package/mcps/vectorworks-mcp/scripts/fetch_github_vectorworks.sh +0 -85
  287. package/mcps/vectorworks-mcp/templates/index.html +0 -40
  288. package/scripts/ecosystem-health-audit.js +0 -257
  289. package/skills/bdb-dev-os-skill/SKILL.md +0 -49
  290. package/skills/bdb-dev-os-skill/package.json +0 -11
  291. package/skills/bdbsaastraining/SKILL.md +0 -316
  292. package/skills/bdbsaastraining/references/exam-pool.md +0 -313
  293. package/skills/bdbsaastraining/references/interaction-modes.md +0 -94
  294. package/skills/bdbsaastraining/references/track-a-ai-agent.md +0 -111
  295. package/skills/bdbsaastraining/references/track-b-wordpress.md +0 -111
  296. package/skills/bdbsaastraining/references/track-c-mailserver.md +0 -107
  297. package/skills/bdbsaastraining/references/track-d-debian.md +0 -109
  298. package/skills/bdbsaastraining/references/track-e-custom.md +0 -83
  299. package/skills/bdbsaastraining/scripts/build_profile.py +0 -529
  300. package/skills/bdbsaastraining/scripts/generate_certificate.py +0 -161
  301. package/skills/bdbsaastraining/scripts/preflight_check.sh +0 -150
  302. package/skills/bdbsaastraining/templates/certificate_template.html +0 -508
  303. package/skills/global_config/bdb-ecosystem-health/SKILL.md +0 -68
  304. package/skills/global_config/bdbsaas-ops/SKILL.md +0 -16
  305. package/skills/global_config/bdbsaashost/SKILL.md +0 -125
@@ -1,28 +0,0 @@
1
- FROM python:3.11-slim
2
-
3
- ENV PYTHONDONTWRITEBYTECODE=1 \
4
- PYTHONUNBUFFERED=1
5
-
6
- WORKDIR /app
7
-
8
- # System deps for faiss/numpy
9
- RUN apt-get update && apt-get install -y --no-install-recommends \
10
- build-essential \
11
- g++ \
12
- libopenblas-dev \
13
- git \
14
- curl \
15
- ca-certificates \
16
- && rm -rf /var/lib/apt/lists/*
17
-
18
- COPY requirements.txt ./
19
- RUN pip install --no-cache-dir -r requirements.txt
20
-
21
- COPY . .
22
-
23
- # Default directories
24
- RUN mkdir -p /app/data /app/index
25
-
26
- EXPOSE 8000 8765
27
-
28
- CMD ["python", "-m", "app.main"]
@@ -1,156 +0,0 @@
1
- # Vectorworks RAG + MCP
2
-
3
- - Vectorworks の Python / VectorScript ドキュメントをローカルに取り込み、FAISS で横断検索します。
4
- - FastAPI で `/search` `/answer` `/get` を提供し、簡易 Web UI から検索・出典確認できます。
5
- - WebSocket(JSON-RPC 2.0) の MCP サーバーを同時起動し、`vw.search` / `vw.answer` / `vw.get` ツールを提供します。
6
- - docker compose で `app`(API/MCP)と `db`(Postgres 16)を同時起動します
7
-
8
- ---
9
-
10
- ## 必要要件
11
-
12
- - Docker / Docker Compose(v2)
13
-
14
- ## クイックスタート
15
-
16
- 1. ビルド
17
-
18
- - `docker compose build`
19
-
20
- 2. 文書取得
21
-
22
- - `docker compose run --rm app bash scripts/fetch_docs_minimal.sh`
23
- - `docker compose run --rm -e GITHUB_TOKEN="$GITHUB_TOKEN" app bash scripts/fetch_github_vectorworks.sh`
24
-
25
- 3. ベクター生成(埋め込み + FAISS)
26
-
27
- - `docker compose run --rm app python -m app.indexer`
28
- - 既にインデックスがある状態でドキュメントを追加した場合は再作成してください:
29
- - `docker compose run --rm app python -m app.indexer --rebuild`
30
-
31
- 4. 起動(UI + MCP + Postgres)
32
-
33
- - `docker compose up`
34
-
35
- 5. アクセス
36
-
37
- - UI: `http://localhost:8000`
38
- - MCP: `ws://localhost:8765`
39
-
40
- 補足
41
-
42
- - 2. と 3) は次のワンライナーでも可:
43
- - `docker compose run --rm app bash -lc 'scripts/fetch_docs_minimal.sh && python -m app.indexer'`
44
-
45
- ## ドキュメントの取得
46
-
47
- 以下のコマンドで、必要最小限のドキュメント(md/html のみ)を `data/` に取得します。
48
-
49
- - 依存: `git`, `curl`
50
- - 実行(コンテナ内):
51
- - `docker compose run --rm app bash scripts/fetch_docs_minimal.sh`
52
- - ネットワーク事情で 403 が発生する場合、スクリプトは該当ページをスキップして続行します。
53
- - 必要なら UA を上書き可能: `docker compose run --rm -e UA="Mozilla/5.0 ..." app bash scripts/fetch_docs_minimal.sh`
54
-
55
- 取得対象(要点のみ)
56
-
57
- - GitHub: Vectorworks/developer-scripting(入門/導線の Markdown)
58
- - App Help: Scripting の基本導線(2022/2023/2024 の要点ページ)
59
- - 日本語サイト: VectorScript 関数索引ページ + 例示ページ
60
- - Developer Wiki: VS Function Reference カテゴリインデックス(HTML)
61
-
62
- 注意
63
-
64
- - インデクサは `.md` `.markdown` `.html` `.htm` `.txt` のみ対応です。PDF 等は対象外です。
65
-
66
- ## GitHub(Vectorworks 指定リポのみ取得)
67
-
68
- - 目的: 次の3つのリポジトリのみを `data/github/vectorworks/` にクローン(または更新)します。
69
- - `Vectorworks/developer-scripting`
70
- - `Vectorworks/developer-sdk`
71
- - `Vectorworks/developer-worksheets`
72
- - 実行(コンテナ内):
73
- - `docker compose run --rm app bash scripts/fetch_github_vectorworks.sh`
74
- - 取得先: `data/github/vectorworks/<repo>`
75
- - 追加/変更したい場合は環境変数 `REPOS` で指定できます(スペースまたはカンマ区切り)。
76
- - 例: `docker compose run --rm -e REPOS="Vectorworks/developer-scripting,Vectorworks/developer-sdk" app bash scripts/fetch_github_vectorworks.sh`
77
- - 更新方式の指定(任意): `UPDATE_MODE=pull`(既定)または `UPDATE_MODE=reset`
78
- - `pull`: `git pull --ff-only --depth=1 --prune` による高速更新(ローカル変更がある場合は失敗→フェールセーフで fetch+reset)
79
- - `reset`: `fetch --depth=1` 後に `reset --hard` で完全同期(ローカル変更を破棄)
80
-
81
- 注意
82
-
83
- - インデクサはテキスト系拡張子(.md/.html/.txt 等)のみ対象とします。
84
-
85
- ## ベクター生成(埋め込み + FAISS インデックス)
86
-
87
- - 実行(コンテナ内):
88
- - `docker compose run --rm app python -m app.indexer`
89
-
90
- 実行後、`index/` に `vw.faiss` と `meta.jsonl` が作成されます。
91
- (先に `bash scripts/fetch_docs_minimal.sh` などで `data/` に文書がある状態にしてください)
92
-
93
- ## 起動(UI + MCP + Postgres)
94
-
95
- - `docker compose up --build`
96
- - UI: `http://localhost:8000`
97
- - MCP: `ws://localhost:8765`
98
- - Postgres はコンテナ内部ネットワークで起動(ホストへ未公開)
99
-
100
- ## API 例
101
-
102
- - 検索: `GET /search?q=PushAttrs&k=6`
103
- - 例: `curl -s "http://localhost:8000/search?q=VectorScript&k=6" | jq .`
104
- - 回答(ドラフト): `GET /answer?q=...&k=6`
105
- - 例: `curl -s "http://localhost:8000/answer?q=record+format" | jq .`
106
- - チャンク取得: `GET /get?doc_id=...&chunk_id=...`
107
-
108
- UI は `GET /` にあり、検索フォームから同等の結果を確認できます。
109
-
110
- ## MCP(Model Context Protocol)
111
-
112
- - VS Code から接続: 次のコマンドで MCP を追加
113
- - `code --add-mcp '{"name":"vw_docs_local","url":"ws://localhost:8765"}'`
114
- - サポートするツール
115
- - `vw.search({ query, k? })`
116
- - `vw.answer({ query, k? })`
117
- - `vw.get({ doc_id, chunk_id })`
118
-
119
- 実装は JSON-RPC 2.0 ベースの WebSocket サーバーです(`app/mcp_server.py`)。
120
-
121
- ## ディレクトリ構成
122
-
123
- - `app/` アプリ本体
124
- - `api.py` FastAPI アプリ
125
- - `mcp_server.py` MCP(WebSocket) サーバー
126
- - `indexer.py` 取込・ベクター化(埋め込み + FAISS 作成)
127
- - `search.py` 検索/回答のコアロジック
128
- - `chunking.py` チャンク分割(約 700 トークン相当の文字長を目安)
129
- - `templates/` Web UI テンプレート
130
- - `data/` 原文の md/html(相対パスが `doc_id`)
131
- - `index/` FAISS とメタデータ(`vw.faiss`, `meta.jsonl`)
132
-
133
- ## 環境変数(任意)
134
-
135
- - `DATA_DIR` データ配置ディレクトリ(既定: `data`)
136
- - `INDEX_DIR` インデックス出力ディレクトリ(既定: `index`)
137
- - `EMBED_MODEL` 埋め込みモデル(既定: `sentence-transformers/all-MiniLM-L6-v2`)
138
- - `CHUNK_CHARS` チャンク文字長の目安(既定: `2800` ≒ 700 トークン)
139
- - `CHUNK_OVERLAP` チャンクの文字オーバーラップ(既定: `480`)
140
- - `API_HOST` / `API_PORT` FastAPI バインド(既定: `0.0.0.0:8000`)
141
- - `MCP_HOST` / `MCP_PORT` MCP バインド(既定: `0.0.0.0:8765`)
142
-
143
- Postgres(将来用)
144
-
145
- - `PGHOST` / `PGPORT` / `PGDATABASE` / `PGUSER` / `PGPASSWORD`
146
-
147
- ## 運用メモ
148
-
149
- - ドキュメントを更新したら、再度ベクター生成: `python -m app.indexer`
150
- - 初回は埋め込みモデルのダウンロードで時間がかかる場合があります。
151
- - CPU で実行する前提のため、FAISS は `IndexFlatIP` + 正規化ベクター(cosine 相当)を使用しています。
152
-
153
- ## ライセンス / 注意
154
-
155
- - このリポジトリはドキュメントを含みません。各自の利用規約・著作権に従って `data/` に配置してください。
156
- - `answer` は抜粋ベースの簡易ドラフトです。最終判断は原文を確認してください。
@@ -1,2 +0,0 @@
1
- __all__ = []
2
-
@@ -1,52 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from pathlib import Path
4
- from typing import Optional
5
-
6
- from fastapi import FastAPI, HTTPException, Query, Request
7
- from fastapi.responses import HTMLResponse
8
- from fastapi.templating import Jinja2Templates
9
-
10
- from .config import settings
11
- from .embeddings import Embedder
12
- from .indexer import IndexPaths, ensure_index
13
- from .search import Searcher
14
-
15
-
16
- def create_app() -> FastAPI:
17
- app = FastAPI(title="Vectorworks Docs RAG")
18
-
19
- templates = Jinja2Templates(directory=str(Path("templates")))
20
-
21
- embedder = Embedder()
22
- index, meta = ensure_index(embedder)
23
- searcher = Searcher(index=index, meta=meta, embedder=embedder)
24
-
25
- @app.get("/", response_class=HTMLResponse)
26
- async def home(request: Request, q: Optional[str] = None, k: int = 6):
27
- results = searcher.search(q, k=k) if q else []
28
- return templates.TemplateResponse(
29
- "index.html",
30
- {"request": request, "q": q or "", "results": results},
31
- )
32
-
33
- @app.get("/search")
34
- async def api_search(q: str = Query(...), k: int = 6):
35
- return {"query": q, "results": searcher.search(q, k=k)}
36
-
37
- @app.get("/answer")
38
- async def api_answer(q: str = Query(...), k: int = 6):
39
- return searcher.answer(q, k=k)
40
-
41
- @app.get("/get")
42
- async def api_get(doc_id: str, chunk_id: int):
43
- try:
44
- return searcher.get(doc_id, chunk_id)
45
- except KeyError as e:
46
- raise HTTPException(status_code=404, detail=str(e))
47
-
48
- return app
49
-
50
-
51
- app = create_app()
52
-
@@ -1,56 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import re
4
- from typing import Iterable, List
5
-
6
-
7
- def split_paragraphs(text: str) -> List[str]:
8
- # Normalize line endings and split on blank lines
9
- parts = re.split(r"\n\s*\n+", text.strip())
10
- return [p.strip() for p in parts if p.strip()]
11
-
12
-
13
- def merge_to_chunks(paragraphs: Iterable[str], max_chars: int, overlap: int) -> List[str]:
14
- chunks: List[str] = []
15
- buf: List[str] = []
16
- buf_len = 0
17
-
18
- for p in paragraphs:
19
- # If a single paragraph is larger than max, hard-split by sentences
20
- if len(p) > max_chars:
21
- sentences = re.split(r"(?<=[。..!?])\s+", p)
22
- p_parts: List[str] = []
23
- cur = ""
24
- for s in sentences:
25
- if not s:
26
- continue
27
- if len(cur) + len(s) + 1 > max_chars and cur:
28
- p_parts.append(cur)
29
- cur = s
30
- else:
31
- cur = (cur + " " + s).strip()
32
- if cur:
33
- p_parts.append(cur)
34
- else:
35
- p_parts = [p]
36
-
37
- for part in p_parts:
38
- if buf_len + len(part) + 2 > max_chars and buf:
39
- chunks.append("\n\n".join(buf))
40
- # overlap by characters from the end of the previous chunk
41
- if overlap > 0:
42
- tail = chunks[-1][-overlap:]
43
- buf = [tail, part]
44
- buf_len = len(tail) + len(part) + 2
45
- else:
46
- buf = [part]
47
- buf_len = len(part)
48
- else:
49
- buf.append(part)
50
- buf_len += len(part) + 2
51
-
52
- if buf:
53
- chunks.append("\n\n".join(buf))
54
-
55
- return chunks
56
-
@@ -1,29 +0,0 @@
1
- import os
2
- from dataclasses import dataclass
3
-
4
-
5
- @dataclass
6
- class Settings:
7
- # Paths
8
- data_dir: str = os.getenv("DATA_DIR", "data")
9
- index_dir: str = os.getenv("INDEX_DIR", "index")
10
- index_file: str = os.getenv("INDEX_FILE", "vw.faiss")
11
- meta_file: str = os.getenv("META_FILE", "meta.jsonl")
12
-
13
- # Embeddings
14
- model_name: str = os.getenv("EMBED_MODEL", "sentence-transformers/all-MiniLM-L6-v2")
15
- batch_size: int = int(os.getenv("EMBED_BATCH", "32"))
16
-
17
- # Chunking
18
- chunk_chars: int = int(os.getenv("CHUNK_CHARS", "2800"))
19
- chunk_overlap: int = int(os.getenv("CHUNK_OVERLAP", "480"))
20
-
21
- # API / MCP
22
- api_host: str = os.getenv("API_HOST", "0.0.0.0")
23
- api_port: int = int(os.getenv("API_PORT", "8000"))
24
- mcp_host: str = os.getenv("MCP_HOST", "0.0.0.0")
25
- mcp_port: int = int(os.getenv("MCP_PORT", "8765"))
26
-
27
-
28
- settings = Settings()
29
-
@@ -1,28 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from dataclasses import dataclass
4
- from typing import List
5
-
6
- import numpy as np
7
- from sentence_transformers import SentenceTransformer
8
-
9
- from .config import settings
10
-
11
-
12
- @dataclass
13
- class Embedder:
14
- model_name: str = settings.model_name
15
- batch_size: int = settings.batch_size
16
-
17
- def __post_init__(self):
18
- self.model = SentenceTransformer(self.model_name, device="cpu")
19
-
20
- def encode(self, texts: List[str]) -> np.ndarray:
21
- vectors = self.model.encode(
22
- texts,
23
- batch_size=self.batch_size,
24
- show_progress_bar=False,
25
- normalize_embeddings=True, # cosine via dot product
26
- )
27
- return np.asarray(vectors, dtype=np.float32)
28
-
@@ -1,106 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import argparse
4
- import json
5
- from dataclasses import dataclass
6
- from pathlib import Path
7
- from typing import List, Tuple
8
-
9
- import faiss # type: ignore
10
- import numpy as np
11
-
12
- from .chunking import merge_to_chunks, split_paragraphs
13
- from .config import settings
14
- from .embeddings import Embedder
15
- from .utils import iter_text_files
16
-
17
-
18
- @dataclass
19
- class IndexPaths:
20
- base: Path
21
- index_file: Path
22
- meta_file: Path
23
-
24
- @staticmethod
25
- def from_settings() -> "IndexPaths":
26
- base = Path(settings.index_dir)
27
- return IndexPaths(
28
- base=base,
29
- index_file=base / settings.index_file,
30
- meta_file=base / settings.meta_file,
31
- )
32
-
33
-
34
- def build_index(data_dir: Path, index_paths: IndexPaths, embedder: Embedder) -> Tuple[faiss.Index, List[dict]]:
35
- index_paths.base.mkdir(parents=True, exist_ok=True)
36
-
37
- texts: List[str] = []
38
- meta: List[dict] = []
39
-
40
- for src in iter_text_files(data_dir):
41
- rel = src.relative_to(data_dir).as_posix()
42
- content = src.read_text(encoding="utf-8", errors="ignore")
43
- paragraphs = split_paragraphs(content)
44
- chunks = merge_to_chunks(paragraphs, settings.chunk_chars, settings.chunk_overlap)
45
- for i, chunk in enumerate(chunks):
46
- texts.append(chunk)
47
- meta.append({"doc_id": rel, "chunk_id": i, "text": chunk})
48
-
49
- if not texts:
50
- raise RuntimeError(f"No ingestable files found under {data_dir}")
51
-
52
- vectors = embedder.encode(texts)
53
- dim = vectors.shape[1]
54
- index = faiss.IndexFlatIP(dim)
55
- index.add(vectors)
56
-
57
- # persist
58
- faiss.write_index(index, str(index_paths.index_file))
59
- with index_paths.meta_file.open("w", encoding="utf-8") as f:
60
- for m in meta:
61
- f.write(json.dumps(m, ensure_ascii=False) + "\n")
62
-
63
- return index, meta
64
-
65
-
66
- def load_index(index_paths: IndexPaths) -> Tuple[faiss.Index, List[dict]]:
67
- index = faiss.read_index(str(index_paths.index_file))
68
- meta: List[dict] = []
69
- with index_paths.meta_file.open("r", encoding="utf-8") as f:
70
- for line in f:
71
- meta.append(json.loads(line))
72
- return index, meta
73
-
74
-
75
- def ensure_index(embedder: Embedder) -> Tuple[faiss.Index, List[dict]]:
76
- data_dir = Path(settings.data_dir)
77
- index_paths = IndexPaths.from_settings()
78
- if not index_paths.index_file.exists() or not index_paths.meta_file.exists():
79
- return build_index(data_dir, index_paths, embedder)
80
- return load_index(index_paths)
81
-
82
-
83
- def main():
84
- parser = argparse.ArgumentParser(description="Build or rebuild FAISS index from data/")
85
- parser.add_argument(
86
- "--rebuild",
87
- action="store_true",
88
- help="Force rebuild index from scratch (ignores existing index files)",
89
- )
90
- args = parser.parse_args()
91
-
92
- emb = Embedder()
93
- data_dir = Path(settings.data_dir)
94
- index_paths = IndexPaths.from_settings()
95
-
96
- if args.rebuild:
97
- index_paths.base.mkdir(parents=True, exist_ok=True)
98
- idx, meta = build_index(data_dir, index_paths, emb)
99
- else:
100
- idx, meta = ensure_index(emb)
101
-
102
- print(f"Indexed {len(meta)} chunks → {settings.index_dir}/{settings.index_file}")
103
-
104
-
105
- if __name__ == "__main__":
106
- main()
@@ -1,33 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import asyncio
4
- import contextlib
5
-
6
- import uvicorn
7
-
8
- from .api import app as fastapi_app
9
- from .config import settings
10
- from .mcp_server import run_server as run_mcp
11
-
12
-
13
- async def main_async():
14
- config = uvicorn.Config(fastapi_app, host=settings.api_host, port=settings.api_port, log_level="info")
15
- server = uvicorn.Server(config)
16
-
17
- async def run_api():
18
- await server.serve()
19
-
20
- async def run_ws():
21
- await run_mcp()
22
-
23
- await asyncio.gather(run_api(), run_ws())
24
-
25
-
26
- def main():
27
- with contextlib.suppress(KeyboardInterrupt):
28
- asyncio.run(main_async())
29
-
30
-
31
- if __name__ == "__main__":
32
- main()
33
-
@@ -1,71 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import asyncio
4
- import json
5
- from dataclasses import dataclass
6
- from typing import Any, Awaitable, Callable, Dict
7
-
8
- import websockets
9
-
10
- from .config import settings
11
- from .embeddings import Embedder
12
- from .indexer import ensure_index
13
- from .search import Searcher
14
-
15
-
16
- Json = Dict[str, Any]
17
-
18
-
19
- @dataclass
20
- class McpServer:
21
- host: str = settings.mcp_host
22
- port: int = settings.mcp_port
23
-
24
- def __post_init__(self):
25
- emb = Embedder()
26
- index, meta = ensure_index(emb)
27
- self.searcher = Searcher(index=index, meta=meta, embedder=emb)
28
-
29
- async def handler(self, websocket):
30
- async for message in websocket:
31
- try:
32
- req = json.loads(message)
33
- if not isinstance(req, dict):
34
- raise ValueError("Invalid JSON-RPC request")
35
- method = req.get("method")
36
- req_id = req.get("id")
37
- params = req.get("params", {})
38
-
39
- if method == "vw.search":
40
- q = params.get("query")
41
- k = int(params.get("k", 6))
42
- result = self.searcher.search(q, k=k)
43
- elif method == "vw.answer":
44
- q = params.get("query")
45
- k = int(params.get("k", 6))
46
- result = self.searcher.answer(q, k=k)
47
- elif method == "vw.get":
48
- doc_id = params.get("doc_id")
49
- chunk_id = int(params.get("chunk_id"))
50
- result = self.searcher.get(doc_id, chunk_id)
51
- else:
52
- raise ValueError(f"Unknown method: {method}")
53
-
54
- resp: Json = {"jsonrpc": "2.0", "id": req_id, "result": result}
55
- except Exception as e: # pragma: no cover - basic error surface
56
- resp = {
57
- "jsonrpc": "2.0",
58
- "id": req.get("id") if isinstance(req, dict) else None,
59
- "error": {"code": -32000, "message": str(e)},
60
- }
61
- await websocket.send(json.dumps(resp, ensure_ascii=False))
62
-
63
- async def run(self):
64
- async with websockets.serve(self.handler, self.host, self.port):
65
- await asyncio.Future() # run forever
66
-
67
-
68
- async def run_server():
69
- server = McpServer()
70
- await server.run()
71
-
@@ -1,54 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from dataclasses import dataclass
4
- from typing import List, Tuple
5
-
6
- import faiss # type: ignore
7
- import numpy as np
8
-
9
- from .embeddings import Embedder
10
-
11
-
12
- @dataclass
13
- class Searcher:
14
- index: faiss.Index
15
- meta: List[dict]
16
- embedder: Embedder
17
-
18
- def search(self, query: str, k: int = 6) -> List[dict]:
19
- vec = self.embedder.encode([query]) # normalized
20
- scores, idxs = self.index.search(vec, k)
21
- out: List[dict] = []
22
- for score, idx in zip(scores[0].tolist(), idxs[0].tolist()):
23
- if idx == -1:
24
- continue
25
- m = self.meta[idx]
26
- out.append({
27
- "score": float(score),
28
- "doc_id": m["doc_id"],
29
- "chunk_id": m["chunk_id"],
30
- "text": m["text"],
31
- })
32
- return out
33
-
34
- def get(self, doc_id: str, chunk_id: int) -> dict:
35
- # naive lookup by scanning meta (meta is same order as index)
36
- for m in self.meta:
37
- if m["doc_id"] == doc_id and m["chunk_id"] == chunk_id:
38
- return m
39
- raise KeyError(f"Chunk not found: {doc_id}#{chunk_id}")
40
-
41
- def answer(self, query: str, k: int = 6) -> dict:
42
- # Simple extractive draft: stitch top-k snippets
43
- hits = self.search(query, k=k)
44
- summary_lines: List[str] = []
45
- for i, h in enumerate(hits, start=1):
46
- text = h["text"].strip().splitlines()
47
- lead = " ".join(text[:2])[:400]
48
- summary_lines.append(f"[{i}] {lead}")
49
- draft = (
50
- "以下は関連する資料からの抜粋です。詳細は出典を参照してください。\n\n"
51
- + "\n".join(summary_lines)
52
- )
53
- return {"draft": draft, "sources": hits}
54
-
@@ -1,14 +0,0 @@
1
- import hashlib
2
- from pathlib import Path
3
-
4
-
5
- def iter_text_files(root: Path):
6
- exts = {".md", ".markdown", ".html", ".htm", ".txt"}
7
- for p in sorted(root.rglob("*")):
8
- if p.is_file() and p.suffix.lower() in exts:
9
- yield p
10
-
11
-
12
- def stable_uid(text: str) -> str:
13
- return hashlib.md5(text.encode("utf-8")).hexdigest() # nosec - non-crypto id
14
-
@@ -1 +0,0 @@
1
-