⚗ writing telemetry
This commit is contained in:
@@ -47,6 +47,18 @@ export interface RevisionMeta {
|
||||
wordCount: number
|
||||
}
|
||||
|
||||
export interface TelemetrySession {
|
||||
id: string
|
||||
storyId: string
|
||||
date: string // YYYY-MM-DD local date
|
||||
startedAt: number // ms timestamp
|
||||
endedAt: number // ms timestamp
|
||||
wordsStart: number
|
||||
wordsEnd: number
|
||||
activeMs: number // typing time, excluding idle gaps
|
||||
wpm: number
|
||||
}
|
||||
|
||||
// ─── Path helpers ─────────────────────────────────────────────────────────────
|
||||
|
||||
const borgesDir = (): string => join(getCollectionRoot(), '.borges')
|
||||
@@ -56,6 +68,7 @@ const sessionFile = (): string => join(borgesDir(), 'session.json')
|
||||
const marketsFile = (): string => join(borgesDir(), 'markets.json')
|
||||
const submissionsFile = (): string => join(borgesDir(), 'submissions.json')
|
||||
const revisionsDir = (): string => join(borgesDir(), 'revisions')
|
||||
const telemetryFile = (): string => join(borgesDir(), 'telemetry.json')
|
||||
|
||||
const MAX_REVISIONS = 50
|
||||
|
||||
@@ -320,3 +333,23 @@ export async function loadRevision(filePath: string, revisionId: string): Promis
|
||||
const raw = JSON.parse(await readFile(revPath, 'utf-8'))
|
||||
return raw.content
|
||||
}
|
||||
|
||||
// ─── Telemetry ────────────────────────────────────────────────────────────────
|
||||
|
||||
export async function appendTelemetrySession(session: TelemetrySession): Promise<void> {
|
||||
await mkdir(borgesDir(), { recursive: true })
|
||||
let sessions: TelemetrySession[] = []
|
||||
try {
|
||||
sessions = JSON.parse(await readFile(telemetryFile(), 'utf-8'))
|
||||
} catch { /* first write */ }
|
||||
sessions.push(session)
|
||||
await writeFile(telemetryFile(), JSON.stringify(sessions, null, 2), 'utf-8')
|
||||
}
|
||||
|
||||
export async function readTelemetry(): Promise<TelemetrySession[]> {
|
||||
try {
|
||||
return JSON.parse(await readFile(telemetryFile(), 'utf-8'))
|
||||
} catch {
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,9 +5,10 @@ import {
|
||||
saveOrderList, readSession, writeSession,
|
||||
listMarkets, upsertMarket, deleteMarket,
|
||||
listSubmissions, addSubmission, updateSubmission,
|
||||
saveRevision, listRevisions, loadRevision
|
||||
saveRevision, listRevisions, loadRevision,
|
||||
appendTelemetrySession, readTelemetry
|
||||
} from './fileSystem'
|
||||
import type { Market, Submission, StoryMeta } from './fileSystem'
|
||||
import type { Market, Submission, StoryMeta, TelemetrySession } from './fileSystem'
|
||||
import { streamMessage, streamPrompt, resetClient } from './aiService'
|
||||
import type { AIPayload } from './aiService'
|
||||
import { readGlobalConfig, writeGlobalConfig } from './globalConfig'
|
||||
@@ -48,6 +49,10 @@ export function registerIpcHandlers(): void {
|
||||
ipcMain.handle('revisions:list', async (_e, path: string) => listRevisions(path))
|
||||
ipcMain.handle('revisions:load', async (_e, path: string, id: string) => loadRevision(path, id))
|
||||
|
||||
// ── Telemetry ─────────────────────────────────────────────────────────────────
|
||||
ipcMain.handle('telemetry:append', async (_e, session: TelemetrySession) => appendTelemetrySession(session))
|
||||
ipcMain.handle('telemetry:read', async () => readTelemetry())
|
||||
|
||||
// ── Config ────────────────────────────────────────────────────────────────────
|
||||
ipcMain.handle('config:read', async () => readGlobalConfig())
|
||||
ipcMain.handle('config:write', async (_e, updates: Partial<GlobalConfig>) => {
|
||||
|
||||
Reference in New Issue
Block a user