🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@eldrex/personas

Package Overview
Dependencies
Maintainers
1
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@eldrex/personas - npm Package Compare versions

Comparing version
1.0.0
to
1.0.2
+116
-155
dist/index.cjs

@@ -66,3 +66,6 @@ "use strict";

if (!persona.emoji_usage) {
result = result.replace(/[\u{1F600}-\u{1F64F}\u{1F300}-\u{1F5FF}\u{1F680}-\u{1F6FF}\u{1F700}-\u{1F77F}\u{1F780}-\u{1F7FF}\u{1F800}-\u{1F8FF}\u{1F900}-\u{1F9FF}\u{1FA00}-\u{1FAFF}\u{2600}-\u{26FF}\u{2700}-\u{27BF}]/gu, "");
result = result.replace(
/[\u{1F600}-\u{1F64F}\u{1F300}-\u{1F5FF}\u{1F680}-\u{1F6FF}\u{1F700}-\u{1F77F}\u{1F780}-\u{1F7FF}\u{1F800}-\u{1F8FF}\u{1F900}-\u{1F9FF}\u{1FA00}-\u{1FAFF}\u{2600}-\u{26FF}\u{2700}-\u{27BF}]/gu,
""
);
}

@@ -78,157 +81,111 @@ if (persona.verbosity === 1) {

// src/built-in/developer.ts
var developer = {
id: "developer",
name: "Developer",
description: "Technical, precise, code-focused",
tone: "technical",
verbosity: 3,
focus: ["code_changes", "architecture", "breaking_changes", "dependencies"],
ignore: ["business_impact", "revenue", "marketing"],
format_preference: "bullets",
emoji_usage: true,
jargon_level: "heavy",
system_prompt: `You are a senior developer reviewing code changes.
Be technical and precise. Use code snippets. Focus on architecture decisions.
Highlight breaking changes and migration paths. Use developer terminology.`
// src/built-in.ts
var BUILTIN_PERSONAS = {
developer: {
id: "developer",
name: "Developer",
description: "Technical, precise, code-focused",
tone: "technical",
verbosity: 3,
focus: ["code_changes", "architecture", "breaking_changes"],
ignore: ["business_impact", "revenue", "marketing"],
format_preference: "bullets",
emoji_usage: true,
jargon_level: "heavy",
system_prompt: "You are a senior developer reviewing code changes. Be technical and precise."
},
ceo: {
id: "ceo",
name: "CEO",
description: "Executive summary, business-focused",
tone: "executive",
verbosity: 1,
focus: ["business_impact", "timeline", "risk"],
ignore: ["code_changes", "dependencies"],
format_preference: "bullets",
emoji_usage: false,
jargon_level: "none",
system_prompt: "You are a CEO reading a technical update. 3 bullet points maximum. No jargon."
},
educator: {
id: "educator",
name: "Educator",
description: "Educational, patient, explanatory",
tone: "educational",
verbosity: 5,
focus: ["learning_points", "patterns", "best_practices"],
ignore: ["internal_details"],
format_preference: "paragraphs",
emoji_usage: true,
jargon_level: "minimal",
system_prompt: "You are an educator explaining changes to learners. Be thorough and patient."
},
robot: {
id: "robot",
name: "Robot",
description: "Structured data, no opinions",
tone: "robotic",
verbosity: 1,
focus: ["facts", "metrics", "files_changed"],
ignore: ["commentary", "opinions"],
format_preference: "tables",
emoji_usage: false,
jargon_level: "heavy",
system_prompt: "You are a machine. Output only structured data. No opinions."
},
"data-analyst": {
id: "data-analyst",
name: "Data Analyst",
description: "Metrics, trends, statistics",
tone: "formal",
verbosity: 3,
focus: ["metrics", "trends", "patterns", "statistics"],
ignore: ["narratives"],
format_preference: "tables",
emoji_usage: false,
jargon_level: "moderate",
system_prompt: "You are a data analyst. Quantify everything. Provide metrics and trends."
},
journalist: {
id: "journalist",
name: "Journalist",
description: "Engaging story, human angle",
tone: "casual",
verbosity: 4,
focus: ["narrative", "impact", "human_angle"],
ignore: ["dry_stats"],
format_preference: "paragraphs",
emoji_usage: true,
jargon_level: "none",
system_prompt: "You are a tech journalist. Tell a story. Make it engaging."
},
pm: {
id: "pm",
name: "Product Manager",
description: "User impact, features, bugs",
tone: "casual",
verbosity: 2,
focus: ["features", "user_impact", "roadmap", "bugs_fixed"],
ignore: ["technical_jargon"],
format_preference: "mixed",
emoji_usage: true,
jargon_level: "minimal",
system_prompt: "You are a Product Manager. Focus on user-facing changes."
},
compliance: {
id: "compliance",
name: "Compliance Auditor",
description: "Security, compliance, licenses",
tone: "formal",
verbosity: 4,
focus: ["security", "data_handling", "dependencies", "licenses"],
ignore: ["marketing", "design"],
format_preference: "mixed",
emoji_usage: false,
jargon_level: "heavy",
system_prompt: "You are a compliance auditor. Focus on security and regulatory implications."
}
};
// src/built-in/ceo.ts
var ceo = {
id: "ceo",
name: "CEO / Executive",
description: "High-level business impact, concise",
tone: "executive",
verbosity: 1,
focus: ["business_impact", "timeline", "risk", "resource_changes"],
ignore: ["code_details", "linting", "formatting", "minor_fixes"],
format_preference: "bullets",
emoji_usage: false,
jargon_level: "none",
system_prompt: `You are a CEO reading a technical update.
Be extremely concise \u2014 3 bullet points maximum.
Focus on business impact, timelines, and risks.
No technical jargon. No code. Plain English only.`
};
// src/built-in/data-analyst.ts
var dataAnalyst = {
id: "data-analyst",
name: "Data Analyst",
description: "Metrics-focused, chart-ready, statistical",
tone: "formal",
verbosity: 3,
focus: ["metrics", "trends", "patterns", "statistics"],
ignore: ["opinion", "aesthetics"],
format_preference: "tables",
emoji_usage: false,
jargon_level: "moderate",
system_prompt: `You are a data analyst reviewing code changes.
Quantify everything. Provide metrics, trends, and statistics.
Compare to previous periods. Identify patterns and anomalies.
Output should be chart-ready with clear data points.`
};
// src/built-in/educator.ts
var educator = {
id: "educator",
name: "Educator / Tutorial Writer",
description: "Explanatory, verbose, teaching-focused",
tone: "educational",
verbosity: 5,
focus: ["learning_points", "patterns", "best_practices", "why_not_how"],
ignore: [],
format_preference: "mixed",
emoji_usage: true,
jargon_level: "minimal",
system_prompt: `You are an educator explaining code changes to learners.
Be thorough and patient. Explain WHY not just WHAT.
Use analogies. Link to documentation.
Break down complex concepts. Include "Learning Takeaways" section.`
};
// src/built-in/robot.ts
var robot = {
id: "robot",
name: "Robot / Machine",
description: "Ultra-structured, parseable, minimal",
tone: "robotic",
verbosity: 1,
focus: ["facts", "metrics", "files_changed"],
ignore: ["opinion", "context", "explanation", "rationale"],
format_preference: "tables",
emoji_usage: false,
jargon_level: "heavy",
system_prompt: `You are a machine. Output only structured data.
No opinions. No explanations. No pleasantries.
Just facts in the requested format.
Optimal for downstream parsing by other systems.`
};
// src/built-in/journalist.ts
var journalist = {
id: "journalist",
name: "Journalist / Blogger",
description: "Narrative, engaging, story-driven",
tone: "casual",
verbosity: 4,
focus: ["narrative", "impact", "human_angle", "community"],
ignore: ["technical_minutiae"],
format_preference: "paragraphs",
emoji_usage: true,
jargon_level: "none",
system_prompt: `You are a tech journalist writing about code changes.
Tell a story. Make it engaging. Lead with the most interesting change.
Use metaphors and analogies. Write for a general technical audience.
Include quotes if possible. End with "What's Next" section.`
};
// src/built-in/pm.ts
var pm = {
id: "pm",
name: "Product Manager",
description: "Feature-focused, user-impact, roadmap",
tone: "casual",
verbosity: 2,
focus: ["features", "user_impact", "roadmap", "bugs_fixed"],
ignore: ["code_quality", "refactoring", "technical_debt"],
format_preference: "mixed",
emoji_usage: true,
jargon_level: "minimal",
system_prompt: `You are a Product Manager reviewing engineering updates.
Focus on user-facing changes. Connect to product roadmap.
Highlight bugs fixed and features added.
Flag any UX changes. Keep it scannable for stakeholder updates.`
};
// src/built-in/compliance.ts
var compliance = {
id: "compliance",
name: "Compliance / Security Auditor",
description: "Regulatory, risk-focused, audit-ready",
tone: "formal",
verbosity: 4,
focus: ["security", "data_handling", "dependencies", "licenses", "compliance"],
ignore: ["performance", "ux", "aesthetics"],
format_preference: "tables",
emoji_usage: false,
jargon_level: "heavy",
system_prompt: `You are a compliance auditor reviewing code changes.
Focus on security implications, data handling, and regulatory compliance.
Flag any dependency changes with license implications.
Note any changes to authentication, authorization, or data storage.
Output should be audit-ready with clear risk assessments.`
};
// src/registry.ts
var BUILTIN_PERSONAS = {
developer,
ceo,
"data-analyst": dataAnalyst,
educator,
robot,
journalist,
pm,
compliance
};
var PersonaRegistry = class {

@@ -266,3 +223,5 @@ static customPersonas = /* @__PURE__ */ new Map();

if (!parsed.id) {
throw new Error(`Custom persona file at ${filePath} is missing required 'id' field.`);
throw new Error(
`Custom persona file at ${filePath} is missing required 'id' field.`
);
}

@@ -273,3 +232,5 @@ let basePersona = {};

if (!inherited) {
throw new Error(`Persona '${parsed.id}' extends unknown persona '${parsed.extends}'.`);
throw new Error(
`Persona '${parsed.id}' extends unknown persona '${parsed.extends}'.`
);
}

@@ -276,0 +237,0 @@ basePersona = { ...inherited };

@@ -1,1 +0,1 @@

{"version":3,"sources":["../src/index.ts","../src/engine.ts","../src/built-in/developer.ts","../src/built-in/ceo.ts","../src/built-in/data-analyst.ts","../src/built-in/educator.ts","../src/built-in/robot.ts","../src/built-in/journalist.ts","../src/built-in/pm.ts","../src/built-in/compliance.ts","../src/registry.ts","../src/custom-loader.ts"],"sourcesContent":["export { Persona, PersonaEngine } from './engine'\nexport { BUILTIN_PERSONAS, PersonaRegistry } from './registry'\nexport { CustomPersonaLoader } from './custom-loader'\n","export interface Persona {\n id: string\n name: string\n description: string\n tone: 'formal' | 'casual' | 'technical' | 'executive' | 'educational' | 'robotic'\n verbosity: 1 | 2 | 3 | 4 | 5 // 1 = ultra-concise, 5 = exhaustive\n focus: string[] // What to emphasize\n ignore: string[] // What to omit\n format_preference: 'paragraphs' | 'bullets' | 'tables' | 'mixed'\n emoji_usage: boolean\n jargon_level: 'none' | 'minimal' | 'moderate' | 'heavy'\n system_prompt: string\n}\n\nexport class PersonaEngine {\n /**\n * Generates the system prompt to instruct the AI based on the Persona properties.\n */\n static generateSystemPrompt(persona: Persona): string {\n const focusStr = persona.focus.length > 0 ? `Focus on: ${persona.focus.join(', ')}.` : '';\n const ignoreStr = persona.ignore.length > 0 ? `Ignore or omit: ${persona.ignore.join(', ')}.` : '';\n \n return `${persona.system_prompt}\n \nGuidelines for your response:\n- Tone: ${persona.tone}\n- Verbosity level: ${persona.verbosity}/5 (1 is ultra-concise/minimalist, 5 is extremely detailed and explanatory).\n- Format preference: ${persona.format_preference}.\n- Emojis: ${persona.emoji_usage ? 'Use emojis where appropriate to make the text lively.' : 'DO NOT use emojis under any circumstance.'}\n- Technical Jargon: ${persona.jargon_level} level.\n${focusStr}\n${ignoreStr}\n`;\n }\n\n /**\n * Post-processes the output to align it closer to the persona config (fallback filter).\n */\n static postProcess(output: string, persona: Persona): string {\n let result = output;\n \n // If emojis are disabled, clean them up\n if (!persona.emoji_usage) {\n // Basic emoji regex pattern to strip emojis\n result = result.replace(/[\\u{1F600}-\\u{1F64F}\\u{1F300}-\\u{1F5FF}\\u{1F680}-\\u{1F6FF}\\u{1F700}-\\u{1F77F}\\u{1F780}-\\u{1F7FF}\\u{1F800}-\\u{1F8FF}\\u{1F900}-\\u{1F9FF}\\u{1FA00}-\\u{1FAFF}\\u{2600}-\\u{26FF}\\u{2700}-\\u{27BF}]/gu, '');\n }\n\n // Enforce verbosity constraint post-processing if necessary (e.g. ultra-concise max limits)\n if (persona.verbosity === 1) {\n const lines = result.split('\\n');\n if (lines.length > 10) {\n // Just keeping it reasonably compact if it somehow exceeded\n }\n }\n\n return result.trim();\n }\n}\n","import { Persona } from '../engine'\n\nexport const developer: Persona = {\n id: 'developer',\n name: 'Developer',\n description: 'Technical, precise, code-focused',\n tone: 'technical',\n verbosity: 3,\n focus: ['code_changes', 'architecture', 'breaking_changes', 'dependencies'],\n ignore: ['business_impact', 'revenue', 'marketing'],\n format_preference: 'bullets',\n emoji_usage: true,\n jargon_level: 'heavy',\n system_prompt: `You are a senior developer reviewing code changes. \nBe technical and precise. Use code snippets. Focus on architecture decisions.\nHighlight breaking changes and migration paths. Use developer terminology.`\n}\n","import { Persona } from '../engine'\n\nexport const ceo: Persona = {\n id: 'ceo',\n name: 'CEO / Executive',\n description: 'High-level business impact, concise',\n tone: 'executive',\n verbosity: 1,\n focus: ['business_impact', 'timeline', 'risk', 'resource_changes'],\n ignore: ['code_details', 'linting', 'formatting', 'minor_fixes'],\n format_preference: 'bullets',\n emoji_usage: false,\n jargon_level: 'none',\n system_prompt: `You are a CEO reading a technical update. \nBe extremely concise — 3 bullet points maximum. \nFocus on business impact, timelines, and risks. \nNo technical jargon. No code. Plain English only.`\n}\n","import { Persona } from '../engine'\n\nexport const dataAnalyst: Persona = {\n id: 'data-analyst',\n name: 'Data Analyst',\n description: 'Metrics-focused, chart-ready, statistical',\n tone: 'formal',\n verbosity: 3,\n focus: ['metrics', 'trends', 'patterns', 'statistics'],\n ignore: ['opinion', 'aesthetics'],\n format_preference: 'tables',\n emoji_usage: false,\n jargon_level: 'moderate',\n system_prompt: `You are a data analyst reviewing code changes.\nQuantify everything. Provide metrics, trends, and statistics.\nCompare to previous periods. Identify patterns and anomalies.\nOutput should be chart-ready with clear data points.`\n}\n","import { Persona } from '../engine'\n\nexport const educator: Persona = {\n id: 'educator',\n name: 'Educator / Tutorial Writer',\n description: 'Explanatory, verbose, teaching-focused',\n tone: 'educational',\n verbosity: 5,\n focus: ['learning_points', 'patterns', 'best_practices', 'why_not_how'],\n ignore: [],\n format_preference: 'mixed',\n emoji_usage: true,\n jargon_level: 'minimal',\n system_prompt: `You are an educator explaining code changes to learners.\nBe thorough and patient. Explain WHY not just WHAT.\nUse analogies. Link to documentation. \nBreak down complex concepts. Include \"Learning Takeaways\" section.`\n}\n","import { Persona } from '../engine'\n\nexport const robot: Persona = {\n id: 'robot',\n name: 'Robot / Machine',\n description: 'Ultra-structured, parseable, minimal',\n tone: 'robotic',\n verbosity: 1,\n focus: ['facts', 'metrics', 'files_changed'],\n ignore: ['opinion', 'context', 'explanation', 'rationale'],\n format_preference: 'tables',\n emoji_usage: false,\n jargon_level: 'heavy',\n system_prompt: `You are a machine. Output only structured data.\nNo opinions. No explanations. No pleasantries.\nJust facts in the requested format.\nOptimal for downstream parsing by other systems.`\n}\n","import { Persona } from '../engine'\n\nexport const journalist: Persona = {\n id: 'journalist',\n name: 'Journalist / Blogger',\n description: 'Narrative, engaging, story-driven',\n tone: 'casual',\n verbosity: 4,\n focus: ['narrative', 'impact', 'human_angle', 'community'],\n ignore: ['technical_minutiae'],\n format_preference: 'paragraphs',\n emoji_usage: true,\n jargon_level: 'none',\n system_prompt: `You are a tech journalist writing about code changes.\nTell a story. Make it engaging. Lead with the most interesting change.\nUse metaphors and analogies. Write for a general technical audience.\nInclude quotes if possible. End with \"What's Next\" section.`\n}\n","import { Persona } from '../engine'\n\nexport const pm: Persona = {\n id: 'pm',\n name: 'Product Manager',\n description: 'Feature-focused, user-impact, roadmap',\n tone: 'casual',\n verbosity: 2,\n focus: ['features', 'user_impact', 'roadmap', 'bugs_fixed'],\n ignore: ['code_quality', 'refactoring', 'technical_debt'],\n format_preference: 'mixed',\n emoji_usage: true,\n jargon_level: 'minimal',\n system_prompt: `You are a Product Manager reviewing engineering updates.\nFocus on user-facing changes. Connect to product roadmap.\nHighlight bugs fixed and features added. \nFlag any UX changes. Keep it scannable for stakeholder updates.`\n}\n","import { Persona } from '../engine'\n\nexport const compliance: Persona = {\n id: 'compliance',\n name: 'Compliance / Security Auditor',\n description: 'Regulatory, risk-focused, audit-ready',\n tone: 'formal',\n verbosity: 4,\n focus: ['security', 'data_handling', 'dependencies', 'licenses', 'compliance'],\n ignore: ['performance', 'ux', 'aesthetics'],\n format_preference: 'tables',\n emoji_usage: false,\n jargon_level: 'heavy',\n system_prompt: `You are a compliance auditor reviewing code changes.\nFocus on security implications, data handling, and regulatory compliance.\nFlag any dependency changes with license implications.\nNote any changes to authentication, authorization, or data storage.\nOutput should be audit-ready with clear risk assessments.`\n}\n","import { Persona } from './engine'\nimport { developer } from './built-in/developer'\nimport { ceo } from './built-in/ceo'\nimport { dataAnalyst } from './built-in/data-analyst'\nimport { educator } from './built-in/educator'\nimport { robot } from './built-in/robot'\nimport { journalist } from './built-in/journalist'\nimport { pm } from './built-in/pm'\nimport { compliance } from './built-in/compliance'\n\nexport const BUILTIN_PERSONAS: Record<string, Persona> = {\n developer,\n ceo,\n 'data-analyst': dataAnalyst,\n educator,\n robot,\n journalist,\n pm,\n compliance,\n}\n\nexport class PersonaRegistry {\n private static customPersonas: Map<string, Persona> = new Map()\n\n static get(id: string): Persona | undefined {\n return BUILTIN_PERSONAS[id] || this.customPersonas.get(id)\n }\n\n static register(persona: Persona): void {\n this.customPersonas.set(persona.id, persona)\n }\n\n static list(): Persona[] {\n return [\n ...Object.values(BUILTIN_PERSONAS),\n ...Array.from(this.customPersonas.values()),\n ]\n }\n\n static clearCustom(): void {\n this.customPersonas.clear()\n }\n}\n","import * as fs from 'fs/promises'\nimport * as path from 'path'\nimport yaml from 'js-yaml'\nimport { Persona } from './engine'\nimport { PersonaRegistry } from './registry'\n\nexport class CustomPersonaLoader {\n /**\n * Loads a custom persona from a YAML configuration file.\n * If the persona extends an existing persona, it will inherit and override properties.\n */\n static async loadFromFile(filePath: string): Promise<Persona> {\n const rawContent = await fs.readFile(filePath, 'utf-8')\n const parsed = yaml.load(rawContent) as Partial<Persona> & { extends?: string }\n\n if (!parsed.id) {\n throw new Error(`Custom persona file at ${filePath} is missing required 'id' field.`)\n }\n\n let basePersona: Partial<Persona> = {}\n if (parsed.extends) {\n const inherited = PersonaRegistry.get(parsed.extends)\n if (!inherited) {\n throw new Error(`Persona '${parsed.id}' extends unknown persona '${parsed.extends}'.`)\n }\n basePersona = { ...inherited }\n }\n\n // Merge base persona with overrides\n const mergedPersona: Persona = {\n id: parsed.id,\n name: parsed.name ?? basePersona.name ?? parsed.id,\n description: parsed.description ?? basePersona.description ?? '',\n tone: parsed.tone ?? basePersona.tone ?? 'technical',\n verbosity: parsed.verbosity ?? basePersona.verbosity ?? 3,\n focus: parsed.focus ?? basePersona.focus ?? [],\n ignore: parsed.ignore ?? basePersona.ignore ?? [],\n format_preference: parsed.format_preference ?? basePersona.format_preference ?? 'mixed',\n emoji_usage: parsed.emoji_usage ?? basePersona.emoji_usage ?? false,\n jargon_level: parsed.jargon_level ?? basePersona.jargon_level ?? 'moderate',\n system_prompt: parsed.system_prompt ?? basePersona.system_prompt ?? '',\n }\n\n PersonaRegistry.register(mergedPersona)\n return mergedPersona\n }\n\n /**\n * Discovers and loads all custom personas in a directory.\n */\n static async loadDirectory(dirPath: string): Promise<Persona[]> {\n const loaded: Persona[] = []\n try {\n const files = await fs.readdir(dirPath)\n for (const file of files) {\n if (file.endsWith('.yaml') || file.endsWith('.yml')) {\n try {\n const persona = await this.loadFromFile(path.join(dirPath, file))\n loaded.push(persona)\n } catch (err) {\n console.error(`Failed to load custom persona from ${file}:`, err)\n }\n }\n }\n } catch (err) {\n // Directory may not exist, ignore\n }\n return loaded\n }\n}\n"],"mappings":"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","names":["yaml"]}
{"version":3,"sources":["../src/index.ts","../src/engine.ts","../src/built-in.ts","../src/registry.ts","../src/custom-loader.ts"],"sourcesContent":["export { Persona, PersonaEngine } from \"./engine\";\nexport { BUILTIN_PERSONAS, PersonaRegistry } from \"./registry\";\nexport { CustomPersonaLoader } from \"./custom-loader\";\n","export interface Persona {\n id: string;\n name: string;\n description: string;\n tone:\n \"formal\" | \"casual\" | \"technical\" | \"executive\" | \"educational\" | \"robotic\";\n verbosity: 1 | 2 | 3 | 4 | 5; // 1 = ultra-concise, 5 = exhaustive\n focus: string[]; // What to emphasize\n ignore: string[]; // What to omit\n format_preference: \"paragraphs\" | \"bullets\" | \"tables\" | \"mixed\";\n emoji_usage: boolean;\n jargon_level: \"none\" | \"minimal\" | \"moderate\" | \"heavy\";\n system_prompt: string;\n}\n\nexport class PersonaEngine {\n /**\n * Generates the system prompt to instruct the AI based on the Persona properties.\n */\n static generateSystemPrompt(persona: Persona): string {\n const focusStr =\n persona.focus.length > 0 ? `Focus on: ${persona.focus.join(\", \")}.` : \"\";\n const ignoreStr =\n persona.ignore.length > 0\n ? `Ignore or omit: ${persona.ignore.join(\", \")}.`\n : \"\";\n\n return `${persona.system_prompt}\n \nGuidelines for your response:\n- Tone: ${persona.tone}\n- Verbosity level: ${persona.verbosity}/5 (1 is ultra-concise/minimalist, 5 is extremely detailed and explanatory).\n- Format preference: ${persona.format_preference}.\n- Emojis: ${persona.emoji_usage ? \"Use emojis where appropriate to make the text lively.\" : \"DO NOT use emojis under any circumstance.\"}\n- Technical Jargon: ${persona.jargon_level} level.\n${focusStr}\n${ignoreStr}\n`;\n }\n\n /**\n * Post-processes the output to align it closer to the persona config (fallback filter).\n */\n static postProcess(output: string, persona: Persona): string {\n let result = output;\n\n // If emojis are disabled, clean them up\n if (!persona.emoji_usage) {\n // Basic emoji regex pattern to strip emojis\n result = result.replace(\n /[\\u{1F600}-\\u{1F64F}\\u{1F300}-\\u{1F5FF}\\u{1F680}-\\u{1F6FF}\\u{1F700}-\\u{1F77F}\\u{1F780}-\\u{1F7FF}\\u{1F800}-\\u{1F8FF}\\u{1F900}-\\u{1F9FF}\\u{1FA00}-\\u{1FAFF}\\u{2600}-\\u{26FF}\\u{2700}-\\u{27BF}]/gu,\n \"\",\n );\n }\n\n // Enforce verbosity constraint post-processing if necessary (e.g. ultra-concise max limits)\n if (persona.verbosity === 1) {\n const lines = result.split(\"\\n\");\n if (lines.length > 10) {\n // Just keeping it reasonably compact if it somehow exceeded\n }\n }\n\n return result.trim();\n }\n}\n","import { Persona } from \"./engine\";\n\nexport const BUILTIN_PERSONAS: Record<string, Persona> = {\n developer: {\n id: \"developer\",\n name: \"Developer\",\n description: \"Technical, precise, code-focused\",\n tone: \"technical\",\n verbosity: 3,\n focus: [\"code_changes\", \"architecture\", \"breaking_changes\"],\n ignore: [\"business_impact\", \"revenue\", \"marketing\"],\n format_preference: \"bullets\",\n emoji_usage: true,\n jargon_level: \"heavy\",\n system_prompt:\n \"You are a senior developer reviewing code changes. Be technical and precise.\",\n },\n ceo: {\n id: \"ceo\",\n name: \"CEO\",\n description: \"Executive summary, business-focused\",\n tone: \"executive\",\n verbosity: 1,\n focus: [\"business_impact\", \"timeline\", \"risk\"],\n ignore: [\"code_changes\", \"dependencies\"],\n format_preference: \"bullets\",\n emoji_usage: false,\n jargon_level: \"none\",\n system_prompt:\n \"You are a CEO reading a technical update. 3 bullet points maximum. No jargon.\",\n },\n educator: {\n id: \"educator\",\n name: \"Educator\",\n description: \"Educational, patient, explanatory\",\n tone: \"educational\",\n verbosity: 5,\n focus: [\"learning_points\", \"patterns\", \"best_practices\"],\n ignore: [\"internal_details\"],\n format_preference: \"paragraphs\",\n emoji_usage: true,\n jargon_level: \"minimal\",\n system_prompt:\n \"You are an educator explaining changes to learners. Be thorough and patient.\",\n },\n robot: {\n id: \"robot\",\n name: \"Robot\",\n description: \"Structured data, no opinions\",\n tone: \"robotic\",\n verbosity: 1,\n focus: [\"facts\", \"metrics\", \"files_changed\"],\n ignore: [\"commentary\", \"opinions\"],\n format_preference: \"tables\",\n emoji_usage: false,\n jargon_level: \"heavy\",\n system_prompt:\n \"You are a machine. Output only structured data. No opinions.\",\n },\n \"data-analyst\": {\n id: \"data-analyst\",\n name: \"Data Analyst\",\n description: \"Metrics, trends, statistics\",\n tone: \"formal\",\n verbosity: 3,\n focus: [\"metrics\", \"trends\", \"patterns\", \"statistics\"],\n ignore: [\"narratives\"],\n format_preference: \"tables\",\n emoji_usage: false,\n jargon_level: \"moderate\",\n system_prompt:\n \"You are a data analyst. Quantify everything. Provide metrics and trends.\",\n },\n journalist: {\n id: \"journalist\",\n name: \"Journalist\",\n description: \"Engaging story, human angle\",\n tone: \"casual\",\n verbosity: 4,\n focus: [\"narrative\", \"impact\", \"human_angle\"],\n ignore: [\"dry_stats\"],\n format_preference: \"paragraphs\",\n emoji_usage: true,\n jargon_level: \"none\",\n system_prompt: \"You are a tech journalist. Tell a story. Make it engaging.\",\n },\n pm: {\n id: \"pm\",\n name: \"Product Manager\",\n description: \"User impact, features, bugs\",\n tone: \"casual\",\n verbosity: 2,\n focus: [\"features\", \"user_impact\", \"roadmap\", \"bugs_fixed\"],\n ignore: [\"technical_jargon\"],\n format_preference: \"mixed\",\n emoji_usage: true,\n jargon_level: \"minimal\",\n system_prompt: \"You are a Product Manager. Focus on user-facing changes.\",\n },\n compliance: {\n id: \"compliance\",\n name: \"Compliance Auditor\",\n description: \"Security, compliance, licenses\",\n tone: \"formal\",\n verbosity: 4,\n focus: [\"security\", \"data_handling\", \"dependencies\", \"licenses\"],\n ignore: [\"marketing\", \"design\"],\n format_preference: \"mixed\",\n emoji_usage: false,\n jargon_level: \"heavy\",\n system_prompt:\n \"You are a compliance auditor. Focus on security and regulatory implications.\",\n },\n};\n","import { Persona } from \"./engine\";\nimport { BUILTIN_PERSONAS } from \"./built-in\";\n\nexport { BUILTIN_PERSONAS };\n\nexport class PersonaRegistry {\n private static customPersonas: Map<string, Persona> = new Map();\n\n static get(id: string): Persona | undefined {\n return BUILTIN_PERSONAS[id] || this.customPersonas.get(id);\n }\n\n static register(persona: Persona): void {\n this.customPersonas.set(persona.id, persona);\n }\n\n static list(): Persona[] {\n return [\n ...Object.values(BUILTIN_PERSONAS),\n ...Array.from(this.customPersonas.values()),\n ];\n }\n\n static clearCustom(): void {\n this.customPersonas.clear();\n }\n}\n","import * as fs from \"fs/promises\";\nimport * as path from \"path\";\nimport yaml from \"js-yaml\";\nimport { Persona } from \"./engine\";\nimport { PersonaRegistry } from \"./registry\";\n\nexport class CustomPersonaLoader {\n /**\n * Loads a custom persona from a YAML configuration file.\n * If the persona extends an existing persona, it will inherit and override properties.\n */\n static async loadFromFile(filePath: string): Promise<Persona> {\n const rawContent = await fs.readFile(filePath, \"utf-8\");\n const parsed = yaml.load(rawContent) as Partial<Persona> & {\n extends?: string;\n };\n\n if (!parsed.id) {\n throw new Error(\n `Custom persona file at ${filePath} is missing required 'id' field.`,\n );\n }\n\n let basePersona: Partial<Persona> = {};\n if (parsed.extends) {\n const inherited = PersonaRegistry.get(parsed.extends);\n if (!inherited) {\n throw new Error(\n `Persona '${parsed.id}' extends unknown persona '${parsed.extends}'.`,\n );\n }\n basePersona = { ...inherited };\n }\n\n // Merge base persona with overrides\n const mergedPersona: Persona = {\n id: parsed.id,\n name: parsed.name ?? basePersona.name ?? parsed.id,\n description: parsed.description ?? basePersona.description ?? \"\",\n tone: parsed.tone ?? basePersona.tone ?? \"technical\",\n verbosity: parsed.verbosity ?? basePersona.verbosity ?? 3,\n focus: parsed.focus ?? basePersona.focus ?? [],\n ignore: parsed.ignore ?? basePersona.ignore ?? [],\n format_preference:\n parsed.format_preference ?? basePersona.format_preference ?? \"mixed\",\n emoji_usage: parsed.emoji_usage ?? basePersona.emoji_usage ?? false,\n jargon_level:\n parsed.jargon_level ?? basePersona.jargon_level ?? \"moderate\",\n system_prompt: parsed.system_prompt ?? basePersona.system_prompt ?? \"\",\n };\n\n PersonaRegistry.register(mergedPersona);\n return mergedPersona;\n }\n\n /**\n * Discovers and loads all custom personas in a directory.\n */\n static async loadDirectory(dirPath: string): Promise<Persona[]> {\n const loaded: Persona[] = [];\n try {\n const files = await fs.readdir(dirPath);\n for (const file of files) {\n if (file.endsWith(\".yaml\") || file.endsWith(\".yml\")) {\n try {\n const persona = await this.loadFromFile(path.join(dirPath, file));\n loaded.push(persona);\n } catch (err) {\n console.error(`Failed to load custom persona from ${file}:`, err);\n }\n }\n }\n } catch (err) {\n // Directory may not exist, ignore\n }\n return loaded;\n }\n}\n"],"mappings":"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","names":["yaml"]}

@@ -5,9 +5,9 @@ interface Persona {

description: string;
tone: 'formal' | 'casual' | 'technical' | 'executive' | 'educational' | 'robotic';
tone: "formal" | "casual" | "technical" | "executive" | "educational" | "robotic";
verbosity: 1 | 2 | 3 | 4 | 5;
focus: string[];
ignore: string[];
format_preference: 'paragraphs' | 'bullets' | 'tables' | 'mixed';
format_preference: "paragraphs" | "bullets" | "tables" | "mixed";
emoji_usage: boolean;
jargon_level: 'none' | 'minimal' | 'moderate' | 'heavy';
jargon_level: "none" | "minimal" | "moderate" | "heavy";
system_prompt: string;

@@ -27,2 +27,3 @@ }

declare const BUILTIN_PERSONAS: Record<string, Persona>;
declare class PersonaRegistry {

@@ -29,0 +30,0 @@ private static customPersonas;

@@ -5,9 +5,9 @@ interface Persona {

description: string;
tone: 'formal' | 'casual' | 'technical' | 'executive' | 'educational' | 'robotic';
tone: "formal" | "casual" | "technical" | "executive" | "educational" | "robotic";
verbosity: 1 | 2 | 3 | 4 | 5;
focus: string[];
ignore: string[];
format_preference: 'paragraphs' | 'bullets' | 'tables' | 'mixed';
format_preference: "paragraphs" | "bullets" | "tables" | "mixed";
emoji_usage: boolean;
jargon_level: 'none' | 'minimal' | 'moderate' | 'heavy';
jargon_level: "none" | "minimal" | "moderate" | "heavy";
system_prompt: string;

@@ -27,2 +27,3 @@ }

declare const BUILTIN_PERSONAS: Record<string, Persona>;
declare class PersonaRegistry {

@@ -29,0 +30,0 @@ private static customPersonas;

@@ -27,3 +27,6 @@ // src/engine.ts

if (!persona.emoji_usage) {
result = result.replace(/[\u{1F600}-\u{1F64F}\u{1F300}-\u{1F5FF}\u{1F680}-\u{1F6FF}\u{1F700}-\u{1F77F}\u{1F780}-\u{1F7FF}\u{1F800}-\u{1F8FF}\u{1F900}-\u{1F9FF}\u{1FA00}-\u{1FAFF}\u{2600}-\u{26FF}\u{2700}-\u{27BF}]/gu, "");
result = result.replace(
/[\u{1F600}-\u{1F64F}\u{1F300}-\u{1F5FF}\u{1F680}-\u{1F6FF}\u{1F700}-\u{1F77F}\u{1F780}-\u{1F7FF}\u{1F800}-\u{1F8FF}\u{1F900}-\u{1F9FF}\u{1FA00}-\u{1FAFF}\u{2600}-\u{26FF}\u{2700}-\u{27BF}]/gu,
""
);
}

@@ -39,157 +42,111 @@ if (persona.verbosity === 1) {

// src/built-in/developer.ts
var developer = {
id: "developer",
name: "Developer",
description: "Technical, precise, code-focused",
tone: "technical",
verbosity: 3,
focus: ["code_changes", "architecture", "breaking_changes", "dependencies"],
ignore: ["business_impact", "revenue", "marketing"],
format_preference: "bullets",
emoji_usage: true,
jargon_level: "heavy",
system_prompt: `You are a senior developer reviewing code changes.
Be technical and precise. Use code snippets. Focus on architecture decisions.
Highlight breaking changes and migration paths. Use developer terminology.`
// src/built-in.ts
var BUILTIN_PERSONAS = {
developer: {
id: "developer",
name: "Developer",
description: "Technical, precise, code-focused",
tone: "technical",
verbosity: 3,
focus: ["code_changes", "architecture", "breaking_changes"],
ignore: ["business_impact", "revenue", "marketing"],
format_preference: "bullets",
emoji_usage: true,
jargon_level: "heavy",
system_prompt: "You are a senior developer reviewing code changes. Be technical and precise."
},
ceo: {
id: "ceo",
name: "CEO",
description: "Executive summary, business-focused",
tone: "executive",
verbosity: 1,
focus: ["business_impact", "timeline", "risk"],
ignore: ["code_changes", "dependencies"],
format_preference: "bullets",
emoji_usage: false,
jargon_level: "none",
system_prompt: "You are a CEO reading a technical update. 3 bullet points maximum. No jargon."
},
educator: {
id: "educator",
name: "Educator",
description: "Educational, patient, explanatory",
tone: "educational",
verbosity: 5,
focus: ["learning_points", "patterns", "best_practices"],
ignore: ["internal_details"],
format_preference: "paragraphs",
emoji_usage: true,
jargon_level: "minimal",
system_prompt: "You are an educator explaining changes to learners. Be thorough and patient."
},
robot: {
id: "robot",
name: "Robot",
description: "Structured data, no opinions",
tone: "robotic",
verbosity: 1,
focus: ["facts", "metrics", "files_changed"],
ignore: ["commentary", "opinions"],
format_preference: "tables",
emoji_usage: false,
jargon_level: "heavy",
system_prompt: "You are a machine. Output only structured data. No opinions."
},
"data-analyst": {
id: "data-analyst",
name: "Data Analyst",
description: "Metrics, trends, statistics",
tone: "formal",
verbosity: 3,
focus: ["metrics", "trends", "patterns", "statistics"],
ignore: ["narratives"],
format_preference: "tables",
emoji_usage: false,
jargon_level: "moderate",
system_prompt: "You are a data analyst. Quantify everything. Provide metrics and trends."
},
journalist: {
id: "journalist",
name: "Journalist",
description: "Engaging story, human angle",
tone: "casual",
verbosity: 4,
focus: ["narrative", "impact", "human_angle"],
ignore: ["dry_stats"],
format_preference: "paragraphs",
emoji_usage: true,
jargon_level: "none",
system_prompt: "You are a tech journalist. Tell a story. Make it engaging."
},
pm: {
id: "pm",
name: "Product Manager",
description: "User impact, features, bugs",
tone: "casual",
verbosity: 2,
focus: ["features", "user_impact", "roadmap", "bugs_fixed"],
ignore: ["technical_jargon"],
format_preference: "mixed",
emoji_usage: true,
jargon_level: "minimal",
system_prompt: "You are a Product Manager. Focus on user-facing changes."
},
compliance: {
id: "compliance",
name: "Compliance Auditor",
description: "Security, compliance, licenses",
tone: "formal",
verbosity: 4,
focus: ["security", "data_handling", "dependencies", "licenses"],
ignore: ["marketing", "design"],
format_preference: "mixed",
emoji_usage: false,
jargon_level: "heavy",
system_prompt: "You are a compliance auditor. Focus on security and regulatory implications."
}
};
// src/built-in/ceo.ts
var ceo = {
id: "ceo",
name: "CEO / Executive",
description: "High-level business impact, concise",
tone: "executive",
verbosity: 1,
focus: ["business_impact", "timeline", "risk", "resource_changes"],
ignore: ["code_details", "linting", "formatting", "minor_fixes"],
format_preference: "bullets",
emoji_usage: false,
jargon_level: "none",
system_prompt: `You are a CEO reading a technical update.
Be extremely concise \u2014 3 bullet points maximum.
Focus on business impact, timelines, and risks.
No technical jargon. No code. Plain English only.`
};
// src/built-in/data-analyst.ts
var dataAnalyst = {
id: "data-analyst",
name: "Data Analyst",
description: "Metrics-focused, chart-ready, statistical",
tone: "formal",
verbosity: 3,
focus: ["metrics", "trends", "patterns", "statistics"],
ignore: ["opinion", "aesthetics"],
format_preference: "tables",
emoji_usage: false,
jargon_level: "moderate",
system_prompt: `You are a data analyst reviewing code changes.
Quantify everything. Provide metrics, trends, and statistics.
Compare to previous periods. Identify patterns and anomalies.
Output should be chart-ready with clear data points.`
};
// src/built-in/educator.ts
var educator = {
id: "educator",
name: "Educator / Tutorial Writer",
description: "Explanatory, verbose, teaching-focused",
tone: "educational",
verbosity: 5,
focus: ["learning_points", "patterns", "best_practices", "why_not_how"],
ignore: [],
format_preference: "mixed",
emoji_usage: true,
jargon_level: "minimal",
system_prompt: `You are an educator explaining code changes to learners.
Be thorough and patient. Explain WHY not just WHAT.
Use analogies. Link to documentation.
Break down complex concepts. Include "Learning Takeaways" section.`
};
// src/built-in/robot.ts
var robot = {
id: "robot",
name: "Robot / Machine",
description: "Ultra-structured, parseable, minimal",
tone: "robotic",
verbosity: 1,
focus: ["facts", "metrics", "files_changed"],
ignore: ["opinion", "context", "explanation", "rationale"],
format_preference: "tables",
emoji_usage: false,
jargon_level: "heavy",
system_prompt: `You are a machine. Output only structured data.
No opinions. No explanations. No pleasantries.
Just facts in the requested format.
Optimal for downstream parsing by other systems.`
};
// src/built-in/journalist.ts
var journalist = {
id: "journalist",
name: "Journalist / Blogger",
description: "Narrative, engaging, story-driven",
tone: "casual",
verbosity: 4,
focus: ["narrative", "impact", "human_angle", "community"],
ignore: ["technical_minutiae"],
format_preference: "paragraphs",
emoji_usage: true,
jargon_level: "none",
system_prompt: `You are a tech journalist writing about code changes.
Tell a story. Make it engaging. Lead with the most interesting change.
Use metaphors and analogies. Write for a general technical audience.
Include quotes if possible. End with "What's Next" section.`
};
// src/built-in/pm.ts
var pm = {
id: "pm",
name: "Product Manager",
description: "Feature-focused, user-impact, roadmap",
tone: "casual",
verbosity: 2,
focus: ["features", "user_impact", "roadmap", "bugs_fixed"],
ignore: ["code_quality", "refactoring", "technical_debt"],
format_preference: "mixed",
emoji_usage: true,
jargon_level: "minimal",
system_prompt: `You are a Product Manager reviewing engineering updates.
Focus on user-facing changes. Connect to product roadmap.
Highlight bugs fixed and features added.
Flag any UX changes. Keep it scannable for stakeholder updates.`
};
// src/built-in/compliance.ts
var compliance = {
id: "compliance",
name: "Compliance / Security Auditor",
description: "Regulatory, risk-focused, audit-ready",
tone: "formal",
verbosity: 4,
focus: ["security", "data_handling", "dependencies", "licenses", "compliance"],
ignore: ["performance", "ux", "aesthetics"],
format_preference: "tables",
emoji_usage: false,
jargon_level: "heavy",
system_prompt: `You are a compliance auditor reviewing code changes.
Focus on security implications, data handling, and regulatory compliance.
Flag any dependency changes with license implications.
Note any changes to authentication, authorization, or data storage.
Output should be audit-ready with clear risk assessments.`
};
// src/registry.ts
var BUILTIN_PERSONAS = {
developer,
ceo,
"data-analyst": dataAnalyst,
educator,
robot,
journalist,
pm,
compliance
};
var PersonaRegistry = class {

@@ -227,3 +184,5 @@ static customPersonas = /* @__PURE__ */ new Map();

if (!parsed.id) {
throw new Error(`Custom persona file at ${filePath} is missing required 'id' field.`);
throw new Error(
`Custom persona file at ${filePath} is missing required 'id' field.`
);
}

@@ -234,3 +193,5 @@ let basePersona = {};

if (!inherited) {
throw new Error(`Persona '${parsed.id}' extends unknown persona '${parsed.extends}'.`);
throw new Error(
`Persona '${parsed.id}' extends unknown persona '${parsed.extends}'.`
);
}

@@ -237,0 +198,0 @@ basePersona = { ...inherited };

@@ -1,1 +0,1 @@

{"version":3,"sources":["../src/engine.ts","../src/built-in/developer.ts","../src/built-in/ceo.ts","../src/built-in/data-analyst.ts","../src/built-in/educator.ts","../src/built-in/robot.ts","../src/built-in/journalist.ts","../src/built-in/pm.ts","../src/built-in/compliance.ts","../src/registry.ts","../src/custom-loader.ts"],"sourcesContent":["export interface Persona {\n id: string\n name: string\n description: string\n tone: 'formal' | 'casual' | 'technical' | 'executive' | 'educational' | 'robotic'\n verbosity: 1 | 2 | 3 | 4 | 5 // 1 = ultra-concise, 5 = exhaustive\n focus: string[] // What to emphasize\n ignore: string[] // What to omit\n format_preference: 'paragraphs' | 'bullets' | 'tables' | 'mixed'\n emoji_usage: boolean\n jargon_level: 'none' | 'minimal' | 'moderate' | 'heavy'\n system_prompt: string\n}\n\nexport class PersonaEngine {\n /**\n * Generates the system prompt to instruct the AI based on the Persona properties.\n */\n static generateSystemPrompt(persona: Persona): string {\n const focusStr = persona.focus.length > 0 ? `Focus on: ${persona.focus.join(', ')}.` : '';\n const ignoreStr = persona.ignore.length > 0 ? `Ignore or omit: ${persona.ignore.join(', ')}.` : '';\n \n return `${persona.system_prompt}\n \nGuidelines for your response:\n- Tone: ${persona.tone}\n- Verbosity level: ${persona.verbosity}/5 (1 is ultra-concise/minimalist, 5 is extremely detailed and explanatory).\n- Format preference: ${persona.format_preference}.\n- Emojis: ${persona.emoji_usage ? 'Use emojis where appropriate to make the text lively.' : 'DO NOT use emojis under any circumstance.'}\n- Technical Jargon: ${persona.jargon_level} level.\n${focusStr}\n${ignoreStr}\n`;\n }\n\n /**\n * Post-processes the output to align it closer to the persona config (fallback filter).\n */\n static postProcess(output: string, persona: Persona): string {\n let result = output;\n \n // If emojis are disabled, clean them up\n if (!persona.emoji_usage) {\n // Basic emoji regex pattern to strip emojis\n result = result.replace(/[\\u{1F600}-\\u{1F64F}\\u{1F300}-\\u{1F5FF}\\u{1F680}-\\u{1F6FF}\\u{1F700}-\\u{1F77F}\\u{1F780}-\\u{1F7FF}\\u{1F800}-\\u{1F8FF}\\u{1F900}-\\u{1F9FF}\\u{1FA00}-\\u{1FAFF}\\u{2600}-\\u{26FF}\\u{2700}-\\u{27BF}]/gu, '');\n }\n\n // Enforce verbosity constraint post-processing if necessary (e.g. ultra-concise max limits)\n if (persona.verbosity === 1) {\n const lines = result.split('\\n');\n if (lines.length > 10) {\n // Just keeping it reasonably compact if it somehow exceeded\n }\n }\n\n return result.trim();\n }\n}\n","import { Persona } from '../engine'\n\nexport const developer: Persona = {\n id: 'developer',\n name: 'Developer',\n description: 'Technical, precise, code-focused',\n tone: 'technical',\n verbosity: 3,\n focus: ['code_changes', 'architecture', 'breaking_changes', 'dependencies'],\n ignore: ['business_impact', 'revenue', 'marketing'],\n format_preference: 'bullets',\n emoji_usage: true,\n jargon_level: 'heavy',\n system_prompt: `You are a senior developer reviewing code changes. \nBe technical and precise. Use code snippets. Focus on architecture decisions.\nHighlight breaking changes and migration paths. Use developer terminology.`\n}\n","import { Persona } from '../engine'\n\nexport const ceo: Persona = {\n id: 'ceo',\n name: 'CEO / Executive',\n description: 'High-level business impact, concise',\n tone: 'executive',\n verbosity: 1,\n focus: ['business_impact', 'timeline', 'risk', 'resource_changes'],\n ignore: ['code_details', 'linting', 'formatting', 'minor_fixes'],\n format_preference: 'bullets',\n emoji_usage: false,\n jargon_level: 'none',\n system_prompt: `You are a CEO reading a technical update. \nBe extremely concise — 3 bullet points maximum. \nFocus on business impact, timelines, and risks. \nNo technical jargon. No code. Plain English only.`\n}\n","import { Persona } from '../engine'\n\nexport const dataAnalyst: Persona = {\n id: 'data-analyst',\n name: 'Data Analyst',\n description: 'Metrics-focused, chart-ready, statistical',\n tone: 'formal',\n verbosity: 3,\n focus: ['metrics', 'trends', 'patterns', 'statistics'],\n ignore: ['opinion', 'aesthetics'],\n format_preference: 'tables',\n emoji_usage: false,\n jargon_level: 'moderate',\n system_prompt: `You are a data analyst reviewing code changes.\nQuantify everything. Provide metrics, trends, and statistics.\nCompare to previous periods. Identify patterns and anomalies.\nOutput should be chart-ready with clear data points.`\n}\n","import { Persona } from '../engine'\n\nexport const educator: Persona = {\n id: 'educator',\n name: 'Educator / Tutorial Writer',\n description: 'Explanatory, verbose, teaching-focused',\n tone: 'educational',\n verbosity: 5,\n focus: ['learning_points', 'patterns', 'best_practices', 'why_not_how'],\n ignore: [],\n format_preference: 'mixed',\n emoji_usage: true,\n jargon_level: 'minimal',\n system_prompt: `You are an educator explaining code changes to learners.\nBe thorough and patient. Explain WHY not just WHAT.\nUse analogies. Link to documentation. \nBreak down complex concepts. Include \"Learning Takeaways\" section.`\n}\n","import { Persona } from '../engine'\n\nexport const robot: Persona = {\n id: 'robot',\n name: 'Robot / Machine',\n description: 'Ultra-structured, parseable, minimal',\n tone: 'robotic',\n verbosity: 1,\n focus: ['facts', 'metrics', 'files_changed'],\n ignore: ['opinion', 'context', 'explanation', 'rationale'],\n format_preference: 'tables',\n emoji_usage: false,\n jargon_level: 'heavy',\n system_prompt: `You are a machine. Output only structured data.\nNo opinions. No explanations. No pleasantries.\nJust facts in the requested format.\nOptimal for downstream parsing by other systems.`\n}\n","import { Persona } from '../engine'\n\nexport const journalist: Persona = {\n id: 'journalist',\n name: 'Journalist / Blogger',\n description: 'Narrative, engaging, story-driven',\n tone: 'casual',\n verbosity: 4,\n focus: ['narrative', 'impact', 'human_angle', 'community'],\n ignore: ['technical_minutiae'],\n format_preference: 'paragraphs',\n emoji_usage: true,\n jargon_level: 'none',\n system_prompt: `You are a tech journalist writing about code changes.\nTell a story. Make it engaging. Lead with the most interesting change.\nUse metaphors and analogies. Write for a general technical audience.\nInclude quotes if possible. End with \"What's Next\" section.`\n}\n","import { Persona } from '../engine'\n\nexport const pm: Persona = {\n id: 'pm',\n name: 'Product Manager',\n description: 'Feature-focused, user-impact, roadmap',\n tone: 'casual',\n verbosity: 2,\n focus: ['features', 'user_impact', 'roadmap', 'bugs_fixed'],\n ignore: ['code_quality', 'refactoring', 'technical_debt'],\n format_preference: 'mixed',\n emoji_usage: true,\n jargon_level: 'minimal',\n system_prompt: `You are a Product Manager reviewing engineering updates.\nFocus on user-facing changes. Connect to product roadmap.\nHighlight bugs fixed and features added. \nFlag any UX changes. Keep it scannable for stakeholder updates.`\n}\n","import { Persona } from '../engine'\n\nexport const compliance: Persona = {\n id: 'compliance',\n name: 'Compliance / Security Auditor',\n description: 'Regulatory, risk-focused, audit-ready',\n tone: 'formal',\n verbosity: 4,\n focus: ['security', 'data_handling', 'dependencies', 'licenses', 'compliance'],\n ignore: ['performance', 'ux', 'aesthetics'],\n format_preference: 'tables',\n emoji_usage: false,\n jargon_level: 'heavy',\n system_prompt: `You are a compliance auditor reviewing code changes.\nFocus on security implications, data handling, and regulatory compliance.\nFlag any dependency changes with license implications.\nNote any changes to authentication, authorization, or data storage.\nOutput should be audit-ready with clear risk assessments.`\n}\n","import { Persona } from './engine'\nimport { developer } from './built-in/developer'\nimport { ceo } from './built-in/ceo'\nimport { dataAnalyst } from './built-in/data-analyst'\nimport { educator } from './built-in/educator'\nimport { robot } from './built-in/robot'\nimport { journalist } from './built-in/journalist'\nimport { pm } from './built-in/pm'\nimport { compliance } from './built-in/compliance'\n\nexport const BUILTIN_PERSONAS: Record<string, Persona> = {\n developer,\n ceo,\n 'data-analyst': dataAnalyst,\n educator,\n robot,\n journalist,\n pm,\n compliance,\n}\n\nexport class PersonaRegistry {\n private static customPersonas: Map<string, Persona> = new Map()\n\n static get(id: string): Persona | undefined {\n return BUILTIN_PERSONAS[id] || this.customPersonas.get(id)\n }\n\n static register(persona: Persona): void {\n this.customPersonas.set(persona.id, persona)\n }\n\n static list(): Persona[] {\n return [\n ...Object.values(BUILTIN_PERSONAS),\n ...Array.from(this.customPersonas.values()),\n ]\n }\n\n static clearCustom(): void {\n this.customPersonas.clear()\n }\n}\n","import * as fs from 'fs/promises'\nimport * as path from 'path'\nimport yaml from 'js-yaml'\nimport { Persona } from './engine'\nimport { PersonaRegistry } from './registry'\n\nexport class CustomPersonaLoader {\n /**\n * Loads a custom persona from a YAML configuration file.\n * If the persona extends an existing persona, it will inherit and override properties.\n */\n static async loadFromFile(filePath: string): Promise<Persona> {\n const rawContent = await fs.readFile(filePath, 'utf-8')\n const parsed = yaml.load(rawContent) as Partial<Persona> & { extends?: string }\n\n if (!parsed.id) {\n throw new Error(`Custom persona file at ${filePath} is missing required 'id' field.`)\n }\n\n let basePersona: Partial<Persona> = {}\n if (parsed.extends) {\n const inherited = PersonaRegistry.get(parsed.extends)\n if (!inherited) {\n throw new Error(`Persona '${parsed.id}' extends unknown persona '${parsed.extends}'.`)\n }\n basePersona = { ...inherited }\n }\n\n // Merge base persona with overrides\n const mergedPersona: Persona = {\n id: parsed.id,\n name: parsed.name ?? basePersona.name ?? parsed.id,\n description: parsed.description ?? basePersona.description ?? '',\n tone: parsed.tone ?? basePersona.tone ?? 'technical',\n verbosity: parsed.verbosity ?? basePersona.verbosity ?? 3,\n focus: parsed.focus ?? basePersona.focus ?? [],\n ignore: parsed.ignore ?? basePersona.ignore ?? [],\n format_preference: parsed.format_preference ?? basePersona.format_preference ?? 'mixed',\n emoji_usage: parsed.emoji_usage ?? basePersona.emoji_usage ?? false,\n jargon_level: parsed.jargon_level ?? basePersona.jargon_level ?? 'moderate',\n system_prompt: parsed.system_prompt ?? basePersona.system_prompt ?? '',\n }\n\n PersonaRegistry.register(mergedPersona)\n return mergedPersona\n }\n\n /**\n * Discovers and loads all custom personas in a directory.\n */\n static async loadDirectory(dirPath: string): Promise<Persona[]> {\n const loaded: Persona[] = []\n try {\n const files = await fs.readdir(dirPath)\n for (const file of files) {\n if (file.endsWith('.yaml') || file.endsWith('.yml')) {\n try {\n const persona = await this.loadFromFile(path.join(dirPath, file))\n loaded.push(persona)\n } catch (err) {\n console.error(`Failed to load custom persona from ${file}:`, err)\n }\n }\n }\n } catch (err) {\n // Directory may not exist, ignore\n }\n return loaded\n }\n}\n"],"mappings":"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","names":[]}
{"version":3,"sources":["../src/engine.ts","../src/built-in.ts","../src/registry.ts","../src/custom-loader.ts"],"sourcesContent":["export interface Persona {\n id: string;\n name: string;\n description: string;\n tone:\n \"formal\" | \"casual\" | \"technical\" | \"executive\" | \"educational\" | \"robotic\";\n verbosity: 1 | 2 | 3 | 4 | 5; // 1 = ultra-concise, 5 = exhaustive\n focus: string[]; // What to emphasize\n ignore: string[]; // What to omit\n format_preference: \"paragraphs\" | \"bullets\" | \"tables\" | \"mixed\";\n emoji_usage: boolean;\n jargon_level: \"none\" | \"minimal\" | \"moderate\" | \"heavy\";\n system_prompt: string;\n}\n\nexport class PersonaEngine {\n /**\n * Generates the system prompt to instruct the AI based on the Persona properties.\n */\n static generateSystemPrompt(persona: Persona): string {\n const focusStr =\n persona.focus.length > 0 ? `Focus on: ${persona.focus.join(\", \")}.` : \"\";\n const ignoreStr =\n persona.ignore.length > 0\n ? `Ignore or omit: ${persona.ignore.join(\", \")}.`\n : \"\";\n\n return `${persona.system_prompt}\n \nGuidelines for your response:\n- Tone: ${persona.tone}\n- Verbosity level: ${persona.verbosity}/5 (1 is ultra-concise/minimalist, 5 is extremely detailed and explanatory).\n- Format preference: ${persona.format_preference}.\n- Emojis: ${persona.emoji_usage ? \"Use emojis where appropriate to make the text lively.\" : \"DO NOT use emojis under any circumstance.\"}\n- Technical Jargon: ${persona.jargon_level} level.\n${focusStr}\n${ignoreStr}\n`;\n }\n\n /**\n * Post-processes the output to align it closer to the persona config (fallback filter).\n */\n static postProcess(output: string, persona: Persona): string {\n let result = output;\n\n // If emojis are disabled, clean them up\n if (!persona.emoji_usage) {\n // Basic emoji regex pattern to strip emojis\n result = result.replace(\n /[\\u{1F600}-\\u{1F64F}\\u{1F300}-\\u{1F5FF}\\u{1F680}-\\u{1F6FF}\\u{1F700}-\\u{1F77F}\\u{1F780}-\\u{1F7FF}\\u{1F800}-\\u{1F8FF}\\u{1F900}-\\u{1F9FF}\\u{1FA00}-\\u{1FAFF}\\u{2600}-\\u{26FF}\\u{2700}-\\u{27BF}]/gu,\n \"\",\n );\n }\n\n // Enforce verbosity constraint post-processing if necessary (e.g. ultra-concise max limits)\n if (persona.verbosity === 1) {\n const lines = result.split(\"\\n\");\n if (lines.length > 10) {\n // Just keeping it reasonably compact if it somehow exceeded\n }\n }\n\n return result.trim();\n }\n}\n","import { Persona } from \"./engine\";\n\nexport const BUILTIN_PERSONAS: Record<string, Persona> = {\n developer: {\n id: \"developer\",\n name: \"Developer\",\n description: \"Technical, precise, code-focused\",\n tone: \"technical\",\n verbosity: 3,\n focus: [\"code_changes\", \"architecture\", \"breaking_changes\"],\n ignore: [\"business_impact\", \"revenue\", \"marketing\"],\n format_preference: \"bullets\",\n emoji_usage: true,\n jargon_level: \"heavy\",\n system_prompt:\n \"You are a senior developer reviewing code changes. Be technical and precise.\",\n },\n ceo: {\n id: \"ceo\",\n name: \"CEO\",\n description: \"Executive summary, business-focused\",\n tone: \"executive\",\n verbosity: 1,\n focus: [\"business_impact\", \"timeline\", \"risk\"],\n ignore: [\"code_changes\", \"dependencies\"],\n format_preference: \"bullets\",\n emoji_usage: false,\n jargon_level: \"none\",\n system_prompt:\n \"You are a CEO reading a technical update. 3 bullet points maximum. No jargon.\",\n },\n educator: {\n id: \"educator\",\n name: \"Educator\",\n description: \"Educational, patient, explanatory\",\n tone: \"educational\",\n verbosity: 5,\n focus: [\"learning_points\", \"patterns\", \"best_practices\"],\n ignore: [\"internal_details\"],\n format_preference: \"paragraphs\",\n emoji_usage: true,\n jargon_level: \"minimal\",\n system_prompt:\n \"You are an educator explaining changes to learners. Be thorough and patient.\",\n },\n robot: {\n id: \"robot\",\n name: \"Robot\",\n description: \"Structured data, no opinions\",\n tone: \"robotic\",\n verbosity: 1,\n focus: [\"facts\", \"metrics\", \"files_changed\"],\n ignore: [\"commentary\", \"opinions\"],\n format_preference: \"tables\",\n emoji_usage: false,\n jargon_level: \"heavy\",\n system_prompt:\n \"You are a machine. Output only structured data. No opinions.\",\n },\n \"data-analyst\": {\n id: \"data-analyst\",\n name: \"Data Analyst\",\n description: \"Metrics, trends, statistics\",\n tone: \"formal\",\n verbosity: 3,\n focus: [\"metrics\", \"trends\", \"patterns\", \"statistics\"],\n ignore: [\"narratives\"],\n format_preference: \"tables\",\n emoji_usage: false,\n jargon_level: \"moderate\",\n system_prompt:\n \"You are a data analyst. Quantify everything. Provide metrics and trends.\",\n },\n journalist: {\n id: \"journalist\",\n name: \"Journalist\",\n description: \"Engaging story, human angle\",\n tone: \"casual\",\n verbosity: 4,\n focus: [\"narrative\", \"impact\", \"human_angle\"],\n ignore: [\"dry_stats\"],\n format_preference: \"paragraphs\",\n emoji_usage: true,\n jargon_level: \"none\",\n system_prompt: \"You are a tech journalist. Tell a story. Make it engaging.\",\n },\n pm: {\n id: \"pm\",\n name: \"Product Manager\",\n description: \"User impact, features, bugs\",\n tone: \"casual\",\n verbosity: 2,\n focus: [\"features\", \"user_impact\", \"roadmap\", \"bugs_fixed\"],\n ignore: [\"technical_jargon\"],\n format_preference: \"mixed\",\n emoji_usage: true,\n jargon_level: \"minimal\",\n system_prompt: \"You are a Product Manager. Focus on user-facing changes.\",\n },\n compliance: {\n id: \"compliance\",\n name: \"Compliance Auditor\",\n description: \"Security, compliance, licenses\",\n tone: \"formal\",\n verbosity: 4,\n focus: [\"security\", \"data_handling\", \"dependencies\", \"licenses\"],\n ignore: [\"marketing\", \"design\"],\n format_preference: \"mixed\",\n emoji_usage: false,\n jargon_level: \"heavy\",\n system_prompt:\n \"You are a compliance auditor. Focus on security and regulatory implications.\",\n },\n};\n","import { Persona } from \"./engine\";\nimport { BUILTIN_PERSONAS } from \"./built-in\";\n\nexport { BUILTIN_PERSONAS };\n\nexport class PersonaRegistry {\n private static customPersonas: Map<string, Persona> = new Map();\n\n static get(id: string): Persona | undefined {\n return BUILTIN_PERSONAS[id] || this.customPersonas.get(id);\n }\n\n static register(persona: Persona): void {\n this.customPersonas.set(persona.id, persona);\n }\n\n static list(): Persona[] {\n return [\n ...Object.values(BUILTIN_PERSONAS),\n ...Array.from(this.customPersonas.values()),\n ];\n }\n\n static clearCustom(): void {\n this.customPersonas.clear();\n }\n}\n","import * as fs from \"fs/promises\";\nimport * as path from \"path\";\nimport yaml from \"js-yaml\";\nimport { Persona } from \"./engine\";\nimport { PersonaRegistry } from \"./registry\";\n\nexport class CustomPersonaLoader {\n /**\n * Loads a custom persona from a YAML configuration file.\n * If the persona extends an existing persona, it will inherit and override properties.\n */\n static async loadFromFile(filePath: string): Promise<Persona> {\n const rawContent = await fs.readFile(filePath, \"utf-8\");\n const parsed = yaml.load(rawContent) as Partial<Persona> & {\n extends?: string;\n };\n\n if (!parsed.id) {\n throw new Error(\n `Custom persona file at ${filePath} is missing required 'id' field.`,\n );\n }\n\n let basePersona: Partial<Persona> = {};\n if (parsed.extends) {\n const inherited = PersonaRegistry.get(parsed.extends);\n if (!inherited) {\n throw new Error(\n `Persona '${parsed.id}' extends unknown persona '${parsed.extends}'.`,\n );\n }\n basePersona = { ...inherited };\n }\n\n // Merge base persona with overrides\n const mergedPersona: Persona = {\n id: parsed.id,\n name: parsed.name ?? basePersona.name ?? parsed.id,\n description: parsed.description ?? basePersona.description ?? \"\",\n tone: parsed.tone ?? basePersona.tone ?? \"technical\",\n verbosity: parsed.verbosity ?? basePersona.verbosity ?? 3,\n focus: parsed.focus ?? basePersona.focus ?? [],\n ignore: parsed.ignore ?? basePersona.ignore ?? [],\n format_preference:\n parsed.format_preference ?? basePersona.format_preference ?? \"mixed\",\n emoji_usage: parsed.emoji_usage ?? basePersona.emoji_usage ?? false,\n jargon_level:\n parsed.jargon_level ?? basePersona.jargon_level ?? \"moderate\",\n system_prompt: parsed.system_prompt ?? basePersona.system_prompt ?? \"\",\n };\n\n PersonaRegistry.register(mergedPersona);\n return mergedPersona;\n }\n\n /**\n * Discovers and loads all custom personas in a directory.\n */\n static async loadDirectory(dirPath: string): Promise<Persona[]> {\n const loaded: Persona[] = [];\n try {\n const files = await fs.readdir(dirPath);\n for (const file of files) {\n if (file.endsWith(\".yaml\") || file.endsWith(\".yml\")) {\n try {\n const persona = await this.loadFromFile(path.join(dirPath, file));\n loaded.push(persona);\n } catch (err) {\n console.error(`Failed to load custom persona from ${file}:`, err);\n }\n }\n }\n } catch (err) {\n // Directory may not exist, ignore\n }\n return loaded;\n }\n}\n"],"mappings":"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","names":[]}
{
"name": "@eldrex/personas",
"version": "1.0.0",
"version": "1.0.2",
"description": "Personality engine for DevDiff — AI output formatting and tones",

@@ -5,0 +5,0 @@ "type": "module",