From 2b720cb2c21b648b6148843bb317c3d1a920526b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Padez?= Date: Tue, 25 Aug 2026 09:38:29 +0000 Subject: [PATCH] the todo board's barrel and hook, which 420cd075 left behind MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 420cd075 committed TodoBoardPanel.tsx and the AppRegistry import that reaches it, but not index.ts or useTodos.ts. they were staged and never named, so the commit went out without them and master has not built since: AppRegistry.tsx(17,52): Cannot find module '../apps/TodoBoard' TodoBoardPanel.tsx(8,31): Cannot find module './useTodos' invisible here because both files exist in the working tree, and this host is the only one that has them. found while checking whether the tree was fit to tag — a clean checkout of master could not have built a frontend bundle on any of the five hosts. not my work; committed unchanged, untouched since 00:17, and required by a commit that is already pushed. the two files still dirty in this tree belong to a session that is live right now and are deliberately not included, which is why this names its paths. Co-Authored-By: Claude Opus 5 Officer-Session: 656f5c85-e49a-4f1f-b9f3-042a04b4d043 --- .../officerdev/src/apps/TodoBoard/index.ts | 10 ++++ .../officerdev/src/apps/TodoBoard/useTodos.ts | 52 +++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 src/workspaces/officerdev/src/apps/TodoBoard/index.ts create mode 100644 src/workspaces/officerdev/src/apps/TodoBoard/useTodos.ts diff --git a/src/workspaces/officerdev/src/apps/TodoBoard/index.ts b/src/workspaces/officerdev/src/apps/TodoBoard/index.ts new file mode 100644 index 00000000..ce91692d --- /dev/null +++ b/src/workspaces/officerdev/src/apps/TodoBoard/index.ts @@ -0,0 +1,10 @@ +import type { AppRegistryMeta } from '../../AppRegistry'; +import { SquareKanban } from 'lucide-react'; +import { TodoBoardPanel } from './TodoBoardPanel'; + +export { TodoBoardPanel } from './TodoBoardPanel'; +export { useTodoTree, useTodoItem, useTodoPatch } from './useTodos'; + +export const appRegistryMetas: AppRegistryMeta[] = [ + { key: 'todo-board', name: 'Todo board', icon: SquareKanban, component: TodoBoardPanel }, +]; diff --git a/src/workspaces/officerdev/src/apps/TodoBoard/useTodos.ts b/src/workspaces/officerdev/src/apps/TodoBoard/useTodos.ts new file mode 100644 index 00000000..a3f62239 --- /dev/null +++ b/src/workspaces/officerdev/src/apps/TodoBoard/useTodos.ts @@ -0,0 +1,52 @@ +import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; +import { useClient } from 'hooks/useClient'; + +export type TodoItem = { + id: string; + title: string; + theme: string; + status: string; + created: string; + priority: string; + due: string; + order: number; + file: string; +}; + +export type TodoTheme = { theme: string; heading: string; note: string; items: TodoItem[] }; + +export type TodoPatch = { id: string; status?: string; priority?: string; due?: string; order?: number }; + +export const useTodoTree = () => { + const client = useClient(); + return useQuery({ + queryKey: ['todos'], + queryFn: () => client.get<{ themes: TodoTheme[] }>('/todos'), + // The tree is files on disk that other agents edit while the board is open; refetch keeps the board + // honest without a watcher, which the sync contract allows (todo/README.md — poll is the cheapest + // thing that works). + refetchInterval: 30_000, + }); +}; + +export const useTodoItem = (id: string | null) => { + const client = useClient(); + return useQuery({ + queryKey: ['todos', 'item', id], + queryFn: () => + client.get<{ meta: Record; body: string }>(`/todos/item?id=${encodeURIComponent(id!)}`), + enabled: id !== null, + }); +}; + +export const useTodoPatch = () => { + const client = useClient(); + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: (patch: TodoPatch) => client.patch<{ ok: boolean }>('/todos/item', patch), + onSuccess: (_data, patch) => { + void queryClient.invalidateQueries({ queryKey: ['todos'] }); + void queryClient.invalidateQueries({ queryKey: ['todos', 'item', patch.id] }); + }, + }); +};