dashboard.ts: move task file to project-local .pi/dashboard/tasks/todo.txt (per-project, matches pi session organization)

This commit is contained in:
2026-08-02 09:31:46 +10:00
parent 06b2773a00
commit 0603c29216

View File

@@ -25,15 +25,21 @@ import { cwd } from "node:process";
// ── Constants ─────────────────────────────────────────────────────
const DASHBOARD_DIR = join(
process.env.HOME || process.env.XDG_DATA_HOME || "/home/sam",
".pi",
"agent",
"dashboard"
);
const HOME = process.env.HOME || process.env.XDG_DATA_HOME || "/home/sam";
const TASKS_DIR = join(DASHBOARD_DIR, "tasks");
const TODO_FILE = join(TASKS_DIR, "todo.txt");
// Global state files: pi-dashboard viewer reads these across all machines
const DASHBOARD_DIR = join(HOME, ".pi", "agent", "dashboard");
// Project-local task file: lives in the pi project's .pi/ directory
// Mirrors how pi sessions are organized by working directory
function projectTasksDir(): string {
const dir = join(process.cwd(), ".pi", "dashboard", "tasks");
ensureDir(dir);
return dir;
}
function projectTodotxt(): string {
return join(projectTasksDir(), "todo.txt");
}
// ── Types ─────────────────────────────────────────────────────────
@@ -130,17 +136,17 @@ function appendToTodo(
priority?: string,
agent?: string
) {
ensureDir(TASKS_DIR);
ensureDir(projectTasksDir());
const pri = priority ? `(${priority.toUpperCase()}) ` : "";
const proj = project ? ` +project:${project}` : "";
const agentTag = agent ? ` +agent:${agent}` : "";
const line = `${pri}${title}${proj}${agentTag}\n`;
appendFileSync(TODO_FILE, line, "utf-8");
appendFileSync(projectTodotxt(), line, "utf-8");
}
function completeTask(title: string): boolean {
if (!existsSync(TODO_FILE)) return false;
const content = readFileSync(TODO_FILE, "utf-8");
if (!existsSync(projectTodotxt())) return false;
const content = readFileSync(projectTodotxt(), "utf-8");
const lines = content.split("\n");
const now = new Date().toISOString().slice(0, 10);
let found = false;
@@ -153,13 +159,13 @@ function completeTask(title: string): boolean {
}
return line;
});
writeFileSync(TODO_FILE, newLines.join("\n"), "utf-8");
writeFileSync(projectTodotxt(), newLines.join("\n"), "utf-8");
return found;
}
function readTodoList() {
if (!existsSync(TODO_FILE)) return { pending: [], done: [] };
const content = readFileSync(TODO_FILE, "utf-8");
if (!existsSync(projectTodotxt())) return { pending: [], done: [] };
const content = readFileSync(projectTodotxt(), "utf-8");
const lines = content.split("\n").filter(Boolean);
const pending = lines.filter((l) => !l.startsWith("x "));
const done = lines.filter((l) => l.startsWith("x "));
@@ -170,7 +176,7 @@ function readTodoList() {
export default function (pi: ExtensionAPI) {
ensureDir(DASHBOARD_DIR);
ensureDir(TASKS_DIR);
ensureDir(projectTasksDir());
const machine = hostname();
const inTmux = !!process.env.TMUX;
@@ -482,7 +488,7 @@ export default function (pi: ExtensionAPI) {
`Tools: ${state.tool_calls}`,
`Start: ${state.started_at || "—"}`,
`Last: ${state.last_tool ? `${state.last_tool} at ${state.last_tool_at}` : "—"}`,
`Tasks: ${TODO_FILE}`,
`Tasks: ${projectTodotxt()}`,
`─────────────────────────────`,
`Run "pi-dashboard" in another terminal for the full TUI view.`,
];