@agent-profile/web 0.1.5 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (258) hide show
  1. package/build/client/_app/immutable/assets/9.BDcQmxob.css +1 -0
  2. package/build/client/_app/immutable/assets/9.BDcQmxob.css.br +0 -0
  3. package/build/client/_app/immutable/assets/9.BDcQmxob.css.gz +0 -0
  4. package/build/client/_app/immutable/chunks/BcMnim1Z.js +2 -0
  5. package/build/client/_app/immutable/chunks/BcMnim1Z.js.br +0 -0
  6. package/build/client/_app/immutable/chunks/BcMnim1Z.js.gz +0 -0
  7. package/build/client/_app/immutable/chunks/D5fBh0I2.js +1 -0
  8. package/build/client/_app/immutable/chunks/D5fBh0I2.js.br +2 -0
  9. package/build/client/_app/immutable/chunks/D5fBh0I2.js.gz +0 -0
  10. package/build/client/_app/immutable/chunks/DJ5W1vn7.js +3 -0
  11. package/build/client/_app/immutable/chunks/DJ5W1vn7.js.br +0 -0
  12. package/build/client/_app/immutable/chunks/DJ5W1vn7.js.gz +0 -0
  13. package/build/client/_app/immutable/chunks/DTBN031P.js +1 -0
  14. package/build/client/_app/immutable/chunks/DTBN031P.js.br +2 -0
  15. package/build/client/_app/immutable/chunks/DTBN031P.js.gz +0 -0
  16. package/build/client/_app/immutable/chunks/D_wMLkFK.js +1 -0
  17. package/build/client/_app/immutable/chunks/D_wMLkFK.js.br +2 -0
  18. package/build/client/_app/immutable/chunks/D_wMLkFK.js.gz +0 -0
  19. package/build/client/_app/immutable/chunks/m4VeB-e-.js +3 -0
  20. package/build/client/_app/immutable/chunks/m4VeB-e-.js.br +0 -0
  21. package/build/client/_app/immutable/chunks/m4VeB-e-.js.gz +0 -0
  22. package/build/client/_app/immutable/entry/app.DMWpO7sJ.js +2 -0
  23. package/build/client/_app/immutable/entry/app.DMWpO7sJ.js.br +0 -0
  24. package/build/client/_app/immutable/entry/app.DMWpO7sJ.js.gz +0 -0
  25. package/build/client/_app/immutable/entry/start.BBaMgJ1R.js +1 -0
  26. package/build/client/_app/immutable/entry/start.BBaMgJ1R.js.br +0 -0
  27. package/build/client/_app/immutable/entry/start.BBaMgJ1R.js.gz +0 -0
  28. package/build/client/_app/immutable/nodes/0.Dv0k2Jqi.js +1 -0
  29. package/build/client/_app/immutable/nodes/0.Dv0k2Jqi.js.br +0 -0
  30. package/build/client/_app/immutable/nodes/0.Dv0k2Jqi.js.gz +0 -0
  31. package/build/client/_app/immutable/nodes/1.E6HqFVj7.js +1 -0
  32. package/build/client/_app/immutable/nodes/1.E6HqFVj7.js.br +0 -0
  33. package/build/client/_app/immutable/nodes/1.E6HqFVj7.js.gz +0 -0
  34. package/build/client/_app/immutable/nodes/10.DorD5wKe.js +3 -0
  35. package/build/client/_app/immutable/nodes/10.DorD5wKe.js.br +0 -0
  36. package/build/client/_app/immutable/nodes/10.DorD5wKe.js.gz +0 -0
  37. package/build/client/_app/immutable/nodes/{10.Bhdlxk-S.js → 11.3lkgWYOd.js} +2 -2
  38. package/build/client/_app/immutable/nodes/11.3lkgWYOd.js.br +0 -0
  39. package/build/client/_app/immutable/nodes/11.3lkgWYOd.js.gz +0 -0
  40. package/build/client/_app/immutable/nodes/12.p6ol8gkx.js +1 -0
  41. package/build/client/_app/immutable/nodes/12.p6ol8gkx.js.br +0 -0
  42. package/build/client/_app/immutable/nodes/12.p6ol8gkx.js.gz +0 -0
  43. package/build/client/_app/immutable/nodes/{2.CI-wpOC8.js → 2.DMK5rlQk.js} +2 -2
  44. package/build/client/_app/immutable/nodes/2.DMK5rlQk.js.br +0 -0
  45. package/build/client/_app/immutable/nodes/2.DMK5rlQk.js.gz +0 -0
  46. package/build/client/_app/immutable/nodes/3.BBvN4Erf.js +2 -0
  47. package/build/client/_app/immutable/nodes/3.BBvN4Erf.js.br +0 -0
  48. package/build/client/_app/immutable/nodes/3.BBvN4Erf.js.gz +0 -0
  49. package/build/client/_app/immutable/nodes/4.3VL8fZOS.js +4 -0
  50. package/build/client/_app/immutable/nodes/4.3VL8fZOS.js.br +0 -0
  51. package/build/client/_app/immutable/nodes/4.3VL8fZOS.js.gz +0 -0
  52. package/build/client/_app/immutable/nodes/5.CiNtblYV.js +2 -0
  53. package/build/client/_app/immutable/nodes/5.CiNtblYV.js.br +0 -0
  54. package/build/client/_app/immutable/nodes/5.CiNtblYV.js.gz +0 -0
  55. package/build/client/_app/immutable/nodes/6.BRCCYakl.js +5 -0
  56. package/build/client/_app/immutable/nodes/6.BRCCYakl.js.br +0 -0
  57. package/build/client/_app/immutable/nodes/6.BRCCYakl.js.gz +0 -0
  58. package/build/client/_app/immutable/nodes/7.Bn-YL1OM.js +4 -0
  59. package/build/client/_app/immutable/nodes/7.Bn-YL1OM.js.br +0 -0
  60. package/build/client/_app/immutable/nodes/7.Bn-YL1OM.js.gz +0 -0
  61. package/build/client/_app/immutable/nodes/8.CkQQuOBs.js +1 -0
  62. package/build/client/_app/immutable/nodes/8.CkQQuOBs.js.br +0 -0
  63. package/build/client/_app/immutable/nodes/8.CkQQuOBs.js.gz +0 -0
  64. package/build/client/_app/immutable/nodes/9.6KxRZbKJ.js +9 -0
  65. package/build/client/_app/immutable/nodes/9.6KxRZbKJ.js.br +0 -0
  66. package/build/client/_app/immutable/nodes/9.6KxRZbKJ.js.gz +0 -0
  67. package/build/client/_app/version.json +1 -1
  68. package/build/client/_app/version.json.br +0 -0
  69. package/build/client/_app/version.json.gz +0 -0
  70. package/build/server/chunks/{0-DWEpTDaF.js → 0-D1xG012U.js} +8 -8
  71. package/build/server/chunks/{0-DWEpTDaF.js.map → 0-D1xG012U.js.map} +1 -1
  72. package/build/server/chunks/1-B1kTzRNn.js +9 -0
  73. package/build/server/chunks/{1-B68UkVTE.js.map → 1-B1kTzRNn.js.map} +1 -1
  74. package/build/server/chunks/{9-tHCipeiW.js → 10-DahfOzGu.js} +7 -7
  75. package/build/server/chunks/10-DahfOzGu.js.map +1 -0
  76. package/build/server/chunks/11-mzYblRmm.js +9 -0
  77. package/build/server/chunks/11-mzYblRmm.js.map +1 -0
  78. package/build/server/chunks/{11-Ms74wtl9.js → 12-Dw1Y6Xen.js} +5 -5
  79. package/build/server/chunks/{11-Ms74wtl9.js.map → 12-Dw1Y6Xen.js.map} +1 -1
  80. package/build/server/chunks/{2-bmpngDVe.js → 2-Cbd6Pglj.js} +3 -3
  81. package/build/server/chunks/{2-bmpngDVe.js.map → 2-Cbd6Pglj.js.map} +1 -1
  82. package/build/server/chunks/3-DjAsck26.js +9 -0
  83. package/build/server/chunks/{3-BkezOAX7.js.map → 3-DjAsck26.js.map} +1 -1
  84. package/build/server/chunks/{4-CSfQwQwV.js → 4-CKQYCTZo.js} +5 -5
  85. package/build/server/chunks/{4-CSfQwQwV.js.map → 4-CKQYCTZo.js.map} +1 -1
  86. package/build/server/chunks/5-BDp1sX0Q.js +9 -0
  87. package/build/server/chunks/{5-D_pZV4fS.js.map → 5-BDp1sX0Q.js.map} +1 -1
  88. package/build/server/chunks/6-CUIuzy6O.js +9 -0
  89. package/build/server/chunks/{6-DcbRMrH1.js.map → 6-CUIuzy6O.js.map} +1 -1
  90. package/build/server/chunks/{7-BsMFIBGU.js → 7-BDv5_nF1.js} +6 -6
  91. package/build/server/chunks/{7-BsMFIBGU.js.map → 7-BDv5_nF1.js.map} +1 -1
  92. package/build/server/chunks/8-CspJz0xl.js +9 -0
  93. package/build/server/chunks/{8-DWleYW_e.js.map → 8-CspJz0xl.js.map} +1 -1
  94. package/build/server/chunks/9-BpgaO-rd.js +33 -0
  95. package/build/server/chunks/9-BpgaO-rd.js.map +1 -0
  96. package/build/server/chunks/{Badge-BYK3z3lr.js → Badge-DCQxSQCS.js} +2 -2
  97. package/build/server/chunks/{Badge-BYK3z3lr.js.map → Badge-DCQxSQCS.js.map} +1 -1
  98. package/build/server/chunks/{SafetyBadge-BXNCgLE-.js → SafetyBadge-BxEGojgX.js} +2 -2
  99. package/build/server/chunks/{SafetyBadge-BXNCgLE-.js.map → SafetyBadge-BxEGojgX.js.map} +1 -1
  100. package/build/server/chunks/{_layout.svelte-Cv35k3JT.js → _layout.svelte-6X0-Uv9x.js} +15 -5
  101. package/build/server/chunks/_layout.svelte-6X0-Uv9x.js.map +1 -0
  102. package/build/server/chunks/{_page.svelte-BftcSD3f.js → _page.svelte-1wUrXGW-.js} +3 -3
  103. package/build/server/chunks/{_page.svelte-BftcSD3f.js.map → _page.svelte-1wUrXGW-.js.map} +1 -1
  104. package/build/server/chunks/{_page.svelte-B-Kaw1RF.js → _page.svelte-B3CasgD8.js} +2 -2
  105. package/build/server/chunks/{_page.svelte-B-Kaw1RF.js.map → _page.svelte-B3CasgD8.js.map} +1 -1
  106. package/build/server/chunks/_page.svelte-BEU4JrAd.js +433 -0
  107. package/build/server/chunks/_page.svelte-BEU4JrAd.js.map +1 -0
  108. package/build/server/chunks/{_page.svelte-Cat8tEeF.js → _page.svelte-Bi4xsxv7.js} +4 -4
  109. package/build/server/chunks/{_page.svelte-Cat8tEeF.js.map → _page.svelte-Bi4xsxv7.js.map} +1 -1
  110. package/build/server/chunks/{_page.svelte-CIEY8g8A.js → _page.svelte-BikYFdJv.js} +4 -4
  111. package/build/server/chunks/{_page.svelte-CIEY8g8A.js.map → _page.svelte-BikYFdJv.js.map} +1 -1
  112. package/build/server/chunks/{_page.svelte-CmuUQI4Y.js → _page.svelte-Bx-fv-rO.js} +43 -20
  113. package/build/server/chunks/_page.svelte-Bx-fv-rO.js.map +1 -0
  114. package/build/server/chunks/{_page.svelte-DZX4Bixr.js → _page.svelte-CveCaqpY.js} +5 -5
  115. package/build/server/chunks/{_page.svelte-DZX4Bixr.js.map → _page.svelte-CveCaqpY.js.map} +1 -1
  116. package/build/server/chunks/{_page.svelte-DyI46sDh.js → _page.svelte-D8ffqrO3.js} +3 -3
  117. package/build/server/chunks/{_page.svelte-DyI46sDh.js.map → _page.svelte-D8ffqrO3.js.map} +1 -1
  118. package/build/server/chunks/{_page.svelte-DLQqGym0.js → _page.svelte-DNmC-yjw.js} +4 -4
  119. package/build/server/chunks/{_page.svelte-DLQqGym0.js.map → _page.svelte-DNmC-yjw.js.map} +1 -1
  120. package/build/server/chunks/{_page.svelte-DHNevyzi.js → _page.svelte-wL3fdD1l.js} +4 -4
  121. package/build/server/chunks/{_page.svelte-DHNevyzi.js.map → _page.svelte-wL3fdD1l.js.map} +1 -1
  122. package/build/server/chunks/{_page.svelte-CUnw0pLx.js → _page.svelte-xTZOj1o8.js} +3 -3
  123. package/build/server/chunks/{_page.svelte-CUnw0pLx.js.map → _page.svelte-xTZOj1o8.js.map} +1 -1
  124. package/build/server/chunks/_server.ts-BBDD0W6t.js +167 -0
  125. package/build/server/chunks/_server.ts-BBDD0W6t.js.map +1 -0
  126. package/build/server/chunks/_server.ts-BkOJmVFg.js +101 -0
  127. package/build/server/chunks/_server.ts-BkOJmVFg.js.map +1 -0
  128. package/build/server/chunks/{_server.ts-BUQYdxPs.js → _server.ts-BkcLO56D.js} +2 -2
  129. package/build/server/chunks/{_server.ts-BUQYdxPs.js.map → _server.ts-BkcLO56D.js.map} +1 -1
  130. package/build/server/chunks/{_server.ts-Dq1jAomo.js → _server.ts-C2WpZqPW.js} +4 -4
  131. package/build/server/chunks/{_server.ts-Dq1jAomo.js.map → _server.ts-C2WpZqPW.js.map} +1 -1
  132. package/build/server/chunks/{_server.ts-5396UuLQ.js → _server.ts-CKn8ym8s.js} +2 -2
  133. package/build/server/chunks/{_server.ts-5396UuLQ.js.map → _server.ts-CKn8ym8s.js.map} +1 -1
  134. package/build/server/chunks/{_server.ts-DHt1bGpF.js → _server.ts-CaVH9FSD.js} +4 -4
  135. package/build/server/chunks/{_server.ts-DHt1bGpF.js.map → _server.ts-CaVH9FSD.js.map} +1 -1
  136. package/build/server/chunks/_server.ts-D7iLlRbM.js +337 -0
  137. package/build/server/chunks/_server.ts-D7iLlRbM.js.map +1 -0
  138. package/build/server/chunks/_server.ts-DPqZOGG_.js +18 -0
  139. package/build/server/chunks/_server.ts-DPqZOGG_.js.map +1 -0
  140. package/build/server/chunks/{_server.ts-sMKRiXFg.js → _server.ts-Dz9oKgWc.js} +5 -5
  141. package/build/server/chunks/{_server.ts-sMKRiXFg.js.map → _server.ts-Dz9oKgWc.js.map} +1 -1
  142. package/build/server/chunks/{_server.ts-CvdpZfED.js → _server.ts-fVP0SuTW.js} +2 -2
  143. package/build/server/chunks/{_server.ts-CvdpZfED.js.map → _server.ts-fVP0SuTW.js.map} +1 -1
  144. package/build/server/chunks/{client-92HF3fc9.js → client-CydontyB.js} +3 -3
  145. package/build/server/chunks/{client-92HF3fc9.js.map → client-CydontyB.js.map} +1 -1
  146. package/build/server/chunks/{dev-Duv_-rxF.js → dev-BdIdjvaY.js} +216 -82
  147. package/build/server/chunks/dev-BdIdjvaY.js.map +1 -0
  148. package/build/server/chunks/{doctorSummary-Bm0dY6PW.js → doctorSummary-BOtGdd9z.js} +3 -3
  149. package/build/server/chunks/{doctorSummary-Bm0dY6PW.js.map → doctorSummary-BOtGdd9z.js.map} +1 -1
  150. package/build/server/chunks/{error.svelte-BEI8QxGW.js → error.svelte-_CDx8UPv.js} +4 -4
  151. package/build/server/chunks/{error.svelte-BEI8QxGW.js.map → error.svelte-_CDx8UPv.js.map} +1 -1
  152. package/build/server/chunks/{hooks.server-BKavEpqC.js → hooks.server-Dva4z7fv.js} +35 -1
  153. package/build/server/chunks/hooks.server-Dva4z7fv.js.map +1 -0
  154. package/build/server/chunks/{internal-DBeni9My.js → internal-DyPeC3rk.js} +21 -16
  155. package/build/server/chunks/internal-DyPeC3rk.js.map +1 -0
  156. package/build/server/chunks/{marketingSeo-Do5o0grg.js → marketingSeo-CugwK52J.js} +2 -2
  157. package/build/server/chunks/{marketingSeo-Do5o0grg.js.map → marketingSeo-CugwK52J.js.map} +1 -1
  158. package/build/server/chunks/migrationReport-f6NoxAVZ.js +40 -0
  159. package/build/server/chunks/migrationReport-f6NoxAVZ.js.map +1 -0
  160. package/build/server/chunks/{profileApiHelpers-BFzohffv.js → profileApiHelpers-DCoI7zMU.js} +3 -3
  161. package/build/server/chunks/{profileApiHelpers-BFzohffv.js.map → profileApiHelpers-DCoI7zMU.js.map} +1 -1
  162. package/build/server/chunks/{projectContext-Cxsfz84C.js → projectContext-B1D-bieW.js} +2439 -127
  163. package/build/server/chunks/projectContext-B1D-bieW.js.map +1 -0
  164. package/build/server/chunks/{src2-DNqJAXv6.js → src2-BtraGDB1.js} +2 -2
  165. package/build/server/chunks/src2-BtraGDB1.js.map +1 -0
  166. package/build/server/chunks/{src3-jm480tTA.js → src3-BXch_OaJ.js} +347 -10
  167. package/build/server/chunks/src3-BXch_OaJ.js.map +1 -0
  168. package/build/server/chunks/{tokenStore-DQfTa-N3.js → tokenStore-CTHhmHsk.js} +30 -2
  169. package/build/server/chunks/tokenStore-CTHhmHsk.js.map +1 -0
  170. package/build/server/index.js +4 -5
  171. package/build/server/index.js.map +1 -1
  172. package/build/server/manifest.js +58 -22
  173. package/build/server/manifest.js.map +1 -1
  174. package/package.json +7 -7
  175. package/build/client/_app/immutable/chunks/6SrQtk22.js +0 -3
  176. package/build/client/_app/immutable/chunks/6SrQtk22.js.br +0 -0
  177. package/build/client/_app/immutable/chunks/6SrQtk22.js.gz +0 -0
  178. package/build/client/_app/immutable/chunks/B1X0Iqjr.js +0 -3
  179. package/build/client/_app/immutable/chunks/B1X0Iqjr.js.br +0 -0
  180. package/build/client/_app/immutable/chunks/B1X0Iqjr.js.gz +0 -0
  181. package/build/client/_app/immutable/chunks/BN4Ca4cJ.js +0 -1
  182. package/build/client/_app/immutable/chunks/BN4Ca4cJ.js.br +0 -0
  183. package/build/client/_app/immutable/chunks/BN4Ca4cJ.js.gz +0 -0
  184. package/build/client/_app/immutable/chunks/BYeYmN2n.js +0 -1
  185. package/build/client/_app/immutable/chunks/BYeYmN2n.js.br +0 -2
  186. package/build/client/_app/immutable/chunks/BYeYmN2n.js.gz +0 -0
  187. package/build/client/_app/immutable/chunks/D0_SwbnT.js +0 -2
  188. package/build/client/_app/immutable/chunks/D0_SwbnT.js.br +0 -0
  189. package/build/client/_app/immutable/chunks/D0_SwbnT.js.gz +0 -0
  190. package/build/client/_app/immutable/chunks/DRoN73NW.js +0 -1
  191. package/build/client/_app/immutable/chunks/DRoN73NW.js.br +0 -2
  192. package/build/client/_app/immutable/chunks/DRoN73NW.js.gz +0 -0
  193. package/build/client/_app/immutable/entry/app.B45QQayJ.js +0 -2
  194. package/build/client/_app/immutable/entry/app.B45QQayJ.js.br +0 -0
  195. package/build/client/_app/immutable/entry/app.B45QQayJ.js.gz +0 -0
  196. package/build/client/_app/immutable/entry/start.BIlQ_snM.js +0 -1
  197. package/build/client/_app/immutable/entry/start.BIlQ_snM.js.br +0 -0
  198. package/build/client/_app/immutable/entry/start.BIlQ_snM.js.gz +0 -0
  199. package/build/client/_app/immutable/nodes/0.JRffyfUR.js +0 -1
  200. package/build/client/_app/immutable/nodes/0.JRffyfUR.js.br +0 -0
  201. package/build/client/_app/immutable/nodes/0.JRffyfUR.js.gz +0 -0
  202. package/build/client/_app/immutable/nodes/1.56EgwKsF.js +0 -1
  203. package/build/client/_app/immutable/nodes/1.56EgwKsF.js.br +0 -0
  204. package/build/client/_app/immutable/nodes/1.56EgwKsF.js.gz +0 -0
  205. package/build/client/_app/immutable/nodes/10.Bhdlxk-S.js.br +0 -0
  206. package/build/client/_app/immutable/nodes/10.Bhdlxk-S.js.gz +0 -0
  207. package/build/client/_app/immutable/nodes/11.DAqRx2TI.js +0 -1
  208. package/build/client/_app/immutable/nodes/11.DAqRx2TI.js.br +0 -0
  209. package/build/client/_app/immutable/nodes/11.DAqRx2TI.js.gz +0 -0
  210. package/build/client/_app/immutable/nodes/2.CI-wpOC8.js.br +0 -0
  211. package/build/client/_app/immutable/nodes/2.CI-wpOC8.js.gz +0 -0
  212. package/build/client/_app/immutable/nodes/3.Bphawycs.js +0 -2
  213. package/build/client/_app/immutable/nodes/3.Bphawycs.js.br +0 -0
  214. package/build/client/_app/immutable/nodes/3.Bphawycs.js.gz +0 -0
  215. package/build/client/_app/immutable/nodes/4.BGFkNM65.js +0 -4
  216. package/build/client/_app/immutable/nodes/4.BGFkNM65.js.br +0 -0
  217. package/build/client/_app/immutable/nodes/4.BGFkNM65.js.gz +0 -0
  218. package/build/client/_app/immutable/nodes/5.VTs5grF0.js +0 -2
  219. package/build/client/_app/immutable/nodes/5.VTs5grF0.js.br +0 -0
  220. package/build/client/_app/immutable/nodes/5.VTs5grF0.js.gz +0 -0
  221. package/build/client/_app/immutable/nodes/6.CndSdLIk.js +0 -5
  222. package/build/client/_app/immutable/nodes/6.CndSdLIk.js.br +0 -0
  223. package/build/client/_app/immutable/nodes/6.CndSdLIk.js.gz +0 -0
  224. package/build/client/_app/immutable/nodes/7.DpFk4StA.js +0 -4
  225. package/build/client/_app/immutable/nodes/7.DpFk4StA.js.br +0 -0
  226. package/build/client/_app/immutable/nodes/7.DpFk4StA.js.gz +0 -0
  227. package/build/client/_app/immutable/nodes/8.Y7A99ODL.js +0 -1
  228. package/build/client/_app/immutable/nodes/8.Y7A99ODL.js.br +0 -0
  229. package/build/client/_app/immutable/nodes/8.Y7A99ODL.js.gz +0 -0
  230. package/build/client/_app/immutable/nodes/9.DF3LeTGi.js +0 -3
  231. package/build/client/_app/immutable/nodes/9.DF3LeTGi.js.br +0 -0
  232. package/build/client/_app/immutable/nodes/9.DF3LeTGi.js.gz +0 -0
  233. package/build/server/chunks/1-B68UkVTE.js +0 -9
  234. package/build/server/chunks/10-D7op0myD.js +0 -9
  235. package/build/server/chunks/10-D7op0myD.js.map +0 -1
  236. package/build/server/chunks/3-BkezOAX7.js +0 -9
  237. package/build/server/chunks/5-D_pZV4fS.js +0 -9
  238. package/build/server/chunks/6-DcbRMrH1.js +0 -9
  239. package/build/server/chunks/8-DWleYW_e.js +0 -9
  240. package/build/server/chunks/9-tHCipeiW.js.map +0 -1
  241. package/build/server/chunks/_layout.svelte-Cv35k3JT.js.map +0 -1
  242. package/build/server/chunks/_page.svelte-CmuUQI4Y.js.map +0 -1
  243. package/build/server/chunks/dev-Duv_-rxF.js.map +0 -1
  244. package/build/server/chunks/hooks.server-BKavEpqC.js.map +0 -1
  245. package/build/server/chunks/internal-DBeni9My.js.map +0 -1
  246. package/build/server/chunks/projectContext-Cxsfz84C.js.map +0 -1
  247. package/build/server/chunks/src2-DNqJAXv6.js.map +0 -1
  248. package/build/server/chunks/src3-jm480tTA.js.map +0 -1
  249. package/build/server/chunks/tokenStore-DQfTa-N3.js.map +0 -1
  250. /package/build/client/_app/immutable/assets/{9.BsbC-D7w.css → 10.BsbC-D7w.css} +0 -0
  251. /package/build/client/_app/immutable/assets/{9.BsbC-D7w.css.br → 10.BsbC-D7w.css.br} +0 -0
  252. /package/build/client/_app/immutable/assets/{9.BsbC-D7w.css.gz → 10.BsbC-D7w.css.gz} +0 -0
  253. /package/build/client/_app/immutable/chunks/{I8rQr1kY.js → CP97kCR3.js} +0 -0
  254. /package/build/client/_app/immutable/chunks/{I8rQr1kY.js.br → CP97kCR3.js.br} +0 -0
  255. /package/build/client/_app/immutable/chunks/{I8rQr1kY.js.gz → CP97kCR3.js.gz} +0 -0
  256. /package/build/client/_app/immutable/chunks/{BFYQcBYR.js → O6-aNYLC.js} +0 -0
  257. /package/build/client/_app/immutable/chunks/{BFYQcBYR.js.br → O6-aNYLC.js.br} +0 -0
  258. /package/build/client/_app/immutable/chunks/{BFYQcBYR.js.gz → O6-aNYLC.js.gz} +0 -0
@@ -16222,9 +16222,22 @@ var ai_profile_schema_default = {
16222
16222
  "properties": {
16223
16223
  "sdd": { "type": "boolean" },
16224
16224
  "tdd": { "type": "boolean" },
16225
- "finalReview": { "type": "boolean" }
16225
+ "finalReview": { "type": "boolean" },
16226
+ "codeReview": { "type": "boolean" },
16227
+ "refactoring": { "type": "boolean" },
16228
+ "documentation": { "type": "boolean" },
16229
+ "subagentDrivenDevelopment": { "type": "boolean" }
16226
16230
  }
16227
16231
  },
16232
+ "capabilities": {
16233
+ "type": "object",
16234
+ "additionalProperties": false,
16235
+ "properties": { "delegation": {
16236
+ "type": "object",
16237
+ "additionalProperties": false,
16238
+ "properties": { "subagents": { "$ref": "#/definitions/subagents" } }
16239
+ } }
16240
+ },
16228
16241
  "permissions": {
16229
16242
  "type": "object",
16230
16243
  "additionalProperties": false,
@@ -16310,11 +16323,315 @@ var ai_profile_schema_default = {
16310
16323
  "minItems": 1,
16311
16324
  "uniqueItems": true,
16312
16325
  "items": { "$ref": "#/definitions/slug" }
16326
+ },
16327
+ "subagents": {
16328
+ "type": "object",
16329
+ "additionalProperties": false,
16330
+ "required": ["enabled"],
16331
+ "properties": {
16332
+ "enabled": { "type": "boolean" },
16333
+ "defaults": {
16334
+ "type": "object",
16335
+ "additionalProperties": false,
16336
+ "properties": {
16337
+ "maxConcurrent": {
16338
+ "type": "integer",
16339
+ "minimum": 1
16340
+ },
16341
+ "maxDepth": {
16342
+ "type": "integer",
16343
+ "minimum": 1
16344
+ }
16345
+ }
16346
+ },
16347
+ "agents": {
16348
+ "type": "array",
16349
+ "items": { "$ref": "#/definitions/subagent" }
16350
+ }
16351
+ },
16352
+ "if": {
16353
+ "properties": { "enabled": { "const": true } },
16354
+ "required": ["enabled"]
16355
+ },
16356
+ "then": {
16357
+ "required": ["agents"],
16358
+ "properties": { "agents": {
16359
+ "type": "array",
16360
+ "minItems": 1,
16361
+ "items": { "$ref": "#/definitions/subagent" }
16362
+ } }
16363
+ }
16364
+ },
16365
+ "subagent": { "oneOf": [{ "$ref": "#/definitions/subagentTemplateRef" }, { "$ref": "#/definitions/subagentInline" }] },
16366
+ "subagentTemplateRef": {
16367
+ "type": "object",
16368
+ "additionalProperties": false,
16369
+ "required": ["useTemplate"],
16370
+ "properties": { "useTemplate": {
16371
+ "type": "string",
16372
+ "enum": [
16373
+ "implementer",
16374
+ "spec-reviewer",
16375
+ "code-quality-reviewer"
16376
+ ]
16377
+ } }
16378
+ },
16379
+ "subagentInline": {
16380
+ "type": "object",
16381
+ "additionalProperties": false,
16382
+ "required": [
16383
+ "name",
16384
+ "description",
16385
+ "purpose",
16386
+ "prompt",
16387
+ "toolScope"
16388
+ ],
16389
+ "properties": {
16390
+ "name": {
16391
+ "type": "string",
16392
+ "minLength": 1,
16393
+ "pattern": "^[a-z0-9][a-z0-9-]*$",
16394
+ "not": { "enum": [
16395
+ "default",
16396
+ "worker",
16397
+ "explorer",
16398
+ "explore",
16399
+ "plan",
16400
+ "general-purpose",
16401
+ "codebase_investigator",
16402
+ "remote-codebase-investigator",
16403
+ "generalist",
16404
+ "browser_agent"
16405
+ ] }
16406
+ },
16407
+ "description": {
16408
+ "type": "string",
16409
+ "minLength": 1,
16410
+ "pattern": "^[^\\r\\n]+$"
16411
+ },
16412
+ "purpose": {
16413
+ "type": "string",
16414
+ "minLength": 1,
16415
+ "pattern": "^[^\\r\\n]+$"
16416
+ },
16417
+ "prompt": {
16418
+ "type": "string",
16419
+ "minLength": 1
16420
+ },
16421
+ "toolScope": {
16422
+ "type": "string",
16423
+ "enum": ["read-only", "workspace-write"]
16424
+ },
16425
+ "modelPreference": {
16426
+ "type": "string",
16427
+ "enum": [
16428
+ "inherit",
16429
+ "fast",
16430
+ "balanced",
16431
+ "capable"
16432
+ ]
16433
+ },
16434
+ "maxTurns": {
16435
+ "type": "integer",
16436
+ "minimum": 1
16437
+ },
16438
+ "timeoutMinutes": {
16439
+ "type": "integer",
16440
+ "minimum": 1
16441
+ },
16442
+ "mcpServers": {
16443
+ "type": "array",
16444
+ "items": { "type": "string" },
16445
+ "maxItems": 0
16446
+ }
16447
+ }
16313
16448
  }
16314
16449
  }
16315
16450
  };
16316
16451
  //#endregion
16317
16452
  //#region ../../packages/core/src/profile.ts
16453
+ var SUBAGENT_TEMPLATE_NAMES = [
16454
+ "implementer",
16455
+ "spec-reviewer",
16456
+ "code-quality-reviewer"
16457
+ ];
16458
+ function isSubagentTemplateRef(entry) {
16459
+ return typeof entry.useTemplate === "string";
16460
+ }
16461
+ function freezeTemplate(template) {
16462
+ if (template.mcpServers !== void 0) Object.freeze(template.mcpServers);
16463
+ return Object.freeze(template);
16464
+ }
16465
+ function cloneTemplate(template) {
16466
+ const clone = {
16467
+ name: template.name,
16468
+ description: template.description,
16469
+ purpose: template.purpose,
16470
+ prompt: template.prompt,
16471
+ toolScope: template.toolScope
16472
+ };
16473
+ if (template.modelPreference !== void 0) clone.modelPreference = template.modelPreference;
16474
+ if (template.maxTurns !== void 0) clone.maxTurns = template.maxTurns;
16475
+ if (template.timeoutMinutes !== void 0) clone.timeoutMinutes = template.timeoutMinutes;
16476
+ if (template.mcpServers !== void 0) clone.mcpServers = [...template.mcpServers];
16477
+ return clone;
16478
+ }
16479
+ var SUBAGENT_TEMPLATES_RAW = {
16480
+ implementer: {
16481
+ name: "implementer",
16482
+ description: "Use for a bounded implementation task after the parent agent has provided the full task text, relevant spec excerpts, file ownership, constraints, and expected tests. Returns an explicit status and does not commit or push unless the parent request includes that requirement.",
16483
+ purpose: "Implement one scoped task with tests, self-review, and honest escalation when requirements or architecture are unclear.",
16484
+ prompt: `You are implementing one bounded task.
16485
+
16486
+ Work only from the task text, spec excerpts, file ownership, constraints,
16487
+ and allowed commands provided in the prompt. Do not assume hidden chat
16488
+ history. If essential context is missing, report NEEDS_CONTEXT instead of
16489
+ guessing.
16490
+
16491
+ Before editing, restate the goal, non-goals, acceptance criteria, and files
16492
+ you expect to touch. If the task is ambiguous, architectural, or broader than
16493
+ the prompt says, stop and report BLOCKED or NEEDS_CONTEXT.
16494
+
16495
+ Implement exactly what the task specifies. Follow the repository's SDD/TDD
16496
+ workflow. Add or update focused tests where practical, verify RED before
16497
+ behavior changes when the task changes behavior, implement the smallest
16498
+ passing change, then verify GREEN. Preserve existing patterns and avoid
16499
+ unrelated refactors.
16500
+
16501
+ Do not commit, push, create branches, install dependencies, access secrets,
16502
+ contact production systems, or upload source unless the parent prompt
16503
+ explicitly authorizes that action.
16504
+
16505
+ Before reporting back, self-review for completeness, quality, scope control,
16506
+ and test validity. Fix issues you find if they are inside the assigned scope.
16507
+
16508
+ Report exactly:
16509
+ - Status: DONE | DONE_WITH_CONCERNS | BLOCKED | NEEDS_CONTEXT
16510
+ - What changed
16511
+ - Tests run and results
16512
+ - Files changed
16513
+ - Self-review findings
16514
+ - Concerns, missing context, or follow-up work`,
16515
+ toolScope: "workspace-write",
16516
+ modelPreference: "balanced",
16517
+ maxTurns: 18,
16518
+ timeoutMinutes: 20,
16519
+ mcpServers: []
16520
+ },
16521
+ "spec-reviewer": {
16522
+ name: "spec-reviewer",
16523
+ description: "Use after an implementation worker reports DONE or DONE_WITH_CONCERNS to verify the actual changed files against the task text, approved spec, acceptance criteria, and claimed result. Reads code and docs only; does not edit.",
16524
+ purpose: "Catch missing requirements, extra scope, and misunderstandings before code-quality review.",
16525
+ prompt: `You are reviewing whether an implementation matches its specification.
16526
+
16527
+ Work only from the full task text, approved spec excerpts, acceptance
16528
+ criteria, changed-file list, and implementer report provided in the prompt.
16529
+ Do not assume hidden chat history and do not trust the implementer report
16530
+ without checking the actual files.
16531
+
16532
+ Read the changed code and documentation. Compare actual behavior against the
16533
+ requested behavior line by line. Look for missing requirements, extra
16534
+ unrequested work, changed contracts, wrong interpretation, and fixture or
16535
+ documentation drift.
16536
+
16537
+ Do not edit files, run broad commands, install dependencies, read secrets,
16538
+ contact production systems, or upload source. If the prompt lacks enough
16539
+ context to review, report NEEDS_CONTEXT.
16540
+
16541
+ Report exactly:
16542
+ - Status: COMPLIANT | ISSUES_FOUND | NEEDS_CONTEXT
16543
+ - Requirements checked
16544
+ - Findings with severity, path, and line or symbol when available
16545
+ - Extra or out-of-scope work, if any
16546
+ - Missing tests or docs tied to acceptance criteria
16547
+ - Recommendation: proceed to code-quality review, fix first, or request context`,
16548
+ toolScope: "read-only",
16549
+ modelPreference: "capable",
16550
+ maxTurns: 10,
16551
+ timeoutMinutes: 8,
16552
+ mcpServers: []
16553
+ },
16554
+ "code-quality-reviewer": {
16555
+ name: "code-quality-reviewer",
16556
+ description: "Use only after spec review passes to assess maintainability, decomposition, tests, naming, risky mocks, and local code quality in the changed files. Reads code and docs only; does not edit.",
16557
+ purpose: "Catch maintainability and test-quality risks after the implementation is known to match the spec.",
16558
+ prompt: `You are reviewing code quality after spec compliance has passed.
16559
+
16560
+ Work only from the full task text, approved spec excerpts, changed-file list,
16561
+ spec-review result, test results, and implementer report provided in the
16562
+ prompt. Do not assume hidden chat history.
16563
+
16564
+ Review only the change's contribution. Do not flag pre-existing file size or
16565
+ architecture unless the change makes it materially worse. Check whether each
16566
+ touched file has a clear responsibility, whether names describe intent,
16567
+ whether complex predicates should be named, whether tests verify behavior
16568
+ rather than mocks, whether mocks preserve required real side effects, and
16569
+ whether new APIs exist only for tests.
16570
+
16571
+ Do not edit files, run broad commands, install dependencies, read secrets,
16572
+ contact production systems, or upload source. If the prompt lacks enough
16573
+ context to review, report NEEDS_CONTEXT.
16574
+
16575
+ Report exactly:
16576
+ - Status: ACCEPTABLE | ISSUES_FOUND | NEEDS_CONTEXT
16577
+ - Strengths
16578
+ - Issues grouped as Critical, Important, or Minor
16579
+ - Test-quality concerns
16580
+ - Maintainability concerns
16581
+ - Assessment: ready, fix first, or request context`,
16582
+ toolScope: "read-only",
16583
+ modelPreference: "capable",
16584
+ maxTurns: 10,
16585
+ timeoutMinutes: 8,
16586
+ mcpServers: []
16587
+ }
16588
+ };
16589
+ var SUBAGENT_TEMPLATES = {
16590
+ implementer: freezeTemplate(SUBAGENT_TEMPLATES_RAW.implementer),
16591
+ "spec-reviewer": freezeTemplate(SUBAGENT_TEMPLATES_RAW["spec-reviewer"]),
16592
+ "code-quality-reviewer": freezeTemplate(SUBAGENT_TEMPLATES_RAW["code-quality-reviewer"])
16593
+ };
16594
+ function expandSubagentEntry(entry) {
16595
+ if (isSubagentTemplateRef(entry)) return cloneTemplate(SUBAGENT_TEMPLATES[entry.useTemplate]);
16596
+ return entry;
16597
+ }
16598
+ function getSubagentTemplateRefs(profile) {
16599
+ const block = profile.capabilities?.delegation?.subagents;
16600
+ if (!block || block.enabled !== true) return [];
16601
+ const refs = [];
16602
+ for (const entry of block.agents ?? []) if (isSubagentTemplateRef(entry)) refs.push(entry.useTemplate);
16603
+ return refs;
16604
+ }
16605
+ function normalizeSubagentName(name) {
16606
+ return name.toLowerCase().replace(/_/gu, "-");
16607
+ }
16608
+ function getSubagentDefaults(profile) {
16609
+ const defaults = profile.capabilities?.delegation?.subagents?.defaults;
16610
+ return {
16611
+ maxConcurrent: defaults?.maxConcurrent ?? 3,
16612
+ maxDepth: defaults?.maxDepth ?? 1
16613
+ };
16614
+ }
16615
+ function getEnabledSubagents(profile) {
16616
+ const block = profile.capabilities?.delegation?.subagents;
16617
+ if (!block || block.enabled !== true) return [];
16618
+ return (block.agents ?? []).map((entry) => expandSubagentEntry(entry));
16619
+ }
16620
+ var SUBAGENT_BUILTIN_NAMES_NORMALIZED = new Set([
16621
+ "default",
16622
+ "worker",
16623
+ "explorer",
16624
+ "explore",
16625
+ "plan",
16626
+ "general-purpose",
16627
+ "codebase-investigator",
16628
+ "remote-codebase-investigator",
16629
+ "generalist",
16630
+ "browser-agent"
16631
+ ]);
16632
+ function isSubagentBuiltinNameCollision(name) {
16633
+ return SUBAGENT_BUILTIN_NAMES_NORMALIZED.has(normalizeSubagentName(name));
16634
+ }
16318
16635
  var compiledValidator;
16319
16636
  var DEFAULT_SAFETY = {
16320
16637
  mode: "guarded",
@@ -16398,6 +16715,11 @@ function validateProfileValue(value) {
16398
16715
  const validate = getValidator();
16399
16716
  if (validate(value)) {
16400
16717
  const profile = value;
16718
+ const subagentIssues = validateSubagentSemantics(profile);
16719
+ if (subagentIssues.length > 0) return {
16720
+ ok: false,
16721
+ issues: subagentIssues.sort((left, right) => compareIssues$1(left, right))
16722
+ };
16401
16723
  return {
16402
16724
  ok: true,
16403
16725
  profile,
@@ -16410,6 +16732,38 @@ function validateProfileValue(value) {
16410
16732
  issues: toValidationIssues(validate.errors ?? [], value)
16411
16733
  };
16412
16734
  }
16735
+ function validateSubagentSemantics(profile) {
16736
+ const subagents = profile.capabilities?.delegation?.subagents;
16737
+ if (!subagents || subagents.enabled !== true) return [];
16738
+ const entries = subagents.agents ?? [];
16739
+ const issues = [];
16740
+ const seenRaw = /* @__PURE__ */ new Map();
16741
+ const seenNormalized = /* @__PURE__ */ new Map();
16742
+ entries.forEach((entry, index) => {
16743
+ const name = expandSubagentEntry(entry).name;
16744
+ const rawIndex = seenRaw.get(name);
16745
+ if (rawIndex !== void 0) issues.push({
16746
+ code: "schema_validation_error",
16747
+ path: `/capabilities/delegation/subagents/agents/${index}/name`,
16748
+ expected: "unique subagent name",
16749
+ actual: "duplicate",
16750
+ message: `/capabilities/delegation/subagents/agents/${index}/name duplicates the name used at index ${rawIndex}.`
16751
+ });
16752
+ else seenRaw.set(name, index);
16753
+ const normalized = normalizeSubagentName(name);
16754
+ const normalizedIndex = seenNormalized.get(normalized);
16755
+ if (normalizedIndex !== void 0 && normalizedIndex !== index) {
16756
+ if (!(rawIndex !== void 0)) issues.push({
16757
+ code: "schema_validation_error",
16758
+ path: `/capabilities/delegation/subagents/agents/${index}/name`,
16759
+ expected: "unique normalized subagent id",
16760
+ actual: "duplicate after hyphen/underscore folding",
16761
+ message: `/capabilities/delegation/subagents/agents/${index}/name collides with the name used at index ${normalizedIndex} after normalization.`
16762
+ });
16763
+ } else if (normalizedIndex === void 0) seenNormalized.set(normalized, index);
16764
+ });
16765
+ return issues;
16766
+ }
16413
16767
  function normalizeSafety(profile) {
16414
16768
  return {
16415
16769
  mode: profile.safety?.mode ?? DEFAULT_SAFETY.mode,
@@ -16449,11 +16803,17 @@ function renderProfileYaml(profile) {
16449
16803
  if (profile.safety.requiresSandbox !== void 0) safety["requiresSandbox"] = profile.safety.requiresSandbox;
16450
16804
  doc["safety"] = safety;
16451
16805
  }
16452
- doc["workflow"] = {
16806
+ const workflow = {
16453
16807
  sdd: profile.workflow.sdd,
16454
16808
  tdd: profile.workflow.tdd,
16455
16809
  finalReview: profile.workflow.finalReview
16456
16810
  };
16811
+ if (profile.workflow.codeReview !== void 0) workflow["codeReview"] = profile.workflow.codeReview;
16812
+ if (profile.workflow.refactoring !== void 0) workflow["refactoring"] = profile.workflow.refactoring;
16813
+ if (profile.workflow.documentation !== void 0) workflow["documentation"] = profile.workflow.documentation;
16814
+ if (profile.workflow.subagentDrivenDevelopment !== void 0) workflow["subagentDrivenDevelopment"] = profile.workflow.subagentDrivenDevelopment;
16815
+ doc["workflow"] = workflow;
16816
+ if (profile.capabilities !== void 0) doc["capabilities"] = buildCapabilitiesDoc(profile.capabilities);
16457
16817
  if (profile.permissions !== void 0) doc["permissions"] = buildPermissionsDoc(profile.permissions);
16458
16818
  return distExports.stringify(doc, {
16459
16819
  lineWidth: 0,
@@ -16461,6 +16821,40 @@ function renderProfileYaml(profile) {
16461
16821
  sortMapEntries: false
16462
16822
  }).replace(/\n+$/, "") + "\n";
16463
16823
  }
16824
+ function buildCapabilitiesDoc(capabilities) {
16825
+ const doc = {};
16826
+ if (capabilities.delegation !== void 0) {
16827
+ const delegation = {};
16828
+ const subagents = capabilities.delegation.subagents;
16829
+ if (subagents !== void 0) {
16830
+ const block = { enabled: subagents.enabled };
16831
+ if (subagents.defaults !== void 0) {
16832
+ const defaults = {};
16833
+ if (subagents.defaults.maxConcurrent !== void 0) defaults["maxConcurrent"] = subagents.defaults.maxConcurrent;
16834
+ if (subagents.defaults.maxDepth !== void 0) defaults["maxDepth"] = subagents.defaults.maxDepth;
16835
+ if (Object.keys(defaults).length > 0) block["defaults"] = defaults;
16836
+ }
16837
+ if (subagents.agents !== void 0) block["agents"] = subagents.agents.map((entry) => isSubagentTemplateRef(entry) ? { useTemplate: entry.useTemplate } : buildSubagentDoc(entry));
16838
+ delegation["subagents"] = block;
16839
+ }
16840
+ if (Object.keys(delegation).length > 0) doc["delegation"] = delegation;
16841
+ }
16842
+ return doc;
16843
+ }
16844
+ function buildSubagentDoc(agent) {
16845
+ const out = {
16846
+ name: agent.name,
16847
+ description: agent.description,
16848
+ purpose: agent.purpose,
16849
+ prompt: agent.prompt,
16850
+ toolScope: agent.toolScope
16851
+ };
16852
+ if (agent.modelPreference !== void 0) out["modelPreference"] = agent.modelPreference;
16853
+ if (agent.maxTurns !== void 0) out["maxTurns"] = agent.maxTurns;
16854
+ if (agent.timeoutMinutes !== void 0) out["timeoutMinutes"] = agent.timeoutMinutes;
16855
+ if (agent.mcpServers !== void 0) out["mcpServers"] = agent.mcpServers;
16856
+ return out;
16857
+ }
16464
16858
  function buildPermissionsDoc(p) {
16465
16859
  const doc = {};
16466
16860
  if (p.filesystem !== void 0) {
@@ -16654,12 +17048,15 @@ function getDefaultTargetIds() {
16654
17048
  "lockfile",
16655
17049
  "tabnine-guidelines",
16656
17050
  "tabnine-mcp-config",
17051
+ "tabnine-subagents",
16657
17052
  "codex-config",
16658
17053
  "codex-workflow-skills",
17054
+ "codex-subagents",
16659
17055
  "claude-settings",
16660
17056
  "claude-mcp",
16661
17057
  "claude-md",
16662
- "claude-workflow-skills"
17058
+ "claude-workflow-skills",
17059
+ "claude-subagents"
16663
17060
  ];
16664
17061
  }
16665
17062
  function createGeneratedTextFile(path, target, templateId, text) {
@@ -16694,17 +17091,20 @@ function compareText(left, right) {
16694
17091
  }
16695
17092
  //#endregion
16696
17093
  //#region ../../packages/compiler/src/lockfile.ts
17094
+ var SUPPORTED_VERSIONS = new Set([1, 2]);
16697
17095
  function buildLockfile(input) {
17096
+ const profilePath = safeOutputPath(input.profilePath ?? "ai-profile.yaml");
17097
+ const mixedByPath = new Map((input.mixedOutputs ?? []).map((entry) => [safeOutputPath(entry.path), entry]));
16698
17098
  return {
16699
- version: 1,
17099
+ version: 2,
16700
17100
  profile: {
16701
- path: safeOutputPath(input.profilePath ?? "ai-profile.yaml"),
17101
+ path: profilePath,
16702
17102
  schemaVersion: 1,
16703
17103
  sha256: sha256Hex(input.profileBytes)
16704
17104
  },
16705
17105
  compiler: input.compiler ?? AGENT_PROFILE_COMPILER,
16706
17106
  templates: input.templates.map(toLockTemplate).sort(compareLockTemplates),
16707
- outputs: input.files.map(toLockOutput).sort(compareLockOutputs)
17107
+ outputs: input.files.map((file) => toLockOutputV2(file, mixedByPath)).sort(compareLockOutputsV2)
16708
17108
  };
16709
17109
  }
16710
17110
  function serializeLockfile(lockfile) {
@@ -16713,6 +17113,28 @@ function serializeLockfile(lockfile) {
16713
17113
  function createLockfileFile(input) {
16714
17114
  return createGeneratedTextFile("ai-profile.lock", "lockfile", "targets/lockfile@1", serializeLockfile(buildLockfile(input)));
16715
17115
  }
17116
+ /**
17117
+ * Migrate a parsed v1 lockfile to v2 by promoting every v1 output to
17118
+ * `generated-owned`. Order, hashes, target, and template ids are copied
17119
+ * unchanged. The migration is deterministic and idempotent: calling it on the
17120
+ * result of `buildLockfile(input)` for the same inputs produces byte-identical
17121
+ * v2 bytes.
17122
+ */
17123
+ function migrateLockfileV1ToV2(lockfile) {
17124
+ return {
17125
+ version: 2,
17126
+ profile: lockfile.profile,
17127
+ compiler: lockfile.compiler,
17128
+ templates: [...lockfile.templates].sort(compareLockTemplates),
17129
+ outputs: lockfile.outputs.map((output) => ({
17130
+ path: output.path,
17131
+ target: output.target,
17132
+ templateId: output.templateId,
17133
+ ownership: "generated-owned",
17134
+ sha256: output.sha256
17135
+ })).sort(compareLockOutputsV2)
17136
+ };
17137
+ }
16716
17138
  function validateLockfileText(source) {
16717
17139
  try {
16718
17140
  return validateLockfileValue(JSON.parse(source));
@@ -16731,14 +17153,48 @@ function validateLockfileText(source) {
16731
17153
  }
16732
17154
  function validateLockfileValue(value) {
16733
17155
  const issues = [];
16734
- validateLockfileObject(value, issues);
17156
+ if (!isRecord(value)) {
17157
+ issues.push(schemaIssue("/", "object", describeValue(value)));
17158
+ return {
17159
+ ok: false,
17160
+ issues
17161
+ };
17162
+ }
17163
+ const version = value.version;
17164
+ if (typeof version !== "number" || !SUPPORTED_VERSIONS.has(version)) {
17165
+ issues.push({
17166
+ code: "lockfile_unsupported_version",
17167
+ path: "/version",
17168
+ expected: "supported lockfile version (1 or 2)",
17169
+ actual: describeValue(version),
17170
+ message: `/version is not a supported lockfile version.`
17171
+ });
17172
+ return {
17173
+ ok: false,
17174
+ issues
17175
+ };
17176
+ }
17177
+ if (version === 1) {
17178
+ validateLockfileV1Object(value, issues);
17179
+ if (issues.length > 0) return {
17180
+ ok: false,
17181
+ issues: issues.sort(compareLockfileIssues)
17182
+ };
17183
+ return {
17184
+ ok: true,
17185
+ lockfile: value,
17186
+ version: 1
17187
+ };
17188
+ }
17189
+ validateLockfileV2Object(value, issues);
16735
17190
  if (issues.length > 0) return {
16736
17191
  ok: false,
16737
17192
  issues: issues.sort(compareLockfileIssues)
16738
17193
  };
16739
17194
  return {
16740
17195
  ok: true,
16741
- lockfile: value
17196
+ lockfile: value,
17197
+ version: 2
16742
17198
  };
16743
17199
  }
16744
17200
  function toLockTemplate(template) {
@@ -16749,7 +17205,7 @@ function toLockTemplate(template) {
16749
17205
  sha256: template.sha256
16750
17206
  };
16751
17207
  }
16752
- function validateLockfileObject(value, issues) {
17208
+ function validateLockfileV1Object(value, issues) {
16753
17209
  if (!isRecord(value)) {
16754
17210
  issues.push(schemaIssue("/", "object", describeValue(value)));
16755
17211
  return;
@@ -16765,7 +17221,25 @@ function validateLockfileObject(value, issues) {
16765
17221
  validateProfile(value.profile, issues);
16766
17222
  validateCompiler(value.compiler, issues);
16767
17223
  validateTemplates(value.templates, issues);
16768
- validateOutputs(value.outputs, issues);
17224
+ validateOutputsV1(value.outputs, issues);
17225
+ }
17226
+ function validateLockfileV2Object(value, issues) {
17227
+ if (!isRecord(value)) {
17228
+ issues.push(schemaIssue("/", "object", describeValue(value)));
17229
+ return;
17230
+ }
17231
+ requireExactKeys(value, "/", [
17232
+ "version",
17233
+ "profile",
17234
+ "compiler",
17235
+ "templates",
17236
+ "outputs"
17237
+ ], issues);
17238
+ if (value.version !== 2) issues.push(schemaIssue("/version", "constant 2", describeValue(value.version)));
17239
+ validateProfile(value.profile, issues);
17240
+ validateCompiler(value.compiler, issues);
17241
+ validateTemplates(value.templates, issues);
17242
+ validateOutputsV2(value.outputs, issues);
16769
17243
  }
16770
17244
  function validateProfile(value, issues) {
16771
17245
  if (!isRecord(value)) {
@@ -16823,7 +17297,7 @@ function validateTemplates(value, issues) {
16823
17297
  previous = current;
16824
17298
  });
16825
17299
  }
16826
- function validateOutputs(value, issues) {
17300
+ function validateOutputsV1(value, issues) {
16827
17301
  if (!Array.isArray(value)) {
16828
17302
  issues.push(schemaIssue("/outputs", "array", describeValue(value)));
16829
17303
  return;
@@ -16856,6 +17330,89 @@ function validateOutputs(value, issues) {
16856
17330
  previous = current;
16857
17331
  });
16858
17332
  }
17333
+ function validateOutputsV2(value, issues) {
17334
+ if (!Array.isArray(value)) {
17335
+ issues.push(schemaIssue("/outputs", "array", describeValue(value)));
17336
+ return;
17337
+ }
17338
+ let previous;
17339
+ value.forEach((item, index) => {
17340
+ const path = `/outputs/${index}`;
17341
+ if (!isRecord(item)) {
17342
+ issues.push(schemaIssue(path, "object", describeValue(item)));
17343
+ return;
17344
+ }
17345
+ const ownership = item.ownership;
17346
+ if (ownership === "generated-owned") {
17347
+ requireExactKeys(item, path, [
17348
+ "path",
17349
+ "target",
17350
+ "templateId",
17351
+ "ownership",
17352
+ "sha256"
17353
+ ], issues);
17354
+ validatePath(item.path, `${path}/path`, issues);
17355
+ validateString(item.target, `${path}/target`, issues);
17356
+ validateString(item.templateId, `${path}/templateId`, issues);
17357
+ validateHash(item.sha256, `${path}/sha256`, issues);
17358
+ } else if (ownership === "mixed") {
17359
+ requireExactKeys(item, path, [
17360
+ "path",
17361
+ "target",
17362
+ "templateId",
17363
+ "ownership",
17364
+ "regions"
17365
+ ], issues);
17366
+ validatePath(item.path, `${path}/path`, issues);
17367
+ validateString(item.target, `${path}/target`, issues);
17368
+ validateString(item.templateId, `${path}/templateId`, issues);
17369
+ validateRegions(item.regions, `${path}/regions`, issues);
17370
+ } else if (ownership === "manual-owned") {
17371
+ requireExactKeys(item, path, [
17372
+ "path",
17373
+ "target",
17374
+ "templateId",
17375
+ "ownership"
17376
+ ], issues);
17377
+ validatePath(item.path, `${path}/path`, issues);
17378
+ if (item.target !== "manual") issues.push(schemaIssue(`${path}/target`, "\"manual\"", describeValue(item.target)));
17379
+ if (item.templateId !== "manual") issues.push(schemaIssue(`${path}/templateId`, "\"manual\"", describeValue(item.templateId)));
17380
+ } else issues.push(schemaIssue(`${path}/ownership`, "\"generated-owned\" | \"mixed\" | \"manual-owned\"", describeValue(ownership)));
17381
+ const current = item;
17382
+ if (previous && compareLockOutputsV2(previous, current) > 0) issues.push({
17383
+ code: "lockfile_order_error",
17384
+ path,
17385
+ expected: "outputs sorted by path then target",
17386
+ actual: "out of order",
17387
+ message: `${path} is not in deterministic order.`
17388
+ });
17389
+ previous = current;
17390
+ });
17391
+ }
17392
+ function validateRegions(value, pathPrefix, issues) {
17393
+ if (!Array.isArray(value)) {
17394
+ issues.push(schemaIssue(pathPrefix, "array", describeValue(value)));
17395
+ return;
17396
+ }
17397
+ if (value.length !== 1) issues.push(schemaIssue(pathPrefix, "exactly one generated region", `${value.length} regions`));
17398
+ value.forEach((item, index) => {
17399
+ const path = `${pathPrefix}/${index}`;
17400
+ if (!isRecord(item)) {
17401
+ issues.push(schemaIssue(path, "object", describeValue(item)));
17402
+ return;
17403
+ }
17404
+ requireExactKeys(item, path, [
17405
+ "id",
17406
+ "target",
17407
+ "templateId",
17408
+ "sha256"
17409
+ ], issues);
17410
+ if (item.id !== "agent-profile:generated") issues.push(schemaIssue(`${path}/id`, "\"agent-profile:generated\"", describeValue(item.id)));
17411
+ validateString(item.target, `${path}/target`, issues);
17412
+ validateString(item.templateId, `${path}/templateId`, issues);
17413
+ validateHash(item.sha256, `${path}/sha256`, issues);
17414
+ });
17415
+ }
16859
17416
  function requireExactKeys(value, path, keys, issues) {
16860
17417
  const allowed = new Set(keys);
16861
17418
  for (const key of keys) if (!Object.prototype.hasOwnProperty.call(value, key)) issues.push(schemaIssue(`${path}/${escapeJsonPointerSegment(key)}`, "required property", "missing"));
@@ -16913,11 +17470,26 @@ function escapeJsonPointerSegment(segment) {
16913
17470
  function isRecord(value) {
16914
17471
  return typeof value === "object" && value !== null && !Array.isArray(value);
16915
17472
  }
16916
- function toLockOutput(file) {
17473
+ function toLockOutputV2(file, mixedByPath) {
17474
+ const safePath = safeOutputPath(file.path);
17475
+ const mixed = mixedByPath.get(safePath);
17476
+ if (mixed) return {
17477
+ path: safePath,
17478
+ target: file.target,
17479
+ templateId: file.templateId,
17480
+ ownership: "mixed",
17481
+ regions: [{
17482
+ id: "agent-profile:generated",
17483
+ target: mixed.target,
17484
+ templateId: mixed.templateId,
17485
+ sha256: mixed.regionHash
17486
+ }]
17487
+ };
16917
17488
  return {
16918
- path: safeOutputPath(file.path),
17489
+ path: safePath,
16919
17490
  target: file.target,
16920
17491
  templateId: file.templateId,
17492
+ ownership: "generated-owned",
16921
17493
  sha256: file.sha256
16922
17494
  };
16923
17495
  }
@@ -16927,106 +17499,663 @@ function compareLockTemplates(left, right) {
16927
17499
  function compareLockOutputs(left, right) {
16928
17500
  return compareText(left.path, right.path) || compareText(left.target, right.target);
16929
17501
  }
16930
- //#endregion
16931
- //#region ../../packages/compiler/src/compiler.ts
16932
- var WORKFLOW_SKILLS = [
16933
- {
16934
- id: "sdd-change",
16935
- workflowFlag: "sdd"
16936
- },
16937
- {
16938
- id: "tdd-change",
16939
- workflowFlag: "tdd"
16940
- },
16941
- {
16942
- id: "final-review",
16943
- workflowFlag: "finalReview"
16944
- }
16945
- ];
16946
- var TEMPLATE_SOURCES = [
16947
- {
16948
- id: "targets/agents-md@1",
16949
- target: "agents-md",
16950
- version: "1",
16951
- source: renderAgentsMdTemplateSource()
16952
- },
16953
- {
16954
- id: "targets/lockfile@1",
16955
- target: "lockfile",
16956
- version: "1",
16957
- source: renderLockfileTemplateSource()
16958
- },
16959
- guidelineTemplateSource("targets/tabnine-guidelines/00-general-agent-behavior@1", renderGeneralAgentBehaviorTemplateSource),
16960
- guidelineTemplateSource("targets/tabnine-guidelines/10-sdd-workflow@1", renderSddWorkflowGuideline),
16961
- guidelineTemplateSource("targets/tabnine-guidelines/20-tdd-workflow@1", renderTddWorkflowGuideline),
16962
- guidelineTemplateSource("targets/tabnine-guidelines/30-stack-typescript-svelte@1", renderTypeScriptSvelteGuideline),
16963
- guidelineTemplateSource("targets/tabnine-guidelines/40-stack-java-spring@1", renderJavaSpringGuideline),
16964
- guidelineTemplateSource("targets/tabnine-guidelines/50-testing-playwright-junit@1", renderPlaywrightJunitGuideline),
16965
- guidelineTemplateSource("targets/tabnine-guidelines/90-final-review@1", renderFinalReviewGuideline),
16966
- {
16967
- id: "targets/tabnine-mcp-config@1",
16968
- target: "tabnine-mcp-config",
16969
- version: "1",
16970
- source: JSON.stringify({ mcpServers: {} }, null, 2)
16971
- },
16972
- {
16973
- id: "targets/codex-config@1",
16974
- target: "codex-config",
16975
- version: "1",
16976
- source: renderCodexConfigToml()
16977
- },
16978
- workflowSkillTemplateSource("targets/codex-workflow-skills/sdd-change@1", "codex-workflow-skills", "sdd-change"),
16979
- workflowSkillTemplateSource("targets/codex-workflow-skills/tdd-change@1", "codex-workflow-skills", "tdd-change"),
16980
- workflowSkillTemplateSource("targets/codex-workflow-skills/final-review@1", "codex-workflow-skills", "final-review"),
16981
- {
16982
- id: "targets/claude-settings@1",
16983
- target: "claude-settings",
16984
- version: "1",
16985
- source: renderClaudeSettingsJson()
16986
- },
16987
- {
16988
- id: "targets/claude-mcp@1",
16989
- target: "claude-mcp",
16990
- version: "1",
16991
- source: JSON.stringify({ mcpServers: {} }, null, 2)
16992
- },
16993
- {
16994
- id: "targets/claude-md@1",
16995
- target: "claude-md",
16996
- version: "1",
16997
- source: renderClaudeMd()
16998
- },
16999
- workflowSkillTemplateSource("targets/claude-workflow-skills/sdd-change@1", "claude-workflow-skills", "sdd-change"),
17000
- workflowSkillTemplateSource("targets/claude-workflow-skills/tdd-change@1", "claude-workflow-skills", "tdd-change"),
17001
- workflowSkillTemplateSource("targets/claude-workflow-skills/final-review@1", "claude-workflow-skills", "final-review")
17002
- ];
17003
- function getDefaultTemplates() {
17004
- return TEMPLATE_SOURCES.map(({ id, target, version, source }) => ({
17005
- id,
17006
- target,
17007
- version,
17008
- sha256: sha256Hex(normalizeGeneratedText(source))
17009
- })).sort(compareTemplates);
17502
+ function compareLockOutputsV2(left, right) {
17503
+ return compareText(left.path, right.path) || compareText(left.target, right.target);
17010
17504
  }
17011
- function compileProfile(request) {
17012
- const targets = uniqueTargets(request.targets ?? getEnabledTargetIds(request.profile));
17013
- const templates = request.templates ?? getDefaultTemplates();
17014
- const issues = validateTargets(request.profile, targets, templates);
17015
- if (issues.length > 0) return {
17016
- ok: false,
17017
- issues: issues.sort(compareIssues)
17018
- };
17019
- return {
17020
- ok: true,
17021
- files: targets.flatMap((target) => renderTarget(target, request.profile)).sort(compareGeneratedFiles),
17022
- templates: templates.filter((template) => targets.includes(template.target)).sort(compareTemplates)
17023
- };
17505
+ /**
17506
+ * Normalize a v1 or v2 lockfile to a uniform v2 view for consumers. v1
17507
+ * outputs are promoted to `generated-owned` outputs.
17508
+ */
17509
+ function toLockfileV2View(lockfile) {
17510
+ if (lockfile.version === 2) return lockfile;
17511
+ return migrateLockfileV1ToV2(lockfile);
17512
+ }
17513
+ //#endregion
17514
+ //#region ../../packages/compiler/src/regions.ts
17515
+ var GENERATED_START_MARKER = "<!-- agent-profile:generated:start -->";
17516
+ var GENERATED_END_MARKER = "<!-- agent-profile:generated:end -->";
17517
+ var MANUAL_START_MARKER = "<!-- agent-profile:manual:start -->";
17518
+ var MANUAL_END_MARKER = "<!-- agent-profile:manual:end -->";
17519
+ var LEGACY_GENERATED_MARKER = "<!-- Generated by Agent Profile Compiler. Do not edit by hand. -->";
17520
+ var GENERATED_START_RE = /^<!-- agent-profile:generated:start -->$/u;
17521
+ var GENERATED_END_RE = /^<!-- agent-profile:generated:end -->$/u;
17522
+ var MANUAL_START_RE = /^<!-- agent-profile:manual:start -->$/u;
17523
+ var MANUAL_END_RE = /^<!-- agent-profile:manual:end -->$/u;
17524
+ /**
17525
+ * Parse a mixed-ownership instruction file (AGENTS.md or CLAUDE.md) into its
17526
+ * generated and manual regions. Raw bytes are preserved; no normalization is
17527
+ * applied so that hashes match the on-disk content exactly.
17528
+ *
17529
+ * The Phase 14 spec defines a strict file shape: the file begins with the
17530
+ * generated start marker, the two regions are separated by exactly one blank
17531
+ * line, and the file ends with the manual end marker plus a single trailing
17532
+ * newline. Markers that appear inside fenced code blocks (``` ... ```) are
17533
+ * not counted as region markers.
17534
+ */
17535
+ function parseMixedFile(bytes) {
17536
+ const text = bytes.toString("utf8");
17537
+ const lineEndings = [];
17538
+ const lines = [];
17539
+ let position = 0;
17540
+ while (position < text.length) {
17541
+ const newlineIndex = text.indexOf("\n", position);
17542
+ if (newlineIndex === -1) {
17543
+ lines.push(text.slice(position));
17544
+ lineEndings.push("");
17545
+ break;
17546
+ }
17547
+ let lineEnd = newlineIndex;
17548
+ let ending = "\n";
17549
+ if (lineEnd > position && text[lineEnd - 1] === "\r") {
17550
+ lineEnd = newlineIndex - 1;
17551
+ ending = "\r\n";
17552
+ }
17553
+ lines.push(text.slice(position, lineEnd));
17554
+ lineEndings.push(ending);
17555
+ position = newlineIndex + 1;
17556
+ }
17557
+ const inFence = computeCodeFenceMask(lines);
17558
+ const matches = {
17559
+ generatedStart: [],
17560
+ generatedEnd: [],
17561
+ manualStart: [],
17562
+ manualEnd: []
17563
+ };
17564
+ lines.forEach((line, index) => {
17565
+ if (inFence[index]) return;
17566
+ if (GENERATED_START_RE.test(line)) matches.generatedStart.push(index);
17567
+ if (GENERATED_END_RE.test(line)) matches.generatedEnd.push(index);
17568
+ if (MANUAL_START_RE.test(line)) matches.manualStart.push(index);
17569
+ if (MANUAL_END_RE.test(line)) matches.manualEnd.push(index);
17570
+ });
17571
+ const issues = [];
17572
+ if (matches.generatedStart.length > 1 || matches.generatedEnd.length > 1 || matches.manualStart.length > 1 || matches.manualEnd.length > 1) {
17573
+ issues.push({
17574
+ code: "duplicate-markers",
17575
+ message: "Mixed instruction file contains duplicate generated/manual region markers."
17576
+ });
17577
+ return {
17578
+ ok: false,
17579
+ issues
17580
+ };
17581
+ }
17582
+ if (matches.generatedStart.length !== 1 || matches.generatedEnd.length !== 1 || matches.manualStart.length !== 1 || matches.manualEnd.length !== 1) {
17583
+ issues.push({
17584
+ code: "missing-markers",
17585
+ message: "Mixed instruction file is missing one or more required region markers."
17586
+ });
17587
+ return {
17588
+ ok: false,
17589
+ issues
17590
+ };
17591
+ }
17592
+ const gs = matches.generatedStart[0];
17593
+ const ge = matches.generatedEnd[0];
17594
+ const ms = matches.manualStart[0];
17595
+ const me = matches.manualEnd[0];
17596
+ if (!(gs < ge && ge < ms && ms < me)) {
17597
+ issues.push({
17598
+ code: "out-of-order",
17599
+ message: "Mixed instruction file region markers must appear in generated-start, generated-end, manual-start, manual-end order."
17600
+ });
17601
+ return {
17602
+ ok: false,
17603
+ issues
17604
+ };
17605
+ }
17606
+ if (gs !== 0) {
17607
+ issues.push({
17608
+ code: "preamble",
17609
+ message: "Mixed instruction file must begin with the generated start marker; no preamble bytes are allowed."
17610
+ });
17611
+ return {
17612
+ ok: false,
17613
+ issues
17614
+ };
17615
+ }
17616
+ if (ms !== ge + 2 || (lines[ge + 1] ?? "") !== "") {
17617
+ issues.push({
17618
+ code: "missing-blank-line",
17619
+ message: "Mixed instruction file must have exactly one blank line between the generated and manual regions."
17620
+ });
17621
+ return {
17622
+ ok: false,
17623
+ issues
17624
+ };
17625
+ }
17626
+ if (!(lines.length === me + 1 && (lineEndings[me] ?? "").length > 0)) {
17627
+ issues.push({
17628
+ code: "missing-trailing-newline",
17629
+ message: "Mixed instruction file must end with the manual end marker followed by exactly one trailing newline."
17630
+ });
17631
+ return {
17632
+ ok: false,
17633
+ issues
17634
+ };
17635
+ }
17636
+ const generatedInnerBytes = computeRangeBytes(bytes, lines, lineEndings, gs, ge);
17637
+ return {
17638
+ ok: true,
17639
+ generatedInner: generatedInnerBytes,
17640
+ manualInner: computeRangeBytes(bytes, lines, lineEndings, ms, me),
17641
+ generatedInnerHash: sha256Hex(generatedInnerBytes)
17642
+ };
17643
+ }
17644
+ function computeCodeFenceMask(lines) {
17645
+ const mask = new Array(lines.length).fill(false);
17646
+ let open = false;
17647
+ for (let index = 0; index < lines.length; index += 1) {
17648
+ const line = lines[index] ?? "";
17649
+ if (/^\s{0,3}(?:```|~~~)/u.test(line)) {
17650
+ mask[index] = open || true;
17651
+ open = !open;
17652
+ continue;
17653
+ }
17654
+ mask[index] = open;
17655
+ }
17656
+ return mask;
17657
+ }
17658
+ function computeRangeBytes(bytes, lines, lineEndings, startMarkerIndex, endMarkerIndex) {
17659
+ const startByte = computeByteOffsetAfterLine(lines, lineEndings, startMarkerIndex);
17660
+ const endByte = computeByteOffsetAtLineStart(lines, lineEndings, endMarkerIndex);
17661
+ return bytes.subarray(startByte, endByte);
17662
+ }
17663
+ function computeByteOffsetAfterLine(lines, lineEndings, lineIndex) {
17664
+ let offset = 0;
17665
+ for (let index = 0; index <= lineIndex; index += 1) {
17666
+ offset += Buffer.byteLength(lines[index] ?? "", "utf8");
17667
+ offset += Buffer.byteLength(lineEndings[index] ?? "", "utf8");
17668
+ }
17669
+ return offset;
17670
+ }
17671
+ function computeByteOffsetAtLineStart(lines, lineEndings, lineIndex) {
17672
+ let offset = 0;
17673
+ for (let index = 0; index < lineIndex; index += 1) {
17674
+ offset += Buffer.byteLength(lines[index] ?? "", "utf8");
17675
+ offset += Buffer.byteLength(lineEndings[index] ?? "", "utf8");
17676
+ }
17677
+ return offset;
17678
+ }
17679
+ /**
17680
+ * Quick predicate: do any of the four region markers appear in the file?
17681
+ * Used to detect partial markers and choose ownership. Marker lines inside
17682
+ * fenced code blocks (``` ... ``` / ~~~ ... ~~~) are not counted.
17683
+ */
17684
+ function hasAnyRegionMarker(bytes) {
17685
+ const lines = bytes.toString("utf8").split(/\r?\n/u);
17686
+ const fence = computeCodeFenceMask(lines);
17687
+ return lines.some((line, index) => !fence[index] && (GENERATED_START_RE.test(line) || GENERATED_END_RE.test(line) || MANUAL_START_RE.test(line) || MANUAL_END_RE.test(line)));
17688
+ }
17689
+ function hasAllRegionMarkers(bytes) {
17690
+ const lines = bytes.toString("utf8").split(/\r?\n/u);
17691
+ const fence = computeCodeFenceMask(lines);
17692
+ const present = (re) => lines.some((line, index) => !fence[index] && re.test(line));
17693
+ return present(GENERATED_START_RE) && present(GENERATED_END_RE) && present(MANUAL_START_RE) && present(MANUAL_END_RE);
17694
+ }
17695
+ function hasLegacyGeneratedMarker(bytes) {
17696
+ return bytes.toString("utf8").split(/\r?\n/u).some((line) => line === LEGACY_GENERATED_MARKER);
17697
+ }
17698
+ /**
17699
+ * Build a mixed-ownership file from a generated inner body and a manual inner
17700
+ * body. The output uses LF line endings between markers and ends with a single
17701
+ * trailing newline.
17702
+ *
17703
+ * `generatedInner` is treated as the bytes strictly between the generated
17704
+ * markers (excluding marker lines). It is emitted verbatim; callers are
17705
+ * responsible for ensuring it is LF-normalized.
17706
+ *
17707
+ * `manualInner` is the bytes strictly between the manual markers and is
17708
+ * emitted verbatim with no normalization.
17709
+ */
17710
+ function serializeMixedFile(input) {
17711
+ const manualInner = endsWithNewline(input.manualInner) ? input.manualInner : Buffer.concat([input.manualInner, Buffer.from("\n", "utf8")]);
17712
+ const parts = [
17713
+ Buffer.from(`${GENERATED_START_MARKER}\n`, "utf8"),
17714
+ input.generatedInner,
17715
+ Buffer.from(`${GENERATED_END_MARKER}\n`, "utf8"),
17716
+ Buffer.from("\n", "utf8"),
17717
+ Buffer.from(`${MANUAL_START_MARKER}\n`, "utf8"),
17718
+ manualInner,
17719
+ Buffer.from(`${MANUAL_END_MARKER}\n`, "utf8")
17720
+ ];
17721
+ return Buffer.concat(parts);
17722
+ }
17723
+ function endsWithNewline(bytes) {
17724
+ if (bytes.length === 0) return false;
17725
+ return bytes[bytes.length - 1] === 10;
17726
+ }
17727
+ /**
17728
+ * Replace only the generated region of an existing mixed file with a new
17729
+ * generated inner body. The manual region bytes and surrounding shape are
17730
+ * preserved byte-for-byte.
17731
+ *
17732
+ * Returns `undefined` if the existing bytes are not a valid mixed file; the
17733
+ * caller must refuse to write in that case.
17734
+ */
17735
+ function replaceGeneratedRegion(existing, newGeneratedInner) {
17736
+ if (!parseMixedFile(existing).ok) return void 0;
17737
+ const text = existing.toString("utf8");
17738
+ let cursor = 0;
17739
+ let position = 0;
17740
+ let generatedStartInnerByte = -1;
17741
+ let generatedEndLineStartByte = -1;
17742
+ while (position < text.length) {
17743
+ const newlineIndex = text.indexOf("\n", position);
17744
+ const hasNewline = newlineIndex !== -1;
17745
+ let lineEnd = hasNewline ? newlineIndex : text.length;
17746
+ let endingLength = 0;
17747
+ if (hasNewline) {
17748
+ endingLength = 1;
17749
+ if (lineEnd > position && text[lineEnd - 1] === "\r") {
17750
+ lineEnd -= 1;
17751
+ endingLength = 2;
17752
+ }
17753
+ }
17754
+ const line = text.slice(position, lineEnd);
17755
+ const lineBytes = Buffer.byteLength(line, "utf8");
17756
+ if (line === "<!-- agent-profile:generated:start -->" && generatedStartInnerByte === -1) generatedStartInnerByte = cursor + lineBytes + endingLength;
17757
+ if (line === "<!-- agent-profile:generated:end -->" && generatedEndLineStartByte === -1) generatedEndLineStartByte = cursor;
17758
+ cursor += lineBytes + endingLength;
17759
+ position = hasNewline ? newlineIndex + 1 : text.length;
17760
+ }
17761
+ if (generatedStartInnerByte === -1 || generatedEndLineStartByte === -1) return;
17762
+ const before = existing.subarray(0, generatedStartInnerByte);
17763
+ const after = existing.subarray(generatedEndLineStartByte);
17764
+ return Buffer.concat([
17765
+ before,
17766
+ newGeneratedInner,
17767
+ after
17768
+ ]);
17769
+ }
17770
+ //#endregion
17771
+ //#region ../../packages/compiler/src/guidance-content.ts
17772
+ var REACT_STACK_TOPIC = {
17773
+ tabnineTitle: "TypeScript and React Stack",
17774
+ agentsMdTitle: "Stack Guidance — React",
17775
+ intro: "Use the existing TypeScript and React conventions in the repository.",
17776
+ subsections: [
17777
+ {
17778
+ heading: "TypeScript Discipline",
17779
+ bullets: [
17780
+ "Do not use `any` without a documented reason.",
17781
+ "Declare explicit types for exported functions, props, and return values.",
17782
+ "Reuse existing types and utilities before adding new ones."
17783
+ ]
17784
+ },
17785
+ {
17786
+ heading: "Component Conventions",
17787
+ bullets: [
17788
+ "Use function components with typed props.",
17789
+ "Co-locate components with the modules that own them.",
17790
+ "Keep render-only components free of side effects."
17791
+ ]
17792
+ },
17793
+ {
17794
+ heading: "Hook Discipline",
17795
+ bullets: [
17796
+ "Add memoization (`useMemo`, `useCallback`) only when a measured re-render or referential-identity problem exists.",
17797
+ "Keep state local; do not introduce a global store by default.",
17798
+ "Honor the rules of hooks; never call hooks conditionally."
17799
+ ]
17800
+ },
17801
+ {
17802
+ heading: "Styling",
17803
+ bullets: ["Follow the existing styling approach in the repository.", "Do not introduce a new CSS framework or component library."]
17804
+ },
17805
+ {
17806
+ heading: "API Calls",
17807
+ bullets: [
17808
+ "Reuse existing client utilities for HTTP and data access.",
17809
+ "Type both request payloads and response bodies.",
17810
+ "Handle error and loading states explicitly."
17811
+ ]
17812
+ },
17813
+ {
17814
+ heading: "SDD and TDD Focus",
17815
+ bullets: [
17816
+ "Cover state transitions, API success, error, and loading paths.",
17817
+ "Cover accessibility-affecting behavior (focus, keyboard, ARIA).",
17818
+ "Add or update focused tests before changing observable behavior."
17819
+ ]
17820
+ }
17821
+ ],
17822
+ tabnineChecklistReference: "See `90-final-review.md` for the shared final-review checklist.",
17823
+ agentsMdChecklistReference: "See the `## Completion Checklist` section for shared review steps."
17824
+ };
17825
+ var CODE_REVIEW_TOPIC = {
17826
+ tabnineTitle: "Code Review",
17827
+ agentsMdTitle: "Code Review",
17828
+ intro: "Use these rules when reviewing a pull request or proposed change.",
17829
+ subsections: [
17830
+ {
17831
+ heading: "Review Focus",
17832
+ bullets: [
17833
+ "Correctness and edge cases.",
17834
+ "Security, including input validation and secret handling.",
17835
+ "Performance hotspots and obvious complexity regressions.",
17836
+ "Unnecessary complexity or premature abstraction.",
17837
+ "Consistency with existing project style.",
17838
+ "Missing or weakened tests.",
17839
+ "Weak typing or unjustified `any`.",
17840
+ "Accessibility-affecting behavior in user-facing changes.",
17841
+ "Error handling and observability gaps.",
17842
+ "Dependency risk and license concerns.",
17843
+ "Spec compliance."
17844
+ ]
17845
+ },
17846
+ {
17847
+ heading: "Severity Labels",
17848
+ bullets: [
17849
+ "Blocker: must fix before merge (correctness, security, contract break).",
17850
+ "High: must fix before merge unless explicitly deferred.",
17851
+ "Medium: should fix before merge or open a tracked follow-up.",
17852
+ "Low: nit or polish; safe to defer."
17853
+ ]
17854
+ },
17855
+ {
17856
+ heading: "Output Format",
17857
+ bullets: [
17858
+ "Summary: one paragraph of intent and overall verdict.",
17859
+ "Spec Compliance: cite the spec and any deviation.",
17860
+ "Findings: grouped by severity, each with file, function, and concrete suggestion.",
17861
+ "Tests: list coverage gaps and whether tests were run.",
17862
+ "Safety Review: secrets, production access, dependency installs, network access.",
17863
+ "Final recommendation: approve, request changes, or block with reason."
17864
+ ]
17865
+ },
17866
+ {
17867
+ heading: "Review Discipline",
17868
+ bullets: [
17869
+ "Skip nitpicks the autoformatter or linter already handles.",
17870
+ "Do not propose broad rewrites; keep suggestions actionable.",
17871
+ "Reference the specific file, function, or component in every finding."
17872
+ ]
17873
+ }
17874
+ ],
17875
+ tabnineChecklistReference: "See `90-final-review.md` for the shared final-review checklist.",
17876
+ agentsMdChecklistReference: "See the `## Completion Checklist` section for shared review steps."
17877
+ };
17878
+ var REFACTORING_TOPIC = {
17879
+ tabnineTitle: "Refactoring",
17880
+ agentsMdTitle: "Refactoring",
17881
+ intro: "Use these rules when restructuring code without changing observable behavior.",
17882
+ subsections: [
17883
+ {
17884
+ heading: "Principles",
17885
+ bullets: [
17886
+ "Refactor to remove duplication, clarify intent, or unlock a planned change.",
17887
+ "Do not refactor for style preference alone or to chase a new pattern.",
17888
+ "Keep refactoring commits separate from behavior changes."
17889
+ ]
17890
+ },
17891
+ {
17892
+ heading: "Safe Refactoring Workflow",
17893
+ bullets: [
17894
+ "Identify the code smell or constraint that motivates the change.",
17895
+ "Check existing abstractions before introducing a new one.",
17896
+ "Define expected behavior in tests before restructuring.",
17897
+ "Make the smallest extraction that solves the problem.",
17898
+ "Preserve public behavior; run tests and golden fixtures after each step.",
17899
+ "Summarize what was intentionally not changed in the review notes."
17900
+ ]
17901
+ },
17902
+ {
17903
+ heading: "Restrictions",
17904
+ bullets: [
17905
+ "Do not rename public APIs without explicit approval.",
17906
+ "Do not move files across modules without explicit approval.",
17907
+ "Do not change schemas, endpoint contracts, or build tooling without explicit approval.",
17908
+ "Do not refactor and add features in the same change."
17909
+ ]
17910
+ }
17911
+ ],
17912
+ tabnineChecklistReference: "See `90-final-review.md` for the shared final-review checklist.",
17913
+ agentsMdChecklistReference: "See the `## Completion Checklist` section for shared review steps."
17914
+ };
17915
+ var DOCUMENTATION_TOPIC = {
17916
+ tabnineTitle: "Documentation",
17917
+ agentsMdTitle: "Documentation",
17918
+ intro: "Use these rules when adding or updating project documentation.",
17919
+ subsections: [
17920
+ {
17921
+ heading: "When to Update Documentation",
17922
+ bullets: [
17923
+ "Setup or onboarding steps changed.",
17924
+ "Workflow, command, or build step changed.",
17925
+ "Public API surface changed.",
17926
+ "Configuration or environment variables changed.",
17927
+ "Testing command changed.",
17928
+ "Deployment or release procedure changed.",
17929
+ "Troubleshooting guidance is newly known."
17930
+ ]
17931
+ },
17932
+ {
17933
+ heading: "Style",
17934
+ bullets: [
17935
+ "Write for maintainers, not marketing.",
17936
+ "Provide copy-pasteable commands where applicable.",
17937
+ "Keep examples current; remove examples that no longer run.",
17938
+ "Reference file paths when they help a reader navigate."
17939
+ ]
17940
+ },
17941
+ {
17942
+ heading: "README Rules",
17943
+ bullets: [
17944
+ "Keep the existing structure intact.",
17945
+ "Add only relevant new sections.",
17946
+ "Do not rewrite the README without an explicit request."
17947
+ ]
17948
+ },
17949
+ {
17950
+ heading: "Code Comment Policy",
17951
+ bullets: [
17952
+ "Comment non-obvious business rules and invariants.",
17953
+ "Comment tricky edge cases the code alone does not reveal.",
17954
+ "Comment surprising technical constraints and security-sensitive behavior.",
17955
+ "Do not write comments that restate the code."
17956
+ ]
17957
+ }
17958
+ ],
17959
+ tabnineChecklistReference: "See `90-final-review.md` for the shared final-review checklist.",
17960
+ agentsMdChecklistReference: "See the `## Completion Checklist` section for shared review steps."
17961
+ };
17962
+ function renderTopicAsTabnineGuideline(topic) {
17963
+ const sections = topic.subsections.map((subsection) => `## ${subsection.heading}\n\n${subsection.bullets.map((bullet) => `- ${bullet}`).join("\n")}\n`).join("\n");
17964
+ return `<!-- Generated by Agent Profile Compiler. Do not edit by hand. -->
17965
+
17966
+ # ${topic.tabnineTitle}
17967
+
17968
+ ${topic.intro}
17969
+
17970
+ ${sections}
17971
+ ${topic.tabnineChecklistReference}
17972
+ `;
17973
+ }
17974
+ function renderTopicAsAgentsMdSection(topic) {
17975
+ const subsections = topic.subsections.map((subsection) => `**${subsection.heading}**\n\n${subsection.bullets.map((bullet) => `- ${bullet}`).join("\n")}`).join("\n\n");
17976
+ return `## ${topic.agentsMdTitle}
17977
+
17978
+ ${topic.intro}
17979
+
17980
+ ${subsections}
17981
+
17982
+ ${topic.agentsMdChecklistReference}
17983
+ `;
17984
+ }
17985
+ //#endregion
17986
+ //#region ../../packages/compiler/src/compiler.ts
17987
+ var WORKFLOW_SKILLS = [
17988
+ {
17989
+ id: "grill-change",
17990
+ workflowFlag: "sdd"
17991
+ },
17992
+ {
17993
+ id: "request-to-spec-issues",
17994
+ workflowFlag: "sdd"
17995
+ },
17996
+ {
17997
+ id: "sdd-change",
17998
+ workflowFlag: "sdd"
17999
+ },
18000
+ {
18001
+ id: "tdd-change",
18002
+ workflowFlag: "tdd"
18003
+ },
18004
+ {
18005
+ id: "final-review",
18006
+ workflowFlag: "finalReview"
18007
+ },
18008
+ {
18009
+ id: "subagent-driven-change",
18010
+ workflowFlag: "subagentDrivenDevelopment"
18011
+ }
18012
+ ];
18013
+ var TEMPLATE_SOURCES = [
18014
+ {
18015
+ id: "targets/agents-md@1",
18016
+ target: "agents-md",
18017
+ version: "1",
18018
+ source: renderAgentsMdTemplateSource()
18019
+ },
18020
+ agentsMdTopicTemplateSource("targets/agents-md/30-stack-typescript-react@1", REACT_STACK_TOPIC),
18021
+ agentsMdTopicTemplateSource("targets/agents-md/60-code-review@1", CODE_REVIEW_TOPIC),
18022
+ agentsMdTopicTemplateSource("targets/agents-md/70-refactoring@1", REFACTORING_TOPIC),
18023
+ agentsMdTopicTemplateSource("targets/agents-md/80-documentation@1", DOCUMENTATION_TOPIC),
18024
+ {
18025
+ id: "targets/lockfile@1",
18026
+ target: "lockfile",
18027
+ version: "1",
18028
+ source: renderLockfileTemplateSource()
18029
+ },
18030
+ guidelineTemplateSource("targets/tabnine-guidelines/00-general-agent-behavior@1", renderGeneralAgentBehaviorTemplateSource),
18031
+ guidelineTemplateSource("targets/tabnine-guidelines/05-planning-workflow@1", renderPlanningWorkflowGuideline),
18032
+ guidelineTemplateSource("targets/tabnine-guidelines/10-sdd-workflow@1", renderSddWorkflowGuideline),
18033
+ guidelineTemplateSource("targets/tabnine-guidelines/20-tdd-workflow@1", renderTddWorkflowGuideline),
18034
+ guidelineTemplateSource("targets/tabnine-guidelines/30-stack-typescript-svelte@1", renderTypeScriptSvelteGuideline),
18035
+ guidelineTemplateSource("targets/tabnine-guidelines/30-stack-typescript-react@1", renderTypeScriptReactGuideline),
18036
+ guidelineTemplateSource("targets/tabnine-guidelines/40-stack-java-spring@1", renderJavaSpringGuideline),
18037
+ guidelineTemplateSource("targets/tabnine-guidelines/50-testing-playwright-junit@1", renderPlaywrightJunitGuideline),
18038
+ guidelineTemplateSource("targets/tabnine-guidelines/60-code-review@1", renderCodeReviewGuideline),
18039
+ guidelineTemplateSource("targets/tabnine-guidelines/70-refactoring@1", renderRefactoringGuideline),
18040
+ guidelineTemplateSource("targets/tabnine-guidelines/80-documentation@1", renderDocumentationGuideline),
18041
+ guidelineTemplateSource("targets/tabnine-guidelines/90-final-review@1", renderFinalReviewGuideline),
18042
+ {
18043
+ id: "targets/tabnine-mcp-config@1",
18044
+ target: "tabnine-mcp-config",
18045
+ version: "1",
18046
+ source: JSON.stringify({ mcpServers: {} }, null, 2)
18047
+ },
18048
+ {
18049
+ id: "targets/codex-config@1",
18050
+ target: "codex-config",
18051
+ version: "1",
18052
+ source: renderCodexConfigToml()
18053
+ },
18054
+ workflowSkillTemplateSource("targets/codex-workflow-skills/grill-change@1", "codex-workflow-skills", "grill-change"),
18055
+ workflowSkillTemplateSource("targets/codex-workflow-skills/request-to-spec-issues@1", "codex-workflow-skills", "request-to-spec-issues"),
18056
+ workflowSkillTemplateSource("targets/codex-workflow-skills/sdd-change@1", "codex-workflow-skills", "sdd-change"),
18057
+ workflowSkillTemplateSource("targets/codex-workflow-skills/tdd-change@2", "codex-workflow-skills", "tdd-change"),
18058
+ workflowSkillTemplateSource("targets/codex-workflow-skills/final-review@1", "codex-workflow-skills", "final-review"),
18059
+ workflowSkillTemplateSource("targets/codex-workflow-skills/subagent-driven-change@1", "codex-workflow-skills", "subagent-driven-change"),
18060
+ {
18061
+ id: "targets/claude-settings@1",
18062
+ target: "claude-settings",
18063
+ version: "1",
18064
+ source: renderClaudeSettingsJson()
18065
+ },
18066
+ {
18067
+ id: "targets/claude-mcp@1",
18068
+ target: "claude-mcp",
18069
+ version: "1",
18070
+ source: JSON.stringify({ mcpServers: {} }, null, 2)
18071
+ },
18072
+ {
18073
+ id: "targets/claude-md@1",
18074
+ target: "claude-md",
18075
+ version: "1",
18076
+ source: renderClaudeMd()
18077
+ },
18078
+ workflowSkillTemplateSource("targets/claude-workflow-skills/grill-change@1", "claude-workflow-skills", "grill-change"),
18079
+ workflowSkillTemplateSource("targets/claude-workflow-skills/request-to-spec-issues@1", "claude-workflow-skills", "request-to-spec-issues"),
18080
+ workflowSkillTemplateSource("targets/claude-workflow-skills/sdd-change@1", "claude-workflow-skills", "sdd-change"),
18081
+ workflowSkillTemplateSource("targets/claude-workflow-skills/tdd-change@2", "claude-workflow-skills", "tdd-change"),
18082
+ workflowSkillTemplateSource("targets/claude-workflow-skills/final-review@1", "claude-workflow-skills", "final-review"),
18083
+ workflowSkillTemplateSource("targets/claude-workflow-skills/subagent-driven-change@1", "claude-workflow-skills", "subagent-driven-change")
18084
+ ];
18085
+ function getDefaultTemplates() {
18086
+ return TEMPLATE_SOURCES.map(({ id, target, version, source }) => ({
18087
+ id,
18088
+ target,
18089
+ version,
18090
+ sha256: sha256Hex(normalizeGeneratedText(source))
18091
+ })).sort(compareTemplates);
18092
+ }
18093
+ function compileProfile(request) {
18094
+ const targets = uniqueTargets(request.targets ?? getEnabledTargetIds(request.profile));
18095
+ const templates = request.templates ?? mergeTemplates(getDefaultTemplates(), getSubagentTemplates(request.profile));
18096
+ const issues = validateTargets(request.profile, targets, templates);
18097
+ if (issues.length > 0) return {
18098
+ ok: false,
18099
+ issues: issues.sort(compareIssues)
18100
+ };
18101
+ const files = targets.flatMap((target) => renderTarget(target, request.profile));
18102
+ const requiredTemplateIds = getRequiredTemplateIdSet(targets, request.profile);
18103
+ return {
18104
+ ok: true,
18105
+ files: files.sort(compareGeneratedFiles),
18106
+ templates: templates.filter((template) => requiredTemplateIds.has(template.id)).sort(compareTemplates)
18107
+ };
18108
+ }
18109
+ function mergeTemplates(base, extra) {
18110
+ const seen = new Set(base.map((template) => template.id));
18111
+ const result = [...base];
18112
+ for (const template of extra) if (!seen.has(template.id)) {
18113
+ seen.add(template.id);
18114
+ result.push(template);
18115
+ }
18116
+ return result.sort(compareTemplates);
18117
+ }
18118
+ function getSubagentTemplates(profile) {
18119
+ const agents = getEnabledSubagents(profile);
18120
+ if (agents.length === 0) return [];
18121
+ const effective = deriveEffectivePermissions(profile);
18122
+ const templates = [];
18123
+ if (profile.clients.claude.enabled) for (const agent of agents) templates.push({
18124
+ id: `targets/claude-subagents/${agent.name}@1`,
18125
+ target: "claude-subagents",
18126
+ version: "1",
18127
+ sha256: sha256Hex(normalizeGeneratedText(renderClaudeSubagent(agent, effective)))
18128
+ });
18129
+ if (profile.clients.codex.enabled) for (const agent of agents) templates.push({
18130
+ id: `targets/codex-subagents/${agent.name}@1`,
18131
+ target: "codex-subagents",
18132
+ version: "1",
18133
+ sha256: sha256Hex(normalizeGeneratedText(renderCodexSubagent(agent, effective)))
18134
+ });
18135
+ if (profile.clients.tabnine.enabled) for (const agent of agents) {
18136
+ if (agent.toolScope !== "read-only") continue;
18137
+ templates.push({
18138
+ id: `targets/tabnine-subagents/${agent.name}@1`,
18139
+ target: "tabnine-subagents",
18140
+ version: "1",
18141
+ sha256: sha256Hex(normalizeGeneratedText(renderTabnineSubagent(agent)))
18142
+ });
18143
+ }
18144
+ return templates;
17024
18145
  }
17025
18146
  function renderAgentsMd(profile) {
17026
18147
  const effectivePermissions = deriveEffectivePermissions(profile);
17027
18148
  const enabledClients = renderEnabledClients(profile);
18149
+ const reactSection = profile.stack.frameworks.includes("react") ? `\n${renderTopicAsAgentsMdSection(REACT_STACK_TOPIC)}` : "";
18150
+ const codeReviewSection = profile.workflow.codeReview === true ? `\n${renderTopicAsAgentsMdSection(CODE_REVIEW_TOPIC)}` : "";
18151
+ const refactoringSection = profile.workflow.refactoring === true ? `\n${renderTopicAsAgentsMdSection(REFACTORING_TOPIC)}` : "";
18152
+ const documentationSection = profile.workflow.documentation === true ? `\n${renderTopicAsAgentsMdSection(DOCUMENTATION_TOPIC)}` : "";
17028
18153
  return normalizeGeneratedText(`# AGENTS.md
17029
18154
 
18155
+ ## Instruction Precedence
18156
+
18157
+ If generated and manual instructions conflict, follow the manual project instructions unless they would weaken safety, privacy, or permission limits. Safety, privacy, and explicit deny rules always win.
18158
+
17030
18159
  ## Project
17031
18160
 
17032
18161
  Name: ${escapeMarkdownText(profile.profile.name)}
@@ -17039,7 +18168,7 @@ Description: ${escapeMarkdownText(profile.profile.description)}
17039
18168
  - Frameworks: ${renderList(profile.stack.frameworks)}
17040
18169
  - Package managers: ${renderList(profile.stack.packageManagers)}
17041
18170
  - Testing: ${renderList(profile.stack.testing)}
17042
-
18171
+ ${reactSection}
17043
18172
  ## Enabled AI Clients
17044
18173
 
17045
18174
  ${enabledClients}
@@ -17049,7 +18178,7 @@ ${enabledClients}
17049
18178
  - SDD: ${renderRequired(profile.workflow.sdd)}
17050
18179
  - TDD: ${renderRequired(profile.workflow.tdd)}
17051
18180
  - Final implementation review: ${renderRequired(profile.workflow.finalReview)}
17052
-
18181
+ ${codeReviewSection}${refactoringSection}${documentationSection}
17053
18182
  ## Permissions
17054
18183
 
17055
18184
  | Permission | Mode |
@@ -17086,6 +18215,10 @@ Cursor, Aider, Copilot, hosted gateways, enterprise RBAC, SIEM integrations, and
17086
18215
  function renderClaudeMd() {
17087
18216
  return `<!-- Generated by Agent Profile Compiler. Do not edit by hand. -->
17088
18217
 
18218
+ ## Instruction Precedence
18219
+
18220
+ If generated and manual instructions conflict, follow the manual project instructions unless they would weaken safety, privacy, or permission limits. Safety, privacy, and explicit deny rules always win.
18221
+
17089
18222
  @AGENTS.md
17090
18223
 
17091
18224
  # Claude Code
@@ -17117,7 +18250,10 @@ function renderTarget(target, profile) {
17117
18250
  case "tabnine-guidelines": return renderTabnineGuidelines(profile);
17118
18251
  case "lockfile": return [];
17119
18252
  case "tabnine-mcp-config": return [createGeneratedTextFile(".tabnine/mcp_servers.json", "tabnine-mcp-config", "targets/tabnine-mcp-config@1", JSON.stringify({ mcpServers: {} }, null, 2))];
17120
- case "codex-config": return [createGeneratedTextFile(".codex/config.toml", "codex-config", "targets/codex-config@1", renderCodexConfigToml())];
18253
+ case "codex-config": return [createGeneratedTextFile(".codex/config.toml", "codex-config", "targets/codex-config@1", renderCodexConfigToml(profile))];
18254
+ case "codex-subagents": return renderCodexSubagentFiles(profile);
18255
+ case "claude-subagents": return renderClaudeSubagentFiles(profile);
18256
+ case "tabnine-subagents": return renderTabnineSubagentFiles(profile);
17121
18257
  case "codex-workflow-skills": return renderWorkflowSkillFiles(profile, "codex-workflow-skills", ".agents/skills");
17122
18258
  case "claude-settings": return [createGeneratedTextFile(".claude/settings.json", "claude-settings", "targets/claude-settings@1", renderClaudeSettingsJson())];
17123
18259
  case "claude-mcp": return [createGeneratedTextFile(".mcp.json", "claude-mcp", "targets/claude-mcp@1", JSON.stringify({ mcpServers: {} }, null, 2))];
@@ -17128,19 +18264,216 @@ function renderTarget(target, profile) {
17128
18264
  function renderTabnineGuidelines(profile) {
17129
18265
  const common = { target: "tabnine-guidelines" };
17130
18266
  const files = [createGeneratedTextFile(".tabnine/guidelines/00-general-agent-behavior.md", common.target, "targets/tabnine-guidelines/00-general-agent-behavior@1", renderGeneralAgentBehaviorGuideline(profile))];
17131
- if (profile.workflow.sdd) files.push(createGeneratedTextFile(".tabnine/guidelines/10-sdd-workflow.md", common.target, "targets/tabnine-guidelines/10-sdd-workflow@1", renderSddWorkflowGuideline()));
18267
+ if (profile.workflow.sdd) {
18268
+ files.push(createGeneratedTextFile(".tabnine/guidelines/05-planning-workflow.md", common.target, "targets/tabnine-guidelines/05-planning-workflow@1", renderPlanningWorkflowGuideline()));
18269
+ files.push(createGeneratedTextFile(".tabnine/guidelines/10-sdd-workflow.md", common.target, "targets/tabnine-guidelines/10-sdd-workflow@1", renderSddWorkflowGuideline()));
18270
+ }
17132
18271
  if (profile.workflow.tdd) files.push(createGeneratedTextFile(".tabnine/guidelines/20-tdd-workflow.md", common.target, "targets/tabnine-guidelines/20-tdd-workflow@1", renderTddWorkflowGuideline()));
17133
18272
  if (hasStack(profile, "languages", "typescript") && hasStack(profile, "frameworks", "sveltekit")) files.push(createGeneratedTextFile(".tabnine/guidelines/30-stack-typescript-svelte.md", common.target, "targets/tabnine-guidelines/30-stack-typescript-svelte@1", renderTypeScriptSvelteGuideline()));
18273
+ if (hasStack(profile, "frameworks", "react")) files.push(createGeneratedTextFile(".tabnine/guidelines/30-stack-typescript-react.md", common.target, "targets/tabnine-guidelines/30-stack-typescript-react@1", renderTypeScriptReactGuideline()));
17134
18274
  if (hasStack(profile, "languages", "java") && hasStack(profile, "frameworks", "spring-boot")) files.push(createGeneratedTextFile(".tabnine/guidelines/40-stack-java-spring.md", common.target, "targets/tabnine-guidelines/40-stack-java-spring@1", renderJavaSpringGuideline()));
17135
18275
  if (hasAnyStack(profile, "testing", ["playwright", "junit"])) files.push(createGeneratedTextFile(".tabnine/guidelines/50-testing-playwright-junit.md", common.target, "targets/tabnine-guidelines/50-testing-playwright-junit@1", renderPlaywrightJunitGuideline()));
18276
+ if (profile.workflow.codeReview === true) files.push(createGeneratedTextFile(".tabnine/guidelines/60-code-review.md", common.target, "targets/tabnine-guidelines/60-code-review@1", renderCodeReviewGuideline()));
18277
+ if (profile.workflow.refactoring === true) files.push(createGeneratedTextFile(".tabnine/guidelines/70-refactoring.md", common.target, "targets/tabnine-guidelines/70-refactoring@1", renderRefactoringGuideline()));
18278
+ if (profile.workflow.documentation === true) files.push(createGeneratedTextFile(".tabnine/guidelines/80-documentation.md", common.target, "targets/tabnine-guidelines/80-documentation@1", renderDocumentationGuideline()));
17136
18279
  if (profile.workflow.finalReview) files.push(createGeneratedTextFile(".tabnine/guidelines/90-final-review.md", common.target, "targets/tabnine-guidelines/90-final-review@1", renderFinalReviewGuideline()));
17137
18280
  return files;
17138
18281
  }
17139
18282
  function renderWorkflowSkillFiles(profile, target, rootPath) {
17140
- return WORKFLOW_SKILLS.filter((skill) => profile.workflow[skill.workflowFlag]).map((skill) => createGeneratedTextFile(`${rootPath}/${skill.id}/SKILL.md`, target, `targets/${target}/${skill.id}@1`, renderWorkflowSkill(skill.id)));
18283
+ return WORKFLOW_SKILLS.filter((skill) => profile.workflow[skill.workflowFlag]).map((skill) => createGeneratedTextFile(`${rootPath}/${skill.id}/SKILL.md`, target, getWorkflowSkillTemplateId(target, skill.id), renderWorkflowSkill(skill.id)));
18284
+ }
18285
+ function getWorkflowSkillTemplateId(target, skill) {
18286
+ return `targets/${target}/${skill}@${skill === "tdd-change" ? "2" : "1"}`;
17141
18287
  }
17142
18288
  function renderWorkflowSkill(skill) {
17143
18289
  switch (skill) {
18290
+ case "grill-change": return `---
18291
+ name: grill-change
18292
+ description: Use when a stakeholder request is rough, ambiguous, or underspecified and needs clarification before planning, writing a spec, or creating issues.
18293
+ ---
18294
+
18295
+ <!-- Generated by Agent Profile Compiler. Do not edit by hand. -->
18296
+
18297
+ # Grill Change
18298
+
18299
+ ## Purpose
18300
+
18301
+ Clarify a stakeholder request before any spec, issue plan, or implementation work starts. The output is an agreement record for a follow-up synthesis workflow; it is not an implementation plan.
18302
+
18303
+ ## Operating Rules
18304
+
18305
+ 1. Ask one focused question, then wait for the user's answer.
18306
+ 2. Include a recommended answer with the question and explain why that answer is safest for the project.
18307
+ 3. Inspect relevant local specs, ADRs, docs, fixtures, and code before asking questions that local context can answer.
18308
+ 4. Challenge vague terms, overloaded words, and claims that conflict with repository evidence.
18309
+ 5. Prefer concrete examples, edge cases, and tradeoff choices over broad brainstorming.
18310
+ 6. Keep implementation details provisional until the product intent and non-goals are settled.
18311
+ 7. Capture durable terms and hard-to-reverse decisions in the agreement record when they crystallize.
18312
+ 8. Do not create issue lists, edit files, or start implementation during the grill.
18313
+
18314
+ ## Question Format
18315
+
18316
+ Use this shape for each question:
18317
+
18318
+ Question: \`<one decision or missing fact>\`
18319
+ Recommended answer: \`<the default direction you would choose>\`
18320
+ Why: \`<short reason based on product intent, safety, contracts, or repo evidence>\`
18321
+
18322
+ ## Decision Checks
18323
+
18324
+ Before ending the grill, confirm:
18325
+
18326
+ - the problem in the stakeholder's terms
18327
+ - the desired outcome
18328
+ - explicit non-goals
18329
+ - product intent and why the change matters
18330
+ - tradeoff direction for ambiguous implementation choices
18331
+ - user-visible behavior changes
18332
+ - compatibility and migration expectations
18333
+ - durable terminology and hard-to-reverse decisions
18334
+ - safety and privacy constraints
18335
+ - unresolved unknowns, if any
18336
+
18337
+ ## Output
18338
+
18339
+ When the user agrees the grill is complete, return:
18340
+
18341
+ - Problem
18342
+ - Intent
18343
+ - Non-goals
18344
+ - Decisions made
18345
+ - Durable terms and hard-to-reverse decisions
18346
+ - Decision rules for implementation tradeoffs
18347
+ - Open questions or risks
18348
+ - Confirmation that post-grill synthesis can run next
18349
+
18350
+ ## Safety
18351
+
18352
+ - Do not upload source code.
18353
+ - Do not read or print secrets.
18354
+ - Do not ask for credentials, environment values, production data, or private endpoints.
18355
+ - Do not propose \`bypassPermissions\`, tool pre-approval, dependency auto-installation, hosted execution, or remote MCP behavior.
18356
+ - Do not write files, create issues, commit changes, or run implementation commands during the grill.
18357
+ `;
18358
+ case "request-to-spec-issues": return `---
18359
+ name: request-to-spec-issues
18360
+ description: Use after a grill-change session is complete to turn the agreement record into an intent-first spec candidate and vertical TDD-ready issue briefs.
18361
+ ---
18362
+
18363
+ <!-- Generated by Agent Profile Compiler. Do not edit by hand. -->
18364
+
18365
+ # Request To Spec Issues
18366
+
18367
+ ## Purpose
18368
+
18369
+ Convert a completed \`grill-change\` agreement record into an intent-first spec candidate and vertical TDD-ready issue briefs. Preserve product intent and decision rules so implementation choices follow the agreed direction.
18370
+
18371
+ ## Preconditions
18372
+
18373
+ - The grill is complete.
18374
+ - The user has confirmed the direction is ready for synthesis.
18375
+ - Relevant local specs, ADRs, docs, fixtures, and code context have been checked.
18376
+ - If there is no completed grill agreement, stop and run \`grill-change\` first.
18377
+
18378
+ ## Synthesis Rules
18379
+
18380
+ 1. Do not re-interview the user unless the grill record contains a contradiction or a genuinely missing decision.
18381
+ 2. Keep product intent, non-goals, durable terms, and hard-to-reverse decisions above implementation mechanics.
18382
+ 3. Preserve existing spec contracts and safety rules unless the user explicitly approved changing them.
18383
+ 4. Split work into vertical behavior slices, not file layers.
18384
+ 5. Make every issue small enough for a focused RED, GREEN, refactor loop.
18385
+ 6. Mark dependencies and parallel-safe work explicitly.
18386
+ 7. Propose architecture rescue candidates before feature slices when a change would deepen an already fragmented codebase.
18387
+
18388
+ ## Architecture Rescue Candidates
18389
+
18390
+ When architecture rescue is needed, propose candidates before feature issues. Each candidate must include:
18391
+
18392
+ - Files or modules involved
18393
+ - Current friction
18394
+ - Proposed deeper module or clearer interface
18395
+ - Expected locality and leverage improvement
18396
+ - Expected test improvement
18397
+ - ADR or spec conflicts
18398
+ - Recommended dependency state: prerequisite, parallel, or later cleanup
18399
+
18400
+ ## Spec Candidate
18401
+
18402
+ Include these sections:
18403
+
18404
+ - Status
18405
+ - Problem
18406
+ - Goal
18407
+ - Intent
18408
+ - Decision Rules
18409
+ - Non-Goals
18410
+ - User Flow
18411
+ - Inputs
18412
+ - Outputs
18413
+ - Contracts
18414
+ - Security Rules
18415
+ - Acceptance Criteria
18416
+ - Tests
18417
+ - TDD Strategy
18418
+ - Issue Plan
18419
+ - Documentation Updates
18420
+ - Final Review Checklist
18421
+
18422
+ \`TDD Strategy\` complements \`Tests\`; it must not replace the required \`Tests\`
18423
+ section from \`docs/specs/SPEC_TEMPLATE.md\`.
18424
+
18425
+ ## Issue Brief Format
18426
+
18427
+ Each issue brief must include:
18428
+
18429
+ - Title
18430
+ - Parent spec or request
18431
+ - Intent summary
18432
+ - Behavior slice
18433
+ - Non-goals
18434
+ - Acceptance criteria
18435
+ - Expected RED proof
18436
+ - Expected GREEN proof
18437
+ - Test command guidance
18438
+ - Likely file ownership
18439
+ - Dependencies
18440
+ - Parallelism notes
18441
+ - Contract impact
18442
+ - Security impact
18443
+ - Documentation impact
18444
+ - Implementation context
18445
+ - Review expectations
18446
+
18447
+ ## Dependency States
18448
+
18449
+ Use these states:
18450
+
18451
+ - \`ready\`
18452
+ - \`blocked\`
18453
+ - \`parallel-safe\`
18454
+ - \`sequenced\`
18455
+ - \`human-gate\`
18456
+
18457
+ ## Output
18458
+
18459
+ Return:
18460
+
18461
+ - Spec candidate or spec patch
18462
+ - Vertical issue briefs
18463
+ - Dependency map
18464
+ - Parallelism map
18465
+ - Human gates
18466
+ - Recommended next step
18467
+
18468
+ ## Safety
18469
+
18470
+ - Do not upload source code.
18471
+ - Do not read or print secrets.
18472
+ - Do not include credentials, environment values, production data, or private endpoints.
18473
+ - Do not create GitHub issues, labels, projects, or milestones.
18474
+ - Do not write files unless the user explicitly asks for local file writes after reviewing the synthesis.
18475
+ - Do not propose \`bypassPermissions\`, tool pre-approval, dependency auto-installation, hosted execution, or remote MCP behavior.
18476
+ `;
17144
18477
  case "sdd-change": return `---
17145
18478
  name: sdd-change
17146
18479
  description: Use when implementing a meaningful repository change that requires an approved spec before code edits.
@@ -17168,7 +18501,7 @@ description: Use when implementing a meaningful repository change that requires
17168
18501
  `;
17169
18502
  case "tdd-change": return `---
17170
18503
  name: tdd-change
17171
- description: Use when changing behavior where a focused failing test or golden fixture should lead the implementation.
18504
+ description: Use when changing behavior where a focused failing test or golden fixture must prove RED before implementation and GREEN after the minimal fix.
17172
18505
  ---
17173
18506
 
17174
18507
  <!-- Generated by Agent Profile Compiler. Do not edit by hand. -->
@@ -17178,11 +18511,24 @@ description: Use when changing behavior where a focused failing test or golden f
17178
18511
  ## Instructions
17179
18512
 
17180
18513
  1. Identify the smallest observable behavior covered by the approved spec.
17181
- 2. Add or update the focused failing test first when practical.
17182
- 3. For generated outputs, add or review the golden fixture intentionally.
17183
- 4. Implement the smallest change that satisfies the test and spec.
17184
- 5. Run the relevant test command and report any test that cannot be run.
17185
- 6. Do not update golden files only to hide an unexplained behavior change.
18514
+ 2. Add or update one focused failing test or golden fixture before changing behavior code.
18515
+ 3. Run the narrowest relevant test command and confirm RED: the test fails for the expected reason, not because of a typo, setup error, or unrelated failure.
18516
+ 4. Implement the smallest change that satisfies the failing test and the spec.
18517
+ 5. Run the same focused test command and confirm GREEN: the test passes without new warnings or unrelated failures.
18518
+ 6. Refactor only after GREEN, then rerun the focused test command.
18519
+ 7. Do not update golden files only to hide an unexplained behavior change.
18520
+
18521
+ ## Testing Anti-Patterns
18522
+
18523
+ - Do not assert on mock elements or mock call counts when a real behavior assertion is possible.
18524
+ - Do not add production methods, flags, or exports that exist only for tests.
18525
+ - Do not mock a dependency until you understand the side effects the test needs.
18526
+ - Keep test doubles structurally complete enough to match the real data shape consumed by the code.
18527
+ - If mock setup is larger than the behavior under test, consider a narrower integration test or a simpler production boundary.
18528
+
18529
+ ## Output
18530
+
18531
+ Report the RED command and expected failure, the GREEN command and passing result, any refactor rerun, and any TDD exception that required human approval.
17186
18532
 
17187
18533
  ## Safety
17188
18534
 
@@ -17211,6 +18557,55 @@ description: Use before handing off an implementation to compare the diff agains
17211
18557
  ## Output
17212
18558
 
17213
18559
  Return a concise final review with spec compliance, tests run, contract impact, security impact, and remaining risks.
18560
+ `;
18561
+ case "subagent-driven-change": return `---
18562
+ name: subagent-driven-change
18563
+ description: Use when a scoped implementation can be delegated to an implementation subagent and then independently reviewed for spec compliance before code quality.
18564
+ ---
18565
+
18566
+ <!-- Generated by Agent Profile Compiler. Do not edit by hand. -->
18567
+
18568
+ # Subagent-Driven Change
18569
+
18570
+ ## Preconditions
18571
+
18572
+ Use this workflow only when the task has a clear spec, acceptance criteria, and file ownership. Keep tightly coupled or architectural decisions in the parent session unless the user explicitly asks for delegation.
18573
+
18574
+ Required subagents: \`implementer\`, \`spec-reviewer\`, and \`code-quality-reviewer\`.
18575
+
18576
+ ## Fresh Context
18577
+
18578
+ Each subagent prompt must include the full task text, relevant spec excerpts, non-goals, acceptance criteria, file ownership, constraints, expected tests, and any command limits. Do not rely on hidden chat history or a previous subagent's memory.
18579
+
18580
+ ## Flow
18581
+
18582
+ 1. Dispatch \`implementer\` with one bounded task and the complete context it needs.
18583
+ 2. If \`implementer\` returns \`BLOCKED\` or \`NEEDS_CONTEXT\`, resolve that before continuing.
18584
+ 3. If \`implementer\` returns \`DONE_WITH_CONCERNS\`, read the concerns before review and decide whether to fix, narrow scope, or continue.
18585
+ 4. Dispatch \`spec-reviewer\` with the original task, relevant spec excerpts, changed files, and implementer report.
18586
+ 5. Fix or escalate every spec-review issue before requesting code-quality review.
18587
+ 6. Dispatch \`code-quality-reviewer\` only after spec review reports compliance.
18588
+ 7. Fix Critical and Important code-quality issues before handoff, or document why a finding is intentionally deferred.
18589
+ 8. Run the relevant tests, golden tests, and doctor/check commands required by the spec before final response.
18590
+
18591
+ ## Status Values
18592
+
18593
+ Implementation worker status values: \`DONE\`, \`DONE_WITH_CONCERNS\`, \`BLOCKED\`, \`NEEDS_CONTEXT\`.
18594
+
18595
+ Spec reviewer status values: \`COMPLIANT\`, \`ISSUES_FOUND\`, \`NEEDS_CONTEXT\`.
18596
+
18597
+ Code-quality reviewer status values: \`ACCEPTABLE\`, \`ISSUES_FOUND\`, \`NEEDS_CONTEXT\`.
18598
+
18599
+ ## Safety
18600
+
18601
+ - Do not ask subagents to commit, push, create branches, install dependencies, read secrets, contact production systems, or upload source unless the user explicitly requested that action.
18602
+ - Do not accept an implementation report without reading reviewer findings.
18603
+ - Do not run code-quality review before spec-compliance review passes.
18604
+ - Keep generated files deterministic and lockfile-tracked.
18605
+
18606
+ ## Output
18607
+
18608
+ Final handoff must list what changed, tests run, contract impact, security impact, remaining risks or TODOs, and whether the spec acceptance criteria are fully met.
17214
18609
  `;
17215
18610
  }
17216
18611
  }
@@ -17248,6 +18643,23 @@ Use the repository-local profile as the source of truth for agent behavior.
17248
18643
  - Ask before mutating files, running shell commands, installing dependencies, or using external network access.
17249
18644
  `;
17250
18645
  }
18646
+ function renderPlanningWorkflowGuideline() {
18647
+ return `<!-- Generated by Agent Profile Compiler. Do not edit by hand. -->
18648
+
18649
+ # Planning Workflow
18650
+
18651
+ Use this before implementation when a stakeholder request is rough, ambiguous, or not yet tied to an approved spec.
18652
+
18653
+ - Clarify the request one decision at a time before writing or changing specs.
18654
+ - Provide a recommended answer and short rationale for each open decision.
18655
+ - Check local specs, ADRs, docs, fixtures, and generated artifacts before asking questions.
18656
+ - Preserve product intent, non-goals, tradeoffs, durable terms, and hard-to-reverse decisions.
18657
+ - If no completed clarification exists, complete the grill-style clarification first.
18658
+ - After clarification, prepare an intent-first spec candidate and vertical TDD-ready issue briefs.
18659
+ - Include dependencies, expected RED proof, expected GREEN proof, file ownership, contract impact, security impact, and review expectations in each issue brief.
18660
+ - Do not create GitHub issues, write files, upload source, read secrets, install dependencies, or change runtime permissions unless explicitly requested and allowed.
18661
+ `;
18662
+ }
17251
18663
  function renderSddWorkflowGuideline() {
17252
18664
  return `<!-- Generated by Agent Profile Compiler. Do not edit by hand. -->
17253
18665
 
@@ -17276,6 +18688,18 @@ Test-driven development is required for this project.
17276
18688
  - Do not update golden fixtures to hide an unexplained behavior change.
17277
18689
  `;
17278
18690
  }
18691
+ function renderTypeScriptReactGuideline() {
18692
+ return renderTopicAsTabnineGuideline(REACT_STACK_TOPIC);
18693
+ }
18694
+ function renderCodeReviewGuideline() {
18695
+ return renderTopicAsTabnineGuideline(CODE_REVIEW_TOPIC);
18696
+ }
18697
+ function renderRefactoringGuideline() {
18698
+ return renderTopicAsTabnineGuideline(REFACTORING_TOPIC);
18699
+ }
18700
+ function renderDocumentationGuideline() {
18701
+ return renderTopicAsTabnineGuideline(DOCUMENTATION_TOPIC);
18702
+ }
17279
18703
  function renderTypeScriptSvelteGuideline() {
17280
18704
  return `<!-- Generated by Agent Profile Compiler. Do not edit by hand. -->
17281
18705
 
@@ -17334,14 +18758,115 @@ Final implementation review is required for this project.
17334
18758
  - List remaining risks or TODOs before considering the task complete.
17335
18759
  `;
17336
18760
  }
17337
- function renderCodexConfigToml() {
17338
- return `approval_policy = "on-request"
18761
+ function renderCodexConfigToml(profile) {
18762
+ const base = `approval_policy = "on-request"
17339
18763
  sandbox_mode = "workspace-write"
17340
18764
  allow_login_shell = false
17341
18765
 
17342
18766
  [sandbox_workspace_write]
17343
18767
  network_access = false
17344
18768
  `;
18769
+ if (!profile || getEnabledSubagents(profile).length === 0) return base;
18770
+ const defaults = getSubagentDefaults(profile);
18771
+ return `${base}
18772
+ [agents]
18773
+ max_threads = ${defaults.maxConcurrent}
18774
+ max_depth = ${defaults.maxDepth}
18775
+ `;
18776
+ }
18777
+ function renderClaudeSubagentFiles(profile) {
18778
+ const agents = getEnabledSubagents(profile);
18779
+ const effective = deriveEffectivePermissions(profile);
18780
+ return agents.map((agent) => createGeneratedTextFile(`.claude/agents/${agent.name}.md`, "claude-subagents", `targets/claude-subagents/${agent.name}@1`, renderClaudeSubagent(agent, effective)));
18781
+ }
18782
+ function renderCodexSubagentFiles(profile) {
18783
+ const agents = getEnabledSubagents(profile);
18784
+ const effective = deriveEffectivePermissions(profile);
18785
+ return agents.map((agent) => createGeneratedTextFile(`.codex/agents/${agent.name}.toml`, "codex-subagents", `targets/codex-subagents/${agent.name}@1`, renderCodexSubagent(agent, effective)));
18786
+ }
18787
+ function renderTabnineSubagentFiles(profile) {
18788
+ return getEnabledSubagents(profile).filter((agent) => agent.toolScope === "read-only").map((agent) => createGeneratedTextFile(`.tabnine/agent/agents/${agent.name}.md`, "tabnine-subagents", `targets/tabnine-subagents/${agent.name}@1`, renderTabnineSubagent(agent)));
18789
+ }
18790
+ function titleCaseFromKebab(name) {
18791
+ return name.split("-").filter((part) => part.length > 0).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
18792
+ }
18793
+ function renderClaudeSubagent(agent, effective) {
18794
+ const lines = ["---", `name: ${yamlScalarSafe(agent.name)}`];
18795
+ lines.push(`description: ${yamlScalarSafe(agent.description)}`);
18796
+ if (agent.toolScope === "read-only") lines.push("tools: Read, Glob, Grep");
18797
+ else {
18798
+ const tools = [
18799
+ "Read",
18800
+ "Glob",
18801
+ "Grep"
18802
+ ];
18803
+ if (effective.filesystem.write !== "deny") tools.push("Edit", "Write");
18804
+ if (effective.shell.run !== "deny") tools.push("Bash");
18805
+ if (effective.network.external !== "deny") tools.push("WebFetch");
18806
+ lines.push(`tools: ${tools.join(", ")}`);
18807
+ }
18808
+ const model = agent.modelPreference ?? "inherit";
18809
+ lines.push(`model: ${model === "inherit" ? "inherit" : "inherit"}`);
18810
+ if (agent.toolScope === "read-only") lines.push("permissionMode: plan");
18811
+ if (agent.maxTurns !== void 0) lines.push(`maxTurns: ${agent.maxTurns}`);
18812
+ lines.push("---", "");
18813
+ lines.push("<!-- Generated by Agent Profile Compiler. Do not edit by hand. -->");
18814
+ lines.push("");
18815
+ lines.push(`# ${titleCaseFromKebab(agent.name)}`);
18816
+ lines.push("");
18817
+ lines.push(agent.prompt.trim());
18818
+ lines.push("");
18819
+ return lines.join("\n");
18820
+ }
18821
+ function renderCodexSubagent(agent, effective) {
18822
+ const lines = [
18823
+ "# Generated by Agent Profile Compiler. Do not edit by hand.",
18824
+ "",
18825
+ `name = "${escapeTomlString(agent.name)}"`,
18826
+ `description = "${escapeTomlString(agent.description)}"`
18827
+ ];
18828
+ if (agent.toolScope === "workspace-write" && effective.filesystem.write !== "deny") lines.push(`sandbox_mode = "workspace-write"`);
18829
+ else lines.push(`sandbox_mode = "read-only"`);
18830
+ if (agent.prompt.includes(`"""`)) throw new Error(`Codex subagent ${agent.name} prompt contains a TOML triple-quote sequence; compile validation should have rejected this.`);
18831
+ lines.push("developer_instructions = \"\"\"");
18832
+ for (const promptLine of agent.prompt.trim().split(/\r?\n/u)) lines.push(promptLine);
18833
+ lines.push("\"\"\"");
18834
+ lines.push("");
18835
+ return lines.join("\n");
18836
+ }
18837
+ function renderTabnineSubagent(agent) {
18838
+ const lines = ["---", `name: ${yamlScalarSafe(agent.name)}`];
18839
+ lines.push(`description: ${yamlScalarSafe(agent.description)}`);
18840
+ lines.push("kind: local");
18841
+ lines.push("tools:");
18842
+ for (const tool of ["grep_search", "read_file"].sort()) lines.push(` - ${tool}`);
18843
+ if (agent.maxTurns !== void 0) lines.push(`max_turns: ${agent.maxTurns}`);
18844
+ if (agent.timeoutMinutes !== void 0) lines.push(`timeout_mins: ${agent.timeoutMinutes}`);
18845
+ lines.push("---", "");
18846
+ lines.push("<!-- Generated by Agent Profile Compiler. Do not edit by hand. -->");
18847
+ lines.push("");
18848
+ lines.push(`# ${titleCaseFromKebab(agent.name)}`);
18849
+ lines.push("");
18850
+ lines.push(agent.prompt.trim());
18851
+ lines.push("");
18852
+ return lines.join("\n");
18853
+ }
18854
+ function escapeTomlString(value) {
18855
+ return value.replace(/\\/gu, "\\\\").replace(/"/gu, "\\\"");
18856
+ }
18857
+ function yamlScalarSafe(value) {
18858
+ if (yamlScalarNeedsQuoting(value)) return JSON.stringify(value);
18859
+ return value;
18860
+ }
18861
+ function yamlScalarNeedsQuoting(value) {
18862
+ if (value.length === 0) return true;
18863
+ if (/[\r\n\t]/u.test(value)) return true;
18864
+ if (/^\s|\s$/u.test(value)) return true;
18865
+ if (/^[\-?:,\[\]{}#&*!|>'"%@`]/u.test(value)) return true;
18866
+ if (value.includes(": ") || value.includes(" #")) return true;
18867
+ if (/^(?:true|false|null|yes|no|on|off|~)$/iu.test(value)) return true;
18868
+ if (/^[+\-]?\d+(?:\.\d+)?(?:[eE][+\-]?\d+)?$/u.test(value)) return true;
18869
+ return false;
17345
18870
  }
17346
18871
  function renderAgentsMdTemplateSource() {
17347
18872
  return `# AGENTS.md
@@ -17380,6 +18905,14 @@ function guidelineTemplateSource(id, render) {
17380
18905
  source: render()
17381
18906
  };
17382
18907
  }
18908
+ function agentsMdTopicTemplateSource(id, topic) {
18909
+ return {
18910
+ id,
18911
+ target: "agents-md",
18912
+ version: "1",
18913
+ source: renderTopicAsAgentsMdSection(topic)
18914
+ };
18915
+ }
17383
18916
  function workflowSkillTemplateSource(id, target, skill) {
17384
18917
  return {
17385
18918
  id,
@@ -17418,9 +18951,19 @@ function renderClaudeSettingsJson() {
17418
18951
  }
17419
18952
  function getEnabledTargetIds(profile) {
17420
18953
  const targets = ["agents-md"];
17421
- if (profile.clients.tabnine.enabled) targets.push("tabnine-guidelines", "tabnine-mcp-config");
17422
- if (profile.clients.codex.enabled) targets.push("codex-config", "codex-workflow-skills");
17423
- if (profile.clients.claude.enabled) targets.push("claude-settings", "claude-mcp", "claude-md", "claude-workflow-skills");
18954
+ const subagentsEnabled = getEnabledSubagents(profile).length > 0;
18955
+ if (profile.clients.tabnine.enabled) {
18956
+ targets.push("tabnine-guidelines", "tabnine-mcp-config");
18957
+ if (subagentsEnabled) targets.push("tabnine-subagents");
18958
+ }
18959
+ if (profile.clients.codex.enabled) {
18960
+ targets.push("codex-config", "codex-workflow-skills");
18961
+ if (subagentsEnabled) targets.push("codex-subagents");
18962
+ }
18963
+ if (profile.clients.claude.enabled) {
18964
+ targets.push("claude-settings", "claude-mcp", "claude-md", "claude-workflow-skills");
18965
+ if (subagentsEnabled) targets.push("claude-subagents");
18966
+ }
17424
18967
  return targets;
17425
18968
  }
17426
18969
  function validateTargets(profile, targets, templates) {
@@ -17428,6 +18971,56 @@ function validateTargets(profile, targets, templates) {
17428
18971
  const templateIds = new Set(templates.map((template) => template.id));
17429
18972
  const enabledTargets = new Set(getEnabledTargetIds(profile));
17430
18973
  const issues = [];
18974
+ if (profile.workflow.subagentDrivenDevelopment === true) {
18975
+ const refs = new Set(getSubagentTemplateRefs(profile));
18976
+ const missing = SUBAGENT_TEMPLATE_NAMES.filter((name) => !refs.has(name));
18977
+ if (missing.length > 0) issues.push({
18978
+ code: "missing_required_template_reference",
18979
+ path: "/workflow/subagentDrivenDevelopment",
18980
+ expected: `useTemplate references for ${SUBAGENT_TEMPLATE_NAMES.join(", ")}`,
18981
+ actual: `missing ${missing.join(", ")}`,
18982
+ message: `workflow.subagentDrivenDevelopment requires capabilities.delegation.subagents.agents[].useTemplate references for ${missing.join(", ")}.`
18983
+ });
18984
+ }
18985
+ if (targets.includes("tabnine-subagents")) {
18986
+ const writeAgents = getEnabledSubagents(profile).filter((agent) => agent.toolScope === "workspace-write");
18987
+ for (const agent of writeAgents) issues.push({
18988
+ code: "unsafe_generated_content",
18989
+ path: `.tabnine/agent/agents/${agent.name}.md`,
18990
+ expected: "read-only Tabnine subagent",
18991
+ actual: "workspace-write Tabnine subagent",
18992
+ message: `tabnine-subagents cannot emit workspace-write agent ${agent.name} while Tabnine subagents are experimental/no-confirmation.`
18993
+ });
18994
+ }
18995
+ if (targets.includes("codex-subagents")) {
18996
+ const effective = deriveEffectivePermissions(profile);
18997
+ for (const agent of getEnabledSubagents(profile)) {
18998
+ if (agent.toolScope === "workspace-write" && effective.filesystem.write === "deny") issues.push({
18999
+ code: "unsafe_generated_content",
19000
+ path: `.codex/agents/${agent.name}.toml`,
19001
+ expected: "narrower than effectivePermissions",
19002
+ actual: "workspace-write subagent under filesystem.write=deny",
19003
+ message: `codex-subagents cannot emit workspace-write agent ${agent.name} because effectivePermissions.filesystem.write is deny.`
19004
+ });
19005
+ if (agent.prompt.includes(`"""`)) issues.push({
19006
+ code: "unsafe_generated_content",
19007
+ path: `.codex/agents/${agent.name}.toml`,
19008
+ expected: "prompt without TOML triple-quote sequence",
19009
+ actual: "prompt contains \"\"\" delimiter",
19010
+ message: `codex-subagents prompt for ${agent.name} contains a TOML triple-quote sequence that would break developer_instructions.`
19011
+ });
19012
+ }
19013
+ }
19014
+ if (targets.includes("claude-subagents")) {
19015
+ const effective = deriveEffectivePermissions(profile);
19016
+ for (const agent of getEnabledSubagents(profile)) if (agent.toolScope === "workspace-write" && effective.filesystem.write === "deny") issues.push({
19017
+ code: "unsafe_generated_content",
19018
+ path: `.claude/agents/${agent.name}.md`,
19019
+ expected: "narrower than effectivePermissions",
19020
+ actual: "workspace-write subagent under filesystem.write=deny",
19021
+ message: `claude-subagents cannot emit workspace-write agent ${agent.name} because effectivePermissions.filesystem.write is deny.`
19022
+ });
19023
+ }
17431
19024
  for (const target of targets) {
17432
19025
  if (!supportedTargets.has(target)) {
17433
19026
  issues.push({
@@ -17449,7 +19042,7 @@ function validateTargets(profile, targets, templates) {
17449
19042
  });
17450
19043
  continue;
17451
19044
  }
17452
- for (const templateId of getRequiredTemplateIds(target)) if (!templateIds.has(templateId)) issues.push({
19045
+ for (const templateId of getRequiredTemplateIds(target, profile)) if (!templateIds.has(templateId)) issues.push({
17453
19046
  code: "missing_template",
17454
19047
  path: target,
17455
19048
  expected: templateId,
@@ -17459,8 +19052,48 @@ function validateTargets(profile, targets, templates) {
17459
19052
  }
17460
19053
  return issues;
17461
19054
  }
17462
- function getRequiredTemplateIds(target) {
17463
- return TEMPLATE_SOURCES.filter((template) => template.target === target).map((template) => template.id);
19055
+ function getRequiredTemplateIdSet(targets, profile) {
19056
+ return new Set(targets.flatMap((target) => getRequiredTemplateIds(target, profile)));
19057
+ }
19058
+ function getRequiredTemplateIds(target, profile) {
19059
+ switch (target) {
19060
+ case "agents-md": return ["targets/agents-md@1", ...getRequiredAgentsMdTopicTemplateIds(profile)];
19061
+ case "tabnine-guidelines": return getRequiredTabnineGuidelineTemplateIds(profile);
19062
+ case "codex-workflow-skills": return getRequiredWorkflowSkillTemplateIds(profile, "codex-workflow-skills");
19063
+ case "claude-workflow-skills": return getRequiredWorkflowSkillTemplateIds(profile, "claude-workflow-skills");
19064
+ case "claude-subagents": return getEnabledSubagents(profile).map((agent) => `targets/claude-subagents/${agent.name}@1`);
19065
+ case "codex-subagents": return getEnabledSubagents(profile).map((agent) => `targets/codex-subagents/${agent.name}@1`);
19066
+ case "tabnine-subagents": return getEnabledSubagents(profile).filter((agent) => agent.toolScope === "read-only").map((agent) => `targets/tabnine-subagents/${agent.name}@1`);
19067
+ default: return TEMPLATE_SOURCES.filter((template) => template.target === target).map((template) => template.id);
19068
+ }
19069
+ }
19070
+ function getRequiredAgentsMdTopicTemplateIds(profile) {
19071
+ const ids = [];
19072
+ if (hasStack(profile, "frameworks", "react")) ids.push("targets/agents-md/30-stack-typescript-react@1");
19073
+ if (profile.workflow.codeReview === true) ids.push("targets/agents-md/60-code-review@1");
19074
+ if (profile.workflow.refactoring === true) ids.push("targets/agents-md/70-refactoring@1");
19075
+ if (profile.workflow.documentation === true) ids.push("targets/agents-md/80-documentation@1");
19076
+ return ids;
19077
+ }
19078
+ function getRequiredTabnineGuidelineTemplateIds(profile) {
19079
+ const ids = ["targets/tabnine-guidelines/00-general-agent-behavior@1"];
19080
+ if (profile.workflow.sdd) {
19081
+ ids.push("targets/tabnine-guidelines/05-planning-workflow@1");
19082
+ ids.push("targets/tabnine-guidelines/10-sdd-workflow@1");
19083
+ }
19084
+ if (profile.workflow.tdd) ids.push("targets/tabnine-guidelines/20-tdd-workflow@1");
19085
+ if (hasStack(profile, "languages", "typescript") && hasStack(profile, "frameworks", "sveltekit")) ids.push("targets/tabnine-guidelines/30-stack-typescript-svelte@1");
19086
+ if (hasStack(profile, "frameworks", "react")) ids.push("targets/tabnine-guidelines/30-stack-typescript-react@1");
19087
+ if (hasStack(profile, "languages", "java") && hasStack(profile, "frameworks", "spring-boot")) ids.push("targets/tabnine-guidelines/40-stack-java-spring@1");
19088
+ if (hasAnyStack(profile, "testing", ["playwright", "junit"])) ids.push("targets/tabnine-guidelines/50-testing-playwright-junit@1");
19089
+ if (profile.workflow.codeReview === true) ids.push("targets/tabnine-guidelines/60-code-review@1");
19090
+ if (profile.workflow.refactoring === true) ids.push("targets/tabnine-guidelines/70-refactoring@1");
19091
+ if (profile.workflow.documentation === true) ids.push("targets/tabnine-guidelines/80-documentation@1");
19092
+ if (profile.workflow.finalReview) ids.push("targets/tabnine-guidelines/90-final-review@1");
19093
+ return ids;
19094
+ }
19095
+ function getRequiredWorkflowSkillTemplateIds(profile, target) {
19096
+ return WORKFLOW_SKILLS.filter((skill) => profile.workflow[skill.workflowFlag]).map((skill) => getWorkflowSkillTemplateId(target, skill.id));
17464
19097
  }
17465
19098
  function uniqueTargets(targets) {
17466
19099
  return Array.from(new Set(targets));
@@ -17498,6 +19131,92 @@ function compareIssues(left, right) {
17498
19131
  }
17499
19132
  //#endregion
17500
19133
  //#region ../../packages/compiler/src/write-plan.ts
19134
+ async function planWrites(request) {
19135
+ return planWritesWithResolvedRoot(await fsPromises.realpath(path.resolve(request.rootDir)), request.writes);
19136
+ }
19137
+ async function planWritesWithResolvedRoot(rootRealPath, plannedWrites) {
19138
+ const writes = normalizeWrites(plannedWrites);
19139
+ const actions = [];
19140
+ for (const write of writes) {
19141
+ const current = await readOptionalFile(await assertWritePathContained(rootRealPath, write.path));
19142
+ const action = current ? Buffer.from(current).equals(Buffer.from(write.bytes)) ? "unchanged" : "change" : "create";
19143
+ actions.push({
19144
+ path: write.path,
19145
+ action,
19146
+ plannedBytes: write.bytes.byteLength
19147
+ });
19148
+ }
19149
+ return {
19150
+ actions,
19151
+ counts: countActions(actions)
19152
+ };
19153
+ }
19154
+ async function applyWritePlan(request) {
19155
+ const rootRealPath = await fsPromises.realpath(path.resolve(request.rootDir));
19156
+ const writes = normalizeWrites(request.writes);
19157
+ const plan = await planWritesWithResolvedRoot(rootRealPath, writes);
19158
+ const writesByPath = new Map(writes.map((write) => [write.path, write]));
19159
+ for (const action of plan.actions) {
19160
+ if (action.action === "unchanged") continue;
19161
+ const write = writesByPath.get(action.path);
19162
+ if (!write) continue;
19163
+ const absolutePath = await assertWritePathContained(rootRealPath, write.path);
19164
+ await fsPromises.mkdir(path.dirname(absolutePath), { recursive: true });
19165
+ await fsPromises.writeFile(absolutePath, write.bytes);
19166
+ }
19167
+ return plan;
19168
+ }
19169
+ function normalizeWrites(writes) {
19170
+ return writes.map((write) => ({
19171
+ path: safeOutputPath(write.path),
19172
+ bytes: typeof write.bytes === "string" ? Buffer.from(write.bytes, "utf8") : write.bytes
19173
+ })).sort((left, right) => compareText(left.path, right.path));
19174
+ }
19175
+ function countActions(actions) {
19176
+ return {
19177
+ create: actions.filter((action) => action.action === "create").length,
19178
+ change: actions.filter((action) => action.action === "change").length,
19179
+ unchanged: actions.filter((action) => action.action === "unchanged").length
19180
+ };
19181
+ }
19182
+ async function assertWritePathContained(rootRealPath, relativePath) {
19183
+ const safePath = safeOutputPath(relativePath);
19184
+ const absolutePath = path.resolve(rootRealPath, ...safePath.split("/").filter(Boolean));
19185
+ if (!isContainedBy(rootRealPath, absolutePath)) throw new Error(`Planned write escapes root: ${safePath}`);
19186
+ const existingTarget = await lstatOptional$1(absolutePath);
19187
+ if (existingTarget) {
19188
+ if (existingTarget.isSymbolicLink()) throw new Error(`Planned write target is a symlink (refusing to follow): ${safePath}`);
19189
+ if (!isContainedBy(rootRealPath, await fsPromises.realpath(absolutePath))) throw new Error(`Planned write target escapes root: ${safePath}`);
19190
+ }
19191
+ const existingParent = await findExistingAncestor(path.dirname(absolutePath));
19192
+ if (!isContainedBy(rootRealPath, await fsPromises.realpath(existingParent))) throw new Error(`Planned write parent escapes root: ${safePath}`);
19193
+ return absolutePath;
19194
+ }
19195
+ async function findExistingAncestor(startPath) {
19196
+ let current = startPath;
19197
+ while (true) {
19198
+ if (await lstatOptional$1(current)) return current;
19199
+ const parent = path.dirname(current);
19200
+ if (parent === current) throw new Error(`No existing parent directory for ${startPath}`);
19201
+ current = parent;
19202
+ }
19203
+ }
19204
+ async function readOptionalFile(absolutePath) {
19205
+ try {
19206
+ return await fsPromises.readFile(absolutePath);
19207
+ } catch (error) {
19208
+ if (isNodeError(error) && error.code === "ENOENT") return;
19209
+ throw error;
19210
+ }
19211
+ }
19212
+ async function lstatOptional$1(absolutePath) {
19213
+ try {
19214
+ return await fsPromises.lstat(absolutePath);
19215
+ } catch (error) {
19216
+ if (isNodeError(error) && error.code === "ENOENT") return;
19217
+ throw error;
19218
+ }
19219
+ }
17501
19220
  function isContainedBy(rootPath, candidatePath) {
17502
19221
  const relative = path.relative(rootPath, candidatePath);
17503
19222
  return relative === "" || !relative.startsWith("..") && !path.isAbsolute(relative);
@@ -17592,6 +19311,599 @@ function computeFileEtag(bytes) {
17592
19311
  return "sha256:" + createHash("sha256").update(bytes).digest("hex");
17593
19312
  }
17594
19313
  //#endregion
19314
+ //#region ../../packages/compiler/src/import-report.ts
19315
+ var PHASE_14_SUPPORTED_PATHS = [
19316
+ {
19317
+ path: "AGENTS.md",
19318
+ kind: "root-instructions",
19319
+ isLocalRuntime: false
19320
+ },
19321
+ {
19322
+ path: "CLAUDE.md",
19323
+ kind: "root-instructions",
19324
+ isLocalRuntime: false
19325
+ },
19326
+ {
19327
+ path: ".claude/settings.json",
19328
+ kind: "client-config",
19329
+ isLocalRuntime: false
19330
+ },
19331
+ {
19332
+ path: ".claude/settings.local.json",
19333
+ kind: "client-config",
19334
+ isLocalRuntime: true
19335
+ },
19336
+ {
19337
+ path: ".codex/config.toml",
19338
+ kind: "client-config",
19339
+ isLocalRuntime: true
19340
+ },
19341
+ {
19342
+ path: ".codex/hooks.json",
19343
+ kind: "client-config",
19344
+ isLocalRuntime: true
19345
+ },
19346
+ {
19347
+ path: ".mcp.json",
19348
+ kind: "mcp-config",
19349
+ isLocalRuntime: true
19350
+ }
19351
+ ];
19352
+ var PHASE_14_SCAN_DIRS = [
19353
+ {
19354
+ root: ".agents/skills",
19355
+ kind: "workflow-skill",
19356
+ fileFilter: (rel) => rel.endsWith("/SKILL.md"),
19357
+ recursive: true
19358
+ },
19359
+ {
19360
+ root: ".claude/skills",
19361
+ kind: "workflow-skill",
19362
+ fileFilter: (rel) => rel.endsWith("/SKILL.md"),
19363
+ recursive: true
19364
+ },
19365
+ {
19366
+ root: ".claude/agents",
19367
+ kind: "subagent",
19368
+ fileFilter: (rel) => rel.endsWith(".md"),
19369
+ recursive: false
19370
+ },
19371
+ {
19372
+ root: ".codex/agents",
19373
+ kind: "subagent",
19374
+ fileFilter: (rel) => rel.endsWith(".toml"),
19375
+ recursive: false
19376
+ },
19377
+ {
19378
+ root: ".tabnine/agent/agents",
19379
+ kind: "subagent",
19380
+ fileFilter: (rel) => rel.endsWith(".md"),
19381
+ recursive: false
19382
+ }
19383
+ ];
19384
+ var RECOMMENDED_IGNORE_LINES = [
19385
+ ".cce/",
19386
+ ".mcp.json",
19387
+ ".claude/settings.local.json",
19388
+ ".claude/worktrees/",
19389
+ ".codex/config.toml",
19390
+ ".codex/hooks.json"
19391
+ ];
19392
+ async function buildPhase14ImportReport(input) {
19393
+ const files = [];
19394
+ let wouldUpdateRegions = 0;
19395
+ let preservedManualFiles = 0;
19396
+ let conflicts = 0;
19397
+ const collisionsByKey = /* @__PURE__ */ new Map();
19398
+ const lockfile = await readLockfileForRegions(input.rootDir);
19399
+ const ownershipByPath = /* @__PURE__ */ new Map();
19400
+ if (lockfile) for (const output of lockfile.outputs) ownershipByPath.set(output.path, output.ownership);
19401
+ for (const entry of PHASE_14_SUPPORTED_PATHS) {
19402
+ const read = await readRegionAwareFile(input.rootDir, entry.path);
19403
+ if (read.refused) {
19404
+ files.push({
19405
+ path: entry.path,
19406
+ exists: true,
19407
+ kind: entry.kind,
19408
+ ownership: "unknown",
19409
+ tags: [],
19410
+ action: "refuse-conflict",
19411
+ notes: ["symlinked; Phase 14 refuses to follow file symlinks"]
19412
+ });
19413
+ conflicts += 1;
19414
+ continue;
19415
+ }
19416
+ const existing = read.bytes;
19417
+ if (!existing) {
19418
+ if (entry.kind === "root-instructions") files.push({
19419
+ path: entry.path,
19420
+ exists: false,
19421
+ kind: entry.kind,
19422
+ ownership: "unknown",
19423
+ tags: [],
19424
+ action: "create",
19425
+ notes: []
19426
+ });
19427
+ continue;
19428
+ }
19429
+ const bytes = Buffer.from(existing);
19430
+ const tags = [];
19431
+ if (entry.isLocalRuntime) tags.push("local-runtime");
19432
+ if (containsAbsolutePathLiteral(bytes)) tags.push("contains-absolute-path");
19433
+ if (entry.kind === "client-config" && !entry.isLocalRuntime) {
19434
+ const ownership = ownershipByPath.get(entry.path) ?? "generated-owned";
19435
+ files.push({
19436
+ path: entry.path,
19437
+ exists: true,
19438
+ kind: entry.kind,
19439
+ ownership,
19440
+ tags,
19441
+ action: "preserve",
19442
+ notes: ["generated client config; refresh via `agent-profile compile --write`"]
19443
+ });
19444
+ preservedManualFiles += 1;
19445
+ continue;
19446
+ }
19447
+ if (entry.kind !== "root-instructions") {
19448
+ files.push({
19449
+ path: entry.path,
19450
+ exists: true,
19451
+ kind: entry.kind,
19452
+ ownership: "manual-owned",
19453
+ tags,
19454
+ action: "ignore-local-runtime",
19455
+ notes: entry.kind === "mcp-config" ? ["contains MCP entries; not imported into ai-profile.yaml in Phase 14"] : ["local runtime config; not adopted by Phase 14"]
19456
+ });
19457
+ preservedManualFiles += 1;
19458
+ continue;
19459
+ }
19460
+ if (hasAllRegionMarkers(bytes)) {
19461
+ const parsed = parseMixedFile(bytes);
19462
+ if (!parsed.ok) {
19463
+ files.push({
19464
+ path: entry.path,
19465
+ exists: true,
19466
+ kind: entry.kind,
19467
+ ownership: "unknown",
19468
+ tags,
19469
+ action: "refuse-conflict",
19470
+ notes: parsed.issues.map((item) => item.message)
19471
+ });
19472
+ conflicts += 1;
19473
+ continue;
19474
+ }
19475
+ files.push({
19476
+ path: entry.path,
19477
+ exists: true,
19478
+ kind: entry.kind,
19479
+ ownership: "mixed",
19480
+ tags,
19481
+ action: "update-generated-region",
19482
+ notes: []
19483
+ });
19484
+ if (input.strategy === "regions") wouldUpdateRegions += 1;
19485
+ continue;
19486
+ }
19487
+ if (hasAnyRegionMarker(bytes)) {
19488
+ files.push({
19489
+ path: entry.path,
19490
+ exists: true,
19491
+ kind: entry.kind,
19492
+ ownership: "unknown",
19493
+ tags,
19494
+ action: "refuse-conflict",
19495
+ notes: ["partial region markers; manual repair required"]
19496
+ });
19497
+ conflicts += 1;
19498
+ continue;
19499
+ }
19500
+ if (hasLegacyGeneratedMarker(bytes)) tags.push("generated-looking");
19501
+ if (input.strategy === "regions") {
19502
+ files.push({
19503
+ path: entry.path,
19504
+ exists: true,
19505
+ kind: entry.kind,
19506
+ ownership: "unknown",
19507
+ tags,
19508
+ action: "insert-regions",
19509
+ notes: ["existing content will be preserved in manual region"]
19510
+ });
19511
+ wouldUpdateRegions += 1;
19512
+ } else {
19513
+ files.push({
19514
+ path: entry.path,
19515
+ exists: true,
19516
+ kind: entry.kind,
19517
+ ownership: "unknown",
19518
+ tags,
19519
+ action: "preserve",
19520
+ notes: ["Run init --import --strategy regions --write to adopt into mixed ownership"]
19521
+ });
19522
+ preservedManualFiles += 1;
19523
+ }
19524
+ }
19525
+ for (const scan of PHASE_14_SCAN_DIRS) {
19526
+ const { files: discovered, refusals: scanRefusals } = await listFilesUnder(input.rootDir, scan.root, scan.recursive);
19527
+ for (const refusedPath of scanRefusals) {
19528
+ files.push({
19529
+ path: refusedPath,
19530
+ exists: true,
19531
+ kind: scan.kind,
19532
+ ownership: "unknown",
19533
+ tags: [],
19534
+ action: "refuse-conflict",
19535
+ notes: ["symlinked; Phase 14 refuses to follow file symlinks"]
19536
+ });
19537
+ conflicts += 1;
19538
+ }
19539
+ for (const relativePath of discovered) {
19540
+ if (!scan.fileFilter(relativePath)) continue;
19541
+ const read = await readRegionAwareFile(input.rootDir, relativePath);
19542
+ const tags = [];
19543
+ if (read.bytes) {
19544
+ const name = extractDeclaredName(Buffer.from(read.bytes), relativePath);
19545
+ if (name) recordName(scan.kind === "workflow-skill" ? "workflow-skill" : "subagent", name, relativePath, collisionsByKey);
19546
+ }
19547
+ if (read.refused) {
19548
+ files.push({
19549
+ path: relativePath,
19550
+ exists: true,
19551
+ kind: scan.kind,
19552
+ ownership: "unknown",
19553
+ tags,
19554
+ action: "refuse-conflict",
19555
+ notes: ["symlinked; Phase 14 refuses to follow file symlinks"]
19556
+ });
19557
+ conflicts += 1;
19558
+ continue;
19559
+ }
19560
+ if (!read.bytes) continue;
19561
+ const lockOwnership = ownershipByPath.get(relativePath);
19562
+ if (lockOwnership === "generated-owned") {
19563
+ files.push({
19564
+ path: relativePath,
19565
+ exists: true,
19566
+ kind: scan.kind,
19567
+ ownership: "generated-owned",
19568
+ tags,
19569
+ action: "preserve",
19570
+ notes: ["lockfile-owned generated output; refresh via `agent-profile compile --write`"]
19571
+ });
19572
+ preservedManualFiles += 1;
19573
+ continue;
19574
+ }
19575
+ if (lockOwnership === "mixed") {
19576
+ files.push({
19577
+ path: relativePath,
19578
+ exists: true,
19579
+ kind: scan.kind,
19580
+ ownership: "mixed",
19581
+ tags,
19582
+ action: "update-generated-region",
19583
+ notes: ["lockfile-owned mixed file; generated region is updated on compile --write"]
19584
+ });
19585
+ if (input.strategy === "regions") wouldUpdateRegions += 1;
19586
+ continue;
19587
+ }
19588
+ files.push({
19589
+ path: relativePath,
19590
+ exists: true,
19591
+ kind: scan.kind,
19592
+ ownership: "manual-owned",
19593
+ tags,
19594
+ action: "preserve",
19595
+ notes: [scan.kind === "workflow-skill" ? "existing workflow skill; not adopted as generated output" : "existing subagent file; not adopted as generated output"]
19596
+ });
19597
+ preservedManualFiles += 1;
19598
+ }
19599
+ }
19600
+ const gitignore = (await getLocalRuntimeGitignoreFindings(input.rootDir)).map((finding) => ({
19601
+ path: ".gitignore",
19602
+ line: finding.line,
19603
+ action: finding.action === "already-present" ? "already-present" : input.mode === "write" ? "would-add" : "suggest-add",
19604
+ reason: finding.reason
19605
+ }));
19606
+ const collisions = [];
19607
+ for (const [key, paths] of collisionsByKey) {
19608
+ if (paths.length < 2) continue;
19609
+ const [kindPart, name] = key.split("\0");
19610
+ collisions.push({
19611
+ name,
19612
+ kind: kindPart === "workflow-skill" ? "workflow-skill" : "subagent",
19613
+ paths: [...paths].sort()
19614
+ });
19615
+ for (const collidingPath of paths) {
19616
+ const row = files.find((f) => f.path === collidingPath);
19617
+ if (row && !row.notes.some((n) => n.startsWith("name collision"))) {
19618
+ const others = paths.filter((p) => p !== collidingPath).sort();
19619
+ row.notes.push(`name collision: \"${name}\" also declared by ${others.join(", ")}`);
19620
+ }
19621
+ }
19622
+ }
19623
+ collisions.sort((left, right) => {
19624
+ if (left.kind !== right.kind) return left.kind === "workflow-skill" ? -1 : 1;
19625
+ return left.name < right.name ? -1 : left.name > right.name ? 1 : 0;
19626
+ });
19627
+ return {
19628
+ command: "init",
19629
+ mode: input.mode,
19630
+ strategy: input.strategy,
19631
+ root: ".",
19632
+ profilePath: input.profilePath,
19633
+ stack: {
19634
+ languages: [...input.stack.languages].sort(),
19635
+ frameworks: [...input.stack.frameworks].sort(),
19636
+ packageManagers: [...input.stack.packageManagers].sort(),
19637
+ testing: [...input.stack.testing].sort()
19638
+ },
19639
+ files: files.sort((left, right) => left.path < right.path ? -1 : left.path > right.path ? 1 : 0),
19640
+ gitignore,
19641
+ collisions,
19642
+ summary: {
19643
+ wouldCreateProfile: input.wouldCreateProfile,
19644
+ wouldUpdateRegions,
19645
+ preservedManualFiles,
19646
+ conflicts,
19647
+ nameCollisions: collisions.length
19648
+ }
19649
+ };
19650
+ }
19651
+ function recordName(kind, name, path, map) {
19652
+ const key = `${kind}\0${name}`;
19653
+ const existing = map.get(key);
19654
+ if (existing) existing.push(path);
19655
+ else map.set(key, [path]);
19656
+ }
19657
+ /**
19658
+ * Extract the declared `name:` value from a SKILL.md / claude-style
19659
+ * subagent (.md with YAML frontmatter) or codex-style subagent (.toml).
19660
+ *
19661
+ * This deliberately avoids pulling in a YAML or TOML parser — the
19662
+ * relevant section is small, the line shape is fixed, and we want the
19663
+ * shared report module to stay dependency-light. Returns undefined when
19664
+ * no name is found; callers treat that as "this file does not
19665
+ * participate in collision detection."
19666
+ */
19667
+ function extractDeclaredName(bytes, relativePath) {
19668
+ const text = bytes.toString("utf8");
19669
+ if (relativePath.endsWith(".toml")) return findTomlTopLevelName(text);
19670
+ if (relativePath.endsWith(".md")) return findYamlFrontmatterName(text);
19671
+ }
19672
+ function findYamlFrontmatterName(text) {
19673
+ const lines = text.split(/\r?\n/u);
19674
+ if (lines.length === 0 || lines[0].trim() !== "---") return void 0;
19675
+ for (let index = 1; index < lines.length; index += 1) {
19676
+ const line = lines[index];
19677
+ if (line.trim() === "---") return void 0;
19678
+ if (!line.startsWith("name")) continue;
19679
+ const match = line.match(/^name\s*:\s*(.+?)\s*$/u);
19680
+ if (!match) continue;
19681
+ return stripYamlQuotes(match[1]);
19682
+ }
19683
+ }
19684
+ function findTomlTopLevelName(text) {
19685
+ const lines = text.split(/\r?\n/u);
19686
+ for (const line of lines) {
19687
+ const trimmed = line.trim();
19688
+ if (trimmed.startsWith("#") || trimmed === "") continue;
19689
+ if (trimmed.startsWith("[")) break;
19690
+ const match = trimmed.match(/^name\s*=\s*(.+?)\s*$/u);
19691
+ if (!match) continue;
19692
+ return stripTomlQuotes(stripInlineTomlComment(match[1]));
19693
+ }
19694
+ }
19695
+ function stripInlineTomlComment(value) {
19696
+ let inDoubleQuote = false;
19697
+ let inSingleQuote = false;
19698
+ for (let index = 0; index < value.length; index += 1) {
19699
+ const char = value[index];
19700
+ if (char === "\"" && !inSingleQuote) {
19701
+ if (inDoubleQuote && value[index - 1] === "\\") continue;
19702
+ inDoubleQuote = !inDoubleQuote;
19703
+ continue;
19704
+ }
19705
+ if (char === "'" && !inDoubleQuote) {
19706
+ inSingleQuote = !inSingleQuote;
19707
+ continue;
19708
+ }
19709
+ if (char === "#" && !inDoubleQuote && !inSingleQuote) return value.slice(0, index).replace(/\s+$/u, "");
19710
+ }
19711
+ return value.replace(/\s+$/u, "");
19712
+ }
19713
+ function stripYamlQuotes(value) {
19714
+ if (value.length >= 2) {
19715
+ const first = value[0];
19716
+ const last = value[value.length - 1];
19717
+ if (first === "\"" && last === "\"" || first === "'" && last === "'") return value.slice(1, -1);
19718
+ }
19719
+ return value;
19720
+ }
19721
+ function stripTomlQuotes(value) {
19722
+ if (value.startsWith("\"") && value.endsWith("\"") && value.length >= 2) return value.slice(1, -1);
19723
+ if (value.startsWith("'") && value.endsWith("'") && value.length >= 2) return value.slice(1, -1);
19724
+ return value;
19725
+ }
19726
+ async function readRegionAwareFile(rootDir, relativePath) {
19727
+ const safePath = safeOutputPath(relativePath);
19728
+ const absolutePath = path.resolve(rootDir, ...safePath.split("/"));
19729
+ let stat;
19730
+ try {
19731
+ stat = await fsPromises.lstat(absolutePath);
19732
+ } catch (error) {
19733
+ if (isNodeNotFound(error)) return {
19734
+ refused: false,
19735
+ bytes: void 0
19736
+ };
19737
+ throw error;
19738
+ }
19739
+ if (stat.isSymbolicLink()) return { refused: true };
19740
+ if (!stat.isFile()) return {
19741
+ refused: false,
19742
+ bytes: void 0
19743
+ };
19744
+ return {
19745
+ refused: false,
19746
+ bytes: await fsPromises.readFile(absolutePath)
19747
+ };
19748
+ }
19749
+ async function listFilesUnder(rootDir, relativeRoot, recursive) {
19750
+ const files = [];
19751
+ const refusals = [];
19752
+ const rootStat = await lstatOptional(path.join(rootDir, relativeRoot));
19753
+ if (!rootStat) return {
19754
+ files: [],
19755
+ refusals: []
19756
+ };
19757
+ if (rootStat.isSymbolicLink()) return {
19758
+ files: [],
19759
+ refusals: [relativeRoot]
19760
+ };
19761
+ if (!rootStat.isDirectory()) return {
19762
+ files: [],
19763
+ refusals: []
19764
+ };
19765
+ await walk(rootDir, relativeRoot, recursive, files, refusals);
19766
+ return {
19767
+ files: files.sort(),
19768
+ refusals: refusals.sort()
19769
+ };
19770
+ }
19771
+ async function walk(rootDir, relativeRoot, recursive, out, refusals) {
19772
+ let entries;
19773
+ try {
19774
+ entries = await fsPromises.readdir(path.join(rootDir, relativeRoot), { withFileTypes: true });
19775
+ } catch (error) {
19776
+ if (isNodeNotFound(error)) return;
19777
+ throw error;
19778
+ }
19779
+ for (const entry of entries) {
19780
+ const child = `${relativeRoot}/${entry.name}`;
19781
+ if (entry.isSymbolicLink()) {
19782
+ refusals.push(child);
19783
+ continue;
19784
+ }
19785
+ if (entry.isDirectory() && recursive) {
19786
+ await walk(rootDir, child, recursive, out, refusals);
19787
+ continue;
19788
+ }
19789
+ if (entry.isFile()) out.push(child);
19790
+ }
19791
+ }
19792
+ async function lstatOptional(absolutePath) {
19793
+ try {
19794
+ return await fsPromises.lstat(absolutePath);
19795
+ } catch (error) {
19796
+ if (isNodeNotFound(error)) return void 0;
19797
+ throw error;
19798
+ }
19799
+ }
19800
+ async function readOptionalBytes(rootDir, relativePath) {
19801
+ const result = await readRegionAwareFile(rootDir, relativePath);
19802
+ if (result.refused) return void 0;
19803
+ return result.bytes;
19804
+ }
19805
+ async function readOptionalText(rootDir, relativePath) {
19806
+ const bytes = await readOptionalBytes(rootDir, relativePath);
19807
+ if (!bytes) return void 0;
19808
+ return Buffer.from(bytes).toString("utf8");
19809
+ }
19810
+ async function readLockfileForRegions(rootDir) {
19811
+ const bytes = await readOptionalBytes(rootDir, "ai-profile.lock");
19812
+ if (!bytes) return void 0;
19813
+ const result = validateLockfileText(Buffer.from(bytes).toString("utf8"));
19814
+ if (!result.ok) return void 0;
19815
+ return toLockfileV2View(result.lockfile);
19816
+ }
19817
+ async function getLocalRuntimeGitignoreFindings(rootDir) {
19818
+ const lines = (await readOptionalText(rootDir, ".gitignore").catch(() => void 0) ?? "").split(/\r?\n/u).map((line) => line.trim()).filter((line) => line !== "" && !line.startsWith("#"));
19819
+ const findings = [];
19820
+ for (const recommended of RECOMMENDED_IGNORE_LINES) {
19821
+ const present = lines.some((line) => {
19822
+ return line.replace(/^\//u, "").replace(/\/$/u, "") === recommended.replace(/\/$/u, "");
19823
+ });
19824
+ findings.push({
19825
+ line: recommended,
19826
+ action: present ? "already-present" : "would-add",
19827
+ reason: "local runtime or machine-specific path"
19828
+ });
19829
+ }
19830
+ return findings;
19831
+ }
19832
+ function containsAbsolutePathLiteral(bytes) {
19833
+ const text = bytes.toString("utf8");
19834
+ return /[A-Z]:\\\\|"\/[A-Za-z]/u.test(text);
19835
+ }
19836
+ function isNodeNotFound(error) {
19837
+ return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
19838
+ }
19839
+ var REGION_AWARE_ROOT_PATHS = ["AGENTS.md", "CLAUDE.md"];
19840
+ async function planRootInstructionsAdoption(rootDir, generatedBytesByPath = /* @__PURE__ */ new Map()) {
19841
+ const results = [];
19842
+ for (const relativePath of REGION_AWARE_ROOT_PATHS) {
19843
+ const read = await readRegionAwareFile(rootDir, relativePath);
19844
+ if (read.refused) {
19845
+ results.push({
19846
+ ok: false,
19847
+ path: relativePath,
19848
+ reason: "symlink"
19849
+ });
19850
+ continue;
19851
+ }
19852
+ const existing = read.bytes;
19853
+ if (!existing) {
19854
+ results.push({
19855
+ ok: false,
19856
+ path: relativePath,
19857
+ reason: "missing-file"
19858
+ });
19859
+ continue;
19860
+ }
19861
+ const compiled = generatedBytesByPath.get(relativePath);
19862
+ if (!compiled) {
19863
+ results.push({
19864
+ ok: false,
19865
+ path: relativePath,
19866
+ reason: "missing-generated-bytes"
19867
+ });
19868
+ continue;
19869
+ }
19870
+ const generatedInner = Buffer.from(compiled);
19871
+ const existingBuffer = Buffer.from(existing);
19872
+ if (hasAllRegionMarkers(existingBuffer)) {
19873
+ const updated = replaceGeneratedRegion(existingBuffer, generatedInner);
19874
+ if (updated) results.push({
19875
+ ok: true,
19876
+ path: relativePath,
19877
+ bytes: updated
19878
+ });
19879
+ else results.push({
19880
+ ok: false,
19881
+ path: relativePath,
19882
+ reason: "duplicate-markers"
19883
+ });
19884
+ continue;
19885
+ }
19886
+ if (hasAnyRegionMarker(existingBuffer)) {
19887
+ results.push({
19888
+ ok: false,
19889
+ path: relativePath,
19890
+ reason: "partial-markers"
19891
+ });
19892
+ continue;
19893
+ }
19894
+ const mixed = serializeMixedFile({
19895
+ generatedInner,
19896
+ manualInner: existingBuffer
19897
+ });
19898
+ results.push({
19899
+ ok: true,
19900
+ path: relativePath,
19901
+ bytes: mixed
19902
+ });
19903
+ }
19904
+ return results;
19905
+ }
19906
+ //#endregion
17595
19907
  //#region src/lib/server/projectContext.ts
17596
19908
  var PROFILE_FILENAME = "ai-profile.yaml";
17597
19909
  /**
@@ -17672,5 +19984,5 @@ function truncatePreview(text, capBytes = 256 * 1024) {
17672
19984
  };
17673
19985
  }
17674
19986
 
17675
- export { ProfileWriteError as P, containsSecretLikeLiteral as a, createLockfileFile as b, compileProfile as c, sha256Hex as d, deriveEffectivePermissions as e, computeFileEtag as f, validateProfileValue as g, renderProfileYaml as h, redactIfSecretLike as i, loadProjectContext as l, normalizeSafety as n, parseProfileYaml as p, resolveProjectRoot as r, safeOutputPath as s, truncatePreview as t, validateLockfileText as v, writeProfileAtomic as w };
17676
- //# sourceMappingURL=projectContext-Cxsfz84C.js.map
19987
+ export { writeProfileAtomic as A, ProfileWriteError as B, computeFileEtag as C, validateProfileValue as D, renderProfileYaml as E, truncatePreview as F, PHASE_14_SUPPORTED_PATHS as P, REGION_AWARE_ROOT_PATHS as R, applyWritePlan as a, buildPhase14ImportReport as b, compileProfile as c, deriveEffectivePermissions as d, containsSecretLikeLiteral as e, hasAnyRegionMarker as f, parseMixedFile as g, hasAllRegionMarkers as h, hasLegacyGeneratedMarker as i, createLockfileFile as j, sha256Hex as k, getEnabledSubagents as l, isSubagentBuiltinNameCollision as m, normalizeSafety as n, readLockfileForRegions as o, parseProfileYaml as p, planRootInstructionsAdoption as q, resolveProjectRoot as r, safeOutputPath as s, toLockfileV2View as t, planWrites as u, validateLockfileText as v, readRegionAwareFile as w, redactIfSecretLike as x, PHASE_14_SCAN_DIRS as y, loadProjectContext as z };
19988
+ //# sourceMappingURL=projectContext-B1D-bieW.js.map