local-cli-agent 5.0.4

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 (776) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +306 -0
  3. package/dist/agents/base/base-agent.d.ts +38 -0
  4. package/dist/agents/base/base-agent.d.ts.map +1 -0
  5. package/dist/agents/base/base-agent.js +69 -0
  6. package/dist/agents/base/base-agent.js.map +1 -0
  7. package/dist/agents/browser/browser-profile-manager.d.ts +16 -0
  8. package/dist/agents/browser/browser-profile-manager.d.ts.map +1 -0
  9. package/dist/agents/browser/browser-profile-manager.js +149 -0
  10. package/dist/agents/browser/browser-profile-manager.js.map +1 -0
  11. package/dist/agents/browser/browser-sub-agent.d.ts +22 -0
  12. package/dist/agents/browser/browser-sub-agent.d.ts.map +1 -0
  13. package/dist/agents/browser/browser-sub-agent.js +162 -0
  14. package/dist/agents/browser/browser-sub-agent.js.map +1 -0
  15. package/dist/agents/browser/confluence-agent.d.ts +3 -0
  16. package/dist/agents/browser/confluence-agent.d.ts.map +1 -0
  17. package/dist/agents/browser/confluence-agent.js +35 -0
  18. package/dist/agents/browser/confluence-agent.js.map +1 -0
  19. package/dist/agents/browser/index.d.ts +4 -0
  20. package/dist/agents/browser/index.d.ts.map +1 -0
  21. package/dist/agents/browser/index.js +4 -0
  22. package/dist/agents/browser/index.js.map +1 -0
  23. package/dist/agents/browser/jira-agent.d.ts +3 -0
  24. package/dist/agents/browser/jira-agent.d.ts.map +1 -0
  25. package/dist/agents/browser/jira-agent.js +35 -0
  26. package/dist/agents/browser/jira-agent.js.map +1 -0
  27. package/dist/agents/browser/prompts.d.ts +4 -0
  28. package/dist/agents/browser/prompts.d.ts.map +1 -0
  29. package/dist/agents/browser/prompts.js +241 -0
  30. package/dist/agents/browser/prompts.js.map +1 -0
  31. package/dist/agents/browser/search-agent.d.ts +3 -0
  32. package/dist/agents/browser/search-agent.d.ts.map +1 -0
  33. package/dist/agents/browser/search-agent.js +31 -0
  34. package/dist/agents/browser/search-agent.js.map +1 -0
  35. package/dist/agents/common/complete-tool.d.ts +3 -0
  36. package/dist/agents/common/complete-tool.d.ts.map +1 -0
  37. package/dist/agents/common/complete-tool.js +18 -0
  38. package/dist/agents/common/complete-tool.js.map +1 -0
  39. package/dist/agents/common/index.d.ts +3 -0
  40. package/dist/agents/common/index.d.ts.map +1 -0
  41. package/dist/agents/common/index.js +3 -0
  42. package/dist/agents/common/index.js.map +1 -0
  43. package/dist/agents/common/sub-agent.d.ts +40 -0
  44. package/dist/agents/common/sub-agent.d.ts.map +1 -0
  45. package/dist/agents/common/sub-agent.js +313 -0
  46. package/dist/agents/common/sub-agent.js.map +1 -0
  47. package/dist/agents/index.d.ts +5 -0
  48. package/dist/agents/index.d.ts.map +1 -0
  49. package/dist/agents/index.js +5 -0
  50. package/dist/agents/index.js.map +1 -0
  51. package/dist/agents/office/complete-tool.d.ts +3 -0
  52. package/dist/agents/office/complete-tool.d.ts.map +1 -0
  53. package/dist/agents/office/complete-tool.js +18 -0
  54. package/dist/agents/office/complete-tool.js.map +1 -0
  55. package/dist/agents/office/excel-agent.d.ts +3 -0
  56. package/dist/agents/office/excel-agent.d.ts.map +1 -0
  57. package/dist/agents/office/excel-agent.js +31 -0
  58. package/dist/agents/office/excel-agent.js.map +1 -0
  59. package/dist/agents/office/excel-create-agent.d.ts +3 -0
  60. package/dist/agents/office/excel-create-agent.d.ts.map +1 -0
  61. package/dist/agents/office/excel-create-agent.js +58 -0
  62. package/dist/agents/office/excel-create-agent.js.map +1 -0
  63. package/dist/agents/office/excel-create-prompts.d.ts +4 -0
  64. package/dist/agents/office/excel-create-prompts.d.ts.map +1 -0
  65. package/dist/agents/office/excel-create-prompts.js +217 -0
  66. package/dist/agents/office/excel-create-prompts.js.map +1 -0
  67. package/dist/agents/office/index.d.ts +10 -0
  68. package/dist/agents/office/index.d.ts.map +1 -0
  69. package/dist/agents/office/index.js +10 -0
  70. package/dist/agents/office/index.js.map +1 -0
  71. package/dist/agents/office/office-sub-agent.d.ts +21 -0
  72. package/dist/agents/office/office-sub-agent.d.ts.map +1 -0
  73. package/dist/agents/office/office-sub-agent.js +127 -0
  74. package/dist/agents/office/office-sub-agent.js.map +1 -0
  75. package/dist/agents/office/powerpoint-agent.d.ts +3 -0
  76. package/dist/agents/office/powerpoint-agent.d.ts.map +1 -0
  77. package/dist/agents/office/powerpoint-agent.js +37 -0
  78. package/dist/agents/office/powerpoint-agent.js.map +1 -0
  79. package/dist/agents/office/powerpoint-create-agent.d.ts +3 -0
  80. package/dist/agents/office/powerpoint-create-agent.d.ts.map +1 -0
  81. package/dist/agents/office/powerpoint-create-agent.js +1124 -0
  82. package/dist/agents/office/powerpoint-create-agent.js.map +1 -0
  83. package/dist/agents/office/powerpoint-create-prompts.d.ts +116 -0
  84. package/dist/agents/office/powerpoint-create-prompts.d.ts.map +1 -0
  85. package/dist/agents/office/powerpoint-create-prompts.js +1354 -0
  86. package/dist/agents/office/powerpoint-create-prompts.js.map +1 -0
  87. package/dist/agents/office/prompts.d.ts +11 -0
  88. package/dist/agents/office/prompts.d.ts.map +1 -0
  89. package/dist/agents/office/prompts.js +852 -0
  90. package/dist/agents/office/prompts.js.map +1 -0
  91. package/dist/agents/office/word-agent.d.ts +3 -0
  92. package/dist/agents/office/word-agent.d.ts.map +1 -0
  93. package/dist/agents/office/word-agent.js +31 -0
  94. package/dist/agents/office/word-agent.js.map +1 -0
  95. package/dist/agents/office/word-create-agent.d.ts +3 -0
  96. package/dist/agents/office/word-create-agent.d.ts.map +1 -0
  97. package/dist/agents/office/word-create-agent.js +36 -0
  98. package/dist/agents/office/word-create-agent.js.map +1 -0
  99. package/dist/agents/office/word-create-prompts.d.ts +4 -0
  100. package/dist/agents/office/word-create-prompts.d.ts.map +1 -0
  101. package/dist/agents/office/word-create-prompts.js +288 -0
  102. package/dist/agents/office/word-create-prompts.js.map +1 -0
  103. package/dist/agents/planner/index.d.ts +14 -0
  104. package/dist/agents/planner/index.d.ts.map +1 -0
  105. package/dist/agents/planner/index.js +334 -0
  106. package/dist/agents/planner/index.js.map +1 -0
  107. package/dist/cli.d.ts +3 -0
  108. package/dist/cli.d.ts.map +1 -0
  109. package/dist/cli.js +166 -0
  110. package/dist/cli.js.map +1 -0
  111. package/dist/commands/chat-command.d.ts +2 -0
  112. package/dist/commands/chat-command.d.ts.map +1 -0
  113. package/dist/commands/chat-command.js +90 -0
  114. package/dist/commands/chat-command.js.map +1 -0
  115. package/dist/commands/electron-client.d.ts +17 -0
  116. package/dist/commands/electron-client.d.ts.map +1 -0
  117. package/dist/commands/electron-client.js +180 -0
  118. package/dist/commands/electron-client.js.map +1 -0
  119. package/dist/commands/jarvis-command.d.ts +2 -0
  120. package/dist/commands/jarvis-command.d.ts.map +1 -0
  121. package/dist/commands/jarvis-command.js +66 -0
  122. package/dist/commands/jarvis-command.js.map +1 -0
  123. package/dist/constants.d.ts +11 -0
  124. package/dist/constants.d.ts.map +1 -0
  125. package/dist/constants.js +13 -0
  126. package/dist/constants.js.map +1 -0
  127. package/dist/core/compact/compact-manager.d.ts +22 -0
  128. package/dist/core/compact/compact-manager.d.ts.map +1 -0
  129. package/dist/core/compact/compact-manager.js +77 -0
  130. package/dist/core/compact/compact-manager.js.map +1 -0
  131. package/dist/core/compact/compact-prompts.d.ts +11 -0
  132. package/dist/core/compact/compact-prompts.d.ts.map +1 -0
  133. package/dist/core/compact/compact-prompts.js +90 -0
  134. package/dist/core/compact/compact-prompts.js.map +1 -0
  135. package/dist/core/compact/context-tracker.d.ts +28 -0
  136. package/dist/core/compact/context-tracker.d.ts.map +1 -0
  137. package/dist/core/compact/context-tracker.js +71 -0
  138. package/dist/core/compact/context-tracker.js.map +1 -0
  139. package/dist/core/compact/index.d.ts +4 -0
  140. package/dist/core/compact/index.d.ts.map +1 -0
  141. package/dist/core/compact/index.js +4 -0
  142. package/dist/core/compact/index.js.map +1 -0
  143. package/dist/core/config/config-manager.d.ts +43 -0
  144. package/dist/core/config/config-manager.d.ts.map +1 -0
  145. package/dist/core/config/config-manager.js +254 -0
  146. package/dist/core/config/config-manager.js.map +1 -0
  147. package/dist/core/config/index.d.ts +2 -0
  148. package/dist/core/config/index.d.ts.map +1 -0
  149. package/dist/core/config/index.js +2 -0
  150. package/dist/core/config/index.js.map +1 -0
  151. package/dist/core/docs-manager.d.ts +46 -0
  152. package/dist/core/docs-manager.d.ts.map +1 -0
  153. package/dist/core/docs-manager.js +475 -0
  154. package/dist/core/docs-manager.js.map +1 -0
  155. package/dist/core/git-auto-updater.d.ts +58 -0
  156. package/dist/core/git-auto-updater.d.ts.map +1 -0
  157. package/dist/core/git-auto-updater.js +374 -0
  158. package/dist/core/git-auto-updater.js.map +1 -0
  159. package/dist/core/llm/index.d.ts +2 -0
  160. package/dist/core/llm/index.d.ts.map +1 -0
  161. package/dist/core/llm/index.js +2 -0
  162. package/dist/core/llm/index.js.map +1 -0
  163. package/dist/core/llm/llm-client.d.ts +110 -0
  164. package/dist/core/llm/llm-client.d.ts.map +1 -0
  165. package/dist/core/llm/llm-client.js +1272 -0
  166. package/dist/core/llm/llm-client.js.map +1 -0
  167. package/dist/core/session/index.d.ts +2 -0
  168. package/dist/core/session/index.d.ts.map +1 -0
  169. package/dist/core/session/index.js +2 -0
  170. package/dist/core/session/index.js.map +1 -0
  171. package/dist/core/session/session-manager.d.ts +73 -0
  172. package/dist/core/session/session-manager.d.ts.map +1 -0
  173. package/dist/core/session/session-manager.js +260 -0
  174. package/dist/core/session/session-manager.js.map +1 -0
  175. package/dist/core/slash-command-handler.d.ts +31 -0
  176. package/dist/core/slash-command-handler.d.ts.map +1 -0
  177. package/dist/core/slash-command-handler.js +304 -0
  178. package/dist/core/slash-command-handler.js.map +1 -0
  179. package/dist/core/telemetry/error-reporter.d.ts +2 -0
  180. package/dist/core/telemetry/error-reporter.d.ts.map +1 -0
  181. package/dist/core/telemetry/error-reporter.js +3 -0
  182. package/dist/core/telemetry/error-reporter.js.map +1 -0
  183. package/dist/core/usage-tracker.d.ts +70 -0
  184. package/dist/core/usage-tracker.d.ts.map +1 -0
  185. package/dist/core/usage-tracker.js +251 -0
  186. package/dist/core/usage-tracker.js.map +1 -0
  187. package/dist/errors/base.d.ts +22 -0
  188. package/dist/errors/base.d.ts.map +1 -0
  189. package/dist/errors/base.js +43 -0
  190. package/dist/errors/base.js.map +1 -0
  191. package/dist/errors/file.d.ts +31 -0
  192. package/dist/errors/file.d.ts.map +1 -0
  193. package/dist/errors/file.js +110 -0
  194. package/dist/errors/file.js.map +1 -0
  195. package/dist/errors/index.d.ts +10 -0
  196. package/dist/errors/index.d.ts.map +1 -0
  197. package/dist/errors/index.js +41 -0
  198. package/dist/errors/index.js.map +1 -0
  199. package/dist/errors/llm.d.ts +30 -0
  200. package/dist/errors/llm.d.ts.map +1 -0
  201. package/dist/errors/llm.js +97 -0
  202. package/dist/errors/llm.js.map +1 -0
  203. package/dist/errors/network.d.ts +19 -0
  204. package/dist/errors/network.d.ts.map +1 -0
  205. package/dist/errors/network.js +82 -0
  206. package/dist/errors/network.js.map +1 -0
  207. package/dist/errors/validation.d.ts +19 -0
  208. package/dist/errors/validation.d.ts.map +1 -0
  209. package/dist/errors/validation.js +62 -0
  210. package/dist/errors/validation.js.map +1 -0
  211. package/dist/eval/eval-runner.d.ts +24 -0
  212. package/dist/eval/eval-runner.d.ts.map +1 -0
  213. package/dist/eval/eval-runner.js +291 -0
  214. package/dist/eval/eval-runner.js.map +1 -0
  215. package/dist/eval/index.d.ts +3 -0
  216. package/dist/eval/index.d.ts.map +1 -0
  217. package/dist/eval/index.js +3 -0
  218. package/dist/eval/index.js.map +1 -0
  219. package/dist/eval/types.d.ts +77 -0
  220. package/dist/eval/types.d.ts.map +1 -0
  221. package/dist/eval/types.js +2 -0
  222. package/dist/eval/types.js.map +1 -0
  223. package/dist/index.d.ts +4 -0
  224. package/dist/index.d.ts.map +1 -0
  225. package/dist/index.js +6 -0
  226. package/dist/index.js.map +1 -0
  227. package/dist/orchestration/index.d.ts +4 -0
  228. package/dist/orchestration/index.d.ts.map +1 -0
  229. package/dist/orchestration/index.js +3 -0
  230. package/dist/orchestration/index.js.map +1 -0
  231. package/dist/orchestration/plan-executor.d.ts +27 -0
  232. package/dist/orchestration/plan-executor.d.ts.map +1 -0
  233. package/dist/orchestration/plan-executor.js +536 -0
  234. package/dist/orchestration/plan-executor.js.map +1 -0
  235. package/dist/orchestration/types.d.ts +69 -0
  236. package/dist/orchestration/types.d.ts.map +1 -0
  237. package/dist/orchestration/types.js +2 -0
  238. package/dist/orchestration/types.js.map +1 -0
  239. package/dist/orchestration/utils.d.ts +14 -0
  240. package/dist/orchestration/utils.d.ts.map +1 -0
  241. package/dist/orchestration/utils.js +105 -0
  242. package/dist/orchestration/utils.js.map +1 -0
  243. package/dist/pipe/index.d.ts +2 -0
  244. package/dist/pipe/index.d.ts.map +1 -0
  245. package/dist/pipe/index.js +2 -0
  246. package/dist/pipe/index.js.map +1 -0
  247. package/dist/pipe/pipe-runner.d.ts +15 -0
  248. package/dist/pipe/pipe-runner.d.ts.map +1 -0
  249. package/dist/pipe/pipe-runner.js +207 -0
  250. package/dist/pipe/pipe-runner.js.map +1 -0
  251. package/dist/prompts/agents/planning.d.ts +4 -0
  252. package/dist/prompts/agents/planning.d.ts.map +1 -0
  253. package/dist/prompts/agents/planning.js +318 -0
  254. package/dist/prompts/agents/planning.js.map +1 -0
  255. package/dist/prompts/index.d.ts +8 -0
  256. package/dist/prompts/index.d.ts.map +1 -0
  257. package/dist/prompts/index.js +8 -0
  258. package/dist/prompts/index.js.map +1 -0
  259. package/dist/prompts/shared/codebase-rules.d.ts +4 -0
  260. package/dist/prompts/shared/codebase-rules.d.ts.map +1 -0
  261. package/dist/prompts/shared/codebase-rules.js +16 -0
  262. package/dist/prompts/shared/codebase-rules.js.map +1 -0
  263. package/dist/prompts/shared/git-rules.d.ts +2 -0
  264. package/dist/prompts/shared/git-rules.d.ts.map +1 -0
  265. package/dist/prompts/shared/git-rules.js +87 -0
  266. package/dist/prompts/shared/git-rules.js.map +1 -0
  267. package/dist/prompts/shared/language-rules.d.ts +4 -0
  268. package/dist/prompts/shared/language-rules.d.ts.map +1 -0
  269. package/dist/prompts/shared/language-rules.js +22 -0
  270. package/dist/prompts/shared/language-rules.js.map +1 -0
  271. package/dist/prompts/shared/tool-usage.d.ts +14 -0
  272. package/dist/prompts/shared/tool-usage.d.ts.map +1 -0
  273. package/dist/prompts/shared/tool-usage.js +92 -0
  274. package/dist/prompts/shared/tool-usage.js.map +1 -0
  275. package/dist/prompts/system/compact.d.ts +3 -0
  276. package/dist/prompts/system/compact.d.ts.map +1 -0
  277. package/dist/prompts/system/compact.js +73 -0
  278. package/dist/prompts/system/compact.js.map +1 -0
  279. package/dist/prompts/system/plan-execute.d.ts +6 -0
  280. package/dist/prompts/system/plan-execute.d.ts.map +1 -0
  281. package/dist/prompts/system/plan-execute.js +178 -0
  282. package/dist/prompts/system/plan-execute.js.map +1 -0
  283. package/dist/tools/browser/browser-client.d.ts +108 -0
  284. package/dist/tools/browser/browser-client.d.ts.map +1 -0
  285. package/dist/tools/browser/browser-client.js +965 -0
  286. package/dist/tools/browser/browser-client.js.map +1 -0
  287. package/dist/tools/browser/browser-tools.d.ts +18 -0
  288. package/dist/tools/browser/browser-tools.d.ts.map +1 -0
  289. package/dist/tools/browser/browser-tools.js +983 -0
  290. package/dist/tools/browser/browser-tools.js.map +1 -0
  291. package/dist/tools/browser/index.d.ts +7 -0
  292. package/dist/tools/browser/index.d.ts.map +1 -0
  293. package/dist/tools/browser/index.js +17 -0
  294. package/dist/tools/browser/index.js.map +1 -0
  295. package/dist/tools/index.d.ts +4 -0
  296. package/dist/tools/index.d.ts.map +1 -0
  297. package/dist/tools/index.js +4 -0
  298. package/dist/tools/index.js.map +1 -0
  299. package/dist/tools/llm/index.d.ts +2 -0
  300. package/dist/tools/llm/index.d.ts.map +1 -0
  301. package/dist/tools/llm/index.js +2 -0
  302. package/dist/tools/llm/index.js.map +1 -0
  303. package/dist/tools/llm/simple/ask-user-tool.d.ts +5 -0
  304. package/dist/tools/llm/simple/ask-user-tool.d.ts.map +1 -0
  305. package/dist/tools/llm/simple/ask-user-tool.js +7 -0
  306. package/dist/tools/llm/simple/ask-user-tool.js.map +1 -0
  307. package/dist/tools/llm/simple/background-bash-tool.d.ts +30 -0
  308. package/dist/tools/llm/simple/background-bash-tool.d.ts.map +1 -0
  309. package/dist/tools/llm/simple/background-bash-tool.js +320 -0
  310. package/dist/tools/llm/simple/background-bash-tool.js.map +1 -0
  311. package/dist/tools/llm/simple/background-powershell-tool.d.ts +30 -0
  312. package/dist/tools/llm/simple/background-powershell-tool.d.ts.map +1 -0
  313. package/dist/tools/llm/simple/background-powershell-tool.js +302 -0
  314. package/dist/tools/llm/simple/background-powershell-tool.js.map +1 -0
  315. package/dist/tools/llm/simple/bash-tool.d.ts +4 -0
  316. package/dist/tools/llm/simple/bash-tool.d.ts.map +1 -0
  317. package/dist/tools/llm/simple/bash-tool.js +167 -0
  318. package/dist/tools/llm/simple/bash-tool.js.map +1 -0
  319. package/dist/tools/llm/simple/file-tools.d.ts +13 -0
  320. package/dist/tools/llm/simple/file-tools.d.ts.map +1 -0
  321. package/dist/tools/llm/simple/file-tools.js +814 -0
  322. package/dist/tools/llm/simple/file-tools.js.map +1 -0
  323. package/dist/tools/llm/simple/final-response-tool.d.ts +12 -0
  324. package/dist/tools/llm/simple/final-response-tool.d.ts.map +1 -0
  325. package/dist/tools/llm/simple/final-response-tool.js +107 -0
  326. package/dist/tools/llm/simple/final-response-tool.js.map +1 -0
  327. package/dist/tools/llm/simple/index.d.ts +11 -0
  328. package/dist/tools/llm/simple/index.d.ts.map +1 -0
  329. package/dist/tools/llm/simple/index.js +20 -0
  330. package/dist/tools/llm/simple/index.js.map +1 -0
  331. package/dist/tools/llm/simple/planning-tools.d.ts +5 -0
  332. package/dist/tools/llm/simple/planning-tools.d.ts.map +1 -0
  333. package/dist/tools/llm/simple/planning-tools.js +121 -0
  334. package/dist/tools/llm/simple/planning-tools.js.map +1 -0
  335. package/dist/tools/llm/simple/powershell-tool.d.ts +4 -0
  336. package/dist/tools/llm/simple/powershell-tool.d.ts.map +1 -0
  337. package/dist/tools/llm/simple/powershell-tool.js +163 -0
  338. package/dist/tools/llm/simple/powershell-tool.js.map +1 -0
  339. package/dist/tools/llm/simple/read-image-tool.d.ts +8 -0
  340. package/dist/tools/llm/simple/read-image-tool.d.ts.map +1 -0
  341. package/dist/tools/llm/simple/read-image-tool.js +170 -0
  342. package/dist/tools/llm/simple/read-image-tool.js.map +1 -0
  343. package/dist/tools/llm/simple/simple-tool-executor.d.ts +40 -0
  344. package/dist/tools/llm/simple/simple-tool-executor.d.ts.map +1 -0
  345. package/dist/tools/llm/simple/simple-tool-executor.js +159 -0
  346. package/dist/tools/llm/simple/simple-tool-executor.js.map +1 -0
  347. package/dist/tools/llm/simple/todo-tools.d.ts +15 -0
  348. package/dist/tools/llm/simple/todo-tools.d.ts.map +1 -0
  349. package/dist/tools/llm/simple/todo-tools.js +145 -0
  350. package/dist/tools/llm/simple/todo-tools.js.map +1 -0
  351. package/dist/tools/llm/simple/user-interaction-tools.d.ts +22 -0
  352. package/dist/tools/llm/simple/user-interaction-tools.d.ts.map +1 -0
  353. package/dist/tools/llm/simple/user-interaction-tools.js +168 -0
  354. package/dist/tools/llm/simple/user-interaction-tools.js.map +1 -0
  355. package/dist/tools/office/common/constants.d.ts +192 -0
  356. package/dist/tools/office/common/constants.d.ts.map +1 -0
  357. package/dist/tools/office/common/constants.js +165 -0
  358. package/dist/tools/office/common/constants.js.map +1 -0
  359. package/dist/tools/office/common/index.d.ts +4 -0
  360. package/dist/tools/office/common/index.d.ts.map +1 -0
  361. package/dist/tools/office/common/index.js +3 -0
  362. package/dist/tools/office/common/index.js.map +1 -0
  363. package/dist/tools/office/common/types.d.ts +82 -0
  364. package/dist/tools/office/common/types.d.ts.map +1 -0
  365. package/dist/tools/office/common/types.js +2 -0
  366. package/dist/tools/office/common/types.js.map +1 -0
  367. package/dist/tools/office/common/utils.d.ts +16 -0
  368. package/dist/tools/office/common/utils.d.ts.map +1 -0
  369. package/dist/tools/office/common/utils.js +60 -0
  370. package/dist/tools/office/common/utils.js.map +1 -0
  371. package/dist/tools/office/excel-client.d.ts +219 -0
  372. package/dist/tools/office/excel-client.d.ts.map +1 -0
  373. package/dist/tools/office/excel-client.js +2346 -0
  374. package/dist/tools/office/excel-client.js.map +1 -0
  375. package/dist/tools/office/excel-tools/cells.d.ts +10 -0
  376. package/dist/tools/office/excel-tools/cells.d.ts.map +1 -0
  377. package/dist/tools/office/excel-tools/cells.js +283 -0
  378. package/dist/tools/office/excel-tools/cells.js.map +1 -0
  379. package/dist/tools/office/excel-tools/charts.d.ts +6 -0
  380. package/dist/tools/office/excel-tools/charts.d.ts.map +1 -0
  381. package/dist/tools/office/excel-tools/charts.js +124 -0
  382. package/dist/tools/office/excel-tools/charts.js.map +1 -0
  383. package/dist/tools/office/excel-tools/comments.d.ts +6 -0
  384. package/dist/tools/office/excel-tools/comments.d.ts.map +1 -0
  385. package/dist/tools/office/excel-tools/comments.js +114 -0
  386. package/dist/tools/office/excel-tools/comments.js.map +1 -0
  387. package/dist/tools/office/excel-tools/data-ops.d.ts +10 -0
  388. package/dist/tools/office/excel-tools/data-ops.d.ts.map +1 -0
  389. package/dist/tools/office/excel-tools/data-ops.js +266 -0
  390. package/dist/tools/office/excel-tools/data-ops.js.map +1 -0
  391. package/dist/tools/office/excel-tools/export.d.ts +5 -0
  392. package/dist/tools/office/excel-tools/export.d.ts.map +1 -0
  393. package/dist/tools/office/excel-tools/export.js +75 -0
  394. package/dist/tools/office/excel-tools/export.js.map +1 -0
  395. package/dist/tools/office/excel-tools/formatting.d.ts +10 -0
  396. package/dist/tools/office/excel-tools/formatting.d.ts.map +1 -0
  397. package/dist/tools/office/excel-tools/formatting.js +276 -0
  398. package/dist/tools/office/excel-tools/formatting.js.map +1 -0
  399. package/dist/tools/office/excel-tools/index.d.ts +18 -0
  400. package/dist/tools/office/excel-tools/index.d.ts.map +1 -0
  401. package/dist/tools/office/excel-tools/index.js +54 -0
  402. package/dist/tools/office/excel-tools/index.js.map +1 -0
  403. package/dist/tools/office/excel-tools/launch.d.ts +10 -0
  404. package/dist/tools/office/excel-tools/launch.d.ts.map +1 -0
  405. package/dist/tools/office/excel-tools/launch.js +250 -0
  406. package/dist/tools/office/excel-tools/launch.js.map +1 -0
  407. package/dist/tools/office/excel-tools/media.d.ts +5 -0
  408. package/dist/tools/office/excel-tools/media.d.ts.map +1 -0
  409. package/dist/tools/office/excel-tools/media.js +84 -0
  410. package/dist/tools/office/excel-tools/media.js.map +1 -0
  411. package/dist/tools/office/excel-tools/named-ranges.d.ts +6 -0
  412. package/dist/tools/office/excel-tools/named-ranges.d.ts.map +1 -0
  413. package/dist/tools/office/excel-tools/named-ranges.js +113 -0
  414. package/dist/tools/office/excel-tools/named-ranges.js.map +1 -0
  415. package/dist/tools/office/excel-tools/protection.d.ts +5 -0
  416. package/dist/tools/office/excel-tools/protection.d.ts.map +1 -0
  417. package/dist/tools/office/excel-tools/protection.js +75 -0
  418. package/dist/tools/office/excel-tools/protection.js.map +1 -0
  419. package/dist/tools/office/excel-tools/rows-columns.d.ts +11 -0
  420. package/dist/tools/office/excel-tools/rows-columns.d.ts.map +1 -0
  421. package/dist/tools/office/excel-tools/rows-columns.js +293 -0
  422. package/dist/tools/office/excel-tools/rows-columns.js.map +1 -0
  423. package/dist/tools/office/excel-tools/sheet-builders.d.ts +9 -0
  424. package/dist/tools/office/excel-tools/sheet-builders.d.ts.map +1 -0
  425. package/dist/tools/office/excel-tools/sheet-builders.js +483 -0
  426. package/dist/tools/office/excel-tools/sheet-builders.js.map +1 -0
  427. package/dist/tools/office/excel-tools/sheets.d.ts +8 -0
  428. package/dist/tools/office/excel-tools/sheets.d.ts.map +1 -0
  429. package/dist/tools/office/excel-tools/sheets.js +182 -0
  430. package/dist/tools/office/excel-tools/sheets.js.map +1 -0
  431. package/dist/tools/office/excel-tools/validation.d.ts +7 -0
  432. package/dist/tools/office/excel-tools/validation.d.ts.map +1 -0
  433. package/dist/tools/office/excel-tools/validation.js +175 -0
  434. package/dist/tools/office/excel-tools/validation.js.map +1 -0
  435. package/dist/tools/office/excel-tools.d.ts +3 -0
  436. package/dist/tools/office/excel-tools.d.ts.map +1 -0
  437. package/dist/tools/office/excel-tools.js +3 -0
  438. package/dist/tools/office/excel-tools.js.map +1 -0
  439. package/dist/tools/office/index.d.ts +6 -0
  440. package/dist/tools/office/index.d.ts.map +1 -0
  441. package/dist/tools/office/index.js +9 -0
  442. package/dist/tools/office/index.js.map +1 -0
  443. package/dist/tools/office/office-client-base.d.ts +33 -0
  444. package/dist/tools/office/office-client-base.d.ts.map +1 -0
  445. package/dist/tools/office/office-client-base.js +166 -0
  446. package/dist/tools/office/office-client-base.js.map +1 -0
  447. package/dist/tools/office/office-client.d.ts +196 -0
  448. package/dist/tools/office/office-client.d.ts.map +1 -0
  449. package/dist/tools/office/office-client.js +200 -0
  450. package/dist/tools/office/office-client.js.map +1 -0
  451. package/dist/tools/office/powerpoint-client.d.ts +148 -0
  452. package/dist/tools/office/powerpoint-client.d.ts.map +1 -0
  453. package/dist/tools/office/powerpoint-client.js +1310 -0
  454. package/dist/tools/office/powerpoint-client.js.map +1 -0
  455. package/dist/tools/office/powerpoint-tools/effects.d.ts +9 -0
  456. package/dist/tools/office/powerpoint-tools/effects.d.ts.map +1 -0
  457. package/dist/tools/office/powerpoint-tools/effects.js +246 -0
  458. package/dist/tools/office/powerpoint-tools/effects.js.map +1 -0
  459. package/dist/tools/office/powerpoint-tools/export.d.ts +6 -0
  460. package/dist/tools/office/powerpoint-tools/export.d.ts.map +1 -0
  461. package/dist/tools/office/powerpoint-tools/export.js +123 -0
  462. package/dist/tools/office/powerpoint-tools/export.js.map +1 -0
  463. package/dist/tools/office/powerpoint-tools/index.d.ts +15 -0
  464. package/dist/tools/office/powerpoint-tools/index.d.ts.map +1 -0
  465. package/dist/tools/office/powerpoint-tools/index.js +40 -0
  466. package/dist/tools/office/powerpoint-tools/index.js.map +1 -0
  467. package/dist/tools/office/powerpoint-tools/launch.d.ts +9 -0
  468. package/dist/tools/office/powerpoint-tools/launch.d.ts.map +1 -0
  469. package/dist/tools/office/powerpoint-tools/launch.js +218 -0
  470. package/dist/tools/office/powerpoint-tools/launch.js.map +1 -0
  471. package/dist/tools/office/powerpoint-tools/layout-builders.d.ts +12 -0
  472. package/dist/tools/office/powerpoint-tools/layout-builders.d.ts.map +1 -0
  473. package/dist/tools/office/powerpoint-tools/layout-builders.js +785 -0
  474. package/dist/tools/office/powerpoint-tools/layout-builders.js.map +1 -0
  475. package/dist/tools/office/powerpoint-tools/media.d.ts +8 -0
  476. package/dist/tools/office/powerpoint-tools/media.d.ts.map +1 -0
  477. package/dist/tools/office/powerpoint-tools/media.js +211 -0
  478. package/dist/tools/office/powerpoint-tools/media.js.map +1 -0
  479. package/dist/tools/office/powerpoint-tools/notes.d.ts +8 -0
  480. package/dist/tools/office/powerpoint-tools/notes.d.ts.map +1 -0
  481. package/dist/tools/office/powerpoint-tools/notes.js +171 -0
  482. package/dist/tools/office/powerpoint-tools/notes.js.map +1 -0
  483. package/dist/tools/office/powerpoint-tools/sections.d.ts +6 -0
  484. package/dist/tools/office/powerpoint-tools/sections.d.ts.map +1 -0
  485. package/dist/tools/office/powerpoint-tools/sections.js +104 -0
  486. package/dist/tools/office/powerpoint-tools/sections.js.map +1 -0
  487. package/dist/tools/office/powerpoint-tools/shapes.d.ts +22 -0
  488. package/dist/tools/office/powerpoint-tools/shapes.d.ts.map +1 -0
  489. package/dist/tools/office/powerpoint-tools/shapes.js +681 -0
  490. package/dist/tools/office/powerpoint-tools/shapes.js.map +1 -0
  491. package/dist/tools/office/powerpoint-tools/slides.d.ts +11 -0
  492. package/dist/tools/office/powerpoint-tools/slides.d.ts.map +1 -0
  493. package/dist/tools/office/powerpoint-tools/slides.js +283 -0
  494. package/dist/tools/office/powerpoint-tools/slides.js.map +1 -0
  495. package/dist/tools/office/powerpoint-tools/tables.d.ts +6 -0
  496. package/dist/tools/office/powerpoint-tools/tables.d.ts.map +1 -0
  497. package/dist/tools/office/powerpoint-tools/tables.js +132 -0
  498. package/dist/tools/office/powerpoint-tools/tables.js.map +1 -0
  499. package/dist/tools/office/powerpoint-tools/text.d.ts +12 -0
  500. package/dist/tools/office/powerpoint-tools/text.d.ts.map +1 -0
  501. package/dist/tools/office/powerpoint-tools/text.js +379 -0
  502. package/dist/tools/office/powerpoint-tools/text.js.map +1 -0
  503. package/dist/tools/office/powerpoint-tools.d.ts +3 -0
  504. package/dist/tools/office/powerpoint-tools.d.ts.map +1 -0
  505. package/dist/tools/office/powerpoint-tools.js +3 -0
  506. package/dist/tools/office/powerpoint-tools.js.map +1 -0
  507. package/dist/tools/office/word-client.d.ts +169 -0
  508. package/dist/tools/office/word-client.d.ts.map +1 -0
  509. package/dist/tools/office/word-client.js +1636 -0
  510. package/dist/tools/office/word-client.js.map +1 -0
  511. package/dist/tools/office/word-tools/bookmarks.d.ts +7 -0
  512. package/dist/tools/office/word-tools/bookmarks.d.ts.map +1 -0
  513. package/dist/tools/office/word-tools/bookmarks.js +146 -0
  514. package/dist/tools/office/word-tools/bookmarks.js.map +1 -0
  515. package/dist/tools/office/word-tools/comments.d.ts +7 -0
  516. package/dist/tools/office/word-tools/comments.d.ts.map +1 -0
  517. package/dist/tools/office/word-tools/comments.js +146 -0
  518. package/dist/tools/office/word-tools/comments.js.map +1 -0
  519. package/dist/tools/office/word-tools/content.d.ts +7 -0
  520. package/dist/tools/office/word-tools/content.d.ts.map +1 -0
  521. package/dist/tools/office/word-tools/content.js +168 -0
  522. package/dist/tools/office/word-tools/content.js.map +1 -0
  523. package/dist/tools/office/word-tools/export.d.ts +5 -0
  524. package/dist/tools/office/word-tools/export.d.ts.map +1 -0
  525. package/dist/tools/office/word-tools/export.js +73 -0
  526. package/dist/tools/office/word-tools/export.js.map +1 -0
  527. package/dist/tools/office/word-tools/formatting.d.ts +6 -0
  528. package/dist/tools/office/word-tools/formatting.d.ts.map +1 -0
  529. package/dist/tools/office/word-tools/formatting.js +129 -0
  530. package/dist/tools/office/word-tools/formatting.js.map +1 -0
  531. package/dist/tools/office/word-tools/headers-footers.d.ts +6 -0
  532. package/dist/tools/office/word-tools/headers-footers.d.ts.map +1 -0
  533. package/dist/tools/office/word-tools/headers-footers.js +117 -0
  534. package/dist/tools/office/word-tools/headers-footers.js.map +1 -0
  535. package/dist/tools/office/word-tools/index.d.ts +19 -0
  536. package/dist/tools/office/word-tools/index.d.ts.map +1 -0
  537. package/dist/tools/office/word-tools/index.js +60 -0
  538. package/dist/tools/office/word-tools/index.js.map +1 -0
  539. package/dist/tools/office/word-tools/launch.d.ts +10 -0
  540. package/dist/tools/office/word-tools/launch.d.ts.map +1 -0
  541. package/dist/tools/office/word-tools/launch.js +257 -0
  542. package/dist/tools/office/word-tools/launch.js.map +1 -0
  543. package/dist/tools/office/word-tools/lists.d.ts +5 -0
  544. package/dist/tools/office/word-tools/lists.d.ts.map +1 -0
  545. package/dist/tools/office/word-tools/lists.js +73 -0
  546. package/dist/tools/office/word-tools/lists.js.map +1 -0
  547. package/dist/tools/office/word-tools/navigation.d.ts +5 -0
  548. package/dist/tools/office/word-tools/navigation.d.ts.map +1 -0
  549. package/dist/tools/office/word-tools/navigation.js +85 -0
  550. package/dist/tools/office/word-tools/navigation.js.map +1 -0
  551. package/dist/tools/office/word-tools/page-setup.d.ts +7 -0
  552. package/dist/tools/office/word-tools/page-setup.d.ts.map +1 -0
  553. package/dist/tools/office/word-tools/page-setup.js +152 -0
  554. package/dist/tools/office/word-tools/page-setup.js.map +1 -0
  555. package/dist/tools/office/word-tools/section-builders.d.ts +12 -0
  556. package/dist/tools/office/word-tools/section-builders.d.ts.map +1 -0
  557. package/dist/tools/office/word-tools/section-builders.js +601 -0
  558. package/dist/tools/office/word-tools/section-builders.js.map +1 -0
  559. package/dist/tools/office/word-tools/tables.d.ts +8 -0
  560. package/dist/tools/office/word-tools/tables.d.ts.map +1 -0
  561. package/dist/tools/office/word-tools/tables.js +197 -0
  562. package/dist/tools/office/word-tools/tables.js.map +1 -0
  563. package/dist/tools/office/word-tools/text.d.ts +9 -0
  564. package/dist/tools/office/word-tools/text.d.ts.map +1 -0
  565. package/dist/tools/office/word-tools/text.js +245 -0
  566. package/dist/tools/office/word-tools/text.js.map +1 -0
  567. package/dist/tools/office/word-tools/undo-redo.d.ts +5 -0
  568. package/dist/tools/office/word-tools/undo-redo.d.ts.map +1 -0
  569. package/dist/tools/office/word-tools/undo-redo.js +73 -0
  570. package/dist/tools/office/word-tools/undo-redo.js.map +1 -0
  571. package/dist/tools/office/word-tools/watermarks.d.ts +5 -0
  572. package/dist/tools/office/word-tools/watermarks.d.ts.map +1 -0
  573. package/dist/tools/office/word-tools/watermarks.js +81 -0
  574. package/dist/tools/office/word-tools/watermarks.js.map +1 -0
  575. package/dist/tools/office/word-tools.d.ts +3 -0
  576. package/dist/tools/office/word-tools.d.ts.map +1 -0
  577. package/dist/tools/office/word-tools.js +3 -0
  578. package/dist/tools/office/word-tools.js.map +1 -0
  579. package/dist/tools/registry.d.ts +55 -0
  580. package/dist/tools/registry.d.ts.map +1 -0
  581. package/dist/tools/registry.js +296 -0
  582. package/dist/tools/registry.js.map +1 -0
  583. package/dist/tools/types.d.ts +88 -0
  584. package/dist/tools/types.d.ts.map +1 -0
  585. package/dist/tools/types.js +19 -0
  586. package/dist/tools/types.js.map +1 -0
  587. package/dist/types/index.d.ts +132 -0
  588. package/dist/types/index.d.ts.map +1 -0
  589. package/dist/types/index.js +2 -0
  590. package/dist/types/index.js.map +1 -0
  591. package/dist/ui/PlanExecuteView.d.ts +11 -0
  592. package/dist/ui/PlanExecuteView.d.ts.map +1 -0
  593. package/dist/ui/PlanExecuteView.js +27 -0
  594. package/dist/ui/PlanExecuteView.js.map +1 -0
  595. package/dist/ui/TodoPanel.d.ts +13 -0
  596. package/dist/ui/TodoPanel.d.ts.map +1 -0
  597. package/dist/ui/TodoPanel.js +138 -0
  598. package/dist/ui/TodoPanel.js.map +1 -0
  599. package/dist/ui/UpdateNotification.d.ts +13 -0
  600. package/dist/ui/UpdateNotification.d.ts.map +1 -0
  601. package/dist/ui/UpdateNotification.js +42 -0
  602. package/dist/ui/UpdateNotification.js.map +1 -0
  603. package/dist/ui/components/ActivityIndicator.d.ts +25 -0
  604. package/dist/ui/components/ActivityIndicator.d.ts.map +1 -0
  605. package/dist/ui/components/ActivityIndicator.js +116 -0
  606. package/dist/ui/components/ActivityIndicator.js.map +1 -0
  607. package/dist/ui/components/CommandBrowser.d.ts +10 -0
  608. package/dist/ui/components/CommandBrowser.d.ts.map +1 -0
  609. package/dist/ui/components/CommandBrowser.js +57 -0
  610. package/dist/ui/components/CommandBrowser.js.map +1 -0
  611. package/dist/ui/components/CustomTextInput.d.ts +13 -0
  612. package/dist/ui/components/CustomTextInput.d.ts.map +1 -0
  613. package/dist/ui/components/CustomTextInput.js +246 -0
  614. package/dist/ui/components/CustomTextInput.js.map +1 -0
  615. package/dist/ui/components/FileBrowser.d.ts +11 -0
  616. package/dist/ui/components/FileBrowser.d.ts.map +1 -0
  617. package/dist/ui/components/FileBrowser.js +45 -0
  618. package/dist/ui/components/FileBrowser.js.map +1 -0
  619. package/dist/ui/components/LLMSetupWizard.d.ts +8 -0
  620. package/dist/ui/components/LLMSetupWizard.d.ts.map +1 -0
  621. package/dist/ui/components/LLMSetupWizard.js +197 -0
  622. package/dist/ui/components/LLMSetupWizard.js.map +1 -0
  623. package/dist/ui/components/Logo.d.ts +20 -0
  624. package/dist/ui/components/Logo.d.ts.map +1 -0
  625. package/dist/ui/components/Logo.js +100 -0
  626. package/dist/ui/components/Logo.js.map +1 -0
  627. package/dist/ui/components/MarkdownRenderer.d.ts +9 -0
  628. package/dist/ui/components/MarkdownRenderer.d.ts.map +1 -0
  629. package/dist/ui/components/MarkdownRenderer.js +198 -0
  630. package/dist/ui/components/MarkdownRenderer.js.map +1 -0
  631. package/dist/ui/components/ModelSelector.d.ts +8 -0
  632. package/dist/ui/components/ModelSelector.d.ts.map +1 -0
  633. package/dist/ui/components/ModelSelector.js +111 -0
  634. package/dist/ui/components/ModelSelector.js.map +1 -0
  635. package/dist/ui/components/PlanExecuteApp.d.ts +23 -0
  636. package/dist/ui/components/PlanExecuteApp.d.ts.map +1 -0
  637. package/dist/ui/components/PlanExecuteApp.js +1377 -0
  638. package/dist/ui/components/PlanExecuteApp.js.map +1 -0
  639. package/dist/ui/components/ProgressBar.d.ts +10 -0
  640. package/dist/ui/components/ProgressBar.d.ts.map +1 -0
  641. package/dist/ui/components/ProgressBar.js +26 -0
  642. package/dist/ui/components/ProgressBar.js.map +1 -0
  643. package/dist/ui/components/StatusBar.d.ts +23 -0
  644. package/dist/ui/components/StatusBar.d.ts.map +1 -0
  645. package/dist/ui/components/StatusBar.js +162 -0
  646. package/dist/ui/components/StatusBar.js.map +1 -0
  647. package/dist/ui/components/ThinkingIndicator.d.ts +14 -0
  648. package/dist/ui/components/ThinkingIndicator.d.ts.map +1 -0
  649. package/dist/ui/components/ThinkingIndicator.js +63 -0
  650. package/dist/ui/components/ThinkingIndicator.js.map +1 -0
  651. package/dist/ui/components/TodoListView.d.ts +11 -0
  652. package/dist/ui/components/TodoListView.d.ts.map +1 -0
  653. package/dist/ui/components/TodoListView.js +69 -0
  654. package/dist/ui/components/TodoListView.js.map +1 -0
  655. package/dist/ui/components/ToolSelector.d.ts +7 -0
  656. package/dist/ui/components/ToolSelector.d.ts.map +1 -0
  657. package/dist/ui/components/ToolSelector.js +112 -0
  658. package/dist/ui/components/ToolSelector.js.map +1 -0
  659. package/dist/ui/components/dialogs/ApprovalDialog.d.ts +13 -0
  660. package/dist/ui/components/dialogs/ApprovalDialog.d.ts.map +1 -0
  661. package/dist/ui/components/dialogs/ApprovalDialog.js +175 -0
  662. package/dist/ui/components/dialogs/ApprovalDialog.js.map +1 -0
  663. package/dist/ui/components/dialogs/AskUserDialog.d.ts +9 -0
  664. package/dist/ui/components/dialogs/AskUserDialog.d.ts.map +1 -0
  665. package/dist/ui/components/dialogs/AskUserDialog.js +111 -0
  666. package/dist/ui/components/dialogs/AskUserDialog.js.map +1 -0
  667. package/dist/ui/components/dialogs/DocsBrowser.d.ts +8 -0
  668. package/dist/ui/components/dialogs/DocsBrowser.d.ts.map +1 -0
  669. package/dist/ui/components/dialogs/DocsBrowser.js +127 -0
  670. package/dist/ui/components/dialogs/DocsBrowser.js.map +1 -0
  671. package/dist/ui/components/dialogs/SettingsDialog.d.ts +10 -0
  672. package/dist/ui/components/dialogs/SettingsDialog.d.ts.map +1 -0
  673. package/dist/ui/components/dialogs/SettingsDialog.js +586 -0
  674. package/dist/ui/components/dialogs/SettingsDialog.js.map +1 -0
  675. package/dist/ui/components/dialogs/index.d.ts +3 -0
  676. package/dist/ui/components/dialogs/index.d.ts.map +1 -0
  677. package/dist/ui/components/dialogs/index.js +3 -0
  678. package/dist/ui/components/dialogs/index.js.map +1 -0
  679. package/dist/ui/components/index.d.ts +12 -0
  680. package/dist/ui/components/index.d.ts.map +1 -0
  681. package/dist/ui/components/index.js +9 -0
  682. package/dist/ui/components/index.js.map +1 -0
  683. package/dist/ui/components/panels/LogPanel.d.ts +7 -0
  684. package/dist/ui/components/panels/LogPanel.d.ts.map +1 -0
  685. package/dist/ui/components/panels/LogPanel.js +280 -0
  686. package/dist/ui/components/panels/LogPanel.js.map +1 -0
  687. package/dist/ui/components/panels/SessionPanel.d.ts +8 -0
  688. package/dist/ui/components/panels/SessionPanel.d.ts.map +1 -0
  689. package/dist/ui/components/panels/SessionPanel.js +81 -0
  690. package/dist/ui/components/panels/SessionPanel.js.map +1 -0
  691. package/dist/ui/components/panels/index.d.ts +4 -0
  692. package/dist/ui/components/panels/index.d.ts.map +1 -0
  693. package/dist/ui/components/panels/index.js +4 -0
  694. package/dist/ui/components/panels/index.js.map +1 -0
  695. package/dist/ui/components/views/ChatView.d.ts +12 -0
  696. package/dist/ui/components/views/ChatView.d.ts.map +1 -0
  697. package/dist/ui/components/views/ChatView.js +289 -0
  698. package/dist/ui/components/views/ChatView.js.map +1 -0
  699. package/dist/ui/components/views/index.d.ts +2 -0
  700. package/dist/ui/components/views/index.d.ts.map +1 -0
  701. package/dist/ui/components/views/index.js +2 -0
  702. package/dist/ui/components/views/index.js.map +1 -0
  703. package/dist/ui/contexts/TokenContext.d.ts +29 -0
  704. package/dist/ui/contexts/TokenContext.d.ts.map +1 -0
  705. package/dist/ui/contexts/TokenContext.js +79 -0
  706. package/dist/ui/contexts/TokenContext.js.map +1 -0
  707. package/dist/ui/hooks/atFileProcessor.d.ts +15 -0
  708. package/dist/ui/hooks/atFileProcessor.d.ts.map +1 -0
  709. package/dist/ui/hooks/atFileProcessor.js +88 -0
  710. package/dist/ui/hooks/atFileProcessor.js.map +1 -0
  711. package/dist/ui/hooks/index.d.ts +9 -0
  712. package/dist/ui/hooks/index.d.ts.map +1 -0
  713. package/dist/ui/hooks/index.js +9 -0
  714. package/dist/ui/hooks/index.js.map +1 -0
  715. package/dist/ui/hooks/slashCommandProcessor.d.ts +21 -0
  716. package/dist/ui/hooks/slashCommandProcessor.d.ts.map +1 -0
  717. package/dist/ui/hooks/slashCommandProcessor.js +96 -0
  718. package/dist/ui/hooks/slashCommandProcessor.js.map +1 -0
  719. package/dist/ui/hooks/useCommandBrowserState.d.ts +12 -0
  720. package/dist/ui/hooks/useCommandBrowserState.d.ts.map +1 -0
  721. package/dist/ui/hooks/useCommandBrowserState.js +66 -0
  722. package/dist/ui/hooks/useCommandBrowserState.js.map +1 -0
  723. package/dist/ui/hooks/useFileBrowserState.d.ts +15 -0
  724. package/dist/ui/hooks/useFileBrowserState.d.ts.map +1 -0
  725. package/dist/ui/hooks/useFileBrowserState.js +80 -0
  726. package/dist/ui/hooks/useFileBrowserState.js.map +1 -0
  727. package/dist/ui/hooks/useFileList.d.ts +20 -0
  728. package/dist/ui/hooks/useFileList.d.ts.map +1 -0
  729. package/dist/ui/hooks/useFileList.js +57 -0
  730. package/dist/ui/hooks/useFileList.js.map +1 -0
  731. package/dist/ui/hooks/useInputHistory.d.ts +9 -0
  732. package/dist/ui/hooks/useInputHistory.d.ts.map +1 -0
  733. package/dist/ui/hooks/useInputHistory.js +68 -0
  734. package/dist/ui/hooks/useInputHistory.js.map +1 -0
  735. package/dist/ui/hooks/usePlanExecution.d.ts +8 -0
  736. package/dist/ui/hooks/usePlanExecution.d.ts.map +1 -0
  737. package/dist/ui/hooks/usePlanExecution.js +218 -0
  738. package/dist/ui/hooks/usePlanExecution.js.map +1 -0
  739. package/dist/ui/hooks/useTerminalWidth.d.ts +4 -0
  740. package/dist/ui/hooks/useTerminalWidth.d.ts.map +1 -0
  741. package/dist/ui/hooks/useTerminalWidth.js +26 -0
  742. package/dist/ui/hooks/useTerminalWidth.js.map +1 -0
  743. package/dist/ui/index.d.ts +7 -0
  744. package/dist/ui/index.d.ts.map +1 -0
  745. package/dist/ui/index.js +7 -0
  746. package/dist/ui/index.js.map +1 -0
  747. package/dist/ui/ink-entry.d.ts +3 -0
  748. package/dist/ui/ink-entry.d.ts.map +1 -0
  749. package/dist/ui/ink-entry.js +22 -0
  750. package/dist/ui/ink-entry.js.map +1 -0
  751. package/dist/utils/file-system.d.ts +9 -0
  752. package/dist/utils/file-system.d.ts.map +1 -0
  753. package/dist/utils/file-system.js +99 -0
  754. package/dist/utils/file-system.js.map +1 -0
  755. package/dist/utils/git-utils.d.ts +2 -0
  756. package/dist/utils/git-utils.d.ts.map +1 -0
  757. package/dist/utils/git-utils.js +16 -0
  758. package/dist/utils/git-utils.js.map +1 -0
  759. package/dist/utils/json-stream-logger.d.ts +74 -0
  760. package/dist/utils/json-stream-logger.d.ts.map +1 -0
  761. package/dist/utils/json-stream-logger.js +808 -0
  762. package/dist/utils/json-stream-logger.js.map +1 -0
  763. package/dist/utils/logger.d.ts +152 -0
  764. package/dist/utils/logger.d.ts.map +1 -0
  765. package/dist/utils/logger.js +1672 -0
  766. package/dist/utils/logger.js.map +1 -0
  767. package/dist/utils/platform-utils.d.ts +19 -0
  768. package/dist/utils/platform-utils.d.ts.map +1 -0
  769. package/dist/utils/platform-utils.js +134 -0
  770. package/dist/utils/platform-utils.js.map +1 -0
  771. package/dist/utils/wsl-utils.d.ts +4 -0
  772. package/dist/utils/wsl-utils.d.ts.map +1 -0
  773. package/dist/utils/wsl-utils.js +72 -0
  774. package/dist/utils/wsl-utils.js.map +1 -0
  775. package/package.json +132 -0
  776. package/scripts/patch-yoga.js +48 -0
@@ -0,0 +1,2346 @@
1
+ import { OfficeClientBase } from './office-client-base.js';
2
+ function columnLetterToNumber(column) {
3
+ let result = 0;
4
+ for (let i = 0; i < column.length; i++) {
5
+ result = result * 26 + (column.charCodeAt(i) - 'A'.charCodeAt(0) + 1);
6
+ }
7
+ return result;
8
+ }
9
+ function columnNumberToLetter(num) {
10
+ if (num < 1) {
11
+ throw new Error(`Invalid column number: ${num}. Must be >= 1`);
12
+ }
13
+ if (num > 16384) {
14
+ throw new Error(`Invalid column number: ${num}. Excel maximum is 16384 (XFD)`);
15
+ }
16
+ let result = '';
17
+ while (num > 0) {
18
+ num--;
19
+ result = String.fromCharCode('A'.charCodeAt(0) + (num % 26)) + result;
20
+ num = Math.floor(num / 26);
21
+ }
22
+ return result;
23
+ }
24
+ function formatFormulaCriteria(criteria) {
25
+ const cellRefPattern = /&\$?[A-Z]+\$?\d+|&\$?[A-Z]+:\$?[A-Z]+/i;
26
+ if (cellRefPattern.test(criteria)) {
27
+ return criteria;
28
+ }
29
+ if (criteria.startsWith('"') && criteria.endsWith('"')) {
30
+ return criteria;
31
+ }
32
+ const escaped = criteria.replace(/"/g, '""');
33
+ return `"${escaped}"`;
34
+ }
35
+ export class ExcelClient extends OfficeClientBase {
36
+ comProgId = 'Excel.Application';
37
+ async excelLaunch() {
38
+ return this.executePowerShell(`
39
+ try {
40
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
41
+ $excel.Visible = -1 # msoTrue
42
+ @{ success = $true; message = "Connected to existing Excel instance" } | ConvertTo-Json -Compress
43
+ } catch {
44
+ $excel = New-Object -ComObject Excel.Application
45
+ $excel.Visible = -1 # msoTrue
46
+ @{ success = $true; message = "Launched new Excel instance" } | ConvertTo-Json -Compress
47
+ }
48
+ `);
49
+ }
50
+ async excelCreate() {
51
+ return this.executePowerShell(`
52
+ try {
53
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
54
+ } catch {
55
+ $excel = New-Object -ComObject Excel.Application
56
+ }
57
+ $excel.DisplayAlerts = $false
58
+ $excel.Visible = -1 # msoTrue
59
+ $workbook = $excel.Workbooks.Add()
60
+ $excel.DisplayAlerts = $true
61
+ @{ success = $true; message = "Created new workbook"; workbook_name = $workbook.Name } | ConvertTo-Json -Compress
62
+ `);
63
+ }
64
+ async excelOpen(filePath) {
65
+ const windowsPath = this.toWindowsPath(filePath).replace(/'/g, "''");
66
+ return this.executePowerShell(`
67
+ try {
68
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
69
+ } catch {
70
+ $excel = New-Object -ComObject Excel.Application
71
+ }
72
+ $excel.DisplayAlerts = $false
73
+ $excel.Visible = -1 # msoTrue
74
+ $workbook = $excel.Workbooks.Open('${windowsPath}')
75
+ $excel.DisplayAlerts = $true
76
+ @{ success = $true; message = "Workbook opened"; workbook_name = $workbook.Name; path = $workbook.FullName } | ConvertTo-Json -Compress
77
+ `);
78
+ }
79
+ async excelWriteCell(cell, value, sheet, options) {
80
+ const strValue = String(value);
81
+ const escapedValue = strValue.replace(/'/g, "''");
82
+ const sheetScript = sheet ? `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` : '$sheet = $workbook.ActiveSheet';
83
+ const hasKorean = /[가-힣ㄱ-ㅎㅏ-ㅣ]/.test(strValue);
84
+ const fontName = options?.fontName || (hasKorean ? 'Malgun Gothic' : '');
85
+ const formatScript = [];
86
+ if (fontName)
87
+ formatScript.push(`$range.Font.Name = '${fontName.replace(/'/g, "''")}'`);
88
+ if (options?.fontSize)
89
+ formatScript.push(`$range.Font.Size = ${options.fontSize}`);
90
+ if (options?.bold !== undefined)
91
+ formatScript.push(`$range.Font.Bold = ${options.bold ? '$true' : '$false'}`);
92
+ let valueScript;
93
+ if (options?.asText) {
94
+ valueScript = `$range.NumberFormat = '@'; $range.Value = '${escapedValue}'`;
95
+ }
96
+ else if (strValue.startsWith('=')) {
97
+ valueScript = `$range.Formula = '${escapedValue}'`;
98
+ }
99
+ else if (typeof value === 'number' || (strValue !== '' && !isNaN(Number(strValue)) && strValue.trim() !== '')) {
100
+ valueScript = `$range.Value = ${strValue}`;
101
+ }
102
+ else if (/^\d{4}-\d{2}-\d{2}$/.test(strValue)) {
103
+ const [year, month, day] = strValue.split('-');
104
+ valueScript = `$range.Value = (Get-Date -Year ${year} -Month ${month} -Day ${day}).ToOADate()`;
105
+ }
106
+ else if (/^\d{1,2}\/\d{1,2}\/\d{4}$/.test(strValue)) {
107
+ valueScript = `$range.Value = '${escapedValue}'`;
108
+ }
109
+ else {
110
+ valueScript = `$range.Value = '${escapedValue}'`;
111
+ }
112
+ return this.executePowerShell(`
113
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
114
+ $workbook = $excel.ActiveWorkbook
115
+ ${sheetScript}
116
+ $range = $sheet.Range('${cell}')
117
+ ${valueScript}
118
+ ${formatScript.join('\n')}
119
+ @{ success = $true; message = "Value written to ${cell}" } | ConvertTo-Json -Compress
120
+ `);
121
+ }
122
+ async excelReadCell(cell, sheet) {
123
+ const sheetScript = sheet ? `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` : '$sheet = $workbook.ActiveSheet';
124
+ return this.executePowerShell(`
125
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
126
+ $workbook = $excel.ActiveWorkbook
127
+ ${sheetScript}
128
+ $value = $sheet.Range('${cell}').Value2
129
+ @{ success = $true; cell = '${cell}'; value = $value } | ConvertTo-Json -Compress
130
+ `);
131
+ }
132
+ async excelWriteRange(startCell, values, sheet) {
133
+ const rows = values.length;
134
+ const cols = Math.max(...values.map(row => (row ? row.length : 0)), 0);
135
+ const sheetScript = sheet ? `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` : '$sheet = $workbook.ActiveSheet';
136
+ let hasKorean = false;
137
+ const toPsValue = (v) => {
138
+ const str = String(v);
139
+ if (/[가-힣ㄱ-ㅎㅏ-ㅣ]/.test(str))
140
+ hasKorean = true;
141
+ if (typeof v === 'number' || (str !== '' && !isNaN(Number(str)) && str.trim() !== '')) {
142
+ return str;
143
+ }
144
+ if (/^\d{4}-\d{2}-\d{2}$/.test(str)) {
145
+ const [year, month, day] = str.split('-');
146
+ return `([DateTime]::new(${year},${month},${day})).ToOADate()`;
147
+ }
148
+ return `'${str.replace(/'/g, "''")}'`;
149
+ };
150
+ const cellAssignments = [];
151
+ const formulaCells = [];
152
+ for (let i = 0; i < values.length; i++) {
153
+ const row = values[i];
154
+ if (!row)
155
+ continue;
156
+ for (let j = 0; j < row.length; j++) {
157
+ const str = String(row[j]);
158
+ if (str.startsWith('=')) {
159
+ formulaCells.push({ row: i, col: j, formula: str.replace(/'/g, "''") });
160
+ cellAssignments.push(`$data[${i},${j}] = ''`);
161
+ }
162
+ else {
163
+ cellAssignments.push(`$data[${i},${j}] = ${toPsValue(row[j])}`);
164
+ }
165
+ }
166
+ }
167
+ const formulaScript = formulaCells.map(f => `$sheet.Cells($startRange.Row + ${f.row}, $startRange.Column + ${f.col}).Formula = '${f.formula}'`).join('\n');
168
+ const fontScript = hasKorean ? "$range.Font.Name = 'Malgun Gothic'" : '';
169
+ return this.executePowerShell(`
170
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
171
+ $workbook = $excel.ActiveWorkbook
172
+ ${sheetScript}
173
+ $startRange = $sheet.Range('${startCell}')
174
+ $endCell = $sheet.Cells($startRange.Row + ${rows - 1}, $startRange.Column + ${cols - 1})
175
+ $range = $sheet.Range($startRange, $endCell)
176
+ $data = New-Object 'object[,]' ${rows},${cols}
177
+ ${cellAssignments.join('\n')}
178
+ $range.Value = $data
179
+ ${formulaScript}
180
+ ${fontScript}
181
+ @{ success = $true; message = "Range written from ${startCell} (${rows}x${cols})" } | ConvertTo-Json -Compress
182
+ `);
183
+ }
184
+ async excelReadRange(range, sheet) {
185
+ const sheetScript = sheet ? `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` : '$sheet = $workbook.ActiveSheet';
186
+ return this.executePowerShell(`
187
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
188
+ $workbook = $excel.ActiveWorkbook
189
+ ${sheetScript}
190
+ $range = $sheet.Range('${range}')
191
+ $rows = $range.Rows.Count
192
+ $cols = $range.Columns.Count
193
+ $startRow = $range.Row
194
+ $startCol = $range.Column
195
+ $lines = @()
196
+ for ($r = 0; $r -lt $rows; $r++) {
197
+ $parts = @()
198
+ for ($c = 0; $c -lt $cols; $c++) {
199
+ $cell = $range.Cells($r + 1, $c + 1)
200
+ $addr = $cell.Address($false, $false)
201
+ $val = $cell.Value2
202
+ if ($cell.HasFormula) { $val = $cell.Formula }
203
+ if ($null -eq $val) { $val = '' }
204
+ $parts += "$addr=$val"
205
+ }
206
+ $lines += ($parts -join ' | ')
207
+ }
208
+ $table = $lines -join [char]10
209
+ @{ success = $true; range = '${range}'; rows = $rows; columns = $cols; table = $table } | ConvertTo-Json -Compress -Depth 10
210
+ `);
211
+ }
212
+ async excelSave(filePath) {
213
+ const windowsPath = filePath ? this.toWindowsPath(filePath).replace(/'/g, "''") : '';
214
+ return this.executePowerShell(`
215
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
216
+ $workbook = $excel.ActiveWorkbook
217
+ ${windowsPath ? `$workbook.SaveAs('${windowsPath}')` : '$workbook.Save()'}
218
+ @{ success = $true; message = "Workbook saved"; path = $workbook.FullName } | ConvertTo-Json -Compress
219
+ `);
220
+ }
221
+ async excelClose(save = false) {
222
+ return this.executePowerShell(`
223
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
224
+ $workbook = $excel.ActiveWorkbook
225
+ $workbook.Close(${save ? '$true' : '$false'})
226
+ @{ success = $true; message = "Workbook closed" } | ConvertTo-Json -Compress
227
+ `);
228
+ }
229
+ async excelQuit(save = false) {
230
+ return this.executePowerShell(`
231
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
232
+ if (${save ? '$true' : '$false'}) {
233
+ foreach ($wb in $excel.Workbooks) { $wb.Save() }
234
+ }
235
+ $excel.Quit()
236
+ @{ success = $true; message = "Excel closed" } | ConvertTo-Json -Compress
237
+ `);
238
+ }
239
+ async excelSetFormula(cell, formula, sheet) {
240
+ const escapedFormula = formula.replace(/'/g, "''");
241
+ const sheetScript = sheet ? `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` : '$sheet = $workbook.ActiveSheet';
242
+ return this.executePowerShell(`
243
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
244
+ $workbook = $excel.ActiveWorkbook
245
+ ${sheetScript}
246
+ $sheet.Range('${cell}').Formula = '${escapedFormula}'
247
+ @{ success = $true; message = "Formula set in ${cell}" } | ConvertTo-Json -Compress
248
+ `);
249
+ }
250
+ async excelSetFont(range, options, sheet) {
251
+ const sheetScript = sheet ? `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` : '$sheet = $workbook.ActiveSheet';
252
+ const commands = [];
253
+ if (options.fontName)
254
+ commands.push(`$range.Font.Name = '${options.fontName.replace(/'/g, "''")}'`);
255
+ if (options.fontSize)
256
+ commands.push(`$range.Font.Size = ${options.fontSize}`);
257
+ if (options.bold !== undefined)
258
+ commands.push(`$range.Font.Bold = ${options.bold ? '$true' : '$false'}`);
259
+ if (options.italic !== undefined)
260
+ commands.push(`$range.Font.Italic = ${options.italic ? '$true' : '$false'}`);
261
+ if (options.underline !== undefined)
262
+ commands.push(`$range.Font.Underline = ${options.underline ? '2' : '0'}`);
263
+ if (options.color) {
264
+ const rgb = this.hexToRgb(options.color);
265
+ if (rgb)
266
+ commands.push(`$range.Font.Color = ${rgb.r + rgb.g * 256 + rgb.b * 65536}`);
267
+ }
268
+ return this.executePowerShell(`
269
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
270
+ $workbook = $excel.ActiveWorkbook
271
+ ${sheetScript}
272
+ $range = $sheet.Range('${range}')
273
+ ${commands.join('\n')}
274
+ @{ success = $true; message = "Font properties set for ${range}" } | ConvertTo-Json -Compress
275
+ `);
276
+ }
277
+ async excelSetAlignment(range, options, sheet) {
278
+ const hAlignMap = { left: -4131, center: -4108, right: -4152 };
279
+ const vAlignMap = { top: -4160, center: -4108, bottom: -4107 };
280
+ const sheetScript = sheet ? `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` : '$sheet = $workbook.ActiveSheet';
281
+ const commands = [];
282
+ if (options.horizontal)
283
+ commands.push(`$range.HorizontalAlignment = ${hAlignMap[options.horizontal]}`);
284
+ if (options.vertical)
285
+ commands.push(`$range.VerticalAlignment = ${vAlignMap[options.vertical]}`);
286
+ if (options.wrapText !== undefined)
287
+ commands.push(`$range.WrapText = ${options.wrapText ? '$true' : '$false'}`);
288
+ if (options.orientation !== undefined)
289
+ commands.push(`$range.Orientation = ${options.orientation}`);
290
+ return this.executePowerShell(`
291
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
292
+ $workbook = $excel.ActiveWorkbook
293
+ ${sheetScript}
294
+ $range = $sheet.Range('${range}')
295
+ ${commands.join('\n')}
296
+ @{ success = $true; message = "Alignment set for ${range}" } | ConvertTo-Json -Compress
297
+ `);
298
+ }
299
+ async excelSetColumnWidth(column, width, autoFit, sheet) {
300
+ const sheetScript = sheet ? `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` : '$sheet = $workbook.ActiveSheet';
301
+ return this.executePowerShell(`
302
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
303
+ $workbook = $excel.ActiveWorkbook
304
+ ${sheetScript}
305
+ $col = $sheet.Columns('${column}')
306
+ ${autoFit ? '$col.AutoFit()' : `$col.ColumnWidth = ${width || 10}`}
307
+ @{ success = $true; message = "Column ${column} width set" } | ConvertTo-Json -Compress
308
+ `);
309
+ }
310
+ async excelSetRowHeight(row, height, autoFit, sheet) {
311
+ const sheetScript = sheet ? `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` : '$sheet = $workbook.ActiveSheet';
312
+ return this.executePowerShell(`
313
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
314
+ $workbook = $excel.ActiveWorkbook
315
+ ${sheetScript}
316
+ $row = $sheet.Rows(${row})
317
+ ${autoFit ? '$row.AutoFit()' : `$row.RowHeight = ${height || 15}`}
318
+ @{ success = $true; message = "Row ${row} height set" } | ConvertTo-Json -Compress
319
+ `);
320
+ }
321
+ async excelMergeCells(range, sheet) {
322
+ const sheetScript = sheet ? `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` : '$sheet = $workbook.ActiveSheet';
323
+ return this.executePowerShell(`
324
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
325
+ $workbook = $excel.ActiveWorkbook
326
+ ${sheetScript}
327
+ $sheet.Range('${range}').Merge()
328
+ @{ success = $true; message = "Cells merged: ${range}" } | ConvertTo-Json -Compress
329
+ `);
330
+ }
331
+ async excelSetBorder(range, options, sheet) {
332
+ const styleMap = { thin: 1, medium: 1, thick: 1, double: -4119, dotted: -4118, dashed: -4115 };
333
+ const weightMap = { thin: 2, medium: -4138, thick: 4, double: 2, dotted: 2, dashed: 2 };
334
+ const edgeMap = { left: 7, right: 10, top: 8, bottom: 9, all: -1 };
335
+ const sheetScript = sheet ? `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` : '$sheet = $workbook.ActiveSheet';
336
+ const edges = options.edges || ['all'];
337
+ const borderStyle = options.style ? styleMap[options.style] : 1;
338
+ const borderWeight = options.style ? weightMap[options.style] : 2;
339
+ let borderScript = '';
340
+ if (edges.includes('all')) {
341
+ borderScript = `
342
+ $range.Borders.LineStyle = ${borderStyle}
343
+ $range.Borders.Weight = ${borderWeight}`;
344
+ }
345
+ else {
346
+ borderScript = edges.map(e => `$range.Borders(${edgeMap[e]}).LineStyle = ${borderStyle}
347
+ $range.Borders(${edgeMap[e]}).Weight = ${borderWeight}`).join('\n');
348
+ }
349
+ return this.executePowerShell(`
350
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
351
+ $workbook = $excel.ActiveWorkbook
352
+ ${sheetScript}
353
+ $range = $sheet.Range('${range}')
354
+ ${borderScript}
355
+ @{ success = $true; message = "Border set for ${range}" } | ConvertTo-Json -Compress
356
+ `);
357
+ }
358
+ async excelSetFill(range, color, sheet) {
359
+ const rgb = this.hexToRgb(color);
360
+ const colorValue = rgb ? rgb.r + rgb.g * 256 + rgb.b * 65536 : 0;
361
+ const sheetScript = sheet ? `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` : '$sheet = $workbook.ActiveSheet';
362
+ return this.executePowerShell(`
363
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
364
+ $workbook = $excel.ActiveWorkbook
365
+ ${sheetScript}
366
+ $sheet.Range('${range}').Interior.Color = ${colorValue}
367
+ @{ success = $true; message = "Fill color set for ${range}" } | ConvertTo-Json -Compress
368
+ `);
369
+ }
370
+ async excelSetNumberFormat(range, format, sheet) {
371
+ const escapedFormat = format.replace(/'/g, "''");
372
+ const sheetScript = sheet ? `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` : '$sheet = $workbook.ActiveSheet';
373
+ return this.executePowerShell(`
374
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
375
+ $workbook = $excel.ActiveWorkbook
376
+ ${sheetScript}
377
+ $sheet.Range('${range}').NumberFormat = '${escapedFormat}'
378
+ @{ success = $true; message = "Number format set for ${range}" } | ConvertTo-Json -Compress
379
+ `);
380
+ }
381
+ async excelAddSheet(name, position) {
382
+ const escapedName = name?.replace(/'/g, "''") || '';
383
+ let positionScript = '';
384
+ if (position === 'start') {
385
+ positionScript = ', [ref]$workbook.Sheets(1)';
386
+ }
387
+ else if (position === 'end') {
388
+ positionScript = ', , [ref]$workbook.Sheets($workbook.Sheets.Count)';
389
+ }
390
+ else if (position) {
391
+ positionScript = `, , [ref]$workbook.Sheets('${position.replace(/'/g, "''")}')`;
392
+ }
393
+ return this.executePowerShell(`
394
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
395
+ $workbook = $excel.ActiveWorkbook
396
+ $newSheet = $workbook.Sheets.Add(${positionScript})
397
+ ${escapedName ? `$newSheet.Name = '${escapedName}'` : ''}
398
+ @{ success = $true; message = "Sheet added"; sheet_name = $newSheet.Name } | ConvertTo-Json -Compress
399
+ `);
400
+ }
401
+ async excelDeleteSheet(name) {
402
+ const escapedName = name.replace(/'/g, "''");
403
+ return this.executePowerShell(`
404
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
405
+ $workbook = $excel.ActiveWorkbook
406
+ $workbook.Sheets('${escapedName}').Delete()
407
+ @{ success = $true; message = "Sheet '${escapedName}' deleted" } | ConvertTo-Json -Compress
408
+ `);
409
+ }
410
+ async excelRenameSheet(oldName, newName) {
411
+ const escapedOld = oldName.replace(/'/g, "''");
412
+ const escapedNew = newName.replace(/'/g, "''");
413
+ return this.executePowerShell(`
414
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
415
+ $workbook = $excel.ActiveWorkbook
416
+ $workbook.Sheets('${escapedOld}').Name = '${escapedNew}'
417
+ @{ success = $true; message = "Sheet renamed from '${escapedOld}' to '${escapedNew}'" } | ConvertTo-Json -Compress
418
+ `);
419
+ }
420
+ async excelCopySheet(sourceName, newName, position, targetSheet) {
421
+ if (newName) {
422
+ if (newName.length > 31) {
423
+ return { success: false, error: 'Sheet name cannot exceed 31 characters' };
424
+ }
425
+ if (/[:\\/?*\[\]]/.test(newName)) {
426
+ return { success: false, error: 'Sheet name cannot contain : \\ / ? * [ ]' };
427
+ }
428
+ }
429
+ const escapedSource = sourceName.replace(/'/g, "''");
430
+ const escapedNew = newName?.replace(/'/g, "''") || '';
431
+ const escapedTarget = targetSheet?.replace(/'/g, "''") || '';
432
+ let positionScript = '';
433
+ if (position === 'before' && targetSheet) {
434
+ positionScript = `$workbook.Sheets('${escapedSource}').Copy([ref]$workbook.Sheets('${escapedTarget}'))`;
435
+ }
436
+ else if (position === 'after' && targetSheet) {
437
+ positionScript = `$workbook.Sheets('${escapedSource}').Copy($null, [ref]$workbook.Sheets('${escapedTarget}'))`;
438
+ }
439
+ else if (position && !targetSheet) {
440
+ if (position === 'before') {
441
+ positionScript = `$workbook.Sheets('${escapedSource}').Copy([ref]$workbook.Sheets(1))`;
442
+ }
443
+ else {
444
+ positionScript = `$workbook.Sheets('${escapedSource}').Copy($null, [ref]$workbook.Sheets($workbook.Sheets.Count))`;
445
+ }
446
+ }
447
+ else {
448
+ positionScript = `$workbook.Sheets('${escapedSource}').Copy($null, [ref]$workbook.Sheets('${escapedSource}'))`;
449
+ }
450
+ return this.executePowerShell(`
451
+ try {
452
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
453
+ $workbook = $excel.ActiveWorkbook
454
+ if (-not $workbook.Sheets('${escapedSource}')) {
455
+ throw "Source sheet '${escapedSource}' not found"
456
+ }
457
+ ${positionScript}
458
+ $newSheet = $workbook.ActiveSheet
459
+ ${escapedNew ? `$newSheet.Name = '${escapedNew}'` : ''}
460
+ @{ success = $true; message = "Sheet copied"; new_sheet_name = $newSheet.Name } | ConvertTo-Json -Compress
461
+ } catch {
462
+ @{ success = $false; error = $_.Exception.Message } | ConvertTo-Json -Compress
463
+ }
464
+ `);
465
+ }
466
+ async excelGetSheets() {
467
+ return this.executePowerShell(`
468
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
469
+ $workbook = $excel.ActiveWorkbook
470
+ $sheets = @()
471
+ foreach ($sheet in $workbook.Sheets) {
472
+ $sheets += $sheet.Name
473
+ }
474
+ @{ success = $true; sheets = $sheets; count = $sheets.Count } | ConvertTo-Json -Compress
475
+ `);
476
+ }
477
+ async excelSortRange(range, sortColumn, ascending = true, hasHeader = true, sheet) {
478
+ const sheetScript = sheet ? `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` : '$sheet = $workbook.ActiveSheet';
479
+ const order = ascending ? 1 : 2;
480
+ const header = hasHeader ? 1 : 2;
481
+ return this.executePowerShell(`
482
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
483
+ $workbook = $excel.ActiveWorkbook
484
+ ${sheetScript}
485
+ $range = $sheet.Range('${range}')
486
+ $sortKey = $sheet.Range('${sortColumn}1')
487
+
488
+ # Use Sort object for better compatibility
489
+ $sheet.Sort.SortFields.Clear()
490
+ $sheet.Sort.SortFields.Add($sortKey, 0, ${order})
491
+ $sheet.Sort.SetRange($range)
492
+ $sheet.Sort.Header = ${header}
493
+ $sheet.Sort.Apply()
494
+
495
+ @{ success = $true; message = "Range sorted by column ${sortColumn}" } | ConvertTo-Json -Compress
496
+ `);
497
+ }
498
+ async excelInsertRow(row, count = 1, sheet) {
499
+ const sheetScript = sheet ? `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` : '$sheet = $workbook.ActiveSheet';
500
+ return this.executePowerShell(`
501
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
502
+ $workbook = $excel.ActiveWorkbook
503
+ ${sheetScript}
504
+ for ($i = 0; $i -lt ${count}; $i++) {
505
+ $sheet.Rows(${row}).Insert()
506
+ }
507
+ @{ success = $true; message = "${count} row(s) inserted at row ${row}" } | ConvertTo-Json -Compress
508
+ `);
509
+ }
510
+ async excelDeleteRow(row, count = 1, sheet) {
511
+ const sheetScript = sheet ? `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` : '$sheet = $workbook.ActiveSheet';
512
+ return this.executePowerShell(`
513
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
514
+ $workbook = $excel.ActiveWorkbook
515
+ ${sheetScript}
516
+ $sheet.Rows("${row}:${row + count - 1}").Delete()
517
+ @{ success = $true; message = "${count} row(s) deleted starting at row ${row}" } | ConvertTo-Json -Compress
518
+ `);
519
+ }
520
+ async excelInsertColumn(column, count = 1, sheet) {
521
+ const sheetScript = sheet ? `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` : '$sheet = $workbook.ActiveSheet';
522
+ return this.executePowerShell(`
523
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
524
+ $workbook = $excel.ActiveWorkbook
525
+ ${sheetScript}
526
+ for ($i = 0; $i -lt ${count}; $i++) {
527
+ $sheet.Columns('${column}').Insert()
528
+ }
529
+ @{ success = $true; message = "${count} column(s) inserted at column ${column}" } | ConvertTo-Json -Compress
530
+ `);
531
+ }
532
+ async excelDeleteColumn(column, count = 1, sheet) {
533
+ const sheetScript = sheet ? `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` : '$sheet = $workbook.ActiveSheet';
534
+ const startColNum = columnLetterToNumber(column.toUpperCase());
535
+ const endCol = columnNumberToLetter(startColNum + count - 1);
536
+ return this.executePowerShell(`
537
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
538
+ $workbook = $excel.ActiveWorkbook
539
+ ${sheetScript}
540
+ $sheet.Columns("${column}:${endCol}").Delete()
541
+ @{ success = $true; message = "${count} column(s) deleted starting at column ${column}" } | ConvertTo-Json -Compress
542
+ `);
543
+ }
544
+ async excelFreezePanes(row, column, sheet) {
545
+ const sheetScript = sheet ? `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` : '$sheet = $workbook.ActiveSheet';
546
+ const cellRef = `${column || 'A'}${row || 1}`;
547
+ return this.executePowerShell(`
548
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
549
+ $workbook = $excel.ActiveWorkbook
550
+ ${sheetScript}
551
+ $sheet.Activate()
552
+ if ($excel.ActiveWindow.FreezePanes) { $excel.ActiveWindow.FreezePanes = $false }
553
+ $sheet.Range('${cellRef}').Select()
554
+ $excel.ActiveWindow.FreezePanes = $true
555
+ @{ success = $true; message = "Panes frozen at ${cellRef}" } | ConvertTo-Json -Compress
556
+ `);
557
+ }
558
+ async excelAutoFilter(range, sheet) {
559
+ const sheetScript = sheet ? `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` : '$sheet = $workbook.ActiveSheet';
560
+ return this.executePowerShell(`
561
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
562
+ $workbook = $excel.ActiveWorkbook
563
+ ${sheetScript}
564
+ $sheet.Range('${range}').AutoFilter()
565
+ @{ success = $true; message = "AutoFilter applied to ${range}" } | ConvertTo-Json -Compress
566
+ `);
567
+ }
568
+ async excelScreenshot() {
569
+ const result = await this.executePowerShell(`
570
+ Add-Type -AssemblyName System.Windows.Forms
571
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
572
+ $sheet = $excel.ActiveWorkbook.ActiveSheet
573
+
574
+ # Get used range and copy as picture
575
+ $usedRange = $sheet.UsedRange
576
+ $usedRange.CopyPicture(1, 2) # xlScreen=1, xlBitmap=2
577
+
578
+ # Get image from clipboard
579
+ Start-Sleep -Milliseconds 500
580
+ $img = [System.Windows.Forms.Clipboard]::GetImage()
581
+ if ($img -eq $null) {
582
+ @{ success = $false; error = "Failed to capture screenshot" } | ConvertTo-Json -Compress
583
+ return
584
+ }
585
+
586
+ # Convert to base64
587
+ $ms = New-Object System.IO.MemoryStream
588
+ $img.Save($ms, [System.Drawing.Imaging.ImageFormat]::Png)
589
+ $bytes = $ms.ToArray()
590
+ $base64 = [Convert]::ToBase64String($bytes)
591
+ $ms.Dispose()
592
+ $img.Dispose()
593
+
594
+ @{
595
+ success = $true
596
+ image = $base64
597
+ format = "png"
598
+ encoding = "base64"
599
+ } | ConvertTo-Json -Compress
600
+ `);
601
+ return result;
602
+ }
603
+ async excelAddChart(dataRange, chartType, options) {
604
+ const chartTypeMap = {
605
+ column: 51,
606
+ bar: 57,
607
+ line: 4,
608
+ pie: 5,
609
+ area: 1,
610
+ scatter: -4169,
611
+ doughnut: -4120,
612
+ };
613
+ const xlChartType = chartTypeMap[chartType] ?? 51;
614
+ const escapedTitle = options?.title?.replace(/'/g, "''") || '';
615
+ const hasKorean = options?.title ? /[가-힣ㄱ-ㅎㅏ-ㅣ]/.test(options.title) : false;
616
+ const sheetScript = options?.sheet ?
617
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${options.sheet.replace(/'/g, "''")}')` :
618
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
619
+ const left = options?.left ?? 100;
620
+ const top = options?.top ?? 100;
621
+ const width = options?.width ?? 400;
622
+ const height = options?.height ?? 300;
623
+ const titleScript = escapedTitle ? `
624
+ $chart.HasTitle = $true
625
+ $chart.ChartTitle.Text = '${escapedTitle}'
626
+ ${hasKorean ? "$chart.ChartTitle.Font.Name = 'Malgun Gothic'" : ''}` : '';
627
+ const koreanFontScript = hasKorean ? `
628
+ # Apply Malgun Gothic to legend
629
+ if ($chart.HasLegend) {
630
+ $chart.Legend.Font.Name = 'Malgun Gothic'
631
+ }
632
+ # Apply to axis labels (Category and Value axes)
633
+ try {
634
+ $chart.Axes(1).TickLabels.Font.Name = 'Malgun Gothic' # xlCategory
635
+ $chart.Axes(2).TickLabels.Font.Name = 'Malgun Gothic' # xlValue
636
+ } catch { }` : '';
637
+ const categoryScript = options?.categoryRange ? `
638
+ try {
639
+ $catRange = $sheet.Range('${options.categoryRange}')
640
+ for ($i = 1; $i -le $chart.SeriesCollection().Count; $i++) {
641
+ $chart.SeriesCollection($i).XValues = $catRange
642
+ }
643
+ } catch { }` : '';
644
+ return this.executePowerShell(`
645
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
646
+ ${sheetScript}
647
+ $range = $sheet.Range('${dataRange}')
648
+ $chartObj = $sheet.ChartObjects().Add(${left}, ${top}, ${width}, ${height})
649
+ $chart = $chartObj.Chart
650
+ $chart.SetSourceData($range)
651
+ $chart.ChartType = ${xlChartType}
652
+ ${categoryScript}
653
+ ${titleScript}
654
+ ${koreanFontScript}
655
+ @{ success = $true; message = "Chart added"; chart_name = $chartObj.Name } | ConvertTo-Json -Compress
656
+ `);
657
+ }
658
+ async excelSetChartTitle(chartIndex, title, sheet) {
659
+ const escapedTitle = title.replace(/'/g, "''");
660
+ const hasKorean = /[가-힣ㄱ-ㅎㅏ-ㅣ]/.test(title);
661
+ const sheetScript = sheet ?
662
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${sheet.replace(/'/g, "''")}')` :
663
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
664
+ return this.executePowerShell(`
665
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
666
+ ${sheetScript}
667
+ $chartObj = $sheet.ChartObjects(${chartIndex})
668
+ $chart = $chartObj.Chart
669
+ $chart.HasTitle = $true
670
+ $chart.ChartTitle.Text = '${escapedTitle}'
671
+ ${hasKorean ? "$chart.ChartTitle.Font.Name = 'Malgun Gothic'" : ''}
672
+ @{ success = $true; message = "Chart title set" } | ConvertTo-Json -Compress
673
+ `);
674
+ }
675
+ async excelDeleteChart(chartIndex, sheet) {
676
+ const sheetScript = sheet ?
677
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${sheet.replace(/'/g, "''")}')` :
678
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
679
+ return this.executePowerShell(`
680
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
681
+ ${sheetScript}
682
+ $sheet.ChartObjects(${chartIndex}).Delete()
683
+ @{ success = $true; message = "Chart deleted" } | ConvertTo-Json -Compress
684
+ `);
685
+ }
686
+ async excelAddConditionalFormat(range, formatType, options) {
687
+ const sheetScript = options?.sheet ?
688
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${options.sheet.replace(/'/g, "''")}')` :
689
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
690
+ const typeMap = {
691
+ cellValue: 1,
692
+ colorScale: 3,
693
+ dataBar: 4,
694
+ iconSet: 6,
695
+ duplicates: 8,
696
+ top10: 5,
697
+ };
698
+ const conditionType = typeMap[formatType] ?? 1;
699
+ const operatorMap = {
700
+ greater: 5,
701
+ less: 6,
702
+ equal: 3,
703
+ between: 1,
704
+ notBetween: 2,
705
+ };
706
+ const xlOperator = options?.operator ? operatorMap[options.operator] : 5;
707
+ let formatScript = '';
708
+ if (formatType === 'cellValue') {
709
+ const formula1 = typeof options?.value1 === 'string' ? `"${options.value1}"` : options?.value1 ?? 0;
710
+ const formula2 = options?.value2 !== undefined ?
711
+ (typeof options.value2 === 'string' ? `"${options.value2}"` : options.value2) : '';
712
+ formatScript = `
713
+ $fc = $range.FormatConditions.Add(${conditionType}, ${xlOperator}, ${formula1}${formula2 ? `, ${formula2}` : ''})`;
714
+ if (options?.fillColor) {
715
+ const rgb = this.hexToRgb(options.fillColor);
716
+ if (rgb) {
717
+ formatScript += `\n$fc.Interior.Color = ${rgb.r + rgb.g * 256 + rgb.b * 65536}`;
718
+ }
719
+ }
720
+ if (options?.fontColor) {
721
+ const rgb = this.hexToRgb(options.fontColor);
722
+ if (rgb) {
723
+ formatScript += `\n$fc.Font.Color = ${rgb.r + rgb.g * 256 + rgb.b * 65536}`;
724
+ }
725
+ }
726
+ }
727
+ else if (formatType === 'colorScale') {
728
+ formatScript = '$range.FormatConditions.AddColorScale(3)';
729
+ }
730
+ else if (formatType === 'dataBar') {
731
+ formatScript = '$range.FormatConditions.AddDataBar()';
732
+ }
733
+ else if (formatType === 'iconSet') {
734
+ formatScript = '$range.FormatConditions.AddIconSetCondition()';
735
+ }
736
+ else if (formatType === 'duplicates') {
737
+ formatScript = `$fc = $range.FormatConditions.AddUniqueValues()
738
+ $fc.DupeUnique = 1`;
739
+ if (options?.fillColor) {
740
+ const rgb = this.hexToRgb(options.fillColor);
741
+ if (rgb) {
742
+ formatScript += `\n$fc.Interior.Color = ${rgb.r + rgb.g * 256 + rgb.b * 65536}`;
743
+ }
744
+ }
745
+ }
746
+ else if (formatType === 'top10') {
747
+ formatScript = `$fc = $range.FormatConditions.AddTop10()
748
+ $fc.TopBottom = 1
749
+ $fc.Rank = 10`;
750
+ if (options?.fillColor) {
751
+ const rgb = this.hexToRgb(options.fillColor);
752
+ if (rgb) {
753
+ formatScript += `\n$fc.Interior.Color = ${rgb.r + rgb.g * 256 + rgb.b * 65536}`;
754
+ }
755
+ }
756
+ }
757
+ return this.executePowerShell(`
758
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
759
+ ${sheetScript}
760
+ $range = $sheet.Range('${range}')
761
+ ${formatScript}
762
+ @{ success = $true; message = "Conditional format added to ${range}" } | ConvertTo-Json -Compress
763
+ `);
764
+ }
765
+ async excelClearConditionalFormat(range, sheet) {
766
+ const sheetScript = sheet ?
767
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${sheet.replace(/'/g, "''")}')` :
768
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
769
+ return this.executePowerShell(`
770
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
771
+ ${sheetScript}
772
+ $sheet.Range('${range}').FormatConditions.Delete()
773
+ @{ success = $true; message = "Conditional formatting cleared from ${range}" } | ConvertTo-Json -Compress
774
+ `);
775
+ }
776
+ async excelSetDataValidation(range, validationType, options) {
777
+ const sheetScript = options?.sheet ?
778
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${options.sheet.replace(/'/g, "''")}')` :
779
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
780
+ const typeMap = {
781
+ list: 3,
782
+ whole: 1,
783
+ decimal: 2,
784
+ date: 4,
785
+ textLength: 6,
786
+ custom: 7,
787
+ };
788
+ const dvType = typeMap[validationType] ?? 3;
789
+ const operatorMap = {
790
+ between: 1,
791
+ notBetween: 2,
792
+ equal: 3,
793
+ notEqual: 4,
794
+ greater: 5,
795
+ less: 6,
796
+ greaterEqual: 7,
797
+ lessEqual: 8,
798
+ };
799
+ const xlOperator = options.operator ? operatorMap[options.operator] : 1;
800
+ const formula1 = options.formula1?.replace(/'/g, "''") || '';
801
+ const formula2 = options.formula2?.replace(/'/g, "''") || '';
802
+ const additionalSettings = [];
803
+ if (options.showInputMessage !== false && (options.inputTitle || options.inputMessage)) {
804
+ additionalSettings.push('$validation.ShowInput = $true');
805
+ if (options.inputTitle)
806
+ additionalSettings.push(`$validation.InputTitle = '${options.inputTitle.replace(/'/g, "''")}'`);
807
+ if (options.inputMessage)
808
+ additionalSettings.push(`$validation.InputMessage = '${options.inputMessage.replace(/'/g, "''")}'`);
809
+ }
810
+ if (options.showErrorMessage !== false && (options.errorTitle || options.errorMessage)) {
811
+ additionalSettings.push('$validation.ShowError = $true');
812
+ if (options.errorTitle)
813
+ additionalSettings.push(`$validation.ErrorTitle = '${options.errorTitle.replace(/'/g, "''")}'`);
814
+ if (options.errorMessage)
815
+ additionalSettings.push(`$validation.ErrorMessage = '${options.errorMessage.replace(/'/g, "''")}'`);
816
+ }
817
+ const validationParams = validationType === 'list'
818
+ ? `${dvType}, 1, 1, '${formula1}'`
819
+ : `${dvType}, 1, ${xlOperator}, '${formula1}'${formula2 ? `, '${formula2}'` : ''}`;
820
+ return this.executePowerShell(`
821
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
822
+ ${sheetScript}
823
+ $range = $sheet.Range('${range}')
824
+ $range.Validation.Delete()
825
+ $range.Validation.Add(${validationParams})
826
+ $validation = $range.Validation
827
+ ${additionalSettings.join('\n')}
828
+ @{ success = $true; message = "Data validation set on ${range}" } | ConvertTo-Json -Compress
829
+ `);
830
+ }
831
+ async excelClearDataValidation(range, sheet) {
832
+ const sheetScript = sheet ?
833
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${sheet.replace(/'/g, "''")}')` :
834
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
835
+ return this.executePowerShell(`
836
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
837
+ ${sheetScript}
838
+ $sheet.Range('${range}').Validation.Delete()
839
+ @{ success = $true; message = "Data validation cleared from ${range}" } | ConvertTo-Json -Compress
840
+ `);
841
+ }
842
+ async excelCreateNamedRange(name, range, sheet) {
843
+ const escapedName = name.replace(/'/g, "''");
844
+ const sheetScript = sheet ?
845
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${sheet.replace(/'/g, "''")}')` :
846
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
847
+ return this.executePowerShell(`
848
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
849
+ $workbook = $excel.ActiveWorkbook
850
+ ${sheetScript}
851
+ $range = $sheet.Range('${range}')
852
+ $workbook.Names.Add('${escapedName}', $range)
853
+ @{ success = $true; message = "Named range '${escapedName}' created" } | ConvertTo-Json -Compress
854
+ `);
855
+ }
856
+ async excelGetNamedRanges() {
857
+ return this.executePowerShell(`
858
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
859
+ $workbook = $excel.ActiveWorkbook
860
+ $names = @()
861
+ foreach ($n in $workbook.Names) {
862
+ $names += @{
863
+ name = $n.Name
864
+ refersTo = $n.RefersTo
865
+ value = $n.Value
866
+ }
867
+ }
868
+ @{ success = $true; named_ranges = $names } | ConvertTo-Json -Compress -Depth 5
869
+ `);
870
+ }
871
+ async excelDeleteNamedRange(name) {
872
+ const escapedName = name.replace(/'/g, "''");
873
+ return this.executePowerShell(`
874
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
875
+ $workbook = $excel.ActiveWorkbook
876
+ $workbook.Names('${escapedName}').Delete()
877
+ @{ success = $true; message = "Named range '${escapedName}' deleted" } | ConvertTo-Json -Compress
878
+ `);
879
+ }
880
+ async excelCopyRange(range, sheet) {
881
+ const sheetScript = sheet ?
882
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${sheet.replace(/'/g, "''")}')` :
883
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
884
+ return this.executePowerShell(`
885
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
886
+ ${sheetScript}
887
+ $sheet.Range('${range}').Copy()
888
+ @{ success = $true; message = "Range ${range} copied to clipboard" } | ConvertTo-Json -Compress
889
+ `);
890
+ }
891
+ async excelPasteRange(destination, sheet) {
892
+ const sheetScript = sheet ?
893
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${sheet.replace(/'/g, "''")}')` :
894
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
895
+ return this.executePowerShell(`
896
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
897
+ ${sheetScript}
898
+ $sheet.Range('${destination}').Select()
899
+ $sheet.Paste()
900
+ @{ success = $true; message = "Pasted to ${destination}" } | ConvertTo-Json -Compress
901
+ `);
902
+ }
903
+ async excelClearRange(range, clearType = 'all', sheet) {
904
+ const sheetScript = sheet ?
905
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${sheet.replace(/'/g, "''")}')` :
906
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
907
+ const clearMethod = {
908
+ all: 'Clear()',
909
+ contents: 'ClearContents()',
910
+ formats: 'ClearFormats()',
911
+ comments: 'ClearComments()',
912
+ }[clearType];
913
+ return this.executePowerShell(`
914
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
915
+ ${sheetScript}
916
+ $sheet.Range('${range}').${clearMethod}
917
+ @{ success = $true; message = "Range ${range} cleared (${clearType})" } | ConvertTo-Json -Compress
918
+ `);
919
+ }
920
+ async excelHideColumn(column, sheet) {
921
+ const sheetScript = sheet ?
922
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${sheet.replace(/'/g, "''")}')` :
923
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
924
+ return this.executePowerShell(`
925
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
926
+ ${sheetScript}
927
+ $sheet.Columns('${column}').Hidden = $true
928
+ @{ success = $true; message = "Column ${column} hidden" } | ConvertTo-Json -Compress
929
+ `);
930
+ }
931
+ async excelShowColumn(column, sheet) {
932
+ const sheetScript = sheet ?
933
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${sheet.replace(/'/g, "''")}')` :
934
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
935
+ return this.executePowerShell(`
936
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
937
+ ${sheetScript}
938
+ $sheet.Columns('${column}').Hidden = $false
939
+ @{ success = $true; message = "Column ${column} shown" } | ConvertTo-Json -Compress
940
+ `);
941
+ }
942
+ async excelHideRow(row, sheet) {
943
+ const sheetScript = sheet ?
944
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${sheet.replace(/'/g, "''")}')` :
945
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
946
+ return this.executePowerShell(`
947
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
948
+ ${sheetScript}
949
+ $sheet.Rows(${row}).Hidden = $true
950
+ @{ success = $true; message = "Row ${row} hidden" } | ConvertTo-Json -Compress
951
+ `);
952
+ }
953
+ async excelShowRow(row, sheet) {
954
+ const sheetScript = sheet ?
955
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${sheet.replace(/'/g, "''")}')` :
956
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
957
+ return this.executePowerShell(`
958
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
959
+ ${sheetScript}
960
+ $sheet.Rows(${row}).Hidden = $false
961
+ @{ success = $true; message = "Row ${row} shown" } | ConvertTo-Json -Compress
962
+ `);
963
+ }
964
+ async excelAddImage(imagePath, cell, options) {
965
+ const windowsPath = this.toWindowsPath(imagePath).replace(/'/g, "''");
966
+ const sheetScript = options?.sheet ?
967
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${options.sheet.replace(/'/g, "''")}')` :
968
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
969
+ const sizeScript = [];
970
+ if (options?.width)
971
+ sizeScript.push(`$pic.Width = ${options.width}`);
972
+ if (options?.height)
973
+ sizeScript.push(`$pic.Height = ${options.height}`);
974
+ return this.executePowerShell(`
975
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
976
+ ${sheetScript}
977
+ $cell = $sheet.Range('${cell}')
978
+ $pic = $sheet.Shapes.AddPicture('${windowsPath}', 0, -1, $cell.Left, $cell.Top, -1, -1)
979
+ ${sizeScript.join('\n')}
980
+ @{ success = $true; message = "Image added at ${cell}" } | ConvertTo-Json -Compress
981
+ `);
982
+ }
983
+ async excelAddHyperlink(cell, url, displayText, sheet) {
984
+ const escapedUrl = url.replace(/'/g, "''");
985
+ const escapedText = displayText?.replace(/'/g, "''") || url;
986
+ const sheetScript = sheet ?
987
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${sheet.replace(/'/g, "''")}')` :
988
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
989
+ return this.executePowerShell(`
990
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
991
+ ${sheetScript}
992
+ $range = $sheet.Range('${cell}')
993
+ $sheet.Hyperlinks.Add($range, '${escapedUrl}', '', '', '${escapedText}')
994
+ @{ success = $true; message = "Hyperlink added to ${cell}" } | ConvertTo-Json -Compress
995
+ `);
996
+ }
997
+ async excelGetHyperlinks(sheet) {
998
+ const sheetScript = sheet ?
999
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` :
1000
+ '$sheet = $workbook.ActiveSheet';
1001
+ return this.executePowerShell(`
1002
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1003
+ $workbook = $excel.ActiveWorkbook
1004
+ ${sheetScript}
1005
+ $links = @()
1006
+ foreach ($hl in $sheet.Hyperlinks) {
1007
+ $links += @{
1008
+ cell = $hl.Range.Address($false, $false)
1009
+ address = $hl.Address
1010
+ subAddress = $hl.SubAddress
1011
+ textToDisplay = $hl.TextToDisplay
1012
+ screenTip = $hl.ScreenTip
1013
+ }
1014
+ }
1015
+ @{ success = $true; hyperlinks = $links; count = $links.Count } | ConvertTo-Json -Compress -Depth 5
1016
+ `);
1017
+ }
1018
+ async excelDeleteHyperlink(cell, sheet) {
1019
+ const sheetScript = sheet ?
1020
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` :
1021
+ '$sheet = $workbook.ActiveSheet';
1022
+ return this.executePowerShell(`
1023
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1024
+ $workbook = $excel.ActiveWorkbook
1025
+ ${sheetScript}
1026
+ $range = $sheet.Range('${cell}')
1027
+ $found = $false
1028
+ foreach ($hl in $sheet.Hyperlinks) {
1029
+ if ($hl.Range.Address -eq $range.Address) {
1030
+ $hl.Delete()
1031
+ $found = $true
1032
+ break
1033
+ }
1034
+ }
1035
+ if ($found) {
1036
+ @{ success = $true; message = "Hyperlink deleted from ${cell}" } | ConvertTo-Json -Compress
1037
+ } else {
1038
+ @{ success = $false; error = "No hyperlink found in ${cell}" } | ConvertTo-Json -Compress
1039
+ }
1040
+ `);
1041
+ }
1042
+ async excelEditHyperlink(cell, newUrl, newDisplayText, sheet) {
1043
+ const sheetScript = sheet ?
1044
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` :
1045
+ '$sheet = $workbook.ActiveSheet';
1046
+ const urlUpdate = newUrl ? `$hl.Address = '${newUrl.replace(/'/g, "''")}'` : '';
1047
+ const textUpdate = newDisplayText ? `$hl.TextToDisplay = '${newDisplayText.replace(/'/g, "''")}'` : '';
1048
+ return this.executePowerShell(`
1049
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1050
+ $workbook = $excel.ActiveWorkbook
1051
+ ${sheetScript}
1052
+ $range = $sheet.Range('${cell}')
1053
+ $found = $false
1054
+ foreach ($hl in $sheet.Hyperlinks) {
1055
+ if ($hl.Range.Address -eq $range.Address) {
1056
+ ${urlUpdate}
1057
+ ${textUpdate}
1058
+ $found = $true
1059
+ break
1060
+ }
1061
+ }
1062
+ if ($found) {
1063
+ @{ success = $true; message = "Hyperlink updated in ${cell}" } | ConvertTo-Json -Compress
1064
+ } else {
1065
+ @{ success = $false; error = "No hyperlink found in ${cell}" } | ConvertTo-Json -Compress
1066
+ }
1067
+ `);
1068
+ }
1069
+ async excelExportPDF(outputPath, sheet) {
1070
+ const windowsPath = this.toWindowsPath(outputPath).replace(/'/g, "''");
1071
+ const sheetScript = sheet ?
1072
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${sheet.replace(/'/g, "''")}')
1073
+ $sheet.ExportAsFixedFormat(0, '${windowsPath}')` :
1074
+ `$excel.ActiveWorkbook.ExportAsFixedFormat(0, '${windowsPath}')`;
1075
+ return this.executePowerShell(`
1076
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1077
+ ${sheetScript}
1078
+ @{ success = $true; message = "Exported to PDF"; path = '${windowsPath}' } | ConvertTo-Json -Compress
1079
+ `);
1080
+ }
1081
+ async excelPrint(copies = 1, sheet) {
1082
+ const sheetScript = sheet ?
1083
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${sheet.replace(/'/g, "''")}')
1084
+ $sheet.PrintOut(1, 9999, ${copies})` :
1085
+ `$excel.ActiveWorkbook.PrintOut(1, 9999, ${copies})`;
1086
+ return this.executePowerShell(`
1087
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1088
+ ${sheetScript}
1089
+ @{ success = $true; message = "Print job sent (${copies} copies)" } | ConvertTo-Json -Compress
1090
+ `);
1091
+ }
1092
+ async excelAddComment(cell, text, _author, sheet) {
1093
+ const escapedText = text.replace(/'/g, "''");
1094
+ const sheetScript = sheet ?
1095
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${sheet.replace(/'/g, "''")}')` :
1096
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
1097
+ return this.executePowerShell(`
1098
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1099
+ ${sheetScript}
1100
+ $cell = $sheet.Range('${cell}')
1101
+ if ($cell.Comment -ne $null) { $cell.Comment.Delete() }
1102
+ $comment = $cell.AddComment('${escapedText}')
1103
+ $comment.Visible = $false
1104
+ @{ success = $true; message = "Comment added to ${cell}" } | ConvertTo-Json -Compress
1105
+ `);
1106
+ }
1107
+ async excelGetComment(cell, sheet) {
1108
+ const sheetScript = sheet ?
1109
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${sheet.replace(/'/g, "''")}')` :
1110
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
1111
+ return this.executePowerShell(`
1112
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1113
+ ${sheetScript}
1114
+ $cell = $sheet.Range('${cell}')
1115
+ if ($cell.Comment -ne $null) {
1116
+ @{ success = $true; has_comment = $true; text = $cell.Comment.Text() } | ConvertTo-Json -Compress
1117
+ } else {
1118
+ @{ success = $true; has_comment = $false } | ConvertTo-Json -Compress
1119
+ }
1120
+ `);
1121
+ }
1122
+ async excelDeleteComment(cell, sheet) {
1123
+ const sheetScript = sheet ?
1124
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${sheet.replace(/'/g, "''")}')` :
1125
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
1126
+ return this.executePowerShell(`
1127
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1128
+ ${sheetScript}
1129
+ $cell = $sheet.Range('${cell}')
1130
+ if ($cell.Comment -ne $null) {
1131
+ $cell.Comment.Delete()
1132
+ @{ success = $true; message = "Comment deleted from ${cell}" } | ConvertTo-Json -Compress
1133
+ } else {
1134
+ @{ success = $false; error = "No comment found at ${cell}" } | ConvertTo-Json -Compress
1135
+ }
1136
+ `);
1137
+ }
1138
+ async excelProtectSheet(password, sheet) {
1139
+ const escapedPassword = password?.replace(/'/g, "''") || '';
1140
+ const sheetScript = sheet ?
1141
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${sheet.replace(/'/g, "''")}')` :
1142
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
1143
+ return this.executePowerShell(`
1144
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1145
+ ${sheetScript}
1146
+ $sheet.Protect('${escapedPassword}')
1147
+ @{ success = $true; message = "Sheet protected" } | ConvertTo-Json -Compress
1148
+ `);
1149
+ }
1150
+ async excelUnprotectSheet(password, sheet) {
1151
+ const escapedPassword = password?.replace(/'/g, "''") || '';
1152
+ const sheetScript = sheet ?
1153
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${sheet.replace(/'/g, "''")}')` :
1154
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
1155
+ return this.executePowerShell(`
1156
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1157
+ ${sheetScript}
1158
+ $sheet.Unprotect('${escapedPassword}')
1159
+ @{ success = $true; message = "Sheet unprotected" } | ConvertTo-Json -Compress
1160
+ `);
1161
+ }
1162
+ async excelUnmergeCells(range, sheet) {
1163
+ const sheetScript = sheet ?
1164
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${sheet.replace(/'/g, "''")}')` :
1165
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
1166
+ return this.executePowerShell(`
1167
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1168
+ ${sheetScript}
1169
+ $sheet.Range('${range}').UnMerge()
1170
+ @{ success = $true; message = "Cells unmerged: ${range}" } | ConvertTo-Json -Compress
1171
+ `);
1172
+ }
1173
+ async excelSelectSheet(name) {
1174
+ const escapedName = name.replace(/'/g, "''");
1175
+ return this.executePowerShell(`
1176
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1177
+ $excel.ActiveWorkbook.Worksheets('${escapedName}').Activate()
1178
+ @{ success = $true; message = "Sheet '${escapedName}' activated" } | ConvertTo-Json -Compress
1179
+ `);
1180
+ }
1181
+ async excelFindReplace(find, replace, options) {
1182
+ const escapedFind = find.replace(/'/g, "''");
1183
+ const escapedReplace = replace.replace(/'/g, "''");
1184
+ const sheetScript = options?.sheet ?
1185
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${options.sheet.replace(/'/g, "''")}')` :
1186
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
1187
+ const rangeScript = options?.range ?
1188
+ `$range = $sheet.Range('${options.range}')` :
1189
+ '$range = $sheet.UsedRange';
1190
+ const matchCase = options?.matchCase ? '$true' : '$false';
1191
+ const lookAt = options?.matchEntireCell ? '1' : '2';
1192
+ return this.executePowerShell(`
1193
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1194
+ ${sheetScript}
1195
+ ${rangeScript}
1196
+ $replaced = $range.Replace('${escapedFind}', '${escapedReplace}', ${lookAt}, 1, ${matchCase})
1197
+ @{ success = $true; message = "Find and replace completed" } | ConvertTo-Json -Compress
1198
+ `);
1199
+ }
1200
+ async excelGroupRows(startRow, endRow, sheet) {
1201
+ const sheetScript = sheet ?
1202
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${sheet.replace(/'/g, "''")}')` :
1203
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
1204
+ return this.executePowerShell(`
1205
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1206
+ ${sheetScript}
1207
+ $sheet.Rows("${startRow}:${endRow}").Group()
1208
+ @{ success = $true; message = "Rows ${startRow}-${endRow} grouped" } | ConvertTo-Json -Compress
1209
+ `);
1210
+ }
1211
+ async excelUngroupRows(startRow, endRow, sheet) {
1212
+ const sheetScript = sheet ?
1213
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${sheet.replace(/'/g, "''")}')` :
1214
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
1215
+ return this.executePowerShell(`
1216
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1217
+ ${sheetScript}
1218
+ $sheet.Rows("${startRow}:${endRow}").Ungroup()
1219
+ @{ success = $true; message = "Rows ${startRow}-${endRow} ungrouped" } | ConvertTo-Json -Compress
1220
+ `);
1221
+ }
1222
+ async excelCreatePivotTable(sourceRange, destCell, tableName, sheet) {
1223
+ const escapedName = tableName?.replace(/'/g, "''") || `PivotTable${Date.now()}`;
1224
+ const sheetScript = sheet ?
1225
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${sheet.replace(/'/g, "''")}')` :
1226
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
1227
+ return this.executePowerShell(`
1228
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1229
+ $workbook = $excel.ActiveWorkbook
1230
+ ${sheetScript}
1231
+ $sourceRange = $sheet.Range('${sourceRange}')
1232
+ $destRange = $sheet.Range('${destCell}')
1233
+
1234
+ $pivotCache = $workbook.PivotCaches().Create(1, $sourceRange) # xlDatabase = 1
1235
+ $pivotTable = $pivotCache.CreatePivotTable($destRange, '${escapedName}')
1236
+
1237
+ @{ success = $true; message = "Pivot table created"; table_name = '${escapedName}' } | ConvertTo-Json -Compress
1238
+ `);
1239
+ }
1240
+ async excelAddPivotField(tableName, fieldName, orientation, aggregateFunction) {
1241
+ const escapedTableName = tableName.replace(/'/g, "''");
1242
+ const escapedFieldName = fieldName.replace(/'/g, "''");
1243
+ const orientationMap = {
1244
+ row: 1,
1245
+ column: 2,
1246
+ data: 4,
1247
+ page: 3,
1248
+ };
1249
+ const xlOrientation = orientationMap[orientation];
1250
+ const functionMap = {
1251
+ sum: -4157,
1252
+ count: -4112,
1253
+ average: -4106,
1254
+ max: -4136,
1255
+ min: -4139,
1256
+ };
1257
+ const xlFunction = aggregateFunction ? functionMap[aggregateFunction] : -4157;
1258
+ const functionScript = orientation === 'data' ? `$field.Function = ${xlFunction}` : '';
1259
+ return this.executePowerShell(`
1260
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1261
+ $workbook = $excel.ActiveWorkbook
1262
+ $pivotTable = $null
1263
+ foreach ($ws in $workbook.Worksheets) {
1264
+ foreach ($pt in $ws.PivotTables()) {
1265
+ if ($pt.Name -eq '${escapedTableName}') {
1266
+ $pivotTable = $pt
1267
+ break
1268
+ }
1269
+ }
1270
+ if ($pivotTable -ne $null) { break }
1271
+ }
1272
+
1273
+ if ($pivotTable -eq $null) {
1274
+ @{ success = $false; error = "Pivot table '${escapedTableName}' not found" } | ConvertTo-Json -Compress
1275
+ } else {
1276
+ $field = $pivotTable.PivotFields('${escapedFieldName}')
1277
+ $field.Orientation = ${xlOrientation}
1278
+ ${functionScript}
1279
+ @{ success = $true; message = "Field '${escapedFieldName}' added as ${orientation}" } | ConvertTo-Json -Compress
1280
+ }
1281
+ `);
1282
+ }
1283
+ async excelRefreshPivotTable(tableName) {
1284
+ const escapedTableName = tableName.replace(/'/g, "''");
1285
+ return this.executePowerShell(`
1286
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1287
+ $workbook = $excel.ActiveWorkbook
1288
+ $pivotTable = $null
1289
+ foreach ($ws in $workbook.Worksheets) {
1290
+ foreach ($pt in $ws.PivotTables()) {
1291
+ if ($pt.Name -eq '${escapedTableName}') {
1292
+ $pivotTable = $pt
1293
+ break
1294
+ }
1295
+ }
1296
+ if ($pivotTable -ne $null) { break }
1297
+ }
1298
+
1299
+ if ($pivotTable -eq $null) {
1300
+ @{ success = $false; error = "Pivot table '${escapedTableName}' not found" } | ConvertTo-Json -Compress
1301
+ } else {
1302
+ $pivotTable.RefreshTable()
1303
+ @{ success = $true; message = "Pivot table '${escapedTableName}' refreshed" } | ConvertTo-Json -Compress
1304
+ }
1305
+ `);
1306
+ }
1307
+ async excelInsertVlookup(cell, lookupValue, tableRange, colIndex, exactMatch = true, sheet) {
1308
+ const sheetScript = sheet ?
1309
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` :
1310
+ '$sheet = $workbook.ActiveSheet';
1311
+ const matchType = exactMatch ? 'FALSE' : 'TRUE';
1312
+ const formula = `=VLOOKUP(${lookupValue},${tableRange},${colIndex},${matchType})`;
1313
+ return this.executePowerShell(`
1314
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1315
+ $workbook = $excel.ActiveWorkbook
1316
+ ${sheetScript}
1317
+ $sheet.Range('${cell}').Formula = '${formula.replace(/'/g, "''")}'
1318
+ @{ success = $true; message = "VLOOKUP formula inserted in ${cell}" } | ConvertTo-Json -Compress
1319
+ `);
1320
+ }
1321
+ async excelInsertSumif(cell, range, criteria, sumRange, sheet) {
1322
+ const sheetScript = sheet ?
1323
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` :
1324
+ '$sheet = $workbook.ActiveSheet';
1325
+ const formattedCriteria = formatFormulaCriteria(criteria);
1326
+ const formula = sumRange
1327
+ ? `=SUMIF(${range},${formattedCriteria},${sumRange})`
1328
+ : `=SUMIF(${range},${formattedCriteria})`;
1329
+ return this.executePowerShell(`
1330
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1331
+ $workbook = $excel.ActiveWorkbook
1332
+ ${sheetScript}
1333
+ $sheet.Range('${cell}').Formula = '${formula.replace(/'/g, "''")}'
1334
+ @{ success = $true; message = "SUMIF formula inserted in ${cell}" } | ConvertTo-Json -Compress
1335
+ `);
1336
+ }
1337
+ async excelInsertCountif(cell, range, criteria, sheet) {
1338
+ const sheetScript = sheet ?
1339
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` :
1340
+ '$sheet = $workbook.ActiveSheet';
1341
+ const formattedCriteria = formatFormulaCriteria(criteria);
1342
+ const formula = `=COUNTIF(${range},${formattedCriteria})`;
1343
+ return this.executePowerShell(`
1344
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1345
+ $workbook = $excel.ActiveWorkbook
1346
+ ${sheetScript}
1347
+ $sheet.Range('${cell}').Formula = '${formula.replace(/'/g, "''")}'
1348
+ @{ success = $true; message = "COUNTIF formula inserted in ${cell}" } | ConvertTo-Json -Compress
1349
+ `);
1350
+ }
1351
+ async excelInsertIndexMatch(cell, returnRange, lookupRange, lookupValue, sheet) {
1352
+ const sheetScript = sheet ?
1353
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` :
1354
+ '$sheet = $workbook.ActiveSheet';
1355
+ const formula = `=INDEX(${returnRange},MATCH(${lookupValue},${lookupRange},0))`;
1356
+ return this.executePowerShell(`
1357
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1358
+ $workbook = $excel.ActiveWorkbook
1359
+ ${sheetScript}
1360
+ $sheet.Range('${cell}').Formula = '${formula.replace(/'/g, "''")}'
1361
+ @{ success = $true; message = "INDEX-MATCH formula inserted in ${cell}" } | ConvertTo-Json -Compress
1362
+ `);
1363
+ }
1364
+ async excelInsertAverageif(cell, range, criteria, avgRange, sheet) {
1365
+ const sheetScript = sheet ?
1366
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` :
1367
+ '$sheet = $workbook.ActiveSheet';
1368
+ const formattedCriteria = formatFormulaCriteria(criteria);
1369
+ const formula = avgRange
1370
+ ? `=AVERAGEIF(${range},${formattedCriteria},${avgRange})`
1371
+ : `=AVERAGEIF(${range},${formattedCriteria})`;
1372
+ return this.executePowerShell(`
1373
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1374
+ $workbook = $excel.ActiveWorkbook
1375
+ ${sheetScript}
1376
+ $sheet.Range('${cell}').Formula = '${formula.replace(/'/g, "''")}'
1377
+ @{ success = $true; message = "AVERAGEIF formula inserted in ${cell}" } | ConvertTo-Json -Compress
1378
+ `);
1379
+ }
1380
+ async excelInsertSumifs(cell, sumRange, criteriaRanges, criteria, sheet) {
1381
+ const sheetScript = sheet ?
1382
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` :
1383
+ '$sheet = $workbook.ActiveSheet';
1384
+ const criteriaPairs = criteriaRanges.map((range, i) => {
1385
+ const formattedCriteria = formatFormulaCriteria(criteria[i] || '');
1386
+ return `${range},${formattedCriteria}`;
1387
+ }).join(',');
1388
+ const formula = `=SUMIFS(${sumRange},${criteriaPairs})`;
1389
+ return this.executePowerShell(`
1390
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1391
+ $workbook = $excel.ActiveWorkbook
1392
+ ${sheetScript}
1393
+ $sheet.Range('${cell}').Formula = '${formula.replace(/'/g, "''")}'
1394
+ @{ success = $true; message = "SUMIFS formula inserted in ${cell}" } | ConvertTo-Json -Compress
1395
+ `);
1396
+ }
1397
+ async excelInsertCountifs(cell, criteriaRanges, criteria, sheet) {
1398
+ const sheetScript = sheet ?
1399
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` :
1400
+ '$sheet = $workbook.ActiveSheet';
1401
+ const criteriaPairs = criteriaRanges.map((range, i) => {
1402
+ const formattedCriteria = formatFormulaCriteria(criteria[i] || '');
1403
+ return `${range},${formattedCriteria}`;
1404
+ }).join(',');
1405
+ const formula = `=COUNTIFS(${criteriaPairs})`;
1406
+ return this.executePowerShell(`
1407
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1408
+ $workbook = $excel.ActiveWorkbook
1409
+ ${sheetScript}
1410
+ $sheet.Range('${cell}').Formula = '${formula.replace(/'/g, "''")}'
1411
+ @{ success = $true; message = "COUNTIFS formula inserted in ${cell}" } | ConvertTo-Json -Compress
1412
+ `);
1413
+ }
1414
+ async excelInsertXlookup(cell, lookupValue, lookupRange, returnRange, notFoundValue, matchMode, sheet) {
1415
+ const sheetScript = sheet ?
1416
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` :
1417
+ '$sheet = $workbook.ActiveSheet';
1418
+ const matchModeMap = {
1419
+ exact: 0,
1420
+ exactOrNext: 1,
1421
+ exactOrPrev: -1,
1422
+ wildcard: 2,
1423
+ };
1424
+ const matchModeValue = matchMode ? matchModeMap[matchMode] : 0;
1425
+ let formula = `=XLOOKUP(${lookupValue},${lookupRange},${returnRange}`;
1426
+ if (notFoundValue !== undefined || matchMode) {
1427
+ if (notFoundValue !== undefined) {
1428
+ formula += `,"${notFoundValue.replace(/"/g, '""')}"`;
1429
+ }
1430
+ else {
1431
+ formula += ',';
1432
+ }
1433
+ if (matchMode || notFoundValue !== undefined) {
1434
+ formula += `,${matchModeValue}`;
1435
+ }
1436
+ }
1437
+ formula += ')';
1438
+ return this.executePowerShell(`
1439
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1440
+ $workbook = $excel.ActiveWorkbook
1441
+ ${sheetScript}
1442
+ $sheet.Range('${cell}').Formula = '${formula.replace(/'/g, "''")}'
1443
+ @{ success = $true; message = "XLOOKUP formula inserted in ${cell}" } | ConvertTo-Json -Compress
1444
+ `);
1445
+ }
1446
+ async excelUnmergeAndFill(range, sheet) {
1447
+ const sheetScript = sheet ?
1448
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${sheet.replace(/'/g, "''")}')` :
1449
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
1450
+ return this.executePowerShell(`
1451
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1452
+ ${sheetScript}
1453
+ $range = $sheet.Range('${range}')
1454
+ $filledCount = 0
1455
+ $processedAreas = @{}
1456
+
1457
+ # Find all merge areas in the range (check first cell of each row for efficiency)
1458
+ foreach ($cell in $range) {
1459
+ if ($cell.MergeCells) {
1460
+ $mergeArea = $cell.MergeArea
1461
+ $areaAddress = $mergeArea.Address
1462
+
1463
+ # Skip if already processed
1464
+ if (-not $processedAreas.ContainsKey($areaAddress)) {
1465
+ $processedAreas[$areaAddress] = $true
1466
+ $originalValue = $mergeArea.Cells(1, 1).Value2
1467
+ $cellCount = $mergeArea.Cells.Count
1468
+ $mergeArea.UnMerge()
1469
+
1470
+ # Fill all cells at once using Value assignment
1471
+ $mergeArea.Value2 = $originalValue
1472
+ $filledCount += $cellCount
1473
+ }
1474
+ }
1475
+ }
1476
+
1477
+ @{ success = $true; message = "Unmerged and filled ${range} ($($processedAreas.Count) merge areas)"; cells_filled = $filledCount; merge_areas = $processedAreas.Count } | ConvertTo-Json -Compress
1478
+ `);
1479
+ }
1480
+ async excelAddChartSeries(chartIndex, valuesRange, nameRange, sheet) {
1481
+ const sheetScript = sheet ?
1482
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${sheet.replace(/'/g, "''")}')` :
1483
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
1484
+ const nameScript = nameRange ? `$series.Name = $sheet.Range('${nameRange}').Value2` : '';
1485
+ return this.executePowerShell(`
1486
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1487
+ ${sheetScript}
1488
+ $chartObj = $sheet.ChartObjects(${chartIndex})
1489
+ $chart = $chartObj.Chart
1490
+ $series = $chart.SeriesCollection().NewSeries()
1491
+ $series.Values = $sheet.Range('${valuesRange}')
1492
+ ${nameScript}
1493
+ @{ success = $true; message = "Series added to chart"; series_index = $chart.SeriesCollection().Count } | ConvertTo-Json -Compress
1494
+ `);
1495
+ }
1496
+ async excelEditChartSeries(chartIndex, seriesIndex, options, sheet) {
1497
+ const sheetScript = sheet ?
1498
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${sheet.replace(/'/g, "''")}')` :
1499
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
1500
+ const commands = [];
1501
+ if (options.valuesRange) {
1502
+ commands.push(`$series.Values = $sheet.Range('${options.valuesRange}')`);
1503
+ }
1504
+ if (options.nameRange) {
1505
+ commands.push(`$series.Name = $sheet.Range('${options.nameRange}').Value2`);
1506
+ }
1507
+ if (options.name) {
1508
+ commands.push(`$series.Name = '${options.name.replace(/'/g, "''")}'`);
1509
+ }
1510
+ return this.executePowerShell(`
1511
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1512
+ ${sheetScript}
1513
+ $chartObj = $sheet.ChartObjects(${chartIndex})
1514
+ $chart = $chartObj.Chart
1515
+ $series = $chart.SeriesCollection(${seriesIndex})
1516
+ ${commands.join('\n')}
1517
+ @{ success = $true; message = "Series ${seriesIndex} updated" } | ConvertTo-Json -Compress
1518
+ `);
1519
+ }
1520
+ async excelDeleteChartSeries(chartIndex, seriesIndex, sheet) {
1521
+ const sheetScript = sheet ?
1522
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${sheet.replace(/'/g, "''")}')` :
1523
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
1524
+ return this.executePowerShell(`
1525
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1526
+ ${sheetScript}
1527
+ $chartObj = $sheet.ChartObjects(${chartIndex})
1528
+ $chart = $chartObj.Chart
1529
+ $chart.SeriesCollection(${seriesIndex}).Delete()
1530
+ @{ success = $true; message = "Series ${seriesIndex} deleted from chart" } | ConvertTo-Json -Compress
1531
+ `);
1532
+ }
1533
+ async excelSetChartLegend(chartIndex, options, sheet) {
1534
+ const sheetScript = sheet ?
1535
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${sheet.replace(/'/g, "''")}')` :
1536
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
1537
+ const positionMap = {
1538
+ bottom: -4107,
1539
+ top: -4160,
1540
+ left: -4131,
1541
+ right: -4152,
1542
+ corner: 2,
1543
+ };
1544
+ let legendScript = '';
1545
+ if (options.show === false) {
1546
+ legendScript = '$chart.HasLegend = $false';
1547
+ }
1548
+ else {
1549
+ legendScript = '$chart.HasLegend = $true';
1550
+ if (options.position) {
1551
+ legendScript += `; $chart.Legend.Position = ${positionMap[options.position]}`;
1552
+ }
1553
+ }
1554
+ return this.executePowerShell(`
1555
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1556
+ ${sheetScript}
1557
+ $chartObj = $sheet.ChartObjects(${chartIndex})
1558
+ $chart = $chartObj.Chart
1559
+ ${legendScript}
1560
+ @{ success = $true; message = "Chart legend updated" } | ConvertTo-Json -Compress
1561
+ `);
1562
+ }
1563
+ async excelSetChartDataLabels(chartIndex, options, sheet) {
1564
+ const sheetScript = sheet ?
1565
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${sheet.replace(/'/g, "''")}')` :
1566
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
1567
+ const labelScript = options.show === false
1568
+ ? 'foreach ($s in $chart.SeriesCollection()) { $s.HasDataLabels = $false }'
1569
+ : `foreach ($s in $chart.SeriesCollection()) {
1570
+ $s.HasDataLabels = $true
1571
+ $s.DataLabels.ShowValue = ${options.showValue !== false ? '$true' : '$false'}
1572
+ $s.DataLabels.ShowCategoryName = ${options.showCategory ? '$true' : '$false'}
1573
+ $s.DataLabels.ShowPercentage = ${options.showPercent ? '$true' : '$false'}
1574
+ }`;
1575
+ return this.executePowerShell(`
1576
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1577
+ ${sheetScript}
1578
+ $chartObj = $sheet.ChartObjects(${chartIndex})
1579
+ $chart = $chartObj.Chart
1580
+ ${labelScript}
1581
+ @{ success = $true; message = "Chart data labels updated" } | ConvertTo-Json -Compress
1582
+ `);
1583
+ }
1584
+ async excelSetChartAxis(chartIndex, axisType, options, sheet) {
1585
+ const sheetScript = sheet ?
1586
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${sheet.replace(/'/g, "''")}')` :
1587
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
1588
+ const axisNum = axisType === 'x' ? 1 : 2;
1589
+ let axisScript = `$axis = $chart.Axes(${axisNum})`;
1590
+ if (options.title !== undefined) {
1591
+ axisScript += `
1592
+ $axis.HasTitle = $true
1593
+ $axis.AxisTitle.Text = '${options.title.replace(/'/g, "''")}'`;
1594
+ }
1595
+ if (options.min !== undefined) {
1596
+ axisScript += `
1597
+ $axis.MinimumScale = ${options.min}`;
1598
+ }
1599
+ if (options.max !== undefined) {
1600
+ axisScript += `
1601
+ $axis.MaximumScale = ${options.max}`;
1602
+ }
1603
+ if (options.majorUnit !== undefined) {
1604
+ axisScript += `
1605
+ $axis.MajorUnit = ${options.majorUnit}`;
1606
+ }
1607
+ return this.executePowerShell(`
1608
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1609
+ ${sheetScript}
1610
+ $chartObj = $sheet.ChartObjects(${chartIndex})
1611
+ $chart = $chartObj.Chart
1612
+ ${axisScript}
1613
+ @{ success = $true; message = "Chart ${axisType}-axis updated" } | ConvertTo-Json -Compress
1614
+ `);
1615
+ }
1616
+ async excelLockCells(range, lock = true, sheet) {
1617
+ const sheetScript = sheet ?
1618
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${sheet.replace(/'/g, "''")}')` :
1619
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
1620
+ const lockValue = lock ? '$true' : '$false';
1621
+ return this.executePowerShell(`
1622
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1623
+ ${sheetScript}
1624
+ $sheet.Range('${range}').Locked = ${lockValue}
1625
+ @{ success = $true; message = "Cells ${range} ${lock ? 'locked' : 'unlocked'}" } | ConvertTo-Json -Compress
1626
+ `);
1627
+ }
1628
+ async excelGetUsedRange(sheet) {
1629
+ const sheetScript = sheet ?
1630
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${sheet.replace(/'/g, "''")}')` :
1631
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
1632
+ return this.executePowerShell(`
1633
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1634
+ ${sheetScript}
1635
+ $usedRange = $sheet.UsedRange
1636
+ $address = $usedRange.Address
1637
+ $rows = $usedRange.Rows.Count
1638
+ $cols = $usedRange.Columns.Count
1639
+ $firstRow = $usedRange.Row
1640
+ $firstCol = $usedRange.Column
1641
+ @{
1642
+ success = $true
1643
+ range = $address
1644
+ rows = $rows
1645
+ columns = $cols
1646
+ first_row = $firstRow
1647
+ first_column = $firstCol
1648
+ } | ConvertTo-Json -Compress
1649
+ `);
1650
+ }
1651
+ async excelAutofitRange(range, fitColumns = true, fitRows = false, sheet) {
1652
+ const sheetScript = sheet ?
1653
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${sheet.replace(/'/g, "''")}')` :
1654
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
1655
+ const fitScript = [];
1656
+ if (fitColumns)
1657
+ fitScript.push('$range.Columns.AutoFit() | Out-Null');
1658
+ if (fitRows)
1659
+ fitScript.push('$range.Rows.AutoFit() | Out-Null');
1660
+ return this.executePowerShell(`
1661
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1662
+ ${sheetScript}
1663
+ $range = $sheet.Range('${range}')
1664
+ ${fitScript.join('\n')}
1665
+ @{ success = $true; message = "Autofit applied to ${range}" } | ConvertTo-Json -Compress
1666
+ `);
1667
+ }
1668
+ async excelRemoveDuplicates(range, columns, hasHeader = true, sheet) {
1669
+ const sheetScript = sheet ?
1670
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${sheet.replace(/'/g, "''")}')` :
1671
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
1672
+ const header = hasHeader ? 1 : 2;
1673
+ const columnsScript = columns && columns.length > 0
1674
+ ? `$columns = @(${columns.join(',')})`
1675
+ : `$columns = @(1..$range.Columns.Count)`;
1676
+ return this.executePowerShell(`
1677
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1678
+ ${sheetScript}
1679
+ $range = $sheet.Range('${range}')
1680
+ $beforeCount = $range.Rows.Count
1681
+ ${columnsScript}
1682
+ $range.RemoveDuplicates($columns, ${header})
1683
+ $afterCount = $sheet.Range('${range}').Rows.Count
1684
+ $removed = $beforeCount - $afterCount
1685
+ @{ success = $true; message = "$removed duplicate rows removed"; rows_removed = $removed } | ConvertTo-Json -Compress
1686
+ `);
1687
+ }
1688
+ async excelGetCharts(sheet) {
1689
+ const sheetScript = sheet ?
1690
+ `$sheet = $excel.ActiveWorkbook.Worksheets('${sheet.replace(/'/g, "''")}')` :
1691
+ '$sheet = $excel.ActiveWorkbook.ActiveSheet';
1692
+ return this.executePowerShell(`
1693
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1694
+ ${sheetScript}
1695
+ $charts = @()
1696
+ $index = 1
1697
+ foreach ($chartObj in $sheet.ChartObjects()) {
1698
+ $chart = $chartObj.Chart
1699
+ $charts += @{
1700
+ index = $index
1701
+ name = $chartObj.Name
1702
+ chart_type = $chart.ChartType
1703
+ has_title = $chart.HasTitle
1704
+ title = if ($chart.HasTitle) { $chart.ChartTitle.Text } else { $null }
1705
+ left = $chartObj.Left
1706
+ top = $chartObj.Top
1707
+ width = $chartObj.Width
1708
+ height = $chartObj.Height
1709
+ series_count = $chart.SeriesCollection().Count
1710
+ }
1711
+ $index++
1712
+ }
1713
+ @{ success = $true; charts = $charts; count = $charts.Count } | ConvertTo-Json -Compress -Depth 5
1714
+ `);
1715
+ }
1716
+ async excelCreateTable(range, tableName, hasHeaders = true, sheet) {
1717
+ const sheetScript = sheet ?
1718
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` :
1719
+ '$sheet = $workbook.ActiveSheet';
1720
+ const xlSrcRange = 1;
1721
+ const xlYes = 1;
1722
+ const xlNo = 2;
1723
+ const headerOption = hasHeaders ? xlYes : xlNo;
1724
+ return this.executePowerShell(`
1725
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1726
+ $workbook = $excel.ActiveWorkbook
1727
+ ${sheetScript}
1728
+ $range = $sheet.Range('${range}')
1729
+ $table = $sheet.ListObjects.Add(${xlSrcRange}, $range, $null, ${headerOption})
1730
+ $table.Name = '${tableName.replace(/'/g, "''")}'
1731
+ $table.TableStyle = 'TableStyleMedium2'
1732
+ @{ success = $true; message = "Table '${tableName}' created"; table_name = $table.Name; range = '${range}' } | ConvertTo-Json -Compress
1733
+ `);
1734
+ }
1735
+ async excelDeleteTable(tableName, sheet) {
1736
+ const sheetScript = sheet ?
1737
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` :
1738
+ '$sheet = $workbook.ActiveSheet';
1739
+ return this.executePowerShell(`
1740
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1741
+ $workbook = $excel.ActiveWorkbook
1742
+ ${sheetScript}
1743
+ $table = $sheet.ListObjects('${tableName.replace(/'/g, "''")}')
1744
+ $table.Delete()
1745
+ @{ success = $true; message = "Table '${tableName}' deleted" } | ConvertTo-Json -Compress
1746
+ `);
1747
+ }
1748
+ async excelGetTables(sheet) {
1749
+ const sheetScript = sheet ?
1750
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` :
1751
+ '$sheet = $workbook.ActiveSheet';
1752
+ return this.executePowerShell(`
1753
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1754
+ $workbook = $excel.ActiveWorkbook
1755
+ ${sheetScript}
1756
+ $tables = @()
1757
+ foreach ($table in $sheet.ListObjects) {
1758
+ $tables += @{
1759
+ name = $table.Name
1760
+ range = $table.Range.Address()
1761
+ row_count = $table.ListRows.Count
1762
+ column_count = $table.ListColumns.Count
1763
+ has_headers = $table.ShowHeaders
1764
+ style = $table.TableStyle.Name
1765
+ }
1766
+ }
1767
+ @{ success = $true; tables = $tables; count = $tables.Count } | ConvertTo-Json -Compress -Depth 5
1768
+ `);
1769
+ }
1770
+ async excelAddTableColumn(tableName, columnName, formula, sheet) {
1771
+ const sheetScript = sheet ?
1772
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` :
1773
+ '$sheet = $workbook.ActiveSheet';
1774
+ const formulaScript = formula
1775
+ ? `$newCol.DataBodyRange.Formula = '${formula.replace(/'/g, "''")}'`
1776
+ : '';
1777
+ return this.executePowerShell(`
1778
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1779
+ $workbook = $excel.ActiveWorkbook
1780
+ ${sheetScript}
1781
+ $table = $sheet.ListObjects('${tableName.replace(/'/g, "''")}')
1782
+ $newCol = $table.ListColumns.Add()
1783
+ $newCol.Name = '${columnName.replace(/'/g, "''")}'
1784
+ ${formulaScript}
1785
+ @{ success = $true; message = "Column '${columnName}' added to table '${tableName}'"; column_index = $newCol.Index } | ConvertTo-Json -Compress
1786
+ `);
1787
+ }
1788
+ async excelSetPageSetup(options, sheet) {
1789
+ const sheetScript = sheet ?
1790
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` :
1791
+ '$sheet = $workbook.ActiveSheet';
1792
+ const orientationMap = {
1793
+ portrait: 1,
1794
+ landscape: 2,
1795
+ };
1796
+ const paperSizeMap = {
1797
+ letter: 1,
1798
+ legal: 5,
1799
+ a4: 9,
1800
+ a3: 8,
1801
+ };
1802
+ const commands = [];
1803
+ if (options.orientation) {
1804
+ commands.push(`$ps.Orientation = ${orientationMap[options.orientation]}`);
1805
+ }
1806
+ if (options.paperSize) {
1807
+ commands.push(`$ps.PaperSize = ${paperSizeMap[options.paperSize]}`);
1808
+ }
1809
+ if (options.margins) {
1810
+ if (options.margins.top !== undefined)
1811
+ commands.push(`$ps.TopMargin = $excel.InchesToPoints(${options.margins.top})`);
1812
+ if (options.margins.bottom !== undefined)
1813
+ commands.push(`$ps.BottomMargin = $excel.InchesToPoints(${options.margins.bottom})`);
1814
+ if (options.margins.left !== undefined)
1815
+ commands.push(`$ps.LeftMargin = $excel.InchesToPoints(${options.margins.left})`);
1816
+ if (options.margins.right !== undefined)
1817
+ commands.push(`$ps.RightMargin = $excel.InchesToPoints(${options.margins.right})`);
1818
+ }
1819
+ if (options.fitToPage) {
1820
+ commands.push('$ps.Zoom = $false');
1821
+ commands.push(`$ps.FitToPagesWide = ${options.fitToWidth ?? 1}`);
1822
+ commands.push(`$ps.FitToPagesTall = ${options.fitToHeight ?? 1}`);
1823
+ }
1824
+ return this.executePowerShell(`
1825
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1826
+ $workbook = $excel.ActiveWorkbook
1827
+ ${sheetScript}
1828
+ $ps = $sheet.PageSetup
1829
+ ${commands.join('\n')}
1830
+ @{ success = $true; message = "Page setup configured" } | ConvertTo-Json -Compress
1831
+ `);
1832
+ }
1833
+ async excelSetPrintArea(range, sheet) {
1834
+ const sheetScript = sheet ?
1835
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` :
1836
+ '$sheet = $workbook.ActiveSheet';
1837
+ return this.executePowerShell(`
1838
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1839
+ $workbook = $excel.ActiveWorkbook
1840
+ ${sheetScript}
1841
+ $sheet.PageSetup.PrintArea = '${range}'
1842
+ @{ success = $true; message = "Print area set to '${range}'" } | ConvertTo-Json -Compress
1843
+ `);
1844
+ }
1845
+ async excelSetPrintTitles(rowsToRepeat, columnsToRepeat, sheet) {
1846
+ const sheetScript = sheet ?
1847
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` :
1848
+ '$sheet = $workbook.ActiveSheet';
1849
+ const commands = [];
1850
+ if (rowsToRepeat) {
1851
+ commands.push(`$sheet.PageSetup.PrintTitleRows = '${rowsToRepeat}'`);
1852
+ }
1853
+ if (columnsToRepeat) {
1854
+ commands.push(`$sheet.PageSetup.PrintTitleColumns = '${columnsToRepeat}'`);
1855
+ }
1856
+ return this.executePowerShell(`
1857
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1858
+ $workbook = $excel.ActiveWorkbook
1859
+ ${sheetScript}
1860
+ ${commands.join('\n')}
1861
+ @{ success = $true; message = "Print titles configured"; rows = '${rowsToRepeat || ''}'; columns = '${columnsToRepeat || ''}' } | ConvertTo-Json -Compress
1862
+ `);
1863
+ }
1864
+ async excelInsertArrayFormula(range, formula, sheet) {
1865
+ const sheetScript = sheet ?
1866
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` :
1867
+ '$sheet = $workbook.ActiveSheet';
1868
+ return this.executePowerShell(`
1869
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1870
+ $workbook = $excel.ActiveWorkbook
1871
+ ${sheetScript}
1872
+ $range = $sheet.Range('${range}')
1873
+ $range.FormulaArray = '${formula.replace(/'/g, "''")}'
1874
+ @{ success = $true; message = "Array formula inserted in '${range}'" } | ConvertTo-Json -Compress
1875
+ `);
1876
+ }
1877
+ async excelTranspose(sourceRange, destCell, sheet) {
1878
+ const sheetScript = sheet ?
1879
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` :
1880
+ '$sheet = $workbook.ActiveSheet';
1881
+ return this.executePowerShell(`
1882
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1883
+ $workbook = $excel.ActiveWorkbook
1884
+ ${sheetScript}
1885
+ $srcRange = $sheet.Range('${sourceRange}')
1886
+ $values = $srcRange.Value2
1887
+ $transposed = $excel.WorksheetFunction.Transpose($values)
1888
+ $rows = $srcRange.Columns.Count
1889
+ $cols = $srcRange.Rows.Count
1890
+ $destStart = $sheet.Range('${destCell}')
1891
+ $destEnd = $sheet.Cells($destStart.Row + $rows - 1, $destStart.Column + $cols - 1)
1892
+ $destRange = $sheet.Range($destStart, $destEnd)
1893
+ $destRange.Value = $transposed
1894
+ @{ success = $true; message = "Transposed '${sourceRange}' to '${destCell}'"; new_size = "$rows x $cols" } | ConvertTo-Json -Compress
1895
+ `);
1896
+ }
1897
+ async excelTextToColumns(range, delimiter, destCell, sheet) {
1898
+ const sheetScript = sheet ?
1899
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` :
1900
+ '$sheet = $workbook.ActiveSheet';
1901
+ const delimiterMap = {
1902
+ comma: '$true, $false, $false, $false, $false',
1903
+ tab: '$false, $false, $false, $true, $false',
1904
+ semicolon: '$false, $true, $false, $false, $false',
1905
+ space: '$false, $false, $false, $false, $true',
1906
+ };
1907
+ const delimiterArgs = delimiterMap[delimiter] || '$false, $false, $false, $false, $false';
1908
+ const otherDelim = delimiterMap[delimiter] ? '' : `, $false, '${delimiter}'`;
1909
+ const destScript = destCell ? `$sheet.Range('${destCell}')` : '$srcRange';
1910
+ return this.executePowerShell(`
1911
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1912
+ $workbook = $excel.ActiveWorkbook
1913
+ ${sheetScript}
1914
+ $srcRange = $sheet.Range('${range}')
1915
+ $srcRange.TextToColumns(${destScript}, 1, 1, $false, ${delimiterArgs}${otherDelim})
1916
+ @{ success = $true; message = "Text to columns applied to '${range}'" } | ConvertTo-Json -Compress
1917
+ `);
1918
+ }
1919
+ async excelHideSheet(sheetName) {
1920
+ return this.executePowerShell(`
1921
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1922
+ $workbook = $excel.ActiveWorkbook
1923
+ $sheet = $workbook.Sheets('${sheetName.replace(/'/g, "''")}')
1924
+ $sheet.Visible = 0 # xlSheetHidden
1925
+ @{ success = $true; message = "Sheet '${sheetName}' hidden" } | ConvertTo-Json -Compress
1926
+ `);
1927
+ }
1928
+ async excelShowSheet(sheetName) {
1929
+ return this.executePowerShell(`
1930
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1931
+ $workbook = $excel.ActiveWorkbook
1932
+ $sheet = $workbook.Sheets('${sheetName.replace(/'/g, "''")}')
1933
+ $sheet.Visible = -1 # xlSheetVisible
1934
+ @{ success = $true; message = "Sheet '${sheetName}' shown" } | ConvertTo-Json -Compress
1935
+ `);
1936
+ }
1937
+ async excelSetTabColor(sheetName, color) {
1938
+ const hexToRgb = (hex) => {
1939
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
1940
+ if (!result || !result[1] || !result[2] || !result[3])
1941
+ return null;
1942
+ return {
1943
+ r: parseInt(result[1], 16),
1944
+ g: parseInt(result[2], 16),
1945
+ b: parseInt(result[3], 16)
1946
+ };
1947
+ };
1948
+ const rgb = hexToRgb(color);
1949
+ if (!rgb) {
1950
+ return { success: false, error: `Invalid hex color: ${color}` };
1951
+ }
1952
+ return this.executePowerShell(`
1953
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1954
+ $workbook = $excel.ActiveWorkbook
1955
+ $sheet = $workbook.Sheets('${sheetName.replace(/'/g, "''")}')
1956
+ $sheet.Tab.Color = [System.Drawing.ColorTranslator]::ToOle([System.Drawing.Color]::FromArgb(${rgb.r}, ${rgb.g}, ${rgb.b}))
1957
+ @{ success = $true; message = "Tab color set for '${sheetName}'" } | ConvertTo-Json -Compress
1958
+ `);
1959
+ }
1960
+ async excelSetZoom(zoomLevel, sheet) {
1961
+ if (zoomLevel < 10 || zoomLevel > 400) {
1962
+ return { success: false, error: `Invalid zoom level: ${zoomLevel}. Must be between 10 and 400.` };
1963
+ }
1964
+ const sheetScript = sheet ?
1965
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}'); $sheet.Activate()` :
1966
+ '';
1967
+ return this.executePowerShell(`
1968
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1969
+ $workbook = $excel.ActiveWorkbook
1970
+ ${sheetScript}
1971
+ $excel.ActiveWindow.Zoom = ${zoomLevel}
1972
+ @{ success = $true; message = "Zoom set to ${zoomLevel}%" } | ConvertTo-Json -Compress
1973
+ `);
1974
+ }
1975
+ async excelSetGridlines(show, sheet) {
1976
+ const sheetScript = sheet ?
1977
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}'); $sheet.Activate()` :
1978
+ '';
1979
+ return this.executePowerShell(`
1980
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1981
+ $workbook = $excel.ActiveWorkbook
1982
+ ${sheetScript}
1983
+ $excel.ActiveWindow.DisplayGridlines = ${show ? '$true' : '$false'}
1984
+ @{ success = $true; message = "Gridlines ${show ? 'shown' : 'hidden'}" } | ConvertTo-Json -Compress
1985
+ `);
1986
+ }
1987
+ async excelSetViewMode(mode, sheet) {
1988
+ const sheetScript = sheet ?
1989
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}'); $sheet.Activate()` :
1990
+ '';
1991
+ const modeMap = {
1992
+ normal: 1,
1993
+ pageBreak: 2,
1994
+ pageLayout: 3,
1995
+ };
1996
+ return this.executePowerShell(`
1997
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
1998
+ $workbook = $excel.ActiveWorkbook
1999
+ ${sheetScript}
2000
+ $excel.ActiveWindow.View = ${modeMap[mode]}
2001
+ @{ success = $true; message = "View mode set to '${mode}'" } | ConvertTo-Json -Compress
2002
+ `);
2003
+ }
2004
+ async excelExportCsv(filePath, sheet) {
2005
+ const windowsPath = this.toWindowsPath(filePath).replace(/'/g, "''");
2006
+ const sheetScript = sheet ?
2007
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` :
2008
+ '$sheet = $workbook.ActiveSheet';
2009
+ return this.executePowerShell(`
2010
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
2011
+ $workbook = $excel.ActiveWorkbook
2012
+ ${sheetScript}
2013
+ $tempWorkbook = $excel.Workbooks.Add()
2014
+ $sheet.Copy($tempWorkbook.Sheets(1))
2015
+ $tempWorkbook.Sheets(1).Delete()
2016
+ $tempWorkbook.SaveAs('${windowsPath}', 6) # xlCSV = 6
2017
+ $tempWorkbook.Close($false)
2018
+ @{ success = $true; message = "Exported to CSV"; path = '${windowsPath}' } | ConvertTo-Json -Compress
2019
+ `);
2020
+ }
2021
+ async excelExportJson(range, filePath, sheet) {
2022
+ const windowsPath = this.toWindowsPath(filePath).replace(/'/g, "''");
2023
+ const sheetScript = sheet ?
2024
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` :
2025
+ '$sheet = $workbook.ActiveSheet';
2026
+ return this.executePowerShell(`
2027
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
2028
+ $workbook = $excel.ActiveWorkbook
2029
+ ${sheetScript}
2030
+ $range = $sheet.Range('${range}')
2031
+ $values = $range.Value2
2032
+ $rows = $range.Rows.Count
2033
+ $cols = $range.Columns.Count
2034
+
2035
+ # Get headers from first row
2036
+ $headers = @()
2037
+ for ($c = 1; $c -le $cols; $c++) {
2038
+ $headers += $values[1, $c]
2039
+ }
2040
+
2041
+ # Build JSON array
2042
+ $jsonArray = @()
2043
+ for ($r = 2; $r -le $rows; $r++) {
2044
+ $obj = @{}
2045
+ for ($c = 1; $c -le $cols; $c++) {
2046
+ $obj[$headers[$c-1]] = $values[$r, $c]
2047
+ }
2048
+ $jsonArray += $obj
2049
+ }
2050
+
2051
+ $json = $jsonArray | ConvertTo-Json -Depth 10
2052
+ [System.IO.File]::WriteAllText('${windowsPath}', $json, [System.Text.Encoding]::UTF8)
2053
+ @{ success = $true; message = "Exported to JSON"; path = '${windowsPath}'; rows = ($rows - 1) } | ConvertTo-Json -Compress
2054
+ `);
2055
+ }
2056
+ async excelImportCsv(filePath, destCell, delimiter = ',', sheet) {
2057
+ const windowsPath = this.toWindowsPath(filePath).replace(/'/g, "''");
2058
+ const sheetScript = sheet ?
2059
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` :
2060
+ '$sheet = $workbook.ActiveSheet';
2061
+ const textQualifier = 1;
2062
+ return this.executePowerShell(`
2063
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
2064
+ $workbook = $excel.ActiveWorkbook
2065
+ ${sheetScript}
2066
+ $destRange = $sheet.Range('${destCell}')
2067
+ $qt = $sheet.QueryTables.Add("TEXT;${windowsPath}", $destRange)
2068
+ $qt.TextFileParseType = 1 # xlDelimited
2069
+ $qt.TextFileCommaDelimiter = ${delimiter === ',' ? '$true' : '$false'}
2070
+ $qt.TextFileTabDelimiter = ${delimiter === '\t' ? '$true' : '$false'}
2071
+ $qt.TextFileSemicolonDelimiter = ${delimiter === ';' ? '$true' : '$false'}
2072
+ $qt.TextFileSpaceDelimiter = ${delimiter === ' ' ? '$true' : '$false'}
2073
+ $qt.TextFileTextQualifier = ${textQualifier}
2074
+ $qt.Refresh($false)
2075
+ $qt.Delete()
2076
+ @{ success = $true; message = "CSV imported to ${destCell}"; source = '${windowsPath}' } | ConvertTo-Json -Compress
2077
+ `);
2078
+ }
2079
+ async excelRemoveImage(imageName, sheet) {
2080
+ const sheetScript = sheet ?
2081
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` :
2082
+ '$sheet = $workbook.ActiveSheet';
2083
+ return this.executePowerShell(`
2084
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
2085
+ $workbook = $excel.ActiveWorkbook
2086
+ ${sheetScript}
2087
+ $shape = $sheet.Shapes('${imageName.replace(/'/g, "''")}')
2088
+ $shape.Delete()
2089
+ @{ success = $true; message = "Image '${imageName}' removed" } | ConvertTo-Json -Compress
2090
+ `);
2091
+ }
2092
+ async excelGetImages(sheet) {
2093
+ const sheetScript = sheet ?
2094
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` :
2095
+ '$sheet = $workbook.ActiveSheet';
2096
+ return this.executePowerShell(`
2097
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
2098
+ $workbook = $excel.ActiveWorkbook
2099
+ ${sheetScript}
2100
+ $images = @()
2101
+ foreach ($shape in $sheet.Shapes) {
2102
+ if ($shape.Type -eq 13) { # msoPicture
2103
+ $images += @{
2104
+ name = $shape.Name
2105
+ left = $shape.Left
2106
+ top = $shape.Top
2107
+ width = $shape.Width
2108
+ height = $shape.Height
2109
+ }
2110
+ }
2111
+ }
2112
+ @{ success = $true; images = $images; count = $images.Count } | ConvertTo-Json -Compress -Depth 5
2113
+ `);
2114
+ }
2115
+ async excelEditComment(cell, newText, sheet) {
2116
+ const sheetScript = sheet ?
2117
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` :
2118
+ '$sheet = $workbook.ActiveSheet';
2119
+ const hasKorean = /[가-힣ㄱ-ㅎㅏ-ㅣ]/.test(newText);
2120
+ return this.executePowerShell(`
2121
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
2122
+ $workbook = $excel.ActiveWorkbook
2123
+ ${sheetScript}
2124
+ $cell = $sheet.Range('${cell}')
2125
+ if ($cell.Comment -eq $null) {
2126
+ @{ success = $false; error = "No comment exists in cell ${cell}" } | ConvertTo-Json -Compress
2127
+ } else {
2128
+ $cell.Comment.Text('${newText.replace(/'/g, "''")}')
2129
+ ${hasKorean ? "$cell.Comment.Shape.TextFrame.Characters().Font.Name = 'Malgun Gothic'" : ''}
2130
+ @{ success = $true; message = "Comment updated in ${cell}" } | ConvertTo-Json -Compress
2131
+ }
2132
+ `);
2133
+ }
2134
+ async excelDeletePivotField(tableName, fieldName, sheet) {
2135
+ const sheetScript = sheet ?
2136
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` :
2137
+ '$sheet = $workbook.ActiveSheet';
2138
+ return this.executePowerShell(`
2139
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
2140
+ $workbook = $excel.ActiveWorkbook
2141
+ ${sheetScript}
2142
+ $pivotTable = $sheet.PivotTables('${tableName.replace(/'/g, "''")}')
2143
+ $field = $pivotTable.PivotFields('${fieldName.replace(/'/g, "''")}')
2144
+ $field.Orientation = 0 # xlHidden
2145
+ @{ success = $true; message = "Field '${fieldName}' removed from pivot table '${tableName}'" } | ConvertTo-Json -Compress
2146
+ `);
2147
+ }
2148
+ async excelSetCalculationMode(mode) {
2149
+ const modeMap = {
2150
+ automatic: -4105,
2151
+ manual: -4135,
2152
+ semiautomatic: 2,
2153
+ };
2154
+ return this.executePowerShell(`
2155
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
2156
+ $excel.Calculation = ${modeMap[mode]}
2157
+ @{ success = $true; message = "Calculation mode set to '${mode}'" } | ConvertTo-Json -Compress
2158
+ `);
2159
+ }
2160
+ async excelRecalculate(scope, range, sheet) {
2161
+ const sheetScript = sheet ?
2162
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` :
2163
+ '$sheet = $workbook.ActiveSheet';
2164
+ let calcScript = '';
2165
+ switch (scope) {
2166
+ case 'workbook':
2167
+ calcScript = '$excel.CalculateFull()';
2168
+ break;
2169
+ case 'sheet':
2170
+ calcScript = `${sheetScript}\n$sheet.Calculate()`;
2171
+ break;
2172
+ case 'range':
2173
+ calcScript = `${sheetScript}\n$sheet.Range('${range}').Calculate()`;
2174
+ break;
2175
+ }
2176
+ return this.executePowerShell(`
2177
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
2178
+ $workbook = $excel.ActiveWorkbook
2179
+ ${calcScript}
2180
+ @{ success = $true; message = "Recalculated ${scope}" } | ConvertTo-Json -Compress
2181
+ `);
2182
+ }
2183
+ async excelTracePrecedents(cell, sheet) {
2184
+ const sheetScript = sheet ?
2185
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` :
2186
+ '$sheet = $workbook.ActiveSheet';
2187
+ return this.executePowerShell(`
2188
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
2189
+ $workbook = $excel.ActiveWorkbook
2190
+ ${sheetScript}
2191
+ $cell = $sheet.Range('${cell}')
2192
+ $cell.ShowPrecedents()
2193
+ @{ success = $true; message = "Showing precedents for ${cell}" } | ConvertTo-Json -Compress
2194
+ `);
2195
+ }
2196
+ async excelTraceDependents(cell, sheet) {
2197
+ const sheetScript = sheet ?
2198
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` :
2199
+ '$sheet = $workbook.ActiveSheet';
2200
+ return this.executePowerShell(`
2201
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
2202
+ $workbook = $excel.ActiveWorkbook
2203
+ ${sheetScript}
2204
+ $cell = $sheet.Range('${cell}')
2205
+ $cell.ShowDependents()
2206
+ @{ success = $true; message = "Showing dependents for ${cell}" } | ConvertTo-Json -Compress
2207
+ `);
2208
+ }
2209
+ async excelClearArrows() {
2210
+ return this.executePowerShell(`
2211
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
2212
+ $workbook = $excel.ActiveWorkbook
2213
+ $workbook.ActiveSheet.ClearArrows()
2214
+ @{ success = $true; message = "Cleared all arrows" } | ConvertTo-Json -Compress
2215
+ `);
2216
+ }
2217
+ async excelGroupColumns(startCol, endCol, sheet) {
2218
+ const sheetScript = sheet ?
2219
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` :
2220
+ '$sheet = $workbook.ActiveSheet';
2221
+ return this.executePowerShell(`
2222
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
2223
+ $workbook = $excel.ActiveWorkbook
2224
+ ${sheetScript}
2225
+ $range = $sheet.Columns("${startCol}:${endCol}")
2226
+ $range.Group()
2227
+ @{ success = $true; message = "Grouped columns ${startCol} to ${endCol}" } | ConvertTo-Json -Compress
2228
+ `);
2229
+ }
2230
+ async excelUngroupColumns(startCol, endCol, sheet) {
2231
+ const sheetScript = sheet ?
2232
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` :
2233
+ '$sheet = $workbook.ActiveSheet';
2234
+ return this.executePowerShell(`
2235
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
2236
+ $workbook = $excel.ActiveWorkbook
2237
+ ${sheetScript}
2238
+ $range = $sheet.Columns("${startCol}:${endCol}")
2239
+ $range.Ungroup()
2240
+ @{ success = $true; message = "Ungrouped columns ${startCol} to ${endCol}" } | ConvertTo-Json -Compress
2241
+ `);
2242
+ }
2243
+ async excelInsertPageBreak(cell, type, sheet) {
2244
+ const sheetScript = sheet ?
2245
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` :
2246
+ '$sheet = $workbook.ActiveSheet';
2247
+ return this.executePowerShell(`
2248
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
2249
+ $workbook = $excel.ActiveWorkbook
2250
+ ${sheetScript}
2251
+ $cell = $sheet.Range("${cell}")
2252
+ $cell.PageBreak = -4135
2253
+ @{ success = $true; message = "Inserted ${type} page break at ${cell}" } | ConvertTo-Json -Compress
2254
+ `);
2255
+ }
2256
+ async excelDeletePageBreak(cell, type, sheet) {
2257
+ const sheetScript = sheet ?
2258
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` :
2259
+ '$sheet = $workbook.ActiveSheet';
2260
+ return this.executePowerShell(`
2261
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
2262
+ $workbook = $excel.ActiveWorkbook
2263
+ ${sheetScript}
2264
+ $cell = $sheet.Range("${cell}")
2265
+ $cell.PageBreak = -4142
2266
+ @{ success = $true; message = "Deleted ${type} page break at ${cell}" } | ConvertTo-Json -Compress
2267
+ `);
2268
+ }
2269
+ async excelResetAllPageBreaks(sheet) {
2270
+ const sheetScript = sheet ?
2271
+ `$sheet = $workbook.Sheets('${sheet.replace(/'/g, "''")}')` :
2272
+ '$sheet = $workbook.ActiveSheet';
2273
+ return this.executePowerShell(`
2274
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
2275
+ $workbook = $excel.ActiveWorkbook
2276
+ ${sheetScript}
2277
+ $sheet.ResetAllPageBreaks()
2278
+ @{ success = $true; message = "Reset all page breaks" } | ConvertTo-Json -Compress
2279
+ `);
2280
+ }
2281
+ async getUsedRangeBottom(sheetName) {
2282
+ try {
2283
+ const result = await this.executePowerShell(`
2284
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
2285
+ $ws = $excel.ActiveWorkbook.Worksheets('${sheetName.replace(/'/g, "''")}')
2286
+ $ur = $ws.UsedRange
2287
+ $lastRow = $ur.Row + $ur.Rows.Count - 1
2288
+ $bottom = $ws.Rows($lastRow).Top + $ws.Rows($lastRow).Height
2289
+ @{ success = $true; bottom = [math]::Round($bottom, 1) } | ConvertTo-Json -Compress
2290
+ `);
2291
+ if (result.success && 'bottom' in result) {
2292
+ const bottom = result['bottom'];
2293
+ return typeof bottom === 'number' ? bottom : 300;
2294
+ }
2295
+ return 300;
2296
+ }
2297
+ catch {
2298
+ return 300;
2299
+ }
2300
+ }
2301
+ async validateWorkbook() {
2302
+ try {
2303
+ const result = await this.executePowerShell(`
2304
+ $excel = [Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
2305
+ $wb = $excel.ActiveWorkbook
2306
+ $issues = @()
2307
+ $sheetCount = $wb.Sheets.Count
2308
+ if ($sheetCount -lt 2) { $issues += "Only $sheetCount sheet(s) found. Add more sheets with excel_add_sheet." }
2309
+ for ($s=1; $s -le $sheetCount; $s++) {
2310
+ $ws = $wb.Sheets.Item($s)
2311
+ $sn = $ws.Name
2312
+ try {
2313
+ $ur = $ws.UsedRange
2314
+ $dataRows = $ur.Rows.Count
2315
+ $dataCols = $ur.Columns.Count
2316
+ if ($dataRows -lt 10) { $issues += "Sheet '$sn' has only $($dataRows - 2) data row(s) (need at least 8). Add more rows with excel_build_data_sheet." }
2317
+ if ($dataCols -lt 5) { $issues += "Sheet '$sn' has only $dataCols column(s) (need at least 5). Add formula columns with excel_build_formula_columns." }
2318
+ # Empty row check removed — prompt guidance is sufficient, hard blocking causes save failures
2319
+ } catch { $issues += "Sheet '$sn' appears empty. Build data with excel_build_data_sheet." }
2320
+ try {
2321
+ $charts = $ws.ChartObjects().Count
2322
+ if ($charts -eq 0) { $issues += "Sheet '$sn' has no charts. Call excel_build_chart." }
2323
+ } catch { $issues += "Sheet '$sn' has no charts. Call excel_build_chart." }
2324
+ try {
2325
+ $cfCount = $ws.UsedRange.FormatConditions.Count
2326
+ if ($cfCount -eq 0) { $issues += "Sheet '$sn' has no conditional formatting. Call excel_build_conditional_format with rule_type cellValue AND colorScale." }
2327
+ elseif ($cfCount -lt 1) { $issues += "Sheet '$sn' has only $cfCount conditional format rule(s). Need at least 1: call excel_build_conditional_format (rule_type cellValue or colorScale)." }
2328
+ } catch { $issues += "Sheet '$sn' has no conditional formatting. Call excel_build_conditional_format with rule_type cellValue AND colorScale." }
2329
+ }
2330
+ @{ success = $true; valid = ($issues.Count -eq 0); issues = $issues } | ConvertTo-Json -Compress
2331
+ `);
2332
+ if (result.success && 'valid' in result) {
2333
+ return {
2334
+ valid: !!result['valid'],
2335
+ issues: result['issues'] || [],
2336
+ };
2337
+ }
2338
+ return { valid: true, issues: [] };
2339
+ }
2340
+ catch {
2341
+ return { valid: true, issues: [] };
2342
+ }
2343
+ }
2344
+ }
2345
+ export const excelClient = new ExcelClient();
2346
+ //# sourceMappingURL=excel-client.js.map