@yemi33/squad 0.1.20 → 0.1.21
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/README.md +38 -17
- package/dashboard.html +438 -203
- package/dashboard.js +349 -66
- package/docs/self-improvement.md +2 -2
- package/engine.js +21 -106
- package/package.json +1 -1
package/dashboard.html
CHANGED
|
@@ -10,90 +10,111 @@
|
|
|
10
10
|
--bg: #0d1117; --surface: #161b22; --surface2: #21262d; --border: #30363d;
|
|
11
11
|
--text: #e6edf3; --muted: #8b949e; --green: #3fb950; --yellow: #d29922;
|
|
12
12
|
--blue: #58a6ff; --purple: #bc8cff; --red: #f85149; --orange: #e3b341;
|
|
13
|
+
|
|
14
|
+
/* Spacing scale */
|
|
15
|
+
--space-1: 2px; --space-2: 4px; --space-3: 6px; --space-4: 8px;
|
|
16
|
+
--space-5: 10px; --space-6: 12px; --space-7: 16px; --space-8: 20px; --space-9: 24px;
|
|
17
|
+
|
|
18
|
+
/* Typography scale */
|
|
19
|
+
--text-xs: 9px; --text-sm: 10px; --text-base: 11px;
|
|
20
|
+
--text-md: 12px; --text-lg: 13px; --text-xl: 14px; --text-2xl: 16px;
|
|
21
|
+
--text-stat: 20px; --text-stat-lg: 24px;
|
|
22
|
+
|
|
23
|
+
/* Border radius */
|
|
24
|
+
--radius-sm: 4px; --radius-md: 6px; --radius-lg: 8px; --radius-xl: 10px; --radius-full: 50%;
|
|
25
|
+
|
|
26
|
+
/* Shadows */
|
|
27
|
+
--shadow-sm: 0 1px 3px rgba(0,0,0,0.2);
|
|
28
|
+
--shadow-md: 0 2px 8px rgba(0,0,0,0.3);
|
|
29
|
+
--shadow-lg: 0 4px 16px rgba(0,0,0,0.4);
|
|
30
|
+
|
|
31
|
+
/* Transitions */
|
|
32
|
+
--transition-fast: 0.15s; --transition-base: 0.2s; --transition-slow: 0.3s;
|
|
13
33
|
}
|
|
14
34
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
15
|
-
body { background: var(--bg); color: var(--text); font-family: 'Segoe UI', system-ui, sans-serif; font-size:
|
|
35
|
+
body { background: var(--bg); color: var(--text); font-family: 'Segoe UI', system-ui, sans-serif; font-size: var(--text-xl); overflow-x: hidden; }
|
|
16
36
|
|
|
17
37
|
header {
|
|
18
38
|
background: var(--surface); border-bottom: 1px solid var(--border);
|
|
19
|
-
padding:
|
|
39
|
+
padding: var(--space-6) var(--space-9); display: flex; align-items: center; justify-content: space-between;
|
|
20
40
|
position: sticky; top: 0; z-index: 100;
|
|
21
41
|
}
|
|
22
|
-
header h1 { font-size:
|
|
23
|
-
header h1 span { color: var(--muted); font-weight: 400; font-size:
|
|
24
|
-
.pulse { width: 8px; height: 8px; border-radius:
|
|
42
|
+
header h1 { font-size: var(--text-2xl); font-weight: 600; color: var(--blue); letter-spacing: 0.5px; }
|
|
43
|
+
header h1 span { color: var(--muted); font-weight: 400; font-size: var(--text-lg); margin-left: var(--space-4); }
|
|
44
|
+
.pulse { width: 8px; height: 8px; border-radius: var(--radius-full); background: var(--green); display: inline-block; margin-right: var(--space-3); animation: pulse 2s infinite; }
|
|
25
45
|
@keyframes pulse { 0%,100%{opacity:1} 50%{opacity:0.3} }
|
|
26
|
-
.timestamp { color: var(--muted); font-size:
|
|
46
|
+
.timestamp { color: var(--muted); font-size: var(--text-md); font-variant-numeric: tabular-nums; }
|
|
27
47
|
|
|
28
48
|
.layout { display: grid; grid-template-columns: 1fr 1fr; gap: 0; max-width: 100vw; overflow-x: hidden; }
|
|
29
|
-
section { padding:
|
|
49
|
+
section { padding: var(--space-8) var(--space-9); border-bottom: 1px solid var(--border); overflow: hidden; min-width: 0; }
|
|
30
50
|
section:nth-child(odd) { border-right: 1px solid var(--border); }
|
|
31
|
-
section h2 { font-size:
|
|
32
|
-
section h2 .count { background: var(--surface2); border: 1px solid var(--border); border-radius:
|
|
51
|
+
section h2 { font-size: var(--text-base); font-weight: 600; text-transform: uppercase; letter-spacing: 1px; color: var(--muted); margin-bottom: 14px; display: flex; align-items: center; gap: var(--space-4); }
|
|
52
|
+
section h2 .count { background: var(--surface2); border: 1px solid var(--border); border-radius: var(--radius-xl); padding: var(--space-1) 7px; font-size: var(--text-base); color: var(--text); }
|
|
33
53
|
|
|
34
|
-
.agents { display: grid; grid-template-columns: 1fr 1fr; gap:
|
|
54
|
+
.agents { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-5); }
|
|
35
55
|
.agent-card {
|
|
36
|
-
background: var(--surface2); border: 1px solid var(--border); border-radius:
|
|
37
|
-
padding:
|
|
56
|
+
background: var(--surface2); border: 1px solid var(--border); border-radius: var(--radius-lg);
|
|
57
|
+
padding: var(--space-6) var(--space-7); transition: all var(--transition-slow); cursor: pointer;
|
|
38
58
|
}
|
|
39
|
-
.agent-card:hover { border-color: var(--blue); transform: translateY(-1px); box-shadow:
|
|
59
|
+
.agent-card:hover { border-color: var(--blue); transform: translateY(-1px); box-shadow: var(--shadow-md); }
|
|
40
60
|
.agent-card.working { border-color: var(--yellow); }
|
|
41
61
|
.agent-card.done { border-color: var(--green); }
|
|
42
|
-
.agent-card-header { display: flex; align-items: center; justify-content: space-between; margin-bottom:
|
|
43
|
-
.agent-name { font-weight: 600; font-size:
|
|
44
|
-
.agent-role { font-size:
|
|
45
|
-
.status-badge { font-size:
|
|
62
|
+
.agent-card-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--space-3); }
|
|
63
|
+
.agent-name { font-weight: 600; font-size: var(--text-xl); }
|
|
64
|
+
.agent-role { font-size: var(--text-base); color: var(--muted); margin-bottom: var(--space-4); }
|
|
65
|
+
.status-badge { font-size: var(--text-sm); font-weight: 600; padding: var(--space-1) var(--space-4); border-radius: var(--radius-xl); text-transform: uppercase; letter-spacing: 0.5px; }
|
|
46
66
|
.status-badge.idle { background: var(--surface); color: var(--muted); border: 1px solid var(--border); }
|
|
47
67
|
.status-badge.working { background: rgba(210,153,34,0.15); color: var(--yellow); border: 1px solid var(--yellow); animation: pulse 1.5s infinite; }
|
|
48
68
|
.status-badge.done { background: rgba(63,185,80,0.15); color: var(--green); border: 1px solid var(--green); }
|
|
49
|
-
.agent-action { font-size:
|
|
50
|
-
.modal-qa { border-top: 1px solid var(--border); padding:
|
|
51
|
-
.modal-qa-thread { max-height: 200px; overflow-y: auto; margin-bottom:
|
|
52
|
-
.modal-qa-q { font-size:
|
|
53
|
-
.modal-qa-q .selection-ref { font-weight: 400; color: var(--muted); font-style: italic; display: block; font-size:
|
|
54
|
-
.modal-qa-a { font-size:
|
|
55
|
-
.modal-qa-loading { font-size:
|
|
69
|
+
.agent-action { font-size: var(--text-base); color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
|
|
70
|
+
.modal-qa { border-top: 1px solid var(--border); padding: var(--space-5) var(--space-8); }
|
|
71
|
+
.modal-qa-thread { max-height: 200px; overflow-y: auto; margin-bottom: var(--space-4); }
|
|
72
|
+
.modal-qa-q { font-size: var(--text-md); color: var(--blue); margin-bottom: var(--space-2); font-weight: 600; }
|
|
73
|
+
.modal-qa-q .selection-ref { font-weight: 400; color: var(--muted); font-style: italic; display: block; font-size: var(--text-sm); margin-top: var(--space-1); }
|
|
74
|
+
.modal-qa-a { font-size: var(--text-md); color: var(--text); margin-bottom: var(--space-6); padding: var(--space-4) var(--space-5); background: var(--surface2); border-radius: var(--radius-md); border-left: 2px solid var(--blue); white-space: pre-wrap; word-break: break-word; line-height: 1.5; }
|
|
75
|
+
.modal-qa-loading { font-size: var(--text-base); color: var(--muted); padding: var(--space-4) var(--space-5); display: flex; align-items: center; gap: var(--space-4); }
|
|
56
76
|
.modal-qa-loading .dot-pulse { display: inline-flex; gap: 3px; }
|
|
57
77
|
.modal-qa-loading .dot-pulse span { width: 5px; height: 5px; background: var(--blue); border-radius: 50%; animation: dotPulse 1.2s infinite; }
|
|
58
78
|
.modal-qa-loading .dot-pulse span:nth-child(2) { animation-delay: 0.2s; }
|
|
59
79
|
.modal-qa-loading .dot-pulse span:nth-child(3) { animation-delay: 0.4s; }
|
|
60
80
|
@keyframes dotPulse { 0%, 80%, 100% { opacity: 0.3; transform: scale(0.8); } 40% { opacity: 1; transform: scale(1); } }
|
|
61
|
-
.modal-qa-selection-pill { display: flex; align-items: center; gap:
|
|
81
|
+
.modal-qa-selection-pill { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-2) var(--space-4); margin-bottom: var(--space-3); background: rgba(88,166,255,0.08); border: 1px solid rgba(88,166,255,0.25); border-radius: var(--radius-sm); font-size: var(--text-base); }
|
|
62
82
|
.modal-qa-selection-pill .pill-label { color: var(--blue); font-weight: 600; white-space: nowrap; }
|
|
63
83
|
.modal-qa-selection-pill .pill-text { color: var(--muted); flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-style: italic; }
|
|
64
84
|
.modal-qa-selection-pill .pill-clear { background: none; border: none; color: var(--muted); cursor: pointer; font-size: 14px; padding: 0 2px; line-height: 1; }
|
|
65
85
|
.modal-qa-selection-pill .pill-clear:hover { color: var(--red); }
|
|
66
86
|
.modal-qa-input-wrap { display: flex; gap: 6px; }
|
|
67
|
-
.modal-qa-input { flex: 1; background: var(--bg); border: 1px solid var(--border); border-radius:
|
|
87
|
+
.modal-qa-input { flex: 1; background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: var(--space-3) var(--space-5); font-size: var(--text-md); color: var(--text); font-family: inherit; }
|
|
68
88
|
.modal-qa-input:focus { border-color: var(--blue); outline: none; }
|
|
69
|
-
.modal-qa-btn { background: var(--blue); color: #fff; border: none; border-radius:
|
|
89
|
+
.modal-qa-btn { background: var(--blue); color: #fff; border: none; border-radius: var(--radius-sm); padding: var(--space-3) var(--space-7); font-size: var(--text-md); cursor: pointer; }
|
|
70
90
|
.modal-qa-btn:hover { opacity: 0.9; }
|
|
71
91
|
.modal-qa-btn:disabled { opacity: 0.4; cursor: not-allowed; }
|
|
72
|
-
.ask-selection-btn { display: none; position: fixed; z-index: 500; background: var(--blue); color: #fff; font-size:
|
|
92
|
+
.ask-selection-btn { display: none; position: fixed; z-index: 500; background: var(--blue); color: #fff; font-size: var(--text-base); padding: 5px var(--space-6); border-radius: var(--radius-sm); cursor: pointer; box-shadow: var(--shadow-md); }
|
|
73
93
|
.ask-selection-btn:hover { opacity: 0.9; }
|
|
74
|
-
.plan-card { background: var(--surface2); border: 1px solid var(--border); border-radius:
|
|
75
|
-
.plan-card
|
|
94
|
+
.plan-card { background: var(--surface2); border: 1px solid var(--border); border-radius: var(--radius-md); padding: var(--space-6); margin-bottom: var(--space-4); transition: border-color var(--transition-base); }
|
|
95
|
+
.plan-card:hover { border-color: var(--blue); }
|
|
96
|
+
.plan-card.awaiting { border-left: 3px solid var(--yellow); }
|
|
76
97
|
.plan-card.approved { border-left: 3px solid var(--green); }
|
|
77
98
|
.plan-card.rejected { border-left: 3px solid var(--red); opacity: 0.6; }
|
|
78
|
-
.plan-card.revision-requested { border-left: 3px solid var(--purple
|
|
79
|
-
.plan-card-header { display: flex; justify-content: space-between; align-items: flex-start; gap:
|
|
80
|
-
.plan-card-title { font-size:
|
|
81
|
-
.plan-card-meta { font-size:
|
|
82
|
-
.plan-card-actions { display: flex; gap:
|
|
83
|
-
.plan-btn { font-size:
|
|
99
|
+
.plan-card.revision-requested { border-left: 3px solid var(--purple); }
|
|
100
|
+
.plan-card-header { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--space-4); }
|
|
101
|
+
.plan-card-title { font-size: var(--text-lg); font-weight: 600; color: var(--text); }
|
|
102
|
+
.plan-card-meta { font-size: var(--text-sm); color: var(--muted); margin-top: var(--space-2); display: flex; gap: var(--space-4); flex-wrap: wrap; }
|
|
103
|
+
.plan-card-actions { display: flex; gap: var(--space-2); margin-top: var(--space-4); flex-wrap: wrap; }
|
|
104
|
+
.plan-btn { font-size: var(--text-base); padding: var(--space-2) var(--space-5); border-radius: var(--radius-sm); cursor: pointer; border: 1px solid var(--border); background: var(--surface); color: var(--text); transition: all var(--transition-fast); position: relative; z-index: 1; }
|
|
84
105
|
.plan-btn:hover { border-color: var(--text); }
|
|
85
106
|
.plan-btn.approve { color: var(--green); border-color: var(--green); }
|
|
86
107
|
.plan-btn.approve:hover { background: rgba(63,185,80,0.1); }
|
|
87
|
-
.plan-btn.revise { color: var(--yellow
|
|
108
|
+
.plan-btn.revise { color: var(--yellow); border-color: var(--yellow); }
|
|
88
109
|
.plan-btn.revise:hover { background: rgba(210,153,34,0.1); }
|
|
89
110
|
.plan-btn.reject { color: var(--red); border-color: var(--red); }
|
|
90
111
|
.plan-btn.reject:hover { background: rgba(248,81,73,0.1); }
|
|
91
|
-
.plan-feedback-input { width: 100%; margin-top:
|
|
92
|
-
.token-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap:
|
|
93
|
-
.token-tile { background: var(--surface2); border: 1px solid var(--border); border-radius:
|
|
94
|
-
.token-tile-label { font-size:
|
|
95
|
-
.token-tile-value { font-size:
|
|
96
|
-
.token-tile-sub { font-size:
|
|
112
|
+
.plan-feedback-input { width: 100%; margin-top: var(--space-3); padding: var(--space-3) var(--space-4); font-size: var(--text-base); background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-sm); color: var(--text); font-family: inherit; resize: vertical; min-height: 50px; }
|
|
113
|
+
.token-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: var(--space-4); margin-bottom: var(--space-6); }
|
|
114
|
+
.token-tile { background: var(--surface2); border: 1px solid var(--border); border-radius: var(--radius-md); padding: var(--space-5) var(--space-6); }
|
|
115
|
+
.token-tile-label { font-size: var(--text-sm); color: var(--muted); text-transform: uppercase; letter-spacing: 0.5px; }
|
|
116
|
+
.token-tile-value { font-size: var(--text-stat); font-weight: 700; color: var(--text); margin-top: var(--space-1); }
|
|
117
|
+
.token-tile-sub { font-size: var(--text-sm); color: var(--muted); margin-top: var(--space-1); }
|
|
97
118
|
.token-chart { display: flex; align-items: flex-end; gap: 3px; height: 80px; margin: 8px 0; }
|
|
98
119
|
.token-bar { flex: 1; min-width: 8px; max-width: 24px; background: var(--blue); border-radius: 2px 2px 0 0; position: relative; cursor: default; transition: background 0.15s; }
|
|
99
120
|
.token-bar:hover { background: var(--green); }
|
|
@@ -101,89 +122,89 @@
|
|
|
101
122
|
.token-bar:hover .token-bar-tip { display: block; }
|
|
102
123
|
.token-chart-labels { display: flex; gap: 3px; }
|
|
103
124
|
.token-chart-labels span { flex: 1; min-width: 8px; max-width: 24px; font-size: 8px; color: var(--muted); text-align: center; overflow: hidden; }
|
|
104
|
-
.token-agent-table { width: 100%; margin-top:
|
|
105
|
-
.token-agent-table th { text-align: left; font-size:
|
|
106
|
-
.token-agent-table td { font-size:
|
|
107
|
-
.kb-tabs { display: flex; gap:
|
|
108
|
-
.kb-tab { background: var(--surface2); border: 1px solid var(--border); color: var(--muted); font-size:
|
|
125
|
+
.token-agent-table { width: 100%; margin-top: var(--space-5); }
|
|
126
|
+
.token-agent-table th { text-align: left; font-size: var(--text-sm); color: var(--muted); font-weight: 500; padding: var(--space-2) var(--space-4); border-bottom: 1px solid var(--border); }
|
|
127
|
+
.token-agent-table td { font-size: var(--text-base); padding: var(--space-2) var(--space-4); }
|
|
128
|
+
.kb-tabs { display: flex; gap: var(--space-2); flex-wrap: wrap; margin-bottom: var(--space-4); }
|
|
129
|
+
.kb-tab { background: var(--surface2); border: 1px solid var(--border); color: var(--muted); font-size: var(--text-base); cursor: pointer; padding: var(--space-1) var(--space-5); border-radius: var(--radius-sm); transition: all var(--transition-base); }
|
|
109
130
|
.kb-tab:hover { color: var(--text); border-color: var(--text); }
|
|
110
131
|
.kb-tab.active { color: var(--blue); border-color: var(--blue); background: rgba(88,166,255,0.08); }
|
|
111
|
-
.kb-tab .badge { background: var(--border); color: var(--text); font-size:
|
|
132
|
+
.kb-tab .badge { background: var(--border); color: var(--text); font-size: var(--text-xs); padding: 0 5px; border-radius: var(--radius-lg); margin-left: var(--space-2); }
|
|
112
133
|
.kb-list { max-height: 400px; overflow-y: auto; }
|
|
113
|
-
.kb-item { display: flex; align-items: flex-start; gap:
|
|
134
|
+
.kb-item { display: flex; align-items: flex-start; gap: var(--space-5); padding: var(--space-4) 0; border-bottom: 1px solid var(--border); cursor: pointer; transition: background var(--transition-fast); }
|
|
114
135
|
.kb-item:hover { background: var(--surface2); }
|
|
115
136
|
.kb-item:last-child { border-bottom: none; }
|
|
116
137
|
.kb-item-body { flex: 1; min-width: 0; }
|
|
117
|
-
.kb-item-title { font-size:
|
|
118
|
-
.kb-item-meta { font-size:
|
|
119
|
-
.kb-item-preview { font-size:
|
|
120
|
-
.agent-result { font-size:
|
|
138
|
+
.kb-item-title { font-size: var(--text-md); color: var(--text); font-weight: 500; }
|
|
139
|
+
.kb-item-meta { font-size: var(--text-sm); color: var(--muted); margin-top: var(--space-1); display: flex; gap: var(--space-4); }
|
|
140
|
+
.kb-item-preview { font-size: var(--text-sm); color: var(--muted); margin-top: var(--space-1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
|
|
141
|
+
.agent-result { font-size: var(--text-sm); color: var(--text); background: var(--surface2); padding: var(--space-3) var(--space-4); border-radius: var(--radius-sm); margin-top: var(--space-3); white-space: pre-wrap; word-break: break-word; max-height: 80px; overflow-y: auto; line-height: 1.4; border-left: 2px solid var(--blue); }
|
|
121
142
|
.agent-card { min-width: 0; }
|
|
122
|
-
.agent-emoji { font-size:
|
|
123
|
-
.click-hint { font-size:
|
|
143
|
+
.agent-emoji { font-size: var(--text-stat); margin-right: var(--space-2); }
|
|
144
|
+
.click-hint { font-size: var(--text-sm); color: var(--border); margin-top: var(--space-3); }
|
|
124
145
|
|
|
125
|
-
.inbox-list { display: flex; flex-direction: column; gap:
|
|
146
|
+
.inbox-list { display: flex; flex-direction: column; gap: var(--space-4); max-height: 320px; overflow-y: auto; }
|
|
126
147
|
|
|
127
148
|
/* PRD Progress */
|
|
128
|
-
.prd-progress-bar { width: 100%; height: 20px; background: var(--bg); border-radius:
|
|
149
|
+
.prd-progress-bar { width: 100%; height: 20px; background: var(--bg); border-radius: var(--radius-xl); overflow: hidden; display: flex; margin-bottom: var(--space-6); border: 1px solid var(--border); }
|
|
129
150
|
.prd-progress-bar .seg { height: 100%; transition: width 0.5s ease; }
|
|
130
151
|
.prd-progress-bar .seg.complete { background: var(--green); }
|
|
131
152
|
.prd-progress-bar .seg.pr-created { background: #2ea043; }
|
|
132
153
|
.prd-progress-bar .seg.in-progress { background: var(--yellow); }
|
|
133
154
|
.prd-progress-bar .seg.planned { background: var(--blue); opacity: 0.4; }
|
|
134
155
|
.prd-progress-bar .seg.missing { background: var(--border); }
|
|
135
|
-
.prd-progress-pct { font-size: 22px; font-weight: 700; color: var(--green); margin-bottom:
|
|
136
|
-
.prd-progress-legend { display: flex; flex-wrap: wrap; gap:
|
|
137
|
-
.prd-legend-item { display: flex; align-items: center; gap: 5px; font-size:
|
|
156
|
+
.prd-progress-pct { font-size: 22px; font-weight: 700; color: var(--green); margin-bottom: var(--space-4); }
|
|
157
|
+
.prd-progress-legend { display: flex; flex-wrap: wrap; gap: var(--space-6); margin-bottom: var(--space-6); }
|
|
158
|
+
.prd-legend-item { display: flex; align-items: center; gap: 5px; font-size: var(--text-base); color: var(--muted); }
|
|
138
159
|
.prd-legend-dot { width: 10px; height: 10px; border-radius: 2px; }
|
|
139
160
|
.prd-legend-dot.complete { background: var(--green); }
|
|
140
161
|
.prd-legend-dot.pr-created { background: #2ea043; }
|
|
141
162
|
.prd-legend-dot.in-progress { background: var(--yellow); }
|
|
142
163
|
.prd-legend-dot.planned { background: var(--blue); opacity: 0.4; }
|
|
143
164
|
.prd-legend-dot.missing { background: var(--border); }
|
|
144
|
-
.prd-items-list { display: flex; flex-direction: column; gap:
|
|
145
|
-
.prd-item-row { display: flex; align-items: center; gap:
|
|
165
|
+
.prd-items-list { display: flex; flex-direction: column; gap: var(--space-2); max-height: 200px; overflow-y: auto; }
|
|
166
|
+
.prd-item-row { display: flex; align-items: center; gap: var(--space-4); padding: 5px var(--space-4); border-radius: var(--radius-sm); font-size: var(--text-base); background: var(--surface2); border: 1px solid var(--border); }
|
|
146
167
|
.prd-item-id { font-family: Consolas, monospace; color: var(--blue); min-width: 36px; }
|
|
147
168
|
.prd-item-name { flex: 1; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
148
|
-
.prd-item-priority { font-size:
|
|
169
|
+
.prd-item-priority { font-size: var(--text-sm); padding: var(--space-1) var(--space-3); border-radius: var(--radius-lg); }
|
|
149
170
|
.prd-item-priority.high { background: rgba(248,81,73,0.15); color: var(--red); }
|
|
150
171
|
.prd-item-priority.medium { background: rgba(210,153,34,0.15); color: var(--yellow); }
|
|
151
172
|
.prd-item-priority.low { background: rgba(139,148,158,0.15); color: var(--muted); }
|
|
152
|
-
.prd-project-badge { font-size:
|
|
173
|
+
.prd-project-badge { font-size: var(--text-xs); padding: var(--space-1) 5px; border-radius: var(--radius-md); background: rgba(56,139,253,0.12); color: var(--blue); border: 1px solid rgba(56,139,253,0.25); white-space: nowrap; }
|
|
153
174
|
|
|
154
|
-
.notes-preview { max-height: 400px; overflow-y: auto; font-size:
|
|
175
|
+
.notes-preview { max-height: 400px; overflow-y: auto; font-size: var(--text-md); line-height: 1.6; color: var(--muted); font-family: Consolas, monospace; white-space: pre-wrap; word-wrap: break-word; background: var(--surface2); border: 1px solid var(--border); border-radius: var(--radius-md); padding: var(--space-6) var(--space-7); cursor: pointer; transition: border-color var(--transition-base); }
|
|
155
176
|
.notes-preview:hover { border-color: var(--blue); }
|
|
156
|
-
.inbox-item { background: var(--surface2); border: 1px solid var(--border); border-left: 3px solid var(--purple); border-radius:
|
|
177
|
+
.inbox-item { background: var(--surface2); border: 1px solid var(--border); border-left: 3px solid var(--purple); border-radius: var(--radius-sm); padding: var(--space-5) var(--space-6); cursor: pointer; }
|
|
157
178
|
.inbox-item:hover { border-color: var(--blue); border-left-color: var(--blue); }
|
|
158
|
-
.inbox-name { font-weight: 500; font-size:
|
|
159
|
-
.inbox-preview { font-size:
|
|
179
|
+
.inbox-name { font-weight: 500; font-size: var(--text-md); color: var(--purple); margin-bottom: var(--space-2); display: flex; justify-content: space-between; }
|
|
180
|
+
.inbox-preview { font-size: var(--text-base); color: var(--muted); line-height: 1.5; max-height: 60px; overflow: hidden; }
|
|
160
181
|
|
|
161
182
|
.prd-panel, .pr-panel { grid-column: 1 / -1; border-bottom: 1px solid var(--border); overflow: visible; min-width: 0; }
|
|
162
183
|
.prd-inner { display: flex; gap: 16px; align-items: flex-start; }
|
|
163
184
|
.prd-stats { display: flex; gap: 16px; }
|
|
164
|
-
.prd-stat { text-align: center; background: var(--surface2); border: 1px solid var(--border); border-radius:
|
|
185
|
+
.prd-stat { text-align: center; background: var(--surface2); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: var(--space-6) var(--space-8); }
|
|
165
186
|
.prd-stat-num { font-size: 28px; font-weight: 700; color: var(--blue); }
|
|
166
187
|
.prd-stat-num.green { color: var(--green); }
|
|
167
188
|
.prd-stat-num.red { color: var(--red); }
|
|
168
189
|
.prd-stat-num.orange { color: var(--orange); }
|
|
169
|
-
.prd-stat-label { font-size:
|
|
170
|
-
.prd-summary { flex: 1; font-size:
|
|
190
|
+
.prd-stat-label { font-size: var(--text-base); color: var(--muted); margin-top: var(--space-1); }
|
|
191
|
+
.prd-summary { flex: 1; font-size: var(--text-lg); color: var(--muted); line-height: 1.6; background: var(--surface2); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 14px; }
|
|
171
192
|
.prd-pending { color: var(--yellow); font-style: italic; }
|
|
172
193
|
|
|
173
194
|
/* PR Tracker */
|
|
174
195
|
.pr-table-wrap { overflow-x: auto; }
|
|
175
|
-
.pr-table { width: 100%; border-collapse: collapse; font-size:
|
|
196
|
+
.pr-table { width: 100%; border-collapse: collapse; font-size: var(--text-md); table-layout: auto; }
|
|
176
197
|
.pr-table th:last-child, .pr-table td:last-child { width: 36px; min-width: 36px; text-align: center; }
|
|
177
|
-
.pr-table th { text-align: left; color: var(--muted); font-weight: 500; font-size:
|
|
178
|
-
.pr-table td { padding:
|
|
198
|
+
.pr-table th { text-align: left; color: var(--muted); font-weight: 500; font-size: var(--text-base); text-transform: uppercase; letter-spacing: 0.5px; padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--border); }
|
|
199
|
+
.pr-table td { padding: var(--space-5); border-bottom: 1px solid var(--border); vertical-align: middle; white-space: nowrap; }
|
|
179
200
|
.pr-table tr:last-child td { border-bottom: none; }
|
|
180
201
|
.pr-table tr:hover { background: var(--surface2); }
|
|
181
202
|
.pr-title { color: var(--blue); text-decoration: none; font-weight: 500; }
|
|
182
203
|
.pr-title:hover { text-decoration: underline; }
|
|
183
|
-
.pr-id { color: var(--muted); font-family: Consolas, monospace; font-size:
|
|
184
|
-
.pr-agent { font-size:
|
|
185
|
-
.pr-branch { font-family: Consolas, monospace; font-size:
|
|
186
|
-
.pr-badge { font-size:
|
|
204
|
+
.pr-id { color: var(--muted); font-family: Consolas, monospace; font-size: var(--text-base); }
|
|
205
|
+
.pr-agent { font-size: var(--text-base); color: var(--text); }
|
|
206
|
+
.pr-branch { font-family: Consolas, monospace; font-size: var(--text-sm); color: var(--muted); background: var(--bg); padding: var(--space-1) var(--space-3); border-radius: 3px; border: 1px solid var(--border); }
|
|
207
|
+
.pr-badge { font-size: var(--text-sm); font-weight: 600; padding: var(--space-1) var(--space-4); border-radius: var(--radius-xl); text-transform: uppercase; letter-spacing: 0.5px; white-space: nowrap; }
|
|
187
208
|
.pr-badge.draft { background: rgba(139,148,158,0.15); color: var(--muted); border: 1px solid var(--border); }
|
|
188
209
|
.pr-badge.active { background: rgba(88,166,255,0.15); color: var(--blue); border: 1px solid var(--blue); }
|
|
189
210
|
.pr-badge.approved { background: rgba(63,185,80,0.15); color: var(--green); border: 1px solid var(--green); }
|
|
@@ -193,55 +214,118 @@
|
|
|
193
214
|
.pr-badge.build-pass { background: rgba(63,185,80,0.15); color: var(--green); border: 1px solid var(--green); }
|
|
194
215
|
.pr-badge.build-fail { background: rgba(248,81,73,0.15); color: var(--red); border: 1px solid var(--red); }
|
|
195
216
|
.pr-badge.no-build { background: var(--surface); color: var(--muted); border: 1px solid var(--border); }
|
|
196
|
-
.error-details-btn { font-size:
|
|
217
|
+
.error-details-btn { font-size: var(--text-xs); padding: var(--space-1) var(--space-3); margin-left: var(--space-2); background: rgba(248,81,73,0.15); color: var(--red); border: 1px solid var(--red); border-radius: var(--radius-lg); cursor: pointer; font-weight: 600; text-transform: uppercase; letter-spacing: 0.3px; }
|
|
197
218
|
.error-details-btn:hover { background: rgba(248,81,73,0.3); }
|
|
198
|
-
.pr-empty { color: var(--muted); font-style: italic; font-size:
|
|
219
|
+
.pr-empty { color: var(--muted); font-style: italic; font-size: var(--text-md); padding: var(--space-6) 0; }
|
|
199
220
|
.pr-pager { display: flex; align-items: center; justify-content: space-between; margin-top: 10px; }
|
|
200
221
|
.pr-pager-btns { display: flex; gap: 6px; }
|
|
201
222
|
.pr-pager-btn {
|
|
202
223
|
background: var(--surface2); border: 1px solid var(--border); color: var(--muted);
|
|
203
|
-
font-size:
|
|
224
|
+
font-size: var(--text-base); padding: var(--space-2) var(--space-5); border-radius: var(--radius-sm); cursor: pointer; transition: all var(--transition-base);
|
|
204
225
|
}
|
|
205
226
|
.pr-pager-btn:hover { color: var(--text); border-color: var(--text); }
|
|
206
227
|
.pr-pager-btn.disabled { opacity: 0.3; pointer-events: none; }
|
|
207
228
|
.pr-pager-btn.see-all { color: var(--blue); border-color: var(--blue); }
|
|
208
229
|
.pr-pager-btn.see-all:hover { background: rgba(88,166,255,0.1); }
|
|
209
|
-
.pr-page-info { font-size:
|
|
210
|
-
.pr-date { font-size:
|
|
230
|
+
.pr-page-info { font-size: var(--text-base); color: var(--muted); }
|
|
231
|
+
.pr-date { font-size: var(--text-base); color: var(--muted); }
|
|
211
232
|
|
|
212
233
|
.archive-btn {
|
|
213
234
|
background: var(--surface2); border: 1px solid var(--border); color: var(--muted);
|
|
214
|
-
font-size:
|
|
235
|
+
font-size: var(--text-base); padding: var(--space-2) var(--space-5); border-radius: var(--radius-sm); cursor: pointer; transition: all var(--transition-base); margin-left: auto;
|
|
215
236
|
}
|
|
216
237
|
.archive-btn:hover { color: var(--purple); border-color: var(--purple); }
|
|
217
|
-
.archive-list { display: flex; flex-direction: column; gap:
|
|
218
|
-
.archive-card { background: var(--surface2); border: 1px solid var(--border); border-radius:
|
|
238
|
+
.archive-list { display: flex; flex-direction: column; gap: var(--space-4); }
|
|
239
|
+
.archive-card { background: var(--surface2); border: 1px solid var(--border); border-radius: var(--radius-md); padding: var(--space-6) var(--space-7); cursor: pointer; transition: all var(--transition-base); }
|
|
219
240
|
.archive-card:hover { border-color: var(--purple); }
|
|
220
|
-
.archive-card h4 { color: var(--purple); font-size:
|
|
221
|
-
.archive-card p { font-size:
|
|
222
|
-
.archive-detail-section { margin-bottom:
|
|
223
|
-
.archive-detail-section h4 { color: var(--blue); font-size:
|
|
224
|
-
.archive-feature { background: var(--surface2); border: 1px solid var(--border); border-radius:
|
|
225
|
-
.archive-feature .feat-id { font-family: Consolas, monospace; color: var(--blue); font-size:
|
|
226
|
-
.archive-feature .feat-name { font-weight: 600; font-size:
|
|
227
|
-
.archive-feature .feat-desc { font-size:
|
|
228
|
-
.archive-feature .feat-meta { font-size:
|
|
229
|
-
.archive-question { background: var(--surface2); border: 1px solid var(--border); border-left: 3px solid var(--orange); border-radius:
|
|
230
|
-
.archive-question .q-id { font-family: Consolas, monospace; color: var(--orange); font-size:
|
|
231
|
-
.archive-question .q-text { font-size:
|
|
232
|
-
.archive-question .q-context { font-size:
|
|
241
|
+
.archive-card h4 { color: var(--purple); font-size: var(--text-lg); margin-bottom: var(--space-3); }
|
|
242
|
+
.archive-card p { font-size: var(--text-base); color: var(--muted); line-height: 1.5; }
|
|
243
|
+
.archive-detail-section { margin-bottom: var(--space-7); }
|
|
244
|
+
.archive-detail-section h4 { color: var(--blue); font-size: var(--text-lg); margin-bottom: var(--space-4); font-family: 'Segoe UI', sans-serif; }
|
|
245
|
+
.archive-feature { background: var(--surface2); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: var(--space-5) var(--space-6); margin-bottom: var(--space-3); }
|
|
246
|
+
.archive-feature .feat-id { font-family: Consolas, monospace; color: var(--blue); font-size: var(--text-base); }
|
|
247
|
+
.archive-feature .feat-name { font-weight: 600; font-size: var(--text-md); color: var(--text); margin: var(--space-2) 0; }
|
|
248
|
+
.archive-feature .feat-desc { font-size: var(--text-base); color: var(--muted); line-height: 1.5; }
|
|
249
|
+
.archive-feature .feat-meta { font-size: var(--text-sm); color: var(--muted); margin-top: var(--space-3); display: flex; gap: var(--space-6); }
|
|
250
|
+
.archive-question { background: var(--surface2); border: 1px solid var(--border); border-left: 3px solid var(--orange); border-radius: var(--radius-sm); padding: var(--space-5) var(--space-6); margin-bottom: var(--space-3); }
|
|
251
|
+
.archive-question .q-id { font-family: Consolas, monospace; color: var(--orange); font-size: var(--text-base); }
|
|
252
|
+
.archive-question .q-text { font-size: var(--text-md); color: var(--text); margin: var(--space-2) 0; }
|
|
253
|
+
.archive-question .q-context { font-size: var(--text-base); color: var(--muted); line-height: 1.5; }
|
|
254
|
+
|
|
255
|
+
/* ── Base component classes ────────────────────────────────────────── */
|
|
256
|
+
|
|
257
|
+
/* Card — unified card base */
|
|
258
|
+
.card {
|
|
259
|
+
background: var(--surface2); border: 1px solid var(--border);
|
|
260
|
+
border-radius: var(--radius-lg); padding: var(--space-6) var(--space-7);
|
|
261
|
+
transition: border-color var(--transition-base);
|
|
262
|
+
}
|
|
263
|
+
.card:hover { border-color: var(--blue); }
|
|
264
|
+
.card.clickable { cursor: pointer; }
|
|
265
|
+
|
|
266
|
+
/* Button — unified button base */
|
|
267
|
+
.btn {
|
|
268
|
+
font-size: var(--text-base); padding: var(--space-2) var(--space-5);
|
|
269
|
+
border-radius: var(--radius-sm); border: 1px solid var(--border);
|
|
270
|
+
background: var(--surface); color: var(--text); cursor: pointer;
|
|
271
|
+
transition: all var(--transition-fast);
|
|
272
|
+
}
|
|
273
|
+
.btn:hover { border-color: var(--text); }
|
|
274
|
+
.btn:disabled { opacity: 0.4; cursor: not-allowed; }
|
|
275
|
+
.btn-primary { background: var(--blue); color: #fff; border: none; }
|
|
276
|
+
.btn-primary:hover { opacity: 0.9; }
|
|
277
|
+
.btn-sm { font-size: var(--text-xs); padding: var(--space-1) var(--space-3); }
|
|
278
|
+
.btn-success { color: var(--green); border-color: var(--green); }
|
|
279
|
+
.btn-danger { color: var(--red); border-color: var(--red); }
|
|
280
|
+
.btn-warning { color: var(--yellow); border-color: var(--yellow); }
|
|
281
|
+
|
|
282
|
+
/* Badge — unified badge/pill base */
|
|
283
|
+
.badge {
|
|
284
|
+
font-size: var(--text-sm); font-weight: 600;
|
|
285
|
+
padding: var(--space-1) var(--space-4);
|
|
286
|
+
border-radius: var(--radius-xl); text-transform: uppercase; white-space: nowrap;
|
|
287
|
+
}
|
|
288
|
+
.badge-blue { background: rgba(88,166,255,0.15); color: var(--blue); border: 1px solid var(--blue); }
|
|
289
|
+
.badge-green { background: rgba(63,185,80,0.15); color: var(--green); border: 1px solid var(--green); }
|
|
290
|
+
.badge-red { background: rgba(248,81,73,0.15); color: var(--red); border: 1px solid var(--red); }
|
|
291
|
+
.badge-yellow { background: rgba(210,153,34,0.15); color: var(--yellow); border: 1px solid var(--yellow); }
|
|
292
|
+
.badge-purple { background: rgba(188,140,255,0.15); color: var(--purple); border: 1px solid var(--purple); }
|
|
293
|
+
.badge-muted { background: var(--surface); color: var(--muted); border: 1px solid var(--border); }
|
|
294
|
+
|
|
295
|
+
/* Table — unified table base */
|
|
296
|
+
.table { width: 100%; border-collapse: collapse; font-size: var(--text-md); }
|
|
297
|
+
.table th { font-size: var(--text-sm); text-transform: uppercase; letter-spacing: 0.5px; color: var(--muted); padding: var(--space-4); border-bottom: 1px solid var(--border); text-align: left; font-weight: 500; }
|
|
298
|
+
.table td { padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--border); }
|
|
299
|
+
.table tr:hover { background: var(--surface2); }
|
|
300
|
+
|
|
301
|
+
/* ── Utility classes ───────────────────────────────────────────────── */
|
|
302
|
+
.text-muted { color: var(--muted); }
|
|
303
|
+
.text-sm { font-size: var(--text-sm); }
|
|
304
|
+
.text-xs { font-size: var(--text-xs); }
|
|
305
|
+
.text-md { font-size: var(--text-md); }
|
|
306
|
+
.text-green { color: var(--green); }
|
|
307
|
+
.text-red { color: var(--red); }
|
|
308
|
+
.text-blue { color: var(--blue); }
|
|
309
|
+
.text-yellow { color: var(--yellow); }
|
|
310
|
+
.text-purple { color: var(--purple); }
|
|
311
|
+
.flex-row { display: flex; gap: var(--space-4); align-items: center; }
|
|
312
|
+
.flex-col { display: flex; flex-direction: column; gap: var(--space-4); }
|
|
313
|
+
.flex-wrap { flex-wrap: wrap; }
|
|
314
|
+
.mono { font-family: Consolas, monospace; }
|
|
315
|
+
.font-bold { font-weight: 600; }
|
|
316
|
+
.truncate { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
233
317
|
|
|
234
318
|
::-webkit-scrollbar { width: 6px; }
|
|
235
319
|
::-webkit-scrollbar-track { background: var(--bg); }
|
|
236
320
|
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
|
|
237
|
-
.empty { color: var(--muted); font-style: italic; font-size:
|
|
321
|
+
.empty { color: var(--muted); font-style: italic; font-size: var(--text-md); padding: var(--space-4) 0; }
|
|
238
322
|
|
|
239
323
|
/* Command Center — Unified Input */
|
|
240
324
|
.cmd-center { grid-column: 1 / -1; overflow: visible !important; }
|
|
241
325
|
.cmd-input-wrap {
|
|
242
326
|
position: relative; display: flex; align-items: flex-start; gap: 0;
|
|
243
|
-
background: var(--bg); border: 2px solid var(--border); border-radius:
|
|
244
|
-
transition: border-color
|
|
327
|
+
background: var(--bg); border: 2px solid var(--border); border-radius: var(--radius-xl);
|
|
328
|
+
transition: border-color var(--transition-base), box-shadow var(--transition-base); padding: 0;
|
|
245
329
|
}
|
|
246
330
|
.cmd-input-wrap:focus-within { border-color: var(--blue); box-shadow: 0 0 0 3px rgba(88,166,255,0.12); }
|
|
247
331
|
.cmd-highlight-layer {
|
|
@@ -263,10 +347,10 @@
|
|
|
263
347
|
}
|
|
264
348
|
.cmd-input-wrap textarea::placeholder { color: var(--muted); }
|
|
265
349
|
.cmd-send-btn {
|
|
266
|
-
background: transparent; color: var(--blue); border: 1px solid var(--blue); padding:
|
|
267
|
-
border-radius: 0
|
|
268
|
-
transition: opacity
|
|
269
|
-
display: flex; align-items: center; gap:
|
|
350
|
+
background: transparent; color: var(--blue); border: 1px solid var(--blue); padding: var(--space-5) 18px;
|
|
351
|
+
border-radius: 0 var(--radius-lg) var(--radius-lg) 0; font-size: var(--text-lg); font-weight: 600; cursor: pointer;
|
|
352
|
+
transition: opacity var(--transition-base); white-space: nowrap; align-self: stretch; min-height: 48px;
|
|
353
|
+
display: flex; align-items: center; gap: var(--space-3);
|
|
270
354
|
}
|
|
271
355
|
.cmd-send-btn:hover { background: rgba(88,166,255,0.1); }
|
|
272
356
|
.cmd-send-btn:disabled { opacity: 0.4; cursor: not-allowed; }
|
|
@@ -275,9 +359,9 @@
|
|
|
275
359
|
/* Intent & meta chips */
|
|
276
360
|
.cmd-meta { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 4px; align-items: center; min-height: 0; }
|
|
277
361
|
.cmd-chip {
|
|
278
|
-
display: inline-flex; align-items: center; gap:
|
|
279
|
-
border-radius:
|
|
280
|
-
background: var(--surface2); color: var(--muted); cursor: default; transition: all
|
|
362
|
+
display: inline-flex; align-items: center; gap: var(--space-2); padding: var(--space-1) var(--space-5);
|
|
363
|
+
border-radius: var(--radius-xl); font-size: var(--text-base); font-weight: 500; border: 1px solid var(--border);
|
|
364
|
+
background: var(--surface2); color: var(--muted); cursor: default; transition: all var(--transition-base);
|
|
281
365
|
}
|
|
282
366
|
.cmd-chip.intent { color: var(--blue); border-color: rgba(88,166,255,0.3); background: rgba(88,166,255,0.08); }
|
|
283
367
|
.cmd-chip.agent-chip { color: var(--purple); border-color: rgba(188,140,255,0.3); background: rgba(188,140,255,0.08); }
|
|
@@ -297,9 +381,9 @@
|
|
|
297
381
|
|
|
298
382
|
/* @ mention autocomplete */
|
|
299
383
|
.cmd-mention-popup {
|
|
300
|
-
display: none; position: relative; left: 0; margin-top:
|
|
301
|
-
background: var(--surface); border: 1px solid var(--border); border-radius:
|
|
302
|
-
padding:
|
|
384
|
+
display: none; position: relative; left: 0; margin-top: var(--space-2);
|
|
385
|
+
background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg);
|
|
386
|
+
padding: var(--space-2) 0; min-width: 280px; box-shadow: var(--shadow-lg);
|
|
303
387
|
z-index: 200; max-height: 320px; overflow-y: auto;
|
|
304
388
|
scrollbar-width: thin; scrollbar-color: var(--border) transparent;
|
|
305
389
|
}
|
|
@@ -307,28 +391,28 @@
|
|
|
307
391
|
.cmd-mention-popup::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; }
|
|
308
392
|
.cmd-mention-popup.visible { display: block; }
|
|
309
393
|
.cmd-mention-item {
|
|
310
|
-
padding:
|
|
311
|
-
align-items: center; gap:
|
|
394
|
+
padding: var(--space-4) var(--space-7); font-size: var(--text-md); cursor: pointer; display: flex;
|
|
395
|
+
align-items: center; gap: var(--space-4); transition: background var(--transition-fast);
|
|
312
396
|
}
|
|
313
397
|
.cmd-mention-item:hover { background: var(--surface2); }
|
|
314
398
|
.cmd-mention-item.active { background: rgba(88,166,255,0.15); border-left: 2px solid var(--blue); }
|
|
315
|
-
.cmd-mention-item .mention-emoji { font-size:
|
|
399
|
+
.cmd-mention-item .mention-emoji { font-size: var(--text-2xl); }
|
|
316
400
|
.cmd-mention-item .mention-name { font-weight: 600; color: var(--purple); }
|
|
317
|
-
.cmd-mention-item .mention-role { color: var(--muted); font-size:
|
|
401
|
+
.cmd-mention-item .mention-role { color: var(--muted); font-size: var(--text-base); }
|
|
318
402
|
|
|
319
403
|
/* Hints bar */
|
|
320
404
|
.cmd-hints {
|
|
321
|
-
display: flex; gap:
|
|
322
|
-
letter-spacing: 0.2px; padding: 0
|
|
405
|
+
display: flex; gap: var(--space-6); margin-top: var(--space-2); font-size: var(--text-sm); color: var(--muted);
|
|
406
|
+
letter-spacing: 0.2px; padding: 0 var(--space-2); overflow-x: auto; white-space: nowrap;
|
|
323
407
|
scrollbar-width: thin; scrollbar-color: var(--border) transparent;
|
|
324
408
|
}
|
|
325
409
|
.cmd-hints::-webkit-scrollbar { height: 3px; }
|
|
326
410
|
.cmd-hints::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
|
|
327
|
-
.cmd-hints code { color: var(--blue); font-size:
|
|
411
|
+
.cmd-hints code { color: var(--blue); font-size: var(--text-sm); background: var(--surface2); padding: var(--space-1) 5px; border-radius: 3px; }
|
|
328
412
|
|
|
329
413
|
.cmd-history-btn {
|
|
330
|
-
background: none; border: 1px solid var(--border); color: var(--muted); font-size:
|
|
331
|
-
cursor: pointer; padding:
|
|
414
|
+
background: none; border: 1px solid var(--border); color: var(--muted); font-size: var(--text-base);
|
|
415
|
+
cursor: pointer; padding: var(--space-1) var(--space-5); border-radius: var(--radius-sm); transition: all var(--transition-base);
|
|
332
416
|
}
|
|
333
417
|
.cmd-history-btn:hover { color: var(--text); border-color: var(--text); }
|
|
334
418
|
.cmd-history-list { list-style: none; padding: 0; margin: 0; }
|
|
@@ -338,42 +422,42 @@
|
|
|
338
422
|
}
|
|
339
423
|
.cmd-history-item:last-child { border-bottom: none; }
|
|
340
424
|
.cmd-history-item-body { flex: 1; min-width: 0; }
|
|
341
|
-
.cmd-history-item-text { font-size:
|
|
342
|
-
.cmd-history-item-meta { font-size:
|
|
343
|
-
.cmd-history-item-meta .chip { background: var(--surface2); padding:
|
|
425
|
+
.cmd-history-item-text { font-size: var(--text-md); color: var(--text); white-space: pre-wrap; word-break: break-word; font-family: Consolas, monospace; }
|
|
426
|
+
.cmd-history-item-meta { font-size: var(--text-sm); color: var(--muted); margin-top: var(--space-1); display: flex; gap: var(--space-4); }
|
|
427
|
+
.cmd-history-item-meta .chip { background: var(--surface2); padding: var(--space-1) var(--space-3); border-radius: 3px; }
|
|
344
428
|
.cmd-history-resubmit {
|
|
345
429
|
background: var(--surface2); border: 1px solid var(--border); color: var(--blue);
|
|
346
|
-
font-size:
|
|
347
|
-
transition: all
|
|
430
|
+
font-size: var(--text-base); cursor: pointer; padding: var(--space-2) var(--space-5); border-radius: var(--radius-sm); white-space: nowrap;
|
|
431
|
+
transition: all var(--transition-base); flex-shrink: 0;
|
|
348
432
|
}
|
|
349
433
|
.cmd-history-resubmit:hover { background: rgba(88,166,255,0.1); border-color: var(--blue); }
|
|
350
|
-
.cmd-history-empty { color: var(--muted); font-size:
|
|
434
|
+
.cmd-history-empty { color: var(--muted); font-size: var(--text-md); padding: var(--space-8) 0; text-align: center; }
|
|
351
435
|
.cmd-toast {
|
|
352
|
-
display: none; padding:
|
|
353
|
-
margin-top:
|
|
436
|
+
display: none; padding: var(--space-4) var(--space-7); border-radius: var(--radius-sm); font-size: var(--text-md);
|
|
437
|
+
margin-top: var(--space-5); animation: fadeIn 0.3s;
|
|
354
438
|
}
|
|
355
439
|
.cmd-toast.success { display: block; background: rgba(63,185,80,0.15); color: var(--green); border: 1px solid var(--green); }
|
|
356
440
|
.cmd-toast.error { display: block; background: rgba(248,81,73,0.15); color: var(--red); border: 1px solid var(--red); }
|
|
357
441
|
@keyframes fadeIn { from{opacity:0;transform:translateY(-4px)} to{opacity:1;transform:translateY(0)} }
|
|
358
442
|
|
|
359
443
|
/* Engine Status */
|
|
360
|
-
.engine-badge { padding:
|
|
444
|
+
.engine-badge { padding: var(--space-2) var(--space-6); border-radius: var(--radius-xl); font-size: var(--text-base); font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; margin-right: var(--space-6); }
|
|
361
445
|
.engine-badge.running { background: rgba(63,185,80,0.15); color: var(--green); border: 1px solid var(--green); }
|
|
362
446
|
.engine-badge.paused { background: rgba(210,153,34,0.15); color: var(--yellow); border: 1px solid var(--yellow); }
|
|
363
447
|
.engine-badge.stopped { background: rgba(248,81,73,0.15); color: var(--red); border: 1px solid var(--red); }
|
|
364
448
|
|
|
365
449
|
/* Dispatch Queue */
|
|
366
|
-
.dispatch-stats { display: flex; gap:
|
|
367
|
-
.dispatch-stat { text-align: center; background: var(--surface2); border: 1px solid var(--border); border-radius:
|
|
368
|
-
.dispatch-stat-num { font-size:
|
|
450
|
+
.dispatch-stats { display: flex; gap: var(--space-7); margin-bottom: 14px; }
|
|
451
|
+
.dispatch-stat { text-align: center; background: var(--surface2); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: var(--space-5) 18px; }
|
|
452
|
+
.dispatch-stat-num { font-size: var(--text-stat-lg); font-weight: 700; }
|
|
369
453
|
.dispatch-stat-num.blue { color: var(--blue); }
|
|
370
454
|
.dispatch-stat-num.green { color: var(--green); }
|
|
371
455
|
.dispatch-stat-num.yellow { color: var(--yellow); }
|
|
372
456
|
.dispatch-stat-num.muted { color: var(--muted); }
|
|
373
|
-
.dispatch-stat-label { font-size:
|
|
374
|
-
.dispatch-list { display: flex; flex-direction: column; gap:
|
|
375
|
-
.dispatch-item { display: flex; align-items: center; gap:
|
|
376
|
-
.dispatch-type { font-size:
|
|
457
|
+
.dispatch-stat-label { font-size: var(--text-sm); color: var(--muted); margin-top: var(--space-1); text-transform: uppercase; letter-spacing: 0.5px; }
|
|
458
|
+
.dispatch-list { display: flex; flex-direction: column; gap: var(--space-3); }
|
|
459
|
+
.dispatch-item { display: flex; align-items: center; gap: var(--space-4); padding: var(--space-4) var(--space-5); background: var(--surface2); border: 1px solid var(--border); border-radius: var(--radius-md); font-size: var(--text-md); }
|
|
460
|
+
.dispatch-type { font-size: var(--text-sm); font-weight: 600; padding: var(--space-1) var(--space-4); border-radius: var(--radius-lg); text-transform: uppercase; white-space: nowrap; }
|
|
377
461
|
.dispatch-type.implement { background: rgba(88,166,255,0.15); color: var(--blue); }
|
|
378
462
|
.dispatch-type.implement\:large { background: rgba(88,166,255,0.25); color: var(--blue); }
|
|
379
463
|
.dispatch-type.review { background: rgba(188,140,255,0.15); color: var(--purple); }
|
|
@@ -387,11 +471,11 @@
|
|
|
387
471
|
.dispatch-type.manual { background: rgba(139,148,158,0.15); color: var(--muted); }
|
|
388
472
|
.dispatch-agent { font-weight: 600; color: var(--text); }
|
|
389
473
|
.dispatch-task { flex: 1; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
390
|
-
.dispatch-time { font-size:
|
|
474
|
+
.dispatch-time { font-size: var(--text-sm); color: var(--border); }
|
|
391
475
|
|
|
392
476
|
/* Engine Log */
|
|
393
|
-
.log-list { max-height: 280px; overflow-y: auto; display: flex; flex-direction: column; gap:
|
|
394
|
-
.log-entry { font-size:
|
|
477
|
+
.log-list { max-height: 280px; overflow-y: auto; display: flex; flex-direction: column; gap: var(--space-1); }
|
|
478
|
+
.log-entry { font-size: var(--text-base); padding: var(--space-2) var(--space-4); border-bottom: 1px solid rgba(48,54,61,0.4); font-family: Consolas, monospace; }
|
|
395
479
|
.log-ts { color: var(--muted); }
|
|
396
480
|
.log-level-info { color: var(--blue); }
|
|
397
481
|
.log-level-warn { color: var(--yellow); }
|
|
@@ -408,41 +492,41 @@
|
|
|
408
492
|
}
|
|
409
493
|
.detail-panel.open { transform: translateX(0); }
|
|
410
494
|
.detail-header {
|
|
411
|
-
padding:
|
|
495
|
+
padding: var(--space-7) var(--space-8); border-bottom: 1px solid var(--border);
|
|
412
496
|
display: flex; justify-content: space-between; align-items: center; flex-shrink: 0;
|
|
413
497
|
}
|
|
414
|
-
.detail-header h3 { font-size:
|
|
415
|
-
.detail-close { background: none; border: 1px solid var(--border); color: var(--muted); font-size:
|
|
498
|
+
.detail-header h3 { font-size: var(--text-2xl); color: var(--blue); display: flex; align-items: center; gap: var(--space-4); }
|
|
499
|
+
.detail-close { background: none; border: 1px solid var(--border); color: var(--muted); font-size: var(--text-md); cursor: pointer; padding: var(--space-2) var(--space-6); border-radius: var(--radius-sm); }
|
|
416
500
|
.detail-close:hover { color: var(--text); border-color: var(--text); }
|
|
417
501
|
.detail-body { flex: 1; overflow-y: auto; padding: 0; }
|
|
418
502
|
.detail-tabs { display: flex; border-bottom: 1px solid var(--border); flex-shrink: 0; background: var(--bg); }
|
|
419
503
|
.detail-tab {
|
|
420
|
-
padding:
|
|
421
|
-
cursor: pointer; border-bottom: 2px solid transparent; transition: all
|
|
504
|
+
padding: var(--space-5) var(--space-7); font-size: var(--text-md); font-weight: 500; color: var(--muted);
|
|
505
|
+
cursor: pointer; border-bottom: 2px solid transparent; transition: all var(--transition-base);
|
|
422
506
|
}
|
|
423
507
|
.detail-tab:hover { color: var(--text); }
|
|
424
508
|
.detail-tab.active { color: var(--blue); border-bottom-color: var(--blue); }
|
|
425
509
|
.detail-content {
|
|
426
|
-
padding:
|
|
510
|
+
padding: var(--space-7) var(--space-8); font-size: var(--text-md); line-height: 1.7;
|
|
427
511
|
white-space: pre-wrap; word-wrap: break-word; font-family: Consolas, monospace; color: var(--muted);
|
|
428
512
|
}
|
|
429
|
-
.detail-content h4 { color: var(--text); font-size:
|
|
430
|
-
.detail-content .section { margin-bottom:
|
|
431
|
-
.status-line { display: flex; align-items: center; gap:
|
|
513
|
+
.detail-content h4 { color: var(--text); font-size: var(--text-lg); margin: var(--space-6) 0 var(--space-3) 0; font-family: 'Segoe UI', sans-serif; }
|
|
514
|
+
.detail-content .section { margin-bottom: var(--space-7); padding: var(--space-6); background: var(--surface2); border: 1px solid var(--border); border-radius: var(--radius-md); }
|
|
515
|
+
.status-line { display: flex; align-items: center; gap: var(--space-5); padding: var(--space-5) var(--space-7); background: var(--bg); border-bottom: 1px solid var(--border); font-size: var(--text-md); }
|
|
432
516
|
|
|
433
517
|
/* Modal for inbox detail */
|
|
434
518
|
.modal-bg { display: none; position: fixed; inset: 0; background: rgba(0,0,0,0.75); z-index: 400; align-items: center; justify-content: center; }
|
|
435
519
|
.modal-bg.open { display: flex; }
|
|
436
|
-
.modal { background: var(--surface); border: 1px solid var(--border); border-radius:
|
|
437
|
-
.modal-header { padding:
|
|
438
|
-
.modal-header h3 { font-size:
|
|
439
|
-
.modal-header-actions { display: flex; align-items: center; gap:
|
|
440
|
-
.modal-copy { background: var(--surface2); border: 1px solid var(--border); color: var(--muted); font-size:
|
|
520
|
+
.modal { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-xl); width: 95%; max-width: 1100px; max-height: 80vh; display: flex; flex-direction: column; }
|
|
521
|
+
.modal-header { padding: var(--space-7) var(--space-8); border-bottom: 1px solid var(--border); display: flex; justify-content: space-between; align-items: center; }
|
|
522
|
+
.modal-header h3 { font-size: var(--text-xl); color: var(--blue); }
|
|
523
|
+
.modal-header-actions { display: flex; align-items: center; gap: var(--space-4); }
|
|
524
|
+
.modal-copy { background: var(--surface2); border: 1px solid var(--border); color: var(--muted); font-size: var(--text-base); cursor: pointer; padding: var(--space-2) var(--space-5); border-radius: var(--radius-sm); display: flex; align-items: center; gap: var(--space-2); transition: all var(--transition-base); }
|
|
441
525
|
.modal-copy:hover { color: var(--text); border-color: var(--text); }
|
|
442
526
|
.modal-copy.copied { color: var(--green); border-color: var(--green); }
|
|
443
|
-
.modal-close { background: none; border: none; color: var(--muted); font-size: 18px; cursor: pointer; padding:
|
|
527
|
+
.modal-close { background: none; border: none; color: var(--muted); font-size: 18px; cursor: pointer; padding: var(--space-2) var(--space-4); }
|
|
444
528
|
.modal-close:hover { color: var(--text); }
|
|
445
|
-
.modal-body { padding:
|
|
529
|
+
.modal-body { padding: var(--space-7) var(--space-8); overflow-y: auto; white-space: pre-wrap; font-size: var(--text-md); line-height: 1.7; color: var(--muted); font-family: Consolas, monospace; }
|
|
446
530
|
|
|
447
531
|
/* Responsive: tablet / narrow window */
|
|
448
532
|
@media (max-width: 1100px) {
|
|
@@ -637,8 +721,8 @@
|
|
|
637
721
|
<button class="pill-clear" onclick="clearQaSelection()" title="Clear selection">×</button>
|
|
638
722
|
</div>
|
|
639
723
|
<div class="modal-qa-input-wrap">
|
|
640
|
-
<input type="text" class="modal-qa-input" id="modal-qa-input" placeholder="Ask
|
|
641
|
-
<button class="modal-qa-btn" id="modal-
|
|
724
|
+
<input type="text" class="modal-qa-input" id="modal-qa-input" placeholder="Ask a question or give an edit instruction..." onkeydown="if(event.key==='Enter')modalSend()">
|
|
725
|
+
<button class="modal-qa-btn" id="modal-send-btn" onclick="modalSend()">Send</button>
|
|
642
726
|
</div>
|
|
643
727
|
</div>
|
|
644
728
|
</div>
|
|
@@ -967,7 +1051,9 @@ function openNotesModal() {
|
|
|
967
1051
|
document.getElementById('modal-body').style.whiteSpace = 'pre-wrap';
|
|
968
1052
|
_modalDocContext = { title: 'Team Notes', content, selection: '' };
|
|
969
1053
|
_modalEditable = 'notes.md';
|
|
1054
|
+
_modalFilePath = 'notes.md';
|
|
970
1055
|
document.getElementById('modal-edit-btn').style.display = '';
|
|
1056
|
+
// steer btn removed — unified send
|
|
971
1057
|
document.getElementById('modal').classList.add('open');
|
|
972
1058
|
}
|
|
973
1059
|
|
|
@@ -1133,15 +1219,26 @@ function openModal(i) {
|
|
|
1133
1219
|
}
|
|
1134
1220
|
function closeModal() {
|
|
1135
1221
|
document.getElementById('modal').classList.remove('open');
|
|
1136
|
-
//
|
|
1222
|
+
// Save Q&A session for this document (persist across modal open/close)
|
|
1223
|
+
if (_qaSessionKey && (_qaHistory.length > 0 || _qaQueue.length > 0)) {
|
|
1224
|
+
_qaSessions.set(_qaSessionKey, {
|
|
1225
|
+
history: _qaHistory,
|
|
1226
|
+
threadHtml: document.getElementById('modal-qa-thread').innerHTML,
|
|
1227
|
+
docContext: { ..._modalDocContext },
|
|
1228
|
+
filePath: _modalFilePath,
|
|
1229
|
+
});
|
|
1230
|
+
}
|
|
1231
|
+
// Reset UI state but don't kill processing/queue — they run in background
|
|
1137
1232
|
_modalDocContext = { title: '', content: '', selection: '' };
|
|
1138
|
-
|
|
1233
|
+
_qaSessionKey = '';
|
|
1139
1234
|
document.getElementById('modal-qa-input').value = '';
|
|
1140
1235
|
document.getElementById('modal-qa-input').placeholder = 'Ask about this document (or select text first)...';
|
|
1141
1236
|
document.getElementById('modal-qa-pill').style.display = 'none';
|
|
1142
1237
|
document.getElementById('ask-selection-btn').style.display = 'none';
|
|
1143
|
-
// Clear edit state
|
|
1238
|
+
// Clear edit/steer state
|
|
1144
1239
|
_modalEditable = null;
|
|
1240
|
+
_modalFilePath = null;
|
|
1241
|
+
// steer btn removed — unified send
|
|
1145
1242
|
const body = document.getElementById('modal-body');
|
|
1146
1243
|
body.contentEditable = 'false';
|
|
1147
1244
|
body.style.border = '';
|
|
@@ -2230,6 +2327,12 @@ async function cmdSubmitPrd(parsed) {
|
|
|
2230
2327
|
// ─── Modal Q&A (Ask about document) ──────────────────────────────────────────
|
|
2231
2328
|
|
|
2232
2329
|
let _modalDocContext = { title: '', content: '', selection: '' };
|
|
2330
|
+
let _modalFilePath = null; // file path for steering (null = read-only Q&A only)
|
|
2331
|
+
let _qaHistory = []; // multi-turn conversation history [{role:'user',text:''},{role:'assistant',text:''}]
|
|
2332
|
+
let _qaProcessing = false; // true while waiting for Haiku response
|
|
2333
|
+
let _qaQueue = []; // queued messages while processing
|
|
2334
|
+
let _qaSessionKey = ''; // key for current conversation (title or filePath)
|
|
2335
|
+
const _qaSessions = new Map(); // persist conversations across modal open/close {key → {history, threadHtml}}
|
|
2233
2336
|
|
|
2234
2337
|
// Track text selection anywhere in content areas for the floating "Ask about this" button
|
|
2235
2338
|
document.addEventListener('mouseup', function(e) {
|
|
@@ -2306,10 +2409,10 @@ function clearQaSelection() {
|
|
|
2306
2409
|
document.getElementById('modal-qa-input').placeholder = 'Ask about this document (or select text first)...';
|
|
2307
2410
|
}
|
|
2308
2411
|
|
|
2309
|
-
|
|
2412
|
+
function modalSend() {
|
|
2310
2413
|
const input = document.getElementById('modal-qa-input');
|
|
2311
|
-
const
|
|
2312
|
-
if (!
|
|
2414
|
+
const message = input.value.trim();
|
|
2415
|
+
if (!message) return;
|
|
2313
2416
|
|
|
2314
2417
|
// Capture content from modal body if not already set
|
|
2315
2418
|
if (!_modalDocContext.content) {
|
|
@@ -2320,38 +2423,144 @@ async function modalAskSubmit() {
|
|
|
2320
2423
|
}
|
|
2321
2424
|
}
|
|
2322
2425
|
if (!_modalDocContext.content) {
|
|
2323
|
-
showToast('cmd-toast', 'No document content
|
|
2426
|
+
showToast('cmd-toast', 'No document content', false);
|
|
2324
2427
|
return;
|
|
2325
2428
|
}
|
|
2326
2429
|
|
|
2327
2430
|
const thread = document.getElementById('modal-qa-thread');
|
|
2328
|
-
const
|
|
2431
|
+
const selection = _modalDocContext.selection || '';
|
|
2432
|
+
|
|
2433
|
+
// Show message in thread immediately
|
|
2434
|
+
let qHtml = '<div class="modal-qa-q">' + escHtml(message);
|
|
2435
|
+
if (selection) {
|
|
2436
|
+
qHtml += '<span class="selection-ref">Re: "' + escHtml(selection.slice(0, 100)) + ((selection.length > 100) ? '...' : '') + '"</span>';
|
|
2437
|
+
}
|
|
2438
|
+
qHtml += '</div>';
|
|
2439
|
+
thread.innerHTML += qHtml;
|
|
2440
|
+
thread.scrollTop = thread.scrollHeight;
|
|
2441
|
+
|
|
2442
|
+
// Clear input immediately so user can type next message
|
|
2443
|
+
input.value = '';
|
|
2444
|
+
_modalDocContext.selection = '';
|
|
2445
|
+
document.getElementById('modal-qa-pill').style.display = 'none';
|
|
2446
|
+
|
|
2447
|
+
if (_qaProcessing) {
|
|
2448
|
+
// Queue the message — show it as "queued" in the thread
|
|
2449
|
+
_qaQueue.push({ message, selection });
|
|
2450
|
+
thread.innerHTML += '<div class="modal-qa-loading" style="color:var(--muted);font-size:10px">Queued — will send after current response</div>';
|
|
2451
|
+
thread.scrollTop = thread.scrollHeight;
|
|
2452
|
+
return;
|
|
2453
|
+
}
|
|
2454
|
+
|
|
2455
|
+
_processQaMessage(message, selection);
|
|
2456
|
+
}
|
|
2457
|
+
|
|
2458
|
+
async function _processQaMessage(message, selection) {
|
|
2459
|
+
const thread = document.getElementById('modal-qa-thread');
|
|
2460
|
+
const btn = document.getElementById('modal-send-btn');
|
|
2461
|
+
_qaProcessing = true;
|
|
2462
|
+
|
|
2463
|
+
const loadingId = 'chat-loading-' + Date.now();
|
|
2464
|
+
thread.innerHTML += '<div class="modal-qa-loading" id="' + loadingId + '"><div class="dot-pulse"><span></span><span></span><span></span></div> Thinking...</div>';
|
|
2465
|
+
thread.scrollTop = thread.scrollHeight;
|
|
2466
|
+
|
|
2467
|
+
try {
|
|
2468
|
+
const res = await fetch('/api/doc-chat', {
|
|
2469
|
+
method: 'POST',
|
|
2470
|
+
headers: { 'Content-Type': 'application/json' },
|
|
2471
|
+
body: JSON.stringify({
|
|
2472
|
+
message,
|
|
2473
|
+
document: _modalDocContext.content,
|
|
2474
|
+
title: _modalDocContext.title,
|
|
2475
|
+
selection: selection,
|
|
2476
|
+
filePath: _modalFilePath || null,
|
|
2477
|
+
history: _qaHistory,
|
|
2478
|
+
}),
|
|
2479
|
+
});
|
|
2480
|
+
const data = await res.json();
|
|
2481
|
+
const loadingEl = document.getElementById(loadingId);
|
|
2482
|
+
if (loadingEl) loadingEl.remove();
|
|
2483
|
+
|
|
2484
|
+
if (data.ok) {
|
|
2485
|
+
const borderColor = data.edited ? 'var(--green)' : 'var(--blue)';
|
|
2486
|
+
const suffix = data.edited ? '\n\n✓ Document saved.' : '';
|
|
2487
|
+
thread.innerHTML += '<div class="modal-qa-a" style="border-left-color:' + borderColor + '">' + escHtml(data.answer + suffix) + '</div>';
|
|
2329
2488
|
|
|
2330
|
-
|
|
2331
|
-
|
|
2489
|
+
// Track conversation history
|
|
2490
|
+
_qaHistory.push({ role: 'user', text: message });
|
|
2491
|
+
_qaHistory.push({ role: 'assistant', text: data.answer });
|
|
2492
|
+
|
|
2493
|
+
// Refresh modal body if document was edited
|
|
2494
|
+
if (data.edited && data.content) {
|
|
2495
|
+
const display = data.content.replace(/^---[\s\S]*?---\n*/m, '');
|
|
2496
|
+
document.getElementById('modal-body').textContent = display;
|
|
2497
|
+
_modalDocContext.content = display;
|
|
2498
|
+
}
|
|
2499
|
+
} else {
|
|
2500
|
+
thread.innerHTML += '<div class="modal-qa-a" style="color:var(--red)">Error: ' + escHtml(data.error || 'Failed') + '</div>';
|
|
2501
|
+
}
|
|
2502
|
+
} catch (e) {
|
|
2503
|
+
const loadingEl = document.getElementById(loadingId);
|
|
2504
|
+
if (loadingEl) loadingEl.remove();
|
|
2505
|
+
thread.innerHTML += '<div class="modal-qa-a" style="color:var(--red)">Error: ' + escHtml(e.message) + '</div>';
|
|
2506
|
+
}
|
|
2507
|
+
|
|
2508
|
+
_qaProcessing = false;
|
|
2509
|
+
thread.scrollTop = thread.scrollHeight;
|
|
2510
|
+
|
|
2511
|
+
// Process next queued message
|
|
2512
|
+
if (_qaQueue.length > 0) {
|
|
2513
|
+
const next = _qaQueue.shift();
|
|
2514
|
+
// Remove the "Queued" indicator
|
|
2515
|
+
const queuedEls = thread.querySelectorAll('.modal-qa-loading');
|
|
2516
|
+
for (const el of queuedEls) {
|
|
2517
|
+
if (el.textContent.includes('Queued')) { el.remove(); break; }
|
|
2518
|
+
}
|
|
2519
|
+
_processQaMessage(next.message, next.selection);
|
|
2520
|
+
} else {
|
|
2521
|
+
document.getElementById('modal-qa-input').focus();
|
|
2522
|
+
}
|
|
2523
|
+
}
|
|
2524
|
+
|
|
2525
|
+
// Override closeModal to clear Q&A state
|
|
2526
|
+
const _origCloseModal = typeof closeModal === 'function' ? closeModal : null;
|
|
2527
|
+
|
|
2528
|
+
async function modalSteerSubmit() {
|
|
2529
|
+
const input = document.getElementById('modal-qa-input');
|
|
2530
|
+
const instruction = input.value.trim();
|
|
2531
|
+
if (!instruction) return;
|
|
2532
|
+
if (!_modalFilePath) {
|
|
2533
|
+
showToast('cmd-toast', 'This document is read-only (no file path)', false);
|
|
2534
|
+
return;
|
|
2535
|
+
}
|
|
2536
|
+
|
|
2537
|
+
const thread = document.getElementById('modal-qa-thread');
|
|
2538
|
+
const btn = document.getElementById('modal-steer-btn');
|
|
2539
|
+
|
|
2540
|
+
// Show instruction
|
|
2541
|
+
let qHtml = '<div class="modal-qa-q" style="color:var(--green)">Edit: ' + escHtml(instruction);
|
|
2332
2542
|
if (_modalDocContext.selection) {
|
|
2333
|
-
qHtml += '<span class="selection-ref">
|
|
2543
|
+
qHtml += '<span class="selection-ref">On: "' + escHtml(_modalDocContext.selection.slice(0, 100)) + '"</span>';
|
|
2334
2544
|
}
|
|
2335
2545
|
qHtml += '</div>';
|
|
2336
2546
|
thread.innerHTML += qHtml;
|
|
2337
2547
|
|
|
2338
2548
|
// Show loading
|
|
2339
|
-
const loadingId = '
|
|
2340
|
-
thread.innerHTML += '<div class="modal-qa-loading" id="' + loadingId + '"><div class="dot-pulse"><span></span><span></span><span></span></div>
|
|
2549
|
+
const loadingId = 'steer-loading-' + Date.now();
|
|
2550
|
+
thread.innerHTML += '<div class="modal-qa-loading" id="' + loadingId + '"><div class="dot-pulse"><span></span><span></span><span></span></div> Editing...</div>';
|
|
2341
2551
|
thread.scrollTop = thread.scrollHeight;
|
|
2342
2552
|
|
|
2343
2553
|
input.value = '';
|
|
2344
|
-
input.placeholder = 'Ask another question...';
|
|
2345
2554
|
btn.disabled = true;
|
|
2555
|
+
document.getElementById('modal-qa-btn').disabled = true;
|
|
2346
2556
|
|
|
2347
2557
|
try {
|
|
2348
|
-
const res = await fetch('/api/
|
|
2558
|
+
const res = await fetch('/api/steer-document', {
|
|
2349
2559
|
method: 'POST',
|
|
2350
2560
|
headers: { 'Content-Type': 'application/json' },
|
|
2351
2561
|
body: JSON.stringify({
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
title: _modalDocContext.title,
|
|
2562
|
+
instruction,
|
|
2563
|
+
filePath: _modalFilePath,
|
|
2355
2564
|
selection: _modalDocContext.selection || '',
|
|
2356
2565
|
}),
|
|
2357
2566
|
});
|
|
@@ -2359,10 +2568,17 @@ async function modalAskSubmit() {
|
|
|
2359
2568
|
const loadingEl = document.getElementById(loadingId);
|
|
2360
2569
|
if (loadingEl) loadingEl.remove();
|
|
2361
2570
|
|
|
2362
|
-
if (data.ok
|
|
2363
|
-
thread.innerHTML += '<div class="modal-qa-a">' + escHtml(data.answer) + '</div>';
|
|
2571
|
+
if (data.ok) {
|
|
2572
|
+
thread.innerHTML += '<div class="modal-qa-a" style="border-left-color:var(--green)">' + escHtml(data.answer) + (data.updated ? '\n\n✓ Document saved.' : '') + '</div>';
|
|
2573
|
+
|
|
2574
|
+
// Refresh the modal body with updated content
|
|
2575
|
+
if (data.updated && data.content) {
|
|
2576
|
+
const display = data.content.replace(/^---[\s\S]*?---\n*/m, '');
|
|
2577
|
+
document.getElementById('modal-body').textContent = display;
|
|
2578
|
+
_modalDocContext.content = display;
|
|
2579
|
+
}
|
|
2364
2580
|
} else {
|
|
2365
|
-
thread.innerHTML += '<div class="modal-qa-a" style="color:var(--red)">Error: ' + escHtml(data.error || '
|
|
2581
|
+
thread.innerHTML += '<div class="modal-qa-a" style="color:var(--red)">Error: ' + escHtml(data.error || 'Failed') + '</div>';
|
|
2366
2582
|
}
|
|
2367
2583
|
} catch (e) {
|
|
2368
2584
|
const loadingEl = document.getElementById(loadingId);
|
|
@@ -2370,17 +2586,14 @@ async function modalAskSubmit() {
|
|
|
2370
2586
|
thread.innerHTML += '<div class="modal-qa-a" style="color:var(--red)">Error: ' + escHtml(e.message) + '</div>';
|
|
2371
2587
|
}
|
|
2372
2588
|
|
|
2373
|
-
_modalDocContext.selection = '';
|
|
2589
|
+
_modalDocContext.selection = '';
|
|
2374
2590
|
document.getElementById('modal-qa-pill').style.display = 'none';
|
|
2375
|
-
document.getElementById('modal-qa-input').placeholder = 'Ask another question...';
|
|
2376
2591
|
btn.disabled = false;
|
|
2592
|
+
document.getElementById('modal-qa-btn').disabled = false;
|
|
2377
2593
|
thread.scrollTop = thread.scrollHeight;
|
|
2378
2594
|
input.focus();
|
|
2379
2595
|
}
|
|
2380
2596
|
|
|
2381
|
-
// Override closeModal to clear Q&A state
|
|
2382
|
-
const _origCloseModal = typeof closeModal === 'function' ? closeModal : null;
|
|
2383
|
-
|
|
2384
2597
|
// ─── Plans (Approval Gate) ────────────────────────────────────────────────────
|
|
2385
2598
|
|
|
2386
2599
|
async function refreshPlans() {
|
|
@@ -2411,11 +2624,10 @@ function renderPlans(plans) {
|
|
|
2411
2624
|
|
|
2412
2625
|
let actions = '';
|
|
2413
2626
|
if (needsAction) {
|
|
2414
|
-
actions = '<div class="plan-card-actions">' +
|
|
2627
|
+
actions = '<div class="plan-card-actions" onclick="event.stopPropagation()">' +
|
|
2415
2628
|
'<button class="plan-btn approve" onclick="planApprove(\'' + escHtml(p.file) + '\')">Approve</button>' +
|
|
2416
2629
|
'<button class="plan-btn" style="color:var(--blue);border-color:var(--blue)" onclick="planDiscuss(\'' + escHtml(p.file) + '\')">Discuss & Revise</button>' +
|
|
2417
2630
|
'<button class="plan-btn reject" onclick="planReject(\'' + escHtml(p.file) + '\')">Reject</button>' +
|
|
2418
|
-
'<button class="plan-btn" onclick="planView(\'' + escHtml(p.file) + '\')">View Full Plan</button>' +
|
|
2419
2631
|
'</div>' +
|
|
2420
2632
|
'<div id="revise-input-' + escHtml(p.file).replace(/\./g, '-') + '" style="display:none">' +
|
|
2421
2633
|
'<textarea class="plan-feedback-input" placeholder="What should be changed? Be specific..." id="revise-feedback-' + escHtml(p.file).replace(/\./g, '-') + '"></textarea>' +
|
|
@@ -2426,11 +2638,10 @@ function renderPlans(plans) {
|
|
|
2426
2638
|
'</div>';
|
|
2427
2639
|
} else if (isRevision) {
|
|
2428
2640
|
actions = '<div class="plan-card-meta" style="margin-top:6px;color:var(--purple,#a855f7)">Revision in progress: ' + escHtml((p.revisionFeedback || '').slice(0, 100)) + '</div>';
|
|
2429
|
-
} else if (status === 'approved' || status === 'active') {
|
|
2430
|
-
actions = '<div class="plan-card-actions"><button class="plan-btn" onclick="planView(\'' + escHtml(p.file) + '\')">View</button></div>';
|
|
2431
2641
|
}
|
|
2642
|
+
// No else needed — whole card is clickable
|
|
2432
2643
|
|
|
2433
|
-
return '<div class="plan-card ' + statusClass(status) + '">' +
|
|
2644
|
+
return '<div class="plan-card ' + statusClass(status) + '" style="cursor:pointer" onclick="planView(\'' + escHtml(p.file) + '\')">' +
|
|
2434
2645
|
'<div class="plan-card-header">' +
|
|
2435
2646
|
'<div><div class="plan-card-title">' + escHtml(p.summary || p.file) + '</div>' +
|
|
2436
2647
|
'<div class="plan-card-meta">' +
|
|
@@ -2517,19 +2728,41 @@ async function planDiscuss(file) {
|
|
|
2517
2728
|
|
|
2518
2729
|
async function planView(file) {
|
|
2519
2730
|
try {
|
|
2520
|
-
const
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2731
|
+
const raw = await fetch('/api/plans/' + encodeURIComponent(file)).then(r => r.text());
|
|
2732
|
+
let title = file;
|
|
2733
|
+
let text = '';
|
|
2734
|
+
|
|
2735
|
+
if (file.endsWith('.json')) {
|
|
2736
|
+
// PRD JSON — format nicely
|
|
2737
|
+
const plan = JSON.parse(raw);
|
|
2738
|
+
title = plan.plan_summary || file;
|
|
2739
|
+
const items = (plan.missing_features || []).map((f, i) =>
|
|
2740
|
+
(i + 1) + '. [' + f.id + '] ' + f.name + ' (' + (f.estimated_complexity || '?') + ', ' + (f.priority || '?') + ')' +
|
|
2741
|
+
(f.depends_on?.length ? ' → depends on: ' + f.depends_on.join(', ') : '') +
|
|
2742
|
+
'\n ' + (f.description || '').slice(0, 200) +
|
|
2743
|
+
(f.acceptance_criteria?.length ? '\n Criteria: ' + f.acceptance_criteria.join('; ') : '')
|
|
2744
|
+
).join('\n\n');
|
|
2745
|
+
text = 'Project: ' + (plan.project || '?') +
|
|
2746
|
+
'\nStrategy: ' + (plan.branch_strategy || 'parallel') +
|
|
2747
|
+
'\nBranch: ' + (plan.feature_branch || 'per-item') +
|
|
2748
|
+
'\nStatus: ' + (plan.status || 'active') +
|
|
2749
|
+
'\nGenerated by: ' + (plan.generated_by || '?') + ' on ' + (plan.generated_at || '?') +
|
|
2750
|
+
'\n\n--- Items (' + (plan.missing_features || []).length + ') ---\n\n' + items +
|
|
2751
|
+
(plan.open_questions?.length ? '\n\n--- Open Questions ---\n\n' + plan.open_questions.map(q => '• ' + q).join('\n') : '');
|
|
2752
|
+
} else {
|
|
2753
|
+
// Markdown plan — show as-is
|
|
2754
|
+
text = raw;
|
|
2755
|
+
const titleMatch = raw.match(/^#\s+(?:Plan:\s*)?(.+)/m);
|
|
2756
|
+
if (titleMatch) title = titleMatch[1];
|
|
2757
|
+
}
|
|
2758
|
+
|
|
2759
|
+
document.getElementById('modal-title').textContent = title;
|
|
2532
2760
|
document.getElementById('modal-body').textContent = text;
|
|
2761
|
+
document.getElementById('modal-body').style.fontFamily = 'Consolas, monospace';
|
|
2762
|
+
document.getElementById('modal-body').style.whiteSpace = 'pre-wrap';
|
|
2763
|
+
_modalDocContext = { title, content: text, selection: '' };
|
|
2764
|
+
_modalFilePath = 'plans/' + file;
|
|
2765
|
+
// steer btn removed — unified send
|
|
2533
2766
|
document.getElementById('modal').classList.add('open');
|
|
2534
2767
|
} catch (e) { console.error(e); }
|
|
2535
2768
|
}
|
|
@@ -2627,10 +2860,12 @@ function kbSetTab(tab) {
|
|
|
2627
2860
|
async function kbOpenItem(category, file) {
|
|
2628
2861
|
try {
|
|
2629
2862
|
const content = await fetch('/api/knowledge/' + category + '/' + encodeURIComponent(file)).then(r => r.text());
|
|
2630
|
-
// Strip frontmatter for display
|
|
2631
2863
|
const display = content.replace(/^---[\s\S]*?---\n*/m, '');
|
|
2632
2864
|
document.getElementById('modal-title').textContent = file;
|
|
2633
2865
|
document.getElementById('modal-body').textContent = display;
|
|
2866
|
+
_modalDocContext = { title: file, content: display, selection: '' };
|
|
2867
|
+
_modalFilePath = 'knowledge/' + category + '/' + file;
|
|
2868
|
+
// steer btn removed — unified send
|
|
2634
2869
|
document.getElementById('modal').classList.add('open');
|
|
2635
2870
|
} catch (e) {
|
|
2636
2871
|
console.error('Failed to load KB item:', e);
|