elanous 0.2.7 → 0.2.8

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 (252) 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/4836-3084c58c1725a40b.js +1 -0
  4. package/apps/pwa/out/_next/static/chunks/7032-f4ef698518fba61c.js +1 -0
  5. package/apps/pwa/out/_next/static/chunks/8067-d976b441a104ab74.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/8519-5632377cce994f86.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/8894-7317998f6cb97d8c.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/9740-8f5ff96c522b5f55.js +1 -0
  9. package/apps/pwa/out/_next/static/chunks/app/approvals/page-9aa47b0bc6d570ff.js +1 -0
  10. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-f4d2ecbbae6088d6.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/app/board/page-2053e49930c82748.js +1 -0
  12. package/apps/pwa/out/_next/static/chunks/app/botlab/{page-624f7a2f89b60c8f.js → page-d4b6df905f185055.js} +1 -1
  13. package/apps/pwa/out/_next/static/chunks/app/bots/{page-5a5fb385a4df0ffe.js → page-a70ba27c33003dd0.js} +1 -1
  14. package/apps/pwa/out/_next/static/chunks/app/chat/page-186fc6952f027acc.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/app/consult/{page-7457f52683562161.js → page-18166f885d831d3e.js} +1 -1
  16. package/apps/pwa/out/_next/static/chunks/app/control/page-1c9d6cfe68b121c2.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/app/design-check/page-cbbe03c0da7b081a.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/app/editor/page-c108ff1fdb665c97.js +1 -0
  19. package/apps/pwa/out/_next/static/chunks/app/exec/{page-b7dcf5d48a854b76.js → page-147a328753d983e2.js} +1 -1
  20. package/apps/pwa/out/_next/static/chunks/app/field/{page-51480757e7d68b92.js → page-799395a9df7d95aa.js} +1 -1
  21. package/apps/pwa/out/_next/static/chunks/app/intake/page-6a8158b71d1fe9d7.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/app/layout-9567560270857531.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/app/live/{page-30533117beb53625.js → page-e7ed3d010153d818.js} +1 -1
  24. package/apps/pwa/out/_next/static/chunks/app/market/page-c0c0d19d51342d3e.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/{page-07267f1391b96aba.js → page-2e002ad8faa43291.js} +1 -1
  26. package/apps/pwa/out/_next/static/chunks/app/morning/{page-55d50e9b0006a91d.js → page-b672e02e4bec8deb.js} +1 -1
  27. package/apps/pwa/out/_next/static/chunks/app/not-found-1ba4a5d857276334.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/app/observatory/page-9db2226f38c542fb.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/app/{page-a7e37af7d0399cb8.js → page-70ee65f5f7a151dc.js} +1 -1
  30. package/apps/pwa/out/_next/static/chunks/app/reflection/page-0bb8e43203efb23b.js +1 -0
  31. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-092e1bcf27d751cc.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/app/sessions/{page-15e5a15db84c56aa.js → page-eb52580c4b75b905.js} +1 -1
  33. package/apps/pwa/out/_next/static/chunks/app/settings/devices/{page-a2e572e4511f2a16.js → page-7464c1987dd76e6d.js} +1 -1
  34. package/apps/pwa/out/_next/static/chunks/app/settings/{page-dd107bf1c7d52a90.js → page-e573437b0a1c728f.js} +1 -1
  35. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-294300625e49e4d3.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/app/setup/page-085847b088675978.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/app/share/page-9fe9d38c36999eb4.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/app/showroom/page-d8ab4d1489223459.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/app/tasks/page-6141f67f531d8b6a.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/app/term/page-295a02b1026b8255.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/app/trace/page-1eb9a0e1e054209d.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/app/vault/{page-56adbe1a1f1379bd.js → page-82efa177a30f3741.js} +1 -1
  43. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-d0be51cec4f62606.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/app/workflows/page-2e367075ffdbc062.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/app/workspace/{page-5d422f38c052967e.js → page-647ed2b66c1d49f1.js} +1 -1
  46. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-ba058c56e38f2792.js +1 -0
  47. package/apps/pwa/out/_next/static/css/5ef72a618a8994f3.css +1 -0
  48. package/apps/pwa/out/approvals/index.html +1 -1
  49. package/apps/pwa/out/approvals/index.txt +13 -13
  50. package/apps/pwa/out/autopilot/index.html +1 -1
  51. package/apps/pwa/out/autopilot/index.txt +13 -13
  52. package/apps/pwa/out/board/index.html +1 -1
  53. package/apps/pwa/out/board/index.txt +13 -13
  54. package/apps/pwa/out/botlab/index.html +1 -1
  55. package/apps/pwa/out/botlab/index.txt +13 -13
  56. package/apps/pwa/out/bots/index.html +1 -1
  57. package/apps/pwa/out/bots/index.txt +13 -13
  58. package/apps/pwa/out/chat/index.html +1 -1
  59. package/apps/pwa/out/chat/index.txt +13 -13
  60. package/apps/pwa/out/consult/index.html +1 -1
  61. package/apps/pwa/out/consult/index.txt +13 -13
  62. package/apps/pwa/out/control/index.html +1 -1
  63. package/apps/pwa/out/control/index.txt +13 -13
  64. package/apps/pwa/out/design-check/index.html +1 -1
  65. package/apps/pwa/out/design-check/index.txt +13 -13
  66. package/apps/pwa/out/editor/index.html +1 -1
  67. package/apps/pwa/out/editor/index.txt +13 -13
  68. package/apps/pwa/out/exec/index.html +1 -1
  69. package/apps/pwa/out/exec/index.txt +13 -13
  70. package/apps/pwa/out/field/index.html +1 -1
  71. package/apps/pwa/out/field/index.txt +13 -13
  72. package/apps/pwa/out/healthz +1 -1
  73. package/apps/pwa/out/index.html +1 -1
  74. package/apps/pwa/out/index.txt +13 -13
  75. package/apps/pwa/out/intake/index.html +1 -1
  76. package/apps/pwa/out/intake/index.txt +13 -13
  77. package/apps/pwa/out/live/index.html +1 -1
  78. package/apps/pwa/out/live/index.txt +13 -13
  79. package/apps/pwa/out/market/index.html +1 -1
  80. package/apps/pwa/out/market/index.txt +13 -13
  81. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  82. package/apps/pwa/out/missions/placeholder/index.txt +13 -13
  83. package/apps/pwa/out/morning/index.html +1 -1
  84. package/apps/pwa/out/morning/index.txt +13 -13
  85. package/apps/pwa/out/observatory/index.html +1 -1
  86. package/apps/pwa/out/observatory/index.txt +13 -13
  87. package/apps/pwa/out/reflection/index.html +1 -1
  88. package/apps/pwa/out/reflection/index.txt +14 -14
  89. package/apps/pwa/out/scheduler/index.html +1 -1
  90. package/apps/pwa/out/scheduler/index.txt +13 -13
  91. package/apps/pwa/out/sessions/index.html +1 -1
  92. package/apps/pwa/out/sessions/index.txt +13 -13
  93. package/apps/pwa/out/settings/devices/index.html +1 -1
  94. package/apps/pwa/out/settings/devices/index.txt +13 -13
  95. package/apps/pwa/out/settings/index.html +1 -1
  96. package/apps/pwa/out/settings/index.txt +13 -13
  97. package/apps/pwa/out/setup/done/index.html +1 -1
  98. package/apps/pwa/out/setup/done/index.txt +13 -13
  99. package/apps/pwa/out/setup/index.html +1 -1
  100. package/apps/pwa/out/setup/index.txt +13 -13
  101. package/apps/pwa/out/share/index.html +1 -1
  102. package/apps/pwa/out/share/index.txt +13 -13
  103. package/apps/pwa/out/showroom/index.html +1 -1
  104. package/apps/pwa/out/showroom/index.txt +13 -13
  105. package/apps/pwa/out/tasks/index.html +1 -1
  106. package/apps/pwa/out/tasks/index.txt +13 -13
  107. package/apps/pwa/out/term/index.html +1 -1
  108. package/apps/pwa/out/term/index.txt +13 -13
  109. package/apps/pwa/out/trace/index.html +1 -1
  110. package/apps/pwa/out/trace/index.txt +13 -13
  111. package/apps/pwa/out/vault/index.html +1 -1
  112. package/apps/pwa/out/vault/index.txt +13 -13
  113. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  114. package/apps/pwa/out/workflows/chat-ui/index.txt +13 -13
  115. package/apps/pwa/out/workflows/index.html +1 -1
  116. package/apps/pwa/out/workflows/index.txt +13 -13
  117. package/apps/pwa/out/workspace/index.html +1 -1
  118. package/apps/pwa/out/workspace/index.txt +13 -13
  119. package/apps/pwa/out/worktrees/index.html +1 -1
  120. package/apps/pwa/out/worktrees/index.txt +13 -13
  121. package/graphs/test-diet/recipes.yaml +9 -0
  122. package/graphs/test-diet/test-diet.yaml +22 -0
  123. package/package.json +2 -1
  124. package/persona-presets/_index.yaml +10 -0
  125. package/persona-presets/_schema.json +146 -0
  126. package/persona-presets/dana.yaml +26 -0
  127. package/persona-presets/haru.yaml +27 -0
  128. package/persona-presets/kai.yaml +27 -0
  129. package/persona-presets/leo.yaml +27 -0
  130. package/persona-presets/mira.yaml +30 -0
  131. package/persona-presets/nari.yaml +27 -0
  132. package/persona-presets/sora.yaml +27 -0
  133. package/persona-presets/yuna.yaml +27 -0
  134. package/plugins/geo-check/graphs/run-step.ts +34 -10
  135. package/scripts/field-feed/deliver-node.ts +8 -3
  136. package/scripts/field-feed/lib.ts +2 -0
  137. package/scripts/install.sh +20 -11
  138. package/scripts/persona-presets/lint.ts +79 -0
  139. package/scripts/release-loop/checklist-gate-node.ts +2 -2
  140. package/scripts/release-loop/gate-node.ts +27 -3
  141. package/scripts/release-loop/npm-publish-node.ts +10 -4
  142. package/scripts/release-loop/ops-upgrade-node.ts +11 -3
  143. package/scripts/release-loop/publish-node.ts +23 -1
  144. package/scripts/release-loop/shard-plan.ts +17 -0
  145. package/scripts/storyboard/storyboard.ts +167 -0
  146. package/scripts/test-diet/lib.ts +88 -0
  147. package/scripts/test-diet/node.ts +102 -0
  148. package/src/acp/auth-methods.ts +30 -0
  149. package/src/acp/server.ts +5 -5
  150. package/src/channel-import/detect.ts +191 -0
  151. package/src/channel-import/run.ts +111 -0
  152. package/src/cli/config-test-sync.ts +4 -0
  153. package/src/cli/decisions-cli.ts +13 -3
  154. package/src/cli/doctor-bundle.ts +128 -0
  155. package/src/cli/doctor-cli.ts +36 -1
  156. package/src/cli/doctor-local-llm.ts +95 -0
  157. package/src/cli/import-cli.ts +60 -0
  158. package/src/cli/mcp-login.ts +13 -4
  159. package/src/cli/persona-cli.ts +116 -0
  160. package/src/cli/release-cli.ts +8 -7
  161. package/src/cli/skills-cli.ts +173 -0
  162. package/src/cli/start-cli.ts +13 -4
  163. package/src/codex/setup.ts +15 -13
  164. package/src/dashboard/index.ts +17 -1
  165. package/src/dashboard/slash-runtime/dashboard-handlers.ts +2 -2
  166. package/src/dashboard/slash-runtime/help-from-registry.ts +4 -2
  167. package/src/decisions/decision-cards.ts +291 -0
  168. package/src/decisions/decision-ledger.ts +5 -2
  169. package/src/decisions/discord-decision-cards.ts +133 -0
  170. package/src/decisions/telegram-decision-cards.ts +100 -0
  171. package/src/directives/version-at.ts +77 -0
  172. package/src/discord.ts +17 -0
  173. package/src/domains/outbound-alert.ts +44 -1
  174. package/src/domains/repeated-failure.ts +1 -1
  175. package/src/error-report/report.ts +200 -0
  176. package/src/exec-requests/planner.ts +8 -2
  177. package/src/exec-requests/runner.ts +64 -24
  178. package/src/exec-requests/store.ts +2 -0
  179. package/src/field/field-feed-auto.ts +48 -0
  180. package/src/field/field-reel.ts +8 -1
  181. package/src/hooks/error-report.ts +210 -0
  182. package/src/hooks/receiver.ts +41 -1
  183. package/src/import/apply.ts +128 -0
  184. package/src/import/plan.ts +197 -0
  185. package/src/index.ts +82 -7
  186. package/src/input-core/text-entry.ts +13 -5
  187. package/src/intake-plane/seat-answer.ts +96 -0
  188. package/src/intake-plane/seat-doc-route.ts +17 -3
  189. package/src/nexus/api/consult-requests.ts +19 -8
  190. package/src/nexus/api/error-reports.ts +108 -0
  191. package/src/nexus/api/http-server.ts +21 -1
  192. package/src/nexus/api/outbound-report.ts +7 -0
  193. package/src/nexus/api/running-runs-background.ts +68 -0
  194. package/src/nexus/api/running-runs-child.ts +6 -0
  195. package/src/nexus/api/share-captures.ts +91 -0
  196. package/src/nexus/api/skill-problems.ts +56 -0
  197. package/src/nexus/api/terminals.ts +24 -8
  198. package/src/nexus/index.ts +25 -1
  199. package/src/nexus/setup-status.ts +7 -2
  200. package/src/oauth/browser-availability.ts +14 -0
  201. package/src/oauth/codex-quota-policy.ts +16 -0
  202. package/src/onboarding/continue-here.ts +13 -8
  203. package/src/onboarding/web-first.ts +8 -1
  204. package/src/onboarding.ts +66 -12
  205. package/src/persona/presets.ts +105 -0
  206. package/src/release-loop/checklist.ts +28 -5
  207. package/src/self-dev/orchestrate.ts +18 -11
  208. package/src/shell-env-bootstrap.ts +44 -7
  209. package/src/skills/connect-claude-plugin.ts +142 -0
  210. package/src/skills/connect.ts +70 -0
  211. package/src/skills/index.ts +29 -1
  212. package/src/skills/repair.ts +124 -0
  213. package/src/skills/runner.ts +11 -2
  214. package/src/skills/trigger-extract.ts +1 -1
  215. package/src/task-orchestrator/surfaces/pod-command-job.ts +16 -8
  216. package/src/telegram-commands.ts +13 -0
  217. package/src/telegram.ts +34 -0
  218. package/src/user-config.ts +111 -13
  219. package/src/version/packed-revision.json +1 -1
  220. package/apps/pwa/out/_next/static/chunks/4836-2eba6079f31b88d4.js +0 -1
  221. package/apps/pwa/out/_next/static/chunks/8067-f74bf14d67ad98f1.js +0 -1
  222. package/apps/pwa/out/_next/static/chunks/8519-f6b5d8a5833a7603.js +0 -1
  223. package/apps/pwa/out/_next/static/chunks/8894-e92491a164192cc1.js +0 -1
  224. package/apps/pwa/out/_next/static/chunks/9740-67051141115ce775.js +0 -1
  225. package/apps/pwa/out/_next/static/chunks/9804-64c02c3c127d5014.js +0 -1
  226. package/apps/pwa/out/_next/static/chunks/app/approvals/page-d5ebde04844689e6.js +0 -1
  227. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-10ed24f413ed66e9.js +0 -1
  228. package/apps/pwa/out/_next/static/chunks/app/board/page-211810b6c93ab66a.js +0 -1
  229. package/apps/pwa/out/_next/static/chunks/app/chat/page-80497e93a878ddc5.js +0 -1
  230. package/apps/pwa/out/_next/static/chunks/app/control/page-cee86394de407aa6.js +0 -1
  231. package/apps/pwa/out/_next/static/chunks/app/design-check/page-4ff8edab44196b8c.js +0 -1
  232. package/apps/pwa/out/_next/static/chunks/app/editor/page-92e4f44428d5e290.js +0 -1
  233. package/apps/pwa/out/_next/static/chunks/app/intake/page-2a05dfe80c8bdf16.js +0 -1
  234. package/apps/pwa/out/_next/static/chunks/app/layout-d9979633aa82f8e6.js +0 -1
  235. package/apps/pwa/out/_next/static/chunks/app/market/page-f7857826c2f97ad7.js +0 -1
  236. package/apps/pwa/out/_next/static/chunks/app/not-found-9699b1786be6171d.js +0 -1
  237. package/apps/pwa/out/_next/static/chunks/app/observatory/page-43dd772aee8af75f.js +0 -1
  238. package/apps/pwa/out/_next/static/chunks/app/reflection/page-973ab7af59c718b7.js +0 -1
  239. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-a9f8d3865b91e436.js +0 -1
  240. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-d42b99cdfb9f27c6.js +0 -1
  241. package/apps/pwa/out/_next/static/chunks/app/setup/page-2764ff40dad5a995.js +0 -1
  242. package/apps/pwa/out/_next/static/chunks/app/share/page-c5f1152db116ff96.js +0 -1
  243. package/apps/pwa/out/_next/static/chunks/app/showroom/page-f933bca81ea38a6f.js +0 -1
  244. package/apps/pwa/out/_next/static/chunks/app/tasks/page-c1c95739c0bff3b8.js +0 -1
  245. package/apps/pwa/out/_next/static/chunks/app/term/page-a7aaffcf771662d8.js +0 -1
  246. package/apps/pwa/out/_next/static/chunks/app/trace/page-71d18eec33b9c667.js +0 -1
  247. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-2c4e59079ee357ac.js +0 -1
  248. package/apps/pwa/out/_next/static/chunks/app/workflows/page-a81f113f3ef89d72.js +0 -1
  249. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-fc27b00e20733146.js +0 -1
  250. package/apps/pwa/out/_next/static/css/f537bdb19c69306a.css +0 -1
  251. /package/apps/pwa/out/_next/static/{keajW7DDyghEs1y8oJe6T → lywc8m_HDzH9MKSDQhyEj}/_buildManifest.js +0 -0
  252. /package/apps/pwa/out/_next/static/{keajW7DDyghEs1y8oJe6T → lywc8m_HDzH9MKSDQhyEj}/_ssgManifest.js +0 -0
@@ -437,11 +437,28 @@ const LLM_DEFAULTS: LLMConfig = { provider: 'auto' };
437
437
  export type SkillSetName =
438
438
  | 'claudecode' | 'opencode' | 'codex' | 'hermes' | 'openclaw' | 'custom';
439
439
 
440
+ export type SkillSourceKind = 'preset' | 'shared' | 'connected' | 'package';
441
+
442
+ /** One skill root elanous reads. `mode` is always `ref` today (the folder is read where it is). */
443
+ export interface SkillSource {
444
+ id: string;
445
+ path: string;
446
+ kind: SkillSourceKind;
447
+ enabled: boolean;
448
+ }
449
+
440
450
  export interface SkillsConfig {
441
451
  activeSet: SkillSetName;
442
452
  dirs: string[];
443
453
  /** Include the existing shared ~/.agents/skills directory. Default true; false opts out. */
444
454
  includeSharedAgentSkills?: boolean;
455
+ /**
456
+ * EN5 — the one source list. On disk it holds only what `elanous connect` registered (kind `connected`, read in
457
+ * place, never copied); the preset (`activeSet`/`dirs`), the shared `~/.agents/skills` root and Claude package
458
+ * roots are derived at read time by `resolveSkillSources()`. The dev-only `connected: string[]` key (EN9, never
459
+ * released) is read and folded in here; the next save writes `sources` instead.
460
+ */
461
+ sources?: SkillSource[];
445
462
  /** Explicit skill-name allowlist. When set and non-empty, the skill
446
463
  * index filters to this list — all other skills are hidden from
447
464
  * routing, autocompletion, and `/run-skill`. Use when a project
@@ -517,34 +534,84 @@ export function bundledSkillsDir(packageRoot: string = dirname(import.meta.dir))
517
534
  return join(packageRoot, 'skills');
518
535
  }
519
536
 
520
- export function defaultSkillDirs(
521
- cfg?: UserConfig,
522
- opts?: DefaultSkillDirsOptions,
523
- ): string[] {
537
+ function packageOptIn(cfg?: UserConfig): boolean {
538
+ try { return (cfg ?? getUserConfig()).skills.includeClaudePackageSkills === true; } catch { return false; }
539
+ }
540
+
541
+ /** Stable id for a connected root: the agent it belongs to, else the folder (plugin) name. */
542
+ export function skillSourceId(path: string): string {
543
+ if (/[/\\]\.codex[/\\]skills\/?$/.test(path)) return 'codex';
544
+ if (/[/\\]\.claude[/\\]skills\/?$/.test(path)) return 'claude';
545
+ const parts = path.split(/[/\\]/).filter(Boolean);
546
+ const last = parts[parts.length - 1] === 'skills' ? parts[parts.length - 2] : parts[parts.length - 1];
547
+ return `plugin:${last ?? 'skills'}`;
548
+ }
549
+
550
+ /** Parse persisted `skills.sources` ⊕ the dev-only `skills.connected` key into connected sources (deduped by path). */
551
+ export function parsePersistedSkillSources(rawSources: unknown, legacyConnected: unknown): SkillSource[] | undefined {
552
+ const out: SkillSource[] = [];
553
+ const seen = new Set<string>();
554
+ const push = (source: SkillSource) => { if (!seen.has(source.path)) { seen.add(source.path); out.push(source); } };
555
+ if (Array.isArray(rawSources)) {
556
+ for (const row of rawSources) {
557
+ if (!row || typeof row !== 'object') continue;
558
+ const r = row as Record<string, unknown>;
559
+ if (typeof r.path !== 'string' || !r.path.trim()) continue;
560
+ const path = r.path.trim();
561
+ push({ id: typeof r.id === 'string' && r.id.trim() ? r.id.trim() : skillSourceId(path), path, kind: 'connected', enabled: r.enabled !== false });
562
+ }
563
+ }
564
+ if (Array.isArray(legacyConnected)) {
565
+ for (const path of legacyConnected) if (typeof path === 'string' && path.trim()) push({ id: skillSourceId(path.trim()), path: path.trim(), kind: 'connected', enabled: true });
566
+ }
567
+ return out.length ? out : undefined;
568
+ }
569
+
570
+ /**
571
+ * ★ EN5 — the ONE function every reader uses (loader · setup checklist · connect · onboarding).
572
+ * Order is the historical order, so an old config resolves to exactly the old directory list:
573
+ * preset (activeSet/dirs) → shared ~/.agents/skills (only when it exists) → connected → Claude package roots (opt-in).
574
+ * Packaged `skills/` is appended by defaultSkillDirs, not listed here.
575
+ */
576
+ export function resolveSkillSources(cfg?: UserConfig, opts?: DefaultSkillDirsOptions): SkillSource[] {
524
577
  const claudecode = skillSetDir('claudecode')!; // = ~/.claude/skills (LOCAL_SKILLS_DIR)
525
- let base = [claudecode];
578
+ const preset = (paths: string[], id: string): SkillSource[] => paths.map((path, i) => ({ id: paths.length > 1 ? `${id}:${i + 1}` : id, path, kind: 'preset', enabled: true }));
579
+ let sources: SkillSource[] = preset([claudecode], 'claudecode');
526
580
  try {
527
581
  const sk = (cfg ?? getUserConfig()).skills;
528
582
  if (sk.activeSet !== 'custom') {
529
583
  const d = skillSetDir(sk.activeSet);
530
- if (d) base = [d];
531
- else if (sk.dirs.length > 0) base = [...sk.dirs];
584
+ if (d) sources = preset([d], sk.activeSet);
585
+ else if (sk.dirs.length > 0) sources = preset([...sk.dirs], 'custom');
532
586
  } else if (sk.dirs.length > 0) {
533
- base = [...sk.dirs];
587
+ sources = preset([...sk.dirs], 'custom');
534
588
  }
589
+ const has = (path: string) => sources.some((source) => source.path === path);
535
590
  const shared = sharedAgentSkillRoots({
536
591
  home: opts?.sharedAgentHome ?? REMOTE_HOME,
537
592
  includeSharedAgentSkills: sk.includeSharedAgentSkills !== false,
538
593
  });
539
594
  try { debug.log('skills.roots', 'shared-agent', { found: shared.length }); }
540
595
  catch { /* discovery remains fail-soft when observation is unavailable */ }
541
- for (const dir of shared) {
542
- if (!base.includes(dir)) base.push(dir);
596
+ for (const path of shared) if (!has(path)) sources.push({ id: 'agents', path, kind: 'shared', enabled: true });
597
+ for (const source of sk.sources ?? []) if (!has(source.path)) sources.push({ ...source, kind: 'connected' });
598
+ if (sk.includeClaudePackageSkills === true) {
599
+ for (const path of appendClaudePackageSkillDirs([], opts?.pluginsRoot)) {
600
+ if (!has(path)) sources.push({ id: `package:${skillSourceId(path).replace(/^plugin:/, '')}`, path, kind: 'package', enabled: true });
601
+ }
543
602
  }
544
- base = sk.includeClaudePackageSkills === true
545
- ? appendClaudePackageSkillDirs(base, opts?.pluginsRoot)
546
- : base;
547
603
  } catch { /* fail-soft — config 없거나 파싱 실패 시 기본 경로 */ }
604
+ return sources;
605
+ }
606
+
607
+ export function defaultSkillDirs(
608
+ cfg?: UserConfig,
609
+ opts?: DefaultSkillDirsOptions,
610
+ ): string[] {
611
+ const sources = resolveSkillSources(cfg, opts);
612
+ const paths = sources.filter((source) => source.enabled).map((source) => source.path);
613
+ // Historical: the package opt-in path also collapsed duplicate user dirs; the plain path kept them (index dedupes later).
614
+ const base = sources.some((source) => source.kind === 'package') || packageOptIn(cfg) ? uniqueSkillDirsPreserveOrder(paths) : paths;
548
615
  return appendBundledSkillsDir(base, opts?.bundledSkillsRoot);
549
616
  }
550
617
 
@@ -1384,6 +1451,28 @@ export interface ChatCompactConfig {
1384
1451
  archiveRetentionMb: number;
1385
1452
  }
1386
1453
 
1454
+ /** ER1 — 액티브 덤퍼(오류 자동 보고). 기본 켬(첫 실행 안내 한 번 · 대표 10-01) · 신원(email/telegramUser)은 따로 «예»일 때만. */
1455
+ export interface ErrorReportsConfig {
1456
+ /** false = never send. Absent = on (the first-run notice says how to turn it off). */
1457
+ enabled?: boolean;
1458
+ /** true = also send email / telegramUser below with each report. Default false. */
1459
+ identity?: boolean;
1460
+ email?: string;
1461
+ telegramUser?: string;
1462
+ }
1463
+
1464
+ export function parseErrorReportsConfig(raw: unknown): ErrorReportsConfig | undefined {
1465
+ if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return undefined;
1466
+ const r = raw as Record<string, unknown>;
1467
+ const out: ErrorReportsConfig = {};
1468
+ if (r.enabled === false || r.enabled === 'false') out.enabled = false;
1469
+ else if (r.enabled === true || r.enabled === 'true') out.enabled = true;
1470
+ if (r.identity === true || r.identity === 'true') out.identity = true;
1471
+ if (typeof r.email === 'string' && r.email.trim()) out.email = r.email.trim();
1472
+ if (typeof r.telegramUser === 'string' && r.telegramUser.trim()) out.telegramUser = r.telegramUser.trim();
1473
+ return Object.keys(out).length ? out : undefined;
1474
+ }
1475
+
1387
1476
  export interface ChatConfig {
1388
1477
  /** Short questions may receive a tool-free first reply. Default true. */
1389
1478
  fastPath: boolean;
@@ -3373,6 +3462,8 @@ export interface UserConfig {
3373
3462
  logs: LogsConfig;
3374
3463
  shell: ShellConfig;
3375
3464
  chat: ChatConfig;
3465
+ /** ER1 — optional so older fixtures stay valid; absent = defaults. */
3466
+ errorReports?: ErrorReportsConfig;
3376
3467
  voice: VoiceConfig;
3377
3468
  intake: IntakeConfig;
3378
3469
  dashboard: DashboardConfig;
@@ -4419,6 +4510,7 @@ export function buildUserConfig(path: string = defaultPath()): UserConfig {
4419
4510
  activeSet: normalizeSkillSet(sk.activeSet),
4420
4511
  dirs: strArray(sk.dirs, skillsDefaults().dirs),
4421
4512
  includeSharedAgentSkills: sk.includeSharedAgentSkills !== false,
4513
+ ...(() => { const sources = parsePersistedSkillSources(sk.sources, sk.connected); return sources ? { sources } : {}; })(),
4422
4514
  allow: strArray(sk.allow, []),
4423
4515
  deny: strArray(sk.deny, []),
4424
4516
  urlRouting: parseUrlRouting(sk.urlRouting),
@@ -4546,6 +4638,7 @@ export function buildUserConfig(path: string = defaultPath()): UserConfig {
4546
4638
  // false required to short-circuit `buildDashboardOptionalToolSpecs`.
4547
4639
  allowDashboardOptionalTools: sh.allowDashboardOptionalTools !== false,
4548
4640
  },
4641
+ ...((): { errorReports?: ErrorReportsConfig } => { const er = parseErrorReportsConfig(rawObj.errorReports); return er ? { errorReports: er } : {}; })(),
4549
4642
  chat: {
4550
4643
  fastPath: chat.fastPath === false || chat.fastPath === 'false' ? false : CHAT_DEFAULTS.fastPath,
4551
4644
  conciseness: {
@@ -5590,6 +5683,10 @@ export function saveUserConfig(
5590
5683
  skills: stripUndef({
5591
5684
  activeSet: cfg.skills.activeSet,
5592
5685
  dirs: [...cfg.skills.dirs],
5686
+ // EN5 — only connected roots are persisted (preset/shared/package are derived). The dev-only `connected` key is not written back.
5687
+ sources: cfg.skills.sources && cfg.skills.sources.some((source) => source.kind === 'connected')
5688
+ ? cfg.skills.sources.filter((source) => source.kind === 'connected').map(({ id, path, enabled }) => ({ id, path, enabled }))
5689
+ : undefined,
5593
5690
  // Omit allow/deny when empty to keep disk JSON minimal for the
5594
5691
  // common "no filter" case.
5595
5692
  allow: cfg.skills.allow && cfg.skills.allow.length > 0 ? [...cfg.skills.allow] : undefined,
@@ -5683,6 +5780,7 @@ export function saveUserConfig(
5683
5780
  debug: cfg.debug,
5684
5781
  logs: cfg.logs,
5685
5782
  shell: cfg.shell,
5783
+ errorReports: cfg.errorReports ? stripUndef({ ...cfg.errorReports }) : undefined,
5686
5784
  chat: stripUndef({
5687
5785
  fastPath: cfg.chat.fastPath,
5688
5786
  conciseness: stripUndef({
@@ -1 +1 @@
1
- {"commit":"eadd7c31e07d4414ce452d943984a2e58a01ede4"}
1
+ {"commit":"eca73b4a3a106df99424c22206165f2fe4e5e910"}
@@ -1 +0,0 @@
1
- "use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[4836],{12455:(e,t,r)=>{r.d(t,{zV:()=>eQ});var n=r(41121),a=r(91269),l=r(66062),s=r(54903),o=r(17591),i=r(10679),c=r(2143),d=r(73455);r(68187);var u=r(38519),m=r(51215);function p(e){let t=e.split("\n"),r=t[0];if(!r)return null;let n=/^\[elanous\/term\/([a-zA-Z]+)\] (.+)$/.exec(r);if(!n)return null;let a=n[1];if("terminalOutput"!==a&&"terminalExit"!==a&&"terminalInputActivity"!==a&&"terminalFrame"!==a)return null;let l=[];for(let e=1;e<t.length;e++){let r=t[e];if(/^<<elanous-term-end /.test(r))break;l.push(r)}try{let e=JSON.parse(l.join("\n"));if("string"!=typeof e.terminalId)return null;if("terminalOutput"===a){if("string"!=typeof e.data)return null;return{method:a,payload:{terminalId:e.terminalId,data:e.data}}}if("terminalExit"===a){if("number"!=typeof e.code)return null;return{method:a,payload:{terminalId:e.terminalId,code:e.code}}}if("terminalFrame"===a){if("string"!=typeof e.frame||"string"!=typeof e.instance||"number"!=typeof e.at||!Number.isFinite(e.at))return null;return{method:a,payload:{terminalId:e.terminalId,frame:e.frame,instance:e.instance,at:e.at}}}if("string"!=typeof e.peerId||"number"!=typeof e.timestamp||"number"!=typeof e.bytes)return null;return{method:a,payload:{terminalId:e.terminalId,peerId:e.peerId,timestamp:e.timestamp,bytes:e.bytes}}}catch(e){return null}}let h="elanous.pwa.peerId",f=null;function b(){if(f)return f;let e=window.sessionStorage.getItem(h);return e&&0!==e.length||(e=function(){if("undefined"!=typeof crypto&&"function"==typeof crypto.getRandomValues){let e=new Uint32Array(2);return crypto.getRandomValues(e),(BigInt(e[0])<<32n|BigInt(e[1])).toString(36).slice(0,8)}return Math.random().toString(36).slice(2,10)}(),window.sessionStorage.setItem(h,e)),f=e,e}var g=r(91732);let x=/^\x1b\[[?>=][\d;]*[a-zA-Z$]/,v=/^\x1b\[\d+;\d+R$/,w=/^\x1b\[0?n$/,y=/^\x1b\][\d;]+;[^\x07\x1b]*(?:\x07|\x1b\\)$/,k=/^\x1b\[\d+;\d+;\d+t$/,j=new Map;function N(e,t){let r=j.get(e);return r?(r.sender(t),!0):((0,m.cY)("webterm.input.no-sender",{terminalId:e,bytes:new TextEncoder().encode(t).length}),!1)}function S(e){var t;let{sessionId:l,terminalId:h,clearRequest:f=0,readOnly:N=!1,onForeignInputActivity:S}=e,I=(0,a.useRef)(null),C=(0,a.useRef)(null),T=(0,a.useRef)(void 0),Y=(0,a.useRef)(h);Y.current!==h&&(Y.current=h,T.current=void 0);let E=(0,a.useRef)(l);E.current=l;let R=(0,a.useRef)(S);R.current=S;let{client:A,config:z,setSessionId:P}=(0,u.Q)(),[M,D]=(0,a.useState)(()=>({state:"CONNECTING",terminalId:h,connectingSince:Date.now()})),[U,L]=(0,a.useState)(0),$=(0,a.useRef)(0),[O,F]=(0,a.useState)(()=>Date.now()),[B,Q]=(0,a.useState)(null),q=(null==B?void 0:B.terminalId)===h?B:null,H=M.terminalId===h?M.state:"CONNECTING",_=M.terminalId===h?M.connectingSince:O;(0,a.useEffect)(()=>{if("CONNECTING"!==H)return;F(Date.now());let e=window.setInterval(()=>F(Date.now()),1e3);return()=>window.clearInterval(e)},[H,h]),(0,a.useEffect)(()=>{var e,t,n;if(!I.current)return;let a=new s.B({fontFamily:'"JetBrainsMono Nerd Font", "JetBrains Mono", monospace',fontSize:13,theme:{background:"#0d0c08",foreground:"#e9e3d4",cursor:"#e9e3d4"},allowProposedApi:!0,scrollback:5e3,cursorBlink:!N,disableStdin:N});(0,m.cY)("webterm.xterm.boot",{sessionId:l,terminalId:h,readOnly:N});let u=new o.Y;a.loadAddon(u),a.loadAddon(new i.c((e,t)=>(0,m.cY)("webterm.link.click",{uri:t}))),a.loadAddon(new c.I);let f=new d.V;a.loadAddon(f),(async()=>{try{let e=await r.e(4323).then(r.bind(r,14323));a.loadAddon(new e.WebglAddon)}catch(e){(0,m.cY)("webterm.webgl.fallback",{reason:String(e)})}})(),(async()=>{try{let e=await r.e(3403).then(r.bind(r,63403));a.loadAddon(new e.ImageAddon),(0,m.cY)("webterm.image-addon.loaded")}catch(e){(0,m.cY)("webterm.image-addon.fallback",{reason:String(e)})}})(),a.unicode.activeVersion="11",a.open(I.current),C.current=a,u.fit();let S=(0,g.o1)("xtermScrollback",h),T=(0,g.N2)(S);"string"==typeof T&&T.length>0&&a.write(T);let Y=()=>{},z=A.connectAcp({...l?{sessionId:l}:{},onSession:e=>{e&&(E.current=e,Y(e)),e&&e!==l&&((0,m.cY)("webterm.acp.session.adopted",{from:l,to:e}),P(e))}});(0,m.cY)("webterm.acp.session.attach",{sessionId:l,terminalId:h});let M=z.onState((e,t)=>{let r=Date.now();D(n=>({state:e,terminalId:h,connectingSince:"CONNECTING"===e?r:n.connectingSince,...(null==t?void 0:t.message)?{reason:t.message}:{}})),"OPEN"===e&&($.current=0),"CONNECTING"===e&&F(r),(0,m.cY)("webterm.xterm.acp-state",{terminalId:h,state:e,reason:null==t?void 0:t.message})}),U=()=>{},L=!1,O=Date.now(),B=new Promise(e=>{let t=!1;U=r=>{t||(t=!0,(0,m.cY)("webterm.shell.ready",{terminalId:h,via:r,ms:Date.now()-O}),e())}}),q=setTimeout(()=>U("cap-20s"),2e4);z.ready.then(e=>e?z.send("terminal/spawn",{sessionId:e,terminalId:h,cols:a.cols,rows:a.rows,replay:!0}):void U("no-session")).then(e=>{if(void 0===e)return;(0,m.cY)("webterm.spawn.result",e);let t="string"!=typeof e.snapshot||0===e.snapshot.trim().length;if("spawned"===e.status||"attached"===e.status&&t?L=!0:U("attached"===e.status?"attached":"status:".concat(String(e.status))),!N&&E.current){try{u.fit()}catch(e){}(0,m.cY)("webterm.xterm.size-sync",{terminalId:h,cols:a.cols,rows:a.rows,status:e.status}),z.send("terminal/resize",{sessionId:E.current,terminalId:h,cols:a.cols,rows:a.rows}).catch(e=>(0,m.cY)("webterm.resize.send-error",{reason:String(e)}))}"attached"===e.status&&"string"==typeof e.snapshot&&e.snapshot.length>0&&((0,m.cY)("webterm.attach.replay",{terminalId:h,bytes:e.snapshot.length}),a.write("\x1b[2J\x1b[H"+e.snapshot.split("\n").join("\r\n")+"\r\n"))}).catch(e=>{(0,m.cY)("webterm.spawn.error",{reason:String(e)}),U("spawn-error")});let H=z.on("sessionUpdate",e=>{var t,r,n;let l=null!=(r=e.params)?r:{},s=E.current;if(l.sessionId&&s&&l.sessionId!==s)return;let o=l.update;if(!o||"agent_thought_chunk"!==o.sessionUpdate)return;let i=(null==(t=o.content)?void 0:t.type)==="text"?o.content.text:null;if(!i)return;let c=p(i);c&&("terminalOutput"===c.method&&c.payload.terminalId===h?((0,m.cY)("webterm.ws.frame.in",{terminalId:h,bytes:c.payload.data.length}),a.write(c.payload.data),L&&(L=!1,U("first-output"))):"terminalExit"===c.method&&c.payload.terminalId===h?((0,m.cY)("webterm.pty.exit",{terminalId:h,code:c.payload.code}),a.write("\r\n\x1b[2m[exit ".concat(c.payload.code,"]\x1b[0m\r\n"))):"terminalInputActivity"===c.method&&c.payload.terminalId===h&&c.payload.peerId!==b()&&((0,m.cY)("webterm.peer.input",{terminalId:h,peerId:c.payload.peerId.slice(0,4),bytes:c.payload.bytes}),null==(n=R.current)||n.call(R,{peerId:c.payload.peerId,bytes:c.payload.bytes,timestamp:c.payload.timestamp})))}),_=function(e){let t,{send:r,ready:n,getSessionId:a,terminalId:l,getPeerId:s,log:o,shellReady:i}=e,c=!i,d=[],u="",m=!1,p=!1,h=!1,f=!1,b=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";if(h)return;let r=new TextEncoder().encode(t+d.join("")).length;d.length=0,o("webterm.input.send-error",{reason:String(e),dropped:r})},g=async()=>{if(u&&c&&!p&&!h){p=!0;try{for(;d.length&&!h;){let e=d.shift();try{let t=a();await r("terminal/input",{sessionId:m&&t?t:u,terminalId:l,data:e,peerId:s()})}catch(t){b(t,e);break}}}finally{p=!1}}};return i&&i.then(()=>{c=!0,g()}),n.then(e=>{if(!h){if(!e){f=!0,b(t="ACP handshake returned no session");return}u=e,g()}},e=>{f=!0,t=e,b(e)}),{confirmSession(e){!h&&u&&e&&(m=!0)},push(e){if(!h){if(f)return void b(t,e);d.push(e),g()}},dispose(){h=!0,d.length=0}}}({send:(e,t)=>z.send(e,t),ready:z.ready,shellReady:B,getSessionId:()=>E.current,terminalId:h,getPeerId:b,log:(e,t)=>{(0,m.cY)(e,t),t.dropped>0&&Q({terminalId:h,dropped:t.dropped})}});Y=_.confirmSession;let V=N?null:function(e,t){let r={sender:t};return j.set(e,r),()=>{j.get(e)===r&&j.delete(e)}}(h,_.push),G=N?null:a.onData(e=>{if(e&&!(e.length<2)&&27===e.charCodeAt(0)&&(x.test(e)||v.test(e)||w.test(e)||y.test(e)||k.test(e)))return void(0,m.cY)("webterm.xterm.onData.capability-swallow",{terminalId:h,bytes:e.length});(0,m.cY)("webterm.xterm.onData",{terminalId:h,bytes:e.length}),_.push(e)}),J=N?null:a.onResize(e=>{let{cols:t,rows:r}=e;(0,m.cY)("webterm.xterm.onResize",{terminalId:h,cols:t,rows:r}),z.send("terminal/resize",{sessionId:E.current,terminalId:h,cols:t,rows:r}).catch(e=>(0,m.cY)("webterm.resize.send-error",{reason:String(e)}))}),K=I.current,W=null,Z=e=>{if(1!==e.touches.length){W=null;return}W={y:e.touches[0].clientY,viewportY:a.buffer.active.viewportY}},X=e=>{var t,r,n;if(!W||1!==e.touches.length)return;let l=a.rows>0?(null!=(n=null==(r=a.element)||null==(t=r.querySelector(".xterm-screen"))?void 0:t.getBoundingClientRect().height)?n:0)/a.rows:0,s=function(e){if(!(e.cellHeight>0))return 0;let t=-Math.trunc((e.currentY-e.startY)/e.cellHeight)-(e.currentViewportY-e.startViewportY);return 0===t?0:t}({startY:W.y,currentY:e.touches[0].clientY,cellHeight:l,startViewportY:W.viewportY,currentViewportY:a.buffer.active.viewportY});0!==s&&a.scrollLines(s)},ee=()=>{W=null};null==(e=K.addEventListener)||e.call(K,"touchstart",Z,{passive:!0}),null==(t=K.addEventListener)||t.call(K,"touchmove",X,{passive:!0}),null==(n=K.addEventListener)||n.call(K,"touchend",ee,{passive:!0});let et=function(e){var t,r;let n=null!=(t=e.trailingDebounceMs)?t:32,a=null,l=!1,s=()=>{if((a=null,!l)&&e.onTrailing)try{e.onTrailing()}catch(e){}},o=t=>{var r,o;if(l)return;let i=performance.now(),c=null==(o=e.target)||null==(r=o.getBoundingClientRect)?void 0:r.call(o),d=c?Math.round(c.width):void 0,u=c?Math.round(c.height):void 0;if((null==c?void 0:c.height)===0){null!==a&&(clearTimeout(a),a=null),(0,m.cY)("webterm.resize.skip",{source:t,...void 0!==d?{w:d}:{},h:u,reason:"zero-height"});return}let p=null;try{e.onImmediate()}catch(e){p=e instanceof Error?e.message:String(e)}(0,m.cY)("webterm.resize.trigger",{source:t,dt:Math.round((performance.now()-i)*100)/100,...void 0!==d?{w:d}:{},...void 0!==u?{h:u}:{},...p?{err:p}:{}}),e.onTrailing&&(null!==a&&clearTimeout(a),a=setTimeout(s,n))},i=null;"undefined"!=typeof ResizeObserver&&(i=new ResizeObserver(()=>o("ro"))).observe(e.target);let c=()=>o("win");window.addEventListener("resize",c);let d=null!=(r=window.visualViewport)?r:null,u=()=>o("vv");return d&&d.addEventListener("resize",u),{dispose(){if(!l){if(l=!0,null!==a&&(clearTimeout(a),a=null),i){try{i.disconnect()}catch(e){}i=null}window.removeEventListener("resize",c),d&&d.removeEventListener("resize",u)}},flushPending(){null!==a&&(clearTimeout(a),s())}}}({target:I.current,onImmediate:()=>{try{u.fit()}catch(e){}},onTrailing:()=>{try{u.fit()}catch(e){}}});return()=>{var e,t,r;try{let e=f.serialize();"string"==typeof e&&(0,g.Os)((0,g.o1)("xtermScrollback",h),e)}catch(e){(0,m.cY)("webterm.xterm.snapshot.error",{reason:String(e)})}try{et.dispose()}catch(e){}null==(e=K.removeEventListener)||e.call(K,"touchstart",Z),null==(t=K.removeEventListener)||t.call(K,"touchmove",X),null==(r=K.removeEventListener)||r.call(K,"touchend",ee),null==V||V(),_.dispose(),clearTimeout(q),H(),M();try{null==G||G.dispose()}catch(e){}try{null==J||J.dispose()}catch(e){}try{z.close()}catch(e){}C.current===a&&(C.current=null);try{a.dispose()}catch(e){}(0,m.cY)("webterm.xterm.teardown",{terminalId:h})}},[h,N,A,U]);let V="FAILED"===H||"CLOSED"===H?(t=M.reason)&&/auth_failed|\b1008\b|unauthori[sz]ed|\b401\b/i.test(t)?"auth":"transient":null,G=(0,a.useRef)(z.token);(0,a.useEffect)(()=>{G.current!==z.token&&(G.current=z.token,"auth"===V&&z.token&&((0,m.cY)("webterm.acp.reconnect",{terminalId:h,why:"token-changed"}),L(e=>e+1)))},[z.token]),(0,a.useEffect)(()=>{var e,t,r;if(null===V)return;let n=e=>{$.current+=1,(0,m.cY)("webterm.acp.reconnect",{terminalId:h,why:e,attempt:$.current,reason:M.reason}),L(e=>e+1)},a="undefined"==typeof document?null:document,l=window,s=()=>{(null==a?void 0:a.visibilityState)==="visible"&&n("visible")},o=()=>n("online");null==a||null==(e=a.addEventListener)||e.call(a,"visibilitychange",s),null==l||null==(t=l.addEventListener)||t.call(l,"online",o);let i="transient"===V?setTimeout(()=>n("backoff"),(r=$.current,Math.min(3e4,1e3*2**Math.max(0,r)))):void 0;return()=>{var e,t;null==a||null==(e=a.removeEventListener)||e.call(a,"visibilitychange",s),null==l||null==(t=l.removeEventListener)||t.call(l,"online",o),void 0!==i&&clearTimeout(i)}},[V,h]),(0,a.useEffect)(()=>{var e;e=T.current,void 0!==e&&e!==f&&C.current&&(C.current.clear(),(0,m.cY)("webterm.controls.clear.applied",{terminalId:h})),T.current=f},[f,h]);let J="CONNECTING"===H?$.current>0?"다시 연결 중(".concat($.current,"회)"):"연결 중":"OPEN"===H?"연결됨":"auth"===V?"토큰 없음":"FAILED"===H?"연결 실패 \xb7 곧 다시 붙습니다":"연결 끊김 \xb7 곧 다시 붙습니다",K="OPEN"===H?"text-emerald-300":"CONNECTING"===H?"text-amber-300":"text-red-300",W=h.trim()||"대상 미지정",Z=Math.max(0,Math.floor((O-_)/1e3));return(0,n.jsxs)("div",{className:"relative h-full w-full bg-[#0d0c08]",children:[(0,n.jsx)("div",{ref:I,className:"h-full w-full"}),q&&(0,n.jsxs)("div",{role:"alert",className:"pointer-events-none absolute bottom-2 left-2 right-2 rounded bg-red-950/95 px-3 py-2 text-sm text-red-100",children:["터미널 입력 전송 실패: ",q.dropped,"바이트가 버려졌습니다. 명령이 일부만 실행됐을 수 있습니다. 입력을 확인하고 다시 입력하세요."]}),"auth"===V&&(0,n.jsxs)("div",{role:"alert",className:"absolute left-2 right-2 top-10 z-30 space-y-1 rounded bg-amber-950/95 px-3 py-2 text-sm text-amber-100","data-webterm-auth-missing":!0,children:[(0,n.jsx)("p",{children:"이 기기에 소유자 토큰이 없어 터미널에 연결하지 못했습니다 — 설정에서 토큰을 붙이면 바로 연결됩니다."}),(0,n.jsx)("p",{className:"text-xs text-amber-200/90",children:"토큰 얻기: 이미 연결된 기기의 설정 › Connect token 에서 만들거나, 데몬 기계에서 pbcopy < ~/.elanous/acp-token → 이 기기의 설정 › Daemon › Bearer token 칸에 붙여 넣기"}),(0,n.jsx)("a",{href:"/app/settings/#bearer-token",className:"inline-block font-medium underline","data-webterm-auth-settings":!0,children:"설정 열기 →"})]}),(0,n.jsxs)("span",{"aria-live":"polite",className:"sr-only",children:["ACP: ",J]}),(0,n.jsxs)("span",{className:"pointer-events-none absolute right-2 top-2 rounded bg-black/70 px-2 py-1 text-xs ".concat(K),children:["ACP: ",J,"CONNECTING"===H&&" \xb7 ".concat(Z,"초 \xb7 ").concat(W," \xb7 ").concat(z.baseUrl)]})]})}let I={failures:0,stopped:!1,message:null,screen:null},C=/^\[screen \d+x\d+ cursor=[^\]\n]*\]\r?\n/;function T(e){let t=e.replace(C,"").replace(/\r?\n/g,"\r\n");return"\x1b[H\x1b[2J".concat(t)}function Y(e,t){var r;if(e.stopped)return e;if((null==t?void 0:t.status)==="success"&&"string"==typeof t.screen)return{failures:0,stopped:!1,message:null,screen:T(t.screen)};if((null==t?void 0:t.status)==="unknown-pty")return{...e,stopped:!0,message:"PTY 가 끝났습니다"};if((null==t?void 0:t.status)==="denied")return{...e,failures:0,stopped:!0,message:t.reason||"화면 조회가 거부되었습니다"};let n=e.failures+1;return(null==t?void 0:t.status)!=="owner-unreachable"?{...e,failures:n,stopped:n>=5,message:(null==t?void 0:t.reason)||"화면 조회에 실패했습니다"}:{...e,failures:n,stopped:n>=5,message:n>=5?"소유 프로세스에 닿지 않습니다":null!=(r=t.reason)?r:null}}function E(e){var t,r;let{terminal:l,client:o,onClose:d}=e,u=(0,a.useRef)(null),p=(0,a.useRef)(null),h=(0,a.useRef)(null),f=(0,a.useRef)(I),[b,g]=(0,a.useState)(!1),[x,v]=(0,a.useState)(!1),w=(0,a.useRef)(!1),[y,k]=(0,a.useState)(null),[j,N]=(0,a.useState)("connecting");return(0,a.useEffect)(()=>{var e,t,r;let n;if(!u.current)return;let a={closed:!1,owned:!1,accepting:!1,queue:Promise.resolve(),takeover:null,release:null};h.current=a,w.current=!1,v(!1);let d={sourceRoot:null==(e=l.sourceRoot)?void 0:e.dbPath},b=new s.B({cols:110,rows:40,fontFamily:'"JetBrainsMono Nerd Font", "JetBrains Mono", monospace',fontSize:13,theme:{background:"#0d0c08",foreground:"#e9e3d4",cursor:"#e9e3d4"},cursorBlink:!1,disableStdin:!0,scrollback:0,allowProposedApi:!0});b.loadAddon(new i.c),b.loadAddon(new c.I),b.unicode.activeVersion="11",b.open(u.current),b.write("\x1b[?25l"),p.current=b,f.current=I,g(!1),k(null);let x=b.onData(e=>{if(!a.accepting||a.closed||!e)return;let t=e.startsWith("\x1b")||"\r"===e||"\n"===e||""===e||" "===e||"\x03"===e;a.queue=a.queue.then(async()=>{try{let r=t?await o.sendTerminalKey(l.id,e,d):await o.sendTerminalText(l.id,e,d);if(a.closed)return;"success"!==r.status&&("denied"===r.status&&(a.accepting=!1,g(!1),b.options.disableStdin=!0),k(r.reason||"입력 실패: ".concat(r.status)))}catch(e){a.closed||k("입력 전송 실패: ".concat(String(e)))}})}),y=u.current,j=!1,S=e=>{a.queue=a.queue.then(async()=>{try{var t;if(!o.sendTerminalMouse)return;let r=await o.sendTerminalMouse(l.id,e,d);if(a.closed||"success"===r.status)return;if((t=r.reason)&&/mouse mode is off|\?1006/i.test(t)){"click"!==e.kind||j||(j=!0,k("이 앱은 마우스를 받지 않는다(마우스 모드 꺼짐) — 키보드로 조작하세요."));return}k(r.reason||"마우스 전송 실패: ".concat(r.status))}catch(e){a.closed||k("마우스 전송 실패: ".concat(String(e)))}})},C=e=>{var t;let r=null==(t=b.element)?void 0:t.querySelector(".xterm-screen");return r?function(e,t,r,n,a){if(!(r.width>0)||!(r.height>0)||n<1||a<1)return null;let l=Math.floor((e-r.left)/r.width*n)+1,s=Math.floor((t-r.top)/r.height*a)+1;return{x:Math.min(n,Math.max(1,l)),y:Math.min(a,Math.max(1,s))}}(e.clientX,e.clientY,r.getBoundingClientRect(),b.cols,b.rows):null},E=()=>a.accepting&&!a.closed&&"none"===b.modes.mouseTrackingMode,R=e=>{var t;if(!E())return;let r=0===(t=e.button)?"left":1===t?"middle":2===t?"right":null,n=C(e);r&&n&&S({...n,kind:"click",button:r})},A=e=>{if(!E()||0===e.deltaY)return;let t=C(e);t&&(e.preventDefault(),e.stopPropagation(),S({...t,kind:e.deltaY<0?"scroll-up":"scroll-down"}))};null==(t=y.addEventListener)||t.call(y,"mousedown",R,{capture:!0}),null==(r=y.addEventListener)||r.call(y,"wheel",A,{passive:!1,capture:!0});let z=async()=>{var e,t,r,s;if(!a.closed&&(e=!document.hidden,t=f.current,e&&!t.stopped)){try{let e=await o.snapshotTerminal(l.id,{ansi:!0,sourceRoot:d.sourceRoot});if(a.closed)return;let t=Y(f.current,e);f.current=t,null!==t.screen&&"success"===e.status&&b.write(t.screen+"\x1b[?25l"),k(t.message)}catch(t){if(a.closed)return;let e=Y(f.current,null);f.current=e,k(e.message)}a.closed||(r=!document.hidden,s=f.current,!r||s.stopped)||(n=setTimeout(()=>{z()},800))}},P=!o.streamTerminal,M=null,D=()=>{!o.streamTerminal||a.closed||P||(N("connecting"),M=o.streamTerminal(l.id,{sourceRoot:d.sourceRoot},e=>{a.closed||("mode"===e.type?N("bytes"===e.mode?"stream-bytes":"stream-screen"):"reset"===e.type||"screen"===e.type?(b.write(T(e.screen)+"\x1b[?25l"),k(null)):"data"===e.type?b.write(e.chunk):"end"===e.type?(k("PTY 가 끝났습니다"),f.current={...f.current,stopped:!0}):"status"===e.type&&k("화면 조회: ".concat(e.status)))},e=>{a.closed||((0,m.cY)("pwa.terminal.stream-fallback",{id:l.id,reason:e}),P=!0,N("poll"),z())}))},U=()=>{if(n&&clearTimeout(n),n=void 0,!P)return void(document.hidden?(null==M||M(),M=null):M||f.current.stopped||D());document.hidden||a.closed||f.current.stopped||z()};return document.addEventListener("visibilitychange",U),P?(N("poll"),z()):D(),()=>{var e,t;a.closed=!0,a.accepting=!1,n&&clearTimeout(n),null==M||M(),document.removeEventListener("visibilitychange",U),x.dispose(),null==(e=y.removeEventListener)||e.call(y,"mousedown",R,{capture:!0}),null==(t=y.removeEventListener)||t.call(y,"wheel",A,{capture:!0}),(async()=>{if(await a.takeover,a.release&&await a.release,a.owned){await a.queue;try{let e=await o.controlTerminal(l.id,"release",d);"success"===e.status&&(a.owned=!1)}catch(e){}}})(),h.current===a&&(h.current=null),p.current=null,b.dispose()}},[o,l.id,null==(t=l.sourceRoot)?void 0:t.dbPath]),(0,n.jsxs)("section",{className:"flex h-full min-h-0 flex-col bg-[#0d0c08]","aria-label":"PTY 라이브 화면",children:[(0,n.jsxs)("header",{className:"flex flex-wrap items-center gap-3 border-b border-zinc-700 px-3 py-2 text-sm text-zinc-100",children:[(0,n.jsx)("span",{className:"font-mono",children:l.id}),(0,n.jsx)("span",{children:null!=(r=l.kind)?r:"PTY"}),(0,n.jsx)("span",{children:b?"입력 가능":"읽기 전용"}),(0,n.jsx)("span",{className:"rounded bg-zinc-800 px-1.5 py-0.5 font-mono text-[10px] text-zinc-300","data-pty-feed":j,title:"화면을 받는 방식",children:"stream-bytes"===j?"● 실시간":"stream-screen"===j?"● 실시간(화면)":"poll"===j?"폴링 0.8s":"연결 중"}),(0,n.jsx)("button",{type:"button",disabled:x,onClick:()=>{(e=>{var t;let r=h.current;if(!r||r.closed||w.current)return;w.current=!0,v(!0);let n={sourceRoot:null==(t=l.sourceRoot)?void 0:t.dbPath};"release"===e&&(r.accepting=!1,p.current&&(p.current.options.disableStdin=!0));let a=(async()=>{try{"release"===e&&await r.queue;let t=await o.controlTerminal(l.id,e,n);if("success"===t.status&&(r.owned="takeover"===e),r.closed)return;"success"===t.status?(r.accepting="takeover"===e,g(r.accepting),p.current&&(p.current.options.disableStdin=!r.accepting),k(null)):("release"===e&&(r.accepting=r.owned,p.current&&(p.current.options.disableStdin=!r.accepting)),k(t.reason||("denied"===t.status?"제어 거부: 권한이 없습니다":"제어 실패: ".concat(t.status))))}catch(t){r.closed||("release"===e&&(r.accepting=r.owned,p.current&&(p.current.options.disableStdin=!r.accepting)),k("제어 요청 실패: ".concat(String(t))))}finally{r.closed||(w.current=!1,v(!1))}})();"takeover"===e?r.takeover=a:r.release=a})(b?"release":"takeover")},children:b?"release":"takeover"}),(0,n.jsx)("button",{type:"button",onClick:d,"aria-label":"PTY 라이브 닫기",children:"닫기"})]}),y&&(0,n.jsx)("p",{role:"status",className:"px-3 py-1 text-amber-300",children:y}),(0,n.jsx)("div",{ref:u,className:"min-h-0 flex-1 overflow-auto","aria-label":"".concat(l.id," 화면")})]})}var R=r(19528);let A=e=>"string"==typeof e&&e.trim()?e:null,z={codex:"codex",claude:"claude",gemini:"gemini",grok:"grok",self:"elanous",mission:"elanous 미션",shell:"셸",pty:"PTY"},P={PLAN:"text-sky-400",ROUTE:"text-violet-400",VERIFY:"text-amber-400",HEAL:"text-emerald-400",ESCALATE:"text-rose-400",SHIP:"text-green-400"};function M(e){let{rows:t,client:r,initial:l,onClose:s,stage:o=!1}=e,[i,c]=(0,a.useState)(l);(0,a.useEffect)(()=>{0===i.length&&t.length&&c(function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:3,r=e.filter(e=>e.alive),n=r.filter(e=>e.kind&&["codex","claude","self","mission","gemini","grok"].includes(e.kind)),a=r.filter(e=>!n.includes(e));return[...n,...a].slice(0,t).map(e=>e.id)}(t))},[t,i.length]),(0,a.useEffect)(()=>{let e=new URLSearchParams(window.location.search);i.length?e.set("wall",i.join(",")):e.delete("wall"),window.history.replaceState(null,"","".concat(window.location.pathname,"?").concat(e.toString()))},[i]);let[d,u]=(0,a.useState)([]);(0,a.useEffect)(()=>{let e=!0,t=async()=>{try{var t;let n=await r.fetchJson("/v1/logs?category=harness.decision&store=@active&since=6h&limit=300");e&&u(null!=(t=n.logs)?t:[])}catch(e){}};t();let n=window.setInterval(()=>{document.hidden||t()},5e3);return()=>{e=!1,window.clearInterval(n)}},[r]);let[m,p]=(0,a.useState)(!1);(0,a.useEffect)(()=>{"public"===new URLSearchParams(window.location.search).get("capture")&&p(!0)},[]);let h=(0,a.useMemo)(()=>m?(0,R.yR)(d.map(e=>{var t;return{ts:e.ts,category:"harness.decision",event:"decision",data:null!=(t=e.data)?t:null}})):d,[d,m]),f=(0,a.useMemo)(()=>i.map(e=>t.find(t=>t.id===e)).filter(e=>!!e),[i,t]),b=e=>c(t=>t.includes(e)?t.filter(t=>t!==e):[...t,e].slice(-3));return(0,n.jsxs)("section",{className:"flex h-full min-h-0 flex-col bg-[#0b0a07]","aria-label":"터미널 나란히","data-pty-wall":!0,children:[(0,n.jsxs)("header",{className:"flex flex-wrap items-center gap-2 border-b border-zinc-700 px-3 py-2 text-xs text-zinc-200",children:[(0,n.jsxs)("span",{className:"font-medium",children:["나란히 \xb7 ",f.length,"/3"]}),t.filter(e=>e.alive).slice(0,14).map(e=>{var t,r,a;return(0,n.jsxs)("button",{type:"button",onClick:()=>b(e.id),"aria-pressed":i.includes(e.id),className:"rounded-full border px-2 py-0.5 font-mono ".concat(i.includes(e.id)?"border-emerald-500 bg-emerald-900/40 text-emerald-200":"border-zinc-700 text-zinc-400 hover:bg-zinc-800"),"data-pty-wall-chip":e.id,children:[null!=(r=e.kind)?r:"pty"," \xb7 ",e.nickname||e.id]},"".concat(null!=(a=null==(t=e.sourceRoot)?void 0:t.dbPath)?a:"",":").concat(e.id))}),(0,n.jsx)("button",{type:"button",onClick:s,className:"ml-auto rounded px-2 py-1 text-zinc-400 hover:bg-zinc-800","aria-label":"나란히 닫기",children:"닫기"})]}),0===f.length?(0,n.jsx)("p",{className:"p-6 text-sm text-zinc-400",children:"위에서 PTY 를 1~3개 고르세요 — 살아 있는 에이전트 PTY 가 없으면 비어 있습니다."}):(0,n.jsx)("div",{className:"grid min-h-0 flex-1 gap-1 p-1 ".concat(1===f.length?"grid-cols-1":2===f.length?"grid-cols-2":"grid-cols-3"),children:f.map(e=>{var t,a;let l=function(e,t){let r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:3;return t.filter(t=>{var r;let n=null!=(r=t.data)?r:{};return!!e.runId&&n.runId===e.runId||n.target===e.id||n.shard===e.id}).sort((e,t)=>e.ts<t.ts?1:-1).slice(0,r).map(e=>{var t,r,n,a,l;let s=null!=(t=e.data)?t:{};return{ts:e.ts,kind:(null!=(r=A(s.kind))?r:"PLAN").toUpperCase(),what:null!=(n=A(s.what))?n:"(판단)",why:null!=(l=null!=(a=A(s.reason))?a:A(s.why))?l:A(s.purpose),target:A(s.target)}})}(e,h,2);return(0,n.jsxs)("div",{className:"flex min-h-0 flex-col overflow-hidden rounded border border-zinc-800","data-pty-wall-pane":e.id,children:[(0,n.jsxs)("div",{className:"flex items-center gap-2 bg-zinc-900 px-2 py-1 text-[11px]",children:[(0,n.jsx)("span",{className:"rounded bg-violet-900/50 px-1.5 py-0.5 text-violet-200","data-pty-agent":!0,children:function(e){let t=e.externalToolName&&z[e.externalToolName]||e.kind&&z[e.kind]||e.externalToolName||e.kind||"PTY";return"에이전트: ".concat(t).concat(e.runId?" \xb7 런 ".concat(e.runId.replace(/^run-/,"").slice(0,8)):"")}(e)}),(0,n.jsx)("span",{className:"truncate font-mono text-zinc-500",children:e.id})]}),(0,n.jsx)("div",{className:"min-h-[38px] border-b border-zinc-800 bg-zinc-950/80 px-2 py-1 ".concat(o?"text-sm":"text-[11px]"),"aria-label":"의도 띠","data-pty-intent":!0,children:0===l.length?(0,n.jsx)("span",{className:"text-zinc-500",children:"이 PTY 를 모는 판단 신호 없음(사람이 모는 PTY 거나 MAX 계측 꺼짐)"}):l.map(e=>{var t;return(0,n.jsxs)("div",{className:"truncate",children:[(0,n.jsx)("span",{className:"font-mono ".concat(null!=(t=P[e.kind])?t:"text-zinc-300"),children:e.kind})," ",(0,n.jsx)("span",{className:"text-zinc-100",children:e.what}),e.why&&(0,n.jsxs)("span",{className:"text-zinc-400",children:[" \xb7 왜: ",e.why]}),e.target&&(0,n.jsxs)("span",{className:"text-zinc-500",children:[" → ",e.target]})]},"".concat(e.ts,"-").concat(e.what))})}),(0,n.jsx)("div",{className:"min-h-0 flex-1",children:(0,n.jsx)(E,{terminal:e,client:r,onClose:()=>b(e.id)})})]},"".concat(null!=(a=null==(t=e.sourceRoot)?void 0:t.dbPath)?a:"",":").concat(e.id))})})]})}var D=r(30913);let U=/\x1b(?:\][^\x07\x1b]*(?:\x07|\x1b\\)|\[[0-?]*[ -/]*[@-~]|[@-Z\\-_])/g,L=new Map;function $(e){let{sessionId:t}=e,{client:r,setSessionId:l}=(0,u.Q)(),[s,o]=(0,a.useState)(L),[i,c]=(0,a.useState)(null);(0,a.useEffect)(()=>{let e=r.connectAcp({...t?{sessionId:t}:{},onSession:e=>{e&&e!==t&&l(e)}});(0,m.cY)("tui-mirror.attach",{sessionId:t});let n=e.on("sessionUpdate",e=>{var t,r;let n=(null!=(r=e.params)?r:{}).update;if(!n||"agent_thought_chunk"!==n.sessionUpdate)return;let a=(null==(t=n.content)?void 0:t.type)==="text"?n.content.text:null;a&&o(e=>{let t=function(e,t){let r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:Date.now(),n=p(t);if(!n||"terminalFrame"!==n.method)return e;let{terminalId:a,frame:l,instance:s,at:o}=n.payload,i="".concat(s).concat("\0").concat(a),c=e.get(i);if(c&&o<c.at)return e;let d=new Map(e);return d.set(i,{key:i,surfaceId:a,frame:l,instance:s,at:o,receivedAt:r}),d}(e,a);return t!==e&&(0,m.cY)("tui-mirror.frame",{bytes:a.length}),t})}),a=setInterval(()=>{o(e=>(function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:Date.now(),r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:15e3,n=!1;for(let a of e.values())if(t-a.receivedAt>r){n=!0;break}if(!n)return e;let a=new Map;for(let[n,l]of e)t-l.receivedAt<=r&&a.set(n,l);return a})(e))},5e3);return()=>{clearInterval(a);try{n()}catch(e){}try{e.close()}catch(e){}}},[r,t,l]);let d=(0,a.useMemo)(()=>[...s.values()].sort((e,t)=>t.receivedAt-e.receivedAt||e.key.localeCompare(t.key)),[s]);(0,a.useEffect)(()=>{var e,t;i&&s.has(i)||c(null!=(t=null==(e=d[0])?void 0:e.key)?t:null)},[d,i,s]);let h=i?s.get(i):void 0;return(0,n.jsxs)("div",{className:"flex h-full min-h-0 flex-col bg-zinc-950 text-zinc-100",children:[(0,n.jsxs)("div",{className:"flex flex-wrap items-center gap-2 border-b border-zinc-800 px-3 py-2 text-xs text-zinc-400",children:[(0,n.jsx)("span",{className:"font-semibold text-zinc-200",children:"\uD83D\uDDA5 TUI 관측"}),(0,n.jsx)("span",{"aria-live":"polite",children:0===d.length?"자기신고 화면 대기 중…":"".concat(d.length,"개 화면 \xb7 라이브 미러")}),d.length>0&&(0,n.jsx)("select",{"aria-label":"관측할 TUI 화면 선택",className:"ml-auto rounded border border-zinc-700 bg-zinc-900 px-2 py-1 text-zinc-100",value:null!=i?i:"",onChange:e=>c(e.target.value),children:d.map(e=>(0,n.jsxs)("option",{value:e.key,children:[e.surfaceId," \xb7 ",e.instance]},e.key))})]}),(0,n.jsx)("pre",{className:"m-0 min-h-0 flex-1 overflow-auto whitespace-pre p-3 font-mono text-xs leading-snug text-zinc-100","aria-live":"polite","aria-label":"선택한 TUI 화면의 라이브 렌더 프레임",children:h?h.frame.replace(U,""):"자기신고하는 elanous 화면이 아직 없습니다. 대시보드(elanous)를 실행하면 여기 라이브로 미러링됩니다."})]})}var O=r(73139),F=r(82823),B=r(82157),Q=r(9290),q=r(31113),H=r(73313);function _(e){let{onFrameUploaded:t}=e,{config:r,client:l,sessionId:s}=(0,u.Q)(),o=(0,a.useRef)(null);(0,a.useEffect)(()=>()=>{try{var e;null==(e=o.current)||e.close()}catch(e){}o.current=null},[]);let i=(0,a.useCallback)(async e=>{if(t){try{t(e)}catch(e){}return}if(s){o.current||(o.current=l.connectAcp({sessionId:s}));try{var r;await o.current.send("terminal/camera/frame/notify",{sessionId:s,attachmentId:e.id,ts:null!=(r=e.createdAt)?r:Date.now()})}catch(e){(0,m.cY)("webterm.live-cam.notify-failed",{reason:e instanceof Error?e.message:String(e)})}}},[l,s,t]),c=function(e){var t,r,n;let l=null!=(t=e.intervalMs)?t:1e3,s=null!=(r=e.jpegQuality)?r:.85,o=null!=(n=e.maxDimension)?n:1280,[i,c]=(0,a.useState)({status:"idle",framesUploaded:0,lastAttachmentId:null,error:null}),d=(0,a.useRef)(null),u=(0,a.useRef)(null),p=(0,a.useRef)(null),h=(0,a.useRef)(null),f=(0,a.useRef)(!1),b=(0,a.useRef)(e.onFrameUploaded);b.current=e.onFrameUploaded;let g=(0,a.useRef)({baseUrl:e.baseUrl,token:e.token});g.current={baseUrl:e.baseUrl,token:e.token};let x=(0,a.useCallback)(()=>{null!==h.current&&(clearInterval(h.current),h.current=null);let e=d.current;if(e){for(let t of e.getTracks())try{t.stop()}catch(e){}d.current=null}if(u.current){try{u.current.pause()}catch(e){}u.current.srcObject=null,u.current=null}p.current=null,f.current=!1},[]),v=(0,a.useCallback)(async()=>{if(f.current)return void(0,m.cY)("webterm.live-cam.frame-dropped",{reason:"in-flight"});let e=u.current;if(!e||0===e.videoWidth||0===e.videoHeight)return void(0,m.cY)("webterm.live-cam.frame-skipped",{reason:"video-not-ready"});f.current=!0;try{let r=function(e,t,r){if(e<=r&&t<=r)return{width:e,height:t};let n=e/t;return e>=t?{width:r,height:Math.round(r/n)}:{width:Math.round(r*n),height:r}}(e.videoWidth,e.videoHeight,o),n=p.current;n&&n.width===r.width&&n.height===r.height||(p.current=n=function(e,t){let r=document.createElement("canvas");return r.width=e,r.height=t,r}(r.width,r.height));let a=n.getContext("2d");if(!a)return void(0,m.cY)("webterm.live-cam.no-ctx");a.drawImage(e,0,0,r.width,r.height);let l=await new Promise(e=>{n.toBlob(t=>e(t),"image/jpeg",s)});if(!l)return void(0,m.cY)("webterm.live-cam.toBlob-null");let i="live-frame-".concat(Date.now(),".jpg"),d=await (0,H.v)({baseUrl:g.current.baseUrl,token:g.current.token,file:l,filename:i});if(!d.ok){c(e=>({...e,error:d.reason})),(0,m.cY)("webterm.live-cam.upload-failed",{reason:d.reason});return}c(e=>({...e,framesUploaded:e.framesUploaded+1,lastAttachmentId:d.meta.id,error:null}));try{var t;null==(t=b.current)||t.call(b,d.meta)}catch(e){(0,m.cY)("webterm.live-cam.onFrameUploaded-throw",{reason:e instanceof Error?e.message:String(e)})}}catch(t){let e=t instanceof Error?t.message:String(t);c(t=>({...t,error:e})),(0,m.cY)("webterm.live-cam.capture-error",{reason:e})}finally{f.current=!1}},[s,o]),w=(0,a.useCallback)(async()=>{var e;let t;if("undefined"==typeof navigator||!(null==(e=navigator.mediaDevices)?void 0:e.getUserMedia))return void c(e=>({...e,status:"unsupported",error:"getUserMedia not available"}));if(!g.current.baseUrl)return void c(e=>({...e,status:"error",error:"daemon baseUrl not configured"}));if(d.current)return;c(e=>({...e,status:"requesting",error:null}));try{t=await navigator.mediaDevices.getUserMedia({video:{facingMode:{ideal:"environment"}}})}catch(r){let e=r instanceof Error?r.message:String(r),t=e.includes("Permission")||e.includes("NotAllowed");c(r=>({...r,status:t?"denied":"error",error:e})),(0,m.cY)("webterm.live-cam.getUserMedia-failed",{reason:e,denied:t});return}d.current=t;let r=document.createElement("video");r.srcObject=t,r.muted=!0,r.playsInline=!0,u.current=r;try{await r.play()}catch(e){(0,m.cY)("webterm.live-cam.video-play-failed",{reason:e instanceof Error?e.message:String(e)})}c(e=>({...e,status:"streaming",framesUploaded:0,error:null})),null!==h.current&&clearInterval(h.current),h.current=setInterval(()=>{v()},l),(0,m.cY)("webterm.live-cam.started",{intervalMs:l})},[v,l]),y=(0,a.useCallback)(()=>{x(),c({status:"idle",framesUploaded:0,lastAttachmentId:null,error:null}),(0,m.cY)("webterm.live-cam.stopped")},[x]);return(0,a.useEffect)(()=>()=>{x()},[x]),{...i,start:w,stop:y,isRunning:"streaming"===i.status}}({baseUrl:r.baseUrl,...r.token?{token:r.token}:{},onFrameUploaded:i});return"unsupported"!==c.status&&r.baseUrl?"denied"===c.status?(0,n.jsx)("button",{type:"button",disabled:!0,className:"rounded border border-rose-300 bg-rose-50 px-2 py-0.5 text-[11px] text-rose-700 dark:border-rose-800 dark:bg-rose-950 dark:text-rose-200",title:"Camera permission denied. Enable in iOS Settings → Safari → Camera, then reload.","data-testid":"live-camera-denied",children:"Camera denied"}):c.isRunning?(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)("button",{type:"button",onClick:()=>c.stop(),className:"rounded border border-rose-300 bg-rose-50 px-2 py-0.5 text-rose-700 dark:border-rose-800 dark:bg-rose-950 dark:text-rose-200 hover:bg-rose-100 dark:hover:bg-rose-900",title:"Stop live camera","data-testid":"live-camera-stop",children:"■ Stop"}),(0,n.jsxs)("span",{className:"rounded border border-border bg-card px-1.5 py-0.5 font-mono text-[10px] text-muted-foreground","data-testid":"live-camera-stats","aria-live":"polite",children:[c.framesUploaded,"f",c.error?(0,n.jsx)("span",{className:"ml-1 text-rose-500",children:"err"}):null]})]}):(0,n.jsx)("button",{type:"button",disabled:"requesting"===c.status,onClick:()=>{c.start()},className:"rounded border px-2 py-0.5 hover:bg-accent disabled:opacity-50",title:"Start live camera — uploads a 1Hz frame stream so the agent can see what you point at","data-testid":"live-camera-start",children:"requesting"===c.status?"Requesting…":"\uD83D\uDCF9 Live"}):null}function V(e){let{terminalId:t,onClear:r,onRecordingChange:l,onAttached:s,voice:o}=e,{client:i,sessionId:c,config:d}=(0,u.Q)(),[p,h]=(0,a.useState)(null),[f,b]=(0,a.useState)(null),[g,x]=(0,a.useState)(!1),[v,w]=(0,a.useState)(null);(0,a.useEffect)(()=>{null==l||l(null!==p)},[p,l]);let y=(0,a.useRef)(null);(0,a.useEffect)(()=>()=>{try{var e;null==(e=y.current)||e.close()}catch(e){}y.current=null},[]),(0,a.useEffect)(()=>{if(!c)return;y.current||(y.current=i.connectAcp({sessionId:c}));let e=y.current,r=!1;return(async()=>{try{var n;let a=await e.send("terminal/record/list",{sessionId:c});if(r)return;let l=null==a||null==(n=a.recordings)?void 0:n.find(e=>e.terminalId===t);l?h({recorderId:l.recorderId,startedAt:l.startedAt}):h(null),b(null),w(null)}catch(e){(0,m.cY)("webterm.controls.list-error",{reason:String(e)})}})(),()=>{r=!0}},[i,c,t]);let k=(0,a.useCallback)(async()=>{if(!c)return void w("session 미설정 — daemon 연결을 먼저 확인하세요");y.current||(y.current=i.connectAcp({sessionId:c}));let e=y.current;x(!0),w(null),b(null);try{var r,n;let a=await e.send("terminal/record/start",{sessionId:c,terminalId:t});(null==a?void 0:a.started)&&a.recorderId?((0,m.cY)("webterm.controls.record.started",{recorderId:a.recorderId,terminalId:t}),h({recorderId:a.recorderId,startedAt:null!=(r=a.startedAt)?r:Date.now()})):w(null!=(n=null==a?void 0:a.reason)?n:"start failed")}catch(e){w(String(e instanceof Error?e.message:e))}finally{x(!1)}},[i,c,t]),j=(0,a.useCallback)(async()=>{var e,r,n,a;if(!c||!p)return;let l=null!=(e=y.current)?e:i.connectAcp({sessionId:c});y.current=l,x(!0),w(null);try{let e=await l.send("terminal/record/stop",{sessionId:c,terminalId:t});(null==e?void 0:e.stopped)&&e.recorderId&&e.downloadUrl?((0,m.cY)("webterm.controls.record.stopped",{recorderId:e.recorderId,frameCount:e.frameCount,elapsedSec:e.elapsedSec}),b({recorderId:e.recorderId,downloadUrl:e.downloadUrl,frameCount:null!=(r=e.frameCount)?r:0,elapsedSec:null!=(n=e.elapsedSec)?n:0}),h(null)):w(null!=(a=null==e?void 0:e.reason)?a:"stop failed")}catch(e){w(String(e instanceof Error?e.message:e))}finally{x(!1)}},[p,i,c,t]);return(0,n.jsxs)("div",{className:"flex flex-wrap items-center gap-2 border-b px-2 py-1 text-xs",children:[(0,n.jsx)("button",{type:"button",className:"rounded border px-2 py-0.5 hover:bg-accent",onClick:()=>{(0,m.cY)("webterm.controls.clear"),r()},children:"clear"}),(0,n.jsx)(Q.T,{onAttached:s?e=>s([e]):void 0}),(0,n.jsx)(q.u,{onAttached:s}),(0,n.jsx)(_,{}),o&&(0,n.jsxs)("button",{type:"button",onClick:o.onToggle,disabled:o.disabled,title:o.disabled?"마이크 사용 불가 (insecure context 등)":"".concat(o.phaseLabel," \xb7 xterm 으로 typing"),"data-elanous-action":"webterm-voice-toggle-controls","aria-pressed":o.active,className:(0,B.cn)("inline-flex items-center gap-1 rounded border px-2 py-0.5",o.active?"border-rose-300 bg-rose-100 text-rose-800 dark:border-rose-700 dark:bg-rose-950/40 dark:text-rose-100":"hover:bg-accent",o.disabled&&"cursor-not-allowed opacity-50"),children:[(0,n.jsx)("span",{className:(0,B.cn)("h-1.5 w-1.5 rounded-full",o.dotColor,("listening"===o.phase||"speaking"===o.phase)&&"animate-pulse"),"aria-hidden":"true"}),o.active?(0,n.jsx)(O.A,{className:"h-3.5 w-3.5"}):(0,n.jsx)(F.A,{className:"h-3.5 w-3.5"}),(0,n.jsx)("span",{children:"voice→stdin"})]}),!p&&!f&&(0,n.jsx)("button",{type:"button",disabled:g,className:"rounded border px-2 py-0.5 ".concat(g?"opacity-50":"hover:bg-accent"," text-rose-600 dark:text-rose-400"),onClick:()=>void k(),title:"start asciicast recording",children:"● record"}),p&&(0,n.jsx)("button",{type:"button",disabled:g,className:"rounded border px-2 py-0.5 ".concat(g?"opacity-50":"hover:bg-accent"," bg-rose-600 text-white animate-pulse"),onClick:()=>void j(),title:"stop + save .cast",children:"■ stop"}),f&&(0,n.jsx)("a",{href:(e=>{var t;if(!e)return"";let r=null!=(t=d.baseUrl)?t:"",n=e.includes("?")?"&":"?",a=d.token?"".concat(n,"auth=").concat(encodeURIComponent(d.token)):"";return"".concat(r).concat(e).concat(a)})(f.downloadUrl),download:"".concat(f.recorderId,".cast"),className:"rounded border border-emerald-500 px-2 py-0.5 text-emerald-600 hover:bg-emerald-50 dark:hover:bg-emerald-950",onClick:()=>(0,m.cY)("webterm.controls.download.click",{recorderId:f.recorderId}),title:"".concat(f.frameCount," frames \xb7 ").concat(f.elapsedSec.toFixed(1),"s"),children:"⬇ download .cast"}),f&&(0,n.jsx)("button",{type:"button",className:"rounded border px-2 py-0.5 text-muted-foreground hover:bg-accent",onClick:()=>b(null),title:"dismiss","aria-label":"dismiss download",children:"\xd7"}),(p||f)&&(0,n.jsxs)("span",{className:"ml-auto text-[11px] text-muted-foreground",children:[p&&"● recording",f&&!p&&"✓ ".concat(f.recorderId)]}),v&&(0,n.jsx)("span",{className:"ml-2 max-w-[40%] truncate text-[11px] text-rose-500",title:v,children:v})]})}let G={ctrl:!1,alt:!1},J={up:"A",down:"B",right:"C",left:"D"},K=[{key:"esc",label:"Esc",width:"wide",title:"Escape (vim normal mode)"},{key:"tab",label:"Tab",width:"wide",title:"Tab (autocomplete)"},{key:"left",label:"←",width:"narrow",title:"Left arrow"},{key:"down",label:"↓",width:"narrow",title:"Down arrow"},{key:"up",label:"↑",width:"narrow",title:"Up arrow"},{key:"right",label:"→",width:"narrow",title:"Right arrow"}];function W(e){let{terminalId:t}=e,{sessionId:r}=(0,u.Q)(),[l,s]=(0,a.useState)(!1),[o,i]=(0,a.useState)(!1),c=(0,a.useRef)(!1),d=(0,a.useRef)(!1);c.current=l,d.current=o;let p=(0,a.useRef)(null),h=(0,a.useCallback)((e,t)=>{null!==p.current&&(clearTimeout(p.current),p.current=null),(e||t)&&(p.current=setTimeout(()=>{s(!1),i(!1),p.current=null,(0,m.cY)("webterm.modbar.auto-release",{})},5e3))},[]);(0,a.useEffect)(()=>()=>{null!==p.current&&(clearTimeout(p.current),p.current=null)},[]);let f=(0,a.useCallback)(e=>{if(!r)return void(0,m.cY)("webterm.modbar.no-session",{key:e});let n={ctrl:c.current,alt:d.current},a=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:G;switch(e){case"esc":return t.alt?"\x1b\x1b":"\x1b";case"tab":return t.alt?"\x1b ":" ";case"up":case"down":case"left":case"right":{let r=J[e],n=function(e){if(!e.ctrl&&!e.alt)return null;let t=0;return e.alt&&(t+=2),e.ctrl&&(t+=4),1+t}(t);return null===n?"\x1b[".concat(r):"\x1b[1;".concat(n).concat(r)}}}(e,n);(0,m.cY)("webterm.modbar.send",{key:e,ctrl:n.ctrl,alt:n.alt,bytes:a.length});try{N(t,a)}catch(e){(0,m.cY)("webterm.modbar.send-error",{reason:String(e)})}(n.ctrl||n.alt)&&(s(!1),i(!1),h(!1,!1))},[r,t,h]),b=(0,a.useCallback)(()=>{let e=!c.current;s(e),h(e,d.current)},[h]),g=(0,a.useCallback)(()=>{let e=!d.current;i(e),h(c.current,e)},[h]),x=e=>["flex h-7 items-center justify-center rounded border font-mono text-[11px] px-2 min-w-[36px] active:translate-y-px disabled:opacity-50 transition-colors",e?"border-amber-400 bg-amber-100 text-amber-900 dark:border-amber-500 dark:bg-amber-900 dark:text-amber-100":"border-border bg-card text-muted-foreground hover:bg-muted hover:border-primary hover:text-foreground"].join(" ");return(0,n.jsxs)("div",{className:"flex flex-wrap items-center gap-1 border-b border-border bg-background/60 px-2 py-1","data-testid":"modifier-bar",role:"toolbar","aria-label":"Mobile keyboard modifiers",children:[K.map(e=>(0,n.jsx)("button",{type:"button",className:["flex h-7 items-center justify-center rounded border border-border bg-card font-mono text-[11px] text-muted-foreground hover:bg-muted hover:border-primary hover:text-foreground active:translate-y-px disabled:opacity-50","wide"===e.width?"px-2 min-w-[36px]":"w-8"].join(" "),onClick:()=>{f(e.key)},disabled:!r,"aria-label":e.title,title:e.title,"data-testid":"modbar-".concat(e.key),children:e.label},e.key)),(0,n.jsx)("span",{className:"mx-1 text-[10px] text-muted-foreground/60","aria-hidden":!0,children:"\xb7"}),(0,n.jsx)("button",{type:"button",className:x(l),onClick:b,disabled:!r,"aria-label":"Ctrl modifier ".concat(l?"active":"idle"),"aria-pressed":l,title:"Ctrl modifier — toggles. Combines with arrow keys (e.g. Ctrl+→ = next word). Auto-releases after 5s or one keystroke.","data-testid":"modbar-ctrl",children:"Ctrl"}),(0,n.jsx)("button",{type:"button",className:x(o),onClick:g,disabled:!r,"aria-label":"Alt modifier ".concat(o?"active":"idle"),"aria-pressed":o,title:"Alt modifier — toggles. Combines with Esc/Tab/arrows. Auto-releases after 5s or one keystroke.","data-testid":"modbar-alt",children:"Alt"})]})}var Z=r(31014);function X(e){let{foreignActivityTick:t,onPeerCountChange:r}=e,{client:l,sessionId:s}=(0,u.Q)(),[o,i]=(0,a.useState)(0),[c,d]=(0,a.useState)(!1);(0,a.useEffect)(()=>{null==r||r(o)},[o,r]);let p=(0,a.useRef)(null),h=(0,a.useRef)(null),f=(0,a.useCallback)(async()=>{if(!s)return;p.current||(p.current=l.connectAcp({sessionId:s}));let e=p.current;try{let t=await e.send("terminal/peers/count",{sessionId:s});"number"==typeof(null==t?void 0:t.count)&&(i(t.count),(0,m.cY)("webterm.peers.count",{count:t.count}))}catch(e){(0,m.cY)("webterm.peers.count.error",{reason:String(e)})}},[l,s]);return((0,a.useEffect)(()=>{f();let e=()=>{"visible"===document.visibilityState&&f()};return document.addEventListener("visibilitychange",e),()=>{document.removeEventListener("visibilitychange",e)}},[f]),(0,a.useEffect)(()=>()=>{try{var e;null==(e=p.current)||e.close()}catch(e){}p.current=null,h.current&&clearTimeout(h.current)},[]),(0,a.useEffect)(()=>{t&&(d(!0),h.current&&clearTimeout(h.current),h.current=setTimeout(()=>{d(!1),h.current=null,f()},1800))},[t,f]),o<=1&&!c)?null:(0,n.jsxs)("div",{className:"flex items-center gap-2 border-b border-border bg-amber-500/10 px-2 py-0.5 text-[11px]",children:[(0,n.jsx)(Z.A,{className:"h-3 w-3 text-amber-600","aria-hidden":!0}),o>1&&(0,n.jsxs)("span",{className:"font-mono text-amber-700 dark:text-amber-400",children:[o," devices"]}),c&&(0,n.jsx)("span",{className:"ml-auto rounded bg-amber-500 px-1.5 py-0.5 font-medium text-white animate-pulse",children:"\uD83D\uDC64 typing"})]})}var ee=r(47963);function et(e){let{onAttached:t,pageWide:r=!0}=e,{config:s}=(0,u.Q)(),[o,i]=(0,a.useState)(!1),[c,d]=(0,a.useState)(!1),p=(0,a.useRef)(0),h=(0,a.useCallback)(async e=>{if(0!==e.length){if(!s.baseUrl)return void l.oR.error("Daemon URL 미설정 — Settings 에서 입력");d(!0),(0,m.cY)("webterm.dropzone.drop",{count:e.length,totalBytes:e.reduce((e,t)=>e+t.size,0)});try{let r=await (0,H.K)(e.map(e=>({file:e,filename:e.name})),{baseUrl:s.baseUrl,...s.token?{token:s.token}:{}}),n=r.filter(e=>e.ok),a=r.filter(e=>!e.ok);n.length>0&&(l.oR.success(1===n.length?"\uD83D\uDCCE ".concat(n[0].meta.filename):"\uD83D\uDCCE ".concat(n.length," files dropped")),null==t||t(n.map(e=>e.meta))),a.length>0&&l.oR.error(1===a.length?"드롭 실패: ".concat(a[0].reason.slice(0,80)):"".concat(a.length," 파일 드롭 실패"))}finally{d(!1)}}},[s.baseUrl,s.token,t]);return((0,a.useEffect)(()=>{if(!r)return;let e=e=>{e.dataTransfer&&e.dataTransfer.types.includes("Files")&&(e.preventDefault(),p.current+=1,i(!0))},t=e=>{e.dataTransfer&&e.dataTransfer.types.includes("Files")&&e.preventDefault()},n=e=>{e.dataTransfer&&e.dataTransfer.types.includes("Files")&&(e.preventDefault(),p.current=Math.max(0,p.current-1),0===p.current&&i(!1))},a=e=>{if(!e.dataTransfer)return;let t=e.dataTransfer.files;t&&0!==t.length&&(e.preventDefault(),p.current=0,i(!1),h(Array.from(t)))};return document.addEventListener("dragenter",e),document.addEventListener("dragover",t),document.addEventListener("dragleave",n),document.addEventListener("drop",a),()=>{document.removeEventListener("dragenter",e),document.removeEventListener("dragover",t),document.removeEventListener("dragleave",n),document.removeEventListener("drop",a)}},[h,r]),o||c)?(0,n.jsx)("div",{className:"pointer-events-none fixed inset-0 z-50 flex items-center justify-center bg-primary/20 backdrop-blur-sm",children:(0,n.jsxs)("div",{className:"rounded-xl border-2 border-dashed border-primary bg-card px-6 py-4 text-center shadow-lg",children:[(0,n.jsx)(ee.A,{className:"mx-auto h-10 w-10 text-primary","aria-hidden":!0}),(0,n.jsx)("div",{className:"mt-2 text-sm font-medium text-foreground",children:c?"업로드 중…":"Drop files to attach"}),(0,n.jsx)("div",{className:"mt-1 text-xs text-muted-foreground",children:c?"":"iCloud \xb7 Files.app \xb7 폴더 모두 지원"})]})}):null}var er=r(82356),en=r(330),ea=r(41657),el=r(8979),es=r(9189),eo=r(10793),ei=r(50940),ec=r(92646),ed=r(19206),eu=r(38869),em=r(68355),ep=r(25194),eh=r(72030),ef=r(45977),eb=r(56594);async function eg(e,t){if(!t||0===t.length)return null;try{let r=await e.fetchJson("/v1/sessions/store/".concat(encodeURIComponent(t),"?ifExists=1"));if(!r||!Array.isArray(r.messages))return null;let n=function(e){let t=[];return e.forEach((e,r)=>{let n=function(e,t){let r=e.role;if("tool"===r)return{...(0,eb.$Q)("\uD83D\uDEE0️ ".concat(e.toolName||"tool")),id:"hydrate-t-".concat(t)};let n=function(e){if("string"==typeof e)return e;if(!Array.isArray(e))return"";let t=[];for(let n of e)if(n&&"object"==typeof n){let e=n.type;if("text"===e&&"string"==typeof n.text)t.push(n.text);else if("image"===e)t.push("\uD83D\uDCCE image");else if("audio"===e)t.push("\uD83D\uDCCE audio");else if("tool_use"===e){var r;let e=null!=(r=n.name)?r:"tool";t.push("\uD83D\uDEE0️ ".concat(e))}else"tool_result"===e&&t.push("\uD83D\uDEE0️ result")}return t.join("\n").trim()}(e.content);return 0===n.length?null:"user"===r?{...(0,eb.tw)(n),id:"hydrate-u-".concat(t)}:"assistant"===r?{id:"hydrate-a-".concat(t),role:"assistant",text:n,timestamp:Date.now(),meta:{provider:"history"}}:"system"===r?null:{...(0,eb.$Q)(n),id:"hydrate-m-".concat(t)}}(e,r);n&&t.push(n)}),t.slice(-200)}(r.messages);return(0,m.cY)("webterm.terminal-chat.hydrate.ok",{sessionId:t,serverCount:r.messages.length,mappedCount:n.length}),n}catch(e){return(0,m.cY)("webterm.terminal-chat.hydrate.skip",{sessionId:t,reason:e instanceof Error?e.message:String(e)}),null}}let ex=[":cwd",":capture",":peers",":tab next",":tab prev"];function ev(e){let t=(null!=e?e:"").replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g,"").replace(/\r/g,"").trim();return t.length>0?t:"(no output)"}let ew=(0,a.forwardRef)(function(e,t){let{terminalId:r,open:s,onTabIntent:o,height:i,voice:c}=e,d="number"==typeof i&&Number.isFinite(i)&&i>0?i:void 0,{client:p,config:h,sessionId:f,setSessionId:b}=(0,u.Q)(),g=(0,a.useRef)(f),x=(0,a.useRef)(null),[v,w]=(0,a.useState)([]),[y,k]=(0,a.useState)(!1),[j,N]=(0,a.useState)(null),[S,I]=(0,a.useState)([]),[C,T]=(0,a.useState)(!1),Y=(0,a.useRef)(async()=>{}),E=(0,a.useRef)(!1);E.current=y;let R=(0,a.useRef)(null),[A,z]=(0,a.useState)(!1),P=(0,ef.$)({enabled:!!(null==c?void 0:c.active)&&!A,language:"ko-KR"}),M=(0,a.useRef)(P);M.current=P,(0,a.useEffect)(()=>{g.current=f},[f]),(0,a.useEffect)(()=>{try{var e;null==(e=x.current)||e.close()}catch(e){}if(x.current=null,s&&f)return x.current=p.connectAcp({sessionId:f}),()=>{try{var e;null==(e=x.current)||e.close()}catch(e){}x.current=null}},[p,s,f]),(0,a.useEffect)(()=>{let e=x.current;if(e&&s&&f)return e.on("sessionUpdate",e=>{var t;let r=R.current;if(!r)return;let n=e.params;if(!n||n.sessionId!==f)return;let a=n.update;if(a&&"agent_message_chunk"===a.sessionUpdate&&(null==(t=a.content)?void 0:t.type)==="text"&&"string"==typeof a.content.text){let e=a.content.text;if(0===e.length)return;w(t=>t.map(t=>{var n;return t.id===r?{...t,text:(null!=(n=t.text)?n:"")+e}:t})),M.current.pushText(e)}})},[s,f]);let D=(0,a.useRef)(null);(0,a.useEffect)(()=>{if(!s||!f||D.current===f)return;D.current=f;let e=!1;return(async()=>{let t=await eg(p,f);e||null===t||w(t)})(),()=>{e=!0}},[p,s,f]);let U=(0,a.useCallback)(e=>{w(t=>[...t,e].slice(-200))},[]);(0,a.useImperativeHandle)(t,()=>({submitVoiceTranscript:e=>{let t=e.trim();if(t){if(E.current)return void(0,m.cY)("webterm.terminal-chat.voice.skip-pending",{len:t.length});(0,m.cY)("webterm.terminal-chat.voice.auto-send",{len:t.length}),Y.current(t)}}}),[]);let L=(0,a.useCallback)(()=>{let e=g.current;return e?(x.current||(x.current=p.connectAcp({sessionId:e})),x.current):null},[p]),$=(0,a.useMemo)(()=>({client:p,sessionId:f,provider:h.provider,setSessionId:b,daemon:{baseUrl:h.baseUrl,...h.token?{token:h.token}:{}},messages:v}),[p,h.baseUrl,h.provider,h.token,v,f,b]),Q=(0,a.useCallback)(e=>{I(t=>[...t,...e]),(0,m.cY)("webterm.terminal-chat.attach.queue",{terminalId:r,added:e.length,filenames:e.map(e=>e.filename)})},[r]),q=(0,a.useCallback)(e=>{I(t=>t.filter(t=>t.id!==e))},[]),H=(0,a.useCallback)(async e=>{let t=e.startsWith(":")?null:await (0,eb.yN)(e,$);if(t){"__CLEAR__"===t.text?w([]):U((0,eb.$Q)(t.text,r)),t.newSessionId&&b(t.newSessionId);return}if(!f)return void U((0,eb.$Q)("session 미설정",r));let n=L();if(!n)return void U((0,eb.$Q)("session 미설정",r));let a=await n.send("terminal/repl/exec",{sessionId:f,terminalId:r,line:e});U((0,eb.$Q)(ev(null==a?void 0:a.output),r)),(null==a?void 0:a.sessionIdChange)&&b(a.sessionIdChange),(null==a?void 0:a.tabIntent)!==void 0&&(null==o||o(a.tabIntent),U((0,eb.$Q)("tab intent → ".concat(String(a.tabIntent)),r))),(null==a?void 0:a.injectPath)&&U((0,eb.$Q)("captured → ".concat(a.injectPath),r)),(null==a?void 0:a.agentChatModeEnter)&&U((0,eb.$Q)("agent chat mode hint — terminal dock already runs plain text as agent turns",r))},[U,$,L,o,f,b,r]),_=(0,a.useCallback)(async()=>{let e=g.current;if(e&&j)try{var t;let n=L();if(!n)return;let a=await n.send("terminal/repl/agent/abort",{sessionId:e,terminalId:r});(0,m.cY)("webterm.terminal-chat.abort",{terminalId:r,aborted:null!=(t=null==a?void 0:a.aborted)&&t}),U((0,eb.$Q)((null==a?void 0:a.aborted)?"agent turn aborted":"no active agent turn to abort",r))}catch(t){let e=t instanceof Error?t.message:String(t);U((0,eb.$Q)("abort failed: ".concat(e),r))}finally{k(!1),N(null)}},[U,L,j,r]),V=(0,a.useCallback)(async e=>{I([]);let t=S.filter(e=>!("string"==typeof e.path&&e.path.length>0)).length;if(t>0){let e=1===t?"첨부 1건이 path 누락으로 누락됐습니다":"첨부 ".concat(t,"건이 path 누락으로 누락됐습니다");l.oR.warning(e),U((0,eb.$Q)("⚠ ".concat(e),r)),(0,m.cY)("webterm.terminal-chat.attach.dropped",{terminalId:r,droppedCount:t,totalCount:S.length})}e.length>0&&U((0,eb.tw)(e,r)),S.length>0&&U((0,eb.$Q)("\uD83D\uDCCE attached: ".concat(S.map(e=>e.filename).join(", ")),r));let n=e.trim();if(n||0!==S.length){k(!0);try{if((0,eb.FM)(n))return void await H(n);if(!f)return void U((0,eb.$Q)("session 미설정",r));let e=L();if(!e)return void U((0,eb.$Q)("session 미설정",r));N(n);let t="assistant-".concat(Date.now(),"-").concat(Math.random().toString(36).slice(2,6));R.current=t,U({id:t,role:"assistant",text:"",timestamp:Date.now(),terminalId:r}),(0,m.cY)("webterm.terminal-chat.turn.start",{terminalId:r,sessionId:f,len:n.length,attachCount:S.length,placeholderId:t});let a=S.filter(e=>e.path).map(e=>"[attached] ".concat(e.path)),l=a.length>0?"".concat(a.join("\n"),"\n\n").concat(n).trimEnd():n,s=await e.send("terminal/repl/exec",{sessionId:f,terminalId:r,line:":agent ".concat(l)});(null==s?void 0:s.agent)?(w(e=>e.map(e=>e.id===t?{...e,text:e.text&&e.text.length>=s.agent.markdown.length?e.text:s.agent.markdown,meta:{provider:s.agent.modelLabel,stopReason:s.agent.stopReason}}:e)),M.current.flush()):(w(e=>e.filter(e=>e.id!==t)),U((0,eb.$Q)(ev(null==s?void 0:s.output),r))),(0,m.cY)("webterm.terminal-chat.turn.end",{terminalId:r,hasAgent:!!(null==s?void 0:s.agent)})}catch(n){let e=n instanceof Error?n.message:String(n),t=R.current;t&&w(e=>e.filter(e=>e.id!==t)),M.current.cancel(),U((0,eb.$Q)("error: ".concat(e),r)),l.oR.error("terminal chat failed: ".concat(e))}finally{R.current=null,k(!1),N(null)}}},[U,L,H,S,f,r]);return((0,a.useEffect)(()=>{Y.current=V},[V]),s)?(0,n.jsxs)("div",{className:"shrink-0 border-t border-border bg-background/95","data-terminal-chat-dock":!0,children:[(0,n.jsxs)("div",{className:"flex items-center gap-2 border-b border-border/80 px-3 py-2",children:[(0,n.jsxs)("div",{className:"flex min-w-0 flex-1 items-center gap-2",children:[(0,n.jsx)("span",{className:"inline-flex h-7 w-7 items-center justify-center rounded-md border border-primary/30 bg-primary/10 text-primary",children:(0,n.jsx)(en.A,{className:"h-4 w-4"})}),(0,n.jsxs)("div",{className:"min-w-0",children:[(0,n.jsx)("div",{className:"truncate text-sm font-medium",children:"Terminal Chat Dock"}),(0,n.jsxs)("div",{className:"truncate text-[11px] text-muted-foreground",children:[r," \xb7 plain text = contextual agent turn \xb7 ",(0,n.jsx)("code",{className:"rounded bg-muted px-1",children:":commands"})," stay local"]})]})]}),(0,n.jsxs)("div",{className:"flex items-center gap-2",children:[c&&(0,n.jsxs)("button",{type:"button",onClick:c.onToggle,disabled:c.disabled,title:c.disabled?"마이크 사용 불가 (insecure context 등)":c.phaseLabel,"data-elanous-action":"webterm-voice-toggle-dock","aria-pressed":c.active,className:(0,B.cn)("inline-flex h-7 items-center gap-1.5 rounded-md border px-2 text-[11px]",c.active?"border-rose-300 bg-rose-100 text-rose-800 dark:border-rose-700 dark:bg-rose-950/40 dark:text-rose-100":"border-border hover:bg-accent",c.disabled&&"cursor-not-allowed opacity-50"),children:[(0,n.jsx)("span",{className:(0,B.cn)("h-1.5 w-1.5 rounded-full",c.dotColor,("listening"===c.phase||"speaking"===c.phase)&&"animate-pulse"),"aria-hidden":"true"}),c.active?(0,n.jsx)(O.A,{className:"h-3.5 w-3.5"}):(0,n.jsx)(F.A,{className:"h-3.5 w-3.5"}),(0,n.jsx)("span",{className:"hidden sm:inline",children:c.phaseLabel})]}),c&&c.active&&P.supported&&(0,n.jsx)("button",{type:"button",onClick:()=>{A||M.current.cancel(),z(e=>!e)},title:A?"음성 응답 켜기":"음성 응답 끄기","data-elanous-action":"webterm-tts-mute-toggle","aria-pressed":A,className:(0,B.cn)("inline-flex h-7 items-center justify-center rounded-md border px-2 text-[11px]",A?"border-border bg-muted text-muted-foreground":"border-fuchsia-300 bg-fuchsia-50 text-fuchsia-800 dark:border-fuchsia-700 dark:bg-fuchsia-950/40 dark:text-fuchsia-100"),children:A?(0,n.jsx)(ea.A,{className:"h-3.5 w-3.5"}):(0,n.jsx)(el.A,{className:"h-3.5 w-3.5"})}),(0,n.jsx)(em.Qh,{}),(0,n.jsx)(er.vG,{children:(0,n.jsx)(eu.rm,{})}),(0,n.jsx)(er.vG,{children:(0,n.jsx)(ep.D,{})}),j&&(0,n.jsxs)(eh.$,{variant:"destructive",size:"sm",onClick:()=>void _(),title:"abort active terminal-context agent turn",children:[(0,n.jsx)(es.A,{className:"h-3.5 w-3.5"}),"Stop"]}),(0,n.jsxs)("div",{className:"relative",children:[(0,n.jsx)(eh.$,{variant:"outline",size:"icon-sm",onClick:()=>T(e=>!e),"aria-label":"terminal quick commands",title:"terminal quick commands",children:(0,n.jsx)(eo.A,{className:"h-3.5 w-3.5"})}),C&&(0,n.jsx)("div",{className:"absolute right-0 top-full z-40 mt-1 w-44 rounded-md border border-border bg-popover p-1 shadow-md",children:ex.map(e=>(0,n.jsx)("button",{type:"button",className:"block w-full rounded px-2 py-1 text-left font-mono text-[11px] hover:bg-accent",onClick:()=>{T(!1),V(e)},children:e},e))})]})]})]}),j&&(0,n.jsxs)("div",{className:"flex items-center gap-2 border-b border-border/70 px-3 py-2 text-[11px] text-muted-foreground",children:[(0,n.jsx)(ei.A,{className:"h-3.5 w-3.5 animate-spin"}),(0,n.jsxs)("span",{className:"truncate",children:["terminal-context agent turn in progress",j.length>0?" \xb7 ".concat(j.slice(0,120)).concat(j.length>120?"…":""):""]})]}),(0,n.jsxs)("div",{className:(0,B.cn)("grid grid-rows-[1fr_auto]",void 0===d?"h-[clamp(160px,30vh,360px)] min-h-[200px]":void 0),...void 0===d?{}:{style:{height:d}},children:[(0,n.jsx)(ec.D,{messages:v,pending:y,tabId:"dock-".concat(r)}),(0,n.jsx)(ed.V,{onSubmit:V,disabled:y,attachments:S,onAttached:Q,onRemoveAttachment:q,tabId:"dock-".concat(r),...c?{voice:c}:{}})]})]}):null});var ey=r(93981),ek=r(72754);let ej=/^100\.(6[4-9]|[7-9]\d|1[01]\d|12[0-7])\./;function eN(){if(!window.location)return{isSecure:!1,reason:"unknown",hostname:"",protocol:""};let e=function(e,t){let r="https:"===e,n="http:"===e;return"localhost"===t||"127.0.0.1"===t||"[::1]"===t||"::1"===t?{isSecure:!0,reason:"localhost",hostname:t,protocol:e}:r&&/\.ts\.net$/i.test(t)?{isSecure:!0,reason:"https-tsnet",hostname:t,protocol:e}:r?{isSecure:!0,reason:"https-other",hostname:t,protocol:e}:n&&ej.test(t)?{isSecure:!1,reason:"http-tailscale",hostname:t,protocol:e,guidance:"Tailscale 100.x 주소는 HTTP라 마이크 권한이 차단됩니다. `tailscale serve` 또는 funnel 로 ts.net HTTPS 호스트를 노출하면 마이크가 동작합니다."}:n?{isSecure:!1,reason:"http-other",hostname:t,protocol:e,guidance:"브라우저는 HTTP origin 에서 마이크 접근을 차단합니다. HTTPS 로 접속하거나 localhost 로 옮기세요."}:{isSecure:!1,reason:"unknown",hostname:t,protocol:e}}(window.location.protocol,window.location.hostname);return e.isSecure&&!1===window.isSecureContext?{...e,isSecure:!1,reason:"unknown",guidance:"현재 origin 이 secure context 가 아닙니다 (브라우저 판정). HTTPS 로 접속하세요."}:e}let eS="elanous.webterm.voiceBanner.dismissed",eI={isSecure:!1,reason:"unknown",hostname:"",protocol:""};function eC(){var e;let{statusOverride:t}=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},[r,l]=(0,a.useState)(!1),[s,o]=(0,a.useState)(null!=t?t:eI);if((0,a.useEffect)(()=>{l(function(){try{return"1"===window.sessionStorage.getItem(eS)}catch(e){return!1}}()),o(null!=t?t:eN())},[t]),s.isSecure||r)return null;let i="http-tailscale"===s.reason?"\uD83C\uDF99 Tailscale HTTP 에서 마이크가 차단됩니다":"\uD83C\uDF99 마이크 사용을 위해 HTTPS 가 필요합니다";return(0,n.jsxs)("div",{role:"alert","aria-live":"polite","data-testid":"webterm-voice-banner","data-reason":s.reason,className:"flex items-start gap-2 border-b border-amber-300 bg-amber-50 px-3 py-2 text-[12px] text-amber-900 dark:border-amber-700 dark:bg-amber-950/40 dark:text-amber-100",children:[(0,n.jsx)(ey.A,{className:"mt-[1px] h-3.5 w-3.5 shrink-0","aria-hidden":"true"}),(0,n.jsxs)("div",{className:"flex-1",children:[(0,n.jsx)("div",{className:"font-medium",children:i}),(0,n.jsx)("div",{className:"mt-0.5 text-amber-800/90 dark:text-amber-200/80",children:null!=(e=s.guidance)?e:"브라우저는 secure context (HTTPS \xb7 localhost) 에서만 마이크를 허용합니다."}),"http-tailscale"===s.reason&&(0,n.jsxs)("div",{className:"mt-1 font-mono text-[11px] text-amber-700 dark:text-amber-200/90",children:[(0,n.jsx)("code",{children:"tailscale serve --bg --https=443 31415"})," ","or"," ",(0,n.jsx)("a",{href:"https://tailscale.com/kb/1242/tailscale-serve",target:"_blank",rel:"noopener noreferrer",className:"underline hover:text-amber-900 dark:hover:text-amber-50",children:"ts.net HTTPS 가이드"})]})]}),(0,n.jsx)("button",{type:"button",onClick:()=>{try{window.sessionStorage.setItem(eS,"1")}catch(e){}l(!0)},"aria-label":"dismiss banner",title:"이 세션 동안 숨기기",className:"rounded p-0.5 text-amber-700 hover:bg-amber-100 dark:text-amber-200 dark:hover:bg-amber-900/40",children:(0,n.jsx)(ek.A,{className:"h-3.5 w-3.5"})})]})}async function eT(e){var t;let{terminalId:r,paths:n}=e,a=null==(t=e.alsoCopyToClipboard)||t,l=n.filter(e=>"string"==typeof e&&e.length>0).map(e=>"'".concat(e.replace(/'/g,"'\\''"),"'")).join(" ");if(!l)return{injected:!1,copied:!1};let s="".concat(l," "),o=!1;try{(o=N(r,s))?(0,m.cY)("webterm.attach.inject.ok",{terminalId:r,pathCount:n.length,bytes:s.length}):(0,m.cY)("webterm.attach.inject.error",{terminalId:r,reason:"no-sender"})}catch(e){(0,m.cY)("webterm.attach.inject.error",{terminalId:r,reason:String(e)})}let i=!1;if(a&&"undefined"!=typeof navigator&&navigator.clipboard)try{await navigator.clipboard.writeText(l),i=!0,(0,m.cY)("webterm.attach.clipboard.ok",{pathCount:n.length})}catch(e){(0,m.cY)("webterm.attach.clipboard.skip",{reason:String(e)})}return{injected:o,copied:i}}var eY=r(68158),eE=r(72422),eR=r(38067),eA=r(47940);function ez(e){return e.length<=32?e:"…".concat(e.slice(-32))}function eP(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:Date.now();if("number"!=typeof e||!Number.isFinite(e)||!Number.isFinite(t)||e>t)return null;let r=new Date(e);return Number.isFinite(r.getTime())?(0,eA.KW)(r.toISOString(),t):null}function eM(e){let t=new Map,r=new Set,n=new Set,a=[];for(let r of e){var l,s;if(n.has(r.id))continue;n.add(r.id),a.push(r);let e=null==(l=r.runId)?void 0:l.trim();if(!e)continue;let o=null!=(s=t.get(e))?s:[];o.push(r),t.set(e,o)}let o=[];for(let[e,n]of t){let t=function(e){let t=e.filter(e=>e.alive&&Number.isFinite(e.startedAt));if(0===t.length)return;let r=Math.max(...t.map(e=>{let{startedAt:t}=e;return t})),n=t.filter(e=>{let{startedAt:t}=e;return t===r});return 1===n.length?n[0]:void 0}(n);if(!t){for(let e of n)r.add(e.id);continue}o.push({runId:e,split:t.id,tabs:n.filter(e=>e.id!==t.id).map(e=>{let{id:t}=e;return t})})}let i=new Set(o.flatMap(e=>{let{split:t,tabs:r}=e;return[t,...r]}));return{layouts:o,unknown:a.filter(e=>{let{id:t}=e;return r.has(t)&&!i.has(t)}).map(e=>{let{id:t}=e;return{id:t,reason:"relationship-unavailable"}})}}function eD(e){return{layouts:e.layouts.map(e=>{let{runId:t,split:r,tabs:n}=e;return{runId:t,slots:[{terminalId:r,position:"split"},...n.map(e=>({terminalId:e,position:"tab"}))]}}),unknown:e.unknown.map(e=>({...e}))}}let eU=["terminal","observe","pty-list"],eL="elanous.webterm.activeId",e$="elanous.webterm.panelsMinimized",eO="elanous.webterm.chatDockOpen";function eF(e){return e.sourceRoot?{sourceRoot:e.sourceRoot.dbPath}:{}}function eB(e){let{layout:t,sessionId:r,onForeignInputActivity:a,terminalIds:l,activeId:s=null,visible:o=!0,clearRequests:i}=e,c=t.layouts.flatMap(e=>e.slots),d=new Map(c.map(e=>[e.terminalId,e])),u=new Set(t.layouts.map(e=>{var t;return null==(t=e.slots[0])?void 0:t.terminalId}).filter(e=>!!e)),m=void 0===l?c.map(e=>e.terminalId):[...new Set([...l,...s?[s]:[],...c.map(e=>e.terminalId)])],p=new Set(c.length>0?c.map(e=>e.terminalId):s?[s]:[]);return(0,n.jsxs)("div",{className:o?"grid h-full min-h-0 grid-cols-2 gap-2 p-2":"hidden","aria-label":"런별 터미널 배치",children:[t.layouts.map(e=>{let{runId:t}=e;return(0,n.jsx)("section",{className:"sr-only","aria-label":"런 ".concat(t," 터미널")},t)}),m.map(e=>{var t,l;let c=d.get(e),m=o&&p.has(e),h=null!=(t=null==c?void 0:c.position)?t:e===s?"single":"inactive-tab";return(0,n.jsxs)("div",{className:m?"".concat(u.has(e)?"col-start-1 ":"").concat((null==c?void 0:c.position)==="split"?"min-h-0 border border-emerald-600":(null==c?void 0:c.position)==="tab"?"min-h-0 border border-zinc-700":"col-span-2 h-full min-h-0"):"hidden","data-pane-position":h,"data-terminal-id":e,children:[c&&(0,n.jsxs)("p",{className:"sr-only",children:["split"===c.position?"분할 터미널":"탭 터미널",": ",e]}),(0,n.jsx)(S,{sessionId:r,terminalId:e,clearRequest:null!=(l=null==i?void 0:i[e])?l:0,onForeignInputActivity:a},e)]},e)}),t.unknown.map(e=>{let{id:t,reason:r}=e;return(0,n.jsxs)("p",{className:"text-xs text-muted-foreground","data-terminal-id":t,"data-pane-relationship":r,children:["터미널 ",t,": 관계를 알 수 없어 배치하지 않았습니다."]},t)})]})}function eQ(){var e,t,r;let{initialPtyId:s=null,onPtySelection:o}=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{client:i,config:c,sessionId:d}=(0,u.Q)(),{isCoarsePointer:p}=function(){let[e,t]=(0,a.useState)(!1);return(0,a.useEffect)(()=>{if(!window.matchMedia)return;let e=window.matchMedia("(pointer: coarse)");t(e.matches);let r=e=>{t(e.matches)};return"function"==typeof e.addEventListener?(e.addEventListener("change",r),()=>e.removeEventListener("change",r)):"function"==typeof e.addListener?(e.addListener(r),()=>e.removeListener(r)):void 0},[]),{isCoarsePointer:e}}(),[h,f]=(0,a.useState)(null),[b,g]=(0,a.useState)({}),[x,v]=(0,a.useState)([]),[w,y]=(0,a.useState)(!1),[k,j]=(0,a.useState)(null),[S,I]=(0,a.useState)(null),[C,T]=(0,a.useState)(!1);(0,a.useEffect)(()=>{var e,t;let r=null!=(t=null==(e=window.location)?void 0:e.search)?t:"",n=function(e){let t=new URLSearchParams(e).get("wall");return t?t.split(",").map(e=>e.trim()).filter(Boolean).slice(0,3):[]}(r);n.length&&I(n),"1"===new URLSearchParams(r).get("stage")&&T(!0)},[]);let[Y,R]=(0,a.useState)({status:"pending"}),A=function(e,t){let r="ready"===e.status&&"local"===e.issuedBy&&"restored-tab"!==e.fallbackReason,n="ready"===e.status&&e.fallbackReason?e.fallbackReason:"사유 미상";return{placeholder:t?null:"pending"===e.status?e.slow?"데몬이 느립니다 — 터미널을 만드는 중… (기다리는 중)":"터미널 이름을 준비하는 중…":"터미널 이름을 로컬에서 정했습니다 (".concat(n,")."),fallbackBanner:r?"터미널 이름을 로컬에서 정했습니다 (".concat(n,"). 데몬 발급을 확인하지 못했습니다."):null}}(Y,null!==h),z=(0,a.useCallback)(e=>{R(e),"pending"===e.status&&f(null)},[]),P=(0,a.useRef)(!1),U=(0,a.useRef)(!1),[L,O]=(0,a.useState)("terminal"),F={view:L,buttons:eU.map(e=>({view:e,selected:e===L}))},B=(0,a.useCallback)(e=>{O(t=>"observe"===e&&"observe"===t?"terminal":e)},[]),[Q,q]=(0,a.useState)(!!s),[H,_]=(0,a.useState)([]),[G,J]=(0,a.useState)(),[K,Z]=(0,a.useState)(new Map),[ee,er]=(0,a.useState)("loading"),[en,ea]=(0,a.useState)(null),[el,es]=(0,a.useState)(null),eo=(0,a.useRef)(!1),ei=null!=(r=null==en?void 0:en.id)?r:null,ec=en?(0,eR.x3)(en):null,[ed,eu]=(0,a.useState)("raw"),[em,ep]=(0,a.useState)(new Map),[eh,ef]=(0,a.useState)(new Map),[eb,eg]=(0,a.useState)({status:"unrequested"}),ex=(0,a.useRef)(0),ev=(0,a.useRef)(0);(0,a.useEffect)(()=>{if("terminal"!==L&&"pty-list"!==L)return;let e=!1;return er("loading"),(async()=>{try{let[t,r]=await Promise.all([i.listTerminals((0,eR.tC)(Q)),i.listProgressFrames().catch(e=>((0,m.cY)("webterm.pty-list.progress.error",{reason:String(e)}),null))]);if(e)return;_((0,eR.xu)(t.terminals)),J(t.scope),Z(r?(0,eR.gA)(r.logs):new Map),er("idle")}catch(t){if(e)return;_([]),J(void 0),Z(new Map),er("error"),(0,m.cY)("webterm.pty-list.error",{reason:String(t)})}})(),()=>{e=!0}},[i,Q,L]),(0,a.useEffect)(()=>{null===ec||H.some(e=>(0,eR.x3)(e)===ec)||(ex.current+=1,ev.current+=1,ea(null),eg({status:"unrequested"}))},[H,ec]);let ey=(0,a.useCallback)((e,t)=>{let{id:r}=e,n=(0,eR.x3)(e),a=++ex.current;if("raw"===t){ep(e=>new Map(e).set(n,{status:"loading"})),i.fetchTerminalScrollback(e.id,100,eF(e)).then(e=>{ex.current===a&&e.id===r&&ep(t=>new Map(t).set(n,{status:"ready",scrollback:e.scrollback}))}).catch(e=>{ex.current===a&&(ep(e=>new Map(e).set(n,{status:"error"})),(0,m.cY)("webterm.pty-list.scrollback.error",{id:r,reason:String(e)}))});return}ef(e=>new Map(e).set(n,{status:"loading"})),i.fetchTerminalFrame(e.id,eF(e)).then(e=>{ex.current===a&&e.id===r&&ef(t=>new Map(t).set(n,{status:"ready",frame:e.frame,frameAt:e.frameAt,frameSource:e.frameSource}))}).catch(e=>{ex.current===a&&(ef(e=>new Map(e).set(n,{status:"error"})),(0,m.cY)("webterm.pty-list.frame.error",{id:r,reason:String(e)}))})},[i]),ek=(0,a.useCallback)(function(e){let t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],{id:r}=e;if(t&&(y(!1),j(e),null==o||o(e)),ec===(0,eR.x3)(e))return;let n=++ev.current;ea(e),eg({status:"loading"}),ey(e,ed),i.fetchTerminalLineage(r).then(e=>{ev.current===n&&e.key===r&&eg({status:"ready",lineage:e})}).catch(e=>{ev.current===n&&(eg({status:"error"}),(0,m.cY)("webterm.pty-list.lineage.error",{id:r,reason:String(e)}))})},[i,o,ed,ey,ec]);(0,a.useEffect)(()=>{if(eo.current||"loading"===ee||(eo.current=!0,!s))return;if("error"===ee){es({kind:"list-unavailable"}),O("pty-list"),(0,m.cY)("webterm.initial-pty-selection",{ptyId:s,kind:"list-unavailable",reason:"pty-list-error"});return}let e=(0,eR.hH)(s,H);es(e),"selected"!==e.kind&&O("pty-list"),(0,m.cY)("webterm.initial-pty-selection",{ptyId:s,kind:e.kind,reason:e.reason}),"selected"===e.kind&&(ek(e.terminal),j(e.terminal))},[ek,s,ee,H]);let ej=(0,a.useCallback)(e=>{e!==ed&&(eu(e),en&&ey(en,e))},[ed,ey,en]),eS=(0,a.useCallback)(async e=>{var t;let r=window.prompt("새 PTY 이름을 입력하세요.",null!=(t=e.nickname)?t:"");if(null!==r)try{let t=await i.renameTerminal(e.id,r),n=function(e){switch(e.status){case"success":return"PTY 이름을 '".concat(e.name,"'(으)로 바꿨습니다.");case"invalid-name":return"이 이름은 사용할 수 없습니다. 다른 이름을 입력해 주세요.";case"unknown-pty":return"이 PTY를 찾을 수 없습니다. 목록을 새로고침한 뒤 다시 시도해 주세요.";case"denied":return"이 PTY의 이름을 바꿀 권한이 없습니다.";case"failed":return"PTY 이름 변경에 실패했습니다. 잠시 후 다시 시도해 주세요.";case"owner-unreachable":return"PTY 소유 프로세스에 연결할 수 없어 이름을 바꾸지 못했습니다.";default:return e}}(t);"success"===t.status?l.oR.success(n):l.oR.error(n)}catch(e){l.oR.error("PTY 이름 변경 요청에 실패했습니다: ".concat(String(e)))}},[i]),eI=(0,a.useMemo)(()=>(0,eR.lH)(Q,H,G,ec,em,ed,eh),[eh,Q,H,G,ed,em,ec]),eA=(0,a.useMemo)(()=>(0,eR.Kh)(ei,eb),[eb,ei]),eQ=(0,a.useMemo)(()=>(function(e,t){let r=t.trim();return r?{layouts:e.layouts.filter(e=>{let{slots:t}=e;return t.some(e=>e.terminalId===r)}).map(e=>({runId:e.runId,slots:e.slots.map(e=>({...e}))})),unknown:e.unknown.map(e=>({...e}))}:{layouts:[],unknown:e.unknown.map(e=>({...e}))}})(null===k&&(null===s||w)?eD(eM(H)):eD(eM(H.filter(e=>{var t;return e.id!==(null!=(t=null==k?void 0:k.id)?t:s)&&x.includes(e.id)}))),null!=h?h:""),[H,x,k,w,s,h]);(0,a.useEffect)(()=>{if(P.current||s||"loading"===ee)return;if(0===H.length){U.current||(U.current=!0,(0,m.cY)("webterm.initial-selection",{skipped:!0,reason:"no-terminals",listState:ee}));return}P.current=!0;let e=(0,eR.Dw)({storedId:null,fallbackId:h,terminals:H});(0,m.cY)("webterm.initial-selection",{terminalId:e.terminalId,reason:e.reason,rowCount:H.length}),e.terminalId!==h&&f(e.terminalId)},[H,ee]);let[eq,eH]=(0,a.useState)(0),[e_,eV]=(0,a.useState)(!1),[eG,eJ]=(0,a.useState)(!0),[eK,eW]=(0,a.useState)(!1),[eZ,eX]=(0,a.useState)(0),[e0,e1]=(0,a.useState)(null),e2=(0,a.useCallback)(e=>{e1({intent:e,nonce:Date.now()})},[]),e3=(0,a.useRef)(null),[e5,e9]=(0,a.useState)("none"),e4=(0,a.useRef)(e5);e4.current=e5;let e8=(0,a.useRef)(h);e8.current=h;let e7=(0,a.useCallback)(e=>{let t=e.trim();if(!t)return;let r=e4.current;if("controls"===r){let e=e8.current;if(!e)return;if(!N(e,t+" ")){(0,m.cY)("webterm.voice.stdin-inject-failed",{len:t.length,terminalId:e,reason:"no-sender"}),l.oR.error("터미널 입력 전송 실패 — 터미널 연결을 확인하고 다시 말해 주세요.");return}(0,m.cY)("webterm.voice.stdin-inject",{len:t.length,terminalId:e})}else if("dock"===r){var n;null==(n=e3.current)||n.submitVoiceTranscript(t)}else(0,m.cY)("webterm.voice.transcript-no-source",{len:t.length})},[]),e6=i.voiceWsUrl(),te=(0,eY.sS)({wsUrl:e6,...c.token?{token:c.token}:{},onTranscript:e7}),tt=(0,a.useMemo)(()=>eN(),[]),tr=!c.baseUrl||!tt.isSecure,tn=(0,a.useCallback)(()=>{te.active&&"dock"===e5?(e9("none"),te.toggle()):(e9("dock"),te.active||te.toggle())},[te,e5]),ta=(0,a.useCallback)(()=>{te.active&&"controls"===e5?(e9("none"),te.toggle()):(e9("controls"),te.active||te.toggle())},[te,e5]),tl=(0,a.useMemo)(()=>({active:te.active&&"dock"===e5,phase:te.phase,dotColor:eE.x[te.phase],phaseLabel:eE.g[te.phase],disabled:tr,onToggle:tn}),[te.active,te.phase,e5,tr,tn]),ts=(0,a.useMemo)(()=>({active:te.active&&"controls"===e5,phase:te.phase,dotColor:eE.x[te.phase],phaseLabel:eE.g[te.phase],disabled:tr,onToggle:ta}),[te.active,te.phase,e5,tr,ta]),to=(0,a.useRef)(tn);to.current=tn,(0,a.useEffect)(()=>{let e=e=>{"m"===e.key.toLowerCase()&&e.shiftKey&&(e.metaKey||e.ctrlKey)&&(e.preventDefault(),(0,m.cY)("webterm.voice.shortcut.toggle"),eJ(!0),to.current())};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[]),(0,a.useEffect)(()=>{let e=window.localStorage.getItem(eL);e&&e.length>0&&(!s||e!==s)&&(f(e),P.current=!0),"1"===window.localStorage.getItem(e$)&&eV(!0),"0"===window.localStorage.getItem(eO)&&eJ(!1)},[]);let ti=(0,a.useCallback)(async e=>{if(!d||!h||0===e.length)return;let t=e.map(e=>e.path).filter(e=>"string"==typeof e&&e.length>0);if(0===t.length)return void(0,m.cY)("webterm.attach.no-path",{count:e.length});let r=await eT({terminalId:h,paths:t});if(r.injected){let e=1===t.length?"터미널에 path 첨부됨":"".concat(t.length," paths 터미널에 첨부됨"),n=r.copied?" \xb7 clipboard 도 복사":"";l.oR.success(e+n)}else l.oR.error("터미널 inject 실패 — 직접 paste 해주세요")},[i,d,h]);return(0,n.jsxs)("div",{className:"flex h-full flex-col",children:[(0,n.jsx)(D.ZO,{activeId:h,onActiveChange:e=>{f(e),window.localStorage.setItem(eL,e),j(null),y(!0),O("terminal")},onInitialTerminalState:z,minimized:e_,onToggleMinimize:()=>{eV(e=>{let t=!e;return window.localStorage.setItem(e$,t?"1":"0"),t})},recording:eK,peerCount:eZ,chatDockOpen:eG,onToggleChatDock:()=>{if(e_){eV(!1),window.localStorage.setItem(e$,"0"),eJ(!0),window.localStorage.setItem(eO,"1");return}eJ(e=>{let t=!e;return window.localStorage.setItem(eO,t?"1":"0"),requestAnimationFrame(()=>{window.dispatchEvent(new Event("resize"))}),t})},tabIntent:e0,onTabsChange:v,suspendInitialSpawn:!!s&&!w}),A.fallbackBanner&&(0,n.jsx)("p",{className:"border-b border-amber-700/50 bg-amber-950/30 px-3 py-1 text-xs text-amber-200",role:"status",children:A.fallbackBanner}),(0,n.jsx)(eC,{}),(0,n.jsxs)("div",{className:e_?"hidden":"flex items-center gap-2 border-b border-zinc-800 px-3 py-1",children:[(0,n.jsx)("button",{type:"button","aria-pressed":F.buttons[0].selected,onClick:()=>{j(null),y(!0),B("terminal")},className:"rounded px-2 py-1 text-xs ".concat(F.buttons[0].selected?"bg-emerald-700 text-white":"bg-zinc-800 text-zinc-300 hover:bg-zinc-700"),children:"터미널"}),(0,n.jsxs)("button",{type:"button","aria-pressed":F.buttons[1].selected,onClick:()=>{j(null),y(!0),B("observe")},className:"rounded px-2 py-1 text-xs ".concat(F.buttons[1].selected?"bg-emerald-700 text-white":"bg-zinc-800 text-zinc-300 hover:bg-zinc-700"),title:"자기신고하는 elanous 대시보드 TUI 를 라이브로 관측(읽기 전용)",children:["\uD83D\uDDA5 TUI 관측 ",F.buttons[1].selected?"ON":"OFF"]}),(0,n.jsx)("button",{type:"button","aria-pressed":F.buttons[2].selected,onClick:()=>{j(null),y(!0),B("pty-list")},className:"rounded px-2 py-1 text-xs ".concat(F.buttons[2].selected?"bg-emerald-700 text-white":"bg-zinc-800 text-zinc-300 hover:bg-zinc-700"),children:"PTY 목록"}),(0,n.jsx)("button",{type:"button","aria-pressed":null!==S,onClick:()=>I(e=>null===e?[]:null),className:"rounded px-2 py-1 text-xs ".concat(null!==S?"bg-emerald-700 text-white":"bg-zinc-800 text-zinc-300 hover:bg-zinc-700"),"data-elanous-action":"pty-wall",children:"▦ 나란히"})]}),h?(0,n.jsxs)("div",{className:e_||"terminal"!==L||null!==k||s&&!w?"hidden":"contents",children:[(0,n.jsx)(X,{foreignActivityTick:eq,onPeerCountChange:eX}),(0,n.jsx)(V,{terminalId:h,onClear:()=>g(e=>{var t;return{...e,[h]:(null!=(t=e[h])?t:0)+1}}),onRecordingChange:eW,onAttached:ti,voice:ts}),p&&(0,n.jsx)(W,{terminalId:h}),(0,n.jsx)(et,{onAttached:ti})]}):null,(0,n.jsxs)("div",{className:"relative flex-1 min-h-0",children:[null!==S&&(0,n.jsx)("div",{className:C?"fixed inset-0 z-50":"absolute inset-0 z-20","data-pty-wall-stage":C?"1":void 0,children:(0,n.jsx)(M,{rows:H,client:i,initial:S,stage:C,onClose:()=>{I(null);let e=new URLSearchParams(window.location.search);e.delete("wall"),window.history.replaceState(null,"","".concat(window.location.pathname).concat(e.toString()?"?".concat(e):""))}})}),(0,n.jsx)(eB,{layout:eQ,sessionId:d,terminalIds:x.filter(e=>e!==(null==k?void 0:k.id)&&(w||e!==s)),activeId:h&&(h===(null==k?void 0:k.id)||!w&&h===s)?null:h,clearRequests:b,visible:null!==h&&"terminal"===L&&null===k&&(!s||w),onForeignInputActivity:()=>eH(e=>e+1)}),k&&(0,n.jsx)(E,{terminal:k,client:i,onClose:()=>{y(!0),j(null),B("terminal")}},(0,eR.x3)(k)),k||"terminal"!==L||h&&(!s||w)?k?null:"pty-list"===L?(0,n.jsxs)("div",{className:"h-full overflow-auto p-3","aria-label":"데몬 PTY 목록",children:[(0,n.jsxs)("label",{className:"mb-3 flex items-center gap-2 text-sm",children:[(0,n.jsx)("input",{type:"checkbox",checked:eI.includeAll,onChange:e=>q(e.target.checked)}),"다른 인스턴스도 보기"]}),eI.scopeSummary&&(0,n.jsx)("p",{className:"mb-3 text-xs text-muted-foreground","aria-label":"PTY 목록 범위 요약",children:eI.scopeSummary}),(null==el?void 0:el.kind)==="ambiguous"&&(0,n.jsxs)("p",{className:"mb-3 text-xs text-amber-500",role:"status","aria-label":"URL PTY 선택 상태",children:["주소의 PTY ",s,"가 ",el.candidates.length,"개 행과 맞아 선택하지 않았습니다."]}),(null==el?void 0:el.kind)==="list-unavailable"&&(0,n.jsxs)("p",{className:"mb-3 text-xs text-rose-500",role:"status","aria-label":"URL PTY 선택 상태",children:["PTY 목록을 읽지 못해 주소의 PTY ",s,"를 확인할 수 없습니다. 목록이 비었다는 뜻이 \xab아닙니다\xbb."]}),(null==el?void 0:el.kind)==="not-found"&&(0,n.jsxs)("p",{className:"mb-3 text-xs text-rose-500",role:"status","aria-label":"URL PTY 선택 상태",children:["주소의 PTY ",s,"를 찾지 못했습니다 (",el.reason,")."]}),(null==(t=eI.rows.find(e=>e.view))||null==(e=t.view)?void 0:e.visible)&&(0,n.jsx)("div",{className:"mb-3 flex gap-2","aria-label":"PTY 화면 보기",children:eI.rows.find(e=>e.view).view.modes.map(e=>(0,n.jsx)("button",{type:"button","aria-pressed":e.selected,onClick:()=>ej(e.mode),className:"rounded px-2 py-1 text-xs ".concat(e.selected?"bg-emerald-700 text-white":"bg-zinc-800 text-zinc-300 hover:bg-zinc-700"),children:e.label},e.mode))}),"loading"===ee?(0,n.jsx)("p",{className:"text-sm text-muted-foreground",children:"PTY 목록을 불러오는 중…"}):"error"===ee?(0,n.jsx)("p",{className:"text-sm text-rose-500",children:"PTY 목록을 불러오지 못했습니다."}):0===H.length?(0,n.jsx)("p",{className:"text-sm text-muted-foreground",children:"데몬이 아는 PTY가 없습니다."}):(0,n.jsx)("ul",{className:"space-y-2",children:eI.rows.map(e=>{let{terminal:t}=e,r=function(e){var t,r,n;let a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:Date.now(),l=e.name||e.id,s=function(e,t,r){let n=[e,t].filter(Boolean).join("/")||r;if(!n||!e||n.length<=32)return n&&ez(n);if(!t)return e.length<=32?e:"…".concat(e.slice(-31));let a=32-e.length-2;return a<=0?e.length<=32?e:"…".concat(e.slice(-31)):"".concat(e,"/…").concat(t.slice(-a))}(e.treeName,e.worktreeName,e.workdir),o=function(e){var t;if(!(null==e?void 0:e.name)&&!(null==e?void 0:e.dbPath))return null;let r=[e.name&&ez(e.name),e.dbPath&&((t=e.dbPath).length<=32?t:"".concat(t.slice(0,31),"…"))].filter(e=>!!e);return"세션: ".concat(r.join(" \xb7 "))}(e.sourceRoot),i=eP(e.startedAt,a),c=void 0===e.lastControlAt?null:eP(e.lastControlAt,a);return{title:l,details:[...l===e.id?[]:[e.id],...e.status?["상태: ".concat(e.status)]:[],...e.kind?["종류: ".concat(e.kind)]:[],...e.nickname?["별명: ".concat(ez(e.nickname))]:[],...s?["위치: ".concat(s)]:[],e.alive?"생존: 실행 중":0===e.exitCode?"종료: 정상 종료 (exit 0)":"number"==typeof e.exitCode?"종료: 비정상 종료 (exit ".concat(e.exitCode,")"):"종료: 종료 코드 미상",function(e){if("direct-human"===e.terminalOriginCategory)return"출처: 사람";if("elanous"===e.terminalOriginCategory)return"출처: elanous";if("external-tool"===e.terminalOriginCategory)return e.externalToolName?"출처: 외부 도구 \xb7 ".concat(ez(e.externalToolName)):"출처: 외부 도구";let t=e.terminalOriginReason?" \xb7 ".concat(ez(e.terminalOriginReason)):"";return"출처: 이 행에서는 알 수 없음".concat(t)}(e),...e.controller?["통제: ".concat(ez(e.controller))]:[],"write"===(t=e.accessMode)?"접근: 쓰기":"read"===t?"접근: 읽기":"auto"===t?"접근: 자동":"접근: 이 행에서는 알 수 없음","running"===(r=e.ownerRunUsage)?"소유 런: 실행 중":"terminated-live-owner"===r?"소유 런: 종료됐지만 터미널 유지":"no-run-id"===r?"소유 런: 소유 런 정보 없음":"소유 런: 이 행에서는 알 수 없음",...e.instance?["우주: ".concat(ez(e.instance))]:[],...e.runId?["런: ".concat((n=e.runId).length<=8?n:"".concat(n.slice(0,8),"…"))]:[],...o?[o]:[],...i?["시작: ".concat(i)]:[],"마지막 제어: ".concat(null!=c?c:"이 행에서는 알 수 없음")]}}(t),a=K.get(t.id);return(0,n.jsxs)("li",{className:"rounded border p-2 text-sm ".concat(e.selected?"border-emerald-500":"border-border"),children:[(0,n.jsxs)("button",{type:"button",className:"w-full text-left","aria-pressed":e.selected,onClick:()=>ek(t,!0),children:[(0,n.jsx)("p",{className:"font-medium",children:r.title}),r.details.map((e,r)=>(0,n.jsx)("p",{className:0===r?"font-mono text-xs text-muted-foreground":"text-xs text-muted-foreground",children:e},"".concat(t.id,"-").concat(e))),a&&(0,n.jsxs)("p",{className:"mt-1 text-xs text-muted-foreground","aria-label":"현재 활동: ".concat("complete"===a.status?"완료":"진행 중"),children:["complete"===a.status?"완료":"진행 중",": ",a.line,a.hasMissingFrames?" \xb7 일부 진행 프레임 누락":""]})]}),(0,n.jsx)("button",{type:"button",className:"mt-2 rounded bg-zinc-800 px-2 py-1 text-xs text-zinc-100 hover:bg-zinc-700",onClick:()=>{eS(t)},children:"이름 바꾸기"}),e.selected&&eA&&(0,n.jsxs)("section",{className:"mt-2 rounded bg-zinc-900 p-2 text-xs","aria-label":"선택 PTY 계보",children:[(0,n.jsx)("p",{className:"font-medium",children:"계보"}),"loading"===eA.kind&&(0,n.jsx)("p",{className:"text-muted-foreground",children:"계보를 불러오는 중…"}),"error"===eA.kind&&(0,n.jsx)("p",{className:"text-rose-400",children:"계보를 불러오지 못했습니다."}),"empty"===eA.kind&&(0,n.jsx)("p",{className:"text-muted-foreground",children:"연결된 다른 화면이 없습니다."}),eA.unreadablePayloadsSummary&&(0,n.jsx)("p",{className:"text-muted-foreground",children:eA.unreadablePayloadsSummary}),eA.groups.map(e=>(0,n.jsxs)("div",{className:"mt-2",children:[(0,n.jsxs)("p",{className:"font-mono",children:["묶음: ",e.joinedBy," \xb7 ",e.key]}),(0,n.jsx)("ul",{className:"mt-1 space-y-1",children:e.rows.map(e=>(0,n.jsxs)("li",{className:e.selected?"rounded bg-emerald-900 px-1 text-emerald-100":"",children:[e.selected?"현재 선택 \xb7 ":"",e.ptyId," \xb7 ",e.kind," \xb7 ",e.instance," \xb7 ",(0,eR.cl)(e.alive,e.closed)," \xb7 시작 ",(0,eR.OZ)(e.startedAt)]},e.ptyId))})]},"".concat(e.joinedBy,"-").concat(e.key)))]}),e.view&&(0,n.jsxs)("div",{className:"mt-2",children:[e.view.display.frameInfo&&(0,n.jsx)("p",{className:"mb-1 font-mono text-xs text-muted-foreground","aria-label":"렌더 화면 정보",children:e.view.display.frameInfo}),e.view.display.frameMetadata&&(0,n.jsxs)("p",{className:"mb-1 text-xs text-muted-foreground","aria-label":"렌더 프레임 메타데이터",children:["관측: ",e.view.display.frameMetadata.frameAt," \xb7 출처: ",e.view.display.frameMetadata.frameSource]}),(0,n.jsx)("pre",{className:"whitespace-pre-wrap rounded bg-zinc-950 p-2 text-xs ".concat("error"===e.view.display.kind?"text-rose-400":"text-zinc-100"),children:e.view.display.text})]})]},(0,eR.x3)(t))})})]}):"observe"===L?(0,n.jsx)($,{sessionId:d},d):null:(0,n.jsxs)("div",{className:"flex h-full flex-col items-center justify-center gap-2 text-sm text-muted-foreground",role:"status","aria-live":"polite",children:[(null==el?void 0:el.kind)==="list-unavailable"&&(0,n.jsxs)("p",{className:"text-xs text-rose-500","aria-label":"URL PTY 선택 상태",children:["PTY 목록을 읽지 못해 주소의 PTY ",s,"를 확인할 수 없습니다. 목록이 비었다는 뜻이 \xab아닙니다\xbb."]}),(0,n.jsx)("span",{children:A.placeholder})]})]}),h&&!e_&&"terminal"===L&&!k&&(!s||w)&&(0,n.jsx)(ew,{ref:e3,terminalId:h,open:eG,onTabIntent:e2,voice:tl})]})}},19528:(e,t,r)=>{r.d(t,{Er:()=>a,cj:()=>c,yR:()=>i});let n=/^(oauth\.|harness\.decision|llm\.router)/;function a(e){let t=[],r=e=>{"string"==typeof e&&e.trim()&&!t.includes(e.trim())&&t.push(e.trim())};for(let t of e){var a;let e=null!=(a=t.data)?a:{};if(t.category.startsWith("oauth.")){for(let t of["from","to","name","account"])r(e[t]);if(Array.isArray(e.usage))for(let t of e.usage)r(null==t?void 0:t.name);continue}if(n.test(t.category))for(let t of(r(e.account),["what","why","reason"])){let n=e[t];if("string"==typeof n)for(let e of n.matchAll(/계정\s+([A-Za-z0-9][\w.-]*)/g))r(e[1])}}return t}function l(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function s(e){let t=new Map(e.map((e,t)=>[e,"account-".concat(t+1)])),r=e.length?RegExp("(^|[^\\w-])(".concat(e.map(l).sort((e,t)=>t.length-e.length).join("|"),")(?![\\w-])"),"g"):null,n=new Map;return(e,a)=>{let l=e.replace(/\b[a-z0-9-]+\.tail[0-9a-f]+\.ts\.net\b/gi,"tailnet-host").replace(/\bmsb\d+\b/gi,e=>(e=>{let t=e.toLowerCase();n.has(t)||n.set(t,"remote-".concat(n.size+1));let r=n.get(t);return e===e.toUpperCase()?r.toUpperCase():r})(e)).replace(/\bmbp\b/gi,e=>e===e.toUpperCase()?"LOCAL":"local").replace(/\/Users\/[^/\s"']+/g,"~").replace(/(크레딧|credits?|💳)(\s*[:=]?\s*)[\d][\d,.]*/gi,"$1$2•••").replace(/[\d][\d,.]*(\s*)(크레딧|credits?)/gi,"•••$1$2").replace(/\$\s?[\d][\d,.]*/g,"$•••").replace(/(잔량?|remaining|left)(\s*[:=]?\s*)(?:[A-Za-z0-9][\w.-]*\s+)?\d+(?:\.\d+)?\s?%/gi,"$1$2•••");return a&&r&&(l=l.replace(r,(e,r,n)=>{var a;return"".concat(r).concat(null!=(a=t.get(n))?a:"account")})),l}}function o(e,t){if("string"==typeof e)return t(e);if(Array.isArray(e))return e.map(e=>o(e,t));if(e&&"object"==typeof e){let r={};for(let[n,a]of Object.entries(e))"apiEquivalentUsd"===n||"usd"===n||/credit(s|Balance)?$/i.test(n)||(r[n]=o(a,t));return r}return e}function i(e){let t=s(a(e));return e.map(e=>{let r=n.test(e.category);return{...e,event:t(e.event,!1),data:e.data?o(e.data,e=>t(e,r)):e.data}})}function c(e,t){let r=s(t);return o(e,e=>r(e,!0))}}}]);
@@ -1 +0,0 @@
1
- "use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[8067],{28211:(e,t,n)=>{n.d(t,{GG:()=>i,HS:()=>c,KN:()=>a,L4:()=>l,U$:()=>f,XG:()=>d,h7:()=>o,t_:()=>m,vq:()=>p,xV:()=>s});var r=n(30913);function a(e){return e?{all:!0,includeTest:!0}:{}}function l(){try{let e=(0,r.Ys)(),t=(0,r.Wq)(e);return(0,r.To)([...e,t]),t}catch(e){return null}}function o(){let e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],t=Object.entries(a(e)).map(e=>{let[t,n]=e;return"".concat(encodeURIComponent(t),"=").concat(encodeURIComponent(String(n)))}).join("&");return 0===t.length?"/v1/terminals":"/v1/terminals?".concat(t)}function s(e){return"/v1/terminals/".concat(encodeURIComponent(e),"/frame")}function i(){return"/v1/terminals/view"}let u={unknown:"Unknown target: this PTY was not found. Check the subject list and try again.",denied:"Denied: takeover was refused. Check ownership and try again.","owner-unreachable":"Owner unreachable: could not reach the PTY owner. Check the owner process and try again.",failed:"Server failed: ownership transfer did not complete. Check status and try again.",http:"Takeover failed. Check status and try again.",network:"Network failed: could not request takeover. Check the connection and try again."};async function c(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:globalThis.fetch,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};try{var r,a;let l=await t("/v1/terminals/".concat(encodeURIComponent(e),"/control"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({action:"takeover"}),signal:n.signal});if(200===l.status)return{ok:!0,ptyId:e};let o=(r=l.status,404===r?"unknown":409===r?"denied":504===r?"owner-unreachable":502===r?"failed":"http");return{ok:!1,ptyId:e,kind:o,status:l.status,message:(a=l.status,"http"===o&&void 0!==a?"Takeover failed (".concat(a,"). Check status and try again."):u[o])}}catch(t){return{ok:!1,ptyId:e,kind:"network",message:u.network}}}function d(e){return{talk:e.talk.length>0,screen:e.screen.ptyIds.length>0,agent:e.agent.names.length>0||e.agent.controllers.length>0}}function m(e){let t=d(e);return e.screen.liveCount>0?"live":!t.screen&&t.agent?"unknown":"inactive"}function f(e){let t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];return t?[...e]:e.filter(e=>"inactive"!==m(e))}function p(e,t){let n=new Map;for(let a of e){var r;let e=(function(e){let t=new Set,n=[];for(let r of e)!1===r.hasPty||t.has(r.id)||(t.add(r.id),n.push({id:r.id,value:r}));return n})(a.screen.ptyIds.map(e=>({id:e}))).sort((e,t)=>e.id.localeCompare(t.id));if(0===e.length){n.set(a.id,{kind:"no-screen"});continue}let l=null==(r=e.find(e=>{let{id:n}=e;return t.has(n)}))?void 0:r.id,o=void 0===l?void 0:t.get(l);n.set(a.id,void 0===l||void 0===o?{kind:"no-progress"}:{kind:"progress",ptyId:l,...o})}return n}},30913:(e,t,n)=>{n.d(t,{ZO:()=>Y,Ys:()=>w,Wq:()=>k,To:()=>y});var r=n(41121),a=n(91269),l=n(31014),o=n(330),s=n(86715),i=n(29565),u=n(38519),c=n(51215);function d(e){return(null==e?void 0:e.terminalOriginCategory)==="direct-human"?"사람":(null==e?void 0:e.terminalOriginCategory)==="elanous"?"elanous":(null==e?void 0:e.terminalOriginCategory)==="external-tool"?e.externalToolName?"외부 도구: ".concat(e.externalToolName):"외부 도구":(null==e?void 0:e.terminalOriginReason)?"이 행에서는 알 수 없음: ".concat(e.terminalOriginReason):"이 행에서는 알 수 없음"}function m(e){return{action:e,sendsDestroy:"terminate"===e}}let f="elanous.webterm.tabs",p="elanous.webterm.hidden-tabs",g=new Map;function h(e){return(null==e?void 0:e.isAlive)&&void 0!==e.controller?"human"===e.controller?"release":"takeover":null}function b(e){return"takeover"===e?"넘겨받기":"놓기"}function w(){try{let e=window.localStorage.getItem(f);if(!e)return[];let t=JSON.parse(e);if(!Array.isArray(t))return[];return t.filter(e=>"string"==typeof e&&e.length>0)}catch(e){return[]}}function y(e){window.localStorage.setItem(f,JSON.stringify(e))}function v(e){window.localStorage.setItem(p,JSON.stringify(e))}function k(e){let t=1;for(;e.includes("preview-".concat(t));)t+=1;return"preview-".concat(t)}function x(e,t){let n=null==e?void 0:e.terminalId;if("string"==typeof n&&n.trim().length>0)return{id:n,issuedBy:"daemon"};let r=I(e)?e.spawnFailure:null==e?"no-response":"response-without-terminal-id";return{id:k(t),issuedBy:"local",fallbackReason:r}}function I(e){return"object"==typeof e&&null!==e&&"string"==typeof e.spawnFailure}async function N(e,t){let n,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:c.cY,a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:S,l=arguments.length>4?arguments[4]:void 0,o=arguments.length>5&&void 0!==arguments[5]?arguments[5]:C;if(r("webterm.tabs.add.start",{hasAcp:!!e,hasSessionId:!!t}),!e||!t){let t=e?"no-session":"no-acp";return r("webterm.tabs.add.skip",{reason:t}),{spawnFailure:t}}r("webterm.tabs.add.spawn-pending",{sessionId:t});let s=l?setTimeout(()=>{r("webterm.tabs.add.spawn-slow",{sessionId:t,slowMs:o}),l()},o):void 0;try{let l=new Promise(e=>{n=setTimeout(()=>e({spawnFailure:"spawn-timeout"}),a)}),o=await Promise.race([e.send("terminal/spawn",{sessionId:t}),l]);return I(o)&&r("webterm.tabs.add.spawn-timeout",{sessionId:t,timeoutMs:a}),o}catch(e){return r("webterm.tabs.add.spawn-error",{reason:String(e)}),{spawnFailure:"spawn-error",detail:String(e)}}finally{void 0!==n&&clearTimeout(n),void 0!==s&&clearTimeout(s)}}let C=8e3,S=9e4;function Y(e){let{activeId:t,onActiveChange:n,onInitialTerminalState:f,minimized:I=!1,onToggleMinimize:Y,recording:T=!1,peerCount:j=0,chatDockOpen:M=!0,onToggleChatDock:A,tabIntent:P=null,onTabsChange:R,suspendInitialSpawn:O=!1}=e,{client:D,sessionId:q}=(0,u.Q)(),[E,U]=(0,a.useState)(w),B=(0,a.useRef)(new Set(function(){try{let e=window.localStorage.getItem(p),t=e?JSON.parse(e):[];return Array.isArray(t)?t.filter(e=>"string"==typeof e&&e.length>0):[]}catch(e){return[]}}())),F=(0,a.useRef)(E);F.current=E;let L=(0,a.useRef)(t);L.current=t;let K=(0,a.useRef)(0),W=(0,a.useRef)(!1),_=(0,a.useRef)(null),J=(0,a.useRef)(!1),[G,H]=(0,a.useState)(0),Z=(0,a.useRef)(null);(0,a.useEffect)(()=>{if(en.current+=1,K.current+=1,W.current=!1,J.current=!1,!q)return;let e=D.connectAcp({sessionId:q});Z.current=e;let t=e.onState(t=>{Z.current===e&&"OPEN"===t&&H(e=>e+1)});return"OPEN"===e.state&&H(e=>e+1),(0,c.cY)("webterm.tabs.acp.attach",{sessionId:q}),()=>{var n;t();let r=null!=(n=Z.current)?n:e;try{r.close()}catch(e){}Z.current=null}},[D,q]);let[$,Q]=(0,a.useState)({sessionId:null,entries:new Map}),[V,X]=(0,a.useState)(new Map),z=(0,a.useRef)(new Map),ee=null!==$.sessionId&&$.sessionId===q,et=ee?$.entries:g,en=(0,a.useRef)(0),er=(0,a.useCallback)(()=>{var e;let t=Z.current;if(!q)return null;if(null!==(e=t?t.state:null)&&"FAILED"!==e&&"CLOSED"!==e)return t;let n=t?t.state:"none";(0,c.cY)("webterm.tabs.acp.reacquire.attempt",{sessionId:q,previousState:n});try{null==t||t.close()}catch(e){}let r=D.connectAcp({sessionId:q});return Z.current=r,en.current+=1,Q({sessionId:null,entries:new Map}),(0,c.cY)("webterm.tabs.acp.reacquire.ok",{sessionId:q,previousState:n,state:r.state}),r},[D,q]),ea=(0,a.useCallback)(async()=>{let e;if(q){try{e=er()}catch(e){(0,c.cY)("webterm.tabs.list.error",{sessionId:q,connectionState:"reacquire-failed",reason:String(e)});return}if(e)try{let t=en.current,n=await e.send("terminal/list",{sessionId:q});if(t!==en.current)return void(0,c.cY)("webterm.tabs.list.stale",{sessionId:q,generation:t,now:en.current});let r=function(e){if(null==e)return{ok:!1,reason:"no-response"};let t=e.terminals;if(!Array.isArray(t))return{ok:!1,reason:"malformed"};let n=[];for(let e of t){if("object"!=typeof e||null===e)return{ok:!1,reason:"malformed"};let{terminalId:t,isAlive:r,pid:a,cols:l,rows:o,lastOutputAt:s,ownerRunUsage:i,terminalOriginCategory:u,terminalOriginReason:c,externalToolName:d,controller:m}=e;if("string"!=typeof t||0===t.trim().length||"boolean"!=typeof r)return{ok:!1,reason:"malformed"};let f=e=>"number"==typeof e&&Number.isFinite(e)?e:void 0;n.push({terminalId:t,isAlive:r,...void 0!==f(a)?{pid:f(a)}:{},...void 0!==f(l)?{cols:f(l)}:{},...void 0!==f(o)?{rows:f(o)}:{},...void 0!==f(s)?{lastOutputAt:f(s)}:{},..."running"===i||"terminated-live-owner"===i||"no-run-id"===i||"unknown"===i?{ownerRunUsage:i}:{},..."direct-human"===u||"elanous"===u||"external-tool"===u||"unknown"===u?{terminalOriginCategory:u}:{},..."string"==typeof c?{terminalOriginReason:c}:{},..."string"==typeof d?{externalToolName:d}:{},..."string"==typeof m?{controller:m}:{}})}return{ok:!0,entries:n}}(n);if(!r.ok)return void(0,c.cY)("webterm.tabs.list.error",{sessionId:q,connectionState:e.state,reason:"list-".concat(r.reason)});let a=r.entries,l=a.map(e=>e.terminalId),o=new Set(l);for(let e of B.current)o.has(e)||B.current.delete(e);v([...B.current]),Q({sessionId:q,entries:new Map(a.map(e=>[e.terminalId,e]))}),(0,c.cY)("webterm.tabs.list",{sessionId:q,local:E.length,daemon:l.length}),U(e=>{let t=[...e];for(let e of l)B.current.has(e)||t.includes(e)||t.push(e);return t.length===e.length?e:(y(t),t)})}catch(t){(0,c.cY)("webterm.tabs.list.error",{sessionId:q,connectionState:e.state,reason:String(t)})}}},[er,q,E.length]);(0,a.useEffect)(()=>{if(!Z.current)return;ea();let e=setInterval(()=>{ea()},15e3);return()=>clearInterval(e)},[Z.current]);let el=(0,a.useCallback)(e=>(y(e),e),[]);(0,a.useEffect)(()=>{null==R||R(E)},[R,E]);let eo=(0,a.useCallback)(async e=>{if(W.current||F.current.length>0)return;W.current=!0;let t=++K.current;null==f||f({status:"pending"});let r=await N(e,q,c.cY,S,()=>{t===K.current&&(null==f||f({status:"pending",slow:!0}))});if(t!==K.current||F.current.length>0){var a;W.current=!1;let e=r&&"spawned"===r.status&&"string"==typeof r.sessionId&&"string"==typeof r.terminalId&&r.sessionId.trim()&&r.terminalId.trim()?{sessionId:r.sessionId,terminalId:r.terminalId}:null;(0,c.cY)("webterm.tabs.initial.discarded",{reason:t!==K.current?"session-changed":"tabs-present",orphan:e}),e&&(null==(a=Z.current)||a.send("terminal/destroy",e).catch(t=>(0,c.cY)("webterm.tabs.initial.orphan-destroy-error",{...e,reason:String(t)})));return}let l=x(r,F.current),o=[l.id];J.current=!0,el(o),U(o),n(l.id),null==f||f({status:"ready",issuedBy:l.issuedBy,...l.fallbackReason?{fallbackReason:l.fallbackReason}:{}}),(0,c.cY)("webterm.tabs.initial",{id:l.id,issuedBy:l.issuedBy,...l.fallbackReason?{fallbackReason:l.fallbackReason}:{}})},[n,f,el,q]);(0,a.useEffect)(()=>{if(O)return;if(E.length>0){let e=J.current;W.current=!1,t||n(E[0]),e||null==f||f({status:"ready",issuedBy:"local",fallbackReason:"restored-tab"});return}let e=Z.current;if(!e||"OPEN"!==e.state){null==f||f({status:"pending"}),null===_.current&&(_.current=Date.now());let e=setTimeout(()=>{var e,t;if(F.current.length>0||(null==(e=Z.current)?void 0:e.state)==="OPEN")return;let r=k(F.current);J.current=!0,el([r]),U([r]),n(r),null==f||f({status:"ready",issuedBy:"local",fallbackReason:"acp-not-open"}),(0,c.cY)("webterm.tabs.initial",{id:r,issuedBy:"local",fallbackReason:"acp-not-open",waitedMs:Date.now()-(null!=(t=_.current)?t:Date.now())})},Math.max(0,C-(Date.now()-_.current)));return()=>clearTimeout(e)}_.current=null,eo(e)},[G,t,eo,n,f,el,O,E.length]);let es=(0,a.useCallback)(async()=>{let e=await N(Z.current,q);U(t=>{let{id:r,issuedBy:a,fallbackReason:l}=x(e,t);if(B.current.delete(r)&&v([...B.current]),t.includes(r))return n(r),(0,c.cY)("webterm.tabs.add.existing",{id:r,issuedBy:a,total:t.length}),t;let o=el([...t,r]);return n(r),(0,c.cY)("webterm.tabs.add",{id:r,total:o.length,issuedBy:a,...l?{fallbackReason:l}:{}}),o})},[n,el,q]),ei=(0,a.useCallback)(e=>{e!==t&&((0,c.cY)("webterm.tabs.switch",{from:t,to:e}),n(e))},[t,n]),eu=(0,a.useCallback)(function(e){var t;let r=arguments.length>1&&void 0!==arguments[1]&&arguments[1];z.current.set(e,(null!=(t=z.current.get(e))?t:0)+1),X(t=>{if(!t.has(e))return t;let n=new Map(t);return n.delete(e),n});let a=F.current;if(r&&(B.current.add(e),v([...B.current])),!a.includes(e))return;let l=a.filter(t=>t!==e);el(l),U(l),e===L.current&&l.length>0&&n(l[0]),0===l.length&&(W.current=!1,null==f||f({status:"pending"}))},[n,f,el]),ec=(0,a.useCallback)(e=>{m("remove-local").sendsDestroy||(eu(e,!0),(0,c.cY)("webterm.tabs.remove-local",{id:e}),ea())},[ea,eu]),ed=(0,a.useCallback)(async(e,t)=>{var n;let r=V.get(e);if(r&&!r.message)return;let a=(null!=(n=z.current.get(e))?n:0)+1;z.current.set(e,a),X(n=>{let r=new Map(n);return r.set(e,{action:t}),r});try{let n=await D.controlTerminal(e,t);if(a!==z.current.get(e)||!F.current.includes(e))return;let r=function(e,t){switch(t.status){case"success":return"takeover"===e?"터미널을 넘겨받았습니다.":"터미널 제어를 놓았습니다.";case"unknown-pty":return"이 PTY를 찾을 수 없습니다. 목록을 새로고침해 주세요.";case"denied":return"이 PTY의 제어를 바꿀 권한이 없습니다.";case"failed":return"PTY 제어 전환에 실패했습니다. 잠시 후 다시 시도해 주세요.";case"owner-unreachable":return"PTY 소유 프로세스에 연결할 수 없어 제어를 전환하지 못했습니다.";default:return t.status}}(t,n);X(n=>{let a=new Map(n);return a.set(e,{action:t,message:r}),a}),(0,c.cY)("webterm.tabs.control",{id:e,action:t,status:n.status}),"success"===n.status&&ea()}catch(n){if(a!==z.current.get(e)||!F.current.includes(e))return;X(n=>{let r=new Map(n);return r.set(e,{action:t,message:"PTY 제어 요청을 전송하지 못했습니다. 네트워크 연결을 확인해 주세요."}),r}),(0,c.cY)("webterm.tabs.control.error",{id:e,action:t,reason:String(n)})}},[D,ea,V]),em=(0,a.useCallback)(async(e,t)=>{let n=m("terminate"),r=function(e){switch("running"===e||"terminated-live-owner"===e||"no-run-id"===e||"unknown"===e?e:"unknown"){case"running":return{title:"터미널을 끝낼까요?",message:"실행 중인 런이 이 터미널을 사용하고 있습니다. 끝내면 터미널과 그 프로세스가 종료됩니다."};case"terminated-live-owner":return{title:"터미널을 끝낼까요?",message:"소유 런은 종료됐지만 이 터미널은 아직 남아 있습니다. 끝내면 터미널과 그 프로세스가 종료됩니다."};case"no-run-id":return{title:"터미널을 끝낼까요?",message:"이 터미널에는 소유 런 정보가 없습니다. 끝내면 터미널과 그 프로세스가 종료됩니다."};case"unknown":return{title:"터미널을 끝낼까요?",message:"이 터미널의 사용 상태를 확인할 수 없습니다. 아무도 쓰지 않는다고 단정할 수 없으며, 끝내면 터미널과 그 프로세스가 종료됩니다."}}}(t);if(!window.confirm("".concat(r.title,"\n\n").concat(r.message))||!n.sendsDestroy)return;let a=Z.current;if(!a||!q)return void(0,c.cY)("webterm.tabs.destroy.error",{id:e,reason:"no-acp-or-session"});try{await a.send("terminal/destroy",{sessionId:q,terminalId:e}),(0,c.cY)("webterm.tabs.destroyed",{id:e}),eu(e,!0),ea()}catch(t){(0,c.cY)("webterm.tabs.destroy.error",{id:e,reason:String(t)})}},[eu,ea,q]);(0,a.useEffect)(()=>{!t||B.current.has(t)||U(e=>e.includes(t)?e:el([...e,t]))},[t,el]),(0,a.useEffect)(()=>{let e;if(!P||!t||0===E.length)return;let r=E.indexOf(t);if("next"===P.intent)e=E[(r+1)%E.length];else if("prev"===P.intent)e=E[(r-1+E.length)%E.length];else if("number"==typeof P.intent){let t=P.intent-1;t>=0&&t<E.length&&(e=E[t])}e&&e!==t&&((0,c.cY)("webterm.tabs.intent.apply",{intent:P.intent,from:t,to:e}),n(e))},[null==P?void 0:P.nonce]);let ef=(0,a.useCallback)(e=>{var t;return null==(t=et.get(e))?void 0:t.isAlive},[et]),ep=(0,a.useMemo)(()=>{if(!q)return"session 미설정";var e=function(e,t){let n=0,r=0,a=0;for(let l of e){let e=t(l);void 0===e?a+=1:e?n+=1:r+=1}return{total:e.length,alive:n,daemonKnownDead:r,daemonUnknown:a}}(E,ef);let t="".concat(e.total," terminal").concat(1===e.total?"":"s");if(!ee)return"".concat(t," \xb7 데몬 상태 미확인");let n=[];return e.alive>0&&n.push("".concat(e.alive," alive")),e.daemonKnownDead>0&&n.push("".concat(e.daemonKnownDead," 종료")),e.daemonUnknown>0&&n.push("".concat(e.daemonUnknown," 데몬이 모름")),n.length>0?"".concat(t," \xb7 ").concat(n.join(" \xb7 ")):t},[q,E,ef,ee]),eg=(0,a.useMemo)(()=>ee&&t?E.filter(e=>e!==t&&void 0===ef(e)):[],[ee,E,ef,t]),eh=(0,a.useCallback)(()=>{if(0===eg.length)return;let e=new Set(eg),t=E.filter(t=>!e.has(t));el(t),(0,c.cY)("webterm.tabs.clean-unknown",{removed:eg.length,remaining:t.length}),U(t)},[eg,el,E]);return(0,r.jsxs)("div",{className:"flex items-center gap-1 border-b bg-background/50 px-2 py-1 text-xs",children:[(0,r.jsxs)("div",{className:"flex flex-1 flex-wrap items-center gap-1",children:[E.map(e=>{let n=e===t,a=et.get(e),l=a?a.isAlive?"bg-emerald-500":"bg-rose-500":"bg-muted-foreground/40",o=function(e){if(!e||!Number.isFinite(e))return"";let t=Math.max(0,Math.floor((Date.now()-e)/1e3));return t<30?"방금":t<3600?"".concat(Math.floor(t/60),"분 전"):t<86400?"".concat(Math.floor(t/3600),"시간 전"):"".concat(Math.floor(t/86400),"일 전")}(null==a?void 0:a.lastOutputAt),s=(null==a?void 0:a.terminalOriginCategory)&&"unknown"!==a.terminalOriginCategory?d(a):"",i="출처: ".concat(d(a)),u=function(e,t){let n="preview-1"===e?"tui-preview":/^preview-\d+$/.test(e)?"web-scratch":e.startsWith("tui:")?"tui-surface":e.startsWith("term-")?"human-terminal":e.startsWith("webterm-")?"web-terminal":e.startsWith("self_")?"harness-run":e.startsWith("agent:")?"agent":e.startsWith("pty_")?"pty":"unknown",r=void 0;switch(n){case"tui-preview":return{text:"TUI 프리뷰",hint:"TUI 프리뷰 페인의 웹 이름 \xb7 ".concat(e),kind:n};case"web-scratch":return{text:e,hint:"이 브라우저가 만든 스크래치 터미널 \xb7 ".concat(e),kind:n};case"tui-surface":return{text:e,hint:"대화형 대시보드 TUI 표면 \xb7 ".concat(e),kind:n};case"human-terminal":return{text:e,hint:"사람이 만든 웹 터미널 \xb7 ".concat(e),kind:n};case"web-terminal":return{text:e,hint:"데몬이 발급한 웹 터미널 \xb7 ".concat(e),kind:n};case"harness-run":return{text:r||e,hint:"하니스 자율 런의 터미널 \xb7 ".concat(e),kind:n};case"agent":return{text:r||e,hint:"서브 에이전트 실행 \xb7 ".concat(e),kind:n};case"pty":return{text:r||e,hint:"PTY \xb7 ".concat(e),kind:n};default:return{text:e,hint:"분류를 모르는 터미널 \xb7 ".concat(e),kind:n}}}(e),c=V.get(e),m=a?"".concat(a.isAlive?"alive":"exited").concat("number"==typeof a.pid?" \xb7 pid ".concat(a.pid):"").concat(o?" \xb7 마지막 출력 ".concat(o):""," \xb7 ").concat(i).concat(a.controller?" \xb7 통제: ".concat(a.controller):""):"데몬 미기동 (선택 시 spawn) \xb7 ".concat(i);return(0,r.jsxs)("span",{className:"inline-flex items-center gap-1 rounded-md border px-2 py-0.5 font-mono ".concat(n?"border-primary bg-primary/10 text-primary":"border-border text-muted-foreground hover:bg-accent"),children:[(0,r.jsx)("span",{className:"h-1.5 w-1.5 shrink-0 rounded-full ".concat(l),title:m,"aria-label":m}),(0,r.jsxs)("button",{type:"button",className:"cursor-pointer",onClick:()=>ei(e),title:"".concat(u.hint," — ").concat(n?"지금 보는 터미널":"눌러서 전환"," \xb7 ").concat(m),"aria-label":"switch to ".concat(e),children:[u.text,s?" \xb7 ".concat(s):"",(null==a?void 0:a.controller)?" \xb7 통제: ".concat(a.controller):""]}),(0,r.jsx)("button",{type:"button",className:"ml-0.5 rounded text-muted-foreground hover:text-rose-500",onClick:t=>{t.stopPropagation(),ec(e)},title:"목록에서 ".concat(e," 탭 빼기 — PTY는 유지합니다"),"aria-label":"remove ".concat(e," locally"),children:"\xd7"}),h(a)&&(0,r.jsx)("button",{type:"button",disabled:void 0!==c&&!c.message,className:"rounded text-muted-foreground hover:text-primary disabled:cursor-wait disabled:opacity-60",onClick:t=>{t.stopPropagation(),ed(e,h(a))},title:"".concat(b(h(a))," ").concat(e),"aria-label":"".concat(h(a)," ").concat(e),children:void 0===c||c.message?b(h(a)):"전환 중…"}),(0,r.jsx)("button",{type:"button",className:"rounded text-muted-foreground hover:text-rose-500",onClick:t=>{t.stopPropagation(),em(e,null==a?void 0:a.ownerRunUsage)},title:"끝내기 ".concat(e),"aria-label":"terminate ".concat(e),children:"끝내기"})]},e)}),(0,r.jsx)("button",{type:"button",className:"rounded-md border border-dashed border-border px-2 py-0.5 text-muted-foreground hover:bg-accent",onClick:()=>{es()},title:"new terminal",children:"+"})]}),[...V.values()].filter(e=>e.message).map((e,t)=>(0,r.jsx)("p",{role:"status",className:"text-muted-foreground",children:e.message},"".concat(e.action,"-").concat(t))),I&&T&&(0,r.jsxs)("span",{className:"ml-2 flex items-center gap-1 rounded bg-rose-500/15 px-1.5 py-0.5 font-medium text-rose-600 dark:text-rose-400",title:"recording in progress",children:[(0,r.jsx)("span",{className:"h-1.5 w-1.5 rounded-full bg-rose-500 animate-pulse","aria-hidden":!0}),"REC"]}),I&&j>1&&(0,r.jsxs)("span",{className:"ml-1 flex items-center gap-1 rounded bg-amber-500/15 px-1.5 py-0.5 font-medium text-amber-700 dark:text-amber-400",title:"".concat(j," devices on this session"),children:[(0,r.jsx)(l.A,{className:"h-3 w-3","aria-hidden":!0}),j]}),(0,r.jsx)("span",{className:"ml-2 text-[11px] text-muted-foreground",title:"터미널 PTY 는 데몬에 상주 — 연결이 끊겨도 유지되고 재접속 시 이어집니다",children:ep}),eg.length>0&&(0,r.jsxs)("button",{type:"button",className:"ml-1 rounded-md border border-dashed border-border px-1.5 py-0.5 text-[11px] text-muted-foreground hover:bg-accent",onClick:eh,title:"데몬이 모르는 탭 ".concat(eg.length,"개를 목록에서 뺍니다 — PTY 는 건드리지 않고, 활성 탭은 남깁니다"),children:["정리 ",eg.length]}),A&&(0,r.jsx)("button",{type:"button",onClick:A,"aria-label":M?"hide terminal chat dock":"show terminal chat dock",title:M?"terminal chat dock 숨기기":"terminal chat dock 보이기",className:"ml-1 rounded-md p-1 ".concat(M?"bg-primary/10 text-primary":"text-muted-foreground hover:bg-accent hover:text-foreground"),children:(0,r.jsx)(o.A,{className:"h-3.5 w-3.5"})}),Y&&(0,r.jsx)("button",{type:"button",onClick:Y,"aria-label":I?"expand panels":"collapse panels",title:I?"패널 펼치기":"패널 접기",className:"ml-1 rounded-md p-1 text-muted-foreground hover:bg-accent hover:text-foreground",children:I?(0,r.jsx)(s.A,{className:"h-3.5 w-3.5"}):(0,r.jsx)(i.A,{className:"h-3.5 w-3.5"})})]})}},38067:(e,t,n)=>{n.d(t,{Dw:()=>g,Kh:()=>u,OZ:()=>s,cl:()=>i,gA:()=>p,hH:()=>d,lH:()=>m,tC:()=>o,x3:()=>c,xu:()=>l});var r=n(28211);function a(e){return"number"==typeof e&&Number.isFinite(e)?Number.isNaN(new Date(e).getTime())?null:e:null}function l(e){let t=new Set,n=[];for(let r of e){let e=c(r);!1===r.hasPty||t.has(e)||(t.add(e),n.push(r))}return n.sort((e,t)=>{var n,r,l,o;let s=a(e.startedAt),i=a(t.startedAt);if(null!==s&&null!==i&&s!==i)return i-s;if(null!==s&&null===i)return -1;if(null===s&&null!==i)return 1;let u=(n=e.id)<(r=t.id)?-1:+(n>r);return 0!==u?u:(l=c(e))<(o=c(t))?-1:+(l>o)})}function o(e){return(0,r.KN)(e)}function s(e){return"number"!=typeof e||!Number.isFinite(e)||Number.isNaN(new Date(e).getTime())?"시작 시각 알 수 없음":new Date(e).toLocaleString()}function i(e,t){return e&&!t?"프로세스 실행 중 \xb7 출력 스트림 열림":e&&t?"프로세스 실행 중 \xb7 출력 스트림 닫힘":e||t?"프로세스 종료 \xb7 출력 스트림 닫힘":"프로세스 종료 \xb7 출력 스트림 열림"}function u(e,t){if(null===e)return null;if("unrequested"===t.status||"loading"===t.status)return{kind:"loading",unreadablePayloadsSummary:null,groups:[]};if("error"===t.status)return{kind:"error",unreadablePayloadsSummary:null,groups:[]};let{lineage:n}=t,r=void 0===n.unreadablePayloads?"읽지 못한 계보 payload 수를 데몬이 알리지 않았습니다.":0===n.unreadablePayloads?"읽지 못한 계보 payload가 0개입니다.":"읽지 못한 계보 payload가 ".concat(n.unreadablePayloads,"개입니다.");return{kind:0===n.groups.length?"empty":"content",unreadablePayloadsSummary:r,groups:n.groups.map(t=>({joinedBy:t.joinedBy,key:t.key,rows:t.rows.map(t=>({ptyId:t.ptyId,kind:t.kind,instance:t.instance,alive:t.alive,startedAt:t.startedAt,closed:!0===t.closed||void 0!==t.closedAt,selected:t.ptyId===e}))}))}}function c(e){var t,n;return"".concat(null!=(n=null==(t=e.sourceRoot)?void 0:t.dbPath)?n:"","\0").concat(e.id)}function d(e,t){let n=t.filter(t=>t.id===e);if(1===n.length){let e=n[0];return{kind:"selected",terminal:e,terminalKey:c(e),candidates:[e],reason:"unique-id"}}return n.length>1?{kind:"ambiguous",terminal:null,terminalKey:null,candidates:n,reason:"duplicate-id"}:{kind:"not-found",terminal:null,terminalKey:null,candidates:[],reason:0===t.length?"empty-terminal-list":"terminal-id-not-found"}}function m(e,t,n,r,a){let l=arguments.length>5&&void 0!==arguments[5]?arguments[5]:"raw",o=arguments.length>6&&void 0!==arguments[6]?arguments[6]:new Map,s=function(e,t,n){let r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"raw",a=arguments.length>4&&void 0!==arguments[4]?arguments[4]:new Map,l=null!==t&&e.some(e=>c(e)===t);return e.map(e=>{var o,s,i;let u=l&&c(e)===t,d=u?"raw"===r?"unrequested"===(i=null!=(o=n.get(c(e)))?o:{status:"unrequested"}).status?{kind:"loading",text:"화면 글자를 아직 불러오지 않았습니다.",frameInfo:null,frameMetadata:null}:"loading"===i.status?{kind:"loading",text:"화면 글자를 불러오는 중…",frameInfo:null,frameMetadata:null}:"error"===i.status?{kind:"error",text:"화면 글자를 불러오지 못했습니다.",frameInfo:null,frameMetadata:null}:0===i.scrollback.length?{kind:"empty",text:"표시할 화면 글자가 없습니다.",frameInfo:null,frameMetadata:null}:{kind:"content",text:i.scrollback,frameInfo:null,frameMetadata:null}:function(e){if("unrequested"===e.status)return{kind:"loading",text:"렌더 화면을 아직 불러오지 않았습니다.",frameInfo:null,frameMetadata:null};if("loading"===e.status)return{kind:"loading",text:"렌더 화면을 불러오는 중…",frameInfo:null,frameMetadata:null};if("error"===e.status)return{kind:"error",text:"렌더 화면을 불러오지 못했습니다.",frameInfo:null,frameMetadata:null};let[t,...n]=e.frame.split("\n"),r=n.join("\n"),a={frameAt:e.frameAt,frameSource:e.frameSource};return 0===r.length?{kind:"empty",text:"표시할 렌더 화면이 없습니다.",frameInfo:t||null,frameMetadata:a}:{kind:"content",text:r,frameInfo:t||null,frameMetadata:a}}(null!=(s=a.get(c(e)))?s:{status:"unrequested"}):null;return{terminal:e,selected:u,scrollback:d,view:null===d?null:{visible:!0,modes:[{mode:"raw",label:"원시 글자",selected:"raw"===r},{mode:"render",label:"렌더 화면",selected:"render"===r}],display:d}}})}(t,r,a,l,o);return{includeAll:e,scopeSummary:["number"!=typeof(null==n?void 0:n.hiddenDead)?null:0===n.hiddenDead?"숨긴 종료 PTY가 0개입니다.":"숨긴 종료 PTY가 ".concat(n.hiddenDead,"개입니다."),function(e){let t=e.filter(e=>{let{terminal:t}=e;return"terminated-live-owner"===t.ownerRunUsage}).length;return"소유 런이 끝났는데 터미널이 남아 있는 행이 ".concat(t,"개입니다.")}(s)].filter(e=>null!==e).join(" "),rows:s}}function f(e,t){return e.observedAt-t.observedAt||e.logId-t.logId}function p(e){var t,n,r;let a=new Map;for(let n of e){let e=function(e){if("headless.progress-frame"!==e.event||!e.data||"object"!=typeof e.data)return null;let t=e.data;if("string"!=typeof t.ptyId||"string"!=typeof t.runId||"string"!=typeof t.planId||!Number.isSafeInteger(t.seq)||t.seq<1||"string"!=typeof t.humanLine)return null;let n=Date.parse(e.ts);return{ptyId:t.ptyId,runId:t.runId,planId:t.planId,seq:t.seq,humanLine:t.humanLine,observedAt:Number.isFinite(n)?n:0,logId:e.id}}(n);if(!e)continue;let r=null!=(t=a.get(e.ptyId))?t:[];r.push(e),a.set(e.ptyId,r)}let l=new Map;for(let[e,t]of a){t.sort(f);let a=t.at(-1),o=new Map;for(let e of t){let t="".concat(e.runId,"\0").concat(e.planId),r=null!=(n=o.get(t))?n:new Set;r.add(e.seq),o.set(t,r)}let s=[...o.values()].some(e=>{let t=[...e].sort((e,t)=>e-t);return t.some((e,n)=>0===n&&1!==e||n>0&&e-t[n-1]!=1)});l.set(e,{line:a.humanLine,status:(r=a.humanLine,/^\s*●/.test(r))?"complete":"running",hasMissingFrames:s})}return l}function g(e){var t;let n=null==(t=e.storedId)?void 0:t.trim();if(n)return{terminalId:n,reason:"stored"};let r=e.terminals.find(e=>!0===e.alive&&"web-terminal"===e.cmd);return r?{terminalId:r.id,reason:"live-pty"}:void 0!==e.fallbackId&&null!==e.fallbackId?{terminalId:e.fallbackId,reason:"fallback"}:{terminalId:null,reason:"no-terminals"}}}}]);