@agimon-ai/doompi-config 0.0.1-alpha.7 → 0.0.1-alpha.71

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 (399) hide show
  1. package/README.md +123 -15
  2. package/dist/agentPluginMcp.cjs +1 -0
  3. package/dist/agentPluginMcp.d.cts +2 -0
  4. package/dist/agentPluginMcp.d.mts +2 -0
  5. package/dist/agentPluginMcp.mjs +1 -0
  6. package/dist/api-contracts.cjs +1 -0
  7. package/dist/api-contracts.d.cts +2 -0
  8. package/dist/api-contracts.d.mts +2 -0
  9. package/dist/api-contracts.mjs +1 -0
  10. package/dist/atomicJson.cjs +1 -2
  11. package/dist/atomicJson.d.cts +2 -6
  12. package/dist/atomicJson.d.mts +2 -6
  13. package/dist/atomicJson.mjs +1 -2
  14. package/dist/config.cjs +1 -2
  15. package/dist/config.d.cts +4 -24
  16. package/dist/config.d.mts +4 -24
  17. package/dist/config.mjs +1 -2
  18. package/dist/configSchema.d.cts +2 -0
  19. package/dist/configSchema.d.mts +2 -0
  20. package/dist/configWriter.cjs +1 -2
  21. package/dist/configWriter.d.cts +2 -52
  22. package/dist/configWriter.d.mts +2 -52
  23. package/dist/configWriter.mjs +1 -2
  24. package/dist/constants/config.cjs +2 -0
  25. package/dist/constants/config.cjs.map +1 -0
  26. package/dist/constants/config.mjs +2 -0
  27. package/dist/constants/config.mjs.map +1 -0
  28. package/dist/constants/settings.cjs +2 -0
  29. package/dist/constants/settings.cjs.map +1 -0
  30. package/dist/constants/settings.mjs +2 -0
  31. package/dist/constants/settings.mjs.map +1 -0
  32. package/dist/controllers/settingsApi.cjs +2 -0
  33. package/dist/controllers/settingsApi.cjs.map +1 -0
  34. package/dist/controllers/settingsApi.mjs +2 -0
  35. package/dist/controllers/settingsApi.mjs.map +1 -0
  36. package/dist/domains.cjs +1 -2
  37. package/dist/domains.d.cts +6 -77
  38. package/dist/domains.d.mts +6 -77
  39. package/dist/domains.mjs +1 -2
  40. package/dist/extensions/pi.cjs +1 -1
  41. package/dist/extensions/pi.cjs.map +1 -1
  42. package/dist/extensions/pi.d.cts +2 -5
  43. package/dist/extensions/pi.d.cts.map +1 -1
  44. package/dist/extensions/pi.d.mts +2 -5
  45. package/dist/extensions/pi.d.mts.map +1 -1
  46. package/dist/extensions/pi.mjs +1 -1
  47. package/dist/extensions/pi.mjs.map +1 -1
  48. package/dist/extensions/server.cjs +2 -0
  49. package/dist/extensions/server.cjs.map +1 -0
  50. package/dist/extensions/server.d.cts +5 -0
  51. package/dist/extensions/server.d.cts.map +1 -0
  52. package/dist/extensions/server.d.mts +5 -0
  53. package/dist/extensions/server.d.mts.map +1 -0
  54. package/dist/extensions/server.mjs +2 -0
  55. package/dist/extensions/server.mjs.map +1 -0
  56. package/dist/harnessState.cjs +1 -2
  57. package/dist/harnessState.d.cts +2 -50
  58. package/dist/harnessState.d.mts +2 -50
  59. package/dist/harnessState.mjs +1 -2
  60. package/dist/harnessStore.cjs +1 -2
  61. package/dist/harnessStore.d.cts +3 -102
  62. package/dist/harnessStore.d.mts +3 -102
  63. package/dist/harnessStore.mjs +1 -2
  64. package/dist/index.cjs +1 -1
  65. package/dist/index.d.cts +21 -16
  66. package/dist/index.d.mts +21 -16
  67. package/dist/index.mjs +1 -1
  68. package/dist/init.cjs +1 -76
  69. package/dist/init.d.cts +2 -33
  70. package/dist/init.d.mts +2 -33
  71. package/dist/init.mjs +1 -76
  72. package/dist/layeredConfig.cjs +1 -2
  73. package/dist/layeredConfig.d.cts +2 -49
  74. package/dist/layeredConfig.d.mts +2 -49
  75. package/dist/layeredConfig.mjs +1 -2
  76. package/dist/majorModes.cjs +1 -2
  77. package/dist/majorModes.d.cts +2 -75
  78. package/dist/majorModes.d.mts +2 -75
  79. package/dist/majorModes.mjs +1 -2
  80. package/dist/models/harnessCache.cjs +2 -0
  81. package/dist/models/harnessCache.cjs.map +1 -0
  82. package/dist/models/harnessCache.d.cts +10 -0
  83. package/dist/models/harnessCache.d.cts.map +1 -0
  84. package/dist/models/harnessCache.d.mts +10 -0
  85. package/dist/models/harnessCache.d.mts.map +1 -0
  86. package/dist/models/harnessCache.mjs +2 -0
  87. package/dist/models/harnessCache.mjs.map +1 -0
  88. package/dist/piConfig.cjs +1 -0
  89. package/dist/piConfig.d.cts +3 -0
  90. package/dist/piConfig.d.mts +3 -0
  91. package/dist/piConfig.mjs +1 -0
  92. package/dist/piContext.cjs +1 -2
  93. package/dist/piContext.d.cts +3 -19
  94. package/dist/piContext.d.mts +3 -19
  95. package/dist/piContext.mjs +1 -2
  96. package/dist/profiles.cjs +1 -4
  97. package/dist/profiles.d.cts +5 -35
  98. package/dist/profiles.d.mts +5 -35
  99. package/dist/profiles.mjs +1 -4
  100. package/dist/schemas/apiContracts.cjs +2 -0
  101. package/dist/schemas/apiContracts.cjs.map +1 -0
  102. package/dist/schemas/apiContracts.d.cts +53 -0
  103. package/dist/schemas/apiContracts.d.cts.map +1 -0
  104. package/dist/schemas/apiContracts.d.mts +53 -0
  105. package/dist/schemas/apiContracts.d.mts.map +1 -0
  106. package/dist/schemas/apiContracts.mjs +2 -0
  107. package/dist/schemas/apiContracts.mjs.map +1 -0
  108. package/dist/selectionSwitch.cjs +1 -0
  109. package/dist/selectionSwitch.d.cts +2 -0
  110. package/dist/selectionSwitch.d.mts +2 -0
  111. package/dist/selectionSwitch.mjs +1 -0
  112. package/dist/services/agentPluginMcp/index.cjs +2 -0
  113. package/dist/services/agentPluginMcp/index.cjs.map +1 -0
  114. package/dist/services/agentPluginMcp/index.d.cts +37 -0
  115. package/dist/services/agentPluginMcp/index.d.cts.map +1 -0
  116. package/dist/services/agentPluginMcp/index.d.mts +37 -0
  117. package/dist/services/agentPluginMcp/index.d.mts.map +1 -0
  118. package/dist/services/agentPluginMcp/index.mjs +2 -0
  119. package/dist/services/agentPluginMcp/index.mjs.map +1 -0
  120. package/dist/services/atomicJson/index.cjs +2 -0
  121. package/dist/services/atomicJson/index.cjs.map +1 -0
  122. package/dist/services/atomicJson/index.d.cts +5 -0
  123. package/dist/services/atomicJson/index.d.cts.map +1 -0
  124. package/dist/services/atomicJson/index.d.mts +5 -0
  125. package/dist/services/atomicJson/index.d.mts.map +1 -0
  126. package/dist/services/atomicJson/index.mjs +2 -0
  127. package/dist/services/atomicJson/index.mjs.map +1 -0
  128. package/dist/services/config/index.cjs +2 -0
  129. package/dist/services/config/index.cjs.map +1 -0
  130. package/dist/services/config/index.d.cts +34 -0
  131. package/dist/services/config/index.d.cts.map +1 -0
  132. package/dist/services/config/index.d.mts +34 -0
  133. package/dist/services/config/index.d.mts.map +1 -0
  134. package/dist/services/config/index.mjs +2 -0
  135. package/dist/services/config/index.mjs.map +1 -0
  136. package/dist/services/configPolicy/index.cjs +2 -0
  137. package/dist/services/configPolicy/index.cjs.map +1 -0
  138. package/dist/services/configPolicy/index.d.cts +81 -0
  139. package/dist/services/configPolicy/index.d.cts.map +1 -0
  140. package/dist/services/configPolicy/index.d.mts +81 -0
  141. package/dist/services/configPolicy/index.d.mts.map +1 -0
  142. package/dist/services/configPolicy/index.mjs +2 -0
  143. package/dist/services/configPolicy/index.mjs.map +1 -0
  144. package/dist/services/configResources/index.cjs +2 -0
  145. package/dist/services/configResources/index.cjs.map +1 -0
  146. package/dist/services/configResources/index.mjs +2 -0
  147. package/dist/services/configResources/index.mjs.map +1 -0
  148. package/dist/services/configRuntime/index.cjs +2 -0
  149. package/dist/services/configRuntime/index.cjs.map +1 -0
  150. package/dist/services/configRuntime/index.mjs +2 -0
  151. package/dist/services/configRuntime/index.mjs.map +1 -0
  152. package/dist/services/configWriter/index.cjs +2 -0
  153. package/dist/services/configWriter/index.cjs.map +1 -0
  154. package/dist/services/configWriter/index.d.cts +65 -0
  155. package/dist/services/configWriter/index.d.cts.map +1 -0
  156. package/dist/services/configWriter/index.d.mts +65 -0
  157. package/dist/services/configWriter/index.d.mts.map +1 -0
  158. package/dist/services/configWriter/index.mjs +2 -0
  159. package/dist/services/configWriter/index.mjs.map +1 -0
  160. package/dist/services/domains/completion.cjs +2 -0
  161. package/dist/services/domains/completion.cjs.map +1 -0
  162. package/dist/services/domains/completion.d.cts +11 -0
  163. package/dist/services/domains/completion.d.cts.map +1 -0
  164. package/dist/services/domains/completion.d.mts +11 -0
  165. package/dist/services/domains/completion.d.mts.map +1 -0
  166. package/dist/services/domains/completion.mjs +2 -0
  167. package/dist/services/domains/completion.mjs.map +1 -0
  168. package/dist/services/domains/index.cjs +2 -0
  169. package/dist/services/domains/index.cjs.map +1 -0
  170. package/dist/services/domains/index.d.cts +35 -0
  171. package/dist/services/domains/index.d.cts.map +1 -0
  172. package/dist/services/domains/index.d.mts +35 -0
  173. package/dist/services/domains/index.d.mts.map +1 -0
  174. package/dist/services/domains/index.mjs +2 -0
  175. package/dist/services/domains/index.mjs.map +1 -0
  176. package/dist/services/doomConfigService/index.cjs +2 -0
  177. package/dist/services/doomConfigService/index.cjs.map +1 -0
  178. package/dist/services/doomConfigService/index.mjs +2 -0
  179. package/dist/services/doomConfigService/index.mjs.map +1 -0
  180. package/dist/services/harnessState/index.cjs +2 -0
  181. package/dist/services/harnessState/index.cjs.map +1 -0
  182. package/dist/services/harnessState/index.d.cts +49 -0
  183. package/dist/services/harnessState/index.d.cts.map +1 -0
  184. package/dist/services/harnessState/index.d.mts +49 -0
  185. package/dist/services/harnessState/index.d.mts.map +1 -0
  186. package/dist/services/harnessState/index.mjs +2 -0
  187. package/dist/services/harnessState/index.mjs.map +1 -0
  188. package/dist/services/harnessStore/index.cjs +2 -0
  189. package/dist/services/harnessStore/index.cjs.map +1 -0
  190. package/dist/services/harnessStore/index.d.cts +106 -0
  191. package/dist/services/harnessStore/index.d.cts.map +1 -0
  192. package/dist/services/harnessStore/index.d.mts +106 -0
  193. package/dist/services/harnessStore/index.d.mts.map +1 -0
  194. package/dist/services/harnessStore/index.mjs +2 -0
  195. package/dist/services/harnessStore/index.mjs.map +1 -0
  196. package/dist/services/imageSettings/index.cjs +2 -0
  197. package/dist/services/imageSettings/index.cjs.map +1 -0
  198. package/dist/services/imageSettings/index.d.cts +22 -0
  199. package/dist/services/imageSettings/index.d.cts.map +1 -0
  200. package/dist/services/imageSettings/index.d.mts +22 -0
  201. package/dist/services/imageSettings/index.d.mts.map +1 -0
  202. package/dist/services/imageSettings/index.mjs +2 -0
  203. package/dist/services/imageSettings/index.mjs.map +1 -0
  204. package/dist/services/init/index.cjs +232 -0
  205. package/dist/services/init/index.cjs.map +1 -0
  206. package/dist/services/init/index.d.cts +38 -0
  207. package/dist/services/init/index.d.cts.map +1 -0
  208. package/dist/services/init/index.d.mts +38 -0
  209. package/dist/services/init/index.d.mts.map +1 -0
  210. package/dist/services/init/index.mjs +232 -0
  211. package/dist/services/init/index.mjs.map +1 -0
  212. package/dist/services/layeredConfig/index.cjs +2 -0
  213. package/dist/services/layeredConfig/index.cjs.map +1 -0
  214. package/dist/services/layeredConfig/index.d.cts +53 -0
  215. package/dist/services/layeredConfig/index.d.cts.map +1 -0
  216. package/dist/services/layeredConfig/index.d.mts +53 -0
  217. package/dist/services/layeredConfig/index.d.mts.map +1 -0
  218. package/dist/services/layeredConfig/index.mjs +2 -0
  219. package/dist/services/layeredConfig/index.mjs.map +1 -0
  220. package/dist/services/majorModes/index.cjs +2 -0
  221. package/dist/services/majorModes/index.cjs.map +1 -0
  222. package/dist/services/majorModes/index.d.cts +117 -0
  223. package/dist/services/majorModes/index.d.cts.map +1 -0
  224. package/dist/services/majorModes/index.d.mts +117 -0
  225. package/dist/services/majorModes/index.d.mts.map +1 -0
  226. package/dist/services/majorModes/index.mjs +2 -0
  227. package/dist/services/majorModes/index.mjs.map +1 -0
  228. package/dist/services/personaFrontMatter/index.cjs +5 -0
  229. package/dist/services/personaFrontMatter/index.cjs.map +1 -0
  230. package/dist/services/personaFrontMatter/index.d.cts +11 -0
  231. package/dist/services/personaFrontMatter/index.d.cts.map +1 -0
  232. package/dist/services/personaFrontMatter/index.d.mts +11 -0
  233. package/dist/services/personaFrontMatter/index.d.mts.map +1 -0
  234. package/dist/services/personaFrontMatter/index.mjs +5 -0
  235. package/dist/services/personaFrontMatter/index.mjs.map +1 -0
  236. package/dist/services/personaIcon/index.cjs +2 -0
  237. package/dist/services/personaIcon/index.cjs.map +1 -0
  238. package/dist/services/personaIcon/index.d.cts +9 -0
  239. package/dist/services/personaIcon/index.d.cts.map +1 -0
  240. package/dist/services/personaIcon/index.d.mts +9 -0
  241. package/dist/services/personaIcon/index.d.mts.map +1 -0
  242. package/dist/services/personaIcon/index.mjs +2 -0
  243. package/dist/services/personaIcon/index.mjs.map +1 -0
  244. package/dist/services/piConfig/index.cjs +2 -0
  245. package/dist/services/piConfig/index.cjs.map +1 -0
  246. package/dist/services/piConfig/index.d.cts +20 -0
  247. package/dist/services/piConfig/index.d.cts.map +1 -0
  248. package/dist/services/piConfig/index.d.mts +20 -0
  249. package/dist/services/piConfig/index.d.mts.map +1 -0
  250. package/dist/services/piConfig/index.mjs +2 -0
  251. package/dist/services/piConfig/index.mjs.map +1 -0
  252. package/dist/services/pluginCatalog/index.cjs +2 -0
  253. package/dist/services/pluginCatalog/index.cjs.map +1 -0
  254. package/dist/services/pluginCatalog/index.d.cts +11 -0
  255. package/dist/services/pluginCatalog/index.d.cts.map +1 -0
  256. package/dist/services/pluginCatalog/index.d.mts +11 -0
  257. package/dist/services/pluginCatalog/index.d.mts.map +1 -0
  258. package/dist/services/pluginCatalog/index.mjs +2 -0
  259. package/dist/services/pluginCatalog/index.mjs.map +1 -0
  260. package/dist/services/profiles/index.cjs +4 -0
  261. package/dist/services/profiles/index.cjs.map +1 -0
  262. package/dist/services/profiles/index.d.cts +55 -0
  263. package/dist/services/profiles/index.d.cts.map +1 -0
  264. package/dist/services/profiles/index.d.mts +55 -0
  265. package/dist/services/profiles/index.d.mts.map +1 -0
  266. package/dist/services/profiles/index.mjs +4 -0
  267. package/dist/services/profiles/index.mjs.map +1 -0
  268. package/dist/services/selectionSwitch/index.cjs +2 -0
  269. package/dist/services/selectionSwitch/index.cjs.map +1 -0
  270. package/dist/services/selectionSwitch/index.d.cts +30 -0
  271. package/dist/services/selectionSwitch/index.d.cts.map +1 -0
  272. package/dist/services/selectionSwitch/index.d.mts +30 -0
  273. package/dist/services/selectionSwitch/index.d.mts.map +1 -0
  274. package/dist/services/selectionSwitch/index.mjs +2 -0
  275. package/dist/services/selectionSwitch/index.mjs.map +1 -0
  276. package/dist/services/sessionConfig/index.cjs +2 -0
  277. package/dist/services/sessionConfig/index.cjs.map +1 -0
  278. package/dist/services/sessionConfig/index.d.cts +33 -0
  279. package/dist/services/sessionConfig/index.d.cts.map +1 -0
  280. package/dist/services/sessionConfig/index.d.mts +33 -0
  281. package/dist/services/sessionConfig/index.d.mts.map +1 -0
  282. package/dist/services/sessionConfig/index.mjs +2 -0
  283. package/dist/services/sessionConfig/index.mjs.map +1 -0
  284. package/dist/services/settings/index.cjs +2 -0
  285. package/dist/services/settings/index.cjs.map +1 -0
  286. package/dist/services/settings/index.mjs +2 -0
  287. package/dist/services/settings/index.mjs.map +1 -0
  288. package/dist/types/config.cjs +1 -0
  289. package/dist/types/config.d.cts +308 -0
  290. package/dist/types/config.d.cts.map +1 -0
  291. package/dist/types/config.d.mts +308 -0
  292. package/dist/types/config.d.mts.map +1 -0
  293. package/dist/types/config.mjs +1 -0
  294. package/dist/types/domains.d.cts +92 -0
  295. package/dist/types/domains.d.cts.map +1 -0
  296. package/dist/types/domains.d.mts +92 -0
  297. package/dist/types/domains.d.mts.map +1 -0
  298. package/dist/{config/schema.d.cts → types/piConfig.d.cts} +7 -8
  299. package/dist/types/piConfig.d.cts.map +1 -0
  300. package/dist/{config/schema.d.mts → types/piConfig.d.mts} +7 -8
  301. package/dist/types/piConfig.d.mts.map +1 -0
  302. package/dist/types/profiles.d.cts +26 -0
  303. package/dist/types/profiles.d.cts.map +1 -0
  304. package/dist/types/profiles.d.mts +26 -0
  305. package/dist/types/profiles.d.mts.map +1 -0
  306. package/dist/types.cjs +1 -2
  307. package/dist/types.d.cts +2 -132
  308. package/dist/types.d.mts +2 -132
  309. package/dist/types.mjs +1 -2
  310. package/llms.txt +12 -0
  311. package/package.json +81 -39
  312. package/src/prompts/doompi-author-config/SKILL.md +26 -0
  313. package/src/prompts/doompi-author-config/agents/openai.yaml +4 -0
  314. package/src/prompts/doompi-author-config/references/config-contract.md +200 -0
  315. package/dist/_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorate.cjs +0 -1
  316. package/dist/_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorate.mjs +0 -1
  317. package/dist/atomicJson.cjs.map +0 -1
  318. package/dist/atomicJson.d.cts.map +0 -1
  319. package/dist/atomicJson.d.mts.map +0 -1
  320. package/dist/atomicJson.mjs.map +0 -1
  321. package/dist/config/piConfig.cjs +0 -2
  322. package/dist/config/piConfig.cjs.map +0 -1
  323. package/dist/config/piConfig.d.cts +0 -7
  324. package/dist/config/piConfig.d.cts.map +0 -1
  325. package/dist/config/piConfig.d.mts +0 -7
  326. package/dist/config/piConfig.d.mts.map +0 -1
  327. package/dist/config/piConfig.mjs +0 -2
  328. package/dist/config/piConfig.mjs.map +0 -1
  329. package/dist/config/schema.d.cts.map +0 -1
  330. package/dist/config/schema.d.mts.map +0 -1
  331. package/dist/config.cjs.map +0 -1
  332. package/dist/config.d.cts.map +0 -1
  333. package/dist/config.d.mts.map +0 -1
  334. package/dist/config.mjs.map +0 -1
  335. package/dist/configWriter.cjs.map +0 -1
  336. package/dist/configWriter.d.cts.map +0 -1
  337. package/dist/configWriter.d.mts.map +0 -1
  338. package/dist/configWriter.mjs.map +0 -1
  339. package/dist/container.cjs +0 -2
  340. package/dist/container.cjs.map +0 -1
  341. package/dist/container.d.cts +0 -12
  342. package/dist/container.d.cts.map +0 -1
  343. package/dist/container.d.mts +0 -12
  344. package/dist/container.d.mts.map +0 -1
  345. package/dist/container.mjs +0 -2
  346. package/dist/container.mjs.map +0 -1
  347. package/dist/domains.cjs.map +0 -1
  348. package/dist/domains.d.cts.map +0 -1
  349. package/dist/domains.d.mts.map +0 -1
  350. package/dist/domains.mjs.map +0 -1
  351. package/dist/extensions/doom.cjs +0 -2
  352. package/dist/extensions/doom.cjs.map +0 -1
  353. package/dist/extensions/doom.d.cts +0 -8
  354. package/dist/extensions/doom.d.cts.map +0 -1
  355. package/dist/extensions/doom.d.mts +0 -8
  356. package/dist/extensions/doom.d.mts.map +0 -1
  357. package/dist/extensions/doom.mjs +0 -2
  358. package/dist/extensions/doom.mjs.map +0 -1
  359. package/dist/harnessState.cjs.map +0 -1
  360. package/dist/harnessState.d.cts.map +0 -1
  361. package/dist/harnessState.d.mts.map +0 -1
  362. package/dist/harnessState.mjs.map +0 -1
  363. package/dist/harnessStore.cjs.map +0 -1
  364. package/dist/harnessStore.d.cts.map +0 -1
  365. package/dist/harnessStore.d.mts.map +0 -1
  366. package/dist/harnessStore.mjs.map +0 -1
  367. package/dist/init.cjs.map +0 -1
  368. package/dist/init.d.cts.map +0 -1
  369. package/dist/init.d.mts.map +0 -1
  370. package/dist/init.mjs.map +0 -1
  371. package/dist/layeredConfig.cjs.map +0 -1
  372. package/dist/layeredConfig.d.cts.map +0 -1
  373. package/dist/layeredConfig.d.mts.map +0 -1
  374. package/dist/layeredConfig.mjs.map +0 -1
  375. package/dist/majorModes.cjs.map +0 -1
  376. package/dist/majorModes.d.cts.map +0 -1
  377. package/dist/majorModes.d.mts.map +0 -1
  378. package/dist/majorModes.mjs.map +0 -1
  379. package/dist/pi.cjs +0 -1
  380. package/dist/pi.d.cts +0 -2
  381. package/dist/pi.d.mts +0 -2
  382. package/dist/pi.mjs +0 -1
  383. package/dist/piContext.cjs.map +0 -1
  384. package/dist/piContext.d.cts.map +0 -1
  385. package/dist/piContext.d.mts.map +0 -1
  386. package/dist/piContext.mjs.map +0 -1
  387. package/dist/profiles.cjs.map +0 -1
  388. package/dist/profiles.d.cts.map +0 -1
  389. package/dist/profiles.d.mts.map +0 -1
  390. package/dist/profiles.mjs.map +0 -1
  391. package/dist/types.cjs.map +0 -1
  392. package/dist/types.d.cts.map +0 -1
  393. package/dist/types.d.mts.map +0 -1
  394. package/dist/types.mjs.map +0 -1
  395. package/skills/doom-pi-config/SKILL.md +0 -26
  396. package/skills/doom-pi-config/agents/openai.yaml +0 -4
  397. package/skills/doom-pi-config/references/config-contract.md +0 -43
  398. /package/dist/{config/schema.cjs → configSchema.cjs} +0 -0
  399. /package/dist/{config/schema.mjs → configSchema.mjs} +0 -0
package/README.md CHANGED
@@ -1,13 +1,18 @@
1
1
  # @agimon-ai/doompi-config
2
2
 
3
- Shared Doom configuration loading and dependency injection.
3
+ Typed runtime configuration and immutable session context for
4
+ [DoomPi](https://www.npmjs.com/package/@agimon-ai/doompi).
4
5
 
5
- Loads and validates `.doom/`: major modes and their layers, domains, profiles, and the hook
6
- registry. Owns the resolved harness state file that every other reader derives from.
6
+ This package is fixed core in the DoomPi distribution. It loads `config.yaml`, validates supported
7
+ runtime settings, publishes the `doom/config` Cordis service, and maintains selection state shared
8
+ by the major-mode, domain, and profile transition flows.
7
9
 
8
- Part of [Doompi](https://www.npmjs.com/package/@agimon-ai/doompi), a coding agent that loads
9
- only the skills and tools you name. This package is composed by Doompi and is not usually
10
- installed on its own.
10
+ > **Alpha:** configuration contracts may change between releases.
11
+
12
+ ## Requirements
13
+
14
+ - Node.js 22.19.0 or newer
15
+ - Pi 0.85.0 as a peer dependency
11
16
 
12
17
  ## Install
13
18
 
@@ -15,21 +20,124 @@ installed on its own.
15
20
  npm install @agimon-ai/doompi-config
16
21
  ```
17
22
 
18
- ## How it loads
23
+ Do not add this package to a DoomPi layer. The distribution activates it before selectable packages
24
+ so the rest of the parent session can consume one resolved configuration snapshot.
25
+
26
+ ## Runtime configuration
27
+
28
+ DoomPi reads `~/.pi/.doom/config.yaml` first and `<repoRoot>/.doom/config.yaml` second. Merge policy
29
+ is field-specific because some settings are personal and others are repository policy:
30
+
31
+ | Setting | Effective source policy |
32
+ | ------------------- | -------------------------------------------------------------------- |
33
+ | `projectTrust` | Repository value, defaulting to `ask` |
34
+ | `editor` | Personal config only |
35
+ | `modes.planning` | Personal and repository fields merge, with repository values winning |
36
+ | `voice` | Personal and repository fields merge, with repository values winning |
37
+ | `voice.autoCapture` | Personal config only |
38
+ | `selection` | Per-axis merge, with repository values winning |
39
+
40
+ Supported root keys are `modes`, `projectTrust`, `editor`, `voice`, and `selection`. Unknown keys and
41
+ invalid values fail during loading.
42
+
43
+ ```yaml
44
+ projectTrust: ask
45
+ modes:
46
+ planning:
47
+ main:
48
+ model: openai/gpt-5.4
49
+ thinking: high
50
+ plansDirectory: .doom/plans
51
+ voice:
52
+ engine: auto
53
+ language: en
54
+ selection:
55
+ majorMode: copilot
56
+ domains: [default]
57
+ profile: reviewer
58
+ ```
59
+
60
+ The `selection` mapping names defaults. Definitions for those axes live in `modes.yaml`,
61
+ `domains.yaml`, and `profiles.yaml` and are documented by their owning package Help skills.
62
+
63
+ See the shipped [configuration contract](./src/prompts/doompi-author-config/references/config-contract.md) for
64
+ the complete runtime schema and additional configuration details.
65
+
66
+ ## Typed session context
67
+
68
+ `@agimon-ai/doompi-config/extensions/pi` joins the runner-scoped Cordis host and provides
69
+ `DOOM_CONFIG_SERVICE`. Consumers must access it under an owning service injection:
70
+
71
+ ```ts
72
+ import { DOOM_CONFIG_SERVICE, type DoomConfigContext, requireDoomConfigContext } from '@agimon-ai/doompi-config';
73
+ import type { Context } from '@deepseek-ai/cordis';
74
+
75
+ export function consumeDoomConfig(context: Context, consume: (snapshot: DoomConfigContext) => void): void {
76
+ context.inject([DOOM_CONFIG_SERVICE], (configContext) => {
77
+ consume(requireDoomConfigContext(configContext));
78
+ });
79
+ }
80
+ ```
81
+
82
+ The snapshot is deeply frozen. It contains validated `settings`, active `harness` state, an optional
83
+ `pendingSelection`, and `requiresRelaunch`. Do not mutate it or retain it across provider or session
84
+ replacement. The next session publishes a new snapshot.
19
85
 
20
- Doompi loads this unconditionally. It is core, not a layer, so it does not appear in
21
- `.doom/modes.yaml`: making it optional would only create broken configurations.
86
+ ## Plugin structure and lifecycle
22
87
 
23
- Extension entry: `@agimon-ai/doompi-config/pi`
88
+ Pi and server entries live directly in `src/extensions`. HTTP request handling lives in `src/controllers`, package behavior in `src/services/{serviceName}`, and cached harness state in `src/models`. Public consumption modules remain flat under `src/exports`.
24
89
 
25
- ## Notes
90
+ The Pi entry uses `definePiExtension` with a Config service contribution and a typed `session_start` event. The shared helper owns mounting and disposal. Config publishes its readiness coordinator synchronously, loads configuration asynchronously, and waits at the session-start barrier before later features run. Session replacement cancels the prior generation and removes its Config and MCP projection services. Help contributions follow their optional provider without restarting Config.
26
91
 
27
- This is the package that defines the config contract. Changing the shape of `.doom/*.yaml`
28
- starts here.
92
+ This session readiness barrier is separate from plugin `onStart`. Awaiting configuration during plugin mounting would block publication of the services that startup consumers need.
29
93
 
30
- ## Entry points
94
+ ## Selection transitions
95
+
96
+ Major-mode, domain, and profile packages resolve their own requested changes, then use the shared
97
+ transition coordinator. Config owns the persisted selection and transition journal records used to
98
+ distinguish active state from pending intent.
99
+
100
+ Transitions are serialized and compared with the active composition fingerprint. A compatible
101
+ change can use Pi reload. A launcher-owned composition change records pending intent for process
102
+ relaunch. A fresh session acknowledges a pending transition only when its exact target selection and
103
+ composition are active.
104
+
105
+ Consumers must not edit `snapshot.harness`, bypass the coordinator, or cache launcher environment
106
+ state at module scope.
107
+
108
+ ## Public API
109
+
110
+ The root and focused `/config` and `/piContext` exports provide runtime parsing, merge policy, and
111
+ session integration:
112
+
113
+ ```ts
114
+ import { loadDoomConfig } from '@agimon-ai/doompi-config';
115
+
116
+ const settings = loadDoomConfig(process.cwd());
117
+ ```
118
+
119
+ Pi-specific JSON settings are exposed through `/pi-config`; their types are exposed through `/config-schema`. The removed `/config/piConfig` and `/config/schema` paths have no aliases.
120
+
121
+ The package also exposes lower-level loaders used by the fixed axis packages. User-facing guidance
122
+ for defining modes, domains, and profiles is intentionally owned by those packages instead of this
123
+ runtime Config authoring skill.
124
+
125
+ ## Help
126
+
127
+ The package publishes `src/prompts/doompi-author-config`, links it from `llms.txt`, and registers
128
+ `doompi-author-config` with the `doom/help` Cordis service. The guidance is visible to the AI only
129
+ while the parent Help minor mode is active.
130
+
131
+ ## Development
132
+
133
+ ```bash
134
+ pnpm build
135
+ pnpm typecheck
136
+ pnpm test
137
+ pnpm lint
138
+ ```
31
139
 
32
- 18 subpaths are declared in the `exports` field of `package.json`.
140
+ Maintained by [Agimon](https://agimon.ai/about).
33
141
 
34
142
  ## License
35
143
 
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./services/agentPluginMcp/index.cjs");exports.normalizeAgentPluginMcpSource=e.normalizeAgentPluginMcpSource;
@@ -0,0 +1,2 @@
1
+ import { AgentPluginMcpConfigSource, NormalizeAgentPluginMcpOptions, NormalizedAgentPluginMcpSource, normalizeAgentPluginMcpSource } from "./services/agentPluginMcp/index.cjs";
2
+ export { type AgentPluginMcpConfigSource, type NormalizeAgentPluginMcpOptions, type NormalizedAgentPluginMcpSource, normalizeAgentPluginMcpSource };
@@ -0,0 +1,2 @@
1
+ import { AgentPluginMcpConfigSource, NormalizeAgentPluginMcpOptions, NormalizedAgentPluginMcpSource, normalizeAgentPluginMcpSource } from "./services/agentPluginMcp/index.mjs";
2
+ export { type AgentPluginMcpConfigSource, type NormalizeAgentPluginMcpOptions, type NormalizedAgentPluginMcpSource, normalizeAgentPluginMcpSource };
@@ -0,0 +1 @@
1
+ import{normalizeAgentPluginMcpSource as e}from"./services/agentPluginMcp/index.mjs";export{e as normalizeAgentPluginMcpSource};
@@ -0,0 +1 @@
1
+ Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("./schemas/apiContracts.cjs");exports.apiContracts=e.apiContracts,exports.default=e.apiContracts;
@@ -0,0 +1,2 @@
1
+ import { apiContracts } from "./schemas/apiContracts.cjs";
2
+ export { apiContracts, apiContracts as default };
@@ -0,0 +1,2 @@
1
+ import { apiContracts } from "./schemas/apiContracts.mjs";
2
+ export { apiContracts, apiContracts as default };
@@ -0,0 +1 @@
1
+ import{apiContracts as e}from"./schemas/apiContracts.mjs";export{e as apiContracts,e as default};
@@ -1,2 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./_virtual/_rolldown/runtime.cjs");let t=require("node:fs");t=e.__toESM(t,1);let n=require("node:path");n=e.__toESM(n,1);let r=require("node:crypto");function i(e,i){t.default.mkdirSync(n.default.dirname(e),{mode:448,recursive:!0});let a=`${e}.${process.pid}.${(0,r.randomUUID)()}.tmp`;try{t.default.writeFileSync(a,`${JSON.stringify(i,null,2)}\n`,{mode:384}),t.default.renameSync(a,e)}catch(e){throw t.default.rmSync(a,{force:!0}),e}}exports.writePrivateAtomicJson=i;
2
- //# sourceMappingURL=atomicJson.cjs.map
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./services/atomicJson/index.cjs");exports.writePrivateAtomicJson=e.writePrivateAtomicJson;
@@ -1,6 +1,2 @@
1
- //#region src/atomicJson.d.ts
2
- /** Writes JSON readable by its owner only, replacing the target atomically. */
3
- declare function writePrivateAtomicJson(filePath: string, value: unknown): void;
4
- //#endregion
5
- export { writePrivateAtomicJson };
6
- //# sourceMappingURL=atomicJson.d.cts.map
1
+ import { writePrivateAtomicJson } from "./services/atomicJson/index.cjs";
2
+ export { writePrivateAtomicJson };
@@ -1,6 +1,2 @@
1
- //#region src/atomicJson.d.ts
2
- /** Writes JSON readable by its owner only, replacing the target atomically. */
3
- declare function writePrivateAtomicJson(filePath: string, value: unknown): void;
4
- //#endregion
5
- export { writePrivateAtomicJson };
6
- //# sourceMappingURL=atomicJson.d.mts.map
1
+ import { writePrivateAtomicJson } from "./services/atomicJson/index.mjs";
2
+ export { writePrivateAtomicJson };
@@ -1,2 +1 @@
1
- import e from"node:fs";import t from"node:path";import{randomUUID as n}from"node:crypto";function r(r,i){e.mkdirSync(t.dirname(r),{mode:448,recursive:!0});let a=`${r}.${process.pid}.${n()}.tmp`;try{e.writeFileSync(a,`${JSON.stringify(i,null,2)}\n`,{mode:384}),e.renameSync(a,r)}catch(t){throw e.rmSync(a,{force:!0}),t}}export{r as writePrivateAtomicJson};
2
- //# sourceMappingURL=atomicJson.mjs.map
1
+ import{writePrivateAtomicJson as e}from"./services/atomicJson/index.mjs";export{e as writePrivateAtomicJson};
package/dist/config.cjs CHANGED
@@ -1,2 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./_virtual/_rolldown/runtime.cjs");let t=require("node:fs");t=e.__toESM(t,1);let n=require("node:os");n=e.__toESM(n,1);let r=require("node:path");r=e.__toESM(r,1);let i=require("yaml");const a=`.doom`,o=`config.yaml`,s=`auto`,c=[`modes`,`projectTrust`,`editor`,`voice`,`selection`],l=[`majorMode`,`domains`,`profile`],ee=[`planning`],u=[`main`,`subagents`,`plansDirectory`],d=[`model`,`thinking`],f=[`command`],p=[`engine`,`language`,`recorder`,`adapters`,`autoCapture`],te=[`binary`,`device`],m=`whisper-cpp`,h=`openai-whisper`,g=`mlx-whisper`,_=[m,h,g],v=[`binary`,`model`],ne=[`path`,`id`],re=[`model`,`startPhrases`,`stopPhrases`,`tts`],y=[`engine`,`voice`,`rate`],b=/^[^/\s]+\/[^/\s]+(?:\/[^/\s]+)*$/u,x=/[\p{P}\p{S}]+/gu,S=[`off`,`minimal`,`low`,`medium`,`high`,`xhigh`,`max`],C=[s,m,h,g],w=[`macos-say`],T=new Set(S),E=new Set([`ask`,`always`,`never`]),D=new Set(C),O=new Set(w);function k(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function A(e,t,n,r){let i=Object.keys(e).filter(e=>!t.includes(e));if(i.length>0)throw Error(`Doom config at ${r} has unsupported ${n} field(s): ${i.join(`, `)}`)}function j(e,t,n){if(e!==void 0){if(typeof e!=`string`||e.trim().length===0)throw Error(`Doom config at ${n} requires ${t} to be a non-empty string`);return e.trim()}}function M(e){for(let t of e){let e=t.codePointAt(0);if(e!==void 0&&(e<=31||e===127))return!0}return!1}function N(e,t,n,r){let i=j(e,t,n);if(i){if(i.length>r)throw Error(`Doom config at ${n} requires ${t} to be at most ${r} characters`);if(M(i))throw Error(`Doom config at ${n} does not allow control characters in ${t}`);return i}}function P(e,t){let n=`voice.autoCapture.model`,r=j(e,n,t);if(!r||!b.test(r))throw Error(`Doom config at ${t} requires ${n} in provider/model-id form`);return r}function F(e){return e.normalize(`NFKC`).toLocaleLowerCase(`en-US`).replace(x,` `).replace(/\s+/gu,` `).trim()}function I(e,t,n){if(e===void 0)return;if(!Array.isArray(e)||e.some(e=>typeof e!=`string`))throw Error(`Doom config at ${n} requires ${t} to be an array of strings`);if(e.length>16)throw Error(`Doom config at ${n} requires ${t} to contain at most 16 phrases`);let r=e.map(e=>e.trim()),i=new Set;for(let e of r){if(e.length===0)throw Error(`Doom config at ${n} requires ${t} to contain non-empty strings`);if(e.length>64)throw Error(`Doom config at ${n} requires ${t} phrases to be at most 64 characters`);if(M(e))throw Error(`Doom config at ${n} does not allow control characters in ${t}`);let r=F(e);if(!r)throw Error(`Doom config at ${n} requires ${t} to contain words`);if(i.has(r))throw Error(`Doom config at ${n} does not allow normalized duplicates in ${t}`);i.add(r)}return r}function L(e,t){let n=`voice.autoCapture.tts`;if(!k(e))throw Error(`Doom config at ${t} requires ${n} to be an object`);if(A(e,y,n,t),typeof e.engine!=`string`||!O.has(e.engine))throw Error(`Doom config at ${t} requires ${n}.engine to be one of: ${[...O].join(`, `)}`);let r=N(e.voice,`${n}.voice`,t,64),i=e.rate;if(i!==void 0&&(typeof i!=`number`||!Number.isInteger(i)||i<80||i>500))throw Error(`Doom config at ${t} requires ${n}.rate to be an integer from 80 to 500`);return{engine:e.engine,...r?{voice:r}:{},...i===void 0?{}:{rate:i}}}function R(e,t){if(e===void 0)return;let n=`voice.autoCapture`;if(!k(e))throw Error(`Doom config at ${t} requires ${n} to be an object`);A(e,re,n,t);let r=I(e.startPhrases,`${n}.startPhrases`,t),i=I(e.stopPhrases,`${n}.stopPhrases`,t),a=new Set((r??[]).map(F));if((i??[]).some(e=>a.has(F(e))))throw Error(`Doom config at ${t} does not allow a phrase in both startPhrases and stopPhrases`);return{model:P(e.model,t),...r?{startPhrases:r}:{},...i?{stopPhrases:i}:{},tts:L(e.tts,t)}}function z(e,t,n){if(e===void 0)return;if(!k(e))throw Error(`Doom config at ${n} requires ${t} to be an object`);A(e,d,t,n);let r=e.thinking;if(r!==void 0&&(typeof r!=`string`||!T.has(r)))throw Error(`Doom config at ${n} requires ${t}.thinking to be one of: ${[...T].join(`, `)}`);let i=j(e.model,`${t}.model`,n);return{...i?{model:i}:{},...r?{thinking:r}:{}}}function B(e,t,n=`modes.planning`){if(!k(e))throw Error(`Doom config at ${t} requires ${n} to be an object`);return A(e,u,n,t),{main:z(e.main,`${n}.main`,t),subagents:z(e.subagents,`${n}.subagents`,t),plansDirectory:j(e.plansDirectory,`${n}.plansDirectory`,t)}}function V(e,t,n,r){if(!k(e))throw Error(`Doom config at ${n} requires ${t} to be an object`);A(e,ne,t,n);let i=j(e.path,`${t}.path`,n),a=j(e.id,`${t}.id`,n);if(!!i==!!a)throw Error(`Doom config at ${n} requires exactly one of ${t}.path or ${t}.id`);if(a&&!r)throw Error(`Doom config at ${n} does not support ${t}.id for whisper-cpp`);return{...i?{path:i}:{},...a?{id:a}:{}}}function H(e,t,n,r){if(e===void 0)return;if(!k(e))throw Error(`Doom config at ${n} requires ${t} to be an object`);A(e,v,t,n);let i=j(e.binary,`${t}.binary`,n);return{...i?{binary:i}:{},model:V(e.model,`${t}.model`,n,r)}}function U(e,t){if(e===void 0)return;if(!k(e))throw Error(`Doom config at ${t} requires voice to be an object`);A(e,p,`voice`,t);let n={};if(e.engine!==void 0){if(typeof e.engine!=`string`||!D.has(e.engine))throw Error(`Doom config at ${t} requires voice.engine to be one of: ${[...D].join(`, `)}`);n.engine=e.engine}let r=j(e.language,`voice.language`,t);if(r&&(n.language=r),e.recorder!==void 0){if(!k(e.recorder))throw Error(`Doom config at ${t} requires voice.recorder to be an object`);A(e.recorder,te,`voice.recorder`,t),n.recorder={};let r=j(e.recorder.binary,`voice.recorder.binary`,t),i=j(e.recorder.device,`voice.recorder.device`,t);r&&(n.recorder.binary=r),i&&(n.recorder.device=i)}if(e.adapters!==void 0){if(!k(e.adapters))throw Error(`Doom config at ${t} requires voice.adapters to be an object`);A(e.adapters,_,`voice.adapters`,t),n.adapters={[m]:H(e.adapters[m],`voice.adapters.${m}`,t,!1),[h]:H(e.adapters[h],`voice.adapters.${h}`,t,!0),[g]:H(e.adapters[g],`voice.adapters.${g}`,t,!0)}}let i=R(e.autoCapture,t);return i&&(n.autoCapture=i),n}function W(e,t){if(e===void 0)return;if(!k(e))throw Error(`Doom config at ${t} requires selection to be an object`);A(e,l,`selection`,t);let n=e.domains;if(n!==void 0&&(!Array.isArray(n)||n.some(e=>typeof e!=`string`)))throw Error(`Doom config at ${t} requires selection.domains to be an array of strings`);return{majorMode:j(e.majorMode,`selection.majorMode`,t),domains:n,profile:j(e.profile,`selection.profile`,t)}}function G(e,t){if(e!==void 0){if(!k(e))throw Error(`Doom config at ${t} requires editor to be an object`);return A(e,f,`editor`,t),{command:j(e.command,`editor.command`,t)}}}function K(e,t){let n;try{n=(0,i.parse)(e)??{}}catch(e){throw Error(`Could not parse Doom config at ${t}`,{cause:e})}if(!k(n))throw Error(`Doom config at ${t} must be a YAML object`);A(n,c,`root`,t);let r;if(n.modes!==void 0){if(!k(n.modes))throw Error(`Doom config at ${t} requires modes to be an object`);A(n.modes,ee,`modes`,t),r=n.modes.planning===void 0?{}:{planning:B(n.modes.planning,t)}}let a=n.projectTrust===void 0?`ask`:n.projectTrust;if(typeof a!=`string`||!E.has(a))throw Error(`Doom config at ${t} projectTrust must be ask, always, or never`);return{modes:r,projectTrust:a,editor:G(n.editor,t),voice:U(n.voice,t),selection:W(n.selection,t)}}function q(e){return t.default.existsSync(e)?K(t.default.readFileSync(e,`utf8`),e):{projectTrust:`ask`}}function J(e,t){return e||t?{...e,...t}:void 0}function Y(e,t){if(t.voice?.autoCapture)throw Error(`Repository Doom config voice.autoCapture is global-only; configure it in ~/.pi/.doom/config.yaml`);let n=e.modes?.planning,r=t.modes?.planning,i=n||r?{main:J(n?.main,r?.main),subagents:J(n?.subagents,r?.subagents),plansDirectory:r?.plansDirectory??n?.plansDirectory}:void 0,a=ie(e.voice,t.voice);return{modes:i?{planning:i}:void 0,projectTrust:t.projectTrust,editor:e.editor,voice:a,selection:e.selection||t.selection?{...e.selection,...t.selection}:void 0}}function X(e,t){if(!(!e&&!t))return{...e,...t,model:t?.model??e.model}}function ie(e,t){if(!(!e&&!t))return{...e,...t,recorder:e?.recorder||t?.recorder?{...e?.recorder,...t?.recorder}:void 0,adapters:e?.adapters||t?.adapters?{[m]:X(e?.adapters?.[m],t?.adapters?.[m]),[h]:X(e?.adapters?.[h],t?.adapters?.[h]),[g]:X(e?.adapters?.[g],t?.adapters?.[g])}:void 0,...e?.autoCapture?{autoCapture:e.autoCapture}:{}}}function ae(e){return{engine:e.engine??s,language:e.language??`auto`,recorder:{...e.recorder,device:e.recorder?.device??`none:default`},adapters:e.adapters??{},...e.autoCapture?{autoCapture:{...e.autoCapture,startPhrases:[...e.autoCapture.startPhrases??[]],stopPhrases:[...e.autoCapture.stopPhrases??[]],tts:{...e.autoCapture.tts}}}:{}}}function Z(e=n.default.homedir()){return r.default.join(e,`.pi`,a)}function Q(e=n.default.homedir()){return r.default.join(Z(e),o)}function oe(e,t,i=n.default.homedir()){if(!e)return r.default.join(i,`.pi`,`plans`);if(e===`~`)return i;if(e.startsWith(`~/`))return r.default.resolve(i,e.slice(2));if(e.startsWith(`~`))throw Error(`Doom planning plansDirectory supports only '~' or '~/' home aliases`);return r.default.isAbsolute(e)?r.default.normalize(e):r.default.resolve(t,e)}function $(e){return r.default.join(e,a,o)}function se(e,t=n.default.homedir()){return Y(q(Q(t)),q($(e)))}exports.DOOM_PLANNING_THINKING_LEVELS=S,exports.DOOM_VOICE_ENGINES=C,exports.DOOM_VOICE_TTS_ENGINES=w,exports.globalDoomConfigDirectory=Z,exports.globalDoomConfigPath=Q,exports.loadDoomConfig=se,exports.mergeDoomConfigs=Y,exports.parseDoomConfig=K,exports.parsePlanningModeConfig=B,exports.repositoryDoomConfigPath=$,exports.resolvePlanningPlansDirectory=oe,exports.resolveVoiceConfig=ae;
2
- //# sourceMappingURL=config.cjs.map
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./services/configPolicy/index.cjs"),t=require("./services/config/index.cjs");exports.DOOM_PLANNING_THINKING_LEVELS=e.DOOM_PLANNING_THINKING_LEVELS,exports.DOOM_VOICE_ENGINES=e.DOOM_VOICE_ENGINES,exports.DOOM_VOICE_MODES=e.DOOM_VOICE_MODES,exports.DOOM_VOICE_TTS_ENGINES=e.DOOM_VOICE_TTS_ENGINES,exports.configLeafKeys=e.configLeafKeys,exports.configRootKeys=e.configRootKeys,exports.configScopeOf=e.configScopeOf,exports.globalDoomConfigDirectory=t.globalDoomConfigDirectory,exports.globalDoomConfigPath=t.globalDoomConfigPath,exports.loadDoomConfig=t.loadDoomConfig,exports.loadDoomConfigAsync=t.loadDoomConfigAsync,exports.loadDoomConfigLayers=t.loadDoomConfigLayers,exports.loadDoomConfigLenient=t.loadDoomConfigLenient,exports.mergeDoomConfigs=e.mergeDoomConfigs,exports.parseAutocompactModeConfig=e.parseAutocompactModeConfig,exports.parseDoomConfig=e.parseDoomConfig,exports.parsePlanningModeConfig=e.parsePlanningModeConfig,exports.repositoryDoomConfigPath=t.repositoryDoomConfigPath,exports.resolvePlanningPlansDirectory=t.resolvePlanningPlansDirectory,exports.resolveVoiceConfig=e.resolveVoiceConfig,exports.valueAtKeyPath=e.valueAtKeyPath;
package/dist/config.d.cts CHANGED
@@ -1,24 +1,4 @@
1
- import { DoomConfig, PlanningModeConfig, ResolvedVoiceConfig, VoiceConfig } from "./types.cjs";
2
- //#region src/config.d.ts
3
- /**
4
- * The accepted values, in the order a picker should offer them.
5
- *
6
- * Exported because the config UI has to offer exactly what the parser accepts,
7
- * and a second hand-written list in the contributing package would drift. The
8
- * validating Sets below are built from these for the same reason.
9
- */
10
- declare const DOOM_PLANNING_THINKING_LEVELS: readonly ["off", "minimal", "low", "medium", "high", "xhigh", "max"];
11
- declare const DOOM_VOICE_ENGINES: readonly ["auto", "whisper-cpp", "openai-whisper", "mlx-whisper"];
12
- declare const DOOM_VOICE_TTS_ENGINES: readonly ["macos-say"];
13
- declare function parsePlanningModeConfig(value: unknown, filePath: string, location?: string): PlanningModeConfig;
14
- declare function parseDoomConfig(content: string, filePath: string): DoomConfig;
15
- declare function mergeDoomConfigs(globalConfig: DoomConfig, repositoryConfig: DoomConfig): DoomConfig;
16
- declare function resolveVoiceConfig(config: VoiceConfig): ResolvedVoiceConfig;
17
- declare function globalDoomConfigDirectory(homeDirectory?: string): string;
18
- declare function globalDoomConfigPath(homeDirectory?: string): string;
19
- declare function resolvePlanningPlansDirectory(configured: string | undefined, repoRoot: string, homeDirectory?: string): string;
20
- declare function repositoryDoomConfigPath(repoRoot: string): string;
21
- declare function loadDoomConfig(repoRoot: string, homeDirectory?: string): DoomConfig;
22
- //#endregion
23
- export { DOOM_PLANNING_THINKING_LEVELS, DOOM_VOICE_ENGINES, DOOM_VOICE_TTS_ENGINES, globalDoomConfigDirectory, globalDoomConfigPath, loadDoomConfig, mergeDoomConfigs, parseDoomConfig, parsePlanningModeConfig, repositoryDoomConfigPath, resolvePlanningPlansDirectory, resolveVoiceConfig };
24
- //# sourceMappingURL=config.d.cts.map
1
+ import { ConfigDiagnostic, ConfigValueOrigin, DoomConfigLayer, DoomConfigLayers, LenientParseOptions, LenientParseResult } from "./types/config.cjs";
2
+ import { globalDoomConfigDirectory, globalDoomConfigPath, loadDoomConfig, loadDoomConfigAsync, loadDoomConfigLayers, loadDoomConfigLenient, repositoryDoomConfigPath, resolvePlanningPlansDirectory } from "./services/config/index.cjs";
3
+ import { ConfigKeyScope, DOOM_PLANNING_THINKING_LEVELS, DOOM_VOICE_ENGINES, DOOM_VOICE_MODES, DOOM_VOICE_TTS_ENGINES, configLeafKeys, configRootKeys, configScopeOf, mergeDoomConfigs, parseAutocompactModeConfig, parseDoomConfig, parsePlanningModeConfig, resolveVoiceConfig, valueAtKeyPath } from "./services/configPolicy/index.cjs";
4
+ export { type ConfigDiagnostic, type ConfigKeyScope, type ConfigValueOrigin, DOOM_PLANNING_THINKING_LEVELS, DOOM_VOICE_ENGINES, DOOM_VOICE_MODES, DOOM_VOICE_TTS_ENGINES, type DoomConfigLayer, type DoomConfigLayers, type LenientParseOptions, type LenientParseResult, configLeafKeys, configRootKeys, configScopeOf, globalDoomConfigDirectory, globalDoomConfigPath, loadDoomConfig, loadDoomConfigAsync, loadDoomConfigLayers, loadDoomConfigLenient, mergeDoomConfigs, parseAutocompactModeConfig, parseDoomConfig, parsePlanningModeConfig, repositoryDoomConfigPath, resolvePlanningPlansDirectory, resolveVoiceConfig, valueAtKeyPath };
package/dist/config.d.mts CHANGED
@@ -1,24 +1,4 @@
1
- import { DoomConfig, PlanningModeConfig, ResolvedVoiceConfig, VoiceConfig } from "./types.mjs";
2
- //#region src/config.d.ts
3
- /**
4
- * The accepted values, in the order a picker should offer them.
5
- *
6
- * Exported because the config UI has to offer exactly what the parser accepts,
7
- * and a second hand-written list in the contributing package would drift. The
8
- * validating Sets below are built from these for the same reason.
9
- */
10
- declare const DOOM_PLANNING_THINKING_LEVELS: readonly ["off", "minimal", "low", "medium", "high", "xhigh", "max"];
11
- declare const DOOM_VOICE_ENGINES: readonly ["auto", "whisper-cpp", "openai-whisper", "mlx-whisper"];
12
- declare const DOOM_VOICE_TTS_ENGINES: readonly ["macos-say"];
13
- declare function parsePlanningModeConfig(value: unknown, filePath: string, location?: string): PlanningModeConfig;
14
- declare function parseDoomConfig(content: string, filePath: string): DoomConfig;
15
- declare function mergeDoomConfigs(globalConfig: DoomConfig, repositoryConfig: DoomConfig): DoomConfig;
16
- declare function resolveVoiceConfig(config: VoiceConfig): ResolvedVoiceConfig;
17
- declare function globalDoomConfigDirectory(homeDirectory?: string): string;
18
- declare function globalDoomConfigPath(homeDirectory?: string): string;
19
- declare function resolvePlanningPlansDirectory(configured: string | undefined, repoRoot: string, homeDirectory?: string): string;
20
- declare function repositoryDoomConfigPath(repoRoot: string): string;
21
- declare function loadDoomConfig(repoRoot: string, homeDirectory?: string): DoomConfig;
22
- //#endregion
23
- export { DOOM_PLANNING_THINKING_LEVELS, DOOM_VOICE_ENGINES, DOOM_VOICE_TTS_ENGINES, globalDoomConfigDirectory, globalDoomConfigPath, loadDoomConfig, mergeDoomConfigs, parseDoomConfig, parsePlanningModeConfig, repositoryDoomConfigPath, resolvePlanningPlansDirectory, resolveVoiceConfig };
24
- //# sourceMappingURL=config.d.mts.map
1
+ import { ConfigDiagnostic, ConfigValueOrigin, DoomConfigLayer, DoomConfigLayers, LenientParseOptions, LenientParseResult } from "./types/config.mjs";
2
+ import { globalDoomConfigDirectory, globalDoomConfigPath, loadDoomConfig, loadDoomConfigAsync, loadDoomConfigLayers, loadDoomConfigLenient, repositoryDoomConfigPath, resolvePlanningPlansDirectory } from "./services/config/index.mjs";
3
+ import { ConfigKeyScope, DOOM_PLANNING_THINKING_LEVELS, DOOM_VOICE_ENGINES, DOOM_VOICE_MODES, DOOM_VOICE_TTS_ENGINES, configLeafKeys, configRootKeys, configScopeOf, mergeDoomConfigs, parseAutocompactModeConfig, parseDoomConfig, parsePlanningModeConfig, resolveVoiceConfig, valueAtKeyPath } from "./services/configPolicy/index.mjs";
4
+ export { type ConfigDiagnostic, type ConfigKeyScope, type ConfigValueOrigin, DOOM_PLANNING_THINKING_LEVELS, DOOM_VOICE_ENGINES, DOOM_VOICE_MODES, DOOM_VOICE_TTS_ENGINES, type DoomConfigLayer, type DoomConfigLayers, type LenientParseOptions, type LenientParseResult, configLeafKeys, configRootKeys, configScopeOf, globalDoomConfigDirectory, globalDoomConfigPath, loadDoomConfig, loadDoomConfigAsync, loadDoomConfigLayers, loadDoomConfigLenient, mergeDoomConfigs, parseAutocompactModeConfig, parseDoomConfig, parsePlanningModeConfig, repositoryDoomConfigPath, resolvePlanningPlansDirectory, resolveVoiceConfig, valueAtKeyPath };
package/dist/config.mjs CHANGED
@@ -1,2 +1 @@
1
- import e from"node:fs";import t from"node:os";import n from"node:path";import{parse as r}from"yaml";const i=`.doom`,a=`config.yaml`,o=`auto`,s=[`modes`,`projectTrust`,`editor`,`voice`,`selection`],c=[`majorMode`,`domains`,`profile`],ee=[`planning`],te=[`main`,`subagents`,`plansDirectory`],ne=[`model`,`thinking`],l=[`command`],u=[`engine`,`language`,`recorder`,`adapters`,`autoCapture`],d=[`binary`,`device`],f=`whisper-cpp`,p=`openai-whisper`,m=`mlx-whisper`,h=[f,p,m],g=[`binary`,`model`],_=[`path`,`id`],v=[`model`,`startPhrases`,`stopPhrases`,`tts`],y=[`engine`,`voice`,`rate`],b=/^[^/\s]+\/[^/\s]+(?:\/[^/\s]+)*$/u,x=/[\p{P}\p{S}]+/gu,S=[`off`,`minimal`,`low`,`medium`,`high`,`xhigh`,`max`],C=[o,f,p,m],w=[`macos-say`],T=new Set(S),E=new Set([`ask`,`always`,`never`]),D=new Set(C),O=new Set(w);function k(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function A(e,t,n,r){let i=Object.keys(e).filter(e=>!t.includes(e));if(i.length>0)throw Error(`Doom config at ${r} has unsupported ${n} field(s): ${i.join(`, `)}`)}function j(e,t,n){if(e!==void 0){if(typeof e!=`string`||e.trim().length===0)throw Error(`Doom config at ${n} requires ${t} to be a non-empty string`);return e.trim()}}function M(e){for(let t of e){let e=t.codePointAt(0);if(e!==void 0&&(e<=31||e===127))return!0}return!1}function N(e,t,n,r){let i=j(e,t,n);if(i){if(i.length>r)throw Error(`Doom config at ${n} requires ${t} to be at most ${r} characters`);if(M(i))throw Error(`Doom config at ${n} does not allow control characters in ${t}`);return i}}function P(e,t){let n=`voice.autoCapture.model`,r=j(e,n,t);if(!r||!b.test(r))throw Error(`Doom config at ${t} requires ${n} in provider/model-id form`);return r}function F(e){return e.normalize(`NFKC`).toLocaleLowerCase(`en-US`).replace(x,` `).replace(/\s+/gu,` `).trim()}function I(e,t,n){if(e===void 0)return;if(!Array.isArray(e)||e.some(e=>typeof e!=`string`))throw Error(`Doom config at ${n} requires ${t} to be an array of strings`);if(e.length>16)throw Error(`Doom config at ${n} requires ${t} to contain at most 16 phrases`);let r=e.map(e=>e.trim()),i=new Set;for(let e of r){if(e.length===0)throw Error(`Doom config at ${n} requires ${t} to contain non-empty strings`);if(e.length>64)throw Error(`Doom config at ${n} requires ${t} phrases to be at most 64 characters`);if(M(e))throw Error(`Doom config at ${n} does not allow control characters in ${t}`);let r=F(e);if(!r)throw Error(`Doom config at ${n} requires ${t} to contain words`);if(i.has(r))throw Error(`Doom config at ${n} does not allow normalized duplicates in ${t}`);i.add(r)}return r}function L(e,t){let n=`voice.autoCapture.tts`;if(!k(e))throw Error(`Doom config at ${t} requires ${n} to be an object`);if(A(e,y,n,t),typeof e.engine!=`string`||!O.has(e.engine))throw Error(`Doom config at ${t} requires ${n}.engine to be one of: ${[...O].join(`, `)}`);let r=N(e.voice,`${n}.voice`,t,64),i=e.rate;if(i!==void 0&&(typeof i!=`number`||!Number.isInteger(i)||i<80||i>500))throw Error(`Doom config at ${t} requires ${n}.rate to be an integer from 80 to 500`);return{engine:e.engine,...r?{voice:r}:{},...i===void 0?{}:{rate:i}}}function R(e,t){if(e===void 0)return;let n=`voice.autoCapture`;if(!k(e))throw Error(`Doom config at ${t} requires ${n} to be an object`);A(e,v,n,t);let r=I(e.startPhrases,`${n}.startPhrases`,t),i=I(e.stopPhrases,`${n}.stopPhrases`,t),a=new Set((r??[]).map(F));if((i??[]).some(e=>a.has(F(e))))throw Error(`Doom config at ${t} does not allow a phrase in both startPhrases and stopPhrases`);return{model:P(e.model,t),...r?{startPhrases:r}:{},...i?{stopPhrases:i}:{},tts:L(e.tts,t)}}function z(e,t,n){if(e===void 0)return;if(!k(e))throw Error(`Doom config at ${n} requires ${t} to be an object`);A(e,ne,t,n);let r=e.thinking;if(r!==void 0&&(typeof r!=`string`||!T.has(r)))throw Error(`Doom config at ${n} requires ${t}.thinking to be one of: ${[...T].join(`, `)}`);let i=j(e.model,`${t}.model`,n);return{...i?{model:i}:{},...r?{thinking:r}:{}}}function B(e,t,n=`modes.planning`){if(!k(e))throw Error(`Doom config at ${t} requires ${n} to be an object`);return A(e,te,n,t),{main:z(e.main,`${n}.main`,t),subagents:z(e.subagents,`${n}.subagents`,t),plansDirectory:j(e.plansDirectory,`${n}.plansDirectory`,t)}}function V(e,t,n,r){if(!k(e))throw Error(`Doom config at ${n} requires ${t} to be an object`);A(e,_,t,n);let i=j(e.path,`${t}.path`,n),a=j(e.id,`${t}.id`,n);if(!!i==!!a)throw Error(`Doom config at ${n} requires exactly one of ${t}.path or ${t}.id`);if(a&&!r)throw Error(`Doom config at ${n} does not support ${t}.id for whisper-cpp`);return{...i?{path:i}:{},...a?{id:a}:{}}}function H(e,t,n,r){if(e===void 0)return;if(!k(e))throw Error(`Doom config at ${n} requires ${t} to be an object`);A(e,g,t,n);let i=j(e.binary,`${t}.binary`,n);return{...i?{binary:i}:{},model:V(e.model,`${t}.model`,n,r)}}function U(e,t){if(e===void 0)return;if(!k(e))throw Error(`Doom config at ${t} requires voice to be an object`);A(e,u,`voice`,t);let n={};if(e.engine!==void 0){if(typeof e.engine!=`string`||!D.has(e.engine))throw Error(`Doom config at ${t} requires voice.engine to be one of: ${[...D].join(`, `)}`);n.engine=e.engine}let r=j(e.language,`voice.language`,t);if(r&&(n.language=r),e.recorder!==void 0){if(!k(e.recorder))throw Error(`Doom config at ${t} requires voice.recorder to be an object`);A(e.recorder,d,`voice.recorder`,t),n.recorder={};let r=j(e.recorder.binary,`voice.recorder.binary`,t),i=j(e.recorder.device,`voice.recorder.device`,t);r&&(n.recorder.binary=r),i&&(n.recorder.device=i)}if(e.adapters!==void 0){if(!k(e.adapters))throw Error(`Doom config at ${t} requires voice.adapters to be an object`);A(e.adapters,h,`voice.adapters`,t),n.adapters={[f]:H(e.adapters[f],`voice.adapters.${f}`,t,!1),[p]:H(e.adapters[p],`voice.adapters.${p}`,t,!0),[m]:H(e.adapters[m],`voice.adapters.${m}`,t,!0)}}let i=R(e.autoCapture,t);return i&&(n.autoCapture=i),n}function W(e,t){if(e===void 0)return;if(!k(e))throw Error(`Doom config at ${t} requires selection to be an object`);A(e,c,`selection`,t);let n=e.domains;if(n!==void 0&&(!Array.isArray(n)||n.some(e=>typeof e!=`string`)))throw Error(`Doom config at ${t} requires selection.domains to be an array of strings`);return{majorMode:j(e.majorMode,`selection.majorMode`,t),domains:n,profile:j(e.profile,`selection.profile`,t)}}function G(e,t){if(e!==void 0){if(!k(e))throw Error(`Doom config at ${t} requires editor to be an object`);return A(e,l,`editor`,t),{command:j(e.command,`editor.command`,t)}}}function K(e,t){let n;try{n=r(e)??{}}catch(e){throw Error(`Could not parse Doom config at ${t}`,{cause:e})}if(!k(n))throw Error(`Doom config at ${t} must be a YAML object`);A(n,s,`root`,t);let i;if(n.modes!==void 0){if(!k(n.modes))throw Error(`Doom config at ${t} requires modes to be an object`);A(n.modes,ee,`modes`,t),i=n.modes.planning===void 0?{}:{planning:B(n.modes.planning,t)}}let a=n.projectTrust===void 0?`ask`:n.projectTrust;if(typeof a!=`string`||!E.has(a))throw Error(`Doom config at ${t} projectTrust must be ask, always, or never`);return{modes:i,projectTrust:a,editor:G(n.editor,t),voice:U(n.voice,t),selection:W(n.selection,t)}}function q(t){return e.existsSync(t)?K(e.readFileSync(t,`utf8`),t):{projectTrust:`ask`}}function J(e,t){return e||t?{...e,...t}:void 0}function Y(e,t){if(t.voice?.autoCapture)throw Error(`Repository Doom config voice.autoCapture is global-only; configure it in ~/.pi/.doom/config.yaml`);let n=e.modes?.planning,r=t.modes?.planning,i=n||r?{main:J(n?.main,r?.main),subagents:J(n?.subagents,r?.subagents),plansDirectory:r?.plansDirectory??n?.plansDirectory}:void 0,a=re(e.voice,t.voice);return{modes:i?{planning:i}:void 0,projectTrust:t.projectTrust,editor:e.editor,voice:a,selection:e.selection||t.selection?{...e.selection,...t.selection}:void 0}}function X(e,t){if(!(!e&&!t))return{...e,...t,model:t?.model??e.model}}function re(e,t){if(!(!e&&!t))return{...e,...t,recorder:e?.recorder||t?.recorder?{...e?.recorder,...t?.recorder}:void 0,adapters:e?.adapters||t?.adapters?{[f]:X(e?.adapters?.[f],t?.adapters?.[f]),[p]:X(e?.adapters?.[p],t?.adapters?.[p]),[m]:X(e?.adapters?.[m],t?.adapters?.[m])}:void 0,...e?.autoCapture?{autoCapture:e.autoCapture}:{}}}function ie(e){return{engine:e.engine??o,language:e.language??`auto`,recorder:{...e.recorder,device:e.recorder?.device??`none:default`},adapters:e.adapters??{},...e.autoCapture?{autoCapture:{...e.autoCapture,startPhrases:[...e.autoCapture.startPhrases??[]],stopPhrases:[...e.autoCapture.stopPhrases??[]],tts:{...e.autoCapture.tts}}}:{}}}function Z(e=t.homedir()){return n.join(e,`.pi`,i)}function Q(e=t.homedir()){return n.join(Z(e),a)}function ae(e,r,i=t.homedir()){if(!e)return n.join(i,`.pi`,`plans`);if(e===`~`)return i;if(e.startsWith(`~/`))return n.resolve(i,e.slice(2));if(e.startsWith(`~`))throw Error(`Doom planning plansDirectory supports only '~' or '~/' home aliases`);return n.isAbsolute(e)?n.normalize(e):n.resolve(r,e)}function $(e){return n.join(e,i,a)}function oe(e,n=t.homedir()){return Y(q(Q(n)),q($(e)))}export{S as DOOM_PLANNING_THINKING_LEVELS,C as DOOM_VOICE_ENGINES,w as DOOM_VOICE_TTS_ENGINES,Z as globalDoomConfigDirectory,Q as globalDoomConfigPath,oe as loadDoomConfig,Y as mergeDoomConfigs,K as parseDoomConfig,B as parsePlanningModeConfig,$ as repositoryDoomConfigPath,ae as resolvePlanningPlansDirectory,ie as resolveVoiceConfig};
2
- //# sourceMappingURL=config.mjs.map
1
+ import{DOOM_PLANNING_THINKING_LEVELS as e,DOOM_VOICE_ENGINES as t,DOOM_VOICE_MODES as n,DOOM_VOICE_TTS_ENGINES as r,configLeafKeys as i,configRootKeys as a,configScopeOf as o,mergeDoomConfigs as s,parseAutocompactModeConfig as c,parseDoomConfig as l,parsePlanningModeConfig as u,resolveVoiceConfig as d,valueAtKeyPath as f}from"./services/configPolicy/index.mjs";import{globalDoomConfigDirectory as p,globalDoomConfigPath as m,loadDoomConfig as h,loadDoomConfigAsync as g,loadDoomConfigLayers as _,loadDoomConfigLenient as v,repositoryDoomConfigPath as y,resolvePlanningPlansDirectory as b}from"./services/config/index.mjs";export{e as DOOM_PLANNING_THINKING_LEVELS,t as DOOM_VOICE_ENGINES,n as DOOM_VOICE_MODES,r as DOOM_VOICE_TTS_ENGINES,i as configLeafKeys,a as configRootKeys,o as configScopeOf,p as globalDoomConfigDirectory,m as globalDoomConfigPath,h as loadDoomConfig,g as loadDoomConfigAsync,_ as loadDoomConfigLayers,v as loadDoomConfigLenient,s as mergeDoomConfigs,c as parseAutocompactModeConfig,l as parseDoomConfig,u as parsePlanningModeConfig,y as repositoryDoomConfigPath,b as resolvePlanningPlansDirectory,d as resolveVoiceConfig,f as valueAtKeyPath};
@@ -0,0 +1,2 @@
1
+ import { ConfigAdapterRegistrationOptions, DoomAdapterSettings, PiConfig, PiConfigLoadOptions, PiConfigPaths } from "./types/piConfig.cjs";
2
+ export type { ConfigAdapterRegistrationOptions, DoomAdapterSettings, PiConfig, PiConfigLoadOptions, PiConfigPaths };
@@ -0,0 +1,2 @@
1
+ import { ConfigAdapterRegistrationOptions, DoomAdapterSettings, PiConfig, PiConfigLoadOptions, PiConfigPaths } from "./types/piConfig.mjs";
2
+ export type { ConfigAdapterRegistrationOptions, DoomAdapterSettings, PiConfig, PiConfigLoadOptions, PiConfigPaths };
@@ -1,2 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./_virtual/_rolldown/runtime.cjs"),t=require("./config.cjs");let n=require("node:path");n=e.__toESM(n,1);let r=require("yaml"),i=require("node:crypto"),a=require("node:fs/promises");a=e.__toESM(a,1);async function o(e){try{return await a.default.readFile(e,`utf8`)}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return``;throw e}}function s(e){if(typeof e!=`object`||!e)return!1;let t=e.items;return Array.isArray(t)&&t.length===0}function c(e,t){for(let n=t.length-1;n>0;--n){let r=t.slice(0,n);if(e.hasIn(r)){if(!s(e.getIn(r,!0)))return;e.deleteIn(r)}}}async function l(e,s,l={}){if(s.length===0)return;let u=await o(e),d=(0,r.parseDocument)(u,{keepSourceTokens:!0});if(d.errors.length>0)throw Error(`Could not parse Doom config at ${e}`);for(let e of s){let t=[...e.keyPath];if(e.value!==void 0){d.setIn(t,e.value);continue}d.hasIn(t)&&(d.deleteIn(t),l.prune!==!1&&c(d,t))}let f=d.toString();t.parseDoomConfig(f,e),await a.default.mkdir(n.default.dirname(e),{mode:448,recursive:!0});let p=`${e}.${process.pid}.${(0,i.randomUUID)()}.tmp`;try{await a.default.writeFile(p,f,{encoding:`utf8`,mode:384}),await a.default.rename(p,e)}catch(e){throw await a.default.rm(p,{force:!0}),e}}async function u(e,t,n){await l(e,[{keyPath:t,value:n}])}async function d(e,t){await l(e,[{keyPath:t}])}exports.setDoomConfigValue=u,exports.unsetDoomConfigValue=d,exports.writeDoomConfigValues=l;
2
- //# sourceMappingURL=configWriter.cjs.map
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./services/configWriter/index.cjs");exports.setDoomConfigValue=e.setDoomConfigValue,exports.unsetDoomConfigValue=e.unsetDoomConfigValue,exports.writeDoomConfigValues=e.writeDoomConfigValues;
@@ -1,52 +1,2 @@
1
- //#region src/configWriter.d.ts
2
- /**
3
- * Writes into the global Doom config file, one key path at a time.
4
- *
5
- * Extracted from doom-file-edit, which owned the only writer in the repo and had
6
- * it hard-coded to `editor.command`. Several extensions now edit their own
7
- * settings from the config panel, and every one of them needs the same four
8
- * properties: keep the user's comments, never publish a file the parser would
9
- * reject, never leave a half-written file behind, and apply a set of related
10
- * edits together.
11
- *
12
- * That last one is not a convenience. `voice.adapters.<engine>.model` accepts a
13
- * path or an id but not both, so switching between them is a set and an unset
14
- * that must land in the same write, or the file is briefly invalid.
15
- *
16
- * Atomicity is the same rename trick as `atomicJson.ts` next door, and carries
17
- * the same caveat: it prevents torn reads, not lost updates. Two sessions with
18
- * the panel open still clobber each other, because the rename only publishes
19
- * what the caller already computed.
20
- *
21
- * AVOID:
22
- * - Treating this as a lock
23
- * - Writing an empty string; the parser rejects blank values, so clearing a key
24
- * means removing it
25
- */
26
- interface DoomConfigEdit {
27
- /** Key path into the document, e.g. `['voice', 'adapters', 'mlx-whisper', 'model', 'id']`. */
28
- readonly keyPath: readonly string[];
29
- /** The value to write. `undefined` removes the key. */
30
- readonly value?: string;
31
- }
32
- interface WriteDoomConfigOptions {
33
- /**
34
- * Remove ancestors left holding nothing. Defaults to true, and is not
35
- * cosmetic: an adapter left as `{}` fails validation, because the parser
36
- * requires a model once the adapter exists at all.
37
- */
38
- readonly prune?: boolean;
39
- }
40
- /**
41
- * Applies every edit as one document mutation, or throws having written nothing.
42
- *
43
- * Validation runs against the serialized result rather than each edit, so a pair
44
- * of edits only valid together is accepted, and a single edit that breaks an
45
- * invariant elsewhere is still caught.
46
- */
47
- declare function writeDoomConfigValues(filePath: string, edits: readonly DoomConfigEdit[], options?: WriteDoomConfigOptions): Promise<void>;
48
- declare function setDoomConfigValue(filePath: string, keyPath: readonly string[], value: string): Promise<void>;
49
- declare function unsetDoomConfigValue(filePath: string, keyPath: readonly string[]): Promise<void>;
50
- //#endregion
51
- export { DoomConfigEdit, WriteDoomConfigOptions, setDoomConfigValue, unsetDoomConfigValue, writeDoomConfigValues };
52
- //# sourceMappingURL=configWriter.d.cts.map
1
+ import { DoomConfigEdit, DoomConfigScope, WriteDoomConfigOptions, setDoomConfigValue, unsetDoomConfigValue, writeDoomConfigValues } from "./services/configWriter/index.cjs";
2
+ export { type DoomConfigEdit, type DoomConfigScope, type WriteDoomConfigOptions, setDoomConfigValue, unsetDoomConfigValue, writeDoomConfigValues };
@@ -1,52 +1,2 @@
1
- //#region src/configWriter.d.ts
2
- /**
3
- * Writes into the global Doom config file, one key path at a time.
4
- *
5
- * Extracted from doom-file-edit, which owned the only writer in the repo and had
6
- * it hard-coded to `editor.command`. Several extensions now edit their own
7
- * settings from the config panel, and every one of them needs the same four
8
- * properties: keep the user's comments, never publish a file the parser would
9
- * reject, never leave a half-written file behind, and apply a set of related
10
- * edits together.
11
- *
12
- * That last one is not a convenience. `voice.adapters.<engine>.model` accepts a
13
- * path or an id but not both, so switching between them is a set and an unset
14
- * that must land in the same write, or the file is briefly invalid.
15
- *
16
- * Atomicity is the same rename trick as `atomicJson.ts` next door, and carries
17
- * the same caveat: it prevents torn reads, not lost updates. Two sessions with
18
- * the panel open still clobber each other, because the rename only publishes
19
- * what the caller already computed.
20
- *
21
- * AVOID:
22
- * - Treating this as a lock
23
- * - Writing an empty string; the parser rejects blank values, so clearing a key
24
- * means removing it
25
- */
26
- interface DoomConfigEdit {
27
- /** Key path into the document, e.g. `['voice', 'adapters', 'mlx-whisper', 'model', 'id']`. */
28
- readonly keyPath: readonly string[];
29
- /** The value to write. `undefined` removes the key. */
30
- readonly value?: string;
31
- }
32
- interface WriteDoomConfigOptions {
33
- /**
34
- * Remove ancestors left holding nothing. Defaults to true, and is not
35
- * cosmetic: an adapter left as `{}` fails validation, because the parser
36
- * requires a model once the adapter exists at all.
37
- */
38
- readonly prune?: boolean;
39
- }
40
- /**
41
- * Applies every edit as one document mutation, or throws having written nothing.
42
- *
43
- * Validation runs against the serialized result rather than each edit, so a pair
44
- * of edits only valid together is accepted, and a single edit that breaks an
45
- * invariant elsewhere is still caught.
46
- */
47
- declare function writeDoomConfigValues(filePath: string, edits: readonly DoomConfigEdit[], options?: WriteDoomConfigOptions): Promise<void>;
48
- declare function setDoomConfigValue(filePath: string, keyPath: readonly string[], value: string): Promise<void>;
49
- declare function unsetDoomConfigValue(filePath: string, keyPath: readonly string[]): Promise<void>;
50
- //#endregion
51
- export { DoomConfigEdit, WriteDoomConfigOptions, setDoomConfigValue, unsetDoomConfigValue, writeDoomConfigValues };
52
- //# sourceMappingURL=configWriter.d.mts.map
1
+ import { DoomConfigEdit, DoomConfigScope, WriteDoomConfigOptions, setDoomConfigValue, unsetDoomConfigValue, writeDoomConfigValues } from "./services/configWriter/index.mjs";
2
+ export { type DoomConfigEdit, type DoomConfigScope, type WriteDoomConfigOptions, setDoomConfigValue, unsetDoomConfigValue, writeDoomConfigValues };
@@ -1,2 +1 @@
1
- import{parseDoomConfig as e}from"./config.mjs";import t from"node:path";import{parseDocument as n}from"yaml";import{randomUUID as r}from"node:crypto";import i from"node:fs/promises";async function a(e){try{return await i.readFile(e,`utf8`)}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return``;throw e}}function o(e){if(typeof e!=`object`||!e)return!1;let t=e.items;return Array.isArray(t)&&t.length===0}function s(e,t){for(let n=t.length-1;n>0;--n){let r=t.slice(0,n);if(e.hasIn(r)){if(!o(e.getIn(r,!0)))return;e.deleteIn(r)}}}async function c(o,c,l={}){if(c.length===0)return;let u=await a(o),d=n(u,{keepSourceTokens:!0});if(d.errors.length>0)throw Error(`Could not parse Doom config at ${o}`);for(let e of c){let t=[...e.keyPath];if(e.value!==void 0){d.setIn(t,e.value);continue}d.hasIn(t)&&(d.deleteIn(t),l.prune!==!1&&s(d,t))}let f=d.toString();e(f,o),await i.mkdir(t.dirname(o),{mode:448,recursive:!0});let p=`${o}.${process.pid}.${r()}.tmp`;try{await i.writeFile(p,f,{encoding:`utf8`,mode:384}),await i.rename(p,o)}catch(e){throw await i.rm(p,{force:!0}),e}}async function l(e,t,n){await c(e,[{keyPath:t,value:n}])}async function u(e,t){await c(e,[{keyPath:t}])}export{l as setDoomConfigValue,u as unsetDoomConfigValue,c as writeDoomConfigValues};
2
- //# sourceMappingURL=configWriter.mjs.map
1
+ import{setDoomConfigValue as e,unsetDoomConfigValue as t,writeDoomConfigValues as n}from"./services/configWriter/index.mjs";export{e as setDoomConfigValue,t as unsetDoomConfigValue,n as writeDoomConfigValues};
@@ -0,0 +1,2 @@
1
+ const e={name:`doompi-author-config`,description:`Configure DoomPi runtime settings, source precedence, and typed session configuration. Use for config.yaml, the doom/config Cordis service, immutable context snapshots, or shared selection transition state. Do not use for defining modes.yaml, domains.yaml, or profiles.yaml.`};exports.CONFIG_HELP_SKILL=e,exports.PACKAGE_SOURCE=`@agimon-ai/doompi-config`;
2
+ //# sourceMappingURL=config.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.cjs","names":[],"sources":["../../src/constants/config.ts"],"sourcesContent":["export const PACKAGE_SOURCE = '@agimon-ai/doompi-config';\nexport const CONFIG_HELP_SKILL = {\n name: 'doompi-author-config',\n description:\n 'Configure DoomPi runtime settings, source precedence, and typed session configuration. Use for config.yaml, the doom/config Cordis service, immutable context snapshots, or shared selection transition state. Do not use for defining modes.yaml, domains.yaml, or profiles.yaml.',\n};\n"],"mappings":"AAAA,MACa,EAAoB,CAC/B,KAAM,uBACN,YACE,oRACJ"}
@@ -0,0 +1,2 @@
1
+ const e=`@agimon-ai/doompi-config`,t={name:`doompi-author-config`,description:`Configure DoomPi runtime settings, source precedence, and typed session configuration. Use for config.yaml, the doom/config Cordis service, immutable context snapshots, or shared selection transition state. Do not use for defining modes.yaml, domains.yaml, or profiles.yaml.`};export{t as CONFIG_HELP_SKILL,e as PACKAGE_SOURCE};
2
+ //# sourceMappingURL=config.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.mjs","names":[],"sources":["../../src/constants/config.ts"],"sourcesContent":["export const PACKAGE_SOURCE = '@agimon-ai/doompi-config';\nexport const CONFIG_HELP_SKILL = {\n name: 'doompi-author-config',\n description:\n 'Configure DoomPi runtime settings, source precedence, and typed session configuration. Use for config.yaml, the doom/config Cordis service, immutable context snapshots, or shared selection transition state. Do not use for defining modes.yaml, domains.yaml, or profiles.yaml.',\n};\n"],"mappings":"AAAA,MAAa,EAAiB,2BACjB,EAAoB,CAC/B,KAAM,uBACN,YACE,oRACJ"}
@@ -0,0 +1,2 @@
1
+ const e={majorMode:[`selection`,`majorMode`],domains:[`selection`,`domains`],profile:[`selection`,`profile`]};exports.SELECTION_KEYS=e;
2
+ //# sourceMappingURL=settings.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.cjs","names":[],"sources":["../../src/constants/settings.ts"],"sourcesContent":["export const KEY_SEPARATOR = '.';\n\nexport const SELECTION_KEYS = {\n majorMode: ['selection', 'majorMode'],\n domains: ['selection', 'domains'],\n profile: ['selection', 'profile'],\n} as const;\n"],"mappings":"AAEA,MAAa,EAAiB,CAC5B,UAAW,CAAC,YAAa,WAAW,EACpC,QAAS,CAAC,YAAa,SAAS,EAChC,QAAS,CAAC,YAAa,SAAS,CAClC"}
@@ -0,0 +1,2 @@
1
+ const e={majorMode:[`selection`,`majorMode`],domains:[`selection`,`domains`],profile:[`selection`,`profile`]};export{e as SELECTION_KEYS};
2
+ //# sourceMappingURL=settings.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.mjs","names":[],"sources":["../../src/constants/settings.ts"],"sourcesContent":["export const KEY_SEPARATOR = '.';\n\nexport const SELECTION_KEYS = {\n majorMode: ['selection', 'majorMode'],\n domains: ['selection', 'domains'],\n profile: ['selection', 'profile'],\n} as const;\n"],"mappings":"AAEA,MAAa,EAAiB,CAC5B,UAAW,CAAC,YAAa,WAAW,EACpC,QAAS,CAAC,YAAa,SAAS,EAChC,QAAS,CAAC,YAAa,SAAS,CAClC"}
@@ -0,0 +1,2 @@
1
+ const e=require("../services/configPolicy/index.cjs"),t=require("../services/config/index.cjs"),n=require("../services/configWriter/index.cjs"),r=require("../services/imageSettings/index.cjs"),i=require("../services/piConfig/index.cjs"),a=require("../services/settings/index.cjs"),o={basePath:`settings`,start(o){if(o.scope===`session`)throw Error(`Configuration settings require a global or workspace mount.`);let{homeDirectory:s}=o,c=()=>o.scope===`workspace`&&o.workspaceId&&o.workspaceRoot?{id:o.workspaceId,name:o.workspaceRoot.split(`/`).at(-1)??o.workspaceId,path:o.workspaceRoot,active:o.repositories?.().find(e=>e.id===o.workspaceId)?.active??!1}:void 0,l=()=>({...i.loadPiImageSettings(s),minDimension:256,maxAllowedDimension:r.DEFAULT_IMAGE_MAX_DIMENSION}),u=Promise.resolve(),d=!1,f=async r=>{if(d)return Response.json({error:`Configuration mount is closed.`},{status:503});let u=new URL(r.url),f=c();if(u.pathname===`/`&&r.method===`GET`)return Response.json(a.configView(o,u.searchParams.getAll(`key`)));if(u.pathname===`/repositories`&&r.method===`GET`)return Response.json({repositories:o.repositories?.()??[]});if(u.pathname===`/repository`&&r.method===`GET`)return f?Response.json(a.repositorySettingsView(f,s)):Response.json({error:`Choose a workspace.`},{status:404});if(u.pathname===`/images`&&o.scope===`global`){if(r.method===`GET`)return Response.json(l());if(r.method===`PUT`){let e=await r.json();return!a.isRecord(e)||e.autoResize!==void 0&&typeof e.autoResize!=`boolean`||e.maxDimension!==void 0&&(typeof e.maxDimension!=`number`||!Number.isFinite(e.maxDimension))?Response.json({error:`Invalid image settings.`},{status:400}):(i.savePiImageSettings({...typeof e.autoResize==`boolean`?{autoResize:e.autoResize}:{},...typeof e.maxDimension==`number`?{maxDimension:e.maxDimension}:{}},s),o.configurationChanged?.(),Response.json(l()))}}if(u.pathname===`/repository/selection`&&r.method===`PUT`){let e=a.parseSelectionWrite(await r.json());if(!e)return Response.json({error:`A selection write needs typed changes and a file hash.`},{status:400});if(!f||e.repositoryId!==f.id)return Response.json({error:`Workspace not found in this mount.`},{status:404});let i=a.repositorySettingsView(f,s);if(i.hash!==e.expectedHash)return Response.json({error:`The repository config changed since it was read.`,hash:i.hash},{status:409});let c=a.validateSelectionChanges(i,e.changes);return c?Response.json({error:c},{status:422}):(await n.writeDoomConfigValues(t.repositoryDoomConfigPath(f.path),a.selectionEdits(e.changes),{scope:`repository`}),o.configurationChanged?.(),Response.json(a.repositorySettingsView(f,s)))}if(u.pathname===`/value`&&r.method===`PUT`){let t=a.parseWrite(await r.json());if(!t)return Response.json({error:`A save requires a scope, key, value and file hash.`},{status:400});let i=o.scope===`global`?`global`:`repository`;if(t.scope!==i||i===`repository`&&t.repoRoot!==f?.path)return Response.json({error:`The write targets a different mount.`},{status:403});if(t.edits.some(t=>{let n=e.configScopeOf(t.keyPath);return n!==`both`&&n!==i}))return Response.json({error:`This key cannot be set at this scope.`},{status:409});let c=a.configView(o,[]);if(c.hashes[i]!==t.expectedHash)return Response.json({error:`The config changed since it was read.`,hash:c.hashes[i]},{status:409});let l=a.pathFor(i,f?.path??``,s);return await n.writeDoomConfigValues(l,t.edits.map(({keyPath:e,value:t})=>({keyPath:e,...t===null?{}:{value:t}})),{scope:i}),o.configurationChanged?.(),Response.json(a.configView(o,t.edits.map(e=>e.keyPath.join(`.`))))}return Response.json({error:`Configuration route not found.`},{status:404})},p=async e=>{try{return await f(e)}catch(e){return Response.json({error:a.describe(e)},{status:e instanceof SyntaxError?400:422})}};return{fetch(e){if(e.method===`GET`||e.method===`HEAD`)return p(e);let t=u.then(()=>p(e));return u=t.catch(()=>void 0),t},close(){d=!0}}}};exports.settingsApi=o;
2
+ //# sourceMappingURL=settingsApi.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settingsApi.cjs","names":["loadPiImageSettings","DEFAULT_IMAGE_MAX_DIMENSION","configView","repositorySettingsView","isRecord","parseSelectionWrite","validateSelectionChanges","writeDoomConfigValues","repositoryDoomConfigPath","selectionEdits","parseWrite","configScopeOf","pathFor","describe"],"sources":["../../src/controllers/settingsApi.ts"],"sourcesContent":["import type { DoomApi } from '@agimon-ai/doompi-core/package-api';\n\nimport { KEY_SEPARATOR } from '../constants/settings';\nimport { repositoryDoomConfigPath } from '../services/config';\nimport { configScopeOf } from '../services/configPolicy';\nimport { writeDoomConfigValues } from '../services/configWriter';\nimport { DEFAULT_IMAGE_MAX_DIMENSION, MIN_IMAGE_MAX_DIMENSION } from '../services/imageSettings';\nimport { loadPiImageSettings, savePiImageSettings } from '../services/piConfig';\nimport {\n configView,\n describe,\n isRecord,\n parseSelectionWrite,\n parseWrite,\n pathFor,\n repositorySettingsView,\n selectionEdits,\n validateSelectionChanges,\n} from '../services/settings';\nimport type { SettingsRepository } from '../types/settings';\n\n/** Config handlers are bound to their mount. Request paths cannot choose a different repository. */\nexport const settingsApi: DoomApi = {\n basePath: 'settings',\n start(context) {\n if (context.scope === 'session') throw new Error('Configuration settings require a global or workspace mount.');\n const { homeDirectory } = context;\n const repository = (): SettingsRepository | undefined =>\n context.scope === 'workspace' && context.workspaceId && context.workspaceRoot\n ? {\n id: context.workspaceId,\n name: context.workspaceRoot.split('/').at(-1) ?? context.workspaceId,\n path: context.workspaceRoot,\n active: context.repositories?.().find((entry) => entry.id === context.workspaceId)?.active ?? false,\n }\n : undefined;\n const imageView = () => ({\n ...loadPiImageSettings(homeDirectory),\n minDimension: MIN_IMAGE_MAX_DIMENSION,\n maxAllowedDimension: DEFAULT_IMAGE_MAX_DIMENSION,\n });\n let writes: Promise<unknown> = Promise.resolve();\n let closed = false;\n const dispatch = async (request: Request): Promise<Response> => {\n if (closed) return Response.json({ error: 'Configuration mount is closed.' }, { status: 503 });\n const url = new URL(request.url);\n const currentRepository = repository();\n if (url.pathname === '/' && request.method === 'GET')\n return Response.json(configView(context, url.searchParams.getAll('key')));\n if (url.pathname === '/repositories' && request.method === 'GET')\n return Response.json({ repositories: context.repositories?.() ?? [] });\n if (url.pathname === '/repository' && request.method === 'GET') {\n return currentRepository\n ? Response.json(repositorySettingsView(currentRepository, homeDirectory))\n : Response.json({ error: 'Choose a workspace.' }, { status: 404 });\n }\n if (url.pathname === '/images' && context.scope === 'global') {\n if (request.method === 'GET') return Response.json(imageView());\n if (request.method === 'PUT') {\n const body: unknown = await request.json();\n if (\n !isRecord(body) ||\n (body.autoResize !== undefined && typeof body.autoResize !== 'boolean') ||\n (body.maxDimension !== undefined &&\n (typeof body.maxDimension !== 'number' || !Number.isFinite(body.maxDimension)))\n )\n return Response.json({ error: 'Invalid image settings.' }, { status: 400 });\n savePiImageSettings(\n {\n ...(typeof body.autoResize === 'boolean' ? { autoResize: body.autoResize } : {}),\n ...(typeof body.maxDimension === 'number' ? { maxDimension: body.maxDimension } : {}),\n },\n homeDirectory,\n );\n context.configurationChanged?.();\n return Response.json(imageView());\n }\n }\n if (url.pathname === '/repository/selection' && request.method === 'PUT') {\n const body = parseSelectionWrite(await request.json());\n if (!body)\n return Response.json({ error: 'A selection write needs typed changes and a file hash.' }, { status: 400 });\n if (!currentRepository || body.repositoryId !== currentRepository.id)\n return Response.json({ error: 'Workspace not found in this mount.' }, { status: 404 });\n const before = repositorySettingsView(currentRepository, homeDirectory);\n if (before.hash !== body.expectedHash)\n return Response.json(\n { error: 'The repository config changed since it was read.', hash: before.hash },\n { status: 409 },\n );\n const invalid = validateSelectionChanges(before, body.changes);\n if (invalid) return Response.json({ error: invalid }, { status: 422 });\n await writeDoomConfigValues(repositoryDoomConfigPath(currentRepository.path), selectionEdits(body.changes), {\n scope: 'repository',\n });\n context.configurationChanged?.();\n return Response.json(repositorySettingsView(currentRepository, homeDirectory));\n }\n if (url.pathname === '/value' && request.method === 'PUT') {\n const body = parseWrite(await request.json());\n if (!body)\n return Response.json({ error: 'A save requires a scope, key, value and file hash.' }, { status: 400 });\n const scope = context.scope === 'global' ? 'global' : 'repository';\n if (body.scope !== scope || (scope === 'repository' && body.repoRoot !== currentRepository?.path))\n return Response.json({ error: 'The write targets a different mount.' }, { status: 403 });\n if (\n body.edits.some((edit) => {\n const allowed = configScopeOf(edit.keyPath);\n return allowed !== 'both' && allowed !== scope;\n })\n )\n return Response.json({ error: 'This key cannot be set at this scope.' }, { status: 409 });\n const before = configView(context, []);\n if (before.hashes[scope] !== body.expectedHash)\n return Response.json(\n { error: 'The config changed since it was read.', hash: before.hashes[scope] },\n { status: 409 },\n );\n const target = pathFor(scope, currentRepository?.path ?? '', homeDirectory);\n await writeDoomConfigValues(\n target,\n body.edits.map(({ keyPath, value }) => ({ keyPath, ...(value === null ? {} : { value }) })),\n { scope },\n );\n context.configurationChanged?.();\n return Response.json(\n configView(\n context,\n body.edits.map((edit) => edit.keyPath.join(KEY_SEPARATOR)),\n ),\n );\n }\n return Response.json({ error: 'Configuration route not found.' }, { status: 404 });\n };\n const guarded = async (request: Request): Promise<Response> => {\n try {\n return await dispatch(request);\n } catch (error) {\n return Response.json({ error: describe(error) }, { status: error instanceof SyntaxError ? 400 : 422 });\n }\n };\n return {\n fetch(request) {\n if (request.method === 'GET' || request.method === 'HEAD') return guarded(request);\n const result = writes.then(() => guarded(request));\n writes = result.catch(() => undefined);\n return result;\n },\n close() {\n closed = true;\n },\n };\n },\n};\n"],"mappings":"yRAsBa,EAAuB,CAClC,SAAU,WACV,MAAM,EAAS,CACb,GAAI,EAAQ,QAAU,UAAW,MAAU,MAAM,6DAA6D,EAC9G,GAAM,CAAE,iBAAkB,EACpB,MACJ,EAAQ,QAAU,aAAe,EAAQ,aAAe,EAAQ,cAC5D,CACE,GAAI,EAAQ,YACZ,KAAM,EAAQ,cAAc,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,GAAK,EAAQ,YACzD,KAAM,EAAQ,cACd,OAAQ,EAAQ,eAAe,CAAC,CAAC,KAAM,GAAU,EAAM,KAAO,EAAQ,WAAW,CAAC,EAAE,QAAU,EAChG,EACA,IAAA,GACA,OAAmB,CACvB,GAAGA,EAAAA,oBAAoB,CAAa,EACpC,aAAA,IACA,oBAAqBC,EAAAA,2BACvB,GACI,EAA2B,QAAQ,QAAQ,EAC3C,EAAS,GACP,EAAW,KAAO,IAAwC,CAC9D,GAAI,EAAQ,OAAO,SAAS,KAAK,CAAE,MAAO,gCAAiC,EAAG,CAAE,OAAQ,GAAI,CAAC,EAC7F,IAAM,EAAM,IAAI,IAAI,EAAQ,GAAG,EACzB,EAAoB,EAAW,EACrC,GAAI,EAAI,WAAa,KAAO,EAAQ,SAAW,MAC7C,OAAO,SAAS,KAAKC,EAAAA,WAAW,EAAS,EAAI,aAAa,OAAO,KAAK,CAAC,CAAC,EAC1E,GAAI,EAAI,WAAa,iBAAmB,EAAQ,SAAW,MACzD,OAAO,SAAS,KAAK,CAAE,aAAc,EAAQ,eAAe,GAAK,CAAC,CAAE,CAAC,EACvE,GAAI,EAAI,WAAa,eAAiB,EAAQ,SAAW,MACvD,OAAO,EACH,SAAS,KAAKC,EAAAA,uBAAuB,EAAmB,CAAa,CAAC,EACtE,SAAS,KAAK,CAAE,MAAO,qBAAsB,EAAG,CAAE,OAAQ,GAAI,CAAC,EAErE,GAAI,EAAI,WAAa,WAAa,EAAQ,QAAU,SAAU,CAC5D,GAAI,EAAQ,SAAW,MAAO,OAAO,SAAS,KAAK,EAAU,CAAC,EAC9D,GAAI,EAAQ,SAAW,MAAO,CAC5B,IAAM,EAAgB,MAAM,EAAQ,KAAK,EAgBzC,MAdE,CAACC,EAAAA,SAAS,CAAI,GACb,EAAK,aAAe,IAAA,IAAa,OAAO,EAAK,YAAe,WAC5D,EAAK,eAAiB,IAAA,KACpB,OAAO,EAAK,cAAiB,UAAY,CAAC,OAAO,SAAS,EAAK,YAAY,GAEvE,SAAS,KAAK,CAAE,MAAO,yBAA0B,EAAG,CAAE,OAAQ,GAAI,CAAC,GAC5E,EAAA,oBACE,CACE,GAAI,OAAO,EAAK,YAAe,UAAY,CAAE,WAAY,EAAK,UAAW,EAAI,CAAC,EAC9E,GAAI,OAAO,EAAK,cAAiB,SAAW,CAAE,aAAc,EAAK,YAAa,EAAI,CAAC,CACrF,EACA,CACF,EACA,EAAQ,uBAAuB,EACxB,SAAS,KAAK,EAAU,CAAC,EAClC,CACF,CACA,GAAI,EAAI,WAAa,yBAA2B,EAAQ,SAAW,MAAO,CACxE,IAAM,EAAOC,EAAAA,oBAAoB,MAAM,EAAQ,KAAK,CAAC,EACrD,GAAI,CAAC,EACH,OAAO,SAAS,KAAK,CAAE,MAAO,wDAAyD,EAAG,CAAE,OAAQ,GAAI,CAAC,EAC3G,GAAI,CAAC,GAAqB,EAAK,eAAiB,EAAkB,GAChE,OAAO,SAAS,KAAK,CAAE,MAAO,oCAAqC,EAAG,CAAE,OAAQ,GAAI,CAAC,EACvF,IAAM,EAASF,EAAAA,uBAAuB,EAAmB,CAAa,EACtE,GAAI,EAAO,OAAS,EAAK,aACvB,OAAO,SAAS,KACd,CAAE,MAAO,mDAAoD,KAAM,EAAO,IAAK,EAC/E,CAAE,OAAQ,GAAI,CAChB,EACF,IAAM,EAAUG,EAAAA,yBAAyB,EAAQ,EAAK,OAAO,EAM7D,OALI,EAAgB,SAAS,KAAK,CAAE,MAAO,CAAQ,EAAG,CAAE,OAAQ,GAAI,CAAC,GACrE,MAAMC,EAAAA,sBAAsBC,EAAAA,yBAAyB,EAAkB,IAAI,EAAGC,EAAAA,eAAe,EAAK,OAAO,EAAG,CAC1G,MAAO,YACT,CAAC,EACD,EAAQ,uBAAuB,EACxB,SAAS,KAAKN,EAAAA,uBAAuB,EAAmB,CAAa,CAAC,EAC/E,CACA,GAAI,EAAI,WAAa,UAAY,EAAQ,SAAW,MAAO,CACzD,IAAM,EAAOO,EAAAA,WAAW,MAAM,EAAQ,KAAK,CAAC,EAC5C,GAAI,CAAC,EACH,OAAO,SAAS,KAAK,CAAE,MAAO,oDAAqD,EAAG,CAAE,OAAQ,GAAI,CAAC,EACvG,IAAM,EAAQ,EAAQ,QAAU,SAAW,SAAW,aACtD,GAAI,EAAK,QAAU,GAAU,IAAU,cAAgB,EAAK,WAAa,GAAmB,KAC1F,OAAO,SAAS,KAAK,CAAE,MAAO,sCAAuC,EAAG,CAAE,OAAQ,GAAI,CAAC,EACzF,GACE,EAAK,MAAM,KAAM,GAAS,CACxB,IAAM,EAAUC,EAAAA,cAAc,EAAK,OAAO,EAC1C,OAAO,IAAY,QAAU,IAAY,CAC3C,CAAC,EAED,OAAO,SAAS,KAAK,CAAE,MAAO,uCAAwC,EAAG,CAAE,OAAQ,GAAI,CAAC,EAC1F,IAAM,EAAST,EAAAA,WAAW,EAAS,CAAC,CAAC,EACrC,GAAI,EAAO,OAAO,KAAW,EAAK,aAChC,OAAO,SAAS,KACd,CAAE,MAAO,wCAAyC,KAAM,EAAO,OAAO,EAAO,EAC7E,CAAE,OAAQ,GAAI,CAChB,EACF,IAAM,EAASU,EAAAA,QAAQ,EAAO,GAAmB,MAAQ,GAAI,CAAa,EAO1E,OANA,MAAML,EAAAA,sBACJ,EACA,EAAK,MAAM,KAAK,CAAE,UAAS,YAAa,CAAE,UAAS,GAAI,IAAU,KAAO,CAAC,EAAI,CAAE,OAAM,CAAG,EAAE,EAC1F,CAAE,OAAM,CACV,EACA,EAAQ,uBAAuB,EACxB,SAAS,KACdL,EAAAA,WACE,EACA,EAAK,MAAM,IAAK,GAAS,EAAK,QAAQ,KAAA,GAAkB,CAAC,CAC3D,CACF,CACF,CACA,OAAO,SAAS,KAAK,CAAE,MAAO,gCAAiC,EAAG,CAAE,OAAQ,GAAI,CAAC,CACnF,EACM,EAAU,KAAO,IAAwC,CAC7D,GAAI,CACF,OAAO,MAAM,EAAS,CAAO,CAC/B,OAAS,EAAO,CACd,OAAO,SAAS,KAAK,CAAE,MAAOW,EAAAA,SAAS,CAAK,CAAE,EAAG,CAAE,OAAQ,aAAiB,YAAc,IAAM,GAAI,CAAC,CACvG,CACF,EACA,MAAO,CACL,MAAM,EAAS,CACb,GAAI,EAAQ,SAAW,OAAS,EAAQ,SAAW,OAAQ,OAAO,EAAQ,CAAO,EACjF,IAAM,EAAS,EAAO,SAAW,EAAQ,CAAO,CAAC,EAEjD,MADA,GAAS,EAAO,UAAY,IAAA,EAAS,EAC9B,CACT,EACA,OAAQ,CACN,EAAS,EACX,CACF,CACF,CACF"}
@@ -0,0 +1,2 @@
1
+ import{configScopeOf as e}from"../services/configPolicy/index.mjs";import{repositoryDoomConfigPath as t}from"../services/config/index.mjs";import{writeDoomConfigValues as n}from"../services/configWriter/index.mjs";import{DEFAULT_IMAGE_MAX_DIMENSION as r}from"../services/imageSettings/index.mjs";import{loadPiImageSettings as i,savePiImageSettings as a}from"../services/piConfig/index.mjs";import{configView as o,describe as s,isRecord as c,parseSelectionWrite as l,parseWrite as u,pathFor as d,repositorySettingsView as f,selectionEdits as p,validateSelectionChanges as m}from"../services/settings/index.mjs";const h={basePath:`settings`,start(h){if(h.scope===`session`)throw Error(`Configuration settings require a global or workspace mount.`);let{homeDirectory:g}=h,_=()=>h.scope===`workspace`&&h.workspaceId&&h.workspaceRoot?{id:h.workspaceId,name:h.workspaceRoot.split(`/`).at(-1)??h.workspaceId,path:h.workspaceRoot,active:h.repositories?.().find(e=>e.id===h.workspaceId)?.active??!1}:void 0,v=()=>({...i(g),minDimension:256,maxAllowedDimension:r}),y=Promise.resolve(),b=!1,x=async r=>{if(b)return Response.json({error:`Configuration mount is closed.`},{status:503});let i=new URL(r.url),s=_();if(i.pathname===`/`&&r.method===`GET`)return Response.json(o(h,i.searchParams.getAll(`key`)));if(i.pathname===`/repositories`&&r.method===`GET`)return Response.json({repositories:h.repositories?.()??[]});if(i.pathname===`/repository`&&r.method===`GET`)return s?Response.json(f(s,g)):Response.json({error:`Choose a workspace.`},{status:404});if(i.pathname===`/images`&&h.scope===`global`){if(r.method===`GET`)return Response.json(v());if(r.method===`PUT`){let e=await r.json();return!c(e)||e.autoResize!==void 0&&typeof e.autoResize!=`boolean`||e.maxDimension!==void 0&&(typeof e.maxDimension!=`number`||!Number.isFinite(e.maxDimension))?Response.json({error:`Invalid image settings.`},{status:400}):(a({...typeof e.autoResize==`boolean`?{autoResize:e.autoResize}:{},...typeof e.maxDimension==`number`?{maxDimension:e.maxDimension}:{}},g),h.configurationChanged?.(),Response.json(v()))}}if(i.pathname===`/repository/selection`&&r.method===`PUT`){let e=l(await r.json());if(!e)return Response.json({error:`A selection write needs typed changes and a file hash.`},{status:400});if(!s||e.repositoryId!==s.id)return Response.json({error:`Workspace not found in this mount.`},{status:404});let i=f(s,g);if(i.hash!==e.expectedHash)return Response.json({error:`The repository config changed since it was read.`,hash:i.hash},{status:409});let a=m(i,e.changes);return a?Response.json({error:a},{status:422}):(await n(t(s.path),p(e.changes),{scope:`repository`}),h.configurationChanged?.(),Response.json(f(s,g)))}if(i.pathname===`/value`&&r.method===`PUT`){let t=u(await r.json());if(!t)return Response.json({error:`A save requires a scope, key, value and file hash.`},{status:400});let i=h.scope===`global`?`global`:`repository`;if(t.scope!==i||i===`repository`&&t.repoRoot!==s?.path)return Response.json({error:`The write targets a different mount.`},{status:403});if(t.edits.some(t=>{let n=e(t.keyPath);return n!==`both`&&n!==i}))return Response.json({error:`This key cannot be set at this scope.`},{status:409});let a=o(h,[]);if(a.hashes[i]!==t.expectedHash)return Response.json({error:`The config changed since it was read.`,hash:a.hashes[i]},{status:409});let c=d(i,s?.path??``,g);return await n(c,t.edits.map(({keyPath:e,value:t})=>({keyPath:e,...t===null?{}:{value:t}})),{scope:i}),h.configurationChanged?.(),Response.json(o(h,t.edits.map(e=>e.keyPath.join(`.`))))}return Response.json({error:`Configuration route not found.`},{status:404})},S=async e=>{try{return await x(e)}catch(e){return Response.json({error:s(e)},{status:e instanceof SyntaxError?400:422})}};return{fetch(e){if(e.method===`GET`||e.method===`HEAD`)return S(e);let t=y.then(()=>S(e));return y=t.catch(()=>void 0),t},close(){b=!0}}}};export{h as settingsApi};
2
+ //# sourceMappingURL=settingsApi.mjs.map