@cccarv82/freya 1.0.34 → 1.0.35
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/cli/web-ui.css +195 -71
- package/cli/web-ui.js +49 -1
- package/cli/web.js +143 -117
- package/package.json +1 -1
package/cli/web-ui.css
CHANGED
|
@@ -2,30 +2,33 @@
|
|
|
2
2
|
Keep this file plain CSS to avoid escaping issues in inline template literals. */
|
|
3
3
|
|
|
4
4
|
:root {
|
|
5
|
-
--radius:
|
|
6
|
-
--
|
|
7
|
-
--
|
|
8
|
-
--
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
--
|
|
13
|
-
--
|
|
14
|
-
--
|
|
15
|
-
--
|
|
16
|
-
--
|
|
17
|
-
--
|
|
5
|
+
--radius: 16px;
|
|
6
|
+
--radius2: 12px;
|
|
7
|
+
--shadow: 0 20px 60px rgba(16, 24, 40, .12);
|
|
8
|
+
--shadow2: 0 10px 22px rgba(16, 24, 40, .10);
|
|
9
|
+
--ring: 0 0 0 4px rgba(37, 99, 235, .18);
|
|
10
|
+
|
|
11
|
+
/* Warm cream palette (light-first) */
|
|
12
|
+
--bg: #f7f0e6;
|
|
13
|
+
--paper: #fffaf2;
|
|
14
|
+
--paper2: rgba(255, 250, 242, .78);
|
|
15
|
+
--line: rgba(30, 41, 59, .10);
|
|
16
|
+
--line2: rgba(30, 41, 59, .18);
|
|
17
|
+
--text: #111827;
|
|
18
|
+
--muted: rgba(17, 24, 39, .74);
|
|
19
|
+
--faint: rgba(17, 24, 39, .56);
|
|
20
|
+
|
|
18
21
|
--accent: #f97316;
|
|
19
22
|
--primary: #2563eb;
|
|
20
|
-
--chip: rgba(37, 99, 235, .
|
|
21
|
-
--chip2: rgba(249, 115, 22, .
|
|
23
|
+
--chip: rgba(37, 99, 235, .10);
|
|
24
|
+
--chip2: rgba(249, 115, 22, .14);
|
|
22
25
|
|
|
23
26
|
--mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
|
24
27
|
--sans: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif;
|
|
25
28
|
}
|
|
26
29
|
|
|
27
30
|
[data-theme="dark"] {
|
|
28
|
-
--bg: #
|
|
31
|
+
--bg: #0b111c;
|
|
29
32
|
--paper: rgba(17, 24, 39, .92);
|
|
30
33
|
--paper2: rgba(17, 24, 39, .78);
|
|
31
34
|
--line: rgba(148, 163, 184, .16);
|
|
@@ -42,35 +45,44 @@
|
|
|
42
45
|
body {
|
|
43
46
|
margin: 0;
|
|
44
47
|
font-family: var(--sans);
|
|
45
|
-
background:
|
|
46
|
-
|
|
47
|
-
|
|
48
|
+
background:
|
|
49
|
+
radial-gradient(900px 400px at 12% 0%, rgba(249,115,22,.12), transparent 60%),
|
|
50
|
+
radial-gradient(900px 450px at 90% 8%, rgba(37,99,235,.14), transparent 60%),
|
|
51
|
+
var(--bg);
|
|
48
52
|
color: var(--text);
|
|
49
53
|
}
|
|
50
54
|
|
|
51
|
-
.app { padding:
|
|
55
|
+
.app { padding: 18px; }
|
|
52
56
|
|
|
53
57
|
.frame {
|
|
54
|
-
max-width:
|
|
58
|
+
max-width: 1400px;
|
|
55
59
|
margin: 0 auto;
|
|
56
60
|
border-radius: 22px;
|
|
57
61
|
overflow: hidden;
|
|
58
62
|
box-shadow: var(--shadow);
|
|
59
63
|
border: 1px solid var(--line);
|
|
60
|
-
background: rgba(255,
|
|
64
|
+
background: rgba(255, 250, 242, .35);
|
|
61
65
|
}
|
|
62
66
|
|
|
63
67
|
.shell {
|
|
64
68
|
display: grid;
|
|
65
|
-
grid-template-columns: 290px 1fr;
|
|
69
|
+
grid-template-columns: 290px minmax(520px, 1fr) 380px;
|
|
70
|
+
min-height: calc(100vh - 36px);
|
|
66
71
|
}
|
|
67
72
|
|
|
68
|
-
@media (max-width:
|
|
73
|
+
@media (max-width: 1200px) {
|
|
74
|
+
.shell { grid-template-columns: 280px 1fr; }
|
|
75
|
+
.chatPane { display: none; }
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
@media (max-width: 860px) {
|
|
69
79
|
.shell { grid-template-columns: 1fr; }
|
|
80
|
+
.sidebar { border-right: none; border-bottom: 1px solid var(--line); }
|
|
70
81
|
}
|
|
71
82
|
|
|
83
|
+
/* LEFT */
|
|
72
84
|
.sidebar {
|
|
73
|
-
background: linear-gradient(180deg, rgba(255,
|
|
85
|
+
background: linear-gradient(180deg, rgba(255,250,242,.85), rgba(255,250,242,.60));
|
|
74
86
|
border-right: 1px solid var(--line);
|
|
75
87
|
padding: 14px;
|
|
76
88
|
}
|
|
@@ -88,7 +100,7 @@ body {
|
|
|
88
100
|
|
|
89
101
|
.sideHeader .logo {
|
|
90
102
|
font-weight: 900;
|
|
91
|
-
letter-spacing: .
|
|
103
|
+
letter-spacing: .10em;
|
|
92
104
|
font-size: 12px;
|
|
93
105
|
color: var(--muted);
|
|
94
106
|
}
|
|
@@ -119,39 +131,41 @@ body {
|
|
|
119
131
|
}
|
|
120
132
|
|
|
121
133
|
.sideGroup { margin-top: 10px; padding: 10px 6px; border-top: 1px solid var(--line); }
|
|
122
|
-
.sideTitle { font-weight: 800; font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); margin-bottom:
|
|
134
|
+
.sideTitle { font-weight: 800; font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); margin-bottom: 10px; }
|
|
123
135
|
|
|
124
|
-
.
|
|
136
|
+
.cardsMini { display: grid; gap: 8px; }
|
|
137
|
+
.miniCard {
|
|
138
|
+
width: 100%;
|
|
139
|
+
text-align: left;
|
|
125
140
|
border: 1px solid var(--line);
|
|
126
|
-
border-radius:
|
|
141
|
+
border-radius: 14px;
|
|
127
142
|
background: var(--paper2);
|
|
128
143
|
padding: 10px 12px;
|
|
129
144
|
cursor: pointer;
|
|
145
|
+
display: flex;
|
|
146
|
+
align-items: center;
|
|
147
|
+
gap: 10px;
|
|
130
148
|
font-weight: 800;
|
|
131
149
|
color: var(--muted);
|
|
132
150
|
}
|
|
151
|
+
.miniCard:hover { border-color: var(--line2); box-shadow: var(--shadow2); }
|
|
133
152
|
|
|
134
|
-
.
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
display: inline-block;
|
|
142
|
-
padding: 2px 6px;
|
|
153
|
+
.miniIcon {
|
|
154
|
+
width: 26px;
|
|
155
|
+
height: 26px;
|
|
156
|
+
border-radius: 10px;
|
|
157
|
+
display: grid;
|
|
158
|
+
place-items: center;
|
|
159
|
+
background: var(--chip);
|
|
143
160
|
border: 1px solid var(--line);
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
font-family: var(--mono);
|
|
147
|
-
font-size: 12px;
|
|
148
|
-
color: var(--muted);
|
|
161
|
+
color: var(--primary);
|
|
162
|
+
font-weight: 900;
|
|
149
163
|
}
|
|
164
|
+
.miniIcon.warn { background: var(--chip2); color: var(--accent); }
|
|
150
165
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
.
|
|
154
|
-
[data-theme="dark"] .main { background: rgba(10, 14, 26, .55); }
|
|
166
|
+
/* CENTER */
|
|
167
|
+
.center { background: rgba(255, 250, 242, .58); }
|
|
168
|
+
[data-theme="dark"] .center { background: rgba(10, 14, 26, .55); }
|
|
155
169
|
|
|
156
170
|
.topbar {
|
|
157
171
|
display: flex;
|
|
@@ -159,67 +173,177 @@ body {
|
|
|
159
173
|
align-items: center;
|
|
160
174
|
padding: 14px 16px;
|
|
161
175
|
border-bottom: 1px solid var(--line);
|
|
162
|
-
background: linear-gradient(90deg, rgba(255,
|
|
176
|
+
background: linear-gradient(90deg, rgba(255,250,242,.75), rgba(255,250,242,.45));
|
|
163
177
|
}
|
|
164
178
|
|
|
165
179
|
[data-theme="dark"] .topbar { background: linear-gradient(90deg, rgba(17,24,39,.88), rgba(17,24,39,.55)); }
|
|
166
180
|
|
|
167
181
|
.brand { display: flex; align-items: center; gap: 10px; font-weight: 900; font-size: 12px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
|
|
168
|
-
.spark { width: 10px; height: 10px; border-radius: 4px; background: linear-gradient(135deg, var(--accent), var(--primary)); box-shadow: 0 0 0 6px rgba(249,115,22,.
|
|
182
|
+
.spark { width: 10px; height: 10px; border-radius: 4px; background: linear-gradient(135deg, var(--accent), var(--primary)); box-shadow: 0 0 0 6px rgba(249,115,22,.10); }
|
|
169
183
|
.actions { display: flex; align-items: center; gap: 10px; }
|
|
170
|
-
.chip { font-family: var(--mono); font-size: 12px; padding: 7px 10px; border-radius: 999px; border: 1px solid var(--line); background: rgba(255,
|
|
184
|
+
.chip { font-family: var(--mono); font-size: 12px; padding: 7px 10px; border-radius: 999px; border: 1px solid var(--line); background: rgba(255,250,242,.65); color: var(--faint); }
|
|
171
185
|
[data-theme="dark"] .chip { background: rgba(0,0,0,.20); }
|
|
172
|
-
.toggle { border: 1px solid var(--line); border-radius: 999px; background: var(--paper2); padding: 7px 10px; cursor: pointer; color: var(--muted); font-weight:
|
|
186
|
+
.toggle { border: 1px solid var(--line); border-radius: 999px; background: var(--paper2); padding: 7px 10px; cursor: pointer; color: var(--muted); font-weight: 800; font-size: 12px; }
|
|
173
187
|
|
|
174
|
-
.
|
|
188
|
+
.centerBody { padding: 16px; }
|
|
189
|
+
.centerHead { display: flex; justify-content: space-between; align-items: flex-end; gap: 18px; margin-bottom: 14px; }
|
|
190
|
+
.statusLine { display:flex; align-items:center; justify-content:flex-end; gap: 12px; }
|
|
175
191
|
|
|
176
192
|
h1 { margin: 0; font-size: 22px; letter-spacing: -.02em; }
|
|
177
193
|
.subtitle { margin-top: 6px; color: var(--muted); font-size: 13px; line-height: 1.4; max-width: 860px; }
|
|
178
194
|
|
|
179
|
-
.
|
|
180
|
-
|
|
181
|
-
@media (max-width:
|
|
182
|
-
|
|
183
|
-
.
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
.icon { width: 34px; height: 34px; border-radius: 12px; display: grid; place-items: center; background: var(--chip); border: 1px solid var(--line); color: var(--primary); font-weight: 900; }
|
|
187
|
-
.icon.orange { background: var(--chip2); color: var(--accent); }
|
|
188
|
-
|
|
189
|
-
.title { font-weight: 800; font-size: 13px; }
|
|
190
|
-
.desc { color: var(--muted); font-size: 12px; line-height: 1.35; }
|
|
191
|
-
|
|
192
|
-
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-top: 14px; }
|
|
193
|
-
@media (max-width: 980px) { .grid2 { grid-template-columns: 1fr; } }
|
|
195
|
+
.midGrid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
|
|
196
|
+
.midSpan { grid-column: 1 / -1; }
|
|
197
|
+
@media (max-width: 980px) {
|
|
198
|
+
.midGrid { grid-template-columns: 1fr; }
|
|
199
|
+
.midSpan { grid-column: auto; }
|
|
200
|
+
}
|
|
194
201
|
|
|
195
|
-
.panel { border: 1px solid var(--line); background: var(--paper); border-radius:
|
|
202
|
+
.panel { border: 1px solid var(--line); background: var(--paper); border-radius: var(--radius); overflow: hidden; box-shadow: 0 1px 0 rgba(16,24,40,.04); }
|
|
196
203
|
.panelHead { display: flex; align-items: center; justify-content: space-between; padding: 12px 12px; border-bottom: 1px solid var(--line); background: linear-gradient(180deg, var(--paper2), var(--paper)); }
|
|
197
204
|
.panelHead b { font-size: 12px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
|
|
198
205
|
.panelBody { padding: 12px; }
|
|
199
206
|
|
|
207
|
+
/* DEV DRAWER */
|
|
208
|
+
.devDrawer { margin-top: 14px; border: 1px dashed var(--line2); border-radius: var(--radius); background: rgba(255,250,242,.42); }
|
|
209
|
+
[data-theme="dark"] .devDrawer { background: rgba(0,0,0,.18); }
|
|
210
|
+
.devDrawer > summary {
|
|
211
|
+
cursor: pointer;
|
|
212
|
+
list-style: none;
|
|
213
|
+
padding: 12px 14px;
|
|
214
|
+
font-weight: 900;
|
|
215
|
+
color: var(--muted);
|
|
216
|
+
}
|
|
217
|
+
.devDrawer > summary::-webkit-details-marker { display:none; }
|
|
218
|
+
.devBody { padding: 0 14px 14px; }
|
|
219
|
+
.devGrid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 14px; }
|
|
220
|
+
@media (max-width: 1100px) { .devGrid { grid-template-columns: 1fr; } }
|
|
221
|
+
|
|
222
|
+
/* FORMS */
|
|
200
223
|
label { display: block; font-size: 12px; color: var(--muted); margin-bottom: 6px; }
|
|
201
224
|
input { width: 100%; padding: 11px 12px; border-radius: 12px; border: 1px solid var(--line); background: rgba(255,255,255,.72); color: var(--text); outline: none; }
|
|
202
225
|
[data-theme="dark"] input { background: rgba(0,0,0,.16); }
|
|
203
226
|
input:focus { box-shadow: var(--ring); border-color: rgba(37,99,235,.35); }
|
|
227
|
+
textarea {
|
|
228
|
+
width: 100%;
|
|
229
|
+
padding: 10px 12px;
|
|
230
|
+
border-radius: 12px;
|
|
231
|
+
border: 1px solid var(--line);
|
|
232
|
+
background: rgba(255,255,255,.72);
|
|
233
|
+
color: var(--text);
|
|
234
|
+
outline: none;
|
|
235
|
+
resize: vertical;
|
|
236
|
+
}
|
|
237
|
+
[data-theme="dark"] textarea { background: rgba(0,0,0,.16); }
|
|
238
|
+
textarea:focus { box-shadow: var(--ring); border-color: rgba(37,99,235,.35); }
|
|
204
239
|
|
|
205
240
|
.row { display: grid; grid-template-columns: 1fr auto; gap: 10px; align-items: center; }
|
|
206
241
|
.stack { display: flex; gap: 10px; flex-wrap: wrap; }
|
|
207
242
|
.help { font-size: 12px; color: var(--faint); line-height: 1.4; }
|
|
243
|
+
.small { font-size: 12px; color: var(--faint); }
|
|
208
244
|
|
|
209
|
-
|
|
245
|
+
/* BUTTONS */
|
|
246
|
+
.btn {
|
|
247
|
+
border: 1px solid var(--line);
|
|
248
|
+
border-radius: 12px;
|
|
249
|
+
background: var(--paper2);
|
|
250
|
+
padding: 10px 12px;
|
|
251
|
+
cursor: pointer;
|
|
252
|
+
font-weight: 900;
|
|
253
|
+
color: var(--muted);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
.btn:hover { border-color: var(--line2); box-shadow: var(--shadow2); }
|
|
257
|
+
.btn.small { padding: 7px 10px; border-radius: 10px; font-size: 12px; }
|
|
258
|
+
.btn.primary { background: rgba(37,99,235,.12); border-color: rgba(37,99,235,.34); color: rgba(37,99,235,.95); }
|
|
259
|
+
.sideBtn { width: 100%; text-align: left; margin-top: 8px; }
|
|
260
|
+
|
|
261
|
+
.k {
|
|
262
|
+
display: inline-block;
|
|
263
|
+
padding: 2px 6px;
|
|
264
|
+
border: 1px solid var(--line);
|
|
265
|
+
border-radius: 8px;
|
|
266
|
+
background: rgba(255,250,242,.75);
|
|
267
|
+
font-family: var(--mono);
|
|
268
|
+
font-size: 12px;
|
|
269
|
+
color: var(--muted);
|
|
270
|
+
}
|
|
271
|
+
[data-theme="dark"] .k { background: rgba(0,0,0,.18); }
|
|
272
|
+
|
|
273
|
+
/* REPORT/TODAY ITEMS + PREVIEW */
|
|
274
|
+
.log { padding: 12px; border: 1px solid var(--line); border-radius: var(--radius); background: rgba(255,250,242,.65); font-family: var(--mono); font-size: 12px; color: var(--muted); white-space: pre-wrap; word-break: break-word; max-height: 360px; overflow: auto; }
|
|
210
275
|
[data-theme="dark"] .log { background: rgba(0,0,0,.18); }
|
|
211
276
|
|
|
212
277
|
.rep { width: 100%; text-align: left; border: 1px solid var(--line); border-radius: 12px; background: var(--paper2); padding: 10px 12px; cursor: pointer; font-family: var(--mono); font-size: 12px; color: var(--muted); }
|
|
213
278
|
.rep:hover { border-color: var(--line2); box-shadow: 0 10px 22px rgba(16,24,40,.10); }
|
|
214
279
|
.repActive { border-color: rgba(59,130,246,.55); box-shadow: 0 0 0 4px rgba(59,130,246,.12); }
|
|
215
280
|
|
|
281
|
+
/* Markdown */
|
|
216
282
|
.md-h1{ font-size: 20px; margin: 10px 0 6px; }
|
|
217
283
|
.md-h2{ font-size: 16px; margin: 10px 0 6px; }
|
|
218
284
|
.md-h3{ font-size: 14px; margin: 10px 0 6px; }
|
|
219
285
|
.md-p{ margin: 6px 0; color: var(--muted); line-height: 1.5; }
|
|
220
286
|
.md-ul{ margin: 6px 0 6px 18px; color: var(--muted); }
|
|
221
|
-
.md-inline{ font-family: var(--mono); font-size: 12px; padding: 2px 6px; border: 1px solid var(--line); border-radius: 8px; background: rgba(255,
|
|
287
|
+
.md-inline{ font-family: var(--mono); font-size: 12px; padding: 2px 6px; border: 1px solid var(--line); border-radius: 8px; background: rgba(255,250,242,.60); }
|
|
222
288
|
[data-theme="dark"] .md-inline{ background: rgba(0,0,0,.18); }
|
|
223
|
-
.md-code{ background: rgba(0,0,0,.05); border: 1px solid var(--line); border-radius:
|
|
289
|
+
.md-code{ background: rgba(0,0,0,.05); border: 1px solid var(--line); border-radius: var(--radius); padding: 12px; overflow:auto; }
|
|
224
290
|
[data-theme="dark"] .md-code{ background: rgba(0,0,0,.22); }
|
|
225
291
|
.md-sp{ height: 10px; }
|
|
292
|
+
|
|
293
|
+
/* RIGHT: CHAT */
|
|
294
|
+
.chatPane {
|
|
295
|
+
border-left: 1px solid var(--line);
|
|
296
|
+
background: linear-gradient(180deg, rgba(255,250,242,.82), rgba(255,250,242,.60));
|
|
297
|
+
display: grid;
|
|
298
|
+
grid-template-rows: auto 1fr auto;
|
|
299
|
+
}
|
|
300
|
+
[data-theme="dark"] .chatPane {
|
|
301
|
+
background: linear-gradient(180deg, rgba(17,24,39,.92), rgba(17,24,39,.68));
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
.chatHead { padding: 14px; border-bottom: 1px solid var(--line); }
|
|
305
|
+
.chatTitle { font-weight: 950; letter-spacing: -.01em; }
|
|
306
|
+
.chatSub { margin-top: 2px; font-size: 12px; color: var(--faint); }
|
|
307
|
+
|
|
308
|
+
.chatThread {
|
|
309
|
+
padding: 14px;
|
|
310
|
+
overflow: auto;
|
|
311
|
+
display: flex;
|
|
312
|
+
flex-direction: column;
|
|
313
|
+
gap: 10px;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
.bubble {
|
|
317
|
+
max-width: 92%;
|
|
318
|
+
border-radius: 18px;
|
|
319
|
+
padding: 10px 12px;
|
|
320
|
+
border: 1px solid var(--line);
|
|
321
|
+
box-shadow: 0 1px 0 rgba(16,24,40,.03);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
.bubble .bubbleMeta { font-size: 11px; font-weight: 900; color: var(--faint); margin-bottom: 6px; }
|
|
325
|
+
.bubble .bubbleBody { font-size: 13px; line-height: 1.45; color: var(--text); }
|
|
326
|
+
|
|
327
|
+
.bubble.user {
|
|
328
|
+
align-self: flex-end;
|
|
329
|
+
background: rgba(37,99,235,.10);
|
|
330
|
+
border-color: rgba(37,99,235,.22);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
.bubble.assistant {
|
|
334
|
+
align-self: flex-start;
|
|
335
|
+
background: rgba(255,250,242,.82);
|
|
336
|
+
}
|
|
337
|
+
[data-theme="dark"] .bubble.assistant { background: rgba(0,0,0,.18); }
|
|
338
|
+
|
|
339
|
+
.chatComposer {
|
|
340
|
+
padding: 12px 14px 14px;
|
|
341
|
+
border-top: 1px solid var(--line);
|
|
342
|
+
background: rgba(255,250,242,.55);
|
|
343
|
+
}
|
|
344
|
+
[data-theme="dark"] .chatComposer { background: rgba(0,0,0,.12); }
|
|
345
|
+
|
|
346
|
+
.composerActions { display: flex; gap: 10px; margin-top: 10px; flex-wrap: wrap; }
|
|
347
|
+
.composerToggles { margin-top: 10px; display: grid; gap: 6px; }
|
|
348
|
+
.toggleRow { display:flex; align-items:center; gap:10px; user-select:none; font-size: 12px; color: var(--muted); }
|
|
349
|
+
.statusFooter { margin-top: 10px; display:flex; justify-content:flex-end; }
|
package/cli/web-ui.js
CHANGED
|
@@ -114,6 +114,37 @@
|
|
|
114
114
|
return html;
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
+
function chatAppend(role, text, opts = {}) {
|
|
118
|
+
const thread = $('chatThread');
|
|
119
|
+
if (!thread) return;
|
|
120
|
+
|
|
121
|
+
const bubble = document.createElement('div');
|
|
122
|
+
bubble.className = 'bubble ' + (role === 'user' ? 'user' : 'assistant');
|
|
123
|
+
|
|
124
|
+
const meta = document.createElement('div');
|
|
125
|
+
meta.className = 'bubbleMeta';
|
|
126
|
+
meta.textContent = role === 'user' ? 'You' : 'FREYA';
|
|
127
|
+
|
|
128
|
+
const body = document.createElement('div');
|
|
129
|
+
body.className = 'bubbleBody';
|
|
130
|
+
|
|
131
|
+
const raw = String(text || '');
|
|
132
|
+
if (opts.markdown) {
|
|
133
|
+
body.innerHTML = renderMarkdown(raw);
|
|
134
|
+
} else {
|
|
135
|
+
body.innerHTML = escapeHtml(raw).replace(/\n/g, '<br>');
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
bubble.appendChild(meta);
|
|
139
|
+
bubble.appendChild(body);
|
|
140
|
+
thread.appendChild(bubble);
|
|
141
|
+
|
|
142
|
+
// keep newest in view
|
|
143
|
+
try {
|
|
144
|
+
thread.scrollTop = thread.scrollHeight;
|
|
145
|
+
} catch {}
|
|
146
|
+
}
|
|
147
|
+
|
|
117
148
|
function setOut(text) {
|
|
118
149
|
state.lastText = text || '';
|
|
119
150
|
const el = $('reportPreview');
|
|
@@ -717,6 +748,8 @@
|
|
|
717
748
|
return;
|
|
718
749
|
}
|
|
719
750
|
|
|
751
|
+
chatAppend('user', text);
|
|
752
|
+
|
|
720
753
|
setPill('run', 'saving…');
|
|
721
754
|
await api('/api/inbox/add', { dir: dirOrDefault(), text });
|
|
722
755
|
|
|
@@ -727,7 +760,9 @@
|
|
|
727
760
|
|
|
728
761
|
// Show plan output in Preview panel
|
|
729
762
|
const header = r.ok === false ? '## Agent Plan (planner unavailable)\n\n' : '## Agent Plan (draft)\n\n';
|
|
730
|
-
|
|
763
|
+
const planOut = header + (r.plan || '');
|
|
764
|
+
setOut(planOut);
|
|
765
|
+
chatAppend('assistant', planOut, { markdown: true });
|
|
731
766
|
ta.value = '';
|
|
732
767
|
|
|
733
768
|
if (r.ok === false) {
|
|
@@ -807,6 +842,7 @@
|
|
|
807
842
|
}
|
|
808
843
|
|
|
809
844
|
setOut(msg);
|
|
845
|
+
chatAppend('assistant', msg, { markdown: true });
|
|
810
846
|
setPill('ok', 'applied');
|
|
811
847
|
setTimeout(() => setPill('ok', 'idle'), 800);
|
|
812
848
|
} catch (e) {
|
|
@@ -821,6 +857,18 @@
|
|
|
821
857
|
$('chipPort').textContent = location.host;
|
|
822
858
|
loadLocal();
|
|
823
859
|
|
|
860
|
+
// Developer drawer (persist open/close)
|
|
861
|
+
try {
|
|
862
|
+
const d = $('devDrawer');
|
|
863
|
+
if (d) {
|
|
864
|
+
const open = localStorage.getItem('freya.devDrawer') === '1';
|
|
865
|
+
if (open) d.open = true;
|
|
866
|
+
d.addEventListener('toggle', () => {
|
|
867
|
+
try { localStorage.setItem('freya.devDrawer', d.open ? '1' : '0'); } catch {}
|
|
868
|
+
});
|
|
869
|
+
}
|
|
870
|
+
} catch {}
|
|
871
|
+
|
|
824
872
|
// Load persisted settings from the workspace + bootstrap (auto-init + auto-health)
|
|
825
873
|
(async () => {
|
|
826
874
|
let defaults = null;
|
package/cli/web.js
CHANGED
|
@@ -677,6 +677,7 @@ function buildHtml(safeDefault) {
|
|
|
677
677
|
<div class="frame">
|
|
678
678
|
<div class="shell">
|
|
679
679
|
|
|
680
|
+
<!-- LEFT: Workspaces / Topics -->
|
|
680
681
|
<aside class="sidebar">
|
|
681
682
|
<div class="sideHeader">
|
|
682
683
|
<div class="logo">FREYA</div>
|
|
@@ -686,47 +687,41 @@ function buildHtml(safeDefault) {
|
|
|
686
687
|
<div class="sidePath" id="sidePath">./freya</div>
|
|
687
688
|
|
|
688
689
|
<div class="sideGroup">
|
|
689
|
-
<div class="sideTitle">
|
|
690
|
-
<
|
|
691
|
-
|
|
692
|
-
|
|
690
|
+
<div class="sideTitle">Workspaces</div>
|
|
691
|
+
<div class="row" style="grid-template-columns: 1fr auto">
|
|
692
|
+
<input id="dir" placeholder="./freya" />
|
|
693
|
+
<button class="btn small" onclick="pickDir()">Browse</button>
|
|
694
|
+
</div>
|
|
695
|
+
<div class="stack" style="margin-top:10px">
|
|
696
|
+
<button class="btn sideBtn" onclick="doUpdate()">Sync workspace</button>
|
|
697
|
+
<button class="btn sideBtn" onclick="doMigrate()">Migrate data</button>
|
|
698
|
+
</div>
|
|
693
699
|
<div style="height:10px"></div>
|
|
694
700
|
<div class="help"><b>Sync workspace</b>: atualiza scripts/templates/agents na pasta <code>freya</code> sem sobrescrever <code>data/</code> e <code>logs/</code>.</div>
|
|
695
701
|
<div class="help"><b>Migrate data</b>: ajusta formatos/schemaVersion quando uma versão nova exige.</div>
|
|
696
702
|
</div>
|
|
697
703
|
|
|
698
704
|
<div class="sideGroup">
|
|
699
|
-
<div class="sideTitle">
|
|
700
|
-
<div class="
|
|
701
|
-
|
|
702
|
-
|
|
705
|
+
<div class="sideTitle">Quick reports</div>
|
|
706
|
+
<div class="cardsMini">
|
|
707
|
+
<button class="miniCard" type="button" onclick="runReport('status')"><span class="miniIcon">E</span><span>Executive</span></button>
|
|
708
|
+
<button class="miniCard" type="button" onclick="runReport('sm-weekly')"><span class="miniIcon">S</span><span>SM weekly</span></button>
|
|
709
|
+
<button class="miniCard" type="button" onclick="runReport('blockers')"><span class="miniIcon warn">B</span><span>Blockers</span></button>
|
|
710
|
+
<button class="miniCard" type="button" onclick="runReport('daily')"><span class="miniIcon">D</span><span>Daily</span></button>
|
|
711
|
+
</div>
|
|
712
|
+
<div class="help" style="margin-top:8px">Clique para gerar e atualizar o preview/publicação.</div>
|
|
703
713
|
</div>
|
|
704
714
|
|
|
705
715
|
<div class="sideGroup">
|
|
706
|
-
<div class="sideTitle">
|
|
707
|
-
<
|
|
708
|
-
<div style="height:
|
|
709
|
-
<div class="
|
|
710
|
-
<button class="btn primary sideBtn" onclick="saveAndPlan()">Save + Process (Agents)</button>
|
|
711
|
-
<button class="btn sideBtn" onclick="runSuggestedReports()">Run suggested reports</button>
|
|
712
|
-
</div>
|
|
713
|
-
|
|
714
|
-
<div style="height:10px"></div>
|
|
715
|
-
<label style="display:flex; align-items:center; gap:10px; user-select:none">
|
|
716
|
-
<input id="autoApply" type="checkbox" checked style="width:auto" onchange="toggleAutoApply()" />
|
|
717
|
-
Auto-apply plan
|
|
718
|
-
</label>
|
|
719
|
-
<div class="help">Quando ligado, o Save+Process já aplica tasks/blockers automaticamente.</div>
|
|
720
|
-
|
|
721
|
-
<label style="display:flex; align-items:center; gap:10px; user-select:none; margin-top:10px">
|
|
722
|
-
<input id="autoRunReports" type="checkbox" style="width:auto" onchange="toggleAutoRunReports()" />
|
|
723
|
-
Auto-run suggested reports
|
|
724
|
-
</label>
|
|
725
|
-
<div class="help">Quando ligado, após aplicar o plano, ele também roda os reports sugeridos automaticamente.</div>
|
|
716
|
+
<div class="sideTitle">Tips</div>
|
|
717
|
+
<div class="help"><span class="k">--dev</span> cria dados de exemplo para testar rápido.</div>
|
|
718
|
+
<div style="height:8px"></div>
|
|
719
|
+
<div class="help"><span class="k">--port</span> muda a porta (default 3872).</div>
|
|
726
720
|
</div>
|
|
727
721
|
</aside>
|
|
728
722
|
|
|
729
|
-
|
|
723
|
+
<!-- MIDDLE: Reports / Today -->
|
|
724
|
+
<main class="center">
|
|
730
725
|
<div class="topbar">
|
|
731
726
|
<div class="brand"><span class="spark"></span> Local-first status assistant</div>
|
|
732
727
|
<div class="actions">
|
|
@@ -735,83 +730,35 @@ function buildHtml(safeDefault) {
|
|
|
735
730
|
</div>
|
|
736
731
|
</div>
|
|
737
732
|
|
|
738
|
-
<div class="
|
|
739
|
-
<
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
<div class="card" onclick="runReport('status')">
|
|
744
|
-
<div class="icon">E</div>
|
|
745
|
-
<div class="title">Executive report</div>
|
|
746
|
-
<div class="desc">Status pronto para stakeholders (entregas, projetos, blockers).</div>
|
|
747
|
-
</div>
|
|
748
|
-
<div class="card" onclick="runReport('sm-weekly')">
|
|
749
|
-
<div class="icon">S</div>
|
|
750
|
-
<div class="title">SM weekly</div>
|
|
751
|
-
<div class="desc">Resumo, wins, riscos e foco da próxima semana.</div>
|
|
733
|
+
<div class="centerBody">
|
|
734
|
+
<div class="centerHead">
|
|
735
|
+
<div>
|
|
736
|
+
<h1 style="margin:0">Your day at a glance</h1>
|
|
737
|
+
<div class="subtitle">Workspaces, Today (tasks/blockers), reports & preview. Use the right panel as a chat-style capture.</div>
|
|
752
738
|
</div>
|
|
753
|
-
<div class="
|
|
754
|
-
<
|
|
755
|
-
<div class="title">Blockers</div>
|
|
756
|
-
<div class="desc">Lista priorizada por severidade + idade (pra destravar rápido).</div>
|
|
757
|
-
</div>
|
|
758
|
-
<div class="card" onclick="runReport('daily')">
|
|
759
|
-
<div class="icon">D</div>
|
|
760
|
-
<div class="title">Daily</div>
|
|
761
|
-
<div class="desc">Ontem / Hoje / Bloqueios — pronto pra standup.</div>
|
|
739
|
+
<div class="statusLine">
|
|
740
|
+
<span class="small" id="last"></span>
|
|
762
741
|
</div>
|
|
763
742
|
</div>
|
|
764
743
|
|
|
765
|
-
<div class="
|
|
766
|
-
<
|
|
767
|
-
<div class="panelHead"
|
|
768
|
-
|
|
769
|
-
<label>Workspace dir</label>
|
|
770
|
-
<div class="row">
|
|
771
|
-
<input id="dir" placeholder="./freya" />
|
|
772
|
-
<button class="btn small" onclick="pickDir()">Browse</button>
|
|
773
|
-
</div>
|
|
774
|
-
<div class="help">Escolha a pasta que contém <code>data/</code>, <code>logs/</code> e <code>scripts/</code>.</div>
|
|
775
|
-
|
|
776
|
-
<div style="height:12px"></div>
|
|
777
|
-
|
|
778
|
-
<label>Discord webhook URL</label>
|
|
779
|
-
<input id="discord" placeholder="https://discord.com/api/webhooks/..." />
|
|
780
|
-
<div style="height:10px"></div>
|
|
781
|
-
|
|
782
|
-
<label>Teams webhook URL</label>
|
|
783
|
-
<input id="teams" placeholder="https://..." />
|
|
784
|
-
<div class="help">Os webhooks ficam salvos na workspace em <code>data/settings/settings.json</code>.</div>
|
|
785
|
-
|
|
786
|
-
<div style="height:10px"></div>
|
|
787
|
-
<label style="display:flex; align-items:center; gap:10px; user-select:none; margin: 6px 0 12px 0">
|
|
788
|
-
<input id="prettyPublish" type="checkbox" checked style="width:auto" onchange="togglePrettyPublish()" />
|
|
789
|
-
Pretty publish (cards/embeds)
|
|
790
|
-
</label>
|
|
791
|
-
|
|
744
|
+
<div class="midGrid">
|
|
745
|
+
<section class="panel">
|
|
746
|
+
<div class="panelHead">
|
|
747
|
+
<b>Today</b>
|
|
792
748
|
<div class="stack">
|
|
793
|
-
<button class="btn" onclick="
|
|
794
|
-
<button class="btn" onclick="publish('discord')">Publish selected → Discord</button>
|
|
795
|
-
<button class="btn" onclick="publish('teams')">Publish selected → Teams</button>
|
|
796
|
-
</div>
|
|
797
|
-
|
|
798
|
-
<div style="height:14px"></div>
|
|
799
|
-
|
|
800
|
-
<div class="help"><b>Dica:</b> clique em um relatório em <i>Reports</i> para ver o preview e habilitar publish/copy.</div>
|
|
801
|
-
|
|
802
|
-
<div style="height:14px"></div>
|
|
803
|
-
<label>Project slug rules</label>
|
|
804
|
-
<textarea id="slugRules" rows="8" placeholder="{ \"rules\": [ { \"contains\": \"fideliza\", \"slug\": \"vivo/fidelizacao\" } ] }" style="width:100%; padding:10px 12px; border-radius:12px; border:1px solid var(--line); background: rgba(255,255,255,.72); color: var(--text); outline:none; resize: vertical; font-family: var(--mono);"></textarea>
|
|
805
|
-
<div class="help">Regras usadas pra inferir <code>projectSlug</code>. Formato JSON (objeto com <code>rules</code>). Editável no estilo Obsidian-friendly.</div>
|
|
806
|
-
<div class="stack" style="margin-top:10px">
|
|
807
|
-
<button class="btn" onclick="reloadSlugRules()">Reload rules</button>
|
|
808
|
-
<button class="btn" onclick="saveSlugRules()">Save rules</button>
|
|
809
|
-
<button class="btn" onclick="exportObsidian()">Export Obsidian notes</button>
|
|
749
|
+
<button class="btn small" onclick="refreshToday()">Refresh</button>
|
|
810
750
|
</div>
|
|
811
751
|
</div>
|
|
812
|
-
|
|
752
|
+
<div class="panelBody">
|
|
753
|
+
<div class="small" style="margin-bottom:8px; opacity:.8">Do Now</div>
|
|
754
|
+
<div id="tasksList" style="display:grid; gap:8px"></div>
|
|
755
|
+
<div style="height:12px"></div>
|
|
756
|
+
<div class="small" style="margin-bottom:8px; opacity:.8">Open blockers</div>
|
|
757
|
+
<div id="blockersList" style="display:grid; gap:8px"></div>
|
|
758
|
+
</div>
|
|
759
|
+
</section>
|
|
813
760
|
|
|
814
|
-
<
|
|
761
|
+
<section class="panel">
|
|
815
762
|
<div class="panelHead">
|
|
816
763
|
<b>Reports</b>
|
|
817
764
|
<div class="stack">
|
|
@@ -823,25 +770,9 @@ function buildHtml(safeDefault) {
|
|
|
823
770
|
<div id="reportsList" style="display:grid; gap:8px"></div>
|
|
824
771
|
<div class="help">Últimos relatórios em <code>docs/reports</code>. Clique para abrir preview.</div>
|
|
825
772
|
</div>
|
|
826
|
-
</
|
|
773
|
+
</section>
|
|
827
774
|
|
|
828
|
-
<
|
|
829
|
-
<div class="panelHead">
|
|
830
|
-
<b>Today</b>
|
|
831
|
-
<div class="stack">
|
|
832
|
-
<button class="btn small" onclick="refreshToday()">Refresh</button>
|
|
833
|
-
</div>
|
|
834
|
-
</div>
|
|
835
|
-
<div class="panelBody">
|
|
836
|
-
<div class="small" style="margin-bottom:8px; opacity:.8">Do Now</div>
|
|
837
|
-
<div id="tasksList" style="display:grid; gap:8px"></div>
|
|
838
|
-
<div style="height:12px"></div>
|
|
839
|
-
<div class="small" style="margin-bottom:8px; opacity:.8">Open blockers</div>
|
|
840
|
-
<div id="blockersList" style="display:grid; gap:8px"></div>
|
|
841
|
-
</div>
|
|
842
|
-
</div>
|
|
843
|
-
|
|
844
|
-
<div class="panel">
|
|
775
|
+
<section class="panel midSpan">
|
|
845
776
|
<div class="panelHead">
|
|
846
777
|
<b>Preview</b>
|
|
847
778
|
<div class="stack">
|
|
@@ -857,11 +788,106 @@ function buildHtml(safeDefault) {
|
|
|
857
788
|
<div id="reportPreview" class="log md" style="font-family: var(--sans);"></div>
|
|
858
789
|
<div class="help">O preview renderiza Markdown básico (headers, listas, code). O botão Copy copia o conteúdo completo.</div>
|
|
859
790
|
</div>
|
|
860
|
-
</
|
|
791
|
+
</section>
|
|
861
792
|
</div>
|
|
793
|
+
|
|
794
|
+
<details class="devDrawer" id="devDrawer">
|
|
795
|
+
<summary>Developer</summary>
|
|
796
|
+
<div class="devBody">
|
|
797
|
+
<div class="devGrid">
|
|
798
|
+
<div class="panel">
|
|
799
|
+
<div class="panelHead"><b>Publish settings</b></div>
|
|
800
|
+
<div class="panelBody">
|
|
801
|
+
<label>Discord webhook URL</label>
|
|
802
|
+
<input id="discord" placeholder="https://discord.com/api/webhooks/..." />
|
|
803
|
+
<div style="height:10px"></div>
|
|
804
|
+
|
|
805
|
+
<label>Teams webhook URL</label>
|
|
806
|
+
<input id="teams" placeholder="https://..." />
|
|
807
|
+
<div class="help">Os webhooks ficam salvos na workspace em <code>data/settings/settings.json</code>.</div>
|
|
808
|
+
|
|
809
|
+
<div style="height:10px"></div>
|
|
810
|
+
<label style="display:flex; align-items:center; gap:10px; user-select:none; margin: 6px 0 12px 0">
|
|
811
|
+
<input id="prettyPublish" type="checkbox" checked style="width:auto" onchange="togglePrettyPublish()" />
|
|
812
|
+
Pretty publish (cards/embeds)
|
|
813
|
+
</label>
|
|
814
|
+
|
|
815
|
+
<div class="stack">
|
|
816
|
+
<button class="btn" onclick="saveSettings()">Save settings</button>
|
|
817
|
+
<button class="btn" onclick="publish('discord')">Publish selected → Discord</button>
|
|
818
|
+
<button class="btn" onclick="publish('teams')">Publish selected → Teams</button>
|
|
819
|
+
</div>
|
|
820
|
+
</div>
|
|
821
|
+
</div>
|
|
822
|
+
|
|
823
|
+
<div class="panel">
|
|
824
|
+
<div class="panelHead"><b>Slug rules & export</b></div>
|
|
825
|
+
<div class="panelBody">
|
|
826
|
+
<label>Project slug rules</label>
|
|
827
|
+
<textarea id="slugRules" rows="8" placeholder="{ \"rules\": [ { \"contains\": \"fideliza\", \"slug\": \"vivo/fidelizacao\" } ] }" style="width:100%; padding:10px 12px; border-radius:12px; border:1px solid var(--line); background: rgba(255,255,255,.72); color: var(--text); outline:none; resize: vertical; font-family: var(--mono);"></textarea>
|
|
828
|
+
<div class="help">Regras usadas pra inferir <code>projectSlug</code>. Formato JSON (objeto com <code>rules</code>).</div>
|
|
829
|
+
<div class="stack" style="margin-top:10px">
|
|
830
|
+
<button class="btn" onclick="reloadSlugRules()">Reload rules</button>
|
|
831
|
+
<button class="btn" onclick="saveSlugRules()">Save rules</button>
|
|
832
|
+
<button class="btn" onclick="exportObsidian()">Export Obsidian notes</button>
|
|
833
|
+
</div>
|
|
834
|
+
</div>
|
|
835
|
+
</div>
|
|
836
|
+
|
|
837
|
+
<div class="panel">
|
|
838
|
+
<div class="panelHead"><b>Debug</b></div>
|
|
839
|
+
<div class="panelBody">
|
|
840
|
+
<div class="help">Logs ficam em <code>logs/</code> e debug traces em <code>.debuglogs/</code> dentro da workspace.</div>
|
|
841
|
+
<div class="help">Use <b>Open file</b> / <b>Copy path</b> no Preview para abrir/compartilhar o relatório selecionado.</div>
|
|
842
|
+
</div>
|
|
843
|
+
</div>
|
|
844
|
+
</div>
|
|
845
|
+
</div>
|
|
846
|
+
</details>
|
|
862
847
|
</div>
|
|
863
848
|
</main>
|
|
864
849
|
|
|
850
|
+
<!-- RIGHT: Chat -->
|
|
851
|
+
<aside class="chatPane">
|
|
852
|
+
<div class="chatHead">
|
|
853
|
+
<div>
|
|
854
|
+
<div class="chatTitle">Chat</div>
|
|
855
|
+
<div class="chatSub">Capture updates, then let Agents plan/apply.</div>
|
|
856
|
+
</div>
|
|
857
|
+
</div>
|
|
858
|
+
|
|
859
|
+
<div class="chatThread" id="chatThread">
|
|
860
|
+
<div class="bubble assistant">
|
|
861
|
+
<div class="bubbleMeta">FREYA</div>
|
|
862
|
+
<div class="bubbleBody">Cole seus updates (status, blockers, decisões, ideias) e clique em <b>Save + Process</b>.</div>
|
|
863
|
+
</div>
|
|
864
|
+
</div>
|
|
865
|
+
|
|
866
|
+
<div class="chatComposer">
|
|
867
|
+
<textarea id="inboxText" rows="5" placeholder="Cole aqui updates do dia (status, blockers, decisões, ideias)…"></textarea>
|
|
868
|
+
|
|
869
|
+
<div class="composerActions">
|
|
870
|
+
<button class="btn primary" type="button" onclick="saveAndPlan()">Save + Process (Agents)</button>
|
|
871
|
+
<button class="btn" type="button" onclick="runSuggestedReports()">Run suggested reports</button>
|
|
872
|
+
</div>
|
|
873
|
+
|
|
874
|
+
<div class="composerToggles">
|
|
875
|
+
<label class="toggleRow">
|
|
876
|
+
<input id="autoApply" type="checkbox" checked style="width:auto" onchange="toggleAutoApply()" />
|
|
877
|
+
Auto-apply plan
|
|
878
|
+
</label>
|
|
879
|
+
<label class="toggleRow">
|
|
880
|
+
<input id="autoRunReports" type="checkbox" style="width:auto" onchange="toggleAutoRunReports()" />
|
|
881
|
+
Auto-run suggested reports
|
|
882
|
+
</label>
|
|
883
|
+
</div>
|
|
884
|
+
|
|
885
|
+
<div class="statusFooter">
|
|
886
|
+
<span id="status" class="small">idle</span>
|
|
887
|
+
</div>
|
|
888
|
+
</div>
|
|
889
|
+
</aside>
|
|
890
|
+
|
|
865
891
|
</div>
|
|
866
892
|
</div>
|
|
867
893
|
</div>
|