excaliagent 0.2.0 → 0.4.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 (168) hide show
  1. package/README.md +129 -30
  2. package/dist/server/args.js +19 -3
  3. package/dist/server/characters.js +540 -0
  4. package/dist/server/cli.js +47 -6
  5. package/dist/server/http.js +122 -11
  6. package/dist/server/hub.js +17 -3
  7. package/dist/server/instance.js +52 -0
  8. package/dist/server/panes/herdr.js +29 -3
  9. package/dist/server/scene-store.js +58 -7
  10. package/dist/server/sources/claude.js +36 -1
  11. package/dist/server/sources/codex-live.js +279 -0
  12. package/dist/server/sources/codex-rollout.js +154 -0
  13. package/dist/server/sources/codex.js +363 -0
  14. package/dist/server/sources/jsonl.js +142 -0
  15. package/dist/server/sources/multi.js +53 -0
  16. package/dist/server/sources/opencode-live.js +144 -0
  17. package/dist/server/sources/opencode.js +265 -0
  18. package/dist/server/sources/proc.js +34 -0
  19. package/dist/server/sources/transcript.js +9 -103
  20. package/dist/server/token.js +23 -0
  21. package/dist/shared/packs.js +62 -0
  22. package/dist/web/apple-touch-icon.png +0 -0
  23. package/dist/web/assets/{abnfDiagram-VCTEODGH-tmjYj3VY.js → abnfDiagram-VCTEODGH-BxrKsDoB.js} +1 -1
  24. package/dist/web/assets/{ar-SA-G6X2FPQ2-8ZGGBDRT.js → ar-SA-G6X2FPQ2-Cc6gbg88.js} +1 -1
  25. package/dist/web/assets/{architecture-7GRP2DOG-CsvDkWt3.js → architecture-7GRP2DOG-CIqN5I9B.js} +1 -1
  26. package/dist/web/assets/{architectureDiagram-5GKGNRK7-Bq-1CDhU.js → architectureDiagram-5GKGNRK7-DsXC8AqK.js} +1 -1
  27. package/dist/web/assets/{az-AZ-76LH7QW2-DbdS_q-w.js → az-AZ-76LH7QW2-BH8VzNec.js} +1 -1
  28. package/dist/web/assets/{bg-BG-XCXSNQG7-CANqXhG1.js → bg-BG-XCXSNQG7-ClFUbics.js} +1 -1
  29. package/dist/web/assets/{blockDiagram-I7D4REHJ-DtYn-xOl.js → blockDiagram-I7D4REHJ-CltS-Zt2.js} +1 -1
  30. package/dist/web/assets/{bn-BD-2XOGV67Q-DJdq0B1R.js → bn-BD-2XOGV67Q-BVUiOO4B.js} +1 -1
  31. package/dist/web/assets/{c4Diagram-7LVT6UL2-DW6Pzj1e.js → c4Diagram-7LVT6UL2-C-C_SvWm.js} +1 -1
  32. package/dist/web/assets/{ca-ES-6MX7JW3Y-B7pUqerV.js → ca-ES-6MX7JW3Y-CEK8mB8J.js} +1 -1
  33. package/dist/web/assets/channel-Dom8D_0o.js +1 -0
  34. package/dist/web/assets/{chunk-4HAMMTFA-_AKNu1--.js → chunk-4HAMMTFA-Bfdmb0Hg.js} +1 -1
  35. package/dist/web/assets/{chunk-75Z2AOVW-BoMl8Mqw.js → chunk-75Z2AOVW-NYwkutzS.js} +1 -1
  36. package/dist/web/assets/{chunk-DU6HZSFF-DYHa8ENH.js → chunk-DU6HZSFF-SqE0xdu5.js} +1 -1
  37. package/dist/web/assets/{chunk-EIO257PC--adgQBo2.js → chunk-EIO257PC-DpOeKaLq.js} +1 -1
  38. package/dist/web/assets/{chunk-F27PBJKO-CvQi01qZ.js → chunk-F27PBJKO-g9bJrSwZ.js} +1 -1
  39. package/dist/web/assets/{chunk-GMAD6QVW-ojaxPuMG.js → chunk-GMAD6QVW-B1y2ol5w.js} +1 -1
  40. package/dist/web/assets/{chunk-GVQU2GXP-DYAeD1IL.js → chunk-GVQU2GXP-BUjRNRXo.js} +1 -1
  41. package/dist/web/assets/{chunk-IMKFNOWR-oVPWqbpV.js → chunk-IMKFNOWR-DyeQep8U.js} +1 -1
  42. package/dist/web/assets/{chunk-L3NEJ4N5-BelAXiIN.js → chunk-L3NEJ4N5-BcTVhsWp.js} +1 -1
  43. package/dist/web/assets/{chunk-OSK3NFVY-CATtjN8l.js → chunk-OSK3NFVY-Db7B8jPm.js} +1 -1
  44. package/dist/web/assets/{chunk-P2QGCYS3-CbKPCENJ.js → chunk-P2QGCYS3-Cx5iBC5z.js} +1 -1
  45. package/dist/web/assets/{chunk-POPQ4Y6H-BfOCSezn.js → chunk-POPQ4Y6H-CqVRZDA8.js} +1 -1
  46. package/dist/web/assets/{chunk-PWAF6VOD-C7O-JWJt.js → chunk-PWAF6VOD-Cf2j9yew.js} +1 -1
  47. package/dist/web/assets/{chunk-SHT3W25Y-BfEpPCTX.js → chunk-SHT3W25Y-0_N13xgE.js} +1 -1
  48. package/dist/web/assets/{chunk-SVP7TREG-CaeKcCSu.js → chunk-SVP7TREG-DkRJF9jr.js} +1 -1
  49. package/dist/web/assets/{chunk-TICWLB2K-Bx6AcLB_.js → chunk-TICWLB2K-D6OC50xH.js} +1 -1
  50. package/dist/web/assets/classDiagram-ZZMXUADV-BMEkgkEJ.js +1 -0
  51. package/dist/web/assets/classDiagram-v2-VYDZK3BY-BMEkgkEJ.js +1 -0
  52. package/dist/web/assets/{cs-CZ-2BRQDIVT-DF8hZ2mh.js → cs-CZ-2BRQDIVT-DWt1RUsP.js} +1 -1
  53. package/dist/web/assets/{cynefin-OW5HDTMX-Dol6Weuo.js → cynefin-OW5HDTMX-Dx0HzRCl.js} +1 -1
  54. package/dist/web/assets/{cynefinDiagram-5FMLGOSQ-CbOJ2lks.js → cynefinDiagram-5FMLGOSQ-C8AMQNhe.js} +1 -1
  55. package/dist/web/assets/{da-DK-5WZEPLOC-CgPdNz6E.js → da-DK-5WZEPLOC-BPggh0j6.js} +1 -1
  56. package/dist/web/assets/{dagre-GXQ25YYZ-CcuaBID7.js → dagre-GXQ25YYZ-f9qU6BFq.js} +1 -1
  57. package/dist/web/assets/{de-DE-XR44H4JA-DaVeYWRc.js → de-DE-XR44H4JA-B1q1pJrQ.js} +1 -1
  58. package/dist/web/assets/{diagram-S7CK7UJ4-BR2gIsNx.js → diagram-S7CK7UJ4-Bcq77Nl3.js} +1 -1
  59. package/dist/web/assets/{diagram-UQ7AKVKN-DwSZsV-Z.js → diagram-UQ7AKVKN-DXzlgVTk.js} +1 -1
  60. package/dist/web/assets/{diagram-VSXAHHWV-BcJpQHbj.js → diagram-VSXAHHWV-C1vz2FvT.js} +1 -1
  61. package/dist/web/assets/{diagram-VX7I27RA-CvjRTkwu.js → diagram-VX7I27RA-_c4ucp3r.js} +1 -1
  62. package/dist/web/assets/{diagram-Z3DM3KII-vg0-r_P4.js → diagram-Z3DM3KII-cUg91K-F.js} +1 -1
  63. package/dist/web/assets/{dist-D-3cz42D.js → dist-DcwmvBdV.js} +4 -4
  64. package/dist/web/assets/{ebnfDiagram-PWID7BFC-DZCaMmMd.js → ebnfDiagram-PWID7BFC-9iWfohHg.js} +1 -1
  65. package/dist/web/assets/{el-GR-BZB4AONW-nYncjO-L.js → el-GR-BZB4AONW-CrhwvNDD.js} +1 -1
  66. package/dist/web/assets/{en-B4ZKOASM-DqIz0rJz.js → en-B4ZKOASM-DCjnkz5L.js} +1 -1
  67. package/dist/web/assets/{erDiagram-RLTQ6QDP-DgyrjoaZ.js → erDiagram-RLTQ6QDP-A72uVlS3.js} +1 -1
  68. package/dist/web/assets/{es-ES-U4NZUMDT-e3WeRDLl.js → es-ES-U4NZUMDT-D0sRCoDL.js} +1 -1
  69. package/dist/web/assets/{eu-ES-A7QVB2H4-CwXv1t13.js → eu-ES-A7QVB2H4-DLG-liPb.js} +1 -1
  70. package/dist/web/assets/{eventmodeling-NTZA5JFV-DCTWpAwP.js → eventmodeling-NTZA5JFV-CIKZvDAj.js} +1 -1
  71. package/dist/web/assets/{fa-IR-HGAKTJCU-D-9plwKu.js → fa-IR-HGAKTJCU-BW3pPOVT.js} +1 -1
  72. package/dist/web/assets/{fi-FI-Z5N7JZ37-BTK1rs8G.js → fi-FI-Z5N7JZ37-D2XaqwPp.js} +1 -1
  73. package/dist/web/assets/flowDiagram-HODETNUW-DhQSc3KP.js +1 -0
  74. package/dist/web/assets/{fr-FR-RHASNOE6-CAuUMPtN.js → fr-FR-RHASNOE6-B-BjRA7r.js} +1 -1
  75. package/dist/web/assets/{ganttDiagram-EL5Y4UJY-bFfu4BMj.js → ganttDiagram-EL5Y4UJY-cgwUfr0G.js} +1 -1
  76. package/dist/web/assets/{gitGraph-4MIJSDKK-DIl4-oqK.js → gitGraph-4MIJSDKK-CeKopPn3.js} +1 -1
  77. package/dist/web/assets/{gitGraphDiagram-WWUBYQGX-ho3FT8XP.js → gitGraphDiagram-WWUBYQGX-BWjAy7ei.js} +1 -1
  78. package/dist/web/assets/{gl-ES-HMX3MZ6V-DlKPdjtk.js → gl-ES-HMX3MZ6V-DYUAqB0N.js} +1 -1
  79. package/dist/web/assets/{he-IL-6SHJWFNN-CLyP0zBo.js → he-IL-6SHJWFNN-CXkYqbuu.js} +1 -1
  80. package/dist/web/assets/{hi-IN-IWLTKZ5I-kvhBHNzH.js → hi-IN-IWLTKZ5I-BwVBsHWG.js} +1 -1
  81. package/dist/web/assets/{hu-HU-A5ZG7DT2-Dtd-o-RJ.js → hu-HU-A5ZG7DT2-DkmlE7Aa.js} +1 -1
  82. package/dist/web/assets/{id-ID-SAP4L64H-VZ3IV-8B.js → id-ID-SAP4L64H-CwkytHX_.js} +1 -1
  83. package/dist/web/assets/{image-GAAHSSAO-DWvjHHd3.js → image-GAAHSSAO-u-hBxkaK.js} +1 -1
  84. package/dist/web/assets/index-D43I17T9.js +212 -0
  85. package/dist/web/assets/{index-DtRVLazd.css → index-DxXUknKX.css} +1 -1
  86. package/dist/web/assets/{info-A6RAGUB7-DN8pwhKt.js → info-A6RAGUB7-DmadBmci.js} +1 -1
  87. package/dist/web/assets/{infoDiagram-27XIBGKW-i2JHBJKe.js → infoDiagram-27XIBGKW-D93CKwhy.js} +1 -1
  88. package/dist/web/assets/{ishikawaDiagram-5VMMS53U-DLLdu9-W.js → ishikawaDiagram-5VMMS53U-BQ-x5YXp.js} +1 -1
  89. package/dist/web/assets/{it-IT-JPQ66NNP-6SULWnRA.js → it-IT-JPQ66NNP-Bc-Qa6KI.js} +1 -1
  90. package/dist/web/assets/{ja-JP-DBVTYXUO-BbgutQYO.js → ja-JP-DBVTYXUO-BPmQCryQ.js} +1 -1
  91. package/dist/web/assets/{journeyDiagram-3NMN7TZE-DsysKJxX.js → journeyDiagram-3NMN7TZE-CO_LXx1E.js} +1 -1
  92. package/dist/web/assets/{kaa-6HZHGXH3-Bc6yhZWQ.js → kaa-6HZHGXH3-DuBFVAjv.js} +1 -1
  93. package/dist/web/assets/{kab-KAB-ZGHBKWFO-BaICxis-.js → kab-KAB-ZGHBKWFO-DhEFzSTh.js} +1 -1
  94. package/dist/web/assets/{kanban-definition-UXKFOSKX-w3k_6RhT.js → kanban-definition-UXKFOSKX-B72Jztau.js} +1 -1
  95. package/dist/web/assets/{kk-KZ-P5N5QNE5-BVsfmPoG.js → kk-KZ-P5N5QNE5-CW7PxU2h.js} +1 -1
  96. package/dist/web/assets/{km-KH-HSX4SM5Z-BS1M1bUx.js → km-KH-HSX4SM5Z-CYy7yySD.js} +1 -1
  97. package/dist/web/assets/{ko-KR-MTYHY66A-C0x16zQm.js → ko-KR-MTYHY66A-C5O645Qe.js} +1 -1
  98. package/dist/web/assets/{ku-TR-6OUDTVRD-BWI9z5E8.js → ku-TR-6OUDTVRD-CKcd_iWr.js} +1 -1
  99. package/dist/web/assets/{line-BRXlgUrO.js → line-Ckd3sAmP.js} +1 -1
  100. package/dist/web/assets/{lt-LT-XHIRWOB4-CTDq1zFR.js → lt-LT-XHIRWOB4-ya2_xWiy.js} +1 -1
  101. package/dist/web/assets/{lv-LV-5QDEKY6T-h8b-E15B.js → lv-LV-5QDEKY6T-cYYwyzmz.js} +1 -1
  102. package/dist/web/assets/{mermaid-parser.core-Da_XEVmR.js → mermaid-parser.core-Dbqkvrw-.js} +3 -3
  103. package/dist/web/assets/{mindmap-definition-YA3MSWOX-DUBdgu2g.js → mindmap-definition-YA3MSWOX-B4onxNgk.js} +1 -1
  104. package/dist/web/assets/{mr-IN-CRQNXWMA-dTdkz007.js → mr-IN-CRQNXWMA-CfaHpVWe.js} +1 -1
  105. package/dist/web/assets/{my-MM-5M5IBNSE-CmYwTRil.js → my-MM-5M5IBNSE-BfKiTATq.js} +1 -1
  106. package/dist/web/assets/{nb-NO-T6EIAALU-DLLYcK-s.js → nb-NO-T6EIAALU-Cz3yDFYg.js} +1 -1
  107. package/dist/web/assets/{nl-NL-IS3SIHDZ-mtv15Mmm.js → nl-NL-IS3SIHDZ-DDX026n5.js} +1 -1
  108. package/dist/web/assets/{nn-NO-6E72VCQL-CJDTT3kB.js → nn-NO-6E72VCQL-BcokL_SN.js} +1 -1
  109. package/dist/web/assets/{oc-FR-POXYY2M6-DdHJTqH4.js → oc-FR-POXYY2M6-bNFsGpEp.js} +1 -1
  110. package/dist/web/assets/{pa-IN-N4M65BXN-DxzzhbLu.js → pa-IN-N4M65BXN-iIHN9Z8W.js} +1 -1
  111. package/dist/web/assets/{packet-AYTQ26CC-CzX42SOE.js → packet-AYTQ26CC-BzBpP9hg.js} +1 -1
  112. package/dist/web/assets/{pegDiagram-XKGWAZYB-1R2Hd3Th.js → pegDiagram-XKGWAZYB-BPScRPVZ.js} +1 -1
  113. package/dist/web/assets/percentages-BXMCSKIN-EDfR-TFr.js +1 -0
  114. package/dist/web/assets/{pie-WAS4IAKB-DEI2uslz.js → pie-WAS4IAKB-N-9RHtKL.js} +1 -1
  115. package/dist/web/assets/{pieDiagram-E7YTZNPT-DOQnFSrs.js → pieDiagram-E7YTZNPT-Bpd_yCG-.js} +1 -1
  116. package/dist/web/assets/{pl-PL-T2D74RX3-Dpyab0lI.js → pl-PL-T2D74RX3-DeqOx-a4.js} +1 -1
  117. package/dist/web/assets/{pt-BR-5N22H2LF-DOGrUA6Y.js → pt-BR-5N22H2LF-DG1PCIkb.js} +1 -1
  118. package/dist/web/assets/{pt-PT-UZXXM6DQ-DAoNiiOg.js → pt-PT-UZXXM6DQ-BsUJk2fq.js} +1 -1
  119. package/dist/web/assets/{quadrantDiagram-AXDQQJYC-CQE1OxRJ.js → quadrantDiagram-AXDQQJYC-CSLCp0xS.js} +1 -1
  120. package/dist/web/assets/{radar-RG4KPBEZ-B-er2ORT.js → radar-RG4KPBEZ-rKULJroO.js} +1 -1
  121. package/dist/web/assets/{railroad-74A4TZTK-D1Veuu81.js → railroad-74A4TZTK-hDn0WPg3.js} +1 -1
  122. package/dist/web/assets/{railroad-abnf-HS5TGJTU-DTxLo5az.js → railroad-abnf-HS5TGJTU-DfI0hiCR.js} +1 -1
  123. package/dist/web/assets/{railroad-ebnf-LZEXJU2U-BmP2IZGe.js → railroad-ebnf-LZEXJU2U-paFQAnqR.js} +1 -1
  124. package/dist/web/assets/{railroad-peg-WCYAUIDC-Do60gMTC.js → railroad-peg-WCYAUIDC-B-2Um3QI.js} +1 -1
  125. package/dist/web/assets/{railroadDiagram-O6MQD6OU-5I8Qk1dI.js → railroadDiagram-O6MQD6OU-WkZPN5MA.js} +1 -1
  126. package/dist/web/assets/{requirementDiagram-BXWQKSXE-CIIM8YmC.js → requirementDiagram-BXWQKSXE-BJULFhuR.js} +1 -1
  127. package/dist/web/assets/{ro-RO-JPDTUUEW-DR9yu2MV.js → ro-RO-JPDTUUEW-yKjTMizq.js} +1 -1
  128. package/dist/web/assets/{ru-RU-B4JR7IUQ-B9uIhZUd.js → ru-RU-B4JR7IUQ-DITGdMQL.js} +1 -1
  129. package/dist/web/assets/{sankeyDiagram-P5KCCOFB-BdGmiiCQ.js → sankeyDiagram-P5KCCOFB-b_vfju3s.js} +1 -1
  130. package/dist/web/assets/{sequenceDiagram-WJ2MYXX4-BeCmgCpG.js → sequenceDiagram-WJ2MYXX4-D5n2aEN6.js} +1 -1
  131. package/dist/web/assets/{si-LK-N5RQ5JYF-C7DYCsOB.js → si-LK-N5RQ5JYF-DaFciStR.js} +1 -1
  132. package/dist/web/assets/{sk-SK-C5VTKIMK-BbBBLLCs.js → sk-SK-C5VTKIMK-CpyCIFtD.js} +1 -1
  133. package/dist/web/assets/{sl-SI-NN7IZMDC-BIaW2Iuj.js → sl-SI-NN7IZMDC-cnwvs7FN.js} +1 -1
  134. package/dist/web/assets/{stateDiagram-D77RDMKH-CmENpSfH.js → stateDiagram-D77RDMKH-CbFjpKDm.js} +1 -1
  135. package/dist/web/assets/stateDiagram-v2-MP3YSRHH-MOkTt8Mv.js +1 -0
  136. package/dist/web/assets/subset-shared.chunk-CWAaXrHb.js +1 -0
  137. package/dist/web/assets/{subset-worker.chunk-Bi16Jh4x.js → subset-worker.chunk-Cebu2JDe.js} +1 -1
  138. package/dist/web/assets/{sv-SE-XGPEYMSR-D5A1U3nk.js → sv-SE-XGPEYMSR-dOntI1Fk.js} +1 -1
  139. package/dist/web/assets/{swimlanes-42K2YHIH-_ymwQg8o.js → swimlanes-42K2YHIH-DtmsuzRR.js} +1 -1
  140. package/dist/web/assets/swimlanesDiagram-VR7AAH4N-v2ue4raa.js +8 -0
  141. package/dist/web/assets/{ta-IN-2NMHFXQM-BDzXUwiE.js → ta-IN-2NMHFXQM-Comju6i2.js} +1 -1
  142. package/dist/web/assets/{th-TH-HPSO5L25-DdVnWuWW.js → th-TH-HPSO5L25-uPCBvbue.js} +1 -1
  143. package/dist/web/assets/{timeline-definition-24CTP7MA-CRcZde4k.js → timeline-definition-24CTP7MA-DKZOmZFD.js} +1 -1
  144. package/dist/web/assets/{tr-TR-DEFEU3FU-BQwfGN3o.js → tr-TR-DEFEU3FU-LaP2C4go.js} +1 -1
  145. package/dist/web/assets/{treeView-Q6P3EWNA-BHZZuSXr.js → treeView-Q6P3EWNA-DJii9IFr.js} +1 -1
  146. package/dist/web/assets/{treemap-WGGIJYW6-DAzotEQZ.js → treemap-WGGIJYW6-U42pUP2Q.js} +1 -1
  147. package/dist/web/assets/{uk-UA-QMV73CPH-CFYnWqHD.js → uk-UA-QMV73CPH-u-WBulor.js} +1 -1
  148. package/dist/web/assets/{vennDiagram-4TSXK5OY-BsNz9Qnn.js → vennDiagram-4TSXK5OY-C8_zJPdp.js} +1 -1
  149. package/dist/web/assets/{vi-VN-M7AON7JQ-DO3BySmm.js → vi-VN-M7AON7JQ-DOSv3aq5.js} +1 -1
  150. package/dist/web/assets/{wardley-WFR3VGLG-Cc2r8Vp8.js → wardley-WFR3VGLG-DU89dbbh.js} +1 -1
  151. package/dist/web/assets/{wardleyDiagram-VM6X3IG4-47UvJO4N.js → wardleyDiagram-VM6X3IG4-BGnASelu.js} +1 -1
  152. package/dist/web/assets/{xychartDiagram-S5SC5T6Z-CVl63zr-.js → xychartDiagram-S5SC5T6Z-js8-abv7.js} +1 -1
  153. package/dist/web/assets/{zh-CN-LNUGB5OW-DKJ2CF-O.js → zh-CN-LNUGB5OW-B8soJHf3.js} +1 -1
  154. package/dist/web/assets/{zh-HK-E62DVLB3-DHW8OH5j.js → zh-HK-E62DVLB3-DKByBmSJ.js} +1 -1
  155. package/dist/web/assets/{zh-TW-RAJ6MFWO-B9cMDifZ.js → zh-TW-RAJ6MFWO-CYBStGL6.js} +1 -1
  156. package/dist/web/favicon-32.png +0 -0
  157. package/dist/web/favicon.svg +12 -0
  158. package/dist/web/index.html +6 -3
  159. package/package.json +5 -3
  160. package/dist/web/assets/channel-gFr9jEgP.js +0 -1
  161. package/dist/web/assets/classDiagram-ZZMXUADV-9J2CNLBI.js +0 -1
  162. package/dist/web/assets/classDiagram-v2-VYDZK3BY-9J2CNLBI.js +0 -1
  163. package/dist/web/assets/flowDiagram-HODETNUW--2QUGuZ7.js +0 -1
  164. package/dist/web/assets/index-B2hGCC2V.js +0 -212
  165. package/dist/web/assets/percentages-BXMCSKIN-Br7824d3.js +0 -1
  166. package/dist/web/assets/stateDiagram-v2-MP3YSRHH-BWgn52cG.js +0 -1
  167. package/dist/web/assets/subset-shared.chunk-d2GNuFHV.js +0 -1
  168. package/dist/web/assets/swimlanesDiagram-VR7AAH4N-fzrjtpfS.js +0 -8
package/README.md CHANGED
@@ -1,21 +1,31 @@
1
1
  # excaliagent
2
2
 
3
- A spatial scratchboard for your Claude Code sessions, on an Excalidraw canvas.
3
+ A 2D board for your coding agents, on an Excalidraw canvas.
4
+
5
+ When you run many coding agents at once, it is hard to remember which one was
6
+ doing what. excaliagent is a memory palace for your agents: each session is a
7
+ card you place on a canvas, and when you come back, its place reminds you what
8
+ it was about.
9
+
10
+ Works with Claude Code, OpenAI Codex and OpenCode.
4
11
 
5
12
  ![The board: session cards triaged into lanes](https://raw.githubusercontent.com/martinkozle/excaliagent/main/docs/images/board.png)
6
13
 
7
14
  Every session is a card. You drag cards wherever they make sense to you (parked,
8
15
  blocked on a colleague, come back to, done) and draw anything around them. The
9
- app keeps each card's **color and label** in sync with the session and never
10
- moves, resizes, or edits anything else.
16
+ app keeps each card's **color and label** in sync with the session (and its
17
+ height fitted to a one- or two-line title, until you resize the card yourself)
18
+ and never moves, resizes, or edits anything else on its own; cards move only
19
+ when you drop one on a lane title or ask for a tidy-up.
11
20
 
12
21
  ```
13
- Fix flaky checkout test ← title (handwritten, larger)
14
- demo-app · fix/flaky ← repo · branch
15
- needs user: input needed · 2m ← status · what it waits for · last activity
16
- cache warm 41m ← prompt-cache warmth
17
- herdr: demo-app › oauth ← herdr workspace › tab
18
- PR #12 ← last PR link
22
+ 🐔 Fix flaky checkout ✳ ← character, title (handwritten, larger), harness logo
23
+ test
24
+ demo-app · fix/flaky ← repo · branch
25
+ needs user: input needed · 2m ← status · what it waits for · last activity
26
+ cache warm 41m ← prompt-cache warmth
27
+ herdr: demo-app › oauth ← herdr workspace › tab
28
+ PR #12 ← last PR link
19
29
  ```
20
30
 
21
31
  | Color | Meaning |
@@ -28,47 +38,132 @@ PR #12 ← last PR link
28
38
 
29
39
  ![Right-click on a card: the excaliagent section next to the Excalidraw menu](https://raw.githubusercontent.com/martinkozle/excaliagent/main/docs/images/card-menu.png)
30
40
 
41
+ ## What it is for
42
+
43
+ The spatial board is the point. Everything else (live status, characters,
44
+ lanes, jumping to a pane, resuming, more agents) is there to make that board a
45
+ better place to keep your sessions. Beyond that, nothing is off the table: new
46
+ features and ideas of any kind are welcome on top of it.
47
+
48
+ ## Supported agents
49
+
50
+ | Agent | Live sessions and status | Dormant sessions | Resume | Stop |
51
+ |---|---|---|---|---|
52
+ | Claude Code | registry in `~/.claude/sessions`: busy, idle, needs input, ... | transcripts | `claude --resume <id>` | yes |
53
+ | Codex (0.163) | Linux only: running threads; busy or idle (approval prompts show as busy) | rollouts in `~/.codex/sessions` | `codex resume <id>` | yes |
54
+ | OpenCode (1.19) | Linux only, best effort (see below); busy or idle | `~/.local/share/opencode/opencode.db` | `opencode -s <id>` | yes |
55
+
56
+ Codex cards carry no prompt-cache line or PR link (Codex records neither), and
57
+ on macOS Codex sessions are only offered as dormant ones. Stop is offered only
58
+ when the board knows the Codex process for sure (`codex resume <id>`, or
59
+ `codex exec`), not when it matched a `codex` started without an id by its
60
+ folder. Rollouts older than a week may be compressed; reading those needs
61
+ Node 22.15+. Codex is looked up in
62
+ `$CODEX_HOME`, else `~/.codex` (`--codex-dir` to change, `--no-codex` to
63
+ turn it off). Details: [design](docs/design.md#codex-data-verified-on-01630).
64
+
65
+ OpenCode keeps no record of which session a running TUI shows, so the board
66
+ infers it: a TUI started with `opencode -s <id>` shows that session, any other
67
+ TUI the newest session of its directory that changed since it started. After
68
+ `/new` or switching sessions inside a TUI the wrong card can be live; see
69
+ [design](docs/design.md#opencode-data-verified-on-1193). Stop is offered only
70
+ for a TUI started with `opencode -s <id>`. OpenCode support needs Node 22.13+
71
+ (for `node:sqlite`; the rest of the board runs on Node 22); `--opencode-dir`
72
+ points at another data dir, `--no-opencode` turns it off.
73
+
31
74
  ## Run
32
75
 
33
76
  ```sh
34
77
  npx excaliagent
35
78
  ```
36
79
 
37
- It starts a server on `127.0.0.1` and opens the board in your browser.
80
+ It starts a server on `127.0.0.1:7357` (a random free port if that one is
81
+ busy; choose with `--port`), prints the URL with its access token, and opens it
82
+ in your browser. After that first visit, `http://127.0.0.1:7357/` works as a
83
+ bookmark. Running it again while a board is up just opens that board.
38
84
 
39
85
  - **Live sessions** appear in the *inbox* by themselves. A new board comes with
40
86
  lanes next to it (To Do, In Progress, Review, Blocked, Parked, Done, and two
41
- blank ones to name yourself); they are plain shapes you can rename, move or
42
- delete. On an older board, add them from the main menu: *Add starter lanes*.
43
- - **Dormant sessions** are added from the **Sessions** panel (top right).
87
+ blank ones to name yourself); they are plain shapes you can move, resize,
88
+ rename (double-click) or delete. **+ Lane** (top right) adds one more at the
89
+ right end.
90
+ - **Line cards up in a lane**: while you drag a card, every lane title shows a
91
+ faint *drop to stack* hint; drop the card on one (it lights up) and the card
92
+ goes into the lane's column, below the lowest card there.
93
+ Dropped anywhere else, a card stays exactly where you put it. Right-click a
94
+ lane → *Tidy cards* stacks its cards in one column, top to bottom (on the
95
+ inbox it packs its columns). **Tidy all** (top right, or the main menu)
96
+ does every lane and the inbox at once. Stacked cards are always 20 px
97
+ apart; if a title later grows a second line, its card may overlap the one
98
+ below a little until you tidy again. Cards
99
+ that are locked, rotated, attached to an arrow or grouped with something
100
+ else stay put; the column goes around them. Ctrl+Z undoes a tidy (or Tidy
101
+ all) in one step and a drop in two (the snap, then the drag). Turn the
102
+ title drop off in the main menu (*Drop on lane title stacks cards*).
103
+ - **Dormant sessions** are added from the **Sessions** panel (top right). On a
104
+ narrow window the top-right buttons show only their icons; hover for the name.
44
105
  - **Double-click a card** to jump to it: a live session focuses its
45
106
  [herdr](https://herdr.dev) pane and raises the terminal window (Hyprland,
46
- Sway). A dormant session is resumed with `claude --resume` in a new herdr
47
- tab, in the workspace for that repo. Without herdr, the resume command is
48
- copied instead.
107
+ Sway, macOS). A dormant session is resumed (`claude --resume <id>`,
108
+ `codex resume <id>`) in a new herdr tab, in the workspace for that repo. Without herdr, the resume command is
109
+ copied instead. A single click on the harness logo in the card's corner
110
+ does the same.
49
111
  - **Right-click a card** for an excaliagent section on top of the Excalidraw
50
112
  menu: focus or resume, copy the resume command (with or without `cd`), open
51
- the PR.
113
+ the PR, or stop a running session (asks first; the conversation is kept and
114
+ can be resumed).
52
115
  - A **PR link** (GitHub, Bitbucket, GitLab) shows on the card; the card's link
53
116
  icon opens it.
54
- - The board is saved to `$XDG_STATE_HOME/excaliagent/scene.json`
55
- (default `~/.local/state/excaliagent/`).
117
+ - Every card has a **character**, so you remember which agent is which: an
118
+ animal by default, different for every card on the board, and the same one
119
+ each time that session comes back. Right-click → *Change character…* picks
120
+ one by hand (or *Shuffle*, *Reset to automatic*, or *None*; deleting the
121
+ character from a card also keeps it off). The **Characters** panel
122
+ (top right) switches the pack (Animals, Cats & friends, Sea, Fantasy, Food)
123
+ and makes your own packs from emoji and images: type or paste an emoji, or
124
+ paste, drop or upload png, gif, webp, jpeg or svg files (up to 1 MB each). A
125
+ custom pack is a folder, `packs/<name>/` in the state directory, so you can
126
+ also drop image files there by hand, and list emoji in its `pack.json` as
127
+ `{"emoji": ["🧟", "👻"]}`.
128
+
129
+ ![The Characters panel: packs, and the characters of the active one](https://raw.githubusercontent.com/martinkozle/excaliagent/main/docs/images/characters.png)
56
130
 
57
- Options: `--port`, `--no-open`, `--state-dir`, `--claude-dir`, `--no-herdr`, `--no-raise`.
131
+ - The board is saved to `$XDG_STATE_HOME/excaliagent/scene.json`
132
+ (default `~/.local/state/excaliagent/`), pasted images under `files/` next
133
+ to it, character choices in `characters.json` and your packs under `packs/`.
134
+ - **Start over**: main menu → *Reset the canvas* (undoable) lays out a fresh
135
+ board with the live sessions. Or try a clean board without touching yours:
136
+ `npx excaliagent --state-dir /tmp/excaliagent-fresh`.
137
+
138
+ Options: `--port`, `--no-open`, `--state-dir`, `--claude-dir`, `--codex-dir`,
139
+ `--no-codex`, `--opencode-dir`, `--no-opencode`, `--no-herdr`, `--no-raise`.
58
140
  See `npx excaliagent --help`.
59
141
 
60
142
  ## Privacy and security
61
143
 
62
144
  - Reads `~/.claude/sessions/*.json` and the transcript files under
63
145
  `~/.claude/projects/` (only metadata lines: title, branch, timestamps, token
64
- usage, PR links; never message content). Installs no hooks, writes nothing
146
+ usage, PR links; never message content). For Codex it reads the rollouts
147
+ under `~/.codex/sessions/` (metadata, turn starts and ends, and the first
148
+ prompt, cut short, as the title, like `codex resume` shows it),
149
+ `session_index.jsonl` (names), the lock files in `thread-writer-locks/`, and
150
+ `/proc` (`/proc/locks`, and the command line and working directory of
151
+ `codex` processes) to tell which threads are running. For OpenCode it reads
152
+ `opencode.db` read-only (session titles, directories, times, and whether the
153
+ newest message is finished; never message content) and the command line,
154
+ working directory and start time of `opencode` processes. Installs no hooks, writes nothing
65
155
  outside its state directory.
66
- - Listens on loopback only. A random token is put into the URL it opens and
67
- exchanged for an HttpOnly cookie; every request needs it. Requests with a
156
+ - Listens on loopback only. A random token (created once, kept in the state
157
+ directory, readable only by you) is put into the URL it opens and exchanged
158
+ for an HttpOnly cookie; every request needs it, so other users on the same
159
+ machine stay out. Requests with a
68
160
  foreign `Host` (DNS rebinding) or cross-origin writes are refused.
69
- - Its only actions: focus a herdr pane, raise the terminal window, and start
70
- `claude --resume <id>` in a new herdr pane. It never types into a running
71
- session.
161
+ - Its only actions: focus a herdr pane, raise the terminal window, start
162
+ `claude --resume <id>`, `codex resume <id>` or `opencode -s <id>` in a new herdr pane, and stop a session when you ask
163
+ (right-click → Stop session, confirmed; it exits as if its terminal closed).
164
+ It never types into a running session.
165
+ - Images you paste onto the board, and the images of your character packs,
166
+ are stored next to the scene, in the state directory.
72
167
  - The only outside request: Chinese, Japanese or Korean text on the board loads
73
168
  Excalidraw's CJK font from esm.sh (it is not bundled, to keep the package
74
169
  small). Everything else, including all other fonts, is served locally.
@@ -93,15 +188,19 @@ The repo ships a Nix flake with Node 24 and Chromium for the browser tests:
93
188
  direnv allow # or: nix develop
94
189
  npm install
95
190
  npm test # unit tests (vitest)
96
- npm run test:e2e # browser tests (playwright) against a mock Claude home
191
+ npm run test:e2e # browser tests (playwright) against mock Claude, Codex and OpenCode homes
97
192
  npm run demo # the board with a seeded, synthetic set of sessions
98
- npm run dev # server + Vite hot reload against your real ~/.claude
193
+ npm run dev # server + Vite hot reload against your real ~/.claude, ~/.codex and OpenCode data
99
194
  ```
100
195
 
101
- Tests never read your real `~/.claude` or talk to your running herdr:
102
- `test/mock-claude.ts` seeds a throwaway Claude home with dummy processes, and the
196
+ Tests never read your real `~/.claude`, `~/.codex` or OpenCode data or talk to
197
+ your running herdr: `test/mock-claude.ts`, `test/mock-codex.ts` and
198
+ `test/mock-opencode.ts` seed throwaway homes with dummy processes, and the
103
199
  herdr tests start an isolated `herdr server` with its own temp home and socket.
104
200
  A privacy test fails if any fixture contains this machine's home path or user
105
201
  name.
106
202
 
107
203
  Docs: [product](docs/product.md), [design](docs/design.md), [roadmap](docs/roadmap.md). Agents start at [AGENTS.md](AGENTS.md).
204
+
205
+ MIT licensed. Built-in characters are Unicode emoji, drawn by your system's
206
+ emoji font. The harness logos on cards (from [simple-icons](https://simpleicons.org), CC0) are trademarks of their owners and only identify which agent a card belongs to. simple-icons has no OpenAI mark, so Codex cards show a neutral `>_` glyph drawn for this project; the OpenCode mark is from simple-icons too.
@@ -1,13 +1,21 @@
1
1
  import { parseArgs } from "node:util";
2
+ /** Used when --port is not given; a busy default falls back to a random port. */
3
+ export const DEFAULT_PORT = 7357;
2
4
  export const USAGE = `Usage: excaliagent [options]
3
5
 
4
- A spatial Excalidraw board for your Claude Code sessions.
6
+ A spatial Excalidraw board for your coding-agent sessions (Claude Code, Codex, OpenCode).
5
7
 
6
8
  Options:
7
- --port <n> Port on 127.0.0.1 (default: random free port)
9
+ --port <n> Port on 127.0.0.1 (default: 7357, or a random free port
10
+ if that is busy; 0 = always random)
8
11
  --no-open Do not open the browser, just print the URL
9
12
  --state-dir <dir> Where scene.json lives (default: $XDG_STATE_HOME/excaliagent)
10
13
  --claude-dir <dir> Claude Code home (default: ~/.claude)
14
+ --codex-dir <dir> Codex home (default: $CODEX_HOME, else ~/.codex)
15
+ --no-codex Do not show Codex sessions
16
+ --opencode-dir <dir> OpenCode data dir, holding opencode.db (default:
17
+ $XDG_DATA_HOME/opencode, else ~/.local/share/opencode)
18
+ --no-opencode Do not show OpenCode sessions
11
19
  --no-herdr Do not link sessions to herdr panes
12
20
  --no-raise Focus the herdr pane but do not raise its terminal window
13
21
  (raising supports Hyprland, Sway and macOS)
@@ -28,11 +36,15 @@ export function parseCliArgs(argv) {
28
36
  raise: { type: "boolean", default: true },
29
37
  "state-dir": { type: "string" },
30
38
  "claude-dir": { type: "string" },
39
+ codex: { type: "boolean", default: true },
40
+ "codex-dir": { type: "string" },
41
+ opencode: { type: "boolean", default: true },
42
+ "opencode-dir": { type: "string" },
31
43
  help: { type: "boolean", short: "h", default: false },
32
44
  version: { type: "boolean", short: "v", default: false },
33
45
  },
34
46
  });
35
- let port = 0;
47
+ let port;
36
48
  if (values.port !== undefined) {
37
49
  port = Number(values.port);
38
50
  if (!Number.isInteger(port) || port < 0 || port > 65535)
@@ -46,6 +58,10 @@ export function parseCliArgs(argv) {
46
58
  raise: values.raise,
47
59
  stateDir: values["state-dir"],
48
60
  claudeDir: values["claude-dir"],
61
+ codex: values.codex,
62
+ codexDir: values["codex-dir"],
63
+ opencode: values.opencode,
64
+ opencodeDir: values["opencode-dir"],
49
65
  help: values.help,
50
66
  version: values.version,
51
67
  };