dominds 1.24.4 → 1.25.1

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 (182) hide show
  1. package/README.md +48 -1
  2. package/README.zh.md +48 -1
  3. package/dist/cli.d.ts +1 -0
  4. package/dist/cli.js +22 -0
  5. package/dist/dialog-display-state.d.ts +4 -4
  6. package/dist/dialog-display-state.js +28 -10
  7. package/dist/dialog-drive-work.js +5 -0
  8. package/dist/dialog-global-registry.d.ts +9 -8
  9. package/dist/dialog-global-registry.js +39 -38
  10. package/dist/dialog-instance-registry.js +7 -0
  11. package/dist/dialog-interruption.d.ts +2 -0
  12. package/dist/dialog-interruption.js +6 -0
  13. package/dist/dialog.d.ts +9 -9
  14. package/dist/dialog.js +82 -56
  15. package/dist/docs/design.md +4 -0
  16. package/dist/docs/design.zh.md +4 -0
  17. package/dist/docs/dialog-system.md +7 -7
  18. package/dist/docs/dialog-system.zh.md +4 -4
  19. package/dist/docs/dlg-drive-algo.zh.md +544 -0
  20. package/dist/docs/roadmap.md +2 -0
  21. package/dist/docs/roadmap.zh.md +2 -0
  22. package/dist/llm/gen/mock.d.ts +2 -2
  23. package/dist/llm/gen/mock.js +2 -2
  24. package/dist/llm/kernel-driver/drive.js +100 -101
  25. package/dist/llm/kernel-driver/engine.d.ts +1 -1
  26. package/dist/llm/kernel-driver/flow.js +687 -205
  27. package/dist/llm/kernel-driver/idle-reminder-wake.js +1 -1
  28. package/dist/llm/kernel-driver/loop.js +131 -61
  29. package/dist/llm/kernel-driver/runtime.js +1 -1
  30. package/dist/llm/kernel-driver/sideDialog.d.ts +1 -1
  31. package/dist/llm/kernel-driver/sideDialog.js +21 -15
  32. package/dist/llm/kernel-driver/tellask-special.js +25 -29
  33. package/dist/llm/kernel-driver/types.d.ts +7 -28
  34. package/dist/llm/kernel-driver/types.js +0 -1
  35. package/dist/minds/system-prompt-parts.js +4 -4
  36. package/dist/persistence-errors.d.ts +1 -1
  37. package/dist/persistence.d.ts +61 -25
  38. package/dist/persistence.js +658 -342
  39. package/dist/priming.js +116 -35
  40. package/dist/recovery/open-generation-recovery.d.ts +1 -0
  41. package/dist/recovery/{proceeding-drive.js → open-generation-recovery.js} +25 -25
  42. package/dist/recovery/reply-delivery-recovery.d.ts +3 -0
  43. package/dist/recovery/{reply-special.js → reply-delivery-recovery.js} +12 -12
  44. package/dist/runtime/driver-messages.d.ts +1 -1
  45. package/dist/runtime/driver-messages.js +37 -19
  46. package/dist/server/api-routes.js +18 -0
  47. package/dist/server/server-core.d.ts +1 -0
  48. package/dist/server/server-core.js +11 -0
  49. package/dist/server/websocket-handler.js +6 -5
  50. package/dist/server.js +4 -4
  51. package/dist/shared-reminders.d.ts +11 -3
  52. package/dist/shared-reminders.js +62 -34
  53. package/dist/tool.d.ts +1 -1
  54. package/dist/tool.js +1 -1
  55. package/dist/tools/app-reminders.js +8 -2
  56. package/dist/tools/builtins.js +4 -2
  57. package/dist/tools/ctrl.js +34 -109
  58. package/dist/tools/os.js +6 -6
  59. package/dist/tools/prompts/control/en/errors.md +5 -19
  60. package/dist/tools/prompts/control/en/index.md +5 -4
  61. package/dist/tools/prompts/control/en/principles.md +23 -19
  62. package/dist/tools/prompts/control/en/scenarios.md +17 -11
  63. package/dist/tools/prompts/control/en/tools.md +4 -6
  64. package/dist/tools/prompts/control/zh/errors.md +5 -19
  65. package/dist/tools/prompts/control/zh/index.md +5 -4
  66. package/dist/tools/prompts/control/zh/principles.md +22 -19
  67. package/dist/tools/prompts/control/zh/scenarios.md +17 -11
  68. package/dist/tools/prompts/control/zh/tools.md +4 -6
  69. package/dist/tools/prompts/personal_memory/en/index.md +1 -1
  70. package/dist/tools/prompts/personal_memory/en/principles.md +2 -2
  71. package/dist/tools/prompts/personal_memory/zh/index.md +1 -1
  72. package/dist/tools/prompts/personal_memory/zh/principles.md +2 -2
  73. package/dist/tools/prompts/skills/en/errors.md +2 -0
  74. package/dist/tools/prompts/skills/en/index.md +1 -0
  75. package/dist/tools/prompts/skills/en/tools.md +6 -0
  76. package/dist/tools/prompts/skills/zh/errors.md +2 -0
  77. package/dist/tools/prompts/skills/zh/index.md +1 -0
  78. package/dist/tools/prompts/skills/zh/tools.md +6 -0
  79. package/dist/tools/ripgrep.js +386 -44
  80. package/dist/tools/skills.d.ts +1 -0
  81. package/dist/tools/skills.js +81 -1
  82. package/dist/tools/team_mgmt.js +46 -10
  83. package/package.json +5 -5
  84. package/webapp/dist/assets/{_basePickBy-ZLV93S3E.js → _basePickBy-CG55qWp2.js} +3 -3
  85. package/webapp/dist/assets/{_basePickBy-ZLV93S3E.js.map → _basePickBy-CG55qWp2.js.map} +1 -1
  86. package/webapp/dist/assets/{_baseUniq-D0wSOJ06.js → _baseUniq-Dd4UGB2O.js} +2 -2
  87. package/webapp/dist/assets/{_baseUniq-D0wSOJ06.js.map → _baseUniq-Dd4UGB2O.js.map} +1 -1
  88. package/webapp/dist/assets/{arc-BHclbMTS.js → arc-C2qiF4r3.js} +2 -2
  89. package/webapp/dist/assets/{arc-BHclbMTS.js.map → arc-C2qiF4r3.js.map} +1 -1
  90. package/webapp/dist/assets/{architectureDiagram-2XIMDMQ5-CK99gE_D.js → architectureDiagram-2XIMDMQ5-DQ4Z8fy_.js} +7 -7
  91. package/webapp/dist/assets/{architectureDiagram-2XIMDMQ5-CK99gE_D.js.map → architectureDiagram-2XIMDMQ5-DQ4Z8fy_.js.map} +1 -1
  92. package/webapp/dist/assets/{blockDiagram-WCTKOSBZ-fE5MBTEU.js → blockDiagram-WCTKOSBZ-CPvOuMZA.js} +7 -7
  93. package/webapp/dist/assets/{blockDiagram-WCTKOSBZ-fE5MBTEU.js.map → blockDiagram-WCTKOSBZ-CPvOuMZA.js.map} +1 -1
  94. package/webapp/dist/assets/{c4Diagram-IC4MRINW-BSLyPyoU.js → c4Diagram-IC4MRINW-DElaFpnJ.js} +3 -3
  95. package/webapp/dist/assets/{c4Diagram-IC4MRINW-BSLyPyoU.js.map → c4Diagram-IC4MRINW-DElaFpnJ.js.map} +1 -1
  96. package/webapp/dist/assets/{channel-DSvMpp-a.js → channel-BR7mZa90.js} +2 -2
  97. package/webapp/dist/assets/{channel-DSvMpp-a.js.map → channel-BR7mZa90.js.map} +1 -1
  98. package/webapp/dist/assets/{chunk-4BX2VUAB-OXEX170k.js → chunk-4BX2VUAB-DTmXCBYX.js} +2 -2
  99. package/webapp/dist/assets/{chunk-4BX2VUAB-OXEX170k.js.map → chunk-4BX2VUAB-DTmXCBYX.js.map} +1 -1
  100. package/webapp/dist/assets/{chunk-55IACEB6-BFQ_spQD.js → chunk-55IACEB6-DeBB4aJ4.js} +2 -2
  101. package/webapp/dist/assets/{chunk-55IACEB6-BFQ_spQD.js.map → chunk-55IACEB6-DeBB4aJ4.js.map} +1 -1
  102. package/webapp/dist/assets/{chunk-FMBD7UC4-CbQ2BBPs.js → chunk-FMBD7UC4-CXpgeev4.js} +2 -2
  103. package/webapp/dist/assets/{chunk-FMBD7UC4-CbQ2BBPs.js.map → chunk-FMBD7UC4-CXpgeev4.js.map} +1 -1
  104. package/webapp/dist/assets/{chunk-JSJVCQXG-C4P1mjCL.js → chunk-JSJVCQXG-DWfckfhO.js} +2 -2
  105. package/webapp/dist/assets/{chunk-JSJVCQXG-C4P1mjCL.js.map → chunk-JSJVCQXG-DWfckfhO.js.map} +1 -1
  106. package/webapp/dist/assets/{chunk-KX2RTZJC-BMd-daMY.js → chunk-KX2RTZJC-DWG_wpHB.js} +2 -2
  107. package/webapp/dist/assets/{chunk-KX2RTZJC-BMd-daMY.js.map → chunk-KX2RTZJC-DWG_wpHB.js.map} +1 -1
  108. package/webapp/dist/assets/{chunk-NQ4KR5QH-B_ZhWMXR.js → chunk-NQ4KR5QH-DRcsqoac.js} +4 -4
  109. package/webapp/dist/assets/{chunk-NQ4KR5QH-B_ZhWMXR.js.map → chunk-NQ4KR5QH-DRcsqoac.js.map} +1 -1
  110. package/webapp/dist/assets/{chunk-QZHKN3VN-Cbf92xIw.js → chunk-QZHKN3VN-B9GPAJ2s.js} +2 -2
  111. package/webapp/dist/assets/{chunk-QZHKN3VN-Cbf92xIw.js.map → chunk-QZHKN3VN-B9GPAJ2s.js.map} +1 -1
  112. package/webapp/dist/assets/{chunk-WL4C6EOR-PtH-blkK.js → chunk-WL4C6EOR-V3Fq1ULq.js} +6 -6
  113. package/webapp/dist/assets/{chunk-WL4C6EOR-PtH-blkK.js.map → chunk-WL4C6EOR-V3Fq1ULq.js.map} +1 -1
  114. package/webapp/dist/assets/{classDiagram-VBA2DB6C-Dc3ncaD0.js → classDiagram-VBA2DB6C-DspG486Z.js} +7 -7
  115. package/webapp/dist/assets/{classDiagram-VBA2DB6C-Dc3ncaD0.js.map → classDiagram-VBA2DB6C-DspG486Z.js.map} +1 -1
  116. package/webapp/dist/assets/{classDiagram-v2-RAHNMMFH-Dc3ncaD0.js → classDiagram-v2-RAHNMMFH-DspG486Z.js} +7 -7
  117. package/webapp/dist/assets/{classDiagram-v2-RAHNMMFH-Dc3ncaD0.js.map → classDiagram-v2-RAHNMMFH-DspG486Z.js.map} +1 -1
  118. package/webapp/dist/assets/{clone-E9Ad85BC.js → clone-M8ztABN5.js} +2 -2
  119. package/webapp/dist/assets/{clone-E9Ad85BC.js.map → clone-M8ztABN5.js.map} +1 -1
  120. package/webapp/dist/assets/{cose-bilkent-S5V4N54A-B-nj0o74.js → cose-bilkent-S5V4N54A-DZihobe3.js} +2 -2
  121. package/webapp/dist/assets/{cose-bilkent-S5V4N54A-B-nj0o74.js.map → cose-bilkent-S5V4N54A-DZihobe3.js.map} +1 -1
  122. package/webapp/dist/assets/{dagre-KLK3FWXG-CyJYNIbm.js → dagre-KLK3FWXG-DBLWy3vi.js} +7 -7
  123. package/webapp/dist/assets/{dagre-KLK3FWXG-CyJYNIbm.js.map → dagre-KLK3FWXG-DBLWy3vi.js.map} +1 -1
  124. package/webapp/dist/assets/{diagram-E7M64L7V-C8eweQ7b.js → diagram-E7M64L7V-D7IrPWaY.js} +8 -8
  125. package/webapp/dist/assets/{diagram-E7M64L7V-C8eweQ7b.js.map → diagram-E7M64L7V-D7IrPWaY.js.map} +1 -1
  126. package/webapp/dist/assets/{diagram-IFDJBPK2-DMdygRl0.js → diagram-IFDJBPK2-DbF-vN3U.js} +7 -7
  127. package/webapp/dist/assets/{diagram-IFDJBPK2-DMdygRl0.js.map → diagram-IFDJBPK2-DbF-vN3U.js.map} +1 -1
  128. package/webapp/dist/assets/{diagram-P4PSJMXO-BQDZHb0a.js → diagram-P4PSJMXO-BxBVRVaM.js} +7 -7
  129. package/webapp/dist/assets/{diagram-P4PSJMXO-BQDZHb0a.js.map → diagram-P4PSJMXO-BxBVRVaM.js.map} +1 -1
  130. package/webapp/dist/assets/{erDiagram-INFDFZHY-C1HaXN6E.js → erDiagram-INFDFZHY-ny9JoOhV.js} +5 -5
  131. package/webapp/dist/assets/{erDiagram-INFDFZHY-C1HaXN6E.js.map → erDiagram-INFDFZHY-ny9JoOhV.js.map} +1 -1
  132. package/webapp/dist/assets/{flowDiagram-PKNHOUZH-24nNqQyo.js → flowDiagram-PKNHOUZH-BMgWUlvY.js} +7 -7
  133. package/webapp/dist/assets/{flowDiagram-PKNHOUZH-24nNqQyo.js.map → flowDiagram-PKNHOUZH-BMgWUlvY.js.map} +1 -1
  134. package/webapp/dist/assets/{ganttDiagram-A5KZAMGK-BWPOFaLV.js → ganttDiagram-A5KZAMGK-CCYpj3PM.js} +3 -3
  135. package/webapp/dist/assets/{ganttDiagram-A5KZAMGK-BWPOFaLV.js.map → ganttDiagram-A5KZAMGK-CCYpj3PM.js.map} +1 -1
  136. package/webapp/dist/assets/{gitGraphDiagram-K3NZZRJ6-D7_L-p_Y.js → gitGraphDiagram-K3NZZRJ6-BFJGaDtk.js} +8 -8
  137. package/webapp/dist/assets/{gitGraphDiagram-K3NZZRJ6-D7_L-p_Y.js.map → gitGraphDiagram-K3NZZRJ6-BFJGaDtk.js.map} +1 -1
  138. package/webapp/dist/assets/{graph-OHu4dL2n.js → graph-Cp0m7fHH.js} +3 -3
  139. package/webapp/dist/assets/{graph-OHu4dL2n.js.map → graph-Cp0m7fHH.js.map} +1 -1
  140. package/webapp/dist/assets/{index-CDCDAfqP.js → index-EvfDN91D.js} +63 -46
  141. package/webapp/dist/assets/{index-CDCDAfqP.js.map → index-EvfDN91D.js.map} +1 -1
  142. package/webapp/dist/assets/{infoDiagram-LFFYTUFH-CvaBM5j6.js → infoDiagram-LFFYTUFH-Dnve0aOc.js} +6 -6
  143. package/webapp/dist/assets/{infoDiagram-LFFYTUFH-CvaBM5j6.js.map → infoDiagram-LFFYTUFH-Dnve0aOc.js.map} +1 -1
  144. package/webapp/dist/assets/{ishikawaDiagram-PHBUUO56-DB1l2Uue.js → ishikawaDiagram-PHBUUO56-DkSZM5sz.js} +2 -2
  145. package/webapp/dist/assets/{ishikawaDiagram-PHBUUO56-DB1l2Uue.js.map → ishikawaDiagram-PHBUUO56-DkSZM5sz.js.map} +1 -1
  146. package/webapp/dist/assets/{journeyDiagram-4ABVD52K-TQR6_teO.js → journeyDiagram-4ABVD52K-D8_2EbDV.js} +5 -5
  147. package/webapp/dist/assets/{journeyDiagram-4ABVD52K-TQR6_teO.js.map → journeyDiagram-4ABVD52K-D8_2EbDV.js.map} +1 -1
  148. package/webapp/dist/assets/{kanban-definition-K7BYSVSG-B-BOuC-U.js → kanban-definition-K7BYSVSG-BdmMXQQk.js} +3 -3
  149. package/webapp/dist/assets/{kanban-definition-K7BYSVSG-B-BOuC-U.js.map → kanban-definition-K7BYSVSG-BdmMXQQk.js.map} +1 -1
  150. package/webapp/dist/assets/{layout-B8yqIqbx.js → layout-3tA84hoP.js} +5 -5
  151. package/webapp/dist/assets/{layout-B8yqIqbx.js.map → layout-3tA84hoP.js.map} +1 -1
  152. package/webapp/dist/assets/{linear-CoLfiZKK.js → linear-CpN6Japh.js} +2 -2
  153. package/webapp/dist/assets/{linear-CoLfiZKK.js.map → linear-CpN6Japh.js.map} +1 -1
  154. package/webapp/dist/assets/{mindmap-definition-YRQLILUH-P70BMIHI.js → mindmap-definition-YRQLILUH-HiYNz7qL.js} +4 -4
  155. package/webapp/dist/assets/{mindmap-definition-YRQLILUH-P70BMIHI.js.map → mindmap-definition-YRQLILUH-HiYNz7qL.js.map} +1 -1
  156. package/webapp/dist/assets/{pieDiagram-SKSYHLDU-DsS_4dTB.js → pieDiagram-SKSYHLDU-DCVp50CX.js} +8 -8
  157. package/webapp/dist/assets/{pieDiagram-SKSYHLDU-DsS_4dTB.js.map → pieDiagram-SKSYHLDU-DCVp50CX.js.map} +1 -1
  158. package/webapp/dist/assets/{quadrantDiagram-337W2JSQ-DoM9PEq-.js → quadrantDiagram-337W2JSQ-CCX7dwY0.js} +3 -3
  159. package/webapp/dist/assets/{quadrantDiagram-337W2JSQ-DoM9PEq-.js.map → quadrantDiagram-337W2JSQ-CCX7dwY0.js.map} +1 -1
  160. package/webapp/dist/assets/{requirementDiagram-Z7DCOOCP-Bn3lYMMI.js → requirementDiagram-Z7DCOOCP-Cba7jjkf.js} +4 -4
  161. package/webapp/dist/assets/{requirementDiagram-Z7DCOOCP-Bn3lYMMI.js.map → requirementDiagram-Z7DCOOCP-Cba7jjkf.js.map} +1 -1
  162. package/webapp/dist/assets/{sankeyDiagram-WA2Y5GQK-97kCegRT.js → sankeyDiagram-WA2Y5GQK-Bz4iUubD.js} +2 -2
  163. package/webapp/dist/assets/{sankeyDiagram-WA2Y5GQK-97kCegRT.js.map → sankeyDiagram-WA2Y5GQK-Bz4iUubD.js.map} +1 -1
  164. package/webapp/dist/assets/{sequenceDiagram-2WXFIKYE-DXqjQjf6.js → sequenceDiagram-2WXFIKYE-DsFI9bic.js} +4 -4
  165. package/webapp/dist/assets/{sequenceDiagram-2WXFIKYE-DXqjQjf6.js.map → sequenceDiagram-2WXFIKYE-DsFI9bic.js.map} +1 -1
  166. package/webapp/dist/assets/{stateDiagram-RAJIS63D-DQcTPKWP.js → stateDiagram-RAJIS63D-DLv9OSg4.js} +9 -9
  167. package/webapp/dist/assets/{stateDiagram-RAJIS63D-DQcTPKWP.js.map → stateDiagram-RAJIS63D-DLv9OSg4.js.map} +1 -1
  168. package/webapp/dist/assets/{stateDiagram-v2-FVOUBMTO-DHmxRVJn.js → stateDiagram-v2-FVOUBMTO-DVlwzCvy.js} +5 -5
  169. package/webapp/dist/assets/{stateDiagram-v2-FVOUBMTO-DHmxRVJn.js.map → stateDiagram-v2-FVOUBMTO-DVlwzCvy.js.map} +1 -1
  170. package/webapp/dist/assets/{timeline-definition-YZTLITO2-BlovQQ4B.js → timeline-definition-YZTLITO2-DnKbq6n0.js} +3 -3
  171. package/webapp/dist/assets/{timeline-definition-YZTLITO2-BlovQQ4B.js.map → timeline-definition-YZTLITO2-DnKbq6n0.js.map} +1 -1
  172. package/webapp/dist/assets/{treemap-KZPCXAKY-CGu93c9S.js → treemap-KZPCXAKY-D9fYHZ__.js} +5 -5
  173. package/webapp/dist/assets/{treemap-KZPCXAKY-CGu93c9S.js.map → treemap-KZPCXAKY-D9fYHZ__.js.map} +1 -1
  174. package/webapp/dist/assets/{vennDiagram-LZ73GAT5-Do1jprrz.js → vennDiagram-LZ73GAT5-CzKI47Ba.js} +2 -2
  175. package/webapp/dist/assets/{vennDiagram-LZ73GAT5-Do1jprrz.js.map → vennDiagram-LZ73GAT5-CzKI47Ba.js.map} +1 -1
  176. package/webapp/dist/assets/{xychartDiagram-JWTSCODW-BKa1DxVq.js → xychartDiagram-JWTSCODW-Bt-gKvam.js} +3 -3
  177. package/webapp/dist/assets/{xychartDiagram-JWTSCODW-BKa1DxVq.js.map → xychartDiagram-JWTSCODW-Bt-gKvam.js.map} +1 -1
  178. package/webapp/dist/index.html +1 -1
  179. package/dist/docs/issues/tellask-background-continuation-live-bugs-2026-05-17.zh.md +0 -101
  180. package/dist/docs/tellask-background-continuation-refactor.zh.md +0 -1146
  181. package/dist/recovery/proceeding-drive.d.ts +0 -1
  182. package/dist/recovery/reply-special.d.ts +0 -3
package/README.md CHANGED
@@ -69,7 +69,7 @@ Dominds is an AI-powered DevOps framework that creates autonomous agentic teams
69
69
 
70
70
  ### Prerequisites
71
71
 
72
- - **Node.js (with npm bundled)**: Version 24.x LTS
72
+ - **Node.js (with npm bundled)**: Version 24.5+ LTS
73
73
  - **npm (if used directly)**: Use the npm bundled with your installed Node.js 24 LTS; current minimum in this repo is `11.9.0`, and newer versions are allowed.
74
74
  - **LLM provider configured for your team**: Dominds ships with a built-in provider catalog [main/llm/defaults.yaml](./main/llm/defaults.yaml) including Codex (ChatGPT) and Anthropic, plus several Anthropic-compatible endpoints (e.g. MiniMax, Z.ai, BigModel). You’ll need valid credentials for at least one provider.
75
75
  - **pnpm (optional)**: Recommended only if you’re developing Dominds itself. Prefer enabling the pinned CLI once via `npm run setup:pm`. If Corepack shims cannot be enabled in your environment, install `pnpm@10` manually.
@@ -80,6 +80,53 @@ For repo development, initialize the package manager once after `nvm use --lts`:
80
80
  npm run setup:pm
81
81
  ```
82
82
 
83
+ ### Proxy Support
84
+
85
+ Dominds can use Node's built-in environment proxy handling on Windows, macOS, and Linux.
86
+
87
+ Default behavior:
88
+
89
+ - `DOMINDS_USE_ENV_PROXY` is enabled by default.
90
+ - When enabled, Dominds calls Node's runtime env-proxy initializer early in CLI startup.
91
+ - Dominds does not set or clear `NODE_USE_ENV_PROXY`; leave that variable for users who intentionally want Node startup-time or child-process behavior.
92
+ - Set `DOMINDS_USE_ENV_PROXY=0` to stop Dominds from auto-enabling env-proxy support.
93
+
94
+ Supported proxy variables:
95
+
96
+ - `HTTP_PROXY`
97
+ - `HTTPS_PROXY`
98
+ - `NO_PROXY`
99
+ - `http_proxy`
100
+ - `https_proxy`
101
+ - `no_proxy`
102
+
103
+ Practical guidance:
104
+
105
+ - Set both `HTTP_PROXY` and `HTTPS_PROXY` when your network uses the same proxy for both schemes. Lowercase forms also work.
106
+ - Use `NO_PROXY` for localhost, loopback, and internal domains that should bypass the proxy.
107
+ - Values should be standard proxy URLs, for example `http://proxy.company.com:8080`.
108
+ - If your shell already exports proxy variables, Dominds will read them too; clear unrelated proxy vars if you want a clean test environment.
109
+
110
+ Examples:
111
+
112
+ ```bash
113
+ # Windows PowerShell
114
+ $env:HTTP_PROXY = "http://proxy.company.com:8080"
115
+ $env:HTTPS_PROXY = "http://proxy.company.com:8080"
116
+ $env:NO_PROXY = "localhost,127.0.0.1,.corp.local"
117
+ dominds
118
+
119
+ # macOS / Linux shell
120
+ export HTTP_PROXY="http://proxy.company.com:8080"
121
+ export HTTPS_PROXY="http://proxy.company.com:8080"
122
+ export NO_PROXY="localhost,127.0.0.1,.corp.local"
123
+ dominds
124
+
125
+ # Disable Dominds env-proxy handling
126
+ export DOMINDS_USE_ENV_PROXY=0
127
+ dominds
128
+ ```
129
+
83
130
  ### Install Dominds
84
131
 
85
132
  ```bash
package/README.zh.md CHANGED
@@ -23,7 +23,7 @@ Dominds 是一款面向开发运作(DevOps)场景的智能体框架,它将
23
23
 
24
24
  ### 环境要求
25
25
 
26
- - **Node.js(含 npm)**:版本 24.x LTS
26
+ - **Node.js(含 npm)**:版本 24.5+ LTS
27
27
  - **npm(如直接使用)**:使用当前安装的 Node.js 24 LTS 自带 npm;本仓库当前最低要求为 `11.9.0`,更高版本也允许。
28
28
  - **至少一个可用的 LLM 服务提供商**:Dominds 内置提供商目录(路径:[main/llm/defaults.yaml](./main/llm/defaults.yaml)),需为其中至少一个提供商配置有效凭证(通过环境变量设置)。
29
29
  - **pnpm(可选)**:仅在开发 Dominds 本体时推荐使用。优先执行一次 `npm run setup:pm` 启用并缓存仓库固定的 pnpm;若你的环境无法启用 Corepack shim,再手动安装 `pnpm@10`。
@@ -34,6 +34,53 @@ Dominds 是一款面向开发运作(DevOps)场景的智能体框架,它将
34
34
  npm run setup:pm
35
35
  ```
36
36
 
37
+ ### 代理支持
38
+
39
+ Dominds 在 Windows、macOS、Linux 上都可以使用 Node 内建的环境变量代理能力。
40
+
41
+ 默认行为:
42
+
43
+ - `DOMINDS_USE_ENV_PROXY` 默认启用。
44
+ - 启用后,Dominds 会在 CLI 启动早期调用 Node 的运行时环境代理初始化。
45
+ - Dominds 不会设置或清理 `NODE_USE_ENV_PROXY`;这个变量留给确实需要 Node 启动期行为或子进程继承语义的用户自己管理。
46
+ - 若要让 Dominds 不再自动开启环境代理支持,设置 `DOMINDS_USE_ENV_PROXY=0`。
47
+
48
+ 支持的代理变量:
49
+
50
+ - `HTTP_PROXY`
51
+ - `HTTPS_PROXY`
52
+ - `NO_PROXY`
53
+ - `http_proxy`
54
+ - `https_proxy`
55
+ - `no_proxy`
56
+
57
+ 实践建议:
58
+
59
+ - 若同一网络对 HTTP/HTTPS 都走同一代理,建议 `HTTP_PROXY` 和 `HTTPS_PROXY` 一起设置。小写变量名同样有效。
60
+ - `NO_PROXY` 用于排除 localhost、回环地址和内网域名。
61
+ - 代理值应使用标准 URL 形式,例如 `http://proxy.company.com:8080`。
62
+ - 如果你的 shell 已经导出了代理变量,Dominds 也会读取它们;想要干净的测试环境时,请清掉无关的代理变量。
63
+
64
+ 示例:
65
+
66
+ ```bash
67
+ # Windows PowerShell
68
+ $env:HTTP_PROXY = "http://proxy.company.com:8080"
69
+ $env:HTTPS_PROXY = "http://proxy.company.com:8080"
70
+ $env:NO_PROXY = "localhost,127.0.0.1,.corp.local"
71
+ dominds
72
+
73
+ # macOS / Linux shell
74
+ export HTTP_PROXY="http://proxy.company.com:8080"
75
+ export HTTPS_PROXY="http://proxy.company.com:8080"
76
+ export NO_PROXY="localhost,127.0.0.1,.corp.local"
77
+ dominds
78
+
79
+ # 关闭 Dominds 的环境代理支持
80
+ export DOMINDS_USE_ENV_PROXY=0
81
+ dominds
82
+ ```
83
+
37
84
  ### 安装 Dominds
38
85
 
39
86
  ```bash
package/dist/cli.d.ts CHANGED
@@ -28,4 +28,5 @@
28
28
  * dominds webui
29
29
  */
30
30
  import './tools/builtins';
31
+ export declare function configureEnvProxySupport(): void;
31
32
  export declare function main(): Promise<void>;
package/dist/cli.js CHANGED
@@ -62,8 +62,10 @@ var __importStar = (this && this.__importStar) || (function () {
62
62
  };
63
63
  })();
64
64
  Object.defineProperty(exports, "__esModule", { value: true });
65
+ exports.configureEnvProxySupport = configureEnvProxySupport;
65
66
  exports.main = main;
66
67
  const fs = __importStar(require("fs"));
68
+ const http = __importStar(require("node:http"));
67
69
  const path = __importStar(require("path"));
68
70
  const runtime_1 = require("./apps/runtime");
69
71
  const dotenv_1 = require("./bootstrap/dotenv");
@@ -81,6 +83,24 @@ const update_1 = require("./cli/update");
81
83
  const validate_team_def_1 = require("./cli/validate-team-def");
82
84
  const webui_1 = require("./cli/webui");
83
85
  require("./tools/builtins");
86
+ function configureEnvProxySupport() {
87
+ const domindsUseEnvProxy = process.env.DOMINDS_USE_ENV_PROXY?.trim();
88
+ if (domindsUseEnvProxy === '0') {
89
+ return;
90
+ }
91
+ try {
92
+ const setGlobalProxyFromEnv = http.setGlobalProxyFromEnv;
93
+ if (typeof setGlobalProxyFromEnv !== 'function') {
94
+ console.error('Error: DOMINDS_USE_ENV_PROXY requires Node.js 24.5+ because http.setGlobalProxyFromEnv() is unavailable.');
95
+ process.exit(1);
96
+ }
97
+ setGlobalProxyFromEnv(process.env);
98
+ }
99
+ catch (err) {
100
+ console.error('Error: invalid proxy environment configuration:', err instanceof Error ? err.message : String(err));
101
+ process.exit(1);
102
+ }
103
+ }
84
104
  function printHelp() {
85
105
  console.log(`
86
106
  Dominds CLI - AI-driven DevOps framework with persistent memory
@@ -163,6 +183,7 @@ async function main() {
163
183
  }
164
184
  }
165
185
  (0, dotenv_1.loadRtwsDotenv)({ cwd: process.cwd() });
186
+ configureEnvProxySupport();
166
187
  await runSubcommand('webui', []);
167
188
  return;
168
189
  }
@@ -214,6 +235,7 @@ async function main() {
214
235
  // Precedence: `.env` then `.env.local` (later overwrites earlier), and both
215
236
  // overwrite any existing process.env values.
216
237
  (0, dotenv_1.loadRtwsDotenv)({ cwd: process.cwd() });
238
+ configureEnvProxySupport();
217
239
  }
218
240
  const shouldLoadApps = subcommand !== 'webui' &&
219
241
  subcommand !== 'create' &&
@@ -43,15 +43,15 @@ export declare function clearMainDialogQuarantining(mainDialogId: DialogID): voi
43
43
  export declare function forceStopActiveRunsForMainDialog(mainDialogId: DialogID): Promise<void>;
44
44
  export declare function getStopRequestedReason(dialogId: DialogID): StopRequestedReason | undefined;
45
45
  export declare function loadDialogExecutionMarker(dialogId: DialogID, status?: 'running' | 'completed' | 'archived'): Promise<DialogExecutionMarker | undefined>;
46
- export declare function setDialogExecutionMarker(dialogId: DialogID, executionMarker: DialogExecutionMarker | undefined): Promise<void>;
47
- export declare function clearDialogInterruptedExecutionMarker(dialogId: DialogID): Promise<void>;
48
- export declare function setDialogDisplayState(dialogId: DialogID, displayState: DialogDisplayState): Promise<void>;
46
+ export declare function setDialogExecutionMarker(dialogId: DialogID, executionMarker: DialogExecutionMarker | undefined, status?: 'running' | 'completed' | 'archived'): Promise<void>;
47
+ export declare function clearDialogInterruptedExecutionMarker(dialogId: DialogID, status?: 'running' | 'completed' | 'archived'): Promise<void>;
48
+ export declare function setDialogDisplayState(dialogId: DialogID, displayState: DialogDisplayState, status?: 'running' | 'completed' | 'archived'): Promise<void>;
49
49
  export declare function broadcastDisplayStateMarker(dialogId: DialogID, marker: {
50
50
  kind: 'interrupted' | 'resumed';
51
51
  reason?: DialogInterruptionReason;
52
52
  }): void;
53
53
  export declare function computeIdleDisplayState(dlg: Dialog): Promise<DialogDisplayState>;
54
- export declare function refreshRunControlProjectionFromPersistenceFacts(dialogId: DialogID, trigger: 'resume_dialog' | 'resume_all' | 'run_control_snapshot' | 'active_callee_dispatches_changed' | 'q4h_changed'): Promise<DialogLatestFile | null>;
54
+ export declare function refreshRunControlProjectionFromPersistenceFacts(dialogId: DialogID, trigger: 'resume_dialog' | 'resume_all' | 'run_control_snapshot' | 'active_callee_dispatches_changed' | 'q4h_changed' | 'restart_reconciliation'): Promise<DialogLatestFile | null>;
55
55
  export declare function reconcileDisplayStatesAfterRestart(): Promise<void>;
56
56
  export declare function requestInterruptDialog(dialogId: DialogID, reason: StopRequestedReason): Promise<{
57
57
  applied: boolean;
@@ -327,7 +327,7 @@ async function loadDialogExecutionMarker(dialogId, status = 'running') {
327
327
  const latest = await persistence_1.DialogPersistence.loadDialogLatest(dialogId, status);
328
328
  return latest?.executionMarker;
329
329
  }
330
- async function setDialogExecutionMarker(dialogId, executionMarker) {
330
+ async function setDialogExecutionMarker(dialogId, executionMarker, status = 'running') {
331
331
  if (executionMarker?.kind === 'dead' && dialogId.selfId === dialogId.rootId) {
332
332
  log.warn('Rejecting dead executionMarker for main dialog (main dialogs must not be dead)', undefined, {
333
333
  dialogId: dialogId.valueOf(),
@@ -338,20 +338,21 @@ async function setDialogExecutionMarker(dialogId, executionMarker) {
338
338
  await persistence_1.DialogPersistence.mutateDialogLatest(dialogId, () => ({
339
339
  kind: 'patch',
340
340
  patch: { executionMarker },
341
- }));
341
+ }), status);
342
342
  }
343
343
  catch (err) {
344
344
  log.warn('Failed to persist dialog executionMarker', err, {
345
345
  dialogId: dialogId.valueOf(),
346
346
  rootId: dialogId.rootId,
347
347
  selfId: dialogId.selfId,
348
+ status,
348
349
  intendedExecutionMarker: executionMarker ?? null,
349
350
  });
350
351
  }
351
352
  }
352
- async function clearDialogInterruptedExecutionMarker(dialogId) {
353
+ async function clearDialogInterruptedExecutionMarker(dialogId, status = 'running') {
353
354
  try {
354
- const latest = await persistence_1.DialogPersistence.loadDialogLatest(dialogId, 'running');
355
+ const latest = await persistence_1.DialogPersistence.loadDialogLatest(dialogId, status);
355
356
  if (latest?.executionMarker?.kind !== 'interrupted') {
356
357
  return;
357
358
  }
@@ -359,12 +360,13 @@ async function clearDialogInterruptedExecutionMarker(dialogId) {
359
360
  catch (err) {
360
361
  log.warn('Failed to inspect executionMarker before clearing interrupted marker', err, {
361
362
  dialogId: dialogId.valueOf(),
363
+ status,
362
364
  });
363
365
  return;
364
366
  }
365
- await setDialogExecutionMarker(dialogId, undefined);
367
+ await setDialogExecutionMarker(dialogId, undefined, status);
366
368
  }
367
- async function setDialogDisplayState(dialogId, displayState) {
369
+ async function setDialogDisplayState(dialogId, displayState, status = 'running') {
368
370
  if (displayState.kind === 'dead' && dialogId.selfId === dialogId.rootId) {
369
371
  log.warn('Rejecting dead displayState for main dialog (main dialogs must not be dead)', undefined, {
370
372
  dialogId: dialogId.valueOf(),
@@ -376,7 +378,7 @@ async function setDialogDisplayState(dialogId, displayState) {
376
378
  // "dead" is irreversible. Once a dialog is marked dead, do not allow overwriting it with
377
379
  // another state (best-effort; races may still exist across concurrent writers).
378
380
  try {
379
- const latest = await persistence_1.DialogPersistence.loadDialogLatest(dialogId, 'running');
381
+ const latest = await persistence_1.DialogPersistence.loadDialogLatest(dialogId, status);
380
382
  previousDisplayState = latest?.displayState;
381
383
  previousExecutionMarker = latest?.executionMarker;
382
384
  if (dialogId.selfId !== dialogId.rootId &&
@@ -400,6 +402,7 @@ async function setDialogDisplayState(dialogId, displayState) {
400
402
  catch (err) {
401
403
  log.warn('Failed to check existing displayState before setDialogDisplayState', err, {
402
404
  dialogId: dialogId.valueOf(),
405
+ status,
403
406
  });
404
407
  }
405
408
  const nextExecutionMarker = displayState.kind === 'stopped'
@@ -413,13 +416,14 @@ async function setDialogDisplayState(dialogId, displayState) {
413
416
  await persistence_1.DialogPersistence.mutateDialogLatest(dialogId, () => ({
414
417
  kind: 'patch',
415
418
  patch: { displayState, executionMarker: nextExecutionMarker },
416
- }));
419
+ }), status);
417
420
  }
418
421
  catch (err) {
419
422
  log.warn('Failed to persist dialog displayState', err, {
420
423
  dialogId: dialogId.valueOf(),
421
424
  rootId: dialogId.rootId,
422
425
  selfId: dialogId.selfId,
426
+ status,
423
427
  intendedDisplayState: displayState,
424
428
  });
425
429
  }
@@ -776,7 +780,7 @@ async function reconcileDisplayStatesAfterRestart() {
776
780
  }));
777
781
  }
778
782
  catch (err) {
779
- log.warn('Failed to preserve proceeding dialog for auto-drive after restart', err, {
783
+ log.warn('Failed to preserve open-generation dialog for auto-drive after restart', err, {
780
784
  dialogId: dialogId.valueOf(),
781
785
  });
782
786
  }
@@ -805,7 +809,21 @@ async function reconcileDisplayStatesAfterRestart() {
805
809
  }));
806
810
  }
807
811
  catch (err) {
808
- log.warn('Failed to reconcile proceeding dialog after restart', err, {
812
+ log.warn('Failed to reconcile open-generation dialog after restart', err, {
813
+ dialogId: dialogId.valueOf(),
814
+ });
815
+ }
816
+ continue;
817
+ }
818
+ if (latest.userWait?.kind === 'awaiting_user_answer' ||
819
+ latest.pendingRuntimePrompt !== undefined ||
820
+ latest.executionMarker?.kind === 'interrupted' ||
821
+ isNonIdleDisplayProjection(latest.displayState)) {
822
+ try {
823
+ await refreshRunControlProjectionFromPersistenceFacts(dialogId, 'restart_reconciliation');
824
+ }
825
+ catch (err) {
826
+ log.warn('Failed to refresh stale run-control projection after restart', err, {
809
827
  dialogId: dialogId.valueOf(),
810
828
  });
811
829
  }
@@ -3,6 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.hasRecoverableGenerationBeyondFinalResponse = hasRecoverableGenerationBeyondFinalResponse;
4
4
  exports.hasDurableDriveWork = hasDurableDriveWork;
5
5
  const dialog_generation_run_1 = require("./dialog-generation-run");
6
+ // Backend drive work is a wake routing filter only. It must stay deliberately shallow: this module
7
+ // says "some persisted continuation source may need a handler", not "the dialog has business value
8
+ // to drive". Each concrete continuation handler must locally re-read and claim its own business
9
+ // facts before starting or continuing a generation. Do not add generic de-dup/fingerprint/cleanup
10
+ // policy here; that would merge unrelated business continuations into one spaghetti gate.
6
11
  function hasResultArrivalTrigger(latest) {
7
12
  return latest.nextStep.triggers.some((trigger) => trigger.kind === 'result_arrival');
8
13
  }
@@ -1,11 +1,11 @@
1
1
  import { type MainDialog } from './dialog';
2
2
  export type DriveTriggerEvent = Readonly<{
3
3
  type: 'drive_trigger_evt';
4
- action: 'wake_drive' | 'clear_drive_wake' | 'active_run_cleared';
4
+ action: 'queue_root_drive' | 'clear_root_drive_queue' | 'active_run_cleared';
5
5
  rootId: string;
6
6
  entryFound: boolean;
7
- previousWakeQueued: boolean | null;
8
- nextWakeQueued: boolean;
7
+ previousDriveQueued: boolean | null;
8
+ nextDriveQueued: boolean;
9
9
  source: string;
10
10
  reason: string;
11
11
  emittedAtMs: number;
@@ -20,7 +20,8 @@ declare class GlobalDialogRegistry {
20
20
  * Runtime-owned roots keyed by rootId.
21
21
  *
22
22
  * Do not add an API that enumerates this map for backend driving. A dialog becomes driveable only
23
- * through an explicit business/runtime wake (`wakeDrive`, result arrival, active-run clear, etc.).
23
+ * through an explicit business/runtime scheduling event (`queueRootDrive`, result arrival,
24
+ * active-run clear, etc.).
24
25
  * Reintroducing "scan every loaded root and see what happens" makes hidden polling loops easy to
25
26
  * create and obscures the business event that should own the next action.
26
27
  */
@@ -40,12 +41,12 @@ declare class GlobalDialogRegistry {
40
41
  private compactSparseQueuedRootsIfNeeded;
41
42
  private publishDriveTrigger;
42
43
  waitForDriveTrigger(): Promise<DriveTriggerEvent>;
43
- wakeDrive(rootId: string, meta?: DriveTriggerMeta): void;
44
- clearDriveWake(rootId: string, meta?: DriveTriggerMeta): void;
44
+ queueRootDrive(rootId: string, meta?: DriveTriggerMeta): void;
45
+ clearRootDriveQueue(rootId: string, meta?: DriveTriggerMeta): void;
45
46
  notifyActiveRunCleared(rootId: string, meta?: DriveTriggerMeta): void;
46
47
  noteActiveRunBlockedQueuedDrive(rootId: string): void;
47
- hasPendingActiveRunClearedWake(rootId: string): boolean;
48
- isDriveWakeQueued(rootId: string): boolean;
48
+ hasPendingActiveRunClearedDrive(rootId: string): boolean;
49
+ isRootDriveQueued(rootId: string): boolean;
49
50
  getLastDriveTrigger(rootId: string): DriveTriggerEvent | undefined;
50
51
  consumeQueuedMainDialogs(): MainDialog[];
51
52
  get size(): number;
@@ -12,7 +12,8 @@ class GlobalDialogRegistry {
12
12
  * Runtime-owned roots keyed by rootId.
13
13
  *
14
14
  * Do not add an API that enumerates this map for backend driving. A dialog becomes driveable only
15
- * through an explicit business/runtime wake (`wakeDrive`, result arrival, active-run clear, etc.).
15
+ * through an explicit business/runtime scheduling event (`queueRootDrive`, result arrival,
16
+ * active-run clear, etc.).
16
17
  * Reintroducing "scan every loaded root and see what happens" makes hidden polling loops easy to
17
18
  * create and obscures the business event that should own the next action.
18
19
  */
@@ -45,24 +46,24 @@ class GlobalDialogRegistry {
45
46
  }
46
47
  this.entries.set(mainDialog.id.rootId, {
47
48
  mainDialog,
48
- wakeQueued: false,
49
- activeRunClearedWakePending: false,
49
+ driveQueued: false,
50
+ activeRunClearedDrivePending: false,
50
51
  });
51
52
  void (async () => {
52
53
  try {
53
54
  const hasPendingNextStepTriggers = await persistence_1.DialogPersistence.hasPendingNextStepTriggers(mainDialog.id);
54
- const watchedDialogIds = await persistence_1.DialogPersistence.loadDriveWatchedDialogIds(mainDialog.id);
55
- if (hasPendingNextStepTriggers || watchedDialogIds.length > 0) {
56
- this.wakeDrive(mainDialog.id.rootId, {
55
+ const wakeQueueEntries = await persistence_1.DialogPersistence.loadWakeQueueEntries(mainDialog.id);
56
+ if (hasPendingNextStepTriggers || wakeQueueEntries.length > 0) {
57
+ this.queueRootDrive(mainDialog.id.rootId, {
57
58
  source: 'dialog_registry_hydration',
58
59
  reason: hasPendingNextStepTriggers
59
60
  ? 'persisted_next_step_triggers'
60
- : 'persisted_drive_watch',
61
+ : 'persisted_wake_queue',
61
62
  });
62
63
  }
63
64
  }
64
65
  catch (error) {
65
- log.warn('Failed to hydrate persisted drive wake for registered main dialog', error, {
66
+ log.warn('Failed to hydrate persisted root drive queue for registered main dialog', error, {
66
67
  rootId: mainDialog.id.rootId,
67
68
  selfId: mainDialog.id.selfId,
68
69
  });
@@ -116,8 +117,8 @@ class GlobalDialogRegistry {
116
117
  action: args.action,
117
118
  rootId: args.rootId,
118
119
  entryFound: args.entryFound,
119
- previousWakeQueued: args.previousWakeQueued,
120
- nextWakeQueued: args.nextWakeQueued,
120
+ previousDriveQueued: args.previousDriveQueued,
121
+ nextDriveQueued: args.nextDriveQueued,
121
122
  source: args.meta.source,
122
123
  reason: args.meta.reason,
123
124
  emittedAtMs: Date.now(),
@@ -135,47 +136,47 @@ class GlobalDialogRegistry {
135
136
  this.driveTriggerSubChan = (0, evt_1.createSubChan)(this.driveTriggerPubChan);
136
137
  }
137
138
  }
138
- wakeDrive(rootId, meta) {
139
+ queueRootDrive(rootId, meta) {
139
140
  const triggerMeta = meta ?? {
140
141
  source: 'unknown',
141
142
  reason: 'unspecified',
142
143
  };
143
144
  const entry = this.entries.get(rootId);
144
- const previousWakeQueued = entry ? entry.wakeQueued : null;
145
+ const previousDriveQueued = entry ? entry.driveQueued : null;
145
146
  if (entry) {
146
- entry.wakeQueued = true;
147
- // A fresh queueing trigger supersedes any earlier "wake me once active run clears" debt.
148
- entry.activeRunClearedWakePending = false;
147
+ entry.driveQueued = true;
148
+ // A fresh root drive queueing supersedes any earlier "drive once active run clears" debt.
149
+ entry.activeRunClearedDrivePending = false;
149
150
  this.enqueueRoot(rootId);
150
151
  }
151
152
  this.publishDriveTrigger({
152
- action: 'wake_drive',
153
+ action: 'queue_root_drive',
153
154
  rootId,
154
155
  entryFound: entry !== undefined,
155
- previousWakeQueued,
156
- nextWakeQueued: true,
156
+ previousDriveQueued,
157
+ nextDriveQueued: true,
157
158
  meta: triggerMeta,
158
159
  });
159
160
  }
160
- clearDriveWake(rootId, meta) {
161
+ clearRootDriveQueue(rootId, meta) {
161
162
  const triggerMeta = meta ?? {
162
163
  source: 'unknown',
163
164
  reason: 'unspecified',
164
165
  };
165
166
  const entry = this.entries.get(rootId);
166
- const previousWakeQueued = entry ? entry.wakeQueued : null;
167
+ const previousDriveQueued = entry ? entry.driveQueued : null;
167
168
  if (entry) {
168
- entry.wakeQueued = false;
169
- entry.activeRunClearedWakePending = false;
169
+ entry.driveQueued = false;
170
+ entry.activeRunClearedDrivePending = false;
170
171
  this.queuedRootIdSet.delete(rootId);
171
172
  this.compactSparseQueuedRootsIfNeeded();
172
173
  }
173
174
  this.publishDriveTrigger({
174
- action: 'clear_drive_wake',
175
+ action: 'clear_root_drive_queue',
175
176
  rootId,
176
177
  entryFound: entry !== undefined,
177
- previousWakeQueued,
178
- nextWakeQueued: false,
178
+ previousDriveQueued,
179
+ nextDriveQueued: false,
179
180
  meta: triggerMeta,
180
181
  });
181
182
  }
@@ -188,20 +189,20 @@ class GlobalDialogRegistry {
188
189
  if (!entry) {
189
190
  return;
190
191
  }
191
- if (!entry.activeRunClearedWakePending) {
192
- entry.activeRunClearedWakePending = false;
192
+ if (!entry.activeRunClearedDrivePending) {
193
+ entry.activeRunClearedDrivePending = false;
193
194
  return;
194
195
  }
195
- const currentWakeQueued = entry.wakeQueued;
196
- entry.activeRunClearedWakePending = false;
197
- entry.wakeQueued = true;
196
+ const currentDriveQueued = entry.driveQueued;
197
+ entry.activeRunClearedDrivePending = false;
198
+ entry.driveQueued = true;
198
199
  this.enqueueRoot(rootId);
199
200
  this.publishDriveTrigger({
200
201
  action: 'active_run_cleared',
201
202
  rootId,
202
203
  entryFound: true,
203
- previousWakeQueued: currentWakeQueued,
204
- nextWakeQueued: entry.wakeQueued,
204
+ previousDriveQueued: currentDriveQueued,
205
+ nextDriveQueued: entry.driveQueued,
205
206
  meta: triggerMeta,
206
207
  });
207
208
  }
@@ -210,13 +211,13 @@ class GlobalDialogRegistry {
210
211
  if (!entry) {
211
212
  return;
212
213
  }
213
- entry.activeRunClearedWakePending = true;
214
+ entry.activeRunClearedDrivePending = true;
214
215
  }
215
- hasPendingActiveRunClearedWake(rootId) {
216
- return this.entries.get(rootId)?.activeRunClearedWakePending === true;
216
+ hasPendingActiveRunClearedDrive(rootId) {
217
+ return this.entries.get(rootId)?.activeRunClearedDrivePending === true;
217
218
  }
218
- isDriveWakeQueued(rootId) {
219
- return this.entries.get(rootId)?.wakeQueued === true;
219
+ isRootDriveQueued(rootId) {
220
+ return this.entries.get(rootId)?.driveQueued === true;
220
221
  }
221
222
  getLastDriveTrigger(rootId) {
222
223
  return this.lastDriveTriggerByRootId.get(rootId);
@@ -234,7 +235,7 @@ class GlobalDialogRegistry {
234
235
  if (!entry) {
235
236
  continue;
236
237
  }
237
- entry.wakeQueued = false;
238
+ entry.driveQueued = false;
238
239
  queued.push(entry.mainDialog);
239
240
  }
240
241
  this.compactQueuedRootsIfNeeded();
@@ -35,6 +35,13 @@ async function resolvePendingRuntimePromptForRestore(args) {
35
35
  if (alreadyPersisted) {
36
36
  if (args.status === 'running') {
37
37
  await persistence_1.DialogPersistence.clearPendingRuntimePrompt(args.dialogId, pending.msgId, args.status);
38
+ const latestAfterClear = await persistence_1.DialogPersistence.loadDialogLatest(args.dialogId, args.status);
39
+ if (latestAfterClear) {
40
+ await persistence_1.DialogPersistence.syncWakeQueueForDialogLatest(args.dialogId, latestAfterClear, args.status);
41
+ }
42
+ else {
43
+ await persistence_1.DialogPersistence.removeWakeQueueEntriesForDialog(args.dialogId, args.status);
44
+ }
38
45
  }
39
46
  return { pendingRuntimePrompt: undefined };
40
47
  }
@@ -1,4 +1,5 @@
1
1
  import type { DialogInterruptionReason } from '@longrun-ai/kernel/types/display-state';
2
+ import type { DialogExecutionMarker } from '@longrun-ai/kernel/types/storage';
2
3
  /**
3
4
  * Decides whether a finalized stopped dialog should expose manual Continue.
4
5
  *
@@ -17,3 +18,4 @@ import type { DialogInterruptionReason } from '@longrun-ai/kernel/types/display-
17
18
  */
18
19
  export declare function isInterruptionReasonManualResumeEligible(reason: DialogInterruptionReason): boolean;
19
20
  export declare function doesInterruptionReasonRequireExplicitResume(reason: DialogInterruptionReason): boolean;
21
+ export declare function isInterruptedDialogBlockedWithoutExplicitResume(marker: DialogExecutionMarker | undefined, explicitResumeAuthorized: boolean): boolean;
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.isInterruptionReasonManualResumeEligible = isInterruptionReasonManualResumeEligible;
4
4
  exports.doesInterruptionReasonRequireExplicitResume = doesInterruptionReasonRequireExplicitResume;
5
+ exports.isInterruptedDialogBlockedWithoutExplicitResume = isInterruptedDialogBlockedWithoutExplicitResume;
5
6
  /**
6
7
  * Decides whether a finalized stopped dialog should expose manual Continue.
7
8
  *
@@ -53,3 +54,8 @@ function doesInterruptionReasonRequireExplicitResume(reason) {
53
54
  }
54
55
  }
55
56
  }
57
+ function isInterruptedDialogBlockedWithoutExplicitResume(marker, explicitResumeAuthorized) {
58
+ return (marker?.kind === 'interrupted' &&
59
+ doesInterruptionReasonRequireExplicitResume(marker.reason) &&
60
+ !explicitResumeAuthorized);
61
+ }
package/dist/dialog.d.ts CHANGED
@@ -19,6 +19,7 @@ import type { LanguageCode } from '@longrun-ai/kernel/types/language';
19
19
  import type { ActiveCalleesFile, CalleeCourseNumber, CalleeGenerationSeqNumber, CallSiteCourseNo, CallSiteGenseqNo, DialogAskerStackState, DialogLatestFile, DialogMetadataFile, DialogNextStepTrigger, HumanQuestion, ProviderData, ReasoningPayload, TellaskCallRecordName, TellaskReplyDirective } from '@longrun-ai/kernel/types/storage';
20
20
  import { ChatMessage, FuncResultMsg, TellaskCarryoverMsg, TellaskResultMsg } from './llm/client';
21
21
  import type { ToolResultImageIngest, UserImageIngest } from './llm/gen';
22
+ import { type SharedReminderTarget } from './shared-reminders';
22
23
  import type { JsonValue } from './tool';
23
24
  import { Reminder, ReminderOptions, ReminderOwner } from './tool';
24
25
  export declare class InvalidReminderIndexError extends Error {
@@ -105,10 +106,10 @@ export type VisibleReminderTarget = Readonly<{
105
106
  index: number;
106
107
  reminder: Reminder;
107
108
  }> | Readonly<{
108
- source: 'agent_shared';
109
+ source: 'runtime';
109
110
  index: number;
110
111
  reminder: Reminder;
111
- agentId: string;
112
+ target: SharedReminderTarget;
112
113
  }>;
113
114
  /**
114
115
  * Assignment from askerDialog for sideDialogs
@@ -150,7 +151,7 @@ export declare abstract class Dialog {
150
151
  protected _lastUserLanguageCode: LanguageCode;
151
152
  protected _lastContextHealth?: ContextHealthSnapshot;
152
153
  protected _lastContextHealthGenseq?: number;
153
- protected _upNextQueue: DialogQueuedPromptState[];
154
+ protected _queuedPrompts: DialogQueuedPromptState[];
154
155
  protected _driveIntents: DriveIntent[];
155
156
  protected _activeRunControlSpec?: DialogRunControlSpec;
156
157
  protected _newCourseHook?: NewCourseHook;
@@ -239,7 +240,6 @@ export declare abstract class Dialog {
239
240
  }>;
240
241
  get activeCalleeDialogIds(): ReadonlyArray<DialogID>;
241
242
  addActiveCalleeDialogs(ids: DialogID[]): void;
242
- removeActiveCalleeDispatch(id: DialogID): void;
243
243
  clearActiveCalleeDialogs(): void;
244
244
  /**
245
245
  * Load active callee dispatches from persistence into memory.
@@ -327,7 +327,7 @@ export declare abstract class Dialog {
327
327
  private setPendingRuntimePrompt;
328
328
  private mergePromptQ4HAnswerCallId;
329
329
  private enqueueQueuedPromptState;
330
- private peekLatestUpNext;
330
+ private peekLatestQueuedPrompt;
331
331
  queueUserPromptAtGenerationBoundary(options: {
332
332
  prompt: string;
333
333
  contentItems?: DialogQueuedUserGenerationBoundaryState['contentItems'];
@@ -372,9 +372,9 @@ export declare abstract class Dialog {
372
372
  skipTaskdoc?: boolean;
373
373
  calleeDialogReplyTarget: DialogCalleeReplyTarget;
374
374
  }): Promise<DialogQueuedPromptState>;
375
- hasUpNext(): boolean;
376
- peekUpNext(): DialogQueuedPromptState | undefined;
377
- takeUpNext(): DialogQueuedPromptState | undefined;
375
+ hasQueuedPrompt(): boolean;
376
+ peekQueuedPrompt(): DialogQueuedPromptState | undefined;
377
+ takeQueuedPrompt(): DialogQueuedPromptState | undefined;
378
378
  setActiveRunControlSpec(spec?: DialogRunControlSpec): void;
379
379
  getActiveRunControlSpec(): DialogRunControlSpec | undefined;
380
380
  setNewCourseHook(hook?: NewCourseHook): void;
@@ -392,7 +392,7 @@ export declare abstract class Dialog {
392
392
  reason?: string;
393
393
  skipRunControlHook?: boolean;
394
394
  skipEnqueueIntent?: boolean;
395
- }): Promise<void>;
395
+ }): Promise<DialogRuntimePrompt>;
396
396
  receiveFuncResult(result: FuncResultMsg): Promise<void>;
397
397
  receiveTellaskResult(result: TellaskResultMsg): Promise<void>;
398
398
  receiveTellaskCarryover(result: TellaskCarryoverMsg): Promise<void>;