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,318 +1,318 @@
1
- """Add comments to DOCX documents.
2
-
3
- Usage:
4
- python comment.py unpacked/ 0 "Comment text"
5
- python comment.py unpacked/ 1 "Reply text" --parent 0
6
-
7
- Text should be pre-escaped XML (e.g., & for &, ’ for smart quotes).
8
-
9
- After running, add markers to document.xml:
10
- <w:commentRangeStart w:id="0"/>
11
- ... commented content ...
12
- <w:commentRangeEnd w:id="0"/>
13
- <w:r><w:rPr><w:rStyle w:val="CommentReference"/></w:rPr><w:commentReference w:id="0"/></w:r>
14
- """
15
-
16
- import argparse
17
- import random
18
- import shutil
19
- import sys
20
- from datetime import datetime, timezone
21
- from pathlib import Path
22
-
23
- import defusedxml.minidom
24
-
25
- TEMPLATE_DIR = Path(__file__).parent / "templates"
26
- NS = {
27
- "w": "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
28
- "w14": "http://schemas.microsoft.com/office/word/2010/wordml",
29
- "w15": "http://schemas.microsoft.com/office/word/2012/wordml",
30
- "w16cid": "http://schemas.microsoft.com/office/word/2016/wordml/cid",
31
- "w16cex": "http://schemas.microsoft.com/office/word/2018/wordml/cex",
32
- }
33
-
34
- COMMENT_XML = """\
35
- <w:comment w:id="{id}" w:author="{author}" w:date="{date}" w:initials="{initials}">
36
- <w:p w14:paraId="{para_id}" w14:textId="77777777">
37
- <w:r>
38
- <w:rPr><w:rStyle w:val="CommentReference"/></w:rPr>
39
- <w:annotationRef/>
40
- </w:r>
41
- <w:r>
42
- <w:rPr>
43
- <w:color w:val="000000"/>
44
- <w:sz w:val="20"/>
45
- <w:szCs w:val="20"/>
46
- </w:rPr>
47
- <w:t>{text}</w:t>
48
- </w:r>
49
- </w:p>
50
- </w:comment>"""
51
-
52
- COMMENT_MARKER_TEMPLATE = """
53
- Add to document.xml (markers must be direct children of w:p, never inside w:r):
54
- <w:commentRangeStart w:id="{cid}"/>
55
- <w:r>...</w:r>
56
- <w:commentRangeEnd w:id="{cid}"/>
57
- <w:r><w:rPr><w:rStyle w:val="CommentReference"/></w:rPr><w:commentReference w:id="{cid}"/></w:r>"""
58
-
59
- REPLY_MARKER_TEMPLATE = """
60
- Nest markers inside parent {pid}'s markers (markers must be direct children of w:p, never inside w:r):
61
- <w:commentRangeStart w:id="{pid}"/><w:commentRangeStart w:id="{cid}"/>
62
- <w:r>...</w:r>
63
- <w:commentRangeEnd w:id="{cid}"/><w:commentRangeEnd w:id="{pid}"/>
64
- <w:r><w:rPr><w:rStyle w:val="CommentReference"/></w:rPr><w:commentReference w:id="{pid}"/></w:r>
65
- <w:r><w:rPr><w:rStyle w:val="CommentReference"/></w:rPr><w:commentReference w:id="{cid}"/></w:r>"""
66
-
67
-
68
- def _generate_hex_id() -> str:
69
- return f"{random.randint(0, 0x7FFFFFFE):08X}"
70
-
71
-
72
- SMART_QUOTE_ENTITIES = {
73
- "\u201c": "&#x201C;",
74
- "\u201d": "&#x201D;",
75
- "\u2018": "&#x2018;",
76
- "\u2019": "&#x2019;",
77
- }
78
-
79
-
80
- def _encode_smart_quotes(text: str) -> str:
81
- for char, entity in SMART_QUOTE_ENTITIES.items():
82
- text = text.replace(char, entity)
83
- return text
84
-
85
-
86
- def _append_xml(xml_path: Path, root_tag: str, content: str) -> None:
87
- dom = defusedxml.minidom.parseString(xml_path.read_text(encoding="utf-8"))
88
- root = dom.getElementsByTagName(root_tag)[0]
89
- ns_attrs = " ".join(f'xmlns:{k}="{v}"' for k, v in NS.items())
90
- wrapper_dom = defusedxml.minidom.parseString(f"<root {ns_attrs}>{content}</root>")
91
- for child in wrapper_dom.documentElement.childNodes:
92
- if child.nodeType == child.ELEMENT_NODE:
93
- root.appendChild(dom.importNode(child, True))
94
- output = _encode_smart_quotes(dom.toxml(encoding="UTF-8").decode("utf-8"))
95
- xml_path.write_text(output, encoding="utf-8")
96
-
97
-
98
- def _find_para_id(comments_path: Path, comment_id: int) -> str | None:
99
- dom = defusedxml.minidom.parseString(comments_path.read_text(encoding="utf-8"))
100
- for c in dom.getElementsByTagName("w:comment"):
101
- if c.getAttribute("w:id") == str(comment_id):
102
- for p in c.getElementsByTagName("w:p"):
103
- if pid := p.getAttribute("w14:paraId"):
104
- return pid
105
- return None
106
-
107
-
108
- def _get_next_rid(rels_path: Path) -> int:
109
- dom = defusedxml.minidom.parseString(rels_path.read_text(encoding="utf-8"))
110
- max_rid = 0
111
- for rel in dom.getElementsByTagName("Relationship"):
112
- rid = rel.getAttribute("Id")
113
- if rid and rid.startswith("rId"):
114
- try:
115
- max_rid = max(max_rid, int(rid[3:]))
116
- except ValueError:
117
- pass
118
- return max_rid + 1
119
-
120
-
121
- def _has_relationship(rels_path: Path, target: str) -> bool:
122
- dom = defusedxml.minidom.parseString(rels_path.read_text(encoding="utf-8"))
123
- for rel in dom.getElementsByTagName("Relationship"):
124
- if rel.getAttribute("Target") == target:
125
- return True
126
- return False
127
-
128
-
129
- def _has_content_type(ct_path: Path, part_name: str) -> bool:
130
- dom = defusedxml.minidom.parseString(ct_path.read_text(encoding="utf-8"))
131
- for override in dom.getElementsByTagName("Override"):
132
- if override.getAttribute("PartName") == part_name:
133
- return True
134
- return False
135
-
136
-
137
- def _ensure_comment_relationships(unpacked_dir: Path) -> None:
138
- rels_path = unpacked_dir / "word" / "_rels" / "document.xml.rels"
139
- if not rels_path.exists():
140
- return
141
-
142
- if _has_relationship(rels_path, "comments.xml"):
143
- return
144
-
145
- dom = defusedxml.minidom.parseString(rels_path.read_text(encoding="utf-8"))
146
- root = dom.documentElement
147
- next_rid = _get_next_rid(rels_path)
148
-
149
- rels = [
150
- (
151
- "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments",
152
- "comments.xml",
153
- ),
154
- (
155
- "http://schemas.microsoft.com/office/2011/relationships/commentsExtended",
156
- "commentsExtended.xml",
157
- ),
158
- (
159
- "http://schemas.microsoft.com/office/2016/09/relationships/commentsIds",
160
- "commentsIds.xml",
161
- ),
162
- (
163
- "http://schemas.microsoft.com/office/2018/08/relationships/commentsExtensible",
164
- "commentsExtensible.xml",
165
- ),
166
- ]
167
-
168
- for rel_type, target in rels:
169
- rel = dom.createElement("Relationship")
170
- rel.setAttribute("Id", f"rId{next_rid}")
171
- rel.setAttribute("Type", rel_type)
172
- rel.setAttribute("Target", target)
173
- root.appendChild(rel)
174
- next_rid += 1
175
-
176
- rels_path.write_bytes(dom.toxml(encoding="UTF-8"))
177
-
178
-
179
- def _ensure_comment_content_types(unpacked_dir: Path) -> None:
180
- ct_path = unpacked_dir / "[Content_Types].xml"
181
- if not ct_path.exists():
182
- return
183
-
184
- if _has_content_type(ct_path, "/word/comments.xml"):
185
- return
186
-
187
- dom = defusedxml.minidom.parseString(ct_path.read_text(encoding="utf-8"))
188
- root = dom.documentElement
189
-
190
- overrides = [
191
- (
192
- "/word/comments.xml",
193
- "application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml",
194
- ),
195
- (
196
- "/word/commentsExtended.xml",
197
- "application/vnd.openxmlformats-officedocument.wordprocessingml.commentsExtended+xml",
198
- ),
199
- (
200
- "/word/commentsIds.xml",
201
- "application/vnd.openxmlformats-officedocument.wordprocessingml.commentsIds+xml",
202
- ),
203
- (
204
- "/word/commentsExtensible.xml",
205
- "application/vnd.openxmlformats-officedocument.wordprocessingml.commentsExtensible+xml",
206
- ),
207
- ]
208
-
209
- for part_name, content_type in overrides:
210
- override = dom.createElement("Override")
211
- override.setAttribute("PartName", part_name)
212
- override.setAttribute("ContentType", content_type)
213
- root.appendChild(override)
214
-
215
- ct_path.write_bytes(dom.toxml(encoding="UTF-8"))
216
-
217
-
218
- def add_comment(
219
- unpacked_dir: str,
220
- comment_id: int,
221
- text: str,
222
- author: str = "Claude",
223
- initials: str = "C",
224
- parent_id: int | None = None,
225
- ) -> tuple[str, str]:
226
- word = Path(unpacked_dir) / "word"
227
- if not word.exists():
228
- return "", f"Error: {word} not found"
229
-
230
- para_id, durable_id = _generate_hex_id(), _generate_hex_id()
231
- ts = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
232
-
233
- comments = word / "comments.xml"
234
- first_comment = not comments.exists()
235
- if first_comment:
236
- shutil.copy(TEMPLATE_DIR / "comments.xml", comments)
237
- _ensure_comment_relationships(Path(unpacked_dir))
238
- _ensure_comment_content_types(Path(unpacked_dir))
239
- _append_xml(
240
- comments,
241
- "w:comments",
242
- COMMENT_XML.format(
243
- id=comment_id,
244
- author=author,
245
- date=ts,
246
- initials=initials,
247
- para_id=para_id,
248
- text=text,
249
- ),
250
- )
251
-
252
- ext = word / "commentsExtended.xml"
253
- if not ext.exists():
254
- shutil.copy(TEMPLATE_DIR / "commentsExtended.xml", ext)
255
- if parent_id is not None:
256
- parent_para = _find_para_id(comments, parent_id)
257
- if not parent_para:
258
- return "", f"Error: Parent comment {parent_id} not found"
259
- _append_xml(
260
- ext,
261
- "w15:commentsEx",
262
- f'<w15:commentEx w15:paraId="{para_id}" w15:paraIdParent="{parent_para}" w15:done="0"/>',
263
- )
264
- else:
265
- _append_xml(
266
- ext,
267
- "w15:commentsEx",
268
- f'<w15:commentEx w15:paraId="{para_id}" w15:done="0"/>',
269
- )
270
-
271
- ids = word / "commentsIds.xml"
272
- if not ids.exists():
273
- shutil.copy(TEMPLATE_DIR / "commentsIds.xml", ids)
274
- _append_xml(
275
- ids,
276
- "w16cid:commentsIds",
277
- f'<w16cid:commentId w16cid:paraId="{para_id}" w16cid:durableId="{durable_id}"/>',
278
- )
279
-
280
- extensible = word / "commentsExtensible.xml"
281
- if not extensible.exists():
282
- shutil.copy(TEMPLATE_DIR / "commentsExtensible.xml", extensible)
283
- _append_xml(
284
- extensible,
285
- "w16cex:commentsExtensible",
286
- f'<w16cex:commentExtensible w16cex:durableId="{durable_id}" w16cex:dateUtc="{ts}"/>',
287
- )
288
-
289
- action = "reply" if parent_id is not None else "comment"
290
- return para_id, f"Added {action} {comment_id} (para_id={para_id})"
291
-
292
-
293
- if __name__ == "__main__":
294
- p = argparse.ArgumentParser(description="Add comments to DOCX documents")
295
- p.add_argument("unpacked_dir", help="Unpacked DOCX directory")
296
- p.add_argument("comment_id", type=int, help="Comment ID (must be unique)")
297
- p.add_argument("text", help="Comment text")
298
- p.add_argument("--author", default="Claude", help="Author name")
299
- p.add_argument("--initials", default="C", help="Author initials")
300
- p.add_argument("--parent", type=int, help="Parent comment ID (for replies)")
301
- args = p.parse_args()
302
-
303
- para_id, msg = add_comment(
304
- args.unpacked_dir,
305
- args.comment_id,
306
- args.text,
307
- args.author,
308
- args.initials,
309
- args.parent,
310
- )
311
- print(msg)
312
- if "Error" in msg:
313
- sys.exit(1)
314
- cid = args.comment_id
315
- if args.parent is not None:
316
- print(REPLY_MARKER_TEMPLATE.format(pid=args.parent, cid=cid))
317
- else:
318
- print(COMMENT_MARKER_TEMPLATE.format(cid=cid))
1
+ """Add comments to DOCX documents.
2
+
3
+ Usage:
4
+ python comment.py unpacked/ 0 "Comment text"
5
+ python comment.py unpacked/ 1 "Reply text" --parent 0
6
+
7
+ Text should be pre-escaped XML (e.g., &amp; for &, &#x2019; for smart quotes).
8
+
9
+ After running, add markers to document.xml:
10
+ <w:commentRangeStart w:id="0"/>
11
+ ... commented content ...
12
+ <w:commentRangeEnd w:id="0"/>
13
+ <w:r><w:rPr><w:rStyle w:val="CommentReference"/></w:rPr><w:commentReference w:id="0"/></w:r>
14
+ """
15
+
16
+ import argparse
17
+ import random
18
+ import shutil
19
+ import sys
20
+ from datetime import datetime, timezone
21
+ from pathlib import Path
22
+
23
+ import defusedxml.minidom
24
+
25
+ TEMPLATE_DIR = Path(__file__).parent / "templates"
26
+ NS = {
27
+ "w": "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
28
+ "w14": "http://schemas.microsoft.com/office/word/2010/wordml",
29
+ "w15": "http://schemas.microsoft.com/office/word/2012/wordml",
30
+ "w16cid": "http://schemas.microsoft.com/office/word/2016/wordml/cid",
31
+ "w16cex": "http://schemas.microsoft.com/office/word/2018/wordml/cex",
32
+ }
33
+
34
+ COMMENT_XML = """\
35
+ <w:comment w:id="{id}" w:author="{author}" w:date="{date}" w:initials="{initials}">
36
+ <w:p w14:paraId="{para_id}" w14:textId="77777777">
37
+ <w:r>
38
+ <w:rPr><w:rStyle w:val="CommentReference"/></w:rPr>
39
+ <w:annotationRef/>
40
+ </w:r>
41
+ <w:r>
42
+ <w:rPr>
43
+ <w:color w:val="000000"/>
44
+ <w:sz w:val="20"/>
45
+ <w:szCs w:val="20"/>
46
+ </w:rPr>
47
+ <w:t>{text}</w:t>
48
+ </w:r>
49
+ </w:p>
50
+ </w:comment>"""
51
+
52
+ COMMENT_MARKER_TEMPLATE = """
53
+ Add to document.xml (markers must be direct children of w:p, never inside w:r):
54
+ <w:commentRangeStart w:id="{cid}"/>
55
+ <w:r>...</w:r>
56
+ <w:commentRangeEnd w:id="{cid}"/>
57
+ <w:r><w:rPr><w:rStyle w:val="CommentReference"/></w:rPr><w:commentReference w:id="{cid}"/></w:r>"""
58
+
59
+ REPLY_MARKER_TEMPLATE = """
60
+ Nest markers inside parent {pid}'s markers (markers must be direct children of w:p, never inside w:r):
61
+ <w:commentRangeStart w:id="{pid}"/><w:commentRangeStart w:id="{cid}"/>
62
+ <w:r>...</w:r>
63
+ <w:commentRangeEnd w:id="{cid}"/><w:commentRangeEnd w:id="{pid}"/>
64
+ <w:r><w:rPr><w:rStyle w:val="CommentReference"/></w:rPr><w:commentReference w:id="{pid}"/></w:r>
65
+ <w:r><w:rPr><w:rStyle w:val="CommentReference"/></w:rPr><w:commentReference w:id="{cid}"/></w:r>"""
66
+
67
+
68
+ def _generate_hex_id() -> str:
69
+ return f"{random.randint(0, 0x7FFFFFFE):08X}"
70
+
71
+
72
+ SMART_QUOTE_ENTITIES = {
73
+ "\u201c": "&#x201C;",
74
+ "\u201d": "&#x201D;",
75
+ "\u2018": "&#x2018;",
76
+ "\u2019": "&#x2019;",
77
+ }
78
+
79
+
80
+ def _encode_smart_quotes(text: str) -> str:
81
+ for char, entity in SMART_QUOTE_ENTITIES.items():
82
+ text = text.replace(char, entity)
83
+ return text
84
+
85
+
86
+ def _append_xml(xml_path: Path, root_tag: str, content: str) -> None:
87
+ dom = defusedxml.minidom.parseString(xml_path.read_text(encoding="utf-8"))
88
+ root = dom.getElementsByTagName(root_tag)[0]
89
+ ns_attrs = " ".join(f'xmlns:{k}="{v}"' for k, v in NS.items())
90
+ wrapper_dom = defusedxml.minidom.parseString(f"<root {ns_attrs}>{content}</root>")
91
+ for child in wrapper_dom.documentElement.childNodes:
92
+ if child.nodeType == child.ELEMENT_NODE:
93
+ root.appendChild(dom.importNode(child, True))
94
+ output = _encode_smart_quotes(dom.toxml(encoding="UTF-8").decode("utf-8"))
95
+ xml_path.write_text(output, encoding="utf-8")
96
+
97
+
98
+ def _find_para_id(comments_path: Path, comment_id: int) -> str | None:
99
+ dom = defusedxml.minidom.parseString(comments_path.read_text(encoding="utf-8"))
100
+ for c in dom.getElementsByTagName("w:comment"):
101
+ if c.getAttribute("w:id") == str(comment_id):
102
+ for p in c.getElementsByTagName("w:p"):
103
+ if pid := p.getAttribute("w14:paraId"):
104
+ return pid
105
+ return None
106
+
107
+
108
+ def _get_next_rid(rels_path: Path) -> int:
109
+ dom = defusedxml.minidom.parseString(rels_path.read_text(encoding="utf-8"))
110
+ max_rid = 0
111
+ for rel in dom.getElementsByTagName("Relationship"):
112
+ rid = rel.getAttribute("Id")
113
+ if rid and rid.startswith("rId"):
114
+ try:
115
+ max_rid = max(max_rid, int(rid[3:]))
116
+ except ValueError:
117
+ pass
118
+ return max_rid + 1
119
+
120
+
121
+ def _has_relationship(rels_path: Path, target: str) -> bool:
122
+ dom = defusedxml.minidom.parseString(rels_path.read_text(encoding="utf-8"))
123
+ for rel in dom.getElementsByTagName("Relationship"):
124
+ if rel.getAttribute("Target") == target:
125
+ return True
126
+ return False
127
+
128
+
129
+ def _has_content_type(ct_path: Path, part_name: str) -> bool:
130
+ dom = defusedxml.minidom.parseString(ct_path.read_text(encoding="utf-8"))
131
+ for override in dom.getElementsByTagName("Override"):
132
+ if override.getAttribute("PartName") == part_name:
133
+ return True
134
+ return False
135
+
136
+
137
+ def _ensure_comment_relationships(unpacked_dir: Path) -> None:
138
+ rels_path = unpacked_dir / "word" / "_rels" / "document.xml.rels"
139
+ if not rels_path.exists():
140
+ return
141
+
142
+ if _has_relationship(rels_path, "comments.xml"):
143
+ return
144
+
145
+ dom = defusedxml.minidom.parseString(rels_path.read_text(encoding="utf-8"))
146
+ root = dom.documentElement
147
+ next_rid = _get_next_rid(rels_path)
148
+
149
+ rels = [
150
+ (
151
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments",
152
+ "comments.xml",
153
+ ),
154
+ (
155
+ "http://schemas.microsoft.com/office/2011/relationships/commentsExtended",
156
+ "commentsExtended.xml",
157
+ ),
158
+ (
159
+ "http://schemas.microsoft.com/office/2016/09/relationships/commentsIds",
160
+ "commentsIds.xml",
161
+ ),
162
+ (
163
+ "http://schemas.microsoft.com/office/2018/08/relationships/commentsExtensible",
164
+ "commentsExtensible.xml",
165
+ ),
166
+ ]
167
+
168
+ for rel_type, target in rels:
169
+ rel = dom.createElement("Relationship")
170
+ rel.setAttribute("Id", f"rId{next_rid}")
171
+ rel.setAttribute("Type", rel_type)
172
+ rel.setAttribute("Target", target)
173
+ root.appendChild(rel)
174
+ next_rid += 1
175
+
176
+ rels_path.write_bytes(dom.toxml(encoding="UTF-8"))
177
+
178
+
179
+ def _ensure_comment_content_types(unpacked_dir: Path) -> None:
180
+ ct_path = unpacked_dir / "[Content_Types].xml"
181
+ if not ct_path.exists():
182
+ return
183
+
184
+ if _has_content_type(ct_path, "/word/comments.xml"):
185
+ return
186
+
187
+ dom = defusedxml.minidom.parseString(ct_path.read_text(encoding="utf-8"))
188
+ root = dom.documentElement
189
+
190
+ overrides = [
191
+ (
192
+ "/word/comments.xml",
193
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml",
194
+ ),
195
+ (
196
+ "/word/commentsExtended.xml",
197
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.commentsExtended+xml",
198
+ ),
199
+ (
200
+ "/word/commentsIds.xml",
201
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.commentsIds+xml",
202
+ ),
203
+ (
204
+ "/word/commentsExtensible.xml",
205
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.commentsExtensible+xml",
206
+ ),
207
+ ]
208
+
209
+ for part_name, content_type in overrides:
210
+ override = dom.createElement("Override")
211
+ override.setAttribute("PartName", part_name)
212
+ override.setAttribute("ContentType", content_type)
213
+ root.appendChild(override)
214
+
215
+ ct_path.write_bytes(dom.toxml(encoding="UTF-8"))
216
+
217
+
218
+ def add_comment(
219
+ unpacked_dir: str,
220
+ comment_id: int,
221
+ text: str,
222
+ author: str = "Claude",
223
+ initials: str = "C",
224
+ parent_id: int | None = None,
225
+ ) -> tuple[str, str]:
226
+ word = Path(unpacked_dir) / "word"
227
+ if not word.exists():
228
+ return "", f"Error: {word} not found"
229
+
230
+ para_id, durable_id = _generate_hex_id(), _generate_hex_id()
231
+ ts = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
232
+
233
+ comments = word / "comments.xml"
234
+ first_comment = not comments.exists()
235
+ if first_comment:
236
+ shutil.copy(TEMPLATE_DIR / "comments.xml", comments)
237
+ _ensure_comment_relationships(Path(unpacked_dir))
238
+ _ensure_comment_content_types(Path(unpacked_dir))
239
+ _append_xml(
240
+ comments,
241
+ "w:comments",
242
+ COMMENT_XML.format(
243
+ id=comment_id,
244
+ author=author,
245
+ date=ts,
246
+ initials=initials,
247
+ para_id=para_id,
248
+ text=text,
249
+ ),
250
+ )
251
+
252
+ ext = word / "commentsExtended.xml"
253
+ if not ext.exists():
254
+ shutil.copy(TEMPLATE_DIR / "commentsExtended.xml", ext)
255
+ if parent_id is not None:
256
+ parent_para = _find_para_id(comments, parent_id)
257
+ if not parent_para:
258
+ return "", f"Error: Parent comment {parent_id} not found"
259
+ _append_xml(
260
+ ext,
261
+ "w15:commentsEx",
262
+ f'<w15:commentEx w15:paraId="{para_id}" w15:paraIdParent="{parent_para}" w15:done="0"/>',
263
+ )
264
+ else:
265
+ _append_xml(
266
+ ext,
267
+ "w15:commentsEx",
268
+ f'<w15:commentEx w15:paraId="{para_id}" w15:done="0"/>',
269
+ )
270
+
271
+ ids = word / "commentsIds.xml"
272
+ if not ids.exists():
273
+ shutil.copy(TEMPLATE_DIR / "commentsIds.xml", ids)
274
+ _append_xml(
275
+ ids,
276
+ "w16cid:commentsIds",
277
+ f'<w16cid:commentId w16cid:paraId="{para_id}" w16cid:durableId="{durable_id}"/>',
278
+ )
279
+
280
+ extensible = word / "commentsExtensible.xml"
281
+ if not extensible.exists():
282
+ shutil.copy(TEMPLATE_DIR / "commentsExtensible.xml", extensible)
283
+ _append_xml(
284
+ extensible,
285
+ "w16cex:commentsExtensible",
286
+ f'<w16cex:commentExtensible w16cex:durableId="{durable_id}" w16cex:dateUtc="{ts}"/>',
287
+ )
288
+
289
+ action = "reply" if parent_id is not None else "comment"
290
+ return para_id, f"Added {action} {comment_id} (para_id={para_id})"
291
+
292
+
293
+ if __name__ == "__main__":
294
+ p = argparse.ArgumentParser(description="Add comments to DOCX documents")
295
+ p.add_argument("unpacked_dir", help="Unpacked DOCX directory")
296
+ p.add_argument("comment_id", type=int, help="Comment ID (must be unique)")
297
+ p.add_argument("text", help="Comment text")
298
+ p.add_argument("--author", default="Claude", help="Author name")
299
+ p.add_argument("--initials", default="C", help="Author initials")
300
+ p.add_argument("--parent", type=int, help="Parent comment ID (for replies)")
301
+ args = p.parse_args()
302
+
303
+ para_id, msg = add_comment(
304
+ args.unpacked_dir,
305
+ args.comment_id,
306
+ args.text,
307
+ args.author,
308
+ args.initials,
309
+ args.parent,
310
+ )
311
+ print(msg)
312
+ if "Error" in msg:
313
+ sys.exit(1)
314
+ cid = args.comment_id
315
+ if args.parent is not None:
316
+ print(REPLY_MARKER_TEMPLATE.format(pid=args.parent, cid=cid))
317
+ else:
318
+ print(COMMENT_MARKER_TEMPLATE.format(cid=cid))