feat: Ghost Shell v2 — AGS v3 statusbar + violet-chaton v2 palette

- AGS v3.1.0 (Astal/GTK3) Ghost Shell avec ghost mode (heartbeat + hover reveal)
- Modules : clock, battery, volume (interactif), network, MPRIS, CPU/RAM, systray
- Brain Power panel (Super + B) — lecture live focus/todos/session
- tetardtek_ prompt avec curseur clignotant
- Palette violet-chaton v2 documentée (Mitsuri Kanroji gradient magenta → green)
- Autostart COSMIC via .desktop
- Archive AGS v1 conservée pour référence
This commit is contained in:
Tetardtek-Cortex
2026-03-26 06:54:17 +01:00
parent 7e9d12e640
commit 932b174c36
30 changed files with 2557 additions and 0 deletions

73
ags-v3/lib/brain.ts Normal file
View File

@@ -0,0 +1,73 @@
import GLib from "gi://GLib"
const BRAIN_ROOT = "/home/tetardtek/Dev/Cortex-Template"
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(),
}
}