dominds 1.2.5 → 1.2.7

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 (149) hide show
  1. package/dist/agent-priming.js +2051 -0
  2. package/dist/apps/app-lock-file.js +228 -0
  3. package/dist/apps/assigned-port.js +124 -0
  4. package/dist/apps/enabled-apps.js +472 -7
  5. package/dist/apps/manifest.js +37 -0
  6. package/dist/apps/override-paths.js +19 -6
  7. package/dist/apps/problems.js +43 -0
  8. package/dist/apps/resolution-file.js +370 -0
  9. package/dist/apps/runtime.js +5 -17
  10. package/dist/apps/teammates.js +102 -1
  11. package/dist/cli/disable.js +10 -6
  12. package/dist/cli/enable.js +21 -19
  13. package/dist/cli/install.js +40 -18
  14. package/dist/cli/uninstall.js +6 -6
  15. package/dist/cli/update.js +38 -13
  16. package/dist/dialog.js +5 -0
  17. package/dist/docs/app-constitution.md +85 -18
  18. package/dist/docs/app-constitution.zh.md +86 -21
  19. package/dist/docs/dialog-system.md +1 -1
  20. package/dist/docs/dialog-system.zh.md +1 -1
  21. package/dist/docs/dominds-agent-priming.md +218 -0
  22. package/dist/docs/dominds-agent-priming.zh.md +196 -0
  23. package/dist/docs/drive-logic-context-refactor-plan.zh.md +338 -0
  24. package/dist/docs/keep-going.md +176 -0
  25. package/dist/docs/keep-going.zh.md +162 -0
  26. package/dist/docs/showing-by-doing.md +208 -0
  27. package/dist/docs/showing-by-doing.zh.md +177 -0
  28. package/dist/docs/team-mgmt-toolset.md +482 -0
  29. package/dist/docs/team-mgmt-toolset.zh.md +426 -0
  30. package/dist/llm/defaults.yaml +1 -1
  31. package/dist/llm/driver.js +4093 -0
  32. package/dist/llm/kernel-driver/drive.js +5 -2
  33. package/dist/llm/kernel-driver/flow.js +3 -0
  34. package/dist/minds/promptdocs.js +263 -0
  35. package/dist/problems.js +67 -16
  36. package/dist/server/api-routes.js +333 -0
  37. package/dist/server/prompts-routes.js +545 -0
  38. package/dist/server/server-core.js +4 -0
  39. package/dist/server/websocket-handler.js +17 -0
  40. package/dist/shared/team-mgmt-manual.js +120 -0
  41. package/dist/shared/types/prompts.js +2 -0
  42. package/dist/shared/types/tellask.js +8 -0
  43. package/dist/showing-by-doing.js +1091 -0
  44. package/dist/snippets/README.en.md +3 -0
  45. package/dist/snippets/README.md +4 -0
  46. package/dist/static/assets/{_basePickBy-CF9r08iy.js → _basePickBy-BMCtwrV7.js} +3 -3
  47. package/dist/static/assets/{_basePickBy-CF9r08iy.js.map → _basePickBy-BMCtwrV7.js.map} +1 -1
  48. package/dist/static/assets/{_baseUniq-CxKv0cd4.js → _baseUniq-BuyCgJiA.js} +2 -2
  49. package/dist/static/assets/{_baseUniq-CxKv0cd4.js.map → _baseUniq-BuyCgJiA.js.map} +1 -1
  50. package/dist/static/assets/{arc-C9JyvnlB.js → arc-BDuN8lwA.js} +2 -2
  51. package/dist/static/assets/{arc-C9JyvnlB.js.map → arc-BDuN8lwA.js.map} +1 -1
  52. package/dist/static/assets/{architectureDiagram-VXUJARFQ-CpcUgjHf.js → architectureDiagram-VXUJARFQ-C-ekqGAD.js} +7 -7
  53. package/dist/static/assets/{architectureDiagram-VXUJARFQ-CpcUgjHf.js.map → architectureDiagram-VXUJARFQ-C-ekqGAD.js.map} +1 -1
  54. package/dist/static/assets/{blockDiagram-VD42YOAC-BA9vtmm7.js → blockDiagram-VD42YOAC-CgQiNuuQ.js} +7 -7
  55. package/dist/static/assets/{blockDiagram-VD42YOAC-BA9vtmm7.js.map → blockDiagram-VD42YOAC-CgQiNuuQ.js.map} +1 -1
  56. package/dist/static/assets/{c4Diagram-YG6GDRKO-D49MGNdF.js → c4Diagram-YG6GDRKO-DONC39q-.js} +3 -3
  57. package/dist/static/assets/{c4Diagram-YG6GDRKO-D49MGNdF.js.map → c4Diagram-YG6GDRKO-DONC39q-.js.map} +1 -1
  58. package/dist/static/assets/{channel-B4KzL0Kg.js → channel-CJTFwXIG.js} +2 -2
  59. package/dist/static/assets/{channel-B4KzL0Kg.js.map → channel-CJTFwXIG.js.map} +1 -1
  60. package/dist/static/assets/{chunk-4BX2VUAB-0F-1ayl0.js → chunk-4BX2VUAB-NaIy4uLJ.js} +2 -2
  61. package/dist/static/assets/{chunk-4BX2VUAB-0F-1ayl0.js.map → chunk-4BX2VUAB-NaIy4uLJ.js.map} +1 -1
  62. package/dist/static/assets/{chunk-55IACEB6-Dnl2HDTZ.js → chunk-55IACEB6-JUKI_Ayx.js} +2 -2
  63. package/dist/static/assets/{chunk-55IACEB6-Dnl2HDTZ.js.map → chunk-55IACEB6-JUKI_Ayx.js.map} +1 -1
  64. package/dist/static/assets/{chunk-B4BG7PRW-Bhx5RbkQ.js → chunk-B4BG7PRW-dIswFJDn.js} +5 -5
  65. package/dist/static/assets/{chunk-B4BG7PRW-Bhx5RbkQ.js.map → chunk-B4BG7PRW-dIswFJDn.js.map} +1 -1
  66. package/dist/static/assets/{chunk-DI55MBZ5-EYd1wL3E.js → chunk-DI55MBZ5-DU2b_N30.js} +4 -4
  67. package/dist/static/assets/{chunk-DI55MBZ5-EYd1wL3E.js.map → chunk-DI55MBZ5-DU2b_N30.js.map} +1 -1
  68. package/dist/static/assets/{chunk-FMBD7UC4-DAjkhhUU.js → chunk-FMBD7UC4-BgExcScw.js} +2 -2
  69. package/dist/static/assets/{chunk-FMBD7UC4-DAjkhhUU.js.map → chunk-FMBD7UC4-BgExcScw.js.map} +1 -1
  70. package/dist/static/assets/{chunk-QN33PNHL-CK6TY7IE.js → chunk-QN33PNHL-bitxyqh7.js} +2 -2
  71. package/dist/static/assets/{chunk-QN33PNHL-CK6TY7IE.js.map → chunk-QN33PNHL-bitxyqh7.js.map} +1 -1
  72. package/dist/static/assets/{chunk-QZHKN3VN-CketngiE.js → chunk-QZHKN3VN-Cor8u7DT.js} +2 -2
  73. package/dist/static/assets/{chunk-QZHKN3VN-CketngiE.js.map → chunk-QZHKN3VN-Cor8u7DT.js.map} +1 -1
  74. package/dist/static/assets/{chunk-TZMSLE5B-Bcuvqo45.js → chunk-TZMSLE5B-Aceoxav_.js} +2 -2
  75. package/dist/static/assets/{chunk-TZMSLE5B-Bcuvqo45.js.map → chunk-TZMSLE5B-Aceoxav_.js.map} +1 -1
  76. package/dist/static/assets/{classDiagram-2ON5EDUG-CaP4T3r4.js → classDiagram-2ON5EDUG-D1Q6a8Hg.js} +6 -6
  77. package/dist/static/assets/{classDiagram-2ON5EDUG-CaP4T3r4.js.map → classDiagram-2ON5EDUG-D1Q6a8Hg.js.map} +1 -1
  78. package/dist/static/assets/{classDiagram-v2-WZHVMYZB-CaP4T3r4.js → classDiagram-v2-WZHVMYZB-D1Q6a8Hg.js} +6 -6
  79. package/dist/static/assets/{classDiagram-v2-WZHVMYZB-CaP4T3r4.js.map → classDiagram-v2-WZHVMYZB-D1Q6a8Hg.js.map} +1 -1
  80. package/dist/static/assets/{clone-C-JULvnG.js → clone-MlWbv1V0.js} +2 -2
  81. package/dist/static/assets/{clone-C-JULvnG.js.map → clone-MlWbv1V0.js.map} +1 -1
  82. package/dist/static/assets/{cose-bilkent-S5V4N54A-vXCmi_eC.js → cose-bilkent-S5V4N54A-DWPCXSrn.js} +2 -2
  83. package/dist/static/assets/{cose-bilkent-S5V4N54A-vXCmi_eC.js.map → cose-bilkent-S5V4N54A-DWPCXSrn.js.map} +1 -1
  84. package/dist/static/assets/{dagre-6UL2VRFP-bhGzX6kO.js → dagre-6UL2VRFP-C8ptQ9V3.js} +7 -7
  85. package/dist/static/assets/{dagre-6UL2VRFP-bhGzX6kO.js.map → dagre-6UL2VRFP-C8ptQ9V3.js.map} +1 -1
  86. package/dist/static/assets/{diagram-PSM6KHXK-BUKfmfGk.js → diagram-PSM6KHXK-Bgf1FqkE.js} +8 -8
  87. package/dist/static/assets/{diagram-PSM6KHXK-BUKfmfGk.js.map → diagram-PSM6KHXK-Bgf1FqkE.js.map} +1 -1
  88. package/dist/static/assets/{diagram-QEK2KX5R-DYlq3uFq.js → diagram-QEK2KX5R-BZ5xzofU.js} +7 -7
  89. package/dist/static/assets/{diagram-QEK2KX5R-DYlq3uFq.js.map → diagram-QEK2KX5R-BZ5xzofU.js.map} +1 -1
  90. package/dist/static/assets/{diagram-S2PKOQOG-CjxkLHWG.js → diagram-S2PKOQOG-Dwp47T9I.js} +7 -7
  91. package/dist/static/assets/{diagram-S2PKOQOG-CjxkLHWG.js.map → diagram-S2PKOQOG-Dwp47T9I.js.map} +1 -1
  92. package/dist/static/assets/{erDiagram-Q2GNP2WA-S3hR85On.js → erDiagram-Q2GNP2WA-Cx4weIHl.js} +5 -5
  93. package/dist/static/assets/{erDiagram-Q2GNP2WA-S3hR85On.js.map → erDiagram-Q2GNP2WA-Cx4weIHl.js.map} +1 -1
  94. package/dist/static/assets/{flowDiagram-NV44I4VS-aBmNMuQ0.js → flowDiagram-NV44I4VS-vNUuIeRk.js} +6 -6
  95. package/dist/static/assets/{flowDiagram-NV44I4VS-aBmNMuQ0.js.map → flowDiagram-NV44I4VS-vNUuIeRk.js.map} +1 -1
  96. package/dist/static/assets/{ganttDiagram-JELNMOA3-DJxXaiW1.js → ganttDiagram-JELNMOA3-BEfozJAr.js} +3 -3
  97. package/dist/static/assets/{ganttDiagram-JELNMOA3-DJxXaiW1.js.map → ganttDiagram-JELNMOA3-BEfozJAr.js.map} +1 -1
  98. package/dist/static/assets/{gitGraphDiagram-V2S2FVAM-DEOBCM0G.js → gitGraphDiagram-V2S2FVAM-eHxwc3d9.js} +8 -8
  99. package/dist/static/assets/{gitGraphDiagram-V2S2FVAM-DEOBCM0G.js.map → gitGraphDiagram-V2S2FVAM-eHxwc3d9.js.map} +1 -1
  100. package/dist/static/assets/{graph-DwrKSIE7.js → graph-C6a6uAok.js} +3 -3
  101. package/dist/static/assets/{graph-DwrKSIE7.js.map → graph-C6a6uAok.js.map} +1 -1
  102. package/dist/static/assets/{index-HWTRvE2k.js → index-D3TQbAKh.js} +383 -59
  103. package/dist/static/assets/index-D3TQbAKh.js.map +1 -0
  104. package/dist/static/assets/{infoDiagram-HS3SLOUP-BH9kVuYd.js → infoDiagram-HS3SLOUP-CX0NiId3.js} +6 -6
  105. package/dist/static/assets/{infoDiagram-HS3SLOUP-BH9kVuYd.js.map → infoDiagram-HS3SLOUP-CX0NiId3.js.map} +1 -1
  106. package/dist/static/assets/{journeyDiagram-XKPGCS4Q-Dap7AcjR.js → journeyDiagram-XKPGCS4Q-C1IepPZ-.js} +5 -5
  107. package/dist/static/assets/{journeyDiagram-XKPGCS4Q-Dap7AcjR.js.map → journeyDiagram-XKPGCS4Q-C1IepPZ-.js.map} +1 -1
  108. package/dist/static/assets/{kanban-definition-3W4ZIXB7-4NOl8MEj.js → kanban-definition-3W4ZIXB7-uMNX4Z1W.js} +3 -3
  109. package/dist/static/assets/{kanban-definition-3W4ZIXB7-4NOl8MEj.js.map → kanban-definition-3W4ZIXB7-uMNX4Z1W.js.map} +1 -1
  110. package/dist/static/assets/{layout-D6uIxu1E.js → layout-CpE3kk5z.js} +5 -5
  111. package/dist/static/assets/{layout-D6uIxu1E.js.map → layout-CpE3kk5z.js.map} +1 -1
  112. package/dist/static/assets/{linear-CvBOGQA2.js → linear-DV8laXr9.js} +2 -2
  113. package/dist/static/assets/{linear-CvBOGQA2.js.map → linear-DV8laXr9.js.map} +1 -1
  114. package/dist/static/assets/{mindmap-definition-VGOIOE7T-ugsrLNY5.js → mindmap-definition-VGOIOE7T-CKjgVM9S.js} +4 -4
  115. package/dist/static/assets/{mindmap-definition-VGOIOE7T-ugsrLNY5.js.map → mindmap-definition-VGOIOE7T-CKjgVM9S.js.map} +1 -1
  116. package/dist/static/assets/{pieDiagram-ADFJNKIX-CdVZjM8g.js → pieDiagram-ADFJNKIX-BBonlNyT.js} +8 -8
  117. package/dist/static/assets/{pieDiagram-ADFJNKIX-CdVZjM8g.js.map → pieDiagram-ADFJNKIX-BBonlNyT.js.map} +1 -1
  118. package/dist/static/assets/{quadrantDiagram-AYHSOK5B-A6m5lZKd.js → quadrantDiagram-AYHSOK5B-BTI8HbBu.js} +3 -3
  119. package/dist/static/assets/{quadrantDiagram-AYHSOK5B-A6m5lZKd.js.map → quadrantDiagram-AYHSOK5B-BTI8HbBu.js.map} +1 -1
  120. package/dist/static/assets/{requirementDiagram-UZGBJVZJ-Cac3zSJH.js → requirementDiagram-UZGBJVZJ-ZtSr9Q5R.js} +4 -4
  121. package/dist/static/assets/{requirementDiagram-UZGBJVZJ-Cac3zSJH.js.map → requirementDiagram-UZGBJVZJ-ZtSr9Q5R.js.map} +1 -1
  122. package/dist/static/assets/{sankeyDiagram-TZEHDZUN-DXDdUUl1.js → sankeyDiagram-TZEHDZUN-DibLVGzg.js} +2 -2
  123. package/dist/static/assets/{sankeyDiagram-TZEHDZUN-DXDdUUl1.js.map → sankeyDiagram-TZEHDZUN-DibLVGzg.js.map} +1 -1
  124. package/dist/static/assets/{sequenceDiagram-WL72ISMW-Domsjl5Y.js → sequenceDiagram-WL72ISMW-qXatfzVt.js} +4 -4
  125. package/dist/static/assets/{sequenceDiagram-WL72ISMW-Domsjl5Y.js.map → sequenceDiagram-WL72ISMW-qXatfzVt.js.map} +1 -1
  126. package/dist/static/assets/{stateDiagram-FKZM4ZOC-Bu0lRQK1.js → stateDiagram-FKZM4ZOC-7fgxCQHo.js} +9 -9
  127. package/dist/static/assets/{stateDiagram-FKZM4ZOC-Bu0lRQK1.js.map → stateDiagram-FKZM4ZOC-7fgxCQHo.js.map} +1 -1
  128. package/dist/static/assets/{stateDiagram-v2-4FDKWEC3-D0K-n3ic.js → stateDiagram-v2-4FDKWEC3-DcWlOAnF.js} +5 -5
  129. package/dist/static/assets/{stateDiagram-v2-4FDKWEC3-D0K-n3ic.js.map → stateDiagram-v2-4FDKWEC3-DcWlOAnF.js.map} +1 -1
  130. package/dist/static/assets/{timeline-definition-IT6M3QCI-BGvpddwR.js → timeline-definition-IT6M3QCI-iX2MRdpY.js} +3 -3
  131. package/dist/static/assets/{timeline-definition-IT6M3QCI-BGvpddwR.js.map → timeline-definition-IT6M3QCI-iX2MRdpY.js.map} +1 -1
  132. package/dist/static/assets/{treemap-GDKQZRPO-BoOzOm2j.js → treemap-GDKQZRPO-AVRnyXu1.js} +5 -5
  133. package/dist/static/assets/{treemap-GDKQZRPO-BoOzOm2j.js.map → treemap-GDKQZRPO-AVRnyXu1.js.map} +1 -1
  134. package/dist/static/assets/{xychartDiagram-PRI3JC2R-C_h3_ICR.js → xychartDiagram-PRI3JC2R-DVYEo5aJ.js} +3 -3
  135. package/dist/static/assets/{xychartDiagram-PRI3JC2R-C_h3_ICR.js.map → xychartDiagram-PRI3JC2R-DVYEo5aJ.js.map} +1 -1
  136. package/dist/static/index.html +1 -1
  137. package/dist/team.js +52 -48
  138. package/dist/tellask.js +439 -0
  139. package/dist/tools/context-health.js +177 -0
  140. package/dist/tools/diag.js +583 -0
  141. package/dist/tools/fs.js +194 -68
  142. package/dist/tools/prompts/memory/en/principles.md +13 -5
  143. package/dist/tools/prompts/memory/en/tools.md +11 -36
  144. package/dist/tools/prompts/memory/zh/principles.md +18 -8
  145. package/dist/tools/prompts/memory/zh/tools.md +11 -36
  146. package/dist/tools/team-mgmt.js +3487 -0
  147. package/dist/utils/task-doc.js +236 -0
  148. package/package.json +1 -1
  149. package/dist/static/assets/index-HWTRvE2k.js.map +0 -1
@@ -0,0 +1,370 @@
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.APPS_RESOLUTION_REL_PATH = exports.DEFAULT_APPS_RESOLUTION_STRATEGY = void 0;
7
+ exports.loadAppsResolutionFile = loadAppsResolutionFile;
8
+ exports.writeAppsResolutionFile = writeAppsResolutionFile;
9
+ exports.writeAppsResolutionFileIfChanged = writeAppsResolutionFileIfChanged;
10
+ exports.findResolvedApp = findResolvedApp;
11
+ exports.upsertResolvedApp = upsertResolvedApp;
12
+ exports.removeResolvedApp = removeResolvedApp;
13
+ exports.setResolvedAppUserEnabled = setResolvedAppUserEnabled;
14
+ exports.setResolvedAppAssignedPort = setResolvedAppAssignedPort;
15
+ exports.applyEffectiveEnabledToResolvedApps = applyEffectiveEnabledToResolvedApps;
16
+ exports.applyAssignedPortToResolvedApps = applyAssignedPortToResolvedApps;
17
+ const promises_1 = __importDefault(require("fs/promises"));
18
+ const path_1 = __importDefault(require("path"));
19
+ const yaml_1 = __importDefault(require("yaml"));
20
+ const app_json_1 = require("./app-json");
21
+ exports.DEFAULT_APPS_RESOLUTION_STRATEGY = {
22
+ order: ['local'],
23
+ localRoots: ['dominds-apps'],
24
+ };
25
+ exports.APPS_RESOLUTION_REL_PATH = path_1.default.join('.apps', 'resolution.yaml');
26
+ function isRecord(v) {
27
+ return typeof v === 'object' && v !== null && !Array.isArray(v);
28
+ }
29
+ function asString(v) {
30
+ return typeof v === 'string' ? v : null;
31
+ }
32
+ function asBool(v) {
33
+ return typeof v === 'boolean' ? v : null;
34
+ }
35
+ function asNullableNumber(v) {
36
+ if (v === null)
37
+ return null;
38
+ if (typeof v === 'number' && Number.isFinite(v))
39
+ return v;
40
+ return null;
41
+ }
42
+ function parseResolutionStrategy(v, at) {
43
+ if (!isRecord(v))
44
+ return { ok: false, errorText: `Invalid ${at}: expected object` };
45
+ const keys = Object.keys(v);
46
+ for (const k of keys) {
47
+ if (k !== 'order' && k !== 'localRoots') {
48
+ return { ok: false, errorText: `Invalid ${at}: unknown key '${k}'` };
49
+ }
50
+ }
51
+ const orderRaw = v['order'];
52
+ const order = (() => {
53
+ if (orderRaw === undefined)
54
+ return undefined;
55
+ if (!Array.isArray(orderRaw)) {
56
+ return { ok: false, errorText: `Invalid ${at}.order: expected array` };
57
+ }
58
+ const out = [];
59
+ for (let i = 0; i < orderRaw.length; i += 1) {
60
+ const item = orderRaw[i];
61
+ if (item !== 'local' && item !== 'npx') {
62
+ return {
63
+ ok: false,
64
+ errorText: `Invalid ${at}.order[${i}]: expected 'local'|'npx'`,
65
+ };
66
+ }
67
+ out.push(item);
68
+ }
69
+ if (out.length === 0) {
70
+ return { ok: false, errorText: `Invalid ${at}.order: must not be empty` };
71
+ }
72
+ return { ok: true, value: out };
73
+ })();
74
+ if (order && !order.ok)
75
+ return order;
76
+ const localRootsRaw = v['localRoots'];
77
+ const localRoots = (() => {
78
+ if (localRootsRaw === undefined)
79
+ return undefined;
80
+ if (!Array.isArray(localRootsRaw)) {
81
+ return { ok: false, errorText: `Invalid ${at}.localRoots: expected array` };
82
+ }
83
+ const out = [];
84
+ for (let i = 0; i < localRootsRaw.length; i += 1) {
85
+ const item = localRootsRaw[i];
86
+ if (typeof item !== 'string' || item.trim() === '') {
87
+ return {
88
+ ok: false,
89
+ errorText: `Invalid ${at}.localRoots[${i}]: expected non-empty string`,
90
+ };
91
+ }
92
+ out.push(item.trim());
93
+ }
94
+ if (out.length === 0) {
95
+ return { ok: false, errorText: `Invalid ${at}.localRoots: must not be empty` };
96
+ }
97
+ return { ok: true, value: out };
98
+ })();
99
+ if (localRoots && !localRoots.ok)
100
+ return localRoots;
101
+ return {
102
+ ok: true,
103
+ strategy: {
104
+ order: order ? order.value : undefined,
105
+ localRoots: localRoots ? localRoots.value : undefined,
106
+ },
107
+ };
108
+ }
109
+ function parseSource(v, at) {
110
+ if (!isRecord(v))
111
+ return { ok: false, errorText: `Invalid ${at}: expected object` };
112
+ const kind = asString(v['kind']);
113
+ if (kind !== 'npx' && kind !== 'local') {
114
+ return { ok: false, errorText: `Invalid ${at}.kind: expected 'npx'|'local'` };
115
+ }
116
+ if (kind === 'npx') {
117
+ const spec = asString(v['spec']);
118
+ if (!spec || spec.trim() === '')
119
+ return { ok: false, errorText: `Invalid ${at}.spec: required` };
120
+ return { ok: true, source: { kind, spec } };
121
+ }
122
+ const pathAbs = asString(v['pathAbs']);
123
+ if (!pathAbs || pathAbs.trim() === '')
124
+ return { ok: false, errorText: `Invalid ${at}.pathAbs: required` };
125
+ return { ok: true, source: { kind, pathAbs } };
126
+ }
127
+ function parseEntry(v, at) {
128
+ if (!isRecord(v))
129
+ return { ok: false, errorText: `Invalid ${at}: expected object` };
130
+ const id = asString(v['id']);
131
+ if (!id || id.trim() === '')
132
+ return { ok: false, errorText: `Invalid ${at}.id: required` };
133
+ const enabled = asBool(v['enabled']);
134
+ if (enabled === null)
135
+ return { ok: false, errorText: `Invalid ${at}.enabled: boolean required` };
136
+ const userEnabledRaw = v['userEnabled'];
137
+ const userEnabled = userEnabledRaw === undefined ? enabled : asBool(userEnabledRaw);
138
+ if (userEnabled === null) {
139
+ return { ok: false, errorText: `Invalid ${at}.userEnabled: expected boolean` };
140
+ }
141
+ const assignedPortRaw = v['assignedPort'] ?? null;
142
+ const assignedPort = asNullableNumber(assignedPortRaw);
143
+ if (assignedPort === null) {
144
+ if (assignedPortRaw !== null) {
145
+ return { ok: false, errorText: `Invalid ${at}.assignedPort: expected number|null` };
146
+ }
147
+ }
148
+ else {
149
+ if (!Number.isInteger(assignedPort) || assignedPort <= 0) {
150
+ return { ok: false, errorText: `Invalid ${at}.assignedPort: expected positive integer|null` };
151
+ }
152
+ }
153
+ const sourceParsed = parseSource(v['source'], `${at}.source`);
154
+ if (!sourceParsed.ok)
155
+ return sourceParsed;
156
+ const installJsonRaw = v['installJson'];
157
+ const installJsonParsed = (0, app_json_1.parseDomindsAppInstallJson)(installJsonRaw);
158
+ if (!installJsonParsed.ok) {
159
+ return { ok: false, errorText: `Invalid ${at}.installJson: ${installJsonParsed.errorText}` };
160
+ }
161
+ return {
162
+ ok: true,
163
+ entry: {
164
+ id,
165
+ enabled,
166
+ userEnabled,
167
+ source: sourceParsed.source,
168
+ assignedPort,
169
+ installJson: installJsonParsed.json,
170
+ },
171
+ };
172
+ }
173
+ async function loadAppsResolutionFile(params) {
174
+ const filePathAbs = path_1.default.resolve(params.rtwsRootAbs, exports.APPS_RESOLUTION_REL_PATH);
175
+ let raw;
176
+ try {
177
+ raw = await promises_1.default.readFile(filePathAbs, 'utf-8');
178
+ }
179
+ catch (err) {
180
+ const isEnoent = typeof err === 'object' &&
181
+ err !== null &&
182
+ 'code' in err &&
183
+ err.code === 'ENOENT';
184
+ if (isEnoent) {
185
+ return { kind: 'ok', filePathAbs, file: { schemaVersion: 1, apps: [] } };
186
+ }
187
+ return {
188
+ kind: 'error',
189
+ filePathAbs,
190
+ errorText: err instanceof Error ? err.message : String(err),
191
+ };
192
+ }
193
+ let parsed;
194
+ try {
195
+ parsed = yaml_1.default.parse(raw);
196
+ }
197
+ catch (err) {
198
+ return {
199
+ kind: 'error',
200
+ filePathAbs,
201
+ errorText: `Failed to parse YAML: ${err instanceof Error ? err.message : String(err)}`,
202
+ };
203
+ }
204
+ if (!isRecord(parsed)) {
205
+ return { kind: 'error', filePathAbs, errorText: 'Invalid resolution.yaml: expected object' };
206
+ }
207
+ const schemaVersion = parsed['schemaVersion'];
208
+ if (schemaVersion !== 1) {
209
+ return {
210
+ kind: 'error',
211
+ filePathAbs,
212
+ errorText: `Unsupported schemaVersion: ${String(schemaVersion)}`,
213
+ };
214
+ }
215
+ const appsRaw = parsed['apps'];
216
+ if (!Array.isArray(appsRaw)) {
217
+ return {
218
+ kind: 'error',
219
+ filePathAbs,
220
+ errorText: 'Invalid resolution.yaml: apps must be an array',
221
+ };
222
+ }
223
+ const apps = [];
224
+ for (let i = 0; i < appsRaw.length; i += 1) {
225
+ const e = parseEntry(appsRaw[i], `apps[${i}]`);
226
+ if (!e.ok)
227
+ return { kind: 'error', filePathAbs, errorText: e.errorText };
228
+ apps.push(e.entry);
229
+ }
230
+ const strategyRaw = parsed['resolutionStrategy'];
231
+ const resolutionStrategy = (() => {
232
+ if (strategyRaw === undefined)
233
+ return undefined;
234
+ const parsedStrategy = parseResolutionStrategy(strategyRaw, 'resolutionStrategy');
235
+ if (!parsedStrategy.ok)
236
+ return parsedStrategy;
237
+ return { ok: true, value: parsedStrategy.strategy };
238
+ })();
239
+ if (resolutionStrategy && !resolutionStrategy.ok) {
240
+ return { kind: 'error', filePathAbs, errorText: resolutionStrategy.errorText };
241
+ }
242
+ const file = resolutionStrategy
243
+ ? {
244
+ schemaVersion: 1,
245
+ resolutionStrategy: resolutionStrategy.value,
246
+ apps,
247
+ }
248
+ : { schemaVersion: 1, apps };
249
+ return { kind: 'ok', filePathAbs, file };
250
+ }
251
+ async function writeAppsResolutionFile(params) {
252
+ const dirAbs = path_1.default.resolve(params.rtwsRootAbs, '.apps');
253
+ await promises_1.default.mkdir(dirAbs, { recursive: true });
254
+ const filePathAbs = path_1.default.resolve(params.rtwsRootAbs, exports.APPS_RESOLUTION_REL_PATH);
255
+ const yamlText = yaml_1.default.stringify(params.file);
256
+ await promises_1.default.writeFile(filePathAbs, yamlText, 'utf-8');
257
+ }
258
+ async function writeAppsResolutionFileIfChanged(params) {
259
+ const dirAbs = path_1.default.resolve(params.rtwsRootAbs, '.apps');
260
+ await promises_1.default.mkdir(dirAbs, { recursive: true });
261
+ const filePathAbs = path_1.default.resolve(params.rtwsRootAbs, exports.APPS_RESOLUTION_REL_PATH);
262
+ const yamlText = yaml_1.default.stringify(params.file);
263
+ try {
264
+ const prev = await promises_1.default.readFile(filePathAbs, 'utf-8');
265
+ if (prev === yamlText)
266
+ return;
267
+ }
268
+ catch (err) {
269
+ const isEnoent = typeof err === 'object' &&
270
+ err !== null &&
271
+ 'code' in err &&
272
+ err.code === 'ENOENT';
273
+ if (!isEnoent)
274
+ throw err;
275
+ }
276
+ await promises_1.default.writeFile(filePathAbs, yamlText, 'utf-8');
277
+ }
278
+ function findResolvedApp(file, appId) {
279
+ const found = file.apps.find((a) => a.id === appId);
280
+ return found ?? null;
281
+ }
282
+ function upsertResolvedApp(params) {
283
+ const apps = [...params.existing.apps];
284
+ const idx = apps.findIndex((a) => a.id === params.next.id);
285
+ if (idx >= 0)
286
+ apps[idx] = params.next;
287
+ else
288
+ apps.push(params.next);
289
+ const resolutionStrategy = params.existing.resolutionStrategy;
290
+ return resolutionStrategy !== undefined
291
+ ? { schemaVersion: 1, resolutionStrategy, apps }
292
+ : { schemaVersion: 1, apps };
293
+ }
294
+ function removeResolvedApp(params) {
295
+ if (!params.existing.apps.some((a) => a.id === params.appId))
296
+ return params.existing;
297
+ const apps = params.existing.apps.filter((a) => a.id !== params.appId);
298
+ const resolutionStrategy = params.existing.resolutionStrategy;
299
+ return resolutionStrategy !== undefined
300
+ ? { schemaVersion: 1, resolutionStrategy, apps }
301
+ : { schemaVersion: 1, apps };
302
+ }
303
+ function setResolvedAppUserEnabled(params) {
304
+ const existingApp = findResolvedApp(params.existing, params.appId);
305
+ if (!existingApp)
306
+ return params.existing;
307
+ if (existingApp.userEnabled === params.userEnabled && existingApp.enabled === params.userEnabled)
308
+ return params.existing;
309
+ const apps = params.existing.apps.map((a) => a.id === params.appId
310
+ ? { ...a, userEnabled: params.userEnabled, enabled: params.userEnabled }
311
+ : a);
312
+ const resolutionStrategy = params.existing.resolutionStrategy;
313
+ return resolutionStrategy !== undefined
314
+ ? { schemaVersion: 1, resolutionStrategy, apps }
315
+ : { schemaVersion: 1, apps };
316
+ }
317
+ function setResolvedAppAssignedPort(params) {
318
+ if (params.assignedPort !== null) {
319
+ if (!Number.isInteger(params.assignedPort) || params.assignedPort <= 0) {
320
+ throw new Error(`Invalid assignedPort: expected positive integer|null (got ${params.assignedPort})`);
321
+ }
322
+ }
323
+ const existingApp = findResolvedApp(params.existing, params.appId);
324
+ if (!existingApp)
325
+ return params.existing;
326
+ if (existingApp.assignedPort === params.assignedPort)
327
+ return params.existing;
328
+ const apps = params.existing.apps.map((a) => a.id === params.appId ? { ...a, assignedPort: params.assignedPort } : a);
329
+ const resolutionStrategy = params.existing.resolutionStrategy;
330
+ return resolutionStrategy !== undefined
331
+ ? { schemaVersion: 1, resolutionStrategy, apps }
332
+ : { schemaVersion: 1, apps };
333
+ }
334
+ function applyEffectiveEnabledToResolvedApps(params) {
335
+ let changed = false;
336
+ const apps = params.existing.apps.map((a) => {
337
+ const effectiveEnabled = params.effectiveEnabledById.get(a.id);
338
+ if (effectiveEnabled === undefined || effectiveEnabled === a.enabled)
339
+ return a;
340
+ changed = true;
341
+ return { ...a, enabled: effectiveEnabled };
342
+ });
343
+ if (!changed)
344
+ return params.existing;
345
+ const resolutionStrategy = params.existing.resolutionStrategy;
346
+ return resolutionStrategy !== undefined
347
+ ? { schemaVersion: 1, resolutionStrategy, apps }
348
+ : { schemaVersion: 1, apps };
349
+ }
350
+ function applyAssignedPortToResolvedApps(params) {
351
+ let changed = false;
352
+ const apps = params.existing.apps.map((a) => {
353
+ const assignedPort = params.assignedPortById.get(a.id);
354
+ if (assignedPort === undefined || assignedPort === a.assignedPort)
355
+ return a;
356
+ if (assignedPort !== null) {
357
+ if (!Number.isInteger(assignedPort) || assignedPort <= 0) {
358
+ throw new Error(`Invalid assignedPort writeback for '${a.id}': ${String(assignedPort)}`);
359
+ }
360
+ }
361
+ changed = true;
362
+ return { ...a, assignedPort };
363
+ });
364
+ if (!changed)
365
+ return params.existing;
366
+ const resolutionStrategy = params.existing.resolutionStrategy;
367
+ return resolutionStrategy !== undefined
368
+ ? { schemaVersion: 1, resolutionStrategy, apps }
369
+ : { schemaVersion: 1, apps };
370
+ }
@@ -9,7 +9,7 @@ const registry_1 = require("../tools/registry");
9
9
  const client_1 = require("../apps-host/client");
10
10
  const dialog_run_controls_1 = require("./dialog-run-controls");
11
11
  const enabled_apps_1 = require("./enabled-apps");
12
- const installed_file_1 = require("./installed-file");
12
+ const problems_1 = require("./problems");
13
13
  const log = (0, log_1.createLogger)('apps-runtime');
14
14
  let appsHostClient = null;
15
15
  const proxyRegisteredAppIds = new Set();
@@ -91,6 +91,7 @@ function registerAppDialogRunControlsForEnabledApps(params) {
91
91
  }
92
92
  async function registerEnabledAppsToolProxies(params) {
93
93
  const snapshot = await (0, enabled_apps_1.loadEnabledAppsSnapshot)({ rtwsRootAbs: params.rtwsRootAbs });
94
+ (0, problems_1.reconcileAppsResolutionIssuesToProblems)({ issues: snapshot.issues });
94
95
  const enabledApps = snapshot.enabledApps.map((a) => ({
95
96
  appId: a.id,
96
97
  runtimePort: a.runtimePort,
@@ -105,6 +106,7 @@ async function initAppsRuntime(params) {
105
106
  throw new Error('Apps runtime already initialized');
106
107
  }
107
108
  const snapshot = await (0, enabled_apps_1.loadEnabledAppsSnapshot)({ rtwsRootAbs: params.rtwsRootAbs });
109
+ (0, problems_1.reconcileAppsResolutionIssuesToProblems)({ issues: snapshot.issues });
108
110
  const enabledApps = snapshot.enabledApps.map((a) => ({
109
111
  appId: a.id,
110
112
  runtimePort: a.runtimePort,
@@ -119,24 +121,10 @@ async function initAppsRuntime(params) {
119
121
  // Register dialog run controls before websocket handlers start processing user drives.
120
122
  registerAppDialogRunControlsForEnabledApps({ enabledApps });
121
123
  log.info(`Starting apps-host (${enabledApps.length} enabled apps)`);
122
- const started = await (0, client_1.startAppsHost)({
124
+ const { client } = await (0, client_1.startAppsHost)({
123
125
  rtwsRootAbs: params.rtwsRootAbs,
124
126
  kernel: params.kernel,
125
127
  apps: enabledApps,
126
128
  });
127
- appsHostClient = started.client;
128
- // Persist actual bound ports for enabled apps (especially when runtimePort=0 for ephemeral ports).
129
- const loaded = await (0, installed_file_1.loadInstalledAppsFile)({ rtwsRootAbs: params.rtwsRootAbs });
130
- if (loaded.kind === 'error') {
131
- throw new Error(`Failed to update installed apps runtime ports: ${loaded.errorText} (${loaded.filePathAbs})`);
132
- }
133
- let nextFile = loaded.file;
134
- for (const a of started.ready.apps) {
135
- if (!a.frontend)
136
- continue;
137
- nextFile = (0, installed_file_1.setAppRuntimePort)({ existing: nextFile, appId: a.appId, port: a.frontend.port });
138
- }
139
- if (nextFile !== loaded.file) {
140
- await (0, installed_file_1.writeInstalledAppsFile)({ rtwsRootAbs: params.rtwsRootAbs, file: nextFile });
141
- }
129
+ appsHostClient = client;
142
130
  }
@@ -8,22 +8,123 @@ const promises_1 = __importDefault(require("fs/promises"));
8
8
  const path_1 = __importDefault(require("path"));
9
9
  const yaml_1 = __importDefault(require("yaml"));
10
10
  const enabled_apps_1 = require("./enabled-apps");
11
+ const manifest_1 = require("./manifest");
11
12
  const override_paths_1 = require("./override-paths");
13
+ const package_info_1 = require("./package-info");
12
14
  function isRecord(v) {
13
15
  return typeof v === 'object' && v !== null && !Array.isArray(v);
14
16
  }
17
+ async function loadEnabledAppDependencyGraph(params) {
18
+ const enabledIds = new Set(params.enabledApps.map((app) => app.id));
19
+ const out = new Map();
20
+ for (const app of params.enabledApps) {
21
+ try {
22
+ const pkgInfo = await (0, package_info_1.readPackageInfo)({ packageRootAbs: app.packageRootAbs });
23
+ const loaded = await (0, manifest_1.loadDomindsAppManifest)({
24
+ packageRootAbs: app.packageRootAbs,
25
+ manifestRelPath: pkgInfo.manifestRelPath,
26
+ });
27
+ if (loaded.kind !== 'ok') {
28
+ out.set(app.id, new Set());
29
+ continue;
30
+ }
31
+ const deps = new Set();
32
+ for (const dep of loaded.manifest.dependencies ?? []) {
33
+ const depId = dep.id.trim();
34
+ if (depId === '' || !enabledIds.has(depId))
35
+ continue;
36
+ deps.add(depId);
37
+ }
38
+ out.set(app.id, deps);
39
+ }
40
+ catch {
41
+ // Fail-open for override owner discovery: unresolved owner deps just don't contribute overrides.
42
+ out.set(app.id, new Set());
43
+ }
44
+ }
45
+ return out;
46
+ }
47
+ function computeOverrideOwnersByTarget(params) {
48
+ const packageRootByAppId = new Map();
49
+ const ownersByDep = new Map();
50
+ for (const app of params.enabledApps) {
51
+ packageRootByAppId.set(app.id, app.packageRootAbs);
52
+ }
53
+ for (const [ownerId, depIds] of params.depGraphByOwner.entries()) {
54
+ for (const depId of depIds) {
55
+ const owners = ownersByDep.get(depId);
56
+ if (owners) {
57
+ owners.push(ownerId);
58
+ }
59
+ else {
60
+ ownersByDep.set(depId, [ownerId]);
61
+ }
62
+ }
63
+ }
64
+ const result = new Map();
65
+ for (const targetApp of params.enabledApps) {
66
+ const targetId = targetApp.id;
67
+ const depthByOwner = new Map();
68
+ const queue = [];
69
+ for (const ownerId of ownersByDep.get(targetId) ?? []) {
70
+ if (ownerId === targetId)
71
+ continue;
72
+ depthByOwner.set(ownerId, 1);
73
+ queue.push({ ownerId, depth: 1 });
74
+ }
75
+ // Use shortest dependency distance from target to owner so traversal remains bounded
76
+ // even when enabled apps contain dependency cycles.
77
+ for (let i = 0; i < queue.length; i += 1) {
78
+ const current = queue[i];
79
+ const nextOwners = ownersByDep.get(current.ownerId) ?? [];
80
+ for (const nextOwnerId of nextOwners) {
81
+ if (nextOwnerId === targetId)
82
+ continue;
83
+ const nextDepth = current.depth + 1;
84
+ const prevDepth = depthByOwner.get(nextOwnerId);
85
+ if (prevDepth !== undefined && prevDepth <= nextDepth)
86
+ continue;
87
+ depthByOwner.set(nextOwnerId, nextDepth);
88
+ queue.push({ ownerId: nextOwnerId, depth: nextDepth });
89
+ }
90
+ }
91
+ const owners = [...depthByOwner.entries()]
92
+ .sort((a, b) => {
93
+ if (a[1] !== b[1])
94
+ return b[1] - a[1];
95
+ return a[0].localeCompare(b[0]);
96
+ })
97
+ .map(([ownerId]) => {
98
+ const packageRootAbs = packageRootByAppId.get(ownerId);
99
+ if (!packageRootAbs)
100
+ return null;
101
+ return { appId: ownerId, packageRootAbs };
102
+ })
103
+ .filter((owner) => owner !== null);
104
+ result.set(targetId, owners);
105
+ }
106
+ return result;
107
+ }
15
108
  async function loadEnabledAppTeammates(params) {
16
109
  const snap = await (0, enabled_apps_1.loadEnabledAppsSnapshot)({ rtwsRootAbs: params.rtwsRootAbs });
110
+ const enabledApps = snap.enabledApps.map((app) => ({
111
+ id: app.id,
112
+ packageRootAbs: app.installJson.package.rootAbs,
113
+ }));
114
+ const depGraphByOwner = await loadEnabledAppDependencyGraph({ enabledApps });
115
+ const overrideOwnersByTarget = computeOverrideOwnersByTarget({ enabledApps, depGraphByOwner });
17
116
  const out = [];
18
117
  for (const app of snap.enabledApps) {
19
118
  const rel = app.installJson.contributes?.teammatesYamlRelPath;
20
119
  if (!rel)
21
120
  continue;
22
- // Workspace overrides (new root + legacy root).
121
+ const appOverrideOwners = overrideOwnersByTarget.get(app.id) ?? [];
122
+ // Priority: rtws override > app override (integrator-provided) > app defaults.
23
123
  const override = await (0, override_paths_1.resolveAppOverrideFileAbs)({
24
124
  rtwsRootAbs: params.rtwsRootAbs,
25
125
  appId: app.id,
26
126
  appRelPath: rel,
127
+ appOverrideOwners,
27
128
  });
28
129
  const filePathAbs = override.kind === 'found'
29
130
  ? override.filePathAbs
@@ -8,7 +8,7 @@
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.main = main;
11
- const installed_file_1 = require("../apps/installed-file");
11
+ const resolution_file_1 = require("../apps/resolution-file");
12
12
  function printHelp() {
13
13
  console.log(`Usage:
14
14
  dominds disable <appId>
@@ -41,20 +41,24 @@ async function main() {
41
41
  return;
42
42
  }
43
43
  const rtwsRootAbs = process.cwd();
44
- const loaded = await (0, installed_file_1.loadInstalledAppsFile)({ rtwsRootAbs });
44
+ const loaded = await (0, resolution_file_1.loadAppsResolutionFile)({ rtwsRootAbs });
45
45
  if (loaded.kind === 'error') {
46
- console.error(`Error: failed to read ${installed_file_1.INSTALLED_APPS_REL_PATH}: ${loaded.errorText}`);
46
+ console.error(`Error: failed to read ${resolution_file_1.APPS_RESOLUTION_REL_PATH}: ${loaded.errorText}`);
47
47
  process.exit(1);
48
48
  return;
49
49
  }
50
- const found = (0, installed_file_1.findInstalledApp)(loaded.file, args.appId);
50
+ const found = (0, resolution_file_1.findResolvedApp)(loaded.file, args.appId);
51
51
  if (!found) {
52
52
  console.error(`Error: app '${args.appId}' not installed`);
53
53
  process.exit(1);
54
54
  return;
55
55
  }
56
- const next = (0, installed_file_1.setAppEnabled)({ existing: loaded.file, appId: args.appId, enabled: false });
57
- await (0, installed_file_1.writeInstalledAppsFile)({ rtwsRootAbs, file: next });
56
+ const next = (0, resolution_file_1.setResolvedAppUserEnabled)({
57
+ existing: loaded.file,
58
+ appId: args.appId,
59
+ userEnabled: false,
60
+ });
61
+ await (0, resolution_file_1.writeAppsResolutionFile)({ rtwsRootAbs, file: next });
58
62
  console.log(`Disabled app '${args.appId}'`);
59
63
  }
60
64
  if (require.main === module) {
@@ -8,14 +8,14 @@
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.main = main;
11
- const installed_file_1 = require("../apps/installed-file");
12
- const runtime_port_1 = require("../apps/runtime-port");
11
+ const assigned_port_1 = require("../apps/assigned-port");
12
+ const resolution_file_1 = require("../apps/resolution-file");
13
13
  function printHelp() {
14
14
  console.log(`Usage:
15
15
  dominds enable <appId> [--port <port>]
16
16
 
17
17
  Options:
18
- --port <port> Set frontend port (stored in ${installed_file_1.INSTALLED_APPS_REL_PATH})
18
+ --port <port> Set frontend port (stored in ${resolution_file_1.APPS_RESOLUTION_REL_PATH}); use 0 to clear
19
19
  `);
20
20
  }
21
21
  function parseArgs(argv) {
@@ -59,38 +59,40 @@ async function main() {
59
59
  return;
60
60
  }
61
61
  const rtwsRootAbs = process.cwd();
62
- const loaded = await (0, installed_file_1.loadInstalledAppsFile)({ rtwsRootAbs });
62
+ const loaded = await (0, resolution_file_1.loadAppsResolutionFile)({ rtwsRootAbs });
63
63
  if (loaded.kind === 'error') {
64
- console.error(`Error: failed to read ${installed_file_1.INSTALLED_APPS_REL_PATH}: ${loaded.errorText}`);
64
+ console.error(`Error: failed to read ${resolution_file_1.APPS_RESOLUTION_REL_PATH}: ${loaded.errorText}`);
65
65
  process.exit(1);
66
66
  return;
67
67
  }
68
- const found = (0, installed_file_1.findInstalledApp)(loaded.file, args.appId);
68
+ const found = (0, resolution_file_1.findResolvedApp)(loaded.file, args.appId);
69
69
  if (!found) {
70
70
  console.error(`Error: app '${args.appId}' not installed`);
71
71
  process.exit(1);
72
72
  return;
73
73
  }
74
- let next = (0, installed_file_1.setAppEnabled)({ existing: loaded.file, appId: args.appId, enabled: true });
74
+ let next = (0, resolution_file_1.setResolvedAppUserEnabled)({
75
+ existing: loaded.file,
76
+ appId: args.appId,
77
+ userEnabled: true,
78
+ });
75
79
  if (args.port !== null) {
76
- next = (0, installed_file_1.setAppRuntimePort)({ existing: next, appId: args.appId, port: args.port });
80
+ next = (0, resolution_file_1.setResolvedAppAssignedPort)({
81
+ existing: next,
82
+ appId: args.appId,
83
+ assignedPort: args.port === 0 ? null : args.port,
84
+ });
77
85
  }
78
86
  else {
79
- const resolvedPort = await (0, runtime_port_1.resolveStableAppRuntimePort)({
87
+ const assignedPort = await (0, assigned_port_1.resolveStableAssignedPort)({
80
88
  appId: found.id,
81
89
  installJson: found.installJson,
82
- existingApps: loaded.file.apps,
83
- existingRuntimePort: found.runtime.port,
90
+ existingApps: next.apps,
91
+ existingAssignedPort: found.assignedPort,
84
92
  });
85
- if (resolvedPort !== found.runtime.port) {
86
- next = (0, installed_file_1.setAppRuntimePort)({
87
- existing: next,
88
- appId: args.appId,
89
- port: resolvedPort,
90
- });
91
- }
93
+ next = (0, resolution_file_1.setResolvedAppAssignedPort)({ existing: next, appId: args.appId, assignedPort });
92
94
  }
93
- await (0, installed_file_1.writeInstalledAppsFile)({ rtwsRootAbs, file: next });
95
+ await (0, resolution_file_1.writeAppsResolutionFile)({ rtwsRootAbs, file: next });
94
96
  console.log(`Enabled app '${args.appId}'`);
95
97
  }
96
98
  if (require.main === module) {