orquesta-cli 0.1.12

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 (851) hide show
  1. package/.eslintrc.json +26 -0
  2. package/.prettierrc.json +10 -0
  3. package/CLAUDE.md +199 -0
  4. package/LICENSE +21 -0
  5. package/README.md +280 -0
  6. package/SECURITY.md +290 -0
  7. package/TEST_LOCAL.md +245 -0
  8. package/dist/agents/base/base-agent.d.ts +38 -0
  9. package/dist/agents/base/base-agent.d.ts.map +1 -0
  10. package/dist/agents/base/base-agent.js +69 -0
  11. package/dist/agents/base/base-agent.js.map +1 -0
  12. package/dist/agents/docs-search/index.d.ts +33 -0
  13. package/dist/agents/docs-search/index.d.ts.map +1 -0
  14. package/dist/agents/docs-search/index.js +244 -0
  15. package/dist/agents/docs-search/index.js.map +1 -0
  16. package/dist/agents/index.d.ts +4 -0
  17. package/dist/agents/index.d.ts.map +1 -0
  18. package/dist/agents/index.js +4 -0
  19. package/dist/agents/index.js.map +1 -0
  20. package/dist/agents/planner/index.d.ts +17 -0
  21. package/dist/agents/planner/index.d.ts.map +1 -0
  22. package/dist/agents/planner/index.js +250 -0
  23. package/dist/agents/planner/index.js.map +1 -0
  24. package/dist/cli.d.ts +3 -0
  25. package/dist/cli.d.ts.map +1 -0
  26. package/dist/cli.js +144 -0
  27. package/dist/cli.js.map +1 -0
  28. package/dist/constants.d.ts +8 -0
  29. package/dist/constants.d.ts.map +1 -0
  30. package/dist/constants.js +10 -0
  31. package/dist/constants.js.map +1 -0
  32. package/dist/core/compact/compact-manager.d.ts +22 -0
  33. package/dist/core/compact/compact-manager.d.ts.map +1 -0
  34. package/dist/core/compact/compact-manager.js +75 -0
  35. package/dist/core/compact/compact-manager.js.map +1 -0
  36. package/dist/core/compact/compact-prompts.d.ts +11 -0
  37. package/dist/core/compact/compact-prompts.d.ts.map +1 -0
  38. package/dist/core/compact/compact-prompts.js +90 -0
  39. package/dist/core/compact/compact-prompts.js.map +1 -0
  40. package/dist/core/compact/context-tracker.d.ts +28 -0
  41. package/dist/core/compact/context-tracker.d.ts.map +1 -0
  42. package/dist/core/compact/context-tracker.js +71 -0
  43. package/dist/core/compact/context-tracker.js.map +1 -0
  44. package/dist/core/compact/index.d.ts +4 -0
  45. package/dist/core/compact/index.d.ts.map +1 -0
  46. package/dist/core/compact/index.js +4 -0
  47. package/dist/core/compact/index.js.map +1 -0
  48. package/dist/core/config/config-manager.d.ts +44 -0
  49. package/dist/core/config/config-manager.d.ts.map +1 -0
  50. package/dist/core/config/config-manager.js +259 -0
  51. package/dist/core/config/config-manager.js.map +1 -0
  52. package/dist/core/config/index.d.ts +2 -0
  53. package/dist/core/config/index.d.ts.map +1 -0
  54. package/dist/core/config/index.js +2 -0
  55. package/dist/core/config/index.js.map +1 -0
  56. package/dist/core/docs-manager.d.ts +46 -0
  57. package/dist/core/docs-manager.d.ts.map +1 -0
  58. package/dist/core/docs-manager.js +475 -0
  59. package/dist/core/docs-manager.js.map +1 -0
  60. package/dist/core/git-auto-updater.d.ts +58 -0
  61. package/dist/core/git-auto-updater.d.ts.map +1 -0
  62. package/dist/core/git-auto-updater.js +374 -0
  63. package/dist/core/git-auto-updater.js.map +1 -0
  64. package/dist/core/llm/index.d.ts +2 -0
  65. package/dist/core/llm/index.d.ts.map +1 -0
  66. package/dist/core/llm/index.js +2 -0
  67. package/dist/core/llm/index.js.map +1 -0
  68. package/dist/core/llm/llm-client.d.ts +97 -0
  69. package/dist/core/llm/llm-client.d.ts.map +1 -0
  70. package/dist/core/llm/llm-client.js +1000 -0
  71. package/dist/core/llm/llm-client.js.map +1 -0
  72. package/dist/core/session/index.d.ts +2 -0
  73. package/dist/core/session/index.d.ts.map +1 -0
  74. package/dist/core/session/index.js +2 -0
  75. package/dist/core/session/index.js.map +1 -0
  76. package/dist/core/session/session-manager.d.ts +71 -0
  77. package/dist/core/session/session-manager.d.ts.map +1 -0
  78. package/dist/core/session/session-manager.js +250 -0
  79. package/dist/core/session/session-manager.js.map +1 -0
  80. package/dist/core/slash-command-handler.d.ts +31 -0
  81. package/dist/core/slash-command-handler.d.ts.map +1 -0
  82. package/dist/core/slash-command-handler.js +302 -0
  83. package/dist/core/slash-command-handler.js.map +1 -0
  84. package/dist/core/usage-tracker.d.ts +70 -0
  85. package/dist/core/usage-tracker.d.ts.map +1 -0
  86. package/dist/core/usage-tracker.js +251 -0
  87. package/dist/core/usage-tracker.js.map +1 -0
  88. package/dist/errors/base.d.ts +22 -0
  89. package/dist/errors/base.d.ts.map +1 -0
  90. package/dist/errors/base.js +43 -0
  91. package/dist/errors/base.js.map +1 -0
  92. package/dist/errors/file.d.ts +31 -0
  93. package/dist/errors/file.d.ts.map +1 -0
  94. package/dist/errors/file.js +110 -0
  95. package/dist/errors/file.js.map +1 -0
  96. package/dist/errors/index.d.ts +10 -0
  97. package/dist/errors/index.d.ts.map +1 -0
  98. package/dist/errors/index.js +41 -0
  99. package/dist/errors/index.js.map +1 -0
  100. package/dist/errors/llm.d.ts +26 -0
  101. package/dist/errors/llm.d.ts.map +1 -0
  102. package/dist/errors/llm.js +86 -0
  103. package/dist/errors/llm.js.map +1 -0
  104. package/dist/errors/network.d.ts +19 -0
  105. package/dist/errors/network.d.ts.map +1 -0
  106. package/dist/errors/network.js +82 -0
  107. package/dist/errors/network.js.map +1 -0
  108. package/dist/errors/validation.d.ts +19 -0
  109. package/dist/errors/validation.d.ts.map +1 -0
  110. package/dist/errors/validation.js +62 -0
  111. package/dist/errors/validation.js.map +1 -0
  112. package/dist/eval/eval-runner.d.ts +24 -0
  113. package/dist/eval/eval-runner.d.ts.map +1 -0
  114. package/dist/eval/eval-runner.js +309 -0
  115. package/dist/eval/eval-runner.js.map +1 -0
  116. package/dist/eval/index.d.ts +3 -0
  117. package/dist/eval/index.d.ts.map +1 -0
  118. package/dist/eval/index.js +3 -0
  119. package/dist/eval/index.js.map +1 -0
  120. package/dist/eval/types.d.ts +77 -0
  121. package/dist/eval/types.d.ts.map +1 -0
  122. package/dist/eval/types.js +2 -0
  123. package/dist/eval/types.js.map +1 -0
  124. package/dist/index.d.ts +4 -0
  125. package/dist/index.d.ts.map +1 -0
  126. package/dist/index.js +6 -0
  127. package/dist/index.js.map +1 -0
  128. package/dist/orchestration/index.d.ts +4 -0
  129. package/dist/orchestration/index.d.ts.map +1 -0
  130. package/dist/orchestration/index.js +3 -0
  131. package/dist/orchestration/index.js.map +1 -0
  132. package/dist/orchestration/plan-executor.d.ts +28 -0
  133. package/dist/orchestration/plan-executor.d.ts.map +1 -0
  134. package/dist/orchestration/plan-executor.js +382 -0
  135. package/dist/orchestration/plan-executor.js.map +1 -0
  136. package/dist/orchestration/types.d.ts +66 -0
  137. package/dist/orchestration/types.d.ts.map +1 -0
  138. package/dist/orchestration/types.js +2 -0
  139. package/dist/orchestration/types.js.map +1 -0
  140. package/dist/orchestration/utils.d.ts +13 -0
  141. package/dist/orchestration/utils.d.ts.map +1 -0
  142. package/dist/orchestration/utils.js +78 -0
  143. package/dist/orchestration/utils.js.map +1 -0
  144. package/dist/orquesta/connection.d.ts +35 -0
  145. package/dist/orquesta/connection.d.ts.map +1 -0
  146. package/dist/orquesta/connection.js +189 -0
  147. package/dist/orquesta/connection.js.map +1 -0
  148. package/dist/prompts/agents/docs-search-decision.d.ts +6 -0
  149. package/dist/prompts/agents/docs-search-decision.d.ts.map +1 -0
  150. package/dist/prompts/agents/docs-search-decision.js +46 -0
  151. package/dist/prompts/agents/docs-search-decision.js.map +1 -0
  152. package/dist/prompts/agents/docs-search.d.ts +4 -0
  153. package/dist/prompts/agents/docs-search.d.ts.map +1 -0
  154. package/dist/prompts/agents/docs-search.js +70 -0
  155. package/dist/prompts/agents/docs-search.js.map +1 -0
  156. package/dist/prompts/agents/planning.d.ts +4 -0
  157. package/dist/prompts/agents/planning.d.ts.map +1 -0
  158. package/dist/prompts/agents/planning.js +119 -0
  159. package/dist/prompts/agents/planning.js.map +1 -0
  160. package/dist/prompts/index.d.ts +10 -0
  161. package/dist/prompts/index.d.ts.map +1 -0
  162. package/dist/prompts/index.js +10 -0
  163. package/dist/prompts/index.js.map +1 -0
  164. package/dist/prompts/shared/codebase-rules.d.ts +4 -0
  165. package/dist/prompts/shared/codebase-rules.d.ts.map +1 -0
  166. package/dist/prompts/shared/codebase-rules.js +16 -0
  167. package/dist/prompts/shared/codebase-rules.js.map +1 -0
  168. package/dist/prompts/shared/git-rules.d.ts +2 -0
  169. package/dist/prompts/shared/git-rules.d.ts.map +1 -0
  170. package/dist/prompts/shared/git-rules.js +87 -0
  171. package/dist/prompts/shared/git-rules.js.map +1 -0
  172. package/dist/prompts/shared/language-rules.d.ts +4 -0
  173. package/dist/prompts/shared/language-rules.d.ts.map +1 -0
  174. package/dist/prompts/shared/language-rules.js +22 -0
  175. package/dist/prompts/shared/language-rules.js.map +1 -0
  176. package/dist/prompts/shared/tool-usage.d.ts +12 -0
  177. package/dist/prompts/shared/tool-usage.d.ts.map +1 -0
  178. package/dist/prompts/shared/tool-usage.js +51 -0
  179. package/dist/prompts/shared/tool-usage.js.map +1 -0
  180. package/dist/prompts/system/compact.d.ts +3 -0
  181. package/dist/prompts/system/compact.d.ts.map +1 -0
  182. package/dist/prompts/system/compact.js +73 -0
  183. package/dist/prompts/system/compact.js.map +1 -0
  184. package/dist/prompts/system/plan-execute.d.ts +3 -0
  185. package/dist/prompts/system/plan-execute.d.ts.map +1 -0
  186. package/dist/prompts/system/plan-execute.js +83 -0
  187. package/dist/prompts/system/plan-execute.js.map +1 -0
  188. package/dist/tools/browser/browser-client.d.ts +107 -0
  189. package/dist/tools/browser/browser-client.d.ts.map +1 -0
  190. package/dist/tools/browser/browser-client.js +958 -0
  191. package/dist/tools/browser/browser-client.js.map +1 -0
  192. package/dist/tools/browser/browser-tools.d.ts +17 -0
  193. package/dist/tools/browser/browser-tools.d.ts.map +1 -0
  194. package/dist/tools/browser/browser-tools.js +972 -0
  195. package/dist/tools/browser/browser-tools.js.map +1 -0
  196. package/dist/tools/browser/index.d.ts +7 -0
  197. package/dist/tools/browser/index.d.ts.map +1 -0
  198. package/dist/tools/browser/index.js +17 -0
  199. package/dist/tools/browser/index.js.map +1 -0
  200. package/dist/tools/index.d.ts +4 -0
  201. package/dist/tools/index.d.ts.map +1 -0
  202. package/dist/tools/index.js +4 -0
  203. package/dist/tools/index.js.map +1 -0
  204. package/dist/tools/llm/agents/docs-search-tools.d.ts +17 -0
  205. package/dist/tools/llm/agents/docs-search-tools.d.ts.map +1 -0
  206. package/dist/tools/llm/agents/docs-search-tools.js +265 -0
  207. package/dist/tools/llm/agents/docs-search-tools.js.map +1 -0
  208. package/dist/tools/llm/agents/index.d.ts +4 -0
  209. package/dist/tools/llm/agents/index.d.ts.map +1 -0
  210. package/dist/tools/llm/agents/index.js +3 -0
  211. package/dist/tools/llm/agents/index.js.map +1 -0
  212. package/dist/tools/llm/index.d.ts +3 -0
  213. package/dist/tools/llm/index.d.ts.map +1 -0
  214. package/dist/tools/llm/index.js +3 -0
  215. package/dist/tools/llm/index.js.map +1 -0
  216. package/dist/tools/llm/simple/ask-user-tool.d.ts +5 -0
  217. package/dist/tools/llm/simple/ask-user-tool.d.ts.map +1 -0
  218. package/dist/tools/llm/simple/ask-user-tool.js +7 -0
  219. package/dist/tools/llm/simple/ask-user-tool.js.map +1 -0
  220. package/dist/tools/llm/simple/background-bash-tool.d.ts +30 -0
  221. package/dist/tools/llm/simple/background-bash-tool.d.ts.map +1 -0
  222. package/dist/tools/llm/simple/background-bash-tool.js +323 -0
  223. package/dist/tools/llm/simple/background-bash-tool.js.map +1 -0
  224. package/dist/tools/llm/simple/background-powershell-tool.d.ts +30 -0
  225. package/dist/tools/llm/simple/background-powershell-tool.d.ts.map +1 -0
  226. package/dist/tools/llm/simple/background-powershell-tool.js +305 -0
  227. package/dist/tools/llm/simple/background-powershell-tool.js.map +1 -0
  228. package/dist/tools/llm/simple/bash-tool.d.ts +4 -0
  229. package/dist/tools/llm/simple/bash-tool.d.ts.map +1 -0
  230. package/dist/tools/llm/simple/bash-tool.js +178 -0
  231. package/dist/tools/llm/simple/bash-tool.js.map +1 -0
  232. package/dist/tools/llm/simple/docs-search-agent-tool.d.ts +6 -0
  233. package/dist/tools/llm/simple/docs-search-agent-tool.d.ts.map +1 -0
  234. package/dist/tools/llm/simple/docs-search-agent-tool.js +104 -0
  235. package/dist/tools/llm/simple/docs-search-agent-tool.js.map +1 -0
  236. package/dist/tools/llm/simple/file-tools.d.ts +13 -0
  237. package/dist/tools/llm/simple/file-tools.d.ts.map +1 -0
  238. package/dist/tools/llm/simple/file-tools.js +785 -0
  239. package/dist/tools/llm/simple/file-tools.js.map +1 -0
  240. package/dist/tools/llm/simple/final-response-tool.d.ts +12 -0
  241. package/dist/tools/llm/simple/final-response-tool.d.ts.map +1 -0
  242. package/dist/tools/llm/simple/final-response-tool.js +107 -0
  243. package/dist/tools/llm/simple/final-response-tool.js.map +1 -0
  244. package/dist/tools/llm/simple/index.d.ts +11 -0
  245. package/dist/tools/llm/simple/index.d.ts.map +1 -0
  246. package/dist/tools/llm/simple/index.js +20 -0
  247. package/dist/tools/llm/simple/index.js.map +1 -0
  248. package/dist/tools/llm/simple/planning-tools.d.ts +5 -0
  249. package/dist/tools/llm/simple/planning-tools.d.ts.map +1 -0
  250. package/dist/tools/llm/simple/planning-tools.js +117 -0
  251. package/dist/tools/llm/simple/planning-tools.js.map +1 -0
  252. package/dist/tools/llm/simple/powershell-tool.d.ts +4 -0
  253. package/dist/tools/llm/simple/powershell-tool.d.ts.map +1 -0
  254. package/dist/tools/llm/simple/powershell-tool.js +178 -0
  255. package/dist/tools/llm/simple/powershell-tool.js.map +1 -0
  256. package/dist/tools/llm/simple/simple-tool-executor.d.ts +38 -0
  257. package/dist/tools/llm/simple/simple-tool-executor.d.ts.map +1 -0
  258. package/dist/tools/llm/simple/simple-tool-executor.js +134 -0
  259. package/dist/tools/llm/simple/simple-tool-executor.js.map +1 -0
  260. package/dist/tools/llm/simple/todo-tools.d.ts +15 -0
  261. package/dist/tools/llm/simple/todo-tools.d.ts.map +1 -0
  262. package/dist/tools/llm/simple/todo-tools.js +145 -0
  263. package/dist/tools/llm/simple/todo-tools.js.map +1 -0
  264. package/dist/tools/llm/simple/user-interaction-tools.d.ts +22 -0
  265. package/dist/tools/llm/simple/user-interaction-tools.d.ts.map +1 -0
  266. package/dist/tools/llm/simple/user-interaction-tools.js +168 -0
  267. package/dist/tools/llm/simple/user-interaction-tools.js.map +1 -0
  268. package/dist/tools/office/common/constants.d.ts +194 -0
  269. package/dist/tools/office/common/constants.d.ts.map +1 -0
  270. package/dist/tools/office/common/constants.js +169 -0
  271. package/dist/tools/office/common/constants.js.map +1 -0
  272. package/dist/tools/office/common/index.d.ts +4 -0
  273. package/dist/tools/office/common/index.d.ts.map +1 -0
  274. package/dist/tools/office/common/index.js +3 -0
  275. package/dist/tools/office/common/index.js.map +1 -0
  276. package/dist/tools/office/common/types.d.ts +82 -0
  277. package/dist/tools/office/common/types.d.ts.map +1 -0
  278. package/dist/tools/office/common/types.js +2 -0
  279. package/dist/tools/office/common/types.js.map +1 -0
  280. package/dist/tools/office/common/utils.d.ts +14 -0
  281. package/dist/tools/office/common/utils.d.ts.map +1 -0
  282. package/dist/tools/office/common/utils.js +58 -0
  283. package/dist/tools/office/common/utils.js.map +1 -0
  284. package/dist/tools/office/excel-client.d.ts +123 -0
  285. package/dist/tools/office/excel-client.d.ts.map +1 -0
  286. package/dist/tools/office/excel-client.js +1037 -0
  287. package/dist/tools/office/excel-client.js.map +1 -0
  288. package/dist/tools/office/excel-tools/cells.d.ts +10 -0
  289. package/dist/tools/office/excel-tools/cells.d.ts.map +1 -0
  290. package/dist/tools/office/excel-tools/cells.js +279 -0
  291. package/dist/tools/office/excel-tools/cells.js.map +1 -0
  292. package/dist/tools/office/excel-tools/charts.d.ts +6 -0
  293. package/dist/tools/office/excel-tools/charts.d.ts.map +1 -0
  294. package/dist/tools/office/excel-tools/charts.js +124 -0
  295. package/dist/tools/office/excel-tools/charts.js.map +1 -0
  296. package/dist/tools/office/excel-tools/comments.d.ts +6 -0
  297. package/dist/tools/office/excel-tools/comments.d.ts.map +1 -0
  298. package/dist/tools/office/excel-tools/comments.js +114 -0
  299. package/dist/tools/office/excel-tools/comments.js.map +1 -0
  300. package/dist/tools/office/excel-tools/data-ops.d.ts +10 -0
  301. package/dist/tools/office/excel-tools/data-ops.d.ts.map +1 -0
  302. package/dist/tools/office/excel-tools/data-ops.js +266 -0
  303. package/dist/tools/office/excel-tools/data-ops.js.map +1 -0
  304. package/dist/tools/office/excel-tools/export.d.ts +5 -0
  305. package/dist/tools/office/excel-tools/export.d.ts.map +1 -0
  306. package/dist/tools/office/excel-tools/export.js +75 -0
  307. package/dist/tools/office/excel-tools/export.js.map +1 -0
  308. package/dist/tools/office/excel-tools/formatting.d.ts +10 -0
  309. package/dist/tools/office/excel-tools/formatting.d.ts.map +1 -0
  310. package/dist/tools/office/excel-tools/formatting.js +276 -0
  311. package/dist/tools/office/excel-tools/formatting.js.map +1 -0
  312. package/dist/tools/office/excel-tools/index.d.ts +16 -0
  313. package/dist/tools/office/excel-tools/index.d.ts.map +1 -0
  314. package/dist/tools/office/excel-tools/index.js +42 -0
  315. package/dist/tools/office/excel-tools/index.js.map +1 -0
  316. package/dist/tools/office/excel-tools/launch.d.ts +10 -0
  317. package/dist/tools/office/excel-tools/launch.d.ts.map +1 -0
  318. package/dist/tools/office/excel-tools/launch.js +248 -0
  319. package/dist/tools/office/excel-tools/launch.js.map +1 -0
  320. package/dist/tools/office/excel-tools/media.d.ts +5 -0
  321. package/dist/tools/office/excel-tools/media.d.ts.map +1 -0
  322. package/dist/tools/office/excel-tools/media.js +84 -0
  323. package/dist/tools/office/excel-tools/media.js.map +1 -0
  324. package/dist/tools/office/excel-tools/named-ranges.d.ts +6 -0
  325. package/dist/tools/office/excel-tools/named-ranges.d.ts.map +1 -0
  326. package/dist/tools/office/excel-tools/named-ranges.js +113 -0
  327. package/dist/tools/office/excel-tools/named-ranges.js.map +1 -0
  328. package/dist/tools/office/excel-tools/protection.d.ts +5 -0
  329. package/dist/tools/office/excel-tools/protection.d.ts.map +1 -0
  330. package/dist/tools/office/excel-tools/protection.js +75 -0
  331. package/dist/tools/office/excel-tools/protection.js.map +1 -0
  332. package/dist/tools/office/excel-tools/rows-columns.d.ts +11 -0
  333. package/dist/tools/office/excel-tools/rows-columns.d.ts.map +1 -0
  334. package/dist/tools/office/excel-tools/rows-columns.js +293 -0
  335. package/dist/tools/office/excel-tools/rows-columns.js.map +1 -0
  336. package/dist/tools/office/excel-tools/sheets.d.ts +8 -0
  337. package/dist/tools/office/excel-tools/sheets.d.ts.map +1 -0
  338. package/dist/tools/office/excel-tools/sheets.js +177 -0
  339. package/dist/tools/office/excel-tools/sheets.js.map +1 -0
  340. package/dist/tools/office/excel-tools/validation.d.ts +7 -0
  341. package/dist/tools/office/excel-tools/validation.d.ts.map +1 -0
  342. package/dist/tools/office/excel-tools/validation.js +175 -0
  343. package/dist/tools/office/excel-tools/validation.js.map +1 -0
  344. package/dist/tools/office/excel-tools.d.ts +3 -0
  345. package/dist/tools/office/excel-tools.d.ts.map +1 -0
  346. package/dist/tools/office/excel-tools.js +3 -0
  347. package/dist/tools/office/excel-tools.js.map +1 -0
  348. package/dist/tools/office/index.d.ts +6 -0
  349. package/dist/tools/office/index.d.ts.map +1 -0
  350. package/dist/tools/office/index.js +9 -0
  351. package/dist/tools/office/index.js.map +1 -0
  352. package/dist/tools/office/office-client-base.d.ts +31 -0
  353. package/dist/tools/office/office-client-base.d.ts.map +1 -0
  354. package/dist/tools/office/office-client-base.js +154 -0
  355. package/dist/tools/office/office-client-base.js.map +1 -0
  356. package/dist/tools/office/office-client.d.ts +196 -0
  357. package/dist/tools/office/office-client.d.ts.map +1 -0
  358. package/dist/tools/office/office-client.js +200 -0
  359. package/dist/tools/office/office-client.js.map +1 -0
  360. package/dist/tools/office/powerpoint-client.d.ts +135 -0
  361. package/dist/tools/office/powerpoint-client.d.ts.map +1 -0
  362. package/dist/tools/office/powerpoint-client.js +1136 -0
  363. package/dist/tools/office/powerpoint-client.js.map +1 -0
  364. package/dist/tools/office/powerpoint-tools/effects.d.ts +9 -0
  365. package/dist/tools/office/powerpoint-tools/effects.d.ts.map +1 -0
  366. package/dist/tools/office/powerpoint-tools/effects.js +246 -0
  367. package/dist/tools/office/powerpoint-tools/effects.js.map +1 -0
  368. package/dist/tools/office/powerpoint-tools/export.d.ts +6 -0
  369. package/dist/tools/office/powerpoint-tools/export.d.ts.map +1 -0
  370. package/dist/tools/office/powerpoint-tools/export.js +108 -0
  371. package/dist/tools/office/powerpoint-tools/export.js.map +1 -0
  372. package/dist/tools/office/powerpoint-tools/index.d.ts +13 -0
  373. package/dist/tools/office/powerpoint-tools/index.d.ts.map +1 -0
  374. package/dist/tools/office/powerpoint-tools/index.js +33 -0
  375. package/dist/tools/office/powerpoint-tools/index.js.map +1 -0
  376. package/dist/tools/office/powerpoint-tools/launch.d.ts +9 -0
  377. package/dist/tools/office/powerpoint-tools/launch.d.ts.map +1 -0
  378. package/dist/tools/office/powerpoint-tools/launch.js +214 -0
  379. package/dist/tools/office/powerpoint-tools/launch.js.map +1 -0
  380. package/dist/tools/office/powerpoint-tools/media.d.ts +8 -0
  381. package/dist/tools/office/powerpoint-tools/media.d.ts.map +1 -0
  382. package/dist/tools/office/powerpoint-tools/media.js +211 -0
  383. package/dist/tools/office/powerpoint-tools/media.js.map +1 -0
  384. package/dist/tools/office/powerpoint-tools/notes.d.ts +8 -0
  385. package/dist/tools/office/powerpoint-tools/notes.d.ts.map +1 -0
  386. package/dist/tools/office/powerpoint-tools/notes.js +171 -0
  387. package/dist/tools/office/powerpoint-tools/notes.js.map +1 -0
  388. package/dist/tools/office/powerpoint-tools/sections.d.ts +6 -0
  389. package/dist/tools/office/powerpoint-tools/sections.d.ts.map +1 -0
  390. package/dist/tools/office/powerpoint-tools/sections.js +104 -0
  391. package/dist/tools/office/powerpoint-tools/sections.js.map +1 -0
  392. package/dist/tools/office/powerpoint-tools/shapes.d.ts +22 -0
  393. package/dist/tools/office/powerpoint-tools/shapes.d.ts.map +1 -0
  394. package/dist/tools/office/powerpoint-tools/shapes.js +681 -0
  395. package/dist/tools/office/powerpoint-tools/shapes.js.map +1 -0
  396. package/dist/tools/office/powerpoint-tools/slides.d.ts +11 -0
  397. package/dist/tools/office/powerpoint-tools/slides.d.ts.map +1 -0
  398. package/dist/tools/office/powerpoint-tools/slides.js +283 -0
  399. package/dist/tools/office/powerpoint-tools/slides.js.map +1 -0
  400. package/dist/tools/office/powerpoint-tools/tables.d.ts +6 -0
  401. package/dist/tools/office/powerpoint-tools/tables.d.ts.map +1 -0
  402. package/dist/tools/office/powerpoint-tools/tables.js +132 -0
  403. package/dist/tools/office/powerpoint-tools/tables.js.map +1 -0
  404. package/dist/tools/office/powerpoint-tools/text.d.ts +12 -0
  405. package/dist/tools/office/powerpoint-tools/text.d.ts.map +1 -0
  406. package/dist/tools/office/powerpoint-tools/text.js +366 -0
  407. package/dist/tools/office/powerpoint-tools/text.js.map +1 -0
  408. package/dist/tools/office/powerpoint-tools.d.ts +3 -0
  409. package/dist/tools/office/powerpoint-tools.d.ts.map +1 -0
  410. package/dist/tools/office/powerpoint-tools.js +3 -0
  411. package/dist/tools/office/powerpoint-tools.js.map +1 -0
  412. package/dist/tools/office/word-client.d.ts +147 -0
  413. package/dist/tools/office/word-client.d.ts.map +1 -0
  414. package/dist/tools/office/word-client.js +1341 -0
  415. package/dist/tools/office/word-client.js.map +1 -0
  416. package/dist/tools/office/word-tools/bookmarks.d.ts +7 -0
  417. package/dist/tools/office/word-tools/bookmarks.d.ts.map +1 -0
  418. package/dist/tools/office/word-tools/bookmarks.js +146 -0
  419. package/dist/tools/office/word-tools/bookmarks.js.map +1 -0
  420. package/dist/tools/office/word-tools/comments.d.ts +7 -0
  421. package/dist/tools/office/word-tools/comments.d.ts.map +1 -0
  422. package/dist/tools/office/word-tools/comments.js +146 -0
  423. package/dist/tools/office/word-tools/comments.js.map +1 -0
  424. package/dist/tools/office/word-tools/content.d.ts +7 -0
  425. package/dist/tools/office/word-tools/content.d.ts.map +1 -0
  426. package/dist/tools/office/word-tools/content.js +168 -0
  427. package/dist/tools/office/word-tools/content.js.map +1 -0
  428. package/dist/tools/office/word-tools/export.d.ts +5 -0
  429. package/dist/tools/office/word-tools/export.d.ts.map +1 -0
  430. package/dist/tools/office/word-tools/export.js +73 -0
  431. package/dist/tools/office/word-tools/export.js.map +1 -0
  432. package/dist/tools/office/word-tools/formatting.d.ts +6 -0
  433. package/dist/tools/office/word-tools/formatting.d.ts.map +1 -0
  434. package/dist/tools/office/word-tools/formatting.js +129 -0
  435. package/dist/tools/office/word-tools/formatting.js.map +1 -0
  436. package/dist/tools/office/word-tools/headers-footers.d.ts +6 -0
  437. package/dist/tools/office/word-tools/headers-footers.d.ts.map +1 -0
  438. package/dist/tools/office/word-tools/headers-footers.js +117 -0
  439. package/dist/tools/office/word-tools/headers-footers.js.map +1 -0
  440. package/dist/tools/office/word-tools/index.d.ts +16 -0
  441. package/dist/tools/office/word-tools/index.d.ts.map +1 -0
  442. package/dist/tools/office/word-tools/index.js +45 -0
  443. package/dist/tools/office/word-tools/index.js.map +1 -0
  444. package/dist/tools/office/word-tools/launch.d.ts +10 -0
  445. package/dist/tools/office/word-tools/launch.d.ts.map +1 -0
  446. package/dist/tools/office/word-tools/launch.js +255 -0
  447. package/dist/tools/office/word-tools/launch.js.map +1 -0
  448. package/dist/tools/office/word-tools/lists.d.ts +5 -0
  449. package/dist/tools/office/word-tools/lists.d.ts.map +1 -0
  450. package/dist/tools/office/word-tools/lists.js +73 -0
  451. package/dist/tools/office/word-tools/lists.js.map +1 -0
  452. package/dist/tools/office/word-tools/navigation.d.ts +5 -0
  453. package/dist/tools/office/word-tools/navigation.d.ts.map +1 -0
  454. package/dist/tools/office/word-tools/navigation.js +85 -0
  455. package/dist/tools/office/word-tools/navigation.js.map +1 -0
  456. package/dist/tools/office/word-tools/page-setup.d.ts +7 -0
  457. package/dist/tools/office/word-tools/page-setup.d.ts.map +1 -0
  458. package/dist/tools/office/word-tools/page-setup.js +152 -0
  459. package/dist/tools/office/word-tools/page-setup.js.map +1 -0
  460. package/dist/tools/office/word-tools/tables.d.ts +8 -0
  461. package/dist/tools/office/word-tools/tables.d.ts.map +1 -0
  462. package/dist/tools/office/word-tools/tables.js +197 -0
  463. package/dist/tools/office/word-tools/tables.js.map +1 -0
  464. package/dist/tools/office/word-tools/text.d.ts +9 -0
  465. package/dist/tools/office/word-tools/text.d.ts.map +1 -0
  466. package/dist/tools/office/word-tools/text.js +235 -0
  467. package/dist/tools/office/word-tools/text.js.map +1 -0
  468. package/dist/tools/office/word-tools/undo-redo.d.ts +5 -0
  469. package/dist/tools/office/word-tools/undo-redo.d.ts.map +1 -0
  470. package/dist/tools/office/word-tools/undo-redo.js +73 -0
  471. package/dist/tools/office/word-tools/undo-redo.js.map +1 -0
  472. package/dist/tools/office/word-tools/watermarks.d.ts +5 -0
  473. package/dist/tools/office/word-tools/watermarks.d.ts.map +1 -0
  474. package/dist/tools/office/word-tools/watermarks.js +81 -0
  475. package/dist/tools/office/word-tools/watermarks.js.map +1 -0
  476. package/dist/tools/office/word-tools.d.ts +3 -0
  477. package/dist/tools/office/word-tools.d.ts.map +1 -0
  478. package/dist/tools/office/word-tools.js +3 -0
  479. package/dist/tools/office/word-tools.js.map +1 -0
  480. package/dist/tools/registry.d.ts +53 -0
  481. package/dist/tools/registry.d.ts.map +1 -0
  482. package/dist/tools/registry.js +278 -0
  483. package/dist/tools/registry.js.map +1 -0
  484. package/dist/tools/types.d.ts +88 -0
  485. package/dist/tools/types.d.ts.map +1 -0
  486. package/dist/tools/types.js +19 -0
  487. package/dist/tools/types.js.map +1 -0
  488. package/dist/types/index.d.ts +126 -0
  489. package/dist/types/index.d.ts.map +1 -0
  490. package/dist/types/index.js +2 -0
  491. package/dist/types/index.js.map +1 -0
  492. package/dist/ui/PlanExecuteView.d.ts +11 -0
  493. package/dist/ui/PlanExecuteView.d.ts.map +1 -0
  494. package/dist/ui/PlanExecuteView.js +29 -0
  495. package/dist/ui/PlanExecuteView.js.map +1 -0
  496. package/dist/ui/TodoPanel.d.ts +13 -0
  497. package/dist/ui/TodoPanel.d.ts.map +1 -0
  498. package/dist/ui/TodoPanel.js +135 -0
  499. package/dist/ui/TodoPanel.js.map +1 -0
  500. package/dist/ui/UpdateNotification.d.ts +13 -0
  501. package/dist/ui/UpdateNotification.d.ts.map +1 -0
  502. package/dist/ui/UpdateNotification.js +42 -0
  503. package/dist/ui/UpdateNotification.js.map +1 -0
  504. package/dist/ui/components/ActivityIndicator.d.ts +25 -0
  505. package/dist/ui/components/ActivityIndicator.d.ts.map +1 -0
  506. package/dist/ui/components/ActivityIndicator.js +115 -0
  507. package/dist/ui/components/ActivityIndicator.js.map +1 -0
  508. package/dist/ui/components/CommandBrowser.d.ts +10 -0
  509. package/dist/ui/components/CommandBrowser.d.ts.map +1 -0
  510. package/dist/ui/components/CommandBrowser.js +53 -0
  511. package/dist/ui/components/CommandBrowser.js.map +1 -0
  512. package/dist/ui/components/CustomTextInput.d.ts +13 -0
  513. package/dist/ui/components/CustomTextInput.d.ts.map +1 -0
  514. package/dist/ui/components/CustomTextInput.js +245 -0
  515. package/dist/ui/components/CustomTextInput.js.map +1 -0
  516. package/dist/ui/components/DocsSearchProgress.d.ts +13 -0
  517. package/dist/ui/components/DocsSearchProgress.d.ts.map +1 -0
  518. package/dist/ui/components/DocsSearchProgress.js +37 -0
  519. package/dist/ui/components/DocsSearchProgress.js.map +1 -0
  520. package/dist/ui/components/FileBrowser.d.ts +11 -0
  521. package/dist/ui/components/FileBrowser.d.ts.map +1 -0
  522. package/dist/ui/components/FileBrowser.js +45 -0
  523. package/dist/ui/components/FileBrowser.js.map +1 -0
  524. package/dist/ui/components/LLMSetupWizard.d.ts +8 -0
  525. package/dist/ui/components/LLMSetupWizard.d.ts.map +1 -0
  526. package/dist/ui/components/LLMSetupWizard.js +192 -0
  527. package/dist/ui/components/LLMSetupWizard.js.map +1 -0
  528. package/dist/ui/components/Logo.d.ts +19 -0
  529. package/dist/ui/components/Logo.d.ts.map +1 -0
  530. package/dist/ui/components/Logo.js +55 -0
  531. package/dist/ui/components/Logo.js.map +1 -0
  532. package/dist/ui/components/MarkdownRenderer.d.ts +9 -0
  533. package/dist/ui/components/MarkdownRenderer.d.ts.map +1 -0
  534. package/dist/ui/components/MarkdownRenderer.js +198 -0
  535. package/dist/ui/components/MarkdownRenderer.js.map +1 -0
  536. package/dist/ui/components/ModelSelector.d.ts +8 -0
  537. package/dist/ui/components/ModelSelector.d.ts.map +1 -0
  538. package/dist/ui/components/ModelSelector.js +111 -0
  539. package/dist/ui/components/ModelSelector.js.map +1 -0
  540. package/dist/ui/components/PlanExecuteApp.d.ts +23 -0
  541. package/dist/ui/components/PlanExecuteApp.d.ts.map +1 -0
  542. package/dist/ui/components/PlanExecuteApp.js +1324 -0
  543. package/dist/ui/components/PlanExecuteApp.js.map +1 -0
  544. package/dist/ui/components/ProgressBar.d.ts +10 -0
  545. package/dist/ui/components/ProgressBar.d.ts.map +1 -0
  546. package/dist/ui/components/ProgressBar.js +26 -0
  547. package/dist/ui/components/ProgressBar.js.map +1 -0
  548. package/dist/ui/components/StatusBar.d.ts +23 -0
  549. package/dist/ui/components/StatusBar.d.ts.map +1 -0
  550. package/dist/ui/components/StatusBar.js +162 -0
  551. package/dist/ui/components/StatusBar.js.map +1 -0
  552. package/dist/ui/components/ThinkingIndicator.d.ts +14 -0
  553. package/dist/ui/components/ThinkingIndicator.d.ts.map +1 -0
  554. package/dist/ui/components/ThinkingIndicator.js +63 -0
  555. package/dist/ui/components/ThinkingIndicator.js.map +1 -0
  556. package/dist/ui/components/TodoListView.d.ts +11 -0
  557. package/dist/ui/components/TodoListView.d.ts.map +1 -0
  558. package/dist/ui/components/TodoListView.js +69 -0
  559. package/dist/ui/components/TodoListView.js.map +1 -0
  560. package/dist/ui/components/ToolSelector.d.ts +7 -0
  561. package/dist/ui/components/ToolSelector.d.ts.map +1 -0
  562. package/dist/ui/components/ToolSelector.js +111 -0
  563. package/dist/ui/components/ToolSelector.js.map +1 -0
  564. package/dist/ui/components/dialogs/ApprovalDialog.d.ts +13 -0
  565. package/dist/ui/components/dialogs/ApprovalDialog.d.ts.map +1 -0
  566. package/dist/ui/components/dialogs/ApprovalDialog.js +173 -0
  567. package/dist/ui/components/dialogs/ApprovalDialog.js.map +1 -0
  568. package/dist/ui/components/dialogs/AskUserDialog.d.ts +9 -0
  569. package/dist/ui/components/dialogs/AskUserDialog.d.ts.map +1 -0
  570. package/dist/ui/components/dialogs/AskUserDialog.js +111 -0
  571. package/dist/ui/components/dialogs/AskUserDialog.js.map +1 -0
  572. package/dist/ui/components/dialogs/DocsBrowser.d.ts +8 -0
  573. package/dist/ui/components/dialogs/DocsBrowser.d.ts.map +1 -0
  574. package/dist/ui/components/dialogs/DocsBrowser.js +127 -0
  575. package/dist/ui/components/dialogs/DocsBrowser.js.map +1 -0
  576. package/dist/ui/components/dialogs/SettingsDialog.d.ts +10 -0
  577. package/dist/ui/components/dialogs/SettingsDialog.d.ts.map +1 -0
  578. package/dist/ui/components/dialogs/SettingsDialog.js +563 -0
  579. package/dist/ui/components/dialogs/SettingsDialog.js.map +1 -0
  580. package/dist/ui/components/dialogs/index.d.ts +4 -0
  581. package/dist/ui/components/dialogs/index.d.ts.map +1 -0
  582. package/dist/ui/components/dialogs/index.js +4 -0
  583. package/dist/ui/components/dialogs/index.js.map +1 -0
  584. package/dist/ui/components/index.d.ts +12 -0
  585. package/dist/ui/components/index.d.ts.map +1 -0
  586. package/dist/ui/components/index.js +9 -0
  587. package/dist/ui/components/index.js.map +1 -0
  588. package/dist/ui/components/panels/LogPanel.d.ts +7 -0
  589. package/dist/ui/components/panels/LogPanel.d.ts.map +1 -0
  590. package/dist/ui/components/panels/LogPanel.js +280 -0
  591. package/dist/ui/components/panels/LogPanel.js.map +1 -0
  592. package/dist/ui/components/panels/SessionPanel.d.ts +8 -0
  593. package/dist/ui/components/panels/SessionPanel.d.ts.map +1 -0
  594. package/dist/ui/components/panels/SessionPanel.js +81 -0
  595. package/dist/ui/components/panels/SessionPanel.js.map +1 -0
  596. package/dist/ui/components/panels/index.d.ts +4 -0
  597. package/dist/ui/components/panels/index.d.ts.map +1 -0
  598. package/dist/ui/components/panels/index.js +4 -0
  599. package/dist/ui/components/panels/index.js.map +1 -0
  600. package/dist/ui/components/views/ChatView.d.ts +12 -0
  601. package/dist/ui/components/views/ChatView.d.ts.map +1 -0
  602. package/dist/ui/components/views/ChatView.js +289 -0
  603. package/dist/ui/components/views/ChatView.js.map +1 -0
  604. package/dist/ui/components/views/index.d.ts +2 -0
  605. package/dist/ui/components/views/index.d.ts.map +1 -0
  606. package/dist/ui/components/views/index.js +2 -0
  607. package/dist/ui/components/views/index.js.map +1 -0
  608. package/dist/ui/contexts/TokenContext.d.ts +29 -0
  609. package/dist/ui/contexts/TokenContext.d.ts.map +1 -0
  610. package/dist/ui/contexts/TokenContext.js +79 -0
  611. package/dist/ui/contexts/TokenContext.js.map +1 -0
  612. package/dist/ui/hooks/atFileProcessor.d.ts +15 -0
  613. package/dist/ui/hooks/atFileProcessor.d.ts.map +1 -0
  614. package/dist/ui/hooks/atFileProcessor.js +88 -0
  615. package/dist/ui/hooks/atFileProcessor.js.map +1 -0
  616. package/dist/ui/hooks/index.d.ts +8 -0
  617. package/dist/ui/hooks/index.d.ts.map +1 -0
  618. package/dist/ui/hooks/index.js +8 -0
  619. package/dist/ui/hooks/index.js.map +1 -0
  620. package/dist/ui/hooks/slashCommandProcessor.d.ts +21 -0
  621. package/dist/ui/hooks/slashCommandProcessor.d.ts.map +1 -0
  622. package/dist/ui/hooks/slashCommandProcessor.js +100 -0
  623. package/dist/ui/hooks/slashCommandProcessor.js.map +1 -0
  624. package/dist/ui/hooks/useCommandBrowserState.d.ts +12 -0
  625. package/dist/ui/hooks/useCommandBrowserState.d.ts.map +1 -0
  626. package/dist/ui/hooks/useCommandBrowserState.js +66 -0
  627. package/dist/ui/hooks/useCommandBrowserState.js.map +1 -0
  628. package/dist/ui/hooks/useFileBrowserState.d.ts +15 -0
  629. package/dist/ui/hooks/useFileBrowserState.d.ts.map +1 -0
  630. package/dist/ui/hooks/useFileBrowserState.js +80 -0
  631. package/dist/ui/hooks/useFileBrowserState.js.map +1 -0
  632. package/dist/ui/hooks/useFileList.d.ts +20 -0
  633. package/dist/ui/hooks/useFileList.d.ts.map +1 -0
  634. package/dist/ui/hooks/useFileList.js +57 -0
  635. package/dist/ui/hooks/useFileList.js.map +1 -0
  636. package/dist/ui/hooks/useInputHistory.d.ts +9 -0
  637. package/dist/ui/hooks/useInputHistory.d.ts.map +1 -0
  638. package/dist/ui/hooks/useInputHistory.js +68 -0
  639. package/dist/ui/hooks/useInputHistory.js.map +1 -0
  640. package/dist/ui/hooks/usePlanExecution.d.ts +8 -0
  641. package/dist/ui/hooks/usePlanExecution.d.ts.map +1 -0
  642. package/dist/ui/hooks/usePlanExecution.js +214 -0
  643. package/dist/ui/hooks/usePlanExecution.js.map +1 -0
  644. package/dist/ui/index.d.ts +7 -0
  645. package/dist/ui/index.d.ts.map +1 -0
  646. package/dist/ui/index.js +7 -0
  647. package/dist/ui/index.js.map +1 -0
  648. package/dist/ui/ink-entry.d.ts +3 -0
  649. package/dist/ui/ink-entry.d.ts.map +1 -0
  650. package/dist/ui/ink-entry.js +22 -0
  651. package/dist/ui/ink-entry.js.map +1 -0
  652. package/dist/utils/env-filter.d.ts +4 -0
  653. package/dist/utils/env-filter.d.ts.map +1 -0
  654. package/dist/utils/env-filter.js +101 -0
  655. package/dist/utils/env-filter.js.map +1 -0
  656. package/dist/utils/file-system.d.ts +9 -0
  657. package/dist/utils/file-system.d.ts.map +1 -0
  658. package/dist/utils/file-system.js +99 -0
  659. package/dist/utils/file-system.js.map +1 -0
  660. package/dist/utils/git-utils.d.ts +2 -0
  661. package/dist/utils/git-utils.d.ts.map +1 -0
  662. package/dist/utils/git-utils.js +16 -0
  663. package/dist/utils/git-utils.js.map +1 -0
  664. package/dist/utils/json-stream-logger.d.ts +74 -0
  665. package/dist/utils/json-stream-logger.d.ts.map +1 -0
  666. package/dist/utils/json-stream-logger.js +808 -0
  667. package/dist/utils/json-stream-logger.js.map +1 -0
  668. package/dist/utils/logger.d.ts +152 -0
  669. package/dist/utils/logger.d.ts.map +1 -0
  670. package/dist/utils/logger.js +1672 -0
  671. package/dist/utils/logger.js.map +1 -0
  672. package/dist/utils/platform-utils.d.ts +19 -0
  673. package/dist/utils/platform-utils.d.ts.map +1 -0
  674. package/dist/utils/platform-utils.js +134 -0
  675. package/dist/utils/platform-utils.js.map +1 -0
  676. package/dist/utils/wsl-utils.d.ts +4 -0
  677. package/dist/utils/wsl-utils.d.ts.map +1 -0
  678. package/dist/utils/wsl-utils.js +72 -0
  679. package/dist/utils/wsl-utils.js.map +1 -0
  680. package/electron.vite.config.ts +63 -0
  681. package/google374b9eba0c52b043.html +1 -0
  682. package/package.json +122 -0
  683. package/src/agents/base/base-agent.ts +159 -0
  684. package/src/agents/docs-search/index.ts +365 -0
  685. package/src/agents/index.ts +34 -0
  686. package/src/agents/planner/index.ts +544 -0
  687. package/src/cli.ts +201 -0
  688. package/src/constants.ts +47 -0
  689. package/src/core/compact/compact-manager.ts +160 -0
  690. package/src/core/compact/compact-prompts.ts +150 -0
  691. package/src/core/compact/context-tracker.ts +164 -0
  692. package/src/core/compact/index.ts +25 -0
  693. package/src/core/config/config-manager.ts +460 -0
  694. package/src/core/config/index.ts +5 -0
  695. package/src/core/docs-manager.ts +678 -0
  696. package/src/core/llm/index.ts +7 -0
  697. package/src/core/llm/llm-client.ts +1550 -0
  698. package/src/core/session/index.ts +5 -0
  699. package/src/core/session/session-manager.ts +464 -0
  700. package/src/core/slash-command-handler.ts +410 -0
  701. package/src/core/usage-tracker.ts +438 -0
  702. package/src/errors/base.ts +81 -0
  703. package/src/errors/file.ts +183 -0
  704. package/src/errors/index.ts +95 -0
  705. package/src/errors/llm.ts +151 -0
  706. package/src/errors/network.ts +124 -0
  707. package/src/errors/validation.ts +111 -0
  708. package/src/eval/eval-runner.ts +456 -0
  709. package/src/eval/index.ts +8 -0
  710. package/src/eval/types.ts +139 -0
  711. package/src/index.ts +22 -0
  712. package/src/orchestration/index.ts +30 -0
  713. package/src/orchestration/plan-executor.ts +652 -0
  714. package/src/orchestration/types.ts +127 -0
  715. package/src/orchestration/utils.ts +119 -0
  716. package/src/orquesta/connection.ts +291 -0
  717. package/src/prompts/agents/docs-search-decision.ts +74 -0
  718. package/src/prompts/agents/docs-search.ts +84 -0
  719. package/src/prompts/agents/planning.ts +143 -0
  720. package/src/prompts/index.ts +31 -0
  721. package/src/prompts/shared/codebase-rules.ts +29 -0
  722. package/src/prompts/shared/git-rules.ts +94 -0
  723. package/src/prompts/shared/language-rules.ts +36 -0
  724. package/src/prompts/shared/tool-usage.ts +72 -0
  725. package/src/prompts/system/compact.ts +80 -0
  726. package/src/prompts/system/plan-execute.ts +89 -0
  727. package/src/tools/browser/browser-client.ts +1363 -0
  728. package/src/tools/browser/browser-tools.ts +1139 -0
  729. package/src/tools/browser/index.ts +65 -0
  730. package/src/tools/index.ts +23 -0
  731. package/src/tools/llm/agents/docs-search-tools.ts +368 -0
  732. package/src/tools/llm/agents/index.ts +22 -0
  733. package/src/tools/llm/index.ts +11 -0
  734. package/src/tools/llm/simple/ask-user-tool.ts +25 -0
  735. package/src/tools/llm/simple/background-bash-tool.ts +443 -0
  736. package/src/tools/llm/simple/background-powershell-tool.ts +421 -0
  737. package/src/tools/llm/simple/bash-tool.ts +238 -0
  738. package/src/tools/llm/simple/docs-search-agent-tool.ts +146 -0
  739. package/src/tools/llm/simple/file-tools.ts +1051 -0
  740. package/src/tools/llm/simple/final-response-tool.ts +180 -0
  741. package/src/tools/llm/simple/index.ts +42 -0
  742. package/src/tools/llm/simple/planning-tools.ts +143 -0
  743. package/src/tools/llm/simple/powershell-tool.ts +241 -0
  744. package/src/tools/llm/simple/simple-tool-executor.ts +279 -0
  745. package/src/tools/llm/simple/todo-tools.ts +207 -0
  746. package/src/tools/llm/simple/user-interaction-tools.ts +277 -0
  747. package/src/tools/office/common/constants.ts +335 -0
  748. package/src/tools/office/common/index.ts +133 -0
  749. package/src/tools/office/common/types.ts +286 -0
  750. package/src/tools/office/common/utils.ts +116 -0
  751. package/src/tools/office/excel-client.ts +1336 -0
  752. package/src/tools/office/excel-tools/cells.ts +359 -0
  753. package/src/tools/office/excel-tools/charts.ts +166 -0
  754. package/src/tools/office/excel-tools/comments.ts +155 -0
  755. package/src/tools/office/excel-tools/data-ops.ts +349 -0
  756. package/src/tools/office/excel-tools/export.ts +105 -0
  757. package/src/tools/office/excel-tools/formatting.ts +357 -0
  758. package/src/tools/office/excel-tools/index.ts +55 -0
  759. package/src/tools/office/excel-tools/launch.ts +303 -0
  760. package/src/tools/office/excel-tools/media.ts +117 -0
  761. package/src/tools/office/excel-tools/named-ranges.ts +148 -0
  762. package/src/tools/office/excel-tools/protection.ts +105 -0
  763. package/src/tools/office/excel-tools/rows-columns.ts +386 -0
  764. package/src/tools/office/excel-tools/sheets.ts +228 -0
  765. package/src/tools/office/excel-tools/validation.ts +226 -0
  766. package/src/tools/office/excel-tools.ts +9 -0
  767. package/src/tools/office/index.ts +259 -0
  768. package/src/tools/office/office-client-base.ts +242 -0
  769. package/src/tools/office/office-client.ts +377 -0
  770. package/src/tools/office/powerpoint-client.ts +1498 -0
  771. package/src/tools/office/powerpoint-tools/effects.ts +315 -0
  772. package/src/tools/office/powerpoint-tools/export.ts +138 -0
  773. package/src/tools/office/powerpoint-tools/index.ts +45 -0
  774. package/src/tools/office/powerpoint-tools/launch.ts +263 -0
  775. package/src/tools/office/powerpoint-tools/media.ts +291 -0
  776. package/src/tools/office/powerpoint-tools/notes.ts +220 -0
  777. package/src/tools/office/powerpoint-tools/sections.ts +140 -0
  778. package/src/tools/office/powerpoint-tools/shapes.ts +870 -0
  779. package/src/tools/office/powerpoint-tools/slides.ts +350 -0
  780. package/src/tools/office/powerpoint-tools/tables.ts +182 -0
  781. package/src/tools/office/powerpoint-tools/text.ts +473 -0
  782. package/src/tools/office/powerpoint-tools.ts +9 -0
  783. package/src/tools/office/word-client.ts +1697 -0
  784. package/src/tools/office/word-tools/bookmarks.ts +186 -0
  785. package/src/tools/office/word-tools/comments.ts +185 -0
  786. package/src/tools/office/word-tools/content.ts +229 -0
  787. package/src/tools/office/word-tools/export.ts +97 -0
  788. package/src/tools/office/word-tools/formatting.ts +161 -0
  789. package/src/tools/office/word-tools/headers-footers.ts +155 -0
  790. package/src/tools/office/word-tools/index.ts +57 -0
  791. package/src/tools/office/word-tools/launch.ts +312 -0
  792. package/src/tools/office/word-tools/lists.ts +97 -0
  793. package/src/tools/office/word-tools/navigation.ts +114 -0
  794. package/src/tools/office/word-tools/page-setup.ts +195 -0
  795. package/src/tools/office/word-tools/tables.ts +262 -0
  796. package/src/tools/office/word-tools/text.ts +294 -0
  797. package/src/tools/office/word-tools/undo-redo.ts +97 -0
  798. package/src/tools/office/word-tools/watermarks.ts +105 -0
  799. package/src/tools/office/word-tools.ts +9 -0
  800. package/src/tools/registry.ts +527 -0
  801. package/src/tools/types.ts +231 -0
  802. package/src/types/index.ts +181 -0
  803. package/src/ui/PlanExecuteView.tsx +119 -0
  804. package/src/ui/TodoPanel.tsx +240 -0
  805. package/src/ui/UpdateNotification.tsx +105 -0
  806. package/src/ui/components/ActivityIndicator.tsx +234 -0
  807. package/src/ui/components/CommandBrowser.tsx +114 -0
  808. package/src/ui/components/CustomTextInput.tsx +389 -0
  809. package/src/ui/components/DocsSearchProgress.tsx +85 -0
  810. package/src/ui/components/FileBrowser.tsx +93 -0
  811. package/src/ui/components/LLMSetupWizard.tsx +333 -0
  812. package/src/ui/components/Logo.tsx +125 -0
  813. package/src/ui/components/MarkdownRenderer.tsx +358 -0
  814. package/src/ui/components/ModelSelector.tsx +203 -0
  815. package/src/ui/components/PlanExecuteApp.tsx +2007 -0
  816. package/src/ui/components/ProgressBar.tsx +51 -0
  817. package/src/ui/components/StatusBar.tsx +302 -0
  818. package/src/ui/components/ThinkingIndicator.tsx +120 -0
  819. package/src/ui/components/TodoListView.tsx +140 -0
  820. package/src/ui/components/ToolSelector.tsx +215 -0
  821. package/src/ui/components/dialogs/ApprovalDialog.tsx +259 -0
  822. package/src/ui/components/dialogs/AskUserDialog.tsx +159 -0
  823. package/src/ui/components/dialogs/DocsBrowser.tsx +222 -0
  824. package/src/ui/components/dialogs/SettingsDialog.tsx +939 -0
  825. package/src/ui/components/dialogs/index.ts +13 -0
  826. package/src/ui/components/index.ts +27 -0
  827. package/src/ui/components/panels/LogPanel.tsx +385 -0
  828. package/src/ui/components/panels/SessionPanel.tsx +146 -0
  829. package/src/ui/components/panels/index.ts +13 -0
  830. package/src/ui/components/views/ChatView.tsx +447 -0
  831. package/src/ui/components/views/index.ts +5 -0
  832. package/src/ui/contexts/TokenContext.tsx +139 -0
  833. package/src/ui/hooks/atFileProcessor.ts +167 -0
  834. package/src/ui/hooks/index.ts +11 -0
  835. package/src/ui/hooks/slashCommandProcessor.ts +174 -0
  836. package/src/ui/hooks/useCommandBrowserState.ts +97 -0
  837. package/src/ui/hooks/useFileBrowserState.ts +116 -0
  838. package/src/ui/hooks/useFileList.ts +132 -0
  839. package/src/ui/hooks/useInputHistory.ts +89 -0
  840. package/src/ui/hooks/usePlanExecution.ts +339 -0
  841. package/src/ui/index.ts +10 -0
  842. package/src/ui/ink-entry.tsx +36 -0
  843. package/src/utils/env-filter.ts +164 -0
  844. package/src/utils/file-system.ts +133 -0
  845. package/src/utils/git-utils.ts +30 -0
  846. package/src/utils/json-stream-logger.ts +1259 -0
  847. package/src/utils/logger.ts +2767 -0
  848. package/src/utils/platform-utils.ts +256 -0
  849. package/src/utils/wsl-utils.ts +113 -0
  850. package/tsconfig.electron.json +39 -0
  851. package/tsconfig.json +64 -0
@@ -0,0 +1,1697 @@
1
+ /**
2
+ * Word Client
3
+ *
4
+ * Microsoft Word automation via PowerShell COM.
5
+ * Extends OfficeClientBase with Word-specific operations.
6
+ */
7
+
8
+ import { OfficeClientBase, OfficeResponse, ScreenshotResponse } from './office-client-base.js';
9
+
10
+ export class WordClient extends OfficeClientBase {
11
+ // ===========================================================================
12
+ // Microsoft Word Operations
13
+ // ===========================================================================
14
+
15
+ async wordLaunch(): Promise<OfficeResponse> {
16
+ return this.executePowerShell(`
17
+ try {
18
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
19
+ $word.Visible = $true
20
+ @{ success = $true; message = "Connected to existing Word instance" } | ConvertTo-Json -Compress
21
+ } catch {
22
+ $word = New-Object -ComObject Word.Application
23
+ $word.Visible = $true
24
+ @{ success = $true; message = "Launched new Word instance" } | ConvertTo-Json -Compress
25
+ }
26
+ `);
27
+ }
28
+
29
+ async wordCreate(): Promise<OfficeResponse> {
30
+ return this.executePowerShell(`
31
+ try {
32
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
33
+ } catch {
34
+ $word = New-Object -ComObject Word.Application
35
+ $word.Visible = $true
36
+ }
37
+ $doc = $word.Documents.Add()
38
+ @{ success = $true; message = "Created new document"; document_name = $doc.Name } | ConvertTo-Json -Compress
39
+ `);
40
+ }
41
+
42
+ async wordWrite(
43
+ text: string,
44
+ options?: { fontName?: string; fontSize?: number; bold?: boolean; italic?: boolean; newParagraph?: boolean }
45
+ ): Promise<OfficeResponse> {
46
+ // Auto-detect Korean text and set appropriate font if not specified
47
+ const hasKorean = /[가-힣ㄱ-ㅎㅏ-ㅣ]/.test(text);
48
+ let fontName = options?.fontName?.replace(/'/g, "''") || '';
49
+ if (!fontName && hasKorean) {
50
+ fontName = 'Malgun Gothic';
51
+ }
52
+
53
+ const fontSize = options?.fontSize || 0;
54
+ const bold = options?.bold ? '$true' : '$false';
55
+ const italic = options?.italic ? '$true' : '$false';
56
+ const newParagraph = options?.newParagraph !== false;
57
+
58
+ // Split text by \n and generate TypeText + TypeParagraph for each line
59
+ const lines = text.split(/\\n|\n/);
60
+ const typeCommands = lines.map((line, index) => {
61
+ const escapedLine = line.replace(/'/g, "''").replace(/`/g, '``');
62
+ const isLastLine = index === lines.length - 1;
63
+ if (isLastLine && !newParagraph) {
64
+ return `$selection.TypeText('${escapedLine}')`;
65
+ } else {
66
+ return `$selection.TypeText('${escapedLine}')\n$selection.TypeParagraph()`;
67
+ }
68
+ }).join('\n');
69
+
70
+ // TEXT FIRST, FONT AFTER pattern (Microsoft recommended for Korean)
71
+ return this.executePowerShell(`
72
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
73
+ $selection = $word.Selection
74
+
75
+ # Set formatting options (except font name for Korean)
76
+ ${fontSize ? `$selection.Font.Size = ${fontSize}` : ''}
77
+ $selection.Font.Bold = ${bold}
78
+ $selection.Font.Italic = ${italic}
79
+
80
+ # Type text first
81
+ ${typeCommands}
82
+
83
+ # Set font after text (prevents Korean garbled text)
84
+ ${fontName ? `$selection.Font.Name = '${fontName}'` : ''}
85
+
86
+ @{ success = $true; message = "Text written successfully" } | ConvertTo-Json -Compress
87
+ `);
88
+ }
89
+
90
+ async wordRead(): Promise<OfficeResponse> {
91
+ return this.executePowerShell(`
92
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
93
+ $doc = $word.ActiveDocument
94
+ $content = $doc.Content.Text
95
+ @{
96
+ success = $true
97
+ document_name = $doc.Name
98
+ content = $content
99
+ character_count = $content.Length
100
+ } | ConvertTo-Json -Compress
101
+ `);
102
+ }
103
+
104
+ async wordSave(filePath?: string): Promise<OfficeResponse> {
105
+ const windowsPath = filePath ? this.toWindowsPath(filePath).replace(/'/g, "''") : '';
106
+ return this.executePowerShell(`
107
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
108
+ $doc = $word.ActiveDocument
109
+ ${windowsPath ? `$doc.SaveAs([ref]'${windowsPath}')` : '$doc.Save()'}
110
+ @{ success = $true; message = "Document saved"; path = $doc.FullName } | ConvertTo-Json -Compress
111
+ `);
112
+ }
113
+
114
+ async wordOpen(filePath: string): Promise<OfficeResponse> {
115
+ const windowsPath = this.toWindowsPath(filePath).replace(/'/g, "''");
116
+ return this.executePowerShell(`
117
+ try {
118
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
119
+ } catch {
120
+ $word = New-Object -ComObject Word.Application
121
+ $word.Visible = $true
122
+ }
123
+ $doc = $word.Documents.Open('${windowsPath}')
124
+ @{ success = $true; message = "Document opened"; document_name = $doc.Name; path = $doc.FullName } | ConvertTo-Json -Compress
125
+ `);
126
+ }
127
+
128
+ async wordClose(save: boolean = false): Promise<OfficeResponse> {
129
+ const saveOption = save ? '-1' : '0'; // wdSaveChanges = -1, wdDoNotSaveChanges = 0
130
+ return this.executePowerShell(`
131
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
132
+ $word.ActiveDocument.Close(${saveOption})
133
+ @{ success = $true; message = "Document closed" } | ConvertTo-Json -Compress
134
+ `);
135
+ }
136
+
137
+ async wordQuit(save: boolean = false): Promise<OfficeResponse> {
138
+ const saveOption = save ? '-1' : '0';
139
+ return this.executePowerShell(`
140
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
141
+ $word.Quit(${saveOption})
142
+ @{ success = $true; message = "Word closed" } | ConvertTo-Json -Compress
143
+ `);
144
+ }
145
+
146
+ async wordSetFont(options: {
147
+ fontName?: string;
148
+ fontSize?: number;
149
+ bold?: boolean;
150
+ italic?: boolean;
151
+ underline?: boolean;
152
+ color?: string;
153
+ highlightColor?: string;
154
+ }): Promise<OfficeResponse> {
155
+ const commands: string[] = [];
156
+ if (options.fontName) commands.push(`$selection.Font.Name = '${options.fontName.replace(/'/g, "''")}'`);
157
+ if (options.fontSize) commands.push(`$selection.Font.Size = ${options.fontSize}`);
158
+ if (options.bold !== undefined) commands.push(`$selection.Font.Bold = ${options.bold ? '$true' : '$false'}`);
159
+ if (options.italic !== undefined) commands.push(`$selection.Font.Italic = ${options.italic ? '$true' : '$false'}`);
160
+ if (options.underline !== undefined) commands.push(`$selection.Font.Underline = ${options.underline ? '1' : '0'}`);
161
+ if (options.color) {
162
+ const rgb = this.hexToRgb(options.color);
163
+ if (rgb) commands.push(`$selection.Font.Color = ${rgb.r + rgb.g * 256 + rgb.b * 65536}`);
164
+ }
165
+
166
+ return this.executePowerShell(`
167
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
168
+ $selection = $word.Selection
169
+ ${commands.join('\n')}
170
+ @{ success = $true; message = "Font properties set" } | ConvertTo-Json -Compress
171
+ `);
172
+ }
173
+
174
+ async wordSetParagraph(options: {
175
+ alignment?: 'left' | 'center' | 'right' | 'justify';
176
+ lineSpacing?: number;
177
+ spaceBefore?: number;
178
+ spaceAfter?: number;
179
+ firstLineIndent?: number;
180
+ }): Promise<OfficeResponse> {
181
+ const alignmentMap: Record<string, number> = { left: 0, center: 1, right: 2, justify: 3 };
182
+ const commands: string[] = [];
183
+ if (options.alignment) commands.push(`$selection.ParagraphFormat.Alignment = ${alignmentMap[options.alignment]}`);
184
+ if (options.lineSpacing) commands.push(`$selection.ParagraphFormat.LineSpacing = ${options.lineSpacing}`);
185
+ if (options.spaceBefore) commands.push(`$selection.ParagraphFormat.SpaceBefore = ${options.spaceBefore}`);
186
+ if (options.spaceAfter) commands.push(`$selection.ParagraphFormat.SpaceAfter = ${options.spaceAfter}`);
187
+ if (options.firstLineIndent) commands.push(`$selection.ParagraphFormat.FirstLineIndent = ${options.firstLineIndent}`);
188
+
189
+ return this.executePowerShell(`
190
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
191
+ $selection = $word.Selection
192
+ ${commands.join('\n')}
193
+ @{ success = $true; message = "Paragraph formatting set" } | ConvertTo-Json -Compress
194
+ `);
195
+ }
196
+
197
+ async wordAddHyperlink(text: string, url: string): Promise<OfficeResponse> {
198
+ const escapedText = text.replace(/'/g, "''");
199
+ const escapedUrl = url.replace(/'/g, "''");
200
+ return this.executePowerShell(`
201
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
202
+ $selection = $word.Selection
203
+ $doc = $word.ActiveDocument
204
+ $range = $selection.Range
205
+ $doc.Hyperlinks.Add($range, '${escapedUrl}', '', '', '${escapedText}')
206
+ @{ success = $true; message = "Hyperlink added" } | ConvertTo-Json -Compress
207
+ `);
208
+ }
209
+
210
+ async wordAddTable(rows: number, cols: number, data?: string[][]): Promise<OfficeResponse> {
211
+ let dataScript = '';
212
+
213
+ // TEXT FIRST, FONT AFTER pattern (Microsoft recommended for Korean)
214
+ if (data) {
215
+ const dataLines: string[] = [];
216
+ for (let i = 0; i < data.length && i < rows; i++) {
217
+ const row = data[i];
218
+ if (!row) continue;
219
+ for (let j = 0; j < row.length && j < cols; j++) {
220
+ const cellValue = row[j];
221
+ if (cellValue === undefined) continue;
222
+ const cellHasKorean = /[가-힣ㄱ-ㅎㅏ-ㅣ]/.test(cellValue);
223
+ const val = cellValue.replace(/'/g, "''");
224
+ // 1. Text first
225
+ dataLines.push(`$table.Cell(${i + 1}, ${j + 1}).Range.Text = '${val}'`);
226
+ // 2. Font after (only if Korean)
227
+ if (cellHasKorean) {
228
+ dataLines.push(`$table.Cell(${i + 1}, ${j + 1}).Range.Font.Name = 'Malgun Gothic'`);
229
+ }
230
+ }
231
+ }
232
+ dataScript = dataLines.join('\n');
233
+ }
234
+
235
+ return this.executePowerShell(`
236
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
237
+ $doc = $word.ActiveDocument
238
+ $range = $word.Selection.Range
239
+ $table = $doc.Tables.Add($range, ${rows}, ${cols})
240
+ $table.Borders.Enable = $true
241
+ ${dataScript}
242
+ # Move cursor after the table and add a new paragraph
243
+ $tableEnd = $table.Range
244
+ $tableEnd.Collapse(0) # wdCollapseEnd = 0
245
+ $tableEnd.Select()
246
+ $word.Selection.TypeParagraph()
247
+ @{ success = $true; message = "Table added with ${rows} rows and ${cols} columns" } | ConvertTo-Json -Compress
248
+ `);
249
+ }
250
+
251
+ async wordAddImage(imagePath: string, width?: number, height?: number): Promise<OfficeResponse> {
252
+ const windowsPath = this.toWindowsPath(imagePath).replace(/'/g, "''");
253
+ const sizeScript = width || height
254
+ ? `
255
+ ${width ? '$shape.Width = ' + width : ''}
256
+ ${height ? '$shape.Height = ' + height : ''}`
257
+ : '';
258
+
259
+ return this.executePowerShell(`
260
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
261
+ $selection = $word.Selection
262
+ $shape = $selection.InlineShapes.AddPicture('${windowsPath}')
263
+ ${sizeScript}
264
+ # Move cursor after the image
265
+ $selection.MoveRight(1, 1) # wdCharacter = 1
266
+ @{ success = $true; message = "Image added" } | ConvertTo-Json -Compress
267
+ `);
268
+ }
269
+
270
+ async wordDeleteText(start: number, end: number): Promise<OfficeResponse> {
271
+ return this.executePowerShell(`
272
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
273
+ $doc = $word.ActiveDocument
274
+ $range = $doc.Range(${start}, ${end})
275
+ $range.Delete()
276
+ @{ success = $true; message = "Text deleted from position ${start} to ${end}" } | ConvertTo-Json -Compress
277
+ `);
278
+ }
279
+
280
+ async wordFindReplace(find: string, replace: string, replaceAll: boolean = true): Promise<OfficeResponse> {
281
+ const escapedFind = find.replace(/'/g, "''");
282
+ const escapedReplace = replace.replace(/'/g, "''");
283
+ const replaceOption = replaceAll ? '2' : '1'; // wdReplaceAll = 2, wdReplaceOne = 1
284
+
285
+ return this.executePowerShell(`
286
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
287
+ $doc = $word.ActiveDocument
288
+ $findObj = $doc.Content.Find
289
+ $findObj.ClearFormatting()
290
+ $findObj.Replacement.ClearFormatting()
291
+ $findObj.Text = '${escapedFind}'
292
+ $findObj.Replacement.Text = '${escapedReplace}'
293
+ $found = $findObj.Execute([ref]'${escapedFind}', [ref]$false, [ref]$false, [ref]$false, [ref]$false, [ref]$false, [ref]$true, [ref]0, [ref]$false, [ref]'${escapedReplace}', [ref]${replaceOption})
294
+ @{ success = $true; message = "Find and replace completed"; found = $found } | ConvertTo-Json -Compress
295
+ `);
296
+ }
297
+
298
+ async wordSetStyle(styleName: string, preserveKoreanFont: boolean = true): Promise<OfficeResponse> {
299
+ const escapedStyle = styleName.replace(/'/g, "''");
300
+
301
+ // Preserve Korean font after style change to prevent garbled text
302
+ const fontPreserveScript = preserveKoreanFont ? `
303
+ # Check if selection contains Korean text and preserve font
304
+ $selectedText = $selection.Text
305
+ if ($selectedText -match '[가-힣ㄱ-ㅎㅏ-ㅣ]') {
306
+ $selection.Font.Name = 'Malgun Gothic'
307
+ }` : '';
308
+
309
+ return this.executePowerShell(`
310
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
311
+ $selection = $word.Selection
312
+ $selection.Style = '${escapedStyle}'
313
+ ${fontPreserveScript}
314
+ @{ success = $true; message = "Style '${escapedStyle}' applied" } | ConvertTo-Json -Compress
315
+ `);
316
+ }
317
+
318
+ async wordInsertBreak(breakType: 'page' | 'line' | 'section' = 'page'): Promise<OfficeResponse> {
319
+ const breakTypeMap: Record<string, number> = { page: 7, line: 6, section: 2 }; // wdPageBreak, wdLineBreak, wdSectionBreakNextPage
320
+ return this.executePowerShell(`
321
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
322
+ $selection = $word.Selection
323
+ $selection.InsertBreak(${breakTypeMap[breakType]})
324
+ @{ success = $true; message = "${breakType} break inserted" } | ConvertTo-Json -Compress
325
+ `);
326
+ }
327
+
328
+ async wordGetSelection(): Promise<OfficeResponse> {
329
+ return this.executePowerShell(`
330
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
331
+ $selection = $word.Selection
332
+ @{
333
+ success = $true
334
+ text = $selection.Text
335
+ start = $selection.Start
336
+ end = $selection.End
337
+ font_name = $selection.Font.Name
338
+ font_size = $selection.Font.Size
339
+ } | ConvertTo-Json -Compress
340
+ `);
341
+ }
342
+
343
+ async wordSelectAll(): Promise<OfficeResponse> {
344
+ return this.executePowerShell(`
345
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
346
+ $word.ActiveDocument.Content.Select()
347
+ @{ success = $true; message = "All content selected" } | ConvertTo-Json -Compress
348
+ `);
349
+ }
350
+
351
+ async wordGoto(what: 'page' | 'line' | 'bookmark', target: number | string): Promise<OfficeResponse> {
352
+ const whatMap: Record<string, number> = { page: 1, line: 3, bookmark: -1 };
353
+ const isBookmark = what === 'bookmark';
354
+ return this.executePowerShell(`
355
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
356
+ $selection = $word.Selection
357
+ ${isBookmark
358
+ ? `$selection.GoTo(-1, 0, 0, '${String(target).replace(/'/g, "''")}')`
359
+ : `$selection.GoTo(${whatMap[what]}, 0, ${target})`}
360
+ @{ success = $true; message = "Moved to ${what} ${target}" } | ConvertTo-Json -Compress
361
+ `);
362
+ }
363
+
364
+ async wordInsertHeader(text: string, options?: { fontName?: string; fontSize?: number }): Promise<OfficeResponse> {
365
+ const escapedText = text.replace(/'/g, "''");
366
+ // Auto-detect Korean and set font
367
+ const hasKorean = /[가-힣ㄱ-ㅎㅏ-ㅣ]/.test(text);
368
+ const fontName = options?.fontName || (hasKorean ? 'Malgun Gothic' : '');
369
+
370
+ return this.executePowerShell(`
371
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
372
+ $doc = $word.ActiveDocument
373
+ $section = $doc.Sections(1)
374
+ $header = $section.Headers(1).Range
375
+ # Convert \\n to actual line breaks
376
+ $headerText = '${escapedText}' -replace '\\\\n', [char]10 -replace '\\n', [char]10
377
+ $header.Text = $headerText
378
+ # TEXT FIRST, FONT AFTER pattern
379
+ ${fontName ? `$header.Font.Name = '${fontName}'` : ''}
380
+ ${options?.fontSize ? `$header.Font.Size = ${options.fontSize}` : ''}
381
+ @{ success = $true; message = "Header added" } | ConvertTo-Json -Compress
382
+ `);
383
+ }
384
+
385
+ async wordInsertFooter(text: string, options?: { fontName?: string; fontSize?: number }): Promise<OfficeResponse> {
386
+ const escapedText = text.replace(/'/g, "''");
387
+ // Auto-detect Korean and set font
388
+ const hasKorean = /[가-힣ㄱ-ㅎㅏ-ㅣ]/.test(text);
389
+ const fontName = options?.fontName || (hasKorean ? 'Malgun Gothic' : '');
390
+
391
+ return this.executePowerShell(`
392
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
393
+ $doc = $word.ActiveDocument
394
+ $section = $doc.Sections(1)
395
+ $footer = $section.Footers(1).Range
396
+ # Convert \\n to actual line breaks
397
+ $footerText = '${escapedText}' -replace '\\\\n', [char]10 -replace '\\n', [char]10
398
+ $footer.Text = $footerText
399
+ # TEXT FIRST, FONT AFTER pattern
400
+ ${fontName ? `$footer.Font.Name = '${fontName.replace(/'/g, "''")}'` : ''}
401
+ ${options?.fontSize ? `$footer.Font.Size = ${options.fontSize}` : ''}
402
+ @{ success = $true; message = "Footer added" } | ConvertTo-Json -Compress
403
+ `);
404
+ }
405
+
406
+ async wordInsertPageNumber(alignment: 'left' | 'center' | 'right' = 'center'): Promise<OfficeResponse> {
407
+ const alignMap: Record<string, number> = { left: 0, center: 1, right: 2 };
408
+ return this.executePowerShell(`
409
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
410
+ $doc = $word.ActiveDocument
411
+ $section = $doc.Sections(1)
412
+ $footer = $section.Footers(1)
413
+ $footer.PageNumbers.Add(${alignMap[alignment]})
414
+ @{ success = $true; message = "Page numbers added" } | ConvertTo-Json -Compress
415
+ `);
416
+ }
417
+
418
+ async wordExportToPDF(outputPath: string): Promise<OfficeResponse> {
419
+ const windowsPath = this.toWindowsPath(outputPath).replace(/'/g, "''");
420
+ return this.executePowerShell(`
421
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
422
+ $doc = $word.ActiveDocument
423
+ $doc.ExportAsFixedFormat('${windowsPath}', 17) # 17 = wdExportFormatPDF
424
+ @{ success = $true; message = "Exported to PDF"; path = '${windowsPath}' } | ConvertTo-Json -Compress
425
+ `);
426
+ }
427
+
428
+ async wordPrint(copies: number = 1): Promise<OfficeResponse> {
429
+ return this.executePowerShell(`
430
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
431
+ $doc = $word.ActiveDocument
432
+ $doc.PrintOut([ref]$false, [ref]$false, [ref]0, [ref]"", [ref]"", [ref]"", [ref]0, [ref]${copies})
433
+ @{ success = $true; message = "Print job sent (${copies} copies)" } | ConvertTo-Json -Compress
434
+ `);
435
+ }
436
+
437
+ async wordScreenshot(): Promise<ScreenshotResponse> {
438
+ // Word screenshot via temporary file export
439
+ const result = await this.executePowerShell(`
440
+ Add-Type -AssemblyName System.Windows.Forms
441
+ Add-Type -AssemblyName System.Drawing
442
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
443
+ $doc = $word.ActiveDocument
444
+
445
+ # Switch to Print Preview to get a good screenshot
446
+ $originalView = $word.ActiveWindow.View.Type
447
+ $word.ActiveWindow.View.Type = 3 # wdPrintView
448
+
449
+ try {
450
+ # Method 1: Try CopyAsPicture on content
451
+ $doc.Content.Select()
452
+ $word.Selection.CopyAsPicture()
453
+ Start-Sleep -Milliseconds 300
454
+
455
+ $img = [System.Windows.Forms.Clipboard]::GetImage()
456
+
457
+ if ($img -eq $null) {
458
+ # Method 2: Fallback - capture the Word window
459
+ $hwnd = $word.Application.Hwnd
460
+ if ($hwnd -gt 0) {
461
+ Add-Type @"
462
+ using System;
463
+ using System.Drawing;
464
+ using System.Runtime.InteropServices;
465
+ public class Screenshot {
466
+ [DllImport("user32.dll")]
467
+ public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
468
+ [DllImport("user32.dll")]
469
+ public static extern bool SetForegroundWindow(IntPtr hWnd);
470
+ public struct RECT { public int Left, Top, Right, Bottom; }
471
+ public static Bitmap CaptureWindow(IntPtr hwnd) {
472
+ RECT rect;
473
+ GetWindowRect(hwnd, out rect);
474
+ int width = rect.Right - rect.Left;
475
+ int height = rect.Bottom - rect.Top;
476
+ if (width <= 0 || height <= 0) return null;
477
+ Bitmap bmp = new Bitmap(width, height);
478
+ using (Graphics g = Graphics.FromImage(bmp)) {
479
+ g.CopyFromScreen(rect.Left, rect.Top, 0, 0, new Size(width, height));
480
+ }
481
+ return bmp;
482
+ }
483
+ }
484
+ "@
485
+ [Screenshot]::SetForegroundWindow([IntPtr]$hwnd)
486
+ Start-Sleep -Milliseconds 500
487
+ $img = [Screenshot]::CaptureWindow([IntPtr]$hwnd)
488
+ }
489
+ }
490
+
491
+ if ($img -eq $null) {
492
+ @{ success = $false; error = "Failed to capture screenshot" } | ConvertTo-Json -Compress
493
+ return
494
+ }
495
+
496
+ # Convert to base64
497
+ $ms = New-Object System.IO.MemoryStream
498
+ $img.Save($ms, [System.Drawing.Imaging.ImageFormat]::Png)
499
+ $bytes = $ms.ToArray()
500
+ $base64 = [Convert]::ToBase64String($bytes)
501
+ $ms.Dispose()
502
+ $img.Dispose()
503
+
504
+ # Deselect
505
+ $word.Selection.Collapse(1)
506
+
507
+ @{
508
+ success = $true
509
+ image = $base64
510
+ format = "png"
511
+ encoding = "base64"
512
+ } | ConvertTo-Json -Compress
513
+ } finally {
514
+ # Restore original view
515
+ $word.ActiveWindow.View.Type = $originalView
516
+ }
517
+ `);
518
+ return result as ScreenshotResponse;
519
+ }
520
+
521
+ // -------------------------------------------------------------------------
522
+ // Word Table Manipulation
523
+ // -------------------------------------------------------------------------
524
+
525
+ async wordSetTableCell(
526
+ tableIndex: number,
527
+ row: number,
528
+ col: number,
529
+ text: string,
530
+ options?: { fontName?: string; fontSize?: number; bold?: boolean }
531
+ ): Promise<OfficeResponse> {
532
+ const escapedText = text.replace(/'/g, "''");
533
+ const hasKorean = /[가-힣ㄱ-ㅎㅏ-ㅣ]/.test(text);
534
+ let fontName = options?.fontName?.replace(/'/g, "''") || '';
535
+ if (!fontName && hasKorean) {
536
+ fontName = 'Malgun Gothic';
537
+ }
538
+
539
+ return this.executePowerShell(`
540
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
541
+ $doc = $word.ActiveDocument
542
+ $table = $doc.Tables(${tableIndex})
543
+ $cell = $table.Cell(${row}, ${col})
544
+ # Convert \\n to actual line breaks, then set text
545
+ $cellText = '${escapedText}' -replace '\\\\n', [char]10 -replace '\\n', [char]10
546
+ $cell.Range.Text = $cellText
547
+ # TEXT FIRST, FONT AFTER pattern
548
+ ${fontName ? `$cell.Range.Font.Name = '${fontName}'` : ''}
549
+ ${options?.fontSize ? `$cell.Range.Font.Size = ${options.fontSize}` : ''}
550
+ ${options?.bold ? '$cell.Range.Font.Bold = -1' : ''}
551
+ @{ success = $true; message = "Table cell (${row},${col}) updated" } | ConvertTo-Json -Compress
552
+ `);
553
+ }
554
+
555
+ async wordMergeTableCells(
556
+ tableIndex: number,
557
+ startRow: number,
558
+ startCol: number,
559
+ endRow: number,
560
+ endCol: number
561
+ ): Promise<OfficeResponse> {
562
+ return this.executePowerShell(`
563
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
564
+ $doc = $word.ActiveDocument
565
+ $table = $doc.Tables(${tableIndex})
566
+ $startCell = $table.Cell(${startRow}, ${startCol})
567
+ $endCell = $table.Cell(${endRow}, ${endCol})
568
+ $startCell.Merge($endCell)
569
+ @{ success = $true; message = "Table cells merged" } | ConvertTo-Json -Compress
570
+ `);
571
+ }
572
+
573
+ async wordSetTableStyle(tableIndex: number, styleName: string, preserveKoreanFont: boolean = true): Promise<OfficeResponse> {
574
+ const escapedStyle = styleName.replace(/'/g, "''");
575
+
576
+ // Map common style names to Word's built-in style constants (wdBuiltinStyle)
577
+ // These work regardless of the UI language
578
+ const styleConstMap: Record<string, number> = {
579
+ 'table grid': -176,
580
+ 'table normal': -106,
581
+ '표 눈금': -176, // Korean for Table Grid
582
+ '표 보통': -106, // Korean for Table Normal
583
+ };
584
+
585
+ const lowerStyleName = styleName.toLowerCase();
586
+ const styleConst = styleConstMap[lowerStyleName];
587
+
588
+ // Preserve Korean font after style change to prevent garbled text
589
+ const fontPreserveScript = preserveKoreanFont ? `
590
+ # Check if table contains Korean text and preserve font
591
+ $tableText = $table.Range.Text
592
+ if ($tableText -match '[가-힣ㄱ-ㅎㅏ-ㅣ]') {
593
+ $table.Range.Font.Name = 'Malgun Gothic'
594
+ }` : '';
595
+
596
+ return this.executePowerShell(`
597
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
598
+ $doc = $word.ActiveDocument
599
+ $table = $doc.Tables(${tableIndex})
600
+ try {
601
+ ${styleConst !== undefined
602
+ ? `$table.Style = ${styleConst}`
603
+ : `$table.Style = '${escapedStyle}'`}
604
+ ${fontPreserveScript}
605
+ @{ success = $true; message = "Table style set" } | ConvertTo-Json -Compress
606
+ } catch {
607
+ # Try with style name directly if constant fails
608
+ try {
609
+ $table.Style = '${escapedStyle}'
610
+ ${fontPreserveScript}
611
+ @{ success = $true; message = "Table style set to '${escapedStyle}'" } | ConvertTo-Json -Compress
612
+ } catch {
613
+ @{ success = $false; error = "Style '${escapedStyle}' not found. Try: 'Table Grid', 'Table Normal', or numeric style index." } | ConvertTo-Json -Compress
614
+ }
615
+ }
616
+ `);
617
+ }
618
+
619
+ async wordSetTableBorder(
620
+ tableIndex: number,
621
+ options: { style?: 'single' | 'double' | 'thick' | 'none'; color?: string }
622
+ ): Promise<OfficeResponse> {
623
+ // wdLineStyleSingle=1, wdLineStyleDouble=7, wdLineStyleThickThinLargeGap=14, wdLineStyleNone=0
624
+ const styleMap: Record<string, number> = {
625
+ single: 1,
626
+ double: 7,
627
+ thick: 14,
628
+ none: 0,
629
+ };
630
+ const lineStyle = styleMap[options.style || 'single'] ?? 1;
631
+
632
+ const colorValue = options.color ? (() => {
633
+ const rgb = this.hexToRgb(options.color);
634
+ return rgb ? rgb.r + rgb.g * 256 + rgb.b * 65536 : 0;
635
+ })() : 0;
636
+
637
+ return this.executePowerShell(`
638
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
639
+ $doc = $word.ActiveDocument
640
+ $table = $doc.Tables(${tableIndex})
641
+
642
+ # Border indices: wdBorderTop=-1, wdBorderLeft=-2, wdBorderBottom=-3, wdBorderRight=-4
643
+ # wdBorderHorizontal=-5, wdBorderVertical=-6
644
+ $borderIndices = @(-1, -2, -3, -4)
645
+ foreach ($idx in $borderIndices) {
646
+ $table.Borders.Item($idx).LineStyle = ${lineStyle}
647
+ ${colorValue ? `$table.Borders.Item($idx).Color = ${colorValue}` : ''}
648
+ }
649
+
650
+ # Inside borders (may not exist for 1-row or 1-column tables)
651
+ try {
652
+ $table.Borders.Item(-5).LineStyle = ${lineStyle} # Horizontal inside
653
+ ${colorValue ? `$table.Borders.Item(-5).Color = ${colorValue}` : ''}
654
+ } catch {}
655
+ try {
656
+ $table.Borders.Item(-6).LineStyle = ${lineStyle} # Vertical inside
657
+ ${colorValue ? `$table.Borders.Item(-6).Color = ${colorValue}` : ''}
658
+ } catch {}
659
+
660
+ @{ success = $true; message = "Table border set" } | ConvertTo-Json -Compress
661
+ `);
662
+ }
663
+
664
+ // -------------------------------------------------------------------------
665
+ // Word Bookmark
666
+ // -------------------------------------------------------------------------
667
+
668
+ async wordAddBookmark(name: string, text?: string): Promise<OfficeResponse> {
669
+ const escapedName = name.replace(/'/g, "''");
670
+ const escapedText = text ? text.replace(/'/g, "''") : '';
671
+ const originalTextLength = text ? text.length : 0; // Use original length, not escaped
672
+ const hasKorean = text ? /[가-힣ㄱ-ㅎㅏ-ㅣ]/.test(text) : false;
673
+
674
+ return this.executePowerShell(`
675
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
676
+ $doc = $word.ActiveDocument
677
+ $selection = $word.Selection
678
+ ${text ? `${hasKorean ? "$selection.Font.Name = 'Malgun Gothic'" : ''}
679
+ $selection.TypeText('${escapedText}')
680
+ $selection.MoveLeft(1, ${originalTextLength}, 1)` : ''}
681
+ $doc.Bookmarks.Add('${escapedName}', $selection.Range)
682
+ @{ success = $true; message = "Bookmark '${escapedName}' added" } | ConvertTo-Json -Compress
683
+ `);
684
+ }
685
+
686
+ async wordGetBookmarks(): Promise<OfficeResponse> {
687
+ return this.executePowerShell(`
688
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
689
+ $doc = $word.ActiveDocument
690
+ $bookmarks = @()
691
+ foreach ($bm in $doc.Bookmarks) {
692
+ $bookmarks += @{
693
+ name = $bm.Name
694
+ start = $bm.Range.Start
695
+ end = $bm.Range.End
696
+ text = $bm.Range.Text
697
+ }
698
+ }
699
+ @{ success = $true; bookmarks = $bookmarks } | ConvertTo-Json -Compress -Depth 5
700
+ `);
701
+ }
702
+
703
+ async wordDeleteBookmark(name: string): Promise<OfficeResponse> {
704
+ const escapedName = name.replace(/'/g, "''");
705
+ return this.executePowerShell(`
706
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
707
+ $doc = $word.ActiveDocument
708
+ if ($doc.Bookmarks.Exists('${escapedName}')) {
709
+ $doc.Bookmarks('${escapedName}').Delete()
710
+ @{ success = $true; message = "Bookmark '${escapedName}' deleted" } | ConvertTo-Json -Compress
711
+ } else {
712
+ @{ success = $false; error = "Bookmark '${escapedName}' not found" } | ConvertTo-Json -Compress
713
+ }
714
+ `);
715
+ }
716
+
717
+ async wordGotoBookmark(name: string): Promise<OfficeResponse> {
718
+ const escapedName = name.replace(/'/g, "''");
719
+ return this.executePowerShell(`
720
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
721
+ $doc = $word.ActiveDocument
722
+ if ($doc.Bookmarks.Exists('${escapedName}')) {
723
+ $doc.Bookmarks('${escapedName}').Select()
724
+ @{ success = $true; message = "Moved to bookmark '${escapedName}'" } | ConvertTo-Json -Compress
725
+ } else {
726
+ @{ success = $false; error = "Bookmark '${escapedName}' not found" } | ConvertTo-Json -Compress
727
+ }
728
+ `);
729
+ }
730
+
731
+ // -------------------------------------------------------------------------
732
+ // Word Comments
733
+ // -------------------------------------------------------------------------
734
+
735
+ async wordAddComment(commentText: string, author?: string): Promise<OfficeResponse> {
736
+ const escapedText = commentText.replace(/'/g, "''");
737
+ const escapedAuthor = author?.replace(/'/g, "''") || '';
738
+
739
+ return this.executePowerShell(`
740
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
741
+ $doc = $word.ActiveDocument
742
+ $selection = $word.Selection
743
+ $comment = $doc.Comments.Add($selection.Range, '${escapedText}')
744
+ ${escapedAuthor ? `$comment.Author = '${escapedAuthor}'` : ''}
745
+ @{ success = $true; message = "Comment added" } | ConvertTo-Json -Compress
746
+ `);
747
+ }
748
+
749
+ async wordGetComments(): Promise<OfficeResponse> {
750
+ return this.executePowerShell(`
751
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
752
+ $doc = $word.ActiveDocument
753
+ $comments = @()
754
+ foreach ($c in $doc.Comments) {
755
+ $comments += @{
756
+ index = $c.Index
757
+ author = $c.Author
758
+ text = $c.Range.Text
759
+ date = $c.Date.ToString("yyyy-MM-dd HH:mm:ss")
760
+ scope = $c.Scope.Text
761
+ }
762
+ }
763
+ @{ success = $true; comments = $comments; count = $doc.Comments.Count } | ConvertTo-Json -Compress -Depth 5
764
+ `);
765
+ }
766
+
767
+ async wordDeleteComment(index: number): Promise<OfficeResponse> {
768
+ return this.executePowerShell(`
769
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
770
+ $doc = $word.ActiveDocument
771
+ if (${index} -le $doc.Comments.Count) {
772
+ $doc.Comments(${index}).Delete()
773
+ @{ success = $true; message = "Comment ${index} deleted" } | ConvertTo-Json -Compress
774
+ } else {
775
+ @{ success = $false; error = "Comment index ${index} out of range" } | ConvertTo-Json -Compress
776
+ }
777
+ `);
778
+ }
779
+
780
+ async wordDeleteAllComments(): Promise<OfficeResponse> {
781
+ return this.executePowerShell(`
782
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
783
+ $doc = $word.ActiveDocument
784
+ $count = $doc.Comments.Count
785
+ while ($doc.Comments.Count -gt 0) {
786
+ $doc.Comments(1).Delete()
787
+ }
788
+ @{ success = $true; message = "Deleted $count comments" } | ConvertTo-Json -Compress
789
+ `);
790
+ }
791
+
792
+ // -------------------------------------------------------------------------
793
+ // Word Lists
794
+ // -------------------------------------------------------------------------
795
+
796
+ async wordCreateBulletList(items: string[]): Promise<OfficeResponse> {
797
+ // TEXT FIRST, FONT AFTER pattern (Microsoft recommended for Korean)
798
+ const itemsScript = items.map(item => {
799
+ const escaped = item.replace(/'/g, "''");
800
+ const hasKorean = /[가-힣ㄱ-ㅎㅏ-ㅣ]/.test(item);
801
+ // Text first, then font after
802
+ return `$selection.TypeText('${escaped}')
803
+ ${hasKorean ? "$selection.Font.Name = 'Malgun Gothic'" : ''}
804
+ $selection.TypeParagraph()`;
805
+ }).join('\n');
806
+
807
+ return this.executePowerShell(`
808
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
809
+ $selection = $word.Selection
810
+ $selection.Range.ListFormat.ApplyBulletDefault()
811
+ ${itemsScript}
812
+ $selection.Range.ListFormat.RemoveNumbers()
813
+ @{ success = $true; message = "Bullet list created with ${items.length} items" } | ConvertTo-Json -Compress
814
+ `);
815
+ }
816
+
817
+ async wordCreateNumberedList(items: string[]): Promise<OfficeResponse> {
818
+ // TEXT FIRST, FONT AFTER pattern (Microsoft recommended for Korean)
819
+ const itemsScript = items.map(item => {
820
+ const escaped = item.replace(/'/g, "''");
821
+ const hasKorean = /[가-힣ㄱ-ㅎㅏ-ㅣ]/.test(item);
822
+ // Text first, then font after
823
+ return `$selection.TypeText('${escaped}')
824
+ ${hasKorean ? "$selection.Font.Name = 'Malgun Gothic'" : ''}
825
+ $selection.TypeParagraph()`;
826
+ }).join('\n');
827
+
828
+ return this.executePowerShell(`
829
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
830
+ $selection = $word.Selection
831
+ $selection.Range.ListFormat.ApplyNumberDefault()
832
+ ${itemsScript}
833
+ $selection.Range.ListFormat.RemoveNumbers()
834
+ @{ success = $true; message = "Numbered list created with ${items.length} items" } | ConvertTo-Json -Compress
835
+ `);
836
+ }
837
+
838
+ // -------------------------------------------------------------------------
839
+ // Word Page Setup
840
+ // -------------------------------------------------------------------------
841
+
842
+ async wordSetPageMargins(options: {
843
+ top?: number;
844
+ bottom?: number;
845
+ left?: number;
846
+ right?: number;
847
+ }): Promise<OfficeResponse> {
848
+ // Points (1 inch = 72 points)
849
+ const commands: string[] = [];
850
+ if (options.top !== undefined) commands.push(`$pageSetup.TopMargin = ${options.top}`);
851
+ if (options.bottom !== undefined) commands.push(`$pageSetup.BottomMargin = ${options.bottom}`);
852
+ if (options.left !== undefined) commands.push(`$pageSetup.LeftMargin = ${options.left}`);
853
+ if (options.right !== undefined) commands.push(`$pageSetup.RightMargin = ${options.right}`);
854
+
855
+ return this.executePowerShell(`
856
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
857
+ $doc = $word.ActiveDocument
858
+ $pageSetup = $doc.PageSetup
859
+ ${commands.join('\n')}
860
+ @{ success = $true; message = "Page margins updated" } | ConvertTo-Json -Compress
861
+ `);
862
+ }
863
+
864
+ async wordSetPageOrientation(orientation: 'portrait' | 'landscape'): Promise<OfficeResponse> {
865
+ // wdOrientPortrait=0, wdOrientLandscape=1
866
+ const value = orientation === 'landscape' ? 1 : 0;
867
+ return this.executePowerShell(`
868
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
869
+ $doc = $word.ActiveDocument
870
+ $doc.PageSetup.Orientation = ${value}
871
+ @{ success = $true; message = "Page orientation set to ${orientation}" } | ConvertTo-Json -Compress
872
+ `);
873
+ }
874
+
875
+ async wordSetPageSize(size: 'A4' | 'Letter' | 'Legal' | 'A3' | 'B5' | 'custom', width?: number, height?: number): Promise<OfficeResponse> {
876
+ // wdPaperA4=7, wdPaperLetter=2, wdPaperLegal=4, wdPaperA3=6, wdPaperB5=13
877
+ const sizeMap: Record<string, number> = {
878
+ A4: 7,
879
+ Letter: 2,
880
+ Legal: 4,
881
+ A3: 6,
882
+ B5: 13,
883
+ };
884
+
885
+ if (size === 'custom' && width && height) {
886
+ return this.executePowerShell(`
887
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
888
+ $doc = $word.ActiveDocument
889
+ $doc.PageSetup.PageWidth = ${width}
890
+ $doc.PageSetup.PageHeight = ${height}
891
+ @{ success = $true; message = "Page size set to custom (${width}x${height})" } | ConvertTo-Json -Compress
892
+ `);
893
+ }
894
+
895
+ const paperSize = sizeMap[size] ?? 7;
896
+ return this.executePowerShell(`
897
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
898
+ $doc = $word.ActiveDocument
899
+ $doc.PageSetup.PaperSize = ${paperSize}
900
+ @{ success = $true; message = "Page size set to ${size}" } | ConvertTo-Json -Compress
901
+ `);
902
+ }
903
+
904
+ // -------------------------------------------------------------------------
905
+ // Word Watermark
906
+ // -------------------------------------------------------------------------
907
+
908
+ async wordAddWatermark(text: string, options?: {
909
+ fontName?: string;
910
+ fontSize?: number;
911
+ color?: string;
912
+ semitransparent?: boolean;
913
+ }): Promise<OfficeResponse> {
914
+ const escapedText = text.replace(/'/g, "''");
915
+ const fontName = options?.fontName?.replace(/'/g, "''") || 'Arial';
916
+ const fontSize = options?.fontSize || 72;
917
+ const colorValue = options?.color ? (() => {
918
+ const rgb = this.hexToRgb(options.color);
919
+ return rgb ? rgb.r + rgb.g * 256 + rgb.b * 65536 : 12632256; // default light gray
920
+ })() : 12632256;
921
+ const semitransparent = options?.semitransparent !== false ? '0.5' : '0';
922
+
923
+ return this.executePowerShell(`
924
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
925
+ $doc = $word.ActiveDocument
926
+
927
+ # Store original view and switch to Print Layout to access headers
928
+ $originalView = $word.ActiveWindow.View.Type
929
+ $word.ActiveWindow.View.Type = 3 # wdPrintView
930
+
931
+ try {
932
+ # Add watermark to header
933
+ $section = $doc.Sections(1)
934
+ $header = $section.Headers(1) # wdHeaderFooterPrimary = 1
935
+
936
+ # Create text effect shape (without Select to avoid view access issues)
937
+ $shape = $header.Shapes.AddTextEffect(0, '${escapedText}', '${fontName}', ${fontSize}, 0, 0, 0, 0)
938
+ $shape.Name = "PowerPlusWaterMarkObject"
939
+ $shape.TextEffect.NormalizedHeight = 0
940
+ $shape.Line.Visible = 0
941
+ $shape.Fill.Visible = -1
942
+ $shape.Fill.Solid()
943
+ $shape.Fill.ForeColor.RGB = ${colorValue}
944
+ $shape.Fill.Transparency = ${semitransparent}
945
+ $shape.Rotation = 315
946
+ $shape.LockAspectRatio = -1
947
+ $shape.Height = 100
948
+ $shape.Width = 350
949
+ $shape.Left = -999995 # wdShapeCenter
950
+ $shape.Top = -999995 # wdShapeCenter
951
+ $shape.WrapFormat.AllowOverlap = -1
952
+ $shape.WrapFormat.Type = 3 # wdWrapBehind
953
+
954
+ @{ success = $true; message = "Watermark added" } | ConvertTo-Json -Compress
955
+ } finally {
956
+ # Restore original view
957
+ $word.ActiveWindow.View.Type = $originalView
958
+ }
959
+ `);
960
+ }
961
+
962
+ async wordRemoveWatermark(): Promise<OfficeResponse> {
963
+ return this.executePowerShell(`
964
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
965
+ $doc = $word.ActiveDocument
966
+
967
+ # Switch to Print Layout view to access headers (wdPrintView = 3)
968
+ $word.ActiveWindow.View.Type = 3
969
+
970
+ foreach ($section in $doc.Sections) {
971
+ $header = $section.Headers(1)
972
+ foreach ($shape in $header.Shapes) {
973
+ if ($shape.Name -like "*WaterMark*") {
974
+ $shape.Delete()
975
+ }
976
+ }
977
+ }
978
+ @{ success = $true; message = "Watermark removed" } | ConvertTo-Json -Compress
979
+ `);
980
+ }
981
+
982
+ // -------------------------------------------------------------------------
983
+ // Word Textbox & Shapes
984
+ // -------------------------------------------------------------------------
985
+
986
+ async wordAddTextbox(
987
+ text: string,
988
+ left: number,
989
+ top: number,
990
+ width: number,
991
+ height: number,
992
+ options?: { fontName?: string; fontSize?: number; borderColor?: string; fillColor?: string }
993
+ ): Promise<OfficeResponse> {
994
+ const escapedText = text.replace(/'/g, "''");
995
+ const hasKorean = /[가-힣ㄱ-ㅎㅏ-ㅣ]/.test(text);
996
+ let fontName = options?.fontName?.replace(/'/g, "''") || '';
997
+ if (!fontName && hasKorean) {
998
+ fontName = 'Malgun Gothic';
999
+ }
1000
+
1001
+ const commands: string[] = [];
1002
+ if (fontName) commands.push(`$shape.TextFrame.TextRange.Font.Name = '${fontName}'`);
1003
+ if (options?.fontSize) commands.push(`$shape.TextFrame.TextRange.Font.Size = ${options.fontSize}`);
1004
+ if (options?.borderColor) {
1005
+ const rgb = this.hexToRgb(options.borderColor);
1006
+ if (rgb) {
1007
+ commands.push('$shape.Line.Visible = -1');
1008
+ commands.push(`$shape.Line.ForeColor.RGB = ${rgb.r + rgb.g * 256 + rgb.b * 65536}`);
1009
+ }
1010
+ }
1011
+ if (options?.fillColor) {
1012
+ const rgb = this.hexToRgb(options.fillColor);
1013
+ if (rgb) {
1014
+ commands.push('$shape.Fill.Visible = -1');
1015
+ commands.push(`$shape.Fill.ForeColor.RGB = ${rgb.r + rgb.g * 256 + rgb.b * 65536}`);
1016
+ }
1017
+ } else {
1018
+ commands.push('$shape.Fill.Visible = 0');
1019
+ }
1020
+
1021
+ // TEXT FIRST, FONT AFTER pattern (Microsoft recommended for Korean)
1022
+ // Also handle \n line breaks
1023
+ return this.executePowerShell(`
1024
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
1025
+ $doc = $word.ActiveDocument
1026
+ $shape = $doc.Shapes.AddTextbox(1, ${left}, ${top}, ${width}, ${height})
1027
+ $textContent = '${escapedText}' -replace '\\\\n', [char]10 -replace '\\n', [char]10
1028
+ $shape.TextFrame.TextRange.Text = $textContent
1029
+ ${fontName ? `$shape.TextFrame.TextRange.Font.Name = '${fontName}'` : ''}
1030
+ ${commands.filter(c => !c.includes('Font.Name')).join('\n')}
1031
+ @{ success = $true; message = "Textbox added"; shape_name = $shape.Name } | ConvertTo-Json -Compress
1032
+ `);
1033
+ }
1034
+
1035
+ async wordAddShape(
1036
+ shapeType: 'rectangle' | 'oval' | 'roundedRectangle' | 'triangle' | 'diamond' | 'arrow' | 'line',
1037
+ left: number,
1038
+ top: number,
1039
+ width: number,
1040
+ height: number,
1041
+ options?: { fillColor?: string; lineColor?: string; lineWeight?: number }
1042
+ ): Promise<OfficeResponse> {
1043
+ // Line is special - use AddLine instead of AddShape
1044
+ if (shapeType === 'line') {
1045
+ return this.wordAddLine(left, top, left + width, top + height, options);
1046
+ }
1047
+
1048
+ // msoShapeRectangle=1, msoShapeOval=9, msoShapeRoundedRectangle=5,
1049
+ // msoShapeIsoscelesTriangle=7, msoShapeDiamond=4, msoShapeRightArrow=33
1050
+ const shapeMap: Record<string, number> = {
1051
+ rectangle: 1,
1052
+ oval: 9,
1053
+ roundedRectangle: 5,
1054
+ triangle: 7,
1055
+ diamond: 4,
1056
+ arrow: 33,
1057
+ };
1058
+ const shapeTypeValue = shapeMap[shapeType] ?? 1;
1059
+
1060
+ const commands: string[] = [];
1061
+ if (options?.fillColor) {
1062
+ const rgb = this.hexToRgb(options.fillColor);
1063
+ if (rgb) {
1064
+ commands.push('$shape.Fill.Visible = -1');
1065
+ commands.push('$shape.Fill.Solid()');
1066
+ commands.push(`$shape.Fill.ForeColor.RGB = ${rgb.r + rgb.g * 256 + rgb.b * 65536}`);
1067
+ }
1068
+ }
1069
+ if (options?.lineColor) {
1070
+ const rgb = this.hexToRgb(options.lineColor);
1071
+ if (rgb) {
1072
+ commands.push('$shape.Line.Visible = -1');
1073
+ commands.push(`$shape.Line.ForeColor.RGB = ${rgb.r + rgb.g * 256 + rgb.b * 65536}`);
1074
+ }
1075
+ }
1076
+ if (options?.lineWeight) {
1077
+ commands.push(`$shape.Line.Weight = ${options.lineWeight}`);
1078
+ }
1079
+
1080
+ return this.executePowerShell(`
1081
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
1082
+ $doc = $word.ActiveDocument
1083
+ $shape = $doc.Shapes.AddShape(${shapeTypeValue}, ${left}, ${top}, ${width}, ${height})
1084
+ ${commands.join('\n')}
1085
+ @{ success = $true; message = "Shape added"; shape_name = $shape.Name } | ConvertTo-Json -Compress
1086
+ `);
1087
+ }
1088
+
1089
+ /**
1090
+ * Add a line shape to the document
1091
+ */
1092
+ private async wordAddLine(
1093
+ startX: number,
1094
+ startY: number,
1095
+ endX: number,
1096
+ endY: number,
1097
+ options?: { lineColor?: string; lineWeight?: number }
1098
+ ): Promise<OfficeResponse> {
1099
+ const commands: string[] = [];
1100
+ if (options?.lineColor) {
1101
+ const rgb = this.hexToRgb(options.lineColor);
1102
+ if (rgb) {
1103
+ commands.push('$shape.Line.Visible = -1');
1104
+ commands.push(`$shape.Line.ForeColor.RGB = ${rgb.r + rgb.g * 256 + rgb.b * 65536}`);
1105
+ }
1106
+ }
1107
+ if (options?.lineWeight) {
1108
+ commands.push(`$shape.Line.Weight = ${options.lineWeight}`);
1109
+ }
1110
+
1111
+ return this.executePowerShell(`
1112
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
1113
+ $doc = $word.ActiveDocument
1114
+ $shape = $doc.Shapes.AddLine(${startX}, ${startY}, ${endX}, ${endY})
1115
+ ${commands.join('\n')}
1116
+ @{ success = $true; message = "Line added"; shape_name = $shape.Name } | ConvertTo-Json -Compress
1117
+ `);
1118
+ }
1119
+
1120
+ // -------------------------------------------------------------------------
1121
+ // Word Document Info
1122
+ // -------------------------------------------------------------------------
1123
+
1124
+ async wordGetDocumentInfo(): Promise<OfficeResponse> {
1125
+ return this.executePowerShell(`
1126
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
1127
+ $doc = $word.ActiveDocument
1128
+ $stats = $doc.ComputeStatistics(0) # wdStatisticWords
1129
+
1130
+ @{
1131
+ success = $true
1132
+ name = $doc.Name
1133
+ path = $doc.FullName
1134
+ pages = $doc.ComputeStatistics(2) # wdStatisticPages
1135
+ words = $doc.ComputeStatistics(0) # wdStatisticWords
1136
+ characters = $doc.ComputeStatistics(3) # wdStatisticCharacters
1137
+ characters_with_spaces = $doc.ComputeStatistics(5) # wdStatisticCharactersWithSpaces
1138
+ paragraphs = $doc.ComputeStatistics(4) # wdStatisticParagraphs
1139
+ lines = $doc.ComputeStatistics(1) # wdStatisticLines
1140
+ saved = $doc.Saved
1141
+ read_only = $doc.ReadOnly
1142
+ } | ConvertTo-Json -Compress
1143
+ `);
1144
+ }
1145
+
1146
+ // -------------------------------------------------------------------------
1147
+ // Word Columns
1148
+ // -------------------------------------------------------------------------
1149
+
1150
+ async wordSetColumns(count: number, spacing?: number): Promise<OfficeResponse> {
1151
+ // spacing is the gap between columns in points (1 inch = 72 points)
1152
+ const spacingScript = spacing !== undefined ? `$pageSetup.TextColumns.Spacing = ${spacing}` : '';
1153
+ return this.executePowerShell(`
1154
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
1155
+ $doc = $word.ActiveDocument
1156
+ $pageSetup = $doc.PageSetup
1157
+ $pageSetup.TextColumns.SetCount(${count})
1158
+ ${spacingScript}
1159
+ @{ success = $true; message = "Columns set to ${count}${spacing !== undefined ? ` with spacing ${spacing}pt` : ''}" } | ConvertTo-Json -Compress
1160
+ `);
1161
+ }
1162
+
1163
+ // -------------------------------------------------------------------------
1164
+ // Word Undo/Redo
1165
+ // -------------------------------------------------------------------------
1166
+
1167
+ async wordUndo(times: number = 1): Promise<OfficeResponse> {
1168
+ return this.executePowerShell(`
1169
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
1170
+ $doc = $word.ActiveDocument
1171
+ for ($i = 0; $i -lt ${times}; $i++) {
1172
+ $doc.Undo()
1173
+ }
1174
+ @{ success = $true; message = "Undo performed ${times} time(s)" } | ConvertTo-Json -Compress
1175
+ `);
1176
+ }
1177
+
1178
+ async wordRedo(times: number = 1): Promise<OfficeResponse> {
1179
+ return this.executePowerShell(`
1180
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
1181
+ $doc = $word.ActiveDocument
1182
+ for ($i = 0; $i -lt ${times}; $i++) {
1183
+ $doc.Redo()
1184
+ }
1185
+ @{ success = $true; message = "Redo performed ${times} time(s)" } | ConvertTo-Json -Compress
1186
+ `);
1187
+ }
1188
+
1189
+ // -------------------------------------------------------------------------
1190
+ // Word Selection
1191
+ // -------------------------------------------------------------------------
1192
+
1193
+ async wordGetSelectedText(): Promise<OfficeResponse> {
1194
+ return this.executePowerShell(`
1195
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
1196
+ $selection = $word.Selection
1197
+ @{
1198
+ success = $true
1199
+ text = $selection.Text
1200
+ start = $selection.Start
1201
+ end = $selection.End
1202
+ type = $selection.Type # 0=none, 1=normal, 2=IP (insertion point)
1203
+ } | ConvertTo-Json -Compress
1204
+ `);
1205
+ }
1206
+
1207
+ /**
1208
+ * Select a range of text by start and end positions
1209
+ */
1210
+ async wordSelectRange(start: number, end: number): Promise<OfficeResponse> {
1211
+ return this.executePowerShell(`
1212
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
1213
+ $doc = $word.ActiveDocument
1214
+ $range = $doc.Range(${start}, ${end})
1215
+ $range.Select()
1216
+ @{ success = $true; message = "Selected range from ${start} to ${end}"; text = $range.Text } | ConvertTo-Json -Compress
1217
+ `);
1218
+ }
1219
+
1220
+ /**
1221
+ * Move cursor by character, word, line, or paragraph
1222
+ */
1223
+ async wordMoveCursor(
1224
+ unit: 'character' | 'word' | 'line' | 'paragraph',
1225
+ count: number,
1226
+ extend: boolean = false
1227
+ ): Promise<OfficeResponse> {
1228
+ // wdCharacter=1, wdWord=2, wdLine=5, wdParagraph=4
1229
+ const unitMap: Record<string, number> = { character: 1, word: 2, line: 5, paragraph: 4 };
1230
+ const unitValue = unitMap[unit] ?? 1;
1231
+ const direction = count >= 0 ? 'MoveRight' : 'MoveLeft';
1232
+ const absCount = Math.abs(count);
1233
+ const extendMode = extend ? '1' : '0'; // wdExtend=1, wdMove=0
1234
+
1235
+ return this.executePowerShell(`
1236
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
1237
+ $selection = $word.Selection
1238
+ $selection.${direction}(${unitValue}, ${absCount}, ${extendMode})
1239
+ @{
1240
+ success = $true
1241
+ message = "Cursor moved ${count} ${unit}(s)"
1242
+ position = $selection.Start
1243
+ end_position = $selection.End
1244
+ } | ConvertTo-Json -Compress
1245
+ `);
1246
+ }
1247
+
1248
+ /**
1249
+ * Move cursor to start or end of document
1250
+ */
1251
+ async wordMoveCursorTo(position: 'start' | 'end'): Promise<OfficeResponse> {
1252
+ const method = position === 'start' ? 'HomeKey' : 'EndKey';
1253
+ return this.executePowerShell(`
1254
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
1255
+ $selection = $word.Selection
1256
+ $selection.${method}(6) # wdStory = 6
1257
+ @{ success = $true; message = "Cursor moved to ${position} of document"; position = $selection.Start } | ConvertTo-Json -Compress
1258
+ `);
1259
+ }
1260
+
1261
+ // -------------------------------------------------------------------------
1262
+ // Word Table Row/Column Operations
1263
+ // -------------------------------------------------------------------------
1264
+
1265
+ /**
1266
+ * Add a row to a table
1267
+ */
1268
+ async wordAddTableRow(tableIndex: number, position?: number): Promise<OfficeResponse> {
1269
+ const positionScript = position !== undefined
1270
+ ? `$row = $table.Rows(${position})\n$table.Rows.Add($row)`
1271
+ : '$table.Rows.Add()';
1272
+ return this.executePowerShell(`
1273
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
1274
+ $doc = $word.ActiveDocument
1275
+ $table = $doc.Tables(${tableIndex})
1276
+ ${positionScript}
1277
+ @{ success = $true; message = "Row added to table ${tableIndex}"; total_rows = $table.Rows.Count } | ConvertTo-Json -Compress
1278
+ `);
1279
+ }
1280
+
1281
+ /**
1282
+ * Add a column to a table
1283
+ */
1284
+ async wordAddTableColumn(tableIndex: number, position?: number): Promise<OfficeResponse> {
1285
+ const positionScript = position !== undefined
1286
+ ? `$col = $table.Columns(${position})\n$table.Columns.Add($col)`
1287
+ : '$table.Columns.Add()';
1288
+ return this.executePowerShell(`
1289
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
1290
+ $doc = $word.ActiveDocument
1291
+ $table = $doc.Tables(${tableIndex})
1292
+ ${positionScript}
1293
+ @{ success = $true; message = "Column added to table ${tableIndex}"; total_columns = $table.Columns.Count } | ConvertTo-Json -Compress
1294
+ `);
1295
+ }
1296
+
1297
+ /**
1298
+ * Delete a row from a table
1299
+ */
1300
+ async wordDeleteTableRow(tableIndex: number, rowIndex: number): Promise<OfficeResponse> {
1301
+ return this.executePowerShell(`
1302
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
1303
+ $doc = $word.ActiveDocument
1304
+ $table = $doc.Tables(${tableIndex})
1305
+ if (${rowIndex} -le $table.Rows.Count) {
1306
+ $table.Rows(${rowIndex}).Delete()
1307
+ @{ success = $true; message = "Row ${rowIndex} deleted from table ${tableIndex}"; remaining_rows = $table.Rows.Count } | ConvertTo-Json -Compress
1308
+ } else {
1309
+ @{ success = $false; error = "Row index ${rowIndex} out of range (table has $($table.Rows.Count) rows)" } | ConvertTo-Json -Compress
1310
+ }
1311
+ `);
1312
+ }
1313
+
1314
+ /**
1315
+ * Delete a column from a table
1316
+ */
1317
+ async wordDeleteTableColumn(tableIndex: number, colIndex: number): Promise<OfficeResponse> {
1318
+ return this.executePowerShell(`
1319
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
1320
+ $doc = $word.ActiveDocument
1321
+ $table = $doc.Tables(${tableIndex})
1322
+ if (${colIndex} -le $table.Columns.Count) {
1323
+ $table.Columns(${colIndex}).Delete()
1324
+ @{ success = $true; message = "Column ${colIndex} deleted from table ${tableIndex}"; remaining_columns = $table.Columns.Count } | ConvertTo-Json -Compress
1325
+ } else {
1326
+ @{ success = $false; error = "Column index ${colIndex} out of range (table has $($table.Columns.Count) columns)" } | ConvertTo-Json -Compress
1327
+ }
1328
+ `);
1329
+ }
1330
+
1331
+ /**
1332
+ * Get table information
1333
+ */
1334
+ async wordGetTableInfo(tableIndex: number): Promise<OfficeResponse> {
1335
+ return this.executePowerShell(`
1336
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
1337
+ $doc = $word.ActiveDocument
1338
+ if (${tableIndex} -le $doc.Tables.Count) {
1339
+ $table = $doc.Tables(${tableIndex})
1340
+ @{
1341
+ success = $true
1342
+ table_index = ${tableIndex}
1343
+ rows = $table.Rows.Count
1344
+ columns = $table.Columns.Count
1345
+ style = $table.Style
1346
+ } | ConvertTo-Json -Compress
1347
+ } else {
1348
+ @{ success = $false; error = "Table index ${tableIndex} out of range (document has $($doc.Tables.Count) tables)" } | ConvertTo-Json -Compress
1349
+ }
1350
+ `);
1351
+ }
1352
+
1353
+ // -------------------------------------------------------------------------
1354
+ // Word Track Changes
1355
+ // -------------------------------------------------------------------------
1356
+
1357
+ /**
1358
+ * Enable or disable track changes
1359
+ */
1360
+ async wordSetTrackChanges(enabled: boolean): Promise<OfficeResponse> {
1361
+ return this.executePowerShell(`
1362
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
1363
+ $doc = $word.ActiveDocument
1364
+ $doc.TrackRevisions = ${enabled ? '$true' : '$false'}
1365
+ @{ success = $true; message = "Track changes ${enabled ? 'enabled' : 'disabled'}"; track_revisions = $doc.TrackRevisions } | ConvertTo-Json -Compress
1366
+ `);
1367
+ }
1368
+
1369
+ /**
1370
+ * Get track changes status
1371
+ */
1372
+ async wordGetTrackChanges(): Promise<OfficeResponse> {
1373
+ return this.executePowerShell(`
1374
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
1375
+ $doc = $word.ActiveDocument
1376
+ $revisions = @()
1377
+ foreach ($rev in $doc.Revisions) {
1378
+ $revisions += @{
1379
+ index = $rev.Index
1380
+ author = $rev.Author
1381
+ type = $rev.Type
1382
+ text = $rev.Range.Text
1383
+ date = $rev.Date.ToString("yyyy-MM-dd HH:mm:ss")
1384
+ }
1385
+ }
1386
+ @{
1387
+ success = $true
1388
+ track_revisions = $doc.TrackRevisions
1389
+ revision_count = $doc.Revisions.Count
1390
+ revisions = $revisions
1391
+ } | ConvertTo-Json -Compress -Depth 5
1392
+ `);
1393
+ }
1394
+
1395
+ /**
1396
+ * Accept all revisions
1397
+ */
1398
+ async wordAcceptAllRevisions(): Promise<OfficeResponse> {
1399
+ return this.executePowerShell(`
1400
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
1401
+ $doc = $word.ActiveDocument
1402
+ $count = $doc.Revisions.Count
1403
+ $doc.AcceptAllRevisions()
1404
+ @{ success = $true; message = "Accepted $count revisions" } | ConvertTo-Json -Compress
1405
+ `);
1406
+ }
1407
+
1408
+ /**
1409
+ * Reject all revisions
1410
+ */
1411
+ async wordRejectAllRevisions(): Promise<OfficeResponse> {
1412
+ return this.executePowerShell(`
1413
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
1414
+ $doc = $word.ActiveDocument
1415
+ $count = $doc.Revisions.Count
1416
+ $doc.RejectAllRevisions()
1417
+ @{ success = $true; message = "Rejected $count revisions" } | ConvertTo-Json -Compress
1418
+ `);
1419
+ }
1420
+
1421
+ /**
1422
+ * Accept or reject a specific revision
1423
+ */
1424
+ async wordHandleRevision(index: number, accept: boolean): Promise<OfficeResponse> {
1425
+ const method = accept ? 'Accept' : 'Reject';
1426
+ return this.executePowerShell(`
1427
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
1428
+ $doc = $word.ActiveDocument
1429
+ if (${index} -le $doc.Revisions.Count) {
1430
+ $doc.Revisions(${index}).${method}()
1431
+ @{ success = $true; message = "Revision ${index} ${accept ? 'accepted' : 'rejected'}" } | ConvertTo-Json -Compress
1432
+ } else {
1433
+ @{ success = $false; error = "Revision index ${index} out of range" } | ConvertTo-Json -Compress
1434
+ }
1435
+ `);
1436
+ }
1437
+
1438
+ // -------------------------------------------------------------------------
1439
+ // Word Table of Contents
1440
+ // -------------------------------------------------------------------------
1441
+
1442
+ /**
1443
+ * Insert a table of contents
1444
+ */
1445
+ async wordInsertTOC(options?: {
1446
+ useHeadingStyles?: boolean;
1447
+ upperHeadingLevel?: number;
1448
+ lowerHeadingLevel?: number;
1449
+ useHyperlinks?: boolean;
1450
+ }): Promise<OfficeResponse> {
1451
+ const useHeadingStyles = options?.useHeadingStyles !== false ? '$true' : '$false';
1452
+ const upperLevel = options?.upperHeadingLevel ?? 1;
1453
+ const lowerLevel = options?.lowerHeadingLevel ?? 3;
1454
+ const useHyperlinks = options?.useHyperlinks !== false ? '$true' : '$false';
1455
+
1456
+ return this.executePowerShell(`
1457
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
1458
+ $doc = $word.ActiveDocument
1459
+ $selection = $word.Selection
1460
+ $range = $selection.Range
1461
+ $toc = $doc.TablesOfContents.Add($range, ${useHeadingStyles}, ${upperLevel}, ${lowerLevel}, $false, "", $true, ${useHyperlinks})
1462
+ @{ success = $true; message = "Table of contents inserted (Heading ${upperLevel}-${lowerLevel})" } | ConvertTo-Json -Compress
1463
+ `);
1464
+ }
1465
+
1466
+ /**
1467
+ * Update all tables of contents
1468
+ */
1469
+ async wordUpdateTOC(): Promise<OfficeResponse> {
1470
+ return this.executePowerShell(`
1471
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
1472
+ $doc = $word.ActiveDocument
1473
+ $count = $doc.TablesOfContents.Count
1474
+ foreach ($toc in $doc.TablesOfContents) {
1475
+ $toc.Update()
1476
+ }
1477
+ @{ success = $true; message = "Updated $count table(s) of contents" } | ConvertTo-Json -Compress
1478
+ `);
1479
+ }
1480
+
1481
+ /**
1482
+ * Delete all tables of contents
1483
+ */
1484
+ async wordDeleteTOC(): Promise<OfficeResponse> {
1485
+ return this.executePowerShell(`
1486
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
1487
+ $doc = $word.ActiveDocument
1488
+ $count = $doc.TablesOfContents.Count
1489
+ while ($doc.TablesOfContents.Count -gt 0) {
1490
+ $doc.TablesOfContents(1).Delete()
1491
+ }
1492
+ @{ success = $true; message = "Deleted $count table(s) of contents" } | ConvertTo-Json -Compress
1493
+ `);
1494
+ }
1495
+
1496
+ // -------------------------------------------------------------------------
1497
+ // Word Footnotes & Endnotes
1498
+ // -------------------------------------------------------------------------
1499
+
1500
+ /**
1501
+ * Add a footnote at the current selection
1502
+ */
1503
+ async wordAddFootnote(text: string): Promise<OfficeResponse> {
1504
+ const hasKorean = /[가-힣ㄱ-ㅎㅏ-ㅣ]/.test(text);
1505
+ const base64Text = this.encodeTextForPowerShell(text);
1506
+ const decodeExpr = this.getPowerShellDecodeExpr(base64Text);
1507
+
1508
+ return this.executePowerShell(`
1509
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
1510
+ $doc = $word.ActiveDocument
1511
+ $selection = $word.Selection
1512
+ $footnote = $doc.Footnotes.Add($selection.Range)
1513
+ $footnote.Range.Text = ${decodeExpr}
1514
+ ${hasKorean ? "$footnote.Range.Font.Name = 'Malgun Gothic'" : ''}
1515
+ @{ success = $true; message = "Footnote added"; index = $footnote.Index } | ConvertTo-Json -Compress
1516
+ `);
1517
+ }
1518
+
1519
+ /**
1520
+ * Add an endnote at the current selection
1521
+ */
1522
+ async wordAddEndnote(text: string): Promise<OfficeResponse> {
1523
+ const hasKorean = /[가-힣ㄱ-ㅎㅏ-ㅣ]/.test(text);
1524
+ const base64Text = this.encodeTextForPowerShell(text);
1525
+ const decodeExpr = this.getPowerShellDecodeExpr(base64Text);
1526
+
1527
+ return this.executePowerShell(`
1528
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
1529
+ $doc = $word.ActiveDocument
1530
+ $selection = $word.Selection
1531
+ $endnote = $doc.Endnotes.Add($selection.Range)
1532
+ $endnote.Range.Text = ${decodeExpr}
1533
+ ${hasKorean ? "$endnote.Range.Font.Name = 'Malgun Gothic'" : ''}
1534
+ @{ success = $true; message = "Endnote added"; index = $endnote.Index } | ConvertTo-Json -Compress
1535
+ `);
1536
+ }
1537
+
1538
+ /**
1539
+ * Get all footnotes in the document
1540
+ */
1541
+ async wordGetFootnotes(): Promise<OfficeResponse> {
1542
+ return this.executePowerShell(`
1543
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
1544
+ $doc = $word.ActiveDocument
1545
+ $footnotes = @()
1546
+ foreach ($fn in $doc.Footnotes) {
1547
+ $footnotes += @{
1548
+ index = $fn.Index
1549
+ text = $fn.Range.Text
1550
+ reference_text = $fn.Reference.Text
1551
+ }
1552
+ }
1553
+ @{ success = $true; footnotes = $footnotes; count = $doc.Footnotes.Count } | ConvertTo-Json -Compress -Depth 5
1554
+ `);
1555
+ }
1556
+
1557
+ /**
1558
+ * Get all endnotes in the document
1559
+ */
1560
+ async wordGetEndnotes(): Promise<OfficeResponse> {
1561
+ return this.executePowerShell(`
1562
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
1563
+ $doc = $word.ActiveDocument
1564
+ $endnotes = @()
1565
+ foreach ($en in $doc.Endnotes) {
1566
+ $endnotes += @{
1567
+ index = $en.Index
1568
+ text = $en.Range.Text
1569
+ reference_text = $en.Reference.Text
1570
+ }
1571
+ }
1572
+ @{ success = $true; endnotes = $endnotes; count = $doc.Endnotes.Count } | ConvertTo-Json -Compress -Depth 5
1573
+ `);
1574
+ }
1575
+
1576
+ /**
1577
+ * Delete a footnote by index
1578
+ */
1579
+ async wordDeleteFootnote(index: number): Promise<OfficeResponse> {
1580
+ return this.executePowerShell(`
1581
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
1582
+ $doc = $word.ActiveDocument
1583
+ if (${index} -le $doc.Footnotes.Count) {
1584
+ $doc.Footnotes(${index}).Delete()
1585
+ @{ success = $true; message = "Footnote ${index} deleted" } | ConvertTo-Json -Compress
1586
+ } else {
1587
+ @{ success = $false; error = "Footnote index ${index} out of range" } | ConvertTo-Json -Compress
1588
+ }
1589
+ `);
1590
+ }
1591
+
1592
+ /**
1593
+ * Delete an endnote by index
1594
+ */
1595
+ async wordDeleteEndnote(index: number): Promise<OfficeResponse> {
1596
+ return this.executePowerShell(`
1597
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
1598
+ $doc = $word.ActiveDocument
1599
+ if (${index} -le $doc.Endnotes.Count) {
1600
+ $doc.Endnotes(${index}).Delete()
1601
+ @{ success = $true; message = "Endnote ${index} deleted" } | ConvertTo-Json -Compress
1602
+ } else {
1603
+ @{ success = $false; error = "Endnote index ${index} out of range" } | ConvertTo-Json -Compress
1604
+ }
1605
+ `);
1606
+ }
1607
+
1608
+ // -------------------------------------------------------------------------
1609
+ // Word Find (without replace)
1610
+ // -------------------------------------------------------------------------
1611
+
1612
+ /**
1613
+ * Find text and optionally select it
1614
+ */
1615
+ async wordFind(text: string, options?: {
1616
+ matchCase?: boolean;
1617
+ matchWholeWord?: boolean;
1618
+ selectFound?: boolean;
1619
+ }): Promise<OfficeResponse> {
1620
+ const base64Text = this.encodeTextForPowerShell(text);
1621
+ const decodeExpr = this.getPowerShellDecodeExpr(base64Text);
1622
+ const matchCase = options?.matchCase ? '$true' : '$false';
1623
+ const matchWholeWord = options?.matchWholeWord ? '$true' : '$false';
1624
+
1625
+ return this.executePowerShell(`
1626
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
1627
+ $doc = $word.ActiveDocument
1628
+ $selection = $word.Selection
1629
+ $selection.HomeKey(6) # Move to start of document
1630
+ $searchText = ${decodeExpr}
1631
+ $find = $selection.Find
1632
+ $find.ClearFormatting()
1633
+ $find.Text = $searchText
1634
+ $find.MatchCase = ${matchCase}
1635
+ $find.MatchWholeWord = ${matchWholeWord}
1636
+ $find.Forward = $true
1637
+ $find.Wrap = 0 # wdFindStop
1638
+
1639
+ $found = $find.Execute()
1640
+ if ($found) {
1641
+ @{
1642
+ success = $true
1643
+ found = $true
1644
+ start = $selection.Start
1645
+ end = $selection.End
1646
+ text = $selection.Text
1647
+ } | ConvertTo-Json -Compress
1648
+ } else {
1649
+ @{ success = $true; found = $false; message = "Text not found" } | ConvertTo-Json -Compress
1650
+ }
1651
+ `);
1652
+ }
1653
+
1654
+ /**
1655
+ * Find all occurrences of text
1656
+ */
1657
+ async wordFindAll(text: string, options?: {
1658
+ matchCase?: boolean;
1659
+ matchWholeWord?: boolean;
1660
+ }): Promise<OfficeResponse> {
1661
+ const base64Text = this.encodeTextForPowerShell(text);
1662
+ const decodeExpr = this.getPowerShellDecodeExpr(base64Text);
1663
+ const matchCase = options?.matchCase ? '$true' : '$false';
1664
+ const matchWholeWord = options?.matchWholeWord ? '$true' : '$false';
1665
+
1666
+ return this.executePowerShell(`
1667
+ $word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
1668
+ $doc = $word.ActiveDocument
1669
+ $range = $doc.Content
1670
+ $searchText = ${decodeExpr}
1671
+ $find = $range.Find
1672
+ $find.ClearFormatting()
1673
+ $find.Text = $searchText
1674
+ $find.MatchCase = ${matchCase}
1675
+ $find.MatchWholeWord = ${matchWholeWord}
1676
+ $find.Forward = $true
1677
+
1678
+ $matches = @()
1679
+ while ($find.Execute()) {
1680
+ $matches += @{
1681
+ start = $range.Start
1682
+ end = $range.End
1683
+ text = $range.Text
1684
+ }
1685
+ $range.Collapse(0) # wdCollapseEnd
1686
+ }
1687
+
1688
+ @{ success = $true; count = $matches.Count; matches = $matches } | ConvertTo-Json -Compress -Depth 5
1689
+ `);
1690
+ }
1691
+
1692
+ }
1693
+
1694
+ // Export singleton instance
1695
+ export const wordClient = new WordClient();
1696
+ export type { OfficeResponse, ScreenshotResponse };
1697
+