refactor(bridge): update tasks-file route
This commit is contained in:
parent
e00c6db544
commit
598dbdd4a4
1 changed files with 10 additions and 26 deletions
|
|
@ -6,18 +6,6 @@
|
||||||
* GET /tiger/file-tasks/active — only active/pending-action tasks
|
* GET /tiger/file-tasks/active — only active/pending-action tasks
|
||||||
* GET /tiger/file-tasks/completed — only completed tasks
|
* GET /tiger/file-tasks/completed — only completed tasks
|
||||||
* GET /tiger/file-tasks/projects — all projects from PROJECTS.md
|
* GET /tiger/file-tasks/projects — all projects from PROJECTS.md
|
||||||
*
|
|
||||||
* Parser contract (TASKS.md):
|
|
||||||
* Tiger maintains a fenced ```json TASKS ... ``` block at the bottom of
|
|
||||||
* TASKS.md. The parser reads ONLY from that block — no regex over markdown.
|
|
||||||
* If the block is absent, the endpoint returns HTTP 502 with a clear error.
|
|
||||||
* Tiger's MEMORY.md contains the rule: always emit the TASKS_JSON block
|
|
||||||
* on every TASKS.md write.
|
|
||||||
*
|
|
||||||
* Task JSON schema per entry:
|
|
||||||
* { id, title, agent, status, section, note?, age?, project? }
|
|
||||||
* section values: "pending-action" | "in-progress" | "completed"
|
|
||||||
* status values: "pending-action" | "in-progress" | "blocked" | "done"
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Router, Request, Response } from "express";
|
import { Router, Request, Response } from "express";
|
||||||
|
|
@ -25,16 +13,10 @@ import { execInSandbox } from "../tiger.js";
|
||||||
|
|
||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
// ── Parser: read TASKS_JSON fenced block from TASKS.md ───────────────────────
|
|
||||||
function parseTasksJsonBlock(stdout: string): any[] {
|
function parseTasksJsonBlock(stdout: string): any[] {
|
||||||
// Match: ```json\nTASKS\n<json>\n```
|
|
||||||
const match = stdout.match(/```json\s+TASKS\s*\n([\s\S]+?)\n```/);
|
const match = stdout.match(/```json\s+TASKS\s*\n([\s\S]+?)\n```/);
|
||||||
if (!match) {
|
if (!match) {
|
||||||
throw new Error(
|
throw new Error("TASKS.md missing TASKS_JSON block.");
|
||||||
"TASKS.md missing TASKS_JSON block. Tiger must emit:\n" +
|
|
||||||
"```json\nTASKS\n[...]\n```\n" +
|
|
||||||
"at the bottom of every TASKS.md write."
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return JSON.parse(match[1]);
|
return JSON.parse(match[1]);
|
||||||
|
|
@ -43,7 +25,6 @@ function parseTasksJsonBlock(stdout: string): any[] {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Parser: projects from PROJECTS.md ────────────────────────────────────────
|
|
||||||
function parseProjectsMarkdown(stdout: string) {
|
function parseProjectsMarkdown(stdout: string) {
|
||||||
const projects: any[] = [];
|
const projects: any[] = [];
|
||||||
const lines = stdout.split("\n");
|
const lines = stdout.split("\n");
|
||||||
|
|
@ -53,7 +34,6 @@ function parseProjectsMarkdown(stdout: string) {
|
||||||
const trimmed = line.trim();
|
const trimmed = line.trim();
|
||||||
if (trimmed.startsWith("## Active Projects")) { inActive = true; continue; }
|
if (trimmed.startsWith("## Active Projects")) { inActive = true; continue; }
|
||||||
if (trimmed.startsWith("## Completed Projects")) break;
|
if (trimmed.startsWith("## Completed Projects")) break;
|
||||||
|
|
||||||
if (inActive && trimmed.match(/^\| \d/)) {
|
if (inActive && trimmed.match(/^\| \d/)) {
|
||||||
const cols = trimmed.split("|").map((c: string) => c.trim()).filter(Boolean);
|
const cols = trimmed.split("|").map((c: string) => c.trim()).filter(Boolean);
|
||||||
if (cols.length >= 5) {
|
if (cols.length >= 5) {
|
||||||
|
|
@ -68,12 +48,9 @@ function parseProjectsMarkdown(stdout: string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return projects;
|
return projects;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Routes ────────────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
// GET /tiger/file-tasks — all tasks
|
// GET /tiger/file-tasks — all tasks
|
||||||
router.get("/", async (req: Request, res: Response) => {
|
router.get("/", async (req: Request, res: Response) => {
|
||||||
try {
|
try {
|
||||||
|
|
@ -81,7 +58,14 @@ router.get("/", async (req: Request, res: Response) => {
|
||||||
const allTasks = parseTasksJsonBlock(stdout);
|
const allTasks = parseTasksJsonBlock(stdout);
|
||||||
const projectFilter = (req.query.project as string || "").trim().toLowerCase();
|
const projectFilter = (req.query.project as string || "").trim().toLowerCase();
|
||||||
const filtered = projectFilter
|
const filtered = projectFilter
|
||||||
? allTasks.filter((t: any) => t.project?.toLowerCase().includes(projectFilter))
|
? allTasks.filter((t: any) => {
|
||||||
|
const pid = (t.project || "").toLowerCase().replace(/^p0?/, "");
|
||||||
|
return (
|
||||||
|
pid.includes(projectFilter) ||
|
||||||
|
t.project?.toLowerCase().includes(projectFilter) ||
|
||||||
|
t.title?.toLowerCase().includes(projectFilter)
|
||||||
|
);
|
||||||
|
})
|
||||||
: allTasks;
|
: allTasks;
|
||||||
res.json({ ok: true, source: "TASKS.md", count: filtered.length, tasks: filtered });
|
res.json({ ok: true, source: "TASKS.md", count: filtered.length, tasks: filtered });
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue