2026-07-14 12:34:47 +00:00
|
|
|
<!DOCTYPE html>
|
|
|
|
|
<html lang="en">
|
|
|
|
|
<head>
|
|
|
|
|
<meta charset="UTF-8">
|
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
|
|
<title>Tasks - Roject</title>
|
|
|
|
|
<link rel="stylesheet" href="../_assets_/styles.css">
|
|
|
|
|
<link rel="stylesheet" href="../_assets_/nav.css">
|
|
|
|
|
<link rel="stylesheet" href="../_assets_/boards.css">
|
|
|
|
|
</head>
|
|
|
|
|
<body>
|
|
|
|
|
<div class="board-page">
|
|
|
|
|
|
|
|
|
|
<header>
|
|
|
|
|
<p class="date">Board</p>
|
|
|
|
|
<h1>Tasks</h1>
|
|
|
|
|
<p class="subtitle">Click a task title to expand or collapse its content.</p>
|
|
|
|
|
</header>
|
|
|
|
|
|
|
|
|
|
<div class="board">
|
|
|
|
|
|
|
|
|
|
<div class="lane">
|
|
|
|
|
<div class="lane-header">To Do</div>
|
|
|
|
|
|
2026-07-16 13:06:33 +00:00
|
|
|
<task-item class="blue hide-content">
|
|
|
|
|
<task-title>Rojo Character Editor</task-title>
|
|
|
|
|
<task-content>
|
|
|
|
|
Allow changing colors and selecting layers of a Rojo character from within
|
|
|
|
|
the rojo-settings-panel. Colors map to fill/stroke/both targets on SVG elements;
|
|
|
|
|
layers toggle visibility of named groups or swap between variants.
|
|
|
|
|
The appearance field (colors[], layers[]) is already in the settings.rojo schema.
|
|
|
|
|
</task-content>
|
|
|
|
|
</task-item>
|
|
|
|
|
|
|
|
|
|
<task-item class="blue hide-content">
|
|
|
|
|
<task-title>Rojo Character Animation Box</task-title>
|
|
|
|
|
<task-content>
|
|
|
|
|
Animation system for emotional feedback during conversations.
|
|
|
|
|
Animations can be scripted (predefined sequences) or driven dynamically by
|
|
|
|
|
an LLM that emits emotion tags alongside its response. The animation box
|
|
|
|
|
plays character animations (idle, happy, thinking, surprised, etc.) in the
|
|
|
|
|
portrait area of the rojo-settings-panel and rojo-chat-panel.
|
|
|
|
|
</task-content>
|
|
|
|
|
</task-item>
|
|
|
|
|
|
|
|
|
|
<task-item class="blue hide-content">
|
|
|
|
|
<task-title>File tree: drag-and-drop move for files and directories</task-title>
|
|
|
|
|
<task-content>
|
|
|
|
|
Allow files and directories to be moved by dragging them within the file tree.
|
|
|
|
|
Dragging a file onto a directory moves it inside; dragging a directory onto another
|
|
|
|
|
directory moves the whole subtree. Use the existing file rename API
|
|
|
|
|
(POST /api/files/:projectId/rename) — moving is a rename to a new parent path.
|
|
|
|
|
</task-content>
|
|
|
|
|
</task-item>
|
|
|
|
|
|
|
|
|
|
<task-item class="blue hide-content">
|
|
|
|
|
<task-title>Tab context menu on right-click (tabs and empty tab bar area)</task-title>
|
|
|
|
|
<task-content>
|
|
|
|
|
The tab ⋮ menu already works but should also open on right-click anywhere on
|
|
|
|
|
the tab bar — both on individual tabs and on the empty space to the right of the tabs.
|
|
|
|
|
Right-clicking a specific tab should also offer a "Close this tab" action directly.
|
|
|
|
|
</task-content>
|
|
|
|
|
</task-item>
|
|
|
|
|
|
|
|
|
|
<task-item class="blue hide-content">
|
|
|
|
|
<task-title>File tree double-click: auto-open or focus existing editor</task-title>
|
|
|
|
|
<task-content>
|
|
|
|
|
When a file is double-clicked in the file tree:
|
|
|
|
|
— If an editor panel that can handle the file type is already open and not pinned,
|
|
|
|
|
focus that panel's tab and load the file into it.
|
|
|
|
|
— If no suitable unpinned editor exists, open a new panel of the correct type
|
|
|
|
|
in the active section before loading the file.
|
|
|
|
|
Single-click keeps current behaviour (selection only, no open).
|
|
|
|
|
</task-content>
|
|
|
|
|
</task-item>
|
|
|
|
|
|
2026-07-14 12:34:47 +00:00
|
|
|
<task-item class="blue hide-content">
|
|
|
|
|
<task-title>Remote Projects in Electron</task-title>
|
|
|
|
|
<task-content>
|
|
|
|
|
Allow the Electron app to connect to roject.rokojori.com and list remote projects
|
|
|
|
|
alongside local ones. The JWT is already available;
|
|
|
|
|
it's a matter of pointing requests at the remote URL with the token.
|
|
|
|
|
</task-content>
|
|
|
|
|
</task-item>
|
|
|
|
|
|
|
|
|
|
<task-item class="blue hide-content">
|
|
|
|
|
<task-title>Unauthenticated Landing Screen</task-title>
|
|
|
|
|
<task-content>
|
|
|
|
|
Unauthenticated users currently crash on dashboard components.
|
|
|
|
|
They should land on a screen that explains the app and shows a login link.
|
|
|
|
|
</task-content>
|
|
|
|
|
</task-item>
|
|
|
|
|
|
|
|
|
|
<task-item class="blue hide-content">
|
|
|
|
|
<task-title>Replace browser confirm() in group editor and account delete</task-title>
|
|
|
|
|
<task-content>
|
|
|
|
|
The group editor and account delete button still use the browser confirm() dialog.
|
|
|
|
|
Replace with the custom <confirm-dialog> component already used elsewhere.
|
|
|
|
|
</task-content>
|
|
|
|
|
</task-item>
|
|
|
|
|
|
|
|
|
|
<task-item class="blue hide-content">
|
|
|
|
|
<task-title>MediaViewerPanel for images and PDFs</task-title>
|
|
|
|
|
<task-content>
|
|
|
|
|
Non-text files (images, PDFs) are visible in the file tree but not openable.
|
|
|
|
|
Add a MediaViewerPanel and register it in FileEditorRegistry for common media types.
|
|
|
|
|
</task-content>
|
|
|
|
|
</task-item>
|
|
|
|
|
|
|
|
|
|
<task-item class="blue hide-content">
|
2026-07-14 20:27:03 +00:00
|
|
|
<task-title>Investigate Gitea webhook auto-deploy</task-title>
|
2026-07-14 12:34:47 +00:00
|
|
|
<task-content>
|
2026-07-14 20:27:03 +00:00
|
|
|
The webhook did not fire on the last two pushes to main. Check the Gitea
|
|
|
|
|
webhook delivery log for the response code from /api/deploy. Also run
|
|
|
|
|
journalctl -u roject -n 100 on the server to see whether the endpoint
|
|
|
|
|
was reached at all. Most likely causes: signature mismatch, wrong branch
|
|
|
|
|
ref, or the deploy command failing silently.
|
2026-07-14 12:34:47 +00:00
|
|
|
</task-content>
|
|
|
|
|
</task-item>
|
|
|
|
|
|
2026-07-15 15:13:06 +00:00
|
|
|
<task-item class="blue hide-content">
|
|
|
|
|
<task-title>Roject: wire lookup-email for member storage migration</task-title>
|
|
|
|
|
<task-content>
|
|
|
|
|
The rokojori-auth side (POST /api/auth/lookup-email) is live.
|
|
|
|
|
Remaining Roject-side work:
|
|
|
|
|
|
|
|
|
|
— Add SERVICE_SECRET to Roject .env (must match rokojori-auth SERVICE_SECRET)
|
|
|
|
|
— In POST /api/projects/:id/members: call account.rokojori.com/api/auth/lookup-email,
|
|
|
|
|
receive the user ID, store member_id as the user ID instead of the email
|
|
|
|
|
— In source/server/projectAccess.ts change memberMatchesUser()
|
|
|
|
|
from member.member_id === user.email
|
|
|
|
|
to member.member_id === user.userId
|
|
|
|
|
— Write a one-off migration script: for each member row, call lookup-email
|
|
|
|
|
with the stored email and replace member_id with the returned user ID
|
|
|
|
|
</task-content>
|
|
|
|
|
</task-item>
|
|
|
|
|
|
2026-07-15 18:39:06 +00:00
|
|
|
<task-item class="blue hide-content">
|
|
|
|
|
<task-title>Investigate session logout after ~1 hour</task-title>
|
|
|
|
|
<task-content>
|
|
|
|
|
Users are logged out after a couple of hours. The access token issued by
|
|
|
|
|
rokojori-auth expires after 1 hour; the refresh token lasts 30 days.
|
|
|
|
|
Roject should silently refresh via GET account.rokojori.com/api/auth/refresh-session
|
|
|
|
|
before the token expires.
|
|
|
|
|
|
|
|
|
|
Investigate:
|
|
|
|
|
— Is the 401 response from any API route triggering a redirect to refresh-session?
|
|
|
|
|
— Is the refreshToken cookie present and being sent cross-domain?
|
|
|
|
|
— Is the refresh-session endpoint actually rotating both cookies correctly?
|
|
|
|
|
— Check journalctl on the server for 401 patterns and the browser network tab
|
|
|
|
|
for which request first returns 401.
|
|
|
|
|
</task-content>
|
|
|
|
|
</task-item>
|
|
|
|
|
|
2026-07-14 12:34:47 +00:00
|
|
|
<task-item class="blue hide-content">
|
|
|
|
|
<task-title>Switch Gitea webhook to dev branch</task-title>
|
|
|
|
|
<task-content>
|
|
|
|
|
The Gitea webhook currently triggers on pushes to main, redeploying on every commit.
|
|
|
|
|
Switch to a dev branch so main is the stable release target.
|
|
|
|
|
</task-content>
|
|
|
|
|
</task-item>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="lane">
|
|
|
|
|
<div class="lane-header">In Progress</div>
|
|
|
|
|
|
2026-07-16 05:27:48 +00:00
|
|
|
<task-item class="yellow hide-content">
|
|
|
|
|
<task-title>rokojori-tunnel — Phase 2</task-title>
|
|
|
|
|
<task-content>
|
tunnel: Electron agent, production deployment, streaming, Roject integration, chunk animation
— Electron Tunnel Agent app (tray, login, tunnel list, start/stop/delete/create)
— tunnel.rokojori.com deployed (nginx WS upgrade, systemd, certbot, port 3003)
— Streaming relay protocol: res_start/res_data/res_end replaces single-shot response
— Roject: browse-tunnels button in rojo-settings-panel, /tunnels/browse proxy route
— Roject: LLM chat via tunnel (TUNNEL_SERVER_URL, /v1 path, dual-source JWT)
— rojo-chat-panel: typeText() splits large relay chunks for smooth streaming appearance
— Boards, outline, and history updated
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-16 13:46:51 +00:00
|
|
|
Production-deployed at tunnel.rokojori.com. Complete so far:
|
|
|
|
|
relay server, CRUD API, streaming WebSocket protocol (res_start / res_data / res_end),
|
|
|
|
|
HTTP proxy with SSE streaming, Electron Tunnel Agent (tray, login, tunnel list),
|
|
|
|
|
Roject browse-tunnels button, Roject LLM chat via tunnel, client-side chunk animation.
|
2026-07-16 05:27:48 +00:00
|
|
|
|
tunnel: Electron agent, production deployment, streaming, Roject integration, chunk animation
— Electron Tunnel Agent app (tray, login, tunnel list, start/stop/delete/create)
— tunnel.rokojori.com deployed (nginx WS upgrade, systemd, certbot, port 3003)
— Streaming relay protocol: res_start/res_data/res_end replaces single-shot response
— Roject: browse-tunnels button in rojo-settings-panel, /tunnels/browse proxy route
— Roject: LLM chat via tunnel (TUNNEL_SERVER_URL, /v1 path, dual-source JWT)
— rojo-chat-panel: typeText() splits large relay chunks for smooth streaming appearance
— Boards, outline, and history updated
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-16 13:46:51 +00:00
|
|
|
Remaining:
|
2026-07-16 05:27:48 +00:00
|
|
|
— Allowed users list enforcement (multi-user private access)
|
|
|
|
|
— Public access mode (no auth required on proxy route)
|
tunnel: Electron agent, production deployment, streaming, Roject integration, chunk animation
— Electron Tunnel Agent app (tray, login, tunnel list, start/stop/delete/create)
— tunnel.rokojori.com deployed (nginx WS upgrade, systemd, certbot, port 3003)
— Streaming relay protocol: res_start/res_data/res_end replaces single-shot response
— Roject: browse-tunnels button in rojo-settings-panel, /tunnels/browse proxy route
— Roject: LLM chat via tunnel (TUNNEL_SERVER_URL, /v1 path, dual-source JWT)
— rojo-chat-panel: typeText() splits large relay chunks for smooth streaming appearance
— Boards, outline, and history updated
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-16 13:46:51 +00:00
|
|
|
— GET /api/tunnels/available with ?purpose= filter surfaced in Roject provider picker
|
2026-07-16 05:27:48 +00:00
|
|
|
</task-content>
|
|
|
|
|
</task-item>
|
|
|
|
|
|
2026-07-15 18:39:06 +00:00
|
|
|
<task-item class="yellow hide-content">
|
|
|
|
|
<task-title>styles.rokojori.com — complete deployment</task-title>
|
|
|
|
|
<task-content>
|
|
|
|
|
Service is built and running manually via npm start on the server.
|
|
|
|
|
Remaining work:
|
|
|
|
|
— Set up systemd service (styles-rokojori.service) so it survives restarts
|
|
|
|
|
— Download Barlow from /add-fonts (weights 100, 400, 700, 900)
|
|
|
|
|
— Verify CORS is working for roject.rokojori.com font imports
|
|
|
|
|
— Add to the add-subdomain deployment guide as a reference example
|
|
|
|
|
</task-content>
|
|
|
|
|
</task-item>
|
|
|
|
|
|
2026-07-14 12:34:47 +00:00
|
|
|
<task-item class="yellow hide-content">
|
|
|
|
|
<task-title>Local Filesystem Access</task-title>
|
|
|
|
|
<task-content>
|
|
|
|
|
Extend the file tree to browse arbitrary directories on the host
|
|
|
|
|
machine using Node.js fs rather than the server's JSON-backed project storage.
|
|
|
|
|
</task-content>
|
|
|
|
|
</task-item>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="lane">
|
|
|
|
|
<div class="lane-header">Done</div>
|
|
|
|
|
|
2026-07-14 20:27:03 +00:00
|
|
|
<task-item class="green hide-content">
|
|
|
|
|
<task-title>CI deploy email notification</task-title>
|
|
|
|
|
<task-content>
|
|
|
|
|
EmailService added to Roject (SMTP via Nodemailer, same credentials as rokojori-auth).
|
|
|
|
|
Startup email sent from startServer() listen callback; deploy email sent from
|
|
|
|
|
/api/deploy after signature verification passes. reportEmail defined as a static
|
|
|
|
|
field on EmailService.
|
|
|
|
|
</task-content>
|
|
|
|
|
</task-item>
|
|
|
|
|
|
2026-07-14 12:34:47 +00:00
|
|
|
<task-item class="green hide-content">
|
|
|
|
|
<task-title>Electron Desktop App Shell</task-title>
|
|
|
|
|
<task-content>
|
|
|
|
|
Login window, JWT auth via API, Authorization header injection, token persistence,
|
|
|
|
|
ROJECT_ROOT path fix, ELECTRON_RUN_AS_NODE workaround. Full local-only Electron app working.
|
|
|
|
|
</task-content>
|
|
|
|
|
</task-item>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<footer>
|
|
|
|
|
Roject — tasks
|
|
|
|
|
</footer>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
<script>var NAV_ROOT = '../';</script>
|
|
|
|
|
<script src="../_assets_/nav-data.js"></script>
|
|
|
|
|
<script src="../_assets_/nav.js"></script>
|
|
|
|
|
<script>
|
|
|
|
|
document.querySelectorAll( 'task-title' ).forEach( title =>
|
|
|
|
|
{
|
|
|
|
|
title.addEventListener( 'click', () =>
|
|
|
|
|
{
|
|
|
|
|
title.closest( 'task-item' ).classList.toggle( 'hide-content' );
|
|
|
|
|
} );
|
|
|
|
|
} );
|
|
|
|
|
</script>
|
|
|
|
|
</body>
|
|
|
|
|
</html>
|