dominds 1.8.11 → 1.9.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 (239) hide show
  1. package/dist/apps/app-json.js +241 -0
  2. package/dist/apps/installed-file.js +207 -0
  3. package/dist/apps/runtime-port.js +91 -0
  4. package/dist/apps-host/app-host-contract.js +2 -0
  5. package/dist/dialog-run-state.js +345 -0
  6. package/dist/docs/kernel-app-architecture.md +286 -0
  7. package/dist/docs/kernel-app-architecture.zh.md +285 -0
  8. package/dist/index.js +8 -0
  9. package/dist/llm/defaults.yaml +19 -0
  10. package/dist/llm/driver-entry.js +28 -0
  11. package/dist/llm/driver-v2/context-health.js +121 -0
  12. package/dist/llm/driver-v2/context.js +56 -0
  13. package/dist/llm/driver-v2/core.js +1545 -0
  14. package/dist/llm/driver-v2/index.js +26 -0
  15. package/dist/llm/driver-v2/orchestrator.js +158 -0
  16. package/dist/llm/driver-v2/policy.js +129 -0
  17. package/dist/llm/driver-v2/restore-dialog-hierarchy.js +73 -0
  18. package/dist/llm/driver-v2/round.js +366 -0
  19. package/dist/llm/driver-v2/runtime-utils.js +365 -0
  20. package/dist/llm/driver-v2/saying-events.js +20 -0
  21. package/dist/llm/driver-v2/subdialog-txn.js +42 -0
  22. package/dist/llm/driver-v2/supdialog-response.js +400 -0
  23. package/dist/llm/driver-v2/tellask-bridge.js +1148 -0
  24. package/dist/llm/driver-v2/types.js +10 -0
  25. package/dist/llm/driver-v2-ref-only/context-health.js +121 -0
  26. package/dist/llm/driver-v2-ref-only/context.js +17 -0
  27. package/dist/llm/driver-v2-ref-only/core.js +1710 -0
  28. package/dist/llm/driver-v2-ref-only/index.js +26 -0
  29. package/dist/llm/driver-v2-ref-only/orchestrator.js +158 -0
  30. package/dist/llm/driver-v2-ref-only/policy.js +129 -0
  31. package/dist/llm/driver-v2-ref-only/restore-dialog-hierarchy.js +73 -0
  32. package/dist/llm/driver-v2-ref-only/round.js +366 -0
  33. package/dist/llm/driver-v2-ref-only/runtime-utils.js +473 -0
  34. package/dist/llm/driver-v2-ref-only/saying-events.js +18 -0
  35. package/dist/llm/driver-v2-ref-only/subdialog-txn.js +42 -0
  36. package/dist/llm/driver-v2-ref-only/supdialog-response.js +453 -0
  37. package/dist/llm/driver-v2-ref-only/tellask-bridge.js +1178 -0
  38. package/dist/llm/driver-v2-ref-only/types.js +10 -0
  39. package/dist/llm/gen/codex.js +16 -9
  40. package/dist/llm/gen/openai.js +16 -6
  41. package/dist/mcp/config.d.ts +11 -0
  42. package/dist/mcp/config.js +17 -0
  43. package/dist/mcp/supervisor.js +5 -0
  44. package/dist/shared/types/context-health.js +2 -0
  45. package/dist/shared/types/dialog.js +11 -0
  46. package/dist/shared/types/drive-intent.js +2 -0
  47. package/dist/shared/types/i18n.js +2 -0
  48. package/dist/shared/types/index.js +27 -0
  49. package/dist/shared/types/language.js +40 -0
  50. package/dist/shared/types/priming.js +2 -0
  51. package/dist/shared/types/problems.js +2 -0
  52. package/dist/shared/types/q4h.js +7 -0
  53. package/dist/shared/types/run-state.js +8 -0
  54. package/dist/shared/types/setup.js +2 -0
  55. package/dist/shared/types/snippets.js +2 -0
  56. package/dist/shared/types/storage.js +87 -0
  57. package/dist/shared/types/tools-registry.js +2 -0
  58. package/dist/shared/types/wire.js +18 -0
  59. package/dist/static/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  60. package/dist/static/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  61. package/dist/static/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  62. package/dist/static/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  63. package/dist/static/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  64. package/dist/static/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  65. package/dist/static/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  66. package/dist/static/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  67. package/dist/static/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  68. package/dist/static/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  69. package/dist/static/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  70. package/dist/static/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  71. package/dist/static/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  72. package/dist/static/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  73. package/dist/static/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  74. package/dist/static/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  75. package/dist/static/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  76. package/dist/static/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  77. package/dist/static/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  78. package/dist/static/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  79. package/dist/static/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  80. package/dist/static/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  81. package/dist/static/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  82. package/dist/static/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  83. package/dist/static/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  84. package/dist/static/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  85. package/dist/static/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  86. package/dist/static/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  87. package/dist/static/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  88. package/dist/static/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  89. package/dist/static/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  90. package/dist/static/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  91. package/dist/static/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  92. package/dist/static/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  93. package/dist/static/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  94. package/dist/static/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  95. package/dist/static/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  96. package/dist/static/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  97. package/dist/static/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  98. package/dist/static/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  99. package/dist/static/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  100. package/dist/static/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  101. package/dist/static/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  102. package/dist/static/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  103. package/dist/static/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  104. package/dist/static/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  105. package/dist/static/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  106. package/dist/static/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  107. package/dist/static/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  108. package/dist/static/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  109. package/dist/static/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  110. package/dist/static/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  111. package/dist/static/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  112. package/dist/static/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  113. package/dist/static/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  114. package/dist/static/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  115. package/dist/static/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  116. package/dist/static/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  117. package/dist/static/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  118. package/dist/static/assets/_basePickBy-BlBhj3XJ.js +196 -0
  119. package/dist/static/assets/_basePickBy-BlBhj3XJ.js.map +1 -0
  120. package/dist/static/assets/_baseUniq-fHvi1qfT.js +836 -0
  121. package/dist/static/assets/_baseUniq-fHvi1qfT.js.map +1 -0
  122. package/dist/static/assets/arc-DT59AXiy.js +132 -0
  123. package/dist/static/assets/arc-DT59AXiy.js.map +1 -0
  124. package/dist/static/assets/architectureDiagram-VXUJARFQ-DHqQ2bIc.js +8686 -0
  125. package/dist/static/assets/architectureDiagram-VXUJARFQ-DHqQ2bIc.js.map +1 -0
  126. package/dist/static/assets/blockDiagram-VD42YOAC-DiN-P6e6.js +3608 -0
  127. package/dist/static/assets/blockDiagram-VD42YOAC-DiN-P6e6.js.map +1 -0
  128. package/dist/static/assets/c4Diagram-YG6GDRKO-L_BnHsyc.js +2482 -0
  129. package/dist/static/assets/c4Diagram-YG6GDRKO-L_BnHsyc.js.map +1 -0
  130. package/dist/static/assets/channel-BR4XoWwP.js +8 -0
  131. package/dist/static/assets/channel-BR4XoWwP.js.map +1 -0
  132. package/dist/static/assets/chunk-4BX2VUAB-RcDNBCC8.js +17 -0
  133. package/dist/static/assets/chunk-4BX2VUAB-RcDNBCC8.js.map +1 -0
  134. package/dist/static/assets/chunk-55IACEB6-DFujAN3X.js +14 -0
  135. package/dist/static/assets/chunk-55IACEB6-DFujAN3X.js.map +1 -0
  136. package/dist/static/assets/chunk-B4BG7PRW-OwGp4Aeh.js +1827 -0
  137. package/dist/static/assets/chunk-B4BG7PRW-OwGp4Aeh.js.map +1 -0
  138. package/dist/static/assets/chunk-DI55MBZ5-BtvUha4f.js +1916 -0
  139. package/dist/static/assets/chunk-DI55MBZ5-BtvUha4f.js.map +1 -0
  140. package/dist/static/assets/chunk-FMBD7UC4-BY9Zij3P.js +20 -0
  141. package/dist/static/assets/chunk-FMBD7UC4-BY9Zij3P.js.map +1 -0
  142. package/dist/static/assets/chunk-QN33PNHL-D6yEuXI4.js +25 -0
  143. package/dist/static/assets/chunk-QN33PNHL-D6yEuXI4.js.map +1 -0
  144. package/dist/static/assets/chunk-QZHKN3VN-D8jUie4l.js +18 -0
  145. package/dist/static/assets/chunk-QZHKN3VN-D8jUie4l.js.map +1 -0
  146. package/dist/static/assets/chunk-TZMSLE5B-CWidilhV.js +109 -0
  147. package/dist/static/assets/chunk-TZMSLE5B-CWidilhV.js.map +1 -0
  148. package/dist/static/assets/classDiagram-2ON5EDUG-Ci0WR0Qt.js +23 -0
  149. package/dist/static/assets/classDiagram-2ON5EDUG-Ci0WR0Qt.js.map +1 -0
  150. package/dist/static/assets/classDiagram-v2-WZHVMYZB-Ci0WR0Qt.js +23 -0
  151. package/dist/static/assets/classDiagram-v2-WZHVMYZB-Ci0WR0Qt.js.map +1 -0
  152. package/dist/static/assets/clone-D1wg1GLT.js +9 -0
  153. package/dist/static/assets/clone-D1wg1GLT.js.map +1 -0
  154. package/dist/static/assets/cose-bilkent-S5V4N54A-CZyMFpp7.js +4943 -0
  155. package/dist/static/assets/cose-bilkent-S5V4N54A-CZyMFpp7.js.map +1 -0
  156. package/dist/static/assets/cytoscape.esm-Bm8DJGmZ.js +30240 -0
  157. package/dist/static/assets/cytoscape.esm-Bm8DJGmZ.js.map +1 -0
  158. package/dist/static/assets/dagre-6UL2VRFP-CsR5rKda.js +695 -0
  159. package/dist/static/assets/dagre-6UL2VRFP-CsR5rKda.js.map +1 -0
  160. package/dist/static/assets/defaultLocale-B2RvLBDe.js +207 -0
  161. package/dist/static/assets/defaultLocale-B2RvLBDe.js.map +1 -0
  162. package/dist/static/assets/diagram-PSM6KHXK-DiBHtzz6.js +850 -0
  163. package/dist/static/assets/diagram-PSM6KHXK-DiBHtzz6.js.map +1 -0
  164. package/dist/static/assets/diagram-QEK2KX5R-Dv7eJui0.js +304 -0
  165. package/dist/static/assets/diagram-QEK2KX5R-Dv7eJui0.js.map +1 -0
  166. package/dist/static/assets/diagram-S2PKOQOG-DkWudo9L.js +214 -0
  167. package/dist/static/assets/diagram-S2PKOQOG-DkWudo9L.js.map +1 -0
  168. package/dist/static/assets/erDiagram-Q2GNP2WA-lHstf6Ay.js +1159 -0
  169. package/dist/static/assets/erDiagram-Q2GNP2WA-lHstf6Ay.js.map +1 -0
  170. package/dist/static/assets/favicon-Cmg5RbCj.svg +8 -0
  171. package/dist/static/assets/flowDiagram-NV44I4VS-Bg3iND3O.js +2332 -0
  172. package/dist/static/assets/flowDiagram-NV44I4VS-Bg3iND3O.js.map +1 -0
  173. package/dist/static/assets/ganttDiagram-JELNMOA3-D7Nbtncu.js +3681 -0
  174. package/dist/static/assets/ganttDiagram-JELNMOA3-D7Nbtncu.js.map +1 -0
  175. package/dist/static/assets/gitGraphDiagram-V2S2FVAM-BEvxtrS9.js +1207 -0
  176. package/dist/static/assets/gitGraphDiagram-V2S2FVAM-BEvxtrS9.js.map +1 -0
  177. package/dist/static/assets/graph-B2Owsqy5.js +425 -0
  178. package/dist/static/assets/graph-B2Owsqy5.js.map +1 -0
  179. package/dist/static/assets/index-CD5wtC_i.css +567 -0
  180. package/dist/static/assets/index-CIyFlluO.js +122686 -0
  181. package/dist/static/assets/index-CIyFlluO.js.map +1 -0
  182. package/dist/static/assets/infoDiagram-HS3SLOUP-CuI1-da5.js +35 -0
  183. package/dist/static/assets/infoDiagram-HS3SLOUP-CuI1-da5.js.map +1 -0
  184. package/dist/static/assets/init-ZxktEp_H.js +17 -0
  185. package/dist/static/assets/init-ZxktEp_H.js.map +1 -0
  186. package/dist/static/assets/journeyDiagram-XKPGCS4Q-DbzuKIyy.js +1255 -0
  187. package/dist/static/assets/journeyDiagram-XKPGCS4Q-DbzuKIyy.js.map +1 -0
  188. package/dist/static/assets/kanban-definition-3W4ZIXB7-Cc4dp2aC.js +1048 -0
  189. package/dist/static/assets/kanban-definition-3W4ZIXB7-Cc4dp2aC.js.map +1 -0
  190. package/dist/static/assets/layout-mw2wqeSj.js +2071 -0
  191. package/dist/static/assets/layout-mw2wqeSj.js.map +1 -0
  192. package/dist/static/assets/linear-C-8iGqQy.js +341 -0
  193. package/dist/static/assets/linear-C-8iGqQy.js.map +1 -0
  194. package/dist/static/assets/mindmap-definition-VGOIOE7T-CaSjMMDb.js +1127 -0
  195. package/dist/static/assets/mindmap-definition-VGOIOE7T-CaSjMMDb.js.map +1 -0
  196. package/dist/static/assets/ordinal-CxptdPJm.js +77 -0
  197. package/dist/static/assets/ordinal-CxptdPJm.js.map +1 -0
  198. package/dist/static/assets/pieDiagram-ADFJNKIX-D0ZNJv-s.js +242 -0
  199. package/dist/static/assets/pieDiagram-ADFJNKIX-D0ZNJv-s.js.map +1 -0
  200. package/dist/static/assets/quadrantDiagram-AYHSOK5B-bIVTM0t7.js +1338 -0
  201. package/dist/static/assets/quadrantDiagram-AYHSOK5B-bIVTM0t7.js.map +1 -0
  202. package/dist/static/assets/requirementDiagram-UZGBJVZJ-Cu7Qom20.js +1162 -0
  203. package/dist/static/assets/requirementDiagram-UZGBJVZJ-Cu7Qom20.js.map +1 -0
  204. package/dist/static/assets/sankeyDiagram-TZEHDZUN-DFfah0f8.js +1195 -0
  205. package/dist/static/assets/sankeyDiagram-TZEHDZUN-DFfah0f8.js.map +1 -0
  206. package/dist/static/assets/sequenceDiagram-WL72ISMW-BRXyRrxs.js +3875 -0
  207. package/dist/static/assets/sequenceDiagram-WL72ISMW-BRXyRrxs.js.map +1 -0
  208. package/dist/static/assets/stateDiagram-FKZM4ZOC-pJkpeW5D.js +452 -0
  209. package/dist/static/assets/stateDiagram-FKZM4ZOC-pJkpeW5D.js.map +1 -0
  210. package/dist/static/assets/stateDiagram-v2-4FDKWEC3-Dz8IBf9p.js +22 -0
  211. package/dist/static/assets/stateDiagram-v2-4FDKWEC3-Dz8IBf9p.js.map +1 -0
  212. package/dist/static/assets/timeline-definition-IT6M3QCI-C-dWWpdA.js +1223 -0
  213. package/dist/static/assets/timeline-definition-IT6M3QCI-C-dWWpdA.js.map +1 -0
  214. package/dist/static/assets/treemap-GDKQZRPO-DI7Z67nL.js +23640 -0
  215. package/dist/static/assets/treemap-GDKQZRPO-DI7Z67nL.js.map +1 -0
  216. package/dist/static/assets/xychartDiagram-PRI3JC2R-BKKhP_kL.js +1888 -0
  217. package/dist/static/assets/xychartDiagram-PRI3JC2R-BKKhP_kL.js.map +1 -0
  218. package/dist/static/index.html +71 -0
  219. package/dist/team.d.ts +3 -2
  220. package/dist/team.js +11 -0
  221. package/dist/tools/builtins.js +17 -4
  222. package/dist/tools/manual/render.js +6 -2
  223. package/dist/tools/manual/spec.d.ts +32 -2
  224. package/dist/tools/manual/spec.js +104 -14
  225. package/dist/tools/prompts/memory/en/errors.md +155 -0
  226. package/dist/tools/prompts/memory/en/index.md +47 -0
  227. package/dist/tools/prompts/memory/en/principles.md +79 -0
  228. package/dist/tools/prompts/memory/en/scenarios.md +174 -0
  229. package/dist/tools/prompts/memory/en/tools.md +154 -0
  230. package/dist/tools/prompts/memory/zh/errors.md +155 -0
  231. package/dist/tools/prompts/memory/zh/index.md +47 -0
  232. package/dist/tools/prompts/memory/zh/principles.md +79 -0
  233. package/dist/tools/prompts/memory/zh/scenarios.md +174 -0
  234. package/dist/tools/prompts/memory/zh/tools.md +154 -0
  235. package/dist/tools/prompts/team_mgmt/en/index.md +37 -0
  236. package/dist/tools/prompts/team_mgmt/zh/index.md +37 -0
  237. package/dist/tools/team_mgmt.js +4 -7
  238. package/dist/tools/txt.js +8 -8
  239. package/package.json +3 -3
@@ -0,0 +1,241 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseDomindsAppInstallJson = parseDomindsAppInstallJson;
4
+ function isRecord(v) {
5
+ return typeof v === 'object' && v !== null && !Array.isArray(v);
6
+ }
7
+ function asString(v) {
8
+ return typeof v === 'string' ? v : null;
9
+ }
10
+ function asNullableString(v) {
11
+ if (v === null)
12
+ return null;
13
+ return typeof v === 'string' ? v : null;
14
+ }
15
+ function isI18nText(v) {
16
+ return isRecord(v) && typeof v['zh'] === 'string' && typeof v['en'] === 'string';
17
+ }
18
+ function isJsonSchema(v) {
19
+ // Dominds JsonSchema is intentionally permissive: it's a passthrough dictionary.
20
+ return isRecord(v);
21
+ }
22
+ function parseToolJson(v, at) {
23
+ if (!isRecord(v))
24
+ return { ok: false, errorText: `Invalid ${at}: expected object` };
25
+ const name = asString(v['name']);
26
+ if (!name || name.trim() === '')
27
+ return { ok: false, errorText: `Invalid ${at}.name: required` };
28
+ const description = asString(v['description']) ?? undefined;
29
+ const descriptionI18n = v['descriptionI18n'];
30
+ if (descriptionI18n !== undefined && !isI18nText(descriptionI18n)) {
31
+ return { ok: false, errorText: `Invalid ${at}.descriptionI18n: expected {zh,en} string` };
32
+ }
33
+ const parameters = v['parameters'];
34
+ if (!isJsonSchema(parameters))
35
+ return { ok: false, errorText: `Invalid ${at}.parameters: expected JSON schema object` };
36
+ return {
37
+ ok: true,
38
+ tool: {
39
+ name,
40
+ description,
41
+ descriptionI18n: descriptionI18n,
42
+ parameters,
43
+ },
44
+ };
45
+ }
46
+ function parseToolsetJson(v, at) {
47
+ if (!isRecord(v))
48
+ return { ok: false, errorText: `Invalid ${at}: expected object` };
49
+ const id = asString(v['id']);
50
+ if (!id || id.trim() === '')
51
+ return { ok: false, errorText: `Invalid ${at}.id: required` };
52
+ const descriptionI18n = v['descriptionI18n'];
53
+ if (descriptionI18n !== undefined && !isI18nText(descriptionI18n)) {
54
+ return { ok: false, errorText: `Invalid ${at}.descriptionI18n: expected {zh,en} string` };
55
+ }
56
+ const toolsRaw = v['tools'];
57
+ if (!Array.isArray(toolsRaw))
58
+ return { ok: false, errorText: `Invalid ${at}.tools: expected array` };
59
+ const tools = [];
60
+ for (let i = 0; i < toolsRaw.length; i += 1) {
61
+ const parsed = parseToolJson(toolsRaw[i], `${at}.tools[${i}]`);
62
+ if (!parsed.ok)
63
+ return parsed;
64
+ tools.push(parsed.tool);
65
+ }
66
+ return {
67
+ ok: true,
68
+ toolset: {
69
+ id,
70
+ descriptionI18n: descriptionI18n,
71
+ tools,
72
+ },
73
+ };
74
+ }
75
+ function parseDialogRunControlJson(v, at) {
76
+ if (!isRecord(v))
77
+ return { ok: false, errorText: `Invalid ${at}: expected object` };
78
+ const id = asString(v['id']);
79
+ if (!id || id.trim() === '')
80
+ return { ok: false, errorText: `Invalid ${at}.id: required` };
81
+ const descriptionI18n = v['descriptionI18n'];
82
+ if (descriptionI18n !== undefined && !isI18nText(descriptionI18n)) {
83
+ return { ok: false, errorText: `Invalid ${at}.descriptionI18n: expected {zh,en} string` };
84
+ }
85
+ return {
86
+ ok: true,
87
+ control: {
88
+ id,
89
+ descriptionI18n: descriptionI18n,
90
+ },
91
+ };
92
+ }
93
+ function parseReminderOwnerJson(v, at) {
94
+ if (!isRecord(v))
95
+ return { ok: false, errorText: `Invalid ${at}: expected object` };
96
+ const ref = asString(v['ref']);
97
+ if (!ref || ref.trim() === '')
98
+ return { ok: false, errorText: `Invalid ${at}.ref: required` };
99
+ const managedByTool = asString(v['managedByTool']) ?? undefined;
100
+ const updateExample = asString(v['updateExample']) ?? undefined;
101
+ return {
102
+ ok: true,
103
+ owner: {
104
+ ref,
105
+ managedByTool,
106
+ updateExample,
107
+ },
108
+ };
109
+ }
110
+ function parseDomindsAppInstallJson(v) {
111
+ if (!isRecord(v)) {
112
+ return { ok: false, errorText: 'Invalid app --dominds-app output: expected object' };
113
+ }
114
+ const schemaVersion = v['schemaVersion'];
115
+ if (schemaVersion !== 1) {
116
+ return { ok: false, errorText: `Unsupported app json schemaVersion: ${String(schemaVersion)}` };
117
+ }
118
+ const appId = asString(v['appId']);
119
+ if (!appId || appId.trim() === '')
120
+ return { ok: false, errorText: 'Invalid app json: appId required' };
121
+ const displayName = asString(v['displayName']) ?? undefined;
122
+ const pkg = v['package'];
123
+ if (!isRecord(pkg))
124
+ return { ok: false, errorText: 'Invalid app json: package must be an object' };
125
+ const packageName = asString(pkg['name']);
126
+ const packageVersion = asNullableString(pkg['version']);
127
+ const rootAbs = asString(pkg['rootAbs']);
128
+ if (!packageName || packageName.trim() === '')
129
+ return { ok: false, errorText: 'Invalid app json: package.name required' };
130
+ if (packageVersion === null) {
131
+ // ok
132
+ }
133
+ else if (!packageVersion || packageVersion.trim() === '') {
134
+ return { ok: false, errorText: 'Invalid app json: package.version must be string|null' };
135
+ }
136
+ if (!rootAbs || rootAbs.trim() === '')
137
+ return { ok: false, errorText: 'Invalid app json: package.rootAbs required' };
138
+ const host = v['host'];
139
+ if (!isRecord(host))
140
+ return { ok: false, errorText: 'Invalid app json: host must be an object' };
141
+ const hostKind = asString(host['kind']);
142
+ if (hostKind !== 'node_module')
143
+ return { ok: false, errorText: "Invalid app json: host.kind must be 'node_module'" };
144
+ const moduleRelPath = asString(host['moduleRelPath']);
145
+ const exportName = asString(host['exportName']);
146
+ if (!moduleRelPath || moduleRelPath.trim() === '')
147
+ return { ok: false, errorText: 'Invalid app json: host.moduleRelPath required' };
148
+ if (!exportName || exportName.trim() === '')
149
+ return { ok: false, errorText: 'Invalid app json: host.exportName required' };
150
+ const frontendRaw = v['frontend'];
151
+ let frontend;
152
+ if (frontendRaw !== undefined) {
153
+ if (!isRecord(frontendRaw))
154
+ return { ok: false, errorText: 'Invalid app json: frontend must be an object' };
155
+ const kind = asString(frontendRaw['kind']);
156
+ if (kind !== 'http')
157
+ return { ok: false, errorText: "Invalid app json: frontend.kind must be 'http'" };
158
+ const defaultPortRaw = frontendRaw['defaultPort'];
159
+ const defaultPort = defaultPortRaw === undefined
160
+ ? undefined
161
+ : typeof defaultPortRaw === 'number' && Number.isFinite(defaultPortRaw)
162
+ ? Math.floor(defaultPortRaw)
163
+ : null;
164
+ if (defaultPort === null || (defaultPort !== undefined && defaultPort < 0)) {
165
+ return {
166
+ ok: false,
167
+ errorText: 'Invalid app json: frontend.defaultPort must be a non-negative number',
168
+ };
169
+ }
170
+ const basePath = asString(frontendRaw['basePath']) ?? undefined;
171
+ const wsPath = asString(frontendRaw['wsPath']) ?? undefined;
172
+ frontend = { kind: 'http', defaultPort, basePath, wsPath };
173
+ }
174
+ const contributesRaw = v['contributes'];
175
+ let contributes;
176
+ if (contributesRaw !== undefined) {
177
+ if (!isRecord(contributesRaw))
178
+ return { ok: false, errorText: 'Invalid app json: contributes must be an object' };
179
+ const teammatesYamlRelPath = asString(contributesRaw['teammatesYamlRelPath']) ?? undefined;
180
+ const toolsetsRaw = contributesRaw['toolsets'];
181
+ let toolsets;
182
+ if (toolsetsRaw !== undefined) {
183
+ if (!Array.isArray(toolsetsRaw))
184
+ return { ok: false, errorText: 'Invalid app json: contributes.toolsets must be an array' };
185
+ toolsets = [];
186
+ for (let i = 0; i < toolsetsRaw.length; i += 1) {
187
+ const parsed = parseToolsetJson(toolsetsRaw[i], `contributes.toolsets[${i}]`);
188
+ if (!parsed.ok)
189
+ return parsed;
190
+ toolsets.push(parsed.toolset);
191
+ }
192
+ }
193
+ const dialogRunControlsRaw = contributesRaw['dialogRunControls'];
194
+ let dialogRunControls;
195
+ if (dialogRunControlsRaw !== undefined) {
196
+ if (!Array.isArray(dialogRunControlsRaw)) {
197
+ return {
198
+ ok: false,
199
+ errorText: 'Invalid app json: contributes.dialogRunControls must be an array',
200
+ };
201
+ }
202
+ dialogRunControls = [];
203
+ for (let i = 0; i < dialogRunControlsRaw.length; i += 1) {
204
+ const parsed = parseDialogRunControlJson(dialogRunControlsRaw[i], `contributes.dialogRunControls[${i}]`);
205
+ if (!parsed.ok)
206
+ return parsed;
207
+ dialogRunControls.push(parsed.control);
208
+ }
209
+ }
210
+ const reminderOwnersRaw = contributesRaw['reminderOwners'];
211
+ let reminderOwners;
212
+ if (reminderOwnersRaw !== undefined) {
213
+ if (!Array.isArray(reminderOwnersRaw)) {
214
+ return {
215
+ ok: false,
216
+ errorText: 'Invalid app json: contributes.reminderOwners must be an array',
217
+ };
218
+ }
219
+ reminderOwners = [];
220
+ for (let i = 0; i < reminderOwnersRaw.length; i += 1) {
221
+ const parsed = parseReminderOwnerJson(reminderOwnersRaw[i], `contributes.reminderOwners[${i}]`);
222
+ if (!parsed.ok)
223
+ return parsed;
224
+ reminderOwners.push(parsed.owner);
225
+ }
226
+ }
227
+ contributes = { teammatesYamlRelPath, toolsets, dialogRunControls, reminderOwners };
228
+ }
229
+ return {
230
+ ok: true,
231
+ json: {
232
+ schemaVersion: 1,
233
+ appId,
234
+ displayName,
235
+ package: { name: packageName, version: packageVersion, rootAbs },
236
+ host: { kind: 'node_module', moduleRelPath, exportName },
237
+ frontend,
238
+ contributes,
239
+ },
240
+ };
241
+ }
@@ -0,0 +1,207 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.INSTALLED_APPS_REL_PATH = void 0;
7
+ exports.loadInstalledAppsFile = loadInstalledAppsFile;
8
+ exports.writeInstalledAppsFile = writeInstalledAppsFile;
9
+ exports.upsertInstalledApp = upsertInstalledApp;
10
+ exports.removeInstalledApp = removeInstalledApp;
11
+ exports.setAppEnabled = setAppEnabled;
12
+ exports.setAppRuntimePort = setAppRuntimePort;
13
+ exports.findInstalledApp = findInstalledApp;
14
+ const promises_1 = __importDefault(require("fs/promises"));
15
+ const path_1 = __importDefault(require("path"));
16
+ const yaml_1 = __importDefault(require("yaml"));
17
+ const time_1 = require("../shared/utils/time");
18
+ exports.INSTALLED_APPS_REL_PATH = path_1.default.join('.apps', 'installed.yaml');
19
+ function isRecord(v) {
20
+ return typeof v === 'object' && v !== null && !Array.isArray(v);
21
+ }
22
+ function asString(v) {
23
+ return typeof v === 'string' ? v : null;
24
+ }
25
+ function asBool(v) {
26
+ return typeof v === 'boolean' ? v : null;
27
+ }
28
+ function asNullableNumber(v) {
29
+ if (v === null)
30
+ return null;
31
+ if (typeof v === 'number' && Number.isFinite(v))
32
+ return v;
33
+ return null;
34
+ }
35
+ function parseSource(v, at) {
36
+ if (!isRecord(v))
37
+ return { ok: false, errorText: `Invalid ${at}: expected object` };
38
+ const kind = asString(v['kind']);
39
+ if (kind !== 'npx' && kind !== 'local') {
40
+ return { ok: false, errorText: `Invalid ${at}.kind: expected 'npx'|'local'` };
41
+ }
42
+ if (kind === 'npx') {
43
+ const spec = asString(v['spec']);
44
+ if (!spec || spec.trim() === '')
45
+ return { ok: false, errorText: `Invalid ${at}.spec: required` };
46
+ return { ok: true, source: { kind, spec } };
47
+ }
48
+ const pathAbs = asString(v['pathAbs']);
49
+ if (!pathAbs || pathAbs.trim() === '')
50
+ return { ok: false, errorText: `Invalid ${at}.pathAbs: required` };
51
+ return { ok: true, source: { kind, pathAbs } };
52
+ }
53
+ function parseRuntime(v, at) {
54
+ if (!isRecord(v))
55
+ return { ok: false, errorText: `Invalid ${at}: expected object` };
56
+ const portRaw = v['port'];
57
+ const port = asNullableNumber(portRaw);
58
+ if (port === null) {
59
+ if (portRaw !== null) {
60
+ return { ok: false, errorText: `Invalid ${at}.port: expected number|null` };
61
+ }
62
+ return { ok: true, runtime: { port: null } };
63
+ }
64
+ if (port < 0 || !Number.isInteger(port))
65
+ return { ok: false, errorText: `Invalid ${at}.port: expected non-negative integer|null` };
66
+ return { ok: true, runtime: { port: port } };
67
+ }
68
+ function parseEntry(v, at) {
69
+ if (!isRecord(v))
70
+ return { ok: false, errorText: `Invalid ${at}: expected object` };
71
+ const id = asString(v['id']);
72
+ if (!id || id.trim() === '')
73
+ return { ok: false, errorText: `Invalid ${at}.id: required` };
74
+ const enabled = asBool(v['enabled']);
75
+ if (enabled === null)
76
+ return { ok: false, errorText: `Invalid ${at}.enabled: boolean required` };
77
+ const installedAt = asString(v['installedAt']);
78
+ const updatedAt = asString(v['updatedAt']);
79
+ if (!installedAt || installedAt.trim() === '')
80
+ return { ok: false, errorText: `Invalid ${at}.installedAt: required` };
81
+ if (!updatedAt || updatedAt.trim() === '')
82
+ return { ok: false, errorText: `Invalid ${at}.updatedAt: required` };
83
+ const sourceParsed = parseSource(v['source'], `${at}.source`);
84
+ if (!sourceParsed.ok)
85
+ return sourceParsed;
86
+ const runtimeParsed = parseRuntime(v['runtime'] ?? { port: null }, `${at}.runtime`);
87
+ if (!runtimeParsed.ok)
88
+ return runtimeParsed;
89
+ // installJson is validated by install/update command on write. On read we keep permissive:
90
+ // kernel will fail fast later if it needs a missing field.
91
+ const installJson = v['installJson'];
92
+ if (!isRecord(installJson))
93
+ return { ok: false, errorText: `Invalid ${at}.installJson: expected object` };
94
+ return {
95
+ ok: true,
96
+ entry: {
97
+ id,
98
+ enabled,
99
+ source: sourceParsed.source,
100
+ runtime: runtimeParsed.runtime,
101
+ installJson: installJson,
102
+ installedAt,
103
+ updatedAt,
104
+ },
105
+ };
106
+ }
107
+ async function loadInstalledAppsFile(params) {
108
+ const filePathAbs = path_1.default.resolve(params.rtwsRootAbs, exports.INSTALLED_APPS_REL_PATH);
109
+ let raw;
110
+ try {
111
+ raw = await promises_1.default.readFile(filePathAbs, 'utf-8');
112
+ }
113
+ catch (err) {
114
+ const isEnoent = typeof err === 'object' &&
115
+ err !== null &&
116
+ 'code' in err &&
117
+ err.code === 'ENOENT';
118
+ if (isEnoent) {
119
+ return { kind: 'ok', filePathAbs, file: { schemaVersion: 1, apps: [] } };
120
+ }
121
+ return {
122
+ kind: 'error',
123
+ filePathAbs,
124
+ errorText: err instanceof Error ? err.message : String(err),
125
+ };
126
+ }
127
+ let parsed;
128
+ try {
129
+ parsed = yaml_1.default.parse(raw);
130
+ }
131
+ catch (err) {
132
+ return {
133
+ kind: 'error',
134
+ filePathAbs,
135
+ errorText: `Failed to parse YAML: ${err instanceof Error ? err.message : String(err)}`,
136
+ };
137
+ }
138
+ if (!isRecord(parsed)) {
139
+ return { kind: 'error', filePathAbs, errorText: 'Invalid installed.yaml: expected object' };
140
+ }
141
+ const schemaVersion = parsed['schemaVersion'];
142
+ if (schemaVersion !== 1) {
143
+ return {
144
+ kind: 'error',
145
+ filePathAbs,
146
+ errorText: `Unsupported schemaVersion: ${String(schemaVersion)}`,
147
+ };
148
+ }
149
+ const appsRaw = parsed['apps'];
150
+ if (!Array.isArray(appsRaw)) {
151
+ return {
152
+ kind: 'error',
153
+ filePathAbs,
154
+ errorText: 'Invalid installed.yaml: apps must be an array',
155
+ };
156
+ }
157
+ const apps = [];
158
+ for (let i = 0; i < appsRaw.length; i += 1) {
159
+ const e = parseEntry(appsRaw[i], `apps[${i}]`);
160
+ if (!e.ok)
161
+ return { kind: 'error', filePathAbs, errorText: e.errorText };
162
+ apps.push(e.entry);
163
+ }
164
+ return { kind: 'ok', filePathAbs, file: { schemaVersion: 1, apps } };
165
+ }
166
+ async function writeInstalledAppsFile(params) {
167
+ const dirAbs = path_1.default.resolve(params.rtwsRootAbs, '.apps');
168
+ await promises_1.default.mkdir(dirAbs, { recursive: true });
169
+ const filePathAbs = path_1.default.resolve(params.rtwsRootAbs, exports.INSTALLED_APPS_REL_PATH);
170
+ const yamlText = yaml_1.default.stringify(params.file);
171
+ await promises_1.default.writeFile(filePathAbs, yamlText, 'utf-8');
172
+ }
173
+ function upsertInstalledApp(params) {
174
+ const apps = [...params.existing.apps];
175
+ const idx = apps.findIndex((a) => a.id === params.next.id);
176
+ if (idx >= 0) {
177
+ apps[idx] = params.next;
178
+ }
179
+ else {
180
+ apps.push(params.next);
181
+ }
182
+ return { schemaVersion: 1, apps };
183
+ }
184
+ function removeInstalledApp(params) {
185
+ return { schemaVersion: 1, apps: params.existing.apps.filter((a) => a.id !== params.appId) };
186
+ }
187
+ function setAppEnabled(params) {
188
+ const now = (0, time_1.formatUnifiedTimestamp)(new Date());
189
+ const apps = params.existing.apps.map((a) => a.id === params.appId ? { ...a, enabled: params.enabled, updatedAt: now } : a);
190
+ return { schemaVersion: 1, apps };
191
+ }
192
+ function setAppRuntimePort(params) {
193
+ const existingApp = findInstalledApp(params.existing, params.appId);
194
+ if (!existingApp)
195
+ return params.existing;
196
+ if (existingApp.runtime.port === params.port)
197
+ return params.existing;
198
+ const now = (0, time_1.formatUnifiedTimestamp)(new Date());
199
+ const apps = params.existing.apps.map((a) => a.id === params.appId
200
+ ? { ...a, runtime: { ...a.runtime, port: params.port }, updatedAt: now }
201
+ : a);
202
+ return { schemaVersion: 1, apps };
203
+ }
204
+ function findInstalledApp(file, appId) {
205
+ const found = file.apps.find((a) => a.id === appId);
206
+ return found ?? null;
207
+ }
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.resolveStableAppRuntimePort = resolveStableAppRuntimePort;
7
+ const node_net_1 = __importDefault(require("node:net"));
8
+ const STABLE_PORT_RANGE_START = 43000;
9
+ const STABLE_PORT_RANGE_END = 49999;
10
+ const PORT_MAX = 65535;
11
+ function isPositivePort(value) {
12
+ return (typeof value === 'number' &&
13
+ Number.isInteger(value) &&
14
+ value > 0 &&
15
+ value <= PORT_MAX &&
16
+ Number.isFinite(value));
17
+ }
18
+ function hashAppId(appId) {
19
+ // FNV-1a 32-bit hash for deterministic port probing order.
20
+ let hash = 0x811c9dc5;
21
+ for (let i = 0; i < appId.length; i += 1) {
22
+ hash ^= appId.charCodeAt(i);
23
+ hash = Math.imul(hash, 0x01000193);
24
+ }
25
+ return hash >>> 0;
26
+ }
27
+ function collectReservedPorts(existingApps, appId) {
28
+ const reserved = new Set();
29
+ for (const app of existingApps) {
30
+ if (app.id === appId)
31
+ continue;
32
+ if (isPositivePort(app.runtime.port)) {
33
+ reserved.add(app.runtime.port);
34
+ }
35
+ }
36
+ return reserved;
37
+ }
38
+ async function canBindPort(port) {
39
+ return await new Promise((resolve) => {
40
+ const server = node_net_1.default.createServer();
41
+ server.unref();
42
+ const finish = (ok) => {
43
+ server.removeAllListeners('error');
44
+ server.removeAllListeners('listening');
45
+ resolve(ok);
46
+ };
47
+ server.once('error', () => {
48
+ finish(false);
49
+ });
50
+ server.once('listening', () => {
51
+ server.close(() => finish(true));
52
+ });
53
+ server.listen({ host: '127.0.0.1', port, exclusive: true });
54
+ });
55
+ }
56
+ async function pickDeterministicAvailablePort(params) {
57
+ const rangeSize = STABLE_PORT_RANGE_END - STABLE_PORT_RANGE_START + 1;
58
+ if (rangeSize <= 0) {
59
+ throw new Error('Invalid stable app runtime port range configuration');
60
+ }
61
+ const baseHash = hashAppId(params.appId);
62
+ for (let i = 0; i < rangeSize; i += 1) {
63
+ const candidate = STABLE_PORT_RANGE_START + ((baseHash + i) % rangeSize);
64
+ if (params.reservedPorts.has(candidate))
65
+ continue;
66
+ if (await canBindPort(candidate))
67
+ return candidate;
68
+ }
69
+ throw new Error(`Failed to allocate stable runtime port for app '${params.appId}': no bindable port in ${STABLE_PORT_RANGE_START}-${STABLE_PORT_RANGE_END}`);
70
+ }
71
+ async function resolveStableAppRuntimePort(params) {
72
+ if (!params.installJson.frontend)
73
+ return null;
74
+ const reservedPorts = collectReservedPorts(params.existingApps, params.appId);
75
+ if (isPositivePort(params.existingRuntimePort)) {
76
+ if (reservedPorts.has(params.existingRuntimePort)) {
77
+ throw new Error(`Invalid installed apps state: runtime port ${params.existingRuntimePort} for '${params.appId}' collides with another installed app`);
78
+ }
79
+ return params.existingRuntimePort;
80
+ }
81
+ const defaultPort = params.installJson.frontend.defaultPort;
82
+ if (isPositivePort(defaultPort) &&
83
+ !reservedPorts.has(defaultPort) &&
84
+ (await canBindPort(defaultPort))) {
85
+ return defaultPort;
86
+ }
87
+ return await pickDeterministicAvailablePort({
88
+ appId: params.appId,
89
+ reservedPorts,
90
+ });
91
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });