@xagent-ai/cli 1.2.2 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (568) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +38 -38
  2. package/.github/ISSUE_TEMPLATE/feature_request.md +20 -20
  3. package/.github/workflows/ci.yml +72 -0
  4. package/.github/workflows/release.yml +109 -0
  5. package/.gitmodules +3 -3
  6. package/README.md +326 -280
  7. package/README_CN.md +325 -279
  8. package/dist/ai-client/factory.d.ts +52 -0
  9. package/dist/ai-client/factory.d.ts.map +1 -0
  10. package/dist/ai-client/factory.js +132 -0
  11. package/dist/ai-client/factory.js.map +1 -0
  12. package/dist/ai-client/index.d.ts +20 -0
  13. package/dist/ai-client/index.d.ts.map +1 -0
  14. package/dist/ai-client/index.js +49 -0
  15. package/dist/ai-client/index.js.map +1 -0
  16. package/dist/ai-client/providers/anthropic.d.ts +57 -0
  17. package/dist/ai-client/providers/anthropic.d.ts.map +1 -0
  18. package/dist/ai-client/providers/anthropic.js +400 -0
  19. package/dist/ai-client/providers/anthropic.js.map +1 -0
  20. package/dist/ai-client/providers/openai.d.ts +57 -0
  21. package/dist/ai-client/providers/openai.d.ts.map +1 -0
  22. package/dist/ai-client/providers/openai.js +286 -0
  23. package/dist/ai-client/providers/openai.js.map +1 -0
  24. package/dist/ai-client/providers/remote.d.ts +111 -0
  25. package/dist/ai-client/providers/remote.d.ts.map +1 -0
  26. package/dist/ai-client/providers/remote.js +351 -0
  27. package/dist/ai-client/providers/remote.js.map +1 -0
  28. package/dist/ai-client/registry.d.ts +51 -0
  29. package/dist/ai-client/registry.d.ts.map +1 -0
  30. package/dist/ai-client/registry.js +81 -0
  31. package/dist/ai-client/registry.js.map +1 -0
  32. package/dist/ai-client/types.d.ts +260 -0
  33. package/dist/ai-client/types.d.ts.map +1 -0
  34. package/dist/ai-client/types.js +73 -0
  35. package/dist/ai-client/types.js.map +1 -0
  36. package/dist/ai-client-factory.d.ts +62 -0
  37. package/dist/ai-client-factory.d.ts.map +1 -0
  38. package/dist/ai-client-factory.js +157 -0
  39. package/dist/ai-client-factory.js.map +1 -0
  40. package/dist/auth.d.ts +23 -1
  41. package/dist/auth.d.ts.map +1 -1
  42. package/dist/auth.js +160 -168
  43. package/dist/auth.js.map +1 -1
  44. package/dist/cancellation.d.ts +5 -4
  45. package/dist/cancellation.d.ts.map +1 -1
  46. package/dist/cancellation.js +55 -32
  47. package/dist/cancellation.js.map +1 -1
  48. package/dist/checkpoint.d.ts +1 -1
  49. package/dist/checkpoint.d.ts.map +1 -1
  50. package/dist/checkpoint.js +2 -2
  51. package/dist/checkpoint.js.map +1 -1
  52. package/dist/cli.js +626 -13
  53. package/dist/cli.js.map +1 -1
  54. package/dist/config.d.ts +10 -4
  55. package/dist/config.d.ts.map +1 -1
  56. package/dist/config.js +62 -25
  57. package/dist/config.js.map +1 -1
  58. package/dist/context-compressor.d.ts +81 -16
  59. package/dist/context-compressor.d.ts.map +1 -1
  60. package/dist/context-compressor.js +712 -153
  61. package/dist/context-compressor.js.map +1 -1
  62. package/dist/gui-subagent/action-parser/actionParser.d.ts.map +1 -1
  63. package/dist/gui-subagent/action-parser/actionParser.js +4 -2
  64. package/dist/gui-subagent/action-parser/actionParser.js.map +1 -1
  65. package/dist/gui-subagent/agent/gui-agent.d.ts +29 -2
  66. package/dist/gui-subagent/agent/gui-agent.d.ts.map +1 -1
  67. package/dist/gui-subagent/agent/gui-agent.js +87 -45
  68. package/dist/gui-subagent/agent/gui-agent.js.map +1 -1
  69. package/dist/gui-subagent/index.d.ts +16 -1
  70. package/dist/gui-subagent/index.d.ts.map +1 -1
  71. package/dist/gui-subagent/index.js +4 -0
  72. package/dist/gui-subagent/index.js.map +1 -1
  73. package/dist/gui-subagent/operator/base-operator.d.ts.map +1 -1
  74. package/dist/gui-subagent/operator/base-operator.js +0 -1
  75. package/dist/gui-subagent/operator/base-operator.js.map +1 -1
  76. package/dist/gui-subagent/operator/computer-operator.d.ts.map +1 -1
  77. package/dist/gui-subagent/operator/computer-operator.js +29 -8
  78. package/dist/gui-subagent/operator/computer-operator.js.map +1 -1
  79. package/dist/gui-subagent/types/actions.d.ts +1 -1
  80. package/dist/gui-subagent/types/actions.d.ts.map +1 -1
  81. package/dist/gui-subagent/types/actions.js +0 -1
  82. package/dist/gui-subagent/types/actions.js.map +1 -1
  83. package/dist/gui-subagent/types/operator.d.ts +1 -1
  84. package/dist/gui-subagent/types/operator.d.ts.map +1 -1
  85. package/dist/index.d.ts +1 -2
  86. package/dist/index.d.ts.map +1 -1
  87. package/dist/index.js +1 -2
  88. package/dist/index.js.map +1 -1
  89. package/dist/input-processor.d.ts.map +1 -1
  90. package/dist/input-processor.js +6 -3
  91. package/dist/input-processor.js.map +1 -1
  92. package/dist/mcp.d.ts +5 -0
  93. package/dist/mcp.d.ts.map +1 -1
  94. package/dist/mcp.js +81 -35
  95. package/dist/mcp.js.map +1 -1
  96. package/dist/ripgrep.d.ts +29 -0
  97. package/dist/ripgrep.d.ts.map +1 -0
  98. package/dist/ripgrep.js +292 -0
  99. package/dist/ripgrep.js.map +1 -0
  100. package/dist/session.d.ts +23 -7
  101. package/dist/session.d.ts.map +1 -1
  102. package/dist/session.js +624 -243
  103. package/dist/session.js.map +1 -1
  104. package/dist/shell.d.ts +33 -0
  105. package/dist/shell.d.ts.map +1 -0
  106. package/dist/shell.js +125 -0
  107. package/dist/shell.js.map +1 -0
  108. package/dist/skill-installer.d.ts +38 -0
  109. package/dist/skill-installer.d.ts.map +1 -0
  110. package/dist/skill-installer.js +447 -0
  111. package/dist/skill-installer.js.map +1 -0
  112. package/dist/skill-invoker.d.ts +7 -1
  113. package/dist/skill-invoker.d.ts.map +1 -1
  114. package/dist/skill-invoker.js +34 -13
  115. package/dist/skill-invoker.js.map +1 -1
  116. package/dist/skill-loader.d.ts +8 -3
  117. package/dist/skill-loader.d.ts.map +1 -1
  118. package/dist/skill-loader.js +46 -44
  119. package/dist/skill-loader.js.map +1 -1
  120. package/dist/skill-manager.d.ts +85 -0
  121. package/dist/skill-manager.d.ts.map +1 -0
  122. package/dist/skill-manager.js +340 -0
  123. package/dist/skill-manager.js.map +1 -0
  124. package/dist/slash-commands.d.ts +38 -1
  125. package/dist/slash-commands.d.ts.map +1 -1
  126. package/dist/slash-commands.js +912 -296
  127. package/dist/slash-commands.js.map +1 -1
  128. package/dist/smart-approval.d.ts.map +1 -1
  129. package/dist/smart-approval.js +67 -55
  130. package/dist/smart-approval.js.map +1 -1
  131. package/dist/system-prompt-generator.d.ts +6 -0
  132. package/dist/system-prompt-generator.d.ts.map +1 -1
  133. package/dist/system-prompt-generator.js +84 -34
  134. package/dist/system-prompt-generator.js.map +1 -1
  135. package/dist/terminal.d.ts +28 -0
  136. package/dist/terminal.d.ts.map +1 -0
  137. package/dist/terminal.js +82 -0
  138. package/dist/terminal.js.map +1 -0
  139. package/dist/tools.d.ts +23 -7
  140. package/dist/tools.d.ts.map +1 -1
  141. package/dist/tools.js +797 -437
  142. package/dist/tools.js.map +1 -1
  143. package/dist/truncate.d.ts +55 -0
  144. package/dist/truncate.d.ts.map +1 -0
  145. package/dist/truncate.js +130 -0
  146. package/dist/truncate.js.map +1 -0
  147. package/dist/types.d.ts +27 -9
  148. package/dist/types.d.ts.map +1 -1
  149. package/dist/update.d.ts.map +1 -1
  150. package/dist/update.js +17 -28
  151. package/dist/update.js.map +1 -1
  152. package/dist/workflow.d.ts +5 -1
  153. package/dist/workflow.d.ts.map +1 -1
  154. package/dist/workflow.js +60 -47
  155. package/dist/workflow.js.map +1 -1
  156. package/docs/architecture/mcp-integration-guide.md +304 -194
  157. package/docs/architecture/overview.md +169 -169
  158. package/docs/architecture/tool-system-design.md +134 -134
  159. package/docs/cli/commands.md +349 -238
  160. package/docs/smart-mode.md +281 -281
  161. package/docs/third-party-models.md +439 -439
  162. package/find-skills/SKILL.md +133 -0
  163. package/package.json +89 -90
  164. package/scripts/install-ripgrep.js +241 -0
  165. package/src/ai-client/factory.ts +151 -0
  166. package/src/ai-client/index.ts +61 -0
  167. package/src/ai-client/providers/anthropic.ts +466 -0
  168. package/src/ai-client/providers/openai.ts +342 -0
  169. package/src/ai-client/providers/remote.ts +436 -0
  170. package/src/ai-client/registry.ts +97 -0
  171. package/src/ai-client/types.ts +345 -0
  172. package/src/ai-client-factory.ts +204 -0
  173. package/src/auth.ts +663 -614
  174. package/src/cancellation.ts +205 -176
  175. package/src/checkpoint.ts +219 -219
  176. package/src/cli.ts +1406 -743
  177. package/src/config.ts +341 -297
  178. package/src/context-compressor.ts +982 -290
  179. package/src/conversation.ts +288 -288
  180. package/src/gui-subagent/action-parser/actionParser.ts +318 -315
  181. package/src/gui-subagent/action-parser/constants.ts +14 -14
  182. package/src/gui-subagent/action-parser/index.ts +8 -8
  183. package/src/gui-subagent/action-parser/types.ts +31 -31
  184. package/src/gui-subagent/agent/gui-agent.ts +1151 -1089
  185. package/src/gui-subagent/agent/index.ts +5 -5
  186. package/src/gui-subagent/index.ts +177 -163
  187. package/src/gui-subagent/operator/base-operator.ts +244 -245
  188. package/src/gui-subagent/operator/computer-operator.ts +540 -520
  189. package/src/gui-subagent/operator/index.ts +6 -6
  190. package/src/gui-subagent/types/actions.ts +260 -262
  191. package/src/gui-subagent/types/index.ts +6 -6
  192. package/src/gui-subagent/types/operator.ts +106 -106
  193. package/src/gui-subagent/utils.ts +51 -51
  194. package/src/index.ts +17 -18
  195. package/src/input-processor.ts +6 -3
  196. package/src/logger.ts +438 -438
  197. package/src/mcp.ts +730 -682
  198. package/src/memory.ts +344 -344
  199. package/src/ripgrep.ts +368 -0
  200. package/src/session-manager.ts +308 -308
  201. package/src/session.ts +948 -386
  202. package/src/shell.ts +133 -0
  203. package/src/skill-installer.ts +518 -0
  204. package/src/skill-invoker.ts +960 -935
  205. package/src/skill-loader.ts +501 -496
  206. package/src/skill-manager.ts +384 -0
  207. package/src/slash-commands.ts +2181 -1389
  208. package/src/smart-approval.ts +117 -73
  209. package/src/system-prompt-generator.ts +89 -34
  210. package/src/terminal.ts +96 -0
  211. package/src/theme.ts +738 -738
  212. package/src/tools.ts +1336 -773
  213. package/src/truncate.ts +173 -0
  214. package/src/types.ts +219 -198
  215. package/src/update.ts +22 -32
  216. package/src/workflow.ts +523 -508
  217. package/tsconfig.json +22 -22
  218. package/vitest.config.ts +19 -19
  219. package/dist/ai-client.d.ts +0 -86
  220. package/dist/ai-client.d.ts.map +0 -1
  221. package/dist/ai-client.js +0 -1372
  222. package/dist/ai-client.js.map +0 -1
  223. package/dist/gui-subagent/operator/browser-operator.d.ts +0 -36
  224. package/dist/gui-subagent/operator/browser-operator.d.ts.map +0 -1
  225. package/dist/gui-subagent/operator/browser-operator.js +0 -306
  226. package/dist/gui-subagent/operator/browser-operator.js.map +0 -1
  227. package/dist/gui-subagent/operator/desktop-operator.d.ts +0 -55
  228. package/dist/gui-subagent/operator/desktop-operator.d.ts.map +0 -1
  229. package/dist/gui-subagent/operator/desktop-operator.js +0 -527
  230. package/dist/gui-subagent/operator/desktop-operator.js.map +0 -1
  231. package/dist/hook.d.ts +0 -73
  232. package/dist/hook.d.ts.map +0 -1
  233. package/dist/hook.js +0 -156
  234. package/dist/hook.js.map +0 -1
  235. package/dist/input-history.d.ts +0 -24
  236. package/dist/input-history.d.ts.map +0 -1
  237. package/dist/input-history.js +0 -94
  238. package/dist/input-history.js.map +0 -1
  239. package/dist/keyboard-manager.d.ts +0 -151
  240. package/dist/keyboard-manager.d.ts.map +0 -1
  241. package/dist/keyboard-manager.js +0 -396
  242. package/dist/keyboard-manager.js.map +0 -1
  243. package/dist/print-system-prompt.d.ts +0 -2
  244. package/dist/print-system-prompt.d.ts.map +0 -1
  245. package/dist/print-system-prompt.js +0 -40
  246. package/dist/print-system-prompt.js.map +0 -1
  247. package/dist/remote-ai-client.d.ts +0 -104
  248. package/dist/remote-ai-client.d.ts.map +0 -1
  249. package/dist/remote-ai-client.js +0 -552
  250. package/dist/remote-ai-client.js.map +0 -1
  251. package/dist/sdk-output-adapter.d.ts +0 -232
  252. package/dist/sdk-output-adapter.d.ts.map +0 -1
  253. package/dist/sdk-output-adapter.js +0 -636
  254. package/dist/sdk-output-adapter.js.map +0 -1
  255. package/dist/sdk-session-v2.d.ts +0 -13
  256. package/dist/sdk-session-v2.d.ts.map +0 -1
  257. package/dist/sdk-session-v2.js +0 -46
  258. package/dist/sdk-session-v2.js.map +0 -1
  259. package/dist/sdk-session.d.ts +0 -13
  260. package/dist/sdk-session.d.ts.map +0 -1
  261. package/dist/sdk-session.js +0 -48
  262. package/dist/sdk-session.js.map +0 -1
  263. package/dist/test-boundary-conditions.d.ts.map +0 -1
  264. package/dist/test-boundary-conditions.js.map +0 -1
  265. package/dist/test-cancellation-fix.d.ts.map +0 -1
  266. package/dist/test-cancellation-fix.js.map +0 -1
  267. package/dist/test-input-history.d.ts.map +0 -1
  268. package/dist/test-input-history.js.map +0 -1
  269. package/dist/test-interaction-flow.d.ts.map +0 -1
  270. package/dist/test-interaction-flow.js.map +0 -1
  271. package/dist/test-quick.d.ts.map +0 -1
  272. package/dist/test-quick.js.map +0 -1
  273. package/dist/test-user-interaction.d.ts.map +0 -1
  274. package/dist/test-user-interaction.js.map +0 -1
  275. package/dist/tools/edit-diff.d.ts +0 -32
  276. package/dist/tools/edit-diff.d.ts.map +0 -1
  277. package/dist/tools/edit-diff.js +0 -185
  278. package/dist/tools/edit-diff.js.map +0 -1
  279. package/dist/tools/edit.d.ts +0 -11
  280. package/dist/tools/edit.d.ts.map +0 -1
  281. package/dist/tools/edit.js +0 -129
  282. package/dist/tools/edit.js.map +0 -1
  283. package/dist/unified-session.d.ts +0 -42
  284. package/dist/unified-session.d.ts.map +0 -1
  285. package/dist/unified-session.js +0 -271
  286. package/dist/unified-session.js.map +0 -1
  287. package/skills/.claude-plugin/marketplace.json +0 -45
  288. package/skills/README.md +0 -94
  289. package/skills/THIRD_PARTY_NOTICES.md +0 -405
  290. package/skills/skills/algorithmic-art/LICENSE.txt +0 -202
  291. package/skills/skills/algorithmic-art/SKILL.md +0 -405
  292. package/skills/skills/algorithmic-art/templates/generator_template.js +0 -223
  293. package/skills/skills/algorithmic-art/templates/viewer.html +0 -599
  294. package/skills/skills/brand-guidelines/LICENSE.txt +0 -202
  295. package/skills/skills/brand-guidelines/SKILL.md +0 -73
  296. package/skills/skills/canvas-design/LICENSE.txt +0 -202
  297. package/skills/skills/canvas-design/SKILL.md +0 -130
  298. package/skills/skills/canvas-design/canvas-fonts/ArsenalSC-OFL.txt +0 -93
  299. package/skills/skills/canvas-design/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
  300. package/skills/skills/canvas-design/canvas-fonts/BigShoulders-Bold.ttf +0 -0
  301. package/skills/skills/canvas-design/canvas-fonts/BigShoulders-OFL.txt +0 -93
  302. package/skills/skills/canvas-design/canvas-fonts/BigShoulders-Regular.ttf +0 -0
  303. package/skills/skills/canvas-design/canvas-fonts/Boldonse-OFL.txt +0 -93
  304. package/skills/skills/canvas-design/canvas-fonts/Boldonse-Regular.ttf +0 -0
  305. package/skills/skills/canvas-design/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
  306. package/skills/skills/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt +0 -93
  307. package/skills/skills/canvas-design/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
  308. package/skills/skills/canvas-design/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
  309. package/skills/skills/canvas-design/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
  310. package/skills/skills/canvas-design/canvas-fonts/CrimsonPro-OFL.txt +0 -93
  311. package/skills/skills/canvas-design/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
  312. package/skills/skills/canvas-design/canvas-fonts/DMMono-OFL.txt +0 -93
  313. package/skills/skills/canvas-design/canvas-fonts/DMMono-Regular.ttf +0 -0
  314. package/skills/skills/canvas-design/canvas-fonts/EricaOne-OFL.txt +0 -94
  315. package/skills/skills/canvas-design/canvas-fonts/EricaOne-Regular.ttf +0 -0
  316. package/skills/skills/canvas-design/canvas-fonts/GeistMono-Bold.ttf +0 -0
  317. package/skills/skills/canvas-design/canvas-fonts/GeistMono-OFL.txt +0 -93
  318. package/skills/skills/canvas-design/canvas-fonts/GeistMono-Regular.ttf +0 -0
  319. package/skills/skills/canvas-design/canvas-fonts/Gloock-OFL.txt +0 -93
  320. package/skills/skills/canvas-design/canvas-fonts/Gloock-Regular.ttf +0 -0
  321. package/skills/skills/canvas-design/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
  322. package/skills/skills/canvas-design/canvas-fonts/IBMPlexMono-OFL.txt +0 -93
  323. package/skills/skills/canvas-design/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
  324. package/skills/skills/canvas-design/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
  325. package/skills/skills/canvas-design/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
  326. package/skills/skills/canvas-design/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
  327. package/skills/skills/canvas-design/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
  328. package/skills/skills/canvas-design/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
  329. package/skills/skills/canvas-design/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
  330. package/skills/skills/canvas-design/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
  331. package/skills/skills/canvas-design/canvas-fonts/InstrumentSans-OFL.txt +0 -93
  332. package/skills/skills/canvas-design/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
  333. package/skills/skills/canvas-design/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
  334. package/skills/skills/canvas-design/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
  335. package/skills/skills/canvas-design/canvas-fonts/Italiana-OFL.txt +0 -93
  336. package/skills/skills/canvas-design/canvas-fonts/Italiana-Regular.ttf +0 -0
  337. package/skills/skills/canvas-design/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
  338. package/skills/skills/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt +0 -93
  339. package/skills/skills/canvas-design/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
  340. package/skills/skills/canvas-design/canvas-fonts/Jura-Light.ttf +0 -0
  341. package/skills/skills/canvas-design/canvas-fonts/Jura-Medium.ttf +0 -0
  342. package/skills/skills/canvas-design/canvas-fonts/Jura-OFL.txt +0 -93
  343. package/skills/skills/canvas-design/canvas-fonts/LibreBaskerville-OFL.txt +0 -93
  344. package/skills/skills/canvas-design/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
  345. package/skills/skills/canvas-design/canvas-fonts/Lora-Bold.ttf +0 -0
  346. package/skills/skills/canvas-design/canvas-fonts/Lora-BoldItalic.ttf +0 -0
  347. package/skills/skills/canvas-design/canvas-fonts/Lora-Italic.ttf +0 -0
  348. package/skills/skills/canvas-design/canvas-fonts/Lora-OFL.txt +0 -93
  349. package/skills/skills/canvas-design/canvas-fonts/Lora-Regular.ttf +0 -0
  350. package/skills/skills/canvas-design/canvas-fonts/NationalPark-Bold.ttf +0 -0
  351. package/skills/skills/canvas-design/canvas-fonts/NationalPark-OFL.txt +0 -93
  352. package/skills/skills/canvas-design/canvas-fonts/NationalPark-Regular.ttf +0 -0
  353. package/skills/skills/canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt +0 -93
  354. package/skills/skills/canvas-design/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
  355. package/skills/skills/canvas-design/canvas-fonts/Outfit-Bold.ttf +0 -0
  356. package/skills/skills/canvas-design/canvas-fonts/Outfit-OFL.txt +0 -93
  357. package/skills/skills/canvas-design/canvas-fonts/Outfit-Regular.ttf +0 -0
  358. package/skills/skills/canvas-design/canvas-fonts/PixelifySans-Medium.ttf +0 -0
  359. package/skills/skills/canvas-design/canvas-fonts/PixelifySans-OFL.txt +0 -93
  360. package/skills/skills/canvas-design/canvas-fonts/PoiretOne-OFL.txt +0 -93
  361. package/skills/skills/canvas-design/canvas-fonts/PoiretOne-Regular.ttf +0 -0
  362. package/skills/skills/canvas-design/canvas-fonts/RedHatMono-Bold.ttf +0 -0
  363. package/skills/skills/canvas-design/canvas-fonts/RedHatMono-OFL.txt +0 -93
  364. package/skills/skills/canvas-design/canvas-fonts/RedHatMono-Regular.ttf +0 -0
  365. package/skills/skills/canvas-design/canvas-fonts/Silkscreen-OFL.txt +0 -93
  366. package/skills/skills/canvas-design/canvas-fonts/Silkscreen-Regular.ttf +0 -0
  367. package/skills/skills/canvas-design/canvas-fonts/SmoochSans-Medium.ttf +0 -0
  368. package/skills/skills/canvas-design/canvas-fonts/SmoochSans-OFL.txt +0 -93
  369. package/skills/skills/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
  370. package/skills/skills/canvas-design/canvas-fonts/Tektur-OFL.txt +0 -93
  371. package/skills/skills/canvas-design/canvas-fonts/Tektur-Regular.ttf +0 -0
  372. package/skills/skills/canvas-design/canvas-fonts/WorkSans-Bold.ttf +0 -0
  373. package/skills/skills/canvas-design/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
  374. package/skills/skills/canvas-design/canvas-fonts/WorkSans-Italic.ttf +0 -0
  375. package/skills/skills/canvas-design/canvas-fonts/WorkSans-OFL.txt +0 -93
  376. package/skills/skills/canvas-design/canvas-fonts/WorkSans-Regular.ttf +0 -0
  377. package/skills/skills/canvas-design/canvas-fonts/YoungSerif-OFL.txt +0 -93
  378. package/skills/skills/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
  379. package/skills/skills/doc-coauthoring/SKILL.md +0 -375
  380. package/skills/skills/docx/LICENSE.txt +0 -30
  381. package/skills/skills/docx/SKILL.md +0 -197
  382. package/skills/skills/docx/docx-js.md +0 -350
  383. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
  384. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
  385. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
  386. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
  387. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
  388. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
  389. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
  390. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
  391. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
  392. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
  393. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
  394. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
  395. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
  396. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
  397. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
  398. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
  399. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
  400. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
  401. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
  402. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
  403. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
  404. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
  405. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
  406. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
  407. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
  408. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
  409. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
  410. package/skills/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
  411. package/skills/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
  412. package/skills/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
  413. package/skills/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
  414. package/skills/skills/docx/ooxml/schemas/mce/mc.xsd +0 -75
  415. package/skills/skills/docx/ooxml/schemas/microsoft/wml-2010.xsd +0 -560
  416. package/skills/skills/docx/ooxml/schemas/microsoft/wml-2012.xsd +0 -67
  417. package/skills/skills/docx/ooxml/schemas/microsoft/wml-2018.xsd +0 -14
  418. package/skills/skills/docx/ooxml/schemas/microsoft/wml-cex-2018.xsd +0 -20
  419. package/skills/skills/docx/ooxml/schemas/microsoft/wml-cid-2016.xsd +0 -13
  420. package/skills/skills/docx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
  421. package/skills/skills/docx/ooxml/schemas/microsoft/wml-symex-2015.xsd +0 -8
  422. package/skills/skills/docx/ooxml/scripts/pack.py +0 -159
  423. package/skills/skills/docx/ooxml/scripts/unpack.py +0 -29
  424. package/skills/skills/docx/ooxml/scripts/validate.py +0 -69
  425. package/skills/skills/docx/ooxml/scripts/validation/__init__.py +0 -15
  426. package/skills/skills/docx/ooxml/scripts/validation/base.py +0 -951
  427. package/skills/skills/docx/ooxml/scripts/validation/docx.py +0 -274
  428. package/skills/skills/docx/ooxml/scripts/validation/pptx.py +0 -315
  429. package/skills/skills/docx/ooxml/scripts/validation/redlining.py +0 -279
  430. package/skills/skills/docx/ooxml.md +0 -610
  431. package/skills/skills/docx/scripts/__init__.py +0 -1
  432. package/skills/skills/docx/scripts/document.py +0 -1276
  433. package/skills/skills/docx/scripts/templates/comments.xml +0 -3
  434. package/skills/skills/docx/scripts/templates/commentsExtended.xml +0 -3
  435. package/skills/skills/docx/scripts/templates/commentsExtensible.xml +0 -3
  436. package/skills/skills/docx/scripts/templates/commentsIds.xml +0 -3
  437. package/skills/skills/docx/scripts/templates/people.xml +0 -3
  438. package/skills/skills/docx/scripts/utilities.py +0 -374
  439. package/skills/skills/frontend-design/LICENSE.txt +0 -177
  440. package/skills/skills/frontend-design/SKILL.md +0 -42
  441. package/skills/skills/internal-comms/LICENSE.txt +0 -202
  442. package/skills/skills/internal-comms/SKILL.md +0 -32
  443. package/skills/skills/internal-comms/examples/3p-updates.md +0 -47
  444. package/skills/skills/internal-comms/examples/company-newsletter.md +0 -65
  445. package/skills/skills/internal-comms/examples/faq-answers.md +0 -30
  446. package/skills/skills/internal-comms/examples/general-comms.md +0 -16
  447. package/skills/skills/mcp-builder/LICENSE.txt +0 -202
  448. package/skills/skills/mcp-builder/SKILL.md +0 -236
  449. package/skills/skills/mcp-builder/reference/evaluation.md +0 -602
  450. package/skills/skills/mcp-builder/reference/mcp_best_practices.md +0 -249
  451. package/skills/skills/mcp-builder/reference/node_mcp_server.md +0 -970
  452. package/skills/skills/mcp-builder/reference/python_mcp_server.md +0 -719
  453. package/skills/skills/mcp-builder/scripts/connections.py +0 -151
  454. package/skills/skills/mcp-builder/scripts/evaluation.py +0 -373
  455. package/skills/skills/mcp-builder/scripts/example_evaluation.xml +0 -22
  456. package/skills/skills/mcp-builder/scripts/requirements.txt +0 -2
  457. package/skills/skills/pdf/LICENSE.txt +0 -30
  458. package/skills/skills/pdf/SKILL.md +0 -294
  459. package/skills/skills/pdf/forms.md +0 -205
  460. package/skills/skills/pdf/reference.md +0 -612
  461. package/skills/skills/pdf/scripts/check_bounding_boxes.py +0 -70
  462. package/skills/skills/pdf/scripts/check_bounding_boxes_test.py +0 -226
  463. package/skills/skills/pdf/scripts/check_fillable_fields.py +0 -12
  464. package/skills/skills/pdf/scripts/convert_pdf_to_images.py +0 -35
  465. package/skills/skills/pdf/scripts/create_validation_image.py +0 -41
  466. package/skills/skills/pdf/scripts/extract_form_field_info.py +0 -152
  467. package/skills/skills/pdf/scripts/fill_fillable_fields.py +0 -114
  468. package/skills/skills/pdf/scripts/fill_pdf_form_with_annotations.py +0 -108
  469. package/skills/skills/pptx/LICENSE.txt +0 -30
  470. package/skills/skills/pptx/SKILL.md +0 -484
  471. package/skills/skills/pptx/html2pptx.md +0 -625
  472. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
  473. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
  474. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
  475. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
  476. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
  477. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
  478. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
  479. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
  480. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
  481. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
  482. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
  483. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
  484. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
  485. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
  486. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
  487. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
  488. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
  489. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
  490. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
  491. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
  492. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
  493. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
  494. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
  495. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
  496. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
  497. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
  498. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
  499. package/skills/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
  500. package/skills/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
  501. package/skills/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
  502. package/skills/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
  503. package/skills/skills/pptx/ooxml/schemas/mce/mc.xsd +0 -75
  504. package/skills/skills/pptx/ooxml/schemas/microsoft/wml-2010.xsd +0 -560
  505. package/skills/skills/pptx/ooxml/schemas/microsoft/wml-2012.xsd +0 -67
  506. package/skills/skills/pptx/ooxml/schemas/microsoft/wml-2018.xsd +0 -14
  507. package/skills/skills/pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd +0 -20
  508. package/skills/skills/pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd +0 -13
  509. package/skills/skills/pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
  510. package/skills/skills/pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd +0 -8
  511. package/skills/skills/pptx/ooxml/scripts/pack.py +0 -159
  512. package/skills/skills/pptx/ooxml/scripts/unpack.py +0 -29
  513. package/skills/skills/pptx/ooxml/scripts/validate.py +0 -69
  514. package/skills/skills/pptx/ooxml/scripts/validation/__init__.py +0 -15
  515. package/skills/skills/pptx/ooxml/scripts/validation/base.py +0 -951
  516. package/skills/skills/pptx/ooxml/scripts/validation/docx.py +0 -274
  517. package/skills/skills/pptx/ooxml/scripts/validation/pptx.py +0 -315
  518. package/skills/skills/pptx/ooxml/scripts/validation/redlining.py +0 -279
  519. package/skills/skills/pptx/ooxml.md +0 -427
  520. package/skills/skills/pptx/scripts/html2pptx.js +0 -979
  521. package/skills/skills/pptx/scripts/inventory.py +0 -1020
  522. package/skills/skills/pptx/scripts/rearrange.py +0 -231
  523. package/skills/skills/pptx/scripts/replace.py +0 -385
  524. package/skills/skills/pptx/scripts/thumbnail.py +0 -450
  525. package/skills/skills/skill-creator/LICENSE.txt +0 -202
  526. package/skills/skills/skill-creator/SKILL.md +0 -356
  527. package/skills/skills/skill-creator/references/output-patterns.md +0 -82
  528. package/skills/skills/skill-creator/references/workflows.md +0 -28
  529. package/skills/skills/skill-creator/scripts/init_skill.py +0 -303
  530. package/skills/skills/skill-creator/scripts/package_skill.py +0 -110
  531. package/skills/skills/skill-creator/scripts/quick_validate.py +0 -95
  532. package/skills/skills/slack-gif-creator/LICENSE.txt +0 -202
  533. package/skills/skills/slack-gif-creator/SKILL.md +0 -254
  534. package/skills/skills/slack-gif-creator/core/easing.py +0 -234
  535. package/skills/skills/slack-gif-creator/core/frame_composer.py +0 -176
  536. package/skills/skills/slack-gif-creator/core/gif_builder.py +0 -269
  537. package/skills/skills/slack-gif-creator/core/validators.py +0 -136
  538. package/skills/skills/slack-gif-creator/requirements.txt +0 -4
  539. package/skills/skills/theme-factory/LICENSE.txt +0 -202
  540. package/skills/skills/theme-factory/SKILL.md +0 -59
  541. package/skills/skills/theme-factory/theme-showcase.pdf +0 -0
  542. package/skills/skills/theme-factory/themes/arctic-frost.md +0 -19
  543. package/skills/skills/theme-factory/themes/botanical-garden.md +0 -19
  544. package/skills/skills/theme-factory/themes/desert-rose.md +0 -19
  545. package/skills/skills/theme-factory/themes/forest-canopy.md +0 -19
  546. package/skills/skills/theme-factory/themes/golden-hour.md +0 -19
  547. package/skills/skills/theme-factory/themes/midnight-galaxy.md +0 -19
  548. package/skills/skills/theme-factory/themes/modern-minimalist.md +0 -19
  549. package/skills/skills/theme-factory/themes/ocean-depths.md +0 -19
  550. package/skills/skills/theme-factory/themes/sunset-boulevard.md +0 -19
  551. package/skills/skills/theme-factory/themes/tech-innovation.md +0 -19
  552. package/skills/skills/web-artifacts-builder/LICENSE.txt +0 -202
  553. package/skills/skills/web-artifacts-builder/SKILL.md +0 -74
  554. package/skills/skills/web-artifacts-builder/scripts/bundle-artifact.sh +0 -54
  555. package/skills/skills/web-artifacts-builder/scripts/init-artifact.sh +0 -322
  556. package/skills/skills/webapp-testing/LICENSE.txt +0 -202
  557. package/skills/skills/webapp-testing/SKILL.md +0 -96
  558. package/skills/skills/webapp-testing/examples/console_logging.py +0 -35
  559. package/skills/skills/webapp-testing/examples/element_discovery.py +0 -40
  560. package/skills/skills/webapp-testing/examples/static_html_automation.py +0 -33
  561. package/skills/skills/webapp-testing/scripts/with_server.py +0 -106
  562. package/skills/skills/xlsx/LICENSE.txt +0 -30
  563. package/skills/skills/xlsx/SKILL.md +0 -289
  564. package/skills/skills/xlsx/recalc.py +0 -178
  565. package/skills/spec/agent-skills-spec.md +0 -3
  566. package/skills/template/SKILL.md +0 -6
  567. package/src/ai-client.ts +0 -1560
  568. package/src/remote-ai-client.ts +0 -664
@@ -1,176 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- Frame Composer - Utilities for composing visual elements into frames.
4
-
5
- Provides functions for drawing shapes, text, emojis, and compositing elements
6
- together to create animation frames.
7
- """
8
-
9
- from typing import Optional
10
-
11
- import numpy as np
12
- from PIL import Image, ImageDraw, ImageFont
13
-
14
-
15
- def create_blank_frame(
16
- width: int, height: int, color: tuple[int, int, int] = (255, 255, 255)
17
- ) -> Image.Image:
18
- """
19
- Create a blank frame with solid color background.
20
-
21
- Args:
22
- width: Frame width
23
- height: Frame height
24
- color: RGB color tuple (default: white)
25
-
26
- Returns:
27
- PIL Image
28
- """
29
- return Image.new("RGB", (width, height), color)
30
-
31
-
32
- def draw_circle(
33
- frame: Image.Image,
34
- center: tuple[int, int],
35
- radius: int,
36
- fill_color: Optional[tuple[int, int, int]] = None,
37
- outline_color: Optional[tuple[int, int, int]] = None,
38
- outline_width: int = 1,
39
- ) -> Image.Image:
40
- """
41
- Draw a circle on a frame.
42
-
43
- Args:
44
- frame: PIL Image to draw on
45
- center: (x, y) center position
46
- radius: Circle radius
47
- fill_color: RGB fill color (None for no fill)
48
- outline_color: RGB outline color (None for no outline)
49
- outline_width: Outline width in pixels
50
-
51
- Returns:
52
- Modified frame
53
- """
54
- draw = ImageDraw.Draw(frame)
55
- x, y = center
56
- bbox = [x - radius, y - radius, x + radius, y + radius]
57
- draw.ellipse(bbox, fill=fill_color, outline=outline_color, width=outline_width)
58
- return frame
59
-
60
-
61
- def draw_text(
62
- frame: Image.Image,
63
- text: str,
64
- position: tuple[int, int],
65
- color: tuple[int, int, int] = (0, 0, 0),
66
- centered: bool = False,
67
- ) -> Image.Image:
68
- """
69
- Draw text on a frame.
70
-
71
- Args:
72
- frame: PIL Image to draw on
73
- text: Text to draw
74
- position: (x, y) position (top-left unless centered=True)
75
- color: RGB text color
76
- centered: If True, center text at position
77
-
78
- Returns:
79
- Modified frame
80
- """
81
- draw = ImageDraw.Draw(frame)
82
-
83
- # Uses Pillow's default font.
84
- # If the font should be changed for the emoji, add additional logic here.
85
- font = ImageFont.load_default()
86
-
87
- if centered:
88
- bbox = draw.textbbox((0, 0), text, font=font)
89
- text_width = bbox[2] - bbox[0]
90
- text_height = bbox[3] - bbox[1]
91
- x = position[0] - text_width // 2
92
- y = position[1] - text_height // 2
93
- position = (x, y)
94
-
95
- draw.text(position, text, fill=color, font=font)
96
- return frame
97
-
98
-
99
- def create_gradient_background(
100
- width: int,
101
- height: int,
102
- top_color: tuple[int, int, int],
103
- bottom_color: tuple[int, int, int],
104
- ) -> Image.Image:
105
- """
106
- Create a vertical gradient background.
107
-
108
- Args:
109
- width: Frame width
110
- height: Frame height
111
- top_color: RGB color at top
112
- bottom_color: RGB color at bottom
113
-
114
- Returns:
115
- PIL Image with gradient
116
- """
117
- frame = Image.new("RGB", (width, height))
118
- draw = ImageDraw.Draw(frame)
119
-
120
- # Calculate color step for each row
121
- r1, g1, b1 = top_color
122
- r2, g2, b2 = bottom_color
123
-
124
- for y in range(height):
125
- # Interpolate color
126
- ratio = y / height
127
- r = int(r1 * (1 - ratio) + r2 * ratio)
128
- g = int(g1 * (1 - ratio) + g2 * ratio)
129
- b = int(b1 * (1 - ratio) + b2 * ratio)
130
-
131
- # Draw horizontal line
132
- draw.line([(0, y), (width, y)], fill=(r, g, b))
133
-
134
- return frame
135
-
136
-
137
- def draw_star(
138
- frame: Image.Image,
139
- center: tuple[int, int],
140
- size: int,
141
- fill_color: tuple[int, int, int],
142
- outline_color: Optional[tuple[int, int, int]] = None,
143
- outline_width: int = 1,
144
- ) -> Image.Image:
145
- """
146
- Draw a 5-pointed star.
147
-
148
- Args:
149
- frame: PIL Image to draw on
150
- center: (x, y) center position
151
- size: Star size (outer radius)
152
- fill_color: RGB fill color
153
- outline_color: RGB outline color (None for no outline)
154
- outline_width: Outline width
155
-
156
- Returns:
157
- Modified frame
158
- """
159
- import math
160
-
161
- draw = ImageDraw.Draw(frame)
162
- x, y = center
163
-
164
- # Calculate star points
165
- points = []
166
- for i in range(10):
167
- angle = (i * 36 - 90) * math.pi / 180 # 36 degrees per point, start at top
168
- radius = size if i % 2 == 0 else size * 0.4 # Alternate between outer and inner
169
- px = x + radius * math.cos(angle)
170
- py = y + radius * math.sin(angle)
171
- points.append((px, py))
172
-
173
- # Draw star
174
- draw.polygon(points, fill=fill_color, outline=outline_color, width=outline_width)
175
-
176
- return frame
@@ -1,269 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- GIF Builder - Core module for assembling frames into GIFs optimized for Slack.
4
-
5
- This module provides the main interface for creating GIFs from programmatically
6
- generated frames, with automatic optimization for Slack's requirements.
7
- """
8
-
9
- from pathlib import Path
10
- from typing import Optional
11
-
12
- import imageio.v3 as imageio
13
- import numpy as np
14
- from PIL import Image
15
-
16
-
17
- class GIFBuilder:
18
- """Builder for creating optimized GIFs from frames."""
19
-
20
- def __init__(self, width: int = 480, height: int = 480, fps: int = 15):
21
- """
22
- Initialize GIF builder.
23
-
24
- Args:
25
- width: Frame width in pixels
26
- height: Frame height in pixels
27
- fps: Frames per second
28
- """
29
- self.width = width
30
- self.height = height
31
- self.fps = fps
32
- self.frames: list[np.ndarray] = []
33
-
34
- def add_frame(self, frame: np.ndarray | Image.Image):
35
- """
36
- Add a frame to the GIF.
37
-
38
- Args:
39
- frame: Frame as numpy array or PIL Image (will be converted to RGB)
40
- """
41
- if isinstance(frame, Image.Image):
42
- frame = np.array(frame.convert("RGB"))
43
-
44
- # Ensure frame is correct size
45
- if frame.shape[:2] != (self.height, self.width):
46
- pil_frame = Image.fromarray(frame)
47
- pil_frame = pil_frame.resize(
48
- (self.width, self.height), Image.Resampling.LANCZOS
49
- )
50
- frame = np.array(pil_frame)
51
-
52
- self.frames.append(frame)
53
-
54
- def add_frames(self, frames: list[np.ndarray | Image.Image]):
55
- """Add multiple frames at once."""
56
- for frame in frames:
57
- self.add_frame(frame)
58
-
59
- def optimize_colors(
60
- self, num_colors: int = 128, use_global_palette: bool = True
61
- ) -> list[np.ndarray]:
62
- """
63
- Reduce colors in all frames using quantization.
64
-
65
- Args:
66
- num_colors: Target number of colors (8-256)
67
- use_global_palette: Use a single palette for all frames (better compression)
68
-
69
- Returns:
70
- List of color-optimized frames
71
- """
72
- optimized = []
73
-
74
- if use_global_palette and len(self.frames) > 1:
75
- # Create a global palette from all frames
76
- # Sample frames to build palette
77
- sample_size = min(5, len(self.frames))
78
- sample_indices = [
79
- int(i * len(self.frames) / sample_size) for i in range(sample_size)
80
- ]
81
- sample_frames = [self.frames[i] for i in sample_indices]
82
-
83
- # Combine sample frames into a single image for palette generation
84
- # Flatten each frame to get all pixels, then stack them
85
- all_pixels = np.vstack(
86
- [f.reshape(-1, 3) for f in sample_frames]
87
- ) # (total_pixels, 3)
88
-
89
- # Create a properly-shaped RGB image from the pixel data
90
- # We'll make a roughly square image from all the pixels
91
- total_pixels = len(all_pixels)
92
- width = min(512, int(np.sqrt(total_pixels))) # Reasonable width, max 512
93
- height = (total_pixels + width - 1) // width # Ceiling division
94
-
95
- # Pad if necessary to fill the rectangle
96
- pixels_needed = width * height
97
- if pixels_needed > total_pixels:
98
- padding = np.zeros((pixels_needed - total_pixels, 3), dtype=np.uint8)
99
- all_pixels = np.vstack([all_pixels, padding])
100
-
101
- # Reshape to proper RGB image format (H, W, 3)
102
- img_array = (
103
- all_pixels[:pixels_needed].reshape(height, width, 3).astype(np.uint8)
104
- )
105
- combined_img = Image.fromarray(img_array, mode="RGB")
106
-
107
- # Generate global palette
108
- global_palette = combined_img.quantize(colors=num_colors, method=2)
109
-
110
- # Apply global palette to all frames
111
- for frame in self.frames:
112
- pil_frame = Image.fromarray(frame)
113
- quantized = pil_frame.quantize(palette=global_palette, dither=1)
114
- optimized.append(np.array(quantized.convert("RGB")))
115
- else:
116
- # Use per-frame quantization
117
- for frame in self.frames:
118
- pil_frame = Image.fromarray(frame)
119
- quantized = pil_frame.quantize(colors=num_colors, method=2, dither=1)
120
- optimized.append(np.array(quantized.convert("RGB")))
121
-
122
- return optimized
123
-
124
- def deduplicate_frames(self, threshold: float = 0.9995) -> int:
125
- """
126
- Remove duplicate or near-duplicate consecutive frames.
127
-
128
- Args:
129
- threshold: Similarity threshold (0.0-1.0). Higher = more strict (0.9995 = nearly identical).
130
- Use 0.9995+ to preserve subtle animations, 0.98 for aggressive removal.
131
-
132
- Returns:
133
- Number of frames removed
134
- """
135
- if len(self.frames) < 2:
136
- return 0
137
-
138
- deduplicated = [self.frames[0]]
139
- removed_count = 0
140
-
141
- for i in range(1, len(self.frames)):
142
- # Compare with previous frame
143
- prev_frame = np.array(deduplicated[-1], dtype=np.float32)
144
- curr_frame = np.array(self.frames[i], dtype=np.float32)
145
-
146
- # Calculate similarity (normalized)
147
- diff = np.abs(prev_frame - curr_frame)
148
- similarity = 1.0 - (np.mean(diff) / 255.0)
149
-
150
- # Keep frame if sufficiently different
151
- # High threshold (0.9995+) means only remove nearly identical frames
152
- if similarity < threshold:
153
- deduplicated.append(self.frames[i])
154
- else:
155
- removed_count += 1
156
-
157
- self.frames = deduplicated
158
- return removed_count
159
-
160
- def save(
161
- self,
162
- output_path: str | Path,
163
- num_colors: int = 128,
164
- optimize_for_emoji: bool = False,
165
- remove_duplicates: bool = False,
166
- ) -> dict:
167
- """
168
- Save frames as optimized GIF for Slack.
169
-
170
- Args:
171
- output_path: Where to save the GIF
172
- num_colors: Number of colors to use (fewer = smaller file)
173
- optimize_for_emoji: If True, optimize for emoji size (128x128, fewer colors)
174
- remove_duplicates: If True, remove duplicate consecutive frames (opt-in)
175
-
176
- Returns:
177
- Dictionary with file info (path, size, dimensions, frame_count)
178
- """
179
- if not self.frames:
180
- raise ValueError("No frames to save. Add frames with add_frame() first.")
181
-
182
- output_path = Path(output_path)
183
-
184
- # Remove duplicate frames to reduce file size
185
- if remove_duplicates:
186
- removed = self.deduplicate_frames(threshold=0.9995)
187
- if removed > 0:
188
- print(
189
- f" Removed {removed} nearly identical frames (preserved subtle animations)"
190
- )
191
-
192
- # Optimize for emoji if requested
193
- if optimize_for_emoji:
194
- if self.width > 128 or self.height > 128:
195
- print(
196
- f" Resizing from {self.width}x{self.height} to 128x128 for emoji"
197
- )
198
- self.width = 128
199
- self.height = 128
200
- # Resize all frames
201
- resized_frames = []
202
- for frame in self.frames:
203
- pil_frame = Image.fromarray(frame)
204
- pil_frame = pil_frame.resize((128, 128), Image.Resampling.LANCZOS)
205
- resized_frames.append(np.array(pil_frame))
206
- self.frames = resized_frames
207
- num_colors = min(num_colors, 48) # More aggressive color limit for emoji
208
-
209
- # More aggressive FPS reduction for emoji
210
- if len(self.frames) > 12:
211
- print(
212
- f" Reducing frames from {len(self.frames)} to ~12 for emoji size"
213
- )
214
- # Keep every nth frame to get close to 12 frames
215
- keep_every = max(1, len(self.frames) // 12)
216
- self.frames = [
217
- self.frames[i] for i in range(0, len(self.frames), keep_every)
218
- ]
219
-
220
- # Optimize colors with global palette
221
- optimized_frames = self.optimize_colors(num_colors, use_global_palette=True)
222
-
223
- # Calculate frame duration in milliseconds
224
- frame_duration = 1000 / self.fps
225
-
226
- # Save GIF
227
- imageio.imwrite(
228
- output_path,
229
- optimized_frames,
230
- duration=frame_duration,
231
- loop=0, # Infinite loop
232
- )
233
-
234
- # Get file info
235
- file_size_kb = output_path.stat().st_size / 1024
236
- file_size_mb = file_size_kb / 1024
237
-
238
- info = {
239
- "path": str(output_path),
240
- "size_kb": file_size_kb,
241
- "size_mb": file_size_mb,
242
- "dimensions": f"{self.width}x{self.height}",
243
- "frame_count": len(optimized_frames),
244
- "fps": self.fps,
245
- "duration_seconds": len(optimized_frames) / self.fps,
246
- "colors": num_colors,
247
- }
248
-
249
- # Print info
250
- print(f"\n✓ GIF created successfully!")
251
- print(f" Path: {output_path}")
252
- print(f" Size: {file_size_kb:.1f} KB ({file_size_mb:.2f} MB)")
253
- print(f" Dimensions: {self.width}x{self.height}")
254
- print(f" Frames: {len(optimized_frames)} @ {self.fps} fps")
255
- print(f" Duration: {info['duration_seconds']:.1f}s")
256
- print(f" Colors: {num_colors}")
257
-
258
- # Size info
259
- if optimize_for_emoji:
260
- print(f" Optimized for emoji (128x128, reduced colors)")
261
- if file_size_mb > 1.0:
262
- print(f"\n Note: Large file size ({file_size_kb:.1f} KB)")
263
- print(" Consider: fewer frames, smaller dimensions, or fewer colors")
264
-
265
- return info
266
-
267
- def clear(self):
268
- """Clear all frames (useful for creating multiple GIFs)."""
269
- self.frames = []
@@ -1,136 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- Validators - Check if GIFs meet Slack's requirements.
4
-
5
- These validators help ensure your GIFs meet Slack's size and dimension constraints.
6
- """
7
-
8
- from pathlib import Path
9
-
10
-
11
- def validate_gif(
12
- gif_path: str | Path, is_emoji: bool = True, verbose: bool = True
13
- ) -> tuple[bool, dict]:
14
- """
15
- Validate GIF for Slack (dimensions, size, frame count).
16
-
17
- Args:
18
- gif_path: Path to GIF file
19
- is_emoji: True for emoji (128x128 recommended), False for message GIF
20
- verbose: Print validation details
21
-
22
- Returns:
23
- Tuple of (passes: bool, results: dict with all details)
24
- """
25
- from PIL import Image
26
-
27
- gif_path = Path(gif_path)
28
-
29
- if not gif_path.exists():
30
- return False, {"error": f"File not found: {gif_path}"}
31
-
32
- # Get file size
33
- size_bytes = gif_path.stat().st_size
34
- size_kb = size_bytes / 1024
35
- size_mb = size_kb / 1024
36
-
37
- # Get dimensions and frame info
38
- try:
39
- with Image.open(gif_path) as img:
40
- width, height = img.size
41
-
42
- # Count frames
43
- frame_count = 0
44
- try:
45
- while True:
46
- img.seek(frame_count)
47
- frame_count += 1
48
- except EOFError:
49
- pass
50
-
51
- # Get duration
52
- try:
53
- duration_ms = img.info.get("duration", 100)
54
- total_duration = (duration_ms * frame_count) / 1000
55
- fps = frame_count / total_duration if total_duration > 0 else 0
56
- except:
57
- total_duration = None
58
- fps = None
59
-
60
- except Exception as e:
61
- return False, {"error": f"Failed to read GIF: {e}"}
62
-
63
- # Validate dimensions
64
- if is_emoji:
65
- optimal = width == height == 128
66
- acceptable = width == height and 64 <= width <= 128
67
- dim_pass = acceptable
68
- else:
69
- aspect_ratio = (
70
- max(width, height) / min(width, height)
71
- if min(width, height) > 0
72
- else float("inf")
73
- )
74
- dim_pass = aspect_ratio <= 2.0 and 320 <= min(width, height) <= 640
75
-
76
- results = {
77
- "file": str(gif_path),
78
- "passes": dim_pass,
79
- "width": width,
80
- "height": height,
81
- "size_kb": size_kb,
82
- "size_mb": size_mb,
83
- "frame_count": frame_count,
84
- "duration_seconds": total_duration,
85
- "fps": fps,
86
- "is_emoji": is_emoji,
87
- "optimal": optimal if is_emoji else None,
88
- }
89
-
90
- # Print if verbose
91
- if verbose:
92
- print(f"\nValidating {gif_path.name}:")
93
- print(
94
- f" Dimensions: {width}x{height}"
95
- + (
96
- f" ({'optimal' if optimal else 'acceptable'})"
97
- if is_emoji and acceptable
98
- else ""
99
- )
100
- )
101
- print(
102
- f" Size: {size_kb:.1f} KB"
103
- + (f" ({size_mb:.2f} MB)" if size_mb >= 1.0 else "")
104
- )
105
- print(
106
- f" Frames: {frame_count}"
107
- + (f" @ {fps:.1f} fps ({total_duration:.1f}s)" if fps else "")
108
- )
109
-
110
- if not dim_pass:
111
- print(
112
- f" Note: {'Emoji should be 128x128' if is_emoji else 'Unusual dimensions for Slack'}"
113
- )
114
-
115
- if size_mb > 5.0:
116
- print(f" Note: Large file size - consider fewer frames/colors")
117
-
118
- return dim_pass, results
119
-
120
-
121
- def is_slack_ready(
122
- gif_path: str | Path, is_emoji: bool = True, verbose: bool = True
123
- ) -> bool:
124
- """
125
- Quick check if GIF is ready for Slack.
126
-
127
- Args:
128
- gif_path: Path to GIF file
129
- is_emoji: True for emoji GIF, False for message GIF
130
- verbose: Print feedback
131
-
132
- Returns:
133
- True if dimensions are acceptable
134
- """
135
- passes, _ = validate_gif(gif_path, is_emoji, verbose)
136
- return passes
@@ -1,4 +0,0 @@
1
- pillow>=10.0.0
2
- imageio>=2.31.0
3
- imageio-ffmpeg>=0.4.9
4
- numpy>=1.24.0