@bryanhu/codexly 0.18.0 → 0.19.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 (223) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +4 -0
  3. package/README.zh-CN.md +4 -0
  4. package/dist/chunk-B2673ODM.js +260 -0
  5. package/dist/chunk-GT7XTSEG.js +56 -0
  6. package/dist/{chunk-NROPHBJ7.js → chunk-HMXTAIDF.js} +2467 -4020
  7. package/dist/{chunk-M6GWGUSX.js → chunk-X5JZ3VOF.js} +311 -77
  8. package/dist/{chunk-3PU3WPOK.js → chunk-YFWMYA6X.js} +658 -72
  9. package/dist/{chunk-2O7SN37L.js → chunk-ZUECHB6L.js} +1 -1
  10. package/dist/cli.js +113 -39
  11. package/dist/client/index.js +135 -11
  12. package/dist/core/index.js +1 -1
  13. package/dist/protocol/index.js +2 -1
  14. package/dist/providers/codex/index.js +4 -3
  15. package/dist/runtime-instance-worker.js +19 -0
  16. package/dist/scheduled-task-recurrence-worker.js +2969 -0
  17. package/dist/server/index.js +6 -5
  18. package/dist/sqlite-state-worker.js +156 -13
  19. package/dist/web/.vite/manifest.json +106 -106
  20. package/dist/web/.vite/manifest.json.br +0 -0
  21. package/dist/web/.vite/manifest.json.gz +0 -0
  22. package/dist/web/assets/{agent-settings-panel-BagNBAoe.js → agent-settings-panel-B3hoqvYI.js} +1 -1
  23. package/dist/web/assets/agent-settings-panel-B3hoqvYI.js.br +0 -0
  24. package/dist/web/assets/agent-settings-panel-B3hoqvYI.js.gz +0 -0
  25. package/dist/web/assets/background-image-picker-DV18Olkx.js +1 -0
  26. package/dist/web/assets/background-image-picker-DV18Olkx.js.br +0 -0
  27. package/dist/web/assets/background-image-picker-DV18Olkx.js.gz +0 -0
  28. package/dist/web/assets/{bing-wallpaper-queries-B-1L0OYP.js → bing-wallpaper-queries-CybCDdtr.js} +1 -1
  29. package/dist/web/assets/bing-wallpaper-queries-CybCDdtr.js.br +0 -0
  30. package/dist/web/assets/bing-wallpaper-queries-CybCDdtr.js.gz +0 -0
  31. package/dist/web/assets/{button-group-DIxa2Erp.js → button-group-DLm5MGrs.js} +1 -1
  32. package/dist/web/assets/button-group-DLm5MGrs.js.br +0 -0
  33. package/dist/web/assets/button-group-DLm5MGrs.js.gz +0 -0
  34. package/dist/web/assets/{commit-settings-panel-Co1u5Lzc.js → commit-settings-panel-RS1ax2vB.js} +1 -1
  35. package/dist/web/assets/commit-settings-panel-RS1ax2vB.js.br +0 -0
  36. package/dist/web/assets/commit-settings-panel-RS1ax2vB.js.gz +0 -0
  37. package/dist/web/assets/{context-menu-HaQeWpEd.js → context-menu-DP6ii80r.js} +1 -1
  38. package/dist/web/assets/context-menu-DP6ii80r.js.br +0 -0
  39. package/dist/web/assets/context-menu-DP6ii80r.js.gz +0 -0
  40. package/dist/web/assets/{file-review-dialog-B-0RkLZR.js → file-review-dialog-C3to4N_J.js} +1 -1
  41. package/dist/web/assets/file-review-dialog-C3to4N_J.js.br +0 -0
  42. package/dist/web/assets/file-review-dialog-C3to4N_J.js.gz +0 -0
  43. package/dist/web/assets/{git-history-panel-QiNKxo_n.js → git-history-panel-D2OdQ1Pg.js} +1 -1
  44. package/dist/web/assets/git-history-panel-D2OdQ1Pg.js.br +0 -0
  45. package/dist/web/assets/git-history-panel-D2OdQ1Pg.js.gz +0 -0
  46. package/dist/web/assets/{global-settings-about-DWXfIOas.js → global-settings-about-DYd77AOa.js} +1 -1
  47. package/dist/web/assets/global-settings-about-DYd77AOa.js.br +0 -0
  48. package/dist/web/assets/global-settings-about-DYd77AOa.js.gz +0 -0
  49. package/dist/web/assets/{global-settings-fields-CmEy5pOE.js → global-settings-fields-C0IfL3RQ.js} +1 -1
  50. package/dist/web/assets/global-settings-fields-C0IfL3RQ.js.br +0 -0
  51. package/dist/web/assets/global-settings-fields-C0IfL3RQ.js.gz +0 -0
  52. package/dist/web/assets/global-settings-model-dAGHIcU5.js +1 -0
  53. package/dist/web/assets/global-settings-model-dAGHIcU5.js.br +0 -0
  54. package/dist/web/assets/global-settings-model-dAGHIcU5.js.gz +0 -0
  55. package/dist/web/assets/global-settings-page-746-HK5D.js +2 -0
  56. package/dist/web/assets/global-settings-page-746-HK5D.js.br +0 -0
  57. package/dist/web/assets/global-settings-page-746-HK5D.js.gz +0 -0
  58. package/dist/web/assets/{global-settings-pets-DP2AxhJW.js → global-settings-pets-B6HRYnYq.js} +1 -1
  59. package/dist/web/assets/global-settings-pets-B6HRYnYq.js.br +0 -0
  60. package/dist/web/assets/global-settings-pets-B6HRYnYq.js.gz +0 -0
  61. package/dist/web/assets/{index-BGtID8VJ.css → index-DGp-a5pq.css} +1 -1
  62. package/dist/web/assets/index-DGp-a5pq.css.br +0 -0
  63. package/dist/web/assets/{index-BGtID8VJ.css.gz → index-DGp-a5pq.css.gz} +0 -0
  64. package/dist/web/assets/index-DwEl9mCY.js +4 -0
  65. package/dist/web/assets/index-DwEl9mCY.js.br +0 -0
  66. package/dist/web/assets/index-DwEl9mCY.js.gz +0 -0
  67. package/dist/web/assets/initial-deps-Bk3GSWTk.js +1 -0
  68. package/dist/web/assets/initial-deps-Bk3GSWTk.js.br +0 -0
  69. package/dist/web/assets/initial-deps-Bk3GSWTk.js.gz +0 -0
  70. package/dist/web/assets/installed-skills-pane-Gzaol8-B.js +1 -0
  71. package/dist/web/assets/installed-skills-pane-Gzaol8-B.js.br +0 -0
  72. package/dist/web/assets/installed-skills-pane-Gzaol8-B.js.gz +0 -0
  73. package/dist/web/assets/{lazy-message-response-3Fr_a8du.js → lazy-message-response-CZT51-go.js} +2 -2
  74. package/dist/web/assets/lazy-message-response-CZT51-go.js.br +0 -0
  75. package/dist/web/assets/lazy-message-response-CZT51-go.js.gz +0 -0
  76. package/dist/web/assets/mcp-management-pane-C0g0wk8t.js +1 -0
  77. package/dist/web/assets/mcp-management-pane-C0g0wk8t.js.br +0 -0
  78. package/dist/web/assets/mcp-management-pane-C0g0wk8t.js.gz +0 -0
  79. package/dist/web/assets/{message-response-D3YFwFiE.js → message-response-CA2hanqw.js} +1 -1
  80. package/dist/web/assets/message-response-CA2hanqw.js.br +0 -0
  81. package/dist/web/assets/message-response-CA2hanqw.js.gz +0 -0
  82. package/dist/web/assets/{official-plugins-pane-k8o9gVMR.js → official-plugins-pane-D6kbUBEm.js} +1 -1
  83. package/dist/web/assets/official-plugins-pane-D6kbUBEm.js.br +0 -0
  84. package/dist/web/assets/official-plugins-pane-D6kbUBEm.js.gz +0 -0
  85. package/dist/web/assets/personalization-settings-panel-DnWZEv6V.js +1 -0
  86. package/dist/web/assets/personalization-settings-panel-DnWZEv6V.js.br +0 -0
  87. package/dist/web/assets/personalization-settings-panel-DnWZEv6V.js.gz +0 -0
  88. package/dist/web/assets/{project-file-popup-page-0uRpUcFH.js → project-file-popup-page-C8zcwgkf.js} +1 -1
  89. package/dist/web/assets/project-file-popup-page-C8zcwgkf.js.br +0 -0
  90. package/dist/web/assets/project-file-popup-page-C8zcwgkf.js.gz +0 -0
  91. package/dist/web/assets/{project-source-panel-CEegjNVo.js → project-source-panel-ChVlP72p.js} +2 -2
  92. package/dist/web/assets/project-source-panel-ChVlP72p.js.br +0 -0
  93. package/dist/web/assets/project-source-panel-ChVlP72p.js.gz +0 -0
  94. package/dist/web/assets/{prompt-input-Bs_e51Ey.js → prompt-input-CcovKFMj.js} +1 -1
  95. package/dist/web/assets/prompt-input-CcovKFMj.js.br +0 -0
  96. package/dist/web/assets/prompt-input-CcovKFMj.js.gz +0 -0
  97. package/dist/web/assets/{prompt-input-controls-DMqyvYVY.js → prompt-input-controls-j_r9SnuL.js} +1 -1
  98. package/dist/web/assets/prompt-input-controls-j_r9SnuL.js.br +0 -0
  99. package/dist/web/assets/prompt-input-controls-j_r9SnuL.js.gz +0 -0
  100. package/dist/web/assets/{scheduled-task-date-time-picker-CHc9a7G1.js → scheduled-task-date-time-picker-CkLwYwGu.js} +1 -1
  101. package/dist/web/assets/scheduled-task-date-time-picker-CkLwYwGu.js.br +0 -0
  102. package/dist/web/assets/scheduled-task-date-time-picker-CkLwYwGu.js.gz +0 -0
  103. package/dist/web/assets/{scheduled-task-schedule-2Ugh5sqp.js → scheduled-task-schedule-f0nylWUa.js} +1 -1
  104. package/dist/web/assets/scheduled-task-schedule-f0nylWUa.js.br +0 -0
  105. package/dist/web/assets/scheduled-task-schedule-f0nylWUa.js.gz +0 -0
  106. package/dist/web/assets/scheduled-tasks-container-DxM30EEY.js +2 -0
  107. package/dist/web/assets/scheduled-tasks-container-DxM30EEY.js.br +0 -0
  108. package/dist/web/assets/scheduled-tasks-container-DxM30EEY.js.gz +0 -0
  109. package/dist/web/assets/{settings-personalization-b55VcvKr.js → settings-personalization-CPFvvwt7.js} +1 -1
  110. package/dist/web/assets/settings-personalization-CPFvvwt7.js.br +0 -0
  111. package/dist/web/assets/settings-personalization-CPFvvwt7.js.gz +0 -0
  112. package/dist/web/assets/{sheet-DbEBBgCs.js → sheet-Co357cup.js} +1 -1
  113. package/dist/web/assets/sheet-Co357cup.js.br +0 -0
  114. package/dist/web/assets/sheet-Co357cup.js.gz +0 -0
  115. package/dist/web/assets/{skills-market-container-BwT-U8XF.js → skills-market-container-CJ8k5fIO.js} +2 -2
  116. package/dist/web/assets/skills-market-container-CJ8k5fIO.js.br +0 -0
  117. package/dist/web/assets/skills-market-container-CJ8k5fIO.js.gz +0 -0
  118. package/dist/web/assets/{third-party-marketplace-pane-Cva9dfRn.js → third-party-marketplace-pane-BrosEBTn.js} +1 -1
  119. package/dist/web/assets/third-party-marketplace-pane-BrosEBTn.js.br +0 -0
  120. package/dist/web/assets/third-party-marketplace-pane-BrosEBTn.js.gz +0 -0
  121. package/dist/web/assets/workbench-composer-CxDyu4IJ.js +8 -0
  122. package/dist/web/assets/workbench-composer-CxDyu4IJ.js.br +0 -0
  123. package/dist/web/assets/workbench-composer-CxDyu4IJ.js.gz +0 -0
  124. package/dist/web/assets/workbench-inspector-changes-DXrYXxmV.js +2 -0
  125. package/dist/web/assets/workbench-inspector-changes-DXrYXxmV.js.br +0 -0
  126. package/dist/web/assets/workbench-inspector-changes-DXrYXxmV.js.gz +0 -0
  127. package/dist/web/assets/workbench-pet-canvas-C5NL9nOc.js +1 -0
  128. package/dist/web/assets/workbench-pet-canvas-C5NL9nOc.js.br +0 -0
  129. package/dist/web/assets/workbench-pet-canvas-C5NL9nOc.js.gz +0 -0
  130. package/dist/web/assets/workbench-shell-C3Zu4F9x.js +8 -0
  131. package/dist/web/assets/workbench-shell-C3Zu4F9x.js.br +0 -0
  132. package/dist/web/assets/workbench-shell-C3Zu4F9x.js.gz +0 -0
  133. package/dist/web/index.html +3 -3
  134. package/dist/web/index.html.br +0 -0
  135. package/dist/web/index.html.gz +0 -0
  136. package/package.json +1 -1
  137. package/dist/chunk-RNTA4MFS.js +0 -23
  138. package/dist/web/assets/agent-settings-panel-BagNBAoe.js.br +0 -0
  139. package/dist/web/assets/agent-settings-panel-BagNBAoe.js.gz +0 -0
  140. package/dist/web/assets/background-image-picker-CjpS0dIk.js +0 -1
  141. package/dist/web/assets/background-image-picker-CjpS0dIk.js.br +0 -0
  142. package/dist/web/assets/background-image-picker-CjpS0dIk.js.gz +0 -0
  143. package/dist/web/assets/bing-wallpaper-queries-B-1L0OYP.js.br +0 -0
  144. package/dist/web/assets/bing-wallpaper-queries-B-1L0OYP.js.gz +0 -0
  145. package/dist/web/assets/button-group-DIxa2Erp.js.br +0 -0
  146. package/dist/web/assets/button-group-DIxa2Erp.js.gz +0 -0
  147. package/dist/web/assets/commit-settings-panel-Co1u5Lzc.js.br +0 -0
  148. package/dist/web/assets/commit-settings-panel-Co1u5Lzc.js.gz +0 -0
  149. package/dist/web/assets/context-menu-HaQeWpEd.js.br +0 -0
  150. package/dist/web/assets/context-menu-HaQeWpEd.js.gz +0 -0
  151. package/dist/web/assets/file-review-dialog-B-0RkLZR.js.br +0 -0
  152. package/dist/web/assets/file-review-dialog-B-0RkLZR.js.gz +0 -0
  153. package/dist/web/assets/git-history-panel-QiNKxo_n.js.br +0 -0
  154. package/dist/web/assets/git-history-panel-QiNKxo_n.js.gz +0 -0
  155. package/dist/web/assets/global-settings-about-DWXfIOas.js.br +0 -0
  156. package/dist/web/assets/global-settings-about-DWXfIOas.js.gz +0 -0
  157. package/dist/web/assets/global-settings-fields-CmEy5pOE.js.br +0 -0
  158. package/dist/web/assets/global-settings-fields-CmEy5pOE.js.gz +0 -0
  159. package/dist/web/assets/global-settings-model-B49sZloO.js +0 -1
  160. package/dist/web/assets/global-settings-model-B49sZloO.js.br +0 -0
  161. package/dist/web/assets/global-settings-model-B49sZloO.js.gz +0 -0
  162. package/dist/web/assets/global-settings-page-DKXRkWmd.js +0 -2
  163. package/dist/web/assets/global-settings-page-DKXRkWmd.js.br +0 -0
  164. package/dist/web/assets/global-settings-page-DKXRkWmd.js.gz +0 -0
  165. package/dist/web/assets/global-settings-pets-DP2AxhJW.js.br +0 -0
  166. package/dist/web/assets/global-settings-pets-DP2AxhJW.js.gz +0 -0
  167. package/dist/web/assets/index-BGtID8VJ.css.br +0 -0
  168. package/dist/web/assets/index-mkWzMsjN.js +0 -4
  169. package/dist/web/assets/index-mkWzMsjN.js.br +0 -0
  170. package/dist/web/assets/index-mkWzMsjN.js.gz +0 -0
  171. package/dist/web/assets/initial-deps-CDAJF_GU.js +0 -1
  172. package/dist/web/assets/initial-deps-CDAJF_GU.js.br +0 -0
  173. package/dist/web/assets/initial-deps-CDAJF_GU.js.gz +0 -0
  174. package/dist/web/assets/installed-skills-pane-CR2LbYh9.js +0 -1
  175. package/dist/web/assets/installed-skills-pane-CR2LbYh9.js.br +0 -0
  176. package/dist/web/assets/installed-skills-pane-CR2LbYh9.js.gz +0 -0
  177. package/dist/web/assets/lazy-message-response-3Fr_a8du.js.br +0 -0
  178. package/dist/web/assets/lazy-message-response-3Fr_a8du.js.gz +0 -0
  179. package/dist/web/assets/mcp-management-pane-DEuUn7Y6.js +0 -1
  180. package/dist/web/assets/mcp-management-pane-DEuUn7Y6.js.br +0 -0
  181. package/dist/web/assets/mcp-management-pane-DEuUn7Y6.js.gz +0 -0
  182. package/dist/web/assets/message-response-D3YFwFiE.js.br +0 -0
  183. package/dist/web/assets/message-response-D3YFwFiE.js.gz +0 -0
  184. package/dist/web/assets/official-plugins-pane-k8o9gVMR.js.br +0 -0
  185. package/dist/web/assets/official-plugins-pane-k8o9gVMR.js.gz +0 -0
  186. package/dist/web/assets/personalization-settings-panel-Cl4_Y5Uk.js +0 -1
  187. package/dist/web/assets/personalization-settings-panel-Cl4_Y5Uk.js.br +0 -0
  188. package/dist/web/assets/personalization-settings-panel-Cl4_Y5Uk.js.gz +0 -0
  189. package/dist/web/assets/project-file-popup-page-0uRpUcFH.js.br +0 -0
  190. package/dist/web/assets/project-file-popup-page-0uRpUcFH.js.gz +0 -0
  191. package/dist/web/assets/project-source-panel-CEegjNVo.js.br +0 -0
  192. package/dist/web/assets/project-source-panel-CEegjNVo.js.gz +0 -0
  193. package/dist/web/assets/prompt-input-Bs_e51Ey.js.br +0 -0
  194. package/dist/web/assets/prompt-input-Bs_e51Ey.js.gz +0 -0
  195. package/dist/web/assets/prompt-input-controls-DMqyvYVY.js.br +0 -0
  196. package/dist/web/assets/prompt-input-controls-DMqyvYVY.js.gz +0 -0
  197. package/dist/web/assets/scheduled-task-date-time-picker-CHc9a7G1.js.br +0 -0
  198. package/dist/web/assets/scheduled-task-date-time-picker-CHc9a7G1.js.gz +0 -0
  199. package/dist/web/assets/scheduled-task-schedule-2Ugh5sqp.js.br +0 -0
  200. package/dist/web/assets/scheduled-task-schedule-2Ugh5sqp.js.gz +0 -0
  201. package/dist/web/assets/scheduled-tasks-container-Ddieo85Q.js +0 -2
  202. package/dist/web/assets/scheduled-tasks-container-Ddieo85Q.js.br +0 -0
  203. package/dist/web/assets/scheduled-tasks-container-Ddieo85Q.js.gz +0 -0
  204. package/dist/web/assets/settings-personalization-b55VcvKr.js.br +0 -0
  205. package/dist/web/assets/settings-personalization-b55VcvKr.js.gz +0 -0
  206. package/dist/web/assets/sheet-DbEBBgCs.js.br +0 -0
  207. package/dist/web/assets/sheet-DbEBBgCs.js.gz +0 -0
  208. package/dist/web/assets/skills-market-container-BwT-U8XF.js.br +0 -0
  209. package/dist/web/assets/skills-market-container-BwT-U8XF.js.gz +0 -0
  210. package/dist/web/assets/third-party-marketplace-pane-Cva9dfRn.js.br +0 -0
  211. package/dist/web/assets/third-party-marketplace-pane-Cva9dfRn.js.gz +0 -0
  212. package/dist/web/assets/workbench-composer-BxYlmKUq.js +0 -10
  213. package/dist/web/assets/workbench-composer-BxYlmKUq.js.br +0 -0
  214. package/dist/web/assets/workbench-composer-BxYlmKUq.js.gz +0 -0
  215. package/dist/web/assets/workbench-inspector-changes-DFZ_PDdt.js +0 -2
  216. package/dist/web/assets/workbench-inspector-changes-DFZ_PDdt.js.br +0 -0
  217. package/dist/web/assets/workbench-inspector-changes-DFZ_PDdt.js.gz +0 -0
  218. package/dist/web/assets/workbench-pet-canvas-DwkSGxpw.js +0 -1
  219. package/dist/web/assets/workbench-pet-canvas-DwkSGxpw.js.br +0 -0
  220. package/dist/web/assets/workbench-pet-canvas-DwkSGxpw.js.gz +0 -0
  221. package/dist/web/assets/workbench-shell-CnjG23lI.js +0 -8
  222. package/dist/web/assets/workbench-shell-CnjG23lI.js.br +0 -0
  223. package/dist/web/assets/workbench-shell-CnjG23lI.js.gz +0 -0
package/CHANGELOG.md CHANGED
@@ -4,6 +4,32 @@
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.19.0] - 2026-09-14
8
+
9
+ ### 新增
10
+
11
+ - 添加任务自动标题生成,并支持从运行时配置读取提交信息模型。
12
+ - 添加服务端持久化项目待办、异步问题管理与统一幂等任务提交流程。
13
+ - 添加完整任务目录、完成任务聚合查询、定时任务 Run 导航及归档任务批量删除能力。
14
+
15
+ ### 优化
16
+
17
+ - 让项目、任务、工作树、技能、宠物、队列与 Git 操作直接返回权威状态,减少额外请求并保持客户端缓存一致。
18
+ - 统一实时消息身份和队列调度,折叠回复后的文件修改操作,并优化运行中任务状态展示。
19
+
20
+ ### 修复
21
+
22
+ - 防止并发重命名覆盖文件,为同一数据目录增加随进程退出释放的独占实例锁。
23
+ - 将定时执行接入持久提交恢复,新增 `unknown` 与 `cleanup_pending` 运行状态;保留关联 Task,阻止结果未知时重发,并在重启后仅重试已启动任务的收尾。
24
+ - 移除服务端异常日志中的原始错误内容,修复开发代理的同源写请求及 WebSocket 连接。
25
+ - 提交清空变更后隐藏变更面板并回到第一个标签,保留成功 toast。
26
+ - 安全访问浏览器存储偏好,并强化定时任务事务、RRULE 计算及 Git 文件 I/O 并发控制。
27
+
28
+ ### 工程
29
+
30
+ - 将发布绑定到通过 Linux、Windows E2E 的同一提交,并更新浏览器测试夹具以符合当前变更响应协议。
31
+ - 将首屏 gzip 预算调整为 320 KiB,保留工作台就绪及异步组预算。
32
+
7
33
  ## [0.18.0] - 2026-09-11
8
34
 
9
35
  ### 新增
package/README.md CHANGED
@@ -66,6 +66,8 @@ npx --package @bryanhu/codexly@latest codexly start
66
66
 
67
67
  Codexly opens the browser automatically. If it does not, use the address printed in the terminal; the default is `http://127.0.0.1:3210`. Keep the terminal running and press `Ctrl+C` to stop.
68
68
 
69
+ Only one Codexly instance can use a data directory. The instance lock is released automatically on exit or crash. Use different `--codex-home <directory>` values for independent instances.
70
+
69
71
  On first launch, sign in with ChatGPT or configure an OpenAI-compatible service that supports the Responses API and `GET /models`.
70
72
 
71
73
  For regular use, install Codexly globally:
@@ -83,6 +85,8 @@ Select **New task** for work that does not need a project. For repository work,
83
85
 
84
86
  Task controls set the model, reasoning, Fast mode, approval, and file access behavior. Notification preferences and the last complete project settings are saved for later tasks. The right inspector provides project files, sources, code changes, Git history, review, and commit actions. Project directories and files always come from the computer running Codexly, including when the UI is opened on another device.
85
87
 
88
+ Scheduled tasks with an unknown outcome pause further runs. Inspect the linked conversation before deleting and recreating the schedule. Tasks marked as finishing cleanup retry cleanup automatically without another launch.
89
+
86
90
  ## Local Network Access
87
91
 
88
92
  Start trusted LAN access with:
package/README.zh-CN.md CHANGED
@@ -36,6 +36,8 @@ npx --package @bryanhu/codexly@latest codexly start
36
36
 
37
37
  Codexly 会自动打开浏览器。若未打开,请访问终端输出的地址;默认地址为 `http://127.0.0.1:3210`。使用期间需保持终端运行,按 `Ctrl+C` 停止。
38
38
 
39
+ 同一数据目录只能运行一个 Codexly 实例,重复启动会被拒绝;进程退出或崩溃后自动释放锁。需要独立实例时使用不同的 `--codex-home <目录>`。
40
+
39
41
  首次启动时,使用 ChatGPT 登录,或配置兼容 Responses API 和 `GET /models` 的 OpenAI-compatible 服务。
40
42
 
41
43
  经常使用时可以全局安装:
@@ -53,6 +55,8 @@ codexly
53
55
 
54
56
  任务控件用于设置模型、思考量、快速模式、审批方式和文件访问范围。通知偏好与项目最近一次完整设置会保存给后续任务。右侧检查器提供项目文件、来源、代码变更、Git 历史、审查和提交操作。即使从其他设备打开界面,项目目录和文件仍来自运行 Codexly 的电脑。
55
57
 
58
+ 定时任务显示“结果未知”时会暂停后续运行,请先查看关联对话;确认后可删除该计划并重新创建。“已启动,正在收尾”会自动重试清理,无需再次运行。
59
+
56
60
  ## 局域网访问
57
61
 
58
62
  在可信局域网中启动:
@@ -0,0 +1,260 @@
1
+ import { createRequire } from 'node:module';
2
+
3
+ createRequire(import.meta.url);
4
+
5
+ // packages/core/src/agent-provider.ts
6
+ var WorkbenchPetProviderError = class extends Error {
7
+ constructor(code, message) {
8
+ super(message);
9
+ this.code = code;
10
+ this.name = "WorkbenchPetProviderError";
11
+ }
12
+ code;
13
+ };
14
+ var PendingRequestResolutionError = class extends Error {
15
+ constructor(code, message) {
16
+ super(message);
17
+ this.code = code;
18
+ this.name = "PendingRequestResolutionError";
19
+ }
20
+ code;
21
+ };
22
+
23
+ // packages/core/src/task-submission.ts
24
+ var TaskSubmissionError = class extends Error {
25
+ constructor(code, message) {
26
+ super(message);
27
+ this.code = code;
28
+ }
29
+ code;
30
+ };
31
+ async function submitTask(repository, projectId, key, fingerprint, input, ports) {
32
+ let record = await repository.readSubmission(projectId, key);
33
+ if (record !== void 0 && record.fingerprint !== fingerprint) {
34
+ throw new TaskSubmissionError(
35
+ "IDEMPOTENCY_CONFLICT",
36
+ "Submission key was used with another request"
37
+ );
38
+ }
39
+ if (record?.stage === "creating" || record?.stage === "starting") {
40
+ throw new TaskSubmissionError(
41
+ "SUBMISSION_OUTCOME_UNKNOWN",
42
+ "Submission outcome is unknown; inspect the task before submitting again"
43
+ );
44
+ }
45
+ if (record?.stage === "completed" && record.result !== void 0) return record.result;
46
+ const save = async (next) => {
47
+ await repository.writeSubmission(projectId, key, next);
48
+ record = next;
49
+ };
50
+ if (record?.stage !== "started") {
51
+ await ports.validate();
52
+ if (input.taskId === void 0 && record?.task === void 0) {
53
+ await save({ fingerprint, stage: "creating" });
54
+ const task2 = await ports.createTask();
55
+ await save({ fingerprint, stage: "ready", task: task2 });
56
+ }
57
+ const task = record?.task;
58
+ const taskId = input.taskId ?? task?.id;
59
+ if (taskId === void 0) throw new Error("Submission task is unavailable");
60
+ const attachmentIds = await ports.prepare(taskId);
61
+ await save({
62
+ fingerprint,
63
+ stage: "starting",
64
+ attachmentIds,
65
+ ...task === void 0 ? {} : { task }
66
+ });
67
+ const result2 = {
68
+ ...await ports.execute(taskId),
69
+ ...task === void 0 ? {} : { createdTask: task }
70
+ };
71
+ await save({
72
+ fingerprint,
73
+ stage: "started",
74
+ result: result2,
75
+ attachmentIds,
76
+ ...task === void 0 ? {} : { task }
77
+ });
78
+ }
79
+ const result = record?.result;
80
+ if (result === void 0) throw new Error("Submission result is unavailable");
81
+ await ports.complete(result, record?.attachmentIds ?? []);
82
+ await save({ ...record, fingerprint, stage: "completed", result });
83
+ return result;
84
+ }
85
+
86
+ // packages/core/src/project-todo.ts
87
+ var ProjectTodoError = class extends Error {
88
+ constructor(code, message) {
89
+ super(message);
90
+ this.code = code;
91
+ }
92
+ code;
93
+ };
94
+ async function saveProjectTodo(repository, projectId, id, draft, expectedVersion, now, prepareAttachments) {
95
+ const existing = (await repository.listProjectTodos(projectId)).find((todo2) => todo2.id === id);
96
+ if (expectedVersion !== null && existing === void 0)
97
+ throw new ProjectTodoError("PROJECT_TODO_NOT_FOUND", "Project todo not found");
98
+ if ((existing?.version ?? null) !== expectedVersion)
99
+ throw new ProjectTodoError("PROJECT_TODO_CHANGED", "Project todo changed");
100
+ const todo = {
101
+ id,
102
+ projectId,
103
+ draft,
104
+ createdAt: existing?.createdAt ?? now,
105
+ updatedAt: now,
106
+ version: (existing?.version ?? 0) + 1
107
+ };
108
+ const attachments = await prepareAttachments();
109
+ await repository.saveProjectTodo(todo, expectedVersion, attachments);
110
+ return todo;
111
+ }
112
+
113
+ // packages/core/src/async-question.ts
114
+ function collectQuestionGroups(turns, identify) {
115
+ return turns.flatMap((turn) => {
116
+ const occurrences = /* @__PURE__ */ new Map();
117
+ return turn.items.flatMap((item) => {
118
+ if (item.type !== "message" || item.role !== "assistant" || !item.questions?.length)
119
+ return [];
120
+ const questions = item.questions.map(({ title, options }) => ({ title, options }));
121
+ const signature = JSON.stringify(questions);
122
+ const occurrence = occurrences.get(signature) ?? 0;
123
+ occurrences.set(signature, occurrence + 1);
124
+ return [
125
+ {
126
+ id: identify(JSON.stringify([turn.id, signature, occurrence])),
127
+ turnId: turn.id,
128
+ questions,
129
+ createdAt: turn.startedAt ?? "1970-01-01T00:00:00.000Z",
130
+ status: "pending"
131
+ }
132
+ ];
133
+ });
134
+ });
135
+ }
136
+ function formatQuestionAnswers(questions, answers) {
137
+ if (answers.length !== questions.length || answers.some((answer) => answer.trim().length === 0 || answer.length > 4e3))
138
+ throw new Error("Invalid question answers");
139
+ const text = questions.map((question, index) => `${question.title}
140
+ ${answers[index]?.trim() ?? ""}`).join("\n\n");
141
+ if (text.length > 1e5) throw new Error("Invalid question answers");
142
+ return text;
143
+ }
144
+
145
+ // packages/core/src/archived-task-deletion.ts
146
+ async function deleteArchivedTasks(provider, scopeId) {
147
+ const ids = /* @__PURE__ */ new Set();
148
+ const cursors = /* @__PURE__ */ new Set();
149
+ let cursor;
150
+ for (; ; ) {
151
+ if (cursors.size >= 1e3) throw new Error("Archived task pagination exceeds the page limit");
152
+ const page = await provider.listTasks({
153
+ archived: true,
154
+ limit: 100,
155
+ ...cursor === void 0 ? {} : { cursor }
156
+ });
157
+ for (const task of page.data) {
158
+ if (task.projectId !== scopeId) throw new Error("Archived task listing crossed its scope");
159
+ ids.add(task.id);
160
+ if (ids.size > 1e4) throw new Error("Archived task deletion exceeds the 10000 task limit");
161
+ }
162
+ if (page.nextCursor === null) break;
163
+ if (cursors.has(page.nextCursor))
164
+ throw new Error("Archived task pagination returned a repeated cursor");
165
+ cursors.add(page.nextCursor);
166
+ cursor = page.nextCursor;
167
+ }
168
+ const tasks = [...ids];
169
+ let deletedCount = 0;
170
+ let failedCount = 0;
171
+ for (let index = 0; index < tasks.length; index += 4) {
172
+ const results = await Promise.allSettled(
173
+ tasks.slice(index, index + 4).map(async (id) => {
174
+ const task = await provider.readTask(id);
175
+ if (task?.projectId !== scopeId) throw new Error("Archived task is no longer in scope");
176
+ await provider.deleteTask(id);
177
+ })
178
+ );
179
+ for (const result of results) {
180
+ if (result.status === "fulfilled") deletedCount++;
181
+ else failedCount++;
182
+ }
183
+ }
184
+ return { deletedCount, failedCount };
185
+ }
186
+
187
+ // packages/core/src/task-catalog.ts
188
+ async function listTaskCatalog(provider, scopeId, options = {}) {
189
+ const tasks = /* @__PURE__ */ new Map();
190
+ const cursors = /* @__PURE__ */ new Set();
191
+ let cursor;
192
+ for (; ; ) {
193
+ if (cursors.size >= 1e3) throw new Error("Task catalog pagination exceeds the page limit");
194
+ const page = await provider.listTasks({
195
+ limit: 100,
196
+ ...options.pinned === true ? { pinnedOnly: true } : {},
197
+ ...cursor === void 0 ? {} : { cursor }
198
+ });
199
+ for (const task of page.data) {
200
+ if (task.projectId !== scopeId) throw new Error("Task catalog crossed its scope");
201
+ if (!tasks.has(task.id)) tasks.set(task.id, task);
202
+ if (tasks.size > 1e4) throw new Error("Task catalog exceeds the 10000 task limit");
203
+ }
204
+ if (page.nextCursor === null) return { data: [...tasks.values()] };
205
+ if (cursors.has(page.nextCursor)) throw new Error("Task catalog returned a repeated cursor");
206
+ cursors.add(page.nextCursor);
207
+ cursor = page.nextCursor;
208
+ }
209
+ }
210
+
211
+ // packages/core/src/completed-task-query.ts
212
+ var CompletedTasksQueryError = class extends Error {
213
+ };
214
+ async function queryCompletedTasks(resolve, input) {
215
+ const { projectIds, cursor } = input;
216
+ const scopes = new Set(projectIds);
217
+ if (scopes.size !== projectIds.length || scopes.size > 100)
218
+ throw new CompletedTasksQueryError("Invalid completed task scopes");
219
+ if (cursor !== void 0 && (Object.keys(cursor).length !== scopes.size || Object.keys(cursor).some((id) => !scopes.has(id)))) {
220
+ throw new CompletedTasksQueryError("Completed task cursor does not match its scopes");
221
+ }
222
+ const active = projectIds.filter((id) => cursor === void 0 || cursor[id] !== null);
223
+ const limit = Math.max(1, Math.ceil(10 / Math.max(1, active.length)));
224
+ const cursors = Object.fromEntries(
225
+ projectIds.map((id) => [id, null])
226
+ );
227
+ const tasks = /* @__PURE__ */ new Map();
228
+ for (let index = 0; index < active.length; index += 4) {
229
+ const pages = await Promise.all(
230
+ active.slice(index, index + 4).map(async (id) => {
231
+ const provider = await resolve(id);
232
+ const previous = cursor?.[id];
233
+ const page = await provider.listTasks({
234
+ completed: true,
235
+ limit,
236
+ ...typeof previous === "string" ? { cursor: previous } : {}
237
+ });
238
+ if (page.data.length > limit) throw new Error("Completed task page exceeds its limit");
239
+ if (page.nextCursor !== null && page.nextCursor === previous)
240
+ throw new Error("Completed task page returned a repeated cursor");
241
+ for (const task of page.data)
242
+ if (task.projectId !== id) throw new Error("Completed task page crossed its scope");
243
+ return { id, page };
244
+ })
245
+ );
246
+ for (const { id, page } of pages) {
247
+ cursors[id] = page.nextCursor;
248
+ for (const task of page.data) {
249
+ const key = JSON.stringify([id, task.id]);
250
+ if (!tasks.has(key)) tasks.set(key, task);
251
+ }
252
+ }
253
+ }
254
+ return {
255
+ data: [...tasks.values()].sort((a, b) => Date.parse(b.updatedAt) - Date.parse(a.updatedAt)),
256
+ nextCursor: Object.values(cursors).some((value) => value !== null) ? cursors : null
257
+ };
258
+ }
259
+
260
+ export { CompletedTasksQueryError, PendingRequestResolutionError, ProjectTodoError, TaskSubmissionError, WorkbenchPetProviderError, collectQuestionGroups, deleteArchivedTasks, formatQuestionAnswers, listTaskCatalog, queryCompletedTasks, saveProjectTodo, submitTask };
@@ -0,0 +1,56 @@
1
+ import { createRequire } from 'node:module';
2
+ import { __export } from './chunk-K6J42667.js';
3
+
4
+ createRequire(import.meta.url);
5
+
6
+ // packages/protocol/src/scheduled-task-wall-time.ts
7
+ var scheduled_task_wall_time_exports = {};
8
+ __export(scheduled_task_wall_time_exports, {
9
+ wallTimeToUnix: () => wallTimeToUnix,
10
+ zonedDateTime: () => zonedDateTime
11
+ });
12
+ var cachedTimezone = "";
13
+ var cachedFormatter;
14
+ function zonedDateTime(unixMs, timezone) {
15
+ if (cachedTimezone !== timezone) {
16
+ cachedFormatter = new Intl.DateTimeFormat("sv-SE", {
17
+ timeZone: timezone,
18
+ year: "numeric",
19
+ month: "2-digit",
20
+ day: "2-digit",
21
+ hour: "2-digit",
22
+ minute: "2-digit",
23
+ second: "2-digit",
24
+ hourCycle: "h23"
25
+ });
26
+ cachedTimezone = timezone;
27
+ }
28
+ const parts = cachedFormatter.formatToParts(unixMs);
29
+ const part = (type) => {
30
+ const value = parts.find((item) => item.type === type)?.value;
31
+ if (value === void 0) throw new Error(`Missing date part: ${type}`);
32
+ return value;
33
+ };
34
+ return `${part("year")}-${part("month")}-${part("day")}T${part("hour")}:${part("minute")}:${part("second")}`;
35
+ }
36
+ function wallTimeToUnix(value, timezone) {
37
+ if (!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(:\d{2})?$/u.test(value)) return void 0;
38
+ const normalized = value.length === 16 ? `${value}:00` : value;
39
+ const wall = Date.parse(`${normalized}Z`);
40
+ if (!Number.isFinite(wall) || new Date(wall).toISOString().slice(0, 19) !== normalized)
41
+ return void 0;
42
+ if (timezone === "UTC") return wall;
43
+ try {
44
+ let candidate = wall;
45
+ for (let attempt = 0; attempt < 3; attempt++) {
46
+ const formatted = zonedDateTime(candidate, timezone);
47
+ if (formatted === normalized) return candidate;
48
+ candidate += wall - Date.parse(`${formatted}Z`);
49
+ }
50
+ } catch {
51
+ return void 0;
52
+ }
53
+ return void 0;
54
+ }
55
+
56
+ export { scheduled_task_wall_time_exports, wallTimeToUnix, zonedDateTime };