Add security hardening, Ghidra, recreate skill, checkpoints, shells, web search and themes
- Sandbox (bubblewrap) for non-admin shell/git, MCP per-user rights, hard budgets and quotas, login rate limiting, audit log and backups - Ghidra headless decompilation (ARM64 natives built from source), binary_info tool, clean room / deep workflow per session - Recreate skill and commands for analysing and re-building old software - File checkpoints with rewind/restore, background shells (bash_output, kill_shell) - web_search tool (DuckDuckGo, SearXNG, Brave, Tavily) - In-app dialogs and toasts instead of browser dialogs - 15 base themes (trilium-themes palettes plus Nord, VS Code, GitHub, Catppuccin, One, Dracula, Rose Pine, Everforest, Kanagawa) with light/dark/auto switcher and license notes Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
fab9add5d5
commit
5b569b6835
108 files changed
+6785
-279
No files matched your search
@@ -4,6 +4,7 @@ import { useStore } from "../store";
|
||||
import type { Part, Todo } from "../types";
|
||||
import { Spinner } from "./Activity";
|
||||
import { Diff } from "./Diff";
|
||||
import { IMAGE_EXT, projectFileUrl } from "./Markdown";
|
||||
|
||||
type ToolCall = Extract<Part, { type: "tool_call" }>;
|
||||
type ToolResult = Extract<Part, { type: "tool_result" }>;
|
||||
@@ -57,7 +58,7 @@ export function TodoList({ todos }: { todos: Todo[] }) {
|
||||
);
|
||||
}
|
||||
|
||||
export function ToolCard({ call, result, running }: { call: ToolCall; result?: ToolResult; running: boolean }) {
|
||||
export function ToolCard({ call, result, running, baseDir }: { call: ToolCall; result?: ToolResult; running: boolean; baseDir?: string }) {
|
||||
const t = useT();
|
||||
const progress = useStore((s) => s.progress[call.id]);
|
||||
const status = result ? (result.is_error ? "err" : "ok") : running ? "run" : "err";
|
||||
@@ -77,6 +78,26 @@ export function ToolCard({ call, result, running }: { call: ToolCall; result?: T
|
||||
);
|
||||
}
|
||||
|
||||
// Image files written by the agent are shown as images (SVG too, rendered via <img>).
|
||||
const writtenImage =
|
||||
(call.name === "write" || call.name === "edit") && typeof call.input?.path === "string" && IMAGE_EXT.test(call.input.path) && result && !result.is_error
|
||||
? projectFileUrl(call.input.path, baseDir)
|
||||
: undefined;
|
||||
if (writtenImage) {
|
||||
return (
|
||||
<div className="tool image-result">
|
||||
<div className="tool-head">
|
||||
<span className="tool-name">{call.name}</span>
|
||||
<span className="tool-title">{call.input.path}</span>
|
||||
<span className="status ok">✓</span>
|
||||
</div>
|
||||
<a href={writtenImage} target="_blank" rel="noreferrer">
|
||||
<img src={`${writtenImage}&v=${result!.call_id}`} alt={call.input.path} />
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Short diffs are shown right away, like in a terminal agent.
|
||||
const diffLines = typeof meta?.diff === "string" ? meta.diff.split("\n").length : 0;
|
||||
const openByDefault =
|
||||
|
||||
Reference in new issue
Block a user