[claude] Add session export as markdown (#288) (#304)
Some checks failed
Deploy Nexus / deploy (push) Has been cancelled
Some checks failed
Deploy Nexus / deploy (push) Has been cancelled
Co-authored-by: Claude (Opus 4.6) <claude@hermes.local> Co-committed-by: Claude (Opus 4.6) <claude@hermes.local>
This commit was merged in pull request #304.
This commit is contained in:
57
app.js
57
app.js
@@ -1223,9 +1223,66 @@ window.addEventListener('player-left', (/** @type {CustomEvent} */ event) => {
|
|||||||
console.log('Player left:', event.detail);
|
console.log('Player left:', event.detail);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// === SESSION EXPORT ===
|
||||||
|
/** @type {{ ts: number, speaker: string, text: string }[]} */
|
||||||
|
const sessionLog = [];
|
||||||
|
const sessionStart = Date.now();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends an entry to the in-memory session log.
|
||||||
|
* @param {string} speaker
|
||||||
|
* @param {string} text
|
||||||
|
*/
|
||||||
|
function logMessage(speaker, text) {
|
||||||
|
sessionLog.push({ ts: Date.now(), speaker, text });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats the session log as Markdown and triggers a browser download.
|
||||||
|
*/
|
||||||
|
function exportSessionAsMarkdown() {
|
||||||
|
const startStr = new Date(sessionStart).toISOString().replace('T', ' ').slice(0, 19) + ' UTC';
|
||||||
|
const lines = [
|
||||||
|
'# Nexus Session Export',
|
||||||
|
'',
|
||||||
|
`**Session started:** ${startStr}`,
|
||||||
|
`**Messages:** ${sessionLog.length}`,
|
||||||
|
'',
|
||||||
|
'---',
|
||||||
|
'',
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const entry of sessionLog) {
|
||||||
|
const timeStr = new Date(entry.ts).toISOString().replace('T', ' ').slice(0, 19) + ' UTC';
|
||||||
|
lines.push(`### ${entry.speaker} — ${timeStr}`);
|
||||||
|
lines.push('');
|
||||||
|
lines.push(entry.text);
|
||||||
|
lines.push('');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sessionLog.length === 0) {
|
||||||
|
lines.push('*No messages recorded this session.*');
|
||||||
|
lines.push('');
|
||||||
|
}
|
||||||
|
|
||||||
|
const blob = new Blob([lines.join('\n')], { type: 'text/markdown' });
|
||||||
|
const url = URL.createObjectURL(blob);
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
a.download = `nexus-session-${new Date(sessionStart).toISOString().slice(0, 10)}.md`;
|
||||||
|
a.click();
|
||||||
|
URL.revokeObjectURL(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
const exportBtn = document.getElementById('export-session');
|
||||||
|
if (exportBtn) {
|
||||||
|
exportBtn.addEventListener('click', exportSessionAsMarkdown);
|
||||||
|
}
|
||||||
|
|
||||||
window.addEventListener('chat-message', (/** @type {CustomEvent} */ event) => {
|
window.addEventListener('chat-message', (/** @type {CustomEvent} */ event) => {
|
||||||
console.log('Chat message:', event.detail);
|
console.log('Chat message:', event.detail);
|
||||||
if (typeof event.detail?.text === 'string') {
|
if (typeof event.detail?.text === 'string') {
|
||||||
|
logMessage(event.detail.speaker || 'TIMMY', event.detail.text);
|
||||||
showTimmySpeech(event.detail.text);
|
showTimmySpeech(event.detail.text);
|
||||||
if (event.detail.text.toLowerCase().includes('sovereignty')) {
|
if (event.detail.text.toLowerCase().includes('sovereignty')) {
|
||||||
triggerSovereigntyEasterEgg();
|
triggerSovereigntyEasterEgg();
|
||||||
|
|||||||
@@ -33,6 +33,9 @@
|
|||||||
<button id="debug-toggle" class="chat-toggle-btn" aria-label="Toggle debug mode" style="background-color: var(--color-secondary); color: var(--color-bg); padding: 4px 8px; border-radius: 4px; font-size: 12px; cursor: pointer;">
|
<button id="debug-toggle" class="chat-toggle-btn" aria-label="Toggle debug mode" style="background-color: var(--color-secondary); color: var(--color-bg); padding: 4px 8px; border-radius: 4px; font-size: 12px; cursor: pointer;">
|
||||||
🔍
|
🔍
|
||||||
</button>
|
</button>
|
||||||
|
<button id="export-session" class="chat-toggle-btn" aria-label="Export session as markdown" title="Export session log as Markdown">
|
||||||
|
📥
|
||||||
|
</button>
|
||||||
<audio id="ambient-sound" src="ambient.mp3" loop></audio>
|
<audio id="ambient-sound" src="ambient.mp3" loop></audio>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
19
style.css
19
style.css
@@ -61,6 +61,25 @@ canvas {
|
|||||||
margin-left: 8px;
|
margin-left: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* === SESSION EXPORT === */
|
||||||
|
#export-session {
|
||||||
|
margin-left: 8px;
|
||||||
|
background-color: var(--color-secondary);
|
||||||
|
color: var(--color-text);
|
||||||
|
padding: 4px 8px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-family: var(--font-body);
|
||||||
|
transition: background-color 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
#export-session:hover {
|
||||||
|
background-color: var(--color-primary);
|
||||||
|
color: var(--color-bg);
|
||||||
|
}
|
||||||
|
|
||||||
.collision-box {
|
.collision-box {
|
||||||
outline: 2px solid red;
|
outline: 2px solid red;
|
||||||
outline-offset: 2px;
|
outline-offset: 2px;
|
||||||
|
|||||||
Reference in New Issue
Block a user