@epoch-agent/cli 0.2.0 → 0.3.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/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- writeProviderKey
4
- } from "./chunk-UEHBHZCZ.js";
3
+ writeProviderSecret
4
+ } from "./chunk-4SOT24BS.js";
5
5
  // src/index.ts
6
6
  import { Command } from "commander";
7
- import { t as t38 } from "@epoch-agent/infra";
7
+ import { t as t39 } from "@epoch-agent/infra";
8
8
  // src/commands/agents.ts
9
9
  import { AGENT_ROLE_DIAG_MODULE, findRole, roleSourceLabel } from "@epoch-agent/core";
10
10
  import { t as t2 } from "@epoch-agent/infra";
@@ -331,9 +331,122 @@ function registerCompletionCommand(program2) {
331
331
  process.stdout.write(renderCompletion(program2, shell));
332
332
  });
333
333
  }
334
+ // src/commands/compliance.ts
335
+ import {
336
+ ComplianceEngine,
337
+ DEFAULT_COMPLIANCE_SETTINGS,
338
+ loadConfig,
339
+ loadLexiconFiles,
340
+ resolveComplianceDir,
341
+ resolveComplianceDirs
342
+ } from "@epoch-agent/core";
343
+ import { t as t4 } from "@epoch-agent/infra";
344
+ // src/paths.ts
345
+ import { existsSync, mkdirSync } from "fs";
346
+ import { hasProviderCredentials } from "@epoch-agent/core";
347
+ import { configPath, envPath, resolveHomeDir } from "@epoch-agent/infra";
348
+ var EPOCH_HOME = resolveHomeDir();
349
+ var CONFIG_PATH = configPath(EPOCH_HOME);
350
+ var ENV_PATH = envPath(EPOCH_HOME);
351
+ function ensureEpochHome() {
352
+ if (!existsSync(EPOCH_HOME)) mkdirSync(EPOCH_HOME, { recursive: true });
353
+ }
354
+ function hasCredentials() {
355
+ return hasProviderCredentials(EPOCH_HOME);
356
+ }
357
+ // src/commands/compliance.ts
358
+ var log2 = (msg) => process.stdout.write(msg + "\n");
359
+ function buildEngine() {
360
+ const config = loadConfig(void 0, { homeDir: EPOCH_HOME });
361
+ const settings = {
362
+ enabled: config.compliance?.enabled ?? DEFAULT_COMPLIANCE_SETTINGS.enabled,
363
+ scope: { ...DEFAULT_COMPLIANCE_SETTINGS.scope, ...config.compliance?.scope },
364
+ skipCodeBlocks: config.compliance?.skipCodeBlocks ?? DEFAULT_COMPLIANCE_SETTINGS.skipCodeBlocks,
365
+ maxHoldChars: config.compliance?.maxHoldChars ?? DEFAULT_COMPLIANCE_SETTINGS.maxHoldChars,
366
+ actions: { ...DEFAULT_COMPLIANCE_SETTINGS.actions, ...config.compliance?.actions }
367
+ };
368
+ const userDir = resolveComplianceDir(config.homeDir);
369
+ const dirs = resolveComplianceDirs({ userDir, trusted: false });
370
+ const rules = [];
371
+ const exempt = [];
372
+ for (const spec of dirs.dirs) {
373
+ const loaded = loadLexiconFiles(spec.dir, spec.source);
374
+ rules.push(...loaded.rules);
375
+ exempt.push(...loaded.exempt);
376
+ }
377
+ return { engine: new ComplianceEngine({ settings, rules, exempt }), settings, dir: userDir };
378
+ }
379
+ async function readStdin() {
380
+ const chunks = [];
381
+ for await (const chunk of process.stdin) chunks.push(Buffer.from(chunk));
382
+ return Buffer.concat(chunks).toString("utf-8");
383
+ }
384
+ function checkText(text) {
385
+ const { engine, settings } = buildEngine();
386
+ if (!settings.enabled) {
387
+ log2(t4("compliance_cmd.disabled"));
388
+ return 0;
389
+ }
390
+ const gate = engine.inspect(text);
391
+ if (!gate) {
392
+ log2(t4("compliance_cmd.clean"));
393
+ return 0;
394
+ }
395
+ const { text: released, verdict } = gate;
396
+ log2(t4("compliance_cmd.verdict", { action: verdict.action, count: verdict.hits.length }));
397
+ for (const hit of verdict.hits) {
398
+ log2(
399
+ t4("compliance_cmd.hit", {
400
+ category: hit.category,
401
+ action: hit.action,
402
+ rule: hit.ruleId,
403
+ excerpt: text.slice(hit.start, hit.end)
404
+ })
405
+ );
406
+ }
407
+ if (verdict.action === "block") log2(t4("compliance_cmd.blocked"));
408
+ else log2(t4("compliance_cmd.released", { text: released }));
409
+ return verdict.action === "warn" ? 0 : 1;
410
+ }
411
+ function printStatus() {
412
+ const { engine, settings, dir } = buildEngine();
413
+ log2(t4("compliance_cmd.status_enabled", { enabled: String(settings.enabled) }));
414
+ log2(
415
+ t4("compliance_cmd.status_rules", {
416
+ active: engine.activeRuleCount,
417
+ builtin: engine.counts.builtin,
418
+ user: engine.counts.user
419
+ })
420
+ );
421
+ log2(t4("compliance_cmd.status_dir", { dir }));
422
+ log2(
423
+ t4("compliance_cmd.status_scope", {
424
+ output: String(settings.scope.output),
425
+ input: String(settings.scope.input),
426
+ code: String(settings.skipCodeBlocks)
427
+ })
428
+ );
429
+ for (const [category, action] of Object.entries(settings.actions)) {
430
+ log2(t4("compliance_cmd.status_action", { category, action }));
431
+ }
432
+ log2(t4("compliance_cmd.status_project_note"));
433
+ }
434
+ function registerComplianceCommand(program2) {
435
+ const cmd = program2.command("compliance").description(t4("compliance_cmd.cmd_root"));
436
+ cmd.command("check", { isDefault: true }).description(t4("compliance_cmd.cmd_check")).argument("[text]", t4("compliance_cmd.arg_text")).option("--stdin", t4("compliance_cmd.opt_stdin")).action(async (text, opts) => {
437
+ const input2 = opts.stdin ? await readStdin() : text;
438
+ if (!input2) {
439
+ log2(t4("compliance_cmd.need_text"));
440
+ process.exitCode = 2;
441
+ return;
442
+ }
443
+ process.exitCode = checkText(input2);
444
+ });
445
+ cmd.command("status").description(t4("compliance_cmd.cmd_status")).action(() => printStatus());
446
+ }
334
447
  // src/commands/config.ts
335
448
  import { existsSync as existsSync2, readFileSync } from "fs";
336
- import { maskApiKey, t as t4 } from "@epoch-agent/infra";
449
+ import { maskApiKey, t as t5 } from "@epoch-agent/infra";
337
450
  import {
338
451
  API_KEY_ENV_VARS,
339
452
  isPermissionLevel,
@@ -354,35 +467,48 @@ import {
354
467
  unsetSectionField,
355
468
  writeConfigYaml
356
469
  } from "@epoch-agent/infra";
357
- // src/paths.ts
358
- import { existsSync, mkdirSync } from "fs";
359
- import { hasProviderCredentials } from "@epoch-agent/core";
360
- import { configPath, envPath, resolveHomeDir } from "@epoch-agent/infra";
361
- var EPOCH_HOME = resolveHomeDir();
362
- var CONFIG_PATH = configPath(EPOCH_HOME);
363
- var ENV_PATH = envPath(EPOCH_HOME);
364
- function ensureEpochHome() {
365
- if (!existsSync(EPOCH_HOME)) mkdirSync(EPOCH_HOME, { recursive: true });
366
- }
367
- function hasCredentials() {
368
- return hasProviderCredentials(EPOCH_HOME);
369
- }
370
470
  // src/commands/config.ts
371
- var log2 = (msg) => {
471
+ var log3 = (msg) => {
372
472
  process.stdout.write(msg + "\n");
373
473
  };
374
474
  function isPositiveNumber(v) {
375
475
  const n = Number(v);
376
476
  return Number.isFinite(n) && n > 0;
377
477
  }
478
+ function isPositiveInt(v) {
479
+ return isPositiveNumber(v) && Number.isInteger(Number(v));
480
+ }
378
481
  var BUDGET_FIELDS = {
379
482
  maxCostUsd: isPositiveNumber,
380
483
  maxTokens: isPositiveNumber,
381
484
  warnAtPercent: (v) => isPositiveNumber(v) && Number(v) <= 100,
382
485
  onUnknownPricing: (v) => v === "block" || v === "warn"
383
486
  };
487
+ var SCALAR_FIELDS = {
488
+ maxTurns: isPositiveInt,
489
+ contextLength: isPositiveInt
490
+ };
491
+ var SECTION_FIELDS = {
492
+ budget: BUDGET_FIELDS,
493
+ compression: {
494
+ enabled: (v) => v === "true" || v === "false",
495
+ threshold: (v) => Number.isFinite(Number(v)) && Number(v) > 0 && Number(v) <= 1
496
+ }
497
+ };
384
498
  function knownKeys() {
385
- return `provider, model, models.utility, permission, shell, ` + Object.keys(BUDGET_FIELDS).map((f) => `budget.${f}`).join(", ");
499
+ const nested = Object.entries(SECTION_FIELDS).flatMap(
500
+ ([section, fields]) => Object.keys(fields).map((field) => `${section}.${field}`)
501
+ );
502
+ return [
503
+ "provider",
504
+ "model",
505
+ "models.utility",
506
+ "fallback.model",
507
+ "permission",
508
+ "shell",
509
+ ...Object.keys(SCALAR_FIELDS),
510
+ ...nested
511
+ ].join(", ");
386
512
  }
387
513
  function maskSecrets(yaml) {
388
514
  return yaml.replace(/^(\s*(?:apiKey|api_key|token|secret)\s*:\s*)(.+)$/gim, (_m, head, raw) => {
@@ -392,111 +518,111 @@ function maskSecrets(yaml) {
392
518
  });
393
519
  }
394
520
  function registerConfigCommand(program2) {
395
- const cmd = program2.command("config").description(t4("cli.config.summary"));
396
- cmd.command("show").description(t4("cli.config.show")).option("--raw", t4("cli.config.opt_raw")).action((opts) => {
521
+ const cmd = program2.command("config").description(t5("cli.config.summary"));
522
+ cmd.command("show").description(t5("cli.config.show")).option("--raw", t5("cli.config.opt_raw")).action((opts) => {
397
523
  if (!existsSync2(CONFIG_PATH)) {
398
- log2(t4("cli.config.not_configured"));
524
+ log3(t5("cli.config.not_configured"));
399
525
  } else {
400
526
  const yaml = readFileSync(CONFIG_PATH, "utf-8").trim();
401
- log2(opts.raw ? yaml : maskSecrets(yaml));
527
+ log3(opts.raw ? yaml : maskSecrets(yaml));
402
528
  }
403
529
  });
404
- cmd.command("path").description(t4("cli.config.path")).action(() => log2(CONFIG_PATH));
405
- cmd.command("get").description(t4("cli.config.get")).argument("<key>", t4("cli.config.keys")).action((key) => {
530
+ cmd.command("path").description(t5("cli.config.path")).action(() => log3(CONFIG_PATH));
531
+ cmd.command("get").description(t5("cli.config.get")).argument("<key>", t5("cli.config.keys")).action((key) => {
406
532
  const value = readKey(
407
533
  readConfigYaml(CONFIG_PATH),
408
534
  key === "provider" ? "provider.type" : key
409
535
  );
410
- if (value === void 0) throw new CliError(t4("cli.config.unset_key", { key }));
411
- log2(value);
536
+ if (value === void 0) throw new CliError(t5("cli.config.unset_key", { key }));
537
+ log3(value);
412
538
  });
413
- cmd.command("set").description(t4("cli.config.set")).argument("<key>", t4("cli.config.keys")).argument("<value>", t4("cli.config.value")).action((key, value) => {
539
+ cmd.command("set").description(t5("cli.config.set")).argument("<key>", t5("cli.config.keys")).argument("<value>", t5("cli.config.value")).action((key, value) => {
414
540
  ensureEpochHome();
415
541
  writeConfigYaml(CONFIG_PATH, applySet(readConfigYaml(CONFIG_PATH), key, value));
416
- log2(`\u2705 ${key} = ${value}`);
542
+ log3(`\u2705 ${key} = ${value}`);
417
543
  });
418
- cmd.command("unset").description(t4("cli.config.unset")).argument("<key>", t4("cli.config.keys_unset")).action((key) => {
544
+ cmd.command("unset").description(t5("cli.config.unset")).argument("<key>", t5("cli.config.keys_unset")).action((key) => {
419
545
  ensureEpochHome();
420
546
  writeConfigYaml(CONFIG_PATH, applyUnset(readConfigYaml(CONFIG_PATH), key));
421
- log2(`\u2705 ${t4("cli.config.removed", { key })}`);
547
+ log3(`\u2705 ${t5("cli.config.removed", { key })}`);
422
548
  });
423
549
  registerSchemaCommand(cmd);
424
550
  registerSecretCommand(cmd);
425
551
  }
426
552
  function registerSchemaCommand(cmd) {
427
- cmd.command("schema").description(t4("cli.config.schema")).action(async () => {
553
+ cmd.command("schema").description(t5("cli.config.schema")).action(async () => {
428
554
  const { resolveProjectRoot: resolveProjectRoot4 } = await import("@epoch-agent/core");
429
555
  const root = resolveProjectRoot4(process.cwd());
430
556
  const { writeProjectSchemas } = await import("./schema-file-DH6X4N4K.js");
431
557
  const written = await writeProjectSchemas(root);
432
- for (const entry of written) log2(`\u2705 ${entry.path}`);
433
- log2("");
434
- log2(t4("cli.config.schema_paste_hint"));
435
- log2(` { "$schema": "${written[0]?.reference ?? ""}", \u2026 }`);
558
+ for (const entry of written) log3(`\u2705 ${entry.path}`);
559
+ log3("");
560
+ log3(t5("cli.config.schema_paste_hint"));
561
+ log3(` { "$schema": "${written[0]?.reference ?? ""}", \u2026 }`);
436
562
  });
437
563
  }
438
564
  function registerSecretCommand(cmd) {
439
- cmd.command("secret").description(t4("cli.config.secret")).option("--export", t4("cli.config.opt_export")).action(async (opts) => {
565
+ cmd.command("secret").description(t5("cli.config.secret")).option("--export", t5("cli.config.opt_export")).action(async (opts) => {
440
566
  const { ensureSecretsReady } = await import("@epoch-agent/runtime");
441
567
  await ensureSecretsReady();
442
568
  const { getSecretStore } = await import("@epoch-agent/infra");
443
569
  const store = getSecretStore();
444
- if (!store) throw new CliError(t4("cli.config.secret_not_ready"));
570
+ if (!store) throw new CliError(t5("cli.config.secret_not_ready"));
445
571
  if (opts.export) await exportSecrets(store);
446
572
  else await printSecretStatus(store);
447
573
  });
448
574
  }
449
575
  async function printSecretStatus(store) {
450
- log2(
451
- `${store.encrypted ? "\u2713" : "\u26A0"} ${t4("cli.config.secret_backend", {
576
+ log3(
577
+ `${store.encrypted ? "\u2713" : "\u26A0"} ${t5("cli.config.secret_backend", {
452
578
  backend: store.backend,
453
579
  detail: store.detail
454
580
  })}`
455
581
  );
456
582
  const names = (await store.list()).filter((n) => API_KEY_ENV_VARS.includes(n));
457
583
  if (names.length === 0) {
458
- log2(t4("cli.config.secret_empty"));
584
+ log3(t5("cli.config.secret_empty"));
459
585
  return;
460
586
  }
461
- for (const name of names) log2(` ${name}`);
587
+ for (const name of names) log3(` ${name}`);
462
588
  }
463
589
  async function exportSecrets(store) {
464
590
  const { isNonInteractive: isNonInteractive9 } = await import("@epoch-agent/core");
465
591
  if (isNonInteractive9()) {
466
- throw new CliError(t4("cli.config.export_needs_tty"), 1, t4("cli.config.export_needs_tty_hint"));
592
+ throw new CliError(t5("cli.config.export_needs_tty"), 1, t5("cli.config.export_needs_tty_hint"));
467
593
  }
468
594
  const { confirm } = await import("@inquirer/prompts");
469
- log2(t4("cli.config.export_about_to", { path: ENV_PATH }));
470
- if (!await confirm({ message: t4("cli.config.export_confirm"), default: false })) {
471
- log2(t4("cli.config.cancelled"));
595
+ log3(t5("cli.config.export_about_to", { path: ENV_PATH }));
596
+ if (!await confirm({ message: t5("cli.config.export_confirm"), default: false })) {
597
+ log3(t5("cli.config.cancelled"));
472
598
  return;
473
599
  }
474
600
  const again = await confirm({
475
- message: t4("cli.config.export_confirm_again", { path: ENV_PATH }),
601
+ message: t5("cli.config.export_confirm_again", { path: ENV_PATH }),
476
602
  default: false
477
603
  });
478
604
  if (!again) {
479
- log2(t4("cli.config.cancelled"));
605
+ log3(t5("cli.config.cancelled"));
480
606
  return;
481
607
  }
482
608
  ensureEpochHome();
483
- const { exportSecretsToEnv } = await import("./env-file-O6P454IQ.js");
609
+ const { exportSecretsToEnv } = await import("./env-file-ERS45V7K.js");
484
610
  const written = await exportSecretsToEnv(store, ENV_PATH, API_KEY_ENV_VARS);
485
611
  if (written.length === 0) {
486
- log2(t4("cli.config.export_nothing"));
612
+ log3(t5("cli.config.export_nothing"));
487
613
  return;
488
614
  }
489
- log2(`\u2705 ${t4("cli.config.export_done", { count: written.length, path: ENV_PATH })}`);
490
- log2(t4("cli.config.export_done_note"));
615
+ log3(`\u2705 ${t5("cli.config.export_done", { count: written.length, path: ENV_PATH })}`);
616
+ log3(t5("cli.config.export_done_note"));
491
617
  }
492
618
  function applySet(yaml, key, value) {
493
619
  switch (key) {
494
620
  case "provider":
495
621
  if (!isProviderType(value)) {
496
622
  throw new CliError(
497
- t4("cli.config.unknown_provider", { value }),
623
+ t5("cli.config.unknown_provider", { value }),
498
624
  1,
499
- t4("cli.config.supported", { list: PROVIDER_TYPES.join(", ") })
625
+ t5("cli.config.supported", { list: PROVIDER_TYPES.join(", ") })
500
626
  );
501
627
  }
502
628
  return yaml.replace(/^(\s*)type:.*$/m, `$1type: ${value}`);
@@ -505,134 +631,146 @@ function applySet(yaml, key, value) {
505
631
  case "permission":
506
632
  if (!isPermissionLevel(value)) {
507
633
  throw new CliError(
508
- t4("cli.config.unknown_permission", { value }),
634
+ t5("cli.config.unknown_permission", { value }),
509
635
  1,
510
- t4("cli.config.supported", { list: PERMISSION_LEVELS.join(", ") })
636
+ t5("cli.config.supported", { list: PERMISSION_LEVELS.join(", ") })
511
637
  );
512
638
  }
513
639
  return setScalar(yaml, "permission", value);
514
640
  case "shell": {
515
641
  if (!SHELL_KINDS.includes(value)) {
516
642
  throw new CliError(
517
- t4("cli.config.unknown_shell", { value }),
643
+ t5("cli.config.unknown_shell", { value }),
518
644
  1,
519
- t4("cli.config.supported", { list: SHELL_KINDS.join(", ") })
645
+ t5("cli.config.supported", { list: SHELL_KINDS.join(", ") })
520
646
  );
521
647
  }
522
648
  return setScalar(yaml, "shell", value);
523
649
  }
524
- case "models.utility": {
650
+ case "models.utility":
651
+ case "fallback.model": {
525
652
  if (!parseModelRef(value)) {
526
- throw new CliError(t4("cli.config.utility_empty"), 1, t4("cli.config.utility_hint"));
653
+ throw new CliError(t5("cli.config.utility_empty"), 1, t5("cli.config.utility_hint"));
527
654
  }
528
- return setSectionField(yaml, "models", "utility", value);
655
+ const [section, field] = key.split(".");
656
+ return setSectionField(yaml, section, field, value);
529
657
  }
530
658
  default: {
531
- const field = budgetField(key);
532
- const validate = BUDGET_FIELDS[field];
533
- if (!validate)
659
+ const scalar = SCALAR_FIELDS[key];
660
+ if (scalar) {
661
+ if (!scalar(value)) throw new CliError(t5("cli.config.bad_value", { key, value }));
662
+ return setScalar(yaml, key, value);
663
+ }
664
+ const [section, field] = splitSection(key);
665
+ const validate = field === void 0 ? void 0 : SECTION_FIELDS[section]?.[field];
666
+ if (!validate || field === void 0)
534
667
  throw new CliError(
535
- t4("cli.config.unknown_key", { key }),
668
+ t5("cli.config.unknown_key", { key }),
536
669
  1,
537
- t4("cli.config.supported", { list: knownKeys() })
670
+ t5("cli.config.supported", { list: knownKeys() })
538
671
  );
539
- if (!validate(value)) throw new CliError(t4("cli.config.bad_value", { key, value }));
540
- return setSectionField(yaml, "budget", field, value);
672
+ if (!validate(value)) throw new CliError(t5("cli.config.bad_value", { key, value }));
673
+ return setSectionField(yaml, section, field, value);
541
674
  }
542
675
  }
543
676
  }
544
677
  function applyUnset(yaml, key) {
545
678
  if (key === "model" || key === "permission" || key === "shell") return unsetScalar(yaml, key);
679
+ if (SCALAR_FIELDS[key]) return unsetScalar(yaml, key);
546
680
  if (key === "models.utility") return unsetSectionField(yaml, "models", "utility");
547
- const field = budgetField(key);
548
- if (BUDGET_FIELDS[field]) return unsetSectionField(yaml, "budget", field);
549
- throw new CliError(t4("cli.config.cannot_unset", { key }), 1, t4("cli.config.can_unset"));
681
+ if (key === "fallback.model") return unsetSectionField(yaml, "fallback", "model");
682
+ const [section, field] = splitSection(key);
683
+ if (field !== void 0 && SECTION_FIELDS[section]?.[field]) {
684
+ return unsetSectionField(yaml, section, field);
685
+ }
686
+ throw new CliError(t5("cli.config.cannot_unset", { key }), 1, t5("cli.config.can_unset"));
550
687
  }
551
- function budgetField(key) {
552
- return key.startsWith("budget.") ? key.slice("budget.".length) : "";
688
+ function splitSection(key) {
689
+ const dot = key.indexOf(".");
690
+ return dot < 0 ? [key, void 0] : [key.slice(0, dot), key.slice(dot + 1)];
553
691
  }
554
692
  // src/commands/mcp.ts
555
- import { t as t5, uiDateLocale } from "@epoch-agent/infra";
693
+ import { t as t6, uiDateLocale } from "@epoch-agent/infra";
556
694
  import {
557
695
  listMcpServers,
558
696
  mcpLogin,
559
697
  mcpLogout,
560
698
  probeMcpServer
561
699
  } from "@epoch-agent/runtime";
562
- var log3 = (msg) => process.stdout.write(msg + "\n");
700
+ var log4 = (msg) => process.stdout.write(msg + "\n");
563
701
  var warn = (msg) => process.stderr.write(msg + "\n");
564
702
  function stateLabel(state) {
565
703
  switch (state) {
566
704
  case "not-applicable":
567
- return t5("mcp.state_not_applicable");
705
+ return t6("mcp.state_not_applicable");
568
706
  case "bearer-header":
569
- return t5("mcp.state_bearer");
707
+ return t6("mcp.state_bearer");
570
708
  case "authorized":
571
- return t5("mcp.state_authorized");
709
+ return t6("mcp.state_authorized");
572
710
  case "refreshable":
573
- return t5("mcp.state_refreshable");
711
+ return t6("mcp.state_refreshable");
574
712
  case "logged-out":
575
- return t5("mcp.state_logged_out");
713
+ return t6("mcp.state_logged_out");
576
714
  }
577
715
  }
578
716
  function registerMcpCommand(program2) {
579
- const cmd = program2.command("mcp").description(t5("mcp.cmd_root"));
580
- cmd.command("list", { isDefault: true }).description(t5("mcp.cmd_list")).action(() => guardAsync(() => printList()));
581
- cmd.command("status").description(t5("mcp.cmd_status")).argument("<name>", t5("mcp.arg_name")).action(
717
+ const cmd = program2.command("mcp").description(t6("mcp.cmd_root"));
718
+ cmd.command("list", { isDefault: true }).description(t6("mcp.cmd_list")).action(() => guardAsync(() => printList()));
719
+ cmd.command("status").description(t6("mcp.cmd_status")).argument("<name>", t6("mcp.arg_name")).action(
582
720
  (name) => guardAsync(async () => {
583
- log3(t5("mcp.connecting", { name }));
721
+ log4(t6("mcp.connecting", { name }));
584
722
  const result = await probeMcpServer(name, { homeDir: EPOCH_HOME });
585
723
  if (!result.connected) {
586
724
  warn(
587
- result.error ? t5("mcp.connect_failed_reason", { reason: result.error }) : t5("mcp.connect_failed")
725
+ result.error ? t6("mcp.connect_failed_reason", { reason: result.error }) : t6("mcp.connect_failed")
588
726
  );
589
- if (result.needsLogin) warn(t5("mcp.needs_login", { name }));
727
+ if (result.needsLogin) warn(t6("mcp.needs_login", { name }));
590
728
  process.exit(1);
591
729
  }
592
- log3(`\u2713 ${t5("mcp.connected", { count: result.toolNames.length })}`);
593
- for (const tool of result.toolNames) log3(` ${tool}`);
730
+ log4(`\u2713 ${t6("mcp.connected", { count: result.toolNames.length })}`);
731
+ for (const tool of result.toolNames) log4(` ${tool}`);
594
732
  })
595
733
  );
596
- cmd.command("login").description(t5("mcp.cmd_login")).argument("<name>", t5("mcp.arg_name")).option("--port <port>", t5("mcp.opt_port")).option("--scope <scope>", t5("mcp.opt_scope")).action(
734
+ cmd.command("login").description(t6("mcp.cmd_login")).argument("<name>", t6("mcp.arg_name")).option("--port <port>", t6("mcp.opt_port")).option("--scope <scope>", t6("mcp.opt_scope")).action(
597
735
  (name, opts) => guardAsync(async () => {
598
736
  const port = opts.port === void 0 ? void 0 : parsePort(opts.port);
599
737
  const { refreshedOnly } = await mcpLogin(name, {
600
738
  homeDir: EPOCH_HOME,
601
739
  ...port === void 0 ? {} : { port },
602
740
  ...opts.scope === void 0 ? {} : { scope: opts.scope },
603
- print: log3
741
+ print: log4
604
742
  });
605
- log3(
606
- refreshedOnly ? `\u2713 ${t5("mcp.refreshed", { name })}` : `\u2713 ${t5("mcp.authorized", { name })}`
743
+ log4(
744
+ refreshedOnly ? `\u2713 ${t6("mcp.refreshed", { name })}` : `\u2713 ${t6("mcp.authorized", { name })}`
607
745
  );
608
746
  })
609
747
  );
610
- cmd.command("logout").description(t5("mcp.cmd_logout")).argument("<name>", t5("mcp.arg_name")).action(
748
+ cmd.command("logout").description(t6("mcp.cmd_logout")).argument("<name>", t6("mcp.arg_name")).action(
611
749
  (name) => guardAsync(async () => {
612
750
  const removed = await mcpLogout(name, { homeDir: EPOCH_HOME });
613
- log3(removed ? `\u2713 ${t5("mcp.removed", { name })}` : t5("mcp.nothing_stored", { name }));
751
+ log4(removed ? `\u2713 ${t6("mcp.removed", { name })}` : t6("mcp.nothing_stored", { name }));
614
752
  })
615
753
  );
616
754
  }
617
755
  async function printList() {
618
756
  const { servers, issues, configPath: configPath2 } = await listMcpServers({ homeDir: EPOCH_HOME });
619
757
  for (const issue of issues)
620
- warn(t5("mcp.config_issue", { path: issue.path, message: issue.message }));
621
- log3(t5("mcp.list_head", { path: configPath2 }));
758
+ warn(t6("mcp.config_issue", { path: issue.path, message: issue.message }));
759
+ log4(t6("mcp.list_head", { path: configPath2 }));
622
760
  if (servers.length === 0) {
623
- log3(t5("mcp.list_empty"));
761
+ log4(t6("mcp.list_empty"));
624
762
  return;
625
763
  }
626
- for (const s of servers) log3(` ${describe(s)}`);
764
+ for (const s of servers) log4(` ${describe(s)}`);
627
765
  }
628
766
  function describe(s) {
629
767
  const target = s.config.transport === "stdio" ? s.config.command : s.config.url;
630
768
  const parts = [
631
769
  `${s.config.name} [${s.config.transport}] ${target ?? ""}`,
632
- t5("mcp.auth_line", { state: stateLabel(s.auth.state) })
770
+ t6("mcp.auth_line", { state: stateLabel(s.auth.state) })
633
771
  ];
634
772
  if (s.auth.expiresAt) {
635
- parts[1] += t5("mcp.expires_at", {
773
+ parts[1] += t6("mcp.expires_at", {
636
774
  when: new Date(s.auth.expiresAt).toLocaleString(uiDateLocale())
637
775
  });
638
776
  }
@@ -641,42 +779,42 @@ function describe(s) {
641
779
  function parsePort(raw) {
642
780
  const port = Number(raw);
643
781
  if (!Number.isInteger(port) || port < 1024 || port > 65535) {
644
- throw new Error(t5("mcp.bad_port", { raw }));
782
+ throw new Error(t6("mcp.bad_port", { raw }));
645
783
  }
646
784
  return port;
647
785
  }
648
786
  function guardAsync(fn) {
649
787
  fn().catch((err2) => {
650
- warn(t5("mcp.error", { message: err2 instanceof Error ? err2.message : String(err2) }));
788
+ warn(t6("mcp.error", { message: err2 instanceof Error ? err2.message : String(err2) }));
651
789
  process.exit(1);
652
790
  });
653
791
  }
654
792
  // src/commands/model.ts
655
793
  import { input, password, select } from "@inquirer/prompts";
656
794
  import { isNonInteractive, readProviderKeyEnv } from "@epoch-agent/core";
657
- import { t as t6 } from "@epoch-agent/infra";
795
+ import { t as t7 } from "@epoch-agent/infra";
658
796
  import {
659
797
  apiKeyEnvVar,
660
798
  PROVIDER_INFOS,
661
799
  PROVIDER_TYPES as PROVIDER_TYPES2
662
800
  } from "@epoch-agent/protocol";
663
801
  import { providerLabel } from "@epoch-agent/runtime";
664
- var log4 = (msg) => process.stdout.write(msg + "\n");
802
+ var log5 = (msg) => process.stdout.write(msg + "\n");
665
803
  var CUSTOM = "__custom__";
666
804
  function registerModelCommand(program2) {
667
- program2.command("model").description(t6("model.cmd_root")).option("-r, --refresh", t6("model.opt_refresh")).action(async (opts) => {
805
+ program2.command("model").description(t7("model.cmd_root")).option("-r, --refresh", t7("model.opt_refresh")).action(async (opts) => {
668
806
  ensureEpochHome();
669
807
  if (opts.refresh) return refreshCache();
670
808
  if (isNonInteractive()) {
671
- throw new CliError(t6("model.needs_tty"), 1, t6("model.needs_tty_hint"));
809
+ throw new CliError(t7("model.needs_tty"), 1, t7("model.needs_tty_hint"));
672
810
  }
673
811
  await runWizard();
674
812
  });
675
813
  }
676
814
  async function refreshCache() {
677
815
  const { clearModelCache } = await import("@epoch-agent/core");
678
- for (const t39 of PROVIDER_TYPES2) clearModelCache(EPOCH_HOME, t39);
679
- log4(t6("model.cache_cleared"));
816
+ for (const t40 of PROVIDER_TYPES2) clearModelCache(EPOCH_HOME, t40);
817
+ log5(t7("model.cache_cleared"));
680
818
  }
681
819
  function readCurrentSelection() {
682
820
  const yaml = readConfigYaml(CONFIG_PATH);
@@ -686,7 +824,7 @@ async function runWizard() {
686
824
  await ensureSecrets();
687
825
  const current = readCurrentSelection();
688
826
  const provider = await select({
689
- message: t6("model.pick_provider"),
827
+ message: t7("model.pick_provider"),
690
828
  choices: providerChoices(current.provider),
691
829
  pageSize: listPageSize(PROVIDER_INFOS.filter((p) => p.interactive).length),
692
830
  ...isKnownProvider(current.provider) ? { default: current.provider } : {}
@@ -695,42 +833,42 @@ async function runWizard() {
695
833
  const keyForDiscover = await resolveApiKey(provider);
696
834
  const { discoverModels } = await import("@epoch-agent/core");
697
835
  const result = await discoverModels(EPOCH_HOME, provider, keyForDiscover, baseUrl);
698
- log4(describeDiscovery(result.source, result.models.length, keyForDiscover !== ""));
836
+ log5(describeDiscovery(result.source, result.models.length, keyForDiscover !== ""));
699
837
  const model = await pickModel(result.models, result.source, carriedModel(provider, current));
700
838
  let yaml = readConfigYaml(CONFIG_PATH);
701
839
  yaml = setSectionField(yaml, "provider", "type", provider);
702
840
  if (baseUrl) yaml = setSectionField(yaml, "provider", "baseUrl", baseUrl);
703
841
  yaml = setScalar(yaml, "model", model);
704
842
  writeConfigYaml(CONFIG_PATH, yaml);
705
- log4(`
843
+ log5(`
706
844
  \u2705 ${provider} / ${model}
707
- ${t6("model.ready")}`);
845
+ ${t7("model.ready")}`);
708
846
  }
709
847
  async function ensureSecrets() {
710
848
  try {
711
849
  const { ensureSecretsReady } = await import("@epoch-agent/runtime");
712
850
  await ensureSecretsReady();
713
851
  } catch (err2) {
714
- log4(t6("model.secret_init_failed", { reason: describeError(err2) }));
852
+ log5(t7("model.secret_init_failed", { reason: describeError(err2) }));
715
853
  }
716
854
  }
717
855
  async function resolveApiKey(provider) {
718
856
  const envKey = apiKeyEnvVar(provider);
719
857
  if (!envKey) return "";
720
858
  const existing = readProviderKeyEnv(EPOCH_HOME)[envKey];
721
- const message = existing ? t6("model.api_key_existing", { envKey }) : t6("model.api_key", { envKey });
859
+ const message = existing ? t7("model.api_key_existing", { envKey }) : t7("model.api_key", { envKey });
722
860
  const typed = (await password({ message, mask: "*" })).trim();
723
861
  if (!typed) return existing ?? "";
724
862
  await saveApiKey(envKey, typed);
725
863
  return typed;
726
864
  }
727
865
  async function saveApiKey(envKey, apiKey) {
728
- const result = await writeProviderKey(envKey, apiKey, ENV_PATH);
729
- log4(result.encrypted ? t6("model.key_stored", { detail: result.detail }) : ` \u26A0 ${result.detail}`);
866
+ const result = await writeProviderSecret(envKey, apiKey, ENV_PATH);
867
+ log5(result.encrypted ? t7("model.key_stored", { detail: result.detail }) : ` \u26A0 ${result.detail}`);
730
868
  }
731
869
  async function askBaseUrl() {
732
870
  const answer = (await input({
733
- message: t6("model.ask_base_url"),
871
+ message: t7("model.ask_base_url"),
734
872
  default: "http://localhost:8080/v1"
735
873
  })).trim();
736
874
  return answer || void 0;
@@ -739,17 +877,17 @@ async function pickModel(models, source, currentModel) {
739
877
  const choices3 = modelChoices(models, source, currentModel);
740
878
  if (choices3.length === 0) {
741
879
  const fallback2 = currentModel ?? "gpt-4o-mini";
742
- return await input({ message: t6("model.type_model"), default: fallback2 }) || fallback2;
880
+ return await input({ message: t7("model.type_model"), default: fallback2 }) || fallback2;
743
881
  }
744
882
  const picked = await select({
745
- message: t6("model.pick_model"),
883
+ message: t7("model.pick_model"),
746
884
  choices: choices3,
747
885
  pageSize: listPageSize(choices3.length),
748
886
  ...currentModel && models.includes(currentModel) ? { default: currentModel } : {}
749
887
  });
750
888
  if (picked !== CUSTOM) return picked;
751
889
  const fallback = currentModel ?? models[0] ?? "gpt-4o-mini";
752
- return await input({ message: t6("model.type_model"), default: fallback }) || fallback;
890
+ return await input({ message: t7("model.type_model"), default: fallback }) || fallback;
753
891
  }
754
892
  function isKnownProvider(value) {
755
893
  return PROVIDER_INFOS.some((p) => p.interactive && p.type === value);
@@ -761,7 +899,7 @@ function providerChoices(currentProvider) {
761
899
  return PROVIDER_INFOS.filter((p) => p.interactive).map((p) => {
762
900
  const label = providerLabel(p);
763
901
  return {
764
- name: p.type === currentProvider ? t6("model.current", { label }) : label,
902
+ name: p.type === currentProvider ? t7("model.current", { label }) : label,
765
903
  value: p.type
766
904
  };
767
905
  });
@@ -769,16 +907,16 @@ function providerChoices(currentProvider) {
769
907
  function modelChoices(models, source, currentModel) {
770
908
  if (models.length === 0) return [];
771
909
  const choices3 = models.map((m) => ({
772
- name: m === currentModel ? t6("model.current", { label: m }) : m,
910
+ name: m === currentModel ? t7("model.current", { label: m }) : m,
773
911
  value: m
774
912
  }));
775
913
  if (currentModel && !models.includes(currentModel)) {
776
914
  choices3.unshift({
777
- name: t6("model.current_not_listed", { label: currentModel }),
915
+ name: t7("model.current_not_listed", { label: currentModel }),
778
916
  value: currentModel
779
917
  });
780
918
  }
781
- if (source !== "live") choices3.push({ name: t6("model.custom_entry"), value: CUSTOM });
919
+ if (source !== "live") choices3.push({ name: t7("model.custom_entry"), value: CUSTOM });
782
920
  return choices3;
783
921
  }
784
922
  function listPageSize(itemCount, rows = process.stdout.rows) {
@@ -786,10 +924,10 @@ function listPageSize(itemCount, rows = process.stdout.rows) {
786
924
  return Math.min(itemCount, Math.max(3, height - 3));
787
925
  }
788
926
  function describeDiscovery(source, count, hasKey) {
789
- if (source === "live") return t6("model.from_api", { count });
790
- const why = hasKey ? t6("model.why_fetch_failed") : t6("model.why_no_key");
791
- const what = source === "cache" ? t6("model.fallback_cache") : t6("model.fallback_static");
792
- return t6("model.fallback_line", { why, what });
927
+ if (source === "live") return t7("model.from_api", { count });
928
+ const why = hasKey ? t7("model.why_fetch_failed") : t7("model.why_no_key");
929
+ const what = source === "cache" ? t7("model.fallback_cache") : t7("model.fallback_static");
930
+ return t7("model.fallback_line", { why, what });
793
931
  }
794
932
  function describeError(err2) {
795
933
  return err2 instanceof Error ? err2.message : String(err2);
@@ -818,98 +956,98 @@ import {
818
956
  marketplacesPath,
819
957
  pluginsDir,
820
958
  pluginsStatePath,
821
- t as t7
959
+ t as t8
822
960
  } from "@epoch-agent/infra";
823
- var log5 = (msg) => {
961
+ var log6 = (msg) => {
824
962
  process.stdout.write(msg + "\n");
825
963
  };
826
964
  function locations() {
827
965
  return { pluginsDir: pluginsDir(EPOCH_HOME), statePath: pluginsStatePath(EPOCH_HOME) };
828
966
  }
829
967
  function registerPluginCommand(program2) {
830
- const cmd = program2.command("plugin").description(t7("plugin.cmd_root"));
968
+ const cmd = program2.command("plugin").description(t8("plugin.cmd_root"));
831
969
  registerBasics(cmd);
832
970
  registerLifecycle(cmd);
833
971
  registerMarketplace(cmd);
834
972
  }
835
973
  function registerBasics(cmd) {
836
- cmd.command("list", { isDefault: true }).alias("ls").description(t7("plugin.cmd_list")).option("--verbose", t7("plugin.opt_verbose")).action((opts) => {
974
+ cmd.command("list", { isDefault: true }).alias("ls").description(t8("plugin.cmd_list")).option("--verbose", t8("plugin.opt_verbose")).action((opts) => {
837
975
  printList2(opts.verbose === true);
838
976
  });
839
- cmd.command("install").alias("add").description(t7("plugin.cmd_install")).argument("<source>", t7("plugin.arg_source")).option("-y, --yes", t7("plugin.opt_yes_install")).action(async (source, opts) => {
977
+ cmd.command("install").alias("add").description(t8("plugin.cmd_install")).argument("<source>", t8("plugin.arg_source")).option("-y, --yes", t8("plugin.opt_yes_install")).action(async (source, opts) => {
840
978
  await runInstall(source, opts.yes === true);
841
979
  });
842
- cmd.command("validate").description(t7("plugin.cmd_validate")).argument("[path]", t7("plugin.arg_dir")).action((path) => {
980
+ cmd.command("validate").description(t8("plugin.cmd_validate")).argument("[path]", t8("plugin.arg_dir")).action((path) => {
843
981
  validateDir(path ?? process.cwd());
844
982
  });
845
983
  }
846
984
  function registerLifecycle(cmd) {
847
- cmd.command("uninstall").alias("rm").description(t7("plugin.cmd_uninstall")).argument("<name>", t7("plugin.arg_name")).action(async (name) => {
985
+ cmd.command("uninstall").alias("rm").description(t8("plugin.cmd_uninstall")).argument("<name>", t8("plugin.arg_name")).action(async (name) => {
848
986
  const outcome = await uninstallPlugin(name, { statePath: pluginsStatePath(EPOCH_HOME) });
849
987
  if (!outcome.ok) throw new CliError(outcome.reason);
850
- log5(`\u2713 ${outcome.message}`);
988
+ log6(`\u2713 ${outcome.message}`);
851
989
  });
852
- cmd.command("disable").description(t7("plugin.cmd_disable")).argument("<name>", t7("plugin.arg_name")).action(async (name) => {
990
+ cmd.command("disable").description(t8("plugin.cmd_disable")).argument("<name>", t8("plugin.arg_name")).action(async (name) => {
853
991
  await toggle(name, false);
854
992
  });
855
- cmd.command("enable").description(t7("plugin.cmd_enable")).argument("<name>", t7("plugin.arg_name")).action(async (name) => {
993
+ cmd.command("enable").description(t8("plugin.cmd_enable")).argument("<name>", t8("plugin.arg_name")).action(async (name) => {
856
994
  await toggle(name, true);
857
995
  });
858
- cmd.command("update").description(t7("plugin.cmd_update")).argument("<name>", t7("plugin.arg_name")).option("-y, --yes", t7("plugin.opt_yes")).action(async (name, opts) => {
996
+ cmd.command("update").description(t8("plugin.cmd_update")).argument("<name>", t8("plugin.arg_name")).option("-y, --yes", t8("plugin.opt_yes")).action(async (name, opts) => {
859
997
  await runUpdate(name, opts.yes === true);
860
998
  });
861
999
  }
862
1000
  function registerMarketplace(cmd) {
863
- const market = cmd.command("marketplace").alias("mp").description(t7("plugin.cmd_market"));
864
- market.command("add").description(t7("plugin.cmd_market_add")).argument("<source>", t7("plugin.arg_market_source")).action(async (source) => {
1001
+ const market = cmd.command("marketplace").alias("mp").description(t8("plugin.cmd_market"));
1002
+ market.command("add").description(t8("plugin.cmd_market_add")).argument("<source>", t8("plugin.arg_market_source")).action(async (source) => {
865
1003
  const outcome = await addMarketplace(source, { statePath: marketplacesPath(EPOCH_HOME) });
866
1004
  if (!outcome.ok) throw new CliError(outcome.reason);
867
1005
  const count = outcome.record.catalog.plugins.length;
868
- log5(`\u2713 ${t7("plugin.market_added", { name: outcome.record.name, count })}`);
869
- log5(t7("plugin.market_added_hint"));
1006
+ log6(`\u2713 ${t8("plugin.market_added", { name: outcome.record.name, count })}`);
1007
+ log6(t8("plugin.market_added_hint"));
870
1008
  });
871
- market.command("list", { isDefault: true }).alias("ls").description(t7("plugin.cmd_market_list")).action(printMarketplaces);
872
- market.command("remove").alias("rm").description(t7("plugin.cmd_market_remove")).argument("<name>", t7("plugin.arg_market_name")).action(async (name) => {
1009
+ market.command("list", { isDefault: true }).alias("ls").description(t8("plugin.cmd_market_list")).action(printMarketplaces);
1010
+ market.command("remove").alias("rm").description(t8("plugin.cmd_market_remove")).argument("<name>", t8("plugin.arg_market_name")).action(async (name) => {
873
1011
  const outcome = await removeMarketplace(name, { statePath: marketplacesPath(EPOCH_HOME) });
874
1012
  if (!outcome.ok)
875
- throw new CliError(outcome.reason ?? t7("plugin.market_remove_failed", { name }));
876
- log5(`\u2713 ${t7("plugin.market_removed", { name })}`);
1013
+ throw new CliError(outcome.reason ?? t8("plugin.market_remove_failed", { name }));
1014
+ log6(`\u2713 ${t8("plugin.market_removed", { name })}`);
877
1015
  });
878
- market.command("update").description(t7("plugin.cmd_market_update")).argument("<name>", t7("plugin.arg_market_name")).action(async (name) => {
1016
+ market.command("update").description(t8("plugin.cmd_market_update")).argument("<name>", t8("plugin.arg_market_name")).action(async (name) => {
879
1017
  const outcome = await updateMarketplace(name, { statePath: marketplacesPath(EPOCH_HOME) });
880
1018
  if (!outcome.ok) throw new CliError(outcome.reason);
881
- log5(
882
- `\u2713 ${t7("plugin.market_updated", {
1019
+ log6(
1020
+ `\u2713 ${t8("plugin.market_updated", {
883
1021
  name,
884
1022
  count: outcome.record.catalog.plugins.length
885
1023
  })}`
886
1024
  );
887
1025
  });
888
- cmd.command("search").description(t7("plugin.cmd_search")).argument("[keyword]", t7("plugin.arg_keyword")).action((keyword) => {
1026
+ cmd.command("search").description(t8("plugin.cmd_search")).argument("[keyword]", t8("plugin.arg_keyword")).action((keyword) => {
889
1027
  printSearch(keyword ?? "");
890
1028
  });
891
1029
  }
892
1030
  function printList2(verbose) {
893
1031
  const artifacts = loadPlugins({ statePath: pluginsStatePath(EPOCH_HOME) });
894
1032
  if (artifacts.loaded.length === 0 && artifacts.skipped.length === 0) {
895
- log5(t7("plugin.none_installed"));
896
- log5(t7("plugin.none_installed_hint"));
1033
+ log6(t8("plugin.none_installed"));
1034
+ log6(t8("plugin.none_installed_hint"));
897
1035
  return;
898
1036
  }
899
- log5(`${t7("plugin.installed_head", { path: pluginsStatePath(EPOCH_HOME) })}
1037
+ log6(`${t8("plugin.installed_head", { path: pluginsStatePath(EPOCH_HOME) })}
900
1038
  `);
901
1039
  for (const plugin of artifacts.loaded) {
902
- log5(loadedLine(plugin));
1040
+ log6(loadedLine(plugin));
903
1041
  if (!verbose) continue;
904
1042
  for (const line of renderInventory(scanPluginDir(plugin.dir, plugin.name))) {
905
- log5(` ${line}`);
1043
+ log6(` ${line}`);
906
1044
  }
907
- log5("");
1045
+ log6("");
908
1046
  }
909
- for (const skipped of artifacts.skipped) log5(skippedLine(skipped));
910
- if (artifacts.skipped.length > 0) log5(`
1047
+ for (const skipped of artifacts.skipped) log6(skippedLine(skipped));
1048
+ if (artifacts.skipped.length > 0) log6(`
911
1049
  ${markLegend()}`);
912
- for (const detail of issueDetails(artifacts.issues)) log5(`
1050
+ for (const detail of issueDetails(artifacts.issues)) log6(`
913
1051
  \u26A0 ${detail}`);
914
1052
  }
915
1053
  function loadedLine(plugin) {
@@ -918,7 +1056,7 @@ function loadedLine(plugin) {
918
1056
  function countsLine(counts) {
919
1057
  const parts = [];
920
1058
  const add = (n, key) => {
921
- if (n > 0) parts.push(t7(key, { count: n }));
1059
+ if (n > 0) parts.push(t8(key, { count: n }));
922
1060
  };
923
1061
  add(counts.commands, "plugin.n_commands");
924
1062
  add(counts.roles, "plugin.n_roles");
@@ -926,84 +1064,84 @@ function countsLine(counts) {
926
1064
  add(counts.hooks, "plugin.n_hooks");
927
1065
  add(counts.denyRules, "plugin.n_deny");
928
1066
  add(counts.mcpServers, "plugin.n_mcp");
929
- return parts.length === 0 ? t7("plugin.brings_nothing") : parts.join(" \xB7 ");
1067
+ return parts.length === 0 ? t8("plugin.brings_nothing") : parts.join(" \xB7 ");
930
1068
  }
931
1069
  function markLegend() {
932
- return t7("plugin.mark_legend");
1070
+ return t8("plugin.mark_legend");
933
1071
  }
934
1072
  function skippedLine(skipped) {
935
1073
  return ` ${skipped.disabled ? "\u25CB" : "\u2717"} ${skipped.name} ${skipped.reason}`;
936
1074
  }
937
1075
  async function runInstall(input2, yes) {
938
1076
  if (!yes && isNonInteractive2()) {
939
- throw new CliError(t7("plugin.install_needs_tty"), 1, t7("plugin.install_needs_tty_hint"));
1077
+ throw new CliError(t8("plugin.install_needs_tty"), 1, t8("plugin.install_needs_tty_hint"));
940
1078
  }
941
1079
  const ref = resolveMarketplaceRef(input2, marketplacesPath(EPOCH_HOME));
942
1080
  if (ref && !ref.ok) throw new CliError(ref.reason);
943
1081
  const source = ref?.ok ? ref.ref.source : input2;
944
- if (ref?.ok) log5(`${input2} \u2192 ${source}`);
1082
+ if (ref?.ok) log6(`${input2} \u2192 ${source}`);
945
1083
  const outcome = await installPlugin(source, {
946
1084
  ...locations(),
947
1085
  epochVersion: currentEpochVersion(),
948
- onProgress: log5,
1086
+ onProgress: log6,
949
1087
  ...ref?.ok ? { marketplace: ref.ref.marketplace } : {},
950
1088
  ...yes ? {} : { confirm: askInstall }
951
1089
  });
952
1090
  if (!outcome.ok) {
953
1091
  if (outcome.cancelled) {
954
- log5(t7("plugin.nothing_installed"));
1092
+ log6(t8("plugin.nothing_installed"));
955
1093
  return;
956
1094
  }
957
- throw new CliError(t7("plugin.install_failed", { source, reason: outcome.reason }));
1095
+ throw new CliError(t8("plugin.install_failed", { source, reason: outcome.reason }));
958
1096
  }
959
- log5(
1097
+ log6(
960
1098
  `
961
- \u2713 ${t7("plugin.installed", {
1099
+ \u2713 ${t8("plugin.installed", {
962
1100
  name: outcome.record.name,
963
1101
  version: outcome.record.version,
964
1102
  path: outcome.record.path
965
1103
  })}`
966
1104
  );
967
1105
  if (outcome.record.linked) {
968
- log5(t7("plugin.installed_linked"));
1106
+ log6(t8("plugin.installed_linked"));
969
1107
  }
970
- log5(t7("plugin.installed_restart"));
1108
+ log6(t8("plugin.installed_restart"));
971
1109
  }
972
1110
  async function runUpdate(name, yes) {
973
1111
  if (!yes && isNonInteractive2()) {
974
- throw new CliError(t7("plugin.update_needs_tty"), 1, t7("plugin.update_needs_tty_hint"));
1112
+ throw new CliError(t8("plugin.update_needs_tty"), 1, t8("plugin.update_needs_tty_hint"));
975
1113
  }
976
1114
  const outcome = await updatePlugin(name, {
977
1115
  ...locations(),
978
1116
  epochVersion: currentEpochVersion(),
979
- onProgress: log5,
1117
+ onProgress: log6,
980
1118
  ...yes ? {} : { confirm: askInstall }
981
1119
  });
982
1120
  if (!outcome.ok) throw new CliError(outcome.reason);
983
- log5(
984
- `\u2713 ${"message" in outcome ? outcome.message : t7("plugin.updated_to", { version: outcome.record.version })}`
1121
+ log6(
1122
+ `\u2713 ${"message" in outcome ? outcome.message : t8("plugin.updated_to", { version: outcome.record.version })}`
985
1123
  );
986
1124
  }
987
1125
  async function askInstall(preview2) {
988
- for (const line of renderPreview(preview2)) log5(line);
1126
+ for (const line of renderPreview(preview2)) log6(line);
989
1127
  const { confirm } = await import("@inquirer/prompts");
990
- return confirm({ message: t7("plugin.confirm_install"), default: false });
1128
+ return confirm({ message: t8("plugin.confirm_install"), default: false });
991
1129
  }
992
1130
  function renderPreview(preview2) {
993
1131
  const { manifest, source, inventory } = preview2;
994
1132
  const lines = [""];
995
- lines.push(t7("plugin.will_install", { name: manifest.name, version: manifest.version }));
1133
+ lines.push(t8("plugin.will_install", { name: manifest.name, version: manifest.version }));
996
1134
  if (manifest.description) lines.push(` ${manifest.description}`);
997
- lines.push(t7("plugin.preview_source", { raw: source.raw, type: source.type }));
998
- if (source.sha256) lines.push(t7("plugin.preview_sha", { sha: source.sha256 }));
999
- if (manifest.author) lines.push(t7("plugin.preview_author", { name: manifest.author.name }));
1000
- if (manifest.homepage) lines.push(t7("plugin.preview_homepage", { url: manifest.homepage }));
1135
+ lines.push(t8("plugin.preview_source", { raw: source.raw, type: source.type }));
1136
+ if (source.sha256) lines.push(t8("plugin.preview_sha", { sha: source.sha256 }));
1137
+ if (manifest.author) lines.push(t8("plugin.preview_author", { name: manifest.author.name }));
1138
+ if (manifest.homepage) lines.push(t8("plugin.preview_homepage", { url: manifest.homepage }));
1001
1139
  if (preview2.versionUnmet) {
1002
1140
  const { required, current } = preview2.versionUnmet;
1003
- lines.push(` ${t7("plugin.preview_version_unmet", { required, current })}`);
1141
+ lines.push(` ${t8("plugin.preview_version_unmet", { required, current })}`);
1004
1142
  }
1005
1143
  lines.push("");
1006
- lines.push(t7("plugin.brings_head_indented"));
1144
+ lines.push(t8("plugin.brings_head_indented"));
1007
1145
  for (const line of renderInventory(inventory)) lines.push(` ${line}`);
1008
1146
  lines.push("");
1009
1147
  return lines;
@@ -1011,105 +1149,105 @@ function renderPreview(preview2) {
1011
1149
  function renderInventory(inv) {
1012
1150
  const lines = [];
1013
1151
  if (inventoryTotal(inv) === 0) {
1014
- lines.push(t7("plugin.inventory_empty"));
1152
+ lines.push(t8("plugin.inventory_empty"));
1015
1153
  }
1016
1154
  if (inv.commands.length > 0)
1017
- lines.push(t7("plugin.inv_commands", { count: inv.commands.length, names: list(inv.commands) }));
1155
+ lines.push(t8("plugin.inv_commands", { count: inv.commands.length, names: list(inv.commands) }));
1018
1156
  if (inv.roles.length > 0)
1019
- lines.push(t7("plugin.inv_roles", { count: inv.roles.length, names: list(inv.roles) }));
1157
+ lines.push(t8("plugin.inv_roles", { count: inv.roles.length, names: list(inv.roles) }));
1020
1158
  if (inv.skills.length > 0)
1021
- lines.push(t7("plugin.inv_skills", { count: inv.skills.length, names: list(inv.skills) }));
1159
+ lines.push(t8("plugin.inv_skills", { count: inv.skills.length, names: list(inv.skills) }));
1022
1160
  if (inv.hooks.length > 0) {
1023
- const tally = inv.hooks.map((h) => `${h.type} \xD7 ${h.count}`).join(t7("plugin.inv_join"));
1024
- lines.push(t7("plugin.inv_hooks", { tally }));
1161
+ const tally = inv.hooks.map((h) => `${h.type} \xD7 ${h.count}`).join(t8("plugin.inv_join"));
1162
+ lines.push(t8("plugin.inv_hooks", { tally }));
1025
1163
  }
1026
- if (inv.denyRules > 0) lines.push(t7("plugin.inv_deny", { count: inv.denyRules }));
1164
+ if (inv.denyRules > 0) lines.push(t8("plugin.inv_deny", { count: inv.denyRules }));
1027
1165
  if (inv.mcpServers.length > 0) {
1028
1166
  lines.push(
1029
- t7("plugin.preview_mcp", {
1167
+ t8("plugin.preview_mcp", {
1030
1168
  count: inv.mcpServers.length,
1031
1169
  names: list(inv.mcpServers)
1032
1170
  })
1033
1171
  );
1034
1172
  }
1035
1173
  if (inv.ignoredBuckets.length > 0) {
1036
- lines.push(t7("plugin.inv_ignored", { buckets: inv.ignoredBuckets.join(" / ") }));
1174
+ lines.push(t8("plugin.inv_ignored", { buckets: inv.ignoredBuckets.join(" / ") }));
1037
1175
  }
1038
1176
  if (inv.jsTools) {
1039
- lines.push(t7("plugin.inv_js_tools"));
1177
+ lines.push(t8("plugin.inv_js_tools"));
1040
1178
  }
1041
1179
  for (const detail of issueDetails(inv.issues)) lines.push(`\u26A0 ${detail}`);
1042
1180
  return lines;
1043
1181
  }
1044
1182
  function list(names) {
1045
1183
  const shown = names.slice(0, 8).join(", ");
1046
- return names.length > 8 ? t7("plugin.list_more", { shown, n: names.length - 8 }) : shown;
1184
+ return names.length > 8 ? t8("plugin.list_more", { shown, n: names.length - 8 }) : shown;
1047
1185
  }
1048
1186
  function printMarketplaces() {
1049
1187
  const state = readMarketplaces(marketplacesPath(EPOCH_HOME));
1050
- for (const detail of issueDetails(state.issues)) log5(`\u26A0 ${detail}`);
1188
+ for (const detail of issueDetails(state.issues)) log6(`\u26A0 ${detail}`);
1051
1189
  if (state.records.length === 0) {
1052
- log5(t7("plugin.no_markets"));
1053
- log5(t7("plugin.no_markets_hint"));
1190
+ log6(t8("plugin.no_markets"));
1191
+ log6(t8("plugin.no_markets_hint"));
1054
1192
  return;
1055
1193
  }
1056
- log5(`${t7("plugin.markets_head", { path: marketplacesPath(EPOCH_HOME) })}
1194
+ log6(`${t8("plugin.markets_head", { path: marketplacesPath(EPOCH_HOME) })}
1057
1195
  `);
1058
1196
  for (const record of state.records) {
1059
1197
  const owner = record.catalog.owner ? ` by ${record.catalog.owner.name}` : "";
1060
- log5(
1061
- ` ${record.name} ${t7("plugin.market_plugin_count", {
1198
+ log6(
1199
+ ` ${record.name} ${t8("plugin.market_plugin_count", {
1062
1200
  count: record.catalog.plugins.length
1063
1201
  })} \u2190 ${record.source}${owner}`
1064
1202
  );
1065
- if (record.catalog.description) log5(` ${record.catalog.description}`);
1203
+ if (record.catalog.description) log6(` ${record.catalog.description}`);
1066
1204
  }
1067
1205
  }
1068
1206
  function printSearch(keyword) {
1069
1207
  const statePath = marketplacesPath(EPOCH_HOME);
1070
1208
  if (readMarketplaces(statePath).records.length === 0) {
1071
- log5(t7("plugin.search_no_markets"));
1209
+ log6(t8("plugin.search_no_markets"));
1072
1210
  return;
1073
1211
  }
1074
1212
  const hits = searchMarketplaces(keyword, statePath);
1075
1213
  if (hits.length === 0) {
1076
- log5(keyword ? t7("plugin.search_no_hit", { keyword }) : t7("plugin.search_all_empty"));
1214
+ log6(keyword ? t8("plugin.search_no_hit", { keyword }) : t8("plugin.search_all_empty"));
1077
1215
  return;
1078
1216
  }
1079
- log5(`${t7("plugin.search_count", { n: hits.length })}
1217
+ log6(`${t8("plugin.search_count", { n: hits.length })}
1080
1218
  `);
1081
1219
  for (const hit of hits) {
1082
1220
  const category = hit.entry.category ? ` [${hit.entry.category}]` : "";
1083
- log5(` ${hit.ref}${category}`);
1084
- if (hit.entry.description) log5(` ${hit.entry.description}`);
1221
+ log6(` ${hit.ref}${category}`);
1222
+ if (hit.entry.description) log6(` ${hit.entry.description}`);
1085
1223
  }
1086
- log5(`
1087
- ${t7("plugin.search_install_hint", { ref: hits[0]?.ref ?? t7("plugin.ref_placeholder") })}`);
1224
+ log6(`
1225
+ ${t8("plugin.search_install_hint", { ref: hits[0]?.ref ?? t8("plugin.ref_placeholder") })}`);
1088
1226
  }
1089
1227
  async function toggle(name, enabled) {
1090
1228
  const outcome = await setPluginEnabled(name, enabled, {
1091
1229
  statePath: pluginsStatePath(EPOCH_HOME)
1092
1230
  });
1093
1231
  if (!outcome.ok) throw new CliError(outcome.reason);
1094
- log5(`\u2713 ${outcome.message}`);
1232
+ log6(`\u2713 ${outcome.message}`);
1095
1233
  }
1096
1234
  function validateDir(dir) {
1097
1235
  const read = readPluginManifest(dir);
1098
1236
  if (!read.manifest) {
1099
1237
  const detail = issueDetails(read.issues).map((d) => ` - ${d}`).join("\n");
1100
- throw new CliError(`${t7("plugin.validate_bad", { dir })}
1238
+ throw new CliError(`${t8("plugin.validate_bad", { dir })}
1101
1239
  ${detail}`);
1102
1240
  }
1103
1241
  const manifest = read.manifest;
1104
- log5(`\u2713 ${t7("plugin.validate_ok", { name: manifest.name, version: manifest.version })}`);
1105
- if (manifest.epochVersion) log5(` epochVersion: ${manifest.epochVersion}`);
1106
- for (const detail of issueDetails(read.issues)) log5(`\u26A0 ${detail}`);
1107
- log5(`
1108
- ${t7("plugin.brings_head")}`);
1242
+ log6(`\u2713 ${t8("plugin.validate_ok", { name: manifest.name, version: manifest.version })}`);
1243
+ if (manifest.epochVersion) log6(` epochVersion: ${manifest.epochVersion}`);
1244
+ for (const detail of issueDetails(read.issues)) log6(`\u26A0 ${detail}`);
1245
+ log6(`
1246
+ ${t8("plugin.brings_head")}`);
1109
1247
  const inventory = scanPluginDir(dir, manifest.name);
1110
- for (const line of renderInventory(inventory)) log5(` ${line}`);
1248
+ for (const line of renderInventory(inventory)) log6(` ${line}`);
1111
1249
  if (inventory.issues.length > 0) {
1112
- throw new CliError(t7("plugin.inv_issues", { count: inventory.issues.length }));
1250
+ throw new CliError(t8("plugin.inv_issues", { count: inventory.issues.length }));
1113
1251
  }
1114
1252
  }
1115
1253
  // src/commands/run.ts
@@ -1117,7 +1255,7 @@ import { existsSync as existsSync6 } from "fs";
1117
1255
  import { dirname as dirname3, join as join5 } from "path";
1118
1256
  import { fileURLToPath as fileURLToPath3 } from "url";
1119
1257
  import { isNonInteractive as isNonInteractive8, OPERATION_TYPES as OPERATION_TYPES3, PERMISSION_LEVELS as PERMISSION_LEVELS3 } from "@epoch-agent/core";
1120
- import { t as t24 } from "@epoch-agent/infra";
1258
+ import { t as t25 } from "@epoch-agent/infra";
1121
1259
  import {
1122
1260
  HEADLESS_INPUT_FORMATS as HEADLESS_INPUT_FORMATS2,
1123
1261
  HEADLESS_OUTPUT_FORMATS as HEADLESS_OUTPUT_FORMATS2,
@@ -1125,13 +1263,13 @@ import {
1125
1263
  } from "@epoch-agent/protocol";
1126
1264
  // src/headless/session.ts
1127
1265
  import { OPERATION_TYPES } from "@epoch-agent/core";
1128
- import { t as t11 } from "@epoch-agent/infra";
1266
+ import { t as t12 } from "@epoch-agent/infra";
1129
1267
  import { buildRuntime } from "@epoch-agent/runtime";
1130
1268
  // src/commands/run-flags.ts
1131
1269
  import { existsSync as existsSync3 } from "fs";
1132
1270
  import { delimiter, resolve } from "path";
1133
1271
  import { isOperationType, resolveWorkspace } from "@epoch-agent/core";
1134
- import { t as t8 } from "@epoch-agent/infra";
1272
+ import { t as t9 } from "@epoch-agent/infra";
1135
1273
  import {
1136
1274
  HEADLESS_INPUT_FORMATS,
1137
1275
  HEADLESS_OUTPUT_FORMATS,
@@ -1151,14 +1289,14 @@ function parseResumeArg(raw) {
1151
1289
  }
1152
1290
  function assertResumeFlagsExclusive(opts) {
1153
1291
  if (opts.continue === true && opts.resume !== void 0) {
1154
- throw new CliError(t8("flags.resume_conflict"), 1, t8("flags.resume_conflict_hint"));
1292
+ throw new CliError(t9("flags.resume_conflict"), 1, t9("flags.resume_conflict_hint"));
1155
1293
  }
1156
1294
  }
1157
1295
  function applySettingsPath(path) {
1158
1296
  if (!path) return;
1159
1297
  const abs = resolve(path);
1160
1298
  if (!existsSync3(abs)) {
1161
- throw new CliError(t8("flags.settings_missing", { path }), 1, t8("flags.resolved_to", { abs }));
1299
+ throw new CliError(t9("flags.settings_missing", { path }), 1, t9("flags.resolved_to", { abs }));
1162
1300
  }
1163
1301
  process.env.EPOCH_SETTINGS = abs;
1164
1302
  }
@@ -1169,9 +1307,9 @@ function applyAddDirs(dirs) {
1169
1307
  const fatal = issues.filter((i) => i.kind !== "redundant");
1170
1308
  if (fatal.length > 0) {
1171
1309
  throw new CliError(
1172
- t8("flags.add_dir_unusable", { inputs: fatal.map((i) => i.input).join(", ") }),
1310
+ t9("flags.add_dir_unusable", { inputs: fatal.map((i) => i.input).join(", ") }),
1173
1311
  1,
1174
- fatal.map((i) => i.detail).join(t8("flags.detail_sep"))
1312
+ fatal.map((i) => i.detail).join(t9("flags.detail_sep"))
1175
1313
  );
1176
1314
  }
1177
1315
  process.env.EPOCH_ADD_DIR = abs.join(delimiter);
@@ -1203,17 +1341,17 @@ function resolveOutputFormat(opts) {
1203
1341
  const explicit = opts.outputFormat;
1204
1342
  if (explicit !== void 0 && !isHeadlessOutputFormat(explicit)) {
1205
1343
  throw new CliError(
1206
- t8("flags.output_format_unknown", { value: explicit }),
1344
+ t9("flags.output_format_unknown", { value: explicit }),
1207
1345
  1,
1208
- t8("flags.choices", { choices: HEADLESS_OUTPUT_FORMATS.join(" / ") })
1346
+ t9("flags.choices", { choices: HEADLESS_OUTPUT_FORMATS.join(" / ") })
1209
1347
  );
1210
1348
  }
1211
1349
  if (explicit === void 0) return opts.json === true ? "json" : "text";
1212
1350
  if (opts.json === true && explicit !== "json") {
1213
1351
  throw new CliError(
1214
- t8("flags.json_conflict", { value: explicit }),
1352
+ t9("flags.json_conflict", { value: explicit }),
1215
1353
  1,
1216
- t8("flags.json_conflict_hint")
1354
+ t9("flags.json_conflict_hint")
1217
1355
  );
1218
1356
  }
1219
1357
  return explicit;
@@ -1222,9 +1360,9 @@ function resolveHeadlessFormats(opts) {
1222
1360
  const raw = opts.inputFormat;
1223
1361
  if (raw !== void 0 && !isHeadlessInputFormat(raw)) {
1224
1362
  throw new CliError(
1225
- t8("flags.input_format_unknown", { value: raw }),
1363
+ t9("flags.input_format_unknown", { value: raw }),
1226
1364
  1,
1227
- t8("flags.choices", { choices: HEADLESS_INPUT_FORMATS.join(" / ") })
1365
+ t9("flags.choices", { choices: HEADLESS_INPUT_FORMATS.join(" / ") })
1228
1366
  );
1229
1367
  }
1230
1368
  const input2 = raw ?? "text";
@@ -1234,7 +1372,7 @@ function resolveHeadlessFormats(opts) {
1234
1372
  }
1235
1373
  const output = resolveOutputFormat(opts);
1236
1374
  if (output !== "stream-json") {
1237
- throw new CliError(t8("flags.stream_pair", { output }), 1, t8("flags.stream_pair_hint"));
1375
+ throw new CliError(t9("flags.stream_pair", { output }), 1, t9("flags.stream_pair_hint"));
1238
1376
  }
1239
1377
  return { input: input2, output };
1240
1378
  }
@@ -1245,9 +1383,9 @@ function resolveApproverProgram(raw) {
1245
1383
  const abs = resolve(value);
1246
1384
  if (!existsSync3(abs)) {
1247
1385
  throw new CliError(
1248
- t8("flags.prompt_tool_missing", { value }),
1386
+ t9("flags.prompt_tool_missing", { value }),
1249
1387
  1,
1250
- t8("flags.prompt_tool_missing_hint", { abs })
1388
+ t9("flags.prompt_tool_missing_hint", { abs })
1251
1389
  );
1252
1390
  }
1253
1391
  return `"${abs}"`;
@@ -1265,15 +1403,15 @@ function parsePositive(raw, flag, extra = () => true) {
1265
1403
  const n = Number(raw);
1266
1404
  if (!Number.isFinite(n) || n <= 0 || !extra(n)) {
1267
1405
  throw new CliError(
1268
- t8("flags.not_a_number", { flag, raw }),
1406
+ t9("flags.not_a_number", { flag, raw }),
1269
1407
  1,
1270
- flag === "--max-turns" ? t8("flags.want_positive_int") : t8("flags.want_positive")
1408
+ flag === "--max-turns" ? t9("flags.want_positive_int") : t9("flags.want_positive")
1271
1409
  );
1272
1410
  }
1273
1411
  return n;
1274
1412
  }
1275
1413
  // src/headless/driver.ts
1276
- import { t as t10 } from "@epoch-agent/infra";
1414
+ import { t as t11 } from "@epoch-agent/infra";
1277
1415
  // src/headless/emit.ts
1278
1416
  import {
1279
1417
  HEADLESS_PROTOCOL_VERSION
@@ -1390,14 +1528,14 @@ function initInfoOf(runtime, cwd) {
1390
1528
  model: runtime.config.model,
1391
1529
  ...provider ? { provider } : {},
1392
1530
  permissionLevel: runtime.permissions.level(),
1393
- tools: runtime.tools.map((t39) => t39.name),
1531
+ tools: runtime.tools.map((t40) => t40.name),
1394
1532
  usageScope: runtime.usageScope,
1395
1533
  diagnostics: runtime.diagnostics
1396
1534
  };
1397
1535
  }
1398
1536
  // src/headless/read.ts
1399
1537
  import { createInterface } from "readline";
1400
- import { t as t9 } from "@epoch-agent/infra";
1538
+ import { t as t10 } from "@epoch-agent/infra";
1401
1539
  import {
1402
1540
  APPROVAL_OUTCOMES,
1403
1541
  HEADLESS_INPUT_EVENT_TYPES,
@@ -1413,17 +1551,17 @@ function parseInputLine(line) {
1413
1551
  } catch (err2) {
1414
1552
  return {
1415
1553
  ok: false,
1416
- message: t9("headless_input.bad_json", { why: describe2(err2), preview: preview(text) })
1554
+ message: t10("headless_input.bad_json", { why: describe2(err2), preview: preview(text) })
1417
1555
  };
1418
1556
  }
1419
1557
  if (!isRecord(raw)) {
1420
- return { ok: false, message: t9("headless_input.not_object", { preview: preview(text) }) };
1558
+ return { ok: false, message: t10("headless_input.not_object", { preview: preview(text) }) };
1421
1559
  }
1422
1560
  const type = raw["type"];
1423
1561
  if (typeof type !== "string" || !HEADLESS_INPUT_EVENT_TYPES.has(type)) {
1424
1562
  return {
1425
1563
  ok: false,
1426
- message: t9("headless_input.bad_type", {
1564
+ message: t10("headless_input.bad_type", {
1427
1565
  value: JSON.stringify(type),
1428
1566
  choices: [...HEADLESS_INPUT_EVENT_TYPES].join(" / ")
1429
1567
  })
@@ -1437,15 +1575,15 @@ function parseInputLine(line) {
1437
1575
  function parseUserMessage(raw) {
1438
1576
  const content = raw["content"];
1439
1577
  if (typeof content === "string") {
1440
- if (!content.trim()) return { ok: false, message: t9("headless_input.msg_empty") };
1578
+ if (!content.trim()) return { ok: false, message: t10("headless_input.msg_empty") };
1441
1579
  return { ok: true, event: { type: "user-message", content } };
1442
1580
  }
1443
1581
  if (!Array.isArray(content) || content.length === 0) {
1444
- return { ok: false, message: t9("headless_input.msg_bad_content") };
1582
+ return { ok: false, message: t10("headless_input.msg_bad_content") };
1445
1583
  }
1446
1584
  const bad = content.findIndex((p) => !isRecord(p) || typeof p["type"] !== "string");
1447
1585
  if (bad >= 0) {
1448
- return { ok: false, message: t9("headless_input.msg_bad_part", { index: bad }) };
1586
+ return { ok: false, message: t10("headless_input.msg_bad_part", { index: bad }) };
1449
1587
  }
1450
1588
  return {
1451
1589
  ok: true,
@@ -1455,13 +1593,13 @@ function parseUserMessage(raw) {
1455
1593
  function parseApprovalResponse(raw) {
1456
1594
  const requestId = raw["requestId"];
1457
1595
  if (typeof requestId !== "string" || !requestId) {
1458
- return { ok: false, message: t9("headless_input.approval_no_id") };
1596
+ return { ok: false, message: t10("headless_input.approval_no_id") };
1459
1597
  }
1460
1598
  const outcome = raw["outcome"];
1461
1599
  if (typeof outcome !== "string" || !isApprovalOutcome(outcome)) {
1462
1600
  return {
1463
1601
  ok: false,
1464
- message: t9("headless_input.approval_bad_outcome", {
1602
+ message: t10("headless_input.approval_bad_outcome", {
1465
1603
  value: JSON.stringify(outcome),
1466
1604
  choices: APPROVAL_OUTCOMES.join(" / ")
1467
1605
  })
@@ -1469,7 +1607,7 @@ function parseApprovalResponse(raw) {
1469
1607
  }
1470
1608
  const note = raw["note"];
1471
1609
  if (note !== void 0 && typeof note !== "string") {
1472
- return { ok: false, message: t9("headless_input.approval_bad_note") };
1610
+ return { ok: false, message: t10("headless_input.approval_bad_note") };
1473
1611
  }
1474
1612
  return {
1475
1613
  ok: true,
@@ -1484,19 +1622,19 @@ function parseApprovalResponse(raw) {
1484
1622
  function parseQuestionResponse(raw) {
1485
1623
  const requestId = raw["requestId"];
1486
1624
  if (typeof requestId !== "string" || !requestId) {
1487
- return { ok: false, message: t9("headless_input.question_no_id") };
1625
+ return { ok: false, message: t10("headless_input.question_no_id") };
1488
1626
  }
1489
1627
  if (!isQuestionAnswerMap(raw["answers"])) {
1490
1628
  return {
1491
1629
  ok: false,
1492
- message: t9("headless_input.question_bad_answers", {
1630
+ message: t10("headless_input.question_bad_answers", {
1493
1631
  json: '{"answers":{},"skipped":true}'
1494
1632
  })
1495
1633
  };
1496
1634
  }
1497
1635
  const skipped = raw["skipped"];
1498
1636
  if (skipped !== void 0 && typeof skipped !== "boolean") {
1499
- return { ok: false, message: t9("headless_input.question_bad_skipped") };
1637
+ return { ok: false, message: t10("headless_input.question_bad_skipped") };
1500
1638
  }
1501
1639
  return {
1502
1640
  ok: true,
@@ -1539,7 +1677,7 @@ async function driveStreamJson(opts) {
1539
1677
  const parsed = parseInputLine(line);
1540
1678
  if (parsed === void 0) continue;
1541
1679
  if (!parsed.ok) {
1542
- warn4(t10("headless_driver.bad_input", { message: parsed.message }));
1680
+ warn4(t11("headless_driver.bad_input", { message: parsed.message }));
1543
1681
  state.sawBadInput = true;
1544
1682
  continue;
1545
1683
  }
@@ -1574,7 +1712,7 @@ var DriverState = class {
1574
1712
  }
1575
1713
  if (event.type === "approval-response") {
1576
1714
  if (!this.emitter.respondApproval(event.requestId, event.outcome, event.note)) {
1577
- this.warn(t10("headless_driver.unknown_request", { id: event.requestId }));
1715
+ this.warn(t11("headless_driver.unknown_request", { id: event.requestId }));
1578
1716
  }
1579
1717
  return false;
1580
1718
  }
@@ -1584,7 +1722,7 @@ var DriverState = class {
1584
1722
  ...event.skipped ? { skipped: true } : {}
1585
1723
  };
1586
1724
  if (!this.emitter.respondQuestion(event.requestId, answer)) {
1587
- this.warn(t10("headless_driver.unknown_request", { id: event.requestId }));
1725
+ this.warn(t11("headless_driver.unknown_request", { id: event.requestId }));
1588
1726
  }
1589
1727
  return false;
1590
1728
  }
@@ -1646,11 +1784,11 @@ var DriverState = class {
1646
1784
  reapLostHost() {
1647
1785
  const approvals = this.emitter.abandonApprovals();
1648
1786
  if (approvals > 0) {
1649
- this.warn(t10("headless_driver.abandoned_approvals", { count: approvals }));
1787
+ this.warn(t11("headless_driver.abandoned_approvals", { count: approvals }));
1650
1788
  }
1651
1789
  const questions = this.emitter.abandonQuestions();
1652
1790
  if (questions > 0) {
1653
- this.warn(t10("headless_driver.abandoned_questions", { count: questions }));
1791
+ this.warn(t11("headless_driver.abandoned_questions", { count: questions }));
1654
1792
  }
1655
1793
  this.queue.length = 0;
1656
1794
  this.controller?.abort();
@@ -1675,9 +1813,9 @@ async function runStreamJsonSession(opts) {
1675
1813
  const { policy: headless, invalid } = parseHeadlessFlags(opts);
1676
1814
  if (invalid.length > 0) {
1677
1815
  throw new CliError(
1678
- t11("run_once.err_bad_operation", { values: invalid.join(", ") }),
1816
+ t12("run_once.err_bad_operation", { values: invalid.join(", ") }),
1679
1817
  EXIT_CODES.FAILURE,
1680
- t11("run_once.err_bad_operation_hint", { choices: OPERATION_TYPES.join(" / ") })
1818
+ t12("run_once.err_bad_operation_hint", { choices: OPERATION_TYPES.join(" / ") })
1681
1819
  );
1682
1820
  }
1683
1821
  const limits = parseCallLimits(opts);
@@ -1706,21 +1844,21 @@ function reportDeadRuntime(runtime) {
1706
1844
  const detail = runtime.diagnostics.join("; ");
1707
1845
  emitter.agentEvent({
1708
1846
  type: "error",
1709
- message: detail ? t11("headless_session.no_provider_detail", {
1710
- message: t11("run_once.err_no_provider"),
1847
+ message: detail ? t12("headless_session.no_provider_detail", {
1848
+ message: t12("run_once.err_no_provider"),
1711
1849
  detail
1712
- }) : t11("run_once.err_no_provider")
1850
+ }) : t12("run_once.err_no_provider")
1713
1851
  });
1714
1852
  emitter.result({ ok: false, reason: "error", text: "", turns: 0 });
1715
1853
  return EXIT_CODES.FAILURE;
1716
1854
  }
1717
1855
  function warnInertFlags(opts) {
1718
1856
  if ((opts.allowTool ?? []).length > 0 || (opts.allowOperation ?? []).length > 0) {
1719
- process.stderr.write(`${t11("headless_session.inert_allow")}
1857
+ process.stderr.write(`${t12("headless_session.inert_allow")}
1720
1858
  `);
1721
1859
  }
1722
1860
  if ((opts.image ?? []).length > 0) {
1723
- process.stderr.write(`${t11("headless_session.inert_image")}
1861
+ process.stderr.write(`${t12("headless_session.inert_image")}
1724
1862
  `);
1725
1863
  }
1726
1864
  }
@@ -1730,17 +1868,17 @@ import { existsSync as existsSync5, mkdirSync as mkdirSync2, readFileSync as rea
1730
1868
  import { get } from "https";
1731
1869
  import { dirname as dirname2, join as join3 } from "path";
1732
1870
  import { fileURLToPath as fileURLToPath2 } from "url";
1733
- import { t as t14 } from "@epoch-agent/infra";
1871
+ import { t as t15 } from "@epoch-agent/infra";
1734
1872
  // src/version.ts
1735
1873
  import { readFileSync as readFileSync2 } from "fs";
1736
1874
  import { dirname, join as join2 } from "path";
1737
1875
  import { fileURLToPath } from "url";
1738
- import { t as t13 } from "@epoch-agent/infra";
1876
+ import { t as t14 } from "@epoch-agent/infra";
1739
1877
  // src/installation.ts
1740
1878
  import { execFileSync } from "child_process";
1741
1879
  import { existsSync as existsSync4, realpathSync } from "fs";
1742
1880
  import { join } from "path";
1743
- import { normalizeForMatch, t as t12 } from "@epoch-agent/infra";
1881
+ import { normalizeForMatch, t as t13 } from "@epoch-agent/infra";
1744
1882
  var PATH_RULES = [
1745
1883
  {
1746
1884
  patterns: [
@@ -1754,7 +1892,7 @@ var PATH_RULES = [
1754
1892
  build: () => ({
1755
1893
  packageManager: "npx",
1756
1894
  isGlobal: false,
1757
- note: t12("installation.npx")
1895
+ note: t13("installation.npx")
1758
1896
  })
1759
1897
  },
1760
1898
  {
@@ -1763,7 +1901,7 @@ var PATH_RULES = [
1763
1901
  packageManager: "volta",
1764
1902
  isGlobal: true,
1765
1903
  updateCommand: `volta install ${pkg}@latest`,
1766
- note: t12("installation.volta")
1904
+ note: t13("installation.volta")
1767
1905
  })
1768
1906
  },
1769
1907
  {
@@ -1777,7 +1915,7 @@ var PATH_RULES = [
1777
1915
  packageManager: "pnpm",
1778
1916
  isGlobal: true,
1779
1917
  updateCommand: `pnpm add -g ${pkg}@latest`,
1780
- note: t12("installation.pnpm")
1918
+ note: t13("installation.pnpm")
1781
1919
  })
1782
1920
  },
1783
1921
  {
@@ -1791,7 +1929,7 @@ var PATH_RULES = [
1791
1929
  packageManager: "yarn",
1792
1930
  isGlobal: true,
1793
1931
  updateCommand: `yarn global add ${pkg}@latest`,
1794
- note: t12("installation.yarn")
1932
+ note: t13("installation.yarn")
1795
1933
  })
1796
1934
  },
1797
1935
  {
@@ -1800,7 +1938,7 @@ var PATH_RULES = [
1800
1938
  packageManager: "bun",
1801
1939
  isGlobal: true,
1802
1940
  updateCommand: `bun add -g ${pkg}@latest`,
1803
- note: t12("installation.bun")
1941
+ note: t13("installation.bun")
1804
1942
  })
1805
1943
  }
1806
1944
  ];
@@ -1820,7 +1958,7 @@ function detectHomebrew(realPath, formula) {
1820
1958
  packageManager: "homebrew",
1821
1959
  isGlobal: true,
1822
1960
  updateCommand: `brew upgrade ${formula}`,
1823
- note: t12("installation.homebrew")
1961
+ note: t13("installation.homebrew")
1824
1962
  };
1825
1963
  }
1826
1964
  } catch {
@@ -1845,12 +1983,12 @@ function detectLocalInstall(matchPath, cwd) {
1845
1983
  return {
1846
1984
  packageManager: manager,
1847
1985
  isGlobal: false,
1848
- note: t12("installation.local")
1986
+ note: t13("installation.local")
1849
1987
  };
1850
1988
  }
1851
1989
  function getInstallationInfo(packageName, cliPath = process.argv[1]) {
1852
1990
  if (!cliPath) {
1853
- return { packageManager: "unknown", isGlobal: false, note: t12("installation.unknown") };
1991
+ return { packageManager: "unknown", isGlobal: false, note: t13("installation.unknown") };
1854
1992
  }
1855
1993
  try {
1856
1994
  const realPath = realpathSync(cliPath).replace(/\\/g, "/");
@@ -1863,7 +2001,7 @@ function getInstallationInfo(packageName, cliPath = process.argv[1]) {
1863
2001
  return {
1864
2002
  packageManager: "source",
1865
2003
  isGlobal: false,
1866
- note: t12("installation.source")
2004
+ note: t13("installation.source")
1867
2005
  };
1868
2006
  }
1869
2007
  const brew = detectHomebrew(realPath, packageName.replace(/^@[^/]+\//, ""));
@@ -1874,10 +2012,10 @@ function getInstallationInfo(packageName, cliPath = process.argv[1]) {
1874
2012
  packageManager: "npm",
1875
2013
  isGlobal: true,
1876
2014
  updateCommand: `npm install -g ${packageName}@latest`,
1877
- note: t12("installation.npm")
2015
+ note: t13("installation.npm")
1878
2016
  };
1879
2017
  } catch {
1880
- return { packageManager: "unknown", isGlobal: false, note: t12("installation.unknown") };
2018
+ return { packageManager: "unknown", isGlobal: false, note: t13("installation.unknown") };
1881
2019
  }
1882
2020
  }
1883
2021
  // src/version.ts
@@ -1901,9 +2039,9 @@ function describeVersion(packageName) {
1901
2039
  return [
1902
2040
  VERSION,
1903
2041
  `Node: ${process.version} (${process.platform}/${process.arch})`,
1904
- t13("version.install", {
2042
+ t14("version.install", {
1905
2043
  manager: info.packageManager,
1906
- global: info.isGlobal ? t13("installation.global_suffix") : "",
2044
+ global: info.isGlobal ? t14("installation.global_suffix") : "",
1907
2045
  note: info.note
1908
2046
  })
1909
2047
  ].join("\n");
@@ -2047,7 +2185,7 @@ function readUpdateNotice(options = {}) {
2047
2185
  name,
2048
2186
  current: version,
2049
2187
  latest: cache.latest,
2050
- message: t14("update_check.available", { name, current: version, latest: cache.latest })
2188
+ message: t15("update_check.available", { name, current: version, latest: cache.latest })
2051
2189
  };
2052
2190
  }
2053
2191
  async function refreshUpdateCache(options = {}) {
@@ -2076,7 +2214,7 @@ async function refreshUpdateCache(options = {}) {
2076
2214
  name,
2077
2215
  current: version,
2078
2216
  latest,
2079
- message: t14("update_check.available", { name, current: version, latest })
2217
+ message: t15("update_check.available", { name, current: version, latest })
2080
2218
  };
2081
2219
  }
2082
2220
  function scheduleUpdateCheck(options = {}) {
@@ -2114,7 +2252,7 @@ import { execFile } from "child_process";
2114
2252
  import { randomBytes } from "crypto";
2115
2253
  import { mkdirSync as mkdirSync3 } from "fs";
2116
2254
  import { basename, join as join4, resolve as resolve2 } from "path";
2117
- import { t as t15, worktreesDir } from "@epoch-agent/infra";
2255
+ import { t as t16, worktreesDir } from "@epoch-agent/infra";
2118
2256
  var TIMEOUT_MS = 6e4;
2119
2257
  function git(args, cwd) {
2120
2258
  return new Promise((done) => {
@@ -2135,13 +2273,13 @@ function git(args, cwd) {
2135
2273
  });
2136
2274
  }
2137
2275
  function firstLine(text) {
2138
- return text.trim().split("\n")[0]?.trim() ?? t15("git.unknown_reason");
2276
+ return text.trim().split("\n")[0]?.trim() ?? t16("git.unknown_reason");
2139
2277
  }
2140
2278
  async function createWorktree(cwd = process.cwd(), container = worktreesDir()) {
2141
2279
  const repoRoot = await resolveRepoRoot(cwd);
2142
2280
  const head = await git(["rev-parse", "HEAD"], repoRoot);
2143
2281
  if (!head.ok) {
2144
- throw new CliError(t15("worktree.err_no_commit"), 1, t15("worktree.err_no_commit_hint"));
2282
+ throw new CliError(t16("worktree.err_no_commit"), 1, t16("worktree.err_no_commit_hint"));
2145
2283
  }
2146
2284
  const baseRef = head.stdout.trim();
2147
2285
  const shortId = randomBytes(3).toString("hex");
@@ -2150,20 +2288,20 @@ async function createWorktree(cwd = process.cwd(), container = worktreesDir()) {
2150
2288
  mkdirSync3(container, { recursive: true });
2151
2289
  const added = await git(["worktree", "add", "-b", branch, path, baseRef], repoRoot);
2152
2290
  if (!added.ok) {
2153
- throw new CliError(t15("worktree.err_add_failed", { path }), 1, firstLine(added.stderr));
2291
+ throw new CliError(t16("worktree.err_add_failed", { path }), 1, firstLine(added.stderr));
2154
2292
  }
2155
2293
  return { repoRoot, path, branch, baseRef };
2156
2294
  }
2157
2295
  async function resolveRepoRoot(cwd) {
2158
2296
  const root = await git(["rev-parse", "--show-toplevel"], cwd);
2159
2297
  if (root.missing) {
2160
- throw new CliError(t15("worktree.err_git_missing"), 1, t15("worktree.err_git_missing_hint"));
2298
+ throw new CliError(t16("worktree.err_git_missing"), 1, t16("worktree.err_git_missing_hint"));
2161
2299
  }
2162
2300
  if (!root.ok) {
2163
2301
  throw new CliError(
2164
- t15("worktree.err_not_a_repo"),
2302
+ t16("worktree.err_not_a_repo"),
2165
2303
  1,
2166
- t15("worktree.err_not_a_repo_hint", { cwd, why: firstLine(root.stderr) })
2304
+ t16("worktree.err_not_a_repo_hint", { cwd, why: firstLine(root.stderr) })
2167
2305
  );
2168
2306
  }
2169
2307
  return resolve2(root.stdout.trim());
@@ -2181,16 +2319,16 @@ async function inspectWorktree(session) {
2181
2319
  };
2182
2320
  }
2183
2321
  function worktreeKeepReason(state) {
2184
- if (state.dirty === null || state.ahead === null) return t15("worktree.keep_unknown");
2185
- if (state.dirty > 0) return t15("worktree.keep_dirty", { count: state.dirty });
2186
- if (state.ahead > 0) return t15("worktree.keep_ahead", { count: state.ahead });
2322
+ if (state.dirty === null || state.ahead === null) return t16("worktree.keep_unknown");
2323
+ if (state.dirty > 0) return t16("worktree.keep_dirty", { count: state.dirty });
2324
+ if (state.ahead > 0) return t16("worktree.keep_ahead", { count: state.ahead });
2187
2325
  return null;
2188
2326
  }
2189
2327
  function worktreeBanner(session) {
2190
- const dir = t15("worktree.banner_dir", { path: session.path });
2191
- const branch = t15("worktree.banner_branch", { branch: session.branch });
2328
+ const dir = t16("worktree.banner_dir", { path: session.path });
2329
+ const branch = t16("worktree.banner_branch", { branch: session.branch });
2192
2330
  return `
2193
- ${t15("worktree.banner")}
2331
+ ${t16("worktree.banner")}
2194
2332
  ${dir}
2195
2333
  ${branch}
2196
2334
  `;
@@ -2202,23 +2340,23 @@ async function finishWorktree(session, opts) {
2202
2340
  if (forced !== null) {
2203
2341
  print(
2204
2342
  `
2205
- ${t15("worktree.kept_forced", { reason: forced })}
2343
+ ${t16("worktree.kept_forced", { reason: forced })}
2206
2344
  ${session.path}
2207
- ${t15("worktree.banner_branch", { branch: session.branch })}`
2345
+ ${t16("worktree.banner_branch", { branch: session.branch })}`
2208
2346
  );
2209
2347
  return;
2210
2348
  }
2211
2349
  const remove = opts.interactive ? await (opts.ask ?? askRemove)(session) : false;
2212
2350
  if (!remove) {
2213
2351
  print(`
2214
- ${t15("worktree.kept", { path: session.path, branch: session.branch })}`);
2352
+ ${t16("worktree.kept", { path: session.path, branch: session.branch })}`);
2215
2353
  return;
2216
2354
  }
2217
2355
  const failure = await removeWorktree(session);
2218
2356
  print(
2219
2357
  failure === null ? `
2220
- ${t15("worktree.removed", { path: session.path, branch: session.branch })}` : `
2221
- ${t15("worktree.remove_failed", { path: session.path })}
2358
+ ${t16("worktree.removed", { path: session.path, branch: session.branch })}` : `
2359
+ ${t16("worktree.remove_failed", { path: session.path })}
2222
2360
  ${failure}`
2223
2361
  );
2224
2362
  }
@@ -2226,7 +2364,7 @@ async function removeWorktree(session) {
2226
2364
  const removed = await git(["worktree", "remove", session.path], session.repoRoot);
2227
2365
  if (!removed.ok) return firstLine(removed.stderr);
2228
2366
  const branch = await git(["branch", "-D", session.branch], session.repoRoot);
2229
- return branch.ok ? null : t15("worktree.branch_remove_failed", {
2367
+ return branch.ok ? null : t16("worktree.branch_remove_failed", {
2230
2368
  branch: session.branch,
2231
2369
  why: firstLine(branch.stderr)
2232
2370
  });
@@ -2235,7 +2373,7 @@ async function askRemove(session) {
2235
2373
  const { confirm } = await import("@inquirer/prompts");
2236
2374
  try {
2237
2375
  return await confirm({
2238
- message: t15("worktree.ask_remove", { path: session.path }),
2376
+ message: t16("worktree.ask_remove", { path: session.path }),
2239
2377
  default: false
2240
2378
  });
2241
2379
  } catch {
@@ -2244,7 +2382,7 @@ async function askRemove(session) {
2244
2382
  }
2245
2383
  // src/commands/run-once.ts
2246
2384
  import { formatUsd, imageFromPath, OPERATION_TYPES as OPERATION_TYPES2 } from "@epoch-agent/core";
2247
- import { t as t21 } from "@epoch-agent/infra";
2385
+ import { t as t22 } from "@epoch-agent/infra";
2248
2386
  import {
2249
2387
  promptTokens
2250
2388
  } from "@epoch-agent/protocol";
@@ -2253,38 +2391,38 @@ import { buildRuntime as buildRuntime2, listBackgroundTasks } from "@epoch-agent
2253
2391
  import {
2254
2392
  isNonInteractive as isNonInteractive3
2255
2393
  } from "@epoch-agent/core";
2256
- import { t as t16 } from "@epoch-agent/infra";
2394
+ import { t as t17 } from "@epoch-agent/infra";
2257
2395
  function typeLabel(type) {
2258
2396
  switch (type) {
2259
2397
  case "file_read":
2260
- return t16("tui.approval.type_file_read");
2398
+ return t17("tui.approval.type_file_read");
2261
2399
  case "file_write":
2262
- return t16("tui.approval.type_file_write");
2400
+ return t17("tui.approval.type_file_write");
2263
2401
  case "command":
2264
- return t16("tui.approval.type_command");
2402
+ return t17("tui.approval.type_command");
2265
2403
  case "network":
2266
- return t16("tui.approval.type_network");
2404
+ return t17("tui.approval.type_network");
2267
2405
  case "code_exec":
2268
- return t16("tui.approval.type_code_exec");
2406
+ return t17("tui.approval.type_code_exec");
2269
2407
  }
2270
2408
  }
2271
2409
  function formatApprovalRequest(req) {
2272
2410
  if (req.plan) {
2273
2411
  return [
2274
- t16("approval.plan_head"),
2275
- t16("approval.plan_previous_level", { level: req.plan.previousLevel }),
2412
+ t17("approval.plan_head"),
2413
+ t17("approval.plan_previous_level", { level: req.plan.previousLevel }),
2276
2414
  "",
2277
2415
  ...req.plan.markdown.split("\n").map((l) => ` ${l}`)
2278
2416
  ];
2279
2417
  }
2280
2418
  const lines = [
2281
- t16("approval.asks", { tool: req.toolName, what: typeLabel(req.type) }),
2282
- t16("approval.target", { target: req.target || t16("approval.target_none") })
2419
+ t17("approval.asks", { tool: req.toolName, what: typeLabel(req.type) }),
2420
+ t17("approval.target", { target: req.target || t17("approval.target_none") })
2283
2421
  ];
2284
2422
  if (req.detail && req.detail !== req.target) {
2285
- lines.push(t16("approval.detail", { detail: req.detail.slice(0, 300) }));
2423
+ lines.push(t17("approval.detail", { detail: req.detail.slice(0, 300) }));
2286
2424
  }
2287
- if (req.reason) lines.push(t16("approval.reason", { reason: req.reason }));
2425
+ if (req.reason) lines.push(t17("approval.reason", { reason: req.reason }));
2288
2426
  return lines;
2289
2427
  }
2290
2428
  function createInteractiveApproval(opts = {}) {
@@ -2292,15 +2430,15 @@ function createInteractiveApproval(opts = {}) {
2292
2430
  return async (req) => {
2293
2431
  if (!interactive()) {
2294
2432
  if (opts.permission?.()?.isPreauthorized(req.toolName, req.type)) {
2295
- console.error(t16("approval.headless_allowed", { tool: req.toolName, target: req.target }));
2433
+ console.error(t17("approval.headless_allowed", { tool: req.toolName, target: req.target }));
2296
2434
  return "allow-once";
2297
2435
  }
2298
2436
  console.error(
2299
- `${t16("approval.headless_denied", {
2437
+ `${t17("approval.headless_denied", {
2300
2438
  tool: req.toolName,
2301
2439
  target: req.target
2302
2440
  })}
2303
- ${t16("approval.headless_denied_hint", { tool: req.toolName })}`
2441
+ ${t17("approval.headless_denied_hint", { tool: req.toolName })}`
2304
2442
  );
2305
2443
  return "deny";
2306
2444
  }
@@ -2309,12 +2447,12 @@ ${t16("approval.headless_denied_hint", { tool: req.toolName })}`
2309
2447
  const { select: select2 } = await import("@inquirer/prompts");
2310
2448
  try {
2311
2449
  return await select2({
2312
- message: t16("approval.ask"),
2450
+ message: t17("approval.ask"),
2313
2451
  choices: [
2314
- { name: t16("tui.approval.allow_once"), value: "allow-once" },
2315
- { name: t16("tui.approval.allow_session"), value: "allow-session" },
2316
- { name: t16("approval.allow_always_cli"), value: "allow-always" },
2317
- { name: t16("tui.approval.deny"), value: "deny" }
2452
+ { name: t17("tui.approval.allow_once"), value: "allow-once" },
2453
+ { name: t17("tui.approval.allow_session"), value: "allow-session" },
2454
+ { name: t17("approval.allow_always_cli"), value: "allow-always" },
2455
+ { name: t17("tui.approval.deny"), value: "deny" }
2318
2456
  ],
2319
2457
  default: "allow-once"
2320
2458
  });
@@ -2328,21 +2466,21 @@ async function askPlan(proposal) {
2328
2466
  const choices3 = [
2329
2467
  ...proposal.canExecute ? [
2330
2468
  {
2331
- name: t16("approval.plan_execute_back", {
2332
- label: t16("approval.plan_execute"),
2469
+ name: t17("approval.plan_execute_back", {
2470
+ label: t17("approval.plan_execute"),
2333
2471
  level: proposal.previousLevel
2334
2472
  }),
2335
2473
  value: "plan-execute"
2336
2474
  }
2337
2475
  ] : [],
2338
- { name: t16("approval.plan_readonly"), value: "plan-readonly" },
2339
- { name: t16("approval.plan_revise"), value: "plan-revise" },
2340
- { name: t16("approval.deny"), value: "deny" }
2476
+ { name: t17("approval.plan_readonly"), value: "plan-readonly" },
2477
+ { name: t17("approval.plan_revise"), value: "plan-revise" },
2478
+ { name: t17("approval.deny"), value: "deny" }
2341
2479
  ];
2342
2480
  try {
2343
- const outcome = await select2({ message: t16("approval.plan_ask"), choices: choices3 });
2481
+ const outcome = await select2({ message: t17("approval.plan_ask"), choices: choices3 });
2344
2482
  if (outcome !== "plan-revise") return outcome;
2345
- const note = (await input2({ message: t16("approval.plan_revise_ask") })).trim();
2483
+ const note = (await input2({ message: t17("approval.plan_revise_ask") })).trim();
2346
2484
  return note ? { outcome, note } : outcome;
2347
2485
  } catch {
2348
2486
  return "deny";
@@ -2355,7 +2493,7 @@ import {
2355
2493
  matchPreauthorization,
2356
2494
  mergeHeadlessPolicy
2357
2495
  } from "@epoch-agent/core";
2358
- import { t as t17 } from "@epoch-agent/infra";
2496
+ import { t as t18 } from "@epoch-agent/infra";
2359
2497
  import { APPROVAL_OUTCOMES as APPROVAL_OUTCOMES2, isApprovalOutcome as isApprovalOutcome2 } from "@epoch-agent/protocol";
2360
2498
  var APPROVER_TIMEOUT_MS = 6e4;
2361
2499
  var MAX_STDOUT_BYTES = 64 * 1024;
@@ -2365,22 +2503,22 @@ function clip(s) {
2365
2503
  }
2366
2504
  function parseApproverVerdict(stdout) {
2367
2505
  const text = stdout.trim();
2368
- if (!text) return { ok: false, why: t17("approver.no_output") };
2506
+ if (!text) return { ok: false, why: t18("approver.no_output") };
2369
2507
  let raw;
2370
2508
  try {
2371
2509
  raw = JSON.parse(text);
2372
2510
  } catch {
2373
- return { ok: false, why: t17("approver.not_json", { text: clip(text) }) };
2511
+ return { ok: false, why: t18("approver.not_json", { text: clip(text) }) };
2374
2512
  }
2375
2513
  if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
2376
- return { ok: false, why: t17("approver.not_object", { text: clip(text) }) };
2514
+ return { ok: false, why: t18("approver.not_object", { text: clip(text) }) };
2377
2515
  }
2378
2516
  const rec = raw;
2379
2517
  const outcome = rec["outcome"];
2380
2518
  if (typeof outcome !== "string" || !isApprovalOutcome2(outcome)) {
2381
2519
  return {
2382
2520
  ok: false,
2383
- why: t17("approver.bad_outcome", {
2521
+ why: t18("approver.bad_outcome", {
2384
2522
  value: clip(String(outcome)),
2385
2523
  choices: APPROVAL_OUTCOMES2.join(" / ")
2386
2524
  })
@@ -2416,7 +2554,7 @@ function askExternalApprover(program2, payload, opts = {}) {
2416
2554
  });
2417
2555
  const timer = setTimeout(() => {
2418
2556
  child.kill("SIGKILL");
2419
- settle({ ok: false, why: t17("approver.timeout", { ms: timeoutMs }) });
2557
+ settle({ ok: false, why: t18("approver.timeout", { ms: timeoutMs }) });
2420
2558
  }, timeoutMs);
2421
2559
  const done = (v) => {
2422
2560
  clearTimeout(timer);
@@ -2426,15 +2564,15 @@ function askExternalApprover(program2, payload, opts = {}) {
2426
2564
  out2 += d.toString("utf-8");
2427
2565
  if (out2.length > MAX_STDOUT_BYTES) {
2428
2566
  child.kill("SIGKILL");
2429
- done({ ok: false, why: t17("approver.too_much_output", { bytes: MAX_STDOUT_BYTES }) });
2567
+ done({ ok: false, why: t18("approver.too_much_output", { bytes: MAX_STDOUT_BYTES }) });
2430
2568
  }
2431
2569
  });
2432
2570
  child.on("error", (err2) => {
2433
- done({ ok: false, why: t17("approver.spawn_failed", { message: err2.message }) });
2571
+ done({ ok: false, why: t18("approver.spawn_failed", { message: err2.message }) });
2434
2572
  });
2435
2573
  child.on("close", (code) => {
2436
2574
  if (code !== 0) {
2437
- done({ ok: false, why: t17("approver.bad_exit", { code: code ?? -1 }) });
2575
+ done({ ok: false, why: t18("approver.bad_exit", { code: code ?? -1 }) });
2438
2576
  return;
2439
2577
  }
2440
2578
  done(parseApproverVerdict(out2));
@@ -2468,7 +2606,7 @@ function createExternalApproval(opts) {
2468
2606
  const hit = req.plan ? null : opts.preauth?.(req) ?? null;
2469
2607
  if (hit) {
2470
2608
  write(
2471
- `${t17("approver.audit_preauth", {
2609
+ `${t18("approver.audit_preauth", {
2472
2610
  tool: req.toolName,
2473
2611
  target: req.target,
2474
2612
  reason: hit
@@ -2480,7 +2618,7 @@ function createExternalApproval(opts) {
2480
2618
  const verdict = await ask(payloadOf(req, cwd, opts.sessionId?.()));
2481
2619
  if (!verdict.ok) {
2482
2620
  write(
2483
- `${t17("approver.audit_rejected", {
2621
+ `${t18("approver.audit_rejected", {
2484
2622
  tool: req.toolName,
2485
2623
  target: req.target,
2486
2624
  why: verdict.why
@@ -2492,7 +2630,7 @@ function createExternalApproval(opts) {
2492
2630
  const { outcome } = verdict.answer;
2493
2631
  const vars = { tool: req.toolName, target: req.target, outcome };
2494
2632
  write(
2495
- `${outcome === "deny" ? t17("approver.audit_denied", vars) : t17("approver.audit_allowed", vars)}
2633
+ `${outcome === "deny" ? t18("approver.audit_denied", vars) : t18("approver.audit_allowed", vars)}
2496
2634
  `
2497
2635
  );
2498
2636
  return verdict.answer;
@@ -2500,35 +2638,35 @@ function createExternalApproval(opts) {
2500
2638
  }
2501
2639
  // src/headless/tasks.ts
2502
2640
  import { describeBackgroundTask } from "@epoch-agent/core";
2503
- import { t as t18 } from "@epoch-agent/infra";
2641
+ import { t as t19 } from "@epoch-agent/infra";
2504
2642
  function backgroundTaskSummary(all) {
2505
- const tasks = all.filter((t39) => t39.kind === "command");
2643
+ const tasks = all.filter((t40) => t40.kind === "command");
2506
2644
  if (tasks.length === 0) return "";
2507
- const running = tasks.filter((t39) => t39.status === "running").length;
2508
- const head = running > 0 ? t18("background_tasks.head_running", { total: tasks.length, running }) : t18("background_tasks.head_done", { total: tasks.length });
2509
- return [head, ...tasks.map((t39) => ` ${describeBackgroundTask(t39)}`)].join("\n");
2645
+ const running = tasks.filter((t40) => t40.status === "running").length;
2646
+ const head = running > 0 ? t19("background_tasks.head_running", { total: tasks.length, running }) : t19("background_tasks.head_done", { total: tasks.length });
2647
+ return [head, ...tasks.map((t40) => ` ${describeBackgroundTask(t40)}`)].join("\n");
2510
2648
  }
2511
2649
  // src/import-prompt.ts
2512
2650
  import {
2513
2651
  createImportGate,
2514
2652
  ImportTrustStore,
2515
2653
  isNonInteractive as isNonInteractive6,
2516
- loadConfig as loadConfig2,
2654
+ loadConfig as loadConfig3,
2517
2655
  resolveProjectRoot as resolveProjectRoot2,
2518
2656
  scanInstructions,
2519
2657
  setImportGate,
2520
2658
  TrustManager as TrustManager2
2521
2659
  } from "@epoch-agent/core";
2522
- import { t as t20, trustedImportsPath, trustPath as trustPath2 } from "@epoch-agent/infra";
2660
+ import { t as t21, trustedImportsPath, trustPath as trustPath2 } from "@epoch-agent/infra";
2523
2661
  // src/trust-prompt.ts
2524
2662
  import {
2525
2663
  findProjectInstructions,
2526
2664
  isNonInteractive as isNonInteractive5,
2527
- loadConfig,
2665
+ loadConfig as loadConfig2,
2528
2666
  resolveProjectRoot,
2529
2667
  TrustManager
2530
2668
  } from "@epoch-agent/core";
2531
- import { t as t19, trustPath } from "@epoch-agent/infra";
2669
+ import { t as t20, trustPath } from "@epoch-agent/infra";
2532
2670
  function trustPromptTarget(deps) {
2533
2671
  if (!deps.gateEnabled) return null;
2534
2672
  if (!deps.interactive) return null;
@@ -2541,29 +2679,29 @@ function trustPromptTarget(deps) {
2541
2679
  function applyTrustChoice(store, root, choice) {
2542
2680
  if (choice.kind === "trust") {
2543
2681
  store.record(root, "trusted", choice.scope);
2544
- const suffix = choice.scope === "directory-tree" ? t19("trust_prompt.granted_tree_suffix") : "";
2545
- return t19("trust_prompt.granted", { root, suffix });
2682
+ const suffix = choice.scope === "directory-tree" ? t20("trust_prompt.granted_tree_suffix") : "";
2683
+ return t20("trust_prompt.granted", { root, suffix });
2546
2684
  }
2547
2685
  if (choice.kind === "never") {
2548
2686
  store.record(root, "untrusted", "directory");
2549
- return t19("trust_prompt.denied", { root });
2687
+ return t20("trust_prompt.denied", { root });
2550
2688
  }
2551
- return t19("trust_prompt.skipped");
2689
+ return t20("trust_prompt.skipped");
2552
2690
  }
2553
2691
  function trustPromptMessage(target) {
2554
2692
  return [
2555
2693
  `
2556
- ${t19("trust_prompt.head", { path: target.instructionsPath })}`,
2557
- ` ${t19("trust_prompt.why")}`,
2694
+ ${t20("trust_prompt.head", { path: target.instructionsPath })}`,
2695
+ ` ${t20("trust_prompt.why")}`,
2558
2696
  ""
2559
2697
  ].join("\n");
2560
2698
  }
2561
2699
  function choices() {
2562
2700
  return [
2563
- { name: t19("trust_prompt.choice_skip"), value: { kind: "skip" } },
2564
- { name: t19("trust_prompt.choice_dir"), value: { kind: "trust", scope: "directory" } },
2565
- { name: t19("trust_prompt.choice_tree"), value: { kind: "trust", scope: "directory-tree" } },
2566
- { name: t19("trust_prompt.choice_never"), value: { kind: "never" } }
2701
+ { name: t20("trust_prompt.choice_skip"), value: { kind: "skip" } },
2702
+ { name: t20("trust_prompt.choice_dir"), value: { kind: "trust", scope: "directory" } },
2703
+ { name: t20("trust_prompt.choice_tree"), value: { kind: "trust", scope: "directory-tree" } },
2704
+ { name: t20("trust_prompt.choice_never"), value: { kind: "never" } }
2567
2705
  ];
2568
2706
  }
2569
2707
  function restoreStdinDefault() {
@@ -2572,7 +2710,7 @@ function restoreStdinDefault() {
2572
2710
  stdin.resume();
2573
2711
  }
2574
2712
  async function maybePromptForTrust(opts = {}) {
2575
- const config = opts.config ?? loadConfig();
2713
+ const config = opts.config ?? loadConfig2();
2576
2714
  const store = opts.store ?? new TrustManager(trustPath(config.homeDir));
2577
2715
  const print = opts.print ?? ((msg) => process.stdout.write(msg + "\n"));
2578
2716
  const target = trustPromptTarget({
@@ -2594,7 +2732,7 @@ async function maybePromptForTrust(opts = {}) {
2594
2732
  print(applyTrustChoice(store, target.root, choice));
2595
2733
  } catch (err2) {
2596
2734
  print(
2597
- t19("trust_prompt.write_failed", {
2735
+ t20("trust_prompt.write_failed", {
2598
2736
  message: err2 instanceof Error ? err2.message : String(err2)
2599
2737
  })
2600
2738
  );
@@ -2606,7 +2744,7 @@ async function askTrustChoice(_target) {
2606
2744
  try {
2607
2745
  const options = choices();
2608
2746
  return await select2({
2609
- message: t19("trust_prompt.ask"),
2747
+ message: t20("trust_prompt.ask"),
2610
2748
  choices: [...options],
2611
2749
  default: options[0]?.value
2612
2750
  });
@@ -2639,38 +2777,38 @@ function externalImportTargets(deps) {
2639
2777
  function importPromptMessage(target) {
2640
2778
  return [
2641
2779
  `
2642
- ${t20("import_prompt.head", { from: target.from })}`,
2780
+ ${t21("import_prompt.head", { from: target.from })}`,
2643
2781
  ` ${target.path}`,
2644
- ` ${t20("import_prompt.spec", { spec: target.spec })}`,
2645
- ` ${t20("import_prompt.why")}`,
2782
+ ` ${t21("import_prompt.spec", { spec: target.spec })}`,
2783
+ ` ${t21("import_prompt.why")}`,
2646
2784
  ""
2647
2785
  ].join("\n");
2648
2786
  }
2649
2787
  function applyImportChoice(store, target, choice) {
2650
2788
  if (choice.kind === "once") {
2651
2789
  store.allowOnce(target.path);
2652
- return t20("import_prompt.once", { path: target.path });
2790
+ return t21("import_prompt.once", { path: target.path });
2653
2791
  }
2654
2792
  if (choice.kind === "remember") {
2655
2793
  store.remember(target.path);
2656
- return t20("import_prompt.remembered", { path: target.path });
2794
+ return t21("import_prompt.remembered", { path: target.path });
2657
2795
  }
2658
2796
  if (choice.kind === "never") {
2659
2797
  store.denyAll();
2660
- return t20("import_prompt.never");
2798
+ return t21("import_prompt.never");
2661
2799
  }
2662
- return t20("import_prompt.skipped", { path: target.path });
2800
+ return t21("import_prompt.skipped", { path: target.path });
2663
2801
  }
2664
2802
  function choices2() {
2665
2803
  return [
2666
- { name: t20("import_prompt.choice_skip"), value: { kind: "skip" } },
2667
- { name: t20("import_prompt.choice_once"), value: { kind: "once" } },
2668
- { name: t20("import_prompt.choice_remember"), value: { kind: "remember" } },
2669
- { name: t20("import_prompt.choice_never"), value: { kind: "never" } }
2804
+ { name: t21("import_prompt.choice_skip"), value: { kind: "skip" } },
2805
+ { name: t21("import_prompt.choice_once"), value: { kind: "once" } },
2806
+ { name: t21("import_prompt.choice_remember"), value: { kind: "remember" } },
2807
+ { name: t21("import_prompt.choice_never"), value: { kind: "never" } }
2670
2808
  ];
2671
2809
  }
2672
2810
  async function maybePromptForExternalImports(opts = {}) {
2673
- const config = opts.config ?? loadConfig2();
2811
+ const config = opts.config ?? loadConfig3();
2674
2812
  const store = opts.store ?? new ImportTrustStore(trustedImportsPath(config.homeDir));
2675
2813
  const print = opts.print ?? ((msg) => process.stdout.write(msg + "\n"));
2676
2814
  const targets = externalImportTargets({
@@ -2693,7 +2831,7 @@ async function maybePromptForExternalImports(opts = {}) {
2693
2831
  print(applyImportChoice(store, target, choice));
2694
2832
  } catch (err2) {
2695
2833
  print(
2696
- t20("import_prompt.write_failed", {
2834
+ t21("import_prompt.write_failed", {
2697
2835
  message: err2 instanceof Error ? err2.message : String(err2)
2698
2836
  })
2699
2837
  );
@@ -2711,7 +2849,7 @@ async function askImportChoice(_target) {
2711
2849
  try {
2712
2850
  const options = choices2();
2713
2851
  return await select2({
2714
- message: t20("import_prompt.ask"),
2852
+ message: t21("import_prompt.ask"),
2715
2853
  choices: [...options],
2716
2854
  default: options[0]?.value
2717
2855
  });
@@ -2762,7 +2900,7 @@ function createStreamWriter(enabled, sink) {
2762
2900
  };
2763
2901
  }
2764
2902
  // src/commands/run-once.ts
2765
- async function readStdin() {
2903
+ async function readStdin2() {
2766
2904
  if (process.stdin.isTTY) return "";
2767
2905
  const chunks = [];
2768
2906
  for await (const chunk of process.stdin) chunks.push(Buffer.from(chunk));
@@ -2788,7 +2926,7 @@ function composeContent(query, images) {
2788
2926
  throw new CliError(
2789
2927
  err2 instanceof Error ? err2.message : String(err2),
2790
2928
  EXIT_CODES.FAILURE,
2791
- t21("run_once.err_image")
2929
+ t22("run_once.err_image")
2792
2930
  );
2793
2931
  }
2794
2932
  }
@@ -2797,9 +2935,9 @@ async function runOnce(query, opts, resumeId) {
2797
2935
  const { policy: headless, invalid } = parseHeadlessFlags(opts);
2798
2936
  if (invalid.length > 0) {
2799
2937
  throw new CliError(
2800
- t21("run_once.err_bad_operation", { values: invalid.join(", ") }),
2938
+ t22("run_once.err_bad_operation", { values: invalid.join(", ") }),
2801
2939
  EXIT_CODES.FAILURE,
2802
- t21("run_once.err_bad_operation_hint", { choices: OPERATION_TYPES2.join(" / ") })
2940
+ t22("run_once.err_bad_operation_hint", { choices: OPERATION_TYPES2.join(" / ") })
2803
2941
  );
2804
2942
  }
2805
2943
  const format = resolveOutputFormat(opts);
@@ -2829,10 +2967,10 @@ async function runOnce(query, opts, resumeId) {
2829
2967
  const detail = runtime.diagnostics.join("\n ");
2830
2968
  await runtime.dispose();
2831
2969
  throw new CliError(
2832
- t21("run_once.err_no_provider"),
2970
+ t22("run_once.err_no_provider"),
2833
2971
  EXIT_CODES.FAILURE,
2834
- detail ? `${t21("run_once.err_no_provider_diag")}
2835
- ${detail}` : t21("run_once.err_no_provider_hint")
2972
+ detail ? `${t22("run_once.err_no_provider_diag")}
2973
+ ${detail}` : t22("run_once.err_no_provider_hint")
2836
2974
  );
2837
2975
  }
2838
2976
  try {
@@ -2840,7 +2978,7 @@ async function runOnce(query, opts, resumeId) {
2840
2978
  if (resumeId) {
2841
2979
  const restored = runtime.session.getHistory().length;
2842
2980
  process.stderr.write(
2843
- `${t21("run_once.resumed", {
2981
+ `${t22("run_once.resumed", {
2844
2982
  id: resumeId.slice(0, SHORT_ID_LEN),
2845
2983
  count: restored
2846
2984
  })}
@@ -2903,7 +3041,7 @@ function collect2(out2, ev, w) {
2903
3041
  } else if (ev.type === "usage") {
2904
3042
  out2.usage = ev.cumulative;
2905
3043
  } else if (ev.type === "error") {
2906
- out2.text = t21("run_once.error_prefix", { message: ev.message });
3044
+ out2.text = t22("run_once.error_prefix", { message: ev.message });
2907
3045
  process.exitCode = EXIT_CODES.FAILURE;
2908
3046
  } else if (ev.type === "finish") {
2909
3047
  out2.finishReason = ev.reason;
@@ -2938,14 +3076,14 @@ function emitOutcome(out2, opts, format, emitter, tasks = []) {
2938
3076
  return;
2939
3077
  }
2940
3078
  if (out2.reasoning) {
2941
- process.stderr.write(`${t21("run_once.reasoning_head")}
3079
+ process.stderr.write(`${t22("run_once.reasoning_head")}
2942
3080
  ${out2.reasoning}
2943
3081
 
2944
3082
  `);
2945
3083
  }
2946
3084
  if (opts.stream === false && out2.text) process.stdout.write(out2.text + "\n");
2947
3085
  if (out2.aborted) process.stderr.write(`
2948
- ${t21("run_once.aborted")}
3086
+ ${t22("run_once.aborted")}
2949
3087
  `);
2950
3088
  if (taskLines) process.stderr.write(taskLines + "\n");
2951
3089
  const summary = formatSummary(out2.usage, out2.budgetExceeded);
@@ -2962,10 +3100,10 @@ function noteworthy(diagnostics, verbose) {
2962
3100
  }
2963
3101
  function formatSummary(usage, budgetExceeded) {
2964
3102
  if (!usage) return "";
2965
- const cached = usage.cacheHitTokens ? t21("run_once.cache_hit", { count: usage.cacheHitTokens }) : "";
3103
+ const cached = usage.cacheHitTokens ? t22("run_once.cache_hit", { count: usage.cacheHitTokens }) : "";
2966
3104
  const tokens = `${promptTokens(usage)} in${cached} / ${usage.outputTokens} out`;
2967
- const cost = usage.costUsd === void 0 ? t21("run_once.cost_unknown") : formatUsd(usage.costUsd);
2968
- const stopped = budgetExceeded ? t21("run_once.budget_reached") : "";
3105
+ const cost = usage.costUsd === void 0 ? t22("run_once.cost_unknown") : formatUsd(usage.costUsd);
3106
+ const stopped = budgetExceeded ? t22("run_once.budget_reached") : "";
2969
3107
  return `\u2500 ${tokens} \xB7 ${cost}${stopped}`;
2970
3108
  }
2971
3109
  function reportHeadlessAudit(permission) {
@@ -2974,7 +3112,7 @@ function reportHeadlessAudit(permission) {
2974
3112
  for (const e of audit) {
2975
3113
  const vars = { tool: e.toolName, target: e.target, reason: e.reason };
2976
3114
  process.stderr.write(
2977
- `${e.outcome === "granted" ? t21("run_once.audit_granted", vars) : t21("run_once.audit_denied", vars)}
3115
+ `${e.outcome === "granted" ? t22("run_once.audit_granted", vars) : t22("run_once.audit_denied", vars)}
2978
3116
  `
2979
3117
  );
2980
3118
  }
@@ -2984,7 +3122,7 @@ function reportHeadlessAudit(permission) {
2984
3122
  }
2985
3123
  // src/commands/run-overrides.ts
2986
3124
  import { isPermissionLevel as isPermissionLevel2, PERMISSION_LEVELS as PERMISSION_LEVELS2 } from "@epoch-agent/core";
2987
- import { t as t22 } from "@epoch-agent/infra";
3125
+ import { t as t23 } from "@epoch-agent/infra";
2988
3126
  import { isProviderType as isProviderType2, PROVIDER_TYPES as PROVIDER_TYPES3 } from "@epoch-agent/protocol";
2989
3127
  function applyRunFlags(opts) {
2990
3128
  applySettingsPath(opts.settings);
@@ -3003,9 +3141,9 @@ function applyOverrides(opts) {
3003
3141
  if (opts.provider) {
3004
3142
  if (!isProviderType2(opts.provider)) {
3005
3143
  throw new CliError(
3006
- t22("flags.provider_unknown", { value: opts.provider }),
3144
+ t23("flags.provider_unknown", { value: opts.provider }),
3007
3145
  1,
3008
- t22("flags.choices", { choices: PROVIDER_TYPES3.join(", ") })
3146
+ t23("flags.choices", { choices: PROVIDER_TYPES3.join(", ") })
3009
3147
  );
3010
3148
  }
3011
3149
  process.env.EPOCH_PROVIDER = opts.provider;
@@ -3013,9 +3151,9 @@ function applyOverrides(opts) {
3013
3151
  if (opts.permission) {
3014
3152
  if (!isPermissionLevel2(opts.permission)) {
3015
3153
  throw new CliError(
3016
- t22("flags.permission_unknown", { value: opts.permission }),
3154
+ t23("flags.permission_unknown", { value: opts.permission }),
3017
3155
  1,
3018
- t22("flags.choices", { choices: PERMISSION_LEVELS2.join(", ") })
3156
+ t23("flags.choices", { choices: PERMISSION_LEVELS2.join(", ") })
3019
3157
  );
3020
3158
  }
3021
3159
  process.env.EPOCH_PERMISSION = opts.permission;
@@ -3026,9 +3164,9 @@ function assertModelName(value, flag) {
3026
3164
  const spec = value.trim();
3027
3165
  if (MODEL_ID.test(spec)) return value;
3028
3166
  throw new CliError(
3029
- t22("flags.model_not_a_name", { flag, value }),
3167
+ t23("flags.model_not_a_name", { flag, value }),
3030
3168
  1,
3031
- t22("flags.model_not_a_name_hint", { value: spec })
3169
+ t23("flags.model_not_a_name_hint", { value: spec })
3032
3170
  );
3033
3171
  }
3034
3172
  function assertHttpUrl(value) {
@@ -3038,60 +3176,60 @@ function assertHttpUrl(value) {
3038
3176
  } catch {
3039
3177
  }
3040
3178
  throw new CliError(
3041
- t22("flags.base_url_invalid", { value }),
3179
+ t23("flags.base_url_invalid", { value }),
3042
3180
  1,
3043
- t22("flags.base_url_invalid_hint", { value: value.trim() })
3181
+ t23("flags.base_url_invalid_hint", { value: value.trim() })
3044
3182
  );
3045
3183
  }
3046
3184
  // src/commands/sessions.ts
3047
3185
  import { isNonInteractive as isNonInteractive7, resolveProjectRoot as resolveProjectRoot3, SessionManager } from "@epoch-agent/core";
3048
- import { dbPath, t as t23, uiDateLocale as uiDateLocale2 } from "@epoch-agent/infra";
3049
- var log6 = (msg) => process.stdout.write(msg + "\n");
3186
+ import { dbPath, t as t24, uiDateLocale as uiDateLocale2 } from "@epoch-agent/infra";
3187
+ var log7 = (msg) => process.stdout.write(msg + "\n");
3050
3188
  var SHORT_ID_LEN2 = 8;
3051
3189
  var PICK_LIMIT = 20;
3052
3190
  function whenOf(startedAt) {
3053
- return startedAt ? new Date(startedAt).toLocaleString(uiDateLocale2()) : t23("sessions.when_unknown");
3191
+ return startedAt ? new Date(startedAt).toLocaleString(uiDateLocale2()) : t24("sessions.when_unknown");
3054
3192
  }
3055
3193
  function titleOf(s) {
3056
- return s.title || s.preview || t23("sessions.untitled");
3194
+ return s.title || s.preview || t24("sessions.untitled");
3057
3195
  }
3058
3196
  function registerSessionsCommand(program2) {
3059
- const cmd = program2.command("sessions").alias("session").description(t23("sessions.cmd_root"));
3060
- cmd.command("list").description(t23("sessions.cmd_list")).option("-n, --limit <n>", t23("sessions.opt_limit"), "10").action((opts) => {
3197
+ const cmd = program2.command("sessions").alias("session").description(t24("sessions.cmd_root"));
3198
+ cmd.command("list").description(t24("sessions.cmd_list")).option("-n, --limit <n>", t24("sessions.opt_limit"), "10").action((opts) => {
3061
3199
  withSessions((sm) => {
3062
3200
  const r = sm.list({ limit: parseInt(opts.limit, 10) });
3063
3201
  if (r.sessions.length === 0) {
3064
- log6(` ${t23("sessions.list_empty")}`);
3202
+ log7(` ${t24("sessions.list_empty")}`);
3065
3203
  return;
3066
3204
  }
3067
3205
  for (const s of r.sessions) {
3068
- log6(` ${s.id.slice(0, SHORT_ID_LEN2)} ${whenOf(s.startedAt)} ${titleOf(s)}`);
3206
+ log7(` ${s.id.slice(0, SHORT_ID_LEN2)} ${whenOf(s.startedAt)} ${titleOf(s)}`);
3069
3207
  }
3070
3208
  });
3071
3209
  });
3072
- cmd.command("resume").description(t23("sessions.cmd_resume")).argument("[id]", t23("sessions.arg_id")).argument("[query]", t23("sessions.arg_query")).action(async (id, query) => {
3210
+ cmd.command("resume").description(t24("sessions.cmd_resume")).argument("[id]", t24("sessions.arg_id")).argument("[query]", t24("sessions.arg_query")).action(async (id, query) => {
3073
3211
  const resolved = resolveSessionId(id);
3074
3212
  if (!resolved.ok) {
3075
3213
  throw new CliError(resolved.error, EXIT_CODES.FAILURE);
3076
3214
  }
3077
- await runOnce(query || t23("sessions.default_query"), {}, resolved.id);
3215
+ await runOnce(query || t24("sessions.default_query"), {}, resolved.id);
3078
3216
  });
3079
3217
  }
3080
3218
  function resolveSessionId(input2) {
3081
3219
  return withSessions((sm) => {
3082
3220
  if (!input2) {
3083
3221
  const latest = sm.getLatest()?.meta.id;
3084
- return latest ? { ok: true, id: latest } : { ok: false, error: t23("sessions.err_none") };
3222
+ return latest ? { ok: true, id: latest } : { ok: false, error: t24("sessions.err_none") };
3085
3223
  }
3086
3224
  if (sm.get(input2)) return { ok: true, id: input2 };
3087
3225
  const candidates = sm.list({ limit: 200 }).sessions.filter((s) => s.id.startsWith(input2)).map((s) => s.id);
3088
3226
  if (candidates.length === 1) return { ok: true, id: candidates[0] };
3089
3227
  if (candidates.length === 0) {
3090
- return { ok: false, error: t23("sessions.err_not_found", { input: input2 }) };
3228
+ return { ok: false, error: t24("sessions.err_not_found", { input: input2 }) };
3091
3229
  }
3092
3230
  return {
3093
3231
  ok: false,
3094
- error: t23("sessions.err_ambiguous", { input: input2, count: candidates.length })
3232
+ error: t24("sessions.err_ambiguous", { input: input2, count: candidates.length })
3095
3233
  };
3096
3234
  });
3097
3235
  }
@@ -3102,9 +3240,9 @@ function latestSessionIdForProject(cwd = process.cwd()) {
3102
3240
  async function pickSessionId() {
3103
3241
  if (isNonInteractive7()) {
3104
3242
  throw new CliError(
3105
- t23("sessions.err_needs_id"),
3243
+ t24("sessions.err_needs_id"),
3106
3244
  EXIT_CODES.FAILURE,
3107
- t23("sessions.err_needs_id_hint")
3245
+ t24("sessions.err_needs_id_hint")
3108
3246
  );
3109
3247
  }
3110
3248
  const rows = withSessions(
@@ -3112,22 +3250,22 @@ async function pickSessionId() {
3112
3250
  id: s.id,
3113
3251
  title: titleOf(s),
3114
3252
  when: whenOf(s.startedAt),
3115
- where: s.cwd ?? t23("sessions.cwd_unrecorded"),
3253
+ where: s.cwd ?? t24("sessions.cwd_unrecorded"),
3116
3254
  messageCount: s.messageCount
3117
3255
  }))
3118
3256
  );
3119
3257
  if (rows.length === 0) {
3120
- log6(t23("sessions.pick_empty"));
3258
+ log7(t24("sessions.pick_empty"));
3121
3259
  return void 0;
3122
3260
  }
3123
3261
  const { select: select2 } = await import("@inquirer/prompts");
3124
3262
  try {
3125
3263
  return await select2({
3126
- message: t23("sessions.pick_prompt"),
3264
+ message: t24("sessions.pick_prompt"),
3127
3265
  choices: rows.map((r) => ({
3128
3266
  name: `${r.id.slice(0, SHORT_ID_LEN2)} ${r.when} ${r.title}`,
3129
3267
  value: r.id,
3130
- description: `${t23("tui.resume.message_count", { n: r.messageCount })} \xB7 ${r.where}`
3268
+ description: `${t24("tui.resume.message_count", { n: r.messageCount })} \xB7 ${r.where}`
3131
3269
  })),
3132
3270
  pageSize: 12
3133
3271
  });
@@ -3144,27 +3282,27 @@ function withSessions(fn) {
3144
3282
  }
3145
3283
  }
3146
3284
  // src/commands/run.ts
3147
- var log7 = (msg) => {
3285
+ var log8 = (msg) => {
3148
3286
  process.stdout.write(msg + "\n");
3149
3287
  };
3150
3288
  function registerRunCommand(program2) {
3151
- program2.argument("[query]", t24("run.arg_query")).option("--allow-tool <name>", t24("run.opt_allow_tool"), collect, []).option(
3289
+ program2.argument("[query]", t25("run.arg_query")).option("--allow-tool <name>", t25("run.opt_allow_tool"), collect, []).option(
3152
3290
  "--allow-operation <type>",
3153
- t24("run.opt_allow_operation", { types: OPERATION_TYPES3.join(" / ") }),
3291
+ t25("run.opt_allow_operation", { types: OPERATION_TYPES3.join(" / ") }),
3154
3292
  collect,
3155
3293
  []
3156
- ).option("-i, --image <path>", t24("run.opt_image"), collect, []).option("-c, --continue", t24("run.opt_continue")).option("-r, --resume [id]", t24("run.opt_resume")).option("-m, --model <name>", t24("run.opt_model")).option("--fallback-model <name>", t24("run.opt_fallback_model")).option("-p, --provider <type>", t24("run.opt_provider", { types: PROVIDER_TYPES4.join(" / ") })).option("--base-url <url>", t24("run.opt_base_url")).option(
3294
+ ).option("-i, --image <path>", t25("run.opt_image"), collect, []).option("-c, --continue", t25("run.opt_continue")).option("-r, --resume [id]", t25("run.opt_resume")).option("-m, --model <name>", t25("run.opt_model")).option("--fallback-model <name>", t25("run.opt_fallback_model")).option("-p, --provider <type>", t25("run.opt_provider", { types: PROVIDER_TYPES4.join(" / ") })).option("--base-url <url>", t25("run.opt_base_url")).option(
3157
3295
  "--permission <level>",
3158
- t24("run.opt_permission", { levels: PERMISSION_LEVELS3.join(" / ") })
3159
- ).option("--settings <file>", t24("run.opt_settings")).option("--add-dir <dir>", t24("run.opt_add_dir"), collect, []).option("--agent <role>", t24("run.opt_agent")).option("--worktree", t24("run.opt_worktree")).option("--json", t24("run.opt_json")).option(
3296
+ t25("run.opt_permission", { levels: PERMISSION_LEVELS3.join(" / ") })
3297
+ ).option("--settings <file>", t25("run.opt_settings")).option("--add-dir <dir>", t25("run.opt_add_dir"), collect, []).option("--agent <role>", t25("run.opt_agent")).option("--worktree", t25("run.opt_worktree")).option("--json", t25("run.opt_json")).option(
3160
3298
  "--output-format <fmt>",
3161
- t24("run.opt_output_format", { formats: HEADLESS_OUTPUT_FORMATS2.join(" / ") })
3299
+ t25("run.opt_output_format", { formats: HEADLESS_OUTPUT_FORMATS2.join(" / ") })
3162
3300
  ).option(
3163
3301
  "--input-format <fmt>",
3164
- t24("run.opt_input_format", { formats: HEADLESS_INPUT_FORMATS2.join(" / ") })
3165
- ).option("--permission-prompt-tool <program>", t24("run.opt_permission_prompt_tool")).option("--max-turns <n>", t24("run.opt_max_turns")).option("--max-budget-usd <x>", t24("run.opt_max_budget")).option("--no-stream", t24("run.opt_no_stream")).option("-v, --verbose", t24("run.opt_verbose")).option("-V, --version", t24("run.opt_version")).action(async (query, opts) => {
3302
+ t25("run.opt_input_format", { formats: HEADLESS_INPUT_FORMATS2.join(" / ") })
3303
+ ).option("--permission-prompt-tool <program>", t25("run.opt_permission_prompt_tool")).option("--max-turns <n>", t25("run.opt_max_turns")).option("--max-budget-usd <x>", t25("run.opt_max_budget")).option("--no-stream", t25("run.opt_no_stream")).option("-v, --verbose", t25("run.opt_verbose")).option("-V, --version", t25("run.opt_version")).action(async (query, opts) => {
3166
3304
  if (opts.version === true) {
3167
- log7(describeVersion(selfPackage().name));
3305
+ log8(describeVersion(selfPackage().name));
3168
3306
  return;
3169
3307
  }
3170
3308
  applyRunFlags(opts);
@@ -3174,39 +3312,39 @@ function registerRunCommand(program2) {
3174
3312
  if (formats.input === "stream-json") {
3175
3313
  if (opts.continue === true || resumeArg.kind !== "off") {
3176
3314
  throw new CliError(
3177
- t24("run.conflict_resume"),
3315
+ t25("run.conflict_resume"),
3178
3316
  EXIT_CODES.FAILURE,
3179
- t24("run.conflict_resume_hint")
3317
+ t25("run.conflict_resume_hint")
3180
3318
  );
3181
3319
  }
3182
3320
  if (opts.worktree === true) {
3183
3321
  throw new CliError(
3184
- t24("run.conflict_worktree"),
3322
+ t25("run.conflict_worktree"),
3185
3323
  EXIT_CODES.FAILURE,
3186
- t24("run.conflict_worktree_hint")
3324
+ t25("run.conflict_worktree_hint")
3187
3325
  );
3188
3326
  }
3189
3327
  if (opts.permissionPromptTool !== void 0) {
3190
3328
  throw new CliError(
3191
- t24("run.conflict_prompt_tool"),
3329
+ t25("run.conflict_prompt_tool"),
3192
3330
  EXIT_CODES.FAILURE,
3193
- t24("run.conflict_prompt_tool_hint")
3331
+ t25("run.conflict_prompt_tool_hint")
3194
3332
  );
3195
3333
  }
3196
3334
  if (!hasCredentials()) {
3197
3335
  throw new CliError(
3198
- t24("run.no_credentials_stream"),
3336
+ t25("run.no_credentials_stream"),
3199
3337
  EXIT_CODES.FAILURE,
3200
- t24("run.no_credentials_hint")
3338
+ t25("run.no_credentials_hint")
3201
3339
  );
3202
3340
  }
3203
3341
  process.exitCode = await runStreamJsonSession(opts);
3204
3342
  return;
3205
3343
  }
3206
3344
  const carried = resumeArg.kind === "pick" ? resumeArg.query : void 0;
3207
- const prompt = composePrompt(query ?? carried, await readStdin());
3345
+ const prompt = composePrompt(query ?? carried, await readStdin2());
3208
3346
  if (!hasCredentials()) {
3209
- log7(t24("run.welcome"));
3347
+ log8(t25("run.welcome"));
3210
3348
  return;
3211
3349
  }
3212
3350
  const resumeId = await resolveResumeTarget(opts, resumeArg);
@@ -3232,7 +3370,7 @@ async function resolveResumeTarget(opts, resumeArg) {
3232
3370
  if (opts.continue === true) {
3233
3371
  const latest = latestSessionIdForProject();
3234
3372
  if (!latest) {
3235
- process.stderr.write(`${t24("run.no_history")}
3373
+ process.stderr.write(`${t25("run.no_history")}
3236
3374
  `);
3237
3375
  }
3238
3376
  return latest;
@@ -3243,7 +3381,7 @@ async function resolveResumeTarget(opts, resumeArg) {
3243
3381
  throw new CliError(
3244
3382
  resolved.error,
3245
3383
  EXIT_CODES.FAILURE,
3246
- t24("run.resume_not_id_hint")
3384
+ t25("run.resume_not_id_hint")
3247
3385
  );
3248
3386
  }
3249
3387
  return resolved.id;
@@ -3262,7 +3400,7 @@ function resolveTuiEntry(baseDir, exists = existsSync6) {
3262
3400
  async function launchTui(resumeId) {
3263
3401
  const target = resolveTuiEntry(dirname3(fileURLToPath3(import.meta.url)));
3264
3402
  if (!target) {
3265
- process.stderr.write(`${t24("run.tui_entry_missing")}
3403
+ process.stderr.write(`${t25("run.tui_entry_missing")}
3266
3404
  `);
3267
3405
  process.exitCode = EXIT_CODES.FAILURE;
3268
3406
  return;
@@ -3277,7 +3415,7 @@ async function launchTui(resumeId) {
3277
3415
  });
3278
3416
  await new Promise((done) => {
3279
3417
  child.on("error", (err2) => {
3280
- process.stderr.write(`${t24("run.tui_spawn_failed", { message: err2.message })}
3418
+ process.stderr.write(`${t25("run.tui_spawn_failed", { message: err2.message })}
3281
3419
  `);
3282
3420
  process.exitCode = EXIT_CODES.FAILURE;
3283
3421
  done();
@@ -3289,13 +3427,13 @@ async function launchTui(resumeId) {
3289
3427
  });
3290
3428
  }
3291
3429
  // src/commands/schedule.ts
3292
- import { t as t32 } from "@epoch-agent/infra";
3430
+ import { t as t33 } from "@epoch-agent/infra";
3293
3431
  // src/schedule/add.ts
3294
3432
  import {
3295
3433
  SCHEDULE_DEFAULTS,
3296
3434
  validateSchedule
3297
3435
  } from "@epoch-agent/core";
3298
- import { automationWorkDir, t as t27 } from "@epoch-agent/infra";
3436
+ import { automationWorkDir, t as t28 } from "@epoch-agent/infra";
3299
3437
  import {
3300
3438
  isOperationType as isOperationType2,
3301
3439
  isPermissionLevel as isPermissionLevel3,
@@ -3304,7 +3442,7 @@ import {
3304
3442
  SCHEDULE_INTERVAL_MINUTES
3305
3443
  } from "@epoch-agent/protocol";
3306
3444
  // src/schedule/labels.ts
3307
- import { t as t25 } from "@epoch-agent/infra";
3445
+ import { t as t26 } from "@epoch-agent/infra";
3308
3446
  import {
3309
3447
  collectPendingApprovals
3310
3448
  } from "@epoch-agent/protocol";
@@ -3356,35 +3494,35 @@ var DRIFT_KEYS = {
3356
3494
  "never-registered": "schedule.drift.never_registered"
3357
3495
  };
3358
3496
  function renderIssues(issues) {
3359
- return issues.map((i) => ` \xB7 ${t25(ISSUE_KEYS[i.code], { detail: i.detail ?? "" })}`).join("\n");
3497
+ return issues.map((i) => ` \xB7 ${t26(ISSUE_KEYS[i.code], { detail: i.detail ?? "" })}`).join("\n");
3360
3498
  }
3361
3499
  function statusLabel(status) {
3362
3500
  const mark = status === "ok" ? "\u2705" : status === "failed" || status === "denied" ? "\u274C" : "\u26A0\uFE0F";
3363
- return `${mark} ${t25(STATUS_KEYS[status])}`;
3501
+ return `${mark} ${t26(STATUS_KEYS[status])}`;
3364
3502
  }
3365
3503
  function driftLabel(kind) {
3366
- return t25(DRIFT_KEYS[kind]);
3504
+ return t26(DRIFT_KEYS[kind]);
3367
3505
  }
3368
3506
  function describeTrigger(trigger) {
3369
3507
  if (trigger.kind === "interval") {
3370
- return trigger.everyMinutes < 60 ? t25("schedule.trigger.every_minutes", { n: trigger.everyMinutes }) : t25("schedule.trigger.every_hours", { n: trigger.everyMinutes / 60 });
3508
+ return trigger.everyMinutes < 60 ? t26("schedule.trigger.every_minutes", { n: trigger.everyMinutes }) : t26("schedule.trigger.every_hours", { n: trigger.everyMinutes / 60 });
3371
3509
  }
3372
3510
  if (trigger.kind === "once") {
3373
- return t25("schedule.trigger.once", { date: trigger.date, at: trigger.at });
3511
+ return t26("schedule.trigger.once", { date: trigger.date, at: trigger.at });
3374
3512
  }
3375
- if (trigger.cycle === "daily") return t25("schedule.trigger.daily", { at: trigger.at });
3513
+ if (trigger.cycle === "daily") return t26("schedule.trigger.daily", { at: trigger.at });
3376
3514
  if (trigger.cycle === "weekly") {
3377
- const days = trigger.weekdays.map((d) => t25(WEEKDAY_KEYS[d])).join("/");
3378
- return t25("schedule.trigger.weekly", { days, at: trigger.at });
3515
+ const days = trigger.weekdays.map((d) => t26(WEEKDAY_KEYS[d])).join("/");
3516
+ return t26("schedule.trigger.weekly", { days, at: trigger.at });
3379
3517
  }
3380
- return t25("schedule.trigger.monthly", { days: trigger.days.join("/"), at: trigger.at });
3518
+ return t26("schedule.trigger.monthly", { days: trigger.days.join("/"), at: trigger.at });
3381
3519
  }
3382
3520
  function permissionLabel(level) {
3383
- if (level === "plan") return t25("schedule.permission.plan");
3384
- if (level === "acceptEdits") return t25("schedule.permission.accept_edits");
3385
- if (level === "bypass") return t25("schedule.permission.bypass");
3386
- if (level === "auto") return t25("schedule.permission.auto");
3387
- return t25("schedule.permission.default");
3521
+ if (level === "plan") return t26("schedule.permission.plan");
3522
+ if (level === "acceptEdits") return t26("schedule.permission.accept_edits");
3523
+ if (level === "bypass") return t26("schedule.permission.bypass");
3524
+ if (level === "auto") return t26("schedule.permission.auto");
3525
+ return t26("schedule.permission.default");
3388
3526
  }
3389
3527
  // src/schedule/shared.ts
3390
3528
  import { realpathSync as realpathSync2 } from "fs";
@@ -3393,8 +3531,8 @@ import {
3393
3531
  ScheduleRegistrar,
3394
3532
  ScheduleStore
3395
3533
  } from "@epoch-agent/core";
3396
- import { dbPath as dbPath2, t as t26, uiDateLocale as uiDateLocale3 } from "@epoch-agent/infra";
3397
- var log8 = (msg) => void process.stdout.write(`${msg}
3534
+ import { dbPath as dbPath2, t as t27, uiDateLocale as uiDateLocale3 } from "@epoch-agent/infra";
3535
+ var log9 = (msg) => void process.stdout.write(`${msg}
3398
3536
  `);
3399
3537
  var warn2 = (msg) => void process.stderr.write(`${msg}
3400
3538
  `);
@@ -3422,24 +3560,24 @@ function mustFind(store, idOrPrefix) {
3422
3560
  if (hits.length === 1) return hits[0];
3423
3561
  if (hits.length === 0) {
3424
3562
  throw new CliError(
3425
- t26("schedule.err_not_found", { id: idOrPrefix }),
3563
+ t27("schedule.err_not_found", { id: idOrPrefix }),
3426
3564
  EXIT_CODES.FAILURE,
3427
- t26("schedule.err_not_found_hint")
3565
+ t27("schedule.err_not_found_hint")
3428
3566
  );
3429
3567
  }
3430
3568
  throw new CliError(
3431
- t26("schedule.err_ambiguous", { id: idOrPrefix }),
3569
+ t27("schedule.err_ambiguous", { id: idOrPrefix }),
3432
3570
  EXIT_CODES.FAILURE,
3433
3571
  hits.map((h) => ` ${h.id} ${h.name}`).join("\n")
3434
3572
  );
3435
3573
  }
3436
3574
  function reportRegistration(outcome, fatal) {
3437
3575
  if (outcome.ok) {
3438
- if (outcome.warnings.includes("source")) warn2(t26("schedule.warn_source_entry"));
3576
+ if (outcome.warnings.includes("source")) warn2(t27("schedule.warn_source_entry"));
3439
3577
  return;
3440
3578
  }
3441
- const message = outcome.reason === "unsupported-platform" ? t26("schedule.err_platform_unsupported") : outcome.reason === "backend-error" ? t26("schedule.err_backend", { detail: outcome.detail }) : outcome.refusal === "npx" ? t26("schedule.err_npx") : t26("schedule.err_no_host_runner");
3442
- const hint = outcome.reason === "refused" && outcome.refusal === "npx" ? t26("schedule.err_npx_hint") : outcome.reason === "refused" ? t26("schedule.err_no_host_runner_hint") : void 0;
3579
+ const message = outcome.reason === "unsupported-platform" ? t27("schedule.err_platform_unsupported") : outcome.reason === "backend-error" ? t27("schedule.err_backend", { detail: outcome.detail }) : outcome.refusal === "npx" ? t27("schedule.err_npx") : t27("schedule.err_no_host_runner");
3580
+ const hint = outcome.reason === "refused" && outcome.refusal === "npx" ? t27("schedule.err_npx_hint") : outcome.reason === "refused" ? t27("schedule.err_no_host_runner_hint") : void 0;
3443
3581
  if (!fatal) {
3444
3582
  warn2(message);
3445
3583
  if (hint) warn2(hint);
@@ -3477,7 +3615,7 @@ async function runAdd(opts) {
3477
3615
  });
3478
3616
  if (validation.issues.length > 0) {
3479
3617
  throw new CliError(
3480
- t27("schedule.err_invalid"),
3618
+ t28("schedule.err_invalid"),
3481
3619
  EXIT_CODES.FAILURE,
3482
3620
  renderIssues(validation.issues)
3483
3621
  );
@@ -3507,26 +3645,26 @@ async function fillInteractively(opts) {
3507
3645
  if (!missing) return opts;
3508
3646
  if (!process.stdin.isTTY || !process.stdout.isTTY) {
3509
3647
  throw new CliError(
3510
- t27("schedule.err_missing_flags"),
3648
+ t28("schedule.err_missing_flags"),
3511
3649
  EXIT_CODES.FAILURE,
3512
- t27("schedule.err_missing_flags_hint")
3650
+ t28("schedule.err_missing_flags_hint")
3513
3651
  );
3514
3652
  }
3515
3653
  const { input: input2, select: select2 } = await import("@inquirer/prompts");
3516
3654
  const next = { ...opts };
3517
- next.name ||= await input2({ message: t27("schedule.ask_name") });
3518
- next.prompt ||= await input2({ message: t27("schedule.ask_prompt") });
3655
+ next.name ||= await input2({ message: t28("schedule.ask_name") });
3656
+ next.prompt ||= await input2({ message: t28("schedule.ask_prompt") });
3519
3657
  if (!hasTrigger) {
3520
- const at = await input2({ message: t27("schedule.ask_at"), default: "09:00" });
3658
+ const at = await input2({ message: t28("schedule.ask_at"), default: "09:00" });
3521
3659
  next.daily = at;
3522
3660
  }
3523
- next.budget ||= await input2({ message: t27("schedule.ask_budget"), default: "0.50" });
3661
+ next.budget ||= await input2({ message: t28("schedule.ask_budget"), default: "0.50" });
3524
3662
  next.permission ||= await select2({
3525
- message: t27("schedule.ask_permission"),
3663
+ message: t28("schedule.ask_permission"),
3526
3664
  choices: [
3527
- { name: t27("schedule.permission.default"), value: "default" },
3528
- { name: t27("schedule.permission.plan"), value: "plan" },
3529
- { name: t27("schedule.permission.accept_edits"), value: "acceptEdits" }
3665
+ { name: t28("schedule.permission.default"), value: "default" },
3666
+ { name: t28("schedule.permission.plan"), value: "plan" },
3667
+ { name: t28("schedule.permission.accept_edits"), value: "acceptEdits" }
3530
3668
  ]
3531
3669
  });
3532
3670
  return next;
@@ -3535,8 +3673,8 @@ function parseTrigger(opts) {
3535
3673
  const given = [opts.daily, opts.weekly, opts.monthly, opts.every, opts.once].filter(
3536
3674
  (v) => v !== void 0
3537
3675
  );
3538
- if (given.length === 0) throw new CliError(t27("schedule.err_no_trigger"), EXIT_CODES.FAILURE);
3539
- if (given.length > 1) throw new CliError(t27("schedule.err_many_triggers"), EXIT_CODES.FAILURE);
3676
+ if (given.length === 0) throw new CliError(t28("schedule.err_no_trigger"), EXIT_CODES.FAILURE);
3677
+ if (given.length > 1) throw new CliError(t28("schedule.err_many_triggers"), EXIT_CODES.FAILURE);
3540
3678
  if (opts.daily !== void 0) return { kind: "cron", cycle: "daily", at: opts.daily };
3541
3679
  if (opts.weekly !== void 0) {
3542
3680
  return {
@@ -3560,14 +3698,14 @@ function parseTrigger(opts) {
3560
3698
  return { kind: "interval", everyMinutes: parseEvery(opts.every) };
3561
3699
  }
3562
3700
  function requireAt(opts) {
3563
- if (!opts.at) throw new CliError(t27("schedule.err_at_required"), EXIT_CODES.FAILURE);
3701
+ if (!opts.at) throw new CliError(t28("schedule.err_at_required"), EXIT_CODES.FAILURE);
3564
3702
  return opts.at;
3565
3703
  }
3566
3704
  function parseWeekday(raw) {
3567
3705
  const idx = WEEKDAY_CODES.indexOf(raw.trim().toUpperCase());
3568
3706
  if (idx < 0) {
3569
3707
  throw new CliError(
3570
- t27("schedule.err_weekday", { value: raw }),
3708
+ t28("schedule.err_weekday", { value: raw }),
3571
3709
  EXIT_CODES.FAILURE,
3572
3710
  WEEKDAY_CODES.join(",")
3573
3711
  );
@@ -3579,9 +3717,9 @@ function parseEvery(raw) {
3579
3717
  const minutes = m ? Number(m[1]) * (m[2]?.toLowerCase() === "h" ? 60 : 1) : Number.NaN;
3580
3718
  if (!SCHEDULE_INTERVAL_MINUTES.includes(minutes)) {
3581
3719
  throw new CliError(
3582
- t27("schedule.err_every", { value: raw }),
3720
+ t28("schedule.err_every", { value: raw }),
3583
3721
  EXIT_CODES.FAILURE,
3584
- t27("schedule.err_every_hint", {
3722
+ t28("schedule.err_every_hint", {
3585
3723
  values: SCHEDULE_INTERVAL_MINUTES.map((n) => n < 60 ? `${n}m` : `${n / 60}h`).join(" / ")
3586
3724
  })
3587
3725
  );
@@ -3592,7 +3730,7 @@ function parsePermission(raw) {
3592
3730
  if (raw === void 0) return "default";
3593
3731
  if (!isPermissionLevel3(raw)) {
3594
3732
  throw new CliError(
3595
- t27("schedule.err_permission", { value: raw }),
3733
+ t28("schedule.err_permission", { value: raw }),
3596
3734
  EXIT_CODES.FAILURE,
3597
3735
  PERMISSION_LEVELS4.join(" / ")
3598
3736
  );
@@ -3604,7 +3742,7 @@ function parseOperations(raw) {
3604
3742
  for (const value of raw ?? []) {
3605
3743
  if (!isOperationType2(value)) {
3606
3744
  throw new CliError(
3607
- t27("schedule.err_operation", { value }),
3745
+ t28("schedule.err_operation", { value }),
3608
3746
  EXIT_CODES.FAILURE,
3609
3747
  OPERATION_TYPES4.join(" / ")
3610
3748
  );
@@ -3617,9 +3755,9 @@ function buildInput(opts, trigger, permission) {
3617
3755
  const budget = Number(opts.budget);
3618
3756
  if (!Number.isFinite(budget) || budget <= 0) {
3619
3757
  throw new CliError(
3620
- t27("schedule.err_budget", { value: opts.budget ?? "" }),
3758
+ t28("schedule.err_budget", { value: opts.budget ?? "" }),
3621
3759
  EXIT_CODES.FAILURE,
3622
- t27("schedule.err_budget_hint")
3760
+ t28("schedule.err_budget_hint")
3623
3761
  );
3624
3762
  }
3625
3763
  return {
@@ -3655,52 +3793,52 @@ function applyDefaultAllowlist(store, def, opts) {
3655
3793
  }) ?? def;
3656
3794
  }
3657
3795
  function printSummary(def) {
3658
- log8(t27("schedule.created", { id: def.id, name: def.name }));
3659
- log8("");
3660
- log8(t27("schedule.created_next", { id: def.id.slice(0, 12) }));
3796
+ log9(t28("schedule.created", { id: def.id, name: def.name }));
3797
+ log9("");
3798
+ log9(t28("schedule.created_next", { id: def.id.slice(0, 12) }));
3661
3799
  }
3662
3800
  // src/schedule/doctor.ts
3663
3801
  import { diagnoseSchedules, pruneSchedules, repairSchedules } from "@epoch-agent/core";
3664
- import { t as t28 } from "@epoch-agent/infra";
3802
+ import { t as t29 } from "@epoch-agent/infra";
3665
3803
  async function runDoctor(opts) {
3666
3804
  const ctx = await openSchedule();
3667
3805
  try {
3668
3806
  const deps = { store: ctx.store, backend: ctx.backend, registrar: ctx.registrar };
3669
3807
  const report = await diagnoseSchedules(deps);
3670
3808
  if (report.unsupported) {
3671
- warn2(t28("schedule.doctor_unsupported"));
3809
+ warn2(t29("schedule.doctor_unsupported"));
3672
3810
  return;
3673
3811
  }
3674
3812
  if (report.drifts.length === 0) {
3675
- log8(t28("schedule.doctor_clean", { n: report.checked }));
3813
+ log9(t29("schedule.doctor_clean", { n: report.checked }));
3676
3814
  return;
3677
3815
  }
3678
- log8(t28("schedule.doctor_found", { n: report.drifts.length }));
3816
+ log9(t29("schedule.doctor_found", { n: report.drifts.length }));
3679
3817
  for (const drift of report.drifts) {
3680
- log8(
3818
+ log9(
3681
3819
  ` \xB7 ${driftLabel(drift.kind)} ${drift.name ?? drift.scheduleId ?? ""} [${drift.osTaskId || "\u2014"}]${drift.detail ? `
3682
3820
  ${drift.detail}` : ""}`
3683
3821
  );
3684
3822
  }
3685
3823
  if (opts.repair !== true && opts.prune !== true) {
3686
- log8("");
3687
- log8(t28("schedule.doctor_hint"));
3824
+ log9("");
3825
+ log9(t29("schedule.doctor_hint"));
3688
3826
  return;
3689
3827
  }
3690
3828
  if (opts.repair === true) {
3691
3829
  for (const outcome of await repairSchedules(report.drifts, deps)) {
3692
3830
  const label = outcome.drift.name ?? outcome.drift.scheduleId ?? "";
3693
- if (outcome.ok) log8(t28("schedule.doctor_repaired", { name: label }));
3831
+ if (outcome.ok) log9(t29("schedule.doctor_repaired", { name: label }));
3694
3832
  else
3695
- warn2(t28("schedule.doctor_repair_failed", { name: label, detail: outcome.detail ?? "" }));
3833
+ warn2(t29("schedule.doctor_repair_failed", { name: label, detail: outcome.detail ?? "" }));
3696
3834
  }
3697
3835
  }
3698
3836
  if (opts.prune === true) {
3699
3837
  for (const outcome of await pruneSchedules(report.drifts, deps)) {
3700
- if (outcome.ok) log8(t28("schedule.doctor_pruned", { id: outcome.drift.osTaskId }));
3838
+ if (outcome.ok) log9(t29("schedule.doctor_pruned", { id: outcome.drift.osTaskId }));
3701
3839
  else {
3702
3840
  warn2(
3703
- t28("schedule.doctor_prune_failed", {
3841
+ t29("schedule.doctor_prune_failed", {
3704
3842
  id: outcome.drift.osTaskId,
3705
3843
  detail: outcome.detail ?? ""
3706
3844
  })
@@ -3714,15 +3852,15 @@ async function runDoctor(opts) {
3714
3852
  }
3715
3853
  }
3716
3854
  // src/schedule/manage.ts
3717
- import { automationLogsDir, t as t29 } from "@epoch-agent/infra";
3855
+ import { automationLogsDir, t as t30 } from "@epoch-agent/infra";
3718
3856
  async function runSetEnabled(idOrPrefix, enabled) {
3719
3857
  const ctx = await openSchedule();
3720
3858
  try {
3721
3859
  const def = mustFind(ctx.store, idOrPrefix);
3722
3860
  const outcome = await ctx.registrar.setEnabled(def, enabled);
3723
3861
  reportRegistration(outcome, false);
3724
- log8(
3725
- enabled ? t29("schedule.enabled_done", { name: def.name }) : t29("schedule.disabled_done", { name: def.name })
3862
+ log9(
3863
+ enabled ? t30("schedule.enabled_done", { name: def.name }) : t30("schedule.disabled_done", { name: def.name })
3726
3864
  );
3727
3865
  } finally {
3728
3866
  ctx.close();
@@ -3734,14 +3872,14 @@ async function runRemove(idOrPrefix) {
3734
3872
  const def = mustFind(ctx.store, idOrPrefix);
3735
3873
  if (def.osTaskId) reportRegistration(await ctx.registrar.unregister(def), false);
3736
3874
  ctx.store.remove(def.id);
3737
- log8(t29("schedule.removed", { name: def.name }));
3738
- log8(t29("schedule.removed_logs_kept", { dir: automationLogsDir(def.id, ctx.homeDir) }));
3875
+ log9(t30("schedule.removed", { name: def.name }));
3876
+ log9(t30("schedule.removed_logs_kept", { dir: automationLogsDir(def.id, ctx.homeDir) }));
3739
3877
  } finally {
3740
3878
  ctx.close();
3741
3879
  }
3742
3880
  }
3743
3881
  // src/schedule/run.ts
3744
- import { t as t30 } from "@epoch-agent/infra";
3882
+ import { t as t31 } from "@epoch-agent/infra";
3745
3883
  import { unfixedRules } from "@epoch-agent/protocol";
3746
3884
  import { fireSchedule } from "@epoch-agent/runtime";
3747
3885
  async function runFire(scheduleId, homeDir) {
@@ -3754,9 +3892,9 @@ async function runFire(scheduleId, homeDir) {
3754
3892
  ctx.close();
3755
3893
  }
3756
3894
  if (result.missing) {
3757
- warn2(t30("schedule.fire_missing", { id: scheduleId }));
3895
+ warn2(t31("schedule.fire_missing", { id: scheduleId }));
3758
3896
  } else if (result.disabled) {
3759
- warn2(t30("schedule.fire_disabled", { id: scheduleId }));
3897
+ warn2(t31("schedule.fire_disabled", { id: scheduleId }));
3760
3898
  } else {
3761
3899
  warn2(`${statusLabel(result.status)}${result.detail ? ` ${result.detail}` : ""}`);
3762
3900
  }
@@ -3766,14 +3904,14 @@ async function runManual(idOrPrefix, opts) {
3766
3904
  const ctx = await openSchedule();
3767
3905
  try {
3768
3906
  const def = mustFind(ctx.store, idOrPrefix);
3769
- log8(t30("schedule.run_start", { name: def.name }));
3907
+ log9(t31("schedule.run_start", { name: def.name }));
3770
3908
  const result = await fireSchedule({
3771
3909
  scheduleId: def.id,
3772
3910
  homeDir: ctx.homeDir,
3773
3911
  manual: true,
3774
3912
  registrar: ctx.registrar
3775
3913
  });
3776
- log8(`${statusLabel(result.status)}${result.detail ? ` ${result.detail}` : ""}`);
3914
+ log9(`${statusLabel(result.status)}${result.detail ? ` ${result.detail}` : ""}`);
3777
3915
  const pending = result.run?.pendingApprovals ?? [];
3778
3916
  if (pending.length === 0) {
3779
3917
  process.exitCode = result.exitCode;
@@ -3782,21 +3920,21 @@ async function runManual(idOrPrefix, opts) {
3782
3920
  printPending(pending);
3783
3921
  if (opts.fix === true) {
3784
3922
  const added = applyFix(ctx.store, def.id, pending);
3785
- log8(added.length > 0 ? t30("schedule.fix_done", { n: added.length }) : t30("schedule.fix_none"));
3923
+ log9(added.length > 0 ? t31("schedule.fix_done", { n: added.length }) : t31("schedule.fix_none"));
3786
3924
  return;
3787
3925
  }
3788
- log8(t30("schedule.fix_hint", { id: def.id.slice(0, 12) }));
3926
+ log9(t31("schedule.fix_hint", { id: def.id.slice(0, 12) }));
3789
3927
  process.exitCode = result.exitCode;
3790
3928
  } finally {
3791
3929
  ctx.close();
3792
3930
  }
3793
3931
  }
3794
3932
  function printPending(pending) {
3795
- log8("");
3796
- log8(t30("schedule.pending_header", { n: pending.length }));
3933
+ log9("");
3934
+ log9(t31("schedule.pending_header", { n: pending.length }));
3797
3935
  for (const item of pending) {
3798
- log8(` \xB7 ${t30("schedule.pending_line", { tool: item.toolName, target: item.target })}`);
3799
- if (item.suggestedRule) log8(` \u2192 ${item.suggestedRule}`);
3936
+ log9(` \xB7 ${t31("schedule.pending_line", { tool: item.toolName, target: item.target })}`);
3937
+ if (item.suggestedRule) log9(` \u2192 ${item.suggestedRule}`);
3800
3938
  }
3801
3939
  }
3802
3940
  function applyFix(store, scheduleId, pending) {
@@ -3808,23 +3946,23 @@ function applyFix(store, scheduleId, pending) {
3808
3946
  }
3809
3947
  // src/schedule/view.ts
3810
3948
  import { nextRunAt, readRecording } from "@epoch-agent/core";
3811
- import { t as t31 } from "@epoch-agent/infra";
3949
+ import { t as t32 } from "@epoch-agent/infra";
3812
3950
  async function runList() {
3813
3951
  const ctx = await openSchedule();
3814
3952
  try {
3815
3953
  const defs = ctx.store.list();
3816
3954
  if (defs.length === 0) {
3817
- log8(t31("schedule.list_empty"));
3818
- log8(t31("schedule.list_empty_hint"));
3955
+ log9(t32("schedule.list_empty"));
3956
+ log9(t32("schedule.list_empty_hint"));
3819
3957
  return;
3820
3958
  }
3821
- log8(t31("schedule.list_header"));
3959
+ log9(t32("schedule.list_header"));
3822
3960
  for (const def of defs) {
3823
- const next = def.enabled ? formatWhen(nextRunAt(def.trigger, Date.now(), def.startDate, def.endDate) ?? void 0) : t31("schedule.disabled_mark");
3961
+ const next = def.enabled ? formatWhen(nextRunAt(def.trigger, Date.now(), def.startDate, def.endDate) ?? void 0) : t32("schedule.disabled_mark");
3824
3962
  const danger = def.permission === "bypass" ? " \u{1F534}" : "";
3825
- log8(
3963
+ log9(
3826
3964
  ` ${def.id.slice(0, 12)} ${def.name}${danger}
3827
- ${describeTrigger(def.trigger)} \xB7 ${t31("schedule.col_next")} ${next} \xB7 ${t31("schedule.col_last")} ${def.lastStatus ? statusLabel(def.lastStatus) : "\u2014"} \xB7 ${permissionLabel(def.permission)}`
3965
+ ${describeTrigger(def.trigger)} \xB7 ${t32("schedule.col_next")} ${next} \xB7 ${t32("schedule.col_last")} ${def.lastStatus ? statusLabel(def.lastStatus) : "\u2014"} \xB7 ${permissionLabel(def.permission)}`
3828
3966
  );
3829
3967
  }
3830
3968
  } finally {
@@ -3835,45 +3973,45 @@ async function runShow(idOrPrefix) {
3835
3973
  const ctx = await openSchedule();
3836
3974
  try {
3837
3975
  const def = mustFind(ctx.store, idOrPrefix);
3838
- log8(`${def.name} (${def.id})`);
3839
- log8(` ${t31("schedule.field_enabled")}: ${def.enabled ? t31("schedule.yes") : t31("schedule.no")}`);
3840
- log8(` ${t31("schedule.field_trigger")}: ${describeTrigger(def.trigger)}`);
3976
+ log9(`${def.name} (${def.id})`);
3977
+ log9(` ${t32("schedule.field_enabled")}: ${def.enabled ? t32("schedule.yes") : t32("schedule.no")}`);
3978
+ log9(` ${t32("schedule.field_trigger")}: ${describeTrigger(def.trigger)}`);
3841
3979
  if (def.startDate ?? def.endDate) {
3842
- log8(` ${t31("schedule.field_window")}: ${def.startDate ?? "\u2014"} .. ${def.endDate ?? "\u2014"}`);
3980
+ log9(` ${t32("schedule.field_window")}: ${def.startDate ?? "\u2014"} .. ${def.endDate ?? "\u2014"}`);
3843
3981
  }
3844
- log8(
3845
- ` ${t31("schedule.field_next")}: ${formatWhen(
3982
+ log9(
3983
+ ` ${t32("schedule.field_next")}: ${formatWhen(
3846
3984
  nextRunAt(def.trigger, Date.now(), def.startDate, def.endDate) ?? void 0
3847
3985
  )}`
3848
3986
  );
3849
- log8(` ${t31("schedule.field_workdir")}: ${def.workDir}`);
3850
- if (def.model) log8(` ${t31("schedule.field_model")}: ${def.model}`);
3851
- log8(` ${t31("schedule.field_permission")}: ${permissionLabel(def.permission)}`);
3852
- log8(
3853
- ` ${t31("schedule.field_limits")}: ` + t31("schedule.limits_value", {
3987
+ log9(` ${t32("schedule.field_workdir")}: ${def.workDir}`);
3988
+ if (def.model) log9(` ${t32("schedule.field_model")}: ${def.model}`);
3989
+ log9(` ${t32("schedule.field_permission")}: ${permissionLabel(def.permission)}`);
3990
+ log9(
3991
+ ` ${t32("schedule.field_limits")}: ` + t32("schedule.limits_value", {
3854
3992
  turns: def.maxTurns,
3855
3993
  budget: def.maxBudgetUsd.toFixed(2),
3856
3994
  minutes: Math.round(def.timeoutMs / 6e4)
3857
3995
  })
3858
3996
  );
3859
- log8(` ${t31("schedule.field_backend")}: ${def.osBackend} ${def.osTaskId || "\u2014"}`);
3860
- log8(` ${t31("schedule.field_prompt")}:`);
3861
- for (const line of def.prompt.split("\n")) log8(` ${line}`);
3862
- log8("");
3997
+ log9(` ${t32("schedule.field_backend")}: ${def.osBackend} ${def.osTaskId || "\u2014"}`);
3998
+ log9(` ${t32("schedule.field_prompt")}:`);
3999
+ for (const line of def.prompt.split("\n")) log9(` ${line}`);
4000
+ log9("");
3863
4001
  printAllowlist(def);
3864
- log8("");
3865
- log8(t31("schedule.field_last_run", { when: formatWhen(def.lastRunAt) }));
4002
+ log9("");
4003
+ log9(t32("schedule.field_last_run", { when: formatWhen(def.lastRunAt) }));
3866
4004
  } finally {
3867
4005
  ctx.close();
3868
4006
  }
3869
4007
  }
3870
4008
  function printAllowlist(def) {
3871
4009
  if (def.permission === "bypass") {
3872
- log8(t31("schedule.allowlist_bypass"));
4010
+ log9(t32("schedule.allowlist_bypass"));
3873
4011
  return;
3874
4012
  }
3875
4013
  if (def.permission === "plan") {
3876
- log8(t31("schedule.allowlist_readonly"));
4014
+ log9(t32("schedule.allowlist_readonly"));
3877
4015
  return;
3878
4016
  }
3879
4017
  const lines = [
@@ -3881,9 +4019,9 @@ function printAllowlist(def) {
3881
4019
  ...def.allowOperations.map((v) => ` ${v}`),
3882
4020
  ...def.allowRules.map((v) => ` ${v}`)
3883
4021
  ];
3884
- log8(t31("schedule.allowlist_header"));
3885
- log8(lines.length > 0 ? lines.join("\n") : ` ${t31("schedule.allowlist_empty")}`);
3886
- log8(t31("schedule.allowlist_scope_note"));
4022
+ log9(t32("schedule.allowlist_header"));
4023
+ log9(lines.length > 0 ? lines.join("\n") : ` ${t32("schedule.allowlist_empty")}`);
4024
+ log9(t32("schedule.allowlist_scope_note"));
3887
4025
  }
3888
4026
  async function runLogs(idOrPrefix, limit, tail) {
3889
4027
  const ctx = await openSchedule();
@@ -3891,7 +4029,7 @@ async function runLogs(idOrPrefix, limit, tail) {
3891
4029
  const def = mustFind(ctx.store, idOrPrefix);
3892
4030
  const runs = ctx.store.listRuns(def.id, limit);
3893
4031
  if (runs.length === 0) {
3894
- log8(t31("schedule.logs_empty"));
4032
+ log9(t32("schedule.logs_empty"));
3895
4033
  return;
3896
4034
  }
3897
4035
  for (const run of runs) printRun(run);
@@ -3901,31 +4039,31 @@ async function runLogs(idOrPrefix, limit, tail) {
3901
4039
  }
3902
4040
  }
3903
4041
  function printRun(run) {
3904
- log8(
3905
- ` ${formatWhen(run.startedAt)} ${statusLabel(run.status)} ` + t31("schedule.run_meta", {
4042
+ log9(
4043
+ ` ${formatWhen(run.startedAt)} ${statusLabel(run.status)} ` + t32("schedule.run_meta", {
3906
4044
  turns: run.turns,
3907
4045
  cost: run.costUsd.toFixed(4),
3908
- manual: run.manual ? t31("schedule.run_manual") : ""
4046
+ manual: run.manual ? t32("schedule.run_manual") : ""
3909
4047
  })
3910
4048
  );
3911
- if (run.reason) log8(` ${run.reason}`);
4049
+ if (run.reason) log9(` ${run.reason}`);
3912
4050
  for (const pending of run.pendingApprovals) {
3913
- log8(
3914
- ` \u26A0 ${t31("schedule.pending_line", { tool: pending.toolName, target: pending.target })}`
4051
+ log9(
4052
+ ` \u26A0 ${t32("schedule.pending_line", { tool: pending.toolName, target: pending.target })}`
3915
4053
  );
3916
4054
  if (pending.suggestedRule) {
3917
- log8(` ${t31("schedule.pending_fix", { rule: pending.suggestedRule })}`);
4055
+ log9(` ${t32("schedule.pending_fix", { rule: pending.suggestedRule })}`);
3918
4056
  }
3919
4057
  }
3920
4058
  }
3921
4059
  function printRecording(run) {
3922
4060
  if (!run.logPath) return;
3923
- log8("");
3924
- log8(t31("schedule.logs_recording", { path: run.logPath }));
4061
+ log9("");
4062
+ log9(t32("schedule.logs_recording", { path: run.logPath }));
3925
4063
  for (const envelope of readRecording(run.logPath)) {
3926
4064
  const event = envelope.event;
3927
4065
  if (event.type === "text-delta" && event.text) process.stdout.write(event.text);
3928
- else if (event.type === "error" && event.message) log8(`
4066
+ else if (event.type === "error" && event.message) log9(`
3929
4067
  [error] ${event.message}`);
3930
4068
  }
3931
4069
  process.stdout.write("\n");
@@ -3933,19 +4071,19 @@ function printRecording(run) {
3933
4071
  // src/commands/schedule.ts
3934
4072
  var DEFAULT_LOG_LIMIT = 10;
3935
4073
  function registerScheduleCommand(program2) {
3936
- const cmd = program2.command("schedule").description(t32("cli.schedule.summary"));
3937
- cmd.command("add").description(t32("cli.schedule.add")).option("--name <name>", t32("cli.schedule.opt_name")).option("--prompt <text>", t32("cli.schedule.opt_prompt")).option("--daily <HH:mm>", t32("cli.schedule.opt_daily")).option("--weekly <days>", t32("cli.schedule.opt_weekly")).option("--monthly <days>", t32("cli.schedule.opt_monthly")).option("--every <interval>", t32("cli.schedule.opt_every")).option("--once <YYYY-MM-DD>", t32("cli.schedule.opt_once")).option("--at <HH:mm>", t32("cli.schedule.opt_at")).option("--start <YYYY-MM-DD>", t32("cli.schedule.opt_start")).option("--end <YYYY-MM-DD>", t32("cli.schedule.opt_end")).option("--workdir <dir>", t32("cli.schedule.opt_workdir")).option("--model <model>", t32("cli.schedule.opt_model")).option("--permission <level>", t32("cli.schedule.opt_permission")).option("--allow-tool <name>", t32("cli.schedule.opt_allow_tool"), collect3, []).option("--allow-operation <type>", t32("cli.schedule.opt_allow_operation"), collect3, []).option("--allow-rule <rule>", t32("cli.schedule.opt_allow_rule"), collect3, []).option("--max-turns <n>", t32("cli.schedule.opt_max_turns")).option("--budget <usd>", t32("cli.schedule.opt_budget")).option("--timeout <minutes>", t32("cli.schedule.opt_timeout")).option("--disabled", t32("cli.schedule.opt_disabled")).option("--i-understand-bypass", t32("cli.schedule.opt_bypass_ack")).action((opts) => runAdd(opts));
3938
- cmd.command("list", { isDefault: true }).description(t32("cli.schedule.list")).action(() => runList());
3939
- cmd.command("show").description(t32("cli.schedule.show")).argument("<id>", t32("cli.schedule.arg_id")).action((id) => runShow(id));
3940
- cmd.command("enable").description(t32("cli.schedule.enable")).argument("<id>", t32("cli.schedule.arg_id")).action((id) => runSetEnabled(id, true));
3941
- cmd.command("disable").description(t32("cli.schedule.disable")).argument("<id>", t32("cli.schedule.arg_id")).action((id) => runSetEnabled(id, false));
3942
- cmd.command("rm").alias("remove").description(t32("cli.schedule.rm")).argument("<id>", t32("cli.schedule.arg_id")).action((id) => runRemove(id));
3943
- cmd.command("run").description(t32("cli.schedule.run")).argument("<id>", t32("cli.schedule.arg_id")).option("--fix", t32("cli.schedule.opt_fix")).action((id, opts) => runManual(id, opts));
3944
- cmd.command("logs").description(t32("cli.schedule.logs")).argument("<id>", t32("cli.schedule.arg_id")).option("-n, --limit <n>", t32("cli.schedule.opt_limit"), String(DEFAULT_LOG_LIMIT)).option("--tail", t32("cli.schedule.opt_tail")).action(
4074
+ const cmd = program2.command("schedule").description(t33("cli.schedule.summary"));
4075
+ cmd.command("add").description(t33("cli.schedule.add")).option("--name <name>", t33("cli.schedule.opt_name")).option("--prompt <text>", t33("cli.schedule.opt_prompt")).option("--daily <HH:mm>", t33("cli.schedule.opt_daily")).option("--weekly <days>", t33("cli.schedule.opt_weekly")).option("--monthly <days>", t33("cli.schedule.opt_monthly")).option("--every <interval>", t33("cli.schedule.opt_every")).option("--once <YYYY-MM-DD>", t33("cli.schedule.opt_once")).option("--at <HH:mm>", t33("cli.schedule.opt_at")).option("--start <YYYY-MM-DD>", t33("cli.schedule.opt_start")).option("--end <YYYY-MM-DD>", t33("cli.schedule.opt_end")).option("--workdir <dir>", t33("cli.schedule.opt_workdir")).option("--model <model>", t33("cli.schedule.opt_model")).option("--permission <level>", t33("cli.schedule.opt_permission")).option("--allow-tool <name>", t33("cli.schedule.opt_allow_tool"), collect3, []).option("--allow-operation <type>", t33("cli.schedule.opt_allow_operation"), collect3, []).option("--allow-rule <rule>", t33("cli.schedule.opt_allow_rule"), collect3, []).option("--max-turns <n>", t33("cli.schedule.opt_max_turns")).option("--budget <usd>", t33("cli.schedule.opt_budget")).option("--timeout <minutes>", t33("cli.schedule.opt_timeout")).option("--disabled", t33("cli.schedule.opt_disabled")).option("--i-understand-bypass", t33("cli.schedule.opt_bypass_ack")).action((opts) => runAdd(opts));
4076
+ cmd.command("list", { isDefault: true }).description(t33("cli.schedule.list")).action(() => runList());
4077
+ cmd.command("show").description(t33("cli.schedule.show")).argument("<id>", t33("cli.schedule.arg_id")).action((id) => runShow(id));
4078
+ cmd.command("enable").description(t33("cli.schedule.enable")).argument("<id>", t33("cli.schedule.arg_id")).action((id) => runSetEnabled(id, true));
4079
+ cmd.command("disable").description(t33("cli.schedule.disable")).argument("<id>", t33("cli.schedule.arg_id")).action((id) => runSetEnabled(id, false));
4080
+ cmd.command("rm").alias("remove").description(t33("cli.schedule.rm")).argument("<id>", t33("cli.schedule.arg_id")).action((id) => runRemove(id));
4081
+ cmd.command("run").description(t33("cli.schedule.run")).argument("<id>", t33("cli.schedule.arg_id")).option("--fix", t33("cli.schedule.opt_fix")).action((id, opts) => runManual(id, opts));
4082
+ cmd.command("logs").description(t33("cli.schedule.logs")).argument("<id>", t33("cli.schedule.arg_id")).option("-n, --limit <n>", t33("cli.schedule.opt_limit"), String(DEFAULT_LOG_LIMIT)).option("--tail", t33("cli.schedule.opt_tail")).action(
3945
4083
  (id, opts) => runLogs(id, Number(opts.limit ?? DEFAULT_LOG_LIMIT), opts.tail === true)
3946
4084
  );
3947
- cmd.command("fire").description(t32("cli.schedule.fire")).argument("<id>", t32("cli.schedule.arg_id")).option("--home <dir>", t32("cli.schedule.opt_home")).action((id, opts) => runFire(id, opts.home));
3948
- cmd.command("doctor").description(t32("cli.schedule.doctor")).option("--repair", t32("cli.schedule.opt_repair")).option("--prune", t32("cli.schedule.opt_prune")).action((opts) => runDoctor(opts));
4085
+ cmd.command("fire").description(t33("cli.schedule.fire")).argument("<id>", t33("cli.schedule.arg_id")).option("--home <dir>", t33("cli.schedule.opt_home")).action((id, opts) => runFire(id, opts.home));
4086
+ cmd.command("doctor").description(t33("cli.schedule.doctor")).option("--repair", t33("cli.schedule.opt_repair")).option("--prune", t33("cli.schedule.opt_prune")).action((opts) => runDoctor(opts));
3949
4087
  }
3950
4088
  function collect3(value, previous) {
3951
4089
  return [...previous, value];
@@ -3956,7 +4094,7 @@ import { statfs } from "fs/promises";
3956
4094
  import {
3957
4095
  describeIsolation,
3958
4096
  getConfigIssues,
3959
- loadConfig as loadConfig3,
4097
+ loadConfig as loadConfig4,
3960
4098
  SANDBOX_COVERS,
3961
4099
  SANDBOX_EXCLUDES
3962
4100
  } from "@epoch-agent/core";
@@ -3964,17 +4102,13 @@ import {
3964
4102
  allJobs,
3965
4103
  confine,
3966
4104
  resolveProfile,
3967
- t as t34
4105
+ t as t35
3968
4106
  } from "@epoch-agent/infra";
3969
4107
  import { hasFailure } from "@epoch-agent/protocol";
3970
- import {
3971
- classifyTerminal,
3972
- probeShiftEnter
3973
- } from "@epoch-agent/tui";
3974
4108
  // src/statusline.ts
3975
4109
  import { execFile as execFile2 } from "child_process";
3976
4110
  import { sanitizeToolOutput } from "@epoch-agent/core";
3977
- import { shellSpawnArgs, t as t33 } from "@epoch-agent/infra";
4111
+ import { shellSpawnArgs, t as t34 } from "@epoch-agent/infra";
3978
4112
  var TIMEOUT_MS2 = 2e3;
3979
4113
  var MAX_WIDTH = 60;
3980
4114
  var MAX_BUFFER = 64 * 1024;
@@ -4002,7 +4136,7 @@ function runStatusLineCommand(command, cwd) {
4002
4136
  const killed = err2.killed === true;
4003
4137
  settle({
4004
4138
  text: null,
4005
- error: killed ? t33("statusline.timeout", { ms: TIMEOUT_MS2 }) : err2.message.trim()
4139
+ error: killed ? t34("statusline.timeout", { ms: TIMEOUT_MS2 }) : err2.message.trim()
4006
4140
  });
4007
4141
  return;
4008
4142
  }
@@ -4016,12 +4150,12 @@ async function probeStatusLine(config, cwd) {
4016
4150
  if (!command) return null;
4017
4151
  const result = await runStatusLineCommand(command, cwd);
4018
4152
  if (result.text === null) {
4019
- return { command, ok: false, detail: result.error ?? t33("statusline.no_output") };
4153
+ return { command, ok: false, detail: result.error ?? t34("statusline.no_output") };
4020
4154
  }
4021
4155
  return { command, ok: true, detail: result.text };
4022
4156
  }
4023
4157
  // src/commands/status.ts
4024
- var log9 = (msg) => {
4158
+ var log10 = (msg) => {
4025
4159
  process.stdout.write(msg + "\n");
4026
4160
  };
4027
4161
  var STATUS_MARK = {
@@ -4049,10 +4183,10 @@ async function describeDisk(path = ".") {
4049
4183
  }
4050
4184
  }
4051
4185
  function describeConfig() {
4052
- if (!existsSync7(CONFIG_PATH)) return t34("cli.status.config_absent");
4053
- loadConfig3();
4186
+ if (!existsSync7(CONFIG_PATH)) return t35("cli.status.config_absent");
4187
+ loadConfig4();
4054
4188
  const n = getConfigIssues().length;
4055
- return n === 0 ? t34("cli.status.config_present") : t34("cli.status.config_present_with_issues", { count: n });
4189
+ return n === 0 ? t35("cli.status.config_present") : t35("cli.status.config_present_with_issues", { count: n });
4056
4190
  }
4057
4191
  async function describeSecretBackend() {
4058
4192
  try {
@@ -4060,18 +4194,18 @@ async function describeSecretBackend() {
4060
4194
  const store = await createSecretStore();
4061
4195
  return store.encrypted ? store.detail : `\u26A0 ${store.detail}`;
4062
4196
  } catch (err2) {
4063
- return t34("cli.status.secret_probe_failed", {
4197
+ return t35("cli.status.secret_probe_failed", {
4064
4198
  message: err2 instanceof Error ? err2.message : String(err2)
4065
4199
  });
4066
4200
  }
4067
4201
  }
4068
4202
  function workspaceLines(rt) {
4069
- const lines = [` ${t34("cli.doctor.workspace_root", { root: rt.workspace.root })}`];
4203
+ const lines = [` ${t35("cli.doctor.workspace_root", { root: rt.workspace.root })}`];
4070
4204
  lines.push(
4071
- ` ${rt.trusted ? t34("cli.doctor.workspace_trusted") : t34("cli.doctor.workspace_untrusted")}`
4205
+ ` ${rt.trusted ? t35("cli.doctor.workspace_trusted") : t35("cli.doctor.workspace_untrusted")}`
4072
4206
  );
4073
4207
  lines.push(
4074
- ` ${rt.workspace.extra.length === 0 ? t34("cli.doctor.workspace_no_extra") : t34("cli.doctor.workspace_extra", { count: rt.workspace.extra.length })}`
4208
+ ` ${rt.workspace.extra.length === 0 ? t35("cli.doctor.workspace_no_extra") : t35("cli.doctor.workspace_extra", { count: rt.workspace.extra.length })}`
4075
4209
  );
4076
4210
  for (const dir of rt.workspace.extra) lines.push(` \xB7 ${dir}`);
4077
4211
  return lines;
@@ -4079,94 +4213,94 @@ function workspaceLines(rt) {
4079
4213
  function sandboxLines(cwd, sandbox) {
4080
4214
  const iso = describeIsolation();
4081
4215
  const lines = [`
4082
- ${t34("cli.doctor.sandbox_head")}`];
4216
+ ${t35("cli.doctor.sandbox_head")}`];
4083
4217
  if (iso.backend === "none") {
4084
4218
  lines.push(` ${STATUS_MARK.skipped} ${iso.detail}`);
4085
4219
  lines.push(
4086
- ` ${STATUS_MARK.warn} ${t34(
4220
+ ` ${STATUS_MARK.warn} ${t35(
4087
4221
  iso.reason === "platform-unsupported" ? "cli.doctor.sandbox_absent_by_design" : "cli.doctor.sandbox_absent_tools"
4088
4222
  )}`
4089
4223
  );
4090
4224
  return lines;
4091
4225
  }
4092
4226
  lines.push(
4093
- ` ${STATUS_MARK.ok} ${t34("cli.doctor.sandbox_backend", { backend: iso.backend, platform: iso.platform })}`
4227
+ ` ${STATUS_MARK.ok} ${t35("cli.doctor.sandbox_backend", { backend: iso.backend, platform: iso.platform })}`
4094
4228
  );
4095
- lines.push(` \xB7 ${t34("cli.doctor.sandbox_code_exec", { detail: iso.detail })}`);
4229
+ lines.push(` \xB7 ${t35("cli.doctor.sandbox_code_exec", { detail: iso.detail })}`);
4096
4230
  const probe = (mode) => confine("/bin/sh", ["-c", "true"], { mode, workspaceRoot: cwd, allowNetwork: true });
4097
4231
  for (const mode of ["workspace-write", "read-only"]) {
4098
4232
  const c = probe(mode);
4099
4233
  if (!c.confined) continue;
4100
- lines.push(` \xB7 ${t34("cli.doctor.sandbox_terminal", { mode, enforcement: c.enforcement })}`);
4101
- if (c.enforcement === "partial") lines.push(` ${t34("cli.doctor.sandbox_partial_devnull")}`);
4234
+ lines.push(` \xB7 ${t35("cli.doctor.sandbox_terminal", { mode, enforcement: c.enforcement })}`);
4235
+ if (c.enforcement === "partial") lines.push(` ${t35("cli.doctor.sandbox_partial_devnull")}`);
4102
4236
  }
4103
4237
  const writable = probe("workspace-write");
4104
4238
  if (writable.confined) {
4105
- lines.push(` \xB7 ${t34("cli.doctor.sandbox_writable")}`);
4239
+ lines.push(` \xB7 ${t35("cli.doctor.sandbox_writable")}`);
4106
4240
  for (const dir of writable.writableDirs) lines.push(` \xB7 ${dir}`);
4107
4241
  }
4108
4242
  lines.push(
4109
- sandbox?.terminal === false ? ` ${STATUS_MARK.warn} ${t34("cli.doctor.sandbox_switch_off")}` : ` ${STATUS_MARK.ok} ${t34("cli.doctor.sandbox_switch_on")}`
4243
+ sandbox?.terminal === false ? ` ${STATUS_MARK.warn} ${t35("cli.doctor.sandbox_switch_off")}` : ` ${STATUS_MARK.ok} ${t35("cli.doctor.sandbox_switch_on")}`
4110
4244
  );
4111
- lines.push(` \xB7 ${t34("cli.doctor.sandbox_covers", { tools: SANDBOX_COVERS.join(", ") })}`);
4245
+ lines.push(` \xB7 ${t35("cli.doctor.sandbox_covers", { tools: SANDBOX_COVERS.join(", ") })}`);
4112
4246
  lines.push(
4113
- SANDBOX_EXCLUDES.length === 0 ? ` ${STATUS_MARK.ok} ${t34("cli.doctor.sandbox_excludes_none")}` : ` ${STATUS_MARK.warn} ${t34("cli.doctor.sandbox_excludes", { tools: SANDBOX_EXCLUDES.join(", ") })}`
4247
+ SANDBOX_EXCLUDES.length === 0 ? ` ${STATUS_MARK.ok} ${t35("cli.doctor.sandbox_excludes_none")}` : ` ${STATUS_MARK.warn} ${t35("cli.doctor.sandbox_excludes", { tools: SANDBOX_EXCLUDES.join(", ") })}`
4114
4248
  );
4115
4249
  return lines;
4116
4250
  }
4117
4251
  function ftsLines(health) {
4118
4252
  const lines = [`
4119
- ${t34("cli.doctor.fts_head")}`];
4253
+ ${t35("cli.doctor.fts_head")}`];
4120
4254
  const indexed = health.tables.map((tb) => `${tb.table} ${tb.rows}`).join(" \xB7 ");
4121
- lines.push(` \xB7 ${t34("cli.doctor.fts_rows", { messages: health.messages, indexed })}`);
4255
+ lines.push(` \xB7 ${t35("cli.doctor.fts_rows", { messages: health.messages, indexed })}`);
4122
4256
  const behind = health.tables.filter((tb) => tb.rows !== health.messages);
4123
4257
  lines.push(
4124
- behind.length === 0 ? ` ${STATUS_MARK.ok} ${t34("cli.doctor.fts_in_sync")}` : (
4125
- ` ${STATUS_MARK.warn} ${t34("cli.doctor.fts_out_of_sync", {
4258
+ behind.length === 0 ? ` ${STATUS_MARK.ok} ${t35("cli.doctor.fts_in_sync")}` : (
4259
+ ` ${STATUS_MARK.warn} ${t35("cli.doctor.fts_out_of_sync", {
4126
4260
  tables: behind.map((tb) => `${tb.table} (${tb.rows - health.messages})`).join(", ")
4127
4261
  })}`
4128
4262
  )
4129
4263
  );
4130
4264
  lines.push(
4131
- health.missingTriggers.length === 0 ? ` ${STATUS_MARK.ok} ${t34("cli.doctor.fts_triggers_ok")}` : ` ${STATUS_MARK.failed} ${t34("cli.doctor.fts_triggers_missing", {
4265
+ health.missingTriggers.length === 0 ? ` ${STATUS_MARK.ok} ${t35("cli.doctor.fts_triggers_ok")}` : ` ${STATUS_MARK.failed} ${t35("cli.doctor.fts_triggers_missing", {
4132
4266
  triggers: health.missingTriggers.join(", ")
4133
4267
  })}`
4134
4268
  );
4135
4269
  for (const tb of health.tables) {
4136
4270
  if (tb.error !== null) {
4137
4271
  lines.push(
4138
- ` ${STATUS_MARK.failed} ${t34("cli.doctor.fts_corrupt", { table: tb.table, detail: tb.error })}`
4272
+ ` ${STATUS_MARK.failed} ${t35("cli.doctor.fts_corrupt", { table: tb.table, detail: tb.error })}`
4139
4273
  );
4140
4274
  }
4141
4275
  if (tb.drift !== null) {
4142
4276
  lines.push(
4143
- ` ${STATUS_MARK.warn} ${t34("cli.doctor.fts_drift", { table: tb.table, detail: tb.drift })}`
4277
+ ` ${STATUS_MARK.warn} ${t35("cli.doctor.fts_drift", { table: tb.table, detail: tb.drift })}`
4144
4278
  );
4145
4279
  }
4146
4280
  }
4147
4281
  if (health.tables.some((tb) => !tb.external)) {
4148
- lines.push(` ${STATUS_MARK.warn} ${t34("cli.doctor.fts_legacy_schema")}`);
4282
+ lines.push(` ${STATUS_MARK.warn} ${t35("cli.doctor.fts_legacy_schema")}`);
4149
4283
  }
4150
4284
  if (health.indexBytes !== void 0) {
4151
- lines.push(` \xB7 ${t34("cli.doctor.fts_size", { size: formatBytes(health.indexBytes) })}`);
4285
+ lines.push(` \xB7 ${t35("cli.doctor.fts_size", { size: formatBytes(health.indexBytes) })}`);
4152
4286
  }
4153
4287
  if (health.space?.fileBytes !== void 0) {
4154
4288
  lines.push(
4155
- ` \xB7 ${t34("cli.doctor.fts_space", {
4289
+ ` \xB7 ${t35("cli.doctor.fts_space", {
4156
4290
  file: formatBytes(health.space.fileBytes),
4157
4291
  free: formatBytes(health.space.freeBytes)
4158
4292
  })}`
4159
4293
  );
4160
- lines.push(` \xB7 ${t34("cli.doctor.fts_reclaim_hint")}`);
4294
+ lines.push(` \xB7 ${t35("cli.doctor.fts_reclaim_hint")}`);
4161
4295
  }
4162
4296
  return lines;
4163
4297
  }
4164
4298
  function reclaimLines(report) {
4165
4299
  const lines = [`
4166
- ${t34("cli.doctor.reclaim_head")}`];
4300
+ ${t35("cli.doctor.reclaim_head")}`];
4167
4301
  const secs = (ms) => `${(ms / 1e3).toFixed(1)}s`;
4168
4302
  lines.push(
4169
- ` ${STATUS_MARK.ok} ${t34("cli.doctor.reclaim_optimize", {
4303
+ ` ${STATUS_MARK.ok} ${t35("cli.doctor.reclaim_optimize", {
4170
4304
  before: formatBytes(report.before.freeBytes),
4171
4305
  after: formatBytes(report.afterOptimize.freeBytes),
4172
4306
  ms: secs(report.optimizeMs)
@@ -4174,7 +4308,7 @@ ${t34("cli.doctor.reclaim_head")}`];
4174
4308
  );
4175
4309
  if (report.vacuumed) {
4176
4310
  lines.push(
4177
- ` ${STATUS_MARK.ok} ${t34("cli.doctor.reclaim_vacuum", {
4311
+ ` ${STATUS_MARK.ok} ${t35("cli.doctor.reclaim_vacuum", {
4178
4312
  before: formatBytes(report.before.pageBytes),
4179
4313
  after: formatBytes(report.after.pageBytes),
4180
4314
  ms: secs(report.vacuumMs)
@@ -4182,14 +4316,14 @@ ${t34("cli.doctor.reclaim_head")}`];
4182
4316
  );
4183
4317
  const saved = report.before.pageBytes - report.after.pageBytes;
4184
4318
  lines.push(
4185
- ` ${STATUS_MARK.ok} ${t34("cli.doctor.reclaim_total", {
4319
+ ` ${STATUS_MARK.ok} ${t35("cli.doctor.reclaim_total", {
4186
4320
  saved: formatBytes(saved),
4187
4321
  pct: `${(saved / Math.max(1, report.before.pageBytes) * 100).toFixed(1)}%`
4188
4322
  })}`
4189
4323
  );
4190
4324
  } else if (report.vacuumError !== null) {
4191
4325
  lines.push(
4192
- ` ${STATUS_MARK.warn} ${t34("cli.doctor.reclaim_vacuum_skipped", {
4326
+ ` ${STATUS_MARK.warn} ${t35("cli.doctor.reclaim_vacuum_skipped", {
4193
4327
  detail: report.vacuumError
4194
4328
  })}`
4195
4329
  );
@@ -4209,17 +4343,17 @@ function hookLines(rt) {
4209
4343
  const { sources } = rt.hook;
4210
4344
  if (sources.length === 0) return [];
4211
4345
  const lines = [`
4212
- ${t34("cli.doctor.hook_head")}`];
4346
+ ${t35("cli.doctor.hook_head")}`];
4213
4347
  for (const source of sources) {
4214
- const label = t34(HOOK_SOURCE_LABEL[source.kind]);
4348
+ const label = t35(HOOK_SOURCE_LABEL[source.kind]);
4215
4349
  if (source.skipped) {
4216
4350
  lines.push(` ${STATUS_MARK.skipped} ${label}: ${source.path}`);
4217
- lines.push(` ${t34("cli.doctor.hook_skipped")}`);
4351
+ lines.push(` ${t35("cli.doctor.hook_skipped")}`);
4218
4352
  continue;
4219
4353
  }
4220
4354
  const name = source.plugin === void 0 ? label : `${label} ${source.plugin}`;
4221
4355
  lines.push(
4222
- ` ${STATUS_MARK.ok} ${name}: ${source.path}${t34("cli.doctor.hook_count", {
4356
+ ` ${STATUS_MARK.ok} ${name}: ${source.path}${t35("cli.doctor.hook_count", {
4223
4357
  n: source.count
4224
4358
  })}`
4225
4359
  );
@@ -4233,65 +4367,65 @@ var JOB_KIND_LABEL = {
4233
4367
  };
4234
4368
  function jobLines(jobs) {
4235
4369
  const lines = [`
4236
- ${t34("cli.doctor.jobs_head")}`];
4370
+ ${t35("cli.doctor.jobs_head")}`];
4237
4371
  const running = jobs.filter((job) => job.status === "running");
4238
4372
  if (running.length === 0) {
4239
- lines.push(` ${STATUS_MARK.ok} ${t34("cli.doctor.jobs_none")}`);
4373
+ lines.push(` ${STATUS_MARK.ok} ${t35("cli.doctor.jobs_none")}`);
4240
4374
  return lines;
4241
4375
  }
4242
- lines.push(` ${STATUS_MARK.warn} ${t34("cli.doctor.jobs_running", { n: running.length })}`);
4376
+ lines.push(` ${STATUS_MARK.warn} ${t35("cli.doctor.jobs_running", { n: running.length })}`);
4243
4377
  for (const job of running) {
4244
4378
  lines.push(
4245
- ` \xB7 ${t34("cli.doctor.jobs_line", {
4246
- kind: t34(JOB_KIND_LABEL[job.kind]),
4379
+ ` \xB7 ${t35("cli.doctor.jobs_line", {
4380
+ kind: t35(JOB_KIND_LABEL[job.kind]),
4247
4381
  id: job.id,
4248
4382
  label: job.label
4249
4383
  })}`
4250
4384
  );
4251
4385
  }
4252
- lines.push(` \xB7 ${t34("cli.doctor.jobs_lifetime")}`);
4386
+ lines.push(` \xB7 ${t35("cli.doctor.jobs_lifetime")}`);
4253
4387
  return lines;
4254
4388
  }
4255
4389
  function terminalLines(result, terminal) {
4256
4390
  const head = `
4257
- ${t34("cli.doctor.terminal_head")}`;
4391
+ ${t35("cli.doctor.terminal_head")}`;
4258
4392
  if (!result.ok) {
4259
4393
  if (result.failure.kind === "no-tty") {
4260
4394
  return [
4261
4395
  head,
4262
- ` ${STATUS_MARK.warn} ${t34("cli.doctor.terminal_no_tty")}`,
4263
- ` \xB7 ${t34("cli.doctor.terminal_alternatives")}`
4396
+ ` ${STATUS_MARK.warn} ${t35("cli.doctor.terminal_no_tty")}`,
4397
+ ` \xB7 ${t35("cli.doctor.terminal_alternatives")}`
4264
4398
  ];
4265
4399
  }
4266
4400
  return [
4267
4401
  head,
4268
- ` ${STATUS_MARK.warn} ${t34("cli.doctor.terminal_timeout", { n: result.failure.timeoutMs / 1e3 })}`
4402
+ ` ${STATUS_MARK.warn} ${t35("cli.doctor.terminal_timeout", { n: result.failure.timeoutMs / 1e3 })}`
4269
4403
  ];
4270
4404
  }
4271
4405
  switch (result.sample.kind) {
4272
4406
  case "shift-enter":
4273
- return [head, ` ${STATUS_MARK.ok} ${t34("cli.doctor.terminal_shift_enter")}`];
4407
+ return [head, ` ${STATUS_MARK.ok} ${t35("cli.doctor.terminal_shift_enter")}`];
4274
4408
  case "enter-only":
4275
4409
  if (terminal?.kind === "apple-terminal") {
4276
4410
  return [
4277
4411
  head,
4278
- ` ${STATUS_MARK.warn} ${t34("cli.doctor.terminal_apple")}`,
4279
- ` \xB7 ${t34("cli.doctor.terminal_alternatives")}`
4412
+ ` ${STATUS_MARK.warn} ${t35("cli.doctor.terminal_apple")}`,
4413
+ ` \xB7 ${t35("cli.doctor.terminal_alternatives")}`
4280
4414
  ];
4281
4415
  }
4282
4416
  return [
4283
4417
  head,
4284
- ` ${STATUS_MARK.warn} ${t34("cli.doctor.terminal_enter_only")}`,
4285
- ` \xB7 ${t34("cli.doctor.terminal_alternatives")}`,
4286
- ` \xB7 ${t34("cli.doctor.terminal_setup_hint")}`
4418
+ ` ${STATUS_MARK.warn} ${t35("cli.doctor.terminal_enter_only")}`,
4419
+ ` \xB7 ${t35("cli.doctor.terminal_alternatives")}`,
4420
+ ` \xB7 ${t35("cli.doctor.terminal_setup_hint")}`
4287
4421
  ];
4288
4422
  case "other":
4289
4423
  return [
4290
4424
  head,
4291
- ` ${STATUS_MARK.warn} ${t34("cli.doctor.terminal_other", { hex: result.sample.hex })}`
4425
+ ` ${STATUS_MARK.warn} ${t35("cli.doctor.terminal_other", { hex: result.sample.hex })}`
4292
4426
  ];
4293
4427
  case "interrupted":
4294
- return [head, ` \xB7 ${t34("cli.doctor.terminal_interrupted")}`];
4428
+ return [head, ` \xB7 ${t35("cli.doctor.terminal_interrupted")}`];
4295
4429
  }
4296
4430
  }
4297
4431
  async function statusLineLines(config, cwd) {
@@ -4299,95 +4433,96 @@ async function statusLineLines(config, cwd) {
4299
4433
  if (!probe) return [];
4300
4434
  return [
4301
4435
  `
4302
- ${t34("cli.doctor.status_line_head")}`,
4303
- ` ${t34("cli.doctor.status_line_command", { command: probe.command })}`,
4304
- ` ${probe.ok ? t34("cli.doctor.status_line_ok", { detail: probe.detail }) : t34("cli.doctor.status_line_broken", { detail: probe.detail })}`
4436
+ ${t35("cli.doctor.status_line_head")}`,
4437
+ ` ${t35("cli.doctor.status_line_command", { command: probe.command })}`,
4438
+ ` ${probe.ok ? t35("cli.doctor.status_line_ok", { detail: probe.detail }) : t35("cli.doctor.status_line_broken", { detail: probe.detail })}`
4305
4439
  ];
4306
4440
  }
4307
4441
  function registerStatusCommands(program2) {
4308
- program2.command("status").description(t34("cli.status.cmd_root")).action(async () => {
4309
- log9(
4442
+ program2.command("status").description(t35("cli.status.cmd_root")).action(async () => {
4443
+ log10(
4310
4444
  [
4311
- t34("cli.status.version", { version: VERSION }),
4445
+ t35("cli.status.version", { version: VERSION }),
4312
4446
  `Node: ${process.version} (${process.platform}/${process.arch})`,
4313
- t34("cli.status.home", { path: EPOCH_HOME }),
4447
+ t35("cli.status.home", { path: EPOCH_HOME }),
4314
4448
  `Profile: ${resolveProfile()}`,
4315
- t34("cli.status.credentials", {
4316
- state: hasCredentials() ? t34("cli.status.credentials_set") : t34("cli.status.credentials_unset")
4449
+ t35("cli.status.credentials", {
4450
+ state: hasCredentials() ? t35("cli.status.credentials_set") : t35("cli.status.credentials_unset")
4317
4451
  }),
4318
- t34("cli.status.secret_backend", { detail: await describeSecretBackend() }),
4452
+ t35("cli.status.secret_backend", { detail: await describeSecretBackend() }),
4319
4453
  `config.yaml: ${describeConfig()}`,
4320
- `.env: ${existsSync7(ENV_PATH) ? t34("cli.status.env_present") : t34("cli.status.env_absent")}`
4454
+ `.env: ${existsSync7(ENV_PATH) ? t35("cli.status.env_present") : t35("cli.status.env_absent")}`
4321
4455
  ].join("\n")
4322
4456
  );
4323
4457
  });
4324
- program2.command("doctor").description(t34("cli.doctor.cmd_root")).option("--reclaim", t34("cli.doctor.reclaim_opt")).action(async (opts) => {
4325
- log9(t34("cli.doctor.node", { version: process.version }));
4458
+ program2.command("doctor").description(t35("cli.doctor.cmd_root")).option("--reclaim", t35("cli.doctor.reclaim_opt")).action(async (opts) => {
4459
+ log10(t35("cli.doctor.node", { version: process.version }));
4326
4460
  const avail = await describeDisk();
4327
- if (avail) log9(t34("cli.doctor.disk", { avail }));
4328
- log9(`${hasCredentials() ? "\u2713" : "\u25CB"} ${t34("cli.doctor.credentials")}`);
4329
- const configIssues = existsSync7(CONFIG_PATH) ? (loadConfig3(), getConfigIssues()) : [];
4461
+ if (avail) log10(t35("cli.doctor.disk", { avail }));
4462
+ log10(`${hasCredentials() ? "\u2713" : "\u25CB"} ${t35("cli.doctor.credentials")}`);
4463
+ const configIssues = existsSync7(CONFIG_PATH) ? (loadConfig4(), getConfigIssues()) : [];
4330
4464
  const configMark = !existsSync7(CONFIG_PATH) ? "\u25CB" : configIssues.length > 0 ? "\u26A0" : "\u2713";
4331
- log9(`${configMark} config: ${CONFIG_PATH}`);
4465
+ log10(`${configMark} config: ${CONFIG_PATH}`);
4332
4466
  try {
4333
4467
  const { buildRuntime: buildRuntime4 } = await import("@epoch-agent/runtime");
4334
4468
  const rt = await buildRuntime4({ installSignalHandlers: true });
4335
- log9(`
4336
- ${t34("cli.doctor.workspace_head")}`);
4337
- for (const line of workspaceLines(rt)) log9(line);
4338
- for (const line of sandboxLines(rt.workspace.root, rt.config.sandbox)) log9(line);
4339
- for (const line of hookLines(rt)) log9(line);
4340
- for (const line of jobLines(allJobs().map((j) => j.info))) log9(line);
4469
+ log10(`
4470
+ ${t35("cli.doctor.workspace_head")}`);
4471
+ for (const line of workspaceLines(rt)) log10(line);
4472
+ for (const line of sandboxLines(rt.workspace.root, rt.config.sandbox)) log10(line);
4473
+ for (const line of hookLines(rt)) log10(line);
4474
+ for (const line of jobLines(allJobs().map((j) => j.info))) log10(line);
4475
+ const { classifyTerminal, probeShiftEnter } = await import("@epoch-agent/tui");
4341
4476
  for (const line of terminalLines(
4342
- await probeShiftEnter({ prompt: t34("cli.doctor.terminal_prompt"), timeoutMs: 8e3 }),
4477
+ await probeShiftEnter({ prompt: t35("cli.doctor.terminal_prompt"), timeoutMs: 8e3 }),
4343
4478
  classifyTerminal(process.env)
4344
4479
  ))
4345
- log9(line);
4346
- for (const line of await statusLineLines(rt.config, process.cwd())) log9(line);
4480
+ log10(line);
4481
+ for (const line of await statusLineLines(rt.config, process.cwd())) log10(line);
4347
4482
  if (rt.sessionStore) {
4348
4483
  try {
4349
- for (const line of ftsLines(rt.sessionStore.ftsHealth())) log9(line);
4484
+ for (const line of ftsLines(rt.sessionStore.ftsHealth())) log10(line);
4350
4485
  } catch (err2) {
4351
- log9(`
4352
- ${t34("cli.doctor.fts_head")}`);
4353
- log9(
4354
- ` ${STATUS_MARK.warn} ${t34("cli.doctor.fts_probe_failed", {
4486
+ log10(`
4487
+ ${t35("cli.doctor.fts_head")}`);
4488
+ log10(
4489
+ ` ${STATUS_MARK.warn} ${t35("cli.doctor.fts_probe_failed", {
4355
4490
  detail: err2 instanceof Error ? err2.message : String(err2)
4356
4491
  })}`
4357
4492
  );
4358
4493
  }
4359
4494
  if (opts.reclaim) {
4360
4495
  try {
4361
- for (const line of reclaimLines(rt.sessionStore.reclaimFts())) log9(line);
4496
+ for (const line of reclaimLines(rt.sessionStore.reclaimFts())) log10(line);
4362
4497
  } catch (err2) {
4363
- log9(`
4364
- ${t34("cli.doctor.reclaim_head")}`);
4365
- log9(
4366
- ` ${STATUS_MARK.failed} ${t34("cli.doctor.reclaim_failed", {
4498
+ log10(`
4499
+ ${t35("cli.doctor.reclaim_head")}`);
4500
+ log10(
4501
+ ` ${STATUS_MARK.failed} ${t35("cli.doctor.reclaim_failed", {
4367
4502
  detail: err2 instanceof Error ? err2.message : String(err2)
4368
4503
  })}`
4369
4504
  );
4370
4505
  }
4371
4506
  }
4372
4507
  }
4373
- log9(`
4374
- ${t34("cli.doctor.modules_head")}`);
4508
+ log10(`
4509
+ ${t35("cli.doctor.modules_head")}`);
4375
4510
  const order = { failed: 0, warn: 1, skipped: 2, ok: 3 };
4376
4511
  const sorted = [...rt.diagnosticList].sort(
4377
4512
  (a, b) => (order[a.status] ?? 9) - (order[b.status] ?? 9)
4378
4513
  );
4379
- for (const d of sorted) log9(` ${STATUS_MARK[d.status]} ${d.module}: ${d.detail}`);
4514
+ for (const d of sorted) log10(` ${STATUS_MARK[d.status]} ${d.module}: ${d.detail}`);
4380
4515
  await rt.dispose();
4381
4516
  if (hasFailure(rt.diagnosticList)) {
4382
4517
  const bad = rt.diagnosticList.filter((d) => d.status === "failed").length;
4383
- log9(`
4384
- ${t34("cli.doctor.modules_failed", { count: bad })}`);
4518
+ log10(`
4519
+ ${t35("cli.doctor.modules_failed", { count: bad })}`);
4385
4520
  process.exitCode = EXIT_CODES.FAILURE;
4386
4521
  }
4387
4522
  } catch (err2) {
4388
- log9(
4523
+ log10(
4389
4524
  `
4390
- ${t34("cli.doctor.build_failed", {
4525
+ ${t35("cli.doctor.build_failed", {
4391
4526
  message: err2 instanceof Error ? err2.message : String(err2)
4392
4527
  })}`
4393
4528
  );
@@ -4397,21 +4532,21 @@ ${t34("cli.doctor.build_failed", {
4397
4532
  // src/commands/trust.ts
4398
4533
  import { existsSync as existsSync8, realpathSync as realpathSync3 } from "fs";
4399
4534
  import { resolve as resolve3 } from "path";
4400
- import { loadConfig as loadConfig4, TrustManager as TrustManager3 } from "@epoch-agent/core";
4401
- import { t as t35, trustPath as trustPath3, uiDateLocale as uiDateLocale4 } from "@epoch-agent/infra";
4402
- var log10 = (msg) => process.stdout.write(msg + "\n");
4535
+ import { loadConfig as loadConfig5, TrustManager as TrustManager3 } from "@epoch-agent/core";
4536
+ import { t as t36, trustPath as trustPath3, uiDateLocale as uiDateLocale4 } from "@epoch-agent/infra";
4537
+ var log11 = (msg) => process.stdout.write(msg + "\n");
4403
4538
  var warn3 = (msg) => process.stderr.write(msg + "\n");
4404
4539
  function scopeLabel(scope) {
4405
- return scope === "directory-tree" ? t35("trust.scope_tree") : t35("trust.scope_dir");
4540
+ return scope === "directory-tree" ? t36("trust.scope_tree") : t36("trust.scope_dir");
4406
4541
  }
4407
4542
  function levelLabel(level) {
4408
4543
  switch (level) {
4409
4544
  case "trusted":
4410
- return t35("trust.level_trusted");
4545
+ return t36("trust.level_trusted");
4411
4546
  case "untrusted":
4412
- return t35("trust.level_untrusted");
4547
+ return t36("trust.level_untrusted");
4413
4548
  case "unknown":
4414
- return t35("trust.level_unknown");
4549
+ return t36("trust.level_unknown");
4415
4550
  }
4416
4551
  }
4417
4552
  function physicalPath(input2) {
@@ -4424,63 +4559,63 @@ function physicalPath(input2) {
4424
4559
  }
4425
4560
  }
4426
4561
  function registerTrustCommand(program2) {
4427
- const cmd = program2.command("trust").description(t35("trust.cmd_root"));
4428
- cmd.command("list", { isDefault: true }).description(t35("trust.cmd_list")).action(() => withTrust((tm) => printList3(tm)));
4429
- cmd.command("add").description(t35("trust.cmd_add")).argument("[path]", t35("trust.arg_path_default")).option("--tree", t35("trust.opt_tree_add")).action((path, opts) => {
4562
+ const cmd = program2.command("trust").description(t36("trust.cmd_root"));
4563
+ cmd.command("list", { isDefault: true }).description(t36("trust.cmd_list")).action(() => withTrust((tm) => printList3(tm)));
4564
+ cmd.command("add").description(t36("trust.cmd_add")).argument("[path]", t36("trust.arg_path_default")).option("--tree", t36("trust.opt_tree_add")).action((path, opts) => {
4430
4565
  withTrust((tm) => {
4431
4566
  const dir = physicalPath(path ?? process.cwd());
4432
4567
  tm.record(dir, "trusted", opts.tree ? "directory-tree" : "directory");
4433
- log10(
4434
- `\u2713 ${t35("trust.added", {
4568
+ log11(
4569
+ `\u2713 ${t36("trust.added", {
4435
4570
  dir,
4436
4571
  scope: scopeLabel(opts.tree ? "directory-tree" : "directory")
4437
4572
  })}`
4438
4573
  );
4439
4574
  });
4440
4575
  });
4441
- cmd.command("deny").description(t35("trust.cmd_deny")).argument("[path]", t35("trust.arg_path_default")).option("--tree", t35("trust.opt_tree_deny")).action((path, opts) => {
4576
+ cmd.command("deny").description(t36("trust.cmd_deny")).argument("[path]", t36("trust.arg_path_default")).option("--tree", t36("trust.opt_tree_deny")).action((path, opts) => {
4442
4577
  withTrust((tm) => {
4443
4578
  const dir = physicalPath(path ?? process.cwd());
4444
4579
  tm.record(dir, "untrusted", opts.tree ? "directory-tree" : "directory");
4445
- log10(
4446
- `\u2717 ${t35("trust.denied", {
4580
+ log11(
4581
+ `\u2717 ${t36("trust.denied", {
4447
4582
  dir,
4448
4583
  scope: scopeLabel(opts.tree ? "directory-tree" : "directory")
4449
4584
  })}`
4450
4585
  );
4451
4586
  });
4452
4587
  });
4453
- cmd.command("remove").alias("rm").description(t35("trust.cmd_remove")).argument("<path>", t35("trust.arg_path")).action((path) => {
4588
+ cmd.command("remove").alias("rm").description(t36("trust.cmd_remove")).argument("<path>", t36("trust.arg_path")).action((path) => {
4454
4589
  withTrust((tm) => {
4455
4590
  const dir = physicalPath(path);
4456
4591
  if (!tm.list().some((r) => resolve3(r.path) === dir)) {
4457
- warn3(t35("trust.no_record", { dir }));
4592
+ warn3(t36("trust.no_record", { dir }));
4458
4593
  process.exit(1);
4459
4594
  }
4460
4595
  tm.revoke(dir);
4461
- log10(t35("trust.removed", { dir, level: levelLabel(tm.check(dir)) }));
4596
+ log11(t36("trust.removed", { dir, level: levelLabel(tm.check(dir)) }));
4462
4597
  });
4463
4598
  });
4464
4599
  }
4465
4600
  function printList3(tm) {
4466
- if (loadConfig4().trust?.enabled === false) {
4467
- warn3(t35("trust.gate_off"));
4601
+ if (loadConfig5().trust?.enabled === false) {
4602
+ warn3(t36("trust.gate_off"));
4468
4603
  }
4469
- log10(t35("trust.list_head", { path: trustPath3(EPOCH_HOME) }));
4604
+ log11(t36("trust.list_head", { path: trustPath3(EPOCH_HOME) }));
4470
4605
  const records = [...tm.list()].sort((a, b) => a.path.localeCompare(b.path));
4471
4606
  if (records.length === 0) {
4472
- log10(t35("trust.list_empty"));
4607
+ log11(t36("trust.list_empty"));
4473
4608
  }
4474
4609
  for (const r of records) {
4475
4610
  const mark = r.level === "trusted" ? "\u2713" : "\u2717";
4476
- const when = r.decidedAt ? new Date(r.decidedAt).toLocaleString(uiDateLocale4()) : t35("trust.when_unknown");
4477
- log10(` ${mark} ${r.path} [${scopeLabel(r.scope)}] ${when}`);
4611
+ const when = r.decidedAt ? new Date(r.decidedAt).toLocaleString(uiDateLocale4()) : t36("trust.when_unknown");
4612
+ log11(` ${mark} ${r.path} [${scopeLabel(r.scope)}] ${when}`);
4478
4613
  }
4479
4614
  const cwd = process.cwd();
4480
- log10(
4615
+ log11(
4481
4616
  `
4482
- ${t35("trust.cwd_line", { cwd })}
4483
- ${t35("trust.cwd_verdict", { level: levelLabel(tm.check(cwd)) })}`
4617
+ ${t36("trust.cwd_line", { cwd })}
4618
+ ${t36("trust.cwd_verdict", { level: levelLabel(tm.check(cwd)) })}`
4484
4619
  );
4485
4620
  }
4486
4621
  function withTrust(fn) {
@@ -4489,46 +4624,46 @@ function withTrust(fn) {
4489
4624
  try {
4490
4625
  fn(tm);
4491
4626
  } catch (err2) {
4492
- warn3(t35("trust.error", { message: err2 instanceof Error ? err2.message : String(err2) }));
4627
+ warn3(t36("trust.error", { message: err2 instanceof Error ? err2.message : String(err2) }));
4493
4628
  process.exit(1);
4494
4629
  }
4495
4630
  }
4496
4631
  // src/commands/upgrade.ts
4497
- import { t as t36 } from "@epoch-agent/infra";
4498
- var log11 = (msg) => process.stdout.write(`${msg}
4632
+ import { t as t37 } from "@epoch-agent/infra";
4633
+ var log12 = (msg) => process.stdout.write(`${msg}
4499
4634
  `);
4500
4635
  function registerUpgradeCommand(program2) {
4501
- program2.command("upgrade").description(t36("upgrade.cmd_root")).action(async () => {
4636
+ program2.command("upgrade").description(t37("upgrade.cmd_root")).action(async () => {
4502
4637
  const self = selfPackage();
4503
4638
  const info = getInstallationInfo(self.name);
4504
- log11(t36("upgrade.current", { version: self.version }));
4505
- log11(
4506
- t36("upgrade.installed_via", {
4639
+ log12(t37("upgrade.current", { version: self.version }));
4640
+ log12(
4641
+ t37("upgrade.installed_via", {
4507
4642
  manager: info.packageManager,
4508
- global: info.isGlobal ? t36("installation.global_suffix") : "",
4643
+ global: info.isGlobal ? t37("installation.global_suffix") : "",
4509
4644
  note: info.note
4510
4645
  })
4511
4646
  );
4512
4647
  const notice = isUpdateCheckDisabled() ? readUpdateNotice() : await refreshUpdateCache({ ttlMs: 0 }).catch(() => null);
4513
4648
  if (notice) {
4514
- log11(`
4515
- ${t36("upgrade.available", { current: notice.current, latest: notice.latest })}`);
4516
- } else log11(`
4517
- ${t36("upgrade.none")}`);
4649
+ log12(`
4650
+ ${t37("upgrade.available", { current: notice.current, latest: notice.latest })}`);
4651
+ } else log12(`
4652
+ ${t37("upgrade.none")}`);
4518
4653
  if (info.updateCommand) {
4519
- log11(`
4520
- ${t36("upgrade.how")}
4654
+ log12(`
4655
+ ${t37("upgrade.how")}
4521
4656
  ${info.updateCommand}`);
4522
- log11(`
4523
- ${t36("upgrade.why_manual")}`);
4657
+ log12(`
4658
+ ${t37("upgrade.why_manual")}`);
4524
4659
  }
4525
4660
  });
4526
- program2.command(UPDATE_CHECK_SUBCOMMAND, { hidden: true }).description(t36("upgrade.cmd_refresh")).action(async () => {
4661
+ program2.command(UPDATE_CHECK_SUBCOMMAND, { hidden: true }).description(t37("upgrade.cmd_refresh")).action(async () => {
4527
4662
  await refreshUpdateCache().catch(() => null);
4528
4663
  });
4529
4664
  }
4530
4665
  // src/commands/web.ts
4531
- import { t as t37 } from "@epoch-agent/infra";
4666
+ import { t as t38 } from "@epoch-agent/infra";
4532
4667
  import { buildRuntime as buildRuntime3 } from "@epoch-agent/runtime";
4533
4668
  import {
4534
4669
  createWebServer,
@@ -4575,7 +4710,7 @@ var err = (msg) => {
4575
4710
  `);
4576
4711
  };
4577
4712
  function registerWebCommand(program2) {
4578
- program2.command("web").description(t37("cli.web.summary")).option("-p, --port <port>", t37("cli.web.opt_port", { port: DEFAULT_WEB_PORT })).option("--host <host>", t37("cli.web.opt_host", { host: DEFAULT_WEB_HOST })).option("--token <token>", t37("cli.web.opt_token")).option("--no-open", t37("cli.web.opt_no_open")).option("--json", t37("cli.web.opt_json")).option("--plugins", t37("cli.web.opt_plugins")).action(async (opts, command) => {
4713
+ program2.command("web").description(t38("cli.web.summary")).option("-p, --port <port>", t38("cli.web.opt_port", { port: DEFAULT_WEB_PORT })).option("--host <host>", t38("cli.web.opt_host", { host: DEFAULT_WEB_HOST })).option("--token <token>", t38("cli.web.opt_token")).option("--no-open", t38("cli.web.opt_no_open")).option("--json", t38("cli.web.opt_json")).option("--plugins", t38("cli.web.opt_plugins")).action(async (opts, command) => {
4579
4714
  await runWeb({ ...opts, json: jsonRequested(opts.json, command.parent?.opts()["json"]) });
4580
4715
  });
4581
4716
  }
@@ -4584,7 +4719,7 @@ function jsonRequested(own, fromProgram) {
4584
4719
  }
4585
4720
  async function runWeb(opts) {
4586
4721
  const port = parsePort2(opts.port);
4587
- if (port === null) return fail(t37("cli.web.err_port", { value: String(opts.port) }));
4722
+ if (port === null) return fail(t38("cli.web.err_port", { value: String(opts.port) }));
4588
4723
  const binding = decideBinding({
4589
4724
  ...opts.host === void 0 ? {} : { host: opts.host },
4590
4725
  ...port === void 0 ? {} : { port },
@@ -4611,8 +4746,8 @@ async function runWeb(opts) {
4611
4746
  if (opts.open && !openInBrowser(server.url)) say(browserFailed());
4612
4747
  installShutdown(server, say);
4613
4748
  }
4614
- var missingWebRoot = () => t37("cli.web.missing_root");
4615
- var browserFailed = () => ` ${t37("cli.web.browser_failed")}`;
4749
+ var missingWebRoot = () => t38("cli.web.missing_root");
4750
+ var browserFailed = () => ` ${t38("cli.web.browser_failed")}`;
4616
4751
  function pluginsOption(plugins) {
4617
4752
  return plugins ? { hostMarketplaces: { sources: [] } } : {};
4618
4753
  }
@@ -4624,7 +4759,7 @@ async function boot(binding, plugins) {
4624
4759
  });
4625
4760
  if (!runtime.session) {
4626
4761
  await runtime.dispose();
4627
- fail(`${t37("cli.web.no_provider")}
4762
+ fail(`${t38("cli.web.no_provider")}
4628
4763
  ${runtime.diagnostics.join("\n")}`);
4629
4764
  return null;
4630
4765
  }
@@ -4646,11 +4781,11 @@ function announceLines(input2) {
4646
4781
  const human = [];
4647
4782
  if (!input2.json) {
4648
4783
  human.push(` Epoch Web http://${input2.host}:${input2.port}`);
4649
- human.push(` ${t37("cli.web.open_this")}
4784
+ human.push(` ${t38("cli.web.open_this")}
4650
4785
  ${input2.url}`);
4651
4786
  }
4652
4787
  if (input2.lanExposed) {
4653
- human.push(` ${t37("cli.web.lan_exposed")}`);
4788
+ human.push(` ${t38("cli.web.lan_exposed")}`);
4654
4789
  }
4655
4790
  if (input2.placeholder) human.push(` \u26A0 ${missingWebRoot()}`);
4656
4791
  if (!input2.json) return { human };
@@ -4668,7 +4803,7 @@ function installShutdown(server, say) {
4668
4803
  if (shuttingDown) process.exit(1);
4669
4804
  shuttingDown = true;
4670
4805
  say(`
4671
- ${t37("cli.web.shutting_down")}`);
4806
+ ${t38("cli.web.shutting_down")}`);
4672
4807
  server.close().then(
4673
4808
  () => process.exit(0),
4674
4809
  () => process.exit(1)
@@ -4687,18 +4822,18 @@ function fail(message) {
4687
4822
  process.exit(1);
4688
4823
  }
4689
4824
  // src/language.ts
4690
- import { loadConfig as loadConfig5 } from "@epoch-agent/core";
4825
+ import { loadConfig as loadConfig6 } from "@epoch-agent/core";
4691
4826
  import { resolveLang, setLang } from "@epoch-agent/infra";
4692
4827
  function applyConfiguredLanguage() {
4693
4828
  try {
4694
- setLang(resolveLang(loadConfig5().display?.language));
4829
+ setLang(resolveLang(loadConfig6().display?.language));
4695
4830
  } catch {
4696
4831
  }
4697
4832
  }
4698
4833
  // src/index.ts
4699
4834
  applyConfiguredLanguage();
4700
4835
  var program = new Command();
4701
- program.name("epoch").description(t38("cli.program_description"));
4836
+ program.name("epoch").description(t39("cli.program_description"));
4702
4837
  registerConfigCommand(program);
4703
4838
  registerMcpCommand(program);
4704
4839
  registerModelCommand(program);
@@ -4707,6 +4842,7 @@ registerSessionsCommand(program);
4707
4842
  registerAgentsCommand(program);
4708
4843
  registerPluginCommand(program);
4709
4844
  registerTrustCommand(program);
4845
+ registerComplianceCommand(program);
4710
4846
  registerScheduleCommand(program);
4711
4847
  registerUpgradeCommand(program);
4712
4848
  registerWebCommand(program);