agentix-cli 0.129.0 → 0.131.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 (203) hide show
  1. package/dist/{App-G37JNRBW.js → App-WZ3HAKES.js} +2 -2
  2. package/dist/{ChatApp-NCKC7C3L.js → ChatApp-K4HDJL2S.js} +2 -2
  3. package/dist/absorb-eval-ER27DHHK.js +2 -0
  4. package/dist/{agent-LJ4SUQCC.js → agent-AQSVISXX.js} +2 -2
  5. package/dist/article-sync-4NOPOQU7.js +2 -0
  6. package/dist/{board-dashboard-LZJT4YWV.js → board-dashboard-3AI2Z2SP.js} +248 -211
  7. package/dist/board-dashboard-3AI2Z2SP.js.map +1 -0
  8. package/dist/chunk-2SXF66O6.js +55 -0
  9. package/dist/chunk-2SXF66O6.js.map +1 -0
  10. package/dist/{chunk-AMW2R676.js → chunk-2YB2G2BP.js} +3 -3
  11. package/dist/{chunk-AMW2R676.js.map → chunk-2YB2G2BP.js.map} +1 -1
  12. package/dist/chunk-2ZDV3DCT.js +52 -0
  13. package/dist/chunk-2ZDV3DCT.js.map +1 -0
  14. package/dist/chunk-3UOTLMXD.js +4 -0
  15. package/dist/chunk-3UOTLMXD.js.map +1 -0
  16. package/dist/chunk-5BI2T3WD.js +3 -0
  17. package/dist/chunk-5BI2T3WD.js.map +1 -0
  18. package/dist/{chunk-VJRITDSQ.js → chunk-6O6NW3ZG.js} +2 -2
  19. package/dist/chunk-6TURWSMN.js +3 -0
  20. package/dist/{chunk-VD7IO653.js.map → chunk-6TURWSMN.js.map} +1 -1
  21. package/dist/{chunk-BGG3ZSMW.js → chunk-7LN4VKDU.js} +14 -16
  22. package/dist/chunk-7LN4VKDU.js.map +1 -0
  23. package/dist/chunk-7UPFZJIT.js +861 -0
  24. package/dist/chunk-7UPFZJIT.js.map +1 -0
  25. package/dist/chunk-7VLLZQ3N.js +2 -0
  26. package/dist/chunk-7VLLZQ3N.js.map +1 -0
  27. package/dist/{chunk-4O4GZBKZ.js → chunk-AKOXTIJS.js} +2 -2
  28. package/dist/{chunk-4ZFLYY5P.js → chunk-APZIH3AY.js} +2 -2
  29. package/dist/{chunk-DVR6PFCJ.js → chunk-B2Q3PTPS.js} +2 -2
  30. package/dist/{chunk-SCJ5ZXEN.js → chunk-B2QYMUTD.js} +2 -2
  31. package/dist/{chunk-SCJ5ZXEN.js.map → chunk-B2QYMUTD.js.map} +1 -1
  32. package/dist/chunk-BIJHMWXK.js +21 -0
  33. package/dist/chunk-BIJHMWXK.js.map +1 -0
  34. package/dist/{chunk-4VDA4UM7.js → chunk-BKHIR2YJ.js} +2 -2
  35. package/dist/chunk-CBFBGN7J.js +54 -0
  36. package/dist/chunk-CBFBGN7J.js.map +1 -0
  37. package/dist/{chunk-4FMZTM3W.js → chunk-CL33CRH5.js} +3 -3
  38. package/dist/chunk-CL33CRH5.js.map +1 -0
  39. package/dist/{chunk-XIA2ACKX.js → chunk-CSWGYSC4.js} +2 -2
  40. package/dist/{chunk-Z5CBUZIW.js → chunk-E2VDBT3T.js} +2 -2
  41. package/dist/{chunk-XZN7QBRH.js → chunk-ERNBJLIQ.js} +2 -2
  42. package/dist/{chunk-R6UCPHUD.js → chunk-IA7INHXY.js} +2 -2
  43. package/dist/chunk-IMLAPB7G.js +4 -0
  44. package/dist/chunk-IMLAPB7G.js.map +1 -0
  45. package/dist/{chunk-3PGPN323.js → chunk-JP5OAMWQ.js} +1 -1
  46. package/dist/chunk-JP5OAMWQ.js.map +1 -0
  47. package/dist/chunk-KBJNJGBP.js +2 -0
  48. package/dist/chunk-KBJNJGBP.js.map +1 -0
  49. package/dist/chunk-KFIJDLQ5.js +3 -0
  50. package/dist/chunk-KFIJDLQ5.js.map +1 -0
  51. package/dist/{chunk-XOQNDWVW.js → chunk-KIYV4ZHG.js} +2 -2
  52. package/dist/{chunk-CPMQZ6Z7.js → chunk-KRK7OOTK.js} +2 -2
  53. package/dist/{chunk-ARSVKSC4.js → chunk-L2WVQREN.js} +2 -2
  54. package/dist/{chunk-I3RAUJCD.js → chunk-L4ALHWII.js} +23 -14
  55. package/dist/{chunk-I3RAUJCD.js.map → chunk-L4ALHWII.js.map} +1 -1
  56. package/dist/{chunk-YHD4PHFX.js → chunk-L4ZS4HGJ.js} +268 -251
  57. package/dist/chunk-L4ZS4HGJ.js.map +1 -0
  58. package/dist/chunk-MCBTVNPX.js +152 -0
  59. package/dist/chunk-MCBTVNPX.js.map +1 -0
  60. package/dist/{chunk-SCC7HBFZ.js → chunk-MFIM5Y3J.js} +2 -2
  61. package/dist/chunk-MRIVENBY.js +2 -0
  62. package/dist/{article-sync-TLZTHRZB.js.map → chunk-MRIVENBY.js.map} +1 -1
  63. package/dist/{chunk-CDLJOGVZ.js → chunk-VSL2SSBH.js} +6 -6
  64. package/dist/{chunk-X5JTG52Q.js → chunk-WKQQIYOE.js} +2 -2
  65. package/dist/{chunk-PVUNDNT3.js → chunk-YA6E47BR.js} +2 -2
  66. package/dist/{chunk-AOFTTIZZ.js → chunk-YPCZ5TNK.js} +2 -2
  67. package/dist/{chunk-BWSB7NOX.js → chunk-YQRWUF4Y.js} +2 -2
  68. package/dist/{chunk-BCUR2TJ7.js → chunk-YVR6652A.js} +2 -2
  69. package/dist/cli.js +1 -1
  70. package/dist/{client-A5OK3IFO.js → client-YIR3ELVN.js} +2 -2
  71. package/dist/config-4DOJYA2K.js +2 -0
  72. package/dist/{config-mutate-62FCJ3S6.js → config-mutate-KDRHKQE4.js} +2 -2
  73. package/dist/config-mutator-4PPBACWU.js +2 -0
  74. package/dist/{contributions-L2YS4AH2.js → contributions-MTKXXLIP.js} +2 -2
  75. package/dist/{contributions-L2YS4AH2.js.map → contributions-MTKXXLIP.js.map} +1 -1
  76. package/dist/{doctor-7TPSMMFA.js → doctor-FJ5RCG4J.js} +2 -2
  77. package/dist/enrich-NH3WHKD6.js +16 -0
  78. package/dist/enrich-NH3WHKD6.js.map +1 -0
  79. package/dist/{follow-up-tool-FKWIRFPW.js → follow-up-tool-SVZDSUIU.js} +2 -2
  80. package/dist/graph-EXDH7EPZ.js +2 -0
  81. package/dist/hub-CF4VFSRT.js +2 -0
  82. package/dist/index.d.ts +496 -0
  83. package/dist/index.js +1 -1
  84. package/dist/index.js.map +1 -1
  85. package/dist/load-5DNMGHFW.js +2 -0
  86. package/dist/model-call-BGTDPWZD.js +2 -0
  87. package/dist/notes-WJJEJ4CJ.js +2 -0
  88. package/dist/notes-settings-WMOH2V75.js +2 -0
  89. package/dist/processes-M3N3S7V5.js +2 -0
  90. package/dist/program-ZPNEAACQ.js +768 -0
  91. package/dist/program-ZPNEAACQ.js.map +1 -0
  92. package/dist/{promote-XBDWCHLU.js → promote-G6BOY7K5.js} +2 -2
  93. package/dist/query-H24BI3BI.js +2 -0
  94. package/dist/query-settings-IJB3QMDW.js +3 -0
  95. package/dist/query-settings-IJB3QMDW.js.map +1 -0
  96. package/dist/registry-TAUHYJCK.js +2 -0
  97. package/dist/{request-planner-SEXYQN7D.js → request-planner-V3R5J3V4.js} +2 -2
  98. package/dist/{review-candidates-PIJWPPHQ.js → review-candidates-TC7RJB4W.js} +2 -2
  99. package/dist/roster-IRXP32XF.js +2 -0
  100. package/dist/{rotation-memo-7VLREGS6.js → rotation-memo-2G6N3VF3.js} +2 -2
  101. package/dist/{routing-2V3Y6ZR5.js → routing-XQD74ERK.js} +2 -2
  102. package/dist/schedule-tool-U6KLY5MT.js +2 -0
  103. package/dist/{scheduler-SVZKDKJV.js → scheduler-WOOXIOER.js} +2 -2
  104. package/dist/scheduler-WOOXIOER.js.map +1 -0
  105. package/dist/{seat-C6TMCJWI.js → seat-B75JIAS3.js} +2 -2
  106. package/dist/seat-B75JIAS3.js.map +1 -0
  107. package/dist/{select-DP64KWO4.js → select-I6BSBQXP.js} +2 -2
  108. package/dist/{set-enabled-WCH6FU4N.js → set-enabled-THNVITGU.js} +2 -2
  109. package/dist/summaries-BIRSNWGH.js +2 -0
  110. package/dist/summaries-BIRSNWGH.js.map +1 -0
  111. package/dist/{tool-TWQRBV4Y.js → tool-CEBIS6GK.js} +2 -2
  112. package/dist/{tool-WUK3ZOWG.js → tool-LFWTZHB7.js} +2 -2
  113. package/dist/wiki-3ATPAHC2.js +2 -0
  114. package/dist/wiki-3ATPAHC2.js.map +1 -0
  115. package/dist/workspace-env-ROH45HXN.js +2 -0
  116. package/dist/workspace-env-ROH45HXN.js.map +1 -0
  117. package/package.json +1 -1
  118. package/dist/absorb-eval-ZCWHWKAD.js +0 -2
  119. package/dist/article-sync-TLZTHRZB.js +0 -2
  120. package/dist/board-dashboard-LZJT4YWV.js.map +0 -1
  121. package/dist/chunk-3PGPN323.js.map +0 -1
  122. package/dist/chunk-4FMZTM3W.js.map +0 -1
  123. package/dist/chunk-A347YHEW.js +0 -4
  124. package/dist/chunk-A347YHEW.js.map +0 -1
  125. package/dist/chunk-BGG3ZSMW.js.map +0 -1
  126. package/dist/chunk-EO4DEEXL.js +0 -2
  127. package/dist/chunk-EO4DEEXL.js.map +0 -1
  128. package/dist/chunk-EOLEKSN6.js +0 -54
  129. package/dist/chunk-EOLEKSN6.js.map +0 -1
  130. package/dist/chunk-M7IJVOJA.js +0 -55
  131. package/dist/chunk-M7IJVOJA.js.map +0 -1
  132. package/dist/chunk-QUXMLLX5.js +0 -2
  133. package/dist/chunk-QUXMLLX5.js.map +0 -1
  134. package/dist/chunk-QX2B4TJU.js +0 -3
  135. package/dist/chunk-QX2B4TJU.js.map +0 -1
  136. package/dist/chunk-VD7IO653.js +0 -3
  137. package/dist/chunk-YHD4PHFX.js.map +0 -1
  138. package/dist/chunk-ZF5U5KPB.js +0 -892
  139. package/dist/chunk-ZF5U5KPB.js.map +0 -1
  140. package/dist/config-DQ5SILHX.js +0 -2
  141. package/dist/config-mutator-3ZL5YQSO.js +0 -2
  142. package/dist/graph-5ZJ7YACP.js +0 -2
  143. package/dist/hub-EU5ECAJB.js +0 -2
  144. package/dist/load-NK3MIYXP.js +0 -2
  145. package/dist/notes-2VC47RCK.js +0 -2
  146. package/dist/notes-settings-X63D5HPM.js +0 -2
  147. package/dist/processes-5MP32QZT.js +0 -2
  148. package/dist/program-UTSXNAHM.js +0 -743
  149. package/dist/program-UTSXNAHM.js.map +0 -1
  150. package/dist/query-UI6GQEL7.js +0 -2
  151. package/dist/registry-JW6ETTBA.js +0 -2
  152. package/dist/schedule-tool-KFZ27JTH.js +0 -2
  153. package/dist/wiki-4LAJ36XR.js +0 -2
  154. /package/dist/{App-G37JNRBW.js.map → App-WZ3HAKES.js.map} +0 -0
  155. /package/dist/{ChatApp-NCKC7C3L.js.map → ChatApp-K4HDJL2S.js.map} +0 -0
  156. /package/dist/{absorb-eval-ZCWHWKAD.js.map → absorb-eval-ER27DHHK.js.map} +0 -0
  157. /package/dist/{agent-LJ4SUQCC.js.map → agent-AQSVISXX.js.map} +0 -0
  158. /package/dist/{client-A5OK3IFO.js.map → article-sync-4NOPOQU7.js.map} +0 -0
  159. /package/dist/{chunk-VJRITDSQ.js.map → chunk-6O6NW3ZG.js.map} +0 -0
  160. /package/dist/{chunk-4O4GZBKZ.js.map → chunk-AKOXTIJS.js.map} +0 -0
  161. /package/dist/{chunk-4ZFLYY5P.js.map → chunk-APZIH3AY.js.map} +0 -0
  162. /package/dist/{chunk-DVR6PFCJ.js.map → chunk-B2Q3PTPS.js.map} +0 -0
  163. /package/dist/{chunk-4VDA4UM7.js.map → chunk-BKHIR2YJ.js.map} +0 -0
  164. /package/dist/{chunk-XIA2ACKX.js.map → chunk-CSWGYSC4.js.map} +0 -0
  165. /package/dist/{chunk-Z5CBUZIW.js.map → chunk-E2VDBT3T.js.map} +0 -0
  166. /package/dist/{chunk-XZN7QBRH.js.map → chunk-ERNBJLIQ.js.map} +0 -0
  167. /package/dist/{chunk-R6UCPHUD.js.map → chunk-IA7INHXY.js.map} +0 -0
  168. /package/dist/{chunk-XOQNDWVW.js.map → chunk-KIYV4ZHG.js.map} +0 -0
  169. /package/dist/{chunk-CPMQZ6Z7.js.map → chunk-KRK7OOTK.js.map} +0 -0
  170. /package/dist/{chunk-ARSVKSC4.js.map → chunk-L2WVQREN.js.map} +0 -0
  171. /package/dist/{chunk-SCC7HBFZ.js.map → chunk-MFIM5Y3J.js.map} +0 -0
  172. /package/dist/{chunk-CDLJOGVZ.js.map → chunk-VSL2SSBH.js.map} +0 -0
  173. /package/dist/{chunk-X5JTG52Q.js.map → chunk-WKQQIYOE.js.map} +0 -0
  174. /package/dist/{chunk-PVUNDNT3.js.map → chunk-YA6E47BR.js.map} +0 -0
  175. /package/dist/{chunk-AOFTTIZZ.js.map → chunk-YPCZ5TNK.js.map} +0 -0
  176. /package/dist/{chunk-BWSB7NOX.js.map → chunk-YQRWUF4Y.js.map} +0 -0
  177. /package/dist/{chunk-BCUR2TJ7.js.map → chunk-YVR6652A.js.map} +0 -0
  178. /package/dist/{config-DQ5SILHX.js.map → client-YIR3ELVN.js.map} +0 -0
  179. /package/dist/{config-mutate-62FCJ3S6.js.map → config-4DOJYA2K.js.map} +0 -0
  180. /package/dist/{config-mutator-3ZL5YQSO.js.map → config-mutate-KDRHKQE4.js.map} +0 -0
  181. /package/dist/{doctor-7TPSMMFA.js.map → config-mutator-4PPBACWU.js.map} +0 -0
  182. /package/dist/{graph-5ZJ7YACP.js.map → doctor-FJ5RCG4J.js.map} +0 -0
  183. /package/dist/{follow-up-tool-FKWIRFPW.js.map → follow-up-tool-SVZDSUIU.js.map} +0 -0
  184. /package/dist/{hub-EU5ECAJB.js.map → graph-EXDH7EPZ.js.map} +0 -0
  185. /package/dist/{load-NK3MIYXP.js.map → hub-CF4VFSRT.js.map} +0 -0
  186. /package/dist/{notes-2VC47RCK.js.map → load-5DNMGHFW.js.map} +0 -0
  187. /package/dist/{notes-settings-X63D5HPM.js.map → model-call-BGTDPWZD.js.map} +0 -0
  188. /package/dist/{processes-5MP32QZT.js.map → notes-WJJEJ4CJ.js.map} +0 -0
  189. /package/dist/{promote-XBDWCHLU.js.map → notes-settings-WMOH2V75.js.map} +0 -0
  190. /package/dist/{query-UI6GQEL7.js.map → processes-M3N3S7V5.js.map} +0 -0
  191. /package/dist/{registry-JW6ETTBA.js.map → promote-G6BOY7K5.js.map} +0 -0
  192. /package/dist/{routing-2V3Y6ZR5.js.map → query-H24BI3BI.js.map} +0 -0
  193. /package/dist/{schedule-tool-KFZ27JTH.js.map → registry-TAUHYJCK.js.map} +0 -0
  194. /package/dist/{request-planner-SEXYQN7D.js.map → request-planner-V3R5J3V4.js.map} +0 -0
  195. /package/dist/{review-candidates-PIJWPPHQ.js.map → review-candidates-TC7RJB4W.js.map} +0 -0
  196. /package/dist/{scheduler-SVZKDKJV.js.map → roster-IRXP32XF.js.map} +0 -0
  197. /package/dist/{rotation-memo-7VLREGS6.js.map → rotation-memo-2G6N3VF3.js.map} +0 -0
  198. /package/dist/{seat-C6TMCJWI.js.map → routing-XQD74ERK.js.map} +0 -0
  199. /package/dist/{wiki-4LAJ36XR.js.map → schedule-tool-U6KLY5MT.js.map} +0 -0
  200. /package/dist/{select-DP64KWO4.js.map → select-I6BSBQXP.js.map} +0 -0
  201. /package/dist/{set-enabled-WCH6FU4N.js.map → set-enabled-THNVITGU.js.map} +0 -0
  202. /package/dist/{tool-TWQRBV4Y.js.map → tool-CEBIS6GK.js.map} +0 -0
  203. /package/dist/{tool-WUK3ZOWG.js.map → tool-LFWTZHB7.js.map} +0 -0
@@ -0,0 +1,152 @@
1
+ import{f as h}from"./chunk-KFIJDLQ5.js";import{f as j,g}from"./chunk-5BI2T3WD.js";import{a as z}from"./chunk-IMLAPB7G.js";function E(o,t){return o.ontology.types.find(e=>e.id===t)?.lens??[{panel:"notes",source:"notes",show:1}]}function v(o,t,e){let a=o.ontology.properties.find(n=>n.id===t);return a?e?a.inverse??a.label:a.label:t.replace(/_/g," ")}function G(o,t){let e=o.until??o.date??o.since??"",a=t.until??t.date??t.since??"";return e!==a?a.localeCompare(e):o.label.localeCompare(t.label)}function R(o,t,e,a,n){let r=a?n:e.target?o.entities.get(e.target):void 0,i=[v(o,e.property,a)];return e.role&&i.unshift(e.role.length>40?`${e.role.slice(0,39)}\u2026`:e.role),{label:r?.title??e.value,entityId:r?.id,type:r?.type,chips:i,since:e.since,until:e.until,status:e.status,private:e.access==="private",statement:a?void 0:t.statements.indexOf(e),sub:e.note}}function H(o,t,e){let a=new Set(j(e)),n=e.types?new Set(e.types):null,r=[],i=new Set,s=x=>!n||!!x&&n.has(x.type);for(let x of t.statements){if(!a.has(x.property))continue;let d=x.target?o.entities.get(x.target):void 0;s(d)&&(r.push(R(o,t,x,!1)),d&&i.add(d.id))}for(let x of o.incoming.get(t.id)??[]){if(!a.has(x.property))continue;let d=o.entities.get(x.from);!d||!s(d)||(x.statement?r.push(R(o,t,x.statement,!0,d)):i.has(d.id)||r.push({label:d.title,entityId:d.id,type:d.type,chips:[v(o,"related",!0)],date:d.updated}),i.add(d.id))}if(a.has("related"))for(let x of o.outgoing.get(t.id)??[]){if(x.property!=="related"||i.has(x.to))continue;let d=o.entities.get(x.to);!d||!s(d)||(r.push({label:d.title,entityId:d.id,type:d.type,chips:[v(o,"related",!1)],date:d.updated}),i.add(d.id))}let c=r.filter(x=>!x.chips.includes(v(o,"related",!1))),p=r.filter(x=>x.chips.includes(v(o,"related",!1)));return[...c.sort(G),...p.sort(G)]}function I(o,t,e){let a=new Set;for(let r of o.outgoing.get(t.id)??[])a.add(r.to);for(let r of o.incoming.get(t.id)??[])a.add(r.from);let n=[];for(let r of a){let i=o.entities.get(r);i&&(!e||e.has(i.type))&&n.push(i)}return n.sort((r,i)=>(i.date||i.updated).localeCompare(r.date||r.updated))}function M(o){return{label:o.title,entityId:o.id,type:o.type,chips:[],date:o.date,importance:o.importance}}function T(o,t,e){let a=I(o,t,new Set(["event"])).map(M),n=new Set(e.importance??["major","normal","minor"]),r=a.filter(p=>n.has(p.importance??o.ontology.importance.default)),i=e.fold?a.filter(p=>p.importance===e.fold):[],s=[],c=e.rollup??o.ontology.importance.rollup;if(i.length>=c.min&&i[0].date){let p=Date.parse(i[0].date),x=i.filter(d=>d.date&&p-Date.parse(d.date)<=c.days*864e5);x.length>=c.min&&s.push(`${x.length} minor events in ${c.days} days up to ${i[0].date}`)}return{shown:r,folded:i,rollups:s}}function V(o,t){let e=o.statements.map((r,i)=>({st:r,i})).filter(({st:r})=>r.property==="reading"||!!r.metric).sort((r,i)=>(i.st.at??"").localeCompare(r.st.at??"")),a=new Set,n=[];for(let{st:r,i}of e){let s=r.metric??"reading";t&&a.has(s)||(a.add(s),n.push({label:`${s.replace(/_/g," ")}: ${r.value}`,chips:[],date:r.at,statement:i,private:r.access==="private"}))}return n}function B(o,t){return t(o.sources).sort((e,a)=>a.date.localeCompare(e.date)).map(e=>{let a=e.content.split(`
2
+ `).map(n=>n.trim()).find(Boolean)??"";return{label:a.length>120?`${a.slice(0,117)}\u2026`:a,chips:[],date:e.date,sub:`${e.date} \xB7 ${e.agentId} \xB7 ${e.source}`}})}function P(o,t,e,a){let n=g(e),r=[],i=[],s=[];if(n==="statements")r=H(o,t,e);else if(n==="linked")r=I(o,t,e.types?new Set(e.types):null).map(M);else if(n==="readings")r=V(t,!a.full&&e.latest!==!1);else if(n==="discussed")r=B(t,a.readEntries);else if(n==="history"){let p=T(o,t,e);r=a.full?I(o,t,new Set(["event"])).map(M):p.shown,i=a.full?[]:p.folded,s=p.rollups}let c=r.length;if(a.full){let p=a.pageSize??50,x=Math.max(1,a.page??1);r=r.slice((x-1)*p,x*p)}else r=r.slice(0,e.show??5);return{def:e,title:e.title??e.panel.replace(/_/g," "),items:r,total:c,folded:i,rollups:s,ownerOnly:e.access==="owner"}}function l(o){return String(o??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}var O={home:'<rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/>',person:'<circle cx="12" cy="8" r="4"/><path d="M4 21c0-4 4-6 8-6s8 2 8 6"/>',org:'<rect x="4" y="3" width="16" height="18" rx="2"/><path d="M9 7h2M13 7h2M9 11h2M13 11h2M9 15h2M13 15h2"/>',pin:'<path d="M12 21s-7-6.2-7-11a7 7 0 0 1 14 0c0 4.8-7 11-7 11z"/><circle cx="12" cy="10" r="2.5"/>',server:'<rect x="3" y="4" width="18" height="7" rx="2"/><rect x="3" y="13" width="18" height="7" rx="2"/><path d="M7 7.5h.01M7 16.5h.01"/>',device:'<rect x="4" y="5" width="16" height="11" rx="1.5"/><path d="M2 19h20"/>',app:'<rect x="4" y="4" width="16" height="16" rx="3"/><path d="M9 12h6M12 9v6"/>',globe:'<circle cx="12" cy="12" r="9"/><path d="M3 12h18M12 3c3 3.5 3 14.5 0 18M12 3c-3 3.5-3 14.5 0 18"/>',key:'<circle cx="8" cy="15" r="4"/><path d="M11 12l9-9M17 6l3 3"/>',agent:'<rect x="5" y="8" width="14" height="11" rx="3"/><path d="M12 4v4M9 13h.01M15 13h.01"/>',project:'<path d="M12 3l8 4.5v9L12 21l-8-4.5v-9z"/><path d="M4 7.5l8 4.5 8-4.5M12 12v9"/>',contract:'<path d="M7 3h7l5 5v13H7z"/><path d="M14 3v5h5M10 13h6M10 17h4"/>',law:'<path d="M12 3v18M5 21h14M6 7h12M6 7l-3 7a3 3 0 0 0 6 0zM18 7l-3 7a3 3 0 0 0 6 0z"/>',calendar:'<rect x="3" y="5" width="18" height="16" rx="2"/><path d="M3 10h18M8 3v4M16 3v4"/>',decision:'<path d="M12 3v18M12 8H6l-2 2 2 2h6M12 12h6l2 2-2 2h-6"/>',steps:'<path d="M9 6h11M9 12h11M9 18h11M4 6l1 1 2-2M4 12l1 1 2-2M4 18l1 1 2-2"/>',topic:'<path d="M4 7h16M4 12h10M4 17h7"/>',chat:'<path d="M4 5h16v11H9l-5 4z"/>',lock:'<rect x="5" y="11" width="14" height="10" rx="2"/><path d="M8 11V8a4 4 0 0 1 8 0v3"/>',arrow:'<path d="M5 12h14M13 6l6 6-6 6"/>',search:'<circle cx="11" cy="11" r="7"/><path d="M21 21l-4.3-4.3"/>',merge:'<circle cx="6" cy="6" r="2"/><circle cx="6" cy="18" r="2"/><circle cx="18" cy="12" r="2"/><path d="M6 8v8M8 6c6 0 8 2 8 6"/>'};function m(o){return`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${O[o??""]??O.topic}</svg>`}function u(o,t){return m(o.types.find(e=>e.id===t)?.icon)}function b(o,t){return o.types.find(e=>e.id===t)?.label??t??""}function f(o){return`/e/${encodeURIComponent(o)}`}function L(o){return`<nav class="ox-crumbs" aria-label="Breadcrumb">${[{label:"Wiki",href:"/"},...o].map((e,a,n)=>a===n.length-1||!e.href?`<b>${l(e.label)}</b>`:`<a href="${e.href}">${l(e.label)}</a>`).join('<span aria-hidden="true">/</span>')}</nav>`}function y(o){let t=["","Pillar","Overview","Panel","Statement"];return`<div class="ox-zoom" title="Zoom level">${[1,2,3,4].map(a=>`<span class="${a===o?"on":""}">Z${a}${a===o?` ${t[a]}`:""}</span>`).join("")}</div>`}function w(o,t){let e=o.ontology,a=`<a class="ox-nav${t.home?" on":""}" href="/">${m("home")}<span>Home</span></a>`,n=e.sidebar.pins.slice(0,e.sidebar.pins_max);if(n.length){a+='<div class="ox-side-h">Pinned</div>';for(let r of n){let i=o.names.get(h(r)),s=i?o.entities.get(i):void 0;s&&(a+=`<a class="ox-nav pin${t.entity===s.id?" on":""}" href="${f(s.id)}">${u(e,s.type)}<span>${l(s.title)}</span></a>`)}}a+='<div class="ox-side-h">Pillars</div>';for(let r of e.pillars)r.sidebar!==!1&&(a+=`<a class="ox-nav${t.pillar===r.id?" on":""}" href="/p/${encodeURIComponent(r.id)}">${m(r.icon)}<span>${l(r.label)}</span></a>`);return a+='<div class="ox-side-foot">Types, topics and agent wikis are one level down, on Home and the pillar pages.</div>',a}function $(o,t,e,a="",n=""){return`<!DOCTYPE html>
3
+ <html lang="en">
4
+ <head>
5
+ <meta charset="utf-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1">
7
+ <title>${l(o)} \u2014 Wiki</title>
8
+ <style>${Z}</style>
9
+ <script>(function(){try{var t=localStorage.getItem('wiki-theme');if(t)document.documentElement.setAttribute('data-theme',t)}catch(e){}})();</script>
10
+ </head>
11
+ <body>
12
+ <div class="ox-app">
13
+ <header class="ox-top">
14
+ <a class="ox-logo" href="/"><span class="mark"><i></i></span>Wiki</a>
15
+ <form class="ox-search" action="/find" method="get" role="search">${m("search")}<input type="search" name="q" value="${l(n)}" placeholder="Jump to any page" aria-label="Search the wiki" autocomplete="off"><kbd>\u2318K</kbd></form>
16
+ <span class="ox-spacer"></span>
17
+ <a class="ox-btn" href="/agents">Agent wikis</a>
18
+ <button class="ox-btn" id="ox-theme" type="button" aria-label="Toggle theme">Theme</button>
19
+ </header>
20
+ <div class="ox-layout${a?" rail":""}">
21
+ <nav class="ox-side" aria-label="Wiki">${t}</nav>
22
+ <main class="ox-main">${e}</main>
23
+ ${a?`<aside class="ox-rail">${a}</aside>`:""}
24
+ </div>
25
+ </div>
26
+ <script>
27
+ (function(){
28
+ var b=document.getElementById('ox-theme');
29
+ if(b)b.addEventListener('click',function(){var d=document.documentElement.getAttribute('data-theme')==='dark'?'':'dark';if(d)document.documentElement.setAttribute('data-theme','dark');else document.documentElement.removeAttribute('data-theme');try{localStorage.setItem('wiki-theme',d)}catch(e){}});
30
+ document.addEventListener('keydown',function(e){if((e.metaKey||e.ctrlKey)&&e.key.toLowerCase()==='k'){e.preventDefault();var i=document.querySelector('.ox-search input');if(i)i.focus();}});
31
+ })();
32
+ </script>
33
+ </body>
34
+ </html>`}var Z=`
35
+ :root{--paper:#fafaf9;--card:#fff;--soft:#f4f4f2;--edge:#e7e7e3;--ink:#121614;--muted:#4f5755;--subtle:#7d8684;
36
+ --accent:#1e40af;--accent-soft:#eef3ff;--accent-edge:#c7d6fb;--ok:#0f766e;--ok-soft:#effcf9;--ok-edge:#a7eadf;
37
+ --warn:#92400e;--warn-soft:#fffbeb;--warn-edge:#fde68a;--bad:#b91c1c;--bad-soft:#fef2f2;--bad-edge:#fecaca;
38
+ --mono:ui-monospace,SFMono-Regular,Menlo,monospace;--sans:system-ui,-apple-system,"Segoe UI",sans-serif}
39
+ [data-theme=dark]{--paper:#111413;--card:#181c1b;--soft:#1f2422;--edge:#2c3331;--ink:#e9eeec;--muted:#b3bcba;--subtle:#87918f;
40
+ --accent:#9db7ff;--accent-soft:#1c2540;--accent-edge:#33406a;--ok:#5eead4;--ok-soft:#10302b;--ok-edge:#1d5249;
41
+ --warn:#fcd34d;--warn-soft:#33290f;--warn-edge:#5c4a17;--bad:#fca5a5;--bad-soft:#3a1717;--bad-edge:#5e2525}
42
+ *{box-sizing:border-box}
43
+ body{margin:0;background:var(--paper);color:var(--ink);font:14px/1.45 var(--sans);-webkit-font-smoothing:antialiased}
44
+ a{color:var(--accent);text-decoration:none}a:hover{text-decoration:underline}
45
+ .ox-top{display:flex;align-items:center;gap:16px;padding:10px 18px;border-bottom:1px solid var(--edge);background:var(--card);position:sticky;top:0;z-index:5}
46
+ body>a[href="/admin"]+.ox-app .ox-top{padding-right:130px}
47
+ .ox-logo{display:flex;align-items:center;gap:9px;font-weight:600;color:var(--ink);width:200px}
48
+ .ox-logo .mark{width:24px;height:24px;border-radius:7px;background:var(--ink);display:flex;align-items:center;justify-content:center}
49
+ .ox-logo .mark i{width:8px;height:8px;border-radius:50%;background:#14b8a6}
50
+ .ox-search{flex:0 1 440px;display:flex;align-items:center;gap:8px;border:1px solid var(--edge);border-radius:999px;padding:6px 12px;background:var(--paper)}
51
+ .ox-search svg{width:15px;height:15px;color:var(--subtle)}
52
+ .ox-search input{flex:1;border:0;background:transparent;color:var(--ink);font:13px var(--sans);outline:none}
53
+ .ox-search kbd{font:11px var(--mono);color:var(--subtle)}
54
+ .ox-spacer{flex:1}
55
+ .ox-btn{font:12.5px var(--sans);border:1px solid var(--edge);background:var(--card);color:var(--ink);border-radius:999px;padding:5px 12px;cursor:pointer;display:inline-flex;gap:6px;align-items:center}
56
+ .ox-layout{display:grid;grid-template-columns:230px minmax(0,1fr)}
57
+ .ox-layout.rail{grid-template-columns:230px minmax(0,1fr) 290px}
58
+ .ox-side{border-right:1px solid var(--edge);padding:14px 12px;min-height:calc(100vh - 50px)}
59
+ .ox-nav{display:flex;align-items:center;gap:10px;padding:7px 10px;border-radius:10px;color:var(--ink)}
60
+ .ox-nav:hover{background:var(--soft);text-decoration:none}
61
+ .ox-nav svg{width:16px;height:16px;color:var(--muted);flex:none}
62
+ .ox-nav span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
63
+ .ox-nav.on{background:var(--accent-soft);color:var(--accent);font-weight:500}.ox-nav.on svg{color:var(--accent)}
64
+ .ox-side-h{font:10.5px var(--mono);letter-spacing:.08em;text-transform:uppercase;color:var(--subtle);padding:16px 10px 6px}
65
+ .ox-side-foot{margin-top:18px;border-top:1px solid var(--edge);padding:12px 10px 0;font:10.5px/1.6 var(--mono);color:var(--subtle)}
66
+ .ox-main{padding:20px 28px 48px;min-width:0}
67
+ .ox-rail{border-left:1px solid var(--edge);padding:20px 18px}
68
+ .ox-bar{display:flex;align-items:center;justify-content:space-between;gap:12px}
69
+ .ox-crumbs{font:11.5px var(--mono);color:var(--subtle);display:flex;gap:8px;flex-wrap:wrap}
70
+ .ox-crumbs b{color:var(--ink);font-weight:500}
71
+ .ox-zoom{display:inline-flex;border:1px solid var(--edge);border-radius:999px;padding:3px;background:var(--card);gap:2px}
72
+ .ox-zoom span{font:10.5px var(--mono);letter-spacing:.05em;text-transform:uppercase;padding:4px 9px;border-radius:999px;color:var(--subtle)}
73
+ .ox-zoom span.on{background:var(--ink);color:var(--paper)}
74
+ .ox-head{display:flex;gap:16px;align-items:flex-start;margin:16px 0 18px}
75
+ .ox-avatar{width:54px;height:54px;border-radius:14px;background:var(--accent-soft);border:1px solid var(--accent-edge);display:flex;align-items:center;justify-content:center;color:var(--accent);flex:none}
76
+ .ox-avatar svg{width:26px;height:26px}
77
+ .ox-head h1{font-size:30px;margin:2px 0 8px;letter-spacing:-.02em;font-weight:600;line-height:1.15}
78
+ .ox-head p{margin:0;color:var(--muted)}
79
+ .ox-chips{display:flex;gap:6px;flex-wrap:wrap;align-items:center}
80
+ .ox-chip{font-size:12px;border:1px solid var(--edge);background:var(--card);border-radius:999px;padding:2px 10px;color:var(--muted);display:inline-flex;gap:6px;align-items:center;white-space:nowrap}
81
+ .ox-chip svg{width:12px;height:12px}
82
+ .ox-chip.type{background:var(--accent-soft);border-color:var(--accent-edge);color:var(--accent)}
83
+ .ox-chip.mono{font:11px var(--mono)}
84
+ .ox-st{font:10px var(--mono);letter-spacing:.07em;text-transform:uppercase;border-radius:999px;padding:3px 8px;border:1px solid;white-space:nowrap}
85
+ .ox-st.ok,.ox-st.confirmed{color:var(--ok);background:var(--ok-soft);border-color:var(--ok-edge)}
86
+ .ox-st.proposed{color:var(--accent);background:var(--accent-soft);border-color:var(--accent-edge)}
87
+ .ox-st.warn,.ox-st.due{color:var(--warn);background:var(--warn-soft);border-color:var(--warn-edge)}
88
+ .ox-st.bad,.ox-st.late{color:var(--bad);background:var(--bad-soft);border-color:var(--bad-edge)}
89
+ .ox-st.major{color:var(--paper);background:var(--ink);border-color:var(--ink)}
90
+ .ox-st.normal{color:var(--muted);background:var(--soft);border-color:var(--edge)}
91
+ .ox-st.minor{color:var(--subtle);background:var(--card);border-color:var(--edge)}
92
+ .ox-card{background:var(--card);border:1px solid var(--edge);border-radius:16px;padding:16px 18px;min-width:0}
93
+ .ox-card-h{display:flex;align-items:baseline;gap:10px;margin-bottom:10px}
94
+ .ox-card-h h2,.ox-card-h h3{font-size:15px;margin:0;font-weight:600;white-space:nowrap}
95
+ .ox-card-h .note{font:11px var(--mono);color:var(--subtle);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
96
+ .ox-card-h .zin{margin-left:auto;font:11px var(--mono);white-space:nowrap}
97
+ .ox-grid2{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:16px;margin-top:16px}
98
+ .ox-grid2>.wide{grid-column:1/-1}
99
+ .ox-grid3{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:14px;margin-top:16px}
100
+ .ox-row{display:flex;align-items:center;gap:10px;padding:8px 0;border-top:1px solid var(--edge);font-size:13.5px;min-width:0}
101
+ .ox-row:first-of-type{border-top:0}
102
+ .ox-row .t{min-width:35%;overflow:hidden;flex:1 1 auto}
103
+ .ox-row .t a,.ox-row .t span.l{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
104
+ .ox-row .r{margin-left:auto;display:flex;gap:6px;align-items:center;flex:0 1 auto;min-width:0;flex-wrap:wrap;justify-content:flex-end}
105
+ .ox-row .r .ox-chip{max-width:240px;overflow:hidden;text-overflow:ellipsis}
106
+ .ox-ic{width:28px;height:28px;border-radius:8px;background:var(--soft);border:1px solid var(--edge);display:flex;align-items:center;justify-content:center;flex:none;color:var(--muted)}
107
+ .ox-ic svg{width:14px;height:14px}
108
+ .ox-card-h .note svg,.ox-row .l svg{width:12px;height:12px;vertical-align:-2px}
109
+ .ox-sub{font:11px var(--mono);color:var(--subtle);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
110
+ .ox-summary{font-size:15px;line-height:1.55;margin:0 0 10px}
111
+ .ox-meta{display:flex;gap:16px;flex-wrap:wrap;font:11px var(--mono);color:var(--subtle)}
112
+ .ox-lbl{font:10.5px var(--mono);letter-spacing:.08em;text-transform:uppercase;color:var(--subtle);display:block;margin:4px 0 10px}
113
+ .ox-annot{border:1px dashed var(--subtle);border-radius:14px;padding:12px 14px;font-size:12.5px;color:var(--muted);line-height:1.5}
114
+ .ox-annot ol{margin:6px 0;padding-left:18px}
115
+ .ox-annot .ox-sub{white-space:normal;overflow-wrap:anywhere}
116
+ .ox-rail .ox-row{font-size:13px}
117
+ .ox-tabs{display:flex;gap:4px;border-bottom:1px solid var(--edge);margin:4px 0 0;flex-wrap:wrap}
118
+ .ox-tabs a{padding:8px 12px;color:var(--muted);border-bottom:2px solid transparent;font-size:13.5px}
119
+ .ox-tabs a.on{color:var(--ink);border-color:var(--ink);font-weight:500}
120
+ .ox-tabs a small{font:11px var(--mono);color:var(--subtle);margin-left:4px}
121
+ .ox-ev{display:grid;grid-template-columns:86px 70px minmax(0,1fr);gap:10px;align-items:center;padding:8px 0;border-top:1px solid var(--edge);font-size:13.5px}
122
+ .ox-ev:first-of-type{border-top:0}
123
+ .ox-ev .d{font:11px var(--mono);color:var(--subtle)}
124
+ .ox-ev a{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block}
125
+ .ox-fold{border:1px solid var(--edge);background:var(--soft);border-radius:12px;padding:8px 12px;margin-top:8px;font-size:13px;color:var(--muted)}
126
+ .ox-fold summary{cursor:pointer}
127
+ .ox-tl-axis,.ox-tl-row{display:grid;grid-template-columns:170px minmax(0,1fr);gap:8px}
128
+ .ox-tl-axis{font:10.5px var(--mono);color:var(--subtle);margin-bottom:4px}
129
+ .ox-tl-axis .yrs{display:flex;justify-content:space-between}
130
+ .ox-tl-row{align-items:center;padding:6px 0;border-top:1px solid var(--edge)}
131
+ .ox-tl-row .who{font-size:12.5px;line-height:1.3;min-width:0;overflow:hidden}
132
+ .ox-tl-row .who small{display:block;font:10.5px var(--mono);color:var(--subtle)}
133
+ .ox-track{position:relative;height:20px;background:var(--soft);border-radius:999px}
134
+ .ox-track i{position:absolute;top:2px;height:16px;border-radius:999px;background:var(--accent);color:#fff;font:10px/16px var(--mono);padding:0 7px;white-space:nowrap;overflow:hidden;font-style:normal}
135
+ .ox-track i.past{background:var(--subtle)}
136
+ .ox-kv{display:grid;grid-template-columns:150px minmax(0,1fr);gap:10px;padding:8px 0;border-top:1px solid var(--edge);font-size:13.5px}
137
+ .ox-kv:first-of-type{border-top:0}
138
+ .ox-kv .k{color:var(--muted)}
139
+ .ox-mask{letter-spacing:.15em;color:var(--muted)}
140
+ .ox-prose{line-height:1.6;font-size:14.5px}
141
+ .ox-prose h1,.ox-prose h2,.ox-prose h3{font-size:16px;margin:18px 0 6px}
142
+ .ox-prose pre{background:var(--soft);padding:10px;border-radius:8px;overflow:auto}
143
+ .ox-prose table{border-collapse:collapse}.ox-prose td,.ox-prose th{border:1px solid var(--edge);padding:4px 8px}
144
+ .ox-pager{display:flex;gap:10px;margin-top:12px;font:12px var(--mono)}
145
+ .ox-empty{color:var(--subtle);font-size:13px;padding:6px 0}
146
+ .ox-err{border:1px solid var(--bad-edge);background:var(--bad-soft);color:var(--bad);border-radius:12px;padding:10px 14px;margin:12px 0;font-size:13px}
147
+ @media (max-width:1100px){.ox-layout.rail{grid-template-columns:230px minmax(0,1fr)}.ox-rail{grid-column:2;border-left:0;border-top:1px solid var(--edge)}}
148
+ @media (max-width:760px){.ox-layout,.ox-layout.rail{grid-template-columns:1fr}.ox-side{min-height:0;border-right:0;border-bottom:1px solid var(--edge)}.ox-rail{grid-column:1}.ox-grid2{grid-template-columns:1fr}.ox-logo{width:auto}.ox-tl-axis,.ox-tl-row{grid-template-columns:110px minmax(0,1fr)}}
149
+ `;var F=()=>new Date().toISOString().slice(0,10);function q(o){return o?`<span class="ox-st ${l(o)}">${l(o)}</span>`:""}function K(o){return o.private?`<span class="l"><span class="ox-mask">\u2022\u2022\u2022\u2022</span> ${m("lock")}</span>`:o.entityId?`<a href="${f(o.entityId)}">${l(o.label)}</a>`:`<span class="l">${l(o.label)}</span>`}function J(o,t){if(t.sub)return t.sub;let e=[];return t.type&&e.push(b(o.ontology,t.type).toLowerCase()),t.since||t.until?e.push(`${t.since??"\u2026"} \u2192 ${t.until??"now"}`):t.date&&e.push(t.date),e.join(" \xB7 ")}function Y(o,t,e){let a=J(o,e),n=e.chips.map(i=>`<span class="ox-chip">${l(i)}</span>`).join(""),r=e.statement!==void 0&&e.statement>=0?`<a class="ox-sub" href="${f(t.id)}/s/${e.statement}" title="Where this comes from (Z4)">Z4</a>`:"";return`<div class="ox-row"><span class="ox-ic">${e.type?u(o.ontology,e.type):m(e.private?"lock":"topic")}</span><div class="t">${K(e)}${a?`<div class="ox-sub">${l(a)}</div>`:""}</div><div class="r">${n}${q(e.status)}${r}</div></div>`}function U(o){let t=o.importance??"normal";return`<div class="ox-ev"><span class="d">${l(o.date??"")}</span><span class="ox-st ${t}">${t}</span><span>${o.entityId?`<a href="${f(o.entityId)}">${l(o.label)}</a>`:l(o.label)}</span></div>`}function Q(o){let t=o.flatMap(s=>[s.since,s.until]).filter(s=>!!s).map(s=>Number(s.slice(0,4))).filter(Boolean),e=Number(F().slice(0,4)),a=Math.min(...t,e-1),n=Math.max(1,e+1-a),r=(s,c)=>{if(!s)return c?100:0;let[p,x]=[Number(s.slice(0,4)),Number(s.slice(5,7))||(c?12:1)];return Math.min(100,Math.max(0,(p-a+(x-1)/12)/n*100))},i=`<div class="ox-tl-axis"><span></span><span class="yrs"><span>${a}</span><span>${e}</span></span></div>`;for(let s of o){let c=r(s.since,!1),p=r(s.until,!0),x=`${s.since??"\u2026"} \u2192 ${s.until??"now"}`;i+=`<div class="ox-tl-row"><div class="who">${s.chips.map(l).join(", ")}<small>${s.entityId?`<a href="${f(s.entityId)}">${l(s.label)}</a>`:l(s.label)}</small></div><div class="ox-track"><i class="${s.until?"past":""}" style="left:${c.toFixed(1)}%;width:${Math.max(4,p-c).toFixed(1)}%" title="${l(x)}">${l(x)}</i></div></div>`}return i}function S(o,t,e,a,n=""){let r=!a&&(e.total>e.items.length||e.def.source==="notes"||e.folded.length)?`<a class="zin" href="${f(t.id)}/${encodeURIComponent(e.def.panel)}">all ${e.total||""} (Z3) \u2192</a>`:"",s=e.def.source==="notes"||e.def.panel==="notes"?`${t.pages.length} page${t.pages.length===1?"":"s"}`:`${e.total} ${e.total===1?"item":"items"}`,c=`<span class="note">${e.ownerOnly?`${m("lock")} private to the owner \xB7 `:""}${s}</span>`,p="";e.def.source==="notes"||e.def.panel==="notes"?p=n||'<div class="ox-empty">No notes.</div>':e.items.length===0?p='<div class="ox-empty">Nothing recorded yet.</div>':e.def.display==="timeline"&&e.items.some(d=>d.since)?p=Q(e.items):e.def.source==="history"||e.items.every(d=>d.type==="event")?p=e.items.map(U).join(""):p=e.items.map(d=>Y(o,t,d)).join("");for(let d of e.rollups)p+=`<div class="ox-fold">\u21BB Recurring: ${l(d)}</div>`;return e.folded.length&&(p+=`<details class="ox-fold"><summary>+ ${e.folded.length} minor event${e.folded.length===1?"":"s"}</summary>${e.folded.slice(0,20).map(U).join("")}</details>`),`<section class="ox-card${e.def.display==="timeline"||e.def.source==="notes"||e.def.panel==="notes"?" wide":""}"><div class="ox-card-h"><h2>${l(e.title)}</h2>${c}${r}</div>${p}</section>`}function C(o,t){return z(t.replace(/<!--\s*tags?:[^>]*-->\s*\n?/gi,"").replace(/<!-- \/overview -->\s*\n?/g,""),{wikilink:(e,a)=>{let n=o.names.get(h(e));return n?`<a href="${f(n)}" class="wikilink">${a}</a>`:`<a href="/find?q=${encodeURIComponent(e)}" class="wikilink broken" title="No page yet">${a}</a>`}})}function k(o){return o.replace(/^---\n[\s\S]*?\n---\n?/,"").trim()}var X=/^##[ \t]+Overview[ \t]*$/im,N="<!-- /overview -->";function D(o){let t=X.exec(o);if(!t)return;let e=t.index+t[0].length,a=o.slice(e),n=a.indexOf(N),r=a.search(/^#{1,2}[ \t]/m),i=[n,r].filter(p=>p>=0),s=e+(i.length?Math.min(...i):a.length),c=n>=0&&e+n===s?s+N.length:s;return{start:t.index,textStart:e,end:s,after:c}}function ee(o){let t=k(o),e=D(t);return(e?t.slice(e.textStart,e.end).trim():"")||void 0}function te(o){let t=[...o.pages].sort((e,a)=>(a.article.meta.lastUpdated||"").localeCompare(e.article.meta.lastUpdated||""));for(let e of t){let a=ee(e.article.content);if(a)return a}}function oe(o,t){if(o.length<=t)return o;let e=o.slice(0,t),a=Math.max(...[". ","! ","? ","\u061F ","\u3002"].map(n=>e.lastIndexOf(n)));return a>t/3?e.slice(0,a+1):`${e.replace(/\s+\S*$/,"")}\u2026`}function ne(o,t=360){let n=(k(o.pages[0]?.article.content??"").split(/\n\s*\n/).map(r=>r.trim()).find(r=>r&&!r.startsWith("#")&&!r.startsWith("|")&&!r.startsWith("```"))??"").replace(/\[\[([^\]|]+)(?:\|([^\]]+))?\]\]/g,(r,i,s)=>s??i).replace(/\[([^\]]+)\]\([^)]*\)/g,"$1").replace(/^[-*]\s+/gm,"").replace(/[*_`]/g,"").replace(/\s+/g," ").trim();return oe(n,t)}function ae(o,t){return o.ontology.pillars.find(e=>e.id===t.pillar)}function W(o,t,e=[]){let a=ae(o,t);return L([{label:a?.label??t.pillar,href:`/p/${encodeURIComponent(t.pillar)}`},{label:b(o.ontology,t.type),href:`/p/${encodeURIComponent(t.pillar)}?kind=${encodeURIComponent(t.type)}`},{label:t.title,href:e.length?f(t.id):void 0},...e])}function _(o,t,e){if(!e){let a=t.pages[0];if(!a)return"";let n=k(a.article.content),r=D(n),i=(r?n.slice(0,r.start)+n.slice(r.after):n).trim(),s=i.length>1600?`${i.slice(0,1600).replace(/\n[^\n]*$/,"")}
150
+
151
+ \u2026`:i;return`<div class="ox-prose">${C(o,s)}</div>`}return t.pages.map(a=>`<div class="ox-sub">from ${l(a.agentId)} \xB7 ${l(a.article.path)} \xB7 updated ${l(a.article.meta.lastUpdated||"\u2014")}</div><div class="ox-prose">${C(o,k(a.article.content))}</div>`).join('<hr style="border:0;border-top:1px solid var(--edge);margin:16px 0">')}function re(o,t,e){let a=o.ontology.types.find(i=>i.id===t.type),n=`<span class="ox-lbl">Lens for this type</span><div class="ox-annot"><b>${l(a?.label??t.type)}</b> opens with:<ol>`;n+=e.map(i=>`<li>${l(i.title??i.panel)}</li>`).join(""),n+=`</ol><span class="ox-sub">from ontology.yaml \xB7 types.${l(t.type)}.lens</span></div>`,n+='<span class="ox-lbl" style="margin-top:20px">Zoom in</span>';for(let i of e)n+=`<div class="ox-row"><span class="ox-ic">${m(g(i)==="history"?"calendar":g(i)==="discussed"?"chat":"arrow")}</span><div class="t"><a href="${f(t.id)}/${encodeURIComponent(i.panel)}">${l(i.title??i.panel)}</a><div class="ox-sub">Z3 \xB7 in full</div></div></div>`;n+='<span class="ox-lbl" style="margin-top:20px">Provenance</span>';let r=new Map;for(let i of t.pages)r.set(i.agentId,(r.get(i.agentId)??0)+1);for(let[i,s]of r){let c=t.pages.find(p=>p.agentId===i);n+=`<div class="ox-row"><span class="ox-ic">${m("agent")}</span><div class="t"><a href="/agent/${encodeURIComponent(i)}/article/${encodeURIComponent(c.article.path)}">${l(i)}</a><div class="ox-sub">${s} page${s===1?"":"s"} \xB7 ${t.statements.filter(p=>p.page.agentId===i).length} statements</div></div></div>`}return t.pages.length>1&&(n+=`<div class="ox-row"><span class="ox-ic">${m("merge")}</span><div class="t"><span class="l">${t.pages.length} pages merged</span><div class="ox-sub">same name, one entity</div></div></div>`),n}function ve(o,t){let{g:e}=o,a=E(e,t.type),n=e.ontology.types.find(p=>p.id===t.type),r=e.ontology.sidebar.pins.some(p=>e.names.get(h(p))===t.id),i=`<div class="ox-bar">${W(e,t)}${y(2)}</div>`;i+=`<div class="ox-head"><div class="ox-avatar">${u(e.ontology,t.type)}</div><div><h1>${l(t.title)}</h1><div class="ox-chips">`,i+=`<span class="ox-chip type">${u(e.ontology,t.type)}${l(n?.label??t.type)}</span>`,n?.schema&&(i+=`<span class="ox-chip mono">${l(n.schema.includes(" ")||n.schema.includes(":")?n.schema:`schema.org/${n.schema}`)}</span>`),t.type==="event"&&(i+=`<span class="ox-st ${t.importance}">${t.importance}</span>`),r&&(i+='<span class="ox-chip">pinned</span>'),t.pages.length>1&&(i+=`<span class="ox-chip">${m("merge")}merged from ${t.pages.length} pages</span>`),i+="</div></div></div>",t.review&&(i+=`<div class="ox-card ox-sub" style="border-color:var(--warn,#d97706)">Check the type: ${l(t.review)}</div>`);let s=te(t),c=s?"":ne(t);if((s||c)&&a[0]?.panel!=="notes"){let p=s?`<div class="ox-summary ox-prose">${C(e,s)}</div>`:`<p class="ox-summary">${l(c)}</p>`;i+=`<section class="ox-card">${p}<div class="ox-meta"><span>updated ${l(t.updated||"\u2014")}</span><span>sources: ${t.sources.length}</span><span>${t.statements.length} statements</span></div></section>`}i+='<div class="ox-grid2">';for(let p of a){let x=P(e,t,p,{full:!1,readEntries:o.readEntries}),d=g(p)==="notes";i+=S(e,t,x,!1,d?_(e,t,!1):"")}return i+="</div>",$(t.title,w(e,{pillar:t.pillar,entity:t.id}),i,re(e,t,a))}function be(o,t,e,a){let{g:n}=o,r=E(n,t.type).find(d=>d.panel===e);if(!r)return null;let i=P(n,t,r,{full:!0,page:a,pageSize:50,readEntries:o.readEntries}),s=r.title??r.panel,c=`<div class="ox-bar">${W(n,t,[{label:s}])}${y(3)}</div>`;c+=`<div class="ox-head"><div class="ox-avatar">${u(n.ontology,t.type)}</div><div><h1>${l(s)}</h1><p>${l(t.title)} \xB7 ${i.total} item${i.total===1?"":"s"}</p></div></div>`;let p=g(r)==="notes";c+=S(n,t,i,!0,p?_(n,t,!0):"");let x=Math.ceil(i.total/50);if(x>1){let d=`${f(t.id)}/${encodeURIComponent(e)}`;c+=`<div class="ox-pager">${a>1?`<a href="${d}?page=${a-1}">\u2190 newer</a>`:""}<span>page ${a} of ${x}</span>${a<x?`<a href="${d}?page=${a+1}">older \u2192</a>`:""}</div>`}return $(`${s} \xB7 ${t.title}`,w(n,{pillar:t.pillar,entity:t.id}),c)}function ye(o,t,e){let{g:a}=o,n=t.statements[e];if(!n)return null;let r=a.ontology.properties.find(d=>d.id===n.property),i=n.target?a.entities.get(n.target):void 0,s=n.page.article.meta,c=[["Subject",`<a href="${f(t.id)}">${l(t.title)}</a>`],["Property",`${l(r?.label??n.property)}${r?.wikidata?` <span class="ox-sub">wikidata ${l(r.wikidata)}</span>`:""}`],["Value",i?`<a href="${f(i.id)}">${l(i.title)}</a>`:l(n.value)]];n.role&&c.push(["Role",l(n.role)]),n.metric&&c.push(["Metric",l(n.metric)]),(n.since||n.until)&&c.push(["True",`${l(n.since??"\u2026")} \u2192 ${l(n.until??"now")}`]),n.at&&c.push(["Measured",l(n.at)]),c.push(["Recorded",l(s.lastUpdated||s.created||"\u2014")]),c.push(["Source",l(n.source??(s.sources.length?`${s.sources.length} conversation entries`:"not given"))]),c.push(["Written by",`${l(n.page.agentId)} \xB7 <a href="/agent/${encodeURIComponent(n.page.agentId)}/article/${encodeURIComponent(n.page.article.path)}">${l(n.page.article.path)}</a>`]),c.push(["Status",n.status?`<span class="ox-st ${l(n.status)}">${l(n.status)}</span>`:"not set"]),n.confirmed_by&&c.push(["Confirmed by",l(n.confirmed_by)]),n.checked_at&&c.push(["Checked",l(n.checked_at)]),c.push(["Access",l(n.access??s.access)]),n.note&&c.push(["Note",l(n.note)]);let p=o.versions(n.page.agentId,n.page.article.path);c.push(["Past versions",p.length?p.slice(0,8).map(d=>l(d.timestamp)).join("<br>"):"none saved"]);let x=`<div class="ox-bar">${W(a,t,[{label:r?.label??n.property}])}${y(4)}</div>`;return x+=`<div class="ox-head"><div class="ox-avatar">${m("key")}</div><div><h1>${l(r?.label??n.property)}</h1><p>${l(t.title)} \u2192 ${l(i?.title??n.value)}</p></div></div>`,x+=`<section class="ox-card">${c.map(([d,A])=>`<div class="ox-kv"><span class="k">${d}</span><span>${A}</span></div>`).join("")}</section>`,$(`${r?.label??n.property} \xB7 ${t.title}`,w(a,{pillar:t.pillar,entity:t.id}),x)}export{I as a,l as b,m as c,u as d,b as e,f,L as g,y as h,w as i,$ as j,k,N as l,D as m,ne as n,ve as o,be as p,ye as q};
152
+ //# sourceMappingURL=chunk-MCBTVNPX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/wiki/ontology/lens.ts","../src/wiki/ontology/view-layout.ts","../src/wiki/ontology/view-panels.ts","../src/wiki/ontology/view-entity.ts"],"sourcesContent":["// --- Panel contents for an entity, per its type's lens (#811) ---\n//\n// A lens lists panels; each panel reads one side of the entity from the\n// graph. At Z2 a panel shows its first few items, at Z3 all of them.\n// This file only selects and orders; the view decides how it looks.\n\nimport type { WikiEntry } from \"../types\"\nimport type { Entity, EntityStatement, WikiGraph } from \"./graph\"\nimport { panelFrom, panelSource } from \"./load\"\nimport type { Importance, LensPanel, TypeDef } from \"./types\"\n\nexport interface PanelItem {\n label: string\n /** Entity id when the item is a page. */\n entityId?: string\n /** Type of the other end, for its icon and sub-line. */\n type?: string\n /** Relation labels: property, role. */\n chips: string[]\n sub?: string\n since?: string\n until?: string\n date?: string\n importance?: Importance\n status?: string\n /** Masked at Z2 and Z3; the value shows at Z4 only. */\n private?: boolean\n /** Index in entity.statements, for the Z4 link. */\n statement?: number\n}\n\nexport interface PanelData {\n def: LensPanel\n title: string\n items: PanelItem[]\n /** Items before paging. */\n total: number\n /** History: minor events folded under the shown ones. */\n folded: PanelItem[]\n /** History: one line per recurring burst of minor events. */\n rollups: string[]\n ownerOnly: boolean\n}\n\nexport function lensFor(g: WikiGraph, type: string): LensPanel[] {\n return g.ontology.types.find((t: TypeDef) => t.id === type)?.lens ?? [{ panel: \"notes\", source: \"notes\", show: 1 }]\n}\n\nfunction propLabel(g: WikiGraph, id: string, inverse: boolean): string {\n const p = g.ontology.properties.find(x => x.id === id)\n if (!p) return id.replace(/_/g, \" \")\n return inverse ? (p.inverse ?? p.label) : p.label\n}\n\nfunction byRecent(a: PanelItem, b: PanelItem): number {\n const da = a.until ?? a.date ?? a.since ?? \"\"\n const db = b.until ?? b.date ?? b.since ?? \"\"\n if (da !== db) return db.localeCompare(da)\n return a.label.localeCompare(b.label)\n}\n\nfunction statementItem(g: WikiGraph, e: Entity, st: EntityStatement, inverse: boolean, from?: Entity): PanelItem {\n const other = inverse ? from : (st.target ? g.entities.get(st.target) : undefined)\n const chips = [propLabel(g, st.property, inverse)]\n // A long role would squeeze the name out of the row.\n if (st.role) chips.unshift(st.role.length > 40 ? `${st.role.slice(0, 39)}…` : st.role)\n return {\n label: other?.title ?? st.value,\n entityId: other?.id,\n type: other?.type,\n chips,\n since: st.since,\n until: st.until,\n status: st.status,\n private: st.access === \"private\",\n statement: inverse ? undefined : e.statements.indexOf(st),\n sub: st.note,\n }\n}\n\nfunction statementsPanel(g: WikiGraph, e: Entity, def: LensPanel): PanelItem[] {\n const from = new Set(panelFrom(def))\n const types = def.types ? new Set(def.types) : null\n const items: PanelItem[] = []\n const seen = new Set<string>()\n const keep = (other?: Entity): boolean => !types || (!!other && types.has(other.type))\n\n for (const st of e.statements) {\n if (!from.has(st.property)) continue\n const other = st.target ? g.entities.get(st.target) : undefined\n if (!keep(other)) continue\n items.push(statementItem(g, e, st, false))\n if (other) seen.add(other.id)\n }\n for (const edge of g.incoming.get(e.id) ?? []) {\n if (!from.has(edge.property)) continue\n const other = g.entities.get(edge.from)\n if (!other || !keep(other)) continue\n if (edge.statement) items.push(statementItem(g, e, edge.statement, true, other))\n else if (!seen.has(other.id)) items.push({ label: other.title, entityId: other.id, type: other.type, chips: [propLabel(g, \"related\", true)], date: other.updated })\n seen.add(other.id)\n }\n if (from.has(\"related\")) {\n for (const edge of g.outgoing.get(e.id) ?? []) {\n if (edge.property !== \"related\" || seen.has(edge.to)) continue\n const other = g.entities.get(edge.to)\n if (!other || !keep(other)) continue\n items.push({ label: other.title, entityId: other.id, type: other.type, chips: [propLabel(g, \"related\", false)], date: other.updated })\n seen.add(other.id)\n }\n }\n // Typed relations first, then plain links; each part newest first.\n const typed = items.filter(i => !i.chips.includes(propLabel(g, \"related\", false)))\n const plain = items.filter(i => i.chips.includes(propLabel(g, \"related\", false)))\n return [...typed.sort(byRecent), ...plain.sort(byRecent)]\n}\n\n/** Entities linked to `e` either way, of the given types. */\nexport function linkedEntities(g: WikiGraph, e: Entity, types: Set<string> | null): Entity[] {\n const ids = new Set<string>()\n for (const edge of g.outgoing.get(e.id) ?? []) ids.add(edge.to)\n for (const edge of g.incoming.get(e.id) ?? []) ids.add(edge.from)\n const out: Entity[] = []\n for (const id of ids) {\n const other = g.entities.get(id)\n if (other && (!types || types.has(other.type))) out.push(other)\n }\n return out.sort((a, b) => (b.date || b.updated).localeCompare(a.date || a.updated))\n}\n\nfunction entityItem(other: Entity): PanelItem {\n return { label: other.title, entityId: other.id, type: other.type, chips: [], date: other.date, importance: other.importance }\n}\n\nfunction historyPanel(g: WikiGraph, e: Entity, def: LensPanel): { shown: PanelItem[]; folded: PanelItem[]; rollups: string[] } {\n const events = linkedEntities(g, e, new Set([\"event\"])).map(entityItem)\n const shownLevels = new Set<Importance>(def.importance ?? [\"major\", \"normal\", \"minor\"])\n const shown = events.filter(i => shownLevels.has(i.importance ?? g.ontology.importance.default))\n const folded = def.fold ? events.filter(i => i.importance === def.fold) : []\n const rollups: string[] = []\n const rule = def.rollup ?? g.ontology.importance.rollup\n if (folded.length >= rule.min && folded[0].date) {\n const newest = Date.parse(folded[0].date)\n const recent = folded.filter(i => i.date && newest - Date.parse(i.date) <= rule.days * 86_400_000)\n if (recent.length >= rule.min) rollups.push(`${recent.length} minor events in ${rule.days} days up to ${folded[0].date}`)\n }\n return { shown, folded, rollups }\n}\n\nfunction readingsPanel(e: Entity, latestOnly: boolean): PanelItem[] {\n const readings = e.statements\n .map((st, i) => ({ st, i }))\n .filter(({ st }) => st.property === \"reading\" || !!st.metric)\n .sort((a, b) => (b.st.at ?? \"\").localeCompare(a.st.at ?? \"\"))\n const seen = new Set<string>()\n const out: PanelItem[] = []\n for (const { st, i } of readings) {\n const metric = st.metric ?? \"reading\"\n if (latestOnly && seen.has(metric)) continue\n seen.add(metric)\n out.push({ label: `${metric.replace(/_/g, \" \")}: ${st.value}`, chips: [], date: st.at, statement: i, private: st.access === \"private\" })\n }\n return out\n}\n\nfunction discussedPanel(e: Entity, readEntries: (ids: string[]) => WikiEntry[]): PanelItem[] {\n return readEntries(e.sources)\n .sort((a, b) => b.date.localeCompare(a.date))\n .map(en => {\n const line = en.content.split(\"\\n\").map(l => l.trim()).find(Boolean) ?? \"\"\n return {\n label: line.length > 120 ? `${line.slice(0, 117)}…` : line,\n chips: [],\n date: en.date,\n // The panel is owner-only as a whole; its rows are not masked.\n sub: `${en.date} · ${en.agentId} · ${en.source}`,\n }\n })\n}\n\nexport interface PanelOpts {\n full: boolean\n page?: number\n pageSize?: number\n readEntries: (ids: string[]) => WikiEntry[]\n}\n\nexport function panelData(g: WikiGraph, e: Entity, def: LensPanel, opts: PanelOpts): PanelData {\n const source = panelSource(def)\n let items: PanelItem[] = []\n let folded: PanelItem[] = []\n let rollups: string[] = []\n if (source === \"statements\") items = statementsPanel(g, e, def)\n else if (source === \"linked\") items = linkedEntities(g, e, def.types ? new Set(def.types) : null).map(entityItem)\n else if (source === \"readings\") items = readingsPanel(e, !opts.full && def.latest !== false)\n else if (source === \"discussed\") items = discussedPanel(e, opts.readEntries)\n else if (source === \"history\") {\n const h = historyPanel(g, e, def)\n // Z3 shows every level, minor ones unfolded.\n items = opts.full ? linkedEntities(g, e, new Set([\"event\"])).map(entityItem) : h.shown\n folded = opts.full ? [] : h.folded\n rollups = h.rollups\n }\n const total = items.length\n if (opts.full) {\n const size = opts.pageSize ?? 50\n const page = Math.max(1, opts.page ?? 1)\n items = items.slice((page - 1) * size, page * size)\n } else {\n items = items.slice(0, def.show ?? 5)\n }\n return {\n def,\n title: def.title ?? def.panel.replace(/_/g, \" \"),\n items,\n total,\n folded,\n rollups,\n ownerOnly: def.access === \"owner\",\n }\n}\n","// --- Wiki knowledge-graph view: page frame, sidebar, icons (#811) ---\n//\n// Server-rendered HTML with no client build, like the rest of the wiki.\n// The sidebar is the widest zoom level (Z0): Home, the owner's pins and\n// the pillars, nothing deeper.\n\nimport { normName, type WikiGraph } from \"./graph\"\nimport type { Ontology } from \"./types\"\n\nexport function esc(s: string): string {\n return String(s ?? \"\").replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\").replace(/\"/g, \"&quot;\")\n}\n\nconst PATHS: Record<string, string> = {\n home: '<rect x=\"3\" y=\"3\" width=\"7\" height=\"7\" rx=\"1\"/><rect x=\"14\" y=\"3\" width=\"7\" height=\"7\" rx=\"1\"/><rect x=\"3\" y=\"14\" width=\"7\" height=\"7\" rx=\"1\"/><rect x=\"14\" y=\"14\" width=\"7\" height=\"7\" rx=\"1\"/>',\n person: '<circle cx=\"12\" cy=\"8\" r=\"4\"/><path d=\"M4 21c0-4 4-6 8-6s8 2 8 6\"/>',\n org: '<rect x=\"4\" y=\"3\" width=\"16\" height=\"18\" rx=\"2\"/><path d=\"M9 7h2M13 7h2M9 11h2M13 11h2M9 15h2M13 15h2\"/>',\n pin: '<path d=\"M12 21s-7-6.2-7-11a7 7 0 0 1 14 0c0 4.8-7 11-7 11z\"/><circle cx=\"12\" cy=\"10\" r=\"2.5\"/>',\n server: '<rect x=\"3\" y=\"4\" width=\"18\" height=\"7\" rx=\"2\"/><rect x=\"3\" y=\"13\" width=\"18\" height=\"7\" rx=\"2\"/><path d=\"M7 7.5h.01M7 16.5h.01\"/>',\n device: '<rect x=\"4\" y=\"5\" width=\"16\" height=\"11\" rx=\"1.5\"/><path d=\"M2 19h20\"/>',\n app: '<rect x=\"4\" y=\"4\" width=\"16\" height=\"16\" rx=\"3\"/><path d=\"M9 12h6M12 9v6\"/>',\n globe: '<circle cx=\"12\" cy=\"12\" r=\"9\"/><path d=\"M3 12h18M12 3c3 3.5 3 14.5 0 18M12 3c-3 3.5-3 14.5 0 18\"/>',\n key: '<circle cx=\"8\" cy=\"15\" r=\"4\"/><path d=\"M11 12l9-9M17 6l3 3\"/>',\n agent: '<rect x=\"5\" y=\"8\" width=\"14\" height=\"11\" rx=\"3\"/><path d=\"M12 4v4M9 13h.01M15 13h.01\"/>',\n project: '<path d=\"M12 3l8 4.5v9L12 21l-8-4.5v-9z\"/><path d=\"M4 7.5l8 4.5 8-4.5M12 12v9\"/>',\n contract: '<path d=\"M7 3h7l5 5v13H7z\"/><path d=\"M14 3v5h5M10 13h6M10 17h4\"/>',\n law: '<path d=\"M12 3v18M5 21h14M6 7h12M6 7l-3 7a3 3 0 0 0 6 0zM18 7l-3 7a3 3 0 0 0 6 0z\"/>',\n calendar: '<rect x=\"3\" y=\"5\" width=\"18\" height=\"16\" rx=\"2\"/><path d=\"M3 10h18M8 3v4M16 3v4\"/>',\n decision: '<path d=\"M12 3v18M12 8H6l-2 2 2 2h6M12 12h6l2 2-2 2h-6\"/>',\n steps: '<path d=\"M9 6h11M9 12h11M9 18h11M4 6l1 1 2-2M4 12l1 1 2-2M4 18l1 1 2-2\"/>',\n topic: '<path d=\"M4 7h16M4 12h10M4 17h7\"/>',\n chat: '<path d=\"M4 5h16v11H9l-5 4z\"/>',\n lock: '<rect x=\"5\" y=\"11\" width=\"14\" height=\"10\" rx=\"2\"/><path d=\"M8 11V8a4 4 0 0 1 8 0v3\"/>',\n arrow: '<path d=\"M5 12h14M13 6l6 6-6 6\"/>',\n search: '<circle cx=\"11\" cy=\"11\" r=\"7\"/><path d=\"M21 21l-4.3-4.3\"/>',\n merge: '<circle cx=\"6\" cy=\"6\" r=\"2\"/><circle cx=\"6\" cy=\"18\" r=\"2\"/><circle cx=\"18\" cy=\"12\" r=\"2\"/><path d=\"M6 8v8M8 6c6 0 8 2 8 6\"/>',\n}\n\nexport function icon(name: string | undefined): string {\n const d = PATHS[name ?? \"\"] ?? PATHS.topic\n return `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.7\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">${d}</svg>`\n}\n\nexport function typeIcon(o: Ontology, type: string | undefined): string {\n return icon(o.types.find(t => t.id === type)?.icon)\n}\n\nexport function typeLabel(o: Ontology, type: string | undefined): string {\n return o.types.find(t => t.id === type)?.label ?? type ?? \"\"\n}\n\nexport function entityHref(id: string): string {\n return `/e/${encodeURIComponent(id)}`\n}\n\nexport interface Crumb { label: string; href?: string }\n\n/** Wiki / Pillar / Kind / Page / Panel, following the zoom. */\nexport function crumbs(list: Crumb[]): string {\n const parts = [{ label: \"Wiki\", href: \"/\" }, ...list].map((c, i, all) =>\n i === all.length - 1 || !c.href ? `<b>${esc(c.label)}</b>` : `<a href=\"${c.href}\">${esc(c.label)}</a>`)\n return `<nav class=\"ox-crumbs\" aria-label=\"Breadcrumb\">${parts.join('<span aria-hidden=\"true\">/</span>')}</nav>`\n}\n\n/** The Z0–Z4 indicator. `at` is the current level. */\nexport function zoomBar(at: 1 | 2 | 3 | 4): string {\n const names = [\"\", \"Pillar\", \"Overview\", \"Panel\", \"Statement\"]\n const cells = [1, 2, 3, 4].map(z => `<span class=\"${z === at ? \"on\" : \"\"}\">Z${z}${z === at ? ` ${names[z]}` : \"\"}</span>`)\n return `<div class=\"ox-zoom\" title=\"Zoom level\">${cells.join(\"\")}</div>`\n}\n\nexport function sidebar(g: WikiGraph, active: { pillar?: string; entity?: string; home?: boolean }): string {\n const o = g.ontology\n let html = `<a class=\"ox-nav${active.home ? \" on\" : \"\"}\" href=\"/\">${icon(\"home\")}<span>Home</span></a>`\n const pins = o.sidebar.pins.slice(0, o.sidebar.pins_max)\n if (pins.length) {\n html += `<div class=\"ox-side-h\">Pinned</div>`\n for (const title of pins) {\n const id = g.names.get(normName(title))\n const e = id ? g.entities.get(id) : undefined\n if (!e) continue\n html += `<a class=\"ox-nav pin${active.entity === e.id ? \" on\" : \"\"}\" href=\"${entityHref(e.id)}\">${typeIcon(o, e.type)}<span>${esc(e.title)}</span></a>`\n }\n }\n html += `<div class=\"ox-side-h\">Pillars</div>`\n for (const p of o.pillars) {\n if (p.sidebar === false) continue\n html += `<a class=\"ox-nav${active.pillar === p.id ? \" on\" : \"\"}\" href=\"/p/${encodeURIComponent(p.id)}\">${icon(p.icon)}<span>${esc(p.label)}</span></a>`\n }\n html += `<div class=\"ox-side-foot\">Types, topics and agent wikis are one level down, on Home and the pillar pages.</div>`\n return html\n}\n\nexport function layout(title: string, side: string, main: string, rail = \"\", q = \"\"): string {\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>${esc(title)} — Wiki</title>\n<style>${CSS}</style>\n<script>(function(){try{var t=localStorage.getItem('wiki-theme');if(t)document.documentElement.setAttribute('data-theme',t)}catch(e){}})();</script>\n</head>\n<body>\n<div class=\"ox-app\">\n <header class=\"ox-top\">\n <a class=\"ox-logo\" href=\"/\"><span class=\"mark\"><i></i></span>Wiki</a>\n <form class=\"ox-search\" action=\"/find\" method=\"get\" role=\"search\">${icon(\"search\")}<input type=\"search\" name=\"q\" value=\"${esc(q)}\" placeholder=\"Jump to any page\" aria-label=\"Search the wiki\" autocomplete=\"off\"><kbd>⌘K</kbd></form>\n <span class=\"ox-spacer\"></span>\n <a class=\"ox-btn\" href=\"/agents\">Agent wikis</a>\n <button class=\"ox-btn\" id=\"ox-theme\" type=\"button\" aria-label=\"Toggle theme\">Theme</button>\n </header>\n <div class=\"ox-layout${rail ? \" rail\" : \"\"}\">\n <nav class=\"ox-side\" aria-label=\"Wiki\">${side}</nav>\n <main class=\"ox-main\">${main}</main>\n ${rail ? `<aside class=\"ox-rail\">${rail}</aside>` : \"\"}\n </div>\n</div>\n<script>\n(function(){\n var b=document.getElementById('ox-theme');\n if(b)b.addEventListener('click',function(){var d=document.documentElement.getAttribute('data-theme')==='dark'?'':'dark';if(d)document.documentElement.setAttribute('data-theme','dark');else document.documentElement.removeAttribute('data-theme');try{localStorage.setItem('wiki-theme',d)}catch(e){}});\n document.addEventListener('keydown',function(e){if((e.metaKey||e.ctrlKey)&&e.key.toLowerCase()==='k'){e.preventDefault();var i=document.querySelector('.ox-search input');if(i)i.focus();}});\n})();\n</script>\n</body>\n</html>`\n}\n\nconst CSS = `\n:root{--paper:#fafaf9;--card:#fff;--soft:#f4f4f2;--edge:#e7e7e3;--ink:#121614;--muted:#4f5755;--subtle:#7d8684;\n--accent:#1e40af;--accent-soft:#eef3ff;--accent-edge:#c7d6fb;--ok:#0f766e;--ok-soft:#effcf9;--ok-edge:#a7eadf;\n--warn:#92400e;--warn-soft:#fffbeb;--warn-edge:#fde68a;--bad:#b91c1c;--bad-soft:#fef2f2;--bad-edge:#fecaca;\n--mono:ui-monospace,SFMono-Regular,Menlo,monospace;--sans:system-ui,-apple-system,\"Segoe UI\",sans-serif}\n[data-theme=dark]{--paper:#111413;--card:#181c1b;--soft:#1f2422;--edge:#2c3331;--ink:#e9eeec;--muted:#b3bcba;--subtle:#87918f;\n--accent:#9db7ff;--accent-soft:#1c2540;--accent-edge:#33406a;--ok:#5eead4;--ok-soft:#10302b;--ok-edge:#1d5249;\n--warn:#fcd34d;--warn-soft:#33290f;--warn-edge:#5c4a17;--bad:#fca5a5;--bad-soft:#3a1717;--bad-edge:#5e2525}\n*{box-sizing:border-box}\nbody{margin:0;background:var(--paper);color:var(--ink);font:14px/1.45 var(--sans);-webkit-font-smoothing:antialiased}\na{color:var(--accent);text-decoration:none}a:hover{text-decoration:underline}\n.ox-top{display:flex;align-items:center;gap:16px;padding:10px 18px;border-bottom:1px solid var(--edge);background:var(--card);position:sticky;top:0;z-index:5}\nbody>a[href=\"/admin\"]+.ox-app .ox-top{padding-right:130px}\n.ox-logo{display:flex;align-items:center;gap:9px;font-weight:600;color:var(--ink);width:200px}\n.ox-logo .mark{width:24px;height:24px;border-radius:7px;background:var(--ink);display:flex;align-items:center;justify-content:center}\n.ox-logo .mark i{width:8px;height:8px;border-radius:50%;background:#14b8a6}\n.ox-search{flex:0 1 440px;display:flex;align-items:center;gap:8px;border:1px solid var(--edge);border-radius:999px;padding:6px 12px;background:var(--paper)}\n.ox-search svg{width:15px;height:15px;color:var(--subtle)}\n.ox-search input{flex:1;border:0;background:transparent;color:var(--ink);font:13px var(--sans);outline:none}\n.ox-search kbd{font:11px var(--mono);color:var(--subtle)}\n.ox-spacer{flex:1}\n.ox-btn{font:12.5px var(--sans);border:1px solid var(--edge);background:var(--card);color:var(--ink);border-radius:999px;padding:5px 12px;cursor:pointer;display:inline-flex;gap:6px;align-items:center}\n.ox-layout{display:grid;grid-template-columns:230px minmax(0,1fr)}\n.ox-layout.rail{grid-template-columns:230px minmax(0,1fr) 290px}\n.ox-side{border-right:1px solid var(--edge);padding:14px 12px;min-height:calc(100vh - 50px)}\n.ox-nav{display:flex;align-items:center;gap:10px;padding:7px 10px;border-radius:10px;color:var(--ink)}\n.ox-nav:hover{background:var(--soft);text-decoration:none}\n.ox-nav svg{width:16px;height:16px;color:var(--muted);flex:none}\n.ox-nav span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.ox-nav.on{background:var(--accent-soft);color:var(--accent);font-weight:500}.ox-nav.on svg{color:var(--accent)}\n.ox-side-h{font:10.5px var(--mono);letter-spacing:.08em;text-transform:uppercase;color:var(--subtle);padding:16px 10px 6px}\n.ox-side-foot{margin-top:18px;border-top:1px solid var(--edge);padding:12px 10px 0;font:10.5px/1.6 var(--mono);color:var(--subtle)}\n.ox-main{padding:20px 28px 48px;min-width:0}\n.ox-rail{border-left:1px solid var(--edge);padding:20px 18px}\n.ox-bar{display:flex;align-items:center;justify-content:space-between;gap:12px}\n.ox-crumbs{font:11.5px var(--mono);color:var(--subtle);display:flex;gap:8px;flex-wrap:wrap}\n.ox-crumbs b{color:var(--ink);font-weight:500}\n.ox-zoom{display:inline-flex;border:1px solid var(--edge);border-radius:999px;padding:3px;background:var(--card);gap:2px}\n.ox-zoom span{font:10.5px var(--mono);letter-spacing:.05em;text-transform:uppercase;padding:4px 9px;border-radius:999px;color:var(--subtle)}\n.ox-zoom span.on{background:var(--ink);color:var(--paper)}\n.ox-head{display:flex;gap:16px;align-items:flex-start;margin:16px 0 18px}\n.ox-avatar{width:54px;height:54px;border-radius:14px;background:var(--accent-soft);border:1px solid var(--accent-edge);display:flex;align-items:center;justify-content:center;color:var(--accent);flex:none}\n.ox-avatar svg{width:26px;height:26px}\n.ox-head h1{font-size:30px;margin:2px 0 8px;letter-spacing:-.02em;font-weight:600;line-height:1.15}\n.ox-head p{margin:0;color:var(--muted)}\n.ox-chips{display:flex;gap:6px;flex-wrap:wrap;align-items:center}\n.ox-chip{font-size:12px;border:1px solid var(--edge);background:var(--card);border-radius:999px;padding:2px 10px;color:var(--muted);display:inline-flex;gap:6px;align-items:center;white-space:nowrap}\n.ox-chip svg{width:12px;height:12px}\n.ox-chip.type{background:var(--accent-soft);border-color:var(--accent-edge);color:var(--accent)}\n.ox-chip.mono{font:11px var(--mono)}\n.ox-st{font:10px var(--mono);letter-spacing:.07em;text-transform:uppercase;border-radius:999px;padding:3px 8px;border:1px solid;white-space:nowrap}\n.ox-st.ok,.ox-st.confirmed{color:var(--ok);background:var(--ok-soft);border-color:var(--ok-edge)}\n.ox-st.proposed{color:var(--accent);background:var(--accent-soft);border-color:var(--accent-edge)}\n.ox-st.warn,.ox-st.due{color:var(--warn);background:var(--warn-soft);border-color:var(--warn-edge)}\n.ox-st.bad,.ox-st.late{color:var(--bad);background:var(--bad-soft);border-color:var(--bad-edge)}\n.ox-st.major{color:var(--paper);background:var(--ink);border-color:var(--ink)}\n.ox-st.normal{color:var(--muted);background:var(--soft);border-color:var(--edge)}\n.ox-st.minor{color:var(--subtle);background:var(--card);border-color:var(--edge)}\n.ox-card{background:var(--card);border:1px solid var(--edge);border-radius:16px;padding:16px 18px;min-width:0}\n.ox-card-h{display:flex;align-items:baseline;gap:10px;margin-bottom:10px}\n.ox-card-h h2,.ox-card-h h3{font-size:15px;margin:0;font-weight:600;white-space:nowrap}\n.ox-card-h .note{font:11px var(--mono);color:var(--subtle);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}\n.ox-card-h .zin{margin-left:auto;font:11px var(--mono);white-space:nowrap}\n.ox-grid2{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:16px;margin-top:16px}\n.ox-grid2>.wide{grid-column:1/-1}\n.ox-grid3{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:14px;margin-top:16px}\n.ox-row{display:flex;align-items:center;gap:10px;padding:8px 0;border-top:1px solid var(--edge);font-size:13.5px;min-width:0}\n.ox-row:first-of-type{border-top:0}\n.ox-row .t{min-width:35%;overflow:hidden;flex:1 1 auto}\n.ox-row .t a,.ox-row .t span.l{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.ox-row .r{margin-left:auto;display:flex;gap:6px;align-items:center;flex:0 1 auto;min-width:0;flex-wrap:wrap;justify-content:flex-end}\n.ox-row .r .ox-chip{max-width:240px;overflow:hidden;text-overflow:ellipsis}\n.ox-ic{width:28px;height:28px;border-radius:8px;background:var(--soft);border:1px solid var(--edge);display:flex;align-items:center;justify-content:center;flex:none;color:var(--muted)}\n.ox-ic svg{width:14px;height:14px}\n.ox-card-h .note svg,.ox-row .l svg{width:12px;height:12px;vertical-align:-2px}\n.ox-sub{font:11px var(--mono);color:var(--subtle);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.ox-summary{font-size:15px;line-height:1.55;margin:0 0 10px}\n.ox-meta{display:flex;gap:16px;flex-wrap:wrap;font:11px var(--mono);color:var(--subtle)}\n.ox-lbl{font:10.5px var(--mono);letter-spacing:.08em;text-transform:uppercase;color:var(--subtle);display:block;margin:4px 0 10px}\n.ox-annot{border:1px dashed var(--subtle);border-radius:14px;padding:12px 14px;font-size:12.5px;color:var(--muted);line-height:1.5}\n.ox-annot ol{margin:6px 0;padding-left:18px}\n.ox-annot .ox-sub{white-space:normal;overflow-wrap:anywhere}\n.ox-rail .ox-row{font-size:13px}\n.ox-tabs{display:flex;gap:4px;border-bottom:1px solid var(--edge);margin:4px 0 0;flex-wrap:wrap}\n.ox-tabs a{padding:8px 12px;color:var(--muted);border-bottom:2px solid transparent;font-size:13.5px}\n.ox-tabs a.on{color:var(--ink);border-color:var(--ink);font-weight:500}\n.ox-tabs a small{font:11px var(--mono);color:var(--subtle);margin-left:4px}\n.ox-ev{display:grid;grid-template-columns:86px 70px minmax(0,1fr);gap:10px;align-items:center;padding:8px 0;border-top:1px solid var(--edge);font-size:13.5px}\n.ox-ev:first-of-type{border-top:0}\n.ox-ev .d{font:11px var(--mono);color:var(--subtle)}\n.ox-ev a{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block}\n.ox-fold{border:1px solid var(--edge);background:var(--soft);border-radius:12px;padding:8px 12px;margin-top:8px;font-size:13px;color:var(--muted)}\n.ox-fold summary{cursor:pointer}\n.ox-tl-axis,.ox-tl-row{display:grid;grid-template-columns:170px minmax(0,1fr);gap:8px}\n.ox-tl-axis{font:10.5px var(--mono);color:var(--subtle);margin-bottom:4px}\n.ox-tl-axis .yrs{display:flex;justify-content:space-between}\n.ox-tl-row{align-items:center;padding:6px 0;border-top:1px solid var(--edge)}\n.ox-tl-row .who{font-size:12.5px;line-height:1.3;min-width:0;overflow:hidden}\n.ox-tl-row .who small{display:block;font:10.5px var(--mono);color:var(--subtle)}\n.ox-track{position:relative;height:20px;background:var(--soft);border-radius:999px}\n.ox-track i{position:absolute;top:2px;height:16px;border-radius:999px;background:var(--accent);color:#fff;font:10px/16px var(--mono);padding:0 7px;white-space:nowrap;overflow:hidden;font-style:normal}\n.ox-track i.past{background:var(--subtle)}\n.ox-kv{display:grid;grid-template-columns:150px minmax(0,1fr);gap:10px;padding:8px 0;border-top:1px solid var(--edge);font-size:13.5px}\n.ox-kv:first-of-type{border-top:0}\n.ox-kv .k{color:var(--muted)}\n.ox-mask{letter-spacing:.15em;color:var(--muted)}\n.ox-prose{line-height:1.6;font-size:14.5px}\n.ox-prose h1,.ox-prose h2,.ox-prose h3{font-size:16px;margin:18px 0 6px}\n.ox-prose pre{background:var(--soft);padding:10px;border-radius:8px;overflow:auto}\n.ox-prose table{border-collapse:collapse}.ox-prose td,.ox-prose th{border:1px solid var(--edge);padding:4px 8px}\n.ox-pager{display:flex;gap:10px;margin-top:12px;font:12px var(--mono)}\n.ox-empty{color:var(--subtle);font-size:13px;padding:6px 0}\n.ox-err{border:1px solid var(--bad-edge);background:var(--bad-soft);color:var(--bad);border-radius:12px;padding:10px 14px;margin:12px 0;font-size:13px}\n@media (max-width:1100px){.ox-layout.rail{grid-template-columns:230px minmax(0,1fr)}.ox-rail{grid-column:2;border-left:0;border-top:1px solid var(--edge)}}\n@media (max-width:760px){.ox-layout,.ox-layout.rail{grid-template-columns:1fr}.ox-side{min-height:0;border-right:0;border-bottom:1px solid var(--edge)}.ox-rail{grid-column:1}.ox-grid2{grid-template-columns:1fr}.ox-logo{width:auto}.ox-tl-axis,.ox-tl-row{grid-template-columns:110px minmax(0,1fr)}}\n`\n","// --- Rendering one lens panel (#811) ---\n\nimport type { Entity, WikiGraph } from \"./graph\"\nimport type { PanelData, PanelItem } from \"./lens\"\nimport { entityHref, esc, icon, typeIcon, typeLabel } from \"./view-layout\"\n\nconst today = (): string => new Date().toISOString().slice(0, 10)\n\nfunction statusChip(s?: string): string {\n return s ? `<span class=\"ox-st ${esc(s)}\">${esc(s)}</span>` : \"\"\n}\n\nfunction itemTitle(it: PanelItem): string {\n if (it.private) return `<span class=\"l\"><span class=\"ox-mask\">••••</span> ${icon(\"lock\")}</span>`\n return it.entityId ? `<a href=\"${entityHref(it.entityId)}\">${esc(it.label)}</a>` : `<span class=\"l\">${esc(it.label)}</span>`\n}\n\nfunction itemSub(g: WikiGraph, it: PanelItem): string {\n if (it.sub) return it.sub\n const parts: string[] = []\n if (it.type) parts.push(typeLabel(g.ontology, it.type).toLowerCase())\n if (it.since || it.until) parts.push(`${it.since ?? \"…\"} → ${it.until ?? \"now\"}`)\n else if (it.date) parts.push(it.date)\n return parts.join(\" · \")\n}\n\nfunction rowHtml(g: WikiGraph, e: Entity, it: PanelItem): string {\n const sub = itemSub(g, it)\n const chips = it.chips.map(c => `<span class=\"ox-chip\">${esc(c)}</span>`).join(\"\")\n const z4 = it.statement !== undefined && it.statement >= 0\n ? `<a class=\"ox-sub\" href=\"${entityHref(e.id)}/s/${it.statement}\" title=\"Where this comes from (Z4)\">Z4</a>` : \"\"\n return `<div class=\"ox-row\"><span class=\"ox-ic\">${it.type ? typeIcon(g.ontology, it.type) : icon(it.private ? \"lock\" : \"topic\")}</span>`\n + `<div class=\"t\">${itemTitle(it)}${sub ? `<div class=\"ox-sub\">${esc(sub)}</div>` : \"\"}</div>`\n + `<div class=\"r\">${chips}${statusChip(it.status)}${z4}</div></div>`\n}\n\nfunction eventRow(it: PanelItem): string {\n const level = it.importance ?? \"normal\"\n return `<div class=\"ox-ev\"><span class=\"d\">${esc(it.date ?? \"\")}</span><span class=\"ox-st ${level}\">${level}</span>`\n + `<span>${it.entityId ? `<a href=\"${entityHref(it.entityId)}\">${esc(it.label)}</a>` : esc(it.label)}</span></div>`\n}\n\nfunction timeline(items: PanelItem[]): string {\n const years = items.flatMap(i => [i.since, i.until]).filter((d): d is string => !!d).map(d => Number(d.slice(0, 4))).filter(Boolean)\n const now = Number(today().slice(0, 4))\n const min = Math.min(...years, now - 1)\n const span = Math.max(1, now + 1 - min)\n const pos = (d: string | undefined, end: boolean): number => {\n if (!d) return end ? 100 : 0\n const [y, m] = [Number(d.slice(0, 4)), Number(d.slice(5, 7)) || (end ? 12 : 1)]\n return Math.min(100, Math.max(0, ((y - min) + (m - 1) / 12) / span * 100))\n }\n let html = `<div class=\"ox-tl-axis\"><span></span><span class=\"yrs\"><span>${min}</span><span>${now}</span></span></div>`\n for (const it of items) {\n const left = pos(it.since, false)\n const right = pos(it.until, true)\n const label = `${it.since ?? \"…\"} → ${it.until ?? \"now\"}`\n html += `<div class=\"ox-tl-row\"><div class=\"who\">${it.chips.map(esc).join(\", \")}<small>${it.entityId ? `<a href=\"${entityHref(it.entityId)}\">${esc(it.label)}</a>` : esc(it.label)}</small></div>`\n + `<div class=\"ox-track\"><i class=\"${it.until ? \"past\" : \"\"}\" style=\"left:${left.toFixed(1)}%;width:${Math.max(4, right - left).toFixed(1)}%\" title=\"${esc(label)}\">${esc(label)}</i></div></div>`\n }\n return html\n}\n\n/** A panel card. `full` is the Z3 view: no zoom link, minor events unfolded. */\nexport function panelCard(g: WikiGraph, e: Entity, p: PanelData, full: boolean, notesHtml = \"\"): string {\n const zin = !full && (p.total > p.items.length || p.def.source === \"notes\" || p.folded.length)\n ? `<a class=\"zin\" href=\"${entityHref(e.id)}/${encodeURIComponent(p.def.panel)}\">all ${p.total || \"\"} (Z3) →</a>` : \"\"\n const isNotes = p.def.source === \"notes\" || p.def.panel === \"notes\"\n const count = isNotes ? `${e.pages.length} page${e.pages.length === 1 ? \"\" : \"s\"}` : `${p.total} ${p.total === 1 ? \"item\" : \"items\"}`\n const note = `<span class=\"note\">${p.ownerOnly ? `${icon(\"lock\")} private to the owner · ` : \"\"}${count}</span>`\n let body = \"\"\n if (p.def.source === \"notes\" || p.def.panel === \"notes\") {\n body = notesHtml || `<div class=\"ox-empty\">No notes.</div>`\n } else if (p.items.length === 0) {\n body = `<div class=\"ox-empty\">Nothing recorded yet.</div>`\n } else if (p.def.display === \"timeline\" && p.items.some(i => i.since)) {\n body = timeline(p.items)\n } else if (p.def.source === \"history\" || p.items.every(i => i.type === \"event\")) {\n body = p.items.map(eventRow).join(\"\")\n } else {\n body = p.items.map(it => rowHtml(g, e, it)).join(\"\")\n }\n for (const r of p.rollups) body += `<div class=\"ox-fold\">↻ Recurring: ${esc(r)}</div>`\n if (p.folded.length) {\n body += `<details class=\"ox-fold\"><summary>+ ${p.folded.length} minor event${p.folded.length === 1 ? \"\" : \"s\"}</summary>${p.folded.slice(0, 20).map(eventRow).join(\"\")}</details>`\n }\n const wide = p.def.display === \"timeline\" || p.def.source === \"notes\" || p.def.panel === \"notes\" ? \" wide\" : \"\"\n return `<section class=\"ox-card${wide}\"><div class=\"ox-card-h\"><h2>${esc(p.title)}</h2>${note}${zin}</div>${body}</section>`\n}\n","// --- Entity pages: overview (Z2), one panel (Z3), one statement (Z4) ---\n\nimport { markdownToHtml } from \"@/utils/markdown-html\"\nimport type { WikiEntry } from \"../types\"\nimport { normName, type Entity, type WikiGraph } from \"./graph\"\nimport { lensFor, panelData } from \"./lens\"\nimport { panelSource } from \"./load\"\nimport type { LensPanel } from \"./types\"\nimport { panelCard } from \"./view-panels\"\nimport { crumbs, entityHref, esc, icon, layout, sidebar, typeIcon, typeLabel, zoomBar } from \"./view-layout\"\n\nexport interface EntityViewCtx {\n g: WikiGraph\n readEntries: (ids: string[]) => WikiEntry[]\n /** Saved earlier versions of one agent's page, newest first. */\n versions: (agentId: string, path: string) => Array<{ timestamp: string }>\n}\n\n/** Article markdown with [[links]] pointing at entity pages. */\nexport function wikiMd(g: WikiGraph, text: string): string {\n return markdownToHtml(text.replace(/<!--\\s*tags?:[^>]*-->\\s*\\n?/gi, \"\").replace(/<!-- \\/overview -->\\s*\\n?/g, \"\"), {\n wikilink: (target, display) => {\n const id = g.names.get(normName(target))\n return id\n ? `<a href=\"${entityHref(id)}\" class=\"wikilink\">${display}</a>`\n : `<a href=\"/find?q=${encodeURIComponent(target)}\" class=\"wikilink broken\" title=\"No page yet\">${display}</a>`\n },\n })\n}\n\n/** Page body without a second frontmatter block some older pages carry. */\nexport function bodyOf(content: string): string {\n return content.replace(/^---\\n[\\s\\S]*?\\n---\\n?/, \"\").trim()\n}\n\nconst OVERVIEW_HEADING = /^##[ \\t]+Overview[ \\t]*$/im\n/** Closes an Overview section on pages whose other text has no headings. */\nexport const OVERVIEW_END = \"<!-- /overview -->\"\n\n/** Where the Overview section starts and ends in a body, if it has one. */\nexport function overviewSpan(body: string): { start: number; textStart: number; end: number; after: number } | undefined {\n const m = OVERVIEW_HEADING.exec(body)\n if (!m) return undefined\n const textStart = m.index + m[0].length\n const rest = body.slice(textStart)\n const marker = rest.indexOf(OVERVIEW_END)\n const heading = rest.search(/^#{1,2}[ \\t]/m)\n const cut = [marker, heading].filter(i => i >= 0)\n const end = textStart + (cut.length ? Math.min(...cut) : rest.length)\n const after = marker >= 0 && textStart + marker === end ? end + OVERVIEW_END.length : end\n return { start: m.index, textStart, end, after }\n}\n\n/** The `## Overview` section of a page body, without its heading. */\nexport function overviewSection(content: string): string | undefined {\n const body = bodyOf(content)\n const span = overviewSpan(body)\n const text = span ? body.slice(span.textStart, span.end).trim() : \"\"\n return text || undefined\n}\n\n/** The newest `## Overview` any of the entity's pages has (#820). */\nexport function overviewOf(e: Entity): string | undefined {\n const pages = [...e.pages].sort((a, b) => (b.article.meta.lastUpdated || \"\").localeCompare(a.article.meta.lastUpdated || \"\"))\n for (const p of pages) {\n const text = overviewSection(p.article.content)\n if (text) return text\n }\n return undefined\n}\n\n/** Cut at the last sentence end that fits, else at a word. */\nexport function cutAtSentence(text: string, max: number): string {\n if (text.length <= max) return text\n const head = text.slice(0, max)\n const end = Math.max(...[\". \", \"! \", \"? \", \"؟ \", \"。\"].map(s => head.lastIndexOf(s)))\n if (end > max / 3) return head.slice(0, end + 1)\n return `${head.replace(/\\s+\\S*$/, \"\")}…`\n}\n\n/** First paragraph of the first page, as plain text. */\nexport function summaryOf(e: Entity, max = 360): string {\n const body = bodyOf(e.pages[0]?.article.content ?? \"\")\n const para = body.split(/\\n\\s*\\n/).map(p => p.trim()).find(p => p && !p.startsWith(\"#\") && !p.startsWith(\"|\") && !p.startsWith(\"```\")) ?? \"\"\n const plain = para\n .replace(/\\[\\[([^\\]|]+)(?:\\|([^\\]]+))?\\]\\]/g, (_m, t, d) => d ?? t)\n .replace(/\\[([^\\]]+)\\]\\([^)]*\\)/g, \"$1\")\n .replace(/^[-*]\\s+/gm, \"\")\n .replace(/[*_`]/g, \"\")\n .replace(/\\s+/g, \" \")\n .trim()\n return cutAtSentence(plain, max)\n}\n\nfunction pillarOf(g: WikiGraph, e: Entity) {\n return g.ontology.pillars.find(p => p.id === e.pillar)\n}\n\nfunction entityCrumbs(g: WikiGraph, e: Entity, tail: Array<{ label: string; href?: string }> = []): string {\n const p = pillarOf(g, e)\n return crumbs([\n { label: p?.label ?? e.pillar, href: `/p/${encodeURIComponent(e.pillar)}` },\n { label: typeLabel(g.ontology, e.type), href: `/p/${encodeURIComponent(e.pillar)}?kind=${encodeURIComponent(e.type)}` },\n { label: e.title, href: tail.length ? entityHref(e.id) : undefined },\n ...tail,\n ])\n}\n\nfunction notesHtml(g: WikiGraph, e: Entity, full: boolean): string {\n if (!full) {\n const first = e.pages[0]\n if (!first) return \"\"\n // The overview card above already shows the Overview section.\n const body = bodyOf(first.article.content)\n const span = overviewSpan(body)\n const text = (span ? body.slice(0, span.start) + body.slice(span.after) : body).trim()\n const short = text.length > 1600 ? `${text.slice(0, 1600).replace(/\\n[^\\n]*$/, \"\")}\\n\\n…` : text\n return `<div class=\"ox-prose\">${wikiMd(g, short)}</div>`\n }\n return e.pages.map(p => `<div class=\"ox-sub\">from ${esc(p.agentId)} · ${esc(p.article.path)} · updated ${esc(p.article.meta.lastUpdated || \"—\")}</div>`\n + `<div class=\"ox-prose\">${wikiMd(g, bodyOf(p.article.content))}</div>`).join(`<hr style=\"border:0;border-top:1px solid var(--edge);margin:16px 0\">`)\n}\n\nfunction rail(g: WikiGraph, e: Entity, lens: LensPanel[]): string {\n const t = g.ontology.types.find(x => x.id === e.type)\n let html = `<span class=\"ox-lbl\">Lens for this type</span><div class=\"ox-annot\"><b>${esc(t?.label ?? e.type)}</b> opens with:<ol>`\n html += lens.map(p => `<li>${esc(p.title ?? p.panel)}</li>`).join(\"\")\n html += `</ol><span class=\"ox-sub\">from ontology.yaml · types.${esc(e.type)}.lens</span></div>`\n html += `<span class=\"ox-lbl\" style=\"margin-top:20px\">Zoom in</span>`\n for (const p of lens) {\n html += `<div class=\"ox-row\"><span class=\"ox-ic\">${icon(panelSource(p) === \"history\" ? \"calendar\" : panelSource(p) === \"discussed\" ? \"chat\" : \"arrow\")}</span><div class=\"t\"><a href=\"${entityHref(e.id)}/${encodeURIComponent(p.panel)}\">${esc(p.title ?? p.panel)}</a><div class=\"ox-sub\">Z3 · in full</div></div></div>`\n }\n html += `<span class=\"ox-lbl\" style=\"margin-top:20px\">Provenance</span>`\n const byAgent = new Map<string, number>()\n for (const p of e.pages) byAgent.set(p.agentId, (byAgent.get(p.agentId) ?? 0) + 1)\n for (const [agent, n] of byAgent) {\n const page = e.pages.find(p => p.agentId === agent)!\n html += `<div class=\"ox-row\"><span class=\"ox-ic\">${icon(\"agent\")}</span><div class=\"t\"><a href=\"/agent/${encodeURIComponent(agent)}/article/${encodeURIComponent(page.article.path)}\">${esc(agent)}</a><div class=\"ox-sub\">${n} page${n === 1 ? \"\" : \"s\"} · ${e.statements.filter(s => s.page.agentId === agent).length} statements</div></div></div>`\n }\n if (e.pages.length > 1) html += `<div class=\"ox-row\"><span class=\"ox-ic\">${icon(\"merge\")}</span><div class=\"t\"><span class=\"l\">${e.pages.length} pages merged</span><div class=\"ox-sub\">same name, one entity</div></div></div>`\n return html\n}\n\n/** Z2: one thing, through the lens of its type. */\nexport function entityPage(ctx: EntityViewCtx, e: Entity): string {\n const { g } = ctx\n const lens = lensFor(g, e.type)\n const t = g.ontology.types.find(x => x.id === e.type)\n const pinned = g.ontology.sidebar.pins.some(p => g.names.get(normName(p)) === e.id)\n let main = `<div class=\"ox-bar\">${entityCrumbs(g, e)}${zoomBar(2)}</div>`\n main += `<div class=\"ox-head\"><div class=\"ox-avatar\">${typeIcon(g.ontology, e.type)}</div><div><h1>${esc(e.title)}</h1><div class=\"ox-chips\">`\n main += `<span class=\"ox-chip type\">${typeIcon(g.ontology, e.type)}${esc(t?.label ?? e.type)}</span>`\n if (t?.schema) main += `<span class=\"ox-chip mono\">${esc(t.schema.includes(\" \") || t.schema.includes(\":\") ? t.schema : `schema.org/${t.schema}`)}</span>`\n if (e.type === \"event\") main += `<span class=\"ox-st ${e.importance}\">${e.importance}</span>`\n if (pinned) main += `<span class=\"ox-chip\">pinned</span>`\n if (e.pages.length > 1) main += `<span class=\"ox-chip\">${icon(\"merge\")}merged from ${e.pages.length} pages</span>`\n main += `</div></div></div>`\n\n if (e.review) main += `<div class=\"ox-card ox-sub\" style=\"border-color:var(--warn,#d97706)\">Check the type: ${esc(e.review)}</div>`\n const overview = overviewOf(e)\n const summary = overview ? \"\" : summaryOf(e)\n if ((overview || summary) && lens[0]?.panel !== \"notes\") {\n const lead = overview ? `<div class=\"ox-summary ox-prose\">${wikiMd(g, overview)}</div>` : `<p class=\"ox-summary\">${esc(summary)}</p>`\n main += `<section class=\"ox-card\">${lead}<div class=\"ox-meta\"><span>updated ${esc(e.updated || \"—\")}</span><span>sources: ${e.sources.length}</span><span>${e.statements.length} statements</span></div></section>`\n }\n main += `<div class=\"ox-grid2\">`\n for (const def of lens) {\n const data = panelData(g, e, def, { full: false, readEntries: ctx.readEntries })\n const isNotes = panelSource(def) === \"notes\"\n main += panelCard(g, e, data, false, isNotes ? notesHtml(g, e, false) : \"\")\n }\n main += `</div>`\n return layout(e.title, sidebar(g, { pillar: e.pillar, entity: e.id }), main, rail(g, e, lens))\n}\n\n/** Z3: one panel in full, paginated. */\nexport function panelPage(ctx: EntityViewCtx, e: Entity, panelId: string, page: number): string | null {\n const { g } = ctx\n const def = lensFor(g, e.type).find(p => p.panel === panelId)\n if (!def) return null\n const data = panelData(g, e, def, { full: true, page, pageSize: 50, readEntries: ctx.readEntries })\n const title = def.title ?? def.panel\n let main = `<div class=\"ox-bar\">${entityCrumbs(g, e, [{ label: title }])}${zoomBar(3)}</div>`\n main += `<div class=\"ox-head\"><div class=\"ox-avatar\">${typeIcon(g.ontology, e.type)}</div><div><h1>${esc(title)}</h1><p>${esc(e.title)} · ${data.total} item${data.total === 1 ? \"\" : \"s\"}</p></div></div>`\n const isNotes = panelSource(def) === \"notes\"\n main += panelCard(g, e, data, true, isNotes ? notesHtml(g, e, true) : \"\")\n const pages = Math.ceil(data.total / 50)\n if (pages > 1) {\n const base = `${entityHref(e.id)}/${encodeURIComponent(panelId)}`\n main += `<div class=\"ox-pager\">${page > 1 ? `<a href=\"${base}?page=${page - 1}\">← newer</a>` : \"\"}<span>page ${page} of ${pages}</span>${page < pages ? `<a href=\"${base}?page=${page + 1}\">older →</a>` : \"\"}</div>`\n }\n return layout(`${title} · ${e.title}`, sidebar(g, { pillar: e.pillar, entity: e.id }), main)\n}\n\n/** Z4: one statement with where it comes from. */\nexport function statementPage(ctx: EntityViewCtx, e: Entity, index: number): string | null {\n const { g } = ctx\n const st = e.statements[index]\n if (!st) return null\n const prop = g.ontology.properties.find(p => p.id === st.property)\n const target = st.target ? g.entities.get(st.target) : undefined\n const meta = st.page.article.meta\n const rows: Array<[string, string]> = [\n [\"Subject\", `<a href=\"${entityHref(e.id)}\">${esc(e.title)}</a>`],\n [\"Property\", `${esc(prop?.label ?? st.property)}${prop?.wikidata ? ` <span class=\"ox-sub\">wikidata ${esc(prop.wikidata)}</span>` : \"\"}`],\n [\"Value\", target ? `<a href=\"${entityHref(target.id)}\">${esc(target.title)}</a>` : esc(st.value)],\n ]\n if (st.role) rows.push([\"Role\", esc(st.role)])\n if (st.metric) rows.push([\"Metric\", esc(st.metric)])\n if (st.since || st.until) rows.push([\"True\", `${esc(st.since ?? \"…\")} → ${esc(st.until ?? \"now\")}`])\n if (st.at) rows.push([\"Measured\", esc(st.at)])\n rows.push([\"Recorded\", esc(meta.lastUpdated || meta.created || \"—\")])\n rows.push([\"Source\", esc(st.source ?? (meta.sources.length ? `${meta.sources.length} conversation entries` : \"not given\"))])\n rows.push([\"Written by\", `${esc(st.page.agentId)} · <a href=\"/agent/${encodeURIComponent(st.page.agentId)}/article/${encodeURIComponent(st.page.article.path)}\">${esc(st.page.article.path)}</a>`])\n rows.push([\"Status\", st.status ? `<span class=\"ox-st ${esc(st.status)}\">${esc(st.status)}</span>` : \"not set\"])\n if (st.confirmed_by) rows.push([\"Confirmed by\", esc(st.confirmed_by)])\n if (st.checked_at) rows.push([\"Checked\", esc(st.checked_at)])\n rows.push([\"Access\", esc(st.access ?? meta.access)])\n if (st.note) rows.push([\"Note\", esc(st.note)])\n const versions = ctx.versions(st.page.agentId, st.page.article.path)\n rows.push([\"Past versions\", versions.length ? versions.slice(0, 8).map(v => esc(v.timestamp)).join(\"<br>\") : \"none saved\"])\n\n let main = `<div class=\"ox-bar\">${entityCrumbs(g, e, [{ label: prop?.label ?? st.property }])}${zoomBar(4)}</div>`\n main += `<div class=\"ox-head\"><div class=\"ox-avatar\">${icon(\"key\")}</div><div><h1>${esc(prop?.label ?? st.property)}</h1><p>${esc(e.title)} → ${esc(target?.title ?? st.value)}</p></div></div>`\n main += `<section class=\"ox-card\">${rows.map(([k, v]) => `<div class=\"ox-kv\"><span class=\"k\">${k}</span><span>${v}</span></div>`).join(\"\")}</section>`\n return layout(`${prop?.label ?? st.property} · ${e.title}`, sidebar(g, { pillar: e.pillar, entity: e.id }), main)\n}\n"],"mappings":"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","names":["lensFor","g","type","t","propLabel","id","inverse","p","x","byRecent","a","b","da","db","statementItem","e","st","from","other","chips","statementsPanel","def","panelFrom","types","items","seen","keep","edge","typed","i","plain","linkedEntities","ids","out","entityItem","historyPanel","events","shownLevels","shown","folded","rollups","rule","newest","recent","readingsPanel","latestOnly","readings","metric","discussedPanel","readEntries","en","line","l","panelData","opts","source","panelSource","h","total","size","page","esc","s","PATHS","icon","name","typeIcon","type","t","typeLabel","entityHref","id","crumbs","list","c","i","all","zoomBar","at","names","z","sidebar","g","active","o","html","pins","title","normName","e","p","layout","side","main","rail","q","CSS","today","statusChip","s","esc","itemTitle","it","icon","entityHref","itemSub","g","parts","typeLabel","rowHtml","e","sub","chips","c","z4","typeIcon","eventRow","level","timeline","items","years","i","d","now","min","span","pos","end","y","m","html","left","right","label","panelCard","p","full","notesHtml","zin","count","note","body","r","wikiMd","g","text","markdownToHtml","target","display","id","normName","entityHref","bodyOf","content","OVERVIEW_HEADING","OVERVIEW_END","overviewSpan","body","m","textStart","rest","marker","heading","cut","i","end","after","overviewSection","span","overviewOf","e","pages","a","b","p","cutAtSentence","max","head","s","summaryOf","plain","_m","t","d","pillarOf","entityCrumbs","tail","crumbs","typeLabel","notesHtml","full","first","short","esc","rail","lens","x","html","icon","panelSource","byAgent","agent","n","page","entityPage","ctx","lensFor","pinned","main","zoomBar","typeIcon","overview","summary","lead","def","data","panelData","isNotes","panelCard","layout","sidebar","panelPage","panelId","title","base","statementPage","index","st","prop","meta","rows","versions","v","k"]}
@@ -1,7 +1,7 @@
1
- import{f as j,i as x,p as O,r as I}from"./chunk-S2GAEH2F.js";import{a as R}from"./chunk-JXF54PT7.js";import{oa as S,ua as L}from"./chunk-EOLEKSN6.js";L();import{Command as z}from"commander";import f from"chalk";import{execFileSync as h}from"child_process";import{accessSync as T,constants as H,existsSync as y,readFileSync as b,readdirSync as $,statSync as X}from"fs";import{join as E,resolve as m}from"path";import{homedir as B}from"os";import{createRequire as F}from"module";import{execFile as M}from"child_process";var q=(t,n)=>new Promise(e=>{try{M(t,n,{timeout:5e3},(i,s)=>e(i?null:String(s)))}catch{e(null)}}),N="Open System Settings \u203A Notifications \u203A AgentX Helper, turn on Allow notifications and choose Banners.";async function P(t={}){if((t.platform??process.platform)!=="darwin")return{state:"unsupported",message:"Desktop banners are only shown on a Mac."};let n=t.helper===void 0?I():t.helper;if(!n)return{state:"missing",message:"AgentX Helper is not installed, so banners come from Script Editor and show its icon.",fix:'Run agentx desktop install, then run agentx notify "Hello" --title "Test" and click Allow.'};let e=await(t.run??q)(n,["notify-status"]),i=null;try{i=e?JSON.parse(e):null}catch{i=null}return i?i.authorization==="notDetermined"?{state:"not-asked",path:n,message:"macOS has not asked yet whether AgentX Helper may notify; banners show the Script Editor icon until it does.",fix:'Run agentx notify "Hello" --title "Test" and click Allow when macOS asks.'}:i.authorization==="denied"?{state:"not-allowed",path:n,message:"macOS does not allow AgentX Helper to notify, so banners show the Script Editor icon.",fix:N}:i.alertStyle==="none"?{state:"hidden",path:n,message:"AgentX Helper may notify, but its banner style is None, so nothing appears on screen.",fix:N}:{state:"ready",path:n,message:"AgentX Helper posts banners with the AgentX icon."}:{state:"outdated",path:n,message:"AgentX Helper is too old to report whether it may notify.",fix:"Run agentx desktop install to update it."}}async function J(t={}){let n=[];await Z(n),U(n);let e=K(n);return e&&Q(n,e),e&&Y(n,e),e&&ee(n,e),e&&te(n,e),e&&oe(n,e),e&&await G(n,e),e&&V(n,e),t.running!==!1&&e&&await ie(n,e),{checks:n,summary:W(n)}}var ke=new z().name("doctor").description("pre-flight health check: Node, config, credentials, daemon").option("--no-running","skip the live daemon probe").option("--json","emit machine-readable JSON (stable shape for CI)").action(async t=>{let{checks:n,summary:e}=await J({running:t.running!==!1});t.json?process.stdout.write(JSON.stringify({checks:n,summary:e},null,2)+`
1
+ import{f as j,i as x,p as O,r as I}from"./chunk-S2GAEH2F.js";import{a as R}from"./chunk-JXF54PT7.js";import{oa as S,wa as L}from"./chunk-CBFBGN7J.js";L();import{Command as z}from"commander";import f from"chalk";import{execFileSync as h}from"child_process";import{accessSync as T,constants as H,existsSync as y,readFileSync as b,readdirSync as $,statSync as X}from"fs";import{join as E,resolve as m}from"path";import{homedir as B}from"os";import{createRequire as F}from"module";import{execFile as M}from"child_process";var q=(t,n)=>new Promise(e=>{try{M(t,n,{timeout:5e3},(i,s)=>e(i?null:String(s)))}catch{e(null)}}),N="Open System Settings \u203A Notifications \u203A AgentX Helper, turn on Allow notifications and choose Banners.";async function P(t={}){if((t.platform??process.platform)!=="darwin")return{state:"unsupported",message:"Desktop banners are only shown on a Mac."};let n=t.helper===void 0?I():t.helper;if(!n)return{state:"missing",message:"AgentX Helper is not installed, so banners come from Script Editor and show its icon.",fix:'Run agentx desktop install, then run agentx notify "Hello" --title "Test" and click Allow.'};let e=await(t.run??q)(n,["notify-status"]),i=null;try{i=e?JSON.parse(e):null}catch{i=null}return i?i.authorization==="notDetermined"?{state:"not-asked",path:n,message:"macOS has not asked yet whether AgentX Helper may notify; banners show the Script Editor icon until it does.",fix:'Run agentx notify "Hello" --title "Test" and click Allow when macOS asks.'}:i.authorization==="denied"?{state:"not-allowed",path:n,message:"macOS does not allow AgentX Helper to notify, so banners show the Script Editor icon.",fix:N}:i.alertStyle==="none"?{state:"hidden",path:n,message:"AgentX Helper may notify, but its banner style is None, so nothing appears on screen.",fix:N}:{state:"ready",path:n,message:"AgentX Helper posts banners with the AgentX icon."}:{state:"outdated",path:n,message:"AgentX Helper is too old to report whether it may notify.",fix:"Run agentx desktop install to update it."}}async function J(t={}){let n=[];await Z(n),U(n);let e=K(n);return e&&Q(n,e),e&&Y(n,e),e&&ee(n,e),e&&te(n,e),e&&oe(n,e),e&&await G(n,e),e&&V(n,e),t.running!==!1&&e&&await ie(n,e),{checks:n,summary:W(n)}}var ke=new z().name("doctor").description("pre-flight health check: Node, config, credentials, daemon").option("--no-running","skip the live daemon probe").option("--json","emit machine-readable JSON (stable shape for CI)").action(async t=>{let{checks:n,summary:e}=await J({running:t.running!==!1});t.json?process.stdout.write(JSON.stringify({checks:n,summary:e},null,2)+`
2
2
  `):se(n),process.exit(e.errors>0?1:0)});async function G(t,n,e=P){if(!O(n.notifications?.local).banner)return;let i=await e();i.state!=="unsupported"&&t.push({severity:i.state==="ready"?"ok":"warn",group:"Notifications",title:i.message,detail:i.path,fix:i.fix})}function V(t,n,e=process.platform,i=s=>{try{return T(s,H.X_OK),!0}catch{return!1}}){let s=n.reminders;if(!s?.enabled)return;if(e!=="darwin"){t.push({severity:"warn",group:"Reminders",title:"Reminders hand-back unavailable on this machine",detail:"reminders.enabled is set, but Apple Reminders exists only on macOS. The daemon starts without it.",fix:"Set reminders.enabled to false here, or enable it on the Mac node instead."});return}let r=s.command||"remindctl",a=r.includes("/")?i(r)?r:null:x(r,process.env.PATH||"",i);t.push(a?{severity:"ok",group:"Reminders",title:`Watching ${(s.lists||[]).join(", ")} for due reminders`,detail:a}:{severity:"fail",group:"Reminders",title:`${r} not found`,detail:"The daemon reads Apple Reminders through remindctl.",fix:"brew install steipete/tap/remindctl, or set reminders.command to its full path."})}async function Z(t){let n=R(process.versions.node);t.push({severity:n?"ok":"fail",group:"Environment",title:`Node.js ${process.versions.node}`,detail:n?void 0:"AgentX requires Node 22.19 or newer, up to Node 26.",fix:n?void 0:"Install Node 22 (nvm install 22 && nvm use 22)"});let e=l=>{try{return h(process.platform==="win32"?"where":"which",[l],{encoding:"utf-8"}).trim().split(`
3
3
  `)[0]}catch{return null}},i=e("npm");t.push({severity:i?"ok":"fail",group:"Environment",title:i?"npm on PATH":"npm not found",detail:i||void 0});let s=e("claude");if(s){let l;try{l=h("claude",["--version"],{encoding:"utf-8",timeout:3e3}).trim()}catch{}t.push({severity:"ok",group:"Environment",title:`claude CLI ${l||"installed"}`,detail:s})}else t.push({severity:"warn",group:"Environment",title:"claude CLI not on PATH",detail:"Only required for agents on the claude-code tier.",fix:"See https://docs.anthropic.com/en/docs/claude-code"});let r=e("codex");if(r){let l;try{l=h("codex",["--version"],{encoding:"utf-8",timeout:3e3}).trim()}catch{}t.push({severity:"ok",group:"Environment",title:`codex CLI ${l||"installed"}`,detail:r})}else t.push({severity:"warn",group:"Environment",title:"codex CLI not on PATH",detail:"Only required for agents on the codex-cli tier.",fix:"Install with `npm i -g @openai/codex`."});let a=e("opencode");if(a){let l;try{l=h("opencode",["--version"],{encoding:"utf-8",timeout:3e3}).trim()}catch{}t.push({severity:"ok",group:"Environment",title:`opencode CLI ${l||"installed"}`,detail:a})}else t.push({severity:"warn",group:"Environment",title:"opencode CLI not on PATH",detail:"Only required for agents on the opencode tier.",fix:"Install from https://opencode.ai/docs/."});try{F(import.meta.url)("better-sqlite3"),t.push({severity:"ok",group:"Environment",title:`better-sqlite3 loads for Node ${process.version}`,detail:`NODE_MODULE_VERSION ${process.versions.modules}`})}catch(l){t.push({severity:"fail",group:"Environment",title:"better-sqlite3 native binding does not load",detail:l?.message??String(l),fix:`Run "pnpm rebuild better-sqlite3" with the same Node used by the daemon (${process.version}, modules ${process.versions.modules}).`})}}function U(t){if(process.platform!=="darwin")return;let n=E(B(),"Library/LaunchAgents"),e=[];try{e=$(n).filter(s=>/agentx\.voice.*\.plist$/.test(s))}catch{return}let i=s=>{try{return T(s,H.X_OK),!0}catch{return!1}};for(let s of e){let r=j(b(E(n,s),"utf-8")),a=x("ffmpeg",r,i);t.push(a?{severity:"ok",group:"Desktop",title:"ffmpeg reachable by the desktop app",detail:`${a} (${s})`}:{severity:"warn",group:"Desktop",title:"ffmpeg not reachable by the desktop app",detail:`Local Whisper transcription fails without it. ${s} sets PATH to ${r}.`,fix:"Install ffmpeg (brew install ffmpeg), then rerun agentx desktop install."})}}function K(t){let n=m(process.cwd(),"agentx.json");if(!y(n))return t.push({severity:"fail",group:"Config",title:"agentx.json not found",detail:`Looked in ${n}`,fix:"Run `agentx setup` to create one via the web wizard."}),null;let e;try{e=JSON.parse(b(n,"utf-8"))}catch(a){return t.push({severity:"fail",group:"Config",title:"agentx.json is not valid JSON",detail:a.message}),null}try{S(n),t.push({severity:"ok",group:"Config",title:`agentx.json valid (${Object.keys(e.agents||{}).length} agents, ${Object.keys(e.crons||{}).length} schedules)`})}catch(a){t.push({severity:"fail",group:"Config",title:"agentx.json failed schema validation",detail:a.message,fix:"Open /admin \u2192 Advanced tab to edit and re-save."})}let i=Object.entries(e.agents||{}).filter(([,a])=>a.tier==="claude-code");i.length>0&&((()=>{try{return h(process.platform==="win32"?"where":"which",["claude"],{stdio:"ignore"}),!0}catch{return!1}})()||t.push({severity:"fail",group:"Config",title:`${i.length} agent(s) use claude-code tier but claude CLI is missing`,detail:i.map(([l])=>l).join(", "),fix:"Install Claude Code (https://docs.anthropic.com/en/docs/claude-code) or switch these agents to tier=sdk."}));let s=Object.entries(e.agents||{}).filter(([,a])=>a.tier==="codex-cli");s.length>0&&((()=>{try{return h(process.platform==="win32"?"where":"which",["codex"],{stdio:"ignore"}),!0}catch{return!1}})()||t.push({severity:"fail",group:"Config",title:`${s.length} agent(s) use codex-cli tier but codex CLI is missing`,detail:s.map(([l])=>l).join(", "),fix:"Install Codex CLI with `npm i -g @openai/codex` or switch these agents to tier=claude-code."}));let r=Object.entries(e.agents||{}).filter(([,a])=>a.tier==="opencode");return r.length>0&&((()=>{try{return h(process.platform==="win32"?"where":"which",["opencode"],{stdio:"ignore"}),!0}catch{return!1}})()||t.push({severity:"fail",group:"Config",title:`${r.length} agent(s) use opencode tier but OpenCode CLI is missing`,detail:r.map(([l])=>l).join(", "),fix:"Install OpenCode from https://opencode.ai/docs/ or switch these agents to another tier."})),e}function Q(t,n){let e=new Set;if(C(n,e),e.size===0){t.push({severity:"ok",group:"Secrets",title:"No ${VAR} references in agentx.json"});return}let i=m(process.cwd(),".env"),s={};if(y(i))for(let l of b(i,"utf-8").split(/\r?\n/)){let u=l.match(/^\s*([A-Z_][A-Z0-9_]*)\s*=\s*(.*)$/i);u&&(s[u[1]]=u[2])}let r=[],a=[];for(let l of e){let u=process.env[l]??s[l];u===void 0?r.push(l):(!u.trim()||/^["']?\s*["']?$/.test(u))&&a.push(l)}r.length===0&&a.length===0?t.push({severity:"ok",group:"Secrets",title:`${e.size} env reference(s) resolved`}):(r.length>0&&t.push({severity:"fail",group:"Secrets",title:`${r.length} env var(s) referenced in agentx.json but missing`,detail:r.join(", "),fix:`Add to .env \u2014 e.g. ${r[0]}=<value>`}),a.length>0&&t.push({severity:"warn",group:"Secrets",title:`${a.length} env var(s) set but empty`,detail:a.join(", ")}))}function C(t,n){if(typeof t=="string")for(let e of t.matchAll(/\$\{([A-Z_][A-Z0-9_]*)\}/g))n.add(e[1]);else if(Array.isArray(t))for(let e of t)C(e,n);else if(t&&typeof t=="object")for(let e of Object.values(t))C(e,n)}function Y(t,n){let e=[];for(let[i,s]of Object.entries(n.agents||{})){if(!s.workspace)continue;let r=s.workspace.startsWith("/")?s.workspace:m(process.cwd(),s.workspace);try{X(r).isDirectory()||e.push(`${i}: ${r} (exists but not a directory)`)}catch{e.push(`${i}: ${r}`)}}e.length===0?t.push({severity:"ok",group:"Workspaces",title:"All agent workspace folders exist"}):t.push({severity:"warn",group:"Workspaces",title:`${e.length} agent workspace(s) missing`,detail:e.join(`
4
4
  `),fix:"The daemon will create missing folders on first task, but you won't see CLAUDE.md / skills until you populate them."})}function ee(t,n){let e=/\$\{[A-Za-z_][A-Za-z0-9_]*\}/g,i=[];for(let[s,r]of Object.entries(n.agents||{})){if(!r.workspace)continue;let a=r.workspace.startsWith("/")?r.workspace:m(process.cwd(),r.workspace);for(let l of["settings.json","settings.local.json"]){let u=m(a,".claude",l);if(!y(u))continue;let w;try{w=JSON.parse(b(u,"utf-8"))}catch(d){i.push({severity:"fail",agent:s,msg:`${l}: JSON parse error \u2014 ${d.message}`});continue}let k=w.env||{};for(let[d,p]of Object.entries(k)){if(typeof p!="string")continue;let g=p.match(e);g&&i.push({severity:"fail",agent:s,msg:`${l} env.${d} contains unexpanded ${[...new Set(g)].join(",")} \u2014 Claude Code does NOT expand \${VAR} in settings.json (use a fully-literal value)`})}let o=k.PATH;if(typeof o=="string"){let d=o.split(":").filter(Boolean);d.includes("/usr/bin")||i.push({severity:"fail",agent:s,msg:`${l} env.PATH missing /usr/bin \u2014 cat/head/sh/which will fail`}),d.includes("/bin")||i.push({severity:"fail",agent:s,msg:`${l} env.PATH missing /bin \u2014 ls/cp/mv will fail`})}let c=w.permissions;if(c&&typeof c=="object"&&"allow"in c){let d=c.allow,p=c.deny;Array.isArray(d)&&d.length===0&&Array.isArray(p)&&p.length>0&&i.push({severity:"warn",agent:s,msg:`${l} permissions.allow is explicitly [] with ${p.length} deny rules \u2014 agent may be locked out (omit the key to use defaults instead)`})}}}if(i.length===0){t.push({severity:"ok",group:"Workspace settings",title:`All ${Object.keys(n.agents||{}).length} agent .claude/settings.json files clean`});return}for(let s of i)t.push({severity:s.severity,group:"Workspace settings",title:`${s.agent}: ${s.msg}`,fix:s.severity==="fail"?"Edit .claude/settings.json \u2014 replace ${VAR} with the literal value or omit the key to inherit.":"Either remove the empty allow list or populate it."})}function te(t,n){let e=n.webhooks??[],i=[],s=m(process.cwd(),n.workflows?.dir||".agentx/workflows"),r=new Set;try{if(y(s))for(let o of $(s))o.endsWith(".json")&&!o.startsWith("_")&&!o.endsWith(".disabled.json")&&r.add(o.replace(/\.json$/,""))}catch{}let a=new Set(["github","gitlab"]);for(let o of e){if(!o.enabled||!a.has(o.source))continue;!(o.triggers&&Object.keys(o.triggers).length>0)&&!o.defaultWorkflow&&i.push({severity:"warn",title:`webhook "${o.id}" (${o.source} -> ${o.agentId}) has no triggers map; every event-type collapses to the bound agent`,fix:'Add a triggers map: { "issues.opened": "wf-id", "pull_request.synchronize": "wf-id" } \u2014 or set defaultWorkflow.'})}for(let o of e)if(!(!o.enabled||!o.triggers)){for(let[c,d]of Object.entries(o.triggers))r.size>0&&!r.has(d)&&i.push({severity:"fail",title:`webhook "${o.id}".triggers["${c}"] -> "${d}" \u2014 no such workflow under ${n.workflows?.dir||".agentx/workflows"}`,fix:"Create the workflow file or fix the id in agentx.json"});o.defaultWorkflow&&r.size>0&&!r.has(o.defaultWorkflow)&&i.push({severity:"fail",title:`webhook "${o.id}".defaultWorkflow -> "${o.defaultWorkflow}" \u2014 no such workflow`,fix:"Create the workflow file or fix the id in agentx.json"})}try{if(y(s)){for(let o of $(s))if(!(!o.endsWith(".json")||o.startsWith("_")||o.endsWith(".disabled.json")))try{let c=JSON.parse(b(m(s,o),"utf-8"));c?.status==="active"&&c?.state==="quarantined"&&i.push({severity:"warn",title:`workflow "${c.id??o}" is status=active but state=quarantined \u2014 it looks live but will never dispatch`,fix:'Resolve the conflict the detector flagged, then set state back to "active" (or set status to "review" while parked).'})}catch{}}}catch{}let l=new Set((n.mesh?.peers??[]).map(o=>o.name));for(let o of e)!o.enabled||!o.node||l.has(o.node)||i.push({severity:"fail",title:`webhook "${o.id}" routes to mesh peer "${o.node}" which is not in mesh.peers`,fix:"Add the peer to mesh.peers or remove the node field on the webhook."});let u=new Map;for(let o of e){if(!o.enabled)continue;let c=`${o.source}:${o.agentId}`,d=u.get(c);d?i.push({severity:"warn",title:`webhook entries "${d}" and "${o.id}" both enabled for ${o.source} -> ${o.agentId}; only the first is dispatched`,fix:"Disable one entry, or merge their triggers maps into a single entry."}):u.set(c,o.id)}let w=new Set(Object.keys(n.agents??{}));for(let o of n.channels?.gitlab?.agentMappings??[])if(o?.agentId){if(o.node){l.has(o.node)||i.push({severity:"fail",title:`gitlab.agentMappings entry agentId="${o.agentId}" routes to mesh peer "${o.node}" which is not in mesh.peers`,fix:"Add the peer to mesh.peers or drop the node field on the mapping."});continue}w.has(o.agentId)||i.push({severity:"warn",title:`gitlab.agentMappings entry agentId="${o.agentId}" \u2014 no such agent in agents.* (and no node field, so it's not a cross-mesh route)`,fix:'Add the agent to agents.*, set node:"<peer>" if the agent lives remotely, or remove the mapping.'})}for(let[o,c]of Object.entries(n.channels?.telegram?.accounts??{}))c.agentBinding?w.has(c.agentBinding)||i.push({severity:"fail",title:`telegram account "${o}".agentBinding -> "${c.agentBinding}" \u2014 no such agent in agents.*`,fix:"Fix the agentBinding or define the agent in agents.*."}):i.push({severity:"fail",title:`telegram account "${o}" has no agentBinding; every DM to this bot will drop`,fix:"Set agentBinding to a valid agent id."});let k=new Set(["telegram-bot","whatsapp","slack-bot","discord-bot","gitlab-user","github-user","gmail","hotmail","smtp","hubspot","salesforce","pipedrive","odoo","trello","linear","asana","jira","notion","stripe","sentry","vercel","twilio","custom"]);for(let[o,c]of Object.entries(n.agents??{})){let d=c.integrations??[];if(!d.length)continue;let p=new Set;for(let g of d){let A=`${g.kind}::${g.label}`;p.has(A)&&i.push({severity:"warn",title:`agents.${o}.integrations: duplicate (${g.kind}, ${g.label})`,fix:"Remove the duplicate or rename one. (kind, label) must be unique per agent."}),p.add(A),k.has(g.kind)||i.push({severity:"warn",title:`agents.${o}.integrations: unknown kind "${g.kind}" on integration "${g.label}"`,fix:'Use a canonical kind from INTEGRATION_KINDS, or "custom" for ad-hoc services.'});let D=g.credentials||{};for(let[_,v]of Object.entries(D))typeof v=="string"&&/^[A-Z][A-Z0-9_]*$/.test(v)&&!process.env[v]&&i.push({severity:"warn",title:`agents.${o}.integrations[${g.kind}/${g.label}].${_} -> $${v} but env var is unset (in this shell)`,fix:`Set ${v} on the daemon environment. The daemon's process.env is what matters; this warning fires from your local shell.`})}}if(i.length===0){t.push({severity:"ok",group:"Routing",title:`${e.length} webhook(s), ${Object.keys(n.channels?.telegram?.accounts??{}).length} telegram account(s) \u2014 all routing references resolve`});return}for(let o of i)t.push({severity:o.severity,group:"Routing",title:o.title,fix:o.fix})}function ne(t){return typeof t?.canMeasure!="boolean"?null:t.canMeasure?{severity:"ok",group:"Runtime",title:"Daemon finds ffmpeg to measure phone recordings"}:{severity:"warn",group:"Runtime",title:t.allowUnmeasured?"Daemon can't find ffmpeg: phone recordings go unmeasured (voice.allowUnmeasured)":"Daemon can't find ffmpeg: phone voice input is refused",fix:"Install ffmpeg (brew install ffmpeg / sudo apt install ffmpeg), or set AGENTX_FFMPEG in the service's environment. The daemon's PATH is shorter than your shell's."}}async function ie(t,n){let e=n.dashboard?.daemonUrl?.replace(/\/+$/,"")||"http://127.0.0.1:18800",i={};n.dashboard?.token&&(i.Authorization=`Bearer ${n.dashboard.token}`);try{let s=new AbortController,r=setTimeout(()=>s.abort(),2e3),a=await fetch(e+"/health",{headers:i,signal:s.signal});if(clearTimeout(r),!a.ok){t.push({severity:"warn",group:"Runtime",title:`Daemon responded ${a.status}`,detail:e});return}let l=await a.json();t.push({severity:"ok",group:"Runtime",title:`Daemon healthy \u2014 ${l.agents?.length??0} agents live, uptime ${Math.round((l.uptime??0)/60)}m`,detail:e});let u=ne(l.voice);u&&t.push(u)}catch{t.push({severity:"warn",group:"Runtime",title:"Daemon not reachable (not running?)",detail:e,fix:"Run `agentx daemon start`. Skip this check with `agentx doctor --no-running`."})}}function oe(t,n){let e=Object.entries(n.agents||{}).filter(([,s])=>s?.codegraph===!0&&(s.tier==="claude-code"||s.tier==="codex-cli"));if(e.length===0)return;let i=null;try{i=h(process.platform==="win32"?"where":"which",["codegraph"],{encoding:"utf-8"}).trim().split(`
5
5
  `)[0]||null}catch{i=null}if(i){let s;try{s=h("codegraph",["--version"],{encoding:"utf-8",timeout:3e3}).trim()}catch{}t.push({severity:"ok",group:"CodeGraph",title:`codegraph CLI ${s||"installed"}`,detail:i})}else t.push({severity:"fail",group:"CodeGraph",title:"codegraph CLI not on PATH",detail:`${e.length} agent(s) have codegraph:true but the binary isn't available.`,fix:"Install with `npm i -g @colbymchenry/codegraph`."});for(let[s,r]of e){if(!r.workspace||!y(r.workspace)){t.push({severity:"warn",group:"CodeGraph",title:`${s}: workspace missing`,detail:`Workspace path ${r.workspace} does not exist \u2014 codegraph will skip this agent.`});continue}let a=m(r.workspace,".codegraph","codegraph.db");y(a)?t.push({severity:"ok",group:"CodeGraph",title:`${s}: index present`,detail:a}):t.push({severity:"warn",group:"CodeGraph",title:`${s}: index not built yet`,detail:".codegraph/ missing \u2014 daemon will background-index this workspace on next boot.",fix:`Run \`codegraph init --index ${r.workspace}\` to build it now.`})}}function W(t){return{errors:t.filter(n=>n.severity==="fail").length,warnings:t.filter(n=>n.severity==="warn").length,ok:t.filter(n=>n.severity==="ok").length}}function se(t){console.log(),console.log(f.bold(" agentx doctor")),console.log();let n=new Map;for(let i of t)n.has(i.group)||n.set(i.group,[]),n.get(i.group).push(i);for(let[i,s]of n){console.log(f.bold(" "+i));for(let r of s){let a=r.severity==="ok"?f.green("\u2713"):r.severity==="warn"?f.yellow("!"):f.red("\u2717");console.log(` ${a} ${r.title}`),r.detail&&console.log(f.dim(" "+r.detail.replace(/\n/g,`
6
6
  `))),r.fix&&console.log(f.dim(" \u2192 "+r.fix))}console.log()}let e=W(t);e.errors>0?console.log(f.red.bold(` ${e.errors} error${e.errors===1?"":"s"}`)+(e.warnings?f.yellow(`, ${e.warnings} warning${e.warnings===1?"":"s"}`):"")+`. Fix the error${e.errors===1?"":"s"} and rerun.`):e.warnings>0?console.log(f.yellow.bold(` ${e.warnings} warning${e.warnings===1?"":"s"}.`)+f.dim(" Review but not blocking.")):console.log(f.green.bold(` All checks passed (${e.ok}).`)),console.log()}export{P as a,J as b,ke as c,G as d,V as e,ne as f};
7
- //# sourceMappingURL=chunk-SCC7HBFZ.js.map
7
+ //# sourceMappingURL=chunk-MFIM5Y3J.js.map
@@ -0,0 +1,2 @@
1
+ import{existsSync as P,unlinkSync as W}from"fs";import{isAbsolute as b,relative as x,resolve as g}from"path";async function I(i,t,n){let s=await fetch(`${i.url.replace(/\/$/,"")}${t}`,{headers:i.token?{Authorization:`Bearer ${i.token}`}:{},signal:AbortSignal.timeout(n)});if(!s.ok)throw new Error(`HTTP ${s.status} for ${t}`);return s.json()}var R=/^[A-Za-z0-9][A-Za-z0-9_.-]*$/;function S(i,t){if(typeof t!="string"||!t.endsWith(".md")||b(t)||t.includes("\\")||t.startsWith("_")||t.startsWith("raw/")||t.split("/").some(s=>s===".."||s==="."||s===""))return!1;let n=x(i,g(i,t));return!!n&&!n.startsWith("..")&&!b(n)}async function v(i){let{hub:t,peer:n,localAgents:s,dryRun:u=!1}=i,p=i.fetchJson??I,f=await p(n,"/wiki/agents",12e4),h=String(f?.nodeId||"unknown"),m=[];for(let y of f?.agents??[]){let o=String(y?.agentId??"");if(!(y?.totalArticles>0))continue;let r={agentId:o,copied:0,unchanged:0,removed:0,rejected:0};if(m.push(r),!R.test(o)){r.skipped="bad-id";continue}if(s.has(o)){r.skipped="local";continue}try{let l=await p(n,`/wiki/articles?agent=${encodeURIComponent(o)}`,3e4);if(!Array.isArray(l?.articles))throw new Error("article list missing from the peer's answer");let d=l.articles,k=g(t.getBaseDir(),"agents",o,t.getMode());if(u&&!P(k)){r.copied=d.filter(e=>S(k,e.path)).length,r.rejected=d.length-r.copied;continue}let c=t.getAgentWiki(o);for(let e of d){if(!S(c.baseDir,e.path)){r.rejected++;continue}let a=c.readArticle(e.path);if(a&&e.lastUpdated&&a.meta.lastUpdated===e.lastUpdated){r.unchanged++;continue}if(u){r.copied++;continue}let w=await p(n,`/wiki/article?agent=${encodeURIComponent(o)}&path=${encodeURIComponent(e.path)}`,15e3),A=e.owner||o;c.writeArticle(e.path,{title:e.title,type:e.type,related:e.related,tags:e.tags??[],owner:A,access:e.access??"private",sharedWith:e.sharedWith,created:String(w?.created??""),lastUpdated:e.lastUpdated??"",sources:e.sources??[],graphPath:e.graphPath},String(w?.content??""),a?.meta.owner??A)?r.copied++:r.rejected++}if(!u){let e=new Set(d.map(a=>a.path));for(let a of c.rebuildIndex().articles)e.has(a.path)||(W(g(c.baseDir,a.path)),r.removed++);c.rebuildIndex(),t.markSynced(o,{node:h,peerUrl:n.url,at:new Date().toISOString()})}}catch(l){r.error=l.message}}return{node:h,agents:m}}export{I as a,S as b,v as c};
2
+ //# sourceMappingURL=chunk-MRIVENBY.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/wiki/article-sync.ts"],"sourcesContent":["import { existsSync, unlinkSync } from \"fs\"\nimport { isAbsolute, relative, resolve } from \"path\"\nimport type { WikiHub } from \"./hub\"\nimport type { WikiIndex } from \"./types\"\n\n/** A mesh peer's daemon, with the token its /wiki/* routes ask for. */\nexport interface WikiPeer {\n url: string\n token?: string\n}\n\nexport type PeerFetch = (peer: WikiPeer, path: string, timeoutMs: number) => Promise<any>\n\nexport async function fetchPeerJson(peer: WikiPeer, path: string, timeoutMs: number): Promise<any> {\n const res = await fetch(`${peer.url.replace(/\\/$/, \"\")}${path}`, {\n headers: peer.token ? { Authorization: `Bearer ${peer.token}` } : {},\n signal: AbortSignal.timeout(timeoutMs),\n })\n if (!res.ok) throw new Error(`HTTP ${res.status} for ${path}`)\n return res.json()\n}\n\nexport interface AgentSyncResult {\n agentId: string\n copied: number\n unchanged: number\n /** Local copies of articles the peer no longer has, deleted (not counted on a dry run). */\n removed: number\n /** Articles refused for an unsafe path, or that the store would not write. */\n rejected: number\n /** Why the agent was not copied at all. */\n skipped?: \"local\" | \"bad-id\"\n error?: string\n}\n\nexport interface ArticleSyncResult {\n node: string\n agents: AgentSyncResult[]\n}\n\n// One path segment, no dots in front: rules out \"..\", \"/\" and \"_shared\".\nconst AGENT_ID = /^[A-Za-z0-9][A-Za-z0-9_.-]*$/\n\n/** An article path from a peer is only written when it stays an ordinary\n * article inside the agent's folder: not a sidecar, raw entry or escape. */\nexport function isSafeArticlePath(baseDir: string, path: unknown): path is string {\n if (typeof path !== \"string\" || !path.endsWith(\".md\") || isAbsolute(path) || path.includes(\"\\\\\")) return false\n if (path.startsWith(\"_\") || path.startsWith(\"raw/\")) return false\n if (path.split(\"/\").some((seg) => seg === \"..\" || seg === \".\" || seg === \"\")) return false\n const rel = relative(baseDir, resolve(baseDir, path))\n return !!rel && !rel.startsWith(\"..\") && !isAbsolute(rel)\n}\n\n/**\n * Copy a peer's per-agent articles into this node's wiki, for every agent\n * this node does not run itself. Copied agents are marked read-only (see\n * WikiHub.syncedFrom): their home node absorbs them, this node only reads.\n * An article whose last_updated matches the local copy is not fetched again.\n */\nexport async function syncPeerArticles(opts: {\n hub: WikiHub\n peer: WikiPeer\n localAgents: Set<string>\n dryRun?: boolean\n fetchJson?: PeerFetch\n}): Promise<ArticleSyncResult> {\n const { hub, peer, localAgents, dryRun = false } = opts\n const fetchJson = opts.fetchJson ?? fetchPeerJson\n\n // The peer counts every agent's entries for this list; that has taken\n // over a minute on a large wiki.\n const summary = await fetchJson(peer, \"/wiki/agents\", 120_000)\n const node = String(summary?.nodeId || \"unknown\")\n const results: AgentSyncResult[] = []\n\n for (const remote of summary?.agents ?? []) {\n const agentId = String(remote?.agentId ?? \"\")\n if (!(remote?.totalArticles > 0)) continue\n const result: AgentSyncResult = { agentId, copied: 0, unchanged: 0, removed: 0, rejected: 0 }\n results.push(result)\n if (!AGENT_ID.test(agentId)) { result.skipped = \"bad-id\"; continue }\n // This node's own agents are absorbed here; a peer's copy never wins.\n if (localAgents.has(agentId)) { result.skipped = \"local\"; continue }\n\n try {\n const listed = await fetchJson(peer, `/wiki/articles?agent=${encodeURIComponent(agentId)}`, 30_000)\n // A malformed list must not read as \"no articles\": that would delete\n // every local copy below.\n if (!Array.isArray(listed?.articles)) throw new Error(\"article list missing from the peer's answer\")\n const articles: WikiIndex[\"articles\"] = listed.articles\n // Opening a store creates its folder; a dry run must not.\n const agentDir = resolve(hub.getBaseDir(), \"agents\", agentId, hub.getMode())\n if (dryRun && !existsSync(agentDir)) {\n result.copied = articles.filter((a) => isSafeArticlePath(agentDir, a.path)).length\n result.rejected = articles.length - result.copied\n continue\n }\n const store = hub.getAgentWiki(agentId)\n\n for (const a of articles) {\n if (!isSafeArticlePath(store.baseDir, a.path)) { result.rejected++; continue }\n const existing = store.readArticle(a.path)\n if (existing && a.lastUpdated && existing.meta.lastUpdated === a.lastUpdated) {\n result.unchanged++\n continue\n }\n if (dryRun) { result.copied++; continue }\n\n const body = await fetchJson(\n peer,\n `/wiki/article?agent=${encodeURIComponent(agentId)}&path=${encodeURIComponent(a.path)}`,\n 15_000,\n )\n // The list carries access, type, links and graph path; the article\n // route carries the body and creation date.\n const owner = a.owner || agentId\n const written = store.writeArticle(a.path, {\n title: a.title,\n type: a.type,\n related: a.related,\n tags: a.tags ?? [],\n owner,\n access: a.access ?? \"private\",\n sharedWith: a.sharedWith,\n created: String(body?.created ?? \"\"),\n lastUpdated: a.lastUpdated ?? \"\",\n sources: a.sources ?? [],\n graphPath: a.graphPath,\n }, String(body?.content ?? \"\"), existing?.meta.owner ?? owner)\n if (written) result.copied++\n else result.rejected++\n }\n\n if (!dryRun) {\n // The peer's absorb renames and merges articles; a copy it no longer\n // lists would otherwise answer queries here for good.\n const remotePaths = new Set(articles.map((a) => a.path))\n for (const local of store.rebuildIndex().articles) {\n if (remotePaths.has(local.path)) continue\n unlinkSync(resolve(store.baseDir, local.path))\n result.removed++\n }\n store.rebuildIndex()\n hub.markSynced(agentId, { node, peerUrl: peer.url, at: new Date().toISOString() })\n }\n } catch (err) {\n result.error = (err as Error).message\n }\n }\n\n return { node, agents: results }\n}\n"],"mappings":"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","names":["existsSync","unlinkSync","isAbsolute","relative","resolve","fetchPeerJson","peer","path","timeoutMs","res","AGENT_ID","isSafeArticlePath","baseDir","seg","rel","syncPeerArticles","opts","hub","localAgents","dryRun","fetchJson","summary","node","results","remote","agentId","result","listed","articles","agentDir","a","store","existing","body","owner","remotePaths","local","err"]}
1
+ {"version":3,"sources":["../src/wiki/article-sync.ts"],"sourcesContent":["import { existsSync, unlinkSync } from \"fs\"\nimport { isAbsolute, relative, resolve } from \"path\"\nimport type { WikiHub } from \"./hub\"\nimport type { WikiIndex } from \"./types\"\n\n/** A mesh peer's daemon, with the token its /wiki/* routes ask for. */\nexport interface WikiPeer {\n url: string\n token?: string\n}\n\nexport type PeerFetch = (peer: WikiPeer, path: string, timeoutMs: number) => Promise<any>\n\nexport async function fetchPeerJson(peer: WikiPeer, path: string, timeoutMs: number): Promise<any> {\n const res = await fetch(`${peer.url.replace(/\\/$/, \"\")}${path}`, {\n headers: peer.token ? { Authorization: `Bearer ${peer.token}` } : {},\n signal: AbortSignal.timeout(timeoutMs),\n })\n if (!res.ok) throw new Error(`HTTP ${res.status} for ${path}`)\n return res.json()\n}\n\nexport interface AgentSyncResult {\n agentId: string\n copied: number\n unchanged: number\n /** Local copies of articles the peer no longer has, deleted (not counted on a dry run). */\n removed: number\n /** Articles refused for an unsafe path, or that the store would not write. */\n rejected: number\n /** Why the agent was not copied at all. */\n skipped?: \"local\" | \"bad-id\"\n error?: string\n}\n\nexport interface ArticleSyncResult {\n node: string\n agents: AgentSyncResult[]\n}\n\n// One path segment, no dots in front: rules out \"..\", \"/\" and \"_shared\".\nconst AGENT_ID = /^[A-Za-z0-9][A-Za-z0-9_.-]*$/\n\n/** An article path from a peer is only written when it stays an ordinary\n * article inside the agent's folder: not a sidecar, raw entry or escape. */\nexport function isSafeArticlePath(baseDir: string, path: unknown): path is string {\n if (typeof path !== \"string\" || !path.endsWith(\".md\") || isAbsolute(path) || path.includes(\"\\\\\")) return false\n if (path.startsWith(\"_\") || path.startsWith(\"raw/\")) return false\n if (path.split(\"/\").some((seg) => seg === \"..\" || seg === \".\" || seg === \"\")) return false\n const rel = relative(baseDir, resolve(baseDir, path))\n return !!rel && !rel.startsWith(\"..\") && !isAbsolute(rel)\n}\n\n/**\n * Copy a peer's per-agent articles into this node's wiki, for every agent\n * this node does not run itself. Copied agents are marked read-only (see\n * WikiHub.syncedFrom): their home node absorbs them, this node only reads.\n * An article whose last_updated matches the local copy is not fetched again.\n */\nexport async function syncPeerArticles(opts: {\n hub: WikiHub\n peer: WikiPeer\n localAgents: Set<string>\n dryRun?: boolean\n fetchJson?: PeerFetch\n}): Promise<ArticleSyncResult> {\n const { hub, peer, localAgents, dryRun = false } = opts\n const fetchJson = opts.fetchJson ?? fetchPeerJson\n\n // The peer counts every agent's entries for this list; that has taken\n // over a minute on a large wiki.\n const summary = await fetchJson(peer, \"/wiki/agents\", 120_000)\n const node = String(summary?.nodeId || \"unknown\")\n const results: AgentSyncResult[] = []\n\n for (const remote of summary?.agents ?? []) {\n const agentId = String(remote?.agentId ?? \"\")\n if (!(remote?.totalArticles > 0)) continue\n const result: AgentSyncResult = { agentId, copied: 0, unchanged: 0, removed: 0, rejected: 0 }\n results.push(result)\n if (!AGENT_ID.test(agentId)) { result.skipped = \"bad-id\"; continue }\n // This node's own agents are absorbed here; a peer's copy never wins.\n if (localAgents.has(agentId)) { result.skipped = \"local\"; continue }\n\n try {\n const listed = await fetchJson(peer, `/wiki/articles?agent=${encodeURIComponent(agentId)}`, 30_000)\n // A malformed list must not read as \"no articles\": that would delete\n // every local copy below.\n if (!Array.isArray(listed?.articles)) throw new Error(\"article list missing from the peer's answer\")\n const articles: WikiIndex[\"articles\"] = listed.articles\n // Opening a store creates its folder; a dry run must not.\n const agentDir = resolve(hub.getBaseDir(), \"agents\", agentId, hub.getMode())\n if (dryRun && !existsSync(agentDir)) {\n result.copied = articles.filter((a) => isSafeArticlePath(agentDir, a.path)).length\n result.rejected = articles.length - result.copied\n continue\n }\n const store = hub.getAgentWiki(agentId)\n\n for (const a of articles) {\n if (!isSafeArticlePath(store.baseDir, a.path)) { result.rejected++; continue }\n const existing = store.readArticle(a.path)\n if (existing && a.lastUpdated && existing.meta.lastUpdated === a.lastUpdated) {\n result.unchanged++\n continue\n }\n if (dryRun) { result.copied++; continue }\n\n const body = await fetchJson(\n peer,\n `/wiki/article?agent=${encodeURIComponent(agentId)}&path=${encodeURIComponent(a.path)}`,\n 15_000,\n )\n // The list carries access, type, links and graph path; the article\n // route carries the body and creation date.\n const owner = a.owner || agentId\n const written = store.writeArticle(a.path, {\n title: a.title,\n type: a.type,\n related: a.related,\n tags: a.tags ?? [],\n owner,\n access: a.access ?? \"private\",\n sharedWith: a.sharedWith,\n created: String(body?.created ?? \"\"),\n lastUpdated: a.lastUpdated ?? \"\",\n sources: a.sources ?? [],\n graphPath: a.graphPath,\n }, String(body?.content ?? \"\"), existing?.meta.owner ?? owner)\n if (written) result.copied++\n else result.rejected++\n }\n\n if (!dryRun) {\n // The peer's absorb renames and merges articles; a copy it no longer\n // lists would otherwise answer queries here for good.\n const remotePaths = new Set(articles.map((a) => a.path))\n for (const local of store.rebuildIndex().articles) {\n if (remotePaths.has(local.path)) continue\n unlinkSync(resolve(store.baseDir, local.path))\n result.removed++\n }\n store.rebuildIndex()\n hub.markSynced(agentId, { node, peerUrl: peer.url, at: new Date().toISOString() })\n }\n } catch (err) {\n result.error = (err as Error).message\n }\n }\n\n return { node, agents: results }\n}\n"],"mappings":"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","names":["existsSync","unlinkSync","isAbsolute","relative","resolve","fetchPeerJson","peer","path","timeoutMs","res","AGENT_ID","isSafeArticlePath","baseDir","seg","rel","syncPeerArticles","opts","hub","localAgents","dryRun","fetchJson","summary","node","results","remote","agentId","result","listed","articles","agentDir","a","store","existing","body","owner","remotePaths","local","err"]}