@cccarv82/freya 2.11.0 → 2.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cli/web-ui.js CHANGED
@@ -237,6 +237,7 @@
237
237
  thread.appendChild(bubble);
238
238
  }
239
239
  try { thread.scrollTop = thread.scrollHeight; } catch { }
240
+ syncChatThreadVisibility();
240
241
  }
241
242
  } catch {
242
243
  // ignore
@@ -330,6 +331,16 @@
330
331
  }
331
332
  }
332
333
 
334
+ // Show/hide the chat thread area based on whether it has content
335
+ function syncChatThreadVisibility() {
336
+ const thread = $('chatThread');
337
+ if (!thread) return;
338
+ const hasContent = thread.children.length > 0;
339
+ thread.style.padding = hasContent ? '12px' : '0';
340
+ thread.style.maxHeight = hasContent ? '280px' : '0';
341
+ thread.style.borderTop = hasContent ? '1px solid var(--border)' : 'none';
342
+ }
343
+
333
344
  // Unified input → Oracle (RAG): reads from the main inboxText textarea
334
345
  async function askFreyaFromInput() {
335
346
  const ta = $('inboxText');
@@ -342,11 +353,12 @@
342
353
 
343
354
  if (ta) ta.value = '';
344
355
 
345
- // Update mode tag
356
+ // Show mode tag
346
357
  const tag = $('chatModeTag');
347
- if (tag) { tag.textContent = 'oracle'; tag.style.color = 'var(--accent)'; tag.style.borderColor = 'var(--accent)'; }
358
+ if (tag) { tag.textContent = '🔍 oracle'; tag.style.display = ''; tag.style.color = 'var(--accent)'; tag.style.borderColor = 'var(--accent)'; }
348
359
 
349
360
  chatAppend('user', query);
361
+ syncChatThreadVisibility();
350
362
  setPill('run', 'pesquisando…');
351
363
 
352
364
  const typingId = 'typing-' + Date.now();
@@ -362,12 +374,13 @@
362
374
 
363
375
  chatAppend('assistant', answer, { markdown: true });
364
376
  setPill('ok', 'pronto');
365
- if (tag) setTimeout(() => { tag.textContent = 'oracle'; tag.style.color = ''; tag.style.borderColor = ''; }, 2000);
377
+ if (tag) setTimeout(() => { tag.style.display = 'none'; }, 3000);
366
378
  } catch (e) {
367
379
  const el = $(typingId);
368
380
  if (el) el.remove();
369
381
  setPill('err', 'falhou');
370
382
  chatAppend('assistant', '❌ ' + String(e && e.message ? e.message : e));
383
+ if (tag) setTimeout(() => { tag.style.display = 'none'; }, 3000);
371
384
  }
372
385
  }
373
386
 
@@ -2223,11 +2236,12 @@
2223
2236
  return;
2224
2237
  }
2225
2238
 
2226
- // Update mode tag
2239
+ // Show mode tag
2227
2240
  const tag = $('chatModeTag');
2228
- if (tag) { tag.textContent = 'inbox'; tag.style.color = 'var(--primary)'; tag.style.borderColor = 'var(--primary)'; }
2241
+ if (tag) { tag.textContent = '📥 inbox'; tag.style.display = ''; tag.style.color = 'var(--primary)'; tag.style.borderColor = 'var(--primary)'; }
2229
2242
 
2230
2243
  chatAppend('user', text);
2244
+ syncChatThreadVisibility();
2231
2245
 
2232
2246
  setPill('run', 'salvando…');
2233
2247
  await api('/api/inbox/add', { dir: dirOrDefault(), text });
@@ -2263,7 +2277,7 @@
2263
2277
  }
2264
2278
 
2265
2279
  const tag2 = $('chatModeTag');
2266
- if (tag2) setTimeout(() => { tag2.textContent = 'oracle'; tag2.style.color = ''; tag2.style.borderColor = ''; }, 1500);
2280
+ if (tag2) setTimeout(() => { tag2.style.display = 'none'; }, 2000);
2267
2281
  setTimeout(() => setPill('ok', 'pronto'), 1200);
2268
2282
  } catch (e) {
2269
2283
  setPill('err', 'falhou');
package/cli/web.js CHANGED
@@ -1207,36 +1207,37 @@ function buildHtml(safeDefault, appVersion) {
1207
1207
  </div>
1208
1208
 
1209
1209
  <div class="centerBody">
1210
- <!-- Unified Input + Chat Panel -->
1211
- <section style="margin-bottom: 24px; display: grid; grid-template-columns: 1fr 1.6fr; gap: 16px; height: 420px; max-height: 480px;">
1212
-
1213
- <!-- Left: Unified Input -->
1214
- <div class="promptBar" style="width: 100%; border-radius: 20px; height: 100%; display: flex; flex-direction: column; overflow: hidden;">
1215
- <div class="promptMeta" style="flex-shrink:0;">
1216
- <div class="promptTitle" style="display: flex; align-items: center; gap: 8px;">
1217
- <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="color: var(--primary)"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="17 8 12 3 7 8"></polyline><line x1="12" y1="3" x2="12" y2="15"></line></svg>
1218
- <span>Freya Input</span>
1219
- </div>
1210
+ <!-- Unified Input Panel -->
1211
+ <div class="promptBar" style="margin-bottom: 24px; border-radius: 16px; display: flex; flex-direction: column; overflow: hidden;">
1212
+ <!-- Header -->
1213
+ <div class="promptMeta" style="flex-shrink:0;">
1214
+ <div class="promptTitle" style="display: flex; align-items: center; gap: 8px;">
1215
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="color: var(--primary)"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="17 8 12 3 7 8"></polyline><line x1="12" y1="3" x2="12" y2="15"></line></svg>
1216
+ <span>Freya Input</span>
1217
+ </div>
1218
+ <div style="display:flex; align-items:center; gap:8px;">
1219
+ <span id="chatModeTag" style="font-size:11px; padding:2px 8px; border-radius:10px; background:var(--bg2); color:var(--muted); border:1px solid var(--border); display:none;"></span>
1220
1220
  <div id="status" class="small">pronto</div>
1221
1221
  </div>
1222
+ </div>
1222
1223
 
1223
- <textarea id="inboxText" placeholder="Cole updates, decisões, blockers... ou faça uma pergunta à Freya.&#10;&#10;▸ Salvar & Processar → extrai tarefas e blockers&#10;▸ Perguntar → consulta o histórico (RAG)" style="resize:none; flex: 1; min-height: 0; border-radius: 0; border-left: none; border-right: none; border-top: none; border-bottom: 1px solid var(--border); padding: 14px 16px; font-size: 13px; line-height: 1.6;"
1224
- onkeydown="if((event.metaKey||event.ctrlKey)&&event.key==='Enter'){event.preventDefault();window.saveAndPlan();}"></textarea>
1224
+ <!-- Textarea -->
1225
+ <textarea id="inboxText" placeholder="Cole updates, decisões, blockers... ou faça uma pergunta à Freya.&#10;&#10;▸ Salvar & Processar → extrai tarefas e blockers do texto&#10;▸ Perguntar → consulta o histórico via busca semântica (RAG)" style="resize:none; min-height: 120px; border-radius: 0; border-left: none; border-right: none; border-top: none; border-bottom: 1px solid var(--border); padding: 14px 16px; font-size: 13px; line-height: 1.6;"
1226
+ onkeydown="if((event.metaKey||event.ctrlKey)&&event.key==='Enter'){event.preventDefault();window.saveAndPlan();}"></textarea>
1225
1227
 
1226
- <!-- Primary actions -->
1227
- <div style="padding: 10px 14px 6px; display: flex; gap: 8px; flex-wrap: wrap; flex-shrink:0;">
1228
- <button class="btn primary small" type="button" onclick="saveAndPlan()" style="flex:1; min-width: 120px;" title="Ctrl+Enter">
1228
+ <!-- Actions bar -->
1229
+ <div style="padding: 10px 14px; display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 8px; flex-shrink:0;">
1230
+ <div style="display:flex; gap:8px; flex-wrap:wrap;">
1231
+ <button class="btn primary small" type="button" onclick="saveAndPlan()" title="Ctrl+Enter">
1229
1232
  <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" style="display:inline;vertical-align:-2px;margin-right:5px"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="17 8 12 3 7 8"></polyline><line x1="12" y1="3" x2="12" y2="15"></line></svg>
1230
- Salvar & Processar
1233
+ Salvar &amp; Processar
1231
1234
  </button>
1232
- <button class="btn small" type="button" onclick="window.askFreyaFromInput()" style="flex:1; min-width: 90px;" title="Consulta semântica ao histórico">
1235
+ <button class="btn small" type="button" onclick="window.askFreyaFromInput()" title="Consulta semântica ao histórico">
1233
1236
  <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="display:inline;vertical-align:-2px;margin-right:5px"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>
1234
1237
  Perguntar
1235
1238
  </button>
1236
1239
  </div>
1237
-
1238
- <!-- Toggles + secondary -->
1239
- <div style="padding: 0 14px 12px; display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 8px; flex-shrink:0;">
1240
+ <div style="display:flex; align-items:center; gap:10px; flex-wrap:wrap;">
1240
1241
  <div class="promptToggles" style="margin:0;">
1241
1242
  <label class="toggleRow" title="Aplica o plano automaticamente após processar">
1242
1243
  <input id="autoApply" type="checkbox" checked style="width:auto; margin: 0;" onchange="toggleAutoApply()" />
@@ -1254,25 +1255,14 @@ function buildHtml(safeDefault, appVersion) {
1254
1255
  </div>
1255
1256
  </div>
1256
1257
 
1257
- <!-- Right: Unified Chat Thread (Oracle responses + Plan outputs) -->
1258
- <div class="panel" style="height: 100%; display: flex; flex-direction: column;">
1259
- <div class="panelHead" style="flex-shrink:0;">
1260
- <b style="display: flex; align-items: center; gap: 8px; font-size:13px;">
1261
- <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="color:var(--accent)"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path></svg>
1262
- Conversa com a Freya
1263
- </b>
1264
- <div class="stack">
1265
- <span id="chatModeTag" style="font-size:11px; padding:2px 8px; border-radius:10px; background:var(--bg2); color:var(--muted); border:1px solid var(--border);">oracle</span>
1266
- </div>
1267
- </div>
1268
- <div id="chatThread" style="flex:1; overflow-y:auto; overflow-x:hidden; padding:12px; display:flex; flex-direction:column; gap:8px; min-height:0;"></div>
1269
- </div>
1270
- </section>
1258
+ <!-- Chat thread: responses appear here after actions -->
1259
+ <div id="chatThread" style="max-height: 280px; overflow-y:auto; overflow-x:hidden; padding:0 12px; display:flex; flex-direction:column; gap:8px; border-top: 1px solid var(--border);"></div>
1260
+ </div>
1271
1261
 
1272
1262
  <div class="centerHead">
1273
1263
  <div>
1274
1264
  <h1 style="margin:0">Seu dia em um painel</h1>
1275
- <div class="subtitle">Use o campo acima para capturar updates (<b>Salvar &amp; Processar</b>) ou consultar o histórico (<b>Perguntar</b>). As respostas aparecem no chat ao lado.</div>
1265
+ <div class="subtitle">Use o campo acima para capturar updates do dia (<b>Salvar &amp; Processar</b>) ou consultar o histórico (<b>Perguntar</b>). As respostas aparecem logo abaixo do input.</div>
1276
1266
  </div>
1277
1267
  <div class="statusLine">
1278
1268
  <span class="small" id="last"></span>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cccarv82/freya",
3
- "version": "2.11.0",
3
+ "version": "2.12.0",
4
4
  "description": "Personal AI Assistant with local-first persistence",
5
5
  "scripts": {
6
6
  "health": "node scripts/validate-data.js && node scripts/validate-structure.js",
@@ -40,8 +40,13 @@ function getDateRange(period) {
40
40
  return { start, end };
41
41
  }
42
42
 
43
+ // Use local date parts (not UTC) to stay consistent with getDailyLogs / daily_logs.date
43
44
  function formatDate(date) {
44
- return toIsoDate(date);
45
+ const d = date instanceof Date ? date : new Date(date);
46
+ const yyyy = d.getFullYear();
47
+ const mm = String(d.getMonth() + 1).padStart(2, '0');
48
+ const dd = String(d.getDate()).padStart(2, '0');
49
+ return `${yyyy}-${mm}-${dd}`;
45
50
  }
46
51
 
47
52
  function ensureDir(dir) {