Add Web Push, guided start screen, SVG icons, chunked uploads, rename

- Web Push (VAPID + RFC 8291, pure Rust): permission/question/finished
  notifications while no app window is visible; settings with test button
- Guided new-session flow: task, craft target (website/app/game/old
  software/fresh), clean room or deep, description, model, folder
  (new, existing or cloned git repository); originals upload to original/
- Craft phase bar (craft_phase tool) for study/specify/build/check/ready
- Chunked uploads (8 MB) up to server.max_upload_mb (default 500 MB)
- All UI glyphs and emojis replaced by themeable SVG icons
- Rename dialog with manual name or model-generated suggestion

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Richard ZinkandClaude Opus 5.5 committed 2026-11-08 21:03:26 +01:00
1 parent 013695722a
commit a0d0e707f2
48 files changed
+2724 -228

No files matched your search

+4 -3
View File
@@ -1,3 +1,4 @@
import { Icon } from "./Icon";
import { useState } from "react";
import { post } from "../api";
import { useT } from "../i18n";
@@ -43,7 +44,7 @@ export function PermissionCard({ req, currentId }: { req: PermissionRequest; cur
return (
<div className="card" role="alertdialog" aria-label={t("permission.title")}>
<h3>
🔐 {t("permission.title")} <span className="chip mono">{req.tool}</span>
<Icon name="lock" /> {t("permission.title")} <span className="chip mono">{req.tool}</span>
</h3>
<SubagentHint sessionId={req.session_id} currentId={currentId} />
<div style={{ margin: "6px 0" }}>{req.title}</div>
@@ -122,7 +123,7 @@ export function QuestionCard({ req, currentId }: { req: QuestionRequest; current
return (
<div className="card" role="dialog" aria-label={t("question.title")}>
<h3>❓ {t("question.title")}</h3>
<h3><Icon name="question" /> {t("question.title")}</h3>
<div className="from">{source}</div>
<SubagentHint sessionId={req.session_id} currentId={currentId} />
{req.questions.map((q, qi) => (
@@ -143,7 +144,7 @@ export function QuestionCard({ req, currentId }: { req: QuestionRequest; current
onClick={() => toggle(qi, o.label, !!q.multi_select)}
onKeyDown={(e) => (e.key === " " || e.key === "Enter") && toggle(qi, o.label, !!q.multi_select)}
>
<span>{q.multi_select ? (isSel ? "☑" : "☐") : isSel ? "◉" : "○"}</span>
<Icon name={q.multi_select ? (isSel ? "box-on" : "box-off") : isSel ? "radio-on" : "radio-off"} />
<div style={{ flex: 1 }}>
{o.label === OTHER ? (
<input