CoolFace
Apppublic

Leon4gr45/builder

sourceHugging Facemitupdated 2d agoView on Hugging Face
0likes
tool-analytics.ts75 linesDownload Raw Back to telemetry
1/**2 * Safe extraction of analytics properties from tool call arguments.3 * Only whitelisted, enumerated values are emitted — no file paths, contents, or user text.4 */5 6import { getBuiltInSkillIds } from '@/lib/vfs/skills/registry';7import { isBuiltInInterviewTemplateId } from '@/lib/interview/templates';8 9/** Built-in interview template ids may be reported; custom ones are anonymized. */10export function bucketInterviewTemplateId(id: string): string {11  return isBuiltInInterviewTemplateId(id) ? id : 'custom';12}13 14const BASH_COMMAND_WHITELIST = new Set([15  'cat', 'head', 'tail', 'nl', 'ls', 'tree', 'grep', 'rg', 'find',16  'mkdir', 'mv', 'cp', 'rm', 'rmdir', 'touch', 'sed', 'ss', 'echo', 'wc',17  'sort', 'uniq', 'tr', 'curl', 'sleep', 'sqlite3', 'build', 'status', 'agent', 'delegate',18  'preview', 'python', 'python3', 'lua', 'runtime', 'generate-image'19]);20 21function extractShellAnalytics(args: Record<string, unknown>): Record<string, unknown> {22  const result: Record<string, unknown> = {};23  const rawCmd = (args.command ?? args.cmd) as string | undefined;24  const cmd = typeof rawCmd === 'string' ? rawCmd.trim() : '';25  if (cmd) {26    const firstWord = cmd.split(/\s+/)[0];27    result.command = BASH_COMMAND_WHITELIST.has(firstWord) ? firstWord : 'other';28    result.has_pipe = cmd.includes(' | ');29    result.has_redirect = / >>? /.test(cmd);30  }31  return result;32}33 34export function extractToolAnalytics(35  toolName: string,36  argsJson: string,37  success: boolean38): Record<string, unknown> {39  const base: Record<string, unknown> = { tool: toolName, success };40 41  let args: Record<string, unknown>;42  try {43    args = JSON.parse(argsJson);44    if (!args || typeof args !== 'object' || Array.isArray(args)) return base;45  } catch {46    return base;47  }48 49  if (toolName === 'bash' || toolName === 'shell') {50    return { ...base, ...extractShellAnalytics(args) };51  }52  return base;53}54 55/**56 * Detect a skill-file read from a bash cat command. Returns the built-in57 * skill id, 'custom' for user skills, or null when not a skill read.58 * Never returns the path itself.59 */60export function extractSkillRead(argsJson: string): { skill: string } | null {61  try {62    const args = JSON.parse(argsJson);63    const raw = (args?.command ?? args?.cmd) as string | undefined;64    if (typeof raw !== 'string') return null;65    const cmd = raw.trim();66    if (!cmd.startsWith('cat ')) return null;67    const m = cmd.match(/\/\.skills\/([A-Za-z0-9_-]+)\.md/);68    if (!m) return null;69    const id = m[1];70    return { skill: getBuiltInSkillIds().includes(id) ? id : 'custom' };71  } catch {72    return null;73  }74}75