@hanzlaa/rcode 3.5.0 → 3.6.1
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.
- package/package.json +7 -1
- package/rihal/bin/rihal-tools.cjs +274 -31
- package/server/dashboard.js +105 -3
- package/server/lib/html/client/agents-data.js +27 -0
- package/server/lib/html/client/app.js +15 -0
- package/server/lib/html/client/components/App.js +211 -0
- package/server/lib/html/client/components/OrchPanel.js +293 -0
- package/server/lib/html/client/components/Sidebar.js +73 -0
- package/server/lib/html/client/components/Topbar.js +53 -0
- package/server/lib/html/client/components/XtermPanel.js +220 -0
- package/server/lib/html/client/components/shared.js +330 -0
- package/server/lib/html/client/icons-client.js +85 -0
- package/server/lib/html/client/orchestrator.js +280 -0
- package/server/lib/html/client/preact.js +34 -0
- package/server/lib/html/client/store.js +91 -0
- package/server/lib/html/client/util.js +186 -0
- package/server/lib/html/client/views/AgentsView.js +83 -0
- package/server/lib/html/client/views/DecisionsView.js +102 -0
- package/server/lib/html/client/views/FilesView.js +223 -0
- package/server/lib/html/client/views/KanbanView.js +236 -0
- package/server/lib/html/client/views/MemoryView.js +157 -0
- package/server/lib/html/client/views/MilestonesView.js +136 -0
- package/server/lib/html/client/views/OrchestrationView.js +167 -0
- package/server/lib/html/client/views/OverviewView.js +221 -0
- package/server/lib/html/client/views/PhasesView.js +184 -0
- package/server/lib/html/client/views/RoadmapView.js +238 -0
- package/server/lib/html/client/views/SprintsView.js +178 -0
- package/server/lib/html/client/views/TasksView.js +148 -0
- package/server/lib/html/client.js +41 -1775
- package/server/lib/html/css.js +265 -56
- package/server/lib/html/icons.js +68 -0
- package/server/lib/html/shell.js +9 -296
- package/server/lib/scanner.js +89 -0
- package/server/orchestrator.js +252 -310
package/server/lib/html/css.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* CLAUDE.md exemption: pure CSS data file, no logic — 1000-line limit does not apply */
|
|
1
2
|
/**
|
|
2
3
|
* Dashboard CSS — Linear design system.
|
|
3
4
|
* Dark-first (Linear-style). Rihal accent: #5e6ad2 (Aether Blue).
|
|
@@ -27,7 +28,6 @@ function renderCss() {
|
|
|
27
28
|
--text-secondary: #b4bcd0;
|
|
28
29
|
--text-tertiary: #8a8f98;
|
|
29
30
|
--text-muted: #62666d;
|
|
30
|
-
--text-on-accent: #ffffff;
|
|
31
31
|
|
|
32
32
|
/* Brand — Rihal keeps Aether Blue */
|
|
33
33
|
--accent-primary: #5e6ad2;
|
|
@@ -42,7 +42,6 @@ function renderCss() {
|
|
|
42
42
|
--red: #eb5757;
|
|
43
43
|
--blue: #26b5ce;
|
|
44
44
|
--violet: #bf7af0;
|
|
45
|
-
--orange: #f2994a;
|
|
46
45
|
|
|
47
46
|
/* Status */
|
|
48
47
|
--status-todo: #e2e2e2;
|
|
@@ -55,13 +54,17 @@ function renderCss() {
|
|
|
55
54
|
--font-mono: "JetBrains Mono", "SF Mono", Menlo, Consolas, monospace;
|
|
56
55
|
|
|
57
56
|
/* Size scale */
|
|
58
|
-
--text-2xl: 24px;
|
|
59
57
|
--text-xl: 20px;
|
|
60
58
|
--text-lg: 17px;
|
|
61
59
|
--text-md: 15px;
|
|
62
60
|
--text-sm: 14px;
|
|
63
61
|
--text-xs: 13px;
|
|
64
62
|
--text-2xs: 11px;
|
|
63
|
+
--text-stat: 28px; /* stat card value — large metric numeral */
|
|
64
|
+
|
|
65
|
+
/* Component dimensions */
|
|
66
|
+
--h-header-btn: 26px; /* topbar button height */
|
|
67
|
+
--size-icon-btn: 32px; /* square icon button (hamburger, etc.) */
|
|
65
68
|
|
|
66
69
|
/* Spacing (4px base) */
|
|
67
70
|
--space-1: 2px;
|
|
@@ -72,7 +75,6 @@ function renderCss() {
|
|
|
72
75
|
--space-6: 20px;
|
|
73
76
|
--space-7: 24px;
|
|
74
77
|
--space-8: 32px;
|
|
75
|
-
--space-9: 48px;
|
|
76
78
|
--space-10: 64px;
|
|
77
79
|
|
|
78
80
|
/* Radius */
|
|
@@ -84,19 +86,13 @@ function renderCss() {
|
|
|
84
86
|
--radius-full: 9999px;
|
|
85
87
|
|
|
86
88
|
/* Shadows */
|
|
87
|
-
--shadow-sm: 0 1px 2px rgba(0,0,0,0.4);
|
|
88
|
-
--shadow-md: 0 4px 12px rgba(0,0,0,0.5);
|
|
89
89
|
--shadow-lg: 0 16px 32px rgba(0,0,0,0.6);
|
|
90
|
-
--shadow-modal: 0 32px 64px rgba(0,0,0,0.7), 0 0 0 1px rgba(255,255,255,0.06);
|
|
91
|
-
--shadow-focus: 0 0 0 2px var(--bg-page), 0 0 0 4px var(--accent-primary);
|
|
92
90
|
|
|
93
91
|
/* Motion */
|
|
94
92
|
--ease: cubic-bezier(0.4,0,0.2,1);
|
|
95
|
-
--ease-in: cubic-bezier(0.4,0,1,1);
|
|
96
93
|
--t-fast: 120ms;
|
|
97
94
|
--t-base: 200ms;
|
|
98
95
|
--t-menu: 240ms;
|
|
99
|
-
--t-view: 320ms;
|
|
100
96
|
|
|
101
97
|
/* Legacy compat aliases */
|
|
102
98
|
--bg: var(--bg-page);
|
|
@@ -104,7 +100,6 @@ function renderCss() {
|
|
|
104
100
|
--border: var(--border-default);
|
|
105
101
|
--radius-sm: var(--radius-2);
|
|
106
102
|
--radius-md: var(--radius-4);
|
|
107
|
-
--radius-lg: var(--radius-5);
|
|
108
103
|
--accent-green: var(--green);
|
|
109
104
|
--accent-amber: var(--amber);
|
|
110
105
|
--accent-red: var(--red);
|
|
@@ -236,9 +231,9 @@ html, body {
|
|
|
236
231
|
.hamburger-btn {
|
|
237
232
|
display: none;
|
|
238
233
|
flex-direction: column;
|
|
239
|
-
gap:
|
|
240
|
-
width:
|
|
241
|
-
height:
|
|
234
|
+
gap: var(--space-2);
|
|
235
|
+
width: var(--size-icon-btn);
|
|
236
|
+
height: var(--size-icon-btn);
|
|
242
237
|
align-items: center;
|
|
243
238
|
justify-content: center;
|
|
244
239
|
background: none;
|
|
@@ -261,7 +256,7 @@ html, body {
|
|
|
261
256
|
display: none;
|
|
262
257
|
position: fixed;
|
|
263
258
|
inset: 0;
|
|
264
|
-
background: rgba(0,0,0,0.5);
|
|
259
|
+
background: rgba(0,0,0,0.5); /* intentional: one-off overlay tint; translucency can't be expressed as a theme token */
|
|
265
260
|
z-index: 15;
|
|
266
261
|
}
|
|
267
262
|
|
|
@@ -276,7 +271,7 @@ html, body {
|
|
|
276
271
|
|
|
277
272
|
/* ── Topbar / header ───────────────────────────────────────────── */
|
|
278
273
|
header {
|
|
279
|
-
background: rgba(8,9,10,0.8);
|
|
274
|
+
background: rgba(8,9,10,0.8); /* intentional: frosted glass tied to --bg-page exact value; alpha can't be expressed as a theme token */
|
|
280
275
|
backdrop-filter: blur(12px);
|
|
281
276
|
-webkit-backdrop-filter: blur(12px);
|
|
282
277
|
border-bottom: 1px solid var(--border-subtle);
|
|
@@ -291,7 +286,7 @@ header {
|
|
|
291
286
|
}
|
|
292
287
|
|
|
293
288
|
[data-theme="light"] header {
|
|
294
|
-
background: rgba(245,245,247,0.85);
|
|
289
|
+
background: rgba(245,245,247,0.85); /* intentional: light frosted glass; alpha channel can't be expressed as a theme token */
|
|
295
290
|
}
|
|
296
291
|
|
|
297
292
|
.brand {
|
|
@@ -328,6 +323,17 @@ header {
|
|
|
328
323
|
gap: var(--space-2);
|
|
329
324
|
}
|
|
330
325
|
|
|
326
|
+
.topbar-start-group {
|
|
327
|
+
display: flex;
|
|
328
|
+
align-items: center;
|
|
329
|
+
gap: var(--space-4); /* --space-4 = 12px */
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
.updated-ago {
|
|
333
|
+
font-size: var(--text-2xs); /* --text-2xs = 11px */
|
|
334
|
+
color: var(--text-muted);
|
|
335
|
+
}
|
|
336
|
+
|
|
331
337
|
.live {
|
|
332
338
|
width: 6px;
|
|
333
339
|
height: 6px;
|
|
@@ -344,8 +350,8 @@ header {
|
|
|
344
350
|
.header-btn {
|
|
345
351
|
display: inline-flex;
|
|
346
352
|
align-items: center;
|
|
347
|
-
gap:
|
|
348
|
-
height:
|
|
353
|
+
gap: var(--space-2);
|
|
354
|
+
height: var(--h-header-btn);
|
|
349
355
|
padding: 0 var(--space-3);
|
|
350
356
|
background: var(--bg-elev-2);
|
|
351
357
|
border: 1px solid var(--border-default);
|
|
@@ -445,7 +451,7 @@ section .body {
|
|
|
445
451
|
color: var(--text-muted);
|
|
446
452
|
}
|
|
447
453
|
.stat .value {
|
|
448
|
-
font-size:
|
|
454
|
+
font-size: var(--text-stat);
|
|
449
455
|
font-weight: 700;
|
|
450
456
|
letter-spacing: -0.025em;
|
|
451
457
|
color: var(--text-primary);
|
|
@@ -988,7 +994,7 @@ section .body {
|
|
|
988
994
|
.agent-card .role {
|
|
989
995
|
font-size: var(--text-2xs);
|
|
990
996
|
color: var(--text-tertiary);
|
|
991
|
-
letter
|
|
997
|
+
letter-spacing: -0.006em;
|
|
992
998
|
}
|
|
993
999
|
.real-badge {
|
|
994
1000
|
font-size: var(--text-2xs);
|
|
@@ -1566,6 +1572,21 @@ footer {
|
|
|
1566
1572
|
text-align: center;
|
|
1567
1573
|
}
|
|
1568
1574
|
|
|
1575
|
+
.orch-empty-tab {
|
|
1576
|
+
padding: var(--space-2) var(--space-3); /* 6px 8px via space tokens */
|
|
1577
|
+
font-size: var(--text-2xs); /* 11px */
|
|
1578
|
+
color: var(--text-muted);
|
|
1579
|
+
}
|
|
1580
|
+
|
|
1581
|
+
.orch-footer-spacer {
|
|
1582
|
+
flex: 1;
|
|
1583
|
+
}
|
|
1584
|
+
|
|
1585
|
+
.orch-footer-status {
|
|
1586
|
+
font-size: var(--text-2xs); /* 11px */
|
|
1587
|
+
color: var(--text-muted);
|
|
1588
|
+
}
|
|
1589
|
+
|
|
1569
1590
|
/* Terminal log lines */
|
|
1570
1591
|
.kt-line { color: #a0c4a0; word-break: break-word; }
|
|
1571
1592
|
.kt-line.tool { color: #7cb8ff; }
|
|
@@ -1921,6 +1942,49 @@ footer {
|
|
|
1921
1942
|
flex-direction: column;
|
|
1922
1943
|
}
|
|
1923
1944
|
.term-panel.open { display: flex; }
|
|
1945
|
+
.term-panel.fullscreen {
|
|
1946
|
+
inset: 0;
|
|
1947
|
+
left: 0;
|
|
1948
|
+
height: 100vh;
|
|
1949
|
+
}
|
|
1950
|
+
|
|
1951
|
+
/* Minimized terminal pill */
|
|
1952
|
+
.term-pill {
|
|
1953
|
+
display: none;
|
|
1954
|
+
position: fixed;
|
|
1955
|
+
bottom: var(--space-4);
|
|
1956
|
+
right: var(--space-4);
|
|
1957
|
+
z-index: 201;
|
|
1958
|
+
align-items: center;
|
|
1959
|
+
gap: var(--space-2);
|
|
1960
|
+
padding: var(--space-2) var(--space-4);
|
|
1961
|
+
background: var(--bg-elev-3);
|
|
1962
|
+
border: 1px solid var(--accent-primary);
|
|
1963
|
+
border-radius: var(--radius-4);
|
|
1964
|
+
color: var(--text-primary);
|
|
1965
|
+
font-size: var(--text-xs);
|
|
1966
|
+
cursor: pointer;
|
|
1967
|
+
box-shadow: 0 6px 20px rgba(0,0,0,0.45);
|
|
1968
|
+
}
|
|
1969
|
+
.term-pill.show { display: flex; }
|
|
1970
|
+
.term-pill:hover { background: var(--bg-hover); }
|
|
1971
|
+
.term-pill-icon { color: var(--text-muted); }
|
|
1972
|
+
|
|
1973
|
+
/* "running" badge for phase / sprint / task cards */
|
|
1974
|
+
.run-badge {
|
|
1975
|
+
display: inline-flex;
|
|
1976
|
+
align-items: center;
|
|
1977
|
+
gap: 4px;
|
|
1978
|
+
margin-left: var(--space-2);
|
|
1979
|
+
padding: 1px var(--space-2);
|
|
1980
|
+
background: rgba(63,185,80,0.15);
|
|
1981
|
+
border: 1px solid rgba(63,185,80,0.4);
|
|
1982
|
+
border-radius: var(--radius-2);
|
|
1983
|
+
color: var(--accent-green);
|
|
1984
|
+
font-size: var(--text-2xs);
|
|
1985
|
+
font-weight: 600;
|
|
1986
|
+
white-space: nowrap;
|
|
1987
|
+
}
|
|
1924
1988
|
.term-header {
|
|
1925
1989
|
display: flex;
|
|
1926
1990
|
align-items: center;
|
|
@@ -1975,47 +2039,14 @@ footer {
|
|
|
1975
2039
|
padding: 6px 8px;
|
|
1976
2040
|
background: #0c0c0e;
|
|
1977
2041
|
}
|
|
1978
|
-
.term-
|
|
1979
|
-
display: flex;
|
|
1980
|
-
align-items: center;
|
|
1981
|
-
gap: var(--space-2);
|
|
2042
|
+
.term-hint {
|
|
1982
2043
|
padding: var(--space-2) var(--space-3);
|
|
1983
2044
|
background: var(--bg-elev-2);
|
|
1984
2045
|
border-top: 1px solid var(--border-subtle);
|
|
1985
|
-
|
|
1986
|
-
}
|
|
1987
|
-
.term-prompt {
|
|
1988
|
-
color: var(--accent-primary);
|
|
1989
|
-
font-family: var(--font-mono);
|
|
2046
|
+
color: var(--text-muted);
|
|
1990
2047
|
font-size: var(--text-xs);
|
|
1991
2048
|
flex-shrink: 0;
|
|
1992
2049
|
}
|
|
1993
|
-
.term-input-field {
|
|
1994
|
-
flex: 1;
|
|
1995
|
-
height: 26px;
|
|
1996
|
-
background: transparent;
|
|
1997
|
-
border: none;
|
|
1998
|
-
color: var(--text-primary);
|
|
1999
|
-
font-family: var(--font-mono);
|
|
2000
|
-
font-size: var(--text-xs);
|
|
2001
|
-
outline: none;
|
|
2002
|
-
letter-spacing: 0;
|
|
2003
|
-
}
|
|
2004
|
-
.term-input-field::placeholder { color: var(--text-muted); }
|
|
2005
|
-
.term-send-btn {
|
|
2006
|
-
height: 24px;
|
|
2007
|
-
padding: 0 var(--space-3);
|
|
2008
|
-
background: var(--accent-primary);
|
|
2009
|
-
border: none;
|
|
2010
|
-
border-radius: var(--radius-2);
|
|
2011
|
-
color: white;
|
|
2012
|
-
font-size: 10px;
|
|
2013
|
-
font-family: var(--font-mono);
|
|
2014
|
-
cursor: pointer;
|
|
2015
|
-
opacity: 0.85;
|
|
2016
|
-
white-space: nowrap;
|
|
2017
|
-
}
|
|
2018
|
-
.term-send-btn:hover { opacity: 1; }
|
|
2019
2050
|
/* Run / Terminal action buttons (used on sprint/phase detail) */
|
|
2020
2051
|
.term-run-btn {
|
|
2021
2052
|
display: inline-flex;
|
|
@@ -2040,12 +2071,133 @@ footer {
|
|
|
2040
2071
|
color: var(--text-secondary);
|
|
2041
2072
|
}
|
|
2042
2073
|
.term-run-btn.outline:hover { background: var(--bg-hover); color: var(--text-primary); }
|
|
2074
|
+
.term-run-btn.danger {
|
|
2075
|
+
background: transparent;
|
|
2076
|
+
border-color: rgba(255,107,107,0.4);
|
|
2077
|
+
color: #ff6b6b;
|
|
2078
|
+
}
|
|
2079
|
+
.term-run-btn.danger:hover { background: rgba(255,107,107,0.12); opacity: 1; }
|
|
2043
2080
|
.term-action-bar {
|
|
2044
2081
|
display: flex;
|
|
2045
2082
|
align-items: center;
|
|
2046
2083
|
gap: var(--space-3);
|
|
2047
2084
|
margin-bottom: var(--space-5);
|
|
2048
2085
|
}
|
|
2086
|
+
.term-status-dot.exited { background: #ff4444; animation: none; }
|
|
2087
|
+
.term-status-dot.waiting { background: var(--accent-amber); animation: pulse 1.2s infinite; }
|
|
2088
|
+
|
|
2089
|
+
/* Compact ▶ Run button on phase / sprint / task list cards */
|
|
2090
|
+
.card-run-btn {
|
|
2091
|
+
float: right;
|
|
2092
|
+
margin-left: var(--space-3);
|
|
2093
|
+
height: 20px;
|
|
2094
|
+
padding: 0 var(--space-3);
|
|
2095
|
+
background: transparent;
|
|
2096
|
+
border: 1px solid var(--border-default);
|
|
2097
|
+
border-radius: var(--radius-2);
|
|
2098
|
+
color: var(--text-tertiary);
|
|
2099
|
+
font-size: 10px;
|
|
2100
|
+
font-weight: 500;
|
|
2101
|
+
cursor: pointer;
|
|
2102
|
+
transition: background var(--t-fast) var(--ease),
|
|
2103
|
+
color var(--t-fast) var(--ease),
|
|
2104
|
+
border-color var(--t-fast) var(--ease);
|
|
2105
|
+
}
|
|
2106
|
+
.card-run-btn:hover {
|
|
2107
|
+
background: var(--accent-green);
|
|
2108
|
+
border-color: var(--accent-green);
|
|
2109
|
+
color: #fff;
|
|
2110
|
+
}
|
|
2111
|
+
.ms-actions {
|
|
2112
|
+
display: inline-flex;
|
|
2113
|
+
align-items: center;
|
|
2114
|
+
gap: var(--space-2);
|
|
2115
|
+
margin-left: var(--space-3);
|
|
2116
|
+
}
|
|
2117
|
+
.ms-audit-btn:hover {
|
|
2118
|
+
background: var(--accent-primary);
|
|
2119
|
+
border-color: var(--accent-primary);
|
|
2120
|
+
}
|
|
2121
|
+
|
|
2122
|
+
/* ── Orchestration view ─────────────────────────────────────── */
|
|
2123
|
+
.orch-subtitle {
|
|
2124
|
+
color: var(--text-tertiary);
|
|
2125
|
+
font-size: var(--text-sm);
|
|
2126
|
+
margin-bottom: var(--space-5);
|
|
2127
|
+
}
|
|
2128
|
+
.orch-grid {
|
|
2129
|
+
display: grid;
|
|
2130
|
+
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
|
2131
|
+
gap: var(--space-4);
|
|
2132
|
+
}
|
|
2133
|
+
.orch-card {
|
|
2134
|
+
background: var(--bg-elev-2);
|
|
2135
|
+
border: 1px solid var(--border-subtle);
|
|
2136
|
+
border-left: 3px solid var(--text-muted);
|
|
2137
|
+
border-radius: var(--radius-4);
|
|
2138
|
+
padding: var(--space-4) var(--space-5);
|
|
2139
|
+
display: flex;
|
|
2140
|
+
flex-direction: column;
|
|
2141
|
+
gap: var(--space-3);
|
|
2142
|
+
}
|
|
2143
|
+
.orch-card.orch-running { border-left-color: var(--accent-green); }
|
|
2144
|
+
.orch-card.orch-waiting {
|
|
2145
|
+
border-left-color: var(--accent-amber);
|
|
2146
|
+
background: rgba(245,158,11,0.05);
|
|
2147
|
+
}
|
|
2148
|
+
.orch-card.orch-waiting .orch-card-badge { color: var(--accent-amber); }
|
|
2149
|
+
.orch-card.orch-error,
|
|
2150
|
+
.orch-card.orch-exited { border-left-color: #ff4444; }
|
|
2151
|
+
.orch-card.orch-stopped { border-left-color: var(--accent-amber); }
|
|
2152
|
+
.orch-card.orch-done { border-left-color: var(--accent-blue); }
|
|
2153
|
+
.orch-card-head {
|
|
2154
|
+
display: flex;
|
|
2155
|
+
align-items: center;
|
|
2156
|
+
gap: var(--space-3);
|
|
2157
|
+
}
|
|
2158
|
+
.orch-card-id {
|
|
2159
|
+
font-weight: 600;
|
|
2160
|
+
font-size: var(--text-sm);
|
|
2161
|
+
color: var(--text-primary);
|
|
2162
|
+
}
|
|
2163
|
+
.orch-card-badge {
|
|
2164
|
+
margin-left: auto;
|
|
2165
|
+
font-size: var(--text-2xs);
|
|
2166
|
+
text-transform: uppercase;
|
|
2167
|
+
letter-spacing: 0.06em;
|
|
2168
|
+
color: var(--text-muted);
|
|
2169
|
+
}
|
|
2170
|
+
.orch-card-cmd {
|
|
2171
|
+
font-family: var(--font-mono);
|
|
2172
|
+
font-size: var(--text-xs);
|
|
2173
|
+
color: var(--text-secondary);
|
|
2174
|
+
background: var(--bg-elev-1);
|
|
2175
|
+
border-radius: var(--radius-2);
|
|
2176
|
+
padding: var(--space-2) var(--space-3);
|
|
2177
|
+
word-break: break-all;
|
|
2178
|
+
}
|
|
2179
|
+
.orch-card-meta {
|
|
2180
|
+
font-size: var(--text-2xs);
|
|
2181
|
+
color: var(--text-tertiary);
|
|
2182
|
+
}
|
|
2183
|
+
.orch-card-actions {
|
|
2184
|
+
display: flex;
|
|
2185
|
+
gap: var(--space-2);
|
|
2186
|
+
}
|
|
2187
|
+
|
|
2188
|
+
/* ── Icon alignment helpers (for sprint 32.2 SVG icon sweep) ── */
|
|
2189
|
+
.ic {
|
|
2190
|
+
display: inline-block;
|
|
2191
|
+
vertical-align: -0.15em; /* optical baseline alignment with surrounding text */
|
|
2192
|
+
flex-shrink: 0;
|
|
2193
|
+
}
|
|
2194
|
+
.btn-icon { display: inline-block; vertical-align: -0.1em; flex-shrink: 0; }
|
|
2195
|
+
.section-icon {
|
|
2196
|
+
display: inline-flex;
|
|
2197
|
+
align-items: center;
|
|
2198
|
+
gap: var(--space-2);
|
|
2199
|
+
}
|
|
2200
|
+
.tree-icon .ic { vertical-align: -0.15em; }
|
|
2049
2201
|
|
|
2050
2202
|
/* ── Scrollbar global ───────────────────────────────────────── */
|
|
2051
2203
|
::-webkit-scrollbar { width: 6px; height: 6px; }
|
|
@@ -2053,6 +2205,63 @@ footer {
|
|
|
2053
2205
|
::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 3px; }
|
|
2054
2206
|
::-webkit-scrollbar-thumb:hover { background: var(--text-muted); }
|
|
2055
2207
|
* { scrollbar-width: thin; scrollbar-color: var(--border-strong) transparent; }
|
|
2208
|
+
|
|
2209
|
+
/* ── Command runner (Sprint 33.2) ───────────────────────────────────────────── */
|
|
2210
|
+
.cmd-runner {
|
|
2211
|
+
background: var(--bg-card);
|
|
2212
|
+
border: 1px solid var(--border);
|
|
2213
|
+
border-radius: var(--radius-md);
|
|
2214
|
+
padding: var(--space-4);
|
|
2215
|
+
margin-bottom: var(--space-5);
|
|
2216
|
+
}
|
|
2217
|
+
.cmd-runner-title {
|
|
2218
|
+
font-size: var(--text-sm);
|
|
2219
|
+
font-weight: 600;
|
|
2220
|
+
color: var(--text-muted);
|
|
2221
|
+
text-transform: uppercase;
|
|
2222
|
+
letter-spacing: 0.05em;
|
|
2223
|
+
margin-bottom: var(--space-3);
|
|
2224
|
+
display: flex;
|
|
2225
|
+
align-items: center;
|
|
2226
|
+
gap: var(--space-2);
|
|
2227
|
+
}
|
|
2228
|
+
.cmd-runner-row {
|
|
2229
|
+
display: flex;
|
|
2230
|
+
gap: var(--space-3);
|
|
2231
|
+
align-items: center;
|
|
2232
|
+
}
|
|
2233
|
+
.cmd-runner-select {
|
|
2234
|
+
flex: 1;
|
|
2235
|
+
background: var(--bg-input, var(--bg-elev-2));
|
|
2236
|
+
border: 1px solid var(--border);
|
|
2237
|
+
border-radius: var(--radius-sm);
|
|
2238
|
+
color: var(--text-primary);
|
|
2239
|
+
padding: var(--space-2) var(--space-3);
|
|
2240
|
+
font-size: var(--text-sm);
|
|
2241
|
+
cursor: pointer;
|
|
2242
|
+
}
|
|
2243
|
+
.cmd-runner-select:focus {
|
|
2244
|
+
outline: none;
|
|
2245
|
+
border-color: var(--accent-blue);
|
|
2246
|
+
}
|
|
2247
|
+
.cmd-runner-btn {
|
|
2248
|
+
background: var(--accent-blue);
|
|
2249
|
+
color: #fff;
|
|
2250
|
+
border: none;
|
|
2251
|
+
border-radius: var(--radius-sm);
|
|
2252
|
+
padding: var(--space-2) var(--space-4);
|
|
2253
|
+
font-size: var(--text-sm);
|
|
2254
|
+
font-weight: 600;
|
|
2255
|
+
cursor: pointer;
|
|
2256
|
+
display: flex;
|
|
2257
|
+
align-items: center;
|
|
2258
|
+
gap: var(--space-2);
|
|
2259
|
+
transition: opacity 0.15s;
|
|
2260
|
+
white-space: nowrap;
|
|
2261
|
+
}
|
|
2262
|
+
.cmd-runner-btn:hover:not(:disabled) { opacity: 0.85; }
|
|
2263
|
+
.cmd-runner-btn:disabled,
|
|
2264
|
+
.cmd-runner-btn--busy { opacity: 0.6; cursor: not-allowed; }
|
|
2056
2265
|
</style>`;
|
|
2057
2266
|
}
|
|
2058
2267
|
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inline SVG icon set (Lucide-style stroke icons).
|
|
3
|
+
*
|
|
4
|
+
* No CDN, no font — just path data rendered into a <svg>. Used server-side
|
|
5
|
+
* by shell.js for static chrome, and embedded as window.__ICONS__ so the
|
|
6
|
+
* client modules can render the same icons in dynamic markup.
|
|
7
|
+
*
|
|
8
|
+
* IMPORTANT: The ICONS map is duplicated in the ESM client counterpart:
|
|
9
|
+
* server/lib/html/client/icons-client.js (in sync with this file)
|
|
10
|
+
* Keep both files in sync when adding or changing icon paths. The duplication
|
|
11
|
+
* is the no-build-step cost — the browser cannot import a CJS module as ESM.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
// name → inner SVG markup (viewBox 0 0 24 24, stroke = currentColor)
|
|
15
|
+
// Keep in sync with server/lib/html/client/icons-client.js
|
|
16
|
+
const ICONS = {
|
|
17
|
+
home: '<path d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><path d="M9 22V12h6v10"/>',
|
|
18
|
+
activity: '<path d="M22 12h-4l-3 9L9 3l-3 9H2"/>',
|
|
19
|
+
map: '<polygon points="3 6 9 3 15 6 21 3 21 18 15 21 9 18 3 21"/><line x1="9" y1="3" x2="9" y2="18"/><line x1="15" y1="6" x2="15" y2="21"/>',
|
|
20
|
+
target: '<circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="6"/><circle cx="12" cy="12" r="2"/>',
|
|
21
|
+
layers: '<polygon points="12 2 2 7 12 12 22 7 12 2"/><polyline points="2 17 12 22 22 17"/><polyline points="2 12 12 17 22 12"/>',
|
|
22
|
+
zap: '<polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/>',
|
|
23
|
+
checkSquare: '<polyline points="9 11 12 14 22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/>',
|
|
24
|
+
kanban: '<rect x="3" y="4" width="5" height="16" rx="1"/><rect x="10" y="4" width="5" height="11" rx="1"/><rect x="17" y="4" width="5" height="14" rx="1"/>',
|
|
25
|
+
file: '<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/>',
|
|
26
|
+
users: '<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/>',
|
|
27
|
+
scale: '<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="8" y1="13" x2="16" y2="13"/><line x1="8" y1="17" x2="13" y2="17"/>',
|
|
28
|
+
database: '<ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5"/><path d="M3 12c0 1.66 4 3 9 3s9-1.34 9-3"/>',
|
|
29
|
+
play: '<polygon points="6 3 20 12 6 21 6 3"/>',
|
|
30
|
+
terminal: '<polyline points="4 17 10 11 4 5"/><line x1="12" y1="19" x2="20" y2="19"/>',
|
|
31
|
+
square: '<rect x="6" y="6" width="12" height="12" rx="1"/>',
|
|
32
|
+
x: '<line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/>',
|
|
33
|
+
minimize: '<line x1="5" y1="14" x2="19" y2="14"/>',
|
|
34
|
+
maximize: '<path d="M8 3H5a2 2 0 0 0-2 2v3"/><path d="M21 8V5a2 2 0 0 0-2-2h-3"/><path d="M3 16v3a2 2 0 0 0 2 2h3"/><path d="M16 21h3a2 2 0 0 0 2-2v-3"/>',
|
|
35
|
+
clock: '<circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/>',
|
|
36
|
+
eye: '<path d="M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7-10-7-10-7z"/><circle cx="12" cy="12" r="3"/>',
|
|
37
|
+
filePen: '<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h7"/><polyline points="14 2 14 8 20 8"/><path d="M18.4 12.6a2 2 0 0 1 3 3L17 20l-4 1 1-4z"/>',
|
|
38
|
+
hourglass: '<path d="M5 22h14M5 2h14M17 22v-4.17a2 2 0 0 0-.59-1.42L12 12l-4.41 4.41A2 2 0 0 0 7 17.83V22M7 2v4.17a2 2 0 0 0 .59 1.42L12 12l4.41-4.41A2 2 0 0 0 17 6.17V2"/>',
|
|
39
|
+
|
|
40
|
+
// Added in sprint 32.2 — emoji-to-SVG sweep
|
|
41
|
+
building: '<rect x="4" y="2" width="16" height="20" rx="2"/><path d="M9 22V12h6v10"/><path d="M8 7h.01M12 7h.01M16 7h.01M8 11h.01M12 11h.01M16 11h.01"/>',
|
|
42
|
+
link: '<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/>',
|
|
43
|
+
'alert-triangle':'<path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/>',
|
|
44
|
+
brain: '<path d="M9.5 2A2.5 2.5 0 0 1 12 4.5v15a2.5 2.5 0 0 1-4.96-.46 2.5 2.5 0 0 1-1.28-4.56A3 3 0 0 1 5 12c0-.56.15-1.1.42-1.57a2.5 2.5 0 0 1-.42-4.93V5.5A2.5 2.5 0 0 1 9.5 2z"/><path d="M14.5 2A2.5 2.5 0 0 0 12 4.5v15a2.5 2.5 0 0 0 4.96-.46 2.5 2.5 0 0 0 1.28-4.56A3 3 0 0 0 19 12c0-.56-.15-1.1-.42-1.57a2.5 2.5 0 0 0 .42-4.93V5.5A2.5 2.5 0 0 0 14.5 2z"/>',
|
|
45
|
+
'clipboard-list':'<rect x="8" y="2" width="8" height="4" rx="1" ry="1"/><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/><line x1="12" y1="11" x2="12" y2="17"/><line x1="9" y1="14" x2="15" y2="14"/>',
|
|
46
|
+
flag: '<path d="M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z"/><line x1="4" y1="22" x2="4" y2="15"/>',
|
|
47
|
+
monitor: '<rect x="2" y="3" width="20" height="14" rx="2" ry="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/>',
|
|
48
|
+
'file-text': '<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/><polyline points="10 9 9 9 8 9"/>',
|
|
49
|
+
copy: '<rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/>',
|
|
50
|
+
lightbulb: '<line x1="9" y1="18" x2="15" y2="18"/><line x1="10" y1="22" x2="14" y2="22"/><path d="M15.09 14c.18-.98.65-1.74 1.41-2.5A4.65 4.65 0 0 0 18 8 6 6 0 0 0 6 8c0 1 .23 2.23 1.5 3.5A4.61 4.61 0 0 1 8.91 14"/>',
|
|
51
|
+
'edit-3': '<path d="M12 20h9"/><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"/>',
|
|
52
|
+
|
|
53
|
+
// Added in sprint 32.3 — App/Topbar theme toggle icons
|
|
54
|
+
moon: '<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>',
|
|
55
|
+
sun: '<circle cx="12" cy="12" r="4"/><line x1="12" y1="2" x2="12" y2="6"/><line x1="12" y1="18" x2="12" y2="22"/><line x1="4.22" y1="4.22" x2="7.05" y2="7.05"/><line x1="16.95" y1="16.95" x2="19.78" y2="19.78"/><line x1="2" y1="12" x2="6" y2="12"/><line x1="18" y1="12" x2="22" y2="12"/><line x1="4.22" y1="19.78" x2="7.05" y2="16.95"/><line x1="16.95" y1="7.05" x2="19.78" y2="4.22"/>',
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// Render an icon as an inline <svg>. size in px; cls adds extra classes.
|
|
59
|
+
function icon(name, size, cls) {
|
|
60
|
+
const p = ICONS[name];
|
|
61
|
+
if (!p) return '';
|
|
62
|
+
const s = size || 16;
|
|
63
|
+
return '<svg class="ic' + (cls ? ' ' + cls : '') + '" width="' + s + '" height="' + s +
|
|
64
|
+
'" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" ' +
|
|
65
|
+
'stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">' + p + '</svg>';
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
module.exports = { ICONS, icon };
|