orquesta-cli 0.1.12 → 0.1.14

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 (540) hide show
  1. package/README.md +30 -4
  2. package/dist/cli.js +65 -4
  3. package/dist/constants.js +1 -1
  4. package/dist/core/config/config-manager.d.ts +13 -1
  5. package/dist/core/config/config-manager.js +83 -0
  6. package/dist/core/slash-command-handler.d.ts +1 -0
  7. package/dist/core/slash-command-handler.js +129 -0
  8. package/dist/orquesta/config-sync.d.ts +73 -0
  9. package/dist/orquesta/config-sync.js +230 -0
  10. package/dist/orquesta/prompt-reporter.d.ts +16 -0
  11. package/dist/orquesta/prompt-reporter.js +85 -0
  12. package/dist/setup/first-run-setup.d.ts +15 -0
  13. package/dist/setup/first-run-setup.js +238 -0
  14. package/dist/types/index.d.ts +11 -2
  15. package/dist/ui/TodoPanel.d.ts +1 -0
  16. package/dist/ui/TodoPanel.js +6 -1
  17. package/dist/ui/components/LLMSetupWizard.js +373 -7
  18. package/dist/ui/components/Logo.d.ts +2 -0
  19. package/dist/ui/components/Logo.js +10 -3
  20. package/dist/ui/components/OpenRouterModelBrowser.d.ts +13 -0
  21. package/dist/ui/components/OpenRouterModelBrowser.js +221 -0
  22. package/dist/ui/components/PlanExecuteApp.js +30 -4
  23. package/dist/ui/components/ProjectSelector.d.ts +8 -0
  24. package/dist/ui/components/ProjectSelector.js +119 -0
  25. package/dist/ui/components/StatusBar.d.ts +2 -0
  26. package/dist/ui/components/StatusBar.js +6 -1
  27. package/dist/ui/hooks/slashCommandProcessor.js +8 -4
  28. package/package.json +11 -5
  29. package/.eslintrc.json +0 -26
  30. package/.prettierrc.json +0 -10
  31. package/CLAUDE.md +0 -199
  32. package/SECURITY.md +0 -290
  33. package/TEST_LOCAL.md +0 -245
  34. package/dist/agents/base/base-agent.d.ts.map +0 -1
  35. package/dist/agents/base/base-agent.js.map +0 -1
  36. package/dist/agents/docs-search/index.d.ts.map +0 -1
  37. package/dist/agents/docs-search/index.js.map +0 -1
  38. package/dist/agents/index.d.ts.map +0 -1
  39. package/dist/agents/index.js.map +0 -1
  40. package/dist/agents/planner/index.d.ts.map +0 -1
  41. package/dist/agents/planner/index.js.map +0 -1
  42. package/dist/cli.d.ts.map +0 -1
  43. package/dist/cli.js.map +0 -1
  44. package/dist/constants.d.ts.map +0 -1
  45. package/dist/constants.js.map +0 -1
  46. package/dist/core/compact/compact-manager.d.ts.map +0 -1
  47. package/dist/core/compact/compact-manager.js.map +0 -1
  48. package/dist/core/compact/compact-prompts.d.ts.map +0 -1
  49. package/dist/core/compact/compact-prompts.js.map +0 -1
  50. package/dist/core/compact/context-tracker.d.ts.map +0 -1
  51. package/dist/core/compact/context-tracker.js.map +0 -1
  52. package/dist/core/compact/index.d.ts.map +0 -1
  53. package/dist/core/compact/index.js.map +0 -1
  54. package/dist/core/config/config-manager.d.ts.map +0 -1
  55. package/dist/core/config/config-manager.js.map +0 -1
  56. package/dist/core/config/index.d.ts.map +0 -1
  57. package/dist/core/config/index.js.map +0 -1
  58. package/dist/core/docs-manager.d.ts.map +0 -1
  59. package/dist/core/docs-manager.js.map +0 -1
  60. package/dist/core/git-auto-updater.d.ts.map +0 -1
  61. package/dist/core/git-auto-updater.js.map +0 -1
  62. package/dist/core/llm/index.d.ts.map +0 -1
  63. package/dist/core/llm/index.js.map +0 -1
  64. package/dist/core/llm/llm-client.d.ts.map +0 -1
  65. package/dist/core/llm/llm-client.js.map +0 -1
  66. package/dist/core/session/index.d.ts.map +0 -1
  67. package/dist/core/session/index.js.map +0 -1
  68. package/dist/core/session/session-manager.d.ts.map +0 -1
  69. package/dist/core/session/session-manager.js.map +0 -1
  70. package/dist/core/slash-command-handler.d.ts.map +0 -1
  71. package/dist/core/slash-command-handler.js.map +0 -1
  72. package/dist/core/usage-tracker.d.ts.map +0 -1
  73. package/dist/core/usage-tracker.js.map +0 -1
  74. package/dist/errors/base.d.ts.map +0 -1
  75. package/dist/errors/base.js.map +0 -1
  76. package/dist/errors/file.d.ts.map +0 -1
  77. package/dist/errors/file.js.map +0 -1
  78. package/dist/errors/index.d.ts.map +0 -1
  79. package/dist/errors/index.js.map +0 -1
  80. package/dist/errors/llm.d.ts.map +0 -1
  81. package/dist/errors/llm.js.map +0 -1
  82. package/dist/errors/network.d.ts.map +0 -1
  83. package/dist/errors/network.js.map +0 -1
  84. package/dist/errors/validation.d.ts.map +0 -1
  85. package/dist/errors/validation.js.map +0 -1
  86. package/dist/eval/eval-runner.d.ts.map +0 -1
  87. package/dist/eval/eval-runner.js.map +0 -1
  88. package/dist/eval/index.d.ts.map +0 -1
  89. package/dist/eval/index.js.map +0 -1
  90. package/dist/eval/types.d.ts.map +0 -1
  91. package/dist/eval/types.js.map +0 -1
  92. package/dist/index.d.ts.map +0 -1
  93. package/dist/index.js.map +0 -1
  94. package/dist/orchestration/index.d.ts.map +0 -1
  95. package/dist/orchestration/index.js.map +0 -1
  96. package/dist/orchestration/plan-executor.d.ts.map +0 -1
  97. package/dist/orchestration/plan-executor.js.map +0 -1
  98. package/dist/orchestration/types.d.ts.map +0 -1
  99. package/dist/orchestration/types.js.map +0 -1
  100. package/dist/orchestration/utils.d.ts.map +0 -1
  101. package/dist/orchestration/utils.js.map +0 -1
  102. package/dist/orquesta/connection.d.ts.map +0 -1
  103. package/dist/orquesta/connection.js.map +0 -1
  104. package/dist/prompts/agents/docs-search-decision.d.ts.map +0 -1
  105. package/dist/prompts/agents/docs-search-decision.js.map +0 -1
  106. package/dist/prompts/agents/docs-search.d.ts.map +0 -1
  107. package/dist/prompts/agents/docs-search.js.map +0 -1
  108. package/dist/prompts/agents/planning.d.ts.map +0 -1
  109. package/dist/prompts/agents/planning.js.map +0 -1
  110. package/dist/prompts/index.d.ts.map +0 -1
  111. package/dist/prompts/index.js.map +0 -1
  112. package/dist/prompts/shared/codebase-rules.d.ts.map +0 -1
  113. package/dist/prompts/shared/codebase-rules.js.map +0 -1
  114. package/dist/prompts/shared/git-rules.d.ts.map +0 -1
  115. package/dist/prompts/shared/git-rules.js.map +0 -1
  116. package/dist/prompts/shared/language-rules.d.ts.map +0 -1
  117. package/dist/prompts/shared/language-rules.js.map +0 -1
  118. package/dist/prompts/shared/tool-usage.d.ts.map +0 -1
  119. package/dist/prompts/shared/tool-usage.js.map +0 -1
  120. package/dist/prompts/system/compact.d.ts.map +0 -1
  121. package/dist/prompts/system/compact.js.map +0 -1
  122. package/dist/prompts/system/plan-execute.d.ts.map +0 -1
  123. package/dist/prompts/system/plan-execute.js.map +0 -1
  124. package/dist/tools/browser/browser-client.d.ts.map +0 -1
  125. package/dist/tools/browser/browser-client.js.map +0 -1
  126. package/dist/tools/browser/browser-tools.d.ts.map +0 -1
  127. package/dist/tools/browser/browser-tools.js.map +0 -1
  128. package/dist/tools/browser/index.d.ts.map +0 -1
  129. package/dist/tools/browser/index.js.map +0 -1
  130. package/dist/tools/index.d.ts.map +0 -1
  131. package/dist/tools/index.js.map +0 -1
  132. package/dist/tools/llm/agents/docs-search-tools.d.ts.map +0 -1
  133. package/dist/tools/llm/agents/docs-search-tools.js.map +0 -1
  134. package/dist/tools/llm/agents/index.d.ts.map +0 -1
  135. package/dist/tools/llm/agents/index.js.map +0 -1
  136. package/dist/tools/llm/index.d.ts.map +0 -1
  137. package/dist/tools/llm/index.js.map +0 -1
  138. package/dist/tools/llm/simple/ask-user-tool.d.ts.map +0 -1
  139. package/dist/tools/llm/simple/ask-user-tool.js.map +0 -1
  140. package/dist/tools/llm/simple/background-bash-tool.d.ts.map +0 -1
  141. package/dist/tools/llm/simple/background-bash-tool.js.map +0 -1
  142. package/dist/tools/llm/simple/background-powershell-tool.d.ts.map +0 -1
  143. package/dist/tools/llm/simple/background-powershell-tool.js.map +0 -1
  144. package/dist/tools/llm/simple/bash-tool.d.ts.map +0 -1
  145. package/dist/tools/llm/simple/bash-tool.js.map +0 -1
  146. package/dist/tools/llm/simple/docs-search-agent-tool.d.ts.map +0 -1
  147. package/dist/tools/llm/simple/docs-search-agent-tool.js.map +0 -1
  148. package/dist/tools/llm/simple/file-tools.d.ts.map +0 -1
  149. package/dist/tools/llm/simple/file-tools.js.map +0 -1
  150. package/dist/tools/llm/simple/final-response-tool.d.ts.map +0 -1
  151. package/dist/tools/llm/simple/final-response-tool.js.map +0 -1
  152. package/dist/tools/llm/simple/index.d.ts.map +0 -1
  153. package/dist/tools/llm/simple/index.js.map +0 -1
  154. package/dist/tools/llm/simple/planning-tools.d.ts.map +0 -1
  155. package/dist/tools/llm/simple/planning-tools.js.map +0 -1
  156. package/dist/tools/llm/simple/powershell-tool.d.ts.map +0 -1
  157. package/dist/tools/llm/simple/powershell-tool.js.map +0 -1
  158. package/dist/tools/llm/simple/simple-tool-executor.d.ts.map +0 -1
  159. package/dist/tools/llm/simple/simple-tool-executor.js.map +0 -1
  160. package/dist/tools/llm/simple/todo-tools.d.ts.map +0 -1
  161. package/dist/tools/llm/simple/todo-tools.js.map +0 -1
  162. package/dist/tools/llm/simple/user-interaction-tools.d.ts.map +0 -1
  163. package/dist/tools/llm/simple/user-interaction-tools.js.map +0 -1
  164. package/dist/tools/office/common/constants.d.ts.map +0 -1
  165. package/dist/tools/office/common/constants.js.map +0 -1
  166. package/dist/tools/office/common/index.d.ts.map +0 -1
  167. package/dist/tools/office/common/index.js.map +0 -1
  168. package/dist/tools/office/common/types.d.ts.map +0 -1
  169. package/dist/tools/office/common/types.js.map +0 -1
  170. package/dist/tools/office/common/utils.d.ts.map +0 -1
  171. package/dist/tools/office/common/utils.js.map +0 -1
  172. package/dist/tools/office/excel-client.d.ts.map +0 -1
  173. package/dist/tools/office/excel-client.js.map +0 -1
  174. package/dist/tools/office/excel-tools/cells.d.ts.map +0 -1
  175. package/dist/tools/office/excel-tools/cells.js.map +0 -1
  176. package/dist/tools/office/excel-tools/charts.d.ts.map +0 -1
  177. package/dist/tools/office/excel-tools/charts.js.map +0 -1
  178. package/dist/tools/office/excel-tools/comments.d.ts.map +0 -1
  179. package/dist/tools/office/excel-tools/comments.js.map +0 -1
  180. package/dist/tools/office/excel-tools/data-ops.d.ts.map +0 -1
  181. package/dist/tools/office/excel-tools/data-ops.js.map +0 -1
  182. package/dist/tools/office/excel-tools/export.d.ts.map +0 -1
  183. package/dist/tools/office/excel-tools/export.js.map +0 -1
  184. package/dist/tools/office/excel-tools/formatting.d.ts.map +0 -1
  185. package/dist/tools/office/excel-tools/formatting.js.map +0 -1
  186. package/dist/tools/office/excel-tools/index.d.ts.map +0 -1
  187. package/dist/tools/office/excel-tools/index.js.map +0 -1
  188. package/dist/tools/office/excel-tools/launch.d.ts.map +0 -1
  189. package/dist/tools/office/excel-tools/launch.js.map +0 -1
  190. package/dist/tools/office/excel-tools/media.d.ts.map +0 -1
  191. package/dist/tools/office/excel-tools/media.js.map +0 -1
  192. package/dist/tools/office/excel-tools/named-ranges.d.ts.map +0 -1
  193. package/dist/tools/office/excel-tools/named-ranges.js.map +0 -1
  194. package/dist/tools/office/excel-tools/protection.d.ts.map +0 -1
  195. package/dist/tools/office/excel-tools/protection.js.map +0 -1
  196. package/dist/tools/office/excel-tools/rows-columns.d.ts.map +0 -1
  197. package/dist/tools/office/excel-tools/rows-columns.js.map +0 -1
  198. package/dist/tools/office/excel-tools/sheets.d.ts.map +0 -1
  199. package/dist/tools/office/excel-tools/sheets.js.map +0 -1
  200. package/dist/tools/office/excel-tools/validation.d.ts.map +0 -1
  201. package/dist/tools/office/excel-tools/validation.js.map +0 -1
  202. package/dist/tools/office/excel-tools.d.ts.map +0 -1
  203. package/dist/tools/office/excel-tools.js.map +0 -1
  204. package/dist/tools/office/index.d.ts.map +0 -1
  205. package/dist/tools/office/index.js.map +0 -1
  206. package/dist/tools/office/office-client-base.d.ts.map +0 -1
  207. package/dist/tools/office/office-client-base.js.map +0 -1
  208. package/dist/tools/office/office-client.d.ts.map +0 -1
  209. package/dist/tools/office/office-client.js.map +0 -1
  210. package/dist/tools/office/powerpoint-client.d.ts.map +0 -1
  211. package/dist/tools/office/powerpoint-client.js.map +0 -1
  212. package/dist/tools/office/powerpoint-tools/effects.d.ts.map +0 -1
  213. package/dist/tools/office/powerpoint-tools/effects.js.map +0 -1
  214. package/dist/tools/office/powerpoint-tools/export.d.ts.map +0 -1
  215. package/dist/tools/office/powerpoint-tools/export.js.map +0 -1
  216. package/dist/tools/office/powerpoint-tools/index.d.ts.map +0 -1
  217. package/dist/tools/office/powerpoint-tools/index.js.map +0 -1
  218. package/dist/tools/office/powerpoint-tools/launch.d.ts.map +0 -1
  219. package/dist/tools/office/powerpoint-tools/launch.js.map +0 -1
  220. package/dist/tools/office/powerpoint-tools/media.d.ts.map +0 -1
  221. package/dist/tools/office/powerpoint-tools/media.js.map +0 -1
  222. package/dist/tools/office/powerpoint-tools/notes.d.ts.map +0 -1
  223. package/dist/tools/office/powerpoint-tools/notes.js.map +0 -1
  224. package/dist/tools/office/powerpoint-tools/sections.d.ts.map +0 -1
  225. package/dist/tools/office/powerpoint-tools/sections.js.map +0 -1
  226. package/dist/tools/office/powerpoint-tools/shapes.d.ts.map +0 -1
  227. package/dist/tools/office/powerpoint-tools/shapes.js.map +0 -1
  228. package/dist/tools/office/powerpoint-tools/slides.d.ts.map +0 -1
  229. package/dist/tools/office/powerpoint-tools/slides.js.map +0 -1
  230. package/dist/tools/office/powerpoint-tools/tables.d.ts.map +0 -1
  231. package/dist/tools/office/powerpoint-tools/tables.js.map +0 -1
  232. package/dist/tools/office/powerpoint-tools/text.d.ts.map +0 -1
  233. package/dist/tools/office/powerpoint-tools/text.js.map +0 -1
  234. package/dist/tools/office/powerpoint-tools.d.ts.map +0 -1
  235. package/dist/tools/office/powerpoint-tools.js.map +0 -1
  236. package/dist/tools/office/word-client.d.ts.map +0 -1
  237. package/dist/tools/office/word-client.js.map +0 -1
  238. package/dist/tools/office/word-tools/bookmarks.d.ts.map +0 -1
  239. package/dist/tools/office/word-tools/bookmarks.js.map +0 -1
  240. package/dist/tools/office/word-tools/comments.d.ts.map +0 -1
  241. package/dist/tools/office/word-tools/comments.js.map +0 -1
  242. package/dist/tools/office/word-tools/content.d.ts.map +0 -1
  243. package/dist/tools/office/word-tools/content.js.map +0 -1
  244. package/dist/tools/office/word-tools/export.d.ts.map +0 -1
  245. package/dist/tools/office/word-tools/export.js.map +0 -1
  246. package/dist/tools/office/word-tools/formatting.d.ts.map +0 -1
  247. package/dist/tools/office/word-tools/formatting.js.map +0 -1
  248. package/dist/tools/office/word-tools/headers-footers.d.ts.map +0 -1
  249. package/dist/tools/office/word-tools/headers-footers.js.map +0 -1
  250. package/dist/tools/office/word-tools/index.d.ts.map +0 -1
  251. package/dist/tools/office/word-tools/index.js.map +0 -1
  252. package/dist/tools/office/word-tools/launch.d.ts.map +0 -1
  253. package/dist/tools/office/word-tools/launch.js.map +0 -1
  254. package/dist/tools/office/word-tools/lists.d.ts.map +0 -1
  255. package/dist/tools/office/word-tools/lists.js.map +0 -1
  256. package/dist/tools/office/word-tools/navigation.d.ts.map +0 -1
  257. package/dist/tools/office/word-tools/navigation.js.map +0 -1
  258. package/dist/tools/office/word-tools/page-setup.d.ts.map +0 -1
  259. package/dist/tools/office/word-tools/page-setup.js.map +0 -1
  260. package/dist/tools/office/word-tools/tables.d.ts.map +0 -1
  261. package/dist/tools/office/word-tools/tables.js.map +0 -1
  262. package/dist/tools/office/word-tools/text.d.ts.map +0 -1
  263. package/dist/tools/office/word-tools/text.js.map +0 -1
  264. package/dist/tools/office/word-tools/undo-redo.d.ts.map +0 -1
  265. package/dist/tools/office/word-tools/undo-redo.js.map +0 -1
  266. package/dist/tools/office/word-tools/watermarks.d.ts.map +0 -1
  267. package/dist/tools/office/word-tools/watermarks.js.map +0 -1
  268. package/dist/tools/office/word-tools.d.ts.map +0 -1
  269. package/dist/tools/office/word-tools.js.map +0 -1
  270. package/dist/tools/registry.d.ts.map +0 -1
  271. package/dist/tools/registry.js.map +0 -1
  272. package/dist/tools/types.d.ts.map +0 -1
  273. package/dist/tools/types.js.map +0 -1
  274. package/dist/types/index.d.ts.map +0 -1
  275. package/dist/types/index.js.map +0 -1
  276. package/dist/ui/PlanExecuteView.d.ts.map +0 -1
  277. package/dist/ui/PlanExecuteView.js.map +0 -1
  278. package/dist/ui/TodoPanel.d.ts.map +0 -1
  279. package/dist/ui/TodoPanel.js.map +0 -1
  280. package/dist/ui/UpdateNotification.d.ts.map +0 -1
  281. package/dist/ui/UpdateNotification.js.map +0 -1
  282. package/dist/ui/components/ActivityIndicator.d.ts.map +0 -1
  283. package/dist/ui/components/ActivityIndicator.js.map +0 -1
  284. package/dist/ui/components/CommandBrowser.d.ts.map +0 -1
  285. package/dist/ui/components/CommandBrowser.js.map +0 -1
  286. package/dist/ui/components/CustomTextInput.d.ts.map +0 -1
  287. package/dist/ui/components/CustomTextInput.js.map +0 -1
  288. package/dist/ui/components/DocsSearchProgress.d.ts.map +0 -1
  289. package/dist/ui/components/DocsSearchProgress.js.map +0 -1
  290. package/dist/ui/components/FileBrowser.d.ts.map +0 -1
  291. package/dist/ui/components/FileBrowser.js.map +0 -1
  292. package/dist/ui/components/LLMSetupWizard.d.ts.map +0 -1
  293. package/dist/ui/components/LLMSetupWizard.js.map +0 -1
  294. package/dist/ui/components/Logo.d.ts.map +0 -1
  295. package/dist/ui/components/Logo.js.map +0 -1
  296. package/dist/ui/components/MarkdownRenderer.d.ts.map +0 -1
  297. package/dist/ui/components/MarkdownRenderer.js.map +0 -1
  298. package/dist/ui/components/ModelSelector.d.ts.map +0 -1
  299. package/dist/ui/components/ModelSelector.js.map +0 -1
  300. package/dist/ui/components/PlanExecuteApp.d.ts.map +0 -1
  301. package/dist/ui/components/PlanExecuteApp.js.map +0 -1
  302. package/dist/ui/components/ProgressBar.d.ts.map +0 -1
  303. package/dist/ui/components/ProgressBar.js.map +0 -1
  304. package/dist/ui/components/StatusBar.d.ts.map +0 -1
  305. package/dist/ui/components/StatusBar.js.map +0 -1
  306. package/dist/ui/components/ThinkingIndicator.d.ts.map +0 -1
  307. package/dist/ui/components/ThinkingIndicator.js.map +0 -1
  308. package/dist/ui/components/TodoListView.d.ts.map +0 -1
  309. package/dist/ui/components/TodoListView.js.map +0 -1
  310. package/dist/ui/components/ToolSelector.d.ts.map +0 -1
  311. package/dist/ui/components/ToolSelector.js.map +0 -1
  312. package/dist/ui/components/dialogs/ApprovalDialog.d.ts.map +0 -1
  313. package/dist/ui/components/dialogs/ApprovalDialog.js.map +0 -1
  314. package/dist/ui/components/dialogs/AskUserDialog.d.ts.map +0 -1
  315. package/dist/ui/components/dialogs/AskUserDialog.js.map +0 -1
  316. package/dist/ui/components/dialogs/DocsBrowser.d.ts.map +0 -1
  317. package/dist/ui/components/dialogs/DocsBrowser.js.map +0 -1
  318. package/dist/ui/components/dialogs/SettingsDialog.d.ts.map +0 -1
  319. package/dist/ui/components/dialogs/SettingsDialog.js.map +0 -1
  320. package/dist/ui/components/dialogs/index.d.ts.map +0 -1
  321. package/dist/ui/components/dialogs/index.js.map +0 -1
  322. package/dist/ui/components/index.d.ts.map +0 -1
  323. package/dist/ui/components/index.js.map +0 -1
  324. package/dist/ui/components/panels/LogPanel.d.ts.map +0 -1
  325. package/dist/ui/components/panels/LogPanel.js.map +0 -1
  326. package/dist/ui/components/panels/SessionPanel.d.ts.map +0 -1
  327. package/dist/ui/components/panels/SessionPanel.js.map +0 -1
  328. package/dist/ui/components/panels/index.d.ts.map +0 -1
  329. package/dist/ui/components/panels/index.js.map +0 -1
  330. package/dist/ui/components/views/ChatView.d.ts.map +0 -1
  331. package/dist/ui/components/views/ChatView.js.map +0 -1
  332. package/dist/ui/components/views/index.d.ts.map +0 -1
  333. package/dist/ui/components/views/index.js.map +0 -1
  334. package/dist/ui/contexts/TokenContext.d.ts.map +0 -1
  335. package/dist/ui/contexts/TokenContext.js.map +0 -1
  336. package/dist/ui/hooks/atFileProcessor.d.ts.map +0 -1
  337. package/dist/ui/hooks/atFileProcessor.js.map +0 -1
  338. package/dist/ui/hooks/index.d.ts.map +0 -1
  339. package/dist/ui/hooks/index.js.map +0 -1
  340. package/dist/ui/hooks/slashCommandProcessor.d.ts.map +0 -1
  341. package/dist/ui/hooks/slashCommandProcessor.js.map +0 -1
  342. package/dist/ui/hooks/useCommandBrowserState.d.ts.map +0 -1
  343. package/dist/ui/hooks/useCommandBrowserState.js.map +0 -1
  344. package/dist/ui/hooks/useFileBrowserState.d.ts.map +0 -1
  345. package/dist/ui/hooks/useFileBrowserState.js.map +0 -1
  346. package/dist/ui/hooks/useFileList.d.ts.map +0 -1
  347. package/dist/ui/hooks/useFileList.js.map +0 -1
  348. package/dist/ui/hooks/useInputHistory.d.ts.map +0 -1
  349. package/dist/ui/hooks/useInputHistory.js.map +0 -1
  350. package/dist/ui/hooks/usePlanExecution.d.ts.map +0 -1
  351. package/dist/ui/hooks/usePlanExecution.js.map +0 -1
  352. package/dist/ui/index.d.ts.map +0 -1
  353. package/dist/ui/index.js.map +0 -1
  354. package/dist/ui/ink-entry.d.ts.map +0 -1
  355. package/dist/ui/ink-entry.js.map +0 -1
  356. package/dist/utils/env-filter.d.ts.map +0 -1
  357. package/dist/utils/env-filter.js.map +0 -1
  358. package/dist/utils/file-system.d.ts.map +0 -1
  359. package/dist/utils/file-system.js.map +0 -1
  360. package/dist/utils/git-utils.d.ts.map +0 -1
  361. package/dist/utils/git-utils.js.map +0 -1
  362. package/dist/utils/json-stream-logger.d.ts.map +0 -1
  363. package/dist/utils/json-stream-logger.js.map +0 -1
  364. package/dist/utils/logger.d.ts.map +0 -1
  365. package/dist/utils/logger.js.map +0 -1
  366. package/dist/utils/platform-utils.d.ts.map +0 -1
  367. package/dist/utils/platform-utils.js.map +0 -1
  368. package/dist/utils/wsl-utils.d.ts.map +0 -1
  369. package/dist/utils/wsl-utils.js.map +0 -1
  370. package/electron.vite.config.ts +0 -63
  371. package/google374b9eba0c52b043.html +0 -1
  372. package/src/agents/base/base-agent.ts +0 -159
  373. package/src/agents/docs-search/index.ts +0 -365
  374. package/src/agents/index.ts +0 -34
  375. package/src/agents/planner/index.ts +0 -544
  376. package/src/cli.ts +0 -201
  377. package/src/constants.ts +0 -47
  378. package/src/core/compact/compact-manager.ts +0 -160
  379. package/src/core/compact/compact-prompts.ts +0 -150
  380. package/src/core/compact/context-tracker.ts +0 -164
  381. package/src/core/compact/index.ts +0 -25
  382. package/src/core/config/config-manager.ts +0 -460
  383. package/src/core/config/index.ts +0 -5
  384. package/src/core/docs-manager.ts +0 -678
  385. package/src/core/llm/index.ts +0 -7
  386. package/src/core/llm/llm-client.ts +0 -1550
  387. package/src/core/session/index.ts +0 -5
  388. package/src/core/session/session-manager.ts +0 -464
  389. package/src/core/slash-command-handler.ts +0 -410
  390. package/src/core/usage-tracker.ts +0 -438
  391. package/src/errors/base.ts +0 -81
  392. package/src/errors/file.ts +0 -183
  393. package/src/errors/index.ts +0 -95
  394. package/src/errors/llm.ts +0 -151
  395. package/src/errors/network.ts +0 -124
  396. package/src/errors/validation.ts +0 -111
  397. package/src/eval/eval-runner.ts +0 -456
  398. package/src/eval/index.ts +0 -8
  399. package/src/eval/types.ts +0 -139
  400. package/src/index.ts +0 -22
  401. package/src/orchestration/index.ts +0 -30
  402. package/src/orchestration/plan-executor.ts +0 -652
  403. package/src/orchestration/types.ts +0 -127
  404. package/src/orchestration/utils.ts +0 -119
  405. package/src/orquesta/connection.ts +0 -291
  406. package/src/prompts/agents/docs-search-decision.ts +0 -74
  407. package/src/prompts/agents/docs-search.ts +0 -84
  408. package/src/prompts/agents/planning.ts +0 -143
  409. package/src/prompts/index.ts +0 -31
  410. package/src/prompts/shared/codebase-rules.ts +0 -29
  411. package/src/prompts/shared/git-rules.ts +0 -94
  412. package/src/prompts/shared/language-rules.ts +0 -36
  413. package/src/prompts/shared/tool-usage.ts +0 -72
  414. package/src/prompts/system/compact.ts +0 -80
  415. package/src/prompts/system/plan-execute.ts +0 -89
  416. package/src/tools/browser/browser-client.ts +0 -1363
  417. package/src/tools/browser/browser-tools.ts +0 -1139
  418. package/src/tools/browser/index.ts +0 -65
  419. package/src/tools/index.ts +0 -23
  420. package/src/tools/llm/agents/docs-search-tools.ts +0 -368
  421. package/src/tools/llm/agents/index.ts +0 -22
  422. package/src/tools/llm/index.ts +0 -11
  423. package/src/tools/llm/simple/ask-user-tool.ts +0 -25
  424. package/src/tools/llm/simple/background-bash-tool.ts +0 -443
  425. package/src/tools/llm/simple/background-powershell-tool.ts +0 -421
  426. package/src/tools/llm/simple/bash-tool.ts +0 -238
  427. package/src/tools/llm/simple/docs-search-agent-tool.ts +0 -146
  428. package/src/tools/llm/simple/file-tools.ts +0 -1051
  429. package/src/tools/llm/simple/final-response-tool.ts +0 -180
  430. package/src/tools/llm/simple/index.ts +0 -42
  431. package/src/tools/llm/simple/planning-tools.ts +0 -143
  432. package/src/tools/llm/simple/powershell-tool.ts +0 -241
  433. package/src/tools/llm/simple/simple-tool-executor.ts +0 -279
  434. package/src/tools/llm/simple/todo-tools.ts +0 -207
  435. package/src/tools/llm/simple/user-interaction-tools.ts +0 -277
  436. package/src/tools/office/common/constants.ts +0 -335
  437. package/src/tools/office/common/index.ts +0 -133
  438. package/src/tools/office/common/types.ts +0 -286
  439. package/src/tools/office/common/utils.ts +0 -116
  440. package/src/tools/office/excel-client.ts +0 -1336
  441. package/src/tools/office/excel-tools/cells.ts +0 -359
  442. package/src/tools/office/excel-tools/charts.ts +0 -166
  443. package/src/tools/office/excel-tools/comments.ts +0 -155
  444. package/src/tools/office/excel-tools/data-ops.ts +0 -349
  445. package/src/tools/office/excel-tools/export.ts +0 -105
  446. package/src/tools/office/excel-tools/formatting.ts +0 -357
  447. package/src/tools/office/excel-tools/index.ts +0 -55
  448. package/src/tools/office/excel-tools/launch.ts +0 -303
  449. package/src/tools/office/excel-tools/media.ts +0 -117
  450. package/src/tools/office/excel-tools/named-ranges.ts +0 -148
  451. package/src/tools/office/excel-tools/protection.ts +0 -105
  452. package/src/tools/office/excel-tools/rows-columns.ts +0 -386
  453. package/src/tools/office/excel-tools/sheets.ts +0 -228
  454. package/src/tools/office/excel-tools/validation.ts +0 -226
  455. package/src/tools/office/excel-tools.ts +0 -9
  456. package/src/tools/office/index.ts +0 -259
  457. package/src/tools/office/office-client-base.ts +0 -242
  458. package/src/tools/office/office-client.ts +0 -377
  459. package/src/tools/office/powerpoint-client.ts +0 -1498
  460. package/src/tools/office/powerpoint-tools/effects.ts +0 -315
  461. package/src/tools/office/powerpoint-tools/export.ts +0 -138
  462. package/src/tools/office/powerpoint-tools/index.ts +0 -45
  463. package/src/tools/office/powerpoint-tools/launch.ts +0 -263
  464. package/src/tools/office/powerpoint-tools/media.ts +0 -291
  465. package/src/tools/office/powerpoint-tools/notes.ts +0 -220
  466. package/src/tools/office/powerpoint-tools/sections.ts +0 -140
  467. package/src/tools/office/powerpoint-tools/shapes.ts +0 -870
  468. package/src/tools/office/powerpoint-tools/slides.ts +0 -350
  469. package/src/tools/office/powerpoint-tools/tables.ts +0 -182
  470. package/src/tools/office/powerpoint-tools/text.ts +0 -473
  471. package/src/tools/office/powerpoint-tools.ts +0 -9
  472. package/src/tools/office/word-client.ts +0 -1697
  473. package/src/tools/office/word-tools/bookmarks.ts +0 -186
  474. package/src/tools/office/word-tools/comments.ts +0 -185
  475. package/src/tools/office/word-tools/content.ts +0 -229
  476. package/src/tools/office/word-tools/export.ts +0 -97
  477. package/src/tools/office/word-tools/formatting.ts +0 -161
  478. package/src/tools/office/word-tools/headers-footers.ts +0 -155
  479. package/src/tools/office/word-tools/index.ts +0 -57
  480. package/src/tools/office/word-tools/launch.ts +0 -312
  481. package/src/tools/office/word-tools/lists.ts +0 -97
  482. package/src/tools/office/word-tools/navigation.ts +0 -114
  483. package/src/tools/office/word-tools/page-setup.ts +0 -195
  484. package/src/tools/office/word-tools/tables.ts +0 -262
  485. package/src/tools/office/word-tools/text.ts +0 -294
  486. package/src/tools/office/word-tools/undo-redo.ts +0 -97
  487. package/src/tools/office/word-tools/watermarks.ts +0 -105
  488. package/src/tools/office/word-tools.ts +0 -9
  489. package/src/tools/registry.ts +0 -527
  490. package/src/tools/types.ts +0 -231
  491. package/src/types/index.ts +0 -181
  492. package/src/ui/PlanExecuteView.tsx +0 -119
  493. package/src/ui/TodoPanel.tsx +0 -240
  494. package/src/ui/UpdateNotification.tsx +0 -105
  495. package/src/ui/components/ActivityIndicator.tsx +0 -234
  496. package/src/ui/components/CommandBrowser.tsx +0 -114
  497. package/src/ui/components/CustomTextInput.tsx +0 -389
  498. package/src/ui/components/DocsSearchProgress.tsx +0 -85
  499. package/src/ui/components/FileBrowser.tsx +0 -93
  500. package/src/ui/components/LLMSetupWizard.tsx +0 -333
  501. package/src/ui/components/Logo.tsx +0 -125
  502. package/src/ui/components/MarkdownRenderer.tsx +0 -358
  503. package/src/ui/components/ModelSelector.tsx +0 -203
  504. package/src/ui/components/PlanExecuteApp.tsx +0 -2007
  505. package/src/ui/components/ProgressBar.tsx +0 -51
  506. package/src/ui/components/StatusBar.tsx +0 -302
  507. package/src/ui/components/ThinkingIndicator.tsx +0 -120
  508. package/src/ui/components/TodoListView.tsx +0 -140
  509. package/src/ui/components/ToolSelector.tsx +0 -215
  510. package/src/ui/components/dialogs/ApprovalDialog.tsx +0 -259
  511. package/src/ui/components/dialogs/AskUserDialog.tsx +0 -159
  512. package/src/ui/components/dialogs/DocsBrowser.tsx +0 -222
  513. package/src/ui/components/dialogs/SettingsDialog.tsx +0 -939
  514. package/src/ui/components/dialogs/index.ts +0 -13
  515. package/src/ui/components/index.ts +0 -27
  516. package/src/ui/components/panels/LogPanel.tsx +0 -385
  517. package/src/ui/components/panels/SessionPanel.tsx +0 -146
  518. package/src/ui/components/panels/index.ts +0 -13
  519. package/src/ui/components/views/ChatView.tsx +0 -447
  520. package/src/ui/components/views/index.ts +0 -5
  521. package/src/ui/contexts/TokenContext.tsx +0 -139
  522. package/src/ui/hooks/atFileProcessor.ts +0 -167
  523. package/src/ui/hooks/index.ts +0 -11
  524. package/src/ui/hooks/slashCommandProcessor.ts +0 -174
  525. package/src/ui/hooks/useCommandBrowserState.ts +0 -97
  526. package/src/ui/hooks/useFileBrowserState.ts +0 -116
  527. package/src/ui/hooks/useFileList.ts +0 -132
  528. package/src/ui/hooks/useInputHistory.ts +0 -89
  529. package/src/ui/hooks/usePlanExecution.ts +0 -339
  530. package/src/ui/index.ts +0 -10
  531. package/src/ui/ink-entry.tsx +0 -36
  532. package/src/utils/env-filter.ts +0 -164
  533. package/src/utils/file-system.ts +0 -133
  534. package/src/utils/git-utils.ts +0 -30
  535. package/src/utils/json-stream-logger.ts +0 -1259
  536. package/src/utils/logger.ts +0 -2767
  537. package/src/utils/platform-utils.ts +0 -256
  538. package/src/utils/wsl-utils.ts +0 -113
  539. package/tsconfig.electron.json +0 -39
  540. package/tsconfig.json +0 -64
@@ -1,1498 +0,0 @@
1
- /**
2
- * PowerPoint Client
3
- *
4
- * Microsoft PowerPoint automation via PowerShell COM.
5
- * Extends OfficeClientBase with PowerPoint-specific operations.
6
- */
7
-
8
- import { OfficeClientBase, OfficeResponse, ScreenshotResponse } from './office-client-base.js';
9
-
10
- export class PowerPointClient extends OfficeClientBase {
11
- async powerpointLaunch(): Promise<OfficeResponse> {
12
- return this.executePowerShell(`
13
- try {
14
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
15
- @{ success = $true; message = "Connected to existing PowerPoint instance" } | ConvertTo-Json -Compress
16
- } catch {
17
- $ppt = New-Object -ComObject PowerPoint.Application
18
- # PowerPoint needs a presentation to be visible
19
- @{ success = $true; message = "Launched new PowerPoint instance" } | ConvertTo-Json -Compress
20
- }
21
- `);
22
- }
23
-
24
- async powerpointCreate(): Promise<OfficeResponse> {
25
- return this.executePowerShell(`
26
- try {
27
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
28
- } catch {
29
- $ppt = New-Object -ComObject PowerPoint.Application
30
- }
31
- # Add presentation with window (msoTrue = -1)
32
- $presentation = $ppt.Presentations.Add(-1)
33
- @{ success = $true; message = "Created new presentation"; presentation_name = $presentation.Name } | ConvertTo-Json -Compress
34
- `);
35
- }
36
-
37
- async powerpointOpen(filePath: string): Promise<OfficeResponse> {
38
- const windowsPath = this.toWindowsPath(filePath).replace(/'/g, "''");
39
- return this.executePowerShell(`
40
- try {
41
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
42
- } catch {
43
- $ppt = New-Object -ComObject PowerPoint.Application
44
- }
45
- $presentation = $ppt.Presentations.Open('${windowsPath}')
46
- @{ success = $true; message = "Presentation opened"; presentation_name = $presentation.Name; path = $presentation.FullName } | ConvertTo-Json -Compress
47
- `);
48
- }
49
-
50
- async powerpointAddSlide(layout: number = 1): Promise<OfficeResponse> {
51
- // Layout: 1=Title Slide, 2=Title and Content, 3=Section Header, 4=Two Content, etc.
52
- return this.executePowerShell(`
53
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
54
- $presentation = $ppt.ActivePresentation
55
- $slideCount = $presentation.Slides.Count
56
- $customLayout = $presentation.SlideMaster.CustomLayouts(${layout})
57
- $slide = $presentation.Slides.AddSlide($slideCount + 1, $customLayout)
58
- @{ success = $true; message = "Slide added"; slide_number = $slide.SlideIndex; layout = ${layout} } | ConvertTo-Json -Compress
59
- `);
60
- }
61
-
62
- async powerpointDeleteSlide(slideNumber: number): Promise<OfficeResponse> {
63
- return this.executePowerShell(`
64
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
65
- $presentation = $ppt.ActivePresentation
66
- $presentation.Slides(${slideNumber}).Delete()
67
- @{ success = $true; message = "Slide ${slideNumber} deleted" } | ConvertTo-Json -Compress
68
- `);
69
- }
70
-
71
- async powerpointMoveSlide(fromIndex: number, toIndex: number): Promise<OfficeResponse> {
72
- return this.executePowerShell(`
73
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
74
- $presentation = $ppt.ActivePresentation
75
- $presentation.Slides(${fromIndex}).MoveTo(${toIndex})
76
- @{ success = $true; message = "Slide moved from ${fromIndex} to ${toIndex}" } | ConvertTo-Json -Compress
77
- `);
78
- }
79
-
80
- async powerpointWriteText(
81
- slideNumber: number,
82
- shapeIndex: number,
83
- text: string,
84
- options?: { fontName?: string; fontSize?: number; bold?: boolean }
85
- ): Promise<OfficeResponse> {
86
- const escapedText = text.replace(/'/g, "''");
87
-
88
- // Auto-detect Korean and set font
89
- const hasKorean = /[가-힣ㄱ-ㅎㅏ-ㅣ]/.test(text);
90
- const fontName = options?.fontName || (hasKorean ? 'Malgun Gothic' : '');
91
-
92
- // TEXT FIRST, FONT AFTER pattern (Microsoft recommended for Korean)
93
- const fontCommands: string[] = [];
94
- if (fontName) fontCommands.push(`$textRange.Font.Name = '${fontName.replace(/'/g, "''")}'`);
95
- if (options?.fontSize) fontCommands.push(`$textRange.Font.Size = ${options.fontSize}`);
96
- if (options?.bold !== undefined) fontCommands.push(`$textRange.Font.Bold = ${options.bold ? '-1' : '0'}`);
97
-
98
- return this.executePowerShell(`
99
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
100
- $presentation = $ppt.ActivePresentation
101
- $slide = $presentation.Slides(${slideNumber})
102
- $shape = $slide.Shapes(${shapeIndex})
103
- $textRange = $shape.TextFrame.TextRange
104
- $textContent = '${escapedText}' -replace '\\\\n', [char]10 -replace '\\n', [char]10
105
- $textRange.Text = $textContent
106
- ${fontCommands.join('\n')}
107
- @{ success = $true; message = "Text written to slide ${slideNumber}, shape ${shapeIndex}" } | ConvertTo-Json -Compress
108
- `);
109
- }
110
-
111
- async powerpointReadSlide(slideNumber: number): Promise<OfficeResponse> {
112
- return this.executePowerShell(`
113
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
114
- $presentation = $ppt.ActivePresentation
115
- $slide = $presentation.Slides(${slideNumber})
116
- $texts = @()
117
- foreach ($shape in $slide.Shapes) {
118
- if ($shape.HasTextFrame -eq -1) {
119
- $texts += @{
120
- shape_index = $shape.Index
121
- shape_name = $shape.Name
122
- text = $shape.TextFrame.TextRange.Text
123
- }
124
- }
125
- }
126
- @{
127
- success = $true
128
- slide_number = ${slideNumber}
129
- shape_count = $slide.Shapes.Count
130
- texts = $texts
131
- } | ConvertTo-Json -Compress -Depth 5
132
- `);
133
- }
134
-
135
- async powerpointAddTextbox(
136
- slideNumber: number,
137
- text: string,
138
- left: number = 100,
139
- top: number = 100,
140
- width: number = 300,
141
- height: number = 50
142
- ): Promise<OfficeResponse> {
143
- const escapedText = text.replace(/'/g, "''");
144
-
145
- // Auto-detect Korean and set font
146
- const hasKorean = /[가-힣ㄱ-ㅎㅏ-ㅣ]/.test(text);
147
- const fontScript = hasKorean ? "$textbox.TextFrame.TextRange.Font.Name = 'Malgun Gothic'" : '';
148
-
149
- // TEXT FIRST, FONT AFTER pattern (Microsoft recommended for Korean)
150
- return this.executePowerShell(`
151
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
152
- $presentation = $ppt.ActivePresentation
153
- $slide = $presentation.Slides(${slideNumber})
154
- # msoTextOrientationHorizontal = 1
155
- $textbox = $slide.Shapes.AddTextbox(1, ${left}, ${top}, ${width}, ${height})
156
- $textContent = '${escapedText}' -replace '\\\\n', [char]10 -replace '\\n', [char]10
157
- $textbox.TextFrame.TextRange.Text = $textContent
158
- ${fontScript}
159
- @{ success = $true; message = "Textbox added to slide ${slideNumber}"; shape_index = $textbox.Index } | ConvertTo-Json -Compress
160
- `);
161
- }
162
-
163
- async powerpointSetFont(
164
- slideNumber: number,
165
- shapeIndex: number,
166
- options: {
167
- fontName?: string;
168
- fontSize?: number;
169
- bold?: boolean;
170
- italic?: boolean;
171
- color?: string;
172
- }
173
- ): Promise<OfficeResponse> {
174
- const commands: string[] = [];
175
- if (options.fontName) commands.push(`$textRange.Font.Name = '${options.fontName.replace(/'/g, "''")}'`);
176
- if (options.fontSize) commands.push(`$textRange.Font.Size = ${options.fontSize}`);
177
- if (options.bold !== undefined) commands.push(`$textRange.Font.Bold = ${options.bold ? '-1' : '0'}`);
178
- if (options.italic !== undefined) commands.push(`$textRange.Font.Italic = ${options.italic ? '-1' : '0'}`);
179
- if (options.color) {
180
- const rgb = this.hexToRgb(options.color);
181
- if (rgb) commands.push(`$textRange.Font.Color.RGB = ${rgb.r + rgb.g * 256 + rgb.b * 65536}`);
182
- }
183
-
184
- return this.executePowerShell(`
185
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
186
- $presentation = $ppt.ActivePresentation
187
- $slide = $presentation.Slides(${slideNumber})
188
- $shape = $slide.Shapes(${shapeIndex})
189
- $textRange = $shape.TextFrame.TextRange
190
- ${commands.join('\n')}
191
- @{ success = $true; message = "Font set for slide ${slideNumber}, shape ${shapeIndex}" } | ConvertTo-Json -Compress
192
- `);
193
- }
194
-
195
- async powerpointAddImage(
196
- slideNumber: number,
197
- imagePath: string,
198
- left: number = 100,
199
- top: number = 100,
200
- width?: number,
201
- height?: number
202
- ): Promise<OfficeResponse> {
203
- const windowsPath = this.toWindowsPath(imagePath).replace(/'/g, "''");
204
- const sizeScript = width !== undefined && height !== undefined
205
- ? `$shape.Width = ${width}; $shape.Height = ${height}`
206
- : '';
207
-
208
- return this.executePowerShell(`
209
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
210
- $presentation = $ppt.ActivePresentation
211
- $slide = $presentation.Slides(${slideNumber})
212
- $shape = $slide.Shapes.AddPicture('${windowsPath}', 0, -1, ${left}, ${top})
213
- ${sizeScript}
214
- @{ success = $true; message = "Image added to slide ${slideNumber}"; shape_index = $shape.Index } | ConvertTo-Json -Compress
215
- `);
216
- }
217
-
218
- async powerpointAddShape(
219
- slideNumber: number,
220
- shapeType: 'rectangle' | 'oval' | 'triangle' | 'arrow' | 'star',
221
- left: number,
222
- top: number,
223
- width: number,
224
- height: number,
225
- fillColor?: string
226
- ): Promise<OfficeResponse> {
227
- // msoShapeRectangle=1, msoShapeOval=9, msoShapeIsoscelesTriangle=7, msoShapeRightArrow=33, msoShape5pointStar=92
228
- const shapeTypeMap: Record<string, number> = {
229
- rectangle: 1,
230
- oval: 9,
231
- triangle: 7,
232
- arrow: 33,
233
- star: 92
234
- };
235
- const shapeTypeNum = shapeTypeMap[shapeType] || 1;
236
-
237
- let fillScript = '';
238
- if (fillColor) {
239
- const rgb = this.hexToRgb(fillColor);
240
- if (rgb) fillScript = `$shape.Fill.ForeColor.RGB = ${rgb.r + rgb.g * 256 + rgb.b * 65536}`;
241
- }
242
-
243
- return this.executePowerShell(`
244
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
245
- $presentation = $ppt.ActivePresentation
246
- $slide = $presentation.Slides(${slideNumber})
247
- $shape = $slide.Shapes.AddShape(${shapeTypeNum}, ${left}, ${top}, ${width}, ${height})
248
- ${fillScript}
249
- @{ success = $true; message = "${shapeType} shape added to slide ${slideNumber}"; shape_index = $shape.Index } | ConvertTo-Json -Compress
250
- `);
251
- }
252
-
253
- async powerpointAddAnimation(
254
- slideNumber: number,
255
- shapeIndex: number,
256
- effect: string = 'fade',
257
- trigger: string = 'on_click'
258
- ): Promise<OfficeResponse> {
259
- // Effect types: fade=3844, appear=3844, fly_in=3844, zoom=3845, wipe=3844
260
- const effectMap: Record<string, number> = {
261
- fade: 3844,
262
- appear: 1,
263
- fly_in: 3844,
264
- zoom: 3845,
265
- wipe: 22
266
- };
267
- // Trigger: on_click=1, with_previous=2, after_previous=3
268
- const triggerMap: Record<string, number> = {
269
- on_click: 1,
270
- with_previous: 2,
271
- after_previous: 3
272
- };
273
-
274
- return this.executePowerShell(`
275
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
276
- $presentation = $ppt.ActivePresentation
277
- $slide = $presentation.Slides(${slideNumber})
278
- $shape = $slide.Shapes(${shapeIndex})
279
- $effect = $slide.TimeLine.MainSequence.AddEffect($shape, ${effectMap[effect] || 3844}, 0, ${triggerMap[trigger] || 1})
280
- @{ success = $true; message = "Animation '${effect}' added to shape ${shapeIndex}" } | ConvertTo-Json -Compress
281
- `);
282
- }
283
-
284
- async powerpointSetTransition(
285
- slideNumber: number,
286
- transitionType: 'fade' | 'push' | 'wipe' | 'split' | 'reveal' | 'random' = 'fade',
287
- duration: number = 1
288
- ): Promise<OfficeResponse> {
289
- // Transition entry effects
290
- const transitionMap: Record<string, number> = {
291
- fade: 3849,
292
- push: 3846,
293
- wipe: 3851,
294
- split: 3848,
295
- reveal: 3850,
296
- random: 0
297
- };
298
-
299
- return this.executePowerShell(`
300
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
301
- $presentation = $ppt.ActivePresentation
302
- $slide = $presentation.Slides(${slideNumber})
303
- $slide.SlideShowTransition.EntryEffect = ${transitionMap[transitionType]}
304
- $slide.SlideShowTransition.Duration = ${duration}
305
- @{ success = $true; message = "Transition '${transitionType}' set for slide ${slideNumber}" } | ConvertTo-Json -Compress
306
- `);
307
- }
308
-
309
- async powerpointSetBackground(
310
- slideNumber: number,
311
- options: { color?: string; imagePath?: string }
312
- ): Promise<OfficeResponse> {
313
- let bgScript = '';
314
- if (options.color) {
315
- const rgb = this.hexToRgb(options.color);
316
- if (rgb) {
317
- bgScript = `
318
- $slide.FollowMasterBackground = 0
319
- $slide.Background.Fill.Solid()
320
- $slide.Background.Fill.ForeColor.RGB = ${rgb.r + rgb.g * 256 + rgb.b * 65536}`;
321
- }
322
- } else if (options.imagePath) {
323
- const windowsPath = this.toWindowsPath(options.imagePath).replace(/'/g, "''");
324
- bgScript = `
325
- $slide.FollowMasterBackground = 0
326
- $slide.Background.Fill.UserPicture('${windowsPath}')`;
327
- }
328
-
329
- return this.executePowerShell(`
330
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
331
- $presentation = $ppt.ActivePresentation
332
- $slide = $presentation.Slides(${slideNumber})
333
- ${bgScript}
334
- @{ success = $true; message = "Background set for slide ${slideNumber}" } | ConvertTo-Json -Compress
335
- `);
336
- }
337
-
338
- async powerpointGetSlideCount(): Promise<OfficeResponse> {
339
- return this.executePowerShell(`
340
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
341
- $presentation = $ppt.ActivePresentation
342
- @{ success = $true; slide_count = $presentation.Slides.Count } | ConvertTo-Json -Compress
343
- `);
344
- }
345
-
346
- async powerpointSave(filePath?: string): Promise<OfficeResponse> {
347
- const windowsPath = filePath ? this.toWindowsPath(filePath).replace(/'/g, "''") : '';
348
- return this.executePowerShell(`
349
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
350
- $presentation = $ppt.ActivePresentation
351
- ${windowsPath ? `$presentation.SaveAs('${windowsPath}')` : '$presentation.Save()'}
352
- @{ success = $true; message = "Presentation saved"; path = $presentation.FullName } | ConvertTo-Json -Compress
353
- `);
354
- }
355
-
356
- async powerpointExportToPDF(outputPath: string): Promise<OfficeResponse> {
357
- const windowsPath = this.toWindowsPath(outputPath).replace(/'/g, "''");
358
- return this.executePowerShell(`
359
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
360
- $presentation = $ppt.ActivePresentation
361
- # ppSaveAsPDF = 32
362
- $presentation.SaveAs('${windowsPath}', 32)
363
- @{ success = $true; message = "Exported to PDF"; path = '${windowsPath}' } | ConvertTo-Json -Compress
364
- `);
365
- }
366
-
367
- async powerpointStartSlideshow(fromSlide: number = 1): Promise<OfficeResponse> {
368
- return this.executePowerShell(`
369
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
370
- $presentation = $ppt.ActivePresentation
371
- $settings = $presentation.SlideShowSettings
372
- $settings.StartingSlide = ${fromSlide}
373
- $settings.Run()
374
- @{ success = $true; message = "Slideshow started from slide ${fromSlide}" } | ConvertTo-Json -Compress
375
- `);
376
- }
377
-
378
- async powerpointClose(save: boolean = false): Promise<OfficeResponse> {
379
- return this.executePowerShell(`
380
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
381
- $presentation = $ppt.ActivePresentation
382
- ${save ? '$presentation.Save()' : ''}
383
- $presentation.Close()
384
- @{ success = $true; message = "Presentation closed" } | ConvertTo-Json -Compress
385
- `);
386
- }
387
-
388
- async powerpointQuit(save: boolean = false): Promise<OfficeResponse> {
389
- return this.executePowerShell(`
390
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
391
- ${save ? `
392
- foreach ($pres in $ppt.Presentations) {
393
- $pres.Save()
394
- }` : ''}
395
- $ppt.Quit()
396
- @{ success = $true; message = "PowerPoint closed" } | ConvertTo-Json -Compress
397
- `);
398
- }
399
-
400
- async powerpointScreenshot(): Promise<ScreenshotResponse> {
401
- const result = await this.executePowerShell(`
402
- Add-Type -AssemblyName System.Windows.Forms
403
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
404
- $presentation = $ppt.ActivePresentation
405
- $slide = $presentation.Slides($ppt.ActiveWindow.View.Slide.SlideIndex)
406
-
407
- # Export slide as image
408
- $tempPath = [System.IO.Path]::GetTempFileName() + ".png"
409
- $slide.Export($tempPath, "PNG")
410
-
411
- # Read and convert to base64
412
- $bytes = [System.IO.File]::ReadAllBytes($tempPath)
413
- $base64 = [Convert]::ToBase64String($bytes)
414
-
415
- # Clean up
416
- Remove-Item $tempPath -Force
417
-
418
- @{
419
- success = $true
420
- image = $base64
421
- format = "png"
422
- encoding = "base64"
423
- } | ConvertTo-Json -Compress
424
- `);
425
- return result as ScreenshotResponse;
426
- }
427
-
428
- // ===========================================================================
429
- // PowerPoint Advanced Features
430
- // ===========================================================================
431
-
432
- // -------------------------------------------------------------------------
433
- // Table Functions
434
- // -------------------------------------------------------------------------
435
-
436
- async powerpointAddTable(
437
- slideNumber: number,
438
- rows: number,
439
- cols: number,
440
- left: number = 100,
441
- top: number = 100,
442
- width: number = 400,
443
- height: number = 200,
444
- data?: string[][]
445
- ): Promise<OfficeResponse> {
446
- // TEXT FIRST, FONT AFTER pattern (Microsoft recommended for Korean)
447
- // Generate per-cell: text first, then font if Korean detected
448
- let dataScript = '';
449
-
450
- if (data) {
451
- const dataLines: string[] = [];
452
- for (let i = 0; i < data.length && i < rows; i++) {
453
- const row = data[i];
454
- if (!row) continue;
455
- for (let j = 0; j < row.length && j < cols; j++) {
456
- const cellValue = row[j];
457
- if (cellValue === undefined) continue;
458
- const val = cellValue.replace(/'/g, "''");
459
- const cellHasKorean = /[가-힣ㄱ-ㅎㅏ-ㅣ]/.test(cellValue);
460
- // 1. Text first
461
- dataLines.push(`$table.Cell(${i + 1}, ${j + 1}).Shape.TextFrame.TextRange.Text = '${val}'`);
462
- // 2. Font after (only if Korean)
463
- if (cellHasKorean) {
464
- dataLines.push(`$table.Cell(${i + 1}, ${j + 1}).Shape.TextFrame.TextRange.Font.Name = 'Malgun Gothic'`);
465
- }
466
- }
467
- }
468
- dataScript = dataLines.join('\n');
469
- }
470
-
471
- return this.executePowerShell(`
472
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
473
- $presentation = $ppt.ActivePresentation
474
- $slide = $presentation.Slides(${slideNumber})
475
- $table = $slide.Shapes.AddTable(${rows}, ${cols}, ${left}, ${top}, ${width}, ${height}).Table
476
- ${dataScript}
477
- @{ success = $true; message = "Table added with ${rows} rows and ${cols} columns"; shape_index = $slide.Shapes.Count } | ConvertTo-Json -Compress
478
- `);
479
- }
480
-
481
- async powerpointSetTableCell(
482
- slideNumber: number,
483
- shapeIndex: number,
484
- row: number,
485
- col: number,
486
- text: string,
487
- options?: { fontName?: string; fontSize?: number; bold?: boolean; fillColor?: string }
488
- ): Promise<OfficeResponse> {
489
- const escapedText = text.replace(/'/g, "''");
490
- const hasKorean = /[가-힣ㄱ-ㅎㅏ-ㅣ]/.test(text);
491
- const fontName = options?.fontName || (hasKorean ? 'Malgun Gothic' : '');
492
-
493
- // TEXT FIRST, FONT AFTER pattern (Microsoft recommended for Korean)
494
- const fontCommands: string[] = [];
495
- if (fontName) fontCommands.push(`$cell.Shape.TextFrame.TextRange.Font.Name = '${fontName}'`);
496
- if (options?.fontSize) fontCommands.push(`$cell.Shape.TextFrame.TextRange.Font.Size = ${options.fontSize}`);
497
- if (options?.bold !== undefined) fontCommands.push(`$cell.Shape.TextFrame.TextRange.Font.Bold = ${options.bold ? '-1' : '0'}`);
498
-
499
- const otherCommands: string[] = [];
500
- if (options?.fillColor) {
501
- const rgb = this.hexToRgb(options.fillColor);
502
- if (rgb) otherCommands.push(`$cell.Shape.Fill.ForeColor.RGB = ${rgb.r + rgb.g * 256 + rgb.b * 65536}`);
503
- }
504
-
505
- return this.executePowerShell(`
506
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
507
- $presentation = $ppt.ActivePresentation
508
- $slide = $presentation.Slides(${slideNumber})
509
- $table = $slide.Shapes(${shapeIndex}).Table
510
- $cell = $table.Cell(${row}, ${col})
511
- $textContent = '${escapedText}' -replace '\\\\n', [char]10 -replace '\\n', [char]10
512
- $cell.Shape.TextFrame.TextRange.Text = $textContent
513
- ${fontCommands.join('\n')}
514
- ${otherCommands.join('\n')}
515
- @{ success = $true; message = "Table cell (${row}, ${col}) updated" } | ConvertTo-Json -Compress
516
- `);
517
- }
518
-
519
- async powerpointSetTableStyle(
520
- slideNumber: number,
521
- shapeIndex: number,
522
- options: {
523
- borderColor?: string;
524
- borderWidth?: number;
525
- headerRowFill?: string;
526
- alternateRowFill?: string;
527
- }
528
- ): Promise<OfficeResponse> {
529
- const commands: string[] = [];
530
-
531
- if (options.borderColor) {
532
- const rgb = this.hexToRgb(options.borderColor);
533
- if (rgb) {
534
- commands.push(`
535
- for ($r = 1; $r -le $table.Rows.Count; $r++) {
536
- for ($c = 1; $c -le $table.Columns.Count; $c++) {
537
- $cell = $table.Cell($r, $c)
538
- $cell.Borders(1).ForeColor.RGB = ${rgb.r + rgb.g * 256 + rgb.b * 65536}
539
- $cell.Borders(2).ForeColor.RGB = ${rgb.r + rgb.g * 256 + rgb.b * 65536}
540
- $cell.Borders(3).ForeColor.RGB = ${rgb.r + rgb.g * 256 + rgb.b * 65536}
541
- $cell.Borders(4).ForeColor.RGB = ${rgb.r + rgb.g * 256 + rgb.b * 65536}
542
- }
543
- }`);
544
- }
545
- }
546
-
547
- if (options.headerRowFill) {
548
- const rgb = this.hexToRgb(options.headerRowFill);
549
- if (rgb) {
550
- commands.push(`
551
- for ($c = 1; $c -le $table.Columns.Count; $c++) {
552
- $table.Cell(1, $c).Shape.Fill.ForeColor.RGB = ${rgb.r + rgb.g * 256 + rgb.b * 65536}
553
- }`);
554
- }
555
- }
556
-
557
- if (options.alternateRowFill) {
558
- const rgb = this.hexToRgb(options.alternateRowFill);
559
- if (rgb) {
560
- commands.push(`
561
- for ($r = 2; $r -le $table.Rows.Count; $r += 2) {
562
- for ($c = 1; $c -le $table.Columns.Count; $c++) {
563
- $table.Cell($r, $c).Shape.Fill.ForeColor.RGB = ${rgb.r + rgb.g * 256 + rgb.b * 65536}
564
- }
565
- }`);
566
- }
567
- }
568
-
569
- return this.executePowerShell(`
570
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
571
- $presentation = $ppt.ActivePresentation
572
- $slide = $presentation.Slides(${slideNumber})
573
- $table = $slide.Shapes(${shapeIndex}).Table
574
- ${commands.join('\n')}
575
- @{ success = $true; message = "Table style updated" } | ConvertTo-Json -Compress
576
- `);
577
- }
578
-
579
- // -------------------------------------------------------------------------
580
- // Shape Management Functions
581
- // -------------------------------------------------------------------------
582
-
583
- async powerpointDeleteShape(slideNumber: number, shapeIndex: number): Promise<OfficeResponse> {
584
- return this.executePowerShell(`
585
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
586
- $presentation = $ppt.ActivePresentation
587
- $slide = $presentation.Slides(${slideNumber})
588
- $slide.Shapes(${shapeIndex}).Delete()
589
- @{ success = $true; message = "Shape ${shapeIndex} deleted from slide ${slideNumber}" } | ConvertTo-Json -Compress
590
- `);
591
- }
592
-
593
- async powerpointDuplicateShape(slideNumber: number, shapeIndex: number): Promise<OfficeResponse> {
594
- return this.executePowerShell(`
595
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
596
- $presentation = $ppt.ActivePresentation
597
- $slide = $presentation.Slides(${slideNumber})
598
- $newShape = $slide.Shapes(${shapeIndex}).Duplicate()
599
- @{ success = $true; message = "Shape duplicated"; new_shape_index = $newShape.Index } | ConvertTo-Json -Compress
600
- `);
601
- }
602
-
603
- async powerpointRotateShape(slideNumber: number, shapeIndex: number, angle: number): Promise<OfficeResponse> {
604
- return this.executePowerShell(`
605
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
606
- $presentation = $ppt.ActivePresentation
607
- $slide = $presentation.Slides(${slideNumber})
608
- $shape = $slide.Shapes(${shapeIndex})
609
- $shape.Rotation = ${angle}
610
- @{ success = $true; message = "Shape rotated to ${angle} degrees" } | ConvertTo-Json -Compress
611
- `);
612
- }
613
-
614
- async powerpointGetShapeInfo(slideNumber: number, shapeIndex: number): Promise<OfficeResponse> {
615
- return this.executePowerShell(`
616
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
617
- $presentation = $ppt.ActivePresentation
618
- $slide = $presentation.Slides(${slideNumber})
619
- $shape = $slide.Shapes(${shapeIndex})
620
- @{
621
- success = $true
622
- name = $shape.Name
623
- type = $shape.Type
624
- left = $shape.Left
625
- top = $shape.Top
626
- width = $shape.Width
627
- height = $shape.Height
628
- rotation = $shape.Rotation
629
- visible = $shape.Visible
630
- has_text = $shape.HasTextFrame
631
- } | ConvertTo-Json -Compress
632
- `);
633
- }
634
-
635
- async powerpointSetShapeName(slideNumber: number, shapeIndex: number, name: string): Promise<OfficeResponse> {
636
- const escapedName = name.replace(/'/g, "''");
637
- return this.executePowerShell(`
638
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
639
- $presentation = $ppt.ActivePresentation
640
- $slide = $presentation.Slides(${slideNumber})
641
- $shape = $slide.Shapes(${shapeIndex})
642
- $shape.Name = '${escapedName}'
643
- @{ success = $true; message = "Shape name set to '${escapedName}'" } | ConvertTo-Json -Compress
644
- `);
645
- }
646
-
647
- async powerpointSetShapeOpacity(slideNumber: number, shapeIndex: number, opacity: number): Promise<OfficeResponse> {
648
- // opacity: 0-100 (0 = fully transparent, 100 = fully opaque)
649
- const transparency = 1 - (opacity / 100);
650
- return this.executePowerShell(`
651
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
652
- $presentation = $ppt.ActivePresentation
653
- $slide = $presentation.Slides(${slideNumber})
654
- $shape = $slide.Shapes(${shapeIndex})
655
- $shape.Fill.Transparency = ${transparency}
656
- @{ success = $true; message = "Shape opacity set to ${opacity}%" } | ConvertTo-Json -Compress
657
- `);
658
- }
659
-
660
- async powerpointGetShapeList(slideNumber: number): Promise<OfficeResponse> {
661
- return this.executePowerShell(`
662
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
663
- $presentation = $ppt.ActivePresentation
664
- $slide = $presentation.Slides(${slideNumber})
665
- $shapes = @()
666
- for ($i = 1; $i -le $slide.Shapes.Count; $i++) {
667
- $s = $slide.Shapes($i)
668
- $shapes += @{
669
- index = $i
670
- name = $s.Name
671
- type = $s.Type
672
- left = $s.Left
673
- top = $s.Top
674
- width = $s.Width
675
- height = $s.Height
676
- }
677
- }
678
- @{ success = $true; slide = ${slideNumber}; count = $slide.Shapes.Count; shapes = $shapes } | ConvertTo-Json -Compress -Depth 5
679
- `);
680
- }
681
-
682
- // -------------------------------------------------------------------------
683
- // Shape Position/Size/Style Functions
684
- // -------------------------------------------------------------------------
685
-
686
- async powerpointSetShapePosition(
687
- slideNumber: number,
688
- shapeIndex: number,
689
- left: number,
690
- top: number
691
- ): Promise<OfficeResponse> {
692
- return this.executePowerShell(`
693
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
694
- $presentation = $ppt.ActivePresentation
695
- $slide = $presentation.Slides(${slideNumber})
696
- $shape = $slide.Shapes(${shapeIndex})
697
- $shape.Left = ${left}
698
- $shape.Top = ${top}
699
- @{ success = $true; message = "Shape position set to (${left}, ${top})" } | ConvertTo-Json -Compress
700
- `);
701
- }
702
-
703
- async powerpointSetShapeSize(
704
- slideNumber: number,
705
- shapeIndex: number,
706
- width: number,
707
- height: number,
708
- lockAspectRatio: boolean = false
709
- ): Promise<OfficeResponse> {
710
- return this.executePowerShell(`
711
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
712
- $presentation = $ppt.ActivePresentation
713
- $slide = $presentation.Slides(${slideNumber})
714
- $shape = $slide.Shapes(${shapeIndex})
715
- $shape.LockAspectRatio = ${lockAspectRatio ? '-1' : '0'}
716
- $shape.Width = ${width}
717
- $shape.Height = ${height}
718
- @{ success = $true; message = "Shape size set to ${width}x${height}" } | ConvertTo-Json -Compress
719
- `);
720
- }
721
-
722
- async powerpointSetShapeStyle(
723
- slideNumber: number,
724
- shapeIndex: number,
725
- options: {
726
- fillColor?: string;
727
- fillTransparency?: number;
728
- lineColor?: string;
729
- lineWeight?: number;
730
- lineStyle?: 'solid' | 'dash' | 'dot' | 'dashDot';
731
- noFill?: boolean;
732
- noLine?: boolean;
733
- }
734
- ): Promise<OfficeResponse> {
735
- const commands: string[] = [];
736
-
737
- if (options.noFill) {
738
- commands.push('$shape.Fill.Visible = 0');
739
- } else if (options.fillColor) {
740
- const rgb = this.hexToRgb(options.fillColor);
741
- if (rgb) {
742
- commands.push('$shape.Fill.Visible = -1');
743
- commands.push('$shape.Fill.Solid()');
744
- commands.push(`$shape.Fill.ForeColor.RGB = ${rgb.r + rgb.g * 256 + rgb.b * 65536}`);
745
- }
746
- }
747
-
748
- if (options.fillTransparency !== undefined) {
749
- commands.push(`$shape.Fill.Transparency = ${options.fillTransparency / 100}`);
750
- }
751
-
752
- if (options.noLine) {
753
- commands.push('$shape.Line.Visible = 0');
754
- } else {
755
- if (options.lineColor) {
756
- const rgb = this.hexToRgb(options.lineColor);
757
- if (rgb) {
758
- commands.push('$shape.Line.Visible = -1');
759
- commands.push(`$shape.Line.ForeColor.RGB = ${rgb.r + rgb.g * 256 + rgb.b * 65536}`);
760
- }
761
- }
762
- if (options.lineWeight !== undefined) {
763
- commands.push(`$shape.Line.Weight = ${options.lineWeight}`);
764
- }
765
- if (options.lineStyle) {
766
- const styleMap: Record<string, number> = { solid: 1, dash: 4, dot: 2, dashDot: 5 };
767
- commands.push(`$shape.Line.DashStyle = ${styleMap[options.lineStyle]}`);
768
- }
769
- }
770
-
771
- return this.executePowerShell(`
772
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
773
- $presentation = $ppt.ActivePresentation
774
- $slide = $presentation.Slides(${slideNumber})
775
- $shape = $slide.Shapes(${shapeIndex})
776
- ${commands.join('\n')}
777
- @{ success = $true; message = "Shape style updated" } | ConvertTo-Json -Compress
778
- `);
779
- }
780
-
781
- // -------------------------------------------------------------------------
782
- // Z-Order Functions
783
- // -------------------------------------------------------------------------
784
-
785
- async powerpointBringToFront(slideNumber: number, shapeIndex: number): Promise<OfficeResponse> {
786
- return this.executePowerShell(`
787
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
788
- $presentation = $ppt.ActivePresentation
789
- $slide = $presentation.Slides(${slideNumber})
790
- $shape = $slide.Shapes(${shapeIndex})
791
- $shape.ZOrder(0) # msoBringToFront = 0
792
- @{ success = $true; message = "Shape brought to front" } | ConvertTo-Json -Compress
793
- `);
794
- }
795
-
796
- async powerpointSendToBack(slideNumber: number, shapeIndex: number): Promise<OfficeResponse> {
797
- return this.executePowerShell(`
798
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
799
- $presentation = $ppt.ActivePresentation
800
- $slide = $presentation.Slides(${slideNumber})
801
- $shape = $slide.Shapes(${shapeIndex})
802
- $shape.ZOrder(1) # msoSendToBack = 1
803
- @{ success = $true; message = "Shape sent to back" } | ConvertTo-Json -Compress
804
- `);
805
- }
806
-
807
- async powerpointBringForward(slideNumber: number, shapeIndex: number): Promise<OfficeResponse> {
808
- return this.executePowerShell(`
809
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
810
- $presentation = $ppt.ActivePresentation
811
- $slide = $presentation.Slides(${slideNumber})
812
- $shape = $slide.Shapes(${shapeIndex})
813
- $shape.ZOrder(2) # msoBringForward = 2
814
- @{ success = $true; message = "Shape brought forward" } | ConvertTo-Json -Compress
815
- `);
816
- }
817
-
818
- async powerpointSendBackward(slideNumber: number, shapeIndex: number): Promise<OfficeResponse> {
819
- return this.executePowerShell(`
820
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
821
- $presentation = $ppt.ActivePresentation
822
- $slide = $presentation.Slides(${slideNumber})
823
- $shape = $slide.Shapes(${shapeIndex})
824
- $shape.ZOrder(3) # msoSendBackward = 3
825
- @{ success = $true; message = "Shape sent backward" } | ConvertTo-Json -Compress
826
- `);
827
- }
828
-
829
- // -------------------------------------------------------------------------
830
- // Alignment Functions
831
- // -------------------------------------------------------------------------
832
-
833
- async powerpointAlignShapes(
834
- slideNumber: number,
835
- shapeIndices: number[],
836
- alignment: 'left' | 'center' | 'right' | 'top' | 'middle' | 'bottom'
837
- ): Promise<OfficeResponse> {
838
- const alignMap: Record<string, number> = {
839
- left: 0, // msoAlignLefts
840
- center: 1, // msoAlignCenters
841
- right: 2, // msoAlignRights
842
- top: 3, // msoAlignTops
843
- middle: 4, // msoAlignMiddles
844
- bottom: 5, // msoAlignBottoms
845
- };
846
-
847
- return this.executePowerShell(`
848
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
849
- $presentation = $ppt.ActivePresentation
850
- $slide = $presentation.Slides(${slideNumber})
851
- $shapeRange = $slide.Shapes.Range(@(${shapeIndices.join(', ')}))
852
- $shapeRange.Align(${alignMap[alignment]}, 0) # 0 = msoFalse (relative to slide)
853
- @{ success = $true; message = "Shapes aligned to ${alignment}" } | ConvertTo-Json -Compress
854
- `);
855
- }
856
-
857
- async powerpointDistributeShapes(
858
- slideNumber: number,
859
- shapeIndices: number[],
860
- direction: 'horizontal' | 'vertical'
861
- ): Promise<OfficeResponse> {
862
- const distributeType = direction === 'horizontal' ? 0 : 1; // msoDistributeHorizontally = 0, msoDistributeVertically = 1
863
-
864
- return this.executePowerShell(`
865
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
866
- $presentation = $ppt.ActivePresentation
867
- $slide = $presentation.Slides(${slideNumber})
868
- $shapeRange = $slide.Shapes.Range(@(${shapeIndices.join(', ')}))
869
- $shapeRange.Distribute(${distributeType}, 0)
870
- @{ success = $true; message = "Shapes distributed ${direction}ly" } | ConvertTo-Json -Compress
871
- `);
872
- }
873
-
874
- // -------------------------------------------------------------------------
875
- // Slide Management Functions
876
- // -------------------------------------------------------------------------
877
-
878
- async powerpointSetSlideLayout(slideNumber: number, layoutIndex: number): Promise<OfficeResponse> {
879
- // Common layouts: 1=Title, 2=Title+Content, 3=Section Header, 4=Two Content, 5=Comparison, 6=Title Only, 7=Blank
880
- return this.executePowerShell(`
881
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
882
- $presentation = $ppt.ActivePresentation
883
- $slide = $presentation.Slides(${slideNumber})
884
- $slide.Layout = ${layoutIndex}
885
- @{ success = $true; message = "Slide layout set to ${layoutIndex}" } | ConvertTo-Json -Compress
886
- `);
887
- }
888
-
889
- async powerpointDuplicateSlide(slideNumber: number): Promise<OfficeResponse> {
890
- return this.executePowerShell(`
891
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
892
- $presentation = $ppt.ActivePresentation
893
- $newSlide = $presentation.Slides(${slideNumber}).Duplicate()
894
- @{ success = $true; message = "Slide ${slideNumber} duplicated"; new_slide_index = $newSlide.SlideIndex } | ConvertTo-Json -Compress
895
- `);
896
- }
897
-
898
- async powerpointHideSlide(slideNumber: number): Promise<OfficeResponse> {
899
- return this.executePowerShell(`
900
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
901
- $presentation = $ppt.ActivePresentation
902
- $slide = $presentation.Slides(${slideNumber})
903
- $slide.SlideShowTransition.Hidden = -1
904
- @{ success = $true; message = "Slide ${slideNumber} hidden" } | ConvertTo-Json -Compress
905
- `);
906
- }
907
-
908
- async powerpointShowSlide(slideNumber: number): Promise<OfficeResponse> {
909
- return this.executePowerShell(`
910
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
911
- $presentation = $ppt.ActivePresentation
912
- $slide = $presentation.Slides(${slideNumber})
913
- $slide.SlideShowTransition.Hidden = 0
914
- @{ success = $true; message = "Slide ${slideNumber} shown" } | ConvertTo-Json -Compress
915
- `);
916
- }
917
-
918
- async powerpointAddSection(sectionName: string, beforeSlide: number): Promise<OfficeResponse> {
919
- const escapedName = sectionName.replace(/'/g, "''");
920
- return this.executePowerShell(`
921
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
922
- $presentation = $ppt.ActivePresentation
923
- $sectionIndex = $presentation.SectionProperties.AddBeforeSlide(${beforeSlide}, '${escapedName}')
924
- @{ success = $true; message = "Section '${escapedName}' added"; section_index = $sectionIndex } | ConvertTo-Json -Compress
925
- `);
926
- }
927
-
928
- async powerpointDeleteSection(sectionIndex: number, deleteSlides: boolean = false): Promise<OfficeResponse> {
929
- return this.executePowerShell(`
930
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
931
- $presentation = $ppt.ActivePresentation
932
- $presentation.SectionProperties.Delete(${sectionIndex}, ${deleteSlides ? '-1' : '0'})
933
- @{ success = $true; message = "Section ${sectionIndex} deleted" } | ConvertTo-Json -Compress
934
- `);
935
- }
936
-
937
- async powerpointGetSections(): Promise<OfficeResponse> {
938
- return this.executePowerShell(`
939
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
940
- $presentation = $ppt.ActivePresentation
941
- $sections = @()
942
- for ($i = 1; $i -le $presentation.SectionProperties.Count; $i++) {
943
- $sections += @{
944
- index = $i
945
- name = $presentation.SectionProperties.Name($i)
946
- firstSlide = $presentation.SectionProperties.FirstSlide($i)
947
- slideCount = $presentation.SectionProperties.SlidesCount($i)
948
- }
949
- }
950
- @{ success = $true; count = $presentation.SectionProperties.Count; sections = $sections } | ConvertTo-Json -Compress -Depth 5
951
- `);
952
- }
953
-
954
- // -------------------------------------------------------------------------
955
- // Notes Functions
956
- // -------------------------------------------------------------------------
957
-
958
- async powerpointAddNote(slideNumber: number, noteText: string): Promise<OfficeResponse> {
959
- const escapedText = noteText.replace(/'/g, "''");
960
- const hasKorean = /[가-힣ㄱ-ㅎㅏ-ㅣ]/.test(noteText);
961
-
962
- // TEXT FIRST, FONT AFTER pattern (Microsoft recommended for Korean)
963
- return this.executePowerShell(`
964
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
965
- $presentation = $ppt.ActivePresentation
966
- $slide = $presentation.Slides(${slideNumber})
967
- $noteRange = $slide.NotesPage.Shapes.Placeholders(2).TextFrame.TextRange
968
- $textContent = '${escapedText}' -replace '\\\\n', [char]10 -replace '\\n', [char]10
969
- $noteRange.Text = $textContent
970
- ${hasKorean ? "$noteRange.Font.Name = 'Malgun Gothic'" : ''}
971
- @{ success = $true; message = "Note added to slide ${slideNumber}" } | ConvertTo-Json -Compress
972
- `);
973
- }
974
-
975
- async powerpointGetNote(slideNumber: number): Promise<OfficeResponse> {
976
- return this.executePowerShell(`
977
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
978
- $presentation = $ppt.ActivePresentation
979
- $slide = $presentation.Slides(${slideNumber})
980
- $noteText = $slide.NotesPage.Shapes.Placeholders(2).TextFrame.TextRange.Text
981
- @{ success = $true; slide = ${slideNumber}; note = $noteText } | ConvertTo-Json -Compress
982
- `);
983
- }
984
-
985
- // -------------------------------------------------------------------------
986
- // Grouping Functions
987
- // -------------------------------------------------------------------------
988
-
989
- async powerpointGroupShapes(slideNumber: number, shapeIndices: number[]): Promise<OfficeResponse> {
990
- return this.executePowerShell(`
991
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
992
- $presentation = $ppt.ActivePresentation
993
- $slide = $presentation.Slides(${slideNumber})
994
- $shapeRange = $slide.Shapes.Range(@(${shapeIndices.join(', ')}))
995
- $group = $shapeRange.Group()
996
- @{ success = $true; message = "Shapes grouped"; group_index = $group.Index } | ConvertTo-Json -Compress
997
- `);
998
- }
999
-
1000
- async powerpointUngroupShapes(slideNumber: number, groupIndex: number): Promise<OfficeResponse> {
1001
- return this.executePowerShell(`
1002
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
1003
- $presentation = $ppt.ActivePresentation
1004
- $slide = $presentation.Slides(${slideNumber})
1005
- $group = $slide.Shapes(${groupIndex})
1006
- $shapeRange = $group.Ungroup()
1007
- @{ success = $true; message = "Group ungrouped"; shape_count = $shapeRange.Count } | ConvertTo-Json -Compress
1008
- `);
1009
- }
1010
-
1011
- // -------------------------------------------------------------------------
1012
- // Text Formatting Functions
1013
- // -------------------------------------------------------------------------
1014
-
1015
- async powerpointSetTextAlignment(
1016
- slideNumber: number,
1017
- shapeIndex: number,
1018
- horizontal: 'left' | 'center' | 'right' | 'justify',
1019
- vertical?: 'top' | 'middle' | 'bottom'
1020
- ): Promise<OfficeResponse> {
1021
- const hAlignMap: Record<string, number> = { left: 1, center: 2, right: 3, justify: 4 };
1022
- const vAlignMap: Record<string, number> = { top: 1, middle: 3, bottom: 4 };
1023
-
1024
- const commands: string[] = [];
1025
- commands.push(`$shape.TextFrame.TextRange.ParagraphFormat.Alignment = ${hAlignMap[horizontal]}`);
1026
- if (vertical) {
1027
- commands.push(`$shape.TextFrame.VerticalAnchor = ${vAlignMap[vertical]}`);
1028
- }
1029
-
1030
- return this.executePowerShell(`
1031
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
1032
- $presentation = $ppt.ActivePresentation
1033
- $slide = $presentation.Slides(${slideNumber})
1034
- $shape = $slide.Shapes(${shapeIndex})
1035
- ${commands.join('\n')}
1036
- @{ success = $true; message = "Text alignment set" } | ConvertTo-Json -Compress
1037
- `);
1038
- }
1039
-
1040
- async powerpointSetBulletList(
1041
- slideNumber: number,
1042
- shapeIndex: number,
1043
- bulletType: 'none' | 'bullet' | 'numbered',
1044
- bulletChar?: string
1045
- ): Promise<OfficeResponse> {
1046
- const typeMap: Record<string, number> = { none: 0, bullet: 1, numbered: 2 };
1047
-
1048
- let bulletScript = `$shape.TextFrame.TextRange.ParagraphFormat.Bullet.Type = ${typeMap[bulletType]}`;
1049
- if (bulletType === 'bullet' && bulletChar) {
1050
- bulletScript += `\n$shape.TextFrame.TextRange.ParagraphFormat.Bullet.Character = [int][char]'${bulletChar}'`;
1051
- }
1052
-
1053
- return this.executePowerShell(`
1054
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
1055
- $presentation = $ppt.ActivePresentation
1056
- $slide = $presentation.Slides(${slideNumber})
1057
- $shape = $slide.Shapes(${shapeIndex})
1058
- ${bulletScript}
1059
- @{ success = $true; message = "Bullet style set to ${bulletType}" } | ConvertTo-Json -Compress
1060
- `);
1061
- }
1062
-
1063
- async powerpointSetLineSpacing(
1064
- slideNumber: number,
1065
- shapeIndex: number,
1066
- lineSpacing: number,
1067
- spaceAfter?: number,
1068
- spaceBefore?: number
1069
- ): Promise<OfficeResponse> {
1070
- const commands: string[] = [];
1071
- commands.push(`$shape.TextFrame.TextRange.ParagraphFormat.LineRuleWithin = 0`); // Use exact spacing
1072
- commands.push(`$shape.TextFrame.TextRange.ParagraphFormat.SpaceWithin = ${lineSpacing}`);
1073
- if (spaceAfter !== undefined) {
1074
- commands.push(`$shape.TextFrame.TextRange.ParagraphFormat.SpaceAfter = ${spaceAfter}`);
1075
- }
1076
- if (spaceBefore !== undefined) {
1077
- commands.push(`$shape.TextFrame.TextRange.ParagraphFormat.SpaceBefore = ${spaceBefore}`);
1078
- }
1079
-
1080
- return this.executePowerShell(`
1081
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
1082
- $presentation = $ppt.ActivePresentation
1083
- $slide = $presentation.Slides(${slideNumber})
1084
- $shape = $slide.Shapes(${shapeIndex})
1085
- ${commands.join('\n')}
1086
- @{ success = $true; message = "Line spacing set to ${lineSpacing}" } | ConvertTo-Json -Compress
1087
- `);
1088
- }
1089
-
1090
- async powerpointSetTextboxBorder(
1091
- slideNumber: number,
1092
- shapeIndex: number,
1093
- options: {
1094
- color?: string;
1095
- weight?: number;
1096
- style?: 'solid' | 'dash' | 'dot';
1097
- visible?: boolean;
1098
- }
1099
- ): Promise<OfficeResponse> {
1100
- const commands: string[] = [];
1101
-
1102
- if (options.visible === false) {
1103
- commands.push('$shape.Line.Visible = 0');
1104
- } else {
1105
- commands.push('$shape.Line.Visible = -1');
1106
- if (options.color) {
1107
- const rgb = this.hexToRgb(options.color);
1108
- if (rgb) commands.push(`$shape.Line.ForeColor.RGB = ${rgb.r + rgb.g * 256 + rgb.b * 65536}`);
1109
- }
1110
- if (options.weight !== undefined) commands.push(`$shape.Line.Weight = ${options.weight}`);
1111
- if (options.style) {
1112
- const styleMap: Record<string, number> = { solid: 1, dash: 4, dot: 2 };
1113
- commands.push(`$shape.Line.DashStyle = ${styleMap[options.style]}`);
1114
- }
1115
- }
1116
-
1117
- return this.executePowerShell(`
1118
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
1119
- $presentation = $ppt.ActivePresentation
1120
- $slide = $presentation.Slides(${slideNumber})
1121
- $shape = $slide.Shapes(${shapeIndex})
1122
- ${commands.join('\n')}
1123
- @{ success = $true; message = "Textbox border updated" } | ConvertTo-Json -Compress
1124
- `);
1125
- }
1126
-
1127
- async powerpointSetTextboxFill(
1128
- slideNumber: number,
1129
- shapeIndex: number,
1130
- options: {
1131
- color?: string;
1132
- transparency?: number;
1133
- visible?: boolean;
1134
- }
1135
- ): Promise<OfficeResponse> {
1136
- const commands: string[] = [];
1137
-
1138
- if (options.visible === false) {
1139
- commands.push('$shape.Fill.Visible = 0');
1140
- } else {
1141
- commands.push('$shape.Fill.Visible = -1');
1142
- commands.push('$shape.Fill.Solid()');
1143
- if (options.color) {
1144
- const rgb = this.hexToRgb(options.color);
1145
- if (rgb) commands.push(`$shape.Fill.ForeColor.RGB = ${rgb.r + rgb.g * 256 + rgb.b * 65536}`);
1146
- }
1147
- if (options.transparency !== undefined) {
1148
- commands.push(`$shape.Fill.Transparency = ${options.transparency / 100}`);
1149
- }
1150
- }
1151
-
1152
- return this.executePowerShell(`
1153
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
1154
- $presentation = $ppt.ActivePresentation
1155
- $slide = $presentation.Slides(${slideNumber})
1156
- $shape = $slide.Shapes(${shapeIndex})
1157
- ${commands.join('\n')}
1158
- @{ success = $true; message = "Textbox fill updated" } | ConvertTo-Json -Compress
1159
- `);
1160
- }
1161
-
1162
- // -------------------------------------------------------------------------
1163
- // Media Functions
1164
- // -------------------------------------------------------------------------
1165
-
1166
- async powerpointAddHyperlink(
1167
- slideNumber: number,
1168
- shapeIndex: number,
1169
- url: string,
1170
- screenTip?: string
1171
- ): Promise<OfficeResponse> {
1172
- const escapedUrl = url.replace(/'/g, "''");
1173
- const escapedTip = screenTip?.replace(/'/g, "''") || '';
1174
-
1175
- return this.executePowerShell(`
1176
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
1177
- $presentation = $ppt.ActivePresentation
1178
- $slide = $presentation.Slides(${slideNumber})
1179
- $shape = $slide.Shapes(${shapeIndex})
1180
- $link = $shape.ActionSettings(1).Hyperlink
1181
- $link.Address = '${escapedUrl}'
1182
- ${escapedTip ? `$link.ScreenTip = '${escapedTip}'` : ''}
1183
- @{ success = $true; message = "Hyperlink added to shape" } | ConvertTo-Json -Compress
1184
- `);
1185
- }
1186
-
1187
- async powerpointAddVideo(
1188
- slideNumber: number,
1189
- videoPath: string,
1190
- left: number = 100,
1191
- top: number = 100,
1192
- width: number = 400,
1193
- height: number = 300
1194
- ): Promise<OfficeResponse> {
1195
- const windowsPath = this.toWindowsPath(videoPath).replace(/'/g, "''");
1196
-
1197
- return this.executePowerShell(`
1198
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
1199
- $presentation = $ppt.ActivePresentation
1200
- $slide = $presentation.Slides(${slideNumber})
1201
- $video = $slide.Shapes.AddMediaObject2('${windowsPath}', 0, -1, ${left}, ${top}, ${width}, ${height})
1202
- @{ success = $true; message = "Video added to slide ${slideNumber}"; shape_index = $video.Index } | ConvertTo-Json -Compress
1203
- `);
1204
- }
1205
-
1206
- async powerpointAddAudio(
1207
- slideNumber: number,
1208
- audioPath: string,
1209
- left: number = 100,
1210
- top: number = 100,
1211
- playInBackground: boolean = false
1212
- ): Promise<OfficeResponse> {
1213
- const windowsPath = this.toWindowsPath(audioPath).replace(/'/g, "''");
1214
-
1215
- const bgScript = playInBackground ? `
1216
- $audio.AnimationSettings.PlaySettings.PlayOnEntry = -1
1217
- $audio.AnimationSettings.PlaySettings.HideWhileNotPlaying = -1
1218
- $audio.AnimationSettings.PlaySettings.LoopUntilStopped = 0
1219
- ` : '';
1220
-
1221
- return this.executePowerShell(`
1222
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
1223
- $presentation = $ppt.ActivePresentation
1224
- $slide = $presentation.Slides(${slideNumber})
1225
- $audio = $slide.Shapes.AddMediaObject2('${windowsPath}', 0, -1, ${left}, ${top})
1226
- ${bgScript}
1227
- @{ success = $true; message = "Audio added to slide ${slideNumber}"; shape_index = $audio.Index } | ConvertTo-Json -Compress
1228
- `);
1229
- }
1230
-
1231
- async powerpointAddChart(
1232
- slideNumber: number,
1233
- chartType: 'column' | 'bar' | 'line' | 'pie' | 'area' | 'scatter',
1234
- left: number = 100,
1235
- top: number = 100,
1236
- width: number = 400,
1237
- height: number = 300,
1238
- data?: { categories: string[]; series: { name: string; values: number[] }[] }
1239
- ): Promise<OfficeResponse> {
1240
- const chartTypeMap: Record<string, number> = {
1241
- column: 51, // xlColumnClustered
1242
- bar: 57, // xlBarClustered
1243
- line: 4, // xlLine
1244
- pie: 5, // xlPie
1245
- area: 1, // xlArea
1246
- scatter: -4169, // xlXYScatter
1247
- };
1248
-
1249
- let dataScript = '';
1250
- if (data) {
1251
- const rows = data.series.length + 1;
1252
- const cols = data.categories.length + 1;
1253
- dataScript = `
1254
- $chart.ChartData.Activate()
1255
- $workbook = $chart.ChartData.Workbook
1256
- $sheet = $workbook.Worksheets(1)
1257
- $sheet.Cells.Clear()
1258
- `;
1259
- // Add categories
1260
- for (let i = 0; i < data.categories.length; i++) {
1261
- const cat = data.categories[i]?.replace(/'/g, "''") || '';
1262
- dataScript += `$sheet.Cells(1, ${i + 2}).Value = '${cat}'\n`;
1263
- }
1264
- // Add series
1265
- for (let s = 0; s < data.series.length; s++) {
1266
- const series = data.series[s];
1267
- if (!series) continue;
1268
- dataScript += `$sheet.Cells(${s + 2}, 1).Value = '${series.name.replace(/'/g, "''")}'\n`;
1269
- for (let v = 0; v < series.values.length; v++) {
1270
- dataScript += `$sheet.Cells(${s + 2}, ${v + 2}).Value = ${series.values[v]}\n`;
1271
- }
1272
- }
1273
- dataScript += `
1274
- $chart.SetSourceData($sheet.Range($sheet.Cells(1,1), $sheet.Cells(${rows}, ${cols})))
1275
- $workbook.Close()
1276
- `;
1277
- }
1278
-
1279
- return this.executePowerShell(`
1280
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
1281
- $presentation = $ppt.ActivePresentation
1282
- $slide = $presentation.Slides(${slideNumber})
1283
- $chart = $slide.Shapes.AddChart2(-1, ${chartTypeMap[chartType]}, ${left}, ${top}, ${width}, ${height}).Chart
1284
- ${dataScript}
1285
- @{ success = $true; message = "${chartType} chart added to slide ${slideNumber}"; shape_index = $slide.Shapes.Count } | ConvertTo-Json -Compress
1286
- `);
1287
- }
1288
-
1289
- // -------------------------------------------------------------------------
1290
- // Effects Functions
1291
- // -------------------------------------------------------------------------
1292
-
1293
- async powerpointSetShadow(
1294
- slideNumber: number,
1295
- shapeIndex: number,
1296
- options: {
1297
- visible?: boolean;
1298
- type?: 'outer' | 'inner';
1299
- color?: string;
1300
- blur?: number;
1301
- offsetX?: number;
1302
- offsetY?: number;
1303
- transparency?: number;
1304
- }
1305
- ): Promise<OfficeResponse> {
1306
- const commands: string[] = [];
1307
-
1308
- if (options.visible === false) {
1309
- commands.push('$shape.Shadow.Visible = 0');
1310
- } else {
1311
- commands.push('$shape.Shadow.Visible = -1');
1312
- if (options.type === 'inner') {
1313
- commands.push('$shape.Shadow.Type = 21'); // msoShadowStyleInnerShadow
1314
- } else {
1315
- commands.push('$shape.Shadow.Type = 1'); // msoShadowStyleOuterShadow
1316
- }
1317
- if (options.color) {
1318
- const rgb = this.hexToRgb(options.color);
1319
- if (rgb) commands.push(`$shape.Shadow.ForeColor.RGB = ${rgb.r + rgb.g * 256 + rgb.b * 65536}`);
1320
- }
1321
- if (options.blur !== undefined) commands.push(`$shape.Shadow.Blur = ${options.blur}`);
1322
- if (options.offsetX !== undefined) commands.push(`$shape.Shadow.OffsetX = ${options.offsetX}`);
1323
- if (options.offsetY !== undefined) commands.push(`$shape.Shadow.OffsetY = ${options.offsetY}`);
1324
- if (options.transparency !== undefined) commands.push(`$shape.Shadow.Transparency = ${options.transparency / 100}`);
1325
- }
1326
-
1327
- return this.executePowerShell(`
1328
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
1329
- $presentation = $ppt.ActivePresentation
1330
- $slide = $presentation.Slides(${slideNumber})
1331
- $shape = $slide.Shapes(${shapeIndex})
1332
- ${commands.join('\n')}
1333
- @{ success = $true; message = "Shadow effect updated" } | ConvertTo-Json -Compress
1334
- `);
1335
- }
1336
-
1337
- async powerpointSetReflection(
1338
- slideNumber: number,
1339
- shapeIndex: number,
1340
- options: {
1341
- visible?: boolean;
1342
- type?: number; // 1-9 reflection types
1343
- blur?: number;
1344
- offset?: number;
1345
- size?: number;
1346
- transparency?: number;
1347
- }
1348
- ): Promise<OfficeResponse> {
1349
- const commands: string[] = [];
1350
-
1351
- if (options.visible === false) {
1352
- commands.push('$shape.Reflection.Type = 0'); // msoReflectionTypeNone
1353
- } else {
1354
- commands.push(`$shape.Reflection.Type = ${options.type || 1}`);
1355
- if (options.blur !== undefined) commands.push(`$shape.Reflection.Blur = ${options.blur}`);
1356
- if (options.offset !== undefined) commands.push(`$shape.Reflection.Offset = ${options.offset}`);
1357
- if (options.size !== undefined) commands.push(`$shape.Reflection.Size = ${options.size}`);
1358
- if (options.transparency !== undefined) commands.push(`$shape.Reflection.Transparency = ${options.transparency / 100}`);
1359
- }
1360
-
1361
- return this.executePowerShell(`
1362
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
1363
- $presentation = $ppt.ActivePresentation
1364
- $slide = $presentation.Slides(${slideNumber})
1365
- $shape = $slide.Shapes(${shapeIndex})
1366
- ${commands.join('\n')}
1367
- @{ success = $true; message = "Reflection effect updated" } | ConvertTo-Json -Compress
1368
- `);
1369
- }
1370
-
1371
- async powerpointApplyTheme(themePath: string): Promise<OfficeResponse> {
1372
- const windowsPath = this.toWindowsPath(themePath).replace(/'/g, "''");
1373
-
1374
- return this.executePowerShell(`
1375
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
1376
- $presentation = $ppt.ActivePresentation
1377
- $presentation.ApplyTheme('${windowsPath}')
1378
- @{ success = $true; message = "Theme applied" } | ConvertTo-Json -Compress
1379
- `);
1380
- }
1381
-
1382
- async powerpointGetThemes(): Promise<OfficeResponse> {
1383
- return this.executePowerShell(`
1384
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
1385
- $themesPath = [Environment]::GetFolderPath('CommonDocuments') + '\\Microsoft\\Templates\\Document Themes'
1386
- $themes = @()
1387
- if (Test-Path $themesPath) {
1388
- Get-ChildItem -Path $themesPath -Filter "*.thmx" | ForEach-Object {
1389
- $themes += @{ name = $_.BaseName; path = $_.FullName }
1390
- }
1391
- }
1392
- # Also check user themes
1393
- $userThemesPath = [Environment]::GetFolderPath('MyDocuments') + '\\Custom Office Templates'
1394
- if (Test-Path $userThemesPath) {
1395
- Get-ChildItem -Path $userThemesPath -Filter "*.thmx" -ErrorAction SilentlyContinue | ForEach-Object {
1396
- $themes += @{ name = $_.BaseName; path = $_.FullName }
1397
- }
1398
- }
1399
- @{ success = $true; themes = $themes } | ConvertTo-Json -Compress -Depth 5
1400
- `);
1401
- }
1402
-
1403
- // -------------------------------------------------------------------------
1404
- // Placeholder Functions
1405
- // -------------------------------------------------------------------------
1406
-
1407
- async powerpointSetPlaceholderText(
1408
- slideNumber: number,
1409
- placeholderType: 'title' | 'subtitle' | 'body' | 'footer' | 'slideNumber' | 'date',
1410
- text: string
1411
- ): Promise<OfficeResponse> {
1412
- const escapedText = text.replace(/'/g, "''");
1413
- const hasKorean = /[가-힣ㄱ-ㅎㅏ-ㅣ]/.test(text);
1414
-
1415
- // ppPlaceholderType values
1416
- const typeMap: Record<string, number> = {
1417
- title: 1,
1418
- subtitle: 4,
1419
- body: 2,
1420
- footer: 5,
1421
- slideNumber: 6,
1422
- date: 16,
1423
- };
1424
-
1425
- // TEXT FIRST, FONT AFTER pattern (Microsoft recommended for Korean)
1426
- return this.executePowerShell(`
1427
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
1428
- $presentation = $ppt.ActivePresentation
1429
- $slide = $presentation.Slides(${slideNumber})
1430
- $placeholder = $null
1431
- foreach ($shape in $slide.Shapes) {
1432
- if ($shape.Type -eq 14) { # msoPlaceholder
1433
- if ($shape.PlaceholderFormat.Type -eq ${typeMap[placeholderType]}) {
1434
- $placeholder = $shape
1435
- break
1436
- }
1437
- }
1438
- }
1439
- if ($placeholder) {
1440
- $textContent = '${escapedText}' -replace '\\\\n', [char]10 -replace '\\n', [char]10
1441
- $placeholder.TextFrame.TextRange.Text = $textContent
1442
- ${hasKorean ? "$placeholder.TextFrame.TextRange.Font.Name = 'Malgun Gothic'" : ''}
1443
- @{ success = $true; message = "${placeholderType} placeholder text set" } | ConvertTo-Json -Compress
1444
- } else {
1445
- @{ success = $false; error = "Placeholder type '${placeholderType}' not found on slide ${slideNumber}" } | ConvertTo-Json -Compress
1446
- }
1447
- `);
1448
- }
1449
-
1450
- async powerpointGetPlaceholders(slideNumber: number): Promise<OfficeResponse> {
1451
- return this.executePowerShell(`
1452
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
1453
- $presentation = $ppt.ActivePresentation
1454
- $slide = $presentation.Slides(${slideNumber})
1455
- $placeholders = @()
1456
- foreach ($shape in $slide.Shapes) {
1457
- if ($shape.Type -eq 14) { # msoPlaceholder
1458
- $placeholders += @{
1459
- index = $shape.Index
1460
- name = $shape.Name
1461
- type = $shape.PlaceholderFormat.Type
1462
- hasText = $shape.HasTextFrame
1463
- text = if ($shape.HasTextFrame -eq -1) { $shape.TextFrame.TextRange.Text } else { "" }
1464
- }
1465
- }
1466
- }
1467
- @{ success = $true; slide = ${slideNumber}; placeholders = $placeholders } | ConvertTo-Json -Compress -Depth 5
1468
- `);
1469
- }
1470
-
1471
- async powerpointGetSlideLayouts(): Promise<OfficeResponse> {
1472
- return this.executePowerShell(`
1473
- $ppt = [Runtime.InteropServices.Marshal]::GetActiveObject("PowerPoint.Application")
1474
- $presentation = $ppt.ActivePresentation
1475
- $layouts = @()
1476
- $master = $presentation.SlideMaster
1477
- for ($i = 1; $i -le $master.CustomLayouts.Count; $i++) {
1478
- $layout = $master.CustomLayouts($i)
1479
- $layouts += @{
1480
- index = $i
1481
- name = $layout.Name
1482
- }
1483
- }
1484
- @{ success = $true; layouts = $layouts } | ConvertTo-Json -Compress -Depth 5
1485
- `);
1486
- }
1487
-
1488
- // ===========================================================================
1489
- // Helper Methods
1490
- // ===========================================================================
1491
-
1492
-
1493
- }
1494
-
1495
- // Export singleton instance
1496
- export const powerpointClient = new PowerPointClient();
1497
- export type { OfficeResponse, ScreenshotResponse };
1498
-