Files
ARTEX/web/src/lib/status.ts
BaaRai e233c02314 Translate all Chinese text to English
Comments, doc comments, UI labels, log and error messages, LLM prompt
strings, markdown docs, test data and assertions. Identifiers, enum
keys, routes, placeholders and code structure are unchanged.

Notes:
- docs/漏洞流量证据.md renamed to docs/vulnerability-traffic-evidence.md
- tests that exercised CJK specific handling (GBK zip names, Chinese
  full text search) now use ASCII equivalents; go build passes and the
  test suite matches the pre translation baseline (remaining failures
  need a PostgreSQL DSN and fail identically on the original)
- frontend mention syntax now uses English kinds (finding, asset, ...)
  matching the backend, chat mentions tests pass
2026-10-08 23:14:34 +02:00

129 lines
4.8 KiB
TypeScript

// Centralised status → color/label semantics, reused across the whole app.
// Spec §8.3: intent / coverage / task / severity each have a consistent color set.
export type Tone = "neutral" | "blue" | "green" | "amber" | "red" | "rose" | "violet" | "slate";
export const toneClasses: Record<Tone, string> = {
neutral: "bg-muted text-muted-foreground border-transparent",
blue: "bg-blue-500/15 text-blue-600 dark:text-blue-400 border-blue-500/20",
green: "bg-emerald-500/15 text-emerald-600 dark:text-emerald-400 border-emerald-500/20",
amber: "bg-amber-500/15 text-amber-600 dark:text-amber-400 border-amber-500/20",
red: "bg-red-500/15 text-red-600 dark:text-red-400 border-red-500/20",
// rose is used for "Critical" — a solid high-emphasis fill clearly above the soft red outline of "High".
rose: "bg-rose-600 text-white border-rose-600 dark:bg-rose-600 dark:text-white",
violet: "bg-violet-500/15 text-violet-600 dark:text-violet-400 border-violet-500/20",
slate: "bg-slate-500/15 text-slate-600 dark:text-slate-400 border-slate-500/20",
};
export const toneDot: Record<Tone, string> = {
neutral: "bg-muted-foreground",
blue: "bg-blue-500",
green: "bg-emerald-500",
amber: "bg-amber-500",
red: "bg-red-500",
rose: "bg-white",
violet: "bg-violet-500",
slate: "bg-slate-500",
};
interface StatusMeta {
label: string;
tone: Tone;
}
const intent: Record<string, StatusMeta> = {
open: { label: "Open", tone: "slate" },
running: { label: "Running", tone: "blue" },
paused: { label: "Paused", tone: "amber" },
done: { label: "Completed", tone: "green" },
// blocked = model/API/network failures exhausted the retries; this intent barely explored anything (not an interception).
blocked: { label: "Error", tone: "red" },
// exhausted = the step/time budget cut the run short midway, only partial results written back (not "direction exhausted").
exhausted: { label: "Budget exhausted", tone: "violet" },
// stopped = legacy soft-deleted state (kept for historical data).
stopped: { label: "Stopped", tone: "slate" },
// deleted = the user soft-deleted this intent (nodes and lineage kept; see delete_reason for the reason).
deleted: { label: "Deleted", tone: "slate" },
};
const task: Record<string, StatusMeta> = {
created: { label: "Created", tone: "slate" },
queued: { label: "Queued", tone: "amber" },
running: { label: "Running", tone: "blue" },
paused: { label: "Paused", tone: "amber" },
done: { label: "Completed", tone: "green" },
failed: { label: "Failed", tone: "red" },
timeout: { label: "Timed out", tone: "amber" },
};
const severity: Record<string, StatusMeta> = {
critical: { label: "Critical", tone: "rose" },
high: { label: "High", tone: "red" },
medium: { label: "Medium", tone: "amber" },
low: { label: "Low", tone: "slate" },
};
const finding: Record<string, StatusMeta> = {
pending: { label: "Pending", tone: "amber" },
in_progress: { label: "In progress", tone: "blue" },
confirmed: { label: "Confirmed", tone: "red" },
resolved: { label: "Resolved", tone: "green" },
fixed: { label: "Fixed", tone: "green" },
false_positive: { label: "False positive", tone: "slate" },
ignored: { label: "Ignored", tone: "neutral" },
duplicate: { label: "Duplicate", tone: "neutral" },
risk_accepted: { label: "Risk accepted", tone: "violet" },
};
const engine: Record<string, StatusMeta> = {
exploring: { label: "Exploring", tone: "blue" },
paused: { label: "Paused", tone: "amber" },
stalled: { label: "Stalled", tone: "red" },
idle: { label: "Idle", tone: "neutral" },
};
const goal: Record<string, StatusMeta> = {
open: { label: "In progress", tone: "blue" },
met: { label: "Met", tone: "green" },
abandoned: { label: "Abandoned", tone: "slate" },
};
const audit: Record<string, StatusMeta> = {
allow: { label: "Allow", tone: "green" },
block: { label: "Block", tone: "red" },
};
const node: Record<string, StatusMeta> = {
observed: { label: "Observed", tone: "slate" },
confirmed: { label: "Confirmed", tone: "green" },
tombstoned: { label: "Tombstoned", tone: "neutral" },
};
// Notification delivery states. sending uses blue rather than amber: it is not "a problem"
// but "claimed and sending now", which must stay distinguishable from pending's waiting.
const delivery: Record<string, StatusMeta> = {
pending: { label: "Pending", tone: "amber" },
sending: { label: "Sending", tone: "blue" },
sent: { label: "Sent", tone: "green" },
failed: { label: "Failed", tone: "red" },
skipped: { label: "Skipped", tone: "neutral" },
};
const maps = {
intent,
task,
severity,
finding,
engine,
goal,
audit,
node,
delivery,
} as const;
export type StatusDomain = keyof typeof maps;
export function statusMeta(domain: StatusDomain, key: string): StatusMeta {
return maps[domain][key] ?? { label: key, tone: "neutral" };
}