- Scaling 16px base pour ultrawide 3440x1440 - Bar: CPU/RAM/GPU visible, media single player (skip playerctld), network tooltip LAN/WAN IPv4 - Volume: class module pour sizing cohérent - Battery: désactivé (PC fixe) - Clock: tooltip calendrier + uptime - BrainPower: panel enrichi (focus, session, intentions, todos, repos git, derniers commits) - App: BrainPower sur moniteur principal uniquement - Heartbeat: Layer.TOP pour compatibilité COSMIC
123 lines
3.5 KiB
TypeScript
123 lines
3.5 KiB
TypeScript
import GLib from "gi://GLib"
|
|
import { exec } from "ags/process"
|
|
|
|
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
|
|
intentions: { active: number; names: string[] }
|
|
repos: { name: string; status: string }[]
|
|
commits: string[]
|
|
kernelVersion: string
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
function sh(cmd: string): string {
|
|
try { return exec(`bash -c "${cmd}"`).trim() } catch { return "" }
|
|
}
|
|
|
|
export function getFocus(): string {
|
|
const content = readFile(`${BRAIN_ROOT}/focus.md`)
|
|
if (!content) return "no focus"
|
|
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 getIntentions(): { active: number; names: string[] } {
|
|
try {
|
|
const out = sh(`grep -rl 'status: active' ${BRAIN_ROOT}/intentions/*.yml 2>/dev/null | while read f; do grep '^name:' "$f" | head -1 | sed 's/name: //'; done`)
|
|
const names = out.split("\n").filter(Boolean)
|
|
return { active: names.length, names: names.slice(0, 5) }
|
|
} catch {
|
|
return { active: 0, names: [] }
|
|
}
|
|
}
|
|
|
|
export function getRepoStatus(): { name: string; status: string }[] {
|
|
const repos = [
|
|
{ name: "brain", path: BRAIN_ROOT },
|
|
{ name: "toolkit", path: `${BRAIN_ROOT}/toolkit` },
|
|
{ name: "progression", path: `${BRAIN_ROOT}/progression` },
|
|
]
|
|
|
|
return repos.map(({ name, path }) => {
|
|
const count = sh(`git -C ${path} status --short 2>/dev/null | wc -l`)
|
|
const n = parseInt(count) || 0
|
|
return {
|
|
name,
|
|
status: n === 0 ? "✅" : `⚠️ ${n} fichiers`,
|
|
}
|
|
})
|
|
}
|
|
|
|
export function getRecentCommits(): string[] {
|
|
const out = sh(`git -C ${BRAIN_ROOT} log --oneline -5 2>/dev/null`)
|
|
return out.split("\n").filter(Boolean)
|
|
}
|
|
|
|
export function getKernelVersion(): string {
|
|
const content = readFile(`${BRAIN_ROOT}/brain-compose.yml`)
|
|
if (!content) return "?"
|
|
const match = content.match(/^version:\s*"?([^"\n]+)"?/m)
|
|
return match ? match[1] : "?"
|
|
}
|
|
|
|
export function getBrainState(): BrainState {
|
|
return {
|
|
focus: getFocus(),
|
|
todos: getTodos(),
|
|
session: getSession(),
|
|
intentions: getIntentions(),
|
|
repos: getRepoStatus(),
|
|
commits: getRecentCommits(),
|
|
kernelVersion: getKernelVersion(),
|
|
}
|
|
}
|