elanous 0.2.41 → 0.2.43

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 (796) hide show
  1. package/apps/pwa/out/404/index.html +1 -1
  2. package/apps/pwa/out/404.html +1 -1
  3. package/apps/pwa/out/_next/static/{GiOLWmt4MqDZePubBjA4Q → Om5xS9jpjSXJCeTNGYEi4}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{2fe2c302.41b517f88d6fe502.js → 0966f8a1.745fcd44f64a87ea.js} +1 -1
  5. package/apps/pwa/out/_next/static/chunks/{385e4574.e9886ab32759eda3.js → 0ad6802e.ae7afb63fdcb4491.js} +1 -1
  6. package/apps/pwa/out/_next/static/chunks/114.2b90424d1a3ce84c.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1151-5c2bb8f002ca2dd6.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1200.6a37c202f9f17e9a.js +226 -0
  9. package/apps/pwa/out/_next/static/chunks/1261-a616d5728e02e624.js +1 -0
  10. package/apps/pwa/out/_next/static/chunks/1313-19f737e0222c4444.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/1357.3bbef3976c37f94a.js +1 -0
  12. package/apps/pwa/out/_next/static/chunks/1362-20adddfaf662b0fa.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/{6874.d5cf7eb8edb2cabe.js → 1406.a1dc2ab6f8449374.js} +2 -2
  14. package/apps/pwa/out/_next/static/chunks/1737-9491fc6ab29b9ec6.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/1803-4f91a8e7dcaf042c.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/{5744.b9415e18ad623100.js → 1961.a81b12872c3e93a9.js} +1 -1
  17. package/apps/pwa/out/_next/static/chunks/1970cf59.2d4d8ce5d6c81853.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/1971-8890f3962ba7ee0a.js +1 -0
  19. package/apps/pwa/out/_next/static/chunks/2073-ba274e00e4f9efb4.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/{5471.1e611302ed3a7c53.js → 2144.25b292396712196d.js} +2 -2
  21. package/apps/pwa/out/_next/static/chunks/{3230-49298c3b73ef2268.js → 2268-53861f339e0b65a2.js} +1 -1
  22. package/apps/pwa/out/_next/static/chunks/{9834.63ab2bbc3153172e.js → 2312.0c8b61e22d3136d7.js} +1 -1
  23. package/apps/pwa/out/_next/static/chunks/{1800.f7ff51dc4978a958.js → 2573.387a707f6f9d720c.js} +2 -2
  24. package/apps/pwa/out/_next/static/chunks/273.f156eee28f11af77.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/2873.d2140e5a82546401.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/{9048.212083de42d25be3.js → 3072.01338851ca21a6f7.js} +2 -2
  27. package/apps/pwa/out/_next/static/chunks/3091.a5a4143dea33d197.js +90 -0
  28. package/apps/pwa/out/_next/static/chunks/3095.dc44586a5f83b86d.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/{2263.e09b6edea33bad2d.js → 3113.d7472bbc27d580c7.js} +1 -1
  30. package/apps/pwa/out/_next/static/chunks/3228-9650b6447b6fa288.js +1 -0
  31. package/apps/pwa/out/_next/static/chunks/3402.44b565b314f2263c.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/{addc2b32.8c4ff8f0aefe987d.js → 3557ac4a.c8931684475018ad.js} +1 -1
  33. package/apps/pwa/out/_next/static/chunks/360.ae9f9f4c33c395e8.js +79 -0
  34. package/apps/pwa/out/_next/static/chunks/3638.80412ea63aae8f3f.js +286 -0
  35. package/apps/pwa/out/_next/static/chunks/{a0a01613.6d1cca322238d7fe.js → 363bfab3.9623b9f89363541f.js} +1 -1
  36. package/apps/pwa/out/_next/static/chunks/3694.e0099884345f0198.js +64 -0
  37. package/apps/pwa/out/_next/static/chunks/3744.54f87db52acfd1ab.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/3903.3ef4656c67572764.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/3935.16701e33f8982dc9.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/3955.6922286237f2ac2b.js +24 -0
  41. package/apps/pwa/out/_next/static/chunks/3969.272ee7f9fd6c62e5.js +34 -0
  42. package/apps/pwa/out/_next/static/chunks/4199.ce86b281fd0a60b7.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/4311-6dd3144002cc0c2d.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/4426-2b230fad00c88930.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/{530.d26346e18089640a.js → 4445.7990c76b3751a918.js} +1 -1
  46. package/apps/pwa/out/_next/static/chunks/4447-14c5161fa59166c7.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/4856-b0b8075bba8c53f4.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/4870-de370d65e73c0bb5.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/4885-2c989165c4b29fad.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/4894.fec2ca9e99caefa2.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/5093.8f04b7f8cb899a95.js +94 -0
  52. package/apps/pwa/out/_next/static/chunks/5122-2bb177cebf89e19a.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/5154.5f56dc3902e3d275.js +36 -0
  54. package/apps/pwa/out/_next/static/chunks/529.64ff7257180b2ac9.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/5394.5dabeb0c62293a28.js +93 -0
  56. package/apps/pwa/out/_next/static/chunks/5461.08bf2404ff38ec85.js +1 -0
  57. package/apps/pwa/out/_next/static/chunks/5474-22e08a85583209b2.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/{1219.7e17964e0e7cd8e5.js → 5564.9e72532188f57586.js} +3 -3
  59. package/apps/pwa/out/_next/static/chunks/5567-265df39ed8fe9dcb.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/5570-a94ae19811cb2046.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/5574-b47c9ef2dceff1fd.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/5628.6ddb2d5ffba4ff4c.js +309 -0
  63. package/apps/pwa/out/_next/static/chunks/5730.43d7ccc09988e646.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/{1178.1aa9cad0e7695427.js → 5789.2da35c258292e1e5.js} +1 -1
  65. package/apps/pwa/out/_next/static/chunks/{4133.2056bb4d78f621af.js → 5824.da9527b15a3221e5.js} +1 -1
  66. package/apps/pwa/out/_next/static/chunks/5866.366966af47fdde5d.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/{4527.a69f2894d1bc9f4a.js → 5930.8b4df3b46c32b05a.js} +1 -1
  68. package/apps/pwa/out/_next/static/chunks/5963-c4d8469c52a0828b.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/6001.ec4049ceb3c43418.js +27 -0
  70. package/apps/pwa/out/_next/static/chunks/6120-471f03db1e299c0c.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/6175-41479e643aca1878.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/6291.a2de4f9787637075.js +104 -0
  73. package/apps/pwa/out/_next/static/chunks/6400-6699907c3537436a.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/6428.1f4327d6ae5fdf9a.js +287 -0
  75. package/apps/pwa/out/_next/static/chunks/644.02cb026fa44bcd0a.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/6466-6c87d60d3dd174fb.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/{9507.7026657a2f47eb64.js → 6540.c7bef57ad8f90a87.js} +16 -16
  78. package/apps/pwa/out/_next/static/chunks/6773.d4264665ab31bec0.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/6822.3c789f1a8443e774.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/{5574.f35accf4f132b29d.js → 6944.309f4e3ea54d1537.js} +1 -1
  81. package/apps/pwa/out/_next/static/chunks/7261-8ff69d3b2ee671fd.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/7266.084c6bbc70035140.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/7271.5c0100e7320aa856.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/7429-bf5731358c8f2f68.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/7464.01f7a0ae1215fbe7.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/7479.0fcad5f37eb64f0c.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/7483.427a2fe2049e388d.js +148 -0
  88. package/apps/pwa/out/_next/static/chunks/7502-be74718178e13e56.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/7530.0889722b19572065.js +24 -0
  90. package/apps/pwa/out/_next/static/chunks/7645.5b2ee3ad45c55ea3.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/7788.7d1c79f1a8e18946.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/7900.096f455c7c1efc53.js +77 -0
  93. package/apps/pwa/out/_next/static/chunks/7910-6f139bcafd238b9f.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/7966.f71c8958d1637548.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/{5947-135e26537d80a6b9.js → 8062-7cd0bcc7f01455ba.js} +3 -3
  96. package/apps/pwa/out/_next/static/chunks/8073.f6cf2f2c71aafbd0.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/8201.190b94088980f430.js +74 -0
  98. package/apps/pwa/out/_next/static/chunks/8205.282ca4bb62d54a0a.js +62 -0
  99. package/apps/pwa/out/_next/static/chunks/8313-dfa1021bb58a46d6.js +1 -0
  100. package/apps/pwa/out/_next/static/chunks/837-81336ebaca8198a8.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/8447.7963352ef5f71b76.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/8574-868e8129525ef6d9.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8588.d1c6a2903727ce87.js +149 -0
  104. package/apps/pwa/out/_next/static/chunks/8637.90f92d5c8db4732c.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/{2743.5d3f76948be32b34.js → 868.6e953be05bcf6dca.js} +2 -2
  106. package/apps/pwa/out/_next/static/chunks/8706-e1fe0309343a2273.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/8749-06384cdfc4520add.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/{5964-7e21164a8f2cf0ce.js → 8861-cc1fa1c7b920fa8e.js} +1 -1
  109. package/apps/pwa/out/_next/static/chunks/8967-7dfebf710c9dec9d.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/{5159.115f1c2ca471386c.js → 8986.8e2e4efbfa655c59.js} +1 -1
  111. package/apps/pwa/out/_next/static/chunks/8997-3c564dbb3b58b055.js +1 -0
  112. package/apps/pwa/out/_next/static/chunks/923.2034d10ae91e9c20.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/9312.bc1b89c5d4368033.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/943.39ae5e82f4f1893f.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/9469.0500480de55fb205.js +32 -0
  116. package/apps/pwa/out/_next/static/chunks/9770.5f75bc6088b16109.js +1 -0
  117. package/apps/pwa/out/_next/static/chunks/9810-2543267050e58b82.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/9870.8419702475254745.js +8 -0
  119. package/apps/pwa/out/_next/static/chunks/9941-376d1b74d51b01a4.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9958.385434ab04241758.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/{b2271e54.c1de3347976e90b0.js → aa57532f.510551854ff239b1.js} +1 -1
  122. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-deea1450b17cb8dc.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/app/approvals/page-70985b904f8650ef.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-a2e15e33e56a4353.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/board/page-fc72ce2db12d6ca9.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/botlab/page-be03e41f9436ebd9.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/bots/page-35a35999382da3f2.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/ceo/page-3ff5b1e6ca88b848.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/chat/page-a65101300a0ee5c1.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/consult/page-3aca5b6d67dba511.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/control/page-45b8ab0a71e61314.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/decisions/page-53046e282d4cda8e.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/design-check/page-17809e60e8354c17.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/editor/page-fd2442d347bf5898.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/exec/page-e9d720d6fc082e21.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/field/page-6b8b4267bab0a677.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/healthz/route-deea1450b17cb8dc.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/inside/page-8bcf6233ac7c17af.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/intake/page-7cc25591cfc2126f.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/layout-053e871f35c9beba.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/live/page-eff819f0c2d5e084.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live-run/page-4d7e9d8db5274a87.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/loops/page-2b2d8f5aa5f69ad4.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/market/page-0b8f92c5062e68b1.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1bd9d0fdac2ced3d.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/morning/page-9ee28f7df07428ea.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/not-found-44b7a1ff468c6648.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/observatory/page-cbc6523711dc1b65.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-fdad47899c2695be.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/release/{page-40f9e19149024298.js → page-79a8b5fee4c20871.js} +1 -1
  151. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-03e8ac9606aeaffb.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/outputs/page-4cd55c55ec287e2f.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/page-db17b4305404161e.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/reflection/page-30041d848350fd02.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-c540da022dbf86b0.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/sessions/page-9399efc538da057f.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/settings/devices/{page-a142dfb0331a05f5.js → page-ca2d09128c585ca4.js} +1 -1
  158. package/apps/pwa/out/_next/static/chunks/app/settings/page-0e2635aecd343038.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-ef7f4399b6b7726e.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/layout-deea1450b17cb8dc.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/page-caf530535b875468.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/share/page-eaa20c1543a5fd8e.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/showroom/page-c541eb1b75120f61.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/tasks/page-ab5e213eda9479f4.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/term/page-0a815f34367b6db6.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/today/page-e858ba0ed9393b68.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/trace/page-1638ee9dd6e0582f.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/vault/page-4cf5a399109391f2.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-b4396321238798ec.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/page-cb72bfd21006781a.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workspace/page-6135d0242afbc434.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-a1dccf907eddb856.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/{53aeb4ee-51c92f8d683f5220.js → c7945435-b44d4dbe90ba0dcb.js} +1 -1
  174. package/apps/pwa/out/_next/static/chunks/{2fdf2931.b431eee4fb468bc3.js → cb0f8df8.09a4a6be97e3fc5f.js} +1 -1
  175. package/apps/pwa/out/_next/static/chunks/{c0c1a699.0ba79f97005965d4.js → d96660fb.cbc21a2a88539dbb.js} +1 -1
  176. package/apps/pwa/out/_next/static/chunks/ea514caa.05a24f78d9dffe5f.js +122 -0
  177. package/apps/pwa/out/_next/static/chunks/{83184dcd-0ee6247ff41eb3f2.js → fb7d20d5-6892502b6ee39ca6.js} +1 -1
  178. package/apps/pwa/out/_next/static/chunks/framework-e8a911e19b1be41f.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-7022f418fabba021.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-app-e5f15df755756a1e.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-4525f91e36940c9b.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-140f0e519c085b0f.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-8f22ef63dcb865b1.js +1 -0
  184. package/apps/pwa/out/_next/static/css/{b9d8151e48998417.css → 62c858ad53854f47.css} +1 -1
  185. package/apps/pwa/out/_next/static/css/d1f8bb401740a549.css +1 -0
  186. package/apps/pwa/out/approvals/index.html +1 -1
  187. package/apps/pwa/out/approvals/index.txt +23 -23
  188. package/apps/pwa/out/autopilot/index.html +1 -1
  189. package/apps/pwa/out/autopilot/index.txt +23 -23
  190. package/apps/pwa/out/board/index.html +1 -1
  191. package/apps/pwa/out/board/index.txt +23 -23
  192. package/apps/pwa/out/botlab/index.html +1 -1
  193. package/apps/pwa/out/botlab/index.txt +22 -22
  194. package/apps/pwa/out/bots/index.html +1 -1
  195. package/apps/pwa/out/bots/index.txt +22 -22
  196. package/apps/pwa/out/ceo/index.html +1 -1
  197. package/apps/pwa/out/ceo/index.txt +23 -23
  198. package/apps/pwa/out/chat/index.html +1 -1
  199. package/apps/pwa/out/chat/index.txt +22 -22
  200. package/apps/pwa/out/consult/index.html +1 -1
  201. package/apps/pwa/out/consult/index.txt +23 -23
  202. package/apps/pwa/out/control/index.html +1 -1
  203. package/apps/pwa/out/control/index.txt +23 -23
  204. package/apps/pwa/out/decisions/index.html +1 -1
  205. package/apps/pwa/out/decisions/index.txt +22 -22
  206. package/apps/pwa/out/design-check/index.html +1 -1
  207. package/apps/pwa/out/design-check/index.txt +23 -23
  208. package/apps/pwa/out/editor/index.html +1 -1
  209. package/apps/pwa/out/editor/index.txt +24 -25
  210. package/apps/pwa/out/exec/index.html +1 -1
  211. package/apps/pwa/out/exec/index.txt +23 -23
  212. package/apps/pwa/out/field/index.html +1 -1
  213. package/apps/pwa/out/field/index.txt +23 -23
  214. package/apps/pwa/out/healthz +1 -1
  215. package/apps/pwa/out/index.html +1 -1
  216. package/apps/pwa/out/index.txt +22 -22
  217. package/apps/pwa/out/inside/index.html +1 -1
  218. package/apps/pwa/out/inside/index.txt +23 -23
  219. package/apps/pwa/out/intake/index.html +1 -1
  220. package/apps/pwa/out/intake/index.txt +23 -23
  221. package/apps/pwa/out/live/index.html +1 -1
  222. package/apps/pwa/out/live/index.txt +24 -25
  223. package/apps/pwa/out/live-run/index.html +1 -1
  224. package/apps/pwa/out/live-run/index.txt +24 -25
  225. package/apps/pwa/out/loops/index.html +1 -1
  226. package/apps/pwa/out/loops/index.txt +22 -22
  227. package/apps/pwa/out/market/index.html +1 -1
  228. package/apps/pwa/out/market/index.txt +22 -22
  229. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  230. package/apps/pwa/out/missions/placeholder/index.txt +22 -22
  231. package/apps/pwa/out/morning/index.html +1 -1
  232. package/apps/pwa/out/morning/index.txt +23 -23
  233. package/apps/pwa/out/observatory/index.html +1 -1
  234. package/apps/pwa/out/observatory/index.txt +23 -23
  235. package/apps/pwa/out/ops/checklist/index.html +1 -1
  236. package/apps/pwa/out/ops/checklist/index.txt +22 -22
  237. package/apps/pwa/out/ops/release/index.html +1 -1
  238. package/apps/pwa/out/ops/release/index.txt +22 -22
  239. package/apps/pwa/out/ops/seats/index.html +1 -1
  240. package/apps/pwa/out/ops/seats/index.txt +22 -22
  241. package/apps/pwa/out/outputs/index.html +1 -1
  242. package/apps/pwa/out/outputs/index.txt +22 -22
  243. package/apps/pwa/out/reflection/index.html +1 -1
  244. package/apps/pwa/out/reflection/index.txt +23 -23
  245. package/apps/pwa/out/scheduler/index.html +1 -1
  246. package/apps/pwa/out/scheduler/index.txt +23 -23
  247. package/apps/pwa/out/sessions/index.html +1 -1
  248. package/apps/pwa/out/sessions/index.txt +22 -22
  249. package/apps/pwa/out/settings/devices/index.html +1 -1
  250. package/apps/pwa/out/settings/devices/index.txt +23 -23
  251. package/apps/pwa/out/settings/index.html +1 -1
  252. package/apps/pwa/out/settings/index.txt +23 -23
  253. package/apps/pwa/out/setup/done/index.html +1 -1
  254. package/apps/pwa/out/setup/done/index.txt +23 -23
  255. package/apps/pwa/out/setup/index.html +1 -1
  256. package/apps/pwa/out/setup/index.txt +23 -23
  257. package/apps/pwa/out/share/index.html +1 -1
  258. package/apps/pwa/out/share/index.txt +23 -23
  259. package/apps/pwa/out/showroom/index.html +1 -1
  260. package/apps/pwa/out/showroom/index.txt +22 -22
  261. package/apps/pwa/out/tasks/index.html +1 -1
  262. package/apps/pwa/out/tasks/index.txt +23 -23
  263. package/apps/pwa/out/term/index.html +1 -1
  264. package/apps/pwa/out/term/index.txt +23 -23
  265. package/apps/pwa/out/today/index.html +1 -1
  266. package/apps/pwa/out/today/index.txt +23 -23
  267. package/apps/pwa/out/trace/index.html +1 -1
  268. package/apps/pwa/out/trace/index.txt +23 -23
  269. package/apps/pwa/out/vault/index.html +1 -1
  270. package/apps/pwa/out/vault/index.txt +23 -23
  271. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  272. package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
  273. package/apps/pwa/out/workflows/index.html +1 -1
  274. package/apps/pwa/out/workflows/index.txt +23 -23
  275. package/apps/pwa/out/workspace/index.html +1 -1
  276. package/apps/pwa/out/workspace/index.txt +23 -23
  277. package/apps/pwa/out/worktrees/index.html +1 -1
  278. package/apps/pwa/out/worktrees/index.txt +23 -23
  279. package/catalog/external-commands.yaml +5 -3
  280. package/catalog/meta/catalogVersion.yaml +2 -1
  281. package/catalog/signing/catalog-signing-public.pem +3 -0
  282. package/docs/goal-context/04-mock-scenarios.md +13 -0
  283. package/graphs/catalog/catalog.yaml +1 -1
  284. package/graphs/heal/heal-loop.yaml +1 -0
  285. package/graphs/intake/intake-daily.yaml +16 -0
  286. package/graphs/intake/news-sources.yaml +1 -0
  287. package/graphs/intake/recipes.yaml +7 -0
  288. package/graphs/overlays/examples/research-runtime-empty-terminal.yaml +28 -0
  289. package/graphs/overlays/stop-heal-ladder.yaml +113 -0
  290. package/graphs/profiles/local.yaml +5 -0
  291. package/graphs/profiles/pod.yaml +4 -0
  292. package/graphs/units/verbs/recipes.yaml +11 -11
  293. package/graphs/work/research-report.yaml +10 -2
  294. package/package.json +6 -2
  295. package/plugins/demo-absorption-briefing/plugin.json +18 -0
  296. package/plugins/demo-absorption-briefing/skills/demo-absorption-briefing/SKILL.md +8 -0
  297. package/plugins/demo-browser-hand/plugin.json +13 -0
  298. package/plugins/demo-browser-hand/skills/demo-browser-hand/SKILL.md +8 -0
  299. package/plugins/demo-linear-secretary/plugin.json +15 -0
  300. package/plugins/demo-linear-secretary/skills/demo-linear-secretary/SKILL.md +8 -0
  301. package/plugins/demo-plugin-wizard/plugin.json +11 -0
  302. package/plugins/demo-plugin-wizard/skills/demo-plugin-wizard/SKILL.md +8 -0
  303. package/plugins/demo-research/plugin.json +16 -0
  304. package/plugins/demo-research/skills/demo-research/SKILL.md +8 -0
  305. package/plugins/demo-video-briefing/plugin.json +15 -0
  306. package/plugins/demo-video-briefing/skills/demo-video-briefing/SKILL.md +8 -0
  307. package/scripts/build-signed-catalog.ts +48 -0
  308. package/scripts/ci-typecheck-main-delta.sh +88 -0
  309. package/scripts/codex-fallback-live-probe.ts +1 -1
  310. package/scripts/demo/demo1104-parallel-scenes.ts +301 -0
  311. package/scripts/demo/demo1104-stage.config.ts +21 -0
  312. package/scripts/demo/demo1104-stage.ts +316 -0
  313. package/scripts/goal-method-audit.ts +17 -1
  314. package/scripts/graph-units/land-enqueue.ts +90 -0
  315. package/scripts/heal/run-role.ts +99 -5
  316. package/scripts/hooks/codex-notify.sh +32 -0
  317. package/scripts/install.sh +10 -38
  318. package/scripts/land-global-checks.ts +6 -1
  319. package/scripts/landing-heal/land-plan.ts +57 -0
  320. package/scripts/lib/decompose-ab.ts +1 -0
  321. package/scripts/lib/fixtures/tui-regress/help-insufficient-commands.txt +15 -0
  322. package/scripts/lib/fixtures/tui-regress/help-live.txt +42 -0
  323. package/scripts/lib/fixtures/tui-regress/help-missing-keys.txt +21 -0
  324. package/scripts/lib/fixtures/tui-regress/help-original.txt +51 -0
  325. package/scripts/lib/fixtures/tui-regress/help-shifted-input.txt +26 -0
  326. package/scripts/lib/tui-regress-checks.ts +33 -13
  327. package/scripts/release-loop/auto-approve-node.ts +1 -1
  328. package/scripts/release-loop/gate-autoheal-sim-evidence.ts +60 -0
  329. package/scripts/release-loop/gate-baseline-receipt.ts +47 -9
  330. package/scripts/release-loop/gate-image-pin.ts +81 -0
  331. package/scripts/release-loop/gate-method.ts +139 -0
  332. package/scripts/release-loop/gate-node-sim.ts +207 -0
  333. package/scripts/release-loop/gate-node.ts +463 -64
  334. package/scripts/release-loop/gate-pod-image-sticky-plan.ts +99 -0
  335. package/scripts/release-loop/gate-radius-live.ts +97 -13
  336. package/scripts/release-loop/gate-shard-dispatch.ts +43 -0
  337. package/scripts/release-loop/gate-traffic-mode.ts +151 -3
  338. package/scripts/release-loop/gate-train-receipts.ts +122 -0
  339. package/scripts/release-loop/node-verdict.ts +38 -25
  340. package/scripts/release-loop/preflight.ts +362 -8
  341. package/scripts/release-loop/resume-release.ts +83 -8
  342. package/scripts/release-loop/unattended-release.ts +20 -9
  343. package/scripts/rhythm/daily.ts +36 -4
  344. package/scripts/rhythm/linear-progress-sync.ts +298 -0
  345. package/scripts/ux-sim.ts +18 -1
  346. package/scripts/video-pipeline.ts +9 -1
  347. package/scripts/warm-pool-provider-config.ts +286 -0
  348. package/skills/omni-crawl/SKILL.md +5 -2
  349. package/skills/omni-crawl/scripts/main.ts +84 -23
  350. package/src/acp/agent-manager.ts +1 -0
  351. package/src/acp/codex-app-server-agent.ts +33 -0
  352. package/src/acp/codex-app-server-client.ts +153 -16
  353. package/src/acp/core-turn-bridge.ts +27 -9
  354. package/src/acp/event-router.ts +20 -1
  355. package/src/acp/server.ts +6 -0
  356. package/src/agent/registry.ts +2 -0
  357. package/src/agent/task-notification.ts +25 -5
  358. package/src/agent/types.ts +6 -0
  359. package/src/agent-mission/browser-roundtrip-coordinator.ts +85 -0
  360. package/src/agent-mission/claude-headless.ts +4 -1
  361. package/src/agent-mission/codex-exec.ts +105 -0
  362. package/src/agent-mission/driver.ts +192 -11
  363. package/src/agent-mission/grok-auth-status.ts +47 -0
  364. package/src/agent-mission/hand-hooks.ts +101 -0
  365. package/src/agent-mission/mission-cli.ts +63 -4
  366. package/src/agent-mission/mission-hand-reply.ts +118 -0
  367. package/src/agent-mission/mission-line.ts +180 -0
  368. package/src/agent-mission/mission-out.ts +833 -0
  369. package/src/agent-mission/tool-install.ts +200 -3
  370. package/src/agent-substrate/context-strategy.ts +4 -4
  371. package/src/agent-substrate/self-review-cli.ts +178 -13
  372. package/src/agents/general-purpose.md +1 -1
  373. package/src/auto-research/research-turn.ts +211 -53
  374. package/src/autopilot/pr-manager.ts +69 -10
  375. package/src/autopilot/pty-control-loop.ts +2 -0
  376. package/src/boot/daemon-tools/self-implement.ts +3 -1
  377. package/src/boot/daemon-tools/web-search.ts +1 -2
  378. package/src/briefing/brief-items.ts +55 -11
  379. package/src/capture/tui-self-report.ts +22 -6
  380. package/src/chat/index.ts +1 -1
  381. package/src/cli/agent-cli.ts +2 -1
  382. package/src/cli/catalog-cli.ts +31 -0
  383. package/src/cli/connector-cli.ts +16 -0
  384. package/src/cli/doctor-fix.ts +2 -2
  385. package/src/cli/fixtures/review-loop-breaker/opwaiver-32646-1694ccc7a170.json +1 -0
  386. package/src/cli/fixtures/review-loop-breaker/opwaiver-32853-bd8f73595c83.json +1 -0
  387. package/src/cli/fixtures/review-loop-breaker/opwaiver-33097-1cc85900413c.json +1 -0
  388. package/src/cli/fixtures/review-loop-breaker/opwaiver-33106-972f31e4a3ca.json +1 -0
  389. package/src/cli/fixtures/review-loop-breaker/opwaiver-33113-3ab51f05968f.json +1 -0
  390. package/src/cli/fixtures/review-loop-breaker/pr-33097-1cc85900413c.json +1 -0
  391. package/src/cli/intake-source-cli.ts +44 -8
  392. package/src/cli/msg-cli.ts +32 -3
  393. package/src/cli/pr-cli.ts +21 -1
  394. package/src/cli/pr-land-heavy-remote.ts +75 -5
  395. package/src/cli/pr-land-overlap-evidence.ts +113 -2
  396. package/src/cli/pr-land-pod-shadow-job.ts +202 -4
  397. package/src/cli/pr-land-pod-shadow.ts +9 -2
  398. package/src/cli/release-checklist-read-cli.ts +57 -19
  399. package/src/cli/release-cli.ts +23 -3
  400. package/src/cli/research-cli.ts +13 -5
  401. package/src/cli/setup-cli.ts +166 -6
  402. package/src/cli/setup-keys.ts +187 -0
  403. package/src/cli/task-plugin-wizard-host.ts +114 -0
  404. package/src/cli/tasks-cli.ts +61 -9
  405. package/src/cli/tui-test-cli.ts +186 -0
  406. package/src/compact/auto.ts +8 -1
  407. package/src/config.ts +4 -2
  408. package/src/connectors/linear-daily-progress.ts +228 -0
  409. package/src/connectors/linear-projector.ts +34 -12
  410. package/src/connectors/linear.ts +151 -7
  411. package/src/control-plane/ledger.ts +52 -2
  412. package/src/control-plane/server.ts +16 -2
  413. package/src/core-turn/deep-turn-bloom.ts +67 -0
  414. package/src/core-turn/research-policy.ts +37 -0
  415. package/src/core-turn/run-core-turn.ts +606 -95
  416. package/src/core-turn/run-goal-loop.ts +18 -0
  417. package/src/core-turn/types.ts +4 -0
  418. package/src/dashboard/chat/acp-chat.ts +10 -0
  419. package/src/dashboard/classic-sidetab-mission-job.ts +161 -0
  420. package/src/dashboard/classic-sidetab-mission-pair.ts +81 -0
  421. package/src/dashboard/classic-sidetab-mission-trio.ts +219 -0
  422. package/src/dashboard/classic-sidetab-mission.ts +347 -0
  423. package/src/dashboard/index.ts +517 -18
  424. package/src/dashboard/input/agent-wake.ts +23 -1
  425. package/src/dashboard/input/chat-main-acp-dispatch.ts +23 -0
  426. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +17 -0
  427. package/src/dashboard/mission-cli-consumer.ts +165 -0
  428. package/src/dashboard/plugin-wizard-runtime.ts +50 -0
  429. package/src/dashboard/plugin-wizard-tool.ts +55 -0
  430. package/src/dashboard/seat-boot-preamble.ts +171 -1
  431. package/src/dashboard/side-basic-runtime.ts +54 -1
  432. package/src/dashboard/sidetab-runtime.ts +90 -1
  433. package/src/dashboard/skill-catalog-preamble.ts +101 -0
  434. package/src/dashboard/skill-detection-runtime.ts +55 -15
  435. package/src/dashboard/slash-runtime/dashboard-handlers.ts +15 -0
  436. package/src/dashboard/terminal-popup-runtime.ts +6 -3
  437. package/src/dashboard/turn-preamble.ts +53 -15
  438. package/src/dashboard/turn-prompt-runtime.ts +4 -2
  439. package/src/decisions/linear-progress-summary.ts +78 -0
  440. package/src/decisions/linear-progress-sync.ts +152 -0
  441. package/src/domains/outbound-alert.ts +49 -11
  442. package/src/domains/telegram-kind-route.ts +16 -9
  443. package/src/graph-runner/arg-allowance.ts +13 -0
  444. package/src/graph-runner/graph-cli.ts +23 -7
  445. package/src/graph-runner/graph-run-api.ts +3 -1
  446. package/src/graph-runner/graph-tick.ts +10 -2
  447. package/src/graph-runner/runner.ts +86 -18
  448. package/src/graph-wizard/mission-compose.ts +407 -12
  449. package/src/grok/agent-search.ts +14 -4
  450. package/src/grok/credential.ts +28 -11
  451. package/src/harness/dispatch-backpressure.ts +54 -1
  452. package/src/harness/dispatch-shadow-compare.ts +74 -0
  453. package/src/harness/harness-cli-command.ts +11 -1
  454. package/src/harness/harness-pod-dispatch.ts +81 -15
  455. package/src/harness/harness-stop.ts +155 -11
  456. package/src/harness/skill-exec.ts +21 -9
  457. package/src/harness/skill-select.ts +1 -1
  458. package/src/hooks/error-report-cloud.ts +101 -0
  459. package/src/hooks/receiver.ts +29 -2
  460. package/src/index.ts +159 -13
  461. package/src/instance/spawn-elanous.ts +6 -4
  462. package/src/intake-plane/actions.ts +354 -0
  463. package/src/intake-plane/adapters/telegram-ambient.ts +34 -18
  464. package/src/intake-plane/intake-sources.ts +78 -8
  465. package/src/intake-plane/items.ts +14 -4
  466. package/src/intake-plane/linear-mission-sync.ts +80 -0
  467. package/src/intake-plane/linear-secretary-runtime.ts +178 -0
  468. package/src/intake-plane/linear-wish.ts +227 -1
  469. package/src/life/life-cli.ts +168 -0
  470. package/src/life/life-kinds.ts +160 -0
  471. package/src/live-supply/budget-consumer.ts +78 -0
  472. package/src/live-supply/read.ts +3 -0
  473. package/src/live-supply/snapshot.ts +45 -0
  474. package/src/llm/provider-credentials.ts +8 -2
  475. package/src/llm.ts +168 -9
  476. package/src/loops/orchestrator/coordinator-shadow.ts +226 -0
  477. package/src/loops/orchestrator/tick.ts +13 -0
  478. package/src/maturity/feature-maturity.ts +4 -4
  479. package/src/msg/msg-sse-server.ts +3 -3
  480. package/src/msg/msg-store.ts +177 -19
  481. package/src/native-tool-catalog.ts +38 -4
  482. package/src/nexus/api/harness-traversal.ts +11 -0
  483. package/src/nexus/api/http-server.ts +37 -1
  484. package/src/nexus/api/mcp-public-allowlist.ts +2 -0
  485. package/src/nexus/index.ts +7 -2
  486. package/src/nexus/outbound/format.ts +9 -0
  487. package/src/nexus/outbound/router.ts +98 -13
  488. package/src/nexus/setup-status.ts +9 -0
  489. package/src/nexus/state/state.ts +3 -0
  490. package/src/oauth/codex-account-store.ts +20 -7
  491. package/src/oauth/codex-owner-mirror.ts +44 -0
  492. package/src/oauth/codex.ts +17 -2
  493. package/src/oauth/fallback-chain.ts +47 -17
  494. package/src/onboarding/first-run-doctor.ts +8 -1
  495. package/src/onboarding/first-run.ts +85 -26
  496. package/src/onboarding/key-setup.ts +103 -0
  497. package/src/onboarding/menu-answer.ts +13 -0
  498. package/src/onboarding/secret-prompt.ts +37 -0
  499. package/src/plugins/install/plugin-install.ts +59 -0
  500. package/src/pr-tool/census.ts +133 -2
  501. package/src/pty-shell/pty-control-ipc.ts +4 -1
  502. package/src/pty-shell/tui-run-state.ts +188 -2
  503. package/src/registry/catalog-server.ts +232 -0
  504. package/src/registry/loader.ts +45 -1
  505. package/src/registry/types.ts +1 -2
  506. package/src/release-loop/checklist-target-path-hint.ts +13 -0
  507. package/src/release-loop/checklist.ts +9 -1
  508. package/src/repl/index.ts +43 -2
  509. package/src/research/axis-fanout.ts +136 -16
  510. package/src/research/bloom-exemplars.ts +3 -1
  511. package/src/research/gap-followup.ts +13 -1
  512. package/src/research/plugin-discovery.ts +36 -14
  513. package/src/research-bridge/invoke.ts +22 -5
  514. package/src/research-bridge/types.ts +2 -0
  515. package/src/self-dev/ask-launch-flow.ts +72 -1
  516. package/src/self-dev/decompose.ts +119 -5
  517. package/src/self-dev/dev-cli.ts +4 -1
  518. package/src/self-dev/dev-pipeline.ts +5 -0
  519. package/src/self-dev/draft-residue.ts +64 -5
  520. package/src/self-dev/graph-front-nodes.ts +2 -1
  521. package/src/self-dev/graph-journey-route.ts +76 -21
  522. package/src/self-dev/launch-preflight-text.ts +5 -6
  523. package/src/self-dev/launch-preflight.ts +58 -0
  524. package/src/self-dev/orchestrate.ts +13 -3
  525. package/src/self-dev/review-provider-fallback.ts +9 -2
  526. package/src/self-dev/run-supervisor.ts +42 -4
  527. package/src/self-dev/run-types.ts +4 -0
  528. package/src/self-dev/shard-aggregate.ts +4 -0
  529. package/src/self-dev/shard-run.ts +36 -15
  530. package/src/self-implement/abandoned-classification.ts +12 -3
  531. package/src/self-implement/budget-gate.ts +7 -0
  532. package/src/self-implement/child-llm-preference.ts +10 -1
  533. package/src/self-implement/doctor-visit.ts +118 -8
  534. package/src/self-implement/elanous-tui-spawn.ts +3 -0
  535. package/src/self-implement/fixtures/tdd-green-missing-passing-child-transcript.txt +2 -0
  536. package/src/self-implement/gate-artifacts.ts +2 -1
  537. package/src/self-implement/goal-author-cli.ts +4 -2
  538. package/src/self-implement/goal-author.ts +684 -7
  539. package/src/self-implement/graph-overlay-yaml.ts +37 -4
  540. package/src/self-implement/graph-overlay.ts +3 -1
  541. package/src/self-implement/graph-profile-yaml.ts +107 -0
  542. package/src/self-implement/graph-yaml.ts +26 -3
  543. package/src/self-implement/headless-elanous-driver.ts +31 -2
  544. package/src/self-implement/heal-intake.ts +112 -4
  545. package/src/self-implement/heal-triage.ts +20 -0
  546. package/src/self-implement/host-regate.ts +27 -4
  547. package/src/self-implement/merge-train.ts +5 -0
  548. package/src/self-implement/off-diff-evidence.ts +249 -5
  549. package/src/self-implement/orchestrator.ts +365 -25
  550. package/src/self-implement/regate-detail.ts +38 -1
  551. package/src/self-implement/rework-child-provider.ts +25 -0
  552. package/src/self-implement/run-chart.ts +122 -0
  553. package/src/self-implement/run-ledger.ts +162 -11
  554. package/src/self-implement/run-stop.ts +188 -4
  555. package/src/self-implement/runtime-overlay-run-steps.ts +95 -0
  556. package/src/self-implement/stop-autoheal.ts +13 -0
  557. package/src/self-implement/tdd-evidence-tags.ts +9 -0
  558. package/src/self-implement/train-gate-receipt.ts +166 -0
  559. package/src/self-implement/train-gate-remote.ts +62 -18
  560. package/src/session/chat.ts +40 -4
  561. package/src/session/session-fanout.ts +2 -0
  562. package/src/session/streaming/acp-stream-sink.ts +2 -1
  563. package/src/session/streaming/chunk-producer.ts +6 -0
  564. package/src/session/streaming/stream-compositor.ts +3 -2
  565. package/src/session-runtime/index.ts +135 -5
  566. package/src/session-runtime/retry-policy.ts +1 -1
  567. package/src/session-runtime/tier-flip.ts +3 -3
  568. package/src/setup/llm-env-detect.ts +3 -0
  569. package/src/setup/service-key-catalog.ts +46 -0
  570. package/src/setup/service-keys.ts +241 -0
  571. package/src/sidetab-core/model.ts +19 -5
  572. package/src/sidetab-core/visible-agent-mission.ts +262 -0
  573. package/src/skills/name-match.ts +20 -0
  574. package/src/skills/tools/agent.ts +53 -6
  575. package/src/skills/tools/omni-search.ts +173 -13
  576. package/src/task-agent/parent-host.ts +10 -0
  577. package/src/task-agent/pod-distributor-entry.ts +3 -0
  578. package/src/task-agent/repair-outcomes.ts +65 -0
  579. package/src/task-agent/task-hand.ts +47 -7
  580. package/src/task-orchestrator/dispatcher.ts +14 -1
  581. package/src/task-orchestrator/linear-capture-events.ts +55 -0
  582. package/src/task-orchestrator/store.ts +16 -5
  583. package/src/task-orchestrator/surfaces/pod-artifact-return.ts +4 -0
  584. package/src/task-orchestrator/surfaces/pod-distributor.ts +48 -0
  585. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +92 -1
  586. package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +38 -1
  587. package/src/task-orchestrator/surfaces/pod-ledger-events.ts +113 -14
  588. package/src/task-orchestrator/surfaces/pod-si-warm-entry.ts +33 -6
  589. package/src/task-orchestrator/surfaces/pod-source-bundle.ts +45 -9
  590. package/src/task-orchestrator/surfaces/pod-source-receive.ts +178 -16
  591. package/src/task-orchestrator/surfaces/pod-source-spec.ts +3 -3
  592. package/src/task-orchestrator/surfaces/pod-warm-switch.ts +2 -0
  593. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +237 -41
  594. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +80 -3
  595. package/src/task-orchestrator/surfaces/self-implement-pod.ts +337 -51
  596. package/src/task-orchestrator/surfaces/self-implement.ts +27 -3
  597. package/src/task-orchestrator/surfaces/warm-reuse-evidence.ts +169 -0
  598. package/src/task-orchestrator/types.ts +14 -0
  599. package/src/telegram.ts +14 -16
  600. package/src/terminal/coding-agent.ts +14 -5
  601. package/src/terminal/session-registry.ts +1 -1
  602. package/src/tokens.ts +35 -2
  603. package/src/tool-hints/gate.ts +1 -0
  604. package/src/tool-runtime/agent-runtime.ts +2 -0
  605. package/src/tool-runtime/browser-hand-runtime.ts +381 -0
  606. package/src/tool-runtime/browser-runtime.ts +2 -1
  607. package/src/tool-runtime/elanous-linear-issue-runtime.ts +76 -0
  608. package/src/tool-runtime/elanous-linear-secretary-runtime.ts +57 -0
  609. package/src/tool-runtime/elanous-skills-list-runtime.ts +5 -1
  610. package/src/tool-runtime/graph-mcp-runtimes.ts +240 -0
  611. package/src/tool-runtime/index.ts +6 -0
  612. package/src/tool-runtime/skill-exec-runtime.ts +33 -13
  613. package/src/tool-runtime/types.ts +4 -0
  614. package/src/tui/entry.ts +38 -5
  615. package/src/tui/sidetab/attach.ts +177 -1
  616. package/src/tui/sidetab/herdr-portal.ts +225 -0
  617. package/src/tui-client/local-chat-turn.ts +26 -13
  618. package/src/tui.ts +22 -0
  619. package/src/user-config.ts +34 -9
  620. package/src/user-intent/types.ts +4 -3
  621. package/src/ux-sim/browser-hand.ts +165 -0
  622. package/src/ux-sim/draft-inventory-builder.ts +198 -0
  623. package/src/ux-sim/fake-browser-page.ts +81 -0
  624. package/src/ux-sim/fake-kubectl.ts +37 -3
  625. package/src/ux-sim/fake-linear-device.ts +31 -0
  626. package/src/ux-sim/fault-pool-cap.ts +11 -6
  627. package/src/ux-sim/graph-engine-sim.ts +47 -0
  628. package/src/ux-sim/linear-secretary.ts +216 -0
  629. package/src/ux-sim/mock-scenario-catalog.json +93 -0
  630. package/src/ux-sim/mock-scenario-catalog.ts +274 -0
  631. package/src/ux-sim/onboarding-first-run-device.ts +31 -21
  632. package/src/ux-sim/scenario.ts +185 -48
  633. package/src/ux-sim/service-key-setup.ts +50 -0
  634. package/src/ux-sim/term-slash-device.ts +74 -0
  635. package/src/ux-sim/turn-throw-sim.ts +31 -0
  636. package/src/version/packed-revision.json +1 -1
  637. package/src/voice/voice-tts-singleton.ts +18 -3
  638. package/src/web-search/exa.ts +77 -0
  639. package/src/web-search/grok.ts +5 -9
  640. package/src/web-search/index.ts +30 -9
  641. package/src/web-search/provider.ts +4 -1
  642. package/src/web-search/x-intent.ts +5 -0
  643. package/apps/pwa/out/_next/static/chunks/1115.434ae2ecb0ad986d.js +0 -149
  644. package/apps/pwa/out/_next/static/chunks/1121.667cec0bcdbb3fdb.js +0 -36
  645. package/apps/pwa/out/_next/static/chunks/1197-54da59d250a6e476.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/1245.1cfd13b26dbd71d6.js +0 -287
  647. package/apps/pwa/out/_next/static/chunks/1494-f93046ff5c5a124d.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/1609.2b312797599b8e45.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/1661.0dd330f3d89f73f3.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/167-0c121e4b47e0f9da.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/1700.cdc2bf8cc685e221.js +0 -90
  652. package/apps/pwa/out/_next/static/chunks/1703-78e46acad29f3cfc.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/1765.679b29625c8e88d4.js +0 -77
  654. package/apps/pwa/out/_next/static/chunks/1971-7efb628c471dc5a0.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/1999-8de7b7bb36801913.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/2073.689dcb2680113d76.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/2198-557d49184104d165.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/221-440ce67fa9f5c839.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/2427-8ed8e98624cbd664.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/2457-725c5827bc003795.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/2491-2718b15a5ccb75a5.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/2527-5c636a43c7cc5dde.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/2692-1027cb16fe4ccf49.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/2773.0e80b9d325fb5635.js +0 -32
  665. package/apps/pwa/out/_next/static/chunks/2873-0f3cb56c8e3528ea.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/3097.864e92bdaa2f4d15.js +0 -79
  667. package/apps/pwa/out/_next/static/chunks/3136-d6870ba63300a93e.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/3173-0289113d434e83b7.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/325-dd9208a1a0ab7ce4.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/3283.528f430dd043fb4e.js +0 -74
  671. package/apps/pwa/out/_next/static/chunks/3295.cc8cb13b8f0dae1a.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/3688-86e3b88abf18cb3b.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/3804-7220467a5473a8df.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/3808.3e1e247ce7bdf889.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/3927.b5473ad109da44c5.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/3934-98ea94832e194796.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/4156.ba4de4a3664f04b4.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/4297-239ca82f293faab0.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/4320-dcc5a7734126f4c9.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/4434.94b4c552a2d91e69.js +0 -148
  681. package/apps/pwa/out/_next/static/chunks/4579.03e4092f73950965.js +0 -226
  682. package/apps/pwa/out/_next/static/chunks/4667.97e31aa38c95c475.js +0 -309
  683. package/apps/pwa/out/_next/static/chunks/4702.4a4adc1f16d7c93b.js +0 -64
  684. package/apps/pwa/out/_next/static/chunks/4815.481501c57b3568d9.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/487-d16e698ef14662d9.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/4888-7a38bf522c9cc6fe.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/5034-30e429d6bb086881.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/5040-35c494e60dadd97d.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/50c6ab1e.81a96e419350909d.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/5154.4b6a836179356f30.js +0 -94
  691. package/apps/pwa/out/_next/static/chunks/5228-a8200df486278f2d.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/5379.97af106d09566f69.js +0 -8
  693. package/apps/pwa/out/_next/static/chunks/5479-b6372e762719f92f.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/5534-699c5cbcbc96c5d7.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/5701.9c4e8f250312eeee.js +0 -24
  696. package/apps/pwa/out/_next/static/chunks/5892.2526d962339662d8.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/5937.c2df9e3447e1f667.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/5941.8210cc93c9202c0a.js +0 -286
  699. package/apps/pwa/out/_next/static/chunks/5975.4004f820ae3cecd5.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/6142-7ccd48795d7abd55.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/6160.bf9177b8c1bfb243.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/6398.71ba0690c8027555.js +0 -27
  703. package/apps/pwa/out/_next/static/chunks/6492.2bd5c10edc1a064e.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/6552.a3840aa7da35ad68.js +0 -62
  705. package/apps/pwa/out/_next/static/chunks/6736.1e36d3ac5fa5e41d.js +0 -24
  706. package/apps/pwa/out/_next/static/chunks/6900.3ccbe069bdd4556a.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/71327eb4.add50b365f94bf3a.js +0 -122
  708. package/apps/pwa/out/_next/static/chunks/7136.deca3e3a2ddaa374.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/7139-ee9f8ed2677a40b3.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/7191.fdc955f7d96064a4.js +0 -1
  711. package/apps/pwa/out/_next/static/chunks/7423-e0aa5d9e2962120e.js +0 -1
  712. package/apps/pwa/out/_next/static/chunks/7453.afc1ea7e05d56a8c.js +0 -1
  713. package/apps/pwa/out/_next/static/chunks/7503-5e6a3d7fe67e4a0c.js +0 -1
  714. package/apps/pwa/out/_next/static/chunks/7761-476fd7bf768abd34.js +0 -1
  715. package/apps/pwa/out/_next/static/chunks/7975.eafb12097a0a9e62.js +0 -1
  716. package/apps/pwa/out/_next/static/chunks/8050-9b364bdef8f71927.js +0 -1
  717. package/apps/pwa/out/_next/static/chunks/8152.64e253c35cccfaae.js +0 -1
  718. package/apps/pwa/out/_next/static/chunks/8190.620f0231b3924bcb.js +0 -1
  719. package/apps/pwa/out/_next/static/chunks/8448.45b6b1f1a99eeb35.js +0 -104
  720. package/apps/pwa/out/_next/static/chunks/8464-e24f10451b658aac.js +0 -1
  721. package/apps/pwa/out/_next/static/chunks/8477.e4c944bb3aa5d2f3.js +0 -1
  722. package/apps/pwa/out/_next/static/chunks/8710.ca385257d5ca422e.js +0 -1
  723. package/apps/pwa/out/_next/static/chunks/8830.627ccf294ec2465c.js +0 -1
  724. package/apps/pwa/out/_next/static/chunks/8880.64c445592f04acaf.js +0 -1
  725. package/apps/pwa/out/_next/static/chunks/8981.c706964c8ba27aff.js +0 -1
  726. package/apps/pwa/out/_next/static/chunks/9053.bd0fffaff8d3f836.js +0 -1
  727. package/apps/pwa/out/_next/static/chunks/9161-c66e723d7ec9d682.js +0 -1
  728. package/apps/pwa/out/_next/static/chunks/9185.1ecdf9b65c0bb684.js +0 -1
  729. package/apps/pwa/out/_next/static/chunks/9356.fccd5f58086b4ff5.js +0 -1
  730. package/apps/pwa/out/_next/static/chunks/9446.dc0406109371d329.js +0 -1
  731. package/apps/pwa/out/_next/static/chunks/9506.dcf25d467a42627e.js +0 -1
  732. package/apps/pwa/out/_next/static/chunks/9541.eb8e2f8480c7feca.js +0 -93
  733. package/apps/pwa/out/_next/static/chunks/9577.ed7582186efa5482.js +0 -1
  734. package/apps/pwa/out/_next/static/chunks/9579.4a8169600fff2058.js +0 -1
  735. package/apps/pwa/out/_next/static/chunks/9642-ff2e039eb62e3b92.js +0 -1
  736. package/apps/pwa/out/_next/static/chunks/9659-8f2323348113ad80.js +0 -1
  737. package/apps/pwa/out/_next/static/chunks/9724.4c5623af2db43153.js +0 -34
  738. package/apps/pwa/out/_next/static/chunks/9869.81a1e24ca682d5a0.js +0 -1
  739. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-8d9d76ea322d855c.js +0 -1
  740. package/apps/pwa/out/_next/static/chunks/app/approvals/page-ed2c4e59f9f1fe21.js +0 -1
  741. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-2dc99e03c5d76ca0.js +0 -1
  742. package/apps/pwa/out/_next/static/chunks/app/board/page-b5a3a788330e920f.js +0 -1
  743. package/apps/pwa/out/_next/static/chunks/app/botlab/page-14949db884bfa672.js +0 -1
  744. package/apps/pwa/out/_next/static/chunks/app/bots/page-ea76c85b36388a97.js +0 -1
  745. package/apps/pwa/out/_next/static/chunks/app/ceo/page-01716d20af62d325.js +0 -1
  746. package/apps/pwa/out/_next/static/chunks/app/chat/page-62baf6881a64b1e9.js +0 -1
  747. package/apps/pwa/out/_next/static/chunks/app/consult/page-f89ba590c2af8afa.js +0 -1
  748. package/apps/pwa/out/_next/static/chunks/app/control/page-22f8b0f78d9637e5.js +0 -1
  749. package/apps/pwa/out/_next/static/chunks/app/decisions/page-817f9d7e6820be80.js +0 -1
  750. package/apps/pwa/out/_next/static/chunks/app/design-check/page-ffb9bc0d2650249a.js +0 -1
  751. package/apps/pwa/out/_next/static/chunks/app/editor/page-f6d0e64873c0f629.js +0 -1
  752. package/apps/pwa/out/_next/static/chunks/app/exec/page-8bfa0d4ba23a209d.js +0 -1
  753. package/apps/pwa/out/_next/static/chunks/app/field/page-f5060462249e32c7.js +0 -1
  754. package/apps/pwa/out/_next/static/chunks/app/healthz/route-8d9d76ea322d855c.js +0 -1
  755. package/apps/pwa/out/_next/static/chunks/app/inside/page-b2049f8b1ef79117.js +0 -1
  756. package/apps/pwa/out/_next/static/chunks/app/intake/page-1446c5fa93907f11.js +0 -1
  757. package/apps/pwa/out/_next/static/chunks/app/layout-b48a7a07c5204156.js +0 -1
  758. package/apps/pwa/out/_next/static/chunks/app/live/page-e974b8c4ca47614c.js +0 -1
  759. package/apps/pwa/out/_next/static/chunks/app/live-run/page-8a919b869bd28594.js +0 -1
  760. package/apps/pwa/out/_next/static/chunks/app/loops/page-d31b8de6bfcd72ed.js +0 -1
  761. package/apps/pwa/out/_next/static/chunks/app/market/page-64765f817909db29.js +0 -1
  762. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-d128c8569a36ee9b.js +0 -1
  763. package/apps/pwa/out/_next/static/chunks/app/morning/page-b2679d357e9b9270.js +0 -1
  764. package/apps/pwa/out/_next/static/chunks/app/not-found-6fabec98a9e7b269.js +0 -1
  765. package/apps/pwa/out/_next/static/chunks/app/observatory/page-048f30149dcf1349.js +0 -1
  766. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-9113181d6b5a2725.js +0 -1
  767. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-1e7a755a13227611.js +0 -1
  768. package/apps/pwa/out/_next/static/chunks/app/outputs/page-3c8f8b67a203cf07.js +0 -1
  769. package/apps/pwa/out/_next/static/chunks/app/page-18032f5437215062.js +0 -1
  770. package/apps/pwa/out/_next/static/chunks/app/reflection/page-da3b739192fd0ee3.js +0 -1
  771. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-d332545571bd6fd1.js +0 -1
  772. package/apps/pwa/out/_next/static/chunks/app/sessions/page-5237aa5b3f3b8ec5.js +0 -1
  773. package/apps/pwa/out/_next/static/chunks/app/settings/page-d16e56c3989c147e.js +0 -1
  774. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-6b6593600869e2cd.js +0 -1
  775. package/apps/pwa/out/_next/static/chunks/app/setup/layout-8d9d76ea322d855c.js +0 -1
  776. package/apps/pwa/out/_next/static/chunks/app/setup/page-29e8b8a8396b55cb.js +0 -1
  777. package/apps/pwa/out/_next/static/chunks/app/share/page-b3414d856a1a7e2f.js +0 -1
  778. package/apps/pwa/out/_next/static/chunks/app/showroom/page-c3affa52b7ce961b.js +0 -1
  779. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f21dddf9f95b6fab.js +0 -1
  780. package/apps/pwa/out/_next/static/chunks/app/term/page-f5a30a24745bf088.js +0 -1
  781. package/apps/pwa/out/_next/static/chunks/app/today/page-8c8569a09b4d4e34.js +0 -1
  782. package/apps/pwa/out/_next/static/chunks/app/trace/page-2ce32722c0243483.js +0 -1
  783. package/apps/pwa/out/_next/static/chunks/app/vault/page-4767b0d9c0a98c6c.js +0 -1
  784. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-116ee1339c387a75.js +0 -1
  785. package/apps/pwa/out/_next/static/chunks/app/workflows/page-35e8c50ca4ef7ffc.js +0 -1
  786. package/apps/pwa/out/_next/static/chunks/app/workspace/page-52e17113356bb891.js +0 -1
  787. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-7458ae05ed2ac1a0.js +0 -1
  788. package/apps/pwa/out/_next/static/chunks/framework-ad6c9dd524ad6ef8.js +0 -1
  789. package/apps/pwa/out/_next/static/chunks/main-app-2ddd1f2b44d6aa59.js +0 -1
  790. package/apps/pwa/out/_next/static/chunks/main-e3d82bdc358d20c5.js +0 -1
  791. package/apps/pwa/out/_next/static/chunks/pages/_app-71d5aa3896e1655f.js +0 -1
  792. package/apps/pwa/out/_next/static/chunks/pages/_error-03ffc54e00438546.js +0 -1
  793. package/apps/pwa/out/_next/static/chunks/webpack-56bb89af5a611d0b.js +0 -1
  794. package/apps/pwa/out/_next/static/css/be9019f696217521.css +0 -1
  795. package/apps/pwa/out/_next/static/css/d0a48dc099ed86cf.css +0 -1
  796. /package/apps/pwa/out/_next/static/{GiOLWmt4MqDZePubBjA4Q → Om5xS9jpjSXJCeTNGYEi4}/_ssgManifest.js +0 -0
@@ -28,6 +28,7 @@ import { homedir } from 'node:os';
28
28
  import type { TextInputInternalTurnYieldPort } from '../../chat/index.js';
29
29
  import { debug } from '../../debug/log.js';
30
30
  import type { PendingTaskNotification } from '../../agent/task-notification.js';
31
+ import { CLASSIC_SIDETAB_MISSION_LABEL } from '../classic-sidetab-mission-job.js';
31
32
  import { detectSeatTui, type SeatDetection } from '../seat-boot-preamble.js';
32
33
  import type { InternalTurnRejectReason, StartTurnIfIdleOptions, StartTurnIfIdleResult } from './internal-turn.js';
33
34
 
@@ -77,6 +78,16 @@ function displayName(n: Pick<PendingTaskNotification, 'label' | 'agentName'>): s
77
78
  return ((n.label ?? '').trim() || n.agentName).replace(/\s+/g, ' ').slice(0, 60);
78
79
  }
79
80
 
81
+ /** Late research results remain visible as one compact line without opening a turn. */
82
+ export function formatAgentSupplementNotice(
83
+ n: Pick<PendingTaskNotification, 'label' | 'agentName' | 'state' | 'output'>,
84
+ ): string {
85
+ const summary = n.output.replace(/\s+/gu, ' ').trim();
86
+ const excerpt = summary.length > 180 ? `${summary.slice(0, 177)}…` : summary;
87
+ const status = n.state === 'done' ? '' : ` (${n.state})`;
88
+ return `↳ 보강: ${displayName(n)}${status}${excerpt ? ` — ${excerpt}` : ' — 결과 없음'}`;
89
+ }
90
+
80
91
  /** 채팅 한 줄 — «✓ 위임 끝: <이름> — 다음 턴에 결과»(실패·중단이면 ✗ ⊕ 상태). */
81
92
  export function formatAgentWakeNotice(n: Pick<PendingTaskNotification, 'label' | 'agentName' | 'state'>): string {
82
93
  const name = displayName(n);
@@ -86,7 +97,10 @@ export function formatAgentWakeNotice(n: Pick<PendingTaskNotification, 'label' |
86
97
  }
87
98
 
88
99
  /** 자리 TUI 에서 여는 내부 턴의 입력 — 결과 본문은 turn-preamble 이 `<task-notification>` 으로 싣는다. */
89
- export function formatAgentWakePrompt(n: Pick<PendingTaskNotification, 'label' | 'agentName' | 'state'>): string {
100
+ export function formatAgentWakePrompt(n: Pick<PendingTaskNotification, 'taskId' | 'label' | 'agentName' | 'state'>): string {
101
+ if (n.label === CLASSIC_SIDETAB_MISSION_LABEL) {
102
+ return `[자동 재개] 사이드탭 미션 완료: ${n.taskId} (${n.state}) — <task-notification> 결과를 원래 요청과 대조해 수용·부분 수용·기각을 판단하고, 필요하면 원래 대화를 계속 진행`;
103
+ }
90
104
  return `[자동 재개] 위임 끝: ${displayName(n)} (${n.state}) — <task-notification> 의 결과를 읽고 이어서 처리`;
91
105
  }
92
106
 
@@ -141,6 +155,14 @@ export function createAgentWake(deps: AgentWakeDeps): AgentWakeController {
141
155
  return false;
142
156
  }
143
157
  handled.add(n.taskId);
158
+ if (n.completionDelivery === 'supplement') {
159
+ let notifyError: string | null = null;
160
+ try { deps.notify(formatAgentSupplementNotice(n)); } catch (error) {
161
+ notifyError = error instanceof Error ? error.message : String(error);
162
+ }
163
+ log('tui.agent-wake', 'supplemented', { ...base, shown: notifyError === null, ...(notifyError !== null ? { notifyError } : {}) });
164
+ return true;
165
+ }
144
166
  // 그리기 실패가 큐·형제 리스너를 막지 않는다 — 대신 관측에 남긴다(알림이 실제로 안 보였음을 볼 수 있게).
145
167
  let notifyError: string | null = null;
146
168
  try { deps.notify(formatAgentWakeNotice(n)); } catch (error) {
@@ -127,6 +127,29 @@ export function dispatchDashboardChatMainAcpSend(
127
127
  else interimBodyRanges.push({ start: assistantBodyStart, end: assistantBodyEnd });
128
128
  deps.setChatScrollToTail();
129
129
  },
130
+ replaceText: (fullText) => {
131
+ const insertionIndex = interimBodyRanges.length > 0
132
+ ? Math.min(...interimBodyRanges.map((range) => range.start))
133
+ : deps.chatLines.length;
134
+ for (const { start, end } of [...interimBodyRanges].reverse()) {
135
+ deps.chatLines.splice(start, end - start);
136
+ }
137
+ interimBodyRanges.length = 0;
138
+ accumulated = fullText;
139
+ firstChunk = false;
140
+ assistantTextActive = true;
141
+ assistantRunUsesPrefix = true;
142
+ assistantBodyText = fullText;
143
+ assistantBodyStart = insertionIndex;
144
+ const rendered = deps.formatAssistantLines(fullText);
145
+ rendered.forEach((line, index) => {
146
+ deps.chatLines.splice(insertionIndex + index, 0,
147
+ index === 0 ? `${deps.formatAssistantPrefix(display)} ${line}` : ` ${line}`);
148
+ });
149
+ assistantBodyEnd = insertionIndex + rendered.length;
150
+ interimBodyRanges.push({ start: insertionIndex, end: assistantBodyEnd });
151
+ deps.setChatScrollToTail();
152
+ },
130
153
  foldGoalInterim: (text) => {
131
154
  const verdict = classifyInterimReply(text.split('\n'));
132
155
  if (verdict.interim && interimBodyRanges.length > 0) {
@@ -9,6 +9,7 @@ import type { DashboardTurnBlockAttachLike } from '../turn-message-runtime.js';
9
9
  import type { DashboardAssistantRenderState } from '../turn-tail-runtime.js';
10
10
  import type { SearchPlannerState } from '../../session-runtime/index.js';
11
11
  import { runDashboardPlainTurnStream } from './dashboard-plain-turn-stream.js';
12
+ import { runConfiguredTurnThrowSim, type TurnThrowSim } from '../../ux-sim/turn-throw-sim.js';
12
13
  import {
13
14
  formatFailureNotice, matchFailureText, recordFailureSignatureMatch,
14
15
  } from '../../self-health/signatures.js';
@@ -103,6 +104,8 @@ export interface DashboardChatMainPlainTurnRuntimeDeps {
103
104
  readToolDispatchCount?: () => number | null;
104
105
 
105
106
  attachChatStreamingKeys: (abortCtrl: AbortController) => () => void;
107
+ /** Test-injectable turn-body failure. Omitted in ordinary callers; the configured simulation remains inert by default. */
108
+ turnThrowSim?: TurnThrowSim;
106
109
  /** ⭐ 관측 심 — 형제 `chat-main-entry-runtime` 과 «같은 형태»다(재발명 0 · `OBS-T124`). */
107
110
  debugLog?: (category: string, event: string, payload: Record<string, unknown>, opts?: { level?: 'warn' }) => void;
108
111
  createOptionalSpecs: () => Promise<unknown[]>;
@@ -228,6 +231,7 @@ export async function runDashboardChatMainPlainTurn(
228
231
  cleanedUp = true;
229
232
  attachedCleanupEsc();
230
233
  };
234
+ await (deps.turnThrowSim ?? runConfiguredTurnThrowSim)(stage);
231
235
  // ⛔⭐⭐⭐ **「스트리밍 키 사다리가 «이 턴»에 걸렸나」를 값으로 남긴다**(2026-08-19 · `OBS-T124`).
232
236
  //
233
237
  // 🚨 왜 필요한가 — 대표 제보(*"스트리밍 중 친 발화가 큐에 안 쌓인다"*)를 라이브로 재현했더니
@@ -270,6 +274,7 @@ export async function runDashboardChatMainPlainTurn(
270
274
  // message actually carries the pixels/bytes, not just the token.
271
275
  await deps.loadAttachments(deps.contextRegistry);
272
276
  stage = 'loadAttachments';
277
+ await (deps.turnThrowSim ?? runConfiguredTurnThrowSim)(stage);
273
278
  if (finishIfAborted()) return;
274
279
 
275
280
  const { userMsg } = deps.buildTurnMessage({
@@ -290,6 +295,7 @@ export async function runDashboardChatMainPlainTurn(
290
295
  typeof userMsg.content === 'string' ? userMsg.content : '',
291
296
  );
292
297
  stage = 'beginCodeEditTurn';
298
+ await (deps.turnThrowSim ?? runConfiguredTurnThrowSim)(stage);
293
299
  if (finishIfAborted()) return;
294
300
 
295
301
  const preamble = deps.buildTurnPreamble({
@@ -309,6 +315,7 @@ export async function runDashboardChatMainPlainTurn(
309
315
  const compactChanged = prePassApplied && (deps.chat.history.length !== beforeCompact.length
310
316
  || deps.chat.history.some((message, index) => message !== beforeCompact[index]));
311
317
  stage = 'runAutoCompact';
318
+ await (deps.turnThrowSim ?? runConfiguredTurnThrowSim)(stage);
312
319
  if (finishIfAborted()) return;
313
320
 
314
321
  deps.pushChatLine('');
@@ -317,6 +324,7 @@ export async function runDashboardChatMainPlainTurn(
317
324
  let assistantStart = deps.chatLines.length;
318
325
  let optionalSpecs = await deps.createOptionalSpecs();
319
326
  stage = 'createOptionalSpecs';
327
+ await (deps.turnThrowSim ?? runConfiguredTurnThrowSim)(stage);
320
328
  if (finishIfAborted()) return;
321
329
  if (deps.control) {
322
330
  const signal = findRecentQuickPassSignal({
@@ -355,6 +363,7 @@ export async function runDashboardChatMainPlainTurn(
355
363
  // 기록되므로 request→first-token 구간은 그대로 측정된다. ISO 시각 좌표는
356
364
  // pty record 및 TUI-BOOT-TIME(src/index.ts) 부팅 계측과의 대응용이다.
357
365
  let firstTokenLogged = false;
366
+ let modelRequestStartedAt: number | null = null;
358
367
  const logFirstToken = (chunk: string): void => {
359
368
  if (firstTokenLogged || !chunk || abortCtrl.signal.aborted) return;
360
369
  firstTokenLogged = true;
@@ -362,6 +371,7 @@ export async function runDashboardChatMainPlainTurn(
362
371
  try {
363
372
  deps.debugLog?.('chat.turn', 'first-token', {
364
373
  ms: firstTokenAt - deps.turnStartedAt,
374
+ modelRequestMs: modelRequestStartedAt === null ? null : firstTokenAt - modelRequestStartedAt,
365
375
  turnStartedAt: deps.turnStartedAt,
366
376
  turnStartedAtIso,
367
377
  firstTokenAtIso: new Date(firstTokenAt).toISOString(),
@@ -391,6 +401,13 @@ export async function runDashboardChatMainPlainTurn(
391
401
  const attempt = async (stage: string): Promise<boolean> => {
392
402
  let emitted = false;
393
403
  try {
404
+ modelRequestStartedAt = Date.now();
405
+ try {
406
+ deps.debugLog?.('chat.turn.stage', 'model-request-start', {
407
+ attempt: stage,
408
+ msSinceTurnStart: modelRequestStartedAt - deps.turnStartedAt,
409
+ });
410
+ } catch { /* observation must never delay a turn */ }
394
411
  await deps.acpSession.send({
395
412
  ...opts,
396
413
  // 라우팅 줄은 브리지가 모델 호출 «전»에 보낸다 — 모델 출력이 아니므로 재시도를 막지 않는다.
@@ -0,0 +1,165 @@
1
+ import { mkdtempSync, rmSync, writeFileSync } from 'node:fs';
2
+ import { tmpdir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ import { spawnElanous } from '../instance/spawn-elanous.js';
5
+ import type { AgentCliPreparation } from '../agent-mission/tool-install.js';
6
+
7
+ export interface ClassicMissionCliResult {
8
+ ok: boolean;
9
+ status: 'completed' | 'cancelled' | 'failed';
10
+ interactionId?: string;
11
+ path: string;
12
+ content?: string;
13
+ error?: string;
14
+ }
15
+ interface MissionStatus {
16
+ missionId: string;
17
+ status: 'running' | 'done' | 'completed' | 'cancelled' | 'failed';
18
+ result?: string;
19
+ }
20
+
21
+ const MISSION_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
22
+ // Status is persisted by the CLI bridge; polling every 500 ms would launch up to
23
+ // 7,200 short-lived CLI processes for a one-hour mission. Five seconds keeps
24
+ // eventual completion observable without turning the dashboard into a process loop.
25
+ const POLL_MS = 5_000;
26
+ const MAX_WAIT_MS = 60 * 60 * 1_000;
27
+
28
+ function runCli(args: string[]): Promise<{ code: number | null; stdout: string; stderr: string }> {
29
+ return new Promise((resolve, reject) => {
30
+ // `process.argv[1]` belongs to the parent surface and can be a TUI-only
31
+ // entry. Always route detached mission operations through the installed
32
+ // CLI command, whose `mission` router owns run/status/cancel.
33
+ const child = spawnElanous(args, { executable: 'eln',
34
+ cwd: process.cwd(),
35
+ env: { ...process.env, ELANOUS_FAST_ROUTER: '0' },
36
+ stdio: ['ignore', 'pipe', 'pipe'],
37
+ });
38
+ if (!child.stdout || !child.stderr) { reject(new Error('Installed CLI streams could not be opened')); return; }
39
+ let stdout = '';
40
+ let stderr = '';
41
+ child.stdout.setEncoding('utf8');
42
+ child.stderr.setEncoding('utf8');
43
+ child.stdout.on('data', (chunk: string) => { stdout = `${stdout}${chunk}`.slice(-64_000); });
44
+ child.stderr.on('data', (chunk: string) => { stderr = `${stderr}${chunk}`.slice(-8_000); });
45
+ child.once('error', reject);
46
+ child.once('close', (code) => resolve({ code, stdout, stderr }));
47
+ });
48
+ }
49
+
50
+ function parseJson<T>(result: { code: number | null; stdout: string; stderr: string }): T {
51
+ if (result.code !== 0) throw new Error('Mission CLI command failed');
52
+ try { return JSON.parse(result.stdout) as T; }
53
+ catch { throw new Error('Mission CLI returned invalid JSON'); }
54
+ }
55
+
56
+ const delay = (ms: number): Promise<void> => new Promise((resolve) => setTimeout(resolve, ms));
57
+
58
+ export interface MissionCliConsumerDeps {
59
+ runCli?: typeof runCli;
60
+ delay?: (ms: number) => Promise<void>;
61
+ now?: () => number;
62
+ prepareAgentCli?: (agent: 'codex' | 'claude') => Promise<AgentCliPreparation>;
63
+ }
64
+
65
+ export interface StartedClassicMissionCliJob {
66
+ ok: true;
67
+ status: 'running';
68
+ interactionId: string;
69
+ path: string;
70
+ startedAt: number;
71
+ completion: Promise<ClassicMissionCliResult>;
72
+ }
73
+
74
+ export type StartClassicMissionCliResult = StartedClassicMissionCliJob | ClassicMissionCliResult;
75
+
76
+ export function redactMissionResultPath(text: string, path?: string): string {
77
+ return path ? text.replaceAll(path, '[internal result]') : text;
78
+ }
79
+
80
+ export function isClassicMissionId(value: string): boolean {
81
+ return MISSION_ID.test(value);
82
+ }
83
+
84
+ /** Explicitly cancel a detached sidetab mission; parent-turn aborts never call this. */
85
+ export async function cancelClassicMissionCli(interactionId: string, executeCli: typeof runCli = runCli): Promise<boolean> {
86
+ if (!isClassicMissionId(interactionId)) return false;
87
+ const result = parseJson<{ missionId: string; status: string; cancelled: boolean }>(
88
+ await executeCli(['mission', 'cancel', interactionId, '--json']),
89
+ );
90
+ return result.missionId === interactionId && result.cancelled === true && result.status === 'cancelled';
91
+ }
92
+
93
+ /** Start a detached mission and return its identity immediately; poll results independently. */
94
+ export async function startClassicMissionCli(input: {
95
+ agent: 'codex' | 'claude';
96
+ prompt: string;
97
+ linearIssueId?: string;
98
+ onInteractionId?: (interactionId: string) => void;
99
+ }, deps: MissionCliConsumerDeps = {}): Promise<StartClassicMissionCliResult> {
100
+ const executeCli = deps.runCli ?? runCli;
101
+ const wait = deps.delay ?? delay;
102
+ const now = deps.now ?? Date.now;
103
+ if (deps.prepareAgentCli) {
104
+ try {
105
+ const prepared = await deps.prepareAgentCli(input.agent);
106
+ if (!prepared.ready) return { ok: false, status: 'failed', path: '', error: prepared.message };
107
+ } catch {
108
+ return { ok: false, status: 'failed', path: '', error: `${input.agent}: 설치·로그인 상태를 확인하지 못했습니다` };
109
+ }
110
+ }
111
+ const tempRoot = mkdtempSync(join(tmpdir(), 'elanous-classic-mission-'));
112
+ const promptPath = join(tempRoot, 'prompt.txt');
113
+ const outputPath = join(tempRoot, 'result.md');
114
+ let interactionId: string | undefined;
115
+ const startedAt = now();
116
+ try {
117
+ writeFileSync(promptPath, input.prompt, { encoding: 'utf8', mode: 0o600 });
118
+ const launched = parseJson<{ missionId: string; status: 'running' }>(await executeCli([
119
+ 'mission', 'run', '--agent', input.agent, '--prompt-file', promptPath, '--out', outputPath,
120
+ ...(input.linearIssueId ? ['--linear-issue-id', input.linearIssueId] : []), '--json',
121
+ ]));
122
+ if (!isClassicMissionId(launched.missionId) || launched.status !== 'running') throw new Error('Mission CLI returned an invalid interaction ID');
123
+ interactionId = launched.missionId;
124
+ try { input.onInteractionId?.(interactionId); } catch { /* telemetry must not interrupt mission startup */ }
125
+ const completion = (async (): Promise<ClassicMissionCliResult> => {
126
+ try {
127
+ while (now() - startedAt < MAX_WAIT_MS) {
128
+ const missionStatus: MissionStatus = parseJson<MissionStatus>(await executeCli(['mission', 'status', interactionId!, '--json']));
129
+ if (missionStatus.missionId !== interactionId) throw new Error('Mission status did not match its interaction ID');
130
+ // `eln mission status --json` exposes completed records as `done`.
131
+ // Keep `completed` accepted for compatible bridges and existing callers.
132
+ if (missionStatus.status === 'done' || missionStatus.status === 'completed') {
133
+ if (typeof missionStatus.result !== 'string' || !missionStatus.result.trim()) throw new Error('Mission completed without a final answer');
134
+ return { ok: true, status: 'completed', interactionId, path: outputPath, content: missionStatus.result };
135
+ }
136
+ if (missionStatus.status !== 'running') return {
137
+ ok: false,
138
+ status: missionStatus.status === 'cancelled' ? 'cancelled' : 'failed',
139
+ interactionId,
140
+ path: outputPath,
141
+ error: 'Mission did not complete successfully',
142
+ };
143
+ await wait(POLL_MS);
144
+ }
145
+ await executeCli(['mission', 'cancel', interactionId!, '--json']).catch(() => undefined);
146
+ return { ok: false, status: 'failed', interactionId, path: outputPath, error: 'Mission exceeded the sidetab time limit' };
147
+ } catch {
148
+ return { ok: false, status: 'failed', interactionId, path: outputPath, error: 'Mission CLI could not complete the request' };
149
+ } finally {
150
+ try { rmSync(tempRoot, { recursive: true, force: true }); } catch { /* temp cleanup cannot replace mission outcome */ }
151
+ }
152
+ })();
153
+ return {
154
+ ok: true,
155
+ status: 'running',
156
+ interactionId,
157
+ path: outputPath,
158
+ startedAt,
159
+ completion,
160
+ };
161
+ } catch {
162
+ try { rmSync(tempRoot, { recursive: true, force: true }); } catch { /* temp cleanup cannot replace mission outcome */ }
163
+ return { ok: false, status: 'failed', ...(interactionId ? { interactionId } : {}), path: outputPath, error: 'Mission CLI could not complete the request' };
164
+ }
165
+ }
@@ -0,0 +1,50 @@
1
+ import { debug } from '../debug/log.js';
2
+ import { effectiveInstanceRoot } from '../instance/resolve.js';
3
+ import { createTaskPluginWizardHostDeps, type TaskPluginWizardHostResult } from '../cli/task-plugin-wizard-host.js';
4
+ import { defaultTaskLauncher } from '../cli/tasks-cli.js';
5
+ import { handTask, type HandTaskOptions } from '../task-agent/task-hand.js';
6
+ import { TASK_CARD_PREFIX } from '../task-agent/task-card-prefix.js';
7
+ import type { PluginMaker, PluginWizardDeps } from '../graph-wizard/mission-compose.js';
8
+ import { createTuiPluginWizardTool, type TuiPluginWizardTool } from './plugin-wizard-tool.js';
9
+ import type { TuiPluginWizardRequest } from './plugin-wizard-tool.js';
10
+
11
+ export interface DashboardPluginWizardRuntimePorts {
12
+ runMissionPair: (request: {
13
+ runId: string;
14
+ prompt: string;
15
+ context?: TuiPluginWizardRequest['context'];
16
+ }) => Promise<Partial<Record<PluginMaker, TaskPluginWizardHostResult>>>;
17
+ getWorkspace: () => string;
18
+ taskHand?: (options: HandTaskOptions) => Promise<unknown>;
19
+ launcher?: HandTaskOptions['launcher'];
20
+ onEvent?: PluginWizardDeps['onEvent'];
21
+ }
22
+
23
+ /** Connect the TUI entry tool to handTask and the existing plugin composer without blocking the ACP turn. */
24
+ export function createDashboardPluginWizardRuntime(ports: DashboardPluginWizardRuntimePorts): TuiPluginWizardTool {
25
+ return createTuiPluginWizardTool(async (request) => {
26
+ const pluginWizardDeps = createTaskPluginWizardHostDeps({
27
+ runMissionPair: ({ prompt }) => ports.runMissionPair({ runId: request.runId, prompt, ...(request.context ? { context: request.context } : {}) }),
28
+ onEvent: ports.onEvent ?? ((event) => {
29
+ if (event.step !== 'validate' || !event.detail || typeof event.detail !== 'object') return;
30
+ const winner = (event.detail as { winner?: unknown }).winner;
31
+ if (winner) debug.log('wizard.validate', 'winner-adopted', { runId: event.wizardId, ts: event.ts, winner });
32
+ }),
33
+ });
34
+ const runHandTask = ports.taskHand ?? handTask;
35
+ await runHandTask({
36
+ id: `${TASK_CARD_PREFIX}plugin-${request.runId.replaceAll('-', '').slice(0, 20)}`,
37
+ text: request.mission,
38
+ seat: 'TC',
39
+ live: true,
40
+ launcher: ports.launcher ?? defaultTaskLauncher,
41
+ pluginWizard: {
42
+ missing: request.missing,
43
+ root: effectiveInstanceRoot(),
44
+ workspace: ports.getWorkspace(),
45
+ wizardId: request.runId,
46
+ },
47
+ pluginWizardDeps,
48
+ });
49
+ });
50
+ }
@@ -0,0 +1,55 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { debug } from '../debug/log.js';
3
+ import type { LLMToolSpec } from '../llm.js';
4
+ import type { ClassicSidetabMissionDispatchContext } from './classic-sidetab-mission.js';
5
+
6
+ export const TUI_PLUGIN_WIZARD_TOOL_NAME = 'StartPluginWizard';
7
+
8
+ export interface TuiPluginWizardRequest {
9
+ runId: string;
10
+ mission: string;
11
+ missing: string;
12
+ context?: ClassicSidetabMissionDispatchContext;
13
+ }
14
+
15
+ export interface TuiPluginWizardTool {
16
+ getTools(existing: readonly LLMToolSpec[]): LLMToolSpec[];
17
+ dispatchTool(name: string, args: unknown, context?: ClassicSidetabMissionDispatchContext): Promise<unknown> | undefined;
18
+ }
19
+
20
+ /** Add a non-blocking TUI entry point; the injected host runs the shared task/plugin-wizard path. */
21
+ export function createTuiPluginWizardTool(start: (request: TuiPluginWizardRequest) => Promise<void>, createId: () => string = randomUUID): TuiPluginWizardTool {
22
+ const spec: LLMToolSpec = {
23
+ name: TUI_PLUGIN_WIZARD_TOOL_NAME,
24
+ description: 'When a needed capability is missing, start the plugin wizard in this TUI session. It asks a short question, searches trusted plugins, and if needed launches the visible Codex and Claude side-tab pair. Returns a run ID immediately; check the task notification for completion.',
25
+ parameters: {
26
+ type: 'object',
27
+ properties: {
28
+ mission: { type: 'string', minLength: 1, description: 'The active task to complete after installing or creating the tool.' },
29
+ missing: { type: 'string', minLength: 1, description: 'The missing tool or capability.' },
30
+ },
31
+ required: ['mission', 'missing'],
32
+ additionalProperties: false,
33
+ },
34
+ };
35
+
36
+ return {
37
+ getTools: (existing) => [...existing, spec],
38
+ dispatchTool(name, args, context) {
39
+ if (name !== TUI_PLUGIN_WIZARD_TOOL_NAME) return undefined;
40
+ const output = (status: 'running' | 'error', body: string, id: string | null = null) => ({ status, body, artifacts: [], id });
41
+ if (!args || typeof args !== 'object' || Array.isArray(args)) return Promise.resolve(output('error', 'arguments must be an object'));
42
+ const input = args as Record<string, unknown>;
43
+ if (Object.keys(input).some((key) => key !== 'mission' && key !== 'missing')) return Promise.resolve(output('error', 'arguments contain unsupported fields'));
44
+ const mission = typeof input.mission === 'string' ? input.mission.trim() : '';
45
+ const missing = typeof input.missing === 'string' ? input.missing.trim() : '';
46
+ if (!mission || !missing) return Promise.resolve(output('error', 'mission and missing capability are required'));
47
+ const runId = createId();
48
+ void Promise.resolve().then(() => start({ runId, mission, missing, ...(context ? { context } : {}) })).catch((error) => {
49
+ try { debug.log('plugin-wizard.tool', 'start-failed', { runId, reason: error instanceof Error ? error.message : String(error) }, { level: 'error' }); }
50
+ catch { /* failure reporting must not re-enter the tool boundary */ }
51
+ });
52
+ return Promise.resolve(output('running', `Plugin wizard started in the background (run ${runId}).`, runId));
53
+ },
54
+ };
55
+ }
@@ -95,6 +95,9 @@ export const SEAT_INTENT_ESCALATION_FLOW =
95
95
  export const SEAT_MEMORY_RECALL_PREFIX = '🧠 직전 인계 회상:';
96
96
  export const SEAT_MEMORY_RECALL_MAX_CHARS = 360;
97
97
  const RECALL_READ_BYTES = 16_384;
98
+ export const SEAT_MEMORY_IMPORT_PREFIX = '🧠 자리 기억 스냅샷:';
99
+ export const SEAT_MEMORY_IMPORT_MAX_CHARS = 2_000;
100
+ const SEAT_MEMORY_HANDOFF_MAX_AGE_MS = 24 * 60 * 60 * 1_000;
98
101
  /** 발췌(제목 — 첫 줄)에 남길 최소 글자 — 이보다 모자라면 전문 경로를 짧은 꼴로 바꾼다. */
99
102
  const RECALL_MIN_EXCERPT = 60;
100
103
  /** 줄에 싣는 파일명 최대 글자. */
@@ -184,6 +187,162 @@ function seatMemoryRecallLine(seatDir: string): string | null {
184
187
  return recall.line;
185
188
  }
186
189
 
190
+ interface SeatMemorySource {
191
+ path: string | null;
192
+ mtimeMs: number | null;
193
+ }
194
+
195
+ function regularMemorySource(path: string): SeatMemorySource {
196
+ try {
197
+ const stat = lstatSync(path);
198
+ return stat.isFile() ? { path, mtimeMs: stat.mtimeMs } : { path: null, mtimeMs: null };
199
+ } catch {
200
+ return { path: null, mtimeMs: null };
201
+ }
202
+ }
203
+
204
+ function handoffPriorityExcerpt(path: string): { priority: string | null; evidence: string | null } {
205
+ // Only inspect a bounded prefix and extract explicit priority/evidence labels;
206
+ // arbitrary handoff prose can contain account values or stale historical claims.
207
+ const lines = readHead(path).split(/\r\n|[\n\r\u0085\u2028\u2029]/);
208
+ const priorityLabel = /^\s*(?:[-*]\s*)?(?:#{1,6}\s*)?(?:다음 한 수|현재 우선순위|1순위|최우선|next step|priority)\s*[::]/i;
209
+ const evidenceLabel = /^\s*(?:[-*]\s*)?(?:#{1,6}\s*)?(?:근거|증거|evidence|source)\s*[::]/i;
210
+ const priorityRaw = lines.find((line) => priorityLabel.test(line.replace(/\*\*/g, '')));
211
+ const evidenceRaw = lines.find((line) => evidenceLabel.test(line.replace(/\*\*/g, '')));
212
+ const cleanExcerpt = (line: string | undefined): string | null => {
213
+ if (!line || SHELL_CHARS.test(line)) return null;
214
+ const clean = oneLine(line.replace(/\*\*/g, '').replace(/^\s*[-*]\s*/, ''));
215
+ return clean || null;
216
+ };
217
+ const evidencePathStart = /(?:seat-state|docs|src|apps|test)\//gu;
218
+ const evidencePathPattern = /(?:seat-state|docs|src|apps|test)\/[\p{L}\p{N}._/@+-]+/u;
219
+ const paths = (line: string | undefined): { values: string[]; complete: boolean } => {
220
+ if (!line) return { values: [], complete: true };
221
+ const values: string[] = [];
222
+ let complete = true;
223
+ for (const startMatch of line.matchAll(evidencePathStart)) {
224
+ const start = startMatch.index ?? -1;
225
+ if (start < 0) {
226
+ complete = false;
227
+ continue;
228
+ }
229
+ const candidate = line.slice(start).match(evidencePathPattern)?.[0];
230
+ if (!candidate) {
231
+ complete = false;
232
+ continue;
233
+ }
234
+ const after = line[start + candidate.length];
235
+ const afterNext = line[start + candidate.length + 1];
236
+ const boundary = after === undefined || /\s/u.test(after)
237
+ || (/[;,!?()[\]{}<>]/u.test(after) && (afterNext === undefined || /\s/u.test(afterNext)));
238
+ const spacedTail = after === ' '
239
+ ? line.slice(start + candidate.length).match(/^\s+([^·,;!?]*?)(?=\s*[·,;!?]|$)/u)?.[1]?.trim()
240
+ : undefined;
241
+ const looksLikeSpacedPath = Boolean(spacedTail && /\.[\p{L}\p{N}]{1,12}$/u.test(spacedTail));
242
+ if (!boundary || looksLikeSpacedPath) {
243
+ // Never publish a prefix when the source may contain a wider path token.
244
+ complete = false;
245
+ continue;
246
+ }
247
+ values.push(redactSecretText(candidate));
248
+ }
249
+ return { values, complete };
250
+ };
251
+ const priorityPaths = paths(priorityRaw);
252
+ const priority = priorityPaths.complete
253
+ ? cleanExcerpt(priorityRaw)?.replace(new RegExp(evidencePathPattern.source, 'gu'), '〔경로는 근거 포인터 참조〕') ?? null
254
+ : null;
255
+ const evidencePaths = [...new Set([...priorityPaths.values, ...paths(evidenceRaw).values])].slice(0, 2);
256
+ return {
257
+ priority: priority ? priority.slice(0, 700) : null,
258
+ evidence: evidencePaths.length ? evidencePaths.join(' · ') : null,
259
+ };
260
+ }
261
+
262
+ /** Session-start only: bounded source pointers plus a short, explicitly labeled priority excerpt.
263
+ * The card cache keeps this snapshot stable for the conversation; newer files appear next session. */
264
+ function buildSeatMemoryImport(cwd: string, seat: string, home: string, now: Date): string {
265
+ const seatDir = join(home, 'elanous-hq', 'seat-state', seat);
266
+ const handoff = newestHandoff(seatDir);
267
+ const handoffSource = handoff ? { path: handoff.path, mtimeMs: handoff.mtime.getTime() } : { path: null, mtimeMs: null };
268
+ const memory = regularMemorySource(join(home, 'elanous-hq', 'seat-state', 'memory', 'MEMORY.md'));
269
+ const knowhowCandidates = [
270
+ join(cwd, 'docs', 'roles', seat, 'KNOWHOW.md'),
271
+ join(home, 'elanous-hq', 'seats', seat, 'docs', 'roles', seat, 'KNOWHOW.md'),
272
+ ];
273
+ const knowhow = knowhowCandidates.map(regularMemorySource).find((source) => source.path) ?? { path: null, mtimeMs: null };
274
+ const stamp = (source: SeatMemorySource): string => source.mtimeMs === null ? '미상' : new Date(source.mtimeMs).toISOString();
275
+ const stale = (source: SeatMemorySource): boolean => source.mtimeMs === null || handoffSource.mtimeMs === null ||
276
+ now.getTime() - handoffSource.mtimeMs > SEAT_MEMORY_HANDOFF_MAX_AGE_MS ||
277
+ handoffSource.mtimeMs > now.getTime() || source.mtimeMs > now.getTime() || source.mtimeMs < handoffSource.mtimeMs;
278
+ const handoffStale = handoffSource.mtimeMs === null || now.getTime() - handoffSource.mtimeMs > SEAT_MEMORY_HANDOFF_MAX_AGE_MS ||
279
+ handoffSource.mtimeMs > now.getTime();
280
+ const handoffLabel = handoffSource.path
281
+ ? `seat-state/${seat}/${redactSecretText(basename(handoffSource.path))}`
282
+ : `seat-state/${seat}/HANDOFF-*.md 없음`;
283
+ const memoryLabel = memory.path ? 'seat-state/memory/MEMORY.md' : 'seat-state/memory/MEMORY.md 없음';
284
+ const knowhowLabel = knowhow.path ? `docs/roles/${seat}/KNOWHOW.md` : `docs/roles/${seat}/KNOWHOW.md 없음`;
285
+ const sourceLines = [
286
+ `- 인계 포인터: ${handoffLabel} · 갱신 ${stamp(handoffSource)}${handoffStale ? ' · stale/unknown' : ''}`,
287
+ `- 공통 기억 색인: ${memoryLabel} · 갱신 ${stamp(memory)}${stale(memory) ? ' · stale/unknown' : ''}`,
288
+ `- 역할 노하우: ${knowhowLabel} · 갱신 ${stamp(knowhow)}${stale(knowhow) ? ' · stale/unknown' : ''}`,
289
+ ];
290
+ let priority: string | null = null;
291
+ let evidence: string | null = null;
292
+ if (!handoffStale && handoffSource.path) {
293
+ try {
294
+ ({ priority, evidence } = handoffPriorityExcerpt(handoffSource.path));
295
+ } catch { /* missing/unreadable excerpt is unknown, but pointers remain useful */ }
296
+ }
297
+ const priorityPrefix = '- 현재 우선순위(인계 발췌): ';
298
+ const evidencePrefix = '- 근거 포인터(인계 발췌): ';
299
+ const priorityAvailable = !handoffStale && Boolean(priority);
300
+ const evidencePaths = !handoffStale && evidence ? evidence.split(' · ') : [];
301
+ const summary = priorityAvailable ? priorityPrefix : '- 현재 우선순위: 미관측(오래됐거나 명시된 우선순위 줄이 없음) · unknown';
302
+ const evidenceLine = evidencePaths.length ? evidencePrefix : '- 근거 포인터: 미관측 · 원본 확인 필요';
303
+ const guidance = 'stale/unknown 또는 상충하는 기억은 사실로 단정하지 말고 unknown으로 답한 뒤 위 포인터의 정본을 확인한다. 비밀·계정 값은 기억에서 가져오지 않는다.';
304
+ const fixedLines = [
305
+ `${SEAT_MEMORY_IMPORT_PREFIX} 읽기 전용 · 세션 시작 스냅샷 · 다음 세션부터 갱신`,
306
+ ...sourceLines,
307
+ summary,
308
+ evidenceLine,
309
+ guidance,
310
+ ];
311
+ // Reserve space separately for each excerpt. Never slice the assembled card:
312
+ // that could cut a path in half or remove the stale/unknown safety guidance.
313
+ const excerptRoom = Math.max(0, SEAT_MEMORY_IMPORT_MAX_CHARS - fixedLines.join('\n').length);
314
+ const excerptCount = Number(priorityAvailable) + Number(evidencePaths.length > 0);
315
+ const excerptBudget = Math.min(520, Math.floor(excerptRoom / (excerptCount || 1)));
316
+ const priorityText = priorityAvailable
317
+ ? (priority!.length > excerptBudget ? `${priority!.slice(0, Math.max(0, excerptBudget - 1))}…` : priority!)
318
+ : '';
319
+ const evidenceParts: string[] = [];
320
+ let evidenceRoom = excerptBudget;
321
+ let omittedEvidencePaths = 0;
322
+ for (const path of evidencePaths) {
323
+ const separator = evidenceParts.length ? ' · ' : '';
324
+ if (separator.length + path.length <= evidenceRoom) {
325
+ evidenceParts.push(path);
326
+ evidenceRoom -= separator.length + path.length;
327
+ } else {
328
+ omittedEvidencePaths++;
329
+ }
330
+ }
331
+ let evidenceText = evidenceParts.join(' · ');
332
+ if (omittedEvidencePaths) {
333
+ const note = `${evidenceText ? ' · ' : ''}${omittedEvidencePaths}개 긴 경로 생략(원문 인계 포인터 참조)`;
334
+ if (note.length <= evidenceRoom) evidenceText += note;
335
+ }
336
+ const content = [
337
+ `${SEAT_MEMORY_IMPORT_PREFIX} 읽기 전용 · 세션 시작 스냅샷 · 다음 세션부터 갱신`,
338
+ ...sourceLines,
339
+ `${summary}${priorityText}`,
340
+ `${evidenceLine}${evidenceText}`,
341
+ guidance,
342
+ ].join('\n');
343
+ return content;
344
+ }
345
+
187
346
  function buildCardMessages(cwd: string, deps: SeatBootDeps): { messages: LLMMessage[]; observed: Record<string, unknown> } {
188
347
  const detection = detectSeat(cwd, deps.env ?? process.env);
189
348
  if (!detection) return { messages: [], observed: { reason: 'no-seat' } };
@@ -194,13 +353,24 @@ function buildCardMessages(cwd: string, deps: SeatBootDeps): { messages: LLMMess
194
353
  if (!isSeatDir) return { messages: [], observed: { reason: 'no-seat-state', seat: detection.seat, source: detection.source } };
195
354
  const { sections, unread } = collectSeatBootSections(detection.seat, { home, msgPath: deps.msgPath ?? defaultMsgStorePath() });
196
355
  const card = renderSeatBootCard(detection.seat, sections, null);
197
- const at = (deps.now?.() ?? new Date()).toISOString();
356
+ const snapshotAt = deps.now?.() ?? new Date();
357
+ const at = snapshotAt.toISOString();
198
358
  const recall = seatMemoryRecallLine(seatDir);
359
+ const memoryImport = buildSeatMemoryImport(cwd, detection.seat, home, snapshotAt);
360
+ debug.log('dashboard.seat-boot', 'memory-import', {
361
+ seat: detection.seat,
362
+ chars: memoryImport.length,
363
+ priority: memoryImport.includes('- 현재 우선순위(인계 발췌):'),
364
+ evidence: memoryImport.includes('- 근거 포인터(인계 발췌):'),
365
+ unknown: memoryImport.includes('- 현재 우선순위: 미관측'),
366
+ updatedAt: snapshotAt.toISOString(),
367
+ });
199
368
  const content =
200
369
  `## 자리 부트 카드 — 너는 이 작업 디렉터리의 ${detection.seat} 자리에서 일한다\n` +
201
370
  `(판정: ${detection.source === 'cwd' ? `cwd 의 /seats/${detection.seat}` : 'COORD_ID'} · 세션 시작 스냅샷 ${at} · 이후 바뀐 값은 다시 조회하라)\n` +
202
371
  `사람이 다른 일을 먼저 시키지 않았다면, 첫 답에서 자리 이름·'자리 역할' 절의 역할·안 읽은 우편 수를 각각 명시하고 처리할 일을 제안하라. 역할이 미관측이면 추측하지 말고 미관측이라고 말하라.\n` +
203
372
  (recall ? `${recall}\n` : '') +
373
+ `${memoryImport}\n` +
204
374
  '\n' +
205
375
  `${SEAT_INTENT_ESCALATION_FLOW}\n\n` +
206
376
  card;