agentgui 1.0.767 → 1.0.769
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/static/app.js +76 -0
- package/static/css/main.css +6 -0
- package/static/index.html +6 -4
package/package.json
CHANGED
package/static/app.js
CHANGED
|
@@ -827,4 +827,80 @@ document.addEventListener('keydown', (e) => {
|
|
|
827
827
|
window.showErrorToast = showErrorToast;
|
|
828
828
|
})();
|
|
829
829
|
|
|
830
|
+
(function initImportButton() {
|
|
831
|
+
const btn = document.getElementById('importConversationBtn');
|
|
832
|
+
if (!btn) return;
|
|
833
|
+
btn.addEventListener('click', () => {
|
|
834
|
+
const input = document.createElement('input');
|
|
835
|
+
input.type = 'file';
|
|
836
|
+
input.accept = '.json';
|
|
837
|
+
input.addEventListener('change', async () => {
|
|
838
|
+
if (!input.files[0]) return;
|
|
839
|
+
try {
|
|
840
|
+
const text = await input.files[0].text();
|
|
841
|
+
const data = JSON.parse(text);
|
|
842
|
+
if (!data.conversation || !data.messages) {
|
|
843
|
+
window.showErrorToast('Import Failed', 'Invalid format. Export a conversation as JSON first.');
|
|
844
|
+
return;
|
|
845
|
+
}
|
|
846
|
+
await window.wsClient.rpc('conv.import', data);
|
|
847
|
+
} catch (e) {
|
|
848
|
+
window.showErrorToast('Import Failed', e.message);
|
|
849
|
+
}
|
|
850
|
+
});
|
|
851
|
+
input.click();
|
|
852
|
+
});
|
|
853
|
+
})();
|
|
854
|
+
|
|
855
|
+
(function initArchivedView() {
|
|
856
|
+
const btn = document.getElementById('viewArchivedBtn');
|
|
857
|
+
if (!btn) return;
|
|
858
|
+
let showing = false;
|
|
859
|
+
btn.addEventListener('click', async () => {
|
|
860
|
+
const list = document.querySelector('[data-conversation-list]');
|
|
861
|
+
if (!list) return;
|
|
862
|
+
if (showing) {
|
|
863
|
+
showing = false;
|
|
864
|
+
btn.textContent = 'Archived';
|
|
865
|
+
if (window.conversationManager) window.conversationManager.render();
|
|
866
|
+
return;
|
|
867
|
+
}
|
|
868
|
+
try {
|
|
869
|
+
const base = window.__BASE_URL || '';
|
|
870
|
+
const resp = await fetch(`${base}/api/conversations/archived`);
|
|
871
|
+
const { conversations } = await resp.json();
|
|
872
|
+
if (!conversations || conversations.length === 0) {
|
|
873
|
+
window.UIDialog?.alert('No archived conversations', 'Archived');
|
|
874
|
+
return;
|
|
875
|
+
}
|
|
876
|
+
showing = true;
|
|
877
|
+
btn.textContent = 'Back';
|
|
878
|
+
list.innerHTML = conversations.map(c => `
|
|
879
|
+
<li class="conversation-item" style="cursor:default;">
|
|
880
|
+
<div class="conversation-item-content">
|
|
881
|
+
<div class="conversation-item-title">${window._escHtml(c.title || 'Untitled')}</div>
|
|
882
|
+
<div class="conversation-item-meta">${new Date(c.created_at).toLocaleDateString()}</div>
|
|
883
|
+
</div>
|
|
884
|
+
<button class="conversation-item-archive" title="Restore" data-restore-conv="${c.id}" style="opacity:1;">
|
|
885
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
886
|
+
<polyline points="1 4 1 10 7 10"></polyline>
|
|
887
|
+
<path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"></path>
|
|
888
|
+
</svg>
|
|
889
|
+
</button>
|
|
890
|
+
</li>
|
|
891
|
+
`).join('');
|
|
892
|
+
list.addEventListener('click', async (e) => {
|
|
893
|
+
const restoreBtn = e.target.closest('[data-restore-conv]');
|
|
894
|
+
if (!restoreBtn) return;
|
|
895
|
+
const id = restoreBtn.dataset.restoreConv;
|
|
896
|
+
await fetch(`${base}/api/conversations/${id}/restore`, { method: 'POST' });
|
|
897
|
+
restoreBtn.closest('li').remove();
|
|
898
|
+
if (!list.querySelector('li')) { showing = false; btn.textContent = 'Archived'; if (window.conversationManager) window.conversationManager.render(); }
|
|
899
|
+
}, { once: false });
|
|
900
|
+
} catch (e) {
|
|
901
|
+
window.showErrorToast('Load Failed', e.message);
|
|
902
|
+
}
|
|
903
|
+
});
|
|
904
|
+
})();
|
|
905
|
+
|
|
830
906
|
window.addEventListener('load', initializeApp);
|
package/static/css/main.css
CHANGED
|
@@ -1156,6 +1156,12 @@
|
|
|
1156
1156
|
.message { max-width: 95%; }
|
|
1157
1157
|
.messages-wrapper { padding: 0.375rem 0.5rem; }
|
|
1158
1158
|
.input-section { padding: 0.5rem; padding-bottom: calc(0.5rem + env(safe-area-inset-bottom)); }
|
|
1159
|
+
.sidebar-header-actions { gap: 0.25rem; }
|
|
1160
|
+
.sidebar-clone-btn { font-size: 0.7rem; padding: 0.25rem 0.375rem; }
|
|
1161
|
+
.conversation-item-export,
|
|
1162
|
+
.conversation-item-archive { display: none; }
|
|
1163
|
+
.conversation-header h2 { font-size: 1.125rem; }
|
|
1164
|
+
.shortcuts-panel { padding: 1rem; }
|
|
1159
1165
|
}
|
|
1160
1166
|
|
|
1161
1167
|
/* ===== SCROLLBAR STYLING ===== */
|
package/static/index.html
CHANGED
|
@@ -30,24 +30,26 @@
|
|
|
30
30
|
|
|
31
31
|
<div class="app-shell">
|
|
32
32
|
<!-- ===== SIDEBAR ===== -->
|
|
33
|
-
<aside class="sidebar" data-sidebar>
|
|
33
|
+
<aside class="sidebar" data-sidebar role="navigation" aria-label="Conversation history">
|
|
34
34
|
<div class="sidebar-header">
|
|
35
35
|
<h2>History</h2>
|
|
36
36
|
<div class="sidebar-header-actions">
|
|
37
|
+
<button id="importConversationBtn" class="sidebar-clone-btn" title="Import conversation from JSON">Import</button>
|
|
38
|
+
<button id="viewArchivedBtn" class="sidebar-clone-btn" title="View archived conversations">Archived</button>
|
|
37
39
|
<button id="deleteAllConversationsBtn" class="sidebar-clone-btn" data-delete-all-conversations title="Delete all conversations and Claude Code artifacts">Clear All</button>
|
|
38
40
|
<button id="cloneRepoBtn" class="sidebar-clone-btn" data-clone-repo title="Clone a GitHub repo">Clone</button>
|
|
39
41
|
<button id="newConversationBtn" class="sidebar-new-btn" data-new-conversation title="Start new conversation">+ New</button>
|
|
40
42
|
</div>
|
|
41
43
|
</div>
|
|
42
44
|
<div class="sidebar-search-bar" id="sidebarSearchBar">
|
|
43
|
-
<input type="text" class="sidebar-search-input" id="sidebarSearchInput" placeholder="Search conversations..." autocomplete="off" spellcheck="false">
|
|
45
|
+
<input type="text" class="sidebar-search-input" id="sidebarSearchInput" placeholder="Search conversations..." autocomplete="off" spellcheck="false" aria-label="Search conversations">
|
|
44
46
|
</div>
|
|
45
47
|
<div class="clone-input-bar" id="cloneInputBar" style="display:none;">
|
|
46
48
|
<input type="text" class="clone-input" id="cloneRepoInput" placeholder="org/repo" autocomplete="off" spellcheck="false">
|
|
47
49
|
<button class="clone-go-btn" id="cloneGoBtn" title="Clone">Go</button>
|
|
48
50
|
<button class="clone-cancel-btn" id="cloneCancelBtn" title="Cancel">×</button>
|
|
49
51
|
</div>
|
|
50
|
-
<ul class="sidebar-list" data-conversation-list>
|
|
52
|
+
<ul class="sidebar-list" data-conversation-list role="listbox" aria-label="Conversations">
|
|
51
53
|
<li class="sidebar-empty" data-conversation-empty>Loading...</li>
|
|
52
54
|
</ul>
|
|
53
55
|
<!-- PM2 Monitor Panel: hidden until active processes detected -->
|
|
@@ -63,7 +65,7 @@
|
|
|
63
65
|
</aside>
|
|
64
66
|
|
|
65
67
|
<!-- ===== MAIN PANEL ===== -->
|
|
66
|
-
<main id="app" class="main-panel">
|
|
68
|
+
<main id="app" class="main-panel" role="main" aria-label="Conversation">
|
|
67
69
|
<!-- Header bar -->
|
|
68
70
|
<div class="main-header">
|
|
69
71
|
<button class="sidebar-toggle-btn" data-sidebar-toggle title="Toggle sidebar (Ctrl+B)" aria-label="Toggle sidebar">
|