feat(ui): Settings view + per-space project cards (status/research/edit/delete) + theming pass

- Settings (#/settings): API tokens (mint/list/revoke), Agents list, Orthos Mode placeholder
- Per-space Projects: Void-1-style expandable cards — inline status, ↻ Research (Eithan stub),
  Edit/New modal, Delete-with-confirm; migration 019 adds research_status/notes/timestamps;
  POST /api/projects/:id/research stub; GET /api/agent-tokens list
- Global +1 font bump; themed scrollbars; larger/bolder themed topbar

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
root
2026-06-05 00:06:08 +10:00
parent 4a55c24700
commit 80363d3e68
14 changed files with 432 additions and 113 deletions

View File

@@ -35,6 +35,9 @@ tokensRouter.use(requireOwner);
router.get('/', asyncWrap(async (_req, res) => { res.json(await repo.list()); }));
// Token metadata across all agents (label/usage/revocation; never the hash) for Settings.
tokensRouter.get('/', asyncWrap(async (_req, res) => { res.json(await repo.listTokenMeta()); }));
router.post('/',
validate({ body: createSchema }),
asyncWrap(async (req, res) => {

View File

@@ -80,6 +80,17 @@ router.patch('/:id',
})
);
// Research stub — owner asks Eithan (later) to research this project.
router.post('/:id/research',
validate({ params: idParams }),
asyncWrap(async (req, res) => {
if (req.actor?.kind !== 'user') return res.status(403).json({ error: { code: 'owner_only' } });
const row = await repo.requestResearch(req.params.id, req.actor);
if (!row) throw new NotFoundError('project not found');
res.json(row);
})
);
router.delete('/:id',
requireWrite('project'),
validate({ params: idParams }),