dominds 1.2.4 → 1.2.6

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 (144) 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 +0 -5
  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/cli/disable.js +10 -6
  11. package/dist/cli/enable.js +21 -19
  12. package/dist/cli/install.js +40 -18
  13. package/dist/cli/uninstall.js +6 -6
  14. package/dist/cli/update.js +38 -13
  15. package/dist/docs/app-constitution.md +85 -18
  16. package/dist/docs/app-constitution.zh.md +86 -21
  17. package/dist/docs/dialog-system.md +1 -1
  18. package/dist/docs/dialog-system.zh.md +1 -1
  19. package/dist/docs/dominds-agent-priming.md +218 -0
  20. package/dist/docs/dominds-agent-priming.zh.md +196 -0
  21. package/dist/docs/drive-logic-context-refactor-plan.zh.md +338 -0
  22. package/dist/docs/keep-going.md +176 -0
  23. package/dist/docs/keep-going.zh.md +162 -0
  24. package/dist/docs/showing-by-doing.md +208 -0
  25. package/dist/docs/showing-by-doing.zh.md +177 -0
  26. package/dist/docs/team-mgmt-toolset.md +482 -0
  27. package/dist/docs/team-mgmt-toolset.zh.md +426 -0
  28. package/dist/llm/defaults.yaml +1 -1
  29. package/dist/llm/driver.js +4093 -0
  30. package/dist/minds/promptdocs.js +263 -0
  31. package/dist/server/api-routes.js +333 -0
  32. package/dist/server/prompts-routes.js +545 -0
  33. package/dist/server/server-core.js +4 -0
  34. package/dist/shared/team-mgmt-manual.js +120 -0
  35. package/dist/shared/types/prompts.js +2 -0
  36. package/dist/shared/types/tellask.js +8 -0
  37. package/dist/showing-by-doing.js +1091 -0
  38. package/dist/snippets/README.en.md +3 -0
  39. package/dist/snippets/README.md +4 -0
  40. package/dist/static/assets/{_basePickBy-CupsMxbi.js → _basePickBy-5YF_9hQW.js} +3 -3
  41. package/dist/static/assets/{_basePickBy-CupsMxbi.js.map → _basePickBy-5YF_9hQW.js.map} +1 -1
  42. package/dist/static/assets/{_baseUniq-BDcVFZR0.js → _baseUniq-jhU9AUhp.js} +2 -2
  43. package/dist/static/assets/{_baseUniq-BDcVFZR0.js.map → _baseUniq-jhU9AUhp.js.map} +1 -1
  44. package/dist/static/assets/{arc-E_Wq3ZBA.js → arc-CxfO0spY.js} +2 -2
  45. package/dist/static/assets/{arc-E_Wq3ZBA.js.map → arc-CxfO0spY.js.map} +1 -1
  46. package/dist/static/assets/{architectureDiagram-VXUJARFQ-522n5Xxv.js → architectureDiagram-VXUJARFQ-DdfdIFQM.js} +7 -7
  47. package/dist/static/assets/{architectureDiagram-VXUJARFQ-522n5Xxv.js.map → architectureDiagram-VXUJARFQ-DdfdIFQM.js.map} +1 -1
  48. package/dist/static/assets/{blockDiagram-VD42YOAC-BLN9Y7a8.js → blockDiagram-VD42YOAC-Cwqz2taZ.js} +7 -7
  49. package/dist/static/assets/{blockDiagram-VD42YOAC-BLN9Y7a8.js.map → blockDiagram-VD42YOAC-Cwqz2taZ.js.map} +1 -1
  50. package/dist/static/assets/{c4Diagram-YG6GDRKO-BwhzzgYq.js → c4Diagram-YG6GDRKO-B4tMGdJJ.js} +3 -3
  51. package/dist/static/assets/{c4Diagram-YG6GDRKO-BwhzzgYq.js.map → c4Diagram-YG6GDRKO-B4tMGdJJ.js.map} +1 -1
  52. package/dist/static/assets/{channel-fLVkm5NV.js → channel-vcTCKrpR.js} +2 -2
  53. package/dist/static/assets/{channel-fLVkm5NV.js.map → channel-vcTCKrpR.js.map} +1 -1
  54. package/dist/static/assets/{chunk-4BX2VUAB-1D1VasqQ.js → chunk-4BX2VUAB-9jaRyZiz.js} +2 -2
  55. package/dist/static/assets/{chunk-4BX2VUAB-1D1VasqQ.js.map → chunk-4BX2VUAB-9jaRyZiz.js.map} +1 -1
  56. package/dist/static/assets/{chunk-55IACEB6-CdrmLoJU.js → chunk-55IACEB6-CqFPCghN.js} +2 -2
  57. package/dist/static/assets/{chunk-55IACEB6-CdrmLoJU.js.map → chunk-55IACEB6-CqFPCghN.js.map} +1 -1
  58. package/dist/static/assets/{chunk-B4BG7PRW-BT6zSZ9C.js → chunk-B4BG7PRW-BVwJVEzB.js} +5 -5
  59. package/dist/static/assets/{chunk-B4BG7PRW-BT6zSZ9C.js.map → chunk-B4BG7PRW-BVwJVEzB.js.map} +1 -1
  60. package/dist/static/assets/{chunk-DI55MBZ5-D2pGqzLg.js → chunk-DI55MBZ5-i9DDRLYs.js} +4 -4
  61. package/dist/static/assets/{chunk-DI55MBZ5-D2pGqzLg.js.map → chunk-DI55MBZ5-i9DDRLYs.js.map} +1 -1
  62. package/dist/static/assets/{chunk-FMBD7UC4-Dly3juUJ.js → chunk-FMBD7UC4-DtB9tnhF.js} +2 -2
  63. package/dist/static/assets/{chunk-FMBD7UC4-Dly3juUJ.js.map → chunk-FMBD7UC4-DtB9tnhF.js.map} +1 -1
  64. package/dist/static/assets/{chunk-QN33PNHL-BgEarQt4.js → chunk-QN33PNHL-Bzbixp1o.js} +2 -2
  65. package/dist/static/assets/{chunk-QN33PNHL-BgEarQt4.js.map → chunk-QN33PNHL-Bzbixp1o.js.map} +1 -1
  66. package/dist/static/assets/{chunk-QZHKN3VN-DedC1KyN.js → chunk-QZHKN3VN-CI-C5uv0.js} +2 -2
  67. package/dist/static/assets/{chunk-QZHKN3VN-DedC1KyN.js.map → chunk-QZHKN3VN-CI-C5uv0.js.map} +1 -1
  68. package/dist/static/assets/{chunk-TZMSLE5B-BEqexZui.js → chunk-TZMSLE5B-CANsFBw_.js} +2 -2
  69. package/dist/static/assets/{chunk-TZMSLE5B-BEqexZui.js.map → chunk-TZMSLE5B-CANsFBw_.js.map} +1 -1
  70. package/dist/static/assets/{classDiagram-2ON5EDUG-BrreExL9.js → classDiagram-2ON5EDUG-D00eOaDx.js} +6 -6
  71. package/dist/static/assets/{classDiagram-2ON5EDUG-BrreExL9.js.map → classDiagram-2ON5EDUG-D00eOaDx.js.map} +1 -1
  72. package/dist/static/assets/{classDiagram-v2-WZHVMYZB-BrreExL9.js → classDiagram-v2-WZHVMYZB-D00eOaDx.js} +6 -6
  73. package/dist/static/assets/{classDiagram-v2-WZHVMYZB-BrreExL9.js.map → classDiagram-v2-WZHVMYZB-D00eOaDx.js.map} +1 -1
  74. package/dist/static/assets/{clone-BbCzdf37.js → clone-BvOc2yso.js} +2 -2
  75. package/dist/static/assets/{clone-BbCzdf37.js.map → clone-BvOc2yso.js.map} +1 -1
  76. package/dist/static/assets/{cose-bilkent-S5V4N54A-EkgySXec.js → cose-bilkent-S5V4N54A-DSYAdAyx.js} +2 -2
  77. package/dist/static/assets/{cose-bilkent-S5V4N54A-EkgySXec.js.map → cose-bilkent-S5V4N54A-DSYAdAyx.js.map} +1 -1
  78. package/dist/static/assets/{dagre-6UL2VRFP-zF1TxR2b.js → dagre-6UL2VRFP-B7J4YtNM.js} +7 -7
  79. package/dist/static/assets/{dagre-6UL2VRFP-zF1TxR2b.js.map → dagre-6UL2VRFP-B7J4YtNM.js.map} +1 -1
  80. package/dist/static/assets/{diagram-PSM6KHXK-YfLDy7xM.js → diagram-PSM6KHXK-htuDE0_8.js} +8 -8
  81. package/dist/static/assets/{diagram-PSM6KHXK-YfLDy7xM.js.map → diagram-PSM6KHXK-htuDE0_8.js.map} +1 -1
  82. package/dist/static/assets/{diagram-QEK2KX5R-DT2Sl1-I.js → diagram-QEK2KX5R-g1GZbARf.js} +7 -7
  83. package/dist/static/assets/{diagram-QEK2KX5R-DT2Sl1-I.js.map → diagram-QEK2KX5R-g1GZbARf.js.map} +1 -1
  84. package/dist/static/assets/{diagram-S2PKOQOG-DuYxXn1P.js → diagram-S2PKOQOG-DYvwVsZm.js} +7 -7
  85. package/dist/static/assets/{diagram-S2PKOQOG-DuYxXn1P.js.map → diagram-S2PKOQOG-DYvwVsZm.js.map} +1 -1
  86. package/dist/static/assets/{erDiagram-Q2GNP2WA-SIbEeh3n.js → erDiagram-Q2GNP2WA-CuCw1fng.js} +5 -5
  87. package/dist/static/assets/{erDiagram-Q2GNP2WA-SIbEeh3n.js.map → erDiagram-Q2GNP2WA-CuCw1fng.js.map} +1 -1
  88. package/dist/static/assets/{flowDiagram-NV44I4VS-CLNKs4id.js → flowDiagram-NV44I4VS-B7e0sjm_.js} +6 -6
  89. package/dist/static/assets/{flowDiagram-NV44I4VS-CLNKs4id.js.map → flowDiagram-NV44I4VS-B7e0sjm_.js.map} +1 -1
  90. package/dist/static/assets/{ganttDiagram-JELNMOA3-tFaNfSzJ.js → ganttDiagram-JELNMOA3-BZRuh3DE.js} +3 -3
  91. package/dist/static/assets/{ganttDiagram-JELNMOA3-tFaNfSzJ.js.map → ganttDiagram-JELNMOA3-BZRuh3DE.js.map} +1 -1
  92. package/dist/static/assets/{gitGraphDiagram-V2S2FVAM-DqO129yJ.js → gitGraphDiagram-V2S2FVAM-B8lN7T9U.js} +8 -8
  93. package/dist/static/assets/{gitGraphDiagram-V2S2FVAM-DqO129yJ.js.map → gitGraphDiagram-V2S2FVAM-B8lN7T9U.js.map} +1 -1
  94. package/dist/static/assets/{graph-CcuoS4cG.js → graph-CVmBZVHx.js} +3 -3
  95. package/dist/static/assets/{graph-CcuoS4cG.js.map → graph-CVmBZVHx.js.map} +1 -1
  96. package/dist/static/assets/{index-C6rZcGnP.js → index-BMt8OZ6H.js} +442 -102
  97. package/dist/static/assets/index-BMt8OZ6H.js.map +1 -0
  98. package/dist/static/assets/{index-CTkAdCTv.css → index-BiNcBn_U.css} +52 -0
  99. package/dist/static/assets/{infoDiagram-HS3SLOUP-DJx03jNn.js → infoDiagram-HS3SLOUP-Bs7DwY4Q.js} +6 -6
  100. package/dist/static/assets/{infoDiagram-HS3SLOUP-DJx03jNn.js.map → infoDiagram-HS3SLOUP-Bs7DwY4Q.js.map} +1 -1
  101. package/dist/static/assets/{journeyDiagram-XKPGCS4Q-CKkr3KnL.js → journeyDiagram-XKPGCS4Q-7zHAqy6Q.js} +5 -5
  102. package/dist/static/assets/{journeyDiagram-XKPGCS4Q-CKkr3KnL.js.map → journeyDiagram-XKPGCS4Q-7zHAqy6Q.js.map} +1 -1
  103. package/dist/static/assets/{kanban-definition-3W4ZIXB7-CbSqCiEs.js → kanban-definition-3W4ZIXB7-DJaBY2Ug.js} +3 -3
  104. package/dist/static/assets/{kanban-definition-3W4ZIXB7-CbSqCiEs.js.map → kanban-definition-3W4ZIXB7-DJaBY2Ug.js.map} +1 -1
  105. package/dist/static/assets/{layout-D7-FKbaT.js → layout-DCgFs2G2.js} +5 -5
  106. package/dist/static/assets/{layout-D7-FKbaT.js.map → layout-DCgFs2G2.js.map} +1 -1
  107. package/dist/static/assets/{linear-BuDfNBon.js → linear-3qLxTIu4.js} +2 -2
  108. package/dist/static/assets/{linear-BuDfNBon.js.map → linear-3qLxTIu4.js.map} +1 -1
  109. package/dist/static/assets/{mindmap-definition-VGOIOE7T-BDwLe04b.js → mindmap-definition-VGOIOE7T-D8LVSYNe.js} +4 -4
  110. package/dist/static/assets/{mindmap-definition-VGOIOE7T-BDwLe04b.js.map → mindmap-definition-VGOIOE7T-D8LVSYNe.js.map} +1 -1
  111. package/dist/static/assets/{pieDiagram-ADFJNKIX-BoZQsSD6.js → pieDiagram-ADFJNKIX-K7J0sf-_.js} +8 -8
  112. package/dist/static/assets/{pieDiagram-ADFJNKIX-BoZQsSD6.js.map → pieDiagram-ADFJNKIX-K7J0sf-_.js.map} +1 -1
  113. package/dist/static/assets/{quadrantDiagram-AYHSOK5B-DCwmFmS8.js → quadrantDiagram-AYHSOK5B-BjOUsjH1.js} +3 -3
  114. package/dist/static/assets/{quadrantDiagram-AYHSOK5B-DCwmFmS8.js.map → quadrantDiagram-AYHSOK5B-BjOUsjH1.js.map} +1 -1
  115. package/dist/static/assets/{requirementDiagram-UZGBJVZJ-b103XjYN.js → requirementDiagram-UZGBJVZJ-B2Q3tMos.js} +4 -4
  116. package/dist/static/assets/{requirementDiagram-UZGBJVZJ-b103XjYN.js.map → requirementDiagram-UZGBJVZJ-B2Q3tMos.js.map} +1 -1
  117. package/dist/static/assets/{sankeyDiagram-TZEHDZUN-Dpa0Lvc2.js → sankeyDiagram-TZEHDZUN-BG5wvCeZ.js} +2 -2
  118. package/dist/static/assets/{sankeyDiagram-TZEHDZUN-Dpa0Lvc2.js.map → sankeyDiagram-TZEHDZUN-BG5wvCeZ.js.map} +1 -1
  119. package/dist/static/assets/{sequenceDiagram-WL72ISMW-DmmctZww.js → sequenceDiagram-WL72ISMW-BuLOLu3-.js} +4 -4
  120. package/dist/static/assets/{sequenceDiagram-WL72ISMW-DmmctZww.js.map → sequenceDiagram-WL72ISMW-BuLOLu3-.js.map} +1 -1
  121. package/dist/static/assets/{stateDiagram-FKZM4ZOC-rzlWUEGW.js → stateDiagram-FKZM4ZOC-CWCqsmNr.js} +9 -9
  122. package/dist/static/assets/{stateDiagram-FKZM4ZOC-rzlWUEGW.js.map → stateDiagram-FKZM4ZOC-CWCqsmNr.js.map} +1 -1
  123. package/dist/static/assets/{stateDiagram-v2-4FDKWEC3-kNazIMQu.js → stateDiagram-v2-4FDKWEC3-DYbP1xu4.js} +5 -5
  124. package/dist/static/assets/{stateDiagram-v2-4FDKWEC3-kNazIMQu.js.map → stateDiagram-v2-4FDKWEC3-DYbP1xu4.js.map} +1 -1
  125. package/dist/static/assets/{timeline-definition-IT6M3QCI-8Jf8mEk1.js → timeline-definition-IT6M3QCI-DaPtomWv.js} +3 -3
  126. package/dist/static/assets/{timeline-definition-IT6M3QCI-8Jf8mEk1.js.map → timeline-definition-IT6M3QCI-DaPtomWv.js.map} +1 -1
  127. package/dist/static/assets/{treemap-GDKQZRPO-pzngdrcL.js → treemap-GDKQZRPO-cEZjfkb6.js} +5 -5
  128. package/dist/static/assets/{treemap-GDKQZRPO-pzngdrcL.js.map → treemap-GDKQZRPO-cEZjfkb6.js.map} +1 -1
  129. package/dist/static/assets/{xychartDiagram-PRI3JC2R-BfBVgrdy.js → xychartDiagram-PRI3JC2R-7zI4Kz0F.js} +3 -3
  130. package/dist/static/assets/{xychartDiagram-PRI3JC2R-BfBVgrdy.js.map → xychartDiagram-PRI3JC2R-7zI4Kz0F.js.map} +1 -1
  131. package/dist/static/index.html +2 -2
  132. package/dist/team.js +52 -48
  133. package/dist/tellask.js +439 -0
  134. package/dist/tools/context-health.js +177 -0
  135. package/dist/tools/diag.js +583 -0
  136. package/dist/tools/fs.js +194 -68
  137. package/dist/tools/prompts/memory/en/principles.md +13 -5
  138. package/dist/tools/prompts/memory/en/tools.md +11 -36
  139. package/dist/tools/prompts/memory/zh/principles.md +18 -8
  140. package/dist/tools/prompts/memory/zh/tools.md +11 -36
  141. package/dist/tools/team-mgmt.js +3487 -0
  142. package/dist/utils/task-doc.js +236 -0
  143. package/package.json +1 -1
  144. package/dist/static/assets/index-C6rZcGnP.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,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) {
@@ -13,10 +13,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
13
13
  exports.main = main;
14
14
  const promises_1 = __importDefault(require("fs/promises"));
15
15
  const path_1 = __importDefault(require("path"));
16
- const installed_file_1 = require("../apps/installed-file");
16
+ const app_lock_file_1 = require("../apps/app-lock-file");
17
+ const assigned_port_1 = require("../apps/assigned-port");
18
+ const resolution_file_1 = require("../apps/resolution-file");
17
19
  const run_app_json_1 = require("../apps/run-app-json");
18
- const runtime_port_1 = require("../apps/runtime-port");
19
- const time_1 = require("../shared/utils/time");
20
20
  function printHelp() {
21
21
  console.log(`Usage:
22
22
  dominds install <spec|path> [--local] [--id <appId>] [--enable] [--force]
@@ -28,7 +28,7 @@ Options:
28
28
  --force Replace existing installed entry with the same id
29
29
 
30
30
  Notes:
31
- - State is stored in ${installed_file_1.INSTALLED_APPS_REL_PATH} under the current rtws (process.cwd()).
31
+ - State is stored in ${resolution_file_1.APPS_RESOLUTION_REL_PATH} under the current rtws (process.cwd()).
32
32
  - dominds installs apps by running '<app> --json' via npx or local package bin.
33
33
  `);
34
34
  }
@@ -103,9 +103,9 @@ async function main() {
103
103
  }
104
104
  const localAbs = path_1.default.resolve(rtwsRootAbs, specOrPath);
105
105
  const shouldUseLocal = args.local || (await pathIsDirectory(localAbs));
106
- const loadedInstalled = await (0, installed_file_1.loadInstalledAppsFile)({ rtwsRootAbs });
107
- if (loadedInstalled.kind === 'error') {
108
- console.error(`Error: failed to read ${installed_file_1.INSTALLED_APPS_REL_PATH}: ${loadedInstalled.errorText}`);
106
+ const loadedResolution = await (0, resolution_file_1.loadAppsResolutionFile)({ rtwsRootAbs });
107
+ if (loadedResolution.kind === 'error') {
108
+ console.error(`Error: failed to read ${resolution_file_1.APPS_RESOLUTION_REL_PATH}: ${loadedResolution.errorText}`);
109
109
  process.exit(1);
110
110
  return;
111
111
  }
@@ -117,33 +117,55 @@ async function main() {
117
117
  process.exit(1);
118
118
  return;
119
119
  }
120
- const prev = loadedInstalled.file.apps.find((a) => a.id === installJson.appId) ?? null;
120
+ const prev = loadedResolution.file.apps.find((a) => a.id === installJson.appId) ?? null;
121
121
  if (prev && !args.force) {
122
122
  console.error(`Error: app '${installJson.appId}' already installed. Use 'dominds update ${installJson.appId}' or 'dominds install ... --force'.`);
123
123
  process.exit(1);
124
124
  return;
125
125
  }
126
- const now = (0, time_1.formatUnifiedTimestamp)(new Date());
127
- const enabled = args.enable || (prev ? prev.enabled : false);
128
- const runtimePort = await (0, runtime_port_1.resolveStableAppRuntimePort)({
126
+ const userEnabled = args.enable || (prev ? prev.userEnabled : false);
127
+ const enabled = userEnabled;
128
+ const assignedPort = await (0, assigned_port_1.resolveStableAssignedPort)({
129
129
  appId: installJson.appId,
130
130
  installJson,
131
- existingApps: loadedInstalled.file.apps,
132
- existingRuntimePort: prev?.runtime.port ?? null,
131
+ existingApps: loadedResolution.file.apps,
132
+ existingAssignedPort: prev?.assignedPort ?? null,
133
133
  });
134
134
  const entry = {
135
135
  id: installJson.appId,
136
136
  enabled,
137
+ userEnabled,
137
138
  source: shouldUseLocal
138
139
  ? { kind: 'local', pathAbs: localAbs }
139
140
  : { kind: 'npx', spec: specOrPath },
140
- runtime: { port: runtimePort },
141
+ assignedPort,
141
142
  installJson,
142
- installedAt: prev ? prev.installedAt : now,
143
- updatedAt: now,
144
143
  };
145
- const nextFile = (0, installed_file_1.upsertInstalledApp)({ existing: loadedInstalled.file, next: entry });
146
- await (0, installed_file_1.writeInstalledAppsFile)({ rtwsRootAbs, file: nextFile });
144
+ const nextFile = (0, resolution_file_1.upsertResolvedApp)({ existing: loadedResolution.file, next: entry });
145
+ await (0, resolution_file_1.writeAppsResolutionFile)({ rtwsRootAbs, file: nextFile });
146
+ try {
147
+ const loadedLock = await (0, app_lock_file_1.loadAppLockFile)({ rtwsRootAbs });
148
+ if (loadedLock.kind === 'error') {
149
+ console.error(`Warning: failed to read .minds/app-lock.yaml: ${loadedLock.errorText}`);
150
+ }
151
+ else {
152
+ const nextLock = (0, app_lock_file_1.upsertLockedApp)({
153
+ existing: loadedLock.file,
154
+ next: {
155
+ id: entry.id,
156
+ source: entry.source,
157
+ package: {
158
+ name: entry.installJson.package.name,
159
+ version: entry.installJson.package.version,
160
+ },
161
+ },
162
+ });
163
+ await (0, app_lock_file_1.writeAppLockFileIfChanged)({ rtwsRootAbs, file: nextLock });
164
+ }
165
+ }
166
+ catch (err) {
167
+ console.error(`Warning: failed to update .minds/app-lock.yaml: ${err instanceof Error ? err.message : String(err)}`);
168
+ }
147
169
  console.log(shouldUseLocal
148
170
  ? `Installed app '${entry.id}' from local package: ${localAbs}`
149
171
  : `Installed app '${entry.id}' via npx spec: ${specOrPath}`);
@@ -13,7 +13,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
13
13
  exports.main = main;
14
14
  const promises_1 = __importDefault(require("fs/promises"));
15
15
  const path_1 = __importDefault(require("path"));
16
- const installed_file_1 = require("../apps/installed-file");
16
+ const resolution_file_1 = require("../apps/resolution-file");
17
17
  function printHelp() {
18
18
  console.log(`Usage:
19
19
  dominds uninstall <appId> [--purge]
@@ -54,20 +54,20 @@ async function main() {
54
54
  return;
55
55
  }
56
56
  const rtwsRootAbs = process.cwd();
57
- const loaded = await (0, installed_file_1.loadInstalledAppsFile)({ rtwsRootAbs });
57
+ const loaded = await (0, resolution_file_1.loadAppsResolutionFile)({ rtwsRootAbs });
58
58
  if (loaded.kind === 'error') {
59
- console.error(`Error: failed to read ${installed_file_1.INSTALLED_APPS_REL_PATH}: ${loaded.errorText}`);
59
+ console.error(`Error: failed to read ${resolution_file_1.APPS_RESOLUTION_REL_PATH}: ${loaded.errorText}`);
60
60
  process.exit(1);
61
61
  return;
62
62
  }
63
- const found = (0, installed_file_1.findInstalledApp)(loaded.file, args.appId);
63
+ const found = (0, resolution_file_1.findResolvedApp)(loaded.file, args.appId);
64
64
  if (!found) {
65
65
  console.error(`Error: app '${args.appId}' not installed`);
66
66
  process.exit(1);
67
67
  return;
68
68
  }
69
- const next = (0, installed_file_1.removeInstalledApp)({ existing: loaded.file, appId: args.appId });
70
- await (0, installed_file_1.writeInstalledAppsFile)({ rtwsRootAbs, file: next });
69
+ const next = (0, resolution_file_1.removeResolvedApp)({ existing: loaded.file, appId: args.appId });
70
+ await (0, resolution_file_1.writeAppsResolutionFile)({ rtwsRootAbs, file: next });
71
71
  if (args.purge) {
72
72
  const rtwsAppDirAbs = path_1.default.resolve(rtwsRootAbs, '.apps', args.appId);
73
73
  await promises_1.default.rm(rtwsAppDirAbs, { recursive: true, force: true });