@waymakeros/cli 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (390) hide show
  1. package/README.md +158 -0
  2. package/dist/cli/cli.d.ts +7 -0
  3. package/dist/cli/cli.d.ts.map +1 -0
  4. package/dist/cli/cli.js +703 -0
  5. package/dist/cli/cli.js.map +1 -0
  6. package/dist/cli/commands/auth.d.ts +14 -0
  7. package/dist/cli/commands/auth.d.ts.map +1 -0
  8. package/dist/cli/commands/auth.js +507 -0
  9. package/dist/cli/commands/auth.js.map +1 -0
  10. package/dist/cli/commands/init.d.ts +13 -0
  11. package/dist/cli/commands/init.d.ts.map +1 -0
  12. package/dist/cli/commands/init.js +297 -0
  13. package/dist/cli/commands/init.js.map +1 -0
  14. package/dist/cli/commands/kanban.d.ts +12 -0
  15. package/dist/cli/commands/kanban.d.ts.map +1 -0
  16. package/dist/cli/commands/kanban.js +71 -0
  17. package/dist/cli/commands/kanban.js.map +1 -0
  18. package/dist/cli/commands/serve.d.ts +12 -0
  19. package/dist/cli/commands/serve.d.ts.map +1 -0
  20. package/dist/cli/commands/serve.js +170 -0
  21. package/dist/cli/commands/serve.js.map +1 -0
  22. package/dist/cli/commands/sync.d.ts +12 -0
  23. package/dist/cli/commands/sync.d.ts.map +1 -0
  24. package/dist/cli/commands/sync.js +222 -0
  25. package/dist/cli/commands/sync.js.map +1 -0
  26. package/dist/cli/daemon.d.ts +106 -0
  27. package/dist/cli/daemon.d.ts.map +1 -0
  28. package/dist/cli/daemon.js +393 -0
  29. package/dist/cli/daemon.js.map +1 -0
  30. package/dist/cli/index.d.ts +13 -0
  31. package/dist/cli/index.d.ts.map +1 -0
  32. package/dist/cli/index.js +90 -0
  33. package/dist/cli/index.js.map +1 -0
  34. package/dist/index.d.ts +10 -0
  35. package/dist/index.d.ts.map +1 -0
  36. package/dist/index.js +238 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/simple-server.d.ts +7 -0
  39. package/dist/simple-server.d.ts.map +1 -0
  40. package/dist/simple-server.js +157 -0
  41. package/dist/simple-server.js.map +1 -0
  42. package/dist/sync/commander-client.d.ts +161 -0
  43. package/dist/sync/commander-client.d.ts.map +1 -0
  44. package/dist/sync/commander-client.js +405 -0
  45. package/dist/sync/commander-client.js.map +1 -0
  46. package/dist/sync/config-manager.d.ts +48 -0
  47. package/dist/sync/config-manager.d.ts.map +1 -0
  48. package/dist/sync/config-manager.js +169 -0
  49. package/dist/sync/config-manager.js.map +1 -0
  50. package/dist/sync/file-watcher.d.ts +53 -0
  51. package/dist/sync/file-watcher.d.ts.map +1 -0
  52. package/dist/sync/file-watcher.js +228 -0
  53. package/dist/sync/file-watcher.js.map +1 -0
  54. package/dist/sync/folder-service.d.ts +110 -0
  55. package/dist/sync/folder-service.d.ts.map +1 -0
  56. package/dist/sync/folder-service.js +298 -0
  57. package/dist/sync/folder-service.js.map +1 -0
  58. package/dist/sync/folder-status-mapper.d.ts +106 -0
  59. package/dist/sync/folder-status-mapper.d.ts.map +1 -0
  60. package/dist/sync/folder-status-mapper.js +235 -0
  61. package/dist/sync/folder-status-mapper.js.map +1 -0
  62. package/dist/sync/layer-resolver.d.ts +54 -0
  63. package/dist/sync/layer-resolver.d.ts.map +1 -0
  64. package/dist/sync/layer-resolver.js +206 -0
  65. package/dist/sync/layer-resolver.js.map +1 -0
  66. package/dist/sync/markdown-parser.d.ts +49 -0
  67. package/dist/sync/markdown-parser.d.ts.map +1 -0
  68. package/dist/sync/markdown-parser.js +202 -0
  69. package/dist/sync/markdown-parser.js.map +1 -0
  70. package/dist/sync/reverse-sync.d.ts +139 -0
  71. package/dist/sync/reverse-sync.d.ts.map +1 -0
  72. package/dist/sync/reverse-sync.js +773 -0
  73. package/dist/sync/reverse-sync.js.map +1 -0
  74. package/dist/sync/sync-engine.d.ts +157 -0
  75. package/dist/sync/sync-engine.d.ts.map +1 -0
  76. package/dist/sync/sync-engine.js +875 -0
  77. package/dist/sync/sync-engine.js.map +1 -0
  78. package/dist/sync/sync-index.d.ts +150 -0
  79. package/dist/sync/sync-index.d.ts.map +1 -0
  80. package/dist/sync/sync-index.js +287 -0
  81. package/dist/sync/sync-index.js.map +1 -0
  82. package/dist/sync/trinity-mapper.d.ts +62 -0
  83. package/dist/sync/trinity-mapper.d.ts.map +1 -0
  84. package/dist/sync/trinity-mapper.js +548 -0
  85. package/dist/sync/trinity-mapper.js.map +1 -0
  86. package/dist/sync/types.d.ts +176 -0
  87. package/dist/sync/types.d.ts.map +1 -0
  88. package/dist/sync/types.js +6 -0
  89. package/dist/sync/types.js.map +1 -0
  90. package/dist/tools/apply-framework.d.ts +7 -0
  91. package/dist/tools/apply-framework.d.ts.map +1 -0
  92. package/dist/tools/apply-framework.js +30 -0
  93. package/dist/tools/apply-framework.js.map +1 -0
  94. package/dist/tools/commander-comment-create.d.ts +7 -0
  95. package/dist/tools/commander-comment-create.d.ts.map +1 -0
  96. package/dist/tools/commander-comment-create.js +100 -0
  97. package/dist/tools/commander-comment-create.js.map +1 -0
  98. package/dist/tools/commander-comment-list.d.ts +7 -0
  99. package/dist/tools/commander-comment-list.d.ts.map +1 -0
  100. package/dist/tools/commander-comment-list.js +110 -0
  101. package/dist/tools/commander-comment-list.js.map +1 -0
  102. package/dist/tools/commander-document-create.d.ts +7 -0
  103. package/dist/tools/commander-document-create.d.ts.map +1 -0
  104. package/dist/tools/commander-document-create.js +168 -0
  105. package/dist/tools/commander-document-create.js.map +1 -0
  106. package/dist/tools/commander-document-get.d.ts +7 -0
  107. package/dist/tools/commander-document-get.d.ts.map +1 -0
  108. package/dist/tools/commander-document-get.js +104 -0
  109. package/dist/tools/commander-document-get.js.map +1 -0
  110. package/dist/tools/commander-document-list.d.ts +7 -0
  111. package/dist/tools/commander-document-list.d.ts.map +1 -0
  112. package/dist/tools/commander-document-list.js +117 -0
  113. package/dist/tools/commander-document-list.js.map +1 -0
  114. package/dist/tools/commander-document-update.d.ts +7 -0
  115. package/dist/tools/commander-document-update.d.ts.map +1 -0
  116. package/dist/tools/commander-document-update.js +133 -0
  117. package/dist/tools/commander-document-update.js.map +1 -0
  118. package/dist/tools/commander-folder-create.d.ts +7 -0
  119. package/dist/tools/commander-folder-create.d.ts.map +1 -0
  120. package/dist/tools/commander-folder-create.js +157 -0
  121. package/dist/tools/commander-folder-create.js.map +1 -0
  122. package/dist/tools/commander-folder-delete.d.ts +7 -0
  123. package/dist/tools/commander-folder-delete.d.ts.map +1 -0
  124. package/dist/tools/commander-folder-delete.js +85 -0
  125. package/dist/tools/commander-folder-delete.js.map +1 -0
  126. package/dist/tools/commander-folder-get.d.ts +7 -0
  127. package/dist/tools/commander-folder-get.d.ts.map +1 -0
  128. package/dist/tools/commander-folder-get.js +94 -0
  129. package/dist/tools/commander-folder-get.js.map +1 -0
  130. package/dist/tools/commander-folder-list.d.ts +7 -0
  131. package/dist/tools/commander-folder-list.d.ts.map +1 -0
  132. package/dist/tools/commander-folder-list.js +96 -0
  133. package/dist/tools/commander-folder-list.js.map +1 -0
  134. package/dist/tools/commander-folder-update.d.ts +7 -0
  135. package/dist/tools/commander-folder-update.d.ts.map +1 -0
  136. package/dist/tools/commander-folder-update.js +120 -0
  137. package/dist/tools/commander-folder-update.js.map +1 -0
  138. package/dist/tools/commander-framework-apply.d.ts +7 -0
  139. package/dist/tools/commander-framework-apply.d.ts.map +1 -0
  140. package/dist/tools/commander-framework-apply.js +110 -0
  141. package/dist/tools/commander-framework-apply.js.map +1 -0
  142. package/dist/tools/commander-framework-categories.d.ts +7 -0
  143. package/dist/tools/commander-framework-categories.d.ts.map +1 -0
  144. package/dist/tools/commander-framework-categories.js +90 -0
  145. package/dist/tools/commander-framework-categories.js.map +1 -0
  146. package/dist/tools/commander-framework-get.d.ts +7 -0
  147. package/dist/tools/commander-framework-get.d.ts.map +1 -0
  148. package/dist/tools/commander-framework-get.js +124 -0
  149. package/dist/tools/commander-framework-get.js.map +1 -0
  150. package/dist/tools/commander-framework-list.d.ts +7 -0
  151. package/dist/tools/commander-framework-list.d.ts.map +1 -0
  152. package/dist/tools/commander-framework-list.js +103 -0
  153. package/dist/tools/commander-framework-list.js.map +1 -0
  154. package/dist/tools/commander-goal-create.d.ts +7 -0
  155. package/dist/tools/commander-goal-create.d.ts.map +1 -0
  156. package/dist/tools/commander-goal-create.js +130 -0
  157. package/dist/tools/commander-goal-create.js.map +1 -0
  158. package/dist/tools/commander-goal-get.d.ts +7 -0
  159. package/dist/tools/commander-goal-get.d.ts.map +1 -0
  160. package/dist/tools/commander-goal-get.js +83 -0
  161. package/dist/tools/commander-goal-get.js.map +1 -0
  162. package/dist/tools/commander-goal-list.d.ts +7 -0
  163. package/dist/tools/commander-goal-list.d.ts.map +1 -0
  164. package/dist/tools/commander-goal-list.js +111 -0
  165. package/dist/tools/commander-goal-list.js.map +1 -0
  166. package/dist/tools/commander-goal-update.d.ts +7 -0
  167. package/dist/tools/commander-goal-update.d.ts.map +1 -0
  168. package/dist/tools/commander-goal-update.js +110 -0
  169. package/dist/tools/commander-goal-update.js.map +1 -0
  170. package/dist/tools/commander-key-result-create.d.ts +7 -0
  171. package/dist/tools/commander-key-result-create.d.ts.map +1 -0
  172. package/dist/tools/commander-key-result-create.js +134 -0
  173. package/dist/tools/commander-key-result-create.js.map +1 -0
  174. package/dist/tools/commander-key-result-update.d.ts +7 -0
  175. package/dist/tools/commander-key-result-update.d.ts.map +1 -0
  176. package/dist/tools/commander-key-result-update.js +119 -0
  177. package/dist/tools/commander-key-result-update.js.map +1 -0
  178. package/dist/tools/commander-layer-create.d.ts +7 -0
  179. package/dist/tools/commander-layer-create.d.ts.map +1 -0
  180. package/dist/tools/commander-layer-create.js +167 -0
  181. package/dist/tools/commander-layer-create.js.map +1 -0
  182. package/dist/tools/commander-layer-delete.d.ts +7 -0
  183. package/dist/tools/commander-layer-delete.d.ts.map +1 -0
  184. package/dist/tools/commander-layer-delete.js +141 -0
  185. package/dist/tools/commander-layer-delete.js.map +1 -0
  186. package/dist/tools/commander-layer-list.d.ts +7 -0
  187. package/dist/tools/commander-layer-list.d.ts.map +1 -0
  188. package/dist/tools/commander-layer-list.js +102 -0
  189. package/dist/tools/commander-layer-list.js.map +1 -0
  190. package/dist/tools/commander-presentation.d.ts +7 -0
  191. package/dist/tools/commander-presentation.d.ts.map +1 -0
  192. package/dist/tools/commander-presentation.js +185 -0
  193. package/dist/tools/commander-presentation.js.map +1 -0
  194. package/dist/tools/commander-project-create.d.ts +7 -0
  195. package/dist/tools/commander-project-create.d.ts.map +1 -0
  196. package/dist/tools/commander-project-create.js +130 -0
  197. package/dist/tools/commander-project-create.js.map +1 -0
  198. package/dist/tools/commander-project-get.d.ts +7 -0
  199. package/dist/tools/commander-project-get.d.ts.map +1 -0
  200. package/dist/tools/commander-project-get.js +107 -0
  201. package/dist/tools/commander-project-get.js.map +1 -0
  202. package/dist/tools/commander-project-list.d.ts +7 -0
  203. package/dist/tools/commander-project-list.d.ts.map +1 -0
  204. package/dist/tools/commander-project-list.js +104 -0
  205. package/dist/tools/commander-project-list.js.map +1 -0
  206. package/dist/tools/commander-project-update.d.ts +7 -0
  207. package/dist/tools/commander-project-update.d.ts.map +1 -0
  208. package/dist/tools/commander-project-update.js +126 -0
  209. package/dist/tools/commander-project-update.js.map +1 -0
  210. package/dist/tools/commander-project.d.ts +7 -0
  211. package/dist/tools/commander-project.d.ts.map +1 -0
  212. package/dist/tools/commander-project.js +144 -0
  213. package/dist/tools/commander-project.js.map +1 -0
  214. package/dist/tools/commander-role-assign.d.ts +7 -0
  215. package/dist/tools/commander-role-assign.d.ts.map +1 -0
  216. package/dist/tools/commander-role-assign.js +115 -0
  217. package/dist/tools/commander-role-assign.js.map +1 -0
  218. package/dist/tools/commander-role-create.d.ts +7 -0
  219. package/dist/tools/commander-role-create.d.ts.map +1 -0
  220. package/dist/tools/commander-role-create.js +130 -0
  221. package/dist/tools/commander-role-create.js.map +1 -0
  222. package/dist/tools/commander-role-get.d.ts +7 -0
  223. package/dist/tools/commander-role-get.d.ts.map +1 -0
  224. package/dist/tools/commander-role-get.js +108 -0
  225. package/dist/tools/commander-role-get.js.map +1 -0
  226. package/dist/tools/commander-role-list.d.ts +7 -0
  227. package/dist/tools/commander-role-list.d.ts.map +1 -0
  228. package/dist/tools/commander-role-list.js +106 -0
  229. package/dist/tools/commander-role-list.js.map +1 -0
  230. package/dist/tools/commander-role-update.d.ts +7 -0
  231. package/dist/tools/commander-role-update.d.ts.map +1 -0
  232. package/dist/tools/commander-role-update.js +126 -0
  233. package/dist/tools/commander-role-update.js.map +1 -0
  234. package/dist/tools/commander-search.d.ts +7 -0
  235. package/dist/tools/commander-search.d.ts.map +1 -0
  236. package/dist/tools/commander-search.js +146 -0
  237. package/dist/tools/commander-search.js.map +1 -0
  238. package/dist/tools/commander-sheet-create.d.ts +7 -0
  239. package/dist/tools/commander-sheet-create.d.ts.map +1 -0
  240. package/dist/tools/commander-sheet-create.js +160 -0
  241. package/dist/tools/commander-sheet-create.js.map +1 -0
  242. package/dist/tools/commander-sheet-get.d.ts +7 -0
  243. package/dist/tools/commander-sheet-get.d.ts.map +1 -0
  244. package/dist/tools/commander-sheet-get.js +128 -0
  245. package/dist/tools/commander-sheet-get.js.map +1 -0
  246. package/dist/tools/commander-sheet-list.d.ts +7 -0
  247. package/dist/tools/commander-sheet-list.d.ts.map +1 -0
  248. package/dist/tools/commander-sheet-list.js +108 -0
  249. package/dist/tools/commander-sheet-list.js.map +1 -0
  250. package/dist/tools/commander-sheet-update.d.ts +7 -0
  251. package/dist/tools/commander-sheet-update.d.ts.map +1 -0
  252. package/dist/tools/commander-sheet-update.js +163 -0
  253. package/dist/tools/commander-sheet-update.js.map +1 -0
  254. package/dist/tools/commander-status-list.d.ts +7 -0
  255. package/dist/tools/commander-status-list.d.ts.map +1 -0
  256. package/dist/tools/commander-status-list.js +103 -0
  257. package/dist/tools/commander-status-list.js.map +1 -0
  258. package/dist/tools/commander-task-assign.d.ts +7 -0
  259. package/dist/tools/commander-task-assign.d.ts.map +1 -0
  260. package/dist/tools/commander-task-assign.js +91 -0
  261. package/dist/tools/commander-task-assign.js.map +1 -0
  262. package/dist/tools/commander-task-create.d.ts +7 -0
  263. package/dist/tools/commander-task-create.d.ts.map +1 -0
  264. package/dist/tools/commander-task-create.js +142 -0
  265. package/dist/tools/commander-task-create.js.map +1 -0
  266. package/dist/tools/commander-task-delete.d.ts +7 -0
  267. package/dist/tools/commander-task-delete.d.ts.map +1 -0
  268. package/dist/tools/commander-task-delete.js +88 -0
  269. package/dist/tools/commander-task-delete.js.map +1 -0
  270. package/dist/tools/commander-task-list-mine.d.ts +7 -0
  271. package/dist/tools/commander-task-list-mine.d.ts.map +1 -0
  272. package/dist/tools/commander-task-list-mine.js +109 -0
  273. package/dist/tools/commander-task-list-mine.js.map +1 -0
  274. package/dist/tools/commander-task-read.d.ts +10 -0
  275. package/dist/tools/commander-task-read.d.ts.map +1 -0
  276. package/dist/tools/commander-task-read.js +96 -0
  277. package/dist/tools/commander-task-read.js.map +1 -0
  278. package/dist/tools/commander-task-update.d.ts +7 -0
  279. package/dist/tools/commander-task-update.d.ts.map +1 -0
  280. package/dist/tools/commander-task-update.js +159 -0
  281. package/dist/tools/commander-task-update.js.map +1 -0
  282. package/dist/tools/commander-taskboard-tasks.d.ts +7 -0
  283. package/dist/tools/commander-taskboard-tasks.d.ts.map +1 -0
  284. package/dist/tools/commander-taskboard-tasks.js +97 -0
  285. package/dist/tools/commander-taskboard-tasks.js.map +1 -0
  286. package/dist/tools/commander-team-add-member.d.ts +7 -0
  287. package/dist/tools/commander-team-add-member.d.ts.map +1 -0
  288. package/dist/tools/commander-team-add-member.js +104 -0
  289. package/dist/tools/commander-team-add-member.js.map +1 -0
  290. package/dist/tools/commander-team-create.d.ts +7 -0
  291. package/dist/tools/commander-team-create.d.ts.map +1 -0
  292. package/dist/tools/commander-team-create.js +117 -0
  293. package/dist/tools/commander-team-create.js.map +1 -0
  294. package/dist/tools/commander-team-list.d.ts +7 -0
  295. package/dist/tools/commander-team-list.d.ts.map +1 -0
  296. package/dist/tools/commander-team-list.js +94 -0
  297. package/dist/tools/commander-team-list.js.map +1 -0
  298. package/dist/tools/commander-team-remove-member.d.ts +7 -0
  299. package/dist/tools/commander-team-remove-member.d.ts.map +1 -0
  300. package/dist/tools/commander-team-remove-member.js +98 -0
  301. package/dist/tools/commander-team-remove-member.js.map +1 -0
  302. package/dist/tools/commander-user-get.d.ts +7 -0
  303. package/dist/tools/commander-user-get.d.ts.map +1 -0
  304. package/dist/tools/commander-user-get.js +101 -0
  305. package/dist/tools/commander-user-get.js.map +1 -0
  306. package/dist/tools/commander-user-invite.d.ts +7 -0
  307. package/dist/tools/commander-user-invite.d.ts.map +1 -0
  308. package/dist/tools/commander-user-invite.js +119 -0
  309. package/dist/tools/commander-user-invite.js.map +1 -0
  310. package/dist/tools/commander-user-list.d.ts +7 -0
  311. package/dist/tools/commander-user-list.d.ts.map +1 -0
  312. package/dist/tools/commander-user-list.js +108 -0
  313. package/dist/tools/commander-user-list.js.map +1 -0
  314. package/dist/tools/commander-workspace-create.d.ts +7 -0
  315. package/dist/tools/commander-workspace-create.d.ts.map +1 -0
  316. package/dist/tools/commander-workspace-create.js +124 -0
  317. package/dist/tools/commander-workspace-create.js.map +1 -0
  318. package/dist/tools/commander-workspace-list.d.ts +7 -0
  319. package/dist/tools/commander-workspace-list.d.ts.map +1 -0
  320. package/dist/tools/commander-workspace-list.js +95 -0
  321. package/dist/tools/commander-workspace-list.js.map +1 -0
  322. package/dist/tools/commander-workspace-update.d.ts +7 -0
  323. package/dist/tools/commander-workspace-update.d.ts.map +1 -0
  324. package/dist/tools/commander-workspace-update.js +118 -0
  325. package/dist/tools/commander-workspace-update.js.map +1 -0
  326. package/dist/tools/commander-workspace.d.ts +7 -0
  327. package/dist/tools/commander-workspace.d.ts.map +1 -0
  328. package/dist/tools/commander-workspace.js +131 -0
  329. package/dist/tools/commander-workspace.js.map +1 -0
  330. package/dist/tools/create-kanban.d.ts +7 -0
  331. package/dist/tools/create-kanban.d.ts.map +1 -0
  332. package/dist/tools/create-kanban.js +32 -0
  333. package/dist/tools/create-kanban.js.map +1 -0
  334. package/dist/tools/create-table.d.ts +7 -0
  335. package/dist/tools/create-table.d.ts.map +1 -0
  336. package/dist/tools/create-table.js +188 -0
  337. package/dist/tools/create-table.js.map +1 -0
  338. package/dist/tools/search-knowledge.d.ts +7 -0
  339. package/dist/tools/search-knowledge.d.ts.map +1 -0
  340. package/dist/tools/search-knowledge.js +33 -0
  341. package/dist/tools/search-knowledge.js.map +1 -0
  342. package/dist/tools/waymaker-kanban-view.d.ts +7 -0
  343. package/dist/tools/waymaker-kanban-view.d.ts.map +1 -0
  344. package/dist/tools/waymaker-kanban-view.js +255 -0
  345. package/dist/tools/waymaker-kanban-view.js.map +1 -0
  346. package/dist/tools/waymaker-sync-configure.d.ts +13 -0
  347. package/dist/tools/waymaker-sync-configure.d.ts.map +1 -0
  348. package/dist/tools/waymaker-sync-configure.js +291 -0
  349. package/dist/tools/waymaker-sync-configure.js.map +1 -0
  350. package/dist/tools/waymaker-sync-file.d.ts +7 -0
  351. package/dist/tools/waymaker-sync-file.d.ts.map +1 -0
  352. package/dist/tools/waymaker-sync-file.js +79 -0
  353. package/dist/tools/waymaker-sync-file.js.map +1 -0
  354. package/dist/tools/waymaker-sync-poll.d.ts +8 -0
  355. package/dist/tools/waymaker-sync-poll.d.ts.map +1 -0
  356. package/dist/tools/waymaker-sync-poll.js +398 -0
  357. package/dist/tools/waymaker-sync-poll.js.map +1 -0
  358. package/dist/tools/waymaker-sync-start.d.ts +7 -0
  359. package/dist/tools/waymaker-sync-start.d.ts.map +1 -0
  360. package/dist/tools/waymaker-sync-start.js +56 -0
  361. package/dist/tools/waymaker-sync-start.js.map +1 -0
  362. package/dist/tools/waymaker-sync-status.d.ts +7 -0
  363. package/dist/tools/waymaker-sync-status.d.ts.map +1 -0
  364. package/dist/tools/waymaker-sync-status.js +45 -0
  365. package/dist/tools/waymaker-sync-status.js.map +1 -0
  366. package/dist/tools/waymaker-sync-stop.d.ts +7 -0
  367. package/dist/tools/waymaker-sync-stop.d.ts.map +1 -0
  368. package/dist/tools/waymaker-sync-stop.js +56 -0
  369. package/dist/tools/waymaker-sync-stop.js.map +1 -0
  370. package/dist/tools/waymaker-sync-workspace.d.ts +26 -0
  371. package/dist/tools/waymaker-sync-workspace.d.ts.map +1 -0
  372. package/dist/tools/waymaker-sync-workspace.js +148 -0
  373. package/dist/tools/waymaker-sync-workspace.js.map +1 -0
  374. package/dist/tools/waymaker-sync-workspace.tool.d.ts +9 -0
  375. package/dist/tools/waymaker-sync-workspace.tool.d.ts.map +1 -0
  376. package/dist/tools/waymaker-sync-workspace.tool.js +68 -0
  377. package/dist/tools/waymaker-sync-workspace.tool.js.map +1 -0
  378. package/dist/types/tool.d.ts +13 -0
  379. package/dist/types/tool.d.ts.map +1 -0
  380. package/dist/types/tool.js +2 -0
  381. package/dist/types/tool.js.map +1 -0
  382. package/dist/utils/daemon-health.d.ts +21 -0
  383. package/dist/utils/daemon-health.d.ts.map +1 -0
  384. package/dist/utils/daemon-health.js +40 -0
  385. package/dist/utils/daemon-health.js.map +1 -0
  386. package/dist/utils/fetch-ipv4.d.ts +36 -0
  387. package/dist/utils/fetch-ipv4.d.ts.map +1 -0
  388. package/dist/utils/fetch-ipv4.js +91 -0
  389. package/dist/utils/fetch-ipv4.js.map +1 -0
  390. package/package.json +62 -0
@@ -0,0 +1,875 @@
1
+ /**
2
+ * Waymaker Sync - Sync Engine
3
+ * Main orchestration engine for bidirectional sync between IDE and Commander
4
+ *
5
+ * Best Practices Implemented:
6
+ * 1. Persistent Index - tracks synced files across daemon restarts
7
+ * 2. Checksum-based change detection - skips unchanged files
8
+ * 3. Retry with exponential backoff - handles transient failures
9
+ * 4. Atomic index writes - prevents corruption
10
+ * 5. Conflict detection - warns when IDE and Commander diverge
11
+ */
12
+ import * as path from 'path';
13
+ import * as fs from 'fs/promises';
14
+ import { glob } from 'glob';
15
+ import { EventEmitter } from 'events';
16
+ import { ConfigManager } from './config-manager.js';
17
+ import { MarkdownParser } from './markdown-parser.js';
18
+ import { TrinityMapper } from './trinity-mapper.js';
19
+ import { FileWatcher } from './file-watcher.js';
20
+ import { FolderStatusMapper } from './folder-status-mapper.js';
21
+ import { SyncIndexManager } from './sync-index.js';
22
+ /** Retry configuration */
23
+ const RETRY_CONFIG = {
24
+ maxRetries: 3,
25
+ baseDelayMs: 1000,
26
+ maxDelayMs: 10000,
27
+ };
28
+ export class SyncEngine extends EventEmitter {
29
+ configManager;
30
+ parser;
31
+ mapper = null; // Initialized in initialize()
32
+ watcher = null;
33
+ folderStatusMapper;
34
+ indexManager;
35
+ projectPath;
36
+ running = false;
37
+ startedAt = null;
38
+ syncCount = 0;
39
+ errorCount = 0;
40
+ lastSyncAt = null;
41
+ recentErrors = [];
42
+ syncStates = new Map();
43
+ initialScanComplete = false;
44
+ constructor(projectPath) {
45
+ super();
46
+ this.projectPath = projectPath;
47
+ this.configManager = new ConfigManager(projectPath);
48
+ this.parser = new MarkdownParser();
49
+ this.folderStatusMapper = new FolderStatusMapper();
50
+ this.indexManager = new SyncIndexManager(projectPath);
51
+ }
52
+ /**
53
+ * Initialize sync engine
54
+ */
55
+ async initialize() {
56
+ console.error('[SyncEngine] Initializing...');
57
+ // Load configuration
58
+ await this.configManager.load();
59
+ const config = this.configManager.getConfig();
60
+ console.error('[SyncEngine] Configuration loaded');
61
+ console.error(`[SyncEngine] Workspace: ${config.workspace_id}`);
62
+ console.error(`[SyncEngine] Project: ${config.project_id}`);
63
+ console.error(`[SyncEngine] Taskboard: ${config.sync.taskboard_id || 'not set'}`);
64
+ console.error(`[SyncEngine] Mode: ${config.sync.mode}`);
65
+ // Load persistent sync index
66
+ await this.indexManager.load();
67
+ if (config.sync.taskboard_id) {
68
+ this.indexManager.setTaskboardId(config.sync.taskboard_id);
69
+ }
70
+ const indexStats = this.indexManager.getStats();
71
+ console.error(`[SyncEngine] Index loaded: ${indexStats.filesCount} files tracked, ${indexStats.totalSyncs} total syncs`);
72
+ // Initialize TrinityMapper with FolderService configuration
73
+ const folderServiceConfig = {
74
+ projectId: config.project_id,
75
+ workspaceId: config.workspace_id,
76
+ organizationId: config.organization_id,
77
+ userId: 'sync-engine', // TBD: Get from auth context
78
+ projectRoot: this.projectPath,
79
+ };
80
+ this.mapper = new TrinityMapper(undefined, folderServiceConfig);
81
+ console.error('[SyncEngine] TrinityMapper initialized with FolderService');
82
+ }
83
+ /**
84
+ * Start sync daemon
85
+ */
86
+ async start() {
87
+ if (this.running) {
88
+ throw new Error('Sync engine is already running');
89
+ }
90
+ await this.initialize();
91
+ const config = this.configManager.getConfig();
92
+ if (!config.sync.enabled) {
93
+ throw new Error('Sync is disabled in configuration');
94
+ }
95
+ if (!config.sync.taskboard_id) {
96
+ console.error('[SyncEngine] WARNING: No taskboard_id configured. Some sync operations may fail.');
97
+ }
98
+ // Create file watcher
99
+ this.watcher = new FileWatcher({
100
+ watchPatterns: config.sync.watch_patterns,
101
+ ignorePatterns: config.sync.ignore_patterns,
102
+ projectPath: this.projectPath,
103
+ debounceMs: 1000,
104
+ });
105
+ // Set up event handlers
106
+ this.watcher.on('change', (event) => {
107
+ this.handleFileChange(event);
108
+ });
109
+ this.watcher.on('ready', () => {
110
+ console.error('[SyncEngine] File watcher ready');
111
+ this.emit('ready');
112
+ });
113
+ this.watcher.on('error', (error) => {
114
+ console.error('[SyncEngine] Watcher error:', error);
115
+ this.handleError(error.message, 'watcher');
116
+ });
117
+ // Start watching
118
+ this.watcher.start();
119
+ this.running = true;
120
+ this.startedAt = new Date();
121
+ console.error('[SyncEngine] ✅ Sync engine started');
122
+ console.error(`[SyncEngine] Watching ${config.sync.watch_patterns.length} patterns`);
123
+ this.emit('started');
124
+ }
125
+ /**
126
+ * Stop sync daemon
127
+ */
128
+ async stop() {
129
+ if (!this.running) {
130
+ return;
131
+ }
132
+ console.error('[SyncEngine] Stopping sync engine...');
133
+ // Flush pending index writes
134
+ await this.indexManager.flush();
135
+ console.error('[SyncEngine] Index saved');
136
+ // Stop file watcher
137
+ if (this.watcher) {
138
+ await this.watcher.stop();
139
+ this.watcher = null;
140
+ }
141
+ this.running = false;
142
+ this.startedAt = null;
143
+ console.error('[SyncEngine] ✅ Sync engine stopped');
144
+ this.emit('stopped');
145
+ }
146
+ /**
147
+ * Handle file change events
148
+ */
149
+ async handleFileChange(event) {
150
+ const config = this.configManager.getConfig();
151
+ const mode = config.sync.mode;
152
+ // Skip if mode is commander-to-ide only
153
+ if (mode === 'commander-to-ide') {
154
+ return;
155
+ }
156
+ console.error(`[SyncEngine] Processing ${event.type}: ${event.path}`);
157
+ try {
158
+ // Handle file moves specially - detect status change
159
+ if (event.type === 'move' && event.oldPath) {
160
+ await this.handleFileMove(event);
161
+ return;
162
+ }
163
+ // Use retry logic for file changes too
164
+ const result = await this.syncWithRetry(event.path);
165
+ if (result.success) {
166
+ this.syncCount++;
167
+ this.lastSyncAt = new Date();
168
+ // Update sync state
169
+ const checksum = this.indexManager.calculateChecksum(await this.parser.parseFile(path.join(this.projectPath, event.path)).then(p => p.content));
170
+ // Update in-memory state
171
+ this.syncStates.set(event.path, {
172
+ filePath: event.path,
173
+ lastSyncedAt: new Date(),
174
+ lastModifiedAt: event.timestamp,
175
+ commanderId: result.commanderId || null,
176
+ documentType: result.documentType,
177
+ checksum,
178
+ });
179
+ // Update persistent index
180
+ if (result.operation !== 'skip') {
181
+ const parsed = await this.parser.parseFile(path.join(this.projectPath, event.path));
182
+ this.indexManager.updateFileState(event.path, {
183
+ checksum,
184
+ documentType: result.documentType,
185
+ taskId: parsed.frontmatter.sync?.task_id || result.commanderId || undefined,
186
+ documentId: parsed.frontmatter.sync?.document_id || undefined,
187
+ layerId: parsed.frontmatter.sync?.layer_id || undefined,
188
+ fileModifiedAt: event.timestamp,
189
+ });
190
+ }
191
+ this.emit('sync-success', result);
192
+ console.error(`[SyncEngine] ✅ ${result.message}`);
193
+ }
194
+ else {
195
+ if (result.operation !== 'skip') {
196
+ this.handleError(result.error || result.message, event.path);
197
+ }
198
+ }
199
+ }
200
+ catch (error) {
201
+ this.handleError(error instanceof Error ? error.message : String(error), event.path);
202
+ }
203
+ }
204
+ /**
205
+ * Handle file move events - update task status based on folder change
206
+ */
207
+ async handleFileMove(event) {
208
+ if (!event.oldPath) {
209
+ // Can't process without old path, fall back to normal sync
210
+ await this.syncFileToCommander(event.path);
211
+ return;
212
+ }
213
+ const absolutePath = path.join(this.projectPath, event.path);
214
+ // Detect status change from folder paths
215
+ const statusChange = this.folderStatusMapper.detectStatusChange(event.oldPath, event.path);
216
+ if (statusChange) {
217
+ console.error(`[SyncEngine] Status change detected: ${statusChange.oldStatus.statusSection} → ${statusChange.newStatus.statusSection}`);
218
+ // Parse the file to get task_id
219
+ const parsed = await this.parser.parseFile(absolutePath);
220
+ if (parsed.frontmatter.sync?.task_id) {
221
+ // Update task status in Commander
222
+ const taskId = parsed.frontmatter.sync.task_id;
223
+ const newStatus = statusChange.newStatus.statusSection;
224
+ console.error(`[SyncEngine] Updating task ${taskId} status to: ${newStatus}`);
225
+ try {
226
+ await this.updateTaskStatus(taskId, newStatus);
227
+ // Update sync state for new path
228
+ const checksum = this.indexManager.calculateChecksum(parsed.content);
229
+ const oldState = this.syncStates.get(event.oldPath);
230
+ const docType = oldState?.documentType || 'task';
231
+ // Update in-memory state
232
+ this.syncStates.delete(event.oldPath);
233
+ this.syncStates.set(event.path, {
234
+ filePath: event.path,
235
+ lastSyncedAt: new Date(),
236
+ lastModifiedAt: event.timestamp,
237
+ commanderId: taskId,
238
+ documentType: docType,
239
+ checksum,
240
+ });
241
+ // Update persistent index (remove old path, add new)
242
+ this.indexManager.removeFile(event.oldPath);
243
+ this.indexManager.updateFileState(event.path, {
244
+ checksum,
245
+ documentType: docType,
246
+ taskId,
247
+ documentId: parsed.frontmatter.sync?.document_id || undefined,
248
+ layerId: parsed.frontmatter.sync?.layer_id || undefined,
249
+ fileModifiedAt: event.timestamp,
250
+ });
251
+ this.syncCount++;
252
+ this.lastSyncAt = new Date();
253
+ const result = {
254
+ success: true,
255
+ operation: 'update',
256
+ documentType: 'task',
257
+ filePath: event.path,
258
+ commanderId: taskId,
259
+ message: `Task status updated: ${statusChange.oldStatus.statusSection} → ${newStatus}`,
260
+ };
261
+ this.emit('sync-success', result);
262
+ console.error(`[SyncEngine] ✅ ${result.message}`);
263
+ }
264
+ catch (error) {
265
+ this.handleError(error instanceof Error ? error.message : String(error), event.path);
266
+ }
267
+ }
268
+ else {
269
+ // No task_id, do a full sync to create/update
270
+ console.error(`[SyncEngine] No task_id in file, performing full sync`);
271
+ await this.syncFileToCommander(event.path);
272
+ }
273
+ }
274
+ else {
275
+ // No status change (move within same status folder), just update path metadata
276
+ console.error(`[SyncEngine] File moved but status unchanged, syncing content`);
277
+ await this.syncFileToCommander(event.path);
278
+ }
279
+ }
280
+ /**
281
+ * Update task status in Commander
282
+ */
283
+ async updateTaskStatus(taskId, newStatus) {
284
+ // Get API key from env or auth.json
285
+ let apiKey = process.env.WAYMAKER_API_KEY;
286
+ if (!apiKey) {
287
+ const authPath = path.join(process.env.HOME || '', '.waymaker', 'auth.json');
288
+ try {
289
+ const authData = JSON.parse(await fs.readFile(authPath, 'utf-8'));
290
+ apiKey = authData.accessToken;
291
+ }
292
+ catch {
293
+ // Ignore auth file read errors
294
+ }
295
+ }
296
+ if (!apiKey) {
297
+ throw new Error('Authentication required. Run: waymaker auth login');
298
+ }
299
+ const baseUrl = process.env.WAYMAKER_APPS_URL || 'https://apps.waymakerone.com';
300
+ const response = await fetch(`${baseUrl}/functions/v1/commander-task-operations`, {
301
+ method: 'POST',
302
+ headers: {
303
+ 'Authorization': `Bearer ${apiKey}`,
304
+ 'Content-Type': 'application/json',
305
+ },
306
+ body: JSON.stringify({
307
+ action: 'update-task',
308
+ id: taskId,
309
+ status: newStatus,
310
+ }),
311
+ });
312
+ if (!response.ok) {
313
+ const errorText = await response.text();
314
+ throw new Error(`Failed to update task status: ${response.status} ${errorText}`);
315
+ }
316
+ const result = await response.json();
317
+ if (!result.success) {
318
+ throw new Error(result.message || 'Failed to update task status');
319
+ }
320
+ }
321
+ /**
322
+ * Sync a single file to Commander
323
+ */
324
+ async syncFileToCommander(relativePath) {
325
+ const config = this.configManager.getConfig();
326
+ const absolutePath = path.join(this.projectPath, relativePath);
327
+ if (!config.sync.taskboard_id) {
328
+ return {
329
+ success: false,
330
+ operation: 'skip',
331
+ documentType: 'document',
332
+ filePath: relativePath,
333
+ message: 'No taskboard_id configured',
334
+ error: 'Configuration error: sync.taskboard_id is required',
335
+ };
336
+ }
337
+ if (!this.mapper) {
338
+ throw new Error('Sync engine not initialized - call initialize() first');
339
+ }
340
+ // Check if file was just written by ReverseSync (prevent sync loop)
341
+ try {
342
+ const parsed = await this.parser.parseFile(absolutePath);
343
+ const commanderModifiedAt = parsed.frontmatter.commander_modified_at;
344
+ if (commanderModifiedAt) {
345
+ const modifiedTime = new Date(commanderModifiedAt).getTime();
346
+ const now = Date.now();
347
+ const timeDiff = now - modifiedTime;
348
+ // If Commander modified this file within the last 10 seconds, skip syncing back
349
+ // This prevents the sync loop between ReverseSync and SyncEngine
350
+ if (timeDiff < 10000) {
351
+ console.log(`[SyncEngine] ✅ Skipping recently synced file (${Math.round(timeDiff / 1000)}s ago from Commander)`);
352
+ return {
353
+ success: true,
354
+ operation: 'skip',
355
+ documentType: 'document',
356
+ filePath: relativePath,
357
+ message: 'Skipped - recently synced from Commander',
358
+ };
359
+ }
360
+ }
361
+ }
362
+ catch (error) {
363
+ // If parsing fails, continue with sync attempt
364
+ console.error(`[SyncEngine] Warning: Could not check commander_modified_at: ${error}`);
365
+ }
366
+ return await this.mapper.syncToCommander({
367
+ filePath: absolutePath,
368
+ taskboardId: config.sync.taskboard_id,
369
+ projectId: config.project_id,
370
+ });
371
+ }
372
+ /**
373
+ * Sync with retry logic and exponential backoff
374
+ * Handles transient failures like network timeouts
375
+ */
376
+ async syncWithRetry(relativePath) {
377
+ let lastError = null;
378
+ for (let attempt = 0; attempt <= RETRY_CONFIG.maxRetries; attempt++) {
379
+ try {
380
+ const result = await this.syncFileToCommander(relativePath);
381
+ // If sync succeeded or was skipped (not an error), return
382
+ if (result.success || result.operation === 'skip') {
383
+ return result;
384
+ }
385
+ // Check if error is retryable
386
+ const errorMsg = result.error || result.message;
387
+ if (!this.isRetryableError(errorMsg)) {
388
+ return result; // Non-retryable error, return immediately
389
+ }
390
+ lastError = new Error(errorMsg);
391
+ }
392
+ catch (error) {
393
+ lastError = error instanceof Error ? error : new Error(String(error));
394
+ // Check if error is retryable
395
+ if (!this.isRetryableError(lastError.message)) {
396
+ throw lastError;
397
+ }
398
+ }
399
+ // If we have more retries, wait with exponential backoff
400
+ if (attempt < RETRY_CONFIG.maxRetries) {
401
+ const delay = Math.min(RETRY_CONFIG.baseDelayMs * Math.pow(2, attempt), RETRY_CONFIG.maxDelayMs);
402
+ console.error(`[SyncEngine] Retry ${attempt + 1}/${RETRY_CONFIG.maxRetries} for ${relativePath} in ${delay}ms`);
403
+ await this.sleep(delay);
404
+ }
405
+ }
406
+ // All retries exhausted
407
+ return {
408
+ success: false,
409
+ operation: 'skip',
410
+ documentType: 'document',
411
+ filePath: relativePath,
412
+ message: `Failed after ${RETRY_CONFIG.maxRetries} retries`,
413
+ error: lastError?.message || 'Unknown error',
414
+ };
415
+ }
416
+ /**
417
+ * Check if an error is retryable (transient failures)
418
+ */
419
+ isRetryableError(errorMsg) {
420
+ const retryablePatterns = [
421
+ /timeout/i,
422
+ /ETIMEDOUT/i,
423
+ /ECONNRESET/i,
424
+ /ECONNREFUSED/i,
425
+ /ENOTFOUND/i,
426
+ /network/i,
427
+ /socket hang up/i,
428
+ /503/i, // Service Unavailable
429
+ /502/i, // Bad Gateway
430
+ /504/i, // Gateway Timeout
431
+ /429/i, // Too Many Requests
432
+ ];
433
+ return retryablePatterns.some(pattern => pattern.test(errorMsg));
434
+ }
435
+ /**
436
+ * Sleep helper for retry delays
437
+ */
438
+ sleep(ms) {
439
+ return new Promise(resolve => setTimeout(resolve, ms));
440
+ }
441
+ /**
442
+ * Handle sync errors
443
+ */
444
+ handleError(error, filePath) {
445
+ this.errorCount++;
446
+ const errorEntry = {
447
+ timestamp: new Date(),
448
+ error,
449
+ filePath,
450
+ };
451
+ this.recentErrors.push(errorEntry);
452
+ // Keep only last 10 errors
453
+ if (this.recentErrors.length > 10) {
454
+ this.recentErrors.shift();
455
+ }
456
+ console.error(`[SyncEngine] ❌ Error in ${filePath}: ${error}`);
457
+ this.emit('error', errorEntry);
458
+ }
459
+ /**
460
+ * Get sync daemon status
461
+ */
462
+ getStatus() {
463
+ const stats = this.watcher?.getStats();
464
+ const indexStats = this.indexManager.getStats();
465
+ return {
466
+ running: this.running,
467
+ startedAt: this.startedAt,
468
+ filesWatched: stats?.filesWatched ?? 0,
469
+ lastSyncAt: this.lastSyncAt,
470
+ syncCount: this.syncCount,
471
+ errorCount: this.errorCount,
472
+ recentErrors: this.recentErrors,
473
+ indexStats,
474
+ };
475
+ }
476
+ /**
477
+ * Get sync state for a file
478
+ */
479
+ getSyncState(filePath) {
480
+ return this.syncStates.get(filePath) || null;
481
+ }
482
+ /**
483
+ * Get all sync states
484
+ */
485
+ getAllSyncStates() {
486
+ return this.syncStates;
487
+ }
488
+ /**
489
+ * Manually trigger sync for a specific file
490
+ */
491
+ async syncFile(relativePath) {
492
+ return await this.syncFileToCommander(relativePath);
493
+ }
494
+ /**
495
+ * Sync all existing files matching watch patterns
496
+ * This is the "initial scan" that runs on daemon start
497
+ */
498
+ async syncAll(options = {}) {
499
+ const startTime = Date.now();
500
+ const { batchSize = 50, concurrency = 5, dryRun = false, force = false, } = options;
501
+ const config = this.configManager.getConfig();
502
+ if (!config.sync.taskboard_id) {
503
+ return {
504
+ totalFiles: 0,
505
+ synced: 0,
506
+ skipped: 0,
507
+ failed: 1,
508
+ results: [],
509
+ errors: [{ filePath: '', error: 'No taskboard_id configured' }],
510
+ duration: Date.now() - startTime,
511
+ };
512
+ }
513
+ console.error('[SyncEngine] Starting initial scan...');
514
+ console.error(`[SyncEngine] Options: batchSize=${batchSize}, concurrency=${concurrency}, dryRun=${dryRun}`);
515
+ console.error(`[SyncEngine] Taskboard ID: ${config.sync.taskboard_id}`);
516
+ console.error(`[SyncEngine] Workspace ID: ${config.workspace_id}`);
517
+ console.error(`[SyncEngine] Organization ID: ${config.organization_id}`);
518
+ console.error(`[SyncEngine] Project ID: ${config.project_id}`);
519
+ // Step 1: Discover and create all folders first (including empty ones)
520
+ // This ensures folder structure parity between IDE and Commander
521
+ console.error('[SyncEngine] Step 1: Discovering directories...');
522
+ const directories = await this.discoverDirectories(config.sync.watch_patterns);
523
+ console.error(`[SyncEngine] Found ${directories.length} directories to sync`);
524
+ if (!dryRun && this.mapper) {
525
+ console.error('[SyncEngine] Creating folder structure in Commander...');
526
+ const folderService = this.mapper.getFolderService();
527
+ if (folderService) {
528
+ let foldersCreated = 0;
529
+ for (const dir of directories) {
530
+ try {
531
+ await folderService.ensureFolderPath(dir);
532
+ foldersCreated++;
533
+ }
534
+ catch (error) {
535
+ console.error(`[SyncEngine] ⚠️ Failed to create folder ${dir}:`, error);
536
+ }
537
+ }
538
+ console.error(`[SyncEngine] ✅ Folder structure synced (${foldersCreated} directories)`);
539
+ }
540
+ }
541
+ // Step 2: Discover all markdown files matching watch patterns
542
+ console.error('[SyncEngine] Step 2: Discovering files...');
543
+ const files = await this.discoverFiles(config.sync.watch_patterns);
544
+ console.error(`[SyncEngine] Found ${files.length} files to scan`);
545
+ if (dryRun) {
546
+ console.error('[SyncEngine] DRY RUN - no files will be synced');
547
+ return {
548
+ totalFiles: files.length,
549
+ synced: 0,
550
+ skipped: files.length,
551
+ failed: 0,
552
+ results: files.map(f => ({
553
+ success: true,
554
+ operation: 'skip',
555
+ documentType: 'document',
556
+ filePath: f,
557
+ message: 'Dry run - skipped',
558
+ })),
559
+ errors: [],
560
+ duration: Date.now() - startTime,
561
+ };
562
+ }
563
+ const results = [];
564
+ const errors = [];
565
+ let synced = 0;
566
+ let skipped = 0;
567
+ let failed = 0;
568
+ // Process files in batches
569
+ for (let i = 0; i < files.length; i += batchSize) {
570
+ const batch = files.slice(i, i + batchSize);
571
+ console.error(`[SyncEngine] Processing batch ${Math.floor(i / batchSize) + 1}/${Math.ceil(files.length / batchSize)} (${batch.length} files)`);
572
+ // Process batch with concurrency limit
573
+ const batchResults = await this.processBatch(batch, concurrency, force);
574
+ for (const result of batchResults) {
575
+ results.push(result);
576
+ if (result.success) {
577
+ if (result.operation === 'skip') {
578
+ skipped++;
579
+ }
580
+ else {
581
+ synced++;
582
+ this.syncCount++;
583
+ }
584
+ }
585
+ else {
586
+ failed++;
587
+ // Use handleError to populate recentErrors (was missing!)
588
+ this.handleError(result.error || result.message, result.filePath);
589
+ errors.push({
590
+ filePath: result.filePath,
591
+ error: result.error || result.message,
592
+ });
593
+ }
594
+ }
595
+ // Save index after each batch (incremental saves - don't lose progress on crash)
596
+ await this.indexManager.flush();
597
+ console.error(`[SyncEngine] Index saved after batch (${Math.min(i + batchSize, files.length)}/${files.length} files processed)`);
598
+ // Emit progress event
599
+ this.emit('sync-progress', {
600
+ total: files.length,
601
+ processed: Math.min(i + batchSize, files.length),
602
+ synced,
603
+ skipped,
604
+ failed,
605
+ });
606
+ }
607
+ this.lastSyncAt = new Date();
608
+ this.initialScanComplete = true;
609
+ // Record full sync in persistent index
610
+ this.indexManager.recordFullSync();
611
+ await this.indexManager.flush(); // Ensure index is saved
612
+ const duration = Date.now() - startTime;
613
+ console.error(`[SyncEngine] Initial scan complete in ${duration}ms`);
614
+ console.error(`[SyncEngine] Results: ${synced} synced, ${skipped} skipped, ${failed} failed`);
615
+ this.emit('sync-all-complete', { totalFiles: files.length, synced, skipped, failed, duration });
616
+ return {
617
+ totalFiles: files.length,
618
+ synced,
619
+ skipped,
620
+ failed,
621
+ results,
622
+ errors,
623
+ duration,
624
+ };
625
+ }
626
+ /**
627
+ * Discover all directories matching watch patterns (including empty ones)
628
+ * This ensures folder structure parity between IDE and Commander
629
+ */
630
+ async discoverDirectories(patterns) {
631
+ const allDirs = new Set();
632
+ const config = this.configManager.getConfig();
633
+ const ignorePatterns = config.sync.ignore_patterns || [];
634
+ for (const pattern of patterns) {
635
+ try {
636
+ // Get base directory from pattern (e.g., "docs/**/*.md" → "docs")
637
+ const baseParts = pattern.split('*')[0].split('/').filter(p => p);
638
+ const baseDir = baseParts.join('/') || '.';
639
+ const absoluteBaseDir = path.join(this.projectPath, baseDir);
640
+ // Check if base directory exists
641
+ try {
642
+ await fs.access(absoluteBaseDir);
643
+ }
644
+ catch {
645
+ continue; // Base directory doesn't exist, skip
646
+ }
647
+ // Walk directory tree to find all subdirectories
648
+ const walkDir = async (dir) => {
649
+ try {
650
+ const entries = await fs.readdir(dir, { withFileTypes: true });
651
+ for (const entry of entries) {
652
+ if (entry.isDirectory()) {
653
+ const fullPath = path.join(dir, entry.name);
654
+ const relativePath = path.relative(this.projectPath, fullPath);
655
+ // Check ignore patterns
656
+ const shouldIgnore = ignorePatterns.some(ignorePattern => {
657
+ // Simple glob matching for common patterns
658
+ if (ignorePattern.includes('**')) {
659
+ const prefix = ignorePattern.split('**')[0];
660
+ return relativePath.startsWith(prefix.replace(/\/$/, ''));
661
+ }
662
+ return relativePath.includes(ignorePattern.replace(/\*\*/g, '').replace(/\//g, ''));
663
+ });
664
+ if (!shouldIgnore) {
665
+ allDirs.add(relativePath);
666
+ await walkDir(fullPath); // Recurse
667
+ }
668
+ }
669
+ }
670
+ }
671
+ catch (error) {
672
+ console.error(`[SyncEngine] Error reading directory ${dir}:`, error);
673
+ }
674
+ };
675
+ await walkDir(absoluteBaseDir);
676
+ }
677
+ catch (error) {
678
+ console.error(`[SyncEngine] Error discovering directories for pattern ${pattern}:`, error);
679
+ }
680
+ }
681
+ // Sort for consistent processing order (parents before children)
682
+ return Array.from(allDirs).sort();
683
+ }
684
+ /**
685
+ * Discover all markdown files matching patterns
686
+ */
687
+ async discoverFiles(patterns) {
688
+ const allFiles = new Set();
689
+ for (const pattern of patterns) {
690
+ try {
691
+ const absolutePattern = path.join(this.projectPath, pattern);
692
+ const matches = await glob(absolutePattern, {
693
+ nodir: true,
694
+ ignore: ['**/node_modules/**', '**/.git/**', '**/dist/**'],
695
+ });
696
+ for (const match of matches) {
697
+ if (match.endsWith('.md')) {
698
+ // Store as relative path
699
+ const relativePath = path.relative(this.projectPath, match);
700
+ allFiles.add(relativePath);
701
+ }
702
+ }
703
+ }
704
+ catch (error) {
705
+ console.error(`[SyncEngine] Error globbing pattern ${pattern}:`, error);
706
+ }
707
+ }
708
+ // Sort files for consistent processing order
709
+ return Array.from(allFiles).sort();
710
+ }
711
+ /**
712
+ * Process a batch of files with concurrency limit
713
+ * Uses Promise.allSettled to prevent one bad file from crashing entire batch
714
+ */
715
+ async processBatch(files, concurrency, force) {
716
+ const results = [];
717
+ // Process in chunks of 'concurrency' size
718
+ for (let i = 0; i < files.length; i += concurrency) {
719
+ const chunk = files.slice(i, i + concurrency);
720
+ const chunkPromises = chunk.map(file => this.syncFileWithCheck(file, force));
721
+ // Use allSettled to handle individual failures gracefully
722
+ const settledResults = await Promise.allSettled(chunkPromises);
723
+ for (let j = 0; j < settledResults.length; j++) {
724
+ const settled = settledResults[j];
725
+ const filePath = chunk[j];
726
+ if (settled.status === 'fulfilled') {
727
+ results.push(settled.value);
728
+ }
729
+ else {
730
+ // Promise rejected - create error result instead of crashing
731
+ console.error(`[SyncEngine] ❌ Unhandled error in ${filePath}:`, settled.reason);
732
+ results.push({
733
+ success: false,
734
+ operation: 'skip',
735
+ documentType: 'document',
736
+ filePath,
737
+ message: `Unhandled error: ${settled.reason?.message || String(settled.reason)}`,
738
+ error: settled.reason?.message || String(settled.reason),
739
+ });
740
+ }
741
+ }
742
+ }
743
+ return results;
744
+ }
745
+ /**
746
+ * Sync a file with checksum verification to avoid unnecessary syncs
747
+ * Uses persistent index and retry logic with exponential backoff
748
+ */
749
+ async syncFileWithCheck(relativePath, force) {
750
+ try {
751
+ const absolutePath = path.join(this.projectPath, relativePath);
752
+ // Read and parse file
753
+ let content;
754
+ let fileStat = null;
755
+ try {
756
+ content = await fs.readFile(absolutePath, 'utf-8');
757
+ fileStat = await fs.stat(absolutePath);
758
+ }
759
+ catch {
760
+ // File was deleted - remove from index
761
+ this.indexManager.removeFile(relativePath);
762
+ return {
763
+ success: false,
764
+ operation: 'skip',
765
+ documentType: 'document',
766
+ filePath: relativePath,
767
+ message: 'File not found or unreadable',
768
+ error: 'File not found',
769
+ };
770
+ }
771
+ // Calculate checksum
772
+ const checksum = this.indexManager.calculateChecksum(content);
773
+ // Check persistent index - skip if unchanged (unless forced)
774
+ if (!force && !this.indexManager.needsSync(relativePath, checksum)) {
775
+ const indexState = this.indexManager.getFileState(relativePath);
776
+ return {
777
+ success: true,
778
+ operation: 'skip',
779
+ documentType: (indexState?.documentType || 'document'),
780
+ filePath: relativePath,
781
+ message: 'Already synced (checksum match in index)',
782
+ };
783
+ }
784
+ // Also check in-memory state for recent syncs (within same session)
785
+ const existingState = this.syncStates.get(relativePath);
786
+ if (!force && existingState && existingState.checksum === checksum) {
787
+ return {
788
+ success: true,
789
+ operation: 'skip',
790
+ documentType: existingState.documentType,
791
+ filePath: relativePath,
792
+ message: 'Already synced (checksum match)',
793
+ };
794
+ }
795
+ // Parse file - auto-init will happen in trinity-mapper if no sync block
796
+ const parsed = await this.parser.parseFile(absolutePath);
797
+ // Only skip if explicitly disabled (sync.enabled: false)
798
+ if (parsed.frontmatter.sync?.enabled === false) {
799
+ console.error(`[SyncEngine] Skipped (sync.enabled: false): ${relativePath}`);
800
+ return {
801
+ success: true,
802
+ operation: 'skip',
803
+ documentType: 'document',
804
+ filePath: relativePath,
805
+ message: 'Sync disabled via frontmatter (sync.enabled: false)',
806
+ };
807
+ }
808
+ // Files without sync block will be auto-initialized by trinity-mapper
809
+ // Don't skip them here - let them flow through to get frontmatter added
810
+ // Check for potential conflicts
811
+ const fileModifiedAt = fileStat ? new Date(fileStat.mtimeMs) : new Date();
812
+ const conflictCheck = this.indexManager.detectPotentialConflicts(relativePath, checksum, fileModifiedAt);
813
+ if (conflictCheck.hasConflict) {
814
+ console.error(`[SyncEngine] ⚠️ Potential conflict detected for ${relativePath}: ${conflictCheck.reason}`);
815
+ this.emit('conflict', { filePath: relativePath, reason: conflictCheck.reason });
816
+ }
817
+ // Extract status from folder path
818
+ const statusFromPath = this.folderStatusMapper.getStatusFromPath(relativePath);
819
+ console.error(`[SyncEngine] ${relativePath} -> status: ${statusFromPath.statusSection} (${statusFromPath.confidence})`);
820
+ // Sync to Commander with retry logic
821
+ const result = await this.syncWithRetry(relativePath);
822
+ // Update both in-memory state and persistent index on success
823
+ if (result.success && result.operation !== 'skip') {
824
+ // Update in-memory state
825
+ this.syncStates.set(relativePath, {
826
+ filePath: relativePath,
827
+ lastSyncedAt: new Date(),
828
+ lastModifiedAt: fileModifiedAt,
829
+ commanderId: result.commanderId || null,
830
+ documentType: result.documentType,
831
+ checksum,
832
+ });
833
+ // Update persistent index
834
+ this.indexManager.updateFileState(relativePath, {
835
+ checksum,
836
+ documentType: result.documentType,
837
+ taskId: parsed.frontmatter.sync?.task_id || result.commanderId || undefined,
838
+ documentId: parsed.frontmatter.sync?.document_id || undefined,
839
+ layerId: parsed.frontmatter.sync?.layer_id || undefined,
840
+ fileModifiedAt,
841
+ });
842
+ }
843
+ return result;
844
+ }
845
+ catch (error) {
846
+ return {
847
+ success: false,
848
+ operation: 'skip',
849
+ documentType: 'document',
850
+ filePath: relativePath,
851
+ message: error instanceof Error ? error.message : String(error),
852
+ error: error instanceof Error ? error.message : String(error),
853
+ };
854
+ }
855
+ }
856
+ /**
857
+ * Get folder status mapper instance
858
+ */
859
+ getFolderStatusMapper() {
860
+ return this.folderStatusMapper;
861
+ }
862
+ /**
863
+ * Check if initial scan is complete
864
+ */
865
+ isInitialScanComplete() {
866
+ return this.initialScanComplete;
867
+ }
868
+ /**
869
+ * Check if engine is running
870
+ */
871
+ isRunning() {
872
+ return this.running;
873
+ }
874
+ }
875
+ //# sourceMappingURL=sync-engine.js.map