Add terminal client, memory, model fallback, version and install improvements
- codecraft: full-screen terminal client (ratatui) – local tools and files, models via the CodeCraft server gateway or own providers (standalone with a guided setup), slash commands, @files, permission dialogs, resume, update - Static Linux CLI builds (x86_64/aarch64, cargo-zigbuild) served by the server: /cli/install.sh and /cli/download/<target> - Project memory (remember tool, .codecraft/memory.md) and personal memory - Model fallback when a host is unreachable or a budget is used up - Version/commit in UI and health, daily release check, "What's new" dialog - PWA: install button, maskable icon, manifest id and screenshots - Case-insensitive detection of connection errors for retries Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
aa1f8cf016
commit
6dffcb501a
52 files changed
+6477
-765
No files matched your search
@@ -0,0 +1,46 @@
|
||||
import { useState } from "react";
|
||||
import { getLang, useT } from "../i18n";
|
||||
import { WHATS_NEW } from "../whatsnew";
|
||||
import { Icon } from "./Icon";
|
||||
|
||||
const KEY = "codecraft.seenVersion";
|
||||
|
||||
/** Shown once after the server was updated to a version with release notes. */
|
||||
export function WhatsNew({ version }: { version: string }) {
|
||||
const t = useT();
|
||||
const seen = localStorage.getItem(KEY);
|
||||
const [open, setOpen] = useState(() => {
|
||||
// First visit ever: just remember the version.
|
||||
if (!seen) {
|
||||
localStorage.setItem(KEY, version);
|
||||
return false;
|
||||
}
|
||||
return seen !== version && !!WHATS_NEW[version];
|
||||
});
|
||||
if (!open) return null;
|
||||
const entry = WHATS_NEW[version];
|
||||
const items = getLang() === "de" ? entry.de : entry.en;
|
||||
const close = () => {
|
||||
localStorage.setItem(KEY, version);
|
||||
setOpen(false);
|
||||
};
|
||||
return (
|
||||
<div className="modal-backdrop" onClick={close}>
|
||||
<div className="modal" role="dialog" aria-label={t("whatsnew.title")} onClick={(e) => e.stopPropagation()}>
|
||||
<h3>
|
||||
<Icon name="sparkle" /> {t("whatsnew.title", { version })}
|
||||
</h3>
|
||||
<ul className="whatsnew">
|
||||
{items.map((i) => (
|
||||
<li key={i}>{i}</li>
|
||||
))}
|
||||
</ul>
|
||||
<div className="row" style={{ justifyContent: "flex-end" }}>
|
||||
<button className="primary" onClick={close}>
|
||||
{t("common.ok")}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user