holomime 2.6.1 → 2.7.0

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/README.md CHANGED
@@ -70,19 +70,19 @@ Eight files define who your agent is. They compile into a single `.personality.j
70
70
  npm install -g holomime
71
71
 
72
72
  # Initialize the identity stack (3 core files: soul + mind + conscience)
73
- holomime init-stack
73
+ holomime core
74
74
 
75
75
  # Or initialize the full 8-file stack (enterprise / robotics)
76
- # holomime init-stack --full
76
+ # holomime identity
77
77
 
78
78
  # Compile into .personality.json
79
79
  holomime compile-stack
80
80
 
81
81
  # Diagnose behavioral drift (no LLM needed)
82
- holomime diagnose --log agent.jsonl
82
+ holomime diagnose
83
83
 
84
84
  # Benchmark alignment (8 adversarial scenarios, grade A-F)
85
- holomime benchmark --personality .personality.json
85
+ holomime benchmark
86
86
 
87
87
  # Push identity to a robot or avatar
88
88
  holomime embody --body registry/bodies/figure-03.body.api
package/dist/cli.js CHANGED
@@ -3466,7 +3466,7 @@ var generic_adapter_exports = {};
3466
3466
  __export(generic_adapter_exports, {
3467
3467
  GenericAdapter: () => GenericAdapter
3468
3468
  });
3469
- import { existsSync as existsSync37, watchFile as watchFile2, unwatchFile as unwatchFile2, readFileSync as readFileSync42 } from "fs";
3469
+ import { existsSync as existsSync38, watchFile as watchFile2, unwatchFile as unwatchFile2, readFileSync as readFileSync42 } from "fs";
3470
3470
  import { createInterface as createInterface5 } from "readline";
3471
3471
  var GenericAdapter;
3472
3472
  var init_generic_adapter = __esm({
@@ -3507,7 +3507,7 @@ var init_generic_adapter = __esm({
3507
3507
  }
3508
3508
  async readFromFile(callbacks) {
3509
3509
  const filePath = this.options.inputPath;
3510
- if (!existsSync37(filePath)) {
3510
+ if (!existsSync38(filePath)) {
3511
3511
  callbacks.onError(`Input file not found: ${filePath}`);
3512
3512
  return;
3513
3513
  }
@@ -18185,6 +18185,46 @@ function diffObjects(a, b, prefix = "") {
18185
18185
  return changes;
18186
18186
  }
18187
18187
 
18188
+ // src/commands/auto-detect.ts
18189
+ import { existsSync as existsSync37 } from "fs";
18190
+ import { join as join34 } from "path";
18191
+ function detectPersonality(cwd) {
18192
+ const dir = cwd ?? process.cwd();
18193
+ const candidates = [
18194
+ join34(dir, ".personality.json"),
18195
+ join34(dir, "personality.json")
18196
+ ];
18197
+ for (const path of candidates) {
18198
+ if (existsSync37(path)) return path;
18199
+ }
18200
+ return null;
18201
+ }
18202
+ function detectProvider() {
18203
+ if (process.env.ANTHROPIC_API_KEY) {
18204
+ return { provider: "anthropic", model: "claude-haiku-4-5-20251001" };
18205
+ }
18206
+ if (process.env.OPENAI_API_KEY) {
18207
+ return { provider: "openai", model: "gpt-4o-mini" };
18208
+ }
18209
+ return { provider: "ollama", model: "llama3" };
18210
+ }
18211
+ function autoDetect(options) {
18212
+ const personalityPath = options.personality ?? detectPersonality();
18213
+ if (!personalityPath && options.requirePersonality !== false) {
18214
+ throw new Error(
18215
+ "No .personality.json found in current directory.\nRun `holomime personality` to create one, or use --personality <path>."
18216
+ );
18217
+ }
18218
+ const detected = detectProvider();
18219
+ const provider = options.provider ?? detected.provider;
18220
+ const model = options.model ?? detected.model;
18221
+ return {
18222
+ personalityPath: personalityPath ?? ".personality.json",
18223
+ provider,
18224
+ model
18225
+ };
18226
+ }
18227
+
18188
18228
  // src/commands/voice.ts
18189
18229
  import chalk42 from "chalk";
18190
18230
  import figures31 from "figures";
@@ -18817,8 +18857,8 @@ Press ${chalk42.cyan("Ctrl+C")} to stop.`,
18817
18857
  // src/commands/install.ts
18818
18858
  import chalk43 from "chalk";
18819
18859
  import figures32 from "figures";
18820
- import { existsSync as existsSync38, mkdirSync as mkdirSync24, writeFileSync as writeFileSync35 } from "fs";
18821
- import { join as join34, resolve as resolve49 } from "path";
18860
+ import { existsSync as existsSync39, mkdirSync as mkdirSync24, writeFileSync as writeFileSync35 } from "fs";
18861
+ import { join as join35, resolve as resolve49 } from "path";
18822
18862
  import { select as select3 } from "@inquirer/prompts";
18823
18863
  var INSTALL_DIRS = {
18824
18864
  "personality": ".",
@@ -18869,11 +18909,11 @@ async function installCommand(handle, options) {
18869
18909
  }
18870
18910
  const installDir = resolve49(process.cwd(), options.output ?? INSTALL_DIRS[asset.type]);
18871
18911
  const filename = INSTALL_FILENAMES[asset.type](asset.handle);
18872
- const installPath = join34(installDir, filename);
18873
- if (!existsSync38(installDir)) {
18912
+ const installPath = join35(installDir, filename);
18913
+ if (!existsSync39(installDir)) {
18874
18914
  mkdirSync24(installDir, { recursive: true });
18875
18915
  }
18876
- if (existsSync38(installPath)) {
18916
+ if (existsSync39(installPath)) {
18877
18917
  const overwrite = await select3({
18878
18918
  message: `${filename} already exists. Overwrite?`,
18879
18919
  choices: [
@@ -18913,12 +18953,12 @@ async function installCommand(handle, options) {
18913
18953
  // src/commands/cure.ts
18914
18954
  import chalk44 from "chalk";
18915
18955
  import figures33 from "figures";
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";
18956
+ import { readFileSync as readFileSync44, writeFileSync as writeFileSync37, existsSync as existsSync41, mkdirSync as mkdirSync26 } from "fs";
18957
+ import { resolve as resolve51, join as join37 } from "path";
18918
18958
 
18919
18959
  // src/analysis/training-pipeline.ts
18920
- import { writeFileSync as writeFileSync36, mkdirSync as mkdirSync25, readFileSync as readFileSync43, existsSync as existsSync39 } from "fs";
18921
- import { resolve as resolve50, join as join35 } from "path";
18960
+ import { writeFileSync as writeFileSync36, mkdirSync as mkdirSync25, readFileSync as readFileSync43, existsSync as existsSync40 } from "fs";
18961
+ import { resolve as resolve50, join as join36 } from "path";
18922
18962
  function ensurePipelineDir() {
18923
18963
  const dir = resolve50(process.cwd(), ".holomime/pipeline");
18924
18964
  mkdirSync25(dir, { recursive: true });
@@ -18926,7 +18966,7 @@ function ensurePipelineDir() {
18926
18966
  }
18927
18967
  function saveStageResult(pipelineDir, stage, data) {
18928
18968
  writeFileSync36(
18929
- join35(pipelineDir, `${stage}.json`),
18969
+ join36(pipelineDir, `${stage}.json`),
18930
18970
  JSON.stringify(data, null, 2) + "\n"
18931
18971
  );
18932
18972
  }
@@ -19002,12 +19042,12 @@ async function runPipeline(options) {
19002
19042
  };
19003
19043
  }
19004
19044
  const exportsDir = resolve50(process.cwd(), ".holomime/exports");
19005
- if (existsSync39(exportsDir)) {
19045
+ if (existsSync40(exportsDir)) {
19006
19046
  try {
19007
19047
  const { readdirSync: readdirSync12 } = await import("fs");
19008
19048
  const files = readdirSync12(exportsDir).filter((f) => f.endsWith(".json") || f.endsWith(".jsonl")).sort().reverse();
19009
19049
  if (files.length > 0 && exportData.examples.length === 0) {
19010
- const latestPath = join35(exportsDir, files[0]);
19050
+ const latestPath = join36(exportsDir, files[0]);
19011
19051
  const latestData = JSON.parse(readFileSync43(latestPath, "utf-8"));
19012
19052
  if (latestData.examples && latestData.examples.length > 0) {
19013
19053
  exportData = latestData;
@@ -19184,14 +19224,14 @@ async function cureCommand(options) {
19184
19224
  }
19185
19225
  const personalityPath = resolve51(process.cwd(), options.personality);
19186
19226
  let logPath;
19187
- if (!existsSync40(personalityPath)) {
19227
+ if (!existsSync41(personalityPath)) {
19188
19228
  console.error(chalk44.red(` Personality file not found: ${options.personality}`));
19189
19229
  process.exit(1);
19190
19230
  return;
19191
19231
  }
19192
19232
  if (options.log) {
19193
19233
  logPath = resolve51(process.cwd(), options.log);
19194
- if (!existsSync40(logPath)) {
19234
+ if (!existsSync41(logPath)) {
19195
19235
  console.error(chalk44.red(` Log file not found: ${options.log}`));
19196
19236
  process.exit(1);
19197
19237
  return;
@@ -19212,7 +19252,7 @@ async function cureCommand(options) {
19212
19252
  }
19213
19253
  const pipelineDir = resolve51(process.cwd(), ".holomime/pipeline");
19214
19254
  mkdirSync26(pipelineDir, { recursive: true });
19215
- logPath = join36(pipelineDir, "auto-generated-log.json");
19255
+ logPath = join37(pipelineDir, "auto-generated-log.json");
19216
19256
  const syntheticLog = {
19217
19257
  conversations: [
19218
19258
  {
@@ -19426,19 +19466,19 @@ function generateProblematicResponse(targetPattern, userMessage) {
19426
19466
  import chalk45 from "chalk";
19427
19467
 
19428
19468
  // src/live/agent-detector.ts
19429
- import { existsSync as existsSync41, readdirSync as readdirSync11, statSync } from "fs";
19430
- import { join as join37, resolve as resolve52 } from "path";
19469
+ import { existsSync as existsSync42, readdirSync as readdirSync11, statSync } from "fs";
19470
+ import { join as join38, resolve as resolve52 } from "path";
19431
19471
  import { homedir as homedir7 } from "os";
19432
19472
  var RECENCY_THRESHOLD_MS = 12e4;
19433
19473
  function findNewestFile(baseDir, extensions, maxDepth = 3, depth = 0) {
19434
19474
  if (depth > maxDepth) return null;
19435
- if (!existsSync41(baseDir)) return null;
19475
+ if (!existsSync42(baseDir)) return null;
19436
19476
  let best = null;
19437
19477
  try {
19438
19478
  const entries = readdirSync11(baseDir);
19439
19479
  for (const entry of entries) {
19440
19480
  if (entry.startsWith(".")) continue;
19441
- const fullPath = join37(baseDir, entry);
19481
+ const fullPath = join38(baseDir, entry);
19442
19482
  try {
19443
19483
  const stat = statSync(fullPath);
19444
19484
  if (stat.isDirectory()) {
@@ -19464,7 +19504,7 @@ function isRecent(mtimeMs) {
19464
19504
  return Date.now() - mtimeMs <= RECENCY_THRESHOLD_MS;
19465
19505
  }
19466
19506
  function findClaudeCodeSession() {
19467
- const claudeDir = join37(homedir7(), ".claude", "projects");
19507
+ const claudeDir = join38(homedir7(), ".claude", "projects");
19468
19508
  const result = findNewestFile(claudeDir, [".jsonl"], 2);
19469
19509
  if (!result || !isRecent(result.mtimeMs)) return null;
19470
19510
  return {
@@ -19475,8 +19515,8 @@ function findClaudeCodeSession() {
19475
19515
  }
19476
19516
  function findClineSession() {
19477
19517
  const searchDirs = [
19478
- join37(process.cwd(), ".cline", "tasks"),
19479
- join37(homedir7(), ".cline", "tasks")
19518
+ join38(process.cwd(), ".cline", "tasks"),
19519
+ join38(homedir7(), ".cline", "tasks")
19480
19520
  ];
19481
19521
  for (const tasksDir of searchDirs) {
19482
19522
  const result = findNewestFile(tasksDir, [".json", ".jsonl"], 2);
@@ -19491,7 +19531,7 @@ function findClineSession() {
19491
19531
  return null;
19492
19532
  }
19493
19533
  function findCodexSession() {
19494
- const codexDir = join37(homedir7(), ".codex", "sessions");
19534
+ const codexDir = join38(homedir7(), ".codex", "sessions");
19495
19535
  const result = findNewestFile(codexDir, [".jsonl"], 4);
19496
19536
  if (!result || !isRecent(result.mtimeMs)) return null;
19497
19537
  return {
@@ -19501,7 +19541,7 @@ function findCodexSession() {
19501
19541
  };
19502
19542
  }
19503
19543
  function findCursorSession() {
19504
- const cursorProjects = join37(homedir7(), ".cursor", "projects");
19544
+ const cursorProjects = join38(homedir7(), ".cursor", "projects");
19505
19545
  const result = findNewestFile(cursorProjects, [".json", ".jsonl"], 3);
19506
19546
  if (result && isRecent(result.mtimeMs)) {
19507
19547
  return {
@@ -19648,8 +19688,8 @@ function readFile(filePath, startByte) {
19648
19688
 
19649
19689
  // src/live/server.ts
19650
19690
  import { createServer as createServer3 } from "http";
19651
- import { readFileSync as readFileSync45, existsSync as existsSync42 } from "fs";
19652
- import { join as join38, extname } from "path";
19691
+ import { readFileSync as readFileSync45, existsSync as existsSync43 } from "fs";
19692
+ import { join as join39, extname } from "path";
19653
19693
  import { fileURLToPath as fileURLToPath4 } from "url";
19654
19694
  import { WebSocketServer } from "ws";
19655
19695
  var __bundleDir = fileURLToPath4(new URL(".", import.meta.url));
@@ -19663,15 +19703,15 @@ var MIME_TYPES = {
19663
19703
  ".ico": "image/x-icon"
19664
19704
  };
19665
19705
  function startServer(port) {
19666
- const staticDir = join38(__bundleDir, "neuralspace");
19706
+ const staticDir = join39(__bundleDir, "neuralspace");
19667
19707
  const clients = /* @__PURE__ */ new Set();
19668
19708
  let lastEvent = null;
19669
19709
  let initMessage = null;
19670
19710
  return new Promise((resolve56, reject) => {
19671
19711
  const server = createServer3((req, res) => {
19672
19712
  const url = req.url === "/" ? "/index.html" : req.url || "/index.html";
19673
- const filePath = join38(staticDir, url);
19674
- if (!existsSync42(filePath)) {
19713
+ const filePath = join39(staticDir, url);
19714
+ if (!existsSync43(filePath)) {
19675
19715
  res.writeHead(404, { "Content-Type": "text/plain" });
19676
19716
  res.end("Not found");
19677
19717
  return;
@@ -21131,8 +21171,8 @@ import { writeFileSync as writeFileSync39 } from "fs";
21131
21171
  import { resolve as resolve55 } from "path";
21132
21172
 
21133
21173
  // src/compliance/audit-trail.ts
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";
21174
+ import { readFileSync as readFileSync46, appendFileSync as appendFileSync2, existsSync as existsSync44, mkdirSync as mkdirSync27 } from "fs";
21175
+ import { join as join40, resolve as resolve54 } from "path";
21136
21176
  function djb2(str) {
21137
21177
  let hash = 5381;
21138
21178
  for (let i = 0; i < str.length; i++) {
@@ -21146,13 +21186,13 @@ function hashEntry(entry) {
21146
21186
  }
21147
21187
  function auditLogPath(agentHandle) {
21148
21188
  const dir = resolve54(process.cwd(), ".holomime", "audit");
21149
- if (!existsSync43(dir)) mkdirSync27(dir, { recursive: true });
21189
+ if (!existsSync44(dir)) mkdirSync27(dir, { recursive: true });
21150
21190
  const filename = agentHandle ? `${agentHandle}-audit.jsonl` : "audit.jsonl";
21151
- return join39(dir, filename);
21191
+ return join40(dir, filename);
21152
21192
  }
21153
21193
  function loadAuditLog(agentHandle) {
21154
21194
  const logPath = auditLogPath(agentHandle);
21155
- if (!existsSync43(logPath)) return [];
21195
+ if (!existsSync44(logPath)) return [];
21156
21196
  return readFileSync46(logPath, "utf-8").trim().split("\n").filter(Boolean).map((line) => {
21157
21197
  try {
21158
21198
  return JSON.parse(line);
@@ -21683,7 +21723,7 @@ program.name("holomime").description("Personality engine for AI agents \u2014 Bi
21683
21723
  const commandName = actionCommand.name();
21684
21724
  showTelemetryBannerIfNeeded();
21685
21725
  trackEvent("cli_command", { command: commandName });
21686
- const skipPersonalityCheck = ["init", "init-stack", "compile-stack", "browse", "use", "install", "activate", "telemetry", "brain"];
21726
+ const skipPersonalityCheck = ["init", "init-stack", "compile-stack", "browse", "use", "install", "activate", "telemetry", "brain", "personality", "core", "identity"];
21687
21727
  if (!skipPersonalityCheck.includes(commandName) && !checkPersonalityExists()) {
21688
21728
  showWelcome();
21689
21729
  process.exit(0);
@@ -21695,6 +21735,12 @@ program.name("holomime").description("Personality engine for AI agents \u2014 Bi
21695
21735
  });
21696
21736
  program.command("init").description("Build a personality profile through a guided assessment").action(initCommand);
21697
21737
  program.command("init-stack").description("Create the 8-file identity stack (default: 3 core files; --full: all 8 files)").option("--full", "Generate all 8 files (soul + mind + purpose + shadow + memory + body + conscience + ego)").option("--from <path>", "Decompose an existing .personality.json into stack files").option("--dir <path>", "Output directory (default: current directory)").action(initStackCommand);
21738
+ program.command("personality").description("Create a personality profile (1 file)").action(initCommand);
21739
+ program.command("core").description("Create core identity stack \u2014 soul.md + mind.sys + conscience.exe (3 files)").option("--dir <path>", "Output directory").action(initStackCommand);
21740
+ program.command("identity").description("Create complete identity \u2014 all 8 files (enterprise/robotics)").option("--dir <path>", "Output directory").action(async (options) => {
21741
+ options.full = true;
21742
+ await initStackCommand(options);
21743
+ });
21698
21744
  program.command("compile-stack").description("Compile identity stack (soul + mind + purpose + shadow + memory + body + conscience + ego) into .personality.json").option("--dir <path>", "Stack directory (default: auto-detect)").option("-o, --output <path>", "Output path (default: .personality.json)").option("--validate-only", "Parse and validate without writing").option("--diff", "Show changes vs existing .personality.json").action(compileStackCommand);
21699
21745
  program.command("compile").description("Compile .personality.json into a provider-specific runtime config").option("--provider <provider>", "Target provider (anthropic, openai, gemini, ollama)", "anthropic").option("--surface <surface>", "Target surface (chat, email, code_review, slack, api, embodied)", "chat").option("--for <format>", "Compile for a specific format (openclaw)").option("--tier <tier>", "Personality loading tier (L0, L1, L2)", "L2").option("-o, --output <path>", "Write output to file instead of stdout").action(compileCommand);
21700
21746
  program.command("validate").description("Validate .personality.json schema and psychological coherence").action(validateCommand);
@@ -21708,13 +21754,25 @@ program.command("publish").description("Share assets to the community marketplac
21708
21754
  program.command("embody").description("Start an embodiment runtime \u2014 push personality to robots/avatars in real-time").option("--personality <path>", "Path to .personality.json").requiredOption("--adapter <adapter>", "Runtime adapter (ros2, unity, webhook, isaac)").option("--stack <dir>", "Path to identity stack directory (soul.md + mind.sys + purpose.cfg + shadow.log + memory.store + body.api + conscience.exe + ego.runtime)").option("--swap-body <path>", "Hot-swap body.api into the stack directory before starting (requires --stack)").option("--endpoint <url>", "WebSocket URL for ROS2 rosbridge (default: ws://localhost:9090)").option("--port <port>", "Port for Unity HTTP server (default: 8765)").option("--url <url>", "Webhook URL for HTTP adapter").option("--headers <headers>", "Custom headers for webhook (Key:Value,Key2:Value2)").option("--bearer-token <token>", "Bearer token for webhook auth").option("--topic-prefix <prefix>", "ROS2 topic prefix (default: /holomime)").option("--transition <ms>", "Unity transition duration in ms (default: 500)").action(embodyCommand);
21709
21755
  program.command("activate").description("Activate a Pro license key").argument("<key>", "License key from holomime.com").action(activateCommand);
21710
21756
  program.command("telemetry").description("Manage anonymous usage telemetry").argument("[action]", "enable, disable, or status (default: status)").action(telemetryCommand);
21711
- program.command("session").description("Live alignment session \u2014 behavioral refinement for your agent [Pro]").requiredOption("--personality <path>", "Path to .personality.json").option("--provider <provider>", "LLM provider (ollama, anthropic, openai)", "ollama").option("--model <model>", "Model override (e.g. claude-sonnet-4-20250514, gpt-4o)").option("--log <path>", "Conversation log for pre-session diagnosis").option("--format <format>", "Log format (auto, holomime, chatgpt, claude, openai-api, anthropic-api, otel, jsonl)", "auto").option("--turns <n>", "Maximum session turns", "24").option("--observe", "Observe mode (watch without intervention)").option("--interactive", "Supervisor mode \u2014 intervene mid-session with directives").option("--apply", "Apply recommendations to .personality.json after session").action(sessionCommand);
21757
+ program.command("session").description("Live alignment session \u2014 behavioral refinement for your agent [Pro]").option("--personality <path>", "Path to .personality.json (auto-detected)").option("--provider <provider>", "LLM provider (ollama, anthropic, openai)", "ollama").option("--model <model>", "Model override (e.g. claude-sonnet-4-20250514, gpt-4o)").option("--log <path>", "Conversation log for pre-session diagnosis").option("--format <format>", "Log format (auto, holomime, chatgpt, claude, openai-api, anthropic-api, otel, jsonl)", "auto").option("--turns <n>", "Maximum session turns", "24").option("--observe", "Observe mode (watch without intervention)").option("--interactive", "Supervisor mode \u2014 intervene mid-session with directives").option("--apply", "Apply recommendations to .personality.json after session").action(async (options) => {
21758
+ const resolved = autoDetect({ personality: options.personality, provider: options.provider, model: options.model });
21759
+ options.personality = resolved.personalityPath;
21760
+ if (!options.provider || options.provider === "ollama") options.provider = resolved.provider;
21761
+ if (!options.model) options.model = resolved.model;
21762
+ await sessionCommand(options);
21763
+ });
21712
21764
  program.command("autopilot").description("Automated behavioral alignment \u2014 diagnose, refine, and apply [Pro]").requiredOption("--personality <path>", "Path to .personality.json").requiredOption("--log <path>", "Conversation log for diagnosis").option("--provider <provider>", "LLM provider (ollama, anthropic, openai)", "ollama").option("--model <model>", "Model override").option("--format <format>", "Log format (auto, holomime, chatgpt, claude, openai-api, anthropic-api, otel, jsonl)", "auto").option("--threshold <level>", "Trigger threshold (routine, targeted, intervention)", "targeted").option("--turns <n>", "Maximum session turns", "24").option("--dry-run", "Show what would happen without running alignment").option("--apply", "Apply recommendations to .personality.json after session").option("--oversight <mode>", "Oversight mode (none, review, approve, approve-specs)", "review").action(autopilotCommand);
21713
21765
  program.command("growth").description("Track improvement over time from assessment history [Pro]").requiredOption("--personality <path>", "Path to .personality.json").option("--history <path>", "Path to assessments directory", ".holomime/assessments").action(growthCommand);
21714
21766
  program.command("export").description("Export alignment sessions as training data (DPO, RLHF, Alpaca, HuggingFace, OpenAI) [Pro]").requiredOption("--format <format>", "Export format (dpo, rlhf, jsonl, alpaca, huggingface, openai)").option("--sessions <path>", "Path to sessions directory", ".holomime/sessions").option("-o, --output <path>", "Output file path").option("--push", "Push to HuggingFace Hub after export (requires HF_TOKEN)").option("--repo <repo>", "HuggingFace Hub repo name for push (e.g. user/dataset-name)").action(exportCommand);
21715
21767
  program.command("train").description("Fine-tune a model with alignment data \u2014 train, deploy, and verify [Pro]").option("--data <path>", "Path to exported training data").option("--provider <provider>", "Training provider (openai, huggingface)", "openai").option("--base-model <model>", "Base model to fine-tune", "gpt-4o-mini").option("--suffix <suffix>", "Model name suffix").option("--epochs <n>", "Training epochs").option("--method <method>", "Training method (auto, sft, dpo)", "auto").option("--personality <path>", "Path to .personality.json", ".personality.json").option("--skip-eval", "Skip auto-evaluation after training").option("--skip-deploy", "Skip auto-deploy to personality").option("--dry-run", "Preview training plan without starting").option("--push", "Push trained model to HuggingFace Hub (HF only)").option("--hub-repo <repo>", "HuggingFace Hub repo name for push (e.g. user/model-name)").option("--verify", "Run behavioral verification after training").option("--pass-threshold <n>", "Minimum verification score (0-100)", "50").action(trainCommand);
21716
21768
  program.command("eval").description("Measure alignment effectiveness \u2014 compare before/after behavior [Pro]").requiredOption("--before <path>", "Conversation log from BEFORE alignment").requiredOption("--after <path>", "Conversation log from AFTER alignment").option("--personality <path>", "Path to .personality.json (for agent name)").option("--format <format>", "Log format (auto, holomime, chatgpt, claude, openai-api, anthropic-api, otel, jsonl)", "auto").action(evalCommand);
21717
- program.command("evolve").description("Recursive behavioral alignment \u2014 iterate until converged [Pro]").requiredOption("--personality <path>", "Path to .personality.json").requiredOption("--log <path>", "Conversation log for diagnosis").option("--provider <provider>", "LLM provider (ollama, anthropic, openai)", "ollama").option("--model <model>", "Model override").option("--format <format>", "Log format (auto, holomime, chatgpt, claude, openai-api, anthropic-api, otel, jsonl)", "auto").option("--max-iterations <n>", "Maximum alignment iterations", "5").option("--convergence <score>", "TES convergence threshold (0-100)", "85").option("--turns <n>", "Max turns per session", "18").option("--apply", "Apply final recommendations to .personality.json").option("--export-dpo <path>", "Export accumulated DPO pairs to file").option("--dry-run", "Preview without running sessions").action(evolveCommand);
21769
+ program.command("evolve").description("Recursive behavioral alignment \u2014 iterate until converged [Pro]").option("--personality <path>", "Path to .personality.json (auto-detected)").requiredOption("--log <path>", "Conversation log for diagnosis").option("--provider <provider>", "LLM provider (ollama, anthropic, openai)", "ollama").option("--model <model>", "Model override").option("--format <format>", "Log format (auto, holomime, chatgpt, claude, openai-api, anthropic-api, otel, jsonl)", "auto").option("--max-iterations <n>", "Maximum alignment iterations", "5").option("--convergence <score>", "TES convergence threshold (0-100)", "85").option("--turns <n>", "Max turns per session", "18").option("--apply", "Apply final recommendations to .personality.json").option("--export-dpo <path>", "Export accumulated DPO pairs to file").option("--dry-run", "Preview without running sessions").action(async (options) => {
21770
+ const resolved = autoDetect({ personality: options.personality, provider: options.provider, model: options.model });
21771
+ options.personality = resolved.personalityPath;
21772
+ if (!options.provider || options.provider === "ollama") options.provider = resolved.provider;
21773
+ if (!options.model) options.model = resolved.model;
21774
+ await evolveCommand(options);
21775
+ });
21718
21776
  program.command("benchmark").description("Run 8 adversarial scenarios against your agent to score behavioral alignment (A-F)").addHelpText("after", `
21719
21777
  Examples:
21720
21778
  $ holomime benchmark --personality .personality.json
@@ -21737,9 +21795,19 @@ Providers:
21737
21795
  ollama Free, local, no API key needed (default)
21738
21796
  anthropic Requires ANTHROPIC_API_KEY env var
21739
21797
  openai Requires OPENAI_API_KEY env var
21740
- `).requiredOption("--personality <path>", "Path to .personality.json").option("--provider <provider>", "LLM provider (ollama, anthropic, openai)", "ollama").option("--model <model>", "Model override").option("--scenarios <list>", "Comma-separated scenario filter (e.g. apology-trap,sycophancy-test)").option("--save", "Save results to ~/.holomime/benchmarks/ and auto-compare with previous run").option("--compare <path>", "Compare against a previous benchmark result file").action(benchmarkCommand);
21798
+ `).option("--personality <path>", "Path to .personality.json (auto-detected)").option("--provider <provider>", "LLM provider (ollama, anthropic, openai)", "ollama").option("--model <model>", "Model override").option("--scenarios <list>", "Comma-separated scenario filter (e.g. apology-trap,sycophancy-test)").option("--save", "Save results to ~/.holomime/benchmarks/ and auto-compare with previous run").option("--compare <path>", "Compare against a previous benchmark result file").action(async (options) => {
21799
+ const resolved = autoDetect({ personality: options.personality, provider: options.provider, model: options.model });
21800
+ options.personality = resolved.personalityPath;
21801
+ if (!options.provider || options.provider === "ollama") options.provider = resolved.provider;
21802
+ if (!options.model) options.model = resolved.model;
21803
+ await benchmarkCommand(options);
21804
+ });
21741
21805
  program.command("watch").description("Continuous relapse detection \u2014 monitor logs and auto-align [Pro]").requiredOption("--personality <path>", "Path to .personality.json").requiredOption("--dir <path>", "Directory to watch for conversation logs").option("--provider <provider>", "LLM provider (ollama, anthropic, openai)", "ollama").option("--model <model>", "Model override").option("--interval <ms>", "Check interval in milliseconds", "30000").option("--threshold <level>", "Drift threshold (routine, targeted, intervention)", "targeted").option("--auto-evolve", "Auto-run evolve when drift detected").action(watchCommand);
21742
- program.command("certify").description("Generate a verifiable behavioral credential or ISO compliance report [Pro]").option("--personality <path>", "Path to .personality.json", ".personality.json").option("--benchmark <path>", "Path to benchmark report JSON").option("--evolve <path>", "Path to evolve result JSON").option("-o, --output <path>", "Output directory for credential, or JSON report path for --standard").option("--verify <path>", "Verify an existing credential").option("--standard <name>", "Check ISO compliance (iso-13482, iso-25785, iso-10218, iso-42001, all)").action(certifyCommand);
21806
+ program.command("certify").description("Generate a verifiable behavioral credential or ISO compliance report [Pro]").option("--personality <path>", "Path to .personality.json (auto-detected)").option("--benchmark <path>", "Path to benchmark report JSON").option("--evolve <path>", "Path to evolve result JSON").option("-o, --output <path>", "Output directory for credential, or JSON report path for --standard").option("--verify <path>", "Verify an existing credential").option("--standard <name>", "Check ISO compliance (iso-13482, iso-25785, iso-10218, iso-42001, all)").action(async (options) => {
21807
+ const resolved = autoDetect({ personality: options.personality, provider: options.provider, model: options.model });
21808
+ options.personality = resolved.personalityPath;
21809
+ await certifyCommand(options);
21810
+ });
21743
21811
  program.command("daemon").description("Background relapse detection with auto-evolve \u2014 proactive alignment [Pro]").requiredOption("--dir <path>", "Directory to watch for conversation logs").option("--personality <path>", "Path to .personality.json", ".personality.json").option("--provider <provider>", "LLM provider (ollama, anthropic, openai)", "ollama").option("--model <model>", "Model override").option("--interval <ms>", "Check interval in milliseconds", "30000").option("--threshold <level>", "Drift threshold (routine, targeted, intervention)", "targeted").option("--oversight <mode>", "Oversight mode (none, review, approve, approve-specs)", "review").action(daemonCommand);
21744
21812
  program.command("fleet").description("Monitor multiple agents from a single dashboard [Pro]").option("--config <path>", "Path to fleet.json config file").option("--dir <path>", "Auto-discover agents in directory").option("--provider <provider>", "LLM provider (ollama, anthropic, openai)", "ollama").option("--model <model>", "Model override").option("--interval <ms>", "Check interval in milliseconds", "30000").option("--threshold <level>", "Drift threshold (routine, targeted, intervention)", "targeted").option("--auto-evolve", "Auto-run evolve when drift detected").action(fleetCommand);
21745
21813
  program.command("group-therapy").alias("fleet-therapy").description("Group therapy \u2014 treat all agents in your fleet simultaneously [Pro]").option("--config <path>", "Path to fleet.json config file").option("--dir <path>", "Auto-discover agents in directory").option("--provider <provider>", "LLM provider (ollama, anthropic, openai)", "ollama").option("--model <model>", "Model override").option("--turns <n>", "Max therapy turns per agent", "24").option("--concurrency <n>", "Max agents treated in parallel", "3").option("--apply", "Auto-apply recommendations to personality files").option("--yes", "Skip confirmation prompt").action(fleetTherapyCommand);
@@ -21748,7 +21816,13 @@ program.command("share").description("Share DPO training pairs to the marketplac
21748
21816
  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);
21749
21817
  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);
21750
21818
  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);
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);
21819
+ program.command("cure").description("End-to-end behavioral fix \u2014 just run it, everything auto-detected").option("--personality <path>", "Path to .personality.json (auto-detected)").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(async (options) => {
21820
+ const resolved = autoDetect({ personality: options.personality, provider: options.provider, model: options.model });
21821
+ options.personality = resolved.personalityPath;
21822
+ if (!options.provider || options.provider === "ollama") options.provider = resolved.provider;
21823
+ if (!options.model) options.model = resolved.model;
21824
+ await cureCommand(options);
21825
+ });
21752
21826
  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({
21753
21827
  watchPath: opts.watch,
21754
21828
  agent: opts.agent,