loopsy 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (262) hide show
  1. package/LICENSE +190 -0
  2. package/README.md +425 -0
  3. package/dist/cli/commands/connect.d.ts +2 -0
  4. package/dist/cli/commands/connect.d.ts.map +1 -0
  5. package/dist/cli/commands/connect.js +120 -0
  6. package/dist/cli/commands/connect.js.map +1 -0
  7. package/dist/cli/commands/context.d.ts +2 -0
  8. package/dist/cli/commands/context.d.ts.map +1 -0
  9. package/dist/cli/commands/context.js +39 -0
  10. package/dist/cli/commands/context.js.map +1 -0
  11. package/dist/cli/commands/daemon.d.ts +4 -0
  12. package/dist/cli/commands/daemon.d.ts.map +1 -0
  13. package/dist/cli/commands/daemon.js +55 -0
  14. package/dist/cli/commands/daemon.js.map +1 -0
  15. package/dist/cli/commands/dashboard.d.ts +2 -0
  16. package/dist/cli/commands/dashboard.d.ts.map +1 -0
  17. package/dist/cli/commands/dashboard.js +24 -0
  18. package/dist/cli/commands/dashboard.js.map +1 -0
  19. package/dist/cli/commands/doctor.d.ts +2 -0
  20. package/dist/cli/commands/doctor.d.ts.map +1 -0
  21. package/dist/cli/commands/doctor.js +130 -0
  22. package/dist/cli/commands/doctor.js.map +1 -0
  23. package/dist/cli/commands/exec.d.ts +2 -0
  24. package/dist/cli/commands/exec.d.ts.map +1 -0
  25. package/dist/cli/commands/exec.js +34 -0
  26. package/dist/cli/commands/exec.js.map +1 -0
  27. package/dist/cli/commands/init.d.ts +2 -0
  28. package/dist/cli/commands/init.d.ts.map +1 -0
  29. package/dist/cli/commands/init.js +71 -0
  30. package/dist/cli/commands/init.js.map +1 -0
  31. package/dist/cli/commands/key.d.ts +2 -0
  32. package/dist/cli/commands/key.d.ts.map +1 -0
  33. package/dist/cli/commands/key.js +39 -0
  34. package/dist/cli/commands/key.js.map +1 -0
  35. package/dist/cli/commands/logs.d.ts +2 -0
  36. package/dist/cli/commands/logs.d.ts.map +1 -0
  37. package/dist/cli/commands/logs.js +26 -0
  38. package/dist/cli/commands/logs.js.map +1 -0
  39. package/dist/cli/commands/mcp.d.ts +4 -0
  40. package/dist/cli/commands/mcp.d.ts.map +1 -0
  41. package/dist/cli/commands/mcp.js +70 -0
  42. package/dist/cli/commands/mcp.js.map +1 -0
  43. package/dist/cli/commands/pair.d.ts +6 -0
  44. package/dist/cli/commands/pair.d.ts.map +1 -0
  45. package/dist/cli/commands/pair.js +208 -0
  46. package/dist/cli/commands/pair.js.map +1 -0
  47. package/dist/cli/commands/peers.d.ts +2 -0
  48. package/dist/cli/commands/peers.d.ts.map +1 -0
  49. package/dist/cli/commands/peers.js +29 -0
  50. package/dist/cli/commands/peers.js.map +1 -0
  51. package/dist/cli/commands/service/linux.d.ts +7 -0
  52. package/dist/cli/commands/service/linux.d.ts.map +1 -0
  53. package/dist/cli/commands/service/linux.js +86 -0
  54. package/dist/cli/commands/service/linux.js.map +1 -0
  55. package/dist/cli/commands/service/macos.d.ts +7 -0
  56. package/dist/cli/commands/service/macos.d.ts.map +1 -0
  57. package/dist/cli/commands/service/macos.js +83 -0
  58. package/dist/cli/commands/service/macos.js.map +1 -0
  59. package/dist/cli/commands/service/windows.d.ts +7 -0
  60. package/dist/cli/commands/service/windows.d.ts.map +1 -0
  61. package/dist/cli/commands/service/windows.js +52 -0
  62. package/dist/cli/commands/service/windows.js.map +1 -0
  63. package/dist/cli/commands/service.d.ts +4 -0
  64. package/dist/cli/commands/service.d.ts.map +1 -0
  65. package/dist/cli/commands/service.js +68 -0
  66. package/dist/cli/commands/service.js.map +1 -0
  67. package/dist/cli/commands/session.d.ts +8 -0
  68. package/dist/cli/commands/session.d.ts.map +1 -0
  69. package/dist/cli/commands/session.js +270 -0
  70. package/dist/cli/commands/session.js.map +1 -0
  71. package/dist/cli/commands/transfer.d.ts +3 -0
  72. package/dist/cli/commands/transfer.d.ts.map +1 -0
  73. package/dist/cli/commands/transfer.js +57 -0
  74. package/dist/cli/commands/transfer.js.map +1 -0
  75. package/dist/cli/index.d.ts +3 -0
  76. package/dist/cli/index.d.ts.map +1 -0
  77. package/dist/cli/index.js +89 -0
  78. package/dist/cli/index.js.map +1 -0
  79. package/dist/cli/package-root.d.ts +27 -0
  80. package/dist/cli/package-root.d.ts.map +1 -0
  81. package/dist/cli/package-root.js +54 -0
  82. package/dist/cli/package-root.js.map +1 -0
  83. package/dist/cli/utils.d.ts +11 -0
  84. package/dist/cli/utils.d.ts.map +1 -0
  85. package/dist/cli/utils.js +48 -0
  86. package/dist/cli/utils.js.map +1 -0
  87. package/dist/daemon/config.d.ts +4 -0
  88. package/dist/daemon/config.d.ts.map +1 -0
  89. package/dist/daemon/config.js +58 -0
  90. package/dist/daemon/config.js.map +1 -0
  91. package/dist/daemon/hooks/permission-hook.mjs +108 -0
  92. package/dist/daemon/index.d.ts +3 -0
  93. package/dist/daemon/index.d.ts.map +1 -0
  94. package/dist/daemon/index.js +3 -0
  95. package/dist/daemon/index.js.map +1 -0
  96. package/dist/daemon/main.d.ts +3 -0
  97. package/dist/daemon/main.d.ts.map +1 -0
  98. package/dist/daemon/main.js +28 -0
  99. package/dist/daemon/main.js.map +1 -0
  100. package/dist/daemon/middleware/auth.d.ts +3 -0
  101. package/dist/daemon/middleware/auth.d.ts.map +1 -0
  102. package/dist/daemon/middleware/auth.js +22 -0
  103. package/dist/daemon/middleware/auth.js.map +1 -0
  104. package/dist/daemon/routes/ai-tasks.d.ts +4 -0
  105. package/dist/daemon/routes/ai-tasks.d.ts.map +1 -0
  106. package/dist/daemon/routes/ai-tasks.js +146 -0
  107. package/dist/daemon/routes/ai-tasks.js.map +1 -0
  108. package/dist/daemon/routes/context.d.ts +4 -0
  109. package/dist/daemon/routes/context.d.ts.map +1 -0
  110. package/dist/daemon/routes/context.js +49 -0
  111. package/dist/daemon/routes/context.js.map +1 -0
  112. package/dist/daemon/routes/execute.d.ts +4 -0
  113. package/dist/daemon/routes/execute.d.ts.map +1 -0
  114. package/dist/daemon/routes/execute.js +74 -0
  115. package/dist/daemon/routes/execute.js.map +1 -0
  116. package/dist/daemon/routes/health.d.ts +15 -0
  117. package/dist/daemon/routes/health.d.ts.map +1 -0
  118. package/dist/daemon/routes/health.js +38 -0
  119. package/dist/daemon/routes/health.js.map +1 -0
  120. package/dist/daemon/routes/pair.d.ts +11 -0
  121. package/dist/daemon/routes/pair.d.ts.map +1 -0
  122. package/dist/daemon/routes/pair.js +149 -0
  123. package/dist/daemon/routes/pair.js.map +1 -0
  124. package/dist/daemon/routes/peers.d.ts +5 -0
  125. package/dist/daemon/routes/peers.d.ts.map +1 -0
  126. package/dist/daemon/routes/peers.js +69 -0
  127. package/dist/daemon/routes/peers.js.map +1 -0
  128. package/dist/daemon/routes/transfer.d.ts +4 -0
  129. package/dist/daemon/routes/transfer.d.ts.map +1 -0
  130. package/dist/daemon/routes/transfer.js +135 -0
  131. package/dist/daemon/routes/transfer.js.map +1 -0
  132. package/dist/daemon/server.d.ts +8 -0
  133. package/dist/daemon/server.d.ts.map +1 -0
  134. package/dist/daemon/server.js +170 -0
  135. package/dist/daemon/server.js.map +1 -0
  136. package/dist/daemon/services/ai-task-manager.d.ts +56 -0
  137. package/dist/daemon/services/ai-task-manager.d.ts.map +1 -0
  138. package/dist/daemon/services/ai-task-manager.js +491 -0
  139. package/dist/daemon/services/ai-task-manager.js.map +1 -0
  140. package/dist/daemon/services/audit-logger.d.ts +16 -0
  141. package/dist/daemon/services/audit-logger.d.ts.map +1 -0
  142. package/dist/daemon/services/audit-logger.js +23 -0
  143. package/dist/daemon/services/audit-logger.js.map +1 -0
  144. package/dist/daemon/services/context-store.d.ts +17 -0
  145. package/dist/daemon/services/context-store.d.ts.map +1 -0
  146. package/dist/daemon/services/context-store.js +97 -0
  147. package/dist/daemon/services/context-store.js.map +1 -0
  148. package/dist/daemon/services/job-manager.d.ts +19 -0
  149. package/dist/daemon/services/job-manager.d.ts.map +1 -0
  150. package/dist/daemon/services/job-manager.js +92 -0
  151. package/dist/daemon/services/job-manager.js.map +1 -0
  152. package/dist/daemon/services/tls-manager.d.ts +33 -0
  153. package/dist/daemon/services/tls-manager.d.ts.map +1 -0
  154. package/dist/daemon/services/tls-manager.js +114 -0
  155. package/dist/daemon/services/tls-manager.js.map +1 -0
  156. package/dist/daemon/utils/which.d.ts +2 -0
  157. package/dist/daemon/utils/which.d.ts.map +1 -0
  158. package/dist/daemon/utils/which.js +18 -0
  159. package/dist/daemon/utils/which.js.map +1 -0
  160. package/dist/dashboard/config.d.ts +8 -0
  161. package/dist/dashboard/config.d.ts.map +1 -0
  162. package/dist/dashboard/config.js +22 -0
  163. package/dist/dashboard/config.js.map +1 -0
  164. package/dist/dashboard/public/app.js +120 -0
  165. package/dist/dashboard/public/icon-192.png +0 -0
  166. package/dist/dashboard/public/icon-512.png +0 -0
  167. package/dist/dashboard/public/index.html +85 -0
  168. package/dist/dashboard/public/manifest.json +12 -0
  169. package/dist/dashboard/public/style.css +784 -0
  170. package/dist/dashboard/public/sw.js +31 -0
  171. package/dist/dashboard/public/views/ai-tasks.js +679 -0
  172. package/dist/dashboard/public/views/context.js +167 -0
  173. package/dist/dashboard/public/views/messages.js +263 -0
  174. package/dist/dashboard/public/views/overview.js +228 -0
  175. package/dist/dashboard/public/views/peers.js +136 -0
  176. package/dist/dashboard/public/views/terminal.js +153 -0
  177. package/dist/dashboard/routes/ai-tasks.d.ts +3 -0
  178. package/dist/dashboard/routes/ai-tasks.d.ts.map +1 -0
  179. package/dist/dashboard/routes/ai-tasks.js +193 -0
  180. package/dist/dashboard/routes/ai-tasks.js.map +1 -0
  181. package/dist/dashboard/routes/messages.d.ts +3 -0
  182. package/dist/dashboard/routes/messages.d.ts.map +1 -0
  183. package/dist/dashboard/routes/messages.js +137 -0
  184. package/dist/dashboard/routes/messages.js.map +1 -0
  185. package/dist/dashboard/routes/peer-utils.d.ts +17 -0
  186. package/dist/dashboard/routes/peer-utils.d.ts.map +1 -0
  187. package/dist/dashboard/routes/peer-utils.js +193 -0
  188. package/dist/dashboard/routes/peer-utils.js.map +1 -0
  189. package/dist/dashboard/routes/peers-all.d.ts +3 -0
  190. package/dist/dashboard/routes/peers-all.d.ts.map +1 -0
  191. package/dist/dashboard/routes/peers-all.js +8 -0
  192. package/dist/dashboard/routes/peers-all.js.map +1 -0
  193. package/dist/dashboard/routes/proxy.d.ts +3 -0
  194. package/dist/dashboard/routes/proxy.d.ts.map +1 -0
  195. package/dist/dashboard/routes/proxy.js +59 -0
  196. package/dist/dashboard/routes/proxy.js.map +1 -0
  197. package/dist/dashboard/routes/sessions.d.ts +3 -0
  198. package/dist/dashboard/routes/sessions.d.ts.map +1 -0
  199. package/dist/dashboard/routes/sessions.js +64 -0
  200. package/dist/dashboard/routes/sessions.js.map +1 -0
  201. package/dist/dashboard/routes/sse.d.ts +3 -0
  202. package/dist/dashboard/routes/sse.d.ts.map +1 -0
  203. package/dist/dashboard/routes/sse.js +49 -0
  204. package/dist/dashboard/routes/sse.js.map +1 -0
  205. package/dist/dashboard/routes/status.d.ts +3 -0
  206. package/dist/dashboard/routes/status.d.ts.map +1 -0
  207. package/dist/dashboard/routes/status.js +38 -0
  208. package/dist/dashboard/routes/status.js.map +1 -0
  209. package/dist/dashboard/server.d.ts +3 -0
  210. package/dist/dashboard/server.d.ts.map +1 -0
  211. package/dist/dashboard/server.js +77 -0
  212. package/dist/dashboard/server.js.map +1 -0
  213. package/dist/dashboard/session-manager.d.ts +17 -0
  214. package/dist/dashboard/session-manager.d.ts.map +1 -0
  215. package/dist/dashboard/session-manager.js +225 -0
  216. package/dist/dashboard/session-manager.js.map +1 -0
  217. package/dist/discovery/health-checker.d.ts +15 -0
  218. package/dist/discovery/health-checker.d.ts.map +1 -0
  219. package/dist/discovery/health-checker.js +47 -0
  220. package/dist/discovery/health-checker.js.map +1 -0
  221. package/dist/discovery/index.d.ts +4 -0
  222. package/dist/discovery/index.d.ts.map +1 -0
  223. package/dist/discovery/index.js +4 -0
  224. package/dist/discovery/index.js.map +1 -0
  225. package/dist/discovery/mdns.d.ts +21 -0
  226. package/dist/discovery/mdns.d.ts.map +1 -0
  227. package/dist/discovery/mdns.js +83 -0
  228. package/dist/discovery/mdns.js.map +1 -0
  229. package/dist/discovery/peer-registry.d.ts +18 -0
  230. package/dist/discovery/peer-registry.d.ts.map +1 -0
  231. package/dist/discovery/peer-registry.js +81 -0
  232. package/dist/discovery/peer-registry.js.map +1 -0
  233. package/dist/mcp-server/daemon-client.d.ts +69 -0
  234. package/dist/mcp-server/daemon-client.d.ts.map +1 -0
  235. package/dist/mcp-server/daemon-client.js +281 -0
  236. package/dist/mcp-server/daemon-client.js.map +1 -0
  237. package/dist/mcp-server/index.d.ts +3 -0
  238. package/dist/mcp-server/index.d.ts.map +1 -0
  239. package/dist/mcp-server/index.js +406 -0
  240. package/dist/mcp-server/index.js.map +1 -0
  241. package/dist/protocol/constants.d.ts +66 -0
  242. package/dist/protocol/constants.d.ts.map +1 -0
  243. package/dist/protocol/constants.js +66 -0
  244. package/dist/protocol/constants.js.map +1 -0
  245. package/dist/protocol/errors.d.ts +47 -0
  246. package/dist/protocol/errors.d.ts.map +1 -0
  247. package/dist/protocol/errors.js +62 -0
  248. package/dist/protocol/errors.js.map +1 -0
  249. package/dist/protocol/index.d.ts +5 -0
  250. package/dist/protocol/index.d.ts.map +1 -0
  251. package/dist/protocol/index.js +5 -0
  252. package/dist/protocol/index.js.map +1 -0
  253. package/dist/protocol/schemas.d.ts +209 -0
  254. package/dist/protocol/schemas.d.ts.map +1 -0
  255. package/dist/protocol/schemas.js +115 -0
  256. package/dist/protocol/schemas.js.map +1 -0
  257. package/dist/protocol/types.d.ts +302 -0
  258. package/dist/protocol/types.d.ts.map +1 -0
  259. package/dist/protocol/types.js +2 -0
  260. package/dist/protocol/types.js.map +1 -0
  261. package/package.json +50 -0
  262. package/scripts/postinstall.mjs +42 -0
@@ -0,0 +1,784 @@
1
+ /* ═══════════════════════════════════════════
2
+ LOOPSY // DASHBOARD — Design System
3
+ ═══════════════════════════════════════════ */
4
+
5
+ @import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;700&family=Inter:wght@400;500;600&display=swap');
6
+
7
+ :root {
8
+ --bg-void: #050508;
9
+ --bg-base: #0a0d14;
10
+ --bg-surface: #0f1420;
11
+ --bg-elevated: #151b2e;
12
+ --bg-input: #0d1117;
13
+
14
+ --border-dim: #1a2235;
15
+ --border-normal: #1e2d45;
16
+ --border-bright: #00d4ff33;
17
+
18
+ --cyan: #00d4ff;
19
+ --cyan-dim: #00d4ff80;
20
+ --cyan-glow: 0 0 10px #00d4ff40, 0 0 30px #00d4ff20;
21
+ --cyan-glow-strong: 0 0 10px #00d4ff, 0 0 30px #00d4ff80;
22
+
23
+ --green: #00ff88;
24
+ --green-dim: #00ff8880;
25
+ --green-glow: 0 0 10px #00ff8840, 0 0 25px #00ff8820;
26
+
27
+ --amber: #ffb800;
28
+ --amber-dim: #ffb80080;
29
+
30
+ --red: #ff3366;
31
+ --red-dim: #ff336680;
32
+ --red-glow: 0 0 10px #ff336640;
33
+
34
+ --text-primary: #e2e8f0;
35
+ --text-secondary: #7a8899;
36
+ --text-muted: #3d4f66;
37
+ --text-accent: #00d4ff;
38
+ --text-code: #00ff88;
39
+
40
+ --font-mono: 'JetBrains Mono', 'Fira Code', 'Cascadia Code', 'Consolas', monospace;
41
+ --font-ui: 'Inter', 'SF Pro Display', system-ui, sans-serif;
42
+ }
43
+
44
+ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
45
+
46
+ html { font-size: 16px; }
47
+
48
+ body {
49
+ background: var(--bg-void);
50
+ color: var(--text-primary);
51
+ font-family: var(--font-ui);
52
+ min-height: 100dvh;
53
+ overflow-x: hidden;
54
+ -webkit-font-smoothing: antialiased;
55
+ }
56
+
57
+ /* ═══ Layout ═══ */
58
+ .app {
59
+ display: grid;
60
+ grid-template-areas: "header" "main";
61
+ grid-template-rows: 3.25rem 1fr;
62
+ min-height: 100dvh;
63
+ }
64
+
65
+ @media (min-width: 768px) {
66
+ .app {
67
+ grid-template-areas: "nav header" "nav main";
68
+ grid-template-columns: 200px 1fr;
69
+ grid-template-rows: 3.25rem 1fr;
70
+ }
71
+ }
72
+
73
+ /* ═══ Header ═══ */
74
+ .header {
75
+ grid-area: header;
76
+ background: var(--bg-surface);
77
+ border-bottom: 1px solid var(--border-dim);
78
+ display: flex;
79
+ align-items: center;
80
+ justify-content: space-between;
81
+ padding: 0 1.25rem;
82
+ z-index: 10;
83
+ }
84
+
85
+ .logo {
86
+ font-family: var(--font-mono);
87
+ font-size: 0.8rem;
88
+ font-weight: 700;
89
+ color: var(--cyan);
90
+ letter-spacing: 0.2em;
91
+ text-transform: uppercase;
92
+ text-shadow: 0 0 20px var(--cyan-dim);
93
+ }
94
+
95
+ .header-meta {
96
+ font-family: var(--font-mono);
97
+ font-size: 0.7rem;
98
+ color: var(--text-muted);
99
+ }
100
+
101
+ /* ═══ Navigation — Sidebar (desktop) ═══ */
102
+ .nav {
103
+ grid-area: nav;
104
+ background: var(--bg-surface);
105
+ border-right: 1px solid var(--border-dim);
106
+ padding: 0.75rem 0;
107
+ display: none;
108
+ }
109
+
110
+ @media (min-width: 768px) {
111
+ .nav { display: block; }
112
+ }
113
+
114
+ .nav-item {
115
+ display: flex;
116
+ align-items: center;
117
+ gap: 0.75rem;
118
+ padding: 0.6rem 1rem;
119
+ color: var(--text-secondary);
120
+ font-family: var(--font-ui);
121
+ font-size: 0.8rem;
122
+ font-weight: 500;
123
+ letter-spacing: 0.04em;
124
+ cursor: pointer;
125
+ border-left: 2px solid transparent;
126
+ transition: all 0.12s;
127
+ user-select: none;
128
+ }
129
+
130
+ .nav-item:hover { color: var(--text-primary); background: var(--bg-elevated); }
131
+
132
+ .nav-item.active {
133
+ color: var(--cyan);
134
+ border-left-color: var(--cyan);
135
+ background: linear-gradient(90deg, rgba(0,212,255,0.08) 0%, transparent 100%);
136
+ }
137
+
138
+ .nav-icon { width: 1.25rem; text-align: center; display: flex; align-items: center; justify-content: center; }
139
+ .nav-icon svg { width: 18px; height: 18px; flex-shrink: 0; }
140
+
141
+ /* ═══ Navigation — Bottom tabs (mobile) ═══ */
142
+ .mobile-nav {
143
+ position: fixed;
144
+ bottom: 0;
145
+ left: 0;
146
+ right: 0;
147
+ height: 56px;
148
+ background: var(--bg-surface);
149
+ border-top: 1px solid var(--border-dim);
150
+ display: flex;
151
+ z-index: 100;
152
+ }
153
+
154
+ @media (min-width: 768px) {
155
+ .mobile-nav { display: none; }
156
+ }
157
+
158
+ .mobile-nav-item {
159
+ flex: 1;
160
+ display: flex;
161
+ flex-direction: column;
162
+ align-items: center;
163
+ justify-content: center;
164
+ gap: 0.15rem;
165
+ color: var(--text-muted);
166
+ font-family: var(--font-ui);
167
+ font-size: 0.6rem;
168
+ font-weight: 500;
169
+ letter-spacing: 0.06em;
170
+ text-transform: uppercase;
171
+ cursor: pointer;
172
+ border-top: 2px solid transparent;
173
+ transition: all 0.12s;
174
+ }
175
+
176
+ .mobile-nav-item:hover { color: var(--text-secondary); }
177
+ .mobile-nav-item.active { color: var(--cyan); border-top-color: var(--cyan); }
178
+ .mobile-nav-icon { display: flex; align-items: center; justify-content: center; }
179
+ .mobile-nav-icon svg { width: 18px; height: 18px; }
180
+
181
+ /* ═══ Main Content ═══ */
182
+ .main {
183
+ grid-area: main;
184
+ padding: 1rem;
185
+ overflow-y: auto;
186
+ padding-bottom: 70px; /* mobile nav */
187
+ }
188
+
189
+ @media (min-width: 768px) {
190
+ .main { padding: 1.5rem; padding-bottom: 1.5rem; }
191
+ }
192
+
193
+ /* ═══ Section Headers ═══ */
194
+ .section-header {
195
+ font-family: var(--font-mono);
196
+ font-size: 0.7rem;
197
+ font-weight: 500;
198
+ color: var(--text-secondary);
199
+ letter-spacing: 0.15em;
200
+ text-transform: uppercase;
201
+ margin-bottom: 1rem;
202
+ }
203
+
204
+ /* ═══ Stats Row ═══ */
205
+ .stats-row {
206
+ display: grid;
207
+ grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
208
+ gap: 0.75rem;
209
+ margin-bottom: 1.25rem;
210
+ }
211
+
212
+ .stat-card {
213
+ background: var(--bg-surface);
214
+ border: 1px solid var(--border-normal);
215
+ border-radius: 4px;
216
+ padding: 0.75rem 1rem;
217
+ text-align: center;
218
+ }
219
+
220
+ .stat-value {
221
+ font-family: var(--font-mono);
222
+ font-size: 1.75rem;
223
+ font-weight: 700;
224
+ color: var(--cyan);
225
+ text-shadow: 0 0 20px var(--cyan-dim);
226
+ line-height: 1.2;
227
+ }
228
+
229
+ .stat-label {
230
+ font-family: var(--font-ui);
231
+ font-size: 0.65rem;
232
+ color: var(--text-muted);
233
+ letter-spacing: 0.1em;
234
+ text-transform: uppercase;
235
+ margin-top: 0.25rem;
236
+ }
237
+
238
+ /* ═══ Session Cards Grid ═══ */
239
+ .session-grid {
240
+ display: grid;
241
+ grid-template-columns: 1fr;
242
+ gap: 0.75rem;
243
+ }
244
+
245
+ @media (min-width: 640px) { .session-grid { grid-template-columns: repeat(2, 1fr); } }
246
+ @media (min-width: 1024px) { .session-grid { grid-template-columns: repeat(3, 1fr); } }
247
+
248
+ .session-card {
249
+ background: var(--bg-surface);
250
+ border: 1px solid var(--border-normal);
251
+ border-left: 3px solid var(--cyan-dim);
252
+ border-radius: 4px;
253
+ padding: 0.875rem 1rem;
254
+ transition: border-color 0.15s, box-shadow 0.15s;
255
+ cursor: default;
256
+ }
257
+
258
+ .session-card:hover {
259
+ border-color: var(--border-bright);
260
+ box-shadow: var(--cyan-glow);
261
+ }
262
+
263
+ .session-card.running { border-left-color: var(--green); }
264
+ .session-card.stopped { border-left-color: var(--red-dim); opacity: 0.65; }
265
+
266
+ .session-card-header {
267
+ display: flex;
268
+ align-items: center;
269
+ justify-content: space-between;
270
+ margin-bottom: 0.5rem;
271
+ }
272
+
273
+ .session-name {
274
+ font-family: var(--font-mono);
275
+ font-size: 0.85rem;
276
+ font-weight: 600;
277
+ color: var(--text-primary);
278
+ display: flex;
279
+ align-items: center;
280
+ gap: 0.5rem;
281
+ }
282
+
283
+ .session-meta {
284
+ font-family: var(--font-mono);
285
+ font-size: 0.7rem;
286
+ color: var(--text-secondary);
287
+ line-height: 1.6;
288
+ }
289
+
290
+ .session-meta span { color: var(--text-muted); }
291
+
292
+ /* ═══ Status Dot ═══ */
293
+ @keyframes pulse-online {
294
+ 0%, 100% { box-shadow: 0 0 0 0 var(--green-dim), 0 0 6px var(--green); }
295
+ 50% { box-shadow: 0 0 0 5px transparent, 0 0 10px var(--green); }
296
+ }
297
+
298
+ .status-dot {
299
+ width: 8px;
300
+ height: 8px;
301
+ border-radius: 50%;
302
+ display: inline-block;
303
+ flex-shrink: 0;
304
+ }
305
+
306
+ .status-dot.online {
307
+ background: var(--green);
308
+ animation: pulse-online 2s ease-in-out infinite;
309
+ }
310
+
311
+ .status-dot.offline {
312
+ background: var(--red-dim);
313
+ box-shadow: var(--red-glow);
314
+ }
315
+
316
+ .status-dot.unknown {
317
+ background: var(--amber-dim);
318
+ }
319
+
320
+ /* ═══ Buttons ═══ */
321
+ .btn {
322
+ font-family: var(--font-mono);
323
+ font-size: 0.7rem;
324
+ font-weight: 500;
325
+ letter-spacing: 0.1em;
326
+ text-transform: uppercase;
327
+ padding: 0.35rem 0.75rem;
328
+ border-radius: 3px;
329
+ border: 1px solid;
330
+ background: transparent;
331
+ cursor: pointer;
332
+ transition: all 0.15s;
333
+ white-space: nowrap;
334
+ }
335
+
336
+ .btn:disabled { opacity: 0.4; cursor: not-allowed; }
337
+
338
+ .btn-primary { border-color: var(--cyan); color: var(--cyan); }
339
+ .btn-primary:hover:not(:disabled) { background: rgba(0,212,255,0.12); box-shadow: var(--cyan-glow); }
340
+
341
+ .btn-danger { border-color: var(--red); color: var(--red); }
342
+ .btn-danger:hover:not(:disabled) { background: rgba(255,51,102,0.12); box-shadow: var(--red-glow); }
343
+
344
+ .btn-success { border-color: var(--green); color: var(--green); }
345
+ .btn-success:hover:not(:disabled) { background: rgba(0,255,136,0.10); box-shadow: var(--green-glow); }
346
+
347
+ .btn-warning { border-color: var(--amber); color: var(--amber); }
348
+ .btn-warning:hover:not(:disabled) { background: rgba(255,184,0,0.12); }
349
+
350
+ .btn-sm { font-size: 0.6rem; padding: 0.2rem 0.5rem; }
351
+
352
+ /* ═══ Inputs ═══ */
353
+ .input, .textarea, select {
354
+ background: var(--bg-input);
355
+ border: 1px solid var(--border-normal);
356
+ border-radius: 3px;
357
+ color: var(--text-primary);
358
+ font-family: var(--font-mono);
359
+ font-size: 0.8rem;
360
+ padding: 0.45rem 0.65rem;
361
+ width: 100%;
362
+ transition: border-color 0.15s, box-shadow 0.15s;
363
+ outline: none;
364
+ }
365
+
366
+ .input:focus, .textarea:focus, select:focus {
367
+ border-color: var(--cyan);
368
+ box-shadow: 0 0 0 1px var(--cyan-dim), var(--cyan-glow);
369
+ }
370
+
371
+ .textarea { resize: vertical; min-height: 3rem; }
372
+
373
+ select {
374
+ appearance: none;
375
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%237a8899' d='M6 8L1 3h10z'/%3E%3C/svg%3E");
376
+ background-repeat: no-repeat;
377
+ background-position: right 0.5rem center;
378
+ padding-right: 1.5rem;
379
+ }
380
+
381
+ select option { background: var(--bg-base); color: var(--text-primary); }
382
+
383
+ .form-row {
384
+ display: flex;
385
+ gap: 0.5rem;
386
+ align-items: center;
387
+ margin-bottom: 0.75rem;
388
+ flex-wrap: wrap;
389
+ }
390
+
391
+ .form-label {
392
+ font-family: var(--font-ui);
393
+ font-size: 0.65rem;
394
+ color: var(--text-muted);
395
+ letter-spacing: 0.08em;
396
+ text-transform: uppercase;
397
+ margin-bottom: 0.25rem;
398
+ }
399
+
400
+ .form-group { flex: 1; min-width: 120px; }
401
+
402
+ /* ═══ Terminal ═══ */
403
+ .terminal {
404
+ background: var(--bg-void);
405
+ border: 1px solid var(--border-dim);
406
+ border-radius: 4px;
407
+ font-family: var(--font-mono);
408
+ font-size: 0.78rem;
409
+ line-height: 1.65;
410
+ padding: 0.875rem;
411
+ overflow-y: auto;
412
+ max-height: calc(100dvh - 280px);
413
+ min-height: 200px;
414
+ background-image: repeating-linear-gradient(
415
+ 0deg, transparent, transparent 1px,
416
+ rgba(0,0,0,0.03) 1px, rgba(0,0,0,0.03) 2px
417
+ );
418
+ }
419
+
420
+ .terminal-line { word-break: break-all; }
421
+ .terminal-line.stdout { color: var(--text-code); }
422
+ .terminal-line.stderr { color: var(--amber); }
423
+ .terminal-line.exit-ok { color: var(--green); font-weight: 500; }
424
+ .terminal-line.exit-err { color: var(--red); font-weight: 500; }
425
+ .terminal-line.system { color: var(--text-muted); font-style: italic; }
426
+
427
+ .terminal-cursor {
428
+ display: inline-block;
429
+ width: 0.55em;
430
+ height: 1.1em;
431
+ background: var(--cyan);
432
+ animation: blink 1s step-end infinite;
433
+ vertical-align: text-bottom;
434
+ }
435
+
436
+ @keyframes blink {
437
+ 0%, 100% { opacity: 1; }
438
+ 50% { opacity: 0; }
439
+ }
440
+
441
+ .prompt-bar {
442
+ display: flex;
443
+ align-items: center;
444
+ gap: 0.5rem;
445
+ background: var(--bg-input);
446
+ border: 1px solid var(--border-normal);
447
+ border-radius: 3px;
448
+ padding: 0.35rem 0.75rem;
449
+ margin-bottom: 0.75rem;
450
+ transition: border-color 0.15s;
451
+ }
452
+
453
+ .prompt-bar:focus-within {
454
+ border-color: var(--cyan);
455
+ box-shadow: var(--cyan-glow);
456
+ }
457
+
458
+ .prompt-prefix {
459
+ color: var(--cyan);
460
+ font-family: var(--font-mono);
461
+ font-size: 0.8rem;
462
+ font-weight: 500;
463
+ user-select: none;
464
+ white-space: nowrap;
465
+ }
466
+
467
+ .prompt-input {
468
+ flex: 1;
469
+ background: transparent;
470
+ border: none;
471
+ color: var(--text-primary);
472
+ font-family: var(--font-mono);
473
+ font-size: 0.8rem;
474
+ outline: none;
475
+ }
476
+
477
+ /* ═══ Data Tables ═══ */
478
+ .data-table {
479
+ width: 100%;
480
+ border-collapse: collapse;
481
+ font-family: var(--font-mono);
482
+ font-size: 0.75rem;
483
+ }
484
+
485
+ .data-table th {
486
+ font-family: var(--font-ui);
487
+ font-size: 0.65rem;
488
+ font-weight: 600;
489
+ color: var(--text-muted);
490
+ letter-spacing: 0.1em;
491
+ text-transform: uppercase;
492
+ text-align: left;
493
+ padding: 0.5rem 0.65rem;
494
+ border-bottom: 1px solid var(--border-normal);
495
+ }
496
+
497
+ .data-table td {
498
+ padding: 0.45rem 0.65rem;
499
+ border-bottom: 1px solid var(--border-dim);
500
+ color: var(--text-primary);
501
+ vertical-align: top;
502
+ }
503
+
504
+ .data-table tr:hover td { background: var(--bg-elevated); }
505
+
506
+ .data-key { color: var(--cyan); cursor: pointer; }
507
+ .data-key:hover { text-decoration: underline; }
508
+
509
+ .data-value {
510
+ max-width: 300px;
511
+ overflow: hidden;
512
+ text-overflow: ellipsis;
513
+ white-space: nowrap;
514
+ }
515
+
516
+ .data-value.expanded {
517
+ white-space: pre-wrap;
518
+ word-break: break-all;
519
+ max-width: none;
520
+ }
521
+
522
+ @media (max-width: 639px) {
523
+ .hide-mobile { display: none; }
524
+ }
525
+
526
+ /* ═══ Badges ═══ */
527
+ .badge {
528
+ font-family: var(--font-mono);
529
+ font-size: 0.6rem;
530
+ letter-spacing: 0.1em;
531
+ padding: 0.1rem 0.4rem;
532
+ border-radius: 2px;
533
+ text-transform: uppercase;
534
+ display: inline-block;
535
+ }
536
+
537
+ .badge-cyan { background: rgba(0,212,255,0.15); color: var(--cyan); border: 1px solid var(--cyan-dim); }
538
+ .badge-green { background: rgba(0,255,136,0.10); color: var(--green); border: 1px solid var(--green-dim); }
539
+ .badge-amber { background: rgba(255,184,0,0.10); color: var(--amber); border: 1px solid var(--amber-dim); }
540
+ .badge-red { background: rgba(255,51,102,0.10); color: var(--red); border: 1px solid var(--red-dim); }
541
+
542
+ /* ═══ Tabs ═══ */
543
+ .tabs {
544
+ display: flex;
545
+ gap: 0;
546
+ border-bottom: 1px solid var(--border-dim);
547
+ margin-bottom: 1rem;
548
+ }
549
+
550
+ .tab {
551
+ font-family: var(--font-mono);
552
+ font-size: 0.7rem;
553
+ font-weight: 500;
554
+ letter-spacing: 0.1em;
555
+ text-transform: uppercase;
556
+ color: var(--text-muted);
557
+ padding: 0.5rem 1rem;
558
+ cursor: pointer;
559
+ border-bottom: 2px solid transparent;
560
+ transition: all 0.12s;
561
+ }
562
+
563
+ .tab:hover { color: var(--text-secondary); }
564
+ .tab.active { color: var(--cyan); border-bottom-color: var(--cyan); }
565
+
566
+ /* ═══ Peer Cards ═══ */
567
+ .peer-grid {
568
+ display: grid;
569
+ grid-template-columns: 1fr;
570
+ gap: 0.75rem;
571
+ }
572
+
573
+ @media (min-width: 640px) { .peer-grid { grid-template-columns: repeat(2, 1fr); } }
574
+ @media (min-width: 1024px) { .peer-grid { grid-template-columns: repeat(3, 1fr); } }
575
+
576
+ .peer-card {
577
+ background: var(--bg-surface);
578
+ border: 1px solid var(--border-normal);
579
+ border-radius: 4px;
580
+ padding: 0.75rem 1rem;
581
+ transition: border-color 0.15s;
582
+ }
583
+
584
+ .peer-card:hover { border-color: var(--border-bright); }
585
+
586
+ /* ═══ Message Rows ═══ */
587
+ .msg-row {
588
+ background: var(--bg-surface);
589
+ border: 1px solid var(--border-dim);
590
+ border-radius: 4px;
591
+ padding: 0.65rem 0.875rem;
592
+ margin-bottom: 0.5rem;
593
+ cursor: pointer;
594
+ transition: border-color 0.12s;
595
+ }
596
+
597
+ .msg-row:hover { border-color: var(--border-bright); }
598
+
599
+ .msg-header {
600
+ display: flex;
601
+ align-items: center;
602
+ gap: 0.5rem;
603
+ margin-bottom: 0.25rem;
604
+ flex-wrap: wrap;
605
+ }
606
+
607
+ .msg-from {
608
+ font-family: var(--font-mono);
609
+ font-size: 0.75rem;
610
+ font-weight: 600;
611
+ color: var(--cyan);
612
+ }
613
+
614
+ .msg-time {
615
+ font-family: var(--font-mono);
616
+ font-size: 0.65rem;
617
+ color: var(--text-muted);
618
+ }
619
+
620
+ .msg-body {
621
+ font-family: var(--font-mono);
622
+ font-size: 0.75rem;
623
+ color: var(--text-secondary);
624
+ line-height: 1.5;
625
+ overflow: hidden;
626
+ text-overflow: ellipsis;
627
+ white-space: nowrap;
628
+ }
629
+
630
+ .msg-body.expanded {
631
+ white-space: pre-wrap;
632
+ word-break: break-word;
633
+ }
634
+
635
+ /* ═══ Empty State ═══ */
636
+ .empty {
637
+ text-align: center;
638
+ padding: 3rem 1rem;
639
+ color: var(--text-muted);
640
+ font-family: var(--font-mono);
641
+ font-size: 0.8rem;
642
+ }
643
+
644
+ /* ═══ Utilities ═══ */
645
+ .mb-1 { margin-bottom: 0.75rem; }
646
+ .mb-2 { margin-bottom: 1.25rem; }
647
+ .mt-1 { margin-top: 0.75rem; }
648
+ .gap-sm { gap: 0.5rem; }
649
+ .flex { display: flex; }
650
+ .flex-wrap { flex-wrap: wrap; }
651
+ .items-center { align-items: center; }
652
+ .justify-between { justify-content: space-between; }
653
+ .text-muted { color: var(--text-muted); }
654
+ .text-cyan { color: var(--cyan); }
655
+ .text-green { color: var(--green); }
656
+ .text-red { color: var(--red); }
657
+ .font-mono { font-family: var(--font-mono); }
658
+ .text-sm { font-size: 0.75rem; }
659
+ .text-xs { font-size: 0.65rem; }
660
+
661
+ /* ═══ AI Tasks ═══ */
662
+
663
+ .task-info {
664
+ background: var(--bg-surface);
665
+ border: 1px solid var(--border-normal);
666
+ border-radius: 6px;
667
+ padding: 0.75rem 1rem;
668
+ margin-bottom: 0.75rem;
669
+ }
670
+ .task-info-header {
671
+ display: flex;
672
+ align-items: center;
673
+ gap: 0.5rem;
674
+ margin-bottom: 0.35rem;
675
+ }
676
+ .task-info-prompt {
677
+ font-family: var(--font-mono);
678
+ font-size: 0.75rem;
679
+ color: var(--text-primary);
680
+ line-height: 1.5;
681
+ margin-bottom: 0.25rem;
682
+ }
683
+ .task-info-meta {
684
+ font-family: var(--font-mono);
685
+ font-size: 0.65rem;
686
+ color: var(--text-muted);
687
+ }
688
+
689
+ .ai-terminal {
690
+ background: var(--bg-void);
691
+ border: 1px solid var(--border-dim);
692
+ border-radius: 8px;
693
+ padding: 0.75rem;
694
+ font-family: var(--font-mono);
695
+ font-size: 0.72rem;
696
+ line-height: 1.5;
697
+ max-height: 50vh;
698
+ overflow-y: auto;
699
+ white-space: pre-wrap;
700
+ word-break: break-word;
701
+ }
702
+ .ai-line { padding: 1px 0; }
703
+ .ai-stdout { color: var(--green); }
704
+ .ai-thinking { color: var(--text-muted); font-style: italic; }
705
+ .ai-tool-use { color: var(--cyan); border-left: 2px solid var(--cyan-dim); padding-left: 0.5rem; margin: 2px 0; }
706
+ .ai-tool-result { color: var(--text-secondary); padding-left: 1rem; border-left: 2px solid var(--border-dim); margin: 2px 0; font-size: 0.65rem; }
707
+ .ai-stderr { color: var(--red); }
708
+ .ai-system { color: var(--text-muted); font-style: italic; }
709
+ .ai-result { color: var(--green); border: 1px solid rgba(0,255,136,0.25); border-radius: 4px; padding: 0.5rem; margin: 4px 0; background: rgba(0,255,136,0.03); }
710
+ .ai-line code { background: rgba(255,255,255,0.06); padding: 0.1em 0.35em; border-radius: 3px; font-size: 0.95em; }
711
+ .ai-line pre { background: rgba(255,255,255,0.04); border: 1px solid var(--border-dim); border-radius: 4px; padding: 0.5em; margin: 0.3em 0; overflow-x: auto; }
712
+ .ai-line pre code { background: none; padding: 0; }
713
+ .ai-line strong { color: var(--text-primary); }
714
+ .followup-bar { display: flex; flex-direction: column; gap: 0.5rem; margin-top: 0.75rem; }
715
+ .followup-bar textarea { width: 100%; min-height: 2.5rem; resize: vertical; box-sizing: border-box; }
716
+ .followup-actions { display: flex; justify-content: flex-end; }
717
+
718
+ .approval-banner {
719
+ background: var(--bg-elevated);
720
+ border: 2px solid var(--amber);
721
+ border-radius: 8px;
722
+ padding: 1rem;
723
+ margin-top: 0.75rem;
724
+ animation: approval-glow 2s ease-in-out infinite alternate;
725
+ }
726
+ @keyframes approval-glow {
727
+ from { box-shadow: 0 0 5px #ffb80030; }
728
+ to { box-shadow: 0 0 20px #ffb80060, 0 0 40px #ffb80020; }
729
+ }
730
+ .approval-header {
731
+ display: flex;
732
+ align-items: center;
733
+ gap: 0.75rem;
734
+ margin-bottom: 0.5rem;
735
+ }
736
+ .approval-desc {
737
+ color: var(--text-secondary);
738
+ font-size: 0.8rem;
739
+ margin-bottom: 0.5rem;
740
+ }
741
+ .approval-input {
742
+ background: var(--bg-void);
743
+ border: 1px solid var(--border-dim);
744
+ border-radius: 4px;
745
+ padding: 0.5rem;
746
+ margin-bottom: 0.75rem;
747
+ max-height: 200px;
748
+ overflow-y: auto;
749
+ }
750
+ .approval-input pre {
751
+ margin: 0;
752
+ font-family: var(--font-mono);
753
+ font-size: 0.7rem;
754
+ color: var(--text-secondary);
755
+ white-space: pre-wrap;
756
+ word-break: break-word;
757
+ }
758
+ .approval-actions {
759
+ display: flex;
760
+ gap: 0.75rem;
761
+ }
762
+ .approval-actions .btn {
763
+ flex: 1;
764
+ padding: 0.6rem;
765
+ font-size: 0.8rem;
766
+ }
767
+
768
+ .needs-attention {
769
+ border-left: 3px solid var(--amber) !important;
770
+ }
771
+
772
+ .pulse {
773
+ animation: pulse-badge 1.5s ease-in-out infinite;
774
+ }
775
+ @keyframes pulse-badge {
776
+ 0%, 100% { opacity: 1; }
777
+ 50% { opacity: 0.5; }
778
+ }
779
+
780
+ /* ═══ Scrollbar ═══ */
781
+ ::-webkit-scrollbar { width: 6px; height: 6px; }
782
+ ::-webkit-scrollbar-track { background: var(--bg-void); }
783
+ ::-webkit-scrollbar-thumb { background: var(--border-normal); border-radius: 3px; }
784
+ ::-webkit-scrollbar-thumb:hover { background: var(--border-bright); }