sophhub 0.4.19 → 0.4.21

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 (633) hide show
  1. package/README.md +199 -187
  2. package/agents/ai-cs-admin/.config.json +51 -51
  3. package/agents/ai-cs-admin/AGENTS.md +293 -293
  4. package/agents/ai-cs-admin/HEARTBEAT.md +18 -18
  5. package/agents/ai-cs-qa/.config.json +47 -47
  6. package/agents/ai-cs-qa/BOOTSTRAP.md +22 -22
  7. package/agents/ai-cs-qa/scripts/setup_links.sh +39 -39
  8. package/agents/beauty/.config.json +17 -17
  9. package/agents/beauty/AGENTS.md +234 -234
  10. package/agents/beauty/BOOTSTRAP.md +55 -55
  11. package/agents/beauty/HEARTBEAT.md +5 -5
  12. package/agents/beauty/IDENTITY.md +5 -5
  13. package/agents/beauty/MEMORY.md +44 -44
  14. package/agents/beauty/SOUL.md +64 -64
  15. package/agents/beauty/TOOLS.md +160 -160
  16. package/agents/beauty/USER.md +114 -114
  17. package/agents/intern-admin/.config.json +60 -60
  18. package/agents/intern-admin/AGENTS.md +267 -267
  19. package/agents/intern-admin/BOOTSTRAP.md +21 -21
  20. package/agents/intern-admin/HEARTBEAT.md +3 -3
  21. package/agents/intern-admin/IDENTITY.md +6 -6
  22. package/agents/intern-admin/MEMORY.md +21 -21
  23. package/agents/intern-admin/SOUL.md +23 -23
  24. package/agents/intern-admin/TOOLS.md +93 -93
  25. package/agents/intern-admin/USER.md +16 -16
  26. package/agents/intern-admin/scripts/init_workspace.sh +27 -27
  27. package/agents/intern-qa/.config.json +46 -46
  28. package/agents/intern-qa/AGENTS.md +303 -303
  29. package/agents/intern-qa/BOOTSTRAP.md +16 -16
  30. package/agents/intern-qa/HEARTBEAT.md +3 -3
  31. package/agents/intern-qa/IDENTITY.md +6 -6
  32. package/agents/intern-qa/MEMORY.md +22 -22
  33. package/agents/intern-qa/SOUL.md +24 -24
  34. package/agents/intern-qa/TOOLS.md +24 -24
  35. package/agents/intern-qa/USER.md +27 -27
  36. package/agents/intern-qa/scripts/setup_links.sh +54 -54
  37. package/agents/parent-toddler/.config.json +37 -37
  38. package/agents/parent-toddler/AGENTS.md +51 -51
  39. package/agents/parent-toddler/BOOTSTRAP.md +55 -55
  40. package/agents/parent-toddler/HEARTBEAT.md +5 -5
  41. package/agents/parent-toddler/IDENTITY.md +5 -5
  42. package/agents/parent-toddler/MEMORY.md +22 -22
  43. package/agents/parent-toddler/SOUL.md +35 -35
  44. package/agents/parent-toddler/TOOLS.md +31 -31
  45. package/agents/parent-toddler/USER.md +44 -44
  46. package/agents/vip-admin/.config.json +51 -51
  47. package/agents/vip-admin/AGENTS.md +314 -314
  48. package/agents/vip-admin/BOOTSTRAP.md +21 -21
  49. package/agents/vip-admin/HEARTBEAT.md +19 -19
  50. package/agents/vip-admin/IDENTITY.md +6 -6
  51. package/agents/vip-admin/MEMORY.md +30 -30
  52. package/agents/vip-admin/SOUL.md +25 -25
  53. package/agents/vip-admin/TOOLS.md +108 -108
  54. package/agents/vip-admin/USER.md +31 -31
  55. package/agents/vip-qa/.config.json +58 -58
  56. package/agents/vip-qa/AGENTS.md +319 -319
  57. package/agents/vip-qa/BOOTSTRAP.md +73 -73
  58. package/agents/vip-qa/HEARTBEAT.md +23 -23
  59. package/agents/vip-qa/IDENTITY.md +7 -7
  60. package/agents/vip-qa/MEMORY.md +23 -23
  61. package/agents/vip-qa/SOUL.md +34 -34
  62. package/agents/vip-qa/TOOLS.md +41 -41
  63. package/agents/vip-qa/USER.md +16 -16
  64. package/agents/vip-qa/scripts/setup_links.sh +39 -39
  65. package/bin/sophhub.js +25 -25
  66. package/package.json +35 -33
  67. package/skills/agent-install/skill.json +34 -34
  68. package/skills/agent-install/src/SKILL.md +240 -240
  69. package/skills/agent-install/src/pyproject.toml +6 -6
  70. package/skills/agent-install/src/scripts/backup_agent.py +120 -120
  71. package/skills/agent-install/src/scripts/check_installed.py +479 -479
  72. package/skills/agent-install/src/scripts/common.py +568 -568
  73. package/skills/agent-install/src/scripts/copy_agent_files.py +59 -59
  74. package/skills/agent-install/src/scripts/list_agents.py +285 -285
  75. package/skills/agent-install/src/scripts/resolve_install_params.py +90 -90
  76. package/skills/agent-install/src/scripts/update_agent_md.py +76 -76
  77. package/skills/agent-install/src/scripts/update_openclaw.py +193 -193
  78. package/skills/agent-install/src/scripts/verify_download.py +148 -148
  79. package/skills/aippt/skill.json +20 -20
  80. package/skills/aippt/src/SKILL.md +235 -235
  81. package/skills/aippt/src/pyproject.toml +8 -8
  82. package/skills/aippt/src/scripts/auth.py +122 -122
  83. package/skills/aippt/src/scripts/ppt.py +361 -361
  84. package/skills/aippt/src/scripts/provider_docmee.py +299 -299
  85. package/skills/beauty-salon-inventory/skill.json +16 -16
  86. package/skills/beauty-salon-inventory/src/SKILL.md +69 -69
  87. package/skills/beauty-salon-inventory/src/scripts/init_salon_inventory.py +39 -39
  88. package/skills/beauty-salon-inventory/src/scripts/init_salon_inventory.sh +4 -4
  89. package/skills/beauty-salon-inventory/src/scripts/salon_inventory_cli.py +244 -244
  90. package/skills/beauty-salon-marketing/skill.json +10 -10
  91. package/skills/beauty-salon-marketing/src/SKILL.md +36 -36
  92. package/skills/beauty-salon-marketing/src/playbooks/beauty-salon-festival.md +19 -19
  93. package/skills/beauty-salon-marketing/src/playbooks/beauty-salon-segment.md +18 -18
  94. package/skills/beauty-salon-marketing/src/scripts/beauty_marketing_cli.py +99 -99
  95. package/skills/beauty-salon-marketing/src/scripts/member_segment.py +114 -114
  96. package/skills/beauty-salon-member-appointment/skill.json +10 -10
  97. package/skills/beauty-salon-member-appointment/src/SKILL.md +36 -36
  98. package/skills/beauty-salon-member-appointment/src/pyproject.toml +9 -9
  99. package/skills/beauty-salon-member-appointment/src/scripts/run_e2e_smoke.py +160 -160
  100. package/skills/beauty-salon-member-appointment/src/src/member_appt_cli/__init__.py +1 -1
  101. package/skills/beauty-salon-member-appointment/src/src/member_appt_cli/__main__.py +4 -4
  102. package/skills/beauty-salon-member-appointment/src/src/member_appt_cli/cli.py +921 -921
  103. package/skills/beauty-salon-member-appointment/src/src/member_appt_cli/db.py +30 -30
  104. package/skills/beauty-salon-membership/skill.json +20 -20
  105. package/skills/beauty-salon-membership/src/SKILL.md +67 -67
  106. package/skills/beauty-salon-product-service/skill.json +12 -12
  107. package/skills/beauty-salon-product-service/src/SKILL.md +42 -42
  108. package/skills/beauty-salon-product-service/src/pyproject.toml +9 -9
  109. package/skills/beauty-salon-product-service/src/src/product_service_cli/__init__.py +1 -1
  110. package/skills/beauty-salon-product-service/src/src/product_service_cli/__main__.py +4 -4
  111. package/skills/beauty-salon-product-service/src/src/product_service_cli/cli.py +329 -329
  112. package/skills/beauty-salon-product-service/src/src/product_service_cli/db.py +29 -29
  113. package/skills/beauty-salon-staff/skill.json +10 -10
  114. package/skills/beauty-salon-staff/src/SKILL.md +37 -37
  115. package/skills/beauty-salon-staff/src/pyproject.toml +9 -9
  116. package/skills/beauty-salon-staff/src/src/staff_cli/__init__.py +1 -1
  117. package/skills/beauty-salon-staff/src/src/staff_cli/__main__.py +4 -4
  118. package/skills/beauty-salon-staff/src/src/staff_cli/cli.py +479 -479
  119. package/skills/beauty-salon-staff/src/src/staff_cli/db.py +28 -28
  120. package/skills/beauty-salon-suite/skill.json +13 -13
  121. package/skills/beauty-salon-suite/src/SKILL.md +18 -18
  122. package/skills/beauty-salon-suite/src/beauty_db/__init__.py +2 -2
  123. package/skills/beauty-salon-suite/src/beauty_db/db.py +249 -249
  124. package/skills/beauty-salon-traffic/skill.json +20 -20
  125. package/skills/beauty-salon-traffic/src/SKILL.md +84 -84
  126. package/skills/bing-image-search/skill.json +20 -20
  127. package/skills/bing-image-search/src/SKILL.md +105 -105
  128. package/skills/bot-api-status/skill.json +44 -44
  129. package/skills/bot-api-status/src/SKILL.md +99 -99
  130. package/skills/bot-api-status/src/pyproject.toml +5 -5
  131. package/skills/bot-api-status/src/scripts/secret.py +496 -496
  132. package/skills/bot-secret/skill.json +35 -35
  133. package/skills/bot-secret/src/SKILL.md +51 -51
  134. package/skills/bot-secret/src/pyproject.toml +5 -5
  135. package/skills/bot-secret/src/scripts/secret.py +120 -120
  136. package/skills/cake-flower-holiday-campaign/skill.json +20 -20
  137. package/skills/cake-flower-holiday-campaign/src/SKILL.md +68 -68
  138. package/skills/cake-flower-order-sop/skill.json +20 -20
  139. package/skills/cake-flower-order-sop/src/SKILL.md +65 -65
  140. package/skills/claw-agent-get-send/skill.json +32 -32
  141. package/skills/claw-agent-get-send/src/SKILL.md +43 -43
  142. package/skills/claw-agent-get-send/src/pyproject.toml +5 -5
  143. package/skills/claw-agent-get-send/src/scripts/appia_claw.py +379 -379
  144. package/skills/compact-context/skill.json +20 -20
  145. package/skills/compact-context/src/SKILL.md +133 -133
  146. package/skills/compact-context/src/scripts/check.sh +381 -381
  147. package/skills/compact-context/src/scripts/set-keep-recent.mjs +1337 -1337
  148. package/skills/compact-context/src/scripts/setup.sh +96 -96
  149. package/skills/consensus/skill.json +20 -20
  150. package/skills/consensus/src/SKILL.md +93 -93
  151. package/skills/deepwiki/skill.json +20 -20
  152. package/skills/deepwiki/src/SKILL.md +45 -45
  153. package/skills/deepwiki/src/_meta.json +5 -5
  154. package/skills/deepwiki/src/scripts/deepwiki.js +135 -135
  155. package/skills/didi-ride/skill.json +20 -20
  156. package/skills/didi-ride/src/SKILL.md +309 -309
  157. package/skills/didi-ride/src/_meta.json +5 -5
  158. package/skills/didi-ride/src/assets/PREFERENCE.md +58 -58
  159. package/skills/didi-ride/src/package.json +15 -15
  160. package/skills/didi-ride/src/references/api_references.md +171 -171
  161. package/skills/didi-ride/src/references/error_handling.md +68 -68
  162. package/skills/didi-ride/src/references/setup.md +73 -73
  163. package/skills/didi-ride/src/references/workflow.md +150 -150
  164. package/skills/feishu-bitable/skill.json +20 -20
  165. package/skills/feishu-bitable/src/CHECKLIST.md +149 -149
  166. package/skills/feishu-bitable/src/README.md +177 -177
  167. package/skills/feishu-bitable/src/SKILL.md +113 -113
  168. package/skills/feishu-bitable/src/_meta.json +5 -5
  169. package/skills/feishu-bitable/src/api.js +380 -380
  170. package/skills/feishu-bitable/src/bin/cli.js +283 -283
  171. package/skills/feishu-bitable/src/description.md +142 -142
  172. package/skills/feishu-bitable/src/examples/create-records.json +51 -51
  173. package/skills/feishu-bitable/src/examples/create-table.json +63 -63
  174. package/skills/feishu-bitable/src/package-lock.json +324 -324
  175. package/skills/feishu-bitable/src/package.json +32 -32
  176. package/skills/feishu-bitable/src/publish-config.json +13 -13
  177. package/skills/feishu-bitable/src/test-simple.js +60 -60
  178. package/skills/feishu-bitable/src/utils.js +260 -260
  179. package/skills/feishu-notes-assistant-universal/skill.json +20 -20
  180. package/skills/feishu-notes-assistant-universal/src/README.md +55 -55
  181. package/skills/feishu-notes-assistant-universal/src/SKILL.md +159 -159
  182. package/skills/feishu-notes-assistant-universal/src/scripts/_resolve_lark_cli.py +58 -58
  183. package/skills/feishu-notes-assistant-universal/src/scripts/openclaw_meeting_minutes.py +462 -462
  184. package/skills/feishu-notes-assistant-universal/src/scripts/openclaw_notes_crud.py +547 -547
  185. package/skills/feishu-notes-assistant-universal/src/scripts/openclaw_notes_crud_test.py +181 -181
  186. package/skills/feishu-notes-assistant-universal/src/scripts/run_meeting_minutes.py +80 -80
  187. package/skills/feishu-notes-assistant-universal/src/scripts/run_meeting_minutes.sh +5 -5
  188. package/skills/feishu-notes-assistant-universal/src/scripts/run_note_crud.py +32 -32
  189. package/skills/feishu-notes-assistant-universal/src/scripts/run_note_crud.sh +5 -5
  190. package/skills/flight-booking/skill.json +36 -36
  191. package/skills/flight-booking/src/SKILL.md +288 -288
  192. package/skills/flight-booking/src/scripts/flight_booking.py +1237 -1237
  193. package/skills/flyai/skill.json +20 -20
  194. package/skills/flyai/src/SKILL.md +119 -119
  195. package/skills/flyai/src/references/fliggy-fast-search.md +53 -53
  196. package/skills/flyai/src/references/search-flight.md +89 -89
  197. package/skills/flyai/src/references/search-hotels.md +57 -57
  198. package/skills/flyai/src/references/search-poi.md +48 -48
  199. package/skills/google-maps/skill.json +20 -20
  200. package/skills/google-maps/src/SKILL.md +237 -237
  201. package/skills/google-maps/src/_meta.json +5 -5
  202. package/skills/google-maps/src/lib/map_helper.py +912 -912
  203. package/skills/image-classify/skill.json +42 -42
  204. package/skills/image-classify/src/SKILL.md +368 -368
  205. package/skills/image-classify/src/references/config.json +4 -4
  206. package/skills/image-classify/src/scripts/face_search.py +1276 -1276
  207. package/skills/image-description/skill.json +34 -34
  208. package/skills/image-description/src/SKILL.md +33 -33
  209. package/skills/image-description/src/pyproject.toml +8 -8
  210. package/skills/image-description/src/scripts/ana_image.py +112 -112
  211. package/skills/image-identify-world/skill.json +20 -20
  212. package/skills/image-identify-world/src/SKILL.md +40 -40
  213. package/skills/image-identify-world/src/pyproject.toml +8 -8
  214. package/skills/image-identify-world/src/scripts/identify_world.py +115 -115
  215. package/skills/insurance-policy-review/skill.json +27 -27
  216. package/skills/insurance-policy-review/src/SKILL.md +75 -75
  217. package/skills/insurance-sales-playbook/skill.json +20 -20
  218. package/skills/insurance-sales-playbook/src/SKILL.md +58 -58
  219. package/skills/inventory-management/skill.json +20 -20
  220. package/skills/inventory-management/src/SKILL.md +241 -241
  221. package/skills/inventory-management/src/scripts/inventory.py +1844 -1844
  222. package/skills/large-task-router/skill.json +20 -20
  223. package/skills/large-task-router/src/SKILL.md +79 -79
  224. package/skills/large-task-router/src/templates/plan.md +74 -74
  225. package/skills/lawding-contract-review/skill.json +20 -20
  226. package/skills/lawding-contract-review/src/SKILL.md +284 -284
  227. package/skills/lawding-contract-review/src/references/legal-language-library.md +1385 -1385
  228. package/skills/lawding-contract-review/src/scripts/build_reminders.py +471 -471
  229. package/skills/lawding-contract-review/src/scripts/register_contract_cron.py +457 -457
  230. package/skills/md2pdf-converter/skill.json +20 -20
  231. package/skills/md2pdf-converter/src/SKILL.md +244 -244
  232. package/skills/md2pdf-converter/src/_meta.json +5 -5
  233. package/skills/md2pdf-converter/src/scripts/generate_emoji_mapping.py +74 -74
  234. package/skills/md2pdf-converter/src/scripts/md2pdf-local.sh +291 -291
  235. package/skills/notes-hub-assistant/skill.json +20 -20
  236. package/skills/notes-hub-assistant/src/SKILL.md +233 -233
  237. package/skills/notes-hub-assistant/src/scripts/_resolve_lark_cli.py +48 -48
  238. package/skills/notes-hub-assistant/src/scripts/openclaw_meeting_minutes.py +473 -473
  239. package/skills/notes-hub-assistant/src/scripts/openclaw_notes_crud.py +596 -596
  240. package/skills/notes-hub-assistant/src/scripts/openclaw_wolai_notes_crud.py +364 -364
  241. package/skills/notes-hub-assistant/src/scripts/run_meeting_minutes.py +79 -79
  242. package/skills/notes-hub-assistant/src/scripts/run_note_crud.py +37 -37
  243. package/skills/notes-hub-assistant/src/scripts/run_notionbot.py +36 -36
  244. package/skills/notes-hub-assistant/src/scripts/run_wolai_note_crud.py +27 -27
  245. package/skills/schedule-reminder/skill.json +20 -20
  246. package/skills/schedule-reminder/src/SKILL.md +619 -619
  247. package/skills/schedule-reminder/src/schedule_template.md +68 -68
  248. package/skills/schedule-reminder/src/scripts/append_event.py +204 -204
  249. package/skills/schedule-reminder/src/scripts/create_reminders.sh +163 -163
  250. package/skills/schedule-reminder/src/scripts/daily_activate.sh +175 -175
  251. package/skills/schedule-reminder/src/scripts/parse_schedule.py +704 -704
  252. package/skills/schedule-reminder/src/scripts/setup.sh +242 -242
  253. package/skills/schedule-reminder/src//347/224/250/346/210/267/346/214/207/345/215/227.md +311 -311
  254. package/skills/sessions-analysis/skill.json +34 -34
  255. package/skills/sessions-analysis/src/SKILL.md +81 -81
  256. package/skills/sessions-analysis/src/pyproject.toml +5 -5
  257. package/skills/sessions-analysis/src/scripts/ana_logs.py +205 -205
  258. package/skills/share-skill/skill.json +20 -20
  259. package/skills/share-skill/src/SKILL.md +261 -261
  260. package/skills/share-skill/src/scripts/share_skill_to_friend.py +1031 -1031
  261. package/skills/skill-creator/skill.json +20 -20
  262. package/skills/skill-creator/src/SKILL.md +370 -370
  263. package/skills/skill-creator/src/license.txt +202 -202
  264. package/skills/skill-creator/src/scripts/init_skill.py +378 -378
  265. package/skills/skill-creator/src/scripts/package_skill.py +111 -111
  266. package/skills/skill-creator/src/scripts/quick_validate.py +101 -101
  267. package/skills/skillhub/skill.json +27 -27
  268. package/skills/skillhub/src/SKILL.md +121 -121
  269. package/skills/sophnet-age-appearance/skill.json +20 -20
  270. package/skills/sophnet-age-appearance/src/SKILL.md +83 -83
  271. package/skills/sophnet-age-appearance/src/pyproject.toml +10 -10
  272. package/skills/sophnet-age-appearance/src/scripts/age_appearance.py +395 -395
  273. package/skills/sophnet-age-appearance/src/scripts/age_face_crop.py +313 -313
  274. package/skills/sophnet-bot-client/skill.json +20 -20
  275. package/skills/sophnet-bot-client/src/SKILL.md +255 -255
  276. package/skills/sophnet-bot-client/src/pyproject.toml +13 -13
  277. package/skills/sophnet-bot-client/src/scripts/bot_client_proxy.py +165 -165
  278. package/skills/sophnet-bot-client/src/scripts/bot_client_safe.sh +29 -29
  279. package/skills/sophnet-bot-client/src/scripts/bot_client_setup.py +502 -502
  280. package/skills/sophnet-bot-client/src/tests/test_bot_client_proxy.py +255 -255
  281. package/skills/sophnet-bot-client/src/tests/test_bot_client_setup.py +679 -679
  282. package/skills/sophnet-bot-client/src/uv.lock +8 -8
  283. package/skills/sophnet-customer-management/skill.json +20 -20
  284. package/skills/sophnet-customer-management/src/SKILL.md +270 -270
  285. package/skills/sophnet-customer-management/src/pyproject.toml +15 -15
  286. package/skills/sophnet-customer-management/src/src/customer_mgmt_cli/__init__.py +2 -2
  287. package/skills/sophnet-customer-management/src/src/customer_mgmt_cli/__main__.py +5 -5
  288. package/skills/sophnet-customer-management/src/src/customer_mgmt_cli/cli.py +67 -67
  289. package/skills/sophnet-customer-management/src/src/customer_mgmt_cli/commands/__init__.py +2 -2
  290. package/skills/sophnet-customer-management/src/src/customer_mgmt_cli/commands/customer.py +60 -60
  291. package/skills/sophnet-customer-management/src/src/customer_mgmt_cli/commands/export_file.py +18 -18
  292. package/skills/sophnet-customer-management/src/src/customer_mgmt_cli/commands/import_file.py +15 -15
  293. package/skills/sophnet-customer-management/src/src/customer_mgmt_cli/commands/reminder.py +26 -26
  294. package/skills/sophnet-customer-management/src/src/customer_mgmt_cli/commands/schema.py +28 -28
  295. package/skills/sophnet-customer-management/src/src/customer_mgmt_cli/config.py +54 -54
  296. package/skills/sophnet-customer-management/src/src/customer_mgmt_core/__init__.py +2 -2
  297. package/skills/sophnet-customer-management/src/src/customer_mgmt_core/exporter.py +85 -85
  298. package/skills/sophnet-customer-management/src/src/customer_mgmt_core/models.py +84 -84
  299. package/skills/sophnet-customer-management/src/src/customer_mgmt_core/normalizer.py +144 -144
  300. package/skills/sophnet-customer-management/src/src/customer_mgmt_core/parser.py +241 -241
  301. package/skills/sophnet-customer-management/src/src/customer_mgmt_core/query.py +109 -109
  302. package/skills/sophnet-customer-management/src/src/customer_mgmt_core/reminder.py +121 -121
  303. package/skills/sophnet-customer-management/src/src/customer_mgmt_core/repository.py +397 -397
  304. package/skills/sophnet-customer-management/src/src/customer_mgmt_core/schema.py +106 -106
  305. package/skills/sophnet-customer-management/src/src/customer_mgmt_core/service.py +565 -565
  306. package/skills/sophnet-customer-management/src/uv.lock +48 -48
  307. package/skills/sophnet-customized-marketing/skill.json +28 -28
  308. package/skills/sophnet-customized-marketing/src/SKILL.md +144 -144
  309. package/skills/sophnet-customized-marketing/src/playbooks/campaign-planning.md +187 -187
  310. package/skills/sophnet-customized-marketing/src/playbooks/content-generation.md +124 -124
  311. package/skills/sophnet-customized-marketing/src/playbooks/marketing-calendar.md +59 -59
  312. package/skills/sophnet-customized-marketing/src/playbooks/multi-channel-bundle.md +94 -94
  313. package/skills/sophnet-customized-marketing/src/playbooks/poster-generation.md +182 -182
  314. package/skills/sophnet-customized-marketing/src/playbooks/style-profile-workflow.md +103 -103
  315. package/skills/sophnet-customized-marketing/src/pyproject.toml +8 -8
  316. package/skills/sophnet-customized-marketing/src/references/campaign-mechanics.md +168 -168
  317. package/skills/sophnet-customized-marketing/src/references/content-safety.md +26 -26
  318. package/skills/sophnet-customized-marketing/src/references/marketing-date-checklist.md +99 -99
  319. package/skills/sophnet-customized-marketing/src/references/platform-writing-guidelines.md +88 -88
  320. package/skills/sophnet-customized-marketing/src/references/quality-checklist.md +44 -44
  321. package/skills/sophnet-customized-marketing/src/scripts/generate_poster.py +572 -572
  322. package/skills/sophnet-customized-marketing/src/scripts/style_profile.py +215 -215
  323. package/skills/sophnet-dailynews/skill.json +20 -20
  324. package/skills/sophnet-dailynews/src/SKILL.md +179 -179
  325. package/skills/sophnet-dailynews/src/cache.json +150 -150
  326. package/skills/sophnet-dailynews/src/sources.json +230 -230
  327. package/skills/sophnet-docx/skill.json +20 -20
  328. package/skills/sophnet-docx/src/SKILL.md +463 -463
  329. package/skills/sophnet-docx/src/package-lock.json +208 -208
  330. package/skills/sophnet-docx/src/package.json +16 -16
  331. package/skills/sophnet-docx/src/pyproject.toml +11 -11
  332. package/skills/sophnet-docx/src/scripts/__init__.py +1 -1
  333. package/skills/sophnet-docx/src/scripts/accept_changes.py +135 -135
  334. package/skills/sophnet-docx/src/scripts/comment.py +318 -318
  335. package/skills/sophnet-docx/src/scripts/ensure_uv_env.sh +68 -68
  336. package/skills/sophnet-docx/src/scripts/office/helpers/merge_runs.py +199 -199
  337. package/skills/sophnet-docx/src/scripts/office/helpers/simplify_redlines.py +197 -197
  338. package/skills/sophnet-docx/src/scripts/office/pack.py +159 -159
  339. package/skills/sophnet-docx/src/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -1499
  340. package/skills/sophnet-docx/src/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -146
  341. package/skills/sophnet-docx/src/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -1085
  342. package/skills/sophnet-docx/src/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -11
  343. package/skills/sophnet-docx/src/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -3081
  344. package/skills/sophnet-docx/src/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -23
  345. package/skills/sophnet-docx/src/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -185
  346. package/skills/sophnet-docx/src/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -287
  347. package/skills/sophnet-docx/src/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -1676
  348. package/skills/sophnet-docx/src/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -28
  349. package/skills/sophnet-docx/src/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -144
  350. package/skills/sophnet-docx/src/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -174
  351. package/skills/sophnet-docx/src/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -25
  352. package/skills/sophnet-docx/src/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -18
  353. package/skills/sophnet-docx/src/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -59
  354. package/skills/sophnet-docx/src/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -56
  355. package/skills/sophnet-docx/src/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -195
  356. package/skills/sophnet-docx/src/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -582
  357. package/skills/sophnet-docx/src/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -25
  358. package/skills/sophnet-docx/src/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -4439
  359. package/skills/sophnet-docx/src/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -570
  360. package/skills/sophnet-docx/src/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -509
  361. package/skills/sophnet-docx/src/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -12
  362. package/skills/sophnet-docx/src/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -108
  363. package/skills/sophnet-docx/src/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -96
  364. package/skills/sophnet-docx/src/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -3646
  365. package/skills/sophnet-docx/src/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -116
  366. package/skills/sophnet-docx/src/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -42
  367. package/skills/sophnet-docx/src/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -50
  368. package/skills/sophnet-docx/src/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -49
  369. package/skills/sophnet-docx/src/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -33
  370. package/skills/sophnet-docx/src/scripts/office/schemas/mce/mc.xsd +75 -75
  371. package/skills/sophnet-docx/src/scripts/office/schemas/microsoft/wml-2010.xsd +560 -560
  372. package/skills/sophnet-docx/src/scripts/office/schemas/microsoft/wml-2012.xsd +67 -67
  373. package/skills/sophnet-docx/src/scripts/office/schemas/microsoft/wml-2018.xsd +14 -14
  374. package/skills/sophnet-docx/src/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -20
  375. package/skills/sophnet-docx/src/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -13
  376. package/skills/sophnet-docx/src/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -4
  377. package/skills/sophnet-docx/src/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -8
  378. package/skills/sophnet-docx/src/scripts/office/soffice.py +183 -183
  379. package/skills/sophnet-docx/src/scripts/office/unpack.py +132 -132
  380. package/skills/sophnet-docx/src/scripts/office/validate.py +111 -111
  381. package/skills/sophnet-docx/src/scripts/office/validators/__init__.py +15 -15
  382. package/skills/sophnet-docx/src/scripts/office/validators/base.py +847 -847
  383. package/skills/sophnet-docx/src/scripts/office/validators/docx.py +446 -446
  384. package/skills/sophnet-docx/src/scripts/office/validators/pptx.py +275 -275
  385. package/skills/sophnet-docx/src/scripts/office/validators/redlining.py +247 -247
  386. package/skills/sophnet-docx/src/scripts/templates/comments.xml +3 -3
  387. package/skills/sophnet-docx/src/scripts/templates/commentsExtended.xml +3 -3
  388. package/skills/sophnet-docx/src/scripts/templates/commentsExtensible.xml +3 -3
  389. package/skills/sophnet-docx/src/scripts/templates/commentsIds.xml +3 -3
  390. package/skills/sophnet-docx/src/scripts/templates/people.xml +3 -3
  391. package/skills/sophnet-docx/src/scripts/upload_file.sh +96 -96
  392. package/skills/sophnet-docx/src/uv.lock +320 -320
  393. package/skills/sophnet-face-search/skill.json +20 -20
  394. package/skills/sophnet-face-search/src/SKILL.md +115 -115
  395. package/skills/sophnet-face-search/src/pyproject.toml +11 -11
  396. package/skills/sophnet-face-search/src/scripts/face_search.py +335 -335
  397. package/skills/sophnet-face-search/src/uv.lock +508 -508
  398. package/skills/sophnet-id-photo/skill.json +20 -20
  399. package/skills/sophnet-id-photo/src/SKILL.md +107 -107
  400. package/skills/sophnet-id-photo/src/pyproject.toml +10 -10
  401. package/skills/sophnet-id-photo/src/scripts/id_photo.py +540 -540
  402. package/skills/sophnet-id-photo/src/scripts/id_photo_compliance.py +215 -215
  403. package/skills/sophnet-id-photo/src/scripts/id_photo_face_crop.py +313 -313
  404. package/skills/sophnet-image-edit/skill.json +20 -20
  405. package/skills/sophnet-image-edit/src/SKILL.md +140 -140
  406. package/skills/sophnet-image-edit/src/pyproject.toml +9 -9
  407. package/skills/sophnet-image-edit/src/scripts/edit_and_preview.sh +68 -68
  408. package/skills/sophnet-image-edit/src/scripts/edit_image.py +279 -279
  409. package/skills/sophnet-image-edit/src/uv.lock +234 -234
  410. package/skills/sophnet-image-generate/skill.json +20 -20
  411. package/skills/sophnet-image-generate/src/SKILL.md +62 -62
  412. package/skills/sophnet-image-generate/src/pyproject.toml +9 -9
  413. package/skills/sophnet-image-generate/src/scripts/generate_image.py +156 -156
  414. package/skills/sophnet-image-generate/src/uv.lock +234 -234
  415. package/skills/sophnet-image-ocr/skill.json +20 -20
  416. package/skills/sophnet-image-ocr/src/SKILL.md +167 -167
  417. package/skills/sophnet-image-ocr/src/pyproject.toml +13 -13
  418. package/skills/sophnet-image-ocr/src/scripts/ocr.py +225 -225
  419. package/skills/sophnet-image-ocr/src/uv.lock +234 -234
  420. package/skills/sophnet-infinite-talk/skill.json +20 -20
  421. package/skills/sophnet-infinite-talk/src/SKILL.md +140 -140
  422. package/skills/sophnet-infinite-talk/src/pyproject.toml +9 -9
  423. package/skills/sophnet-infinite-talk/src/scripts/gen.py +172 -172
  424. package/skills/sophnet-oss/skill.json +27 -27
  425. package/skills/sophnet-oss/src/SKILL.md +118 -118
  426. package/skills/sophnet-oss/src/pyproject.toml +8 -8
  427. package/skills/sophnet-oss/src/scripts/upload_file.py +43 -43
  428. package/skills/sophnet-pdf/skill.json +20 -20
  429. package/skills/sophnet-pdf/src/SKILL.md +413 -413
  430. package/skills/sophnet-pdf/src/forms.md +297 -297
  431. package/skills/sophnet-pdf/src/pyproject.toml +14 -14
  432. package/skills/sophnet-pdf/src/reference.md +611 -611
  433. package/skills/sophnet-pdf/src/scripts/check_bounding_boxes.py +65 -65
  434. package/skills/sophnet-pdf/src/scripts/check_fillable_fields.py +11 -11
  435. package/skills/sophnet-pdf/src/scripts/convert_pdf_to_images.py +33 -33
  436. package/skills/sophnet-pdf/src/scripts/create_validation_image.py +37 -37
  437. package/skills/sophnet-pdf/src/scripts/enhance_tutorial.py +557 -557
  438. package/skills/sophnet-pdf/src/scripts/ensure_uv_env.sh +68 -68
  439. package/skills/sophnet-pdf/src/scripts/extract_form_field_info.py +122 -122
  440. package/skills/sophnet-pdf/src/scripts/extract_form_structure.py +115 -115
  441. package/skills/sophnet-pdf/src/scripts/extract_pdf_content.py +34 -34
  442. package/skills/sophnet-pdf/src/scripts/fill_fillable_fields.py +98 -98
  443. package/skills/sophnet-pdf/src/scripts/fill_pdf_form_with_annotations.py +107 -107
  444. package/skills/sophnet-pdf/src/scripts/upload_file.sh +88 -88
  445. package/skills/sophnet-pdf/src/uv.lock +537 -537
  446. package/skills/sophnet-qa-install/skill.json +27 -27
  447. package/skills/sophnet-qa-install/src/SKILL.md +210 -210
  448. package/skills/sophnet-qa-install/src/pyproject.toml +6 -6
  449. package/skills/sophnet-qa-install/src/scripts/backup_md.py +35 -35
  450. package/skills/sophnet-qa-install/src/scripts/check_installed.py +143 -143
  451. package/skills/sophnet-qa-install/src/scripts/update_config.py +142 -142
  452. package/skills/sophnet-qa-install/src/scripts/update_md.py +73 -73
  453. package/skills/sophnet-schedule/skill.json +20 -20
  454. package/skills/sophnet-schedule/src/ARCHITECTURE.md +321 -321
  455. package/skills/sophnet-schedule/src/IMPROVEMENTS.md +145 -145
  456. package/skills/sophnet-schedule/src/SKILL.md +1050 -1050
  457. package/skills/sophnet-schedule/src/_meta.json +6 -6
  458. package/skills/sophnet-schedule/src/api/models.py +245 -245
  459. package/skills/sophnet-schedule/src/apps/add_event.py +237 -237
  460. package/skills/sophnet-schedule/src/apps/check_reminders.py +112 -112
  461. package/skills/sophnet-schedule/src/apps/check_roc.py +246 -246
  462. package/skills/sophnet-schedule/src/apps/generate_daily_plan.py +342 -342
  463. package/skills/sophnet-schedule/src/apps/import_events.py +216 -216
  464. package/skills/sophnet-schedule/src/apps/monitor_calendar_changes.py +140 -140
  465. package/skills/sophnet-schedule/src/apps/register_tasks.py +169 -169
  466. package/skills/sophnet-schedule/src/apps/sync_roc_to_gcal.py +174 -174
  467. package/skills/sophnet-schedule/src/compat.py +66 -66
  468. package/skills/sophnet-schedule/src/config/reminder_rules.yaml +96 -96
  469. package/skills/sophnet-schedule/src/config/roc_events.yaml +44 -44
  470. package/skills/sophnet-schedule/src/config/settings.py +133 -133
  471. package/skills/sophnet-schedule/src/config/task_registry.yaml +92 -92
  472. package/skills/sophnet-schedule/src/docs/FRONTEND_INTEGRATION_GUIDE.md +437 -437
  473. package/skills/sophnet-schedule/src/gcal/client.py +374 -374
  474. package/skills/sophnet-schedule/src/gcal/models.py +91 -91
  475. package/skills/sophnet-schedule/src/requirements.txt +6 -6
  476. package/skills/sophnet-schedule/src/scripts/setup_gcal_token.py +85 -85
  477. package/skills/sophnet-schedule/src/server.py +669 -669
  478. package/skills/sophnet-schedule/src/services/calendar_backend.py +139 -139
  479. package/skills/sophnet-schedule/src/services/conflict_detector.py +96 -96
  480. package/skills/sophnet-schedule/src/services/datetime_utils.py +117 -117
  481. package/skills/sophnet-schedule/src/services/event_classifier.py +100 -100
  482. package/skills/sophnet-schedule/src/services/event_diff.py +160 -160
  483. package/skills/sophnet-schedule/src/services/google_integration.py +500 -500
  484. package/skills/sophnet-schedule/src/services/job_store.py +100 -100
  485. package/skills/sophnet-schedule/src/services/local_event_store.py +266 -266
  486. package/skills/sophnet-schedule/src/services/reminder_planner.py +116 -116
  487. package/skills/sophnet-schedule/src/services/runtime_utils.py +31 -31
  488. package/skills/sophnet-schedule/src/services/table_parser.py +286 -286
  489. package/skills/sophnet-schedule/src/services/task_builder.py +167 -167
  490. package/skills/sophnet-schedule/src/services/time_window.py +72 -72
  491. package/skills/sophnet-sticker-edit/skill.json +27 -27
  492. package/skills/sophnet-sticker-edit/src/SKILL.md +80 -80
  493. package/skills/sophnet-sticker-edit/src/pyproject.toml +9 -9
  494. package/skills/sophnet-sticker-edit/src/scripts/edit_sticker_image.py +403 -403
  495. package/skills/sophnet-stock/skill.json +20 -20
  496. package/skills/sophnet-stock/src/App-Plan.md +442 -442
  497. package/skills/sophnet-stock/src/README.md +214 -214
  498. package/skills/sophnet-stock/src/SKILL.md +236 -236
  499. package/skills/sophnet-stock/src/TODO.md +394 -394
  500. package/skills/sophnet-stock/src/_meta.json +5 -5
  501. package/skills/sophnet-stock/src/docs/ARCHITECTURE.md +408 -408
  502. package/skills/sophnet-stock/src/docs/CONCEPT.md +233 -233
  503. package/skills/sophnet-stock/src/docs/HOT_SCANNER.md +288 -288
  504. package/skills/sophnet-stock/src/docs/README.md +95 -95
  505. package/skills/sophnet-stock/src/docs/USAGE.md +465 -465
  506. package/skills/sophnet-stock/src/scripts/analyze_stock.py +2565 -2565
  507. package/skills/sophnet-stock/src/scripts/dividends.py +365 -365
  508. package/skills/sophnet-stock/src/scripts/hot_scanner.py +582 -582
  509. package/skills/sophnet-stock/src/scripts/portfolio.py +548 -548
  510. package/skills/sophnet-stock/src/scripts/rumor_scanner.py +342 -342
  511. package/skills/sophnet-stock/src/scripts/test_stock_analysis.py +409 -409
  512. package/skills/sophnet-stock/src/scripts/watchlist.py +336 -336
  513. package/skills/sophnet-training-install/skill.json +27 -27
  514. package/skills/sophnet-training-install/src/SKILL.md +211 -211
  515. package/skills/sophnet-training-install/src/pyproject.toml +6 -6
  516. package/skills/sophnet-training-install/src/scripts/backup_md.py +35 -35
  517. package/skills/sophnet-training-install/src/scripts/check_installed.py +144 -144
  518. package/skills/sophnet-training-install/src/scripts/update_config.py +142 -142
  519. package/skills/sophnet-training-install/src/scripts/update_md.py +73 -73
  520. package/skills/sophnet-tts/skill.json +20 -20
  521. package/skills/sophnet-tts/src/SKILL.md +79 -79
  522. package/skills/sophnet-tts/src/pyproject.toml +9 -9
  523. package/skills/sophnet-tts/src/scripts/gen_tts.py +130 -130
  524. package/skills/sophnet-video-generate/skill.json +37 -37
  525. package/skills/sophnet-video-generate/src/SKILL.md +117 -117
  526. package/skills/sophnet-video-generate/src/scripts/gen_video.py +321 -321
  527. package/skills/sophnet-xlsx/skill.json +20 -20
  528. package/skills/sophnet-xlsx/src/SKILL.md +399 -399
  529. package/skills/sophnet-xlsx/src/pyproject.toml +11 -11
  530. package/skills/sophnet-xlsx/src/scripts/ensure_uv_env.sh +68 -68
  531. package/skills/sophnet-xlsx/src/scripts/office/helpers/merge_runs.py +199 -199
  532. package/skills/sophnet-xlsx/src/scripts/office/helpers/simplify_redlines.py +197 -197
  533. package/skills/sophnet-xlsx/src/scripts/office/pack.py +159 -159
  534. package/skills/sophnet-xlsx/src/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -1499
  535. package/skills/sophnet-xlsx/src/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -146
  536. package/skills/sophnet-xlsx/src/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -1085
  537. package/skills/sophnet-xlsx/src/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -11
  538. package/skills/sophnet-xlsx/src/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -3081
  539. package/skills/sophnet-xlsx/src/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -23
  540. package/skills/sophnet-xlsx/src/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -185
  541. package/skills/sophnet-xlsx/src/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -287
  542. package/skills/sophnet-xlsx/src/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -1676
  543. package/skills/sophnet-xlsx/src/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -28
  544. package/skills/sophnet-xlsx/src/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -144
  545. package/skills/sophnet-xlsx/src/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -174
  546. package/skills/sophnet-xlsx/src/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -25
  547. package/skills/sophnet-xlsx/src/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -18
  548. package/skills/sophnet-xlsx/src/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -59
  549. package/skills/sophnet-xlsx/src/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -56
  550. package/skills/sophnet-xlsx/src/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -195
  551. package/skills/sophnet-xlsx/src/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -582
  552. package/skills/sophnet-xlsx/src/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -25
  553. package/skills/sophnet-xlsx/src/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -4439
  554. package/skills/sophnet-xlsx/src/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -570
  555. package/skills/sophnet-xlsx/src/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -509
  556. package/skills/sophnet-xlsx/src/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -12
  557. package/skills/sophnet-xlsx/src/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -108
  558. package/skills/sophnet-xlsx/src/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -96
  559. package/skills/sophnet-xlsx/src/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -3646
  560. package/skills/sophnet-xlsx/src/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -116
  561. package/skills/sophnet-xlsx/src/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -42
  562. package/skills/sophnet-xlsx/src/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -50
  563. package/skills/sophnet-xlsx/src/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -49
  564. package/skills/sophnet-xlsx/src/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -33
  565. package/skills/sophnet-xlsx/src/scripts/office/schemas/mce/mc.xsd +75 -75
  566. package/skills/sophnet-xlsx/src/scripts/office/schemas/microsoft/wml-2010.xsd +560 -560
  567. package/skills/sophnet-xlsx/src/scripts/office/schemas/microsoft/wml-2012.xsd +67 -67
  568. package/skills/sophnet-xlsx/src/scripts/office/schemas/microsoft/wml-2018.xsd +14 -14
  569. package/skills/sophnet-xlsx/src/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -20
  570. package/skills/sophnet-xlsx/src/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -13
  571. package/skills/sophnet-xlsx/src/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -4
  572. package/skills/sophnet-xlsx/src/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -8
  573. package/skills/sophnet-xlsx/src/scripts/office/soffice.py +183 -183
  574. package/skills/sophnet-xlsx/src/scripts/office/unpack.py +132 -132
  575. package/skills/sophnet-xlsx/src/scripts/office/validate.py +111 -111
  576. package/skills/sophnet-xlsx/src/scripts/office/validators/__init__.py +15 -15
  577. package/skills/sophnet-xlsx/src/scripts/office/validators/base.py +847 -847
  578. package/skills/sophnet-xlsx/src/scripts/office/validators/docx.py +446 -446
  579. package/skills/sophnet-xlsx/src/scripts/office/validators/pptx.py +275 -275
  580. package/skills/sophnet-xlsx/src/scripts/office/validators/redlining.py +247 -247
  581. package/skills/sophnet-xlsx/src/scripts/recalc.py +184 -184
  582. package/skills/sophnet-xlsx/src/scripts/upload_file.sh +96 -96
  583. package/skills/sophnet-xlsx/src/uv.lock +319 -319
  584. package/skills/ui-ux-pro-max/skill.json +20 -20
  585. package/skills/ui-ux-pro-max/src/SKILL.md +377 -377
  586. package/skills/ui-ux-pro-max/src/data/icons.csv +101 -101
  587. package/skills/ui-ux-pro-max/src/data/react-performance.csv +45 -45
  588. package/skills/ui-ux-pro-max/src/data/stacks/astro.csv +54 -54
  589. package/skills/ui-ux-pro-max/src/data/stacks/jetpack-compose.csv +53 -53
  590. package/skills/ui-ux-pro-max/src/data/stacks/nuxt-ui.csv +51 -51
  591. package/skills/ui-ux-pro-max/src/data/stacks/nuxtjs.csv +59 -59
  592. package/skills/ui-ux-pro-max/src/data/stacks/shadcn.csv +61 -61
  593. package/skills/ui-ux-pro-max/src/data/typography.csv +57 -57
  594. package/skills/ui-ux-pro-max/src/data/ui-reasoning.csv +101 -101
  595. package/skills/ui-ux-pro-max/src/data/web-interface.csv +31 -31
  596. package/skills/ui-ux-pro-max/src/scripts/core.py +253 -253
  597. package/skills/ui-ux-pro-max/src/scripts/design_system.py +1067 -1067
  598. package/skills/video-understand/skill.json +20 -20
  599. package/skills/video-understand/src/SKILL.md +79 -79
  600. package/skills/video-understand/src/scripts/video_understand.py +204 -204
  601. package/skills/weather/skill.json +19 -19
  602. package/skills/weather/src/SKILL.md +112 -112
  603. package/skills/web-scraper/skill.json +20 -20
  604. package/skills/web-scraper/src/SKILL.md +101 -101
  605. package/skills/web-scraper/src/scripts/scrape.py +270 -270
  606. package/skills/website-builder/skill.json +20 -20
  607. package/skills/website-builder/src/SKILL.md +266 -266
  608. package/skills/website-builder/src/scripts/deploy_site.sh +46 -46
  609. package/skills/wechat-article-publisher/skill.json +20 -20
  610. package/skills/wechat-article-publisher/src/SKILL.md +60 -60
  611. package/skills/wechat-article-publisher/src/config.json +6 -6
  612. package/skills/wechat-article-publisher/src/pyproject.toml +12 -12
  613. package/skills/wechat-article-publisher/src/scripts/publish_wechat.py +825 -825
  614. package/skills/xiaohongshu/skill.json +20 -20
  615. package/skills/xiaohongshu/src/SKILL.md +91 -91
  616. package/skills/xiaohongshu/src/_meta.json +5 -5
  617. package/skills/xiaohongshu/src/assets/card.html +216 -216
  618. package/skills/xiaohongshu/src/assets/cover.html +82 -82
  619. package/skills/xiaohongshu/src/assets/example.md +84 -84
  620. package/skills/xiaohongshu/src/assets/styles.css +318 -318
  621. package/skills/xiaohongshu/src/scripts/render_xhs_v2.py +737 -737
  622. package/skills/xiaohongshu/src/scripts/sign_server.py +158 -158
  623. package/skills/xiaohongshu/src/scripts/stealth.min.js +6 -6
  624. package/skills/xiaohongshu/src/scripts/xhs_tool.py +186 -186
  625. package/skills/xiaohongshu/src/workflow.py +185 -185
  626. package/src/commands/agent.js +112 -112
  627. package/src/commands/download.js +101 -101
  628. package/src/commands/info.js +58 -58
  629. package/src/commands/list.js +71 -71
  630. package/src/utils/agents.js +36 -36
  631. package/src/utils/config.js +22 -22
  632. package/src/utils/paths.js +31 -31
  633. package/src/utils/versions.js +57 -57
@@ -1,368 +1,368 @@
1
- ---
2
- name: image-classify
3
- description: 照片分类器。通过人脸识别对照片进行分类、搜索和管理。当用户说「用照片分类器查找/搜索 xxx」「对 xx 文件夹进行分类」「添加 xx 到照片分类器」「从照片分类器删除 xx」时使用。
4
- ---
5
-
6
- # 📸 照片分类器
7
-
8
- 基于人脸 embedding 相似度的照片分类系统。支持注册用户人脸、按用户搜索照片、一键全量分类、删除用户;搜索/分类结束后**生成下载链接**(`pack`)即完成结果导出。
9
-
10
- ## Processing Mode
11
-
12
- **STRICT SERIAL PROCESSING ONLY** — 单次顺序执行,不拆分子任务、不并行。
13
-
14
- **子会话(耗时任务)**:`search`、`quick-search`、`classify` 在**独立子会话**中执行。**子命令结束(成功或失败)后,须立即关闭并删除该子会话**,不得保留空壳会话。后续步骤——向用户展示结果表格、执行 `pack`——一律在**当前主会话**中完成。
15
-
16
- ## Prerequisites
17
-
18
- - Python 3.10+、uv
19
- - 依赖:`requests`, `opencv-python`, `numpy`, `sophnet_tools`(项目内置)
20
- - 配置文件:`{baseDir}/references/config.json`
21
- - 若使用 **DM 自动推送**(注册时 `--friend-id`、一键 `classify` 后推送结果),需本机存在有效 JWT:`/home/node/.openclaw/jwt.json`(与 `send_dm_message.py` 一致)
22
-
23
- ## 核心概念
24
-
25
- - **`{baseDir}`**:本 skill 根目录,即 `skills/image-classify`,调用时替换为实际绝对路径。
26
- - **配置文件**:`{baseDir}/references/config.json`,存储所有注册用户的名称、照片路径、人脸 embedding 向量,以及可选 **DM 绑定**:`friendId`(好友 userId)、`friendLabel`(可选展示名)。旧字段 `xia_you_hao` / `xia_you_label` 仍可被脚本读取。
27
- - **脚本入口**:`{baseDir}/scripts/face_search.py`,通过 `uv run` 以子命令方式调用。
28
- - **所有命令输出均为 JSON 格式**,方便解析结果。
29
-
30
- ## 通用调用格式
31
-
32
- ```bash
33
- uv run {baseDir}/scripts/face_search.py [-c CONFIG_PATH] <command> [args...]
34
- ```
35
-
36
- `-c` / `--config` 可选,指定配置文件路径,默认为 `references/config.json`(相对于执行目录)。建议始终传入绝对路径 `{baseDir}/references/config.json`。
37
-
38
- ## 可用命令一览
39
-
40
- | 命令 | 用途 | 示例 |
41
- |------|------|------|
42
- | `check <name>` | 检查用户名是否已注册 | `check 张三` |
43
- | `add <name> <image> [--friend-id ID] [--friend-label 名]` | 注册新用户;可选 `friendId` 与 `friendLabel`(括号内提示用) | `add 张三 /path/photo.jpg --friend-label 小李 --friend-id 23725` |
44
- | `replace <name> <image>` | 替换用户照片(删除旧照片) | `replace 张三 /path/new.jpg` |
45
- | `append <name> <image>` | 为已有用户追加一张照片 | `append 张三 /path/extra.jpg` |
46
- | `rename <old> <new>` | 修改用户名 | `rename 张三 李三` |
47
- | `delete <name>` | 删除用户 | `delete 张三` |
48
- | `search <name> <dir>` | 在目录中搜索某用户的相似人脸 | `search 张三 /home/photos` |
49
- | `quick-search <image> <dir>` | 直接用照片搜索相似人脸(不注册) | `quick-search /tmp/face.jpg /home/photos` |
50
- | `classify <dir>` | 一键分类:遍历所有用户搜索全部照片 | `classify /home/photos` |
51
- | `copy <target> [--name N]` | (可选)将搜索结果复制到本地文件夹 | `copy /output --name 张三` |
52
- | `pack [--name N] [--timeout T]` | 压缩结果为 zip 并上传获取下载链接 | `pack --timeout 120` |
53
- | `upload <file> [--timeout T]` | 上传文件获取 URL | `upload /path/file.zip` |
54
- | `init-today-folder` | 创建并返回待搜索目录当天子目录 | `init-today-folder` |
55
- | `upload-image <file...>` | 将一张或多张图片串行剪切到待搜索目录 `images/当天日期(YYYYMMDD)` | `upload-image /tmp/a.jpg /tmp/b.jpg` |
56
- | `list-date-folders` | 列出待搜索根目录 `images` 下全部 `YYYYMMDD` 子文件夹(新→旧),供未指定目录时选择 | `list-date-folders` |
57
-
58
- > ⚠️ 注意:如果用户发送的图片格式为 `![image](xxx.jpg)`,需要先执行 `upload` 命令将其转换为 URL 格式后再处理。
59
-
60
- ## Usage
61
-
62
- 根据用户意图匹配以下操作流程:
63
-
64
- ### 未指定搜索目录时(`search` / `quick-search` / `classify` 共用)
65
-
66
- 待搜索根目录由脚本内 `get_images_path()` 解析(通常为仓库上级 `images`)。其下按日期命名的子目录(`YYYYMMDD`)为可选搜索范围。
67
-
68
- 若用户**未说明**搜索目录(或只说「默认目录」「最近上传的」等),**不要猜测路径**,先执行:
69
-
70
- ```bash
71
- uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json list-date-folders
72
- ```
73
-
74
- 输出 JSON 字段说明:
75
- - `folders`:全部合法日期文件夹,`{ "name": "20260410", "path": "/绝对路径/20260410" }`,已按日期**从新到旧**排序
76
- - `preview` / `preview_n`:默认只向用户展示**最近 `preview_n` 个(默认 3 个)**即可
77
- - `total`:总数;若大于 `preview_n`,用户可说「更多」「全部」「列出全部」——此时用 Markdown 列出剩余项(**只展示 `name`**,不罗列每条 `path`),再请用户回复**序号**或**日期名(YYYYMMDD)**;用户若粘贴目录路径则按路径解析
78
-
79
- 选定目录后,将解析出的**绝对路径**作为 `<dir>` 传入 `search` / `quick-search` / `classify`。
80
-
81
- 若 `folders` 为空,提示用户在 `images` 下先上传或创建日期目录(可用 `init-today-folder`、`upload-image`),或**手动提供**任意搜索目录路径。
82
-
83
- **向用户展示候选目录时(示例模版)** — 用 Markdown 呈现,**只展示日期文件夹名**,不要把磁盘绝对路径列给用户:
84
-
85
- - 📅📂 **最近可用的日期文件夹(任选其一)**
86
- - 1️⃣ 📁 `20260410`
87
-
88
- - 2️⃣ 📁 `20260409`
89
-
90
- - 3️⃣ 📁 `20260408`
91
- - 💬 请回复**序号**或**日期名**;需要查看更多请说「更多」。内部调用命令时仍使用 JSON 里的 `path` 字段。✨
92
-
93
- ### 1. 添加/注册用户
94
-
95
- **触发词**:「添加 xxx 到照片分类器」「注册 xxx」「把这张照片记为 xxx」
96
-
97
- **流程**:
98
-
99
- 1. 获取用户提供的**用户名**、**照片路径**,以及是否绑定 **DM 接收方**(均可选)。用户常以自然语言写出类似:**虾友:xxx,ID:23725**(虾友即 DM 对象;**23725** 即 `friendId`)。解析规则:**xxx** → `--friend-label`;**23725** → `--friend-id`(正整数,与 `send_dm_message.py` 的 `--user-id` / 接口 `userId` 一致)。可只填 `friendId`、不填展示名。
100
- 2. 检查用户名是否已存在:
101
- ```bash
102
- uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json check "张三"
103
- ```
104
- 输出:`{"exists": true/false, "name": "张三"}`
105
-
106
- 3. **如果不存在** → 注册新用户(无虾友号):
107
- ```bash
108
- uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json add "张三" "/path/to/photo.jpg"
109
- ```
110
- 若用户提供了 `friendId`,追加 `--friend-id <正整数>`;若有展示名,追加 `--friend-label "xxx"`(注意转义或引号,避免 shell 拆词):
111
- ```bash
112
- uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json add "张三" "/path/to/photo.jpg" --friend-label "小李" --friend-id 23725
113
- ```
114
- 输出:`{"success": true/false, "message": "...", "name": "张三", "image_url": "https://...", "friendId": 23725, "friendLabel": "小李"}`(`friendId` / `friendLabel` 仅在实际传入时出现)
115
- - `success: true` → 提示:`🎉✨ **注册成功** · xxx`,并使用返回的 `image_url` 展示照片:`![image](image_url)`;若返回含 `friendId` / `friendLabel`,可顺带一句已绑定 DM(不必冗长)
116
- - `success: false` → 提示:`❌🙈 照片中未发现有效的人脸信息,注册失败!`
117
-
118
- 4. **如果已存在** → 提示用户选择操作:
119
- ```
120
- ⚡👤 用户名已存在,请选择操作:
121
- 1️⃣ 🔄 更新照片(替换主照片)
122
- 2️⃣ ✏️ 重新命名
123
- 3️⃣ ➕ 同时保留多张照片
124
- ```
125
- - **更新照片**:
126
- ```bash
127
- uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json replace "张三" "/path/to/new.jpg"
128
- ```
129
- 输出包含 `image_url` 字段。
130
- - 成功:`✅🔄 **照片已更新** · xxx`,使用 `image_url` 展示照片:`![image](image_url)`
131
- - 失败:`❌🙈 照片中未发现有效的人脸信息,更新失败!`
132
- - **重新命名**:
133
- ```bash
134
- uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json rename "张三" "李三"
135
- ```
136
- - 提示:`✏️📛 **用户名已更新** · xxx → yyy`
137
- - **保留多张**:
138
- ```bash
139
- uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json append "张三" "/path/to/extra.jpg"
140
- ```
141
- 输出包含 `image_url` 字段。
142
- - 成功:`✅➕ **新照片已追加** · xxx`,使用 `image_url` 展示照片:`![image](image_url)`
143
- - 失败:`❌🙈 照片中未发现有效的人脸信息,添加失败!`
144
-
145
- ### 2. 搜索用户照片
146
-
147
- **触发词**:「用照片分类器在 yy 文件夹下查找 xxx」「搜索 xxx 的照片」
148
-
149
- **流程**:
150
-
151
- 1. 从用户表述中提取**用户名**和**搜索目录**。若**未指定搜索目录**,先按上文「未指定搜索目录时」列出最近 3 个日期文件夹供选择(支持「更多」展示全部),得到 `<dir>` 后再继续。
152
- 2. 检查用户名是否存在(`check` 命令),不存在则提示:`❌🔍 **未找到该用户** · 请确认姓名后重试`
153
- 3. 使用**子会话**执行搜索(可能耗时较长):
154
- ```bash
155
- uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json search "张三" "<dir>"
156
- ```
157
- (`<dir>` 为用户指定路径,或从 `list-date-folders` 选中的 `path`。)**命令返回后立刻关闭并删除该子会话。**
158
- 输出:
159
- ```json
160
- {"name": "张三", "count": 3, "results": [{"image_path": "...", "face_index": 0, "similarity": 0.85}, ...]}
161
- ```
162
- 4. 将结果通知到当前会话,以表格形式展示:
163
- ```
164
- 🔎✨ **人脸搜索结果** · 👤 <用户名>
165
- ───────────────────────
166
- ```
167
- | 🖼️ 照片路径 | 📊 相似度 |
168
- |:----:|:----:|
169
- | /path/to/photo.jpg | 0.85 |
170
- 5. 展示结果后按「结果导出」执行 `pack` 生成下载链接(见 §6);`pack` 返回后若含 `dm_lines`(向虾友推送**下载链接**的状态),须在链接展示之后**再**逐行展示(可与搜索结果本身区分开)。
171
-
172
- ### 3. 直接搜索(不注册)
173
-
174
- **触发词**:「用这张照片搜索 yy 文件夹」「直接用照片查找」「不注册直接搜」
175
-
176
- **流程**:
177
-
178
- 1. 获取用户提供的**照片路径**和**搜索目录**。若**未指定搜索目录**,先按「未指定搜索目录时」列出最近 3 个日期文件夹供选择(支持「更多」),得到 `<dir>` 后再继续。
179
- 2. 使用**子会话**执行搜索(先提取人脸 embedding,再匹配,可能耗时较长):
180
- ```bash
181
- uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json quick-search "/path/to/face.jpg" "<dir>"
182
- ```
183
- **命令返回后立刻关闭并删除该子会话。**
184
- 输出:
185
- ```json
186
- {"success": true/false, "count": 3, "results": [...], "message": "..."}
187
- ```
188
- - `success: false` → 表示照片中未检测到有效人脸,提示:`❌🙈 **未检测到人脸** · 无法搜索`
189
- 3. 将结果通知到当前会话,以表格形式展示:
190
- ```
191
- 🪪🖼️ **直接搜索**(未注册)· 已用查询图匹配
192
- ───────────────────────
193
- ```
194
- | 🖼️ 照片路径 | 📊 相似度 |
195
- |:----:|:----:|
196
- | /path/to/photo.jpg | 0.85 |
197
- 4. 展示结果后按「结果导出」执行 `pack` 生成下载链接(见 §6);`pack` 返回后若含 `dm_lines`,须在链接展示之后**再**逐行展示。
198
-
199
- ### 4. 一键分类
200
-
201
- **触发词**:「用照片分类器对 xx 文件夹进行分类」「一键分类」「对这些照片按人分类」
202
-
203
- **流程**:
204
-
205
- 1. 从用户表述中提取**搜索目录**。若**未指定搜索目录**,先按「未指定搜索目录时」列出最近 3 个日期文件夹供选择(支持「更多」),得到 `<dir>` 后再继续。
206
- 2. 使用**子会话**执行分类(可能耗时较长):
207
- ```bash
208
- uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json classify "<dir>"
209
- ```
210
- **命令返回后立刻关闭并删除该子会话。**
211
- 输出(节选):
212
- ```json
213
- {
214
- "user_count": 2,
215
- "users": {"张三": {"count": 3, "results": [...]}, "李四": {"count": 1, "results": [...]}},
216
- "dm": {"张三": {"success": true, "friendId": 23725, "friendLabel": "小李"}},
217
- "dm_lines": ["✅ 💌 已向虾友「小李」发送成功", "📭 「李四」暂未绑定虾友,跳过私信"]
218
- }
219
- ```
220
- - `dm`:仅当配置里**至少有一位用户**登记了 `friendId` 时出现;脚本在分类结束后**自动调用** `{baseDir}/scripts/send_dm_message.py`(`--user-id` = `friendId`),将**该用户本轮分类结果摘要**发出。失败时含 `"success": false` 与 `detail`。
221
- - `dm_lines`:**只要本轮参与分类的用户数 ≥1 即出现**(与是否有人绑定 `friendId` 无关)。为**最终提示专用**短句数组,顺序与本轮 `users` 中用户顺序一致。句式固定:
222
- - 已绑定且发送成功:`✅ 💌 已向虾友「xxx」发送成功` — **xxx** 优先为配置中的 `friendLabel`,否则为 `friendId` 数字字符串。
223
- - 已绑定且发送失败:`❌ 💢 虾友「xxx」发送失败:<原因>`(原因取自 `dm` 中对应用户的 `detail`)。
224
- - 未绑定 `friendId`:`📭 「<本地用户名>」暂未绑定虾友,跳过私信`。
225
- - `user_count: 0` → 提示:`❌👥 **暂无注册用户** · 请先注册人脸后再分类`
226
- 3. 将结果通知到当前会话,对每个用户分别展示:
227
- ```
228
- 🗂️✨ **一键分类完成** · 共 👥 N 位注册用户参与匹配
229
- ───────────────────────
230
- ```
231
- 对每个有匹配结果的用户:
232
- ```
233
- 👤✅ **张三** · 📸 匹配 M 张
234
- ```
235
- | 🖼️ 照片路径 | 📊 相似度 |
236
- |:----:|:----:|
237
- | /path/to/photo.jpg | 0.85 |
238
-
239
- 无匹配结果的用户:
240
- ```
241
- 👤💤 **王五** · 本轮暂无匹配
242
- ```
243
- 4. **分类摘要 DM(必须在表格之后、`pack` 之前展示)**:若 `classify` 的 JSON 含 `dm_lines`(本轮**分类结果摘要**的私信状态),在分类表格**之后**单独加一块,**逐行原样**展示。示例:
244
- ```
245
- 📬 **虾友发送状态(分类摘要)**
246
- ✅ 💌 已向虾友「小李」发送成功
247
- 📭 「李四」暂未绑定虾友,跳过私信
248
- ```
249
- 无 `dm_lines` 时(仅 `user_count: 0` 等异常)跳过本块。
250
- 5. 展示结果后按「结果导出」执行 `pack` 生成下载链接(见 §6)。**`pack` 成功后还会自动向对应 `friendId` 私信「打包下载链接」**;若 `pack` 的 JSON 另含 `dm_lines`(**下载链接**的私信状态),须在下载链接展示之后**再**逐行展示,可与上一步标题区分,例如「下载链接私信状态」。
251
-
252
- ### 5. 删除用户
253
-
254
- **触发词**:「删除照片分类器中 xxx 的信息」「把 xxx 从照片分类器移除」
255
-
256
- **流程**:
257
-
258
- 1. 从用户表述中提取**用户名**
259
- 2. 检查用户名是否存在(`check` 命令),不存在则提示:`❌🔍 **未找到该用户** · 请确认姓名后重试`
260
- 3. 提示确认:`⚠️🗑️ **确认删除用户 xxx?** · 此操作不可撤销`
261
- - 用户确认 →
262
- ```bash
263
- uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json delete "张三"
264
- ```
265
- 提示:`🗑️✨ **用户已删除** · xxx`
266
- - 用户取消 → 提示:`↩️👋 **已取消删除**`
267
-
268
- ### 6. 结果导出(搜索/分类完成后)
269
-
270
- 搜索或分类完成后,结果已保存在 `config.json` 中。展示匹配结果表格(分类场景下若已有「分类摘要」`dm_lines`,须先展示完毕)后,**不要先弹出与导出无关的菜单**,直接执行 **`pack`** 生成下载链接(压缩包可能较大,超时默认 120 秒)。
271
-
272
- **`pack` 成功后,脚本会自动调用** `{baseDir}/scripts/send_dm_message.py`,向**已绑定 `friendId` 的注册用户**私信发送**对应用户的打包下载链接**;正文模板为:先提示「「用户名」的照片已为您送达」,再附 URL,并提醒 **24 小时内下载**、逾期链接可能失效。无 `friendId` 的用户条目会体现在返回的 `dm_lines` 里(`📭 「xxx」暂未绑定虾友,跳过私信`)。**仅 `quick-search` 结果、无注册用户名时**,无法绑定虾友,不会发链接私信。
273
-
274
- - **单用户 `search`**(指定 `--name`):
275
- ```bash
276
- uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json pack --name "张三" --timeout 120
277
- ```
278
- 输出(节选):`{"success": true, "url": "https://...", "zip_path": "/tmp/.../search_results.zip", "dm": {...}, "dm_lines": [...]}`(有 `friendId` 时含 `dm` / `dm_lines`)
279
- 成功提示:`📦🔗 **下载链接已就绪** ✨` → `<url>` → 若有 `dm_lines`,再展示「下载链接私信状态」块。
280
-
281
- - **`quick-search`(直接搜索)**:结果存于 `quick_search_result`,执行 **不带 `--name`** 的 `pack`(与仅含直接搜索结果时一致):
282
- ```bash
283
- uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json pack --timeout 120
284
- ```
285
- 成功提示:`📦🔗 **下载链接已就绪** ✨` → `<url>`(通常**无**虾友私信,因无注册用户上下文)
286
-
287
- - **一键 `classify`**(不指定 `--name`,**每位用户单独打包**):
288
- ```bash
289
- uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json pack --timeout 120
290
- ```
291
- 输出示例(节选):
292
- ```json
293
- {
294
- "success": true,
295
- "user_urls": {"张三": "https://...", "李四": "https://..."},
296
- "errors": null,
297
- "dm": {"张三": {"success": true, "friendId": 23725, "friendLabel": "小李", "url": "https://..."}},
298
- "dm_lines": ["✅ 💌 已向虾友「小李」发送成功", "📭 「李四」暂未绑定虾友,跳过私信"]
299
- }
300
- ```
301
- 成功提示:先逐用户展示链接,例如:
302
- ```
303
- 📦✨ **各用户独立下载包**
304
- ───────────────────────
305
- 👤 张三 📎 <url>
306
- 👤 李四 📎 <url>
307
- ```
308
- 再展示 `dm_lines`(下载链接私信状态)。
309
- 部分失败:列出已成功链接,并对失败用户提示:`⚠️❌ **<用户名>** · 下载包生成失败:<原因>`;`dm_lines` 中亦会有对应失败说明。全部失败:`❌📦 下载链接全部失败`。
310
-
311
- `pack` 完成后,**结果导出即结束**。若用户另行要求把文件复制到本地目录,可再使用命令表中的 `copy`(非本 skill 默认流程)。
312
-
313
- ### 7. 上传图片到待搜索目录
314
-
315
- **触发词**:「上传这张图片到待搜索目录」「上传这些图片到待搜索目录」「上传这些照片」「把图片放到今天目录供搜索」「把图片移到待搜索目录」
316
-
317
- **流程**:
318
-
319
- 1. 获取用户提供的**图片路径**(支持单张或多张)
320
- 2. 直接执行:
321
- ```bash
322
- uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json upload-image "/path/to/a.jpg" "/path/to/b.jpg"
323
- ```
324
- 3. 单张时输出:`{"success": true/false, "folder_path": "/abs/path/to/images/YYYYMMDD", "file_path": "/abs/path/to/images/YYYYMMDD/a.jpg", "failed": []}`
325
- 4. 多张时输出:`{"success": true/false, "folder_path": "/abs/path/to/images/YYYYMMDD", "uploaded": [...], "failed": [...]}`
326
- 5. 成功后提示:`✅📤 **已放入待搜索目录** → <folder_path> ✨`;如果有失败文件,提示:`⚠️ 部分失败:` 并列出项。
327
-
328
- ## Example Workflow
329
-
330
- - 用户:「把这张照片添加为张三」
331
- 1. `uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json check "张三"`
332
- 2. 不存在 → `uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json add "张三" "/path/to/photo.jpg"`
333
- 3. 提示:`🎉✨ **注册成功** · 张三`
334
-
335
- - 用户:「用照片分类器在 /home/photos 下查找张三」
336
- 1. `uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json check "张三"` → 存在
337
- 2. 子会话执行 `uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json search "张三" "/home/photos"`
338
- 3. 展示结果表格 → `pack --name "张三" --timeout 120` 生成下载链接(见 §6)→ 若有 `dm_lines`,展示下载链接私信状态
339
-
340
- - 用户:「用这张照片在 /home/photos 里找找有没有类似的」
341
- 1. 子会话执行 `uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json quick-search "/tmp/face.jpg" "/home/photos"`
342
- 2. 成功 → 展示表格 → `pack --timeout 120`(不带 `--name`);失败 → 提示未检测到有效人脸
343
-
344
- - 用户:「用照片分类器对 /home/album 进行分类」
345
- 1. 子会话执行 `uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json classify "/home/album"`
346
- 2. 展示各用户结果(及分类摘要 `dm_lines` 若有)→ `pack --timeout 120`(多用户各一链接,见 §6)→ 展示链接及 **`pack` 返回的 `dm_lines`**(下载链接私信状态)
347
-
348
- - 用户:「删除照片分类器中李四的信息」
349
- 1. `uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json check "李四"` → 存在
350
- 2. 提示确认 → 用户确认 → `uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json delete "李四"`
351
- 3. 提示:`🗑️✨ **用户已删除** · 李四`
352
-
353
- - 用户:「把这些图片放到待搜索目录」
354
- 1. `uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json upload-image "/tmp/a.jpg" "/tmp/b.jpg"`
355
- 2. 全部成功后提示:`✅📤 **已放入待搜索目录** → <folder_path> ✨`
356
-
357
- ## Notes
358
-
359
- - 建议始终通过 `-c` 传入 `{baseDir}/references/config.json` 的绝对路径,避免相对路径导致找不到配置文件。
360
- - `search`、`quick-search` 和 `classify` 可能耗时较长(取决于搜索目录中的图片数量),应在**子会话**中执行;**结束后立即关闭并删除该子会话**,再将结果展示与 `pack` 放在**主会话**中完成。
361
- - `images/` 目录用于存放待搜索图片;`upload-image` 内部会创建当天目录并串行逐张处理图片。
362
- - 搜索过程中会在图片所在目录下创建 `.embedding` 隐藏目录缓存 embedding 结果,后续搜索同一目录会自动跳过已处理的图片。
363
- - `pack` 与 `copy` 均依赖 `config.json` 中保存的搜索结果(`search_result` 或 `quick_search_result` 等),须先执行 `search`、`classify` 或 `quick-search`。默认流程只需 **`pack`**;`copy` 为可选,由用户另行提出时再执行。
364
- - **`classify`** 会向 `friendId` 发**分类结果摘要**;**`pack`** 会向 `friendId` 发**打包下载链接**(两次私信、用途不同);若只需其一,可后续再改脚本或配置(当前实现为两者都发)。
365
- - `pack` 的压缩文件存放在系统临时目录中,上传完成后可忽略清理。上传超时默认 120 秒,文件特别大时可通过 `--timeout` 增大。
366
- - `config.json` 中的 `query_threshold`(默认 0.7)控制人脸检测置信度阈值,`search_similarity_threshold`(默认 0.3)控制搜索匹配的最低相似度。
367
- - `{baseDir}` 指本 skill 根目录(如 `skills/image-classify`),调用时替换为实际绝对路径。
368
- - `friendId`(虾友号)与可选 `friendLabel` 写在用户条目下;**注册时**通过 `add ... --friend-id` / `--friend-label` 写入。后续若需修改可编辑 `config.json`(本 skill 未单独提供改绑子命令)。旧键名仍兼容读取。
1
+ ---
2
+ name: image-classify
3
+ description: 照片分类器。通过人脸识别对照片进行分类、搜索和管理。当用户说「用照片分类器查找/搜索 xxx」「对 xx 文件夹进行分类」「添加 xx 到照片分类器」「从照片分类器删除 xx」时使用。
4
+ ---
5
+
6
+ # 📸 照片分类器
7
+
8
+ 基于人脸 embedding 相似度的照片分类系统。支持注册用户人脸、按用户搜索照片、一键全量分类、删除用户;搜索/分类结束后**生成下载链接**(`pack`)即完成结果导出。
9
+
10
+ ## Processing Mode
11
+
12
+ **STRICT SERIAL PROCESSING ONLY** — 单次顺序执行,不拆分子任务、不并行。
13
+
14
+ **子会话(耗时任务)**:`search`、`quick-search`、`classify` 在**独立子会话**中执行。**子命令结束(成功或失败)后,须立即关闭并删除该子会话**,不得保留空壳会话。后续步骤——向用户展示结果表格、执行 `pack`——一律在**当前主会话**中完成。
15
+
16
+ ## Prerequisites
17
+
18
+ - Python 3.10+、uv
19
+ - 依赖:`requests`, `opencv-python`, `numpy`, `sophnet_tools`(项目内置)
20
+ - 配置文件:`{baseDir}/references/config.json`
21
+ - 若使用 **DM 自动推送**(注册时 `--friend-id`、一键 `classify` 后推送结果),需本机存在有效 JWT:`/home/node/.openclaw/jwt.json`(与 `send_dm_message.py` 一致)
22
+
23
+ ## 核心概念
24
+
25
+ - **`{baseDir}`**:本 skill 根目录,即 `skills/image-classify`,调用时替换为实际绝对路径。
26
+ - **配置文件**:`{baseDir}/references/config.json`,存储所有注册用户的名称、照片路径、人脸 embedding 向量,以及可选 **DM 绑定**:`friendId`(好友 userId)、`friendLabel`(可选展示名)。旧字段 `xia_you_hao` / `xia_you_label` 仍可被脚本读取。
27
+ - **脚本入口**:`{baseDir}/scripts/face_search.py`,通过 `uv run` 以子命令方式调用。
28
+ - **所有命令输出均为 JSON 格式**,方便解析结果。
29
+
30
+ ## 通用调用格式
31
+
32
+ ```bash
33
+ uv run {baseDir}/scripts/face_search.py [-c CONFIG_PATH] <command> [args...]
34
+ ```
35
+
36
+ `-c` / `--config` 可选,指定配置文件路径,默认为 `references/config.json`(相对于执行目录)。建议始终传入绝对路径 `{baseDir}/references/config.json`。
37
+
38
+ ## 可用命令一览
39
+
40
+ | 命令 | 用途 | 示例 |
41
+ |------|------|------|
42
+ | `check <name>` | 检查用户名是否已注册 | `check 张三` |
43
+ | `add <name> <image> [--friend-id ID] [--friend-label 名]` | 注册新用户;可选 `friendId` 与 `friendLabel`(括号内提示用) | `add 张三 /path/photo.jpg --friend-label 小李 --friend-id 23725` |
44
+ | `replace <name> <image>` | 替换用户照片(删除旧照片) | `replace 张三 /path/new.jpg` |
45
+ | `append <name> <image>` | 为已有用户追加一张照片 | `append 张三 /path/extra.jpg` |
46
+ | `rename <old> <new>` | 修改用户名 | `rename 张三 李三` |
47
+ | `delete <name>` | 删除用户 | `delete 张三` |
48
+ | `search <name> <dir>` | 在目录中搜索某用户的相似人脸 | `search 张三 /home/photos` |
49
+ | `quick-search <image> <dir>` | 直接用照片搜索相似人脸(不注册) | `quick-search /tmp/face.jpg /home/photos` |
50
+ | `classify <dir>` | 一键分类:遍历所有用户搜索全部照片 | `classify /home/photos` |
51
+ | `copy <target> [--name N]` | (可选)将搜索结果复制到本地文件夹 | `copy /output --name 张三` |
52
+ | `pack [--name N] [--timeout T]` | 压缩结果为 zip 并上传获取下载链接 | `pack --timeout 120` |
53
+ | `upload <file> [--timeout T]` | 上传文件获取 URL | `upload /path/file.zip` |
54
+ | `init-today-folder` | 创建并返回待搜索目录当天子目录 | `init-today-folder` |
55
+ | `upload-image <file...>` | 将一张或多张图片串行剪切到待搜索目录 `images/当天日期(YYYYMMDD)` | `upload-image /tmp/a.jpg /tmp/b.jpg` |
56
+ | `list-date-folders` | 列出待搜索根目录 `images` 下全部 `YYYYMMDD` 子文件夹(新→旧),供未指定目录时选择 | `list-date-folders` |
57
+
58
+ > ⚠️ 注意:如果用户发送的图片格式为 `![image](xxx.jpg)`,需要先执行 `upload` 命令将其转换为 URL 格式后再处理。
59
+
60
+ ## Usage
61
+
62
+ 根据用户意图匹配以下操作流程:
63
+
64
+ ### 未指定搜索目录时(`search` / `quick-search` / `classify` 共用)
65
+
66
+ 待搜索根目录由脚本内 `get_images_path()` 解析(通常为仓库上级 `images`)。其下按日期命名的子目录(`YYYYMMDD`)为可选搜索范围。
67
+
68
+ 若用户**未说明**搜索目录(或只说「默认目录」「最近上传的」等),**不要猜测路径**,先执行:
69
+
70
+ ```bash
71
+ uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json list-date-folders
72
+ ```
73
+
74
+ 输出 JSON 字段说明:
75
+ - `folders`:全部合法日期文件夹,`{ "name": "20260410", "path": "/绝对路径/20260410" }`,已按日期**从新到旧**排序
76
+ - `preview` / `preview_n`:默认只向用户展示**最近 `preview_n` 个(默认 3 个)**即可
77
+ - `total`:总数;若大于 `preview_n`,用户可说「更多」「全部」「列出全部」——此时用 Markdown 列出剩余项(**只展示 `name`**,不罗列每条 `path`),再请用户回复**序号**或**日期名(YYYYMMDD)**;用户若粘贴目录路径则按路径解析
78
+
79
+ 选定目录后,将解析出的**绝对路径**作为 `<dir>` 传入 `search` / `quick-search` / `classify`。
80
+
81
+ 若 `folders` 为空,提示用户在 `images` 下先上传或创建日期目录(可用 `init-today-folder`、`upload-image`),或**手动提供**任意搜索目录路径。
82
+
83
+ **向用户展示候选目录时(示例模版)** — 用 Markdown 呈现,**只展示日期文件夹名**,不要把磁盘绝对路径列给用户:
84
+
85
+ - 📅📂 **最近可用的日期文件夹(任选其一)**
86
+ - 1️⃣ 📁 `20260410`
87
+
88
+ - 2️⃣ 📁 `20260409`
89
+
90
+ - 3️⃣ 📁 `20260408`
91
+ - 💬 请回复**序号**或**日期名**;需要查看更多请说「更多」。内部调用命令时仍使用 JSON 里的 `path` 字段。✨
92
+
93
+ ### 1. 添加/注册用户
94
+
95
+ **触发词**:「添加 xxx 到照片分类器」「注册 xxx」「把这张照片记为 xxx」
96
+
97
+ **流程**:
98
+
99
+ 1. 获取用户提供的**用户名**、**照片路径**,以及是否绑定 **DM 接收方**(均可选)。用户常以自然语言写出类似:**虾友:xxx,ID:23725**(虾友即 DM 对象;**23725** 即 `friendId`)。解析规则:**xxx** → `--friend-label`;**23725** → `--friend-id`(正整数,与 `send_dm_message.py` 的 `--user-id` / 接口 `userId` 一致)。可只填 `friendId`、不填展示名。
100
+ 2. 检查用户名是否已存在:
101
+ ```bash
102
+ uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json check "张三"
103
+ ```
104
+ 输出:`{"exists": true/false, "name": "张三"}`
105
+
106
+ 3. **如果不存在** → 注册新用户(无虾友号):
107
+ ```bash
108
+ uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json add "张三" "/path/to/photo.jpg"
109
+ ```
110
+ 若用户提供了 `friendId`,追加 `--friend-id <正整数>`;若有展示名,追加 `--friend-label "xxx"`(注意转义或引号,避免 shell 拆词):
111
+ ```bash
112
+ uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json add "张三" "/path/to/photo.jpg" --friend-label "小李" --friend-id 23725
113
+ ```
114
+ 输出:`{"success": true/false, "message": "...", "name": "张三", "image_url": "https://...", "friendId": 23725, "friendLabel": "小李"}`(`friendId` / `friendLabel` 仅在实际传入时出现)
115
+ - `success: true` → 提示:`🎉✨ **注册成功** · xxx`,并使用返回的 `image_url` 展示照片:`![image](image_url)`;若返回含 `friendId` / `friendLabel`,可顺带一句已绑定 DM(不必冗长)
116
+ - `success: false` → 提示:`❌🙈 照片中未发现有效的人脸信息,注册失败!`
117
+
118
+ 4. **如果已存在** → 提示用户选择操作:
119
+ ```
120
+ ⚡👤 用户名已存在,请选择操作:
121
+ 1️⃣ 🔄 更新照片(替换主照片)
122
+ 2️⃣ ✏️ 重新命名
123
+ 3️⃣ ➕ 同时保留多张照片
124
+ ```
125
+ - **更新照片**:
126
+ ```bash
127
+ uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json replace "张三" "/path/to/new.jpg"
128
+ ```
129
+ 输出包含 `image_url` 字段。
130
+ - 成功:`✅🔄 **照片已更新** · xxx`,使用 `image_url` 展示照片:`![image](image_url)`
131
+ - 失败:`❌🙈 照片中未发现有效的人脸信息,更新失败!`
132
+ - **重新命名**:
133
+ ```bash
134
+ uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json rename "张三" "李三"
135
+ ```
136
+ - 提示:`✏️📛 **用户名已更新** · xxx → yyy`
137
+ - **保留多张**:
138
+ ```bash
139
+ uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json append "张三" "/path/to/extra.jpg"
140
+ ```
141
+ 输出包含 `image_url` 字段。
142
+ - 成功:`✅➕ **新照片已追加** · xxx`,使用 `image_url` 展示照片:`![image](image_url)`
143
+ - 失败:`❌🙈 照片中未发现有效的人脸信息,添加失败!`
144
+
145
+ ### 2. 搜索用户照片
146
+
147
+ **触发词**:「用照片分类器在 yy 文件夹下查找 xxx」「搜索 xxx 的照片」
148
+
149
+ **流程**:
150
+
151
+ 1. 从用户表述中提取**用户名**和**搜索目录**。若**未指定搜索目录**,先按上文「未指定搜索目录时」列出最近 3 个日期文件夹供选择(支持「更多」展示全部),得到 `<dir>` 后再继续。
152
+ 2. 检查用户名是否存在(`check` 命令),不存在则提示:`❌🔍 **未找到该用户** · 请确认姓名后重试`
153
+ 3. 使用**子会话**执行搜索(可能耗时较长):
154
+ ```bash
155
+ uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json search "张三" "<dir>"
156
+ ```
157
+ (`<dir>` 为用户指定路径,或从 `list-date-folders` 选中的 `path`。)**命令返回后立刻关闭并删除该子会话。**
158
+ 输出:
159
+ ```json
160
+ {"name": "张三", "count": 3, "results": [{"image_path": "...", "face_index": 0, "similarity": 0.85}, ...]}
161
+ ```
162
+ 4. 将结果通知到当前会话,以表格形式展示:
163
+ ```
164
+ 🔎✨ **人脸搜索结果** · 👤 <用户名>
165
+ ───────────────────────
166
+ ```
167
+ | 🖼️ 照片路径 | 📊 相似度 |
168
+ |:----:|:----:|
169
+ | /path/to/photo.jpg | 0.85 |
170
+ 5. 展示结果后按「结果导出」执行 `pack` 生成下载链接(见 §6);`pack` 返回后若含 `dm_lines`(向虾友推送**下载链接**的状态),须在链接展示之后**再**逐行展示(可与搜索结果本身区分开)。
171
+
172
+ ### 3. 直接搜索(不注册)
173
+
174
+ **触发词**:「用这张照片搜索 yy 文件夹」「直接用照片查找」「不注册直接搜」
175
+
176
+ **流程**:
177
+
178
+ 1. 获取用户提供的**照片路径**和**搜索目录**。若**未指定搜索目录**,先按「未指定搜索目录时」列出最近 3 个日期文件夹供选择(支持「更多」),得到 `<dir>` 后再继续。
179
+ 2. 使用**子会话**执行搜索(先提取人脸 embedding,再匹配,可能耗时较长):
180
+ ```bash
181
+ uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json quick-search "/path/to/face.jpg" "<dir>"
182
+ ```
183
+ **命令返回后立刻关闭并删除该子会话。**
184
+ 输出:
185
+ ```json
186
+ {"success": true/false, "count": 3, "results": [...], "message": "..."}
187
+ ```
188
+ - `success: false` → 表示照片中未检测到有效人脸,提示:`❌🙈 **未检测到人脸** · 无法搜索`
189
+ 3. 将结果通知到当前会话,以表格形式展示:
190
+ ```
191
+ 🪪🖼️ **直接搜索**(未注册)· 已用查询图匹配
192
+ ───────────────────────
193
+ ```
194
+ | 🖼️ 照片路径 | 📊 相似度 |
195
+ |:----:|:----:|
196
+ | /path/to/photo.jpg | 0.85 |
197
+ 4. 展示结果后按「结果导出」执行 `pack` 生成下载链接(见 §6);`pack` 返回后若含 `dm_lines`,须在链接展示之后**再**逐行展示。
198
+
199
+ ### 4. 一键分类
200
+
201
+ **触发词**:「用照片分类器对 xx 文件夹进行分类」「一键分类」「对这些照片按人分类」
202
+
203
+ **流程**:
204
+
205
+ 1. 从用户表述中提取**搜索目录**。若**未指定搜索目录**,先按「未指定搜索目录时」列出最近 3 个日期文件夹供选择(支持「更多」),得到 `<dir>` 后再继续。
206
+ 2. 使用**子会话**执行分类(可能耗时较长):
207
+ ```bash
208
+ uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json classify "<dir>"
209
+ ```
210
+ **命令返回后立刻关闭并删除该子会话。**
211
+ 输出(节选):
212
+ ```json
213
+ {
214
+ "user_count": 2,
215
+ "users": {"张三": {"count": 3, "results": [...]}, "李四": {"count": 1, "results": [...]}},
216
+ "dm": {"张三": {"success": true, "friendId": 23725, "friendLabel": "小李"}},
217
+ "dm_lines": ["✅ 💌 已向虾友「小李」发送成功", "📭 「李四」暂未绑定虾友,跳过私信"]
218
+ }
219
+ ```
220
+ - `dm`:仅当配置里**至少有一位用户**登记了 `friendId` 时出现;脚本在分类结束后**自动调用** `{baseDir}/scripts/send_dm_message.py`(`--user-id` = `friendId`),将**该用户本轮分类结果摘要**发出。失败时含 `"success": false` 与 `detail`。
221
+ - `dm_lines`:**只要本轮参与分类的用户数 ≥1 即出现**(与是否有人绑定 `friendId` 无关)。为**最终提示专用**短句数组,顺序与本轮 `users` 中用户顺序一致。句式固定:
222
+ - 已绑定且发送成功:`✅ 💌 已向虾友「xxx」发送成功` — **xxx** 优先为配置中的 `friendLabel`,否则为 `friendId` 数字字符串。
223
+ - 已绑定且发送失败:`❌ 💢 虾友「xxx」发送失败:<原因>`(原因取自 `dm` 中对应用户的 `detail`)。
224
+ - 未绑定 `friendId`:`📭 「<本地用户名>」暂未绑定虾友,跳过私信`。
225
+ - `user_count: 0` → 提示:`❌👥 **暂无注册用户** · 请先注册人脸后再分类`
226
+ 3. 将结果通知到当前会话,对每个用户分别展示:
227
+ ```
228
+ 🗂️✨ **一键分类完成** · 共 👥 N 位注册用户参与匹配
229
+ ───────────────────────
230
+ ```
231
+ 对每个有匹配结果的用户:
232
+ ```
233
+ 👤✅ **张三** · 📸 匹配 M 张
234
+ ```
235
+ | 🖼️ 照片路径 | 📊 相似度 |
236
+ |:----:|:----:|
237
+ | /path/to/photo.jpg | 0.85 |
238
+
239
+ 无匹配结果的用户:
240
+ ```
241
+ 👤💤 **王五** · 本轮暂无匹配
242
+ ```
243
+ 4. **分类摘要 DM(必须在表格之后、`pack` 之前展示)**:若 `classify` 的 JSON 含 `dm_lines`(本轮**分类结果摘要**的私信状态),在分类表格**之后**单独加一块,**逐行原样**展示。示例:
244
+ ```
245
+ 📬 **虾友发送状态(分类摘要)**
246
+ ✅ 💌 已向虾友「小李」发送成功
247
+ 📭 「李四」暂未绑定虾友,跳过私信
248
+ ```
249
+ 无 `dm_lines` 时(仅 `user_count: 0` 等异常)跳过本块。
250
+ 5. 展示结果后按「结果导出」执行 `pack` 生成下载链接(见 §6)。**`pack` 成功后还会自动向对应 `friendId` 私信「打包下载链接」**;若 `pack` 的 JSON 另含 `dm_lines`(**下载链接**的私信状态),须在下载链接展示之后**再**逐行展示,可与上一步标题区分,例如「下载链接私信状态」。
251
+
252
+ ### 5. 删除用户
253
+
254
+ **触发词**:「删除照片分类器中 xxx 的信息」「把 xxx 从照片分类器移除」
255
+
256
+ **流程**:
257
+
258
+ 1. 从用户表述中提取**用户名**
259
+ 2. 检查用户名是否存在(`check` 命令),不存在则提示:`❌🔍 **未找到该用户** · 请确认姓名后重试`
260
+ 3. 提示确认:`⚠️🗑️ **确认删除用户 xxx?** · 此操作不可撤销`
261
+ - 用户确认 →
262
+ ```bash
263
+ uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json delete "张三"
264
+ ```
265
+ 提示:`🗑️✨ **用户已删除** · xxx`
266
+ - 用户取消 → 提示:`↩️👋 **已取消删除**`
267
+
268
+ ### 6. 结果导出(搜索/分类完成后)
269
+
270
+ 搜索或分类完成后,结果已保存在 `config.json` 中。展示匹配结果表格(分类场景下若已有「分类摘要」`dm_lines`,须先展示完毕)后,**不要先弹出与导出无关的菜单**,直接执行 **`pack`** 生成下载链接(压缩包可能较大,超时默认 120 秒)。
271
+
272
+ **`pack` 成功后,脚本会自动调用** `{baseDir}/scripts/send_dm_message.py`,向**已绑定 `friendId` 的注册用户**私信发送**对应用户的打包下载链接**;正文模板为:先提示「「用户名」的照片已为您送达」,再附 URL,并提醒 **24 小时内下载**、逾期链接可能失效。无 `friendId` 的用户条目会体现在返回的 `dm_lines` 里(`📭 「xxx」暂未绑定虾友,跳过私信`)。**仅 `quick-search` 结果、无注册用户名时**,无法绑定虾友,不会发链接私信。
273
+
274
+ - **单用户 `search`**(指定 `--name`):
275
+ ```bash
276
+ uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json pack --name "张三" --timeout 120
277
+ ```
278
+ 输出(节选):`{"success": true, "url": "https://...", "zip_path": "/tmp/.../search_results.zip", "dm": {...}, "dm_lines": [...]}`(有 `friendId` 时含 `dm` / `dm_lines`)
279
+ 成功提示:`📦🔗 **下载链接已就绪** ✨` → `<url>` → 若有 `dm_lines`,再展示「下载链接私信状态」块。
280
+
281
+ - **`quick-search`(直接搜索)**:结果存于 `quick_search_result`,执行 **不带 `--name`** 的 `pack`(与仅含直接搜索结果时一致):
282
+ ```bash
283
+ uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json pack --timeout 120
284
+ ```
285
+ 成功提示:`📦🔗 **下载链接已就绪** ✨` → `<url>`(通常**无**虾友私信,因无注册用户上下文)
286
+
287
+ - **一键 `classify`**(不指定 `--name`,**每位用户单独打包**):
288
+ ```bash
289
+ uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json pack --timeout 120
290
+ ```
291
+ 输出示例(节选):
292
+ ```json
293
+ {
294
+ "success": true,
295
+ "user_urls": {"张三": "https://...", "李四": "https://..."},
296
+ "errors": null,
297
+ "dm": {"张三": {"success": true, "friendId": 23725, "friendLabel": "小李", "url": "https://..."}},
298
+ "dm_lines": ["✅ 💌 已向虾友「小李」发送成功", "📭 「李四」暂未绑定虾友,跳过私信"]
299
+ }
300
+ ```
301
+ 成功提示:先逐用户展示链接,例如:
302
+ ```
303
+ 📦✨ **各用户独立下载包**
304
+ ───────────────────────
305
+ 👤 张三 📎 <url>
306
+ 👤 李四 📎 <url>
307
+ ```
308
+ 再展示 `dm_lines`(下载链接私信状态)。
309
+ 部分失败:列出已成功链接,并对失败用户提示:`⚠️❌ **<用户名>** · 下载包生成失败:<原因>`;`dm_lines` 中亦会有对应失败说明。全部失败:`❌📦 下载链接全部失败`。
310
+
311
+ `pack` 完成后,**结果导出即结束**。若用户另行要求把文件复制到本地目录,可再使用命令表中的 `copy`(非本 skill 默认流程)。
312
+
313
+ ### 7. 上传图片到待搜索目录
314
+
315
+ **触发词**:「上传这张图片到待搜索目录」「上传这些图片到待搜索目录」「上传这些照片」「把图片放到今天目录供搜索」「把图片移到待搜索目录」
316
+
317
+ **流程**:
318
+
319
+ 1. 获取用户提供的**图片路径**(支持单张或多张)
320
+ 2. 直接执行:
321
+ ```bash
322
+ uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json upload-image "/path/to/a.jpg" "/path/to/b.jpg"
323
+ ```
324
+ 3. 单张时输出:`{"success": true/false, "folder_path": "/abs/path/to/images/YYYYMMDD", "file_path": "/abs/path/to/images/YYYYMMDD/a.jpg", "failed": []}`
325
+ 4. 多张时输出:`{"success": true/false, "folder_path": "/abs/path/to/images/YYYYMMDD", "uploaded": [...], "failed": [...]}`
326
+ 5. 成功后提示:`✅📤 **已放入待搜索目录** → <folder_path> ✨`;如果有失败文件,提示:`⚠️ 部分失败:` 并列出项。
327
+
328
+ ## Example Workflow
329
+
330
+ - 用户:「把这张照片添加为张三」
331
+ 1. `uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json check "张三"`
332
+ 2. 不存在 → `uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json add "张三" "/path/to/photo.jpg"`
333
+ 3. 提示:`🎉✨ **注册成功** · 张三`
334
+
335
+ - 用户:「用照片分类器在 /home/photos 下查找张三」
336
+ 1. `uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json check "张三"` → 存在
337
+ 2. 子会话执行 `uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json search "张三" "/home/photos"`
338
+ 3. 展示结果表格 → `pack --name "张三" --timeout 120` 生成下载链接(见 §6)→ 若有 `dm_lines`,展示下载链接私信状态
339
+
340
+ - 用户:「用这张照片在 /home/photos 里找找有没有类似的」
341
+ 1. 子会话执行 `uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json quick-search "/tmp/face.jpg" "/home/photos"`
342
+ 2. 成功 → 展示表格 → `pack --timeout 120`(不带 `--name`);失败 → 提示未检测到有效人脸
343
+
344
+ - 用户:「用照片分类器对 /home/album 进行分类」
345
+ 1. 子会话执行 `uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json classify "/home/album"`
346
+ 2. 展示各用户结果(及分类摘要 `dm_lines` 若有)→ `pack --timeout 120`(多用户各一链接,见 §6)→ 展示链接及 **`pack` 返回的 `dm_lines`**(下载链接私信状态)
347
+
348
+ - 用户:「删除照片分类器中李四的信息」
349
+ 1. `uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json check "李四"` → 存在
350
+ 2. 提示确认 → 用户确认 → `uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json delete "李四"`
351
+ 3. 提示:`🗑️✨ **用户已删除** · 李四`
352
+
353
+ - 用户:「把这些图片放到待搜索目录」
354
+ 1. `uv run {baseDir}/scripts/face_search.py -c {baseDir}/references/config.json upload-image "/tmp/a.jpg" "/tmp/b.jpg"`
355
+ 2. 全部成功后提示:`✅📤 **已放入待搜索目录** → <folder_path> ✨`
356
+
357
+ ## Notes
358
+
359
+ - 建议始终通过 `-c` 传入 `{baseDir}/references/config.json` 的绝对路径,避免相对路径导致找不到配置文件。
360
+ - `search`、`quick-search` 和 `classify` 可能耗时较长(取决于搜索目录中的图片数量),应在**子会话**中执行;**结束后立即关闭并删除该子会话**,再将结果展示与 `pack` 放在**主会话**中完成。
361
+ - `images/` 目录用于存放待搜索图片;`upload-image` 内部会创建当天目录并串行逐张处理图片。
362
+ - 搜索过程中会在图片所在目录下创建 `.embedding` 隐藏目录缓存 embedding 结果,后续搜索同一目录会自动跳过已处理的图片。
363
+ - `pack` 与 `copy` 均依赖 `config.json` 中保存的搜索结果(`search_result` 或 `quick_search_result` 等),须先执行 `search`、`classify` 或 `quick-search`。默认流程只需 **`pack`**;`copy` 为可选,由用户另行提出时再执行。
364
+ - **`classify`** 会向 `friendId` 发**分类结果摘要**;**`pack`** 会向 `friendId` 发**打包下载链接**(两次私信、用途不同);若只需其一,可后续再改脚本或配置(当前实现为两者都发)。
365
+ - `pack` 的压缩文件存放在系统临时目录中,上传完成后可忽略清理。上传超时默认 120 秒,文件特别大时可通过 `--timeout` 增大。
366
+ - `config.json` 中的 `query_threshold`(默认 0.7)控制人脸检测置信度阈值,`search_similarity_threshold`(默认 0.3)控制搜索匹配的最低相似度。
367
+ - `{baseDir}` 指本 skill 根目录(如 `skills/image-classify`),调用时替换为实际绝对路径。
368
+ - `friendId`(虾友号)与可选 `friendLabel` 写在用户条目下;**注册时**通过 `add ... --friend-id` / `--friend-label` 写入。后续若需修改可编辑 `config.json`(本 skill 未单独提供改绑子命令)。旧键名仍兼容读取。