elanous 0.2.14 → 0.2.16

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 (350) 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/chunks/{1307-6e7e0377c1db0bdc.js → 1307-b46d45b705e8c9ae.js} +1 -1
  4. package/apps/pwa/out/_next/static/chunks/5977-c952712c87a1f757.js +1 -0
  5. package/apps/pwa/out/_next/static/chunks/899-46946fe8363e1262.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/{9103-7a3ae7f60af3b99f.js → 9103-60fbef33e66f0a46.js} +1 -1
  7. package/apps/pwa/out/_next/static/chunks/app/approvals/page-79c3ed84baaedd03.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/app/autopilot/{page-7b2b4f378354869a.js → page-3cb52e5ea8fc2fa5.js} +1 -1
  9. package/apps/pwa/out/_next/static/chunks/app/board/page-a424ef80885d1743.js +1 -0
  10. package/apps/pwa/out/_next/static/chunks/app/botlab/page-c1e20d7d338713f1.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/app/bots/{page-1512d91c7491ed62.js → page-482c5dbde699947c.js} +1 -1
  12. package/apps/pwa/out/_next/static/chunks/app/ceo/page-1e962b31d1f11081.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/app/chat/{page-a627db94ec6904a0.js → page-8c2d9526164f5d09.js} +1 -1
  14. package/apps/pwa/out/_next/static/chunks/app/consult/page-ffff6d819fbc6e0f.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/app/control/{page-e6b84ab07d3567d5.js → page-a0e2a6d1bfb52fc5.js} +1 -1
  16. package/apps/pwa/out/_next/static/chunks/app/design-check/page-c53598cfce6156f2.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/app/editor/{page-fed69f9759d248d0.js → page-13a63953f53c6a23.js} +1 -1
  18. package/apps/pwa/out/_next/static/chunks/app/exec/{page-15374909d8f1aebd.js → page-5d3c8429d04f3831.js} +1 -1
  19. package/apps/pwa/out/_next/static/chunks/app/field/{page-012a742f81218b01.js → page-3193bdc0bbab047a.js} +1 -1
  20. package/apps/pwa/out/_next/static/chunks/app/inside/page-76270efaee638f17.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/app/intake/{page-99effd9d893a43dc.js → page-6107ca8ddd5e3bdd.js} +1 -1
  22. package/apps/pwa/out/_next/static/chunks/app/{layout-938de57ae0315e46.js → layout-dce686e582c23937.js} +1 -1
  23. package/apps/pwa/out/_next/static/chunks/app/live/page-d3d53b146416e422.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/app/loops/{page-160089123a40dd91.js → page-1a61c7ca1ceb3ae7.js} +1 -1
  25. package/apps/pwa/out/_next/static/chunks/app/market/{page-629e1ede482ec6eb.js → page-51f811fa119308b6.js} +1 -1
  26. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-dacff46049e1557e.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/app/morning/{page-27e99b4e54a849d4.js → page-4167348049166852.js} +1 -1
  28. package/apps/pwa/out/_next/static/chunks/app/not-found-de52e8fdf9095f7a.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/app/observatory/page-36a7d994f4ca0299.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/{page-32cde713be47cddb.js → page-ca3952cd78a83ca2.js} +1 -1
  31. package/apps/pwa/out/_next/static/chunks/app/ops/release/{page-e7e10cd3386222e5.js → page-5b042736aa113756.js} +1 -1
  32. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-acb749f1e432bcf3.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/app/outputs/page-cd78862707999911.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/app/page-54b9ef8afe6278fd.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/app/reflection/{page-e64caff084f7ce21.js → page-1ebfe049c640e171.js} +1 -1
  36. package/apps/pwa/out/_next/static/chunks/app/scheduler/{page-db07eaffba0df7e3.js → page-57924393e3e4e539.js} +1 -1
  37. package/apps/pwa/out/_next/static/chunks/app/sessions/page-9e0ce6c8129fa641.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-31fa1ce4c4aff9ae.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/app/settings/{page-86f91034bd5cabe5.js → page-0f5cd57ca928f42b.js} +1 -1
  40. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-abe8e3b74bea1ffc.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/app/setup/page-4364ef9f4e7c7f0f.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/app/share/{page-ce4d8a1215ce53a3.js → page-d28573d6792b4275.js} +1 -1
  43. package/apps/pwa/out/_next/static/chunks/app/showroom/{page-58043db78ba519ae.js → page-59f03fda76c03d22.js} +1 -1
  44. package/apps/pwa/out/_next/static/chunks/app/tasks/{page-357750dfb91bf960.js → page-d751de5f8062ff5e.js} +1 -1
  45. package/apps/pwa/out/_next/static/chunks/app/term/{page-274703bc41b71333.js → page-fe1759f94003b32b.js} +1 -1
  46. package/apps/pwa/out/_next/static/chunks/app/today/page-d64c984e855c8c68.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/app/trace/page-86914b0dee8ab7f8.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/app/vault/{page-3b7e821dc492bdfd.js → page-9afdee66b820c76e.js} +1 -1
  49. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-d4aef67abf264874.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/app/workflows/{page-f8da5dc6f3752276.js → page-1ea64acadd704ace.js} +1 -1
  51. package/apps/pwa/out/_next/static/chunks/app/workspace/{page-2f810b18d89ecba6.js → page-3544f154c87b43ee.js} +1 -1
  52. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-30c2073bfc21c004.js +1 -0
  53. package/apps/pwa/out/_next/static/css/001d5fbaee388a25.css +1 -0
  54. package/apps/pwa/out/_next/static/css/{04dabcbcc4bfa6db.css → 085673d826b98b62.css} +1 -1
  55. package/apps/pwa/out/_next/static/rv9cierV0jSOvDBm1g0XB/_buildManifest.js +1 -0
  56. package/apps/pwa/out/approvals/index.html +1 -1
  57. package/apps/pwa/out/approvals/index.txt +15 -15
  58. package/apps/pwa/out/autopilot/index.html +1 -1
  59. package/apps/pwa/out/autopilot/index.txt +15 -15
  60. package/apps/pwa/out/board/index.html +1 -1
  61. package/apps/pwa/out/board/index.txt +15 -15
  62. package/apps/pwa/out/botlab/index.html +1 -1
  63. package/apps/pwa/out/botlab/index.txt +15 -15
  64. package/apps/pwa/out/bots/index.html +1 -1
  65. package/apps/pwa/out/bots/index.txt +15 -15
  66. package/apps/pwa/out/ceo/index.html +1 -0
  67. package/apps/pwa/out/ceo/index.txt +33 -0
  68. package/apps/pwa/out/chat/index.html +1 -1
  69. package/apps/pwa/out/chat/index.txt +15 -15
  70. package/apps/pwa/out/consult/index.html +1 -1
  71. package/apps/pwa/out/consult/index.txt +15 -15
  72. package/apps/pwa/out/control/index.html +1 -1
  73. package/apps/pwa/out/control/index.txt +15 -15
  74. package/apps/pwa/out/design-check/index.html +1 -1
  75. package/apps/pwa/out/design-check/index.txt +15 -15
  76. package/apps/pwa/out/editor/index.html +1 -1
  77. package/apps/pwa/out/editor/index.txt +15 -15
  78. package/apps/pwa/out/exec/index.html +1 -1
  79. package/apps/pwa/out/exec/index.txt +15 -15
  80. package/apps/pwa/out/field/index.html +1 -1
  81. package/apps/pwa/out/field/index.txt +15 -15
  82. package/apps/pwa/out/healthz +1 -1
  83. package/apps/pwa/out/index.html +1 -1
  84. package/apps/pwa/out/index.txt +15 -15
  85. package/apps/pwa/out/inside/index.html +1 -1
  86. package/apps/pwa/out/inside/index.txt +15 -15
  87. package/apps/pwa/out/intake/index.html +1 -1
  88. package/apps/pwa/out/intake/index.txt +15 -15
  89. package/apps/pwa/out/live/index.html +1 -1
  90. package/apps/pwa/out/live/index.txt +15 -15
  91. package/apps/pwa/out/loops/index.html +1 -1
  92. package/apps/pwa/out/loops/index.txt +15 -15
  93. package/apps/pwa/out/market/index.html +1 -1
  94. package/apps/pwa/out/market/index.txt +15 -15
  95. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  96. package/apps/pwa/out/missions/placeholder/index.txt +15 -15
  97. package/apps/pwa/out/morning/index.html +1 -1
  98. package/apps/pwa/out/morning/index.txt +15 -15
  99. package/apps/pwa/out/observatory/index.html +1 -1
  100. package/apps/pwa/out/observatory/index.txt +15 -15
  101. package/apps/pwa/out/ops/checklist/index.html +1 -1
  102. package/apps/pwa/out/ops/checklist/index.txt +15 -15
  103. package/apps/pwa/out/ops/release/index.html +1 -1
  104. package/apps/pwa/out/ops/release/index.txt +15 -15
  105. package/apps/pwa/out/ops/seats/index.html +1 -1
  106. package/apps/pwa/out/ops/seats/index.txt +15 -15
  107. package/apps/pwa/out/outputs/index.html +1 -1
  108. package/apps/pwa/out/outputs/index.txt +15 -15
  109. package/apps/pwa/out/reflection/index.html +1 -1
  110. package/apps/pwa/out/reflection/index.txt +16 -16
  111. package/apps/pwa/out/scheduler/index.html +1 -1
  112. package/apps/pwa/out/scheduler/index.txt +15 -15
  113. package/apps/pwa/out/sessions/index.html +1 -1
  114. package/apps/pwa/out/sessions/index.txt +15 -15
  115. package/apps/pwa/out/settings/devices/index.html +1 -1
  116. package/apps/pwa/out/settings/devices/index.txt +15 -15
  117. package/apps/pwa/out/settings/index.html +1 -1
  118. package/apps/pwa/out/settings/index.txt +15 -15
  119. package/apps/pwa/out/setup/done/index.html +1 -1
  120. package/apps/pwa/out/setup/done/index.txt +15 -15
  121. package/apps/pwa/out/setup/index.html +1 -1
  122. package/apps/pwa/out/setup/index.txt +15 -15
  123. package/apps/pwa/out/share/index.html +1 -1
  124. package/apps/pwa/out/share/index.txt +15 -15
  125. package/apps/pwa/out/showroom/index.html +1 -1
  126. package/apps/pwa/out/showroom/index.txt +15 -15
  127. package/apps/pwa/out/tasks/index.html +1 -1
  128. package/apps/pwa/out/tasks/index.txt +15 -15
  129. package/apps/pwa/out/term/index.html +1 -1
  130. package/apps/pwa/out/term/index.txt +15 -15
  131. package/apps/pwa/out/today/index.html +1 -1
  132. package/apps/pwa/out/today/index.txt +15 -15
  133. package/apps/pwa/out/trace/index.html +1 -1
  134. package/apps/pwa/out/trace/index.txt +15 -15
  135. package/apps/pwa/out/vault/index.html +1 -1
  136. package/apps/pwa/out/vault/index.txt +15 -15
  137. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  138. package/apps/pwa/out/workflows/chat-ui/index.txt +15 -15
  139. package/apps/pwa/out/workflows/index.html +1 -1
  140. package/apps/pwa/out/workflows/index.txt +15 -15
  141. package/apps/pwa/out/workspace/index.html +1 -1
  142. package/apps/pwa/out/workspace/index.txt +15 -15
  143. package/apps/pwa/out/worktrees/index.html +1 -1
  144. package/apps/pwa/out/worktrees/index.txt +15 -15
  145. package/graphs/doc-gen/doc-gen.yaml +24 -0
  146. package/graphs/doc-gen/recipes.yaml +3 -0
  147. package/graphs/heal/heal-loop.yaml +1 -1
  148. package/graphs/implement-loop.yaml +1 -1
  149. package/graphs/orchestrator/orchestrator.yaml +7 -0
  150. package/graphs/orchestrator/recipes.yaml +3 -0
  151. package/graphs/release/recipes.yaml +3 -0
  152. package/graphs/release/release-loop.yaml +4 -2
  153. package/graphs/steward/recipes.yaml +2 -1
  154. package/package.json +1 -1
  155. package/scripts/brand/check.ts +7 -5
  156. package/scripts/ci-public-export-import-gate.ts +154 -0
  157. package/scripts/ci-test-interference-gate.ts +5 -1
  158. package/scripts/ci-typecheck-changed.ts +82 -31
  159. package/scripts/docs/doc-rot.ts +164 -0
  160. package/scripts/docs/generate-graph-anatomy.ts +437 -0
  161. package/scripts/docs-cli-check.ts +4 -4
  162. package/scripts/expose-rubric-suggest.ts +18 -12
  163. package/scripts/goals/goal-census.ts +343 -0
  164. package/scripts/lecture-note/node.ts +31 -11
  165. package/scripts/lessons/handbook-page.ts +30 -3
  166. package/scripts/marketing/generate-ax-brief.ts +140 -0
  167. package/scripts/marketing/generate-feature-map.ts +118 -0
  168. package/scripts/measure/author-section-contribution.ts +84 -0
  169. package/scripts/release-loop/checklist-gate-node.ts +53 -14
  170. package/scripts/release-loop/cut-branch.ts +43 -13
  171. package/scripts/release-loop/gate-node.ts +82 -14
  172. package/scripts/release-loop/vault-note-node.ts +257 -8
  173. package/scripts/release-story/draft.ts +57 -9
  174. package/scripts/rhythm/daily.ts +263 -76
  175. package/scripts/rhythm/monthly.ts +97 -0
  176. package/scripts/rhythm/weekly.ts +30 -9
  177. package/scripts/smart-merge/resync-shadow.ts +147 -0
  178. package/src/acp/client.ts +17 -2
  179. package/src/agent-env/profile.ts +161 -0
  180. package/src/agent-mission/driver.ts +51 -1
  181. package/src/agent-mission/supervisor-metrics-cli.ts +40 -0
  182. package/src/agent-mission/supervisor-metrics.ts +218 -0
  183. package/src/agent-substrate/pr-reviewer.ts +2 -0
  184. package/src/ask-user-question/pending-questions.ts +5 -0
  185. package/src/auth/github-app-token.ts +112 -13
  186. package/src/autopilot/build/llm-conflict-merge.ts +32 -6
  187. package/src/autopilot/track-agent-shadow.ts +2 -1
  188. package/src/briefing/brief-items.ts +276 -0
  189. package/src/budget/usage-outcomes.ts +204 -0
  190. package/src/claims/claims-render.ts +14 -5
  191. package/src/cli/agent-env-cli.ts +21 -0
  192. package/src/cli/brief-cli.ts +73 -0
  193. package/src/cli/decisions-cli.ts +9 -0
  194. package/src/cli/doctor-cli.ts +23 -1
  195. package/src/cli/doctor-node-modules.ts +147 -0
  196. package/src/cli/intake-cli.ts +46 -17
  197. package/src/cli/know-cli.ts +20 -0
  198. package/src/cli/logs-cli.ts +43 -1
  199. package/src/cli/pod-cli.ts +2 -0
  200. package/src/cli/pr-cli.ts +80 -12
  201. package/src/cli/release-cli.ts +66 -29
  202. package/src/cli/seat-requests-cli.ts +52 -0
  203. package/src/cli/self-update.ts +200 -1
  204. package/src/cli/usage-cli.ts +26 -0
  205. package/src/context-bus/context-now-public.ts +16 -6
  206. package/src/context-bus/context-now.ts +3 -1
  207. package/src/context-bus/coord-events.ts +6 -4
  208. package/src/decisions/decision-cards.ts +33 -7
  209. package/src/decisions/proact-meter.ts +286 -0
  210. package/src/decisions/proact1-lite.ts +86 -0
  211. package/src/decisions/web-push-decision-cards.ts +1 -1
  212. package/src/discord-self-message.ts +9 -0
  213. package/src/domains/alert-audit.ts +271 -0
  214. package/src/domains/core-tools.ts +4 -3
  215. package/src/domains/ops-facts-tool.ts +31 -1
  216. package/src/flow-loop/split.ts +24 -0
  217. package/src/harness/harness-cli-command.ts +147 -17
  218. package/src/harness/harness-incidents.ts +2 -0
  219. package/src/harness/harness-pod-dispatch.ts +67 -8
  220. package/src/harness/harness-queue.ts +380 -50
  221. package/src/harness/harness-seams.ts +13 -3
  222. package/src/harness/helper-repair.ts +218 -0
  223. package/src/harness/helper-scan.ts +27 -4
  224. package/src/harness/launch-stamp.ts +236 -0
  225. package/src/harness/ledger-write-guard-child.fixture.ts +12 -0
  226. package/src/harness/ledger-write-guard.ts +35 -0
  227. package/src/harness/nested-elanous-policy.ts +114 -0
  228. package/src/harness/pod-memory-policy.ts +15 -0
  229. package/src/harness/repository-name.ts +55 -0
  230. package/src/hq/fence-audit.ts +90 -0
  231. package/src/hq/hq.ts +70 -6
  232. package/src/hq/lease.ts +9 -7
  233. package/src/hq/move-plan.ts +126 -0
  234. package/src/hq/promote.ts +31 -0
  235. package/src/hq/transfer.ts +185 -0
  236. package/src/index.ts +189 -13
  237. package/src/intake-plane/check.ts +63 -0
  238. package/src/intake-plane/digest.ts +65 -21
  239. package/src/intake-plane/front-classifier.ts +6 -0
  240. package/src/intake-plane/items.ts +3 -2
  241. package/src/intake-plane/lens.ts +177 -0
  242. package/src/intake-plane/route.ts +145 -1
  243. package/src/knowledge/know-find.ts +105 -0
  244. package/src/llm.ts +75 -19
  245. package/src/loops/budget.ts +36 -5
  246. package/src/loops/checker.ts +2 -2
  247. package/src/loops/orchestrator/author-depth.ts +65 -9
  248. package/src/loops/orchestrator/author-input-check.ts +8 -3
  249. package/src/loops/orchestrator/author-ledger.ts +3 -1
  250. package/src/loops/orchestrator/finish-rate.ts +14 -3
  251. package/src/loops/orchestrator/seat-share.ts +56 -0
  252. package/src/loops/orchestrator/tick.ts +107 -29
  253. package/src/loops/orchestrator/traffic.ts +117 -11
  254. package/src/loops/registry.ts +142 -61
  255. package/src/maturity/bot-slash-catalog.ts +11 -2
  256. package/src/maturity/feature-maturity.ts +4 -3
  257. package/src/maturity/tui-slash-availability.ts +40 -0
  258. package/src/mss/logging/log-store.ts +35 -4
  259. package/src/nexus/api/http-server.ts +28 -14
  260. package/src/nexus/api/loop-edges.ts +173 -0
  261. package/src/nexus/api/schedules-read.ts +13 -0
  262. package/src/nexus/api/seat-requests.ts +79 -56
  263. package/src/oauth/overload-failover-launch.ts +75 -0
  264. package/src/oauth/overload-failover.ts +137 -0
  265. package/src/prompt-enhance/enhance.ts +6 -1
  266. package/src/release-loop/auto-start.ts +6 -3
  267. package/src/release-loop/checklist.ts +19 -5
  268. package/src/release-loop/feature-store.ts +59 -31
  269. package/src/release-loop/merged-pr-checklist.ts +125 -0
  270. package/src/release-loop/placement.ts +98 -29
  271. package/src/seat-dispatch/seat-ask.ts +33 -6
  272. package/src/seat-dispatch/seat-request-eligibility.ts +19 -0
  273. package/src/seat-dispatch/seat-request-ledger.ts +133 -0
  274. package/src/seat-loop/seat-loop.ts +215 -12
  275. package/src/self-dev/ask-launch-flow.ts +22 -1
  276. package/src/self-dev/authored-goal-trace.ts +64 -0
  277. package/src/self-dev/dev-cli.ts +19 -1
  278. package/src/self-dev/dev-pipeline.ts +14 -9
  279. package/src/self-dev/draft-sweep.ts +90 -10
  280. package/src/self-dev/draft-triage-rules.ts +25 -8
  281. package/src/self-dev/entrance-registry.ts +10 -6
  282. package/src/self-dev/old-door.ts +73 -0
  283. package/src/self-dev/orchestrate.ts +15 -1
  284. package/src/self-dev/review-provider-fallback.ts +6 -1
  285. package/src/self-dev/run-supervisor.ts +49 -2
  286. package/src/self-implement/app-api-budget.ts +166 -0
  287. package/src/self-implement/budget-gate.ts +7 -5
  288. package/src/self-implement/follow-up-goals.ts +289 -0
  289. package/src/self-implement/frozen-merges.ts +3 -2
  290. package/src/self-implement/goal-author.ts +50 -6
  291. package/src/self-implement/goal-clarification-escalation.ts +5 -0
  292. package/src/self-implement/heal-intake.ts +120 -2
  293. package/src/self-implement/heal-triage.ts +44 -0
  294. package/src/self-implement/host-regate.ts +9 -2
  295. package/src/self-implement/l8-merge-queue.ts +132 -0
  296. package/src/self-implement/orchestrator.ts +325 -47
  297. package/src/self-implement/pipeline-shape.ts +1 -1
  298. package/src/self-implement/revert-guard.ts +42 -7
  299. package/src/self-implement/run-ledger.ts +6 -0
  300. package/src/self-implement/run-status-mapping.ts +2 -0
  301. package/src/self-implement/seams.ts +45 -16
  302. package/src/self-implement/self-implement-cli.ts +1 -0
  303. package/src/self-implement/speed-claims.ts +338 -0
  304. package/src/session-runtime/index.ts +2 -0
  305. package/src/session-runtime/retry-api.ts +87 -0
  306. package/src/session-runtime/retry-policy.ts +107 -6
  307. package/src/steward/triage.ts +74 -3
  308. package/src/steward/working-backwards.ts +20 -2
  309. package/src/task-cards/card-cli.ts +25 -0
  310. package/src/task-cards/card-store.ts +5 -3
  311. package/src/task-orchestrator/surfaces/pod-artifact-return.ts +63 -48
  312. package/src/task-orchestrator/surfaces/pod-command-job.ts +84 -9
  313. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +48 -0
  314. package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +4 -3
  315. package/src/task-orchestrator/surfaces/pod-ledger-prod-sink.ts +75 -0
  316. package/src/task-orchestrator/surfaces/pod-pool.ts +70 -9
  317. package/src/task-orchestrator/surfaces/pod-source-receive.ts +37 -1
  318. package/src/task-orchestrator/surfaces/self-implement-pod.ts +166 -46
  319. package/src/task-orchestrator/surfaces/self-implement.ts +7 -1
  320. package/src/telegram-commands.ts +5 -0
  321. package/src/telegram.ts +72 -4
  322. package/src/user-config.ts +64 -7
  323. package/src/version/packed-revision.json +1 -1
  324. package/src/workflow-runtime/nodes/bash.ts +9 -1
  325. package/apps/pwa/out/_next/static/chunks/4562-071d8bac44a01069.js +0 -1
  326. package/apps/pwa/out/_next/static/chunks/5977-2df489622a52a33a.js +0 -1
  327. package/apps/pwa/out/_next/static/chunks/app/approvals/page-74383f890f075511.js +0 -1
  328. package/apps/pwa/out/_next/static/chunks/app/board/page-c496bb16da85385f.js +0 -1
  329. package/apps/pwa/out/_next/static/chunks/app/botlab/page-1abfe3aec3be6bdc.js +0 -1
  330. package/apps/pwa/out/_next/static/chunks/app/consult/page-fb260b9283dbf646.js +0 -1
  331. package/apps/pwa/out/_next/static/chunks/app/design-check/page-61ec1d2e92bdd50a.js +0 -1
  332. package/apps/pwa/out/_next/static/chunks/app/inside/page-fd7e200d4d83fbd7.js +0 -1
  333. package/apps/pwa/out/_next/static/chunks/app/live/page-d47266766766d227.js +0 -1
  334. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-2ce5471926761fdd.js +0 -1
  335. package/apps/pwa/out/_next/static/chunks/app/not-found-e995d30f6800b6bf.js +0 -1
  336. package/apps/pwa/out/_next/static/chunks/app/observatory/page-39f89c53038a51d4.js +0 -1
  337. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-5a753bb4ec0cc511.js +0 -1
  338. package/apps/pwa/out/_next/static/chunks/app/outputs/page-04250f0e2c0d03df.js +0 -1
  339. package/apps/pwa/out/_next/static/chunks/app/page-341480ed8e3c1ea8.js +0 -1
  340. package/apps/pwa/out/_next/static/chunks/app/sessions/page-8ac8d71c2adf9c8a.js +0 -1
  341. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-e1e47d8d940aba3d.js +0 -1
  342. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-94dc383d3d54db1a.js +0 -1
  343. package/apps/pwa/out/_next/static/chunks/app/setup/page-b3759cc14da80908.js +0 -1
  344. package/apps/pwa/out/_next/static/chunks/app/today/page-194dce4a83143fce.js +0 -1
  345. package/apps/pwa/out/_next/static/chunks/app/trace/page-35bdeae2e2c17147.js +0 -1
  346. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-16bef3da05a900c3.js +0 -1
  347. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-134c1bc762aee62c.js +0 -1
  348. package/apps/pwa/out/_next/static/css/2e33713c444d5b39.css +0 -1
  349. package/apps/pwa/out/_next/static/x6mjI6vqOkVVu0jFuDkz1/_buildManifest.js +0 -1
  350. /package/apps/pwa/out/_next/static/{x6mjI6vqOkVVu0jFuDkz1 → rv9cierV0jSOvDBm1g0XB}/_ssgManifest.js +0 -0
package/src/telegram.ts CHANGED
@@ -66,7 +66,9 @@ import { detectUrlRoute, type UrlRouteDecision } from './skills/url-router.js';
66
66
  import { observeDevRequestRouteFailSoft } from './skills/dev-request-router.js';
67
67
  import { runUrlRoute } from './skills/url-route-exec.js';
68
68
  import { recordRoutedLinkAbsorbed } from './intake-plane/link-ledger.js';
69
- import { classifyFrontInput } from './intake-plane/front-classifier.js';
69
+ import { classifyFrontInput, telegramAbsorbUrls } from './intake-plane/front-classifier.js';
70
+ import { scheduleIntakeEvent } from './intake-plane/route.js';
71
+ import { dispatchTaskCreate } from './task-orchestrator/runtimes/create.js';
70
72
  import { handleTelegramSeatWork, type TelegramSeatWorkDeps } from './intake-plane/telegram-seat-work.js';
71
73
  import { deliverSeatAnswers } from './seat-dispatch/seat-ask.js';
72
74
  import { effectiveInstanceRoot } from './instance/resolve.js';
@@ -78,6 +80,8 @@ import type { TranscriptionEngine, FieldAudio } from './field-note/transcribe.js
78
80
  import { maybeHandleCardPhoto, type CardPhotoDeps } from './telegram-card-followup.js';
79
81
  import { attachTelegramProjectButtons } from './telegram-project-command.js';
80
82
  import { attachTelegramFabricPlan } from './telegram-fabric-plan.js';
83
+ import { contextNow as readContextNow, type ContextNowDeps } from './context-bus/context-now.js';
84
+ import { renderTelegramNow } from './context-bus/context-now-surfaces.js';
81
85
 
82
86
  export type TgAttachmentKind = 'photo' | 'voice' | 'audio' | 'document';
83
87
 
@@ -231,6 +235,9 @@ export interface TelegramBotOpts {
231
235
  /** Test seam for the business-card graph and its private run root. */
232
236
  cardFollowupDeps?: Pick<CardPhotoDeps, 'runGraph' | 'rootDir' | 'ocrText'>;
233
237
  fabricPlanDeps?: import('./telegram-fabric-plan.js').TelegramFabricPlanDeps;
238
+ /** 시험 seam — `/v1/context/now` 와 같은 `contextNow` 읽기. 던지면 «맥락 못 읽음». */
239
+ readContextNow?: typeof readContextNow;
240
+ contextNowDeps?: ContextNowDeps;
234
241
  }
235
242
 
236
243
  /** Surface-unification v2 (FU-2) — Telegram trigger event passed to
@@ -262,6 +269,9 @@ const EMPTY_ALLOWLIST_NOTICE_GAP_MS = 10 * 60 * 1000;
262
269
  // Tuned above a normal chat answer but below a real delegation (which
263
270
  // pays a multi-second session load before any work).
264
271
  const NOTIFY_AS_NEW_MSG_THRESHOLD_MS = 20_000;
272
+ /** 같은 대화에서 이 간격 안이면 context-now 요약을 다시 보내지 않는다. */
273
+ const CONTEXT_FIRST_GAP_MS = 6 * 60 * 60 * 1000;
274
+ const CONTEXT_UNREADABLE = '맥락 못 읽음';
265
275
 
266
276
  interface ApiResponse<T> {
267
277
  ok: boolean;
@@ -353,6 +363,12 @@ export class TelegramBot {
353
363
  private readonly cardFollowupDeps: Pick<CardPhotoDeps, 'runGraph' | 'rootDir' | 'ocrText'>;
354
364
  private readonly seatWorkDeps: TelegramSeatWorkDeps;
355
365
  private readonly handleFabricPlan: (ctx: TgIncoming) => Promise<boolean>;
366
+ private readonly readContextNow: typeof readContextNow;
367
+ private readonly contextNowDeps?: ContextNowDeps;
368
+ /** 대화 키(chat+thread) → 그 대화의 마지막 사용자 발화 시각(요약 여부와 무관하게 매 발화마다 갱신). */
369
+ private readonly lastUtteranceAt = new Map<string, number>();
370
+ /** 첫 말이거나 6시간 이상 쉰 뒤라 요약이 «밀려 있는» 대화 키 — 다음 일반 답이 한 번 소비한다. */
371
+ private readonly contextFirstPending = new Set<string>();
356
372
  private seatAskTimer: ReturnType<typeof setInterval> | null = null;
357
373
  /** 앨범 id → `#현장` 행사 · 답장 디바운스. 태그된 앨범만 들어온다. */
358
374
  private readonly fieldGroups = new Map<string, {
@@ -392,6 +408,8 @@ export class TelegramBot {
392
408
  this.fieldNoteDecodeAudio = opts.fieldNoteDecodeAudio;
393
409
  this.cardFollowupDeps = opts.cardFollowupDeps ?? {};
394
410
  this.handleFabricPlan = attachTelegramFabricPlan(this, opts.fabricPlanDeps);
411
+ this.readContextNow = opts.readContextNow ?? readContextNow;
412
+ this.contextNowDeps = opts.contextNowDeps;
395
413
  this.seatWorkDeps = { ...opts.seatWorkDeps, askDeps: { ...opts.seatWorkDeps?.askDeps,
396
414
  channel: 'telegram', botId: this.botId,
397
415
  send: opts.seatWorkDeps?.askDeps?.send ?? (async (origin, text) => {
@@ -412,6 +430,34 @@ export class TelegramBot {
412
430
  return this.allowedUsers.size > 0 && this.allowedUsers.has(userId);
413
431
  }
414
432
 
433
+ /** 허용된 모든 발화(명령 포함)마다 부른다 — 쉼은 마지막 발화부터 재고, 요약 전송과는 따로 기록한다. */
434
+ private noteUtterance(ctx: TgIncoming): void {
435
+ const key = `${ctx.chatId}:${ctx.threadId ?? ''}`;
436
+ const now = this.nowImpl();
437
+ const previous = this.lastUtteranceAt.get(key);
438
+ this.lastUtteranceAt.set(key, now);
439
+ if (previous === undefined || now - previous >= CONTEXT_FIRST_GAP_MS) this.contextFirstPending.add(key);
440
+ }
441
+
442
+ /** 처음이거나 6시간 이상 쉰 대화의 첫 일반 답 앞에 context-now 요약 한 메시지를 보낸다. 실패해도 본 답은 막지 않는다. */
443
+ private async maybeSendContextFirst(ctx: TgIncoming): Promise<void> {
444
+ const key = `${ctx.chatId}:${ctx.threadId ?? ''}`;
445
+ if (!this.contextFirstPending.delete(key)) return;
446
+ const cfg = this.slashContext?.userConfig.telegram;
447
+ if (cfg?.contextFirst === false) return;
448
+ let text = CONTEXT_UNREADABLE;
449
+ try {
450
+ text = renderTelegramNow(this.readContextNow({}, this.contextNowDeps));
451
+ } catch {
452
+ text = CONTEXT_UNREADABLE;
453
+ }
454
+ try {
455
+ await this.sendMessage(ctx.chatId, text, { replyTo: ctx.messageId, threadId: ctx.threadId });
456
+ } catch (err) {
457
+ this.log(`telegram context-first failed: ${err instanceof Error ? err.message : String(err)}`);
458
+ }
459
+ }
460
+
415
461
  private async refuseMessage(ctx: TgIncoming): Promise<void> {
416
462
  const empty = this.allowedUsers.size === 0;
417
463
  debug.log('telegram.owner-gate', 'refused', {
@@ -1543,6 +1589,7 @@ export class TelegramBot {
1543
1589
  await this.refuseMessage(ctx);
1544
1590
  return;
1545
1591
  }
1592
+ this.noteUtterance(ctx);
1546
1593
  if (await this.handleFabricPlan(ctx)) return;
1547
1594
  // 현장 업로드 — `#현장` 캡션(또는 태그된 앨범의 나머지)의 사진·영상은 LLM 대신 현장 폴더로.
1548
1595
  if (await this.tryHandleFieldUpload(ctx)) return;
@@ -1919,11 +1966,30 @@ export class TelegramBot {
1919
1966
  ? getActiveDelegation(delegationChatKey(this.botId, ctx.chatId, ctx.threadId))
1920
1967
  : null;
1921
1968
  if (!activeDeleg) {
1922
- try {
1923
- classifyFrontInput({ text: ctx.text, surface: 'telegram' }, { urlRouting: getUserConfig().skills.urlRouting });
1924
- } catch { /* observation must not interrupt URL routing */ }
1925
1969
  const urlDec = detectUrlRoute(ctx.text, getUserConfig().skills.urlRouting);
1926
1970
  if (urlDec) {
1971
+ try {
1972
+ const frontInput = { text: ctx.text, surface: 'telegram' as const };
1973
+ const decision = classifyFrontInput(frontInput, { urlRouting: getUserConfig().skills.urlRouting });
1974
+ const absorbUrls = telegramAbsorbUrls(frontInput, decision);
1975
+ for (const url of absorbUrls) {
1976
+ const result = await scheduleIntakeEvent(effectiveInstanceRoot(), url, {
1977
+ eventMax: getUserConfig().intake.eventMax,
1978
+ post: async ({ url: link }) => {
1979
+ const posted = await dispatchTaskCreate({
1980
+ title: `흡수: ${link}`.slice(0, 80),
1981
+ surface: { kind: 'llm-direct', prompt: `이 링크를 흡수하고 노트로 저장하세요: ${link}` },
1982
+ });
1983
+ if (!posted.taskId) throw new Error('intake event task not created');
1984
+ return { taskId: posted.taskId };
1985
+ },
1986
+ });
1987
+ if (result.reply) await this.sendMessage(ctx.chatId, result.reply, { threadId: ctx.threadId, markdown: true });
1988
+ }
1989
+ if (absorbUrls.length) return;
1990
+ } catch (error) {
1991
+ debug.log('intake.event', 'failed', { reason: error instanceof Error ? error.name : 'unknown' });
1992
+ }
1927
1993
  const handled = await this.runUrlRouteReply(ctx, urlDec);
1928
1994
  if (handled) return;
1929
1995
  }
@@ -1952,6 +2018,8 @@ export class TelegramBot {
1952
2018
  debug.log('telegram.deliver', 'reaction', { chatId: ctx.chatId, phase: 'start', emoji: '👀', on: reactionsOn });
1953
2019
  if (reactionsOn && ctx.messageId != null) void this.setMessageReaction(ctx.chatId, ctx.messageId, '👀');
1954
2020
 
2021
+ await this.maybeSendContextFirst(ctx);
2022
+
1955
2023
  // Post a placeholder NOW so the user sees acknowledgement while
1956
2024
  // the LLM is thinking. The same message is then edited in-place
1957
2025
  // as tokens stream in — far better UX than dead air followed by
@@ -922,6 +922,8 @@ export interface TelegramConfig {
922
922
  fieldDefaultEvent?: string;
923
923
  /** `#현장` 영상의 기본 렌더 모드. 미지정 시 standard, 캡션의 `즉석`/`instant` 가 우선. */
924
924
  fieldReelMode?: 'standard' | 'instant';
925
+ /** 대화를 처음 열거나 6시간 이상 쉰 뒤 첫 말 앞에 `/v1/context/now` 요약을 한 메시지로 보낸다. 기본 켬. `false` 만 끈다. */
926
+ contextFirst?: boolean;
925
927
  }
926
928
 
927
929
  const TELEGRAM_DEFAULTS: TelegramConfig = { enabled: false, allowedUsers: [] };
@@ -1096,6 +1098,8 @@ export const DEFAULT_BUDGET_GATE_MAX_USED_PERCENT: BudgetGateMaxUsedPercent = {
1096
1098
  'openai-codex': 95,
1097
1099
  grok: 48,
1098
1100
  };
1101
+ /** 발사 관문이 grok 주간 사용률에 실제로 적용하는 상한. `elanous usage` 와 같은 수를 이 값 미만으로만 통과시킨다. */
1102
+ export const LAUNCH_GROK_USED_PERCENT_CAP = 80;
1099
1103
 
1100
1104
  export interface HarnessBudgetGateConfig {
1101
1105
  /** 0~100. 기본 15. 범위 밖이면 경고와 함께 기본. */
@@ -1140,7 +1144,9 @@ export interface SelfImplementToolConfig {
1140
1144
  decompositionShadow: SelfImplementDecompositionShadowConfig;
1141
1145
  /** Opt-in delivery of authored goal clarifications from unattended dev runs. */
1142
1146
  clarificationEscalation: SelfImplementClarificationEscalationConfig;
1143
- /** 사용자 자식 모델 선호. 없으면 해석기가 auto + fallbackChain 으로 만든다. */
1147
+ /** 사용자 자식 모델 선호. 없으면 해석기가 auto + fallbackChain 으로 만든다.
1148
+ * Overload failover (OVERLOAD-FAILOVER) may move an unpinned codex child to
1149
+ * grok. A pinned codex provider is never moved. */
1144
1150
  childLlm?: ChildLlmPreferenceConfig;
1145
1151
  /** ⭐ PR-open 사전 승인 (2026-07-26 · 대표 결정 "오토 선호 · 기본 ON").
1146
1152
  *
@@ -3097,6 +3103,8 @@ export interface IntakeSurfaceConfig {
3097
3103
  }
3098
3104
 
3099
3105
  export interface IntakeConfig {
3106
+ /** Maximum immediately scheduled Telegram absorption links per KST day. */
3107
+ eventMax?: number;
3100
3108
  telegram: IntakeSurfaceConfig;
3101
3109
  discord: IntakeSurfaceConfig;
3102
3110
  approvals?: { repo?: string };
@@ -3484,10 +3492,13 @@ export interface OrchestratorLoopConfig {
3484
3492
  /** Per-seat release gate; absent seats retain the spawn-budget default. */
3485
3493
  releaseGate?: Partial<Record<OrchestratorSeat, number>>;
3486
3494
  trafficMode: 'shadow' | 'live';
3495
+ idleRequest?: 'off' | 'shadow' | 'live';
3496
+ /** FINISH-RATE — the queue tick reads finish metrics before launching; shadow logs the hold only, on holds (default shadow). */
3497
+ finishGate?: 'off' | 'shadow' | 'on';
3487
3498
  }
3488
3499
 
3489
3500
  export const ORCHESTRATOR_DEFAULTS: OrchestratorLoopConfig = {
3490
- mode: 'shadow', seatTrees: {}, seatCaps: { TC: 8, UX: 6, MK: 6, OP: 4 }, trafficMode: 'shadow',
3501
+ mode: 'shadow', seatTrees: {}, seatCaps: { TC: 8, UX: 6, MK: 6, OP: 4 }, trafficMode: 'shadow', idleRequest: 'shadow', finishGate: 'shadow',
3491
3502
  };
3492
3503
 
3493
3504
  export function parseOrchestratorLoopConfig(raw: unknown): OrchestratorLoopConfig {
@@ -3510,7 +3521,9 @@ export function parseOrchestratorLoopConfig(raw: unknown): OrchestratorLoopConfi
3510
3521
  }
3511
3522
  const mode = value.mode === 'off' || value.mode === 'live' ? value.mode : 'shadow';
3512
3523
  return { mode, seatTrees, seatCaps, ...(Object.keys(releaseGate).length ? { releaseGate } : {}),
3513
- trafficMode: value.trafficMode === 'live' ? 'live' : 'shadow' };
3524
+ trafficMode: value.trafficMode === 'live' ? 'live' : 'shadow',
3525
+ idleRequest: value.idleRequest === 'off' || value.idleRequest === 'live' ? value.idleRequest : 'shadow',
3526
+ finishGate: value.finishGate === 'off' || value.finishGate === 'on' ? value.finishGate : 'shadow' };
3514
3527
  }
3515
3528
 
3516
3529
  export type StewardLoopMode = 'off' | 'shadow' | 'live' | 'rescue';
@@ -3531,6 +3544,8 @@ export interface SeatLoopConfig {
3531
3544
  reportPr?: number;
3532
3545
  /** Parent routing and age limits for checklist stalls; omitted values use findStalls defaults. */
3533
3546
  stall?: { parents?: Record<string, string>; redMinutes?: number; blockedMinutes?: number };
3547
+ /** Unlanded attempts of the same seat cell before the loop stops relaunching and asks a person. Absent or invalid means 3. */
3548
+ repeatStop?: number;
3534
3549
  }
3535
3550
 
3536
3551
  export type EventSeat = 'OP' | 'TC' | 'MK' | 'UX';
@@ -3566,6 +3581,8 @@ export interface HqConfig {
3566
3581
  standby?: string;
3567
3582
  /** Lease TTL in seconds (default 1500 = 25 min). */
3568
3583
  ttlSeconds?: number;
3584
+ /** Arbiter silence threshold (default 3); applying promotion requires explicit opt-in. */
3585
+ autoPromote?: { enabled?: boolean; streak?: number };
3569
3586
  /** Roles that may still run when this host is fenced only for lack of quorum (never when a newer generation exists). Absent = none. */
3570
3587
  failOpenRoles?: HqFenceRole[];
3571
3588
  /** Per-host nexus health URL over the tailnet (default https://<host>.<tailnetDomain>:31415/v1/health). */
@@ -3601,9 +3618,14 @@ export interface UserConfig {
3601
3618
  loops?: { owners?: Record<string, EventSeat>; defaultOwner?: EventSeat; orchestrator?: OrchestratorLoopConfig; steward?: { mode?: StewardLoopMode; linearTeam?: string; roles?: Record<string, { maxConcurrent?: number }>; budget?: number; tracks?: Record<string, string>; alertAfterFailures?: number; launch?: 'off' | 'shadow' | 'live'; maxParallel?: number; podPool?: string }; seat?: SeatLoopConfig; persona?: PersonaLoopConfig };
3602
3619
  /** 🔐 Pod 의 Grok API 키 과금은 명시 opt-in 만. 생략·잘못된 값은 false.
3603
3620
  * budgetGate 와 같은 `harness` 객체다 — 중복 선언이면 뒤 타입이 앞을 지운다. */
3604
- harness?: { revertGuard?: { depth: number }; pod?: { grokApiKeyOptIn: boolean }; budgetGate?: HarnessBudgetGateConfig; exposeGate?: 'warn' | 'strict'; difficultyPlacement?: boolean; defaultRepo?: string; substrate?: 'local' | 'pod'; podPool?: string; worktreeAddTimeoutSec?: number; queue?: { seatCap?: Partial<Record<'OP' | 'TC' | 'MK' | 'UX', number>> } };
3621
+ harness?: { revertGuard?: { depth: number }; pod?: { grokApiKeyOptIn: boolean }; budgetGate?: HarnessBudgetGateConfig; exposeGate?: 'warn' | 'strict'; difficultyPlacement?: boolean; defaultRepo?: string; /** Optional GitHub repository name (owner/repo), distinct from the local defaultRepo path. */ repo?: string; substrate?: 'local' | 'pod'; podPool?: string; worktreeAddTimeoutSec?: number; queue?: { seatCap?: Partial<Record<'OP' | 'TC' | 'MK' | 'UX', number>> }; /** `harness say` 문장을 Pod 안에서 저작부터 돌릴지. 생략·false = 끔(호스트가 저작). */ authorOnPod?: boolean; /** Stopped-PR repair goals: shadow records only (default); live enqueues them. */ helper?: { repair?: 'shadow' | 'live'; /** Live launches allowed per UTC day. Absent or invalid means 3. */ repairPerDay?: number };
3622
+ /** Nested elanous launches. Only depth 0 may set `allow`. Absent or any other value refuses. A depth >= 1 `--nested-elanous allow` is ignored. */
3623
+ nestedElanous?: 'allow' | 'refuse';
3624
+ /** Follow-up goal after a merged harness PR. Omitted and anything but `live` record only. */
3625
+ followUp?: 'shadow' | 'live';
3626
+ };
3605
3627
  /** ☸️ Pod 실행 칸 — `pool` = 기존 기본 풀(`컨텍스트[@ssh호스트][:상한][#k3d-레지스트리:포트]` 쉼표 · 앞이 우선). harness 실행은 인자·ELANOUS_POD_POOL·harness.podPool 다음으로 읽는다. */
3606
- pod?: { pool?: string; /** 호스트 Git 미러 디렉터리 — Pod Job 에 읽기 전용으로 마운트한다. */ hostMirror?: string; /** 원격 그라운딩 엔드포인트(호스트 nexus · tailnet 주소) — Pod 가 토큰으로 «질의→인용»만 묻는다(P13). */ groundingUrl?: string; /** 읽기 전용 Pod lease 권장에 쓰는 계정별 동시 수. */ lease?: { perAccount?: number }; /** 실측 권고를 Pod 발사 기본값으로 쓸지 (기본 off). */ memory?: { adviseDefaults?: boolean } };
3628
+ pod?: { pool?: string; /** 호스트 Git 미러 디렉터리 — Pod Job 에 읽기 전용으로 마운트한다. */ hostMirror?: string; /** 원격 그라운딩 엔드포인트(호스트 nexus · tailnet 주소) — Pod 가 토큰으로 «질의→인용»만 묻는다(P13). */ groundingUrl?: string; /** 읽기 전용 Pod lease 권장에 쓰는 계정별 동시 수. */ lease?: { perAccount?: number }; /** 실측 권고를 Pod 발사 기본값으로 쓸지 (기본 off). */ memory?: { adviseDefaults?: boolean }; /** 명령 Job 자식 로그(child.log) 상한 바이트. 양의 정수만. 넘으면 끝부분 우선. */ childLogMaxBytes?: number };
3607
3629
  skillRouter: SkillRouterConfig;
3608
3630
  llm: LLMConfig;
3609
3631
  skills: SkillsConfig;
@@ -3962,7 +3984,7 @@ function defaultConfig(): UserConfig {
3962
3984
  },
3963
3985
  },
3964
3986
  voice: { stt: {}, tts: {}, vad: {}, chat: {}, discord: {}, telegram: {}, pwa: {} },
3965
- intake: { telegram: {}, discord: {} },
3987
+ intake: { eventMax: 10, telegram: {}, discord: {} },
3966
3988
  dashboard: {
3967
3989
  promptBank: { ...DASHBOARD_PROMPT_BANK_DEFAULTS },
3968
3990
  foldMode: 'task-unit',
@@ -4000,7 +4022,7 @@ function defaultConfig(): UserConfig {
4000
4022
  nativeStructure: { ...TOOLS_DEFAULTS.nativeStructure },
4001
4023
  selfImplement: { ...TOOLS_DEFAULTS.selfImplement },
4002
4024
  },
4003
- harness: { revertGuard: { depth: 50 }, budgetGate: { ...DEFAULT_BUDGET_GATE }, exposeGate: 'warn', difficultyPlacement: false },
4025
+ harness: { revertGuard: { depth: 50 }, budgetGate: { ...DEFAULT_BUDGET_GATE }, exposeGate: 'warn', difficultyPlacement: false, followUp: 'shadow' },
4004
4026
  grounding: { sources: [] },
4005
4027
  raw: {},
4006
4028
  };
@@ -4517,6 +4539,8 @@ function parseSeatLoopsConfig(input: unknown): SeatLoopConfig {
4517
4539
  ...(minutes(raw.blockedMinutes) ? { blockedMinutes: raw.blockedMinutes } : {}),
4518
4540
  } };
4519
4541
  })(),
4542
+ ...(typeof values.repeatStop === 'number' && Number.isSafeInteger(values.repeatStop) && values.repeatStop > 0
4543
+ ? { repeatStop: values.repeatStop } : {}),
4520
4544
  };
4521
4545
  }
4522
4546
 
@@ -4564,6 +4588,13 @@ export function parseHqConfig(raw: unknown): HqConfig | undefined {
4564
4588
  }
4565
4589
  if (typeof r.ttlSeconds === 'number' && Number.isFinite(r.ttlSeconds) && r.ttlSeconds > 0) out.ttlSeconds = r.ttlSeconds;
4566
4590
  if (typeof r.probeTimeoutSeconds === 'number' && Number.isFinite(r.probeTimeoutSeconds) && r.probeTimeoutSeconds > 0) out.probeTimeoutSeconds = r.probeTimeoutSeconds;
4591
+ if (r.autoPromote && typeof r.autoPromote === 'object' && !Array.isArray(r.autoPromote)) {
4592
+ const auto = r.autoPromote as Record<string, unknown>;
4593
+ const setting: NonNullable<HqConfig['autoPromote']> = {};
4594
+ if (typeof auto.enabled === 'boolean') setting.enabled = auto.enabled;
4595
+ if (typeof auto.streak === 'number' && Number.isSafeInteger(auto.streak) && auto.streak > 0) setting.streak = auto.streak;
4596
+ if (Object.keys(setting).length) out.autoPromote = setting;
4597
+ }
4567
4598
  if (Array.isArray(r.failOpenRoles)) out.failOpenRoles = r.failOpenRoles.filter((v): v is HqFenceRole => HQ_FENCE_ROLES.includes(v as HqFenceRole));
4568
4599
  if (r.healthUrls && typeof r.healthUrls === 'object' && !Array.isArray(r.healthUrls)) {
4569
4600
  out.healthUrls = Object.fromEntries(Object.entries(r.healthUrls as Record<string, unknown>).filter((e): e is [string, string] => typeof e[1] === 'string'));
@@ -4698,6 +4729,7 @@ export function buildUserConfig(path: string = defaultPath()): UserConfig {
4698
4729
  pod: {
4699
4730
  ...(typeof legacyPod.pool === 'string' && legacyPod.pool.trim() ? { pool: legacyPod.pool.trim() } : {}),
4700
4731
  ...(typeof legacyPod.hostMirror === 'string' && legacyPod.hostMirror.trim() ? { hostMirror: legacyPod.hostMirror.trim() } : {}),
4732
+ ...(typeof legacyPod.childLogMaxBytes === 'number' && Number.isSafeInteger(legacyPod.childLogMaxBytes) && legacyPod.childLogMaxBytes > 0 ? { childLogMaxBytes: legacyPod.childLogMaxBytes } : {}),
4701
4733
  ...(typeof legacyPod.groundingUrl === 'string' ? { groundingUrl: legacyPod.groundingUrl } : {}),
4702
4734
  memory: { adviseDefaults: Boolean(legacyPod.memory && typeof legacyPod.memory === 'object' && !Array.isArray(legacyPod.memory)
4703
4735
  && (legacyPod.memory as Record<string, unknown>).adviseDefaults === true) },
@@ -4730,6 +4762,22 @@ export function buildUserConfig(path: string = defaultPath()): UserConfig {
4730
4762
  ? { worktreeAddTimeoutSec: harness.worktreeAddTimeoutSec } : {}),
4731
4763
  ...(typeof harness.defaultRepo === 'string' && isAbsolute(harness.defaultRepo)
4732
4764
  ? { defaultRepo: harness.defaultRepo } : {}),
4765
+ ...(typeof harness.repo === 'string' && harness.repo.trim()
4766
+ ? { repo: harness.repo.trim() } : {}),
4767
+ helper: (() => {
4768
+ const helper = harness.helper && typeof harness.helper === 'object' && !Array.isArray(harness.helper)
4769
+ ? harness.helper as Record<string, unknown> : {};
4770
+ const repairPerDay = helper.repairPerDay;
4771
+ return {
4772
+ repair: helper.repair === 'live' ? 'live' as const : 'shadow' as const,
4773
+ repairPerDay: typeof repairPerDay === 'number' && Number.isSafeInteger(repairPerDay) && repairPerDay >= 0
4774
+ ? repairPerDay : 3,
4775
+ };
4776
+ })(),
4777
+ ...(harness.authorOnPod === true ? { authorOnPod: true } : {}),
4778
+ ...(harness.nestedElanous === 'allow' || harness.nestedElanous === 'refuse'
4779
+ ? { nestedElanous: harness.nestedElanous } : {}),
4780
+ followUp: harness.followUp === 'live' ? 'live' : 'shadow',
4733
4781
  budgetGate: parseHarnessBudgetGate(
4734
4782
  rawObj.harness && typeof rawObj.harness === 'object' && !Array.isArray(rawObj.harness)
4735
4783
  ? (rawObj.harness as Record<string, unknown>).budgetGate
@@ -4867,6 +4915,7 @@ export function buildUserConfig(path: string = defaultPath()): UserConfig {
4867
4915
  ...(normalizeKindRoles(tg.kindRoles) ? { kindRoles: normalizeKindRoles(tg.kindRoles)! } : {}),
4868
4916
  ...(str(tg.fieldDefaultEvent) ? { fieldDefaultEvent: str(tg.fieldDefaultEvent)! } : {}),
4869
4917
  ...(tg.fieldReelMode === 'instant' || tg.fieldReelMode === 'standard' ? { fieldReelMode: tg.fieldReelMode } : {}),
4918
+ ...(tg.contextFirst === false ? { contextFirst: false } : {}),
4870
4919
  },
4871
4920
  discord: {
4872
4921
  enabled: dc.enabled === true,
@@ -5266,6 +5315,7 @@ export function buildUserConfig(path: string = defaultPath()): UserConfig {
5266
5315
  },
5267
5316
  },
5268
5317
  intake: {
5318
+ eventMax: typeof intake.eventMax === 'number' && Number.isSafeInteger(intake.eventMax) && intake.eventMax >= 0 ? intake.eventMax : 10,
5269
5319
  telegram: {
5270
5320
  ...(normalizeIntakeAmbientCaptureMode(intakeTelegram.ambientCapture) !== undefined
5271
5321
  ? { ambientCapture: normalizeIntakeAmbientCaptureMode(intakeTelegram.ambientCapture)! }
@@ -5972,9 +6022,13 @@ export function saveUserConfig(
5972
6022
  revertGuard: cfg.harness?.revertGuard ?? rawHarness.revertGuard,
5973
6023
  difficultyPlacement: cfg.harness?.difficultyPlacement ?? rawHarness.difficultyPlacement,
5974
6024
  defaultRepo: cfg.harness?.defaultRepo ?? rawHarness.defaultRepo,
6025
+ repo: cfg.harness?.repo,
5975
6026
  substrate: cfg.harness?.substrate,
5976
6027
  podPool: cfg.harness?.podPool,
6028
+ authorOnPod: cfg.harness?.authorOnPod === true ? true : undefined,
6029
+ followUp: cfg.harness?.followUp === 'live' ? 'live' : undefined,
5977
6030
  queue: cfg.harness?.queue ?? rawHarness.queue,
6031
+ helper: cfg.harness?.helper ?? rawHarness.helper,
5978
6032
  }),
5979
6033
  ...rawRest,
5980
6034
  ...(cfg.loops ? { loops: {
@@ -5989,6 +6043,8 @@ export function saveUserConfig(
5989
6043
  podPool: cfg.loops.seat.podPool ?? 'pool-node-b@node-b:8',
5990
6044
  ...(cfg.loops.seat.neighbors ? { neighbors: cfg.loops.seat.neighbors } : {}),
5991
6045
  ...(cfg.loops.seat.reportPr === undefined ? {} : { reportPr: cfg.loops.seat.reportPr }),
6046
+ ...(cfg.loops.seat.stall ? { stall: cfg.loops.seat.stall } : {}),
6047
+ ...(cfg.loops.seat.repeatStop === undefined ? {} : { repeatStop: cfg.loops.seat.repeatStop }),
5992
6048
  } } : {}),
5993
6049
  } } : {}),
5994
6050
  ...(cfg.autopilot ? { autopilot: {
@@ -6208,6 +6264,7 @@ export function saveUserConfig(
6208
6264
  }),
6209
6265
  }),
6210
6266
  }),
6267
+ intake: { ...(rawRest.intake && typeof rawRest.intake === 'object' ? rawRest.intake as Record<string, unknown> : {}), ...cfg.intake },
6211
6268
  dashboard: stripUndef({
6212
6269
  views: cfg.dashboard.views,
6213
6270
  theme: cfg.dashboard.theme,
@@ -1 +1 @@
1
- {"commit":"855920facfd9b702ac0c47f96011b2fd67dc0f30"}
1
+ {"commit":"e2304faf1275e38379d5f8f18bbf93e453dd448d"}
@@ -8,6 +8,14 @@
8
8
  import type { BashNode, NodeExecContext, NodeOutput, WorkflowDeps } from '../types.js';
9
9
  import { interpolate } from '../variables.js';
10
10
 
11
+ /** Keep the start of stderr and its real error line. Bun prints the source frame first. */
12
+ export function formatBashStderr(stderr: string): string {
13
+ const head = 200;
14
+ const tail = 800;
15
+ if (stderr.length <= head + tail) return stderr;
16
+ return `${stderr.slice(0, head)}…${stderr.slice(-tail)}`;
17
+ }
18
+
11
19
  export async function executeBashNode(
12
20
  node: BashNode,
13
21
  ctx: NodeExecContext,
@@ -30,7 +38,7 @@ export async function executeBashNode(
30
38
  return {
31
39
  ok: false,
32
40
  output: r.stdout, // surface partial output for $node.output access
33
- error: `bash exit ${r.exitCode}${r.stderr ? `: ${r.stderr.slice(0, 500)}` : ''}`,
41
+ error: `bash exit ${r.exitCode}${r.stderr ? `: ${formatBashStderr(r.stderr)}` : ''}`,
34
42
  durationMs: Date.now() - startedAt,
35
43
  };
36
44
  }
@@ -1 +0,0 @@
1
- "use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[4562],{12958:(e,t,n)=>{n.d(t,{a:()=>o});var r=n(55539),a=n(46124),s=n(74780);let l=e=>JSON.stringify([e.graphId,e.runId]);function o(e){let{client:t,approvals:n,onDecided:o,onPendingChange:i}=e,c=(0,a.useMemo)(()=>(0,s.ll)({client:t}),[t]),[d,u]=(0,a.useState)([]),[m,p]=(0,a.useState)({}),[h,f]=(0,a.useState)(null),[g,x]=(0,a.useState)(""),b=(0,a.useRef)(0),v=n.map(l).join("|");function y(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:m;u(e),i(n.filter(n=>!t[l(n)]&&e.some(e=>l(e)===l(n))).length)}async function w(e,t){let r=l(e);if(h||m[r]||!n.some(e=>l(e)===r)||!d.some(e=>l(e)===r))return;let a=b.current;f(r),x("");try{if(await c.decide(e.graphId,e.runId,t),b.current!==a)return;let n={...m,[r]:t};p(n),y(d,n),o();let s=await c.list();b.current===a&&y(s.items,n)}catch(e){b.current===a&&x((0,s.LP)(e,"decide"))}finally{b.current===a&&f(null)}}return((0,a.useEffect)(()=>{let e=++b.current;return(u([]),x(""),v)?(c.list().then(t=>{b.current===e&&y(t.items)}).catch(t=>{b.current===e&&x((0,s.LP)(t,"list"))}),()=>{b.current+=1}):(i(0),()=>{b.current+=1})},[c,v]),0===n.length)?null:(0,r.jsxs)("div",{className:"space-y-2",children:[(0,r.jsx)("h3",{className:"font-semibold",children:"게시 승인"}),g&&(0,r.jsx)("p",{role:"alert",className:"text-sm text-destructive",children:g}),(0,r.jsx)("ul",{className:"space-y-2",children:n.map(e=>{let t=l(e),n=d.some(e=>l(e)===t);return(0,r.jsxs)("li",{className:"rounded-lg border border-border bg-background px-4 py-3 text-sm",children:[(0,r.jsx)("p",{children:e.message}),m[t]?(0,r.jsx)("p",{className:"mt-2 text-muted-foreground",children:"approved"===m[t]?"승인됨":"보류됨"}):n?(0,r.jsxs)("div",{className:"mt-2 flex gap-2",children:[(0,r.jsx)("button",{type:"button",disabled:null!==h,onClick:()=>void w(e,"approved"),className:"rounded-lg bg-primary px-3 py-1 text-primary-foreground disabled:opacity-50",children:"승인"}),(0,r.jsx)("button",{type:"button",disabled:null!==h,onClick:()=>void w(e,"rejected"),className:"rounded-lg border border-border px-3 py-1 disabled:opacity-50",children:"보류"})]}):(0,r.jsx)("p",{className:"mt-2 text-muted-foreground",children:"대기 중인 승인이 아닙니다."})]},t)})})]})}},43537:(e,t,n)=>{function r(e){return null!==e&&"object"==typeof e&&!Array.isArray(e)}function a(e){return"string"==typeof e}function s(e){return a(e)&&/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,3})?Z$/.test(e)&&Number.isFinite(Date.parse(e))&&new Date(e).toISOString().slice(0,19)===e.slice(0,19)}function l(e){return r(e)&&a(e.nodeId)&&(null===e.ok||"boolean"==typeof e.ok)&&a(e.summary)}function o(e){return r(e)&&a(e.runId)&&a(e.status)&&a(e.startedAt)&&(null===e.version||a(e.version))&&Array.isArray(e.path)&&e.path.every(a)&&Array.isArray(e.nodes)&&e.nodes.every(l)}function i(e){return r(e)&&a(e.id)&&a(e.title)&&a(e.status)&&(void 0===e.owner||a(e.owner))&&a(e.updatedAt)&&(void 0===e.evidence||a(e.evidence))}n.d(t,{HG:()=>g,Kh:()=>f,Nn:()=>p,oc:()=>h});let c=e=>Number.isInteger(e)&&e>=0;function d(e){return r(e)&&a(e.id)&&a(e.title)&&(null===e.open||c(e.open))&&(null===e.landed||c(e.landed))&&(null===e.blocked||Array.isArray(e.blocked)&&e.blocked.every(e=>r(e)&&a(e.id)&&a(e.title)))}function u(e){return r(e)&&["OP","MK","TC","UX"].includes(e.seat)&&(void 0===e.role||a(e.role))&&(null===e.now||r(e.now)&&a(e.now.text)&&a(e.now.at))&&(null===e.landed||Array.isArray(e.landed)&&e.landed.every(e=>r(e)&&c(e.pr)&&a(e.title)&&a(e.at)&&(null===e.checklistId||a(e.checklistId))))&&(null===e.blocked||Array.isArray(e.blocked)&&e.blocked.every(e=>r(e)&&a(e.id)&&a(e.title)&&"red"===e.status))&&(null===e.pendingDecisions||c(e.pendingDecisions))&&(null===e.checklist||r(e.checklist)&&["green","yellow","red","done"].every(t=>c(e.checklist[t])))&&(void 0===e.subSeats||null===e.subSeats||Array.isArray(e.subSeats)&&e.subSeats.every(d))}async function m(e,t,n){try{let r=await e.fetchResponse(t,{method:"GET"});if(403===r.status)return{kind:"forbidden"};if(!r.ok)return{kind:"error",status:r.status};let a=n(await r.json());return null===a?{kind:"error",status:r.status}:{kind:"ready",data:a}}catch(e){return{kind:"error",status:0}}}function p(e,t){return m(e,"/v1/ops/seats".concat(t?"?date=".concat(encodeURIComponent(t)):""),e=>r(e)&&a(e.date)&&Array.isArray(e.seats)&&e.seats.every(u)&&new Set(e.seats.map(e=>e.seat)).size===e.seats.length?{date:e.date,seats:e.seats}:null)}function h(e,t){return m(e,"/v1/ops/release/runs".concat(t?"?version=".concat(encodeURIComponent(t)):""),e=>Array.isArray(e)&&e.every(o)?e:null)}function f(e,t,n){return m(e,"/v1/ops/release/runs/".concat(encodeURIComponent(t),"/nodes/").concat(encodeURIComponent(n),"/log"),e=>r(e)&&a(e.log)?{log:e.log}:null)}function g(e,t){return m(e,"/v1/ops/checklist?version=".concat(encodeURIComponent(t)),e=>{var t,n,l,o;if(!(r(e)&&a(e.version)&&(void 0===e.codename||a(e.codename))&&Array.isArray(e.items)&&e.items.every(i)&&["green","yellow","red","done"].every(t=>void 0===e[t]||Number.isInteger(e[t])&&e[t]>=0)&&(void 0===e.blocked||Array.isArray(e.blocked)&&e.blocked.every(a))&&(void 0===e.byOwner||r(e.byOwner)&&Object.values(e.byOwner).every(e=>Number.isInteger(e)&&e>=0))&&(void 0===e.history||Array.isArray(e.history))))return null;let c={green:0,yellow:0,red:0,done:0};for(let t of e.items)t.status in c&&c[t.status]++;return{version:e.version,...void 0!==e.codename?{codename:e.codename}:{},schedule:r(e.schedule)&&s(e.schedule.cutAt)&&(null===e.schedule.landBy||s(e.schedule.landBy))?{cutAt:e.schedule.cutAt,landBy:e.schedule.landBy}:null,items:e.items,green:null!=(t=e.green)?t:c.green,yellow:null!=(n=e.yellow)?n:c.yellow,red:null!=(l=e.red)?l:c.red,done:null!=(o=e.done)?o:c.done,...void 0!==e.blocked?{blocked:e.blocked}:{},...void 0!==e.byOwner?{byOwner:e.byOwner}:{},...void 0!==e.history?{history:e.history}:{}}})}},74780:(e,t,n)=>{function r(e){return{slides:e.slides.map(e=>{let{image:t,caption:n,include:r}=e;return{image:t,caption:n,include:r}}),caption:{hook:e.caption.hook,body:e.caption.body},hashtags:[...e.hashtags],cover:{text:e.cover.text,sub:e.cover.sub},location:e.location}}n.d(t,{$Y:()=>l,LP:()=>i,Mz:()=>r,ll:()=>d,rH:()=>o});class a extends Error{constructor(e,t){super(t),this.status=e,this.name="GraphApprovalsApiError"}}let s={list:"목록을 보려면",decide:"승인하려면",save:"초안을 저장하려면"},l="/app/settings/#bearer-token";function o(e){return e instanceof a&&(401===e.status||403===e.status)}function i(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"decide";return e instanceof a?401===e.status||403===e.status?"".concat(s[t]," 이 기기를 데몬에 연결해야 합니다 — 설정 › 데몬 연결 › 연결 토큰 칸에 토큰을 넣어 주세요."):404===e.status?"이 실행을 찾지 못했습니다. 목록을 다시 확인해 주세요.":409===e.status?"이미 결정된 실행입니다. 목록을 다시 확인해 주세요.":400===e.status?"결정 내용을 확인한 뒤 다시 시도해 주세요.":"승인 요청을 처리하지 못했습니다. 잠시 뒤 다시 시도해 주세요.":e instanceof TypeError?"서버에 연결하지 못했습니다. 연결 상태를 확인해 주세요.":"승인 요청을 처리하지 못했습니다. 잠시 뒤 다시 시도해 주세요."}let c="/v1/graph-approvals";function d(e){var t,n;let r=(null!=(t=e.baseUrl)?t:"").replace(/\/+$/,""),s=null!=(n=e.fetchImpl)?n:fetch;async function l(t,n){let l={...n,headers:{"content-type":"application/json",...e.authHeader?{authorization:e.authHeader}:{}}},o=e.client?await e.client.fetchResponse(t,l):await s("".concat(r).concat(t),l),i=await o.json().catch(()=>null);if(!o.ok){let e=i&&"object"==typeof i&&"error"in i&&"string"==typeof i.error?i.error:"request-failed";throw new a(o.status,e)}return i}return{list:()=>l(c),decide:(e,t,n)=>l("".concat(c,"/").concat(encodeURIComponent(e),"/").concat(encodeURIComponent(t)),{method:"POST",body:JSON.stringify({decision:n})}),saveFeedDraft:(e,t,n)=>l("".concat(c,"/").concat(encodeURIComponent(e),"/").concat(encodeURIComponent(t),"/feed-draft"),{method:"PUT",body:JSON.stringify(n)}),feedMedia:async(t,n,l)=>{let o="".concat(c,"/").concat(encodeURIComponent(t),"/").concat(encodeURIComponent(n),"/media?path=").concat(encodeURIComponent(l)),i={headers:e.authHeader?{authorization:e.authHeader}:{}},d=e.client?await e.client.fetchResponse(o,i):await s("".concat(r).concat(o),i);if(!d.ok)throw new a(d.status,"media-failed");return d.blob()}}}},94562:(e,t,n)=>{n.d(t,{ChatPanel:()=>eZ});var r=n(55539),a=n(46124),s=n(92156),l=n(94226),o=n(16190),i=n(46586),c=n(71923),d=n(15151),u=n(43537),m=n(37768);function p(){let{client:e}=(0,d.Q)(),[t,n]=(0,a.useState)([]);if((0,a.useEffect)(()=>{if("undefined"==typeof document)return;let t=!0,r=!1,a=async()=>{if(!t||r||document.hidden)return;r=!0;let a=new Intl.DateTimeFormat("sv-SE",{timeZone:"Asia/Seoul"}).format(new Date),s=await (0,u.Nn)(e,a);r=!1,t&&n((0,m.z)("ready"===s.kind?s.data:null,Date.now()))};n([]),a();let s=globalThis.setInterval(()=>{a()},6e4),l=()=>{document.hidden||a()};return document.addEventListener("visibilitychange",l),()=>{t=!1,globalThis.clearInterval(s),document.removeEventListener("visibilitychange",l)}},[e]),0===t.length)return null;let s=t.map(e=>{let{seat:t,text:n,ago:r}=e;return"".concat(t," ").concat(n," \xb7 ").concat(r)}).join(" | ");return(0,r.jsx)("div",{role:"status","aria-label":"지금 자리들이 하는 일",title:s,className:"h-8 min-h-8 min-w-0 shrink-0 overflow-hidden text-ellipsis whitespace-nowrap border-b border-border bg-background px-3 text-xs leading-8 text-muted-foreground",children:t.map((e,t)=>{let{seat:n,text:a,ago:s}=e;return(0,r.jsxs)("span",{children:[t>0&&" | ",n," ",a," \xb7 ",s]},n)})})}var h=n(3180),f=n(72215);function g(){let{client:e}=(0,d.Q)(),[t,n]=(0,a.useState)(!1),[s,l]=(0,a.useState)(!1),[o,i]=(0,a.useState)(""),c=(0,a.useRef)(!1),u=(0,a.useRef)(0),m=(0,a.useRef)(!1);(0,a.useEffect)(()=>(n("speechSynthesis"in window&&"undefined"!=typeof SpeechSynthesisUtterance),()=>{u.current++,m.current&&"speechSynthesis"in window&&window.speechSynthesis.cancel()}),[]);let p=async()=>{if(c.current||!t)return;c.current=!0;let n=++u.current;l(!0),i(""),m.current&&window.speechSynthesis.cancel(),m.current=!1;try{let t=await e.fetchResponse("/v1/context/now?format=voice",{method:"GET"});if(!t.ok)throw Error("HTTP ".concat(t.status));let r=await t.json();if(!r||"object"!=typeof r||!("text"in r)||"string"!=typeof r.text||!r.text.trim())throw Error("invalid voice summary");if(n!==u.current)return;let a=new SpeechSynthesisUtterance(r.text);a.lang="ko-KR",a.onend=()=>{n===u.current&&(m.current=!1)},a.onerror=()=>{n===u.current&&(m.current=!1)},m.current=!0,window.speechSynthesis.speak(a),(0,f.cY)("chat.now.speak",{outcome:"spoken"})}catch(e){if(n!==u.current)return;m.current=!1,i("지금 상황을 읽지 못했습니다. 다시 시도해 주세요."),(0,f.cY)("chat.now.speak",{outcome:"error",reason:String(e)})}finally{n===u.current&&(c.current=!1,l(!1))}};return(0,r.jsxs)("div",{className:"flex shrink-0 items-center gap-1",children:[(0,r.jsxs)("button",{type:"button","data-elanous-action":"chat-now-speak","aria-label":"지금 상황 듣기",title:t?"지금 상황 두 문장 듣기":"이 브라우저는 음성 읽기를 지원하지 않습니다",disabled:!t||s,onClick:()=>void p(),className:"inline-flex min-h-9 items-center gap-1.5 rounded-full border border-border bg-background px-3 text-xs font-medium text-foreground hover:bg-muted disabled:cursor-not-allowed disabled:opacity-50",children:[(0,r.jsx)(h.A,{className:"h-4 w-4","aria-hidden":"true"}),(0,r.jsx)("span",{children:"지금 상황 듣기"})]}),o&&(0,r.jsx)("span",{role:"alert",className:"text-xs text-rose-600",children:o})]})}var x=n(12958),b=n(74780);function v(){let{client:e}=(0,d.Q)(),t=(0,a.useMemo)(()=>(0,b.ll)({client:e}),[e]),[n,s]=(0,a.useState)({client:e,items:[],pending:0,expanded:!1}),l=(0,a.useRef)(e);l.current=e;let o=(0,a.useRef)(!1),i=(0,a.useRef)(0),c=n.client===e?n:null,u=(0,a.useCallback)(async()=>{if(!o.current||l.current!==e||"undefined"!=typeof document&&document.hidden)return;let n=++i.current;try{let r=await t.list();if(!o.current||l.current!==e||i.current!==n)return;s(t=>l.current===e&&i.current===n?{client:e,items:r.items,pending:r.items.length,expanded:r.items.length>0&&t.client===e&&t.expanded}:t)}catch(t){if(!o.current||l.current!==e||i.current!==n)return;s(t=>l.current===e&&i.current===n?{client:e,items:[],pending:0,expanded:!1}:t)}},[t,e]);return((0,a.useEffect)(()=>{o.current=!0,s({client:e,items:[],pending:0,expanded:!1}),u();let t=globalThis.setInterval(()=>{u()},3e4),n=()=>{document.hidden||u()};return"undefined"!=typeof document&&document.addEventListener("visibilitychange",n),()=>{o.current=!1,i.current+=1,globalThis.clearInterval(t),"undefined"!=typeof document&&document.removeEventListener("visibilitychange",n)}},[e,u]),(0,a.useEffect)(()=>{var e,t;(0,f.cY)("chat.approvals",{pending:null!=(e=null==c?void 0:c.pending)?e:0,expanded:null!=(t=null==c?void 0:c.expanded)&&t})},[null==c?void 0:c.pending,null==c?void 0:c.expanded]),null==c?void 0:c.pending)?(0,r.jsxs)("div",{className:"shrink-0 border-b border-border bg-background px-3 py-1.5 text-sm",children:[(0,r.jsxs)("button",{type:"button","aria-expanded":c.expanded,"aria-controls":"chat-approvals-panel",onClick:()=>s(t=>t.client===e?{...t,expanded:!t.expanded}:t),className:"rounded-full border border-border bg-muted px-3 py-1 font-medium text-foreground hover:bg-muted/70",children:["승인 대기 ",c.pending]}),c.expanded&&(0,r.jsx)("div",{id:"chat-approvals-panel",className:"mt-2 max-h-[min(50vh,24rem)] overflow-y-auto rounded-lg border border-border p-3",children:(0,r.jsx)(x.a,{client:e,approvals:c.items,onDecided:()=>{u()},onPendingChange:t=>{l.current===e&&s(n=>n.client===e?{...n,pending:t,...0===t?{items:[],expanded:!1}:{}}:n)}})})]}):null}async function y(e){let t=await e.fetchResponse("/v1/decisions?status=open");if(!t.ok)throw Error("decisions list failed: ".concat(t.status));return(await t.json()).decisions}async function w(e,t,n){let r=await e.fetchResponse("/v1/decisions/".concat(encodeURIComponent(t),"/decide"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({choice:n})});if(!r.ok)throw Error("decision failed: ".concat(r.status))}function j(){var e;let{client:t}=(0,d.Q)(),[n,s]=(0,a.useState)({client:t,items:[],expanded:!1,decided:{},busy:null}),l=(0,a.useRef)(t);l.current=t;let o=(0,a.useRef)(!1),i=(0,a.useRef)(0),c=(0,a.useRef)(null),u=n.client===t?n:null,m=(0,a.useCallback)(async()=>{if(!o.current||l.current!==t||"undefined"!=typeof document&&document.hidden)return;let e=++i.current;try{let n=await y(t);if(!o.current||l.current!==t||i.current!==e)return;s(e=>e.client===t?{...e,items:[...n,...e.items.filter(t=>e.decided[t.id]&&!n.some(e=>e.id===t.id))],expanded:e.expanded&&(n.length>0||e.items.some(t=>e.decided[t.id]))}:e)}catch(n){if(!o.current||l.current!==t||i.current!==e)return;s(e=>e.client===t?{...e,items:[],expanded:!1}:e)}},[t]);(0,a.useEffect)(()=>{o.current=!0,c.current=null,s({client:t,items:[],expanded:!1,decided:{},busy:null}),m();let e=globalThis.setInterval(()=>{m()},3e4),n=()=>{document.hidden||m()};return"undefined"!=typeof document&&document.addEventListener("visibilitychange",n),()=>{o.current=!1,c.current=null,i.current+=1,globalThis.clearInterval(e),"undefined"!=typeof document&&document.removeEventListener("visibilitychange",n)}},[t,m]);let p=async(e,r)=>{if(!c.current&&!n.busy&&!n.decided[e.id]){c.current=e.id,s(n=>n.client===t?{...n,busy:e.id}:n);try{if(await w(t,e.id,r.id),!o.current||l.current!==t)return;c.current=null,s(n=>n.client===t?{...n,busy:null,decided:{...n.decided,[e.id]:r.label}}:n),await m()}catch(e){o.current&&l.current===t&&(c.current=null,s(e=>e.client===t?{...e,busy:null}:e))}}},h=null!=(e=null==u?void 0:u.items.filter(e=>!u.decided[e.id]).length)?e:0;return u&&(h||u.expanded&&u.items.some(e=>u.decided[e.id]))?(0,r.jsxs)("div",{className:"shrink-0 border-b border-border bg-background px-3 py-1.5 text-sm",children:[(0,r.jsxs)("button",{type:"button","aria-expanded":u.expanded,"aria-controls":"chat-decisions-panel",onClick:()=>s(e=>e.client===t?{...e,expanded:!e.expanded}:e),className:"rounded-full border border-border bg-muted px-3 py-1 font-medium text-foreground hover:bg-muted/70",children:["대표 결정 ",h]}),u.expanded&&(0,r.jsx)("ul",{id:"chat-decisions-panel",className:"mt-2 max-h-[min(50vh,24rem)] space-y-2 overflow-y-auto rounded-lg border border-border p-3",children:u.items.map(e=>(0,r.jsxs)("li",{className:"rounded-lg border border-border p-3",children:[(0,r.jsx)("h3",{className:"font-semibold",children:e.title}),(0,r.jsx)("p",{className:"truncate text-muted-foreground",title:e.situation,children:e.situation}),u.decided[e.id]?(0,r.jsxs)("p",{role:"status",children:["결정함 — ",u.decided[e.id]]}):(0,r.jsx)("div",{className:"mt-2 flex flex-wrap gap-2",children:e.options.map(t=>(0,r.jsxs)("button",{type:"button",disabled:!!u.busy,onClick:()=>{p(e,t)},className:"rounded-md border border-border px-2 py-1 hover:bg-muted disabled:opacity-50",children:[t.label,"option"in e.recommendation&&e.recommendation.option===t.id&&(0,r.jsx)("span",{className:"ml-1 text-primary",children:"추천"})]},t.id))})]},e.id))})]}):null}var k=n(84968),N=n(9851);function S(e){let{queue:t,onRemove:n,onClear:a}=e;return 0===t.length?null:(0,r.jsxs)("div",{className:"flex shrink-0 flex-wrap items-center gap-1.5 border-t border-border bg-background px-3 py-2","aria-label":"보낼 차례",children:[t.map((e,t)=>(0,r.jsxs)("span",{className:"inline-flex max-w-full items-center gap-1 rounded-full border border-border bg-muted px-2 py-1 text-xs",children:[(0,r.jsxs)("span",{className:"max-w-[160px] truncate",title:e.text,children:[t+1," \xb7 ",Array.from(e.text).slice(0,20).join("")]}),(0,r.jsx)("button",{type:"button",onClick:()=>n(e.id),"aria-label":"".concat(t+1,"번 지우기"),className:"rounded-full px-1 hover:bg-background",children:"\xd7"})]},e.id)),(0,r.jsx)("button",{type:"button",onClick:a,className:"rounded px-2 py-1 text-xs text-muted-foreground hover:bg-muted",children:"모두 지우기"})]})}function C(e){let t={files:[],tooLarge:0,tooMany:0};for(let n of e)n.file.size>0x1400000?t.tooLarge+=1:t.files.length>=10?t.tooMany+=1:t.files.push(n);return t}function I(e){return!!(e&&Array.from(e.types).includes("Files"))}function A(){return(0,r.jsx)("div",{role:"status","aria-label":"여기에 놓으면 첨부","data-elanous-chat-drop-overlay":"",className:"pointer-events-none absolute inset-0 z-30 flex items-center justify-center bg-background/80 backdrop-blur-sm",children:(0,r.jsxs)("div",{className:"mx-4 rounded-2xl border-2 border-dashed border-primary/60 bg-card/90 px-8 py-6 text-center shadow-lg",children:[(0,r.jsx)("p",{className:"text-lg font-semibold text-foreground",children:"여기에 놓으면 첨부"}),(0,r.jsxs)("p",{className:"mt-2 text-sm text-muted-foreground",children:["파일 ",10,"개까지 \xb7 큰 파일은 빠집니다"]})]})})}function E(e,t,n){if("drop"===t||"end"===t||!n)return{visible:!1,depth:0};let r="enter"===t?e.depth+1:Math.max(0,e.depth-1);return{visible:r>0,depth:r}}var R=n(64667),D=n(44373),T=n(8114);function q(e){let{segmentKey:t,value:n,glyph:a}=e,s=function(e){var t;let n=/(\d{1,3})\s*%/.exec(e);if(!n)return null;let r=Number.parseInt(null!=(t=n[1])?t:"",10);return Number.isFinite(r)?Math.max(0,Math.min(100,r)):null}(n);if(null===s)return(0,r.jsxs)("span",{"data-elanous-hud-key":t,"data-elanous-hud-gauge":"false",className:"inline-flex items-center gap-1 font-mono text-[11px] text-muted-foreground",children:[a?(0,r.jsx)("span",{"aria-hidden":"true",children:a}):null,(0,r.jsx)("span",{children:n})]});let{bar:l,text:o}=s>=80?{bar:"bg-pink-400",text:"text-pink-300"}:s>=60?{bar:"bg-amber-400",text:"text-amber-300"}:{bar:"bg-emerald-500",text:"text-emerald-300"};return(0,r.jsxs)("span",{"data-elanous-hud-key":t,"data-elanous-hud-gauge":"true","data-elanous-hud-percent":String(s),className:"inline-flex items-center gap-1.5 font-mono text-[11px]",children:[a?(0,r.jsx)("span",{"aria-hidden":"true",className:"text-muted-foreground",children:a}):null,(0,r.jsx)("span",{role:"progressbar","aria-valuenow":s,"aria-valuemin":0,"aria-valuemax":100,"aria-label":"".concat(t," ").concat(s,"%"),className:"relative h-2 w-20 overflow-hidden rounded bg-muted/30",children:(0,r.jsx)("span",{"aria-hidden":"true",style:{width:"".concat(s,"%")},className:(0,D.cn)("block h-full",l)})}),(0,r.jsx)("span",{className:(0,D.cn)("tabular-nums",o),children:n})]})}let L=new Set(["variant","workspace","model","token-gauge","ctx","agent-activity","agents"]),U=new Set(["token-gauge","ctx"]),O={normal:"text-foreground",warn:"text-amber-300",danger:"text-pink-300",success:"text-emerald-300",info:"text-sky-300",muted:"text-muted-foreground"};function M(e){var t,n;let{segment:a}=e;if(U.has(a.key))return(0,r.jsx)(q,{segmentKey:a.key,value:a.value,...void 0!==a.glyph?{glyph:a.glyph}:{}});let s=a.tone?O[a.tone]:O.normal;return(0,r.jsxs)("span",{"data-elanous-hud-key":a.key,"data-elanous-hud-tone":null!=(t=a.tone)?t:"normal","data-elanous-hud-priority":String(null!=(n=a.priority)?n:50),className:(0,D.cn)("inline-flex items-center gap-1 font-mono text-[11px]",s),children:[a.glyph?(0,r.jsx)("span",{"aria-hidden":"true",children:a.glyph}):null,(0,r.jsx)("span",{children:a.value})]})}function F(e){let{segments:t,row:n,className:a}=e;return 0===t.length?null:(0,r.jsx)("div",{"data-elanous-hud-row":n,className:(0,D.cn)("flex flex-wrap items-center gap-x-3 gap-y-1",a),children:t.map((e,t)=>(0,r.jsxs)("span",{className:"flex items-center gap-x-3",children:[t>0?(0,r.jsx)("span",{"aria-hidden":"true",className:"text-muted-foreground",children:"\xb7"}):null,(0,r.jsx)(M,{segment:e})]},e.key))})}function P(e){let{segments:t}=e;if(0===t.length)return null;let{top:n,bottom:a}=function(e){let t=[],n=[];for(let r of e)L.has(r.key)?t.push(r):n.push(r);return{top:t,bottom:n}}(t);return(0,r.jsxs)("div",{"data-elanous-hud":"strip",role:"status","aria-label":"HUD status",className:"flex flex-col gap-0.5 border-b border-border/40 bg-muted/10 px-3 py-1.5",children:[(0,r.jsx)(F,{segments:n,row:"top"}),(0,r.jsx)(F,{segments:a,row:"bottom",className:"hidden sm:flex"})]})}let Y=[];function _(){return Y}function J(){let e=(0,a.useSyncExternalStore)(T.er,T.Wl,_);return(0,r.jsx)(P,{segments:e})}function z(e,t){if("string"!=typeof e)return t;let n=/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.\d+)?(?:Z|[+-](\d{2}):(\d{2}))$/.exec(e);if(!n)return t;let[,r,a,s,l,o,i,c,d]=n,u=Number(r),m=Number(a),p=Number(s),h=[31,u%4==0&&(u%100!=0||u%400==0)?29:28,31,30,31,30,31,31,30,31,30,31][m-1];if(p<1||void 0===h||p>h||Number(l)>23||Number(o)>59||Number(i)>59||void 0!==c&&(Number(c)>23||Number(d)>59))return t;let f=Date.parse(e);return Number.isFinite(f)?f:t}var $=n(5997),Q=n(65194),K=n(67903),B=n(36898),G=n(56360),H=n(76573),W=n(75342),Z=n(14222);let V={idle:"음성 대기",connecting:"데몬 연결 중…",listening:"듣는 중",processing:"생각 중…",speaking:"말하는 중",error:"음성 오류"},X={idle:"마이크를 켜서 대화를 시작하세요.",connecting:"잠시만 기다려주세요.",listening:"문장이 끝나면 자동으로 전송됩니다.",processing:"서버가 응답을 생성하는 중입니다.",speaking:"음성 응답을 재생하는 중입니다.",error:"아래 메시지를 확인하고 다시 시도하세요."},ee={idle:"bg-slate-400",connecting:"bg-amber-500",listening:"bg-emerald-500",processing:"bg-sky-500",speaking:"bg-fuchsia-500",error:"bg-rose-600"};function et(e){let{active:t,phase:n,errorMsg:a,onToggle:s,ttsSupported:i=!1,ttsMuted:c=!1,onTtsToggle:d,onInterrupt:u}=e,m="speaking"===n&&"function"==typeof u;return(0,r.jsxs)("div",{"data-elanous-voice-overlay":!0,"aria-hidden":!t,className:(0,D.cn)("pointer-events-none absolute inset-0 z-10 flex items-center justify-center transition-opacity duration-300",t?"pointer-events-auto opacity-100":"opacity-0"),children:[(0,r.jsx)("div",{className:"absolute inset-0 bg-background/60 backdrop-blur-md"}),(0,r.jsxs)("div",{className:"relative mx-4 flex w-full max-w-sm flex-col items-center gap-5 rounded-xl border border-border bg-card px-6 py-7 text-center shadow-xl",children:[(0,r.jsxs)("div",{className:"flex items-center gap-2 text-sm",children:[(0,r.jsx)("span",{className:(0,D.cn)("h-2.5 w-2.5 rounded-full",ee[n],("listening"===n||"speaking"===n||"connecting"===n)&&"animate-pulse"),"aria-hidden":!0}),(0,r.jsx)("span",{className:"font-medium tracking-wide",children:V[n]})]}),(0,r.jsx)("p",{className:"text-xs text-muted-foreground",children:X[n]}),(0,r.jsx)("button",{type:"button",onClick:m?u:s,"data-elanous-action":m?"voice-overlay-interrupt":"voice-overlay-toggle",className:(0,D.cn)("inline-flex h-16 w-16 items-center justify-center rounded-full text-white transition-colors",m?"bg-amber-500 hover:bg-amber-400 animate-pulse":"connecting"===n||"processing"===n?"bg-sky-500 hover:bg-sky-400":"error"===n?"bg-rose-600 hover:bg-rose-500":"bg-rose-500 hover:bg-rose-400"),"aria-label":m?"끼어들기":"마이크 끄기",children:m?(0,r.jsx)(G.A,{className:"h-7 w-7"}):"connecting"===n||"processing"===n?(0,r.jsx)(H.A,{className:"h-7 w-7 animate-spin"}):"error"===n?(0,r.jsx)(W.A,{className:"h-7 w-7"}):(0,r.jsx)(l.A,{className:"h-7 w-7"})}),a&&(0,r.jsx)("p",{className:"max-w-xs text-xs text-rose-500",children:a}),(0,r.jsxs)("div",{className:"flex items-center gap-4",children:[i&&d&&(0,r.jsxs)("button",{type:"button",onClick:d,"data-elanous-action":"voice-overlay-tts-toggle",className:"inline-flex items-center gap-1.5 text-xs text-muted-foreground hover:text-foreground","aria-label":c?"음성 응답 켜기":"음성 응답 끄기","aria-pressed":!c,children:[c?(0,r.jsx)(Z.A,{className:"h-3.5 w-3.5"}):(0,r.jsx)(h.A,{className:"h-3.5 w-3.5"}),(0,r.jsx)("span",{children:c?"음성 응답 OFF":"음성 응답 ON"})]}),(0,r.jsxs)("button",{type:"button",onClick:s,className:"inline-flex items-center gap-1.5 text-xs text-muted-foreground hover:text-foreground","aria-label":"음성 닫고 텍스트로 돌아가기",children:[(0,r.jsx)(o.A,{className:"h-3.5 w-3.5"}),(0,r.jsx)("span",{children:"음성 끄기"})]})]})]})]})}function en(e){let{open:t,onClose:n,lines:s}=e,[l,o]=(0,a.useState)(""),i=(0,a.useMemo)(()=>{if(!l.trim())return null;try{return RegExp(l,"i")}catch(e){return null}},[l]),c=(0,a.useMemo)(()=>l.trim().toLowerCase(),[l]),d=(0,a.useMemo)(()=>{let e=s.length>200?s.slice(s.length-200):s;return i?e.filter(e=>i.test(e.category)||i.test(e.event)):c?e.filter(e=>e.category.toLowerCase().includes(c)||e.event.toLowerCase().includes(c)):e},[s,i,c]);return(0,r.jsx)("div",{"data-elanous-debug-tap-drawer":t?"open":"closed",className:(0,D.cn)("fixed bottom-0 left-0 right-0 z-50 transition-transform duration-200 ease-out","pointer-events-none",t?"translate-y-0":"translate-y-full"),role:"region","aria-label":"Debug Tap Drawer","aria-hidden":!t,children:(0,r.jsxs)("div",{className:(0,D.cn)("pointer-events-auto mx-auto flex max-h-[60vh] w-full max-w-[1100px] flex-col","rounded-t-md border border-b-0 border-border bg-card shadow-xl"),children:[(0,r.jsxs)("header",{className:"flex items-center justify-between gap-2 border-b border-border/60 px-3 py-2",children:[(0,r.jsxs)("div",{className:"flex items-center gap-2",children:[(0,r.jsx)("span",{className:"text-xs font-semibold uppercase tracking-wide text-muted-foreground",children:"Debug Tap"}),(0,r.jsxs)("span",{className:"text-[10px] text-muted-foreground/70","data-elanous-debug-tap-count":d.length,"data-elanous-debug-tap-total":s.length,children:[d.length,"/",s.length]})]}),(0,r.jsxs)("div",{className:"flex items-center gap-2",children:[(0,r.jsx)("input",{type:"text",placeholder:"regex filter…",value:l,onChange:e=>o(e.target.value),spellCheck:!1,autoComplete:"off",className:(0,D.cn)("w-40 rounded border border-border bg-background px-2 py-1 text-[11px] font-mono","focus:outline-none focus:ring-1 focus:ring-primary"),"data-elanous-debug-tap-filter":"","aria-label":"Filter debug lines"}),(0,r.jsx)("button",{type:"button",onClick:n,className:"rounded px-2 py-1 text-xs text-muted-foreground hover:bg-muted hover:text-foreground","aria-label":"Close debug drawer","data-elanous-debug-tap-close":"",children:"✕"})]})]}),(0,r.jsx)("ul",{className:"flex-1 overflow-y-auto px-3 py-2 text-[11px] font-mono","data-elanous-debug-tap-list":"",children:0===d.length?(0,r.jsx)("li",{className:"italic text-muted-foreground/60",children:0===s.length?"(no debug lines yet)":"(no matches for filter)"}):d.map((e,t)=>(0,r.jsx)(er,{line:e},"".concat(e.loggedAt,"-").concat(e.seq,"-").concat(t)))})]})})}function er(e){let{line:t}=e,n=new Date(t.loggedAt).toISOString().slice(11,23);return(0,r.jsxs)("li",{"data-elanous-debug-tap-line":"","data-elanous-category":t.category,"data-elanous-event":t.event,className:"py-0.5",children:[(0,r.jsxs)("span",{className:"text-muted-foreground/70",children:["[",n,"]"]})," ",(0,r.jsxs)("span",{className:"text-amber-400",children:["[",t.category,"]"]})," ",(0,r.jsx)("span",{className:"text-foreground",children:t.event}),void 0!==t.data&&(0,r.jsxs)("details",{className:"ml-4 text-muted-foreground",children:[(0,r.jsx)("summary",{className:"cursor-pointer select-none text-[10px]",children:"data"}),(0,r.jsx)("pre",{className:"m-0 mt-1 whitespace-pre-wrap break-all text-[10px] text-muted-foreground/80",children:function(e){try{return JSON.stringify(e,null,2)}catch(t){return String(e)}}(t.data)})]})]})}var ea=n(60516),es=n(56974),el=n(87969),eo=n(25042),ei=n(9734),ec=n(30158),ed=n(2021);let eu="Other";function em(e){let{request:t,onSubmit:n,onCancel:a,onChatAboutThis:s}=e;return(0,r.jsx)(eo.lG,{open:null!==t,onOpenChange:e=>{e||a()},children:(0,r.jsx)(eo.Cf,{className:"max-w-2xl",children:t?(0,r.jsx)(ep,{request:t,onSubmit:n,onCancel:a,onChatAboutThis:s}):null})})}function ep(e){let{request:t,onSubmit:n,onCancel:s,onChatAboutThis:l}=e,[o,i]=(0,a.useState)(()=>Object.fromEntries(t.questions.map(e=>[e.id,new Set]))),[c,d]=(0,a.useState)({}),[u,m]=(0,a.useState)({}),p=1===t.questions.length?t.questions[0].header:"Pick options",h=(0,a.useMemo)(()=>{for(let n of t.questions){var e;let t=null!=(e=o[n.id])?e:new Set,r=eg(n,o,u);if(0===t.size&&!r)return!1}return!0},[t.questions,o,u]);return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)(eo.c7,{children:[(0,r.jsx)(eo.L3,{children:p}),1===t.questions.length?(0,r.jsx)(eo.rr,{children:t.questions[0].question}):(0,r.jsxs)(eo.rr,{children:[t.questions.length," questions"]})]}),(0,r.jsx)(ed.F,{className:"max-h-[60vh] pr-2",children:(0,r.jsx)("div",{className:"flex flex-col gap-6 py-2",children:t.questions.map(e=>{var t;return(0,r.jsx)(eh,{question:e,isSelected:t=>{var n,r,a;return n=e.id,null!=(a=null==(r=o[n])?void 0:r.has(t))&&a},onToggle:t=>{i(n=>{var r;let a={...n},s=new Set(null!=(r=a[e.id])?r:[]);return e.multiSelect?s.has(t)?s.delete(t):s.add(t):(s.clear(),s.add(t),m(t=>({...t,[e.id]:!1}))),a[e.id]=s,a})},otherActive:eg(e,o,u),onToggleOther:()=>{e.multiSelect?m(t=>{var n;return{...t,[e.id]:!(null!=(n=t[e.id])&&n)}}):i(t=>{let n={...t};return n[e.id]=new Set([eu]),n})},otherText:null!=(t=c[e.id])?t:"",onOtherText:t=>d(n=>({...n,[e.id]:t}))},e.id)})})}),(0,r.jsxs)(eo.Es,{className:"flex-wrap gap-2 sm:justify-between",children:[(0,r.jsx)(ei.$,{variant:"ghost",onClick:l,"aria-label":"Chat about this",children:"\uD83D\uDCAC Chat about this"}),(0,r.jsxs)("div",{className:"flex gap-2",children:[(0,r.jsx)(ei.$,{variant:"outline",onClick:s,children:"Cancel"}),(0,r.jsx)(ei.$,{onClick:function(){let e={},r={};for(let n of t.questions){var a,s;let t=Array.from(null!=(a=o[n.id])?a:[]);if(eg(n,o,u)&&!t.includes(eu)&&t.push(eu),0!==t.length&&(n.multiSelect?e[n.id]=t:e[n.id]=t[0],t.includes(eu))){let e=(null!=(s=c[n.id])?s:"").trim();e.length>0&&(r[n.id]=e)}}let l={answers:e};Object.keys(r).length>0&&(l.otherText=r),n(l)},disabled:!h,children:"Submit"})]})]})]})}function eh(e){var t,n;let{question:a}=e;return(0,r.jsxs)("section",{className:"flex flex-col gap-2",children:[""!==e.question.id?(0,r.jsxs)("div",{className:"flex items-center gap-2",children:[(0,r.jsx)("span",{className:"rounded-full bg-primary/15 px-2 py-0.5 text-xs font-medium text-primary",children:a.header}),a.multiSelect?(0,r.jsx)("span",{className:"text-xs text-muted-foreground",children:"multi-select"}):null]}):null,(0,r.jsxs)("div",{className:"flex flex-col gap-1.5",children:[a.options.map(t=>{var n;return(0,r.jsx)(ef,{multi:null!=(n=a.multiSelect)&&n,option:t,selected:e.isSelected(t.label),onToggle:()=>e.onToggle(t.label)},t.label)}),null==(t=a.includeOther)||t?(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ef,{multi:null!=(n=a.multiSelect)&&n,option:{label:"Other",description:"Type your own response"},selected:e.otherActive,onToggle:e.onToggleOther}),e.otherActive?(0,r.jsx)(ec.p,{value:e.otherText,onChange:t=>e.onOtherText(t.target.value),placeholder:"Type your own response","aria-label":"Other response",className:"ml-8"}):null]}):null]})]})}function ef(e){let{multi:t,option:n,selected:a,onToggle:s}=e;return(0,r.jsxs)("button",{type:"button",role:t?"checkbox":"radio","aria-checked":a,onClick:s,className:"\n flex items-start gap-3 rounded-md border p-3 text-left\n transition-colors\n ".concat(a?"border-primary bg-primary/10":"border-border hover:bg-muted/40","\n "),children:[(0,r.jsx)("span",{className:"mt-0.5 flex h-5 w-5 shrink-0 items-center justify-center ".concat(t?"rounded":"rounded-full"," border ").concat(a?"border-primary bg-primary text-primary-foreground":"border-muted-foreground/40"),"aria-hidden":"true",children:a?t?"✓":"●":null}),(0,r.jsxs)("span",{className:"flex flex-col gap-0.5",children:[(0,r.jsx)("span",{className:"font-medium",children:n.label}),(0,r.jsx)("span",{className:"text-sm text-muted-foreground",children:n.description}),n.preview?(0,r.jsx)("span",{className:"mt-1 rounded bg-muted/40 px-2 py-1 text-xs font-mono text-muted-foreground",children:n.preview}):null]})]})}function eg(e,t,n){var r,a,s;return e.multiSelect?null!=(a=n[e.id])&&a:null!=(s=null==(r=t[e.id])?void 0:r.has(eu))&&s}function ex(e){if(void 0===e)return"";if("string"==typeof e)return e;try{var t;return null!=(t=JSON.stringify(e,null,2))?t:""}catch(e){return""}}function eb(e){let{request:t,receivedAt:n,onChoose:s,onCancel:l}=e,[o,i]=(0,a.useState)(()=>Date.now());(0,a.useEffect)(()=>{if(!t)return;i(Date.now());let e=setInterval(()=>i(Date.now()),1e3);return()=>clearInterval(e)},[t]);let c=t?ex(t.toolCall.rawInput):"",d=t?function(e){if(e&&"object"==typeof e&&!Array.isArray(e)){for(let t of["file_path","filePath","path","command","cmd"])if("string"==typeof e[t])return e[t].slice(0,80)}return ex(e).replace(/\s+/g," ").slice(0,80)}(t.toolCall.rawInput):"",u=Math.max(0,Math.ceil((n+6e4-o)/1e3));return(0,r.jsx)(eo.lG,{open:null!==t,onOpenChange:e=>{!e&&t&&l(t)},children:(0,r.jsx)(eo.Cf,{className:"max-w-lg",children:t&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)(eo.c7,{children:[(0,r.jsx)(eo.L3,{children:"이 작업을 실행할까요?"}),(0,r.jsxs)(eo.rr,{children:["도구: ",t.toolCall.title]})]}),d&&(0,r.jsx)("p",{className:"truncate font-mono text-sm",title:d,children:d}),c&&(0,r.jsxs)("details",{className:"text-sm",children:[(0,r.jsx)("summary",{className:"cursor-pointer",children:"자세히"}),(0,r.jsx)("pre",{className:"mt-2 max-h-48 overflow-auto whitespace-pre-wrap break-all rounded bg-muted p-2",children:c})]}),(0,r.jsxs)("p",{className:"text-xs text-muted-foreground","aria-live":"off",children:["남은 시간: ",u,"초"]}),(0,r.jsxs)(eo.Es,{className:"flex-wrap gap-2",children:[(0,r.jsx)(ei.$,{onClick:()=>s(t,"allow_once"),children:"이번만 허용"}),(0,r.jsx)(ei.$,{variant:"outline",onClick:()=>s(t,"allow_always"),children:"이 도구는 항상 허용"}),(0,r.jsx)(ei.$,{variant:"outline",onClick:()=>s(t,"reject_once"),children:"거절"})]})]})})})}let ev={outcome:{outcome:"cancelled"}},ey=["allow_once","allow_always","reject_once","reject_always"],ew="unverified";var ej=n(60750),ek=n(67327);function eN(e,t){var n;return"error"!==t.kind?null:null!=(n=function(e){if(!e||"object"!=typeof e)return null;let{error:t,message:n,holder:r}=e;return"turn_busy"!==t?null:{message:"string"==typeof n?n:"This session is currently receiving input. Please try again when that turn finishes.",holder:"string"==typeof r&&r.trim()?r:null}}(t.payload))?n:e}var eS=n(61897);function eC(e){return"string"==typeof e.mediaType&&e.mediaType.toLowerCase().startsWith("image/")}async function eI(e,t){let n=e.downloadUrl.startsWith("http")?e.downloadUrl:"".concat(t.baseUrl.replace(/\/$/,"")).concat(e.downloadUrl),r={};t.token&&(r.authorization="Bearer ".concat(t.token));let a=await fetch(n,{headers:r});if(!a.ok)throw Error("fetch attachment ".concat(e.id," failed: ").concat(a.status));return function(e){let t=new Uint8Array(e),n="";for(let e=0;e<t.length;e+=32768)n+=String.fromCharCode(...t.subarray(e,e+32768));return btoa(n)}(await a.arrayBuffer())}async function eA(e,t,n){if(0===t.length)return null;let r=[];for(let a of(e.length>0&&r.push({type:"text",text:e}),t))if(eC(a))try{let e=await eI(a,n);r.push({type:"image",mimeType:a.mediaType,data:e})}catch(t){let e=t instanceof Error?t.message:String(t);r.push({type:"text",text:"[image fetch failed: ".concat(a.filename," — ").concat(e,"]")})}else r.push({type:"resource_link",uri:a.path?"file://".concat(a.path):a.downloadUrl,mimeType:a.mediaType,name:a.filename});return r}let eE="elanous.pwa.pendingCardFollowups";function eR(e,t){try{var n;let r=JSON.parse(null!=(n=e.getItem(eE))?n:"[]");if(!Array.isArray(r))return[];return r.filter(e=>!!e&&"object"==typeof e&&"string"==typeof e.sessionId&&e.sessionId.length>0&&"string"==typeof e.id&&e.id.length>0&&"number"==typeof e.startedAt&&Number.isFinite(e.startedAt)&&e.startedAt<=t&&t-e.startedAt<9e5)}catch(e){return[]}}function eD(e,t){try{t.length?e.setItem(eE,JSON.stringify(t)):e.removeItem(eE)}catch(e){}}function eT(){try{return window.localStorage}catch(e){return}}async function eq(e,t,n,r){let a=await e.fetchResponse("/v1/card-followup",{...r?{signal:r}:{},method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({attachmentId:t,...void 0===n?{}:{context:n}})});if(!a.ok)throw Error("card followup start failed: ".concat(a.status));let s=await a.json();if("string"!=typeof s.id||!s.id)throw Error("card followup start returned no id");return s.id}async function eL(e,t){let n,{intervalMs:r=3e3,signal:a,onStatus:s,startedAt:l}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},o=void 0===l?6e5:Math.max(0,l+9e5-Date.now()),i=Date.now()+o,c={status:"failed"},d=new AbortController,u=a?AbortSignal.any([a,d.signal]):d.signal,m=!1,p=function(e){let t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];return new Promise((n,r)=>{let s;if(u.aborted){var l;r(null!=(l=null==a?void 0:a.reason)?l:Error("aborted"));return}let o="undefined"==typeof document?void 0:document,i=()=>{clearTimeout(s),null==o||o.removeEventListener("visibilitychange",c),u.removeEventListener("abort",d)},c=()=>{(null==o?void 0:o.visibilityState)!=="hidden"&&(i(),n())},d=()=>{var e;i(),r(null!=(e=null==a?void 0:a.reason)?e:Error("aborted"))};s=setTimeout(()=>{i(),n()},e),t&&(null==o||o.addEventListener("visibilitychange",c)),u.addEventListener("abort",d,{once:!0})})},h=async()=>{for(;Date.now()<i;){var n,l;if(null==a?void 0:a.aborted)throw null!=(n=a.reason)?n:Error("aborted");if("undefined"!=typeof document&&"hidden"===document.visibilityState){await p(i-Date.now(),!0);continue}let o=await e.fetchResponse("/v1/card-followup/".concat(encodeURIComponent(t)),{signal:u});if(!o.ok)throw Error("card followup poll failed: ".concat(o.status));let d=await o.json();if(null==a?void 0:a.aborted)throw null!=(l=a.reason)?l:Error("aborted");if(m)return c;if(null==s||s(d.status),"done"===d.status||"not-card"===d.status||"failed"===d.status)return d;await p(Math.min(Math.max(0,r),Math.max(0,i-Date.now())))}return null==s||s("failed"),c};try{return await Promise.race([h(),new Promise(e=>{n=setTimeout(()=>{m=!0,d.abort(),null==s||s("failed"),e(c)},o)})])}finally{clearTimeout(n)}}function eU(){var e;let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{compact:n}=(0,c.K)(),[u,m]=(0,a.useState)(!1),h=(0,a.useRef)(null);(0,a.useEffect)(()=>{if(!u)return;let e=e=>{h.current&&h.current.contains(e.target)||m(!1)},t=e=>{"Escape"===e.key&&m(!1)};return document.addEventListener("pointerdown",e),document.addEventListener("keydown",t),()=>{document.removeEventListener("pointerdown",e),document.removeEventListener("keydown",t)}},[u]),(0,a.useEffect)(()=>{n||m(!1)},[n]);let{client:x,config:b,sessionId:y,setSessionId:w}=(0,d.Q)(),[q,L]=(0,a.useState)([]),[U,O]=(0,a.useState)(),[M,F]=(0,a.useState)(!1),[P,Y]=(0,a.useState)([]),_=(0,a.useRef)([]),G=(0,a.useRef)(y),H=(0,a.useRef)(y),W=(0,a.useRef)(null),Z=(0,a.useRef)(0),V=(0,a.useRef)(0),X=(0,a.useRef)(!1),[ee,er]=(0,a.useState)(null),eo=G.current!==y&&W.current!==y?[]:P;(0,a.useLayoutEffect)(()=>{H.current=y,G.current!==y&&(W.current!==y&&(Z.current++,_.current=[],Y([]),L([]),eg.current&&F(!1)),G.current=y,W.current=null)},[y]);let ei=e=>{_.current=e,Y(e)},[ec,ed]=(0,a.useState)(null),[eu,ep]=(0,a.useState)(null),[eh,ef]=(0,a.useState)([]),eg=(0,a.useRef)(null),ex=(0,a.useRef)(null);(0,a.useEffect)(()=>()=>{var e;ex.current!==H.current&&(null==(e=eg.current)||e.abort())},[y]),(0,a.useEffect)(()=>()=>{var e;null==(e=eg.current)||e.abort()},[]);let[eI,eE]=(0,a.useState)({visible:!1,depth:0});(0,a.useEffect)(()=>{let e=()=>eE(e=>E(e,"end",!1));return window.addEventListener("dragend",e),()=>window.removeEventListener("dragend",e)},[]);let eU=(0,a.useRef)(!1),eO=(0,a.useRef)(null),eM=(0,a.useRef)(null),[eF,eP]=(0,a.useState)(null),eY=(0,a.useMemo)(()=>{try{let e=new URLSearchParams(window.location.search);return"on"===e.get("debug-tap")}catch(e){return!1}},[]),[e_,eJ]=(0,a.useState)(eY),ez=(0,a.useMemo)(()=>{let e=[];for(let t of q)if(Array.isArray(t.blocks)){for(let n of t.blocks)if("debug_session"===n.kind)for(let t of n.lines)e.push({seq:t.seq,category:t.category,event:t.event,...void 0!==t.data?{data:t.data}:{},loggedAt:t.loggedAt})}return e},[q]),e$=(0,a.useRef)(async()=>{}),eQ=(0,a.useRef)(!1);eQ.current=M;let eK=(0,a.useRef)(async()=>{}),eB=x.voiceWsUrl(),eG=(0,a.useCallback)(e=>{let t=e.trim();if(t){if(eQ.current)return void(0,f.cY)("chat.voice.skip-pending",{len:t.length});(0,f.cY)("chat.voice.auto-send",{len:t.length}),e$.current(t)}},[]),eH=(0,es.sS)({wsUrl:eB,...b.token?{token:b.token}:{},onTranscript:eG}),eW=!!b.baseUrl;eK.current=()=>eH.toggle();let[eZ,eV]=(0,a.useState)(!1),eX=(0,el.$)({enabled:eH.active&&!eZ,language:"ko-KR"}),e0=(0,a.useCallback)(()=>{null==eu||eu.abort(),(0,f.cY)("webterm.chat.stop",{had:!!eu})},[eu]);(0,a.useEffect)(()=>{if(!eu)return;let e=e=>{var t;if("Escape"!==e.key)return;let n=e.target,r=null==n||null==(t=n.tagName)?void 0:t.toLowerCase();"input"===r||"textarea"===r||null!=n&&n.isContentEditable||(e.preventDefault(),e0())};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[eu,e0]),(0,a.useEffect)(()=>{let e=e=>{"m"===e.key.toLowerCase()&&e.shiftKey&&(e.metaKey||e.ctrlKey)&&(e.preventDefault(),(0,f.cY)("chat.voice.shortcut.toggle"),eK.current())};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[]);let e1=(0,a.useCallback)(e=>{ef(t=>[...t,...e]),(0,f.cY)("webterm.chat.attach.queue",{added:e.length,filenames:e.map(e=>e.filename)})},[]),e2=async e=>{let{files:t,tooLarge:n,tooMany:r}=e;if(n&&ek.oR.error("".concat(n," files exceed the 20 MB attachment limit")),r&&ek.oR.error("".concat(r," files exceed the 10-file attachment limit")),0===t.length)return;if(!b.baseUrl)return void ek.oR.error("Daemon URL 미설정 — Settings 에서 입력");let a=await (0,eS.K)(t,{baseUrl:b.baseUrl,...b.token?{token:b.token}:{}}),s=a.filter(e=>e.ok).map(e=>e.meta),l=a.filter(e=>!e.ok);s.length&&(e1(s),ek.oR.success(1===s.length?"\uD83D\uDCCE ".concat(s[0].filename):"\uD83D\uDCCE ".concat(s.length," files attached"))),l.length&&ek.oR.error(1===l.length?"업로드 실패: ".concat(l[0].reason.slice(0,80)):"".concat(l.length," 파일 업로드 실패"))};(0,a.useEffect)(()=>{try{let e=window.sessionStorage.getItem("elanous.pwa.shareAttachments");if(!e)return;window.sessionStorage.removeItem("elanous.pwa.shareAttachments");let t=JSON.parse(e);if(!Array.isArray(t)||0===t.length)return;ef(e=>[...e,...t]);let n=1===t.length?"1 file shared from another app":"".concat(t.length," files shared from another app");ek.oR.success(n),(0,f.cY)("pwa.chat.share-attachments.consume",{count:t.length})}catch(e){(0,f.cY)("pwa.chat.share-attachments.parse-failed",{reason:e instanceof Error?e.message:String(e)})}},[]),(0,a.useEffect)(()=>{if(!y)return;let e=!0;return(async()=>{try{let t=await x.fetchJson("/v1/sessions/store/".concat(encodeURIComponent(y),"?ifExists=1"));if(!e||!(null==t?void 0:t.messages)||0===t.messages.length)return;L(e=>e.some(e=>!e.id.startsWith("m-card-resume-"))?e:[...function(e,t){let n,r,a=[],s=[];for(let o of e){var l;if("tool"===o.role){for(let e of(0===s.length&&(r=o.ts),function(e,t){let n,r=function(e,t){var n,r;let a,s=String(null!=(n=e.toolName)?n:"");try{a=JSON.parse(String(null!=(r=e.toolResult)?r:""))}catch(e){a=void 0}let l=a&&"object"==typeof a&&!Array.isArray(a)?a:void 0,o=null==l?void 0:l._meta,i=o&&"object"==typeof o&&!Array.isArray(o)?o.ui:void 0,c=i&&"object"==typeof i&&!Array.isArray(i)?i.resourceUri:void 0,d=null==l?void 0:l["ui/resourceUri"],u="string"==typeof c?c:"string"==typeof d?d:void 0;return void 0!==u&&""!==u.trim()?{kind:"mcp_app",toolId:t,toolName:s,screenUrl:u,...void 0!==a?{toolResult:a}:{}}:{kind:"tool_use",id:t,name:s,status:"done",...void 0!==l&&void 0!==e.toolArgs?{args:{raw:String(e.toolArgs)}}:{}}}(e,t);try{var a;n=JSON.parse(String(null!=(a=e.toolResult)?a:""))}catch(e){n=void 0}let s=(0,T.uS)(n).map(e=>({kind:"image",...e})),l=[];return(0,T.ki)(l,null!=n?n:e.toolResult),[...s,r,...l]}(o,"restore-tool-".concat(s.length,"-").concat(a.length))))"image"===e.kind&&s.some(t=>"image"===t.kind&&t.src===e.src)||s.push(e);continue}if("user"!==o.role&&"assistant"!==o.role)continue;let e=String(null!=(l=o.content)?l:""),i=String(null!=e?e:"").split("\n").filter(e=>!/^\[tool_(use|result)\]$/.test(e.trim())).join("\n"),c="assistant"===o.role?"assistant":"user";if(""===i.trim()){s.length>0&&"assistant"===c&&(a.push({id:"restore-".concat(a.length),role:c,text:"",blocks:s,timestamp:z(r,t+a.length)}),s=[],r=void 0);continue}let d=i!==e,u=void 0!==n&&n.role===c&&n.text===i&&(d||n.wasStripped)&&0===s.length;if(n={role:c,text:i,wasStripped:d},u)continue;let m=s.length>0&&"assistant"===c?[...s,{kind:"text",text:i}]:void 0,p=z(void 0!==m?r:o.ts,t+a.length);void 0!==m&&(s=[],r=void 0),a.push({id:"restore-".concat(a.length),role:c,text:i,...void 0!==m?{blocks:m}:{},timestamp:p})}return s.length>0&&a.push({id:"restore-".concat(a.length),role:"assistant",text:"",blocks:s,timestamp:z(r,t+a.length)}),a}(t.messages,Date.now()),...e])}catch(e){}})(),()=>{e=!1}},[y,x]);let e3=(0,a.useCallback)(e=>{ef(t=>t.filter(t=>t.id!==e))},[]),e5={client:x,sessionId:y,provider:b.provider,setSessionId:w,daemon:{baseUrl:b.baseUrl,...b.token?{token:b.token}:{}},messages:q},e4=e=>{L(t=>[...t,e])},e6=async(e,t,n,r,a)=>{var s;let l=await eL(x,e,{signal:r.signal,...void 0===a?{}:{startedAt:a},onStatus:e=>(0,f.cY)("pwa.chat.card-followup",{phase:"poll",status:e})});if(r.signal.aborted||H.current!==t)return"terminal";let o=eT();return(o&&function(e,t,n){let r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:Date.now();eD(e,eR(e,r).filter(e=>e.sessionId!==t||e.id!==n))}(o,t,e),"not-card"===l.status)?(L(e=>e.filter(e=>e.id!==n)),(0,f.cY)("pwa.chat.card-followup",{phase:"fallback",status:l.status}),"not-card"):("done"===l.status&&(null==(s=l.replies)?void 0:s.length)===3&&l.replies.every(e=>"string"==typeof e)?(L(e=>[...e.filter(e=>e.id!==n),...l.replies.map((e,t)=>({id:"".concat(n,"-").concat(t),role:"assistant",text:e,timestamp:Date.now(),meta:{provider:b.provider}}))]),(0,f.cY)("pwa.chat.card-followup",{phase:"complete",status:"done"})):(L(e=>e.map(e=>e.id===n?{...e,text:"명함 정리에 실패했습니다 — 다시 보내 주세요"}:e)),(0,f.cY)("pwa.chat.card-followup",{phase:"complete",status:"failed"})),"terminal")};(0,a.useEffect)(()=>{if(!y)return;let e=eT();if(!e)return;let t=(function(e,t){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:Date.now(),r=eR(e,n);return eD(e,r),r.filter(e=>e.sessionId===t)})(e,y).map(e=>{let{id:t,startedAt:n}=e,r=new AbortController,a="m-card-resume-".concat(t);return L(e=>e.some(e=>e.id===a)?e:[...e,{id:a,role:"assistant",text:"명함 읽는 중… 조사 중…",timestamp:n,meta:{provider:b.provider}}]),e6(t,y,a,r,n).catch(()=>{r.signal.aborted||H.current!==y||L(e=>e.map(e=>e.id===a?{...e,text:"명함 정리에 실패했습니다 — 다시 보내 주세요"}:e))}),r});return()=>{t.forEach(e=>e.abort())}},[x,y]);let e8=async function(e){let n=arguments.length>1&&void 0!==arguments[1]&&arguments[1];ed(e=>eN(e,{kind:"turn-begin"})),(0,f.cY)("webterm.chat.input",{len:e.length,attachCount:eh.length});let r=n?[]:eh;n||ef([]);let a=n?{ok:!1}:function(e,t){if(1!==t.length||!t[0]||!eC(t[0])||!t[0].id)return{ok:!1};let n=e.trim();if(!n)return{ok:!0,attachmentId:t[0].id};let r=n.replace(/메일\s*초안/g,"메일초안").split(/[\s,]+/).filter(Boolean);return!r.length||r.some(e=>!/^(?:명함|전략|메일초안|crm)$/i.test(e))?{ok:!1}:{ok:!0,attachmentId:t[0].id,context:n}}(e,r),s=!1;if(a.ok){let n=H.current;if(!n){var l;W.current=n=(0,$.f6)(),H.current=n,null==(l=t.onSessionAdopt)||l.call(t,n),w(n)}let o=new AbortController;eg.current=o,ex.current=n,s=!0,e.length>0&&e4((0,T.tw)(e)),e4((0,T.$Q)("\uD83D\uDCCE attached: ".concat(r.map(e=>e.filename).join(", "))));let i="m-card-".concat(Date.now(),"-").concat(Math.random().toString(36).slice(2,6));e4({id:i,role:"assistant",text:"명함 읽는 중… 조사 중…",timestamp:Date.now(),meta:{provider:b.provider}}),F(!0),(0,f.cY)("pwa.chat.card-followup",{phase:"start",status:"judging"});try{let e=await eq(x,a.attachmentId,a.context,o.signal);if(o.signal.aborted||H.current!==n)return;let t=eT(),r=Date.now();t&&function(e,t){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:Date.now(),r=eR(e,n).filter(e=>e.sessionId!==t.sessionId||e.id!==t.id);if(!t.sessionId||!t.id||!Number.isFinite(t.startedAt)||t.startedAt>n||n-t.startedAt>=9e5)return eD(e,r);eD(e,[...r,t])}(t,{sessionId:n,id:e,startedAt:r});let s=await e6(e,n,i,o,r);if("terminal"===s||o.signal.aborted||H.current!==n)return}catch(e){if(o.signal.aborted||H.current!==n)return;L(e=>e.map(e=>e.id===i?{...e,text:"명함 정리에 실패했습니다 — 다시 보내 주세요"}:e)),(0,f.cY)("pwa.chat.card-followup",{phase:"complete",status:"failed"});return}finally{eg.current===o&&(eg.current=null),o.signal.aborted||H.current!==n||(F(!1),ed(e=>eN(e,{kind:"turn-end"})))}}let o=r.filter(eC),i=r.filter(e=>!eC(e)),c=function(e){if(!e)return!0;let t=e.toLowerCase();return!!("auto"===t||t.startsWith("anthropic")||"anthropic"===t||t.startsWith("codex")||"openai-codex"===t||t.startsWith("openai")||"openai"===t||t.startsWith("gemini")||"gemini"===t||t.startsWith("grok")||"grok"===t||t.startsWith("local"))}(b.provider),d=o.length>0&&c;o.length>0&&!c&&ek.oR.warning("이 모델은 이미지 입력을 지원하지 않습니다 — ".concat(o.length,"개 이미지가 무시됩니다. (vision 모델로 전환 후 재첨부)"));let u=i.map(e=>e.path?"[attached] ".concat(e.path):"").filter(e=>e.length>0),m=u.length>0?"".concat(u.join("\n"),"\n\n").concat(e).trimEnd():e,p=null;if(d&&b.baseUrl)try{p=await eA(m,o,{baseUrl:b.baseUrl,token:b.token})}catch(t){let e=t instanceof Error?t.message:String(t);(0,f.cY)("webterm.chat.attach.contentblock.error",{msg:e}),ek.oR.error("이미지 첨부 변환 실패 — 텍스트만 전송: ".concat(e)),p=null}!s&&(e.length>0&&e4((0,T.tw)(e)),r.length>0&&e4((0,T.$Q)("\uD83D\uDCCE attached: ".concat(r.map(e=>e.filename).join(", ")))));let h=e?await (0,T.yN)(e,e5):null;if(h){if("__CLEAR__"===h.text)L([]);else{let e=(0,T.$Q)(h.text);h.harnessAsk&&(e.blocks=[{kind:"harness_ask",acceptanceId:h.harnessAsk.acceptanceId}]),e4(e)}h.newSessionId&&(Z.current++,ei([]),G.current=h.newSessionId,H.current=h.newSessionId,w(h.newSessionId));return}if(!b.baseUrl)return void e4((0,T.$Q)("error: daemon baseUrl not configured. Visit /settings."));F(!0),eU.current=!0;let g="m-stream-".concat(Date.now(),"-").concat(Math.random().toString(36).slice(2,6));e4({id:g,role:"assistant",text:"",timestamp:Date.now(),meta:{provider:b.provider}});let v=new AbortController;ep(v);let j=0,k=eM.current,N=!!(k&&y&&b.baseUrl),S=null;(0,f.cY)("webterm.chat.runturn.path",{useAcpPath:N,hasAcp:!!k,hasSession:!!y});let C=e=>{L(t=>t.map(t=>t.id===g?{...t,text:e}:t)),e.length>j&&(eX.pushText(e.slice(j)),j=e.length)},I=e=>{L(t=>t.map(t=>t.id===g?{...t,blocks:e}:t))};try{N&&(S=x.connectAcp({sessionId:y}));let{message:e,newSessionId:t}=N?await (0,T.py)(S,m,{...e5,sessionId:await S.ready||y},{signal:v.signal,...p?{userContent:p}:{},onPartial:C,onPartialBlocks:I}):await (0,T.HD)(m,e5,{signal:v.signal,...p?{userContent:p}:{},...e_?{debugTap:!0}:{},onPartial:C,onPartialBlocks:I,onError:e=>ed(t=>eN(t,{kind:"error",payload:e}))});ed(e=>eN(e,{kind:"turn-end"})),L(t=>t.map(t=>t.id===g?e:t)),t&&t!==y&&H.current===y&&(W.current=t,H.current=t,w(t)),eX.flush()}catch(n){let e=v.signal.aborted,t=n instanceof Error?n.message:String(n);eX.cancel(),e?(L(e=>e.map(e=>e.id===g?{...e,meta:{...e.meta,stopReason:"aborted"}}:e)),(0,f.cY)("webterm.chat.runturn.stream.abort",{reason:t})):(L(e=>e.filter(e=>e.id!==g)),e4((0,T.$Q)("error: ".concat(t))),ek.oR.error("chat failed: ".concat(t)),(0,f.cY)("webterm.chat.runturn.error",{reason:t,useAcpPath:N}))}finally{null==S||S.close(),F(!1),ep(null),eU.current=!1}},e7=async function(e){let t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];if(X.current||!t&&_.current.length>0){var n,r;if(!t&&(eh.length>0||/^[\s]*[:/]/.test(e))){ek.oR.info("답이 끝난 뒤 보내 주세요"),O(t=>{var n;return{text:e,id:(null!=(n=null==t?void 0:t.id)?n:0)+1}});return}let a=(n=_.current,(r={id:++V.current,text:e}).text.trim()?n.length>=5?{queue:[...n],error:"줄이 찼습니다"}:{queue:[...n,{...r,text:r.text.trim()}]}:{queue:[...n]});a.error?(ek.oR.info(a.error),O(t=>{var n;return{text:e,id:(null!=(n=null==t?void 0:t.id)?n:0)+1}})):ei(a.queue);return}X.current=!0;let a=Z.current,s=H.current;try{await e8(e,t)}finally{X.current=!1,a!==Z.current&&(0,f.cY)("webterm.chat.queue.session-changed",{turnSessionId:s,currentSessionId:H.current}),er({generation:Z.current,sessionId:H.current})}};(0,a.useEffect)(()=>{var e;if(X.current||0===_.current.length||!ee||ee.generation!==Z.current||ee.sessionId!==y)return;let{entry:t,queue:n}={entry:(e=_.current)[0],queue:e.slice(1)};t&&(ei(n),e$.current(t.text,!0))},[ee]),e$.current=e7,(0,a.useEffect)(()=>{ed(e=>eN(e,{kind:"session-change"}))},[y]),(0,a.useEffect)(()=>{if(!y||!b.baseUrl)return;let e=(0,T.lY)(x,y,{isLocalTurnInFlight:()=>eU.current,provider:b.provider,onPlaceholder:e=>{let{sessionId:t}=e;ed(e=>eN(e,{kind:"turn-begin"}));let n="m-obs-".concat(Date.now(),"-").concat(Math.random().toString(36).slice(2,6)),r={id:n,role:"assistant",text:"",timestamp:Date.now(),meta:{provider:b.provider}};return(0,f.cY)("webterm.chat.observer.placeholder",{id:n,turnSessionId:t}),L(e=>[...e,r]),eO.current=n,n},onPartialBlocks:(e,t)=>{L(n=>n.map(n=>n.id===e?{...n,blocks:t}:n))},onFinalize:(e,t)=>{ed(e=>eN(e,{kind:"turn-end"})),L(n=>n.map(n=>n.id===e?t:n)),eO.current===e&&(eO.current=null)},onError:(e,t)=>{ed(e=>eN(e,{kind:"error",payload:t})),(0,f.cY)("webterm.chat.observer.error",{placeholderId:e,error:t.error}),L(n=>n.map(n=>n.id===e?{...n,meta:{...n.meta,stopReason:t.error}}:n)),eO.current===e&&(eO.current=null)}});return()=>{e()}},[x,y,b.baseUrl,b.provider]),(0,a.useEffect)(()=>{if(!y||!b.baseUrl)return;let e=x.subscribeChatFeedbackEvents(y,{agentStatus:{onFeedback:e=>{L(t=>{if(0===t.length)return t;for(let n=t.length-1;n>=0;n--){if("assistant"!==t[n].role)continue;let r=t[n],a=Array.isArray(r.blocks)?[...r.blocks]:[];if("applied"!==(0,ea.K4)(a,e))break;let s={...r,blocks:a};return[...t.slice(0,n),s,...t.slice(n+1)]}return t})},onError:e=>{(0,f.cY)("webterm.agent-status.error",e)}},hudSegment:{onFeedback:e=>(0,T.Ju)(e),onError:e=>{(0,f.cY)("webterm.hud-segment.error",e)}}});return()=>{e()}},[x,y,b.baseUrl]),(0,a.useEffect)(()=>{if(!y||!b.baseUrl)return;let e=null;try{e=x.connectAcp({sessionId:y,onSession:e=>{if(e&&e!==y){var n;(0,f.cY)("webterm.chat.acp.session-adopt",{previous:y,issued:e}),H.current===y&&(W.current=e,H.current=e,null==(n=t.onSessionAdopt)||n.call(t,e),w(e))}}})}catch(e){(0,f.cY)("webterm.chat.acp.connect-failed",{reason:String(e)});return}eM.current=e,eP(e);let n=e;(0,f.x8)(async e=>{let t=JSON.parse(e);return await n.send("elanous/debug-logs/ingest",{records:t.records}),!0});let r=(0,T.ZH)(e,y,{isLocalTurnInFlight:()=>eU.current,isRemoteSseTurnInFlight:()=>null!==eO.current,onPlaceholder:e=>{let{sessionId:t}=e;ed(e=>eN(e,{kind:"turn-begin"}));let n="m-acp-".concat(Date.now(),"-").concat(Math.random().toString(36).slice(2,6)),r={id:n,role:"assistant",text:"",timestamp:Date.now(),meta:{provider:b.provider}};return(0,f.cY)("webterm.chat.acp.foreign-placeholder",{id:n,turnSessionId:t}),L(e=>[...e,r]),n},onPartialBlocks:(e,t)=>{let n=t.find(e=>"text"===e.kind),r=t.some(e=>"image"===e.kind||"tool_use"===e.kind);L(a=>a.map(a=>a.id===e?{...a,...n?{text:n.text}:{},...r?{blocks:t}:{}}:a))},onFinalize:e=>{(0,f.cY)("webterm.chat.acp.foreign-finalize",{placeholderId:e})}});return()=>{r(),(0,f.x8)(null);try{null==e||e.close()}catch(e){}eM.current===e&&(eM.current=null),eP(null)}},[x,y,b.baseUrl,b.provider]);let e9=function(e){var t;let{acp:n,onComposerPrefill:r}=e,[s,l]=(0,a.useState)(null),o=(0,a.useRef)(null),i=(0,a.useCallback)(e=>{o.current=e,l(e)},[]),c=(0,a.useCallback)(e=>{let t=o.current;t&&(t.resolve(e),i(null))},[i]);(0,a.useEffect)(()=>{if(!n)return;let e=n.onRequest("elanous/ask/request",async e=>{let t=function(e){if(!e||"object"!=typeof e||"string"!=typeof e.id||!e.id||!e.request||"object"!=typeof e.request)return null;let t=e.request;return Array.isArray(t.questions)&&0!==t.questions.length?{id:e.id,request:e.request}:null}(e);if(!t)return{answers:{},cancelled:!0};let n=o.current;return n&&n.resolve({answers:{},cancelled:!0}),await new Promise(e=>{i({request:t.request,resolve:e,askId:t.id})})}),t=n.on("sessionUpdate",()=>{}),r=n.onAny(e=>{var t;if("elanous/ask/cancel"!==e.method||void 0!==e.id)return;let n=(t=e.params)&&"object"==typeof t&&"string"==typeof t.id&&t.id?{id:t.id,..."string"==typeof t.reason?{reason:t.reason}:{}}:null;if(!n)return;let r=o.current;r&&r.askId===n.id&&c({answers:{},cancelled:!0})});return()=>{e(),t(),r();let n=o.current;n&&(n.resolve({answers:{},cancelled:!0}),o.current=null)}},[n,i,c]);let d=(0,a.useCallback)(e=>{c(e)},[c]),u=(0,a.useCallback)(()=>{c({answers:{},cancelled:!0})},[c]),m=(0,a.useCallback)(()=>{let e=o.current;e&&r&&r(e.request),c({answers:{},cancelled:!0})},[c,r]);return{pendingRequest:null!=(t=null==s?void 0:s.request)?t:null,submit:d,cancel:u,chatAboutThis:m}}({acp:eF,onComposerPrefill:e=>{let t=e.questions[0];if(!t)return;let n="[ Q: ".concat(t.question.trim()," ]\n\n");(0,Q.vn)(n),O(e=>{var t;return{text:n,id:(null!=(t=null==e?void 0:e.id)?t:0)+1}}),ek.oR.info("\uD83D\uDCAC 입력 영역에 질문 prefill 됨 (Chat about this)")}}),te=function(e){var t,n;let{acp:r,sessionId:s}=e,[l,o]=(0,a.useState)(null),i=(0,a.useRef)(null),c=(0,a.useRef)(s);c.current=s;let d=(0,a.useCallback)((e,t,n)=>{let r=i.current;r&&(!n||r.request===n)&&(i.current=null,clearTimeout(r.timer),o(null),(0,f.cY)("pwa.tool-approval.".concat("cancelled"===t?"cancelled":"decided"),{tool:ew,choice:t}),r.resolve(e))},[]);(0,a.useEffect)(()=>{if(!r)return;let e=r.onRequest("session/request_permission",e=>{let t=function(e){try{if(!e||"object"!=typeof e)return null;let t=e.toolCall;if(!t||"object"!=typeof t||"string"!=typeof e.sessionId||!e.sessionId||"string"!=typeof t.toolCallId||!t.toolCallId||"string"!=typeof t.title||!t.title||!Array.isArray(e.options))return null;let n=e.options.map(e=>{if(!e||"object"!=typeof e||"string"!=typeof e.optionId||!e.optionId||"string"!=typeof e.kind||!ey.includes(e.kind))throw Error("invalid option");return{optionId:e.optionId,kind:e.kind}});if(new Set(n.map(e=>e.optionId)).size!==n.length||new Set(n.map(e=>e.kind)).size!==n.length||["allow_once","allow_always","reject_once"].some(e=>!n.some(t=>t.kind===e)))return null;return{sessionId:e.sessionId,toolCall:{toolCallId:t.toolCallId,title:t.title,...void 0!==t.rawInput?{rawInput:t.rawInput}:{}},options:n}}catch(e){return null}}(e);return t&&t.sessionId===c.current?((0,f.cY)("pwa.tool-approval.requested",{tool:ew,choice:null}),d(ev,"cancelled"),new Promise(e=>{let n={request:t,receivedAt:Date.now(),resolve:e,timer:setTimeout(()=>{i.current===n&&d(ev,"cancelled")},6e4)};i.current=n,o(n)})):((0,f.cY)("pwa.tool-approval.cancelled",{tool:ew,choice:"cancelled"}),ev)}),t="function"==typeof r.onState?r.onState(e=>{("CLOSED"===e||"FAILED"===e)&&d(ev,"cancelled")}):()=>{};return()=>{e(),t(),d(ev,"cancelled")}},[r,d]),(0,a.useEffect)(()=>{i.current&&i.current.request.sessionId!==s&&d(ev,"cancelled")},[s,d]);let u=(0,a.useCallback)((e,t)=>{var n;if((null==(n=i.current)?void 0:n.request)!==e)return;let r=e.options.find(e=>e.kind===t);r&&d({outcome:{outcome:"selected",optionId:r.optionId}},t,e)},[d]),m=(0,a.useCallback)(e=>d(ev,"cancelled",e),[d]);return{pendingRequest:null!=(t=null==l?void 0:l.request)?t:null,receivedAt:null!=(n=null==l?void 0:l.receivedAt)?n:0,choose:u,cancel:m}}({acp:eF,sessionId:y}),tt=(0,r.jsxs)("button",{type:"button",onClick:()=>void eH.toggle(),disabled:!eW,title:eW?null!=(e=eH.errorMsg)?e:ej.g[eH.phase]:"daemon URL 미설정 — Settings 에서 Base URL 입력","data-elanous-action":"chat-voice-toggle",className:(0,D.cn)("inline-flex items-center gap-1.5 rounded-full border px-2.5 py-1 text-xs font-medium transition-colors",eH.active?"border-rose-500/40 bg-rose-500/10 text-rose-600 hover:bg-rose-500/20":"border-border bg-background text-foreground hover:bg-muted",!eW&&"cursor-not-allowed opacity-50"),children:[(0,r.jsx)("span",{className:(0,D.cn)("h-2 w-2 rounded-full",ej.x[eH.phase],("listening"===eH.phase||"speaking"===eH.phase)&&"animate-pulse"),"aria-hidden":!0}),eH.active?(0,r.jsx)(l.A,{className:"h-3.5 w-3.5"}):(0,r.jsx)(o.A,{className:"h-3.5 w-3.5"}),(0,r.jsx)("span",{className:"hidden sm:inline",children:ej.g[eH.phase]})]});return(0,r.jsxs)("div",{className:"relative flex h-full flex-col",onPaste:e=>{let t=function(e,t){if(!e)return C([]);let n=[];if(e.items.length>0)for(let t of Array.from(e.items)){if("file"!==t.kind)continue;let e=t.getAsFile();e&&n.push(e)}else n.push(...Array.from(e.files));return C(n.map(e=>({file:e,filename:e.name||"paste-".concat(t,".png")})))}(e.clipboardData,Date.now());(0!==t.files.length||0!==t.tooLarge||0!==t.tooMany)&&(e.preventDefault(),e2(t))},onDragEnter:e=>{eE(t=>E(t,"enter",I(e.dataTransfer)))},onDragLeave:e=>{eE(t=>E(t,"leave",I(e.dataTransfer)))},onDragOver:e=>{I(e.dataTransfer)&&e.preventDefault()},onDrop:e=>{var t;eE(t=>E(t,"drop",I(e.dataTransfer)));let n=C((t=e.dataTransfer)?Array.from(t.files,e=>({file:e,filename:e.name})):[]);(0!==n.files.length||0!==n.tooLarge||0!==n.tooMany)&&(e.preventDefault(),e2(n))},children:[eI.visible&&(0,r.jsx)(A,{}),n?(0,r.jsxs)("div",{"data-elanous-chat-compact-header":"",className:"flex h-11 max-h-11 min-w-0 shrink-0 items-center gap-2 border-b border-border bg-background px-3 whitespace-nowrap",children:[t.leading&&(0,r.jsx)("div",{className:"shrink-0",children:t.leading}),(0,r.jsx)("div",{className:"min-w-0 flex-1 [&>div]:min-w-0 [&>div]:max-w-full [&>div>div:first-child]:min-w-0 [&>div>div:first-child]:max-w-full [&>div>div:first-child]:overflow-hidden [&>div>div:first-child>span:last-child]:shrink-0 [&>div>div:first-child_span]:min-w-0 [&>div>div:first-child_span]:truncate [&>div>div[role=menu]]:max-w-[calc(100vw-4rem)]",children:(0,r.jsx)(R.Qh,{sessionId:y,...t.onAttachRequest?{onAttachRequest:t.onAttachRequest}:{},...t.onForgetRequest?{onForgetRequest:t.onForgetRequest}:{}})}),(0,r.jsx)(g,{}),(0,r.jsxs)("div",{ref:h,className:"relative shrink-0",children:[(0,r.jsx)("button",{type:"button","aria-label":"채팅 더보기","aria-expanded":u,"aria-controls":"chat-header-more",onClick:()=>m(e=>!e),className:"inline-flex h-8 w-8 items-center justify-center rounded-lg hover:bg-muted",children:(0,r.jsx)(i.A,{className:"h-5 w-5","aria-hidden":"true"})}),u&&(0,r.jsxs)("div",{id:"chat-header-more",className:"absolute right-0 top-full z-50 mt-1 flex max-w-[calc(100vw-1.5rem)] flex-col gap-2 rounded-lg border border-border bg-popover p-3 shadow-lg",children:[(0,r.jsx)(s.vG,{children:(0,r.jsx)(K.rm,{})}),(0,r.jsx)(s.vG,{children:(0,r.jsx)(B.D,{})}),tt]})]})]}):(0,r.jsxs)("div",{className:"flex shrink-0 items-center justify-between gap-3 border-b border-border bg-background px-4 py-2",children:[(0,r.jsxs)("div",{className:"flex items-center gap-2",children:[(0,r.jsx)(R.Qh,{sessionId:y,...t.onAttachRequest?{onAttachRequest:t.onAttachRequest}:{},...t.onForgetRequest?{onForgetRequest:t.onForgetRequest}:{}}),(0,r.jsx)(s.vG,{children:(0,r.jsx)(K.rm,{})}),(0,r.jsx)(s.vG,{children:(0,r.jsx)(B.D,{})})]}),(0,r.jsxs)("div",{className:"flex items-center gap-2",children:[(0,r.jsx)(g,{}),tt]})]}),(0,r.jsx)(p,{}),(0,r.jsx)(v,{}),(0,r.jsx)(j,{}),(0,r.jsx)(J,{}),(0,r.jsxs)("div",{className:"relative flex flex-1 min-h-0 flex-col",children:[(0,r.jsx)(k.D,{messages:q,pending:M,...t.tabId?{tabId:t.tabId}:{}}),ec&&(0,r.jsxs)("div",{role:"alert",className:"mx-4 mb-3 flex shrink-0 items-start justify-between gap-3 rounded-md border border-amber-500/40 bg-amber-500/10 px-3 py-2 text-sm text-foreground","data-elanous-turn-busy-banner":"",children:[(0,r.jsxs)("div",{children:[(0,r.jsx)("p",{className:"font-medium",children:"이 대화는 지금 응답 중입니다"}),(0,r.jsx)("p",{className:"text-muted-foreground",children:ec.message}),(0,r.jsx)("p",{className:"mt-1 text-xs text-muted-foreground",children:ec.holder?"Current input holder: ".concat(ec.holder):"The current input holder is not available."})]}),(0,r.jsx)("button",{type:"button",onClick:()=>ed(null),className:"rounded px-2 py-1 text-xs text-muted-foreground hover:bg-amber-500/10 hover:text-foreground","aria-label":"응답 중 알림 닫기",children:"Dismiss"})]}),(0,r.jsx)(et,{active:eH.active,phase:eH.phase,errorMsg:eH.errorMsg,onToggle:()=>void eH.toggle(),ttsSupported:eX.supported,ttsMuted:eZ,onTtsToggle:()=>eV(e=>!e),onInterrupt:()=>{try{eX.cancel()}catch(e){}eH.interrupt()}})]}),M&&eu&&(0,r.jsxs)("div",{className:"flex shrink-0 items-center justify-end gap-2 border-t border-border bg-muted/30 px-4 py-1.5 text-xs",children:[(0,r.jsx)("span",{className:"text-muted-foreground",children:"streaming…"}),(0,r.jsx)("button",{type:"button",onClick:e0,className:"rounded border border-border bg-background px-2 py-0.5 font-mono hover:bg-muted","data-elanous-action":"chat-stop",title:"Stop the running turn (Esc)",children:"Stop ⎋"})]}),(0,r.jsx)(S,{queue:eo,onRemove:e=>{var t;return ei((t=_.current,t.filter(t=>t.id!==e)))},onClear:()=>ei([])}),(0,r.jsx)(N.V,{onSubmit:e7,prefill:U,attachments:eh,onAttached:e1,onRemoveAttachment:e3,voice:{active:eH.active,phase:eH.phase,dotColor:ej.x[eH.phase],phaseLabel:ej.g[eH.phase],disabled:!eW,onToggle:()=>void eH.toggle()},...t.tabId?{tabId:t.tabId}:{},onListFiles:eF&&y?async e=>{var t,n;let r=await eF.send("elanous/fs/list",{sessionId:y,query:e,limit:50}),a=(null!=(t=r.entries)?t:[]).filter(e=>"string"==typeof(null==e?void 0:e.name)&&"boolean"==typeof(null==e?void 0:e.isDir)&&"string"==typeof(null==e?void 0:e.relPath)).map(e=>({name:e.name,isDir:e.isDir,relPath:e.relPath}));return{cwd:null!=(n=r.cwd)?n:"",entries:a}}:void 0,onListSkills:eF&&y?async e=>{var t;return{entries:(null!=(t=(await eF.send("elanous/skills/list",{sessionId:y,query:e})).entries)?t:[]).filter(e=>"string"==typeof(null==e?void 0:e.name)&&"string"==typeof(null==e?void 0:e.description)).map(e=>({name:e.name,description:e.description}))}}:void 0}),eY&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(en,{open:e_,onClose:()=>eJ(!1),lines:ez}),!e_&&(0,r.jsxs)("button",{type:"button",onClick:()=>eJ(!0),"data-elanous-debug-tap-reopen":"",className:(0,D.cn)("fixed bottom-3 right-3 z-40 rounded-full border border-border bg-card px-3 py-1.5","text-[11px] font-mono text-muted-foreground shadow hover:bg-muted hover:text-foreground"),"aria-label":"Reopen debug drawer",title:"Reopen Debug Tap drawer",children:["⌁ debug (",ez.length,")"]})]}),(0,r.jsx)(em,{request:e9.pendingRequest,onSubmit:e9.submit,onCancel:e9.cancel,onChatAboutThis:e9.chatAboutThis}),(0,r.jsx)(eb,{request:te.pendingRequest,receivedAt:te.receivedAt,onChoose:te.choose,onCancel:te.cancel})]})}var eO=n(8819),eM=n(21383),eF=n(25503);class eP{list(){return this.client.fetchJson("/v1/projects")}create(e){return this.client.fetchJson("/v1/projects",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({name:e})})}assign(e,t){return this.client.fetchJson("/v1/sessions/store/".concat(encodeURIComponent(e)),{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify({projectId:t})})}constructor(e){this.client=e}}let eY="elanous.chat.projectSelection";function e_(e){let{projects:t,selection:n,onChange:s,onCreate:l}=e,[o,i]=(0,a.useState)(!1),[c,d]=(0,a.useState)(""),[u,m]=(0,a.useState)(!1);return(0,r.jsxs)("div",{className:"space-y-2",children:[0===t.length&&!o&&(0,r.jsx)("button",{type:"button",onClick:()=>i(!0),className:"text-sm text-muted-foreground hover:text-foreground",children:"+ 프로젝트 만들기"}),t.length>0&&(0,r.jsxs)("select",{"aria-label":"프로젝트 바꾸기",value:n,onChange:e=>{if("create"===e.target.value)return void i(!0);s(e.target.value)},className:"w-full rounded-lg border border-border bg-background px-3 py-2 text-sm",children:[(0,r.jsx)("option",{value:"all",children:"모든 대화"}),(0,r.jsx)("option",{value:"none",children:"받은 대화(프로젝트 없음)"}),t.map(e=>(0,r.jsx)("option",{value:e.id,children:e.name},e.id)),(0,r.jsx)("option",{value:"create",children:"+ 프로젝트 만들기"})]}),o&&(0,r.jsxs)("form",{onSubmit:e=>{e.preventDefault();let t=c.trim();t&&l(t).then(()=>{i(!1),d(""),m(!1)}).catch(()=>m(!0))},className:"flex gap-2",children:[(0,r.jsx)("input",{"aria-label":"프로젝트 이름",autoFocus:!0,value:c,maxLength:80,onChange:e=>d(e.target.value),className:"min-w-0 flex-1 rounded-lg border border-border bg-background px-2 py-1 text-sm"}),(0,r.jsx)("button",{type:"submit",className:"rounded-lg border border-border px-2 text-sm",children:"만들기"}),u&&(0,r.jsx)("span",{role:"alert",children:"프로젝트를 만들지 못했습니다"})]})]})}function eJ(e,t){var n,r;return(null==t?void 0:t.trim())||(null==(r=e.lastMsgPreview)||null==(n=r.trim().split(/\r?\n/)[0])?void 0:n.trim())||"대화"}let ez="elanous.chat.pendingProjects";function e$(e){try{return"undefined"==typeof localStorage?null:localStorage.getItem(e)}catch(e){return null}}function eQ(e,t){try{"undefined"!=typeof localStorage&&localStorage.setItem(e,t)}catch(e){}}function eK(e){let{onSelect:t}=e,n=(0,d.Q)(),s=(0,eF.t)({activePoll:!0}),[l,o]=(0,a.useState)({}),[i,c]=(0,a.useState)(""),[u,m]=(0,a.useState)([]),[p,h]=(0,a.useState)("all"),[f,g]=(0,a.useState)([]),[x,b]=(0,a.useState)(()=>{try{var e;let t=JSON.parse(null!=(e=e$(ez))?e:"{}");if(t&&"object"==typeof t&&!Array.isArray(t))return Object.fromEntries(Object.entries(t).filter(e=>{let[t,n]=e;return t&&"string"==typeof n&&n}))}catch(e){}return{}}),[v,y]=(0,a.useState)({}),w=(0,a.useRef)(new Set);(0,a.useEffect)(()=>{var e;h(null!=(e=e$(eY))?e:"all");let t=!0;return new eP(n.client).list().then(e=>{var n;t&&m(null!=(n=e.projects)?n:[])}).catch(()=>{}),()=>{t=!1}},[n.client]),(0,a.useEffect)(()=>{eQ(ez,JSON.stringify(x))},[x]),(0,a.useEffect)(()=>{let e=!0,t=u.length>0&&"all"!==p&&"none"!==p?"?projectId=".concat(encodeURIComponent(p)):"";return n.client.fetchJson("/v1/sessions/store".concat(t)).then(t=>{var n;if(!e)return;let r=null!=(n=t.sessions)?n:[];g(r),o(Object.fromEntries(r.map(e=>[e.id,e.title])))}).catch(()=>{}),()=>{e=!1}},[n.client,s,u,p]),(0,a.useEffect)(()=>{let e=Object.keys(x).filter(e=>s.some(t=>t.id===e)&&!f.some(t=>t.id===e));if(0===e.length)return;let t=!0;for(let r of e)n.client.fetchJson("/v1/sessions/store/".concat(encodeURIComponent(r),"?ifExists=1")).then(e=>{t&&e.meta&&g(t=>t.some(e=>e.id===r)?t:[...t,e.meta])}).catch(()=>{});return()=>{t=!1}},[f,n.client,x,s]),(0,a.useEffect)(()=>{for(let[e,t]of Object.entries(x)){if(!s.some(t=>t.id===e)||w.current.has(e))continue;let r=f.find(t=>t.id===e);if(r){if(r.projectId===t||v[e]===t){b(t=>{let n={...t};return delete n[e],n});continue}w.current.add(e),new eP(n.client).assign(e,t).then(()=>{y(n=>({...n,[e]:t})),g(n=>n.map(n=>n.id===e?{...n,projectId:t}:n)),b(t=>{let n={...t};return delete n[e],n})}).catch(()=>{w.current.delete(e)})}}},[v,f,n.client,x,s]);let j=u.some(e=>e.id===p)||"none"===p?p:"all",k=0===u.length||"all"===j?s:s.filter(e=>x[e.id]?x[e.id]===j:"none"===j?!f.some(t=>t.id===e.id&&t.projectId)&&!v[e.id]:v[e.id]===j||f.some(t=>t.id===e.id&&t.projectId===j)),N=[...k].filter(e=>{var t;return"".concat(eJ(e,l[e.id])," ").concat(null!=(t=e.lastMsgPreview)?t:"").toLocaleLowerCase().includes(i.trim().toLocaleLowerCase())}).sort((e,t)=>Date.parse(t.lastTurnAt)-Date.parse(e.lastTurnAt)),S=()=>{let e=(0,$.Zr)();u.length>0&&"all"!==j&&"none"!==j&&b(t=>({...t,[e]:j})),n.setSessionId(e),null==t||t()};return(0,r.jsxs)("nav",{"aria-label":"대화 목록",className:"flex h-full min-h-0 flex-col bg-background",children:[(0,r.jsxs)("div",{className:"shrink-0 space-y-3 border-b border-border p-3",children:[(0,r.jsx)(e_,{projects:u,selection:j,onChange:e=>{h(e),eQ(eY,e)},onCreate:async e=>{let{project:t}=await new eP(n.client).create(e);m(e=>[...e,t]),h(t.id),eQ(eY,t.id)}}),(0,r.jsxs)("button",{type:"button",onClick:S,className:"flex w-full items-center gap-2 rounded-lg bg-primary px-3 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90",children:[(0,r.jsx)(eO.A,{className:"h-4 w-4","aria-hidden":"true"})," 새 대화"]}),(0,r.jsxs)("label",{className:"flex items-center gap-2 rounded-lg border border-border bg-muted/30 px-2.5 py-2 focus-within:ring-2 focus-within:ring-ring",children:[(0,r.jsx)(eM.A,{className:"h-4 w-4 shrink-0 text-muted-foreground","aria-hidden":"true"}),(0,r.jsx)("input",{"aria-label":"대화 검색",type:"search",value:i,onChange:e=>c(e.target.value),placeholder:"대화 검색",className:"min-w-0 flex-1 bg-transparent text-sm outline-none placeholder:text-muted-foreground"})]})]}),(0,r.jsx)("div",{className:"min-h-0 flex-1 overflow-y-auto p-2",children:0===k.length?(0,r.jsxs)("div",{className:"space-y-3 px-2 py-8 text-center text-sm text-muted-foreground",children:[(0,r.jsx)("p",{children:"아직 대화가 없습니다"}),(0,r.jsx)("button",{type:"button",onClick:S,className:"rounded-lg border border-border px-3 py-2 text-foreground hover:bg-muted",children:"+ 새 대화"})]}):0===N.length?(0,r.jsx)("p",{className:"px-2 py-8 text-center text-sm text-muted-foreground",children:"검색 결과가 없습니다"}):(0,r.jsx)("ul",{className:"space-y-1",children:N.map(e=>(0,r.jsx)("li",{children:(0,r.jsxs)("button",{type:"button","aria-current":n.sessionId===e.id?"page":void 0,onClick:()=>{n.setSessionId(e.id),null==t||t()},className:"w-full rounded-lg px-3 py-2.5 text-left transition-colors ".concat(n.sessionId===e.id?"bg-primary/10 text-primary ring-1 ring-inset ring-primary/25":"text-foreground hover:bg-muted"),children:[(0,r.jsx)("span",{className:"block truncate text-sm font-medium",children:eJ(e,l[e.id])}),(0,r.jsxs)("span",{className:"mt-1 block truncate text-xs text-muted-foreground",children:[function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:Date.now(),n=Date.parse(e);if(!Number.isFinite(n))return"";let r=Math.max(0,Math.floor((t-n)/6e4));if(r<1)return"방금 전";if(r<60)return"".concat(r,"분 전");let a=Math.floor(r/60);if(a<24)return"".concat(a,"시간 전");let s=Math.floor(a/24);return s<7?"".concat(s,"일 전"):new Date(n).toLocaleDateString()}(e.lastTurnAt)," \xb7 ",e.msgCount,"개 메시지"]})]})},e.id))})})]})}var eB=n(35622),eG=n(69147),eH=n(44614),eW=n(3155);function eZ(){var e;let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{compact:n}=(0,c.K)(),s=(0,eH.tg)(),{client:l,sessionId:o,setSessionId:i}=(0,d.Q)(),[u,m]=(0,a.useState)(o||"default"),[p,h]=(0,a.useState)(!1);(0,a.useEffect)(()=>{if(!p)return;let e=e=>{"Escape"===e.key&&h(!1)};return document.addEventListener("keydown",e),()=>document.removeEventListener("keydown",e)},[p]);let f=(0,a.useRef)(null);(0,a.useEffect)(()=>{if(f.current===o){f.current=null;return}f.current=null,m(o||"default")},[o]);let g=(0,a.useRef)(t.sessionId),x=(0,a.useRef)(o),b=null!=(e=null==s?void 0:s.state.activeId)?e:null;(0,a.useEffect)(()=>{let e=t.sessionId;if(s&&t.tabId&&e&&o){var n,r;let a=function(e){if(!e.isActive||e.tabSessionId===e.daemonSessionId)return"none";let t=e.prevTabSessionId!==e.tabSessionId,n=e.prevDaemonSessionId!==e.daemonSessionId;return t||!n?"adopt-tab":"record-global"}({isActive:b===t.tabId,tabSessionId:e,daemonSessionId:o,prevTabSessionId:null!=(n=g.current)?n:e,prevDaemonSessionId:null!=(r=x.current)?r:o});"adopt-tab"===a?i(e):"record-global"===a&&s.updateChatTab(t.tabId,{sessionId:o})}g.current=t.sessionId,x.current=o},[s,b,t.tabId,t.sessionId,o,i]);let v=s&&t.tabId?()=>s.openPicker({kind:"attachToTab",tabId:t.tabId}):void 0,y=s&&t.sessionId?async()=>{let e=(0,eW.hG)(l);await e.forget(t.sessionId)}:void 0,w=(0,r.jsx)("button",{type:"button",onClick:()=>h(!0),"aria-label":"대화 목록","aria-expanded":p,"aria-controls":"chat-conversation-drawer",className:"inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-lg hover:bg-muted",children:(0,r.jsx)(eB.A,{className:"h-4 w-4","aria-hidden":"true"})}),j=(0,r.jsx)(eU,{onSessionAdopt:e=>{f.current=e},...t.showConversationList&&n?{leading:w}:{},...v?{onAttachRequest:v}:{},...y?{onForgetRequest:y}:{},...t.tabId?{tabId:t.tabId}:{}},u);return t.showConversationList?(0,r.jsxs)("div",{className:"flex h-full min-h-0 min-w-0",children:[(0,r.jsx)("aside",{className:n?"hidden":"hidden h-full w-[260px] shrink-0 border-r border-border md:block",children:(0,r.jsx)(eK,{})}),(0,r.jsxs)("div",{className:"flex min-h-0 min-w-0 flex-1 flex-col",children:[!n&&(0,r.jsx)("div",{className:"shrink-0 border-b border-border bg-background px-3 py-2 md:hidden",children:(0,r.jsxs)("button",{type:"button",onClick:()=>h(!0),"aria-label":"대화 목록","aria-expanded":p,"aria-controls":"chat-conversation-drawer",className:"inline-flex items-center gap-2 rounded-lg px-2 py-1.5 text-sm font-medium hover:bg-muted",children:[(0,r.jsx)(eB.A,{className:"h-4 w-4","aria-hidden":"true"})," 대화 목록"]})}),(0,r.jsx)("div",{className:"min-h-0 min-w-0 flex-1",children:j})]}),p&&(0,r.jsxs)("div",{className:n?"fixed inset-0 z-50":"fixed inset-0 z-50 md:hidden",children:[(0,r.jsx)("button",{type:"button","aria-label":"대화 목록 닫기",onClick:()=>h(!1),className:"absolute inset-0 bg-black/50"}),(0,r.jsxs)("aside",{id:"chat-conversation-drawer",role:"dialog","aria-modal":"true","aria-label":"대화 목록",className:"relative h-full w-[min(260px,85vw)] bg-background shadow-xl",children:[(0,r.jsx)("button",{type:"button","aria-label":"대화 목록 닫기",onClick:()=>h(!1),className:"absolute right-2 top-2 z-10 rounded p-1 hover:bg-muted",children:(0,r.jsx)(eG.A,{className:"h-4 w-4"})}),(0,r.jsx)(eK,{onSelect:()=>h(!1)})]})]})]}):j}}}]);