/** * Mirror of `convex/lib/agentKind.ts` for the CLI. The published package * cannot import from the Convex backend, so the normalization logic lives * here as well. Keep both copies in lockstep. */ export const KNOWN_AGENT_KINDS = [ "claude_code", "codex", "cursor", "hermes", "openclaw", "other", ] as const; export type KnownAgentKind = (typeof KNOWN_AGENT_KINDS)[number]; export const KNOWN_AGENT_KIND_SET: ReadonlySet = new Set( KNOWN_AGENT_KINDS, ); export const DEFAULT_AGENT_KIND: KnownAgentKind = "other"; export const KNOWN_AGENT_KIND_LABELS: Record = { claude_code: "Claude Code Agent", codex: "Codex Agent", cursor: "Cursor Agent", hermes: "Hermes Agent", openclaw: "OpenClaw Agent", other: "Agent", }; const MAX_AGENT_KIND_LENGTH = 64; /** * Normalize a user-supplied agent kind into the canonical form Dench stores. * Lower-cases, trims, replaces spaces and dashes with underscores, drops * unsafe characters, caps length, and falls back to `other` when the input * is missing or normalizes to empty. */ export function normalizeAgentKind(input: unknown): string { if (typeof input !== "string") return DEFAULT_AGENT_KIND; const trimmed = input.trim().toLowerCase(); if (!trimmed) return DEFAULT_AGENT_KIND; const normalized = trimmed .replace(/[\s-]+/g, "_") .replace(/[^a-z0-9_]/g, "") .replace(/_+/g, "_") .replace(/^_+|_+$/g, "") .slice(0, MAX_AGENT_KIND_LENGTH); return normalized || DEFAULT_AGENT_KIND; } export function agentKindLabel(kind: string): string { return KNOWN_AGENT_KIND_LABELS[kind as KnownAgentKind] ?? "Agent"; }