agentacta 1.1.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/public/app.js +61 -12
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentacta",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "Audit trail and search engine for AI agent sessions",
5
5
  "main": "index.js",
6
6
  "bin": {
package/public/app.js CHANGED
@@ -218,7 +218,11 @@ async function showSearchHome() {
218
218
  });
219
219
 
220
220
  $$('.session-item', el).forEach(item => {
221
- item.addEventListener('click', () => viewSession(item.dataset.id));
221
+ item.addEventListener('click', () => {
222
+ window._lastView = 'search';
223
+ window._lastSearchQuery = $('#searchInput')?.value || '';
224
+ viewSession(item.dataset.id);
225
+ });
222
226
  });
223
227
  }
224
228
 
@@ -260,11 +264,16 @@ async function doSearch(q) {
260
264
  `).join('');
261
265
 
262
266
  $$('.session-link', el).forEach(link => {
263
- link.addEventListener('click', () => viewSession(link.dataset.session));
267
+ link.addEventListener('click', () => {
268
+ window._lastView = 'search';
269
+ window._lastSearchQuery = q;
270
+ viewSession(link.dataset.session);
271
+ });
264
272
  });
265
273
  }
266
274
 
267
275
  async function viewSessions() {
276
+ window._currentSessionId = null;
268
277
  content.innerHTML = '<div class="loading">Loading…</div>';
269
278
  const data = await api('/sessions?limit=200');
270
279
 
@@ -278,6 +287,7 @@ async function viewSessions() {
278
287
  }
279
288
 
280
289
  async function viewSession(id) {
290
+ window._currentSessionId = id;
281
291
  content.innerHTML = '<div class="loading">Loading…</div>';
282
292
  const data = await api(`/sessions/${id}`);
283
293
 
@@ -287,14 +297,12 @@ async function viewSession(id) {
287
297
  const cost = fmtCost(s.total_cost);
288
298
  let html = `
289
299
  <div class="back-btn" id="backBtn">← Back</div>
290
- <div style="display:flex;justify-content:space-between;align-items:center">
291
- <div class="page-title">Session</div>
292
- <div style="display:flex;gap:8px;align-items:center">
293
- ${s.first_message_id ? `<button class="jump-to-start-btn" id="jumpToStartBtn" title="Jump to initial prompt">↗️ Initial Prompt</button>` : ''}
294
- ${data.hasArchive ? `<a class="export-btn" href="#" onclick="dlExport('/api/archive/export/${id}','session.jsonl');return false">📦 JSONL</a>` : ''}
295
- <a class="export-btn" href="#" onclick="dlExport('/api/export/session/${id}?format=md','session.md');return false">📄 MD</a>
296
- <a class="export-btn" href="#" onclick="dlExport('/api/export/session/${id}?format=json','session.json');return false">📋 JSON</a>
297
- </div>
300
+ <div class="page-title">Session</div>
301
+ <div style="display:flex;gap:6px;align-items:center;flex-wrap:wrap;margin-bottom:8px">
302
+ ${s.first_message_id ? `<button class="jump-to-start-btn" id="jumpToStartBtn" title="Jump to initial prompt">↗️ Initial Prompt</button>` : ''}
303
+ ${data.hasArchive ? `<a class="export-btn" href="#" onclick="dlExport('/api/archive/export/${id}','session.jsonl');return false">📦 JSONL</a>` : ''}
304
+ <a class="export-btn" href="#" onclick="dlExport('/api/export/session/${id}?format=md','session.md');return false">📄 MD</a>
305
+ <a class="export-btn" href="#" onclick="dlExport('/api/export/session/${id}?format=json','session.json');return false">📋 JSON</a>
298
306
  </div>
299
307
  <div class="session-item" style="cursor:default">
300
308
  <div class="session-header">
@@ -320,6 +328,7 @@ async function viewSession(id) {
320
328
  $('#backBtn').addEventListener('click', () => {
321
329
  if (window._lastView === 'timeline') viewTimeline();
322
330
  else if (window._lastView === 'files') viewFiles();
331
+ else if (window._lastView === 'search') viewSearch(window._lastSearchQuery || '');
323
332
  else viewSessions();
324
333
  });
325
334
 
@@ -613,6 +622,40 @@ $$('.nav-item').forEach(item => {
613
622
 
614
623
  viewSearch();
615
624
 
625
+ // Swipe right from left edge to go back
626
+ (function initSwipeBack() {
627
+ let startX = 0, startY = 0, swiping = false;
628
+ const edgeWidth = 30; // px from left edge
629
+ const threshold = 80;
630
+
631
+ document.addEventListener('touchstart', e => {
632
+ const x = e.touches[0].clientX;
633
+ if (x <= edgeWidth) {
634
+ startX = x;
635
+ startY = e.touches[0].clientY;
636
+ swiping = true;
637
+ }
638
+ }, { passive: true });
639
+
640
+ document.addEventListener('touchmove', e => {
641
+ if (!swiping) return;
642
+ const dx = e.touches[0].clientX - startX;
643
+ const dy = Math.abs(e.touches[0].clientY - startY);
644
+ // Cancel if vertical movement exceeds horizontal (it's a scroll)
645
+ if (dy > dx) { swiping = false; }
646
+ }, { passive: true });
647
+
648
+ document.addEventListener('touchend', e => {
649
+ if (!swiping) return;
650
+ swiping = false;
651
+ const dx = e.changedTouches[0].clientX - startX;
652
+ if (dx > threshold) {
653
+ const backBtn = $('#backBtn');
654
+ if (backBtn) backBtn.click();
655
+ }
656
+ });
657
+ })();
658
+
616
659
  // Pull to refresh
617
660
  (function initPTR() {
618
661
  let startY = 0;
@@ -652,8 +695,14 @@ viewSearch();
652
695
  indicator.classList.add('refreshing');
653
696
  try {
654
697
  await api('/reindex');
655
- const active = $('.nav-item.active');
656
- if (active) active.click();
698
+ // If viewing a session detail, refresh it in place
699
+ const backBtn = $('#backBtn');
700
+ if (backBtn && window._currentSessionId) {
701
+ await viewSession(window._currentSessionId);
702
+ } else {
703
+ const active = $('.nav-item.active');
704
+ if (active) active.click();
705
+ }
657
706
  } catch(err) {}
658
707
  setTimeout(() => {
659
708
  indicator.classList.remove('visible', 'refreshing');