- brain.ts: BRAIN_ROOT résolu via $BRAIN_ROOT env / ~/.config/brain-path / fallback ~/Dev/Brain - Volume.tsx: bindings volume + mute séparés et réactifs - style.scss: importe _bar.scss et _heartbeat.scss via @use, supprime 199 lignes dupliquées
76 lines
1.9 KiB
TypeScript
76 lines
1.9 KiB
TypeScript
import GLib from "gi://GLib"
|
|
|
|
const BRAIN_ROOT = GLib.getenv("BRAIN_ROOT")
|
|
|| readFile(GLib.get_home_dir() + "/.config/brain-path")?.trim()
|
|
|| GLib.get_home_dir() + "/Dev/Brain"
|
|
|
|
export interface BrainState {
|
|
focus: string
|
|
todos: { open: number; done: number; top3: string[] }
|
|
session: string | null
|
|
}
|
|
|
|
function readFile(path: string): string | null {
|
|
try {
|
|
const [ok, contents] = GLib.file_get_contents(path)
|
|
if (ok && contents) {
|
|
return new TextDecoder().decode(contents)
|
|
}
|
|
} catch {}
|
|
return null
|
|
}
|
|
|
|
export function getFocus(): string {
|
|
const content = readFile(`${BRAIN_ROOT}/focus.md`)
|
|
if (!content) return "no focus"
|
|
// skip header lines, get the meat
|
|
const lines = content.split("\n").filter(
|
|
(l) => !l.startsWith("#") && !l.startsWith(">") && l.trim() !== "" && !l.startsWith("---")
|
|
)
|
|
return lines[0]?.trim() || "no focus"
|
|
}
|
|
|
|
export function getTodos(): { open: number; done: number; top3: string[] } {
|
|
const content = readFile(`${BRAIN_ROOT}/todo/README.md`)
|
|
if (!content) return { open: 0, done: 0, top3: [] }
|
|
|
|
const lines = content.split("\n")
|
|
const open: string[] = []
|
|
let done = 0
|
|
|
|
for (const line of lines) {
|
|
const trimmed = line.trim()
|
|
if (trimmed.startsWith("- [ ]") || trimmed.startsWith("⬜")) {
|
|
open.push(trimmed.replace(/^- \[ \] /, "").replace(/^⬜ ?/, ""))
|
|
} else if (trimmed.startsWith("- [x]") || trimmed.startsWith("✅")) {
|
|
done++
|
|
}
|
|
}
|
|
|
|
return {
|
|
open: open.length,
|
|
done,
|
|
top3: open.slice(0, 3),
|
|
}
|
|
}
|
|
|
|
export function getSession(): string | null {
|
|
try {
|
|
const [ok, contents] = GLib.file_get_contents(
|
|
GLib.get_home_dir() + "/.claude/session-role"
|
|
)
|
|
if (ok && contents) {
|
|
return new TextDecoder().decode(contents).trim()
|
|
}
|
|
} catch {}
|
|
return null
|
|
}
|
|
|
|
export function getBrainState(): BrainState {
|
|
return {
|
|
focus: getFocus(),
|
|
todos: getTodos(),
|
|
session: getSession(),
|
|
}
|
|
}
|