@ouro.bot/cli 0.1.0-alpha.456 → 0.1.0-alpha.458

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/changelog.json CHANGED
@@ -1,6 +1,22 @@
1
1
  {
2
2
  "_note": "This changelog is maintained as part of the PR/version-bump workflow. Agent-curated, not auto-generated. Agents read this file directly via read_file to understand what changed between versions.",
3
3
  "versions": [
4
+ {
5
+ "version": "0.1.0-alpha.458",
6
+ "changes": [
7
+ "Agent Mail setup guidance now explicitly forbids telling the human to run setup CLI commands; the agent must run `ouro account ensure`, `ouro connect mail`, `ouro mail import-mbox`, `ouro status`, and `ouro doctor` itself when doing setup.",
8
+ "If the agent's current surface cannot run shell/tools, the setup contract now says to move to a tool-capable Ouro setup session or companion instead of offloading CLI operation to the human.",
9
+ "Prompt and runbook contract tests now cover the live failure mode where the agent says it owns setup but still asks Ari to run `ouro connect mail`."
10
+ ]
11
+ },
12
+ {
13
+ "version": "0.1.0-alpha.457",
14
+ "changes": [
15
+ "Agent Mail setup is now explicitly agent-guided in the system prompt and runbook: when a human asks an agent to set up email, the agent should lead the flow, run agent-runnable commands itself, ask only for human-required browser/file/confirmation steps, and verify each step before continuing.",
16
+ "`ouro account ensure` and `ouro connect mail` now accept non-interactive mail source flags (`--owner-email`, `--source`, and `--no-delegated-source`), so an agent can provision Mailroom after collecting the needed human answer instead of relying on an interactive prompt.",
17
+ "Mailroom repair and setup guidance now labels repair as agent-runnable, avoids the false `ouro doctor --agent` path, and keeps HEY MBOX import as an agent-run command after the human provides the browser-exported file path."
18
+ ]
19
+ },
4
20
  {
5
21
  "version": "0.1.0-alpha.456",
6
22
  "changes": [
@@ -2698,7 +2698,16 @@ function mailroomPrivateKeys(mailroom) {
2698
2698
  const keys = isPlainRecord(mailroom?.privateKeys) ? mailroom.privateKeys : {};
2699
2699
  return Object.fromEntries(Object.entries(keys).filter((entry) => typeof entry[1] === "string"));
2700
2700
  }
2701
- async function promptDelegatedMailSource(deps) {
2701
+ async function promptDelegatedMailSource(deps, input = {}) {
2702
+ if (input.noDelegatedSource)
2703
+ return { ownerEmail: "", source: "" };
2704
+ if (input.ownerEmail !== undefined) {
2705
+ const ownerEmail = input.ownerEmail.trim();
2706
+ return {
2707
+ ownerEmail,
2708
+ source: ownerEmail ? (input.source?.trim() || "hey") : "",
2709
+ };
2710
+ }
2702
2711
  const promptInput = requirePromptInput(deps, "Agent Mail setup");
2703
2712
  const ownerEmail = (await promptInput("Delegated owner email for first source alias [blank to skip]: ")).trim();
2704
2713
  const source = ownerEmail
@@ -2768,7 +2777,7 @@ async function ensureAgentMailroom(agent, input, deps, progressLabel) {
2768
2777
  const syncSummary = pushAgentBundleAfterCliMutation(agent, deps);
2769
2778
  return { mailboxAddress, sourceAlias, registryPath, storePath, stored, syncSummary };
2770
2779
  }
2771
- async function executeConnectMail(agent, deps) {
2780
+ async function executeConnectMail(agent, deps, input = {}) {
2772
2781
  writeConnectorIntro(deps, {
2773
2782
  title: "Connect Agent Mail",
2774
2783
  subtitle: `${agent} gets a private Mailroom identity and delegated source lane.`,
@@ -2803,7 +2812,7 @@ async function executeConnectMail(agent, deps) {
2803
2812
  "The registry and encrypted local store live under the agent bundle state.",
2804
2813
  ],
2805
2814
  });
2806
- const setup = await promptDelegatedMailSource(deps);
2815
+ const setup = await promptDelegatedMailSource(deps, input);
2807
2816
  const outcome = await ensureAgentMailroom(agent, setup, deps, "connect mail");
2808
2817
  return writeCapabilityOutcome(deps, {
2809
2818
  subtitle: `${agent}'s Mail sense is configured.`,
@@ -2865,7 +2874,7 @@ async function executeAccountEnsure(command, deps) {
2865
2874
  "This creates or preserves runtime/config Mailroom coordinates and enables the Mail sense.",
2866
2875
  ],
2867
2876
  });
2868
- const setup = await promptDelegatedMailSource(deps);
2877
+ const setup = await promptDelegatedMailSource(deps, command);
2869
2878
  const outcome = await ensureAgentMailroom(command.agent, setup, deps, "account ensure");
2870
2879
  return writeCapabilityOutcome(deps, {
2871
2880
  subtitle: `${command.agent}'s work substrate account is configured.`,
@@ -2912,13 +2921,13 @@ async function executeMailImportMbox(command, deps) {
2912
2921
  const mailroom = runtime.config.mailroom;
2913
2922
  if (!mailroom || typeof mailroom !== "object" || Array.isArray(mailroom)) {
2914
2923
  progress.end();
2915
- throw new Error(`missing mailroom config for ${command.agent}; run 'ouro connect mail --agent ${command.agent}' first`);
2924
+ throw new Error(`missing mailroom config for ${command.agent}; agent-runnable repair: 'ouro connect mail --agent ${command.agent}'`);
2916
2925
  }
2917
2926
  const registryPath = stringField(mailroom, "registryPath");
2918
2927
  const storePath = stringField(mailroom, "storePath");
2919
2928
  if (!registryPath || !storePath) {
2920
2929
  progress.end();
2921
- throw new Error(`mailroom config for ${command.agent} is missing registryPath/storePath; run 'ouro connect mail --agent ${command.agent}' again`);
2930
+ throw new Error(`mailroom config for ${command.agent} is missing registryPath/storePath; agent-runnable repair: 'ouro connect mail --agent ${command.agent}'`);
2922
2931
  }
2923
2932
  progress.updateDetail("reading registry and MBOX");
2924
2933
  const registry = JSON.parse(fs.readFileSync(registryPath, "utf-8"));
@@ -3009,7 +3018,7 @@ async function executeConnect(command, deps) {
3009
3018
  if (command.target === "bluebubbles")
3010
3019
  return executeConnectBlueBubbles(command.agent, deps);
3011
3020
  if (command.target === "mail")
3012
- return executeConnectMail(command.agent, deps);
3021
+ return executeConnectMail(command.agent, deps, command);
3013
3022
  const progress = createHumanCommandProgress(deps, "connect");
3014
3023
  let menu;
3015
3024
  try {
@@ -313,13 +313,13 @@ const SUBCOMMAND_HELP = {
313
313
  },
314
314
  "connect mail": {
315
315
  description: "Provision portable Agent Mail / Mailroom access and enable the Mail sense",
316
- usage: "ouro connect mail [--agent <name>]",
317
- example: "ouro connect mail",
316
+ usage: "ouro connect mail [--agent <name>] [--owner-email <email> --source <label>|--no-delegated-source]",
317
+ example: "ouro connect mail --agent slugger --owner-email ari@mendelow.me --source hey",
318
318
  },
319
319
  "account ensure": {
320
320
  description: "Idempotently prepare an agent's vault-backed work substrate account and private Mailroom mailbox",
321
- usage: "ouro account ensure [--agent <name>]",
322
- example: "ouro account ensure --agent slugger",
321
+ usage: "ouro account ensure [--agent <name>] [--owner-email <email> --source <label>|--no-delegated-source]",
322
+ example: "ouro account ensure --agent slugger --owner-email ari@mendelow.me --source hey",
323
323
  },
324
324
  "mail import-mbox": {
325
325
  description: "Import a HEY or other MBOX export into an existing delegated Mailroom source grant",
@@ -83,8 +83,8 @@ function usage() {
83
83
  " ouro config model [--agent <name>] <model-name>",
84
84
  " ouro config models [--agent <name>]",
85
85
  " ouro auth [--agent <name>] [--provider <provider>]",
86
- " ouro account ensure [--agent <name>]",
87
- " ouro connect [providers|perplexity|embeddings|teams|bluebubbles|mail] [--agent <name>]",
86
+ " ouro account ensure [--agent <name>] [--owner-email <email> --source <label>|--no-delegated-source]",
87
+ " ouro connect [providers|perplexity|embeddings|teams|bluebubbles|mail] [--agent <name>] [--owner-email <email> --source <label>|--no-delegated-source]",
88
88
  " ouro mail import-mbox --file <path> [--owner-email <email>] [--source <label>] [--agent <name>]",
89
89
  " ouro auth verify [--agent <name>] [--provider <provider>]",
90
90
  " ouro auth switch [--agent <name>] --provider <provider>",
@@ -606,12 +606,67 @@ function normalizeConnectTarget(value) {
606
606
  return "mail";
607
607
  throw new Error("Usage: ouro connect [providers|perplexity|embeddings|teams|bluebubbles|mail] [--agent <name>]");
608
608
  }
609
+ function extractMailSourceFlags(args, usageText) {
610
+ const rest = [];
611
+ let ownerEmail;
612
+ let source;
613
+ let noDelegatedSource = false;
614
+ let hasMailSourceFlags = false;
615
+ for (let i = 0; i < args.length; i += 1) {
616
+ const token = args[i];
617
+ if (token === "--owner-email") {
618
+ if (args[i + 1] === undefined)
619
+ throw new Error(usageText);
620
+ ownerEmail = args[++i];
621
+ hasMailSourceFlags = true;
622
+ continue;
623
+ }
624
+ if (token === "--source") {
625
+ if (args[i + 1] === undefined)
626
+ throw new Error(usageText);
627
+ source = args[++i];
628
+ hasMailSourceFlags = true;
629
+ continue;
630
+ }
631
+ if (token === "--no-delegated-source") {
632
+ noDelegatedSource = true;
633
+ hasMailSourceFlags = true;
634
+ continue;
635
+ }
636
+ rest.push(token);
637
+ }
638
+ if (noDelegatedSource && (ownerEmail !== undefined || source !== undefined)) {
639
+ throw new Error("--no-delegated-source cannot be combined with --owner-email or --source");
640
+ }
641
+ if (source !== undefined && ownerEmail === undefined) {
642
+ throw new Error("--source requires --owner-email");
643
+ }
644
+ return {
645
+ rest,
646
+ ...(ownerEmail !== undefined ? { ownerEmail } : {}),
647
+ ...(source !== undefined ? { source } : {}),
648
+ ...(noDelegatedSource ? { noDelegatedSource: true } : {}),
649
+ hasMailSourceFlags,
650
+ };
651
+ }
609
652
  function parseConnectCommand(args) {
610
- const { agent, rest } = extractAgentFlag(args);
611
- if (rest.length > 1)
612
- throw new Error("Usage: ouro connect [providers|perplexity|embeddings|teams|bluebubbles|mail] [--agent <name>]");
613
- const target = normalizeConnectTarget(rest[0]);
614
- return { kind: "connect", ...(agent ? { agent } : {}), ...(target ? { target } : {}) };
653
+ const usageText = "Usage: ouro connect [providers|perplexity|embeddings|teams|bluebubbles|mail] [--agent <name>] [--owner-email <email> --source <label>|--no-delegated-source]";
654
+ const { agent, rest: afterAgent } = extractAgentFlag(args);
655
+ const mailFlags = extractMailSourceFlags(afterAgent, usageText);
656
+ if (mailFlags.rest.length > 1)
657
+ throw new Error(usageText);
658
+ const target = normalizeConnectTarget(mailFlags.rest[0]);
659
+ if (mailFlags.hasMailSourceFlags && target !== "mail") {
660
+ throw new Error("Mail source flags require `ouro connect mail`.");
661
+ }
662
+ return {
663
+ kind: "connect",
664
+ ...(agent ? { agent } : {}),
665
+ ...(target ? { target } : {}),
666
+ ...(mailFlags.ownerEmail !== undefined ? { ownerEmail: mailFlags.ownerEmail } : {}),
667
+ ...(mailFlags.source !== undefined ? { source: mailFlags.source } : {}),
668
+ ...(mailFlags.noDelegatedSource ? { noDelegatedSource: true } : {}),
669
+ };
615
670
  }
616
671
  function parseMailCommand(args) {
617
672
  const [sub, ...subArgs] = args;
@@ -651,13 +706,21 @@ function parseMailCommand(args) {
651
706
  }
652
707
  function parseAccountCommand(args) {
653
708
  const [sub, ...subArgs] = args;
709
+ const usageText = "Usage: ouro account ensure [--agent <name>] [--owner-email <email> --source <label>|--no-delegated-source]";
654
710
  if (sub !== "ensure") {
655
- throw new Error("Usage: ouro account ensure [--agent <name>]");
711
+ throw new Error(usageText);
656
712
  }
657
- const { agent, rest } = extractAgentFlag(subArgs);
658
- if (rest.length > 0)
659
- throw new Error("Usage: ouro account ensure [--agent <name>]");
660
- return { kind: "account.ensure", ...(agent ? { agent } : {}) };
713
+ const { agent, rest: afterAgent } = extractAgentFlag(subArgs);
714
+ const mailFlags = extractMailSourceFlags(afterAgent, usageText);
715
+ if (mailFlags.rest.length > 0)
716
+ throw new Error(usageText);
717
+ return {
718
+ kind: "account.ensure",
719
+ ...(agent ? { agent } : {}),
720
+ ...(mailFlags.ownerEmail !== undefined ? { ownerEmail: mailFlags.ownerEmail } : {}),
721
+ ...(mailFlags.source !== undefined ? { source: mailFlags.source } : {}),
722
+ ...(mailFlags.noDelegatedSource ? { noDelegatedSource: true } : {}),
723
+ };
661
724
  }
662
725
  function parseProviderUseCommand(args) {
663
726
  const { agent, rest: afterAgent } = extractAgentFlag(args);
@@ -194,7 +194,7 @@ function senseRepairHint(agent, sense) {
194
194
  return `Run 'ouro vault config set --agent ${agent} --key teams.clientId', teams.clientSecret, and teams.tenantId; then run 'ouro up' again.`;
195
195
  }
196
196
  if (sense === "mail") {
197
- return `Run 'ouro connect mail --agent ${agent}' to provision Mailroom access; then run 'ouro up' again.`;
197
+ return `Agent-runnable: provision Mailroom access with 'ouro connect mail --agent ${agent}', then restart with 'ouro up'.`;
198
198
  }
199
199
  return `Run 'ouro connect bluebubbles --agent ${agent}' to attach BlueBubbles on this machine; then run 'ouro up' again.`;
200
200
  }
@@ -121,7 +121,7 @@ function resolveMailroomReader(agentName = (0, identity_2.getAgentName)()) {
121
121
  ok: false,
122
122
  agentName,
123
123
  reason: "auth-required",
124
- error: `AUTH_REQUIRED:mailroom -- Mail is not available because ${runtime.itemPath} is ${runtime.reason}. Run 'ouro connect mail --agent ${agentName}' after the vault is unlocked.`,
124
+ error: `AUTH_REQUIRED:mailroom -- Mail is not available because ${runtime.itemPath} is ${runtime.reason}. Agent-runnable repair after vault unlock: 'ouro connect mail --agent ${agentName}'.`,
125
125
  };
126
126
  (0, runtime_1.emitNervesEvent)({
127
127
  component: "senses",
@@ -464,9 +464,11 @@ function senseRuntimeGuidance(channel, preReadStatusLines) {
464
464
  lines.push("If asked how to enable another sense, I explain the relevant agent.json senses entry and required agent-vault runtime/config fields instead of guessing.");
465
465
  lines.push("teams setup truth: run `ouro connect teams --agent <agent>` from the connect bay; it stores Teams runtime/config fields and enables `senses.teams.enabled`.");
466
466
  lines.push("bluebubbles setup truth: run `ouro connect bluebubbles --agent <agent>` from the connect bay; it stores this machine's BlueBubbles URL/password/listener config in the agent vault machine runtime item.");
467
- lines.push("mail setup truth: Agent Mail uses Mailroom, not HEY OAuth/IMAP. For the full work substrate account, run `ouro account ensure --agent <agent>`; use `ouro connect mail --agent <agent>` for mail-only repair/provisioning. Use the human's owner email when asked so Mailroom creates the delegated source alias. The detailed runbook is `docs/agent-mail-setup.md`.");
468
- lines.push("mail setup truth: HEY archive bootstrap is human-exported MBOX only. Ask for the browser-downloaded MBOX path, then run `ouro mail import-mbox --file <path> --owner-email <email> --source hey --agent <agent>`.");
469
- lines.push("mail setup truth: verify with `ouro status`, `ouro doctor --agent <agent>`, bounded mail tools (`mail_recent`, `mail_search`, `mail_thread`, `mail_access_log`), and the read-only Outlook Mailbox tab.");
467
+ lines.push("mail setup AX: if a human asks me to set up email, I do not hand them a terminal checklist. I guide the flow end-to-end: name the current phase, run agent-runnable commands myself with shell/tools when available, ask the human only for human-required facts or browser actions, wait for their reply, verify the result, then continue.");
468
+ lines.push("mail setup hard rule: never tell the human to run `ouro account ensure`, `ouro connect mail`, `ouro mail import-mbox`, `ouro status`, or `ouro doctor` for setup. Say what I am about to run, run it myself, and report the result. If my current surface cannot run shell/tools, I ask for a tool-capable Ouro setup session or companion to continue; I do not offload CLI operation to the human.");
469
+ lines.push("mail setup truth: Agent Mail uses Mailroom, not HEY OAuth/IMAP. For the full work substrate account, the agent-runnable command is `ouro account ensure --agent <agent> --owner-email <email> --source hey`; use `ouro connect mail --agent <agent> --owner-email <email> --source hey` for mail-only repair/provisioning, or `--no-delegated-source` for native-only mail. The detailed runbook is `docs/agent-mail-setup.md`.");
470
+ lines.push("mail setup truth: HEY archive bootstrap is human-exported MBOX only. I ask for the browser-downloaded MBOX path, then I run `ouro mail import-mbox --file <path> --owner-email <email> --source hey --agent <agent>` myself and verify the import.");
471
+ lines.push("mail setup truth: verify with `ouro status`, `ouro doctor`, bounded mail tools (`mail_recent`, `mail_search`, `mail_thread`, `mail_access_log`), and the read-only Outlook Mailbox tab. `ouro doctor` is installation-wide; do not invent `ouro doctor --agent <agent>`.");
470
472
  lines.push("mail setup boundaries: do not invent `ouro auth verify --provider mail`, HEY OAuth, HEY IMAP, `ouro mcp call mail ...`, policy flags, autonomous sending, destructive mail actions, or production MX/DNS/forwarding changes. HEY export, HEY forwarding, DNS, MX cutover, sending, and destructive actions require explicit human confirmation.");
471
473
  if (channel === "cli") {
472
474
  lines.push("cli is interactive: it is available when the user opens it, not something `ouro up` daemonizes.");
@@ -114,7 +114,7 @@ async function startMailSenseApp(options) {
114
114
  throw new Error(resolved.error);
115
115
  }
116
116
  if (!resolved.config.registryPath) {
117
- throw new Error(`missing mailroom.registryPath for ${options.agentName}; run 'ouro connect mail --agent ${options.agentName}' again`);
117
+ throw new Error(`missing mailroom.registryPath for ${options.agentName}; agent-runnable repair: 'ouro connect mail --agent ${options.agentName}'`);
118
118
  }
119
119
  const registry = readRegistry(resolved.config.registryPath);
120
120
  const host = resolved.config.host ?? "127.0.0.1";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ouro.bot/cli",
3
- "version": "0.1.0-alpha.456",
3
+ "version": "0.1.0-alpha.458",
4
4
  "main": "dist/heart/daemon/ouro-entry.js",
5
5
  "bin": {
6
6
  "cli": "dist/heart/daemon/ouro-bot-entry.js",