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

+5 -4
View File
@@ -1,3 +1,4 @@
import { Icon } from "./Icon";
import { useEffect, useState } from "react";
import { post } from "../api";
import { fmtRelative, useT } from "../i18n";
@@ -104,17 +105,17 @@ export function GitPanel({
{f.path}
</button>
<button className="small ghost" title={t("git.openFile")} onClick={() => openFile(abs(f))}>
↗
<Icon name="external" />
</button>
{isStaged ? (
<button className="small" title={t("git.unstage")} onClick={() => run("unstage", () => call("unstage", { files: [abs(f)] }))}>
−
<Icon name="minus" />
</button>
) : (
<>
{f.index !== "?" && (
<button className="small ghost danger" title={t("git.discard")} onClick={() => void confirmDialog({ message: t("git.discardConfirm", { file: f.path }), danger: true, confirmLabel: t("git.discard") }).then((ok): unknown => ok && run("discard", () => call("discard", { files: [abs(f)] })))}>
↺
<Icon name="refresh" />
</button>
)}
<button className="small" title={t("git.stage")} onClick={() => run("stage", () => call("stage", { files: [abs(f)] }))}>
@@ -153,7 +154,7 @@ export function GitPanel({
</button>
{status.upstream && (
<span className="chip" title={status.upstream}>
↑{status.ahead} ↓{status.behind}
<Icon name="arrow-up" className="tiny" />{status.ahead} <Icon name="arrow-down" className="tiny" />{status.behind}
</span>
)}
<span className="spacer" />