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-17 11:37:48 +00:00
|
|
|
<task-item class="blue hide-content">
|
2026-07-30 06:44:46 +00:00
|
|
|
<task-title>Rojo Chat: LLM Tools</task-title>
|
|
|
|
|
<task-content>
|
|
|
|
|
Allow users to define and use tools in rojo-chat-panel. Tools extend the LLM
|
|
|
|
|
with callable functions (e.g. file read, web search, custom actions). The chat
|
|
|
|
|
panel should support declaring a tool set, passing tool definitions to the model,
|
|
|
|
|
handling tool-call responses, and feeding results back into the conversation.
|
|
|
|
|
</task-content>
|
|
|
|
|
</task-item>
|
|
|
|
|
|
|
|
|
|
<task-item class="blue hide-content">
|
|
|
|
|
<task-title>Rojo Chat: Claude API</task-title>
|
2026-07-17 11:37:48 +00:00
|
|
|
<task-content>
|
2026-07-30 06:44:46 +00:00
|
|
|
Integrate the Claude API (Anthropic) as a provider option in rojo-chat-panel.
|
|
|
|
|
Allows testing and using Claude models alongside the existing OpenAI-compatible
|
|
|
|
|
provider. Covers API key configuration, model selection, and verifying streaming
|
|
|
|
|
and tool-use work end-to-end with the Anthropic SDK.
|
2026-07-17 11:37:48 +00:00
|
|
|
</task-content>
|
|
|
|
|
</task-item>
|
|
|
|
|
|
|
|
|
|
<task-item class="blue hide-content">
|
|
|
|
|
<task-title>Mobile: editor layout too tall, chat input not reachable</task-title>
|
|
|
|
|
<task-content>
|
|
|
|
|
On mobile the overall editor layout is still too tall — panels overflow the
|
|
|
|
|
viewport and the chat input area is pushed out of view even after the
|
|
|
|
|
min-height: 0 fix on rojo-chat-panel. Needs a broader mobile layout pass
|
|
|
|
|
on the panel/section/editor structure.
|
|
|
|
|
</task-content>
|
|
|
|
|
</task-item>
|
|
|
|
|
|
2026-07-18 06:37:47 +00:00
|
|
|
|
2026-07-17 11:37:48 +00:00
|
|
|
|
|
|
|
|
<task-item class="blue hide-content">
|
|
|
|
|
<task-title>Code syntax highlighting in rojo-chat (Highlight.js)</task-title>
|
|
|
|
|
<task-content>
|
|
|
|
|
Code blocks in assistant responses are rendered as plain text inside pre/code tags.
|
|
|
|
|
Integrate Highlight.js to apply syntax highlighting after markdown-it renders each
|
|
|
|
|
response chunk. Apply highlighting to all code blocks in the assistant bubble.
|
|
|
|
|
</task-content>
|
|
|
|
|
</task-item>
|
|
|
|
|
|
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>
|
|
|
|
|
|
2026-07-14 12:34:47 +00:00
|
|
|
<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
|
|
|
|
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>
|
|
|
|
|
|
2026-07-18 06:37:47 +00:00
|
|
|
<task-item class="blue hide-content">
|
|
|
|
|
<task-title>Ensure time is not depending on the user's clock</task-title>
|
|
|
|
|
<task-content>
|
|
|
|
|
JWT verification on the local server failed because the Windows client clock was
|
|
|
|
|
~65 minutes ahead of the production auth server clock. Any time-based logic that
|
|
|
|
|
compares client-side time against server-issued timestamps (JWT exp, token TTL,
|
|
|
|
|
session validity) is broken when clocks diverge.
|
|
|
|
|
|
|
|
|
|
Work to do:
|
|
|
|
|
— Audit all places where Date.now() / new Date() is used for security or
|
|
|
|
|
session decisions; replace with server-authoritative time where possible.
|
|
|
|
|
— On the auth side: use clockTolerance in jwt.verify as a configurable
|
|
|
|
|
escape hatch (JWT_CLOCK_TOLERANCE env var, already added for local dev).
|
|
|
|
|
— Write a developer guide covering: why user/client clock cannot be trusted,
|
|
|
|
|
how to use server time for all authoritative checks, how to diagnose clock
|
|
|
|
|
skew issues, and the JWT_CLOCK_TOLERANCE workaround for local dev.
|
|
|
|
|
— Consider syncing advice in the local dev setup docs (future local-dev task).
|
|
|
|
|
</task-content>
|
|
|
|
|
</task-item>
|
|
|
|
|
|
2026-07-14 12:34:47 +00:00
|
|
|
</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
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="lane">
|
|
|
|
|
<div class="lane-header">Done</div>
|
|
|
|
|
|
2026-07-30 20:02:14 +00:00
|
|
|
<task-item class="green hide-content">
|
2026-07-31 18:43:08 +00:00
|
|
|
<task-title>Per-project per-device layout persistence</task-title>
|
2026-07-30 20:02:14 +00:00
|
|
|
<task-content>
|
2026-07-31 18:43:08 +00:00
|
|
|
Full tab tree (panels → sections → tab-containers → tabs including open files)
|
|
|
|
|
saved to .roject/layout-<deviceId>.json inside each project directory.
|
|
|
|
|
Remote projects: storage/<id>/root/.roject/. Local Electron: <localRoot>/.roject/.
|
|
|
|
|
Remote proxy (Electron opening a roject.rokojori.com project): centralized
|
|
|
|
|
layouts dir keyed by device + remoteProjectId.
|
|
|
|
|
deviceId in localStorage already differentiates Firefox, Chrome, and Electron.
|
|
|
|
|
Serialized format: { version, activePortraitPanel, panels: { left, center, right } }
|
|
|
|
|
where each panel has sections[], each section has tabContainers[], each
|
|
|
|
|
tab-container has tabs[] with { id, label, panelType, tag, openFile }.
|
|
|
|
|
FileEditorPanel interface extended with getCurrentFile(): string | null,
|
|
|
|
|
implemented in code-panel and page-editor-panel.
|
|
|
|
|
Restored on editor load; falls back to default layout if none saved.
|
|
|
|
|
makeResizeHandle() gained an optional onResize callback so inner handles trigger saves.
|
|
|
|
|
.roject/ filtered from both remote (storage.ts) and local (localFiles.ts) file trees.
|
|
|
|
|
Save triggers: panel resize, inner handle resize, tab click, file open,
|
|
|
|
|
split, close-container, add-panel, portrait panel switch.
|
2026-07-14 12:34:47 +00:00
|
|
|
</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>
|