@epoch-agent/cli 0.2.0 → 0.3.2

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);
@@ -2819,7 +2957,7 @@ async function runOnce(query, opts, resumeId) {
2819
2957
  sessionId: () => rt?.sessionId,
2820
2958
  preauth: (req) => preauthorizedBy(rt?.config.headless, headless, req)
2821
2959
  }) : createInteractiveApproval({ permission: () => rt?.permission }),
2822
- installSignalHandlers: true,
2960
+ installSignalHandlers: false,
2823
2961
  ...approver ? { interactive: true } : {},
2824
2962
  ...headless ? { headless } : {},
2825
2963
  ...resumeId ? { resumeId } : {}
@@ -2829,18 +2967,19 @@ 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
  }
2976
+ installShutdown(runtime);
2838
2977
  try {
2839
2978
  if (format !== "json") reportDiagnostics(runtime.diagnostics, opts.verbose === true);
2840
2979
  if (resumeId) {
2841
2980
  const restored = runtime.session.getHistory().length;
2842
2981
  process.stderr.write(
2843
- `${t21("run_once.resumed", {
2982
+ `${t22("run_once.resumed", {
2844
2983
  id: resumeId.slice(0, SHORT_ID_LEN),
2845
2984
  count: restored
2846
2985
  })}
@@ -2858,12 +2997,23 @@ async function runOnce(query, opts, resumeId) {
2858
2997
  }
2859
2998
  const limited = limitExitCode(outcome, limits);
2860
2999
  if (limited !== void 0 && !process.exitCode) process.exitCode = limited;
2861
- if (outcome.aborted && !process.exitCode) process.exitCode = 130;
3000
+ if (outcome.aborted && !process.exitCode) process.exitCode = INTERRUPTED_EXIT_CODE;
2862
3001
  } finally {
2863
3002
  reportHeadlessAudit(runtime.permission);
2864
3003
  await runtime.dispose();
2865
3004
  }
2866
3005
  }
3006
+ var INTERRUPTED_EXIT_CODE = 130;
3007
+ function installShutdown(runtime) {
3008
+ let shuttingDown = false;
3009
+ const onSignal = (code) => () => {
3010
+ if (shuttingDown) process.exit(EXIT_CODES.FAILURE);
3011
+ shuttingDown = true;
3012
+ void runtime.dispose().finally(() => process.exit(code));
3013
+ };
3014
+ process.on("SIGINT", onSignal(INTERRUPTED_EXIT_CODE));
3015
+ process.on("SIGTERM", onSignal(EXIT_CODES.SUCCESS));
3016
+ }
2867
3017
  async function consume(runtime, query, opts, format, limits, emitter) {
2868
3018
  const out2 = emptyOutcome(runtime.diagnostics);
2869
3019
  const streaming = opts.stream !== false && format === "text";
@@ -2903,7 +3053,7 @@ function collect2(out2, ev, w) {
2903
3053
  } else if (ev.type === "usage") {
2904
3054
  out2.usage = ev.cumulative;
2905
3055
  } else if (ev.type === "error") {
2906
- out2.text = t21("run_once.error_prefix", { message: ev.message });
3056
+ out2.text = t22("run_once.error_prefix", { message: ev.message });
2907
3057
  process.exitCode = EXIT_CODES.FAILURE;
2908
3058
  } else if (ev.type === "finish") {
2909
3059
  out2.finishReason = ev.reason;
@@ -2938,14 +3088,14 @@ function emitOutcome(out2, opts, format, emitter, tasks = []) {
2938
3088
  return;
2939
3089
  }
2940
3090
  if (out2.reasoning) {
2941
- process.stderr.write(`${t21("run_once.reasoning_head")}
3091
+ process.stderr.write(`${t22("run_once.reasoning_head")}
2942
3092
  ${out2.reasoning}
2943
3093
 
2944
3094
  `);
2945
3095
  }
2946
3096
  if (opts.stream === false && out2.text) process.stdout.write(out2.text + "\n");
2947
3097
  if (out2.aborted) process.stderr.write(`
2948
- ${t21("run_once.aborted")}
3098
+ ${t22("run_once.aborted")}
2949
3099
  `);
2950
3100
  if (taskLines) process.stderr.write(taskLines + "\n");
2951
3101
  const summary = formatSummary(out2.usage, out2.budgetExceeded);
@@ -2962,10 +3112,10 @@ function noteworthy(diagnostics, verbose) {
2962
3112
  }
2963
3113
  function formatSummary(usage, budgetExceeded) {
2964
3114
  if (!usage) return "";
2965
- const cached = usage.cacheHitTokens ? t21("run_once.cache_hit", { count: usage.cacheHitTokens }) : "";
3115
+ const cached = usage.cacheHitTokens ? t22("run_once.cache_hit", { count: usage.cacheHitTokens }) : "";
2966
3116
  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") : "";
3117
+ const cost = usage.costUsd === void 0 ? t22("run_once.cost_unknown") : formatUsd(usage.costUsd);
3118
+ const stopped = budgetExceeded ? t22("run_once.budget_reached") : "";
2969
3119
  return `\u2500 ${tokens} \xB7 ${cost}${stopped}`;
2970
3120
  }
2971
3121
  function reportHeadlessAudit(permission) {
@@ -2974,7 +3124,7 @@ function reportHeadlessAudit(permission) {
2974
3124
  for (const e of audit) {
2975
3125
  const vars = { tool: e.toolName, target: e.target, reason: e.reason };
2976
3126
  process.stderr.write(
2977
- `${e.outcome === "granted" ? t21("run_once.audit_granted", vars) : t21("run_once.audit_denied", vars)}
3127
+ `${e.outcome === "granted" ? t22("run_once.audit_granted", vars) : t22("run_once.audit_denied", vars)}
2978
3128
  `
2979
3129
  );
2980
3130
  }
@@ -2984,7 +3134,7 @@ function reportHeadlessAudit(permission) {
2984
3134
  }
2985
3135
  // src/commands/run-overrides.ts
2986
3136
  import { isPermissionLevel as isPermissionLevel2, PERMISSION_LEVELS as PERMISSION_LEVELS2 } from "@epoch-agent/core";
2987
- import { t as t22 } from "@epoch-agent/infra";
3137
+ import { t as t23 } from "@epoch-agent/infra";
2988
3138
  import { isProviderType as isProviderType2, PROVIDER_TYPES as PROVIDER_TYPES3 } from "@epoch-agent/protocol";
2989
3139
  function applyRunFlags(opts) {
2990
3140
  applySettingsPath(opts.settings);
@@ -3003,9 +3153,9 @@ function applyOverrides(opts) {
3003
3153
  if (opts.provider) {
3004
3154
  if (!isProviderType2(opts.provider)) {
3005
3155
  throw new CliError(
3006
- t22("flags.provider_unknown", { value: opts.provider }),
3156
+ t23("flags.provider_unknown", { value: opts.provider }),
3007
3157
  1,
3008
- t22("flags.choices", { choices: PROVIDER_TYPES3.join(", ") })
3158
+ t23("flags.choices", { choices: PROVIDER_TYPES3.join(", ") })
3009
3159
  );
3010
3160
  }
3011
3161
  process.env.EPOCH_PROVIDER = opts.provider;
@@ -3013,9 +3163,9 @@ function applyOverrides(opts) {
3013
3163
  if (opts.permission) {
3014
3164
  if (!isPermissionLevel2(opts.permission)) {
3015
3165
  throw new CliError(
3016
- t22("flags.permission_unknown", { value: opts.permission }),
3166
+ t23("flags.permission_unknown", { value: opts.permission }),
3017
3167
  1,
3018
- t22("flags.choices", { choices: PERMISSION_LEVELS2.join(", ") })
3168
+ t23("flags.choices", { choices: PERMISSION_LEVELS2.join(", ") })
3019
3169
  );
3020
3170
  }
3021
3171
  process.env.EPOCH_PERMISSION = opts.permission;
@@ -3026,9 +3176,9 @@ function assertModelName(value, flag) {
3026
3176
  const spec = value.trim();
3027
3177
  if (MODEL_ID.test(spec)) return value;
3028
3178
  throw new CliError(
3029
- t22("flags.model_not_a_name", { flag, value }),
3179
+ t23("flags.model_not_a_name", { flag, value }),
3030
3180
  1,
3031
- t22("flags.model_not_a_name_hint", { value: spec })
3181
+ t23("flags.model_not_a_name_hint", { value: spec })
3032
3182
  );
3033
3183
  }
3034
3184
  function assertHttpUrl(value) {
@@ -3038,60 +3188,60 @@ function assertHttpUrl(value) {
3038
3188
  } catch {
3039
3189
  }
3040
3190
  throw new CliError(
3041
- t22("flags.base_url_invalid", { value }),
3191
+ t23("flags.base_url_invalid", { value }),
3042
3192
  1,
3043
- t22("flags.base_url_invalid_hint", { value: value.trim() })
3193
+ t23("flags.base_url_invalid_hint", { value: value.trim() })
3044
3194
  );
3045
3195
  }
3046
3196
  // src/commands/sessions.ts
3047
3197
  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");
3198
+ import { dbPath, t as t24, uiDateLocale as uiDateLocale2 } from "@epoch-agent/infra";
3199
+ var log7 = (msg) => process.stdout.write(msg + "\n");
3050
3200
  var SHORT_ID_LEN2 = 8;
3051
3201
  var PICK_LIMIT = 20;
3052
3202
  function whenOf(startedAt) {
3053
- return startedAt ? new Date(startedAt).toLocaleString(uiDateLocale2()) : t23("sessions.when_unknown");
3203
+ return startedAt ? new Date(startedAt).toLocaleString(uiDateLocale2()) : t24("sessions.when_unknown");
3054
3204
  }
3055
3205
  function titleOf(s) {
3056
- return s.title || s.preview || t23("sessions.untitled");
3206
+ return s.title || s.preview || t24("sessions.untitled");
3057
3207
  }
3058
3208
  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) => {
3209
+ const cmd = program2.command("sessions").alias("session").description(t24("sessions.cmd_root"));
3210
+ cmd.command("list").description(t24("sessions.cmd_list")).option("-n, --limit <n>", t24("sessions.opt_limit"), "10").action((opts) => {
3061
3211
  withSessions((sm) => {
3062
3212
  const r = sm.list({ limit: parseInt(opts.limit, 10) });
3063
3213
  if (r.sessions.length === 0) {
3064
- log6(` ${t23("sessions.list_empty")}`);
3214
+ log7(` ${t24("sessions.list_empty")}`);
3065
3215
  return;
3066
3216
  }
3067
3217
  for (const s of r.sessions) {
3068
- log6(` ${s.id.slice(0, SHORT_ID_LEN2)} ${whenOf(s.startedAt)} ${titleOf(s)}`);
3218
+ log7(` ${s.id.slice(0, SHORT_ID_LEN2)} ${whenOf(s.startedAt)} ${titleOf(s)}`);
3069
3219
  }
3070
3220
  });
3071
3221
  });
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) => {
3222
+ 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
3223
  const resolved = resolveSessionId(id);
3074
3224
  if (!resolved.ok) {
3075
3225
  throw new CliError(resolved.error, EXIT_CODES.FAILURE);
3076
3226
  }
3077
- await runOnce(query || t23("sessions.default_query"), {}, resolved.id);
3227
+ await runOnce(query || t24("sessions.default_query"), {}, resolved.id);
3078
3228
  });
3079
3229
  }
3080
3230
  function resolveSessionId(input2) {
3081
3231
  return withSessions((sm) => {
3082
3232
  if (!input2) {
3083
3233
  const latest = sm.getLatest()?.meta.id;
3084
- return latest ? { ok: true, id: latest } : { ok: false, error: t23("sessions.err_none") };
3234
+ return latest ? { ok: true, id: latest } : { ok: false, error: t24("sessions.err_none") };
3085
3235
  }
3086
3236
  if (sm.get(input2)) return { ok: true, id: input2 };
3087
3237
  const candidates = sm.list({ limit: 200 }).sessions.filter((s) => s.id.startsWith(input2)).map((s) => s.id);
3088
3238
  if (candidates.length === 1) return { ok: true, id: candidates[0] };
3089
3239
  if (candidates.length === 0) {
3090
- return { ok: false, error: t23("sessions.err_not_found", { input: input2 }) };
3240
+ return { ok: false, error: t24("sessions.err_not_found", { input: input2 }) };
3091
3241
  }
3092
3242
  return {
3093
3243
  ok: false,
3094
- error: t23("sessions.err_ambiguous", { input: input2, count: candidates.length })
3244
+ error: t24("sessions.err_ambiguous", { input: input2, count: candidates.length })
3095
3245
  };
3096
3246
  });
3097
3247
  }
@@ -3102,9 +3252,9 @@ function latestSessionIdForProject(cwd = process.cwd()) {
3102
3252
  async function pickSessionId() {
3103
3253
  if (isNonInteractive7()) {
3104
3254
  throw new CliError(
3105
- t23("sessions.err_needs_id"),
3255
+ t24("sessions.err_needs_id"),
3106
3256
  EXIT_CODES.FAILURE,
3107
- t23("sessions.err_needs_id_hint")
3257
+ t24("sessions.err_needs_id_hint")
3108
3258
  );
3109
3259
  }
3110
3260
  const rows = withSessions(
@@ -3112,22 +3262,22 @@ async function pickSessionId() {
3112
3262
  id: s.id,
3113
3263
  title: titleOf(s),
3114
3264
  when: whenOf(s.startedAt),
3115
- where: s.cwd ?? t23("sessions.cwd_unrecorded"),
3265
+ where: s.cwd ?? t24("sessions.cwd_unrecorded"),
3116
3266
  messageCount: s.messageCount
3117
3267
  }))
3118
3268
  );
3119
3269
  if (rows.length === 0) {
3120
- log6(t23("sessions.pick_empty"));
3270
+ log7(t24("sessions.pick_empty"));
3121
3271
  return void 0;
3122
3272
  }
3123
3273
  const { select: select2 } = await import("@inquirer/prompts");
3124
3274
  try {
3125
3275
  return await select2({
3126
- message: t23("sessions.pick_prompt"),
3276
+ message: t24("sessions.pick_prompt"),
3127
3277
  choices: rows.map((r) => ({
3128
3278
  name: `${r.id.slice(0, SHORT_ID_LEN2)} ${r.when} ${r.title}`,
3129
3279
  value: r.id,
3130
- description: `${t23("tui.resume.message_count", { n: r.messageCount })} \xB7 ${r.where}`
3280
+ description: `${t24("tui.resume.message_count", { n: r.messageCount })} \xB7 ${r.where}`
3131
3281
  })),
3132
3282
  pageSize: 12
3133
3283
  });
@@ -3144,27 +3294,27 @@ function withSessions(fn) {
3144
3294
  }
3145
3295
  }
3146
3296
  // src/commands/run.ts
3147
- var log7 = (msg) => {
3297
+ var log8 = (msg) => {
3148
3298
  process.stdout.write(msg + "\n");
3149
3299
  };
3150
3300
  function registerRunCommand(program2) {
3151
- program2.argument("[query]", t24("run.arg_query")).option("--allow-tool <name>", t24("run.opt_allow_tool"), collect, []).option(
3301
+ program2.argument("[query]", t25("run.arg_query")).option("--allow-tool <name>", t25("run.opt_allow_tool"), collect, []).option(
3152
3302
  "--allow-operation <type>",
3153
- t24("run.opt_allow_operation", { types: OPERATION_TYPES3.join(" / ") }),
3303
+ t25("run.opt_allow_operation", { types: OPERATION_TYPES3.join(" / ") }),
3154
3304
  collect,
3155
3305
  []
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(
3306
+ ).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
3307
  "--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(
3308
+ t25("run.opt_permission", { levels: PERMISSION_LEVELS3.join(" / ") })
3309
+ ).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
3310
  "--output-format <fmt>",
3161
- t24("run.opt_output_format", { formats: HEADLESS_OUTPUT_FORMATS2.join(" / ") })
3311
+ t25("run.opt_output_format", { formats: HEADLESS_OUTPUT_FORMATS2.join(" / ") })
3162
3312
  ).option(
3163
3313
  "--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) => {
3314
+ t25("run.opt_input_format", { formats: HEADLESS_INPUT_FORMATS2.join(" / ") })
3315
+ ).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
3316
  if (opts.version === true) {
3167
- log7(describeVersion(selfPackage().name));
3317
+ log8(describeVersion(selfPackage().name));
3168
3318
  return;
3169
3319
  }
3170
3320
  applyRunFlags(opts);
@@ -3174,39 +3324,39 @@ function registerRunCommand(program2) {
3174
3324
  if (formats.input === "stream-json") {
3175
3325
  if (opts.continue === true || resumeArg.kind !== "off") {
3176
3326
  throw new CliError(
3177
- t24("run.conflict_resume"),
3327
+ t25("run.conflict_resume"),
3178
3328
  EXIT_CODES.FAILURE,
3179
- t24("run.conflict_resume_hint")
3329
+ t25("run.conflict_resume_hint")
3180
3330
  );
3181
3331
  }
3182
3332
  if (opts.worktree === true) {
3183
3333
  throw new CliError(
3184
- t24("run.conflict_worktree"),
3334
+ t25("run.conflict_worktree"),
3185
3335
  EXIT_CODES.FAILURE,
3186
- t24("run.conflict_worktree_hint")
3336
+ t25("run.conflict_worktree_hint")
3187
3337
  );
3188
3338
  }
3189
3339
  if (opts.permissionPromptTool !== void 0) {
3190
3340
  throw new CliError(
3191
- t24("run.conflict_prompt_tool"),
3341
+ t25("run.conflict_prompt_tool"),
3192
3342
  EXIT_CODES.FAILURE,
3193
- t24("run.conflict_prompt_tool_hint")
3343
+ t25("run.conflict_prompt_tool_hint")
3194
3344
  );
3195
3345
  }
3196
3346
  if (!hasCredentials()) {
3197
3347
  throw new CliError(
3198
- t24("run.no_credentials_stream"),
3348
+ t25("run.no_credentials_stream"),
3199
3349
  EXIT_CODES.FAILURE,
3200
- t24("run.no_credentials_hint")
3350
+ t25("run.no_credentials_hint")
3201
3351
  );
3202
3352
  }
3203
3353
  process.exitCode = await runStreamJsonSession(opts);
3204
3354
  return;
3205
3355
  }
3206
3356
  const carried = resumeArg.kind === "pick" ? resumeArg.query : void 0;
3207
- const prompt = composePrompt(query ?? carried, await readStdin());
3357
+ const prompt = composePrompt(query ?? carried, await readStdin2());
3208
3358
  if (!hasCredentials()) {
3209
- log7(t24("run.welcome"));
3359
+ log8(t25("run.welcome"));
3210
3360
  return;
3211
3361
  }
3212
3362
  const resumeId = await resolveResumeTarget(opts, resumeArg);
@@ -3232,7 +3382,7 @@ async function resolveResumeTarget(opts, resumeArg) {
3232
3382
  if (opts.continue === true) {
3233
3383
  const latest = latestSessionIdForProject();
3234
3384
  if (!latest) {
3235
- process.stderr.write(`${t24("run.no_history")}
3385
+ process.stderr.write(`${t25("run.no_history")}
3236
3386
  `);
3237
3387
  }
3238
3388
  return latest;
@@ -3243,7 +3393,7 @@ async function resolveResumeTarget(opts, resumeArg) {
3243
3393
  throw new CliError(
3244
3394
  resolved.error,
3245
3395
  EXIT_CODES.FAILURE,
3246
- t24("run.resume_not_id_hint")
3396
+ t25("run.resume_not_id_hint")
3247
3397
  );
3248
3398
  }
3249
3399
  return resolved.id;
@@ -3262,7 +3412,7 @@ function resolveTuiEntry(baseDir, exists = existsSync6) {
3262
3412
  async function launchTui(resumeId) {
3263
3413
  const target = resolveTuiEntry(dirname3(fileURLToPath3(import.meta.url)));
3264
3414
  if (!target) {
3265
- process.stderr.write(`${t24("run.tui_entry_missing")}
3415
+ process.stderr.write(`${t25("run.tui_entry_missing")}
3266
3416
  `);
3267
3417
  process.exitCode = EXIT_CODES.FAILURE;
3268
3418
  return;
@@ -3277,7 +3427,7 @@ async function launchTui(resumeId) {
3277
3427
  });
3278
3428
  await new Promise((done) => {
3279
3429
  child.on("error", (err2) => {
3280
- process.stderr.write(`${t24("run.tui_spawn_failed", { message: err2.message })}
3430
+ process.stderr.write(`${t25("run.tui_spawn_failed", { message: err2.message })}
3281
3431
  `);
3282
3432
  process.exitCode = EXIT_CODES.FAILURE;
3283
3433
  done();
@@ -3289,13 +3439,13 @@ async function launchTui(resumeId) {
3289
3439
  });
3290
3440
  }
3291
3441
  // src/commands/schedule.ts
3292
- import { t as t32 } from "@epoch-agent/infra";
3442
+ import { t as t33 } from "@epoch-agent/infra";
3293
3443
  // src/schedule/add.ts
3294
3444
  import {
3295
3445
  SCHEDULE_DEFAULTS,
3296
3446
  validateSchedule
3297
3447
  } from "@epoch-agent/core";
3298
- import { automationWorkDir, t as t27 } from "@epoch-agent/infra";
3448
+ import { automationWorkDir, t as t28 } from "@epoch-agent/infra";
3299
3449
  import {
3300
3450
  isOperationType as isOperationType2,
3301
3451
  isPermissionLevel as isPermissionLevel3,
@@ -3304,7 +3454,7 @@ import {
3304
3454
  SCHEDULE_INTERVAL_MINUTES
3305
3455
  } from "@epoch-agent/protocol";
3306
3456
  // src/schedule/labels.ts
3307
- import { t as t25 } from "@epoch-agent/infra";
3457
+ import { t as t26 } from "@epoch-agent/infra";
3308
3458
  import {
3309
3459
  collectPendingApprovals
3310
3460
  } from "@epoch-agent/protocol";
@@ -3356,35 +3506,35 @@ var DRIFT_KEYS = {
3356
3506
  "never-registered": "schedule.drift.never_registered"
3357
3507
  };
3358
3508
  function renderIssues(issues) {
3359
- return issues.map((i) => ` \xB7 ${t25(ISSUE_KEYS[i.code], { detail: i.detail ?? "" })}`).join("\n");
3509
+ return issues.map((i) => ` \xB7 ${t26(ISSUE_KEYS[i.code], { detail: i.detail ?? "" })}`).join("\n");
3360
3510
  }
3361
3511
  function statusLabel(status) {
3362
3512
  const mark = status === "ok" ? "\u2705" : status === "failed" || status === "denied" ? "\u274C" : "\u26A0\uFE0F";
3363
- return `${mark} ${t25(STATUS_KEYS[status])}`;
3513
+ return `${mark} ${t26(STATUS_KEYS[status])}`;
3364
3514
  }
3365
3515
  function driftLabel(kind) {
3366
- return t25(DRIFT_KEYS[kind]);
3516
+ return t26(DRIFT_KEYS[kind]);
3367
3517
  }
3368
3518
  function describeTrigger(trigger) {
3369
3519
  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 });
3520
+ return trigger.everyMinutes < 60 ? t26("schedule.trigger.every_minutes", { n: trigger.everyMinutes }) : t26("schedule.trigger.every_hours", { n: trigger.everyMinutes / 60 });
3371
3521
  }
3372
3522
  if (trigger.kind === "once") {
3373
- return t25("schedule.trigger.once", { date: trigger.date, at: trigger.at });
3523
+ return t26("schedule.trigger.once", { date: trigger.date, at: trigger.at });
3374
3524
  }
3375
- if (trigger.cycle === "daily") return t25("schedule.trigger.daily", { at: trigger.at });
3525
+ if (trigger.cycle === "daily") return t26("schedule.trigger.daily", { at: trigger.at });
3376
3526
  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 });
3527
+ const days = trigger.weekdays.map((d) => t26(WEEKDAY_KEYS[d])).join("/");
3528
+ return t26("schedule.trigger.weekly", { days, at: trigger.at });
3379
3529
  }
3380
- return t25("schedule.trigger.monthly", { days: trigger.days.join("/"), at: trigger.at });
3530
+ return t26("schedule.trigger.monthly", { days: trigger.days.join("/"), at: trigger.at });
3381
3531
  }
3382
3532
  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");
3533
+ if (level === "plan") return t26("schedule.permission.plan");
3534
+ if (level === "acceptEdits") return t26("schedule.permission.accept_edits");
3535
+ if (level === "bypass") return t26("schedule.permission.bypass");
3536
+ if (level === "auto") return t26("schedule.permission.auto");
3537
+ return t26("schedule.permission.default");
3388
3538
  }
3389
3539
  // src/schedule/shared.ts
3390
3540
  import { realpathSync as realpathSync2 } from "fs";
@@ -3393,8 +3543,8 @@ import {
3393
3543
  ScheduleRegistrar,
3394
3544
  ScheduleStore
3395
3545
  } 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}
3546
+ import { dbPath as dbPath2, t as t27, uiDateLocale as uiDateLocale3 } from "@epoch-agent/infra";
3547
+ var log9 = (msg) => void process.stdout.write(`${msg}
3398
3548
  `);
3399
3549
  var warn2 = (msg) => void process.stderr.write(`${msg}
3400
3550
  `);
@@ -3422,24 +3572,24 @@ function mustFind(store, idOrPrefix) {
3422
3572
  if (hits.length === 1) return hits[0];
3423
3573
  if (hits.length === 0) {
3424
3574
  throw new CliError(
3425
- t26("schedule.err_not_found", { id: idOrPrefix }),
3575
+ t27("schedule.err_not_found", { id: idOrPrefix }),
3426
3576
  EXIT_CODES.FAILURE,
3427
- t26("schedule.err_not_found_hint")
3577
+ t27("schedule.err_not_found_hint")
3428
3578
  );
3429
3579
  }
3430
3580
  throw new CliError(
3431
- t26("schedule.err_ambiguous", { id: idOrPrefix }),
3581
+ t27("schedule.err_ambiguous", { id: idOrPrefix }),
3432
3582
  EXIT_CODES.FAILURE,
3433
3583
  hits.map((h) => ` ${h.id} ${h.name}`).join("\n")
3434
3584
  );
3435
3585
  }
3436
3586
  function reportRegistration(outcome, fatal) {
3437
3587
  if (outcome.ok) {
3438
- if (outcome.warnings.includes("source")) warn2(t26("schedule.warn_source_entry"));
3588
+ if (outcome.warnings.includes("source")) warn2(t27("schedule.warn_source_entry"));
3439
3589
  return;
3440
3590
  }
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;
3591
+ 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");
3592
+ 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
3593
  if (!fatal) {
3444
3594
  warn2(message);
3445
3595
  if (hint) warn2(hint);
@@ -3477,7 +3627,7 @@ async function runAdd(opts) {
3477
3627
  });
3478
3628
  if (validation.issues.length > 0) {
3479
3629
  throw new CliError(
3480
- t27("schedule.err_invalid"),
3630
+ t28("schedule.err_invalid"),
3481
3631
  EXIT_CODES.FAILURE,
3482
3632
  renderIssues(validation.issues)
3483
3633
  );
@@ -3507,26 +3657,26 @@ async function fillInteractively(opts) {
3507
3657
  if (!missing) return opts;
3508
3658
  if (!process.stdin.isTTY || !process.stdout.isTTY) {
3509
3659
  throw new CliError(
3510
- t27("schedule.err_missing_flags"),
3660
+ t28("schedule.err_missing_flags"),
3511
3661
  EXIT_CODES.FAILURE,
3512
- t27("schedule.err_missing_flags_hint")
3662
+ t28("schedule.err_missing_flags_hint")
3513
3663
  );
3514
3664
  }
3515
3665
  const { input: input2, select: select2 } = await import("@inquirer/prompts");
3516
3666
  const next = { ...opts };
3517
- next.name ||= await input2({ message: t27("schedule.ask_name") });
3518
- next.prompt ||= await input2({ message: t27("schedule.ask_prompt") });
3667
+ next.name ||= await input2({ message: t28("schedule.ask_name") });
3668
+ next.prompt ||= await input2({ message: t28("schedule.ask_prompt") });
3519
3669
  if (!hasTrigger) {
3520
- const at = await input2({ message: t27("schedule.ask_at"), default: "09:00" });
3670
+ const at = await input2({ message: t28("schedule.ask_at"), default: "09:00" });
3521
3671
  next.daily = at;
3522
3672
  }
3523
- next.budget ||= await input2({ message: t27("schedule.ask_budget"), default: "0.50" });
3673
+ next.budget ||= await input2({ message: t28("schedule.ask_budget"), default: "0.50" });
3524
3674
  next.permission ||= await select2({
3525
- message: t27("schedule.ask_permission"),
3675
+ message: t28("schedule.ask_permission"),
3526
3676
  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" }
3677
+ { name: t28("schedule.permission.default"), value: "default" },
3678
+ { name: t28("schedule.permission.plan"), value: "plan" },
3679
+ { name: t28("schedule.permission.accept_edits"), value: "acceptEdits" }
3530
3680
  ]
3531
3681
  });
3532
3682
  return next;
@@ -3535,8 +3685,8 @@ function parseTrigger(opts) {
3535
3685
  const given = [opts.daily, opts.weekly, opts.monthly, opts.every, opts.once].filter(
3536
3686
  (v) => v !== void 0
3537
3687
  );
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);
3688
+ if (given.length === 0) throw new CliError(t28("schedule.err_no_trigger"), EXIT_CODES.FAILURE);
3689
+ if (given.length > 1) throw new CliError(t28("schedule.err_many_triggers"), EXIT_CODES.FAILURE);
3540
3690
  if (opts.daily !== void 0) return { kind: "cron", cycle: "daily", at: opts.daily };
3541
3691
  if (opts.weekly !== void 0) {
3542
3692
  return {
@@ -3560,14 +3710,14 @@ function parseTrigger(opts) {
3560
3710
  return { kind: "interval", everyMinutes: parseEvery(opts.every) };
3561
3711
  }
3562
3712
  function requireAt(opts) {
3563
- if (!opts.at) throw new CliError(t27("schedule.err_at_required"), EXIT_CODES.FAILURE);
3713
+ if (!opts.at) throw new CliError(t28("schedule.err_at_required"), EXIT_CODES.FAILURE);
3564
3714
  return opts.at;
3565
3715
  }
3566
3716
  function parseWeekday(raw) {
3567
3717
  const idx = WEEKDAY_CODES.indexOf(raw.trim().toUpperCase());
3568
3718
  if (idx < 0) {
3569
3719
  throw new CliError(
3570
- t27("schedule.err_weekday", { value: raw }),
3720
+ t28("schedule.err_weekday", { value: raw }),
3571
3721
  EXIT_CODES.FAILURE,
3572
3722
  WEEKDAY_CODES.join(",")
3573
3723
  );
@@ -3579,9 +3729,9 @@ function parseEvery(raw) {
3579
3729
  const minutes = m ? Number(m[1]) * (m[2]?.toLowerCase() === "h" ? 60 : 1) : Number.NaN;
3580
3730
  if (!SCHEDULE_INTERVAL_MINUTES.includes(minutes)) {
3581
3731
  throw new CliError(
3582
- t27("schedule.err_every", { value: raw }),
3732
+ t28("schedule.err_every", { value: raw }),
3583
3733
  EXIT_CODES.FAILURE,
3584
- t27("schedule.err_every_hint", {
3734
+ t28("schedule.err_every_hint", {
3585
3735
  values: SCHEDULE_INTERVAL_MINUTES.map((n) => n < 60 ? `${n}m` : `${n / 60}h`).join(" / ")
3586
3736
  })
3587
3737
  );
@@ -3592,7 +3742,7 @@ function parsePermission(raw) {
3592
3742
  if (raw === void 0) return "default";
3593
3743
  if (!isPermissionLevel3(raw)) {
3594
3744
  throw new CliError(
3595
- t27("schedule.err_permission", { value: raw }),
3745
+ t28("schedule.err_permission", { value: raw }),
3596
3746
  EXIT_CODES.FAILURE,
3597
3747
  PERMISSION_LEVELS4.join(" / ")
3598
3748
  );
@@ -3604,7 +3754,7 @@ function parseOperations(raw) {
3604
3754
  for (const value of raw ?? []) {
3605
3755
  if (!isOperationType2(value)) {
3606
3756
  throw new CliError(
3607
- t27("schedule.err_operation", { value }),
3757
+ t28("schedule.err_operation", { value }),
3608
3758
  EXIT_CODES.FAILURE,
3609
3759
  OPERATION_TYPES4.join(" / ")
3610
3760
  );
@@ -3617,9 +3767,9 @@ function buildInput(opts, trigger, permission) {
3617
3767
  const budget = Number(opts.budget);
3618
3768
  if (!Number.isFinite(budget) || budget <= 0) {
3619
3769
  throw new CliError(
3620
- t27("schedule.err_budget", { value: opts.budget ?? "" }),
3770
+ t28("schedule.err_budget", { value: opts.budget ?? "" }),
3621
3771
  EXIT_CODES.FAILURE,
3622
- t27("schedule.err_budget_hint")
3772
+ t28("schedule.err_budget_hint")
3623
3773
  );
3624
3774
  }
3625
3775
  return {
@@ -3655,52 +3805,52 @@ function applyDefaultAllowlist(store, def, opts) {
3655
3805
  }) ?? def;
3656
3806
  }
3657
3807
  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) }));
3808
+ log9(t28("schedule.created", { id: def.id, name: def.name }));
3809
+ log9("");
3810
+ log9(t28("schedule.created_next", { id: def.id.slice(0, 12) }));
3661
3811
  }
3662
3812
  // src/schedule/doctor.ts
3663
3813
  import { diagnoseSchedules, pruneSchedules, repairSchedules } from "@epoch-agent/core";
3664
- import { t as t28 } from "@epoch-agent/infra";
3814
+ import { t as t29 } from "@epoch-agent/infra";
3665
3815
  async function runDoctor(opts) {
3666
3816
  const ctx = await openSchedule();
3667
3817
  try {
3668
3818
  const deps = { store: ctx.store, backend: ctx.backend, registrar: ctx.registrar };
3669
3819
  const report = await diagnoseSchedules(deps);
3670
3820
  if (report.unsupported) {
3671
- warn2(t28("schedule.doctor_unsupported"));
3821
+ warn2(t29("schedule.doctor_unsupported"));
3672
3822
  return;
3673
3823
  }
3674
3824
  if (report.drifts.length === 0) {
3675
- log8(t28("schedule.doctor_clean", { n: report.checked }));
3825
+ log9(t29("schedule.doctor_clean", { n: report.checked }));
3676
3826
  return;
3677
3827
  }
3678
- log8(t28("schedule.doctor_found", { n: report.drifts.length }));
3828
+ log9(t29("schedule.doctor_found", { n: report.drifts.length }));
3679
3829
  for (const drift of report.drifts) {
3680
- log8(
3830
+ log9(
3681
3831
  ` \xB7 ${driftLabel(drift.kind)} ${drift.name ?? drift.scheduleId ?? ""} [${drift.osTaskId || "\u2014"}]${drift.detail ? `
3682
3832
  ${drift.detail}` : ""}`
3683
3833
  );
3684
3834
  }
3685
3835
  if (opts.repair !== true && opts.prune !== true) {
3686
- log8("");
3687
- log8(t28("schedule.doctor_hint"));
3836
+ log9("");
3837
+ log9(t29("schedule.doctor_hint"));
3688
3838
  return;
3689
3839
  }
3690
3840
  if (opts.repair === true) {
3691
3841
  for (const outcome of await repairSchedules(report.drifts, deps)) {
3692
3842
  const label = outcome.drift.name ?? outcome.drift.scheduleId ?? "";
3693
- if (outcome.ok) log8(t28("schedule.doctor_repaired", { name: label }));
3843
+ if (outcome.ok) log9(t29("schedule.doctor_repaired", { name: label }));
3694
3844
  else
3695
- warn2(t28("schedule.doctor_repair_failed", { name: label, detail: outcome.detail ?? "" }));
3845
+ warn2(t29("schedule.doctor_repair_failed", { name: label, detail: outcome.detail ?? "" }));
3696
3846
  }
3697
3847
  }
3698
3848
  if (opts.prune === true) {
3699
3849
  for (const outcome of await pruneSchedules(report.drifts, deps)) {
3700
- if (outcome.ok) log8(t28("schedule.doctor_pruned", { id: outcome.drift.osTaskId }));
3850
+ if (outcome.ok) log9(t29("schedule.doctor_pruned", { id: outcome.drift.osTaskId }));
3701
3851
  else {
3702
3852
  warn2(
3703
- t28("schedule.doctor_prune_failed", {
3853
+ t29("schedule.doctor_prune_failed", {
3704
3854
  id: outcome.drift.osTaskId,
3705
3855
  detail: outcome.detail ?? ""
3706
3856
  })
@@ -3714,15 +3864,15 @@ async function runDoctor(opts) {
3714
3864
  }
3715
3865
  }
3716
3866
  // src/schedule/manage.ts
3717
- import { automationLogsDir, t as t29 } from "@epoch-agent/infra";
3867
+ import { automationLogsDir, t as t30 } from "@epoch-agent/infra";
3718
3868
  async function runSetEnabled(idOrPrefix, enabled) {
3719
3869
  const ctx = await openSchedule();
3720
3870
  try {
3721
3871
  const def = mustFind(ctx.store, idOrPrefix);
3722
3872
  const outcome = await ctx.registrar.setEnabled(def, enabled);
3723
3873
  reportRegistration(outcome, false);
3724
- log8(
3725
- enabled ? t29("schedule.enabled_done", { name: def.name }) : t29("schedule.disabled_done", { name: def.name })
3874
+ log9(
3875
+ enabled ? t30("schedule.enabled_done", { name: def.name }) : t30("schedule.disabled_done", { name: def.name })
3726
3876
  );
3727
3877
  } finally {
3728
3878
  ctx.close();
@@ -3734,14 +3884,14 @@ async function runRemove(idOrPrefix) {
3734
3884
  const def = mustFind(ctx.store, idOrPrefix);
3735
3885
  if (def.osTaskId) reportRegistration(await ctx.registrar.unregister(def), false);
3736
3886
  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) }));
3887
+ log9(t30("schedule.removed", { name: def.name }));
3888
+ log9(t30("schedule.removed_logs_kept", { dir: automationLogsDir(def.id, ctx.homeDir) }));
3739
3889
  } finally {
3740
3890
  ctx.close();
3741
3891
  }
3742
3892
  }
3743
3893
  // src/schedule/run.ts
3744
- import { t as t30 } from "@epoch-agent/infra";
3894
+ import { t as t31 } from "@epoch-agent/infra";
3745
3895
  import { unfixedRules } from "@epoch-agent/protocol";
3746
3896
  import { fireSchedule } from "@epoch-agent/runtime";
3747
3897
  async function runFire(scheduleId, homeDir) {
@@ -3754,9 +3904,9 @@ async function runFire(scheduleId, homeDir) {
3754
3904
  ctx.close();
3755
3905
  }
3756
3906
  if (result.missing) {
3757
- warn2(t30("schedule.fire_missing", { id: scheduleId }));
3907
+ warn2(t31("schedule.fire_missing", { id: scheduleId }));
3758
3908
  } else if (result.disabled) {
3759
- warn2(t30("schedule.fire_disabled", { id: scheduleId }));
3909
+ warn2(t31("schedule.fire_disabled", { id: scheduleId }));
3760
3910
  } else {
3761
3911
  warn2(`${statusLabel(result.status)}${result.detail ? ` ${result.detail}` : ""}`);
3762
3912
  }
@@ -3766,14 +3916,14 @@ async function runManual(idOrPrefix, opts) {
3766
3916
  const ctx = await openSchedule();
3767
3917
  try {
3768
3918
  const def = mustFind(ctx.store, idOrPrefix);
3769
- log8(t30("schedule.run_start", { name: def.name }));
3919
+ log9(t31("schedule.run_start", { name: def.name }));
3770
3920
  const result = await fireSchedule({
3771
3921
  scheduleId: def.id,
3772
3922
  homeDir: ctx.homeDir,
3773
3923
  manual: true,
3774
3924
  registrar: ctx.registrar
3775
3925
  });
3776
- log8(`${statusLabel(result.status)}${result.detail ? ` ${result.detail}` : ""}`);
3926
+ log9(`${statusLabel(result.status)}${result.detail ? ` ${result.detail}` : ""}`);
3777
3927
  const pending = result.run?.pendingApprovals ?? [];
3778
3928
  if (pending.length === 0) {
3779
3929
  process.exitCode = result.exitCode;
@@ -3782,21 +3932,21 @@ async function runManual(idOrPrefix, opts) {
3782
3932
  printPending(pending);
3783
3933
  if (opts.fix === true) {
3784
3934
  const added = applyFix(ctx.store, def.id, pending);
3785
- log8(added.length > 0 ? t30("schedule.fix_done", { n: added.length }) : t30("schedule.fix_none"));
3935
+ log9(added.length > 0 ? t31("schedule.fix_done", { n: added.length }) : t31("schedule.fix_none"));
3786
3936
  return;
3787
3937
  }
3788
- log8(t30("schedule.fix_hint", { id: def.id.slice(0, 12) }));
3938
+ log9(t31("schedule.fix_hint", { id: def.id.slice(0, 12) }));
3789
3939
  process.exitCode = result.exitCode;
3790
3940
  } finally {
3791
3941
  ctx.close();
3792
3942
  }
3793
3943
  }
3794
3944
  function printPending(pending) {
3795
- log8("");
3796
- log8(t30("schedule.pending_header", { n: pending.length }));
3945
+ log9("");
3946
+ log9(t31("schedule.pending_header", { n: pending.length }));
3797
3947
  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}`);
3948
+ log9(` \xB7 ${t31("schedule.pending_line", { tool: item.toolName, target: item.target })}`);
3949
+ if (item.suggestedRule) log9(` \u2192 ${item.suggestedRule}`);
3800
3950
  }
3801
3951
  }
3802
3952
  function applyFix(store, scheduleId, pending) {
@@ -3808,23 +3958,23 @@ function applyFix(store, scheduleId, pending) {
3808
3958
  }
3809
3959
  // src/schedule/view.ts
3810
3960
  import { nextRunAt, readRecording } from "@epoch-agent/core";
3811
- import { t as t31 } from "@epoch-agent/infra";
3961
+ import { t as t32 } from "@epoch-agent/infra";
3812
3962
  async function runList() {
3813
3963
  const ctx = await openSchedule();
3814
3964
  try {
3815
3965
  const defs = ctx.store.list();
3816
3966
  if (defs.length === 0) {
3817
- log8(t31("schedule.list_empty"));
3818
- log8(t31("schedule.list_empty_hint"));
3967
+ log9(t32("schedule.list_empty"));
3968
+ log9(t32("schedule.list_empty_hint"));
3819
3969
  return;
3820
3970
  }
3821
- log8(t31("schedule.list_header"));
3971
+ log9(t32("schedule.list_header"));
3822
3972
  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");
3973
+ const next = def.enabled ? formatWhen(nextRunAt(def.trigger, Date.now(), def.startDate, def.endDate) ?? void 0) : t32("schedule.disabled_mark");
3824
3974
  const danger = def.permission === "bypass" ? " \u{1F534}" : "";
3825
- log8(
3975
+ log9(
3826
3976
  ` ${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)}`
3977
+ ${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
3978
  );
3829
3979
  }
3830
3980
  } finally {
@@ -3835,45 +3985,45 @@ async function runShow(idOrPrefix) {
3835
3985
  const ctx = await openSchedule();
3836
3986
  try {
3837
3987
  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)}`);
3988
+ log9(`${def.name} (${def.id})`);
3989
+ log9(` ${t32("schedule.field_enabled")}: ${def.enabled ? t32("schedule.yes") : t32("schedule.no")}`);
3990
+ log9(` ${t32("schedule.field_trigger")}: ${describeTrigger(def.trigger)}`);
3841
3991
  if (def.startDate ?? def.endDate) {
3842
- log8(` ${t31("schedule.field_window")}: ${def.startDate ?? "\u2014"} .. ${def.endDate ?? "\u2014"}`);
3992
+ log9(` ${t32("schedule.field_window")}: ${def.startDate ?? "\u2014"} .. ${def.endDate ?? "\u2014"}`);
3843
3993
  }
3844
- log8(
3845
- ` ${t31("schedule.field_next")}: ${formatWhen(
3994
+ log9(
3995
+ ` ${t32("schedule.field_next")}: ${formatWhen(
3846
3996
  nextRunAt(def.trigger, Date.now(), def.startDate, def.endDate) ?? void 0
3847
3997
  )}`
3848
3998
  );
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", {
3999
+ log9(` ${t32("schedule.field_workdir")}: ${def.workDir}`);
4000
+ if (def.model) log9(` ${t32("schedule.field_model")}: ${def.model}`);
4001
+ log9(` ${t32("schedule.field_permission")}: ${permissionLabel(def.permission)}`);
4002
+ log9(
4003
+ ` ${t32("schedule.field_limits")}: ` + t32("schedule.limits_value", {
3854
4004
  turns: def.maxTurns,
3855
4005
  budget: def.maxBudgetUsd.toFixed(2),
3856
4006
  minutes: Math.round(def.timeoutMs / 6e4)
3857
4007
  })
3858
4008
  );
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("");
4009
+ log9(` ${t32("schedule.field_backend")}: ${def.osBackend} ${def.osTaskId || "\u2014"}`);
4010
+ log9(` ${t32("schedule.field_prompt")}:`);
4011
+ for (const line of def.prompt.split("\n")) log9(` ${line}`);
4012
+ log9("");
3863
4013
  printAllowlist(def);
3864
- log8("");
3865
- log8(t31("schedule.field_last_run", { when: formatWhen(def.lastRunAt) }));
4014
+ log9("");
4015
+ log9(t32("schedule.field_last_run", { when: formatWhen(def.lastRunAt) }));
3866
4016
  } finally {
3867
4017
  ctx.close();
3868
4018
  }
3869
4019
  }
3870
4020
  function printAllowlist(def) {
3871
4021
  if (def.permission === "bypass") {
3872
- log8(t31("schedule.allowlist_bypass"));
4022
+ log9(t32("schedule.allowlist_bypass"));
3873
4023
  return;
3874
4024
  }
3875
4025
  if (def.permission === "plan") {
3876
- log8(t31("schedule.allowlist_readonly"));
4026
+ log9(t32("schedule.allowlist_readonly"));
3877
4027
  return;
3878
4028
  }
3879
4029
  const lines = [
@@ -3881,9 +4031,9 @@ function printAllowlist(def) {
3881
4031
  ...def.allowOperations.map((v) => ` ${v}`),
3882
4032
  ...def.allowRules.map((v) => ` ${v}`)
3883
4033
  ];
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"));
4034
+ log9(t32("schedule.allowlist_header"));
4035
+ log9(lines.length > 0 ? lines.join("\n") : ` ${t32("schedule.allowlist_empty")}`);
4036
+ log9(t32("schedule.allowlist_scope_note"));
3887
4037
  }
3888
4038
  async function runLogs(idOrPrefix, limit, tail) {
3889
4039
  const ctx = await openSchedule();
@@ -3891,7 +4041,7 @@ async function runLogs(idOrPrefix, limit, tail) {
3891
4041
  const def = mustFind(ctx.store, idOrPrefix);
3892
4042
  const runs = ctx.store.listRuns(def.id, limit);
3893
4043
  if (runs.length === 0) {
3894
- log8(t31("schedule.logs_empty"));
4044
+ log9(t32("schedule.logs_empty"));
3895
4045
  return;
3896
4046
  }
3897
4047
  for (const run of runs) printRun(run);
@@ -3901,31 +4051,31 @@ async function runLogs(idOrPrefix, limit, tail) {
3901
4051
  }
3902
4052
  }
3903
4053
  function printRun(run) {
3904
- log8(
3905
- ` ${formatWhen(run.startedAt)} ${statusLabel(run.status)} ` + t31("schedule.run_meta", {
4054
+ log9(
4055
+ ` ${formatWhen(run.startedAt)} ${statusLabel(run.status)} ` + t32("schedule.run_meta", {
3906
4056
  turns: run.turns,
3907
4057
  cost: run.costUsd.toFixed(4),
3908
- manual: run.manual ? t31("schedule.run_manual") : ""
4058
+ manual: run.manual ? t32("schedule.run_manual") : ""
3909
4059
  })
3910
4060
  );
3911
- if (run.reason) log8(` ${run.reason}`);
4061
+ if (run.reason) log9(` ${run.reason}`);
3912
4062
  for (const pending of run.pendingApprovals) {
3913
- log8(
3914
- ` \u26A0 ${t31("schedule.pending_line", { tool: pending.toolName, target: pending.target })}`
4063
+ log9(
4064
+ ` \u26A0 ${t32("schedule.pending_line", { tool: pending.toolName, target: pending.target })}`
3915
4065
  );
3916
4066
  if (pending.suggestedRule) {
3917
- log8(` ${t31("schedule.pending_fix", { rule: pending.suggestedRule })}`);
4067
+ log9(` ${t32("schedule.pending_fix", { rule: pending.suggestedRule })}`);
3918
4068
  }
3919
4069
  }
3920
4070
  }
3921
4071
  function printRecording(run) {
3922
4072
  if (!run.logPath) return;
3923
- log8("");
3924
- log8(t31("schedule.logs_recording", { path: run.logPath }));
4073
+ log9("");
4074
+ log9(t32("schedule.logs_recording", { path: run.logPath }));
3925
4075
  for (const envelope of readRecording(run.logPath)) {
3926
4076
  const event = envelope.event;
3927
4077
  if (event.type === "text-delta" && event.text) process.stdout.write(event.text);
3928
- else if (event.type === "error" && event.message) log8(`
4078
+ else if (event.type === "error" && event.message) log9(`
3929
4079
  [error] ${event.message}`);
3930
4080
  }
3931
4081
  process.stdout.write("\n");
@@ -3933,19 +4083,19 @@ function printRecording(run) {
3933
4083
  // src/commands/schedule.ts
3934
4084
  var DEFAULT_LOG_LIMIT = 10;
3935
4085
  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(
4086
+ const cmd = program2.command("schedule").description(t33("cli.schedule.summary"));
4087
+ 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));
4088
+ cmd.command("list", { isDefault: true }).description(t33("cli.schedule.list")).action(() => runList());
4089
+ cmd.command("show").description(t33("cli.schedule.show")).argument("<id>", t33("cli.schedule.arg_id")).action((id) => runShow(id));
4090
+ cmd.command("enable").description(t33("cli.schedule.enable")).argument("<id>", t33("cli.schedule.arg_id")).action((id) => runSetEnabled(id, true));
4091
+ cmd.command("disable").description(t33("cli.schedule.disable")).argument("<id>", t33("cli.schedule.arg_id")).action((id) => runSetEnabled(id, false));
4092
+ cmd.command("rm").alias("remove").description(t33("cli.schedule.rm")).argument("<id>", t33("cli.schedule.arg_id")).action((id) => runRemove(id));
4093
+ 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));
4094
+ 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
4095
  (id, opts) => runLogs(id, Number(opts.limit ?? DEFAULT_LOG_LIMIT), opts.tail === true)
3946
4096
  );
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));
4097
+ 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));
4098
+ 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
4099
  }
3950
4100
  function collect3(value, previous) {
3951
4101
  return [...previous, value];
@@ -3956,7 +4106,7 @@ import { statfs } from "fs/promises";
3956
4106
  import {
3957
4107
  describeIsolation,
3958
4108
  getConfigIssues,
3959
- loadConfig as loadConfig3,
4109
+ loadConfig as loadConfig4,
3960
4110
  SANDBOX_COVERS,
3961
4111
  SANDBOX_EXCLUDES
3962
4112
  } from "@epoch-agent/core";
@@ -3964,17 +4114,13 @@ import {
3964
4114
  allJobs,
3965
4115
  confine,
3966
4116
  resolveProfile,
3967
- t as t34
4117
+ t as t35
3968
4118
  } from "@epoch-agent/infra";
3969
4119
  import { hasFailure } from "@epoch-agent/protocol";
3970
- import {
3971
- classifyTerminal,
3972
- probeShiftEnter
3973
- } from "@epoch-agent/tui";
3974
4120
  // src/statusline.ts
3975
4121
  import { execFile as execFile2 } from "child_process";
3976
4122
  import { sanitizeToolOutput } from "@epoch-agent/core";
3977
- import { shellSpawnArgs, t as t33 } from "@epoch-agent/infra";
4123
+ import { shellSpawnArgs, t as t34 } from "@epoch-agent/infra";
3978
4124
  var TIMEOUT_MS2 = 2e3;
3979
4125
  var MAX_WIDTH = 60;
3980
4126
  var MAX_BUFFER = 64 * 1024;
@@ -4002,7 +4148,7 @@ function runStatusLineCommand(command, cwd) {
4002
4148
  const killed = err2.killed === true;
4003
4149
  settle({
4004
4150
  text: null,
4005
- error: killed ? t33("statusline.timeout", { ms: TIMEOUT_MS2 }) : err2.message.trim()
4151
+ error: killed ? t34("statusline.timeout", { ms: TIMEOUT_MS2 }) : err2.message.trim()
4006
4152
  });
4007
4153
  return;
4008
4154
  }
@@ -4016,12 +4162,12 @@ async function probeStatusLine(config, cwd) {
4016
4162
  if (!command) return null;
4017
4163
  const result = await runStatusLineCommand(command, cwd);
4018
4164
  if (result.text === null) {
4019
- return { command, ok: false, detail: result.error ?? t33("statusline.no_output") };
4165
+ return { command, ok: false, detail: result.error ?? t34("statusline.no_output") };
4020
4166
  }
4021
4167
  return { command, ok: true, detail: result.text };
4022
4168
  }
4023
4169
  // src/commands/status.ts
4024
- var log9 = (msg) => {
4170
+ var log10 = (msg) => {
4025
4171
  process.stdout.write(msg + "\n");
4026
4172
  };
4027
4173
  var STATUS_MARK = {
@@ -4049,10 +4195,10 @@ async function describeDisk(path = ".") {
4049
4195
  }
4050
4196
  }
4051
4197
  function describeConfig() {
4052
- if (!existsSync7(CONFIG_PATH)) return t34("cli.status.config_absent");
4053
- loadConfig3();
4198
+ if (!existsSync7(CONFIG_PATH)) return t35("cli.status.config_absent");
4199
+ loadConfig4();
4054
4200
  const n = getConfigIssues().length;
4055
- return n === 0 ? t34("cli.status.config_present") : t34("cli.status.config_present_with_issues", { count: n });
4201
+ return n === 0 ? t35("cli.status.config_present") : t35("cli.status.config_present_with_issues", { count: n });
4056
4202
  }
4057
4203
  async function describeSecretBackend() {
4058
4204
  try {
@@ -4060,18 +4206,18 @@ async function describeSecretBackend() {
4060
4206
  const store = await createSecretStore();
4061
4207
  return store.encrypted ? store.detail : `\u26A0 ${store.detail}`;
4062
4208
  } catch (err2) {
4063
- return t34("cli.status.secret_probe_failed", {
4209
+ return t35("cli.status.secret_probe_failed", {
4064
4210
  message: err2 instanceof Error ? err2.message : String(err2)
4065
4211
  });
4066
4212
  }
4067
4213
  }
4068
4214
  function workspaceLines(rt) {
4069
- const lines = [` ${t34("cli.doctor.workspace_root", { root: rt.workspace.root })}`];
4215
+ const lines = [` ${t35("cli.doctor.workspace_root", { root: rt.workspace.root })}`];
4070
4216
  lines.push(
4071
- ` ${rt.trusted ? t34("cli.doctor.workspace_trusted") : t34("cli.doctor.workspace_untrusted")}`
4217
+ ` ${rt.trusted ? t35("cli.doctor.workspace_trusted") : t35("cli.doctor.workspace_untrusted")}`
4072
4218
  );
4073
4219
  lines.push(
4074
- ` ${rt.workspace.extra.length === 0 ? t34("cli.doctor.workspace_no_extra") : t34("cli.doctor.workspace_extra", { count: rt.workspace.extra.length })}`
4220
+ ` ${rt.workspace.extra.length === 0 ? t35("cli.doctor.workspace_no_extra") : t35("cli.doctor.workspace_extra", { count: rt.workspace.extra.length })}`
4075
4221
  );
4076
4222
  for (const dir of rt.workspace.extra) lines.push(` \xB7 ${dir}`);
4077
4223
  return lines;
@@ -4079,94 +4225,94 @@ function workspaceLines(rt) {
4079
4225
  function sandboxLines(cwd, sandbox) {
4080
4226
  const iso = describeIsolation();
4081
4227
  const lines = [`
4082
- ${t34("cli.doctor.sandbox_head")}`];
4228
+ ${t35("cli.doctor.sandbox_head")}`];
4083
4229
  if (iso.backend === "none") {
4084
4230
  lines.push(` ${STATUS_MARK.skipped} ${iso.detail}`);
4085
4231
  lines.push(
4086
- ` ${STATUS_MARK.warn} ${t34(
4232
+ ` ${STATUS_MARK.warn} ${t35(
4087
4233
  iso.reason === "platform-unsupported" ? "cli.doctor.sandbox_absent_by_design" : "cli.doctor.sandbox_absent_tools"
4088
4234
  )}`
4089
4235
  );
4090
4236
  return lines;
4091
4237
  }
4092
4238
  lines.push(
4093
- ` ${STATUS_MARK.ok} ${t34("cli.doctor.sandbox_backend", { backend: iso.backend, platform: iso.platform })}`
4239
+ ` ${STATUS_MARK.ok} ${t35("cli.doctor.sandbox_backend", { backend: iso.backend, platform: iso.platform })}`
4094
4240
  );
4095
- lines.push(` \xB7 ${t34("cli.doctor.sandbox_code_exec", { detail: iso.detail })}`);
4241
+ lines.push(` \xB7 ${t35("cli.doctor.sandbox_code_exec", { detail: iso.detail })}`);
4096
4242
  const probe = (mode) => confine("/bin/sh", ["-c", "true"], { mode, workspaceRoot: cwd, allowNetwork: true });
4097
4243
  for (const mode of ["workspace-write", "read-only"]) {
4098
4244
  const c = probe(mode);
4099
4245
  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")}`);
4246
+ lines.push(` \xB7 ${t35("cli.doctor.sandbox_terminal", { mode, enforcement: c.enforcement })}`);
4247
+ if (c.enforcement === "partial") lines.push(` ${t35("cli.doctor.sandbox_partial_devnull")}`);
4102
4248
  }
4103
4249
  const writable = probe("workspace-write");
4104
4250
  if (writable.confined) {
4105
- lines.push(` \xB7 ${t34("cli.doctor.sandbox_writable")}`);
4251
+ lines.push(` \xB7 ${t35("cli.doctor.sandbox_writable")}`);
4106
4252
  for (const dir of writable.writableDirs) lines.push(` \xB7 ${dir}`);
4107
4253
  }
4108
4254
  lines.push(
4109
- sandbox?.terminal === false ? ` ${STATUS_MARK.warn} ${t34("cli.doctor.sandbox_switch_off")}` : ` ${STATUS_MARK.ok} ${t34("cli.doctor.sandbox_switch_on")}`
4255
+ sandbox?.terminal === false ? ` ${STATUS_MARK.warn} ${t35("cli.doctor.sandbox_switch_off")}` : ` ${STATUS_MARK.ok} ${t35("cli.doctor.sandbox_switch_on")}`
4110
4256
  );
4111
- lines.push(` \xB7 ${t34("cli.doctor.sandbox_covers", { tools: SANDBOX_COVERS.join(", ") })}`);
4257
+ lines.push(` \xB7 ${t35("cli.doctor.sandbox_covers", { tools: SANDBOX_COVERS.join(", ") })}`);
4112
4258
  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(", ") })}`
4259
+ 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
4260
  );
4115
4261
  return lines;
4116
4262
  }
4117
4263
  function ftsLines(health) {
4118
4264
  const lines = [`
4119
- ${t34("cli.doctor.fts_head")}`];
4265
+ ${t35("cli.doctor.fts_head")}`];
4120
4266
  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 })}`);
4267
+ lines.push(` \xB7 ${t35("cli.doctor.fts_rows", { messages: health.messages, indexed })}`);
4122
4268
  const behind = health.tables.filter((tb) => tb.rows !== health.messages);
4123
4269
  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", {
4270
+ behind.length === 0 ? ` ${STATUS_MARK.ok} ${t35("cli.doctor.fts_in_sync")}` : (
4271
+ ` ${STATUS_MARK.warn} ${t35("cli.doctor.fts_out_of_sync", {
4126
4272
  tables: behind.map((tb) => `${tb.table} (${tb.rows - health.messages})`).join(", ")
4127
4273
  })}`
4128
4274
  )
4129
4275
  );
4130
4276
  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", {
4277
+ health.missingTriggers.length === 0 ? ` ${STATUS_MARK.ok} ${t35("cli.doctor.fts_triggers_ok")}` : ` ${STATUS_MARK.failed} ${t35("cli.doctor.fts_triggers_missing", {
4132
4278
  triggers: health.missingTriggers.join(", ")
4133
4279
  })}`
4134
4280
  );
4135
4281
  for (const tb of health.tables) {
4136
4282
  if (tb.error !== null) {
4137
4283
  lines.push(
4138
- ` ${STATUS_MARK.failed} ${t34("cli.doctor.fts_corrupt", { table: tb.table, detail: tb.error })}`
4284
+ ` ${STATUS_MARK.failed} ${t35("cli.doctor.fts_corrupt", { table: tb.table, detail: tb.error })}`
4139
4285
  );
4140
4286
  }
4141
4287
  if (tb.drift !== null) {
4142
4288
  lines.push(
4143
- ` ${STATUS_MARK.warn} ${t34("cli.doctor.fts_drift", { table: tb.table, detail: tb.drift })}`
4289
+ ` ${STATUS_MARK.warn} ${t35("cli.doctor.fts_drift", { table: tb.table, detail: tb.drift })}`
4144
4290
  );
4145
4291
  }
4146
4292
  }
4147
4293
  if (health.tables.some((tb) => !tb.external)) {
4148
- lines.push(` ${STATUS_MARK.warn} ${t34("cli.doctor.fts_legacy_schema")}`);
4294
+ lines.push(` ${STATUS_MARK.warn} ${t35("cli.doctor.fts_legacy_schema")}`);
4149
4295
  }
4150
4296
  if (health.indexBytes !== void 0) {
4151
- lines.push(` \xB7 ${t34("cli.doctor.fts_size", { size: formatBytes(health.indexBytes) })}`);
4297
+ lines.push(` \xB7 ${t35("cli.doctor.fts_size", { size: formatBytes(health.indexBytes) })}`);
4152
4298
  }
4153
4299
  if (health.space?.fileBytes !== void 0) {
4154
4300
  lines.push(
4155
- ` \xB7 ${t34("cli.doctor.fts_space", {
4301
+ ` \xB7 ${t35("cli.doctor.fts_space", {
4156
4302
  file: formatBytes(health.space.fileBytes),
4157
4303
  free: formatBytes(health.space.freeBytes)
4158
4304
  })}`
4159
4305
  );
4160
- lines.push(` \xB7 ${t34("cli.doctor.fts_reclaim_hint")}`);
4306
+ lines.push(` \xB7 ${t35("cli.doctor.fts_reclaim_hint")}`);
4161
4307
  }
4162
4308
  return lines;
4163
4309
  }
4164
4310
  function reclaimLines(report) {
4165
4311
  const lines = [`
4166
- ${t34("cli.doctor.reclaim_head")}`];
4312
+ ${t35("cli.doctor.reclaim_head")}`];
4167
4313
  const secs = (ms) => `${(ms / 1e3).toFixed(1)}s`;
4168
4314
  lines.push(
4169
- ` ${STATUS_MARK.ok} ${t34("cli.doctor.reclaim_optimize", {
4315
+ ` ${STATUS_MARK.ok} ${t35("cli.doctor.reclaim_optimize", {
4170
4316
  before: formatBytes(report.before.freeBytes),
4171
4317
  after: formatBytes(report.afterOptimize.freeBytes),
4172
4318
  ms: secs(report.optimizeMs)
@@ -4174,7 +4320,7 @@ ${t34("cli.doctor.reclaim_head")}`];
4174
4320
  );
4175
4321
  if (report.vacuumed) {
4176
4322
  lines.push(
4177
- ` ${STATUS_MARK.ok} ${t34("cli.doctor.reclaim_vacuum", {
4323
+ ` ${STATUS_MARK.ok} ${t35("cli.doctor.reclaim_vacuum", {
4178
4324
  before: formatBytes(report.before.pageBytes),
4179
4325
  after: formatBytes(report.after.pageBytes),
4180
4326
  ms: secs(report.vacuumMs)
@@ -4182,14 +4328,14 @@ ${t34("cli.doctor.reclaim_head")}`];
4182
4328
  );
4183
4329
  const saved = report.before.pageBytes - report.after.pageBytes;
4184
4330
  lines.push(
4185
- ` ${STATUS_MARK.ok} ${t34("cli.doctor.reclaim_total", {
4331
+ ` ${STATUS_MARK.ok} ${t35("cli.doctor.reclaim_total", {
4186
4332
  saved: formatBytes(saved),
4187
4333
  pct: `${(saved / Math.max(1, report.before.pageBytes) * 100).toFixed(1)}%`
4188
4334
  })}`
4189
4335
  );
4190
4336
  } else if (report.vacuumError !== null) {
4191
4337
  lines.push(
4192
- ` ${STATUS_MARK.warn} ${t34("cli.doctor.reclaim_vacuum_skipped", {
4338
+ ` ${STATUS_MARK.warn} ${t35("cli.doctor.reclaim_vacuum_skipped", {
4193
4339
  detail: report.vacuumError
4194
4340
  })}`
4195
4341
  );
@@ -4209,17 +4355,17 @@ function hookLines(rt) {
4209
4355
  const { sources } = rt.hook;
4210
4356
  if (sources.length === 0) return [];
4211
4357
  const lines = [`
4212
- ${t34("cli.doctor.hook_head")}`];
4358
+ ${t35("cli.doctor.hook_head")}`];
4213
4359
  for (const source of sources) {
4214
- const label = t34(HOOK_SOURCE_LABEL[source.kind]);
4360
+ const label = t35(HOOK_SOURCE_LABEL[source.kind]);
4215
4361
  if (source.skipped) {
4216
4362
  lines.push(` ${STATUS_MARK.skipped} ${label}: ${source.path}`);
4217
- lines.push(` ${t34("cli.doctor.hook_skipped")}`);
4363
+ lines.push(` ${t35("cli.doctor.hook_skipped")}`);
4218
4364
  continue;
4219
4365
  }
4220
4366
  const name = source.plugin === void 0 ? label : `${label} ${source.plugin}`;
4221
4367
  lines.push(
4222
- ` ${STATUS_MARK.ok} ${name}: ${source.path}${t34("cli.doctor.hook_count", {
4368
+ ` ${STATUS_MARK.ok} ${name}: ${source.path}${t35("cli.doctor.hook_count", {
4223
4369
  n: source.count
4224
4370
  })}`
4225
4371
  );
@@ -4233,65 +4379,65 @@ var JOB_KIND_LABEL = {
4233
4379
  };
4234
4380
  function jobLines(jobs) {
4235
4381
  const lines = [`
4236
- ${t34("cli.doctor.jobs_head")}`];
4382
+ ${t35("cli.doctor.jobs_head")}`];
4237
4383
  const running = jobs.filter((job) => job.status === "running");
4238
4384
  if (running.length === 0) {
4239
- lines.push(` ${STATUS_MARK.ok} ${t34("cli.doctor.jobs_none")}`);
4385
+ lines.push(` ${STATUS_MARK.ok} ${t35("cli.doctor.jobs_none")}`);
4240
4386
  return lines;
4241
4387
  }
4242
- lines.push(` ${STATUS_MARK.warn} ${t34("cli.doctor.jobs_running", { n: running.length })}`);
4388
+ lines.push(` ${STATUS_MARK.warn} ${t35("cli.doctor.jobs_running", { n: running.length })}`);
4243
4389
  for (const job of running) {
4244
4390
  lines.push(
4245
- ` \xB7 ${t34("cli.doctor.jobs_line", {
4246
- kind: t34(JOB_KIND_LABEL[job.kind]),
4391
+ ` \xB7 ${t35("cli.doctor.jobs_line", {
4392
+ kind: t35(JOB_KIND_LABEL[job.kind]),
4247
4393
  id: job.id,
4248
4394
  label: job.label
4249
4395
  })}`
4250
4396
  );
4251
4397
  }
4252
- lines.push(` \xB7 ${t34("cli.doctor.jobs_lifetime")}`);
4398
+ lines.push(` \xB7 ${t35("cli.doctor.jobs_lifetime")}`);
4253
4399
  return lines;
4254
4400
  }
4255
4401
  function terminalLines(result, terminal) {
4256
4402
  const head = `
4257
- ${t34("cli.doctor.terminal_head")}`;
4403
+ ${t35("cli.doctor.terminal_head")}`;
4258
4404
  if (!result.ok) {
4259
4405
  if (result.failure.kind === "no-tty") {
4260
4406
  return [
4261
4407
  head,
4262
- ` ${STATUS_MARK.warn} ${t34("cli.doctor.terminal_no_tty")}`,
4263
- ` \xB7 ${t34("cli.doctor.terminal_alternatives")}`
4408
+ ` ${STATUS_MARK.warn} ${t35("cli.doctor.terminal_no_tty")}`,
4409
+ ` \xB7 ${t35("cli.doctor.terminal_alternatives")}`
4264
4410
  ];
4265
4411
  }
4266
4412
  return [
4267
4413
  head,
4268
- ` ${STATUS_MARK.warn} ${t34("cli.doctor.terminal_timeout", { n: result.failure.timeoutMs / 1e3 })}`
4414
+ ` ${STATUS_MARK.warn} ${t35("cli.doctor.terminal_timeout", { n: result.failure.timeoutMs / 1e3 })}`
4269
4415
  ];
4270
4416
  }
4271
4417
  switch (result.sample.kind) {
4272
4418
  case "shift-enter":
4273
- return [head, ` ${STATUS_MARK.ok} ${t34("cli.doctor.terminal_shift_enter")}`];
4419
+ return [head, ` ${STATUS_MARK.ok} ${t35("cli.doctor.terminal_shift_enter")}`];
4274
4420
  case "enter-only":
4275
4421
  if (terminal?.kind === "apple-terminal") {
4276
4422
  return [
4277
4423
  head,
4278
- ` ${STATUS_MARK.warn} ${t34("cli.doctor.terminal_apple")}`,
4279
- ` \xB7 ${t34("cli.doctor.terminal_alternatives")}`
4424
+ ` ${STATUS_MARK.warn} ${t35("cli.doctor.terminal_apple")}`,
4425
+ ` \xB7 ${t35("cli.doctor.terminal_alternatives")}`
4280
4426
  ];
4281
4427
  }
4282
4428
  return [
4283
4429
  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")}`
4430
+ ` ${STATUS_MARK.warn} ${t35("cli.doctor.terminal_enter_only")}`,
4431
+ ` \xB7 ${t35("cli.doctor.terminal_alternatives")}`,
4432
+ ` \xB7 ${t35("cli.doctor.terminal_setup_hint")}`
4287
4433
  ];
4288
4434
  case "other":
4289
4435
  return [
4290
4436
  head,
4291
- ` ${STATUS_MARK.warn} ${t34("cli.doctor.terminal_other", { hex: result.sample.hex })}`
4437
+ ` ${STATUS_MARK.warn} ${t35("cli.doctor.terminal_other", { hex: result.sample.hex })}`
4292
4438
  ];
4293
4439
  case "interrupted":
4294
- return [head, ` \xB7 ${t34("cli.doctor.terminal_interrupted")}`];
4440
+ return [head, ` \xB7 ${t35("cli.doctor.terminal_interrupted")}`];
4295
4441
  }
4296
4442
  }
4297
4443
  async function statusLineLines(config, cwd) {
@@ -4299,95 +4445,96 @@ async function statusLineLines(config, cwd) {
4299
4445
  if (!probe) return [];
4300
4446
  return [
4301
4447
  `
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 })}`
4448
+ ${t35("cli.doctor.status_line_head")}`,
4449
+ ` ${t35("cli.doctor.status_line_command", { command: probe.command })}`,
4450
+ ` ${probe.ok ? t35("cli.doctor.status_line_ok", { detail: probe.detail }) : t35("cli.doctor.status_line_broken", { detail: probe.detail })}`
4305
4451
  ];
4306
4452
  }
4307
4453
  function registerStatusCommands(program2) {
4308
- program2.command("status").description(t34("cli.status.cmd_root")).action(async () => {
4309
- log9(
4454
+ program2.command("status").description(t35("cli.status.cmd_root")).action(async () => {
4455
+ log10(
4310
4456
  [
4311
- t34("cli.status.version", { version: VERSION }),
4457
+ t35("cli.status.version", { version: VERSION }),
4312
4458
  `Node: ${process.version} (${process.platform}/${process.arch})`,
4313
- t34("cli.status.home", { path: EPOCH_HOME }),
4459
+ t35("cli.status.home", { path: EPOCH_HOME }),
4314
4460
  `Profile: ${resolveProfile()}`,
4315
- t34("cli.status.credentials", {
4316
- state: hasCredentials() ? t34("cli.status.credentials_set") : t34("cli.status.credentials_unset")
4461
+ t35("cli.status.credentials", {
4462
+ state: hasCredentials() ? t35("cli.status.credentials_set") : t35("cli.status.credentials_unset")
4317
4463
  }),
4318
- t34("cli.status.secret_backend", { detail: await describeSecretBackend() }),
4464
+ t35("cli.status.secret_backend", { detail: await describeSecretBackend() }),
4319
4465
  `config.yaml: ${describeConfig()}`,
4320
- `.env: ${existsSync7(ENV_PATH) ? t34("cli.status.env_present") : t34("cli.status.env_absent")}`
4466
+ `.env: ${existsSync7(ENV_PATH) ? t35("cli.status.env_present") : t35("cli.status.env_absent")}`
4321
4467
  ].join("\n")
4322
4468
  );
4323
4469
  });
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 }));
4470
+ program2.command("doctor").description(t35("cli.doctor.cmd_root")).option("--reclaim", t35("cli.doctor.reclaim_opt")).action(async (opts) => {
4471
+ log10(t35("cli.doctor.node", { version: process.version }));
4326
4472
  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()) : [];
4473
+ if (avail) log10(t35("cli.doctor.disk", { avail }));
4474
+ log10(`${hasCredentials() ? "\u2713" : "\u25CB"} ${t35("cli.doctor.credentials")}`);
4475
+ const configIssues = existsSync7(CONFIG_PATH) ? (loadConfig4(), getConfigIssues()) : [];
4330
4476
  const configMark = !existsSync7(CONFIG_PATH) ? "\u25CB" : configIssues.length > 0 ? "\u26A0" : "\u2713";
4331
- log9(`${configMark} config: ${CONFIG_PATH}`);
4477
+ log10(`${configMark} config: ${CONFIG_PATH}`);
4332
4478
  try {
4333
4479
  const { buildRuntime: buildRuntime4 } = await import("@epoch-agent/runtime");
4334
4480
  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);
4481
+ log10(`
4482
+ ${t35("cli.doctor.workspace_head")}`);
4483
+ for (const line of workspaceLines(rt)) log10(line);
4484
+ for (const line of sandboxLines(rt.workspace.root, rt.config.sandbox)) log10(line);
4485
+ for (const line of hookLines(rt)) log10(line);
4486
+ for (const line of jobLines(allJobs().map((j) => j.info))) log10(line);
4487
+ const { classifyTerminal, probeShiftEnter } = await import("@epoch-agent/tui");
4341
4488
  for (const line of terminalLines(
4342
- await probeShiftEnter({ prompt: t34("cli.doctor.terminal_prompt"), timeoutMs: 8e3 }),
4489
+ await probeShiftEnter({ prompt: t35("cli.doctor.terminal_prompt"), timeoutMs: 8e3 }),
4343
4490
  classifyTerminal(process.env)
4344
4491
  ))
4345
- log9(line);
4346
- for (const line of await statusLineLines(rt.config, process.cwd())) log9(line);
4492
+ log10(line);
4493
+ for (const line of await statusLineLines(rt.config, process.cwd())) log10(line);
4347
4494
  if (rt.sessionStore) {
4348
4495
  try {
4349
- for (const line of ftsLines(rt.sessionStore.ftsHealth())) log9(line);
4496
+ for (const line of ftsLines(rt.sessionStore.ftsHealth())) log10(line);
4350
4497
  } catch (err2) {
4351
- log9(`
4352
- ${t34("cli.doctor.fts_head")}`);
4353
- log9(
4354
- ` ${STATUS_MARK.warn} ${t34("cli.doctor.fts_probe_failed", {
4498
+ log10(`
4499
+ ${t35("cli.doctor.fts_head")}`);
4500
+ log10(
4501
+ ` ${STATUS_MARK.warn} ${t35("cli.doctor.fts_probe_failed", {
4355
4502
  detail: err2 instanceof Error ? err2.message : String(err2)
4356
4503
  })}`
4357
4504
  );
4358
4505
  }
4359
4506
  if (opts.reclaim) {
4360
4507
  try {
4361
- for (const line of reclaimLines(rt.sessionStore.reclaimFts())) log9(line);
4508
+ for (const line of reclaimLines(rt.sessionStore.reclaimFts())) log10(line);
4362
4509
  } catch (err2) {
4363
- log9(`
4364
- ${t34("cli.doctor.reclaim_head")}`);
4365
- log9(
4366
- ` ${STATUS_MARK.failed} ${t34("cli.doctor.reclaim_failed", {
4510
+ log10(`
4511
+ ${t35("cli.doctor.reclaim_head")}`);
4512
+ log10(
4513
+ ` ${STATUS_MARK.failed} ${t35("cli.doctor.reclaim_failed", {
4367
4514
  detail: err2 instanceof Error ? err2.message : String(err2)
4368
4515
  })}`
4369
4516
  );
4370
4517
  }
4371
4518
  }
4372
4519
  }
4373
- log9(`
4374
- ${t34("cli.doctor.modules_head")}`);
4520
+ log10(`
4521
+ ${t35("cli.doctor.modules_head")}`);
4375
4522
  const order = { failed: 0, warn: 1, skipped: 2, ok: 3 };
4376
4523
  const sorted = [...rt.diagnosticList].sort(
4377
4524
  (a, b) => (order[a.status] ?? 9) - (order[b.status] ?? 9)
4378
4525
  );
4379
- for (const d of sorted) log9(` ${STATUS_MARK[d.status]} ${d.module}: ${d.detail}`);
4526
+ for (const d of sorted) log10(` ${STATUS_MARK[d.status]} ${d.module}: ${d.detail}`);
4380
4527
  await rt.dispose();
4381
4528
  if (hasFailure(rt.diagnosticList)) {
4382
4529
  const bad = rt.diagnosticList.filter((d) => d.status === "failed").length;
4383
- log9(`
4384
- ${t34("cli.doctor.modules_failed", { count: bad })}`);
4530
+ log10(`
4531
+ ${t35("cli.doctor.modules_failed", { count: bad })}`);
4385
4532
  process.exitCode = EXIT_CODES.FAILURE;
4386
4533
  }
4387
4534
  } catch (err2) {
4388
- log9(
4535
+ log10(
4389
4536
  `
4390
- ${t34("cli.doctor.build_failed", {
4537
+ ${t35("cli.doctor.build_failed", {
4391
4538
  message: err2 instanceof Error ? err2.message : String(err2)
4392
4539
  })}`
4393
4540
  );
@@ -4397,21 +4544,21 @@ ${t34("cli.doctor.build_failed", {
4397
4544
  // src/commands/trust.ts
4398
4545
  import { existsSync as existsSync8, realpathSync as realpathSync3 } from "fs";
4399
4546
  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");
4547
+ import { loadConfig as loadConfig5, TrustManager as TrustManager3 } from "@epoch-agent/core";
4548
+ import { t as t36, trustPath as trustPath3, uiDateLocale as uiDateLocale4 } from "@epoch-agent/infra";
4549
+ var log11 = (msg) => process.stdout.write(msg + "\n");
4403
4550
  var warn3 = (msg) => process.stderr.write(msg + "\n");
4404
4551
  function scopeLabel(scope) {
4405
- return scope === "directory-tree" ? t35("trust.scope_tree") : t35("trust.scope_dir");
4552
+ return scope === "directory-tree" ? t36("trust.scope_tree") : t36("trust.scope_dir");
4406
4553
  }
4407
4554
  function levelLabel(level) {
4408
4555
  switch (level) {
4409
4556
  case "trusted":
4410
- return t35("trust.level_trusted");
4557
+ return t36("trust.level_trusted");
4411
4558
  case "untrusted":
4412
- return t35("trust.level_untrusted");
4559
+ return t36("trust.level_untrusted");
4413
4560
  case "unknown":
4414
- return t35("trust.level_unknown");
4561
+ return t36("trust.level_unknown");
4415
4562
  }
4416
4563
  }
4417
4564
  function physicalPath(input2) {
@@ -4424,63 +4571,63 @@ function physicalPath(input2) {
4424
4571
  }
4425
4572
  }
4426
4573
  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) => {
4574
+ const cmd = program2.command("trust").description(t36("trust.cmd_root"));
4575
+ cmd.command("list", { isDefault: true }).description(t36("trust.cmd_list")).action(() => withTrust((tm) => printList3(tm)));
4576
+ 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
4577
  withTrust((tm) => {
4431
4578
  const dir = physicalPath(path ?? process.cwd());
4432
4579
  tm.record(dir, "trusted", opts.tree ? "directory-tree" : "directory");
4433
- log10(
4434
- `\u2713 ${t35("trust.added", {
4580
+ log11(
4581
+ `\u2713 ${t36("trust.added", {
4435
4582
  dir,
4436
4583
  scope: scopeLabel(opts.tree ? "directory-tree" : "directory")
4437
4584
  })}`
4438
4585
  );
4439
4586
  });
4440
4587
  });
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) => {
4588
+ 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
4589
  withTrust((tm) => {
4443
4590
  const dir = physicalPath(path ?? process.cwd());
4444
4591
  tm.record(dir, "untrusted", opts.tree ? "directory-tree" : "directory");
4445
- log10(
4446
- `\u2717 ${t35("trust.denied", {
4592
+ log11(
4593
+ `\u2717 ${t36("trust.denied", {
4447
4594
  dir,
4448
4595
  scope: scopeLabel(opts.tree ? "directory-tree" : "directory")
4449
4596
  })}`
4450
4597
  );
4451
4598
  });
4452
4599
  });
4453
- cmd.command("remove").alias("rm").description(t35("trust.cmd_remove")).argument("<path>", t35("trust.arg_path")).action((path) => {
4600
+ cmd.command("remove").alias("rm").description(t36("trust.cmd_remove")).argument("<path>", t36("trust.arg_path")).action((path) => {
4454
4601
  withTrust((tm) => {
4455
4602
  const dir = physicalPath(path);
4456
4603
  if (!tm.list().some((r) => resolve3(r.path) === dir)) {
4457
- warn3(t35("trust.no_record", { dir }));
4604
+ warn3(t36("trust.no_record", { dir }));
4458
4605
  process.exit(1);
4459
4606
  }
4460
4607
  tm.revoke(dir);
4461
- log10(t35("trust.removed", { dir, level: levelLabel(tm.check(dir)) }));
4608
+ log11(t36("trust.removed", { dir, level: levelLabel(tm.check(dir)) }));
4462
4609
  });
4463
4610
  });
4464
4611
  }
4465
4612
  function printList3(tm) {
4466
- if (loadConfig4().trust?.enabled === false) {
4467
- warn3(t35("trust.gate_off"));
4613
+ if (loadConfig5().trust?.enabled === false) {
4614
+ warn3(t36("trust.gate_off"));
4468
4615
  }
4469
- log10(t35("trust.list_head", { path: trustPath3(EPOCH_HOME) }));
4616
+ log11(t36("trust.list_head", { path: trustPath3(EPOCH_HOME) }));
4470
4617
  const records = [...tm.list()].sort((a, b) => a.path.localeCompare(b.path));
4471
4618
  if (records.length === 0) {
4472
- log10(t35("trust.list_empty"));
4619
+ log11(t36("trust.list_empty"));
4473
4620
  }
4474
4621
  for (const r of records) {
4475
4622
  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}`);
4623
+ const when = r.decidedAt ? new Date(r.decidedAt).toLocaleString(uiDateLocale4()) : t36("trust.when_unknown");
4624
+ log11(` ${mark} ${r.path} [${scopeLabel(r.scope)}] ${when}`);
4478
4625
  }
4479
4626
  const cwd = process.cwd();
4480
- log10(
4627
+ log11(
4481
4628
  `
4482
- ${t35("trust.cwd_line", { cwd })}
4483
- ${t35("trust.cwd_verdict", { level: levelLabel(tm.check(cwd)) })}`
4629
+ ${t36("trust.cwd_line", { cwd })}
4630
+ ${t36("trust.cwd_verdict", { level: levelLabel(tm.check(cwd)) })}`
4484
4631
  );
4485
4632
  }
4486
4633
  function withTrust(fn) {
@@ -4489,46 +4636,46 @@ function withTrust(fn) {
4489
4636
  try {
4490
4637
  fn(tm);
4491
4638
  } catch (err2) {
4492
- warn3(t35("trust.error", { message: err2 instanceof Error ? err2.message : String(err2) }));
4639
+ warn3(t36("trust.error", { message: err2 instanceof Error ? err2.message : String(err2) }));
4493
4640
  process.exit(1);
4494
4641
  }
4495
4642
  }
4496
4643
  // src/commands/upgrade.ts
4497
- import { t as t36 } from "@epoch-agent/infra";
4498
- var log11 = (msg) => process.stdout.write(`${msg}
4644
+ import { t as t37 } from "@epoch-agent/infra";
4645
+ var log12 = (msg) => process.stdout.write(`${msg}
4499
4646
  `);
4500
4647
  function registerUpgradeCommand(program2) {
4501
- program2.command("upgrade").description(t36("upgrade.cmd_root")).action(async () => {
4648
+ program2.command("upgrade").description(t37("upgrade.cmd_root")).action(async () => {
4502
4649
  const self = selfPackage();
4503
4650
  const info = getInstallationInfo(self.name);
4504
- log11(t36("upgrade.current", { version: self.version }));
4505
- log11(
4506
- t36("upgrade.installed_via", {
4651
+ log12(t37("upgrade.current", { version: self.version }));
4652
+ log12(
4653
+ t37("upgrade.installed_via", {
4507
4654
  manager: info.packageManager,
4508
- global: info.isGlobal ? t36("installation.global_suffix") : "",
4655
+ global: info.isGlobal ? t37("installation.global_suffix") : "",
4509
4656
  note: info.note
4510
4657
  })
4511
4658
  );
4512
4659
  const notice = isUpdateCheckDisabled() ? readUpdateNotice() : await refreshUpdateCache({ ttlMs: 0 }).catch(() => null);
4513
4660
  if (notice) {
4514
- log11(`
4515
- ${t36("upgrade.available", { current: notice.current, latest: notice.latest })}`);
4516
- } else log11(`
4517
- ${t36("upgrade.none")}`);
4661
+ log12(`
4662
+ ${t37("upgrade.available", { current: notice.current, latest: notice.latest })}`);
4663
+ } else log12(`
4664
+ ${t37("upgrade.none")}`);
4518
4665
  if (info.updateCommand) {
4519
- log11(`
4520
- ${t36("upgrade.how")}
4666
+ log12(`
4667
+ ${t37("upgrade.how")}
4521
4668
  ${info.updateCommand}`);
4522
- log11(`
4523
- ${t36("upgrade.why_manual")}`);
4669
+ log12(`
4670
+ ${t37("upgrade.why_manual")}`);
4524
4671
  }
4525
4672
  });
4526
- program2.command(UPDATE_CHECK_SUBCOMMAND, { hidden: true }).description(t36("upgrade.cmd_refresh")).action(async () => {
4673
+ program2.command(UPDATE_CHECK_SUBCOMMAND, { hidden: true }).description(t37("upgrade.cmd_refresh")).action(async () => {
4527
4674
  await refreshUpdateCache().catch(() => null);
4528
4675
  });
4529
4676
  }
4530
4677
  // src/commands/web.ts
4531
- import { t as t37 } from "@epoch-agent/infra";
4678
+ import { t as t38 } from "@epoch-agent/infra";
4532
4679
  import { buildRuntime as buildRuntime3 } from "@epoch-agent/runtime";
4533
4680
  import {
4534
4681
  createWebServer,
@@ -4575,7 +4722,7 @@ var err = (msg) => {
4575
4722
  `);
4576
4723
  };
4577
4724
  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) => {
4725
+ 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
4726
  await runWeb({ ...opts, json: jsonRequested(opts.json, command.parent?.opts()["json"]) });
4580
4727
  });
4581
4728
  }
@@ -4584,7 +4731,7 @@ function jsonRequested(own, fromProgram) {
4584
4731
  }
4585
4732
  async function runWeb(opts) {
4586
4733
  const port = parsePort2(opts.port);
4587
- if (port === null) return fail(t37("cli.web.err_port", { value: String(opts.port) }));
4734
+ if (port === null) return fail(t38("cli.web.err_port", { value: String(opts.port) }));
4588
4735
  const binding = decideBinding({
4589
4736
  ...opts.host === void 0 ? {} : { host: opts.host },
4590
4737
  ...port === void 0 ? {} : { port },
@@ -4609,10 +4756,10 @@ async function runWeb(opts) {
4609
4756
  if (lines.machine) out(lines.machine);
4610
4757
  for (const line of lines.human) say(line);
4611
4758
  if (opts.open && !openInBrowser(server.url)) say(browserFailed());
4612
- installShutdown(server, say);
4759
+ installShutdown2(server, say);
4613
4760
  }
4614
- var missingWebRoot = () => t37("cli.web.missing_root");
4615
- var browserFailed = () => ` ${t37("cli.web.browser_failed")}`;
4761
+ var missingWebRoot = () => t38("cli.web.missing_root");
4762
+ var browserFailed = () => ` ${t38("cli.web.browser_failed")}`;
4616
4763
  function pluginsOption(plugins) {
4617
4764
  return plugins ? { hostMarketplaces: { sources: [] } } : {};
4618
4765
  }
@@ -4624,7 +4771,7 @@ async function boot(binding, plugins) {
4624
4771
  });
4625
4772
  if (!runtime.session) {
4626
4773
  await runtime.dispose();
4627
- fail(`${t37("cli.web.no_provider")}
4774
+ fail(`${t38("cli.web.no_provider")}
4628
4775
  ${runtime.diagnostics.join("\n")}`);
4629
4776
  return null;
4630
4777
  }
@@ -4646,11 +4793,11 @@ function announceLines(input2) {
4646
4793
  const human = [];
4647
4794
  if (!input2.json) {
4648
4795
  human.push(` Epoch Web http://${input2.host}:${input2.port}`);
4649
- human.push(` ${t37("cli.web.open_this")}
4796
+ human.push(` ${t38("cli.web.open_this")}
4650
4797
  ${input2.url}`);
4651
4798
  }
4652
4799
  if (input2.lanExposed) {
4653
- human.push(` ${t37("cli.web.lan_exposed")}`);
4800
+ human.push(` ${t38("cli.web.lan_exposed")}`);
4654
4801
  }
4655
4802
  if (input2.placeholder) human.push(` \u26A0 ${missingWebRoot()}`);
4656
4803
  if (!input2.json) return { human };
@@ -4662,13 +4809,13 @@ function announceLines(input2) {
4662
4809
  });
4663
4810
  return { machine, human };
4664
4811
  }
4665
- function installShutdown(server, say) {
4812
+ function installShutdown2(server, say) {
4666
4813
  let shuttingDown = false;
4667
4814
  const onSignal = () => {
4668
4815
  if (shuttingDown) process.exit(1);
4669
4816
  shuttingDown = true;
4670
4817
  say(`
4671
- ${t37("cli.web.shutting_down")}`);
4818
+ ${t38("cli.web.shutting_down")}`);
4672
4819
  server.close().then(
4673
4820
  () => process.exit(0),
4674
4821
  () => process.exit(1)
@@ -4687,18 +4834,18 @@ function fail(message) {
4687
4834
  process.exit(1);
4688
4835
  }
4689
4836
  // src/language.ts
4690
- import { loadConfig as loadConfig5 } from "@epoch-agent/core";
4837
+ import { loadConfig as loadConfig6 } from "@epoch-agent/core";
4691
4838
  import { resolveLang, setLang } from "@epoch-agent/infra";
4692
4839
  function applyConfiguredLanguage() {
4693
4840
  try {
4694
- setLang(resolveLang(loadConfig5().display?.language));
4841
+ setLang(resolveLang(loadConfig6().display?.language));
4695
4842
  } catch {
4696
4843
  }
4697
4844
  }
4698
4845
  // src/index.ts
4699
4846
  applyConfiguredLanguage();
4700
4847
  var program = new Command();
4701
- program.name("epoch").description(t38("cli.program_description"));
4848
+ program.name("epoch").description(t39("cli.program_description"));
4702
4849
  registerConfigCommand(program);
4703
4850
  registerMcpCommand(program);
4704
4851
  registerModelCommand(program);
@@ -4707,6 +4854,7 @@ registerSessionsCommand(program);
4707
4854
  registerAgentsCommand(program);
4708
4855
  registerPluginCommand(program);
4709
4856
  registerTrustCommand(program);
4857
+ registerComplianceCommand(program);
4710
4858
  registerScheduleCommand(program);
4711
4859
  registerUpgradeCommand(program);
4712
4860
  registerWebCommand(program);