@agimon-ai/doompi-config 0.0.1-alpha.2 → 0.0.1-alpha.21

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 (309) hide show
  1. package/README.md +139 -14
  2. package/dist/adapters/atomicJson.cjs +2 -0
  3. package/dist/adapters/atomicJson.cjs.map +1 -0
  4. package/dist/adapters/atomicJson.d.cts +6 -0
  5. package/dist/adapters/atomicJson.d.cts.map +1 -0
  6. package/dist/adapters/atomicJson.d.mts +6 -0
  7. package/dist/adapters/atomicJson.d.mts.map +1 -0
  8. package/dist/adapters/atomicJson.mjs +2 -0
  9. package/dist/adapters/atomicJson.mjs.map +1 -0
  10. package/dist/adapters/config.cjs +2 -0
  11. package/dist/adapters/config.cjs.map +1 -0
  12. package/dist/adapters/config.d.cts +11 -0
  13. package/dist/adapters/config.d.cts.map +1 -0
  14. package/dist/adapters/config.d.mts +11 -0
  15. package/dist/adapters/config.d.mts.map +1 -0
  16. package/dist/adapters/config.mjs +2 -0
  17. package/dist/adapters/config.mjs.map +1 -0
  18. package/dist/adapters/configWriter.cjs +2 -0
  19. package/dist/adapters/configWriter.cjs.map +1 -0
  20. package/dist/adapters/configWriter.d.cts +52 -0
  21. package/dist/adapters/configWriter.d.cts.map +1 -0
  22. package/dist/adapters/configWriter.d.mts +52 -0
  23. package/dist/adapters/configWriter.d.mts.map +1 -0
  24. package/dist/adapters/configWriter.mjs +2 -0
  25. package/dist/adapters/configWriter.mjs.map +1 -0
  26. package/dist/adapters/domains.cjs +2 -0
  27. package/dist/adapters/domains.cjs.map +1 -0
  28. package/dist/adapters/domains.d.cts +25 -0
  29. package/dist/adapters/domains.d.cts.map +1 -0
  30. package/dist/adapters/domains.d.mts +25 -0
  31. package/dist/adapters/domains.d.mts.map +1 -0
  32. package/dist/adapters/domains.mjs +2 -0
  33. package/dist/adapters/domains.mjs.map +1 -0
  34. package/dist/adapters/harnessState.cjs +2 -0
  35. package/dist/adapters/harnessState.cjs.map +1 -0
  36. package/dist/adapters/harnessState.d.cts +50 -0
  37. package/dist/adapters/harnessState.d.cts.map +1 -0
  38. package/dist/adapters/harnessState.d.mts +50 -0
  39. package/dist/adapters/harnessState.d.mts.map +1 -0
  40. package/dist/adapters/harnessState.mjs +2 -0
  41. package/dist/adapters/harnessState.mjs.map +1 -0
  42. package/dist/adapters/harnessStore.cjs +2 -0
  43. package/dist/adapters/harnessStore.cjs.map +1 -0
  44. package/dist/adapters/harnessStore.d.cts +102 -0
  45. package/dist/adapters/harnessStore.d.cts.map +1 -0
  46. package/dist/adapters/harnessStore.d.mts +102 -0
  47. package/dist/adapters/harnessStore.d.mts.map +1 -0
  48. package/dist/adapters/harnessStore.mjs +2 -0
  49. package/dist/adapters/harnessStore.mjs.map +1 -0
  50. package/dist/adapters/init.cjs +178 -0
  51. package/dist/adapters/init.cjs.map +1 -0
  52. package/dist/adapters/init.d.cts +39 -0
  53. package/dist/adapters/init.d.cts.map +1 -0
  54. package/dist/adapters/init.d.mts +39 -0
  55. package/dist/adapters/init.d.mts.map +1 -0
  56. package/dist/adapters/init.mjs +178 -0
  57. package/dist/adapters/init.mjs.map +1 -0
  58. package/dist/adapters/layeredConfig.cjs +2 -0
  59. package/dist/adapters/layeredConfig.cjs.map +1 -0
  60. package/dist/adapters/layeredConfig.d.cts +49 -0
  61. package/dist/adapters/layeredConfig.d.cts.map +1 -0
  62. package/dist/adapters/layeredConfig.d.mts +49 -0
  63. package/dist/adapters/layeredConfig.d.mts.map +1 -0
  64. package/dist/adapters/layeredConfig.mjs +2 -0
  65. package/dist/adapters/layeredConfig.mjs.map +1 -0
  66. package/dist/adapters/majorModes.cjs +2 -0
  67. package/dist/adapters/majorModes.cjs.map +1 -0
  68. package/dist/adapters/majorModes.d.cts +88 -0
  69. package/dist/adapters/majorModes.d.cts.map +1 -0
  70. package/dist/adapters/majorModes.d.mts +88 -0
  71. package/dist/adapters/majorModes.d.mts.map +1 -0
  72. package/dist/adapters/majorModes.mjs +2 -0
  73. package/dist/adapters/majorModes.mjs.map +1 -0
  74. package/dist/adapters/pi/configExtension.cjs +2 -0
  75. package/dist/adapters/pi/configExtension.cjs.map +1 -0
  76. package/dist/adapters/pi/configExtension.d.cts +8 -0
  77. package/dist/adapters/pi/configExtension.d.cts.map +1 -0
  78. package/dist/adapters/pi/configExtension.d.mts +8 -0
  79. package/dist/adapters/pi/configExtension.d.mts.map +1 -0
  80. package/dist/adapters/pi/configExtension.mjs +2 -0
  81. package/dist/adapters/pi/configExtension.mjs.map +1 -0
  82. package/dist/adapters/pi/doomConfigExtension.cjs +2 -0
  83. package/dist/adapters/pi/doomConfigExtension.cjs.map +1 -0
  84. package/dist/adapters/pi/doomConfigExtension.d.cts +8 -0
  85. package/dist/adapters/pi/doomConfigExtension.d.cts.map +1 -0
  86. package/dist/adapters/pi/doomConfigExtension.d.mts +8 -0
  87. package/dist/adapters/pi/doomConfigExtension.d.mts.map +1 -0
  88. package/dist/adapters/pi/doomConfigExtension.mjs +2 -0
  89. package/dist/adapters/pi/doomConfigExtension.mjs.map +1 -0
  90. package/dist/adapters/pi/helpContribution.cjs +2 -0
  91. package/dist/adapters/pi/helpContribution.cjs.map +1 -0
  92. package/dist/adapters/pi/helpContribution.mjs +2 -0
  93. package/dist/adapters/pi/helpContribution.mjs.map +1 -0
  94. package/dist/adapters/pi/piContext.cjs +2 -0
  95. package/dist/adapters/pi/piContext.cjs.map +1 -0
  96. package/dist/adapters/pi/piContext.d.cts +20 -0
  97. package/dist/adapters/pi/piContext.d.cts.map +1 -0
  98. package/dist/adapters/pi/piContext.d.mts +20 -0
  99. package/dist/adapters/pi/piContext.d.mts.map +1 -0
  100. package/dist/adapters/pi/piContext.mjs +2 -0
  101. package/dist/adapters/pi/piContext.mjs.map +1 -0
  102. package/dist/adapters/piConfig.cjs +2 -0
  103. package/dist/adapters/piConfig.cjs.map +1 -0
  104. package/dist/adapters/piConfig.d.cts +8 -0
  105. package/dist/adapters/piConfig.d.cts.map +1 -0
  106. package/dist/adapters/piConfig.d.mts +8 -0
  107. package/dist/adapters/piConfig.d.mts.map +1 -0
  108. package/dist/adapters/piConfig.mjs +2 -0
  109. package/dist/adapters/piConfig.mjs.map +1 -0
  110. package/dist/adapters/pluginCatalog.cjs +2 -0
  111. package/dist/adapters/pluginCatalog.cjs.map +1 -0
  112. package/dist/adapters/pluginCatalog.d.cts +12 -0
  113. package/dist/adapters/pluginCatalog.d.cts.map +1 -0
  114. package/dist/adapters/pluginCatalog.d.mts +12 -0
  115. package/dist/adapters/pluginCatalog.d.mts.map +1 -0
  116. package/dist/adapters/pluginCatalog.mjs +2 -0
  117. package/dist/adapters/pluginCatalog.mjs.map +1 -0
  118. package/dist/adapters/profiles.cjs +4 -0
  119. package/dist/adapters/profiles.cjs.map +1 -0
  120. package/dist/adapters/profiles.d.cts +36 -0
  121. package/dist/adapters/profiles.d.cts.map +1 -0
  122. package/dist/adapters/profiles.d.mts +36 -0
  123. package/dist/adapters/profiles.d.mts.map +1 -0
  124. package/dist/adapters/profiles.mjs +4 -0
  125. package/dist/adapters/profiles.mjs.map +1 -0
  126. package/dist/atomicJson.cjs +1 -2
  127. package/dist/atomicJson.d.cts +2 -6
  128. package/dist/atomicJson.d.mts +2 -6
  129. package/dist/atomicJson.mjs +1 -2
  130. package/dist/config/piConfig.cjs +1 -2
  131. package/dist/config/piConfig.d.cts +2 -7
  132. package/dist/config/piConfig.d.mts +2 -7
  133. package/dist/config/piConfig.mjs +1 -2
  134. package/dist/config/schema.d.cts +2 -33
  135. package/dist/config/schema.d.mts +2 -33
  136. package/dist/config.cjs +1 -2
  137. package/dist/config.d.cts +3 -24
  138. package/dist/config.d.mts +3 -24
  139. package/dist/config.mjs +1 -2
  140. package/dist/configWriter.cjs +1 -2
  141. package/dist/configWriter.d.cts +2 -52
  142. package/dist/configWriter.d.mts +2 -52
  143. package/dist/configWriter.mjs +1 -2
  144. package/dist/container/doomConfigContainer.cjs +2 -0
  145. package/dist/container/doomConfigContainer.cjs.map +1 -0
  146. package/dist/container/doomConfigContainer.d.cts +12 -0
  147. package/dist/container/doomConfigContainer.d.cts.map +1 -0
  148. package/dist/container/doomConfigContainer.d.mts +12 -0
  149. package/dist/container/doomConfigContainer.d.mts.map +1 -0
  150. package/dist/container/doomConfigContainer.mjs +2 -0
  151. package/dist/container/doomConfigContainer.mjs.map +1 -0
  152. package/dist/container.cjs +1 -2
  153. package/dist/container.d.cts +2 -12
  154. package/dist/container.d.mts +2 -12
  155. package/dist/container.mjs +1 -2
  156. package/dist/domains.cjs +1 -2
  157. package/dist/domains.d.cts +6 -77
  158. package/dist/domains.d.mts +6 -77
  159. package/dist/domains.mjs +1 -2
  160. package/dist/extensions/doom.cjs +1 -2
  161. package/dist/extensions/doom.d.cts +2 -8
  162. package/dist/extensions/doom.d.mts +2 -8
  163. package/dist/extensions/doom.mjs +1 -2
  164. package/dist/extensions/pi.cjs +1 -2
  165. package/dist/extensions/pi.d.cts +2 -8
  166. package/dist/extensions/pi.d.mts +2 -8
  167. package/dist/extensions/pi.mjs +1 -2
  168. package/dist/harnessState.cjs +1 -2
  169. package/dist/harnessState.d.cts +2 -50
  170. package/dist/harnessState.d.mts +2 -50
  171. package/dist/harnessState.mjs +1 -2
  172. package/dist/harnessStore.cjs +1 -2
  173. package/dist/harnessStore.d.cts +2 -102
  174. package/dist/harnessStore.d.mts +2 -102
  175. package/dist/harnessStore.mjs +1 -2
  176. package/dist/index.cjs +1 -1
  177. package/dist/index.d.cts +20 -16
  178. package/dist/index.d.mts +20 -16
  179. package/dist/index.mjs +1 -1
  180. package/dist/init.cjs +1 -76
  181. package/dist/init.d.cts +2 -33
  182. package/dist/init.d.mts +2 -33
  183. package/dist/init.mjs +1 -76
  184. package/dist/layeredConfig.cjs +1 -2
  185. package/dist/layeredConfig.d.cts +2 -49
  186. package/dist/layeredConfig.d.mts +2 -49
  187. package/dist/layeredConfig.mjs +1 -2
  188. package/dist/majorModes.cjs +1 -2
  189. package/dist/majorModes.d.cts +2 -75
  190. package/dist/majorModes.d.mts +2 -75
  191. package/dist/majorModes.mjs +1 -2
  192. package/dist/pi.cjs +1 -1
  193. package/dist/pi.d.cts +1 -1
  194. package/dist/pi.d.mts +1 -1
  195. package/dist/pi.mjs +1 -1
  196. package/dist/piContext.cjs +1 -2
  197. package/dist/piContext.d.cts +2 -19
  198. package/dist/piContext.d.mts +2 -19
  199. package/dist/piContext.mjs +1 -2
  200. package/dist/profiles.cjs +1 -4
  201. package/dist/profiles.d.cts +2 -35
  202. package/dist/profiles.d.mts +2 -35
  203. package/dist/profiles.mjs +1 -4
  204. package/dist/schemas/config/schema.d.cts +33 -0
  205. package/dist/schemas/config/schema.d.cts.map +1 -0
  206. package/dist/schemas/config/schema.d.mts +33 -0
  207. package/dist/schemas/config/schema.d.mts.map +1 -0
  208. package/dist/services/configPolicy.cjs +2 -0
  209. package/dist/services/configPolicy.cjs.map +1 -0
  210. package/dist/services/configPolicy.d.cts +19 -0
  211. package/dist/services/configPolicy.d.cts.map +1 -0
  212. package/dist/services/configPolicy.d.mts +19 -0
  213. package/dist/services/configPolicy.d.mts.map +1 -0
  214. package/dist/services/configPolicy.mjs +2 -0
  215. package/dist/services/configPolicy.mjs.map +1 -0
  216. package/dist/services/domains.cjs +2 -0
  217. package/dist/services/domains.cjs.map +1 -0
  218. package/dist/services/domains.d.cts +12 -0
  219. package/dist/services/domains.d.cts.map +1 -0
  220. package/dist/services/domains.d.mts +12 -0
  221. package/dist/services/domains.d.mts.map +1 -0
  222. package/dist/services/domains.mjs +2 -0
  223. package/dist/services/domains.mjs.map +1 -0
  224. package/dist/types/config.cjs +2 -0
  225. package/dist/types/config.cjs.map +1 -0
  226. package/dist/types/config.d.cts +136 -0
  227. package/dist/types/config.d.cts.map +1 -0
  228. package/dist/types/config.d.mts +136 -0
  229. package/dist/types/config.d.mts.map +1 -0
  230. package/dist/types/config.mjs +2 -0
  231. package/dist/types/config.mjs.map +1 -0
  232. package/dist/types/domains.d.cts +89 -0
  233. package/dist/types/domains.d.cts.map +1 -0
  234. package/dist/types/domains.d.mts +89 -0
  235. package/dist/types/domains.d.mts.map +1 -0
  236. package/dist/types.cjs +1 -2
  237. package/dist/types.d.cts +2 -132
  238. package/dist/types.d.mts +2 -132
  239. package/dist/types.mjs +1 -2
  240. package/llms.txt +9 -0
  241. package/package.json +18 -6
  242. package/skills/doom-pi-config/SKILL.md +6 -3
  243. package/skills/doom-pi-config/references/config-contract.md +123 -8
  244. package/dist/atomicJson.cjs.map +0 -1
  245. package/dist/atomicJson.d.cts.map +0 -1
  246. package/dist/atomicJson.d.mts.map +0 -1
  247. package/dist/atomicJson.mjs.map +0 -1
  248. package/dist/config/piConfig.cjs.map +0 -1
  249. package/dist/config/piConfig.d.cts.map +0 -1
  250. package/dist/config/piConfig.d.mts.map +0 -1
  251. package/dist/config/piConfig.mjs.map +0 -1
  252. package/dist/config/schema.d.cts.map +0 -1
  253. package/dist/config/schema.d.mts.map +0 -1
  254. package/dist/config.cjs.map +0 -1
  255. package/dist/config.d.cts.map +0 -1
  256. package/dist/config.d.mts.map +0 -1
  257. package/dist/config.mjs.map +0 -1
  258. package/dist/configWriter.cjs.map +0 -1
  259. package/dist/configWriter.d.cts.map +0 -1
  260. package/dist/configWriter.d.mts.map +0 -1
  261. package/dist/configWriter.mjs.map +0 -1
  262. package/dist/container.cjs.map +0 -1
  263. package/dist/container.d.cts.map +0 -1
  264. package/dist/container.d.mts.map +0 -1
  265. package/dist/container.mjs.map +0 -1
  266. package/dist/domains.cjs.map +0 -1
  267. package/dist/domains.d.cts.map +0 -1
  268. package/dist/domains.d.mts.map +0 -1
  269. package/dist/domains.mjs.map +0 -1
  270. package/dist/extensions/doom.cjs.map +0 -1
  271. package/dist/extensions/doom.d.cts.map +0 -1
  272. package/dist/extensions/doom.d.mts.map +0 -1
  273. package/dist/extensions/doom.mjs.map +0 -1
  274. package/dist/extensions/pi.cjs.map +0 -1
  275. package/dist/extensions/pi.d.cts.map +0 -1
  276. package/dist/extensions/pi.d.mts.map +0 -1
  277. package/dist/extensions/pi.mjs.map +0 -1
  278. package/dist/harnessState.cjs.map +0 -1
  279. package/dist/harnessState.d.cts.map +0 -1
  280. package/dist/harnessState.d.mts.map +0 -1
  281. package/dist/harnessState.mjs.map +0 -1
  282. package/dist/harnessStore.cjs.map +0 -1
  283. package/dist/harnessStore.d.cts.map +0 -1
  284. package/dist/harnessStore.d.mts.map +0 -1
  285. package/dist/harnessStore.mjs.map +0 -1
  286. package/dist/init.cjs.map +0 -1
  287. package/dist/init.d.cts.map +0 -1
  288. package/dist/init.d.mts.map +0 -1
  289. package/dist/init.mjs.map +0 -1
  290. package/dist/layeredConfig.cjs.map +0 -1
  291. package/dist/layeredConfig.d.cts.map +0 -1
  292. package/dist/layeredConfig.d.mts.map +0 -1
  293. package/dist/layeredConfig.mjs.map +0 -1
  294. package/dist/majorModes.cjs.map +0 -1
  295. package/dist/majorModes.d.cts.map +0 -1
  296. package/dist/majorModes.d.mts.map +0 -1
  297. package/dist/majorModes.mjs.map +0 -1
  298. package/dist/piContext.cjs.map +0 -1
  299. package/dist/piContext.d.cts.map +0 -1
  300. package/dist/piContext.d.mts.map +0 -1
  301. package/dist/piContext.mjs.map +0 -1
  302. package/dist/profiles.cjs.map +0 -1
  303. package/dist/profiles.d.cts.map +0 -1
  304. package/dist/profiles.d.mts.map +0 -1
  305. package/dist/profiles.mjs.map +0 -1
  306. package/dist/types.cjs.map +0 -1
  307. package/dist/types.d.cts.map +0 -1
  308. package/dist/types.d.mts.map +0 -1
  309. package/dist/types.mjs.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"layeredConfig.d.mts","names":[],"sources":["../src/layeredConfig.ts"],"mappings":";;cAOa;;UAKI,iBAAiB;;EAEhC;;;;;;;;;;EAUA;;EAEA;EACA,UAAU;;;;;;;;;;;iBAYI,qBACd,kBACA,kBACA,yBACC;EAAQ;EAAkB;;iBAQb,sBAAsB,WACpC,kBACA,kBACA,yBACC,MAAM,iBAAiB;;;;;;;;;iBAwBV,kBAAkB,WAAW,QAC3C,SAAS,cAAc,iBAAiB,aACxC,SAAS,UAAU,cAAc,eAAe,sBAC/C,eAAe;EAAW"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"layeredConfig.mjs","names":["parseYaml"],"sources":["../src/layeredConfig.ts"],"sourcesContent":["import fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport { parse as parseYaml } from 'yaml';\nimport { globalDoomConfigDirectory } from './config.ts';\n\n/** Repository-local doom-pi configuration directory, committed to git. */\nexport const DOOM_DIR = '.doom';\n\nconst TEXT_ENCODING = 'utf8';\n\n/** One `.doom` document plus the root its relative paths resolve against. */\nexport interface DoomConfigSource<TDocument> {\n /** Absolute path of the file the document was read from. */\n filePath: string;\n /**\n * Where relative paths inside this document point.\n *\n * A repository document resolves against the repository root, so `plugins/x`\n * keeps meaning the same thing it always has. A global document resolves\n * against the global `.doom` directory, so it can name plugins and extensions\n * that live beside it in `~/.pi/.doom` rather than inside whichever\n * repository happens to be open.\n */\n baseDirectory: string;\n /** Raw file contents, for callers that cache parsed results by source text. */\n text: string;\n document: TDocument;\n}\n\n/**\n * Reads one named `.doom` document from the global and repository config\n * directories, lowest precedence first.\n *\n * A missing or empty file contributes nothing, so either location on its own is\n * a complete configuration. Documents are deliberately returned unmerged:\n * merging is by name, and only the caller knows what a name means in its own\n * document, so each one folds the sources itself with the repository last.\n */\nexport function doomConfigCandidates(\n fileName: string,\n repoRoot: string,\n homeDirectory: string = os.homedir(),\n): Array<{ filePath: string; baseDirectory: string }> {\n const globalDirectory = globalDoomConfigDirectory(homeDirectory);\n return [\n { filePath: path.join(globalDirectory, fileName), baseDirectory: globalDirectory },\n { filePath: path.join(repoRoot, DOOM_DIR, fileName), baseDirectory: repoRoot },\n ];\n}\n\nexport function readDoomConfigSources<TDocument>(\n fileName: string,\n repoRoot: string,\n homeDirectory: string = os.homedir(),\n): Array<DoomConfigSource<TDocument>> {\n const candidates = doomConfigCandidates(fileName, repoRoot, homeDirectory);\n\n const sources: Array<DoomConfigSource<TDocument>> = [];\n for (const candidate of candidates) {\n if (!fs.existsSync(candidate.filePath)) continue;\n const text = fs.readFileSync(candidate.filePath, TEXT_ENCODING);\n const document = parseYaml(text) as TDocument | null | undefined;\n // An empty file parses to null and is treated as an absent one, so a seeded\n // placeholder never has to be deleted to get out of the way.\n if (document === null || document === undefined) continue;\n sources.push({ ...candidate, text, document });\n }\n return sources;\n}\n\n/**\n * Merges same-named records across sources, tagging each entry with the base\n * directory of the document that supplied it.\n *\n * Later sources win outright rather than being deep-merged: a repository that\n * redefines a name is replacing it, and a half-inherited definition whose paths\n * straddle two roots would be impossible to resolve.\n */\nexport function mergeNamedSources<TDocument, TEntry>(\n sources: ReadonlyArray<DoomConfigSource<TDocument>>,\n select: (document: TDocument) => Record<string, TEntry> | undefined,\n): Record<string, TEntry & { baseDirectory: string }> {\n const merged: Record<string, TEntry & { baseDirectory: string }> = {};\n for (const source of sources) {\n for (const [name, entry] of Object.entries(select(source.document) ?? {})) {\n merged[name] = { ...entry, baseDirectory: source.baseDirectory };\n }\n }\n return merged;\n}\n"],"mappings":"6JAOA,MAAa,EAAW,QAgCxB,SAAgB,EACd,EACA,EACA,EAAwB,EAAG,QAAQ,EACiB,CACpD,IAAM,EAAkB,EAA0B,CAAa,EAC/D,MAAO,CACL,CAAE,SAAU,EAAK,KAAK,EAAiB,CAAQ,EAAG,cAAe,CAAgB,EACjF,CAAE,SAAU,EAAK,KAAK,EAAU,EAAU,CAAQ,EAAG,cAAe,CAAS,CAC/E,CACF,CAEA,SAAgB,EACd,EACA,EACA,EAAwB,EAAG,QAAQ,EACC,CACpC,IAAM,EAAa,EAAqB,EAAU,EAAU,CAAa,EAEnE,EAA8C,CAAC,EACrD,IAAK,IAAM,KAAa,EAAY,CAClC,GAAI,CAAC,EAAG,WAAW,EAAU,QAAQ,EAAG,SACxC,IAAM,EAAO,EAAG,aAAa,EAAU,SAAU,MAAa,EACxD,EAAWA,EAAU,CAAI,EAG3B,GAAa,MACjB,EAAQ,KAAK,CAAE,GAAG,EAAW,OAAM,UAAS,CAAC,CAC/C,CACA,OAAO,CACT,CAUA,SAAgB,EACd,EACA,EACoD,CACpD,IAAM,EAA6D,CAAC,EACpE,IAAK,IAAM,KAAU,EACnB,IAAK,GAAM,CAAC,EAAM,KAAU,OAAO,QAAQ,EAAO,EAAO,QAAQ,GAAK,CAAC,CAAC,EACtE,EAAO,GAAQ,CAAE,GAAG,EAAO,cAAe,EAAO,aAAc,EAGnE,OAAO,CACT"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"majorModes.cjs","names":["path","DOOM_DIR","os","readDoomConfigSources"],"sources":["../src/majorModes.ts"],"sourcesContent":["import os from 'node:os';\nimport path from 'node:path';\nimport { DOOM_DIR, readDoomConfigSources } from './layeredConfig.ts';\nimport type { PlanningThinkingLevel } from './types.ts';\n\nexport interface LayerPackage {\n name: string;\n optional?: boolean;\n}\n\nexport interface SubagentLayerModelConfig {\n model: string;\n thinking?: PlanningThinkingLevel;\n}\n\nexport interface SubagentLayerConfig {\n models?: SubagentLayerModelConfig[];\n excludeTools?: string[];\n}\n\nexport interface LayerCustomizationConfig {\n subagents?: SubagentLayerConfig;\n}\n\nexport interface LayerDefinition {\n extensions?: string[];\n /**\n * npm specifiers, or paths relative to the config that declares the layer.\n * A path (`./`, `../`, or absolute) is resolved against the repository root\n * for `.doom/modes.yaml` and against the global `.doom` directory for\n * `~/.pi/.doom/modes.yaml`, which is how an extension that was never\n * published to npm gets loaded.\n */\n packages?: Array<string | LayerPackage>;\n hookGroups?: string[];\n config?: LayerCustomizationConfig;\n}\n\n/** A layer plus the root its relative package paths resolve against. */\nexport interface ResolvedLayerDefinition extends LayerDefinition {\n baseDirectory: string;\n}\n\nexport interface MajorModesConfig {\n layers: Record<string, ResolvedLayerDefinition>;\n /** The mode selected when neither a flag nor the environment names one. */\n defaultMajorMode: string;\n /** Named major modes, each one a set of layer names. */\n majorMode: Record<string, string[]>;\n}\n\nexport interface LayerResolvers {\n ownEntry: (name: string) => string;\n packageEntry: (name: string) => string;\n optionalPackageEntry: (name: string) => string | undefined;\n /** Resolves a path-style layer package against the config that declared it. */\n localEntry: (specifier: string, baseDirectory: string) => string | undefined;\n}\n\ninterface ModesDocument {\n layers?: Record<string, unknown>;\n defaultMajorMode?: unknown;\n majorMode?: Record<string, string[]>;\n}\n\nconst MODES_FILE = 'modes.yaml';\nconst FALLBACK_MAJOR_MODE = 'copilot';\nconst MAJOR_MODES_RELATIVE_PATH = path.join(DOOM_DIR, MODES_FILE);\nconst RELATIVE_PREFIXES = ['./', '../'] as const;\n\n/**\n * Whether a layer package names a path rather than an installed package.\n *\n * The same rule Node applies to import specifiers, so a bare name is always an\n * npm package and a path always looks like one.\n */\nexport function isLocalPackageSpecifier(specifier: string): boolean {\n return path.isAbsolute(specifier) || RELATIVE_PREFIXES.some((prefix) => specifier.startsWith(prefix));\n}\nconst LAYER_CONFIG_KEYS = ['subagents'] as const;\nconst SUBAGENT_CONFIG_KEYS = ['models', 'excludeTools'] as const;\nconst SUBAGENT_MODEL_KEYS = ['model', 'thinking'] as const;\nconst THINKING_VALUES = new Set<PlanningThinkingLevel>(['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max']);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction assertKnownKeys(value: Record<string, unknown>, keys: readonly string[], location: string): void {\n const unsupported = Object.keys(value).filter((key) => !keys.includes(key));\n if (unsupported.length > 0) {\n throw new Error(`${location} has unsupported field(s): ${unsupported.join(', ')}`);\n }\n}\n\nfunction parseLayerCustomization(name: string, value: unknown): LayerCustomizationConfig | undefined {\n if (value === undefined) return undefined;\n const location = `Layer \"${name}\" config in ${MAJOR_MODES_RELATIVE_PATH}`;\n if (!isRecord(value)) throw new Error(`${location} must be a mapping`);\n assertKnownKeys(value, LAYER_CONFIG_KEYS, location);\n if (value.subagents === undefined) return {};\n if (!isRecord(value.subagents)) throw new Error(`${location}.subagents must be a mapping`);\n assertKnownKeys(value.subagents, SUBAGENT_CONFIG_KEYS, `${location}.subagents`);\n const hasModels = Object.hasOwn(value.subagents, 'models');\n const hasExcludeTools = Object.hasOwn(value.subagents, 'excludeTools');\n if (!hasModels && !hasExcludeTools) {\n throw new Error(`${location}.subagents must define models or excludeTools`);\n }\n\n let models: SubagentLayerModelConfig[] | undefined;\n if (hasModels) {\n if (!Array.isArray(value.subagents.models) || value.subagents.models.length === 0) {\n throw new Error(`${location}.subagents.models must be a non-empty array`);\n }\n models = value.subagents.models.map((entry, index): SubagentLayerModelConfig => {\n const entryLocation = `${location}.subagents.models[${index}]`;\n if (!isRecord(entry)) throw new Error(`${entryLocation} must be a mapping`);\n assertKnownKeys(entry, SUBAGENT_MODEL_KEYS, entryLocation);\n if (typeof entry.model !== 'string' || !entry.model.trim()) {\n throw new Error(`${entryLocation}.model must be a non-empty string`);\n }\n if (\n entry.thinking !== undefined &&\n (typeof entry.thinking !== 'string' || !THINKING_VALUES.has(entry.thinking as PlanningThinkingLevel))\n ) {\n throw new Error(`${entryLocation}.thinking must be one of: ${[...THINKING_VALUES].join(', ')}`);\n }\n return {\n model: entry.model.trim(),\n ...(entry.thinking ? { thinking: entry.thinking as PlanningThinkingLevel } : {}),\n };\n });\n }\n\n let normalizedExcludeTools: string[] | undefined;\n if (hasExcludeTools) {\n const excludeTools = value.subagents.excludeTools;\n if (!Array.isArray(excludeTools) || excludeTools.length === 0) {\n throw new Error(`${location}.subagents.excludeTools must be a non-empty array`);\n }\n normalizedExcludeTools = [\n ...new Set(\n excludeTools.map((entry, index) => {\n const entryLocation = `${location}.subagents.excludeTools[${index}]`;\n if (typeof entry !== 'string' || !entry.trim()) {\n throw new Error(`${entryLocation} must be a non-empty string`);\n }\n return entry.trim();\n }),\n ),\n ];\n }\n\n return {\n subagents: {\n ...(models ? { models } : {}),\n ...(normalizedExcludeTools ? { excludeTools: normalizedExcludeTools } : {}),\n },\n };\n}\n\nfunction parseDefaultMajorMode(value: unknown): string {\n if (typeof value !== 'string' || !value.trim()) {\n throw new Error(`defaultMajorMode in ${MAJOR_MODES_RELATIVE_PATH} must be a non-empty string`);\n }\n return value.trim();\n}\n\nfunction parseLayer(name: string, definition: unknown): LayerDefinition {\n if (!isRecord(definition)) throw new Error(`Layer \"${name}\" in ${MAJOR_MODES_RELATIVE_PATH} must be a mapping`);\n if ('targets' in definition) {\n throw new Error(\n `Layer \"${name}\" in ${MAJOR_MODES_RELATIVE_PATH} uses removed field \"targets\"; select availability through major modes`,\n );\n }\n const config = parseLayerCustomization(name, definition.config);\n return (config === undefined ? definition : { ...definition, config }) as LayerDefinition;\n}\n\n/**\n * Reads layers and major modes from the global and repository configs.\n *\n * The repository is read last, so it replaces a global layer or major mode of\n * the same name. Layers keep the root they were declared under so that a\n * global layer naming `./extensions/x` still points beside the global config\n * once it is loaded from inside some other repository.\n */\nexport function loadMajorModesConfig(repoRoot: string, homeDirectory: string = os.homedir()): MajorModesConfig {\n const sources = readDoomConfigSources<ModesDocument>(MODES_FILE, repoRoot, homeDirectory);\n const layers: Record<string, ResolvedLayerDefinition> = {};\n const majorMode: Record<string, string[]> = {};\n let defaultMajorMode = FALLBACK_MAJOR_MODE;\n let hasConfiguredDefault = false;\n for (const source of sources) {\n for (const [name, definition] of Object.entries(source.document.layers ?? {})) {\n layers[name] = { ...parseLayer(name, definition), baseDirectory: source.baseDirectory };\n }\n if (Object.hasOwn(source.document, 'defaultMajorMode')) {\n defaultMajorMode = parseDefaultMajorMode(source.document.defaultMajorMode);\n hasConfiguredDefault = true;\n }\n Object.assign(majorMode, source.document.majorMode ?? {});\n }\n\n for (const [modeName, names] of Object.entries(majorMode)) {\n for (const name of names) {\n if (!layers[name]) {\n throw new Error(`Unknown layer \"${name}\" in majorMode.${modeName} of ${MAJOR_MODES_RELATIVE_PATH}`);\n }\n }\n }\n if (hasConfiguredDefault && !Object.hasOwn(majorMode, defaultMajorMode)) {\n throw new Error(`Unknown default major mode \"${defaultMajorMode}\" in ${MAJOR_MODES_RELATIVE_PATH}`);\n }\n return { layers, defaultMajorMode, majorMode };\n}\n\n/** Merges selected layer customization in order, with later models winning and exclusions unioned. */\nexport function resolveLayerCustomization(config: MajorModesConfig, names: string[]): LayerCustomizationConfig {\n let subagents: SubagentLayerConfig | undefined;\n const excludeTools = new Set<string>();\n let hasExcludeTools = false;\n for (const name of names) {\n const layer = config.layers[name];\n if (!layer) throw new Error(`Unknown layer: ${name}`);\n const next = layer.config?.subagents;\n if (!next) continue;\n if (next.excludeTools !== undefined) {\n hasExcludeTools = true;\n for (const tool of next.excludeTools) excludeTools.add(tool);\n }\n subagents = {\n ...subagents,\n ...(next.models ? { models: next.models.map((model) => ({ ...model })) } : {}),\n ...(hasExcludeTools ? { excludeTools: [...excludeTools] } : {}),\n };\n }\n return subagents ? { subagents } : {};\n}\n\n/** Resolves one named major mode into its configured layer components. */\nexport function resolveLayers(config: MajorModesConfig, majorMode: string): string[] {\n if (!Object.hasOwn(config.majorMode, majorMode)) {\n throw new Error(\n `Unknown major mode: ${majorMode}. Known major modes: ${Object.keys(config.majorMode).sort().join(', ')}`,\n );\n }\n return [...config.majorMode[majorMode]!];\n}\n\n/** Resolves one layer's extension and package entries to absolute paths. */\nexport function layerEntries(config: MajorModesConfig, name: string, resolvers: LayerResolvers): string[] {\n const layer = config.layers[name];\n if (!layer) throw new Error(`Unknown layer: ${name}`);\n const entries: string[] = [];\n for (const entry of layer.extensions ?? []) entries.push(resolvers.ownEntry(entry));\n for (const entry of layer.packages ?? []) {\n const specifier = typeof entry === 'string' ? entry : entry.name;\n const optional = typeof entry === 'string' ? false : entry.optional === true;\n if (isLocalPackageSpecifier(specifier)) {\n const resolved = resolvers.localEntry(specifier, layer.baseDirectory);\n if (resolved) entries.push(resolved);\n else if (!optional) {\n throw new Error(\n `Layer \"${name}\" package \"${specifier}\" does not resolve under ${layer.baseDirectory}. ` +\n 'Point it at an extension file, or a directory whose package.json names one.',\n );\n }\n continue;\n }\n if (optional) {\n const resolved = resolvers.optionalPackageEntry(specifier);\n if (resolved) entries.push(resolved);\n continue;\n }\n entries.push(resolvers.packageEntry(specifier));\n }\n return entries;\n}\n\n/** Hook group ids contributed by the selected layers, deduped. */\nexport function layerHookGroups(config: MajorModesConfig, names: string[]): string[] {\n const groups = new Set<string>();\n for (const name of names) {\n for (const group of config.layers[name]?.hookGroups ?? []) groups.add(group);\n }\n return [...groups];\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"majorModes.d.cts","names":[],"sources":["../src/majorModes.ts"],"mappings":";;UAKiB;EACf;EACA;;UAGe;EACf;EACA,WAAW;;UAGI;EACf,SAAS;EACT;;UAGe;EACf,YAAY;;UAGG;EACf;;;;;;;;EAQA,WAAW,eAAe;EAC1B;EACA,SAAS;;;UAIM,gCAAgC;EAC/C;;UAGe;EACf,QAAQ,eAAe;;EAEvB;;EAEA,WAAW;;UAGI;EACf,WAAW;EACX,eAAe;EACf,uBAAuB;;EAEvB,aAAa,mBAAmB;;;;;;;;iBAoBlB,wBAAwB;;;;;;;;;iBA+GxB,qBAAqB,kBAAkB,yBAAuC;;iBA+B9E,0BAA0B,QAAQ,kBAAkB,kBAAkB;;iBAuBtE,cAAc,QAAQ,kBAAkB;;iBAUxC,aAAa,QAAQ,kBAAkB,cAAc,WAAW;;iBA8BhE,gBAAgB,QAAQ,kBAAkB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"majorModes.d.mts","names":[],"sources":["../src/majorModes.ts"],"mappings":";;UAKiB;EACf;EACA;;UAGe;EACf;EACA,WAAW;;UAGI;EACf,SAAS;EACT;;UAGe;EACf,YAAY;;UAGG;EACf;;;;;;;;EAQA,WAAW,eAAe;EAC1B;EACA,SAAS;;;UAIM,gCAAgC;EAC/C;;UAGe;EACf,QAAQ,eAAe;;EAEvB;;EAEA,WAAW;;UAGI;EACf,WAAW;EACX,eAAe;EACf,uBAAuB;;EAEvB,aAAa,mBAAmB;;;;;;;;iBAoBlB,wBAAwB;;;;;;;;;iBA+GxB,qBAAqB,kBAAkB,yBAAuC;;iBA+B9E,0BAA0B,QAAQ,kBAAkB,kBAAkB;;iBAuBtE,cAAc,QAAQ,kBAAkB;;iBAUxC,aAAa,QAAQ,kBAAkB,cAAc,WAAW;;iBA8BhE,gBAAgB,QAAQ,kBAAkB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"majorModes.mjs","names":[],"sources":["../src/majorModes.ts"],"sourcesContent":["import os from 'node:os';\nimport path from 'node:path';\nimport { DOOM_DIR, readDoomConfigSources } from './layeredConfig.ts';\nimport type { PlanningThinkingLevel } from './types.ts';\n\nexport interface LayerPackage {\n name: string;\n optional?: boolean;\n}\n\nexport interface SubagentLayerModelConfig {\n model: string;\n thinking?: PlanningThinkingLevel;\n}\n\nexport interface SubagentLayerConfig {\n models?: SubagentLayerModelConfig[];\n excludeTools?: string[];\n}\n\nexport interface LayerCustomizationConfig {\n subagents?: SubagentLayerConfig;\n}\n\nexport interface LayerDefinition {\n extensions?: string[];\n /**\n * npm specifiers, or paths relative to the config that declares the layer.\n * A path (`./`, `../`, or absolute) is resolved against the repository root\n * for `.doom/modes.yaml` and against the global `.doom` directory for\n * `~/.pi/.doom/modes.yaml`, which is how an extension that was never\n * published to npm gets loaded.\n */\n packages?: Array<string | LayerPackage>;\n hookGroups?: string[];\n config?: LayerCustomizationConfig;\n}\n\n/** A layer plus the root its relative package paths resolve against. */\nexport interface ResolvedLayerDefinition extends LayerDefinition {\n baseDirectory: string;\n}\n\nexport interface MajorModesConfig {\n layers: Record<string, ResolvedLayerDefinition>;\n /** The mode selected when neither a flag nor the environment names one. */\n defaultMajorMode: string;\n /** Named major modes, each one a set of layer names. */\n majorMode: Record<string, string[]>;\n}\n\nexport interface LayerResolvers {\n ownEntry: (name: string) => string;\n packageEntry: (name: string) => string;\n optionalPackageEntry: (name: string) => string | undefined;\n /** Resolves a path-style layer package against the config that declared it. */\n localEntry: (specifier: string, baseDirectory: string) => string | undefined;\n}\n\ninterface ModesDocument {\n layers?: Record<string, unknown>;\n defaultMajorMode?: unknown;\n majorMode?: Record<string, string[]>;\n}\n\nconst MODES_FILE = 'modes.yaml';\nconst FALLBACK_MAJOR_MODE = 'copilot';\nconst MAJOR_MODES_RELATIVE_PATH = path.join(DOOM_DIR, MODES_FILE);\nconst RELATIVE_PREFIXES = ['./', '../'] as const;\n\n/**\n * Whether a layer package names a path rather than an installed package.\n *\n * The same rule Node applies to import specifiers, so a bare name is always an\n * npm package and a path always looks like one.\n */\nexport function isLocalPackageSpecifier(specifier: string): boolean {\n return path.isAbsolute(specifier) || RELATIVE_PREFIXES.some((prefix) => specifier.startsWith(prefix));\n}\nconst LAYER_CONFIG_KEYS = ['subagents'] as const;\nconst SUBAGENT_CONFIG_KEYS = ['models', 'excludeTools'] as const;\nconst SUBAGENT_MODEL_KEYS = ['model', 'thinking'] as const;\nconst THINKING_VALUES = new Set<PlanningThinkingLevel>(['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max']);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction assertKnownKeys(value: Record<string, unknown>, keys: readonly string[], location: string): void {\n const unsupported = Object.keys(value).filter((key) => !keys.includes(key));\n if (unsupported.length > 0) {\n throw new Error(`${location} has unsupported field(s): ${unsupported.join(', ')}`);\n }\n}\n\nfunction parseLayerCustomization(name: string, value: unknown): LayerCustomizationConfig | undefined {\n if (value === undefined) return undefined;\n const location = `Layer \"${name}\" config in ${MAJOR_MODES_RELATIVE_PATH}`;\n if (!isRecord(value)) throw new Error(`${location} must be a mapping`);\n assertKnownKeys(value, LAYER_CONFIG_KEYS, location);\n if (value.subagents === undefined) return {};\n if (!isRecord(value.subagents)) throw new Error(`${location}.subagents must be a mapping`);\n assertKnownKeys(value.subagents, SUBAGENT_CONFIG_KEYS, `${location}.subagents`);\n const hasModels = Object.hasOwn(value.subagents, 'models');\n const hasExcludeTools = Object.hasOwn(value.subagents, 'excludeTools');\n if (!hasModels && !hasExcludeTools) {\n throw new Error(`${location}.subagents must define models or excludeTools`);\n }\n\n let models: SubagentLayerModelConfig[] | undefined;\n if (hasModels) {\n if (!Array.isArray(value.subagents.models) || value.subagents.models.length === 0) {\n throw new Error(`${location}.subagents.models must be a non-empty array`);\n }\n models = value.subagents.models.map((entry, index): SubagentLayerModelConfig => {\n const entryLocation = `${location}.subagents.models[${index}]`;\n if (!isRecord(entry)) throw new Error(`${entryLocation} must be a mapping`);\n assertKnownKeys(entry, SUBAGENT_MODEL_KEYS, entryLocation);\n if (typeof entry.model !== 'string' || !entry.model.trim()) {\n throw new Error(`${entryLocation}.model must be a non-empty string`);\n }\n if (\n entry.thinking !== undefined &&\n (typeof entry.thinking !== 'string' || !THINKING_VALUES.has(entry.thinking as PlanningThinkingLevel))\n ) {\n throw new Error(`${entryLocation}.thinking must be one of: ${[...THINKING_VALUES].join(', ')}`);\n }\n return {\n model: entry.model.trim(),\n ...(entry.thinking ? { thinking: entry.thinking as PlanningThinkingLevel } : {}),\n };\n });\n }\n\n let normalizedExcludeTools: string[] | undefined;\n if (hasExcludeTools) {\n const excludeTools = value.subagents.excludeTools;\n if (!Array.isArray(excludeTools) || excludeTools.length === 0) {\n throw new Error(`${location}.subagents.excludeTools must be a non-empty array`);\n }\n normalizedExcludeTools = [\n ...new Set(\n excludeTools.map((entry, index) => {\n const entryLocation = `${location}.subagents.excludeTools[${index}]`;\n if (typeof entry !== 'string' || !entry.trim()) {\n throw new Error(`${entryLocation} must be a non-empty string`);\n }\n return entry.trim();\n }),\n ),\n ];\n }\n\n return {\n subagents: {\n ...(models ? { models } : {}),\n ...(normalizedExcludeTools ? { excludeTools: normalizedExcludeTools } : {}),\n },\n };\n}\n\nfunction parseDefaultMajorMode(value: unknown): string {\n if (typeof value !== 'string' || !value.trim()) {\n throw new Error(`defaultMajorMode in ${MAJOR_MODES_RELATIVE_PATH} must be a non-empty string`);\n }\n return value.trim();\n}\n\nfunction parseLayer(name: string, definition: unknown): LayerDefinition {\n if (!isRecord(definition)) throw new Error(`Layer \"${name}\" in ${MAJOR_MODES_RELATIVE_PATH} must be a mapping`);\n if ('targets' in definition) {\n throw new Error(\n `Layer \"${name}\" in ${MAJOR_MODES_RELATIVE_PATH} uses removed field \"targets\"; select availability through major modes`,\n );\n }\n const config = parseLayerCustomization(name, definition.config);\n return (config === undefined ? definition : { ...definition, config }) as LayerDefinition;\n}\n\n/**\n * Reads layers and major modes from the global and repository configs.\n *\n * The repository is read last, so it replaces a global layer or major mode of\n * the same name. Layers keep the root they were declared under so that a\n * global layer naming `./extensions/x` still points beside the global config\n * once it is loaded from inside some other repository.\n */\nexport function loadMajorModesConfig(repoRoot: string, homeDirectory: string = os.homedir()): MajorModesConfig {\n const sources = readDoomConfigSources<ModesDocument>(MODES_FILE, repoRoot, homeDirectory);\n const layers: Record<string, ResolvedLayerDefinition> = {};\n const majorMode: Record<string, string[]> = {};\n let defaultMajorMode = FALLBACK_MAJOR_MODE;\n let hasConfiguredDefault = false;\n for (const source of sources) {\n for (const [name, definition] of Object.entries(source.document.layers ?? {})) {\n layers[name] = { ...parseLayer(name, definition), baseDirectory: source.baseDirectory };\n }\n if (Object.hasOwn(source.document, 'defaultMajorMode')) {\n defaultMajorMode = parseDefaultMajorMode(source.document.defaultMajorMode);\n hasConfiguredDefault = true;\n }\n Object.assign(majorMode, source.document.majorMode ?? {});\n }\n\n for (const [modeName, names] of Object.entries(majorMode)) {\n for (const name of names) {\n if (!layers[name]) {\n throw new Error(`Unknown layer \"${name}\" in majorMode.${modeName} of ${MAJOR_MODES_RELATIVE_PATH}`);\n }\n }\n }\n if (hasConfiguredDefault && !Object.hasOwn(majorMode, defaultMajorMode)) {\n throw new Error(`Unknown default major mode \"${defaultMajorMode}\" in ${MAJOR_MODES_RELATIVE_PATH}`);\n }\n return { layers, defaultMajorMode, majorMode };\n}\n\n/** Merges selected layer customization in order, with later models winning and exclusions unioned. */\nexport function resolveLayerCustomization(config: MajorModesConfig, names: string[]): LayerCustomizationConfig {\n let subagents: SubagentLayerConfig | undefined;\n const excludeTools = new Set<string>();\n let hasExcludeTools = false;\n for (const name of names) {\n const layer = config.layers[name];\n if (!layer) throw new Error(`Unknown layer: ${name}`);\n const next = layer.config?.subagents;\n if (!next) continue;\n if (next.excludeTools !== undefined) {\n hasExcludeTools = true;\n for (const tool of next.excludeTools) excludeTools.add(tool);\n }\n subagents = {\n ...subagents,\n ...(next.models ? { models: next.models.map((model) => ({ ...model })) } : {}),\n ...(hasExcludeTools ? { excludeTools: [...excludeTools] } : {}),\n };\n }\n return subagents ? { subagents } : {};\n}\n\n/** Resolves one named major mode into its configured layer components. */\nexport function resolveLayers(config: MajorModesConfig, majorMode: string): string[] {\n if (!Object.hasOwn(config.majorMode, majorMode)) {\n throw new Error(\n `Unknown major mode: ${majorMode}. Known major modes: ${Object.keys(config.majorMode).sort().join(', ')}`,\n );\n }\n return [...config.majorMode[majorMode]!];\n}\n\n/** Resolves one layer's extension and package entries to absolute paths. */\nexport function layerEntries(config: MajorModesConfig, name: string, resolvers: LayerResolvers): string[] {\n const layer = config.layers[name];\n if (!layer) throw new Error(`Unknown layer: ${name}`);\n const entries: string[] = [];\n for (const entry of layer.extensions ?? []) entries.push(resolvers.ownEntry(entry));\n for (const entry of layer.packages ?? []) {\n const specifier = typeof entry === 'string' ? entry : entry.name;\n const optional = typeof entry === 'string' ? false : entry.optional === true;\n if (isLocalPackageSpecifier(specifier)) {\n const resolved = resolvers.localEntry(specifier, layer.baseDirectory);\n if (resolved) entries.push(resolved);\n else if (!optional) {\n throw new Error(\n `Layer \"${name}\" package \"${specifier}\" does not resolve under ${layer.baseDirectory}. ` +\n 'Point it at an extension file, or a directory whose package.json names one.',\n );\n }\n continue;\n }\n if (optional) {\n const resolved = resolvers.optionalPackageEntry(specifier);\n if (resolved) entries.push(resolved);\n continue;\n }\n entries.push(resolvers.packageEntry(specifier));\n }\n return entries;\n}\n\n/** Hook group ids contributed by the selected layers, deduped. */\nexport function layerHookGroups(config: MajorModesConfig, names: string[]): string[] {\n const groups = new Set<string>();\n for (const name of names) {\n for (const group of config.layers[name]?.hookGroups ?? []) groups.add(group);\n }\n return [...groups];\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"piContext.cjs","names":["getHarnessState","loadDoomConfig","createDoomTelemetry"],"sources":["../src/piContext.ts"],"sourcesContent":["import type { ExtensionAPI, ExtensionContext, ExtensionFactory, SessionEntry } from '@earendil-works/pi-coding-agent';\nimport { createDoomTelemetry, type DoomTelemetry } from '@agimon-ai/doompi-telemetry';\nimport { loadDoomConfig } from './config.ts';\nimport { getHarnessState } from './harnessStore.ts';\nimport type { DeepReadonly, DoomConfigContext, HarnessState } from './types.ts';\n\nexport const DOOM_CONFIG_ENTRY_TYPE = 'doom-pi:config:v1';\n\nexport interface DoomConfigSelection {\n readonly version: 1;\n readonly majorMode: string;\n readonly domains: readonly string[];\n readonly profile?: string;\n}\n\ninterface ConfigBinding {\n readonly context: DoomConfigContext;\n readonly generation: symbol;\n}\n\nconst configBindings = new WeakMap<ExtensionContext['sessionManager'], ConfigBinding>();\n\nfunction isSelection(value: unknown): value is DoomConfigSelection {\n if (typeof value !== 'object' || value === null) return false;\n const selection = value as Partial<DoomConfigSelection>;\n return (\n selection.version === 1 &&\n typeof selection.majorMode === 'string' &&\n Array.isArray(selection.domains) &&\n selection.domains.every((domain) => typeof domain === 'string') &&\n (selection.profile === undefined || typeof selection.profile === 'string')\n );\n}\n\nfunction branchSelection(entries: readonly SessionEntry[]): DoomConfigSelection | undefined {\n for (let index = entries.length - 1; index >= 0; index -= 1) {\n const entry = entries[index];\n if (entry?.type === 'custom' && entry.customType === DOOM_CONFIG_ENTRY_TYPE && isSelection(entry.data)) {\n return entry.data;\n }\n }\n return undefined;\n}\n\nfunction deepFreeze<TValue>(value: TValue): DeepReadonly<TValue> {\n if (typeof value !== 'object' || value === null || Object.isFrozen(value)) {\n return value as DeepReadonly<TValue>;\n }\n for (const child of Object.values(value)) deepFreeze(child);\n return Object.freeze(value) as DeepReadonly<TValue>;\n}\n\nexport function readDoomConfigSelection(\n ctx: Pick<ExtensionContext, 'sessionManager'>,\n): DoomConfigSelection | undefined {\n return branchSelection(ctx.sessionManager.getBranch());\n}\n\nexport function createDoomConfigContext(ctx: Pick<ExtensionContext, 'cwd' | 'sessionManager'>): DoomConfigContext {\n const bootstrap = getHarnessState();\n const selection = readDoomConfigSelection(ctx);\n const harness: HarnessState = selection\n ? { ...bootstrap, majorMode: selection.majorMode, domains: [...selection.domains], profile: selection.profile }\n : bootstrap;\n const requiresRelaunch = Boolean(\n selection &&\n (selection.majorMode !== bootstrap.majorMode ||\n selection.profile !== bootstrap.profile ||\n selection.domains.join(',') !== bootstrap.domains.join(',')),\n );\n return deepFreeze({ settings: loadDoomConfig(bootstrap.root ?? ctx.cwd), harness, requiresRelaunch });\n}\n\nexport function appendDoomConfigSelection(pi: Pick<ExtensionAPI, 'appendEntry'>, selection: DoomConfigSelection): void {\n pi.appendEntry(DOOM_CONFIG_ENTRY_TYPE, selection);\n}\n\nexport function provideDoomConfigContext(\n ctx: Pick<ExtensionContext, 'sessionManager'>,\n context: DoomConfigContext,\n): () => void {\n const binding = { context, generation: Symbol('doom-config-context') };\n configBindings.set(ctx.sessionManager, binding);\n return () => {\n if (configBindings.get(ctx.sessionManager)?.generation === binding.generation) {\n configBindings.delete(ctx.sessionManager);\n }\n };\n}\n\nexport function requireDoomConfigContext(ctx: Pick<ExtensionContext, 'sessionManager'>): DoomConfigContext {\n const binding = configBindings.get(ctx.sessionManager);\n if (!binding) throw new Error('Doom config context is unavailable. Load @agimon-ai/doompi-config/pi.');\n return binding.context;\n}\n\nexport const doomConfigExtension: ExtensionFactory = (pi) => {\n let dispose: (() => void) | undefined;\n let telemetry: DoomTelemetry | undefined;\n pi.on('session_start', async (_event, ctx) => {\n dispose?.();\n const context = createDoomConfigContext(ctx);\n dispose = provideDoomConfigContext(ctx, context);\n telemetry ??= createDoomTelemetry({\n serviceName: 'doom-config',\n packageName: '@agimon-ai/doompi-config',\n cwd: ctx.cwd,\n env: process.env,\n enableLogs: true,\n enableTraces: true,\n });\n await telemetry.recordEvent('doom_config.context_bound', {\n 'config.major_mode': context.harness.majorMode,\n 'config.domain_count': context.harness.domains.length,\n 'config.has_profile': context.harness.profile !== undefined,\n 'config.requires_relaunch': context.requiresRelaunch,\n });\n });\n pi.on('session_shutdown', async () => {\n // Other extensions consume config during shutdown. Keep the WeakMap entry\n // alive for that phase and let it disappear with Pi's sessionManager.\n dispose = undefined;\n await telemetry?.shutdown();\n telemetry = undefined;\n });\n};\n"],"mappings":"gLAMA,MAAa,EAAyB,oBAchC,EAAiB,IAAI,QAE3B,SAAS,EAAY,EAA8C,CACjE,GAAI,OAAO,GAAU,WAAY,EAAgB,MAAO,GACxD,IAAM,EAAY,EAClB,OACE,EAAU,UAAY,GACtB,OAAO,EAAU,WAAc,UAC/B,MAAM,QAAQ,EAAU,OAAO,GAC/B,EAAU,QAAQ,MAAO,GAAW,OAAO,GAAW,QAAQ,IAC7D,EAAU,UAAY,IAAA,IAAa,OAAO,EAAU,SAAY,SAErE,CAEA,SAAS,EAAgB,EAAmE,CAC1F,IAAK,IAAI,EAAQ,EAAQ,OAAS,EAAG,GAAS,EAAG,IAAY,CAC3D,IAAM,EAAQ,EAAQ,GACtB,GAAI,GAAO,OAAS,UAAY,EAAM,aAAA,qBAAyC,EAAY,EAAM,IAAI,EACnG,OAAO,EAAM,IAEjB,CAEF,CAEA,SAAS,EAAmB,EAAqC,CAC/D,GAAI,OAAO,GAAU,WAAY,GAAkB,OAAO,SAAS,CAAK,EACtE,OAAO,EAET,IAAK,IAAM,KAAS,OAAO,OAAO,CAAK,EAAG,EAAW,CAAK,EAC1D,OAAO,OAAO,OAAO,CAAK,CAC5B,CAEA,SAAgB,EACd,EACiC,CACjC,OAAO,EAAgB,EAAI,eAAe,UAAU,CAAC,CACvD,CAEA,SAAgB,EAAwB,EAA0E,CAChH,IAAM,EAAYA,EAAAA,gBAAgB,EAC5B,EAAY,EAAwB,CAAG,EACvC,EAAwB,EAC1B,CAAE,GAAG,EAAW,UAAW,EAAU,UAAW,QAAS,CAAC,GAAG,EAAU,OAAO,EAAG,QAAS,EAAU,OAAQ,EAC5G,EACE,EAAmB,GACvB,IACC,EAAU,YAAc,EAAU,WACjC,EAAU,UAAY,EAAU,SAChC,EAAU,QAAQ,KAAK,GAAG,IAAM,EAAU,QAAQ,KAAK,GAAG,IAE9D,OAAO,EAAW,CAAE,SAAUC,EAAAA,eAAe,EAAU,MAAQ,EAAI,GAAG,EAAG,UAAS,kBAAiB,CAAC,CACtG,CAEA,SAAgB,EAA0B,EAAuC,EAAsC,CACrH,EAAG,YAAY,EAAwB,CAAS,CAClD,CAEA,SAAgB,EACd,EACA,EACY,CACZ,IAAM,EAAU,CAAE,UAAS,WAAY,OAAO,qBAAqB,CAAE,EAErE,OADA,EAAe,IAAI,EAAI,eAAgB,CAAO,MACjC,CACP,EAAe,IAAI,EAAI,cAAc,CAAC,EAAE,aAAe,EAAQ,YACjE,EAAe,OAAO,EAAI,cAAc,CAE5C,CACF,CAEA,SAAgB,EAAyB,EAAkE,CACzG,IAAM,EAAU,EAAe,IAAI,EAAI,cAAc,EACrD,GAAI,CAAC,EAAS,MAAU,MAAM,uEAAuE,EACrG,OAAO,EAAQ,OACjB,CAEA,MAAa,EAAyC,GAAO,CAC3D,IAAI,EACA,EACJ,EAAG,GAAG,gBAAiB,MAAO,EAAQ,IAAQ,CAC5C,IAAU,EACV,IAAM,EAAU,EAAwB,CAAG,EAC3C,EAAU,EAAyB,EAAK,CAAO,EAC/C,KAAA,EAAcC,EAAAA,oBAAAA,CAAoB,CAChC,YAAa,cACb,YAAa,2BACb,IAAK,EAAI,IACT,IAAK,QAAQ,IACb,WAAY,GACZ,aAAc,EAChB,CAAC,EACD,MAAM,EAAU,YAAY,4BAA6B,CACvD,oBAAqB,EAAQ,QAAQ,UACrC,sBAAuB,EAAQ,QAAQ,QAAQ,OAC/C,qBAAsB,EAAQ,QAAQ,UAAY,IAAA,GAClD,2BAA4B,EAAQ,gBACtC,CAAC,CACH,CAAC,EACD,EAAG,GAAG,mBAAoB,SAAY,CAGpC,EAAU,IAAA,GACV,MAAM,GAAW,SAAS,EAC1B,EAAY,IAAA,EACd,CAAC,CACH"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"piContext.d.cts","names":[],"sources":["../src/piContext.ts"],"mappings":";;;cAMa;UAEI;WACN;WACA;WACA;WACA;;iBAwCK,wBACd,KAAK,KAAK,sCACT;iBAIa,wBAAwB,KAAK,KAAK,8CAA8C;iBAehF,0BAA0B,IAAI,KAAK,8BAA8B,WAAW;iBAI5E,yBACd,KAAK,KAAK,qCACV,SAAS;iBAWK,yBAAyB,KAAK,KAAK,sCAAsC;cAM5E,qBAAqB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"piContext.d.mts","names":[],"sources":["../src/piContext.ts"],"mappings":";;;cAMa;UAEI;WACN;WACA;WACA;WACA;;iBAwCK,wBACd,KAAK,KAAK,sCACT;iBAIa,wBAAwB,KAAK,KAAK,8CAA8C;iBAehF,0BAA0B,IAAI,KAAK,8BAA8B,WAAW;iBAI5E,yBACd,KAAK,KAAK,qCACV,SAAS;iBAWK,yBAAyB,KAAK,KAAK,sCAAsC;cAM5E,qBAAqB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"piContext.mjs","names":[],"sources":["../src/piContext.ts"],"sourcesContent":["import type { ExtensionAPI, ExtensionContext, ExtensionFactory, SessionEntry } from '@earendil-works/pi-coding-agent';\nimport { createDoomTelemetry, type DoomTelemetry } from '@agimon-ai/doompi-telemetry';\nimport { loadDoomConfig } from './config.ts';\nimport { getHarnessState } from './harnessStore.ts';\nimport type { DeepReadonly, DoomConfigContext, HarnessState } from './types.ts';\n\nexport const DOOM_CONFIG_ENTRY_TYPE = 'doom-pi:config:v1';\n\nexport interface DoomConfigSelection {\n readonly version: 1;\n readonly majorMode: string;\n readonly domains: readonly string[];\n readonly profile?: string;\n}\n\ninterface ConfigBinding {\n readonly context: DoomConfigContext;\n readonly generation: symbol;\n}\n\nconst configBindings = new WeakMap<ExtensionContext['sessionManager'], ConfigBinding>();\n\nfunction isSelection(value: unknown): value is DoomConfigSelection {\n if (typeof value !== 'object' || value === null) return false;\n const selection = value as Partial<DoomConfigSelection>;\n return (\n selection.version === 1 &&\n typeof selection.majorMode === 'string' &&\n Array.isArray(selection.domains) &&\n selection.domains.every((domain) => typeof domain === 'string') &&\n (selection.profile === undefined || typeof selection.profile === 'string')\n );\n}\n\nfunction branchSelection(entries: readonly SessionEntry[]): DoomConfigSelection | undefined {\n for (let index = entries.length - 1; index >= 0; index -= 1) {\n const entry = entries[index];\n if (entry?.type === 'custom' && entry.customType === DOOM_CONFIG_ENTRY_TYPE && isSelection(entry.data)) {\n return entry.data;\n }\n }\n return undefined;\n}\n\nfunction deepFreeze<TValue>(value: TValue): DeepReadonly<TValue> {\n if (typeof value !== 'object' || value === null || Object.isFrozen(value)) {\n return value as DeepReadonly<TValue>;\n }\n for (const child of Object.values(value)) deepFreeze(child);\n return Object.freeze(value) as DeepReadonly<TValue>;\n}\n\nexport function readDoomConfigSelection(\n ctx: Pick<ExtensionContext, 'sessionManager'>,\n): DoomConfigSelection | undefined {\n return branchSelection(ctx.sessionManager.getBranch());\n}\n\nexport function createDoomConfigContext(ctx: Pick<ExtensionContext, 'cwd' | 'sessionManager'>): DoomConfigContext {\n const bootstrap = getHarnessState();\n const selection = readDoomConfigSelection(ctx);\n const harness: HarnessState = selection\n ? { ...bootstrap, majorMode: selection.majorMode, domains: [...selection.domains], profile: selection.profile }\n : bootstrap;\n const requiresRelaunch = Boolean(\n selection &&\n (selection.majorMode !== bootstrap.majorMode ||\n selection.profile !== bootstrap.profile ||\n selection.domains.join(',') !== bootstrap.domains.join(',')),\n );\n return deepFreeze({ settings: loadDoomConfig(bootstrap.root ?? ctx.cwd), harness, requiresRelaunch });\n}\n\nexport function appendDoomConfigSelection(pi: Pick<ExtensionAPI, 'appendEntry'>, selection: DoomConfigSelection): void {\n pi.appendEntry(DOOM_CONFIG_ENTRY_TYPE, selection);\n}\n\nexport function provideDoomConfigContext(\n ctx: Pick<ExtensionContext, 'sessionManager'>,\n context: DoomConfigContext,\n): () => void {\n const binding = { context, generation: Symbol('doom-config-context') };\n configBindings.set(ctx.sessionManager, binding);\n return () => {\n if (configBindings.get(ctx.sessionManager)?.generation === binding.generation) {\n configBindings.delete(ctx.sessionManager);\n }\n };\n}\n\nexport function requireDoomConfigContext(ctx: Pick<ExtensionContext, 'sessionManager'>): DoomConfigContext {\n const binding = configBindings.get(ctx.sessionManager);\n if (!binding) throw new Error('Doom config context is unavailable. Load @agimon-ai/doompi-config/pi.');\n return binding.context;\n}\n\nexport const doomConfigExtension: ExtensionFactory = (pi) => {\n let dispose: (() => void) | undefined;\n let telemetry: DoomTelemetry | undefined;\n pi.on('session_start', async (_event, ctx) => {\n dispose?.();\n const context = createDoomConfigContext(ctx);\n dispose = provideDoomConfigContext(ctx, context);\n telemetry ??= createDoomTelemetry({\n serviceName: 'doom-config',\n packageName: '@agimon-ai/doompi-config',\n cwd: ctx.cwd,\n env: process.env,\n enableLogs: true,\n enableTraces: true,\n });\n await telemetry.recordEvent('doom_config.context_bound', {\n 'config.major_mode': context.harness.majorMode,\n 'config.domain_count': context.harness.domains.length,\n 'config.has_profile': context.harness.profile !== undefined,\n 'config.requires_relaunch': context.requiresRelaunch,\n });\n });\n pi.on('session_shutdown', async () => {\n // Other extensions consume config during shutdown. Keep the WeakMap entry\n // alive for that phase and let it disappear with Pi's sessionManager.\n dispose = undefined;\n await telemetry?.shutdown();\n telemetry = undefined;\n });\n};\n"],"mappings":"qKAMA,MAAa,EAAyB,oBAchC,EAAiB,IAAI,QAE3B,SAAS,EAAY,EAA8C,CACjE,GAAI,OAAO,GAAU,WAAY,EAAgB,MAAO,GACxD,IAAM,EAAY,EAClB,OACE,EAAU,UAAY,GACtB,OAAO,EAAU,WAAc,UAC/B,MAAM,QAAQ,EAAU,OAAO,GAC/B,EAAU,QAAQ,MAAO,GAAW,OAAO,GAAW,QAAQ,IAC7D,EAAU,UAAY,IAAA,IAAa,OAAO,EAAU,SAAY,SAErE,CAEA,SAAS,EAAgB,EAAmE,CAC1F,IAAK,IAAI,EAAQ,EAAQ,OAAS,EAAG,GAAS,EAAG,IAAY,CAC3D,IAAM,EAAQ,EAAQ,GACtB,GAAI,GAAO,OAAS,UAAY,EAAM,aAAA,qBAAyC,EAAY,EAAM,IAAI,EACnG,OAAO,EAAM,IAEjB,CAEF,CAEA,SAAS,EAAmB,EAAqC,CAC/D,GAAI,OAAO,GAAU,WAAY,GAAkB,OAAO,SAAS,CAAK,EACtE,OAAO,EAET,IAAK,IAAM,KAAS,OAAO,OAAO,CAAK,EAAG,EAAW,CAAK,EAC1D,OAAO,OAAO,OAAO,CAAK,CAC5B,CAEA,SAAgB,EACd,EACiC,CACjC,OAAO,EAAgB,EAAI,eAAe,UAAU,CAAC,CACvD,CAEA,SAAgB,EAAwB,EAA0E,CAChH,IAAM,EAAY,EAAgB,EAC5B,EAAY,EAAwB,CAAG,EACvC,EAAwB,EAC1B,CAAE,GAAG,EAAW,UAAW,EAAU,UAAW,QAAS,CAAC,GAAG,EAAU,OAAO,EAAG,QAAS,EAAU,OAAQ,EAC5G,EACE,EAAmB,GACvB,IACC,EAAU,YAAc,EAAU,WACjC,EAAU,UAAY,EAAU,SAChC,EAAU,QAAQ,KAAK,GAAG,IAAM,EAAU,QAAQ,KAAK,GAAG,IAE9D,OAAO,EAAW,CAAE,SAAU,EAAe,EAAU,MAAQ,EAAI,GAAG,EAAG,UAAS,kBAAiB,CAAC,CACtG,CAEA,SAAgB,EAA0B,EAAuC,EAAsC,CACrH,EAAG,YAAY,EAAwB,CAAS,CAClD,CAEA,SAAgB,EACd,EACA,EACY,CACZ,IAAM,EAAU,CAAE,UAAS,WAAY,OAAO,qBAAqB,CAAE,EAErE,OADA,EAAe,IAAI,EAAI,eAAgB,CAAO,MACjC,CACP,EAAe,IAAI,EAAI,cAAc,CAAC,EAAE,aAAe,EAAQ,YACjE,EAAe,OAAO,EAAI,cAAc,CAE5C,CACF,CAEA,SAAgB,EAAyB,EAAkE,CACzG,IAAM,EAAU,EAAe,IAAI,EAAI,cAAc,EACrD,GAAI,CAAC,EAAS,MAAU,MAAM,uEAAuE,EACrG,OAAO,EAAQ,OACjB,CAEA,MAAa,EAAyC,GAAO,CAC3D,IAAI,EACA,EACJ,EAAG,GAAG,gBAAiB,MAAO,EAAQ,IAAQ,CAC5C,IAAU,EACV,IAAM,EAAU,EAAwB,CAAG,EAC3C,EAAU,EAAyB,EAAK,CAAO,EAC/C,IAAc,EAAoB,CAChC,YAAa,cACb,YAAa,2BACb,IAAK,EAAI,IACT,IAAK,QAAQ,IACb,WAAY,GACZ,aAAc,EAChB,CAAC,EACD,MAAM,EAAU,YAAY,4BAA6B,CACvD,oBAAqB,EAAQ,QAAQ,UACrC,sBAAuB,EAAQ,QAAQ,QAAQ,OAC/C,qBAAsB,EAAQ,QAAQ,UAAY,IAAA,GAClD,2BAA4B,EAAQ,gBACtC,CAAC,CACH,CAAC,EACD,EAAG,GAAG,mBAAoB,SAAY,CAGpC,EAAU,IAAA,GACV,MAAM,GAAW,SAAS,EAC1B,EAAY,IAAA,EACd,CAAC,CACH"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"profiles.cjs","names":["path","fs","os","readDoomConfigSources"],"sources":["../src/profiles.ts"],"sourcesContent":["import fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport { readDoomConfigSources } from './layeredConfig.ts';\n\n/** Files that make up one repository persona, concatenated in this order. */\nexport const PERSONA_FILES = ['profile.md', 'SOUL.md', 'AGENTS.md'];\n\nexport interface AgentProfile {\n name: string;\n /** Directory under agents/, relative to personaRoot, which remains the persona source. */\n persona: string;\n /**\n * Root the persona path resolves against: the repository root for a\n * repository profile, the global `.doom` directory for a global one.\n */\n personaRoot: string;\n /** Environment defaults. Values already exported by the caller win. */\n env: Record<string, string>;\n}\n\nconst PROFILE_KEYS = new Set(['persona', 'env']);\nconst PROFILES_FILE = 'profiles.yaml';\nconst PROFILES_ROOT_KEY = 'profiles';\nconst AGENTS_DIRECTORY = 'agents';\nconst PARENT_DIRECTORY = '..';\nconst TEXT_ENCODING = 'utf8';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction parseEnvironment(name: string, value: unknown): Record<string, string> {\n if (value === undefined) return {};\n if (!isRecord(value)) throw new Error(`Profile \"${name}\" env must be a string mapping`);\n\n const environment: Record<string, string> = {};\n for (const [key, entry] of Object.entries(value)) {\n if (typeof entry !== 'string') throw new Error(`Profile \"${name}\" env.${key} must be a string`);\n environment[key] = entry;\n }\n return environment;\n}\n\nfunction parseProfile(personaRoot: string, name: string, value: unknown): AgentProfile {\n if (!isRecord(value)) throw new Error(`Profile \"${name}\" must be a mapping`);\n\n const unsupported = Object.keys(value).filter((key) => !PROFILE_KEYS.has(key));\n if (unsupported.length > 0) {\n throw new Error(`Profile \"${name}\" may only set persona and env; unsupported: ${unsupported.join(', ')}`);\n }\n if (typeof value.persona !== 'string' || value.persona.trim().length === 0) {\n throw new Error(`Profile \"${name}\" must set a persona`);\n }\n if (path.isAbsolute(value.persona)) {\n throw new Error(`Profile \"${name}\" persona must be relative to the config that declares it`);\n }\n\n const persona = value.persona;\n const personaPath = path.resolve(personaRoot, persona);\n const relativePersonaPath = path.relative(personaRoot, personaPath);\n if (relativePersonaPath !== AGENTS_DIRECTORY && !relativePersonaPath.startsWith(`${AGENTS_DIRECTORY}${path.sep}`)) {\n throw new Error(`Profile \"${name}\" persona must stay inside agents/`);\n }\n if (!fs.existsSync(personaPath) || !fs.statSync(personaPath).isDirectory()) {\n throw new Error(`Profile \"${name}\" references a missing persona: ${persona}`);\n }\n const realAgentsPath = fs.realpathSync(path.join(personaRoot, AGENTS_DIRECTORY));\n const realPersonaPath = fs.realpathSync(personaPath);\n const realRelativePersonaPath = path.relative(realAgentsPath, realPersonaPath);\n if (\n realRelativePersonaPath === PARENT_DIRECTORY ||\n realRelativePersonaPath.startsWith(`${PARENT_DIRECTORY}${path.sep}`)\n ) {\n throw new Error(`Profile \"${name}\" persona must stay inside agents/`);\n }\n if (!buildPersonaPrompt(personaRoot, persona)) {\n throw new Error(`Profile \"${name}\" persona has no readable persona files: ${persona}`);\n }\n\n return { name, persona, personaRoot, env: parseEnvironment(name, value.env) };\n}\n\n/**\n * Loads profiles from the global and repository configs, repository last.\n *\n * A repository profile replaces the global profile of the same name. Each one\n * keeps the root it was declared under, so a global profile's persona is read\n * from `~/.pi/.doom/agents/` however many repositories inherit it.\n */\nexport function loadProfiles(repoRoot: string, homeDirectory: string = os.homedir()): AgentProfile[] {\n const sources = readDoomConfigSources<unknown>(PROFILES_FILE, repoRoot, homeDirectory);\n const byName = new Map<string, AgentProfile>();\n\n for (const source of sources) {\n const parsed = source.document;\n if (!isRecord(parsed) || !isRecord(parsed[PROFILES_ROOT_KEY])) {\n throw new Error(`${source.filePath} must contain a profiles mapping`);\n }\n const unsupported = Object.keys(parsed).filter((key) => key !== PROFILES_ROOT_KEY);\n if (unsupported.length > 0) {\n throw new Error(`${source.filePath} may only contain profiles; unsupported: ${unsupported.join(', ')}`);\n }\n for (const [name, value] of Object.entries(parsed[PROFILES_ROOT_KEY])) {\n byName.set(name, parseProfile(source.baseDirectory, name, value));\n }\n }\n\n return [...byName.values()].sort((left, right) => left.name.localeCompare(right.name));\n}\n\n/** Resolves one selected profile and fails clearly when its name is unknown. */\nexport function resolveProfile(repoRoot: string, name: string, homeDirectory?: string): AgentProfile {\n const profile = loadProfiles(repoRoot, homeDirectory).find((candidate) => candidate.name === name);\n if (!profile) throw new Error(`Unknown profile: ${name}`);\n return profile;\n}\n\nexport function listProfileNames(repoRoot: string, homeDirectory?: string): string[] {\n return loadProfiles(repoRoot, homeDirectory).map((profile) => profile.name);\n}\n\n/** Builds the persona system-prompt block, or undefined when nothing is readable. */\nexport function buildPersonaPrompt(personaRoot: string, personaDirectory: string): string | undefined {\n const sections: string[] = [];\n const personaPath = fs.realpathSync(path.join(personaRoot, personaDirectory));\n for (const file of PERSONA_FILES) {\n const filePath = path.join(personaPath, file);\n if (!fs.existsSync(filePath)) continue;\n const realFilePath = fs.realpathSync(filePath);\n const relativeFilePath = path.relative(personaPath, realFilePath);\n if (relativeFilePath === PARENT_DIRECTORY || relativeFilePath.startsWith(`${PARENT_DIRECTORY}${path.sep}`)) {\n throw new Error(`Persona file must stay inside ${personaDirectory}: ${file}`);\n }\n const content = fs.readFileSync(realFilePath, TEXT_ENCODING).trim();\n if (content) sections.push(content);\n }\n if (sections.length === 0) return undefined;\n return [`[PERSONA] You are operating as the person described below (source: ${personaDirectory}).`, ...sections].join(\n '\\n\\n',\n );\n}\n\n/** Applies profile environment defaults and returns only the values it contributed. */\nexport function applyProfileEnvironment(\n environment: NodeJS.ProcessEnv,\n defaults: Record<string, string>,\n): Record<string, string> {\n const applied: Record<string, string> = {};\n for (const [key, value] of Object.entries(defaults)) {\n if (environment[key] !== undefined) continue;\n environment[key] = value;\n applied[key] = value;\n }\n return applied;\n}\n\n/** Replaces environment defaults previously contributed by another profile. */\nexport function replaceProfileEnvironment(\n environment: NodeJS.ProcessEnv,\n previous: Record<string, string>,\n next: Record<string, string>,\n): Record<string, string> {\n for (const [key, value] of Object.entries(previous)) {\n if (environment[key] === value) delete environment[key];\n }\n return applyProfileEnvironment(environment, next);\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"profiles.d.cts","names":[],"sources":["../src/profiles.ts"],"mappings":";;cAMa;UAEI;EACf;;EAEA;;;;;EAKA;;EAEA,KAAK;;;;;;;;;iBAwES,aAAa,kBAAkB,yBAAuC;;iBAsBtE,eAAe,kBAAkB,cAAc,yBAAyB;iBAMxE,iBAAiB,kBAAkB;;iBAKnC,mBAAmB,qBAAqB;;iBAqBxC,wBACd,aAAa,OAAO,YACpB,UAAU,yBACT;;iBAWa,0BACd,aAAa,OAAO,YACpB,UAAU,wBACV,MAAM,yBACL"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"profiles.d.mts","names":[],"sources":["../src/profiles.ts"],"mappings":";;cAMa;UAEI;EACf;;EAEA;;;;;EAKA;;EAEA,KAAK;;;;;;;;;iBAwES,aAAa,kBAAkB,yBAAuC;;iBAsBtE,eAAe,kBAAkB,cAAc,yBAAyB;iBAMxE,iBAAiB,kBAAkB;;iBAKnC,mBAAmB,qBAAqB;;iBAqBxC,wBACd,aAAa,OAAO,YACpB,UAAU,yBACT;;iBAWa,0BACd,aAAa,OAAO,YACpB,UAAU,wBACV,MAAM,yBACL"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"profiles.mjs","names":[],"sources":["../src/profiles.ts"],"sourcesContent":["import fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport { readDoomConfigSources } from './layeredConfig.ts';\n\n/** Files that make up one repository persona, concatenated in this order. */\nexport const PERSONA_FILES = ['profile.md', 'SOUL.md', 'AGENTS.md'];\n\nexport interface AgentProfile {\n name: string;\n /** Directory under agents/, relative to personaRoot, which remains the persona source. */\n persona: string;\n /**\n * Root the persona path resolves against: the repository root for a\n * repository profile, the global `.doom` directory for a global one.\n */\n personaRoot: string;\n /** Environment defaults. Values already exported by the caller win. */\n env: Record<string, string>;\n}\n\nconst PROFILE_KEYS = new Set(['persona', 'env']);\nconst PROFILES_FILE = 'profiles.yaml';\nconst PROFILES_ROOT_KEY = 'profiles';\nconst AGENTS_DIRECTORY = 'agents';\nconst PARENT_DIRECTORY = '..';\nconst TEXT_ENCODING = 'utf8';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction parseEnvironment(name: string, value: unknown): Record<string, string> {\n if (value === undefined) return {};\n if (!isRecord(value)) throw new Error(`Profile \"${name}\" env must be a string mapping`);\n\n const environment: Record<string, string> = {};\n for (const [key, entry] of Object.entries(value)) {\n if (typeof entry !== 'string') throw new Error(`Profile \"${name}\" env.${key} must be a string`);\n environment[key] = entry;\n }\n return environment;\n}\n\nfunction parseProfile(personaRoot: string, name: string, value: unknown): AgentProfile {\n if (!isRecord(value)) throw new Error(`Profile \"${name}\" must be a mapping`);\n\n const unsupported = Object.keys(value).filter((key) => !PROFILE_KEYS.has(key));\n if (unsupported.length > 0) {\n throw new Error(`Profile \"${name}\" may only set persona and env; unsupported: ${unsupported.join(', ')}`);\n }\n if (typeof value.persona !== 'string' || value.persona.trim().length === 0) {\n throw new Error(`Profile \"${name}\" must set a persona`);\n }\n if (path.isAbsolute(value.persona)) {\n throw new Error(`Profile \"${name}\" persona must be relative to the config that declares it`);\n }\n\n const persona = value.persona;\n const personaPath = path.resolve(personaRoot, persona);\n const relativePersonaPath = path.relative(personaRoot, personaPath);\n if (relativePersonaPath !== AGENTS_DIRECTORY && !relativePersonaPath.startsWith(`${AGENTS_DIRECTORY}${path.sep}`)) {\n throw new Error(`Profile \"${name}\" persona must stay inside agents/`);\n }\n if (!fs.existsSync(personaPath) || !fs.statSync(personaPath).isDirectory()) {\n throw new Error(`Profile \"${name}\" references a missing persona: ${persona}`);\n }\n const realAgentsPath = fs.realpathSync(path.join(personaRoot, AGENTS_DIRECTORY));\n const realPersonaPath = fs.realpathSync(personaPath);\n const realRelativePersonaPath = path.relative(realAgentsPath, realPersonaPath);\n if (\n realRelativePersonaPath === PARENT_DIRECTORY ||\n realRelativePersonaPath.startsWith(`${PARENT_DIRECTORY}${path.sep}`)\n ) {\n throw new Error(`Profile \"${name}\" persona must stay inside agents/`);\n }\n if (!buildPersonaPrompt(personaRoot, persona)) {\n throw new Error(`Profile \"${name}\" persona has no readable persona files: ${persona}`);\n }\n\n return { name, persona, personaRoot, env: parseEnvironment(name, value.env) };\n}\n\n/**\n * Loads profiles from the global and repository configs, repository last.\n *\n * A repository profile replaces the global profile of the same name. Each one\n * keeps the root it was declared under, so a global profile's persona is read\n * from `~/.pi/.doom/agents/` however many repositories inherit it.\n */\nexport function loadProfiles(repoRoot: string, homeDirectory: string = os.homedir()): AgentProfile[] {\n const sources = readDoomConfigSources<unknown>(PROFILES_FILE, repoRoot, homeDirectory);\n const byName = new Map<string, AgentProfile>();\n\n for (const source of sources) {\n const parsed = source.document;\n if (!isRecord(parsed) || !isRecord(parsed[PROFILES_ROOT_KEY])) {\n throw new Error(`${source.filePath} must contain a profiles mapping`);\n }\n const unsupported = Object.keys(parsed).filter((key) => key !== PROFILES_ROOT_KEY);\n if (unsupported.length > 0) {\n throw new Error(`${source.filePath} may only contain profiles; unsupported: ${unsupported.join(', ')}`);\n }\n for (const [name, value] of Object.entries(parsed[PROFILES_ROOT_KEY])) {\n byName.set(name, parseProfile(source.baseDirectory, name, value));\n }\n }\n\n return [...byName.values()].sort((left, right) => left.name.localeCompare(right.name));\n}\n\n/** Resolves one selected profile and fails clearly when its name is unknown. */\nexport function resolveProfile(repoRoot: string, name: string, homeDirectory?: string): AgentProfile {\n const profile = loadProfiles(repoRoot, homeDirectory).find((candidate) => candidate.name === name);\n if (!profile) throw new Error(`Unknown profile: ${name}`);\n return profile;\n}\n\nexport function listProfileNames(repoRoot: string, homeDirectory?: string): string[] {\n return loadProfiles(repoRoot, homeDirectory).map((profile) => profile.name);\n}\n\n/** Builds the persona system-prompt block, or undefined when nothing is readable. */\nexport function buildPersonaPrompt(personaRoot: string, personaDirectory: string): string | undefined {\n const sections: string[] = [];\n const personaPath = fs.realpathSync(path.join(personaRoot, personaDirectory));\n for (const file of PERSONA_FILES) {\n const filePath = path.join(personaPath, file);\n if (!fs.existsSync(filePath)) continue;\n const realFilePath = fs.realpathSync(filePath);\n const relativeFilePath = path.relative(personaPath, realFilePath);\n if (relativeFilePath === PARENT_DIRECTORY || relativeFilePath.startsWith(`${PARENT_DIRECTORY}${path.sep}`)) {\n throw new Error(`Persona file must stay inside ${personaDirectory}: ${file}`);\n }\n const content = fs.readFileSync(realFilePath, TEXT_ENCODING).trim();\n if (content) sections.push(content);\n }\n if (sections.length === 0) return undefined;\n return [`[PERSONA] You are operating as the person described below (source: ${personaDirectory}).`, ...sections].join(\n '\\n\\n',\n );\n}\n\n/** Applies profile environment defaults and returns only the values it contributed. */\nexport function applyProfileEnvironment(\n environment: NodeJS.ProcessEnv,\n defaults: Record<string, string>,\n): Record<string, string> {\n const applied: Record<string, string> = {};\n for (const [key, value] of Object.entries(defaults)) {\n if (environment[key] !== undefined) continue;\n environment[key] = value;\n applied[key] = value;\n }\n return applied;\n}\n\n/** Replaces environment defaults previously contributed by another profile. */\nexport function replaceProfileEnvironment(\n environment: NodeJS.ProcessEnv,\n previous: Record<string, string>,\n next: Record<string, string>,\n): Record<string, string> {\n for (const [key, value] of Object.entries(previous)) {\n if (environment[key] === value) delete environment[key];\n }\n return applyProfileEnvironment(environment, next);\n}\n"],"mappings":"mIAMA,MAAa,EAAgB,CAAC,aAAc,UAAW,WAAW,EAe5D,EAAe,IAAI,IAAI,CAAC,UAAW,KAAK,CAAC,EAEzC,EAAoB,WACpB,EAAmB,SAIzB,SAAS,EAAS,EAAkD,CAClE,OAAO,OAAO,GAAU,YAAY,GAAkB,CAAC,MAAM,QAAQ,CAAK,CAC5E,CAEA,SAAS,EAAiB,EAAc,EAAwC,CAC9E,GAAI,IAAU,IAAA,GAAW,MAAO,CAAC,EACjC,GAAI,CAAC,EAAS,CAAK,EAAG,MAAU,MAAM,YAAY,EAAK,+BAA+B,EAEtF,IAAM,EAAsC,CAAC,EAC7C,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,CAAK,EAAG,CAChD,GAAI,OAAO,GAAU,SAAU,MAAU,MAAM,YAAY,EAAK,QAAQ,EAAI,kBAAkB,EAC9F,EAAY,GAAO,CACrB,CACA,OAAO,CACT,CAEA,SAAS,EAAa,EAAqB,EAAc,EAA8B,CACrF,GAAI,CAAC,EAAS,CAAK,EAAG,MAAU,MAAM,YAAY,EAAK,oBAAoB,EAE3E,IAAM,EAAc,OAAO,KAAK,CAAK,CAAC,CAAC,OAAQ,GAAQ,CAAC,EAAa,IAAI,CAAG,CAAC,EAC7E,GAAI,EAAY,OAAS,EACvB,MAAU,MAAM,YAAY,EAAK,+CAA+C,EAAY,KAAK,IAAI,GAAG,EAE1G,GAAI,OAAO,EAAM,SAAY,UAAY,EAAM,QAAQ,KAAK,CAAC,CAAC,SAAW,EACvE,MAAU,MAAM,YAAY,EAAK,qBAAqB,EAExD,GAAI,EAAK,WAAW,EAAM,OAAO,EAC/B,MAAU,MAAM,YAAY,EAAK,0DAA0D,EAG7F,IAAM,EAAU,EAAM,QAChB,EAAc,EAAK,QAAQ,EAAa,CAAO,EAC/C,EAAsB,EAAK,SAAS,EAAa,CAAW,EAClE,GAAI,IAAwB,GAAoB,CAAC,EAAoB,WAAW,GAAG,IAAmB,EAAK,KAAK,EAC9G,MAAU,MAAM,YAAY,EAAK,mCAAmC,EAEtE,GAAI,CAAC,EAAG,WAAW,CAAW,GAAK,CAAC,EAAG,SAAS,CAAW,CAAC,CAAC,YAAY,EACvE,MAAU,MAAM,YAAY,EAAK,kCAAkC,GAAS,EAE9E,IAAM,EAAiB,EAAG,aAAa,EAAK,KAAK,EAAa,CAAgB,CAAC,EACzE,EAAkB,EAAG,aAAa,CAAW,EAC7C,EAA0B,EAAK,SAAS,EAAgB,CAAe,EAC7E,GACE,IAA4B,MAC5B,EAAwB,WAAW,KAAsB,EAAK,KAAK,EAEnE,MAAU,MAAM,YAAY,EAAK,mCAAmC,EAEtE,GAAI,CAAC,EAAmB,EAAa,CAAO,EAC1C,MAAU,MAAM,YAAY,EAAK,2CAA2C,GAAS,EAGvF,MAAO,CAAE,OAAM,UAAS,cAAa,IAAK,EAAiB,EAAM,EAAM,GAAG,CAAE,CAC9E,CASA,SAAgB,EAAa,EAAkB,EAAwB,EAAG,QAAQ,EAAmB,CACnG,IAAM,EAAU,EAA+B,gBAAe,EAAU,CAAa,EAC/E,EAAS,IAAI,IAEnB,IAAK,IAAM,KAAU,EAAS,CAC5B,IAAM,EAAS,EAAO,SACtB,GAAI,CAAC,EAAS,CAAM,GAAK,CAAC,EAAS,EAAO,EAAkB,EAC1D,MAAU,MAAM,GAAG,EAAO,SAAS,iCAAiC,EAEtE,IAAM,EAAc,OAAO,KAAK,CAAM,CAAC,CAAC,OAAQ,GAAQ,IAAQ,CAAiB,EACjF,GAAI,EAAY,OAAS,EACvB,MAAU,MAAM,GAAG,EAAO,SAAS,2CAA2C,EAAY,KAAK,IAAI,GAAG,EAExG,IAAK,GAAM,CAAC,EAAM,KAAU,OAAO,QAAQ,EAAO,EAAkB,EAClE,EAAO,IAAI,EAAM,EAAa,EAAO,cAAe,EAAM,CAAK,CAAC,CAEpE,CAEA,MAAO,CAAC,GAAG,EAAO,OAAO,CAAC,CAAC,CAAC,MAAM,EAAM,IAAU,EAAK,KAAK,cAAc,EAAM,IAAI,CAAC,CACvF,CAGA,SAAgB,EAAe,EAAkB,EAAc,EAAsC,CACnG,IAAM,EAAU,EAAa,EAAU,CAAa,CAAC,CAAC,KAAM,GAAc,EAAU,OAAS,CAAI,EACjG,GAAI,CAAC,EAAS,MAAU,MAAM,oBAAoB,GAAM,EACxD,OAAO,CACT,CAEA,SAAgB,EAAiB,EAAkB,EAAkC,CACnF,OAAO,EAAa,EAAU,CAAa,CAAC,CAAC,IAAK,GAAY,EAAQ,IAAI,CAC5E,CAGA,SAAgB,EAAmB,EAAqB,EAA8C,CACpG,IAAM,EAAqB,CAAC,EACtB,EAAc,EAAG,aAAa,EAAK,KAAK,EAAa,CAAgB,CAAC,EAC5E,IAAK,IAAM,KAAQ,EAAe,CAChC,IAAM,EAAW,EAAK,KAAK,EAAa,CAAI,EAC5C,GAAI,CAAC,EAAG,WAAW,CAAQ,EAAG,SAC9B,IAAM,EAAe,EAAG,aAAa,CAAQ,EACvC,EAAmB,EAAK,SAAS,EAAa,CAAY,EAChE,GAAI,IAAqB,MAAoB,EAAiB,WAAW,KAAsB,EAAK,KAAK,EACvG,MAAU,MAAM,iCAAiC,EAAiB,IAAI,GAAM,EAE9E,IAAM,EAAU,EAAG,aAAa,EAAc,MAAa,CAAC,CAAC,KAAK,EAC9D,GAAS,EAAS,KAAK,CAAO,CACpC,CACI,KAAS,SAAW,EACxB,MAAO,CAAC,sEAAsE,EAAiB,IAAK,GAAG,CAAQ,CAAC,CAAC,KAC/G;;CACF,CACF,CAGA,SAAgB,EACd,EACA,EACwB,CACxB,IAAM,EAAkC,CAAC,EACzC,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,CAAQ,EAC5C,EAAY,KAAS,IAAA,KACzB,EAAY,GAAO,EACnB,EAAQ,GAAO,GAEjB,OAAO,CACT,CAGA,SAAgB,EACd,EACA,EACA,EACwB,CACxB,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,CAAQ,EAC5C,EAAY,KAAS,GAAO,OAAO,EAAY,GAErD,OAAO,EAAwB,EAAa,CAAI,CAClD"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.cjs","names":[],"sources":["../src/types.ts"],"sourcesContent":["export const DOOM_CONFIG_TYPES = { ConfigService: Symbol.for('DoomConfig:ConfigService') } as const;\n\nexport type ProjectTrust = 'ask' | 'always' | 'never';\nexport type PlanningThinkingLevel = 'off' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max';\nexport type VoiceEngine = 'auto' | 'whisper-cpp' | 'openai-whisper' | 'mlx-whisper';\nexport type VoiceTtsEngine = 'macos-say';\n\nexport interface PlanningAgentConfig {\n model?: string;\n thinking?: PlanningThinkingLevel;\n}\nexport interface PlanningModeConfig {\n main?: PlanningAgentConfig;\n subagents?: PlanningAgentConfig;\n plansDirectory?: string;\n}\nexport interface EditorConfig {\n command?: string;\n}\nexport interface VoiceModelConfig {\n path?: string;\n id?: string;\n}\nexport interface VoiceAdapterConfig {\n binary?: string;\n model: VoiceModelConfig;\n}\nexport interface VoiceTtsConfig {\n engine: VoiceTtsEngine;\n voice?: string;\n rate?: number;\n}\nexport interface VoiceAutoCaptureConfig {\n model: string;\n startPhrases?: string[];\n stopPhrases?: string[];\n tts: VoiceTtsConfig;\n}\nexport interface ResolvedVoiceAutoCaptureConfig {\n model: string;\n startPhrases: string[];\n stopPhrases: string[];\n tts: VoiceTtsConfig;\n}\nexport interface VoiceConfig {\n engine?: VoiceEngine;\n language?: string;\n recorder?: { binary?: string; device?: string };\n adapters?: {\n 'whisper-cpp'?: VoiceAdapterConfig;\n 'openai-whisper'?: VoiceAdapterConfig;\n 'mlx-whisper'?: VoiceAdapterConfig;\n };\n autoCapture?: VoiceAutoCaptureConfig;\n}\nexport interface ResolvedVoiceConfig {\n engine: VoiceEngine;\n language: string;\n recorder: { binary?: string; device: string };\n adapters: NonNullable<VoiceConfig['adapters']>;\n autoCapture?: ResolvedVoiceAutoCaptureConfig;\n}\n/**\n * The matrix a repository selects by default.\n *\n * Read by `doom-pi sync`, which pins it into the generated Pi config so a plain\n * `pi` session starts on the same matrix the repository declares. The launcher\n * keeps taking its selection from flags and the environment.\n */\nexport interface DoomSelectionConfig {\n majorMode?: string;\n domains?: string[];\n profile?: string;\n}\n\nexport interface DoomConfig {\n modes?: { planning?: PlanningModeConfig };\n projectTrust: ProjectTrust;\n editor?: EditorConfig;\n voice?: VoiceConfig;\n selection?: DoomSelectionConfig;\n}\n\nexport interface PluginHookSource {\n pluginRoot: string;\n configPath: string;\n}\n\nexport interface HarnessState {\n root?: string;\n /** The one named major mode this session runs under. */\n majorMode: string;\n temporaryDirectory?: string;\n domains: string[];\n /** The layer components the major mode resolved to. */\n layers: string[];\n profile?: string;\n profileEnvironment: Record<string, string>;\n hookGroups?: string[];\n skillDirectories: string[];\n agentDirectories: string[];\n additionalDirectories: string[];\n childExtensions: string[];\n pluginDirectories: string[];\n pluginHooks: PluginHookSource[];\n mcpConfigPath?: string;\n personaFile?: string;\n workflowExtension?: string;\n allowProtectedWrites: boolean;\n hooks: boolean;\n agents: boolean;\n mcp: boolean;\n}\n\nexport type DeepReadonly<TValue> = TValue extends (...args: never[]) => unknown\n ? TValue\n : TValue extends readonly (infer TItem)[]\n ? readonly DeepReadonly<TItem>[]\n : TValue extends object\n ? { readonly [TKey in keyof TValue]: DeepReadonly<TValue[TKey]> }\n : TValue;\n\nexport type DoomHarnessContext = DeepReadonly<HarnessState>;\n\nexport interface DoomConfigContext {\n readonly settings: DeepReadonly<DoomConfig>;\n readonly harness: DoomHarnessContext;\n readonly requiresRelaunch: boolean;\n}\n\nexport interface IDoomConfigService {\n load(repoRoot: string, homeDirectory?: string): DoomConfig;\n}\n"],"mappings":"mEAAA,MAAa,EAAoB,CAAE,cAAe,OAAO,IAAI,0BAA0B,CAAE"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.cts","names":[],"sources":["../src/types.ts"],"mappings":";cAAa;WAAA;;KAED;KACA;KACA;KACA;UAEK;EACf;EACA,WAAW;;UAEI;EACf,OAAO;EACP,YAAY;EACZ;;UAEe;EACf;;UAEe;EACf;EACA;;UAEe;EACf;EACA,OAAO;;UAEQ;EACf,QAAQ;EACR;EACA;;UAEe;EACf;EACA;EACA;EACA,KAAK;;UAEU;EACf;EACA;EACA;EACA,KAAK;;UAEU;EACf,SAAS;EACT;EACA;IAAa;IAAiB;;EAC9B;IACE,gBAAgB;IAChB,mBAAmB;IACnB,gBAAgB;;EAElB,cAAc;;UAEC;EACf,QAAQ;EACR;EACA;IAAY;IAAiB;;EAC7B,UAAU,YAAY;EACtB,cAAc;;;;;;;;;UASC;EACf;EACA;EACA;;UAGe;EACf;IAAU,WAAW;;EACrB,cAAc;EACd,SAAS;EACT,QAAQ;EACR,YAAY;;UAGG;EACf;EACA;;UAGe;EACf;;EAEA;EACA;EACA;;EAEA;EACA;EACA,oBAAoB;EACpB;EACA;EACA;EACA;EACA;EACA;EACA,aAAa;EACb;EACA;EACA;EACA;EACA;EACA;EACA;;KAGU,aAAa,UAAU,oBAAmB,6BAClD,SACA,+BAA+B,oBACpB,aAAa,WACtB,oCACc,cAAc,SAAS,aAAa,OAAO,YACvD;KAEI,qBAAqB,aAAa;UAE7B;WACN,UAAU,aAAa;WACvB,SAAS;WACT;;UAGM;EACf,KAAK,kBAAkB,yBAAyB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.mts","names":[],"sources":["../src/types.ts"],"mappings":";cAAa;WAAA;;KAED;KACA;KACA;KACA;UAEK;EACf;EACA,WAAW;;UAEI;EACf,OAAO;EACP,YAAY;EACZ;;UAEe;EACf;;UAEe;EACf;EACA;;UAEe;EACf;EACA,OAAO;;UAEQ;EACf,QAAQ;EACR;EACA;;UAEe;EACf;EACA;EACA;EACA,KAAK;;UAEU;EACf;EACA;EACA;EACA,KAAK;;UAEU;EACf,SAAS;EACT;EACA;IAAa;IAAiB;;EAC9B;IACE,gBAAgB;IAChB,mBAAmB;IACnB,gBAAgB;;EAElB,cAAc;;UAEC;EACf,QAAQ;EACR;EACA;IAAY;IAAiB;;EAC7B,UAAU,YAAY;EACtB,cAAc;;;;;;;;;UASC;EACf;EACA;EACA;;UAGe;EACf;IAAU,WAAW;;EACrB,cAAc;EACd,SAAS;EACT,QAAQ;EACR,YAAY;;UAGG;EACf;EACA;;UAGe;EACf;;EAEA;EACA;EACA;;EAEA;EACA;EACA,oBAAoB;EACpB;EACA;EACA;EACA;EACA;EACA;EACA,aAAa;EACb;EACA;EACA;EACA;EACA;EACA;EACA;;KAGU,aAAa,UAAU,oBAAmB,6BAClD,SACA,+BAA+B,oBACpB,aAAa,WACtB,oCACc,cAAc,SAAS,aAAa,OAAO,YACvD;KAEI,qBAAqB,aAAa;UAE7B;WACN,UAAU,aAAa;WACvB,SAAS;WACT;;UAGM;EACf,KAAK,kBAAkB,yBAAyB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.mjs","names":[],"sources":["../src/types.ts"],"sourcesContent":["export const DOOM_CONFIG_TYPES = { ConfigService: Symbol.for('DoomConfig:ConfigService') } as const;\n\nexport type ProjectTrust = 'ask' | 'always' | 'never';\nexport type PlanningThinkingLevel = 'off' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max';\nexport type VoiceEngine = 'auto' | 'whisper-cpp' | 'openai-whisper' | 'mlx-whisper';\nexport type VoiceTtsEngine = 'macos-say';\n\nexport interface PlanningAgentConfig {\n model?: string;\n thinking?: PlanningThinkingLevel;\n}\nexport interface PlanningModeConfig {\n main?: PlanningAgentConfig;\n subagents?: PlanningAgentConfig;\n plansDirectory?: string;\n}\nexport interface EditorConfig {\n command?: string;\n}\nexport interface VoiceModelConfig {\n path?: string;\n id?: string;\n}\nexport interface VoiceAdapterConfig {\n binary?: string;\n model: VoiceModelConfig;\n}\nexport interface VoiceTtsConfig {\n engine: VoiceTtsEngine;\n voice?: string;\n rate?: number;\n}\nexport interface VoiceAutoCaptureConfig {\n model: string;\n startPhrases?: string[];\n stopPhrases?: string[];\n tts: VoiceTtsConfig;\n}\nexport interface ResolvedVoiceAutoCaptureConfig {\n model: string;\n startPhrases: string[];\n stopPhrases: string[];\n tts: VoiceTtsConfig;\n}\nexport interface VoiceConfig {\n engine?: VoiceEngine;\n language?: string;\n recorder?: { binary?: string; device?: string };\n adapters?: {\n 'whisper-cpp'?: VoiceAdapterConfig;\n 'openai-whisper'?: VoiceAdapterConfig;\n 'mlx-whisper'?: VoiceAdapterConfig;\n };\n autoCapture?: VoiceAutoCaptureConfig;\n}\nexport interface ResolvedVoiceConfig {\n engine: VoiceEngine;\n language: string;\n recorder: { binary?: string; device: string };\n adapters: NonNullable<VoiceConfig['adapters']>;\n autoCapture?: ResolvedVoiceAutoCaptureConfig;\n}\n/**\n * The matrix a repository selects by default.\n *\n * Read by `doom-pi sync`, which pins it into the generated Pi config so a plain\n * `pi` session starts on the same matrix the repository declares. The launcher\n * keeps taking its selection from flags and the environment.\n */\nexport interface DoomSelectionConfig {\n majorMode?: string;\n domains?: string[];\n profile?: string;\n}\n\nexport interface DoomConfig {\n modes?: { planning?: PlanningModeConfig };\n projectTrust: ProjectTrust;\n editor?: EditorConfig;\n voice?: VoiceConfig;\n selection?: DoomSelectionConfig;\n}\n\nexport interface PluginHookSource {\n pluginRoot: string;\n configPath: string;\n}\n\nexport interface HarnessState {\n root?: string;\n /** The one named major mode this session runs under. */\n majorMode: string;\n temporaryDirectory?: string;\n domains: string[];\n /** The layer components the major mode resolved to. */\n layers: string[];\n profile?: string;\n profileEnvironment: Record<string, string>;\n hookGroups?: string[];\n skillDirectories: string[];\n agentDirectories: string[];\n additionalDirectories: string[];\n childExtensions: string[];\n pluginDirectories: string[];\n pluginHooks: PluginHookSource[];\n mcpConfigPath?: string;\n personaFile?: string;\n workflowExtension?: string;\n allowProtectedWrites: boolean;\n hooks: boolean;\n agents: boolean;\n mcp: boolean;\n}\n\nexport type DeepReadonly<TValue> = TValue extends (...args: never[]) => unknown\n ? TValue\n : TValue extends readonly (infer TItem)[]\n ? readonly DeepReadonly<TItem>[]\n : TValue extends object\n ? { readonly [TKey in keyof TValue]: DeepReadonly<TValue[TKey]> }\n : TValue;\n\nexport type DoomHarnessContext = DeepReadonly<HarnessState>;\n\nexport interface DoomConfigContext {\n readonly settings: DeepReadonly<DoomConfig>;\n readonly harness: DoomHarnessContext;\n readonly requiresRelaunch: boolean;\n}\n\nexport interface IDoomConfigService {\n load(repoRoot: string, homeDirectory?: string): DoomConfig;\n}\n"],"mappings":"AAAA,MAAa,EAAoB,CAAE,cAAe,OAAO,IAAI,0BAA0B,CAAE"}