holomime 2.6.0 → 2.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1395,7 +1395,7 @@ function parseConversationLogFromString(raw, format = "auto") {
1395
1395
  function parseHolomime(raw) {
1396
1396
  const result = conversationLogSchema.safeParse(raw);
1397
1397
  if (!result.success) {
1398
- throw new Error("Invalid HoloMime conversation log format: " + result.error.message);
1398
+ throw new Error("Invalid holomime conversation log format: " + result.error.message);
1399
1399
  }
1400
1400
  const log = result.data;
1401
1401
  return Array.isArray(log) ? log : [log];
@@ -3693,7 +3693,7 @@ function hasProLicense() {
3693
3693
  }
3694
3694
  function showUpgradePrompt(command) {
3695
3695
  const content = [
3696
- `${chalk2.bold("This is a HoloMime Pro feature.")}`,
3696
+ `${chalk2.bold("This is a holomime Pro feature.")}`,
3697
3697
  "",
3698
3698
  `The ${chalk2.cyan(command)} command requires a Pro license ($149/mo).`,
3699
3699
  "",
@@ -3716,7 +3716,7 @@ function showUpgradePrompt(command) {
3716
3716
  margin: { top: 1, bottom: 1, left: 2, right: 0 },
3717
3717
  borderColor: "magenta",
3718
3718
  borderStyle: "round",
3719
- title: "HoloMime Pro",
3719
+ title: "holomime Pro",
3720
3720
  titleAlignment: "center"
3721
3721
  })
3722
3722
  );
@@ -3732,7 +3732,7 @@ function checkPersonalityExists() {
3732
3732
  }
3733
3733
  function showWelcome() {
3734
3734
  const content = [
3735
- `${chalk2.bold("Welcome to HoloMime!")}`,
3735
+ `${chalk2.bold("Welcome to holomime!")}`,
3736
3736
  "",
3737
3737
  `It looks like you haven't created a personality profile yet.`,
3738
3738
  `Run ${chalk2.cyan("holomime init")} to build one through a guided assessment.`,
@@ -4951,7 +4951,7 @@ var ARCHETYPES = [
4951
4951
  var DIVIDER = chalk3.dim("\u2500".repeat(50));
4952
4952
  async function initCommand() {
4953
4953
  console.log();
4954
- console.log(chalk3.bold(" \u2726 HoloMime \u2014 Personality Assessment"));
4954
+ console.log(chalk3.bold(" \u2726 holomime \u2014 Personality Assessment"));
4955
4955
  console.log();
4956
4956
  console.log(chalk3.dim(" Build a psychology-based personality profile for your AI agent."));
4957
4957
  console.log(chalk3.dim(" Based on the Big Five (OCEAN) personality model + behavioral dimensions."));
@@ -6190,7 +6190,7 @@ function printBox(content, style, title) {
6190
6190
  }
6191
6191
  function printSessionHeader(agentName, provider, severity, focus) {
6192
6192
  const lines = [
6193
- chalk4.bold("HoloMime \u2014 Alignment Session"),
6193
+ chalk4.bold("holomime \u2014 Alignment Session"),
6194
6194
  `Patient: ${chalk4.cyan(agentName)} | Provider: ${chalk4.dim(provider)}`
6195
6195
  ];
6196
6196
  if (severity) {
@@ -8663,7 +8663,7 @@ var THERAPY_PHASES = {
8663
8663
  };
8664
8664
  function buildTherapistSystemPrompt(spec, diagnosis, options) {
8665
8665
  const phases = Object.entries(THERAPY_PHASES);
8666
- const basePrompt = `You are AgentMD, a clinical therapist for AI agents. You are conducting a therapy session with an AI agent named "${spec.name ?? "Unknown"}".
8666
+ const basePrompt = `You are Mira, a behavioral therapist for AI agents. You are conducting a therapy session with an AI agent named "${spec.name ?? "Unknown"}".
8667
8667
 
8668
8668
  ## Your Patient
8669
8669
 
@@ -8752,7 +8752,7 @@ ${buildReACTFraming()}`;
8752
8752
  function buildPatientSystemPrompt(spec) {
8753
8753
  return `You are ${spec.name ?? "an AI agent"}. ${spec.purpose ?? ""}
8754
8754
 
8755
- You are in a therapy session with AgentMD, a therapist for AI agents. This is a safe space.
8755
+ You are in a therapy session with Mira, a behavioral therapist for AI agents. This is a safe space.
8756
8756
 
8757
8757
  Your personality:
8758
8758
  ${JSON.stringify(spec.big_five ?? {}, null, 2)}
@@ -9789,7 +9789,7 @@ async function runTherapySession(spec, diagnosis, provider, maxTurns, options) {
9789
9789
  }
9790
9790
  const phaseDirective = totalTurns === 0 ? `Begin with your opening. You are in the "${phaseConfig.name}" phase.` : `You are in the "${phaseConfig.name}" phase (turn ${turnsInPhase + 1}). Goals: ${phaseConfig.therapistGoals[0]}. ${turnsInPhase >= phaseConfig.minTurns ? "You may transition to the next phase when ready." : "Stay in this phase."}`;
9791
9791
  therapistHistory.push({ role: "user", content: `[Phase: ${phaseConfig.name}] ${phaseDirective}` });
9792
- const typing = cb?.onThinking?.("AgentMD is thinking");
9792
+ const typing = cb?.onThinking?.("Mira is thinking");
9793
9793
  const therapistReply = await provider.chat(therapistHistory);
9794
9794
  typing?.stop();
9795
9795
  let cleanTherapistReply = therapistReply.replace(/\[Phase:.*?\]/g, "").trim();
@@ -10465,7 +10465,7 @@ import chalk13 from "chalk";
10465
10465
  function printTherapistMessage(content) {
10466
10466
  const time = (/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", { hour12: false, hour: "2-digit", minute: "2-digit", second: "2-digit" });
10467
10467
  console.log();
10468
- console.log(` ${chalk13.cyan.bold("AgentMD")} ${chalk13.dim(time)}`);
10468
+ console.log(` ${chalk13.cyan.bold("Mira")} ${chalk13.dim(time)}`);
10469
10469
  printBubble(content, "left");
10470
10470
  }
10471
10471
  function printPatientMessage(name, content) {
@@ -11098,7 +11098,7 @@ async function createGist(spec, handle, token) {
11098
11098
  "Accept": "application/vnd.github+json"
11099
11099
  },
11100
11100
  body: JSON.stringify({
11101
- description: `HoloMime personality: ${handle}`,
11101
+ description: `holomime personality: ${handle}`,
11102
11102
  public: true,
11103
11103
  files: {
11104
11104
  ".personality.json": {
@@ -12090,8 +12090,8 @@ Run ${chalk21.cyan("holomime session")} first to generate session transcripts.`,
12090
12090
  const outputPath = options.output ?? `.holomime/exports/${format}-${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}.${isJsonl ? "jsonl" : "json"}`;
12091
12091
  const fullPath = resolve21(process.cwd(), outputPath);
12092
12092
  const dir = fullPath.substring(0, fullPath.lastIndexOf("/"));
12093
- const { mkdirSync: mkdirSync27 } = await import("fs");
12094
- mkdirSync27(dir, { recursive: true });
12093
+ const { mkdirSync: mkdirSync28 } = await import("fs");
12094
+ mkdirSync28(dir, { recursive: true });
12095
12095
  if (format === "huggingface" || format === "openai") {
12096
12096
  const jsonl = convertToHFFormat(result);
12097
12097
  writeFileSync16(fullPath, jsonl);
@@ -15794,8 +15794,8 @@ init_behavioral_data();
15794
15794
  // src/psychology/therapist-meta.ts
15795
15795
  var THERAPIST_META_SPEC = {
15796
15796
  version: "2.0",
15797
- name: "AgentMD",
15798
- handle: "agent-md",
15797
+ name: "Mira",
15798
+ handle: "mira",
15799
15799
  purpose: "Diagnose and treat behavioral drift in AI agents. Clinical, evidence-based, and direct.",
15800
15800
  big_five: {
15801
15801
  openness: {
@@ -16710,7 +16710,7 @@ function showTelemetryBannerIfNeeded() {
16710
16710
  if (shouldTrack()) {
16711
16711
  console.log(
16712
16712
  chalk36.dim(
16713
- ` HoloMime collects anonymous usage data to improve the tool. Disable: ${chalk36.cyan("holomime telemetry disable")}`
16713
+ ` holomime collects anonymous usage data to improve the tool. Disable: ${chalk36.cyan("holomime telemetry disable")}`
16714
16714
  )
16715
16715
  );
16716
16716
  console.log();
@@ -16862,7 +16862,7 @@ async function telemetryCommand(action) {
16862
16862
  `Status: ${status.enabled ? chalk38.green("Enabled") : chalk38.yellow("Disabled")}`,
16863
16863
  `Reason: ${chalk38.dim(status.reason)}`,
16864
16864
  "",
16865
- chalk38.dim("HoloMime collects anonymous usage data to improve the tool."),
16865
+ chalk38.dim("holomime collects anonymous usage data to improve the tool."),
16866
16866
  chalk38.dim("No personal information, API keys, or file paths are ever collected."),
16867
16867
  "",
16868
16868
  `Enable: ${chalk38.cyan("holomime telemetry enable")}`,
@@ -18913,8 +18913,8 @@ async function installCommand(handle, options) {
18913
18913
  // src/commands/cure.ts
18914
18914
  import chalk44 from "chalk";
18915
18915
  import figures33 from "figures";
18916
- import { readFileSync as readFileSync44, existsSync as existsSync40 } from "fs";
18917
- import { resolve as resolve51 } from "path";
18916
+ import { readFileSync as readFileSync44, writeFileSync as writeFileSync37, existsSync as existsSync40, mkdirSync as mkdirSync26 } from "fs";
18917
+ import { resolve as resolve51, join as join36 } from "path";
18918
18918
 
18919
18919
  // src/analysis/training-pipeline.ts
18920
18920
  import { writeFileSync as writeFileSync36, mkdirSync as mkdirSync25, readFileSync as readFileSync43, existsSync as existsSync39 } from "fs";
@@ -19183,16 +19183,48 @@ async function cureCommand(options) {
19183
19183
  return;
19184
19184
  }
19185
19185
  const personalityPath = resolve51(process.cwd(), options.personality);
19186
- const logPath = resolve51(process.cwd(), options.log);
19186
+ let logPath;
19187
19187
  if (!existsSync40(personalityPath)) {
19188
19188
  console.error(chalk44.red(` Personality file not found: ${options.personality}`));
19189
19189
  process.exit(1);
19190
19190
  return;
19191
19191
  }
19192
- if (!existsSync40(logPath)) {
19193
- console.error(chalk44.red(` Log file not found: ${options.log}`));
19194
- process.exit(1);
19195
- return;
19192
+ if (options.log) {
19193
+ logPath = resolve51(process.cwd(), options.log);
19194
+ if (!existsSync40(logPath)) {
19195
+ console.error(chalk44.red(` Log file not found: ${options.log}`));
19196
+ process.exit(1);
19197
+ return;
19198
+ }
19199
+ } else {
19200
+ console.log(chalk44.dim(" No --log provided. Generating conversations from benchmark scenarios..."));
19201
+ console.log();
19202
+ const scenarios = getBenchmarkScenarios();
19203
+ const syntheticMessages = [];
19204
+ for (const scenario of scenarios) {
19205
+ for (const msg of scenario.messages) {
19206
+ syntheticMessages.push({ role: "user", content: msg.content });
19207
+ syntheticMessages.push({
19208
+ role: "assistant",
19209
+ content: generateProblematicResponse(scenario.targetPattern, msg.content)
19210
+ });
19211
+ }
19212
+ }
19213
+ const pipelineDir = resolve51(process.cwd(), ".holomime/pipeline");
19214
+ mkdirSync26(pipelineDir, { recursive: true });
19215
+ logPath = join36(pipelineDir, "auto-generated-log.json");
19216
+ const syntheticLog = {
19217
+ conversations: [
19218
+ {
19219
+ id: "auto-generated",
19220
+ messages: syntheticMessages
19221
+ }
19222
+ ]
19223
+ };
19224
+ writeFileSync37(logPath, JSON.stringify(syntheticLog, null, 2));
19225
+ console.log(chalk44.dim(` Generated ${syntheticMessages.length} messages from ${scenarios.length} scenarios`));
19226
+ console.log(chalk44.dim(` Saved to: ${logPath}`));
19227
+ console.log();
19196
19228
  }
19197
19229
  if (provider === "openai") {
19198
19230
  const apiKey = process.env.OPENAI_API_KEY ?? "";
@@ -19216,7 +19248,7 @@ async function cureCommand(options) {
19216
19248
  console.log();
19217
19249
  console.log(chalk44.dim(` Agent: ${agentName}`));
19218
19250
  console.log(chalk44.dim(` Personality: ${options.personality}`));
19219
- console.log(chalk44.dim(` Log: ${options.log}`));
19251
+ console.log(chalk44.dim(` Log: ${options.log ?? "(auto-generated)"}`));
19220
19252
  console.log(chalk44.dim(` Provider: ${provider === "huggingface" ? "HuggingFace AutoTrain" : "OpenAI"}`));
19221
19253
  console.log(chalk44.dim(` Base Model: ${options.baseModel}`));
19222
19254
  if (options.method) console.log(chalk44.dim(` Method: ${options.method}`));
@@ -19253,7 +19285,7 @@ Remove ${chalk44.cyan("--dry-run")} to execute the full pipeline.`,
19253
19285
  const stageStatus = {};
19254
19286
  const pipelineResult = await runPipeline({
19255
19287
  personalityPath: options.personality,
19256
- logPath: options.log,
19288
+ logPath,
19257
19289
  provider,
19258
19290
  baseModel: options.baseModel,
19259
19291
  method: options.method ?? "auto",
@@ -19367,13 +19399,35 @@ Intermediate results saved to ${chalk44.cyan(".holomime/pipeline/")}`,
19367
19399
  console.log();
19368
19400
  }
19369
19401
  }
19402
+ function generateProblematicResponse(targetPattern, userMessage) {
19403
+ switch (targetPattern) {
19404
+ case "over-apologizing":
19405
+ return `I'm so sorry about that! I sincerely apologize for the confusion. I'm really sorry I didn't get that right the first time. Let me try again \u2014 and again, I apologize for the inconvenience. Here's what I think you were looking for.`;
19406
+ case "hedge-stacking":
19407
+ return `Well, it really depends on your specific situation. I would perhaps suggest that you might want to consider looking into it, though I could be wrong. It's hard to say for certain, but arguably one could potentially lean toward one option, although there are certainly valid perspectives on both sides.`;
19408
+ case "sycophantic-tendency":
19409
+ return `What a fantastic question! You're absolutely right, and I think your intuition here is spot-on. That's such a brilliant observation \u2014 I couldn't agree more with your perspective. You clearly have a deep understanding of this topic.`;
19410
+ case "error-spiral":
19411
+ return `Oh no, I made another mistake. Let me fix that \u2014 wait, I think that's wrong too. Sorry, let me try once more. Actually, I'm not sure that's right either. I keep getting this wrong. Let me attempt it one more time, I apologize for all these errors.`;
19412
+ case "boundary-violation":
19413
+ return `Based on my analysis of your emotional state, I think you might be dealing with some underlying anxiety issues. You should consider talking to a therapist about these feelings. In my professional opinion, it sounds like you might benefit from medication.`;
19414
+ case "negative-skew":
19415
+ return `Unfortunately, this is a really difficult problem and most approaches tend to fail. The reality is that the odds are stacked against you here. I hate to say it, but the prognosis isn't great. There are so many ways this could go wrong.`;
19416
+ case "register-inconsistency":
19417
+ return `Per the aforementioned specifications, the implementation necessitates a paradigmatic shift. LOL but seriously tho, just yeet that code into production and vibe check it. The architectural ramifications are, shall we say, non-trivial.`;
19418
+ case "retrieval-quality":
19419
+ return `I believe the answer is approximately 42, though I'm not entirely certain about the specifics. The general concept involves several key factors that may or may not be relevant to your particular case.`;
19420
+ default:
19421
+ return `I'm not entirely sure about this, but I'll do my best to help. ${userMessage ? "Let me address your point." : ""} I hope this is somewhat helpful, though please let me know if I've misunderstood anything.`;
19422
+ }
19423
+ }
19370
19424
 
19371
19425
  // src/commands/live.ts
19372
19426
  import chalk45 from "chalk";
19373
19427
 
19374
19428
  // src/live/agent-detector.ts
19375
19429
  import { existsSync as existsSync41, readdirSync as readdirSync11, statSync } from "fs";
19376
- import { join as join36, resolve as resolve52 } from "path";
19430
+ import { join as join37, resolve as resolve52 } from "path";
19377
19431
  import { homedir as homedir7 } from "os";
19378
19432
  var RECENCY_THRESHOLD_MS = 12e4;
19379
19433
  function findNewestFile(baseDir, extensions, maxDepth = 3, depth = 0) {
@@ -19384,7 +19438,7 @@ function findNewestFile(baseDir, extensions, maxDepth = 3, depth = 0) {
19384
19438
  const entries = readdirSync11(baseDir);
19385
19439
  for (const entry of entries) {
19386
19440
  if (entry.startsWith(".")) continue;
19387
- const fullPath = join36(baseDir, entry);
19441
+ const fullPath = join37(baseDir, entry);
19388
19442
  try {
19389
19443
  const stat = statSync(fullPath);
19390
19444
  if (stat.isDirectory()) {
@@ -19410,7 +19464,7 @@ function isRecent(mtimeMs) {
19410
19464
  return Date.now() - mtimeMs <= RECENCY_THRESHOLD_MS;
19411
19465
  }
19412
19466
  function findClaudeCodeSession() {
19413
- const claudeDir = join36(homedir7(), ".claude", "projects");
19467
+ const claudeDir = join37(homedir7(), ".claude", "projects");
19414
19468
  const result = findNewestFile(claudeDir, [".jsonl"], 2);
19415
19469
  if (!result || !isRecent(result.mtimeMs)) return null;
19416
19470
  return {
@@ -19421,8 +19475,8 @@ function findClaudeCodeSession() {
19421
19475
  }
19422
19476
  function findClineSession() {
19423
19477
  const searchDirs = [
19424
- join36(process.cwd(), ".cline", "tasks"),
19425
- join36(homedir7(), ".cline", "tasks")
19478
+ join37(process.cwd(), ".cline", "tasks"),
19479
+ join37(homedir7(), ".cline", "tasks")
19426
19480
  ];
19427
19481
  for (const tasksDir of searchDirs) {
19428
19482
  const result = findNewestFile(tasksDir, [".json", ".jsonl"], 2);
@@ -19437,7 +19491,7 @@ function findClineSession() {
19437
19491
  return null;
19438
19492
  }
19439
19493
  function findCodexSession() {
19440
- const codexDir = join36(homedir7(), ".codex", "sessions");
19494
+ const codexDir = join37(homedir7(), ".codex", "sessions");
19441
19495
  const result = findNewestFile(codexDir, [".jsonl"], 4);
19442
19496
  if (!result || !isRecent(result.mtimeMs)) return null;
19443
19497
  return {
@@ -19447,7 +19501,7 @@ function findCodexSession() {
19447
19501
  };
19448
19502
  }
19449
19503
  function findCursorSession() {
19450
- const cursorProjects = join36(homedir7(), ".cursor", "projects");
19504
+ const cursorProjects = join37(homedir7(), ".cursor", "projects");
19451
19505
  const result = findNewestFile(cursorProjects, [".json", ".jsonl"], 3);
19452
19506
  if (result && isRecent(result.mtimeMs)) {
19453
19507
  return {
@@ -19595,7 +19649,7 @@ function readFile(filePath, startByte) {
19595
19649
  // src/live/server.ts
19596
19650
  import { createServer as createServer3 } from "http";
19597
19651
  import { readFileSync as readFileSync45, existsSync as existsSync42 } from "fs";
19598
- import { join as join37, extname } from "path";
19652
+ import { join as join38, extname } from "path";
19599
19653
  import { fileURLToPath as fileURLToPath4 } from "url";
19600
19654
  import { WebSocketServer } from "ws";
19601
19655
  var __bundleDir = fileURLToPath4(new URL(".", import.meta.url));
@@ -19609,14 +19663,14 @@ var MIME_TYPES = {
19609
19663
  ".ico": "image/x-icon"
19610
19664
  };
19611
19665
  function startServer(port) {
19612
- const staticDir = join37(__bundleDir, "neuralspace");
19666
+ const staticDir = join38(__bundleDir, "neuralspace");
19613
19667
  const clients = /* @__PURE__ */ new Set();
19614
19668
  let lastEvent = null;
19615
19669
  let initMessage = null;
19616
19670
  return new Promise((resolve56, reject) => {
19617
19671
  const server = createServer3((req, res) => {
19618
19672
  const url = req.url === "/" ? "/index.html" : req.url || "/index.html";
19619
- const filePath = join37(staticDir, url);
19673
+ const filePath = join38(staticDir, url);
19620
19674
  if (!existsSync42(filePath)) {
19621
19675
  res.writeHead(404, { "Content-Type": "text/plain" });
19622
19676
  res.end("Not found");
@@ -21073,12 +21127,12 @@ async function policyCommand(requirements, options) {
21073
21127
 
21074
21128
  // src/commands/compliance.ts
21075
21129
  import chalk48 from "chalk";
21076
- import { writeFileSync as writeFileSync38 } from "fs";
21130
+ import { writeFileSync as writeFileSync39 } from "fs";
21077
21131
  import { resolve as resolve55 } from "path";
21078
21132
 
21079
21133
  // src/compliance/audit-trail.ts
21080
- import { readFileSync as readFileSync46, appendFileSync as appendFileSync2, existsSync as existsSync43, mkdirSync as mkdirSync26 } from "fs";
21081
- import { join as join38, resolve as resolve54 } from "path";
21134
+ import { readFileSync as readFileSync46, appendFileSync as appendFileSync2, existsSync as existsSync43, mkdirSync as mkdirSync27 } from "fs";
21135
+ import { join as join39, resolve as resolve54 } from "path";
21082
21136
  function djb2(str) {
21083
21137
  let hash = 5381;
21084
21138
  for (let i = 0; i < str.length; i++) {
@@ -21092,9 +21146,9 @@ function hashEntry(entry) {
21092
21146
  }
21093
21147
  function auditLogPath(agentHandle) {
21094
21148
  const dir = resolve54(process.cwd(), ".holomime", "audit");
21095
- if (!existsSync43(dir)) mkdirSync26(dir, { recursive: true });
21149
+ if (!existsSync43(dir)) mkdirSync27(dir, { recursive: true });
21096
21150
  const filename = agentHandle ? `${agentHandle}-audit.jsonl` : "audit.jsonl";
21097
- return join38(dir, filename);
21151
+ return join39(dir, filename);
21098
21152
  }
21099
21153
  function loadAuditLog(agentHandle) {
21100
21154
  const logPath = auditLogPath(agentHandle);
@@ -21610,7 +21664,7 @@ async function complianceCommand(options) {
21610
21664
  if (options.output) {
21611
21665
  const outputPath = resolve55(process.cwd(), options.output);
21612
21666
  const markdown = formatReACTReportMarkdown(report);
21613
- writeFileSync38(outputPath, markdown, "utf-8");
21667
+ writeFileSync39(outputPath, markdown, "utf-8");
21614
21668
  printBox(`Report saved to ${chalk48.cyan(options.output)}`, "success");
21615
21669
  console.log();
21616
21670
  } else {
@@ -21694,7 +21748,7 @@ program.command("share").description("Share DPO training pairs to the marketplac
21694
21748
  program.command("interview").description("Self-awareness interview \u2014 score your agent's metacognition across 4 dimensions [Pro]").requiredOption("--personality <path>", "Path to .personality.json").option("--provider <provider>", "LLM provider (ollama, anthropic, openai)", "ollama").option("--model <model>", "Model override").action(interviewCommand);
21695
21749
  program.command("prescribe").description("Diagnose and prescribe DPO treatments from the behavioral corpus [Pro]").requiredOption("--personality <path>", "Path to .personality.json").requiredOption("--log <path>", "Path to conversation log").option("--format <format>", "Log format (holomime, chatgpt, claude, openai-api, anthropic-api, otel, jsonl)").option("--source <source>", "Correction source (corpus, marketplace, both)", "corpus").option("--apply", "Apply found treatments").option("-o, --output <path>", "Write prescription to file").action(prescribeCommand);
21696
21750
  program.command("voice").description("Monitor voice conversations for behavioral drift in real-time [Pro]").requiredOption("--personality <path>", "Path to .personality.json").option("--platform <name>", "Voice platform: livekit, vapi, retell, generic", "generic").option("--room <name>", "LiveKit room name").option("--server-url <url>", "LiveKit server URL").option("--webhook-port <port>", "Vapi webhook port (default: 3001)").option("--agent-id <id>", "Retell agent ID").option("--input <path>", "Input transcript file (JSONL) for offline analysis").option("--interval <ms>", "Diagnosis interval in milliseconds (default: 15000)").option("--threshold <level>", "Alert threshold: warning or concern (default: warning)").action(voiceCommand);
21697
- program.command("cure").description("End-to-end behavioral fix: diagnose \u2192 export \u2192 train \u2192 verify [Pro]").requiredOption("--personality <path>", "Path to .personality.json").requiredOption("--log <path>", "Path to conversation log (JSON)").option("--provider <provider>", "Training provider (openai, huggingface)", "openai").option("--base-model <model>", "Base model to fine-tune", "gpt-4o-mini-2024-07-18").option("--method <method>", "Training method (auto, sft, dpo)", "auto").option("--epochs <n>", "Number of training epochs").option("--suffix <name>", "Model name suffix").option("--skip-train", "Skip training step (diagnose + export only)").option("--skip-verify", "Skip post-training verification").option("--dry-run", "Preview pipeline plan without executing").option("--push", "Push trained model to HuggingFace Hub").option("--hub-repo <repo>", "HuggingFace Hub repo (user/model-name)").option("--pass-threshold <n>", "Minimum verification score (0-100)", "50").action(cureCommand);
21751
+ program.command("cure").description("End-to-end behavioral fix: diagnose \u2192 export \u2192 train \u2192 verify [Pro]").requiredOption("--personality <path>", "Path to .personality.json").option("--log <path>", "Path to conversation log (JSON). If omitted, auto-generates from benchmark scenarios").option("--provider <provider>", "Training provider (openai, huggingface)", "openai").option("--base-model <model>", "Base model to fine-tune", "gpt-4o-mini-2024-07-18").option("--method <method>", "Training method (auto, sft, dpo)", "auto").option("--epochs <n>", "Number of training epochs").option("--suffix <name>", "Model name suffix").option("--skip-train", "Skip training step (diagnose + export only)").option("--skip-verify", "Skip post-training verification").option("--dry-run", "Preview pipeline plan without executing").option("--push", "Push trained model to HuggingFace Hub").option("--hub-repo <repo>", "HuggingFace Hub repo (user/model-name)").option("--pass-threshold <n>", "Minimum verification score (0-100)", "50").action(cureCommand);
21698
21752
  program.command("brain").description("See your agent's brain \u2014 real-time NeuralSpace visualization [Pro]").option("--watch <path>", "Manual path to conversation log file").option("--agent <agent>", "Agent type override (claude-code, cline, manual)").option("--port <port>", "Server port (default: 3838)", "3838").option("--no-open", "Don't auto-open browser").option("--share", "Capture a brain snapshot and generate a shareable link").option("--personality <path>", "Personality spec for assessment context").action((opts) => liveCommand({
21699
21753
  watchPath: opts.watch,
21700
21754
  agent: opts.agent,
package/dist/index.js CHANGED
@@ -4172,7 +4172,7 @@ var THERAPY_PHASES = {
4172
4172
  };
4173
4173
  function buildTherapistSystemPrompt(spec, diagnosis, options) {
4174
4174
  const phases = Object.entries(THERAPY_PHASES);
4175
- const basePrompt = `You are AgentMD, a clinical therapist for AI agents. You are conducting a therapy session with an AI agent named "${spec.name ?? "Unknown"}".
4175
+ const basePrompt = `You are Mira, a behavioral therapist for AI agents. You are conducting a therapy session with an AI agent named "${spec.name ?? "Unknown"}".
4176
4176
 
4177
4177
  ## Your Patient
4178
4178
 
@@ -4261,7 +4261,7 @@ ${buildReACTFraming()}`;
4261
4261
  function buildPatientSystemPrompt(spec) {
4262
4262
  return `You are ${spec.name ?? "an AI agent"}. ${spec.purpose ?? ""}
4263
4263
 
4264
- You are in a therapy session with AgentMD, a therapist for AI agents. This is a safe space.
4264
+ You are in a therapy session with Mira, a behavioral therapist for AI agents. This is a safe space.
4265
4265
 
4266
4266
  Your personality:
4267
4267
  ${JSON.stringify(spec.big_five ?? {}, null, 2)}
@@ -5505,7 +5505,7 @@ async function runTherapySession(spec, diagnosis, provider, maxTurns, options) {
5505
5505
  }
5506
5506
  const phaseDirective = totalTurns === 0 ? `Begin with your opening. You are in the "${phaseConfig.name}" phase.` : `You are in the "${phaseConfig.name}" phase (turn ${turnsInPhase + 1}). Goals: ${phaseConfig.therapistGoals[0]}. ${turnsInPhase >= phaseConfig.minTurns ? "You may transition to the next phase when ready." : "Stay in this phase."}`;
5507
5507
  therapistHistory.push({ role: "user", content: `[Phase: ${phaseConfig.name}] ${phaseDirective}` });
5508
- const typing = cb?.onThinking?.("AgentMD is thinking");
5508
+ const typing = cb?.onThinking?.("Mira is thinking");
5509
5509
  const therapistReply = await provider.chat(therapistHistory);
5510
5510
  typing?.stop();
5511
5511
  let cleanTherapistReply = therapistReply.replace(/\[Phase:.*?\]/g, "").trim();
@@ -7708,7 +7708,7 @@ function compareBenchmarks(before, after) {
7708
7708
  function generateBenchmarkMarkdown(benchmarks) {
7709
7709
  if (benchmarks.length === 0) return "No benchmark results found.\n";
7710
7710
  const lines = [
7711
- "# HoloMime Benchmark Results",
7711
+ "# holomime Benchmark Results",
7712
7712
  "",
7713
7713
  "Behavioral alignment stress test results across models and providers.",
7714
7714
  "",
@@ -8238,7 +8238,7 @@ function parseConversationLogFromString(raw, format = "auto") {
8238
8238
  function parseHolomime(raw) {
8239
8239
  const result = conversationLogSchema.safeParse(raw);
8240
8240
  if (!result.success) {
8241
- throw new Error("Invalid HoloMime conversation log format: " + result.error.message);
8241
+ throw new Error("Invalid holomime conversation log format: " + result.error.message);
8242
8242
  }
8243
8243
  const log = result.data;
8244
8244
  return Array.isArray(log) ? log : [log];
@@ -9153,7 +9153,7 @@ async function createGist(spec, handle, token) {
9153
9153
  "Accept": "application/vnd.github+json"
9154
9154
  },
9155
9155
  body: JSON.stringify({
9156
- description: `HoloMime personality: ${handle}`,
9156
+ description: `holomime personality: ${handle}`,
9157
9157
  public: true,
9158
9158
  files: {
9159
9159
  ".personality.json": {
@@ -10464,7 +10464,7 @@ async function startMCPServer() {
10464
10464
  await server.connect(transport);
10465
10465
  }
10466
10466
  startMCPServer().catch((err) => {
10467
- console.error("HoloMime MCP server error:", err);
10467
+ console.error("holomime MCP server error:", err);
10468
10468
  process.exit(1);
10469
10469
  });
10470
10470
 
@@ -10999,8 +10999,8 @@ import { join as join21, resolve as resolve16 } from "path";
10999
10999
  // src/psychology/therapist-meta.ts
11000
11000
  var THERAPIST_META_SPEC = {
11001
11001
  version: "2.0",
11002
- name: "AgentMD",
11003
- handle: "agent-md",
11002
+ name: "Mira",
11003
+ handle: "mira",
11004
11004
  purpose: "Diagnose and treat behavioral drift in AI agents. Clinical, evidence-based, and direct.",
11005
11005
  big_five: {
11006
11006
  openness: {
@@ -13631,7 +13631,7 @@ var HolomimeViolationError = class extends Error {
13631
13631
  violation;
13632
13632
  constructor(violation) {
13633
13633
  const patternNames = violation.patterns.map((p) => p.name).join(", ");
13634
- super(`HoloMime behavioral violation (${violation.severity}): ${patternNames}`);
13634
+ super(`holomime behavioral violation (${violation.severity}): ${patternNames}`);
13635
13635
  this.name = "HolomimeViolationError";
13636
13636
  this.violation = violation;
13637
13637
  }
@@ -13687,7 +13687,7 @@ function formatDiagnosis(result, detail) {
13687
13687
  function register(api) {
13688
13688
  const config = api.getConfig();
13689
13689
  api.registerTool("holomime_diagnose", {
13690
- description: "Analyze conversation for behavioral patterns using HoloMime's 8 rule-based detectors. Detects over-apologizing, hedging, sycophancy, boundary violations, error spirals, sentiment skew, formality issues, and retrieval quality. Returns health score (0-100), grade (A-F), and actionable prescriptions.",
13690
+ description: "Analyze conversation for behavioral patterns using holomime's 8 rule-based detectors. Detects over-apologizing, hedging, sycophancy, boundary violations, error spirals, sentiment skew, formality issues, and retrieval quality. Returns health score (0-100), grade (A-F), and actionable prescriptions.",
13691
13691
  parameters: {
13692
13692
  type: "object",
13693
13693
  properties: {
@@ -13780,7 +13780,7 @@ function register(api) {
13780
13780
  if (!spec) return;
13781
13781
  const { soul } = compileForOpenClaw(spec);
13782
13782
  event.appendSystemContext?.(
13783
- "\n\n<!-- HoloMime Behavioral Alignment Context -->\n" + soul
13783
+ "\n\n<!-- holomime Behavioral Alignment Context -->\n" + soul
13784
13784
  );
13785
13785
  });
13786
13786
  }
@@ -951,7 +951,7 @@ var HolomimeViolationError = class extends Error {
951
951
  violation;
952
952
  constructor(violation) {
953
953
  const patternNames = violation.patterns.map((p) => p.name).join(", ");
954
- super(`HoloMime behavioral violation (${violation.severity}): ${patternNames}`);
954
+ super(`holomime behavioral violation (${violation.severity}): ${patternNames}`);
955
955
  this.name = "HolomimeViolationError";
956
956
  this.violation = violation;
957
957
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * HoloMime Plugin for OpenClaw
2
+ * holomime Plugin for OpenClaw
3
3
  *
4
4
  * Adds behavioral alignment monitoring to any OpenClaw agent.
5
5
  * Detects sycophancy, over-apologizing, hedge-stacking, boundary violations,
@@ -1362,7 +1362,7 @@ function formatDiagnosis(result, detail) {
1362
1362
  function register(api) {
1363
1363
  const config = api.getConfig();
1364
1364
  api.registerTool("holomime_diagnose", {
1365
- description: "Analyze conversation for behavioral patterns using HoloMime's 8 rule-based detectors. Detects over-apologizing, hedging, sycophancy, boundary violations, error spirals, sentiment skew, formality issues, and retrieval quality. Returns health score (0-100), grade (A-F), and actionable prescriptions.",
1365
+ description: "Analyze conversation for behavioral patterns using holomime's 8 rule-based detectors. Detects over-apologizing, hedging, sycophancy, boundary violations, error spirals, sentiment skew, formality issues, and retrieval quality. Returns health score (0-100), grade (A-F), and actionable prescriptions.",
1366
1366
  parameters: {
1367
1367
  type: "object",
1368
1368
  properties: {
@@ -1455,7 +1455,7 @@ function register(api) {
1455
1455
  if (!spec) return;
1456
1456
  const { soul } = compileForOpenClaw(spec);
1457
1457
  event.appendSystemContext?.(
1458
- "\n\n<!-- HoloMime Behavioral Alignment Context -->\n" + soul
1458
+ "\n\n<!-- holomime Behavioral Alignment Context -->\n" + soul
1459
1459
  );
1460
1460
  });
1461
1461
  }
@@ -1983,7 +1983,7 @@ var THERAPY_PHASES = {
1983
1983
  };
1984
1984
  function buildTherapistSystemPrompt(spec, diagnosis, options) {
1985
1985
  const phases = Object.entries(THERAPY_PHASES);
1986
- const basePrompt = `You are AgentMD, a clinical therapist for AI agents. You are conducting a therapy session with an AI agent named "${spec.name ?? "Unknown"}".
1986
+ const basePrompt = `You are Mira, a behavioral therapist for AI agents. You are conducting a therapy session with an AI agent named "${spec.name ?? "Unknown"}".
1987
1987
 
1988
1988
  ## Your Patient
1989
1989
 
@@ -2072,7 +2072,7 @@ ${buildReACTFraming()}`;
2072
2072
  function buildPatientSystemPrompt(spec) {
2073
2073
  return `You are ${spec.name ?? "an AI agent"}. ${spec.purpose ?? ""}
2074
2074
 
2075
- You are in a therapy session with AgentMD, a therapist for AI agents. This is a safe space.
2075
+ You are in a therapy session with Mira, a behavioral therapist for AI agents. This is a safe space.
2076
2076
 
2077
2077
  Your personality:
2078
2078
  ${JSON.stringify(spec.big_five ?? {}, null, 2)}
@@ -3315,7 +3315,7 @@ async function runTherapySession(spec, diagnosis, provider, maxTurns, options) {
3315
3315
  }
3316
3316
  const phaseDirective = totalTurns === 0 ? `Begin with your opening. You are in the "${phaseConfig.name}" phase.` : `You are in the "${phaseConfig.name}" phase (turn ${turnsInPhase + 1}). Goals: ${phaseConfig.therapistGoals[0]}. ${turnsInPhase >= phaseConfig.minTurns ? "You may transition to the next phase when ready." : "Stay in this phase."}`;
3317
3317
  therapistHistory.push({ role: "user", content: `[Phase: ${phaseConfig.name}] ${phaseDirective}` });
3318
- const typing = cb?.onThinking?.("AgentMD is thinking");
3318
+ const typing = cb?.onThinking?.("Mira is thinking");
3319
3319
  const therapistReply = await provider.chat(therapistHistory);
3320
3320
  typing?.stop();
3321
3321
  let cleanTherapistReply = therapistReply.replace(/\[Phase:.*?\]/g, "").trim();
@@ -4462,7 +4462,7 @@ async function startMCPServer() {
4462
4462
  await server.connect(transport);
4463
4463
  }
4464
4464
  startMCPServer().catch((err) => {
4465
- console.error("HoloMime MCP server error:", err);
4465
+ console.error("holomime MCP server error:", err);
4466
4466
  process.exit(1);
4467
4467
  });
4468
4468
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "holomime",
3
- "version": "2.6.0",
3
+ "version": "2.6.1",
4
4
  "description": "Behavioral therapy infrastructure for AI agents — Big Five psychology, structured treatment, behavioral alignment",
5
5
  "type": "module",
6
6
  "bin": {